@wrongstack/core 0.281.1 → 0.282.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/{agent-subagent-runner-DyOSK2Wy.d.ts → agent-subagent-runner-Dksf0QVU.d.ts} +15 -4
  2. package/dist/{config-CN-vdDEI.d.ts → config-BCAEJicb.d.ts} +33 -1
  3. package/dist/coordination/index.d.ts +147 -48
  4. package/dist/coordination/index.js +1244 -274
  5. package/dist/coordination/index.js.map +1 -1
  6. package/dist/defaults/index.d.ts +18 -18
  7. package/dist/defaults/index.js +991 -173
  8. package/dist/defaults/index.js.map +1 -1
  9. package/dist/{director-state-BfeCUbmk.d.ts → director-state-B_GPa78Q.d.ts} +14 -0
  10. package/dist/{events-C5hLU0AT.d.ts → events-CovDylaH.d.ts} +2 -1
  11. package/dist/execution/index.d.ts +10 -10
  12. package/dist/execution/index.js +69 -3
  13. package/dist/execution/index.js.map +1 -1
  14. package/dist/extension/index.d.ts +4 -4
  15. package/dist/{global-mailbox-CHM1QkCi.d.ts → global-mailbox-CNfgvRw3.d.ts} +1 -1
  16. package/dist/{goal-store-BLGZq16t.d.ts → goal-store-CBd749M4.d.ts} +1 -1
  17. package/dist/hq/index.d.ts +4 -4
  18. package/dist/{index-C1E-_71T.d.ts → index-D5HB7WkV.d.ts} +4 -3
  19. package/dist/index.d.ts +3005 -2704
  20. package/dist/index.js +51869 -49930
  21. package/dist/index.js.map +1 -1
  22. package/dist/infrastructure/index.d.ts +3 -3
  23. package/dist/kernel/index.d.ts +7 -7
  24. package/dist/kernel/index.js.map +1 -1
  25. package/dist/{mcp-servers-EKRAcJDi.d.ts → mcp-servers-DJYwZXyH.d.ts} +1 -1
  26. package/dist/models/index.d.ts +2 -2
  27. package/dist/models/index.js +111 -21
  28. package/dist/models/index.js.map +1 -1
  29. package/dist/{multi-agent-coordinator-IpHCuHUa.d.ts → multi-agent-coordinator-4DC31QWu.d.ts} +1 -1
  30. package/dist/{null-fleet-bus-ZBkKGR9j.d.ts → null-fleet-bus-DuvA8PIR.d.ts} +74 -6
  31. package/dist/observability/index.d.ts +1 -1
  32. package/dist/{parallel-eternal-engine-Cc2CNgmv.d.ts → parallel-eternal-engine-BwcA0bAt.d.ts} +4 -4
  33. package/dist/{pipeline-E7_jqGyV.d.ts → pipeline-DM-CPTUs.d.ts} +1 -1
  34. package/dist/{provider-model-resolve-KgIdiEQ6.d.ts → provider-model-resolve-hNUbewMd.d.ts} +1 -1
  35. package/dist/{provider-runner-DxWXNHL1.d.ts → provider-runner-Bz4GyUqo.d.ts} +1 -1
  36. package/dist/sdd/index.d.ts +6 -6
  37. package/dist/sdd/index.js +76 -2
  38. package/dist/sdd/index.js.map +1 -1
  39. package/dist/{session-event-bridge-vA2fLV58.d.ts → session-event-bridge-Bkp7ORfc.d.ts} +2 -2
  40. package/dist/skills/index.d.ts +84 -84
  41. package/dist/storage/index.d.ts +168 -168
  42. package/dist/storage/index.js +19 -7
  43. package/dist/storage/index.js.map +1 -1
  44. package/dist/{todos-checkpoint-B1QVkoa8.d.ts → todos-checkpoint-addCdQ9f.d.ts} +2 -2
  45. package/dist/{tool-executor-BWtYwuPI.d.ts → tool-executor-B3spV_Q6.d.ts} +7 -7
  46. package/dist/tools/index.d.ts +1 -1
  47. package/dist/types/index.d.ts +33 -33
  48. package/dist/types/index.js.map +1 -1
  49. package/dist/utils/index.d.ts +113 -113
  50. package/dist/{worktree-manager-C6CIilTT.d.ts → worktree-manager-BBXdJq-Y.d.ts} +1 -1
  51. package/instructions/agents/reviewer.md +25 -0
  52. package/instructions/agents/verifier.md +24 -0
  53. package/instructions/coordination/director-preamble.md +24 -2
  54. package/instructions/coordination/subagent-baseline.md +8 -1
  55. package/package.json +1 -1
@@ -1855,6 +1855,34 @@ var BUILD_AGENTS = [
1855
1855
 
1856
1856
  // src/coordination/agents/phase4-verify.ts
1857
1857
  var VERIFY_AGENTS = [
1858
+ {
1859
+ config: {
1860
+ id: "verifier",
1861
+ name: "Verifier",
1862
+ role: "verifier",
1863
+ tools: [...TOOLS.inspect, "bash", "exec", "lint", "typecheck", "test", "git"],
1864
+ prompt: agentPrompt("verifier")
1865
+ },
1866
+ budget: HEAVY_BUDGET,
1867
+ capability: {
1868
+ phase: "verify",
1869
+ summary: "Independent verification gate: runs the relevant checks until they pass or returns exact failures that need another implementation pass.",
1870
+ keywords: [
1871
+ "verify",
1872
+ "verification",
1873
+ "quality gate",
1874
+ "prove it works",
1875
+ "run checks",
1876
+ "run tests until pass",
1877
+ "test pass",
1878
+ "green build",
1879
+ "typecheck",
1880
+ "lint",
1881
+ "regression check",
1882
+ "acceptance gate"
1883
+ ]
1884
+ }
1885
+ },
1858
1886
  {
1859
1887
  config: {
1860
1888
  id: "test",
@@ -2121,6 +2149,34 @@ var VERIFY_AGENTS = [
2121
2149
 
2122
2150
  // src/coordination/agents/phase5-review.ts
2123
2151
  var REVIEW_AGENTS = [
2152
+ {
2153
+ config: {
2154
+ id: "reviewer",
2155
+ name: "Reviewer",
2156
+ role: "reviewer",
2157
+ tools: [...TOOLS.inspect, "git"],
2158
+ prompt: agentPrompt("reviewer")
2159
+ },
2160
+ budget: MEDIUM_BUDGET,
2161
+ capability: {
2162
+ phase: "review",
2163
+ summary: "Independent AI reviewer: audits another agent's output, flags uncertainty, correlated-failure risk, and must-fix defects.",
2164
+ keywords: [
2165
+ "reviewer",
2166
+ "independent review",
2167
+ "ai review",
2168
+ "review agent",
2169
+ "quality review",
2170
+ "second opinion",
2171
+ "check another agent",
2172
+ "cross check",
2173
+ "uncertainty",
2174
+ "correlated error",
2175
+ "verify output",
2176
+ "quality control"
2177
+ ]
2178
+ }
2179
+ },
2124
2180
  {
2125
2181
  config: {
2126
2182
  id: "code-reviewer",
@@ -3977,6 +4033,28 @@ var FLEET_ROSTER_WITHACP = {
3977
4033
  ...Object.fromEntries(ACP_AGENTS.map((a) => [a.role, a]))
3978
4034
  };
3979
4035
 
4036
+ // src/security/capabilities.ts
4037
+ var ToolCapabilities = {
4038
+ /** Can execute arbitrary commands in the user's shell (the `bash` tool). */
4039
+ SHELL_ARBITRARY: "shell.arbitrary",
4040
+ /** Can execute a restricted set of commands (the `exec` tool). */
4041
+ SHELL_RESTRICTED: "shell.restricted",
4042
+ /** Can run a restricted project formatter/linter-style command. */
4043
+ SHELL_EXEC: "shell.exec",
4044
+ /** Can write / modify / delete files inside the project. */
4045
+ FS_WRITE: "fs.write",
4046
+ /** Can write files outside the current project root (very high risk). */
4047
+ FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project",
4048
+ /** Can spawn or manage subagents / multi-agent tasks. */
4049
+ SUBAGENT_SPAWN: "subagent.spawn",
4050
+ /** Can inspect fleet/subagent coordination state without mutating it. */
4051
+ COORDINATION_FLEET_READ: "coordination.fleet.read",
4052
+ /** Can read or write inter-agent mailbox messages. */
4053
+ COORDINATION_MAIL: "coordination.mail",
4054
+ /** Can install packages or run package managers with side effects. */
4055
+ PACKAGE_INSTALL: "package.install"
4056
+ };
4057
+
3980
4058
  // src/coordination/delegate-tool.ts
3981
4059
  function createDelegateTool(opts) {
3982
4060
  const defaultTimeoutMs = opts.defaultTimeoutMs ?? 30 * 60 * 1e3;
@@ -4048,6 +4126,7 @@ function createDelegateTool(opts) {
4048
4126
  usageHint: "Set `task` to a complete instruction. Either pick `role` from the roster (audit-log, bug-hunter, refactor-planner, security-scanner) or pass `name` to run a free-form coding agent. For non-trivial work, also pass `timeoutMs`, `maxIterations`, and `maxToolCalls`. Returns the subagent's `TaskResult` \u2014 including the textual `result`, iteration count, tool count, and duration. Auto-promotes the host into director mode on first call.",
4049
4127
  permission: "auto",
4050
4128
  mutating: false,
4129
+ capabilities: [ToolCapabilities.SUBAGENT_SPAWN],
4051
4130
  inputSchema,
4052
4131
  async execute(input) {
4053
4132
  const sessionId = opts.directorRunId;
@@ -4647,9 +4726,24 @@ var DirectorStateCheckpoint = class {
4647
4726
  recordTaskStatus(taskId, patch) {
4648
4727
  this.snapshot = {
4649
4728
  ...this.snapshot,
4650
- tasks: this.snapshot.tasks.map(
4651
- (t) => t.taskId === taskId ? { ...t, ...patch } : t
4652
- )
4729
+ tasks: this.snapshot.tasks.map((t) => t.taskId === taskId ? { ...t, ...patch } : t)
4730
+ };
4731
+ this.bumpUpdatedAt();
4732
+ this.schedule();
4733
+ }
4734
+ recordTaskWorktree(taskId, worktree) {
4735
+ const exists = this.snapshot.tasks.some((t) => t.taskId === taskId);
4736
+ this.snapshot = {
4737
+ ...this.snapshot,
4738
+ tasks: exists ? this.snapshot.tasks.map((t) => t.taskId === taskId ? { ...t, worktree } : t) : [
4739
+ ...this.snapshot.tasks,
4740
+ {
4741
+ taskId,
4742
+ subagentId: worktree.subagentId,
4743
+ status: "running",
4744
+ worktree
4745
+ }
4746
+ ]
4653
4747
  };
4654
4748
  this.bumpUpdatedAt();
4655
4749
  this.schedule();
@@ -4692,10 +4786,7 @@ var DirectorStateCheckpoint = class {
4692
4786
  mode: 384
4693
4787
  });
4694
4788
  } catch (err) {
4695
- console.warn(
4696
- "[director-state] checkpoint write failed:",
4697
- toErrorMessage(err)
4698
- );
4789
+ console.warn("[director-state] checkpoint write failed:", toErrorMessage(err));
4699
4790
  } finally {
4700
4791
  this.writing = false;
4701
4792
  if (this.rewriteRequested) {
@@ -4705,6 +4796,49 @@ var DirectorStateCheckpoint = class {
4705
4796
  }
4706
4797
  }
4707
4798
  };
4799
+
4800
+ // src/coordination/director/director-errors.ts
4801
+ var FleetSpawnBudgetError = class extends Error {
4802
+ kind;
4803
+ limit;
4804
+ observed;
4805
+ constructor(kind, limit, observed, message) {
4806
+ const defaultMsg = kind === "max_spawns" ? `Director spawn budget exceeded: tried to spawn #${observed} but maxSpawns is ${limit}` : `Director spawn depth budget exceeded: this director is at depth ${observed} and maxSpawnDepth is ${limit}`;
4807
+ super(message ?? defaultMsg);
4808
+ this.name = "FleetSpawnBudgetError";
4809
+ this.kind = kind;
4810
+ this.limit = limit;
4811
+ this.observed = observed;
4812
+ }
4813
+ };
4814
+ var FleetCostCapError = class extends Error {
4815
+ kind;
4816
+ limit;
4817
+ observed;
4818
+ constructor(limit, observed) {
4819
+ super(
4820
+ `Director cost cap exceeded: total fleet spend ${observed.toFixed(4)} exceeds maxCostUsd ${limit.toFixed(4)}`
4821
+ );
4822
+ this.name = "FleetCostCapError";
4823
+ this.kind = "max_cost_usd";
4824
+ this.limit = limit;
4825
+ this.observed = observed;
4826
+ }
4827
+ };
4828
+ var FleetContextOverflowError = class extends Error {
4829
+ kind;
4830
+ limit;
4831
+ observed;
4832
+ constructor(limit, observed) {
4833
+ super(
4834
+ `Leader context overflow: leader has ${observed} tokens in flight (limit: ${limit}). Compact the leader context before spawning more subagents.`
4835
+ );
4836
+ this.name = "FleetContextOverflowError";
4837
+ this.kind = "max_context_load";
4838
+ this.limit = limit;
4839
+ this.observed = observed;
4840
+ }
4841
+ };
4708
4842
  var textCache = /* @__PURE__ */ new Map();
4709
4843
  var rootCandidates;
4710
4844
  function readBundledInstructionText(relativePath) {
@@ -4929,32 +5063,57 @@ function makeLLMClassifier(complete) {
4929
5063
  };
4930
5064
  }
4931
5065
 
4932
- // src/security/capabilities.ts
4933
- var ToolCapabilities = {
4934
- /** Can spawn or manage subagents / multi-agent tasks. */
4935
- SUBAGENT_SPAWN: "subagent.spawn",
4936
- /** Can inspect fleet/subagent coordination state without mutating it. */
4937
- COORDINATION_FLEET_READ: "coordination.fleet.read",
4938
- /** Can read or write inter-agent mailbox messages. */
4939
- COORDINATION_MAIL: "coordination.mail"};
4940
-
4941
5066
  // src/coordination/director-tools.ts
4942
5067
  function makeSpawnTool(director, roster) {
4943
5068
  const inputSchema = {
4944
5069
  type: "object",
4945
5070
  properties: {
4946
- role: { type: "string", description: "Roster role id. When set, the spawn uses the matching config from the roster and ignores other fields." },
4947
- description: { type: "string", description: "Free-form task description. When `role` is not set, the director uses the smart dispatcher to route this to the best-matching catalog agent. Use this when you don't know the exact role name." },
4948
- name: { type: "string", description: "Display name for the subagent. Used as a fallback when description-based dispatch does not resolve a role." },
4949
- provider: { type: "string", description: 'Provider id (e.g. "anthropic", "openai"). Defaults to the leader provider when omitted.' },
4950
- model: { type: "string", description: "Model id within the provider. Defaults to the leader model when omitted." },
4951
- systemPromptOverride: { type: "string", description: "Extra prompt text appended after the role-base prompt." },
5071
+ role: {
5072
+ type: "string",
5073
+ description: "Roster role id. When set, the spawn uses the matching config from the roster and ignores other fields."
5074
+ },
5075
+ description: {
5076
+ type: "string",
5077
+ description: "Free-form task description. When `role` is not set, the director uses the smart dispatcher to route this to the best-matching catalog agent. Use this when you don't know the exact role name."
5078
+ },
5079
+ name: {
5080
+ type: "string",
5081
+ description: "Display name for the subagent. Used as a fallback when description-based dispatch does not resolve a role."
5082
+ },
5083
+ provider: {
5084
+ type: "string",
5085
+ description: 'Provider id (e.g. "anthropic", "openai"). Defaults to the leader provider when omitted.'
5086
+ },
5087
+ model: {
5088
+ type: "string",
5089
+ description: "Model id within the provider. Defaults to the leader model when omitted."
5090
+ },
5091
+ systemPromptOverride: {
5092
+ type: "string",
5093
+ description: "Extra prompt text appended after the role-base prompt."
5094
+ },
4952
5095
  maxIterations: { type: "number", minimum: 1 },
4953
5096
  maxToolCalls: { type: "number", minimum: 1 },
4954
5097
  maxCostUsd: { type: "number", minimum: 0 },
4955
- timeoutMs: { type: "number", minimum: 1, description: "Hard wall-clock cap in milliseconds. Defaults to none (idle timeout is the default reaper)." },
4956
- idleTimeoutMs: { type: "number", minimum: 1, description: "Idle timeout in ms: reap the subagent after this long with no activity. Resets on every iteration/tool call. Default is role/coordinator-specific." },
4957
- maxTokens: { type: "number", minimum: 1, description: "Maximum total tokens (input + output) the subagent may use." }
5098
+ timeoutMs: {
5099
+ type: "number",
5100
+ minimum: 1,
5101
+ description: "Hard wall-clock cap in milliseconds. Defaults to none (idle timeout is the default reaper)."
5102
+ },
5103
+ idleTimeoutMs: {
5104
+ type: "number",
5105
+ minimum: 1,
5106
+ description: "Idle timeout in ms: reap the subagent after this long with no activity. Resets on every iteration/tool call. Default is role/coordinator-specific."
5107
+ },
5108
+ maxTokens: {
5109
+ type: "number",
5110
+ minimum: 1,
5111
+ description: "Maximum total tokens (input + output) the subagent may use."
5112
+ },
5113
+ worktree: {
5114
+ anyOf: [{ type: "boolean" }, { type: "string", enum: ["auto", "required", "off"] }],
5115
+ description: 'Git-worktree isolation override. true/"required" requires an isolated worktree; false/"off" disables it; "auto" follows fleet policy.'
5116
+ }
4958
5117
  },
4959
5118
  required: []
4960
5119
  };
@@ -4973,7 +5132,8 @@ function makeSpawnTool(director, roster) {
4973
5132
  let cfg;
4974
5133
  if (role && roster) {
4975
5134
  const base = roster[role];
4976
- if (!base) return { error: `unknown role "${role}". roster has: ${Object.keys(roster).join(", ")}` };
5135
+ if (!base)
5136
+ return { error: `unknown role "${role}". roster has: ${Object.keys(roster).join(", ")}` };
4977
5137
  cfg = instantiateRosterConfig2(role, base);
4978
5138
  } else if (description && !role) {
4979
5139
  const dispatchResult = await dispatchAgent(description, {
@@ -4997,16 +5157,26 @@ function makeSpawnTool(director, roster) {
4997
5157
  if (typeof i.name === "string") cfg.name = i.name;
4998
5158
  if (typeof i.provider === "string") cfg.provider = i.provider;
4999
5159
  if (typeof i.model === "string") cfg.model = i.model;
5000
- if (typeof i.systemPromptOverride === "string") cfg.systemPromptOverride = i.systemPromptOverride;
5160
+ if (typeof i.systemPromptOverride === "string")
5161
+ cfg.systemPromptOverride = i.systemPromptOverride;
5001
5162
  if (typeof i.maxIterations === "number") cfg.maxIterations = i.maxIterations;
5002
5163
  if (typeof i.maxToolCalls === "number") cfg.maxToolCalls = i.maxToolCalls;
5003
5164
  if (typeof i.maxCostUsd === "number") cfg.maxCostUsd = i.maxCostUsd;
5004
5165
  if (typeof i.timeoutMs === "number") cfg.timeoutMs = i.timeoutMs;
5005
5166
  if (typeof i.idleTimeoutMs === "number") cfg.idleTimeoutMs = i.idleTimeoutMs;
5006
5167
  if (typeof i.maxTokens === "number") cfg.maxTokens = i.maxTokens;
5168
+ if (typeof i.worktree === "boolean" || i.worktree === "auto" || i.worktree === "required" || i.worktree === "off") {
5169
+ cfg.worktree = i.worktree;
5170
+ }
5007
5171
  try {
5008
5172
  const subagentId = await director.spawn(cfg);
5009
- return { subagentId, provider: cfg.provider, model: cfg.model, name: cfg.name, role: cfg.role };
5173
+ return {
5174
+ subagentId,
5175
+ provider: cfg.provider,
5176
+ model: cfg.model,
5177
+ name: cfg.name,
5178
+ role: cfg.role
5179
+ };
5010
5180
  } catch (err) {
5011
5181
  if (err instanceof FleetSpawnBudgetError) {
5012
5182
  return { error: err.message, kind: err.kind, limit: err.limit, observed: err.observed };
@@ -5027,13 +5197,402 @@ function instantiateRosterConfig2(role, base) {
5027
5197
  id: `${role}-${randomUUID().slice(0, 8)}`
5028
5198
  };
5029
5199
  }
5200
+ function makeQualityGateTool(director, roster) {
5201
+ return {
5202
+ name: "quality_gate",
5203
+ description: "Run a first-class implementation quality gate. It can await implementer task ids, spawn independent verifier/reviewer agents, summarize their verdicts, and optionally send must-fix feedback back to an implementer until the gate passes or the repair-attempt limit is reached.",
5204
+ usageHint: "Use after code-changing work. Provide implementerTaskIds when available. Add repairSubagentId to iterate fixes automatically. Verdict only passes when every enabled reviewer/verifier explicitly passes.",
5205
+ permission: "auto",
5206
+ mutating: false,
5207
+ capabilities: [ToolCapabilities.SUBAGENT_SPAWN],
5208
+ inputSchema: {
5209
+ type: "object",
5210
+ properties: {
5211
+ task: {
5212
+ type: "string",
5213
+ description: "Original implementation task or acceptance goal being gated."
5214
+ },
5215
+ implementerTaskIds: {
5216
+ type: "array",
5217
+ items: { type: "string" },
5218
+ description: "Optional completed or in-flight implementer task ids to await and include as implementation evidence."
5219
+ },
5220
+ repairSubagentId: {
5221
+ type: "string",
5222
+ description: "Optional implementer subagent id. When set and the gate fails, quality_gate assigns a repair task with reviewer/verifier feedback and reruns the gate."
5223
+ },
5224
+ maxRepairAttempts: {
5225
+ type: "number",
5226
+ minimum: 0,
5227
+ maximum: 5,
5228
+ description: "Maximum automatic repair iterations. Default: 2 when repairSubagentId is set, otherwise 0."
5229
+ },
5230
+ targets: {
5231
+ type: "array",
5232
+ items: { type: "string" },
5233
+ description: "Files, packages, or paths that reviewer/verifier should focus on."
5234
+ },
5235
+ commands: {
5236
+ type: "array",
5237
+ items: { type: "string" },
5238
+ description: 'Verification commands that should pass, e.g. ["pnpm --filter @wrongstack/core typecheck"].'
5239
+ },
5240
+ expected: {
5241
+ type: "string",
5242
+ description: "Expected behavior or acceptance criteria."
5243
+ },
5244
+ evidence: {
5245
+ type: "string",
5246
+ description: "Known implementation notes, diff summary, or commands already run."
5247
+ },
5248
+ reviewer: {
5249
+ type: "boolean",
5250
+ description: "Whether to run the reviewer lane. Default true."
5251
+ },
5252
+ verifier: {
5253
+ type: "boolean",
5254
+ description: "Whether to run the verifier lane. Default true."
5255
+ },
5256
+ timeoutMs: {
5257
+ type: "number",
5258
+ minimum: 1,
5259
+ description: "Optional per reviewer/verifier/repair task timeout."
5260
+ },
5261
+ reviewerWorktree: {
5262
+ anyOf: [{ type: "boolean" }, { type: "string", enum: ["auto", "required", "off"] }],
5263
+ description: "Reviewer worktree override. Default off because reviewer is read-only."
5264
+ },
5265
+ verifierWorktree: {
5266
+ anyOf: [{ type: "boolean" }, { type: "string", enum: ["auto", "required", "off"] }],
5267
+ description: "Verifier worktree override. Default auto so test artifacts stay isolated when fleet policy wants it."
5268
+ }
5269
+ }
5270
+ },
5271
+ async execute(input) {
5272
+ const i = normalizeQualityGateInput(input);
5273
+ const runReviewer = i.reviewer !== false;
5274
+ const runVerifier = i.verifier !== false;
5275
+ if (!runReviewer && !runVerifier) {
5276
+ return {
5277
+ verdict: "inconclusive",
5278
+ passed: false,
5279
+ error: "quality_gate requires reviewer, verifier, or both."
5280
+ };
5281
+ }
5282
+ const implementerResults = i.implementerTaskIds && i.implementerTaskIds.length > 0 ? await director.awaitTasks(i.implementerTaskIds) : [];
5283
+ const maxRepairAttempts = clampRepairAttempts(
5284
+ i.maxRepairAttempts ?? (i.repairSubagentId ? 2 : 0)
5285
+ );
5286
+ const repairResults = [];
5287
+ const attempts = [];
5288
+ for (let attempt = 1; ; attempt++) {
5289
+ const gateTaskIds = [];
5290
+ const taskRoleById = /* @__PURE__ */ new Map();
5291
+ if (runVerifier) {
5292
+ const subagentId = await director.spawn(
5293
+ makeQualityGateSubagentConfig("verifier", roster, i.verifierWorktree ?? "auto")
5294
+ );
5295
+ const taskId = await director.assign({
5296
+ id: randomUUID(),
5297
+ subagentId,
5298
+ description: buildVerifierTask(i, {
5299
+ attempt,
5300
+ implementerResults,
5301
+ repairResults,
5302
+ priorAttempts: attempts
5303
+ }),
5304
+ timeoutMs: i.timeoutMs
5305
+ });
5306
+ gateTaskIds.push(taskId);
5307
+ taskRoleById.set(taskId, "verifier");
5308
+ }
5309
+ if (runReviewer) {
5310
+ const subagentId = await director.spawn(
5311
+ makeQualityGateSubagentConfig("reviewer", roster, i.reviewerWorktree ?? "off")
5312
+ );
5313
+ const taskId = await director.assign({
5314
+ id: randomUUID(),
5315
+ subagentId,
5316
+ description: buildReviewerTask(i, {
5317
+ attempt,
5318
+ implementerResults,
5319
+ repairResults,
5320
+ priorAttempts: attempts
5321
+ }),
5322
+ timeoutMs: i.timeoutMs
5323
+ });
5324
+ gateTaskIds.push(taskId);
5325
+ taskRoleById.set(taskId, "reviewer");
5326
+ }
5327
+ const gateResults = await director.awaitTasks(gateTaskIds);
5328
+ const reports = gateResults.map((r) => assessRoleResult(taskRoleById.get(r.taskId), r));
5329
+ const assessment = assessQualityGate(reports);
5330
+ attempts.push({ attempt, reports, ...assessment });
5331
+ if (assessment.passed || !i.repairSubagentId || attempt > maxRepairAttempts) {
5332
+ return {
5333
+ verdict: assessment.verdict,
5334
+ passed: assessment.passed,
5335
+ attempts,
5336
+ repairAttemptsUsed: repairResults.length,
5337
+ implementerResults: implementerResults.map(summarizeTaskResult),
5338
+ nextAction: assessment.passed ? "accept" : i.repairSubagentId && attempt > maxRepairAttempts ? "manual_intervention_or_raise_repair_limit" : "inspect_failures"
5339
+ };
5340
+ }
5341
+ const repairTaskId = await director.assign({
5342
+ id: randomUUID(),
5343
+ subagentId: i.repairSubagentId,
5344
+ description: buildRepairTask(i, attempts[attempts.length - 1], attempt),
5345
+ timeoutMs: i.timeoutMs
5346
+ });
5347
+ const [repairResult] = await director.awaitTasks([repairTaskId]);
5348
+ if (repairResult) repairResults.push(repairResult);
5349
+ if (repairResult?.status !== "success") {
5350
+ return {
5351
+ verdict: "fail",
5352
+ passed: false,
5353
+ attempts,
5354
+ repairAttemptsUsed: repairResults.length,
5355
+ repairResult: repairResult ? summarizeTaskResult(repairResult) : void 0,
5356
+ implementerResults: implementerResults.map(summarizeTaskResult),
5357
+ nextAction: "repair_failed"
5358
+ };
5359
+ }
5360
+ }
5361
+ }
5362
+ };
5363
+ }
5364
+ function normalizeQualityGateInput(input) {
5365
+ const raw = input ?? {};
5366
+ return {
5367
+ task: typeof raw.task === "string" ? raw.task : void 0,
5368
+ implementerTaskIds: stringArray(raw.implementerTaskIds),
5369
+ repairSubagentId: typeof raw.repairSubagentId === "string" && raw.repairSubagentId.trim() ? raw.repairSubagentId.trim() : void 0,
5370
+ maxRepairAttempts: typeof raw.maxRepairAttempts === "number" ? raw.maxRepairAttempts : void 0,
5371
+ targets: stringArray(raw.targets),
5372
+ commands: stringArray(raw.commands),
5373
+ expected: typeof raw.expected === "string" ? raw.expected : void 0,
5374
+ evidence: typeof raw.evidence === "string" ? raw.evidence : void 0,
5375
+ reviewer: typeof raw.reviewer === "boolean" ? raw.reviewer : void 0,
5376
+ verifier: typeof raw.verifier === "boolean" ? raw.verifier : void 0,
5377
+ timeoutMs: typeof raw.timeoutMs === "number" ? raw.timeoutMs : void 0,
5378
+ reviewerWorktree: normalizeWorktreeOverride(raw.reviewerWorktree),
5379
+ verifierWorktree: normalizeWorktreeOverride(raw.verifierWorktree)
5380
+ };
5381
+ }
5382
+ function stringArray(value) {
5383
+ if (!Array.isArray(value)) return void 0;
5384
+ const strings = value.filter((v) => typeof v === "string" && v.trim().length > 0);
5385
+ return strings.length > 0 ? strings : void 0;
5386
+ }
5387
+ function normalizeWorktreeOverride(value) {
5388
+ if (typeof value === "boolean") return value;
5389
+ if (value === "auto" || value === "required" || value === "off") return value;
5390
+ return void 0;
5391
+ }
5392
+ function clampRepairAttempts(value) {
5393
+ if (!Number.isFinite(value)) return 0;
5394
+ return Math.max(0, Math.min(5, Math.floor(value)));
5395
+ }
5396
+ function makeQualityGateSubagentConfig(role, roster, worktree) {
5397
+ const base = roster?.[role] ?? getAgentDefinition(role)?.config ?? { name: role, role };
5398
+ return {
5399
+ ...instantiateRosterConfig2(role, base),
5400
+ worktree
5401
+ };
5402
+ }
5403
+ function buildVerifierTask(input, state) {
5404
+ return [
5405
+ "Run the independent verification gate for this implementation.",
5406
+ "Return Markdown with `## Verdict` and make the first verdict word exactly `pass`, `fail`, or `blocked`.",
5407
+ "Do not edit code. Run the smallest meaningful command set and include exact failures.",
5408
+ "",
5409
+ `Gate attempt: ${state.attempt}`,
5410
+ input.task ? `Original task:
5411
+ ${input.task}` : void 0,
5412
+ input.targets?.length ? `Targets:
5413
+ ${input.targets.map((t) => `- ${t}`).join("\n")}` : void 0,
5414
+ input.commands?.length ? `Required or suggested commands:
5415
+ ${input.commands.map((c) => `- ${c}`).join("\n")}` : void 0,
5416
+ input.expected ? `Expected behavior:
5417
+ ${input.expected}` : void 0,
5418
+ input.evidence ? `Known evidence:
5419
+ ${input.evidence}` : void 0,
5420
+ taskResultsBlock("Implementer results", state.implementerResults),
5421
+ taskResultsBlock("Repair results so far", state.repairResults),
5422
+ priorAttemptsBlock(state.priorAttempts)
5423
+ ].filter((part) => !!part).join("\n\n");
5424
+ }
5425
+ function buildReviewerTask(input, state) {
5426
+ return [
5427
+ "Run independent code review for this implementation.",
5428
+ "Return Markdown with `## Verdict` and make the first verdict phrase exactly `approve`, `request changes`, or `needs verification`.",
5429
+ "Do not edit code. Treat missing proof, vague tests, and uncertainty as blocking until verifier evidence exists.",
5430
+ "",
5431
+ `Gate attempt: ${state.attempt}`,
5432
+ input.task ? `Original task:
5433
+ ${input.task}` : void 0,
5434
+ input.targets?.length ? `Targets:
5435
+ ${input.targets.map((t) => `- ${t}`).join("\n")}` : void 0,
5436
+ input.expected ? `Expected behavior:
5437
+ ${input.expected}` : void 0,
5438
+ input.evidence ? `Known evidence:
5439
+ ${input.evidence}` : void 0,
5440
+ taskResultsBlock("Implementer results", state.implementerResults),
5441
+ taskResultsBlock("Repair results so far", state.repairResults),
5442
+ priorAttemptsBlock(state.priorAttempts)
5443
+ ].filter((part) => !!part).join("\n\n");
5444
+ }
5445
+ function buildRepairTask(input, attempt, attemptNumber) {
5446
+ return [
5447
+ `Repair the implementation after quality gate attempt ${attemptNumber} failed.`,
5448
+ "Address every must-fix item. Run relevant checks before returning.",
5449
+ "Do not claim done unless verifier/reviewer feedback is resolved.",
5450
+ "",
5451
+ input.task ? `Original task:
5452
+ ${input.task}` : void 0,
5453
+ input.targets?.length ? `Targets:
5454
+ ${input.targets.map((t) => `- ${t}`).join("\n")}` : void 0,
5455
+ input.commands?.length ? `Commands expected to pass:
5456
+ ${input.commands.map((c) => `- ${c}`).join("\n")}` : void 0,
5457
+ input.expected ? `Expected behavior:
5458
+ ${input.expected}` : void 0,
5459
+ attempt.mustFix.length ? `Must fix:
5460
+ ${attempt.mustFix.map((f) => `- ${f}`).join("\n")}` : void 0,
5461
+ attempt.uncertaintyFlags.length ? `Uncertainty flags to resolve:
5462
+ ${attempt.uncertaintyFlags.map((f) => `- ${f}`).join("\n")}` : void 0,
5463
+ `Reviewer/verifier reports:
5464
+ ${attempt.reports.map((r) => `### ${r.role} (${r.verdict})
5465
+ ${r.summary}`).join("\n\n")}`
5466
+ ].filter((part) => !!part).join("\n\n");
5467
+ }
5468
+ function taskResultsBlock(title, results) {
5469
+ if (results.length === 0) return void 0;
5470
+ return `${title}:
5471
+ ${results.map((r) => `### ${r.subagentId}/${r.taskId}
5472
+ ${summarizeTaskResult(r).summary}`).join("\n\n")}`;
5473
+ }
5474
+ function priorAttemptsBlock(attempts) {
5475
+ if (attempts.length === 0) return void 0;
5476
+ return `Prior quality gate attempts:
5477
+ ${attempts.map(
5478
+ (a) => `### Attempt ${a.attempt}
5479
+ ${a.reports.map((r) => `- ${r.role}: ${r.verdict}${r.error ? ` (${r.error})` : ""}`).join("\n")}`
5480
+ ).join("\n\n")}`;
5481
+ }
5482
+ function summarizeTaskResult(result) {
5483
+ const text = typeof result.result === "string" ? result.result : result.result !== void 0 ? JSON.stringify(result.result, null, 2) : "";
5484
+ const error = result.error ? `${result.error.kind}: ${result.error.message}` : void 0;
5485
+ return {
5486
+ taskId: result.taskId,
5487
+ subagentId: result.subagentId,
5488
+ status: result.status,
5489
+ summary: excerpt(text || error || "(no output)", 4e3),
5490
+ error
5491
+ };
5492
+ }
5493
+ function assessRoleResult(role, result) {
5494
+ const resolvedRole = role ?? (result.subagentId.includes("review") ? "reviewer" : "verifier");
5495
+ const summary = summarizeTaskResult(result);
5496
+ const text = summary.summary;
5497
+ const uncertaintyFlags = extractSection(text, "Uncertainty Flags");
5498
+ if (result.status !== "success") {
5499
+ return {
5500
+ role: resolvedRole,
5501
+ subagentId: result.subagentId,
5502
+ taskId: result.taskId,
5503
+ status: result.status,
5504
+ verdict: "fail",
5505
+ summary: text,
5506
+ uncertaintyFlags,
5507
+ error: summary.error ?? result.status
5508
+ };
5509
+ }
5510
+ return {
5511
+ role: resolvedRole,
5512
+ subagentId: result.subagentId,
5513
+ taskId: result.taskId,
5514
+ status: result.status,
5515
+ verdict: parseQualityVerdict(resolvedRole, text),
5516
+ summary: text,
5517
+ uncertaintyFlags
5518
+ };
5519
+ }
5520
+ function assessQualityGate(reports) {
5521
+ const mustFix = [];
5522
+ const uncertaintyFlags = [];
5523
+ let hasFail = false;
5524
+ let hasInconclusive = false;
5525
+ for (const report of reports) {
5526
+ if (report.verdict === "fail") hasFail = true;
5527
+ if (report.verdict === "inconclusive") hasInconclusive = true;
5528
+ const blocking = extractSection(report.summary, "Must Fix") || extractSection(report.summary, "Failures") || extractSection(report.summary, "Verification Gaps");
5529
+ if (blocking) mustFix.push(`${report.role}: ${excerpt(blocking, 1e3)}`);
5530
+ if (report.uncertaintyFlags) {
5531
+ uncertaintyFlags.push(`${report.role}: ${excerpt(report.uncertaintyFlags, 1e3)}`);
5532
+ }
5533
+ if (report.error) mustFix.push(`${report.role}: ${report.error}`);
5534
+ }
5535
+ if (hasFail) return { verdict: "fail", passed: false, mustFix, uncertaintyFlags };
5536
+ if (hasInconclusive || reports.length === 0) {
5537
+ return { verdict: "inconclusive", passed: false, mustFix, uncertaintyFlags };
5538
+ }
5539
+ return { verdict: "pass", passed: true, mustFix, uncertaintyFlags };
5540
+ }
5541
+ function parseQualityVerdict(role, text) {
5542
+ const normalized = text.toLowerCase();
5543
+ const verdictBlock = normalized.match(/(?:^|\n)\s*(?:#+\s*)?verdict\b[^\n]*(?:\n|:|-)?([\s\S]{0,500})/)?.[0] ?? normalized.slice(0, 1e3);
5544
+ if (role === "reviewer") {
5545
+ if (/\b(request\s+changes|needs\s+verification|reject|rejected|fail|failed|blocked)\b/.test(
5546
+ verdictBlock
5547
+ )) {
5548
+ return "fail";
5549
+ }
5550
+ if (/\b(approve|approved|pass|passed)\b/.test(verdictBlock)) return "pass";
5551
+ if (sectionHasBlockingContent(text, "Must Fix") || sectionHasBlockingContent(text, "Verification Gaps")) {
5552
+ return "fail";
5553
+ }
5554
+ return "inconclusive";
5555
+ }
5556
+ if (/\b(fail|failed|blocked|red)\b/.test(verdictBlock)) return "fail";
5557
+ if (/\b(pass|passed|green|approve|approved)\b/.test(verdictBlock)) return "pass";
5558
+ if (sectionHasBlockingContent(text, "Failures")) return "fail";
5559
+ return "inconclusive";
5560
+ }
5561
+ function sectionHasBlockingContent(text, heading) {
5562
+ const section = extractSection(text, heading);
5563
+ if (!section) return false;
5564
+ return !/^\s*(none|n\/a|no\b|no issues|empty|\(none\))\s*\.?\s*$/i.test(section.trim());
5565
+ }
5566
+ function extractSection(text, heading) {
5567
+ const escaped = heading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5568
+ const pattern = new RegExp(
5569
+ `(?:^|\\n)\\s*#{1,6}\\s*${escaped}\\s*\\n([\\s\\S]*?)(?=\\n\\s*#{1,6}\\s+|$)`,
5570
+ "i"
5571
+ );
5572
+ const match = text.match(pattern);
5573
+ const body = match?.[1]?.trim();
5574
+ return body ? body : void 0;
5575
+ }
5576
+ function excerpt(text, max) {
5577
+ if (text.length <= max) return text;
5578
+ return `${text.slice(0, max - 20).trimEnd()}
5579
+ ...(truncated)`;
5580
+ }
5030
5581
  function makeAssignTool(director) {
5031
5582
  const inputSchema = {
5032
5583
  type: "object",
5033
5584
  properties: {
5034
5585
  subagentId: { type: "string", minLength: 1, description: "Target subagent id. Required." },
5035
- description: { type: "string", minLength: 1, description: "The task in natural language \u2014 what you want this subagent to do." },
5036
- maxToolCalls: { type: "number", minimum: 1, description: "Optional per-task tool-call budget override." },
5586
+ description: {
5587
+ type: "string",
5588
+ minLength: 1,
5589
+ description: "The task in natural language \u2014 what you want this subagent to do."
5590
+ },
5591
+ maxToolCalls: {
5592
+ type: "number",
5593
+ minimum: 1,
5594
+ description: "Optional per-task tool-call budget override."
5595
+ },
5037
5596
  timeoutMs: { type: "number", minimum: 1, description: "Optional per-task timeout in ms." }
5038
5597
  },
5039
5598
  required: ["subagentId", "description"]
@@ -5047,7 +5606,13 @@ function makeAssignTool(director) {
5047
5606
  inputSchema,
5048
5607
  async execute(input) {
5049
5608
  const i = input;
5050
- const task = { id: randomUUID(), description: i.description, subagentId: i.subagentId, maxToolCalls: i.maxToolCalls, timeoutMs: i.timeoutMs };
5609
+ const task = {
5610
+ id: randomUUID(),
5611
+ description: i.description,
5612
+ subagentId: i.subagentId,
5613
+ maxToolCalls: i.maxToolCalls,
5614
+ timeoutMs: i.timeoutMs
5615
+ };
5051
5616
  const taskId = await director.assign(task);
5052
5617
  return { taskId, subagentId: i.subagentId };
5053
5618
  }
@@ -5063,22 +5628,39 @@ function makeAwaitTasksTool(director) {
5063
5628
  inputSchema: {
5064
5629
  type: "object",
5065
5630
  properties: {
5066
- taskIds: { type: "array", items: { type: "string" }, description: "One or more task ids returned by `assign_task`." },
5067
- mode: { type: "string", enum: ["all", "any"], description: '"all" (default): block until every task completes. "any": return on the first completion with the rest listed as pending.' },
5068
- timeoutMs: { type: "number", minimum: 1, description: 'mode:"any" only \u2014 return {timedOut:true, completed:[]} if nothing completes within this window instead of blocking.' }
5631
+ taskIds: {
5632
+ type: "array",
5633
+ items: { type: "string" },
5634
+ description: "One or more task ids returned by `assign_task`."
5635
+ },
5636
+ mode: {
5637
+ type: "string",
5638
+ enum: ["all", "any"],
5639
+ description: '"all" (default): block until every task completes. "any": return on the first completion with the rest listed as pending.'
5640
+ },
5641
+ timeoutMs: {
5642
+ type: "number",
5643
+ minimum: 1,
5644
+ description: 'mode:"any" only \u2014 return {timedOut:true, completed:[]} if nothing completes within this window instead of blocking.'
5645
+ }
5069
5646
  },
5070
5647
  required: ["taskIds"]
5071
5648
  },
5072
5649
  async execute(input) {
5073
5650
  const i = input;
5074
5651
  if (i.mode === "any") {
5075
- const r = await director.awaitTasksAny(i.taskIds, i.timeoutMs !== void 0 ? { timeoutMs: i.timeoutMs } : void 0);
5652
+ const r = await director.awaitTasksAny(
5653
+ i.taskIds,
5654
+ i.timeoutMs !== void 0 ? { timeoutMs: i.timeoutMs } : void 0
5655
+ );
5076
5656
  return {
5077
5657
  mode: "any",
5078
5658
  completed: r.completed,
5079
5659
  pending: r.pending,
5080
5660
  ...r.timedOut ? { timedOut: true } : {},
5081
- ...r.pending.length > 0 ? { hint: 'Handle the completed results now. Re-call await_tasks with the pending ids (mode:"any") for the next finisher \u2014 or assign new work to the now-idle subagent first.' } : {}
5661
+ ...r.pending.length > 0 ? {
5662
+ hint: 'Handle the completed results now. Re-call await_tasks with the pending ids (mode:"any") for the next finisher \u2014 or assign new work to the now-idle subagent first.'
5663
+ } : {}
5082
5664
  };
5083
5665
  }
5084
5666
  const results = await director.awaitTasks(i.taskIds);
@@ -5096,9 +5678,17 @@ function makeAskTool(director) {
5096
5678
  inputSchema: {
5097
5679
  type: "object",
5098
5680
  properties: {
5099
- subagentId: { type: "string", minLength: 1, description: "Subagent to ask. Must be a previously spawned id." },
5681
+ subagentId: {
5682
+ type: "string",
5683
+ minLength: 1,
5684
+ description: "Subagent to ask. Must be a previously spawned id."
5685
+ },
5100
5686
  question: { type: "string", minLength: 1, description: "The question or instruction." },
5101
- timeoutMs: { type: "number", minimum: 1, description: "Optional timeout in ms (default 30s)." }
5687
+ timeoutMs: {
5688
+ type: "number",
5689
+ minimum: 1,
5690
+ description: "Optional timeout in ms (default 30s)."
5691
+ }
5102
5692
  },
5103
5693
  required: ["subagentId", "question"]
5104
5694
  },
@@ -5144,7 +5734,10 @@ function makeAskResultTool(director) {
5144
5734
  const i = input;
5145
5735
  const value = director.largeAnswerStore.retrieveAnswer(i.key);
5146
5736
  if (value === void 0) {
5147
- return { ok: false, error: `No stored answer found for key "${i.key}" \u2014 it may have been cleared or the key is invalid.` };
5737
+ return {
5738
+ ok: false,
5739
+ error: `No stored answer found for key "${i.key}" \u2014 it may have been cleared or the key is invalid.`
5740
+ };
5148
5741
  }
5149
5742
  return { ok: true, value };
5150
5743
  }
@@ -5160,9 +5753,17 @@ function makeRollUpTool(director) {
5160
5753
  inputSchema: {
5161
5754
  type: "object",
5162
5755
  properties: {
5163
- taskIds: { type: "array", items: { type: "string" }, description: "Completed task ids to aggregate." },
5164
- style: { type: "string", enum: ["markdown", "json"], description: "Output flavor \u2014 markdown (default) or json." }
5165
- },
5756
+ taskIds: {
5757
+ type: "array",
5758
+ items: { type: "string" },
5759
+ description: "Completed task ids to aggregate."
5760
+ },
5761
+ style: {
5762
+ type: "string",
5763
+ enum: ["markdown", "json"],
5764
+ description: "Output flavor \u2014 markdown (default) or json."
5765
+ }
5766
+ },
5166
5767
  required: ["taskIds"]
5167
5768
  },
5168
5769
  async execute(input) {
@@ -5179,7 +5780,11 @@ function makeTerminateTool(director) {
5179
5780
  permission: "auto",
5180
5781
  mutating: true,
5181
5782
  capabilities: [ToolCapabilities.SUBAGENT_SPAWN],
5182
- inputSchema: { type: "object", properties: { subagentId: { type: "string", description: "Subagent to abort." } }, required: ["subagentId"] },
5783
+ inputSchema: {
5784
+ type: "object",
5785
+ properties: { subagentId: { type: "string", description: "Subagent to abort." } },
5786
+ required: ["subagentId"]
5787
+ },
5183
5788
  async execute(input) {
5184
5789
  const i = input;
5185
5790
  await director.terminate(i.subagentId);
@@ -5197,7 +5802,10 @@ function makeTerminateAllTool(director) {
5197
5802
  inputSchema: { type: "object", properties: {}, required: [] },
5198
5803
  async execute() {
5199
5804
  await director.terminateAll();
5200
- return { ok: true, message: `Fleet shutdown complete \u2014 all subagents stopped, pending tasks drained.` };
5805
+ return {
5806
+ ok: true,
5807
+ message: `Fleet shutdown complete \u2014 all subagents stopped, pending tasks drained.`
5808
+ };
5201
5809
  }
5202
5810
  };
5203
5811
  }
@@ -5239,7 +5847,12 @@ function makeFleetTool(director) {
5239
5847
  return {
5240
5848
  action: "status",
5241
5849
  subagents: base.subagents,
5242
- coordinatorStats: stats ? { total: stats.total, running: stats.running, idle: stats.idle, stopped: stats.stopped } : void 0,
5850
+ coordinatorStats: stats ? {
5851
+ total: stats.total,
5852
+ running: stats.running,
5853
+ idle: stats.idle,
5854
+ stopped: stats.stopped
5855
+ } : void 0,
5243
5856
  pending: fleetStatus?.pending ?? [],
5244
5857
  usage: fm?.snapshot()
5245
5858
  };
@@ -5272,7 +5885,10 @@ function makeFleetTool(director) {
5272
5885
  case "session": {
5273
5886
  const subagentId = i.subagentId;
5274
5887
  if (!subagentId) {
5275
- return { action: "session", error: 'fleet: subagentId is required for action: "session"' };
5888
+ return {
5889
+ action: "session",
5890
+ error: 'fleet: subagentId is required for action: "session"'
5891
+ };
5276
5892
  }
5277
5893
  const result = await director.readSession(subagentId, i.tail);
5278
5894
  if (!result) {
@@ -5284,7 +5900,9 @@ function makeFleetTool(director) {
5284
5900
  return { action: "session", ...result };
5285
5901
  }
5286
5902
  default:
5287
- return { error: `fleet: unknown action "${action}". Valid: status, usage, health, session.` };
5903
+ return {
5904
+ error: `fleet: unknown action "${action}". Valid: status, usage, health, session.`
5905
+ };
5288
5906
  }
5289
5907
  }
5290
5908
  };
@@ -5728,6 +6346,31 @@ function providerStatusToCode(status, type) {
5728
6346
  if (status >= 500) return ERROR_CODES.PROVIDER_SERVER_ERROR;
5729
6347
  return ERROR_CODES.PROVIDER_INVALID_REQUEST;
5730
6348
  }
6349
+
6350
+ // src/core/fallback-model.ts
6351
+ function parseModelRef(ref) {
6352
+ const trimmed = ref.trim();
6353
+ const slash = trimmed.indexOf("/");
6354
+ if (slash !== -1) {
6355
+ return {
6356
+ provider: trimmed.slice(0, slash) || void 0,
6357
+ model: trimmed.slice(slash + 1).trim()
6358
+ };
6359
+ }
6360
+ const parts = trimmed.split(/\s+/);
6361
+ if (parts.length >= 2) {
6362
+ return { provider: parts[0], model: parts.slice(1).join(" ") };
6363
+ }
6364
+ return { model: trimmed };
6365
+ }
6366
+ function fallbackProfileChain(config, profileName) {
6367
+ if (!profileName) return [];
6368
+ const chain = config.fallbackProfiles?.[profileName];
6369
+ return Array.isArray(chain) ? chain.filter((ref) => parseModelRef(ref).model) : [];
6370
+ }
6371
+
6372
+ // src/coordination/model-matrix.ts
6373
+ var MATRIX_PHASE_KEYS = Object.keys(AGENTS_BY_PHASE);
5731
6374
  var ROLE_TO_PHASE = (() => {
5732
6375
  const map = {};
5733
6376
  for (const [phase, defs] of Object.entries(AGENTS_BY_PHASE)) {
@@ -5741,14 +6384,162 @@ var ROLE_TO_PHASE = (() => {
5741
6384
  function phaseForRole(role) {
5742
6385
  return role ? ROLE_TO_PHASE[role] : void 0;
5743
6386
  }
5744
- function resolveModelMatrix(matrix, role) {
6387
+ function resolveModelMatrixResolution(matrix, role) {
5745
6388
  if (!matrix) return void 0;
5746
- if (role && matrix[role]) return matrix[role];
6389
+ if (role && matrix[role]) return { entry: matrix[role], source: "role", key: role };
5747
6390
  const phase = phaseForRole(role);
5748
- if (phase && matrix[phase]) return matrix[phase];
5749
- if (matrix["*"]) return matrix["*"];
6391
+ if (phase && matrix[phase]) return { entry: matrix[phase], source: "phase", key: phase };
6392
+ if (matrix["*"]) return { entry: matrix["*"], source: "default", key: "*" };
5750
6393
  return void 0;
5751
6394
  }
6395
+ function resolveModelMatrix(matrix, role) {
6396
+ return resolveModelMatrixResolution(matrix, role)?.entry;
6397
+ }
6398
+ function resolveModelTargetFromEntry(config, entry) {
6399
+ if (!entry) return void 0;
6400
+ if (entry.model) {
6401
+ return {
6402
+ provider: entry.provider,
6403
+ model: entry.model,
6404
+ modelRuntime: entry.modelRuntime,
6405
+ fallbackProfile: entry.fallbackProfile,
6406
+ fallbackModels: fallbackProfileChain(config, entry.fallbackProfile)
6407
+ };
6408
+ }
6409
+ const chain = fallbackProfileChain(config, entry.fallbackProfile);
6410
+ const first = chain[0];
6411
+ if (!first) {
6412
+ return entry.modelRuntime ? { modelRuntime: entry.modelRuntime } : void 0;
6413
+ }
6414
+ const parsed = parseModelRef(first);
6415
+ return {
6416
+ provider: parsed.provider,
6417
+ model: parsed.model,
6418
+ modelRuntime: entry.modelRuntime,
6419
+ fallbackProfile: entry.fallbackProfile,
6420
+ fallbackModels: chain.slice(1)
6421
+ };
6422
+ }
6423
+ function roleNeedsIndependentReviewModel(role) {
6424
+ if (!role) return false;
6425
+ return role === "reviewer" || phaseForRole(role) === "review";
6426
+ }
6427
+ function resolveSubagentModelTarget(config, role, opts = {}) {
6428
+ const resolution = resolveModelMatrixResolution(config.modelMatrix, role);
6429
+ const matrixTarget = resolveModelTargetFromEntry(config, resolution?.entry);
6430
+ const implementationTarget = opts.implementationTarget ?? resolveImplementationModelTarget(config);
6431
+ if (!roleNeedsIndependentReviewModel(role)) {
6432
+ if (!matrixTarget) return void 0;
6433
+ return {
6434
+ ...matrixTarget,
6435
+ source: "matrix",
6436
+ matrixSource: resolution?.source
6437
+ };
6438
+ }
6439
+ const matrixRef = materializeTarget(config, matrixTarget);
6440
+ if (resolution?.source === "role" || resolution?.source === "phase") {
6441
+ return matrixTarget ? { ...matrixTarget, source: "matrix", matrixSource: resolution.source } : void 0;
6442
+ }
6443
+ if (matrixRef && !sameModelReference(matrixRef, implementationTarget)) {
6444
+ return {
6445
+ ...matrixTarget ?? {},
6446
+ source: "matrix",
6447
+ matrixSource: resolution?.source
6448
+ };
6449
+ }
6450
+ const diverse = chooseDiverseModelTarget(config, implementationTarget);
6451
+ if (diverse) {
6452
+ return {
6453
+ provider: diverse.provider,
6454
+ model: diverse.model,
6455
+ modelRuntime: matrixTarget?.modelRuntime,
6456
+ fallbackModels: matrixTarget?.fallbackModels,
6457
+ fallbackProfile: matrixTarget?.fallbackProfile,
6458
+ source: "diversity",
6459
+ matrixSource: resolution?.source,
6460
+ diversified: true
6461
+ };
6462
+ }
6463
+ if (!matrixTarget) return void 0;
6464
+ return {
6465
+ ...matrixTarget,
6466
+ source: "matrix",
6467
+ matrixSource: resolution?.source
6468
+ };
6469
+ }
6470
+ function resolveImplementationModelTarget(config) {
6471
+ const target = resolveModelTargetFromEntry(
6472
+ config,
6473
+ resolveModelMatrix(config.modelMatrix, "executor")
6474
+ );
6475
+ return materializeTarget(config, target) ?? {
6476
+ provider: config.provider,
6477
+ model: config.model
6478
+ };
6479
+ }
6480
+ function sameModelReference(a, b) {
6481
+ if (!a?.model || !b?.model) return false;
6482
+ const providerA = a.provider ?? "";
6483
+ const providerB = b.provider ?? "";
6484
+ return providerA === providerB && a.model === b.model;
6485
+ }
6486
+ function materializeTarget(config, target) {
6487
+ if (!target?.model) return void 0;
6488
+ return {
6489
+ provider: target.provider ?? config.provider,
6490
+ model: target.model
6491
+ };
6492
+ }
6493
+ function chooseDiverseModelTarget(config, avoid) {
6494
+ const candidates = collectConfiguredModelTargets(config).filter(
6495
+ (candidate) => !sameModelReference(candidate, avoid)
6496
+ );
6497
+ candidates.sort((a, b) => modelDiversityScore(b, avoid) - modelDiversityScore(a, avoid));
6498
+ return candidates[0];
6499
+ }
6500
+ function collectConfiguredModelTargets(config) {
6501
+ const seen = /* @__PURE__ */ new Set();
6502
+ const out = [];
6503
+ const add = (provider, model) => {
6504
+ if (!provider || !model) return;
6505
+ const key = `${provider}\0${model}`;
6506
+ if (seen.has(key)) return;
6507
+ seen.add(key);
6508
+ out.push({ provider, model });
6509
+ };
6510
+ add(config.provider, config.model);
6511
+ for (const [providerId, provider] of Object.entries(config.providers ?? {})) {
6512
+ if (!isProviderAvailable(providerId, provider, config.provider)) continue;
6513
+ for (const model of provider.models ?? []) add(providerId, model);
6514
+ for (const model of Object.keys(provider.customModels ?? {})) add(providerId, model);
6515
+ }
6516
+ for (const model of Object.keys(config.models ?? {})) add(config.provider, model);
6517
+ return out;
6518
+ }
6519
+ function isProviderAvailable(providerId, provider, leaderProvider) {
6520
+ if (providerId === leaderProvider) return true;
6521
+ if (typeof provider.apiKey === "string" && provider.apiKey.length > 0) return true;
6522
+ if (Array.isArray(provider.apiKeys) && provider.apiKeys.some((key) => key?.apiKey)) return true;
6523
+ if (typeof provider.baseUrl === "string" && provider.baseUrl.length > 0) return true;
6524
+ return false;
6525
+ }
6526
+ function modelDiversityScore(candidate, avoid) {
6527
+ let score = 0;
6528
+ if (candidate.provider !== avoid.provider) score += 100;
6529
+ if (candidate.model !== avoid.model) score += 20;
6530
+ if (/opus|gpt-5|o3|o4|gemini.*pro|deepseek-r1/i.test(candidate.model)) score += 10;
6531
+ if (/mini|haiku|flash/i.test(candidate.model)) score -= 5;
6532
+ return score;
6533
+ }
6534
+ function matrixKeyKind(key) {
6535
+ if (key === "*") return "default";
6536
+ if (key in AGENT_CATALOG) return "role";
6537
+ if (MATRIX_PHASE_KEYS.includes(key)) return "phase";
6538
+ return "unknown";
6539
+ }
6540
+ function isValidMatrixKey(key) {
6541
+ return matrixKeyKind(key) !== "unknown";
6542
+ }
5752
6543
 
5753
6544
  // src/coordination/coordinator/error-classifier.ts
5754
6545
  function classifySubagentError(err, hints = {}) {
@@ -6770,48 +7561,200 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6770
7561
  }
6771
7562
  };
6772
7563
 
6773
- // src/coordination/director/director-errors.ts
6774
- var FleetSpawnBudgetError = class extends Error {
6775
- kind;
6776
- limit;
6777
- observed;
6778
- constructor(kind, limit, observed, message) {
6779
- const defaultMsg = kind === "max_spawns" ? `Director spawn budget exceeded: tried to spawn #${observed} but maxSpawns is ${limit}` : `Director spawn depth budget exceeded: this director is at depth ${observed} and maxSpawnDepth is ${limit}`;
6780
- super(message ?? defaultMsg);
6781
- this.name = "FleetSpawnBudgetError";
6782
- this.kind = kind;
6783
- this.limit = limit;
6784
- this.observed = observed;
7564
+ // src/coordination/worktree-task-runner.ts
7565
+ var WorktreeIntegrationError = class extends Error {
7566
+ taskId;
7567
+ subagentId;
7568
+ branch;
7569
+ conflictFiles;
7570
+ constructor(message, opts) {
7571
+ super(message);
7572
+ this.name = "WorktreeIntegrationError";
7573
+ this.taskId = opts.taskId;
7574
+ this.subagentId = opts.subagentId;
7575
+ this.branch = opts.branch;
7576
+ this.conflictFiles = opts.conflictFiles;
6785
7577
  }
6786
7578
  };
6787
- var FleetCostCapError = class extends Error {
6788
- kind;
6789
- limit;
6790
- observed;
6791
- constructor(limit, observed) {
6792
- super(
6793
- `Director cost cap exceeded: total fleet spend ${observed.toFixed(4)} exceeds maxCostUsd ${limit.toFixed(4)}`
6794
- );
6795
- this.name = "FleetCostCapError";
6796
- this.kind = "max_cost_usd";
6797
- this.limit = limit;
6798
- this.observed = observed;
7579
+ var MUTATING_TOOL_NAMES = /* @__PURE__ */ new Set([
7580
+ "write",
7581
+ "edit",
7582
+ "replace",
7583
+ "patch",
7584
+ "task",
7585
+ "plan",
7586
+ "design",
7587
+ "document",
7588
+ "scaffold",
7589
+ "bash",
7590
+ "exec",
7591
+ "lint",
7592
+ "format",
7593
+ "typecheck",
7594
+ "test",
7595
+ "install"
7596
+ ]);
7597
+ var MUTATING_CAPABILITIES = /* @__PURE__ */ new Set([
7598
+ ToolCapabilities.FS_WRITE,
7599
+ ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,
7600
+ ToolCapabilities.SHELL_ARBITRARY,
7601
+ ToolCapabilities.SHELL_RESTRICTED,
7602
+ ToolCapabilities.SHELL_EXEC,
7603
+ ToolCapabilities.PACKAGE_INSTALL
7604
+ ]);
7605
+ function subagentNeedsWorktree(config) {
7606
+ if (config.provider === "acp") return false;
7607
+ if (config.tools?.some((tool) => MUTATING_TOOL_NAMES.has(tool))) return true;
7608
+ if (config.allowedCapabilities?.some((cap) => MUTATING_CAPABILITIES.has(cap))) return true;
7609
+ return !config.tools && !config.allowedCapabilities;
7610
+ }
7611
+ function resolveSubagentWorktreeDecision(config, policy) {
7612
+ if (policy?.enabled === false || policy?.mode === "off") return "off";
7613
+ if (config.worktree === false || config.worktree === "off") return "off";
7614
+ if (config.worktree === true || config.worktree === "required") return "required";
7615
+ const needsIsolation = subagentNeedsWorktree(config);
7616
+ if (!needsIsolation) return "off";
7617
+ return policy?.mode === "required" ? "required" : "optional";
7618
+ }
7619
+ function wrapSubagentRunnerWithWorktrees(opts) {
7620
+ return async (task, ctx) => {
7621
+ const decision = resolveSubagentWorktreeDecision(ctx.config, opts.policy);
7622
+ if (decision === "off") return opts.runner(task, ctx);
7623
+ if (!opts.worktrees) {
7624
+ if (decision === "required") {
7625
+ throw new WorktreeIntegrationError(
7626
+ "worktree isolation is required but no WorktreeManager is configured",
7627
+ {
7628
+ taskId: task.id,
7629
+ subagentId: ctx.subagentId
7630
+ }
7631
+ );
7632
+ }
7633
+ return opts.runner(task, ctx);
7634
+ }
7635
+ const handle = await opts.worktrees.allocate(task.id, {
7636
+ slugHint: worktreeSlugHint(task, ctx.config),
7637
+ ownerLabel: worktreeOwnerLabel(task, ctx.config)
7638
+ });
7639
+ if (handle.status !== "active") {
7640
+ emitUpdate(opts, task, ctx, handle, {
7641
+ status: "fallback",
7642
+ error: handle.lastError ?? "worktree allocation failed"
7643
+ });
7644
+ if (decision === "required") {
7645
+ throw new WorktreeIntegrationError(
7646
+ `worktree allocation failed: ${handle.lastError ?? "unknown error"}`,
7647
+ {
7648
+ taskId: task.id,
7649
+ subagentId: ctx.subagentId,
7650
+ branch: handle.branch
7651
+ }
7652
+ );
7653
+ }
7654
+ return opts.runner(task, ctx);
7655
+ }
7656
+ emitUpdate(opts, task, ctx, handle, { status: "allocated" });
7657
+ const isolatedConfig = { ...ctx.config, cwd: handle.dir };
7658
+ const isolatedCtx = { ...ctx, config: isolatedConfig };
7659
+ let outcome;
7660
+ try {
7661
+ outcome = await opts.runner(task, isolatedCtx);
7662
+ } catch (err) {
7663
+ await parkFailedWorktree(opts, task, ctx, handle, err);
7664
+ throw err;
7665
+ }
7666
+ await integrateSuccessfulWorktree(opts, task, ctx, isolatedConfig, handle);
7667
+ return outcome;
7668
+ };
7669
+ }
7670
+ async function integrateSuccessfulWorktree(opts, task, ctx, config, handle) {
7671
+ const committed = await opts.worktrees.commitAll(
7672
+ handle,
7673
+ `subagent(${config.role ?? config.name}): ${task.id}`
7674
+ );
7675
+ if (!committed.committed) {
7676
+ await opts.worktrees.release(handle, { keep: false });
7677
+ emitUpdate(opts, task, ctx, handle, { status: "released" });
7678
+ return;
6799
7679
  }
6800
- };
6801
- var FleetContextOverflowError = class extends Error {
6802
- kind;
6803
- limit;
6804
- observed;
6805
- constructor(limit, observed) {
6806
- super(
6807
- `Leader context overflow: leader has ${observed} tokens in flight (limit: ${limit}). Compact the leader context before spawning more subagents.`
7680
+ emitUpdate(opts, task, ctx, handle, { status: "committed", commitSha: handle.sha });
7681
+ if (opts.policy?.autoMerge === false) {
7682
+ await opts.worktrees.release(handle, { keep: true });
7683
+ emitUpdate(opts, task, ctx, handle, { status: "kept", commitSha: handle.sha });
7684
+ return;
7685
+ }
7686
+ const merged = await opts.worktrees.merge(handle, {
7687
+ squash: true,
7688
+ message: `merge subagent ${ctx.subagentId} task ${task.id} (squash)`,
7689
+ ...opts.conflictResolver ? {
7690
+ resolve: (info) => opts.conflictResolver({
7691
+ task,
7692
+ config,
7693
+ conflictFiles: info.conflictFiles,
7694
+ cwd: info.cwd
7695
+ })
7696
+ } : {}
7697
+ });
7698
+ if (!merged.ok) {
7699
+ await opts.worktrees.release(handle, { keep: true }).catch(() => void 0);
7700
+ const conflictFiles = merged.conflictFiles ?? [];
7701
+ emitUpdate(opts, task, ctx, handle, {
7702
+ status: merged.conflict ? "conflict" : "failed",
7703
+ commitSha: handle.sha,
7704
+ conflictFiles,
7705
+ error: merged.stderr || (merged.conflict ? "merge conflict" : "worktree merge failed")
7706
+ });
7707
+ throw new WorktreeIntegrationError(
7708
+ merged.conflict ? `worktree merge conflict${conflictFiles.length ? `: ${conflictFiles.join(", ")}` : ""}` : `worktree merge failed: ${merged.stderr ?? "unknown error"}`,
7709
+ {
7710
+ taskId: task.id,
7711
+ subagentId: ctx.subagentId,
7712
+ branch: handle.branch,
7713
+ conflictFiles
7714
+ }
6808
7715
  );
6809
- this.name = "FleetContextOverflowError";
6810
- this.kind = "max_context_load";
6811
- this.limit = limit;
6812
- this.observed = observed;
6813
7716
  }
6814
- };
7717
+ await opts.worktrees.release(handle, { keep: false });
7718
+ emitUpdate(opts, task, ctx, handle, { status: "merged", commitSha: handle.sha });
7719
+ }
7720
+ async function parkFailedWorktree(opts, task, ctx, handle, err) {
7721
+ let committed = false;
7722
+ try {
7723
+ const res = await opts.worktrees.commitAll(
7724
+ handle,
7725
+ `subagent(${ctx.config.role ?? ctx.config.name}) failed: ${task.id}`
7726
+ );
7727
+ committed = res.committed;
7728
+ } catch {
7729
+ committed = false;
7730
+ }
7731
+ const keep = (opts.policy?.keepFailed ?? true) && committed;
7732
+ await opts.worktrees.release(handle, { keep }).catch(() => void 0);
7733
+ emitUpdate(opts, task, ctx, handle, {
7734
+ status: keep ? "kept" : "released",
7735
+ commitSha: handle.sha,
7736
+ error: toErrorMessage(err)
7737
+ });
7738
+ }
7739
+ function emitUpdate(opts, task, ctx, handle, patch) {
7740
+ opts.onUpdate?.({
7741
+ taskId: task.id,
7742
+ subagentId: ctx.subagentId,
7743
+ handleId: handle.id,
7744
+ dir: handle.dir,
7745
+ branch: handle.branch,
7746
+ baseBranch: handle.baseBranch,
7747
+ ...patch
7748
+ });
7749
+ }
7750
+ function worktreeSlugHint(task, config) {
7751
+ return `${config.role ?? config.name ?? "subagent"}-${task.id}`;
7752
+ }
7753
+ function worktreeOwnerLabel(task, config) {
7754
+ const who = config.name || config.role || "Subagent";
7755
+ const brief = task.description.trim().replace(/\s+/g, " ").slice(0, 80);
7756
+ return brief ? `${who}: ${brief}` : who;
7757
+ }
6815
7758
 
6816
7759
  // src/coordination/director.ts
6817
7760
  var Director = class _Director {
@@ -6943,6 +7886,8 @@ var Director = class _Director {
6943
7886
  /** Resolves task descriptions back from `assign()` so completion events
6944
7887
  * can also carry a human-readable title. */
6945
7888
  taskDescriptions = /* @__PURE__ */ new Map();
7889
+ /** Latest worktree state per task id (allocated/committed/merged/conflict/etc.). */
7890
+ taskWorktrees = /* @__PURE__ */ new Map();
6946
7891
  /** Snapshot of which subagent owns each task — drives state-checkpoint
6947
7892
  * status updates without re-walking the manifest. */
6948
7893
  taskOwners = /* @__PURE__ */ new Map();
@@ -7056,9 +8001,16 @@ var Director = class _Director {
7056
8001
  (id) => this.subagentMeta.get(id)
7057
8002
  );
7058
8003
  }
8004
+ const runner = opts.runner && (opts.worktrees || opts.worktreePolicy) ? wrapSubagentRunnerWithWorktrees({
8005
+ runner: opts.runner,
8006
+ worktrees: opts.worktrees,
8007
+ policy: opts.worktreePolicy,
8008
+ conflictResolver: opts.worktreeConflictResolver,
8009
+ onUpdate: (update) => this.recordWorktreeTaskUpdate(update)
8010
+ }) : opts.runner;
7059
8011
  this.coordinator = new DefaultMultiAgentCoordinator(
7060
8012
  { ...opts.config, coordinatorId: this.id },
7061
- { runner: opts.runner, sessionId: () => this.currentSessionId() }
8013
+ { runner, sessionId: () => this.currentSessionId() }
7062
8014
  );
7063
8015
  this.coordinator.setFleetBus(this.fleet);
7064
8016
  this.fleetManager?.setCoordinator(this.coordinator);
@@ -7428,6 +8380,17 @@ var Director = class _Director {
7428
8380
  clearTimeout(this.manifestTimer);
7429
8381
  this.manifestTimer = null;
7430
8382
  }
8383
+ recordWorktreeTaskUpdate(update) {
8384
+ this.taskWorktrees.set(update.taskId, update);
8385
+ const owner = this.taskOwners.get(update.taskId) ?? update.subagentId;
8386
+ const entry = this.manifestEntries.get(owner);
8387
+ if (entry) {
8388
+ entry.worktrees = { ...entry.worktrees ?? {}, [update.taskId]: update };
8389
+ }
8390
+ this.stateCheckpoint?.recordTaskWorktree(update.taskId, update);
8391
+ this.fleetManager?.recordTaskWorktree(update);
8392
+ if (!this.fleetManager) this.scheduleManifest();
8393
+ }
7431
8394
  /**
7432
8395
  * Spawn a subagent. Identical to the coordinator's `spawn()` but
7433
8396
  * captures provider/model metadata for the usage aggregator and
@@ -7449,7 +8412,8 @@ var Director = class _Director {
7449
8412
  const config = { ...callerConfig };
7450
8413
  if (!config.model && this.modelMatrix) {
7451
8414
  const matrix = typeof this.modelMatrix === "function" ? this.modelMatrix() : this.modelMatrix;
7452
- const entry = resolveModelMatrix(matrix, config.role);
8415
+ const resolution = resolveModelMatrixResolution(matrix, config.role);
8416
+ const entry = resolution?.source === "default" && roleNeedsIndependentReviewModel(config.role) ? void 0 : resolution?.entry;
7453
8417
  if (entry?.model) {
7454
8418
  config.model = entry.model;
7455
8419
  if (entry.provider) config.provider = entry.provider;
@@ -7669,13 +8633,15 @@ var Director = class _Director {
7669
8633
  // success/failure state.
7670
8634
  results: e.taskIds.map((tid) => {
7671
8635
  const r = this.completed.get(tid);
8636
+ const worktree = e.worktrees?.[tid];
7672
8637
  return r ? {
7673
8638
  taskId: tid,
7674
8639
  status: r.status,
7675
8640
  iterations: r.iterations,
7676
8641
  toolCalls: r.toolCalls,
7677
- durationMs: r.durationMs
7678
- } : { taskId: tid, status: "pending" };
8642
+ durationMs: r.durationMs,
8643
+ ...worktree ? { worktree } : {}
8644
+ } : { taskId: tid, status: "pending", ...worktree ? { worktree } : {} };
7679
8645
  })
7680
8646
  })),
7681
8647
  usage: this.usage.snapshot()
@@ -8114,6 +9080,7 @@ var Director = class _Director {
8114
9080
  makeAskTool(this),
8115
9081
  makeAskResultTool(this),
8116
9082
  makeRollUpTool(this),
9083
+ makeQualityGateTool(this, effectiveRoster),
8117
9084
  makeTerminateTool(this),
8118
9085
  makeTerminateAllTool(this),
8119
9086
  makeFleetTool(this),
@@ -10207,14 +11174,17 @@ var FleetManager = class {
10207
11174
  model: config.model,
10208
11175
  taskIds: []
10209
11176
  });
10210
- this.stateCheckpoint?.recordSpawn({
10211
- id: subagentId,
10212
- name: config.name,
10213
- role: config.role,
10214
- provider: config.provider,
10215
- model: config.model,
10216
- spawnedAt: (/* @__PURE__ */ new Date()).toISOString()
10217
- }, this.spawnCount);
11177
+ this.stateCheckpoint?.recordSpawn(
11178
+ {
11179
+ id: subagentId,
11180
+ name: config.name,
11181
+ role: config.role,
11182
+ provider: config.provider,
11183
+ model: config.model,
11184
+ spawnedAt: (/* @__PURE__ */ new Date()).toISOString()
11185
+ },
11186
+ this.spawnCount
11187
+ );
10218
11188
  void this.appendSessionEvent({
10219
11189
  type: "agent_spawned",
10220
11190
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -10242,7 +11212,8 @@ var FleetManager = class {
10242
11212
  role: entry.role,
10243
11213
  provider: entry.provider,
10244
11214
  model: entry.model,
10245
- taskIds: entry.taskIds
11215
+ taskIds: entry.taskIds,
11216
+ worktrees: entry.worktrees
10246
11217
  })),
10247
11218
  usage: this.usage.snapshot()
10248
11219
  };
@@ -10258,6 +11229,14 @@ var FleetManager = class {
10258
11229
  const entry = this.manifestEntries.get(subagentId);
10259
11230
  if (entry) entry.taskIds.push(taskId);
10260
11231
  }
11232
+ recordTaskWorktree(update) {
11233
+ const entry = this.manifestEntries.get(update.subagentId);
11234
+ if (entry) {
11235
+ entry.worktrees = { ...entry.worktrees ?? {}, [update.taskId]: update };
11236
+ }
11237
+ this.stateCheckpoint?.recordTaskWorktree(update.taskId, update);
11238
+ this.scheduleManifest();
11239
+ }
10261
11240
  /**
10262
11241
  * Debounced manifest write. Call after any state mutation
10263
11242
  * (spawn, assign, complete) so a burst collapses into one write.
@@ -10269,10 +11248,7 @@ var FleetManager = class {
10269
11248
  if (this.manifestDebounceMs === 0) {
10270
11249
  void this.writeManifest().catch((err) => {
10271
11250
  const detail = toErrorMessage(err);
10272
- process.emitWarning(
10273
- `FleetManager manifest write failed: ${detail}`,
10274
- "FleetManagerWarning"
10275
- );
11251
+ process.emitWarning(`FleetManager manifest write failed: ${detail}`, "FleetManagerWarning");
10276
11252
  });
10277
11253
  return;
10278
11254
  }
@@ -10282,10 +11258,7 @@ var FleetManager = class {
10282
11258
  this.manifestTimer = null;
10283
11259
  void this.writeManifest().catch((err) => {
10284
11260
  const detail = toErrorMessage(err);
10285
- process.emitWarning(
10286
- `FleetManager manifest write failed: ${detail}`,
10287
- "FleetManagerWarning"
10288
- );
11261
+ process.emitWarning(`FleetManager manifest write failed: ${detail}`, "FleetManagerWarning");
10289
11262
  });
10290
11263
  }, this.manifestDebounceMs);
10291
11264
  }
@@ -10298,10 +11271,7 @@ var FleetManager = class {
10298
11271
  this.clearManifestTimer();
10299
11272
  await this.writeManifest().catch((err) => {
10300
11273
  const detail = toErrorMessage(err);
10301
- process.emitWarning(
10302
- `FleetManager manifest write failed: ${detail}`,
10303
- "FleetManagerWarning"
10304
- );
11274
+ process.emitWarning(`FleetManager manifest write failed: ${detail}`, "FleetManagerWarning");
10305
11275
  });
10306
11276
  }
10307
11277
  clearManifestTimer() {
@@ -11467,166 +12437,6 @@ function formatMessage(m, readerId) {
11467
12437
  };
11468
12438
  }
11469
12439
 
11470
- // src/coordination/mail-tools.ts
11471
- function makeResolver(opts) {
11472
- return opts.resolveMailbox ?? ((ctx) => new GlobalMailbox(opts.projectDir ?? defaultResolveProjectDir(ctx), opts.events));
11473
- }
11474
- async function register(mb, ctx) {
11475
- const identity = resolveMailboxIdentity(ctx);
11476
- try {
11477
- await mb.registerAgent({
11478
- agentId: identity.callerId,
11479
- sessionId: identity.sessionId,
11480
- name: identity.name,
11481
- role: identity.role,
11482
- pid: process.pid,
11483
- source: ctx.meta["source"] ?? "cli"
11484
- });
11485
- await mb.heartbeat({ agentId: identity.callerId });
11486
- } catch {
11487
- }
11488
- return identity;
11489
- }
11490
- function makeMailSendTool(opts = {}) {
11491
- const resolveMailbox = makeResolver(opts);
11492
- return {
11493
- name: "mail_send",
11494
- description: 'Send a mail to other agents working on this project (other terminals, TUIs, WebUIs). Use it to hand off work, ask questions, announce what you just did, or request a review (type="review" \u2014 passive ask, no immediate reply required). to="*" broadcasts to everyone; to="leader" reaches every leader process; an exact id like "leader@a1b2c3d4" reaches one agent. Recipients see your mail automatically before their next step. Pick the type that matches the intent: note (default), ask (blocking question), assign (task), steer (mid-task direction), result (completion notice), review (passive ask), btw/status/broadcast/control (informational).',
11495
- usageHint: 'mail_send to="<id>" type="review" body="please skim <file>"',
11496
- category: "Coordination",
11497
- permission: "auto",
11498
- mutating: true,
11499
- capabilities: [ToolCapabilities.COORDINATION_MAIL],
11500
- inputSchema: {
11501
- type: "object",
11502
- properties: {
11503
- to: {
11504
- type: "string",
11505
- description: 'Recipient: exact agent id ("leader@a1b2c3d4"), base alias ("leader"), or "*" / "all" for everyone.'
11506
- },
11507
- subject: { type: "string", description: "Short subject line." },
11508
- body: { type: "string", description: "The message." },
11509
- type: {
11510
- type: "string",
11511
- enum: ["note", "ask", "assign", "steer", "btw", "broadcast", "status", "result", "review"],
11512
- description: 'Message intent. Default: "broadcast" when to="*", otherwise "note". Actionable types: ask (blocking question), assign (task), result (completion notice), review (passive ask \u2014 code/doc/PR review, no immediate reply required). Behavioral: steer (mid-task direction change), btw (low-priority aside). Informational: note/status/broadcast/control.'
11513
- },
11514
- priority: { type: "string", enum: ["low", "normal", "high"] },
11515
- replyTo: { type: "string", description: "Message id this replies to." }
11516
- },
11517
- required: ["to", "subject", "body"]
11518
- },
11519
- async execute(input, ctx) {
11520
- const i = input ?? {};
11521
- const rawTo = i.to;
11522
- const subject = i.subject;
11523
- const body = i.body;
11524
- if (!rawTo || !subject || body === void 0 || body === null) {
11525
- return { ok: false, error: '"to", "subject" and "body" are required.' };
11526
- }
11527
- const to = normalizeRecipient(rawTo);
11528
- const mb = resolveMailbox(ctx);
11529
- const identity = await register(mb, ctx);
11530
- const type = i.type ?? (to === "*" ? "broadcast" : "note");
11531
- const msg = await mb.send({
11532
- from: identity.callerId,
11533
- to,
11534
- type,
11535
- subject,
11536
- body,
11537
- priority: i.priority ?? "normal",
11538
- replyTo: i.replyTo
11539
- });
11540
- return {
11541
- ok: true,
11542
- messageId: msg.id,
11543
- from: identity.callerId,
11544
- to: msg.to,
11545
- summary: `Mail sent to ${msg.to === "*" ? "all agents" : msg.to} as ${identity.callerId}.`
11546
- };
11547
- }
11548
- };
11549
- }
11550
- function makeMailInboxTool(opts = {}) {
11551
- const resolveMailbox = makeResolver(opts);
11552
- return {
11553
- name: "mail_inbox",
11554
- description: 'Read your unread mail from other agents on this project and mark it read. Covers mail addressed to you directly, to your base name (e.g. "leader"), and broadcasts ("*"). Urgent steer/btw mail is already injected automatically \u2014 use this to catch up on notes, questions, handoffs, results, and review requests (type="review" \u2014 passive asks where no reply is required). Best called after a long stretch of tool work. Set completed=true to finish every returned message in the same call.',
11555
- usageHint: 'mail_inbox (optionally: limit=10, markRead=false to peek, completed=true outcome="handled")',
11556
- category: "Coordination",
11557
- permission: "auto",
11558
- mutating: true,
11559
- capabilities: [ToolCapabilities.COORDINATION_MAIL],
11560
- inputSchema: {
11561
- type: "object",
11562
- properties: {
11563
- limit: { type: "number", description: "Max messages to return (default 20)." },
11564
- markRead: {
11565
- type: "boolean",
11566
- description: "Add a read receipt for each returned message (default true)."
11567
- },
11568
- completed: {
11569
- type: "boolean",
11570
- description: "Also mark each returned message completed (default false)."
11571
- },
11572
- outcome: {
11573
- type: "string",
11574
- description: "Completion outcome to store when completed=true."
11575
- }
11576
- }
11577
- },
11578
- async execute(input, ctx) {
11579
- const i = input ?? {};
11580
- const limit = i.limit ?? 20;
11581
- const markRead = i.markRead ?? true;
11582
- const completed = i.completed ?? false;
11583
- const outcome = i.outcome;
11584
- const mb = resolveMailbox(ctx);
11585
- const identity = await register(mb, ctx);
11586
- const targets = [identity.callerId];
11587
- if (identity.baseId !== identity.callerId) targets.push(identity.baseId);
11588
- const batches = await Promise.all(
11589
- targets.map(
11590
- (to) => mb.query({ to, unreadBy: identity.callerId, limit }).catch(() => [])
11591
- )
11592
- );
11593
- const seen = /* @__PURE__ */ new Set();
11594
- const messages = batches.flat().filter((m) => {
11595
- if (seen.has(m.id) || m.from === identity.callerId) return false;
11596
- seen.add(m.id);
11597
- return true;
11598
- }).slice(0, limit);
11599
- if (markRead || completed) {
11600
- await mb.ackMany({
11601
- acks: messages.map((m) => ({
11602
- messageId: m.id,
11603
- readerId: identity.callerId,
11604
- read: markRead,
11605
- completed,
11606
- outcome: completed ? outcome : void 0
11607
- }))
11608
- }).catch(() => null);
11609
- }
11610
- return {
11611
- ok: true,
11612
- you: identity.callerId,
11613
- count: messages.length,
11614
- messages: messages.map((m) => ({
11615
- id: m.id,
11616
- from: m.from,
11617
- to: m.to,
11618
- type: m.type,
11619
- subject: m.subject,
11620
- body: m.body.length > 2e3 ? `${m.body.slice(0, 2e3)}\u2026 [truncated]` : m.body,
11621
- timestamp: m.timestamp,
11622
- replyTo: m.replyTo
11623
- })),
11624
- summary: messages.length === 0 ? "Inbox empty." : `${messages.length} unread message(s)${markRead ? " (marked read)" : ""}${completed ? " (completed)" : ""}. Reply with mail_send using the sender id.`
11625
- };
11626
- }
11627
- };
11628
- }
11629
-
11630
12440
  // src/coordination/fleet-status-tool.ts
11631
12441
  var TASK_SNIPPET_CHARS = 120;
11632
12442
  function snippet(s) {
@@ -12271,6 +13081,166 @@ Idle workers: ${idleWorkerIds.join(", ")}`,
12271
13081
  }
12272
13082
  }
12273
13083
  };
13084
+
13085
+ // src/coordination/mail-tools.ts
13086
+ function makeResolver(opts) {
13087
+ return opts.resolveMailbox ?? ((ctx) => new GlobalMailbox(opts.projectDir ?? defaultResolveProjectDir(ctx), opts.events));
13088
+ }
13089
+ async function register(mb, ctx) {
13090
+ const identity = resolveMailboxIdentity(ctx);
13091
+ try {
13092
+ await mb.registerAgent({
13093
+ agentId: identity.callerId,
13094
+ sessionId: identity.sessionId,
13095
+ name: identity.name,
13096
+ role: identity.role,
13097
+ pid: process.pid,
13098
+ source: ctx.meta["source"] ?? "cli"
13099
+ });
13100
+ await mb.heartbeat({ agentId: identity.callerId });
13101
+ } catch {
13102
+ }
13103
+ return identity;
13104
+ }
13105
+ function makeMailSendTool(opts = {}) {
13106
+ const resolveMailbox = makeResolver(opts);
13107
+ return {
13108
+ name: "mail_send",
13109
+ description: 'Send a mail to other agents working on this project (other terminals, TUIs, WebUIs). Use it to hand off work, ask questions, announce what you just did, or request a review (type="review" \u2014 passive ask, no immediate reply required). to="*" broadcasts to everyone; to="leader" reaches every leader process; an exact id like "leader@a1b2c3d4" reaches one agent. Recipients see your mail automatically before their next step. Pick the type that matches the intent: note (default), ask (blocking question), assign (task), steer (mid-task direction), result (completion notice), review (passive ask), btw/status/broadcast/control (informational).',
13110
+ usageHint: 'mail_send to="<id>" type="review" body="please skim <file>"',
13111
+ category: "Coordination",
13112
+ permission: "auto",
13113
+ mutating: true,
13114
+ capabilities: [ToolCapabilities.COORDINATION_MAIL],
13115
+ inputSchema: {
13116
+ type: "object",
13117
+ properties: {
13118
+ to: {
13119
+ type: "string",
13120
+ description: 'Recipient: exact agent id ("leader@a1b2c3d4"), base alias ("leader"), or "*" / "all" for everyone.'
13121
+ },
13122
+ subject: { type: "string", description: "Short subject line." },
13123
+ body: { type: "string", description: "The message." },
13124
+ type: {
13125
+ type: "string",
13126
+ enum: ["note", "ask", "assign", "steer", "btw", "broadcast", "status", "result", "review"],
13127
+ description: 'Message intent. Default: "broadcast" when to="*", otherwise "note". Actionable types: ask (blocking question), assign (task), result (completion notice), review (passive ask \u2014 code/doc/PR review, no immediate reply required). Behavioral: steer (mid-task direction change), btw (low-priority aside). Informational: note/status/broadcast/control.'
13128
+ },
13129
+ priority: { type: "string", enum: ["low", "normal", "high"] },
13130
+ replyTo: { type: "string", description: "Message id this replies to." }
13131
+ },
13132
+ required: ["to", "subject", "body"]
13133
+ },
13134
+ async execute(input, ctx) {
13135
+ const i = input ?? {};
13136
+ const rawTo = i.to;
13137
+ const subject = i.subject;
13138
+ const body = i.body;
13139
+ if (!rawTo || !subject || body === void 0 || body === null) {
13140
+ return { ok: false, error: '"to", "subject" and "body" are required.' };
13141
+ }
13142
+ const to = normalizeRecipient(rawTo);
13143
+ const mb = resolveMailbox(ctx);
13144
+ const identity = await register(mb, ctx);
13145
+ const type = i.type ?? (to === "*" ? "broadcast" : "note");
13146
+ const msg = await mb.send({
13147
+ from: identity.callerId,
13148
+ to,
13149
+ type,
13150
+ subject,
13151
+ body,
13152
+ priority: i.priority ?? "normal",
13153
+ replyTo: i.replyTo
13154
+ });
13155
+ return {
13156
+ ok: true,
13157
+ messageId: msg.id,
13158
+ from: identity.callerId,
13159
+ to: msg.to,
13160
+ summary: `Mail sent to ${msg.to === "*" ? "all agents" : msg.to} as ${identity.callerId}.`
13161
+ };
13162
+ }
13163
+ };
13164
+ }
13165
+ function makeMailInboxTool(opts = {}) {
13166
+ const resolveMailbox = makeResolver(opts);
13167
+ return {
13168
+ name: "mail_inbox",
13169
+ description: 'Read your unread mail from other agents on this project and mark it read. Covers mail addressed to you directly, to your base name (e.g. "leader"), and broadcasts ("*"). Urgent steer/btw mail is already injected automatically \u2014 use this to catch up on notes, questions, handoffs, results, and review requests (type="review" \u2014 passive asks where no reply is required). Best called after a long stretch of tool work. Set completed=true to finish every returned message in the same call.',
13170
+ usageHint: 'mail_inbox (optionally: limit=10, markRead=false to peek, completed=true outcome="handled")',
13171
+ category: "Coordination",
13172
+ permission: "auto",
13173
+ mutating: true,
13174
+ capabilities: [ToolCapabilities.COORDINATION_MAIL],
13175
+ inputSchema: {
13176
+ type: "object",
13177
+ properties: {
13178
+ limit: { type: "number", description: "Max messages to return (default 20)." },
13179
+ markRead: {
13180
+ type: "boolean",
13181
+ description: "Add a read receipt for each returned message (default true)."
13182
+ },
13183
+ completed: {
13184
+ type: "boolean",
13185
+ description: "Also mark each returned message completed (default false)."
13186
+ },
13187
+ outcome: {
13188
+ type: "string",
13189
+ description: "Completion outcome to store when completed=true."
13190
+ }
13191
+ }
13192
+ },
13193
+ async execute(input, ctx) {
13194
+ const i = input ?? {};
13195
+ const limit = i.limit ?? 20;
13196
+ const markRead = i.markRead ?? true;
13197
+ const completed = i.completed ?? false;
13198
+ const outcome = i.outcome;
13199
+ const mb = resolveMailbox(ctx);
13200
+ const identity = await register(mb, ctx);
13201
+ const targets = [identity.callerId];
13202
+ if (identity.baseId !== identity.callerId) targets.push(identity.baseId);
13203
+ const batches = await Promise.all(
13204
+ targets.map(
13205
+ (to) => mb.query({ to, unreadBy: identity.callerId, limit }).catch(() => [])
13206
+ )
13207
+ );
13208
+ const seen = /* @__PURE__ */ new Set();
13209
+ const messages = batches.flat().filter((m) => {
13210
+ if (seen.has(m.id) || m.from === identity.callerId) return false;
13211
+ seen.add(m.id);
13212
+ return true;
13213
+ }).slice(0, limit);
13214
+ if (markRead || completed) {
13215
+ await mb.ackMany({
13216
+ acks: messages.map((m) => ({
13217
+ messageId: m.id,
13218
+ readerId: identity.callerId,
13219
+ read: markRead,
13220
+ completed,
13221
+ outcome: completed ? outcome : void 0
13222
+ }))
13223
+ }).catch(() => null);
13224
+ }
13225
+ return {
13226
+ ok: true,
13227
+ you: identity.callerId,
13228
+ count: messages.length,
13229
+ messages: messages.map((m) => ({
13230
+ id: m.id,
13231
+ from: m.from,
13232
+ to: m.to,
13233
+ type: m.type,
13234
+ subject: m.subject,
13235
+ body: m.body.length > 2e3 ? `${m.body.slice(0, 2e3)}\u2026 [truncated]` : m.body,
13236
+ timestamp: m.timestamp,
13237
+ replyTo: m.replyTo
13238
+ })),
13239
+ summary: messages.length === 0 ? "Inbox empty." : `${messages.length} unread message(s)${markRead ? " (marked read)" : ""}${completed ? " (completed)" : ""}. Reply with mail_send using the sender id.`
13240
+ };
13241
+ }
13242
+ };
13243
+ }
12274
13244
  var MAILBOX_FILE2 = "_mailbox.jsonl";
12275
13245
  var LINE_SEPARATOR2 = "\n";
12276
13246
  var MESSAGE_CACHE_MAX_ENTRIES2 = 1e4;
@@ -16272,6 +17242,6 @@ ${input.detail}`
16272
17242
  }
16273
17243
  };
16274
17244
 
16275
- export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, TOOLS as AGENT_TOOL_PRESETS, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, AdaptiveConcurrencyController, AgentMonitorService, 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, FleetSupervisor, FleetUsageAggregator, GlobalMailbox, HEAVY_BUDGET, HumanEscalatingBrainArbiter, InMemoryAgentBridge, InMemoryBridgeTransport, KNOWLEDGE_AGENTS, KnowledgeGraph, LIGHT_BUDGET, LargeAnswerStore, MAILBOX_BRIDGE_LOCK_FILENAME, MAILBOX_BRIDGE_TOKEN_FILENAME, MAILBOX_HEALTH_DEFAULT_FAILURE_THRESHOLD, MAILBOX_HEALTH_DEFAULT_FROM, MAILBOX_HEALTH_DEFAULT_INTERVAL_MS, MAILBOX_HEALTH_DEFAULT_TIMEOUT_MS, MEDIUM_BUDGET, META_AGENTS, MailboxHealthWatchdog, NULL_FLEET_BUS, ObservableBrainArbiter, PLANNING_AGENTS, REFACTOR_PLANNER_AGENT, REVIEW_AGENTS, SECURITY_SCANNER_AGENT, SubagentBudget, TIMEOUT_PREEMPT_FRACTION, TaskAuctioneer, TaskDAG, VERIFY_AGENTS, acquireOrJoin, actionToAckInput, applyRosterBudget, attachAutoExtend, attachDepWatcherBridge, buildDownAlert, buildRecoveryAlert, composeDirectorPrompt, composeSubagentPrompt, createAgentMonitorService, createDelegateTool, createMailboxHooks, createMessage, detectEcosystem, dispatchAgent, finalize, formatHumanPrompt, getAgentDefinition, getFullPackageLog, getManifestPackages, getPackageAuthor, getPackagesByAgent, mailboxSessionTag, makeAgentSubagentRunner, makeAskResultTool, makeAskTool, makeAssignTool, makeAwaitTasksTool, makeCollabDebugTool, makeDependencyWatcherConfig, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetTool as makeFleetHealthTool, makeFleetTool as makeFleetSessionTool, makeFleetStatusTool, makeFleetTool, makeFleetTool as makeFleetUsageTool, makeLLMClassifier, makeMailInboxTool, makeMailSendTool, makeMailboxTool, makeRollUpTool, makeSpawnTool, makeTerminateAllTool, makeTerminateTool, makeWorkCompleteTool, normalizeRecipient, readLiveLock, recordPackageAction, release, resolveMailboxIdentity, resolveProjectDir, rosterSummaryFromConfigs, scoreAgents, startPackageOutdatedWatcher, updatePackageOutdatedStatus, validateWatchdogOptions, withDisabledToolFiltering };
17245
+ export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, TOOLS as AGENT_TOOL_PRESETS, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, AdaptiveConcurrencyController, AgentMonitorService, 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, FleetSupervisor, FleetUsageAggregator, GlobalMailbox, HEAVY_BUDGET, HumanEscalatingBrainArbiter, InMemoryAgentBridge, InMemoryBridgeTransport, KNOWLEDGE_AGENTS, KnowledgeGraph, LIGHT_BUDGET, LargeAnswerStore, MAILBOX_BRIDGE_LOCK_FILENAME, MAILBOX_BRIDGE_TOKEN_FILENAME, MAILBOX_HEALTH_DEFAULT_FAILURE_THRESHOLD, MAILBOX_HEALTH_DEFAULT_FROM, MAILBOX_HEALTH_DEFAULT_INTERVAL_MS, MAILBOX_HEALTH_DEFAULT_TIMEOUT_MS, MATRIX_PHASE_KEYS, MEDIUM_BUDGET, META_AGENTS, MailboxHealthWatchdog, NULL_FLEET_BUS, ObservableBrainArbiter, PLANNING_AGENTS, REFACTOR_PLANNER_AGENT, REVIEW_AGENTS, SECURITY_SCANNER_AGENT, SubagentBudget, TIMEOUT_PREEMPT_FRACTION, TaskAuctioneer, TaskDAG, VERIFY_AGENTS, WorktreeIntegrationError, acquireOrJoin, actionToAckInput, applyRosterBudget, attachAutoExtend, attachDepWatcherBridge, buildDownAlert, buildRecoveryAlert, composeDirectorPrompt, composeSubagentPrompt, createAgentMonitorService, createDelegateTool, createMailboxHooks, createMessage, detectEcosystem, dispatchAgent, finalize, formatHumanPrompt, getAgentDefinition, getFullPackageLog, getManifestPackages, getPackageAuthor, getPackagesByAgent, isValidMatrixKey, mailboxSessionTag, makeAgentSubagentRunner, makeAskResultTool, makeAskTool, makeAssignTool, makeAwaitTasksTool, makeCollabDebugTool, makeDependencyWatcherConfig, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetTool as makeFleetHealthTool, makeFleetTool as makeFleetSessionTool, makeFleetStatusTool, makeFleetTool, makeFleetTool as makeFleetUsageTool, makeLLMClassifier, makeMailInboxTool, makeMailSendTool, makeMailboxTool, makeQualityGateTool, makeRollUpTool, makeSpawnTool, makeTerminateAllTool, makeTerminateTool, makeWorkCompleteTool, matrixKeyKind, normalizeRecipient, phaseForRole, readLiveLock, recordPackageAction, release, resolveImplementationModelTarget, resolveMailboxIdentity, resolveModelMatrix, resolveModelMatrixResolution, resolveModelTargetFromEntry, resolveProjectDir, resolveSubagentModelTarget, resolveSubagentWorktreeDecision, roleNeedsIndependentReviewModel, rosterSummaryFromConfigs, sameModelReference, scoreAgents, startPackageOutdatedWatcher, subagentNeedsWorktree, updatePackageOutdatedStatus, validateWatchdogOptions, withDisabledToolFiltering, wrapSubagentRunnerWithWorktrees };
16276
17246
  //# sourceMappingURL=index.js.map
16277
17247
  //# sourceMappingURL=index.js.map