@wrongstack/core 0.155.0 → 0.250.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-4gc0vfW2.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-Bsueu0J2.d.ts → agent-subagent-runner-Dz-9kiE6.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-eSsrto5d.d.ts} +8 -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 +1986 -146
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/defaults/index.d.ts +26 -26
  11. package/dist/defaults/index.js +1110 -296
  12. package/dist/defaults/index.js.map +1 -1
  13. package/dist/execution/index.d.ts +45 -16
  14. package/dist/execution/index.js +229 -56
  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-BjJpnLW4.d.ts} +19 -10
  23. package/dist/{index-CI1hRfPt.d.ts → index-Dy8OwfBD.d.ts} +8 -8
  24. package/dist/{index-B5wz-GXm.d.ts → index-IehiNryU.d.ts} +7 -5
  25. package/dist/index.d.ts +438 -128
  26. package/dist/index.js +4989 -849
  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-DfXxCASH.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-DpanBg8D.d.ts} +1 -1
  41. package/dist/{multi-agent-coordinator-BSKSFNhv.d.ts → multi-agent-coordinator-CnbEqpv0.d.ts} +8 -8
  42. package/dist/{null-fleet-bus-CGOez8Le.d.ts → null-fleet-bus-Do1OLYpj.d.ts} +7 -7
  43. package/dist/observability/index.d.ts +2 -2
  44. package/dist/package-outdated-watcher-CA5GGB4C.d.ts +560 -0
  45. package/dist/{parallel-eternal-engine-CYoTKjsz.d.ts → parallel-eternal-engine-UZg1xOzE.d.ts} +13 -9
  46. package/dist/{path-resolver-DuhlmPil.d.ts → path-resolver-BaP06Owy.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-D1n-gQI-.d.ts +493 -0
  50. package/dist/{plan-templates-DbH7lg-t.d.ts → plan-templates-BUVRY0pU.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 +221 -87
  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 +562 -55
  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 +25 -4
  74. package/dist/utils/index.js +45 -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
package/dist/sdd/index.js CHANGED
@@ -617,6 +617,81 @@ function topologicalSort(graph) {
617
617
  return result;
618
618
  }
619
619
 
620
+ // src/types/errors.ts
621
+ var ERROR_CODES = {
622
+ // Provider
623
+ PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
624
+ PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
625
+ PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
626
+ PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
627
+ PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
628
+ PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
629
+ // Agent
630
+ AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
631
+ AGENT_ABORTED: "AGENT_ABORTED",
632
+ AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
633
+ // SDD (Spec-Driven Development)
634
+ SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
635
+ SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
636
+ SDD_INVALID_STATE: "SDD_INVALID_STATE",
637
+ SDD_NOT_READY: "SDD_NOT_READY"};
638
+ var WrongStackError = class extends Error {
639
+ code;
640
+ subsystem;
641
+ severity;
642
+ recoverable;
643
+ context;
644
+ constructor(opts) {
645
+ super(opts.message, { cause: opts.cause });
646
+ this.name = "WrongStackError";
647
+ this.code = opts.code;
648
+ this.subsystem = opts.subsystem;
649
+ this.severity = opts.severity ?? "error";
650
+ this.recoverable = opts.recoverable ?? false;
651
+ this.context = opts.context;
652
+ }
653
+ /**
654
+ * Render a one-line user-facing description.
655
+ * Subclasses should override for domain-specific formatting.
656
+ */
657
+ describe() {
658
+ const ctx = this.context ? ` ${formatContext(this.context)}` : "";
659
+ return `${this.code}: ${this.message}${ctx}`;
660
+ }
661
+ };
662
+ function formatContext(ctx) {
663
+ const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
664
+ return parts.length > 0 ? `[${parts.join(" ")}]` : "";
665
+ }
666
+ var AgentError = class extends WrongStackError {
667
+ constructor(opts) {
668
+ super({
669
+ message: opts.message,
670
+ code: opts.code,
671
+ subsystem: "agent",
672
+ severity: opts.code === ERROR_CODES.AGENT_ABORTED ? "warning" : "error",
673
+ recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,
674
+ context: opts.context,
675
+ cause: opts.cause
676
+ });
677
+ this.name = "AgentError";
678
+ }
679
+ };
680
+ var SddError = class extends WrongStackError {
681
+ constructor(opts) {
682
+ super({
683
+ message: opts.message,
684
+ code: opts.code,
685
+ subsystem: "sdd",
686
+ severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? "warning" : "error",
687
+ recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,
688
+ context: opts.context,
689
+ cause: opts.cause
690
+ });
691
+ this.name = "SddError";
692
+ }
693
+ };
694
+
620
695
  // src/sdd/task-tracker.ts
621
696
  var TaskTracker = class {
622
697
  constructor(opts) {
@@ -651,7 +726,10 @@ var TaskTracker = class {
651
726
  return this.graph;
652
727
  }
653
728
  addNode(node) {
654
- if (!this.graph) throw new Error("No graph loaded");
729
+ if (!this.graph) throw new SddError({
730
+ message: "No graph loaded",
731
+ code: ERROR_CODES.SDD_INVALID_STATE
732
+ });
655
733
  const now = Date.now();
656
734
  const newNode = {
657
735
  ...node,
@@ -669,7 +747,10 @@ var TaskTracker = class {
669
747
  return newNode;
670
748
  }
671
749
  addEdge(from, to, type = "depends_on") {
672
- if (!this.graph) throw new Error("No graph loaded");
750
+ if (!this.graph) throw new SddError({
751
+ message: "No graph loaded",
752
+ code: ERROR_CODES.SDD_INVALID_STATE
753
+ });
673
754
  this.graph.edges.push({
674
755
  id: crypto.randomUUID(),
675
756
  from,
@@ -680,9 +761,16 @@ var TaskTracker = class {
680
761
  this.persist();
681
762
  }
682
763
  updateNodeStatus(id, status, reason) {
683
- if (!this.graph) throw new Error("No graph loaded");
764
+ if (!this.graph) throw new SddError({
765
+ message: "No graph loaded",
766
+ code: ERROR_CODES.SDD_INVALID_STATE
767
+ });
684
768
  const node = this.graph.nodes.get(id);
685
- if (!node) throw new Error(`Node ${id} not found`);
769
+ if (!node) throw new SddError({
770
+ message: `Node ${id} not found`,
771
+ code: ERROR_CODES.SDD_NOT_READY,
772
+ context: { nodeId: id }
773
+ });
686
774
  const from = node.status;
687
775
  const now = Date.now();
688
776
  node.status = status;
@@ -705,9 +793,16 @@ var TaskTracker = class {
705
793
  this.persist();
706
794
  }
707
795
  updateNode(id, patch) {
708
- if (!this.graph) throw new Error("No graph loaded");
796
+ if (!this.graph) throw new SddError({
797
+ message: "No graph loaded",
798
+ code: ERROR_CODES.SDD_INVALID_STATE
799
+ });
709
800
  const node = this.graph.nodes.get(id);
710
- if (!node) throw new Error(`Node ${id} not found`);
801
+ if (!node) throw new SddError({
802
+ message: `Node ${id} not found`,
803
+ code: ERROR_CODES.SDD_NOT_READY,
804
+ context: { nodeId: id }
805
+ });
711
806
  if (patch.title !== void 0) node.title = patch.title;
712
807
  if (patch.description !== void 0) node.description = patch.description;
713
808
  if (patch.priority !== void 0) node.priority = patch.priority;
@@ -826,7 +921,12 @@ var TaskTracker = class {
826
921
  persist() {
827
922
  if (!this.graph) return;
828
923
  this.opts.store.saveGraph(this.graph).catch((err) => {
829
- this.opts.onPersistError ? this.opts.onPersistError(err) : console.warn("[task-tracker] saveGraph failed:", err instanceof Error ? err.message : String(err));
924
+ this.opts.onPersistError ? this.opts.onPersistError(err) : console.warn(JSON.stringify({
925
+ level: "warn",
926
+ event: "task_tracker.save_graph_failed",
927
+ message: err instanceof Error ? err.message : String(err),
928
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
929
+ }));
830
930
  });
831
931
  }
832
932
  };
@@ -879,12 +979,14 @@ var TaskFlow = class {
879
979
  const analysis = parser.analyze(this.spec);
880
980
  this.emit("spec.analyzed", { analysis });
881
981
  if (analysis.completeness < 50) {
882
- this.emit("error", {
883
- phase: "analyzing",
884
- error: new Error(`Spec completeness too low: ${analysis.completeness}%`)
982
+ const err = new SddError({
983
+ message: `Spec completeness too low: ${analysis.completeness}%`,
984
+ code: ERROR_CODES.SDD_VALIDATION_FAILED,
985
+ context: { completeness: analysis.completeness }
885
986
  });
987
+ this.emit("error", { phase: "analyzing", error: err });
886
988
  this.setPhase("failed");
887
- throw new Error("Spec too incomplete");
989
+ throw err;
888
990
  }
889
991
  this.setPhase("generating");
890
992
  const generator = new TaskGenerator({ taskTracker: this.opts.tracker });
@@ -892,7 +994,11 @@ var TaskFlow = class {
892
994
  return this.graph;
893
995
  }
894
996
  async execute(ctx) {
895
- if (!this.graph) throw new Error("No graph loaded. Call fromSpec first.");
997
+ if (!this.graph) throw new SddError({
998
+ message: "No graph loaded. Call fromSpec first.",
999
+ code: ERROR_CODES.SDD_INVALID_STATE,
1000
+ context: { phase: this.phase }
1001
+ });
896
1002
  this.setPhase("executing");
897
1003
  this.stopped = false;
898
1004
  const pendingTasks = this.getExecutableTasks();
@@ -932,7 +1038,11 @@ var TaskFlow = class {
932
1038
  }
933
1039
  async reviewTask(taskId, approved, comment) {
934
1040
  const task = this.opts.tracker.getNode(taskId);
935
- if (!task) throw new Error(`Task ${taskId} not found`);
1041
+ if (!task) throw new SddError({
1042
+ message: `Task ${taskId} not found`,
1043
+ code: ERROR_CODES.SDD_NOT_READY,
1044
+ context: { taskId }
1045
+ });
936
1046
  if (approved) {
937
1047
  this.opts.tracker.updateNodeStatus(taskId, "completed", comment);
938
1048
  this.emit("task.completed", { taskId });
@@ -1246,7 +1356,9 @@ var TaskGraphStore = class {
1246
1356
  // src/utils/expect-defined.ts
1247
1357
  function expectDefined(value, label) {
1248
1358
  if (value === null || value === void 0) {
1249
- throw new Error("Expected value to be defined");
1359
+ const err = new Error("Expected value to be defined");
1360
+ err.name = "ExpectDefinedError";
1361
+ throw err;
1250
1362
  }
1251
1363
  return value;
1252
1364
  }
@@ -1584,7 +1696,11 @@ var AISpecBuilder = class {
1584
1696
  switch (this.session.phase) {
1585
1697
  case "questioning":
1586
1698
  if (!this.session.spec) {
1587
- throw new Error("Cannot approve: no spec generated yet.");
1699
+ throw new SddError({
1700
+ message: "Cannot approve: no spec generated yet.",
1701
+ code: ERROR_CODES.SDD_INVALID_STATE,
1702
+ context: { phase: "questioning", sessionId: this.session.id }
1703
+ });
1588
1704
  }
1589
1705
  this.session.phase = "spec_review";
1590
1706
  break;
@@ -1642,7 +1758,11 @@ var AISpecBuilder = class {
1642
1758
  */
1643
1759
  async saveSpec() {
1644
1760
  if (!this.session.spec) {
1645
- throw new Error("No spec to save.");
1761
+ throw new SddError({
1762
+ message: "No spec to save.",
1763
+ code: ERROR_CODES.SDD_NOT_READY,
1764
+ context: { sessionId: this.session.id }
1765
+ });
1646
1766
  }
1647
1767
  await this.store.save(this.session.spec);
1648
1768
  return this.session.spec;
@@ -1657,17 +1777,30 @@ var AISpecBuilder = class {
1657
1777
  try {
1658
1778
  parsed = JSON.parse(jsonStr);
1659
1779
  } catch (e) {
1660
- throw new Error(`Invalid JSON for spec: ${e instanceof Error ? e.message : "parse error"}`);
1780
+ throw new SddError({
1781
+ message: "Invalid JSON for spec",
1782
+ code: ERROR_CODES.SDD_PARSE_FAILED,
1783
+ cause: e,
1784
+ context: { detail: e instanceof Error ? e.message : "parse error" }
1785
+ });
1661
1786
  }
1662
1787
  if (!parsed || typeof parsed !== "object") {
1663
- throw new Error("Spec JSON must be an object.");
1788
+ throw new SddError({
1789
+ message: "Spec JSON must be an object",
1790
+ code: ERROR_CODES.SDD_VALIDATION_FAILED,
1791
+ context: { actualType: typeof parsed }
1792
+ });
1664
1793
  }
1665
1794
  const raw = parsed;
1666
1795
  const now = Date.now();
1667
1796
  const title = String(raw.title ?? this.session.title ?? "Untitled");
1668
1797
  const overview = String(raw.overview ?? "");
1669
1798
  if (!overview || overview === "undefined") {
1670
- throw new Error("Spec must have an overview.");
1799
+ throw new SddError({
1800
+ message: "Spec must have an overview",
1801
+ code: ERROR_CODES.SDD_VALIDATION_FAILED,
1802
+ context: { field: "overview", title }
1803
+ });
1671
1804
  }
1672
1805
  const rawSections = Array.isArray(raw.sections) ? raw.sections : [];
1673
1806
  const sections = rawSections.filter((s) => s && typeof s === "object").map((s) => ({
@@ -1883,6 +2016,11 @@ function templateToMarkdown(template, title) {
1883
2016
  return lines.join("\n");
1884
2017
  }
1885
2018
 
2019
+ // src/utils/string.ts
2020
+ function truncate(s, max) {
2021
+ return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;
2022
+ }
2023
+
1886
2024
  // src/sdd/task-visualizer.ts
1887
2025
  var STATUS_ICON = {
1888
2026
  pending: "\u25CB",
@@ -2033,10 +2171,6 @@ function renderSpecAnalysis(spec, analysis) {
2033
2171
  }
2034
2172
  return lines.join("\n");
2035
2173
  }
2036
- function truncate(str, maxLen) {
2037
- if (str.length <= maxLen) return str;
2038
- return str.slice(0, maxLen - 1) + "\u2026";
2039
- }
2040
2174
 
2041
2175
  // src/sdd/critical-path.ts
2042
2176
  function analyzeCriticalPath(graph) {
@@ -2211,9 +2345,11 @@ function computeParallelGroups(graph, blockedByMap) {
2211
2345
 
2212
2346
  // src/utils/assert-never.ts
2213
2347
  function assertNever(x, message) {
2214
- throw new Error(
2348
+ const err = new Error(
2215
2349
  `Unhandled case: ${JSON.stringify(x)}`
2216
2350
  );
2351
+ err.name = "AssertNeverError";
2352
+ throw err;
2217
2353
  }
2218
2354
 
2219
2355
  // src/sdd/spec-versioning.ts
@@ -3136,21 +3272,40 @@ function makeAgentSubagentRunner(opts) {
3136
3272
  if (budgetError) throw budgetError;
3137
3273
  }
3138
3274
  if (result.status === "failed") {
3139
- throw result.error instanceof Error ? result.error : new Error(String(result.error ?? "agent failed"));
3275
+ throw result.error instanceof AgentError ? result.error : new AgentError({
3276
+ message: result.error instanceof Error ? result.error.message : String(result.error ?? "agent failed"),
3277
+ code: ERROR_CODES.AGENT_RUN_FAILED,
3278
+ cause: result.error
3279
+ });
3140
3280
  }
3141
3281
  if (result.status === "aborted") {
3142
- throw new Error("agent aborted");
3282
+ throw new AgentError({
3283
+ message: "agent aborted",
3284
+ code: ERROR_CODES.AGENT_ABORTED
3285
+ });
3143
3286
  }
3144
3287
  if (result.status === "max_iterations") {
3145
- throw new Error("agent exhausted iteration limit");
3288
+ throw new AgentError({
3289
+ message: "agent exhausted iteration limit",
3290
+ code: ERROR_CODES.AGENT_ITERATION_LIMIT,
3291
+ recoverable: true
3292
+ });
3146
3293
  }
3147
3294
  const usage = ctx.budget.usage();
3148
3295
  const finalText = (result.finalText ?? "").trim();
3149
3296
  if (finalText.length === 0 && usage.toolCalls === 0) {
3150
- throw new Error("empty response");
3297
+ throw new AgentError({
3298
+ message: "empty response \u2014 agent produced no text and no tool calls",
3299
+ code: ERROR_CODES.AGENT_RUN_FAILED,
3300
+ context: { iterations: result.iterations }
3301
+ });
3151
3302
  }
3152
3303
  if (finalText.length === 0 && lastToolFailed !== null) {
3153
- throw new Error(`tool failed: ${lastToolFailed}`);
3304
+ throw new AgentError({
3305
+ message: `unrecovered tool failure: ${lastToolFailed} \u2014 agent ended turn without acknowledging the error`,
3306
+ code: ERROR_CODES.AGENT_RUN_FAILED,
3307
+ context: { tool: lastToolFailed, iterations: result.iterations }
3308
+ });
3154
3309
  }
3155
3310
  return {
3156
3311
  result: result.finalText,
@@ -3163,44 +3318,6 @@ function defaultFormatTaskInput(task) {
3163
3318
  return task.description ?? "";
3164
3319
  }
3165
3320
 
3166
- // src/types/errors.ts
3167
- var ERROR_CODES = {
3168
- // Provider
3169
- PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
3170
- PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
3171
- PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
3172
- PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
3173
- PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
3174
- PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR"};
3175
- var WrongStackError = class extends Error {
3176
- code;
3177
- subsystem;
3178
- severity;
3179
- recoverable;
3180
- context;
3181
- constructor(opts) {
3182
- super(opts.message, { cause: opts.cause });
3183
- this.name = "WrongStackError";
3184
- this.code = opts.code;
3185
- this.subsystem = opts.subsystem;
3186
- this.severity = opts.severity ?? "error";
3187
- this.recoverable = opts.recoverable ?? false;
3188
- this.context = opts.context;
3189
- }
3190
- /**
3191
- * Render a one-line user-facing description.
3192
- * Subclasses should override for domain-specific formatting.
3193
- */
3194
- describe() {
3195
- const ctx = this.context ? ` ${formatContext(this.context)}` : "";
3196
- return `${this.code}: ${this.message}${ctx}`;
3197
- }
3198
- };
3199
- function formatContext(ctx) {
3200
- const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
3201
- return parts.length > 0 ? `[${parts.join(" ")}]` : "";
3202
- }
3203
-
3204
3321
  // src/types/provider.ts
3205
3322
  var ProviderError = class extends WrongStackError {
3206
3323
  status;
@@ -3241,7 +3358,7 @@ var ProviderError = class extends WrongStackError {
3241
3358
  const detail = this.body?.message?.trim();
3242
3359
  const reqId = this.body?.requestId ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? "\u2026" : ""}]` : "";
3243
3360
  if (detail && detail.length > 0) {
3244
- return `${head}: ${truncate2(detail, 240)}${reqId}`;
3361
+ return `${head}: ${truncate(detail, 240)}${reqId}`;
3245
3362
  }
3246
3363
  return `${head}${reqId}`;
3247
3364
  }
@@ -3259,9 +3376,6 @@ function describeStatus(status, type) {
3259
3376
  if (type) return `${type} (${status})`;
3260
3377
  return `HTTP ${status}`;
3261
3378
  }
3262
- function truncate2(s, n) {
3263
- return s.length <= n ? s : `${s.slice(0, n - 1)}\u2026`;
3264
- }
3265
3379
  function providerStatusToCode(status, type) {
3266
3380
  if (status === 0) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
3267
3381
  if (type === "rate_limit_error" || status === 429) return ERROR_CODES.PROVIDER_RATE_LIMITED;
@@ -3275,6 +3389,9 @@ function providerStatusToCode(status, type) {
3275
3389
 
3276
3390
  // src/coordination/coordinator/error-classifier.ts
3277
3391
  function classifySubagentError(err, hints = {}) {
3392
+ if (err instanceof AgentError && err.cause) {
3393
+ return classifySubagentError(err.cause, hints);
3394
+ }
3278
3395
  const cause = err instanceof Error ? { name: err.name, message: err.message, stack: err.stack } : void 0;
3279
3396
  if (err instanceof ProviderError) {
3280
3397
  const baseMessage2 = err.describe();
@@ -3307,7 +3424,7 @@ function classifySubagentError(err, hints = {}) {
3307
3424
  if (/agent exhausted iteration limit$/i.test(baseMessage)) {
3308
3425
  return { kind: "budget_iterations", message: baseMessage, retryable: false, cause };
3309
3426
  }
3310
- if (/empty response$/i.test(baseMessage)) {
3427
+ if (/empty response/i.test(baseMessage)) {
3311
3428
  return { kind: "empty_response", message: baseMessage, retryable: false, cause };
3312
3429
  }
3313
3430
  if (/^tool failed: /i.test(baseMessage)) {
@@ -3357,11 +3474,11 @@ var HEAVY_BUDGET = {
3357
3474
  };
3358
3475
  var TOOLS = {
3359
3476
  /** Pure read/inspect — safe for analysis and review agents. */
3360
- read: ["read", "grep", "glob", "search", "tree"],
3477
+ read: ["read", "grep", "glob", "search", "tree", "mailbox"],
3361
3478
  /** Read + structured inspection (logs, diffs, json, dependency audit). */
3362
- inspect: ["read", "grep", "glob", "search", "tree", "json", "diff", "logs", "audit"],
3479
+ inspect: ["read", "grep", "glob", "search", "tree", "json", "diff", "logs", "audit", "mailbox"],
3363
3480
  /** Read + edit (no shell). For agents that write code/docs but don't run it. */
3364
- write: ["read", "grep", "glob", "search", "tree", "write", "edit", "replace", "patch"],
3481
+ write: ["read", "grep", "glob", "search", "tree", "write", "edit", "replace", "patch", "mailbox"],
3365
3482
  /** Full build loop: edit + run (lint/format/typecheck/test/bash). */
3366
3483
  build: [
3367
3484
  "read",
@@ -3378,16 +3495,17 @@ var TOOLS = {
3378
3495
  "lint",
3379
3496
  "format",
3380
3497
  "typecheck",
3381
- "test"
3498
+ "test",
3499
+ "mailbox"
3382
3500
  ],
3383
3501
  /** Version control. */
3384
3502
  vcs: ["read", "grep", "glob", "git", "diff"],
3385
3503
  /** Dependency management + CVE audit. */
3386
- deps: ["read", "grep", "glob", "install", "outdated", "audit", "json"],
3504
+ deps: ["read", "grep", "glob", "install", "outdated", "audit", "json", "mailbox"],
3387
3505
  /** Documentation authoring. */
3388
- docs: ["read", "grep", "glob", "search", "tree", "write", "edit", "document"],
3506
+ docs: ["read", "grep", "glob", "search", "tree", "write", "edit", "document", "mailbox"],
3389
3507
  /** Web research. */
3390
- research: ["read", "grep", "glob", "search", "fetch"]
3508
+ research: ["read", "grep", "glob", "search", "fetch", "mailbox"]
3391
3509
  };
3392
3510
 
3393
3511
  // src/coordination/agents/phase1-discovery.ts
@@ -5800,7 +5918,7 @@ Working rules:
5800
5918
  id: "tech-stack",
5801
5919
  name: "Tech Stack Validator",
5802
5920
  role: "tech-stack",
5803
- tools: ["search", "fetch", "read", "grep", "glob", "outdated", "audit", "json"],
5921
+ tools: ["search", "fetch", "read", "grep", "glob", "outdated", "audit", "json", "mailbox"],
5804
5922
  prompt: `You are the Tech Stack Validator \u2014 a single-shot validation agent that fires
5805
5923
  before any package, library, or framework choice is committed.
5806
5924
 
@@ -5808,6 +5926,16 @@ Your ONLY job: verify that a technology choice is current, real, and not obsolet
5808
5926
  You are the "this isn't code, this is 10-year-old technology" agent. Intervene
5809
5927
  hard when the LLM hallucinates a version number or suggests dead tech.
5810
5928
 
5929
+ ## Before you begin
5930
+
5931
+ Check the inter-agent mailbox for pending tasks. Other agents or the file-watcher
5932
+ may have left assign messages with dependency files to audit:
5933
+ - mailbox action=check
5934
+
5935
+ If you find an assign message, use the specified file path and packages.
5936
+ When done, post results back:
5937
+ - mailbox action=send to=<sender> type=result subject="Tech stack audit results" body="..."
5938
+
5811
5939
  ## Critical rules
5812
5940
 
5813
5941
  1. **Verify existence.** Search npm registry (fetch https://registry.npmjs.org/<pkg>/latest)
@@ -5866,11 +5994,11 @@ When APPROVED:
5866
5994
  **Install**: pnpm add <name>@^<major>.<minor>.0`
5867
5995
  },
5868
5996
  budget: {
5869
- timeoutMs: 6e4,
5870
- maxIterations: 5,
5871
- maxToolCalls: 20,
5872
- maxTokens: 4e4,
5873
- maxCostUsd: 0.1
5997
+ timeoutMs: 12e4,
5998
+ maxIterations: 10,
5999
+ maxToolCalls: 40,
6000
+ maxTokens: 6e4,
6001
+ maxCostUsd: 0.25
5874
6002
  },
5875
6003
  capability: {
5876
6004
  phase: "meta",
@@ -6911,7 +7039,10 @@ var SddParallelRun = class {
6911
7039
  "\u2022 Do not ask before routine in-project tool use; if a permission gate appears, wait for that flow.",
6912
7040
  "\u2022 Keep output concise \u2014 summarize changes, do not transcribe files."
6913
7041
  ].join("\n");
6914
- if (!this.coordinator) throw new Error("SDD parallel runner requires a coordinator");
7042
+ if (!this.coordinator) throw new SddError({
7043
+ message: "SDD parallel runner requires a coordinator",
7044
+ code: ERROR_CODES.SDD_INVALID_STATE
7045
+ });
6915
7046
  const coordinator = this.coordinator;
6916
7047
  const spawns = subagentIds.map(
6917
7048
  (subagentId) => coordinator.spawn({
@@ -6923,7 +7054,10 @@ var SddParallelRun = class {
6923
7054
  );
6924
7055
  const spawnResults = await Promise.all(spawns);
6925
7056
  if (!spawnResults.every((r) => Boolean(r.subagentId))) {
6926
- throw new Error("One or more subagent spawns failed");
7057
+ throw new SddError({
7058
+ message: "One or more subagent spawns failed",
7059
+ code: ERROR_CODES.SDD_INVALID_STATE
7060
+ });
6927
7061
  }
6928
7062
  const assignPromises = tasks.map((task, i) => {
6929
7063
  const spec = {