@wrongstack/core 0.264.0 → 0.265.1

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 (87) hide show
  1. package/dist/{agent-bridge-D8sa1vtv.d.ts → agent-bridge-DrkBxszZ.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-c9DLkaas.d.ts → agent-subagent-runner-DM2pP-B6.d.ts} +113 -11
  3. package/dist/{brain-O1IdKPaK.d.ts → brain-BXd_61kQ.d.ts} +31 -2
  4. package/dist/{compactor-BBy0rCtB.d.ts → compactor-B8pOf45Y.d.ts} +1 -1
  5. package/dist/{config-Dz2F3H2K.d.ts → config-BMCj_XDs.d.ts} +80 -12
  6. package/dist/{context-BGSpZNSE.d.ts → context-MRk5PhNv.d.ts} +26 -12
  7. package/dist/coordination/index.d.ts +77 -21
  8. package/dist/coordination/index.js +557 -159
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/{default-config-CXsDvOmP.d.ts → default-config-B0cj-Hry.d.ts} +11 -1
  11. package/dist/defaults/index.d.ts +28 -28
  12. package/dist/defaults/index.js +609 -195
  13. package/dist/defaults/index.js.map +1 -1
  14. package/dist/execution/index.d.ts +16 -16
  15. package/dist/execution/index.js +394 -155
  16. package/dist/execution/index.js.map +1 -1
  17. package/dist/execution/prompt-enhancer.d.ts +2 -2
  18. package/dist/execution/prompt-enhancer.js +1 -1
  19. package/dist/execution/prompt-enhancer.js.map +1 -1
  20. package/dist/extension/index.d.ts +6 -6
  21. package/dist/{goal-preamble-DzjFuN3p.d.ts → goal-preamble-DvHDSKSe.d.ts} +14 -10
  22. package/dist/{goal-store-CxWmCGbH.d.ts → goal-store-DtLMySNb.d.ts} +1 -1
  23. package/dist/{index-CYIQrXVF.d.ts → index-B-ch8K9C.d.ts} +8 -8
  24. package/dist/{index-CbLSI66_.d.ts → index-CEDeNodM.d.ts} +5 -5
  25. package/dist/index.d.ts +183 -52
  26. package/dist/index.js +1779 -673
  27. package/dist/index.js.map +1 -1
  28. package/dist/infrastructure/index.d.ts +6 -6
  29. package/dist/infrastructure/index.js +12 -8
  30. package/dist/infrastructure/index.js.map +1 -1
  31. package/dist/kernel/index.d.ts +9 -9
  32. package/dist/kernel/index.js +1 -1
  33. package/dist/kernel/index.js.map +1 -1
  34. package/dist/{llm-selector-DzxuZnNz.d.ts → llm-selector-C0tfTCUe.d.ts} +14 -2
  35. package/dist/{mcp-servers-DC4QRPUI.d.ts → mcp-servers-2x4w6Jn9.d.ts} +3 -3
  36. package/dist/models/index.d.ts +5 -5
  37. package/dist/models/index.js +74 -30
  38. package/dist/models/index.js.map +1 -1
  39. package/dist/{models-registry-B_siPxqN.d.ts → models-registry-DmJlKuNp.d.ts} +1 -1
  40. package/dist/{multi-agent-coordinator-CK5Jdj9K.d.ts → multi-agent-coordinator-DyCkCZnU.d.ts} +1 -1
  41. package/dist/{null-fleet-bus-DgvD4SCO.d.ts → null-fleet-bus-CG9QY2aP.d.ts} +6 -6
  42. package/dist/observability/index.d.ts +2 -2
  43. package/dist/{parallel-eternal-engine-bK0JQBR_.d.ts → parallel-eternal-engine-Jw9uhEoT.d.ts} +9 -9
  44. package/dist/{path-resolver-BPEDlN38.d.ts → path-resolver-Dy2ej-gE.d.ts} +3 -3
  45. package/dist/{permission-4yvGmMRB.d.ts → permission-B9SB45lp.d.ts} +1 -1
  46. package/dist/{permission-policy-C6XpsBOy.d.ts → permission-policy-CkjSXabK.d.ts} +2 -2
  47. package/dist/{pipeline-CXCeMz8J.d.ts → pipeline-DPDxH_7m.d.ts} +3 -3
  48. package/dist/{plan-templates-BvzRBkJc.d.ts → plan-templates-CzD9GnAU.d.ts} +32 -8
  49. package/dist/{provider-runner-C5aQpDWE.d.ts → provider-runner-DMa70ODu.d.ts} +3 -3
  50. package/dist/{retry-policy-CFhdtRzz.d.ts → retry-policy-CN0khdlj.d.ts} +1 -1
  51. package/dist/sdd/index.d.ts +8 -8
  52. package/dist/sdd/index.js +274 -93
  53. package/dist/sdd/index.js.map +1 -1
  54. package/dist/{secret-vault-CxiVLbt1.d.ts → secret-vault-B2yw84VT.d.ts} +43 -4
  55. package/dist/secret-vault-BAKpgFw_.d.ts +57 -0
  56. package/dist/security/index.d.ts +5 -5
  57. package/dist/security/index.js +204 -23
  58. package/dist/security/index.js.map +1 -1
  59. package/dist/{selector-gIuhRTkN.d.ts → selector-CzHh_igB.d.ts} +1 -1
  60. package/dist/{session-event-bridge-DkvvrpDt.d.ts → session-event-bridge-BUI6Jf-4.d.ts} +1 -1
  61. package/dist/{session-reader-KdfVwkKP.d.ts → session-reader-CMgdMSRP.d.ts} +1 -1
  62. package/dist/storage/index.d.ts +112 -15
  63. package/dist/storage/index.js +419 -81
  64. package/dist/storage/index.js.map +1 -1
  65. package/dist/tools/index.d.ts +2 -2
  66. package/dist/types/index.d.ts +21 -21
  67. package/dist/types/index.js +261 -53
  68. package/dist/types/index.js.map +1 -1
  69. package/dist/utils/index.d.ts +3 -3
  70. package/dist/utils/index.js +3 -5
  71. package/dist/utils/index.js.map +1 -1
  72. package/dist/{wstack-paths-CJjEwPXn.d.ts → wstack-paths-hOpNLmvf.d.ts} +2 -0
  73. package/package.json +1 -1
  74. package/skills/api-design/SKILL.md +1 -1
  75. package/skills/audit-log/SKILL.md +6 -6
  76. package/skills/bug-hunter/SKILL.md +5 -5
  77. package/skills/chimera/SKILL.md +4 -4
  78. package/skills/docker-deploy/SKILL.md +1 -1
  79. package/skills/git-flow/SKILL.md +3 -3
  80. package/skills/multi-agent/SKILL.md +3 -3
  81. package/skills/node-modern/SKILL.md +1 -0
  82. package/skills/observability/SKILL.md +2 -2
  83. package/skills/output-standards/SKILL.md +51 -28
  84. package/skills/refactor-planner/SKILL.md +3 -3
  85. package/skills/security-scanner/SKILL.md +4 -3
  86. package/skills/tech-stack/SKILL.md +1 -2
  87. package/dist/secret-vault-BJDY28ev.d.ts +0 -25
@@ -5089,6 +5089,7 @@ function resolveModelMatrix(matrix, role) {
5089
5089
 
5090
5090
  // src/coordination/subagent-budget.ts
5091
5091
  var TIMEOUT_PREEMPT_FRACTION = 0.85;
5092
+ var DECISION_TIMEOUT_MS = 6e4;
5092
5093
  var BudgetExceededError = class extends Error {
5093
5094
  kind;
5094
5095
  limit;
@@ -5118,6 +5119,31 @@ var BudgetThresholdSignal = class extends Error {
5118
5119
  };
5119
5120
  var SubagentBudget = class _SubagentBudget {
5120
5121
  limits;
5122
+ /** Patch one or more budget limits in-place after construction.
5123
+ * Used by the coordinator watchdog when granting an extension.
5124
+ * All fields are optional — only provided fields are updated.
5125
+ * This is the single write path for limit mutations so that future
5126
+ * validation or side-effects live in one place (M1). */
5127
+ patchLimits(ext) {
5128
+ if (ext.maxIterations !== void 0) {
5129
+ this.limits.maxIterations = ext.maxIterations;
5130
+ }
5131
+ if (ext.maxToolCalls !== void 0) {
5132
+ this.limits.maxToolCalls = ext.maxToolCalls;
5133
+ }
5134
+ if (ext.maxTokens !== void 0) {
5135
+ this.limits.maxTokens = ext.maxTokens;
5136
+ }
5137
+ if (ext.maxCostUsd !== void 0) {
5138
+ this.limits.maxCostUsd = ext.maxCostUsd;
5139
+ }
5140
+ if (ext.timeoutMs !== void 0) {
5141
+ this.limits.timeoutMs = ext.timeoutMs;
5142
+ }
5143
+ if (ext.idleTimeoutMs !== void 0) {
5144
+ this.limits.idleTimeoutMs = ext.idleTimeoutMs;
5145
+ }
5146
+ }
5121
5147
  iterations = 0;
5122
5148
  toolCalls = 0;
5123
5149
  tokenInput = 0;
@@ -5138,12 +5164,44 @@ var SubagentBudget = class _SubagentBudget {
5138
5164
  * or hung listener (Director not built / event filter detached mid-run)
5139
5165
  * leaves the budget over-limit and never enforces anything.
5140
5166
  */
5141
- static DECISION_TIMEOUT_MS = 6e4;
5167
+ static DECISION_TIMEOUT_MS = DECISION_TIMEOUT_MS;
5142
5168
  /**
5143
5169
  * Injected by the runner when wiring the budget to its EventBus.
5144
5170
  * Used to emit `budget.threshold_reached` events in `'auto'` mode.
5145
5171
  */
5146
5172
  _events;
5173
+ /**
5174
+ * Guard against dual-path races between the coordinator watchdog
5175
+ * (`executeWithTimeout`) and the budget's own `checkTimeout()`.
5176
+ * Both paths detect `elapsed >= timeoutMs` and can emit
5177
+ * `budget.threshold_reached` for kind `'timeout'` simultaneously.
5178
+ * Set to the current `timeoutMs` ceiling by the coordinator BEFORE
5179
+ * calling `onThreshold`, and cleared after the negotiation resolves.
5180
+ * `checkTimeout()` skips its wall-clock check while this is set so
5181
+ * the coordinator's watchdog is the sole source of wall-clock timeout
5182
+ * events — `checkTimeout()` focuses exclusively on `idle_timeout`.
5183
+ */
5184
+ _watchdogActive;
5185
+ /** Returns the timeout ceiling currently being negotiated by the watchdog,
5186
+ * or `undefined` when no wall-clock negotiation is in flight.
5187
+ * Used by `executeWithTimeout` to detect a stale lock (M3). */
5188
+ get watchdogActive() {
5189
+ return this._watchdogActive;
5190
+ }
5191
+ /** Called by the coordinator watchdog BEFORE calling `onThreshold` so that
5192
+ * `checkTimeout()` skips its wall-clock check for this ceiling. Prevents
5193
+ * the budget's own `checkTimeout()` from emitting a second
5194
+ * `budget.threshold_reached` event while the watchdog is already
5195
+ * negotiating the same wall-clock deadline (C1). */
5196
+ setWatchdogNegotiation(timeoutMs) {
5197
+ this._watchdogActive = timeoutMs;
5198
+ }
5199
+ /** Clears the watchdog guard after negotiation resolves. Called in the
5200
+ * `finally` block of both the pre-empt and deadline branches so it fires
5201
+ * on every exit path: grant, deny, throw, or error. */
5202
+ clearWatchdogNegotiation() {
5203
+ this._watchdogActive = void 0;
5204
+ }
5147
5205
  /**
5148
5206
  * Negotiation mode — controls whether a threshold hit tries to emit
5149
5207
  * `budget.threshold_reached` and wait for a coordinator decision, or
@@ -5244,7 +5302,8 @@ var SubagentBudget = class _SubagentBudget {
5244
5302
  if (this.limits.idleTimeoutMs !== void 0 && idle > this.limits.idleTimeoutMs) {
5245
5303
  exceeded.push({ kind: "idle_timeout", used: idle, limit: this.limits.idleTimeoutMs });
5246
5304
  }
5247
- if (this.limits.timeoutMs !== void 0 && elapsedMs > this.limits.timeoutMs) {
5305
+ const wallOwnedByWatchdog = this._onThreshold !== void 0 && this._watchdogActive === this.limits.timeoutMs;
5306
+ if (this.limits.timeoutMs !== void 0 && elapsedMs > this.limits.timeoutMs && !wallOwnedByWatchdog) {
5248
5307
  exceeded.push({ kind: "timeout", used: elapsedMs, limit: this.limits.timeoutMs });
5249
5308
  }
5250
5309
  }
@@ -5258,19 +5317,99 @@ var SubagentBudget = class _SubagentBudget {
5258
5317
  throw new BudgetExceededError(first2.kind, first2.limit, first2.used);
5259
5318
  }
5260
5319
  const bus = this._events;
5261
- if (!bus || !bus.hasListenerFor("budget.threshold_reached")) {
5320
+ if (!bus) {
5262
5321
  const first2 = exceeded[0] ?? { kind: "iterations", limit: 0, used: 0 };
5263
5322
  throw new BudgetExceededError(first2.kind, first2.limit, first2.used);
5264
5323
  }
5324
+ const first = exceeded[0] ?? { kind: "iterations", limit: 0, used: 0 };
5325
+ if (bus.hasListenerFor("budget.threshold_reached")) {
5326
+ for (const entry of exceeded) {
5327
+ if (this._pendingNegotiations.has(entry.kind)) continue;
5328
+ this._pendingNegotiations.set(entry.kind, this._negotiateExtension(entry));
5329
+ }
5330
+ const decision = this._pendingNegotiations.get(first.kind);
5331
+ if (!decision) throw new Error(`No pending negotiation for ${first.kind}`);
5332
+ throw new BudgetThresholdSignal(first.kind, first.limit, first.used, decision);
5333
+ }
5334
+ let hardStop = null;
5265
5335
  for (const entry of exceeded) {
5266
5336
  if (this._pendingNegotiations.has(entry.kind)) continue;
5267
- const decision2 = this._negotiateExtension(entry.kind, exceeded);
5268
- this._pendingNegotiations.set(entry.kind, decision2);
5337
+ const marker = Promise.resolve("stop");
5338
+ this._pendingNegotiations.set(entry.kind, marker);
5339
+ void marker.finally(() => this._pendingNegotiations.delete(entry.kind));
5340
+ const sync = this._invokeHandlerSync(entry);
5341
+ if (!sync) hardStop ??= new BudgetExceededError(entry.kind, entry.limit, entry.used);
5342
+ }
5343
+ if (hardStop) throw hardStop;
5344
+ return exceeded;
5345
+ }
5346
+ /**
5347
+ * Invoke `onThreshold` once for `entry` on the NO-LISTENER path and report
5348
+ * whether it decided synchronously. Returns `true` when the handler returned
5349
+ * a synchronous decision (already honored — an `extend` patched the limits),
5350
+ * or `false` when it returned a Promise (async; the caller hard-stops, since
5351
+ * there is no listener to resolve the negotiation). The handler is given the
5352
+ * full info shape (`requestDecision` plus direct `extend`/`deny`) so both
5353
+ * recording handlers and policy handlers work without a wired listener.
5354
+ */
5355
+ _invokeHandlerSync(entry) {
5356
+ const handler = this._onThreshold;
5357
+ if (!handler) return false;
5358
+ let extendArg;
5359
+ const result = handler({
5360
+ kind: entry.kind,
5361
+ used: entry.used,
5362
+ limit: entry.limit,
5363
+ requestDecision: () => this._busRequestDecision(entry),
5364
+ // Direct hooks for synchronous policy/recording handlers.
5365
+ extend: (extra) => {
5366
+ extendArg = extra;
5367
+ },
5368
+ deny: () => {
5369
+ }
5370
+ });
5371
+ if (result && typeof result.then === "function") return false;
5372
+ if (result === "throw") return false;
5373
+ if (result && typeof result === "object" && "extend" in result) {
5374
+ extendArg = result.extend;
5269
5375
  }
5270
- const first = exceeded[0] ?? { kind: "iterations", limit: 0, used: 0 };
5271
- const decision = this._pendingNegotiations.get(first.kind);
5272
- if (!decision) throw new Error(`No pending negotiation for ${first.kind}`);
5273
- throw new BudgetThresholdSignal(first.kind, first.limit, first.used, decision);
5376
+ if (extendArg) this.patchLimits(extendArg);
5377
+ return true;
5378
+ }
5379
+ /**
5380
+ * Emit `budget.threshold_reached` and resolve to the listener's verdict.
5381
+ * Resolves to `'stop'` immediately when there is no listener (or no bus) so
5382
+ * no negotiation can hang and no fallback timer leaks. Mirrors the
5383
+ * coordinator watchdog's own request path so both agree on the no-listener
5384
+ * default.
5385
+ */
5386
+ _busRequestDecision(entry) {
5387
+ const bus = this._events;
5388
+ if (!bus || !bus.hasListenerFor("budget.threshold_reached")) {
5389
+ return Promise.resolve("stop");
5390
+ }
5391
+ return new Promise((resolve3) => {
5392
+ let resolved = false;
5393
+ const respond = (d) => {
5394
+ if (resolved) return;
5395
+ resolved = true;
5396
+ clearTimeout(fallback);
5397
+ resolve3(d);
5398
+ };
5399
+ const fallback = setTimeout(() => respond("stop"), _SubagentBudget.DECISION_TIMEOUT_MS);
5400
+ bus.emit("budget.threshold_reached", {
5401
+ kind: entry.kind,
5402
+ used: entry.used,
5403
+ limit: entry.limit,
5404
+ timeoutMs: _SubagentBudget.DECISION_TIMEOUT_MS,
5405
+ // deny() wins over a same-dispatch extend(): a listener that both grants
5406
+ // and denies (or two listeners disagreeing) is resolved as a stop. The
5407
+ // grant is deferred a microtask so a synchronous deny in the same emit
5408
+ // pre-empts it; async grants still resolve normally.
5409
+ extend: (extra) => queueMicrotask(() => respond({ extend: extra })),
5410
+ deny: () => respond("stop")
5411
+ });
5412
+ });
5274
5413
  }
5275
5414
  /**
5276
5415
  * Per-kind in-flight negotiation Promises. Each budget kind can have its
@@ -5290,77 +5429,33 @@ var SubagentBudget = class _SubagentBudget {
5290
5429
  * `{ extend: {} }` — keep going without patching; next overrun fires
5291
5430
  * a fresh signal.
5292
5431
  */
5293
- async _negotiateExtension(kind, exceeded) {
5432
+ async _negotiateExtension(entry) {
5294
5433
  if (!this._onThreshold) {
5295
5434
  return "stop";
5296
5435
  }
5297
5436
  try {
5298
- const first = exceeded[0] ?? { kind: "iterations", limit: 0, used: 0 };
5299
5437
  const result = this._onThreshold({
5300
- kind: first.kind,
5301
- used: first.used,
5302
- limit: first.limit,
5303
- requestDecision: () => {
5304
- const bus = this._events;
5305
- if (!bus || !bus.hasListenerFor("budget.threshold_reached")) {
5306
- return Promise.resolve("stop");
5307
- }
5308
- return new Promise((resolve3) => {
5309
- let resolved = false;
5310
- const respond = (d) => {
5311
- if (resolved) return;
5312
- resolved = true;
5313
- resolve3(d);
5314
- };
5315
- const fallback = setTimeout(
5316
- () => respond("stop"),
5317
- _SubagentBudget.DECISION_TIMEOUT_MS
5318
- );
5319
- for (const { kind: kind2, used, limit } of exceeded) {
5320
- bus.emit("budget.threshold_reached", {
5321
- kind: kind2,
5322
- used,
5323
- limit,
5324
- timeoutMs: _SubagentBudget.DECISION_TIMEOUT_MS,
5325
- extend: (extra) => {
5326
- clearTimeout(fallback);
5327
- respond({ extend: extra });
5328
- },
5329
- deny: () => {
5330
- clearTimeout(fallback);
5331
- respond("stop");
5332
- }
5333
- });
5334
- }
5335
- });
5438
+ kind: entry.kind,
5439
+ used: entry.used,
5440
+ limit: entry.limit,
5441
+ // One event for THIS kind only — each exceeded kind has its own
5442
+ // negotiation (and its own resolve), so there is no cross-kind
5443
+ // first-wins drop and no O(N^2) re-emission.
5444
+ requestDecision: () => this._busRequestDecision(entry),
5445
+ extend: (extra) => {
5446
+ this.patchLimits(extra);
5447
+ },
5448
+ deny: () => {
5336
5449
  }
5337
5450
  });
5338
5451
  if (result === "throw") return "stop";
5339
5452
  if (result === "continue") return { extend: {} };
5340
5453
  const decision = await result;
5341
5454
  if (decision === "stop") return "stop";
5342
- const ext = decision.extend;
5343
- if (ext.maxIterations !== void 0) {
5344
- this.limits.maxIterations = ext.maxIterations;
5345
- }
5346
- if (ext.maxToolCalls !== void 0) {
5347
- this.limits.maxToolCalls = ext.maxToolCalls;
5348
- }
5349
- if (ext.maxTokens !== void 0) {
5350
- this.limits.maxTokens = ext.maxTokens;
5351
- }
5352
- if (ext.maxCostUsd !== void 0) {
5353
- this.limits.maxCostUsd = ext.maxCostUsd;
5354
- }
5355
- if (ext.timeoutMs !== void 0) {
5356
- this.limits.timeoutMs = ext.timeoutMs;
5357
- }
5358
- if (ext.idleTimeoutMs !== void 0) {
5359
- this.limits.idleTimeoutMs = ext.idleTimeoutMs;
5360
- }
5455
+ this.patchLimits(decision.extend);
5361
5456
  return decision;
5362
5457
  } finally {
5363
- this._pendingNegotiations.delete(kind);
5458
+ this._pendingNegotiations.delete(entry.kind);
5364
5459
  }
5365
5460
  }
5366
5461
  recordIteration() {
@@ -5403,7 +5498,8 @@ var SubagentBudget = class _SubagentBudget {
5403
5498
  const { timeoutMs, idleTimeoutMs } = this.limits;
5404
5499
  if (timeoutMs === void 0 && idleTimeoutMs === void 0) return;
5405
5500
  const elapsed = Date.now() - this.startTime;
5406
- const wallTripped = timeoutMs !== void 0 && elapsed > timeoutMs;
5501
+ const wallSkipped = this._onThreshold !== void 0 && this._watchdogActive !== void 0 && timeoutMs !== void 0 && this._watchdogActive === timeoutMs;
5502
+ const wallTripped = wallSkipped ? false : timeoutMs !== void 0 && elapsed > timeoutMs;
5407
5503
  const idleTripped = idleTimeoutMs !== void 0 && this.idleMs() > idleTimeoutMs;
5408
5504
  if (!wallTripped && !idleTripped) return;
5409
5505
  void this.checkLimits(elapsed);
@@ -6025,6 +6121,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6025
6121
  terminating = /* @__PURE__ */ new Set();
6026
6122
  constructor(config, options = {}) {
6027
6123
  super();
6124
+ this.setMaxListeners(0);
6028
6125
  this.coordinatorId = config.coordinatorId;
6029
6126
  this.config = config;
6030
6127
  this.runner = options.runner;
@@ -6419,7 +6516,13 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6419
6516
  let result;
6420
6517
  budget.start();
6421
6518
  try {
6422
- const outcome = await this.executeWithTimeout(this.runner, task, runCtx, budget);
6519
+ const outcome = await this.executeWithTimeout(
6520
+ this.runner,
6521
+ task,
6522
+ runCtx,
6523
+ budget,
6524
+ subagent.config.preemptFraction
6525
+ );
6423
6526
  result = {
6424
6527
  subagentId,
6425
6528
  taskId: task.id,
@@ -6446,7 +6549,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6446
6549
  }
6447
6550
  this.recordCompletion(result);
6448
6551
  }
6449
- async executeWithTimeout(runner, task, ctx, budget) {
6552
+ async executeWithTimeout(runner, task, ctx, budget, preemptFraction = TIMEOUT_PREEMPT_FRACTION) {
6450
6553
  const initialTimeoutMs = budget.limits.timeoutMs;
6451
6554
  const idleLimitMs = budget.limits.idleTimeoutMs;
6452
6555
  if (initialTimeoutMs === void 0 && idleLimitMs === void 0) {
@@ -6454,8 +6557,21 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6454
6557
  }
6455
6558
  const start = Date.now();
6456
6559
  let timer = null;
6457
- let preemptedForLimit = null;
6560
+ let PreemptState;
6561
+ ((PreemptState2) => {
6562
+ PreemptState2["ACTIVE"] = "active";
6563
+ PreemptState2["LOCKED"] = "locked";
6564
+ })(PreemptState || (PreemptState = {}));
6565
+ let preemptedCeiling = null;
6566
+ let preemptState = "active" /* ACTIVE */;
6567
+ let lastGrantActivityTs = -1;
6458
6568
  const timeoutPromise = new Promise((_, reject) => {
6569
+ const terminate = (kind, limit, used) => {
6570
+ this.subagents.get(ctx.subagentId)?.abortController.abort();
6571
+ reject(
6572
+ budget._events?.hasListenerFor("budget.threshold_reached") ? new Error(`subagent stopped: budget ${kind} (limit=${limit}, used=${used})`) : new BudgetExceededError(kind, limit, used)
6573
+ );
6574
+ };
6459
6575
  const armFor = (ms) => {
6460
6576
  if (timer) clearTimeout(timer);
6461
6577
  timer = setTimeout(onTick, Math.max(0, ms));
@@ -6464,7 +6580,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6464
6580
  const wallLimit = budget.limits.timeoutMs ?? initialTimeoutMs;
6465
6581
  const wallRemaining = initialTimeoutMs === void 0 ? Number.POSITIVE_INFINITY : wallLimit - (Date.now() - start);
6466
6582
  const idleRemaining = idleLimitMs === void 0 ? Number.POSITIVE_INFINITY : (budget.limits.idleTimeoutMs ?? idleLimitMs) - budget.idleMs();
6467
- const preemptRemaining = initialTimeoutMs === void 0 || preemptedForLimit === wallLimit ? Number.POSITIVE_INFINITY : wallLimit * TIMEOUT_PREEMPT_FRACTION - (Date.now() - start);
6583
+ const preemptRemaining = initialTimeoutMs === void 0 || preemptedCeiling === wallLimit ? Number.POSITIVE_INFINITY : wallLimit * preemptFraction - (Date.now() - start);
6468
6584
  armFor(Math.max(25, Math.min(wallRemaining, idleRemaining, preemptRemaining)));
6469
6585
  };
6470
6586
  const negotiateTimeout = async (used, limit) => {
@@ -6474,16 +6590,42 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6474
6590
  kind: "timeout",
6475
6591
  used,
6476
6592
  limit,
6477
- requestDecision: () => new Promise((resolveDecision) => {
6478
- budget._events?.emit("budget.threshold_reached", {
6479
- kind: "timeout",
6480
- used,
6481
- limit,
6482
- timeoutMs: 6e4,
6483
- extend: (extra) => resolveDecision({ extend: extra }),
6484
- deny: () => resolveDecision("stop")
6593
+ requestDecision: () => {
6594
+ if (!budget._events?.hasListenerFor("budget.threshold_reached")) {
6595
+ return Promise.resolve("stop");
6596
+ }
6597
+ return new Promise((resolveDecision) => {
6598
+ let settled = false;
6599
+ const resolve3 = (d) => {
6600
+ if (settled) return;
6601
+ settled = true;
6602
+ resolveDecision(d);
6603
+ };
6604
+ const fallback = setTimeout(() => resolve3("stop"), DECISION_TIMEOUT_MS);
6605
+ budget._events?.emit("budget.threshold_reached", {
6606
+ kind: "timeout",
6607
+ used,
6608
+ limit,
6609
+ // Informational: the budget's own decision deadline. Listeners may use
6610
+ // this to display a countdown. The coordinator does NOT enforce it —
6611
+ // it is the budget's own `setTimeout(fallback)` that races against
6612
+ // the listener's `extend()`/`deny()` call to guarantee progress.
6613
+ timeoutMs: DECISION_TIMEOUT_MS,
6614
+ // deny() wins over a same-dispatch extend(): defer the grant a
6615
+ // microtask so a synchronous deny in the same emit pre-empts it
6616
+ // (a listener that both grants and denies, or two listeners
6617
+ // disagreeing, resolves as a stop). Async grants still resolve.
6618
+ extend: (extra) => {
6619
+ clearTimeout(fallback);
6620
+ queueMicrotask(() => resolve3({ extend: extra }));
6621
+ },
6622
+ deny: () => {
6623
+ clearTimeout(fallback);
6624
+ resolve3("stop");
6625
+ }
6626
+ });
6485
6627
  });
6486
- })
6628
+ }
6487
6629
  });
6488
6630
  return typeof result === "string" ? result : await result;
6489
6631
  };
@@ -6494,21 +6636,45 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6494
6636
  const wallExceeded = wallLimit !== void 0 && elapsed >= wallLimit;
6495
6637
  const idleExceeded = idleLimit !== void 0 && budget.idleMs() >= idleLimit;
6496
6638
  if (idleExceeded && !wallExceeded) {
6639
+ budget._events?.emit("budget.threshold_reached", {
6640
+ kind: "idle_timeout",
6641
+ used: budget.idleMs(),
6642
+ limit: idleLimit ?? 0,
6643
+ timeoutMs: DECISION_TIMEOUT_MS,
6644
+ extend: () => {
6645
+ },
6646
+ deny: () => {
6647
+ }
6648
+ });
6497
6649
  this.subagents.get(ctx.subagentId)?.abortController.abort();
6498
- reject(new BudgetExceededError("timeout", idleLimit ?? 0, budget.idleMs()));
6650
+ reject(new BudgetExceededError("idle_timeout", idleLimit ?? 0, budget.idleMs()));
6499
6651
  return;
6500
6652
  }
6501
- if (wallLimit !== void 0 && !wallExceeded && budget.onThreshold && preemptedForLimit !== wallLimit && elapsed >= wallLimit * TIMEOUT_PREEMPT_FRACTION) {
6653
+ if (wallLimit !== void 0 && !wallExceeded && budget.onThreshold && preemptState === "active" /* ACTIVE */ && elapsed >= wallLimit * preemptFraction) {
6654
+ const activityTs = Date.now() - budget.idleMs();
6655
+ if (activityTs <= lastGrantActivityTs) {
6656
+ preemptState = "locked" /* LOCKED */;
6657
+ preemptedCeiling = wallLimit;
6658
+ scheduleNext();
6659
+ return;
6660
+ }
6661
+ budget.setWatchdogNegotiation(wallLimit);
6502
6662
  try {
6503
6663
  const decision = await negotiateTimeout(elapsed, wallLimit);
6504
6664
  if (typeof decision !== "string" && decision.extend.timeoutMs !== void 0) {
6505
- budget.limits.timeoutMs = decision.extend.timeoutMs;
6506
- preemptedForLimit = null;
6665
+ budget.patchLimits({ timeoutMs: decision.extend.timeoutMs });
6666
+ lastGrantActivityTs = Date.now() - budget.idleMs();
6667
+ preemptState = "active" /* ACTIVE */;
6668
+ preemptedCeiling = null;
6507
6669
  } else {
6508
- preemptedForLimit = wallLimit;
6670
+ preemptState = "locked" /* LOCKED */;
6671
+ preemptedCeiling = wallLimit;
6509
6672
  }
6510
6673
  } catch {
6511
- preemptedForLimit = wallLimit;
6674
+ preemptState = "locked" /* LOCKED */;
6675
+ preemptedCeiling = wallLimit;
6676
+ } finally {
6677
+ budget.clearWatchdogNegotiation();
6512
6678
  }
6513
6679
  scheduleNext();
6514
6680
  return;
@@ -6523,26 +6689,41 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6523
6689
  reject(new BudgetExceededError("timeout", limit, elapsed));
6524
6690
  return;
6525
6691
  }
6692
+ budget.setWatchdogNegotiation(limit);
6526
6693
  try {
6527
6694
  const decision = await negotiateTimeout(elapsed, limit);
6528
- if (decision === "continue" || decision === "throw" || decision === "stop") {
6529
- preemptedForLimit = null;
6695
+ if (decision === "throw") {
6696
+ terminate("timeout", limit, elapsed);
6697
+ return;
6698
+ }
6699
+ if (decision === "continue") {
6700
+ preemptState = "locked" /* LOCKED */;
6701
+ preemptedCeiling = wallLimit;
6530
6702
  armFor(Math.max(1e3, limit));
6531
6703
  return;
6532
6704
  }
6705
+ if (decision === "stop") {
6706
+ terminate("timeout", limit, elapsed);
6707
+ return;
6708
+ }
6533
6709
  if (decision.extend.timeoutMs !== void 0) {
6534
- budget.limits.timeoutMs = decision.extend.timeoutMs;
6535
- preemptedForLimit = null;
6710
+ budget.patchLimits({ timeoutMs: decision.extend.timeoutMs });
6711
+ lastGrantActivityTs = Date.now() - budget.idleMs();
6712
+ preemptState = "active" /* ACTIVE */;
6713
+ preemptedCeiling = null;
6536
6714
  scheduleNext();
6537
6715
  return;
6538
6716
  }
6539
- this.subagents.get(ctx.subagentId)?.abortController.abort();
6540
- reject(new BudgetExceededError("timeout", limit, elapsed));
6717
+ terminate("timeout", limit, elapsed);
6718
+ return;
6541
6719
  } catch (err) {
6542
6720
  this.subagents.get(ctx.subagentId)?.abortController.abort();
6543
6721
  reject(
6544
6722
  err instanceof BudgetExceededError ? err : new BudgetExceededError("timeout", limit, elapsed)
6545
6723
  );
6724
+ return;
6725
+ } finally {
6726
+ budget.clearWatchdogNegotiation();
6546
6727
  }
6547
6728
  };
6548
6729
  scheduleNext();
@@ -8516,11 +8697,34 @@ var DefaultSessionStore = class _DefaultSessionStore {
8516
8697
  dir;
8517
8698
  events;
8518
8699
  secretScrubber;
8700
+ /**
8701
+ * In-memory cache for load() results, keyed by session ID. The cache is
8702
+ * invalidated when the file's mtimeMs or size changes (indicating the
8703
+ * file was written to). This eliminates redundant full-file reads and
8704
+ * JSON parses when the same session is loaded multiple times within the
8705
+ * store's lifetime (e.g., webui session detail views, list() fallbacks).
8706
+ *
8707
+ * Max size is capped to prevent unbounded memory growth in long-running
8708
+ * processes. When the limit is reached, the oldest entry is evicted.
8709
+ */
8710
+ _loadCache = /* @__PURE__ */ new Map();
8711
+ static LOAD_CACHE_MAX_ENTRIES = 50;
8519
8712
  constructor(opts) {
8520
8713
  this.dir = opts.dir;
8521
8714
  this.events = opts.events;
8522
8715
  this.secretScrubber = opts.secretScrubber;
8523
8716
  }
8717
+ /**
8718
+ * Clear the load() cache. Useful for testing or when the caller knows
8719
+ * the file has changed externally (e.g., another process wrote to it).
8720
+ */
8721
+ clearLoadCache(sessionId) {
8722
+ if (sessionId !== void 0) {
8723
+ this._loadCache.delete(sessionId);
8724
+ } else {
8725
+ this._loadCache.clear();
8726
+ }
8727
+ }
8524
8728
  // ── Storage event helpers ───────────────────────────────────────────────────
8525
8729
  emitRead(sessionId, filePath, operation, outcome, durationMs, error) {
8526
8730
  this.events?.emit("storage.read", {
@@ -8663,7 +8867,20 @@ var DefaultSessionStore = class _DefaultSessionStore {
8663
8867
  const t0 = Date.now();
8664
8868
  let outcome = "success";
8665
8869
  let errorMsg;
8870
+ let cacheHit = false;
8666
8871
  try {
8872
+ let stat6;
8873
+ try {
8874
+ const s = await fsp6.stat(file);
8875
+ stat6 = { mtimeMs: s.mtimeMs, size: s.size };
8876
+ } catch (err) {
8877
+ throw err;
8878
+ }
8879
+ const cached = this._loadCache.get(id);
8880
+ if (cached && cached.mtimeMs === stat6.mtimeMs && cached.size === stat6.size) {
8881
+ cacheHit = true;
8882
+ return cached.data;
8883
+ }
8667
8884
  const raw = await fsp6.readFile(file, "utf8");
8668
8885
  const lines = raw.split("\n").filter((l) => l.trim());
8669
8886
  const events = [];
@@ -8679,13 +8896,30 @@ var DefaultSessionStore = class _DefaultSessionStore {
8679
8896
  const meta = this.metaFromEvents(id, events);
8680
8897
  const { messages, usage } = this.replay(events, id);
8681
8898
  const toolCallEnds = extractToolCallEnds(events);
8682
- return { metadata: meta, events, messages, usage, toolCallEnds };
8899
+ const data = { metadata: meta, events, messages, usage, toolCallEnds };
8900
+ if (this._loadCache.size >= _DefaultSessionStore.LOAD_CACHE_MAX_ENTRIES) {
8901
+ const oldest = this._loadCache.keys().next().value;
8902
+ if (oldest !== void 0) {
8903
+ this._loadCache.delete(oldest);
8904
+ }
8905
+ }
8906
+ this._loadCache.set(id, { mtimeMs: stat6.mtimeMs, size: stat6.size, data });
8907
+ return data;
8683
8908
  } catch (err) {
8684
8909
  outcome = "failure";
8685
8910
  errorMsg = toErrorMessage(err);
8686
8911
  throw err;
8687
8912
  } finally {
8688
8913
  this.emitRead(id, file, "load", outcome, Date.now() - t0, errorMsg);
8914
+ if (cacheHit) {
8915
+ this.events?.emit("storage.cache_hit", {
8916
+ sessionId: id,
8917
+ store: "session",
8918
+ filePath: file,
8919
+ operation: "load",
8920
+ durationMs: Date.now() - t0
8921
+ });
8922
+ }
8689
8923
  }
8690
8924
  }
8691
8925
  async list(limit = 20) {
@@ -9692,6 +9926,7 @@ function attachAutoExtend(events, policy = {}) {
9692
9926
  const extendCounts = /* @__PURE__ */ new Map();
9693
9927
  let progress = 0;
9694
9928
  let lastTimeoutProgress = -1;
9929
+ let lastSeenKey = null;
9695
9930
  const unsubs = [
9696
9931
  events.on("tool.executed", () => {
9697
9932
  progress++;
@@ -9701,6 +9936,9 @@ function attachAutoExtend(events, policy = {}) {
9701
9936
  }),
9702
9937
  events.on("budget.threshold_reached", (e) => {
9703
9938
  const { kind, limit, extend, deny } = e;
9939
+ const key = `${kind}:${limit}`;
9940
+ if (key === lastSeenKey) return;
9941
+ lastSeenKey = key;
9704
9942
  if (kind === "timeout" || kind === "idle_timeout") {
9705
9943
  if (progress > lastTimeoutProgress) {
9706
9944
  lastTimeoutProgress = progress;
@@ -10410,7 +10648,8 @@ var BrainMonitor = class {
10410
10648
  id: "steer",
10411
10649
  label: "Steer the agent with corrective guidance",
10412
10650
  consequence: "A steer message is injected before its next step.",
10413
- risk: "low"
10651
+ risk: "low",
10652
+ recommended: true
10414
10653
  },
10415
10654
  {
10416
10655
  id: "continue",
@@ -10419,9 +10658,9 @@ var BrainMonitor = class {
10419
10658
  }
10420
10659
  ],
10421
10660
  risk: "medium",
10422
- // Without an LLM layer the policy brain resolves this fallback to
10423
- // "continue" the monitor observes but never interferes.
10424
- fallback: "continue"
10661
+ // 'ask_human' routes to the LLM-backed autonomous layer via
10662
+ // createTieredBrainArbiter before any human escalation.
10663
+ fallback: "ask_human"
10425
10664
  };
10426
10665
  const decision = await this.opts.brain.decide(request);
10427
10666
  const intervened = await this.maybeIntervene(kind, request, decision);
@@ -11518,6 +11757,10 @@ function makeDependencyWatcherConfig(opts) {
11518
11757
  return {
11519
11758
  watchPaths: unique,
11520
11759
  debounceMs,
11760
+ dispose() {
11761
+ for (const t of pending.values()) clearTimeout(t);
11762
+ pending.clear();
11763
+ },
11521
11764
  async onChange(entry) {
11522
11765
  if (entry.event === "delete") return;
11523
11766
  if (!matchesPattern(entry.path)) return;
@@ -11935,6 +12178,10 @@ var KnowledgeGraph = class {
11935
12178
  pendingDeliveries = /* @__PURE__ */ new Map();
11936
12179
  filePath;
11937
12180
  graphFilePath;
12181
+ /** Exposed for unit-testing only: read current index contents. */
12182
+ getIndex() {
12183
+ return this.index;
12184
+ }
11938
12185
  constructor(sessionDir) {
11939
12186
  this.filePath = path5.join(sessionDir, "_knowledge_graph");
11940
12187
  this.graphFilePath = path5.join(this.filePath, "graph.jsonl");
@@ -11947,7 +12194,7 @@ var KnowledgeGraph = class {
11947
12194
  async add(node) {
11948
12195
  const full = { id: randomUUID(), ...node };
11949
12196
  this.nodes.set(full.id, full);
11950
- this._index(full);
12197
+ this._addToIndex(full, this._indexKeys(full));
11951
12198
  await this._persist(full);
11952
12199
  this._deliver(full);
11953
12200
  return full;
@@ -11956,8 +12203,10 @@ var KnowledgeGraph = class {
11956
12203
  async update(id, patch) {
11957
12204
  const existing = this.nodes.get(id);
11958
12205
  if (!existing) return null;
12206
+ this._removeFromIndex(existing, this._indexKeys(existing));
11959
12207
  const updated = { ...existing, ...patch };
11960
12208
  this.nodes.set(id, updated);
12209
+ this._addToIndex(updated, this._indexKeys(updated));
11961
12210
  this._deliver(updated);
11962
12211
  await this._append(updated);
11963
12212
  return updated;
@@ -12043,15 +12292,10 @@ var KnowledgeGraph = class {
12043
12292
  return { passed: checks.every((c) => c.passed), checks };
12044
12293
  }
12045
12294
  // ── Private ────────────────────────────────────────────────────────────
12046
- _index(node) {
12047
- const add = (key) => {
12048
- let set = this.index.get(key);
12049
- if (!set) {
12050
- set = /* @__PURE__ */ new Set();
12051
- this.index.set(key, set);
12052
- }
12053
- set.add(node.id);
12054
- };
12295
+ /** Pure: compute the set of index keys a node would belong to. */
12296
+ _indexKeys(node) {
12297
+ const keys = /* @__PURE__ */ new Set();
12298
+ const add = (key) => keys.add(key);
12055
12299
  add(`type:${node.type}`);
12056
12300
  if (node.type === "fact") {
12057
12301
  const f = node;
@@ -12060,6 +12304,8 @@ var KnowledgeGraph = class {
12060
12304
  add(`by:${f.discoveredBy}`);
12061
12305
  for (const tag of f.tags) add(`tag:${tag}`);
12062
12306
  add(`key:${f.key}`);
12307
+ add(`subject:${f.subject}`);
12308
+ if (f.detail) add(`detail:${f.detail}`);
12063
12309
  }
12064
12310
  if (node.type === "goal") {
12065
12311
  const g = node;
@@ -12074,6 +12320,24 @@ var KnowledgeGraph = class {
12074
12320
  add(`by:${c.proposedBy}`);
12075
12321
  for (const g of c.satisfiesGoals) add(`goal:${g}`);
12076
12322
  }
12323
+ return keys;
12324
+ }
12325
+ /** Mutate the index: add a node's id to every set for the given keys. */
12326
+ _addToIndex(node, keys) {
12327
+ for (const key of keys) {
12328
+ let set = this.index.get(key);
12329
+ if (!set) {
12330
+ set = /* @__PURE__ */ new Set();
12331
+ this.index.set(key, set);
12332
+ }
12333
+ set.add(node.id);
12334
+ }
12335
+ }
12336
+ /** Remove a node's id from all index sets for the given keys. */
12337
+ _removeFromIndex(node, keys) {
12338
+ for (const key of keys) {
12339
+ this.index.get(key)?.delete(node.id);
12340
+ }
12077
12341
  }
12078
12342
  _matches(node, f) {
12079
12343
  if (f.type && node.type !== f.type) return false;
@@ -12123,11 +12387,15 @@ var KnowledgeGraph = class {
12123
12387
  try {
12124
12388
  const parsed = JSON.parse(line);
12125
12389
  if (parsed.op === "update") {
12390
+ const oldNode = this.nodes.get(parsed.node.id);
12391
+ if (oldNode) {
12392
+ this._removeFromIndex(oldNode, this._indexKeys(oldNode));
12393
+ }
12126
12394
  this.nodes.set(parsed.node.id, parsed.node);
12127
- this._index(parsed.node);
12395
+ this._addToIndex(parsed.node, this._indexKeys(parsed.node));
12128
12396
  } else {
12129
12397
  this.nodes.set(parsed.id, parsed);
12130
- this._index(parsed);
12398
+ this._addToIndex(parsed, this._indexKeys(parsed));
12131
12399
  }
12132
12400
  } catch {
12133
12401
  }
@@ -12428,7 +12696,7 @@ var TaskDAG = class {
12428
12696
  if (visited.has(current)) continue;
12429
12697
  visited.add(current);
12430
12698
  const node = this.nodes.get(current);
12431
- if (node) stack.push(...node.dependents);
12699
+ if (node) stack.push(...node.deps);
12432
12700
  }
12433
12701
  return false;
12434
12702
  }
@@ -12531,8 +12799,10 @@ var ConsensusProtocol = class {
12531
12799
  return this._resolve(changeId, change.votes, eligible);
12532
12800
  }
12533
12801
  // ── Private ───────────────────────────────────────────────────────────
12534
- _eligibleVoters(_change) {
12535
- return Array.from(this.voters.keys());
12802
+ _eligibleVoters(change) {
12803
+ return Array.from(this.voters.keys()).filter(
12804
+ (agentId) => agentId !== change.proposedBy
12805
+ );
12536
12806
  }
12537
12807
  _resolve(changeId, votes, eligible) {
12538
12808
  const totalEligible = eligible.length;
@@ -12577,7 +12847,7 @@ var ConsensusProtocol = class {
12577
12847
  if (!quorumMet) {
12578
12848
  return {
12579
12849
  changeId,
12580
- outcome: "pending",
12850
+ outcome: "quorum_not_met",
12581
12851
  votes,
12582
12852
  approveCount: approve.length,
12583
12853
  rejectCount: reject.length,
@@ -12954,7 +13224,7 @@ var AutonomousBrain = class {
12954
13224
  }
12955
13225
  return { type: "deny", reason: `Brain LLM failed: ${String(err)}` };
12956
13226
  }
12957
- void this._recordDecision({
13227
+ this._recordDecision({
12958
13228
  id,
12959
13229
  decisionType,
12960
13230
  question,
@@ -12963,6 +13233,7 @@ var AutonomousBrain = class {
12963
13233
  rationale: result.rationale,
12964
13234
  madeBy: "autonomous-brain",
12965
13235
  context: JSON.stringify(context)
13236
+ }).catch(() => {
12966
13237
  });
12967
13238
  if (requiresConsensus) {
12968
13239
  this._emit("brain.decision", { id, decisionType, optionId: result.optionId, rationale: result.rationale, consensusRequired: true });
@@ -13241,10 +13512,16 @@ var TaskAuctioneer = class {
13241
13512
  maxTasksPerAgent;
13242
13513
  minConfidence;
13243
13514
  // minimum dispatcher confidence to accept a bid
13515
+ maxBidRetries;
13516
+ // max republished attempts before marking task failed
13244
13517
  /** Pending bids keyed by taskId. */
13245
13518
  pendingBids = /* @__PURE__ */ new Map();
13246
13519
  /** Active bid windows keyed by taskId. */
13247
13520
  bidTimers = /* @__PURE__ */ new Map();
13521
+ /** FleetBus subscription disposers, detached in dispose(). */
13522
+ unsubs = [];
13523
+ /** How many times a task has been republished with no bids received. */
13524
+ bidRetryCounts = /* @__PURE__ */ new Map();
13248
13525
  /** Agent → current task count (from graph + in-flight). */
13249
13526
  agentTaskCounts = /* @__PURE__ */ new Map();
13250
13527
  constructor(opts) {
@@ -13255,8 +13532,26 @@ var TaskAuctioneer = class {
13255
13532
  this.bidWindowMs = opts.bidWindowMs ?? 3e4;
13256
13533
  this.maxTasksPerAgent = opts.maxTasksPerAgent ?? 3;
13257
13534
  this.minConfidence = opts.minConfidence ?? 0.3;
13258
- this.fleet?.filter("task:bid", (e) => this._onBidEvent(e));
13259
- this.fleet?.filter("task:claimed", (e) => this._onClaimedEvent(e));
13535
+ this.maxBidRetries = opts.maxBidRetries ?? 3;
13536
+ const offBid = this.fleet?.filter("task:bid", (e) => this._onBidEvent(e));
13537
+ const offClaimed = this.fleet?.filter("task:claimed", (e) => this._onClaimedEvent(e));
13538
+ if (offBid) this.unsubs.push(offBid);
13539
+ if (offClaimed) this.unsubs.push(offClaimed);
13540
+ }
13541
+ /**
13542
+ * Detach all FleetBus subscriptions and cancel any open bid-window timers.
13543
+ * Call when the owning coordinator stops/restarts so handlers and timers
13544
+ * don't accumulate across cycles.
13545
+ */
13546
+ dispose() {
13547
+ for (const off of this.unsubs.splice(0)) {
13548
+ try {
13549
+ off();
13550
+ } catch {
13551
+ }
13552
+ }
13553
+ for (const t of this.bidTimers.values()) clearTimeout(t);
13554
+ this.bidTimers.clear();
13260
13555
  }
13261
13556
  // ── Publish a task ────────────────────────────────────────────────────
13262
13557
  /**
@@ -13266,14 +13561,16 @@ var TaskAuctioneer = class {
13266
13561
  * If `targetAgent` is specified, the task is assigned directly without auction.
13267
13562
  */
13268
13563
  async publishTask(input) {
13564
+ const blockedBy = input.blockedBy ?? [];
13565
+ const hasOpenBlockers = blockedBy.length > 0 && blockedBy.some((id) => this.graph.get(id)?.status !== "done");
13269
13566
  const goal = await this.graph.add({
13270
13567
  type: "goal",
13271
13568
  title: input.title,
13272
13569
  description: input.description,
13273
- status: input.targetAgent ? "in_progress" : "pending",
13570
+ status: input.targetAgent ? "in_progress" : hasOpenBlockers ? "blocked" : "pending",
13274
13571
  priority: input.priority ?? "medium",
13275
13572
  assignee: input.targetAgent,
13276
- blockedBy: [],
13573
+ blockedBy,
13277
13574
  dependsOn: input.satisfiesGoals ?? [],
13278
13575
  createdBy: this.selfAgentId,
13279
13576
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -13290,6 +13587,12 @@ var TaskAuctioneer = class {
13290
13587
  });
13291
13588
  }
13292
13589
  }
13590
+ for (const blockerId of blockedBy) {
13591
+ const blocker = this.graph.get(blockerId);
13592
+ if (blocker && !blocker.children.includes(goal.id)) {
13593
+ await this.graph.update(blockerId, { children: [...blocker.children, goal.id] });
13594
+ }
13595
+ }
13293
13596
  if (input.targetAgent) {
13294
13597
  await this._assignDirect(goal.id, input.targetAgent);
13295
13598
  } else {
@@ -13401,9 +13704,12 @@ Priority: ${goal.priority}`,
13401
13704
  status: "done",
13402
13705
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
13403
13706
  });
13707
+ this.bidRetryCounts.delete(taskId);
13708
+ this.pendingBids.delete(taskId);
13709
+ this._cancelBidWindow(taskId);
13404
13710
  for (const childId of goal.children) {
13405
13711
  const child = this.graph.get(childId);
13406
- if (child) {
13712
+ if (child && child.status === "blocked") {
13407
13713
  const allUnblocked = child.blockedBy.every((blockedId) => {
13408
13714
  const blocked = this.graph.get(blockedId);
13409
13715
  return blocked?.status === "done";
@@ -13412,6 +13718,7 @@ Priority: ${goal.priority}`,
13412
13718
  await this.graph.update(childId, { status: "pending", updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
13413
13719
  const unblockedGoal = this.graph.get(childId);
13414
13720
  await this._broadcastTask(unblockedGoal);
13721
+ this._startBidWindow(childId);
13415
13722
  }
13416
13723
  }
13417
13724
  }
@@ -13437,6 +13744,9 @@ ${_result ?? "No result provided."}`
13437
13744
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
13438
13745
  result: error
13439
13746
  });
13747
+ this.bidRetryCounts.delete(taskId);
13748
+ this.pendingBids.delete(taskId);
13749
+ this._cancelBidWindow(taskId);
13440
13750
  this._emit("task:failed", { taskId, agentId, error });
13441
13751
  await this._mailboxPublish({
13442
13752
  type: "note",
@@ -13515,7 +13825,7 @@ Assignee: ${agentId}`
13515
13825
  priority: goal.priority,
13516
13826
  tags: goal.tags
13517
13827
  });
13518
- void this._mailboxPublish({
13828
+ this._mailboxPublish({
13519
13829
  type: "broadcast",
13520
13830
  subject: `[task] ${goal.title} (${goal.priority})`,
13521
13831
  body: `New task available: "${goal.title}"
@@ -13526,6 +13836,7 @@ Task ID: ${goal.id}
13526
13836
  Tags: ${goal.tags.join(", ") || "none"}
13527
13837
 
13528
13838
  Bid by calling taskAuctioneer.bid("${goal.id}", ...)`
13839
+ }).catch(() => {
13529
13840
  });
13530
13841
  }
13531
13842
  async _mailboxPublish(msg) {
@@ -13559,9 +13870,10 @@ Bid by calling taskAuctioneer.bid("${goal.id}", ...)`
13559
13870
  }
13560
13871
  _startBidWindow(taskId) {
13561
13872
  this._cancelBidWindow(taskId);
13562
- const timer = setTimeout(async () => {
13873
+ const timer = setTimeout(() => {
13563
13874
  this.bidTimers.delete(taskId);
13564
- await this._evaluateBids(taskId);
13875
+ void this._evaluateBids(taskId).catch(() => {
13876
+ });
13565
13877
  }, this.bidWindowMs);
13566
13878
  this.bidTimers.set(taskId, timer);
13567
13879
  }
@@ -13575,6 +13887,13 @@ Bid by calling taskAuctioneer.bid("${goal.id}", ...)`
13575
13887
  async _evaluateBids(taskId) {
13576
13888
  const bids = this.pendingBids.get(taskId);
13577
13889
  if (!bids || bids.length === 0) {
13890
+ const retryCount = (this.bidRetryCounts.get(taskId) ?? 0) + 1;
13891
+ this.bidRetryCounts.set(taskId, retryCount);
13892
+ if (retryCount >= this.maxBidRetries) {
13893
+ await this.fail(taskId, `No bids received after ${this.maxBidRetries} attempts`);
13894
+ this.bidRetryCounts.delete(taskId);
13895
+ return;
13896
+ }
13578
13897
  const goal = this.graph.get(taskId);
13579
13898
  if (goal) {
13580
13899
  await this._broadcastTask(goal);
@@ -13583,7 +13902,15 @@ Bid by calling taskAuctioneer.bid("${goal.id}", ...)`
13583
13902
  return;
13584
13903
  }
13585
13904
  bids.sort((a, b) => b.score - a.score);
13586
- const winner = bids[0];
13905
+ const winner = bids.find((b) => this._getAgentTaskCount(b.agentId) < this.maxTasksPerAgent);
13906
+ if (!winner) {
13907
+ const goal = this.graph.get(taskId);
13908
+ if (goal) {
13909
+ await this._broadcastTask(goal);
13910
+ this._startBidWindow(taskId);
13911
+ }
13912
+ return;
13913
+ }
13587
13914
  await this.claim(taskId, winner.agentId, winner.agentName);
13588
13915
  }
13589
13916
  async _assignDirect(taskId, agentId) {
@@ -13630,16 +13957,24 @@ var AutonomousCoordinator = class {
13630
13957
  selfAgentId;
13631
13958
  fleet;
13632
13959
  fleetManager;
13960
+ director;
13633
13961
  mailbox;
13634
13962
  events;
13963
+ onCoordinatorEvent;
13635
13964
  running = false;
13636
13965
  iterationCount = 0;
13966
+ /** Tasks already handled by _onSubagentTerminated (to avoid double goal:failed on fleet event). */
13967
+ _handledBySubagent = /* @__PURE__ */ new Set();
13968
+ /** FleetBus subscription disposers, detached in dispose(). */
13969
+ unsubs = [];
13637
13970
  constructor(opts) {
13638
13971
  this.selfAgentId = opts.selfAgentId;
13639
13972
  this.fleet = opts.fleet ?? void 0;
13640
13973
  this.fleetManager = opts.fleetManager ?? void 0;
13974
+ this.director = opts.director ?? void 0;
13641
13975
  this.mailbox = opts.mailbox ?? void 0;
13642
13976
  this.events = opts.events ?? void 0;
13977
+ this.onCoordinatorEvent = opts.onCoordinatorEvent;
13643
13978
  this.graph = new KnowledgeGraph(opts.sessionDir);
13644
13979
  this.dag = new TaskDAG();
13645
13980
  this.auction = new TaskAuctioneer({
@@ -13675,9 +14010,19 @@ var AutonomousCoordinator = class {
13675
14010
  this.dag.onEvent((event) => {
13676
14011
  this._onDagEvent(event);
13677
14012
  });
13678
- this.fleet?.filter("subagent.terminated", (e) => {
14013
+ const offCompleted = this.fleet?.filter("subagent.completed", (e) => {
13679
14014
  this._onSubagentTerminated(e);
13680
14015
  });
14016
+ if (offCompleted) this.unsubs.push(offCompleted);
14017
+ const offFailed = this.fleet?.filter("task:failed", (e) => {
14018
+ const payload = e.payload;
14019
+ const taskId = payload?.taskId;
14020
+ if (!taskId || this._handledBySubagent.has(taskId)) return;
14021
+ this._handledBySubagent.add(taskId);
14022
+ this._emit({ type: "goal:failed", goalId: taskId, text: payload?.error ?? "Task failed" });
14023
+ });
14024
+ if (offFailed) this.unsubs.push(offFailed);
14025
+ this._emit({ type: "coordinator:mode", mode: this.fleet ? "fleet" : "standalone" });
13681
14026
  }
13682
14027
  // ── Public API ───────────────────────────────────────────────────────
13683
14028
  /**
@@ -13691,11 +14036,13 @@ var AutonomousCoordinator = class {
13691
14036
  const maxIterations = opts.maxIterations ?? 100;
13692
14037
  const goal = opts.goal ?? "Improve the codebase";
13693
14038
  const maxCost = opts.maxCostUsd;
13694
- await this.graph.load();
13695
14039
  try {
14040
+ await this.graph.load();
13696
14041
  const goalConfigs = await this._decomposeGoal(goal);
13697
14042
  for (const g of goalConfigs) {
13698
- await this.auction.publishTask(g);
14043
+ const goalId = await this.auction.publishTask(g);
14044
+ this.dag.addNode(goalId, g.description, []);
14045
+ this._emit({ type: "goal:added", goalId, title: g.title, text: g.description });
13699
14046
  }
13700
14047
  while (this.running) {
13701
14048
  this.iterationCount++;
@@ -13722,6 +14069,7 @@ var AutonomousCoordinator = class {
13722
14069
  const blocked = this.dag.getBlocked();
13723
14070
  if (blocked.length > 0 && this.dag.hasDeadlock()) {
13724
14071
  (this.events?.emit)("autonomous:deadlock", { blocked });
14072
+ this._emit({ type: "deadlock:detected", goalId: blocked[0]?.id ?? "", text: `Deadlock detected: ${blocked.map((n) => n.id).join(", ")}` });
13725
14073
  this.running = false;
13726
14074
  }
13727
14075
  break;
@@ -13738,7 +14086,15 @@ var AutonomousCoordinator = class {
13738
14086
  }
13739
14087
  const pendingChanges = this.changes.getPendingReviews();
13740
14088
  for (const change of pendingChanges) {
13741
- await this._handlePendingChange(change);
14089
+ try {
14090
+ await this._handlePendingChange(change);
14091
+ } catch (err) {
14092
+ this._emit({
14093
+ type: "goal:failed",
14094
+ goalId: change.id,
14095
+ text: `Consensus handling failed: ${err instanceof Error ? err.message : String(err)}`
14096
+ });
14097
+ }
13742
14098
  }
13743
14099
  }
13744
14100
  } finally {
@@ -13748,7 +14104,26 @@ var AutonomousCoordinator = class {
13748
14104
  }
13749
14105
  /** Stop the autonomous loop. */
13750
14106
  stop() {
14107
+ if (!this.running) return;
13751
14108
  this.running = false;
14109
+ console.error(`[AutonomousCoordinator] stop signal received \u2014 shutting down (iteration ${this.iterationCount})`);
14110
+ }
14111
+ /**
14112
+ * Tear down the coordinator for good: stop the loop and detach all FleetBus
14113
+ * subscriptions (this coordinator's + the auctioneer's) plus any open bid
14114
+ * timers. Call this when discarding the instance (e.g. `/coordinator stop`
14115
+ * that recreates a fresh coordinator on the next start) so handlers and
14116
+ * timers don't accumulate across cycles. `stop()` only pauses the loop.
14117
+ */
14118
+ dispose() {
14119
+ this.stop();
14120
+ for (const off of this.unsubs.splice(0)) {
14121
+ try {
14122
+ off();
14123
+ } catch {
14124
+ }
14125
+ }
14126
+ this.auction.dispose();
13752
14127
  }
13753
14128
  /** Get a stats snapshot. */
13754
14129
  getStats() {
@@ -13803,6 +14178,7 @@ var AutonomousCoordinator = class {
13803
14178
  body: `**${input.category}**${input.file ? ` in ${input.file}${input.line ? `:${input.line}` : ""}` : ""}
13804
14179
  ${input.detail}`
13805
14180
  });
14181
+ this._emit({ type: "knowledge:added", knowledgeId: fact.id, title: input.subject, text: input.detail });
13806
14182
  return fact;
13807
14183
  }
13808
14184
  // ── Goal creation helpers ────────────────────────────────────────────
@@ -13815,7 +14191,10 @@ ${input.detail}`
13815
14191
  title: input.title,
13816
14192
  description: input.description,
13817
14193
  priority: resolvedPriority,
13818
- ...input.tags ? { tags: input.tags } : {}
14194
+ ...input.tags ? { tags: input.tags } : {},
14195
+ // Mirror the dependency edges into the auction so blocked goals aren't
14196
+ // biddable until their deps complete (the DAG tracks the same edges).
14197
+ ...input.deps && input.deps.length > 0 ? { blockedBy: input.deps } : {}
13819
14198
  });
13820
14199
  const goal = this.graph.get(goalId);
13821
14200
  for (const depId of input.deps ?? []) {
@@ -13856,30 +14235,34 @@ ${input.detail}`
13856
14235
  async _processGoal(goalId) {
13857
14236
  const ready = this.dag.getReady();
13858
14237
  if (ready.length === 0) return;
13859
- const next = ready.find((n) => n.id === goalId) ?? ready[0];
13860
- this.dag.start(next.id, "auctioneer");
13861
- const existingAgent = this.auction.getTasksForAgent(this.selfAgentId).find((g) => g.id === next.id);
13862
- if (!existingAgent) {
13863
- await this.auction.publishTask({
13864
- title: next.description,
13865
- description: next.description,
13866
- priority: this._dagPriorityToGoal(next.priority),
13867
- tags: next.tags
14238
+ const dagNode = ready.find((n) => n.id === goalId) ?? ready[0];
14239
+ this.dag.start(dagNode.id, "auctioneer");
14240
+ const goalNode = this.graph.get(goalId);
14241
+ if (!goalNode) return;
14242
+ const title = goalNode.title || dagNode.description;
14243
+ const taskId = await this.auction.publishTask({
14244
+ title,
14245
+ description: goalNode.description,
14246
+ priority: this._dagPriorityToGoal(dagNode.priority),
14247
+ tags: dagNode.tags
14248
+ });
14249
+ this._emit({ type: "task:ready", goalId, taskId, title });
14250
+ if (this.director) {
14251
+ const config = {
14252
+ name: `worker-${goalId.slice(0, 8)}`,
14253
+ role: "general",
14254
+ maxIterations: 100,
14255
+ timeoutMs: 6e5
14256
+ // 10 minutes per goal
14257
+ };
14258
+ const subagentId = await this.director.spawn(config);
14259
+ await this.auction.claim(taskId, subagentId, config.name);
14260
+ await this.director.assign({
14261
+ id: goalId,
14262
+ subagentId,
14263
+ description: goalNode.description
13868
14264
  });
13869
14265
  }
13870
- await this._waitForClaim(next.id);
13871
- }
13872
- async _waitForClaim(taskId) {
13873
- const maxWait = 6e4;
13874
- const pollInterval = 2e3;
13875
- const start = Date.now();
13876
- while (Date.now() - start < maxWait) {
13877
- const goal = this.graph.get(taskId);
13878
- if (goal?.status === "in_progress" || goal?.status === "done") {
13879
- return;
13880
- }
13881
- await this._sleep(pollInterval);
13882
- }
13883
14266
  }
13884
14267
  async _handlePendingChange(change) {
13885
14268
  const result = this.consensus.getStatus(change.id);
@@ -13893,6 +14276,17 @@ ${input.detail}`
13893
14276
  );
13894
14277
  if (voteResult.outcome === "approved") {
13895
14278
  await this.changes.markApplied(change.id, (/* @__PURE__ */ new Date()).toISOString());
14279
+ this._emit({ type: "consensus:reached", goalId: change.id, text: "Change approved and applied" });
14280
+ }
14281
+ } else {
14282
+ const voteResult = await this.consensus.castVote(
14283
+ change.id,
14284
+ this.selfAgentId,
14285
+ "reject",
14286
+ `Quality gate failed: ${change.qualityGate.checks.map((c) => `${c.name}=${c.passed}`).join(", ")}`
14287
+ );
14288
+ if (voteResult.outcome === "rejected" || voteResult.outcome === "vetoed") {
14289
+ this._emit({ type: "consensus:reached", goalId: change.id, text: "Change rejected by quality gate" });
13896
14290
  }
13897
14291
  }
13898
14292
  }
@@ -13903,10 +14297,6 @@ ${input.detail}`
13903
14297
  (this.events?.emit)("autonomous:task_ready", { taskId: event.nodeId, description: node.description });
13904
14298
  }
13905
14299
  }
13906
- if (event.type === "deadlock") {
13907
- (this.events?.emit)("autonomous:deadlock", { blocked: event.blocked });
13908
- this.running = false;
13909
- }
13910
14300
  if (event.type === "graph:done") {
13911
14301
  (this.events?.emit)("autonomous:all_done", this.getStats());
13912
14302
  }
@@ -13914,13 +14304,16 @@ ${input.detail}`
13914
14304
  _onSubagentTerminated(e) {
13915
14305
  const payload = e.payload;
13916
14306
  const subagentId = payload?.subagentId ?? e.subagentId;
13917
- const stopReason = payload?.stopReason ?? "unknown";
14307
+ const stopReason = payload?.stopReason ?? (payload?.status === "ok" ? "end_turn" : payload?.status ?? "unknown");
13918
14308
  const tasks = this.auction.getTasksForAgent(subagentId);
13919
14309
  for (const task of tasks) {
14310
+ this._handledBySubagent.add(task.id);
13920
14311
  if (stopReason === "end_turn") {
13921
14312
  void this.auction.complete(task.id, "Subagent completed successfully");
14313
+ this._emit({ type: "task:completed", goalId: task.id, taskId: task.id, text: "Subagent completed successfully" });
13922
14314
  } else {
13923
14315
  void this.auction.fail(task.id, `Subagent terminated: ${stopReason}`);
14316
+ this._emit({ type: "goal:failed", goalId: task.id, text: `Subagent terminated: ${stopReason}` });
13924
14317
  }
13925
14318
  }
13926
14319
  }
@@ -13934,6 +14327,10 @@ ${input.detail}`
13934
14327
  }
13935
14328
  _buildVoters() {
13936
14329
  return [
14330
+ // The coordinator itself casts the quality-gate auto-vote in
14331
+ // _handlePendingChange — it MUST be a registered, eligible voter or
14332
+ // castVote throws "unknown voter" and tears down the run() loop.
14333
+ { agentId: this.selfAgentId, agentName: "Coordinator", role: "coordinator", weight: 1 },
13937
14334
  { agentId: "critic", agentName: "Critic", role: "critic", weight: 2, veto: true },
13938
14335
  { agentId: "bug-hunter", agentName: "Bug Hunter", role: "bug-hunter", weight: 1.5 },
13939
14336
  { agentId: "security-scanner", agentName: "Security Scanner", role: "security-scanner", weight: 1.5 },
@@ -13971,11 +14368,12 @@ ${input.detail}`
13971
14368
  } catch {
13972
14369
  }
13973
14370
  }
13974
- _sleep(ms) {
13975
- return new Promise((r) => setTimeout(r, ms));
14371
+ /** Emit a CoordinatorEvent to the subscriber (e.g. TUI panel timeline). */
14372
+ _emit(event) {
14373
+ this.onCoordinatorEvent?.(event);
13976
14374
  }
13977
14375
  };
13978
14376
 
13979
- export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, TOOLS as AGENT_TOOL_PRESETS, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, AutonomousBrain, AutonomousCoordinator, BUG_HUNTER_AGENT, BUILD_AGENTS, BrainDecisionQueue, BrainMonitor, BudgetExceededError, BudgetThresholdSignal, ChangeManager, CollabSession, ConsensusProtocol, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_QUALITY_CHECKS, DEFAULT_SUBAGENT_BASELINE, DELIVERY_AGENTS, DEPENDENCY_FILE_PATTERNS, DISCOVERY_AGENTS, DOMAIN_AGENTS, DefaultBrainArbiter, DefaultMailbox, DefaultMultiAgentCoordinator, Director, DirectorAlertLevel, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, GlobalMailbox, HEAVY_BUDGET, HumanEscalatingBrainArbiter, InMemoryAgentBridge, InMemoryBridgeTransport, KNOWLEDGE_AGENTS, KnowledgeGraph, LIGHT_BUDGET, LargeAnswerStore, MEDIUM_BUDGET, META_AGENTS, NULL_FLEET_BUS, ObservableBrainArbiter, PLANNING_AGENTS, REFACTOR_PLANNER_AGENT, REVIEW_AGENTS, SECURITY_SCANNER_AGENT, SubagentBudget, TaskAuctioneer, TaskDAG, VERIFY_AGENTS, applyRosterBudget, attachAutoExtend, attachDepWatcherBridge, composeDirectorPrompt, composeSubagentPrompt, createDelegateTool, createMailboxHooks, createMessage, detectEcosystem, dispatchAgent, formatHumanPrompt, getAgentDefinition, getFullPackageLog, getManifestPackages, getPackageAuthor, getPackagesByAgent, mailboxSessionTag, makeAgentSubagentRunner, makeAskResultTool, makeAskTool, makeAssignTool, makeAwaitTasksTool, makeCollabDebugTool, makeDependencyWatcherConfig, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeMailInboxTool, makeMailSendTool, makeMailboxTool, makeRollUpTool, makeSpawnTool, makeTerminateTool, makeWorkCompleteTool, normalizeRecipient, recordPackageAction, resolveMailboxIdentity, resolveProjectDir, rosterSummaryFromConfigs, scoreAgents, startPackageOutdatedWatcher, updatePackageOutdatedStatus, withDisabledToolFiltering };
14377
+ export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, TOOLS as AGENT_TOOL_PRESETS, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, AutonomousBrain, AutonomousCoordinator, BUG_HUNTER_AGENT, BUILD_AGENTS, BrainDecisionQueue, BrainMonitor, BudgetExceededError, BudgetThresholdSignal, ChangeManager, CollabSession, ConsensusProtocol, DECISION_TIMEOUT_MS, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_QUALITY_CHECKS, DEFAULT_SUBAGENT_BASELINE, DELIVERY_AGENTS, DEPENDENCY_FILE_PATTERNS, DISCOVERY_AGENTS, DOMAIN_AGENTS, DefaultBrainArbiter, DefaultMailbox, DefaultMultiAgentCoordinator, Director, DirectorAlertLevel, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, GlobalMailbox, HEAVY_BUDGET, HumanEscalatingBrainArbiter, InMemoryAgentBridge, InMemoryBridgeTransport, KNOWLEDGE_AGENTS, KnowledgeGraph, LIGHT_BUDGET, LargeAnswerStore, MEDIUM_BUDGET, META_AGENTS, NULL_FLEET_BUS, ObservableBrainArbiter, PLANNING_AGENTS, REFACTOR_PLANNER_AGENT, REVIEW_AGENTS, SECURITY_SCANNER_AGENT, SubagentBudget, TIMEOUT_PREEMPT_FRACTION, TaskAuctioneer, TaskDAG, VERIFY_AGENTS, applyRosterBudget, attachAutoExtend, attachDepWatcherBridge, composeDirectorPrompt, composeSubagentPrompt, createDelegateTool, createMailboxHooks, createMessage, detectEcosystem, dispatchAgent, formatHumanPrompt, getAgentDefinition, getFullPackageLog, getManifestPackages, getPackageAuthor, getPackagesByAgent, mailboxSessionTag, makeAgentSubagentRunner, makeAskResultTool, makeAskTool, makeAssignTool, makeAwaitTasksTool, makeCollabDebugTool, makeDependencyWatcherConfig, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeMailInboxTool, makeMailSendTool, makeMailboxTool, makeRollUpTool, makeSpawnTool, makeTerminateTool, makeWorkCompleteTool, normalizeRecipient, recordPackageAction, resolveMailboxIdentity, resolveProjectDir, rosterSummaryFromConfigs, scoreAgents, startPackageOutdatedWatcher, updatePackageOutdatedStatus, withDisabledToolFiltering };
13980
14378
  //# sourceMappingURL=index.js.map
13981
14379
  //# sourceMappingURL=index.js.map