@relayflows/sdk 2.0.20 → 2.0.21

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.
@@ -0,0 +1,4 @@
1
+ import type { ChildStop } from './child-stop.js';
2
+ /** Kill this agent tree if the process ends first. Returns the release. */
3
+ export declare function reapOnExit(stop: ChildStop): () => void;
4
+ //# sourceMappingURL=agent-reaper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-reaper.d.ts","sourceRoot":"","sources":["../src/agent-reaper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AA2CjD,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,IAAI,CAOtD"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * An agent CLI runs in a process group of its own, so nothing that ends this
3
+ * process reaches it by default: a signal to our pid, or to our group, leaves
4
+ * it running, reparented to init. That is how a `claude` outlived a Cloud run
5
+ * that was killed at its deadline, for hours. While any agent is live this
6
+ * module kills every live agent tree on the way out:
7
+ *
8
+ * - on `'exit'`, which covers normal exit and `process.exit()`;
9
+ * - on SIGINT, SIGTERM and SIGHUP, but only where the default action would
10
+ * have ended the process anyway — this listener is the only one. It then
11
+ * removes itself and re-raises the signal, so the process still dies of it.
12
+ * A host that installed its own listener owns that signal; it aborts the
13
+ * lease signal, and the abort already stops the tree.
14
+ *
15
+ * Nothing survives a SIGKILL of this process; that needs a supervisor.
16
+ */
17
+ const live = new Set();
18
+ const FATAL_SIGNALS = ['SIGINT', 'SIGTERM', 'SIGHUP'];
19
+ function killAll() {
20
+ for (const stop of live)
21
+ stop.kill();
22
+ live.clear();
23
+ }
24
+ function onFatalSignal(signal) {
25
+ if (process.listenerCount(signal) !== 1)
26
+ return;
27
+ killAll();
28
+ uninstall();
29
+ process.kill(process.pid, signal);
30
+ }
31
+ function install() {
32
+ process.on('exit', killAll);
33
+ for (const signal of FATAL_SIGNALS)
34
+ process.on(signal, onFatalSignal);
35
+ }
36
+ function uninstall() {
37
+ process.off('exit', killAll);
38
+ for (const signal of FATAL_SIGNALS)
39
+ process.off(signal, onFatalSignal);
40
+ }
41
+ /** Kill this agent tree if the process ends first. Returns the release. */
42
+ export function reapOnExit(stop) {
43
+ if (live.size === 0)
44
+ install();
45
+ live.add(stop);
46
+ return () => {
47
+ if (!live.delete(stop))
48
+ return;
49
+ if (live.size === 0)
50
+ uninstall();
51
+ };
52
+ }
53
+ //# sourceMappingURL=agent-reaper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-reaper.js","sourceRoot":"","sources":["../src/agent-reaper.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,IAAI,GAAG,IAAI,GAAG,EAAa,CAAC;AAClC,MAAM,aAAa,GAA8B,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEjF,SAAS,OAAO;IACd,KAAK,MAAM,IAAI,IAAI,IAAI;QAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IACrC,IAAI,CAAC,KAAK,EAAE,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,MAAsB;IAC3C,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC;QAAE,OAAO;IAChD,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,OAAO;IACd,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5B,KAAK,MAAM,MAAM,IAAI,aAAa;QAAE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,KAAK,MAAM,MAAM,IAAI,aAAa;QAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AACzE,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,UAAU,CAAC,IAAe;IACxC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACf,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO;QAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;YAAE,SAAS,EAAE,CAAC;IACnC,CAAC,CAAC;AACJ,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { ChildProcess } from 'node:child_process';
1
+ import { type ChildProcess } from 'node:child_process';
2
2
  /**
3
3
  * Grace between the graceful signal and the force kill. A tree that ignores
4
4
  * `SIGTERM` still has to go: it is holding the inherited stdio pipes that keep
@@ -1 +1 @@
1
- {"version":3,"file":"child-stop.d.ts","sourceRoot":"","sources":["../src/child-stop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AAEzC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,SAAS;IACxB,0CAA0C;IAC1C,IAAI,IAAI,IAAI,CAAC;IACb,gEAAgE;IAChE,SAAS,IAAI,IAAI,CAAC;IAClB;;;;;;;;;;;;;;;;;;OAkBG;IACH,oBAAoB,IAAI,OAAO,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAEzE;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,OAAO,EAClB,gBAAgB,GAAE,MAA4B,GAC7C,SAAS,CAsEX"}
1
+ {"version":3,"file":"child-stop.d.ts","sourceRoot":"","sources":["../src/child-stop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAErE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AAEzC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,SAAS;IACxB,0CAA0C;IAC1C,IAAI,IAAI,IAAI,CAAC;IACb,gEAAgE;IAChE,SAAS,IAAI,IAAI,CAAC;IAClB;;;;;;;;;;;;;;;;;;OAkBG;IACH,oBAAoB,IAAI,OAAO,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAEzE;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,OAAO,EAClB,gBAAgB,GAAE,MAA4B,GAC7C,SAAS,CAqFX"}
@@ -1,3 +1,4 @@
1
+ import { execFileSync } from 'node:child_process';
1
2
  /**
2
3
  * Grace between the graceful signal and the force kill. A tree that ignores
3
4
  * `SIGTERM` still has to go: it is holding the inherited stdio pipes that keep
@@ -28,27 +29,45 @@ export function childStop(child, ownsGroup, forceKillDelayMs = FORCE_KILL_DELAY_
28
29
  clearTimeout(forceTimer);
29
30
  forceTimer = undefined;
30
31
  };
31
- /** Whether anything is still in the group. See `maySettleOnChildExit`. */
32
+ // Descendants that moved into process groups of their own, captured at the
33
+ // first stop. Claude Code runs a `run_in_background` Bash command that way,
34
+ // so a group signal alone leaves it running after the agent is gone. They
35
+ // must be found while the direct child is still their ancestor: once it
36
+ // dies they are reparented and no longer traceable to this spawn.
37
+ let escapedGroups;
38
+ /**
39
+ * Whether anything the stop reaches is still alive: the child's own group or
40
+ * any group a descendant escaped into. See `maySettleOnChildExit`.
41
+ */
32
42
  const groupAnswers = () => {
33
43
  // With no group of our own a stop never reached past the direct child, so
34
44
  // that child's exit IS the whole of our reach and there is nothing left to
35
45
  // ask about.
36
46
  if (!ownsGroup || pid === undefined)
37
47
  return false;
38
- try {
39
- process.kill(-pid, 0);
40
- return true;
41
- }
42
- catch (error) {
43
- // Only `ESRCH` proves the group is empty. `EPERM` proves the opposite —
44
- // something is in there that we may not signal — and any other errno
45
- // proves nothing at all, so both must read as alive: an unproven group is
46
- // not a reason to spare a survivor.
47
- return error.code !== 'ESRCH';
48
- }
48
+ return [pid, ...(escapedGroups ?? [])].some(group => {
49
+ try {
50
+ process.kill(-group, 0);
51
+ return true;
52
+ }
53
+ catch (error) {
54
+ // Only `ESRCH` proves the group is empty. `EPERM` proves the opposite
55
+ // — something is in there that we may not signal — and any other
56
+ // errno proves nothing at all, so both must read as alive: an unproven
57
+ // group is not a reason to spare a survivor.
58
+ return error.code !== 'ESRCH';
59
+ }
60
+ });
49
61
  };
50
62
  const signalTree = (name) => {
51
63
  if (ownsGroup && pid !== undefined) {
64
+ escapedGroups ??= descendantGroups(pid);
65
+ for (const group of escapedGroups) {
66
+ try {
67
+ process.kill(-group, name);
68
+ }
69
+ catch { /* already gone */ }
70
+ }
52
71
  // `-pid` addresses the group this detached child leads, which is every
53
72
  // descendant that has not left it. It throws only once the whole group
54
73
  // is gone — the outcome we were asking for — so fall through and let the
@@ -91,4 +110,41 @@ export function childStop(child, ownsGroup, forceKillDelayMs = FORCE_KILL_DELAY_
91
110
  },
92
111
  };
93
112
  }
113
+ /**
114
+ * Process groups, other than `rootPid`'s own and this process's, that hold a
115
+ * descendant of `rootPid`. Reads `ps` for pid, parent and group only — never a
116
+ * command line. Where `ps` cannot answer, the answer is none: the group signal
117
+ * still reaches everything that stayed in the group.
118
+ */
119
+ function descendantGroups(rootPid) {
120
+ let table;
121
+ try {
122
+ table = execFileSync('ps', ['-A', '-o', 'pid=,ppid=,pgid='], {
123
+ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 2_000,
124
+ });
125
+ }
126
+ catch {
127
+ return [];
128
+ }
129
+ const children = new Map();
130
+ const groupOf = new Map();
131
+ for (const line of table.split('\n')) {
132
+ const fields = line.trim().split(/\s+/).map(Number);
133
+ if (fields.length !== 3 || !fields.every(Number.isSafeInteger))
134
+ continue;
135
+ const [row, parent, group] = fields;
136
+ groupOf.set(row, group);
137
+ children.set(parent, [...(children.get(parent) ?? []), row]);
138
+ }
139
+ const spared = new Set([rootPid, groupOf.get(process.pid)]);
140
+ const groups = new Set();
141
+ const pending = [...(children.get(rootPid) ?? [])];
142
+ for (let next = pending.pop(); next !== undefined; next = pending.pop()) {
143
+ const group = groupOf.get(next);
144
+ if (group !== undefined && group > 1 && !spared.has(group))
145
+ groups.add(group);
146
+ pending.push(...(children.get(next) ?? []));
147
+ }
148
+ return [...groups];
149
+ }
94
150
  //# sourceMappingURL=child-stop.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"child-stop.js","sourceRoot":"","sources":["../src/child-stop.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AA6CzC;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAA+B;IAC9D,OAAO,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,KAAmB,EACnB,SAAkB,EAClB,mBAA2B,mBAAmB;IAE9C,4EAA4E;IAC5E,0EAA0E;IAC1E,2EAA2E;IAC3E,6EAA6E;IAC7E,2EAA2E;IAC3E,6DAA6D;IAC7D,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACtB,IAAI,UAAsC,CAAC;IAC3C,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,IAAI,UAAU,KAAK,SAAS;YAAE,YAAY,CAAC,UAAU,CAAC,CAAC;QACvD,UAAU,GAAG,SAAS,CAAC;IACzB,CAAC,CAAC;IACF,0EAA0E;IAC1E,MAAM,YAAY,GAAG,GAAY,EAAE;QACjC,0EAA0E;QAC1E,2EAA2E;QAC3E,aAAa;QACb,IAAI,CAAC,SAAS,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAClD,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACtB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,wEAAwE;YACxE,qEAAqE;YACrE,0EAA0E;YAC1E,oCAAoC;YACpC,OAAQ,KAA+B,CAAC,IAAI,KAAK,OAAO,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,CAAC,IAAoB,EAAQ,EAAE;QAChD,IAAI,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACnC,uEAAuE;YACvE,uEAAuE;YACvE,yEAAyE;YACzE,oEAAoE;YACpE,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACzB,OAAO;YACT,CAAC;YAAC,MAAM,CAAC,CAAC,4CAA4C,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,CAAC;IACF,OAAO;QACL,IAAI,EAAE,GAAS,EAAE;YACf,MAAM,EAAE,CAAC;YACT,UAAU,CAAC,SAAS,CAAC,CAAC;QACxB,CAAC;QACD,SAAS,EAAE,GAAS,EAAE;YACpB,MAAM,EAAE,CAAC;YACT,UAAU,CAAC,SAAS,CAAC,CAAC;YACtB,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC3B,UAAU,GAAG,SAAS,CAAC;gBACvB,UAAU,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC,EAAE,gBAAgB,CAAC,CAAC;YACrB,yEAAyE;YACzE,yEAAyE;YACzE,yEAAyE;YACzE,wEAAwE;YACxE,qEAAqE;YACrE,+DAA+D;YAC/D,sDAAsD;QACxD,CAAC;QACD,oBAAoB,EAAE,GAAY,EAAE;YAClC,IAAI,UAAU,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YAC1C,IAAI,YAAY,EAAE;gBAAE,OAAO,KAAK,CAAC;YACjC,MAAM,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"child-stop.js","sourceRoot":"","sources":["../src/child-stop.ts"],"names":[],"mappings":"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"}
@@ -38,4 +38,12 @@ export interface AgentRelayContext {
38
38
  resultSchema?: unknown;
39
39
  }
40
40
  export declare function runAgentCli(cli: string, instruction: string, wakeContext: unknown, model?: string, wrapperLimits?: Partial<WrapperSessionLimits>, signal?: AbortSignal, mode?: 'agent' | 'llm', sidechannel?: SidechannelContext, cwd?: string, transport?: AgentTransport, relayContext?: AgentRelayContext): Promise<WorkerCliResult>;
41
+ /**
42
+ * How long a CLI that has reported its final result may take to exit. Claude
43
+ * Code in print mode waits, after its result, for every background task it
44
+ * started to finish; one that never finishes kept a finished step running
45
+ * until the whole run's deadline. Past this grace the result stands and the
46
+ * tree is stopped.
47
+ */
48
+ export declare const RESULT_EXIT_GRACE_MS = 30000;
41
49
  //# sourceMappingURL=worker-cli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker-cli.d.ts","sourceRoot":"","sources":["../src/worker-cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAWhF,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,4BAA4B,CAAC;AAEpC,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,SAAS,oBAAoB,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,OAAO,0BAA0B,EAAE,gBAAgB,CAAC;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,OAAO,EACpB,KAAK,CAAC,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,EAC7C,MAAM,CAAC,EAAE,WAAW,EACpB,IAAI,GAAE,OAAO,GAAG,KAAe,EAC/B,WAAW,CAAC,EAAE,kBAAkB,EAChC,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,GAAE,cAAyB,EACpC,YAAY,CAAC,EAAE,iBAAiB,GAC/B,OAAO,CAAC,eAAe,CAAC,CAgE1B"}
1
+ {"version":3,"file":"worker-cli.d.ts","sourceRoot":"","sources":["../src/worker-cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAahF,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,4BAA4B,CAAC;AAEpC,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,SAAS,oBAAoB,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,OAAO,0BAA0B,EAAE,gBAAgB,CAAC;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,OAAO,EACpB,KAAK,CAAC,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,EAC7C,MAAM,CAAC,EAAE,WAAW,EACpB,IAAI,GAAE,OAAO,GAAG,KAAe,EAC/B,WAAW,CAAC,EAAE,kBAAkB,EAChC,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,GAAE,cAAyB,EACpC,YAAY,CAAC,EAAE,iBAAiB,GAC/B,OAAO,CAAC,eAAe,CAAC,CAmE1B;AAuDD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,QAAS,CAAC"}
@@ -1,9 +1,11 @@
1
1
  import { resolve } from 'node:path';
2
2
  import { diffWorkspaceFiles, snapshotWorkspaceFiles } from './agent-artifacts.js';
3
- import { decodeProviderResult, decodeWrapperResult, requirePricedUsage } from './worker-usage.js';
3
+ import { claudeResultOutcome, decodeProviderResult, decodeWrapperResult, requirePricedUsage } from './worker-usage.js';
4
4
  import { openSidechannel } from './pty-sidechannel.js';
5
5
  import { spawn } from 'node:child_process';
6
- import { childStop, ownsProcessGroup } from './child-stop.js';
6
+ import { StringDecoder } from 'node:string_decoder';
7
+ import { childStop } from './child-stop.js';
8
+ import { reapOnExit } from './agent-reaper.js';
7
9
  import { agentExecution, llmExecution, cliAdapterKind, resolveCliModel, } from './cli-adapter.js';
8
10
  import { runWrapperSession, } from './wrapper-session.js';
9
11
  import { wrapperEnvironment } from './wrapper-runtime.js';
@@ -62,10 +64,13 @@ export async function runAgentCli(cli, instruction, wakeContext, model, wrapperL
62
64
  }
63
65
  if (invocation.modelEnv !== undefined)
64
66
  env[MODEL_ENV] = invocation.modelEnv;
65
- // Structured provider output carries the authoritative token counts.
67
+ // Structured provider output carries the authoritative token counts. Claude
68
+ // streams it, so its final result is seen when it is emitted rather than
69
+ // only once the process exits — which, after a background task, it may not.
66
70
  const args = [...invocation.args];
67
- args.splice(args.length - 1, 0, ...(kind === 'claude' ? ['--output-format', 'json'] : ['--json']));
68
- return requirePricedUsage(decodeProviderResult(await spawnInvocation(cli, { ...invocation, args }, env, signal, sidechannel, cwd), kind), effectiveModel);
71
+ args.splice(args.length - 1, 0, ...(kind === 'claude' ? ['--output-format', 'stream-json', '--verbose'] : ['--json']));
72
+ const completion = kind === 'claude' ? claudeResultOutcome : undefined;
73
+ return requirePricedUsage(decodeProviderResult(await spawnInvocation(cli, { ...invocation, args }, env, signal, sidechannel, cwd, completion), kind), effectiveModel);
69
74
  }
70
75
  }
71
76
  /** One agent at a time per canonical working directory, for the artifact interval. */
@@ -119,7 +124,15 @@ function redactRelayError(message) {
119
124
  }
120
125
  return message.replace(/\b(?:at|rk|nt|ot|br|arr)_(?:live_)?[A-Za-z0-9_-]+/g, '[redacted]');
121
126
  }
122
- async function spawnInvocation(cli, invocation, env, signal, sidechannel, cwd) {
127
+ /**
128
+ * How long a CLI that has reported its final result may take to exit. Claude
129
+ * Code in print mode waits, after its result, for every background task it
130
+ * started to finish; one that never finishes kept a finished step running
131
+ * until the whole run's deadline. Past this grace the result stands and the
132
+ * tree is stopped.
133
+ */
134
+ export const RESULT_EXIT_GRACE_MS = 30_000;
135
+ async function spawnInvocation(cli, invocation, env, signal, sidechannel, cwd, completion) {
123
136
  let writeInput = async () => false;
124
137
  let canDrive = () => false;
125
138
  let driven = false;
@@ -132,7 +145,9 @@ async function spawnInvocation(cli, invocation, env, signal, sidechannel, cwd) {
132
145
  signal.throwIfAborted();
133
146
  }
134
147
  return new Promise((resolve) => {
135
- const ownsGroup = ownsProcessGroup(signal);
148
+ // Always a group of its own off Windows, so every stop — and
149
+ // `reapOnExit` — reaches the whole agent tree, lease-bound or not.
150
+ const ownsGroup = process.platform !== 'win32';
136
151
  const child = spawn(cli, invocation.args, {
137
152
  stdio: ['pipe', 'pipe', 'pipe'], env,
138
153
  detached: ownsGroup,
@@ -158,10 +173,14 @@ async function spawnInvocation(cli, invocation, env, signal, sidechannel, cwd) {
158
173
  child.stdin.write(bytes, error => resolve(!error));
159
174
  });
160
175
  const stop = childStop(child, ownsGroup);
176
+ const release = ownsGroup ? reapOnExit(stop) : () => { };
161
177
  const stdout = [];
162
178
  const stderr = [];
163
179
  let settled = false;
164
180
  let timer;
181
+ let graceTimer;
182
+ const decoder = new StringDecoder('utf8');
183
+ let partialLine = '';
165
184
  const finish = (result) => {
166
185
  if (settled)
167
186
  return;
@@ -171,6 +190,8 @@ async function spawnInvocation(cli, invocation, env, signal, sidechannel, cwd) {
171
190
  channel?.close();
172
191
  if (timer !== undefined)
173
192
  clearTimeout(timer);
193
+ if (graceTimer !== undefined)
194
+ clearTimeout(graceTimer);
174
195
  signal?.removeEventListener('abort', onAbort);
175
196
  resolve(result);
176
197
  };
@@ -194,13 +215,47 @@ async function spawnInvocation(cli, invocation, env, signal, sidechannel, cwd) {
194
215
  signal?.addEventListener('abort', onAbort, { once: true });
195
216
  if (signal?.aborted)
196
217
  onAbort();
197
- child.stdout.on('data', (chunk) => { stdout.push(chunk); channel?.publish(chunk); });
218
+ /**
219
+ * The CLI has reported its final result. A normal exit inside the grace
220
+ * settles through `'close'` exactly as before, with the real exit code.
221
+ * Past it, the result settles the step with the exit status that result
222
+ * would have carried, and the stop outlives the settle as the timeout's
223
+ * does.
224
+ */
225
+ const onResult = (outcome) => {
226
+ if (graceTimer !== undefined || settled)
227
+ return;
228
+ graceTimer = setTimeout(() => {
229
+ stop.terminate();
230
+ finish({
231
+ exit_code: outcome.failed ? 1 : 0,
232
+ stdout_tail: Buffer.concat(stdout).toString('utf8'),
233
+ stderr_tail: `${Buffer.concat(stderr).toString('utf8')}\nCLI reported its final result but had not exited ${RESULT_EXIT_GRACE_MS}ms later; its process tree was stopped.`.trim(),
234
+ });
235
+ }, RESULT_EXIT_GRACE_MS);
236
+ };
237
+ child.stdout.on('data', (chunk) => {
238
+ stdout.push(chunk);
239
+ channel?.publish(chunk);
240
+ if (completion === undefined || graceTimer !== undefined)
241
+ return;
242
+ const lines = (partialLine + decoder.write(chunk)).split('\n');
243
+ partialLine = lines.pop() ?? '';
244
+ for (const line of lines) {
245
+ const outcome = completion(line);
246
+ if (outcome !== undefined)
247
+ onResult(outcome);
248
+ }
249
+ });
198
250
  child.stderr.on('data', (chunk) => { stderr.push(chunk); channel?.publish(chunk); });
199
251
  child.once('error', (error) => finishOnChildExit({
200
252
  exit_code: null,
201
253
  stdout_tail: Buffer.concat(stdout).toString('utf8'),
202
254
  stderr_tail: error.message,
203
255
  }));
256
+ child.once('error', () => { if (child.pid === undefined)
257
+ release(); });
258
+ child.once('close', release);
204
259
  child.once('close', (code) => finishOnChildExit({
205
260
  exit_code: code,
206
261
  stdout_tail: Buffer.concat(stdout).toString('utf8'),
@@ -1 +1 @@
1
- {"version":3,"file":"worker-cli.js","sourceRoot":"","sources":["../src/worker-cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker-cli.js","sourceRoot":"","sources":["../src/worker-cli.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,14 @@
1
1
  import type { WorkerCliResult } from './worker-cli.js';
2
2
  /** Provider envelopes are execution metadata, never the authored output. */
3
3
  export declare function decodeProviderResult(result: WorkerCliResult, kind: 'claude' | 'codex'): WorkerCliResult;
4
+ /**
5
+ * Claude's terminal `stream-json` frame, recognised line by line as it
6
+ * streams. `failed` mirrors the exit status Claude gives that result: an
7
+ * error flag or a non-success subtype is a failed run.
8
+ */
9
+ export declare function claudeResultOutcome(line: string): {
10
+ failed: boolean;
11
+ } | undefined;
4
12
  /** Optional wrapper result envelope; existing opaque text output stays valid. */
5
13
  export declare function decodeWrapperResult(result: WorkerCliResult): WorkerCliResult;
6
14
  export declare function requirePricedUsage(result: WorkerCliResult, model?: string): WorkerCliResult;
@@ -1 +1 @@
1
- {"version":3,"file":"worker-usage.d.ts","sourceRoot":"","sources":["../src/worker-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAoBvD,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,eAAe,CAUvG;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,CAK5E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAM3F"}
1
+ {"version":3,"file":"worker-usage.d.ts","sourceRoot":"","sources":["../src/worker-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAoBvD,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,eAAe,CAUvG;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAMjF;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,CAK5E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAM3F"}
@@ -31,6 +31,25 @@ export function decodeProviderResult(result, kind) {
31
31
  .flatMap(f => f.type === 'item.completed' && record(f.item) && f.item.type === 'agent_message' && typeof f.item.text === 'string' ? [f.item.text] : []).join('\n');
32
32
  return usageResult(result, terminal.usage, text);
33
33
  }
34
+ /**
35
+ * Claude's terminal `stream-json` frame, recognised line by line as it
36
+ * streams. `failed` mirrors the exit status Claude gives that result: an
37
+ * error flag or a non-success subtype is a failed run.
38
+ */
39
+ export function claudeResultOutcome(line) {
40
+ if (!line.includes('"result"'))
41
+ return undefined;
42
+ let frame;
43
+ try {
44
+ frame = JSON.parse(line);
45
+ }
46
+ catch {
47
+ return undefined;
48
+ }
49
+ if (!record(frame) || frame.type !== 'result')
50
+ return undefined;
51
+ return { failed: frame.is_error === true || (typeof frame.subtype === 'string' && frame.subtype !== 'success') };
52
+ }
34
53
  /** Optional wrapper result envelope; existing opaque text output stays valid. */
35
54
  export function decodeWrapperResult(result) {
36
55
  let value;
@@ -1 +1 @@
1
- {"version":3,"file":"worker-usage.js","sourceRoot":"","sources":["../src/worker-usage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker-usage.js","sourceRoot":"","sources":["../src/worker-usage.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relayflows/sdk",
3
- "version": "2.0.20",
3
+ "version": "2.0.21",
4
4
  "description": "TypeScript-first authoring SDK for Relayflows. Compiles specs; speaks the journal protocol.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -49,7 +49,7 @@
49
49
  "@modelcontextprotocol/sdk": "^1.30.0",
50
50
  "@relayfile/adapter-core": "0.5.26",
51
51
  "@relayfile/relay-helpers": "0.4.11",
52
- "@relayflows/surface": "2.0.20",
52
+ "@relayflows/surface": "2.0.21",
53
53
  "@types/js-yaml": "^4.0.9",
54
54
  "ai-hist": "0.4.1",
55
55
  "ajv": "^8.17.1",
@@ -0,0 +1,52 @@
1
+ import type { ChildStop } from './child-stop.js';
2
+
3
+ /**
4
+ * An agent CLI runs in a process group of its own, so nothing that ends this
5
+ * process reaches it by default: a signal to our pid, or to our group, leaves
6
+ * it running, reparented to init. That is how a `claude` outlived a Cloud run
7
+ * that was killed at its deadline, for hours. While any agent is live this
8
+ * module kills every live agent tree on the way out:
9
+ *
10
+ * - on `'exit'`, which covers normal exit and `process.exit()`;
11
+ * - on SIGINT, SIGTERM and SIGHUP, but only where the default action would
12
+ * have ended the process anyway — this listener is the only one. It then
13
+ * removes itself and re-raises the signal, so the process still dies of it.
14
+ * A host that installed its own listener owns that signal; it aborts the
15
+ * lease signal, and the abort already stops the tree.
16
+ *
17
+ * Nothing survives a SIGKILL of this process; that needs a supervisor.
18
+ */
19
+ const live = new Set<ChildStop>();
20
+ const FATAL_SIGNALS: readonly NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGHUP'];
21
+
22
+ function killAll(): void {
23
+ for (const stop of live) stop.kill();
24
+ live.clear();
25
+ }
26
+
27
+ function onFatalSignal(signal: NodeJS.Signals): void {
28
+ if (process.listenerCount(signal) !== 1) return;
29
+ killAll();
30
+ uninstall();
31
+ process.kill(process.pid, signal);
32
+ }
33
+
34
+ function install(): void {
35
+ process.on('exit', killAll);
36
+ for (const signal of FATAL_SIGNALS) process.on(signal, onFatalSignal);
37
+ }
38
+
39
+ function uninstall(): void {
40
+ process.off('exit', killAll);
41
+ for (const signal of FATAL_SIGNALS) process.off(signal, onFatalSignal);
42
+ }
43
+
44
+ /** Kill this agent tree if the process ends first. Returns the release. */
45
+ export function reapOnExit(stop: ChildStop): () => void {
46
+ if (live.size === 0) install();
47
+ live.add(stop);
48
+ return () => {
49
+ if (!live.delete(stop)) return;
50
+ if (live.size === 0) uninstall();
51
+ };
52
+ }
package/src/child-stop.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ChildProcess } from 'node:child_process';
1
+ import { execFileSync, type ChildProcess } from 'node:child_process';
2
2
 
3
3
  /**
4
4
  * Grace between the graceful signal and the force kill. A tree that ignores
@@ -78,25 +78,40 @@ export function childStop(
78
78
  if (forceTimer !== undefined) clearTimeout(forceTimer);
79
79
  forceTimer = undefined;
80
80
  };
81
- /** Whether anything is still in the group. See `maySettleOnChildExit`. */
81
+ // Descendants that moved into process groups of their own, captured at the
82
+ // first stop. Claude Code runs a `run_in_background` Bash command that way,
83
+ // so a group signal alone leaves it running after the agent is gone. They
84
+ // must be found while the direct child is still their ancestor: once it
85
+ // dies they are reparented and no longer traceable to this spawn.
86
+ let escapedGroups: readonly number[] | undefined;
87
+ /**
88
+ * Whether anything the stop reaches is still alive: the child's own group or
89
+ * any group a descendant escaped into. See `maySettleOnChildExit`.
90
+ */
82
91
  const groupAnswers = (): boolean => {
83
92
  // With no group of our own a stop never reached past the direct child, so
84
93
  // that child's exit IS the whole of our reach and there is nothing left to
85
94
  // ask about.
86
95
  if (!ownsGroup || pid === undefined) return false;
87
- try {
88
- process.kill(-pid, 0);
89
- return true;
90
- } catch (error) {
91
- // Only `ESRCH` proves the group is empty. `EPERM` proves the opposite —
92
- // something is in there that we may not signal — and any other errno
93
- // proves nothing at all, so both must read as alive: an unproven group is
94
- // not a reason to spare a survivor.
95
- return (error as NodeJS.ErrnoException).code !== 'ESRCH';
96
- }
96
+ return [pid, ...(escapedGroups ?? [])].some(group => {
97
+ try {
98
+ process.kill(-group, 0);
99
+ return true;
100
+ } catch (error) {
101
+ // Only `ESRCH` proves the group is empty. `EPERM` proves the opposite
102
+ // — something is in there that we may not signal — and any other
103
+ // errno proves nothing at all, so both must read as alive: an unproven
104
+ // group is not a reason to spare a survivor.
105
+ return (error as NodeJS.ErrnoException).code !== 'ESRCH';
106
+ }
107
+ });
97
108
  };
98
109
  const signalTree = (name: NodeJS.Signals): void => {
99
110
  if (ownsGroup && pid !== undefined) {
111
+ escapedGroups ??= descendantGroups(pid);
112
+ for (const group of escapedGroups) {
113
+ try { process.kill(-group, name); } catch { /* already gone */ }
114
+ }
100
115
  // `-pid` addresses the group this detached child leads, which is every
101
116
  // descendant that has not left it. It throws only once the whole group
102
117
  // is gone — the outcome we were asking for — so fall through and let the
@@ -136,3 +151,38 @@ export function childStop(
136
151
  },
137
152
  };
138
153
  }
154
+
155
+ /**
156
+ * Process groups, other than `rootPid`'s own and this process's, that hold a
157
+ * descendant of `rootPid`. Reads `ps` for pid, parent and group only — never a
158
+ * command line. Where `ps` cannot answer, the answer is none: the group signal
159
+ * still reaches everything that stayed in the group.
160
+ */
161
+ function descendantGroups(rootPid: number): number[] {
162
+ let table: string;
163
+ try {
164
+ table = execFileSync('ps', ['-A', '-o', 'pid=,ppid=,pgid='], {
165
+ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 2_000,
166
+ });
167
+ } catch {
168
+ return [];
169
+ }
170
+ const children = new Map<number, number[]>();
171
+ const groupOf = new Map<number, number>();
172
+ for (const line of table.split('\n')) {
173
+ const fields = line.trim().split(/\s+/).map(Number);
174
+ if (fields.length !== 3 || !fields.every(Number.isSafeInteger)) continue;
175
+ const [row, parent, group] = fields as [number, number, number];
176
+ groupOf.set(row, group);
177
+ children.set(parent, [...(children.get(parent) ?? []), row]);
178
+ }
179
+ const spared = new Set([rootPid, groupOf.get(process.pid)]);
180
+ const groups = new Set<number>();
181
+ const pending = [...(children.get(rootPid) ?? [])];
182
+ for (let next = pending.pop(); next !== undefined; next = pending.pop()) {
183
+ const group = groupOf.get(next);
184
+ if (group !== undefined && group > 1 && !spared.has(group)) groups.add(group);
185
+ pending.push(...(children.get(next) ?? []));
186
+ }
187
+ return [...groups];
188
+ }
package/src/worker-cli.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import { resolve } from 'node:path';
2
2
  import { diffWorkspaceFiles, snapshotWorkspaceFiles } from './agent-artifacts.js';
3
- import { decodeProviderResult, decodeWrapperResult, requirePricedUsage } from './worker-usage.js';
3
+ import { claudeResultOutcome, decodeProviderResult, decodeWrapperResult, requirePricedUsage } from './worker-usage.js';
4
4
  import { openSidechannel, type SidechannelContext } from './pty-sidechannel.js';
5
5
  import { spawn } from 'node:child_process';
6
- import { childStop, ownsProcessGroup } from './child-stop.js';
6
+ import { StringDecoder } from 'node:string_decoder';
7
+ import { childStop } from './child-stop.js';
8
+ import { reapOnExit } from './agent-reaper.js';
7
9
  import {
8
10
  agentExecution,
9
11
  llmExecution,
@@ -134,10 +136,13 @@ export async function runAgentCli(
134
136
  }
135
137
 
136
138
  if (invocation.modelEnv !== undefined) env[MODEL_ENV] = invocation.modelEnv;
137
- // Structured provider output carries the authoritative token counts.
139
+ // Structured provider output carries the authoritative token counts. Claude
140
+ // streams it, so its final result is seen when it is emitted rather than
141
+ // only once the process exits — which, after a background task, it may not.
138
142
  const args = [...invocation.args];
139
- args.splice(args.length - 1, 0, ...(kind === 'claude' ? ['--output-format', 'json'] : ['--json']));
140
- return requirePricedUsage(decodeProviderResult(await spawnInvocation(cli, { ...invocation, args }, env, signal, sidechannel, cwd), kind), effectiveModel);
143
+ args.splice(args.length - 1, 0, ...(kind === 'claude' ? ['--output-format', 'stream-json', '--verbose'] : ['--json']));
144
+ const completion = kind === 'claude' ? claudeResultOutcome : undefined;
145
+ return requirePricedUsage(decodeProviderResult(await spawnInvocation(cli, { ...invocation, args }, env, signal, sidechannel, cwd, completion), kind), effectiveModel);
141
146
  }
142
147
  }
143
148
 
@@ -194,6 +199,15 @@ function redactRelayError(message: string): string {
194
199
  return message.replace(/\b(?:at|rk|nt|ot|br|arr)_(?:live_)?[A-Za-z0-9_-]+/g, '[redacted]');
195
200
  }
196
201
 
202
+ /**
203
+ * How long a CLI that has reported its final result may take to exit. Claude
204
+ * Code in print mode waits, after its result, for every background task it
205
+ * started to finish; one that never finishes kept a finished step running
206
+ * until the whole run's deadline. Past this grace the result stands and the
207
+ * tree is stopped.
208
+ */
209
+ export const RESULT_EXIT_GRACE_MS = 30_000;
210
+
197
211
  async function spawnInvocation(
198
212
  cli: string,
199
213
  invocation: CliInvocation,
@@ -201,6 +215,7 @@ async function spawnInvocation(
201
215
  signal?: AbortSignal,
202
216
  sidechannel?: SidechannelContext,
203
217
  cwd?: string,
218
+ completion?: (line: string) => { failed: boolean } | undefined,
204
219
  ): Promise<WorkerCliResult> {
205
220
  let writeInput: (bytes: Buffer) => Promise<boolean> = async () => false;
206
221
  let canDrive = () => false;
@@ -211,7 +226,9 @@ async function spawnInvocation(
211
226
  }, bytes => writeInput(bytes), () => canDrive());
212
227
  if (signal?.aborted) { channel?.close(); signal.throwIfAborted(); }
213
228
  return new Promise((resolve) => {
214
- const ownsGroup = ownsProcessGroup(signal);
229
+ // Always a group of its own off Windows, so every stop — and
230
+ // `reapOnExit` — reaches the whole agent tree, lease-bound or not.
231
+ const ownsGroup = process.platform !== 'win32';
215
232
  const child = spawn(cli, invocation.args, {
216
233
  stdio: ['pipe', 'pipe', 'pipe'], env,
217
234
  detached: ownsGroup,
@@ -232,16 +249,21 @@ async function spawnInvocation(
232
249
  child.stdin.write(bytes, error => resolve(!error));
233
250
  });
234
251
  const stop = childStop(child, ownsGroup);
252
+ const release = ownsGroup ? reapOnExit(stop) : () => {};
235
253
  const stdout: Buffer[] = [];
236
254
  const stderr: Buffer[] = [];
237
255
  let settled = false;
238
256
  let timer: NodeJS.Timeout | undefined;
257
+ let graceTimer: NodeJS.Timeout | undefined;
258
+ const decoder = new StringDecoder('utf8');
259
+ let partialLine = '';
239
260
  const finish = (result: WorkerCliResult): void => {
240
261
  if (settled) return;
241
262
  settled = true;
242
263
  if (inputTimer !== undefined) clearTimeout(inputTimer);
243
264
  channel?.close();
244
265
  if (timer !== undefined) clearTimeout(timer);
266
+ if (graceTimer !== undefined) clearTimeout(graceTimer);
245
267
  signal?.removeEventListener('abort', onAbort);
246
268
  resolve(result);
247
269
  };
@@ -263,13 +285,43 @@ async function spawnInvocation(
263
285
  };
264
286
  signal?.addEventListener('abort', onAbort, { once: true });
265
287
  if (signal?.aborted) onAbort();
266
- child.stdout.on('data', (chunk: Buffer) => { stdout.push(chunk); channel?.publish(chunk); });
288
+ /**
289
+ * The CLI has reported its final result. A normal exit inside the grace
290
+ * settles through `'close'` exactly as before, with the real exit code.
291
+ * Past it, the result settles the step with the exit status that result
292
+ * would have carried, and the stop outlives the settle as the timeout's
293
+ * does.
294
+ */
295
+ const onResult = (outcome: { failed: boolean }): void => {
296
+ if (graceTimer !== undefined || settled) return;
297
+ graceTimer = setTimeout(() => {
298
+ stop.terminate();
299
+ finish({
300
+ exit_code: outcome.failed ? 1 : 0,
301
+ stdout_tail: Buffer.concat(stdout).toString('utf8'),
302
+ stderr_tail: `${Buffer.concat(stderr).toString('utf8')}\nCLI reported its final result but had not exited ${RESULT_EXIT_GRACE_MS}ms later; its process tree was stopped.`.trim(),
303
+ });
304
+ }, RESULT_EXIT_GRACE_MS);
305
+ };
306
+ child.stdout.on('data', (chunk: Buffer) => {
307
+ stdout.push(chunk);
308
+ channel?.publish(chunk);
309
+ if (completion === undefined || graceTimer !== undefined) return;
310
+ const lines = (partialLine + decoder.write(chunk)).split('\n');
311
+ partialLine = lines.pop() ?? '';
312
+ for (const line of lines) {
313
+ const outcome = completion(line);
314
+ if (outcome !== undefined) onResult(outcome);
315
+ }
316
+ });
267
317
  child.stderr.on('data', (chunk: Buffer) => { stderr.push(chunk); channel?.publish(chunk); });
268
318
  child.once('error', (error) => finishOnChildExit({
269
319
  exit_code: null,
270
320
  stdout_tail: Buffer.concat(stdout).toString('utf8'),
271
321
  stderr_tail: error.message,
272
322
  }));
323
+ child.once('error', () => { if (child.pid === undefined) release(); });
324
+ child.once('close', release);
273
325
  child.once('close', (code) => finishOnChildExit({
274
326
  exit_code: code,
275
327
  stdout_tail: Buffer.concat(stdout).toString('utf8'),
@@ -31,6 +31,19 @@ export function decodeProviderResult(result: WorkerCliResult, kind: 'claude' | '
31
31
  return usageResult(result, terminal.usage, text);
32
32
  }
33
33
 
34
+ /**
35
+ * Claude's terminal `stream-json` frame, recognised line by line as it
36
+ * streams. `failed` mirrors the exit status Claude gives that result: an
37
+ * error flag or a non-success subtype is a failed run.
38
+ */
39
+ export function claudeResultOutcome(line: string): { failed: boolean } | undefined {
40
+ if (!line.includes('"result"')) return undefined;
41
+ let frame: unknown;
42
+ try { frame = JSON.parse(line); } catch { return undefined; }
43
+ if (!record(frame) || frame.type !== 'result') return undefined;
44
+ return { failed: frame.is_error === true || (typeof frame.subtype === 'string' && frame.subtype !== 'success') };
45
+ }
46
+
34
47
  /** Optional wrapper result envelope; existing opaque text output stays valid. */
35
48
  export function decodeWrapperResult(result: WorkerCliResult): WorkerCliResult {
36
49
  let value: unknown;