Verdict legend
| build now | Core surface. Maps to an existing contract method or needs one added now. |
| drop | Duplicate, alias, or a Next.js-only artifact with no place in the Go daemon. |
| defer | Niche or one-time; safe to push past Phase 1, or keep CLI-only. |
| reshape | Keep the capability but as a read-model / daemon goroutine, not this shape of route. |
| different lane | Belongs to the SCM poller / webhook ingress, not the session/project API. |
Projects — the stated focus
Legacy paths link to source on ComposioHQ/agent-orchestrator @ main ↗. The New (v1) column is the proposed Go daemon route.
| Method | Legacy path | New (v1) | Purpose | Verdict | Note |
|---|---|---|---|---|---|
| GET | /api/projects | /api/v1/projects | List registered projects | build now | Needs new ProjectManager port |
| POST | /api/projects | /api/v1/projects | Register project — git check, 409 on collision | build now | Structured 409 drives the add-project modal |
| GET | /api/projects/:id | /api/v1/projects/:id | Get one (+ degraded-config payload) | build now | |
| DEL | /api/projects/:id | /api/v1/projects/:id | Unregister + kill sessions + destroy workspaces + rm storage | build now | Composes SessionManager.Kill + Workspace.Destroy |
| POST | /api/projects/:id | /api/v1/projects/:id/repair | Repair wrapped/degraded config | defer | Only if the legacy YAML-wrapping is carried forward |
| POST | /api/projects/reload | — none | Invalidate cache + reload config from disk | drop | A Next.js in-process cache hack; a Go daemon reads config differently |
Projects — API contract (request / response shapes)
GET /api/v1/projects
build now→ req (none)
← 200 { projects: [ { id, name, sessionPrefix, resolveError? } ] }
← 500 { error }
POST /api/v1/projects
build now→ req { path: string (required), projectId?: string, name?: string }
← 201 { ok: true, projectId: string }
← 400 { error } // invalid JSON · missing path · not a git repo
← 409 { error, existingProjectId, suggestedProjectId, suggestion: "choose-project-id" }
GET /api/v1/projects/:id
build now→ req (none)
← 200 { project: { id, name, path, repo, defaultBranch, agent?, runtime?, tracker?, scm?, reactions? } }
← 200 { error, projectId, degraded: true, project: { id, name, path, resolveError } } // degraded state
← 404 { error: "Unknown project: {id}" }
← 500 { error }
PATCH /api/v1/projects/:id
verify→ req { agent?, runtime?, tracker?, scm?, reactions? } // identity fields (projectId/path/repo/defaultBranch) frozen
← 200 { ok: true }
← 400 { error } // frozen identity field · invalid JSON · malformed local config
← 404 { error } // unknown project
← 409 { error } // degraded / missing registry path
← 500 { error }
⚠ verify: confirm the dashboard actually issues this PATCH before building it — it may be unused in practice.
DELETE /api/v1/projects/:id
build now→ req (none)
← 200 { ok: true, projectId, removedStorageDir: boolean }
← 400 { error } // invalid project id (path-traversal guard)
← 404 { error } // unknown project
← 500 { error }
POST /api/v1/projects/:id/repair
defer→ req (none)
← 200 { ok: true, repaired: true, projectId }
← 400 { error } // not degraded · not auto-repairable
← 404 { error } // unknown project
← 500 { error }
POST /api/projects/reload
drop→ req (none)
← 200 { reloaded: true, projectCount, degradedCount }
← 500 { error }
// legacy only — no v1 equivalent; the Go daemon reloads config differently
Sessions — mostly covered by SessionManager
Legacy paths link to source on ComposioHQ/agent-orchestrator @ main ↗. New (v1) is the proposed Go daemon route; Maps to is the
SessionManager method.| Method | Legacy path | New (v1) | Maps to | Verdict | Note |
|---|---|---|---|---|---|
| POST | /api/spawn | /api/v1/sessions | Spawn | build now | |
| GET | /api/sessions | /api/v1/sessions | List | build now | ?project, ?active, ?orchestratorOnly, ?fresh filters |
| GET | /api/sessions/:id | /api/v1/sessions/:id | Get | build now | |
| POST | /api/sessions/:id/kill | /api/v1/sessions/:id/kill | Kill | build now | |
| POST | /api/sessions/:id/restore | /api/v1/sessions/:id/restore | Restore | build now | |
| POST | /api/sessions/:id/send | /api/v1/sessions/:id/send | Send | build now | Strips control chars before runtime inject |
| POST | /api/sessions/:id/message | — none | Send (dup) | drop | Identical to /send — both call sessionManager.send |
| PATCH | /api/sessions/:id | /api/v1/sessions/:id (PATCH) | — (gap) | build now | Rename only (displayName). No inbound method — add Rename/SetMetadata → PatchMetadata |
| POST | /api/sessions/:id/remap | /api/v1/sessions/:id/remap | — | defer | OpenCode-specific dead-session recovery; keep only if the new agent needs it |
| GET | /api/sessions/patches | /api/v1/sessions/patches | — | reshape | Lightweight diff read-model — belongs in a query layer, not SessionManager |
| POST | /api/orchestrators | /api/v1/orchestrators | — (gap) | build now | Spawn/relaunch orchestrator. Decide: a SessionKind on Spawn, or a dedicated method |
SessionManager.Cleanup has no legacy HTTP route of its own — it's reached today through the project DELETE path. Decide whether to expose it directly.Sessions — API contract (request / response shapes)
POST /api/v1/sessions
build now→ req { projectId: string (required), issueId?: string, prompt?: string (≤ 4096) }
← 201 { session }
← 400 { error } // missing projectId · prompt too long
← 404 { error } // unknown project
← 500 { error }
GET /api/v1/sessions
build now→ req ?project= &?active= &?orchestratorOnly= &?fresh=
← 200 { sessions: [ … ] }
GET /api/v1/sessions/:id
build now→ req (none)
← 200 { session } // dashboard session read-model
← 404 { error }
POST /api/v1/sessions/:id/kill
build now→ req (none)
← 200 { ok: true, sessionId }
← 404 { error }
POST /api/v1/sessions/:id/restore
build now→ req (none)
← 200 { ok: true, sessionId, session }
← 404 { error } // unknown session
← 409 { error } // not restorable in current state
← 422 { error } // restore preconditions unmet
POST /api/v1/sessions/:id/send
build now→ req { message: string (required, ≤ MAX) }
← 200 { ok: true, sessionId, message }
← 400 { error } // empty / too long
← 404 { error }
PATCH /api/v1/sessions/:id
build now→ req { displayName: string } // rename only
← 200 { session }
← 400 { error }
← 404 { error }
// gap: needs a Rename / SetMetadata inbound method → LifecycleStore.PatchMetadata
// (must never write the derived display status)
POST /api/v1/sessions/:id/remap
defer→ req { opencodeSessionId: string }
← 200 { ok: true }
← 404 { error } // unknown session
← 422 { error } // remap not applicable
// OpenCode-specific dead-session recovery; only if the new agent needs it
GET /api/v1/sessions/patches
reshape→ req (none)
← 200 { sessions: [ …patch read-model… ] }
// reshape into a query / read-model layer, not SessionManager
POST /api/v1/orchestrators
build now→ req { projectId: string (required), clean?: boolean }
← 201 { orchestrator: { id, projectId, projectName } }
← 400 { error } // missing projectId
← 404 { error } // unknown project
// clean=true → relaunchOrchestrator; else spawnOrchestrator
SCM / issues / PRs — a different lane
Legacy paths link to source on ComposioHQ/agent-orchestrator @ main ↗. These belong to the SCM poller / webhook ingress, not the session/project API — so most have no
/api/v1 session-route equivalent.| Method | Legacy path | New (v1) | Purpose | Verdict | Note |
|---|---|---|---|---|---|
| POST | /api/prs/:id/merge | — SCM lane | Merge a PR | different lane | SCM action |
| POST | /api/prs/:id/resolve-comments | — SCM lane | Resolve review comments on a PR | different lane | SCM action |
SCM — API contract (request / response shapes — for the SCM lane to own)
POST /api/prs/:id/merge
SCM lane→ req (none)
← 200 { ok: true, prNumber, method: "squash" }
← 404 { error } // unknown PR
← 409 { error } // not mergeable
← 422 { error } // merge preconditions unmet
POST /api/prs/:id/resolve-comments
SCM lane→ req { commentIds?: string[] } // omit to resolve all
← 200 { ok: true, resolved: number }
← 404 { error } // unknown PR
← 422 { error } // nothing to resolve
Platform / infra
Legacy paths link to source on ComposioHQ/agent-orchestrator @ main ↗. The New (v1) column shows the proposed Go route — several are CLI/desktop concerns with no daemon REST equivalent.
| Method | Legacy path | New (v1) | Purpose | Verdict | Note |
|---|---|---|---|---|---|
| GET | /api/observability | /api/v1/observability | Observability / metrics | reshape | Read-model / metrics endpoint |
| GET | /api/version | — none | AO version + update channel | drop | CLI / desktop self-update concern |
| POST | /api/update | — none | Kick off ao update | drop | Not the daemon's REST surface |
| GET | /api/filesystem/browse | /api/v1/filesystem/browse | Directory picker for add-project | defer | Keep one browse route |
| GET | /api/browse-directory | — none | 307 redirect → filesystem/browse | drop | Redundant alias |
| GET | /api/runtime/terminal | /mux (P4) | Terminal runtime info | reshape | Tied to the tmux/PTY (WebSocket) lane — Phase 4 |
Platform — API contract (request / response shapes)
GET /api/v1/observability
reshape→ req (none)
← 200 { …metrics / health summary… }
GET /api/version
drop→ req (none)
← 200 { current, latest, channel, …, checkedAt }
// CLI / desktop self-update concern — not the daemon's REST surface
POST /api/update
drop→ req (none)
← 202 { ok: true, message } // update kicked off
← 409 { ok: false, message } // refuses while active sessions exist
GET /api/v1/filesystem/browse
defer→ req ?path=~ // ~ expands to home
← 200 { entries: [ … ] }
← 400 { error } // invalid path
← 404 { error } // not found
GET /api/browse-directory
drop← 307 → /api/filesystem/browse
// redundant alias
GET /api/runtime/terminal
reshape → P4→ req (none)
← 200 { terminalPort, directTerminalPort, proxyWsPath }
// folds into the tmux/PTY WebSocket lane (/mux) in Phase 4
Recommendation — at a glance
Build now
core
All
/projects CRUD (new ProjectManager port) · session
spawn / list / get / kill / restore / send · plus two contract additions: session
rename and orchestrator spawn.
Drop
cut/sessions/:id/message (dup) · /projects/reload (cache hack) ·
/version + /update (CLI) · /browse-directory (alias).
Defer
later
Project repair · session remap · setup-labels · filesystem browse.
Different lane
SCM
issues · backlog · verify · PR merge · webhooks · observability — SCM-poller &
read-model concerns. Webhooks/pollers feed
ApplySCMObservation; they aren't
pulled through REST handlers.