zcode-acp-server 0.45.0 → 0.46.0

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.
Files changed (39) hide show
  1. package/README.md +1 -1
  2. package/dist/backend/listener.d.ts +7 -3
  3. package/dist/backend/listener.d.ts.map +1 -1
  4. package/dist/backend/listener.js +20 -4
  5. package/dist/backend/listener.js.map +1 -1
  6. package/dist/backend/types.d.ts +6 -0
  7. package/dist/backend/types.d.ts.map +1 -1
  8. package/dist/code-fingerprint.json +1 -1
  9. package/dist/config/mcp-discovery.d.ts +19 -0
  10. package/dist/config/mcp-discovery.d.ts.map +1 -1
  11. package/dist/config/mcp-discovery.js +26 -0
  12. package/dist/config/mcp-discovery.js.map +1 -1
  13. package/dist/handlers/dispatch.d.ts.map +1 -1
  14. package/dist/handlers/dispatch.js +33 -0
  15. package/dist/handlers/dispatch.js.map +1 -1
  16. package/dist/handlers/session.d.ts.map +1 -1
  17. package/dist/handlers/session.js +108 -11
  18. package/dist/handlers/session.js.map +1 -1
  19. package/dist/handlers/slash.d.ts +3 -1
  20. package/dist/handlers/slash.d.ts.map +1 -1
  21. package/dist/handlers/slash.js +60 -5
  22. package/dist/handlers/slash.js.map +1 -1
  23. package/dist/i18n.d.ts +11 -0
  24. package/dist/i18n.d.ts.map +1 -1
  25. package/dist/i18n.js +14 -0
  26. package/dist/i18n.js.map +1 -1
  27. package/dist/server.d.ts +13 -0
  28. package/dist/server.d.ts.map +1 -1
  29. package/dist/server.js +16 -0
  30. package/dist/server.js.map +1 -1
  31. package/dist/translators/event-translator.d.ts +9 -1
  32. package/dist/translators/event-translator.d.ts.map +1 -1
  33. package/dist/translators/event-translator.js +37 -1
  34. package/dist/translators/event-translator.js.map +1 -1
  35. package/dist/translators/types.d.ts +16 -1
  36. package/dist/translators/types.d.ts.map +1 -1
  37. package/dist/translators/types.js.map +1 -1
  38. package/docs/BACKLOG.md +85 -61
  39. package/package.json +1 -1
package/docs/BACKLOG.md CHANGED
@@ -73,14 +73,14 @@ elsewhere.
73
73
  The protocol enum now labels these `@deprecated` (`index.ts:3573-3645`); wire
74
74
  cases remain, so calls still work, but plan for the v4 successors:
75
75
 
76
- | Method | Source note | Bridge call site |
77
- | ---------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------- |
78
- | `session/send` | Main path converged on v4 `sendText`; only the adapter-attachment fallback branch still consumes | the turn loop (fine until v4 lands) |
79
- | `session/stop` | Host client method deleted (stop converged on the v4 stop command) | `stopBackendTurn` (dual-send) |
80
- | `session/cancelBackgroundTask` | Replacement: v4 `cancelBackgroundWork` | `handlers/extensions.ts` |
81
- | `session/fork` | Desktop host client chain deleted; v4 `forkAssistant` (via `forkSessionAtMessage`) is the successor | `handlers/extensions.ts` |
82
- | `usage/stats` | Host consumption moved to `v4/usage/stats`; wire-compat case only | not used |
83
- | `session/usage` | Host moved to `v4/conversation/usage`; slated for removal with `usage/stats` | candidate only |
76
+ | Method | Source note | Bridge call site |
77
+ | ------------------------------ | --------------------------------------------------------------------------------------------------- | ----------------------------------- |
78
+ | `session/send` | Main path converged on v4 `sendText`; only the adapter-attachment fallback branch still consumes | the turn loop (fine until v4 lands) |
79
+ | `session/stop` | Host client method deleted (stop converged on the v4 stop command) | `stopBackendTurn` (dual-send) |
80
+ | `session/cancelBackgroundTask` | Replacement: v4 `cancelBackgroundWork` | `handlers/extensions.ts` |
81
+ | `session/fork` | Desktop host client chain deleted; v4 `forkAssistant` (via `forkSessionAtMessage`) is the successor | `handlers/extensions.ts` |
82
+ | `usage/stats` | Host consumption moved to `v4/usage/stats`; wire-compat case only | not used |
83
+ | `session/usage` | Host moved to `v4/conversation/usage`; slated for removal with `usage/stats` | candidate only |
84
84
 
85
85
  ## Candidate methods (optional enhancements)
86
86
 
@@ -88,29 +88,29 @@ Available in the backend but with no ACP-side counterpart yet. Pick them up
88
88
  when a concrete ACP/editor need appears. Ranked shortlist in
89
89
  "Alignment opportunities" below.
90
90
 
91
- | Method | Purpose | Current bridge behavior |
92
- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
- | `session/subagents` (`index.ts:1520-1618`) | Sub-agent states: `running{status: running\|waiting\|blocked}`, `ended{total, items[{status: success\|failed\|cancelled\|lost}], nextCursor}` | Sub-agent info is parsed from the `Agent` tool result (`_meta.subagent`); the RPC adds waiting/blocked/lost states for stuck-subagent detection (pairs with the watermark liveness logic in `runEventTurn`) |
94
- | `session/events` (`{sessionId, afterSeq?, limit?}`, `index.ts:1667-1674`) | Pull-mode event history | Not used; gap-fill after the drain gate's close-escalation reload (re-subscribe + replay only the missed window), durable audit for `/debug` |
95
- | `session/subscribe` `afterSeq` + `includeSnapshot` (`index.ts:1496-1513`) | Resume the event stream from a seq watermark, optionally with a full state snapshot | Not used; crash-safe resubscribe instead of full replay |
96
- | `session/usage` / `v4/conversation/usage` | Per-session cumulative usage: input/output/reasoning/cache tokens, `modelRequestCount`, `modelErrorCount` (`index.ts:1627-1646`) | Per-turn billing usage is now carried on the ACP `session/prompt` result (`usage` + `_meta.zcode.usage`), sourced from `turn.completed`; this RPC remains a candidate for session-cumulative reconciliation (deprecated upstream, see table above) |
97
- | `session/compact` `instructions` + `result.compact` (`index.ts:1829-1853`) | Custom compact instructions; result acks `{state: accepted\|already_running, inputId?, operationId?}` | Not forwarded — `/compact <focus>` could pass instructions; the backend's own `already_running` ack can backstop the bridge's `autoCompactInFlight` single-flight |
98
- | `session/debug` (`index.ts:3571`, `bootstrap/src/zcode-protocol/session-debug.ts`) | Per-session debug snapshot accumulated from the live event stream | Not used; `zcode-acp` diagnostics command / `/debug` extension |
99
- | `session/list` rich params (`sessionIds` incl. hidden, `includeArchived`, `limit`, `index.ts:1600-1609`) | Explicit identity lookup, archived sessions | Not used |
100
- | `session/create` extras: `toolAllowlist`/`toolDenylist` (per-session tool face — could move Cron* hiding off process-wide `--disallowed-tools`), `importedHistory` (claudeCode / sharedContext+sha256 provenance), `persistence:"immediate"\|"deferred"`, `titleGenerationEnabled:false` (bridge sets its own titles), `parentSessionId` (`index.ts:1558-1580`) | Session-creation knobs | Not forwarded; `session/resume` also takes `toolAllowlist`/`toolDenylist` — a resume WITHOUT them drops the tool face on cold recovery (`index.ts:1589-1595`) |
101
- | `mcp/list` `mode:"status"` (`index.ts:686-723`) | Status without connecting: per-server `{status, transport, toolCount, failureKind(19-value enum), authorization{authorizationUrl}}` | Not used; editor MCP health panel + OAuth start URL without new transport |
102
- | `process/childProcesses` (3.12.3) | List a session's child processes (`{pid, serverName, mcpSource, pluginName?}`, pure memory) | Not used; potentially useful for background-task diagnostics |
103
- | `skills/referenceCatalog`, `plugins/referenceCatalog[WithCategory]` (categorized variant new in 0.16.9) | Session-scoped FROZEN catalogs — the authoritative per-session view vs the bridge's live disk reads | Not used; fixes the stale-catalog class of bug (backend freezes discovery at session start) |
104
- | `workspace/readPresentation` (3.12.3) | The backend's own view of workspace mode + slash-command list | Not used; cross-check the bridge's disk-based slash discovery for drift |
105
- | `workflows/*` family (NEW 0.16.9: `list/get/updateMeta/delete/runs/move`, `index.ts:2685-2937, 3618-3625`) | Session-less management of saved dynamic workflows (`<cwd>/.zcode/workflows/`, project+global scopes), run history with `artifacts`, cross-cwd runs query | Not used; pairs with v4 commands `startSavedWorkflow` / `resumeWorkflowRun` |
106
- | `provider/testModelConnectivity` (3.12.3) | Probe a provider/model endpoint | Not used; model availability comes from the `session/create` response |
107
- | `runtime/capabilities` (3.12.3; returns `{independentPlanState:true}`) | Trivial capability handshake | Not used; cheap preflight for a `zcode-acp doctor` command |
108
- | `interaction/providerRuntimeHeadersCancelled` notification (`index.ts:336, 2396-2406`) | Backend cancels a pending runtime-headers refresh (workspace/session/requestId scoped) | Not handled; drop pending answerers immediately on turn cancel instead of waiting them out |
109
- | `workspace/generateText` / `workspace/cancelGenerateText` (0.16.5) | Workspace-scoped one-shot text generation | Not used; no ACP counterpart |
110
- | `workspace/updateInteractionPreferences` / `workspace/updateModelIoPreferences` | Client preference updates | Not used |
111
- | `offPeak/{create,list}`, `workspace/updateOffPeakToolPolicy` (3.12.3) | Off-peak (discounted-hours) task family | Not used; `session/send` carries the matching `offPeakTaskId`/`offPeakRunType` params — candidate if a client wants to schedule discounted-hours runs. Off-peak tools are fail-closed at the protocol layer with three unlock channels (per-session param OR'd, process policy method, `offPeakPort` injection) |
112
- | `automation/{create,update,list,delete,checkTaskBinding}` (3.12.3) | Scheduled (cron) task family — served by the host over `automation/*` requests | Not planned (see below) |
113
- | `plugins/{list,setEnabled,overview,install,uninstall,update,cancelOperation,restoreBuiltin,configure,resetConfig,validate,describe}` + `plugins/marketplace/{add,remove,update}` (3.12.3) | Full plugin management + marketplace family | Not used — **compat watchpoint**: if upstream moves plugin distribution to the marketplace, the bridge's disk-based discovery (`config/plugin-commands.ts`) may go stale |
91
+ | Method | Purpose | Current bridge behavior |
92
+ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
+ | `session/subagents` (`index.ts:1520-1618`) | Sub-agent states: `running{status: running\|waiting\|blocked}`, `ended{total, items[{status: success\|failed\|cancelled\|lost}], nextCursor}` | Sub-agent info is parsed from the `Agent` tool result (`_meta.subagent`); the RPC adds waiting/blocked/lost states for stuck-subagent detection (pairs with the watermark liveness logic in `runEventTurn`) |
94
+ | `session/events` (`{sessionId, afterSeq?, limit?}`, `index.ts:1667-1674`) | Pull-mode event history | Not used; gap-fill after the drain gate's close-escalation reload (re-subscribe + replay only the missed window), durable audit for `/debug` |
95
+ | `session/subscribe` `afterSeq` + `includeSnapshot` (`index.ts:1496-1513`) | Resume the event stream from a seq watermark, optionally with a full state snapshot | Not used; crash-safe resubscribe instead of full replay |
96
+ | `session/usage` / `v4/conversation/usage` | Per-session cumulative usage: input/output/reasoning/cache tokens, `modelRequestCount`, `modelErrorCount` (`index.ts:1627-1646`) | Per-turn billing usage is now carried on the ACP `session/prompt` result (`usage` + `_meta.zcode.usage`), sourced from `turn.completed`; this RPC remains a candidate for session-cumulative reconciliation (deprecated upstream, see table above) |
97
+ | `session/compact` `instructions` + `result.compact` (`index.ts:1829-1853`) | Custom compact instructions; result acks `{state: accepted\|already_running, inputId?, operationId?}` | Not forwarded — `/compact <focus>` could pass instructions; the backend's own `already_running` ack can backstop the bridge's `autoCompactInFlight` single-flight |
98
+ | `session/debug` (`index.ts:3571`, `bootstrap/src/zcode-protocol/session-debug.ts`) | Per-session debug snapshot accumulated from the live event stream | Not used; `zcode-acp` diagnostics command / `/debug` extension |
99
+ | `session/list` rich params (`sessionIds` incl. hidden, `includeArchived`, `limit`, `index.ts:1600-1609`) | Explicit identity lookup, archived sessions | Not used |
100
+ | `session/create` extras: `toolAllowlist`/`toolDenylist` (per-session tool face — could move Cron* hiding off process-wide `--disallowed-tools`), `importedHistory` (claudeCode / sharedContext+sha256 provenance), `persistence:"immediate"\|"deferred"`, `titleGenerationEnabled:false` (bridge sets its own titles), `parentSessionId` (`index.ts:1558-1580`) | Session-creation knobs | Not forwarded; `session/resume` also takes `toolAllowlist`/`toolDenylist` — a resume WITHOUT them drops the tool face on cold recovery (`index.ts:1589-1595`) |
101
+ | `mcp/list` `mode:"status"` (`index.ts:686-723`) | Status without connecting: per-server `{status, transport, toolCount, failureKind(19-value enum), authorization{authorizationUrl}}` | Not used; editor MCP health panel + OAuth start URL without new transport |
102
+ | `process/childProcesses` (3.12.3) | List a session's child processes (`{pid, serverName, mcpSource, pluginName?}`, pure memory) | Not used; potentially useful for background-task diagnostics |
103
+ | `skills/referenceCatalog`, `plugins/referenceCatalog[WithCategory]` (categorized variant new in 0.16.9) | Session-scoped FROZEN catalogs — the authoritative per-session view vs the bridge's live disk reads | Not used; fixes the stale-catalog class of bug (backend freezes discovery at session start) |
104
+ | `workspace/readPresentation` (3.12.3) | The backend's own view of workspace mode + slash-command list | Not used; cross-check the bridge's disk-based slash discovery for drift |
105
+ | `workflows/*` family (NEW 0.16.9: `list/get/updateMeta/delete/runs/move`, `index.ts:2685-2937, 3618-3625`) | Session-less management of saved dynamic workflows (`<cwd>/.zcode/workflows/`, project+global scopes), run history with `artifacts`, cross-cwd runs query | Not used; pairs with v4 commands `startSavedWorkflow` / `resumeWorkflowRun` |
106
+ | `provider/testModelConnectivity` (3.12.3) | Probe a provider/model endpoint | Not used; model availability comes from the `session/create` response |
107
+ | `runtime/capabilities` (3.12.3; returns `{independentPlanState:true}`) | Trivial capability handshake | Not used; cheap preflight for a `zcode-acp doctor` command |
108
+ | `interaction/providerRuntimeHeadersCancelled` notification (`index.ts:336, 2396-2406`) | Backend cancels a pending runtime-headers refresh (workspace/session/requestId scoped) | Not handled; drop pending answerers immediately on turn cancel instead of waiting them out |
109
+ | `workspace/generateText` / `workspace/cancelGenerateText` (0.16.5) | Workspace-scoped one-shot text generation | Not used; no ACP counterpart |
110
+ | `workspace/updateInteractionPreferences` / `workspace/updateModelIoPreferences` | Client preference updates | Not used |
111
+ | `offPeak/{create,list}`, `workspace/updateOffPeakToolPolicy` (3.12.3) | Off-peak (discounted-hours) task family | Not used; `session/send` carries the matching `offPeakTaskId`/`offPeakRunType` params — candidate if a client wants to schedule discounted-hours runs. Off-peak tools are fail-closed at the protocol layer with three unlock channels (per-session param OR'd, process policy method, `offPeakPort` injection) |
112
+ | `automation/{create,update,list,delete,checkTaskBinding}` (3.12.3) | Scheduled (cron) task family — served by the host over `automation/*` requests | Not planned (see below) |
113
+ | `plugins/{list,setEnabled,overview,install,uninstall,update,cancelOperation,restoreBuiltin,configure,resetConfig,validate,describe}` + `plugins/marketplace/{add,remove,update}` (3.12.3) | Full plugin management + marketplace family | Not used — **compat watchpoint**: if upstream moves plugin distribution to the marketplace, the bridge's disk-based discovery (`config/plugin-commands.ts`) may go stale |
114
114
 
115
115
  ### `session/send` params (0.16.9-verified, `index.ts:1730-1768`)
116
116
 
@@ -120,7 +120,7 @@ expectedProviderRevision, automationId, offPeakTaskId, offPeakRunType,
120
120
  toolDenylist`. Not forwarded by the bridge today:
121
121
 
122
122
  - `modelSelection` — per-message model override `{providerId, modelId,
123
- options:{reasoningLevel?}}` (`packages/shared/src/model-selection.ts`); the
123
+ options:{reasoningLevel?}}` (`packages/shared/src/model-selection.ts`); the
124
124
  previously-listed `runtimeModel` does NOT exist in 0.16.9 (bundle-audit
125
125
  error). Enables per-turn model switching without a `session/setModel`
126
126
  round-trip.
@@ -146,21 +146,21 @@ toolDenylist`. Not forwarded by the bridge today:
146
146
 
147
147
  Notes per type (the ones with known bridge relevance):
148
148
 
149
- | Event | Notes |
150
- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
151
- | `session.titleUpdated` | **Wired** — `SessionTitleListener` adopts `generated`/`custom` pushes |
152
- | `message.upserted` / `message.removed` | Message-granular upsert/remove; the projection differ reconciles instead |
153
- | `part.started` / `part.delta` / `part.upserted` / `part.removed` | Message-PART granular streaming (the v4 conversation model on the v3 envelope) |
154
- | `permission.requested` / `permission.resolved` | Interaction lifecycle OBSERVER events; the bridge serves the request methods |
155
- | `userInput.requested` / `userInput.resolved` | Same, for user-input interactions |
156
- | `checkpoint.created` / `rewind.triggered` | Checkpoint + rewind lifecycle (rewinds initiated elsewhere are observable) |
157
- | `streamRecovery.updated` | Stream recovery progress — payload is an untyped `jsonObjectSchema` upstream; useful for the replay/gap-fill path |
158
- | `turn.started` payload extras (`index.ts:1168-1186`) | `executionKind:"agent"\|"controlOnly"` (controlOnly = no model turn — the bridge's own boot-resume ack could be classified by this instead of text-matching), `foregroundExecutionId` (feeds the precise v4 stop), `backgroundSource`, `intent`, `originMeta` |
159
- | `turn.steerQueued` / `turn.steerDrained` payloads (`index.ts:1191-1229`) | Queue length, `commandKind`, `delivery`, `targetTurnId`, drained `injectedMessageIds` — enough to render a proper "queued behind running turn" ACP update. Steer is only reachable via v4 delivery semantics (see Gotchas) — a steer caused by ANOTHER client on the same backend is visible here |
160
- | `turn.completed` `resultType` + `cacheStats` (`index.ts:1230-1261`) | `resultType: success\|cancelled\|error_max_turns\|error_max_budget\|error_during_execution\|error_max_tool_calls`; `cacheStats{totalMessages, cachedMessages, lastCacheHit, cacheReadTokens?}` — rich terminal lines + cache-health visibility |
161
- | `turn.failed` `turnPhase` (`index.ts:1262-1269`) | Failure phase string for better triage |
162
- | `model.streaming` kinds (`index.ts:987-1014`) | 13 kinds incl. `reasoning_*` deltas — relevant if thinking streams are ever surfaced directly |
163
- | `session.updated` with `state.updated` mutation reasons | Compact terminal state IS observable here: `session_compacted` / `session_compact_cancelled` / `session_compact_failed` (source: `server-operations.ts:2082-2119`) — the bridge can report real compact failures instead of assuming success from the RPC ack |
149
+ | Event | Notes |
150
+ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
151
+ | `session.titleUpdated` | **Wired** — `SessionTitleListener` adopts `generated`/`custom` pushes |
152
+ | `message.upserted` / `message.removed` | Message-granular upsert/remove; the projection differ reconciles instead |
153
+ | `part.started` / `part.delta` / `part.upserted` / `part.removed` | Message-PART granular streaming (the v4 conversation model on the v3 envelope) |
154
+ | `permission.requested` / `permission.resolved` | Interaction lifecycle OBSERVER events; the bridge serves the request methods |
155
+ | `userInput.requested` / `userInput.resolved` | Same, for user-input interactions |
156
+ | `checkpoint.created` / `rewind.triggered` | Checkpoint + rewind lifecycle (rewinds initiated elsewhere are observable) |
157
+ | `streamRecovery.updated` | Stream recovery progress — payload is an untyped `jsonObjectSchema` upstream; useful for the replay/gap-fill path |
158
+ | `turn.started` payload extras (`index.ts:1168-1186`) | `executionKind:"agent"\|"controlOnly"` (controlOnly = no model turn — the bridge's own boot-resume ack could be classified by this instead of text-matching), `foregroundExecutionId` (feeds the precise v4 stop), `backgroundSource`, `intent`, `originMeta` |
159
+ | `turn.steerQueued` / `turn.steerDrained` payloads (`index.ts:1191-1229`) | Queue length, `commandKind`, `delivery`, `targetTurnId`, drained `injectedMessageIds` — enough to render a proper "queued behind running turn" ACP update. Steer is only reachable via v4 delivery semantics (see Gotchas) — a steer caused by ANOTHER client on the same backend is visible here |
160
+ | `turn.completed` `resultType` + `cacheStats` (`index.ts:1230-1261`) | `resultType: success\|cancelled\|error_max_turns\|error_max_budget\|error_during_execution\|error_max_tool_calls`; `cacheStats{totalMessages, cachedMessages, lastCacheHit, cacheReadTokens?}` — rich terminal lines + cache-health visibility |
161
+ | `turn.failed` `turnPhase` (`index.ts:1262-1269`) | Failure phase string for better triage |
162
+ | `model.streaming` kinds (`index.ts:987-1014`) | 13 kinds incl. `reasoning_*` deltas — relevant if thinking streams are ever surfaced directly |
163
+ | `session.updated` with `state.updated` mutation reasons | Compact terminal state IS observable here: `session_compacted` / `session_compact_cancelled` / `session_compact_failed` (source: `server-operations.ts:2082-2119`) — the bridge can report real compact failures instead of assuming success from the RPC ack |
164
164
 
165
165
  **Corrected 2026-09-21 (source)**: `rewind.started` / `rewind.failed` /
166
166
  `rewind.completed`, `turn.attachments.resolved`, `usage.delta`, and
@@ -276,15 +276,35 @@ Status markers updated after the 2026-09-21 implementation pass. Details and
276
276
  matches 0.16.9's "A prompt is already running" wording (previously only
277
277
  the 0.16.5 "prompt is running" substring — on 0.16.9 every probe fell to
278
278
  the NON-LOCK branch and relied on the 30s grace).
279
- 4. **Drain-gate simplification**: mid-turn `session/send` now fails fast with
280
- `-32010` (whole-turn busy window; "1308" never existed in source) — the
281
- "accepted as steer and silently dropped" premise is obsolete. PENDING
282
- (core flow rewrite — needs its own change).
283
- 5. **`session/subagents`** → sub-agent status cards (waiting/blocked/lost
284
- detection); **`session/events` afterSeq** → gap-fill after drain-gate
285
- reloads instead of blind re-baseline. PENDING.
286
- 6. **`mcp/list mode:"status"`** → editor MCP health panel incl. OAuth
287
- `authorizationUrl`. PENDING.
279
+ 4. ~~**Drain-gate simplification**~~ **WIRED (behavior-adaptive,
280
+ 2026-09-21)** — `server.observedSendBusyReject`: once this backend
281
+ process has rejected a send with -32010 "A prompt is already running for
282
+ this session" (code AND message — -32010 is shared by unrelated errors),
283
+ the drain gate's pre-send poll (and its close-escalation) is skipped and
284
+ the send busy-retry loop is the single authority. Parity kept: one-shot
285
+ queued note on busy waits, post-accept differ re-baseline
286
+ (`sendAttempt > 1` ⇒ the abandoned turn unwound during our retries).
287
+ Backends that never showed the rejection keep the full legacy gate.
288
+ Regression tests: `tests/drain-gate-fast-path.test.ts`.
289
+ 5. ~~**`session/subagents`** + **`session/events` afterSeq**~~ **WIRED
290
+ (2026-09-21)** — sub-agent status text lines during silent phases: the
291
+ stall-reconcile probe polls `session/subagents` and surfaces roster
292
+ CHANGES as one-line `agent_message_chunk` updates (running/waiting/blocked
293
+ - a one-shot ended summary with failed/cancelled counts; best-effort,
294
+ -32601 backends are silent). Gap-fill landed via the ALREADY-WIRED
295
+ subscribe channel instead of the pull RPC: `resubscribe` consumes the
296
+ missed window the backend returns IN the subscribe response (`events`,
297
+ seq-ordered, deduped against the watermark), and the initial `subscribe`
298
+ now OMITS `afterSeq` — the old explicit `afterSeq: 0` made the backend
299
+ materialize the FULL event log into a response the bridge discarded,
300
+ every turn. `session/events` itself stays a `/debug`-only candidate.
301
+ Regression tests: `tests/subagent-status.test.ts`,
302
+ `tests/resubscribe-gap-fill.test.ts`.
303
+ 6. ~~**`mcp/list mode:"status"`**~~ **WIRED (2026-09-21)** — `/mcp` upgraded
304
+ to a live health panel (per-server `name · status · N tools ·
305
+ failureKind`, OAuth `authorizationUrl` indented beneath its server; any
306
+ RPC failure falls back to the local-discovery card). Regression tests:
307
+ `tests/mcp-health.test.ts`.
288
308
  7. ~~**Retire `session/updateRuntimeModelConfig`**~~ **DONE** — the ACP
289
309
  extension method and handler were removed (absent from the 0.16.9 enum,
290
310
  every call answered -32601); `setModel` + `applyModelSwitch` cover the
@@ -293,8 +313,11 @@ Status markers updated after the 2026-09-21 implementation pass. Details and
293
313
  answers at frame arrival, so nothing is ever pending;
294
314
  `interaction/providerRuntimeHeadersCancelled` is now logged-and-acked
295
315
  instead of silently ignored.
296
- 9. **`turn.completed` `resultType`/`cacheStats`** → rich terminal lines and
297
- cache-health visibility. PENDING.
316
+ 9. ~~**`turn.completed` `resultType`/`cacheStats`**~~ **WIRED (2026-09-21)** —
317
+ one turn-end status line per reply (agent_message_chunk, distinct
318
+ messageId): success renders prompt-cache stats (`cache N/M messages ·
319
+ cache-read tokens`), non-success resultTypes surface verbatim as a
320
+ warning line. Regression tests: `tests/turn-info-line.test.ts`.
298
321
  10. **Per-session `toolDenylist` at create/resume** — move Cron* hiding off
299
322
  process-wide `--disallowed-tools`; note a resume WITHOUT the lists drops
300
323
  the tool face on cold recovery. PENDING.
@@ -326,6 +349,7 @@ EOF
326
349
  Never conclude a method was removed from a single string-literal search; a
327
350
  missing dispatch case plus a live `-32601` is the proof. With the open-source
328
351
  checkout available, prefer reading `packages/shared/src/zcode-protocol/index.ts`
329
- + the dispatch switch in
330
- `apps/zcode-cli/packages/bootstrap/src/zcode-protocol/server.ts` first; fall
331
- back to this method only for released versions newer than the checkout.
352
+
353
+ - the dispatch switch in
354
+ `apps/zcode-cli/packages/bootstrap/src/zcode-protocol/server.ts` first; fall
355
+ back to this method only for released versions newer than the checkout.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zcode-acp-server",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
4
4
  "description": "Agent Client Protocol (ACP) server bridging headless ZCode to editors like Zed and JetBrains.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",