@wrongstack/core 0.260.0 → 0.265.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/{agent-bridge-BbskZ7HH.d.ts → agent-bridge-DrkBxszZ.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-BNIGZx18.d.ts → agent-subagent-runner-DM2pP-B6.d.ts} +116 -12
  3. package/dist/{brain-C2yDd7Lw.d.ts → brain-BXd_61kQ.d.ts} +32 -3
  4. package/dist/{compactor-t0R_AIt_.d.ts → compactor-B8pOf45Y.d.ts} +1 -1
  5. package/dist/{config-FG6As4H5.d.ts → config-BMCj_XDs.d.ts} +86 -12
  6. package/dist/{context-JFOVvu6z.d.ts → context-MRk5PhNv.d.ts} +26 -1
  7. package/dist/coordination/index.d.ts +1737 -15
  8. package/dist/coordination/index.js +3152 -494
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/{default-config-CXsDvOmP.d.ts → default-config-B0cj-Hry.d.ts} +11 -1
  11. package/dist/defaults/index.d.ts +28 -28
  12. package/dist/defaults/index.js +1804 -1363
  13. package/dist/defaults/index.js.map +1 -1
  14. package/dist/dispatcher-types.d-BBeXBQgS.d.ts +66 -0
  15. package/dist/execution/index.d.ts +16 -16
  16. package/dist/execution/index.js +933 -672
  17. package/dist/execution/index.js.map +1 -1
  18. package/dist/execution/prompt-enhancer.d.ts +1 -1
  19. package/dist/execution/prompt-enhancer.js +7 -1
  20. package/dist/execution/prompt-enhancer.js.map +1 -1
  21. package/dist/extension/index.d.ts +6 -6
  22. package/dist/extension/index.js.map +1 -1
  23. package/dist/{goal-preamble-B1IXJtLX.d.ts → goal-preamble-DvHDSKSe.d.ts} +26 -10
  24. package/dist/{goal-store-CPXz6Mml.d.ts → goal-store-DtLMySNb.d.ts} +1 -1
  25. package/dist/{index-CebbJB94.d.ts → index-B-ch8K9C.d.ts} +8 -8
  26. package/dist/{index-BPcg4N3M.d.ts → index-CEDeNodM.d.ts} +5 -5
  27. package/dist/index.d.ts +189 -104
  28. package/dist/index.js +24693 -21162
  29. package/dist/index.js.map +1 -1
  30. package/dist/infrastructure/index.d.ts +6 -6
  31. package/dist/infrastructure/index.js +12 -8
  32. package/dist/infrastructure/index.js.map +1 -1
  33. package/dist/kernel/index.d.ts +9 -9
  34. package/dist/kernel/index.js +7 -2
  35. package/dist/kernel/index.js.map +1 -1
  36. package/dist/{llm-selector-DXxI2tlu.d.ts → llm-selector-C0tfTCUe.d.ts} +14 -2
  37. package/dist/{mcp-servers-OwNHo43-.d.ts → mcp-servers-2x4w6Jn9.d.ts} +3 -3
  38. package/dist/models/index.d.ts +5 -5
  39. package/dist/models/index.js +80 -31
  40. package/dist/models/index.js.map +1 -1
  41. package/dist/{models-registry-Djlmq4uB.d.ts → models-registry-DmJlKuNp.d.ts} +1 -1
  42. package/dist/{multi-agent-coordinator-CEmrSCMJ.d.ts → multi-agent-coordinator-DyCkCZnU.d.ts} +2 -2
  43. package/dist/{null-fleet-bus-DT92xqgJ.d.ts → null-fleet-bus-CG9QY2aP.d.ts} +6 -6
  44. package/dist/observability/index.d.ts +2 -2
  45. package/dist/observability/index.js +8 -3
  46. package/dist/observability/index.js.map +1 -1
  47. package/dist/{parallel-eternal-engine-0SItuq5r.d.ts → parallel-eternal-engine-Jw9uhEoT.d.ts} +9 -9
  48. package/dist/{path-resolver-DKBh6Jlo.d.ts → path-resolver-Dy2ej-gE.d.ts} +3 -3
  49. package/dist/{permission-BJ7eO9Vl.d.ts → permission-B9SB45lp.d.ts} +1 -1
  50. package/dist/{permission-policy-DEXOfnpm.d.ts → permission-policy-CkjSXabK.d.ts} +2 -2
  51. package/dist/{pipeline-zflkI2dp.d.ts → pipeline-DPDxH_7m.d.ts} +59 -4
  52. package/dist/{plan-templates-BFXyRkEK.d.ts → plan-templates-CzD9GnAU.d.ts} +32 -8
  53. package/dist/{provider-runner-BC-uywtT.d.ts → provider-runner-DMa70ODu.d.ts} +3 -3
  54. package/dist/{retry-policy-Cavrzmtk.d.ts → retry-policy-CN0khdlj.d.ts} +1 -1
  55. package/dist/sdd/index.d.ts +8 -8
  56. package/dist/sdd/index.js +313 -122
  57. package/dist/sdd/index.js.map +1 -1
  58. package/dist/{secret-vault-CDvDYXWX.d.ts → secret-vault-B2yw84VT.d.ts} +43 -4
  59. package/dist/secret-vault-BAKpgFw_.d.ts +57 -0
  60. package/dist/security/index.d.ts +5 -5
  61. package/dist/security/index.js +411 -225
  62. package/dist/security/index.js.map +1 -1
  63. package/dist/{selector-B7AivHsu.d.ts → selector-CzHh_igB.d.ts} +1 -1
  64. package/dist/{session-event-bridge-BmIDxdJd.d.ts → session-event-bridge-BUI6Jf-4.d.ts} +8 -2
  65. package/dist/{session-reader-DtofsB-2.d.ts → session-reader-CMgdMSRP.d.ts} +1 -1
  66. package/dist/skills/index.js +67 -64
  67. package/dist/skills/index.js.map +1 -1
  68. package/dist/storage/index.d.ts +132 -16
  69. package/dist/storage/index.js +851 -432
  70. package/dist/storage/index.js.map +1 -1
  71. package/dist/tools/index.d.ts +57 -0
  72. package/dist/tools/index.js +411 -0
  73. package/dist/tools/index.js.map +1 -0
  74. package/dist/types/index.d.ts +21 -21
  75. package/dist/types/index.js +928 -711
  76. package/dist/types/index.js.map +1 -1
  77. package/dist/utils/error.d.ts +7 -0
  78. package/dist/utils/error.js +8 -0
  79. package/dist/utils/error.js.map +1 -0
  80. package/dist/utils/index.d.ts +8 -68
  81. package/dist/utils/index.js +20 -10
  82. package/dist/utils/index.js.map +1 -1
  83. package/dist/{wstack-paths-CJjEwPXn.d.ts → wstack-paths-hOpNLmvf.d.ts} +2 -0
  84. package/package.json +5 -1
  85. package/skills/api-design/SKILL.md +1 -1
  86. package/skills/audit-log/SKILL.md +6 -6
  87. package/skills/bug-hunter/SKILL.md +5 -5
  88. package/skills/chimera/SKILL.md +4 -4
  89. package/skills/docker-deploy/SKILL.md +1 -1
  90. package/skills/git-flow/SKILL.md +3 -3
  91. package/skills/multi-agent/SKILL.md +3 -3
  92. package/skills/node-modern/SKILL.md +1 -0
  93. package/skills/observability/SKILL.md +2 -2
  94. package/skills/output-standards/SKILL.md +51 -28
  95. package/skills/refactor-planner/SKILL.md +3 -3
  96. package/skills/security-scanner/SKILL.md +4 -3
  97. package/skills/tech-stack/SKILL.md +1 -2
  98. package/dist/package-outdated-watcher-C70ag2G9.d.ts +0 -581
  99. package/dist/secret-vault-BJDY28ev.d.ts +0 -25
@@ -1,4 +1,4 @@
1
- import { P as Provider, M as Message } from '../context-JFOVvu6z.js';
1
+ import { P as Provider, M as Message } from '../context-MRk5PhNv.js';
2
2
 
3
3
  /**
4
4
  * Prompt refinement ("did you mean this?").
@@ -3,6 +3,11 @@ function isTextBlock(b) {
3
3
  return b.type === "text";
4
4
  }
5
5
 
6
+ // src/utils/error.ts
7
+ function toErrorMessage(err) {
8
+ return err instanceof Error ? err.message : String(err);
9
+ }
10
+
6
11
  // src/execution/prompt-enhancer.ts
7
12
  var ENHANCER_SYSTEM_PROMPT = `You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into clearer, unambiguous instructions that the coding agent can act on confidently.
8
13
 
@@ -95,9 +100,10 @@ async function enhanceUserPrompt(opts) {
95
100
  opts.onError?.(`timed out after ${Math.round(timeoutMs / 1e3)}s`);
96
101
  return null;
97
102
  }
98
- opts.onError?.(err instanceof Error ? err.message : String(err));
103
+ opts.onError?.(toErrorMessage(err));
99
104
  return null;
100
105
  } finally {
106
+ timer.abort();
101
107
  clearTimeout(to);
102
108
  }
103
109
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/blocks.ts","../../src/execution/prompt-enhancer.ts"],"names":[],"mappings":";AA2EO,SAAS,YAAY,CAAA,EAAiC;AAC3D,EAAA,OAAO,EAAE,IAAA,KAAS,MAAA;AACpB;;;AC1DO,IAAM,sBAAA,GAAyB,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA,oEAAA;AAwBtC,IAAM,cAAA,GACJ,mIAAA;AAQK,SAAS,cAAc,IAAA,EAAuB;AACnD,EAAA,MAAM,CAAA,GAAI,KAAK,IAAA,EAAK;AACpB,EAAA,IAAI,CAAC,GAAG,OAAO,KAAA;AACf,EAAA,IAAI,CAAA,CAAE,UAAA,CAAW,GAAG,CAAA,EAAG,OAAO,KAAA;AAC9B,EAAA,IAAI,CAAA,CAAE,MAAA,GAAS,EAAA,EAAI,OAAO,KAAA;AAC1B,EAAA,IAAI,cAAA,CAAe,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,KAAA;AACnC,EAAA,IAAI,aAAA,CAAc,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,KAAA;AAClC,EAAA,MAAM,QAAQ,CAAA,CAAE,KAAA,CAAM,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA;AAC3C,EAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,OAAO,KAAA;AAC7B,EAAA,OAAO,IAAA;AACT;AAOO,SAAS,eAAA,CAAgB,GAAW,CAAA,EAAoB;AAC7D,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAc,CAAA,CAAE,IAAA,GAAO,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CAAE,WAAA,EAAY;AACtE,EAAA,OAAO,IAAA,CAAK,CAAC,CAAA,KAAM,IAAA,CAAK,CAAC,CAAA;AAC3B;AAkDA,SAAS,iBAAA,CAAkB,MAAc,OAAA,EAAsC;AAC7E,EAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,MAAA,KAAW,GAAG,OAAO,IAAA;AAC7C,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAM,CAAA,EAAG,CAAA,CAAE,IAAA,KAAS,MAAA,GAAS,MAAA,GAAS,WAAW,CAAA,EAAA,EAAK,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AACzF,EAAA,OAAO;AAAA,IACL,6DAAA;AAAA,IACA,GAAG,KAAA;AAAA,IACH,EAAA;AAAA,IACA,2BAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;AAQA,eAAsB,kBACpB,IAAA,EAC+B;AAC/B,EAAA,MAAM,EAAE,QAAA,EAAU,KAAA,EAAO,IAAA,EAAK,GAAI,IAAA;AAGlC,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,GAAA;AAIpC,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,IAAA;AAEpC,EAAA,MAAM,GAAA,GAAe;AAAA,IACnB,KAAA;AAAA,IACA,QAAQ,CAAC,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,wBAAwB,CAAA;AAAA,IACvD,QAAA,EAAU,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,iBAAA,CAAkB,IAAA,EAAM,IAAA,CAAK,OAAO,CAAA,EAAG,CAAA;AAAA,IAC3E;AAAA;AAAA;AAAA;AAAA;AAAA,GAKF;AAIA,EAAA,MAAM,KAAA,GAAQ,IAAI,eAAA,EAAgB;AAClC,EAAA,MAAM,EAAA,GAAK,UAAA,CAAW,MAAM,KAAA,CAAM,KAAA,CAAM,IAAI,KAAA,CAAM,kBAAkB,CAAC,CAAA,EAAG,SAAS,CAAA;AACjF,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,GAChB,WAAA,CAAY,GAAA,CAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,MAAM,CAAC,CAAA,GAC3C,KAAA,CAAM,MAAA;AAEV,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,MAAM,QAAA,CAAS,SAAS,GAAA,EAAK,EAAE,QAAQ,CAAA;AACnD,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CACb,MAAA,CAAO,WAAW,CAAA,CAClB,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA,CACjB,IAAA,CAAK,IAAI,EACT,IAAA,EAAK;AACR,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,IAAA,CAAK,UAAU,wBAAwB,CAAA;AACvC,MAAA,OAAO,IAAA;AAAA,IACT;AAIA,IAAA,MAAM,MAAA,GAAS,GAAA,CAAI,OAAA,CAAQ,SAAS,CAAA;AACpC,IAAA,IAAI,WAAW,CAAA,CAAA,EAAI;AAGjB,MAAA,IAAA,CAAK,UAAU,oCAAoC,CAAA;AACnD,MAAA,OAAO,EAAE,OAAA,EAAS,GAAA,EAAK,OAAA,EAAS,GAAA,EAAI;AAAA,IACtC;AACA,IAAA,MAAM,UAAU,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,MAAM,EAAE,IAAA,EAAK;AAC1C,IAAA,MAAM,UAAU,GAAA,CAAI,KAAA,CAAM,MAAA,GAAS,CAAC,EAAE,IAAA,EAAK;AAC3C,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,EAAS;AACxB,MAAA,IAAA,CAAK,UAAU,4BAA4B,CAAA;AAC3C,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,EAAE,SAAS,OAAA,EAAQ;AAAA,EAC5B,SAAS,GAAA,EAAK;AAEZ,IAAA,IAAI,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,OAAO,IAAA;AACjC,IAAA,IAAI,KAAA,CAAM,OAAO,OAAA,EAAS;AACxB,MAAA,IAAA,CAAK,UAAU,CAAA,gBAAA,EAAmB,IAAA,CAAK,MAAM,SAAA,GAAY,GAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AACjE,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAA,CAAK,UAAU,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAC/D,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,EAAE,CAAA;AAAA,EACjB;AACF;AAGA,SAAS,YAAY,OAAA,EAA0C;AAC7D,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,OAAA;AACxC,EAAA,OAAO,OAAA,CACJ,MAAA,CAAO,WAAW,CAAA,CAClB,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,CACjB,IAAA,CAAK,IAAI,EACT,IAAA,EAAK;AACV;AASO,SAAS,eAAA,CACd,QAAA,EACA,QAAA,GAAW,CAAA,EACX,WAAW,IAAA,EACS;AACpB,EAAA,MAAM,QAA4B,EAAC;AACnC,EAAA,KAAA,IAAS,CAAA,GAAI,SAAS,MAAA,GAAS,CAAA,EAAG,KAAK,CAAA,IAAK,KAAA,CAAM,MAAA,GAAS,QAAA,EAAU,CAAA,EAAA,EAAK;AACxE,IAAA,MAAM,CAAA,GAAI,SAAS,CAAC,CAAA;AACpB,IAAA,IAAI,CAAC,CAAA,IAAM,CAAA,CAAE,SAAS,MAAA,IAAU,CAAA,CAAE,SAAS,WAAA,EAAc;AACzD,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,CAAA,CAAE,OAAO,CAAA;AAClC,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,KAAA,CAAM,OAAA,CAAQ;AAAA,MACZ,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,IAAA,EAAM,IAAA,CAAK,MAAA,GAAS,QAAA,GAAW,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,QAAA,GAAW,CAAC,CAAC,CAAA,MAAA,CAAA,GAAM;AAAA,KACpE,CAAA;AAAA,EACH;AACA,EAAA,OAAO,KAAA;AACT","file":"prompt-enhancer.js","sourcesContent":["export interface TextBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' | undefined };\n}\n\nexport interface ToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n /**\n * Provider-specific opaque metadata captured from the wire response.\n * Echoed back verbatim in the next request so providers that bind\n * extra state to function calls keep working. Example: Gemini's\n * `thoughtSignature` — required for tool-use turns with thinking\n * models, otherwise the next request fails with 400 \"Function call\n * is missing a thought_signature in functionCall parts\".\n *\n * Keys are namespaced by intent so multiple wires can coexist:\n * - `google.thoughtSignature` — Gemini signed-thought blob\n * Other providers can add their own keys without colliding.\n */\n providerMeta?: Record<string, unknown>;\n}\n\nexport interface ToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n /**\n * The original tool name. Useful for providers like Google Gemini that\n * need the tool name in `functionResponse.name` — the tool_use_id is\n * only a session-local identifier and is not stable across replays.\n * Always set by ToolExecutor; may be absent on manually-constructed blocks.\n */\n name?: string | undefined;\n content: string;\n is_error?: boolean | undefined;\n}\n\nexport interface ImageBlock {\n type: 'image';\n source: {\n type: 'base64' | 'url';\n media_type?: string | undefined;\n data?: string | undefined;\n url?: string | undefined;\n };\n}\n\n/**\n * Chain-of-thought / extended-thinking content emitted by the model.\n *\n * Both Anthropic extended thinking (`{type:'thinking', thinking, signature}`)\n * and DeepSeek reasoning mode (top-level `reasoning_content` on the assistant\n * message) require this content to be echoed back verbatim on the next\n * request, otherwise the provider returns 400:\n * - Anthropic: \"The `content[].thinking` in the thinking mode must be passed back\"\n * - DeepSeek: \"The `reasoning_content` in the thinking mode must be passed back\"\n *\n * `signature` is Anthropic-specific (an opaque integrity blob). DeepSeek\n * doesn't issue a signature — the field is absent for that provider.\n *\n * Per Anthropic, thinking blocks MUST appear before any text/tool_use blocks\n * in an assistant message. Stream builders preserve that order.\n */\nexport interface ThinkingBlock {\n type: 'thinking';\n thinking: string;\n signature?: string | undefined;\n providerMeta?: Record<string, unknown>;\n}\n\nexport type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock | ThinkingBlock;\n\nexport function isTextBlock(b: ContentBlock): b is TextBlock {\n return b.type === 'text';\n}\nexport function isToolUseBlock(b: ContentBlock): b is ToolUseBlock {\n return b.type === 'tool_use';\n}\nexport function isToolResultBlock(b: ContentBlock): b is ToolResultBlock {\n return b.type === 'tool_result';\n}\nexport function isImageBlock(b: ContentBlock): b is ImageBlock {\n return b.type === 'image';\n}\nexport function isThinkingBlock(b: ContentBlock): b is ThinkingBlock {\n return b.type === 'thinking';\n}\n","import { isTextBlock } from '../types/blocks.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { Provider, Request } from '../types/provider.js';\n\n/**\n * Prompt refinement (\"did you mean this?\").\n *\n * Runs a one-shot LLM call in a SEPARATE context (its own system prompt, no\n * conversation history, no tools) that rewrites a raw user message into a\n * clearer, more complete instruction BEFORE the main agent sees it. The goal\n * is to make the main context start from a well-understood request rather than\n * guessing intent from terse input like \"fix the bug\".\n *\n * This mirrors `IntelligentCompactor.callSummarizer` — a plain\n * `provider.complete()` with a dedicated system prompt — and is deliberately\n * free of React / TUI dependencies so it can be unit-tested in isolation.\n */\n\nexport const ENHANCER_SYSTEM_PROMPT = `You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into clearer, unambiguous instructions that the coding agent can act on confidently.\n\nRules:\n- Preserve the user's intent and scope EXACTLY. Do not add new requirements, features, constraints, or steps the user did not ask for. Do not remove anything they did ask for.\n- Do NOT answer, solve, or perform the request. Only restate it more clearly.\n- Keep all concrete details verbatim: file paths, identifiers, code, error text, numbers, names, URLs.\n- Resolve obvious ambiguity by making the implied subject explicit, not by inventing specifics. If something is genuinely unspecified, leave it general rather than guessing.\n- Be concise: one tight instruction per version (a few sentences at most). No preamble, no explanation, no quotes, no markdown headers.\n- If the message is already clear and complete, return it essentially unchanged.\n\nYou MUST output TWO versions of the refined request, separated by a line containing only \"---\".\n- First version: refined in the SAME LANGUAGE the user wrote in (if Turkish → Turkish, if Spanish → Spanish, etc.).\n- Second version: refined in ENGLISH (translate the intent into clear English while preserving all concrete details).\n\nOutput format:\n<refined in user's language>\n---\n<refined in English>\n\nWhen earlier conversation turns are provided, they are CONTEXT ONLY. Use them to resolve references in the user's latest message — \"it\", \"that\", \"the same\", \"the other one\", \"this file\", \"again\" — so the refined instruction is self-contained. Refine ONLY the user's latest message; do not answer it, do not act on or restate earlier turns, and do not summarize the conversation.\n\nOutput ONLY the two versions separated by \"---\" — nothing else.`;\n\n/** Words/phrases that are control answers, not refinable requests. */\nconst AFFIRMATION_RE =\n /^(y|n|yes|no|yep|nope|ok|okay|sure|go|go ahead|continue|proceed|stop|cancel|done|next|skip|retry|again|please do|do it)\\b[.! ]*$/i;\n\n/**\n * Heuristic gate: should this raw input be sent through the refiner at all?\n * Pure + exported for unit testing. Returns false for inputs where refinement\n * is pointless or unwanted (slash commands, one-word affirmations, trivially\n * short text, bare numbers).\n */\nexport function shouldEnhance(text: string): boolean {\n const t = text.trim();\n if (!t) return false;\n if (t.startsWith('/')) return false; // slash command\n if (t.length < 12) return false; // too short to be worth refining\n if (AFFIRMATION_RE.test(t)) return false; // \"yes\" / \"continue\" / ...\n if (/^[\\d\\s.,]+$/.test(t)) return false; // bare numbers (menu picks, etc.)\n const words = t.split(/\\s+/).filter(Boolean);\n if (words.length < 3) return false; // 1–2 words rarely benefit\n return true;\n}\n\n/**\n * Normalize for \"did the refiner actually change anything?\" comparison —\n * collapse whitespace and lowercase so trivial reformatting doesn't trigger\n * the confirmation panel.\n */\nexport function normalizedEqual(a: string, b: string): boolean {\n const norm = (s: string) => s.trim().replace(/\\s+/g, ' ').toLowerCase();\n return norm(a) === norm(b);\n}\n\n/** A single text-only conversation turn used as refiner context. */\nexport interface ConversationTurn {\n role: 'user' | 'assistant';\n text: string;\n}\n\n/**\n * Result of a successful prompt refinement. Contains both the\n * original-language and English versions so the UI can offer both.\n */\nexport interface EnhanceResult {\n /** Refined in the user's original language. */\n refined: string;\n /** Refined in English. */\n english: string;\n}\n\nexport interface EnhanceUserPromptOptions {\n provider: Provider;\n model: string;\n text: string;\n /**\n * Recent conversation turns (oldest→newest), text only, used purely as\n * CONTEXT so the refiner can resolve references in a follow-up message\n * (\"it\", \"the same\", \"that file\"). Without this, the refiner is blind to\n * the conversation and can only refine self-contained prompts. Build with\n * `recentTextTurns(ctx.messages)`.\n */\n history?: ConversationTurn[] | undefined;\n /** Parent abort signal (e.g. the run controller / Esc). */\n signal?: AbortSignal | undefined;\n /** Hard cap on how long to wait for the refiner before giving up. Default 90s. */\n timeoutMs?: number | undefined;\n /** Max tokens for the refined output. Default 2048. */\n maxTokens?: number | undefined;\n /**\n * Called with a short reason when refinement fails (provider error, timeout,\n * empty response). NOT called when the caller cancels via `signal`. Lets the\n * UI surface *why* a refine fell through instead of a generic message.\n */\n onError?: ((reason: string) => void) | undefined;\n}\n\n/**\n * Compose the single user message sent to the refiner: the recent\n * conversation embedded as plain text (so we never trip provider\n * role-alternation rules) followed by the latest message to refine.\n */\nfunction buildRefinerInput(text: string, history?: ConversationTurn[]): string {\n if (!history || history.length === 0) return text;\n const lines = history.map((t) => `${t.role === 'user' ? 'User' : 'Assistant'}: ${t.text}`);\n return [\n 'Recent conversation (context only — do not act on it):',\n ...lines,\n '',\n 'Latest message to refine:',\n text,\n ].join('\\n');\n}\n\n/**\n * Refine a raw user prompt. Returns the refined text, or `null` when the\n * caller should fall back to the original (refiner errored, timed out, was\n * aborted, or returned nothing useful). NEVER throws — refinement is a\n * best-effort convenience and must never block the user from sending.\n */\nexport async function enhanceUserPrompt(\n opts: EnhanceUserPromptOptions,\n): Promise<EnhanceResult | null> {\n const { provider, model, text } = opts;\n // Reasoning models (\"thinking\" models like DeepSeek reasoner / o1) take\n // longer to first token, so give a generous default window.\n const timeoutMs = opts.timeoutMs ?? 90000;\n // Generous default: on some endpoints the model's hidden \"thinking\" tokens\n // count against this budget, so a small cap can leave NO room for the actual\n // refined text (→ empty completion → null). 2048 keeps the output room ample.\n const maxTokens = opts.maxTokens ?? 2048;\n\n const req: Request = {\n model,\n system: [{ type: 'text', text: ENHANCER_SYSTEM_PROMPT }],\n messages: [{ role: 'user', content: buildRefinerInput(text, opts.history) }],\n maxTokens,\n // NOTE: deliberately NO `temperature`. The main agent loop never sets it,\n // and reasoning models (DeepSeek reasoner, o1/o3, …) return HTTP 400 when\n // `temperature` is present — which would make every refine call fail and\n // silently fall back to the original (no panel shown).\n };\n\n // Link a local timeout to the parent signal so a stuck provider call can't\n // hang the submit path. AbortSignal.any keeps both cancellation sources.\n const timer = new AbortController();\n const to = setTimeout(() => timer.abort(new Error('enhancer timeout')), timeoutMs);\n const signal = opts.signal\n ? AbortSignal.any([opts.signal, timer.signal])\n : timer.signal;\n\n try {\n const res = await provider.complete(req, { signal });\n const raw = res.content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join('\\n')\n .trim();\n if (!raw) {\n opts.onError?.('model returned no text');\n return null;\n }\n\n // The model outputs two versions separated by a line with only \"---\".\n // Split on the first occurrence so the delimiter can appear in the text.\n const sepIdx = raw.indexOf('\\n---\\n');\n if (sepIdx === -1) {\n // Model didn't follow the format — treat the whole response as a\n // single refined version (best-effort fallback).\n opts.onError?.('model did not produce two versions');\n return { refined: raw, english: raw };\n }\n const refined = raw.slice(0, sepIdx).trim();\n const english = raw.slice(sepIdx + 5).trim(); // skip \"\\n---\\n\"\n if (!refined || !english) {\n opts.onError?.('one or both versions empty');\n return null;\n }\n return { refined, english };\n } catch (err) {\n // User-initiated cancel → stay silent (they chose to send the original).\n if (opts.signal?.aborted) return null;\n if (timer.signal.aborted) {\n opts.onError?.(`timed out after ${Math.round(timeoutMs / 1000)}s`);\n return null;\n }\n opts.onError?.(err instanceof Error ? err.message : String(err));\n return null;\n } finally {\n clearTimeout(to);\n }\n}\n\n/** Pull the visible text out of a message's content (ignores tool blocks). */\nfunction messageText(content: string | ContentBlock[]): string {\n if (typeof content === 'string') return content;\n return content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join('\\n')\n .trim();\n}\n\n/**\n * Extract the last few user/assistant TEXT turns from a conversation, newest\n * last, for use as refiner context. Skips system messages and tool-only turns\n * (tool_use / tool_result carry no useful natural-language context and bloat\n * the call). Each turn is truncated to `maxChars`; at most `maxTurns` are\n * returned. Pure + exported for unit testing.\n */\nexport function recentTextTurns(\n messages: Message[],\n maxTurns = 6,\n maxChars = 1500,\n): ConversationTurn[] {\n const turns: ConversationTurn[] = [];\n for (let i = messages.length - 1; i >= 0 && turns.length < maxTurns; i--) {\n const m = messages[i];\n if (!m || (m.role !== 'user' && m.role !== 'assistant')) continue;\n const text = messageText(m.content);\n if (!text) continue;\n turns.unshift({\n role: m.role,\n text: text.length > maxChars ? `${text.slice(0, maxChars - 1)}…` : text,\n });\n }\n return turns;\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/blocks.ts","../../src/utils/error.ts","../../src/execution/prompt-enhancer.ts"],"names":[],"mappings":"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","file":"prompt-enhancer.js","sourcesContent":["export interface TextBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' | undefined };\n}\n\nexport interface ToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n /**\n * Provider-specific opaque metadata captured from the wire response.\n * Echoed back verbatim in the next request so providers that bind\n * extra state to function calls keep working. Example: Gemini's\n * `thoughtSignature` — required for tool-use turns with thinking\n * models, otherwise the next request fails with 400 \"Function call\n * is missing a thought_signature in functionCall parts\".\n *\n * Keys are namespaced by intent so multiple wires can coexist:\n * - `google.thoughtSignature` — Gemini signed-thought blob\n * Other providers can add their own keys without colliding.\n */\n providerMeta?: Record<string, unknown>;\n}\n\nexport interface ToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n /**\n * The original tool name. Useful for providers like Google Gemini that\n * need the tool name in `functionResponse.name` — the tool_use_id is\n * only a session-local identifier and is not stable across replays.\n * Always set by ToolExecutor; may be absent on manually-constructed blocks.\n */\n name?: string | undefined;\n content: string;\n is_error?: boolean | undefined;\n}\n\nexport interface ImageBlock {\n type: 'image';\n source: {\n type: 'base64' | 'url';\n media_type?: string | undefined;\n data?: string | undefined;\n url?: string | undefined;\n };\n}\n\n/**\n * Chain-of-thought / extended-thinking content emitted by the model.\n *\n * Both Anthropic extended thinking (`{type:'thinking', thinking, signature}`)\n * and DeepSeek reasoning mode (top-level `reasoning_content` on the assistant\n * message) require this content to be echoed back verbatim on the next\n * request, otherwise the provider returns 400:\n * - Anthropic: \"The `content[].thinking` in the thinking mode must be passed back\"\n * - DeepSeek: \"The `reasoning_content` in the thinking mode must be passed back\"\n *\n * `signature` is Anthropic-specific (an opaque integrity blob). DeepSeek\n * doesn't issue a signature — the field is absent for that provider.\n *\n * Per Anthropic, thinking blocks MUST appear before any text/tool_use blocks\n * in an assistant message. Stream builders preserve that order.\n */\nexport interface ThinkingBlock {\n type: 'thinking';\n thinking: string;\n signature?: string | undefined;\n providerMeta?: Record<string, unknown>;\n}\n\nexport type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock | ThinkingBlock;\n\nexport function isTextBlock(b: ContentBlock): b is TextBlock {\n return b.type === 'text';\n}\nexport function isToolUseBlock(b: ContentBlock): b is ToolUseBlock {\n return b.type === 'tool_use';\n}\nexport function isToolResultBlock(b: ContentBlock): b is ToolResultBlock {\n return b.type === 'tool_result';\n}\nexport function isImageBlock(b: ContentBlock): b is ImageBlock {\n return b.type === 'image';\n}\nexport function isThinkingBlock(b: ContentBlock): b is ThinkingBlock {\n return b.type === 'thinking';\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import { isTextBlock } from '../types/blocks.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { Provider, Request } from '../types/provider.js';\nimport { toErrorMessage } from '../utils/error.js';\n\n/**\n * Prompt refinement (\"did you mean this?\").\n *\n * Runs a one-shot LLM call in a SEPARATE context (its own system prompt, no\n * conversation history, no tools) that rewrites a raw user message into a\n * clearer, more complete instruction BEFORE the main agent sees it. The goal\n * is to make the main context start from a well-understood request rather than\n * guessing intent from terse input like \"fix the bug\".\n *\n * This mirrors `IntelligentCompactor.callSummarizer` — a plain\n * `provider.complete()` with a dedicated system prompt — and is deliberately\n * free of React / TUI dependencies so it can be unit-tested in isolation.\n */\n\nexport const ENHANCER_SYSTEM_PROMPT = `You are a request refiner embedded in a coding agent. Your ONLY job is to rewrite the user's message into clearer, unambiguous instructions that the coding agent can act on confidently.\n\nRules:\n- Preserve the user's intent and scope EXACTLY. Do not add new requirements, features, constraints, or steps the user did not ask for. Do not remove anything they did ask for.\n- Do NOT answer, solve, or perform the request. Only restate it more clearly.\n- Keep all concrete details verbatim: file paths, identifiers, code, error text, numbers, names, URLs.\n- Resolve obvious ambiguity by making the implied subject explicit, not by inventing specifics. If something is genuinely unspecified, leave it general rather than guessing.\n- Be concise: one tight instruction per version (a few sentences at most). No preamble, no explanation, no quotes, no markdown headers.\n- If the message is already clear and complete, return it essentially unchanged.\n\nYou MUST output TWO versions of the refined request, separated by a line containing only \"---\".\n- First version: refined in the SAME LANGUAGE the user wrote in (if Turkish → Turkish, if Spanish → Spanish, etc.).\n- Second version: refined in ENGLISH (translate the intent into clear English while preserving all concrete details).\n\nOutput format:\n<refined in user's language>\n---\n<refined in English>\n\nWhen earlier conversation turns are provided, they are CONTEXT ONLY. Use them to resolve references in the user's latest message — \"it\", \"that\", \"the same\", \"the other one\", \"this file\", \"again\" — so the refined instruction is self-contained. Refine ONLY the user's latest message; do not answer it, do not act on or restate earlier turns, and do not summarize the conversation.\n\nOutput ONLY the two versions separated by \"---\" — nothing else.`;\n\n/** Words/phrases that are control answers, not refinable requests. */\nconst AFFIRMATION_RE =\n /^(y|n|yes|no|yep|nope|ok|okay|sure|go|go ahead|continue|proceed|stop|cancel|done|next|skip|retry|again|please do|do it)\\b[.! ]*$/i;\n\n/**\n * Heuristic gate: should this raw input be sent through the refiner at all?\n * Pure + exported for unit testing. Returns false for inputs where refinement\n * is pointless or unwanted (slash commands, one-word affirmations, trivially\n * short text, bare numbers).\n */\nexport function shouldEnhance(text: string): boolean {\n const t = text.trim();\n if (!t) return false;\n if (t.startsWith('/')) return false; // slash command\n if (t.length < 12) return false; // too short to be worth refining\n if (AFFIRMATION_RE.test(t)) return false; // \"yes\" / \"continue\" / ...\n if (/^[\\d\\s.,]+$/.test(t)) return false; // bare numbers (menu picks, etc.)\n const words = t.split(/\\s+/).filter(Boolean);\n if (words.length < 3) return false; // 1–2 words rarely benefit\n return true;\n}\n\n/**\n * Normalize for \"did the refiner actually change anything?\" comparison —\n * collapse whitespace and lowercase so trivial reformatting doesn't trigger\n * the confirmation panel.\n */\nexport function normalizedEqual(a: string, b: string): boolean {\n const norm = (s: string) => s.trim().replace(/\\s+/g, ' ').toLowerCase();\n return norm(a) === norm(b);\n}\n\n/** A single text-only conversation turn used as refiner context. */\nexport interface ConversationTurn {\n role: 'user' | 'assistant';\n text: string;\n}\n\n/**\n * Result of a successful prompt refinement. Contains both the\n * original-language and English versions so the UI can offer both.\n */\nexport interface EnhanceResult {\n /** Refined in the user's original language. */\n refined: string;\n /** Refined in English. */\n english: string;\n}\n\nexport interface EnhanceUserPromptOptions {\n provider: Provider;\n model: string;\n text: string;\n /**\n * Recent conversation turns (oldest→newest), text only, used purely as\n * CONTEXT so the refiner can resolve references in a follow-up message\n * (\"it\", \"the same\", \"that file\"). Without this, the refiner is blind to\n * the conversation and can only refine self-contained prompts. Build with\n * `recentTextTurns(ctx.messages)`.\n */\n history?: ConversationTurn[] | undefined;\n /** Parent abort signal (e.g. the run controller / Esc). */\n signal?: AbortSignal | undefined;\n /** Hard cap on how long to wait for the refiner before giving up. Default 90s. */\n timeoutMs?: number | undefined;\n /** Max tokens for the refined output. Default 2048. */\n maxTokens?: number | undefined;\n /**\n * Called with a short reason when refinement fails (provider error, timeout,\n * empty response). NOT called when the caller cancels via `signal`. Lets the\n * UI surface *why* a refine fell through instead of a generic message.\n */\n onError?: ((reason: string) => void) | undefined;\n}\n\n/**\n * Compose the single user message sent to the refiner: the recent\n * conversation embedded as plain text (so we never trip provider\n * role-alternation rules) followed by the latest message to refine.\n */\nfunction buildRefinerInput(text: string, history?: ConversationTurn[]): string {\n if (!history || history.length === 0) return text;\n const lines = history.map((t) => `${t.role === 'user' ? 'User' : 'Assistant'}: ${t.text}`);\n return [\n 'Recent conversation (context only — do not act on it):',\n ...lines,\n '',\n 'Latest message to refine:',\n text,\n ].join('\\n');\n}\n\n/**\n * Refine a raw user prompt. Returns the refined text, or `null` when the\n * caller should fall back to the original (refiner errored, timed out, was\n * aborted, or returned nothing useful). NEVER throws — refinement is a\n * best-effort convenience and must never block the user from sending.\n */\nexport async function enhanceUserPrompt(\n opts: EnhanceUserPromptOptions,\n): Promise<EnhanceResult | null> {\n const { provider, model, text } = opts;\n // Reasoning models (\"thinking\" models like DeepSeek reasoner / o1) take\n // longer to first token, so give a generous default window.\n const timeoutMs = opts.timeoutMs ?? 90000;\n // Generous default: on some endpoints the model's hidden \"thinking\" tokens\n // count against this budget, so a small cap can leave NO room for the actual\n // refined text (→ empty completion → null). 2048 keeps the output room ample.\n const maxTokens = opts.maxTokens ?? 2048;\n\n const req: Request = {\n model,\n system: [{ type: 'text', text: ENHANCER_SYSTEM_PROMPT }],\n messages: [{ role: 'user', content: buildRefinerInput(text, opts.history) }],\n maxTokens,\n // NOTE: deliberately NO `temperature`. The main agent loop never sets it,\n // and reasoning models (DeepSeek reasoner, o1/o3, …) return HTTP 400 when\n // `temperature` is present — which would make every refine call fail and\n // silently fall back to the original (no panel shown).\n };\n\n // Link a local timeout to the parent signal so a stuck provider call can't\n // hang the submit path. AbortSignal.any keeps both cancellation sources.\n const timer = new AbortController();\n const to = setTimeout(() => timer.abort(new Error('enhancer timeout')), timeoutMs);\n const signal = opts.signal\n ? AbortSignal.any([opts.signal, timer.signal])\n : timer.signal;\n\n try {\n const res = await provider.complete(req, { signal });\n const raw = res.content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join('\\n')\n .trim();\n if (!raw) {\n opts.onError?.('model returned no text');\n return null;\n }\n\n // The model outputs two versions separated by a line with only \"---\".\n // Split on the first occurrence so the delimiter can appear in the text.\n const sepIdx = raw.indexOf('\\n---\\n');\n if (sepIdx === -1) {\n // Model didn't follow the format — treat the whole response as a\n // single refined version (best-effort fallback).\n opts.onError?.('model did not produce two versions');\n return { refined: raw, english: raw };\n }\n const refined = raw.slice(0, sepIdx).trim();\n const english = raw.slice(sepIdx + 5).trim(); // skip \"\\n---\\n\"\n if (!refined || !english) {\n opts.onError?.('one or both versions empty');\n return null;\n }\n return { refined, english };\n } catch (err) {\n // User-initiated cancel → stay silent (they chose to send the original).\n if (opts.signal?.aborted) return null;\n if (timer.signal.aborted) {\n opts.onError?.(`timed out after ${Math.round(timeoutMs / 1000)}s`);\n return null;\n }\n opts.onError?.(toErrorMessage(err));\n return null;\n } finally {\n // Idempotent — abort() after signal already fired is a no-op, so this is\n // always safe regardless of whether the timeout fired first.\n timer.abort();\n clearTimeout(to);\n }\n}\n\n/** Pull the visible text out of a message's content (ignores tool blocks). */\nfunction messageText(content: string | ContentBlock[]): string {\n if (typeof content === 'string') return content;\n return content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join('\\n')\n .trim();\n}\n\n/**\n * Extract the last few user/assistant TEXT turns from a conversation, newest\n * last, for use as refiner context. Skips system messages and tool-only turns\n * (tool_use / tool_result carry no useful natural-language context and bloat\n * the call). Each turn is truncated to `maxChars`; at most `maxTurns` are\n * returned. Pure + exported for unit testing.\n */\nexport function recentTextTurns(\n messages: Message[],\n maxTurns = 6,\n maxChars = 1500,\n): ConversationTurn[] {\n const turns: ConversationTurn[] = [];\n for (let i = messages.length - 1; i >= 0 && turns.length < maxTurns; i--) {\n const m = messages[i];\n if (!m || (m.role !== 'user' && m.role !== 'assistant')) continue;\n const text = messageText(m.content);\n if (!text) continue;\n turns.unshift({\n role: m.role,\n text: text.length > maxChars ? `${text.slice(0, maxChars - 1)}…` : text,\n });\n }\n return turns;\n}\n"]}
@@ -1,8 +1,8 @@
1
- export { i as AfterIterationHook, j as AfterRunHook, k as AfterToolExecutionHook, l as AgentExtension, B as BeforeIterationHook, m as BeforeRunHook, n as BeforeToolExecutionHook, E as ExtensionRegistry, O as OnErrorHook, v as ProviderRunnerFn, t as ProviderRunnerWrapper } from '../index-BPcg4N3M.js';
2
- import '../context-JFOVvu6z.js';
1
+ export { i as AfterIterationHook, j as AfterRunHook, k as AfterToolExecutionHook, l as AgentExtension, B as BeforeIterationHook, m as BeforeRunHook, n as BeforeToolExecutionHook, E as ExtensionRegistry, O as OnErrorHook, v as ProviderRunnerFn, t as ProviderRunnerWrapper } from '../index-CEDeNodM.js';
2
+ import '../context-MRk5PhNv.js';
3
3
  import '../logger-B63L5bTg.js';
4
- import '../pipeline-zflkI2dp.js';
5
- import '../config-FG6As4H5.js';
4
+ import '../pipeline-DPDxH_7m.js';
5
+ import '../config-BMCj_XDs.js';
6
6
  import '../observability-D-HZN_mF.js';
7
- import '../brain-C2yDd7Lw.js';
8
- import '../permission-BJ7eO9Vl.js';
7
+ import '../brain-BXd_61kQ.js';
8
+ import '../permission-B9SB45lp.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/expect-defined.ts","../../src/types/errors.ts","../../src/extension/registry.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = err instanceof Error ? err.message : String(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import { expectDefined } from '../utils/expect-defined.js';\n/**\n * ExtensionRegistry — manages AgentExtension registrations.\n *\n * Extensions are called in registration order at each lifecycle phase.\n * Each extension hook failure is caught and logged independently so\n * one bad extension can't take down the agent.\n */\n\nimport type { TextBlock } from '../types/blocks.js';\nimport { WrongStackError, ERROR_CODES } from '../types/errors.js';\nimport type { Logger } from '../types/logger.js';\nimport type { SystemPromptContributor } from '../types/system-prompt-contributor.js';\nimport type {\n AfterIterationHook,\n AfterRunHook,\n AfterToolExecutionHook,\n AgentExtension,\n BeforeIterationHook,\n BeforeRunHook,\n BeforeToolExecutionHook,\n OnErrorHook,\n ProviderRunnerFn,\n} from './extension-points.js';\nexport class ExtensionRegistry {\n private readonly extensions: AgentExtension[] = [];\n private readonly promptContributors: SystemPromptContributor[] = [];\n private log: Logger | undefined;\n\n setLogger(log: Logger): void {\n this.log = log;\n }\n\n /**\n * Register a system prompt contributor. Returns an unregister function.\n * Contributors are called on every system prompt build in registration\n * order. Their output blocks are inserted after the core environment\n * block, before the mode and plan blocks.\n */\n registerSystemPromptContributor(c: SystemPromptContributor): () => void {\n this.promptContributors.push(c);\n return () => {\n const idx = this.promptContributors.indexOf(c);\n if (idx >= 0) this.promptContributors.splice(idx, 1);\n };\n }\n\n /**\n * Build all registered system prompt contributions.\n * Failures are caught and logged — one bad contributor doesn't\n * break the prompt assembly.\n */\n async buildSystemPromptContributions(\n ctx: Parameters<SystemPromptContributor>[0],\n ): Promise<TextBlock[]> {\n const blocks: TextBlock[] = [];\n // Snapshot before iterating so mid-iteration registration doesn't cause\n // skipped or duplicate contributor invocations during this phase.\n const snapshot = [...this.promptContributors];\n for (const c of snapshot) {\n try {\n const contributed = await c(ctx);\n blocks.push(...contributed);\n } catch (err) {\n this.log?.error('SystemPromptContributor failed', err);\n }\n }\n return blocks;\n }\n\n /**\n * Returns the live array of contributors (readonly snapshot for\n * passing to DefaultSystemPromptBuilder at build time).\n */\n listSystemPromptContributors(): readonly SystemPromptContributor[] {\n return this.promptContributors;\n }\n\n /**\n * Register an extension. Duplicate names are rejected.\n * Returns an unregister function.\n */\n register(ext: AgentExtension): () => void {\n if (this.extensions.some((e) => e.name === ext.name)) {\n throw new WrongStackError({\n message: `Extension \"${ext.name}\" already registered`,\n code: ERROR_CODES.REGISTRY_DUPLICATE,\n subsystem: 'container',\n context: { extension: ext.name },\n });\n }\n this.extensions.push(ext);\n return () => this.unregister(ext.name);\n }\n\n /**\n * Register an extension, silently replacing any previous registration\n * with the same name. Use this when overriding a default extension.\n */\n registerOrReplace(ext: AgentExtension): () => void {\n const idx = this.extensions.findIndex((e) => e.name === ext.name);\n if (idx >= 0) this.extensions.splice(idx, 1);\n return this.register(ext);\n }\n\n /**\n * Unregister an extension by name. Returns true if found.\n */\n unregister(name: string): boolean {\n const idx = this.extensions.findIndex((e) => e.name === name);\n if (idx === -1) return false;\n this.extensions.splice(idx, 1);\n return true;\n }\n\n /**\n * List registered extension names in order.\n */\n list(): readonly string[] {\n return this.extensions.map((e) => e.name);\n }\n\n /**\n * Check if an extension with the given name is registered.\n */\n has(name: string): boolean {\n return this.extensions.some((e) => e.name === name);\n }\n\n /**\n * Remove all registered extensions and contributors.\n */\n clear(): void {\n this.extensions.length = 0;\n this.promptContributors.length = 0;\n }\n\n // ── Hook runners ─────────────────────────────────────────────────\n\n async runBeforeRun(...args: Parameters<BeforeRunHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.beforeRun) continue;\n try {\n await ext.beforeRun(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" beforeRun hook failed`, err);\n }\n }\n }\n\n async runAfterRun(...args: Parameters<AfterRunHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.afterRun) continue;\n try {\n await ext.afterRun(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" afterRun hook failed`, err);\n }\n }\n }\n\n async runBeforeIteration(...args: Parameters<BeforeIterationHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.beforeIteration) continue;\n try {\n await ext.beforeIteration(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" beforeIteration hook failed`, err);\n }\n }\n }\n\n async runAfterIteration(...args: Parameters<AfterIterationHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.afterIteration) continue;\n try {\n await ext.afterIteration(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" afterIteration hook failed`, err);\n }\n }\n }\n\n /**\n * Run onError hooks in order. The first hook that returns a non-void\n * result wins; subsequent hooks are skipped.\n */\n async runOnError(\n ...args: Parameters<OnErrorHook>\n ): Promise<\n { action: 'retry'; model?: string | undefined } | { action: 'fail' } | { action: 'continue' } | void\n > {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.onError) continue;\n try {\n const result = await ext.onError(...args);\n if (result) return result;\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" onError hook failed`, err);\n }\n }\n }\n\n /**\n * Build a composed provider runner. Extensions with `wrapProviderRunner`\n * form a middleware-style chain: the innermost extension wraps the\n * default runner, each subsequent wrapper wraps the previous.\n */\n wrapProviderRunner(inner: ProviderRunnerFn): ProviderRunnerFn {\n const wrappers = this.extensions\n .filter((e) => e.wrapProviderRunner)\n .map((e) => ({ name: e.name, wrap: expectDefined(e.wrapProviderRunner) }));\n\n if (wrappers.length === 0) return inner;\n\n // Build chain from innermost to outermost\n let composed: ProviderRunnerFn = inner;\n for (let i = wrappers.length - 1; i >= 0; i--) {\n const wrapper = wrappers[i];\n if (!wrapper) continue;\n const next = composed;\n composed = async (ctx, req) => {\n try {\n return await wrapper.wrap(ctx, req, next);\n } catch (err) {\n this.log?.error(`Extension \"${wrapper.name}\" wrapProviderRunner failed`, err);\n throw err;\n }\n };\n }\n return composed;\n }\n\n async runBeforeToolExecution(\n ...args: Parameters<BeforeToolExecutionHook>\n ): Promise<Parameters<BeforeToolExecutionHook>[1]> {\n let toolUses = args[1];\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.beforeToolExecution) continue;\n try {\n toolUses = await ext.beforeToolExecution(args[0], toolUses);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" beforeToolExecution hook failed`, err);\n }\n }\n return toolUses;\n }\n\n async runAfterToolExecution(...args: Parameters<AfterToolExecutionHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.afterToolExecution) continue;\n try {\n await ext.afterToolExecution(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" afterToolExecution hook failed`, err);\n }\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/expect-defined.ts","../../src/types/errors.ts","../../src/extension/registry.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import { expectDefined } from '../utils/expect-defined.js';\n/**\n * ExtensionRegistry — manages AgentExtension registrations.\n *\n * Extensions are called in registration order at each lifecycle phase.\n * Each extension hook failure is caught and logged independently so\n * one bad extension can't take down the agent.\n */\n\nimport type { TextBlock } from '../types/blocks.js';\nimport { WrongStackError, ERROR_CODES } from '../types/errors.js';\nimport type { Logger } from '../types/logger.js';\nimport type { SystemPromptContributor } from '../types/system-prompt-contributor.js';\nimport type {\n AfterIterationHook,\n AfterRunHook,\n AfterToolExecutionHook,\n AgentExtension,\n BeforeIterationHook,\n BeforeRunHook,\n BeforeToolExecutionHook,\n OnErrorHook,\n ProviderRunnerFn,\n} from './extension-points.js';\nexport class ExtensionRegistry {\n private readonly extensions: AgentExtension[] = [];\n private readonly promptContributors: SystemPromptContributor[] = [];\n private log: Logger | undefined;\n\n setLogger(log: Logger): void {\n this.log = log;\n }\n\n /**\n * Register a system prompt contributor. Returns an unregister function.\n * Contributors are called on every system prompt build in registration\n * order. Their output blocks are inserted after the core environment\n * block, before the mode and plan blocks.\n */\n registerSystemPromptContributor(c: SystemPromptContributor): () => void {\n this.promptContributors.push(c);\n return () => {\n const idx = this.promptContributors.indexOf(c);\n if (idx >= 0) this.promptContributors.splice(idx, 1);\n };\n }\n\n /**\n * Build all registered system prompt contributions.\n * Failures are caught and logged — one bad contributor doesn't\n * break the prompt assembly.\n */\n async buildSystemPromptContributions(\n ctx: Parameters<SystemPromptContributor>[0],\n ): Promise<TextBlock[]> {\n const blocks: TextBlock[] = [];\n // Snapshot before iterating so mid-iteration registration doesn't cause\n // skipped or duplicate contributor invocations during this phase.\n const snapshot = [...this.promptContributors];\n for (const c of snapshot) {\n try {\n const contributed = await c(ctx);\n blocks.push(...contributed);\n } catch (err) {\n this.log?.error('SystemPromptContributor failed', err);\n }\n }\n return blocks;\n }\n\n /**\n * Returns the live array of contributors (readonly snapshot for\n * passing to DefaultSystemPromptBuilder at build time).\n */\n listSystemPromptContributors(): readonly SystemPromptContributor[] {\n return this.promptContributors;\n }\n\n /**\n * Register an extension. Duplicate names are rejected.\n * Returns an unregister function.\n */\n register(ext: AgentExtension): () => void {\n if (this.extensions.some((e) => e.name === ext.name)) {\n throw new WrongStackError({\n message: `Extension \"${ext.name}\" already registered`,\n code: ERROR_CODES.REGISTRY_DUPLICATE,\n subsystem: 'container',\n context: { extension: ext.name },\n });\n }\n this.extensions.push(ext);\n return () => this.unregister(ext.name);\n }\n\n /**\n * Register an extension, silently replacing any previous registration\n * with the same name. Use this when overriding a default extension.\n */\n registerOrReplace(ext: AgentExtension): () => void {\n const idx = this.extensions.findIndex((e) => e.name === ext.name);\n if (idx >= 0) this.extensions.splice(idx, 1);\n return this.register(ext);\n }\n\n /**\n * Unregister an extension by name. Returns true if found.\n */\n unregister(name: string): boolean {\n const idx = this.extensions.findIndex((e) => e.name === name);\n if (idx === -1) return false;\n this.extensions.splice(idx, 1);\n return true;\n }\n\n /**\n * List registered extension names in order.\n */\n list(): readonly string[] {\n return this.extensions.map((e) => e.name);\n }\n\n /**\n * Check if an extension with the given name is registered.\n */\n has(name: string): boolean {\n return this.extensions.some((e) => e.name === name);\n }\n\n /**\n * Remove all registered extensions and contributors.\n */\n clear(): void {\n this.extensions.length = 0;\n this.promptContributors.length = 0;\n }\n\n // ── Hook runners ─────────────────────────────────────────────────\n\n async runBeforeRun(...args: Parameters<BeforeRunHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.beforeRun) continue;\n try {\n await ext.beforeRun(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" beforeRun hook failed`, err);\n }\n }\n }\n\n async runAfterRun(...args: Parameters<AfterRunHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.afterRun) continue;\n try {\n await ext.afterRun(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" afterRun hook failed`, err);\n }\n }\n }\n\n async runBeforeIteration(...args: Parameters<BeforeIterationHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.beforeIteration) continue;\n try {\n await ext.beforeIteration(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" beforeIteration hook failed`, err);\n }\n }\n }\n\n async runAfterIteration(...args: Parameters<AfterIterationHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.afterIteration) continue;\n try {\n await ext.afterIteration(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" afterIteration hook failed`, err);\n }\n }\n }\n\n /**\n * Run onError hooks in order. The first hook that returns a non-void\n * result wins; subsequent hooks are skipped.\n */\n async runOnError(\n ...args: Parameters<OnErrorHook>\n ): Promise<\n { action: 'retry'; model?: string | undefined } | { action: 'fail' } | { action: 'continue' } | void\n > {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.onError) continue;\n try {\n const result = await ext.onError(...args);\n if (result) return result;\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" onError hook failed`, err);\n }\n }\n }\n\n /**\n * Build a composed provider runner. Extensions with `wrapProviderRunner`\n * form a middleware-style chain: the innermost extension wraps the\n * default runner, each subsequent wrapper wraps the previous.\n */\n wrapProviderRunner(inner: ProviderRunnerFn): ProviderRunnerFn {\n const wrappers = this.extensions\n .filter((e) => e.wrapProviderRunner)\n .map((e) => ({ name: e.name, wrap: expectDefined(e.wrapProviderRunner) }));\n\n if (wrappers.length === 0) return inner;\n\n // Build chain from innermost to outermost\n let composed: ProviderRunnerFn = inner;\n for (let i = wrappers.length - 1; i >= 0; i--) {\n const wrapper = wrappers[i];\n if (!wrapper) continue;\n const next = composed;\n composed = async (ctx, req) => {\n try {\n return await wrapper.wrap(ctx, req, next);\n } catch (err) {\n this.log?.error(`Extension \"${wrapper.name}\" wrapProviderRunner failed`, err);\n throw err;\n }\n };\n }\n return composed;\n }\n\n async runBeforeToolExecution(\n ...args: Parameters<BeforeToolExecutionHook>\n ): Promise<Parameters<BeforeToolExecutionHook>[1]> {\n let toolUses = args[1];\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.beforeToolExecution) continue;\n try {\n toolUses = await ext.beforeToolExecution(args[0], toolUses);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" beforeToolExecution hook failed`, err);\n }\n }\n return toolUses;\n }\n\n async runAfterToolExecution(...args: Parameters<AfterToolExecutionHook>): Promise<void> {\n const snapshot = [...this.extensions];\n for (const ext of snapshot) {\n if (!ext.afterToolExecution) continue;\n try {\n await ext.afterToolExecution(...args);\n } catch (err) {\n this.log?.error(`Extension \"${ext.name}\" afterToolExecution hook failed`, err);\n }\n }\n }\n}\n"]}
@@ -1,14 +1,14 @@
1
1
  import { S as SkillLoader, a as SkillManifest, b as SkillEntry } from './skill-DGIXCtdv.js';
2
- import { W as WstackPaths } from './wstack-paths-CJjEwPXn.js';
3
- import { P as Provider, C as Context } from './context-JFOVvu6z.js';
4
- import { C as Compactor, a as CompactReport } from './compactor-t0R_AIt_.js';
5
- import { M as MessageSelector } from './selector-B7AivHsu.js';
6
- import { E as EventBus } from './brain-C2yDd7Lw.js';
7
- import { M as MiddlewareHandler } from './pipeline-zflkI2dp.js';
8
- import { S as SessionEventBridge } from './session-event-bridge-BmIDxdJd.js';
9
- import { C as ContextWindowAggressiveOn, g as ContextWindowPolicy } from './config-FG6As4H5.js';
10
- import { g as Agent, D as DoneCondition } from './agent-subagent-runner-BNIGZx18.js';
11
- import { R as RunResult, S as SystemPromptContributor } from './index-BPcg4N3M.js';
2
+ import { W as WstackPaths } from './wstack-paths-hOpNLmvf.js';
3
+ import { P as Provider, C as Context } from './context-MRk5PhNv.js';
4
+ import { C as Compactor, a as CompactReport } from './compactor-B8pOf45Y.js';
5
+ import { M as MessageSelector } from './selector-CzHh_igB.js';
6
+ import { E as EventBus } from './brain-BXd_61kQ.js';
7
+ import { M as MiddlewareHandler } from './pipeline-DPDxH_7m.js';
8
+ import { S as SessionEventBridge } from './session-event-bridge-BUI6Jf-4.js';
9
+ import { C as ContextWindowAggressiveOn, g as ContextWindowPolicy } from './config-BMCj_XDs.js';
10
+ import { g as Agent, D as DoneCondition } from './agent-subagent-runner-DM2pP-B6.js';
11
+ import { R as RunResult, S as SystemPromptContributor } from './index-CEDeNodM.js';
12
12
 
13
13
  interface SkillLoaderOptions {
14
14
  paths: WstackPaths;
@@ -121,6 +121,8 @@ interface SelectiveCompactorOptions {
121
121
  eliseThreshold?: number | undefined;
122
122
  /** Model for selector LLM calls (default: same as provider default). */
123
123
  selectorModel?: string | undefined;
124
+ /** Max output tokens for the selector LLM call (default: 1024). */
125
+ selectorMaxOutputTokens?: number | undefined;
124
126
  /** Summarizer model for collapsed ranges (default: same as selectorModel). */
125
127
  summarizerModel?: string | undefined;
126
128
  /** Prompt for the summarizer sub-LLM. */
@@ -198,6 +200,8 @@ interface StrategyCompactorOptions {
198
200
  smart?: boolean | undefined;
199
201
  /** Model used by the LLM-backed strategies for summarization/selection. */
200
202
  summarizerModel?: string | undefined;
203
+ /** Max output tokens for the selector LLM call in 'selective' strategy (default: 1024). */
204
+ selectorMaxOutputTokens?: number | undefined;
201
205
  /**
202
206
  * Legacy shortcut for `strategy: 'selective'`. When `strategy` is unset (or
203
207
  * 'hybrid') and this is true, the selective (LLM-driven) compactor is used.
@@ -248,6 +252,12 @@ declare class AutoCompactionMiddleware {
248
252
  private readonly hardThreshold;
249
253
  /** Writable so model-switch can update the denominator without re-registering the middleware. */
250
254
  private _maxContext;
255
+ /**
256
+ * Runtime on/off gate. The middleware is always installed in the pipeline so
257
+ * auto-compaction can be toggled live from the TUI `/settings` picker; when
258
+ * disabled the handler is a pass-through. Defaults to enabled.
259
+ */
260
+ private _enabled;
251
261
  private readonly aggressiveOn;
252
262
  private readonly events?;
253
263
  private readonly failureMode;
@@ -294,6 +304,12 @@ declare class AutoCompactionMiddleware {
294
304
  /** Allow callers (e.g. model-switch in WebUI) to update the context window
295
305
  * denominator when the active model changes. */
296
306
  setMaxContext(maxContext: number): void;
307
+ /** Whether auto-compaction is currently active. */
308
+ get enabled(): boolean;
309
+ /** Toggle auto-compaction on a live session (TUI `/settings`). When disabled
310
+ * the middleware passes every iteration straight through without estimating
311
+ * tokens or compacting. */
312
+ setEnabled(enabled: boolean): void;
297
313
  handler(): MiddlewareHandler<Context>;
298
314
  /**
299
315
  * H1: try to read a pre-computed token total from `ctx.lastRequestTokens`
@@ -1,4 +1,4 @@
1
- import { E as EventBus } from './brain-C2yDd7Lw.js';
1
+ import { E as EventBus } from './brain-BXd_61kQ.js';
2
2
 
3
3
  /**
4
4
  * Long-running autonomous mission. A goal survives across sessions and
@@ -1,15 +1,15 @@
1
- import { T as Token, a as Renderer, S as SystemPromptBuilder, H as HookRegistry } from './pipeline-zflkI2dp.js';
2
- import { E as EventBus, l as MemoryStore, B as BrainArbiter } from './brain-C2yDd7Lw.js';
3
- import { C as Compactor } from './compactor-t0R_AIt_.js';
4
- import { j as ConfigLoader, i as ConfigStore, M as ModelsRegistry } from './config-FG6As4H5.js';
5
- import { E as ErrorHandler, R as RetryPolicy } from './retry-policy-Cavrzmtk.js';
1
+ import { T as Token, a as Renderer, S as SystemPromptBuilder, H as HookRegistry } from './pipeline-DPDxH_7m.js';
2
+ import { E as EventBus, c as MemoryStore, B as BrainArbiter } from './brain-BXd_61kQ.js';
3
+ import { C as Compactor } from './compactor-B8pOf45Y.js';
4
+ import { j as ConfigLoader, i as ConfigStore, M as ModelsRegistry } from './config-BMCj_XDs.js';
5
+ import { E as ErrorHandler, R as RetryPolicy } from './retry-policy-CN0khdlj.js';
6
6
  import { I as InputReader } from './input-reader-E-ffP2ee.js';
7
7
  import { L as Logger } from './logger-B63L5bTg.js';
8
8
  import { M as ModeStore } from './mode-CZlO9iU1.js';
9
9
  import { P as PathResolver } from './path-resolver-CPRj4bFY.js';
10
- import { P as PermissionPolicy, S as SecretScrubber } from './permission-BJ7eO9Vl.js';
11
- import { P as ProviderRunner } from './provider-runner-BC-uywtT.js';
12
- import { c as TokenCounter, i as SessionStore } from './context-JFOVvu6z.js';
10
+ import { P as PermissionPolicy, S as SecretScrubber } from './permission-B9SB45lp.js';
11
+ import { P as ProviderRunner } from './provider-runner-DMa70ODu.js';
12
+ import { c as TokenCounter, i as SessionStore } from './context-MRk5PhNv.js';
13
13
  import { S as SkillLoader } from './skill-DGIXCtdv.js';
14
14
 
15
15
  /**
@@ -1,10 +1,10 @@
1
- import { n as TextBlock, T as Tool, l as ToolUseBlock, C as Context, m as ToolResultBlock, R as Request, b as Response, P as Provider, g as ContentBlock, a2 as WrongStackError } from './context-JFOVvu6z.js';
1
+ import { n as TextBlock, T as Tool, l as ToolUseBlock, C as Context, m as ToolResultBlock, R as Request, b as Response, P as Provider, g as ContentBlock, a3 as WrongStackError } from './context-MRk5PhNv.js';
2
2
  import { L as Logger } from './logger-B63L5bTg.js';
3
- import { B as BuildContext, H as HookRegistry, a as Renderer, P as Pipeline, C as Container } from './pipeline-zflkI2dp.js';
4
- import { H as HookEvent, W as WireFamily, P as ProviderConfig } from './config-FG6As4H5.js';
3
+ import { B as BuildContext, H as HookRegistry, a as Renderer, P as Pipeline, C as Container } from './pipeline-DPDxH_7m.js';
4
+ import { H as HookEvent, W as WireFamily, P as ProviderConfig } from './config-BMCj_XDs.js';
5
5
  import { T as Tracer } from './observability-D-HZN_mF.js';
6
- import { E as EventBus } from './brain-C2yDd7Lw.js';
7
- import { P as PermissionPolicy, S as SecretScrubber } from './permission-BJ7eO9Vl.js';
6
+ import { E as EventBus } from './brain-BXd_61kQ.js';
7
+ import { P as PermissionPolicy, S as SecretScrubber } from './permission-B9SB45lp.js';
8
8
 
9
9
  /**
10
10
  * A contributor that injects additional TextBlocks into the system prompt.