From e7aed649493a668b5b09baac4251969667cf7a20 Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" Date: Wed, 13 May 2026 14:59:13 +0000 Subject: [PATCH] chore: generate --- specs/v2/api.html | 750 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 565 insertions(+), 185 deletions(-) diff --git a/specs/v2/api.html b/specs/v2/api.html index c23d7d4f00..147d24f58b 100644 --- a/specs/v2/api.html +++ b/specs/v2/api.html @@ -17,7 +17,13 @@ --accent: #496b5a; --accent-soft: #dce7dc; font-family: - Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + Inter, + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + sans-serif; } * { @@ -34,8 +40,7 @@ background: radial-gradient(circle at 12% 0%, rgba(73, 107, 90, 0.12), transparent 34rem), linear-gradient(90deg, rgba(38, 52, 47, 0.055) 1px, transparent 1px), - linear-gradient(rgba(38, 52, 47, 0.045) 1px, transparent 1px), - var(--bg); + linear-gradient(rgba(38, 52, 47, 0.045) 1px, transparent 1px), var(--bg); background-size: 72px 72px; color: var(--fg); line-height: 1.5; @@ -231,7 +236,13 @@ .diagram text { fill: var(--fg); font-family: - Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + Inter, + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + sans-serif; } .diagram .box { @@ -412,7 +423,10 @@
- Everything has one canonical route. Some routes are server-scoped; runtime routes use context; session item routes use the session. + Everything has one canonical route. Some routes are server-scoped; runtime routes use context; session item + routes use the session.

Server-scoped routes manage the whole server: projects, workspace lifecycle, and auth accounts. Runtime context is for anything resolved from an active directory, including config, provider capabilities, tools, @@ -432,7 +446,9 @@

Context Model

API context resolution - Non-session routes resolve from request context, session item routes resolve from session storage. + + Non-session routes resolve from request context, session item routes resolve from session storage. + @@ -468,8 +484,8 @@

Request-context calls

- These calls operate against a directory, optionally through a workspace. Simple clients omit context and - use the default runtime. + These calls operate against a directory, optionally through a workspace. Simple clients omit context and use + the default runtime.

GET /api/fs/tree?path=.&directory=/repo/app&workspace=ws_123
@@ -491,187 +507,551 @@ sessionID -> { directory, workspaceID? }

Operation Inventory

- The SDK is the source of truth. HTTP routes are mounts for RPC-style operations. server operations do not use runtime context. request operations use request/default runtime context from directory and workspace query parameters. session operations use pinned session context and should not accept context input. + The SDK is the source of truth. HTTP routes are mounts for RPC-style operations. + server operations do not use runtime context. + request operations use request/default runtime context from + directory and workspace query parameters. + session operations use pinned session context and should not accept + context input.

- + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperationInputContextHTTP mountPurpose
OperationInputContextHTTP mountPurpose
agent.list{}requestGET /api/agentAvailable agents.
auth.activate{ accountID: AccountID }serverPOST /api/auth/:accountID/activateSet the account as active for its service.
auth.create{ - serviceID: ServiceID - credential: - | { type: "oauth", refresh: string, access: string, expires: number } - | { type: "api", key: string, metadata?: Record<string, string> } - description?: string - active?: boolean -}serverPOST /api/authCreate an auth account.
auth.delete{ accountID: AccountID }serverDELETE /api/auth/:accountIDRemove an auth account.
auth.get{ accountID: AccountID }serverGET /api/auth/:accountIDGet one auth account.
auth.list{ serviceID?: ServiceID }serverGET /api/authList saved auth accounts. Response includes active account mapping.
auth.update{ - accountID: AccountID - description?: string - credential?: - | { type: "oauth", refresh: string, access: string, expires: number } - | { type: "api", key: string, metadata?: Record<string, string> } -}serverPATCH /api/auth/:accountIDUpdate account description or credential.
catalog.model.get{ - providerID: ProviderID - modelID: ModelID -}serverGET /api/catalog/model/:providerID/:modelIDGet one catalog model.
catalog.model.list{}serverGET /api/catalog/modelList flattened catalog models.
command.list{}requestGET /api/commandAvailable commands.
config.get{}requestGET /api/configResolved config.
config.update{ config: Config }requestPATCH /api/configUpdate config.
event.subscribe{}requestGET /api/eventServer-sent events for the resolved runtime context.
formatter.status{}requestGET /api/formatterFormatter status.
fs.file{ path: string }requestGET /api/fs/fileRead one file.
fs.grep{ - pattern: string - include?: string - limit?: number -}requestPOST /api/fs/grepSearch file contents.
fs.search{ - query: string - type?: "file" | "directory" - limit?: number -}requestPOST /api/fs/searchSearch paths by name.
fs.tree{ path: string }requestGET /api/fs/treeBrowse a directory.
lsp.status{}requestGET /api/lspLSP status.
mcp.prompt.list{}requestGET /api/mcp/promptList MCP prompts.
mcp.prompt.render{ - server: string - name: string - arguments?: Record<string, string> -}requestPOST /api/mcp/prompt/renderRender one MCP prompt.
mcp.resource.list{}requestGET /api/mcp/resourceList MCP resources.
mcp.resource.read{ - server: string - uri: string -}requestGET /api/mcp/resource/readRead one MCP resource.
mcp.server.create{ - name: string - config: - | { type: "local", command: string, arguments?: string[], environment?: Record<string, string> } - | { type: "remote", url: string, headers?: Record<string, string>, oauth?: boolean | object } -}requestPOST /api/mcp/serverAdd an MCP server to runtime config.
mcp.server.list{}requestGET /api/mcp/serverList MCP servers with status and auth state.
mcp.server.oauth.callback{ - name: string - code: string -}requestPOST /api/mcp/server/:name/oauth/callbackComplete MCP OAuth.
mcp.server.oauth.delete{ name: string }requestDELETE /api/mcp/server/:name/oauthRemove MCP OAuth credentials.
mcp.server.oauth.start{ name: string }requestPOST /api/mcp/server/:name/oauthStart MCP OAuth.
permission.list{}requestGET /api/permissionPending permission requests.
permission.reply{ - permissionID: PermissionID - response: PermissionReply -}requestPOST /api/permission/:permissionID/replyReply to a permission request.
project.get{ projectID: ProjectID }serverGET /api/project/:projectIDGet project metadata.
project.list{}serverGET /api/projectList projects known to this server.
project.update{ - projectID: ProjectID - name?: string - icon?: string - commands?: Array<{ - name: string - command: string - }> -}serverPATCH /api/project/:projectIDUpdate project metadata.
provider.list{}requestGET /api/providerProvider inventory for the runtime context.
pty.create{ - command?: string - cwd?: string - shell?: string -}requestPOST /api/ptyCreate PTY in the runtime context.
pty.delete{ ptyID: PtyID }requestDELETE /api/pty/:ptyIDDelete PTY.
pty.get{ ptyID: PtyID }requestGET /api/pty/:ptyIDGet PTY info.
pty.list{}requestGET /api/ptyList PTYs for the runtime.
pty.update{ - ptyID: PtyID - title?: string - size?: { columns: number, rows: number } -}requestPATCH /api/pty/:ptyIDUpdate PTY.
question.list{}requestGET /api/questionPending user questions.
question.reject{ questionID: QuestionID }requestPOST /api/question/:questionID/rejectReject a question.
question.reply{ - questionID: QuestionID - response: QuestionResponse -}requestPOST /api/question/:questionID/replyReply to a question.
session.compact{ sessionID: SessionID }sessionPOST /api/session/:sessionID/compactCompact the session conversation.
session.context{ sessionID: SessionID }sessionGET /api/session/:sessionID/contextReturn active context messages after the last compaction.
session.create{ - title?: string - agent?: string - model?: { providerID: ProviderID, modelID: ModelID } - permission?: PermissionRule[] -}requestPOST /api/sessionCreate a session pinned to resolved runtime context.
session.delete{ sessionID: SessionID }sessionDELETE /api/session/:sessionIDDelete a session.
session.diff{ sessionID: SessionID }sessionGET /api/session/:sessionID/diffReturn session diff summary.
session.get{ sessionID: SessionID }sessionGET /api/session/:sessionIDGet one session.
session.list{ - limit?: number - order?: "asc" | "desc" - path?: string - roots?: boolean - start?: number - search?: string - cursor?: string -}requestGET /api/sessionList sessions for the current runtime context by default.
session.message.list{ - sessionID: SessionID - limit?: number - order?: "asc" | "desc" - cursor?: string -}sessionGET /api/session/:sessionID/messagePage through session messages.
session.prompt{ - sessionID: SessionID - prompt: Prompt - delivery?: "immediate" | "deferred" -}sessionPOST /api/session/:sessionID/promptCreate a user message and queue the agent loop.
session.todo{ sessionID: SessionID }sessionGET /api/session/:sessionID/todoReturn todos associated with the session.
session.update{ - sessionID: SessionID - title?: string - archived?: number - permission?: PermissionRule[] -}sessionPATCH /api/session/:sessionIDUpdate title, archival state, or session metadata.
session.wait{ sessionID: SessionID }sessionPOST /api/session/:sessionID/waitWait until the session is idle.
skill.list{}requestGET /api/skillAvailable skills.
vcs.diff{ - format?: "json" | "patch" - mode?: "worktree" | "default" -}requestGET /api/vcs/diffDiff for the runtime directory.
vcs.get{}requestGET /api/vcsVCS metadata.
vcs.patch{ patch: string }requestPOST /api/vcs/patchApply a patch to the runtime directory.
vcs.status{}requestGET /api/vcs/statusChanged files.
workspace.create{ - projectID?: ProjectID - name?: string - directory?: string - type: string - metadata?: Record<string, unknown> -}serverPOST /api/workspaceCreate or register a workspace.
workspace.delete{ workspaceID: WorkspaceID }serverDELETE /api/workspace/:workspaceIDRemove a workspace registration.
workspace.get{ workspaceID: WorkspaceID }serverGET /api/workspace/:workspaceIDGet workspace metadata.
workspace.list{ projectID?: ProjectID }serverGET /api/workspaceList workspaces, optionally filtered by project.
workspace.status{}serverGET /api/workspace/statusConnection/lifecycle status for all workspaces. Needs team discussion.
workspace.sync{}serverPOST /api/workspace/syncSync workspace metadata from adapters. Needs team discussion.
workspace.update{ - workspaceID: WorkspaceID - name?: string - metadata?: Record<string, unknown> - archived?: boolean -}serverPATCH /api/workspace/:workspaceIDUpdate workspace metadata or lifecycle state.
workspace.warp{ - workspaceID?: WorkspaceID - sessionID: SessionID - copyChanges: boolean -}serverPOST /api/workspace/warpMove a session into or out of a workspace. Needs team discussion.
agent.list{}requestGET /api/agentAvailable agents.
auth.activate{ accountID: AccountID }serverPOST /api/auth/:accountID/activateSet the account as active for its service.
auth.create + { serviceID: ServiceID credential: | { type: "oauth", refresh: string, access: string, expires: + number } | { type: "api", key: string, metadata?: Record<string, string> } description?: + string active?: boolean } + serverPOST /api/authCreate an auth account.
auth.delete{ accountID: AccountID }serverDELETE /api/auth/:accountIDRemove an auth account.
auth.get{ accountID: AccountID }serverGET /api/auth/:accountIDGet one auth account.
auth.list{ serviceID?: ServiceID }serverGET /api/authList saved auth accounts. Response includes active account mapping.
auth.update + { accountID: AccountID description?: string credential?: | { type: "oauth", refresh: string, + access: string, expires: number } | { type: "api", key: string, metadata?: Record<string, + string> } } + serverPATCH /api/auth/:accountIDUpdate account description or credential.
catalog.model.get{ providerID: ProviderID modelID: ModelID }serverGET /api/catalog/model/:providerID/:modelIDGet one catalog model.
catalog.model.list{}serverGET /api/catalog/modelList flattened catalog models.
command.list{}requestGET /api/commandAvailable commands.
config.get{}requestGET /api/configResolved config.
config.update{ config: Config }requestPATCH /api/configUpdate config.
event.subscribe{}requestGET /api/eventServer-sent events for the resolved runtime context.
formatter.status{}requestGET /api/formatterFormatter status.
fs.file{ path: string }requestGET /api/fs/fileRead one file.
fs.grep{ pattern: string include?: string limit?: number }requestPOST /api/fs/grepSearch file contents.
fs.search{ query: string type?: "file" | "directory" limit?: number }requestPOST /api/fs/searchSearch paths by name.
fs.tree{ path: string }requestGET /api/fs/treeBrowse a directory.
lsp.status{}requestGET /api/lspLSP status.
mcp.prompt.list{}requestGET /api/mcp/promptList MCP prompts.
mcp.prompt.render + { server: string name: string arguments?: Record<string, string> } + requestPOST /api/mcp/prompt/renderRender one MCP prompt.
mcp.resource.list{}requestGET /api/mcp/resourceList MCP resources.
mcp.resource.read{ server: string uri: string }requestGET /api/mcp/resource/readRead one MCP resource.
mcp.server.create + { name: string config: | { type: "local", command: string, arguments?: string[], environment?: + Record<string, string> } | { type: "remote", url: string, headers?: Record<string, + string>, oauth?: boolean | object } } + requestPOST /api/mcp/serverAdd an MCP server to runtime config.
mcp.server.list{}requestGET /api/mcp/serverList MCP servers with status and auth state.
mcp.server.oauth.callback{ name: string code: string }requestPOST /api/mcp/server/:name/oauth/callbackComplete MCP OAuth.
mcp.server.oauth.delete{ name: string }requestDELETE /api/mcp/server/:name/oauthRemove MCP OAuth credentials.
mcp.server.oauth.start{ name: string }requestPOST /api/mcp/server/:name/oauthStart MCP OAuth.
permission.list{}requestGET /api/permissionPending permission requests.
permission.reply{ permissionID: PermissionID response: PermissionReply }requestPOST /api/permission/:permissionID/replyReply to a permission request.
project.get{ projectID: ProjectID }serverGET /api/project/:projectIDGet project metadata.
project.list{}serverGET /api/projectList projects known to this server.
project.update + { projectID: ProjectID name?: string icon?: string commands?: Array<{ name: string command: + string }> } + serverPATCH /api/project/:projectIDUpdate project metadata.
provider.list{}requestGET /api/providerProvider inventory for the runtime context.
pty.create{ command?: string cwd?: string shell?: string }requestPOST /api/ptyCreate PTY in the runtime context.
pty.delete{ ptyID: PtyID }requestDELETE /api/pty/:ptyIDDelete PTY.
pty.get{ ptyID: PtyID }requestGET /api/pty/:ptyIDGet PTY info.
pty.list{}requestGET /api/ptyList PTYs for the runtime.
pty.update + { ptyID: PtyID title?: string size?: { columns: number, rows: number } } + requestPATCH /api/pty/:ptyIDUpdate PTY.
question.list{}requestGET /api/questionPending user questions.
question.reject{ questionID: QuestionID }requestPOST /api/question/:questionID/rejectReject a question.
question.reply{ questionID: QuestionID response: QuestionResponse }requestPOST /api/question/:questionID/replyReply to a question.
session.compact{ sessionID: SessionID }sessionPOST /api/session/:sessionID/compactCompact the session conversation.
session.context{ sessionID: SessionID }sessionGET /api/session/:sessionID/contextReturn active context messages after the last compaction.
session.create + { title?: string agent?: string model?: { providerID: ProviderID, modelID: ModelID } permission?: + PermissionRule[] } + requestPOST /api/sessionCreate a session pinned to resolved runtime context.
session.delete{ sessionID: SessionID }sessionDELETE /api/session/:sessionIDDelete a session.
session.diff{ sessionID: SessionID }sessionGET /api/session/:sessionID/diffReturn session diff summary.
session.get{ sessionID: SessionID }sessionGET /api/session/:sessionIDGet one session.
session.list + { limit?: number order?: "asc" | "desc" path?: string roots?: boolean start?: number search?: + string cursor?: string } + requestGET /api/sessionList sessions for the current runtime context by default.
session.message.list + { sessionID: SessionID limit?: number order?: "asc" | "desc" cursor?: string } + sessionGET /api/session/:sessionID/messagePage through session messages.
session.prompt + { sessionID: SessionID prompt: Prompt delivery?: "immediate" | "deferred" } + sessionPOST /api/session/:sessionID/promptCreate a user message and queue the agent loop.
session.todo{ sessionID: SessionID }sessionGET /api/session/:sessionID/todoReturn todos associated with the session.
session.update + { sessionID: SessionID title?: string archived?: number permission?: PermissionRule[] } + sessionPATCH /api/session/:sessionIDUpdate title, archival state, or session metadata.
session.wait{ sessionID: SessionID }sessionPOST /api/session/:sessionID/waitWait until the session is idle.
skill.list{}requestGET /api/skillAvailable skills.
vcs.diff{ format?: "json" | "patch" mode?: "worktree" | "default" }requestGET /api/vcs/diffDiff for the runtime directory.
vcs.get{}requestGET /api/vcsVCS metadata.
vcs.patch{ patch: string }requestPOST /api/vcs/patchApply a patch to the runtime directory.
vcs.status{}requestGET /api/vcs/statusChanged files.
workspace.create + { projectID?: ProjectID name?: string directory?: string type: string metadata?: Record<string, + unknown> } + serverPOST /api/workspaceCreate or register a workspace.
workspace.delete{ workspaceID: WorkspaceID }serverDELETE /api/workspace/:workspaceIDRemove a workspace registration.
workspace.get{ workspaceID: WorkspaceID }serverGET /api/workspace/:workspaceIDGet workspace metadata.
workspace.list{ projectID?: ProjectID }serverGET /api/workspaceList workspaces, optionally filtered by project.
workspace.status{}serverGET /api/workspace/statusConnection/lifecycle status for all workspaces. Needs team discussion.
workspace.sync{}serverPOST /api/workspace/syncSync workspace metadata from adapters. Needs team discussion.
workspace.update + { workspaceID: WorkspaceID name?: string metadata?: Record<string, unknown> archived?: + boolean } + serverPATCH /api/workspace/:workspaceIDUpdate workspace metadata or lifecycle state.
workspace.warp + { workspaceID?: WorkspaceID sessionID: SessionID copyChanges: boolean } + serverPOST /api/workspace/warpMove a session into or out of a workspace. Needs team discussion.
@@ -681,8 +1061,8 @@ sessionID -> { directory, workspaceID? }

Event Envelope

- Every event uses the same envelope. Resource identity belongs in payload. Runtime identity belongs - in context. + Every event uses the same envelope. Resource identity belongs in payload. Runtime identity + belongs in context.

type ApiEvent<Payload> = {