zcode-acp-server 0.47.10 → 0.48.1

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 (73) hide show
  1. package/README.md +1 -1
  2. package/dist/backend/adapter.d.ts +129 -0
  3. package/dist/backend/adapter.d.ts.map +1 -0
  4. package/dist/backend/adapter.js +71 -0
  5. package/dist/backend/adapter.js.map +1 -0
  6. package/dist/backend/client.d.ts +14 -103
  7. package/dist/backend/client.d.ts.map +1 -1
  8. package/dist/backend/client.js +63 -413
  9. package/dist/backend/client.js.map +1 -1
  10. package/dist/backend/index.d.ts +3 -1
  11. package/dist/backend/index.d.ts.map +1 -1
  12. package/dist/backend/index.js +2 -0
  13. package/dist/backend/index.js.map +1 -1
  14. package/dist/backend/jsonrpc-child.d.ts +128 -0
  15. package/dist/backend/jsonrpc-child.d.ts.map +1 -0
  16. package/dist/backend/jsonrpc-child.js +397 -0
  17. package/dist/backend/jsonrpc-child.js.map +1 -0
  18. package/dist/code-fingerprint.json +2 -2
  19. package/dist/config/options.d.ts.map +1 -1
  20. package/dist/config/options.js +14 -4
  21. package/dist/config/options.js.map +1 -1
  22. package/dist/config/workflow-gate.d.ts +97 -0
  23. package/dist/config/workflow-gate.d.ts.map +1 -0
  24. package/dist/config/workflow-gate.js +159 -0
  25. package/dist/config/workflow-gate.js.map +1 -0
  26. package/dist/handlers/background-tasks.d.ts.map +1 -1
  27. package/dist/handlers/background-tasks.js +56 -0
  28. package/dist/handlers/background-tasks.js.map +1 -1
  29. package/dist/handlers/dispatch.js +4 -0
  30. package/dist/handlers/dispatch.js.map +1 -1
  31. package/dist/handlers/session.d.ts +11 -0
  32. package/dist/handlers/session.d.ts.map +1 -1
  33. package/dist/handlers/session.js +80 -32
  34. package/dist/handlers/session.js.map +1 -1
  35. package/dist/handlers/slash.d.ts +7 -2
  36. package/dist/handlers/slash.d.ts.map +1 -1
  37. package/dist/handlers/slash.js +115 -4
  38. package/dist/handlers/slash.js.map +1 -1
  39. package/dist/i18n.d.ts +2 -0
  40. package/dist/i18n.d.ts.map +1 -1
  41. package/dist/i18n.js +6 -0
  42. package/dist/i18n.js.map +1 -1
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +7 -3
  45. package/dist/index.js.map +1 -1
  46. package/dist/remote/session-close-endpoint.d.ts.map +1 -1
  47. package/dist/remote/session-close-endpoint.js +6 -0
  48. package/dist/remote/session-close-endpoint.js.map +1 -1
  49. package/dist/remote/settings-endpoint.d.ts.map +1 -1
  50. package/dist/remote/settings-endpoint.js +380 -3
  51. package/dist/remote/settings-endpoint.js.map +1 -1
  52. package/dist/server.d.ts +49 -1
  53. package/dist/server.d.ts.map +1 -1
  54. package/dist/server.js +80 -0
  55. package/dist/server.js.map +1 -1
  56. package/dist/settings/workflow.d.ts +139 -0
  57. package/dist/settings/workflow.d.ts.map +1 -0
  58. package/dist/settings/workflow.js +443 -0
  59. package/dist/settings/workflow.js.map +1 -0
  60. package/dist/translators/tool-helpers.d.ts.map +1 -1
  61. package/dist/translators/tool-helpers.js +4 -0
  62. package/dist/translators/tool-helpers.js.map +1 -1
  63. package/dist/utils.d.ts +9 -0
  64. package/dist/utils.d.ts.map +1 -1
  65. package/dist/utils.js +8 -0
  66. package/dist/utils.js.map +1 -1
  67. package/dist/workflow/poller.d.ts +68 -0
  68. package/dist/workflow/poller.d.ts.map +1 -0
  69. package/dist/workflow/poller.js +290 -0
  70. package/dist/workflow/poller.js.map +1 -0
  71. package/docs/ARCHITECTURE.md +8 -6
  72. package/docs/BACKLOG.md +20 -2
  73. package/package.json +1 -1
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Dynamic-workflow run progress poller.
3
+ *
4
+ * The backend strips per-actor/per-node workflow progress from the v3 stream
5
+ * (session-mapper filters `dynamic_workflow_run_progress`; the authoritative
6
+ * projection lives behind the v4 conversation API), so an ACP client would see
7
+ * the CreateWorkflow card sit silent for the whole run. This module re-attaches
8
+ * progress by polling the v4 journal query and folding concise progress lines
9
+ * into the card as `tool_call_update` notifications.
10
+ *
11
+ * v4/conversation/workflowRunEvents {sessionId, runId, afterSequence, limit}
12
+ * → {events: [{sequence, type, payload, truncated?}], hasMore}
13
+ *
14
+ * The cursor is the journal sequence (never invalidated), so the poll is
15
+ * stateless and safe to re-issue. Runs are armed by the background-task
16
+ * listener (taskKind "workflow", taskId ≡ runId) — the SINGLE arm point,
17
+ * covering model-launched runs (visible CreateWorkflow card) and
18
+ * settings-launched ones (synthetic tool call, no live card — the fallback
19
+ * [background] card is the fold target). Emissions are append DELTAS (only
20
+ * the lines added since the previous emission) fanned out per-alias via
21
+ * `server.notifyByZcodeSid`, covering both turn-internal and turn-external
22
+ * runs.
23
+ *
24
+ * Everything here is best-effort: request() resolves `{error}` instead of
25
+ * throwing, and every failure path only logs — never into the event loop.
26
+ */
27
+ import type { ZcodeAcpServer } from "../server.js";
28
+ /** Poll cadence (setTimeout chain, timers unref'd). Injectable for tests. */
29
+ export declare const WORKFLOW_POLL_INTERVAL_MS = 3000;
30
+ /** One v4 journal event (transport.ts:599-646). */
31
+ interface WorkflowRunEvent {
32
+ sequence: number;
33
+ type: string;
34
+ payload?: Record<string, unknown>;
35
+ truncated?: boolean;
36
+ }
37
+ /**
38
+ * Reduce one journal event to a concise progress line, or null when the event
39
+ * is chatty (log/report/usage updates) and must not reach the card. Payload
40
+ * fields are read defensively — engine payload shapes are not part of the v4
41
+ * wire contract we consume, and raw ids (actorSessionId) are never printed.
42
+ */
43
+ export declare function workflowEventLine(ev: WorkflowRunEvent): string | null;
44
+ /**
45
+ * Arm the progress poller for a workflow run. Single-flight per runId: a
46
+ * re-arm (task status updates repeat the launch payload) is a no-op. The
47
+ * first poll fires after one interval.
48
+ */
49
+ export declare function armWorkflowRunPoller(server: ZcodeAcpServer, zcodeSid: string, opts: {
50
+ runId: string;
51
+ toolCallId: string;
52
+ intervalMs?: number;
53
+ }): void;
54
+ /** Stop the poller for one run (background task reached a terminal status). */
55
+ export declare function stopWorkflowRunPoller(runId: string): void;
56
+ /** Stop every poller (bridge shutdown — mirrors background-task shutdown records). */
57
+ export declare function stopAllWorkflowRunPollers(): void;
58
+ /**
59
+ * Stop every poller armed under one backend session (the session/close
60
+ * cleanup path). Best-effort, never throws — a closed session's journal
61
+ * answers can outlive the runtime, and polling it would only end at the hard
62
+ * cap with a stray timeout notice for a conversation nobody can see anymore.
63
+ */
64
+ export declare function stopPollersForSession(zcodeSid: string): void;
65
+ /** Test/observability hook: is a poller currently armed for this runId? */
66
+ export declare function workflowPollerActive(runId: string): boolean;
67
+ export {};
68
+ //# sourceMappingURL=poller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poller.d.ts","sourceRoot":"","sources":["../../src/workflow/poller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,6EAA6E;AAC7E,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAiB9C,mDAAmD;AACnD,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA+BD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAqCrE;AA6JD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/D,IAAI,CAsBN;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAKzD;AAED,sFAAsF;AACtF,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAI5D;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE3D"}
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Dynamic-workflow run progress poller.
3
+ *
4
+ * The backend strips per-actor/per-node workflow progress from the v3 stream
5
+ * (session-mapper filters `dynamic_workflow_run_progress`; the authoritative
6
+ * projection lives behind the v4 conversation API), so an ACP client would see
7
+ * the CreateWorkflow card sit silent for the whole run. This module re-attaches
8
+ * progress by polling the v4 journal query and folding concise progress lines
9
+ * into the card as `tool_call_update` notifications.
10
+ *
11
+ * v4/conversation/workflowRunEvents {sessionId, runId, afterSequence, limit}
12
+ * → {events: [{sequence, type, payload, truncated?}], hasMore}
13
+ *
14
+ * The cursor is the journal sequence (never invalidated), so the poll is
15
+ * stateless and safe to re-issue. Runs are armed by the background-task
16
+ * listener (taskKind "workflow", taskId ≡ runId) — the SINGLE arm point,
17
+ * covering model-launched runs (visible CreateWorkflow card) and
18
+ * settings-launched ones (synthetic tool call, no live card — the fallback
19
+ * [background] card is the fold target). Emissions are append DELTAS (only
20
+ * the lines added since the previous emission) fanned out per-alias via
21
+ * `server.notifyByZcodeSid`, covering both turn-internal and turn-external
22
+ * runs.
23
+ *
24
+ * Everything here is best-effort: request() resolves `{error}` instead of
25
+ * throwing, and every failure path only logs — never into the event loop.
26
+ */
27
+ import { log } from "../utils.js";
28
+ /** Poll cadence (setTimeout chain, timers unref'd). Injectable for tests. */
29
+ export const WORKFLOW_POLL_INTERVAL_MS = 3000;
30
+ /** Hard cap: no run polls longer than this, whatever the backend says. */
31
+ const WORKFLOW_POLL_HARD_TIMEOUT_MS = 10 * 60_000;
32
+ /** Consecutive poll failures tolerated before the poller gives up. */
33
+ const MAX_CONSECUTIVE_ERRORS = 5;
34
+ /** Page size per workflowRunEvents request (upstream cap 500). */
35
+ const EVENTS_PAGE_LIMIT = 100;
36
+ /** Pages drained back-to-back per tick while `hasMore` (runaway guard). */
37
+ const MAX_PAGES_PER_TICK = 50;
38
+ /** Cap on accumulated progress lines (keep first/last, drop the middle). */
39
+ const MAX_LINES = 200;
40
+ /** Active runs keyed by runId (taskId ≡ runId upstream — one key per run). */
41
+ const activeRuns = new Map();
42
+ /**
43
+ * Reduce one journal event to a concise progress line, or null when the event
44
+ * is chatty (log/report/usage updates) and must not reach the card. Payload
45
+ * fields are read defensively — engine payload shapes are not part of the v4
46
+ * wire contract we consume, and raw ids (actorSessionId) are never printed.
47
+ */
48
+ export function workflowEventLine(ev) {
49
+ const p = ev.payload ?? {};
50
+ const str = (k) => typeof p[k] === "string" ? p[k] : undefined;
51
+ const num = (k) => typeof p[k] === "number" ? p[k] : undefined;
52
+ switch (ev.type) {
53
+ case "actor-created": {
54
+ const name = str("name") ?? str("actorName");
55
+ const ordinal = num("ordinal");
56
+ const site = str("siteId") ?? str("actorSiteId");
57
+ const label = name ?? site;
58
+ const tag = ordinal !== undefined ? `#${ordinal}` : (site ?? "");
59
+ return label ? `+ actor ${tag} ${label}` : `+ actor ${tag}`.trim();
60
+ }
61
+ case "phase-entered": {
62
+ const phase = str("phaseName") ?? str("name");
63
+ return phase ? `> phase ${phase}` : "> phase";
64
+ }
65
+ case "run-settled": {
66
+ const status = str("status") ?? "unknown";
67
+ return `= run settled: ${status}`;
68
+ }
69
+ default: {
70
+ // Node lifecycle: only the SETTLED events carry an outcome worth a line.
71
+ if (!ev.type.startsWith("node-"))
72
+ return null;
73
+ const outcome = str("outcome");
74
+ if (outcome !== "ok" && outcome !== "failed" && outcome !== "cancelled")
75
+ return null;
76
+ const ordinal = num("ordinal");
77
+ const site = str("siteId");
78
+ const label = [site, ordinal !== undefined ? `#${ordinal}` : null]
79
+ .filter((x) => x !== null && x !== undefined && x !== "")
80
+ .join("/");
81
+ const icon = outcome === "ok" ? "✓" : outcome === "failed" ? "✗" : "–";
82
+ return label ? `${icon} node ${label} ${outcome}` : `${icon} node ${outcome}`;
83
+ }
84
+ }
85
+ }
86
+ /**
87
+ * Append a line under the cap: keep first/last halves with an ellipsis mark.
88
+ * The capped `lines` buffer is trim accounting only — emission sends the
89
+ * `pending` delta, so a trim that drops still-unemitted lines marks the gap
90
+ * with a one-time `…` line in that tick's delta.
91
+ */
92
+ function pushLine(run, line) {
93
+ run.lines.push(line);
94
+ run.pending.push(line);
95
+ if (run.lines.length > MAX_LINES) {
96
+ const half = Math.floor(MAX_LINES / 2);
97
+ run.lines = [...run.lines.slice(0, half), "…", ...run.lines.slice(-(half - 1))];
98
+ run.pending.push("…");
99
+ }
100
+ }
101
+ /**
102
+ * Emit the lines added since the previous emission (plus an optional one-off
103
+ * notice line) onto the CreateWorkflow card — append semantics, per-alias
104
+ * fan-out. A tick with nothing new emits nothing.
105
+ */
106
+ async function emitCardUpdate(run, notice) {
107
+ const delta = [...run.pending, ...(notice ? [notice] : [])];
108
+ run.pending = [];
109
+ if (delta.length === 0)
110
+ return;
111
+ const update = {
112
+ sessionUpdate: "tool_call_update",
113
+ toolCallId: run.toolCallId,
114
+ content: [{ type: "content", content: { type: "text", text: delta.join("\n") } }],
115
+ _meta: { workflowRun: { runId: run.runId, sequence: run.afterSequence } },
116
+ };
117
+ await run.server.notifyByZcodeSid(run.zcodeSid, update);
118
+ }
119
+ /** Tear the run down: clear the timer and forget it. Idempotent. */
120
+ function teardown(run) {
121
+ if (run.timer)
122
+ clearTimeout(run.timer);
123
+ run.timer = null;
124
+ run.stopped = true;
125
+ if (activeRuns.get(run.runId) === run)
126
+ activeRuns.delete(run.runId);
127
+ }
128
+ function scheduleNext(run) {
129
+ if (run.stopped)
130
+ return;
131
+ const t = setTimeout(() => void pollTick(run), run.intervalMs);
132
+ t.unref?.();
133
+ run.timer = t;
134
+ }
135
+ /**
136
+ * One poll tick: fetch journal pages (draining `hasMore` back-to-back), fold
137
+ * new lines, emit when something meaningful appeared, schedule the next tick.
138
+ */
139
+ async function pollTick(run) {
140
+ run.timer = null;
141
+ if (run.stopped || run.polling)
142
+ return;
143
+ run.polling = true;
144
+ let emitted = false;
145
+ try {
146
+ if (Date.now() - run.startedAt > WORKFLOW_POLL_HARD_TIMEOUT_MS) {
147
+ log(`workflow poller: run ${run.runId.slice(-8)} hit the 10min hard cap — stopping`);
148
+ await emitCardUpdate(run, "[progress polling stopped: timeout]");
149
+ teardown(run);
150
+ return;
151
+ }
152
+ const backend = run.server.backend;
153
+ if (!backend || backend.isDead) {
154
+ // Backend gone (respawn/shutdown): counts as an error; consecutive
155
+ // failures stop the poller naturally. Never ensureBackend() from here —
156
+ // a poller must not spawn backends as a side effect.
157
+ await handleError(run, { message: "backend unavailable" });
158
+ return;
159
+ }
160
+ for (let page = 0; page < MAX_PAGES_PER_TICK; page++) {
161
+ const resp = await backend.request(run.server.nextId(), "v4/conversation/workflowRunEvents", {
162
+ sessionId: run.zcodeSid,
163
+ runId: run.runId,
164
+ afterSequence: run.afterSequence,
165
+ limit: EVENTS_PAGE_LIMIT,
166
+ }, 8000);
167
+ if (resp.error) {
168
+ await handleError(run, resp.error);
169
+ return;
170
+ }
171
+ const result = resp.result;
172
+ const events = Array.isArray(result?.events) ? result.events : [];
173
+ for (const ev of events) {
174
+ if (typeof ev?.sequence === "number" && ev.sequence > run.afterSequence) {
175
+ run.afterSequence = ev.sequence;
176
+ }
177
+ const line = workflowEventLine(ev);
178
+ if (line) {
179
+ pushLine(run, line);
180
+ emitted = true;
181
+ }
182
+ if (ev.type === "run-settled") {
183
+ await emitCardUpdate(run);
184
+ log(`workflow poller: run ${run.runId.slice(-8)} settled — stopping`);
185
+ teardown(run);
186
+ return;
187
+ }
188
+ }
189
+ if (!result?.hasMore)
190
+ break;
191
+ }
192
+ run.consecutiveErrors = 0;
193
+ if (emitted)
194
+ await emitCardUpdate(run);
195
+ }
196
+ catch (e) {
197
+ // request() never throws; anything here is our own bug — count it as an
198
+ // error tick so the consecutive-failure stop still applies.
199
+ await handleError(run, {
200
+ message: e instanceof Error ? e.message : String(e),
201
+ });
202
+ }
203
+ finally {
204
+ run.polling = false;
205
+ // Stop paths tore the run down (stopped=true); transient errors keep
206
+ // polling. Scheduling from the finally so early `return`s never strand
207
+ // the chain.
208
+ scheduleNext(run);
209
+ }
210
+ }
211
+ /** Classify an error response: -32601 stops silently, everything else counts. */
212
+ async function handleError(run, error) {
213
+ if (error.code === -32601) {
214
+ // Backend build without the v4 family — log once, stop without a notice
215
+ // (the run itself is unaffected; only the progress folding is unavailable).
216
+ log(`workflow poller: backend has no v4/conversation/workflowRunEvents — ` +
217
+ `stopping run ${run.runId.slice(-8)}`);
218
+ teardown(run);
219
+ return;
220
+ }
221
+ run.consecutiveErrors += 1;
222
+ if (run.consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
223
+ log(`workflow poller: ${run.consecutiveErrors} consecutive failures — ` +
224
+ `stopping run ${run.runId.slice(-8)}`);
225
+ await emitCardUpdate(run, "[progress polling stopped: repeated errors]");
226
+ teardown(run);
227
+ return;
228
+ }
229
+ // Transient (timeout / dead pipe / backend respawn window) — retry next tick.
230
+ }
231
+ /**
232
+ * Arm the progress poller for a workflow run. Single-flight per runId: a
233
+ * re-arm (task status updates repeat the launch payload) is a no-op. The
234
+ * first poll fires after one interval.
235
+ */
236
+ export function armWorkflowRunPoller(server, zcodeSid, opts) {
237
+ const { runId, toolCallId } = opts;
238
+ if (!runId || !toolCallId)
239
+ return;
240
+ if (activeRuns.has(runId))
241
+ return;
242
+ const run = {
243
+ server,
244
+ zcodeSid,
245
+ runId,
246
+ toolCallId,
247
+ afterSequence: 0,
248
+ lines: [],
249
+ pending: [],
250
+ startedAt: Date.now(),
251
+ intervalMs: opts.intervalMs ?? WORKFLOW_POLL_INTERVAL_MS,
252
+ consecutiveErrors: 0,
253
+ stopped: false,
254
+ timer: null,
255
+ polling: false,
256
+ };
257
+ activeRuns.set(runId, run);
258
+ log(`workflow poller: armed for run ${runId.slice(-8)} on card ${toolCallId.slice(-12)}`);
259
+ scheduleNext(run);
260
+ }
261
+ /** Stop the poller for one run (background task reached a terminal status). */
262
+ export function stopWorkflowRunPoller(runId) {
263
+ const run = activeRuns.get(runId);
264
+ if (!run)
265
+ return;
266
+ teardown(run);
267
+ log(`workflow poller: stopped run ${runId.slice(-8)}`);
268
+ }
269
+ /** Stop every poller (bridge shutdown — mirrors background-task shutdown records). */
270
+ export function stopAllWorkflowRunPollers() {
271
+ for (const run of [...activeRuns.values()])
272
+ teardown(run);
273
+ }
274
+ /**
275
+ * Stop every poller armed under one backend session (the session/close
276
+ * cleanup path). Best-effort, never throws — a closed session's journal
277
+ * answers can outlive the runtime, and polling it would only end at the hard
278
+ * cap with a stray timeout notice for a conversation nobody can see anymore.
279
+ */
280
+ export function stopPollersForSession(zcodeSid) {
281
+ for (const run of [...activeRuns.values()]) {
282
+ if (run.zcodeSid === zcodeSid)
283
+ teardown(run);
284
+ }
285
+ }
286
+ /** Test/observability hook: is a poller currently armed for this runId? */
287
+ export function workflowPollerActive(runId) {
288
+ return activeRuns.has(runId);
289
+ }
290
+ //# sourceMappingURL=poller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poller.js","sourceRoot":"","sources":["../../src/workflow/poller.ts"],"names":[],"mappings":"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"}
@@ -153,11 +153,13 @@ API only because the ZCode backend itself sends them for inference.
153
153
 
154
154
  ### `backend/` — ZCode process communication
155
155
 
156
- | File | Responsibility |
157
- | ------------- | ----------------------------------------------------------------------------------------------- |
158
- | `client.ts` | Spawn/manage the zcode subprocess, reader-loop, request/response multiplexing, process watchdog |
159
- | `listener.ts` | EventStreamListener (subscribe/consume the event stream) and TurnMonitor (snapshot polling) |
160
- | `types.ts` | ZCode JSON-RPC message type definitions |
156
+ | File | Responsibility |
157
+ | ------------------ | ----------------------------------------------------------------------------------------------------------- |
158
+ | `adapter.ts` | `BackendAdapter` seam (ADR-0023): `BackendKind`, the capability table (single gate source), wire vocabulary |
159
+ | `jsonrpc-child.ts` | Shared stdio JSON-RPC transport: spawn, reader-loop, request multiplexing, watchdog, dialect hooks |
160
+ | `client.ts` | `ZcodeBackend` — the zcode dialect over `JsonRpcChild` (bare frames, arrival responders) |
161
+ | `listener.ts` | EventStreamListener (subscribe/consume the event stream) and TurnMonitor (snapshot polling) |
162
+ | `types.ts` | ZCode JSON-RPC message type definitions |
161
163
 
162
164
  ### `translators/` — Event translation
163
165
 
@@ -476,7 +478,7 @@ when the bridge exits cleanly enough for its signal handlers to fire
476
478
  crash, OOM), the handler never runs and the zcode subprocess group is
477
479
  orphaned.
478
480
 
479
- The watchdog (`backend/client.ts:startWatchdog`) closes that gap. It is a tiny
481
+ The watchdog (`backend/jsonrpc-child.ts:startWatchdog`) closes that gap. It is a tiny
480
482
  detached child that polls the bridge pid every 2s and, once the bridge is
481
483
  gone, sends SIGKILL to the zcode process group, then exits. It is its own
482
484
  process-group leader and `unref`'d, so it never holds the event loop open and
package/docs/BACKLOG.md CHANGED
@@ -23,6 +23,19 @@ version). Full audit detail with `file:line` evidence:
23
23
  `.zcode/scratch/alignment-protocol.md` (protocol surface) and
24
24
  `.zcode/scratch/alignment-hacks.md` (Gotchas verification).
25
25
 
26
+ **3.14.3 audit (2026-09-24, commit `328c1a0` — no bridge impact)**: the single
27
+ upstream release commit is entirely the dynamic-workflow subsystem (runtime
28
+ concurrency adjustment, modify/restart reuse, large-run status rendering,
29
+ script-submit token cost) plus bot delivery (`botDeliveryTarget` on
30
+ `session/send` and `automation/create` — both OPTIONAL fields the bridge
31
+ never sends — and the bots providers: feishu/telegram/weixin/webhook).
32
+ app-server stays `0.16.9`; `server-operations.ts` touches only the
33
+ botDeliveryTarget passthrough (stop's `activeAbortController` and compact's
34
+ `state.updated` swallow unchanged); provider bootstrap / runtime headers /
35
+ setModel / goal / fork untouched. `bundled-skills.ts` is the DWF skill pack's
36
+ own distribution channel (explicitly not in the settings page or `$` panel)
37
+ — no overlap with the bridge's filesystem skill discovery.
38
+
26
39
  **3.14.0 audit (2026-09-20, app-server 0.16.9 — live-probed end to end)**: the
27
40
  dynamic-workflow family (ten model tools led by `CreateWorkflow`) is OFF by
28
41
  default headless and enabled per PROCESS via
@@ -102,7 +115,7 @@ when a concrete ACP/editor need appears. Ranked shortlist in
102
115
  | `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
116
  | `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
117
  | `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` |
118
+ | `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 | **WIRED (2026-09-24, ADR-0029)**: proxied under `/settings/workflows*` + the local `/workflows` slash listing; availability is the remote `/client/configs` verdict (`src/config/workflow-gate.ts`), and `v4/command startSavedWorkflow`/`resumeWorkflowRun` + the `workflowRun*` queries are wired with it (see the v4 section below) |
106
119
  | `provider/testModelConnectivity` (3.12.3) | Probe a provider/model endpoint | Not used; model availability comes from the `session/create` response |
107
120
  | `runtime/capabilities` (3.12.3; returns `{independentPlanState:true}`) | Trivial capability handshake | Not used; cheap preflight for a `zcode-acp doctor` command |
108
121
  | `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 |
@@ -212,7 +225,12 @@ Topic model (`transport.ts:83-161`): subscribe with
212
225
  toSeq]` deltas — the watermark/CAS vocabulary row-targeting commands require
213
226
  (`baseRevision` + `baseLogEpoch`, `command.ts:293-317`).
214
227
 
215
- The bridge already speaks `v4/command` (the dual stop). Its payload union
228
+ The bridge already speaks `v4/command` (the dual stop), and since 2026-09-24
229
+ also `startSavedWorkflow` / `resumeWorkflowRun` (Settings API launch routes,
230
+ ADR-0029 — the ack is terminal, awaited via `request()`) plus the seven
231
+ `v4/conversation/workflowRun*` read queries (run progress poller + run-detail
232
+ routes). The launch consent is the API call itself (upstream skips the
233
+ permission popup for hub clicks). Its payload union
216
234
  (`command.ts:43-244`) is a single-method stepping stone to
217
235
  rewind/edit-turn/feedback/queue UX over ACP without implementing the v4
218
236
  subscription mesh: `sendText (requestedDelivery startNow|queue|guide,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zcode-acp-server",
3
- "version": "0.47.10",
3
+ "version": "0.48.1",
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",