@namzu/sdk 14.0.2 → 14.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # Changelog
2
2
 
3
+ ## 14.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - b4a3fa7: `StdioTransport.close()` resolves when the child is gone, not when the signal
8
+ was sent.
9
+
10
+ It called `kill('SIGTERM')` and returned. `kill()` returns as soon as the
11
+ signal is delivered, so an awaited `close()` meant "SIGTERM is on its way", and
12
+ a caller that closed a transport and then deleted the child's working directory
13
+ raced the exit — reported as `EBUSY` from a real integration, not inferred. A
14
+ close that does not mean closed makes every teardown built on it a guess, and
15
+ the guess is only wrong sometimes.
16
+
17
+ `close()` now waits for the child's `exit`. A child ignoring SIGTERM is sent
18
+ SIGKILL after two seconds, and a second timer gives up waiting, so `close()`
19
+ cannot hang; both timers are unreferenced, so neither holds the event loop
20
+ open. A spawn that never produced a process emits `error` and no `exit`, and
21
+ that path settles too rather than waiting for an event that is not coming.
22
+
23
+ ## 14.0.3
24
+
25
+ ### Patch Changes
26
+
27
+ - c50f9bf: `ProjectManager.archive` refuses when it cannot establish the precondition.
28
+
29
+ 14.0.0 shipped archival that "refuses rather than cascading" — a workspace with
30
+ a live session throws `ProjectNotEmptyError` instead of closing over running
31
+ work. The check read the session list as
32
+ `(await store.listSessionsByProject?.(...)) ?? []`, and `listSessionsByProject`
33
+ is optional. So on a store that does not implement it, "this store cannot tell
34
+ me what is running here" became "nothing is running here": the workspace closed
35
+ over live sessions and the call returned success.
36
+
37
+ It now throws, naming the missing method and what to do instead. Both stores in
38
+ this package implement it, so nothing in-tree changes; a host with its own
39
+ `SessionStore` gets a refusal where it previously got a wrong answer.
40
+
41
+ The mistake is worth naming, because the two halves are each correct and only
42
+ the combination is not. Optional-on-the-interface protects implementors: a
43
+ host's own store should not stop compiling because the SDK grew a method. It
44
+ cannot also mean a **safety precondition silently passes**. Where a store
45
+ cannot answer the question the check exists to ask, the answer is a refusal,
46
+ not a default.
47
+
3
48
  ## 14.0.2
4
49
 
5
50
  ### Patch Changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=a-close-that-means-closed.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a-close-that-means-closed.test.d.ts","sourceRoot":"","sources":["../../../../src/connector/mcp/__tests__/a-close-that-means-closed.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,106 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { StdioTransport } from '../stdio.js';
3
+ /**
4
+ * `close()` sent SIGTERM and returned without waiting, so a resolved close
5
+ * meant "the signal is on its way", not "the child is gone". A caller that
6
+ * closed a transport and then deleted the child's working directory raced the
7
+ * exit and saw EBUSY — reported from a real integration, not inferred.
8
+ *
9
+ * A close that does not mean closed makes every teardown built on top of it a
10
+ * guess, and the guess is only wrong sometimes, which is the worst kind.
11
+ *
12
+ * These assert on the operating system rather than on the transport's own
13
+ * state: `process.kill(pid, 0)` throws ESRCH once the pid is gone, so the
14
+ * assertion cannot pass by the transport merely believing it closed.
15
+ */
16
+ /** The child the transport spawned, read before `close()` clears the field. */
17
+ function childOf(transport) {
18
+ const child = transport.process;
19
+ if (!child)
20
+ throw new Error('transport spawned no process');
21
+ return child;
22
+ }
23
+ function pidOf(transport) {
24
+ const pid = childOf(transport).pid;
25
+ if (pid === undefined)
26
+ throw new Error('transport spawned no process');
27
+ return pid;
28
+ }
29
+ function isAlive(pid) {
30
+ try {
31
+ process.kill(pid, 0);
32
+ return true;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ describe('a close that means closed', () => {
39
+ it('does not resolve until the child is actually gone', async () => {
40
+ const transport = new StdioTransport({
41
+ type: 'stdio',
42
+ command: process.execPath,
43
+ args: ['-e', 'setInterval(() => {}, 1000)'],
44
+ });
45
+ await transport.connect();
46
+ const child = childOf(transport);
47
+ const pid = pidOf(transport);
48
+ expect(isAlive(pid)).toBe(true);
49
+ await transport.close();
50
+ // The reaped-ness of the child, not the liveness of the pid.
51
+ //
52
+ // `isAlive(pid)` alone is sound about the wrong thing: on Windows
53
+ // `kill('SIGTERM')` terminates the process synchronously, so the pid is
54
+ // already gone by the next line whether or not `close()` waited — the
55
+ // assertion passed under a deliberately reintroduced fire-and-forget
56
+ // kill, which is how this was caught. Node fills `exitCode`/`signalCode`
57
+ // only when it reaps the child and emits `exit`, a later tick, so these
58
+ // are non-null here exactly when `close()` awaited that event.
59
+ expect(child.exitCode !== null || child.signalCode !== null).toBe(true);
60
+ expect(isAlive(pid)).toBe(false);
61
+ });
62
+ it('returns rather than hanging when the command does not exist', async () => {
63
+ // A spawn that fails emits `error` and never `exit`. Waiting on `exit`
64
+ // alone would turn a bad command into a shutdown that never completes.
65
+ const transport = new StdioTransport({
66
+ type: 'stdio',
67
+ command: 'namzu-no-such-command-exists-here',
68
+ args: [],
69
+ });
70
+ await transport.connect();
71
+ await expect(transport.close()).resolves.toBeUndefined();
72
+ });
73
+ it('is safe to call twice', async () => {
74
+ const transport = new StdioTransport({
75
+ type: 'stdio',
76
+ command: process.execPath,
77
+ args: ['-e', 'setInterval(() => {}, 1000)'],
78
+ });
79
+ await transport.connect();
80
+ const pid = pidOf(transport);
81
+ await transport.close();
82
+ await transport.close();
83
+ expect(isAlive(pid)).toBe(false);
84
+ });
85
+ it('reports the exit to the handler registered for that session', async () => {
86
+ // The waiting must not swallow the notification the client depends on
87
+ // to learn the session ended.
88
+ const transport = new StdioTransport({
89
+ type: 'stdio',
90
+ command: process.execPath,
91
+ args: ['-e', 'setInterval(() => {}, 1000)'],
92
+ });
93
+ await transport.connect();
94
+ let closes = 0;
95
+ transport.onClose(() => {
96
+ closes++;
97
+ });
98
+ await transport.close();
99
+ // `close` on a ChildProcess follows `exit` by a tick once the stdio
100
+ // streams drain; give the loop that tick rather than asserting on a
101
+ // race.
102
+ await new Promise((resolve) => setTimeout(resolve, 50));
103
+ expect(closes).toBe(1);
104
+ });
105
+ });
106
+ //# sourceMappingURL=a-close-that-means-closed.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a-close-that-means-closed.test.js","sourceRoot":"","sources":["../../../../src/connector/mcp/__tests__/a-close-that-means-closed.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../../src/connector/mcp/stdio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,MAAM,gCAAgC,CAAA;AAGvC,qBAAa,cAAe,YAAW,YAAY;IAWtC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVnC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,eAAe,CAAkD;IACzE,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,SAAS,CAAQ;IACzB,6DAA6D;IAC7D,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,GAAG,CAAQ;gBAEU,MAAM,EAAE,uBAAuB;IAItD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB5B;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAMf,IAAI,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQrD,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,GAAG,IAAI;IAI9D,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIlC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI9C,WAAW,IAAI,OAAO;IAItB,OAAO,CAAC,aAAa;CAerB"}
1
+ {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../../src/connector/mcp/stdio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,MAAM,gCAAgC,CAAA;AAUvC,qBAAa,cAAe,YAAW,YAAY;IAWtC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVnC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,eAAe,CAAkD;IACzE,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,SAAS,CAAQ;IACzB,6DAA6D;IAC7D,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,GAAG,CAAQ;gBAEU,MAAM,EAAE,uBAAuB;IAItD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD5B;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAMf,IAAI,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQrD,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,GAAG,IAAI;IAI9D,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIlC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI9C,WAAW,IAAI,OAAO;IAItB,OAAO,CAAC,aAAa;CAerB"}
@@ -1,5 +1,11 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { getRootLogger } from '../../utils/logger.js';
3
+ /**
4
+ * How long a child gets to honour SIGTERM before SIGKILL. Two seconds is
5
+ * long enough for a server flushing a response and short enough that a
6
+ * shutdown does not read as a hang.
7
+ */
8
+ const TERMINATE_GRACE_MS = 2_000;
3
9
  export class StdioTransport {
4
10
  config;
5
11
  process = null;
@@ -60,9 +66,40 @@ export class StdioTransport {
60
66
  }
61
67
  this.connected = false;
62
68
  this.exitPending = true;
63
- this.process.kill('SIGTERM');
69
+ const child = this.process;
64
70
  this.process = null;
65
71
  this.buffer = '';
72
+ // Resolve when the child is actually gone, not when the signal was
73
+ // sent. `kill()` returns as soon as the signal is delivered, so an
74
+ // awaited `close()` meant only "SIGTERM is on its way" — a caller that
75
+ // closed and then deleted the child's working directory raced the exit
76
+ // and saw EBUSY. A close that does not mean closed makes every
77
+ // teardown after it a guess.
78
+ //
79
+ // A spawn that never produced a process emits `error` and no `exit`,
80
+ // so both settle this, and two timers make a hang impossible: the
81
+ // first escalates to SIGKILL for a child ignoring SIGTERM, the second
82
+ // gives up waiting. Neither holds the event loop open.
83
+ if (child.pid === undefined)
84
+ return;
85
+ await new Promise((resolve) => {
86
+ let settled = false;
87
+ const finish = () => {
88
+ if (settled)
89
+ return;
90
+ settled = true;
91
+ clearTimeout(escalate);
92
+ clearTimeout(giveUp);
93
+ resolve();
94
+ };
95
+ child.once('exit', finish);
96
+ child.once('error', finish);
97
+ child.kill('SIGTERM');
98
+ const escalate = setTimeout(() => child.kill('SIGKILL'), TERMINATE_GRACE_MS);
99
+ const giveUp = setTimeout(finish, TERMINATE_GRACE_MS * 2);
100
+ escalate.unref?.();
101
+ giveUp.unref?.();
102
+ });
66
103
  // The handlers deliberately survive this call. `process.on('close')`
67
104
  // fires them when the process actually exits, and dropping them here
68
105
  // would leave `MCPClient` believing it is still connected — so its next
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../../src/connector/mcp/stdio.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../../src/connector/mcp/stdio.ts"],"names":[],"mappings":"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"}
@@ -205,4 +205,44 @@ describe('a workspace stored before it had a status', () => {
205
205
  expect(archived.status).toBe('archived');
206
206
  });
207
207
  });
208
+ describe('a store that cannot answer the precondition', () => {
209
+ /**
210
+ * `listSessionsByProject` is optional on `SessionStore` so a host's own
211
+ * store keeps compiling. The archive path read it as
212
+ * `(await store.listSessionsByProject?.(...)) ?? []`, which turned "this
213
+ * store cannot tell me what is running here" into "nothing is running
214
+ * here" — so a host with such a store closed a workspace over live
215
+ * sessions and got a success back. The refusal that the whole feature is
216
+ * about was skippable by not implementing one method.
217
+ */
218
+ function storeWithoutTheListing(inner) {
219
+ const partial = {};
220
+ for (const key of [
221
+ 'getProject',
222
+ 'createProject',
223
+ 'createSession',
224
+ 'getSession',
225
+ 'updateSession',
226
+ 'setProjectStatus',
227
+ ]) {
228
+ const fn = inner[key];
229
+ if (typeof fn === 'function')
230
+ partial[key] = fn.bind(inner);
231
+ }
232
+ return partial;
233
+ }
234
+ it('refuses to archive rather than assuming the workspace is empty', async () => {
235
+ const h = await harness();
236
+ await h.store.updateSession({ ...h.parentSession, status: 'active' }, TENANT);
237
+ const blind = new ProjectManager({ store: storeWithoutTheListing(h.store) });
238
+ await expect(blind.archive(h.project.id, TENANT)).rejects.toThrow(/listSessionsByProject/);
239
+ });
240
+ it('leaves the workspace open after refusing', async () => {
241
+ // The refusal has to happen before the write, or it is only a message.
242
+ const h = await harness();
243
+ const blind = new ProjectManager({ store: storeWithoutTheListing(h.store) });
244
+ await blind.archive(h.project.id, TENANT).catch(() => undefined);
245
+ expect((await h.store.getProject(h.project.id, TENANT))?.status).toBe('open');
246
+ });
247
+ });
208
248
  //# sourceMappingURL=a-closed-workspace-takes-no-work.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"a-closed-workspace-takes-no-work.test.js","sourceRoot":"","sources":["../../../../src/manager/project/__tests__/a-closed-workspace-takes-no-work.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"a-closed-workspace-takes-no-work.test.js","sourceRoot":"","sources":["../../../../src/manager/project/__tests__/a-closed-workspace-takes-no-work.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/manager/project/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAA;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAgBhE;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACvC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,EACvC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,MAAM,GACR,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,YAAY,CAAA;CACnB;AAED,qBAAa,cAAc;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,kBAAkB;IAErD,sCAAsC;IACtC,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,SAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5F;;;;;;;;;;;;;OAaG;IACG,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAwBzE;;;;OAIG;IACG,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YAS1D,KAAK;CAwBnB"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/manager/project/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAA;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAgBhE;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACvC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,EACvC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,MAAM,GACR,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,YAAY,CAAA;CACnB;AAED,qBAAa,cAAc;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,kBAAkB;IAErD,sCAAsC;IACtC,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,SAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5F;;;;;;;;;;;;;OAaG;IACG,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IA0CzE;;;;OAIG;IACG,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YAS1D,KAAK;CAwBnB"}
@@ -79,7 +79,23 @@ export class ProjectManager {
79
79
  if (!project) {
80
80
  throw new Error(`Project ${projectId} not found for tenant ${tenantId} — archive rejected`);
81
81
  }
82
- const sessions = (await this.deps.store.listSessionsByProject?.(projectId, tenantId)) ?? [];
82
+ // An unanswerable precondition is a refusal, not an empty answer.
83
+ //
84
+ // This read used to be `?? []`, which turned "this store cannot tell me
85
+ // what is running here" into "nothing is running here": a store without
86
+ // the optional method archived the workspace over live sessions and
87
+ // reported success. The whole point of the check is that archival does
88
+ // not cascade over running work, and the check was skippable by any
89
+ // store that had not implemented one optional method.
90
+ //
91
+ // Optional on the interface protects implementors — a host's own store
92
+ // should not stop compiling because the SDK grew a method. It cannot
93
+ // also mean a safety precondition silently passes.
94
+ const listByProject = this.deps.store.listSessionsByProject;
95
+ if (!listByProject) {
96
+ throw new Error(`Project ${projectId} cannot be archived: this SessionStore does not implement listSessionsByProject, so whether a session is still running in the workspace cannot be established. Implement it, or settle and verify the sessions through your own path before closing the workspace.`);
97
+ }
98
+ const sessions = await listByProject.call(this.deps.store, projectId, tenantId);
83
99
  const blocking = sessions.filter((s) => ARCHIVAL_BLOCKING_STATUSES.has(s.status));
84
100
  if (blocking.length > 0) {
85
101
  throw new ProjectNotEmptyError({
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/manager/project/lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/manager/project/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACN,8BAA8B,EAC9B,kBAAkB,EAClB,oBAAoB,GACpB,MAAM,yBAAyB,CAAA;AAOhC;;;;;;GAMG;AACH,MAAM,0BAA0B,GAA+B,IAAI,GAAG,CAAC;IACtE,QAAQ;IACR,QAAQ;IACR,gBAAgB;IAChB,eAAe;CACf,CAAC,CAAA;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,KAAuC,EACvC,SAAoB,EACpB,QAAkB,EAClB,EAAU;IAEV,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;IAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,yBAAyB,QAAQ,MAAM,EAAE,WAAW,CAAC,CAAA;IAC1F,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,OAAO,CAAA;AACf,CAAC;AAMD,MAAM,OAAO,cAAc;IACG;IAA7B,YAA6B,IAAwB;QAAxB,SAAI,GAAJ,IAAI,CAAoB;IAAG,CAAC;IAEzD,sCAAsC;IACtC,WAAW,CAAC,SAAoB,EAAE,QAAkB,EAAE,EAAE,GAAG,cAAc;QACxE,OAAO,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;IACpE,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,OAAO,CAAC,SAAoB,EAAE,QAAkB;QACrD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;QACrE,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,yBAAyB,QAAQ,qBAAqB,CAAC,CAAA;QAC5F,CAAC;QAED,kEAAkE;QAClE,EAAE;QACF,wEAAwE;QACxE,wEAAwE;QACxE,oEAAoE;QACpE,uEAAuE;QACvE,oEAAoE;QACpE,sDAAsD;QACtD,EAAE;QACF,uEAAuE;QACvE,qEAAqE;QACrE,mDAAmD;QACnD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAA;QAC3D,IAAI,CAAC,aAAa,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACd,WAAW,SAAS,oQAAoQ,CACxR,CAAA;QACF,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAA;QAC/E,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;QACjF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,oBAAoB,CAAC;gBAC9B,SAAS;gBACT,QAAQ;gBACR,EAAE,EAAE,SAAS;gBACb,gBAAgB,EAAE,QAAQ;qBACxB,KAAK,CAAC,CAAC,EAAE,8BAA8B,CAAC;qBACxC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;gBACrD,qBAAqB,EAAE,QAAQ,CAAC,MAAM;aACtC,CAAC,CAAA;QACH,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU;YAAE,OAAO,OAAO,CAAA;QACjD,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IACzE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,SAAoB,EAAE,QAAkB;QACpD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;QACrE,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,yBAAyB,QAAQ,oBAAoB,CAAC,CAAA;QAC3F,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,OAAO,CAAA;QAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IACrE,CAAC;IAEO,KAAK,CAAC,KAAK,CAClB,SAAoB,EACpB,MAAyB,EACzB,QAAkB,EAClB,oBAA4B;QAE5B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAA;QAClD,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACd,WAAW,SAAS,sBAAsB,MAAM,uLAAuL,CACvO,CAAA;QACF,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,CACnC,IAAI,CAAC,IAAI,CAAC,KAAK,EACf,SAAS,EACT,MAAM,EACN,QAAQ,EACR,oBAAoB,CACpB,CAAA;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,wBAAwB,MAAM,SAAS,CAAC,CAAA;QAC7E,CAAC;QACD,OAAO,OAAO,CAAA;IACf,CAAC;CACD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namzu/sdk",
3
- "version": "14.0.2",
3
+ "version": "14.0.4",
4
4
  "description": "Open-source AI agent SDK with a built-in runtime. Nothing between you and your agents.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "type": "module",
@@ -0,0 +1,119 @@
1
+ import type { ChildProcess } from 'node:child_process'
2
+ import { describe, expect, it } from 'vitest'
3
+
4
+ import { StdioTransport } from '../stdio.js'
5
+
6
+ /**
7
+ * `close()` sent SIGTERM and returned without waiting, so a resolved close
8
+ * meant "the signal is on its way", not "the child is gone". A caller that
9
+ * closed a transport and then deleted the child's working directory raced the
10
+ * exit and saw EBUSY — reported from a real integration, not inferred.
11
+ *
12
+ * A close that does not mean closed makes every teardown built on top of it a
13
+ * guess, and the guess is only wrong sometimes, which is the worst kind.
14
+ *
15
+ * These assert on the operating system rather than on the transport's own
16
+ * state: `process.kill(pid, 0)` throws ESRCH once the pid is gone, so the
17
+ * assertion cannot pass by the transport merely believing it closed.
18
+ */
19
+
20
+ /** The child the transport spawned, read before `close()` clears the field. */
21
+ function childOf(transport: StdioTransport): ChildProcess {
22
+ const child = (transport as unknown as { process: ChildProcess | null }).process
23
+ if (!child) throw new Error('transport spawned no process')
24
+ return child
25
+ }
26
+
27
+ function pidOf(transport: StdioTransport): number {
28
+ const pid = childOf(transport).pid
29
+ if (pid === undefined) throw new Error('transport spawned no process')
30
+ return pid
31
+ }
32
+
33
+ function isAlive(pid: number): boolean {
34
+ try {
35
+ process.kill(pid, 0)
36
+ return true
37
+ } catch {
38
+ return false
39
+ }
40
+ }
41
+
42
+ describe('a close that means closed', () => {
43
+ it('does not resolve until the child is actually gone', async () => {
44
+ const transport = new StdioTransport({
45
+ type: 'stdio',
46
+ command: process.execPath,
47
+ args: ['-e', 'setInterval(() => {}, 1000)'],
48
+ })
49
+ await transport.connect()
50
+ const child = childOf(transport)
51
+ const pid = pidOf(transport)
52
+ expect(isAlive(pid)).toBe(true)
53
+
54
+ await transport.close()
55
+
56
+ // The reaped-ness of the child, not the liveness of the pid.
57
+ //
58
+ // `isAlive(pid)` alone is sound about the wrong thing: on Windows
59
+ // `kill('SIGTERM')` terminates the process synchronously, so the pid is
60
+ // already gone by the next line whether or not `close()` waited — the
61
+ // assertion passed under a deliberately reintroduced fire-and-forget
62
+ // kill, which is how this was caught. Node fills `exitCode`/`signalCode`
63
+ // only when it reaps the child and emits `exit`, a later tick, so these
64
+ // are non-null here exactly when `close()` awaited that event.
65
+ expect(child.exitCode !== null || child.signalCode !== null).toBe(true)
66
+ expect(isAlive(pid)).toBe(false)
67
+ })
68
+
69
+ it('returns rather than hanging when the command does not exist', async () => {
70
+ // A spawn that fails emits `error` and never `exit`. Waiting on `exit`
71
+ // alone would turn a bad command into a shutdown that never completes.
72
+ const transport = new StdioTransport({
73
+ type: 'stdio',
74
+ command: 'namzu-no-such-command-exists-here',
75
+ args: [],
76
+ })
77
+ await transport.connect()
78
+
79
+ await expect(transport.close()).resolves.toBeUndefined()
80
+ })
81
+
82
+ it('is safe to call twice', async () => {
83
+ const transport = new StdioTransport({
84
+ type: 'stdio',
85
+ command: process.execPath,
86
+ args: ['-e', 'setInterval(() => {}, 1000)'],
87
+ })
88
+ await transport.connect()
89
+ const pid = pidOf(transport)
90
+
91
+ await transport.close()
92
+ await transport.close()
93
+
94
+ expect(isAlive(pid)).toBe(false)
95
+ })
96
+
97
+ it('reports the exit to the handler registered for that session', async () => {
98
+ // The waiting must not swallow the notification the client depends on
99
+ // to learn the session ended.
100
+ const transport = new StdioTransport({
101
+ type: 'stdio',
102
+ command: process.execPath,
103
+ args: ['-e', 'setInterval(() => {}, 1000)'],
104
+ })
105
+ await transport.connect()
106
+ let closes = 0
107
+ transport.onClose(() => {
108
+ closes++
109
+ })
110
+
111
+ await transport.close()
112
+ // `close` on a ChildProcess follows `exit` by a tick once the stdio
113
+ // streams drain; give the loop that tick rather than asserting on a
114
+ // race.
115
+ await new Promise((resolve) => setTimeout(resolve, 50))
116
+
117
+ expect(closes).toBe(1)
118
+ })
119
+ })
@@ -6,6 +6,13 @@ import type {
6
6
  } from '../../types/connector/index.js'
7
7
  import { type Logger, getRootLogger } from '../../utils/logger.js'
8
8
 
9
+ /**
10
+ * How long a child gets to honour SIGTERM before SIGKILL. Two seconds is
11
+ * long enough for a server flushing a response and short enough that a
12
+ * shutdown does not read as a hang.
13
+ */
14
+ const TERMINATE_GRACE_MS = 2_000
15
+
9
16
  export class StdioTransport implements MCPTransport {
10
17
  private process: ChildProcess | null = null
11
18
  private messageHandlers: Array<(message: MCPJsonRpcMessage) => void> = []
@@ -71,9 +78,39 @@ export class StdioTransport implements MCPTransport {
71
78
  }
72
79
  this.connected = false
73
80
  this.exitPending = true
74
- this.process.kill('SIGTERM')
81
+ const child = this.process
75
82
  this.process = null
76
83
  this.buffer = ''
84
+
85
+ // Resolve when the child is actually gone, not when the signal was
86
+ // sent. `kill()` returns as soon as the signal is delivered, so an
87
+ // awaited `close()` meant only "SIGTERM is on its way" — a caller that
88
+ // closed and then deleted the child's working directory raced the exit
89
+ // and saw EBUSY. A close that does not mean closed makes every
90
+ // teardown after it a guess.
91
+ //
92
+ // A spawn that never produced a process emits `error` and no `exit`,
93
+ // so both settle this, and two timers make a hang impossible: the
94
+ // first escalates to SIGKILL for a child ignoring SIGTERM, the second
95
+ // gives up waiting. Neither holds the event loop open.
96
+ if (child.pid === undefined) return
97
+ await new Promise<void>((resolve) => {
98
+ let settled = false
99
+ const finish = (): void => {
100
+ if (settled) return
101
+ settled = true
102
+ clearTimeout(escalate)
103
+ clearTimeout(giveUp)
104
+ resolve()
105
+ }
106
+ child.once('exit', finish)
107
+ child.once('error', finish)
108
+ child.kill('SIGTERM')
109
+ const escalate = setTimeout(() => child.kill('SIGKILL'), TERMINATE_GRACE_MS)
110
+ const giveUp = setTimeout(finish, TERMINATE_GRACE_MS * 2)
111
+ escalate.unref?.()
112
+ giveUp.unref?.()
113
+ })
77
114
  // The handlers deliberately survive this call. `process.on('close')`
78
115
  // fires them when the process actually exits, and dropping them here
79
116
  // would leave `MCPClient` believing it is still connected — so its next
@@ -22,6 +22,7 @@ import type { AgentDefinition } from '../../../types/agent/factory.js'
22
22
  import type { AgentTaskContext } from '../../../types/agent/task.js'
23
23
  import type { AgentId, TenantId } from '../../../types/ids/index.js'
24
24
  import type { SummaryId } from '../../../types/session/ids.js'
25
+ import type { SessionStore } from '../../../types/session/store.js'
25
26
  import { ZERO_COST } from '../../../utils/cost.js'
26
27
  import { AgentManager } from '../../agent/lifecycle.js'
27
28
  import { ThreadManager } from '../../thread/lifecycle.js'
@@ -266,3 +267,48 @@ describe('a workspace stored before it had a status', () => {
266
267
  expect(archived.status).toBe('archived')
267
268
  })
268
269
  })
270
+
271
+ describe('a store that cannot answer the precondition', () => {
272
+ /**
273
+ * `listSessionsByProject` is optional on `SessionStore` so a host's own
274
+ * store keeps compiling. The archive path read it as
275
+ * `(await store.listSessionsByProject?.(...)) ?? []`, which turned "this
276
+ * store cannot tell me what is running here" into "nothing is running
277
+ * here" — so a host with such a store closed a workspace over live
278
+ * sessions and got a success back. The refusal that the whole feature is
279
+ * about was skippable by not implementing one method.
280
+ */
281
+ function storeWithoutTheListing(inner: SessionStore): SessionStore {
282
+ const partial: Record<string, unknown> = {}
283
+ for (const key of [
284
+ 'getProject',
285
+ 'createProject',
286
+ 'createSession',
287
+ 'getSession',
288
+ 'updateSession',
289
+ 'setProjectStatus',
290
+ ]) {
291
+ const fn = (inner as unknown as Record<string, unknown>)[key]
292
+ if (typeof fn === 'function') partial[key] = (fn as (...a: unknown[]) => unknown).bind(inner)
293
+ }
294
+ return partial as unknown as SessionStore
295
+ }
296
+
297
+ it('refuses to archive rather than assuming the workspace is empty', async () => {
298
+ const h = await harness()
299
+ await h.store.updateSession({ ...h.parentSession, status: 'active' }, TENANT)
300
+ const blind = new ProjectManager({ store: storeWithoutTheListing(h.store) })
301
+
302
+ await expect(blind.archive(h.project.id, TENANT)).rejects.toThrow(/listSessionsByProject/)
303
+ })
304
+
305
+ it('leaves the workspace open after refusing', async () => {
306
+ // The refusal has to happen before the write, or it is only a message.
307
+ const h = await harness()
308
+ const blind = new ProjectManager({ store: storeWithoutTheListing(h.store) })
309
+
310
+ await blind.archive(h.project.id, TENANT).catch(() => undefined)
311
+
312
+ expect((await h.store.getProject(h.project.id, TENANT))?.status).toBe('open')
313
+ })
314
+ })
@@ -101,7 +101,25 @@ export class ProjectManager {
101
101
  throw new Error(`Project ${projectId} not found for tenant ${tenantId} — archive rejected`)
102
102
  }
103
103
 
104
- const sessions = (await this.deps.store.listSessionsByProject?.(projectId, tenantId)) ?? []
104
+ // An unanswerable precondition is a refusal, not an empty answer.
105
+ //
106
+ // This read used to be `?? []`, which turned "this store cannot tell me
107
+ // what is running here" into "nothing is running here": a store without
108
+ // the optional method archived the workspace over live sessions and
109
+ // reported success. The whole point of the check is that archival does
110
+ // not cascade over running work, and the check was skippable by any
111
+ // store that had not implemented one optional method.
112
+ //
113
+ // Optional on the interface protects implementors — a host's own store
114
+ // should not stop compiling because the SDK grew a method. It cannot
115
+ // also mean a safety precondition silently passes.
116
+ const listByProject = this.deps.store.listSessionsByProject
117
+ if (!listByProject) {
118
+ throw new Error(
119
+ `Project ${projectId} cannot be archived: this SessionStore does not implement listSessionsByProject, so whether a session is still running in the workspace cannot be established. Implement it, or settle and verify the sessions through your own path before closing the workspace.`,
120
+ )
121
+ }
122
+ const sessions = await listByProject.call(this.deps.store, projectId, tenantId)
105
123
  const blocking = sessions.filter((s) => ARCHIVAL_BLOCKING_STATUSES.has(s.status))
106
124
  if (blocking.length > 0) {
107
125
  throw new ProjectNotEmptyError({