@wrongstack/core 0.54.1 → 0.63.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.
Files changed (54) hide show
  1. package/dist/{agent-bridge-Dnhw4tnM.d.ts → agent-bridge-B5rxWrg3.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-By7jruZ_.d.ts → agent-subagent-runner-Zc3f37Sg.d.ts} +3 -3
  3. package/dist/{compactor-Duhsf0ge.d.ts → compactor-0vjZ8KTk.d.ts} +1 -1
  4. package/dist/{config-bht0txXS.d.ts → config-BdDuaZmB.d.ts} +112 -2
  5. package/dist/{context-DtPKqKYV.d.ts → context-iFMEO2rN.d.ts} +8 -8
  6. package/dist/coordination/index.d.ts +12 -12
  7. package/dist/defaults/index.d.ts +21 -21
  8. package/dist/defaults/index.js +254 -92
  9. package/dist/defaults/index.js.map +1 -1
  10. package/dist/{events-CbHTS4ZZ.d.ts → events-k8CHjcrN.d.ts} +20 -1
  11. package/dist/execution/index.d.ts +14 -14
  12. package/dist/execution/index.js +70 -10
  13. package/dist/execution/index.js.map +1 -1
  14. package/dist/extension/index.d.ts +7 -7
  15. package/dist/{goal-store-DwcTDDiX.d.ts → goal-store-iHltMi5n.d.ts} +1 -1
  16. package/dist/{index-CI271MjL.d.ts → index-Bc6BiP5q.d.ts} +77 -6
  17. package/dist/{index-ge5F2dnc.d.ts → index-CWdW_CJt.d.ts} +10 -8
  18. package/dist/index.d.ts +56 -32
  19. package/dist/index.js +520 -85
  20. package/dist/index.js.map +1 -1
  21. package/dist/infrastructure/index.d.ts +6 -6
  22. package/dist/infrastructure/index.js +1 -1
  23. package/dist/infrastructure/index.js.map +1 -1
  24. package/dist/kernel/index.d.ts +9 -9
  25. package/dist/kernel/index.js +3 -1
  26. package/dist/kernel/index.js.map +1 -1
  27. package/dist/{mcp-servers-DE6gzBry.d.ts → mcp-servers-CwqQDMYy.d.ts} +3 -3
  28. package/dist/models/index.d.ts +2 -2
  29. package/dist/{multi-agent-BmC_xiog.d.ts → multi-agent-SASYOrWA.d.ts} +2 -2
  30. package/dist/{multi-agent-coordinator-CjNX4uBD.d.ts → multi-agent-coordinator-CNUJYq7U.d.ts} +2 -2
  31. package/dist/{null-fleet-bus-BNiSlTna.d.ts → null-fleet-bus-DRoJ0uOY.d.ts} +7 -7
  32. package/dist/observability/index.d.ts +2 -2
  33. package/dist/{path-resolver-Bax85amb.d.ts → path-resolver-C5sPVne8.d.ts} +2 -2
  34. package/dist/{permission-Drm7LpPo.d.ts → permission-Ld-i5ugf.d.ts} +13 -1
  35. package/dist/{permission-policy-CU6sqWxF.d.ts → permission-policy-CL-mPufp.d.ts} +14 -7
  36. package/dist/{plan-templates-CLRcurWN.d.ts → plan-templates-ThBHOjaM.d.ts} +4 -4
  37. package/dist/{provider-runner-BikCxGCx.d.ts → provider-runner-DJQa211J.d.ts} +3 -3
  38. package/dist/{retry-policy-Chtlvr5b.d.ts → retry-policy-BfBScewS.d.ts} +1 -1
  39. package/dist/sdd/index.d.ts +9 -9
  40. package/dist/sdd/index.js +1 -1
  41. package/dist/sdd/index.js.map +1 -1
  42. package/dist/security/index.d.ts +3 -3
  43. package/dist/security/index.js +115 -13
  44. package/dist/security/index.js.map +1 -1
  45. package/dist/{selector-BvSPdJj6.d.ts → selector-DxhW7ML3.d.ts} +1 -1
  46. package/dist/{session-reader-BGhzMir4.d.ts → session-reader-q2ThszgG.d.ts} +1 -1
  47. package/dist/storage/index.d.ts +6 -6
  48. package/dist/{system-prompt-dtzV_mLm.d.ts → system-prompt-7LHyBbIf.d.ts} +32 -2
  49. package/dist/{tool-executor-CgU0yWpB.d.ts → tool-executor-CIjpGaRA.d.ts} +5 -4
  50. package/dist/types/index.d.ts +14 -14
  51. package/dist/types/index.js +62 -6
  52. package/dist/types/index.js.map +1 -1
  53. package/dist/utils/index.d.ts +2 -2
  54. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import * as crypto2 from 'crypto';
2
2
  import { randomBytes, randomUUID, createCipheriv, createDecipheriv, createHash } from 'crypto';
3
3
  import * as fsp from 'fs/promises';
4
- import * as path15 from 'path';
4
+ import * as path16 from 'path';
5
5
  import { isAbsolute, resolve } from 'path';
6
6
  import * as fs5 from 'fs';
7
7
  import * as os from 'os';
@@ -32,9 +32,9 @@ __export(atomic_write_exports, {
32
32
  ensureDir: () => ensureDir
33
33
  });
34
34
  async function atomicWrite(targetPath, content, opts = {}) {
35
- const dir = path15.dirname(targetPath);
35
+ const dir = path16.dirname(targetPath);
36
36
  await fsp.mkdir(dir, { recursive: true });
37
- const tmp = path15.join(dir, `.${path15.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
37
+ const tmp = path16.join(dir, `.${path16.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
38
38
  try {
39
39
  if (typeof content === "string") {
40
40
  await fsp.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
@@ -89,7 +89,7 @@ async function renameWithRetry(from, to) {
89
89
  if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
90
90
  throw err;
91
91
  }
92
- await new Promise((resolve4) => setTimeout(resolve4, delays[i]));
92
+ await new Promise((resolve5) => setTimeout(resolve5, delays[i]));
93
93
  }
94
94
  }
95
95
  throw lastErr;
@@ -169,7 +169,7 @@ var DefaultLogger = class _DefaultLogger {
169
169
  this.pretty = opts.pretty ?? true;
170
170
  if (this.file) {
171
171
  try {
172
- fs5.mkdirSync(path15.dirname(this.file), { recursive: true });
172
+ fs5.mkdirSync(path16.dirname(this.file), { recursive: true });
173
173
  } catch {
174
174
  }
175
175
  }
@@ -342,7 +342,7 @@ var DefaultSessionStore = class {
342
342
  }
343
343
  /** Join session ID to its absolute path within the store directory. */
344
344
  sessionPath(id, ext) {
345
- return path15.join(this.dir, `${id}${ext}`);
345
+ return path16.join(this.dir, `${id}${ext}`);
346
346
  }
347
347
  async ensureShardDir(_id) {
348
348
  await ensureDir(this.dir);
@@ -352,7 +352,7 @@ var DefaultSessionStore = class {
352
352
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
353
353
  const id = meta.id ?? `${startedAt.replace(/[:.]/g, "-")}-${randomBytes(2).toString("hex")}`;
354
354
  const shardDir = await this.ensureShardDir(id);
355
- const file = path15.join(shardDir, `${id}.jsonl`);
355
+ const file = path16.join(shardDir, `${id}.jsonl`);
356
356
  let handle;
357
357
  try {
358
358
  handle = await fsp.open(file, "a", 384);
@@ -445,7 +445,7 @@ var DefaultSessionStore = class {
445
445
  const ids = [];
446
446
  const entries = await fsp.readdir(dir, { withFileTypes: true });
447
447
  for (const entry of entries) {
448
- const full = path15.join(dir, entry.name);
448
+ const full = path16.join(dir, entry.name);
449
449
  if (entry.isDirectory()) {
450
450
  ids.push(...await this.collectSessionIds(full));
451
451
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -601,7 +601,7 @@ var FileSessionWriter = class {
601
601
  this.meta = meta;
602
602
  this.events = events;
603
603
  this.resumed = opts.resumed ?? false;
604
- this.manifestFile = opts.dir ? path15.join(opts.dir, `${id}.summary.json`) : "";
604
+ this.manifestFile = opts.dir ? path16.join(opts.dir, `${id}.summary.json`) : "";
605
605
  this.filePath = opts.filePath ?? "";
606
606
  this.secretScrubber = opts.secretScrubber;
607
607
  this.summary = {
@@ -883,7 +883,7 @@ init_atomic_write();
883
883
  var QueueStore = class {
884
884
  file;
885
885
  constructor(opts) {
886
- this.file = path15.join(opts.dir, "queue.json");
886
+ this.file = path16.join(opts.dir, "queue.json");
887
887
  }
888
888
  async write(items) {
889
889
  if (items.length === 0) {
@@ -953,7 +953,7 @@ var DefaultAttachmentStore = class {
953
953
  let data = input.data;
954
954
  if (this.spoolDir && bytes >= this.spoolThreshold) {
955
955
  await fsp.mkdir(this.spoolDir, { recursive: true });
956
- spooledPath = path15.join(this.spoolDir, `${id}.bin`);
956
+ spooledPath = path16.join(this.spoolDir, `${id}.bin`);
957
957
  await atomicWrite(spooledPath, input.data, {
958
958
  encoding: input.kind === "image" ? "base64" : "utf8"
959
959
  });
@@ -1141,7 +1141,7 @@ ${body.trim()}`);
1141
1141
  async remember(text, scope = "project-memory") {
1142
1142
  return this.runSerialized(scope, async () => {
1143
1143
  const file = this.files[scope];
1144
- await ensureDir(path15.dirname(file));
1144
+ await ensureDir(path16.dirname(file));
1145
1145
  let existing = "";
1146
1146
  try {
1147
1147
  existing = await fsp.readFile(file, "utf8");
@@ -1765,7 +1765,7 @@ var RecoveryLock = class {
1765
1765
  sessionStore;
1766
1766
  probe;
1767
1767
  constructor(opts) {
1768
- this.file = path15.join(opts.dir, LOCK_FILE);
1768
+ this.file = path16.join(opts.dir, LOCK_FILE);
1769
1769
  this.pid = opts.pid ?? process.pid;
1770
1770
  this.hostname = opts.hostname ?? os.hostname();
1771
1771
  this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
@@ -1823,7 +1823,7 @@ var RecoveryLock = class {
1823
1823
  * null return before calling this.
1824
1824
  */
1825
1825
  async write(sessionId) {
1826
- await ensureDir(path15.dirname(this.file));
1826
+ await ensureDir(path16.dirname(this.file));
1827
1827
  const lock = {
1828
1828
  v: 1,
1829
1829
  sessionId,
@@ -3050,7 +3050,7 @@ var DefaultSecretVault = class {
3050
3050
  } catch (err) {
3051
3051
  if (err.code !== "ENOENT") throw err;
3052
3052
  }
3053
- fs5.mkdirSync(path15.dirname(this.keyFile), { recursive: true });
3053
+ fs5.mkdirSync(path16.dirname(this.keyFile), { recursive: true });
3054
3054
  const key = randomBytes(KEY_BYTES);
3055
3055
  try {
3056
3056
  fs5.writeFileSync(this.keyFile, key, { mode: 384, flag: "wx" });
@@ -3119,7 +3119,7 @@ async function rewriteConfigEncrypted(configPath, vault, patch) {
3119
3119
  }
3120
3120
  const merged = deepMerge2(current, patch ?? {});
3121
3121
  const encrypted = encryptConfigSecrets(merged, vault);
3122
- await fsp.mkdir(path15.dirname(configPath), { recursive: true });
3122
+ await fsp.mkdir(path16.dirname(configPath), { recursive: true });
3123
3123
  await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
3124
3124
  await restrictFilePermissions(configPath);
3125
3125
  }
@@ -3321,6 +3321,87 @@ function matchGlob(pattern, input) {
3321
3321
  function matchAny(patterns, input) {
3322
3322
  return patterns.some((p) => matchGlob(p, input));
3323
3323
  }
3324
+ var DESTRUCTIVE_BASH_PATTERNS = [
3325
+ /\bgit\s+(?:clean\s+-[^\s]*[xdf]|reset\s+--hard)\b/i,
3326
+ /\b(?:drop|truncate)\s+(?:table|database|schema)\b/i,
3327
+ /\bdelete\s+from\b/i,
3328
+ /\b(?:mkfs|format|diskpart|shutdown|reboot)\b/i,
3329
+ /\bchmod\s+-R\s+777\b/i,
3330
+ /\bchown\s+-R\b/i,
3331
+ /\b(?:curl|wget)\b.*\|\s*(?:sh|bash|zsh|pwsh|powershell)\b/i,
3332
+ /\b(?:powershell|pwsh)\b.*(?:-encodedcommand|-enc)\b/i,
3333
+ /:\(\)\s*\{\s*:\|:&\s*}\s*;/
3334
+ ];
3335
+ var PROJECT_ESCAPE_PATTERN = /(?:^|[\s"'])\.\.(?:[\\/]|$)/;
3336
+ var ABSOLUTE_PATH_PATTERN = /(?:^|[\s"'])(?:~[\\/]|\/[A-Za-z0-9_.-]|[A-Za-z]:[\\/])/;
3337
+ var SHELL_OPERATORS = /* @__PURE__ */ new Set(["&&", "||", "|", ";", ">", ">>", "<", "2>", "2>>"]);
3338
+ function getInputString(input, key) {
3339
+ if (!input || typeof input !== "object") return void 0;
3340
+ const value = input[key];
3341
+ return typeof value === "string" ? value : void 0;
3342
+ }
3343
+ function pathLooksInsideProject(rawPath, projectRoot) {
3344
+ if (!projectRoot) return false;
3345
+ if (rawPath === "~" || rawPath.startsWith("~/") || rawPath.startsWith("~\\")) return false;
3346
+ const resolved = path16.resolve(projectRoot, rawPath);
3347
+ const relative2 = path16.relative(projectRoot, resolved);
3348
+ return !!relative2 && !relative2.startsWith("..") && !path16.isAbsolute(relative2);
3349
+ }
3350
+ function tokenizeShell(command) {
3351
+ return command.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token) => token.replace(/^['"]|['"]$/g, "")) ?? [];
3352
+ }
3353
+ function pathTokenIsOutsideProject(token, projectRoot) {
3354
+ if (!token || SHELL_OPERATORS.has(token) || token.startsWith("-")) return false;
3355
+ if (token === "/" || token === "~" || token === "." || token === "..") return token !== ".";
3356
+ if (token.includes("*")) return true;
3357
+ if (token.startsWith("..") || token.includes("../") || token.includes("..\\")) return true;
3358
+ if (path16.isAbsolute(token) || token.startsWith("~/")) return !pathLooksInsideProject(token, projectRoot);
3359
+ return false;
3360
+ }
3361
+ function hasDangerousDeleteTarget(tokens, start, projectRoot) {
3362
+ const targets = tokens.slice(start).filter((token) => !token.startsWith("-") && !SHELL_OPERATORS.has(token));
3363
+ if (targets.length === 0) return true;
3364
+ return targets.some((target) => pathTokenIsOutsideProject(target, projectRoot));
3365
+ }
3366
+ function hasDestructiveDelete(command, projectRoot) {
3367
+ const tokens = tokenizeShell(command);
3368
+ for (let i = 0; i < tokens.length; i++) {
3369
+ const token = tokens[i]?.toLowerCase();
3370
+ if (!token) continue;
3371
+ if (token === "rm") {
3372
+ const args = tokens.slice(i + 1);
3373
+ const recursiveOrForce = args.some(
3374
+ (arg) => /^-[^-]*[rf]/i.test(arg) || arg === "--recursive" || arg === "--force"
3375
+ );
3376
+ if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
3377
+ }
3378
+ if (token === "rmdir" || token === "rd") {
3379
+ const args = tokens.slice(i + 1);
3380
+ const recursive = args.some((arg) => arg.toLowerCase() === "/s");
3381
+ if (recursive && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
3382
+ }
3383
+ if (token === "del" || token === "erase") {
3384
+ if (hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
3385
+ }
3386
+ if (token === "remove-item") {
3387
+ const args = tokens.slice(i + 1).map((arg) => arg.toLowerCase());
3388
+ const recursiveOrForce = args.includes("-recurse") || args.includes("-force");
3389
+ if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
3390
+ }
3391
+ }
3392
+ return false;
3393
+ }
3394
+ function isClearlyDestructiveBashCommand(command, projectRoot) {
3395
+ const trimmed = command.trim();
3396
+ if (!trimmed) return false;
3397
+ if (hasDestructiveDelete(trimmed, projectRoot)) return true;
3398
+ if (DESTRUCTIVE_BASH_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
3399
+ if (/\bcd\s+(?:\.\.|~|\/|[A-Za-z]:[\\/])/i.test(trimmed)) return true;
3400
+ if (PROJECT_ESCAPE_PATTERN.test(trimmed)) return true;
3401
+ const absolute = trimmed.match(ABSOLUTE_PATH_PATTERN)?.[0]?.trim().replace(/^['"]|['"]$/g, "");
3402
+ if (absolute && !pathLooksInsideProject(absolute, projectRoot)) return true;
3403
+ return false;
3404
+ }
3324
3405
 
3325
3406
  // src/security/permission-policy.ts
3326
3407
  var DefaultPermissionPolicy = class {
@@ -3328,7 +3409,7 @@ var DefaultPermissionPolicy = class {
3328
3409
  loaded = false;
3329
3410
  trustFile;
3330
3411
  yolo;
3331
- forceAllYolo;
3412
+ yoloDestructive;
3332
3413
  /**
3333
3414
  * Session-scoped "soft deny" map. When the user presses 'n' (block once),
3334
3415
  * the tool+pattern is added here. If the LLM retries in the same session,
@@ -3361,7 +3442,7 @@ var DefaultPermissionPolicy = class {
3361
3442
  constructor(opts) {
3362
3443
  this.trustFile = opts.trustFile;
3363
3444
  this.yolo = opts.yolo ?? false;
3364
- this.forceAllYolo = opts.forceAllYolo ?? false;
3445
+ this.yoloDestructive = opts.yoloDestructive ?? opts.forceAllYolo ?? false;
3365
3446
  this.promptDelegate = opts.promptDelegate;
3366
3447
  }
3367
3448
  /**
@@ -3381,13 +3462,21 @@ var DefaultPermissionPolicy = class {
3381
3462
  getYolo() {
3382
3463
  return this.yolo;
3383
3464
  }
3384
- /** Toggle force-all-YOLO at runtime. */
3465
+ /** Toggle the destructive YOLO override at runtime. */
3466
+ setYoloDestructive(enabled) {
3467
+ this.yoloDestructive = enabled;
3468
+ }
3469
+ /** Check whether the destructive YOLO override is active. */
3470
+ getYoloDestructive() {
3471
+ return this.yoloDestructive;
3472
+ }
3473
+ /** @deprecated Use `setYoloDestructive`. */
3385
3474
  setForceAllYolo(enabled) {
3386
- this.forceAllYolo = enabled;
3475
+ this.setYoloDestructive(enabled);
3387
3476
  }
3388
- /** Check whether force-all-YOLO is active. */
3477
+ /** @deprecated Use `getYoloDestructive`. */
3389
3478
  getForceAllYolo() {
3390
- return this.forceAllYolo;
3479
+ return this.getYoloDestructive();
3391
3480
  }
3392
3481
  async reload() {
3393
3482
  try {
@@ -3434,7 +3523,8 @@ var DefaultPermissionPolicy = class {
3434
3523
  return { permission: "auto", source: "trust" };
3435
3524
  }
3436
3525
  if (this.yolo) {
3437
- if (tool.riskTier === "destructive" && !this.forceAllYolo) {
3526
+ const destructive = this.isDestructiveYoloCall(tool, input, ctx);
3527
+ if (destructive && !this.yoloDestructive) {
3438
3528
  if (this.promptDelegate) {
3439
3529
  const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
3440
3530
  if (decision === "always") {
@@ -3486,6 +3576,18 @@ var DefaultPermissionPolicy = class {
3486
3576
  }
3487
3577
  return { permission: "confirm", source: "default" };
3488
3578
  }
3579
+ isDestructiveYoloCall(tool, input, ctx) {
3580
+ if (tool.name === "bash") {
3581
+ const command = getInputString(input, "command");
3582
+ return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;
3583
+ }
3584
+ if (tool.name === "write" || tool.name === "edit" || tool.name === "replace" || tool.name === "patch") {
3585
+ const targetPath = getInputString(input, "path") ?? getInputString(input, "file");
3586
+ if (!targetPath || !ctx.projectRoot) return false;
3587
+ return !pathLooksInsideProject(targetPath, ctx.projectRoot);
3588
+ }
3589
+ return tool.riskTier === "destructive";
3590
+ }
3489
3591
  async trust(rule) {
3490
3592
  if (!this.loaded) await this.reload();
3491
3593
  const entry = this.policy[rule.tool] ?? {};
@@ -3803,7 +3905,7 @@ var DefaultRetryPolicy = class {
3803
3905
  };
3804
3906
 
3805
3907
  // src/execution/error-handler.ts
3806
- var CONTEXT_OVERFLOW_RE = /context|too long|tokens/i;
3908
+ var CONTEXT_OVERFLOW_RE = /context|too long|tokens|exceeds the context window|context window/i;
3807
3909
  function buildRecoveryStrategies(opts) {
3808
3910
  return [
3809
3911
  {
@@ -3811,7 +3913,7 @@ function buildRecoveryStrategies(opts) {
3811
3913
  compactor: opts?.compactor,
3812
3914
  async attempt(err, ctx) {
3813
3915
  if (!(err instanceof ProviderError)) return null;
3814
- if (err.status !== 413 && !CONTEXT_OVERFLOW_RE.test(err.message)) return null;
3916
+ if (err.status !== 413 && !isContextOverflowError(err)) return null;
3815
3917
  if (this.compactor) {
3816
3918
  try {
3817
3919
  const report = await this.compactor.compact(ctx, { aggressive: true });
@@ -3845,6 +3947,14 @@ function buildRecoveryStrategies(opts) {
3845
3947
  ];
3846
3948
  }
3847
3949
  var DEFAULT_RECOVERY_STRATEGIES = buildRecoveryStrategies();
3950
+ function isContextOverflowError(err) {
3951
+ return CONTEXT_OVERFLOW_RE.test([
3952
+ err.message,
3953
+ err.body?.message,
3954
+ err.body?.type,
3955
+ err.body?.raw
3956
+ ].filter(Boolean).join("\n"));
3957
+ }
3848
3958
  var DefaultErrorHandler = class {
3849
3959
  strategies;
3850
3960
  constructor(strategies = DEFAULT_RECOVERY_STRATEGIES) {
@@ -3861,7 +3971,7 @@ var DefaultErrorHandler = class {
3861
3971
  if (err.status === 429) return { kind: "rate_limit", retryable: true };
3862
3972
  if (err.status === 529) return { kind: "overloaded", retryable: true };
3863
3973
  if (err.status >= 500) return { kind: "server", retryable: true };
3864
- if (err.status === 413 || CONTEXT_OVERFLOW_RE.test(err.message)) {
3974
+ if (err.status === 413 || isContextOverflowError(err)) {
3865
3975
  return { kind: "context_overflow", retryable: false };
3866
3976
  }
3867
3977
  if (err.status >= 400) return { kind: "client", retryable: false };
@@ -3900,7 +4010,7 @@ var DefaultSkillLoader = class {
3900
4010
  const entries = await fsp.readdir(dir, { withFileTypes: true });
3901
4011
  for (const e of entries) {
3902
4012
  if (!e.isDirectory()) continue;
3903
- const skillFile = path15.join(dir, e.name, "SKILL.md");
4013
+ const skillFile = path16.join(dir, e.name, "SKILL.md");
3904
4014
  try {
3905
4015
  const raw = await fsp.readFile(skillFile, "utf8");
3906
4016
  const meta = parseFrontmatter(raw);
@@ -4312,8 +4422,8 @@ async function streamProviderToResponse(provider, req, signal, ctx, events) {
4312
4422
  try {
4313
4423
  await Promise.race([
4314
4424
  Promise.resolve(iter.return?.()),
4315
- new Promise((resolve4) => {
4316
- drainTimer = setTimeout(resolve4, 500);
4425
+ new Promise((resolve5) => {
4426
+ drainTimer = setTimeout(resolve5, 500);
4317
4427
  })
4318
4428
  ]);
4319
4429
  } finally {
@@ -4374,7 +4484,7 @@ async function runProviderWithRetry(opts) {
4374
4484
  description
4375
4485
  });
4376
4486
  }
4377
- await new Promise((resolve4, reject) => {
4487
+ await new Promise((resolve5, reject) => {
4378
4488
  let settled = false;
4379
4489
  const onAbort = () => {
4380
4490
  if (settled) return;
@@ -4387,7 +4497,7 @@ async function runProviderWithRetry(opts) {
4387
4497
  settled = true;
4388
4498
  clearTimeout(t);
4389
4499
  signal.removeEventListener("abort", onAbort);
4390
- resolve4();
4500
+ resolve5();
4391
4501
  }, delay);
4392
4502
  if (signal.aborted) {
4393
4503
  onAbort();
@@ -5488,11 +5598,11 @@ function validateAgainstSchema(value, schema) {
5488
5598
  walk3(value, schema, "", errors);
5489
5599
  return { ok: errors.length === 0, errors };
5490
5600
  }
5491
- function walk3(value, schema, path18, errors) {
5601
+ function walk3(value, schema, path19, errors) {
5492
5602
  if (schema.enum !== void 0) {
5493
5603
  if (!schema.enum.some((e) => deepEqual(e, value))) {
5494
5604
  errors.push({
5495
- path: path18 || "<root>",
5605
+ path: path19 || "<root>",
5496
5606
  message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
5497
5607
  });
5498
5608
  return;
@@ -5501,7 +5611,7 @@ function walk3(value, schema, path18, errors) {
5501
5611
  if (typeof schema.type === "string") {
5502
5612
  if (!checkType(value, schema.type)) {
5503
5613
  errors.push({
5504
- path: path18 || "<root>",
5614
+ path: path19 || "<root>",
5505
5615
  message: `expected ${schema.type}, got ${describeType(value)}`
5506
5616
  });
5507
5617
  return;
@@ -5511,19 +5621,19 @@ function walk3(value, schema, path18, errors) {
5511
5621
  const obj = value;
5512
5622
  for (const req of schema.required ?? []) {
5513
5623
  if (!(req in obj)) {
5514
- errors.push({ path: joinPath(path18, req), message: "required property missing" });
5624
+ errors.push({ path: joinPath(path19, req), message: "required property missing" });
5515
5625
  }
5516
5626
  }
5517
5627
  if (schema.properties) {
5518
5628
  for (const [key, subSchema] of Object.entries(schema.properties)) {
5519
5629
  if (key in obj) {
5520
- walk3(obj[key], subSchema, joinPath(path18, key), errors);
5630
+ walk3(obj[key], subSchema, joinPath(path19, key), errors);
5521
5631
  }
5522
5632
  }
5523
5633
  }
5524
5634
  }
5525
5635
  if (schema.type === "array" && Array.isArray(value) && schema.items) {
5526
- value.forEach((item, i) => walk3(item, schema.items, `${path18}[${i}]`, errors));
5636
+ value.forEach((item, i) => walk3(item, schema.items, `${path19}[${i}]`, errors));
5527
5637
  }
5528
5638
  }
5529
5639
  function checkType(value, type) {
@@ -5649,8 +5759,9 @@ var ToolExecutor = class {
5649
5759
  */
5650
5760
  async executeBatch(toolUses, ctx, strategy) {
5651
5761
  let budget = this.opts.perIterationOutputCapBytes ?? 1e5;
5652
- const runOne = async (use) => {
5762
+ const runOne = async (use0) => {
5653
5763
  const start = Date.now();
5764
+ let use = use0;
5654
5765
  const tool = this.registry.get(use.name);
5655
5766
  if (!tool) {
5656
5767
  const result = this.unknownToolResult(use, () => this.registry.list().map((t) => t.name));
@@ -5683,10 +5794,36 @@ Please call the tool again with arguments that match its inputSchema. You can us
5683
5794
  budget = this.decrementBudget(result, budget);
5684
5795
  return { result, tool, durationMs: Date.now() - start };
5685
5796
  }
5797
+ if (this.opts.hookRunner?.has("PreToolUse")) {
5798
+ const pre = await this.opts.hookRunner.preToolUse(tool.name, use.input, ctx);
5799
+ if (pre.block) {
5800
+ const result = this.blockedByHookResult(use, pre.reason);
5801
+ budget = this.decrementBudget(result, budget);
5802
+ return { result, tool, durationMs: Date.now() - start };
5803
+ }
5804
+ if (pre.input) {
5805
+ const reval = validateAgainstSchema(pre.input, tool.inputSchema);
5806
+ if (!reval.ok) {
5807
+ const errorDetails = reval.errors.map((e) => ` - ${e.path || "input"}: ${e.message}`).join("\n");
5808
+ const result = {
5809
+ type: "tool_result",
5810
+ tool_use_id: use.id,
5811
+ content: `A PreToolUse hook rewrote the arguments for "${tool.name}" into an invalid shape.
5812
+
5813
+ Validation errors:
5814
+ ${errorDetails}`,
5815
+ is_error: true
5816
+ };
5817
+ budget = this.decrementBudget(result, budget);
5818
+ return { result, tool, durationMs: Date.now() - start };
5819
+ }
5820
+ use = { ...use, input: pre.input };
5821
+ }
5822
+ }
5686
5823
  const decision = await this.opts.permissionPolicy.evaluate(tool, use.input, ctx);
5687
5824
  let effectivePermission = decision.permission;
5688
5825
  const policy = this.opts.permissionPolicy;
5689
- const yolo = policy.getYolo?.() === true || policy.getForceAllYolo?.() === true;
5826
+ const yolo = policy.getYolo?.() === true || policy.getYoloDestructive?.() === true || policy.getForceAllYolo?.() === true;
5690
5827
  if (toolDangerousCaps.length > 0 && effectivePermission === "auto" && !yolo) {
5691
5828
  effectivePermission = "confirm";
5692
5829
  }
@@ -5729,7 +5866,20 @@ Please call the tool again with arguments that match its inputSchema. You can us
5729
5866
  "tool.has_dangerous_capabilities": toolCapsForAudit.length > 0
5730
5867
  });
5731
5868
  try {
5732
- const result = await this.executeTool(tool, use, ctx, budget);
5869
+ let result = await this.executeTool(tool, use, ctx, budget);
5870
+ if (this.opts.hookRunner?.has("PostToolUse")) {
5871
+ const post = await this.opts.hookRunner.postToolUse(
5872
+ tool.name,
5873
+ use.input,
5874
+ { content: String(result.content), isError: !!result.is_error },
5875
+ ctx
5876
+ );
5877
+ if (post.additionalContext) {
5878
+ result = { ...result, content: `${result.content}
5879
+
5880
+ ${post.additionalContext}` };
5881
+ }
5882
+ }
5733
5883
  budget = this.decrementBudget(result, budget);
5734
5884
  span?.setAttribute("tool.is_error", !!result.is_error);
5735
5885
  span?.setAttribute(
@@ -5918,6 +6068,14 @@ ${excerpt}`;
5918
6068
  is_error: true
5919
6069
  };
5920
6070
  }
6071
+ blockedByHookResult(use, reason) {
6072
+ return {
6073
+ type: "tool_result",
6074
+ tool_use_id: use.id,
6075
+ content: `Tool "${use.name}" was blocked by a PreToolUse hook: ${reason ?? "no reason given"}`,
6076
+ is_error: true
6077
+ };
6078
+ }
5921
6079
  decrementBudget(result, budget) {
5922
6080
  const contentBytes = typeof result.content === "string" ? Buffer.byteLength(result.content, "utf8") : Buffer.byteLength(JSON.stringify(result.content), "utf8");
5923
6081
  return Math.max(0, budget - contentBytes);
@@ -6144,8 +6302,8 @@ var AutonomousRunner = class {
6144
6302
  init_atomic_write();
6145
6303
  var MAX_JOURNAL_ENTRIES = 500;
6146
6304
  function goalFilePath(projectRoot) {
6147
- const hash = createHash("sha256").update(path15.resolve(projectRoot)).digest("hex").slice(0, 12);
6148
- return path15.join(os.homedir(), ".wrongstack", "projects", hash, "goal.json");
6305
+ const hash = createHash("sha256").update(path16.resolve(projectRoot)).digest("hex").slice(0, 12);
6306
+ return path16.join(os.homedir(), ".wrongstack", "projects", hash, "goal.json");
6149
6307
  }
6150
6308
  async function loadGoal(filePath) {
6151
6309
  let raw;
@@ -6631,7 +6789,8 @@ ${recentJournal}` : "No prior iterations.",
6631
6789
  " \u2022 When this iteration's Task is finished (real artifact / passing",
6632
6790
  " test / applied diff / clean output), emit `[done]` on its own line.",
6633
6791
  " \u2022 Do not stop on the first obstacle \u2014 try at least 3 distinct",
6634
- " approaches before giving up. YOLO is active; no confirmations.",
6792
+ " approaches before giving up. YOLO is active for normal project work;",
6793
+ " destructive-gated confirmations still belong to the permission flow.",
6635
6794
  "",
6636
6795
  "2. UPDATE TODO STATE (when Source is `todo`)",
6637
6796
  " \u2022 Mark this todo `in_progress` via the todos tool before tool work.",
@@ -6760,7 +6919,7 @@ ${recentJournal}` : "No prior iterations.",
6760
6919
  }
6761
6920
  };
6762
6921
  function sleep(ms) {
6763
- return new Promise((resolve4) => setTimeout(resolve4, ms));
6922
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
6764
6923
  }
6765
6924
 
6766
6925
  // src/coordination/subagent-budget.ts
@@ -6976,12 +7135,12 @@ var SubagentBudget = class _SubagentBudget {
6976
7135
  if (!bus || !bus.hasListenerFor("budget.threshold_reached")) {
6977
7136
  return Promise.resolve("stop");
6978
7137
  }
6979
- return new Promise((resolve4) => {
7138
+ return new Promise((resolve5) => {
6980
7139
  let resolved = false;
6981
7140
  const respond = (d) => {
6982
7141
  if (resolved) return;
6983
7142
  resolved = true;
6984
- resolve4(d);
7143
+ resolve5(d);
6985
7144
  };
6986
7145
  const fallback = setTimeout(
6987
7146
  () => respond("stop"),
@@ -10208,7 +10367,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
10208
10367
  taskIds.map((id) => {
10209
10368
  const cached = this.completedResults.find((r) => r.taskId === id);
10210
10369
  if (cached) return cached;
10211
- return new Promise((resolve4, reject) => {
10370
+ return new Promise((resolve5, reject) => {
10212
10371
  const timeout = setTimeout(() => {
10213
10372
  this.off("task.completed", handler);
10214
10373
  reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
@@ -10217,7 +10376,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
10217
10376
  if (result.taskId === id) {
10218
10377
  clearTimeout(timeout);
10219
10378
  this.off("task.completed", handler);
10220
- resolve4(result);
10379
+ resolve5(result);
10221
10380
  }
10222
10381
  };
10223
10382
  this.on("task.completed", handler);
@@ -10720,7 +10879,7 @@ function providerErrorToSubagentError(err, message, cause) {
10720
10879
 
10721
10880
  // src/execution/parallel-eternal-engine.ts
10722
10881
  function sleep2(ms) {
10723
- return new Promise((resolve4) => setTimeout(resolve4, ms));
10882
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
10724
10883
  }
10725
10884
  var GOAL_COMPLETE_MARKER2 = /^\s*\[goal[_\s-]?complete\]\s*$/im;
10726
10885
  var ParallelEternalEngine = class {
@@ -10899,7 +11058,8 @@ ${recentJournal}` : "No prior iterations.",
10899
11058
  "\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
10900
11059
  "\u2022 Execute the assigned task end-to-end using multiple tool calls.",
10901
11060
  "\u2022 Emit `[done]` on its own line when the task is complete.",
10902
- "\u2022 Do not ask for confirmation \u2014 YOLO is active.",
11061
+ "\u2022 Do not ask before routine in-project tool use \u2014 YOLO is active for normal project work.",
11062
+ "\u2022 If a destructive-gated confirmation appears, wait for the permission flow.",
10903
11063
  "\u2022 If the overall Mission is accomplished, emit `[GOAL_COMPLETE]` followed by a verification recipe.",
10904
11064
  "\u2022 Keep output concise \u2014 summarize findings, do not transcribe files."
10905
11065
  ].join("\n");
@@ -11156,8 +11316,10 @@ ${journalTail.join("\n")}` : "Recent journal: (none \u2014 this is the first ite
11156
11316
  " decide.",
11157
11317
  "",
11158
11318
  "### Operating principles",
11159
- "- YOLO is active. Do NOT ask for confirmation, do NOT propose",
11160
- " options. Pick the best path and execute it.",
11319
+ "- YOLO is active for normal project work. Proceed with routine",
11320
+ " in-project tool use without pre-confirming; pick the best path and execute it.",
11321
+ " If the permission system raises a destructive-gated confirmation, wait",
11322
+ " for that flow instead of trying to bypass it.",
11161
11323
  "- Use tools freely; multiple calls per turn are normal and expected.",
11162
11324
  "- When working on a todo, mark it `in_progress` via the todos tool",
11163
11325
  " before tool work and `completed` (or `cancelled` with a reason)",
@@ -11346,7 +11508,7 @@ var InMemoryAgentBridge = class {
11346
11508
  );
11347
11509
  }
11348
11510
  this.inflightGuards.add(correlationId);
11349
- return new Promise((resolve4, reject) => {
11511
+ return new Promise((resolve5, reject) => {
11350
11512
  const timer = setTimeout(() => {
11351
11513
  this.inflightGuards.delete(correlationId);
11352
11514
  this.pendingRequests.delete(correlationId);
@@ -11358,7 +11520,7 @@ var InMemoryAgentBridge = class {
11358
11520
  return;
11359
11521
  }
11360
11522
  this.pendingRequests.set(correlationId, {
11361
- resolve: resolve4,
11523
+ resolve: resolve5,
11362
11524
  reject,
11363
11525
  timer
11364
11526
  });
@@ -13658,7 +13820,7 @@ var Director = class _Director {
13658
13820
  })),
13659
13821
  usage: this.usage.snapshot()
13660
13822
  };
13661
- await fsp.mkdir(path15.dirname(this.manifestPath), { recursive: true });
13823
+ await fsp.mkdir(path16.dirname(this.manifestPath), { recursive: true });
13662
13824
  await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
13663
13825
  return this.manifestPath;
13664
13826
  }
@@ -13777,11 +13939,11 @@ var Director = class _Director {
13777
13939
  if (cached) return cached;
13778
13940
  const existing = this.taskWaiters.get(id);
13779
13941
  if (existing) return existing.promise;
13780
- let resolve4;
13942
+ let resolve5;
13781
13943
  const promise = new Promise((res) => {
13782
- resolve4 = res;
13944
+ resolve5 = res;
13783
13945
  });
13784
- this.taskWaiters.set(id, { promise, resolve: resolve4 });
13946
+ this.taskWaiters.set(id, { promise, resolve: resolve5 });
13785
13947
  return promise;
13786
13948
  })
13787
13949
  );
@@ -13864,7 +14026,7 @@ var Director = class _Director {
13864
14026
  */
13865
14027
  async readSession(subagentId, tail) {
13866
14028
  if (!this.sessionsRoot) return null;
13867
- const filePath = path15.join(this.sessionsRoot, this.directorRunId, `${subagentId}.jsonl`);
14029
+ const filePath = path16.join(this.sessionsRoot, this.directorRunId, `${subagentId}.jsonl`);
13868
14030
  let raw;
13869
14031
  try {
13870
14032
  raw = await fsp.readFile(filePath, "utf8");
@@ -14166,7 +14328,7 @@ function createDelegateTool(opts) {
14166
14328
  subagentId
14167
14329
  });
14168
14330
  const dir = director;
14169
- const result = await new Promise((resolve4) => {
14331
+ const result = await new Promise((resolve5) => {
14170
14332
  let settled = false;
14171
14333
  let timer;
14172
14334
  const finish = (value) => {
@@ -14176,7 +14338,7 @@ function createDelegateTool(opts) {
14176
14338
  offTool();
14177
14339
  offIter();
14178
14340
  offProgress();
14179
- resolve4(value);
14341
+ resolve5(value);
14180
14342
  };
14181
14343
  const arm = () => {
14182
14344
  if (timer) clearTimeout(timer);
@@ -14320,13 +14482,13 @@ async function readSubagentPartial(opts, subagentId) {
14320
14482
  if (!opts.sessionsRoot) return void 0;
14321
14483
  const candidates = [];
14322
14484
  if (opts.directorRunId) {
14323
- candidates.push(path15.join(opts.sessionsRoot, opts.directorRunId, `${subagentId}.jsonl`));
14485
+ candidates.push(path16.join(opts.sessionsRoot, opts.directorRunId, `${subagentId}.jsonl`));
14324
14486
  } else {
14325
14487
  try {
14326
14488
  const entries = await fsp.readdir(opts.sessionsRoot, { withFileTypes: true });
14327
14489
  for (const entry of entries) {
14328
14490
  if (entry.isDirectory()) {
14329
- candidates.push(path15.join(opts.sessionsRoot, entry.name, `${subagentId}.jsonl`));
14491
+ candidates.push(path16.join(opts.sessionsRoot, entry.name, `${subagentId}.jsonl`));
14330
14492
  }
14331
14493
  }
14332
14494
  } catch {
@@ -14373,9 +14535,9 @@ function makeDirectorSessionFactory(opts) {
14373
14535
  let dir;
14374
14536
  if (opts.store) {
14375
14537
  store = opts.store;
14376
- dir = opts.sessionsRoot ? path15.join(opts.sessionsRoot, runId) : "(caller-managed)";
14538
+ dir = opts.sessionsRoot ? path16.join(opts.sessionsRoot, runId) : "(caller-managed)";
14377
14539
  } else if (opts.sessionsRoot) {
14378
- dir = path15.join(opts.sessionsRoot, runId);
14540
+ dir = path16.join(opts.sessionsRoot, runId);
14379
14541
  store = new DefaultSessionStore({ dir });
14380
14542
  } else {
14381
14543
  throw new Error("makeDirectorSessionFactory requires either `store` or `sessionsRoot`");
@@ -14579,7 +14741,7 @@ var DefaultModelsRegistry = class {
14579
14741
  this.overlay = opts.overlay;
14580
14742
  this.overlayUrl = opts.overlayUrl;
14581
14743
  this.overlayFile = opts.overlayFile;
14582
- this.overlayCacheFile = opts.overlayCacheFile ?? (opts.overlayUrl ? path15.join(path15.dirname(opts.cacheFile), "models-overlay-cache.json") : void 0);
14744
+ this.overlayCacheFile = opts.overlayCacheFile ?? (opts.overlayUrl ? path16.join(path16.dirname(opts.cacheFile), "models-overlay-cache.json") : void 0);
14583
14745
  }
14584
14746
  async load(opts = {}) {
14585
14747
  if (this.payload && !opts.force) return this.payload;
@@ -14792,7 +14954,7 @@ var DefaultModelsRegistry = class {
14792
14954
  }
14793
14955
  /** Used by `wstack models refresh` to expose where the cache lives. */
14794
14956
  cacheLocation() {
14795
- return path15.resolve(this.cacheFile);
14957
+ return path16.resolve(this.cacheFile);
14796
14958
  }
14797
14959
  };
14798
14960
  function hasEntries(payload) {
@@ -15079,7 +15241,7 @@ var DefaultModeStore = class {
15079
15241
  }
15080
15242
  async loadActiveMode() {
15081
15243
  try {
15082
- const configPath = path15.join(this.configDir, "mode.json");
15244
+ const configPath = path16.join(this.configDir, "mode.json");
15083
15245
  const content = await fsp.readFile(configPath, "utf8");
15084
15246
  const data = JSON.parse(content);
15085
15247
  this.activeModeId = data.activeMode ?? null;
@@ -15090,7 +15252,7 @@ var DefaultModeStore = class {
15090
15252
  async saveActiveMode() {
15091
15253
  try {
15092
15254
  await fsp.mkdir(this.configDir, { recursive: true });
15093
- const configPath = path15.join(this.configDir, "mode.json");
15255
+ const configPath = path16.join(this.configDir, "mode.json");
15094
15256
  await atomicWrite(
15095
15257
  configPath,
15096
15258
  JSON.stringify({ activeMode: this.activeModeId }, null, 2)
@@ -15105,11 +15267,11 @@ async function loadProjectModes(modesDir) {
15105
15267
  const entries = await fsp.readdir(modesDir);
15106
15268
  for (const entry of entries) {
15107
15269
  if (!entry.endsWith(".md") && !entry.endsWith(".txt")) continue;
15108
- const filePath = path15.join(modesDir, entry);
15270
+ const filePath = path16.join(modesDir, entry);
15109
15271
  const stat5 = await fsp.stat(filePath);
15110
15272
  if (!stat5.isFile()) continue;
15111
15273
  const content = await fsp.readFile(filePath, "utf8");
15112
- const id = path15.basename(entry, path15.extname(entry));
15274
+ const id = path16.basename(entry, path16.extname(entry));
15113
15275
  modes.push({
15114
15276
  id,
15115
15277
  name: id.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
@@ -15125,7 +15287,7 @@ async function loadProjectModes(modesDir) {
15125
15287
  async function loadUserModes(modesDir) {
15126
15288
  const modes = [];
15127
15289
  try {
15128
- const manifestPath = path15.join(modesDir, "modes.json");
15290
+ const manifestPath = path16.join(modesDir, "modes.json");
15129
15291
  const content = await fsp.readFile(manifestPath, "utf8");
15130
15292
  const manifest = JSON.parse(content);
15131
15293
  for (const mode of manifest.modes) {
@@ -16042,7 +16204,7 @@ var SpecStore = class {
16042
16204
  indexPath;
16043
16205
  constructor(opts) {
16044
16206
  this.baseDir = opts.baseDir;
16045
- this.indexPath = path15.join(this.baseDir, "_index.json");
16207
+ this.indexPath = path16.join(this.baseDir, "_index.json");
16046
16208
  }
16047
16209
  async save(spec) {
16048
16210
  await ensureDir(this.baseDir);
@@ -16111,7 +16273,7 @@ var SpecStore = class {
16111
16273
  return updated;
16112
16274
  }
16113
16275
  filePath(id) {
16114
- return path15.join(this.baseDir, `${id}.json`);
16276
+ return path16.join(this.baseDir, `${id}.json`);
16115
16277
  }
16116
16278
  async readIndex() {
16117
16279
  try {
@@ -16168,7 +16330,7 @@ var TaskGraphStore = class {
16168
16330
  indexPath;
16169
16331
  constructor(opts) {
16170
16332
  this.baseDir = opts.baseDir;
16171
- this.indexPath = path15.join(this.baseDir, "_index.json");
16333
+ this.indexPath = path16.join(this.baseDir, "_index.json");
16172
16334
  }
16173
16335
  async save(graph) {
16174
16336
  await ensureDir(this.baseDir);
@@ -16206,7 +16368,7 @@ var TaskGraphStore = class {
16206
16368
  }
16207
16369
  }
16208
16370
  filePath(id) {
16209
- return path15.join(this.baseDir, `${id}.json`);
16371
+ return path16.join(this.baseDir, `${id}.json`);
16210
16372
  }
16211
16373
  async readIndex() {
16212
16374
  try {
@@ -16451,9 +16613,9 @@ var AISpecBuilder = class {
16451
16613
  if (!this.sessionPath) return;
16452
16614
  try {
16453
16615
  const fsp16 = await import('fs/promises');
16454
- const path18 = await import('path');
16616
+ const path19 = await import('path');
16455
16617
  const { atomicWrite: atomicWrite2 } = await Promise.resolve().then(() => (init_atomic_write(), atomic_write_exports));
16456
- await fsp16.mkdir(path18.dirname(this.sessionPath), { recursive: true });
16618
+ await fsp16.mkdir(path19.dirname(this.sessionPath), { recursive: true });
16457
16619
  await atomicWrite2(this.sessionPath, JSON.stringify(this.session, null, 2));
16458
16620
  } catch {
16459
16621
  }
@@ -17163,15 +17325,15 @@ function computeCriticalPath(graph, _topoOrder, blockedByMap) {
17163
17325
  maxId = id;
17164
17326
  }
17165
17327
  }
17166
- const path18 = [];
17328
+ const path19 = [];
17167
17329
  let current = maxId;
17168
17330
  const visited = /* @__PURE__ */ new Set();
17169
17331
  while (current && !visited.has(current)) {
17170
17332
  visited.add(current);
17171
- path18.unshift(current);
17333
+ path19.unshift(current);
17172
17334
  current = prev.get(current) ?? null;
17173
17335
  }
17174
- return path18;
17336
+ return path19;
17175
17337
  }
17176
17338
  function computeParallelGroups(graph, blockedByMap) {
17177
17339
  const groups = [];
@@ -17721,7 +17883,7 @@ var SddParallelRun = class {
17721
17883
  "\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
17722
17884
  "\u2022 Execute the assigned SDD task end-to-end using multiple tool calls.",
17723
17885
  "\u2022 Mark the task [done] in the tracker when complete.",
17724
- "\u2022 Do not ask for confirmation.",
17886
+ "\u2022 Do not ask before routine in-project tool use; if a permission gate appears, wait for that flow.",
17725
17887
  "\u2022 Keep output concise \u2014 summarize changes, do not transcribe files."
17726
17888
  ].join("\n");
17727
17889
  const spawns = subagentIds.map(
@@ -17964,9 +18126,9 @@ var DefaultHealthRegistry = class {
17964
18126
  }
17965
18127
  async runOne(check) {
17966
18128
  let timer = null;
17967
- const timeout = new Promise((resolve4) => {
18129
+ const timeout = new Promise((resolve5) => {
17968
18130
  timer = setTimeout(
17969
- () => resolve4({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
18131
+ () => resolve5({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
17970
18132
  this.timeoutMs
17971
18133
  );
17972
18134
  });
@@ -18149,7 +18311,7 @@ async function startMetricsServer(opts) {
18149
18311
  const tls = opts.tls;
18150
18312
  const useHttps = !!(tls?.cert && tls?.key);
18151
18313
  const host = opts.host ?? "127.0.0.1";
18152
- const path18 = opts.path ?? "/metrics";
18314
+ const path19 = opts.path ?? "/metrics";
18153
18315
  const healthPath = opts.healthPath ?? "/healthz";
18154
18316
  const healthRegistry = opts.healthRegistry;
18155
18317
  const listener = (req, res) => {
@@ -18159,7 +18321,7 @@ async function startMetricsServer(opts) {
18159
18321
  return;
18160
18322
  }
18161
18323
  const url = req.url.split("?")[0];
18162
- if (url === path18) {
18324
+ if (url === path19) {
18163
18325
  let body;
18164
18326
  try {
18165
18327
  body = renderPrometheus(opts.sink.snapshot());
@@ -18205,14 +18367,14 @@ async function startMetricsServer(opts) {
18205
18367
  const { createServer } = await import('http');
18206
18368
  server = createServer(listener);
18207
18369
  }
18208
- await new Promise((resolve4, reject) => {
18370
+ await new Promise((resolve5, reject) => {
18209
18371
  const onError = (err) => {
18210
18372
  server.off("listening", onListening);
18211
18373
  reject(err);
18212
18374
  };
18213
18375
  const onListening = () => {
18214
18376
  server.off("error", onError);
18215
- resolve4();
18377
+ resolve5();
18216
18378
  };
18217
18379
  server.once("error", onError);
18218
18380
  server.once("listening", onListening);
@@ -18223,9 +18385,9 @@ async function startMetricsServer(opts) {
18223
18385
  const protocol = useHttps ? "https" : "http";
18224
18386
  return {
18225
18387
  port: boundPort,
18226
- url: `${protocol}://${host}:${boundPort}${path18}`,
18227
- close: () => new Promise((resolve4, reject) => {
18228
- server.close((err) => err ? reject(err) : resolve4());
18388
+ url: `${protocol}://${host}:${boundPort}${path19}`,
18389
+ close: () => new Promise((resolve5, reject) => {
18390
+ server.close((err) => err ? reject(err) : resolve5());
18229
18391
  })
18230
18392
  };
18231
18393
  }
@@ -18774,7 +18936,7 @@ var context7Server = () => ({
18774
18936
  name: "context7",
18775
18937
  description: "Codebase-aware documentation and Q&A (context7.ai)",
18776
18938
  transport: "streamable-http",
18777
- url: "https://server.context7.ai/mcp",
18939
+ url: "https://mcp.context7.com/mcp",
18778
18940
  permission: "confirm"
18779
18941
  });
18780
18942
  var braveSearchServer = () => ({