@wrongstack/core 0.6.6 → 0.7.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 (52) hide show
  1. package/dist/{agent-bridge-BBXK_ppx.d.ts → agent-bridge-CrQpYjM7.d.ts} +1 -1
  2. package/dist/{compactor-C8NhpSt5.d.ts → compactor-CWV1u-IU.d.ts} +1 -1
  3. package/dist/{config-DfC6g6KV.d.ts → config-C34JRwl4.d.ts} +1 -1
  4. package/dist/{context-DN5v-uQX.d.ts → context-bmR0YgBm.d.ts} +74 -8
  5. package/dist/coordination/index.d.ts +11 -11
  6. package/dist/coordination/index.js +115 -39
  7. package/dist/coordination/index.js.map +1 -1
  8. package/dist/default-config-DvRSTELf.d.ts +20 -0
  9. package/dist/defaults/index.d.ts +20 -19
  10. package/dist/defaults/index.js +224 -64
  11. package/dist/defaults/index.js.map +1 -1
  12. package/dist/{events-CJqwQl8G.d.ts → events-CEKFTmIY.d.ts} +10 -1
  13. package/dist/execution/index.d.ts +27 -13
  14. package/dist/execution/index.js +153 -40
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/extension/index.d.ts +6 -6
  17. package/dist/extension/index.js +3 -1
  18. package/dist/extension/index.js.map +1 -1
  19. package/dist/{index-DcnXDPdY.d.ts → index-BJIFLGII.d.ts} +20 -5
  20. package/dist/{index-CXnWsGBp.d.ts → index-CZR0HjxM.d.ts} +14 -110
  21. package/dist/index.d.ts +27 -26
  22. package/dist/index.js +396 -180
  23. package/dist/index.js.map +1 -1
  24. package/dist/infrastructure/index.d.ts +6 -6
  25. package/dist/kernel/index.d.ts +9 -9
  26. package/dist/kernel/index.js +8 -4
  27. package/dist/kernel/index.js.map +1 -1
  28. package/dist/{mcp-servers-CevFHHM1.d.ts → mcp-servers-BRJicm5o.d.ts} +3 -3
  29. package/dist/models/index.d.ts +2 -2
  30. package/dist/{multi-agent-D5IbASk_.d.ts → multi-agent-Cm1wYSrw.d.ts} +9 -4
  31. package/dist/{agent-subagent-runner-DsSm9lKN.d.ts → multi-agent-coordinator-CCupVFqv.d.ts} +117 -4
  32. package/dist/observability/index.d.ts +2 -2
  33. package/dist/{path-resolver-CBx_q1HA.d.ts → path-resolver-CfT7e_HT.d.ts} +2 -2
  34. package/dist/{plan-templates-BEOllUJV.d.ts → plan-templates-Q78an-GJ.d.ts} +4 -4
  35. package/dist/{provider-runner-Byh5TcJs.d.ts → provider-runner-WDj28o7J.d.ts} +3 -3
  36. package/dist/{retry-policy-BZSIMxrJ.d.ts → retry-policy-Dpxp4SET.d.ts} +1 -1
  37. package/dist/sdd/index.d.ts +3 -3
  38. package/dist/{secret-scrubber-CT7wefiO.d.ts → secret-scrubber-C2YCYtkn.d.ts} +1 -1
  39. package/dist/{secret-scrubber-I0QHY_ob.d.ts → secret-scrubber-CowtdEF8.d.ts} +1 -1
  40. package/dist/security/index.d.ts +3 -3
  41. package/dist/{selector-DDb_mq9X.d.ts → selector-CP39HhCe.d.ts} +1 -1
  42. package/dist/{session-reader-B9nVkziM.d.ts → session-reader-Dwjn4WZR.d.ts} +1 -1
  43. package/dist/storage/index.d.ts +5 -5
  44. package/dist/storage/index.js +94 -11
  45. package/dist/storage/index.js.map +1 -1
  46. package/dist/{system-prompt-gL06H9P4.d.ts → system-prompt-CfgXqyv2.d.ts} +1 -1
  47. package/dist/{tool-executor-BF7QfYVE.d.ts → tool-executor-D5NFi_LV.d.ts} +5 -5
  48. package/dist/types/index.d.ts +16 -15
  49. package/dist/types/index.js +102 -23
  50. package/dist/types/index.js.map +1 -1
  51. package/dist/utils/index.d.ts +1 -1
  52. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { B as BridgeTransport, l as BridgeMessage, A as AgentBridge, m as AgentBridgeConfig } from './multi-agent-D5IbASk_.js';
1
+ import { B as BridgeTransport, l as BridgeMessage, A as AgentBridge, m as AgentBridgeConfig } from './multi-agent-Cm1wYSrw.js';
2
2
 
3
3
  /**
4
4
  * In-memory pub/sub transport for agent-to-agent messaging.
@@ -1,4 +1,4 @@
1
- import { a2 as Context } from './context-DN5v-uQX.js';
1
+ import { a5 as Context } from './context-bmR0YgBm.js';
2
2
 
3
3
  interface CompactRepairReport {
4
4
  removedToolUses: string[];
@@ -1,5 +1,5 @@
1
1
  import { W as WireFamily } from './models-registry-Y2xbog0E.js';
2
- import { P as Permission } from './context-DN5v-uQX.js';
2
+ import { P as Permission } from './context-bmR0YgBm.js';
3
3
 
4
4
  type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';
5
5
  type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';
@@ -91,8 +91,62 @@ declare function asText(content: string | ContentBlock[]): string;
91
91
  * This lets consumers (CLI, TUI, plugins, tests) branch on structured
92
92
  * data instead of parsing error messages.
93
93
  */
94
- type ErrorCode = 'PROVIDER_RATE_LIMITED' | 'PROVIDER_AUTH_FAILED' | 'PROVIDER_OVERLOADED' | 'PROVIDER_INVALID_REQUEST' | 'PROVIDER_SERVER_ERROR' | 'PROVIDER_NETWORK_ERROR' | 'PROVIDER_CONTEXT_OVERFLOW' | 'TOOL_NOT_FOUND' | 'TOOL_PERMISSION_DENIED' | 'TOOL_EXECUTION_FAILED' | 'TOOL_TIMEOUT' | 'TOOL_INPUT_INVALID' | 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED' | 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY' | 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED' | 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED' | 'CONTAINER_TOKEN_ALREADY_BOUND' | 'CONTAINER_TOKEN_NOT_BOUND' | 'REGISTRY_DUPLICATE' | 'REGISTRY_NOT_FOUND' | 'UNKNOWN';
95
- type ErrorSubsystem = 'provider' | 'tool' | 'config' | 'plugin' | 'agent' | 'session' | 'container' | 'general';
94
+ /**
95
+ * Machine-readable error codes as frozen constants.
96
+ *
97
+ * Use `ERROR_CODES.X` instead of raw string literals for:
98
+ * - IDE autocomplete and compile-time validation
99
+ * - Safe refactoring (rename updates all usages)
100
+ * - Plugin extensibility (extend the object to add custom codes)
101
+ *
102
+ * The `ErrorCode` type is derived from this object, so adding a new
103
+ * code here automatically updates the type without extra changes.
104
+ */
105
+ declare const ERROR_CODES: {
106
+ readonly PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED";
107
+ readonly PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED";
108
+ readonly PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED";
109
+ readonly PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST";
110
+ readonly PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR";
111
+ readonly PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR";
112
+ readonly PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW";
113
+ readonly TOOL_NOT_FOUND: "TOOL_NOT_FOUND";
114
+ readonly TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED";
115
+ readonly TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED";
116
+ readonly TOOL_TIMEOUT: "TOOL_TIMEOUT";
117
+ readonly TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID";
118
+ readonly CONFIG_INVALID: "CONFIG_INVALID";
119
+ readonly CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND";
120
+ readonly CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED";
121
+ readonly CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED";
122
+ readonly PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED";
123
+ readonly PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH";
124
+ readonly PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY";
125
+ readonly AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT";
126
+ readonly AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW";
127
+ readonly AGENT_ABORTED: "AGENT_ABORTED";
128
+ readonly AGENT_RUN_FAILED: "AGENT_RUN_FAILED";
129
+ readonly SESSION_NOT_FOUND: "SESSION_NOT_FOUND";
130
+ readonly SESSION_CORRUPTED: "SESSION_CORRUPTED";
131
+ readonly SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED";
132
+ readonly CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND";
133
+ readonly CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND";
134
+ readonly REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE";
135
+ readonly REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND";
136
+ readonly FS_READ_FAILED: "FS_READ_FAILED";
137
+ readonly FS_WRITE_FAILED: "FS_WRITE_FAILED";
138
+ readonly FS_MKDIR_FAILED: "FS_MKDIR_FAILED";
139
+ readonly FS_DELETE_FAILED: "FS_DELETE_FAILED";
140
+ readonly FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED";
141
+ readonly UNKNOWN: "UNKNOWN";
142
+ };
143
+ /**
144
+ * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`
145
+ * instead of a string literal union means TypeScript auto-updates the type whenever
146
+ * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.
147
+ */
148
+ type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
149
+ type ErrorSubsystem = 'provider' | 'tool' | 'config' | 'plugin' | 'agent' | 'session' | 'container' | 'fs' | 'general';
96
150
  type ErrorSeverity = 'fatal' | 'error' | 'warning';
97
151
  declare class WrongStackError extends Error {
98
152
  readonly code: ErrorCode;
@@ -186,12 +240,26 @@ declare class SessionError extends WrongStackError {
186
240
  cause?: unknown;
187
241
  });
188
242
  }
243
+ /**
244
+ * File system operation errors.
245
+ */
246
+ declare class FsError extends WrongStackError {
247
+ readonly path?: string;
248
+ constructor(opts: {
249
+ message: string;
250
+ code: Extract<ErrorCode, 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'>;
251
+ path?: string;
252
+ context?: Record<string, unknown>;
253
+ cause?: unknown;
254
+ });
255
+ }
189
256
  declare function isWrongStackError(err: unknown): err is WrongStackError;
190
257
  declare function isToolError(err: unknown): err is ToolError;
191
258
  declare function isConfigError(err: unknown): err is ConfigError;
192
259
  declare function isPluginError(err: unknown): err is PluginError;
193
260
  declare function isSessionError(err: unknown): err is SessionError;
194
261
  declare function isAgentError(err: unknown): err is AgentError;
262
+ declare function isFsError(err: unknown): err is FsError;
195
263
 
196
264
  type Permission = 'auto' | 'confirm' | 'deny';
197
265
  /**
@@ -952,11 +1020,9 @@ declare class Context implements RunEnv {
952
1020
  private _state;
953
1021
  get state(): ConversationState;
954
1022
  /**
955
- * Register a teardown hook tied to the current run's abort signal. The
956
- * hook fires when the run aborts or ends normally Agent.run wires this
957
- * through a RunController. Hooks registered before a run starts are stored
958
- * and fired when the next run ends; there is no "immediate fire" when no
959
- * run is active.
1023
+ * Register a teardown hook tied to the current run's abort signal.
1024
+ * Hooks registered before a run starts are stored and fired when the
1025
+ * next run ends; there is no immediate fire when no run is active.
960
1026
  *
961
1027
  * **Scope:** these hooks fire on the **whole agent run's** abort, not on
962
1028
  * an individual tool call. For per-tool teardown of resources owned by
@@ -972,4 +1038,4 @@ declare class Context implements RunEnv {
972
1038
  usage(): Usage;
973
1039
  }
974
1040
 
975
- export { isToolUseBlock as $, AgentError as A, type ToolResultBlock as B, type Capabilities as C, type ToolStreamEvent as D, type ErrorCode as E, type FileSnapshot as F, type ToolUseBlock as G, asBlocks as H, type ImageBlock as I, type JSONSchema as J, asText as K, isAgentError as L, type Message as M, isConfigError as N, isImageBlock as O, type Permission as P, isPluginError as Q, type Request as R, type SessionData as S, type TextBlock as T, type Usage as U, isSessionError as V, WrongStackError as W, isTextBlock as X, isThinkingBlock as Y, isToolError as Z, isToolResultBlock as _, ConfigError as a, isWrongStackError as a0, toWrongStackError as a1, Context as a2, type TokenCounter as a3, type CacheStats as a4, type TodoItem as a5, ConversationState as a6, type ContextInit as a7, type ReadonlyConversationState as a8, type RunEnv as a9, type RunOptions as aa, type StateChange as ab, type StateChangeHandler as ac, extractRunEnv as ad, wrapAsState as ae, type ContentBlock as b, type ErrorSeverity as c, type ErrorSubsystem as d, type MessageRole as e, PluginError as f, type Provider as g, ProviderError as h, type ProviderErrorBody as i, type Response as j, type ResumedSession as k, type RiskTier as l, SessionError as m, type SessionEvent as n, type SessionMetadata as o, type SessionStore as p, type SessionSummary as q, type SessionWriter as r, type StopReason as s, type StreamEvent as t, type ThinkingBlock as u, type Tool as v, type ToolCallContext as w, ToolError as x, type ToolFinalEvent as y, type ToolProgressEvent as z };
1041
+ export { isThinkingBlock as $, AgentError as A, type ToolFinalEvent as B, type Capabilities as C, type ToolProgressEvent as D, ERROR_CODES as E, type FileSnapshot as F, type ToolResultBlock as G, type ToolStreamEvent as H, type ImageBlock as I, type JSONSchema as J, type ToolUseBlock as K, asBlocks as L, type Message as M, asText as N, isAgentError as O, type Permission as P, isConfigError as Q, type Request as R, type SessionData as S, type TextBlock as T, type Usage as U, isFsError as V, WrongStackError as W, isImageBlock as X, isPluginError as Y, isSessionError as Z, isTextBlock as _, ConfigError as a, isToolError as a0, isToolResultBlock as a1, isToolUseBlock as a2, isWrongStackError as a3, toWrongStackError as a4, Context as a5, type TokenCounter as a6, type CacheStats as a7, type TodoItem as a8, ConversationState as a9, type ContextInit as aa, type ReadonlyConversationState as ab, type RunEnv as ac, type RunOptions as ad, type StateChange as ae, type StateChangeHandler as af, extractRunEnv as ag, wrapAsState as ah, type ContentBlock as b, type ErrorCode as c, type ErrorSeverity as d, type ErrorSubsystem as e, FsError as f, type MessageRole as g, PluginError as h, type Provider as i, ProviderError as j, type ProviderErrorBody as k, type Response as l, type ResumedSession as m, type RiskTier as n, SessionError as o, type SessionEvent as p, type SessionMetadata as q, type SessionStore as r, type SessionSummary as s, type SessionWriter as t, type StopReason as u, type StreamEvent as v, type ThinkingBlock as w, type Tool as x, type ToolCallContext as y, ToolError as z };
@@ -1,15 +1,15 @@
1
- export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, b as DEFAULT_SUBAGENT_BASELINE, c as DefaultMultiAgentCoordinator, d as DelegateHost, e as Director, f as DirectorPromptParts, g as DirectorSessionFactory, h as DirectorSessionFactoryOptions, F as FLEET_ROSTER, u as FleetCostCapError, j as FleetManager, k as FleetManagerOptions, l as FleetSpawnBudgetError, I as ICoordinator, m as IFleetManager, M as MultiAgentCoordinatorOptions, N as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, n as SubagentPromptParts, p as composeDirectorPrompt, q as composeSubagentPrompt, r as createDelegateTool, s as makeDirectorSessionFactory, t as rosterSummaryFromConfigs } from '../index-CXnWsGBp.js';
2
- export { n as BudgetExceededError, o as BudgetKind, p as BudgetLimits, s as BudgetThresholdDecision, t as BudgetThresholdHandler, u as BudgetThresholdSignal, q as BudgetUsage, r as SubagentBudget } from '../multi-agent-D5IbASk_.js';
3
- export { A as AgentFactory, a as AgentFactoryResult, b as AgentRunnerOptions, F as FleetBus, c as FleetEvent, d as FleetHandler, e as FleetUsage, f as FleetUsageAggregator, S as SubagentUsageSnapshot, m as makeAgentSubagentRunner } from '../agent-subagent-runner-DsSm9lKN.js';
4
- export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-BBXK_ppx.js';
1
+ export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, b as DEFAULT_SUBAGENT_BASELINE, c as DelegateHost, d as Director, e as DirectorPromptParts, f as DirectorSessionFactory, g as DirectorSessionFactoryOptions, F as FLEET_ROSTER, t as FleetCostCapError, i as FleetManager, j as FleetManagerOptions, k as FleetSpawnBudgetError, I as ICoordinator, l as IFleetManager, N as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, m as SubagentPromptParts, o as composeDirectorPrompt, p as composeSubagentPrompt, q as createDelegateTool, r as makeDirectorSessionFactory, s as rosterSummaryFromConfigs } from '../index-CZR0HjxM.js';
2
+ export { A as AgentFactory, a as AgentFactoryResult, b as AgentRunnerOptions, D as DefaultMultiAgentCoordinator, F as FleetBus, c as FleetEvent, d as FleetHandler, e as FleetUsage, f as FleetUsageAggregator, M as MultiAgentCoordinatorOptions, S as SubagentUsageSnapshot, m as makeAgentSubagentRunner } from '../multi-agent-coordinator-CCupVFqv.js';
3
+ export { n as BudgetExceededError, o as BudgetKind, p as BudgetLimits, s as BudgetThresholdDecision, t as BudgetThresholdHandler, u as BudgetThresholdSignal, q as BudgetUsage, r as SubagentBudget } from '../multi-agent-Cm1wYSrw.js';
4
+ export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-CrQpYjM7.js';
5
5
  import '../director-state-BmYi3DGA.js';
6
- import '../context-DN5v-uQX.js';
7
- import 'node:events';
8
- import '../events-CJqwQl8G.js';
9
- import '../index-DcnXDPdY.js';
6
+ import '../context-bmR0YgBm.js';
7
+ import '../index-BJIFLGII.js';
10
8
  import '../logger-BMQgxvdy.js';
11
- import '../system-prompt-gL06H9P4.js';
9
+ import '../system-prompt-CfgXqyv2.js';
12
10
  import '../observability-BhnVLBLS.js';
13
- import '../secret-scrubber-CT7wefiO.js';
14
- import '../config-DfC6g6KV.js';
11
+ import '../events-CEKFTmIY.js';
12
+ import '../secret-scrubber-C2YCYtkn.js';
13
+ import '../config-C34JRwl4.js';
15
14
  import '../models-registry-Y2xbog0E.js';
15
+ import 'node:events';
@@ -197,7 +197,7 @@ var DirectorStateCheckpoint = class {
197
197
  this.timer = null;
198
198
  }
199
199
  await this.persist();
200
- if (this.rewriteRequested) {
200
+ while (this.rewriteRequested) {
201
201
  this.rewriteRequested = false;
202
202
  await this.persist();
203
203
  }
@@ -338,10 +338,8 @@ var InMemoryAgentBridge = class {
338
338
  this.pendingRequests.delete(correlationId);
339
339
  reject(new Error(`Request ${correlationId} timed out after ${timeout}ms`));
340
340
  }, timeout);
341
- if (this.stopped) {
341
+ if (!this.inflightGuards.has(correlationId)) {
342
342
  clearTimeout(timer);
343
- this.inflightGuards.delete(correlationId);
344
- this.pendingRequests.delete(correlationId);
345
343
  reject(new Error("Bridge stopped"));
346
344
  return;
347
345
  }
@@ -635,6 +633,14 @@ var FleetUsageAggregator = class {
635
633
  };
636
634
 
637
635
  // src/types/errors.ts
636
+ var ERROR_CODES = {
637
+ // Provider
638
+ PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
639
+ PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
640
+ PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
641
+ PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
642
+ PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
643
+ PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR"};
638
644
  var WrongStackError = class extends Error {
639
645
  code;
640
646
  subsystem;
@@ -726,14 +732,14 @@ function truncate(s, n) {
726
732
  return s.length <= n ? s : `${s.slice(0, n - 1)}\u2026`;
727
733
  }
728
734
  function providerStatusToCode(status, type) {
729
- if (status === 0) return "PROVIDER_NETWORK_ERROR";
730
- if (type === "rate_limit_error" || status === 429) return "PROVIDER_RATE_LIMITED";
731
- if (type === "authentication_error" || status === 401) return "PROVIDER_AUTH_FAILED";
732
- if (type === "overloaded_error" || status === 529) return "PROVIDER_OVERLOADED";
733
- if (type === "invalid_request_error" || status === 400) return "PROVIDER_INVALID_REQUEST";
734
- if (status === 408) return "PROVIDER_NETWORK_ERROR";
735
- if (status >= 500) return "PROVIDER_SERVER_ERROR";
736
- return "PROVIDER_INVALID_REQUEST";
735
+ if (status === 0) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
736
+ if (type === "rate_limit_error" || status === 429) return ERROR_CODES.PROVIDER_RATE_LIMITED;
737
+ if (type === "authentication_error" || status === 401) return ERROR_CODES.PROVIDER_AUTH_FAILED;
738
+ if (type === "overloaded_error" || status === 529) return ERROR_CODES.PROVIDER_OVERLOADED;
739
+ if (type === "invalid_request_error" || status === 400) return ERROR_CODES.PROVIDER_INVALID_REQUEST;
740
+ if (status === 408) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
741
+ if (status >= 500) return ERROR_CODES.PROVIDER_SERVER_ERROR;
742
+ return ERROR_CODES.PROVIDER_INVALID_REQUEST;
737
743
  }
738
744
 
739
745
  // src/coordination/subagent-budget.ts
@@ -789,10 +795,10 @@ var SubagentBudget = class _SubagentBudget {
789
795
  * or hung listener (Director not built / event filter detached mid-run)
790
796
  * leaves the budget over-limit and never enforces anything, since
791
797
  * `checkLimit` returns synchronously via `void this.checkLimitAsync`.
792
- * Hardcoded for now most fleets set their own per-task timeout that
793
- * dwarfs this anyway. 30 s matches the existing event-emit timeoutMs.
798
+ * Raised from 30s to 60s to give subagents more headroom before
799
+ * the threshold negotiation times out and triggers a hard stop.
794
800
  */
795
- static DECISION_TIMEOUT_MS = 3e4;
801
+ static DECISION_TIMEOUT_MS = 6e4;
796
802
  /**
797
803
  * Injected by the runner when wiring the budget to its EventBus.
798
804
  * Used by `checkLimitAsync` to emit `budget.threshold_reached` events.
@@ -1155,13 +1161,19 @@ var FLEET_ROSTER = {
1155
1161
  "security-scanner": SECURITY_SCANNER_AGENT
1156
1162
  };
1157
1163
  var FLEET_ROSTER_BUDGETS = {
1158
- "audit-log": { timeoutMs: 8 * 60 * 1e3, maxIterations: 150, maxToolCalls: 500 },
1159
- "bug-hunter": { timeoutMs: 15 * 60 * 1e3, maxIterations: 200, maxToolCalls: 600 },
1160
- "refactor-planner": { timeoutMs: 12 * 60 * 1e3, maxIterations: 180, maxToolCalls: 550 },
1161
- "security-scanner": { timeoutMs: 15 * 60 * 1e3, maxIterations: 200, maxToolCalls: 600 }
1164
+ "audit-log": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 5e3, maxToolCalls: 15e3 },
1165
+ "bug-hunter": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
1166
+ "refactor-planner": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 6e3, maxToolCalls: 18e3 },
1167
+ "security-scanner": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 }
1168
+ };
1169
+ var GENERIC_SUBAGENT_BUDGET = {
1170
+ timeoutMs: 3 * 60 * 60 * 1e3,
1171
+ maxIterations: 5e3,
1172
+ maxToolCalls: 15e3
1162
1173
  };
1163
1174
  function applyRosterBudget(cfg) {
1164
- const defaultBudget = FLEET_ROSTER_BUDGETS[cfg.role ?? ""];
1175
+ const roleBudget = cfg.role ? FLEET_ROSTER_BUDGETS[cfg.role] : void 0;
1176
+ const defaultBudget = roleBudget ?? (cfg.name ? GENERIC_SUBAGENT_BUDGET : void 0);
1165
1177
  if (!defaultBudget) return cfg;
1166
1178
  return {
1167
1179
  ...cfg,
@@ -1233,7 +1245,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
1233
1245
  // hasParentBridge() — the type now reflects this.
1234
1246
  parentBridge: null,
1235
1247
  doneCondition: this.config.doneCondition,
1236
- maxConcurrent: this.config.maxConcurrent ?? 4
1248
+ maxConcurrent: this.config.maxConcurrent ?? 16
1237
1249
  };
1238
1250
  this.subagents.set(id, {
1239
1251
  config: { ...subagent, id },
@@ -1279,6 +1291,30 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
1279
1291
  this.drainPendingAsAborted("Coordinator stopAll() drained the pending queue");
1280
1292
  await Promise.allSettled([...this.subagents.keys()].map((id) => this.stop(id)));
1281
1293
  }
1294
+ async remove(subagentId) {
1295
+ await this.stop(subagentId);
1296
+ this.subagents.delete(subagentId);
1297
+ }
1298
+ /**
1299
+ * Get current coordinator stats for monitoring/debugging.
1300
+ */
1301
+ getStats() {
1302
+ let running = 0, idle = 0, stopped = 0;
1303
+ for (const [, entry] of this.subagents) {
1304
+ if (entry.status === "running") running++;
1305
+ else if (entry.status === "idle") idle++;
1306
+ else stopped++;
1307
+ }
1308
+ return {
1309
+ total: this.subagents.size,
1310
+ running,
1311
+ idle,
1312
+ stopped,
1313
+ inFlight: this.inFlight,
1314
+ pending: this.pendingTasks.length,
1315
+ completed: this.completedResults.length
1316
+ };
1317
+ }
1282
1318
  getStatus() {
1283
1319
  return {
1284
1320
  coordinatorId: this.coordinatorId,
@@ -1360,7 +1396,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
1360
1396
  }
1361
1397
  }
1362
1398
  canDispatch() {
1363
- const max = this.config.maxConcurrent ?? 4;
1399
+ const max = this.config.maxConcurrent ?? 16;
1364
1400
  return this.inFlight < max && this.pendingTasks.length > 0;
1365
1401
  }
1366
1402
  takeNextDispatchableTask() {
@@ -1454,13 +1490,18 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
1454
1490
  task.subagentId = subagentId;
1455
1491
  subagent.context.tasks.push(task);
1456
1492
  this.emit("task.assigned", { task, subagentId });
1493
+ const rawMaxIterations = subagent.config.maxIterations;
1494
+ const rawMaxToolCalls = subagent.config.maxToolCalls;
1495
+ const rawMaxTokens = subagent.config.maxTokens;
1496
+ const rawMaxCostUsd = subagent.config.maxCostUsd;
1497
+ const rawTimeoutMs = subagent.config.timeoutMs;
1457
1498
  const configWithRosterDefaults = applyRosterBudget(subagent.config);
1458
1499
  const budget = new SubagentBudget({
1459
- maxIterations: configWithRosterDefaults.maxIterations ?? this.config.defaultBudget?.maxIterations,
1460
- maxToolCalls: task.maxToolCalls ?? configWithRosterDefaults.maxToolCalls ?? this.config.defaultBudget?.maxToolCalls,
1461
- maxTokens: configWithRosterDefaults.maxTokens ?? this.config.defaultBudget?.maxTokens,
1462
- maxCostUsd: configWithRosterDefaults.maxCostUsd ?? this.config.defaultBudget?.maxCostUsd,
1463
- timeoutMs: task.timeoutMs ?? configWithRosterDefaults.timeoutMs ?? this.config.defaultBudget?.timeoutMs
1500
+ maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
1501
+ maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
1502
+ maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
1503
+ maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
1504
+ timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs
1464
1505
  });
1465
1506
  subagent.activeBudget = budget;
1466
1507
  if (!this.runner) {
@@ -1531,7 +1572,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
1531
1572
  kind: "timeout",
1532
1573
  used: elapsed,
1533
1574
  limit,
1534
- timeoutMs: 3e4,
1575
+ timeoutMs: 6e4,
1535
1576
  extend: (extra) => resolveDecision({ extend: extra }),
1536
1577
  deny: () => resolveDecision("stop")
1537
1578
  });
@@ -2249,7 +2290,12 @@ var Director = class {
2249
2290
  }
2250
2291
  }
2251
2292
  }
2252
- const result = await this.coordinator.spawn(config);
2293
+ let result;
2294
+ try {
2295
+ result = await this.coordinator.spawn(config);
2296
+ } catch (err) {
2297
+ throw err;
2298
+ }
2253
2299
  if (this.fleetManager) {
2254
2300
  this.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
2255
2301
  } else {
@@ -2517,6 +2563,9 @@ var Director = class {
2517
2563
  async terminateAll() {
2518
2564
  await this.coordinator.stopAll();
2519
2565
  }
2566
+ async remove(subagentId) {
2567
+ await this.coordinator.remove(subagentId);
2568
+ }
2520
2569
  status() {
2521
2570
  return this.coordinator.getStatus();
2522
2571
  }
@@ -2697,7 +2746,7 @@ var Director = class {
2697
2746
  }
2698
2747
  };
2699
2748
  function createDelegateTool(opts) {
2700
- const defaultTimeoutMs = opts.defaultTimeoutMs ?? 4 * 60 * 60 * 1e3;
2749
+ const defaultTimeoutMs = opts.defaultTimeoutMs ?? 30 * 60 * 1e3;
2701
2750
  const rosterIds = opts.roster ? Object.keys(opts.roster) : [];
2702
2751
  const inputSchema = {
2703
2752
  type: "object",
@@ -2713,7 +2762,7 @@ function createDelegateTool(opts) {
2713
2762
  },
2714
2763
  name: {
2715
2764
  type: "string",
2716
- description: "Display name for the subagent when not using a roster role. Required when `role` is omitted."
2765
+ description: "Display name for free-form subagents (not using a roster role). The subagent gets a large default budget (3h, 5000 iter, 15000 tool calls). Required when `role` is omitted."
2717
2766
  },
2718
2767
  provider: {
2719
2768
  type: "string",
@@ -2744,8 +2793,8 @@ function createDelegateTool(opts) {
2744
2793
  };
2745
2794
  return {
2746
2795
  name: "delegate",
2747
- description: "Hand a discrete piece of work to a dedicated subagent and wait for its result. The subagent has its own context, its own LLM call, and its own budget \u2014 use this when a task is self-contained, would otherwise blow up your context, or benefits from a specialized role (bug-hunter, security-scanner, refactor-planner, audit-log). YOU decide how big the budget is: pass `timeoutMs`, `maxIterations`, and `maxToolCalls` sized to the actual work. There is no hidden cap forcing a 3-minute / 80-iteration limit \u2014 if a monorepo audit needs 2 hours and 500 tool calls, ask for that. Call multiple delegates in parallel through the provider's parallel-tool-call surface to fan work out across roles.",
2748
- usageHint: "Set `task` to a complete instruction. Either pick `role` from the roster or pass `name` + `provider` + `model`. For non-trivial work, also pass `timeoutMs` (the wall-clock budget you actually need), `maxIterations`, and `maxToolCalls` \u2014 defaults are intentionally generous (4 hours) but the right values depend on scope. 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.",
2796
+ description: "Hand a discrete piece of work to a dedicated subagent and wait for its result. The subagent has its own context, its own LLM call, and its own budget \u2014 use this when a task is self-contained, would otherwise blow up your context, or benefits from a specialized role (bug-hunter, security-scanner, refactor-planner, audit-log). For free-form coding tasks (not tied to a pre-defined role), pass `name` + `task` \u2014 the subagent runs as a general-purpose coding agent with a large default budget. YOU decide how big the budget is: pass `timeoutMs`, `maxIterations`, and `maxToolCalls` sized to the actual work. There is no hidden cap forcing a 3-minute / 80-iteration limit \u2014 if a monorepo audit needs 2 hours and 500 tool calls, ask for that. Call multiple delegates in parallel through the provider's parallel-tool-call surface to fan work out across roles.",
2797
+ 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.",
2749
2798
  permission: "auto",
2750
2799
  mutating: false,
2751
2800
  inputSchema,
@@ -2793,6 +2842,7 @@ function createDelegateTool(opts) {
2793
2842
  model: i.model,
2794
2843
  systemPromptOverride: i.systemPromptOverride
2795
2844
  };
2845
+ cfg = applyRosterBudget({ ...cfg, name: i.name });
2796
2846
  }
2797
2847
  if (typeof i.maxIterations === "number" && i.maxIterations > 0) {
2798
2848
  cfg.maxIterations = i.maxIterations;
@@ -2800,7 +2850,7 @@ function createDelegateTool(opts) {
2800
2850
  if (typeof i.maxToolCalls === "number" && i.maxToolCalls > 0) {
2801
2851
  cfg.maxToolCalls = i.maxToolCalls;
2802
2852
  }
2803
- const SUBAGENT_TIMEOUT_BUFFER_MS = opts.subagentTimeoutBufferMs ?? 3e4;
2853
+ const SUBAGENT_TIMEOUT_BUFFER_MS = opts.subagentTimeoutBufferMs ?? 6e4;
2804
2854
  const desiredSubTimeout = Math.max(3e4, timeoutMs - SUBAGENT_TIMEOUT_BUFFER_MS);
2805
2855
  if (!cfg.timeoutMs || cfg.timeoutMs > desiredSubTimeout) {
2806
2856
  cfg.timeoutMs = desiredSubTimeout;
@@ -2837,6 +2887,7 @@ function createDelegateTool(opts) {
2837
2887
  const errorKind = result.error?.kind;
2838
2888
  const retryable = result.error?.retryable;
2839
2889
  const backoffMs = result.error?.backoffMs;
2890
+ const summary = buildDelegateSummary(i.role, result);
2840
2891
  return {
2841
2892
  ok: result.status === "success",
2842
2893
  status: result.status,
@@ -2852,7 +2903,10 @@ function createDelegateTool(opts) {
2852
2903
  toolCalls: result.toolCalls,
2853
2904
  durationMs: result.durationMs,
2854
2905
  ...partial ? { partial } : {},
2855
- ...hintForKind(errorKind, retryable, backoffMs, partial) ? { hint: hintForKind(errorKind, retryable, backoffMs, partial) } : {}
2906
+ ...hintForKind(errorKind, retryable, backoffMs, partial) ? { hint: hintForKind(errorKind, retryable, backoffMs, partial) } : {},
2907
+ // Summary is included so callers (TUI, CLI renderer) can surface
2908
+ // it as a chat history line — the LLM also sees it for continuity.
2909
+ summary
2856
2910
  };
2857
2911
  } catch (err) {
2858
2912
  return {
@@ -2865,10 +2919,11 @@ function createDelegateTool(opts) {
2865
2919
  };
2866
2920
  }
2867
2921
  function instantiateRosterConfig2(role, base) {
2922
+ const withBudget = applyRosterBudget({ ...base, role });
2868
2923
  return {
2869
- ...base,
2870
- // Roster entries are templates. Give each spawn a fresh id so
2871
- // parallel or repeated delegates can use the same role safely.
2924
+ ...withBudget,
2925
+ // Give each spawn a fresh id so parallel or repeated delegates
2926
+ // can use the same role safely.
2872
2927
  id: `${role}-${randomUUID().slice(0, 8)}`
2873
2928
  };
2874
2929
  }
@@ -2928,6 +2983,18 @@ ${partial.lastAssistantText}`;
2928
2983
  return retryable ? "Failure classified as retryable. Try again with the same input." : void 0;
2929
2984
  }
2930
2985
  }
2986
+ function buildDelegateSummary(role, result) {
2987
+ const roleLabel = role ?? "subagent";
2988
+ const ms = result.durationMs;
2989
+ const duration = ms < 6e4 ? `${Math.round(ms / 1e3)}s` : ms < 36e5 ? `${Math.round(ms / 6e4)}m` : `${(ms / 36e5).toFixed(1)}h`;
2990
+ if (result.status === "success") {
2991
+ const preview = typeof result.result === "string" ? result.result.trim().slice(0, 120).replace(/\n+/g, " ") : null;
2992
+ const tail = preview ? ` \u2014 ${preview}` : "";
2993
+ return `[${roleLabel}] done in ${duration} (${result.iterations} iter, ${result.toolCalls} tools)${tail}`;
2994
+ }
2995
+ const errLabel = result.error?.kind ?? result.status;
2996
+ return `[${roleLabel}] ${result.status} after ${duration} (${result.iterations} iter, ${result.toolCalls} tools) \u2014 ${errLabel}`;
2997
+ }
2931
2998
  async function readSubagentPartial(opts, subagentId) {
2932
2999
  if (!opts.sessionsRoot) return void 0;
2933
3000
  const candidates = [];
@@ -2968,6 +3035,7 @@ async function readSubagentPartial(opts, subagentId) {
2968
3035
  }
2969
3036
  }
2970
3037
  } catch {
3038
+ continue;
2971
3039
  }
2972
3040
  }
2973
3041
  return {
@@ -3273,8 +3341,16 @@ var DefaultSessionStore = class {
3273
3341
  }
3274
3342
  }
3275
3343
  async resume(id) {
3276
- const data = await this.load(id);
3277
3344
  const file = path4.join(this.dir, `${id}.jsonl`);
3345
+ try {
3346
+ await fsp4.access(file, fsp4.constants.R_OK);
3347
+ } catch {
3348
+ throw new Error(
3349
+ `Session "${id}" not found \u2014 the session file does not exist or was deleted.`,
3350
+ { cause: new Error("ENOENT") }
3351
+ );
3352
+ }
3353
+ const data = await this.load(id);
3278
3354
  let handle;
3279
3355
  try {
3280
3356
  handle = await fsp4.open(file, "a", 384);