@wrongstack/core 0.277.2 → 0.280.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 (83) hide show
  1. package/dist/{agent-bridge-BFJ2ODzI.d.ts → agent-bridge-DXC6QDJ4.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-BimKihiC.d.ts → agent-subagent-runner-PoqNKiR4.d.ts} +563 -471
  3. package/dist/{compactor-D3BGw26y.d.ts → compactor-U3agvUIG.d.ts} +1 -1
  4. package/dist/{config-DAOjriz9.d.ts → config-Cr3312zc.d.ts} +102 -4
  5. package/dist/coordination/index.d.ts +1087 -998
  6. package/dist/coordination/index.js +12235 -12052
  7. package/dist/coordination/index.js.map +1 -1
  8. package/dist/defaults/index.d.ts +31 -30
  9. package/dist/defaults/index.js +403 -189
  10. package/dist/defaults/index.js.map +1 -1
  11. package/dist/{brain-CCfuEOdp.d.ts → events-Bs2fmldo.d.ts} +117 -112
  12. package/dist/execution/index.d.ts +27 -19
  13. package/dist/execution/index.js +216 -63
  14. package/dist/execution/index.js.map +1 -1
  15. package/dist/execution/prompt-enhancer.d.ts +1 -1
  16. package/dist/execution/prompt-enhancer.js.map +1 -1
  17. package/dist/extension/index.d.ts +8 -7
  18. package/dist/{global-mailbox-Dr4cTKqL.d.ts → global-mailbox-Ct7IorLJ.d.ts} +84 -6
  19. package/dist/{goal-store-C1uH4srH.d.ts → goal-store-C4F6DjC0.d.ts} +1 -1
  20. package/dist/hq/index.d.ts +504 -7
  21. package/dist/hq/index.js +1069 -20
  22. package/dist/hq/index.js.map +1 -1
  23. package/dist/{index-DJXj-dcr.d.ts → index-kidebiDh.d.ts} +8 -5
  24. package/dist/{index-cMEmzCVN.d.ts → index-nP09-oP2.d.ts} +2 -2
  25. package/dist/index.d.ts +153 -76
  26. package/dist/index.js +5791 -3163
  27. package/dist/index.js.map +1 -1
  28. package/dist/infrastructure/index.d.ts +7 -6
  29. package/dist/kernel/index.d.ts +14 -13
  30. package/dist/kernel/index.js +31 -15
  31. package/dist/kernel/index.js.map +1 -1
  32. package/dist/{mailbox-types-DTl7bRH3.d.ts → mailbox-types-BGZWrYTJ.d.ts} +38 -0
  33. package/dist/{mcp-servers-CFb60-pH.d.ts → mcp-servers-D910X5_r.d.ts} +3 -3
  34. package/dist/models/index.d.ts +5 -5
  35. package/dist/models/index.js.map +1 -1
  36. package/dist/{models-registry-5Ufn7f2m.d.ts → models-registry-CLkoOcHk.d.ts} +1 -1
  37. package/dist/{multi-agent-coordinator-CcrcncvG.d.ts → multi-agent-coordinator-CieyUoEL.d.ts} +1 -1
  38. package/dist/{null-fleet-bus-C9KsYyrI.d.ts → null-fleet-bus-DkdmZJ_W.d.ts} +464 -464
  39. package/dist/observability/index.d.ts +3 -2
  40. package/dist/{path-resolver-CEeX9I7O.d.ts → path-resolver-XfZ9eLxG.d.ts} +3 -3
  41. package/dist/{permission-DbsGOA1C.d.ts → permission-Dx6dIqS2.d.ts} +2 -7
  42. package/dist/{permission-policy-BpEea3r7.d.ts → permission-policy-C8vJcnX5.d.ts} +2 -2
  43. package/dist/{pipeline-CEjBjzVA.d.ts → pipeline-BwAP21_4.d.ts} +9 -4
  44. package/dist/{provider-model-resolve-BpfXp3Jj.d.ts → provider-model-resolve-CwQNZWt_.d.ts} +3 -3
  45. package/dist/{provider-runner-CnOSr5BN.d.ts → provider-runner-CYHFImzV.d.ts} +3 -3
  46. package/dist/{retry-policy-Git9WF6d.d.ts → retry-policy-D4feSLk3.d.ts} +1 -1
  47. package/dist/sdd/index.d.ts +11 -10
  48. package/dist/sdd/index.js +2 -2
  49. package/dist/sdd/index.js.map +1 -1
  50. package/dist/secret-scrubber-3MHDDAtm.d.ts +6 -0
  51. package/dist/{secret-vault-DDSMHqIm.d.ts → secret-vault-CImt2XrR.d.ts} +1 -1
  52. package/dist/security/index.d.ts +6 -5
  53. package/dist/security/index.js.map +1 -1
  54. package/dist/{selector-Cq72C0Oy.d.ts → selector-Dy-MzKp1.d.ts} +1 -1
  55. package/dist/{session-event-bridge-DG94B3Bk.d.ts → session-event-bridge-CqdiGnfU.d.ts} +1 -1
  56. package/dist/{session-reader-BzT-iMQT.d.ts → session-reader-Hk0WbNm9.d.ts} +1 -1
  57. package/dist/{skill-DGIXCtdv.d.ts → skill-DHniprNl.d.ts} +15 -1
  58. package/dist/skills/index.d.ts +472 -26
  59. package/dist/skills/index.js +872 -129
  60. package/dist/skills/index.js.map +1 -1
  61. package/dist/storage/index.d.ts +27 -14
  62. package/dist/storage/index.js +264 -85
  63. package/dist/storage/index.js.map +1 -1
  64. package/dist/{strategy-compactor-Bt_ZH6R0.d.ts → strategy-compactor-CQwhbErd.d.ts} +32 -17
  65. package/dist/{todos-checkpoint-CH1pcua9.d.ts → todos-checkpoint-Bk2uP7Ex.d.ts} +6 -6
  66. package/dist/{context-DPlA6kid.d.ts → tool-BkOgs_KL.d.ts} +306 -286
  67. package/dist/{tool-executor-SVFq7IOR.d.ts → tool-executor-SiE1wlZo.d.ts} +9 -9
  68. package/dist/tools/index.d.ts +2 -2
  69. package/dist/tools/index.js.map +1 -1
  70. package/dist/types/index.d.ts +22 -21
  71. package/dist/types/index.js +7 -9
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/utils/index.d.ts +30 -4
  74. package/dist/utils/index.js +50 -1
  75. package/dist/utils/index.js.map +1 -1
  76. package/dist/{worktree-manager-C4YIf1Fa.d.ts → worktree-manager-BjOFF6bt.d.ts} +1 -1
  77. package/dist/{wstack-paths-_NrRovdr.d.ts → wstack-paths-CMl_cYgq.d.ts} +8 -0
  78. package/package.json +1 -1
  79. package/skills/mailbox-bridge/SKILL.md +1 -0
  80. package/skills/plugin-author/SKILL.md +350 -0
  81. package/skills/sdd/SKILL.md +134 -134
  82. package/skills/skill-creator/SKILL.md +45 -7
  83. package/skills/wrongstack-mailbox/SKILL.md +40 -21
@@ -1,328 +1,117 @@
1
- import { A as AgentPhase, b as AgentDefinition, a as DefaultMultiAgentCoordinator, D as DispatchClassifier } from './multi-agent-coordinator-CcrcncvG.js';
2
- import { F as FleetBus, j as FleetUsage, S as SubagentConfig, k as FleetUsageAggregator, g as TaskResult, C as CoordinatorStatus, T as TaskSpec, c as MultiAgentConfig, d as SubagentRunner } from './agent-subagent-runner-BimKihiC.js';
3
- import { b as SessionWriter, T as Tool, k as SessionStore } from './context-DPlA6kid.js';
4
- import { B as BrainArbiter, E as EventBus } from './brain-CCfuEOdp.js';
1
+ import { A as AgentPhase, b as AgentDefinition, a as DefaultMultiAgentCoordinator, D as DispatchClassifier } from './multi-agent-coordinator-CieyUoEL.js';
2
+ import { E as EventBus, B as BrainArbiter } from './events-Bs2fmldo.js';
3
+ import { F as FleetBus, j as FleetUsage, S as SubagentConfig, k as FleetUsageAggregator, g as TaskResult, C as CoordinatorStatus, T as TaskSpec, c as MultiAgentConfig, d as SubagentRunner } from './agent-subagent-runner-PoqNKiR4.js';
4
+ import { b as SessionWriter, T as Tool, k as SessionStore } from './tool-BkOgs_KL.js';
5
5
  import { EventEmitter } from 'node:events';
6
6
  import { L as Logger } from './logger-B63L5bTg.js';
7
7
  import { D as DirectorStateSnapshot } from './director-state-BfeCUbmk.js';
8
- import { d as ModelMatrixEntry } from './config-DAOjriz9.js';
9
- import { I as InMemoryAgentBridge } from './agent-bridge-BFJ2ODzI.js';
8
+ import { d as ModelMatrixEntry } from './config-Cr3312zc.js';
9
+ import { I as InMemoryAgentBridge } from './agent-bridge-DXC6QDJ4.js';
10
10
 
11
11
  /**
12
- * Alert levels the Director can emit when a collab session needs attention.
13
- * These flow through the FleetBus so the host can display them in the UI.
14
- */
15
- declare enum DirectorAlertLevel {
16
- /** The agent is still making progress but has hit a soft budget limit. */
17
- WARNING = "warning",
18
- /** The agent has hit a hard limit and the session cannot continue. */
19
- CRITICAL = "critical",
20
- /** The Director has decided to cancel the session (user request or policy). */
21
- CANCELLED = "cancelled"
22
- }
23
- interface DirectorAlert {
24
- sessionId: string;
25
- subagentId: string;
26
- role: string;
27
- level: DirectorAlertLevel;
28
- /** Human-readable message for UI/logs */
29
- message: string;
30
- /** Budget kind that triggered this alert, if any */
31
- budgetKind?: 'timeout' | 'idle_timeout' | 'iterations' | 'tool_calls' | 'tokens' | 'cost' | undefined;
32
- /** Elapsed ms at time of alert */
33
- elapsedMs?: number | undefined;
34
- /** Limit that was hit */
35
- limit?: number | undefined;
36
- /** /btw notes the director has collected (may be empty) */
37
- btwNotes?: string[] | undefined;
38
- }
39
- /**
40
- * Immutable snapshot of target files at the start of a collab session.
41
- * All agents in the session read from this snapshot — they see the same baseline.
42
- */
43
- interface SharedFileSnapshot {
44
- id: string;
45
- createdAt: string;
46
- files: SharedFileEntry[];
47
- }
48
- interface SharedFileEntry {
49
- path: string;
50
- content: string;
51
- language?: string | undefined;
52
- snapshotMtimeMs?: number | undefined;
53
- snapshotSizeBytes?: number | undefined;
54
- }
55
- /**
56
- * Bug finding emitted by BugHunter and consumed by RefactorPlanner + Critic.
12
+ * Agent catalog aggregator.
13
+ *
14
+ * Collects every phase's `AgentDefinition[]` into:
15
+ * - `ALL_AGENT_DEFINITIONS` — flat list, catalog order (phase 1 → 9)
16
+ * - `AGENT_CATALOG` — keyed by role for O(1) lookup
17
+ * - `AGENTS_BY_PHASE` — grouped for statusline / dispatcher tie-breaks
18
+ *
19
+ * `fleet.ts` derives `FLEET_ROSTER` + `FLEET_ROSTER_BUDGETS` from this, and the
20
+ * dispatcher routes free-form tasks against `capability` metadata here.
57
21
  */
58
- interface BugFinding {
59
- id: string;
60
- type: string;
61
- severity: 'critical' | 'high' | 'medium' | 'low';
62
- location: {
63
- file: string;
64
- line: number;
65
- };
66
- description: string;
67
- suggestedFix?: string | undefined;
68
- }
22
+
23
+ /** Every catalog agent, in phase order. */
24
+ declare const ALL_AGENT_DEFINITIONS: AgentDefinition[];
25
+ /** Phase its agents, for grouped display and dispatcher fallbacks. */
26
+ declare const AGENTS_BY_PHASE: Record<AgentPhase, AgentDefinition[]>;
69
27
  /**
70
- * Refactoring plan emitted by RefactorPlanner, consuming BugFinding(s).
28
+ * Role definition. Built once at module load. Throws on a duplicate role so
29
+ * a copy-paste collision fails loudly at startup instead of silently shadowing.
71
30
  */
72
- interface RefactorPlan {
73
- id: string;
74
- basedOnBugIds: string[];
75
- phases: RefactorPhase[];
76
- riskScore: 'low' | 'medium' | 'high';
77
- estimatedChangeCount: number;
78
- rollbackStrategy: string;
79
- }
80
- /** One phase within a refactor plan. */
81
- interface RefactorPhase {
82
- number: number;
83
- title: string;
84
- tasks: string[];
85
- risk: 'low' | 'medium' | 'high';
86
- }
31
+ declare const AGENT_CATALOG: Record<string, AgentDefinition>;
32
+ /** Role lookup helper. Returns undefined for unknown roles. */
33
+ declare function getAgentDefinition(role: string): AgentDefinition | undefined;
34
+
87
35
  /**
88
- * Critic evaluation of a bug finding or refactor plan.
36
+ * Default auto-extend policy for subagent budgets.
37
+ *
38
+ * The budget's soft-limit path (`SubagentBudget` → `budget.threshold_reached`)
39
+ * only negotiates an extension when SOMETHING listens on the EventBus. Under a
40
+ * `Director`, that listener is the director's own auto-extend handler. On the
41
+ * plain coordinator path (e.g. a bare `/spawn` with no director) nothing
42
+ * listens, so the budget falls back to a hard stop and the subagent dies the
43
+ * moment it crosses a soft limit.
44
+ *
45
+ * `attachAutoExtend` is the additive fix: wire it to a subagent's EventBus and
46
+ * budget overruns are auto-granted headroom instead of killing the run. It is
47
+ * heartbeat-aware for the timeout kind — wall-clock time always advances, so a
48
+ * naive "extend timeout forever" would let a wedged agent run indefinitely.
49
+ * Instead, a timeout extension is granted only when the agent has executed a
50
+ * new tool call or started a new iteration since the last timeout extension.
51
+ * No progress since last time ⇒ the agent is genuinely stuck ⇒ deny and let it
52
+ * fail. The non-timeout kinds (iterations/tool_calls/tokens/cost) extend up to
53
+ * a per-kind cap, then deny — those ceilings are the real runaway guard.
89
54
  */
90
- interface CriticEvaluation {
91
- id: string;
92
- subjectType: 'bug_finding' | 'refactor_plan';
93
- subjectId: string;
94
- score: number;
95
- verdict: 'approve' | 'needs_revision' | 'reject';
96
- strengths: string[];
97
- weaknesses: string[];
98
- concerns: CriticConcern[];
99
- }
100
- interface CriticConcern {
101
- description: string;
102
- location?: {
103
- file: string | undefined;
104
- line: number;
105
- };
106
- severity: 'blocking' | 'advisory';
55
+
56
+ interface AutoExtendCeiling {
57
+ maxIterations?: number | undefined;
58
+ maxToolCalls?: number | undefined;
59
+ maxTokens?: number | undefined;
60
+ maxCostUsd?: number | undefined;
61
+ timeoutMs?: number | undefined;
107
62
  }
108
- /**
109
- * Full structured report produced when a CollabSession resolves.
110
- */
111
- interface CollabDebugReport {
112
- sessionId: string;
113
- startedAt: string;
114
- completedAt: string;
115
- targetPaths: string[];
116
- /** How the session ended. 'completed' = all agents finished normally.
117
- * 'cancelled' = Director called cancelCollabSession().
118
- * 'timeout' = session-level timeout elapsed before all agents finished.
119
- * 'critical_alert' = Director escalated a warning to a cancel decision.
63
+ interface AutoExtendPolicy {
64
+ /** Multiplier applied to the tripped limit when extending. Default 0.5 (+50%). */
65
+ factor?: number | undefined;
66
+ /**
67
+ * Max extensions per NON-timeout kind before denying. Timeout is governed by
68
+ * the heartbeat check, not this cap, so it can extend indefinitely while the
69
+ * agent makes progress. Default 8.
120
70
  */
121
- disposition: 'completed' | 'cancelled' | 'timeout' | 'critical_alert';
122
- bugs: BugFinding[];
123
- refactorPlans: RefactorPlan[];
124
- evaluations: CriticEvaluation[];
125
- /** Alerts that were raised during the session (may be empty). */
126
- alerts: DirectorAlert[];
127
- /** Files modified after the initial static snapshot was captured. */
128
- snapshotWarnings?: string[] | undefined;
129
- /** Overall verdict from the Critic across all evaluated subjects. */
130
- overallVerdict: 'approve' | 'needs_revision' | 'reject';
131
- /** Markdown-formatted summary for the director's context window. */
132
- summary: string;
133
- }
134
- /**
135
- * Per-agent budget configuration for collab sessions.
136
- * Allows the caller (Director) to control the exact limits instead of
137
- * using hard-coded defaults that may not match the director's policy.
138
- */
139
- interface CollabBudgetConfig {
140
- maxIterations: number;
141
- maxToolCalls: number;
142
- timeoutMs: number;
71
+ maxExtensionsPerKind?: number | undefined;
72
+ /** Absolute ceilings — an extension never pushes a limit past these. */
73
+ ceiling?: AutoExtendCeiling | undefined;
143
74
  }
144
75
  /**
145
- * Budget overrides for specific roles in a collab session.
146
- * When a role is not present in the map, the default budget is used.
147
- */
148
- type CollabBudgetOverrides = Partial<Record<string, CollabBudgetConfig>>;
149
- /**
150
- * Emitted by a collab agent when it hits a soft budget limit.
151
- * The Director's fleet handler receives this and calls collabAlert().
76
+ * Attach an auto-extend policy to a subagent's EventBus. Returns an unsubscribe
77
+ * function that detaches all listeners call it when the subagent task ends.
152
78
  */
153
- interface CollabBudgetWarningPayload {
154
- sessionId: string;
155
- role: string;
156
- kind: 'timeout' | 'idle_timeout' | 'iterations' | 'tool_calls' | 'tokens' | 'cost';
157
- used: number;
158
- limit: number;
159
- timeoutMs?: number | undefined;
160
- elapsedMs: number;
161
- }
79
+ declare function attachAutoExtend(events: EventBus, policy?: AutoExtendPolicy): () => void;
80
+
162
81
  /**
163
- * Emitted by the Director to cancel all agents in a collab session.
164
- * CollabSession listens for this and causes its agent pool to finish early.
82
+ * Interface for fleet-level lifecycle and policy. Covers:
83
+ * - Spawn lifecycle hooks (canSpawn check, recordSpawn after-effects)
84
+ * - Budget enforcement (fleet-wide cost cap, spawn count/depth caps)
85
+ * - Fleet manifest assembly and writing
86
+ * - Subagent metadata and usage tracking
87
+ *
88
+ * `FleetBus` is pure event fan-out and implements no policy.
89
+ * `FleetManager` encapsulates all fleet-level policy decisions.
90
+ * `Director` currently owns all of this — this interface lets us
91
+ * extract it into a swappable component in Phase 5.
165
92
  */
166
- interface DirectorCancelCollabPayload {
167
- sessionId: string;
168
- reason: string;
169
- cancelledAt: string;
170
- }
171
- interface CollabSessionOptions {
172
- /** Paths to scan — used to build the SharedFileSnapshot. */
173
- targetPaths: string[];
174
- /** Files already read and snapshot. When provided, snapshot is skipped. */
175
- prebuiltSnapshot?: SharedFileSnapshot | undefined;
176
- /** Max time to wait for the session to resolve (ms). Default: 10 min. */
177
- timeoutMs?: number | undefined;
93
+ interface IFleetManager {
94
+ /** The FleetBus this manager publishes lifecycle events to. */
95
+ readonly fleetBus: FleetBus;
178
96
  /**
179
- * Maximum number of files to include in the snapshot.
180
- * - If set explicitly: use this value (hard override).
181
- * - If `contextWindow` is set: calculate dynamically from estimated token budget.
182
- * - If neither: use `DEFAULT_MAX_TARGET_FILES` (30).
97
+ * Snapshot of fleet-wide token usage and cost rollup.
98
+ * Safe to call from a tool's execute() body.
183
99
  */
184
- maxTargetFiles?: number | undefined;
100
+ snapshot(): FleetUsage;
185
101
  /**
186
- * Context window size (in tokens) of the model running the subagents.
187
- * When provided and `maxTargetFiles` is not set, the limit is computed
188
- * dynamically: `floor((contextWindow * 0.4) / AVG_TOKENS_PER_FILE)`.
189
- * If not provided, `DEFAULT_MAX_TARGET_FILES` is used as the fallback.
102
+ * Per-subagent metadata captured at spawn time (provider/model/name).
103
+ * Returns undefined if the subagent is not known to this manager.
190
104
  */
191
- contextWindow?: number | undefined;
105
+ getSubagentMeta(id: string): {
106
+ provider?: string | undefined;
107
+ model?: string | undefined;
108
+ name?: string | undefined;
109
+ } | undefined;
192
110
  /**
193
- * Budget overrides per role. When provided, these override the hard-coded
194
- * defaults so the Director can enforce fleet-wide budget policy.
195
- * Keys must match role names: 'bug-hunter', 'refactor-planner', 'critic'.
196
- */
197
- budgetOverrides?: CollabBudgetOverrides | undefined;
198
- /**
199
- * Called by the Director when a collab agent hits a soft budget limit.
200
- * The Director uses this to decide whether to cancel the session or extend.
201
- * Return 'cancel' to stop the session immediately; 'extend' to continue
202
- * with the agent's proposed new limits; 'ignore' to let the default
203
- * auto-extend logic handle it.
204
- */
205
- onBudgetWarning?: ((alert: DirectorAlert) => 'cancel' | 'extend' | 'ignore') | undefined;
206
- }
207
- declare class CollabSession extends EventEmitter {
208
- readonly sessionId: string;
209
- readonly options: CollabSessionOptions;
210
- readonly snapshot: SharedFileSnapshot;
211
- private readonly director;
212
- private readonly fleetBus;
213
- private readonly subagentIds;
214
- private readonly bugs;
215
- private readonly plans;
216
- private readonly evaluations;
217
- private readonly disposers;
218
- private settled;
219
- private readonly timeoutMs;
220
- private cancelled;
221
- private _raceResolved;
222
- private readonly alerts;
223
- private snapshotWarnings;
224
- /** Tracks tool call counts per subagent for progress-based timeout decisions. */
225
- private readonly progressBySubagent;
226
- /** Last tool call count when a timeout warning was handled. */
227
- private readonly lastTimeoutProgress;
228
- /** Session-level timeout timer handle (cleared on cancel or natural completion). */
229
- private _timeoutTimer?;
230
- constructor(director: Director, fleetBus: FleetBus, options: CollabSessionOptions);
231
- get id(): string;
232
- getSessionAlerts(): DirectorAlert[];
233
- isCancelled(): boolean;
234
- /**
235
- * Snapshot of role → subagentId map. The Director calls coordinator.stop()
236
- * for each agent when cancelling the session, using this map to enumerate
237
- * all three collab agents.
238
- */
239
- getSubagentIds(): ReadonlyMap<string, string>;
240
- /**
241
- * Returns the effective file limit for this session.
242
- * Priority: explicit `maxTargetFiles` > dynamic from `contextWindow` > `DEFAULT_MAX_TARGET_FILES`.
243
- */
244
- effectiveFileLimit(): number;
245
- buildSnapshot(): Promise<SharedFileSnapshot>;
246
- /**
247
- * Cancel the session. Emits director.cancel_collab on the FleetBus so all
248
- * collab agents finish early. The session-level timeout timer is also cleared.
249
- * Safe to call multiple times (idempotent after first call).
250
- */
251
- cancel(reason?: string): void;
252
- start(): Promise<CollabDebugReport>;
253
- private parseAndEmit;
254
- private extractJsonObjects;
255
- private budgetForRole;
256
- private spawnAgent;
257
- private buildBugHunterTask;
258
- private buildRefactorPlannerTask;
259
- private buildCriticTask;
260
- private wireFleetBus;
261
- private roleFromSubagentId;
262
- private assembleReport;
263
- private checkSnapshotFreshness;
264
- private buildMarkdownSummary;
265
- private cleanup;
266
- }
267
-
268
- /**
269
- * Agent catalog aggregator.
270
- *
271
- * Collects every phase's `AgentDefinition[]` into:
272
- * - `ALL_AGENT_DEFINITIONS` — flat list, catalog order (phase 1 → 9)
273
- * - `AGENT_CATALOG` — keyed by role for O(1) lookup
274
- * - `AGENTS_BY_PHASE` — grouped for statusline / dispatcher tie-breaks
275
- *
276
- * `fleet.ts` derives `FLEET_ROSTER` + `FLEET_ROSTER_BUDGETS` from this, and the
277
- * dispatcher routes free-form tasks against `capability` metadata here.
278
- */
279
-
280
- /** Every catalog agent, in phase order. */
281
- declare const ALL_AGENT_DEFINITIONS: AgentDefinition[];
282
- /** Phase → its agents, for grouped display and dispatcher fallbacks. */
283
- declare const AGENTS_BY_PHASE: Record<AgentPhase, AgentDefinition[]>;
284
- /**
285
- * Role → definition. Built once at module load. Throws on a duplicate role so
286
- * a copy-paste collision fails loudly at startup instead of silently shadowing.
287
- */
288
- declare const AGENT_CATALOG: Record<string, AgentDefinition>;
289
- /** Role lookup helper. Returns undefined for unknown roles. */
290
- declare function getAgentDefinition(role: string): AgentDefinition | undefined;
291
-
292
- /**
293
- * Interface for fleet-level lifecycle and policy. Covers:
294
- * - Spawn lifecycle hooks (canSpawn check, recordSpawn after-effects)
295
- * - Budget enforcement (fleet-wide cost cap, spawn count/depth caps)
296
- * - Fleet manifest assembly and writing
297
- * - Subagent metadata and usage tracking
298
- *
299
- * `FleetBus` is pure event fan-out and implements no policy.
300
- * `FleetManager` encapsulates all fleet-level policy decisions.
301
- * `Director` currently owns all of this — this interface lets us
302
- * extract it into a swappable component in Phase 5.
303
- */
304
- interface IFleetManager {
305
- /** The FleetBus this manager publishes lifecycle events to. */
306
- readonly fleetBus: FleetBus;
307
- /**
308
- * Snapshot of fleet-wide token usage and cost rollup.
309
- * Safe to call from a tool's execute() body.
310
- */
311
- snapshot(): FleetUsage;
312
- /**
313
- * Per-subagent metadata captured at spawn time (provider/model/name).
314
- * Returns undefined if the subagent is not known to this manager.
315
- */
316
- getSubagentMeta(id: string): {
317
- provider?: string | undefined;
318
- model?: string | undefined;
319
- name?: string | undefined;
320
- } | undefined;
321
- /**
322
- * Called before a spawn is recorded. Returns a reason string if the
323
- * spawn should be rejected (budget cap, depth limit, cost cap, context
324
- * overload, etc.), or null to proceed. Director.spawn() calls this
325
- * internally.
111
+ * Called before a spawn is recorded. Returns a reason string if the
112
+ * spawn should be rejected (budget cap, depth limit, cost cap, context
113
+ * overload, etc.), or null to proceed. Director.spawn() calls this
114
+ * internally.
326
115
  */
327
116
  canSpawn(config: SubagentConfig): {
328
117
  kind: 'max_spawns' | 'max_spawn_depth' | 'max_cost_usd' | 'max_context_load';
@@ -1471,64 +1260,262 @@ declare class Director implements ICoordinator {
1471
1260
  resumeFromCheckpoint(snapshot: DirectorStateSnapshot): void;
1472
1261
  }
1473
1262
 
1474
- declare function makeSpawnTool(director: Director, roster?: Record<string, SubagentConfig>): Tool;
1475
- declare function makeAssignTool(director: Director): Tool;
1476
- declare function makeAwaitTasksTool(director: Director): Tool;
1477
- declare function makeAskTool(director: Director): Tool;
1478
1263
  /**
1479
- * Retrieve a previously stored `ask_subagent` answer by its store key.
1480
- * The key was returned as `_answerKey` in the ask_subagent response.
1481
- * Use this only for large responses that were stored out-of-context.
1264
+ * Alert levels the Director can emit when a collab session needs attention.
1265
+ * These flow through the FleetBus so the host can display them in the UI.
1482
1266
  */
1483
- declare function makeAskResultTool(director: Director): Tool;
1484
- declare function makeRollUpTool(director: Director): Tool;
1485
- declare function makeTerminateTool(director: Director): Tool;
1486
- declare function makeTerminateAllTool(director: Director): Tool;
1267
+ declare enum DirectorAlertLevel {
1268
+ /** The agent is still making progress but has hit a soft budget limit. */
1269
+ WARNING = "warning",
1270
+ /** The agent has hit a hard limit and the session cannot continue. */
1271
+ CRITICAL = "critical",
1272
+ /** The Director has decided to cancel the session (user request or policy). */
1273
+ CANCELLED = "cancelled"
1274
+ }
1275
+ interface DirectorAlert {
1276
+ sessionId: string;
1277
+ subagentId: string;
1278
+ role: string;
1279
+ level: DirectorAlertLevel;
1280
+ /** Human-readable message for UI/logs */
1281
+ message: string;
1282
+ /** Budget kind that triggered this alert, if any */
1283
+ budgetKind?: 'timeout' | 'idle_timeout' | 'iterations' | 'tool_calls' | 'tokens' | 'cost' | undefined;
1284
+ /** Elapsed ms at time of alert */
1285
+ elapsedMs?: number | undefined;
1286
+ /** Limit that was hit */
1287
+ limit?: number | undefined;
1288
+ /** /btw notes the director has collected (may be empty) */
1289
+ btwNotes?: string[] | undefined;
1290
+ }
1487
1291
  /**
1488
- * Unified fleet observation tool consolidates the former fleet_status,
1489
- * fleet_usage, fleet_session, and fleet_health tools under a single `action`
1490
- * parameter (status, usage, health, session).
1491
- *
1492
- * These four are all read-only fleet queries; merging them into one tool
1493
- * reduces tool-schema token overhead (4 × ~150 tokens → 1 × ~250 tokens)
1494
- * and eliminates model confusion when choosing between similar tools.
1292
+ * Immutable snapshot of target files at the start of a collab session.
1293
+ * All agents in the session read from this snapshot — they see the same baseline.
1495
1294
  */
1496
- declare function makeFleetTool(director: Director): Tool;
1295
+ interface SharedFileSnapshot {
1296
+ id: string;
1297
+ createdAt: string;
1298
+ files: SharedFileEntry[];
1299
+ }
1300
+ interface SharedFileEntry {
1301
+ path: string;
1302
+ content: string;
1303
+ language?: string | undefined;
1304
+ snapshotMtimeMs?: number | undefined;
1305
+ snapshotSizeBytes?: number | undefined;
1306
+ }
1497
1307
  /**
1498
- * Collaborative debugging session: BugHunter, RefactorPlanner, and Critic
1499
- * run in parallel on the same target files, with findings flowing through
1500
- * the FleetBus (bug.found → refactor.plan → critic.evaluation).
1501
- *
1502
- * Returns a structured CollabDebugReport containing all bug findings,
1503
- * refactor plans, critic evaluations, and an overall verdict.
1308
+ * Bug finding emitted by BugHunter and consumed by RefactorPlanner + Critic.
1504
1309
  */
1505
- declare function makeCollabDebugTool(director: Director): Tool;
1310
+ interface BugFinding {
1311
+ id: string;
1312
+ type: string;
1313
+ severity: 'critical' | 'high' | 'medium' | 'low';
1314
+ location: {
1315
+ file: string;
1316
+ line: number;
1317
+ };
1318
+ description: string;
1319
+ suggestedFix?: string | undefined;
1320
+ }
1506
1321
  /**
1507
- * Tool for subagents to emit structured events on the FleetBus.
1508
- * Any agent can emit any event type; the Director routes it to all listeners.
1509
- * Common event types in collaborative sessions:
1510
- * bug.found — BugHunter emits per-finding
1511
- * refactor.plan — RefactorPlanner emits per-plan
1512
- * critic.evaluation — Critic emits per-evaluation
1513
- *
1514
- * The payload structure is event-type-specific. Use null for empty payloads.
1322
+ * Refactoring plan emitted by RefactorPlanner, consuming BugFinding(s).
1515
1323
  */
1516
- declare function makeFleetEmitTool(director: Director): Tool;
1324
+ interface RefactorPlan {
1325
+ id: string;
1326
+ basedOnBugIds: string[];
1327
+ phases: RefactorPhase[];
1328
+ riskScore: 'low' | 'medium' | 'high';
1329
+ estimatedChangeCount: number;
1330
+ rollbackStrategy: string;
1331
+ }
1332
+ /** One phase within a refactor plan. */
1333
+ interface RefactorPhase {
1334
+ number: number;
1335
+ title: string;
1336
+ tasks: string[];
1337
+ risk: 'low' | 'medium' | 'high';
1338
+ }
1517
1339
  /**
1518
- * Signal that the director's work is satisfied and the fleet should wind down.
1519
- *
1520
- * Once called:
1521
- * - `spawn_subagent` throws — no new subagents can be created
1522
- * - `assign_task` synthesizes an immediate `aborted_by_parent` completion
1523
- * for any queued task (callers awaiting those tasks unblock immediately)
1524
- * - Running subagents are NOT killed — they finish naturally; no new
1525
- * tasks are dispatched to them
1526
- *
1527
- * Use this when you are satisfied with the results and want the fleet to
1528
- * stop spawning without forcibly stopping in-flight work. Call
1529
- * `terminate_subagent` separately for any subagent you need to stop immediately.
1340
+ * Critic evaluation of a bug finding or refactor plan.
1530
1341
  */
1531
- declare function makeWorkCompleteTool(director: Director): Tool;
1342
+ interface CriticEvaluation {
1343
+ id: string;
1344
+ subjectType: 'bug_finding' | 'refactor_plan';
1345
+ subjectId: string;
1346
+ score: number;
1347
+ verdict: 'approve' | 'needs_revision' | 'reject';
1348
+ strengths: string[];
1349
+ weaknesses: string[];
1350
+ concerns: CriticConcern[];
1351
+ }
1352
+ interface CriticConcern {
1353
+ description: string;
1354
+ location?: {
1355
+ file: string | undefined;
1356
+ line: number;
1357
+ };
1358
+ severity: 'blocking' | 'advisory';
1359
+ }
1360
+ /**
1361
+ * Full structured report produced when a CollabSession resolves.
1362
+ */
1363
+ interface CollabDebugReport {
1364
+ sessionId: string;
1365
+ startedAt: string;
1366
+ completedAt: string;
1367
+ targetPaths: string[];
1368
+ /** How the session ended. 'completed' = all agents finished normally.
1369
+ * 'cancelled' = Director called cancelCollabSession().
1370
+ * 'timeout' = session-level timeout elapsed before all agents finished.
1371
+ * 'critical_alert' = Director escalated a warning to a cancel decision.
1372
+ */
1373
+ disposition: 'completed' | 'cancelled' | 'timeout' | 'critical_alert';
1374
+ bugs: BugFinding[];
1375
+ refactorPlans: RefactorPlan[];
1376
+ evaluations: CriticEvaluation[];
1377
+ /** Alerts that were raised during the session (may be empty). */
1378
+ alerts: DirectorAlert[];
1379
+ /** Files modified after the initial static snapshot was captured. */
1380
+ snapshotWarnings?: string[] | undefined;
1381
+ /** Overall verdict from the Critic across all evaluated subjects. */
1382
+ overallVerdict: 'approve' | 'needs_revision' | 'reject';
1383
+ /** Markdown-formatted summary for the director's context window. */
1384
+ summary: string;
1385
+ }
1386
+ /**
1387
+ * Per-agent budget configuration for collab sessions.
1388
+ * Allows the caller (Director) to control the exact limits instead of
1389
+ * using hard-coded defaults that may not match the director's policy.
1390
+ */
1391
+ interface CollabBudgetConfig {
1392
+ maxIterations: number;
1393
+ maxToolCalls: number;
1394
+ timeoutMs: number;
1395
+ }
1396
+ /**
1397
+ * Budget overrides for specific roles in a collab session.
1398
+ * When a role is not present in the map, the default budget is used.
1399
+ */
1400
+ type CollabBudgetOverrides = Partial<Record<string, CollabBudgetConfig>>;
1401
+ /**
1402
+ * Emitted by a collab agent when it hits a soft budget limit.
1403
+ * The Director's fleet handler receives this and calls collabAlert().
1404
+ */
1405
+ interface CollabBudgetWarningPayload {
1406
+ sessionId: string;
1407
+ role: string;
1408
+ kind: 'timeout' | 'idle_timeout' | 'iterations' | 'tool_calls' | 'tokens' | 'cost';
1409
+ used: number;
1410
+ limit: number;
1411
+ timeoutMs?: number | undefined;
1412
+ elapsedMs: number;
1413
+ }
1414
+ /**
1415
+ * Emitted by the Director to cancel all agents in a collab session.
1416
+ * CollabSession listens for this and causes its agent pool to finish early.
1417
+ */
1418
+ interface DirectorCancelCollabPayload {
1419
+ sessionId: string;
1420
+ reason: string;
1421
+ cancelledAt: string;
1422
+ }
1423
+ interface CollabSessionOptions {
1424
+ /** Paths to scan — used to build the SharedFileSnapshot. */
1425
+ targetPaths: string[];
1426
+ /** Files already read and snapshot. When provided, snapshot is skipped. */
1427
+ prebuiltSnapshot?: SharedFileSnapshot | undefined;
1428
+ /** Max time to wait for the session to resolve (ms). Default: 10 min. */
1429
+ timeoutMs?: number | undefined;
1430
+ /**
1431
+ * Maximum number of files to include in the snapshot.
1432
+ * - If set explicitly: use this value (hard override).
1433
+ * - If `contextWindow` is set: calculate dynamically from estimated token budget.
1434
+ * - If neither: use `DEFAULT_MAX_TARGET_FILES` (30).
1435
+ */
1436
+ maxTargetFiles?: number | undefined;
1437
+ /**
1438
+ * Context window size (in tokens) of the model running the subagents.
1439
+ * When provided and `maxTargetFiles` is not set, the limit is computed
1440
+ * dynamically: `floor((contextWindow * 0.4) / AVG_TOKENS_PER_FILE)`.
1441
+ * If not provided, `DEFAULT_MAX_TARGET_FILES` is used as the fallback.
1442
+ */
1443
+ contextWindow?: number | undefined;
1444
+ /**
1445
+ * Budget overrides per role. When provided, these override the hard-coded
1446
+ * defaults so the Director can enforce fleet-wide budget policy.
1447
+ * Keys must match role names: 'bug-hunter', 'refactor-planner', 'critic'.
1448
+ */
1449
+ budgetOverrides?: CollabBudgetOverrides | undefined;
1450
+ /**
1451
+ * Called by the Director when a collab agent hits a soft budget limit.
1452
+ * The Director uses this to decide whether to cancel the session or extend.
1453
+ * Return 'cancel' to stop the session immediately; 'extend' to continue
1454
+ * with the agent's proposed new limits; 'ignore' to let the default
1455
+ * auto-extend logic handle it.
1456
+ */
1457
+ onBudgetWarning?: ((alert: DirectorAlert) => 'cancel' | 'extend' | 'ignore') | undefined;
1458
+ }
1459
+ declare class CollabSession extends EventEmitter {
1460
+ readonly sessionId: string;
1461
+ readonly options: CollabSessionOptions;
1462
+ readonly snapshot: SharedFileSnapshot;
1463
+ private readonly director;
1464
+ private readonly fleetBus;
1465
+ private readonly subagentIds;
1466
+ private readonly bugs;
1467
+ private readonly plans;
1468
+ private readonly evaluations;
1469
+ private readonly disposers;
1470
+ private settled;
1471
+ private readonly timeoutMs;
1472
+ private cancelled;
1473
+ private _raceResolved;
1474
+ private readonly alerts;
1475
+ private snapshotWarnings;
1476
+ /** Tracks tool call counts per subagent for progress-based timeout decisions. */
1477
+ private readonly progressBySubagent;
1478
+ /** Last tool call count when a timeout warning was handled. */
1479
+ private readonly lastTimeoutProgress;
1480
+ /** Session-level timeout timer handle (cleared on cancel or natural completion). */
1481
+ private _timeoutTimer?;
1482
+ constructor(director: Director, fleetBus: FleetBus, options: CollabSessionOptions);
1483
+ get id(): string;
1484
+ getSessionAlerts(): DirectorAlert[];
1485
+ isCancelled(): boolean;
1486
+ /**
1487
+ * Snapshot of role → subagentId map. The Director calls coordinator.stop()
1488
+ * for each agent when cancelling the session, using this map to enumerate
1489
+ * all three collab agents.
1490
+ */
1491
+ getSubagentIds(): ReadonlyMap<string, string>;
1492
+ /**
1493
+ * Returns the effective file limit for this session.
1494
+ * Priority: explicit `maxTargetFiles` > dynamic from `contextWindow` > `DEFAULT_MAX_TARGET_FILES`.
1495
+ */
1496
+ effectiveFileLimit(): number;
1497
+ buildSnapshot(): Promise<SharedFileSnapshot>;
1498
+ /**
1499
+ * Cancel the session. Emits director.cancel_collab on the FleetBus so all
1500
+ * collab agents finish early. The session-level timeout timer is also cleared.
1501
+ * Safe to call multiple times (idempotent after first call).
1502
+ */
1503
+ cancel(reason?: string): void;
1504
+ start(): Promise<CollabDebugReport>;
1505
+ private parseAndEmit;
1506
+ private extractJsonObjects;
1507
+ private budgetForRole;
1508
+ private spawnAgent;
1509
+ private buildBugHunterTask;
1510
+ private buildRefactorPlannerTask;
1511
+ private buildCriticTask;
1512
+ private wireFleetBus;
1513
+ private roleFromSubagentId;
1514
+ private assembleReport;
1515
+ private checkSnapshotFreshness;
1516
+ private buildMarkdownSummary;
1517
+ private cleanup;
1518
+ }
1532
1519
 
1533
1520
  /**
1534
1521
  * Opaque host interface so this factory doesn't have to depend on the
@@ -1619,73 +1606,6 @@ interface CreateDelegateToolOptions {
1619
1606
  */
1620
1607
  declare function createDelegateTool(opts: CreateDelegateToolOptions): Tool;
1621
1608
 
1622
- /**
1623
- * Per-subagent session factory.
1624
- *
1625
- * Director runs produce many parallel transcripts — one per spawned
1626
- * subagent — and we want them all rooted under the same director-run
1627
- * directory so a future `wstack replay <runId>` can rehydrate the whole
1628
- * fleet from a single tree.
1629
- *
1630
- * The factory builds (or accepts) a `SessionStore` whose `dir` points at
1631
- * `<sessionsRoot>/<directorRunId>/`, and returns a small `create()`
1632
- * function that the orchestration layer calls per-spawn. Each call
1633
- * yields a fresh `SessionWriter` whose JSONL file lives in that
1634
- * directory, named by either the caller-supplied `subagentId` (preferred,
1635
- * so the file name is human-readable) or a derived id.
1636
- *
1637
- * **Why a thin factory instead of plumbing options through every spawn
1638
- * site?** Because the director is the only caller that needs this
1639
- * isolation pattern, and shoving `sessionStore` options into
1640
- * `SubagentConfig` would leak storage details into a config shape that
1641
- * agents and the coordinator have no business knowing about.
1642
- */
1643
- interface DirectorSessionFactoryOptions {
1644
- /**
1645
- * Either a parent directory where `<directorRunId>/` will be created,
1646
- * or a pre-built `SessionStore` whose `dir` already points at the
1647
- * director run directory. Tests pass an in-memory store for isolation;
1648
- * production code passes the path under `~/.wrongstack/sessions/`.
1649
- */
1650
- store?: SessionStore | undefined;
1651
- sessionsRoot?: string | undefined;
1652
- /**
1653
- * Director run id — namespaces all subagent JSONLs under one folder.
1654
- * Defaults to a timestamped id; supplied explicitly when resuming a
1655
- * prior fleet manifest.
1656
- */
1657
- directorRunId?: string | undefined;
1658
- /**
1659
- * Session-level trace ID for correlating subagent storage events with
1660
- * the parent session's trace in observability pipelines.
1661
- */
1662
- traceId?: string | undefined;
1663
- }
1664
- interface DirectorSessionFactory {
1665
- /** Absolute directory where this director run's transcripts live. */
1666
- readonly dir: string;
1667
- /** The director run id used to namespace the directory. */
1668
- readonly directorRunId: string;
1669
- /**
1670
- * Create a fresh `SessionWriter` for the named subagent. Each
1671
- * subagent gets its own JSONL file. The writer's `id` matches the
1672
- * supplied `subagentId` so disk paths line up with in-memory ids.
1673
- */
1674
- createSubagentSession(args: {
1675
- subagentId: string;
1676
- provider?: string | undefined;
1677
- model?: string | undefined;
1678
- title?: string | undefined;
1679
- }): Promise<SessionWriter>;
1680
- }
1681
- /**
1682
- * Build a `DirectorSessionFactory`. Pass either a pre-configured
1683
- * `SessionStore` (tests) or a `sessionsRoot` path (production). When
1684
- * neither is supplied the factory throws — there's no sane default for
1685
- * "where do these JSONLs live".
1686
- */
1687
- declare function makeDirectorSessionFactory(opts: DirectorSessionFactoryOptions): DirectorSessionFactory;
1688
-
1689
1609
  /**
1690
1610
  * System-prompt composition helpers for the Director ecosystem.
1691
1611
  *
@@ -1805,6 +1725,132 @@ declare function rosterSummaryFromConfigs(roster: Record<string, {
1805
1725
  role?: string | undefined;
1806
1726
  }>): string;
1807
1727
 
1728
+ /**
1729
+ * Per-subagent session factory.
1730
+ *
1731
+ * Director runs produce many parallel transcripts — one per spawned
1732
+ * subagent — and we want them all rooted under the same director-run
1733
+ * directory so a future `wstack replay <runId>` can rehydrate the whole
1734
+ * fleet from a single tree.
1735
+ *
1736
+ * The factory builds (or accepts) a `SessionStore` whose `dir` points at
1737
+ * `<sessionsRoot>/<directorRunId>/`, and returns a small `create()`
1738
+ * function that the orchestration layer calls per-spawn. Each call
1739
+ * yields a fresh `SessionWriter` whose JSONL file lives in that
1740
+ * directory, named by either the caller-supplied `subagentId` (preferred,
1741
+ * so the file name is human-readable) or a derived id.
1742
+ *
1743
+ * **Why a thin factory instead of plumbing options through every spawn
1744
+ * site?** Because the director is the only caller that needs this
1745
+ * isolation pattern, and shoving `sessionStore` options into
1746
+ * `SubagentConfig` would leak storage details into a config shape that
1747
+ * agents and the coordinator have no business knowing about.
1748
+ */
1749
+ interface DirectorSessionFactoryOptions {
1750
+ /**
1751
+ * Either a parent directory where `<directorRunId>/` will be created,
1752
+ * or a pre-built `SessionStore` whose `dir` already points at the
1753
+ * director run directory. Tests pass an in-memory store for isolation;
1754
+ * production code passes the path under `~/.wrongstack/sessions/`.
1755
+ */
1756
+ store?: SessionStore | undefined;
1757
+ sessionsRoot?: string | undefined;
1758
+ /**
1759
+ * Director run id — namespaces all subagent JSONLs under one folder.
1760
+ * Defaults to a timestamped id; supplied explicitly when resuming a
1761
+ * prior fleet manifest.
1762
+ */
1763
+ directorRunId?: string | undefined;
1764
+ /**
1765
+ * Session-level trace ID for correlating subagent storage events with
1766
+ * the parent session's trace in observability pipelines.
1767
+ */
1768
+ traceId?: string | undefined;
1769
+ }
1770
+ interface DirectorSessionFactory {
1771
+ /** Absolute directory where this director run's transcripts live. */
1772
+ readonly dir: string;
1773
+ /** The director run id used to namespace the directory. */
1774
+ readonly directorRunId: string;
1775
+ /**
1776
+ * Create a fresh `SessionWriter` for the named subagent. Each
1777
+ * subagent gets its own JSONL file. The writer's `id` matches the
1778
+ * supplied `subagentId` so disk paths line up with in-memory ids.
1779
+ */
1780
+ createSubagentSession(args: {
1781
+ subagentId: string;
1782
+ provider?: string | undefined;
1783
+ model?: string | undefined;
1784
+ title?: string | undefined;
1785
+ }): Promise<SessionWriter>;
1786
+ }
1787
+ /**
1788
+ * Build a `DirectorSessionFactory`. Pass either a pre-configured
1789
+ * `SessionStore` (tests) or a `sessionsRoot` path (production). When
1790
+ * neither is supplied the factory throws — there's no sane default for
1791
+ * "where do these JSONLs live".
1792
+ */
1793
+ declare function makeDirectorSessionFactory(opts: DirectorSessionFactoryOptions): DirectorSessionFactory;
1794
+
1795
+ declare function makeSpawnTool(director: Director, roster?: Record<string, SubagentConfig>): Tool;
1796
+ declare function makeAssignTool(director: Director): Tool;
1797
+ declare function makeAwaitTasksTool(director: Director): Tool;
1798
+ declare function makeAskTool(director: Director): Tool;
1799
+ /**
1800
+ * Retrieve a previously stored `ask_subagent` answer by its store key.
1801
+ * The key was returned as `_answerKey` in the ask_subagent response.
1802
+ * Use this only for large responses that were stored out-of-context.
1803
+ */
1804
+ declare function makeAskResultTool(director: Director): Tool;
1805
+ declare function makeRollUpTool(director: Director): Tool;
1806
+ declare function makeTerminateTool(director: Director): Tool;
1807
+ declare function makeTerminateAllTool(director: Director): Tool;
1808
+ /**
1809
+ * Unified fleet observation tool — consolidates the former fleet_status,
1810
+ * fleet_usage, fleet_session, and fleet_health tools under a single `action`
1811
+ * parameter (status, usage, health, session).
1812
+ *
1813
+ * These four are all read-only fleet queries; merging them into one tool
1814
+ * reduces tool-schema token overhead (4 × ~150 tokens → 1 × ~250 tokens)
1815
+ * and eliminates model confusion when choosing between similar tools.
1816
+ */
1817
+ declare function makeFleetTool(director: Director): Tool;
1818
+ /**
1819
+ * Collaborative debugging session: BugHunter, RefactorPlanner, and Critic
1820
+ * run in parallel on the same target files, with findings flowing through
1821
+ * the FleetBus (bug.found → refactor.plan → critic.evaluation).
1822
+ *
1823
+ * Returns a structured CollabDebugReport containing all bug findings,
1824
+ * refactor plans, critic evaluations, and an overall verdict.
1825
+ */
1826
+ declare function makeCollabDebugTool(director: Director): Tool;
1827
+ /**
1828
+ * Tool for subagents to emit structured events on the FleetBus.
1829
+ * Any agent can emit any event type; the Director routes it to all listeners.
1830
+ * Common event types in collaborative sessions:
1831
+ * bug.found — BugHunter emits per-finding
1832
+ * refactor.plan — RefactorPlanner emits per-plan
1833
+ * critic.evaluation — Critic emits per-evaluation
1834
+ *
1835
+ * The payload structure is event-type-specific. Use null for empty payloads.
1836
+ */
1837
+ declare function makeFleetEmitTool(director: Director): Tool;
1838
+ /**
1839
+ * Signal that the director's work is satisfied and the fleet should wind down.
1840
+ *
1841
+ * Once called:
1842
+ * - `spawn_subagent` throws — no new subagents can be created
1843
+ * - `assign_task` synthesizes an immediate `aborted_by_parent` completion
1844
+ * for any queued task (callers awaiting those tasks unblock immediately)
1845
+ * - Running subagents are NOT killed — they finish naturally; no new
1846
+ * tasks are dispatched to them
1847
+ *
1848
+ * Use this when you are satisfied with the results and want the fleet to
1849
+ * stop spawning without forcibly stopping in-flight work. Call
1850
+ * `terminate_subagent` separately for any subagent you need to stop immediately.
1851
+ */
1852
+ declare function makeWorkCompleteTool(director: Director): Tool;
1853
+
1808
1854
  /**
1809
1855
  * Pre-built subagent role configurations for the WrongStack fleet.
1810
1856
  * These can be passed to `MultiAgentHost.spawn()` or used as templates
@@ -1856,52 +1902,6 @@ declare const ACP_AGENTS: SubagentConfig[];
1856
1902
  /** Extended roster including ACP agents. */
1857
1903
  declare const FLEET_ROSTER_WITHACP: Record<string, SubagentConfig>;
1858
1904
 
1859
- /**
1860
- * Default auto-extend policy for subagent budgets.
1861
- *
1862
- * The budget's soft-limit path (`SubagentBudget` → `budget.threshold_reached`)
1863
- * only negotiates an extension when SOMETHING listens on the EventBus. Under a
1864
- * `Director`, that listener is the director's own auto-extend handler. On the
1865
- * plain coordinator path (e.g. a bare `/spawn` with no director) nothing
1866
- * listens, so the budget falls back to a hard stop and the subagent dies the
1867
- * moment it crosses a soft limit.
1868
- *
1869
- * `attachAutoExtend` is the additive fix: wire it to a subagent's EventBus and
1870
- * budget overruns are auto-granted headroom instead of killing the run. It is
1871
- * heartbeat-aware for the timeout kind — wall-clock time always advances, so a
1872
- * naive "extend timeout forever" would let a wedged agent run indefinitely.
1873
- * Instead, a timeout extension is granted only when the agent has executed a
1874
- * new tool call or started a new iteration since the last timeout extension.
1875
- * No progress since last time ⇒ the agent is genuinely stuck ⇒ deny and let it
1876
- * fail. The non-timeout kinds (iterations/tool_calls/tokens/cost) extend up to
1877
- * a per-kind cap, then deny — those ceilings are the real runaway guard.
1878
- */
1879
-
1880
- interface AutoExtendCeiling {
1881
- maxIterations?: number | undefined;
1882
- maxToolCalls?: number | undefined;
1883
- maxTokens?: number | undefined;
1884
- maxCostUsd?: number | undefined;
1885
- timeoutMs?: number | undefined;
1886
- }
1887
- interface AutoExtendPolicy {
1888
- /** Multiplier applied to the tripped limit when extending. Default 0.5 (+50%). */
1889
- factor?: number | undefined;
1890
- /**
1891
- * Max extensions per NON-timeout kind before denying. Timeout is governed by
1892
- * the heartbeat check, not this cap, so it can extend indefinitely while the
1893
- * agent makes progress. Default 8.
1894
- */
1895
- maxExtensionsPerKind?: number | undefined;
1896
- /** Absolute ceilings — an extension never pushes a limit past these. */
1897
- ceiling?: AutoExtendCeiling | undefined;
1898
- }
1899
- /**
1900
- * Attach an auto-extend policy to a subagent's EventBus. Returns an unsubscribe
1901
- * function that detaches all listeners — call it when the subagent task ends.
1902
- */
1903
- declare function attachAutoExtend(events: EventBus, policy?: AutoExtendPolicy): () => void;
1904
-
1905
1905
  /**
1906
1906
  * A no-op FleetBus that discards all events. Used when no real fleet
1907
1907
  * bus is available (non-director mode) so the runner's `fleetBus`