Files
codex-app-server/cloud/console-react/src/api/paths.ts
T
host 7983567491
ci / test (push) Successful in 25m2s
feat: side-thread task kind (Muse role alignment phase 2)
Tasks gain kind='main'|'side' (NULL=main). A side thread hangs under a
parent task, defaults to the local executor, never builds a worktree,
branch or container unless explicitly asked, and writes its conclusion
back to the parent via task_followups on terminal transition.

- server: kind validation + side-thread gates (parent required, no
  coordinator_parts/upload_id/environment_id, parent must not be a
  coordinator), local executor default, GET /tasks kind filter,
  /worktree 404 and /fork /merge /pr 409 for side threads.
- worker: side-default shunt in _run_attempt (no-worktree scratch cwd,
  in-memory plan=1 when a repo is present, seed/checkpoint skipped),
  _writeback_side_thread, marker task-create kind field + inheritance,
  side threads excluded from marker spawn counts.
- host/sandbox: --no-worktree plumbing for dispatch/goal/popen
  (Local + Docker), scratch cwd work/side-threads/<task-id>.
- console (classic only): kind filter + [旁聊] rows + '开旁聊' entry,
  side-thread dispatch mode, side-thread list in detail, merge/PR/fork
  hidden for side threads; build exit 0, console.html sha df39db5a.
- tests: new test_sidethread.py (29 tests) + kind backfill tests in
  test_p2_migrations.py; full cloud suite 3900 tests OK (skipped=13).

Design: verification/codex-muse-role-alignment-design-20261108.md
Summary: verification/codex-muse-role-align-p1p2-20261108.md
Local only: not pushed, not merged, not deployed.
2026-11-07 20:51:23 +00:00

75 lines
4.4 KiB
TypeScript

// Every API path in the app, in one place. No section or hook builds a
// URL string by hand; they all go through this table. Paths are
// same-origin absolute paths, exactly as in the live console.
const enc = encodeURIComponent;
export const paths = {
health: "/health",
relayModels: "/relay/models",
quotaMe: "/users/me/quota",
userKeys: "/users/me/keys",
userKey: (id: string) => "/users/me/keys/" + enc(id),
githubRepos: "/github/repos",
projects: "/projects",
project: (id: string) => "/projects/" + enc(id),
projectMembers: (pid: string) => "/projects/" + enc(pid) + "/members",
projectMember: (pid: string, uid: string) => "/projects/" + enc(pid) + "/members/" + enc(uid),
projectSkills: (pid: string) => "/projects/" + enc(pid) + "/skills",
projectApps: (pid: string) => "/projects/" + enc(pid) + "/apps",
projectMcp: (pid: string) => "/projects/" + enc(pid) + "/mcp-servers",
projectMcpReload: (pid: string) => "/projects/" + enc(pid) + "/mcp-servers/reload",
projectMcpOauth: (pid: string, name: string) => "/projects/" + enc(pid) + "/mcp-servers/" + enc(name) + "/oauth-login",
projectAutomations: (pid: string) => "/projects/" + enc(pid) + "/automations",
projectAutomation: (pid: string, id: string) => "/projects/" + enc(pid) + "/automations/" + enc(id),
projectAutomationCancel: (pid: string, id: string) => "/projects/" + enc(pid) + "/automations/" + enc(id) + "/cancel",
projectTriage: (pid: string) => "/projects/" + enc(pid) + "/triage",
projectTodos: (pid: string) => "/projects/" + enc(pid) + "/todos",
projectTodo: (pid: string, id: string) => "/projects/" + enc(pid) + "/todos/" + enc(id),
workers: "/workers",
environments: (pid: string) => "/environments?project_id=" + enc(pid),
environmentsCreate: "/environments",
environmentArchive: (id: string) => "/environments/" + enc(id) + "/archive",
tasks: (pid: string) => "/tasks?project_id=" + enc(pid),
tasksPage: (pid: string, limit: number, offset: number, status?: string, executor?: string, q?: string, kind?: string) => {
let u = "/tasks?project_id=" + enc(pid) + "&limit=" + limit + "&offset=" + offset + "&order=desc";
if (status) u += "&status=" + enc(status);
if (executor) u += "&executor=" + enc(executor);
if (q && q.trim()) u += "&q=" + enc(q.trim());
if (kind) u += "&kind=" + enc(kind);
return u;
},
tasksByParent: (pid: string, parent: string, kind?: string) => {
let u = "/tasks?project_id=" + enc(pid) + "&parent_task_id=" + enc(parent);
if (kind) u += "&kind=" + enc(kind);
return u;
},
tasksCreate: "/tasks",
task: (id: string) => "/tasks/" + enc(id),
taskAction: (id: string, kind: string) => "/tasks/" + enc(id) + "/" + kind,
taskFork: (id: string) => "/tasks/" + enc(id) + "/fork",
taskContinue: (id: string) => "/tasks/" + enc(id) + "/continue",
taskTrace: (id: string) => "/tasks/" + enc(id) + "/trace",
taskTraceStream: (id: string) => "/tasks/" + enc(id) + "/trace/stream",
taskAgents: (id: string) => "/tasks/" + enc(id) + "/agents",
taskReviews: (id: string) => "/tasks/" + enc(id) + "/reviews",
taskReviewFindings: (id: string, rid: string) => "/tasks/" + enc(id) + "/reviews/" + enc(rid) + "/findings",
taskApprovals: (id: string) => "/tasks/" + enc(id) + "/approvals",
taskApprovalDecision: (id: string, aid: string, verb: string) => "/tasks/" + enc(id) + "/approvals/" + enc(aid) + "/" + verb,
taskFollowups: (id: string) => "/tasks/" + enc(id) + "/followups",
taskChatHistory: (id: string) => "/tasks/" + enc(id) + "/chat-history",
taskMessages: (id: string) => "/tasks/" + enc(id) + "/messages",
taskMessagesTo: (target: string) => "/tasks/" + enc(target) + "/messages",
taskThread: (id: string) => "/tasks/" + enc(id) + "/thread",
taskThreads: (id: string) => "/tasks/" + enc(id) + "/threads",
taskThreadAction: (id: string, kind: string) => "/tasks/" + enc(id) + "/thread/" + kind,
taskCost: (id: string) => "/tasks/" + enc(id) + "/cost",
taskBrowserState: (id: string) => "/tasks/" + enc(id) + "/browser/state",
taskBrowserStream: (id: string) => "/tasks/" + enc(id) + "/browser/stream",
taskBrowserInput: (id: string) => "/tasks/" + enc(id) + "/browser/input",
taskBrowserControl: (id: string) => "/tasks/" + enc(id) + "/browser/control",
uploads: "/uploads",
adminQuotas: "/admin/quotas",
adminQuotaUser: (uid: string) => "/admin/quotas?user_id=" + enc(uid),
adminSweep: "/admin/sweep",
adminBackup: "/admin/backup",
};