@wrongstack/core 0.6.7 → 0.7.2

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 (56) hide show
  1. package/dist/{agent-bridge-BCVxmrOn.d.ts → agent-bridge-Bji75Iv9.d.ts} +1 -1
  2. package/dist/{compactor-BUJ8550X.d.ts → compactor-BFKGzKd5.d.ts} +1 -1
  3. package/dist/{config-BHkYGzUT.d.ts → config-BXAhlqJb.d.ts} +1 -1
  4. package/dist/{context-C8mBUzBv.d.ts → context-BwxhvyW8.d.ts} +75 -3
  5. package/dist/coordination/index.d.ts +42 -12
  6. package/dist/coordination/index.js +2573 -40
  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 +21 -20
  10. package/dist/defaults/index.js +2896 -243
  11. package/dist/defaults/index.js.map +1 -1
  12. package/dist/{director-state-BmYi3DGA.d.ts → director-state-BUB7JRUr.d.ts} +1 -1
  13. package/dist/{events-DounT6pP.d.ts → events-AjrvHJ9V.d.ts} +25 -1
  14. package/dist/execution/index.d.ts +42 -13
  15. package/dist/execution/index.js +2497 -40
  16. package/dist/execution/index.js.map +1 -1
  17. package/dist/extension/index.d.ts +6 -6
  18. package/dist/extension/index.js +3 -1
  19. package/dist/extension/index.js.map +1 -1
  20. package/dist/{index-DiIGZh5I.d.ts → index-B2WWETRP.d.ts} +6 -6
  21. package/dist/index.d.ts +36 -27
  22. package/dist/index.js +2863 -137
  23. package/dist/index.js.map +1 -1
  24. package/dist/infrastructure/index.d.ts +6 -6
  25. package/dist/infrastructure/index.js +12 -0
  26. package/dist/infrastructure/index.js.map +1 -1
  27. package/dist/kernel/index.d.ts +9 -9
  28. package/dist/kernel/index.js +20 -4
  29. package/dist/kernel/index.js.map +1 -1
  30. package/dist/{mcp-servers-CXFfDN_d.d.ts → mcp-servers-BDM2Leff.d.ts} +3 -3
  31. package/dist/models/index.d.ts +2 -2
  32. package/dist/{multi-agent-Iy8YUe3v.d.ts → multi-agent-DenFfUv5.d.ts} +11 -3
  33. package/dist/multi-agent-coordinator-DGUn-5Bb.d.ts +448 -0
  34. package/dist/{index-BlVITqm-.d.ts → null-fleet-bus-DJMbqYhL.d.ts} +105 -107
  35. package/dist/observability/index.d.ts +2 -2
  36. package/dist/{path-resolver-DwJO5XBn.d.ts → path-resolver-C1NM67-u.d.ts} +2 -2
  37. package/dist/{plan-templates-CG_pInJV.d.ts → plan-templates-CNY6f82B.d.ts} +4 -4
  38. package/dist/{provider-runner-DoohzfyD.d.ts → provider-runner-Cmuevptw.d.ts} +3 -3
  39. package/dist/{retry-policy-DOnwHAyz.d.ts → retry-policy-mEBn5qpv.d.ts} +1 -1
  40. package/dist/sdd/index.d.ts +3 -3
  41. package/dist/{secret-scrubber-DcTK9JHC.d.ts → secret-scrubber-BmiGszvl.d.ts} +1 -1
  42. package/dist/{secret-scrubber-C9UJxFCJ.d.ts → secret-scrubber-bZ5AyhwJ.d.ts} +1 -1
  43. package/dist/security/index.d.ts +3 -3
  44. package/dist/{selector-DVo3eT-P.d.ts → selector-BmUma5iG.d.ts} +1 -1
  45. package/dist/{session-reader-BXWxFAhS.d.ts → session-reader-g-FKCyBw.d.ts} +1 -1
  46. package/dist/storage/index.d.ts +6 -6
  47. package/dist/storage/index.js +101 -14
  48. package/dist/storage/index.js.map +1 -1
  49. package/dist/{system-prompt-BBGles-N.d.ts → system-prompt-BKrzd_ci.d.ts} +1 -1
  50. package/dist/{tool-executor-CwpjhwHC.d.ts → tool-executor-BoM0U0qn.d.ts} +6 -5
  51. package/dist/types/index.d.ts +16 -15
  52. package/dist/types/index.js +130 -20
  53. package/dist/types/index.js.map +1 -1
  54. package/dist/utils/index.d.ts +1 -1
  55. package/package.json +1 -1
  56. package/dist/agent-subagent-runner-BTloSwjE.d.ts +0 -174
@@ -1,9 +1,33 @@
1
- import { a as DirectorStateSnapshot } from './director-state-BmYi3DGA.js';
2
- import { c as SubagentConfig, j as TaskResult, a as CoordinatorStatus, k as TaskSpec, M as MultiAgentConfig, i as SubagentRunner, b as MultiAgentCoordinator, S as SpawnResult, l as BridgeMessage, A as AgentBridge } from './multi-agent-Iy8YUe3v.js';
3
- import { r as SessionWriter, v as Tool, p as SessionStore } from './context-C8mBUzBv.js';
4
- import { I as InMemoryAgentBridge } from './agent-bridge-BCVxmrOn.js';
5
- import { F as FleetBus, e as FleetUsage, f as FleetUsageAggregator } from './agent-subagent-runner-BTloSwjE.js';
6
- import { EventEmitter } from 'node:events';
1
+ import { e as AgentPhase, A as AgentDefinition, F as FleetBus, o as FleetUsage, p as FleetUsageAggregator } from './multi-agent-coordinator-DGUn-5Bb.js';
2
+ import { c as SubagentConfig, j as TaskResult, a as CoordinatorStatus, k as TaskSpec, M as MultiAgentConfig, i as SubagentRunner } from './multi-agent-DenFfUv5.js';
3
+ import { t as SessionWriter, x as Tool, r as SessionStore } from './context-BwxhvyW8.js';
4
+ import { D as DirectorStateSnapshot } from './director-state-BUB7JRUr.js';
5
+ import { I as InMemoryAgentBridge } from './agent-bridge-Bji75Iv9.js';
6
+ import { E as EventBus } from './events-AjrvHJ9V.js';
7
+
8
+ /**
9
+ * Agent catalog aggregator.
10
+ *
11
+ * Collects every phase's `AgentDefinition[]` into:
12
+ * - `ALL_AGENT_DEFINITIONS` — flat list, catalog order (phase 1 → 9)
13
+ * - `AGENT_CATALOG` — keyed by role for O(1) lookup
14
+ * - `AGENTS_BY_PHASE` — grouped for statusline / dispatcher tie-breaks
15
+ *
16
+ * `fleet.ts` derives `FLEET_ROSTER` + `FLEET_ROSTER_BUDGETS` from this, and the
17
+ * dispatcher routes free-form tasks against `capability` metadata here.
18
+ */
19
+
20
+ /** Every catalog agent, in phase order. */
21
+ declare const ALL_AGENT_DEFINITIONS: AgentDefinition[];
22
+ /** Phase → its agents, for grouped display and dispatcher fallbacks. */
23
+ declare const AGENTS_BY_PHASE: Record<AgentPhase, AgentDefinition[]>;
24
+ /**
25
+ * Role → definition. Built once at module load. Throws on a duplicate role so
26
+ * a copy-paste collision fails loudly at startup instead of silently shadowing.
27
+ */
28
+ declare const AGENT_CATALOG: Record<string, AgentDefinition>;
29
+ /** Role lookup helper. Returns undefined for unknown roles. */
30
+ declare function getAgentDefinition(role: string): AgentDefinition | undefined;
7
31
 
8
32
  /**
9
33
  * Interface for a fleet coordinator. Implemented by both `Director`
@@ -70,6 +94,12 @@ interface ICoordinator {
70
94
  * no new tasks are dispatched.
71
95
  */
72
96
  terminateAll(): Promise<void>;
97
+ /**
98
+ * Stop a subagent and remove it from the coordinator. Releases all
99
+ * associated resources (AbortController, budget state). The subagent
100
+ * entry is deleted so the id can be reused in a future spawn.
101
+ */
102
+ remove(subagentId: string): Promise<void>;
73
103
  /**
74
104
  * Live coordinator status — subagent list, pending task count,
75
105
  * completed task count, iteration totals.
@@ -570,6 +600,9 @@ declare class Director implements ICoordinator {
570
600
  /** Snapshot of which subagent owns each task — drives state-checkpoint
571
601
  * status updates without re-walking the manifest. */
572
602
  private readonly taskOwners;
603
+ /** Cumulative auto-extension grants per subagent (all budget kinds). Lets
604
+ * /fleet render "⚡ extended ×N" without replaying the event stream. */
605
+ private readonly extendTotals;
573
606
  /**
574
607
  * Handle to the coordinator-side `task.completed` listener so we can
575
608
  * unsubscribe in `shutdown()`. Without this, repeated Director
@@ -579,6 +612,14 @@ declare class Director implements ICoordinator {
579
612
  */
580
613
  private taskCompletedListener;
581
614
  constructor(opts: DirectorOptions);
615
+ /**
616
+ * Record a granted budget extension and broadcast it on the FleetBus so
617
+ * the host can re-emit `subagent.budget_extended` for live UI badges.
618
+ * Called from both the timeout heartbeat path and the per-kind grant path.
619
+ */
620
+ private recordExtension;
621
+ /** Cumulative auto-extension count for one subagent (0 when never extended). */
622
+ extensionsFor(subagentId: string): number;
582
623
  /** Best-effort session-writer append. Swallows failures — the director
583
624
  * must not break a fleet run because the session JSONL handle closed. */
584
625
  private appendSessionEvent;
@@ -665,6 +706,7 @@ declare class Director implements ICoordinator {
665
706
  awaitTasks(taskIds: string[]): Promise<TaskResult[]>;
666
707
  terminate(subagentId: string): Promise<void>;
667
708
  terminateAll(): Promise<void>;
709
+ remove(subagentId: string): Promise<void>;
668
710
  status(): CoordinatorStatus;
669
711
  /**
670
712
  * Subscribe to coordinator events. Currently only `task.completed` is
@@ -849,105 +891,6 @@ interface CreateDelegateToolOptions {
849
891
  */
850
892
  declare function createDelegateTool(opts: CreateDelegateToolOptions): Tool;
851
893
 
852
- interface MultiAgentCoordinatorOptions {
853
- /**
854
- * Callback that executes a task on behalf of a subagent. Required for
855
- * `assign()` to actually run anything — without it, tasks queue forever.
856
- * The coordinator provides per-subagent isolation (own budget, own signal,
857
- * own bridge) and enforces timeout + concurrency.
858
- */
859
- runner?: SubagentRunner;
860
- }
861
- declare class DefaultMultiAgentCoordinator extends EventEmitter implements MultiAgentCoordinator {
862
- readonly coordinatorId: string;
863
- readonly config: MultiAgentConfig;
864
- private runner?;
865
- private readonly subagents;
866
- private pendingTasks;
867
- private completedResults;
868
- private totalIterations;
869
- private inFlight;
870
- /**
871
- * Subagents currently being stopped. Set on entry to `stop()`, cleared
872
- * once `recordCompletion` lands the terminal TaskResult. Used by
873
- * `runDispatched` and `findIdleSubagent` to refuse mid-flight dispatch
874
- * to a subagent the caller has already asked to terminate — closes the
875
- * assign+terminate race where a fresh task could land on a worker that
876
- * was about to be killed.
877
- */
878
- private readonly terminating;
879
- constructor(config: MultiAgentConfig, options?: MultiAgentCoordinatorOptions);
880
- /**
881
- * Replace the runner after construction. Used when the runner depends
882
- * on infrastructure (e.g. FleetBus) that isn't available until after
883
- * the coordinator's owning Director is built.
884
- */
885
- setRunner(runner: SubagentRunner): void;
886
- /**
887
- * Change the in-flight dispatch ceiling at runtime. Lowering does NOT
888
- * preempt running tasks — already-dispatched subagents finish their
889
- * current task; only future dispatches respect the new cap. Raising
890
- * immediately tries to fill the freed slots from the pending queue.
891
- */
892
- setMaxConcurrent(n: number): void;
893
- spawn(subagent: SubagentConfig): Promise<SpawnResult>;
894
- assign(task: TaskSpec): Promise<void>;
895
- delegate(to: string, msg: BridgeMessage): Promise<void>;
896
- /**
897
- * Wire up the communication bridge for a subagent. Call after spawn() once
898
- * the caller has created the bidirectional connection.
899
- */
900
- setSubagentBridge(subagentId: string, bridge: AgentBridge): void;
901
- stop(subagentId: string): Promise<void>;
902
- stopAll(): Promise<void>;
903
- getStatus(): CoordinatorStatus;
904
- /** Expose snapshot of completed results — useful for callers awaiting all done. */
905
- results(): readonly TaskResult[];
906
- /**
907
- * Wait for one or more tasks to complete and return their results.
908
- * If a task is already done when called, returns immediately.
909
- * Resolves to an array in the same order as `taskIds`.
910
- */
911
- awaitTasks(taskIds: string[]): Promise<TaskResult[]>;
912
- /**
913
- * Manual completion — for callers that drive subagents without a runner
914
- * (e.g. external orchestrators). When a runner is configured the coordinator
915
- * calls this itself.
916
- */
917
- completeTask(result: TaskResult): void;
918
- private tryDispatchNext;
919
- private canDispatch;
920
- private takeNextDispatchableTask;
921
- private findIdleSubagent;
922
- private isIdleSubagent;
923
- /**
924
- * Returns true iff at least one spawned subagent could still
925
- * process a task. A "live" subagent is one that is not stopped
926
- * AND not mid-termination — `running` workers count because they
927
- * will eventually finish and become idle.
928
- *
929
- * When no subagent has ever been spawned, returns `true` so a
930
- * pre-spawn `assign()` simply queues (legacy behaviour). The
931
- * dead-end detection only fires after `stop()` has retired every
932
- * spawned worker.
933
- *
934
- * Used by `tryDispatchNext` to detect a dead-end pending queue.
935
- */
936
- private hasLiveSubagent;
937
- /**
938
- * Drain every pending task with a synthetic `aborted_by_parent`
939
- * completion event. Same shape as the `stopAll()` drain — we go
940
- * around `recordCompletion` because pending tasks were never
941
- * counted in `inFlight` and routing them through would trip the
942
- * underflow guard on every task after the first.
943
- */
944
- private drainPendingAsAborted;
945
- private runDispatched;
946
- private executeWithTimeout;
947
- private recordCompletion;
948
- private isDone;
949
- }
950
-
951
894
  /**
952
895
  * Per-subagent session factory.
953
896
  *
@@ -1156,7 +1099,12 @@ declare const REFACTOR_PLANNER_AGENT: SubagentConfig;
1156
1099
  * Use for: CI checks, pre-release audits, dependency vulnerability scanning.
1157
1100
  */
1158
1101
  declare const SECURITY_SCANNER_AGENT: SubagentConfig;
1159
- /** All pre-built agents in a map for easy lookup by role. */
1102
+ /**
1103
+ * All agents in a map for easy lookup by role. The four legacy pre-built
1104
+ * agents plus the phase 1-9 catalog (`ALL_AGENT_DEFINITIONS`). Catalog roles
1105
+ * are guaranteed collision-free by the catalog builder; none overlap the
1106
+ * legacy four.
1107
+ */
1160
1108
  declare const FLEET_ROSTER: Record<string, SubagentConfig>;
1161
1109
  interface FleetRosterBudget {
1162
1110
  timeoutMs?: number;
@@ -1169,6 +1117,56 @@ declare const FLEET_ROSTER_BUDGETS: Record<string, FleetRosterBudget>;
1169
1117
  declare function applyRosterBudget(cfg: SubagentConfig): SubagentConfig;
1170
1118
  /** Quick-access list for spawning all at once. */
1171
1119
  declare const ALL_FLEET_AGENTS: SubagentConfig[];
1120
+ /** All ACP external agents. */
1121
+ declare const ACP_AGENTS: SubagentConfig[];
1122
+ /** Extended roster including ACP agents. */
1123
+ declare const FLEET_ROSTER_WITHACP: Record<string, SubagentConfig>;
1124
+
1125
+ /**
1126
+ * Default auto-extend policy for subagent budgets.
1127
+ *
1128
+ * The budget's soft-limit path (`SubagentBudget` → `budget.threshold_reached`)
1129
+ * only negotiates an extension when SOMETHING listens on the EventBus. Under a
1130
+ * `Director`, that listener is the director's own auto-extend handler. On the
1131
+ * plain coordinator path (e.g. a bare `/spawn` with no director) nothing
1132
+ * listens, so the budget falls back to a hard stop and the subagent dies the
1133
+ * moment it crosses a soft limit.
1134
+ *
1135
+ * `attachAutoExtend` is the additive fix: wire it to a subagent's EventBus and
1136
+ * budget overruns are auto-granted headroom instead of killing the run. It is
1137
+ * heartbeat-aware for the timeout kind — wall-clock time always advances, so a
1138
+ * naive "extend timeout forever" would let a wedged agent run indefinitely.
1139
+ * Instead, a timeout extension is granted only when the agent has executed a
1140
+ * new tool call or started a new iteration since the last timeout extension.
1141
+ * No progress since last time ⇒ the agent is genuinely stuck ⇒ deny and let it
1142
+ * fail. The non-timeout kinds (iterations/tool_calls/tokens/cost) extend up to
1143
+ * a per-kind cap, then deny — those ceilings are the real runaway guard.
1144
+ */
1145
+
1146
+ interface AutoExtendCeiling {
1147
+ maxIterations?: number;
1148
+ maxToolCalls?: number;
1149
+ maxTokens?: number;
1150
+ maxCostUsd?: number;
1151
+ timeoutMs?: number;
1152
+ }
1153
+ interface AutoExtendPolicy {
1154
+ /** Multiplier applied to the tripped limit when extending. Default 0.5 (+50%). */
1155
+ factor?: number;
1156
+ /**
1157
+ * Max extensions per NON-timeout kind before denying. Timeout is governed by
1158
+ * the heartbeat check, not this cap, so it can extend indefinitely while the
1159
+ * agent makes progress. Default 8.
1160
+ */
1161
+ maxExtensionsPerKind?: number;
1162
+ /** Absolute ceilings — an extension never pushes a limit past these. */
1163
+ ceiling?: AutoExtendCeiling;
1164
+ }
1165
+ /**
1166
+ * Attach an auto-extend policy to a subagent's EventBus. Returns an unsubscribe
1167
+ * function that detaches all listeners — call it when the subagent task ends.
1168
+ */
1169
+ declare function attachAutoExtend(events: EventBus, policy?: AutoExtendPolicy): () => void;
1172
1170
 
1173
1171
  /**
1174
1172
  * A no-op FleetBus that discards all events. Used when no real fleet
@@ -1179,4 +1177,4 @@ declare const ALL_FLEET_AGENTS: SubagentConfig[];
1179
1177
  */
1180
1178
  declare const NULL_FLEET_BUS: FleetBus;
1181
1179
 
1182
- export { ALL_FLEET_AGENTS as A, BUG_HUNTER_AGENT as B, type CreateDelegateToolOptions as C, DEFAULT_DIRECTOR_PREAMBLE as D, FLEET_ROSTER as F, type ICoordinator as I, type MultiAgentCoordinatorOptions as M, NULL_FLEET_BUS as N, REFACTOR_PLANNER_AGENT as R, SECURITY_SCANNER_AGENT as S, AUDIT_LOG_AGENT as a, DEFAULT_SUBAGENT_BASELINE as b, DefaultMultiAgentCoordinator as c, type DelegateHost as d, Director as e, type DirectorPromptParts as f, type DirectorSessionFactory as g, type DirectorSessionFactoryOptions as h, FLEET_ROSTER_BUDGETS as i, FleetManager as j, type FleetManagerOptions as k, FleetSpawnBudgetError as l, type IFleetManager as m, type SubagentPromptParts as n, applyRosterBudget as o, composeDirectorPrompt as p, composeSubagentPrompt as q, createDelegateTool as r, makeDirectorSessionFactory as s, rosterSummaryFromConfigs as t, FleetCostCapError as u };
1180
+ export { ACP_AGENTS as A, BUG_HUNTER_AGENT as B, type CreateDelegateToolOptions as C, DEFAULT_DIRECTOR_PREAMBLE as D, createDelegateTool as E, FLEET_ROSTER as F, getAgentDefinition as G, makeDirectorSessionFactory as H, type ICoordinator as I, rosterSummaryFromConfigs as J, NULL_FLEET_BUS as N, REFACTOR_PLANNER_AGENT as R, SECURITY_SCANNER_AGENT as S, AGENTS_BY_PHASE as a, AGENT_CATALOG as b, ALL_AGENT_DEFINITIONS as c, ALL_FLEET_AGENTS as d, AUDIT_LOG_AGENT as e, type AutoExtendCeiling as f, type AutoExtendPolicy as g, DEFAULT_SUBAGENT_BASELINE as h, type DelegateHost as i, Director as j, type DirectorPromptParts as k, type DirectorSessionFactory as l, type DirectorSessionFactoryOptions as m, FLEET_ROSTER_BUDGETS as n, FLEET_ROSTER_WITHACP as o, FleetCostCapError as p, FleetManager as q, type FleetManagerOptions as r, type FleetRosterBudget as s, FleetSpawnBudgetError as t, type IFleetManager as u, type SubagentPromptParts as v, applyRosterBudget as w, attachAutoExtend as x, composeDirectorPrompt as y, composeSubagentPrompt as z };
@@ -1,6 +1,6 @@
1
1
  import { e as MetricsSink, M as MetricLabels, f as MetricsSnapshot, b as HealthRegistry, H as HealthCheck, A as AggregateHealth, T as Tracer, S as Span } from '../observability-BhnVLBLS.js';
2
- import { E as EventBus } from '../events-DounT6pP.js';
3
- import '../context-C8mBUzBv.js';
2
+ import { E as EventBus } from '../events-AjrvHJ9V.js';
3
+ import '../context-BwxhvyW8.js';
4
4
 
5
5
  /**
6
6
  * In-memory metrics sink. Suitable for embedded use, tests, and /metrics
@@ -1,6 +1,6 @@
1
- import { E as EventBus } from './events-DounT6pP.js';
1
+ import { E as EventBus } from './events-AjrvHJ9V.js';
2
2
  import { M as ModelsRegistry, b as ResolvedModel } from './models-registry-Y2xbog0E.js';
3
- import { a3 as TokenCounter, U as Usage, a4 as CacheStats } from './context-C8mBUzBv.js';
3
+ import { a6 as TokenCounter, U as Usage, a7 as CacheStats } from './context-BwxhvyW8.js';
4
4
  import { P as PathResolver } from './path-resolver-CPRj4bFY.js';
5
5
 
6
6
  /**
@@ -1,9 +1,9 @@
1
- import { E as EventBus } from './events-DounT6pP.js';
2
- import { p as SessionStore, o as SessionMetadata, r as SessionWriter, k as ResumedSession, S as SessionData, q as SessionSummary, b as ContentBlock, n as SessionEvent, a5 as TodoItem, a6 as ConversationState } from './context-C8mBUzBv.js';
3
- import { e as AttachmentStore, A as AddAttachmentInput, d as AttachmentRef, a as Attachment } from './session-reader-BXWxFAhS.js';
1
+ import { E as EventBus } from './events-AjrvHJ9V.js';
2
+ import { r as SessionStore, q as SessionMetadata, t as SessionWriter, m as ResumedSession, S as SessionData, s as SessionSummary, b as ContentBlock, p as SessionEvent, a8 as TodoItem, a9 as ConversationState } from './context-BwxhvyW8.js';
3
+ import { e as AttachmentStore, A as AddAttachmentInput, d as AttachmentRef, a as Attachment } from './session-reader-g-FKCyBw.js';
4
4
  import { b as MemoryStore, a as MemoryScope } from './memory-CEXuo7sz.js';
5
5
  import { W as WstackPaths } from './wstack-paths-86YPFktR.js';
6
- import { c as ConfigStore, a as Config, b as ConfigLoader } from './config-BHkYGzUT.js';
6
+ import { c as ConfigStore, a as Config, b as ConfigLoader } from './config-BXAhlqJb.js';
7
7
  import { S as SecretVault } from './secret-vault-DoISxaKO.js';
8
8
 
9
9
  interface SessionStoreOptions {
@@ -1,8 +1,8 @@
1
- import { E as EventBus } from './events-DounT6pP.js';
1
+ import { E as EventBus } from './events-AjrvHJ9V.js';
2
2
  import { L as Logger } from './logger-BMQgxvdy.js';
3
3
  import { T as Tracer } from './observability-BhnVLBLS.js';
4
- import { g as Provider, R as Request, a2 as Context, j as Response } from './context-C8mBUzBv.js';
5
- import { R as RetryPolicy } from './retry-policy-DOnwHAyz.js';
4
+ import { i as Provider, R as Request, a5 as Context, l as Response } from './context-BwxhvyW8.js';
5
+ import { R as RetryPolicy } from './retry-policy-mEBn5qpv.js';
6
6
 
7
7
  /**
8
8
  * Options passed to a ProviderRunner when calling the provider.
@@ -1,4 +1,4 @@
1
- import { j as Response, a2 as Context, h as ProviderError } from './context-C8mBUzBv.js';
1
+ import { l as Response, a5 as Context, j as ProviderError } from './context-BwxhvyW8.js';
2
2
 
3
3
  type RecoveryDecision = {
4
4
  /**
@@ -1,7 +1,7 @@
1
1
  import { h as Specification, S as SpecAnalysis, g as SpecValidationResult, l as TaskGraph, m as TaskNode, k as TaskFilter, p as TaskSort, o as TaskProgress, r as TaskType, n as TaskPriority, e as SpecStatus, f as SpecTemplate, b as SpecRequirement } from '../task-graph-D1YQbpxF.js';
2
- import { E as EventBus } from '../events-DounT6pP.js';
3
- import { D as DoneCondition } from '../multi-agent-Iy8YUe3v.js';
4
- import '../context-C8mBUzBv.js';
2
+ import { E as EventBus } from '../events-AjrvHJ9V.js';
3
+ import { D as DoneCondition } from '../multi-agent-DenFfUv5.js';
4
+ import '../context-BwxhvyW8.js';
5
5
 
6
6
  declare class SpecParser {
7
7
  parse(content: string): Specification;
@@ -1,5 +1,5 @@
1
1
  import { S as SecretVault } from './secret-vault-DoISxaKO.js';
2
- import { S as SecretScrubber } from './secret-scrubber-C9UJxFCJ.js';
2
+ import { S as SecretScrubber } from './secret-scrubber-bZ5AyhwJ.js';
3
3
 
4
4
  interface SecretVaultOptions {
5
5
  /** Absolute path to the key file. Created with mode 0o600 if missing. */
@@ -1,4 +1,4 @@
1
- import { v as Tool, a2 as Context, P as Permission } from './context-C8mBUzBv.js';
1
+ import { x as Tool, a5 as Context, P as Permission } from './context-BwxhvyW8.js';
2
2
 
3
3
  interface TrustPolicy {
4
4
  [toolNameOrPattern: string]: {
@@ -1,7 +1,7 @@
1
- export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-scrubber-DcTK9JHC.js';
2
- import { v as Tool, a2 as Context } from '../context-C8mBUzBv.js';
1
+ export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-scrubber-BmiGszvl.js';
2
+ import { x as Tool, a5 as Context } from '../context-BwxhvyW8.js';
3
3
  import { I as InputReader } from '../input-reader-E-ffP2ee.js';
4
- import { a as PermissionPolicy, P as PermissionDecision } from '../secret-scrubber-C9UJxFCJ.js';
4
+ import { a as PermissionPolicy, P as PermissionDecision } from '../secret-scrubber-bZ5AyhwJ.js';
5
5
  import '../secret-vault-DoISxaKO.js';
6
6
 
7
7
  interface PermissionPolicyOptions {
@@ -1,4 +1,4 @@
1
- import { M as Message } from './context-C8mBUzBv.js';
1
+ import { M as Message } from './context-BwxhvyW8.js';
2
2
 
3
3
  /**
4
4
  * Result of LLM-driven message importance analysis.
@@ -1,4 +1,4 @@
1
- import { b as ContentBlock, n as SessionEvent, o as SessionMetadata, p as SessionStore } from './context-C8mBUzBv.js';
1
+ import { b as ContentBlock, p as SessionEvent, q as SessionMetadata, r as SessionStore } from './context-BwxhvyW8.js';
2
2
 
3
3
  type AttachmentKind = 'text' | 'image' | 'file';
4
4
  interface AttachmentMeta {
@@ -1,13 +1,13 @@
1
- export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, M as MemoryStoreOptions, j as MigrationContext, k as MigrationResult, P as PersistedQueueItem, l as PlanFile, m as PlanItem, n as PlanTemplate, Q as QueueStore, R as RecoveryLock, o as RecoveryLockOptions, S as SessionAnalyzer, p as SessionStoreOptions, T as TodosCheckpointFile, q as addPlanItem, r as attachPlanCheckpoint, s as attachTodosCheckpoint, t as clearPlan, u as deriveTodosFromPlanItem, v as emptyPlan, w as formatPlan, x as formatPlanTemplates, y as getPlanTemplate, z as listPlanTemplates, B as loadPlan, E as loadTodosCheckpoint, F as removePlanItem, G as runConfigMigrations, H as savePlan, I as saveTodosCheckpoint, J as setPlanItemStatus } from '../plan-templates-CG_pInJV.js';
2
- export { D as DefaultSessionReader } from '../session-reader-BXWxFAhS.js';
1
+ export { A as AbandonedSession, a as AttachmentStoreOptions, C as ConfigLoaderOptions, b as ConfigMigration, c as ConfigMigrationError, d as ConfigSource, D as DEFAULT_CONFIG_MIGRATIONS, e as DefaultAttachmentStore, f as DefaultConfigLoader, g as DefaultConfigStore, h as DefaultMemoryStore, i as DefaultSessionStore, M as MemoryStoreOptions, j as MigrationContext, k as MigrationResult, P as PersistedQueueItem, l as PlanFile, m as PlanItem, n as PlanTemplate, Q as QueueStore, R as RecoveryLock, o as RecoveryLockOptions, S as SessionAnalyzer, p as SessionStoreOptions, T as TodosCheckpointFile, q as addPlanItem, r as attachPlanCheckpoint, s as attachTodosCheckpoint, t as clearPlan, u as deriveTodosFromPlanItem, v as emptyPlan, w as formatPlan, x as formatPlanTemplates, y as getPlanTemplate, z as listPlanTemplates, B as loadPlan, E as loadTodosCheckpoint, F as removePlanItem, G as runConfigMigrations, H as savePlan, I as saveTodosCheckpoint, J as setPlanItemStatus } from '../plan-templates-CNY6f82B.js';
2
+ export { D as DefaultSessionReader } from '../session-reader-g-FKCyBw.js';
3
3
  import { S as SessionRewinder, C as CheckpointInfo, a as RewindResultExtended } from '../session-rewinder-C9HnMkhP.js';
4
- export { D as DirectorStateCheckpoint, a as DirectorStateSnapshot, b as DirectorSubagentState, c as DirectorTaskState, l as loadDirectorState } from '../director-state-BmYi3DGA.js';
4
+ export { a as DirectorStateCheckpoint, D as DirectorStateSnapshot, b as DirectorSubagentState, c as DirectorTaskState, l as loadDirectorState } from '../director-state-BUB7JRUr.js';
5
5
  export { G as GoalFile, J as JournalEntry, M as MAX_JOURNAL_ENTRIES, a as appendJournal, e as emptyGoal, f as formatGoal, g as goalFilePath, l as loadGoal, s as saveGoal, b as summarizeUsage } from '../goal-store-HHgaq5ue.js';
6
- import '../events-DounT6pP.js';
7
- import '../context-C8mBUzBv.js';
6
+ import '../events-AjrvHJ9V.js';
7
+ import '../context-BwxhvyW8.js';
8
8
  import '../memory-CEXuo7sz.js';
9
9
  import '../wstack-paths-86YPFktR.js';
10
- import '../config-BHkYGzUT.js';
10
+ import '../config-BXAhlqJb.js';
11
11
  import '../models-registry-Y2xbog0E.js';
12
12
  import '../secret-vault-DoISxaKO.js';
13
13
 
@@ -199,8 +199,16 @@ var DefaultSessionStore = class {
199
199
  }
200
200
  }
201
201
  async resume(id) {
202
- const data = await this.load(id);
203
202
  const file = path2.join(this.dir, `${id}.jsonl`);
203
+ try {
204
+ await fsp.access(file, fsp.constants.R_OK);
205
+ } catch {
206
+ throw new Error(
207
+ `Session "${id}" not found \u2014 the session file does not exist or was deleted.`,
208
+ { cause: new Error("ENOENT") }
209
+ );
210
+ }
211
+ const data = await this.load(id);
204
212
  let handle;
205
213
  try {
206
214
  handle = await fsp.open(file, "a", 384);
@@ -1145,6 +1153,20 @@ function safeParse(input, maxBytes = 5e6) {
1145
1153
  }
1146
1154
  }
1147
1155
 
1156
+ // src/types/default-config.ts
1157
+ var DEFAULT_TOOLS_CONFIG = Object.freeze({
1158
+ defaultExecutionStrategy: "smart",
1159
+ maxIterations: 100,
1160
+ iterationTimeoutMs: 3e5,
1161
+ sessionTimeoutMs: 18e5,
1162
+ perIterationOutputCapBytes: 1e5,
1163
+ autoExtendLimit: true
1164
+ });
1165
+ var DEFAULT_CONTEXT_CONFIG = Object.freeze({
1166
+ preserveK: 10,
1167
+ eliseThreshold: 2e3
1168
+ });
1169
+
1148
1170
  // src/storage/config-loader.ts
1149
1171
  var BEHAVIOR_DEFAULTS = {
1150
1172
  version: 1,
@@ -1154,16 +1176,16 @@ var BEHAVIOR_DEFAULTS = {
1154
1176
  softThreshold: 0.75,
1155
1177
  hardThreshold: 0.9,
1156
1178
  autoCompact: true,
1157
- preserveK: 10,
1158
- eliseThreshold: 2e3
1179
+ preserveK: DEFAULT_CONTEXT_CONFIG.preserveK,
1180
+ eliseThreshold: DEFAULT_CONTEXT_CONFIG.eliseThreshold
1159
1181
  },
1160
1182
  tools: {
1161
- defaultExecutionStrategy: "smart",
1162
- maxIterations: 100,
1163
- iterationTimeoutMs: 3e5,
1164
- sessionTimeoutMs: 18e5,
1165
- perIterationOutputCapBytes: 1e5,
1166
- autoExtendLimit: true
1183
+ defaultExecutionStrategy: DEFAULT_TOOLS_CONFIG.defaultExecutionStrategy,
1184
+ maxIterations: DEFAULT_TOOLS_CONFIG.maxIterations,
1185
+ iterationTimeoutMs: DEFAULT_TOOLS_CONFIG.iterationTimeoutMs,
1186
+ sessionTimeoutMs: DEFAULT_TOOLS_CONFIG.sessionTimeoutMs,
1187
+ perIterationOutputCapBytes: DEFAULT_TOOLS_CONFIG.perIterationOutputCapBytes,
1188
+ autoExtendLimit: DEFAULT_TOOLS_CONFIG.autoExtendLimit
1167
1189
  },
1168
1190
  log: { level: "info" },
1169
1191
  features: {
@@ -1177,19 +1199,23 @@ var BEHAVIOR_DEFAULTS = {
1177
1199
  var ENV_MAP = {
1178
1200
  WRONGSTACK_PROVIDER: (c, v) => {
1179
1201
  c.provider = v;
1180
- (c._envSource ??= /* @__PURE__ */ new Set()).add("provider");
1202
+ if (c._envSource === void 0) c._envSource = /* @__PURE__ */ new Set();
1203
+ c._envSource.add("provider");
1181
1204
  },
1182
1205
  WRONGSTACK_MODEL: (c, v) => {
1183
1206
  c.model = v;
1184
- (c._envSource ??= /* @__PURE__ */ new Set()).add("model");
1207
+ if (c._envSource === void 0) c._envSource = /* @__PURE__ */ new Set();
1208
+ c._envSource.add("model");
1185
1209
  },
1186
1210
  WRONGSTACK_API_KEY: (c, v) => {
1187
1211
  c.apiKey = v;
1188
- (c._envSource ??= /* @__PURE__ */ new Set()).add("apiKey");
1212
+ if (c._envSource === void 0) c._envSource = /* @__PURE__ */ new Set();
1213
+ c._envSource.add("apiKey");
1189
1214
  },
1190
1215
  WRONGSTACK_BASE_URL: (c, v) => {
1191
1216
  c.baseUrl = v;
1192
- (c._envSource ??= /* @__PURE__ */ new Set()).add("baseUrl");
1217
+ if (c._envSource === void 0) c._envSource = /* @__PURE__ */ new Set();
1218
+ c._envSource.add("baseUrl");
1193
1219
  },
1194
1220
  WRONGSTACK_LOG_LEVEL: (c, v) => {
1195
1221
  if (!c.log) c.log = { level: "info" };
@@ -2552,6 +2578,58 @@ var DirectorStateCheckpoint = class {
2552
2578
  }
2553
2579
  }
2554
2580
  };
2581
+
2582
+ // src/types/errors.ts
2583
+ var ERROR_CODES = {
2584
+ // File system
2585
+ FS_READ_FAILED: "FS_READ_FAILED",
2586
+ FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED"};
2587
+ var WrongStackError = class extends Error {
2588
+ code;
2589
+ subsystem;
2590
+ severity;
2591
+ recoverable;
2592
+ context;
2593
+ constructor(opts) {
2594
+ super(opts.message, { cause: opts.cause });
2595
+ this.name = "WrongStackError";
2596
+ this.code = opts.code;
2597
+ this.subsystem = opts.subsystem;
2598
+ this.severity = opts.severity ?? "error";
2599
+ this.recoverable = opts.recoverable ?? false;
2600
+ this.context = opts.context;
2601
+ }
2602
+ /**
2603
+ * Render a one-line user-facing description.
2604
+ * Subclasses should override for domain-specific formatting.
2605
+ */
2606
+ describe() {
2607
+ const ctx = this.context ? ` ${formatContext(this.context)}` : "";
2608
+ return `${this.code}: ${this.message}${ctx}`;
2609
+ }
2610
+ };
2611
+ function formatContext(ctx) {
2612
+ const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
2613
+ return parts.length > 0 ? `[${parts.join(" ")}]` : "";
2614
+ }
2615
+ var FsError = class extends WrongStackError {
2616
+ path;
2617
+ constructor(opts) {
2618
+ super({
2619
+ message: opts.message,
2620
+ code: opts.code,
2621
+ subsystem: "fs",
2622
+ severity: "error",
2623
+ recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,
2624
+ context: { path: opts.path, ...opts.context },
2625
+ cause: opts.cause
2626
+ });
2627
+ this.name = "FsError";
2628
+ this.path = opts.path;
2629
+ }
2630
+ };
2631
+
2632
+ // src/storage/goal-store.ts
2555
2633
  var MAX_JOURNAL_ENTRIES = 500;
2556
2634
  function goalFilePath(projectRoot) {
2557
2635
  return path2.join(projectRoot, ".wrongstack", "goal.json");
@@ -2574,7 +2652,16 @@ async function loadGoal(filePath) {
2574
2652
  }
2575
2653
  }
2576
2654
  async function saveGoal(filePath, goal) {
2577
- await atomicWrite(filePath, JSON.stringify(goal, null, 2), { mode: 384 });
2655
+ try {
2656
+ await atomicWrite(filePath, JSON.stringify(goal, null, 2), { mode: 384 });
2657
+ } catch (err) {
2658
+ throw new FsError({
2659
+ message: err instanceof Error ? err.message : String(err),
2660
+ code: ERROR_CODES.FS_ATOMIC_WRITE_FAILED,
2661
+ path: filePath,
2662
+ cause: err
2663
+ });
2664
+ }
2578
2665
  }
2579
2666
  function emptyGoal(goal) {
2580
2667
  const now = (/* @__PURE__ */ new Date()).toISOString();