wicked-crew 0.9.13 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/api/job-title.d.ts +24 -0
  2. package/dist/api/job-title.d.ts.map +1 -0
  3. package/dist/api/job-title.js +97 -0
  4. package/dist/api/job-title.js.map +1 -0
  5. package/dist/api/mcp.d.ts +26 -6
  6. package/dist/api/mcp.d.ts.map +1 -1
  7. package/dist/api/mcp.js +87 -10
  8. package/dist/api/mcp.js.map +1 -1
  9. package/dist/api/routes.d.ts.map +1 -1
  10. package/dist/api/routes.js +32 -2
  11. package/dist/api/routes.js.map +1 -1
  12. package/dist/api/run-timing-index.d.ts +23 -1
  13. package/dist/api/run-timing-index.d.ts.map +1 -1
  14. package/dist/api/run-timing-index.js +66 -1
  15. package/dist/api/run-timing-index.js.map +1 -1
  16. package/dist/api/seat-record.d.ts +1 -1
  17. package/dist/api/seat-record.js +1 -1
  18. package/dist/api/server.js +1 -1
  19. package/dist/api/server.js.map +1 -1
  20. package/dist/editors/registry.d.ts +11 -11
  21. package/dist/editors/registry.d.ts.map +1 -1
  22. package/dist/editors/registry.js +1 -0
  23. package/dist/editors/registry.js.map +1 -1
  24. package/dist/editors/routes.d.ts +19 -1
  25. package/dist/editors/routes.d.ts.map +1 -1
  26. package/dist/editors/routes.js +85 -7
  27. package/dist/editors/routes.js.map +1 -1
  28. package/dist/mcp/broker.d.ts.map +1 -1
  29. package/dist/mcp/broker.js +17 -0
  30. package/dist/mcp/broker.js.map +1 -1
  31. package/dist/mcp/classify.d.ts +12 -2
  32. package/dist/mcp/classify.d.ts.map +1 -1
  33. package/dist/mcp/classify.js +5 -2
  34. package/dist/mcp/classify.js.map +1 -1
  35. package/dist/mcp/policies.d.ts +10 -1
  36. package/dist/mcp/policies.d.ts.map +1 -1
  37. package/dist/mcp/policies.js +16 -4
  38. package/dist/mcp/policies.js.map +1 -1
  39. package/dist/mcp/probe.d.ts +2 -0
  40. package/dist/mcp/probe.d.ts.map +1 -1
  41. package/dist/mcp/probe.js.map +1 -1
  42. package/dist/mcp/registry-store.d.ts +6 -0
  43. package/dist/mcp/registry-store.d.ts.map +1 -1
  44. package/dist/mcp/registry-store.js.map +1 -1
  45. package/dist/mcp/registry.d.ts +83 -7
  46. package/dist/mcp/registry.d.ts.map +1 -1
  47. package/dist/mcp/registry.js +213 -24
  48. package/dist/mcp/registry.js.map +1 -1
  49. package/dist/mcp/rest.d.ts +29 -2
  50. package/dist/mcp/rest.d.ts.map +1 -1
  51. package/dist/mcp/rest.js +123 -2
  52. package/dist/mcp/rest.js.map +1 -1
  53. package/dist/mcp-inspect/routes.d.ts +55 -0
  54. package/dist/mcp-inspect/routes.d.ts.map +1 -0
  55. package/dist/mcp-inspect/routes.js +268 -0
  56. package/dist/mcp-inspect/routes.js.map +1 -0
  57. package/dist/mcp-inspect/session.d.ts +153 -0
  58. package/dist/mcp-inspect/session.d.ts.map +1 -0
  59. package/dist/mcp-inspect/session.js +487 -0
  60. package/dist/mcp-inspect/session.js.map +1 -0
  61. package/dist/projects/state-home.d.ts +2 -1
  62. package/dist/projects/state-home.d.ts.map +1 -1
  63. package/dist/projects/state-home.js +34 -4
  64. package/dist/projects/state-home.js.map +1 -1
  65. package/endpoint-manifest.json +56 -2
  66. package/package.json +2 -2
@@ -0,0 +1,487 @@
1
+ /**
2
+ * The MCP inspector bridge's sessions (DES-MCP-INSPECTOR-001 §3).
3
+ *
4
+ * One session = one live transport to one MCP server, opened on the operator's explicit start and
5
+ * driven by studio's host for an `mcp-server` editor plugin. The SDK's transports are used WITHOUT
6
+ * the SDK `Client`, so every JSON-RPC message in both directions is seen and logged raw.
7
+ *
8
+ * - The bridge owns the handshake: `initialize` (no client capabilities) then
9
+ * `notifications/initialized`. A server request (sampling, elicitation, roots, anything) is
10
+ * answered `-32601` and logged.
11
+ * - Only {@link INSPECT_METHODS} may be sent.
12
+ * - The log is a ring (1000 entries, 4 MB); each entry's text is capped at 64 KB.
13
+ * - Secrets: every value the bridge injected (the registry secret, each typed env/header value) is
14
+ * scrubbed from every entry and every reply, and credential-shaped strings are replaced. Field-name
15
+ * redaction is NOT applied: it would blank the `session`/`token`-named fields being debugged.
16
+ * - Lifetime: at most {@link MAX_SESSIONS}; idle (no rpc, no poll) for {@link IDLE_MS} = closed;
17
+ * `closeAll` on the daemon's close; `killAllSync` on process exit (a stdio child gets SIGKILL).
18
+ */
19
+ import { randomBytes } from 'node:crypto';
20
+ import { basename } from 'node:path';
21
+ import { redactString } from '../mcp/redact.js';
22
+ import { scrubSecrets, SECRET_REDACTION } from '../mcp/secrets.js';
23
+ /** The methods a plugin may send. The bridge itself owns `initialize`. */
24
+ export const INSPECT_METHODS = new Set([
25
+ 'tools/list',
26
+ 'tools/call',
27
+ 'resources/list',
28
+ 'resources/templates/list',
29
+ 'resources/read',
30
+ 'prompts/list',
31
+ 'prompts/get',
32
+ 'completion/complete',
33
+ 'logging/setLevel',
34
+ 'ping',
35
+ ]);
36
+ export const MAX_SESSIONS = 4;
37
+ export const IDLE_MS = 10 * 60_000;
38
+ export const INIT_TIMEOUT_MS = 15_000;
39
+ export const CALL_TIMEOUT_MS = 60_000;
40
+ export const LOG_MAX_ENTRIES = 1000;
41
+ export const LOG_MAX_BYTES = 4 * 1024 * 1024;
42
+ export const ENTRY_MAX_CHARS = 64 * 1024;
43
+ export const REPLY_MAX_CHARS = 1024 * 1024;
44
+ export const POLL_MAX_MS = 20_000;
45
+ const CLIENT_INFO = { name: 'wicked-mcp-inspector', version: '1' };
46
+ const PROTOCOL_VERSION = '2025-06-18';
47
+ export class InspectError extends Error {
48
+ status;
49
+ code;
50
+ constructor(status, code, message) {
51
+ super(message);
52
+ this.status = status;
53
+ this.code = code;
54
+ }
55
+ }
56
+ /**
57
+ * Every form a secret can take in what the bridge emits: the value itself and its JSON-escaped body
58
+ * (a quote, backslash or newline in a secret changes its serialized form; codex r1).
59
+ */
60
+ export function secretForms(secrets) {
61
+ const out = new Set();
62
+ for (const v of secrets) {
63
+ if (v.length === 0)
64
+ continue;
65
+ out.add(v);
66
+ out.add(JSON.stringify(v).slice(1, -1));
67
+ }
68
+ return [...out].sort((a, b) => b.length - a.length);
69
+ }
70
+ /** Scrub exact secrets (every form), then credential shapes, from any JSON value or string. */
71
+ export function scrub(value, forms) {
72
+ const exact = scrubSecrets(value, forms);
73
+ const walk = (v) => {
74
+ if (typeof v === 'string')
75
+ return redactString(v);
76
+ if (Array.isArray(v))
77
+ return v.map(walk);
78
+ if (v !== null && typeof v === 'object') {
79
+ const out = {};
80
+ for (const [k, inner] of Object.entries(v))
81
+ out[k] = walk(inner);
82
+ return out;
83
+ }
84
+ return v;
85
+ };
86
+ return walk(exact);
87
+ }
88
+ function cap(text, max) {
89
+ return text.length <= max ? { text, truncated: false } : { text: text.slice(0, max), truncated: true };
90
+ }
91
+ /** At most this many timed-out requests keep their send time (for a late answer's round trip). */
92
+ const SENT_AT_MAX = 256;
93
+ /** A stderr line longer than this is logged without waiting for its newline. */
94
+ const STDERR_LINE_MAX = 8 * 1024;
95
+ /** An upstream DELETE of a streamable-HTTP session gets this long. */
96
+ const TERMINATE_MS = 2_000;
97
+ /** Longer than SDK 1.31's stdio close (2 s for EOF, then 2 s after SIGTERM, then SIGKILL; codex r2). */
98
+ const CLOSE_MS = 5_000;
99
+ /**
100
+ * How many trailing characters of `text` could be the start of a secret form: the longest tail
101
+ * that is a proper prefix of one (codex r2). Bounded by the longest form, so a buffer holding it
102
+ * back never grows past that.
103
+ */
104
+ export function heldTail(text, forms) {
105
+ let held = 0;
106
+ for (const f of forms) {
107
+ for (let k = Math.min(f.length - 1, text.length); k > held; k--) {
108
+ if (text.charCodeAt(text.length - k) === f.charCodeAt(0) && text.endsWith(f.slice(0, k))) {
109
+ held = k;
110
+ break;
111
+ }
112
+ }
113
+ }
114
+ return held;
115
+ }
116
+ export class InspectSession {
117
+ rawTarget;
118
+ opened;
119
+ now;
120
+ callTimeoutMs;
121
+ id = randomBytes(12).toString('hex');
122
+ startedAt;
123
+ state = 'connecting';
124
+ error = null;
125
+ initialize = null;
126
+ lastSeen;
127
+ seq = 0;
128
+ log = [];
129
+ bytes = 0;
130
+ nextId = 1;
131
+ pending = new Map();
132
+ /** When each request went out, so a response that lands after its timeout still shows its time. */
133
+ sentAt = new Map();
134
+ waiters = new Set();
135
+ forms;
136
+ /** Stderr not yet logged: at most a tail that could begin a secret (whole secrets are scrubbed in it first). */
137
+ stderrBuf = '';
138
+ closing = null;
139
+ /**
140
+ * The stdio child's pid, held from start until the child is known gone: the SDK forgets its
141
+ * process the moment close() begins, so `opened.pid()` cannot be asked then (codex r2).
142
+ */
143
+ childPid = null;
144
+ constructor(rawTarget, opened, secrets, now = Date.now, callTimeoutMs = CALL_TIMEOUT_MS) {
145
+ this.rawTarget = rawTarget;
146
+ this.opened = opened;
147
+ this.now = now;
148
+ this.callTimeoutMs = callTimeoutMs;
149
+ this.forms = secretForms(secrets);
150
+ this.startedAt = new Date(now()).toISOString();
151
+ this.lastSeen = now();
152
+ }
153
+ /** The target as anyone outside may see it: a secret the operator also typed into an argument is scrubbed (codex r1). */
154
+ get target() {
155
+ return scrub(this.rawTarget, this.forms);
156
+ }
157
+ /** Scrub a message meant for a reply, an error or a daemon log line. */
158
+ scrubText(text) {
159
+ return scrub(text, this.forms);
160
+ }
161
+ view() {
162
+ return { id: this.id, target: this.target, state: this.state, initialize: this.initialize, error: this.error, startedAt: this.startedAt, lastSeq: this.seq };
163
+ }
164
+ touch() {
165
+ this.lastSeen = this.now();
166
+ }
167
+ /**
168
+ * Connect and run the handshake, all of it (transport start, `initialize`, `initialized`) under
169
+ * ONE deadline (codex r1: a legacy SSE endpoint that never sends its `endpoint` event hung the
170
+ * start). Never throws: a failure is the session's `failed` state.
171
+ */
172
+ async start(initTimeoutMs = INIT_TIMEOUT_MS) {
173
+ const { transport, stderr } = this.opened;
174
+ stderr?.on('data', (chunk) => this.stderrData(typeof chunk === 'string' ? chunk : chunk.toString('utf8')));
175
+ // The pipe's end is the only point where a held tail is final (codex r2 verify: a SIGKILL does
176
+ // not drain the pipe, so a flush after the kill could still split a secret).
177
+ stderr?.once('end', () => this.flushStderr());
178
+ transport.onmessage = (m) => this.received(m);
179
+ transport.onerror = (e) => this.append({ dir: 'host', kind: 'state', error: true, text: `transport error: ${e.message}` });
180
+ transport.onclose = () => {
181
+ this.closed('the connection closed');
182
+ this.childPid = null;
183
+ };
184
+ let timer;
185
+ const deadline = new Promise((_, reject) => {
186
+ timer = setTimeout(() => reject(new Error(`no answer to the handshake in ${Math.round(initTimeoutMs / 1000)} s`)), initTimeoutMs);
187
+ });
188
+ const handshake = (async () => {
189
+ await transport.start();
190
+ this.childPid = this.opened.pid();
191
+ this.append({ dir: 'host', kind: 'state', text: 'connected' });
192
+ const init = await this.request('initialize', { protocolVersion: PROTOCOL_VERSION, capabilities: {}, clientInfo: CLIENT_INFO }, initTimeoutMs);
193
+ if (init.response.error !== undefined)
194
+ throw new Error(`initialize failed: ${init.response.error.message}`);
195
+ const r = (init.response.result ?? {});
196
+ const info = r['serverInfo'];
197
+ this.initialize = {
198
+ protocolVersion: typeof r['protocolVersion'] === 'string' ? r['protocolVersion'] : null,
199
+ serverInfo: info !== null && typeof info === 'object' ? info : null,
200
+ capabilities: r['capabilities'] !== null && typeof r['capabilities'] === 'object' ? r['capabilities'] : {},
201
+ instructions: typeof r['instructions'] === 'string' ? r['instructions'] : null,
202
+ };
203
+ const setter = transport.setProtocolVersion;
204
+ if (typeof setter === 'function' && this.initialize.protocolVersion !== null)
205
+ setter.call(transport, this.initialize.protocolVersion);
206
+ await this.send({ jsonrpc: '2.0', method: 'notifications/initialized' });
207
+ })();
208
+ try {
209
+ await Promise.race([handshake, deadline]);
210
+ if (this.state === 'connecting') {
211
+ this.state = 'ready';
212
+ this.append({ dir: 'host', kind: 'state', text: 'ready' });
213
+ }
214
+ }
215
+ catch (err) {
216
+ handshake.catch(() => undefined);
217
+ this.fail(err instanceof Error ? err.message : String(err));
218
+ }
219
+ finally {
220
+ clearTimeout(timer);
221
+ }
222
+ }
223
+ /** Send one allowed request and wait for its answer. */
224
+ async rpc(method, params) {
225
+ this.touch();
226
+ if (!INSPECT_METHODS.has(method))
227
+ throw new InspectError(400, 'method_not_allowed', `${method} is not a method the inspector sends`);
228
+ if (this.state !== 'ready')
229
+ throw new InspectError(409, 'not_connected', `the session is ${this.state}`);
230
+ return this.request(method, params, this.callTimeoutMs);
231
+ }
232
+ request(method, params, timeoutMs) {
233
+ const id = this.nextId++;
234
+ const msg = { jsonrpc: '2.0', id, method, ...(params !== undefined ? { params } : {}) };
235
+ return new Promise((resolve, reject) => {
236
+ const timer = setTimeout(() => {
237
+ this.pending.delete(id);
238
+ // Kept (bounded) so a late answer still shows its round trip in the log.
239
+ while (this.sentAt.size > SENT_AT_MAX)
240
+ this.sentAt.delete(this.sentAt.keys().next().value);
241
+ reject(new InspectError(504, 'timeout', `${method}: no answer in ${Math.round(timeoutMs / 1000)} s (it may still answer; watch the log)`));
242
+ }, timeoutMs);
243
+ this.pending.set(id, { method, resolve, reject, timer });
244
+ this.sentAt.set(id, this.now());
245
+ this.send(msg).catch((err) => {
246
+ clearTimeout(timer);
247
+ this.pending.delete(id);
248
+ this.sentAt.delete(id);
249
+ // An SDK error can carry the upstream's response body, which can echo a secret (codex r1).
250
+ reject(new InspectError(502, 'send_failed', this.scrubText(`could not send ${method}: ${err instanceof Error ? err.message : String(err)}`)));
251
+ });
252
+ });
253
+ }
254
+ async send(msg) {
255
+ const id = msg['id'];
256
+ const method = msg['method'];
257
+ const kind = method === undefined ? 'response' : id === undefined ? 'notification' : 'request';
258
+ this.append({ dir: 'out', kind, ...(method !== undefined ? { method } : {}), ...(id !== undefined ? { rpcId: id } : {}) }, msg);
259
+ await this.opened.transport.send(msg);
260
+ }
261
+ received(msg) {
262
+ const id = msg['id'];
263
+ const method = typeof msg['method'] === 'string' ? msg['method'] : undefined;
264
+ if (method === undefined && id !== undefined) {
265
+ const sentAt = this.sentAt.get(id);
266
+ this.sentAt.delete(id);
267
+ const ms = sentAt === undefined ? undefined : this.now() - sentAt;
268
+ const isError = msg['error'] !== undefined;
269
+ const entry = this.append({ dir: 'in', kind: 'response', rpcId: id, ...(ms !== undefined ? { ms } : {}), ...(isError ? { error: true } : {}) }, msg);
270
+ const p = this.pending.get(id);
271
+ if (p !== undefined) {
272
+ this.pending.delete(id);
273
+ clearTimeout(p.timer);
274
+ const scrubbed = scrub(isError ? { error: msg['error'] } : { result: msg['result'] }, this.forms);
275
+ const raw = JSON.stringify(scrubbed);
276
+ const truncated = raw.length > REPLY_MAX_CHARS;
277
+ p.resolve({ response: truncated ? { result: { truncated: true, text: raw.slice(0, REPLY_MAX_CHARS) } } : scrubbed, ms: ms ?? 0, truncated: truncated || entry.truncated === true });
278
+ }
279
+ return;
280
+ }
281
+ if (method !== undefined && id !== undefined) {
282
+ // A server request: the inspector declares no client capabilities, so it serves none.
283
+ this.append({ dir: 'in', kind: 'request', method, rpcId: id }, msg);
284
+ void this.send({ jsonrpc: '2.0', id, error: { code: -32601, message: `the MCP inspector does not serve ${method}` } }).catch(() => undefined);
285
+ return;
286
+ }
287
+ this.append({ dir: 'in', kind: 'notification', ...(method !== undefined ? { method } : {}) }, msg);
288
+ }
289
+ /**
290
+ * Stderr as it arrives (codex r1/r2), by whole line: whole secrets are scrubbed in the buffer
291
+ * first, so none can straddle what is logged; a tail that could begin a secret is never logged;
292
+ * and only complete lines go out (a partial one waits for its newline, up to 8 KiB), so the
293
+ * credential-shape patterns see a line whole however the server's writes were chunked.
294
+ */
295
+ stderrData(text) {
296
+ const buf = scrubSecrets(this.stderrBuf + text, this.forms);
297
+ let end = buf.length - heldTail(buf, this.forms);
298
+ const nl = end > 0 ? buf.lastIndexOf('\n', end - 1) : -1;
299
+ if (nl !== -1)
300
+ end = nl + 1;
301
+ else if (end <= STDERR_LINE_MAX)
302
+ end = 0;
303
+ this.stderrBuf = buf.slice(end);
304
+ if (end > 0)
305
+ this.append({ dir: 'in', kind: 'stderr', text: buf.slice(0, end) });
306
+ }
307
+ /**
308
+ * The pipe ended: a partial last line is logged, and a held tail (a secret's start that never
309
+ * became a whole secret) is redacted, never logged.
310
+ */
311
+ flushStderr() {
312
+ if (this.stderrBuf === '')
313
+ return;
314
+ const buf = this.stderrBuf;
315
+ const keep = heldTail(buf, this.forms);
316
+ this.stderrBuf = '';
317
+ this.append({ dir: 'in', kind: 'stderr', text: buf.slice(0, buf.length - keep) + (keep > 0 ? SECRET_REDACTION : '') });
318
+ }
319
+ /**
320
+ * One log entry. A JSON-RPC message is scrubbed as a VALUE, then serialized (codex r1: scrubbing
321
+ * the serialized text missed escaped secrets), and so are `method` and `rpcId`.
322
+ */
323
+ append(e, message) {
324
+ const clean = scrub({ ...e, ...(message !== undefined ? { text: JSON.stringify(scrub(message, this.forms)) } : {}) }, this.forms);
325
+ const { text, truncated } = cap(clean.text ?? '', ENTRY_MAX_CHARS);
326
+ this.seq += 1;
327
+ const entry = { ...clean, seq: this.seq, at: new Date(this.now()).toISOString(), text, ...(truncated ? { truncated: true } : {}) };
328
+ this.log.push(entry);
329
+ this.bytes += text.length;
330
+ while (this.log.length > LOG_MAX_ENTRIES || (this.bytes > LOG_MAX_BYTES && this.log.length > 1)) {
331
+ const gone = this.log.shift();
332
+ this.bytes -= gone.text.length;
333
+ }
334
+ for (const w of [...this.waiters])
335
+ w();
336
+ return entry;
337
+ }
338
+ /** Entries after `after`, at once if any, else when one lands or `waitMs` passes. */
339
+ async entries(after, waitMs) {
340
+ this.touch();
341
+ if (this.seq <= after && waitMs > 0 && this.state !== 'closed' && this.state !== 'failed') {
342
+ await new Promise((resolve) => {
343
+ const done = () => {
344
+ clearTimeout(timer);
345
+ this.waiters.delete(done);
346
+ resolve();
347
+ };
348
+ const timer = setTimeout(done, Math.min(waitMs, POLL_MAX_MS));
349
+ this.waiters.add(done);
350
+ });
351
+ this.touch();
352
+ }
353
+ const entries = this.log.filter((x) => x.seq > after);
354
+ return { entries, next: this.seq, first: this.log[0]?.seq ?? this.seq + 1, state: this.state, error: this.error };
355
+ }
356
+ fail(message) {
357
+ if (this.state === 'closed' || this.state === 'failed')
358
+ return;
359
+ const msg = this.scrubText(message);
360
+ this.state = 'failed';
361
+ this.error = msg;
362
+ this.append({ dir: 'host', kind: 'state', error: true, text: `failed: ${msg}` });
363
+ void this.close('failed');
364
+ }
365
+ closed(reason) {
366
+ if (this.state === 'closed' || this.state === 'failed')
367
+ return;
368
+ const pid = this.childPid;
369
+ this.state = this.state === 'connecting' ? 'failed' : 'closed';
370
+ if (this.state === 'failed')
371
+ this.error = reason;
372
+ this.append({ dir: 'host', kind: 'state', text: `${reason}${pid !== null ? ` (pid ${pid})` : ''}` });
373
+ this.rejectPending(reason);
374
+ }
375
+ rejectPending(reason) {
376
+ for (const [id, p] of this.pending) {
377
+ clearTimeout(p.timer);
378
+ p.reject(new InspectError(409, 'not_connected', `${p.method}: ${reason}`));
379
+ this.pending.delete(id);
380
+ }
381
+ this.sentAt.clear();
382
+ for (const w of [...this.waiters])
383
+ w();
384
+ }
385
+ /**
386
+ * Close it. A streamable-HTTP session is terminated upstream first (its DELETE, codex r1), then the
387
+ * transport is closed (a stdio child is terminated by the SDK). Bounded and idempotent.
388
+ */
389
+ close(reason = 'closed by the operator') {
390
+ if (this.state !== 'failed')
391
+ this.closed(reason);
392
+ else
393
+ this.rejectPending(reason);
394
+ this.closing ??= (async () => {
395
+ const t = this.opened.transport;
396
+ const bounded = (p, ms) => Promise.race([p.catch(() => undefined), new Promise((r) => setTimeout(r, ms).unref())]);
397
+ if (typeof t.terminateSession === 'function' && t.sessionId !== undefined)
398
+ await bounded(t.terminateSession(), TERMINATE_MS);
399
+ await bounded(t.close(), CLOSE_MS);
400
+ // The SDK's close ends in SIGKILL; a child that outlived even that is killed here, by the pid
401
+ // held since start (codex r2).
402
+ this.killSync();
403
+ this.childPid = null;
404
+ })();
405
+ return this.closing;
406
+ }
407
+ /** Process exit: no awaiting, so a stdio child is killed outright. */
408
+ killSync() {
409
+ const pid = this.childPid;
410
+ if (pid === null)
411
+ return;
412
+ try {
413
+ process.kill(pid, 'SIGKILL');
414
+ }
415
+ catch {
416
+ /* already gone */
417
+ }
418
+ }
419
+ }
420
+ /** A short, path-free name for a stdio command (`node build/index.js` → `index.js`). */
421
+ export function commandName(command, args) {
422
+ const script = args.find((a) => !a.startsWith('-'));
423
+ return (basename(script ?? command) || command).slice(0, 60);
424
+ }
425
+ export class InspectSessions {
426
+ now;
427
+ sessions = new Map();
428
+ /** Sessions removed but still closing, with their close: killable at exit, awaited by closeAll (codex r2). */
429
+ closingSessions = new Map();
430
+ sweeper = null;
431
+ constructor(now = Date.now) {
432
+ this.now = now;
433
+ }
434
+ get size() {
435
+ return this.sessions.size;
436
+ }
437
+ add(s) {
438
+ if (this.sessions.size >= MAX_SESSIONS)
439
+ throw new InspectError(429, 'too_many_sessions', `at most ${MAX_SESSIONS} inspector sessions at once; disconnect one first`);
440
+ this.sessions.set(s.id, s);
441
+ if (this.sweeper === null) {
442
+ this.sweeper = setInterval(() => void this.sweep(), 30_000);
443
+ this.sweeper.unref();
444
+ }
445
+ }
446
+ /** Reserve a slot before the (slow) connect, so concurrent starts cannot exceed the cap. */
447
+ hasRoom() {
448
+ return this.sessions.size < MAX_SESSIONS;
449
+ }
450
+ get(id) {
451
+ return this.sessions.get(id) ?? null;
452
+ }
453
+ async remove(id, reason) {
454
+ const s = this.sessions.get(id);
455
+ if (s === undefined)
456
+ return false;
457
+ this.sessions.delete(id);
458
+ // Still killable at process exit while its close runs (codex r2).
459
+ const closing = s.close(reason);
460
+ this.closingSessions.set(s, closing);
461
+ try {
462
+ await closing;
463
+ }
464
+ finally {
465
+ this.closingSessions.delete(s);
466
+ }
467
+ return true;
468
+ }
469
+ async sweep() {
470
+ const t = this.now();
471
+ for (const s of [...this.sessions.values()]) {
472
+ if (t - s.lastSeen > IDLE_MS)
473
+ await this.remove(s.id, 'closed after 10 minutes idle');
474
+ }
475
+ }
476
+ async closeAll() {
477
+ if (this.sweeper !== null)
478
+ clearInterval(this.sweeper);
479
+ this.sweeper = null;
480
+ await Promise.all([...[...this.sessions.keys()].map((id) => this.remove(id, 'the daemon is stopping')), ...this.closingSessions.values()]);
481
+ }
482
+ killAllSync() {
483
+ for (const s of [...this.sessions.values(), ...this.closingSessions.keys()])
484
+ s.killSync();
485
+ }
486
+ }
487
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/mcp-inspect/session.ts"],"names":[],"mappings":"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"}
@@ -36,7 +36,8 @@ export declare function defaultStateHome(home: string): string;
36
36
  */
37
37
  export declare function setCrewStateHome(stateHome: string | undefined): void;
38
38
  /** The state home every durable store resolves under: the bootstrap-configured `--db` parent when
39
- * a daemon is running, the historical `~/.wicked-crew` default otherwise. */
39
+ * a daemon is running, the historical `~/.wicked-crew` default otherwise. Under a test runner it
40
+ * refuses the real user's `~/.wicked-crew` (crew#986, {@link refuseLiveHomeUnderTest}). */
40
41
  export declare function crewStateHome(): string;
41
42
  /**
42
43
  * Is the daemon on the historical default state home (`~/.wicked-crew`, or none configured)? Compared
@@ -1 +1 @@
1
- {"version":3,"file":"state-home.d.ts","sourceRoot":"","sources":["../../src/projects/state-home.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAYH,uFAAuF;AACvF,eAAO,MAAM,0BAA0B,iBAAiB,CAAC;AAEzD;;gFAEgF;AAChF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAEpE;AAED;8EAC8E;AAC9E,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAmBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"state-home.d.ts","sourceRoot":"","sources":["../../src/projects/state-home.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAYH,uFAAuF;AACvF,eAAO,MAAM,0BAA0B,iBAAiB,CAAC;AAEzD;;gFAEgF;AAChF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAEpE;AAED;;4FAE4F;AAC5F,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAgCD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAmBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD"}
@@ -23,7 +23,7 @@
23
23
  * state home at their own resolution sites: they are the more specific instruction, and the one
24
24
  * the tests and proof scripts already use.
25
25
  */
26
- import { homedir } from 'node:os';
26
+ import { homedir, userInfo } from 'node:os';
27
27
  import { existsSync, realpathSync } from 'node:fs';
28
28
  import { basename, dirname, join, resolve } from 'node:path';
29
29
  /**
@@ -48,9 +48,39 @@ export function setCrewStateHome(stateHome) {
48
48
  configuredStateHome = stateHome;
49
49
  }
50
50
  /** The state home every durable store resolves under: the bootstrap-configured `--db` parent when
51
- * a daemon is running, the historical `~/.wicked-crew` default otherwise. */
51
+ * a daemon is running, the historical `~/.wicked-crew` default otherwise. Under a test runner it
52
+ * refuses the real user's `~/.wicked-crew` (crew#986, {@link refuseLiveHomeUnderTest}). */
52
53
  export function crewStateHome() {
53
- return configuredStateHome ?? defaultStateHome(homedir());
54
+ return refuseLiveHomeUnderTest(configuredStateHome ?? defaultStateHome(homedir()));
55
+ }
56
+ /**
57
+ * crew#986: a test must never resolve the operator's LIVE state home. The suite's
58
+ * `tests/setup/hermetic-home.ts` arms a temp one, but only when vitest loads crew's
59
+ * `vitest.config.ts`. A run from another directory (the repo root has no vitest config), or a test
60
+ * that unconfigures the home and leaves it unset, fell back to the real `~/.wicked-crew`: a live
61
+ * daemon's decision ledger held 21 gate decisions written by crew tests that way.
62
+ *
63
+ * So under a test runner (`VITEST` / `NODE_ENV=test`, the posture `server.ts` already keys on),
64
+ * resolving the real user's default state home throws instead. "Real" is the account's home from
65
+ * `os.userInfo()`, which ignores `HOME`, so a test that points `HOME` at a temp dir may still
66
+ * exercise the unconfigured default. Compared by identity, like {@link isDefaultStateHome}.
67
+ */
68
+ function refuseLiveHomeUnderTest(stateHome) {
69
+ if (process.env['VITEST'] === undefined && process.env['NODE_ENV'] !== 'test')
70
+ return stateHome;
71
+ let realHome;
72
+ try {
73
+ realHome = userInfo().homedir;
74
+ }
75
+ catch {
76
+ realHome = homedir();
77
+ }
78
+ if (realSpelling(stateHome) === realSpelling(defaultStateHome(realHome))) {
79
+ throw new Error(`crew#986: refusing the live state home (${stateHome}) under a test runner. Run vitest from ` +
80
+ `packages/crew (its vitest.config.ts arms a temp state home), or give the test its own ` +
81
+ `state home (setCrewStateHome) or a temp HOME.`);
82
+ }
83
+ return stateHome;
54
84
  }
55
85
  /**
56
86
  * Is the daemon on the historical default state home (`~/.wicked-crew`, or none configured)? Compared
@@ -58,7 +88,7 @@ export function crewStateHome() {
58
88
  * default (codex on #760). Each side is the realpath of its deepest existing ancestor plus the rest.
59
89
  */
60
90
  export function isDefaultStateHome() {
61
- return configuredStateHome === undefined || realSpelling(configuredStateHome) === realSpelling(defaultStateHome(homedir()));
91
+ return realSpelling(crewStateHome()) === realSpelling(defaultStateHome(homedir()));
62
92
  }
63
93
  function realSpelling(p) {
64
94
  const abs = resolve(p);
@@ -1 +1 @@
1
- {"version":3,"file":"state-home.js","sourceRoot":"","sources":["../../src/projects/state-home.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7D;;;GAGG;AACH,IAAI,mBAAuC,CAAC;AAE5C,uFAAuF;AACvF,MAAM,CAAC,MAAM,0BAA0B,GAAG,cAAc,CAAC;AAEzD;;gFAEgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,IAAI,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAA6B;IAC5D,mBAAmB,GAAG,SAAS,CAAC;AAClC,CAAC;AAED;8EAC8E;AAC9E,MAAM,UAAU,aAAa;IAC3B,OAAO,mBAAmB,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,mBAAmB,KAAK,SAAS,IAAI,YAAY,CAAC,mBAAmB,CAAC,KAAK,YAAY,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAC9H,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,GAAG,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/B,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"state-home.js","sourceRoot":"","sources":["../../src/projects/state-home.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7D;;;GAGG;AACH,IAAI,mBAAuC,CAAC;AAE5C,uFAAuF;AACvF,MAAM,CAAC,MAAM,0BAA0B,GAAG,cAAc,CAAC;AAEzD;;gFAEgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,IAAI,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAA6B;IAC5D,mBAAmB,GAAG,SAAS,CAAC;AAClC,CAAC;AAED;;4FAE4F;AAC5F,MAAM,UAAU,aAAa;IAC3B,OAAO,uBAAuB,CAAC,mBAAmB,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACrF,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,uBAAuB,CAAC,SAAiB;IAChD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IAChG,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,QAAQ,EAAE,CAAC,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,GAAG,OAAO,EAAE,CAAC;IACvB,CAAC;IACD,IAAI,YAAY,CAAC,SAAS,CAAC,KAAK,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CACb,2CAA2C,SAAS,yCAAyC;YAC3F,wFAAwF;YACxF,+CAA+C,CAClD,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,YAAY,CAAC,aAAa,EAAE,CAAC,KAAK,YAAY,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,GAAG,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/B,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAClC,CAAC"}