@volter/supercode-frontend-vscode 0.1.63 → 0.1.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -72
- package/dist/extension.js +245 -104
- package/dist/host-controls.d.ts +0 -1
- package/dist/proposals.d.ts +1 -1
- package/dist/proposals.js +18 -2
- package/dist/session.d.ts +2 -21
- package/dist/session.js +3 -35
- package/dist/view.d.ts +58 -5
- package/dist/view.js +234 -109
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -180,7 +180,10 @@ default is never stored as a choice (a pick equal to the default follows the def
|
|
|
180
180
|
changes), and an Auto approve is never stored for a conversation that cannot answer. Conversations opened before 0.1.36 saved their picker's
|
|
181
181
|
**Ask** when opened and keep it. Auto approve approves the requests the harness would ask you about, including requests to run
|
|
182
182
|
outside its sandbox (Codex's approval requests are its sandbox escalations); the harness's deny
|
|
183
|
-
rules still apply.
|
|
183
|
+
rules still apply. A request it answers adds no line of its own: the call's row is the record, as in Code-OSS's own
|
|
184
|
+
agent host, whose Auto approve answers a harness's call with no reason on its row; a card already shown loses its
|
|
185
|
+
buttons where the host can retire it (`chatConfirmationResolution`), else gets its answer as a line beneath it, and an
|
|
186
|
+
approval it could not answer has its card drawn again for the person to answer. A turn
|
|
184
187
|
re-joined after a page reload (the conversation's active response) is answered the same way. Unsupported modes are refused. Unanswerable
|
|
185
188
|
harnesses show **Harness permissions**. Previously answered requests cannot affect another
|
|
186
189
|
connection. Native command-button fallback limitations are documented below.
|
|
@@ -296,7 +299,7 @@ Fresh snapshots also restore retained `history_events` before replay at the
|
|
|
296
299
|
runtime's cursor. Their original sequences and payloads are preserved. Recovered
|
|
297
300
|
unseen events reach existing response listeners, and an authoritative idle
|
|
298
301
|
snapshot releases a restored response even when its terminal event is no longer
|
|
299
|
-
retained.
|
|
302
|
+
retained.
|
|
300
303
|
An unavailable saved runtime returns an error in Chat instead of a blank draft.
|
|
301
304
|
These are implemented source paths; real editor recovery and pending approval
|
|
302
305
|
interaction remain unqualified.
|
|
@@ -310,7 +313,9 @@ the frontend does not coerce them into JavaScript's object label.
|
|
|
310
313
|
record this history path. The original Windows approval-row report remains
|
|
311
314
|
unattributed, and native approval behavior is separate.
|
|
312
315
|
|
|
313
|
-
The extension asks for
|
|
316
|
+
The extension asks for eight proposals. Three of them (`chatSessionResponses`, `chatSystemNotification`,
|
|
317
|
+
`chatConfirmationResolution`) exist only in Volter's Code-OSS fork (volter-ai/code-oss, from `cb0c38b5`); a host
|
|
318
|
+
without one drops its name as a proposal that does not exist. A host grants them through
|
|
314
319
|
`product.json#extensionEnabledApiProposals` (a Code-OSS derivative that bundles this extension) or
|
|
315
320
|
`--enable-proposed-api volter-ai-dev.supercode-frontend-vscode`. **Stock VS Code grants none, and
|
|
316
321
|
everything below still works there** — the granted set is read back from the extension host at
|
|
@@ -322,53 +327,79 @@ request), and each part declares its own fallback.
|
|
|
322
327
|
| `defaultChatParticipant` | `isDefault` — Volter Harness answers the Chat view with no `@` mention | the ordinary `@supercode` participant; a mention is required |
|
|
323
328
|
| `chatParticipantAdditions` | `ChatToolInvocationPart` (with its terminal, todo-list and subagent data), `ChatResponseConfirmationPart`, `ChatResponseWarningPart`, `codeblockUri`, `ChatResponseThinkingProgressPart`, `ChatResponseHookPart`, `questionCarousel` | progress lines, labeled Markdown results, typed replies, plain fenced diffs, blockquoted reasoning, quoted hook lines, answer buttons |
|
|
324
329
|
| `chatSessionsProvider` | the runtime's sessions in the Chat view's session picker, each reopening with its history | the participant still attaches; there is no session list |
|
|
325
|
-
| `chatParticipantPrivate` | dynamic participant identity with the harness and provider icon | static participant identity |
|
|
330
|
+
| `chatParticipantPrivate` | dynamic participant identity with the harness and provider icon; an interrupted turn's error at warning level | static participant identity; the interruption is an ordinary error |
|
|
326
331
|
| `chatProvider` | native fixed-model identity and provider icon | host new-chat configuration |
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
|
344
|
-
|
|
345
|
-
|
|
|
346
|
-
|
|
|
347
|
-
|
|
|
348
|
-
|
|
|
349
|
-
|
|
|
350
|
-
|
|
|
351
|
-
|
|
|
352
|
-
|
|
|
353
|
-
|
|
|
354
|
-
|
|
|
355
|
-
|
|
|
356
|
-
| `
|
|
357
|
-
| `
|
|
358
|
-
| `
|
|
359
|
-
| `
|
|
360
|
-
| `
|
|
361
|
-
| `
|
|
362
|
-
| `
|
|
363
|
-
|
|
|
364
|
-
|
|
|
365
|
-
| `
|
|
366
|
-
| `
|
|
367
|
-
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
`
|
|
332
|
+
| `chatSessionResponses` | the `ChatResult` a re-joined response resolves with and a saved turn's `result.errorDetails` as the response's error; the question carousel on a re-joined response; a conversation that could not be opened anchored to the system-initiated request "Couldn't open session" (`ChatRequestTurn.systemInitiatedLabel`) | a re-joined or saved response's error as a warning part, `Answer…` buttons on a re-joined response, that conversation's error under the marker request |
|
|
333
|
+
| `chatSystemNotification` | `ChatResponseSystemNotificationPart` for a harness notice, with its icon, live and saved | the notice as a plain line |
|
|
334
|
+
| `chatConfirmationResolution` | `ChatResponseConfirmationPart.isUsed`: an approval card answered elsewhere loses its buttons | one plain line beneath the card says the answer |
|
|
335
|
+
|
|
336
|
+
### Parity with Code-OSS's own chat
|
|
337
|
+
|
|
338
|
+
The measure is the event, not the API part: **does this event look as Code-OSS draws its own equivalent
|
|
339
|
+
event?** The citations are read from Volter's Code-OSS fork at the editor's `FORK.json` pin; the workbench archives
|
|
340
|
+
this product ships are cut from earlier fork commits until they are re-cut at it: `4a7cd45` on macOS arm64, `4782d9a2`
|
|
341
|
+
on Linux x64 and Windows x64. Using a native part for something VS Code never draws is not
|
|
342
|
+
parity. Each row names what Code-OSS itself draws, with its source, and what this frontend draws on the product's
|
|
343
|
+
host (all eight proposals granted). **Native**: drawn as Code-OSS draws it. **Fallback**: drawn, but plainer than
|
|
344
|
+
Code-OSS's own (why given). **Gap (API)**: Code-OSS's own drawing is not reachable through the extension API at the
|
|
345
|
+
pin; the row names the fork change that would reach it. **Gap**: reachable, not built. This count is the measure of
|
|
346
|
+
done; a change that moves a row says so here. Paths are under `src/vs/` unless they start with `src/vscode-dts`.
|
|
347
|
+
|
|
348
|
+
| Event | Code-OSS draws its own as | This frontend | Status |
|
|
349
|
+
|---|---|---|---|
|
|
350
|
+
| The agent's text | markdown (`chatMarkdownContentPart.ts`) | `ChatResponseMarkdownPart`; a subagent's own text is not shown | native |
|
|
351
|
+
| The agent's reasoning, live and saved | thinking (`chatThinkingContentPart.ts`) | `ChatResponseThinkingProgressPart`, in history too | native |
|
|
352
|
+
| A tool call, started then finished | one tool row updated in place (`chatToolInvocationPart.ts`) | `ChatToolInvocationPart` with `enablePartialUpdate` | native |
|
|
353
|
+
| A shell call | the terminal row: command and output (`chatTerminalToolProgressPart.ts`) | terminal tool data | native |
|
|
354
|
+
| A call's work left running in the background (a background Bash, a Monitor, a subagent sent to the background) | Code-OSS's own Claude host (`platform/agentHost/node/claude/claudeToolDisplay.ts` `TOOL_ROWS`, lines 100-102) sets no `isBackground`: a background `Bash` is a terminal row that completes with its launch result; `BashOutput` ("Reading shell output") and `KillBash` ("Kill shell command") are terminal rows of their own. The person stops a task by asking the agent; current Claude Code (2.1.312) then calls `TaskStop` (which still answers to the old names `KillShell` and `KillBash`), which Code-OSS's table does not list, so it is an ordinary tool row there and here | the same: the Bash row completes with its launch result, and BashOutput and KillBash are terminal rows with Code-OSS's titles; the harness's listing of its background tasks draws nothing | native |
|
|
355
|
+
| Output a background-status call drained (`background_output`) | that call's own row (`get_terminal_output`'s row) | nothing more: the status call's row result already carries it | native |
|
|
356
|
+
| A plan (TodoWrite, the task tools, `update_plan`) | the todo list (`chatTodoListWidget.ts`) | todo-list tool data | native |
|
|
357
|
+
| Codex's plan (`turn/plan/updated`, not a call) | the todo list | a status line | fallback: no call carries it, and a todo list is a tool row |
|
|
358
|
+
| A subagent and its calls | the subagent row with its calls grouped under it (`chatSubagentContentPart.ts`) | subagent tool data, `subAgentInvocationId` | native |
|
|
359
|
+
| A hook that blocked or warned | the hook row (`chatHookContentPart.ts`) | `ChatResponseHookPart` | native; **gap (API)** inside a subagent: the part carries no subagent id |
|
|
360
|
+
| An approval | the confirmation card, answered in the running turn (`chatConfirmationContentPart.ts`; the fork's `volter.chat.inTurnApprovalCapability`, `volterHarness/volterChat.ts`) | `ChatResponseConfirmationPart` where the host advertises in-turn cards (this product's host does); command buttons on a stock host, whose confirmation answers with a new request | native; fallback on a stock host |
|
|
361
|
+
| A harness's questions | the question carousel (`chatQuestionCarouselPart.ts`), in its turn's response | the carousel, on a turn this window runs and on a re-joined response (`chatSessionResponses`: `mainThreadChatSessions.ts` forwards the answer to the session's stream by its `resolveId`); `Answer…` buttons on a re-joined response on a host without it | native; fallback on a re-joined response without `chatSessionResponses` |
|
|
362
|
+
| A request answered through its own card in this window | the card or carousel shows what was chosen (`chatConfirmationContentPart.ts`, `chatQuestionCarouselPart.ts`); the call's row carries on or ends denied | the same; a stock host's buttons stay, inert, and the status bar says what was sent | native |
|
|
363
|
+
| A request answered any other way (another window, Auto approve turned on after its card showed, a typed reply) | the request's card retires itself: the call's row carries on or ends denied (`agentHostSessionHandler.ts` `IChatToolInvocation.confirmWith`); a carousel answered elsewhere is marked used with its answers (`answeredExternally`) | an approval card loses its buttons (`chatConfirmationResolution`: the same `ChatResponseConfirmationPart` pushed with `isUsed`, which `chatModel.ts` matches by its `data`); the call's row carries the outcome. A question carousel stays live, with one plain line beneath it saying the answer | native for an approval card; **gap (API)** for a question carousel: an extension cannot mark a carousel it pushed answered. Fork: let the extension resolve a pushed carousel with the answers given elsewhere (`answeredExternally`) |
|
|
364
|
+
| An approval answered automatically (Auto approve) | the call's row alone: Code-OSS's own agent host answers a harness's call under its Auto approve with `confirmed: NotNeeded` and no reason (`platform/agentHost/node/sessionPermissions.ts` `createToolReadyAction`, after `agentSideEffects.ts` strips the confirmation), so `getApprovalMessageFromReason` (`chatToolPartUtilities.ts`) has nothing to say. Only a client tool the workbench runs itself is "Auto approved by `autoApprove`" (`agentHostSessionHandler.ts` `getClientToolPreApproval`) | the call's row alone; an answer that fails or does not settle draws the approval's card again, as the one still waiting | native |
|
|
365
|
+
| A request this window cannot answer (another client holds it) | no read-only confirmation: another client's call is its row, "Running {0} on another client…", with a cancel action (`stateToProgressAdapter.ts` `toolCallStateToInvocation`) | its title and summary as words, no controls; its answer as a line beneath it | fallback: the extension API cannot draw another client's call |
|
|
366
|
+
| A turn that failed | the response's error (`agentHostSessionHandler.ts` `_getTurnErrorDetails`, `errorDetails`) | the request handler's `ChatResult.errorDetails`; on a re-joined response the `ChatResult` its `activeResponseCallback` resolves with, and in history the saved turn's `result.errorDetails` (`chatSessionResponses`: `extHostChatSessions.ts` passes both on, and `chatServiceImpl.ts` sets the result on the response as it completes); on a host without it, VS Code's warning part with the error's words there | native; fallback on a re-joined response and in history without `chatSessionResponses` |
|
|
367
|
+
| A turn interrupted from elsewhere | the response's warning-level, expected error (`_getTurnErrorDetails`, `executionInterrupted`) | `errorDetails` with `level: Warning`, `isExpectedError`, on the same paths | native; fallback without `chatSessionResponses`, as above |
|
|
368
|
+
| A turn the person stopped | VS Code marks the response stopped | nothing more | native |
|
|
369
|
+
| A request Chat cannot run (no sign-in, no runtime, a refused send) | the request's error | a thrown error, which the workbench writes as the response's error | native |
|
|
370
|
+
| A transport or stream error while a turn may still run (`stream_error`, `transport_error`, `watch_error`, `runtime_disconnected`) | the response's error | VS Code's warning part with the error's words | fallback: the turn may still be running, so it is not ended with an error |
|
|
371
|
+
| A re-joined stream that fails; a conversation that cannot be recovered | the response's error; a session that cannot be loaded is the system-initiated request "Couldn't open session" with that error (`agentHostSessionHandler.ts` `sessionLoadFailed`, `sessionLoadFailedLabel`) | the re-joined response's result carries the error; the conversation's marker request is the system-initiated "Couldn't open session" and its saved response's result carries the error (`chatSessionResponses`); VS Code's warning part under the marker request on a host without it | native; fallback without `chatSessionResponses` |
|
|
372
|
+
| A harness warning (`cache_warning`, `warning`, a usage limit) | the warning part (`chatErrorContentPart.ts`, warning level) | `ChatResponseWarningPart` | native |
|
|
373
|
+
| A harness record that is not the person's words (a background task's notification, live or saved; an interruption record) | a system notification row, its icon picked per notification kind with the completion check as default (`stateToProgressAdapter.ts` `systemNotificationToChatPart`; `claudeReplayMapper.ts` keeps `compact_boundary` and `notification`) | `ChatResponseSystemNotificationPart` with the notice's own words (`chatSystemNotification`, converted to `{kind: 'systemNotification'}` in `extHostTypeConverters.ts`), live and saved, once per task (Claude Code reports a finished task both as `system/task_notification` and as the user-role record that wakes the agent; the saved transcript keeps only the latter, a `queued_command` attachment). "Turn interrupted." and a background task that failed or was stopped carry `warning`, by analogy with the icon upstream gives an automatic-approval review that was interrupted: upstream draws neither as a notification of its own. A plain line on a host without it, never a progress part, which Code-OSS hides once any other part follows it (`chatProgressContentPart.ts`) | native; fallback without `chatSystemNotification` |
|
|
374
|
+
| A status line (`status`) | the progress message, hidden once another part follows (`chatProgressContentPart.ts`) | `ChatResponseProgressPart` | native |
|
|
375
|
+
| Input arriving from elsewhere while a turn runs | the running turn's pending Steering message until the turn takes it in, then nothing: the turn keeps its response and no request turn opens (`agentHostSessionHandler.ts` `_applyRemotePendingMessages` → `syncPendingRequestsFromRemote`; `removePendingRequest` once taken in) | **Additional input** and the words, inside the running response, once the turn takes it in | **gap (runtime)**: the runtime announces no input waiting to be taken in (no frontend event carries it), and the runtime must echo a client-chosen input id on `user_message` and `turn_started`, and return it from `submit` and `steer` (`sdk/frontend/contract.json` carries no turn or input id, so which input started which turn is only a guess by text and order). Then a proposed API with which a session's provider sets and removes its pending Steering messages, mirroring those two calls |
|
|
376
|
+
| A message sent from this window while a turn it follows runs (a re-joined response) | a pending Steering message, which the workbench dispatches to a streamed session's provider at once (`chatServiceImpl.ts`, mid-turn steering); the turn keeps its response | the request handler's own turn, which the runtime refuses while a turn runs | **gap (runtime)**: steering it into the running turn without drawing its runtime echo a second time needs to know which `user_message` is that echo: the runtime must echo a client-chosen input id on `user_message` and `turn_started`, and return it from `submit` and `steer` (`sdk/frontend/contract.json` carries no turn or input id, so which input started which turn is only a guess by text and order) |
|
|
377
|
+
| A turn the runtime starts on its own (input that starts a turn while none runs, a turn after the previous one ended) | a request turn of its own (`agentHostSessionHandler.ts`, a changed active turn id: `startServerRequest`) | drawn inside the response of this window that follows the conversation, which follows to idle (a re-joined response), or only when the conversation reopens | **gap (runtime)**: opening it as a request turn of its own needs to know which input started it: the runtime must echo a client-chosen input id on `user_message` and `turn_started`, and return it from `submit` and `steer` (`sdk/frontend/contract.json` carries no turn or input id, so which input started which turn is only a guess by text and order) |
|
|
378
|
+
| A prompt the runtime's scheduler starts | a system-initiated request turn: a notification row with its label (`chatListRenderer.ts` `renderSystemInitiatedRequest`) | a notice, "Scheduled prompt: …", inside the response this window follows, or nothing until the conversation reopens; the same in saved history. Nothing in this repository produces `scheduled_prompt_started` (it is declared by `agent-runtime-host.mjs` `displayKinds` and read by `frontend-transcript.mjs` and the browser client), so its payload is not known; the prompt is read from `prompt`, `name` or `message` | **gap (runtime)**: a producer, and the turn attribution above, so that its turn opens as its own system-initiated request without also drawing the runtime's `user_message` for it |
|
|
379
|
+
| A Codex diff | file edits with Keep/Undo and the multi-file diff (`chatTextEditContentPart.ts`, `chatMultiDiffContentPart.ts`) | `codeblockUri` with a fenced diff, plus one reference per file | **gap (known)**: the harness has already written the files and no event carries the before/after the editor needs (see *Why `diff_updated` is not an edit part*) |
|
|
380
|
+
| An MCP call | the MCP input/output row | the simple input/output row | fallback: its result arrives as text |
|
|
381
|
+
| Token usage | the context-window indicator (`stream.usage`) | not shown | **gap** |
|
|
382
|
+
| A protocol record (`native_event`, a kind this version does not know, a malformed request) | nothing | nothing; an unknown kind and a malformed request go to the output channel | native |
|
|
383
|
+
| Saved history | the same parts a live response draws | the same converter: tool rows, hooks, warnings, reasoning | native |
|
|
384
|
+
| History past its bound | left out without a word; a turn without its request gets "Message content could not be retrieved" (`claudeReplayMapper.ts` `missingPromptPlaceholder`) | the same | native |
|
|
385
|
+
| A call waiting on approval in re-joined history | its row, with its card on the active response | the same | native |
|
|
386
|
+
|
|
387
|
+
Count, by row (36), on this product's host (Volter's Code-OSS fork at the editor's `FORK.json` pin, with all eight
|
|
388
|
+
proposals granted; a stock host draws the fallbacks above): 26 native, of which hooks are an API gap inside a
|
|
389
|
+
subagent and a request answered elsewhere an API gap for a question carousel; 4 fallback; 4 gaps that wait on the
|
|
390
|
+
runtime's turn attribution (input from elsewhere while a turn runs, a message this window sends into a turn it
|
|
391
|
+
follows, a turn the runtime starts on its own, a scheduled prompt, which also has no producer yet); 1 known gap
|
|
392
|
+
(native edits); 1 gap not built (`stream.usage`). The rows marked native for a harness's questions on a re-joined
|
|
393
|
+
response, harness records, a failed or interrupted turn on a re-joined or saved response, a conversation that cannot
|
|
394
|
+
be recovered, and a card answered elsewhere rest on the fork's proposals `chatSessionResponses`,
|
|
395
|
+
`chatSystemNotification` and `chatConfirmationResolution`; an automatic approval is native because Code-OSS's own
|
|
396
|
+
agent host draws that call's row alone.
|
|
397
|
+
|
|
398
|
+
Parts the extension API offers that no harness event this frontend receives carries, so not used:
|
|
399
|
+
`ChatResponseAnchorPart`, `ChatResponseFileTreePart`, `ChatResponseMarkdownWithVulnerabilitiesPart`,
|
|
400
|
+
`ChatResponseCodeCitationPart`, `ChatResponseMovePart`, `ChatResponseExtensionsPart`, `ChatResponsePullRequestPart`,
|
|
401
|
+
`ChatResponseInfoPart`, `ChatResponseAutoModeResolutionPart`, `ChatResponseProgressPart2`,
|
|
402
|
+
`ChatResponseReferencePart2`, `ChatResponseVoiceProgressPart`, and the resources tool data.
|
|
372
403
|
|
|
373
404
|
The session participant uses the exact session type id (`supercode`). With
|
|
374
405
|
`chatParticipantPrivate`, the extension registers its dynamic identity directly and keeps
|
|
@@ -402,24 +433,25 @@ it needs and the fallback it degrades to. Each arm names the producer it reads.
|
|
|
402
433
|
| Event kind | Producer | Rendered as |
|
|
403
434
|
|---|---|---|
|
|
404
435
|
| `text_delta` | `crates/runtime/src/event.rs` `AgentEvent::TextDelta` | `response.markdown` (streamed) |
|
|
405
|
-
| `user_message` | `sdk/interchange/agent-runtime-host.mjs` accepted-turn projection; `runtime-native-projection.mjs` `claudeBlocks` for Claude's own user-role records (`source: harness`) | the request turn in history; dropped live (VS Code already shows it); a harness record shows its `notice` or nothing |
|
|
436
|
+
| `user_message` | `sdk/interchange/agent-runtime-host.mjs` accepted-turn projection; `runtime-native-projection.mjs` `claudeBlocks` for Claude's own user-role records (`source: harness`) | the request turn in history; dropped live before `turn_started` (VS Code already shows it); after it, **Additional input** inside the response; a harness record shows its `notice` as a system notification row (`chatSystemNotification`) → a plain line, or nothing |
|
|
406
437
|
| `turn_started` / `turn_completed` / `turn_succeeded` | `submit_claimed`; `AgentEvent::TurnCompleted` | lifecycle only — the handler resolves, nothing renders |
|
|
407
|
-
| `turn_interrupted` | `submit_claimed` |
|
|
408
|
-
| `turn_failed` | `submit_claimed` | `ChatResponseWarningPart` → blockquote |
|
|
438
|
+
| `turn_interrupted` | `submit_claimed` | the response's result: `errorDetails` at warning level (a re-joined or saved response needs `chatSessionResponses`); else `ChatResponseWarningPart` → its words |
|
|
439
|
+
| `turn_failed` | `submit_claimed` | the response's result: `errorDetails` (a re-joined or saved response needs `chatSessionResponses`); else `ChatResponseWarningPart` → blockquote |
|
|
409
440
|
| `tool_call_started` / `tool_call_completed` | `AgentEvent::ToolCallStarted` / `ToolCallCompleted` | one `ChatToolInvocationPart` per call, updated in place with its result (`enablePartialUpdate`) → a progress line plus a labeled Markdown result |
|
|
410
441
|
| `diff_updated` | `crates/codex-frontend/src/codex_app_server_v0_144.rs` (stock Codex `turn/diff/updated`) | `codeblockUri` + a fenced `diff` block, plus one stable `reference` per file the diff names → the fenced block alone |
|
|
411
|
-
| `request` | `sdk/interchange/frontend-request-bridge.mjs` request publication | a titled markdown block plus one **command button per answer
|
|
442
|
+
| `request` | `sdk/interchange/frontend-request-bridge.mjs` request publication | `ChatResponseConfirmationPart` where the host advertises in-turn cards, the question carousel for questions; else a titled markdown block plus one **command button per answer**. Read-only (title and summary) for a request this window cannot answer |
|
|
443
|
+
| `request_resolved` | `FrontendRequestBroker::respond` | nothing for a card answered through itself in this window; a native approval card answered elsewhere loses its buttons (`chatConfirmationResolution`); else one plain line beneath the card naming the answer |
|
|
412
444
|
| `cache_warning` | `AgentEvent::CacheWarning` | `ChatResponseWarningPart` → blockquote |
|
|
413
445
|
| `hook` | `runtime-native-projection.mjs` from Claude Code's failed `hook_response`, its blocked-prompt `informational` record, and a tool result in its own `PreToolUse:<tool> hook error:` words | `ChatResponseHookPart` ("Blocked by" / "Warning from" the hook) → blockquote |
|
|
414
|
-
| `background_tasks` | `runtime-native-projection.mjs` from Claude Code's `background_tasks_changed` | nothing
|
|
446
|
+
| `background_tasks` | `runtime-native-projection.mjs` from Claude Code's `background_tasks_changed` | nothing: a background command is its call's row, as in Code-OSS's own Claude host |
|
|
415
447
|
| any event with `parent_id` | `runtime-native-projection.mjs` from Claude Code's `parent_tool_use_id` | a subagent's calls are grouped under its call; its own text, reasoning and input are not shown |
|
|
416
|
-
| `usage` | `AgentEvent::Usage` |
|
|
417
|
-
| `background_output` | `
|
|
418
|
-
| `scheduled_prompt_started` / `_deferred` / `_completed` | declared by `
|
|
419
|
-
| `scheduler_error` | same | `ChatResponseWarningPart` → blockquote |
|
|
448
|
+
| `usage` | `AgentEvent::Usage` | nothing (see `stream.usage` in the parity table) |
|
|
449
|
+
| `background_output` | `sdk/interchange/agent-background.mjs` `status` | nothing: the status call's own row carries the output |
|
|
450
|
+
| `scheduled_prompt_started` / `_deferred` / `_completed` | declared by `agent-runtime-host.mjs` `displayKinds`; no producer here | started: a notice, "Scheduled prompt: …"; deferred and completed: lifecycle only |
|
|
451
|
+
| `scheduler_error` | same | `ChatResponseWarningPart` with its words → blockquote |
|
|
420
452
|
| `reasoning` / `thinking` | no producer in this repository; read because `sdk/interchange/frontend-transcript.mjs` reads them | `ChatResponseThinkingProgressPart` → blockquote |
|
|
421
|
-
| `stream_error` / `transport_error` / `watch_error` / `runtime_disconnected` | `crates/opencode-frontend/src/server.rs`; `crates/interchange/src/watch.rs`; synthesized by a frontend (`sdk/interchange/frontend-app.mjs`); `stream_error` has no producer here | `ChatResponseWarningPart` → blockquote |
|
|
422
|
-
| anything else | opaque by contract |
|
|
453
|
+
| `stream_error` / `transport_error` / `watch_error` / `runtime_disconnected` | `crates/opencode-frontend/src/server.rs`; `crates/interchange/src/watch.rs`; synthesized by a frontend (`sdk/interchange/frontend-app.mjs`); `stream_error` has no producer here | `ChatResponseWarningPart` with its words → blockquote |
|
|
454
|
+
| anything else | opaque by contract | nothing in the transcript; written to the output channel |
|
|
423
455
|
|
|
424
456
|
**Why `diff_updated` is not an edit part.** Measured: the payload carries one unified-diff *string*
|
|
425
457
|
and nothing else. `ChatResponseTextEditPart` wants ranges and the runtime has already written the
|
|
@@ -446,16 +478,18 @@ invisible is one nobody can trust. A pushed command button cannot be withdrawn
|
|
|
446
478
|
enables on `!isStale` and carries no used-state, and only `confirmation`, `mcpAuthenticationRequired`,
|
|
447
479
|
`planReview` and `questionCarousel` have one — so the buttons stay visible after the answer. They are
|
|
448
480
|
inert: the command refuses a request the runtime no longer holds and says "already resolved", and the
|
|
449
|
-
|
|
481
|
+
status bar says what was sent. An elicitation that carries a `requested_schema` gets an
|
|
450
482
|
`Answer…` button that asks for the value first; a request still pending while the session is idle
|
|
451
483
|
can also be answered by typing.
|
|
452
484
|
|
|
453
485
|
**A harness's questions are VS Code's question carousel.** Why the carousel once swallowed its answer, read
|
|
454
|
-
from
|
|
486
|
+
from Code-OSS at `4a7cd45`, the fork commit the macOS arm64 archive is still cut from (Linux and Windows: `4782d9a2`): `questionCarousel` resolves through the resolver map of the stream it
|
|
455
487
|
was called on, and `$handleQuestionCarouselAnswer` reads only the participant's map
|
|
456
488
|
(`extHostChatAgents2.ts`). A session's *re-joined* response (`activeResponseCallback`) gets a stream with a
|
|
457
|
-
map of its own (`extHostChatSessions.ts`) that no answer
|
|
458
|
-
|
|
489
|
+
map of its own (`extHostChatSessions.ts`) that no answer reached at that pin. The fork's `chatSessionResponses`
|
|
490
|
+
routes a carousel answer to a session's stream by its `resolveId` (`mainThreadChatSessions.ts` →
|
|
491
|
+
`$handleQuestionCarouselAnswer`), so on the product's host the carousel is used on a re-joined response too;
|
|
492
|
+
a host without it keeps the buttons above on a re-joined response. The design:
|
|
459
493
|
|
|
460
494
|
- *The question reaches Chat as a request.* Supercode's own `ask_user` already asks through an `elicitation`
|
|
461
495
|
whose `requested_schema.properties.qN` carry `title`, `description`, `x-options` (`[{label, description}]`)
|
|
@@ -470,7 +504,8 @@ turn this window's request handler is running; a re-joined response keeps the bu
|
|
|
470
504
|
alone as `x-question`, and `x-options`) is one `ChatQuestion` per property: single or multi select with
|
|
471
505
|
free text allowed, or text when it has no options; Skip is allowed. Any other form (an MCP server's own
|
|
472
506
|
schema, with its `enum`, `format` or `required`) keeps the `Answer…` door, which honours them. Without the
|
|
473
|
-
carousel (no `chatParticipantAdditions`, or a re-joined response
|
|
507
|
+
carousel (no `chatParticipantAdditions`, or a re-joined response on a host without `chatSessionResponses`) it is
|
|
508
|
+
the `Answer…` button.
|
|
474
509
|
- *The answer reaches the harness in its own format.* The carousel's answers become the elicitation's
|
|
475
510
|
`{action:'accept', content:{qN: label | [labels] | text}}`, or `decline` when skipped or submitted with
|
|
476
511
|
nothing chosen; a stopped turn sends nothing (Stop cancels its requests). A reply typed into Chat instead
|
|
@@ -488,14 +523,16 @@ own envelope, which for Claude Code is `{behavior:'allow'}` / `{behavior:'deny',
|
|
|
488
523
|
request states which decisions its harness protocol actually carries, so this view offers exactly
|
|
489
524
|
those and no button the runtime would refuse — Claude Code has an allow and a deny and no
|
|
490
525
|
always-allow *behavior* at all, so it gets two. A harness with no translation keeps
|
|
491
|
-
`actions.respond: false`, and then the request is
|
|
492
|
-
because a control appears only for an action the descriptor advertises
|
|
526
|
+
`actions.respond: false`, and then the request is drawn read-only, its title and summary with no controls,
|
|
527
|
+
because a control appears only for an action the descriptor advertises; Code-OSS likewise draws another
|
|
528
|
+
client's pending call for every observer. Tool completions name only
|
|
493
529
|
the call they answer (Claude Code's `tool_result` block carries just a `tool_use_id`), so an unnamed
|
|
494
530
|
completion keeps the name the start stated rather than becoming a tool called `tool`.
|
|
495
531
|
|
|
496
532
|
**Bounds.** The projection is bounded like `@volter/supercode-frontend-browser`'s: 64 KiB per
|
|
497
|
-
part, 256 characters per title, 2 KiB for an opaque payload, 500 history turns.
|
|
498
|
-
|
|
533
|
+
part, 256 characters per title, 2 KiB for an opaque payload, 500 history turns. Turns past the bound are
|
|
534
|
+
left out without a word, as VS Code's own agent host shows a transcript its harness truncated; the
|
|
535
|
+
runtime's own history is unchanged and authoritative. Terminal control
|
|
499
536
|
characters never reach a rendered part.
|
|
500
537
|
|
|
501
538
|
**The turn.** A chat request submits through `frontend.v2.send_input` and resolves on the first
|
|
@@ -527,7 +564,7 @@ create no person-message bubble, live or restored; ordinary quoted text
|
|
|
527
564
|
without those flags stays a person message. A task notification becomes a
|
|
528
565
|
short background-task notice, and Claude's unmarked, exact interruption
|
|
529
566
|
records (`[Request interrupted by user]`, `… for tool use]`) a short turn
|
|
530
|
-
interruption notice. The native transcript remains authoritative and unchanged.
|
|
567
|
+
interruption notice, each a plain line of its own words (see the parity table's harness-record row). The native transcript remains authoritative and unchanged.
|
|
531
568
|
[Source evidence and remaining qualification](../../docs/evidence/chat-native-notices-20261013.md).
|
|
532
569
|
|
|
533
570
|
**Session times are real or nothing.** `frontend.v2` carries no session timestamp, and the editor's
|
|
@@ -541,8 +578,9 @@ not supported by native history rendering. A saved call is labeled neutrally bec
|
|
|
541
578
|
a recorded invocation does not prove that permission was granted. VS Code's chat history is request/response **pairs** and drops a response turn with no
|
|
542
579
|
request before it. A runtime transcript legitimately opens with assistant or system content — the
|
|
543
580
|
runtime compacts, so its canonical history can begin `[earlier conversation compacted: N messages]`
|
|
544
|
-
with no user turn left. Rather than drop it, the projection pairs it with a marker turn
|
|
545
|
-
|
|
581
|
+
with no user turn left. Rather than drop it, the projection pairs it with a marker turn whose prompt is
|
|
582
|
+
Code-OSS's own for a turn whose request is missing, "Message content could not be retrieved"
|
|
583
|
+
(`claudeReplayMapper.ts` `missingPromptPlaceholder`): nothing is presented as a person's words.
|
|
546
584
|
|
|
547
585
|
## Building and packaging
|
|
548
586
|
|