@wrongstack/core 0.51.3 → 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 (62) hide show
  1. package/dist/{agent-bridge-CjbD-i7-.d.ts → agent-bridge-B5rxWrg3.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-DfvlBx5N.d.ts → agent-subagent-runner-Zc3f37Sg.d.ts} +3 -3
  3. package/dist/{compactor-D1RHFRmF.d.ts → compactor-0vjZ8KTk.d.ts} +1 -1
  4. package/dist/{config-ZRCf7sTu.d.ts → config-BdDuaZmB.d.ts} +143 -2
  5. package/dist/{context-7u93AcGD.d.ts → context-iFMEO2rN.d.ts} +9 -8
  6. package/dist/coordination/index.d.ts +12 -12
  7. package/dist/coordination/index.js.map +1 -1
  8. package/dist/defaults/index.d.ts +22 -22
  9. package/dist/defaults/index.js +285 -108
  10. package/dist/defaults/index.js.map +1 -1
  11. package/dist/{events-Bt44ikPN.d.ts → events-k8CHjcrN.d.ts} +20 -1
  12. package/dist/execution/index.d.ts +14 -14
  13. package/dist/execution/index.js +70 -10
  14. package/dist/execution/index.js.map +1 -1
  15. package/dist/extension/index.d.ts +7 -7
  16. package/dist/{goal-store-BeRsj7YX.d.ts → goal-store-iHltMi5n.d.ts} +1 -1
  17. package/dist/{index-mAWBdLyJ.d.ts → index-Bc6BiP5q.d.ts} +77 -6
  18. package/dist/{index-OzA1XjHL.d.ts → index-CWdW_CJt.d.ts} +10 -8
  19. package/dist/index.d.ts +58 -34
  20. package/dist/index.js +587 -100
  21. package/dist/index.js.map +1 -1
  22. package/dist/infrastructure/index.d.ts +6 -6
  23. package/dist/infrastructure/index.js +1 -1
  24. package/dist/infrastructure/index.js.map +1 -1
  25. package/dist/kernel/index.d.ts +9 -9
  26. package/dist/kernel/index.js +3 -1
  27. package/dist/kernel/index.js.map +1 -1
  28. package/dist/{mcp-servers-DONdo-XM.d.ts → mcp-servers-CwqQDMYy.d.ts} +3 -3
  29. package/dist/models/index.d.ts +3 -3
  30. package/dist/models/index.js +31 -16
  31. package/dist/models/index.js.map +1 -1
  32. package/dist/{models-registry-gwMAo6E3.d.ts → models-registry-Cuq1C8V9.d.ts} +7 -0
  33. package/dist/{multi-agent-Ba9Ni2hC.d.ts → multi-agent-SASYOrWA.d.ts} +2 -2
  34. package/dist/{multi-agent-coordinator-BuKq0q89.d.ts → multi-agent-coordinator-CNUJYq7U.d.ts} +2 -2
  35. package/dist/{null-fleet-bus-C0xd73YP.d.ts → null-fleet-bus-DRoJ0uOY.d.ts} +7 -7
  36. package/dist/observability/index.d.ts +2 -2
  37. package/dist/{path-resolver-nkmdiFgi.d.ts → path-resolver-C5sPVne8.d.ts} +2 -2
  38. package/dist/{permission-B6sldrSp.d.ts → permission-Ld-i5ugf.d.ts} +13 -1
  39. package/dist/{permission-policy-CtNscWOA.d.ts → permission-policy-CL-mPufp.d.ts} +14 -7
  40. package/dist/{plan-templates-BmDdJ7UL.d.ts → plan-templates-ThBHOjaM.d.ts} +4 -4
  41. package/dist/{provider-runner-BGro2qQB.d.ts → provider-runner-DJQa211J.d.ts} +3 -3
  42. package/dist/{retry-policy-KF18W4dg.d.ts → retry-policy-BfBScewS.d.ts} +1 -1
  43. package/dist/sdd/index.d.ts +9 -9
  44. package/dist/sdd/index.js +1 -1
  45. package/dist/sdd/index.js.map +1 -1
  46. package/dist/security/index.d.ts +3 -3
  47. package/dist/security/index.js +115 -13
  48. package/dist/security/index.js.map +1 -1
  49. package/dist/{selector-DmXxpFyM.d.ts → selector-DxhW7ML3.d.ts} +1 -1
  50. package/dist/{session-reader-bfgsy2a0.d.ts → session-reader-q2ThszgG.d.ts} +1 -1
  51. package/dist/storage/index.d.ts +6 -6
  52. package/dist/storage/index.js +57 -37
  53. package/dist/storage/index.js.map +1 -1
  54. package/dist/{system-prompt-CM6zOhd2.d.ts → system-prompt-7LHyBbIf.d.ts} +32 -2
  55. package/dist/{tool-executor-p4tP9tGF.d.ts → tool-executor-CIjpGaRA.d.ts} +5 -4
  56. package/dist/types/index.d.ts +15 -15
  57. package/dist/types/index.js +93 -22
  58. package/dist/types/index.js.map +1 -1
  59. package/dist/utils/index.d.ts +14 -2
  60. package/dist/utils/index.js +18 -1
  61. package/dist/utils/index.js.map +1 -1
  62. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -93,7 +93,7 @@ async function renameWithRetry(from, to) {
93
93
  if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
94
94
  throw err;
95
95
  }
96
- await new Promise((resolve11) => setTimeout(resolve11, delays[i]));
96
+ await new Promise((resolve13) => setTimeout(resolve13, delays[i]));
97
97
  }
98
98
  }
99
99
  throw lastErr;
@@ -884,7 +884,9 @@ var TOKENS = {
884
884
  /** Optional git-worktree lifecycle manager (per-phase isolation in AutoPhase). */
885
885
  WorktreeManager: t("WorktreeManager"),
886
886
  /** Optional global Brain arbiter for policy/decision escalation. */
887
- BrainArbiter: t("BrainArbiter")
887
+ BrainArbiter: t("BrainArbiter"),
888
+ /** Lifecycle hook registry (shell + in-process hooks). */
889
+ HookRegistry: t("HookRegistry")
888
890
  };
889
891
 
890
892
  // src/kernel/run-controller.ts
@@ -2058,7 +2060,7 @@ var DefaultPathResolver = class {
2058
2060
  var NETWORK_ERR_RE = /ECONN|ETIMEDOUT|ETIME|ENOTFOUND|EAI_AGAIN|fetch failed/i;
2059
2061
 
2060
2062
  // src/execution/error-handler.ts
2061
- var CONTEXT_OVERFLOW_RE = /context|too long|tokens/i;
2063
+ var CONTEXT_OVERFLOW_RE = /context|too long|tokens|exceeds the context window|context window/i;
2062
2064
  function buildRecoveryStrategies(opts) {
2063
2065
  return [
2064
2066
  {
@@ -2066,7 +2068,7 @@ function buildRecoveryStrategies(opts) {
2066
2068
  compactor: opts?.compactor,
2067
2069
  async attempt(err, ctx) {
2068
2070
  if (!(err instanceof ProviderError)) return null;
2069
- if (err.status !== 413 && !CONTEXT_OVERFLOW_RE.test(err.message)) return null;
2071
+ if (err.status !== 413 && !isContextOverflowError(err)) return null;
2070
2072
  if (this.compactor) {
2071
2073
  try {
2072
2074
  const report = await this.compactor.compact(ctx, { aggressive: true });
@@ -2129,6 +2131,14 @@ function buildRecoveryStrategies(opts) {
2129
2131
  ];
2130
2132
  }
2131
2133
  var DEFAULT_RECOVERY_STRATEGIES = buildRecoveryStrategies();
2134
+ function isContextOverflowError(err) {
2135
+ return CONTEXT_OVERFLOW_RE.test([
2136
+ err.message,
2137
+ err.body?.message,
2138
+ err.body?.type,
2139
+ err.body?.raw
2140
+ ].filter(Boolean).join("\n"));
2141
+ }
2132
2142
  var DefaultErrorHandler = class {
2133
2143
  strategies;
2134
2144
  constructor(strategies = DEFAULT_RECOVERY_STRATEGIES) {
@@ -2145,7 +2155,7 @@ var DefaultErrorHandler = class {
2145
2155
  if (err.status === 429) return { kind: "rate_limit", retryable: true };
2146
2156
  if (err.status === 529) return { kind: "overloaded", retryable: true };
2147
2157
  if (err.status >= 500) return { kind: "server", retryable: true };
2148
- if (err.status === 413 || CONTEXT_OVERFLOW_RE.test(err.message)) {
2158
+ if (err.status === 413 || isContextOverflowError(err)) {
2149
2159
  return { kind: "context_overflow", retryable: false };
2150
2160
  }
2151
2161
  if (err.status >= 400) return { kind: "client", retryable: false };
@@ -2369,6 +2379,7 @@ function stripUndefined(obj) {
2369
2379
  // src/models/models-registry.ts
2370
2380
  var DEFAULT_URL = "https://models.dev/api.json";
2371
2381
  var DEFAULT_TTL_SECONDS = 24 * 3600;
2382
+ var DEFAULT_REFRESH_TIMEOUT_MS = 15e3;
2372
2383
  var FAMILY_BY_NPM = {
2373
2384
  "@ai-sdk/anthropic": "anthropic",
2374
2385
  "@ai-sdk/google-vertex/anthropic": "anthropic",
@@ -2405,6 +2416,7 @@ var DefaultModelsRegistry = class {
2405
2416
  fetchImpl;
2406
2417
  seed;
2407
2418
  maxStaleAgeMs;
2419
+ refreshTimeoutMs;
2408
2420
  overlay;
2409
2421
  overlayUrl;
2410
2422
  overlayFile;
@@ -2417,6 +2429,7 @@ var DefaultModelsRegistry = class {
2417
2429
  this.seed = opts.seed;
2418
2430
  const maxStaleSeconds = opts.maxStaleAgeSeconds ?? 7 * 24 * 3600;
2419
2431
  this.maxStaleAgeMs = maxStaleSeconds * 1e3;
2432
+ this.refreshTimeoutMs = opts.refreshTimeoutMs ?? DEFAULT_REFRESH_TIMEOUT_MS;
2420
2433
  this.overlay = opts.overlay;
2421
2434
  this.overlayUrl = opts.overlayUrl;
2422
2435
  this.overlayFile = opts.overlayFile;
@@ -2468,22 +2481,34 @@ var DefaultModelsRegistry = class {
2468
2481
  }
2469
2482
  /** Fetch + cache the models.dev base. Throws on failure (used by `refresh`). */
2470
2483
  async refreshBase() {
2471
- const res = await this.fetchImpl(this.url, {
2472
- method: "GET",
2473
- headers: { accept: "application/json" }
2474
- });
2475
- if (!res.ok) {
2476
- throw new Error(`ModelsRegistry: HTTP ${res.status} fetching ${this.url}`);
2477
- }
2478
- const json = await res.json();
2479
- this.fetchedAt = /* @__PURE__ */ new Date();
2480
- const envelope = {
2481
- fetchedAt: this.fetchedAt.toISOString(),
2482
- url: this.url,
2483
- payload: json
2484
- };
2485
- await atomicWrite(this.cacheFile, JSON.stringify(envelope));
2486
- return json;
2484
+ const controller = new AbortController();
2485
+ const timeout = setTimeout(() => controller.abort(), this.refreshTimeoutMs);
2486
+ try {
2487
+ const res = await this.fetchImpl(this.url, {
2488
+ method: "GET",
2489
+ headers: { accept: "application/json" },
2490
+ signal: controller.signal
2491
+ });
2492
+ clearTimeout(timeout);
2493
+ if (!res.ok) {
2494
+ throw new Error(`ModelsRegistry: HTTP ${res.status} fetching ${this.url}`);
2495
+ }
2496
+ const json = await res.json();
2497
+ this.fetchedAt = /* @__PURE__ */ new Date();
2498
+ const envelope = {
2499
+ fetchedAt: this.fetchedAt.toISOString(),
2500
+ url: this.url,
2501
+ payload: json
2502
+ };
2503
+ await atomicWrite(this.cacheFile, JSON.stringify(envelope));
2504
+ return json;
2505
+ } catch (err) {
2506
+ clearTimeout(timeout);
2507
+ if (err instanceof Error && err.name === "AbortError") {
2508
+ throw new Error(`ModelsRegistry: fetch timed out after ${this.refreshTimeoutMs}ms`);
2509
+ }
2510
+ throw err;
2511
+ }
2487
2512
  }
2488
2513
  /**
2489
2514
  * Resolve the curated overlay, memoised. Order: in-memory `overlay` →
@@ -3034,7 +3059,7 @@ var InMemoryAgentBridge = class {
3034
3059
  );
3035
3060
  }
3036
3061
  this.inflightGuards.add(correlationId);
3037
- return new Promise((resolve11, reject) => {
3062
+ return new Promise((resolve13, reject) => {
3038
3063
  const timer = setTimeout(() => {
3039
3064
  this.inflightGuards.delete(correlationId);
3040
3065
  this.pendingRequests.delete(correlationId);
@@ -3046,7 +3071,7 @@ var InMemoryAgentBridge = class {
3046
3071
  return;
3047
3072
  }
3048
3073
  this.pendingRequests.set(correlationId, {
3049
- resolve: resolve11,
3074
+ resolve: resolve13,
3050
3075
  reject,
3051
3076
  timer
3052
3077
  });
@@ -3239,11 +3264,11 @@ function validateAgainstSchema(value, schema) {
3239
3264
  walk2(value, schema, "", errors);
3240
3265
  return { ok: errors.length === 0, errors };
3241
3266
  }
3242
- function walk2(value, schema, path36, errors) {
3267
+ function walk2(value, schema, path37, errors) {
3243
3268
  if (schema.enum !== void 0) {
3244
3269
  if (!schema.enum.some((e) => deepEqual(e, value))) {
3245
3270
  errors.push({
3246
- path: path36 || "<root>",
3271
+ path: path37 || "<root>",
3247
3272
  message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
3248
3273
  });
3249
3274
  return;
@@ -3252,7 +3277,7 @@ function walk2(value, schema, path36, errors) {
3252
3277
  if (typeof schema.type === "string") {
3253
3278
  if (!checkType(value, schema.type)) {
3254
3279
  errors.push({
3255
- path: path36 || "<root>",
3280
+ path: path37 || "<root>",
3256
3281
  message: `expected ${schema.type}, got ${describeType(value)}`
3257
3282
  });
3258
3283
  return;
@@ -3262,19 +3287,19 @@ function walk2(value, schema, path36, errors) {
3262
3287
  const obj = value;
3263
3288
  for (const req of schema.required ?? []) {
3264
3289
  if (!(req in obj)) {
3265
- errors.push({ path: joinPath(path36, req), message: "required property missing" });
3290
+ errors.push({ path: joinPath(path37, req), message: "required property missing" });
3266
3291
  }
3267
3292
  }
3268
3293
  if (schema.properties) {
3269
3294
  for (const [key, subSchema] of Object.entries(schema.properties)) {
3270
3295
  if (key in obj) {
3271
- walk2(obj[key], subSchema, joinPath(path36, key), errors);
3296
+ walk2(obj[key], subSchema, joinPath(path37, key), errors);
3272
3297
  }
3273
3298
  }
3274
3299
  }
3275
3300
  }
3276
3301
  if (schema.type === "array" && Array.isArray(value) && schema.items) {
3277
- value.forEach((item, i) => walk2(item, schema.items, `${path36}[${i}]`, errors));
3302
+ value.forEach((item, i) => walk2(item, schema.items, `${path37}[${i}]`, errors));
3278
3303
  }
3279
3304
  }
3280
3305
  function checkType(value, type) {
@@ -3400,8 +3425,9 @@ var ToolExecutor = class {
3400
3425
  */
3401
3426
  async executeBatch(toolUses, ctx, strategy) {
3402
3427
  let budget = this.opts.perIterationOutputCapBytes ?? 1e5;
3403
- const runOne = async (use) => {
3428
+ const runOne = async (use0) => {
3404
3429
  const start = Date.now();
3430
+ let use = use0;
3405
3431
  const tool = this.registry.get(use.name);
3406
3432
  if (!tool) {
3407
3433
  const result = this.unknownToolResult(use, () => this.registry.list().map((t2) => t2.name));
@@ -3434,10 +3460,36 @@ Please call the tool again with arguments that match its inputSchema. You can us
3434
3460
  budget = this.decrementBudget(result, budget);
3435
3461
  return { result, tool, durationMs: Date.now() - start };
3436
3462
  }
3463
+ if (this.opts.hookRunner?.has("PreToolUse")) {
3464
+ const pre = await this.opts.hookRunner.preToolUse(tool.name, use.input, ctx);
3465
+ if (pre.block) {
3466
+ const result = this.blockedByHookResult(use, pre.reason);
3467
+ budget = this.decrementBudget(result, budget);
3468
+ return { result, tool, durationMs: Date.now() - start };
3469
+ }
3470
+ if (pre.input) {
3471
+ const reval = validateAgainstSchema(pre.input, tool.inputSchema);
3472
+ if (!reval.ok) {
3473
+ const errorDetails = reval.errors.map((e) => ` - ${e.path || "input"}: ${e.message}`).join("\n");
3474
+ const result = {
3475
+ type: "tool_result",
3476
+ tool_use_id: use.id,
3477
+ content: `A PreToolUse hook rewrote the arguments for "${tool.name}" into an invalid shape.
3478
+
3479
+ Validation errors:
3480
+ ${errorDetails}`,
3481
+ is_error: true
3482
+ };
3483
+ budget = this.decrementBudget(result, budget);
3484
+ return { result, tool, durationMs: Date.now() - start };
3485
+ }
3486
+ use = { ...use, input: pre.input };
3487
+ }
3488
+ }
3437
3489
  const decision = await this.opts.permissionPolicy.evaluate(tool, use.input, ctx);
3438
3490
  let effectivePermission = decision.permission;
3439
3491
  const policy = this.opts.permissionPolicy;
3440
- const yolo = policy.getYolo?.() === true || policy.getForceAllYolo?.() === true;
3492
+ const yolo = policy.getYolo?.() === true || policy.getYoloDestructive?.() === true || policy.getForceAllYolo?.() === true;
3441
3493
  if (toolDangerousCaps.length > 0 && effectivePermission === "auto" && !yolo) {
3442
3494
  effectivePermission = "confirm";
3443
3495
  }
@@ -3480,7 +3532,20 @@ Please call the tool again with arguments that match its inputSchema. You can us
3480
3532
  "tool.has_dangerous_capabilities": toolCapsForAudit.length > 0
3481
3533
  });
3482
3534
  try {
3483
- const result = await this.executeTool(tool, use, ctx, budget);
3535
+ let result = await this.executeTool(tool, use, ctx, budget);
3536
+ if (this.opts.hookRunner?.has("PostToolUse")) {
3537
+ const post = await this.opts.hookRunner.postToolUse(
3538
+ tool.name,
3539
+ use.input,
3540
+ { content: String(result.content), isError: !!result.is_error },
3541
+ ctx
3542
+ );
3543
+ if (post.additionalContext) {
3544
+ result = { ...result, content: `${result.content}
3545
+
3546
+ ${post.additionalContext}` };
3547
+ }
3548
+ }
3484
3549
  budget = this.decrementBudget(result, budget);
3485
3550
  span?.setAttribute("tool.is_error", !!result.is_error);
3486
3551
  span?.setAttribute(
@@ -3669,6 +3734,14 @@ ${excerpt}`;
3669
3734
  is_error: true
3670
3735
  };
3671
3736
  }
3737
+ blockedByHookResult(use, reason) {
3738
+ return {
3739
+ type: "tool_result",
3740
+ tool_use_id: use.id,
3741
+ content: `Tool "${use.name}" was blocked by a PreToolUse hook: ${reason ?? "no reason given"}`,
3742
+ is_error: true
3743
+ };
3744
+ }
3672
3745
  decrementBudget(result, budget) {
3673
3746
  const contentBytes = typeof result.content === "string" ? Buffer.byteLength(result.content, "utf8") : Buffer.byteLength(JSON.stringify(result.content), "utf8");
3674
3747
  return Math.max(0, budget - contentBytes);
@@ -4752,6 +4825,23 @@ function tryParse(s) {
4752
4825
  }
4753
4826
  }
4754
4827
 
4828
+ // src/utils/merge-custom-models.ts
4829
+ function mergeCustomModelDefs(providerCustomModels, configModels) {
4830
+ const out = {};
4831
+ if (providerCustomModels) {
4832
+ for (const [id, def] of Object.entries(providerCustomModels)) {
4833
+ out[id] = { ...def };
4834
+ }
4835
+ }
4836
+ if (configModels) {
4837
+ for (const [id, def] of Object.entries(configModels)) {
4838
+ out[id] = { ...def };
4839
+ }
4840
+ }
4841
+ if (Object.keys(out).length === 0) return void 0;
4842
+ return out;
4843
+ }
4844
+
4755
4845
  // src/storage/session-store.ts
4756
4846
  init_atomic_write();
4757
4847
  var DefaultSessionStore = class {
@@ -6901,12 +6991,95 @@ var DirectorStateCheckpoint = class {
6901
6991
  }
6902
6992
  };
6903
6993
  init_atomic_write();
6994
+ var DESTRUCTIVE_BASH_PATTERNS = [
6995
+ /\bgit\s+(?:clean\s+-[^\s]*[xdf]|reset\s+--hard)\b/i,
6996
+ /\b(?:drop|truncate)\s+(?:table|database|schema)\b/i,
6997
+ /\bdelete\s+from\b/i,
6998
+ /\b(?:mkfs|format|diskpart|shutdown|reboot)\b/i,
6999
+ /\bchmod\s+-R\s+777\b/i,
7000
+ /\bchown\s+-R\b/i,
7001
+ /\b(?:curl|wget)\b.*\|\s*(?:sh|bash|zsh|pwsh|powershell)\b/i,
7002
+ /\b(?:powershell|pwsh)\b.*(?:-encodedcommand|-enc)\b/i,
7003
+ /:\(\)\s*\{\s*:\|:&\s*}\s*;/
7004
+ ];
7005
+ var PROJECT_ESCAPE_PATTERN = /(?:^|[\s"'])\.\.(?:[\\/]|$)/;
7006
+ var ABSOLUTE_PATH_PATTERN = /(?:^|[\s"'])(?:~[\\/]|\/[A-Za-z0-9_.-]|[A-Za-z]:[\\/])/;
7007
+ var SHELL_OPERATORS = /* @__PURE__ */ new Set(["&&", "||", "|", ";", ">", ">>", "<", "2>", "2>>"]);
7008
+ function getInputString(input, key) {
7009
+ if (!input || typeof input !== "object") return void 0;
7010
+ const value = input[key];
7011
+ return typeof value === "string" ? value : void 0;
7012
+ }
7013
+ function pathLooksInsideProject(rawPath, projectRoot) {
7014
+ if (!projectRoot) return false;
7015
+ if (rawPath === "~" || rawPath.startsWith("~/") || rawPath.startsWith("~\\")) return false;
7016
+ const resolved = path6.resolve(projectRoot, rawPath);
7017
+ const relative8 = path6.relative(projectRoot, resolved);
7018
+ return !!relative8 && !relative8.startsWith("..") && !path6.isAbsolute(relative8);
7019
+ }
7020
+ function tokenizeShell(command) {
7021
+ return command.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token) => token.replace(/^['"]|['"]$/g, "")) ?? [];
7022
+ }
7023
+ function pathTokenIsOutsideProject(token, projectRoot) {
7024
+ if (!token || SHELL_OPERATORS.has(token) || token.startsWith("-")) return false;
7025
+ if (token === "/" || token === "~" || token === "." || token === "..") return token !== ".";
7026
+ if (token.includes("*")) return true;
7027
+ if (token.startsWith("..") || token.includes("../") || token.includes("..\\")) return true;
7028
+ if (path6.isAbsolute(token) || token.startsWith("~/")) return !pathLooksInsideProject(token, projectRoot);
7029
+ return false;
7030
+ }
7031
+ function hasDangerousDeleteTarget(tokens, start, projectRoot) {
7032
+ const targets = tokens.slice(start).filter((token) => !token.startsWith("-") && !SHELL_OPERATORS.has(token));
7033
+ if (targets.length === 0) return true;
7034
+ return targets.some((target) => pathTokenIsOutsideProject(target, projectRoot));
7035
+ }
7036
+ function hasDestructiveDelete(command, projectRoot) {
7037
+ const tokens = tokenizeShell(command);
7038
+ for (let i = 0; i < tokens.length; i++) {
7039
+ const token = tokens[i]?.toLowerCase();
7040
+ if (!token) continue;
7041
+ if (token === "rm") {
7042
+ const args = tokens.slice(i + 1);
7043
+ const recursiveOrForce = args.some(
7044
+ (arg) => /^-[^-]*[rf]/i.test(arg) || arg === "--recursive" || arg === "--force"
7045
+ );
7046
+ if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
7047
+ }
7048
+ if (token === "rmdir" || token === "rd") {
7049
+ const args = tokens.slice(i + 1);
7050
+ const recursive = args.some((arg) => arg.toLowerCase() === "/s");
7051
+ if (recursive && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
7052
+ }
7053
+ if (token === "del" || token === "erase") {
7054
+ if (hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
7055
+ }
7056
+ if (token === "remove-item") {
7057
+ const args = tokens.slice(i + 1).map((arg) => arg.toLowerCase());
7058
+ const recursiveOrForce = args.includes("-recurse") || args.includes("-force");
7059
+ if (recursiveOrForce && hasDangerousDeleteTarget(tokens, i + 1, projectRoot)) return true;
7060
+ }
7061
+ }
7062
+ return false;
7063
+ }
7064
+ function isClearlyDestructiveBashCommand(command, projectRoot) {
7065
+ const trimmed = command.trim();
7066
+ if (!trimmed) return false;
7067
+ if (hasDestructiveDelete(trimmed, projectRoot)) return true;
7068
+ if (DESTRUCTIVE_BASH_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
7069
+ if (/\bcd\s+(?:\.\.|~|\/|[A-Za-z]:[\\/])/i.test(trimmed)) return true;
7070
+ if (PROJECT_ESCAPE_PATTERN.test(trimmed)) return true;
7071
+ const absolute = trimmed.match(ABSOLUTE_PATH_PATTERN)?.[0]?.trim().replace(/^['"]|['"]$/g, "");
7072
+ if (absolute && !pathLooksInsideProject(absolute, projectRoot)) return true;
7073
+ return false;
7074
+ }
7075
+
7076
+ // src/security/permission-policy.ts
6904
7077
  var DefaultPermissionPolicy = class {
6905
7078
  policy = {};
6906
7079
  loaded = false;
6907
7080
  trustFile;
6908
7081
  yolo;
6909
- forceAllYolo;
7082
+ yoloDestructive;
6910
7083
  /**
6911
7084
  * Session-scoped "soft deny" map. When the user presses 'n' (block once),
6912
7085
  * the tool+pattern is added here. If the LLM retries in the same session,
@@ -6939,7 +7112,7 @@ var DefaultPermissionPolicy = class {
6939
7112
  constructor(opts) {
6940
7113
  this.trustFile = opts.trustFile;
6941
7114
  this.yolo = opts.yolo ?? false;
6942
- this.forceAllYolo = opts.forceAllYolo ?? false;
7115
+ this.yoloDestructive = opts.yoloDestructive ?? opts.forceAllYolo ?? false;
6943
7116
  this.promptDelegate = opts.promptDelegate;
6944
7117
  }
6945
7118
  /**
@@ -6959,13 +7132,21 @@ var DefaultPermissionPolicy = class {
6959
7132
  getYolo() {
6960
7133
  return this.yolo;
6961
7134
  }
6962
- /** Toggle force-all-YOLO at runtime. */
7135
+ /** Toggle the destructive YOLO override at runtime. */
7136
+ setYoloDestructive(enabled) {
7137
+ this.yoloDestructive = enabled;
7138
+ }
7139
+ /** Check whether the destructive YOLO override is active. */
7140
+ getYoloDestructive() {
7141
+ return this.yoloDestructive;
7142
+ }
7143
+ /** @deprecated Use `setYoloDestructive`. */
6963
7144
  setForceAllYolo(enabled) {
6964
- this.forceAllYolo = enabled;
7145
+ this.setYoloDestructive(enabled);
6965
7146
  }
6966
- /** Check whether force-all-YOLO is active. */
7147
+ /** @deprecated Use `getYoloDestructive`. */
6967
7148
  getForceAllYolo() {
6968
- return this.forceAllYolo;
7149
+ return this.getYoloDestructive();
6969
7150
  }
6970
7151
  async reload() {
6971
7152
  try {
@@ -7012,7 +7193,8 @@ var DefaultPermissionPolicy = class {
7012
7193
  return { permission: "auto", source: "trust" };
7013
7194
  }
7014
7195
  if (this.yolo) {
7015
- if (tool.riskTier === "destructive" && !this.forceAllYolo) {
7196
+ const destructive = this.isDestructiveYoloCall(tool, input, ctx);
7197
+ if (destructive && !this.yoloDestructive) {
7016
7198
  if (this.promptDelegate) {
7017
7199
  const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
7018
7200
  if (decision === "always") {
@@ -7064,6 +7246,18 @@ var DefaultPermissionPolicy = class {
7064
7246
  }
7065
7247
  return { permission: "confirm", source: "default" };
7066
7248
  }
7249
+ isDestructiveYoloCall(tool, input, ctx) {
7250
+ if (tool.name === "bash") {
7251
+ const command = getInputString(input, "command");
7252
+ return command ? isClearlyDestructiveBashCommand(command, ctx.projectRoot) : true;
7253
+ }
7254
+ if (tool.name === "write" || tool.name === "edit" || tool.name === "replace" || tool.name === "patch") {
7255
+ const targetPath = getInputString(input, "path") ?? getInputString(input, "file");
7256
+ if (!targetPath || !ctx.projectRoot) return false;
7257
+ return !pathLooksInsideProject(targetPath, ctx.projectRoot);
7258
+ }
7259
+ return tool.riskTier === "destructive";
7260
+ }
7067
7261
  async trust(rule) {
7068
7262
  if (!this.loaded) await this.reload();
7069
7263
  const entry = this.policy[rule.tool] ?? {};
@@ -7534,8 +7728,8 @@ async function streamProviderToResponse(provider, req, signal, ctx, events) {
7534
7728
  try {
7535
7729
  await Promise.race([
7536
7730
  Promise.resolve(iter.return?.()),
7537
- new Promise((resolve11) => {
7538
- drainTimer = setTimeout(resolve11, 500);
7731
+ new Promise((resolve13) => {
7732
+ drainTimer = setTimeout(resolve13, 500);
7539
7733
  })
7540
7734
  ]);
7541
7735
  } finally {
@@ -7596,7 +7790,7 @@ async function runProviderWithRetry(opts) {
7596
7790
  description
7597
7791
  });
7598
7792
  }
7599
- await new Promise((resolve11, reject) => {
7793
+ await new Promise((resolve13, reject) => {
7600
7794
  let settled = false;
7601
7795
  const onAbort = () => {
7602
7796
  if (settled) return;
@@ -7609,7 +7803,7 @@ async function runProviderWithRetry(opts) {
7609
7803
  settled = true;
7610
7804
  clearTimeout(t2);
7611
7805
  signal.removeEventListener("abort", onAbort);
7612
- resolve11();
7806
+ resolve13();
7613
7807
  }, delay);
7614
7808
  if (signal.aborted) {
7615
7809
  onAbort();
@@ -9159,7 +9353,8 @@ ${recentJournal}` : "No prior iterations.",
9159
9353
  " \u2022 When this iteration's Task is finished (real artifact / passing",
9160
9354
  " test / applied diff / clean output), emit `[done]` on its own line.",
9161
9355
  " \u2022 Do not stop on the first obstacle \u2014 try at least 3 distinct",
9162
- " approaches before giving up. YOLO is active; no confirmations.",
9356
+ " approaches before giving up. YOLO is active for normal project work;",
9357
+ " destructive-gated confirmations still belong to the permission flow.",
9163
9358
  "",
9164
9359
  "2. UPDATE TODO STATE (when Source is `todo`)",
9165
9360
  " \u2022 Mark this todo `in_progress` via the todos tool before tool work.",
@@ -9288,7 +9483,7 @@ ${recentJournal}` : "No prior iterations.",
9288
9483
  }
9289
9484
  };
9290
9485
  function sleep(ms) {
9291
- return new Promise((resolve11) => setTimeout(resolve11, ms));
9486
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
9292
9487
  }
9293
9488
 
9294
9489
  // src/coordination/subagent-budget.ts
@@ -9504,12 +9699,12 @@ var SubagentBudget = class _SubagentBudget {
9504
9699
  if (!bus || !bus.hasListenerFor("budget.threshold_reached")) {
9505
9700
  return Promise.resolve("stop");
9506
9701
  }
9507
- return new Promise((resolve11) => {
9702
+ return new Promise((resolve13) => {
9508
9703
  let resolved = false;
9509
9704
  const respond = (d) => {
9510
9705
  if (resolved) return;
9511
9706
  resolved = true;
9512
- resolve11(d);
9707
+ resolve13(d);
9513
9708
  };
9514
9709
  const fallback = setTimeout(
9515
9710
  () => respond("stop"),
@@ -12736,7 +12931,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
12736
12931
  taskIds.map((id) => {
12737
12932
  const cached = this.completedResults.find((r) => r.taskId === id);
12738
12933
  if (cached) return cached;
12739
- return new Promise((resolve11, reject) => {
12934
+ return new Promise((resolve13, reject) => {
12740
12935
  const timeout = setTimeout(() => {
12741
12936
  this.off("task.completed", handler);
12742
12937
  reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
@@ -12745,7 +12940,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
12745
12940
  if (result.taskId === id) {
12746
12941
  clearTimeout(timeout);
12747
12942
  this.off("task.completed", handler);
12748
- resolve11(result);
12943
+ resolve13(result);
12749
12944
  }
12750
12945
  };
12751
12946
  this.on("task.completed", handler);
@@ -13248,7 +13443,7 @@ function providerErrorToSubagentError(err, message, cause) {
13248
13443
 
13249
13444
  // src/execution/parallel-eternal-engine.ts
13250
13445
  function sleep2(ms) {
13251
- return new Promise((resolve11) => setTimeout(resolve11, ms));
13446
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
13252
13447
  }
13253
13448
  var GOAL_COMPLETE_MARKER2 = /^\s*\[goal[_\s-]?complete\]\s*$/im;
13254
13449
  var ParallelEternalEngine = class {
@@ -13427,7 +13622,8 @@ ${recentJournal}` : "No prior iterations.",
13427
13622
  "\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
13428
13623
  "\u2022 Execute the assigned task end-to-end using multiple tool calls.",
13429
13624
  "\u2022 Emit `[done]` on its own line when the task is complete.",
13430
- "\u2022 Do not ask for confirmation \u2014 YOLO is active.",
13625
+ "\u2022 Do not ask before routine in-project tool use \u2014 YOLO is active for normal project work.",
13626
+ "\u2022 If a destructive-gated confirmation appears, wait for the permission flow.",
13431
13627
  "\u2022 If the overall Mission is accomplished, emit `[GOAL_COMPLETE]` followed by a verification recipe.",
13432
13628
  "\u2022 Keep output concise \u2014 summarize findings, do not transcribe files."
13433
13629
  ].join("\n");
@@ -13684,8 +13880,10 @@ ${journalTail.join("\n")}` : "Recent journal: (none \u2014 this is the first ite
13684
13880
  " decide.",
13685
13881
  "",
13686
13882
  "### Operating principles",
13687
- "- YOLO is active. Do NOT ask for confirmation, do NOT propose",
13688
- " options. Pick the best path and execute it.",
13883
+ "- YOLO is active for normal project work. Proceed with routine",
13884
+ " in-project tool use without pre-confirming; pick the best path and execute it.",
13885
+ " If the permission system raises a destructive-gated confirmation, wait",
13886
+ " for that flow instead of trying to bypass it.",
13689
13887
  "- Use tools freely; multiple calls per turn are normal and expected.",
13690
13888
  "- When working on a todo, mark it `in_progress` via the todos tool",
13691
13889
  " before tool work and `completed` (or `cancelled` with a reason)",
@@ -16053,11 +16251,11 @@ var Director = class _Director {
16053
16251
  if (cached) return cached;
16054
16252
  const existing = this.taskWaiters.get(id);
16055
16253
  if (existing) return existing.promise;
16056
- let resolve11;
16254
+ let resolve13;
16057
16255
  const promise = new Promise((res) => {
16058
- resolve11 = res;
16256
+ resolve13 = res;
16059
16257
  });
16060
- this.taskWaiters.set(id, { promise, resolve: resolve11 });
16258
+ this.taskWaiters.set(id, { promise, resolve: resolve13 });
16061
16259
  return promise;
16062
16260
  })
16063
16261
  );
@@ -16442,7 +16640,7 @@ function createDelegateTool(opts) {
16442
16640
  subagentId
16443
16641
  });
16444
16642
  const dir = director;
16445
- const result = await new Promise((resolve11) => {
16643
+ const result = await new Promise((resolve13) => {
16446
16644
  let settled = false;
16447
16645
  let timer;
16448
16646
  const finish = (value) => {
@@ -16452,7 +16650,7 @@ function createDelegateTool(opts) {
16452
16650
  offTool();
16453
16651
  offIter();
16454
16652
  offProgress();
16455
- resolve11(value);
16653
+ resolve13(value);
16456
16654
  };
16457
16655
  const arm = () => {
16458
16656
  if (timer) clearTimeout(timer);
@@ -18082,9 +18280,9 @@ var AISpecBuilder = class {
18082
18280
  if (!this.sessionPath) return;
18083
18281
  try {
18084
18282
  const fsp20 = await import('fs/promises');
18085
- const path36 = await import('path');
18283
+ const path37 = await import('path');
18086
18284
  const { atomicWrite: atomicWrite2 } = await Promise.resolve().then(() => (init_atomic_write(), atomic_write_exports));
18087
- await fsp20.mkdir(path36.dirname(this.sessionPath), { recursive: true });
18285
+ await fsp20.mkdir(path37.dirname(this.sessionPath), { recursive: true });
18088
18286
  await atomicWrite2(this.sessionPath, JSON.stringify(this.session, null, 2));
18089
18287
  } catch {
18090
18288
  }
@@ -18794,15 +18992,15 @@ function computeCriticalPath(graph, _topoOrder, blockedByMap) {
18794
18992
  maxId = id;
18795
18993
  }
18796
18994
  }
18797
- const path36 = [];
18995
+ const path37 = [];
18798
18996
  let current = maxId;
18799
18997
  const visited = /* @__PURE__ */ new Set();
18800
18998
  while (current && !visited.has(current)) {
18801
18999
  visited.add(current);
18802
- path36.unshift(current);
19000
+ path37.unshift(current);
18803
19001
  current = prev.get(current) ?? null;
18804
19002
  }
18805
- return path36;
19003
+ return path37;
18806
19004
  }
18807
19005
  function computeParallelGroups(graph, blockedByMap) {
18808
19006
  const groups = [];
@@ -19352,7 +19550,7 @@ var SddParallelRun = class {
19352
19550
  "\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
19353
19551
  "\u2022 Execute the assigned SDD task end-to-end using multiple tool calls.",
19354
19552
  "\u2022 Mark the task [done] in the tracker when complete.",
19355
- "\u2022 Do not ask for confirmation.",
19553
+ "\u2022 Do not ask before routine in-project tool use; if a permission gate appears, wait for that flow.",
19356
19554
  "\u2022 Keep output concise \u2014 summarize changes, do not transcribe files."
19357
19555
  ].join("\n");
19358
19556
  const spawns = subagentIds.map(
@@ -19595,9 +19793,9 @@ var DefaultHealthRegistry = class {
19595
19793
  }
19596
19794
  async runOne(check) {
19597
19795
  let timer = null;
19598
- const timeout = new Promise((resolve11) => {
19796
+ const timeout = new Promise((resolve13) => {
19599
19797
  timer = setTimeout(
19600
- () => resolve11({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
19798
+ () => resolve13({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
19601
19799
  this.timeoutMs
19602
19800
  );
19603
19801
  });
@@ -19780,7 +19978,7 @@ async function startMetricsServer(opts) {
19780
19978
  const tls = opts.tls;
19781
19979
  const useHttps = !!(tls?.cert && tls?.key);
19782
19980
  const host = opts.host ?? "127.0.0.1";
19783
- const path36 = opts.path ?? "/metrics";
19981
+ const path37 = opts.path ?? "/metrics";
19784
19982
  const healthPath = opts.healthPath ?? "/healthz";
19785
19983
  const healthRegistry = opts.healthRegistry;
19786
19984
  const listener = (req, res) => {
@@ -19790,7 +19988,7 @@ async function startMetricsServer(opts) {
19790
19988
  return;
19791
19989
  }
19792
19990
  const url = req.url.split("?")[0];
19793
- if (url === path36) {
19991
+ if (url === path37) {
19794
19992
  let body;
19795
19993
  try {
19796
19994
  body = renderPrometheus(opts.sink.snapshot());
@@ -19836,14 +20034,14 @@ async function startMetricsServer(opts) {
19836
20034
  const { createServer } = await import('http');
19837
20035
  server = createServer(listener);
19838
20036
  }
19839
- await new Promise((resolve11, reject) => {
20037
+ await new Promise((resolve13, reject) => {
19840
20038
  const onError = (err) => {
19841
20039
  server.off("listening", onListening);
19842
20040
  reject(err);
19843
20041
  };
19844
20042
  const onListening = () => {
19845
20043
  server.off("error", onError);
19846
- resolve11();
20044
+ resolve13();
19847
20045
  };
19848
20046
  server.once("error", onError);
19849
20047
  server.once("listening", onListening);
@@ -19854,9 +20052,9 @@ async function startMetricsServer(opts) {
19854
20052
  const protocol = useHttps ? "https" : "http";
19855
20053
  return {
19856
20054
  port: boundPort,
19857
- url: `${protocol}://${host}:${boundPort}${path36}`,
19858
- close: () => new Promise((resolve11, reject) => {
19859
- server.close((err) => err ? reject(err) : resolve11());
20055
+ url: `${protocol}://${host}:${boundPort}${path37}`,
20056
+ close: () => new Promise((resolve13, reject) => {
20057
+ server.close((err) => err ? reject(err) : resolve13());
19860
20058
  })
19861
20059
  };
19862
20060
  }
@@ -20405,7 +20603,7 @@ var context7Server = () => ({
20405
20603
  name: "context7",
20406
20604
  description: "Codebase-aware documentation and Q&A (context7.ai)",
20407
20605
  transport: "streamable-http",
20408
- url: "https://server.context7.ai/mcp",
20606
+ url: "https://mcp.context7.com/mcp",
20409
20607
  permission: "confirm"
20410
20608
  });
20411
20609
  var braveSearchServer = () => ({
@@ -21995,7 +22193,7 @@ var CloudSync = class {
21995
22193
  const localPath = this.categoryToPath(cat);
21996
22194
  if (!localPath) continue;
21997
22195
  const rel = segments.slice(2).join("/");
21998
- const destPath = rel ? path6.join(localPath, rel) : localPath;
22196
+ const destPath = resolvePulledCategoryPath(cat, localPath, rel, entry.path);
21999
22197
  const blobData = await this.getBlob(token, owner, repoName, entry.sha);
22000
22198
  await fsp3.mkdir(path6.dirname(destPath), { recursive: true });
22001
22199
  await fsp3.writeFile(destPath, Buffer.from(blobData, "base64"));
@@ -22169,6 +22367,26 @@ var CloudSync = class {
22169
22367
  return results;
22170
22368
  }
22171
22369
  };
22370
+ function resolvePulledCategoryPath(cat, localPath, rel, remotePath) {
22371
+ const directoryBacked = cat === "skills" || cat === "prompts";
22372
+ if (!directoryBacked) {
22373
+ if (rel) throw new Error(`Refusing nested CloudSync path for file category: ${remotePath}`);
22374
+ return localPath;
22375
+ }
22376
+ if (!rel) return localPath;
22377
+ const normalizedRel = path6.normalize(rel);
22378
+ const traversesUp = normalizedRel === ".." || normalizedRel.startsWith(`..${path6.sep}`);
22379
+ if (path6.isAbsolute(normalizedRel) || traversesUp) {
22380
+ throw new Error(`Refusing CloudSync path traversal: ${remotePath}`);
22381
+ }
22382
+ const dest = path6.resolve(localPath, normalizedRel);
22383
+ const root = path6.resolve(localPath);
22384
+ const relative8 = path6.relative(root, dest);
22385
+ if (relative8.startsWith("..") || path6.isAbsolute(relative8)) {
22386
+ throw new Error(`Refusing CloudSync path outside category root: ${remotePath}`);
22387
+ }
22388
+ return dest;
22389
+ }
22172
22390
  function timeAgo(iso) {
22173
22391
  const diff = Date.now() - new Date(iso).getTime();
22174
22392
  const mins = Math.floor(diff / 6e4);
@@ -23337,7 +23555,7 @@ var SecurityScannerOrchestrator = class {
23337
23555
  const delay = Math.round(policy.delayMs(attempt));
23338
23556
  const status = isProviderErr ? err.status : 0;
23339
23557
  console.warn(`[SecurityScanner] retry ${attempt + 1} after ${delay}ms (status=${status}) \u2014 ${errAsErr.message}`);
23340
- await new Promise((resolve11) => setTimeout(resolve11, delay));
23558
+ await new Promise((resolve13) => setTimeout(resolve13, delay));
23341
23559
  return this.completeWithRetry(provider, request, abortController, attempt + 1);
23342
23560
  }
23343
23561
  }
@@ -24913,12 +25131,12 @@ function makeContinueToNextIterationTool() {
24913
25131
  // src/core/iteration-limit.ts
24914
25132
  function requestLimitExtension(opts) {
24915
25133
  const { events, currentIterations, currentLimit, autoExtend, timeoutMs = 3e4 } = opts;
24916
- return new Promise((resolve11) => {
25134
+ return new Promise((resolve13) => {
24917
25135
  let resolved = false;
24918
25136
  const timerFired = () => {
24919
25137
  if (!resolved) {
24920
25138
  resolved = true;
24921
- resolve11(0);
25139
+ resolve13(0);
24922
25140
  }
24923
25141
  };
24924
25142
  const timer = setTimeout(timerFired, timeoutMs);
@@ -24927,14 +25145,14 @@ function requestLimitExtension(opts) {
24927
25145
  if (!resolved) {
24928
25146
  resolved = true;
24929
25147
  clearTimeout(timer);
24930
- resolve11(0);
25148
+ resolve13(0);
24931
25149
  }
24932
25150
  };
24933
25151
  const grant = (extra) => {
24934
25152
  if (!resolved) {
24935
25153
  resolved = true;
24936
25154
  clearTimeout(timer);
24937
- resolve11(Math.max(0, extra));
25155
+ resolve13(Math.max(0, extra));
24938
25156
  }
24939
25157
  };
24940
25158
  events.emit("iteration.limit_reached", {
@@ -24948,7 +25166,7 @@ function requestLimitExtension(opts) {
24948
25166
  if (!resolved) {
24949
25167
  resolved = true;
24950
25168
  clearTimeout(timer);
24951
- resolve11(100);
25169
+ resolve13(100);
24952
25170
  }
24953
25171
  });
24954
25172
  }
@@ -25540,13 +25758,13 @@ var Agent = class {
25540
25758
  }
25541
25759
  }
25542
25760
  waitForConfirm(info) {
25543
- return new Promise((resolve11) => {
25761
+ return new Promise((resolve13) => {
25544
25762
  this.events.emit("tool.confirm_needed", {
25545
25763
  tool: info.tool,
25546
25764
  input: info.input,
25547
25765
  toolUseId: info.toolUseId,
25548
25766
  suggestedPattern: info.suggestedPattern,
25549
- resolve: resolve11
25767
+ resolve: resolve13
25550
25768
  });
25551
25769
  });
25552
25770
  }
@@ -25620,6 +25838,260 @@ function sizeSignals(toolName, content) {
25620
25838
  }
25621
25839
  return { outputBytes, outputTokens, outputLines };
25622
25840
  }
25841
+
25842
+ // src/hooks/registry.ts
25843
+ var HookRegistry = class {
25844
+ entries = [];
25845
+ /** Register an in-process hook. Returns an unsubscribe function. */
25846
+ registerInProcess(event, matcher, hook, owner) {
25847
+ const entry = {
25848
+ kind: "inprocess",
25849
+ event,
25850
+ matcher: matcher ?? "*",
25851
+ hook,
25852
+ owner
25853
+ };
25854
+ this.entries.push(entry);
25855
+ return () => this.remove(entry);
25856
+ }
25857
+ /** Register a single shell hook. Returns an unsubscribe function. */
25858
+ registerShell(event, hook) {
25859
+ const entry = {
25860
+ kind: "shell",
25861
+ event,
25862
+ matcher: hook.matcher ?? "*",
25863
+ command: hook.command,
25864
+ timeoutMs: hook.timeoutMs
25865
+ };
25866
+ this.entries.push(entry);
25867
+ return () => this.remove(entry);
25868
+ }
25869
+ /** Bulk-load shell hooks from a `config.hooks` map. */
25870
+ loadShellHooks(hooks) {
25871
+ if (!hooks) return;
25872
+ for (const [event, list] of Object.entries(hooks)) {
25873
+ for (const h of list ?? []) {
25874
+ if (h?.command) this.registerShell(event, h);
25875
+ }
25876
+ }
25877
+ }
25878
+ /** All entries registered for an event, in registration order. */
25879
+ list(event) {
25880
+ return this.entries.filter((e) => e.event === event);
25881
+ }
25882
+ /** True when any entry is registered for the event. */
25883
+ has(event) {
25884
+ return this.entries.some((e) => e.event === event);
25885
+ }
25886
+ /** Drop every registered hook (used in teardown / tests). */
25887
+ clear() {
25888
+ this.entries.length = 0;
25889
+ }
25890
+ remove(entry) {
25891
+ const i = this.entries.indexOf(entry);
25892
+ if (i >= 0) this.entries.splice(i, 1);
25893
+ }
25894
+ };
25895
+ function hookMatcherMatches(matcher, toolName) {
25896
+ if (!matcher || matcher === "*") return true;
25897
+ if (toolName === void 0) return true;
25898
+ const target = toolName.toLowerCase();
25899
+ return matcher.split("|").map((s) => s.trim().toLowerCase()).filter(Boolean).includes(target);
25900
+ }
25901
+ var DEFAULT_TIMEOUT_MS3 = 5e3;
25902
+ var MAX_OUTPUT_BYTES = 64 * 1024;
25903
+ async function runShellHook(spec, input, logger) {
25904
+ const timeoutMs = spec.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
25905
+ return await new Promise((resolve13) => {
25906
+ let settled = false;
25907
+ const done = (v) => {
25908
+ if (settled) return;
25909
+ settled = true;
25910
+ clearTimeout(timer);
25911
+ resolve13(v);
25912
+ };
25913
+ let child;
25914
+ try {
25915
+ child = spawn(spec.command, {
25916
+ cwd: input.cwd,
25917
+ env: process.env,
25918
+ stdio: ["pipe", "pipe", "pipe"],
25919
+ shell: true
25920
+ });
25921
+ } catch (err2) {
25922
+ logger?.warn?.(`hook spawn failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
25923
+ return resolve13(null);
25924
+ }
25925
+ const timer = setTimeout(() => {
25926
+ logger?.warn?.(`hook command timed out after ${timeoutMs}ms: ${spec.command}`);
25927
+ try {
25928
+ child.kill("SIGKILL");
25929
+ } catch {
25930
+ }
25931
+ done(null);
25932
+ }, timeoutMs);
25933
+ let out = "";
25934
+ let err = "";
25935
+ let outTrunc = false;
25936
+ child.stdout?.on("data", (d) => {
25937
+ if (outTrunc) return;
25938
+ out += d.toString("utf8");
25939
+ if (Buffer.byteLength(out, "utf8") > MAX_OUTPUT_BYTES) {
25940
+ out = out.slice(0, MAX_OUTPUT_BYTES);
25941
+ outTrunc = true;
25942
+ }
25943
+ });
25944
+ child.stderr?.on("data", (d) => {
25945
+ if (err.length < MAX_OUTPUT_BYTES) err += d.toString("utf8");
25946
+ });
25947
+ child.on("error", (e) => {
25948
+ logger?.warn?.(`hook command error: ${e instanceof Error ? e.message : String(e)}`);
25949
+ done(null);
25950
+ });
25951
+ child.on("close", (code) => {
25952
+ if (code === 2) {
25953
+ const reason = (err.trim() || out.trim() || "blocked by hook").slice(0, 2e3);
25954
+ return done({ decision: "block", reason });
25955
+ }
25956
+ const parsed = parseOutcome(out);
25957
+ done(parsed);
25958
+ });
25959
+ try {
25960
+ child.stdin?.end(`${JSON.stringify(input)}
25961
+ `);
25962
+ } catch {
25963
+ }
25964
+ });
25965
+ }
25966
+ function parseOutcome(stdout) {
25967
+ const trimmed = stdout.trim();
25968
+ if (!trimmed || trimmed[0] !== "{") return null;
25969
+ try {
25970
+ const obj = JSON.parse(trimmed);
25971
+ const outcome = {};
25972
+ if (obj["decision"] === "block" || obj["decision"] === "allow") {
25973
+ outcome.decision = obj["decision"];
25974
+ }
25975
+ if (typeof obj["reason"] === "string") outcome.reason = obj["reason"];
25976
+ if (typeof obj["additionalContext"] === "string") {
25977
+ outcome.additionalContext = obj["additionalContext"];
25978
+ }
25979
+ if (obj["modifiedInput"] && typeof obj["modifiedInput"] === "object") {
25980
+ outcome.modifiedInput = obj["modifiedInput"];
25981
+ }
25982
+ return outcome;
25983
+ } catch {
25984
+ return null;
25985
+ }
25986
+ }
25987
+
25988
+ // src/hooks/runner.ts
25989
+ var HookRunner = class {
25990
+ constructor(opts) {
25991
+ this.opts = opts;
25992
+ this.registry = opts.registry;
25993
+ }
25994
+ opts;
25995
+ registry;
25996
+ /** Cheap guard so callers can skip building payloads when nothing listens. */
25997
+ has(event) {
25998
+ return this.registry.has(event);
25999
+ }
26000
+ async preToolUse(toolName, toolInput, env) {
26001
+ const entries = this.matching("PreToolUse", toolName);
26002
+ if (entries.length === 0) return {};
26003
+ let current = toolInput;
26004
+ let mutated = false;
26005
+ for (const entry of entries) {
26006
+ const payload = {
26007
+ event: "PreToolUse",
26008
+ toolName,
26009
+ toolInput: current,
26010
+ ...this.base(env)
26011
+ };
26012
+ const outcome = await this.invoke(entry, payload);
26013
+ if (!outcome) continue;
26014
+ if (outcome.modifiedInput && typeof outcome.modifiedInput === "object") {
26015
+ current = outcome.modifiedInput;
26016
+ mutated = true;
26017
+ }
26018
+ if (outcome.decision === "block") {
26019
+ return { block: true, reason: outcome.reason ?? `Blocked by ${entry.event} hook` };
26020
+ }
26021
+ }
26022
+ return mutated ? { input: current } : {};
26023
+ }
26024
+ async postToolUse(toolName, toolInput, result, env) {
26025
+ const payload = {
26026
+ event: "PostToolUse",
26027
+ toolName,
26028
+ toolInput,
26029
+ toolResult: result,
26030
+ ...this.base(env)
26031
+ };
26032
+ return { additionalContext: await this.collectContext("PostToolUse", toolName, payload) };
26033
+ }
26034
+ async userPromptSubmit(prompt, env) {
26035
+ const entries = this.matching("UserPromptSubmit", void 0);
26036
+ if (entries.length === 0) return {};
26037
+ const payload = { event: "UserPromptSubmit", prompt, ...this.base(env) };
26038
+ const parts = [];
26039
+ for (const entry of entries) {
26040
+ const outcome = await this.invoke(entry, payload);
26041
+ if (!outcome) continue;
26042
+ if (outcome.decision === "block") {
26043
+ return { block: true, reason: outcome.reason ?? "Blocked by UserPromptSubmit hook" };
26044
+ }
26045
+ if (outcome.additionalContext) parts.push(outcome.additionalContext);
26046
+ }
26047
+ return parts.length ? { additionalContext: parts.join("\n") } : {};
26048
+ }
26049
+ async sessionStart(env) {
26050
+ const payload = { event: "SessionStart", ...this.base(env) };
26051
+ return { additionalContext: await this.collectContext("SessionStart", void 0, payload) };
26052
+ }
26053
+ async stop(env) {
26054
+ const payload = { event: "Stop", ...this.base(env) };
26055
+ await this.collectContext("Stop", void 0, payload);
26056
+ }
26057
+ // ── internals ──────────────────────────────────────────────────────
26058
+ base(env) {
26059
+ const sessionId = this.opts.sessionId?.();
26060
+ return sessionId ? { cwd: env.cwd, sessionId } : { cwd: env.cwd };
26061
+ }
26062
+ matching(event, toolName) {
26063
+ return this.registry.list(event).filter((e) => hookMatcherMatches(e.matcher, toolName));
26064
+ }
26065
+ async invoke(entry, payload) {
26066
+ try {
26067
+ if (entry.kind === "inprocess") {
26068
+ const r = await entry.hook(payload);
26069
+ return r ?? null;
26070
+ }
26071
+ if (this.opts.allowShell === false) return null;
26072
+ return await runShellHook(
26073
+ { command: entry.command, timeoutMs: entry.timeoutMs },
26074
+ payload,
26075
+ this.opts.logger
26076
+ );
26077
+ } catch (err) {
26078
+ this.opts.logger?.warn?.(
26079
+ `${payload.event} hook threw: ${err instanceof Error ? err.message : String(err)}`
26080
+ );
26081
+ return null;
26082
+ }
26083
+ }
26084
+ async collectContext(event, toolName, payload) {
26085
+ const entries = this.matching(event, toolName);
26086
+ if (entries.length === 0) return void 0;
26087
+ const parts = [];
26088
+ for (const entry of entries) {
26089
+ const outcome = await this.invoke(entry, payload);
26090
+ if (outcome?.additionalContext) parts.push(outcome.additionalContext);
26091
+ }
26092
+ return parts.length ? parts.join("\n") : void 0;
26093
+ }
26094
+ };
25623
26095
  async function bootConfig(options = {}) {
25624
26096
  const { flags = {}, appLabel = "wstack", loadSyncConfig = true } = options;
25625
26097
  const cwd = typeof flags["cwd"] === "string" ? path6.resolve(flags["cwd"]) : process.cwd();
@@ -25667,6 +26139,10 @@ function flagsToConfigPatch(flags) {
25667
26139
  const patch = {};
25668
26140
  if (typeof flags["provider"] === "string") patch.provider = flags["provider"];
25669
26141
  if (typeof flags["model"] === "string") patch.model = flags["model"];
26142
+ if (typeof flags["fallback-model"] === "string") {
26143
+ const list = flags["fallback-model"].split(",").map((s) => s.trim()).filter(Boolean);
26144
+ if (list.length > 0) patch.fallbackModels = list;
26145
+ }
25670
26146
  if (typeof flags["cwd"] === "string") patch.cwd = flags["cwd"];
25671
26147
  if (typeof flags["log-level"] === "string") {
25672
26148
  patch.log = { level: flags["log-level"] };
@@ -25998,8 +26474,8 @@ var InputBuilder = class {
25998
26474
  async registerFile(input) {
25999
26475
  const ref = await this.store.add({ ...input, kind: "file" });
26000
26476
  this.refs.push(ref);
26001
- const path36 = ref.meta.filename ?? ref.meta.label ?? String(ref.seq);
26002
- return `[file:${path36}]`;
26477
+ const path37 = ref.meta.filename ?? ref.meta.label ?? String(ref.seq);
26478
+ return `[file:${path37}]`;
26003
26479
  }
26004
26480
  /**
26005
26481
  * Whether `appendPaste(text)` would collapse the text to a placeholder
@@ -26399,12 +26875,12 @@ ${mem}`);
26399
26875
  }
26400
26876
  }
26401
26877
  async gitStatus(root) {
26402
- return new Promise((resolve11) => {
26878
+ return new Promise((resolve13) => {
26403
26879
  let settled = false;
26404
26880
  const finish = (s) => {
26405
26881
  if (settled) return;
26406
26882
  settled = true;
26407
- resolve11(s);
26883
+ resolve13(s);
26408
26884
  };
26409
26885
  let proc;
26410
26886
  const timer = setTimeout(() => {
@@ -26799,9 +27275,13 @@ var DefaultPluginAPI = class {
26799
27275
  config;
26800
27276
  log;
26801
27277
  configStore;
27278
+ hookRegistry;
27279
+ ownerName;
26802
27280
  pluginCleanupFns = [];
26803
27281
  constructor(init) {
26804
27282
  const owner = init.ownerName;
27283
+ this.ownerName = owner;
27284
+ this.hookRegistry = init.hookRegistry;
26805
27285
  this.container = init.container;
26806
27286
  this.events = init.events;
26807
27287
  this.config = init.config;
@@ -26888,6 +27368,13 @@ var DefaultPluginAPI = class {
26888
27368
  registerSystemPromptContributor(c) {
26889
27369
  return this.extensions.registerSystemPromptContributor(c);
26890
27370
  }
27371
+ registerHook(event, matcher, hook) {
27372
+ if (!this.hookRegistry) return () => {
27373
+ };
27374
+ const off = this.hookRegistry.registerInProcess(event, matcher, hook, this.ownerName);
27375
+ this.pluginCleanupFns.push(off);
27376
+ return off;
27377
+ }
26891
27378
  };
26892
27379
  var noopMcp = {
26893
27380
  start: async () => void 0,
@@ -27610,7 +28097,7 @@ var PhaseOrchestrator = class {
27610
28097
  async mergeOne(phase, handle) {
27611
28098
  if (!this.worktrees) return;
27612
28099
  try {
27613
- const resolve11 = this.ctx.resolveConflict ? async (info) => {
28100
+ const resolve13 = this.ctx.resolveConflict ? async (info) => {
27614
28101
  const shouldResolve = await this.shouldAttemptConflictResolution(phase, info);
27615
28102
  if (!shouldResolve) return false;
27616
28103
  this.emit("phase.conflictResolving", {
@@ -27620,7 +28107,7 @@ var PhaseOrchestrator = class {
27620
28107
  });
27621
28108
  return this.ctx.resolveConflict(phase, info);
27622
28109
  } : void 0;
27623
- const result = await this.worktrees.merge(handle, { squash: true, resolve: resolve11 });
28110
+ const result = await this.worktrees.merge(handle, { squash: true, resolve: resolve13 });
27624
28111
  if (result.resolved) {
27625
28112
  this.emit("phase.conflictResolved", { phaseId: phase.id, name: phase.name });
27626
28113
  }
@@ -27970,7 +28457,7 @@ var PhaseOrchestrator = class {
27970
28457
  }
27971
28458
  }
27972
28459
  delay(ms) {
27973
- return new Promise((resolve11) => setTimeout(resolve11, ms));
28460
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
27974
28461
  }
27975
28462
  };
27976
28463
 
@@ -29007,12 +29494,12 @@ var BrainDecisionQueue = class {
29007
29494
  options: request.options,
29008
29495
  rationale: "Decision escalated to human authority."
29009
29496
  };
29010
- const pending = new Promise((resolve11) => {
29011
- const entry = { request, resolve: resolve11 };
29497
+ const pending = new Promise((resolve13) => {
29498
+ const entry = { request, resolve: resolve13 };
29012
29499
  if (this.opts.timeoutMs && this.opts.timeoutMs > 0) {
29013
29500
  entry.timer = setTimeout(() => {
29014
29501
  this.pending.delete(request.id);
29015
- resolve11({ type: "deny", reason: "Brain human decision timed out." });
29502
+ resolve13({ type: "deny", reason: "Brain human decision timed out." });
29016
29503
  }, this.opts.timeoutMs);
29017
29504
  }
29018
29505
  this.pending.set(request.id, entry);
@@ -29127,8 +29614,8 @@ var CollaborationBus = class {
29127
29614
  if (this.isPaused()) return false;
29128
29615
  this.pausedAtMs = Date.now();
29129
29616
  this.pausedBy = byParticipant;
29130
- this.pausePromise = new Promise((resolve11) => {
29131
- this.pauseResolve = resolve11;
29617
+ this.pausePromise = new Promise((resolve13) => {
29618
+ this.pauseResolve = resolve13;
29132
29619
  });
29133
29620
  return true;
29134
29621
  }
@@ -29164,8 +29651,8 @@ var CollaborationBus = class {
29164
29651
  return true;
29165
29652
  }
29166
29653
  let timer;
29167
- const timeoutPromise = new Promise((resolve11) => {
29168
- timer = setTimeout(() => resolve11("timeout"), timeoutMs);
29654
+ const timeoutPromise = new Promise((resolve13) => {
29655
+ timer = setTimeout(() => resolve13("timeout"), timeoutMs);
29169
29656
  });
29170
29657
  const resumedPromise = this.pausePromise.then(() => "resumed");
29171
29658
  const winner = await Promise.race([resumedPromise, timeoutPromise]);
@@ -29656,7 +30143,7 @@ function createGitPlugin() {
29656
30143
  }
29657
30144
  async function runGit(args, cwd) {
29658
30145
  try {
29659
- return await new Promise((resolve11, reject) => {
30146
+ return await new Promise((resolve13, reject) => {
29660
30147
  const child = spawn("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
29661
30148
  let stdout = "";
29662
30149
  let stderr = "";
@@ -29677,7 +30164,7 @@ async function runGit(args, cwd) {
29677
30164
  })
29678
30165
  );
29679
30166
  });
29680
- child.on("close", (code) => resolve11({ stdout, stderr, code: code ?? 0 }));
30167
+ child.on("close", (code) => resolve13({ stdout, stderr, code: code ?? 0 }));
29681
30168
  });
29682
30169
  } catch (err) {
29683
30170
  if (err instanceof WrongStackError) throw err;
@@ -30353,6 +30840,6 @@ ${formatPlan(updated)}`
30353
30840
  };
30354
30841
  }
30355
30842
 
30356
- export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BrainDecisionQueue, BudgetExceededError, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HumanEscalatingBrainArbiter, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, bootConfig, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob, extractRunEnv, filesystemServer, findCriticalPath, flagsToConfigPatch, formatContextWindowModeList, formatGoal, formatHumanPrompt, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getCalibrationState, getContextWindowMode, getPlanTemplate, getTemplate, getTermSize, githubServer, goalFilePath, googleMapsServer, hashRequest, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isInteractive, isPluginError, isSessionError, isStdinTTY, isStdoutTTY, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isValidMatrixKey, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, matrixKeyKind, mergeModelsPayload, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, onResize, parseContinueDirective, parseSkillRef, pendingBtwCount, phaseForRole, projectHash, recordActualUsage, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resetCalibration, resolveAuditLevel, resolveContextWindowPolicy, resolveModelMatrix, resolveSessionLoggingConfig, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, runProviderWithRetry, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, setRawMode, slackServer, stableStringify, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, writeErr, writeOut, zaiVisionServer };
30843
+ export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BrainDecisionQueue, BudgetExceededError, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HookRegistry, HookRunner, HumanEscalatingBrainArbiter, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, bootConfig, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob, extractRunEnv, filesystemServer, findCriticalPath, flagsToConfigPatch, formatContextWindowModeList, formatGoal, formatHumanPrompt, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getCalibrationState, getContextWindowMode, getPlanTemplate, getTemplate, getTermSize, githubServer, goalFilePath, googleMapsServer, hashRequest, hookMatcherMatches, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isInteractive, isPluginError, isSessionError, isStdinTTY, isStdoutTTY, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isValidMatrixKey, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, matrixKeyKind, mergeCustomModelDefs, mergeModelsPayload, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, onResize, parseContinueDirective, parseSkillRef, pendingBtwCount, phaseForRole, projectHash, recordActualUsage, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resetCalibration, resolveAuditLevel, resolveContextWindowPolicy, resolveModelMatrix, resolveSessionLoggingConfig, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, runProviderWithRetry, runShellHook, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, setRawMode, slackServer, stableStringify, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, writeErr, writeOut, zaiVisionServer };
30357
30844
  //# sourceMappingURL=index.js.map
30358
30845
  //# sourceMappingURL=index.js.map