Buckets:
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>opencode v2 API</title> | |
| <style> | |
| :root { | |
| --bg: #f6f1e8; | |
| --fg: #1f2723; | |
| --muted: #6f756d; | |
| --dim: #ebe3d6; | |
| --panel: #fffaf1; | |
| --line: #26342f; | |
| --thin: #d6ccbd; | |
| --code: #eee5d8; | |
| --accent: #496b5a; | |
| --accent-soft: #dce7dc; | |
| font-family: | |
| Inter, | |
| ui-sans-serif, | |
| system-ui, | |
| -apple-system, | |
| BlinkMacSystemFont, | |
| "Segoe UI", | |
| sans-serif; | |
| } | |
| * { | |
| box-sizing: border-box; | |
| } | |
| html { | |
| background: var(--bg); | |
| color: var(--fg); | |
| } | |
| body { | |
| margin: 0; | |
| 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); | |
| background-size: 72px 72px; | |
| color: var(--fg); | |
| line-height: 1.5; | |
| } | |
| main { | |
| width: 100%; | |
| padding: 40px 32px 72px; | |
| } | |
| header { | |
| display: grid; | |
| grid-template-columns: minmax(0, 1.25fr) minmax(360px, 0.75fr); | |
| gap: 32px; | |
| align-items: end; | |
| border-bottom: 2px solid var(--line); | |
| padding-bottom: 32px; | |
| } | |
| h1, | |
| h2, | |
| h3, | |
| p { | |
| margin: 0; | |
| } | |
| h1 { | |
| max-width: 1180px; | |
| font-size: clamp(4rem, 12vw, 13rem); | |
| line-height: 0.82; | |
| letter-spacing: -0.09em; | |
| } | |
| h2 { | |
| font-size: clamp(1.75rem, 4vw, 4rem); | |
| line-height: 0.95; | |
| letter-spacing: -0.07em; | |
| } | |
| h3 { | |
| font-size: 0.78rem; | |
| letter-spacing: 0.12em; | |
| text-transform: uppercase; | |
| } | |
| code, | |
| pre { | |
| font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; | |
| } | |
| code { | |
| border: 1px solid var(--thin); | |
| padding: 1px 5px; | |
| background: var(--code); | |
| color: var(--fg); | |
| font-size: 0.9em; | |
| } | |
| pre { | |
| overflow: auto; | |
| margin: 0; | |
| border: 1px solid var(--line); | |
| padding: 16px; | |
| background: var(--code); | |
| color: var(--fg); | |
| font-size: 0.92rem; | |
| line-height: 1.5; | |
| } | |
| pre code { | |
| border: 0; | |
| padding: 0; | |
| background: transparent; | |
| font-size: inherit; | |
| } | |
| section { | |
| margin-top: 34px; | |
| } | |
| .eyebrow { | |
| display: inline-block; | |
| border: 1px solid var(--line); | |
| margin-bottom: 18px; | |
| padding: 5px 8px; | |
| font-size: 0.78rem; | |
| font-weight: 800; | |
| letter-spacing: 0.12em; | |
| text-transform: uppercase; | |
| } | |
| .lede { | |
| max-width: 620px; | |
| color: var(--muted); | |
| font-size: 1.15rem; | |
| } | |
| .panel { | |
| border: 2px solid var(--line); | |
| background: rgba(255, 250, 241, 0.92); | |
| box-shadow: 0 20px 50px rgba(31, 39, 35, 0.08); | |
| } | |
| .panel-pad { | |
| padding: 22px; | |
| } | |
| .grid { | |
| display: grid; | |
| grid-template-columns: repeat(12, minmax(0, 1fr)); | |
| gap: 18px; | |
| } | |
| .span-12 { | |
| grid-column: span 12; | |
| } | |
| .span-8 { | |
| grid-column: span 8; | |
| } | |
| .span-6 { | |
| grid-column: span 6; | |
| } | |
| .span-4 { | |
| grid-column: span 4; | |
| } | |
| .stack { | |
| display: grid; | |
| gap: 16px; | |
| } | |
| .muted { | |
| color: var(--muted); | |
| } | |
| .rule { | |
| display: grid; | |
| gap: 16px; | |
| border: 2px solid var(--line); | |
| padding: 22px; | |
| background: var(--accent); | |
| color: #fffaf1; | |
| } | |
| .rule strong { | |
| font-size: clamp(1.45rem, 3vw, 2.45rem); | |
| line-height: 1; | |
| letter-spacing: -0.06em; | |
| } | |
| .rule code { | |
| border-color: var(--bg); | |
| background: rgba(255, 250, 241, 0.18); | |
| color: #fffaf1; | |
| } | |
| .key { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 8px; | |
| } | |
| .pill { | |
| display: inline-flex; | |
| align-items: center; | |
| width: fit-content; | |
| border: 1px solid var(--line); | |
| padding: 4px 8px; | |
| background: var(--panel); | |
| color: var(--fg); | |
| font-size: 0.75rem; | |
| font-weight: 900; | |
| letter-spacing: 0.08em; | |
| text-transform: uppercase; | |
| } | |
| .pill.inverse { | |
| background: var(--accent); | |
| color: #fffaf1; | |
| } | |
| .diagram { | |
| display: block; | |
| width: 100%; | |
| height: auto; | |
| border: 2px solid var(--line); | |
| background: var(--panel); | |
| } | |
| .diagram text { | |
| fill: var(--fg); | |
| font-family: | |
| Inter, | |
| ui-sans-serif, | |
| system-ui, | |
| -apple-system, | |
| BlinkMacSystemFont, | |
| "Segoe UI", | |
| sans-serif; | |
| } | |
| .diagram .box { | |
| fill: var(--panel); | |
| stroke: var(--fg); | |
| stroke-width: 2; | |
| } | |
| .diagram .fill { | |
| fill: var(--accent); | |
| stroke: var(--accent); | |
| stroke-width: 2; | |
| } | |
| .diagram .fill-text { | |
| fill: #fffaf1; | |
| } | |
| .diagram .line { | |
| stroke: var(--fg); | |
| stroke-width: 2; | |
| fill: none; | |
| marker-end: url(#arrow); | |
| } | |
| table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| border: 2px solid var(--line); | |
| background: var(--panel); | |
| } | |
| th, | |
| td { | |
| border: 1px solid var(--thin); | |
| padding: 11px 12px; | |
| text-align: left; | |
| vertical-align: top; | |
| } | |
| th { | |
| border-bottom: 2px solid var(--line); | |
| background: var(--accent); | |
| color: #fffaf1; | |
| font-size: 0.75rem; | |
| letter-spacing: 0.12em; | |
| text-transform: uppercase; | |
| } | |
| td.route { | |
| width: 34%; | |
| white-space: nowrap; | |
| } | |
| td.body { | |
| width: 28%; | |
| } | |
| td.body code { | |
| display: block; | |
| white-space: pre-wrap; | |
| line-height: 1.45; | |
| } | |
| td.method { | |
| width: 72px; | |
| font-weight: 900; | |
| letter-spacing: 0.06em; | |
| } | |
| td.context { | |
| width: 150px; | |
| } | |
| td.operation { | |
| width: 210px; | |
| white-space: nowrap; | |
| } | |
| .context-tag { | |
| display: inline-block; | |
| border: 1px solid var(--line); | |
| padding: 3px 7px; | |
| font-size: 0.72rem; | |
| font-weight: 900; | |
| letter-spacing: 0.07em; | |
| text-transform: uppercase; | |
| } | |
| tr.question-row td { | |
| background: #f7e8b7; | |
| } | |
| .request { | |
| background: var(--accent); | |
| color: #fffaf1; | |
| } | |
| .session { | |
| background: var(--panel); | |
| color: var(--fg); | |
| } | |
| .server { | |
| background: var(--dim); | |
| color: var(--fg); | |
| } | |
| .note { | |
| border-left: 6px solid var(--line); | |
| padding: 14px 18px; | |
| background: var(--dim); | |
| } | |
| .toc { | |
| display: grid; | |
| gap: 8px; | |
| } | |
| .toc a { | |
| display: flex; | |
| justify-content: space-between; | |
| gap: 16px; | |
| border-bottom: 1px solid var(--thin); | |
| padding: 8px 0; | |
| color: var(--fg); | |
| text-decoration: none; | |
| } | |
| .toc span { | |
| color: var(--muted); | |
| } | |
| @media (max-width: 980px) { | |
| main { | |
| padding: 28px 16px 56px; | |
| } | |
| header, | |
| .grid { | |
| grid-template-columns: 1fr; | |
| } | |
| .span-12, | |
| .span-8, | |
| .span-6, | |
| .span-4 { | |
| grid-column: 1 / -1; | |
| } | |
| table { | |
| display: block; | |
| overflow-x: auto; | |
| white-space: nowrap; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <main> | |
| <header> | |
| <div> | |
| <div class="eyebrow">opencode v2</div> | |
| <h1>API map</h1> | |
| </div> | |
| <div class="stack"> | |
| <p class="lede"> | |
| A single <code>/api</code> route surface for simple clients and multi-directory frontends. The important | |
| design question is not route nesting; it is where runtime context comes from. | |
| </p> | |
| <div class="key"> | |
| <span class="pill">Server scoped</span> | |
| <span class="pill inverse">Request context</span> | |
| <span class="pill">Session pinned</span> | |
| </div> | |
| </div> | |
| </header> | |
| <section class="grid"> | |
| <article class="span-8 rule"> | |
| <strong | |
| >Everything has one canonical route. Some routes are server-scoped; runtime routes use context; session item | |
| routes use the session.</strong | |
| > | |
| <p> | |
| 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, | |
| files, and VCS. | |
| </p> | |
| </article> | |
| <nav class="span-4 panel panel-pad toc" aria-label="Page sections"> | |
| <a href="#context"><strong>Context Model</strong><span>how calls resolve</span></a> | |
| <a href="#endpoints"><strong>Endpoint Inventory</strong><span>all planned routes</span></a> | |
| <a href="#events"><strong>Events</strong><span>one envelope</span></a> | |
| <a href="#store"><strong>Frontend Store</strong><span>sync model</span></a> | |
| </nav> | |
| </section> | |
| <section id="context" class="grid"> | |
| <div class="span-12 stack"> | |
| <h2>Context Model</h2> | |
| <svg class="diagram" viewBox="0 0 1280 360" role="img" aria-labelledby="ctx-title ctx-desc"> | |
| <title id="ctx-title">API context resolution</title> | |
| <desc id="ctx-desc"> | |
| Non-session routes resolve from request context, session item routes resolve from session storage. | |
| </desc> | |
| <defs> | |
| <marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto"> | |
| <path d="M0,0 L0,6 L9,3 z" fill="#26342f" /> | |
| </marker> | |
| </defs> | |
| <rect class="fill" x="34" y="44" width="294" height="96" /> | |
| <text class="fill-text" x="58" y="84" font-size="24" font-weight="900">Non-session route</text> | |
| <text class="fill-text" x="58" y="116" font-size="17">/api/file, /api/vcs/status</text> | |
| <path class="line" d="M328 92 H472" /> | |
| <rect class="box" x="486" y="44" width="286" height="96" /> | |
| <text x="510" y="84" font-size="24" font-weight="900">Request context</text> | |
| <text x="510" y="116" font-size="17">query params or default runtime</text> | |
| <path class="line" d="M772 92 H916" /> | |
| <rect class="box" x="930" y="44" width="316" height="96" /> | |
| <text x="954" y="84" font-size="24" font-weight="900">Runtime context</text> | |
| <text x="954" y="116" font-size="17">directory + workspaceID?</text> | |
| <rect class="box" x="34" y="220" width="294" height="96" /> | |
| <text x="58" y="260" font-size="24" font-weight="900">Session item route</text> | |
| <text x="58" y="292" font-size="17">/api/session/:id/prompt</text> | |
| <path class="line" d="M328 268 H472" /> | |
| <rect class="fill" x="486" y="220" width="286" height="96" /> | |
| <text class="fill-text" x="510" y="260" font-size="24" font-weight="900">Session row</text> | |
| <text class="fill-text" x="510" y="292" font-size="17">contains pinned context</text> | |
| <path class="line" d="M772 268 H916" /> | |
| <rect class="box" x="930" y="220" width="316" height="96" /> | |
| <text x="954" y="260" font-size="24" font-weight="900">Runtime context</text> | |
| <text x="954" y="292" font-size="17">directory + workspaceID?</text> | |
| </svg> | |
| </div> | |
| <article class="span-6 panel panel-pad stack"> | |
| <h3>Request-context calls</h3> | |
| <p class="muted"> | |
| These calls operate against a directory, optionally through a workspace. Simple clients omit context and use | |
| the default runtime. | |
| </p> | |
| <pre><code>GET /api/fs/tree?path=.&directory=/repo/app&workspace=ws_123</code></pre> | |
| </article> | |
| <article class="span-6 panel panel-pad stack"> | |
| <h3>Session-pinned calls</h3> | |
| <p class="muted"> | |
| These calls never take request context. The session is already pinned to the directory and workspace it was | |
| created in. | |
| </p> | |
| <pre><code>POST /api/session/ses_123/prompt | |
| // server resolves | |
| sessionID -> { directory, workspaceID? }</code></pre> | |
| </article> | |
| </section> | |
| <section id="endpoints" class="grid"> | |
| <div class="span-12 stack"> | |
| <h2>Operation Inventory</h2> | |
| <p class="muted"> | |
| The SDK is the source of truth. HTTP routes are mounts for RPC-style operations. | |
| <span class="context-tag server">server</span> operations do not use runtime context. | |
| <span class="context-tag request">request</span> operations use request/default runtime context from | |
| <code>directory</code> and <code>workspace</code> query parameters. | |
| <span class="context-tag session">session</span> operations use pinned session context and should not accept | |
| context input. | |
| </p> | |
| </div> | |
| <article class="span-12 panel panel-pad stack"> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Operation</th> | |
| <th>Input</th> | |
| <th>Context</th> | |
| <th>HTTP mount</th> | |
| <th>Purpose</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td class="operation"><code>agent.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/agent</code></td> | |
| <td>Available agents.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>auth.activate</code></td> | |
| <td class="body"><code>{ accountID: AccountID }</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>POST /api/auth/:accountID/activate</code></td> | |
| <td>Set the account as active for its service.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>auth.create</code></td> | |
| <td class="body"> | |
| <code | |
| >{ serviceID: ServiceID credential: | { type: "oauth", refresh: string, access: string, expires: | |
| number } | { type: "api", key: string, metadata?: Record<string, string> } description?: | |
| string active?: boolean }</code | |
| > | |
| </td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>POST /api/auth</code></td> | |
| <td>Create an auth account.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>auth.delete</code></td> | |
| <td class="body"><code>{ accountID: AccountID }</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>DELETE /api/auth/:accountID</code></td> | |
| <td>Remove an auth account.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>auth.get</code></td> | |
| <td class="body"><code>{ accountID: AccountID }</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>GET /api/auth/:accountID</code></td> | |
| <td>Get one auth account.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>auth.list</code></td> | |
| <td class="body"><code>{ serviceID?: ServiceID }</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>GET /api/auth</code></td> | |
| <td>List saved auth accounts. Response includes active account mapping.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>auth.update</code></td> | |
| <td class="body"> | |
| <code | |
| >{ accountID: AccountID description?: string credential?: | { type: "oauth", refresh: string, | |
| access: string, expires: number } | { type: "api", key: string, metadata?: Record<string, | |
| string> } }</code | |
| > | |
| </td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>PATCH /api/auth/:accountID</code></td> | |
| <td>Update account description or credential.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>catalog.model.get</code></td> | |
| <td class="body"><code>{ providerID: ProviderID modelID: ModelID }</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>GET /api/catalog/model/:providerID/:modelID</code></td> | |
| <td>Get one catalog model.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>catalog.model.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>GET /api/catalog/model</code></td> | |
| <td>List flattened catalog models.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>command.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/command</code></td> | |
| <td>Available commands.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>config.get</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/config</code></td> | |
| <td>Resolved config.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>config.update</code></td> | |
| <td class="body"><code>{ config: Config }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>PATCH /api/config</code></td> | |
| <td>Update config.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>event.subscribe</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/event</code></td> | |
| <td>Server-sent events for the resolved runtime context.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>formatter.status</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/formatter</code></td> | |
| <td>Formatter status.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>fs.file</code></td> | |
| <td class="body"><code>{ path: string }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/fs/file</code></td> | |
| <td>Read one file.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>fs.grep</code></td> | |
| <td class="body"><code>{ pattern: string include?: string limit?: number }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/fs/grep</code></td> | |
| <td>Search file contents.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>fs.search</code></td> | |
| <td class="body"><code>{ query: string type?: "file" | "directory" limit?: number }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/fs/search</code></td> | |
| <td>Search paths by name.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>fs.tree</code></td> | |
| <td class="body"><code>{ path: string }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/fs/tree</code></td> | |
| <td>Browse a directory.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>lsp.status</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/lsp</code></td> | |
| <td>LSP status.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>mcp.prompt.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/mcp/prompt</code></td> | |
| <td>List MCP prompts.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>mcp.prompt.render</code></td> | |
| <td class="body"> | |
| <code>{ server: string name: string arguments?: Record<string, string> }</code> | |
| </td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/mcp/prompt/render</code></td> | |
| <td>Render one MCP prompt.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>mcp.resource.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/mcp/resource</code></td> | |
| <td>List MCP resources.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>mcp.resource.read</code></td> | |
| <td class="body"><code>{ server: string uri: string }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/mcp/resource/read</code></td> | |
| <td>Read one MCP resource.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>mcp.server.create</code></td> | |
| <td class="body"> | |
| <code | |
| >{ name: string config: | { type: "local", command: string, arguments?: string[], environment?: | |
| Record<string, string> } | { type: "remote", url: string, headers?: Record<string, | |
| string>, oauth?: boolean | object } }</code | |
| > | |
| </td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/mcp/server</code></td> | |
| <td>Add an MCP server to runtime config.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>mcp.server.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/mcp/server</code></td> | |
| <td>List MCP servers with status and auth state.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>mcp.server.oauth.callback</code></td> | |
| <td class="body"><code>{ name: string code: string }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/mcp/server/:name/oauth/callback</code></td> | |
| <td>Complete MCP OAuth.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>mcp.server.oauth.delete</code></td> | |
| <td class="body"><code>{ name: string }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>DELETE /api/mcp/server/:name/oauth</code></td> | |
| <td>Remove MCP OAuth credentials.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>mcp.server.oauth.start</code></td> | |
| <td class="body"><code>{ name: string }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/mcp/server/:name/oauth</code></td> | |
| <td>Start MCP OAuth.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>permission.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/permission</code></td> | |
| <td>Pending permission requests.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>permission.reply</code></td> | |
| <td class="body"><code>{ permissionID: PermissionID response: PermissionReply }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/permission/:permissionID/reply</code></td> | |
| <td>Reply to a permission request.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>project.get</code></td> | |
| <td class="body"><code>{ projectID: ProjectID }</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>GET /api/project/:projectID</code></td> | |
| <td>Get project metadata.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>project.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>GET /api/project</code></td> | |
| <td>List projects known to this server.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>project.update</code></td> | |
| <td class="body"> | |
| <code | |
| >{ projectID: ProjectID name?: string icon?: string commands?: Array<{ name: string command: | |
| string }> }</code | |
| > | |
| </td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>PATCH /api/project/:projectID</code></td> | |
| <td>Update project metadata.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>provider.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/provider</code></td> | |
| <td>Provider inventory for the runtime context.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>pty.create</code></td> | |
| <td class="body"><code>{ command?: string cwd?: string shell?: string }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/pty</code></td> | |
| <td>Create PTY in the runtime context.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>pty.delete</code></td> | |
| <td class="body"><code>{ ptyID: PtyID }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>DELETE /api/pty/:ptyID</code></td> | |
| <td>Delete PTY.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>pty.get</code></td> | |
| <td class="body"><code>{ ptyID: PtyID }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/pty/:ptyID</code></td> | |
| <td>Get PTY info.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>pty.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/pty</code></td> | |
| <td>List PTYs for the runtime.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>pty.update</code></td> | |
| <td class="body"> | |
| <code>{ ptyID: PtyID title?: string size?: { columns: number, rows: number } }</code> | |
| </td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>PATCH /api/pty/:ptyID</code></td> | |
| <td>Update PTY.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>question.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/question</code></td> | |
| <td>Pending user questions.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>question.reject</code></td> | |
| <td class="body"><code>{ questionID: QuestionID }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/question/:questionID/reject</code></td> | |
| <td>Reject a question.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>question.reply</code></td> | |
| <td class="body"><code>{ questionID: QuestionID response: QuestionResponse }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/question/:questionID/reply</code></td> | |
| <td>Reply to a question.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.compact</code></td> | |
| <td class="body"><code>{ sessionID: SessionID }</code></td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>POST /api/session/:sessionID/compact</code></td> | |
| <td>Compact the session conversation.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.context</code></td> | |
| <td class="body"><code>{ sessionID: SessionID }</code></td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>GET /api/session/:sessionID/context</code></td> | |
| <td>Return active context messages after the last compaction.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.create</code></td> | |
| <td class="body"> | |
| <code | |
| >{ title?: string agent?: string model?: { providerID: ProviderID, modelID: ModelID } permission?: | |
| PermissionRule[] }</code | |
| > | |
| </td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/session</code></td> | |
| <td>Create a session pinned to resolved runtime context.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.delete</code></td> | |
| <td class="body"><code>{ sessionID: SessionID }</code></td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>DELETE /api/session/:sessionID</code></td> | |
| <td>Delete a session.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.diff</code></td> | |
| <td class="body"><code>{ sessionID: SessionID }</code></td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>GET /api/session/:sessionID/diff</code></td> | |
| <td>Return session diff summary.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.get</code></td> | |
| <td class="body"><code>{ sessionID: SessionID }</code></td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>GET /api/session/:sessionID</code></td> | |
| <td>Get one session.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.list</code></td> | |
| <td class="body"> | |
| <code | |
| >{ limit?: number order?: "asc" | "desc" path?: string roots?: boolean start?: number search?: | |
| string cursor?: string }</code | |
| > | |
| </td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/session</code></td> | |
| <td>List sessions for the current runtime context by default.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.message.list</code></td> | |
| <td class="body"> | |
| <code>{ sessionID: SessionID limit?: number order?: "asc" | "desc" cursor?: string }</code> | |
| </td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>GET /api/session/:sessionID/message</code></td> | |
| <td>Page through session messages.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.prompt</code></td> | |
| <td class="body"> | |
| <code>{ sessionID: SessionID prompt: Prompt delivery?: "immediate" | "deferred" }</code> | |
| </td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>POST /api/session/:sessionID/prompt</code></td> | |
| <td>Create a user message and queue the agent loop.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.todo</code></td> | |
| <td class="body"><code>{ sessionID: SessionID }</code></td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>GET /api/session/:sessionID/todo</code></td> | |
| <td>Return todos associated with the session.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.update</code></td> | |
| <td class="body"> | |
| <code>{ sessionID: SessionID title?: string archived?: number permission?: PermissionRule[] }</code> | |
| </td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>PATCH /api/session/:sessionID</code></td> | |
| <td>Update title, archival state, or session metadata.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>session.wait</code></td> | |
| <td class="body"><code>{ sessionID: SessionID }</code></td> | |
| <td><span class="context-tag session">session</span></td> | |
| <td class="route"><code>POST /api/session/:sessionID/wait</code></td> | |
| <td>Wait until the session is idle.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>skill.list</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/skill</code></td> | |
| <td>Available skills.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>vcs.diff</code></td> | |
| <td class="body"><code>{ format?: "json" | "patch" mode?: "worktree" | "default" }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/vcs/diff</code></td> | |
| <td>Diff for the runtime directory.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>vcs.get</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/vcs</code></td> | |
| <td>VCS metadata.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>vcs.patch</code></td> | |
| <td class="body"><code>{ patch: string }</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>POST /api/vcs/patch</code></td> | |
| <td>Apply a patch to the runtime directory.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>vcs.status</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag request">request</span></td> | |
| <td class="route"><code>GET /api/vcs/status</code></td> | |
| <td>Changed files.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>workspace.create</code></td> | |
| <td class="body"> | |
| <code | |
| >{ projectID?: ProjectID name?: string directory?: string type: string metadata?: Record<string, | |
| unknown> }</code | |
| > | |
| </td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>POST /api/workspace</code></td> | |
| <td>Create or register a workspace.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>workspace.delete</code></td> | |
| <td class="body"><code>{ workspaceID: WorkspaceID }</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>DELETE /api/workspace/:workspaceID</code></td> | |
| <td>Remove a workspace registration.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>workspace.get</code></td> | |
| <td class="body"><code>{ workspaceID: WorkspaceID }</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>GET /api/workspace/:workspaceID</code></td> | |
| <td>Get workspace metadata.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>workspace.list</code></td> | |
| <td class="body"><code>{ projectID?: ProjectID }</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>GET /api/workspace</code></td> | |
| <td>List workspaces, optionally filtered by project.</td> | |
| </tr> | |
| <tr class="question-row"> | |
| <td class="operation"><code>workspace.status</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>GET /api/workspace/status</code></td> | |
| <td>Connection/lifecycle status for all workspaces. Needs team discussion.</td> | |
| </tr> | |
| <tr class="question-row"> | |
| <td class="operation"><code>workspace.sync</code></td> | |
| <td class="body"><code>{}</code></td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>POST /api/workspace/sync</code></td> | |
| <td>Sync workspace metadata from adapters. Needs team discussion.</td> | |
| </tr> | |
| <tr> | |
| <td class="operation"><code>workspace.update</code></td> | |
| <td class="body"> | |
| <code | |
| >{ workspaceID: WorkspaceID name?: string metadata?: Record<string, unknown> archived?: | |
| boolean }</code | |
| > | |
| </td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>PATCH /api/workspace/:workspaceID</code></td> | |
| <td>Update workspace metadata or lifecycle state.</td> | |
| </tr> | |
| <tr class="question-row"> | |
| <td class="operation"><code>workspace.warp</code></td> | |
| <td class="body"> | |
| <code>{ workspaceID?: WorkspaceID sessionID: SessionID copyChanges: boolean }</code> | |
| </td> | |
| <td><span class="context-tag server">server</span></td> | |
| <td class="route"><code>POST /api/workspace/warp</code></td> | |
| <td>Move a session into or out of a workspace. Needs team discussion.</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </article> | |
| </section> | |
| <section id="events" class="grid"> | |
| <article class="span-12 panel panel-pad stack"> | |
| <h2>Event Envelope</h2> | |
| <p class="muted"> | |
| Every event uses the same envelope. Resource identity belongs in <code>payload</code>. Runtime identity | |
| belongs in <code>context</code>. | |
| </p> | |
| <div class="grid"> | |
| <pre class="span-6"><code>type ApiEvent<Payload> = { | |
| id: string | |
| type: string | |
| time: number | |
| context: { | |
| directory: string | |
| workspaceID?: string | |
| } | |
| payload: Payload | |
| }</code></pre> | |
| <pre class="span-6"><code>{ | |
| "id": "evt_01", | |
| "type": "message.part.delta", | |
| "time": 1760000000000, | |
| "context": { | |
| "directory": "/repo/app", | |
| "workspaceID": "ws_123" | |
| }, | |
| "payload": { | |
| "sessionID": "ses_123", | |
| "messageID": "msg_456", | |
| "partID": "part_789", | |
| "field": "text", | |
| "delta": "hello" | |
| } | |
| }</code></pre> | |
| </div> | |
| </article> | |
| </section> | |
| <section id="store" class="grid"> | |
| <article class="span-12 panel panel-pad stack"> | |
| <h2>Frontend Sync Store</h2> | |
| <p class="muted"> | |
| A frontend can keep one giant store like the current TUI. Runtime data is partitioned by | |
| <code>contextKey</code>. Durable entities such as sessions and messages are keyed by their own IDs. | |
| </p> | |
| <pre><code>type RuntimeContext = { | |
| directory: string | |
| workspaceID?: string | |
| } | |
| type ContextKey = string | |
| type SessionID = string | |
| type MessageID = string | |
| type SyncStore = { | |
| status: "loading" | "partial" | "complete" | |
| shared: { | |
| provider: Provider[] | |
| provider_default: Record<string, string> | |
| provider_next: ProviderListResponse | |
| provider_auth: Record<string, ProviderAuthMethod[]> | |
| console_state: ConsoleState | |
| } | |
| contexts: Record< | |
| ContextKey, | |
| { | |
| context: RuntimeContext | |
| config: Config | |
| agent: Agent[] | |
| command: Command[] | |
| lsp: LspStatus[] | |
| formatter: FormatterStatus[] | |
| vcs: VcsInfo | undefined | |
| mcp: Record<string, McpStatus> | |
| mcp_resource: Record<string, McpResource> | |
| session: SessionID[] | |
| session_status: Record<SessionID, SessionStatus> | |
| } | |
| > | |
| session: Record<SessionID, Session & { context: RuntimeContext }> | |
| session_diff: Record<SessionID, Snapshot.FileDiff[]> | |
| todo: Record<SessionID, Todo[]> | |
| permission: Record<SessionID, PermissionRequest[]> | |
| question: Record<SessionID, QuestionRequest[]> | |
| message: Record<SessionID, Message[]> | |
| part: Record<MessageID, Part[]> | |
| } | |
| function contextKey(context: RuntimeContext) { | |
| return `${context.workspaceID ?? "local"}:${context.directory}` | |
| }</code></pre> | |
| </article> | |
| </section> | |
| </main> | |
| </body> | |
| </html> | |
Xet Storage Details
- Size:
- 45.4 kB
- Xet hash:
- cdab7b22c0fe2a2bca620ed967084e66527fe987cd2c8d566bc8660fcf412b93
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.