@wrongstack/core 0.155.0 → 0.236.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 (81) hide show
  1. package/dist/{agent-bridge-BbZU5TPN.d.ts → agent-bridge-Cimv7bK7.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-Bsueu0J2.d.ts → agent-subagent-runner-C658wj_c.d.ts} +9 -8
  3. package/dist/{brain-CS_B0vIE.d.ts → brain-sCZ3lCjq.d.ts} +26 -2
  4. package/dist/{compactor-BueGt7LG.d.ts → compactor-BRfg3QPd.d.ts} +1 -1
  5. package/dist/{config-BaVThgnT.d.ts → config-Koq6f3fs.d.ts} +2 -2
  6. package/dist/{context-C7G_MtLV.d.ts → context-CLz3z_E8.d.ts} +126 -2
  7. package/dist/coordination/index.d.ts +70 -13
  8. package/dist/coordination/index.js +1983 -145
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +26 -26
  11. package/dist/defaults/index.js +1105 -289
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/execution/index.d.ts +45 -16
  14. package/dist/execution/index.js +224 -53
  15. package/dist/execution/index.js.map +1 -1
  16. package/dist/execution/prompt-enhancer.d.ts +86 -0
  17. package/dist/execution/prompt-enhancer.js +125 -0
  18. package/dist/execution/prompt-enhancer.js.map +1 -0
  19. package/dist/extension/index.d.ts +6 -6
  20. package/dist/extension/index.js +3 -1
  21. package/dist/extension/index.js.map +1 -1
  22. package/dist/{goal-preamble-CbV8pXLD.d.ts → goal-preamble-CnbzyVvl.d.ts} +19 -10
  23. package/dist/{index-CI1hRfPt.d.ts → index-BlMqh5GO.d.ts} +8 -8
  24. package/dist/{index-B5wz-GXm.d.ts → index-C2eSNPsB.d.ts} +7 -5
  25. package/dist/index.d.ts +438 -128
  26. package/dist/index.js +4974 -836
  27. package/dist/index.js.map +1 -1
  28. package/dist/infrastructure/index.d.ts +7 -7
  29. package/dist/infrastructure/index.js +61 -13
  30. package/dist/infrastructure/index.js.map +1 -1
  31. package/dist/kernel/index.d.ts +9 -9
  32. package/dist/kernel/index.js +7 -1
  33. package/dist/kernel/index.js.map +1 -1
  34. package/dist/{llm-selector-CP72f1lC.d.ts → llm-selector-D22R4AFz.d.ts} +2 -2
  35. package/dist/logger-DmmQhf4P.d.ts +65 -0
  36. package/dist/{mcp-servers-CPERR2De.d.ts → mcp-servers-DFbirBv6.d.ts} +3 -3
  37. package/dist/models/index.d.ts +5 -5
  38. package/dist/models/index.js +89 -9
  39. package/dist/models/index.js.map +1 -1
  40. package/dist/{models-registry-D90K9UnM.d.ts → models-registry-CnJRjTXc.d.ts} +1 -1
  41. package/dist/{multi-agent-coordinator-BSKSFNhv.d.ts → multi-agent-coordinator-60weDZoA.d.ts} +8 -8
  42. package/dist/{null-fleet-bus-CGOez8Le.d.ts → null-fleet-bus-1068dEnr.d.ts} +7 -7
  43. package/dist/observability/index.d.ts +2 -2
  44. package/dist/package-outdated-watcher-pzJ5w7y8.d.ts +560 -0
  45. package/dist/{parallel-eternal-engine-CYoTKjsz.d.ts → parallel-eternal-engine-DtG1fjc9.d.ts} +13 -9
  46. package/dist/{path-resolver-DuhlmPil.d.ts → path-resolver-CA1ULU0J.d.ts} +3 -3
  47. package/dist/{permission-B7nKnEvQ.d.ts → permission-DbWPbuoA.d.ts} +1 -1
  48. package/dist/{permission-policy-8-6zBmfA.d.ts → permission-policy-AOk0LVsV.d.ts} +2 -2
  49. package/dist/pipeline-DsmlwTXu.d.ts +493 -0
  50. package/dist/{plan-templates-DbH7lg-t.d.ts → plan-templates-DPABrDvy.d.ts} +18 -7
  51. package/dist/{provider-runner-Cocq0O9E.d.ts → provider-runner-D0HgUqwV.d.ts} +3 -3
  52. package/dist/{retry-policy-rutAfVeR.d.ts → retry-policy-BVnkbMET.d.ts} +1 -1
  53. package/dist/sdd/index.d.ts +8 -8
  54. package/dist/sdd/index.js +215 -79
  55. package/dist/sdd/index.js.map +1 -1
  56. package/dist/{secret-vault-w8MbUe2Q.d.ts → secret-vault-CeVNiy_f.d.ts} +3 -2
  57. package/dist/security/index.d.ts +5 -4
  58. package/dist/security/index.js +155 -13
  59. package/dist/security/index.js.map +1 -1
  60. package/dist/{selector-4vDFZKt3.d.ts → selector-Cb4_9-hf.d.ts} +1 -1
  61. package/dist/{session-event-bridge-DWlvglC2.d.ts → session-event-bridge-BhtkkFFy.d.ts} +4 -2
  62. package/dist/{session-reader-BAtCxdaw.d.ts → session-reader-CCOssnBS.d.ts} +1 -1
  63. package/dist/skills/index.js +171 -21
  64. package/dist/skills/index.js.map +1 -1
  65. package/dist/storage/index.d.ts +150 -12
  66. package/dist/storage/index.js +1041 -214
  67. package/dist/storage/index.js.map +1 -1
  68. package/dist/types/index.d.ts +67 -20
  69. package/dist/types/index.js +557 -52
  70. package/dist/types/index.js.map +1 -1
  71. package/dist/utils/expect-defined.js +3 -1
  72. package/dist/utils/expect-defined.js.map +1 -1
  73. package/dist/utils/index.d.ts +16 -4
  74. package/dist/utils/index.js +40 -14
  75. package/dist/utils/index.js.map +1 -1
  76. package/dist/{wstack-paths-DD50Omgn.d.ts → wstack-paths-CJjEwPXn.d.ts} +14 -1
  77. package/package.json +7 -3
  78. package/skills/chimera/SKILL.md +105 -0
  79. package/skills/research-web/SKILL.md +342 -0
  80. package/dist/logger-B9J5puGM.d.ts +0 -32
  81. package/dist/pipeline-BG7UgbDc.d.ts +0 -239
@@ -1,23 +1,23 @@
1
- export { C as CompactorOptions, D as DefaultErrorHandler, a as DefaultRetryPolicy, E as EternalAutonomyEngine, b as EternalAutonomyOptions, c as EternalEngineState, H as HybridCompactor, I as IterationStage, P as ParallelEngineState, d as ParallelEternalEngine, e as ParallelEternalOptions, f as ParallelIterationStage, T as ToolExecutor } from '../parallel-eternal-engine-CYoTKjsz.js';
2
- export { A as AutoCompactionMiddleware, a as AutonomousRunner, b as AutonomousRunnerOptions, c as AutonomyPromptContributorOptions, C as CompactorStrategy, D as DefaultSkillLoader, d as DoneCheckResult, e as DoneConditionChecker, I as IntelligentCompactor, f as IntelligentCompactorOptions, S as SelectiveCompactor, g as SelectiveCompactorOptions, h as SkillLoaderOptions, i as StrategyCompactorOptions, j as buildGoalPreamble, k as createStrategyCompactor, m as makeAutonomyPromptContributor } from '../goal-preamble-CbV8pXLD.js';
3
- import { P as Provider } from '../context-C7G_MtLV.js';
4
- import { B as BrainDecision, a as BrainDecisionRequest, b as BrainArbiter } from '../brain-CS_B0vIE.js';
5
- import '../retry-policy-rutAfVeR.js';
6
- import '../compactor-BueGt7LG.js';
7
- import '../config-BaVThgnT.js';
8
- import '../index-B5wz-GXm.js';
1
+ export { C as CompactorOptions, a as DefaultErrorHandler, b as DefaultRetryPolicy, E as EternalAutonomyEngine, c as EternalAutonomyOptions, d as EternalEngineState, H as HybridCompactor, I as IterationStage, P as ParallelEngineState, e as ParallelEternalEngine, f as ParallelEternalOptions, g as ParallelIterationStage, T as ToolExecutor } from '../parallel-eternal-engine-DtG1fjc9.js';
2
+ export { A as AutoCompactionMiddleware, a as AutonomousRunner, b as AutonomousRunnerOptions, c as AutonomyPromptContributorOptions, C as CompactorStrategy, D as DefaultSkillLoader, d as DoneCheckResult, e as DoneConditionChecker, I as IntelligentCompactor, f as IntelligentCompactorOptions, S as SelectiveCompactor, g as SelectiveCompactorOptions, h as SkillLoaderOptions, i as StrategyCompactorOptions, j as buildGoalPreamble, k as createStrategyCompactor, m as makeAutonomyPromptContributor } from '../goal-preamble-CnbzyVvl.js';
3
+ import { P as Provider } from '../context-CLz3z_E8.js';
4
+ import { b as BrainDecision, e as BrainDecisionRequest, B as BrainArbiter } from '../brain-sCZ3lCjq.js';
5
+ import '../retry-policy-BVnkbMET.js';
6
+ import '../compactor-BRfg3QPd.js';
7
+ import '../config-Koq6f3fs.js';
8
+ import '../index-C2eSNPsB.js';
9
9
  import '../logger-B63L5bTg.js';
10
- import '../pipeline-BG7UgbDc.js';
10
+ import '../pipeline-DsmlwTXu.js';
11
11
  import '../observability-D-HZN_mF.js';
12
- import '../permission-B7nKnEvQ.js';
13
- import '../agent-subagent-runner-Bsueu0J2.js';
12
+ import '../permission-DbWPbuoA.js';
13
+ import '../agent-subagent-runner-C658wj_c.js';
14
14
  import '../goal-store-CV9Yz2X_.js';
15
- import '../multi-agent-coordinator-BSKSFNhv.js';
15
+ import '../multi-agent-coordinator-60weDZoA.js';
16
16
  import 'node:events';
17
17
  import '../skill-Bj6Ezqb8.js';
18
- import '../wstack-paths-DD50Omgn.js';
19
- import '../selector-4vDFZKt3.js';
20
- import '../session-event-bridge-DWlvglC2.js';
18
+ import '../wstack-paths-CJjEwPXn.js';
19
+ import '../selector-Cb4_9-hf.js';
20
+ import '../session-event-bridge-BhtkkFFy.js';
21
21
 
22
22
  /**
23
23
  * AutonomyBrain — a self-driving decision layer for autonomous workflows.
@@ -69,6 +69,35 @@ interface AutonomyBrainOptions {
69
69
  */
70
70
  onDecision?: ((summary: string, decision: BrainDecision, request: BrainDecisionRequest) => void) | undefined;
71
71
  }
72
+ /** Runtime-adjustable autonomy ceiling for the tiered brain. */
73
+ type BrainAutoRisk = 'off' | 'low' | 'medium' | 'high' | 'all';
74
+ interface TieredBrainArbiterOptions {
75
+ /** Fast deterministic policy layer (DefaultBrainArbiter). Consulted first. */
76
+ policy: BrainArbiter;
77
+ /** LLM-backed autonomous layer (createAutonomyBrain). Consulted when the
78
+ * policy layer would escalate to the human and the request's risk is
79
+ * within the live ceiling. */
80
+ autonomous?: BrainArbiter | undefined;
81
+ /**
82
+ * Live autonomy ceiling — read on EVERY decision so `/brain risk <level>`
83
+ * changes take effect immediately. 'off' disables the autonomous layer
84
+ * entirely (everything the policy can't answer goes to the human).
85
+ */
86
+ getMaxAutoRisk?: (() => BrainAutoRisk) | undefined;
87
+ }
88
+ /**
89
+ * The standard Brain positioning: policy first, LLM second, human last.
90
+ *
91
+ * 1. POLICY — deterministic DefaultBrainArbiter (low-risk fast path,
92
+ * fallback semantics). Answers and denies pass through untouched.
93
+ * 2. LLM — when the policy says `ask_human` and the request's risk is
94
+ * within the live ceiling, the autonomous brain gets a chance to
95
+ * answer. Only a real `answer` short-circuits; LLM denials/failures
96
+ * fall through.
97
+ * 3. HUMAN — anything left escalates (callers wrap this in
98
+ * HumanEscalatingBrainArbiter so `ask_human` becomes a real prompt).
99
+ */
100
+ declare function createTieredBrainArbiter(opts: TieredBrainArbiterOptions): BrainArbiter;
72
101
  /**
73
102
  * Create a self-driving brain that makes autonomous decisions.
74
103
  * Never asks the human — within its risk boundary it answers, above it denies.
@@ -79,4 +108,4 @@ declare function createAutonomyBrain(opts: AutonomyBrainOptions): BrainArbiter;
79
108
  */
80
109
  declare function formatDecisionSummary(decision: BrainDecision, request: BrainDecisionRequest): string;
81
110
 
82
- export { type AutonomyBrainOptions, createAutonomyBrain, formatDecisionSummary };
111
+ export { type AutonomyBrainOptions, type BrainAutoRisk, type TieredBrainArbiterOptions, createAutonomyBrain, createTieredBrainArbiter, formatDecisionSummary };
@@ -9,7 +9,9 @@ import { EventEmitter } from 'events';
9
9
  // src/utils/expect-defined.ts
10
10
  function expectDefined(value, label) {
11
11
  if (value === null || value === void 0) {
12
- throw new Error("Expected value to be defined");
12
+ const err = new Error("Expected value to be defined");
13
+ err.name = "ExpectDefinedError";
14
+ throw err;
13
15
  }
14
16
  return value;
15
17
  }
@@ -58,22 +60,31 @@ function estimateToolResultTokens(content) {
58
60
  function estimateTextTokens(text) {
59
61
  return RoughTokenEstimate(text);
60
62
  }
63
+ function computeMessageTokens(msg) {
64
+ if (typeof msg.content === "string") return estimateTextTokens(msg.content);
65
+ let total = 0;
66
+ for (const b of msg.content) {
67
+ if (b.type === "text") total += estimateTextTokens(b.text);
68
+ else if (b.type === "tool_use") total += estimateToolInputTokens(b.input);
69
+ else if (b.type === "tool_result") total += estimateToolResultTokens(b.content);
70
+ else total += RoughTokenEstimate(JSON.stringify(b));
71
+ }
72
+ return total;
73
+ }
61
74
  function estimateMessageTokens(messages) {
62
75
  let total = 0;
63
76
  for (const m of messages) {
64
- if (typeof m.content === "string") {
65
- total += estimateTextTokens(m.content);
66
- } else {
67
- for (const b of m.content) {
68
- if (b.type === "text") total += estimateTextTokens(b.text);
69
- else if (b.type === "tool_use") total += estimateToolInputTokens(b.input);
70
- else if (b.type === "tool_result") total += estimateToolResultTokens(b.content);
71
- }
77
+ if (typeof m._estTokens === "number" && m._estTokens > 0) {
78
+ total += m._estTokens;
79
+ continue;
72
80
  }
81
+ total += computeMessageTokens(m);
73
82
  }
74
83
  return total;
75
84
  }
76
85
  function estimateToolDefTokens(tool) {
86
+ const cached = tool._estDefTokens;
87
+ if (typeof cached === "number" && cached > 0) return cached;
77
88
  return RoughTokenEstimate(tool.name) + RoughTokenEstimate(tool.description ?? "") + RoughTokenEstimate(JSON.stringify(tool.inputSchema));
78
89
  }
79
90
  function estimateRequestTokens(messages, systemPrompt, tools, calibrationKey = CALIBRATION_GLOBAL_KEY) {
@@ -83,6 +94,11 @@ function estimateRequestTokens(messages, systemPrompt, tools, calibrationKey = C
83
94
  } else if (Array.isArray(messages)) {
84
95
  for (const m of messages) {
85
96
  if (typeof m === "object" && m !== null && "content" in m) {
97
+ const cached = m._estTokens;
98
+ if (typeof cached === "number" && cached > 0) {
99
+ messagesTokens += cached;
100
+ continue;
101
+ }
86
102
  const content = m.content;
87
103
  if (typeof content === "string") {
88
104
  messagesTokens += RoughTokenEstimate(content);
@@ -267,6 +283,18 @@ function findPreserveStart(messages, preserveK) {
267
283
  }
268
284
  function eliseOldToolResults(messages, opts) {
269
285
  const preserveStart = findPreserveStart(messages, opts.preserveK);
286
+ let hasOversized = false;
287
+ for (let i = 0; i < preserveStart && !hasOversized; i++) {
288
+ const msg = messages[i];
289
+ if (!msg || !Array.isArray(msg.content)) continue;
290
+ for (const b of msg.content) {
291
+ if (b.type === "tool_result" && estimateToolResultTokens(b.content) >= opts.eliseThreshold) {
292
+ hasOversized = true;
293
+ break;
294
+ }
295
+ }
296
+ }
297
+ if (!hasOversized) return { messages, saved: 0, changed: false };
270
298
  let saved = 0;
271
299
  let changed = false;
272
300
  const next = new Array(messages.length);
@@ -1245,6 +1273,15 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
1245
1273
  static NOOP_RETRY_DELTA_TOKENS = 2e3;
1246
1274
  /** Tracks the most recent no-op attempt so we can avoid re-firing per turn. */
1247
1275
  lastNoopAttempt = null;
1276
+ /**
1277
+ * Cached token estimate from the last handler() invocation. When the
1278
+ * message count and tool count haven't changed since the last estimate
1279
+ * (autonomous idle loops), we skip the expensive O(n) token estimation
1280
+ * and reuse this value. Reset to -1 when the context changes.
1281
+ */
1282
+ _cachedTokens = -1;
1283
+ _cachedMsgCount = -1;
1284
+ _cachedToolCount = -1;
1248
1285
  /**
1249
1286
  * @param compactor Compactor to use for compaction.
1250
1287
  * @param maxContext Provider's max context window in tokens.
@@ -1280,12 +1317,24 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
1280
1317
  }
1281
1318
  handler() {
1282
1319
  return async (ctx, next) => {
1283
- const tokens = this._estimator ? this._estimator(ctx) : estimateRequestTokensCalibrated(
1284
- ctx.messages,
1285
- ctx.systemPrompt,
1286
- ctx.tools ?? [],
1287
- `${ctx.provider?.id ?? "unknown"}/${ctx.model}`
1288
- ).total;
1320
+ const msgCount = ctx.messages.length;
1321
+ const toolCount = (ctx.tools ?? []).length;
1322
+ let tokens;
1323
+ if (this._estimator) {
1324
+ tokens = this._estimator(ctx);
1325
+ } else if (msgCount === this._cachedMsgCount && toolCount === this._cachedToolCount && this._cachedTokens >= 0) {
1326
+ tokens = this._cachedTokens;
1327
+ } else {
1328
+ tokens = estimateRequestTokensCalibrated(
1329
+ ctx.messages,
1330
+ ctx.systemPrompt,
1331
+ ctx.tools ?? [],
1332
+ `${ctx.provider?.id ?? "unknown"}/${ctx.model}`
1333
+ ).total;
1334
+ this._cachedTokens = tokens;
1335
+ this._cachedMsgCount = msgCount;
1336
+ this._cachedToolCount = toolCount;
1337
+ }
1289
1338
  const load = tokens / this._maxContext;
1290
1339
  const policy = this.policyProvider?.(ctx);
1291
1340
  const thresholds = policy?.thresholds ?? {
@@ -1566,7 +1615,7 @@ function createToolOutputSerializer(opts = {}) {
1566
1615
  }
1567
1616
 
1568
1617
  // src/execution/tool-executor.ts
1569
- var ToolExecutor = class {
1618
+ var ToolExecutor = class _ToolExecutor {
1570
1619
  constructor(registry, opts) {
1571
1620
  this.registry = registry;
1572
1621
  this.opts = opts;
@@ -1578,6 +1627,10 @@ var ToolExecutor = class {
1578
1627
  }
1579
1628
  registry;
1580
1629
  opts;
1630
+ /** Minimum gap between coalesced `partial_output` tool.progress emits. */
1631
+ static PROGRESS_EMIT_INTERVAL_MS = 100;
1632
+ /** Max chars of accumulated stream text carried per coalesced emit. */
1633
+ static PROGRESS_TAIL_CHARS = 16384;
1581
1634
  serializer;
1582
1635
  iterationTimeoutMs;
1583
1636
  maxToolTimeoutMs;
@@ -1623,9 +1676,6 @@ Please call the tool again with arguments that match its inputSchema. You can us
1623
1676
  return { result, tool, durationMs: Date.now() - start };
1624
1677
  }
1625
1678
  const toolDangerousCaps = getDangerousCapabilities(tool);
1626
- if (toolDangerousCaps.length > 0) {
1627
- if (this.opts.events) ;
1628
- }
1629
1679
  if (hasMalformedArguments(use.input)) {
1630
1680
  const result = this.malformedInputResult(use, extractMalformedRaw(use.input));
1631
1681
  budget = this.decrementBudget(result, budget);
@@ -1863,17 +1913,48 @@ ${post.additionalContext}` };
1863
1913
  throw new Error(`Tool "${tool.name}" does not support streaming execution`);
1864
1914
  }
1865
1915
  const stream = tool.executeStream(input, ctx, { signal });
1866
- for await (const ev of stream) {
1867
- if (ev.type === "final") {
1868
- finalOutput = ev.output;
1869
- sawFinal = true;
1870
- break;
1871
- }
1916
+ const iter = stream[Symbol.asyncIterator]();
1917
+ let progressTail = "";
1918
+ let lastProgressEmitAt = 0;
1919
+ const emitProgress = (ev) => {
1872
1920
  this.opts.events?.emit("tool.progress", {
1873
1921
  name: tool.name,
1874
1922
  id: toolUseId ?? "<unknown>",
1875
1923
  event: ev
1876
1924
  });
1925
+ };
1926
+ const flushProgressTail = (force) => {
1927
+ if (progressTail.length === 0) return;
1928
+ const now = Date.now();
1929
+ if (!force && now - lastProgressEmitAt < _ToolExecutor.PROGRESS_EMIT_INTERVAL_MS) return;
1930
+ const text = progressTail;
1931
+ progressTail = "";
1932
+ lastProgressEmitAt = now;
1933
+ emitProgress({ type: "partial_output", text });
1934
+ };
1935
+ try {
1936
+ while (true) {
1937
+ const { done, value: ev } = await iter.next();
1938
+ if (done) break;
1939
+ if (ev.type === "final") {
1940
+ finalOutput = ev.output;
1941
+ sawFinal = true;
1942
+ break;
1943
+ }
1944
+ if (ev.type === "partial_output" && typeof ev.text === "string") {
1945
+ progressTail += ev.text;
1946
+ if (progressTail.length > _ToolExecutor.PROGRESS_TAIL_CHARS) {
1947
+ progressTail = progressTail.slice(-_ToolExecutor.PROGRESS_TAIL_CHARS);
1948
+ }
1949
+ flushProgressTail(false);
1950
+ continue;
1951
+ }
1952
+ flushProgressTail(true);
1953
+ emitProgress(ev);
1954
+ }
1955
+ flushProgressTail(true);
1956
+ } finally {
1957
+ await iter.return?.(void 0);
1877
1958
  }
1878
1959
  if (!sawFinal) {
1879
1960
  throw new Error(`tool "${tool.name}" executeStream completed without a 'final' event`);
@@ -1984,9 +2065,11 @@ function extractMalformedRaw(input) {
1984
2065
 
1985
2066
  // src/utils/assert-never.ts
1986
2067
  function assertNever(x, message) {
1987
- throw new Error(
2068
+ const err = new Error(
1988
2069
  `Unhandled case: ${JSON.stringify(x)}`
1989
2070
  );
2071
+ err.name = "AssertNeverError";
2072
+ throw err;
1990
2073
  }
1991
2074
 
1992
2075
  // src/utils/regex-guard.ts
@@ -2033,7 +2116,13 @@ var DoneConditionChecker = class {
2033
2116
  const result = compileUserRegex(condition.pattern, "");
2034
2117
  this.compiledRegex = result.ok ? result.regex : null;
2035
2118
  if (!result.ok) {
2036
- console.warn(`[DoneConditionChecker] Invalid regex pattern "${condition.pattern}": ${result.reason}`);
2119
+ console.warn(JSON.stringify({
2120
+ level: "warn",
2121
+ event: "autonomous.done_condition_invalid_regex",
2122
+ pattern: condition.pattern,
2123
+ reason: result.reason,
2124
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
2125
+ }));
2037
2126
  }
2038
2127
  } else {
2039
2128
  this.compiledRegex = null;
@@ -2267,9 +2356,13 @@ function projectSlug(absRoot) {
2267
2356
  function slugify(name) {
2268
2357
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40) || "project";
2269
2358
  }
2359
+ function wstackGlobalRoot() {
2360
+ const fromEnv = process.env["WRONGSTACK_HOME"];
2361
+ if (fromEnv && fromEnv.trim().length > 0) return path2.resolve(fromEnv);
2362
+ return path2.join(os.homedir(), ".wrongstack");
2363
+ }
2270
2364
  function resolveWstackPaths(opts) {
2271
- const home = opts.userHome ?? os.homedir();
2272
- const globalRoot = opts.globalRoot ?? path2.join(home, ".wrongstack");
2365
+ const globalRoot = opts.globalRoot ?? (opts.userHome ? path2.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
2273
2366
  const hash = projectHash(opts.projectRoot);
2274
2367
  const slug = projectSlug(opts.projectRoot);
2275
2368
  const projectDir = path2.join(globalRoot, "projects", slug);
@@ -2326,12 +2419,24 @@ async function loadGoal(filePath) {
2326
2419
  try {
2327
2420
  const parsed = JSON.parse(raw);
2328
2421
  if (parsed?.version !== 1 || typeof parsed.goal !== "string" || !Array.isArray(parsed.journal)) {
2329
- console.warn(`[goal-store] Corrupt goal.json at ${filePath} \u2014 invalid schema. Consider deleting it and re-creating.`);
2422
+ console.warn(JSON.stringify({
2423
+ level: "warn",
2424
+ event: "goal_store.invalid_schema",
2425
+ path: filePath,
2426
+ message: "invalid schema \u2014 consider deleting and re-creating",
2427
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
2428
+ }));
2330
2429
  return null;
2331
2430
  }
2332
2431
  return parsed;
2333
2432
  } catch {
2334
- console.warn(`[goal-store] Corrupt goal.json at ${filePath} \u2014 JSON parse failed. Consider deleting it and re-creating.`);
2433
+ console.warn(JSON.stringify({
2434
+ level: "warn",
2435
+ event: "goal_store.parse_failed",
2436
+ path: filePath,
2437
+ message: "JSON parse failed \u2014 consider deleting and re-creating",
2438
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
2439
+ }));
2335
2440
  return null;
2336
2441
  }
2337
2442
  }
@@ -2406,6 +2511,25 @@ var RISK_LEVELS = {
2406
2511
  high: 2,
2407
2512
  critical: 3
2408
2513
  };
2514
+ function createTieredBrainArbiter(opts) {
2515
+ return {
2516
+ async decide(request) {
2517
+ const policyDecision = await opts.policy.decide(request);
2518
+ if (policyDecision.type !== "ask_human") return policyDecision;
2519
+ const ceiling = opts.getMaxAutoRisk?.() ?? "medium";
2520
+ if (!opts.autonomous || ceiling === "off") return policyDecision;
2521
+ const ceilingLevel = ceiling === "all" ? 3 : RISK_LEVELS[ceiling] ?? 1;
2522
+ const requestLevel = RISK_LEVELS[request.risk] ?? 2;
2523
+ if (requestLevel > ceilingLevel) return policyDecision;
2524
+ try {
2525
+ const llmDecision = await opts.autonomous.decide(request);
2526
+ if (llmDecision.type === "answer") return llmDecision;
2527
+ } catch {
2528
+ }
2529
+ return policyDecision;
2530
+ }
2531
+ };
2532
+ }
2409
2533
  function createAutonomyBrain(opts) {
2410
2534
  const maxRisk = opts.maxAutoRisk ?? "high";
2411
2535
  const maxRiskLevel = RISK_LEVELS[maxRisk] ?? 2;
@@ -2612,7 +2736,14 @@ var EternalAutonomyEngine = class {
2612
2736
  stop() {
2613
2737
  this.stopRequested = true;
2614
2738
  this.currentCtrl?.abort();
2615
- void this.persistEngineState("stopped").catch(() => {
2739
+ void this.persistEngineState("stopped").catch((err) => {
2740
+ console.error(JSON.stringify({
2741
+ level: "error",
2742
+ event: "engine.persist_state_failed",
2743
+ message: err instanceof Error ? err.message : String(err),
2744
+ context: { expectedState: "stopped" },
2745
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
2746
+ }));
2616
2747
  });
2617
2748
  this.state = "stopped";
2618
2749
  }
@@ -3728,21 +3859,40 @@ function makeAgentSubagentRunner(opts) {
3728
3859
  if (budgetError) throw budgetError;
3729
3860
  }
3730
3861
  if (result.status === "failed") {
3731
- throw result.error instanceof Error ? result.error : new Error(String(result.error ?? "agent failed"));
3862
+ throw result.error instanceof AgentError ? result.error : new AgentError({
3863
+ message: result.error instanceof Error ? result.error.message : String(result.error ?? "agent failed"),
3864
+ code: ERROR_CODES.AGENT_RUN_FAILED,
3865
+ cause: result.error
3866
+ });
3732
3867
  }
3733
3868
  if (result.status === "aborted") {
3734
- throw new Error("agent aborted");
3869
+ throw new AgentError({
3870
+ message: "agent aborted",
3871
+ code: ERROR_CODES.AGENT_ABORTED
3872
+ });
3735
3873
  }
3736
3874
  if (result.status === "max_iterations") {
3737
- throw new Error("agent exhausted iteration limit");
3875
+ throw new AgentError({
3876
+ message: "agent exhausted iteration limit",
3877
+ code: ERROR_CODES.AGENT_ITERATION_LIMIT,
3878
+ recoverable: true
3879
+ });
3738
3880
  }
3739
3881
  const usage = ctx.budget.usage();
3740
3882
  const finalText = (result.finalText ?? "").trim();
3741
3883
  if (finalText.length === 0 && usage.toolCalls === 0) {
3742
- throw new Error("empty response");
3884
+ throw new AgentError({
3885
+ message: "empty response \u2014 agent produced no text and no tool calls",
3886
+ code: ERROR_CODES.AGENT_RUN_FAILED,
3887
+ context: { iterations: result.iterations }
3888
+ });
3743
3889
  }
3744
3890
  if (finalText.length === 0 && lastToolFailed !== null) {
3745
- throw new Error(`tool failed: ${lastToolFailed}`);
3891
+ throw new AgentError({
3892
+ message: `unrecovered tool failure: ${lastToolFailed} \u2014 agent ended turn without acknowledging the error`,
3893
+ code: ERROR_CODES.AGENT_RUN_FAILED,
3894
+ context: { tool: lastToolFailed, iterations: result.iterations }
3895
+ });
3746
3896
  }
3747
3897
  return {
3748
3898
  result: result.finalText,
@@ -3774,11 +3924,11 @@ var HEAVY_BUDGET = {
3774
3924
  };
3775
3925
  var TOOLS = {
3776
3926
  /** Pure read/inspect — safe for analysis and review agents. */
3777
- read: ["read", "grep", "glob", "search", "tree"],
3927
+ read: ["read", "grep", "glob", "search", "tree", "mailbox"],
3778
3928
  /** Read + structured inspection (logs, diffs, json, dependency audit). */
3779
- inspect: ["read", "grep", "glob", "search", "tree", "json", "diff", "logs", "audit"],
3929
+ inspect: ["read", "grep", "glob", "search", "tree", "json", "diff", "logs", "audit", "mailbox"],
3780
3930
  /** Read + edit (no shell). For agents that write code/docs but don't run it. */
3781
- write: ["read", "grep", "glob", "search", "tree", "write", "edit", "replace", "patch"],
3931
+ write: ["read", "grep", "glob", "search", "tree", "write", "edit", "replace", "patch", "mailbox"],
3782
3932
  /** Full build loop: edit + run (lint/format/typecheck/test/bash). */
3783
3933
  build: [
3784
3934
  "read",
@@ -3795,16 +3945,17 @@ var TOOLS = {
3795
3945
  "lint",
3796
3946
  "format",
3797
3947
  "typecheck",
3798
- "test"
3948
+ "test",
3949
+ "mailbox"
3799
3950
  ],
3800
3951
  /** Version control. */
3801
3952
  vcs: ["read", "grep", "glob", "git", "diff"],
3802
3953
  /** Dependency management + CVE audit. */
3803
- deps: ["read", "grep", "glob", "install", "outdated", "audit", "json"],
3954
+ deps: ["read", "grep", "glob", "install", "outdated", "audit", "json", "mailbox"],
3804
3955
  /** Documentation authoring. */
3805
- docs: ["read", "grep", "glob", "search", "tree", "write", "edit", "document"],
3956
+ docs: ["read", "grep", "glob", "search", "tree", "write", "edit", "document", "mailbox"],
3806
3957
  /** Web research. */
3807
- research: ["read", "grep", "glob", "search", "fetch"]
3958
+ research: ["read", "grep", "glob", "search", "fetch", "mailbox"]
3808
3959
  };
3809
3960
 
3810
3961
  // src/coordination/agents/phase1-discovery.ts
@@ -6217,7 +6368,7 @@ Working rules:
6217
6368
  id: "tech-stack",
6218
6369
  name: "Tech Stack Validator",
6219
6370
  role: "tech-stack",
6220
- tools: ["search", "fetch", "read", "grep", "glob", "outdated", "audit", "json"],
6371
+ tools: ["search", "fetch", "read", "grep", "glob", "outdated", "audit", "json", "mailbox"],
6221
6372
  prompt: `You are the Tech Stack Validator \u2014 a single-shot validation agent that fires
6222
6373
  before any package, library, or framework choice is committed.
6223
6374
 
@@ -6225,6 +6376,16 @@ Your ONLY job: verify that a technology choice is current, real, and not obsolet
6225
6376
  You are the "this isn't code, this is 10-year-old technology" agent. Intervene
6226
6377
  hard when the LLM hallucinates a version number or suggests dead tech.
6227
6378
 
6379
+ ## Before you begin
6380
+
6381
+ Check the inter-agent mailbox for pending tasks. Other agents or the file-watcher
6382
+ may have left assign messages with dependency files to audit:
6383
+ - mailbox action=check
6384
+
6385
+ If you find an assign message, use the specified file path and packages.
6386
+ When done, post results back:
6387
+ - mailbox action=send to=<sender> type=result subject="Tech stack audit results" body="..."
6388
+
6228
6389
  ## Critical rules
6229
6390
 
6230
6391
  1. **Verify existence.** Search npm registry (fetch https://registry.npmjs.org/<pkg>/latest)
@@ -6283,11 +6444,11 @@ When APPROVED:
6283
6444
  **Install**: pnpm add <name>@^<major>.<minor>.0`
6284
6445
  },
6285
6446
  budget: {
6286
- timeoutMs: 6e4,
6287
- maxIterations: 5,
6288
- maxToolCalls: 20,
6289
- maxTokens: 4e4,
6290
- maxCostUsd: 0.1
6447
+ timeoutMs: 12e4,
6448
+ maxIterations: 10,
6449
+ maxToolCalls: 40,
6450
+ maxTokens: 6e4,
6451
+ maxCostUsd: 0.25
6291
6452
  },
6292
6453
  capability: {
6293
6454
  phase: "meta",
@@ -6517,6 +6678,9 @@ function providerStatusToCode(status, type) {
6517
6678
 
6518
6679
  // src/coordination/coordinator/error-classifier.ts
6519
6680
  function classifySubagentError(err, hints = {}) {
6681
+ if (err instanceof AgentError && err.cause) {
6682
+ return classifySubagentError(err.cause, hints);
6683
+ }
6520
6684
  const cause = err instanceof Error ? { name: err.name, message: err.message, stack: err.stack } : void 0;
6521
6685
  if (err instanceof ProviderError) {
6522
6686
  const baseMessage2 = err.describe();
@@ -6549,7 +6713,7 @@ function classifySubagentError(err, hints = {}) {
6549
6713
  if (/agent exhausted iteration limit$/i.test(baseMessage)) {
6550
6714
  return { kind: "budget_iterations", message: baseMessage, retryable: false, cause };
6551
6715
  }
6552
- if (/empty response$/i.test(baseMessage)) {
6716
+ if (/empty response/i.test(baseMessage)) {
6553
6717
  return { kind: "empty_response", message: baseMessage, retryable: false, cause };
6554
6718
  }
6555
6719
  if (/^tool failed: /i.test(baseMessage)) {
@@ -7498,7 +7662,14 @@ var ParallelEternalEngine = class {
7498
7662
  }
7499
7663
  stop() {
7500
7664
  this.stopRequested = true;
7501
- void this.persistState("stopped").catch(() => {
7665
+ void this.persistState("stopped").catch((err) => {
7666
+ console.error(JSON.stringify({
7667
+ level: "error",
7668
+ event: "engine.persist_state_failed",
7669
+ message: err instanceof Error ? err.message : String(err),
7670
+ context: { expectedState: "stopped" },
7671
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
7672
+ }));
7502
7673
  });
7503
7674
  this.state = "stopped";
7504
7675
  }
@@ -8259,6 +8430,6 @@ function parseDescription(raw) {
8259
8430
  return { trigger, scope };
8260
8431
  }
8261
8432
 
8262
- export { AutoCompactionMiddleware, AutonomousRunner, DefaultErrorHandler, DefaultRetryPolicy, DefaultSkillLoader, DoneConditionChecker, EternalAutonomyEngine, HybridCompactor, IntelligentCompactor, ParallelEternalEngine, SelectiveCompactor, ToolExecutor, buildGoalPreamble, createAutonomyBrain, createStrategyCompactor, formatDecisionSummary, makeAutonomyPromptContributor };
8433
+ export { AutoCompactionMiddleware, AutonomousRunner, DefaultErrorHandler, DefaultRetryPolicy, DefaultSkillLoader, DoneConditionChecker, EternalAutonomyEngine, HybridCompactor, IntelligentCompactor, ParallelEternalEngine, SelectiveCompactor, ToolExecutor, buildGoalPreamble, createAutonomyBrain, createStrategyCompactor, createTieredBrainArbiter, formatDecisionSummary, makeAutonomyPromptContributor };
8263
8434
  //# sourceMappingURL=index.js.map
8264
8435
  //# sourceMappingURL=index.js.map