@wrongstack/core 0.275.0 → 0.276.2

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 (83) hide show
  1. package/dist/{agent-bridge-D9JkPvJ0.d.ts → agent-bridge-D7A-eu3C.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-CArSFKFl.d.ts → agent-subagent-runner-CEuw4ATz.d.ts} +16 -10
  3. package/dist/{brain-DCkB5_e7.d.ts → brain-BLOyN5ZP.d.ts} +127 -1
  4. package/dist/{compactor-CzSvxM1g.d.ts → compactor-DcBpaJsI.d.ts} +1 -1
  5. package/dist/{config-BzFRKkg7.d.ts → config-Bf5mj-ad.d.ts} +20 -2
  6. package/dist/{context-BrLe8pJy.d.ts → context-CLnUMW5g.d.ts} +40 -2
  7. package/dist/coordination/index.d.ts +43 -24
  8. package/dist/coordination/index.js +849 -648
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +28 -28
  11. package/dist/defaults/index.js +1636 -845
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/execution/index.d.ts +16 -16
  14. package/dist/execution/index.js +218 -49
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/execution/prompt-enhancer.d.ts +1 -1
  17. package/dist/extension/index.d.ts +7 -7
  18. package/dist/extension/index.js.map +1 -1
  19. package/dist/{global-mailbox-CXkugtNQ.d.ts → global-mailbox-Iqfkgmwu.d.ts} +3 -3
  20. package/dist/{goal-store-DUwdbdoY.d.ts → goal-store-DGb6b5Ed.d.ts} +1 -1
  21. package/dist/hq/index.d.ts +6 -6
  22. package/dist/hq/index.js +178 -75
  23. package/dist/hq/index.js.map +1 -1
  24. package/dist/{index-CtlizLTK.d.ts → index-Cn0NOshr.d.ts} +10 -5
  25. package/dist/{index-neOCEy6q.d.ts → index-L4RZN9jJ.d.ts} +2 -2
  26. package/dist/index.d.ts +56 -48
  27. package/dist/index.js +2789 -1546
  28. package/dist/index.js.map +1 -1
  29. package/dist/infrastructure/index.d.ts +6 -6
  30. package/dist/infrastructure/index.js +26 -7
  31. package/dist/infrastructure/index.js.map +1 -1
  32. package/dist/kernel/index.d.ts +20 -12
  33. package/dist/kernel/index.js +55 -9
  34. package/dist/kernel/index.js.map +1 -1
  35. package/dist/{mailbox-types-_7gaY0Rl.d.ts → mailbox-types-DTl7bRH3.d.ts} +3 -1
  36. package/dist/{mcp-servers-MLL6bMlv.d.ts → mcp-servers-CuZGf9fI.d.ts} +4 -4
  37. package/dist/models/index.d.ts +5 -5
  38. package/dist/models/index.js +223 -139
  39. package/dist/models/index.js.map +1 -1
  40. package/dist/{models-registry-CrkcxQ-g.d.ts → models-registry-8XOdxWQu.d.ts} +16 -1
  41. package/dist/{multi-agent-coordinator-Dc_HuG9p.d.ts → multi-agent-coordinator-CiRtKVTk.d.ts} +8 -1
  42. package/dist/{null-fleet-bus-BMZwMin7.d.ts → null-fleet-bus-d9G-bVy9.d.ts} +26 -22
  43. package/dist/observability/index.d.ts +2 -2
  44. package/dist/{path-resolver-uVK4BatM.d.ts → path-resolver-BhIb6mtd.d.ts} +8 -3
  45. package/dist/{permission-CJR1qfOi.d.ts → permission-BCbQDR2s.d.ts} +1 -1
  46. package/dist/{permission-policy-DLVKKk4w.d.ts → permission-policy-C0ikndX_.d.ts} +2 -18
  47. package/dist/{pipeline-BYR-Vdau.d.ts → pipeline-Dl6XbfE7.d.ts} +10 -6
  48. package/dist/{provider-model-resolve-iREK_1lG.d.ts → provider-model-resolve-B70epO19.d.ts} +3 -3
  49. package/dist/{provider-runner-i7SQXZuC.d.ts → provider-runner-DZ808MSM.d.ts} +3 -3
  50. package/dist/{retry-policy-BmY5ooh3.d.ts → retry-policy-Dt3_z8Aj.d.ts} +1 -1
  51. package/dist/sdd/index.d.ts +19 -10
  52. package/dist/sdd/index.js +411 -240
  53. package/dist/sdd/index.js.map +1 -1
  54. package/dist/{secret-vault-C9leEMzr.d.ts → secret-vault-BUJ2d1gB.d.ts} +1 -1
  55. package/dist/security/index.d.ts +5 -5
  56. package/dist/security/index.js +30 -6
  57. package/dist/security/index.js.map +1 -1
  58. package/dist/{selector-qjpee9BF.d.ts → selector-BCkWgdwy.d.ts} +1 -1
  59. package/dist/{session-event-bridge-m7y--I-H.d.ts → session-event-bridge-CMvIO59_.d.ts} +1 -1
  60. package/dist/{session-reader-BjLH4V9n.d.ts → session-reader-C8aiChUu.d.ts} +1 -1
  61. package/dist/skills/index.js +1 -0
  62. package/dist/skills/index.js.map +1 -1
  63. package/dist/storage/index.d.ts +68 -30
  64. package/dist/storage/index.js +839 -528
  65. package/dist/storage/index.js.map +1 -1
  66. package/dist/{strategy-compactor-C2bmlWYg.d.ts → strategy-compactor-DI1OHVbB.d.ts} +10 -10
  67. package/dist/{todos-checkpoint-oDS9IBNS.d.ts → todos-checkpoint-Ddd2CGr0.d.ts} +56 -9
  68. package/dist/{tool-executor-D4YdaJ-M.d.ts → tool-executor-Bmd5Ygoo.d.ts} +45 -10
  69. package/dist/tools/index.d.ts +2 -2
  70. package/dist/tools/index.js.map +1 -1
  71. package/dist/types/index.d.ts +20 -20
  72. package/dist/types/index.js +331 -98
  73. package/dist/types/index.js.map +1 -1
  74. package/dist/utils/index.d.ts +16 -3
  75. package/dist/utils/index.js +159 -83
  76. package/dist/utils/index.js.map +1 -1
  77. package/dist/{worktree-manager-A1Efnvs0.d.ts → worktree-manager-DBdl_5rs.d.ts} +4 -1
  78. package/instructions/agents/shadow-agent.md +3 -3
  79. package/instructions/coordination/director-preamble.md +3 -3
  80. package/instructions/modes/research-web.md +4 -4
  81. package/package.json +1 -1
  82. package/skills/research-web/SKILL.md +26 -26
  83. package/skills/research-web/SKILL.save.md +1 -1
package/dist/sdd/index.js CHANGED
@@ -24,6 +24,19 @@ var __export = (target, all) => {
24
24
  __defProp(target, name, { get: all[name], enumerable: true });
25
25
  };
26
26
 
27
+ // src/utils/assert-never.ts
28
+ function assertNever(x, message) {
29
+ const err = new Error(
30
+ `Unhandled case: ${JSON.stringify(x)}`
31
+ );
32
+ err.name = "AssertNeverError";
33
+ throw err;
34
+ }
35
+ var init_assert_never = __esm({
36
+ "src/utils/assert-never.ts"() {
37
+ }
38
+ });
39
+
27
40
  // src/utils/atomic-write.ts
28
41
  var atomic_write_exports = {};
29
42
  __export(atomic_write_exports, {
@@ -108,7 +121,12 @@ async function withFileLock(targetPath, fn, opts = {}) {
108
121
  continue;
109
122
  }
110
123
  if (Date.now() - started >= timeoutMs) {
111
- throw new Error(`Timed out waiting for file lock: ${targetPath}`);
124
+ throw new FsError({
125
+ message: `Timed out waiting for file lock: ${targetPath}`,
126
+ code: "FS_ATOMIC_WRITE_FAILED",
127
+ path: targetPath,
128
+ context: { timeoutMs }
129
+ });
112
130
  }
113
131
  await new Promise((resolve4) => setTimeout(resolve4, 25));
114
132
  }
@@ -151,10 +169,303 @@ async function renameWithRetry(from, to) {
151
169
  var TRANSIENT_RENAME_CODES;
152
170
  var init_atomic_write = __esm({
153
171
  "src/utils/atomic-write.ts"() {
172
+ init_errors();
154
173
  TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES", "ENOTEMPTY"]);
155
174
  }
156
175
  });
157
176
 
177
+ // src/utils/child-env.ts
178
+ function looksSecret(name) {
179
+ const upper = name.toUpperCase();
180
+ for (const p of SECRET_NAME_PARTS) {
181
+ if (upper.includes(p)) return true;
182
+ }
183
+ if (/(?:^|_)KEY(?:$|_|S$)/i.test(upper)) return true;
184
+ if (/API[_-]?KEY/i.test(upper)) return true;
185
+ if (/ACCESS[_-]?KEY/i.test(upper)) return true;
186
+ if (/SESSION[_-]?ID/i.test(upper) === false && /SESSION/i.test(upper)) {
187
+ return true;
188
+ }
189
+ return false;
190
+ }
191
+ function valueHasEmbeddedCredential(value) {
192
+ return /\b[a-z][a-z0-9+.-]*:\/\/[^/\s:@]*:[^/\s@]+@/i.test(value);
193
+ }
194
+ function sanitizeNodeOptions(value) {
195
+ const tokens = value.split(/\s+/).filter(Boolean);
196
+ const kept = [];
197
+ for (let i = 0; i < tokens.length; i++) {
198
+ const tok = tokens[i];
199
+ if (NODE_OPTIONS_INJECTION_FLAG_EQ.test(tok)) continue;
200
+ if (NODE_OPTIONS_INJECTION_FLAG.test(tok)) {
201
+ i++;
202
+ continue;
203
+ }
204
+ kept.push(tok);
205
+ }
206
+ return kept.join(" ");
207
+ }
208
+ function buildChildEnv(optsOrSessionId) {
209
+ const opts = {};
210
+ const hasOwn = Object.hasOwn(process.env, "WRONGSTACK_CHILD_ENV_PASSTHROUGH");
211
+ const legacyHasOwn = Object.hasOwn(process.env, "WRONGSTACK_BASH_ENV_PASSTHROUGH");
212
+ const passthrough = hasOwn && process.env["WRONGSTACK_CHILD_ENV_PASSTHROUGH"] === "1" || legacyHasOwn && process.env["WRONGSTACK_BASH_ENV_PASSTHROUGH"] === "1";
213
+ if (passthrough && !process.env["CI"]) {
214
+ console.warn(
215
+ "[agent] WARNING: WRONGSTACK_*_ENV_PASSTHROUGH=1 is active \u2014\n all parent env vars (including API keys) forwarded to child processes.\n Do not use on shared or multi-tenant systems."
216
+ );
217
+ }
218
+ const out = {};
219
+ const nodeEnvDefaulted = process.env["WRONGSTACK_NODE_ENV_DEFAULTED"] === "1";
220
+ for (const [k, v] of Object.entries(process.env)) {
221
+ if (v === void 0) continue;
222
+ if (nodeEnvDefaulted && (k === "NODE_ENV" || k === "WRONGSTACK_NODE_ENV_DEFAULTED")) continue;
223
+ if (passthrough) {
224
+ out[k] = v;
225
+ continue;
226
+ }
227
+ const upper = k.toUpperCase();
228
+ if (valueHasEmbeddedCredential(v)) continue;
229
+ if (ALLOWED_KEYS.has(upper)) {
230
+ out[k] = v;
231
+ continue;
232
+ }
233
+ if (looksSecret(upper)) continue;
234
+ if (upper === "NODE_OPTIONS") {
235
+ const sanitized = sanitizeNodeOptions(v);
236
+ if (sanitized) out[k] = sanitized;
237
+ continue;
238
+ }
239
+ if (upper.startsWith("NODE_") || upper.startsWith("NPM_") || upper.startsWith("PNPM_") || upper.startsWith("YARN_") || upper.startsWith("GIT_") || upper.startsWith("CI") || upper.startsWith("XDG_") || // Our own non-secret knobs (WRONGSTACK_HOME, WRONGSTACK_SESSION_ID, …).
240
+ // Secrets never live in WRONGSTACK_* env vars (they're in the encrypted
241
+ // vault). Forwarding keeps child wstack processes — e.g. ones spawned
242
+ // by the test suite — inside the same redirected global root.
243
+ upper.startsWith("WRONGSTACK_") || upper === "EDITOR" || upper === "VISUAL" || upper === "PAGER") {
244
+ out[k] = v;
245
+ }
246
+ }
247
+ if (opts.extra) {
248
+ Object.assign(out, opts.extra);
249
+ }
250
+ if (opts.sessionId) out["WRONGSTACK_SESSION_ID"] = opts.sessionId;
251
+ return out;
252
+ }
253
+ var ALLOWED_KEYS, SECRET_NAME_PARTS, NODE_OPTIONS_INJECTION_FLAG, NODE_OPTIONS_INJECTION_FLAG_EQ;
254
+ var init_child_env = __esm({
255
+ "src/utils/child-env.ts"() {
256
+ ALLOWED_KEYS = /* @__PURE__ */ new Set([
257
+ "PATH",
258
+ "HOME",
259
+ "USER",
260
+ "USERNAME",
261
+ "LOGNAME",
262
+ "SHELL",
263
+ "LANG",
264
+ "LC_ALL",
265
+ "LC_CTYPE",
266
+ "TERM",
267
+ "TZ",
268
+ "TMPDIR",
269
+ "TEMP",
270
+ "TMP",
271
+ "PWD",
272
+ "OLDPWD",
273
+ "COMSPEC",
274
+ "SYSTEMROOT",
275
+ "SYSTEMDRIVE",
276
+ "WINDIR",
277
+ "PROGRAMFILES",
278
+ "PROGRAMFILES(X86)",
279
+ "PROGRAMDATA",
280
+ "APPDATA",
281
+ "LOCALAPPDATA",
282
+ "USERPROFILE",
283
+ "PUBLIC",
284
+ "PATHEXT"
285
+ ]);
286
+ SECRET_NAME_PARTS = [
287
+ "TOKEN",
288
+ "SECRET",
289
+ "PASSWORD",
290
+ "PASSWD",
291
+ "AUTH",
292
+ "CRED",
293
+ "BEARER",
294
+ "COOKIE",
295
+ "PRIVATE"
296
+ ];
297
+ NODE_OPTIONS_INJECTION_FLAG = /^(?:--require|-r|--import|--loader|--experimental-loader)$/;
298
+ NODE_OPTIONS_INJECTION_FLAG_EQ = /^(?:--require|-r|--import|--loader|--experimental-loader)=/;
299
+ }
300
+ });
301
+
302
+ // src/utils/error.ts
303
+ function toErrorMessage(err) {
304
+ return err instanceof Error ? err.message : String(err);
305
+ }
306
+ var init_error = __esm({
307
+ "src/utils/error.ts"() {
308
+ }
309
+ });
310
+
311
+ // src/utils/expect-defined.ts
312
+ function expectDefined(value, label) {
313
+ if (value === null || value === void 0) {
314
+ const err = new Error("Expected value to be defined");
315
+ err.name = "ExpectDefinedError";
316
+ throw err;
317
+ }
318
+ return value;
319
+ }
320
+ var init_expect_defined = __esm({
321
+ "src/utils/expect-defined.ts"() {
322
+ }
323
+ });
324
+
325
+ // src/utils/string.ts
326
+ function truncate(s, max) {
327
+ return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;
328
+ }
329
+ var init_string = __esm({
330
+ "src/utils/string.ts"() {
331
+ }
332
+ });
333
+
334
+ // src/types/errors.ts
335
+ function formatContext(ctx) {
336
+ const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
337
+ return parts.length > 0 ? `[${parts.join(" ")}]` : "";
338
+ }
339
+ var ERROR_CODES, WrongStackError, AgentError, SddError, FsError;
340
+ var init_errors = __esm({
341
+ "src/types/errors.ts"() {
342
+ ERROR_CODES = {
343
+ // Provider
344
+ PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
345
+ PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
346
+ PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
347
+ PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
348
+ PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
349
+ PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
350
+ PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
351
+ // Tool
352
+ TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
353
+ TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
354
+ TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
355
+ TOOL_TIMEOUT: "TOOL_TIMEOUT",
356
+ TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
357
+ // Config
358
+ CONFIG_INVALID: "CONFIG_INVALID",
359
+ CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
360
+ CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
361
+ CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
362
+ // Plugin
363
+ PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
364
+ PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
365
+ PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
366
+ // Agent
367
+ AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
368
+ AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
369
+ AGENT_ABORTED: "AGENT_ABORTED",
370
+ AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
371
+ // Session
372
+ SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
373
+ SESSION_CORRUPTED: "SESSION_CORRUPTED",
374
+ SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
375
+ // Container / Registry
376
+ CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
377
+ CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
378
+ CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
379
+ REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
380
+ REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
381
+ REGISTRY_INVALID: "REGISTRY_INVALID",
382
+ // File system
383
+ FS_READ_FAILED: "FS_READ_FAILED",
384
+ FS_WRITE_FAILED: "FS_WRITE_FAILED",
385
+ FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
386
+ FS_DELETE_FAILED: "FS_DELETE_FAILED",
387
+ FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
388
+ // SDD (Spec-Driven Development)
389
+ SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
390
+ SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
391
+ SDD_INVALID_STATE: "SDD_INVALID_STATE",
392
+ SDD_NOT_READY: "SDD_NOT_READY",
393
+ // General
394
+ VALIDATION_ERROR: "VALIDATION_ERROR",
395
+ PARSE_FAILED: "PARSE_FAILED",
396
+ UNKNOWN: "UNKNOWN"
397
+ };
398
+ WrongStackError = class extends Error {
399
+ code;
400
+ subsystem;
401
+ severity;
402
+ recoverable;
403
+ context;
404
+ constructor(opts) {
405
+ super(opts.message, { cause: opts.cause });
406
+ this.name = "WrongStackError";
407
+ this.code = opts.code;
408
+ this.subsystem = opts.subsystem;
409
+ this.severity = opts.severity ?? "error";
410
+ this.recoverable = opts.recoverable ?? false;
411
+ this.context = opts.context;
412
+ }
413
+ /**
414
+ * Render a one-line user-facing description.
415
+ * Subclasses should override for domain-specific formatting.
416
+ */
417
+ describe() {
418
+ const ctx = this.context ? ` ${formatContext(this.context)}` : "";
419
+ return `${this.code}: ${this.message}${ctx}`;
420
+ }
421
+ };
422
+ AgentError = class extends WrongStackError {
423
+ constructor(opts) {
424
+ super({
425
+ message: opts.message,
426
+ code: opts.code,
427
+ subsystem: "agent",
428
+ severity: opts.code === ERROR_CODES.AGENT_ABORTED ? "warning" : "error",
429
+ recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,
430
+ context: opts.context,
431
+ cause: opts.cause
432
+ });
433
+ this.name = "AgentError";
434
+ }
435
+ };
436
+ SddError = class extends WrongStackError {
437
+ constructor(opts) {
438
+ super({
439
+ message: opts.message,
440
+ code: opts.code,
441
+ subsystem: "sdd",
442
+ severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? "warning" : "error",
443
+ recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,
444
+ context: opts.context,
445
+ cause: opts.cause
446
+ });
447
+ this.name = "SddError";
448
+ }
449
+ };
450
+ FsError = class extends WrongStackError {
451
+ path;
452
+ constructor(opts) {
453
+ super({
454
+ message: opts.message,
455
+ code: opts.code,
456
+ subsystem: "fs",
457
+ severity: "error",
458
+ recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,
459
+ context: { path: opts.path, ...opts.context },
460
+ cause: opts.cause
461
+ });
462
+ this.name = "FsError";
463
+ this.path = opts.path;
464
+ }
465
+ };
466
+ }
467
+ });
468
+
158
469
  // src/sdd/spec-parser.ts
159
470
  var SpecParser = class {
160
471
  parse(content) {
@@ -657,231 +968,9 @@ function topologicalSort(graph) {
657
968
  return result;
658
969
  }
659
970
 
660
- // src/utils/assert-never.ts
661
- function assertNever(x, message) {
662
- const err = new Error(
663
- `Unhandled case: ${JSON.stringify(x)}`
664
- );
665
- err.name = "AssertNeverError";
666
- throw err;
667
- }
668
-
669
- // src/utils/child-env.ts
670
- var ALLOWED_KEYS = /* @__PURE__ */ new Set([
671
- "PATH",
672
- "HOME",
673
- "USER",
674
- "USERNAME",
675
- "LOGNAME",
676
- "SHELL",
677
- "LANG",
678
- "LC_ALL",
679
- "LC_CTYPE",
680
- "TERM",
681
- "TZ",
682
- "TMPDIR",
683
- "TEMP",
684
- "TMP",
685
- "PWD",
686
- "OLDPWD",
687
- "COMSPEC",
688
- "SYSTEMROOT",
689
- "SYSTEMDRIVE",
690
- "WINDIR",
691
- "PROGRAMFILES",
692
- "PROGRAMFILES(X86)",
693
- "PROGRAMDATA",
694
- "APPDATA",
695
- "LOCALAPPDATA",
696
- "USERPROFILE",
697
- "PUBLIC",
698
- "PATHEXT"
699
- ]);
700
- var SECRET_NAME_PARTS = [
701
- "TOKEN",
702
- "SECRET",
703
- "PASSWORD",
704
- "PASSWD",
705
- "AUTH",
706
- "CRED",
707
- "BEARER",
708
- "COOKIE",
709
- "PRIVATE"
710
- ];
711
- function looksSecret(name) {
712
- const upper = name.toUpperCase();
713
- for (const p of SECRET_NAME_PARTS) {
714
- if (upper.includes(p)) return true;
715
- }
716
- if (/(?:^|_)KEY(?:$|_|S$)/i.test(upper)) return true;
717
- if (/API[_-]?KEY/i.test(upper)) return true;
718
- if (/ACCESS[_-]?KEY/i.test(upper)) return true;
719
- if (/SESSION[_-]?ID/i.test(upper) === false && /SESSION/i.test(upper)) {
720
- return true;
721
- }
722
- return false;
723
- }
724
- function valueHasEmbeddedCredential(value) {
725
- return /\b[a-z][a-z0-9+.-]*:\/\/[^/\s:@]*:[^/\s@]+@/i.test(value);
726
- }
727
- var NODE_OPTIONS_INJECTION_FLAG = /^(?:--require|-r|--import|--loader|--experimental-loader)$/;
728
- var NODE_OPTIONS_INJECTION_FLAG_EQ = /^(?:--require|-r|--import|--loader|--experimental-loader)=/;
729
- function sanitizeNodeOptions(value) {
730
- const tokens = value.split(/\s+/).filter(Boolean);
731
- const kept = [];
732
- for (let i = 0; i < tokens.length; i++) {
733
- const tok = tokens[i];
734
- if (NODE_OPTIONS_INJECTION_FLAG_EQ.test(tok)) continue;
735
- if (NODE_OPTIONS_INJECTION_FLAG.test(tok)) {
736
- i++;
737
- continue;
738
- }
739
- kept.push(tok);
740
- }
741
- return kept.join(" ");
742
- }
743
- function buildChildEnv(optsOrSessionId) {
744
- const opts = {};
745
- const hasOwn = Object.hasOwn(process.env, "WRONGSTACK_CHILD_ENV_PASSTHROUGH");
746
- const legacyHasOwn = Object.hasOwn(process.env, "WRONGSTACK_BASH_ENV_PASSTHROUGH");
747
- const passthrough = hasOwn && process.env["WRONGSTACK_CHILD_ENV_PASSTHROUGH"] === "1" || legacyHasOwn && process.env["WRONGSTACK_BASH_ENV_PASSTHROUGH"] === "1";
748
- if (passthrough && !process.env["CI"]) {
749
- console.warn(
750
- "[agent] WARNING: WRONGSTACK_*_ENV_PASSTHROUGH=1 is active \u2014\n all parent env vars (including API keys) forwarded to child processes.\n Do not use on shared or multi-tenant systems."
751
- );
752
- }
753
- const out = {};
754
- const nodeEnvDefaulted = process.env["WRONGSTACK_NODE_ENV_DEFAULTED"] === "1";
755
- for (const [k, v] of Object.entries(process.env)) {
756
- if (v === void 0) continue;
757
- if (nodeEnvDefaulted && (k === "NODE_ENV" || k === "WRONGSTACK_NODE_ENV_DEFAULTED")) continue;
758
- if (passthrough) {
759
- out[k] = v;
760
- continue;
761
- }
762
- const upper = k.toUpperCase();
763
- if (valueHasEmbeddedCredential(v)) continue;
764
- if (ALLOWED_KEYS.has(upper)) {
765
- out[k] = v;
766
- continue;
767
- }
768
- if (looksSecret(upper)) continue;
769
- if (upper === "NODE_OPTIONS") {
770
- const sanitized = sanitizeNodeOptions(v);
771
- if (sanitized) out[k] = sanitized;
772
- continue;
773
- }
774
- if (upper.startsWith("NODE_") || upper.startsWith("NPM_") || upper.startsWith("PNPM_") || upper.startsWith("YARN_") || upper.startsWith("GIT_") || upper.startsWith("CI") || upper.startsWith("XDG_") || // Our own non-secret knobs (WRONGSTACK_HOME, WRONGSTACK_SESSION_ID, …).
775
- // Secrets never live in WRONGSTACK_* env vars (they're in the encrypted
776
- // vault). Forwarding keeps child wstack processes — e.g. ones spawned
777
- // by the test suite — inside the same redirected global root.
778
- upper.startsWith("WRONGSTACK_") || upper === "EDITOR" || upper === "VISUAL" || upper === "PAGER") {
779
- out[k] = v;
780
- }
781
- }
782
- if (opts.extra) {
783
- Object.assign(out, opts.extra);
784
- }
785
- if (opts.sessionId) out["WRONGSTACK_SESSION_ID"] = opts.sessionId;
786
- return out;
787
- }
788
-
789
- // src/utils/error.ts
790
- function toErrorMessage(err) {
791
- return err instanceof Error ? err.message : String(err);
792
- }
793
-
794
- // src/utils/expect-defined.ts
795
- function expectDefined(value, label) {
796
- if (value === null || value === void 0) {
797
- const err = new Error("Expected value to be defined");
798
- err.name = "ExpectDefinedError";
799
- throw err;
800
- }
801
- return value;
802
- }
803
-
804
- // src/utils/string.ts
805
- function truncate(s, max) {
806
- return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;
807
- }
808
-
809
- // src/types/errors.ts
810
- var ERROR_CODES = {
811
- // Provider
812
- PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
813
- PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
814
- PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
815
- PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
816
- PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
817
- PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
818
- // Agent
819
- AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
820
- AGENT_ABORTED: "AGENT_ABORTED",
821
- AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
822
- // SDD (Spec-Driven Development)
823
- SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
824
- SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
825
- SDD_INVALID_STATE: "SDD_INVALID_STATE",
826
- SDD_NOT_READY: "SDD_NOT_READY"};
827
- var WrongStackError = class extends Error {
828
- code;
829
- subsystem;
830
- severity;
831
- recoverable;
832
- context;
833
- constructor(opts) {
834
- super(opts.message, { cause: opts.cause });
835
- this.name = "WrongStackError";
836
- this.code = opts.code;
837
- this.subsystem = opts.subsystem;
838
- this.severity = opts.severity ?? "error";
839
- this.recoverable = opts.recoverable ?? false;
840
- this.context = opts.context;
841
- }
842
- /**
843
- * Render a one-line user-facing description.
844
- * Subclasses should override for domain-specific formatting.
845
- */
846
- describe() {
847
- const ctx = this.context ? ` ${formatContext(this.context)}` : "";
848
- return `${this.code}: ${this.message}${ctx}`;
849
- }
850
- };
851
- function formatContext(ctx) {
852
- const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
853
- return parts.length > 0 ? `[${parts.join(" ")}]` : "";
854
- }
855
- var AgentError = class extends WrongStackError {
856
- constructor(opts) {
857
- super({
858
- message: opts.message,
859
- code: opts.code,
860
- subsystem: "agent",
861
- severity: opts.code === ERROR_CODES.AGENT_ABORTED ? "warning" : "error",
862
- recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,
863
- context: opts.context,
864
- cause: opts.cause
865
- });
866
- this.name = "AgentError";
867
- }
868
- };
869
- var SddError = class extends WrongStackError {
870
- constructor(opts) {
871
- super({
872
- message: opts.message,
873
- code: opts.code,
874
- subsystem: "sdd",
875
- severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? "warning" : "error",
876
- recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,
877
- context: opts.context,
878
- cause: opts.cause
879
- });
880
- this.name = "SddError";
881
- }
882
- };
883
-
884
971
  // src/sdd/task-tracker.ts
972
+ init_errors();
973
+ init_error();
885
974
  var TaskTracker = class {
886
975
  constructor(opts) {
887
976
  this.opts = opts;
@@ -1239,6 +1328,7 @@ function compareByField(a, b, field) {
1239
1328
  }
1240
1329
 
1241
1330
  // src/sdd/task-flow.ts
1331
+ init_errors();
1242
1332
  var TaskFlow = class {
1243
1333
  constructor(opts) {
1244
1334
  this.opts = opts;
@@ -2089,13 +2179,22 @@ var SddBoardProjector = class _SddBoardProjector {
2089
2179
  this.timer = null;
2090
2180
  }
2091
2181
  const snap = this.build();
2092
- this.o.events.emit("sdd.board.snapshot", { runId: this.o.runId, snapshot: snap });
2182
+ const sessionId = this.currentSessionId();
2183
+ this.o.events.emit("sdd.board.snapshot", {
2184
+ ...sessionId ? { sessionId } : {},
2185
+ runId: this.o.runId,
2186
+ snapshot: snap
2187
+ });
2093
2188
  if (this.o.store) {
2094
2189
  const store = this.o.store;
2095
2190
  this.lastSave = this.lastSave.then(() => store.saveSnapshot(snap)).catch(() => {
2096
2191
  });
2097
2192
  }
2098
2193
  }
2194
+ currentSessionId() {
2195
+ const value = typeof this.o.sessionId === "function" ? this.o.sessionId() : this.o.sessionId;
2196
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2197
+ }
2099
2198
  };
2100
2199
 
2101
2200
  // src/sdd/sdd-run-registry.ts
@@ -2113,6 +2212,9 @@ var SddRunRegistry = class {
2113
2212
  };
2114
2213
 
2115
2214
  // src/sdd/spec-builder.ts
2215
+ init_expect_defined();
2216
+ init_error();
2217
+ init_errors();
2116
2218
  function buildQuestioningPrompt(session, min, max) {
2117
2219
  const answered = session.answers.length;
2118
2220
  const remaining = Math.max(0, min - answered);
@@ -2930,6 +3032,12 @@ function isExplanatoryText(text) {
2930
3032
  return lower.startsWith("i'") || lower.startsWith("i will") || lower.startsWith("let me") || lower.startsWith("here's my") || lower.startsWith("here is my") || lower.startsWith("i'm going to") || lower.startsWith("first, let me") || lower.startsWith("sure") || lower.startsWith("of course") || lower.startsWith("okay") || lower.startsWith("ok,") || lower.startsWith("sounds good") || lower.startsWith("no problem") || text.split("\n").length < 3 && !text.includes(".");
2931
3033
  }
2932
3034
 
3035
+ // src/sdd/sdd-parallel-run.ts
3036
+ init_expect_defined();
3037
+
3038
+ // src/coordination/agent-subagent-runner.ts
3039
+ init_errors();
3040
+
2933
3041
  // src/coordination/subagent-budget.ts
2934
3042
  var TIMEOUT_PREEMPT_FRACTION = 0.85;
2935
3043
  var DECISION_TIMEOUT_MS = 6e4;
@@ -3001,6 +3109,7 @@ var SubagentBudget = class _SubagentBudget {
3001
3109
  */
3002
3110
  lastActivityTime = null;
3003
3111
  _onThreshold;
3112
+ _sessionId;
3004
3113
  /**
3005
3114
  * Hard cap on how long `_negotiateExtension` waits for the coordinator to
3006
3115
  * respond before defaulting to 'stop'. Without this fallback an absent
@@ -3069,10 +3178,15 @@ var SubagentBudget = class _SubagentBudget {
3069
3178
  get mode() {
3070
3179
  return this._mode;
3071
3180
  }
3072
- constructor(limits = {}, mode = "auto") {
3181
+ constructor(limits = {}, mode = "auto", options = {}) {
3073
3182
  this._mode = mode;
3183
+ this._sessionId = options.sessionId;
3074
3184
  this.limits = { ...limits };
3075
3185
  }
3186
+ currentSessionId() {
3187
+ const value = typeof this._sessionId === "function" ? this._sessionId() : this._sessionId;
3188
+ return typeof value === "string" && value.length > 0 ? value : void 0;
3189
+ }
3076
3190
  start() {
3077
3191
  this.startTime = Date.now();
3078
3192
  this.lastActivityTime = this.startTime;
@@ -3240,7 +3354,9 @@ var SubagentBudget = class _SubagentBudget {
3240
3354
  resolve4(d);
3241
3355
  };
3242
3356
  const fallback = setTimeout(() => respond("stop"), _SubagentBudget.DECISION_TIMEOUT_MS);
3357
+ const sessionId = this.currentSessionId();
3243
3358
  bus.emit("budget.threshold_reached", {
3359
+ ...sessionId ? { sessionId } : {},
3244
3360
  kind: entry.kind,
3245
3361
  used: entry.used,
3246
3362
  limit: entry.limit,
@@ -3584,6 +3700,8 @@ function defaultFormatTaskInput(task) {
3584
3700
  }
3585
3701
 
3586
3702
  // src/types/provider.ts
3703
+ init_errors();
3704
+ init_string();
3587
3705
  var ProviderError = class extends WrongStackError {
3588
3706
  status;
3589
3707
  retryable;
@@ -3653,6 +3771,8 @@ function providerStatusToCode(status, type) {
3653
3771
  }
3654
3772
 
3655
3773
  // src/coordination/coordinator/error-classifier.ts
3774
+ init_errors();
3775
+ init_error();
3656
3776
  function classifySubagentError(err, hints = {}) {
3657
3777
  if (err instanceof AgentError && err.cause) {
3658
3778
  return classifySubagentError(err.cause, hints);
@@ -5461,6 +5581,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
5461
5581
  coordinatorId;
5462
5582
  config;
5463
5583
  runner;
5584
+ sessionId;
5464
5585
  fleetBus;
5465
5586
  subagents = /* @__PURE__ */ new Map();
5466
5587
  /**
@@ -5495,6 +5616,11 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
5495
5616
  this.coordinatorId = config.coordinatorId;
5496
5617
  this.config = config;
5497
5618
  this.runner = options.runner;
5619
+ this.sessionId = options.sessionId;
5620
+ }
5621
+ currentSessionId() {
5622
+ const value = typeof this.sessionId === "function" ? this.sessionId() : this.sessionId;
5623
+ return typeof value === "string" && value.length > 0 ? value : void 0;
5498
5624
  }
5499
5625
  /**
5500
5626
  * Replace the runner after construction. Used when the runner depends
@@ -5653,11 +5779,16 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
5653
5779
  status: s.status,
5654
5780
  assigned: s.context.parentBridge !== null
5655
5781
  }));
5782
+ const sessionId = this.currentSessionId();
5656
5783
  this.fleetBus?.emit({
5657
5784
  subagentId: this.coordinatorId,
5658
5785
  ts: Date.now(),
5659
5786
  type: "coordinator.stats",
5660
- payload: { ...stats, subagentStatuses }
5787
+ payload: {
5788
+ ...sessionId ? { sessionId } : {},
5789
+ ...stats,
5790
+ subagentStatuses
5791
+ }
5661
5792
  });
5662
5793
  }
5663
5794
  getStatus() {
@@ -5860,16 +5991,20 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
5860
5991
  const rawTimeoutMs = subagent.config.timeoutMs;
5861
5992
  const rawIdleTimeoutMs = subagent.config.idleTimeoutMs;
5862
5993
  const configWithRosterDefaults = applyRosterBudget(subagent.config);
5863
- const budget = new SubagentBudget({
5864
- maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
5865
- maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
5866
- maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
5867
- maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
5868
- // Wall-clock cap is opt-in (explicit config / defaultBudget only); the
5869
- // roster no longer supplies one. Idle is the default reaper.
5870
- timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs,
5871
- idleTimeoutMs: rawIdleTimeoutMs ?? this.config.defaultBudget?.idleTimeoutMs ?? configWithRosterDefaults.idleTimeoutMs
5872
- });
5994
+ const budget = new SubagentBudget(
5995
+ {
5996
+ maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
5997
+ maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
5998
+ maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
5999
+ maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
6000
+ // Wall-clock cap is opt-in (explicit config / defaultBudget only); the
6001
+ // roster no longer supplies one. Idle is the default reaper.
6002
+ timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs,
6003
+ idleTimeoutMs: rawIdleTimeoutMs ?? this.config.defaultBudget?.idleTimeoutMs ?? configWithRosterDefaults.idleTimeoutMs
6004
+ },
6005
+ "auto",
6006
+ { sessionId: () => this.currentSessionId() }
6007
+ );
5873
6008
  subagent.activeBudget = budget;
5874
6009
  if (!this.runner) {
5875
6010
  return;
@@ -5972,7 +6107,9 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
5972
6107
  resolveDecision(d);
5973
6108
  };
5974
6109
  const fallback = setTimeout(() => resolve4("stop"), DECISION_TIMEOUT_MS);
6110
+ const sessionId = this.currentSessionId();
5975
6111
  budget._events?.emit("budget.threshold_reached", {
6112
+ ...sessionId ? { sessionId } : {},
5976
6113
  kind: "timeout",
5977
6114
  used,
5978
6115
  limit,
@@ -6006,7 +6143,9 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6006
6143
  const wallExceeded = wallLimit !== void 0 && elapsed >= wallLimit;
6007
6144
  const idleExceeded = idleLimit !== void 0 && budget.idleMs() >= idleLimit;
6008
6145
  if (idleExceeded && !wallExceeded) {
6146
+ const sessionId = this.currentSessionId();
6009
6147
  budget._events?.emit("budget.threshold_reached", {
6148
+ ...sessionId ? { sessionId } : {},
6010
6149
  kind: "idle_timeout",
6011
6150
  used: budget.idleMs(),
6012
6151
  limit: idleLimit ?? 0,
@@ -6214,6 +6353,9 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6214
6353
  }
6215
6354
  };
6216
6355
 
6356
+ // src/sdd/sdd-parallel-run.ts
6357
+ init_errors();
6358
+
6217
6359
  // src/sdd/sdd-task-decomposer.ts
6218
6360
  var SddTaskDecomposer = class {
6219
6361
  constructor(tracker, _graph, opts = {}) {
@@ -6332,6 +6474,7 @@ var SddParallelRun = class {
6332
6474
  this.maxFailedSweeps = Math.max(0, opts.maxFailedRetrySweeps ?? 2);
6333
6475
  this.runId = opts.runId ?? `sdd-${randomUUID().slice(0, 8)}`;
6334
6476
  this.events = opts.events;
6477
+ this.sessionIdSource = opts.sessionId;
6335
6478
  this.maxTotalWaves = opts.maxTotalWaves ?? opts.graph.nodes.size * (this.maxRetries + 2) + 10;
6336
6479
  this.maxWallClockMs = opts.maxWallClockMs;
6337
6480
  this.maxRecoveryRounds = Math.max(0, opts.maxRecoveryRounds ?? 0);
@@ -6360,6 +6503,7 @@ var SddParallelRun = class {
6360
6503
  retryMap = /* @__PURE__ */ new Map();
6361
6504
  runId;
6362
6505
  events;
6506
+ sessionIdSource;
6363
6507
  maxTotalWaves;
6364
6508
  maxWallClockMs;
6365
6509
  maxRecoveryRounds;
@@ -6392,7 +6536,15 @@ var SddParallelRun = class {
6392
6536
  round = 0;
6393
6537
  /** Type-safe emit on the optional EventBus (no-op when unwired). */
6394
6538
  emit(event, payload) {
6395
- this.events?.emit(event, payload);
6539
+ const sessionId = this.currentSessionId();
6540
+ this.events?.emit(
6541
+ event,
6542
+ sessionId ? { ...payload, sessionId } : payload
6543
+ );
6544
+ }
6545
+ currentSessionId() {
6546
+ const value = typeof this.sessionIdSource === "function" ? this.sessionIdSource() : this.sessionIdSource;
6547
+ return typeof value === "string" && value.length > 0 ? value : void 0;
6396
6548
  }
6397
6549
  // -------------------------------------------------------------------
6398
6550
  // Public API
@@ -7231,6 +7383,7 @@ function startSddRun(opts) {
7231
7383
  graph: opts.graph,
7232
7384
  agent: opts.agent,
7233
7385
  projectRoot: opts.projectRoot,
7386
+ sessionId: opts.sessionId,
7234
7387
  parallelSlots: opts.parallelSlots,
7235
7388
  taskTimeoutMs: opts.taskTimeoutMs,
7236
7389
  taskIdleTimeoutMs: opts.taskIdleTimeoutMs,
@@ -7253,6 +7406,7 @@ function startSddRun(opts) {
7253
7406
  tracker: opts.tracker,
7254
7407
  events: opts.events,
7255
7408
  store: opts.boardStore,
7409
+ sessionId: opts.sessionId,
7256
7410
  specId: opts.graph.specId,
7257
7411
  defaultModel: opts.defaultModel,
7258
7412
  defaultProvider: opts.defaultProvider,
@@ -7327,10 +7481,15 @@ function startSddRun(opts) {
7327
7481
  stop: () => run.stop()
7328
7482
  };
7329
7483
  }
7484
+
7485
+ // src/worktree/worktree-manager.ts
7486
+ init_child_env();
7487
+ init_error();
7330
7488
  var MAX_SLUG = 40;
7331
7489
  var WorktreeManager = class {
7332
7490
  projectRoot;
7333
7491
  events;
7492
+ sessionIdSource;
7334
7493
  gitBin;
7335
7494
  runGit;
7336
7495
  /** Keyed by ownerId. */
@@ -7339,6 +7498,7 @@ var WorktreeManager = class {
7339
7498
  constructor(opts) {
7340
7499
  this.projectRoot = resolve(opts.projectRoot);
7341
7500
  this.events = opts.events;
7501
+ this.sessionIdSource = opts.sessionId;
7342
7502
  this.gitBin = opts.gitBin ?? "git";
7343
7503
  this.runGit = opts.run ?? ((args, cwd) => this.defaultRun(args, cwd));
7344
7504
  }
@@ -7932,7 +8092,15 @@ ${check.stderr}`);
7932
8092
  if (patch) Object.assign(handle, patch);
7933
8093
  }
7934
8094
  emit(event, payload) {
7935
- this.events?.emit(event, payload);
8095
+ const sessionId = this.currentSessionId();
8096
+ this.events?.emit(
8097
+ event,
8098
+ sessionId && payload && typeof payload === "object" ? { ...payload, sessionId } : payload
8099
+ );
8100
+ }
8101
+ currentSessionId() {
8102
+ const value = typeof this.sessionIdSource === "function" ? this.sessionIdSource() : this.sessionIdSource;
8103
+ return typeof value === "string" && value.length > 0 ? value : void 0;
7936
8104
  }
7937
8105
  defaultRun(args, cwd) {
7938
8106
  return new Promise((res) => {
@@ -8206,6 +8374,7 @@ function templateToMarkdown(template, title) {
8206
8374
  }
8207
8375
 
8208
8376
  // src/sdd/task-visualizer.ts
8377
+ init_string();
8209
8378
  var STATUS_ICON = {
8210
8379
  pending: "\u25CB",
8211
8380
  in_progress: "\u25D0",
@@ -8357,6 +8526,7 @@ function renderSpecAnalysis(spec, analysis) {
8357
8526
  }
8358
8527
 
8359
8528
  // src/sdd/critical-path.ts
8529
+ init_expect_defined();
8360
8530
  function analyzeCriticalPath(graph) {
8361
8531
  const nodes = Array.from(graph.nodes.values());
8362
8532
  const topoOrder = topologicalSort(graph);
@@ -8528,6 +8698,7 @@ function computeParallelGroups(graph, blockedByMap) {
8528
8698
  }
8529
8699
 
8530
8700
  // src/sdd/spec-versioning.ts
8701
+ init_assert_never();
8531
8702
  var SpecVersioning = class {
8532
8703
  versions = /* @__PURE__ */ new Map();
8533
8704
  /** Record a new version of a spec. */