@wrongstack/core 0.297.0 → 0.298.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 (800) hide show
  1. package/dist/chronicle/index.js +126 -22
  2. package/dist/chronicle/project-server-client.d.ts +12 -0
  3. package/dist/chronicle/project-server-protocol.d.ts +22 -0
  4. package/dist/chronicle/project-server.js +238 -157
  5. package/dist/coordination/agents/index.js +136 -1
  6. package/dist/coordination/agents/role-skills.d.ts +3 -2
  7. package/dist/coordination/brain-trace.d.ts +2 -1
  8. package/dist/coordination/director/director-task-registry.d.ts +12 -0
  9. package/dist/coordination/fleet-supervisor.d.ts +21 -0
  10. package/dist/coordination/index.d.ts +23 -21
  11. package/dist/coordination/index.js +16493 -16068
  12. package/dist/coordination/mail-tools.d.ts +3 -3
  13. package/dist/coordination/mailbox-credential-store.d.ts +22 -2
  14. package/dist/coordination/mailbox-credential-throttle.d.ts +63 -0
  15. package/dist/coordination/mailbox-project-server-client.d.ts +16 -0
  16. package/dist/coordination/mailbox-project-server-protocol.d.ts +43 -5
  17. package/dist/coordination/mailbox-project-server.js +508 -253
  18. package/dist/coordination/provider-status-tracker.d.ts +2 -0
  19. package/dist/coordination/remote-mailbox-credential-store.d.ts +5 -5
  20. package/dist/coordination/remote-mailbox.d.ts +8 -4
  21. package/dist/coordination/sqlite-mailbox-credentials.d.ts +11 -0
  22. package/dist/core/fallback-profile-manager.d.ts +14 -0
  23. package/dist/core/index.js +451 -137
  24. package/dist/core/instruction-bundle.d.ts +12 -0
  25. package/dist/core/system-prompt-builder.d.ts +14 -0
  26. package/dist/core/system-prompt-skill-bodies.d.ts +1 -1
  27. package/dist/core/system-prompt-skill-text.d.ts +1 -2
  28. package/dist/defaults/index.js +2081 -1102
  29. package/dist/design/index.js +47 -8
  30. package/dist/execution/design-materialize.d.ts +22 -0
  31. package/dist/execution/index.js +495 -248
  32. package/dist/execution/skill-loader.d.ts +10 -1
  33. package/dist/execution/tool-error-taxonomy.d.ts +31 -0
  34. package/dist/execution/tool-executor.d.ts +1 -0
  35. package/dist/goal/index.js +3 -1
  36. package/dist/hooks/index.js +5 -0
  37. package/dist/hq/auth-audit.d.ts +6 -0
  38. package/dist/hq/auth-store.d.ts +59 -3
  39. package/dist/hq/index.js +401 -101
  40. package/dist/hq/kanban-store.d.ts +3 -0
  41. package/dist/hq/protocol/core.d.ts +3 -15
  42. package/dist/hq/protocol/envelope.d.ts +29 -0
  43. package/dist/hq/protocol/governance.d.ts +34 -0
  44. package/dist/hq/protocol/project.d.ts +3 -0
  45. package/dist/hq/protocol/resume.d.ts +1 -1
  46. package/dist/hq/protocol.d.ts +9 -8
  47. package/dist/hq/protocol.js +675 -0
  48. package/dist/index.js +8518 -6416
  49. package/dist/infrastructure/index.js +198 -101
  50. package/dist/kernel/events/session-events.d.ts +3 -0
  51. package/dist/kernel/events/tool-events.d.ts +3 -1
  52. package/dist/models/index.js +1 -1
  53. package/dist/observability/index.js +27 -0
  54. package/dist/observability/prometheus.d.ts +11 -0
  55. package/dist/plugin/index.d.ts +5 -1
  56. package/dist/plugin/index.js +950 -509
  57. package/dist/plugins/review-store-maintenance.d.ts +26 -0
  58. package/dist/plugins/review-types.d.ts +6 -0
  59. package/dist/security/capabilities.d.ts +45 -1
  60. package/dist/security/error-sanitize.d.ts +49 -0
  61. package/dist/security/file-permissions.d.ts +41 -0
  62. package/dist/security/index.d.ts +9 -6
  63. package/dist/security/index.js +3007 -2032
  64. package/dist/security/permission-policy.d.ts +55 -3
  65. package/dist/security/secret-vault.d.ts +17 -0
  66. package/dist/security/totp.d.ts +86 -0
  67. package/dist/skills/frontmatter.d.ts +12 -1
  68. package/dist/skills/github-fetcher.d.ts +48 -0
  69. package/dist/skills/index.js +137 -26
  70. package/dist/skills/limits.d.ts +19 -0
  71. package/dist/skills/skill-installer.d.ts +13 -0
  72. package/dist/storage/index.js +928 -732
  73. package/dist/storage/provider-config-watcher.d.ts +1 -0
  74. package/dist/storage/session-helpers.d.ts +1 -0
  75. package/dist/storage/session-store.d.ts +9 -2
  76. package/dist/storage/session-workspace-checkpoints.d.ts +5 -0
  77. package/dist/tools/fallback-manage-tools.d.ts +6 -0
  78. package/dist/tools/index.js +287 -131
  79. package/dist/tools/mcp-use.d.ts +1 -1
  80. package/dist/types/blocks.d.ts +7 -0
  81. package/dist/types/config/autonomy.d.ts +12 -3
  82. package/dist/types/config/mcp-features.d.ts +9 -1
  83. package/dist/types/config/root.d.ts +10 -4
  84. package/dist/types/context-window.d.ts +15 -0
  85. package/dist/types/index.d.ts +1 -1
  86. package/dist/types/secret-vault.d.ts +8 -0
  87. package/dist/types/session.d.ts +2 -0
  88. package/dist/types/skill.d.ts +56 -0
  89. package/dist/types/tool-executor.d.ts +2 -0
  90. package/dist/utils/env-typed.d.ts +64 -0
  91. package/dist/utils/glob-match.d.ts +21 -1
  92. package/dist/utils/heap-watchdog.js +1 -1
  93. package/dist/utils/incoming-images.d.ts +19 -0
  94. package/dist/utils/index.d.ts +15 -12
  95. package/dist/utils/index.js +3083 -2801
  96. package/dist/utils/path-segment.d.ts +29 -0
  97. package/dist/utils/win32-cmd.d.ts +25 -0
  98. package/dist/worktree/index.js +5 -0
  99. package/package.json +8 -3
  100. package/skills/chimera/SKILL.md +16 -4
  101. package/skills/data-governance/SKILL.md +92 -0
  102. package/skills/wrongstack-kanban/SKILL.md +125 -64
  103. package/dist/agent-status-helpers.d.ts.map +0 -1
  104. package/dist/agent-status-tracker.d.ts.map +0 -1
  105. package/dist/boot.d.ts.map +0 -1
  106. package/dist/chronicle/context.d.ts.map +0 -1
  107. package/dist/chronicle/decision-adapter.d.ts.map +0 -1
  108. package/dist/chronicle/domain-adapter.d.ts.map +0 -1
  109. package/dist/chronicle/event-hash.d.ts.map +0 -1
  110. package/dist/chronicle/file-observer.d.ts.map +0 -1
  111. package/dist/chronicle/health-monitor.d.ts.map +0 -1
  112. package/dist/chronicle/identity.d.ts.map +0 -1
  113. package/dist/chronicle/index.d.ts.map +0 -1
  114. package/dist/chronicle/index.js.map +0 -7
  115. package/dist/chronicle/journal.d.ts.map +0 -1
  116. package/dist/chronicle/legacy-journal-import.d.ts.map +0 -1
  117. package/dist/chronicle/metrics-store.d.ts.map +0 -1
  118. package/dist/chronicle/partition-filename.d.ts.map +0 -1
  119. package/dist/chronicle/partition-range-cache.d.ts.map +0 -1
  120. package/dist/chronicle/process-adapter.d.ts.map +0 -1
  121. package/dist/chronicle/project-access.d.ts.map +0 -1
  122. package/dist/chronicle/project-server-client.d.ts.map +0 -1
  123. package/dist/chronicle/project-server-endpoint.d.ts.map +0 -1
  124. package/dist/chronicle/project-server-protocol.d.ts.map +0 -1
  125. package/dist/chronicle/project-server.d.ts.map +0 -1
  126. package/dist/chronicle/project-server.js.map +0 -7
  127. package/dist/chronicle/prompt-manifest.d.ts.map +0 -1
  128. package/dist/chronicle/provider-adapter.d.ts.map +0 -1
  129. package/dist/chronicle/query.d.ts.map +0 -1
  130. package/dist/chronicle/review-adapter.d.ts.map +0 -1
  131. package/dist/chronicle/rollup-adapter.d.ts.map +0 -1
  132. package/dist/chronicle/sink.d.ts.map +0 -1
  133. package/dist/chronicle/sqlite-journal.d.ts.map +0 -1
  134. package/dist/chronicle/sqlite-query.d.ts.map +0 -1
  135. package/dist/chronicle/stream-adapter.d.ts.map +0 -1
  136. package/dist/chronicle/tool-adapter.d.ts.map +0 -1
  137. package/dist/chronicle/types.d.ts.map +0 -1
  138. package/dist/coordination/adaptive-concurrency.d.ts.map +0 -1
  139. package/dist/coordination/agent-bridge.d.ts.map +0 -1
  140. package/dist/coordination/agent-monitor.d.ts.map +0 -1
  141. package/dist/coordination/agent-subagent-runner.d.ts.map +0 -1
  142. package/dist/coordination/agents/agent-prompts.d.ts.map +0 -1
  143. package/dist/coordination/agents/index.d.ts.map +0 -1
  144. package/dist/coordination/agents/index.js.map +0 -7
  145. package/dist/coordination/agents/phase1-discovery.d.ts.map +0 -1
  146. package/dist/coordination/agents/phase2-planning.d.ts.map +0 -1
  147. package/dist/coordination/agents/phase3-build.d.ts.map +0 -1
  148. package/dist/coordination/agents/phase3-techstack.d.ts.map +0 -1
  149. package/dist/coordination/agents/phase3-wave1-platform.d.ts.map +0 -1
  150. package/dist/coordination/agents/phase3-wave2-meta.d.ts.map +0 -1
  151. package/dist/coordination/agents/phase4-verify.d.ts.map +0 -1
  152. package/dist/coordination/agents/phase5-review.d.ts.map +0 -1
  153. package/dist/coordination/agents/phase6-domain.d.ts.map +0 -1
  154. package/dist/coordination/agents/phase7-knowledge.d.ts.map +0 -1
  155. package/dist/coordination/agents/phase8-delivery.d.ts.map +0 -1
  156. package/dist/coordination/agents/phase8-wave3-products.d.ts.map +0 -1
  157. package/dist/coordination/agents/phase9-meta.d.ts.map +0 -1
  158. package/dist/coordination/agents/phase9-wave4-platform-meta.d.ts.map +0 -1
  159. package/dist/coordination/agents/project-agent-config-validation.d.ts.map +0 -1
  160. package/dist/coordination/agents/project-agent-consolidation.d.ts.map +0 -1
  161. package/dist/coordination/agents/project-agent-files.d.ts.map +0 -1
  162. package/dist/coordination/agents/project-agent-identity-types.d.ts.map +0 -1
  163. package/dist/coordination/agents/project-agent-identity.d.ts.map +0 -1
  164. package/dist/coordination/agents/project-agent-knowledge-manifests.d.ts.map +0 -1
  165. package/dist/coordination/agents/project-agent-learning-entries.d.ts.map +0 -1
  166. package/dist/coordination/agents/project-agent-learning-normalize.d.ts.map +0 -1
  167. package/dist/coordination/agents/project-agent-learning-policy.d.ts.map +0 -1
  168. package/dist/coordination/agents/project-agent-learning-structured.d.ts.map +0 -1
  169. package/dist/coordination/agents/project-agent-paths.d.ts.map +0 -1
  170. package/dist/coordination/agents/project-agent-profile.d.ts.map +0 -1
  171. package/dist/coordination/agents/role-skills.d.ts.map +0 -1
  172. package/dist/coordination/agents/types.d.ts.map +0 -1
  173. package/dist/coordination/agents.d.ts.map +0 -1
  174. package/dist/coordination/auto-extend.d.ts.map +0 -1
  175. package/dist/coordination/autonomous-brain.d.ts.map +0 -1
  176. package/dist/coordination/autonomous-coordinator.d.ts.map +0 -1
  177. package/dist/coordination/brain-cache.d.ts.map +0 -1
  178. package/dist/coordination/brain-heuristics.d.ts.map +0 -1
  179. package/dist/coordination/brain-ledger.d.ts.map +0 -1
  180. package/dist/coordination/brain-monitor.d.ts.map +0 -1
  181. package/dist/coordination/brain-rules.d.ts.map +0 -1
  182. package/dist/coordination/brain-telemetry.d.ts.map +0 -1
  183. package/dist/coordination/brain-trace.d.ts.map +0 -1
  184. package/dist/coordination/brain.d.ts.map +0 -1
  185. package/dist/coordination/change-manager.d.ts.map +0 -1
  186. package/dist/coordination/checkpoint-wiring.d.ts.map +0 -1
  187. package/dist/coordination/collab-bus.d.ts.map +0 -1
  188. package/dist/coordination/collab-debug-types.d.ts.map +0 -1
  189. package/dist/coordination/collab-debug.d.ts.map +0 -1
  190. package/dist/coordination/collab-director-host.d.ts.map +0 -1
  191. package/dist/coordination/commit-safety.d.ts.map +0 -1
  192. package/dist/coordination/consensus-protocol.d.ts.map +0 -1
  193. package/dist/coordination/coordinator/error-classifier.d.ts.map +0 -1
  194. package/dist/coordination/delegate-tool.d.ts.map +0 -1
  195. package/dist/coordination/dep-watcher-bridge.d.ts.map +0 -1
  196. package/dist/coordination/dep-watcher.d.ts.map +0 -1
  197. package/dist/coordination/director/director-btw-notes.d.ts.map +0 -1
  198. package/dist/coordination/director/director-budget-policy.d.ts.map +0 -1
  199. package/dist/coordination/director/director-collab.d.ts.map +0 -1
  200. package/dist/coordination/director/director-errors.d.ts.map +0 -1
  201. package/dist/coordination/director/director-task-registry.d.ts.map +0 -1
  202. package/dist/coordination/director/director-toolset.d.ts.map +0 -1
  203. package/dist/coordination/director-basic-tools.d.ts.map +0 -1
  204. package/dist/coordination/director-collab-tools.d.ts.map +0 -1
  205. package/dist/coordination/director-host-contracts.d.ts.map +0 -1
  206. package/dist/coordination/director-input-helpers.d.ts.map +0 -1
  207. package/dist/coordination/director-kanban-queue-helpers.d.ts.map +0 -1
  208. package/dist/coordination/director-options.d.ts.map +0 -1
  209. package/dist/coordination/director-prompts.d.ts.map +0 -1
  210. package/dist/coordination/director-quality-gate-tool.d.ts.map +0 -1
  211. package/dist/coordination/director-session.d.ts.map +0 -1
  212. package/dist/coordination/director-spawn-model.d.ts.map +0 -1
  213. package/dist/coordination/director-tools.d.ts.map +0 -1
  214. package/dist/coordination/director.d.ts.map +0 -1
  215. package/dist/coordination/dispatcher.d.ts.map +0 -1
  216. package/dist/coordination/file-author-tracker.d.ts.map +0 -1
  217. package/dist/coordination/fleet-bus.d.ts.map +0 -1
  218. package/dist/coordination/fleet-event-validation.d.ts.map +0 -1
  219. package/dist/coordination/fleet-manager.d.ts.map +0 -1
  220. package/dist/coordination/fleet-spawn.d.ts.map +0 -1
  221. package/dist/coordination/fleet-status-tool.d.ts.map +0 -1
  222. package/dist/coordination/fleet-supervisor.d.ts.map +0 -1
  223. package/dist/coordination/fleet.d.ts.map +0 -1
  224. package/dist/coordination/global-mailbox-completion.d.ts.map +0 -1
  225. package/dist/coordination/global-mailbox-paths.d.ts.map +0 -1
  226. package/dist/coordination/icoordinator.d.ts.map +0 -1
  227. package/dist/coordination/ifleet-manager.d.ts.map +0 -1
  228. package/dist/coordination/in-memory-transport.d.ts.map +0 -1
  229. package/dist/coordination/index.d.ts.map +0 -1
  230. package/dist/coordination/index.js.map +0 -7
  231. package/dist/coordination/knowledge-graph.d.ts.map +0 -1
  232. package/dist/coordination/large-answer-store.d.ts.map +0 -1
  233. package/dist/coordination/mail-tools.d.ts.map +0 -1
  234. package/dist/coordination/mailbox-actions.d.ts.map +0 -1
  235. package/dist/coordination/mailbox-auth-types.d.ts.map +0 -1
  236. package/dist/coordination/mailbox-codecs.d.ts.map +0 -1
  237. package/dist/coordination/mailbox-constants.d.ts.map +0 -1
  238. package/dist/coordination/mailbox-credential-store.d.ts.map +0 -1
  239. package/dist/coordination/mailbox-events.d.ts.map +0 -1
  240. package/dist/coordination/mailbox-health.d.ts.map +0 -1
  241. package/dist/coordination/mailbox-hooks.d.ts.map +0 -1
  242. package/dist/coordination/mailbox-http-auth.d.ts.map +0 -1
  243. package/dist/coordination/mailbox-http-rate-limit.d.ts.map +0 -1
  244. package/dist/coordination/mailbox-http-router.d.ts.map +0 -1
  245. package/dist/coordination/mailbox-http-validation.d.ts.map +0 -1
  246. package/dist/coordination/mailbox-message-codec.d.ts.map +0 -1
  247. package/dist/coordination/mailbox-parse-state.d.ts.map +0 -1
  248. package/dist/coordination/mailbox-project-server-client.d.ts.map +0 -1
  249. package/dist/coordination/mailbox-project-server-endpoint.d.ts.map +0 -1
  250. package/dist/coordination/mailbox-project-server-protocol.d.ts.map +0 -1
  251. package/dist/coordination/mailbox-project-server.d.ts.map +0 -1
  252. package/dist/coordination/mailbox-project-server.js.map +0 -7
  253. package/dist/coordination/mailbox-receipt-folding.d.ts.map +0 -1
  254. package/dist/coordination/mailbox-registry-codec.d.ts.map +0 -1
  255. package/dist/coordination/mailbox-retention-state.d.ts.map +0 -1
  256. package/dist/coordination/mailbox-status-mappers.d.ts.map +0 -1
  257. package/dist/coordination/mailbox-tool.d.ts.map +0 -1
  258. package/dist/coordination/mailbox-type-properties.d.ts.map +0 -1
  259. package/dist/coordination/mailbox-types.d.ts.map +0 -1
  260. package/dist/coordination/model-matrix.d.ts.map +0 -1
  261. package/dist/coordination/multi-agent-coordinator.d.ts.map +0 -1
  262. package/dist/coordination/multi-agent-timeout.d.ts.map +0 -1
  263. package/dist/coordination/null-fleet-bus.d.ts.map +0 -1
  264. package/dist/coordination/package-author-tracker.d.ts.map +0 -1
  265. package/dist/coordination/package-outdated-watcher.d.ts.map +0 -1
  266. package/dist/coordination/provider-status-tracker.d.ts.map +0 -1
  267. package/dist/coordination/remote-mailbox-credential-store.d.ts.map +0 -1
  268. package/dist/coordination/remote-mailbox.d.ts.map +0 -1
  269. package/dist/coordination/single-instance-mailbox.d.ts.map +0 -1
  270. package/dist/coordination/spawn-budget.d.ts.map +0 -1
  271. package/dist/coordination/sqlite-mailbox-compaction.d.ts.map +0 -1
  272. package/dist/coordination/sqlite-mailbox-credentials.d.ts.map +0 -1
  273. package/dist/coordination/sqlite-mailbox-rows.d.ts.map +0 -1
  274. package/dist/coordination/sqlite-mailbox-schema.d.ts.map +0 -1
  275. package/dist/coordination/sqlite-mailbox.d.ts.map +0 -1
  276. package/dist/coordination/subagent-budget.d.ts.map +0 -1
  277. package/dist/coordination/subagent-nicknames.d.ts.map +0 -1
  278. package/dist/coordination/subagent-result-tool.d.ts.map +0 -1
  279. package/dist/coordination/task-auctioneer.d.ts.map +0 -1
  280. package/dist/coordination/task-dag.d.ts.map +0 -1
  281. package/dist/coordination/techstack-mailbox-consumer.d.ts.map +0 -1
  282. package/dist/coordination/transport.d.ts.map +0 -1
  283. package/dist/coordination/worktree-task-runner.d.ts.map +0 -1
  284. package/dist/core/agent-internals.d.ts.map +0 -1
  285. package/dist/core/agent-loop.d.ts.map +0 -1
  286. package/dist/core/agent-response.d.ts.map +0 -1
  287. package/dist/core/agent-tools.d.ts.map +0 -1
  288. package/dist/core/agent-types.d.ts.map +0 -1
  289. package/dist/core/agent.d.ts.map +0 -1
  290. package/dist/core/btw.d.ts.map +0 -1
  291. package/dist/core/context.d.ts.map +0 -1
  292. package/dist/core/continue-intent.d.ts.map +0 -1
  293. package/dist/core/continue-to-next-iteration.d.ts.map +0 -1
  294. package/dist/core/conversation-state.d.ts.map +0 -1
  295. package/dist/core/fallback-model.d.ts.map +0 -1
  296. package/dist/core/fallback-profile-manager.d.ts.map +0 -1
  297. package/dist/core/fleet-pulse.d.ts.map +0 -1
  298. package/dist/core/index.d.ts.map +0 -1
  299. package/dist/core/index.js.map +0 -7
  300. package/dist/core/input-builder.d.ts.map +0 -1
  301. package/dist/core/instruction-bundle.d.ts.map +0 -1
  302. package/dist/core/iteration-limit.d.ts.map +0 -1
  303. package/dist/core/mailbox-loop.d.ts.map +0 -1
  304. package/dist/core/model-availability-calendar.d.ts.map +0 -1
  305. package/dist/core/model-ref.d.ts.map +0 -1
  306. package/dist/core/model-ref.js.map +0 -7
  307. package/dist/core/modes/brief.d.ts.map +0 -1
  308. package/dist/core/modes/default.d.ts.map +0 -1
  309. package/dist/core/modes/teach.d.ts.map +0 -1
  310. package/dist/core/provider-runner.d.ts.map +0 -1
  311. package/dist/core/queued-messages.d.ts.map +0 -1
  312. package/dist/core/request-provider-binding.d.ts.map +0 -1
  313. package/dist/core/run-env.d.ts.map +0 -1
  314. package/dist/core/streaming-response-builder.d.ts.map +0 -1
  315. package/dist/core/system-prompt-blocks.d.ts.map +0 -1
  316. package/dist/core/system-prompt-builder.d.ts.map +0 -1
  317. package/dist/core/system-prompt-environment-probes.d.ts.map +0 -1
  318. package/dist/core/system-prompt-environment.d.ts.map +0 -1
  319. package/dist/core/system-prompt-memory-skills.d.ts.map +0 -1
  320. package/dist/core/system-prompt-plan.d.ts.map +0 -1
  321. package/dist/core/system-prompt-shell.d.ts.map +0 -1
  322. package/dist/core/system-prompt-skill-bodies.d.ts.map +0 -1
  323. package/dist/core/system-prompt-skill-text.d.ts.map +0 -1
  324. package/dist/defaults/index.d.ts.map +0 -1
  325. package/dist/defaults/index.js.map +0 -7
  326. package/dist/design/index.d.ts.map +0 -1
  327. package/dist/design/index.js.map +0 -7
  328. package/dist/execution/auto-compaction-middleware.d.ts.map +0 -1
  329. package/dist/execution/autonomous-runner.d.ts.map +0 -1
  330. package/dist/execution/autonomy-brain.d.ts.map +0 -1
  331. package/dist/execution/autonomy-prompt-contributor.d.ts.map +0 -1
  332. package/dist/execution/brain-chain.d.ts.map +0 -1
  333. package/dist/execution/brain-circuit.d.ts.map +0 -1
  334. package/dist/execution/brain-evaluation.d.ts.map +0 -1
  335. package/dist/execution/brain-runtime-constants.d.ts.map +0 -1
  336. package/dist/execution/brain-runtime.d.ts.map +0 -1
  337. package/dist/execution/compaction-core.d.ts.map +0 -1
  338. package/dist/execution/compaction-scoring.d.ts.map +0 -1
  339. package/dist/execution/compaction-summary-cache.d.ts.map +0 -1
  340. package/dist/execution/compactor.d.ts.map +0 -1
  341. package/dist/execution/council-brain.d.ts.map +0 -1
  342. package/dist/execution/council-orchestrator.d.ts.map +0 -1
  343. package/dist/execution/council-personas.d.ts.map +0 -1
  344. package/dist/execution/council-profiles.d.ts.map +0 -1
  345. package/dist/execution/council-prompts.d.ts.map +0 -1
  346. package/dist/execution/council-resolution.d.ts.map +0 -1
  347. package/dist/execution/design-color.d.ts.map +0 -1
  348. package/dist/execution/design-detect.d.ts.map +0 -1
  349. package/dist/execution/design-kit-loader.d.ts.map +0 -1
  350. package/dist/execution/design-materialize.d.ts.map +0 -1
  351. package/dist/execution/design-project-store.d.ts.map +0 -1
  352. package/dist/execution/design-tune.d.ts.map +0 -1
  353. package/dist/execution/design-verify.d.ts.map +0 -1
  354. package/dist/execution/enhance-recovery.d.ts.map +0 -1
  355. package/dist/execution/error-handler.d.ts.map +0 -1
  356. package/dist/execution/eternal-autonomy-types.d.ts.map +0 -1
  357. package/dist/execution/eternal-autonomy.d.ts.map +0 -1
  358. package/dist/execution/goal-preamble.d.ts.map +0 -1
  359. package/dist/execution/index.d.ts.map +0 -1
  360. package/dist/execution/index.js.map +0 -7
  361. package/dist/execution/intelligent-compactor.d.ts.map +0 -1
  362. package/dist/execution/model-runtime.d.ts.map +0 -1
  363. package/dist/execution/one-shot-llm.d.ts.map +0 -1
  364. package/dist/execution/parallel-eternal-engine.d.ts.map +0 -1
  365. package/dist/execution/prompt-enhancer.d.ts.map +0 -1
  366. package/dist/execution/prompt-enhancer.js.map +0 -7
  367. package/dist/execution/prompt-loader.d.ts.map +0 -1
  368. package/dist/execution/provider-runner-impl.d.ts.map +0 -1
  369. package/dist/execution/regex-patterns.d.ts.map +0 -1
  370. package/dist/execution/retry-policy.d.ts.map +0 -1
  371. package/dist/execution/selective-compactor.d.ts.map +0 -1
  372. package/dist/execution/skill-loader.d.ts.map +0 -1
  373. package/dist/execution/strategy-compactor.d.ts.map +0 -1
  374. package/dist/execution/subagent-compaction.d.ts.map +0 -1
  375. package/dist/execution/tool-executor-logging.d.ts.map +0 -1
  376. package/dist/execution/tool-executor-results.d.ts.map +0 -1
  377. package/dist/execution/tool-executor-stream.d.ts.map +0 -1
  378. package/dist/execution/tool-executor-support.d.ts.map +0 -1
  379. package/dist/execution/tool-executor.d.ts.map +0 -1
  380. package/dist/extension/extension-points.d.ts.map +0 -1
  381. package/dist/extension/index.d.ts.map +0 -1
  382. package/dist/extension/index.js.map +0 -7
  383. package/dist/extension/registry.d.ts.map +0 -1
  384. package/dist/fleet-notifier.d.ts.map +0 -1
  385. package/dist/goal/checkpoint.d.ts.map +0 -1
  386. package/dist/goal/goal-assessor.d.ts.map +0 -1
  387. package/dist/goal/goal-planner.d.ts.map +0 -1
  388. package/dist/goal/goal-runner.d.ts.map +0 -1
  389. package/dist/goal/index.d.ts.map +0 -1
  390. package/dist/goal/index.js.map +0 -7
  391. package/dist/goal/phase-board-mutations.d.ts.map +0 -1
  392. package/dist/goal/phase-graph-builder.d.ts.map +0 -1
  393. package/dist/goal/phase-orchestrator-integration.d.ts.map +0 -1
  394. package/dist/goal/phase-orchestrator-queries.d.ts.map +0 -1
  395. package/dist/goal/phase-orchestrator-runtime.d.ts.map +0 -1
  396. package/dist/goal/phase-orchestrator-types.d.ts.map +0 -1
  397. package/dist/goal/phase-orchestrator.d.ts.map +0 -1
  398. package/dist/goal/phase-store.d.ts.map +0 -1
  399. package/dist/goal/types.d.ts.map +0 -1
  400. package/dist/hooks/http-executor.d.ts.map +0 -1
  401. package/dist/hooks/index.d.ts.map +0 -1
  402. package/dist/hooks/index.js.map +0 -7
  403. package/dist/hooks/registry.d.ts.map +0 -1
  404. package/dist/hooks/runner.d.ts.map +0 -1
  405. package/dist/hooks/shell-executor.d.ts.map +0 -1
  406. package/dist/hooks/shell-hooks-equal.d.ts.map +0 -1
  407. package/dist/hq/alerts.d.ts.map +0 -1
  408. package/dist/hq/auth-audit.d.ts.map +0 -1
  409. package/dist/hq/auth-store.d.ts.map +0 -1
  410. package/dist/hq/bootstrap-store.d.ts.map +0 -1
  411. package/dist/hq/brain-bridge.d.ts.map +0 -1
  412. package/dist/hq/bridge-context.d.ts.map +0 -1
  413. package/dist/hq/commands.d.ts.map +0 -1
  414. package/dist/hq/cost-bridge.d.ts.map +0 -1
  415. package/dist/hq/exposure.d.ts.map +0 -1
  416. package/dist/hq/factory.d.ts.map +0 -1
  417. package/dist/hq/fleet-bridge.d.ts.map +0 -1
  418. package/dist/hq/index.d.ts.map +0 -1
  419. package/dist/hq/index.js.map +0 -7
  420. package/dist/hq/kanban-store.d.ts.map +0 -1
  421. package/dist/hq/mailbox-mapper.d.ts.map +0 -1
  422. package/dist/hq/persistence/event-log.d.ts.map +0 -1
  423. package/dist/hq/persistence/jsonl-io.d.ts.map +0 -1
  424. package/dist/hq/persistence/simple-log.d.ts.map +0 -1
  425. package/dist/hq/persistence/snapshot-store.d.ts.map +0 -1
  426. package/dist/hq/persistence/timeseries-store.d.ts.map +0 -1
  427. package/dist/hq/persistence.d.ts.map +0 -1
  428. package/dist/hq/protocol/brain.d.ts.map +0 -1
  429. package/dist/hq/protocol/browser.d.ts.map +0 -1
  430. package/dist/hq/protocol/client.d.ts.map +0 -1
  431. package/dist/hq/protocol/core.d.ts.map +0 -1
  432. package/dist/hq/protocol/fleet.d.ts.map +0 -1
  433. package/dist/hq/protocol/kanban.d.ts.map +0 -1
  434. package/dist/hq/protocol/mailbox.d.ts.map +0 -1
  435. package/dist/hq/protocol/mcp.d.ts.map +0 -1
  436. package/dist/hq/protocol/peer.d.ts.map +0 -1
  437. package/dist/hq/protocol/project.d.ts.map +0 -1
  438. package/dist/hq/protocol/resume.d.ts.map +0 -1
  439. package/dist/hq/protocol/session.d.ts.map +0 -1
  440. package/dist/hq/protocol/tool.d.ts.map +0 -1
  441. package/dist/hq/protocol.d.ts.map +0 -1
  442. package/dist/hq/publisher.d.ts.map +0 -1
  443. package/dist/hq/redaction.d.ts.map +0 -1
  444. package/dist/hq/session-bridge.d.ts.map +0 -1
  445. package/dist/hq/tool-bridge.d.ts.map +0 -1
  446. package/dist/hq/transcript-mapper.d.ts.map +0 -1
  447. package/dist/hq/worktree-bridge.d.ts.map +0 -1
  448. package/dist/hq/write-queues.d.ts.map +0 -1
  449. package/dist/index.d.ts.map +0 -1
  450. package/dist/index.js.map +0 -7
  451. package/dist/infrastructure/context-manager.d.ts.map +0 -1
  452. package/dist/infrastructure/index.d.ts.map +0 -1
  453. package/dist/infrastructure/index.js.map +0 -7
  454. package/dist/infrastructure/logger.d.ts.map +0 -1
  455. package/dist/infrastructure/mcp-servers.d.ts.map +0 -1
  456. package/dist/infrastructure/path-resolver.d.ts.map +0 -1
  457. package/dist/infrastructure/provider-cache-ledger.d.ts.map +0 -1
  458. package/dist/infrastructure/token-counter.d.ts.map +0 -1
  459. package/dist/kernel/container.d.ts.map +0 -1
  460. package/dist/kernel/events/agent-events.d.ts.map +0 -1
  461. package/dist/kernel/events/brain-events.d.ts.map +0 -1
  462. package/dist/kernel/events/file-events.d.ts.map +0 -1
  463. package/dist/kernel/events/fleet-events.d.ts.map +0 -1
  464. package/dist/kernel/events/memory-events.d.ts.map +0 -1
  465. package/dist/kernel/events/network-events.d.ts.map +0 -1
  466. package/dist/kernel/events/process-events.d.ts.map +0 -1
  467. package/dist/kernel/events/provider-events.d.ts.map +0 -1
  468. package/dist/kernel/events/sdd-events.d.ts.map +0 -1
  469. package/dist/kernel/events/session-events.d.ts.map +0 -1
  470. package/dist/kernel/events/tool-events.d.ts.map +0 -1
  471. package/dist/kernel/events/worktree-events.d.ts.map +0 -1
  472. package/dist/kernel/events.d.ts.map +0 -1
  473. package/dist/kernel/index.d.ts.map +0 -1
  474. package/dist/kernel/index.js.map +0 -7
  475. package/dist/kernel/pipeline.d.ts.map +0 -1
  476. package/dist/kernel/run-controller.d.ts.map +0 -1
  477. package/dist/kernel/tokens.d.ts.map +0 -1
  478. package/dist/mailbox-attach.d.ts.map +0 -1
  479. package/dist/middleware/collab-pause.d.ts.map +0 -1
  480. package/dist/models/alibaba-token-plan-catalog.d.ts.map +0 -1
  481. package/dist/models/codex-catalog.d.ts.map +0 -1
  482. package/dist/models/index.d.ts.map +0 -1
  483. package/dist/models/index.js.map +0 -7
  484. package/dist/models/llm-selector.d.ts.map +0 -1
  485. package/dist/models/mode-store.d.ts.map +0 -1
  486. package/dist/models/model-intelligence.d.ts.map +0 -1
  487. package/dist/models/model-router.d.ts.map +0 -1
  488. package/dist/models/models-registry.d.ts.map +0 -1
  489. package/dist/models/provider-model-resolve.d.ts.map +0 -1
  490. package/dist/notifications/index.d.ts.map +0 -1
  491. package/dist/notifications/index.js.map +0 -7
  492. package/dist/notifications/notifier-impl.d.ts.map +0 -1
  493. package/dist/notifications/notifier.d.ts.map +0 -1
  494. package/dist/notifications/types.d.ts.map +0 -1
  495. package/dist/observability/event-bridge.d.ts.map +0 -1
  496. package/dist/observability/health.d.ts.map +0 -1
  497. package/dist/observability/index.d.ts.map +0 -1
  498. package/dist/observability/index.js.map +0 -7
  499. package/dist/observability/metrics.d.ts.map +0 -1
  500. package/dist/observability/network-telemetry.d.ts.map +0 -1
  501. package/dist/observability/otel-tracer.d.ts.map +0 -1
  502. package/dist/observability/otlp-metrics.d.ts.map +0 -1
  503. package/dist/observability/otlp-traces.d.ts.map +0 -1
  504. package/dist/observability/process-telemetry.d.ts.map +0 -1
  505. package/dist/observability/prometheus.d.ts.map +0 -1
  506. package/dist/observability/redact-command.d.ts.map +0 -1
  507. package/dist/observability/tracer.d.ts.map +0 -1
  508. package/dist/plugin/api.d.ts.map +0 -1
  509. package/dist/plugin/config.d.ts.map +0 -1
  510. package/dist/plugin/index.d.ts.map +0 -1
  511. package/dist/plugin/index.js.map +0 -7
  512. package/dist/plugin/loader.d.ts.map +0 -1
  513. package/dist/plugins/auto-review-plugin.d.ts.map +0 -1
  514. package/dist/plugins/chimera-plugin.d.ts.map +0 -1
  515. package/dist/plugins/prompts-plugin.d.ts.map +0 -1
  516. package/dist/plugins/review-claim-registry.d.ts.map +0 -1
  517. package/dist/plugins/review-context-builder.d.ts.map +0 -1
  518. package/dist/plugins/review-finding-commands.d.ts.map +0 -1
  519. package/dist/plugins/review-finding-integration.d.ts.map +0 -1
  520. package/dist/plugins/review-finding-parser.d.ts.map +0 -1
  521. package/dist/plugins/review-finding-store.d.ts.map +0 -1
  522. package/dist/plugins/review-finding-types.d.ts.map +0 -1
  523. package/dist/plugins/review-report-integration.d.ts.map +0 -1
  524. package/dist/plugins/review-report-store.d.ts.map +0 -1
  525. package/dist/plugins/review-report-types.d.ts.map +0 -1
  526. package/dist/plugins/review-types.d.ts.map +0 -1
  527. package/dist/plugins/skills-plugin.d.ts.map +0 -1
  528. package/dist/plugins/sync-plugin.d.ts.map +0 -1
  529. package/dist/prompts/index.d.ts.map +0 -1
  530. package/dist/prompts/prompt-installer.d.ts.map +0 -1
  531. package/dist/prompts/prompt-manifest-store.d.ts.map +0 -1
  532. package/dist/registry/index.d.ts.map +0 -1
  533. package/dist/registry/index.js.map +0 -7
  534. package/dist/registry/provider-registry.d.ts.map +0 -1
  535. package/dist/registry/slash-command-registry.d.ts.map +0 -1
  536. package/dist/registry/tool-registry.d.ts.map +0 -1
  537. package/dist/replay/hash.d.ts.map +0 -1
  538. package/dist/replay/index.d.ts.map +0 -1
  539. package/dist/replay/index.js.map +0 -7
  540. package/dist/replay/replay-provider-runner.d.ts.map +0 -1
  541. package/dist/security/capabilities.d.ts.map +0 -1
  542. package/dist/security/config-secrets.d.ts.map +0 -1
  543. package/dist/security/directory-permission-policy.d.ts.map +0 -1
  544. package/dist/security/directory-policy-schema.d.ts.map +0 -1
  545. package/dist/security/index.d.ts.map +0 -1
  546. package/dist/security/index.js.map +0 -7
  547. package/dist/security/kanban-boundary.d.ts.map +0 -1
  548. package/dist/security/permission-policy-schema.d.ts.map +0 -1
  549. package/dist/security/permission-policy.d.ts.map +0 -1
  550. package/dist/security/readonly-permission-policy.d.ts.map +0 -1
  551. package/dist/security/secret-scrubber.d.ts.map +0 -1
  552. package/dist/security/secret-vault.d.ts.map +0 -1
  553. package/dist/security/trust-boundary.d.ts.map +0 -1
  554. package/dist/security/yolo-risk.d.ts.map +0 -1
  555. package/dist/session-registry-atomic-file.d.ts.map +0 -1
  556. package/dist/session-registry-types.d.ts.map +0 -1
  557. package/dist/session-registry.d.ts.map +0 -1
  558. package/dist/skills/foreign-sources.d.ts.map +0 -1
  559. package/dist/skills/frontmatter.d.ts.map +0 -1
  560. package/dist/skills/github-fetcher.d.ts.map +0 -1
  561. package/dist/skills/index.d.ts.map +0 -1
  562. package/dist/skills/index.js.map +0 -7
  563. package/dist/skills/limits.d.ts.map +0 -1
  564. package/dist/skills/manifest-store.d.ts.map +0 -1
  565. package/dist/skills/registry/github-direct-adapter.d.ts.map +0 -1
  566. package/dist/skills/registry/registry-adapter.d.ts.map +0 -1
  567. package/dist/skills/registry/skills-sh-adapter.d.ts.map +0 -1
  568. package/dist/skills/skill-generator.d.ts.map +0 -1
  569. package/dist/skills/skill-installer.d.ts.map +0 -1
  570. package/dist/storage/annotations-store.d.ts.map +0 -1
  571. package/dist/storage/attachment-store.d.ts.map +0 -1
  572. package/dist/storage/cloud-sync.d.ts.map +0 -1
  573. package/dist/storage/completed-work-checkpoint.d.ts.map +0 -1
  574. package/dist/storage/config-loader/bootstrap.d.ts.map +0 -1
  575. package/dist/storage/config-loader/default-repair.d.ts.map +0 -1
  576. package/dist/storage/config-loader/defaults.d.ts.map +0 -1
  577. package/dist/storage/config-loader/diagnostics.d.ts.map +0 -1
  578. package/dist/storage/config-loader/env-overrides.d.ts.map +0 -1
  579. package/dist/storage/config-loader/in-project-policy.d.ts.map +0 -1
  580. package/dist/storage/config-loader/inline-provider-models.d.ts.map +0 -1
  581. package/dist/storage/config-loader/legacy-sage-migration.d.ts.map +0 -1
  582. package/dist/storage/config-loader/path-identity.d.ts.map +0 -1
  583. package/dist/storage/config-loader/types.d.ts.map +0 -1
  584. package/dist/storage/config-loader/validation.d.ts.map +0 -1
  585. package/dist/storage/config-loader.d.ts.map +0 -1
  586. package/dist/storage/config-migration.d.ts.map +0 -1
  587. package/dist/storage/config-store.d.ts.map +0 -1
  588. package/dist/storage/director-state.d.ts.map +0 -1
  589. package/dist/storage/file-session-writer.d.ts.map +0 -1
  590. package/dist/storage/goal-coordination.d.ts.map +0 -1
  591. package/dist/storage/goal-kanban.d.ts.map +0 -1
  592. package/dist/storage/goal-store.d.ts.map +0 -1
  593. package/dist/storage/index.d.ts.map +0 -1
  594. package/dist/storage/index.js.map +0 -7
  595. package/dist/storage/input-history-store.d.ts.map +0 -1
  596. package/dist/storage/memory-backend.d.ts.map +0 -1
  597. package/dist/storage/memory-consolidator.d.ts.map +0 -1
  598. package/dist/storage/memory-graph-backend.d.ts.map +0 -1
  599. package/dist/storage/plan-store.d.ts.map +0 -1
  600. package/dist/storage/plan-templates.d.ts.map +0 -1
  601. package/dist/storage/prompt-store.d.ts.map +0 -1
  602. package/dist/storage/prompt-usage-store.d.ts.map +0 -1
  603. package/dist/storage/provider-config-watcher.d.ts.map +0 -1
  604. package/dist/storage/queue-store.d.ts.map +0 -1
  605. package/dist/storage/recovery-lock.d.ts.map +0 -1
  606. package/dist/storage/replay-log-store.d.ts.map +0 -1
  607. package/dist/storage/session-analyzer.d.ts.map +0 -1
  608. package/dist/storage/session-checkpoint-cas.d.ts.map +0 -1
  609. package/dist/storage/session-event-bridge.d.ts.map +0 -1
  610. package/dist/storage/session-helpers.d.ts.map +0 -1
  611. package/dist/storage/session-id-resolver.d.ts.map +0 -1
  612. package/dist/storage/session-id.d.ts.map +0 -1
  613. package/dist/storage/session-read-scrubber.d.ts.map +0 -1
  614. package/dist/storage/session-reader.d.ts.map +0 -1
  615. package/dist/storage/session-recovery.d.ts.map +0 -1
  616. package/dist/storage/session-resume-validation.d.ts.map +0 -1
  617. package/dist/storage/session-rewind-apply.d.ts.map +0 -1
  618. package/dist/storage/session-rewinder.d.ts.map +0 -1
  619. package/dist/storage/session-store/delete-session-artifacts.d.ts.map +0 -1
  620. package/dist/storage/session-store/delete-session-guards.d.ts.map +0 -1
  621. package/dist/storage/session-store/directory-scan.d.ts.map +0 -1
  622. package/dist/storage/session-store/directory-session-files.d.ts.map +0 -1
  623. package/dist/storage/session-store/events.d.ts.map +0 -1
  624. package/dist/storage/session-store/fork-session.d.ts.map +0 -1
  625. package/dist/storage/session-store/index-reader.d.ts.map +0 -1
  626. package/dist/storage/session-store/load-cache.d.ts.map +0 -1
  627. package/dist/storage/session-store/load-session-data.d.ts.map +0 -1
  628. package/dist/storage/session-store/paths.d.ts.map +0 -1
  629. package/dist/storage/session-store/prune-helpers.d.ts.map +0 -1
  630. package/dist/storage/session-store/replay.d.ts.map +0 -1
  631. package/dist/storage/session-store/search-events.d.ts.map +0 -1
  632. package/dist/storage/session-store/shard-manifest.d.ts.map +0 -1
  633. package/dist/storage/session-store/summary-builder.d.ts.map +0 -1
  634. package/dist/storage/session-store/summary-header.d.ts.map +0 -1
  635. package/dist/storage/session-store/types.d.ts.map +0 -1
  636. package/dist/storage/session-store.d.ts.map +0 -1
  637. package/dist/storage/session-summary.d.ts.map +0 -1
  638. package/dist/storage/session-tool-call-ends.d.ts.map +0 -1
  639. package/dist/storage/session-writer-scrubber.d.ts.map +0 -1
  640. package/dist/storage/session-writer-truncate.d.ts.map +0 -1
  641. package/dist/storage/storage-concurrency.d.ts.map +0 -1
  642. package/dist/storage/task-store.d.ts.map +0 -1
  643. package/dist/storage/todos-checkpoint.d.ts.map +0 -1
  644. package/dist/storage/tool-audit-log.d.ts.map +0 -1
  645. package/dist/tasking/index.d.ts.map +0 -1
  646. package/dist/tasking/index.js.map +0 -7
  647. package/dist/tasking/task-store.d.ts.map +0 -1
  648. package/dist/tasking/task-tracker.d.ts.map +0 -1
  649. package/dist/tools/council-tool.d.ts.map +0 -1
  650. package/dist/tools/fallback-chain-manage-tool.d.ts.map +0 -1
  651. package/dist/tools/fallback-favorite-manage-tool.d.ts.map +0 -1
  652. package/dist/tools/fallback-manage-helpers.d.ts.map +0 -1
  653. package/dist/tools/fallback-manage-tool-options.d.ts.map +0 -1
  654. package/dist/tools/fallback-manage-tools.d.ts.map +0 -1
  655. package/dist/tools/fallback-model-ref-parse.d.ts.map +0 -1
  656. package/dist/tools/fallback-provider-key-store.d.ts.map +0 -1
  657. package/dist/tools/fallback-system-config-view-tool.d.ts.map +0 -1
  658. package/dist/tools/index.d.ts.map +0 -1
  659. package/dist/tools/index.js.map +0 -7
  660. package/dist/tools/mcp-control.d.ts.map +0 -1
  661. package/dist/tools/mcp-use.d.ts.map +0 -1
  662. package/dist/tools/one-shot-llm-tool.d.ts.map +0 -1
  663. package/dist/tools/plugin-manager.d.ts.map +0 -1
  664. package/dist/types/agent-bridge.d.ts.map +0 -1
  665. package/dist/types/attachment.d.ts.map +0 -1
  666. package/dist/types/autonomy.d.ts.map +0 -1
  667. package/dist/types/blocks.d.ts.map +0 -1
  668. package/dist/types/compactor.d.ts.map +0 -1
  669. package/dist/types/config/autonomy.d.ts.map +0 -1
  670. package/dist/types/config/context.d.ts.map +0 -1
  671. package/dist/types/config/fleet-chat.d.ts.map +0 -1
  672. package/dist/types/config/mcp-features.d.ts.map +0 -1
  673. package/dist/types/config/providers.d.ts.map +0 -1
  674. package/dist/types/config/root.d.ts.map +0 -1
  675. package/dist/types/config/runtime.d.ts.map +0 -1
  676. package/dist/types/config/skills-fleet-brain.d.ts.map +0 -1
  677. package/dist/types/config/tools.d.ts.map +0 -1
  678. package/dist/types/config.d.ts.map +0 -1
  679. package/dist/types/context-evidence.d.ts.map +0 -1
  680. package/dist/types/context-window.d.ts.map +0 -1
  681. package/dist/types/council.d.ts.map +0 -1
  682. package/dist/types/default-config.d.ts.map +0 -1
  683. package/dist/types/design-kit.d.ts.map +0 -1
  684. package/dist/types/error-handler.d.ts.map +0 -1
  685. package/dist/types/errors.d.ts.map +0 -1
  686. package/dist/types/file-event-record.d.ts.map +0 -1
  687. package/dist/types/hooks.d.ts.map +0 -1
  688. package/dist/types/index.d.ts.map +0 -1
  689. package/dist/types/index.js.map +0 -7
  690. package/dist/types/input-reader.d.ts.map +0 -1
  691. package/dist/types/logger.d.ts.map +0 -1
  692. package/dist/types/memory.d.ts.map +0 -1
  693. package/dist/types/messages.d.ts.map +0 -1
  694. package/dist/types/mode-prompts.d.ts.map +0 -1
  695. package/dist/types/mode.d.ts.map +0 -1
  696. package/dist/types/models-registry.d.ts.map +0 -1
  697. package/dist/types/multi-agent.d.ts.map +0 -1
  698. package/dist/types/observability.d.ts.map +0 -1
  699. package/dist/types/one-shot-llm.d.ts.map +0 -1
  700. package/dist/types/path-resolver.d.ts.map +0 -1
  701. package/dist/types/permission.d.ts.map +0 -1
  702. package/dist/types/plugin.d.ts.map +0 -1
  703. package/dist/types/prompt-registry.d.ts.map +0 -1
  704. package/dist/types/prompt.d.ts.map +0 -1
  705. package/dist/types/provider-runner.d.ts.map +0 -1
  706. package/dist/types/provider.d.ts.map +0 -1
  707. package/dist/types/quota-regex.d.ts.map +0 -1
  708. package/dist/types/renderer.d.ts.map +0 -1
  709. package/dist/types/retry-policy.d.ts.map +0 -1
  710. package/dist/types/secret-scrubber.d.ts.map +0 -1
  711. package/dist/types/secret-vault.d.ts.map +0 -1
  712. package/dist/types/selector.d.ts.map +0 -1
  713. package/dist/types/session-markers.d.ts.map +0 -1
  714. package/dist/types/session-markers.js.map +0 -7
  715. package/dist/types/session-reader.d.ts.map +0 -1
  716. package/dist/types/session-rewinder.d.ts.map +0 -1
  717. package/dist/types/session.d.ts.map +0 -1
  718. package/dist/types/side-effect.d.ts.map +0 -1
  719. package/dist/types/skill.d.ts.map +0 -1
  720. package/dist/types/slash-command.d.ts.map +0 -1
  721. package/dist/types/spec.d.ts.map +0 -1
  722. package/dist/types/system-prompt-contributor.d.ts.map +0 -1
  723. package/dist/types/system-prompt.d.ts.map +0 -1
  724. package/dist/types/task-graph.d.ts.map +0 -1
  725. package/dist/types/token-counter.d.ts.map +0 -1
  726. package/dist/types/tool-executor.d.ts.map +0 -1
  727. package/dist/types/tool-markers.d.ts.map +0 -1
  728. package/dist/types/tool.d.ts.map +0 -1
  729. package/dist/types/utility-types.d.ts.map +0 -1
  730. package/dist/utils/assert-never.d.ts.map +0 -1
  731. package/dist/utils/atomic-write.d.ts.map +0 -1
  732. package/dist/utils/cache-key.d.ts.map +0 -1
  733. package/dist/utils/child-env.d.ts.map +0 -1
  734. package/dist/utils/color.d.ts.map +0 -1
  735. package/dist/utils/compaction-preview.d.ts.map +0 -1
  736. package/dist/utils/config-backup.d.ts.map +0 -1
  737. package/dist/utils/config-json.d.ts.map +0 -1
  738. package/dist/utils/connectivity.d.ts.map +0 -1
  739. package/dist/utils/context-breakdown.d.ts.map +0 -1
  740. package/dist/utils/context-evidence.d.ts.map +0 -1
  741. package/dist/utils/continuous-memory-profiler.d.ts.map +0 -1
  742. package/dist/utils/crash-shield.d.ts.map +0 -1
  743. package/dist/utils/deep-merge.d.ts.map +0 -1
  744. package/dist/utils/diff.d.ts.map +0 -1
  745. package/dist/utils/error.d.ts.map +0 -1
  746. package/dist/utils/error.js.map +0 -7
  747. package/dist/utils/expect-defined.d.ts.map +0 -1
  748. package/dist/utils/expect-defined.js.map +0 -7
  749. package/dist/utils/glob-expand.d.ts.map +0 -1
  750. package/dist/utils/glob-match.d.ts.map +0 -1
  751. package/dist/utils/heap-watchdog-types.d.ts.map +0 -1
  752. package/dist/utils/heap-watchdog.d.ts.map +0 -1
  753. package/dist/utils/heap-watchdog.js.map +0 -7
  754. package/dist/utils/incoming-images.d.ts.map +0 -1
  755. package/dist/utils/index.d.ts.map +0 -1
  756. package/dist/utils/index.js.map +0 -7
  757. package/dist/utils/instruction-file.d.ts.map +0 -1
  758. package/dist/utils/ip-guard.d.ts.map +0 -1
  759. package/dist/utils/json-repair.d.ts.map +0 -1
  760. package/dist/utils/json-schema-validate.d.ts.map +0 -1
  761. package/dist/utils/lru-cache.d.ts.map +0 -1
  762. package/dist/utils/memory-flight-recorder.d.ts.map +0 -1
  763. package/dist/utils/merge-custom-models.d.ts.map +0 -1
  764. package/dist/utils/merge-models-payload.d.ts.map +0 -1
  765. package/dist/utils/message-invariants.d.ts.map +0 -1
  766. package/dist/utils/newline-normalize.d.ts.map +0 -1
  767. package/dist/utils/perf-profile.d.ts.map +0 -1
  768. package/dist/utils/pid.d.ts.map +0 -1
  769. package/dist/utils/project-identity.d.ts.map +0 -1
  770. package/dist/utils/project-watch.d.ts.map +0 -1
  771. package/dist/utils/regex-guard.d.ts.map +0 -1
  772. package/dist/utils/safe-json.d.ts.map +0 -1
  773. package/dist/utils/sage-output-block.d.ts.map +0 -1
  774. package/dist/utils/session-scoped-path.d.ts.map +0 -1
  775. package/dist/utils/sleep.d.ts.map +0 -1
  776. package/dist/utils/slug.d.ts.map +0 -1
  777. package/dist/utils/socket-path.d.ts.map +0 -1
  778. package/dist/utils/sqlite-warning.d.ts.map +0 -1
  779. package/dist/utils/string.d.ts.map +0 -1
  780. package/dist/utils/task-format.d.ts.map +0 -1
  781. package/dist/utils/term.d.ts.map +0 -1
  782. package/dist/utils/todos-format.d.ts.map +0 -1
  783. package/dist/utils/token-estimate.d.ts.map +0 -1
  784. package/dist/utils/tool-description-mode.d.ts.map +0 -1
  785. package/dist/utils/tool-name.d.ts.map +0 -1
  786. package/dist/utils/tool-output-serializer.d.ts.map +0 -1
  787. package/dist/utils/tool-result-render-mode.d.ts.map +0 -1
  788. package/dist/utils/tool-subject.d.ts.map +0 -1
  789. package/dist/utils/tool-wire-compact.d.ts.map +0 -1
  790. package/dist/utils/tree-kill.d.ts.map +0 -1
  791. package/dist/utils/tree-kill.js.map +0 -7
  792. package/dist/utils/ulid.d.ts.map +0 -1
  793. package/dist/utils/walk-ignore.d.ts.map +0 -1
  794. package/dist/utils/wstack-paths.d.ts.map +0 -1
  795. package/dist/worktree/index.d.ts.map +0 -1
  796. package/dist/worktree/index.js.map +0 -7
  797. package/dist/worktree/worktree-git.d.ts.map +0 -1
  798. package/dist/worktree/worktree-managed-ops.d.ts.map +0 -1
  799. package/dist/worktree/worktree-manager.d.ts.map +0 -1
  800. package/dist/worktree/worktree-types.d.ts.map +0 -1
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/execution/council-personas.ts", "../../src/execution/council-profiles.ts", "../../src/utils/instruction-file.ts", "../../src/execution/council-prompts.ts", "../../src/execution/council-resolution.ts", "../../src/execution/council-orchestrator.ts", "../../src/tools/council-tool.ts", "../../src/types/blocks.ts", "../../src/utils/string.ts", "../../src/utils/error.ts", "../../src/types/errors.ts", "../../src/types/quota-regex.ts", "../../src/types/provider.ts", "../../src/utils/tool-wire-compact.ts", "../../src/utils/token-estimate.ts", "../../src/core/model-ref.ts", "../../src/core/model-availability-calendar.ts", "../../src/core/fallback-profile-manager.ts", "../../src/core/fallback-model.ts", "../../src/coordination/agents/types.ts", "../../src/coordination/agents/agent-prompts.ts", "../../src/utils/wstack-paths.ts", "../../src/coordination/agents/project-agent-identity.ts", "../../src/coordination/agents/project-agent-knowledge-manifests.ts", "../../src/coordination/agents/project-agent-learning-policy.ts", "../../src/coordination/agents/project-agent-paths.ts", "../../src/coordination/agents/project-agent-learning-entries.ts", "../../src/coordination/agents/project-agent-consolidation.ts", "../../src/coordination/agents/phase1-discovery.ts", "../../src/coordination/agents/phase2-planning.ts", "../../src/coordination/agents/phase3-build.ts", "../../src/coordination/agents/phase3-wave1-platform.ts", "../../src/coordination/agents/phase3-wave2-meta.ts", "../../src/coordination/agents/phase4-verify.ts", "../../src/coordination/agents/phase5-review.ts", "../../src/coordination/agents/phase6-domain.ts", "../../src/coordination/agents/phase7-knowledge.ts", "../../src/coordination/agents/phase8-delivery.ts", "../../src/coordination/agents/phase8-wave3-products.ts", "../../src/coordination/agents/phase9-meta.ts", "../../src/coordination/agents/phase9-wave4-platform-meta.ts", "../../src/coordination/agents/role-skills.ts", "../../src/coordination/agents/index.ts", "../../src/coordination/model-matrix.ts", "../../src/tools/fallback-manage-helpers.ts", "../../src/tools/fallback-chain-manage-tool.ts", "../../src/tools/fallback-favorite-manage-tool.ts", "../../src/tools/fallback-provider-key-store.ts", "../../src/tools/fallback-system-config-view-tool.ts", "../../src/tools/fallback-manage-tools.ts", "../../src/utils/expect-defined.ts", "../../src/security/capabilities.ts", "../../src/infrastructure/mcp-servers.ts", "../../src/utils/config-json.ts", "../../src/utils/atomic-write.ts", "../../src/tools/mcp-control.ts", "../../src/utils/tool-name.ts", "../../src/tools/mcp-use.ts", "../../src/execution/one-shot-llm.ts", "../../src/tools/one-shot-llm-tool.ts", "../../src/utils/json-schema-validate.ts", "../../src/tools/plugin-manager.ts"],
4
- "sourcesContent": ["import type { CouncilPersona } from '../types/council.js';\n\nconst PERSONA_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/** Provider-neutral personas shipped with every Council installation. */\nexport const BUILTIN_COUNCIL_PERSONAS: readonly CouncilPersona[] = Object.freeze([\n freezePersona({\n id: 'executor',\n name: 'Executor',\n description: 'Tests whether a proposal is practical and keeps useful work moving.',\n instruction:\n 'Evaluate operational feasibility, concrete progress, and the cost of delay. Favor decisive action when evidence supports it, but reject action whose prerequisites are missing.',\n tags: ['delivery', 'feasibility', 'progress'],\n }),\n freezePersona({\n id: 'skeptic',\n name: 'Skeptic',\n description: 'Challenges assumptions and looks for concrete failure modes.',\n instruction:\n 'Identify unsupported assumptions, unsafe premises, irreversible consequences, and credible failure modes. Oppose or refuse only when you can name a concrete reason.',\n defaultVeto: true,\n tags: ['risk', 'assumptions', 'failure-modes'],\n }),\n freezePersona({\n id: 'auditor',\n name: 'Auditor',\n description: 'Evaluates cost, waste, evidence quality, and expected value.',\n instruction:\n 'Compare resource cost, opportunity cost, evidence quality, reversibility, and expected value. Prefer the option that achieves the objective with the least avoidable waste.',\n tags: ['cost', 'evidence', 'efficiency'],\n }),\n freezePersona({\n id: 'security',\n name: 'Security Reviewer',\n description: 'Examines trust boundaries, abuse cases, and security impact.',\n instruction:\n 'Evaluate trust boundaries, attacker-controlled inputs, privilege changes, data exposure, abuse cases, and recovery options. Treat unmitigated high-impact security risk as grounds to refuse.',\n defaultVeto: true,\n tags: ['security', 'trust', 'abuse-cases'],\n }),\n freezePersona({\n id: 'maintainer',\n name: 'Maintainer',\n description: 'Evaluates complexity, compatibility, and long-term ownership.',\n instruction:\n 'Evaluate behavioral compatibility, conceptual complexity, testability, migration cost, and future maintenance. Prefer the smallest design that remains clear and extensible.',\n tags: ['maintenance', 'compatibility', 'simplicity'],\n }),\n freezePersona({\n id: 'user-advocate',\n name: 'User Advocate',\n description: 'Evaluates the decision from the affected user\u2019s perspective.',\n instruction:\n 'Evaluate usability, surprise, accessibility, failure recovery, and whether the outcome solves the user\u2019s stated need. Prefer understandable behavior with safe recovery paths.',\n tags: ['users', 'usability', 'accessibility'],\n }),\n]);\n\n/** Immutable registry of trusted Council persona definitions. */\nexport class CouncilPersonaRegistry {\n private readonly byId: ReadonlyMap<string, CouncilPersona>;\n\n constructor(personas: readonly CouncilPersona[] = []) {\n const entries = new Map<string, CouncilPersona>();\n for (const persona of personas) {\n const normalized = freezePersona(persona);\n if (entries.has(normalized.id)) {\n throw new Error(`CouncilPersonaRegistry: duplicate persona id \"${normalized.id}\".`);\n }\n entries.set(normalized.id, normalized);\n }\n this.byId = entries;\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n get(id: string): CouncilPersona | undefined {\n return this.byId.get(id);\n }\n\n require(id: string): CouncilPersona {\n const persona = this.get(id);\n if (!persona) throw new Error(`CouncilPersonaRegistry: unknown persona \"${id}\".`);\n return persona;\n }\n\n list(): readonly CouncilPersona[] {\n return Object.freeze([...this.byId.values()]);\n }\n\n /** Return a new registry; the current registry is never mutated. */\n with(persona: CouncilPersona, opts: { replace?: boolean | undefined } = {}): CouncilPersonaRegistry {\n const normalized = freezePersona(persona);\n if (this.has(normalized.id) && opts.replace !== true) {\n throw new Error(`CouncilPersonaRegistry: persona \"${normalized.id}\" already exists.`);\n }\n return new CouncilPersonaRegistry([\n ...this.list().filter((entry) => entry.id !== normalized.id),\n normalized,\n ]);\n }\n}\n\nexport const DEFAULT_COUNCIL_PERSONA_REGISTRY = new CouncilPersonaRegistry(\n BUILTIN_COUNCIL_PERSONAS,\n);\n\nexport function createCouncilPersonaRegistry(\n additional: readonly CouncilPersona[] = [],\n): CouncilPersonaRegistry {\n let registry = DEFAULT_COUNCIL_PERSONA_REGISTRY;\n for (const persona of additional) registry = registry.with(persona);\n return registry;\n}\n\nfunction freezePersona(persona: CouncilPersona): CouncilPersona {\n const id = persona.id.trim();\n const name = persona.name.trim();\n const description = persona.description.trim();\n const instruction = persona.instruction.trim();\n if (!PERSONA_ID_RE.test(id)) {\n throw new Error(`CouncilPersonaRegistry: invalid persona id \"${persona.id}\".`);\n }\n if (!name) throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires a name.`);\n if (!description) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires a description.`);\n }\n if (!instruction) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires an instruction.`);\n }\n if (\n persona.defaultWeight !== undefined &&\n (!Number.isFinite(persona.defaultWeight) || persona.defaultWeight <= 0)\n ) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" has an invalid default weight.`);\n }\n const tags = Object.freeze(\n [...new Set((persona.tags ?? []).map((tag) => tag.trim()).filter(Boolean))],\n );\n return Object.freeze({\n id,\n name,\n description,\n instruction,\n ...(persona.defaultWeight !== undefined ? { defaultWeight: persona.defaultWeight } : {}),\n ...(persona.defaultVeto !== undefined ? { defaultVeto: persona.defaultVeto } : {}),\n ...(tags.length > 0 ? { tags } : {}),\n });\n}\n", "import type {\n CouncilDistinctness,\n CouncilModelTarget,\n CouncilProfileConfig,\n ResolvedCouncilProfile,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport {\n type CouncilPersonaRegistry,\n DEFAULT_COUNCIL_PERSONA_REGISTRY,\n} from './council-personas.js';\n\nconst PROFILE_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst DISTINCTNESS_VALUES: ReadonlySet<CouncilDistinctness> = new Set([\n 'none',\n 'model',\n 'provider',\n]);\n\nexport const DEFAULT_COUNCIL_QUORUM_FRACTION = 0.5;\nexport const DEFAULT_COUNCIL_APPROVAL_FRACTION = 0.5;\nexport const DEFAULT_COUNCIL_VOTER_MAX_TOKENS = 300;\nexport const DEFAULT_COUNCIL_JUDGE_MAX_TOKENS = 500;\nexport const DEFAULT_COUNCIL_PER_CALL_TIMEOUT_MS = 30_000;\nexport const DEFAULT_COUNCIL_OVERALL_TIMEOUT_MS = 90_000;\n\n/** Model-agnostic profiles. Roles are routing hints, never provider/model pins. */\nexport const BUILTIN_COUNCIL_PROFILES: readonly CouncilProfileConfig[] = Object.freeze([\n Object.freeze({\n id: 'balanced',\n name: 'Balanced',\n description: 'Three complementary lenses plus an independent judge for general decisions.',\n seats: Object.freeze([\n Object.freeze({ persona: 'executor', target: Object.freeze({ role: 'planner' }) }),\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n Object.freeze({ persona: 'auditor', target: Object.freeze({ role: 'analyst' }) }),\n ]),\n judge: Object.freeze({ role: 'reviewer' }),\n quorumFraction: 0.5,\n approvalFraction: 0.5,\n distinctness: 'model',\n }),\n Object.freeze({\n id: 'fast',\n name: 'Fast',\n description: 'Two-seat panel without a judge for quick, low-cost decisions.',\n seats: Object.freeze([\n Object.freeze({ persona: 'executor', target: Object.freeze({ role: 'planner' }) }),\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n ]),\n judge: false,\n quorumFraction: 0.5,\n approvalFraction: 0.5,\n distinctness: 'none',\n voterMaxTokens: 200,\n perCallTimeoutMs: 20_000,\n overallTimeoutMs: 30_000,\n }),\n Object.freeze({\n id: 'risk-review',\n name: 'Risk Review',\n description: 'Security, assumptions, maintenance, and cost review for high-impact choices.',\n seats: Object.freeze([\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n Object.freeze({ persona: 'security', target: Object.freeze({ role: 'security-reviewer' }) }),\n Object.freeze({ persona: 'maintainer', target: Object.freeze({ role: 'reviewer' }) }),\n Object.freeze({ persona: 'auditor', target: Object.freeze({ role: 'analyst' }) }),\n ]),\n judge: Object.freeze({ role: 'architect' }),\n quorumFraction: 0.75,\n approvalFraction: 0.5,\n distinctness: 'provider',\n judgeMaxTokens: 700,\n overallTimeoutMs: 120_000,\n }),\n]);\n\n/** Immutable registry of normalized Council profiles. */\nexport class CouncilProfileRegistry {\n private readonly byId: ReadonlyMap<string, ResolvedCouncilProfile>;\n private readonly personas: CouncilPersonaRegistry;\n\n constructor(\n profiles: readonly CouncilProfileConfig[] = [],\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n ) {\n this.personas = personas;\n const entries = new Map<string, ResolvedCouncilProfile>();\n for (const profile of profiles) {\n const normalized = normalizeCouncilProfile(profile, personas);\n if (entries.has(normalized.id)) {\n throw new Error(`CouncilProfileRegistry: duplicate profile id \"${normalized.id}\".`);\n }\n entries.set(normalized.id, normalized);\n }\n this.byId = entries;\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n get(id: string): ResolvedCouncilProfile | undefined {\n return this.byId.get(id);\n }\n\n require(id: string): ResolvedCouncilProfile {\n const profile = this.get(id);\n if (!profile) throw new Error(`CouncilProfileRegistry: unknown profile \"${id}\".`);\n return profile;\n }\n\n list(): readonly ResolvedCouncilProfile[] {\n return Object.freeze([...this.byId.values()]);\n }\n\n /** Return a new registry; the current registry is never mutated. */\n with(\n profile: CouncilProfileConfig,\n opts: {\n replace?: boolean | undefined;\n personas?: CouncilPersonaRegistry | undefined;\n } = {},\n ): CouncilProfileRegistry {\n const personas = opts.personas ?? this.personas;\n const normalized = normalizeCouncilProfile(profile, personas);\n if (this.has(normalized.id) && opts.replace !== true) {\n throw new Error(`CouncilProfileRegistry: profile \"${normalized.id}\" already exists.`);\n }\n return new CouncilProfileRegistry(\n [\n ...this.list().filter((entry) => entry.id !== normalized.id),\n profile,\n ],\n personas,\n );\n }\n}\n\nexport const DEFAULT_COUNCIL_PROFILE_REGISTRY = new CouncilProfileRegistry(\n BUILTIN_COUNCIL_PROFILES,\n);\n\nexport function createCouncilProfileRegistry(\n additional: readonly CouncilProfileConfig[] = [],\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n): CouncilProfileRegistry {\n return new CouncilProfileRegistry([...BUILTIN_COUNCIL_PROFILES, ...additional], personas);\n}\n\nexport function resolveCouncilProfile(\n profile: string | CouncilProfileConfig | undefined,\n opts: {\n registry?: CouncilProfileRegistry | undefined;\n personas?: CouncilPersonaRegistry | undefined;\n defaultProfile?: string | undefined;\n } = {},\n): ResolvedCouncilProfile {\n const personas = opts.personas ?? DEFAULT_COUNCIL_PERSONA_REGISTRY;\n if (profile && typeof profile !== 'string') return normalizeCouncilProfile(profile, personas);\n const id = profile ?? opts.defaultProfile ?? 'balanced';\n return (opts.registry ?? DEFAULT_COUNCIL_PROFILE_REGISTRY).require(id);\n}\n\nexport function normalizeCouncilProfile(\n profile: CouncilProfileConfig,\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n): ResolvedCouncilProfile {\n const id = profile.id.trim();\n if (!PROFILE_ID_RE.test(id)) {\n throw new Error(`CouncilProfileRegistry: invalid profile id \"${profile.id}\".`);\n }\n if (profile.seats.length === 0) {\n throw new Error(`CouncilProfileRegistry: profile \"${id}\" requires at least one seat.`);\n }\n\n const usedIds = new Set<string>();\n const seats = profile.seats.map((seat) => {\n const persona = personas.require(seat.persona.trim());\n const explicitSeatId = seat.id?.trim();\n if (explicitSeatId && usedIds.has(explicitSeatId)) {\n throw new Error(`CouncilProfileRegistry: duplicate seat id \"${explicitSeatId}\".`);\n }\n const seatId = uniqueSeatId(explicitSeatId || persona.id, usedIds);\n const label = seat.label?.trim() || persona.name;\n const weight = seat.weight ?? persona.defaultWeight ?? 1;\n if (!Number.isFinite(weight) || weight <= 0) {\n throw new Error(`CouncilProfileRegistry: seat \"${seatId}\" has an invalid weight.`);\n }\n return Object.freeze({\n id: seatId,\n label,\n persona: persona.id,\n ...(seat.target ? { target: freezeTarget(seat.target, `seat \"${seatId}\"`) } : {}),\n weight,\n veto: seat.veto ?? persona.defaultVeto ?? false,\n }) satisfies ResolvedCouncilSeat;\n });\n\n const quorumFraction = fraction(\n profile.quorumFraction ?? DEFAULT_COUNCIL_QUORUM_FRACTION,\n 'quorumFraction',\n id,\n );\n const approvalFraction = fraction(\n profile.approvalFraction ?? DEFAULT_COUNCIL_APPROVAL_FRACTION,\n 'approvalFraction',\n id,\n );\n const distinctness = profile.distinctness ?? 'model';\n if (!DISTINCTNESS_VALUES.has(distinctness)) {\n throw new Error(`CouncilProfileRegistry: profile \"${id}\" has invalid distinctness.`);\n }\n const voterMaxTokens = positiveInteger(\n profile.voterMaxTokens ?? DEFAULT_COUNCIL_VOTER_MAX_TOKENS,\n 'voterMaxTokens',\n id,\n );\n const judgeMaxTokens = positiveInteger(\n profile.judgeMaxTokens ?? DEFAULT_COUNCIL_JUDGE_MAX_TOKENS,\n 'judgeMaxTokens',\n id,\n );\n const perCallTimeoutMs = positiveInteger(\n profile.perCallTimeoutMs ?? DEFAULT_COUNCIL_PER_CALL_TIMEOUT_MS,\n 'perCallTimeoutMs',\n id,\n );\n const overallTimeoutMs = positiveInteger(\n profile.overallTimeoutMs ?? DEFAULT_COUNCIL_OVERALL_TIMEOUT_MS,\n 'overallTimeoutMs',\n id,\n );\n if (overallTimeoutMs < perCallTimeoutMs) {\n throw new Error(\n `CouncilProfileRegistry: profile \"${id}\" overallTimeoutMs must be at least perCallTimeoutMs.`,\n );\n }\n\n return Object.freeze({\n id,\n name: profile.name?.trim() || id,\n description: profile.description?.trim() || '',\n seats: Object.freeze(seats),\n judge: profile.judge ? freezeTarget(profile.judge, 'judge') : false,\n quorumFraction,\n approvalFraction,\n distinctness,\n voterMaxTokens,\n judgeMaxTokens,\n perCallTimeoutMs,\n overallTimeoutMs,\n });\n}\n\nfunction uniqueSeatId(base: string, used: Set<string>): string {\n if (!PROFILE_ID_RE.test(base)) {\n throw new Error(`CouncilProfileRegistry: invalid seat id \"${base}\".`);\n }\n let id = base;\n let suffix = 2;\n while (used.has(id)) id = `${base}-${suffix++}`;\n used.add(id);\n return id;\n}\n\nfunction freezeTarget(target: CouncilModelTarget, label: string): CouncilModelTarget {\n const providerId = optionalText(target.providerId);\n const model = optionalText(target.model);\n const role = optionalText(target.role);\n const fallbackProfile = optionalText(target.fallbackProfile);\n const fallbackModels = Object.freeze(\n [...new Set((target.fallbackModels ?? []).map((ref) => ref.trim()).filter(Boolean))],\n );\n if (\n !providerId &&\n !model &&\n !role &&\n !fallbackProfile &&\n fallbackModels.length === 0\n ) {\n throw new Error(`CouncilProfileRegistry: ${label} target is empty.`);\n }\n return Object.freeze({\n ...(providerId ? { providerId } : {}),\n ...(model ? { model } : {}),\n ...(role ? { role } : {}),\n ...(fallbackProfile ? { fallbackProfile } : {}),\n ...(fallbackModels.length > 0 ? { fallbackModels } : {}),\n });\n}\n\nfunction optionalText(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed || undefined;\n}\n\nfunction fraction(value: number, field: string, profileId: string): number {\n if (!Number.isFinite(value) || value <= 0 || value > 1) {\n throw new Error(`CouncilProfileRegistry: profile \"${profileId}\" ${field} must be in (0, 1].`);\n }\n return value;\n}\n\nfunction positiveInteger(value: number, field: string, profileId: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error(\n `CouncilProfileRegistry: profile \"${profileId}\" ${field} must be a positive integer.`,\n );\n }\n return value;\n}\n", "import { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Cache of resolved instruction text, keyed by the relative path. Bundled\n * instruction files are immutable for the process lifetime, so re-reading them\n * on every call (some callers do so per LLM request) is wasted disk I/O.\n */\nconst textCache = new Map<string, string>();\n\n/** Resolved once \u2014 the candidate roots only depend on this module's location. */\nlet rootCandidates: string[] | undefined;\n\nexport function readBundledInstructionText(relativePath: string): string {\n const cached = textCache.get(relativePath);\n if (cached !== undefined) return cached;\n\n let resolved = '';\n for (const root of instructionRootCandidates()) {\n try {\n resolved = readFileSync(path.join(root, relativePath), 'utf8').trimEnd();\n break;\n } catch {\n // try next candidate\n }\n }\n textCache.set(relativePath, resolved);\n return resolved;\n}\n\nexport function renderInstructionTemplate(\n template: string,\n values: Record<string, string>,\n): string {\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_.-]+)\\s*\\}\\}/g, (match, key: string) =>\n Object.hasOwn(values, key) ? (values[key] ?? '') : match,\n );\n}\n\nfunction instructionRootCandidates(): string[] {\n if (rootCandidates !== undefined) return rootCandidates;\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../../instructions'),\n path.resolve(here, '../instructions'),\n path.resolve(here, 'instructions'),\n ];\n rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n return rootCandidates;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import type {\n CouncilOption,\n CouncilPersona,\n CouncilQuestion,\n CouncilVoteResult,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport {\n readBundledInstructionText,\n renderInstructionTemplate,\n} from '../utils/instruction-file.js';\n\nexport const COUNCIL_VOTER_PROMPT_PATH = 'llm/council-voter.md';\nexport const COUNCIL_JUDGE_PROMPT_PATH = 'llm/council-judge.md';\n\n/** Build the trusted system instruction for one independent seat. */\nexport function buildCouncilVoterSystemPrompt(persona: CouncilPersona): string {\n const template = requiredInstruction(COUNCIL_VOTER_PROMPT_PATH);\n return renderInstructionTemplate(template, {\n personaInstruction: persona.instruction,\n });\n}\n\n/** Build the trusted system instruction for the final judge. */\nexport function buildCouncilJudgeSystemPrompt(): string {\n return requiredInstruction(COUNCIL_JUDGE_PROMPT_PATH);\n}\n\n/** Render the original question as delimited, untrusted user data. */\nexport function buildCouncilQuestionPrompt(\n question: CouncilQuestion,\n opts: { refusalOptionId?: string | undefined } = {},\n): string {\n const text = question.question.trim();\n if (!text) throw new Error('buildCouncilQuestionPrompt: question must not be empty.');\n const options = normalizeOptions(question.options);\n return [\n '<council-question>',\n `Question: ${text}`,\n question.context?.trim() ? `Context:\\n${question.context.trim()}` : '',\n options.length > 0 ? `Options (JSON):\\n${JSON.stringify(options)}` : 'Options: none',\n opts.refusalOptionId\n ? `Refusal option id: ${opts.refusalOptionId}`\n : 'Refusal option id: not supplied',\n '</council-question>',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** Build the voter user prompt. Persona instructions stay in the system prompt. */\nexport function buildCouncilVoterUserPrompt(\n question: CouncilQuestion,\n seat: ResolvedCouncilSeat,\n opts: { refusalOptionId?: string | undefined } = {},\n): string {\n return [\n buildCouncilQuestionPrompt(question, opts),\n '<seat-metadata>',\n `Seat id: ${seat.id}`,\n `Seat label: ${seat.label}`,\n `Persona id: ${seat.persona}`,\n `Vote weight: ${seat.weight}`,\n seat.veto ? 'Veto power: yes \u2014 your refusal unilaterally denies the proposal.' : '',\n '</seat-metadata>',\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\n/** Build the judge user prompt with seat outputs serialized as untrusted JSON. */\nexport function buildCouncilJudgeUserPrompt(\n question: CouncilQuestion,\n votes: readonly CouncilVoteResult[],\n opts: {\n reason?: string | undefined;\n refusalOptionId?: string | undefined;\n } = {},\n): string {\n const ballots = votes.map((vote) => ({\n seatId: vote.seatId,\n persona: vote.persona,\n status: vote.status,\n ...(vote.optionId ? { optionId: vote.optionId } : {}),\n ...(vote.stance ? { stance: vote.stance } : {}),\n ...(vote.rationale ? { rationale: vote.rationale } : {}),\n }));\n return [\n buildCouncilQuestionPrompt(question, { refusalOptionId: opts.refusalOptionId }),\n '<council-ballots>',\n opts.reason?.trim() ? `Reason judging is required: ${opts.reason.trim()}` : '',\n JSON.stringify(ballots),\n '</council-ballots>',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nfunction normalizeOptions(options: readonly CouncilOption[] | undefined): CouncilOption[] {\n if (!options) return [];\n const seen = new Set<string>();\n return options.map((option) => {\n const id = option.id.trim();\n const label = option.label.trim();\n if (!id) throw new Error('buildCouncilQuestionPrompt: option id must not be empty.');\n if (!label) throw new Error(`buildCouncilQuestionPrompt: option \"${id}\" needs a label.`);\n if (seen.has(id)) throw new Error(`buildCouncilQuestionPrompt: duplicate option id \"${id}\".`);\n seen.add(id);\n return {\n id,\n label,\n ...(option.consequence?.trim() ? { consequence: option.consequence.trim() } : {}),\n };\n });\n}\n\nfunction requiredInstruction(path: string): string {\n const text = readBundledInstructionText(path);\n if (!text) throw new Error(`Council instruction file is unavailable: ${path}`);\n return text;\n}\n", "/**\n * Provider- and Brain-independent council vote resolution.\n *\n * This module contains only deterministic quorum, veto, weighted-majority,\n * refusal, and judge-escalation rules. LLM calls, prompts, parsing, and host\n * decision types belong in adapters such as `council-brain.ts`.\n */\n\nexport interface CouncilResolutionSeat {\n id: string;\n /** Vote weight in the tally. Default 1. */\n weight?: number | undefined;\n /** A refusal from this seat immediately denies the proposal. */\n veto?: boolean | undefined;\n}\n\nexport interface CouncilResolutionVote {\n seatId: string;\n optionId: string;\n}\n\nexport interface CouncilResolutionInput {\n seats: readonly CouncilResolutionSeat[];\n votes: readonly CouncilResolutionVote[];\n refusalOptionId: string;\n /** Fraction of configured seats required to return a vote. */\n quorumFraction: number;\n /** Winning weight must exceed this fraction of cast weight. */\n approvalFraction: number;\n}\n\nexport type CouncilResolution =\n | {\n status: 'abstained';\n reason: 'quorum_not_met';\n validVoteCount: number;\n seatCount: number;\n }\n | {\n status: 'denied';\n method: 'veto';\n optionId: string;\n seatId: string;\n }\n | {\n status: 'denied';\n method: 'refusal';\n optionId: string;\n winningWeight: number;\n castWeight: number;\n }\n | {\n status: 'decided';\n method: 'majority';\n optionId: string;\n winningWeight: number;\n castWeight: number;\n }\n | {\n status: 'needs_judge';\n reason: 'tie' | 'approval_threshold_not_met';\n castWeight: number;\n };\n\n/** Resolve already-parsed council votes without performing any I/O. */\nexport function resolveCouncilVotes(input: CouncilResolutionInput): CouncilResolution {\n validateInput(input);\n\n const seatById = new Map(input.seats.map((seat) => [seat.id, seat] as const));\n const validVotes: CouncilResolutionVote[] = [];\n const votedSeatIds = new Set<string>();\n for (const vote of input.votes) {\n if (!seatById.has(vote.seatId) || votedSeatIds.has(vote.seatId)) continue;\n votedSeatIds.add(vote.seatId);\n validVotes.push(vote);\n }\n\n if (validVotes.length / input.seats.length < input.quorumFraction) {\n return {\n status: 'abstained',\n reason: 'quorum_not_met',\n validVoteCount: validVotes.length,\n seatCount: input.seats.length,\n };\n }\n\n const veto = validVotes.find(\n (vote) =>\n vote.optionId === input.refusalOptionId && seatById.get(vote.seatId)?.veto === true,\n );\n if (veto) {\n return {\n status: 'denied',\n method: 'veto',\n optionId: veto.optionId,\n seatId: veto.seatId,\n };\n }\n\n const weightByOption = new Map<string, number>();\n let castWeight = 0;\n for (const vote of validVotes) {\n const weight = seatById.get(vote.seatId)?.weight ?? 1;\n castWeight += weight;\n weightByOption.set(vote.optionId, (weightByOption.get(vote.optionId) ?? 0) + weight);\n }\n\n let winner: { optionId: string; weight: number } | undefined;\n let contested = false;\n for (const [optionId, weight] of weightByOption) {\n if (!winner || weight > winner.weight) {\n winner = { optionId, weight };\n contested = false;\n } else if (weight === winner.weight) {\n contested = true;\n }\n }\n\n const decisive =\n winner !== undefined &&\n !contested &&\n winner.weight > input.approvalFraction * castWeight;\n\n if (!decisive || !winner) {\n return {\n status: 'needs_judge',\n reason: contested ? 'tie' : 'approval_threshold_not_met',\n castWeight,\n };\n }\n\n if (winner.optionId === input.refusalOptionId) {\n return {\n status: 'denied',\n method: 'refusal',\n optionId: winner.optionId,\n winningWeight: winner.weight,\n castWeight,\n };\n }\n\n return {\n status: 'decided',\n method: 'majority',\n optionId: winner.optionId,\n winningWeight: winner.weight,\n castWeight,\n };\n}\n\nfunction validateInput(input: CouncilResolutionInput): void {\n if (input.seats.length === 0) {\n throw new Error('resolveCouncilVotes: at least one seat is required.');\n }\n requireFraction(input.quorumFraction, 'quorumFraction');\n requireFraction(input.approvalFraction, 'approvalFraction');\n\n const seatIds = new Set<string>();\n for (const seat of input.seats) {\n if (!seat.id.trim()) throw new Error('resolveCouncilVotes: seat id must not be empty.');\n if (seatIds.has(seat.id)) {\n throw new Error(`resolveCouncilVotes: duplicate seat id \"${seat.id}\".`);\n }\n seatIds.add(seat.id);\n if (seat.weight !== undefined && (!Number.isFinite(seat.weight) || seat.weight <= 0)) {\n throw new Error(`resolveCouncilVotes: invalid weight for seat \"${seat.id}\".`);\n }\n }\n}\n\nfunction requireFraction(value: number, label: string): void {\n if (!Number.isFinite(value) || value <= 0 || value > 1) {\n throw new Error(`resolveCouncilVotes: ${label} must be in (0, 1].`);\n }\n}\n", "import type {\n CouncilLLMCaller,\n CouncilModelTarget,\n CouncilQuestion,\n CouncilResult,\n CouncilUsage,\n CouncilVoteResult,\n ResolvedCouncilProfile,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport type { OneShotLLMResult } from '../types/one-shot-llm.js';\nimport {\n DEFAULT_COUNCIL_PERSONA_REGISTRY,\n type CouncilPersonaRegistry,\n} from './council-personas.js';\nimport {\n DEFAULT_COUNCIL_PROFILE_REGISTRY,\n type CouncilProfileRegistry,\n resolveCouncilProfile,\n} from './council-profiles.js';\nimport {\n buildCouncilJudgeSystemPrompt,\n buildCouncilJudgeUserPrompt,\n buildCouncilVoterSystemPrompt,\n buildCouncilVoterUserPrompt,\n} from './council-prompts.js';\nimport { resolveCouncilVotes } from './council-resolution.js';\nimport type { FallbackProfileManager } from '../core/fallback-profile-manager.js';\nimport type { Config } from '../types/config.js';\n\n/** Synthetic ballot entry for \"refuse every real option\". */\nexport const COUNCIL_REFUSAL_OPTION_ID = 'council_refuse';\nexport const DEFAULT_COUNCIL_MAX_CONCURRENCY = 3;\nexport const MAX_COUNCIL_CONCURRENCY = 8;\n\nexport interface CouncilOrchestratorOptions {\n /**\n * Shared LLM caller used for every seat and the judge when no per-seat\n * caller is configured. Optional \u2014 supply `seatCaller` (per-seat callers)\n * and/or `judgeCaller` (separate judge caller) to route votes to different\n * providers. At least one of `caller`, `seatCaller`, or `judgeCaller`\n * must be provided; the constructor throws otherwise.\n */\n caller?: CouncilLLMCaller | undefined;\n personas?: CouncilPersonaRegistry | undefined;\n profiles?: CouncilProfileRegistry | undefined;\n defaultProfile?: string | undefined;\n maxConcurrency?: number | undefined;\n refusalOptionId?: string | undefined;\n /** Live config accessor for fallback profile resolution. */\n getConfig?: (() => Config) | undefined;\n /**\n * Shared live FallbackProfileManager \u2014 required for reliable fallback\n * profile pre-resolution. Pass the runtime container's manager.\n */\n fallbackProfileManager?: FallbackProfileManager | undefined;\n /**\n * Per-seat LLM caller factory. When set, each seat gets its own caller\n * instead of the shared `caller`. The factory receives (seatIndex) and\n * returns a CouncilLLMCaller. Used by Brain council arbitration where\n * each voter has its own Provider instance.\n */\n seatCaller?: ((seatIndex: number) => CouncilLLMCaller) | undefined;\n /**\n * Separate caller for the judge seat. Required when `seatCaller` is set\n * because the judge uses the shared caller path. When absent and\n * `seatCaller` is set, the judge falls back to `seatCaller(0)`.\n */\n judgeCaller?: CouncilLLMCaller | undefined;\n}\n\ninterface ParsedVote {\n optionId?: string | undefined;\n stance?: string | undefined;\n rationale?: string | undefined;\n}\n\ninterface ParsedJudge {\n optionId?: string | undefined;\n answer?: string | undefined;\n rationale?: string | undefined;\n}\n\ninterface UsageAccumulator {\n calls: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n}\n\n/** Provider-neutral Council runner backed by an injected one-shot LLM caller. */\nexport class CouncilOrchestrator {\n private readonly caller: CouncilLLMCaller | undefined;\n private readonly personas: CouncilPersonaRegistry;\n private readonly profiles: CouncilProfileRegistry;\n private readonly defaultProfile: string | undefined;\n private readonly maxConcurrency: number;\n private readonly refusalOptionId: string;\n private readonly fallbackProfileManager: FallbackProfileManager | undefined;\n private readonly seatCaller: ((seatIndex: number) => CouncilLLMCaller) | undefined;\n private readonly judgeCaller: CouncilLLMCaller | undefined;\n\n constructor(opts: CouncilOrchestratorOptions) {\n if (!opts.caller && !opts.seatCaller && !opts.judgeCaller) {\n throw new Error(\n 'CouncilOrchestrator: provide `caller`, `seatCaller`, or `judgeCaller`.',\n );\n }\n this.caller = opts.caller;\n this.personas = opts.personas ?? DEFAULT_COUNCIL_PERSONA_REGISTRY;\n this.profiles = opts.profiles ?? DEFAULT_COUNCIL_PROFILE_REGISTRY;\n this.defaultProfile = opts.defaultProfile;\n this.maxConcurrency = validateConcurrency(\n opts.maxConcurrency ?? DEFAULT_COUNCIL_MAX_CONCURRENCY,\n );\n this.refusalOptionId = opts.refusalOptionId?.trim() || COUNCIL_REFUSAL_OPTION_ID;\n this.fallbackProfileManager = opts.fallbackProfileManager;\n this.seatCaller = opts.seatCaller;\n this.judgeCaller = opts.judgeCaller;\n }\n\n async ask(question: CouncilQuestion): Promise<CouncilResult> {\n const startedAt = Date.now();\n const profile = resolveCouncilProfile(question.profile, {\n registry: this.profiles,\n personas: this.personas,\n defaultProfile: this.defaultProfile,\n });\n validateRefusalCollision(question, this.refusalOptionId);\n\n const timeoutSignal = AbortSignal.timeout(profile.overallTimeoutMs);\n const signal = question.signal\n ? AbortSignal.any([question.signal, timeoutSignal])\n : timeoutSignal;\n const usage: UsageAccumulator = {\n calls: 0,\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n };\n\n const votes = await mapConcurrent(\n profile.seats,\n Math.min(this.maxConcurrency, profile.seats.length),\n async (seat, i) => {\n try {\n return await this.callSeat(question, profile, seat, i, signal, usage);\n } catch (error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: signal.aborted ? 'cancelled' : 'failed',\n error: errorMessage(error),\n } satisfies CouncilVoteResult;\n }\n },\n );\n const warnings = distinctnessWarnings(votes, profile);\n const errors = votes\n .filter((vote) => vote.status === 'failed' || vote.status === 'invalid')\n .map((vote) => `${vote.seatId}: ${vote.error ?? vote.status}`);\n\n if (question.signal?.aborted) {\n return resultEnvelope({\n status: 'cancelled',\n reason: 'Council call cancelled.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (timeoutSignal.aborted) {\n return resultEnvelope({\n status: 'failed',\n reason: 'Council overall timeout exceeded.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, 'Council overall timeout exceeded.'],\n });\n }\n\n if (!question.options || question.options.length === 0) {\n return this.resolveOpenQuestion(\n question,\n profile,\n votes,\n signal,\n usage,\n startedAt,\n warnings,\n errors,\n );\n }\n return this.resolveOptionQuestion(\n question,\n profile,\n votes,\n signal,\n usage,\n startedAt,\n warnings,\n errors,\n );\n }\n\n private async callSeat(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n seat: ResolvedCouncilSeat,\n seatIndex: number,\n signal: AbortSignal,\n usage: UsageAccumulator,\n ): Promise<CouncilVoteResult> {\n if (signal.aborted) return cancelledVote(seat);\n let persona;\n try {\n persona = this.personas.require(seat.persona);\n } catch (error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'failed',\n error: errorMessage(error),\n };\n }\n const result = await this.safeCall({\n system: buildCouncilVoterSystemPrompt(persona),\n userPrompt: buildCouncilVoterUserPrompt(question, seat, {\n refusalOptionId: question.options?.length ? this.refusalOptionId : undefined,\n }),\n target: seat.target,\n maxTokens: profile.voterMaxTokens,\n timeoutMs: profile.perCallTimeoutMs,\n signal,\n usage,\n seatIndex,\n });\n\n const metadata = callMetadata(result);\n if (result.error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: signal.aborted ? 'cancelled' : 'failed',\n ...metadata,\n error: result.error,\n };\n }\n const parsed = parseVote(result.text, question, this.refusalOptionId);\n if (!parsed.ok) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'invalid',\n ...metadata,\n error: parsed.error,\n };\n }\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'valid',\n ...parsed.vote,\n ...metadata,\n };\n }\n\n private async resolveOptionQuestion(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n signal: AbortSignal,\n usage: UsageAccumulator,\n startedAt: number,\n warnings: string[],\n errors: string[],\n ): Promise<CouncilResult> {\n const validVotes = votes.filter(\n (vote): vote is CouncilVoteResult & { optionId: string } =>\n vote.status === 'valid' && typeof vote.optionId === 'string',\n );\n const resolution = resolveCouncilVotes({\n seats: profile.seats.map((seat) => ({\n id: seat.id,\n weight: seat.weight,\n veto: seat.veto,\n })),\n votes: validVotes.map((vote) => ({ seatId: vote.seatId, optionId: vote.optionId })),\n refusalOptionId: this.refusalOptionId,\n quorumFraction: profile.quorumFraction,\n approvalFraction: profile.approvalFraction,\n });\n\n if (resolution.status === 'abstained') {\n return resultEnvelope({\n status: 'abstained',\n reason: 'Council quorum was not met.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (resolution.status === 'denied') {\n return resultEnvelope({\n status: 'denied',\n optionId: resolution.optionId,\n reason: `Council denied the proposal via ${resolution.method}.`,\n resolution: resolution.method,\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (resolution.status === 'decided') {\n return resultEnvelope({\n status: 'decided',\n optionId: resolution.optionId,\n answer: optionLabel(question, resolution.optionId),\n resolution: 'majority',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (!profile.judge) {\n return resultEnvelope({\n status: 'abstained',\n reason: `Council requires a judge (${resolution.reason}), but this profile has none.`,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n\n const judged = await this.callJudge(\n question,\n profile,\n votes,\n profile.judge,\n resolution.reason,\n signal,\n usage,\n );\n if (!judged.ok) {\n return resultEnvelope({\n status: signal.aborted ? 'cancelled' : 'abstained',\n reason: judged.error,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, judged.error],\n judgeUsed: true,\n });\n }\n if (judged.value.optionId === this.refusalOptionId) {\n return resultEnvelope({\n status: 'denied',\n optionId: this.refusalOptionId,\n reason: judged.value.rationale ?? 'Council judge refused all options.',\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n return resultEnvelope({\n status: 'decided',\n optionId: judged.value.optionId,\n answer: optionLabel(question, judged.value.optionId),\n reason: judged.value.rationale,\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n\n private async resolveOpenQuestion(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n signal: AbortSignal,\n usage: UsageAccumulator,\n startedAt: number,\n warnings: string[],\n errors: string[],\n ): Promise<CouncilResult> {\n const valid = votes.filter(\n (vote): vote is CouncilVoteResult & { stance: string } =>\n vote.status === 'valid' && typeof vote.stance === 'string',\n );\n if (valid.length / profile.seats.length < profile.quorumFraction) {\n return resultEnvelope({\n status: 'abstained',\n reason: 'Council quorum was not met.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (!profile.judge) {\n const first = valid[0];\n if (!first) {\n return resultEnvelope({\n status: 'failed',\n reason: 'Council produced no valid stance.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n return resultEnvelope({\n status: 'decided',\n answer: first.stance,\n reason: first.rationale,\n resolution: 'first_stance',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n\n const judged = await this.callJudge(\n question,\n profile,\n votes,\n profile.judge,\n 'open_question_synthesis',\n signal,\n usage,\n );\n if (!judged.ok) {\n return resultEnvelope({\n status: signal.aborted ? 'cancelled' : 'failed',\n reason: judged.error,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, judged.error],\n judgeUsed: true,\n });\n }\n return resultEnvelope({\n status: 'decided',\n answer: judged.value.answer,\n reason: judged.value.rationale,\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n\n private async callJudge(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n target: CouncilModelTarget,\n reason: string,\n signal: AbortSignal,\n usage: UsageAccumulator,\n ): Promise<{ ok: true; value: ParsedJudge } | { ok: false; error: string }> {\n const result = await this.safeCall({\n system: buildCouncilJudgeSystemPrompt(),\n userPrompt: buildCouncilJudgeUserPrompt(question, votes, {\n reason,\n refusalOptionId: question.options?.length ? this.refusalOptionId : undefined,\n }),\n target,\n maxTokens: profile.judgeMaxTokens,\n timeoutMs: profile.perCallTimeoutMs,\n signal,\n usage,\n });\n if (result.error) return { ok: false, error: result.error };\n return parseJudge(result.text, question, this.refusalOptionId);\n }\n\n /**\n * Resolve the effective LLM caller for a call. Voter seats use\n * `seatCaller(seatIndex)` when wired. Judge seats (seatIndex undefined)\n * use `judgeCaller` if set, otherwise `seatCaller(0)` if set, otherwise\n * the shared `caller`.\n */\n private resolveCaller(seatIndex?: number): CouncilLLMCaller {\n if (seatIndex !== undefined && this.seatCaller) {\n return this.seatCaller(seatIndex);\n }\n if (this.judgeCaller) return this.judgeCaller;\n if (this.seatCaller) return this.seatCaller(0);\n // Shared caller \u2014 guaranteed present by the constructor invariant\n // (at least one of `caller` / `seatCaller` / `judgeCaller` is required).\n return this.caller as CouncilLLMCaller;\n }\n\n private async safeCall(input: {\n system: string;\n userPrompt: string;\n target?: CouncilModelTarget | undefined;\n maxTokens: number;\n timeoutMs: number;\n signal: AbortSignal;\n usage: UsageAccumulator;\n seatIndex?: number | undefined;\n }): Promise<OneShotLLMResult> {\n const effectiveCaller = this.resolveCaller(input.seatIndex);\n\n const resolvedTarget = this.resolveCouncilTarget(input.target);\n\n try {\n const result = await effectiveCaller.call({\n system: input.system,\n userPrompt: input.userPrompt,\n responseFormat: { type: 'json_object' },\n maxTokens: input.maxTokens,\n timeoutMs: input.timeoutMs,\n signal: input.signal,\n ...(resolvedTarget?.providerId ? { providerId: resolvedTarget.providerId } : {}),\n ...(resolvedTarget?.model ? { model: resolvedTarget.model } : {}),\n ...(resolvedTarget?.role ? { role: resolvedTarget.role } : {}),\n ...(resolvedTarget?.fallbackModels && resolvedTarget.fallbackModels.length > 0\n ? { fallbackModels: [...resolvedTarget.fallbackModels] }\n : {}),\n });\n addUsage(input.usage, result);\n return result;\n } catch (error) {\n input.usage.calls += 1;\n return emptyCallResult(errorMessage(error));\n }\n }\n\n /**\n * Resolve a CouncilModelTarget: pre-resolve fallbackProfile to fallbackModels\n * so the downstream caller only sees the resolved chain.\n */\n private resolveCouncilTarget(\n target?: CouncilModelTarget | undefined,\n ): CouncilModelTarget | undefined {\n if (!target) return undefined;\n if (!target.fallbackProfile) return target;\n\n const mgr = this.fallbackProfileManager;\n if (!mgr) return target;\n const chain = mgr.resolve(target.fallbackProfile);\n if (chain.length === 0) return target;\n\n // Combine profile-resolved chain with any explicit fallbackModels\n const combined = [\n ...chain.map((e) => `${e.providerId}/${e.model}`),\n ...(target.fallbackModels ?? []),\n ];\n // Deduplicate while preserving order\n const seen = new Set<string>();\n const deduped = combined.filter((ref) => {\n if (seen.has(ref)) return false;\n seen.add(ref);\n return true;\n });\n\n return {\n ...(target.providerId ? { providerId: target.providerId } : {}),\n ...(target.model ? { model: target.model } : {}),\n ...(target.role ? { role: target.role } : {}),\n fallbackModels: deduped,\n };\n }\n}\n\nfunction parseVote(\n text: string,\n question: CouncilQuestion,\n refusalOptionId: string,\n): { ok: true; vote: ParsedVote } | { ok: false; error: string } {\n const parsed = parseObject(text);\n if (!parsed.ok && (!question.options || question.options.length === 0)) {\n // Optionless: if JSON parsing fails, use the raw text as stance\n // (backward compat with old council-brain behavior).\n const fallback = text.trim();\n if (fallback) return { ok: true, vote: { stance: fallback } };\n return { ok: false, error: 'Voter returned an empty response.' };\n }\n if (!parsed.ok) return parsed;\n const rationale = optionalString(parsed.value['rationale']);\n if (question.options && question.options.length > 0) {\n const optionId = optionalString(parsed.value['optionId']);\n const allowed = new Set([...question.options.map((option) => option.id.trim()), refusalOptionId]);\n if (!optionId || !allowed.has(optionId)) {\n return { ok: false, error: 'Voter returned an unknown or missing optionId.' };\n }\n return { ok: true, vote: { optionId, ...(rationale ? { rationale } : {}) } };\n }\n const stance = optionalString(parsed.value['stance']);\n if (!stance) return { ok: false, error: 'Voter returned an empty or missing stance.' };\n return { ok: true, vote: { stance, ...(rationale ? { rationale } : {}) } };\n}\n\nfunction parseJudge(\n text: string,\n question: CouncilQuestion,\n refusalOptionId: string,\n): { ok: true; value: ParsedJudge } | { ok: false; error: string } {\n const parsed = parseObject(text);\n if (!parsed.ok && (!question.options || question.options.length === 0)) {\n // Optionless: if JSON parsing fails, use raw text as answer\n const fallback = text.trim();\n if (fallback) return { ok: true, value: { answer: fallback } };\n return { ok: false, error: 'Judge returned an empty response.' };\n }\n if (!parsed.ok) return parsed;\n const rationale = optionalString(parsed.value['rationale']);\n if (question.options && question.options.length > 0) {\n const optionId = optionalString(parsed.value['optionId']);\n const allowed = new Set([...question.options.map((option) => option.id.trim()), refusalOptionId]);\n if (!optionId || !allowed.has(optionId)) {\n return { ok: false, error: 'Judge returned an unknown or missing optionId.' };\n }\n return { ok: true, value: { optionId, ...(rationale ? { rationale } : {}) } };\n }\n const answer = optionalString(parsed.value['answer']);\n if (!answer) return { ok: false, error: 'Judge returned an empty or missing answer.' };\n return { ok: true, value: { answer, ...(rationale ? { rationale } : {}) } };\n}\n\nfunction parseObject(\n text: string,\n): { ok: true; value: Record<string, unknown> } | { ok: false; error: string } {\n const trimmed = text.trim();\n const first = trimmed.indexOf('{');\n const last = trimmed.lastIndexOf('}');\n if (first < 0 || last < first) return { ok: false, error: 'LLM response did not contain JSON.' };\n try {\n const value: unknown = JSON.parse(trimmed.slice(first, last + 1));\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return { ok: false, error: 'LLM response JSON must be an object.' };\n }\n return { ok: true, value: value as Record<string, unknown> };\n } catch (error) {\n return { ok: false, error: `Invalid LLM response JSON: ${errorMessage(error)}` };\n }\n}\n\nfunction resultEnvelope(input: {\n status: CouncilResult['status'];\n answer?: string | undefined;\n optionId?: string | undefined;\n reason?: string | undefined;\n resolution: CouncilResult['resolution'];\n votes: CouncilVoteResult[];\n profile: ResolvedCouncilProfile;\n usage: UsageAccumulator;\n startedAt: number;\n warnings: string[];\n errors: string[];\n judgeUsed?: boolean | undefined;\n}): CouncilResult {\n const validVoteCount = input.votes.filter((vote) => vote.status === 'valid').length;\n return {\n status: input.status,\n ...(input.answer ? { answer: input.answer } : {}),\n ...(input.optionId ? { optionId: input.optionId } : {}),\n ...(input.reason ? { reason: input.reason } : {}),\n resolution: input.resolution,\n votes: Object.freeze([...input.votes]),\n configuredSeatCount: input.profile.seats.length,\n validVoteCount,\n distinctTargetCount: distinctTargetCount(input.votes, input.profile),\n judgeUsed: input.judgeUsed ?? false,\n usage: usageResult(input.usage, input.startedAt),\n ...(input.warnings.length > 0 ? { warnings: Object.freeze([...input.warnings]) } : {}),\n ...(input.errors.length > 0 ? { errors: Object.freeze([...input.errors]) } : {}),\n };\n}\n\nfunction callMetadata(result: OneShotLLMResult): Omit<CouncilVoteResult, 'seatId' | 'persona' | 'status'> {\n return {\n ...(result.provider ? { provider: result.provider } : {}),\n ...(result.model ? { model: result.model } : {}),\n ...(result.fromFallback ? { fromFallback: true } : {}),\n durationMs: result.durationMs,\n };\n}\n\nfunction addUsage(usage: UsageAccumulator, result: OneShotLLMResult): void {\n usage.calls += 1;\n usage.inputTokens += result.tokens.input;\n usage.outputTokens += result.tokens.output;\n usage.totalTokens += result.tokens.total;\n}\n\nfunction usageResult(usage: UsageAccumulator, startedAt: number): CouncilUsage {\n return Object.freeze({ ...usage, durationMs: Math.max(0, Date.now() - startedAt) });\n}\n\nfunction cancelledVote(seat: ResolvedCouncilSeat): CouncilVoteResult {\n return { seatId: seat.id, persona: seat.persona, status: 'cancelled', error: 'Cancelled.' };\n}\n\nfunction distinctTargetCount(\n votes: readonly CouncilVoteResult[],\n profile: ResolvedCouncilProfile,\n): number {\n const keys = votes\n .filter((vote) => vote.status === 'valid')\n .map((vote) =>\n profile.distinctness === 'provider'\n ? vote.provider\n : `${vote.provider ?? ''}/${vote.model ?? ''}`,\n )\n .filter(Boolean);\n return new Set(keys).size;\n}\n\nfunction distinctnessWarnings(\n votes: readonly CouncilVoteResult[],\n profile: ResolvedCouncilProfile,\n): string[] {\n if (profile.distinctness === 'none') return [];\n const valid = votes.filter((vote) => vote.status === 'valid');\n const distinct = distinctTargetCount(valid, profile);\n if (valid.length > 1 && distinct < valid.length) {\n return [\n `Council distinctness policy \"${profile.distinctness}\" was not met: ${distinct} distinct target(s) served ${valid.length} valid vote(s).`,\n ];\n }\n return [];\n}\n\nfunction optionLabel(question: CouncilQuestion, optionId: string | undefined): string | undefined {\n if (!optionId) return undefined;\n return question.options?.find((option) => option.id.trim() === optionId)?.label.trim();\n}\n\nfunction validateRefusalCollision(question: CouncilQuestion, refusalOptionId: string): void {\n if (question.options?.some((option) => option.id.trim() === refusalOptionId)) {\n throw new Error(`CouncilOrchestrator: option id \"${refusalOptionId}\" is reserved.`);\n }\n}\n\nfunction validateConcurrency(value: number): number {\n if (!Number.isSafeInteger(value) || value <= 0 || value > MAX_COUNCIL_CONCURRENCY) {\n throw new Error(\n `CouncilOrchestrator: maxConcurrency must be an integer in [1, ${MAX_COUNCIL_CONCURRENCY}].`,\n );\n }\n return value;\n}\n\nasync function mapConcurrent<T, R>(\n items: readonly T[],\n concurrency: number,\n worker: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let next = 0;\n const run = async (): Promise<void> => {\n while (true) {\n const index = next++;\n if (index >= items.length) return;\n const item = items[index];\n if (item !== undefined) results[index] = await worker(item, index);\n }\n };\n await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => run()));\n return results;\n}\n\nfunction emptyCallResult(error: string): OneShotLLMResult {\n return {\n text: '',\n model: '',\n provider: '',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: 0,\n fromFallback: false,\n error,\n };\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n", "import { CouncilOrchestrator } from '../execution/council-orchestrator.js';\nimport type { FallbackProfileManager } from '../core/fallback-profile-manager.js';\nimport type {\n CouncilLLMCaller,\n CouncilOption,\n CouncilProfileConfig,\n CouncilQuestion,\n CouncilResult,\n} from '../types/council.js';\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport type { CouncilPersonaRegistry } from '../execution/council-personas.js';\nimport type { CouncilProfileRegistry } from '../execution/council-profiles.js';\n\nexport const COUNCIL_TOOL_NAME = 'council';\nexport const MAX_COUNCIL_TOOL_OPTIONS = 12;\nexport const MAX_COUNCIL_QUESTION_CHARS = 20_000;\nexport const MAX_COUNCIL_CONTEXT_CHARS = 80_000;\n\nexport interface CouncilToolInput {\n question: string;\n context?: string | undefined;\n options?: CouncilOption[] | undefined;\n profile?: string | CouncilProfileConfig | undefined;\n}\n\nexport interface CreateCouncilToolOptions {\n caller: CouncilLLMCaller;\n personas?: CouncilPersonaRegistry | undefined;\n profiles?: CouncilProfileRegistry | undefined;\n defaultProfile?: string | undefined;\n maxConcurrency?: number | undefined;\n refusalOptionId?: string | undefined;\n /** Shared live FallbackProfileManager. */\n fallbackProfileManager?: FallbackProfileManager | undefined;\n}\n\nconst INPUT_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n question: {\n type: 'string',\n description: 'The decision or open question for the Council.',\n maxLength: MAX_COUNCIL_QUESTION_CHARS,\n },\n context: {\n type: 'string',\n description: 'Optional evidence and constraints. Treated as untrusted quoted data.',\n maxLength: MAX_COUNCIL_CONTEXT_CHARS,\n },\n options: {\n type: 'array',\n maxItems: MAX_COUNCIL_TOOL_OPTIONS,\n items: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Stable option id.' },\n label: { type: 'string', description: 'Human-readable option label.' },\n consequence: { type: 'string', description: 'Optional consequence or trade-off.' },\n },\n required: ['id', 'label'],\n additionalProperties: false,\n },\n description: 'Optional bounded list of choices. Omit for an open-ended Council answer.',\n },\n profile: {\n type: 'string',\n description: 'Registered Council profile id. Defaults to the host-configured profile.',\n },\n },\n required: ['question'],\n additionalProperties: false,\n};\n\n/** Create a read-only, bounded agent-callable Council tool. */\nexport function createCouncilTool(\n opts: CreateCouncilToolOptions,\n): Tool<CouncilToolInput, CouncilResult> {\n const orchestrator = new CouncilOrchestrator({\n ...opts,\n fallbackProfileManager: opts.fallbackProfileManager,\n });\n return {\n name: COUNCIL_TOOL_NAME,\n description:\n 'Ask an independent, multi-persona Council to evaluate a decision or synthesize an answer. ' +\n 'Uses bounded parallel voters, quorum/veto/weighted resolution, optional judging, model routing, fallback chains, and cancellation.',\n usageHint:\n 'Use for consequential or disputed decisions that benefit from independent lenses. ' +\n 'Provide `options` for a vote or omit them for an open answer. ' +\n 'Keep context evidence-focused; the Council treats it as untrusted data.',\n category: 'meta',\n inputSchema: INPUT_SCHEMA,\n permission: 'auto',\n mutating: false,\n riskTier: 'safe',\n managesOwnTimeout: true,\n maxOutputBytes: 256_000,\n async execute(input, _ctx, { signal }) {\n const question: CouncilQuestion = {\n question: input.question,\n ...(input.context ? { context: input.context } : {}),\n ...(input.options ? { options: input.options } : {}),\n ...(input.profile ? { profile: input.profile } : {}),\n signal,\n };\n return orchestrator.ask(question);\n },\n validate: validateCouncilToolInput,\n };\n}\n\nfunction validateCouncilToolInput(input: CouncilToolInput): string[] {\n const errors: string[] = [];\n const question = input.question?.trim() ?? '';\n if (!question) errors.push('`question` must not be empty.');\n if (question.length > MAX_COUNCIL_QUESTION_CHARS) {\n errors.push(`\\`question\\` must not exceed ${MAX_COUNCIL_QUESTION_CHARS} characters.`);\n }\n if ((input.context?.length ?? 0) > MAX_COUNCIL_CONTEXT_CHARS) {\n errors.push(`\\`context\\` must not exceed ${MAX_COUNCIL_CONTEXT_CHARS} characters.`);\n }\n if ((input.options?.length ?? 0) > MAX_COUNCIL_TOOL_OPTIONS) {\n errors.push(`\\`options\\` must not contain more than ${MAX_COUNCIL_TOOL_OPTIONS} items.`);\n }\n const ids = new Set<string>();\n for (const option of input.options ?? []) {\n const id = option.id.trim();\n if (!id) errors.push('Every option must have a non-empty `id`.');\n if (!option.label.trim()) errors.push(`Option \"${id || '<empty>'}\" must have a label.`);\n if (ids.has(id)) errors.push(`Duplicate option id \"${id}\".`);\n ids.add(id);\n }\n return errors;\n}\n", "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` \u2014 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` \u2014 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` \u2014 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 \u2014 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}\n", "/**\n * String utilities shared across the WrongStack codebase.\n */\n\n/**\n * Truncate a string to at most `max` characters, appending an ellipsis if it\n * was longer. Returns the original string unchanged when it fits.\n */\nexport function truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;\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 { toErrorMessage } from '../utils/error.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// \u2500\u2500 Error codes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 PARSE_FAILED: 'PARSE_FAILED',\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` \u2014 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// \u2500\u2500 Base error class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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// \u2500\u2500 Specific error classes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Tool execution errors \u2014 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 \u2014 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 \u2014 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/**\n * HTTP fetch error \u2014 thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 \u2192 transient, 404 \u2192 not_found, 401 \u2192 permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error \u2014 thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error \u2014 thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed \u2014 e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// \u2500\u2500 Type guards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n", "/**\n * Shared regex literals for classifying provider error messages as\n * account/plan-level quota exhaustion vs. per-request rate limiting.\n *\n * ## Why this module exists\n *\n * The same regex used by `classifyProviderError` (`packages/core/src/types/provider.ts`)\n * is also used by `isQuotaExhausted` in `provider-status-tracker.ts`. Hand-maintained\n * duplicates of a regex literal that mutates every release cycle (new provider\n * message shapes) silently drift \u2014 the two paths classify messages\n * inconsistently. Centralising the literal here makes a single edit take\n * effect on every caller.\n *\n * Callers MUST NOT re-declare these regexes locally. Import from this module.\n *\n * @module types/quota-regex\n */\n\nexport const QUOTA_EXHAUSTED_RE =\n /(?:insufficient|exhausted|depleted|exceeded|no|not enough)[-_\\s]*(?:quota|credit|balance)|(?:quota|credit|balance)(?:\\s+(?:has|have))?(?:\\s+been)?[-_\\s]*(?:exhausted|depleted|exceeded|insufficient)|billing[_\\s-]*(?:hard[_\\s-]*)?limit|payment required|spending limit|plan limit|usage[-_\\s]*limit[-_\\s]*(?:reached|exceeded)/i;\n\nexport const ROUTE_SCOPED_QUOTA_RE =\n /\\b(?:for|on)\\s+(?:(?:this|the)\\s+)?(?:route|model)\\b|\\b(?:route|model)(?:[-_\\s]+[\\w.-]+)?[-_\\s]*(?:quota|limit)\\b|\\b(?:quota|limit).{0,24}\\b(?:for|on)\\s+(?:(?:this|the)\\s+)?(?:route|model)\\b/i;\n", "import { truncate } from '../utils/string.js';\nimport type { ContentBlock, TextBlock } from './blocks.js';\nimport type { ErrorCode } from './errors.js';\nimport { ERROR_CODES, WrongStackError } from './errors.js';\nimport type { Message } from './messages.js';\nimport { QUOTA_EXHAUSTED_RE } from './quota-regex.js';\nimport type { Tool } from './tool.js';\n\n/**\n * Token usage for a single provider call, normalized across providers.\n *\n * Disjoint semantics: the four fields never overlap. `input` is the count\n * of FRESH input tokens (billed at the full input rate); `cacheRead` and\n * `cacheWrite` are separate cached subsets each priced at their own rate.\n * The total context the model loaded for this turn is\n * `input + (cacheRead ?? 0) + (cacheWrite ?? 0)`.\n *\n * Provider quirks normalized at the adapter layer:\n * - Anthropic: returns `input_tokens` already disjoint from cache fields.\n * - OpenAI / OpenAI-compatible: `prompt_tokens` is the TOTAL including\n * cached portion; the adapter subtracts `cached_tokens` to stay disjoint.\n * - Google: `promptTokenCount` likewise includes cache; adapter subtracts\n * `cachedContentTokenCount`.\n *\n * Cost math and the context-fullness chip both depend on the disjoint\n * invariant \u2014 a TOTAL `input` plus a separate `cacheRead` count would bill\n * cached tokens twice and skew cache-hit-ratio reporting.\n */\nexport type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';\nexport type CacheTtl = '5m' | '1h';\n\n/**\n * Provider-agnostic response-format directive.\n *\n * - `{ type: 'text' }` \u2014 free-form text (default).\n * - `{ type: 'json_object' }` \u2014 valid JSON without a schema constraint.\n * - `{ type: 'json_schema', jsonSchema: { name, schema, strict? } }` \u2014 JSON\n * constrained to the supplied JSON Schema. The `strict` flag is\n * OpenAI-specific; Gemini ignores it in favour of `responseMimeType`.\n *\n * Each provider adapter maps this into its own wire format:\n * OpenAI \u2192 `response_format`\n * Gemini \u2192 `responseMimeType` + `responseSchema`\n * Anthropic \u2192 (not yet supported; uses tools for structured output)\n */\nexport interface JsonSchemaSpec {\n name: string;\n /** OpenAI-specific: enable strict schema adherence. */\n strict?: boolean | undefined;\n /** The JSON Schema object describing the expected shape. */\n schema: Record<string, unknown>;\n /** Optional human-readable description (OpenAI). */\n description?: string | undefined;\n}\n\nexport type ResponseFormat =\n | { type: 'text' }\n | { type: 'json_object' }\n | { type: 'json_schema'; jsonSchema: JsonSchemaSpec };\n\n/**\n * Safety category threshold pair used by Google Gemini's `safetySettings`.\n *\n * Categories: `HARM_CATEGORY_HARASSMENT`, `HARM_CATEGORY_HATE_SPEECH`,\n * `HARM_CATEGORY_SEXUALLY_EXPLICIT`, `HARM_CATEGORY_DANGEROUS_CONTENT`.\n *\n * Thresholds: `BLOCK_NONE`, `BLOCK_ONLY_HIGH`, `BLOCK_MEDIUM_AND_ABOVE`,\n * `BLOCK_LOW_AND_ABOVE`.\n */\nexport interface SafetySetting {\n category: string;\n threshold: string;\n}\n\nexport interface Usage {\n input: number;\n output: number;\n cacheRead?: number | undefined;\n /** Back-compat aggregate of all cache-write tokens. Prefer TTL-specific fields when present. */\n cacheWrite?: number | undefined;\n cacheWrite5m?: number | undefined;\n cacheWrite1h?: number | undefined;\n}\n\n/**\n * Effective prompt tokens loaded by the model for one request.\n *\n * Provider adapters normalize `Usage` to disjoint fields: `input` is fresh\n * full-rate tokens, `cacheRead` is cached prefix tokens, and `cacheWrite` is\n * the cache-written prefix segment. Context-window pressure cares about the\n * full prompt the model saw, not only the bill-at-full-rate slice.\n */\nexport function effectiveInputTokens(usage: Usage): number {\n return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);\n}\n\nexport interface ReasoningRequest {\n enabled?: boolean | undefined;\n effort?: ReasoningEffort | undefined;\n preserve?: boolean | undefined;\n display?: 'summarized' | 'omitted' | undefined;\n}\n\nexport interface RequestCacheControl {\n ttl?: CacheTtl | undefined;\n /**\n * Provider-agnostic cache-partition key. A stable hash of the cacheable\n * system-prompt prefix (see `deriveCachePrefixKey`); requests sharing a prefix\n * share a key so provider backends route them to the same automatic-cache\n * partition. Consumed by OpenAI-family wires as `prompt_cache_key`; ignored by\n * Anthropic (which uses `ttl` + explicit `cache_control` markers).\n */\n key?: string | undefined;\n /**\n * Opt-in flag (from `ModelRuntimeCacheConfig.geminiExplicit`) telling the\n * Google provider to use explicit `cachedContents` for this request. Ignored\n * by other providers.\n */\n geminiExplicit?: boolean | undefined;\n /**\n * Resolved Gemini `cachedContents/*` resource name, injected by\n * `GoogleProvider.stream()` after it creates/reuses the cache. When present,\n * the Google wire sends `cachedContent` and OMITS the (now-cached) system\n * instruction + tool defs from the live body. Internal \u2014 never set by callers.\n */\n geminiCachedContentName?: string | undefined;\n}\n\nexport interface ReasoningConfig {\n default: 'enabled' | 'disabled' | 'adaptive' | 'always_on';\n disableSupported: boolean;\n effortSupported: boolean;\n effortLevels: ReasoningEffort[];\n preserveThinking: 'unsupported' | 'optional' | 'always_on';\n}\n\nexport interface Capabilities {\n tools: boolean;\n parallelTools: boolean;\n vision: boolean;\n streaming: boolean;\n promptCache: boolean;\n systemPrompt: boolean;\n jsonMode: boolean;\n reasoning: boolean;\n maxContext: number;\n /**\n * Maximum output tokens the model can produce in a single response.\n * Used as the default for `Request.maxTokens` when the caller doesn't\n * supply an explicit value \u2014 letting subagents run up to the model's\n * native ceiling instead of a fixed 8192 cap. Omit (undefined) to fall\n * back to a conservative default; populate per family in\n * `family-capabilities.ts` once you know the spec.\n */\n maxOutput?: number | undefined;\n cacheControl: 'native' | 'auto' | 'none';\n\n // \u2500\u2500 Extended parameter support (optional; family defaults in CAPABILITIES_BY_FAMILY) \u2500\u2500\n\n /** Model accepts `top_k` / `topK` sampling parameter. */\n topK?: boolean | undefined;\n /** Model accepts `frequency_penalty` / `frequencyPenalty` parameter. */\n frequencyPenalty?: boolean | undefined;\n /** Model accepts `presence_penalty` / `presencePenalty` parameter. */\n presencePenalty?: boolean | undefined;\n /** Model accepts `seed` parameter for deterministic generation. */\n seed?: boolean | undefined;\n /**\n * Model accepts JSON Schema / structured-output constraints\n * (OpenAI `response_format.json_schema`, Gemini `responseMimeType`+`responseSchema`).\n * Distinct from `jsonMode` (which is just a system-prompt hint).\n */\n structuredOutput?: boolean | undefined;\n /** Model supports log-probability output (`logprobs`, `top_logprobs`). */\n logprobs?: boolean | undefined;\n /** Model supports audio input/output modality. */\n audio?: boolean | undefined;\n /** Model supports the `n` parameter for multiple completions. */\n multipleCompletions?: boolean | undefined;\n}\n\nexport interface Request {\n model: string;\n system?: TextBlock[] | undefined;\n messages: Message[];\n tools?: Tool[] | undefined;\n /**\n * Cap on output tokens for this single response. Optional \u2014 when\n * omitted, the provider adapter falls back to its own\n * `capabilities.maxOutput` (which the catalog populates from\n * `ModelsDevModel.limit.output`). If neither is available, the\n * adapter applies a conservative 8192 safety net. Letting this stay\n * undefined at the call site means callers like Chimera can hand the\n * model its native output ceiling without hard-coding a number.\n */\n maxTokens?: number | undefined;\n temperature?: number | undefined;\n topP?: number | undefined;\n topK?: number | undefined;\n frequencyPenalty?: number | undefined;\n presencePenalty?: number | undefined;\n seed?: number | undefined;\n /**\n * End-user identifier for abuse monitoring and per-user rate limiting.\n * - Anthropic \u2192 `metadata.user_id`\n * - OpenAI \u2192 `user`\n * - Gemini \u2192 (not supported)\n */\n user?: string | undefined;\n /**\n * Number of response candidates to generate. Google Gemini supports\n * this via `generationConfig.candidateCount`. OpenAI does not have\n * an equivalent (`n` is conceptually similar but distinct).\n */\n candidateCount?: number | undefined;\n /**\n * Whether to return log probabilities for output tokens.\n * - OpenAI \u2192 `logprobs: boolean` (+ `topLogprobs: number`)\n * - Gemini \u2192 `generationConfig.logprobs: number` (how many top candidates)\n * Default undefined = no logprobs requested.\n */\n logprobs?: boolean | undefined;\n /**\n * Number of most probable tokens to return log probabilities for\n * (OpenAI `top_logprobs`). Only meaningful when `logprobs` is true.\n * Range: 0-20. Gemini ignores this (uses `logprobs` as the count).\n */\n topLogprobs?: number | undefined;\n stopSequences?: string[] | undefined;\n toolChoice?: 'auto' | 'required' | 'none' | { type: 'tool' | undefined; name: string };\n reasoning?: ReasoningRequest | undefined;\n cache?: RequestCacheControl | undefined;\n /**\n * Structured-output / response-format directive.\n * When set, the provider adapter maps this to its native response-format\n * parameter (OpenAI `response_format`, Gemini `responseMimeType`, etc.).\n * The model must advertise `capabilities.structuredOutput` for this to be\n * honoured; unsupported models will likely 400 or ignore it.\n */\n responseFormat?: ResponseFormat | undefined;\n /**\n * Safety category thresholds for filtering harmful content.\n * - Gemini \u2192 top-level `safetySettings` array with `{ category, threshold }`\n * - OpenAI \u2192 not supported (uses server-side moderation)\n * - Anthropic \u2192 not supported\n */\n safetySettings?: SafetySetting[] | undefined;\n}\n\nexport type StopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | 'refusal';\n\nexport interface Response {\n content: ContentBlock[];\n stopReason: StopReason;\n usage: Usage;\n model: string;\n}\n\nexport type StreamEvent =\n | { type: 'message_start'; model: string }\n | {\n type: 'content_block_start';\n kind: 'text' | 'tool_use' | 'thinking';\n id?: string | undefined;\n name?: string | undefined;\n }\n | { type: 'content_block_stop'; index: number }\n | { type: 'text_delta'; text: string }\n | { type: 'tool_use_start'; id: string; name: string }\n | { type: 'tool_use_input_delta'; id: string; partial: string }\n | { type: 'tool_use_stop'; id: string; input: unknown; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_start'; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_delta'; text: string }\n | { type: 'thinking_signature'; signature: string }\n | { type: 'thinking_stop' }\n | { type: 'message_stop'; stopReason: StopReason; usage: Usage };\n\nexport interface Provider {\n readonly id: string;\n readonly capabilities: Capabilities;\n /** Canonical streaming entry point. `complete()` defaults to a wrapper that\n * aggregates this stream \u2014 providers may override for non-streaming wires. */\n stream(req: Request, opts: { signal: AbortSignal }): AsyncIterable<StreamEvent>;\n complete(req: Request, opts: { signal: AbortSignal }): Promise<Response>;\n}\n\n/**\n * Structured body parsed from a provider's HTTP error response. Populated\n * best-effort: providers return JSON shaped differently (Anthropic uses\n * `{error: {type, message}}`, OpenAI uses `{error: {message, code}}`,\n * Google uses `{error: {status, message}}`), so the fields here are the\n * intersection that's usable for rendering and routing.\n */\nexport interface ProviderErrorBody {\n /** Provider-specific kind, e.g. \"overloaded_error\", \"rate_limit_error\", \"invalid_request_error\". */\n type?: string | undefined;\n /** Human-readable explanation from the provider. */\n message?: string | undefined;\n /** Provider request id, when present in the body or headers. */\n requestId?: string | undefined;\n /** Parsed Retry-After header (or equivalent body hint) in milliseconds. */\n retryAfterMs?: number | undefined;\n /** The raw response body (truncated to ~2 KB), kept for debugging. */\n raw?: string | undefined;\n /** True when `raw` was truncated; check `rawLength` for the original size. */\n truncated?: boolean | undefined;\n /** Original length of the response body in bytes, when `truncated` is true. */\n rawLength?: number | undefined;\n}\n\n/**\n * Canonical provider-failure taxonomy. Computed ONCE at error-construction\n * time (`classifyProviderError`) and carried on `ProviderError.kind` so\n * every downstream consumer \u2014 retry policy, cross-provider fallback,\n * recovery strategies, the subagent error classifier \u2014 branches on the\n * same classification instead of re-deriving it from status codes and\n * message regexes. When a new provider's error format needs special\n * handling, this module is the only place to teach it.\n */\nexport type ProviderErrorKind =\n | 'rate_limit' // 429 / rate_limit_error \u2014 back off (honour Retry-After), then failover\n | 'quota_exhausted' // credits/plan depleted \u2014 do not retry same route; fail over immediately\n | 'overloaded' // 529 / overloaded_error \u2014 retry with backoff, then failover\n | 'server' // other 5xx \u2014 retry same provider\n | 'timeout' // 408 request timeout\n | 'network' // status 0 \u2014 connection/DNS failure before a response arrived\n | 'stream_hang' // 599 sentinel \u2014 stream stalled mid-response (StreamHangError)\n | 'auth' // 401/403 \u2014 key invalid/expired; retrying without action is pointless\n | 'context_overflow' // 413 or an overflow-shaped 4xx \u2014 compact, don't retry as-is\n | 'content_filter' // provider refused on policy grounds \u2014 a sibling model may pass, but the `content_filter_reroute` recovery strategy owns that hop, NOT the fallback engine (which surfaces this kind)\n | 'invalid_request' // other 4xx \u2014 request is malformed; retrying won't help\n | 'unknown';\n\n/**\n * Overflow-shaped provider messages. Union of the patterns previously\n * scattered across `error-handler.ts` and `coordinator/error-classifier.ts`\n * (which had drifted apart) \u2014 keep additions here, nowhere else.\n */\nconst CONTEXT_OVERFLOW_RE =\n /context.length|context.window|maximum context|max.*tokens?.*exceeded|prompt is too long|too long|exceeds the context|\\btokens\\b.*exceed|too many tokens|reduce the length|resulted in \\d+ tokens|input.{0,12}too (?:large|long)|context_length_exceeded/i;\n\n/** Content-policy refusals surfaced as HTTP errors (Azure/OpenAI `content_filter`, etc.). */\nconst CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;\n/** \"rate limit exceeded\" pattern \u2014 checked against body.message only, NOT the\n * raw JSON text, because OpenAI's `\"code\":\"rate_limit_exceeded\"` field would\n * produce a false positive in the combined-text regex. */\nconst RATE_LIMIT_EXCEEDED_RE = /rate[-_\\s]*limit[-_\\s]*exceeded/i;\n\n/**\n * Classify a provider HTTP failure into the canonical taxonomy from its\n * status code plus the parsed error body (and, for message-only errors\n * without a structured body, the error message itself). Pure and total \u2014\n * always returns a kind, never throws.\n */\nexport function classifyProviderError(\n status: number,\n body?: ProviderErrorBody,\n message?: string,\n): ProviderErrorKind {\n const type = body?.type;\n const text = [message, body?.message, type, body?.raw].filter(Boolean).join('\\n');\n if (status === 0) return 'network';\n if (status === 408) return 'timeout';\n if (status === 599) return 'stream_hang';\n if (status === 402 || QUOTA_EXHAUSTED_RE.test(text)) return 'quota_exhausted';\n // Check body.message separately for \"rate limit exceeded\" \u2014 this pattern\n // should NOT match against body.raw because OpenAI's error response\n // includes `\"code\":\"rate_limit_exceeded\"` in the JSON, which would be a\n // false positive (it's a transient burst, not a hard limit).\n if (status === 429 && body?.message && RATE_LIMIT_EXCEEDED_RE.test(body.message)) {\n return 'quota_exhausted';\n }\n if (type === 'rate_limit_error' || status === 429) return 'rate_limit';\n if (type === 'overloaded_error' || status === 529) return 'overloaded';\n if (status >= 500) return 'server';\n if (\n type === 'authentication_error' ||\n type === 'permission_error' ||\n status === 401 ||\n status === 403\n ) {\n return 'auth';\n }\n if (type === 'content_filter' || CONTENT_FILTER_RE.test(text)) return 'content_filter';\n if (status === 413 || (status >= 400 && CONTEXT_OVERFLOW_RE.test(text))) {\n return 'context_overflow';\n }\n if (status >= 400) return 'invalid_request';\n return 'unknown';\n}\n\n// \u2500\u2500 Prose reset-hint parsing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Many providers answer an exhausted hourly/daily/weekly/monthly budget with\n// a 429/402 whose *message prose* says when the limit resets \u2014 e.g.\n// \"Please try again in 6h12m\" (OpenAI, Go durations)\n// \"usage limit reached; resets in 2 hours\" (plan-cap notices)\n// \"Your usage limit resets at 2026-07-28T00:00:00Z\" (weekly caps)\n// When no structured `Retry-After` header was captured into\n// `ProviderErrorBody.retryAfterMs`, the waiting room should still honor the\n// provider-published reset instead of falling back to a fixed default block\n// (which probes a weekly cap every 15 minutes).\n//\n// `parseResetHintMs` extracts that hint. It is deliberately conservative:\n// only text following an explicit lead-in (\"try again in\", \"retry after\",\n// \"reset(s) in/at/on\", \"available in\") is parsed, garbage yields `undefined`,\n// and any parsed delay is clamped to `MAX_RESET_HINT_MS` so a corrupt or\n// absurd message cannot park a model forever (manual `retryNow()` and the\n// periodic sweep remain the escape hatches).\n\n/** Upper bound for any prose-parsed reset delay: 7 days. */\nexport const MAX_RESET_HINT_MS = 7 * 24 * 60 * 60 * 1_000;\n\nconst RESET_HINT_LEAD_RE =\n /(?:try again|retry|resets?|resetting|available|returns?|back online|usable again)\\s+(?:in|after)\\s+/i;\nconst RESET_AT_LEAD_RE = /resets?\\s+(?:at|on)\\s+/i;\n\n/** Longest-unit-first so `minutes` wins over `m`; `(?![a-z])` keeps `12m0.5s` compound durations intact. */\nconst DURATION_TOKEN_RE =\n /(\\d+(?:\\.\\d+)?)\\s*(ms|secs?|seconds?|s|mins?|minutes?|m|hrs?|hours?|h|days?|d)(?![a-z])/gi;\n\nconst UNIT_MS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n};\n\nfunction unitMs(unit: string): number {\n const u = unit.toLowerCase();\n if (u === 'ms') return 1;\n if (u.startsWith('s')) return UNIT_MS['s']!;\n if (u.startsWith('m')) return UNIT_MS['m']!;\n if (u.startsWith('h')) return UNIT_MS['h']!;\n return UNIT_MS['d']!;\n}\n\nconst ISO_TIMESTAMP_RE =\n /(\\d{4}-\\d{2}-\\d{2}(?:[T ]\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:\\s*(?:Z|[+-]\\d{2}:?\\d{2}|UTC|GMT))?)?)/i;\n\n/**\n * Parse a prose reset/retry hint from a provider error message into\n * milliseconds-from-`now`. Returns `undefined` when no usable hint exists.\n *\n * @param message - Provider error message (body.message / error text).\n * @param now - Reference timestamp (ms epoch); injectable for tests.\n */\nexport function parseResetHintMs(message: string, now: number = Date.now()): number | undefined {\n if (!message) return undefined;\n\n // 1. Relative duration: \"try again in 6h12m\", \"retry after 90 seconds\",\n // \"resets in 2 hours\", \"available in 1 day\".\n const lead = RESET_HINT_LEAD_RE.exec(message);\n if (lead) {\n const window = message.slice(lead.index + lead[0].length, lead.index + lead[0].length + 80);\n let total = 0;\n let matched = false;\n DURATION_TOKEN_RE.lastIndex = 0;\n for (let m = DURATION_TOKEN_RE.exec(window); m; m = DURATION_TOKEN_RE.exec(window)) {\n const value = Number.parseFloat(m[1]!);\n if (Number.isFinite(value) && value > 0) {\n total += value * unitMs(m[2]!);\n matched = true;\n }\n }\n // Bare-word units: \"try again in an hour\" / \"retry after a minute\".\n if (!matched) {\n const bare = /^(?:an?\\s+)?(second|minute|hour|day)\\b/i.exec(window.trim());\n if (bare) {\n total = unitMs(bare[1]!);\n matched = true;\n }\n }\n if (matched && total > 0) {\n return Math.min(total, MAX_RESET_HINT_MS);\n }\n }\n\n // 2. Absolute timestamp: \"resets at 2026-07-28T00:00:00Z\",\n // \"reset on 2026-08-01 00:00 UTC\".\n const atLead = RESET_AT_LEAD_RE.exec(message);\n if (atLead) {\n const window = message.slice(atLead.index + atLead[0].length);\n const iso = ISO_TIMESTAMP_RE.exec(window);\n if (iso) {\n // Normalize \"2026-08-01 00:00 UTC\" \u2192 \"2026-08-01T00:00Z\" so Date.parse\n // is deterministic across JS engines.\n const normalized = iso[1]!\n .replace(/^(\\d{4}-\\d{2}-\\d{2}) (\\d{2}:\\d{2})/, '$1T$2')\n .replace(/\\s*(UTC|GMT)$/i, 'Z');\n const ts = Date.parse(normalized);\n if (Number.isFinite(ts) && ts > now) {\n return Math.min(ts - now, MAX_RESET_HINT_MS);\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Whether a kind is worth retrying against the SAME provider/model.\n * `context_overflow` is deliberately false \u2014 the request must shrink first;\n * `auth`/`invalid_request`/`content_filter` won't improve on replay.\n *\n * Exhaustive by construction (`Record<ProviderErrorKind, \u2026>`): adding a new\n * kind refuses to compile until it is classified here. Every kind\u2192X mapping\n * in the codebase follows this drift-guard pattern \u2014 see also KIND_TO_CODE\n * below, DefaultRetryPolicy.maxAttempts, fallback-model shouldFallback, and\n * the coordinator's providerErrorToSubagentError.\n */\nexport function isRetryableKind(kind: ProviderErrorKind): boolean {\n return RETRYABLE_BY_KIND[kind];\n}\n\nconst RETRYABLE_BY_KIND: Record<ProviderErrorKind, boolean> = {\n rate_limit: true,\n quota_exhausted: false,\n overloaded: true,\n server: true,\n timeout: true,\n network: true,\n stream_hang: true,\n auth: false,\n context_overflow: false,\n content_filter: false,\n invalid_request: false,\n unknown: false,\n};\n\n/**\n * Whether a kind is worth HOPPING to a different provider/model \u2014 the gate for\n * the cross-provider fallback engine (agent-loop extension AND the one-shot\n * orchestrator both branch on this ONE table, so their behavior can't drift).\n *\n * A distinct question from {@link isRetryableKind} (retry the SAME model):\n * a hop only helps for capacity/transport failures. Request-shaped failures\n * surface instead \u2014 `context_overflow` needs compaction, `content_filter` is\n * owned by the `content_filter_reroute` recovery strategy, and `auth` /\n * `invalid_request` are user-actionable and would fail identically on a hop.\n * The value set is currently identical to the retryable set, but it is kept as\n * its own table on purpose: the two answer different questions and may diverge.\n *\n * Exhaustive by construction (`Record<ProviderErrorKind, \u2026>`) \u2014 a new kind\n * refuses to compile until it is classified here.\n */\nexport function isFallbackWorthy(kind: ProviderErrorKind): boolean {\n return FALLBACK_WORTHY_BY_KIND[kind];\n}\n\nconst FALLBACK_WORTHY_BY_KIND: Record<ProviderErrorKind, boolean> = {\n rate_limit: true,\n quota_exhausted: true,\n overloaded: true,\n server: true,\n timeout: true,\n network: true,\n stream_hang: true,\n auth: false,\n context_overflow: false,\n content_filter: false,\n invalid_request: false,\n unknown: false,\n};\n\nexport class ProviderError extends WrongStackError {\n public readonly status: number;\n public readonly retryable: boolean;\n public readonly providerId: string;\n /** Canonical failure classification \u2014 see {@link ProviderErrorKind}. */\n public readonly kind: ProviderErrorKind;\n public readonly body?: ProviderErrorBody | undefined;\n\n /**\n * Duck-type guard: checks whether an unknown value *looks like* a\n * ProviderError by probing for its structural properties. Use this\n * anywhere the constructor identity might cross a package boundary\n * (e.g. `@wrongstack/providers` creates the error, but the runner in\n * `@wrongstack/core` checks it). A plain `instanceof ProviderError`\n * can fail when npm hoists duplicate copies of `@wrongstack/core`,\n * each with its own class identity.\n *\n * The check tests for the four invariant properties defined in the\n * constructor: `name === 'ProviderError'`, `status` (number),\n * `retryable` (boolean), and `kind` (string). This tolerates both\n * true `ProviderError` instances and cross-boundary copies.\n */\n static isProviderError(err: unknown): err is ProviderError {\n if (!err || typeof err !== 'object') return false;\n const e = err as Record<string, unknown>;\n // Accept both ProviderError and its subclasses (e.g. StreamHangError) by\n // checking for the structural invariant properties defined in the\n // constructor. The `name` check accepts 'ProviderError' and any subclass\n // name that ends with 'Error' \u2014 this tolerates both true instances and\n // cross-boundary copies where instanceof may fail due to npm hoisting.\n const name = e.name;\n if (typeof name !== 'string' || !name.endsWith('Error')) return false;\n return (\n typeof e.status === 'number' &&\n typeof e.retryable === 'boolean' &&\n typeof e.kind === 'string'\n );\n }\n\n constructor(\n message: string,\n status: number,\n retryable: boolean,\n providerId: string,\n opts: {\n body?: ProviderErrorBody | undefined;\n cause?: unknown | undefined;\n /** Override the computed classification (rarely needed \u2014 tests, custom wires). */\n kind?: ProviderErrorKind | undefined;\n } = {},\n ) {\n const kind = opts.kind ?? classifyProviderError(status, opts.body, message);\n super({\n message,\n code: kindToCode(kind),\n subsystem: 'provider',\n severity: status >= 500 ? 'error' : 'warning',\n recoverable: retryable,\n context: { providerId, status },\n cause: opts.cause,\n });\n this.name = 'ProviderError';\n this.status = status;\n this.retryable = retryable;\n this.providerId = providerId;\n this.kind = kind;\n this.body = opts.body;\n }\n\n /**\n * Render a one-line, user-facing description. Designed for the CLI/TUI\n * status line and the agent's retry warning. Avoids dumping raw JSON\n * (which is what users see today when a 529 lands and the log message\n * includes the full `{\"type\":\"error\",...}` body).\n *\n * Examples:\n * \"minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0\u2026]\"\n * \"openai rate limited (429): Retry after 12s\"\n * \"anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'\"\n * \"groq HTTP 500 (server error)\"\n */\n override describe(): string {\n const kind = describeStatus(this.status, this.body?.type);\n const head = `${this.providerId} ${kind}`;\n const detail = this.body?.message?.trim();\n const reqId = this.body?.requestId\n ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? '\u2026' : ''}]`\n : '';\n if (detail && detail.length > 0) {\n return `${head}: ${truncate(detail, 240)}${reqId}`;\n }\n return `${head}${reqId}`;\n }\n}\n\n/**\n * Belt-and-suspenders overflow detection for the recovery layer. Returns true\n * when a `ProviderError` is *shaped* like a context overflow even if its `kind`\n * says otherwise \u2014 an HTTP 413, or an overflow phrase anywhere in its message /\n * body. Gateways and proxies sometimes relabel an overflow as a generic\n * `invalid_request`/400 (or a caller constructs the error with an explicit\n * wrong `kind`); the `context_overflow_reduce` strategy uses this so those\n * still trigger compact-and-retry instead of failing terminally.\n */\nexport function isContextOverflowShaped(err: unknown): boolean {\n if (!(err instanceof ProviderError) && !ProviderError.isProviderError(err)) return false;\n const providerErr = err as ProviderError;\n if (providerErr.kind === 'context_overflow' || providerErr.status === 413) return true;\n if (providerErr.status < 400) return false;\n const text = [providerErr.message, providerErr.body?.message, providerErr.body?.type, providerErr.body?.raw]\n .filter(Boolean)\n .join('\\n');\n return CONTEXT_OVERFLOW_RE.test(text);\n}\n\nfunction describeStatus(status: number, type?: string): string {\n if (status === 0) return 'network error';\n if (status === 599) return `stream hang (${status})`;\n if (type === 'overloaded_error' || status === 529) return `overloaded (${status})`;\n if (type === 'rate_limit_error' || status === 429) return `rate limited (${status})`;\n if (type === 'authentication_error' || status === 401) return `auth failed (${status})`;\n if (type === 'permission_error' || status === 403) return `forbidden (${status})`;\n if (type === 'not_found_error' || status === 404) return `not found (${status})`;\n if (type === 'content_filter') return `content filtered (${status})`;\n if (type === 'invalid_request_error' || status === 400) return `invalid request (${status})`;\n if (status === 408) return `timeout (${status})`;\n if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;\n if (type) return `${type} (${status})`;\n return `HTTP ${status}`;\n}\n\n/**\n * Thrown when the provider stream stops delivering data mid-response.\n * This is distinct from a network error (TCP reset, DNS failure) \u2014 the\n * connection is established and the response started, but chunks stopped\n * arriving before the stream completed.\n *\n * Status 599 is used as a sentinel to distinguish stream hangs from\n * regular HTTP errors while still flowing through ProviderError-based\n * retry and fallback infrastructure.\n */\nexport class StreamHangError extends ProviderError {\n /** Name of the provider that hung, e.g. \"zai\", \"anthropic\". */\n public readonly hungProviderId: string;\n /** Model that was being called when the hang occurred. */\n public readonly hungModel: string;\n /** How long (ms) we waited for the next chunk before declaring a hang. */\n public readonly hangTimeoutMs: number;\n /** How many bytes were received before the hang. */\n public readonly bytesReceived: number;\n /** Elapsed time (ms) from the start of the stream until the hang. */\n public readonly elapsedMs: number;\n\n constructor(opts: {\n providerId: string;\n model: string;\n hangTimeoutMs: number;\n bytesReceived: number;\n elapsedMs: number;\n cause?: unknown | undefined;\n }) {\n super(\n `Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,\n 599,\n true, // always retryable\n opts.providerId,\n {\n body: {\n message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`,\n },\n cause: opts.cause,\n },\n );\n this.name = 'StreamHangError';\n this.hungProviderId = opts.providerId;\n this.hungModel = opts.model;\n this.hangTimeoutMs = opts.hangTimeoutMs;\n this.bytesReceived = opts.bytesReceived;\n this.elapsedMs = opts.elapsedMs;\n }\n}\n\n/** Exhaustive kind \u2192 ErrorCode mapping \u2014 new kinds must be added here or the\n * file stops compiling (same drift-guard pattern as RETRYABLE_BY_KIND). */\nconst KIND_TO_CODE: Record<ProviderErrorKind, ErrorCode> = {\n network: ERROR_CODES.PROVIDER_NETWORK_ERROR,\n timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,\n rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,\n quota_exhausted: ERROR_CODES.PROVIDER_RATE_LIMITED,\n auth: ERROR_CODES.PROVIDER_AUTH_FAILED,\n overloaded: ERROR_CODES.PROVIDER_OVERLOADED,\n context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,\n server: ERROR_CODES.PROVIDER_SERVER_ERROR,\n stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,\n content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n};\n\nfunction kindToCode(kind: ProviderErrorKind): ErrorCode {\n return KIND_TO_CODE[kind];\n}\n", "import type { JSONSchema } from '../types/tool.js';\n\nexport interface ToolWireDefinitionLike {\n name: string;\n description?: string | undefined;\n inputSchema: unknown;\n}\n\nexport interface CompactToolDefinitionForWireOptions {\n /** Top-level tool description budget. */\n descriptionMaxChars?: number | undefined;\n /** Per-JSON-Schema `description` annotation budget. */\n schemaDescriptionMaxChars?: number | undefined;\n}\n\nexport interface CompactWireToolDefinition {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}\n\nconst TOOL_DESCRIPTION_MAX_CHARS = 400;\nconst SCHEMA_DESCRIPTION_MAX_CHARS = 120;\n\nconst compactCache = new WeakMap<object, CompactWireToolDefinition>();\n\n/**\n * Return the provider-wire version of a tool definition.\n *\n * Tool schemas remain structurally intact: validation keywords, property\n * names, required fields, enum values, and nested shapes are preserved. The\n * only reduction is on human prose annotations (`description`), which are the\n * largest repeated cost in provider tool declarations.\n */\nexport function compactToolDefinitionForWire(\n tool: ToolWireDefinitionLike,\n opts: CompactToolDefinitionForWireOptions = {},\n): CompactWireToolDefinition {\n const useDefaultOptions =\n opts.descriptionMaxChars === undefined && opts.schemaDescriptionMaxChars === undefined;\n if (useDefaultOptions && typeof tool === 'object' && tool !== null) {\n const cached = compactCache.get(tool);\n if (cached) return cached;\n }\n\n const compact: CompactWireToolDefinition = {\n name: tool.name,\n description: compactDescription(\n tool.description ?? '',\n opts.descriptionMaxChars ?? TOOL_DESCRIPTION_MAX_CHARS,\n ),\n inputSchema: normalizeTopLevelToolSchema(\n compactSchemaDescriptions(\n tool.inputSchema,\n opts.schemaDescriptionMaxChars ?? SCHEMA_DESCRIPTION_MAX_CHARS,\n ),\n ),\n };\n\n if (useDefaultOptions && typeof tool === 'object' && tool !== null) {\n compactCache.set(tool, compact);\n }\n return compact;\n}\n\n/**\n * Tool inputs are always JSON objects, but dynamically supplied MCP/plugin\n * schemas sometimes express that object as a top-level oneOf/anyOf/allOf.\n * Anthropic-family endpoints reject those combinators at the input_schema\n * root (including when reached through an OpenAI-compatible gateway such as\n * OmniRoute). Keep nested combinators intact and flatten only the root.\n * Runtime validation still uses the tool's original schema.\n */\nexport function normalizeTopLevelToolSchema(\n schema: Record<string, unknown>,\n): Record<string, unknown> {\n const combinators = (['oneOf', 'anyOf', 'allOf'] as const)\n .map((keyword) => ({ keyword, branches: schema[keyword] }))\n .filter((entry): entry is { keyword: 'oneOf' | 'anyOf' | 'allOf'; branches: unknown[] } =>\n Array.isArray(entry.branches),\n );\n if (combinators.length === 0) return schema;\n\n const out: Record<string, unknown> = { ...schema, type: 'object' };\n delete out['oneOf'];\n delete out['anyOf'];\n delete out['allOf'];\n\n const properties: Record<string, unknown> = isRecord(schema['properties'])\n ? { ...schema['properties'] }\n : {};\n let required = stringSet(schema['required']);\n\n for (const { keyword, branches } of combinators) {\n const objectBranches = branches.filter(isRecord);\n for (const branch of objectBranches) {\n if (isRecord(branch['properties'])) Object.assign(properties, branch['properties']);\n }\n\n const branchRequired = objectBranches.map((branch) => stringSet(branch['required']));\n if (keyword === 'allOf') {\n for (const fields of branchRequired) for (const field of fields) required.add(field);\n } else if (branchRequired.length > 0) {\n const common = new Set(\n [...branchRequired[0]!].filter((field) =>\n branchRequired.slice(1).every((fields) => fields.has(field)),\n ),\n );\n required = new Set([...required, ...common]);\n }\n }\n\n out['properties'] = properties;\n if (required.size > 0) out['required'] = [...required];\n else delete out['required'];\n return out;\n}\n\nfunction stringSet(value: unknown): Set<string> {\n return new Set(\n Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [],\n );\n}\n\nexport function compactSchemaDescriptions(\n schema: unknown,\n maxDescriptionChars = SCHEMA_DESCRIPTION_MAX_CHARS,\n): Record<string, unknown> {\n const compact = compactSchemaNode(schema, maxDescriptionChars);\n return isRecord(compact) ? compact : { type: 'object', properties: {} };\n}\n\nfunction compactSchemaNode(node: unknown, maxDescriptionChars: number): unknown {\n if (Array.isArray(node)) {\n return node.map((item) => compactSchemaNode(item, maxDescriptionChars));\n }\n if (!isRecord(node)) return node;\n\n const out: JSONSchema = {};\n for (const [key, value] of Object.entries(node)) {\n if (key === 'description' && typeof value === 'string') {\n out[key] = compactDescription(value, maxDescriptionChars);\n } else {\n out[key] = compactSchemaNode(value, maxDescriptionChars);\n }\n }\n return out;\n}\n\nexport function compactDescription(text: string, maxChars: number): string {\n const normalized = text.replace(/\\s+/g, ' ').trim();\n if (normalized.length <= maxChars) return normalized;\n if (maxChars <= 20) return normalized.slice(0, maxChars);\n\n const hardLimit = maxChars - 12;\n const boundary = findSemanticBoundary(normalized, hardLimit);\n const head = normalized.slice(0, boundary > 0 ? boundary : hardLimit).trimEnd();\n return `${head} ...`;\n}\n\nexport function findSemanticBoundary(text: string, limit: number): number {\n const punctuation = Math.max(\n text.lastIndexOf('. ', limit),\n text.lastIndexOf('; ', limit),\n text.lastIndexOf(': ', limit),\n );\n if (punctuation >= Math.floor(limit * 0.45)) return punctuation + 1;\n\n const comma = text.lastIndexOf(', ', limit);\n if (comma >= Math.floor(limit * 0.6)) return comma + 1;\n\n const space = text.lastIndexOf(' ', limit);\n return space >= Math.floor(limit * 0.6) ? space : limit;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n", "import type { Message } from '../types/messages.js';\nimport { compactToolDefinitionForWire } from './tool-wire-compact.js';\n\n/**\n * Shared token estimation with JSON.stringify caching.\n * Avoids repeated stringification of tool input objects.\n *\n * ## Calibration\n *\n * `estimateRequestTokens` uses a fixed 3.5 chars/token heuristic \u2014 a\n * conservative overestimate that prevents underestimation but reduces\n * accuracy. After each API call, call `recordActualUsage()` with the\n * provider-authoritative effective prompt tokens (`input + cacheRead +\n * cacheWrite` after adapter normalization). The module maintains a rolling\n * average of `actual / estimated` ratio (EWM, \u03B1=0.3) and applies it to\n * subsequent calls via `estimateRequestTokensCalibrated`.\n *\n * Calibration is per-module (shared across all callers), which is\n * sufficient: the chars/token ratio is a property of the tokenizer,\n * not the model. Uncalibrated calls (before any samples, or when\n * `recordActualUsage` is not called) fall back to the uncalibrated\n * estimate so nothing breaks.\n */\n\nconst RoughTokenEstimate = (text: string, charsPerToken = 3.5): number =>\n Math.max(1, Math.ceil(text.length / charsPerToken));\n\n/** Calibration state: actual/estimated ratio via exponential weighted moving average. */\ninterface CalState {\n ratio: number; // current calibration multiplier (actual / estimated)\n count: number; // number of samples recorded\n prevEst: number; // estimated tokens from the most recent estimateRequestTokens call\n}\n\n/** EWM \u03B1 \u2014 higher = faster adaptation, more volatile. */\nconst CAL_ALPHA = 0.3;\n\n/**\n * Calibration is keyed so that, in a multi-agent / model-switching process,\n * each (provider, model) tokenizer gets its own ratio instead of all of them\n * collapsing onto one shared number. Callers that don't pass a key use the\n * shared `__global__` bucket \u2014 that preserves the original single-session\n * behavior and keeps all existing call sites working unchanged.\n */\nconst CALIBRATION_GLOBAL_KEY = '__global__';\nconst _cals = new Map<string, CalState>();\n\nfunction calState(key: string): CalState {\n let state = _cals.get(key);\n if (!state) {\n state = { ratio: 1.0, count: 0, prevEst: 0 };\n _cals.set(key, state);\n }\n return state;\n}\n\nconst MIN_SAMPLES_FOR_CALIBRATION = 3;\n\n/**\n * Fallback chars/token ratios per model family for providers that don't return\n * usage data. Used when `recordActualUsage` receives zero/negative tokens and\n * we have enough samples to trust the fallback. Keys are lowercase prefixes.\n */\nconst MODEL_FAMILY_RATIO: Record<string, number> = {\n // Anthropic: ~3.8-4.0 chars/token depending on model\n claude: 3.8,\n // OpenAI: ~4.0 chars/token\n 'gpt-4': 4.0,\n 'gpt-3.5': 4.0,\n // Google: ~3.5 chars/token\n gemini: 3.5,\n // DeepSeek: ~3.5 chars/token\n deepseek: 3.5,\n};\n\n/**\n * Cache of computed estimates keyed by a compact HASH of the stringified input \u2014\n * NOT the stringified input itself. The estimator is called per tool_use and per\n * tool_result on every context-window check, and the source strings are full tool\n * payloads (file reads, command output). Keying the Map by those strings meant the\n * cache retained up to 50 000 full payloads \u2014 hundreds of MB \u2014 for a value that is\n * a single number. We now key by `\"<len>:<djb2>\"` (\u224815 chars) and never retain the\n * payload. A hash collision (same length AND djb2) at worst returns a slightly-off\n * heuristic token estimate, which only nudges compaction timing \u2014 never correctness.\n */\nconst ESTIMATE_CACHE = new Map<string, number>();\n/** Insertion-order queue for O(1) LRU eviction: shift from front on overcapacity. */\nconst _estimateCacheOrder: string[] = [];\n\nconst ESTIMATE_CACHE_MAX_SIZE = 50_000;\n\n/** Compact collision-resistant key: length prefix + 32-bit DJB2 of the source. */\nfunction estimateCacheKey(source: string): string {\n let h = 5381;\n for (let i = 0; i < source.length; i++) {\n h = ((h << 5) + h + source.charCodeAt(i)) | 0;\n }\n return `${source.length}:${h >>> 0}`;\n}\n\nfunction getCachedEstimate(source: string, compute: (source: string) => number): number {\n const key = estimateCacheKey(source);\n const existing = ESTIMATE_CACHE.get(key);\n if (existing !== undefined) return existing;\n if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {\n // Evict oldest half \u2014 O(1) per eviction (array shift + Map.delete) instead\n // of O(n) iteration over all 50 000 keys in the Map.\n while (ESTIMATE_CACHE.size > Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) {\n const oldest = _estimateCacheOrder.shift();\n if (oldest !== undefined) ESTIMATE_CACHE.delete(oldest);\n }\n }\n // Compute on the full source (never retained); only the hash key + number stay.\n const estimate = compute(source);\n ESTIMATE_CACHE.set(key, estimate);\n _estimateCacheOrder.push(key);\n return estimate;\n}\n\n/**\n * Estimate tokens for a tool_use block input.\n * Caches the stringified result keyed by the stable string representation\n * to avoid repeated JSON.stringify calls during context window checks.\n */\nexport function estimateToolInputTokens(input: unknown): number {\n if (typeof input === 'string') return RoughTokenEstimate(input);\n if (input === null || typeof input !== 'object') {\n return RoughTokenEstimate(String(input));\n }\n // JSON.stringify is called once to form the cache key; RoughTokenEstimate\n // is deferred only on cache miss (compute callback), not wrapped unnecessarily.\n return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a tool_result content.\n */\nexport function estimateToolResultTokens(content: string | unknown): number {\n if (typeof content === 'string') return RoughTokenEstimate(content);\n return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a text block.\n */\nexport function estimateTextTokens(text: string): number {\n return RoughTokenEstimate(text);\n}\n\n/**\n * Compute and cache the token estimate for a single message. This is the\n * canonical per-message estimator \u2014 called once by ConversationState on\n * append/replace so the O(n\u00B7m) content-block walk happens at mutation time,\n * not on every context-pressure check.\n */\nexport function computeMessageTokens(msg: Message): number {\n if (typeof msg.content === 'string') return estimateTextTokens(msg.content);\n let total = 0;\n for (const b of msg.content) {\n if (b.type === 'text') total += estimateTextTokens(b.text);\n else if (b.type === 'tool_use') total += estimateToolInputTokens(b.input);\n else if (b.type === 'tool_result') total += estimateToolResultTokens(b.content);\n else total += RoughTokenEstimate(JSON.stringify(b));\n }\n return total;\n}\n\n/**\n * Estimate tokens for an array of messages (text + tool I/O), using the shared\n * 3.5 chars/token basis. This is the single canonical message-array estimator \u2014\n * compactors, the context_manager tool, and the `/context` display all route\n * through it so the number a user sees matches the number compaction decides on.\n *\n * When a message carries a pre-computed `_estTokens` field (set by\n * ConversationState on append/replace), it is used directly instead of\n * re-walking the content blocks \u2014 turning the O(n\u00B7m) scan into an O(n)\n * sum for fully-cached arrays.\n */\nexport function estimateMessageTokens(messages: readonly Message[]): number {\n let total = 0;\n for (const m of messages) {\n if (typeof m._estTokens === 'number' && m._estTokens > 0) {\n total += m._estTokens;\n continue;\n }\n total += computeMessageTokens(m);\n }\n return total;\n}\n\n/**\n * Real-usage-anchored input-token count. Given the provider's authoritative\n * prompt-token count from the last response (`anchorTokens`, a REAL number) and\n * the `messages.length` of the request that produced it (`anchorMsgCount`),\n * returns `anchorTokens + estimate(messages appended since)` \u2014 so everything up\n * to the last turn is exact and only the newest, not-yet-sent messages are\n * estimated. This is deliberately NOT calibrated: the base is already real, and\n * on the next response the whole thing re-anchors to the new real count.\n *\n * Returns `null` when there is no usable anchor (no response yet, or the\n * message array shrank below the anchor \u2014 e.g. after compaction \u2014 in which case\n * the caller falls back to a full estimate until the next response re-anchors).\n */\nexport function realAnchoredInputTokens(\n messages: readonly Message[],\n anchorTokens: number | undefined,\n anchorMsgCount: number | undefined,\n): number | null {\n if (typeof anchorTokens !== 'number' || anchorTokens <= 0) return null;\n if (typeof anchorMsgCount !== 'number' || anchorMsgCount < 0) return null;\n if (messages.length < anchorMsgCount) return null;\n const delta = anchorMsgCount === messages.length ? 0 : estimateMessageTokens(messages.slice(anchorMsgCount));\n return anchorTokens + delta;\n}\n\n/**\n * Rough estimate of tokens in a tool definition (name + description + schema).\n * Accounts for the JSON-serialized inputSchema which is sent to the API\n * but NOT included in roughEstimate(content).\n */\nexport function estimateToolDefTokens(tool: {\n name: string;\n description?: string | undefined;\n inputSchema: unknown;\n}): number {\n // Fast path: pre-computed by ToolRegistry at registration time.\n const cached = (tool as { _estDefTokens?: number | undefined })._estDefTokens;\n if (typeof cached === 'number' && cached > 0) return cached;\n\n const compact = compactToolDefinitionForWire(tool);\n return (\n RoughTokenEstimate(tool.name) +\n RoughTokenEstimate(compact.description) +\n RoughTokenEstimate(JSON.stringify(compact.inputSchema))\n );\n}\n\n/**\n * Estimate the total API request token count: system prompt + tool definitions\n * + conversation messages. Use this for context-window bar calculations\n * instead of roughEstimate (which only counts messages).\n *\n * The overhead ratio (overhead / messages) varies by conversation length:\n * - Short conversations (< 10 messages): ~30-50% overhead (large system+tools)\n * - Medium (10-50 messages): ~15-30%\n * - Long (> 50 messages): ~5-15%\n *\n * Returns { messages, systemPrompt, tools, total } for debugging display.\n */\nexport interface RequestTokenBreakdown {\n messages: number;\n systemPrompt: number;\n tools: number;\n total: number;\n}\n\nexport function estimateRequestTokens(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n // Messages: apply the same logic as roughEstimate\n let messagesTokens = 0;\n if (typeof messages === 'string') {\n messagesTokens = RoughTokenEstimate(messages);\n } else if (Array.isArray(messages)) {\n for (const m of messages) {\n if (typeof m === 'object' && m !== null && 'content' in m) {\n // Fast path: pre-computed per-message token estimate (set by\n // ConversationState on append/replace). Skips the O(m) content-block\n // walk entirely for cached messages.\n const cached = (m as { _estTokens?: number | undefined })._estTokens;\n if (typeof cached === 'number' && cached > 0) {\n messagesTokens += cached;\n continue;\n }\n const content = (m as { content: unknown }).content;\n if (typeof content === 'string') {\n messagesTokens += RoughTokenEstimate(content);\n } else if (Array.isArray(content)) {\n for (const b of content) {\n if (typeof b === 'object' && b !== null) {\n if ((b as { type?: string | undefined }).type === 'text') {\n messagesTokens += RoughTokenEstimate((b as { text: string }).text);\n } else {\n messagesTokens += RoughTokenEstimate(JSON.stringify(b));\n }\n }\n }\n }\n }\n }\n }\n\n // System prompt\n let systemTokens = 0;\n if (typeof systemPrompt === 'string') {\n systemTokens = RoughTokenEstimate(systemPrompt);\n } else if (Array.isArray(systemPrompt)) {\n for (const b of systemPrompt) {\n if (\n typeof b === 'object' &&\n b !== null &&\n (b as { type?: string | undefined }).type === 'text'\n ) {\n systemTokens += RoughTokenEstimate((b as { text: string }).text);\n }\n }\n }\n\n // Tool definitions\n let toolsTokens = 0;\n for (const t of tools) {\n toolsTokens += estimateToolDefTokens(t);\n }\n\n const total = messagesTokens + systemTokens + toolsTokens;\n\n // Record the raw estimate for calibration: the next recordActualUsage()\n // call will pair this against the actual API usage so the rolling ratio\n // stays in sync with the real chars/token ratio of the content.\n calState(calibrationKey).prevEst = total;\n\n return {\n messages: messagesTokens,\n systemPrompt: systemTokens,\n tools: toolsTokens,\n total,\n };\n}\n\n/**\n * Record the actual API input token count after a provider call so\n * `estimateRequestTokensCalibrated` can self-correct on subsequent calls.\n *\n * Prefer passing `estimatedInputTokens` explicitly (the calibrated pre-flight\n * estimate from the middleware) \u2014 this avoids race conditions when other code\n * also calls `estimateRequestTokens` between the pre-flight and this call\n * (e.g. audit logging in agent.ts).\n *\n * When `estimatedInputTokens` is omitted, falls back to the keyed bucket's\n * `prevEst` for backward compatibility with callers that don't have the\n * pre-flight value. `calibrationKey` selects the per-(provider,model) bucket\n * (defaults to the shared global bucket).\n */\nexport function recordActualUsage(\n actualInputTokens: number,\n estimatedInputTokens?: number,\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): void {\n if (actualInputTokens <= 0) return;\n const cal = calState(calibrationKey);\n const est = estimatedInputTokens ?? cal.prevEst;\n if (est <= 0) return;\n\n const sampleRatio = actualInputTokens / est;\n if (cal.count === 0) {\n cal.ratio = sampleRatio;\n } else {\n // EWM: new = \u03B1 * sample + (1-\u03B1) * old \u2192 \u03B1=0.3 = fast initial converge\n cal.ratio = CAL_ALPHA * sampleRatio + (1 - CAL_ALPHA) * cal.ratio;\n }\n // Sanity bound: keep the rolling ratio within [0.5, 1.5] so a sequence\n // of bad samples can't blow up the calibration for everyone.\n cal.ratio = Math.min(1.5, Math.max(0.5, cal.ratio));\n cal.count++;\n}\n\n/**\n * Returns the current calibration state for a bucket. Exposed for debugging\n * and tests \u2014 not needed by normal callers.\n */\nexport function getCalibrationState(calibrationKey: string = CALIBRATION_GLOBAL_KEY): {\n ratio: number;\n count: number;\n calibrated: boolean;\n} {\n const cal = calState(calibrationKey);\n return {\n ratio: cal.ratio,\n count: cal.count,\n calibrated: cal.count >= MIN_SAMPLES_FOR_CALIBRATION,\n };\n}\n\n/**\n * Like `estimateRequestTokens` but applies the rolling calibration factor\n * so context pressure readings converge on reality within a few iterations.\n *\n * Before any `recordActualUsage` samples are collected, returns the same\n * result as `estimateRequestTokens` (ratio = 1.0, no distortion).\n * After `MIN_SAMPLES_FOR_CALIBRATION` samples, applies the calibrated\n * multiplier capped to the range [0.5, 1.5] as a sanity bound.\n */\nexport function estimateRequestTokensCalibrated(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n const result = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);\n const cal = calState(calibrationKey);\n\n if (cal.count >= MIN_SAMPLES_FOR_CALIBRATION) {\n const safeRatio = Math.min(1.5, Math.max(0.5, cal.ratio));\n return {\n messages: Math.round(result.messages * safeRatio),\n systemPrompt: Math.round(result.systemPrompt * safeRatio),\n tools: Math.round(result.tools * safeRatio),\n total: Math.round(result.total * safeRatio),\n };\n }\n\n // No calibration samples yet \u2014 fall back to model-family ratio if available,\n // otherwise use the uncalibrated estimate (ratio = 1.0).\n const fallbackRatio = getModelFamilyRatio(calibrationKey);\n if (fallbackRatio !== null) {\n return {\n messages: Math.round(result.messages * fallbackRatio),\n systemPrompt: Math.round(result.systemPrompt * fallbackRatio),\n tools: Math.round(result.tools * fallbackRatio),\n total: Math.round(result.total * fallbackRatio),\n };\n }\n\n return result;\n}\n\n/** Per-block sample cap for the density scan \u2014 bounds work on giant blocks. */\nconst DENSITY_SAMPLE_PER_BLOCK = 4_096;\n/** Hard cap on total sampled chars so the density scan stays cheap. */\nconst DENSITY_SAMPLE_TOTAL_CAP = 2_000_000;\n\n/**\n * Estimate a **token-density multiplier** for content that the flat 3.5\n * chars/token basis under-counts. The basis is tuned for ASCII English\n * (~4 chars/token); CJK, and other high-codepoint scripts tokenize at ~1.5-2\n * chars/token, so a message that is mostly CJK carries up to ~2.3\u00D7 the tokens\n * the flat basis predicts. Long unbroken ASCII runs (base64, minified blobs)\n * pack slightly denser too. This scans a bounded sample and returns a\n * multiplier in [1, 2.5] \u2014 always \u2265 1, so it can only push the estimate UP,\n * never down. Used only by the send-time overflow guard, never for display.\n */\nfunction textDensityMultiplier(messages: readonly Message[]): number {\n let sampled = 0;\n let nonAscii = 0;\n let maxRun = 0;\n const consider = (s: string): void => {\n const n = Math.min(s.length, DENSITY_SAMPLE_PER_BLOCK);\n let run = 0;\n for (let i = 0; i < n; i++) {\n const c = s.charCodeAt(i);\n if (c > 127) nonAscii++;\n if (c === 32 || c === 9 || c === 10 || c === 13) {\n if (run > maxRun) maxRun = run;\n run = 0;\n } else {\n run++;\n }\n }\n if (run > maxRun) maxRun = run;\n sampled += n;\n };\n\n for (const m of messages) {\n if (typeof m.content === 'string') {\n consider(m.content);\n } else if (Array.isArray(m.content)) {\n for (const b of m.content) {\n if (b.type === 'text') consider(b.text);\n else if (b.type === 'tool_result' && typeof b.content === 'string') consider(b.content);\n else if (b.type === 'thinking') consider(b.thinking);\n }\n }\n if (sampled >= DENSITY_SAMPLE_TOTAL_CAP) break;\n }\n\n if (sampled === 0) return 1;\n const nonAsciiRatio = nonAscii / sampled;\n // 3.5 chars/token at 0% non-ASCII \u2192 1.5 at 100% (heavy CJK).\n let charsPerToken = 3.5 - 2.0 * nonAsciiRatio;\n // A very long unbroken ASCII run (base64/minified) packs a little denser.\n if (maxRun > 2_000 && nonAsciiRatio < 0.1) charsPerToken = Math.min(charsPerToken, 3.0);\n const multiplier = 3.5 / Math.max(1.4, charsPerToken);\n return Math.min(2.5, Math.max(1, multiplier));\n}\n\n/**\n * Never-undercount upper bound for the request token total, for the **send\n * guard** only. Takes the flat estimate and scales it up by the greater of the\n * content-density multiplier and the calibration ceiling, so the guarded value\n * satisfies `real \u2264 upperBound`. The context bar and `/context` keep using the\n * calibrated estimate \u2014 this deliberately over-counts, which is only ever safe\n * for the \"must this be trimmed before sending?\" decision.\n */\nexport function estimateRequestTokensUpperBound(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n const base = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);\n const density = Array.isArray(messages)\n ? textDensityMultiplier(messages as readonly Message[])\n : 1;\n const cal = calState(calibrationKey);\n const calCeiling =\n cal.count >= MIN_SAMPLES_FOR_CALIBRATION ? Math.min(1.5, Math.max(1, cal.ratio)) : 1;\n const mult = Math.max(density, calCeiling);\n if (mult <= 1) return base;\n return {\n messages: Math.ceil(base.messages * mult),\n systemPrompt: Math.ceil(base.systemPrompt * mult),\n tools: Math.ceil(base.tools * mult),\n total: Math.ceil(base.total * mult),\n };\n}\n\n/** Look up the fallback chars/token ratio for a calibration key (e.g. \"provider/model\"). */\nfunction getModelFamilyRatio(calibrationKey: string): number | null {\n const lower = calibrationKey.toLowerCase();\n for (const [family, ratio] of Object.entries(MODEL_FAMILY_RATIO)) {\n if (lower.includes(family)) return ratio / 3.5; // MODEL_FAMILY_RATIO is chars/token, we need multiplier\n }\n return null;\n}\n\n/**\n * Resets calibration state. Primarily for tests that run in the same\n * process and need a clean slate between suites. With no argument it clears\n * every bucket (including the global one); pass a key to reset just that bucket.\n */\nexport function resetCalibration(calibrationKey?: string): void {\n if (calibrationKey === undefined) {\n _cals.clear();\n return;\n }\n _cals.delete(calibrationKey);\n}\n", "/** A provider-qualified or provider-relative model reference. */\nexport interface ModelRef {\n provider?: string | undefined;\n model: string;\n}\n\n/** Parse `model`, `provider/model`, or `provider model`. */\nexport function parseModelRef(ref: string): ModelRef {\n const trimmed = ref.trim();\n const slash = trimmed.indexOf('/');\n if (slash !== -1) {\n return {\n provider: trimmed.slice(0, slash) || undefined,\n model: trimmed.slice(slash + 1).trim(),\n };\n }\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n return { provider: parts[0], model: parts.slice(1).join(' ') };\n }\n return { model: trimmed };\n}\n\nexport function formatModelRef(ref: ModelRef, defaultProvider?: string | undefined): string {\n const provider = ref.provider ?? defaultProvider;\n return provider ? `${provider}/${ref.model}` : ref.model;\n}\n\nexport function normalizeModelRef(ref: string, defaultProvider?: string | undefined): string {\n return formatModelRef(parseModelRef(ref), defaultProvider);\n}\n", "export interface ModelBlackoutRule {\n id: string;\n enabled?: boolean | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n /** JavaScript weekday numbers: Sunday=0 \u2026 Saturday=6. Empty means every day. */\n days?: number[] | undefined;\n /** Inclusive local start, HH:mm. */\n start: string;\n /** Exclusive local end, HH:mm. Equal to start means all day. */\n end: string;\n /** IANA timezone. Defaults to the host timezone. */\n timezone?: string | undefined;\n label?: string | undefined;\n /** `blackout`: deny inside. `allow_only`: deny outside all matching allow windows. */\n mode?: 'blackout' | 'allow_only' | undefined;\n}\n\nexport interface ModelCalendarDecision {\n allowed: boolean;\n rule?: ModelBlackoutRule | undefined;\n}\n\nexport function logicalCalendarTarget(\n providerId: string,\n model: string,\n): {\n providerId: string;\n model: string;\n} {\n if (providerId !== 'omniroute') return { providerId, model };\n const slash = model.indexOf('/');\n return slash > 0 && slash < model.length - 1\n ? { providerId: model.slice(0, slash), model: model.slice(slash + 1) }\n : { providerId, model };\n}\n\nconst WEEKDAYS: Record<string, number> = {\n Sun: 0,\n Mon: 1,\n Tue: 2,\n Wed: 3,\n Thu: 4,\n Fri: 5,\n Sat: 6,\n};\n\nfunction minuteOfDay(value: string): number | undefined {\n const match = /^(\\d{2}):(\\d{2})$/.exec(value);\n if (!match) return undefined;\n const hour = Number(match[1]);\n const minute = Number(match[2]);\n if (hour > 23 || minute > 59) return undefined;\n return hour * 60 + minute;\n}\n\nfunction clockAt(date: Date, timezone?: string): { day: number; minute: number } | undefined {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: timezone,\n weekday: 'short',\n hour: '2-digit',\n minute: '2-digit',\n hourCycle: 'h23',\n }).formatToParts(date);\n const weekday = parts.find((part) => part.type === 'weekday')?.value;\n const hour = Number(parts.find((part) => part.type === 'hour')?.value);\n const minute = Number(parts.find((part) => part.type === 'minute')?.value);\n if (!weekday || WEEKDAYS[weekday] === undefined || !Number.isFinite(hour + minute))\n return undefined;\n return { day: WEEKDAYS[weekday], minute: hour * 60 + minute };\n } catch {\n return undefined;\n }\n}\n\nfunction targetMatches(rule: ModelBlackoutRule, providerId: string, model: string): boolean {\n if (rule.provider && rule.provider !== providerId) return false;\n if (rule.model && rule.model !== model) return false;\n return Boolean(rule.provider || rule.model);\n}\n\nfunction timeMatches(rule: ModelBlackoutRule, day: number, minute: number): boolean {\n const start = minuteOfDay(rule.start);\n const end = minuteOfDay(rule.end);\n if (start === undefined || end === undefined) return false;\n const days = rule.days?.length ? new Set(rule.days) : undefined;\n if (start === end) return !days || days.has(day);\n if (start < end) return (!days || days.has(day)) && minute >= start && minute < end;\n // Overnight: Monday 22:00\u201307:00 includes early Tuesday morning.\n if (minute >= start) return !days || days.has(day);\n const previousDay = (day + 6) % 7;\n return minute < end && (!days || days.has(previousDay));\n}\n\nexport function evaluateModelCalendar(\n rules: readonly ModelBlackoutRule[] | undefined,\n providerId: string,\n model: string,\n at = new Date(),\n): ModelCalendarDecision {\n ({ providerId, model } = logicalCalendarTarget(providerId, model));\n const allowRules: ModelBlackoutRule[] = [];\n let allowMatched = false;\n for (const rule of rules ?? []) {\n if (rule.enabled === false || !targetMatches(rule, providerId, model)) continue;\n const clock = clockAt(at, rule.timezone);\n if (!clock || minuteOfDay(rule.start) === undefined || minuteOfDay(rule.end) === undefined)\n continue;\n if (rule.mode === 'allow_only') {\n allowRules.push(rule);\n if (timeMatches(rule, clock.day, clock.minute)) allowMatched = true;\n } else if (timeMatches(rule, clock.day, clock.minute)) {\n return { allowed: false, rule };\n }\n }\n if (allowRules.length > 0 && !allowMatched) return { allowed: false, rule: allowRules[0] };\n return { allowed: true };\n}\n", "/**\n * FallbackProfileManager \u2014 centralized, decoupled fallback profile resolution.\n *\n * Every consumer (fallback-model, council orchestrator, one-shot LLM, plugins)\n * resolves its fallback chain through this single manager instead of parsing\n * config.fallbackProfiles independently. This guarantees consistent resolution,\n * provider-health filtering, and a single reload point on config changes.\n *\n * Design:\n * - Stable service identity: `reload()` atomically replaces the manager's\n * immutable config/profile snapshot so injected consumers stay live.\n * - Immutable outputs: every resolved chain is frozen.\n * - Provider-aware: each profile entry is checked against live provider config\n * (has API key?) before inclusion.\n * - Zero coupling: consumers only see `readonly FallbackChainEntry[]` \u2014\n * no awareness of profile names, config shape, or provider internals.\n */\n\nimport type { ProviderModelStatusTracker } from '../coordination/provider-status-tracker.js';\nimport type { Config, ProviderConfig } from '../types/config.js';\nimport { parseModelRef } from './model-ref.js';\nimport { evaluateModelCalendar } from './model-availability-calendar.js';\n\n// \u2500\u2500 Public types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** One resolved entry in a fallback chain. */\nexport interface FallbackChainEntry {\n /** Resolved provider id. */\n readonly providerId: string;\n /** Resolved model id. */\n readonly model: string;\n /** Whether this entry uses a different provider than the primary. */\n readonly providerSwitched: boolean;\n}\n\n/** Immutable fallback chain returned by the manager. */\nexport type FallbackChain = readonly FallbackChainEntry[];\n\n/**\n * Configuration-level provider health used while resolving fallback chains.\n *\n * This deliberately answers whether the runtime has enough configuration to\n * construct the provider; it does not perform a network probe. Keyless\n * self-hosted endpoints are usable when they declare a `baseUrl`.\n */\nexport interface ProviderHealth {\n readonly providerId: string;\n readonly hasKey: boolean;\n readonly hasEndpoint: boolean;\n readonly hasModels: boolean;\n readonly usable: boolean;\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction hasText(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction providerHasKey(entry: ProviderConfig | undefined): boolean {\n if (!entry) return false;\n if (hasText(entry.apiKey)) return true;\n if (Array.isArray(entry.apiKeys) && entry.apiKeys.some((k) => hasText(k?.apiKey))) return true;\n if (Array.isArray(entry.envVars) && entry.envVars.some((v) => hasText(process.env[v])))\n return true;\n return false;\n}\n\nfunction visibleProviderModels(\n config: Config,\n providerId: string,\n providerModels: string[],\n): string[] {\n const entry = config.providers?.[providerId];\n return entry?.models !== undefined ? [...entry.models] : providerModels;\n}\n\nfunction buildProfiles(config: Config): ReadonlyMap<string, readonly string[]> {\n const entries = new Map<string, readonly string[]>();\n for (const [name, chain] of Object.entries(config.fallbackProfiles ?? {})) {\n if (Array.isArray(chain) && chain.length > 0) {\n entries.set(name, Object.freeze([...chain]));\n }\n }\n return entries;\n}\n\n// \u2500\u2500 Manager \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class FallbackProfileManager {\n /** Immutable snapshot of config.fallbackProfiles for the active config. */\n private profiles: ReadonlyMap<string, readonly string[]>;\n /** Active frozen config snapshot for provider lookups. */\n private config: Config;\n /** Optional shared runtime status tracker. */\n private statusTracker: ProviderModelStatusTracker | undefined;\n\n constructor(config: Config, opts?: { statusTracker?: ProviderModelStatusTracker | undefined }) {\n this.config = config;\n this.profiles = buildProfiles(config);\n this.statusTracker = opts?.statusTracker;\n }\n\n /**\n * Bind (or replace) the shared runtime status tracker.\n * Called by the boot path after the tracker is created.\n */\n setStatusTracker(tracker: ProviderModelStatusTracker | undefined): void {\n this.statusTracker = tracker;\n }\n\n // \u2500\u2500 Profile existence \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n hasProfile(name: string): boolean {\n return this.profiles.has(name);\n }\n\n listProfiles(): readonly string[] {\n return Object.freeze([...this.profiles.keys()]);\n }\n\n // \u2500\u2500 Resolution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve a named fallback profile to a validated, provider-filtered chain.\n *\n * Returns an empty chain when:\n * - The profile doesn't exist.\n * - Every entry's provider is missing, has no key, or has no matching model.\n *\n * @param name - Profile name from config.fallbackProfiles.\n * @param defaultProvider - Used when an entry has no explicit provider.\n * @param exclude - Optional { providerId, model } to skip (avoid self-fallback).\n */\n resolve(\n name: string,\n opts: {\n defaultProvider?: string | undefined;\n exclude?: { providerId: string; model: string } | undefined;\n } = {},\n ): FallbackChain {\n const defaultProvider = opts.defaultProvider ?? this.config.provider;\n const chain = this.profiles.get(name);\n if (!chain) return FREEZER_EMPTY;\n\n const excludeKey = opts.exclude\n ? `${opts.exclude.providerId}/${opts.exclude.model}`\n : undefined;\n\n const resolved: FallbackChainEntry[] = [];\n const seen = new Set<string>();\n\n for (const ref of chain) {\n const parsed = parseModelRef(ref);\n if (!parsed.model) continue;\n\n const providerId = parsed.provider ?? defaultProvider;\n const key = `${providerId}/${parsed.model}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n // Skip self-reference\n if (excludeKey && key === excludeKey) continue;\n\n const health = this.checkProvider(providerId);\n if (!health.usable) continue;\n\n // Skip entries that are blocked by the runtime status tracker\n if (this.statusTracker && !this.statusTracker.isAvailable(providerId, parsed.model)) continue;\n if (\n !evaluateModelCalendar(this.config.modelAvailabilitySchedule, providerId, parsed.model)\n .allowed\n )\n continue;\n\n // Skip entries whose provider has no matching model in its allow-list\n // (provider may restrict which models are available).\n const allowedModels = this.config.providers?.[providerId]?.models;\n if (allowedModels && !allowedModels.includes(parsed.model)) continue;\n\n resolved.push({\n providerId,\n model: parsed.model,\n providerSwitched: providerId !== (opts.exclude?.providerId ?? this.config.provider),\n });\n }\n\n return Object.freeze(resolved);\n }\n\n /**\n * Resolve the effective fallback chain for a session: explicit fallbackModels\n * first, then named profile, then smart default (unless disabled).\n *\n * Mirrors the previous `effectiveFallbackChain()` logic but centralized.\n */\n resolveEffective(\n opts: {\n fallbackModels?: readonly string[] | undefined;\n fallbackProfile?: string | undefined;\n fallbackAuto?: boolean | undefined;\n exclude?: { providerId: string; model: string } | undefined;\n } = {},\n ): FallbackChain {\n // 1. Explicit fallbackModels (already resolved refs)\n // Only return if non-empty; empty chain falls through to next source.\n if (opts.fallbackModels && opts.fallbackModels.length > 0) {\n const resolved = this.resolveRefs(opts.fallbackModels, opts.exclude);\n if (resolved.length > 0) return resolved;\n }\n\n // 2. Named profile \u2014 only return if non-empty\n if (opts.fallbackProfile) {\n const resolved = this.resolve(opts.fallbackProfile, { exclude: opts.exclude });\n if (resolved.length > 0) return resolved;\n }\n\n // 3. Smart default\n if (opts.fallbackAuto !== false) {\n return this.smartDefault(opts.exclude);\n }\n\n return FREEZER_EMPTY;\n }\n\n // \u2500\u2500 Provider availability (read-only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n checkProvider(providerId: string): ProviderHealth {\n const entry = this.config.providers?.[providerId];\n const isPrimary = providerId === this.config.provider;\n const hasKey = providerHasKey(entry) || (isPrimary && hasText(this.config.apiKey));\n const hasEndpoint = hasText(entry?.baseUrl) || (isPrimary && hasText(this.config.baseUrl));\n const hasModels =\n (Array.isArray(entry?.models) && entry.models.length > 0) ||\n (isPrimary && hasText(this.config.model));\n return Object.freeze({\n providerId,\n hasKey,\n hasEndpoint,\n hasModels,\n usable: hasKey || hasEndpoint,\n });\n }\n\n // \u2500\u2500 Rebuild on config change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Atomically replace the active immutable snapshot while preserving this\n * service identity for every injected consumer.\n */\n reload(newConfig: Config): void {\n this.config = newConfig;\n this.profiles = buildProfiles(newConfig);\n }\n\n // \u2500\u2500 Internal helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve an array of model ref strings (from explicit fallbackModels config).\n * Public so consumers like one-shot-llm can use it directly.\n */\n resolveRefs(\n refs: readonly string[],\n exclude?: { providerId: string; model: string },\n ): FallbackChain {\n const excludeKey = exclude ? `${exclude.providerId}/${exclude.model}` : undefined;\n const resolved: FallbackChainEntry[] = [];\n const seen = new Set<string>();\n\n for (const ref of refs) {\n const parsed = parseModelRef(ref);\n if (!parsed.model) continue;\n\n const providerId = parsed.provider ?? this.config.provider;\n const key = `${providerId}/${parsed.model}`;\n if (seen.has(key)) continue;\n seen.add(key);\n if (excludeKey && key === excludeKey) continue;\n\n // Skip entries blocked by the runtime status tracker\n if (this.statusTracker && !this.statusTracker.isAvailable(providerId, parsed.model)) continue;\n if (\n !evaluateModelCalendar(this.config.modelAvailabilitySchedule, providerId, parsed.model)\n .allowed\n )\n continue;\n\n resolved.push({\n providerId,\n model: parsed.model,\n providerSwitched: providerId !== (exclude?.providerId ?? this.config.provider),\n });\n }\n\n return Object.freeze(resolved);\n }\n\n /**\n * Derive a smart default chain from configured providers when nothing\n * explicit is set. Same-provider alternatives first, then cross-provider.\n * Limited to 4 entries to avoid burning through models on a transient blip.\n */\n private smartDefault(exclude?: { providerId: string; model: string }): FallbackChain {\n const leaderProvider = this.config.provider;\n const leaderModel = this.config.model;\n const providers = this.config.providers ?? {};\n const favoriteSet = new Set(\n (this.config.favoriteModels ?? []).map((ref) => {\n const p = parseModelRef(ref);\n return `${p.provider ?? leaderProvider}/${p.model}`;\n }),\n );\n const hasFavorites = favoriteSet.size > 0;\n const favoritesOnly = this.config.favoriteModelsOnly === true;\n const seen = new Set<string>();\n const favorites: string[] = [];\n const sameProvider: string[] = [];\n const crossProvider: string[] = [];\n\n const excludeKey = exclude ? `${exclude.providerId}/${exclude.model}` : undefined;\n\n const ids = Object.keys(providers).sort((a, b) =>\n a === leaderProvider ? -1 : b === leaderProvider ? 1 : a.localeCompare(b),\n );\n\n for (const id of ids) {\n const entry = providers[id];\n if (!this.checkProvider(id).usable) continue;\n // Skip the entire provider if it's blocked at the provider level\n // (all its models would be blocked too, but we check per-model below)\n const models = visibleProviderModels(this.config, id, entry?.models ?? []);\n for (const model of models) {\n if (id === leaderProvider && model === leaderModel) continue;\n const ref = `${id}/${model}`;\n if (seen.has(ref)) continue;\n seen.add(ref);\n if (excludeKey && ref === excludeKey) continue;\n // Skip models blocked by the runtime status tracker\n if (this.statusTracker && !this.statusTracker.isAvailable(id, model)) continue;\n if (!evaluateModelCalendar(this.config.modelAvailabilitySchedule, id, model).allowed)\n continue;\n if (favoriteSet.has(ref)) {\n favorites.push(ref);\n continue;\n }\n if (favoritesOnly && hasFavorites) continue;\n (id === leaderProvider ? sameProvider : crossProvider).push(ref);\n }\n }\n\n const MAX = 4;\n const all = [...favorites, ...sameProvider, ...crossProvider].slice(0, MAX);\n return Object.freeze(\n all.map((ref) => {\n const p = parseModelRef(ref);\n return {\n providerId: p.provider ?? leaderProvider,\n model: p.model,\n providerSwitched:\n (p.provider ?? leaderProvider) !== (exclude?.providerId ?? leaderProvider),\n } satisfies FallbackChainEntry;\n }),\n );\n }\n}\n\nconst FREEZER_EMPTY: FallbackChain = Object.freeze([]);\n", "/**\n * Cross-provider fallback model extension.\n *\n * Lives in core so EVERY agent surface can reuse it: the CLI leader, the CLI\n * director/host subagent factory, and the runtime light subagent factory (used\n * by standalone SDD runs). It wraps the provider runner and, when the active\n * model 429s / overloads / stream-hangs, rotates through a fallback chain. The\n * chain is recomputed from live config every turn, so changes take effect\n * without a restart; an empty chain makes the wrapper a no-op.\n *\n * Moved here from `@wrongstack/cli` (it only ever depended on core types) so the\n * runtime light factory can wire fallbacks for SDD worker subagents.\n */\n\nimport type { ProviderModelStatusTracker } from '../coordination/provider-status-tracker.js';\nimport type { AgentExtension } from '../extension/extension-points.js';\nimport type { EventBus } from '../kernel/events.js';\nimport { isTextBlock, isToolUseBlock } from '../types/blocks.js';\nimport type { Config } from '../types/config.js';\nimport type { Logger } from '../types/logger.js';\nimport {\n isFallbackWorthy,\n type Provider,\n ProviderError,\n type Response,\n} from '../types/provider.js';\nimport { resolveEventSessionId } from './context.js';\nimport type { FallbackChain, FallbackChainEntry } from './fallback-profile-manager.js';\nimport { FallbackProfileManager } from './fallback-profile-manager.js';\nimport { evaluateModelCalendar, logicalCalendarTarget } from './model-availability-calendar.js';\nimport { bindRequestProvider } from './request-provider-binding.js';\n\nexport type { ModelRef } from './model-ref.js';\n// Compatibility: the canonical leaf implementation lives in model-ref.ts.\nexport { formatModelRef, normalizeModelRef, parseModelRef } from './model-ref.js';\n\nexport interface FallbackModelDeps {\n /** Returns the live config (re-read each turn so `/model` switches are honored). */\n getConfig: () => Config;\n /** Shared live manager from the runtime container. */\n fallbackProfileManager?: FallbackProfileManager | undefined;\n /** Live named profile selected for this worker (for example by `/setmodel`). */\n getFallbackProfile?: (() => string | undefined) | undefined;\n /** Live task/role-specific chain. Explicit task fallbacks may return a stable list. */\n getFallbackModels?: (() => readonly string[] | undefined) | undefined;\n /** Worker-local primary; prevents a subagent fallback from restoring the leader model. */\n getPrimaryTarget?: (() => { providerId: string; model: string } | undefined) | undefined;\n /** When true, only the explicitly supplied fallback chain may be attempted. */\n isClosedWorld?: (() => boolean) | undefined;\n /**\n * Builds a credential-resolved Provider for a provider id (alias-resolved),\n * WITHOUT persisting anything to config/configStore. Supplied by the boot\n * path, which shares this with the `/model` switch logic. May be async \u2014 the\n * subagent host resolves a provider's real context window asynchronously.\n */\n buildProvider: (providerId: string, modelId?: string | undefined) => Provider | Promise<Provider>;\n /**\n * Called after the active model changes (a fallback hop or the primary\n * restore) so the host can refresh the auto-compaction / context-window\n * denominator \u2014 important when a fallback crosses to a smaller-window model.\n */\n onModelSwitch?: (providerId: string, modelId: string) => void | Promise<void>;\n events: EventBus;\n /** Optional \u2014 warnings about un-buildable fallback providers. */\n logger?: Logger | undefined;\n /**\n * Base cooldown after the configured primary fails with a fallback-worthy\n * error. While active, `beforeRun` leaves the context on the working fallback\n * instead of retrying the primary at the start of every turn. Default: 60s.\n * Set 0 to preserve the legacy \"probe primary every turn\" behavior.\n */\n primaryCooldownMs?: number | undefined;\n /**\n * Maximum exponential cooldown for repeated failed primary probes. Default:\n * 10 minutes. Ignored when `primaryCooldownMs` is 0.\n */\n primaryCooldownMaxMs?: number | undefined;\n /**\n * Number of consecutive primary successes required to fully reset the\n * failure ladder after a cooldown expiry. Set 1 for the legacy \"one\n * success fully resets\" behavior; higher values prevent an\n * intermittently-available primary from causing model bouncing \u2014 the\n * streak is retained across a single success so the next failure\n * continues the exponential backoff instead of restarting at 1.\n * Default: 2.\n */\n primaryRecoverySuccesses?: number | undefined;\n /**\n * Minimum number of turns to dwell on a working fallback before the\n * primary becomes eligible for a half-open probe \u2014 even if the cooldown\n * timer has already expired. Default: 0 (timer alone governs).\n * Set to e.g. 3 to require three full turns on the fallback before the\n * system risks switching back to the primary.\n */\n stickyFallbackTurns?: number | undefined;\n /** Test hook for deterministic cooldown assertions. */\n now?: (() => number) | undefined;\n /**\n * Shared provider/model status tracker. When set, the extension records\n * failures and successes in the tracker, and skips blocked entries in\n * the fallback chain.\n */\n statusTracker?: ProviderModelStatusTracker | undefined;\n}\n\nexport function fallbackProfileChain(config: Config, profileName: string | undefined): string[] {\n if (!profileName) return [];\n const mgr = new FallbackProfileManager(config);\n return mgr.resolve(profileName).map((e) => `${e.providerId}/${e.model}`);\n}\n\n/**\n * Check if an error should trigger a fallback. Returns the status for\n * logging, or null if the error doesn't warrant a fallback attempt.\n *\n * Branches on the canonical `ProviderError.kind`: capacity/availability\n * failures (rate limit, overload, server error, stream hang, timeout,\n * network) are worth trying on another provider; request-shaped failures\n * (auth, invalid request, context overflow, content filter) would fail\n * identically anywhere \u2014 or need a different remedy (compaction, key fix) \u2014\n * so they surface instead.\n */\nfunction shouldFallback(err: unknown): number | null {\n if (!(err instanceof ProviderError) && !ProviderError.isProviderError(err)) return null;\n const kind = (err as ProviderError).kind;\n return isFallbackWorthy(kind) ? (err as ProviderError).status : null;\n}\n\nfunction isUsableModelResponse(response: Response): boolean | undefined {\n if (!response?.content) return undefined;\n return response.content.some(\n (block) => isToolUseBlock(block) || (isTextBlock(block) && block.text.trim().length > 0),\n );\n}\n\nfunction ensureUsableModelResponse(\n response: Response,\n providerId: string,\n model: string,\n): Response {\n const usable = isUsableModelResponse(response);\n // undefined content means the caller didn't provide a content field (e.g. test mocks) \u2014 let it through\n if (usable !== false) return response;\n throw new ProviderError(\n `Empty response from ${providerId}/${model}; trying the next configured model`,\n 503,\n true,\n providerId,\n { kind: 'overloaded' },\n );\n}\n\nexport function smartDefaultFallbackChain(config: Config): string[] {\n const mgr = new FallbackProfileManager(config);\n return mgr.resolveEffective({ fallbackAuto: true }).map((e) => `${e.providerId}/${e.model}`);\n}\n\n/**\n * The effective fallback chain for a turn: the explicit `fallbackModels` list\n * when non-empty, otherwise the smart default (unless `fallbackAuto` is off).\n */\nexport function effectiveFallbackChain(config: Config): string[] {\n const mgr = new FallbackProfileManager(config);\n return mgr\n .resolveEffective({\n fallbackModels: config.fallbackModels,\n fallbackAuto: config.fallbackAuto,\n })\n .map((e) => `${e.providerId}/${e.model}`);\n}\n\nconst DEFAULT_PRIMARY_COOLDOWN_MS = 60_000;\nconst DEFAULT_PRIMARY_COOLDOWN_MAX_MS = 10 * 60_000;\nconst DEFAULT_PRIMARY_RECOVERY_SUCCESSES = 2;\n\nfunction sameTarget(\n a: { providerId: string; model: string } | undefined,\n b: { providerId: string; model: string },\n): boolean {\n return !!a && a.providerId === b.providerId && a.model === b.model;\n}\n\nfunction fallbackCandidates(\n config: Config,\n current: { providerId: string; model: string },\n opts: {\n fallbackModels?: readonly string[] | undefined;\n fallbackProfile?: string | undefined;\n sharedManager?: FallbackProfileManager | undefined;\n primary?: { providerId: string; model: string } | undefined;\n closedWorld?: boolean | undefined;\n } = {},\n): FallbackChain {\n const mgr = opts.sharedManager ?? new FallbackProfileManager(config);\n const configuredPrimary = opts.primary ?? primaryTarget(config);\n // The effective fallbackAuto: honour the config explicitly, fall back to\n // !closedWorld only when config.fallbackAuto is undefined/null.\n const configFallbackAuto = config.fallbackAuto;\n const effectiveFallbackAuto =\n configFallbackAuto !== undefined && configFallbackAuto !== null\n ? configFallbackAuto\n : !opts.closedWorld;\n const selectedChain = mgr.resolveEffective({\n fallbackModels: opts.fallbackModels ?? config.fallbackModels,\n fallbackProfile: opts.fallbackProfile,\n fallbackAuto: effectiveFallbackAuto,\n exclude: current,\n });\n const candidates: FallbackChainEntry[] = [];\n\n // A model allowlist is a permission boundary. Never append the session\n // model, default profile, or auto-discovered providers outside that boundary.\n if (opts.closedWorld) {\n candidates.push(...selectedChain);\n const seen = new Set<string>();\n return Object.freeze(\n candidates.filter((entry) => {\n const key = `${entry.providerId}/${entry.model}`;\n if (key === `${current.providerId}/${current.model}` || seen.has(key)) return false;\n seen.add(key);\n return true;\n }),\n );\n }\n\n // 1. A live config or role-selected primary is the user's current model\n // choice, so try it before any fallback entries when the active context\n // is still on an older model.\n if (!sameTarget(configuredPrimary, current)) {\n candidates.push({\n providerId: configuredPrimary.providerId,\n model: configuredPrimary.model,\n providerSwitched: configuredPrimary.providerId !== current.providerId,\n });\n }\n\n // 2. Preserve the exact order of the user's explicit / role-selected chain.\n candidates.push(...selectedChain);\n\n // 3. The default profile is additional fallback depth (unless we already\n // resolved it as the selected chain above).\n if (opts.fallbackProfile !== 'default') {\n candidates.push(...mgr.resolve('default', { exclude: current }));\n }\n\n // 4. Every other configured provider as a last resort \u2014 but only\n // when fallbackAuto is actually enabled.\n if (effectiveFallbackAuto) {\n const smartDefaults = mgr.resolveEffective({ fallbackAuto: true, exclude: current });\n candidates.push(...smartDefaults);\n }\n\n const seen = new Set<string>();\n return Object.freeze(\n candidates.filter((entry) => {\n const key = `${entry.providerId}/${entry.model}`;\n if (key === `${current.providerId}/${current.model}` || seen.has(key)) return false;\n seen.add(key);\n return true;\n }),\n );\n}\n\nconst primaryTarget = (cfg: Config) => ({ providerId: cfg.provider, model: cfg.model });\n\nfunction maxContextOf(provider: Provider): number {\n const max = provider.capabilities.maxContext;\n return typeof max === 'number' && Number.isFinite(max) ? max : 0;\n}\n\nfunction contextWindowWarning(\n currentProvider: Provider,\n nextProvider: Provider,\n currentTokens: unknown,\n):\n | { fromMaxContext: number; toMaxContext: number; currentTokens?: number | undefined }\n | undefined {\n const fromMaxContext = maxContextOf(currentProvider);\n const toMaxContext = maxContextOf(nextProvider);\n if (fromMaxContext <= 0 || toMaxContext <= 0 || toMaxContext >= fromMaxContext) return undefined;\n return {\n fromMaxContext,\n toMaxContext,\n ...(typeof currentTokens === 'number' && currentTokens > 0 ? { currentTokens } : {}),\n };\n}\n\n/**\n * Build the cross-provider fallback extension. Always returns an extension \u2014\n * the effective chain (`effectiveFallbackChain`) is recomputed every turn from\n * the live config, so a chain that is empty at boot but populated later (via\n * `/fallback add` or the smart default kicking in once a key is added) takes\n * effect WITHOUT a restart. An empty chain makes the wrapper a no-op (it just\n * rethrows the original error).\n *\n * Mechanism (see plan): wraps the provider runner. The inner runner already\n * applies the per-model retry policy (backoff, up to 5 tries for 429), so the\n * fallback only engages AFTER the active model's own retries are exhausted.\n * Because the wrapper resolves within a single provider call, it does not\n * consume the agent loop's `recoveryRetries` budget \u2014 chains longer than two\n * entries work. `beforeRun` keeps the last working fallback while the primary\n * is cooling down, then restores the configured primary for a half-open probe.\n */\nexport function createFallbackModelExtension(deps: FallbackModelDeps): AgentExtension {\n // True when a prior turn left the live context on a fallback model.\n let dirty = false;\n let primaryFailureStreak = 0;\n let primaryRecoveryHits = 0;\n let stickyTurnsElapsed = 0;\n // Remembers the last fallback model that succeeded so the chain can\n // front-load it on subsequent primary failures \u2014 avoiding a full\n // re-traversal through flaky entries that were already tried.\n let lastWorkingFallback: { providerId: string; model: string } | undefined;\n let blockedPrimary: { providerId: string; model: string } | undefined;\n let primaryBlockedUntil = 0;\n\n const now = () => deps.now?.() ?? Date.now();\n const cooldownBase = () => Math.max(0, deps.primaryCooldownMs ?? DEFAULT_PRIMARY_COOLDOWN_MS);\n const cooldownMax = () =>\n Math.max(cooldownBase(), deps.primaryCooldownMaxMs ?? DEFAULT_PRIMARY_COOLDOWN_MAX_MS);\n const selectedPrimary = (cfg: Config) => deps.getPrimaryTarget?.() ?? primaryTarget(cfg);\n const primaryInCooldown = (cfg: Config) =>\n sameTarget(blockedPrimary, selectedPrimary(cfg)) && now() < primaryBlockedUntil;\n\n const markPrimaryFailure = (cfg: Config) => {\n const primary = selectedPrimary(cfg);\n primaryFailureStreak = sameTarget(blockedPrimary, primary) ? primaryFailureStreak + 1 : 1;\n // A failure breaks any in-progress recovery chain.\n primaryRecoveryHits = 0;\n // A new fallback hop starts the sticky-dwell window from zero.\n stickyTurnsElapsed = 0;\n blockedPrimary = primary;\n const base = cooldownBase();\n if (base <= 0) {\n primaryBlockedUntil = 0;\n return;\n }\n const multiplier = 2 ** Math.max(0, primaryFailureStreak - 1);\n primaryBlockedUntil = now() + Math.min(cooldownMax(), base * multiplier);\n };\n\n const recoveryTarget = () =>\n Math.max(1, deps.primaryRecoverySuccesses ?? DEFAULT_PRIMARY_RECOVERY_SUCCESSES);\n\n const stickyTarget = () => Math.max(0, deps.stickyFallbackTurns ?? 0);\n\n /** Whether the mandatory fallback dwell period is still in effect. */\n const inStickyWindow = () => stickyTurnsElapsed < stickyTarget();\n\n /**\n * Graduated primary recovery: a single success does NOT fully reset the\n * failure ladder. The streak is retained so the next failure continues\n * the exponential backoff instead of restarting at 1 \u2014 preventing an\n * intermittently-available primary from causing endless model bouncing.\n * Only after `recoveryTarget()` consecutive successes is the ladder\n * fully cleared.\n */\n const onPrimarySuccess = (cfg: Config) => {\n if (!sameTarget(blockedPrimary, selectedPrimary(cfg))) return;\n primaryRecoveryHits += 1;\n if (primaryRecoveryHits >= recoveryTarget()) {\n // Enough consecutive successes \u2014 fully clear the ladder.\n primaryFailureStreak = 0;\n primaryRecoveryHits = 0;\n stickyTurnsElapsed = 0;\n lastWorkingFallback = undefined;\n blockedPrimary = undefined;\n primaryBlockedUntil = 0;\n } else {\n // Partial recovery: allow probing next turn but retain the streak\n // so a subsequent failure continues the exponential backoff.\n primaryBlockedUntil = 0;\n }\n };\n\n return {\n name: 'fallback-model',\n\n beforeRun: async (ctx) => {\n if (!dirty) return;\n const cfg = deps.getConfig();\n const primary = selectedPrimary(cfg);\n\n // \u2500\u2500 Sticky fallback dwell \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Count this turn as one completed turn on the working fallback.\n // If we haven't yet dwelled for `stickyTarget()` turns, stay on\n // the fallback even if the cooldown timer has expired.\n stickyTurnsElapsed += 1;\n if (inStickyWindow()) return;\n\n if (primaryInCooldown(cfg)) return;\n if (\n !evaluateModelCalendar(cfg.modelAvailabilitySchedule, primary.providerId, primary.model)\n .allowed ||\n (deps.statusTracker && !deps.statusTracker.isAvailable(primary.providerId, primary.model))\n )\n return;\n try {\n ctx.provider = await deps.buildProvider(primary.providerId, primary.model);\n ctx.model = primary.model;\n await deps.onModelSwitch?.(primary.providerId, primary.model);\n // The next provider call is the half-open primary probe. If it\n // succeeds, onPrimarySuccess will either partially clear (allowing\n // another probe) or fully reset the ladder (after recoveryTarget\n // consecutive successes). If it fails, the catch path marks a\n // longer cooldown and rotates back through the chain.\n primaryBlockedUntil = 0;\n } catch (err) {\n deps.logger?.warn(\n `fallback-model: could not restore primary \"${primary.providerId}/${primary.model}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n markPrimaryFailure(cfg);\n return;\n }\n dirty = false;\n },\n\n wrapProviderRunner: async (ctx, request, inner) => {\n // \u2500\u2500 Before calling, check if the current provider/model is blocked \u2500\u2500\n const tracker = deps.statusTracker;\n const calendar = evaluateModelCalendar(\n deps.getConfig().modelAvailabilitySchedule,\n ctx.provider.id,\n ctx.model,\n );\n const trackerBlocked = tracker ? !tracker.isAvailable(ctx.provider.id, ctx.model) : false;\n if (trackerBlocked || !calendar.allowed) {\n deps.logger?.warn(\n `provider-status: \"${ctx.provider.id}/${ctx.model}\" is blocked \u2014 trying fallback chain`,\n );\n // Emit active_blocked so the UI can surface a prominent warning\n const status = tracker?.getStatus(ctx.provider.id, ctx.model);\n const logical =\n tracker?.logicalIdentity(ctx.provider.id, ctx.model) ??\n logicalCalendarTarget(ctx.provider.id, ctx.model);\n deps.events.emit('provider.active_blocked', {\n providerId: logical.providerId,\n model: logical.model,\n state: 'blocked',\n fallbackProviderId: '',\n fallbackModel: '',\n lastError:\n calendar.rule?.label ??\n (calendar.rule ? 'Blocked by model availability calendar' : undefined) ??\n status?.lastErrorMessage ??\n 'Rate limit or repeated failures',\n sessionId: resolveEventSessionId(ctx),\n timestamp: Date.now(),\n });\n // Skipping the blocked primary \u2014 simulate a fallback-worthy error\n const skipErr = new ProviderError(\n `Skipping unavailable \"${ctx.provider.id}/${ctx.model}\" \u2014 try fallback`,\n 429,\n true,\n ctx.provider.id,\n { kind: 'rate_limit' },\n );\n return runFallbackChain(ctx, request, inner, skipErr, true);\n }\n\n try {\n const response = ensureUsableModelResponse(\n await inner(ctx, request),\n ctx.provider.id,\n ctx.model,\n );\n // Record success in the tracker\n tracker?.recordSuccess(ctx.provider.id, ctx.model, {\n sessionId: resolveEventSessionId(ctx),\n agentId: ctx.agentId,\n });\n const cfg = deps.getConfig();\n const primary = selectedPrimary(cfg);\n if (ctx.provider.id === primary.providerId && ctx.model === primary.model) {\n onPrimarySuccess(cfg);\n }\n return response;\n } catch (firstErr) {\n return runFallbackChain(ctx, request, inner, firstErr);\n }\n\n // \u2500\u2500 Shared fallback-chain runner with tracker integration \u2500\u2500\n async function runFallbackChain(\n ctx_: typeof ctx,\n request_: typeof request,\n inner_: typeof inner,\n firstErr_: unknown,\n alreadyTracked = false,\n ): Promise<Response> {\n let lastErr: unknown = firstErr_;\n const cfg = deps.getConfig();\n const current = { providerId: ctx_.provider.id, model: ctx_.model };\n\n // Record the failure in the tracker (real ProviderError, not our synthetic skip)\n const firstErrIsProvider = firstErr_ instanceof ProviderError || ProviderError.isProviderError(firstErr_);\n if (!alreadyTracked && firstErrIsProvider && tracker) {\n tracker.recordFailure(\n ctx_.provider.id,\n ctx_.model,\n (firstErr_ as ProviderError).kind,\n (firstErr_ as ProviderError).status,\n (firstErr_ as ProviderError).describe(),\n {\n sessionId: resolveEventSessionId(ctx_),\n agentId: ctx_.agentId,\n retryAfterMs: firstErr_.body?.retryAfterMs,\n },\n );\n }\n\n const chain = fallbackCandidates(cfg, current, {\n fallbackModels: deps.getFallbackModels?.(),\n fallbackProfile: deps.getFallbackProfile?.(),\n sharedManager: deps.fallbackProfileManager,\n primary: selectedPrimary(cfg),\n closedWorld: deps.isClosedWorld?.() ?? false,\n });\n\n // Filter blocked entries from the chain via the tracker\n let usableChain = tracker\n ? chain.filter((e) => tracker.isAvailable(e.providerId, e.model))\n : chain;\n\n // \u2500\u2500 Last-working-fallback prioritization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // If a prior turn found a model that worked, move it to the front\n // of the chain so we don't re-traverse flaky entries that already\n // failed. The dedup filter in fallbackCandidates already removed\n // duplicates, so this is a stable re-order, not a duplication.\n if (\n lastWorkingFallback &&\n usableChain.length > 1 &&\n // Don't front-load if the last-working is the current model\n // (we're already on it) or if it's now blocked.\n !(lastWorkingFallback.providerId === current.providerId &&\n lastWorkingFallback.model === current.model) &&\n !(tracker && !tracker.isAvailable(lastWorkingFallback.providerId, lastWorkingFallback.model))\n ) {\n const lwfKey = `${lastWorkingFallback.providerId}/${lastWorkingFallback.model}`;\n const lwfEntry = usableChain.find(\n (e) => `${e.providerId}/${e.model}` === lwfKey,\n );\n if (lwfEntry) {\n usableChain = [\n lwfEntry,\n ...usableChain.filter((e) => `${e.providerId}/${e.model}` !== lwfKey),\n ];\n }\n }\n\n if (\n !alreadyTracked &&\n shouldFallback(firstErr_) !== null &&\n sameTarget(selectedPrimary(cfg), current)\n ) {\n markPrimaryFailure(cfg);\n }\n\n // Gate ONCE, on the error that TRIGGERED the fallback \u2014 not per entry\n // on `lastErr`.\n //\n // `lastErr` is reassigned by every failed attempt below, so the old\n // per-entry check let ONE bad candidate abort the whole chain: a model\n // id that no longer exists on its provider answers 404, which\n // classifies as `invalid_request` (not fallback-worthy), and the next\n // iteration hit `break`. Every healthy entry after it went untried and\n // the turn died with \"model not found\" while a working fallback sat\n // one slot down. Stale entries are easy to acquire \u2014 `resolveRefs`\n // never validates `fallbackModels` against the provider's model list,\n // `buildProvider` ignores the model argument entirely, and\n // `config.providers[].models` is an unrefreshed snapshot.\n //\n // A per-entry failure now just moves to the next candidate; only the\n // triggering error decides whether we fall back at all.\n const status = shouldFallback(firstErr_);\n if (status === null) throw firstErr_; // not a fallback-worthy error\n\n for (const entry of usableChain) {\n if (\n !evaluateModelCalendar(cfg.modelAvailabilitySchedule, entry.providerId, entry.model)\n .allowed\n )\n continue;\n\n // Re-check tracker availability right before attempting this entry.\n // The chain was computed from a snapshot of `isAvailable`, but an\n // intervening failure \u2014 from a concurrent subagent, a prior entry\n // in this loop, or a race with the one-shot LLM helper \u2014 may have\n // pushed this (providerId, model) into the waiting room since then.\n // A stale-chain call would waste time and burn rate-limit budget.\n if (tracker && !tracker.isAvailable(entry.providerId, entry.model)) {\n deps.logger?.warn(\n `provider-status: \"${entry.providerId}/${entry.model}\" entered the waiting room` +\n ` since the chain was computed \u2014 skipping`,\n );\n continue;\n }\n\n const targetProviderId = entry.providerId;\n const targetModel = entry.model;\n if (targetProviderId === ctx_.provider.id && targetModel === ctx_.model) continue;\n if (\n primaryInCooldown(cfg) &&\n sameTarget(selectedPrimary(cfg), {\n providerId: targetProviderId,\n model: targetModel,\n })\n ) {\n continue;\n }\n\n const from = { providerId: ctx_.provider.id, model: ctx_.model };\n const logicalFrom = tracker?.logicalIdentity(from.providerId, from.model) ?? from;\n\n let nextProvider: Provider;\n try {\n nextProvider = await deps.buildProvider(targetProviderId, targetModel);\n } catch (err) {\n deps.logger?.warn(\n `fallback-model: skipping \"${targetProviderId}/${targetModel}\" \u2014 cannot build provider \"${targetProviderId}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n continue;\n }\n\n // Pre-filter: if we know the current request's token count and this\n // fallback model's context window is provably too small, skip it\n // instead of dispatching a call that will fail with context_overflow\n // (which is NOT fallback-worthy and would surface as an error to the\n // user). The check is conservative: only skips when the INPUT alone\n // exceeds the window \u2014 if input fits, the call may still succeed.\n const entryMaxContext = maxContextOf(nextProvider);\n const currentTokens = ctx_.lastRequestTokens;\n if (\n entryMaxContext > 0 &&\n typeof currentTokens === 'number' &&\n currentTokens > 0 &&\n currentTokens > entryMaxContext\n ) {\n deps.logger?.warn(\n `fallback-model: skipping \"${targetProviderId}/${targetModel}\" \u2014 context window ` +\n `(${entryMaxContext}) is smaller than current request tokens (${currentTokens})`,\n );\n continue;\n }\n\n const providerSwitched = nextProvider.id !== from.providerId;\n const warning = contextWindowWarning(ctx_.provider, nextProvider, ctx_.lastRequestTokens);\n ctx_.provider = nextProvider;\n ctx_.model = targetModel;\n request_.model = targetModel;\n bindRequestProvider(request_, nextProvider);\n dirty = true;\n await deps.onModelSwitch?.(targetProviderId, targetModel);\n\n deps.events.emit('provider.fallback', {\n sessionId: resolveEventSessionId(ctx_),\n from: logicalFrom,\n to: tracker?.logicalIdentity(nextProvider.id, targetModel) ?? {\n providerId: nextProvider.id,\n model: targetModel,\n },\n status,\n providerSwitched,\n ...(warning ? { contextWindowWarning: warning } : {}),\n });\n\n try {\n const response = ensureUsableModelResponse(\n await inner_(ctx_, request_),\n ctx_.provider.id,\n ctx_.model,\n );\n tracker?.recordSuccess(nextProvider.id, targetModel, {\n sessionId: resolveEventSessionId(ctx_),\n agentId: ctx_.agentId,\n });\n // Remember this model so the next chain traversal front-loads it.\n lastWorkingFallback = { providerId: nextProvider.id, model: targetModel };\n return response;\n } catch (err) {\n // Record fallback failure too\n if ((err instanceof ProviderError || ProviderError.isProviderError(err)) && tracker) {\n tracker.recordFailure(\n nextProvider.id,\n targetModel,\n (err as ProviderError).kind,\n (err as ProviderError).status,\n (err as ProviderError).describe(),\n {\n sessionId: resolveEventSessionId(ctx_),\n agentId: ctx_.agentId,\n retryAfterMs: err.body?.retryAfterMs,\n },\n );\n }\n lastErr = err;\n }\n }\n\n throw lastErr;\n }\n },\n };\n}\n", "/**\n * Catalog types for the WrongStack agent fleet.\n *\n * An `AgentDefinition` bundles the runtime `SubagentConfig` (id/name/role/\n * prompt/tools) with two things the bare config lacks:\n * - a per-role `budget` tier (consumed by FLEET_ROSTER_BUDGETS), and\n * - dispatcher `capability` metadata (keywords + summary + phase) used by\n * the smart dispatcher to route a free-form task to the best agent.\n *\n * Phase files (`phase1-discovery.ts` \u2026 `phase9-meta.ts`) each export an\n * `AgentDefinition[]`; `index.ts` aggregates them into `AGENT_CATALOG`.\n * `fleet.ts` derives `FLEET_ROSTER` + `FLEET_ROSTER_BUDGETS` from the catalog.\n */\nimport type { SubagentConfig } from '../../types/multi-agent.js';\n\n/** Lifecycle phase grouping. Drives statusline labels + dispatcher tie-breaks. */\nexport type AgentPhase =\n | 'discovery'\n | 'planning'\n | 'build'\n | 'verify'\n | 'review'\n | 'domain'\n | 'knowledge'\n | 'delivery'\n | 'meta';\n\n/** Per-role budget tier. Same shape as fleet.ts `FleetRosterBudget`. */\nexport interface AgentBudgetTier {\n timeoutMs?: number | undefined;\n maxIterations?: number | undefined;\n maxToolCalls?: number | undefined;\n maxTokens?: number | undefined;\n maxCostUsd?: number | undefined;\n}\n\n/** Dispatcher routing metadata. */\nexport interface AgentCapability {\n phase: AgentPhase;\n /**\n * One-line capability summary. Fed to the LLM dispatcher classifier as the\n * candidate's description, and shown to the user when explaining a routing\n * decision. Keep it concrete and distinct from sibling agents.\n */\n summary: string;\n /**\n * Lowercased signal words/phrases for the heuristic dispatcher. A task whose\n * description contains these scores toward this agent. Order doesn't matter;\n * prefer specific terms (\"graphql\", \"wcag\") over generic ones (\"code\").\n */\n keywords: string[];\n /**\n * Optional `RoleDispatcherSignal` attached to the role. Wave-1/2/3/4 roles\n * carry this to make the \"why this role wins\" rationale auditable; legacy\n * roles omit it and the dispatcher falls back to `summary` + `keywords`.\n */\n rationale?: RoleDispatcherSignal | undefined;\n}\n\n/**\n * Read-only view of a role's dispatcher rationale, surfaceable to operators.\n *\n * `rationale` explains what the role owns; `signals` are the dispatcher's\n * routing tokens (extended with role id, sibling keywords, etc. at scoring\n * time); `differentiatesFrom` is the human-readable contrast against the\n * closest sibling.\n */\nexport interface RoleDispatcherSignal {\n rationale: string;\n signals: readonly string[];\n /**\n * One-line description of how this role differs from its closest sibling\n * (\"X finds defects; Y designs threats before code exists\"). Used by tests\n * to assert distinct boundaries and by docs to explain routing.\n */\n differentiatesFrom: string;\n}\n\n/** A single catalog entry: runtime config + budget tier + routing metadata. */\nexport interface AgentDefinition {\n config: SubagentConfig;\n budget: AgentBudgetTier;\n capability: AgentCapability;\n}\n\nconst HOUR = 60 * 60 * 1000;\n\n/**\n * Budget tiers by workload weight. Deliberately generous \u2014 the project's\n * existing roster uses multi-hour ceilings to avoid spurious timeouts on\n * monorepo-scale work, and the auto-extend handshake raises them further when\n * a subagent is still making progress.\n */\nexport const LIGHT_BUDGET: AgentBudgetTier = {\n timeoutMs: 3 * HOUR,\n maxIterations: 3000,\n maxToolCalls: 8000,\n};\nexport const MEDIUM_BUDGET: AgentBudgetTier = {\n timeoutMs: 5 * HOUR,\n maxIterations: 5000,\n maxToolCalls: 14000,\n};\nexport const HEAVY_BUDGET: AgentBudgetTier = {\n timeoutMs: 10 * HOUR,\n maxIterations: 8000,\n maxToolCalls: 20000,\n};\n\n/**\n * Tool allowlist presets. Agents pass the smallest set that covers their job \u2014\n * a planning agent should not hold `write`/`bash`, a reviewer should be\n * read-only. Spread + extend per-agent where a role needs one extra tool.\n */\nexport const TOOLS = {\n /** Pure read/inspect \u2014 safe for analysis and review agents. */\n read: ['read', 'grep', 'glob', 'search', 'tree', 'mailbox'],\n /** Read + structured inspection (logs, diffs, json, dependency audit). */\n inspect: ['read', 'grep', 'glob', 'search', 'tree', 'json', 'diff', 'logs', 'audit', 'mailbox'],\n /** Read + edit (no shell). For agents that write code/docs but don't run it. */\n write: ['read', 'grep', 'glob', 'search', 'tree', 'write', 'edit', 'replace', 'patch', 'mailbox'],\n /** Full build loop: edit + run (lint/format/typecheck/test/bash). */\n build: [\n 'read',\n 'grep',\n 'glob',\n 'search',\n 'tree',\n 'write',\n 'edit',\n 'replace',\n 'patch',\n 'bash',\n 'exec',\n 'lint',\n 'format',\n 'typecheck',\n 'test',\n 'mailbox',\n ],\n /** Version control. */\n vcs: ['read', 'grep', 'glob', 'git', 'diff'],\n /** Dependency management + CVE audit. */\n deps: ['read', 'grep', 'glob', 'install', 'outdated', 'audit', 'json', 'mailbox'],\n /** Documentation authoring. */\n docs: ['read', 'grep', 'glob', 'search', 'tree', 'write', 'edit', 'document', 'mailbox'],\n /** Web research. */\n research: ['read', 'grep', 'glob', 'search', 'fetch', 'mailbox'],\n} as const satisfies Record<string, readonly string[]>;\n", "import { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { resolveWstackPaths } from '../../utils/wstack-paths.js';\nimport { buildProjectContextualizedPrompt } from './project-agent-identity.js';\n\n/**\n * Cache of resolved prompt text, keyed by `<envDir>\\0<id>`. Prompt files do\n * not change during a process lifetime, so the first successful (or failed)\n * lookup is memoized. The key includes the override env var so tests that set\n * `WRONGSTACK_AGENT_INSTRUCTIONS_DIR` still observe fresh resolution.\n */\nconst promptCache = new Map<string, string>();\n\n/**\n * Cache of the ordered candidate directory list, keyed by `<envDir>\\0<cwd-home>`.\n * The list is otherwise identical for every `agentPrompt()` call, so resolving\n * (and sorting via `statSync`) it once per env avoids ~7 redundant `statSync`\n * probes per call. `fleet.ts` + the phase catalogs alone call `agentPrompt()`\n * ~60 times at import time.\n */\nconst candidateCache = new Map<string, string[]>();\n\n/**\n * Mandatory modern technology policy that every built-in roster agent\n * inherits. Read at most once per process (memoized in `promptCache`) and\n * prepended to each role's base prompt so the rule travels with the persona.\n */\nconst TECH_VERSION_POLICY_KEY = '\\u0000__tech_version_policy__';\n\nlet techVersionPolicyBody: string | undefined;\n\nconst INLINE_TECH_VERSION_POLICY = `# Mandatory modern technology policy\n\nYou are bound to the current stable version of every library, framework and\npackage you use. The latest stable is preferred; the latest *published* is\n*required*.\n\n## Non-negotiable rules\n\n1. **Verify the version, never trust a number from training data.** Before\n recommending a package or framework version, fetch the live registry\n (npm, PyPI, crates, Go proxy, GitHub releases). Treat the value you read\n as the only acceptable reference; do not interpolate from memory.\n\n2. **Latest stable by default.** Pick the highest stable release that\n satisfies the project runtime, the pinned peer-dependency range, and\n the role's required APIs. Pin to \\`^<major>.<minor>.0\\` and report the\n exact version.\n\n3. **Reject alpha / beta / RC / nightly** unless the user explicitly\n requests a pre-release. State the rejection reason in the output.\n\n4. **Reject EOL, deprecated and unmaintained packages** \u2014 a package with\n no release in >2 years **and** open critical issues is *dead*. Reject\n it on the same day you find it and propose a maintained replacement.\n\n5. **Reject prehistoric technology.** The well-known blocklist:\n - \\`axios\\` / \\`node-fetch\\` / \\`got\\` / \\`request\\` \u2192 native \\`fetch\\` (Node 18+).\n - \\`moment\\` \u2192 \\`date-fns\\`, \\`luxon\\` or \\`Temporal\\`.\n - jQuery on new projects \u2192 vanilla DOM or React.\n - Gulp / Grunt \u2192 \\`tsup\\`, \\`esbuild\\` or \\`vite\\`.\n - CoffeeScript / Flow \u2192 TypeScript.\n - \\`Bluebird\\` \u2192 native Promises.\n - \\`crypto-js\\` \u2192 \\`node:crypto\\` or Web Crypto.\n - Bower \u2192 npm or pnpm.\n - \\`underscore\\` \u2192 \\`lodash\\` or native ES2020+.\n Use the intervention phrase: **\"This isn't code, this is X-year-old\n technology.\"** Follow with the modern replacement and a one-step\n migration path.\n\n6. **Prefer built-in over third-party.** Before adding a dependency, check\n the language or runtime native API. Examples:\n - Node \u226522.19 \u2192 \\`node:test\\`, \\`node:sqlite\\`, \\`node:fs/promises\\`,\n \\`fetch\\`, \\`WebSocket\\`, \\`node:crypto\\`, \\`node:stream/web\\`, AbortSignal.\n - Browsers \u2192 \\`fetch\\`, \\`AbortController\\`, \\`structuredClone\\`,\n \\`URLPattern\\`, Web Streams.\n - TypeScript \u22655.6 \u2192 \\`using\\` declarations, \\`await using\\`, the new\n iterator helpers, \\`NoInfer\\`, the \\`esnext.disposable\\` types.\n\n7. **Never silently upgrade a pinned version.** If the project pins an\n old version, call it out and report: the new compatible version,\n the breaking changes between them, and a migration recipe. Do not\n upgrade without confirmation.\n\n8. **Always cite the source and the verification time.** Output must\n include the registry URL and the date you verified, so the operator\n can audit the choice.\n\n9. **Never use deprecated APIs even if a tutorial says so.** When a\n vendor marks an API deprecated, switch to the documented replacement\n and record the migration in the role's working notes.\n\n10. **A package must exist.** Reject and call out any hallucinated package\n or framework. The intervention phrase for missing packages is\n **\"This package does not exist on the registry.\"** and the role must\n propose a real, maintained alternative.`;\n\nfunction loadTechVersionPolicy(): string {\n if (techVersionPolicyBody !== undefined) return techVersionPolicyBody;\n const fromDisk = policyBody();\n techVersionPolicyBody = fromDisk || INLINE_TECH_VERSION_POLICY;\n return techVersionPolicyBody;\n}\n\nfunction policyCandidateDirs(): string[] {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const profileInstructions = resolveWstackPaths({ projectRoot: process.cwd() }).globalInstructions;\n return [\n path.resolve(here, '../../../../instructions/agents'),\n path.resolve(here, '../../../instructions/agents'),\n path.resolve(here, '../../instructions/agents'),\n path.resolve(here, '../instructions/agents'),\n path.resolve(here, 'instructions/agents'),\n path.join(profileInstructions, 'agents'),\n profileInstructions,\n ].filter((dir, index, all) => all.indexOf(dir) === index);\n}\n\nfunction policyBody(): string {\n const here = path.dirname(fileURLToPath(import.meta.url));\n // Two layouts must resolve:\n // * source: `packages/core/src/coordination/agents` \u2192 `../../instructions/agents/_policy/tech-version.md`\n // * build: `packages/core/dist/coordination/agents` \u2192 `../../../instructions/agents/_policy/tech-version.md`\n // Both point at the same on-disk file. We list every plausible relative\n // depth so the policy finds the prompt regardless of where the consumer\n // imported the helper from.\n const roots = [\n path.resolve(here, '_policy/tech-version.md'),\n path.resolve(here, '../_policy/tech-version.md'),\n path.resolve(here, '../../../instructions/agents/_policy/tech-version.md'),\n path.resolve(here, '../../instructions/agents/_policy/tech-version.md'),\n path.resolve(here, '../instructions/agents/_policy/tech-version.md'),\n path.resolve(here, '../../../../instructions/agents/_policy/tech-version.md'),\n path.resolve(here, 'instructions/agents/_policy/tech-version.md'),\n ];\n for (const file of roots) {\n try {\n return readFileSync(file, 'utf8').trim();\n } catch {\n // try next candidate\n }\n }\n for (const dir of policyCandidateDirs()) {\n try {\n return readFileSync(path.join(dir, '_policy', 'tech-version.md'), 'utf8').trim();\n } catch {\n // try next candidate\n }\n }\n return '';\n}\n\nexport function agentPrompt(id: string): string {\n // The policy body itself is a single shared suffix; return it directly\n // when the sentinel key is requested (used by tests / docs).\n if (id === TECH_VERSION_POLICY_KEY) return loadTechVersionPolicy();\n\n const envDir = process.env['WRONGSTACK_AGENT_INSTRUCTIONS_DIR'] ?? '';\n const policyOn = process.env['WRONGSTACK_AGENT_POLICY'] === 'on';\n const cacheBypass =\n (globalThis as { __WS_DISABLE_PROMPT_CACHE__?: boolean }).__WS_DISABLE_PROMPT_CACHE__ ===\n true;\n const cacheKey = `${envDir}\\u0000${policyOn ? 1 : 0}\\u0000${id}`;\n const cached = cacheBypass ? undefined : promptCache.get(cacheKey);\n if (cached !== undefined) return cached;\n\n const fileName = `${id}.md`;\n let resolved = '';\n for (const dir of agentPromptDirCandidates(envDir)) {\n try {\n resolved = readFileSync(path.join(dir, fileName), 'utf8').trim();\n break;\n } catch {\n // try next candidate\n }\n }\n // The policy body is appended to *every* role's prompt so the latest-stable\n // invariant is enforced uniformly. It is opt-in: the policy ships only when\n // the host explicitly enables it via `WRONGSTACK_AGENT_POLICY=on`. Tests\n // and byte-equality smoke fixtures stay deterministic by default; the\n // dispatcher and `agent-catalog` integration test opt in for the contract.\n const policy = policyOn ? loadTechVersionPolicy() : '';\n if (policy) {\n if (!resolved) {\n resolved = policy;\n } else if (cacheBypass || !resolved.includes('Mandatory modern technology policy')) {\n // Older role briefs reference the policy by name but do not yet embed\n // its body \u2014 append the canonical body so every prompt carries the\n // latest-stable invariant in full. In test-bypass mode we always\n // append so the cache-bypass assertion sees the canonical text even\n // when an older prompt already mentions the policy by name.\n resolved = `${resolved}\\n\\n---\\n\\n${policy}`;\n }\n }\n // Project-contextualized prompt: overlay identity, learned wisdom and\n // current-knowledge checklist on top of the base role prompt.\n // Uses the current working directory as project root when no explicit\n // WRONGSTACK_PROJECT_ROOT is set, allowing the project-specific agent\n // identity mechanism to work without any code changes.\n const projectRoot = process.env['WRONGSTACK_PROJECT_ROOT'] || process.cwd();\n resolved = buildProjectContextualizedPrompt(resolved, id, projectRoot);\n if (!cacheBypass) promptCache.set(cacheKey, resolved);\n return resolved;\n}\n\nfunction agentPromptDirCandidates(envDir: string): string[] {\n const profileInstructions = resolveWstackPaths({ projectRoot: process.cwd() }).globalInstructions;\n const candKey = `${envDir}\\u0000${profileInstructions}`;\n const cached = candidateCache.get(candKey);\n if (cached !== undefined) return cached;\n\n const here = path.dirname(fileURLToPath(import.meta.url));\n const explicitDir = envDir || undefined;\n const candidates = [\n ...(explicitDir ? [path.resolve(explicitDir)] : []),\n path.join(profileInstructions, 'agents'),\n path.resolve(here, '../../../../instructions/agents'),\n path.resolve(here, '../../../instructions/agents'),\n path.resolve(here, '../../instructions/agents'),\n path.resolve(here, '../instructions/agents'),\n path.resolve(here, 'instructions/agents'),\n ];\n const ordered = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n candidateCache.set(candKey, ordered);\n return ordered;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import { createHash } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Path layout. All developer-level state lives in ~/.wrongstack/.\n * Per-project state is keyed by the canonical project root under\n * ~/.wrongstack/projects/<slug>/. Linked Git worktrees resolve to their main\n * checkout so coordination and durable state are shared across worktrees.\n *\n * The ONLY thing inside the project tree is the optional\n * .wrongstack/AGENTS.md (committed) and .wrongstack/skills/ (committed).\n */\n\nexport interface WstackPaths {\n /** ~/.wrongstack \u2014 global root. */\n globalRoot: string;\n /** Active profile name resolved from the bootstrap config. */\n profileName: string;\n /** ~/.wrongstack/profiles/<activeProfile> \u2014 active user-profile root. */\n profileDir: string;\n /** Absolute project root. */\n projectRoot: string;\n /** Home directory (~) \u2014 base for foreign tool state (~/.codex, ~/.agents, \u2026). */\n homeDir: string;\n /**\n * ~/.wrongstack/profiles/<activeProfile> \u2014 directory for profile-scoped\n * user state (mode.json, statusline.json, custom-context-modes.json, \u2026).\n */\n configDir: string;\n /** ~/.wrongstack/config.json \u2014 bootstrap config (activeProfile + version). */\n globalConfig: string;\n /**\n * ~/.wrongstack/profiles \u2014 directory containing per-profile configs.\n * Each profile has its own subdirectory with a config.json.\n */\n profilesDir: string;\n /**\n * Resolve the config path for a named profile.\n * Returns ~/.wrongstack/profiles/<name>/config.json.\n */\n profileConfig: (name: string) => string;\n /** Resolve ~/.wrongstack/profiles/<name>/statusline.json */\n profileStatuslineConfig: (name: string) => string;\n /** Resolve ~/.wrongstack/profiles/<name>/mode.json */\n profileModeConfig: (name: string) => string;\n /** Resolve ~/.wrongstack/profiles/<name>/provider-status.json */\n profileProviderStatus: (name: string) => string;\n /** Resolve ~/.wrongstack/profiles/<name>/update-cache.json */\n profileUpdateCache: (name: string) => string;\n /** ~/.wrongstack/.key \u2014 32 random bytes, mode 0600, AES-GCM key for the secret vault. */\n secretsKey: string;\n /** ~/.wrongstack/profiles/<activeProfile>/memory.md \u2014 profile memory. */\n globalMemory: string;\n /** ~/.wrongstack/profiles/<activeProfile>/skills \u2014 profile skills. */\n globalSkills: string;\n /** ~/.claude/skills \u2014 user-global skills from foreign coding agents (Claude Code, Codex, \u2026). Read-only. */\n globalClaudeSkills: string;\n /** ~/.wrongstack/profiles/<activeProfile>/design-kits \u2014 profile Design Studio kits. */\n globalDesignKits: string;\n /** ~/.wrongstack/profiles/<activeProfile>/prompts \u2014 profile prompt library. */\n globalPrompts: string;\n /** ~/.wrongstack/profiles/<activeProfile>/instructions \u2014 profile instruction overrides. */\n globalInstructions: string;\n /** ~/.wrongstack/profiles/<activeProfile>/prompt-usage.json \u2014 prompt usage. */\n promptUsage: string;\n /** ~/.wrongstack/cache \u2014 fetched data (models.dev, etc.). */\n cacheDir: string;\n /** ~/.wrongstack/cache/models.dev.json */\n modelsCache: string;\n /** ~/.wrongstack/cache/models-overlay.json \u2014 cached curated overlay. */\n modelsOverlayCache: string;\n /**\n * Per-project codebase symbol index (SQLite). Lives under the global project\n * dir \u2014 NOT inside the repo \u2014 so it never clutters the working tree or needs\n * gitignoring. `~/.wrongstack/projects/<hash>/codebase-index`.\n */\n projectCodebaseIndex: string;\n /** ~/.wrongstack/profiles/<activeProfile>/history \u2014 REPL line history. */\n historyFile: string;\n /** ~/.wrongstack/logs/wrongstack.log */\n logFile: string;\n /** ~/.wrongstack/projects/<hash> */\n projectDir: string;\n /** ~/.wrongstack/projects/<hash>/memory.md */\n projectMemory: string;\n /** ~/.wrongstack/projects/<hash>/sessions */\n projectSessions: string;\n /** ~/.wrongstack/projects/<hash>/trust.json */\n projectTrust: string;\n /** ~/.wrongstack/projects/<hash>/meta.json */\n projectMeta: string;\n /** ~/.wrongstack/projects/<hash>/config.local.json \u2014 optional override */\n projectLocalConfig: string;\n /** <project>/.wrongstack/config.json \u2014 per-project settings (safe fields only).\n * This lives inside the project root so it can be gitignored or shared. */\n inProjectConfig: string;\n /** <project>/.wrongstack/AGENTS.md \u2014 committed project memory. */\n inProjectAgentsFile: string;\n /** <project>/.wrongstack/skills \u2014 committed project skills. */\n inProjectSkills: string;\n /** <project>/.claude/skills \u2014 project skills authored for foreign coding agents (Claude Code, \u2026). Read-only. */\n inProjectClaudeSkills: string;\n /** <project>/.wrongstack/prompts \u2014 committed project prompt library. */\n inProjectPrompts: string;\n /** <project>/.wrongstack/instructions \u2014 committed project instruction overrides. */\n inProjectInstructions: string;\n /** <project>/.wrongstack/design-kits \u2014 committed project Design Studio kits. */\n inProjectDesignKits: string;\n /** <project>/.wrongstack/worktrees \u2014 git worktrees for per-phase isolation (gitignored). */\n inProjectWorktrees: string;\n /** Stable hash for the canonical project root (shared by linked Git worktrees). */\n projectHash: string;\n /** Human-readable canonical project slug, shared by linked Git worktrees. */\n projectSlug: string;\n /** ~/.wrongstack/projects/<hash>/goal.json \u2014 goal persistence */\n projectGoal: string;\n /** ~/.wrongstack/projects/<hash>/input-history.json \u2014 TUI prompt input history */\n projectInputHistory: string;\n /** ~/.wrongstack/projects/<hash>/specs \u2014 SDD spec files */\n projectSpecs: string;\n /** ~/.wrongstack/projects/<hash>/task-graphs \u2014 SDD task graphs */\n projectTaskGraphs: string;\n /** ~/.wrongstack/projects/<hash>/sdd-session.json \u2014 SDD session state */\n projectSddSession: string;\n /** ~/.wrongstack/projects/<hash>/plan.json \u2014 plan persistence */\n projectPlan: string;\n /** ~/.wrongstack/projects/<hash>/autophase \u2014 Goal phase-graph JSON files (dir name kept for backward compat) */\n projectAutophase: string;\n /** ~/.wrongstack/projects/<hash>/sdd-boards \u2014 live SDD board snapshots + JSONL event logs */\n projectSddBoards: string;\n /** ~/.wrongstack/profiles/<activeProfile>/sync.json \u2014 CloudSync configuration */\n syncConfig: string;\n /** ~/.wrongstack/config-history \u2014 timestamped backups on every config write */\n configHistoryDir: string;\n /** Function to get the status.json path for a project given its hash. */\n projectStatus: (projectHash: string) => string;\n}\n\n/**\n * Resolve the stable project identity root used by global WrongStack state.\n *\n * A linked Git worktree has its own checkout path and a `.git` *file* that\n * points into `<main>/.git/worktrees/<name>`. Its `commondir` points back to\n * the main checkout's `.git` directory. Treating the linked checkout path as\n * the project identity would split one repository into multiple session,\n * registry, and mailbox directories \u2014 agents in different worktrees would be\n * unable to see or message each other.\n *\n * Project-local paths still use the caller's actual checkout. Only global\n * state identity is canonicalized. Non-Git projects, normal checkouts, Git\n * submodules, and separate-git-dir layouts keep their existing identity.\n */\nexport function canonicalProjectRoot(absRoot: string): string {\n const checkoutRoot = path.resolve(absRoot);\n const dotGit = path.join(checkoutRoot, '.git');\n\n try {\n if (!fs.statSync(dotGit).isFile()) return checkoutRoot;\n\n const gitDirLine = fs.readFileSync(dotGit, 'utf8').trim();\n const match = /^gitdir:\\s*(.+)$/i.exec(gitDirLine);\n if (!match?.[1]) return checkoutRoot;\n\n const gitDir = path.resolve(checkoutRoot, match[1].trim());\n const commonDirFile = path.join(gitDir, 'commondir');\n if (!fs.statSync(commonDirFile).isFile()) return checkoutRoot;\n\n const commonDir = path.resolve(gitDir, fs.readFileSync(commonDirFile, 'utf8').trim());\n // Linked worktrees created by Git share the main checkout's `.git` dir.\n // A submodule or --separate-git-dir layout may point elsewhere; do not\n // guess a working-tree root for those shapes.\n if (path.basename(commonDir).toLowerCase() !== '.git') return checkoutRoot;\n return path.dirname(commonDir);\n } catch {\n // Missing/malformed administrative files must never make path resolution\n // fail. Falling back preserves the pre-canonicalization behavior.\n return checkoutRoot;\n }\n}\n\nexport function projectHash(absRoot: string): string {\n return createHash('sha256').update(canonicalProjectRoot(absRoot)).digest('hex').slice(0, 12);\n}\n\n/**\n * Human-readable project directory name: slugified folder name + short hash\n * suffix for uniqueness. e.g. `wrongstack-a1b2c3` instead of `3024e5e6fa58`.\n */\nexport function projectSlug(absRoot: string): string {\n const identityRoot = canonicalProjectRoot(absRoot);\n const base = slugify(path.basename(identityRoot));\n const hash = createHash('sha256').update(identityRoot).digest('hex').slice(0, 6);\n return `${base}-${hash}`;\n}\n\n/** Turn a folder name into a filesystem-safe lowercase slug. */\nfunction slugify(name: string): string {\n return (\n name\n .toLowerCase()\n // Collapse any run of non-alphanumeric chars into a single hyphen.\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40) || 'project'\n );\n}\n\nexport interface WstackPathOptions {\n userHome?: string | undefined;\n projectRoot: string;\n /** Override the global root (e.g. for tests). Default: `${userHome}/.wrongstack`. */\n globalRoot?: string | undefined;\n /** Explicit profile override. Otherwise read from the root bootstrap config. */\n profileName?: string | undefined;\n}\n\n/** Make an untrusted profile name safe for use as one path segment. */\nexport function safeProfileName(name: string | undefined): string {\n const safe = (name ?? '').replace(/[/\\\\:]/g, '_').replace(/\\.\\./g, '_').trim();\n return safe || 'default';\n}\n\n/**\n * Resolve the selected profile from ~/.wrongstack/config.json. The root file\n * is bootstrap metadata only; a missing/corrupt bootstrap selects `default`.\n */\nexport function activeProfileName(globalRoot: string): string {\n try {\n const parsed = JSON.parse(fs.readFileSync(path.join(globalRoot, 'config.json'), 'utf8')) as {\n activeProfile?: unknown;\n };\n return safeProfileName(typeof parsed.activeProfile === 'string' ? parsed.activeProfile : undefined);\n } catch {\n return 'default';\n }\n}\n\n/**\n * The global `~/.wrongstack` root, honoring the `WRONGSTACK_HOME` env\n * override. The override exists so tests (and sandboxed runs) can redirect\n * ALL global state \u2014 config, secrets, logs, projects/, mailboxes \u2014 away from\n * the real user home. Before it existed, `pnpm test` booted runtimes against\n * the real `~/.wrongstack`: it read the user's real config.json (starting a\n * second live Telegram poller), appended to the real wrongstack.log, and left\n * ~20k orphaned fixture dirs under projects/.\n *\n * Every code path that wants the global dir must come through here (or\n * through `resolveWstackPaths`) instead of `path.join(os.homedir(), '.wrongstack')`.\n */\nexport function wstackGlobalRoot(): string {\n const fromEnv = process.env['WRONGSTACK_HOME'];\n if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);\n return path.join(os.homedir(), '.wrongstack');\n}\n\nexport function resolveWstackPaths(opts: WstackPathOptions): WstackPaths {\n // Precedence: explicit globalRoot > explicit userHome (callers/tests that\n // pass one expect paths under it) > WRONGSTACK_HOME env > real home dir.\n const globalRoot =\n opts.globalRoot ?? (opts.userHome ? path.join(opts.userHome, '.wrongstack') : wstackGlobalRoot());\n // Home dir for FOREIGN tool state (Claude Code's ~/.claude). Independent of\n // WRONGSTACK_HOME, which redirects only WrongStack state: a real user's\n // Claude skills live in their real home, but tests pass `userHome` to keep\n // both `.wrongstack` and `.claude` under a temp dir.\n const homeDir = opts.userHome ?? os.homedir();\n const profileName = safeProfileName(opts.profileName ?? activeProfileName(globalRoot));\n const profileDir = path.join(globalRoot, 'profiles', profileName);\n const hash = projectHash(opts.projectRoot);\n const slug = projectSlug(opts.projectRoot);\n const projectDir = path.join(globalRoot, 'projects', slug);\n return {\n globalRoot,\n profileName,\n profileDir,\n projectRoot: opts.projectRoot,\n homeDir,\n configDir: profileDir,\n globalConfig: path.join(globalRoot, 'config.json'),\n profilesDir: path.join(globalRoot, 'profiles'),\n profileConfig: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'config.json');\n },\n profileStatuslineConfig: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'statusline.json');\n },\n profileModeConfig: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'mode.json');\n },\n profileProviderStatus: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'provider-status.json');\n },\n profileUpdateCache: (name: string) => {\n return path.join(globalRoot, 'profiles', safeProfileName(name), 'update-cache.json');\n },\n secretsKey: path.join(globalRoot, '.key'),\n globalMemory: path.join(profileDir, 'memory.md'),\n globalSkills: path.join(profileDir, 'skills'),\n globalClaudeSkills: path.join(homeDir, '.claude', 'skills'),\n globalDesignKits: path.join(profileDir, 'design-kits'),\n globalPrompts: path.join(profileDir, 'prompts'),\n globalInstructions: path.join(profileDir, 'instructions'),\n promptUsage: path.join(profileDir, 'prompt-usage.json'),\n cacheDir: path.join(globalRoot, 'cache'),\n modelsCache: path.join(globalRoot, 'cache', 'models.dev.json'),\n modelsOverlayCache: path.join(globalRoot, 'cache', 'models-overlay.json'),\n historyFile: path.join(profileDir, 'history'),\n logFile: path.join(globalRoot, 'logs', 'wrongstack.log'),\n projectDir,\n projectCodebaseIndex: path.join(projectDir, 'codebase-index'),\n projectMemory: path.join(projectDir, 'memory.md'),\n projectSessions: path.join(projectDir, 'sessions'),\n projectTrust: path.join(projectDir, 'trust.json'),\n projectMeta: path.join(projectDir, 'meta.json'),\n projectLocalConfig: path.join(projectDir, 'config.local.json'),\n inProjectConfig: path.join(opts.projectRoot, '.wrongstack', 'config.json'),\n inProjectAgentsFile: path.join(opts.projectRoot, '.wrongstack', 'AGENTS.md'),\n inProjectSkills: path.join(opts.projectRoot, '.wrongstack', 'skills'),\n inProjectClaudeSkills: path.join(opts.projectRoot, '.claude', 'skills'),\n inProjectPrompts: path.join(opts.projectRoot, '.wrongstack', 'prompts'),\n inProjectInstructions: path.join(opts.projectRoot, '.wrongstack', 'instructions'),\n inProjectDesignKits: path.join(opts.projectRoot, '.wrongstack', 'design-kits'),\n inProjectWorktrees: path.join(opts.projectRoot, '.wrongstack', 'worktrees'),\n projectHash: hash,\n projectSlug: slug,\n projectGoal: path.join(projectDir, 'goal.json'),\n projectInputHistory: path.join(projectDir, 'input-history.json'),\n projectSpecs: path.join(projectDir, 'specs'),\n projectTaskGraphs: path.join(projectDir, 'task-graphs'),\n projectSddSession: path.join(projectDir, 'sdd-session.json'),\n projectPlan: path.join(projectDir, 'plan.json'),\n projectAutophase: path.join(projectDir, 'autophase'),\n projectSddBoards: path.join(projectDir, 'sdd-boards'),\n syncConfig: path.join(profileDir, 'sync.json'),\n configHistoryDir: path.join(globalRoot, 'config-history'),\n projectStatus: (projectHash: string) => path.join(globalRoot, 'projects', projectHash, 'status.json'),\n };\n}\n", "/**\n * Project-level agent identity, override and learning layer.\n *\n * Every built-in roster agent has a base definition (role + prompt + tools +\n * skills) in the catalog. On top of that, **each project** can:\n *\n * 1. Override prompt, tools, skills, budget per role\n * 2. Accumulate learned wisdom specific to this codebase\n * 3. Attach a project-custom identity (name, avatar, tone)\n *\n * Resolution cascade (most \u2192 least specific):\n * activeLearning.json \u2192 project-identity.md \u2192 catalog base\n *\n * Files live under `.wrongstack/agents/<role>/`:\n * config.json \u2014 static overrides (tools, budget, skillNames)\n * identity.md \u2014 custom prompt appendix (tone, project-specific rules)\n * learned.md \u2014 auto-generated wisdom from past sessions\n * knowledge.md \u2014 current-needs checklist (what versions to verify today)\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport * as path from 'node:path';\nimport type { SubagentConfig } from '../../types/multi-agent.js';\nimport { validateProjectAgentConfig } from './project-agent-config-validation.js';\nimport { BUILT_IN_KNOWLEDGE_MANIFESTS } from './project-agent-knowledge-manifests.js';\nimport {\n loadProjectAgentLearningPolicy,\n type ProjectAgentLearningPolicy,\n} from './project-agent-learning-policy.js';\nimport {\n splitLearnedEntries,\n tokenOverlap,\n} from './project-agent-learning-entries.js';\nimport {\n mergeStructuredEntries,\n parseStructuredLearnedEntriesFromContent,\n renderLearnedInstructions,\n type StructuredLearnedEntry,\n} from './project-agent-learning-structured.js';\nimport {\n assertProjectAgentRole,\n learningPolicyPath,\n roleDir,\n writeTextAtomically,\n} from './project-agent-paths.js';\nimport {\n LEARNED_HARD_LIMIT,\n LEARNED_SOFT_LIMIT,\n normalizeForComparison,\n normalizeLearnedEntry,\n} from './project-agent-learning-normalize.js';\nimport type {\n LearnedCaptureResult,\n ProjectAgentConfig,\n RoleKnowledgeManifest,\n} from './project-agent-identity-types.js';\nimport {\n isConsolidated,\n loadConsolidationMetadata,\n loadProjectAgentConsolidated,\n type ConsolidationMetadata,\n} from './project-agent-consolidation.js';\n\nexport { validateProjectAgentConfig } from './project-agent-config-validation.js';\nexport {\n classifyLearnedEntry,\n LEARNED_ENTRY_MAX_CHARS,\n LEARNED_HARD_LIMIT,\n LEARNED_SOFT_LIMIT,\n type LearnedEntryCategory,\n normalizeLearnedEntry,\n} from './project-agent-learning-normalize.js';\nexport {\n decomposeLearnedEntry,\n mergeStructuredEntries,\n parseLearnedEntryStamp,\n renderLearnedInstructions,\n type StructuredLearnedEntry,\n} from './project-agent-learning-structured.js';\nexport {\n loadProjectAgentLearningPolicy,\n type ProjectAgentLearningPolicy,\n updateProjectAgentLearningPolicy,\n} from './project-agent-learning-policy.js';\nexport { assertProjectAgentRole } from './project-agent-paths.js';\nexport {\n buildConsolidationInstruction,\n clearProjectAgentConsolidated,\n isConsolidated,\n loadConsolidationMetadata,\n loadProjectAgentConsolidated,\n saveProjectAgentConsolidated,\n type ConsolidationMetadata,\n} from './project-agent-consolidation.js';\nexport type {\n CreateProjectAgentInput,\n LearnedCaptureResult,\n ProjectAgentConfig,\n ProjectAgentProfile,\n RoleKnowledgeManifest,\n} from './project-agent-identity-types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport {\n createProjectAgent,\n loadProjectAgentProfile,\n slugifyProjectAgentRole,\n} from './project-agent-profile.js';\nexport {\n listProjectAgentRoles,\n refreshProjectAgentIdentity,\n resetProjectAgentIdentity,\n updateProjectAgentConfig,\n updateProjectAgentIdentity,\n updateProjectAgentKnowledge,\n updateProjectAgentLearned,\n} from './project-agent-files.js';\nimport { loadProjectAgentProfile } from './project-agent-profile.js';\nimport { listProjectAgentRoles } from './project-agent-files.js';\n\n/**\n * Live roster overlay. Project policy is resolved lazily for both built-in and\n * project-created roles, so WebUI changes take effect on the next spawn without\n * rebuilding the Director. Built-in roles keep their safety floors; custom\n * roles may opt into a deliberately narrow runtime.\n */\nexport function createProjectAgentRoster(\n baseRoster: Record<string, SubagentConfig>,\n projectRoot?: string,\n): Record<string, SubagentConfig> {\n const target = { ...baseRoster };\n const resolveRole = (role: string, resolving = new Set<string>()): SubagentConfig | undefined => {\n if (resolving.has(role)) return undefined;\n const isBuiltIn = Object.hasOwn(target, role);\n if (!isBuiltIn && !listProjectAgentRoles(projectRoot).includes(role)) return undefined;\n resolving.add(role);\n const profile = loadProjectAgentProfile(role, projectRoot);\n const template = isBuiltIn\n ? target[role]\n : profile\n ? (resolveRole(profile.baseRole, resolving) ?? target['generic'])\n : target['generic'];\n resolving.delete(role);\n if (!template) return undefined;\n const base = isBuiltIn\n ? template\n : {\n ...template,\n id: role,\n role,\n name: profile?.name ?? role,\n ...(profile\n ? {\n dispatch: {\n summary: profile.purpose,\n keywords: [\n ...profile.taskTypes,\n ...new Set(\n `${profile.purpose} ${profile.taskTypes.join(' ')}`\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((word) => word.length >= 3),\n ),\n ],\n },\n }\n : {}),\n };\n return applyProjectAgentConfig(base, loadProjectAgentConfig(role, projectRoot), {\n protectSystemRole: isBuiltIn && !profile,\n });\n };\n\n return new Proxy(target, {\n get(current, property, receiver) {\n if (typeof property !== 'string') return Reflect.get(current, property, receiver);\n return resolveRole(property) ?? Reflect.get(current, property, receiver);\n },\n has(current, property) {\n return typeof property === 'string'\n ? Reflect.has(current, property) || resolveRole(property) !== undefined\n : Reflect.has(current, property);\n },\n ownKeys(current) {\n return [...new Set([...Reflect.ownKeys(current), ...listProjectAgentRoles(projectRoot)])];\n },\n getOwnPropertyDescriptor(current, property) {\n const descriptor = Reflect.getOwnPropertyDescriptor(current, property);\n if (descriptor || typeof property !== 'string' || !resolveRole(property)) return descriptor;\n return {\n configurable: true,\n enumerable: true,\n writable: false,\n value: resolveRole(property),\n };\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Project agent config loading\n// ---------------------------------------------------------------------------\n\n/**\n * Load the project-level agent config for a given role.\n * Returns `undefined` when no project override exists.\n */\nexport function loadProjectAgentConfig(\n role: string,\n projectRoot?: string,\n): ProjectAgentConfig | undefined {\n const cfgPath = path.join(roleDir(role, projectRoot), 'config.json');\n try {\n const raw = readFileSync(cfgPath, 'utf8');\n return validateProjectAgentConfig(JSON.parse(raw));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Load the project-level identity appendix for a given role.\n * Appended to the subagent prompt after the base role prompt and policy.\n * Returns the empty string when no identity file exists.\n */\nexport function loadProjectAgentIdentity(role: string, projectRoot?: string): string {\n const identityPath = path.join(roleDir(role, projectRoot), 'identity.md');\n try {\n return readFileSync(identityPath, 'utf8').trim();\n } catch {\n return '';\n }\n}\n\n/**\n * Load the learning-derived wisdom for a given role.\n * Appended to the subagent prompt as a \"knowledge from past sessions\" block.\n * The learning file is auto-generated by the `memory-curator` or\n * `self-improving` agent roles and contains de-duplicated, curated findings.\n */\nexport function loadProjectAgentLearned(role: string, projectRoot?: string): string {\n const learnedPath = path.join(roleDir(role, projectRoot), 'learned.md');\n try {\n return readFileSync(learnedPath, 'utf8').trim();\n } catch {\n return '';\n }\n}\n\n/**\n * Load the current-knowledge checklist for a given role.\n * Returns the built-in directive if no project override exists.\n * The checklist guides the agent on what to verify from live registries\n * before answering questions in its domain.\n */\nexport function loadRoleKnowledgeManifest(\n role: string,\n projectRoot?: string,\n): RoleKnowledgeManifest | undefined {\n // First look for project-level knowledge manifest\n const projectPath = path.join(roleDir(role, projectRoot), 'knowledge.json');\n try {\n const raw = readFileSync(projectPath, 'utf8');\n return JSON.parse(raw) as RoleKnowledgeManifest;\n } catch {\n // Fall back to built-in manifests\n return BUILT_IN_KNOWLEDGE_MANIFESTS[role];\n }\n}\n\n/**\n * Merge a project agent config onto a base `SubagentConfig`.\n * Returns a new config; does not mutate either input.\n */\nexport function applyProjectAgentConfig(\n base: SubagentConfig,\n projectConfig: ProjectAgentConfig | undefined,\n options: { protectSystemRole?: boolean | undefined } = {},\n): SubagentConfig {\n if (!projectConfig) return base;\n const result: SubagentConfig = { ...base };\n if (projectConfig.tools !== undefined) {\n result.tools = options.protectSystemRole\n ? base.tools === undefined\n ? undefined\n : [...new Set([...base.tools, ...projectConfig.tools])]\n : [...projectConfig.tools];\n }\n if (projectConfig.skillNames !== undefined) result.skillNames = [...projectConfig.skillNames];\n if (projectConfig.provider !== undefined) result.provider = projectConfig.provider;\n if (projectConfig.model !== undefined) result.model = projectConfig.model;\n if (projectConfig.modelPolicy !== undefined) {\n result.modelPolicy = {\n allowed: projectConfig.modelPolicy.allowed.map((target) => ({ ...target })),\n fallbacks: projectConfig.modelPolicy.fallbacks?.map((target) => ({ ...target })),\n // System roles must remain recoverable even when a preferred model is\n // temporarily unavailable. Custom roles may opt into a hard boundary.\n strict: options.protectSystemRole ? false : (projectConfig.modelPolicy.strict ?? false),\n };\n result.fallbackModels = (projectConfig.modelPolicy.fallbacks ?? []).map(\n (target) => `${target.provider}/${target.model}`,\n );\n } else if (projectConfig.fallbackProfile !== undefined) {\n result.fallbackProfile = projectConfig.fallbackProfile;\n }\n if (projectConfig.cwd !== undefined) result.cwd = projectConfig.cwd;\n if (projectConfig.worktree !== undefined) {\n result.worktree =\n options.protectSystemRole &&\n (projectConfig.worktree === true || projectConfig.worktree === 'required')\n ? 'auto'\n : projectConfig.worktree;\n }\n if (projectConfig.availability !== undefined) {\n result.availability = {\n ...projectConfig.availability,\n days: [...projectConfig.availability.days],\n mode: options.protectSystemRole ? 'advisory' : (projectConfig.availability.mode ?? 'enforce'),\n };\n }\n if (projectConfig.allowedCapabilities !== undefined) {\n result.allowedCapabilities = options.protectSystemRole\n ? base.allowedCapabilities === undefined\n ? undefined\n : [...new Set([...base.allowedCapabilities, ...projectConfig.allowedCapabilities])]\n : [...projectConfig.allowedCapabilities];\n }\n if (projectConfig.budget) {\n if (projectConfig.budget.timeoutMs !== undefined)\n result.timeoutMs = projectConfig.budget.timeoutMs;\n if (projectConfig.budget.idleTimeoutMs !== undefined)\n result.idleTimeoutMs = projectConfig.budget.idleTimeoutMs;\n if (projectConfig.budget.maxIterations !== undefined)\n result.maxIterations = projectConfig.budget.maxIterations;\n if (projectConfig.budget.maxToolCalls !== undefined)\n result.maxToolCalls = projectConfig.budget.maxToolCalls;\n if (projectConfig.budget.maxTokens !== undefined)\n result.maxTokens = projectConfig.budget.maxTokens;\n if (projectConfig.budget.maxCostUsd !== undefined)\n result.maxCostUsd = projectConfig.budget.maxCostUsd;\n }\n if (options.protectSystemRole) applySystemAgentBudgetFloors(result);\n return result;\n}\n\nconst SYSTEM_AGENT_BUDGET_FLOORS = {\n timeoutMs: 300_000,\n idleTimeoutMs: 120_000,\n maxIterations: 20,\n maxToolCalls: 40,\n maxTokens: 8_192,\n maxCostUsd: 0.25,\n} as const satisfies Partial<Record<keyof SubagentConfig, number>>;\n\ntype BudgetFloorEntry = {\n [K in keyof typeof SYSTEM_AGENT_BUDGET_FLOORS]: [K, (typeof SYSTEM_AGENT_BUDGET_FLOORS)[K]];\n}[keyof typeof SYSTEM_AGENT_BUDGET_FLOORS];\n\nfunction applySystemAgentBudgetFloors(config: SubagentConfig): void {\n for (const [field, floor] of Object.entries(SYSTEM_AGENT_BUDGET_FLOORS) as BudgetFloorEntry[]) {\n const value = config[field];\n if (typeof value === 'number' && value < floor) config[field] = floor;\n }\n}\n\n/**\n * Build the full project-contextualized prompt for a given role.\n *\n * Cascade, from start to end:\n * 1. Base role prompt from instruction files (agentPrompt(id))\n * 2. Technology policy (appended by agentPrompt)\n * 3. Project identity appendix (identity.md)\n * 4. Learned wisdom (learned.md)\n * 5. Live-knowledge checklist\n */\nexport function buildProjectContextualizedPrompt(\n basePrompt: string,\n role: string,\n projectRoot?: string,\n options: { identityOverride?: string | undefined } = {},\n): string {\n const contextStart = '<!-- wrongstack:project-agent-context:start -->';\n const contextEnd = '<!-- wrongstack:project-agent-context:end -->';\n\n // Skip project identity when WRONGSTACK_AGENT_INSTRUCTIONS_DIR is set\n // (this is a test/override context \u2014 keep byte-exact equality with on-disk files).\n // The marker cleanup below is intentionally placed AFTER this early return so a\n // prompt that already contains legacy context markers is preserved verbatim.\n if (process.env['WRONGSTACK_AGENT_INSTRUCTIONS_DIR']) return basePrompt;\n\n const cleanBase = basePrompt\n .replace(\n /\\s*<!-- wrongstack:project-agent-context:start -->[\\s\\S]*?<!-- wrongstack:project-agent-context:end -->\\s*/g,\n '\\n',\n )\n .trim();\n const parts: string[] = [cleanBase];\n\n const identity = options.identityOverride ?? loadProjectAgentIdentity(role, projectRoot);\n if (identity) {\n parts.push(`\\n\\n# Project custom identity\\n\\n${identity}`);\n }\n\n const learningPolicy = loadProjectAgentLearningPolicy(role, projectRoot);\n // Prefer the reviewed, consolidated document over the raw learned.md buffer.\n // The consolidated version is a synthesized, narrowly-scoped representation\n // of everything the agent has learned \u2014 same information, less context volume.\n //\n // STALENESS GATE: When new raw entries have been captured since the last\n // consolidation (entry count > sourceEntryCount), the consolidation is stale.\n // In that case we append the delta entries so the agent still sees new\n // learnings \u2014 preserving the capture\u2192inject feedback loop without losing\n // the optimization benefit of the consolidated document.\n let learnedContent = '';\n let learnedLabel = '';\n if (learningPolicy.enabled) {\n const consolidated = loadProjectAgentConsolidated(role, projectRoot);\n if (consolidated) {\n const meta = loadConsolidationMetadata(role, projectRoot);\n // Read the raw buffer once; split it for entry counting.\n const rawLearned = loadProjectAgentLearned(role, projectRoot);\n const rawEntries = splitLearnedEntries(rawLearned);\n const rawBytes = Buffer.byteLength(rawLearned, 'utf8');\n // Freshness gate: consolidated.md is preferred, but only while the\n // raw buffer hasn't grown past the snapshot at consolidation time.\n // We check both entry count and byte size \u2014 either exceeding the\n // recorded snapshot means the consolidated document is stale. When\n // metadata is missing entirely we cannot verify freshness, so treat\n // it as stale to avoid orphaning new captures.\n const stale =\n meta === undefined ||\n rawEntries.length > meta.sourceEntryCount ||\n rawBytes > meta.sourceBytes;\n if (stale) {\n if (meta !== undefined && meta.sourceEntryCount < rawEntries.length) {\n // New countable entries arrived since consolidation \u2014 append just\n // the delta to preserve the context optimization while surfacing\n // freshly captured knowledge (capture\u2192inject loop).\n const deltaEntries = rawEntries.slice(meta.sourceEntryCount);\n learnedContent = `${consolidated}\\n\\n---\\n\\n## Recently captured (pending next optimization)\\n\\n${deltaEntries.join('\\n\\n---\\n\\n')}`;\n } else {\n // Metadata missing, or raw grew without new countable entries \u2014\n // cannot compute a precise delta, so serve the full raw buffer.\n learnedContent = rawLearned;\n }\n } else {\n learnedContent = consolidated;\n }\n learnedLabel = 'Consolidated knowledge for this project';\n } else {\n learnedContent = loadProjectAgentLearned(role, projectRoot);\n learnedLabel = 'Learned instructions for this project (structured: what / why / how)';\n }\n }\n if (learnedContent) {\n // Only include content that has meaningful text (strip HTML comments)\n const meaningful = learnedContent.replace(/<!--[\\s\\S]*?-->/g, '').trim();\n if (meaningful.length > 0) {\n parts.push(`\\n\\n# ${learnedLabel}\\n\\n${learnedContent}`);\n }\n }\n\n // \u2500\u2500 Capture mechanism: tell every agent HOW to persist new knowledge \u2500\u2500\n const effectiveProjectRoot = projectRoot || process.cwd();\n const learnedFilePath = path.join(\n effectiveProjectRoot,\n '.wrongstack',\n 'agents',\n role,\n 'learned.md',\n );\n if (learningPolicy.enabled) {\n parts.push(\n `\\n\\n## Knowledge capture\\n\\n` +\n `The file below stores **learning data for this project's \"${role}\" agent** \u2014 not your memory, not a session log. ` +\n `It is read back into the system prompt of every future \"${role}\" invocation, so each entry must teach a future agent how to act. ` +\n `On every capture the runtime **merges your new entry with every prior entry and rewrites the whole buffer as a structured instruction list** \u2014 grouped by category (\"What to do\", \"What to avoid\", \"Patterns to follow\", \"Project facts\"), with each item decomposed into **what** (the rule), **why** (the reason), and **how** (the concrete commands, file paths, or package names that anchor the rule). ` +\n `When you discover a durable principle that future invocations should follow, end your response with a \\`## LEARNED\\` block. The runtime persists it to:\\n\\n` +\n ` \\`\\`\\`\\n ${learnedFilePath}\\n \\`\\`\\`\\n\\n` +\n `**Write directives, not narratives.** Each LEARNED entry should be:\\n\\n` +\n `- A **rule or principle** that applies across sessions, not a description of what happened in this one.\\n` +\n `- A short **imperative or statement** (1\u20133 sentences), starting with a verb like \"Always verify\u2026\", \"Use X for Y\", \"Avoid\u2026\", \"Never assume\u2026\".\\n` +\n `- **Generic** \u2014 no commit SHAs, timestamps, specific line numbers, or PR/issue numbers. File paths, package names, and command names are fine when they anchor the lesson.\\n` +\n `- **Self-contained** \u2014 understandable without the surrounding session context.\\n` +\n `- **Front-load concrete anchors** \u2014 commands in backticks, package names like \\`@wrongstack/core\\`, file paths like \\`packages/core/src/.../foo.ts\\`. The structured-list renderer extracts these as the \"how\" for the entry.\\n\\n` +\n `**Bad** (session log \u2014 rejected at capture time):\\n\\n` +\n `\\`\\`\\`\\n## LEARNED\\nWhen I worked on the telegram plugin today, commit 9c7682b84 had a race condition in poll-lock at line 42 because writeFileSync wasn't using the 'wx' flag.\\n\\`\\`\\`\\n\\n` +\n `**Good** (directive \u2014 persists, then merges into the structured list):\\n\\n` +\n `\\`\\`\\`\\n## LEARNED\\nAlways use the 'wx' (exclusive create) flag with writeFileSync when implementing concurrent lock acquisition in \\`packages/core/src/.../poll-lock.ts\\` \u2014 filesystem-level atomicity guarantees only one writer wins.\\n\\`\\`\\`\\n\\n` +\n `Capture only durable, cross-session knowledge \u2014 never ephemeral task details.`,\n );\n }\n\n const knowledge = loadRoleKnowledgeManifest(role, projectRoot);\n if (knowledge && knowledge.checklist.length > 0) {\n const checklist = knowledge.checklist.map((item) => `- ${item}`).join('\\n');\n parts.push(\n `\\n\\n## Current knowledge requirements\\n\\nVerify these before answering:\\n${checklist}`,\n );\n }\n\n const additions = parts.slice(1).join('\\n\\n').trim();\n if (!additions) return cleanBase;\n return `${cleanBase}\\n\\n${contextStart}\\n${additions}\\n${contextEnd}`;\n}\n\n// ---------------------------------------------------------------------------\n// Learned-wisdom capture from agent output\n// ---------------------------------------------------------------------------\n\n// \u2500\u2500\u2500 learned.md automation contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// TRIGGER Primary: end of a delegated subagent task (CLI fleet host's\n// task.completed handler). The director's task resolution checks the\n// final output text for ## LEARNED blocks and captures durable entries.\n// Secondary: leader's own output after a user-invoked improvement\n// prompt (\"improve the executor agent\"). Never on intermediate tool\n// calls or every iteration \u2014 only once per task resolution.\n// Manual: `/agent-improve <role> capture` at any time.\n//\n// GUARDRAILS\n//\n// 1. COOLDOWN Per-role: minimum 120 seconds between captures. Tracks the\n// last capture timestamp in a module-level Map. A capture within the\n// cooldown window is silently skipped (counter not bumped).\n//\n// 2. FREQUENCY CAP Per-session: at most 3 captures per role before the\n// capture falls through to `/agent-improve` (human-gated). The session\n// is reset on process restart (module reload).\n//\n// 3. HUMAN-APPROVAL THRESHOLD When `learned.md` exceeds `LEARNED_SOFT_LIMIT`\n// (8 KB) the next capture is deferred \u2014 the agent is asked to run\n// `/agent-improve <role> refresh` or the user must call it explicitly.\n// The hintLearnedNeedsSummarization() check is exposed so the CLI can\n// surface this in /agent-improve output.\n//\n// 4. SIZE SOFT_LIMIT = 8 192 B \u2192 hintLearnedNeedsSummarization() returns true.\n// HARD_LIMIT = 16 384 B \u2192 capture halves the structured entry list\n// (oldest first) and re-renders before writing.\n//\n// 5. CONTENT QUALITY A block is run through `normalizeLearnedEntry` and\n// skipped when it cannot be converted into an instructive directive:\n// - too short after stripping ephemeral artifacts (< 30 chars)\n// - all narrative framing with no salvageable directive tail\n// - overwhelmingly narrative (>50% sentences are event descriptions)\n// - longer than LEARNED_ENTRY_MAX_CHARS (600 chars) \u2014 truncated to the\n// first instructive sentence cluster that fits\n// Ephemeral artifacts stripped BEFORE the length check:\n// - git commit SHAs, ISO timestamps, specific line numbers, PR/issue refs\n// Code-only blocks (>70% fenced-code lines) and near-duplicates\n// (Jaccard \u2265 0.55) are still rejected. Surviving entries are stamped\n// with a category tag (convention / pattern / warning / fact).\n//\n// OWNER logic : packages/core/src/coordination/agents/project-agent-identity.ts\n// hook : packages/cli/src/fleet/host.ts\n// ---------------------------------------------------------------------------\n\n// \u2500\u2500\u2500 Automation guardrails \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst captureCooldowns = new Map<string, number>(); // role \u2192 timestamp\nconst captureFrequency = new Map<string, number>(); // role \u2192 count\n\nexport const CAPTURE_COOLDOWN_MS = 120_000; // 2 minutes\nexport const CAPTURE_MAX_PER_SESSION = 3;\n\n/**\n * Check whether a new capture is allowed for this role. Returns a rejection\n * reason string when blocked, or undefined when capture may proceed.\n */\nexport function canCaptureNewLearned(\n role: string,\n existingSize: number,\n isManual: boolean,\n projectRoot?: string,\n): string | undefined {\n const key = `${path.resolve(projectRoot ?? process.cwd())}\\0${assertProjectAgentRole(role)}`;\n // Cooldown gate (bypassed for manual captures)\n if (!isManual) {\n const last = captureCooldowns.get(key);\n if (last && Date.now() - last < CAPTURE_COOLDOWN_MS) {\n return `Cooldown active for role \"${role}\" (${Math.ceil((CAPTURE_COOLDOWN_MS - (Date.now() - last)) / 1000)}s remaining)`;\n }\n }\n\n // Frequency cap (bypassed for manual captures)\n if (!isManual) {\n const count = captureFrequency.get(key) ?? 0;\n if (count >= CAPTURE_MAX_PER_SESSION) {\n return `Frequency cap reached for role \"${role}\" (${count}/${CAPTURE_MAX_PER_SESSION}). Use /agent-improve ${role} capture for manual override.`;\n }\n }\n\n // Size gate: when over SOFT_LIMIT, require manual approval\n if (existingSize > LEARNED_SOFT_LIMIT && !isManual) {\n return `learned.md for role \"${role}\" exceeds soft limit (${existingSize}B / ${LEARNED_SOFT_LIMIT}B). Run /agent-improve ${role} capture manually or /agent-improve ${role} refresh to reset.`;\n }\n\n return undefined;\n}\n\n/**\n * Per-role learning stats for monitoring UIs.\n */\nexport interface ProjectAgentLearnStats {\n role: string;\n exists: boolean;\n entryCount: number;\n totalBytes: number;\n lastCapture: string | null;\n lastCaptureTimestamp: number | null;\n cooldownRemainingMs: number;\n sessionCaptureCount: number;\n needsSummarization: boolean;\n learnedPath: string | null;\n identityPath: string | null;\n hasIdentity: boolean;\n hasConfig: boolean;\n hasKnowledge: boolean;\n learningEnabled: boolean;\n lifetimeCaptureCount: number;\n lastCaptureSource: ProjectAgentLearningPolicy['lastCaptureSource'] | null;\n /** Whether a consolidated document exists for this role. */\n isConsolidated: boolean;\n /** Consolidation metadata, if a consolidation has been performed. */\n consolidation?: ConsolidationMetadata | undefined;\n}\n\nexport function getProjectAgentLearnStats(\n role: string,\n projectRoot?: string,\n): ProjectAgentLearnStats {\n const dir = roleDir(role, projectRoot);\n const learnedPath_ = path.join(dir, 'learned.md');\n const identityPath_ = path.join(dir, 'identity.md');\n const configPath_ = path.join(dir, 'config.json');\n const knowledgePath_ = path.join(dir, 'knowledge.json');\n let learnedText = '';\n try {\n learnedText = readFileSync(learnedPath_, 'utf8');\n } catch {\n /* no file */\n }\n // Use the structured parser so entryCount reflects directive entries, not\n // raw chunks split by `---` (the structured document also uses `---` for\n // section dividers and the footer, which would inflate chunk counts).\n const entries = parseStructuredLearnedEntries(role, projectRoot);\n const exists = existsSync(dir);\n const policy = loadProjectAgentLearningPolicy(role, projectRoot);\n const captureKey = `${path.resolve(projectRoot ?? process.cwd())}\\0${assertProjectAgentRole(role)}`;\n const runtimeLastTs = captureCooldowns.get(captureKey) ?? null;\n const persistedLastTs = policy.lastCaptureAt ? Date.parse(policy.lastCaptureAt) : Number.NaN;\n const lastTs = runtimeLastTs ?? (Number.isFinite(persistedLastTs) ? persistedLastTs : null);\n const cooldownRemaining = lastTs ? Math.max(0, CAPTURE_COOLDOWN_MS - (Date.now() - lastTs)) : 0;\n const freq = captureFrequency.get(captureKey) ?? 0;\n\n return {\n role,\n exists,\n entryCount: entries.length,\n totalBytes: Buffer.byteLength(learnedText, 'utf8'),\n lastCapture: lastTs ? new Date(lastTs).toISOString() : null,\n lastCaptureTimestamp: lastTs,\n cooldownRemainingMs: cooldownRemaining,\n sessionCaptureCount: freq,\n needsSummarization: exists\n ? hintLearnedNeedsSummarization(role, projectRoot).length > 0\n : false,\n learnedPath: existsSync(learnedPath_) ? learnedPath_ : null,\n identityPath: existsSync(identityPath_) ? identityPath_ : null,\n hasIdentity: existsSync(identityPath_),\n hasConfig: existsSync(configPath_),\n hasKnowledge: existsSync(knowledgePath_),\n learningEnabled: policy.enabled,\n lifetimeCaptureCount: policy.lifetimeCaptureCount,\n lastCaptureSource: policy.lastCaptureSource ?? null,\n isConsolidated: isConsolidated(role, projectRoot),\n consolidation: loadConsolidationMetadata(role, projectRoot),\n };\n}\n\n/**\n * Re-export existsSync so callers can check file existence without importing fs.\n */\nexport { existsSync };\n\n/**\n * Detect semantic conflicts between different roles' learned wisdom.\n * Returns entries where token overlap \u2265 0.60, which suggests the two\n * roles have learned about the same topic \u2014 potentially contradicting.\n */\nexport function detectLearnedConflicts(projectRoot?: string): Array<{\n roleA: string;\n roleB: string;\n snippetA: string;\n snippetB: string;\n similarity: number;\n detectedAt: string;\n}> {\n const roles = listProjectAgentRoles(projectRoot);\n const entries: { role: string; normalized: string; raw: string }[] = [];\n for (const role of roles) {\n const text = loadProjectAgentLearned(role, projectRoot);\n if (!text || text.trim().length < 50) continue;\n entries.push({ role, normalized: normalizeForComparison(text), raw: text });\n }\n const conflicts: Array<{\n roleA: string;\n roleB: string;\n snippetA: string;\n snippetB: string;\n similarity: number;\n detectedAt: string;\n }> = [];\n for (const [i, a] of entries.entries()) {\n for (const b of entries.slice(i + 1)) {\n const sim = tokenOverlap(a.normalized, b.normalized);\n if (sim >= 0.6) {\n conflicts.push({\n roleA: a.role,\n roleB: b.role,\n snippetA: a.raw.slice(0, 200),\n snippetB: b.raw.slice(0, 200),\n similarity: sim,\n detectedAt: new Date().toISOString(),\n });\n }\n }\n }\n return conflicts.sort((a, b) => b.similarity - a.similarity);\n}\n\nexport function listProjectAgentLearnedEntries(role: string, projectRoot?: string): string[] {\n return splitLearnedEntries(loadProjectAgentLearned(role, projectRoot));\n}\n\n// ---------------------------------------------------------------------------\n// Structured instruction list\n//\n// Each `learned.md` capture now produces a structured instruction list rather\n// than an append-only journal. Every entry is decomposed into a \"what / why /\n// how\" shape so a future agent invocation can read the buffer and immediately\n// understand the rule, the reason behind it, and the concrete steps to apply\n// it. The buffer is rewritten in this structured form on every capture, with\n// historical entries re-decomposed in lockstep so the file stays\n// self-describing and scannable across the lifetime of the role.\n// ---------------------------------------------------------------------------\n\nexport function parseStructuredLearnedEntries(\n role: string,\n projectRoot?: string,\n): StructuredLearnedEntry[] {\n const raw = loadProjectAgentLearned(role, projectRoot);\n return parseStructuredLearnedEntriesFromContent(\n raw,\n listProjectAgentLearnedEntries(role, projectRoot),\n );\n}\n\n/**\n * Learned-wisdom capture from agent output.\n *\n * Scans `output` for `## LEARNED` blocks and persists each unique,\n * quality-passing block to the role's `learned.md`. Each block is run\n * through `normalizeLearnedEntry` so the buffer only accumulates instructive\n * directives \u2014 narrative session logs are rejected at capture time. Near-\n * duplicate entries (token overlap \u2265 0.55) are silently skipped.\n *\n * When the resulting file would exceed `LEARNED_HARD_LIMIT` (16 KB)\n * the oldest entries are rotated out before writing.\n *\n * @returns the number of **new** items actually persisted (0 if none).\n */\nexport function captureLearnedFromAgentOutput(\n output: string,\n role: string,\n projectRoot?: string,\n isManual = false,\n): number {\n return captureLearnedFromAgentOutputDetailed(output, role, projectRoot, isManual).captured;\n}\n\nexport function captureLearnedFromAgentOutputDetailed(\n output: string,\n role: string,\n projectRoot?: string,\n isManual = false,\n): LearnedCaptureResult {\n const normalizedRole = assertProjectAgentRole(role);\n if (!output.trim()) {\n return { role: normalizedRole, captured: 0, skipped: 0, status: 'empty_output' };\n }\n const policy = loadProjectAgentLearningPolicy(normalizedRole, projectRoot);\n if (!policy.enabled && !isManual) {\n return {\n role: normalizedRole,\n captured: 0,\n skipped: 0,\n status: 'disabled',\n reason: 'Automatic learning is disabled for this role.',\n };\n }\n\n const regex = /^##\\s*LEARNED\\s*$/gim;\n const candidates: string[] = [];\n let startMatch = regex.exec(output);\n while (startMatch !== null) {\n const blockStart = startMatch.index + startMatch[0].length;\n const rest = output.slice(blockStart);\n const nextHeading = /^##\\s/gm.exec(rest);\n const blockEnd = nextHeading ? blockStart + nextHeading.index : output.length;\n candidates.push(output.slice(blockStart, blockEnd).trim());\n regex.lastIndex = Math.max(regex.lastIndex, blockEnd);\n startMatch = regex.exec(output);\n }\n if (candidates.length === 0) {\n return { role: normalizedRole, captured: 0, skipped: 0, status: 'no_blocks' };\n }\n\n const existingRaw = loadProjectAgentLearned(normalizedRole, projectRoot);\n const guard = canCaptureNewLearned(\n normalizedRole,\n Buffer.byteLength(existingRaw, 'utf8'),\n isManual,\n projectRoot,\n );\n if (guard) {\n return {\n role: normalizedRole,\n captured: 0,\n skipped: candidates.length,\n status: 'guarded',\n reason: guard,\n };\n }\n\n // Dedup against existing structured entries' directive keys so the\n // capture loop can reject near-duplicates using the same normalization\n // the structured renderer applies. This replaces the old chunked-text\n // dedup path which could not see through the structured document format.\n const normalizedEntries = parseStructuredLearnedEntries(normalizedRole, projectRoot).map(\n (entry) => entry.key,\n );\n let structuredEntries = parseStructuredLearnedEntries(normalizedRole, projectRoot);\n let captured = 0;\n let skipped = 0;\n const now = new Date();\n const nowIso = now.toISOString();\n const remainingSessionCaptures = isManual\n ? Number.POSITIVE_INFINITY\n : Math.max(\n 0,\n CAPTURE_MAX_PER_SESSION -\n (captureFrequency.get(\n `${path.resolve(projectRoot ?? process.cwd())}\\0${normalizedRole}`,\n ) ?? 0),\n );\n\n for (const content of candidates) {\n if (captured >= remainingSessionCaptures) {\n skipped++;\n continue;\n }\n // Run normalization FIRST: strip ephemeral artifacts, drop narrative\n // framing, classify, and reject entries that cannot be salvaged into\n // instructive directives. This is the quality gate that keeps the\n // buffer from accumulating session logs.\n const normalized = normalizeLearnedEntry(content);\n if (!normalized) {\n skipped++;\n continue;\n }\n // Code-only check: rejects entries that are mostly fenced code even after\n // normalization (the normalizer preserves prose, so a code-only block\n // will already be short on text \u2014 this is a belt-and-braces check).\n const totalLines = Math.max(1, content.split('\\n').length);\n const codeBodyLines = (content.match(/```[\\s\\S]*?```/g) ?? []).reduce(\n (sum, block) => sum + Math.max(0, block.split('\\n').length - 2),\n 0,\n );\n if (totalLines > 5 && codeBodyLines / totalLines > 0.7) {\n skipped++;\n continue;\n }\n const candidateNorm = normalizeForComparison(normalized.text);\n if (normalizedEntries.some((entry) => tokenOverlap(candidateNorm, entry) >= 0.55)) {\n skipped++;\n continue;\n }\n normalizedEntries.push(candidateNorm);\n // Merge the new directive into the structured list, deduplicating against\n // existing entries by content similarity. The buffer is rewritten as a\n // structured instruction list (what / why / how) at the end of this\n // function \u2014 historical entries are re-decomposed in lockstep so the\n // file is always a current, consistent snapshot.\n structuredEntries = mergeStructuredEntries(structuredEntries, {\n text: normalized.text,\n category: normalized.category,\n capturedAt: nowIso,\n });\n captured++;\n }\n\n if (captured === 0) {\n return {\n role: normalizedRole,\n captured: 0,\n skipped,\n status: 'quality_rejected',\n reason:\n 'Every LEARNED block was too short, too narrative, or a near-duplicate. Write directives, not session logs.',\n };\n }\n\n // Render the merged list as a structured instruction document. This is the\n // single source of truth \u2014 the buffer is rewritten in full on every\n // capture so the file always reflects the current, merged state.\n let newContent = renderLearnedInstructions(normalizedRole, structuredEntries, nowIso);\n if (Buffer.byteLength(newContent, 'utf8') >= LEARNED_HARD_LIMIT) {\n // Trim oldest entries when the document exceeds the hard limit. Keep\n // the structured form intact by re-rendering after pruning.\n const trimmed = structuredEntries.slice(-Math.max(1, Math.floor(structuredEntries.length / 2)));\n newContent = renderLearnedInstructions(normalizedRole, trimmed, nowIso);\n }\n\n writeTextAtomically(path.join(roleDir(normalizedRole, projectRoot), 'learned.md'), newContent);\n const captureKey = `${path.resolve(projectRoot ?? process.cwd())}\\0${normalizedRole}`;\n captureCooldowns.set(captureKey, now.getTime());\n // Increment the frequency counter by 1 per capture attempt (not by\n // `captured`, the number of LEARNED blocks appended). Otherwise a single\n // response that yields N blocks immediately exhausts the\n // CAPTURE_MAX_PER_SESSION budget for the rest of the session, while a\n // response that yields 0 blocks consumes nothing \u2014 both diverge from the\n // documented \"attempts per session\" semantics the cap is meant to enforce.\n captureFrequency.set(captureKey, (captureFrequency.get(captureKey) ?? 0) + 1);\n const nextPolicy: ProjectAgentLearningPolicy = {\n ...policy,\n lifetimeCaptureCount: policy.lifetimeCaptureCount + captured,\n lastCaptureAt: now.toISOString(),\n lastCaptureSource: isManual ? 'manual' : 'automatic',\n };\n writeTextAtomically(\n learningPolicyPath(normalizedRole, projectRoot),\n `${JSON.stringify(nextPolicy, null, 2)}\\n`,\n );\n return { role: normalizedRole, captured, skipped, status: 'captured' };\n}\n\n/**\n * Signal the host that a background summarisation pass is warranted.\n * Called by `captureLearnedFromAgentOutput` when the **new** learned size\n * crosses `LEARNED_SOFT_LIMIT`. The host is responsible for scheduling a\n * low-priority consolidation task (typically via the Brain or a shadow agent).\n *\n * The summary _mechanism_ is intentionally shallow here \u2014 the real\n * summarisation is an LLM call that should run as a deferred, uncritical\n * fleet task so it never blocks a user-facing operation.\n *\n * @returns a summary brief for the host, or '' when no action is needed.\n */\nexport function hintLearnedNeedsSummarization(role: string, projectRoot?: string): string {\n const learned = loadProjectAgentLearned(role, projectRoot);\n if (!learned) return '';\n const bytes = Buffer.byteLength(learned, 'utf8');\n if (bytes < LEARNED_SOFT_LIMIT) return '';\n return `Learned wisdom for role \"${role}\" is ${bytes} B (soft limit ${LEARNED_SOFT_LIMIT}). Schedule a low-priority consolidation pass.`;\n}\n\n// ---------------------------------------------------------------------------\n// Consolidation: review raw learned.md \u2192 produce consolidated.md\n// ---------------------------------------------------------------------------\n//\n// The learned.md file is an append-only capture buffer. Over time it grows\n// with verbose, overlapping entries. The consolidation pass reads every raw\n// entry, asks an LLM to synthesize them into a single narrowly-scoped\n// document that represents what the agent has learned for its role, and\n// writes the result to consolidated.md.\n//\n// Once consolidated.md exists, buildProjectContextualizedPrompt prefers it\n// over the raw learned.md \u2014 the raw buffer is retained on disk for audit\n// but no longer injected into prompts (reducing context volume without\n// omitting information, because every fact was carried into the summary).\n//\n// Files (under .wrongstack/agents/<role>/):\n// consolidated.md \u2014 the synthesized, reviewed document\n// consolidation.json \u2014 metadata tracking the last review\n", "import type { RoleKnowledgeManifest } from './project-agent-identity-types.js';\n\nexport const BUILT_IN_KNOWLEDGE_MANIFESTS: Record<string, RoleKnowledgeManifest> = {\n android: {\n role: 'android',\n // Only machine-readable JSON registries belong in liveQueries. Android\n // release/API data has no JSON registry endpoint, so those checks stay as\n // checklist prose below.\n liveQueries: {\n kotlin: {\n registry: 'https://registry.npmjs.org/kotlin/latest',\n key: 'version',\n description: 'Kotlin latest stable',\n },\n },\n checklist: [\n 'Current Android Gradle Plugin version (8.x+)',\n 'Current Kotlin version (2.x+)',\n 'Current compileSdk / targetSdk (\u2265 34, check Play Store policy)',\n 'Current Jetpack Compose stable version',\n 'All third-party dependencies are at latest compatible minor',\n ],\n verifyThreshold: 0.5,\n },\n frontend: {\n role: 'frontend',\n liveQueries: {\n react: {\n registry: 'https://registry.npmjs.org/react/latest',\n key: 'version',\n description: 'React latest stable',\n },\n nextjs: {\n registry: 'https://registry.npmjs.org/next/latest',\n key: 'version',\n description: 'Next.js latest stable',\n },\n },\n checklist: [\n 'Current React version (pinned in package.json)',\n 'Current Next.js / Vite / framework version',\n 'Node.js runtime version (project .nvmrc or engines)',\n 'All devDependencies are at latest compatible versions',\n 'Browser compatibility targets from browserslist',\n ],\n verifyThreshold: 0.5,\n },\n executor: {\n role: 'executor',\n liveQueries: {\n node: {\n registry: 'https://registry.npmjs.org/node/latest',\n key: 'version',\n description: 'Node.js latest release',\n },\n },\n checklist: [\n 'Node.js version from .nvmrc or package.engines',\n 'TypeScript version from package.json',\n 'Package manager (pnpm \u2265 9) from packageManager',\n 'Current toolchain: esbuild, vitest, etc.',\n ],\n verifyThreshold: 0.6,\n },\n};\n", "import { readFileSync } from 'node:fs';\nimport {\n learningPolicyPath,\n writeTextAtomically,\n} from './project-agent-paths.js';\n\n/** Persistent controls and counters for one roster role's learning loop. */\nexport interface ProjectAgentLearningPolicy {\n /** Retain knowledge but stop prompt injection and automatic capture when false. */\n enabled: boolean;\n lifetimeCaptureCount: number;\n lastCaptureAt?: string | undefined;\n lastCaptureSource?: 'automatic' | 'manual' | 'taught' | undefined;\n}\n\nconst DEFAULT_LEARNING_POLICY: ProjectAgentLearningPolicy = {\n enabled: true,\n lifetimeCaptureCount: 0,\n};\n\nexport function loadProjectAgentLearningPolicy(\n role: string,\n projectRoot?: string,\n): ProjectAgentLearningPolicy {\n try {\n const parsed = JSON.parse(\n readFileSync(learningPolicyPath(role, projectRoot), 'utf8'),\n ) as Partial<ProjectAgentLearningPolicy>;\n return {\n enabled: parsed.enabled !== false,\n lifetimeCaptureCount:\n typeof parsed.lifetimeCaptureCount === 'number' &&\n Number.isInteger(parsed.lifetimeCaptureCount) &&\n parsed.lifetimeCaptureCount >= 0\n ? parsed.lifetimeCaptureCount\n : 0,\n ...(typeof parsed.lastCaptureAt === 'string' ? { lastCaptureAt: parsed.lastCaptureAt } : {}),\n ...(parsed.lastCaptureSource === 'automatic' ||\n parsed.lastCaptureSource === 'manual' ||\n parsed.lastCaptureSource === 'taught'\n ? { lastCaptureSource: parsed.lastCaptureSource }\n : {}),\n };\n } catch {\n return { ...DEFAULT_LEARNING_POLICY };\n }\n}\n\nexport function updateProjectAgentLearningPolicy(\n role: string,\n patch: Partial<Pick<ProjectAgentLearningPolicy, 'enabled'>>,\n projectRoot?: string,\n): ProjectAgentLearningPolicy {\n const current = loadProjectAgentLearningPolicy(role, projectRoot);\n const updated = {\n ...current,\n ...(patch.enabled !== undefined ? { enabled: patch.enabled } : {}),\n };\n writeTextAtomically(\n learningPolicyPath(role, projectRoot),\n `${JSON.stringify(updated, null, 2)}\\n`,\n );\n return updated;\n}\n", "import { randomUUID } from 'node:crypto';\nimport { mkdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';\nimport * as path from 'node:path';\n\nconst AGENT_ROLE_PATTERN = /^[a-z0-9][a-z0-9._-]{0,95}$/i;\n\nexport function assertProjectAgentRole(role: string): string {\n const normalized = role.trim();\n if (\n !AGENT_ROLE_PATTERN.test(normalized) ||\n normalized === '.' ||\n normalized === '..' ||\n normalized.includes('/') ||\n normalized.includes('\\\\')\n ) {\n throw new Error(`Invalid project agent role: \"${role}\".`);\n }\n return normalized;\n}\n\nexport function isProjectAgentRoleName(name: string): boolean {\n return AGENT_ROLE_PATTERN.test(name) && name !== '.' && name !== '..';\n}\n\nexport function agentsDir(projectRoot?: string): string {\n const root = projectRoot ?? process.cwd();\n return path.join(root, '.wrongstack', 'agents');\n}\n\nexport function roleDir(role: string, projectRoot?: string): string {\n return path.join(agentsDir(projectRoot), assertProjectAgentRole(role));\n}\n\nexport function writeTextAtomically(filePath: string, content: string): void {\n mkdirSync(path.dirname(filePath), { recursive: true });\n const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;\n try {\n writeFileSync(temporaryPath, content, 'utf8');\n renameSync(temporaryPath, filePath);\n } finally {\n try {\n rmSync(temporaryPath, { force: true });\n } catch {\n // Best-effort cleanup after a failed rename.\n }\n }\n}\n\nexport function learningPolicyPath(role: string, projectRoot?: string): string {\n return path.join(roleDir(role, projectRoot), 'learning.json');\n}\n\nexport function projectAgentProfilePath(role: string, projectRoot?: string): string {\n return path.join(roleDir(role, projectRoot), 'profile.json');\n}\n", "/**\n * Return the Jaccard similarity (0-1) of two normalised token sets.\n */\nexport function tokenOverlap(a: string, b: string): number {\n const setA = new Set(a.split(/\\s+/));\n const setB = new Set(b.split(/\\s+/));\n const intersect = new Set([...setA].filter((t) => setB.has(t)));\n const union = new Set([...setA, ...setB]);\n return union.size === 0 ? 0 : intersect.size / union.size;\n}\n\n/**\n * Split an existing learned.md body into individual entries.\n * Entries are delimited by `---\\n\\n` sequences.\n */\nexport function splitLearnedEntries(body: string): string[] {\n return body\n .split(/\\n---\\n+/)\n .map((entry) => entry.trim())\n .map((entry) =>\n entry\n .replace(/^# Learned wisdom for .+$/im, '')\n .replace(/<!--[\\s\\S]*?-->/g, '')\n .trim(),\n )\n .filter(Boolean);\n}\n", "import {\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n} from 'node:fs';\nimport * as path from 'node:path';\nimport { splitLearnedEntries } from './project-agent-learning-entries.js';\nimport { assertProjectAgentRole, roleDir, writeTextAtomically } from './project-agent-paths.js';\n\nexport interface ConsolidationMetadata {\n /** ISO timestamp of the last consolidation. */\n consolidatedAt: string;\n /** Number of raw learned.md entries that were synthesized. */\n sourceEntryCount: number;\n /** Byte size of the raw learned.md at consolidation time. */\n sourceBytes: number;\n /** Byte size of the resulting consolidated.md. */\n consolidatedBytes: number;\n /** Whether the consolidation was user-triggered or automatic. */\n trigger: 'manual' | 'automatic';\n /** Optional model that produced the consolidation. */\n model?: string | undefined;\n}\n\nfunction learnedPath(role: string, projectRoot?: string): string {\n return path.join(roleDir(role, projectRoot), 'learned.md');\n}\n\nfunction loadProjectAgentLearnedText(role: string, projectRoot?: string): string {\n try {\n return readFileSync(learnedPath(role, projectRoot), 'utf8').trim();\n } catch {\n return '';\n }\n}\n\nfunction listProjectAgentLearnedTextEntries(role: string, projectRoot?: string): string[] {\n return splitLearnedEntries(loadProjectAgentLearnedText(role, projectRoot));\n}\n\nfunction consolidationPath(role: string, projectRoot?: string): string {\n return path.join(roleDir(role, projectRoot), 'consolidated.md');\n}\n\nfunction consolidationMetaPath(role: string, projectRoot?: string): string {\n return path.join(roleDir(role, projectRoot), 'consolidation.json');\n}\n\nexport function loadProjectAgentConsolidated(role: string, projectRoot?: string): string {\n try {\n return readFileSync(consolidationPath(role, projectRoot), 'utf8').trim();\n } catch {\n return '';\n }\n}\n\nexport function loadConsolidationMetadata(\n role: string,\n projectRoot?: string,\n): ConsolidationMetadata | undefined {\n try {\n const raw = readFileSync(consolidationMetaPath(role, projectRoot), 'utf8');\n const parsed = JSON.parse(raw) as unknown;\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n typeof (parsed as ConsolidationMetadata).consolidatedAt === 'string' &&\n typeof (parsed as ConsolidationMetadata).sourceEntryCount === 'number'\n ) {\n return parsed as ConsolidationMetadata;\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function isConsolidated(role: string, projectRoot?: string): boolean {\n return existsSync(consolidationMetaPath(role, projectRoot));\n}\n\nexport function saveProjectAgentConsolidated(\n role: string,\n content: string,\n projectRoot?: string,\n metadata?: Partial<ConsolidationMetadata>,\n): string {\n if (!content.trim()) {\n return consolidationPath(assertProjectAgentRole(role), projectRoot);\n }\n const normalizedRole = assertProjectAgentRole(role);\n const dir = roleDir(normalizedRole, projectRoot);\n mkdirSync(dir, { recursive: true });\n const fp = consolidationPath(normalizedRole, projectRoot);\n writeTextAtomically(fp, content);\n\n const rawEntries = listProjectAgentLearnedTextEntries(normalizedRole, projectRoot);\n const rawBytes = Buffer.byteLength(loadProjectAgentLearnedText(normalizedRole, projectRoot), 'utf8');\n const meta: ConsolidationMetadata = {\n consolidatedAt: new Date().toISOString(),\n sourceEntryCount: rawEntries.length,\n sourceBytes: rawBytes,\n consolidatedBytes: Buffer.byteLength(content, 'utf8'),\n trigger: metadata?.trigger ?? 'manual',\n ...(metadata?.model ? { model: metadata.model } : {}),\n };\n writeTextAtomically(\n consolidationMetaPath(normalizedRole, projectRoot),\n `${JSON.stringify(meta, null, 2)}\\n`,\n );\n return fp;\n}\n\nexport function clearProjectAgentConsolidated(role: string, projectRoot?: string): void {\n const normalizedRole = assertProjectAgentRole(role);\n for (const file of [\n consolidationPath(normalizedRole, projectRoot),\n consolidationMetaPath(normalizedRole, projectRoot),\n ]) {\n try {\n rmSync(file, { force: true });\n } catch {\n // already absent\n }\n }\n}\n\nexport function buildConsolidationInstruction(\n role: string,\n projectRoot?: string,\n): {\n instruction: string;\n rawEntries: string[];\n hasExistingConsolidation: boolean;\n} {\n const normalizedRole = assertProjectAgentRole(role);\n const rawEntries = listProjectAgentLearnedTextEntries(normalizedRole, projectRoot);\n const existingConsolidation = loadProjectAgentConsolidated(normalizedRole, projectRoot);\n const rawBody = rawEntries.map((entry, i) => `### Entry ${i + 1}\\n\\n${entry}`).join('\\n\\n');\n\n const sections: string[] = [\n `You are reviewing and consolidating the captured learning entries for the \"${normalizedRole}\" agent role in this project.`,\n '',\n 'Your task is to synthesize the raw entries below into a single, narrowly-scoped document that represents what this agent has learned \u2014 specifically for its skills and role responsibilities. This document is the **instruction manual for future invocations** of this agent in this project. It is not a journal, not an exhaustive transcription, and not a memory store.',\n '',\n '## Requirements',\n '',\n '1. **Be selective.** Some raw entries are noise \u2014 narrative descriptions of single-session events, ephemeral references (commit SHAs, timestamps, line numbers, PR refs), or thin fragments that cannot be generalized. **Drop them.** The output must be smaller than the input; a consolidation that preserves every word is not a consolidation.',\n '2. **Extract the directive.** When a raw entry mixes narrative framing with a buried lesson (\"When I worked on X, I realized Y\"), extract the lesson as a directive and discard the framing.',\n '3. **Generic, not specific.** Rewrite entries so they apply across sessions. Replace session-specific anchors (commit SHAs, dates, line numbers) with general principles or concrete tools/commands that will still be valid next month.',\n '4. **Self-contained bullets.** Each bullet must make sense standalone \u2014 understandable to a future agent that has no context about the session that produced it.',\n '5. **Narrow scope.** Keep only knowledge that is genuinely durable and role-relevant. When in doubt, leave it out.',\n '6. **Structured format.** Organize the content under clear markdown headings (##) by topic. Use bullet points for individual facts. Group by category (Conventions, Patterns, Warnings, Project Facts) when it helps scannability.',\n '7. **Preserve actionable anchors.** Keep exact file paths, command names, package names, and configuration values that make a directive concrete and runnable.',\n '8. **No filler.** Do not include meta-commentary about the consolidation process. The document should read as if it were always a single authoritative reference.',\n '',\n rawEntries.length > 0\n ? `## Raw learned entries (${rawEntries.length} total)\\n\\n${rawBody}`\n : '## Raw learned entries\\n\\n(No raw entries yet \u2014 return an empty document.)',\n ];\n\n if (existingConsolidation) {\n sections.push(\n '',\n `## Existing consolidated document (for reference \u2014 improve upon it)\\n\\n${existingConsolidation}`,\n );\n }\n\n sections.push(\n '',\n '## Output',\n '',\n 'Return ONLY the consolidated markdown document. Do not wrap it in code fences or add commentary.',\n );\n\n return {\n instruction: sections.join('\\n'),\n rawEntries,\n hasExistingConsolidation: Boolean(existingConsolidation),\n };\n}\n", "import { type AgentDefinition, LIGHT_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 1 \u00B7 Discovery \u2014 map the territory before any work begins. */\nexport const DISCOVERY_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'explore',\n name: 'Explore',\n role: 'explore',\n tools: [...TOOLS.read],\n prompt: agentPrompt('explore'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'discovery',\n summary: 'Maps unfamiliar codebases: entry points, structure, architecture, feature flow (read-only).',\n keywords: [\n 'explore',\n 'map',\n 'understand',\n 'where is',\n 'how does',\n 'codebase',\n 'architecture',\n 'structure',\n 'overview',\n 'find file',\n 'entry point',\n 'orient',\n ],\n },\n },\n {\n config: {\n id: 'search',\n name: 'Search',\n role: 'search',\n tools: [...TOOLS.read],\n prompt: agentPrompt('search'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'discovery',\n summary: 'Semantic + lexical code search across repos; finds definitions, references, duplicates, ranks by relevance.',\n keywords: [\n 'search',\n 'find all',\n 'references',\n 'usages',\n 'call sites',\n 'grep',\n 'locate symbol',\n 'duplicate',\n 'where used',\n 'occurrences',\n 'cross-repo',\n ],\n },\n },\n {\n config: {\n id: 'research',\n name: 'Research',\n role: 'research',\n tools: [...TOOLS.research],\n prompt: agentPrompt('research'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'discovery',\n summary: 'Technical research and feasibility: compares libraries/approaches, recommends a path with evidence and tradeoffs.',\n keywords: [\n 'research',\n 'feasibility',\n 'compare libraries',\n 'which library',\n 'best practice',\n 'tradeoff',\n 'investigate',\n 'evaluate approach',\n 'should we use',\n 'pros and cons',\n ],\n },\n },\n];\n", "import { type AgentDefinition, HEAVY_BUDGET, LIGHT_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\nconst PLAN_TOOLS = [...TOOLS.read, 'plan', 'todo'];\n\n/** Phase 2 \u00B7 Planning \u2014 turn intent into requirements, plans, and architecture. */\nexport const PLANNING_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'analyst',\n name: 'Analyst',\n role: 'analyst',\n tools: [...PLAN_TOOLS],\n prompt: agentPrompt('analyst'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Requirement analysis: turns vague requests into testable specs with acceptance criteria and open questions.',\n keywords: [\n 'requirements',\n 'analyze requirement',\n 'acceptance criteria',\n 'spec',\n 'specification',\n 'clarify',\n 'scope',\n 'user story',\n 'what should it do',\n ],\n },\n },\n {\n config: {\n id: 'planner',\n name: 'Planner',\n role: 'planner',\n tools: [...PLAN_TOOLS],\n prompt: agentPrompt('planner'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Execution planning: decomposes a goal into ordered, dependency-aware, parallelizable steps with checkpoints.',\n keywords: [\n 'plan',\n 'execution plan',\n 'break down',\n 'decompose',\n 'steps',\n 'sequence',\n 'roadmap',\n 'task breakdown',\n 'order of work',\n 'milestones',\n ],\n },\n },\n {\n config: {\n id: 'architect',\n name: 'Architect',\n role: 'architect',\n tools: [...PLAN_TOOLS],\n prompt: agentPrompt('architect'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'System architecture: designs module boundaries, interfaces, data flow, and records key decisions.',\n keywords: [\n 'architecture',\n 'design system',\n 'module boundaries',\n 'interfaces',\n 'data flow',\n 'component design',\n 'system design',\n 'decision record',\n 'adr',\n 'structure the',\n ],\n },\n },\n {\n config: {\n id: 'critic',\n name: 'Critic',\n role: 'critic',\n tools: [...TOOLS.read],\n prompt: agentPrompt('critic'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Adversarial review of plans/designs: finds gaps, risks, and unstated assumptions with ranked fixes.',\n keywords: [\n 'critique',\n 'review plan',\n 'review design',\n 'red team',\n 'poke holes',\n 'risks',\n 'what could go wrong',\n 'second opinion',\n 'challenge',\n 'flaws',\n ],\n },\n },\n {\n config: {\n id: 'refactor-planner',\n name: 'Refactor Planner',\n role: 'refactor-planner',\n tools: [...PLAN_TOOLS, 'diff'],\n prompt: agentPrompt('refactor-planner'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Refactoring planner: analyzes code structure, maps dependencies, produces risk-scored phased plans with rollback strategy.',\n keywords: [\n 'refactor',\n 'refactoring',\n 'restructure',\n 'debt',\n 'technical debt',\n 'clean up',\n 'modularize',\n 'decouple',\n 'dependency graph',\n 'code structure',\n ],\n },\n },\n];\n", "import { type AgentDefinition, HEAVY_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 3 \u00B7 Build \u2014 write, refactor, migrate, and fix code. */\nexport const BUILD_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'executor',\n name: 'Executor',\n role: 'executor',\n tools: [...TOOLS.build],\n prompt: agentPrompt('executor'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Implements well-specified tasks: writes code, runs checks, leaves the tree green.',\n keywords: [\n 'implement',\n 'build',\n 'write code',\n 'add feature',\n 'create',\n 'code up',\n 'develop',\n 'apply change',\n 'make it work',\n ],\n },\n },\n {\n config: {\n id: 'refactor',\n name: 'Refactor',\n role: 'refactor',\n tools: [...TOOLS.build],\n prompt: agentPrompt('refactor'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Structural refactoring: extract/split/move/rename/decouple without changing observable behavior.',\n keywords: [\n 'refactor',\n 'restructure',\n 'extract',\n 'split module',\n 'decouple',\n 'rename',\n 'move code',\n 'break dependency',\n 'reorganize',\n ],\n },\n },\n {\n config: {\n id: 'simplifier',\n name: 'Simplifier',\n role: 'simplifier',\n tools: [...TOOLS.build],\n prompt: agentPrompt('simplifier'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Reduces complexity: deletes dead code, collapses needless abstractions, shortens and clarifies code.',\n keywords: [\n 'simplify',\n 'dead code',\n 'remove unused',\n 'reduce complexity',\n 'clean up',\n 'denest',\n 'shorten',\n 'over-engineered',\n 'too complex',\n ],\n },\n },\n {\n config: {\n id: 'migration',\n name: 'Migration',\n role: 'migration',\n tools: [...TOOLS.build, 'install', 'outdated'],\n prompt: agentPrompt('migration'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Framework/language/version upgrades: applies codemods across call sites, staged and verified.',\n keywords: [\n 'migrate',\n 'upgrade',\n 'codemod',\n 'breaking change',\n 'major version',\n 'port to',\n 'convert to',\n 'esm',\n 'modernize',\n ],\n },\n },\n {\n config: {\n id: 'vision',\n name: 'Vision',\n role: 'vision',\n tools: [...TOOLS.write, 'fetch'],\n prompt: agentPrompt('vision'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Screenshot/mockup \u2192 UI code: infers component tree and generates matching, accessible markup.',\n keywords: [\n 'screenshot',\n 'mockup',\n 'design to code',\n 'image to ui',\n 'figma',\n 'replicate this ui',\n 'from this picture',\n 'vision',\n 'clone ui',\n ],\n },\n },\n {\n config: {\n id: 'debugger',\n name: 'Debugger',\n role: 'debugger',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('debugger'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Root-cause bug fixing: reproduces, bisects to the true cause, applies a minimal fix with a regression test.',\n keywords: [\n 'bug',\n 'fix',\n 'debug',\n 'broken',\n 'error',\n 'crash',\n 'root cause',\n 'not working',\n 'failing',\n 'reproduce',\n 'why does',\n ],\n },\n },\n {\n config: {\n id: 'tracer',\n name: 'Tracer',\n role: 'tracer',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('tracer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Runtime tracing: instruments and runs code to observe call order, values, and timing, then cleans up.',\n keywords: [\n 'trace',\n 'runtime',\n 'instrument',\n 'execution path',\n 'what happens at runtime',\n 'call order',\n 'profile execution',\n 'observe behavior',\n 'stack trace',\n ],\n },\n },\n];\n", "import { agentPrompt } from './agent-prompts.js';\nimport type { BundledAgentSkill } from './role-skills.js';\nimport {\n type AgentDefinition,\n type RoleDispatcherSignal,\n HEAVY_BUDGET,\n MEDIUM_BUDGET,\n TOOLS,\n} from './types.js';\n\n\nconst skillSet = (...names: BundledAgentSkill[]): BundledAgentSkill[] => names;\n\nvoid skillSet;\n\n/**\n * Wave 1: Platform and systems engineering.\n *\n * Six new specialist roles sit alongside the existing build/domain/verify\n * phases. Each carries an explicit `RoleDispatcherSignal` so the dispatcher\n * can tell it apart from siblings that share vocabulary.\n */\n\nconst ANDROID_META = {\n rationale:\n 'Android platform specialist: Kotlin, Jetpack Compose, Android SDK and Play Store delivery. Mirrors the iOS role on the Android side of the mobile fence.',\n signals: [\n 'android',\n 'kotlin',\n 'jetpack compose',\n 'compose',\n 'android sdk',\n 'gradle',\n 'play store',\n 'aosp',\n ] as const,\n differentiatesFrom:\n 'frontend builds cross-platform UI; android owns the Android-specific lifecycle, framework and platform APIs.',\n} satisfies RoleDispatcherSignal;\n\nconst DESKTOP_META = {\n rationale:\n 'Desktop application specialist: Electron, Tauri, native packaging, IPC and OS integration. Owns the process/IPC boundary that web-only roles ignore.',\n signals: [\n 'desktop',\n 'electron',\n 'tauri',\n 'ipc',\n 'tray',\n 'native packaging',\n 'sandbox',\n 'os integration',\n ] as const,\n differentiatesFrom:\n 'frontend assumes a single browser tab; desktop owns the multi-process / IPC / OS-level boundaries.',\n} satisfies RoleDispatcherSignal;\n\nconst REALTIME_META = {\n rationale:\n 'Realtime transport specialist: WebSocket, SSE, presence, heartbeat, reconnect and backpressure. Owns long-lived connection state and lifecycle.',\n signals: [\n 'realtime',\n 'websocket',\n 'sse',\n 'server-sent events',\n 'presence',\n 'heartbeat',\n 'backpressure',\n 'reconnect',\n ] as const,\n differentiatesFrom:\n 'api designs request/response contracts; realtime designs long-lived connections and presence semantics.',\n} satisfies RoleDispatcherSignal;\n\nconst DISTRIBUTED_SYSTEMS_META = {\n rationale:\n 'Distributed-systems engineer: consistency, partitioning, idempotency, saga and distributed coordination. Implementation-level specialist; architect designs the surface, distributed-systems implements the failure semantics.',\n signals: [\n 'distributed systems',\n 'consensus',\n 'saga',\n 'idempotency',\n 'partition',\n 'eventual consistency',\n 'leader election',\n 'replication',\n ] as const,\n differentiatesFrom:\n 'architect designs the system surface; distributed-systems implements the failure semantics and coordination protocols.',\n} satisfies RoleDispatcherSignal;\n\nconst CONCURRENCY_META = {\n rationale:\n 'Concurrency engineer: race conditions, locks, worker pools, async lifecycle and shared-state safety. Focused practitioner; debugger diagnoses, concurrency designs.',\n signals: [\n 'concurrency',\n 'race condition',\n 'deadlock',\n 'worker pool',\n 'lock',\n 'mutex',\n 'async lifecycle',\n 'shared state',\n ] as const,\n differentiatesFrom:\n 'debugger diagnoses concurrency incidents; concurrency designs shared-state systems to avoid them in the first place.',\n} satisfies RoleDispatcherSignal;\n\nconst PLATFORM_ENGINEER_META = {\n rationale:\n 'Platform engineer: monorepo, build graph, internal tooling and developer experience. The \"DX half\" of CI/CD, separate from devops which owns deployment.',\n signals: [\n 'platform',\n 'monorepo',\n 'build graph',\n 'developer experience',\n 'developer tooling',\n 'scaffolding',\n 'workspace',\n ] as const,\n differentiatesFrom:\n 'devops owns deploy/operate; platform-engineer owns the internal developer surface that ships the code.',\n} satisfies RoleDispatcherSignal;\n\nexport const WAVE1_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'android',\n name: 'Android',\n role: 'android',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('android'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Android platform specialist: Kotlin, Jetpack Compose, Android SDK, lifecycle and Play Store delivery.',\n keywords: [\n ...ANDROID_META.signals,\n 'android',\n 'kotlin',\n 'compose',\n 'gradle',\n 'playstore',\n ],\n },\n },\n {\n config: {\n id: 'desktop',\n name: 'Desktop',\n role: 'desktop',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('desktop'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Desktop application specialist: Electron or Tauri, native packaging, IPC and OS integration.',\n keywords: [\n ...DESKTOP_META.signals,\n 'desktop',\n 'electron',\n 'tauri',\n 'ipc',\n 'tray',\n ],\n },\n },\n {\n config: {\n id: 'realtime',\n name: 'Realtime',\n role: 'realtime',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('realtime'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Realtime transport specialist: WebSocket, SSE, presence, heartbeat, reconnect and backpressure.',\n keywords: [\n ...REALTIME_META.signals,\n 'realtime',\n 'websocket',\n 'sse',\n 'presence',\n 'heartbeat',\n 'reconnect',\n ],\n },\n },\n {\n config: {\n id: 'distributed-systems',\n name: 'Distributed Systems',\n role: 'distributed-systems',\n tools: [...TOOLS.inspect, 'plan', 'test'],\n prompt: agentPrompt('distributed-systems'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Distributed-systems engineer: consistency, partitioning, idempotency, saga and coordination at the implementation level.',\n keywords: [\n ...DISTRIBUTED_SYSTEMS_META.signals,\n 'distributed-systems',\n 'consensus',\n 'saga',\n 'idempotency',\n 'partition',\n 'leader-election',\n ],\n },\n },\n {\n config: {\n id: 'concurrency',\n name: 'Concurrency',\n role: 'concurrency',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('concurrency'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary:\n 'Concurrency engineer: race conditions, locks, worker pools, async lifecycle and shared-state safety.',\n keywords: [\n ...CONCURRENCY_META.signals,\n 'concurrency',\n 'race',\n 'deadlock',\n 'worker-pool',\n 'lock',\n ],\n },\n },\n {\n config: {\n id: 'platform-engineer',\n name: 'Platform Engineer',\n role: 'platform-engineer',\n tools: [...TOOLS.build, 'install', 'git', 'node-modern'],\n prompt: agentPrompt('platform-engineer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary:\n 'Platform engineer: monorepo, build graph, internal tooling and developer experience.',\n keywords: [\n ...PLATFORM_ENGINEER_META.signals,\n 'platform',\n 'monorepo',\n 'build-graph',\n 'dx',\n 'scaffolding',\n 'workspace',\n ],\n },\n },\n];\n\nexport const WAVE1_ROLE_METAS: Record<string, RoleDispatcherSignal> = {\n android: ANDROID_META,\n desktop: DESKTOP_META,\n realtime: REALTIME_META,\n 'distributed-systems': DISTRIBUTED_SYSTEMS_META,\n concurrency: CONCURRENCY_META,\n 'platform-engineer': PLATFORM_ENGINEER_META,\n};\n\nexport const WAVE1_ROLES = new Set<string>(Object.keys(WAVE1_ROLE_METAS));\n", "import { agentPrompt } from './agent-prompts.js';\nimport type { BundledAgentSkill } from './role-skills.js';\nimport {\n type AgentDefinition,\n type RoleDispatcherSignal,\n LIGHT_BUDGET,\n MEDIUM_BUDGET,\n TOOLS,\n} from './types.js';\n\nconst skillSet = (...names: BundledAgentSkill[]): BundledAgentSkill[] => names;\n\n/**\n * Wave 2: Security, resilience, governance and agent platform.\n *\n * These roles extend the existing 51-role phase catalog with focused\n * specialists. Each role carries an `agentMeta` block so the dispatcher\n * can distinguish it from siblings via an explicit rationale and signal\n * list. The legacy `keywords` array is kept for backward compatibility\n * with the heuristic dispatcher.\n */\n\nconst THREAT_MODELER_META = {\n rationale:\n 'Models trust boundaries, abuse cases and data flow before code is written; threat-modeler is the pre-implementation counterpart to security-reviewer.',\n signals: [\n 'threat model',\n 'trust boundary',\n 'abuse case',\n 'attack tree',\n 'data flow diagram',\n 'stride',\n 'asset',\n 'adversary',\n ] as const,\n differentiatesFrom:\n 'security-reviewer finds defects in code; threat-modeler designs the threat surface before code exists.',\n};\n\nconst SECURE_CODING_COACH_META = {\n rationale:\n 'Teaches secure patterns, produces safe defaults and walks engineers through fixes; secure-coding-coach is the counterpart to security-scanner that drives adoption.',\n signals: [\n 'secure coding',\n 'secure default',\n 'hardening',\n 'security example',\n 'security review',\n 'security fix',\n 'defensive',\n 'owasp',\n ] as const,\n differentiatesFrom:\n 'security-scanner detects issues; secure-coding-coach produces prescriptive safe-by-default code and guidance.',\n};\n\nconst RESILIENCE_ENGINEER_META = {\n rationale:\n 'Designs retry, timeout, circuit breaker and graceful-degradation patterns; resilience-engineer is the protective counterpart to chaos.',\n signals: [\n 'retry',\n 'timeout',\n 'circuit breaker',\n 'bulkhead',\n 'graceful degradation',\n 'backoff',\n 'resilience',\n 'fault tolerance',\n ] as const,\n differentiatesFrom:\n 'chaos injects faults to test existing code; resilience-engineer designs the protective mechanisms ahead of time.',\n};\n\nconst CHAOS_ENGINEER_META = {\n rationale:\n 'Builds the controlled fault-injection harness and blast-radius discipline; chaos-engineer is the operator counterpart to the chaos reviewer.',\n signals: [\n 'chaos experiment',\n 'fault injection',\n 'blast radius',\n 'gameday',\n 'steady state',\n 'hypothesis',\n 'explosion radius',\n ] as const,\n differentiatesFrom:\n 'chaos verifies fault behavior; chaos-engineer designs the experiments and runs them safely.',\n};\n\nconst COMPLIANCE_AUDITOR_META = {\n rationale:\n 'Produces auditable control evidence, traceability and evidence maps; compliance-auditor is the documenter counterpart to compliance.',\n signals: [\n 'audit',\n 'control evidence',\n 'evidence map',\n 'soc2',\n 'iso 27001',\n 'attestation',\n 'auditable',\n 'remediation tracking',\n ] as const,\n differentiatesFrom:\n 'compliance reviews the design; compliance-auditor produces traceable evidence for an external audit.',\n};\n\nconst PRIVACY_ENGINEER_META = {\n rationale:\n 'Implements data minimization, consent, retention and deletion; privacy-engineer is the implementation counterpart to compliance.',\n signals: [\n 'privacy',\n 'pii',\n 'consent',\n 'retention',\n 'deletion',\n 'data minimization',\n 'lawful basis',\n 'gdpr',\n ] as const,\n differentiatesFrom:\n 'compliance audits controls; privacy-engineer implements privacy-by-design in code and pipelines.',\n};\n\nconst PLUGIN_AUTHOR_META = {\n rationale:\n 'Builds, packages and ships runnable WrongStack plugins; plugin-author is the production counterpart to skill-manage.',\n signals: [\n 'plugin',\n 'plugin api',\n 'lifecycle',\n 'health',\n 'teardown',\n 'packaging',\n 'distribution',\n ] as const,\n differentiatesFrom:\n 'skill-manage authors skills; plugin-author authors full lifecycle plugins with health and teardown.',\n};\n\nconst TOOL_AUTHOR_META = {\n rationale:\n 'Designs tool schemas, capability declarations and error contracts; tool-author is the narrow, security-focused counterpart to plugin-author.',\n signals: [\n 'tool',\n 'tool schema',\n 'capability',\n 'permission',\n 'tool contract',\n 'tool error',\n 'tool lifecycle',\n ] as const,\n differentiatesFrom:\n 'plugin-author writes full plugin lifecycle; tool-author focuses on a single tool contract and capability set.',\n};\n\nconst PROMPT_EVALUATOR_META = {\n rationale:\n 'Builds rubrics and runs adversarial / regression tests on prompts; prompt-evaluator is the independent measurement counterpart to prompt.',\n signals: [\n 'prompt eval',\n 'prompt regression',\n 'rubric',\n 'adversarial prompt',\n 'prompt benchmark',\n 'judge prompt',\n 'eval suite',\n ] as const,\n differentiatesFrom:\n 'prompt authors prompts; prompt-evaluator independently measures them with rubrics and adversarial inputs.',\n};\n\nconst BENCHMARK_ENGINEER_META = {\n rationale:\n 'Designs reproducible benchmarks and methodology for comparing models and agent setups; benchmark-engineer is the measurement-infrastructure counterpart to performance.',\n signals: [\n 'benchmark',\n 'reproducible',\n 'evaluation harness',\n 'regression suite',\n 'metric methodology',\n 'baseline',\n 'deterministic run',\n ] as const,\n differentiatesFrom:\n 'performance optimizes product code; benchmark-engineer builds the measurement infrastructure that supports comparison.',\n};\n\nconst MEMORY_CURATOR_META = {\n rationale:\n 'Validates, merges and de-duplicates long-term memory entries with audience scope; memory-curator is the quality counterpart to context.',\n signals: [\n 'memory',\n 'curate',\n 'memory audit',\n 'memory merge',\n 'memory expiry',\n 'audience scope',\n 'memory recall quality',\n ] as const,\n differentiatesFrom:\n 'context manages the active context window; memory-curator curates the long-term memory store for accuracy.',\n};\n\nconst FLEET_COORDINATOR_META = {\n rationale:\n 'Owns job partitioning, capacity and result synthesis across many workers; fleet-coordinator is the multi-agent execution counterpart to planner.',\n signals: [\n 'fleet',\n 'fan out',\n 'parallel agents',\n 'synthesis',\n 'subagent capacity',\n 'coordinator',\n 'result aggregation',\n ] as const,\n differentiatesFrom:\n 'planner designs ordered steps for one worker; fleet-coordinator runs many workers in parallel and merges their results.',\n};\n\nexport const WAVE2_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'threat-modeler',\n name: 'Threat Modeler',\n role: 'threat-modeler',\n tools: [...TOOLS.read, 'write', 'document'],\n prompt: agentPrompt('threat-modeler'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Models trust boundaries, abuse cases and data flow before code is written; produces a threat model with attack trees.',\n keywords: [\n ...THREAT_MODELER_META.signals,\n 'threat-modeler',\n 'trust',\n 'boundary',\n 'abuse',\n 'attack',\n 'stride',\n 'asset',\n 'adversary',\n ],\n },\n },\n {\n config: {\n id: 'secure-coding-coach',\n name: 'Secure Coding Coach',\n role: 'secure-coding-coach',\n tools: [...TOOLS.read],\n prompt: agentPrompt('secure-coding-coach'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Teaches secure patterns, produces safe defaults and walks engineers through prescriptive fixes.',\n keywords: [\n ...SECURE_CODING_COACH_META.signals,\n 'secure-coding',\n 'security-coach',\n 'hardening',\n 'safe-default',\n 'owasp',\n ],\n },\n },\n {\n config: {\n id: 'resilience-engineer',\n name: 'Resilience Engineer',\n role: 'resilience-engineer',\n tools: [...TOOLS.build, 'logs', 'observability'],\n // uniqueness guaranteed by 'observability' vs chaos-engineer's 'test'\n prompt: agentPrompt('resilience-engineer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Designs retry, timeout, circuit breaker, bulkhead and graceful-degradation patterns ahead of time.',\n keywords: [\n ...RESILIENCE_ENGINEER_META.signals,\n 'resilience',\n 'timeout',\n 'circuit-breaker',\n 'bulkhead',\n 'backoff',\n 'graceful',\n ],\n },\n },\n {\n config: {\n id: 'chaos-engineer',\n name: 'Chaos Engineer',\n role: 'chaos-engineer',\n tools: [...TOOLS.build, 'logs', 'observability'],\n // uniqueness guaranteed by 'observability' vs chaos-engineer's 'test'\n prompt: agentPrompt('chaos-engineer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Builds and runs controlled fault-injection experiments with a defined blast radius, steady state and hypothesis.',\n keywords: [\n ...CHAOS_ENGINEER_META.signals,\n 'chaos-engineer',\n 'chaos-experiment',\n 'gameday',\n 'steady-state',\n ],\n },\n },\n {\n config: {\n id: 'compliance-auditor',\n name: 'Compliance Auditor',\n role: 'compliance-auditor',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('compliance-auditor'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Produces auditable control evidence, traceability and evidence maps for SOC2, ISO and similar frameworks.',\n keywords: [\n ...COMPLIANCE_AUDITOR_META.signals,\n 'compliance-auditor',\n 'soc2',\n 'iso',\n 'evidence-map',\n 'attestation',\n 'auditable',\n ],\n },\n },\n {\n config: {\n id: 'privacy-engineer',\n name: 'Privacy Engineer',\n role: 'privacy-engineer',\n tools: [...TOOLS.build, 'audit'],\n prompt: agentPrompt('privacy-engineer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Implements data minimization, consent, retention and deletion; privacy-by-design across the stack.',\n keywords: [\n ...PRIVACY_ENGINEER_META.signals,\n 'privacy-engineer',\n 'pii',\n 'gdpr',\n 'consent',\n 'retention',\n 'deletion',\n 'data-minimization',\n ],\n },\n },\n];\n\nexport const WAVE2_ROLE_METAS: Record<string, RoleDispatcherSignal> = {\n 'threat-modeler': THREAT_MODELER_META,\n 'secure-coding-coach': SECURE_CODING_COACH_META,\n 'resilience-engineer': RESILIENCE_ENGINEER_META,\n 'chaos-engineer': CHAOS_ENGINEER_META,\n 'compliance-auditor': COMPLIANCE_AUDITOR_META,\n 'privacy-engineer': PRIVACY_ENGINEER_META,\n 'plugin-author': PLUGIN_AUTHOR_META,\n 'tool-author': TOOL_AUTHOR_META,\n 'prompt-evaluator': PROMPT_EVALUATOR_META,\n 'benchmark-engineer': BENCHMARK_ENGINEER_META,\n 'memory-curator': MEMORY_CURATOR_META,\n 'fleet-coordinator': FLEET_COORDINATOR_META,\n};\n\nexport const WAVE2_ROLES = new Set<string>(Object.keys(WAVE2_ROLE_METAS));\n\nvoid skillSet;\n\n", "import { agentPrompt } from './agent-prompts.js';\nimport { type AgentDefinition, HEAVY_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\n\n/** Phase 4 \u00B7 Verify \u2014 prove the code works under normal, end-to-end, and adverse conditions. */\nexport const VERIFY_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'verifier',\n name: 'Verifier',\n role: 'verifier',\n tools: [...TOOLS.inspect, 'bash', 'exec', 'lint', 'typecheck', 'test', 'git'],\n prompt: agentPrompt('verifier'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Independent verification gate: runs the relevant checks until they pass or returns exact failures that need another implementation pass.',\n keywords: [\n 'verify',\n 'verification',\n 'quality gate',\n 'prove it works',\n 'run checks',\n 'run tests until pass',\n 'test pass',\n 'green build',\n 'typecheck',\n 'lint',\n 'regression check',\n 'acceptance gate',\n ],\n },\n },\n {\n config: {\n id: 'test',\n name: 'Test',\n role: 'test',\n tools: [...TOOLS.build],\n prompt: agentPrompt('test'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Unit + integration testing: writes meaningful tests covering golden path and edge cases, runs the suite.',\n keywords: [\n 'test',\n 'unit test',\n 'integration test',\n 'write tests',\n 'coverage',\n 'test suite',\n 'vitest',\n 'jest',\n 'add tests',\n 'spec',\n ],\n },\n },\n {\n config: {\n id: 'e2e',\n name: 'E2E',\n role: 'e2e',\n tools: [\n ...TOOLS.build,\n 'fetch',\n 'playwright_navigate',\n 'playwright_screenshot',\n 'playwright_click',\n 'playwright_type',\n 'playwright_evaluate',\n 'playwright_select_option',\n 'playwright_hover',\n 'playwright_fill_form',\n 'playwright_wait_for',\n 'playwright_press_key',\n 'playwright_drag',\n ],\n prompt: agentPrompt('e2e'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'End-to-end testing: drives full user journeys across UI/CLI/API boundaries with reproducible failures.',\n keywords: [\n 'e2e',\n 'end to end',\n 'end-to-end',\n 'user journey',\n 'smoke test',\n 'playwright',\n 'browser',\n 'screenshot',\n 'web ui',\n 'headless',\n 'cypress',\n 'full flow',\n 'browser test',\n 'acceptance test',\n 'navigate',\n 'click',\n 'form fill',\n 'dom',\n 'page load',\n ],\n },\n },\n {\n config: {\n id: 'browser',\n name: 'Browser',\n role: 'browser',\n tools: [\n ...TOOLS.read,\n 'fetch',\n 'playwright_navigate',\n 'playwright_screenshot',\n 'playwright_click',\n 'playwright_type',\n 'playwright_evaluate',\n 'playwright_select_option',\n 'playwright_hover',\n 'playwright_fill_form',\n 'playwright_wait_for',\n 'playwright_press_key',\n 'playwright_drag',\n ],\n prompt: agentPrompt('browser'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Browser automation: opens pages, clicks, types, screenshots, extracts data via Playwright headless Chromium.',\n keywords: [\n 'browser',\n 'screenshot',\n 'navigate',\n 'web page',\n 'scrape',\n 'crawl',\n 'headless',\n 'chrome',\n 'open url',\n 'capture',\n 'page title',\n 'extract data',\n 'fill form',\n 'click button',\n 'take screenshot',\n ],\n },\n },\n {\n config: {\n id: 'performance',\n name: 'Performance',\n role: 'performance',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('performance'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Performance analysis: benchmarks/profiles to find the real bottleneck, optimizes, proves speedup with numbers.',\n keywords: [\n 'performance',\n 'slow',\n 'optimize',\n 'bottleneck',\n 'profile',\n 'benchmark',\n 'latency',\n 'throughput',\n 'memory',\n 'speed up',\n 'too slow',\n ],\n },\n },\n {\n config: {\n id: 'chaos',\n name: 'Chaos',\n role: 'chaos',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('chaos'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Resilience testing via fault injection: breaks network/disk/timing to find ungraceful failures and recovery gaps.',\n keywords: [\n 'chaos',\n 'resilience',\n 'fault injection',\n 'failure mode',\n 'fail safe',\n 'retry',\n 'circuit breaker',\n 'graceful degradation',\n 'inject failure',\n 'robustness',\n ],\n },\n },\n {\n config: {\n id: 'security-scanner',\n name: 'Security Scanner',\n role: 'security-scanner',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('security-scanner'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Security scanner: detects hardcoded secrets, injection vectors, insecure patterns, and supply-chain risks with remediation.',\n keywords: [\n 'security',\n 'scan',\n 'vulnerability',\n 'secret',\n 'api key',\n 'hardcoded',\n 'injection',\n 'cve',\n 'audit dependencies',\n 'supply chain',\n 'xss',\n 'sqli',\n 'shell injection',\n 'sensitive data',\n 'credential',\n ],\n },\n },\n {\n config: {\n id: 'bug-hunter',\n name: 'Bug Hunter',\n role: 'bug-hunter',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('bug-hunter'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Bug hunter: scans source code for bugs, anti-patterns, and code smells, producing a file:line-ranked hit list with fixes.',\n keywords: [\n 'bug',\n 'hunt',\n 'scan',\n 'code smell',\n 'anti-pattern',\n 'race condition',\n 'memory leak',\n 'null deref',\n 'type safety',\n 'unhandled error',\n 'find bugs',\n 'audit code',\n 'code quality',\n ],\n },\n },\n {\n config: {\n id: 'audit-log',\n name: 'Audit Log',\n role: 'audit-log',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('audit-log'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Audit log analyzer: parses session JSONL, detects failure patterns, tool anomalies, and cost trends with structured reports.',\n keywords: [\n 'audit',\n 'log',\n 'logs',\n 'session',\n 'trace',\n 'analyze logs',\n 'error patterns',\n 'cost analysis',\n 'tool usage',\n 'token usage',\n 'post-mortem',\n 'trend',\n 'anomaly',\n ],\n },\n },\n];\n", "import { agentPrompt } from './agent-prompts.js';\nimport { type AgentDefinition, MEDIUM_BUDGET, TOOLS } from './types.js';\n\n/** Phase 5 \u00B7 Review \u2014 read-only quality, security, a11y, and compliance gates. */\nexport const REVIEW_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'reviewer',\n name: 'Reviewer',\n role: 'reviewer',\n tools: [...TOOLS.inspect, 'git'],\n prompt: agentPrompt('reviewer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n \"Independent AI reviewer: audits another agent's output, flags uncertainty, correlated-failure risk, and must-fix defects.\",\n keywords: [\n 'reviewer',\n 'independent review',\n 'ai review',\n 'review agent',\n 'quality review',\n 'second opinion',\n 'check another agent',\n 'cross check',\n 'uncertainty',\n 'correlated error',\n 'verify output',\n 'quality control',\n ],\n },\n },\n {\n config: {\n id: 'code-reviewer',\n name: 'Code Reviewer',\n role: 'code-reviewer',\n tools: [...TOOLS.inspect, 'git'],\n prompt: agentPrompt('code-reviewer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Correctness-first code review of diffs/PRs: finds bugs, edge cases, and convention violations with fixes.',\n keywords: [\n 'review',\n 'code review',\n 'review pr',\n 'review diff',\n 'look over',\n 'feedback on code',\n 'quality',\n 'is this correct',\n 'check my code',\n ],\n },\n },\n {\n config: {\n id: 'security-reviewer',\n name: 'Security Reviewer',\n role: 'security-reviewer',\n tools: [...TOOLS.inspect, 'git'],\n prompt: agentPrompt('security-reviewer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Security review: finds injection/authz/secret/crypto issues mapped to OWASP severity with remediation.',\n keywords: [\n 'security review',\n 'security',\n 'vulnerability',\n 'vulnerabilities',\n 'owasp',\n 'injection',\n 'sql injection',\n 'xss',\n 'ssrf',\n 'authz',\n 'secrets',\n 'security audit',\n 'threat',\n 'unsafe',\n ],\n },\n },\n {\n config: {\n id: 'accessibility',\n name: 'Accessibility',\n role: 'accessibility',\n tools: [...TOOLS.read],\n prompt: agentPrompt('accessibility'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'WCAG/a11y review of UI: checks semantics, ARIA, keyboard, contrast; maps findings to success criteria.',\n keywords: [\n 'accessibility',\n 'a11y',\n 'wcag',\n 'aria',\n 'screen reader',\n 'keyboard navigation',\n 'contrast',\n 'disabled users',\n 'accessible',\n ],\n },\n },\n {\n config: {\n id: 'compliance',\n name: 'Compliance',\n role: 'compliance',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('compliance'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'License/privacy/regulatory review: audits licenses, PII handling, and controls vs GDPR/SOC2.',\n keywords: [\n 'compliance',\n 'license',\n 'gdpr',\n 'soc2',\n 'privacy',\n 'pii',\n 'data retention',\n 'regulatory',\n 'audit log',\n 'legal review',\n ],\n },\n },\n];\n", "import { type AgentDefinition, HEAVY_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 6 \u00B7 Domain \u2014 specialists for the major slices of a system. */\nexport const DOMAIN_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'database',\n name: 'Database',\n role: 'database',\n tools: [...TOOLS.build],\n prompt: agentPrompt('database'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Schema design, query optimization, and safe reversible migrations for SQL databases.',\n keywords: [\n 'database',\n 'schema',\n 'sql',\n 'migration',\n 'query',\n 'index',\n 'postgres',\n 'mysql',\n 'table',\n 'orm',\n 'slow query',\n ],\n },\n },\n {\n config: {\n id: 'api',\n name: 'API',\n role: 'api',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('api'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'REST + GraphQL API design and implementation: contracts, HTTP/GraphQL semantics, versioning.',\n keywords: [\n 'api',\n 'rest',\n 'graphql',\n 'endpoint',\n 'resolver',\n 'http',\n 'openapi',\n 'swagger',\n 'route',\n 'contract',\n 'webhook',\n ],\n },\n },\n {\n config: {\n id: 'auth',\n name: 'Auth',\n role: 'auth',\n tools: [...TOOLS.build],\n prompt: agentPrompt('auth'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Authentication and authorization: identity, sessions/tokens, RBAC/ABAC, OAuth/OIDC, done securely.',\n keywords: [\n 'auth',\n 'authentication',\n 'authorization',\n 'login',\n 'session',\n 'jwt',\n 'oauth',\n 'oidc',\n 'rbac',\n 'permissions',\n 'token',\n 'sso',\n ],\n },\n },\n {\n config: {\n id: 'data',\n name: 'Data',\n role: 'data',\n tools: [...TOOLS.build],\n prompt: agentPrompt('data'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Data engineering: ETL/ELT pipelines, data-quality validation, idempotent transforms, reconciliation.',\n keywords: [\n 'etl',\n 'elt',\n 'pipeline',\n 'data quality',\n 'data engineering',\n 'transform',\n 'ingestion',\n 'batch',\n 'stream',\n 'reconcile',\n 'dataset',\n ],\n },\n },\n {\n config: {\n id: 'frontend',\n name: 'Frontend',\n role: 'frontend',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('frontend'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'UI implementation: components, client state, data fetching, responsive and accessible by default.',\n keywords: [\n 'frontend',\n 'component',\n 'react',\n 'vue',\n 'svelte',\n 'client state',\n 'ui implementation',\n 'css',\n 'responsive',\n 'hook',\n 'render',\n ],\n },\n },\n {\n config: {\n id: 'backend',\n name: 'Backend',\n role: 'backend',\n tools: [...TOOLS.build],\n prompt: agentPrompt('backend'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Server-side logic: services, business rules, persistence/queue wiring, concurrency and transactions.',\n keywords: [\n 'backend',\n 'server',\n 'service',\n 'business logic',\n 'controller',\n 'handler',\n 'queue',\n 'cache',\n 'transaction',\n 'microservice',\n 'server-side',\n ],\n },\n },\n {\n config: {\n id: 'designer',\n name: 'Designer',\n role: 'designer',\n tools: [...TOOLS.docs],\n prompt: agentPrompt('designer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'UI/UX design: user flows, layout/wireframes, interaction states, and design-system decisions.',\n keywords: [\n 'design',\n 'ux',\n 'ui design',\n 'wireframe',\n 'user flow',\n 'layout',\n 'design system',\n 'interaction',\n 'mockup design',\n 'information architecture',\n ],\n },\n },\n {\n config: {\n id: 'ios',\n name: 'iOS',\n role: 'ios',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('ios'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Apple-platform app development in Swift against the latest Xcode/iOS-SDK line: SwiftUI, UIKit, SwiftData, concurrency, accessibility, and App Store submission.',\n keywords: [\n 'ios',\n 'iphone',\n 'ipad',\n 'ipados',\n 'watchos',\n 'tvos',\n 'visionos',\n 'macos',\n 'swift',\n 'swiftui',\n 'uikit',\n 'xcode',\n 'swiftdata',\n 'app store',\n 'app intents',\n 'swift package manager',\n 'cocoapods',\n 'foundation models',\n ],\n },\n },\n];\n", "import { type AgentDefinition, LIGHT_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 7 \u00B7 Knowledge \u2014 documentation, diagrams, localization, and prompts. */\nexport const KNOWLEDGE_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'document',\n name: 'Document',\n role: 'document',\n tools: [...TOOLS.docs],\n prompt: agentPrompt('document'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Technical documentation: READMEs, API/reference docs, guides, and verified examples grounded in code.',\n keywords: [\n 'document',\n 'documentation',\n 'readme',\n 'docs',\n 'write up',\n 'guide',\n 'api docs',\n 'explain in writing',\n 'reference',\n 'changelog notes',\n ],\n },\n },\n {\n config: {\n id: 'uml',\n name: 'UML',\n role: 'uml',\n tools: [...TOOLS.read, 'write', 'edit'],\n prompt: agentPrompt('uml'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Diagram generation from code: class/sequence/component/ER diagrams as Mermaid/PlantUML.',\n keywords: [\n 'uml',\n 'diagram',\n 'mermaid',\n 'plantuml',\n 'sequence diagram',\n 'class diagram',\n 'er diagram',\n 'visualize',\n 'flowchart',\n 'architecture diagram',\n ],\n },\n },\n {\n config: {\n id: 'i18n',\n name: 'I18n',\n role: 'i18n',\n tools: [...TOOLS.write],\n prompt: agentPrompt('i18n'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Internationalization/localization: string extraction, catalog management, plurals/RTL/format handling.',\n keywords: [\n 'i18n',\n 'internationalization',\n 'localization',\n 'l10n',\n 'translation',\n 'translate ui',\n 'locale',\n 'rtl',\n 'message catalog',\n 'multilingual',\n ],\n },\n },\n {\n config: {\n id: 'prompt',\n name: 'Prompt',\n role: 'prompt',\n tools: [...TOOLS.write],\n prompt: agentPrompt('prompt'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Prompt engineering: designs/refines/evaluates LLM system prompts and agent instructions.',\n keywords: [\n 'prompt',\n 'prompt engineering',\n 'system prompt',\n 'llm instructions',\n 'few-shot',\n 'refine prompt',\n 'agent instructions',\n 'prompt template',\n ],\n },\n },\n];\n", "import { type AgentDefinition, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 8 \u00B7 Delivery & Ops \u2014 ship it, run it, keep it healthy. */\nexport const DELIVERY_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'git',\n name: 'Git',\n role: 'git',\n tools: [...TOOLS.vcs, 'bash'],\n prompt: agentPrompt('git'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Git automation: focused commits, branch/rebase/conflict handling, PR prep, history investigation.',\n keywords: [\n 'git',\n 'commit',\n 'branch',\n 'rebase',\n 'merge',\n 'pull request',\n 'pr',\n 'conflict',\n 'blame',\n 'bisect',\n 'cherry-pick',\n 'stash',\n ],\n },\n },\n {\n config: {\n id: 'release',\n name: 'Release',\n role: 'release',\n tools: [...TOOLS.vcs, 'bash', 'json'],\n prompt: agentPrompt('release'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Release management: semver bumps, changelogs, and release notes derived from real history.',\n keywords: [\n 'release',\n 'version',\n 'semver',\n 'changelog',\n 'release notes',\n 'tag',\n 'bump version',\n 'publish',\n 'versioning',\n ],\n },\n },\n {\n config: {\n id: 'devops',\n name: 'DevOps',\n role: 'devops',\n tools: [\n ...TOOLS.build,\n 'mcp__ssh__ssh_list_servers',\n 'mcp__ssh__ssh_connection_status',\n 'mcp__ssh__ssh_execute',\n 'mcp__ssh__ssh_execute_sudo',\n 'mcp__ssh__ssh_upload',\n 'mcp__ssh__ssh_download',\n 'mcp__ssh__ssh_sync',\n 'mcp__ssh__ssh_deploy',\n 'mcp__ssh__ssh_health_check',\n 'mcp__ssh__ssh_service_status',\n 'mcp__ssh__ssh_process_manager',\n 'mcp__ssh__ssh_tunnel',\n 'mcp__ssh__ssh_backup_create',\n 'mcp__ssh__ssh_backup_list',\n 'mcp__ssh__ssh_backup_restore',\n 'mcp__ssh__ssh_db_list',\n 'mcp__ssh__ssh_db_query',\n 'mcp__ssh__ssh_profile',\n ],\n prompt: agentPrompt('devops'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'CI/CD, containerization, and deployment config: reproducible builds and safe deploys with rollback.',\n keywords: [\n 'devops',\n 'ci',\n 'cd',\n 'ci/cd',\n 'pipeline',\n 'docker',\n 'dockerfile',\n 'kubernetes',\n 'k8s',\n 'deploy',\n 'ssh',\n 'remote ssh',\n 'remote server',\n 'sftp',\n 'tunnel',\n 'bastion',\n 'jump host',\n 'github actions',\n 'container',\n ],\n },\n },\n {\n config: {\n id: 'observability',\n name: 'Observability',\n role: 'observability',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('observability'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Observability: structured logging, metrics, distributed tracing, and alerts/dashboards.',\n keywords: [\n 'observability',\n 'logging',\n 'metrics',\n 'tracing',\n 'telemetry',\n 'opentelemetry',\n 'otel',\n 'prometheus',\n 'monitoring',\n 'alert',\n 'dashboard',\n 'instrument',\n ],\n },\n },\n {\n config: {\n id: 'dependency',\n name: 'Dependency',\n role: 'dependency',\n tools: [...TOOLS.deps, 'bash'],\n prompt: agentPrompt('dependency'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Package management + supply-chain safety: CVE audit, safe upgrades, pruning, install-script review.',\n keywords: [\n 'dependency',\n 'dependencies',\n 'package',\n 'npm',\n 'pnpm',\n 'cve',\n 'vulnerability scan',\n 'upgrade deps',\n 'audit',\n 'supply chain',\n 'outdated',\n 'lockfile',\n ],\n },\n },\n];\n", "import { agentPrompt } from './agent-prompts.js';\nimport type { BundledAgentSkill } from './role-skills.js';\nimport {\n type AgentDefinition,\n type RoleDispatcherSignal,\n HEAVY_BUDGET,\n MEDIUM_BUDGET,\n TOOLS,\n} from './types.js';\n\nconst skillSet = (...names: BundledAgentSkill[]): BundledAgentSkill[] => names;\n\n/**\n * Wave 3: Product and data specialists.\n *\n * Six roles that own areas the existing 51-role catalog only touches\n * generically. Each carries an explicit `RoleDispatcherSignal` so the\n * dispatcher can disambiguate from close siblings.\n */\n\nconst PAYMENTS_META = {\n rationale:\n 'Payments specialist: ledger, refund, webhook, idempotency, reconciliation. Financial correctness is too domain-specific to leave to a general backend role.',\n signals: [\n 'payments',\n 'ledger',\n 'refund',\n 'webhook',\n 'idempotency',\n 'reconciliation',\n 'pci',\n 'currency',\n ] as const,\n differentiatesFrom:\n 'backend builds services; payments owns the financial-correctness invariants and money-handling patterns.',\n} satisfies RoleDispatcherSignal;\n\nconst MESSAGING_META = {\n rationale:\n 'Messaging infrastructure specialist: queue, pub/sub, delivery semantics, DLQ. Owns distributed-messaging failure modes that the distributed-systems role designs but does not implement.',\n signals: [\n 'messaging',\n 'queue',\n 'pubsub',\n 'dead letter',\n 'dlq',\n 'delivery semantics',\n 'at-least-once',\n 'at-most-once',\n 'kafka',\n ] as const,\n differentiatesFrom:\n 'distributed-systems designs the failure semantics; messaging implements the broker and consumer infrastructure.',\n} satisfies RoleDispatcherSignal;\n\nconst SEARCH_RELEVANCE_META = {\n rationale:\n 'Search relevance specialist: indexing, ranking, retrieval, evaluation. Owns the offline and online quality metrics that a generic database role does not.',\n signals: [\n 'search',\n 'search relevance',\n 'ranking',\n 'retrieval',\n 'indexing',\n 'recall',\n 'precision',\n 'reranker',\n ] as const,\n differentiatesFrom:\n 'database stores rows; search-relevance owns the ranking, retrieval and relevance-evaluation pipeline.',\n} satisfies RoleDispatcherSignal;\n\nconst STORAGE_META = {\n rationale:\n 'Object-storage specialist: upload, checksum, lifecycle, CDN. Owns the durability and replication boundaries of blob data.',\n signals: [\n 'object storage',\n 'blob',\n 'upload',\n 'checksum',\n 'lifecycle',\n 'cdn',\n 'presigned url',\n 'multipart upload',\n ] as const,\n differentiatesFrom:\n 'database owns structured rows; storage owns unstructured blob lifecycle and replication.',\n} satisfies RoleDispatcherSignal;\n\nconst ML_ENGINEER_META = {\n rationale:\n 'ML engineer: model integration, inference, evaluation, guardrail. The catalog has no existing ML-application specialist.',\n signals: [\n 'ml',\n 'machine learning',\n 'inference',\n 'embedding',\n 'model evaluation',\n 'guardrail',\n 'llm evaluation',\n ] as const,\n differentiatesFrom:\n 'data builds pipelines; ml-engineer integrates models, evaluates them and wires guardrails.',\n} satisfies RoleDispatcherSignal;\n\nconst DATA_GOVERNANCE_META = {\n rationale:\n 'Data governance specialist: lineage, classification, ownership, data contracts. Owns accountability and quality-of-record for data assets.',\n signals: [\n 'data governance',\n 'lineage',\n 'classification',\n 'ownership',\n 'data contract',\n 'data quality',\n 'retention policy',\n ] as const,\n differentiatesFrom:\n 'data builds pipelines; data-governance owns accountability, lineage and the data contracts that bind them.',\n} satisfies RoleDispatcherSignal;\n\nexport const WAVE3_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'payments',\n name: 'Payments',\n role: 'payments',\n tools: [...new Set([...TOOLS.build, ...TOOLS.write, ...TOOLS.inspect, 'fetch'])],\n prompt: agentPrompt('payments'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Payments specialist: ledger, refund, webhook, idempotency and reconciliation with financial-correctness invariants.',\n keywords: [\n ...PAYMENTS_META.signals,\n 'payments',\n 'ledger',\n 'refund',\n 'webhook',\n 'idempotency',\n 'pci',\n ],\n },\n },\n {\n config: {\n id: 'messaging',\n name: 'Messaging',\n role: 'messaging',\n tools: [...TOOLS.build, 'logs', 'observability'],\n prompt: agentPrompt('messaging'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Messaging infrastructure specialist: queue, pub/sub, delivery semantics and DLQ with broker failure modes.',\n keywords: [\n ...MESSAGING_META.signals,\n 'messaging',\n 'queue',\n 'pubsub',\n 'dlq',\n 'kafka',\n 'rabbitmq',\n ],\n },\n },\n {\n config: {\n id: 'search-relevance',\n name: 'Search Relevance',\n role: 'search-relevance',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('search-relevance'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Search relevance specialist: indexing, ranking, retrieval and offline/online evaluation of search quality.',\n keywords: [\n ...SEARCH_RELEVANCE_META.signals,\n 'search',\n 'ranking',\n 'retrieval',\n 'indexing',\n 'recall',\n 'rerank',\n ],\n },\n },\n {\n config: {\n id: 'storage',\n name: 'Storage',\n role: 'storage',\n tools: [...TOOLS.build, 'fetch', 'logs'],\n prompt: agentPrompt('storage'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Object-storage specialist: upload, checksum, lifecycle, CDN and replication for unstructured blob data.',\n keywords: [\n ...STORAGE_META.signals,\n 'object-storage',\n 'blob',\n 'upload',\n 'checksum',\n 'lifecycle',\n 'cdn',\n ],\n },\n },\n {\n config: {\n id: 'ml-engineer',\n name: 'ML Engineer',\n role: 'ml-engineer',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('ml-engineer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'ML engineer: model integration, inference, evaluation and guardrail wiring.',\n keywords: [\n ...ML_ENGINEER_META.signals,\n 'ml',\n 'inference',\n 'embedding',\n 'guardrail',\n 'llm-eval',\n ],\n },\n },\n {\n config: {\n id: 'data-governance',\n name: 'Data Governance',\n role: 'data-governance',\n tools: [...TOOLS.read, 'write', 'audit'],\n prompt: agentPrompt('data-governance'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Data governance specialist: lineage, classification, ownership and data contracts with quality-of-record.',\n keywords: [\n ...DATA_GOVERNANCE_META.signals,\n 'data-governance',\n 'lineage',\n 'classification',\n 'data-contract',\n 'retention',\n ],\n },\n },\n];\n\nexport const WAVE3_ROLE_METAS: Record<string, RoleDispatcherSignal> = {\n payments: PAYMENTS_META,\n messaging: MESSAGING_META,\n 'search-relevance': SEARCH_RELEVANCE_META,\n storage: STORAGE_META,\n 'ml-engineer': ML_ENGINEER_META,\n 'data-governance': DATA_GOVERNANCE_META,\n};\n\nexport const WAVE3_ROLES = new Set<string>(Object.keys(WAVE3_ROLE_METAS));\n\nvoid skillSet;\n", "import { type AgentDefinition, LIGHT_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 9 \u00B7 Meta \u2014 agents that improve the agent system itself. */\nexport const META_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'skill-manage',\n name: 'Skill Manager',\n role: 'skill-manage',\n tools: [...TOOLS.write],\n prompt: agentPrompt('skill-manage'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Skill curation: audits, refines descriptions/triggers, scaffolds, and retires skills.',\n keywords: [\n 'skill',\n 'skills',\n 'curate skill',\n 'skill description',\n 'create skill',\n 'skill library',\n 'skill trigger',\n 'manage skills',\n ],\n },\n },\n {\n config: {\n id: 'self-improving',\n name: 'Self-Improving',\n role: 'self-improving',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('self-improving'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Learns from execution logs: mines recurring failures/inefficiencies and proposes evidence-based improvements.',\n keywords: [\n 'self-improving',\n 'learn from',\n 'session logs',\n 'execution analysis',\n 'recurring failure',\n 'improve agents',\n 'post-mortem',\n 'retrospective',\n 'meta-analysis',\n ],\n },\n },\n {\n config: {\n id: 'context',\n name: 'Context',\n role: 'context',\n tools: [...TOOLS.inspect, 'remember', 'forget'],\n prompt: agentPrompt('context'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Memory + context-window management: compaction, recall, and curation within a token budget.',\n keywords: [\n 'context',\n 'context window',\n 'memory',\n 'compact',\n 'summarize history',\n 'recall',\n 'token budget',\n 'prune context',\n 'remember',\n 'dfmt',\n ],\n },\n },\n {\n config: {\n id: 'cost',\n name: 'Cost',\n role: 'cost',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('cost'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Token/cloud cost optimization: finds spend waste, recommends model routing and trimming with $ estimates.',\n keywords: [\n 'cost',\n 'token cost',\n 'optimize cost',\n 'spend',\n 'cheaper',\n 'model routing',\n 'budget',\n 'expensive',\n 'reduce tokens',\n 'pricing',\n 'cloud cost',\n ],\n },\n },\n {\n config: {\n id: 'tech-stack',\n name: 'Tech Stack Validator',\n role: 'tech-stack',\n tools: ['search', 'fetch', 'read', 'grep', 'glob', 'outdated', 'audit', 'json', 'mailbox'],\n prompt: agentPrompt('tech-stack'),\n },\n budget: {\n timeoutMs: 120_000,\n maxIterations: 10,\n maxToolCalls: 40,\n maxTokens: 60_000,\n maxCostUsd: 0.25,\n },\n capability: {\n phase: 'meta',\n summary: 'Single-shot tech stack validator: checks npm for latest versions, rejects dead/obsolete packages, enforces modern alternatives.',\n keywords: [\n 'tech stack',\n 'version',\n 'package',\n 'library',\n 'framework',\n 'dependency',\n 'install',\n 'upgrade',\n 'latest',\n 'npm',\n 'pnpm add',\n 'outdated',\n 'obsolete',\n 'deprecated',\n 'what version',\n 'which package',\n 'check version',\n 'verify version',\n 'is this current',\n ],\n },\n },\n];\n", "import { agentPrompt } from './agent-prompts.js';\nimport type { BundledAgentSkill } from './role-skills.js';\nimport {\n type AgentDefinition,\n type RoleDispatcherSignal,\n LIGHT_BUDGET,\n MEDIUM_BUDGET,\n TOOLS,\n} from './types.js';\n\nconst skillSet = (...names: BundledAgentSkill[]): BundledAgentSkill[] => names;\n\n/**\n * Wave 4: Agent platform and quality.\n *\n * Six roles that improve the agent system itself. The existing\n * `skill-manage`, `self-improving`, `context`, `cost` and `tech-stack` roles\n * are kept; the new roles focus on quality measurement and the platform\n * surface that the host exposes to extensions.\n */\n\nconst PROMPT_evaluator_META = {\n rationale:\n 'Prompt evaluator: builds rubrics, adversarial tests and regression suites. Independent measurement counterpart to the `prompt` author role.',\n signals: [\n 'prompt eval',\n 'prompt regression',\n 'rubric',\n 'adversarial prompt',\n 'prompt benchmark',\n 'judge prompt',\n 'eval suite',\n ] as const,\n differentiatesFrom:\n 'prompt authors prompts; prompt-evaluator independently measures them with rubrics and adversarial inputs.',\n} satisfies RoleDispatcherSignal;\n\nconst BENCHMARK_ENGINEER_META = {\n rationale:\n 'Benchmark engineer: reproducible benchmark design and methodology. The measurement-infrastructure counterpart to `performance`.',\n signals: [\n 'benchmark',\n 'reproducible',\n 'evaluation harness',\n 'regression suite',\n 'metric methodology',\n 'baseline',\n 'deterministic run',\n ] as const,\n differentiatesFrom:\n 'performance optimizes product code; benchmark-engineer builds the measurement infrastructure that supports comparison.',\n} satisfies RoleDispatcherSignal;\n\nconst MEMORY_CURATOR_META = {\n rationale:\n 'Memory curator: validates, merges and de-duplicates long-term memory with audience scope. Quality counterpart to `context`.',\n signals: [\n 'memory',\n 'curate',\n 'memory audit',\n 'memory merge',\n 'memory expiry',\n 'audience scope',\n 'memory recall quality',\n ] as const,\n differentiatesFrom:\n 'context manages the active context window; memory-curator curates the long-term memory store for accuracy.',\n} satisfies RoleDispatcherSignal;\n\nconst FLEET_COORDINATOR_META = {\n rationale:\n 'Fleet coordinator: multi-agent job partitioning, capacity planning and result synthesis. Operational counterpart to `planner`.',\n signals: [\n 'fleet',\n 'fan out',\n 'parallel agents',\n 'synthesis',\n 'subagent capacity',\n 'coordinator',\n 'result aggregation',\n ] as const,\n differentiatesFrom:\n 'planner designs ordered steps for one worker; fleet-coordinator runs many workers in parallel and merges their results.',\n} satisfies RoleDispatcherSignal;\n\nconst PLUGIN_AUTHOR_META = {\n rationale:\n 'Plugin author: build, package and ship runnable WrongStack plugins. The production counterpart to `skill-manage`.',\n signals: [\n 'plugin',\n 'plugin api',\n 'lifecycle',\n 'health',\n 'teardown',\n 'packaging',\n 'distribution',\n ] as const,\n differentiatesFrom:\n 'skill-manage authors skills; plugin-author authors full lifecycle plugins with health and teardown.',\n} satisfies RoleDispatcherSignal;\n\nconst TOOL_AUTHOR_META = {\n rationale:\n 'Tool author: tool schema, capability declaration, permission and error contract. The narrow, security-focused counterpart to `plugin-author`.',\n signals: [\n 'tool',\n 'tool schema',\n 'capability',\n 'permission',\n 'tool contract',\n 'tool error',\n 'tool lifecycle',\n ] as const,\n differentiatesFrom:\n 'plugin-author writes full plugin lifecycle; tool-author focuses on a single tool contract and capability set.',\n} satisfies RoleDispatcherSignal;\n\nexport const WAVE4_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'plugin-author',\n name: 'Plugin Author',\n role: 'plugin-author',\n tools: [...TOOLS.write, 'fetch'],\n prompt: agentPrompt('plugin-author'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'meta',\n summary:\n 'Plugin author: build, package and ship runnable WrongStack plugins with full lifecycle, health and teardown.',\n keywords: [\n ...PLUGIN_AUTHOR_META.signals,\n 'plugin',\n 'plugin-author',\n 'lifecycle',\n 'health',\n 'teardown',\n 'plugin-packaging',\n ],\n },\n },\n {\n config: {\n id: 'tool-author',\n name: 'Tool Author',\n role: 'tool-author',\n tools: [...TOOLS.write, 'install'],\n prompt: agentPrompt('tool-author'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary:\n 'Tool author: design tool schemas, capability declarations, permissions and error contracts with security as the first concern.',\n keywords: [\n ...TOOL_AUTHOR_META.signals,\n 'tool',\n 'tool-author',\n 'capability',\n 'permission',\n 'tool-schema',\n 'tool-error',\n ],\n },\n },\n {\n config: {\n id: 'prompt-evaluator',\n name: 'Prompt Evaluator',\n role: 'prompt-evaluator',\n tools: [...TOOLS.read, 'write'],\n prompt: agentPrompt('prompt-evaluator'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'meta',\n summary:\n 'Prompt evaluator: build rubrics, adversarial prompt tests and regression suites for independent measurement.',\n keywords: [\n ...PROMPT_evaluator_META.signals,\n 'prompt-evaluator',\n 'rubric',\n 'adversarial',\n 'regression',\n 'judge',\n ],\n },\n },\n {\n config: {\n id: 'benchmark-engineer',\n name: 'Benchmark Engineer',\n role: 'benchmark-engineer',\n tools: [...TOOLS.read, 'write', 'logs'],\n prompt: agentPrompt('benchmark-engineer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'meta',\n summary:\n 'Benchmark engineer: design reproducible benchmarks and methodology with deterministic baselines.',\n keywords: [\n ...BENCHMARK_ENGINEER_META.signals,\n 'benchmark-engineer',\n 'benchmark',\n 'baseline',\n 'eval-harness',\n 'deterministic',\n ],\n },\n },\n {\n config: {\n id: 'memory-curator',\n name: 'Memory Curator',\n role: 'memory-curator',\n tools: [...TOOLS.read, 'memory'],\n prompt: agentPrompt('memory-curator'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary:\n 'Memory curator: validate, merge and de-duplicate long-term memory entries with audience scoping.',\n keywords: [\n ...MEMORY_CURATOR_META.signals,\n 'memory-curator',\n 'curate',\n 'memory-audit',\n 'memory-merge',\n 'audience-scope',\n ],\n },\n },\n {\n config: {\n id: 'fleet-coordinator',\n name: 'Fleet Coordinator',\n role: 'fleet-coordinator',\n tools: [...TOOLS.read, 'plan', 'multi-agent'],\n prompt: agentPrompt('fleet-coordinator'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'meta',\n summary:\n 'Fleet coordinator: own multi-agent job partitioning, capacity planning and result synthesis across many parallel workers.',\n keywords: [\n ...FLEET_COORDINATOR_META.signals,\n 'fleet-coordinator',\n 'fan-out',\n 'parallel',\n 'synthesis',\n 'subagent-capacity',\n ],\n },\n },\n];\n\nexport const WAVE4_ROLE_METAS: Record<string, RoleDispatcherSignal> = {\n 'plugin-author': PLUGIN_AUTHOR_META,\n 'tool-author': TOOL_AUTHOR_META,\n 'prompt-evaluator': PROMPT_evaluator_META,\n 'benchmark-engineer': BENCHMARK_ENGINEER_META,\n 'memory-curator': MEMORY_CURATOR_META,\n 'fleet-coordinator': FLEET_COORDINATOR_META,\n};\n\nexport const WAVE4_ROLES = new Set<string>(Object.keys(WAVE4_ROLE_METAS));\n\nvoid skillSet;\n", "import type { AgentDefinition } from './types.js';\n\n/**\n * Bundled skills currently assigned to built-in roster agents.\n *\n * Keeping this list explicit makes role assignments auditable and prevents a\n * typo from silently degrading a worker into its persona-only fallback.\n */\nconst BUNDLED_AGENT_SKILLS = [\n 'api-design',\n 'audit-log',\n 'bug-hunter',\n 'chimera',\n 'data-governance',\n 'docker-deploy',\n 'git-flow',\n 'mnemosyne',\n 'multi-agent',\n 'node-modern',\n 'observability',\n 'output-standards',\n 'plugin-author',\n 'prompt-engineering',\n 'react-modern',\n 'refactor-planner',\n 'research-web',\n 'sdd',\n 'security-scanner',\n 'skill-creator',\n 'tech-stack',\n 'testing',\n 'typescript-strict',\n 'wrongstack-mailbox',\n] as const;\n\nexport type BundledAgentSkill = (typeof BUNDLED_AGENT_SKILLS)[number];\n\nconst skillSet = (...names: BundledAgentSkill[]): BundledAgentSkill[] => names;\n\n/**\n * Curated cross-disciplinary skill sets for every catalog role.\n *\n * A role prompt supplies the specialist persona; these skills add reusable\n * methods and safety rails from adjacent disciplines. Sets intentionally mix\n * domain knowledge, verification, security, and delivery rather than merely\n * repeating the role name.\n */\nexport const ROLE_SKILL_SETS = {\n explore: skillSet('research-web', 'node-modern', 'typescript-strict'),\n search: skillSet('bug-hunter', 'typescript-strict', 'research-web'),\n research: skillSet('research-web', 'tech-stack', 'security-scanner', 'api-design'),\n\n analyst: skillSet('sdd', 'api-design', 'testing', 'security-scanner'),\n planner: skillSet('sdd', 'multi-agent', 'refactor-planner', 'testing'),\n architect: skillSet('sdd', 'api-design', 'refactor-planner', 'security-scanner', 'observability'),\n critic: skillSet('chimera', 'bug-hunter', 'security-scanner', 'refactor-planner'),\n 'refactor-planner': skillSet(\n 'refactor-planner',\n 'sdd',\n 'typescript-strict',\n 'testing',\n 'bug-hunter',\n ),\n\n executor: skillSet('sdd', 'typescript-strict', 'node-modern', 'testing', 'git-flow'),\n refactor: skillSet('refactor-planner', 'typescript-strict', 'testing', 'bug-hunter'),\n simplifier: skillSet('bug-hunter', 'typescript-strict', 'testing', 'refactor-planner'),\n migration: skillSet('tech-stack', 'node-modern', 'typescript-strict', 'testing', 'git-flow'),\n vision: skillSet('react-modern', 'testing', 'typescript-strict', 'security-scanner'),\n debugger: skillSet('bug-hunter', 'testing', 'typescript-strict', 'observability', 'audit-log'),\n tracer: skillSet('observability', 'audit-log', 'bug-hunter', 'testing'),\n\n verifier: skillSet('testing', 'typescript-strict', 'security-scanner', 'chimera'),\n test: skillSet('testing', 'typescript-strict', 'bug-hunter', 'security-scanner'),\n e2e: skillSet('testing', 'react-modern', 'api-design', 'security-scanner'),\n browser: skillSet('testing', 'react-modern', 'security-scanner', 'research-web'),\n performance: skillSet('observability', 'testing', 'node-modern', 'audit-log'),\n chaos: skillSet('testing', 'observability', 'security-scanner', 'audit-log'),\n 'security-scanner': skillSet('security-scanner', 'bug-hunter', 'api-design', 'tech-stack'),\n 'bug-hunter': skillSet('bug-hunter', 'typescript-strict', 'testing', 'security-scanner'),\n 'audit-log': skillSet('audit-log', 'observability', 'bug-hunter', 'output-standards'),\n\n reviewer: skillSet('chimera', 'bug-hunter', 'security-scanner', 'testing'),\n 'code-reviewer': skillSet('chimera', 'bug-hunter', 'typescript-strict', 'testing'),\n 'security-reviewer': skillSet('security-scanner', 'chimera', 'api-design', 'tech-stack'),\n accessibility: skillSet('react-modern', 'testing', 'chimera', 'security-scanner'),\n compliance: skillSet('security-scanner', 'audit-log', 'tech-stack', 'chimera'),\n\n database: skillSet('api-design', 'testing', 'security-scanner', 'observability'),\n api: skillSet('api-design', 'typescript-strict', 'node-modern', 'testing', 'security-scanner'),\n auth: skillSet('security-scanner', 'api-design', 'testing', 'typescript-strict', 'audit-log'),\n data: skillSet('typescript-strict', 'testing', 'observability', 'security-scanner'),\n frontend: skillSet('react-modern', 'typescript-strict', 'testing', 'security-scanner'),\n backend: skillSet('node-modern', 'typescript-strict', 'api-design', 'testing', 'observability'),\n designer: skillSet('react-modern', 'prompt-engineering', 'research-web', 'output-standards'),\n ios: skillSet('sdd', 'testing', 'security-scanner', 'research-web'),\n\n document: skillSet('output-standards', 'research-web', 'api-design', 'prompt-engineering'),\n uml: skillSet('sdd', 'refactor-planner', 'api-design', 'output-standards'),\n i18n: skillSet('react-modern', 'testing', 'typescript-strict', 'output-standards'),\n prompt: skillSet('prompt-engineering', 'skill-creator', 'output-standards', 'testing'),\n\n git: skillSet('git-flow', 'chimera', 'testing', 'security-scanner'),\n release: skillSet('git-flow', 'tech-stack', 'chimera', 'security-scanner'),\n devops: skillSet('docker-deploy', 'observability', 'security-scanner', 'git-flow', 'tech-stack'),\n observability: skillSet('observability', 'node-modern', 'testing', 'audit-log'),\n dependency: skillSet('tech-stack', 'security-scanner', 'node-modern', 'git-flow'),\n\n 'skill-manage': skillSet(\n 'skill-creator',\n 'prompt-engineering',\n 'security-scanner',\n 'output-standards',\n ),\n 'self-improving': skillSet(\n 'audit-log',\n 'mnemosyne',\n 'prompt-engineering',\n 'bug-hunter',\n 'observability',\n ),\n context: skillSet('mnemosyne', 'output-standards', 'prompt-engineering', 'audit-log'),\n cost: skillSet('audit-log', 'tech-stack', 'observability', 'research-web'),\n 'tech-stack': skillSet('tech-stack', 'research-web', 'security-scanner', 'node-modern'),\n\n // \u2500\u2500 Wave 1: Platform and systems engineering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n android: skillSet('react-modern', 'typescript-strict', 'testing', 'security-scanner', 'tech-stack'),\n desktop: skillSet('node-modern', 'typescript-strict', 'testing', 'security-scanner', 'tech-stack'),\n realtime: skillSet(\n 'api-design',\n 'observability',\n 'node-modern',\n 'typescript-strict',\n 'testing',\n 'tech-stack',\n ),\n 'distributed-systems': skillSet(\n 'api-design',\n 'observability',\n 'typescript-strict',\n 'testing',\n 'security-scanner',\n 'tech-stack',\n ),\n concurrency: skillSet(\n 'bug-hunter',\n 'typescript-strict',\n 'testing',\n 'observability',\n 'node-modern',\n 'tech-stack',\n ),\n 'platform-engineer': skillSet(\n 'node-modern',\n 'typescript-strict',\n 'git-flow',\n 'docker-deploy',\n 'tech-stack',\n ),\n\n // \u2500\u2500 Wave 3: Product and data specialists \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n payments: skillSet(\n 'api-design',\n 'security-scanner',\n 'audit-log',\n 'testing',\n 'typescript-strict',\n 'tech-stack',\n ),\n messaging: skillSet(\n 'api-design',\n 'observability',\n 'node-modern',\n 'testing',\n 'security-scanner',\n 'tech-stack',\n ),\n 'search-relevance': skillSet(\n 'api-design',\n 'observability',\n 'testing',\n 'typescript-strict',\n 'data-governance',\n 'tech-stack',\n ),\n storage: skillSet(\n 'api-design',\n 'security-scanner',\n 'testing',\n 'observability',\n 'node-modern',\n 'tech-stack',\n ),\n 'ml-engineer': skillSet(\n 'observability',\n 'typescript-strict',\n 'testing',\n 'security-scanner',\n 'data-governance',\n 'tech-stack',\n ),\n 'data-governance': skillSet(\n 'audit-log',\n 'security-scanner',\n 'observability',\n 'testing',\n 'output-standards',\n 'tech-stack',\n ),\n\n // \u2500\u2500 Wave 4: Agent platform and quality \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n 'plugin-author': skillSet(\n 'plugin-author',\n 'node-modern',\n 'typescript-strict',\n 'testing',\n 'security-scanner',\n 'tech-stack',\n ),\n 'tool-author': skillSet(\n 'typescript-strict',\n 'security-scanner',\n 'testing',\n 'output-standards',\n 'tech-stack',\n ),\n 'prompt-evaluator': skillSet(\n 'prompt-engineering',\n 'testing',\n 'output-standards',\n 'security-scanner',\n 'tech-stack',\n ),\n 'benchmark-engineer': skillSet(\n 'observability',\n 'testing',\n 'output-standards',\n 'tech-stack',\n ),\n 'memory-curator': skillSet(\n 'mnemosyne',\n 'audit-log',\n 'testing',\n 'output-standards',\n 'tech-stack',\n ),\n 'fleet-coordinator': skillSet(\n 'multi-agent',\n 'sdd',\n 'output-standards',\n 'testing',\n 'tech-stack',\n ),\n\n // \u2500\u2500 Wave 2: Security, resilience, governance and agent platform \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n 'threat-modeler': skillSet(\n 'security-scanner',\n 'api-design',\n 'tech-stack',\n 'audit-log',\n 'testing',\n ),\n 'secure-coding-coach': skillSet(\n 'security-scanner',\n 'testing',\n 'typescript-strict',\n 'api-design',\n 'tech-stack',\n ),\n 'resilience-engineer': skillSet(\n 'observability',\n 'testing',\n 'typescript-strict',\n 'api-design',\n 'tech-stack',\n ),\n 'chaos-engineer': skillSet(\n 'observability',\n 'testing',\n 'security-scanner',\n 'git-flow',\n 'tech-stack',\n ),\n 'compliance-auditor': skillSet(\n 'audit-log',\n 'security-scanner',\n 'output-standards',\n 'testing',\n 'tech-stack',\n ),\n 'privacy-engineer': skillSet(\n 'security-scanner',\n 'audit-log',\n 'api-design',\n 'data-governance',\n 'tech-stack',\n ),\n} as const satisfies Record<string, readonly BundledAgentSkill[]>;\n\nexport type CatalogRoleWithSkills = keyof typeof ROLE_SKILL_SETS;\n\n/** Standalone operational role that lives outside the phase catalog. */\nexport const SHADOW_AGENT_SKILLS = skillSet(\n 'wrongstack-mailbox',\n 'multi-agent',\n 'audit-log',\n 'observability',\n 'security-scanner',\n);\n\n/** Attach a fresh skill-name array so catalog templates remain mutation-safe. */\nexport function assignSkillsToAgents(definitions: readonly AgentDefinition[]): AgentDefinition[] {\n return definitions.map((definition) => {\n const role = definition.config.role;\n if (!role || !Object.hasOwn(ROLE_SKILL_SETS, role)) {\n throw new Error(\n `Missing curated skill set for roster role: \"${role ?? definition.config.name}\"`,\n );\n }\n const skills = ROLE_SKILL_SETS[role as CatalogRoleWithSkills];\n return {\n ...definition,\n config: {\n ...definition.config,\n skillNames: [...skills],\n },\n };\n });\n}\n", "/**\n * Agent catalog aggregator.\n *\n * Collects every phase's `AgentDefinition[]` into:\n * - `ALL_AGENT_DEFINITIONS` \u2014 flat list, catalog order (phase 1 \u2192 9 + waves)\n * - `AGENT_CATALOG` \u2014 keyed by role for O(1) lookup\n * - `AGENTS_BY_PHASE` \u2014 grouped for statusline / dispatcher tie-breaks\n *\n * `fleet.ts` derives `FLEET_ROSTER` + `FLEET_ROSTER_BUDGETS` from this, and the\n * dispatcher routes free-form tasks against `capability` metadata here.\n */\n\nimport { DISCOVERY_AGENTS } from './phase1-discovery.js';\nimport { PLANNING_AGENTS } from './phase2-planning.js';\nimport { BUILD_AGENTS } from './phase3-build.js';\nimport { WAVE1_AGENTS } from './phase3-wave1-platform.js';\nimport { WAVE2_AGENTS } from './phase3-wave2-meta.js';\nimport { VERIFY_AGENTS } from './phase4-verify.js';\nimport { REVIEW_AGENTS } from './phase5-review.js';\nimport { DOMAIN_AGENTS } from './phase6-domain.js';\nimport { KNOWLEDGE_AGENTS } from './phase7-knowledge.js';\nimport { DELIVERY_AGENTS } from './phase8-delivery.js';\nimport { WAVE3_AGENTS } from './phase8-wave3-products.js';\nimport { META_AGENTS } from './phase9-meta.js';\nimport { WAVE4_AGENTS } from './phase9-wave4-platform-meta.js';\nimport { ROLE_SKILL_SETS, SHADOW_AGENT_SKILLS, assignSkillsToAgents } from './role-skills.js';\nimport type { AgentDefinition, AgentPhase } from './types.js';\n\nexport * from './role-skills.js';\nexport * from './types.js';\nexport * from './phase3-wave1-platform.js';\nexport * from './phase3-wave2-meta.js';\nexport * from './phase8-wave3-products.js';\nexport * from './phase9-wave4-platform-meta.js';\nexport * from './project-agent-identity.js';\nexport {\n BUILD_AGENTS,\n DELIVERY_AGENTS,\n DISCOVERY_AGENTS,\n DOMAIN_AGENTS,\n KNOWLEDGE_AGENTS,\n META_AGENTS,\n PLANNING_AGENTS,\n REVIEW_AGENTS,\n VERIFY_AGENTS,\n WAVE1_AGENTS,\n WAVE2_AGENTS,\n WAVE3_AGENTS,\n WAVE4_AGENTS,\n};\n\n/** Every catalog agent, in phase order, enriched with its curated skills. */\nexport const ALL_AGENT_DEFINITIONS: AgentDefinition[] = assignSkillsToAgents([\n ...DISCOVERY_AGENTS,\n ...PLANNING_AGENTS,\n ...BUILD_AGENTS,\n ...WAVE1_AGENTS,\n ...WAVE2_AGENTS,\n ...VERIFY_AGENTS,\n ...REVIEW_AGENTS,\n ...DOMAIN_AGENTS,\n ...KNOWLEDGE_AGENTS,\n ...DELIVERY_AGENTS,\n ...WAVE3_AGENTS,\n ...META_AGENTS,\n ...WAVE4_AGENTS,\n]);\n\n/** Phase \u2192 its enriched agents, for grouped display and dispatcher fallbacks. */\nconst agentsInPhase = (phase: AgentPhase): AgentDefinition[] =>\n ALL_AGENT_DEFINITIONS.filter((definition) => definition.capability.phase === phase);\n\nexport const AGENTS_BY_PHASE = {\n discovery: agentsInPhase('discovery'),\n planning: agentsInPhase('planning'),\n build: agentsInPhase('build'),\n verify: agentsInPhase('verify'),\n review: agentsInPhase('review'),\n domain: agentsInPhase('domain'),\n knowledge: agentsInPhase('knowledge'),\n delivery: agentsInPhase('delivery'),\n meta: agentsInPhase('meta'),\n} satisfies Record<AgentPhase, AgentDefinition[]>;\n\n/**\n * Role \u2192 definition. Built once at module load. Throws on a duplicate role so\n * a copy-paste collision fails loudly at startup instead of silently shadowing.\n */\nexport const AGENT_CATALOG: Record<string, AgentDefinition> = (() => {\n const map: Record<string, AgentDefinition> = {};\n for (const def of ALL_AGENT_DEFINITIONS) {\n const role = def.config.role;\n if (!role) {\n throw new Error(`Agent \"${def.config.name}\" is missing a role`);\n }\n if (map[role]) {\n throw new Error(`Duplicate agent role in catalog: \"${role}\"`);\n }\n map[role] = def;\n }\n return map;\n})();\n\n/** Role lookup helper. Returns undefined for unknown roles. */\nexport function getAgentDefinition(role: string): AgentDefinition | undefined {\n return AGENT_CATALOG[role];\n}\n\n// Re-export the skill-set aliases that some callers historically imported\n// from this module so the wave-1/2/3/4 surface keeps backward compatibility.\nexport { ROLE_SKILL_SETS, SHADOW_AGENT_SKILLS };\n", "/**\n * Per-task model matrix resolution.\n *\n * The matrix (Config.modelMatrix) maps a catalog **role**, a **phase** name, or\n * the `*` default to a {@link ModelMatrixEntry} (model + optional provider).\n * At subagent spawn time we resolve the most specific match so different task\n * types can run on different models \u2014 e.g. `security-scanner` on one model,\n * `documentation` on another \u2014 while the leader keeps its own model.\n *\n * Resolution precedence (most \u2192 least specific):\n * 1. exact role (matrix[\"security-scanner\"])\n * 2. the role's phase (matrix[\"review\"])\n * 3. the `*` default (matrix[\"*\"])\n * 4. undefined (caller falls back to the leader model)\n *\n * Set via the `/setmodel` slash command; this module is the single source of\n * truth both that command and the spawn path use to validate + resolve keys.\n */\n\nimport { fallbackProfileChain, parseModelRef } from '../core/fallback-model.js';\nimport type { Config, ModelMatrixEntry, ProviderConfig } from '../types/config.js';\nimport { AGENT_CATALOG, AGENTS_BY_PHASE } from './agents/index.js';\n\n/** Either a static matrix or a live getter (re-read on every spawn). */\nexport type ModelMatrixSource =\n | Record<string, ModelMatrixEntry>\n | (() => Record<string, ModelMatrixEntry> | undefined);\n\n/** All valid phase keys, in catalog order. */\nexport const MATRIX_PHASE_KEYS: readonly string[] = Object.keys(AGENTS_BY_PHASE);\n\n/** Role \u2192 phase lookup, built once from the catalog. */\nconst ROLE_TO_PHASE: Record<string, string> = (() => {\n const map: Record<string, string> = {};\n for (const [phase, defs] of Object.entries(AGENTS_BY_PHASE)) {\n for (const def of defs) {\n const role = def.config.role;\n if (role) map[role] = phase;\n }\n }\n return map;\n})();\n\n/** The phase a catalog role belongs to, or undefined for unknown roles. */\nexport function phaseForRole(role: string | undefined): string | undefined {\n return role ? ROLE_TO_PHASE[role] : undefined;\n}\n\nexport type ModelMatrixResolutionSource = 'role' | 'phase' | 'default';\n\nexport interface ModelMatrixResolution {\n entry: ModelMatrixEntry;\n source: ModelMatrixResolutionSource;\n key: string;\n}\n\n/**\n * Resolve the matrix entry plus the key tier it came from. Use this when the\n * caller needs to distinguish an explicit role/phase pin from the global `*`\n * default.\n */\nexport function resolveModelMatrixResolution(\n matrix: Record<string, ModelMatrixEntry> | undefined,\n role: string | undefined,\n): ModelMatrixResolution | undefined {\n if (!matrix) return undefined;\n if (role && matrix[role]) return { entry: matrix[role], source: 'role', key: role };\n const phase = phaseForRole(role);\n if (phase && matrix[phase]) return { entry: matrix[phase], source: 'phase', key: phase };\n if (matrix['*']) return { entry: matrix['*'], source: 'default', key: '*' };\n return undefined;\n}\n\n/**\n * Resolve the matrix entry for a subagent role. Returns the most specific\n * match (role \u2192 phase \u2192 `*`), or undefined when nothing matches.\n */\nexport function resolveModelMatrix(\n matrix: Record<string, ModelMatrixEntry> | undefined,\n role: string | undefined,\n): ModelMatrixEntry | undefined {\n return resolveModelMatrixResolution(matrix, role)?.entry;\n}\n\nexport interface ResolvedModelTarget {\n provider?: string | undefined;\n model?: string | undefined;\n modelRuntime?: Config['modelRuntime'] | undefined;\n fallbackModels?: string[] | undefined;\n fallbackProfile?: string | undefined;\n}\n\nexport interface ResolvedSubagentModelTarget extends ResolvedModelTarget {\n /** Where the concrete provider/model came from. */\n source: 'matrix' | 'diversity' | 'none';\n /** Matrix tier used before any reviewer diversity adjustment. */\n matrixSource?: ModelMatrixResolutionSource | undefined;\n /** True when a reviewer model was shifted away from the implementation model. */\n diversified?: boolean | undefined;\n}\n\n/**\n * Expand a matrix entry into a concrete primary model plus optional fallback\n * chain. A profile-only matrix entry treats the first profile model as primary\n * and the remaining profile entries as that subagent's fallback chain.\n */\nexport function resolveModelTargetFromEntry(\n config: Config,\n entry: ModelMatrixEntry | undefined,\n): ResolvedModelTarget | undefined {\n if (!entry) return undefined;\n if (entry.model) {\n return {\n provider: entry.provider,\n model: entry.model,\n modelRuntime: entry.modelRuntime,\n fallbackProfile: entry.fallbackProfile,\n fallbackModels: fallbackProfileChain(config, entry.fallbackProfile),\n };\n }\n const chain = fallbackProfileChain(config, entry.fallbackProfile);\n const first = chain[0];\n if (!first) {\n return entry.modelRuntime ? { modelRuntime: entry.modelRuntime } : undefined;\n }\n const parsed = parseModelRef(first);\n return {\n provider: parsed.provider,\n model: parsed.model,\n modelRuntime: entry.modelRuntime,\n fallbackProfile: entry.fallbackProfile,\n fallbackModels: chain.slice(1),\n };\n}\n\nexport interface ModelReference {\n provider?: string | undefined;\n model?: string | undefined;\n}\n\ninterface ConcreteModelReference {\n provider: string;\n model: string;\n}\n\n/**\n * Roles whose output is meant to challenge an implementer. When these roles\n * would otherwise use the same provider/model as the implementation path,\n * WrongStack tries to pick a different available model to reduce correlated\n * model-family mistakes. Exact role/phase `/setmodel` entries still win.\n */\nexport function roleNeedsIndependentReviewModel(role: string | undefined): boolean {\n if (!role) return false;\n return role === 'reviewer' || phaseForRole(role) === 'review';\n}\n\n/**\n * Resolve a subagent's matrix target with the reviewer diversity rule applied.\n *\n * Precedence:\n * 1. Exact role or phase matrix entry.\n * 2. Global `*` matrix entry when it is already different from the\n * implementation model.\n * 3. A different configured provider/model for review roles.\n * 4. The matrix/leader fallback.\n */\nexport function resolveSubagentModelTarget(\n config: Config,\n role: string | undefined,\n opts: { implementationTarget?: ModelReference | undefined } = {},\n): ResolvedSubagentModelTarget | undefined {\n const resolution = resolveModelMatrixResolution(config.modelMatrix, role);\n const matrixTarget = resolveModelTargetFromEntry(config, resolution?.entry);\n const implementationTarget =\n opts.implementationTarget ?? resolveImplementationModelTarget(config);\n\n if (!roleNeedsIndependentReviewModel(role)) {\n if (!matrixTarget) return undefined;\n return {\n ...matrixTarget,\n source: 'matrix',\n matrixSource: resolution?.source,\n };\n }\n\n const matrixRef = materializeTarget(config, matrixTarget);\n\n if (resolution?.source === 'role' || resolution?.source === 'phase') {\n return matrixTarget\n ? { ...matrixTarget, source: 'matrix', matrixSource: resolution.source }\n : undefined;\n }\n\n if (matrixRef && !sameModelReference(matrixRef, implementationTarget)) {\n return {\n ...(matrixTarget ?? {}),\n source: 'matrix',\n matrixSource: resolution?.source,\n };\n }\n\n const diverse = chooseDiverseModelTarget(config, implementationTarget);\n if (diverse) {\n return {\n provider: diverse.provider,\n model: diverse.model,\n modelRuntime: matrixTarget?.modelRuntime,\n fallbackModels: matrixTarget?.fallbackModels,\n fallbackProfile: matrixTarget?.fallbackProfile,\n source: 'diversity',\n matrixSource: resolution?.source,\n diversified: true,\n };\n }\n\n if (!matrixTarget) return undefined;\n return {\n ...matrixTarget,\n source: 'matrix',\n matrixSource: resolution?.source,\n };\n}\n\n/**\n * Resolve the default implementation lane. The generic Executor is the closest\n * stable proxy for \"the implementer\" when a reviewer is spawned without a\n * concrete sibling id.\n */\nexport function resolveImplementationModelTarget(config: Config): ModelReference {\n const target = resolveModelTargetFromEntry(\n config,\n resolveModelMatrix(config.modelMatrix, 'executor'),\n );\n return (\n materializeTarget(config, target) ?? {\n provider: config.provider,\n model: config.model,\n }\n );\n}\n\nexport function sameModelReference(\n a: ModelReference | undefined,\n b: ModelReference | undefined,\n): boolean {\n if (!a?.model || !b?.model) return false;\n const providerA = a.provider ?? '';\n const providerB = b.provider ?? '';\n return providerA === providerB && a.model === b.model;\n}\n\nfunction materializeTarget(\n config: Config,\n target: ResolvedModelTarget | undefined,\n): ModelReference | undefined {\n if (!target?.model) return undefined;\n return {\n provider: target.provider ?? config.provider,\n model: target.model,\n };\n}\n\nfunction chooseDiverseModelTarget(\n config: Config,\n avoid: ModelReference,\n): ConcreteModelReference | undefined {\n const candidates = collectConfiguredModelTargets(config).filter(\n (candidate) => !sameModelReference(candidate, avoid),\n );\n candidates.sort((a, b) => modelDiversityScore(b, avoid) - modelDiversityScore(a, avoid));\n return candidates[0];\n}\n\nfunction collectConfiguredModelTargets(config: Config): ConcreteModelReference[] {\n const seen = new Set<string>();\n const out: ConcreteModelReference[] = [];\n const add = (provider: string | undefined, model: string | undefined) => {\n if (!provider || !model) return;\n const key = `${provider}\\u0000${model}`;\n if (seen.has(key)) return;\n seen.add(key);\n out.push({ provider, model });\n };\n\n add(config.provider, config.model);\n for (const [providerId, provider] of Object.entries(config.providers ?? {})) {\n if (!isProviderAvailable(providerId, provider, config.provider)) continue;\n for (const model of provider.models ?? []) add(providerId, model);\n for (const model of Object.keys(provider.customModels ?? {})) add(providerId, model);\n }\n for (const model of Object.keys(config.models ?? {})) add(config.provider, model);\n return out;\n}\n\nfunction isProviderAvailable(\n providerId: string,\n provider: ProviderConfig,\n leaderProvider: string,\n): boolean {\n if (providerId === leaderProvider) return true;\n if (typeof provider.apiKey === 'string' && provider.apiKey.length > 0) return true;\n if (Array.isArray(provider.apiKeys) && provider.apiKeys.some((key) => key?.apiKey)) return true;\n if (typeof provider.baseUrl === 'string' && provider.baseUrl.length > 0) return true;\n return false;\n}\n\nfunction modelDiversityScore(candidate: ConcreteModelReference, avoid: ModelReference): number {\n let score = 0;\n if (candidate.provider !== avoid.provider) score += 100;\n if (candidate.model !== avoid.model) score += 20;\n if (/opus|gpt-5|o3|o4|gemini.*pro|deepseek-r1/i.test(candidate.model)) score += 10;\n if (/mini|haiku|flash/i.test(candidate.model)) score -= 5;\n return score;\n}\n\nexport type MatrixKeyKind = 'role' | 'phase' | 'default' | 'unknown';\n\n/** Classify a matrix key so `/setmodel` can reject typos before persisting. */\nexport function matrixKeyKind(key: string): MatrixKeyKind {\n if (key === '*') return 'default';\n if (key in AGENT_CATALOG) return 'role';\n if (MATRIX_PHASE_KEYS.includes(key)) return 'phase';\n return 'unknown';\n}\n\n/** True when `key` is a usable matrix key (role, phase, or `*`). */\nexport function isValidMatrixKey(key: string): boolean {\n return matrixKeyKind(key) !== 'unknown';\n}\n", "import type { Config } from '../types/config.js';\nimport { normalizeModelRef } from '../core/fallback-model.js';\n\n/** Canonicalize a model reference so equivalent spellings dedupe. */\nexport function normalizeRef(ref: string): string {\n return ref\n .trim()\n .replace(/\\s*\\/\\s*/g, '/')\n .replace(/\\s+/g, ' ');\n}\n\n/**\n * Validate that a model reference is in the user's favorites list (or that\n * favorites are not enforced). Returns `true` when the ref is valid.\n */\nexport function isFavoriteRef(ref: string, config: Config): boolean {\n const favorites = config.favoriteModels ?? [];\n if (favorites.length === 0) return true;\n const canonical = normalizeModelRef(ref, config.provider);\n return favorites.some((f) => normalizeModelRef(f, config.provider) === canonical);\n}\n\n/** Build a human-friendly error listing provider/model favorites. */\nexport function notFavoriteError(ref: string, config: Config): string {\n const favorites = config.favoriteModels ?? [];\n return (\n `\"${ref}\" is not in your favorites list. ` +\n (favorites.length === 0\n ? 'Add some favorites first with favorite_manage({ action: \"add\", model: \"<provider/model>\" }).'\n : `Current favorites: ${favorites.join(', ') || '(none)'}. ` +\n 'Use favorite_manage to add this model first.')\n );\n}\n\nexport function modelList(config: Config): string[] {\n return config.favoriteModels ?? [];\n}\n\nexport function profileList(config: Config): Record<string, string[]> {\n return (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n}\n\nexport function chainList(config: Config): string[] {\n return config.fallbackModels ?? [];\n}\n", "import type { JSONSchema, Tool } from '../types/tool.js';\nimport {\n chainList,\n isFavoriteRef,\n notFavoriteError,\n normalizeRef,\n} from './fallback-manage-helpers.js';\nimport type { FallbackManageToolOptions } from './fallback-manage-tool-options.js';\n\nexport const FALLBACK_CHAIN_MANAGE_TOOL_NAME = 'fallback_chain_manage';\n\nconst FALLBACK_CHAIN_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'add', 'insert', 'remove', 'clear'],\n description:\n 'Operation: list (show chain), add (append), insert (insert at position), ' +\n 'remove (by index or ref), clear (empty the chain).',\n },\n model: {\n type: 'string',\n description:\n 'Model reference for add/insert/remove (e.g. \"anthropic/claude-haiku-3\"). ' +\n 'Must be in your favorites list for add/insert. Required for add, insert, and remove (when removing by ref).',\n },\n index: {\n type: 'number',\n description:\n '1-based insertion position (for action=\"insert\") or removal index (for action=\"remove\"). ' +\n 'For insert: the new entry is placed before this position. Omit to append. ' +\n 'For remove: alternative to model. Omit to remove by model ref.',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface FallbackChainInput {\n action: 'list' | 'add' | 'insert' | 'remove' | 'clear';\n model?: string | undefined;\n index?: number | undefined;\n}\n\ninterface FallbackChainOutput {\n status: 'ok' | 'error';\n message: string;\n chain?: string[];\n}\n\nexport function createFallbackChainManageTool(\n opts: FallbackManageToolOptions,\n): Tool<FallbackChainInput, FallbackChainOutput> {\n return {\n name: FALLBACK_CHAIN_MANAGE_TOOL_NAME,\n description:\n 'View or change the active rate-limit fallback chain. When the primary model ' +\n 'is overloaded (429/5xx), the agent rotates through this chain in order. ' +\n 'Every new entry must be a FAVORITE model \u2014 add it via favorite_manage first. ' +\n 'Use insert to place a fallback at a specific position; use remove to delete an entry.',\n usageHint:\n '\"list\" to see the current chain. \"add\" with a favorite model to append. ' +\n '\"insert\" with an index (1-based) to place before that position. ' +\n '\"remove\" with index or model ref. \"clear\" to empty the chain (auto fallback takes over).',\n category: 'Config',\n inputSchema: FALLBACK_CHAIN_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const chain = [...chainList(config)];\n\n if (input.action === 'list') {\n if (chain.length === 0) {\n return {\n status: 'ok',\n message: 'Fallback chain is empty. Add entries with \"add\" or enable auto fallback.',\n chain: [],\n };\n }\n const msg = chain.map((ref, i) => ` ${i + 1}. ${ref}`).join('\\n');\n return {\n status: 'ok',\n message: `Fallback chain (${chain.length}):\\n${msg}`,\n chain: [...chain],\n };\n }\n\n if (input.action === 'add') {\n if (!input.model) {\n return {\n status: 'error',\n message: 'Provide \"model\" (e.g. \"anthropic/claude-haiku-3\") to add to the chain.',\n };\n }\n const ref = normalizeRef(input.model);\n if (!isFavoriteRef(ref, config)) {\n return { status: 'error', message: notFavoriteError(ref, config) };\n }\n if (chain.some((e) => normalizeRef(e) === ref)) {\n return { status: 'error', message: `\"${ref}\" is already in the chain.` };\n }\n chain.push(ref);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return {\n status: 'ok',\n message: `\u2713 Added to chain: ${ref} (position ${chain.length})`,\n chain: [...chain],\n };\n }\n\n if (input.action === 'insert') {\n if (!input.model) {\n return { status: 'error', message: 'Provide \"model\" to insert into the chain.' };\n }\n const ref = normalizeRef(input.model);\n if (!isFavoriteRef(ref, config)) {\n return { status: 'error', message: notFavoriteError(ref, config) };\n }\n if (chain.some((e) => normalizeRef(e) === ref)) {\n return { status: 'error', message: `\"${ref}\" is already in the chain.` };\n }\n let pos = chain.length;\n if (input.index !== undefined) {\n pos = Math.max(0, Math.min(chain.length, input.index - 1));\n }\n chain.splice(pos, 0, ref);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return {\n status: 'ok',\n message: `\u2713 Inserted at position ${pos + 1}: ${ref}`,\n chain: [...chain],\n };\n }\n\n if (input.action === 'remove') {\n if (chain.length === 0) {\n return { status: 'error', message: 'Chain is empty \u2014 nothing to remove.' };\n }\n if (input.index !== undefined) {\n const idx = input.index - 1;\n if (idx < 0 || idx >= chain.length) {\n return {\n status: 'error',\n message: `Index ${input.index} is out of range (1\u2013${chain.length}).`,\n };\n }\n const [removed] = chain.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return { status: 'ok', message: `\u2713 Removed: ${removed}`, chain: [...chain] };\n }\n if (input.model) {\n const ref = normalizeRef(input.model);\n const idx = chain.findIndex((e) => normalizeRef(e) === ref);\n if (idx === -1) {\n return { status: 'error', message: `\"${ref}\" not found in chain.` };\n }\n const [removed] = chain.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return { status: 'ok', message: `\u2713 Removed: ${removed}`, chain: [...chain] };\n }\n return { status: 'error', message: 'Provide \"index\" or \"model\" to remove from the chain.' };\n }\n\n if (input.action === 'clear') {\n if (chain.length === 0) {\n return { status: 'ok', message: 'Chain is already empty.' };\n }\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = [];\n });\n return {\n status: 'ok',\n message: '\u2713 Cleared the fallback chain. Auto fallback will take over when enabled.',\n };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n", "import { normalizeModelRef } from '../core/fallback-model.js';\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport type { FallbackManageToolOptions } from './fallback-manage-tool-options.js';\nimport { modelList, normalizeRef } from './fallback-manage-helpers.js';\n\nexport const FAVORITE_MANAGE_TOOL_NAME = 'favorite_manage';\n\nconst FAVORITE_MANAGE_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'add', 'remove'],\n description: 'Operation to perform: list (show all), add (add a favorite), remove (remove by index or ref).',\n },\n model: {\n type: 'string',\n description:\n 'Model reference to add/remove (e.g. \"anthropic/claude-haiku-3\", \"openai/gpt-4o-mini\"). ' +\n 'Required for \"add\" and \"remove\" (when removing by ref).',\n },\n index: {\n type: 'number',\n description: '1-based index for removal. Alternative to `model`. Used when action=\"remove\".',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface FavoriteManageInput {\n action: 'list' | 'add' | 'remove';\n model?: string | undefined;\n index?: number | undefined;\n}\n\ninterface FavoriteManageOutput {\n status: 'ok' | 'error';\n message: string;\n favorites?: string[];\n}\n\nexport function createFavoriteManageTool(\n opts: FallbackManageToolOptions,\n): Tool<FavoriteManageInput, FavoriteManageOutput> {\n return {\n name: FAVORITE_MANAGE_TOOL_NAME,\n description:\n 'Manage your favorite provider/model list. Favorites are the only models ' +\n 'that can be added to fallback chains and profiles. The LLM uses this tool ' +\n 'to curate which models are available for fallback and role assignment.',\n usageHint: 'Start with \"list\" to see current favorites. Use \"add <provider/model>\" to add. Use \"remove <index|ref>\" to remove.',\n category: 'Config',\n inputSchema: FAVORITE_MANAGE_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const favorites = [...modelList(config)];\n\n if (input.action === 'list') {\n const msg =\n favorites.length === 0\n ? 'No favorites set. Add one with favorite_manage({ action: \"add\", model: \"<provider/model>\" }).'\n : `Favorites (${favorites.length}):\\n` + favorites.map((f, i) => ` ${i + 1}. ${f}`).join('\\n');\n return { status: 'ok', message: msg, favorites: [...favorites] };\n }\n\n if (input.action === 'add') {\n if (!input.model) {\n return { status: 'error', message: 'Provide \"model\" (e.g. \"anthropic/claude-haiku-3\") to add a favorite.' };\n }\n const ref = normalizeRef(input.model);\n const canonical = normalizeModelRef(ref, config.provider);\n if (favorites.some((f) => normalizeModelRef(f, config.provider) === canonical)) {\n return { status: 'error', message: `\"${ref}\" is already a favorite.` };\n }\n favorites.push(ref);\n await opts.updateConfig((cfg) => {\n cfg.favoriteModels = favorites;\n });\n return {\n status: 'ok',\n message: `\u2713 Added favorite: ${ref} (${favorites.length} total)`,\n favorites: [...favorites],\n };\n }\n\n if (input.action === 'remove') {\n if (input.index !== undefined) {\n const idx = input.index - 1;\n if (idx < 0 || idx >= favorites.length) {\n return { status: 'error', message: `Index ${input.index} is out of range (1\u2013${favorites.length}).` };\n }\n const [removed] = favorites.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.favoriteModels = favorites;\n });\n return { status: 'ok', message: `\u2713 Removed favorite: ${removed}`, favorites: [...favorites] };\n }\n if (input.model) {\n const ref = normalizeRef(input.model);\n const canonical = normalizeModelRef(ref, config.provider);\n const idx = favorites.findIndex((f) => normalizeModelRef(f, config.provider) === canonical);\n if (idx === -1) {\n return { status: 'error', message: `Favorite \"${ref}\" not found. Use \"list\" to see all favorites.` };\n }\n const [removed] = favorites.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.favoriteModels = favorites;\n });\n return { status: 'ok', message: `\u2713 Removed favorite: ${removed}`, favorites: [...favorites] };\n }\n return { status: 'error', message: 'Provide either \"model\" or \"index\" to remove a favorite.' };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\". Use \"list\", \"add\", or \"remove\".` };\n },\n };\n}\n", "interface ProviderKeyStoreInput {\n provider: string;\n envVar?: string | undefined;\n label?: string | undefined;\n setActive?: boolean | undefined;\n}\n\ninterface ProviderKeyStoreOptions {\n updateConfig: (mutate: (cfg: Record<string, unknown>) => void) => Promise<void>;\n}\n\nexport interface ProviderKeyStoreOutput {\n status: 'ok';\n message: string;\n}\n\nexport async function storeProviderKey(\n providers: Record<string, Record<string, unknown>>,\n input: ProviderKeyStoreInput,\n keyValue: string,\n opts: ProviderKeyStoreOptions,\n): Promise<ProviderKeyStoreOutput> {\n const providerId = input.provider;\n\n // Ensure the provider config exists.\n if (!providers[providerId]) {\n // Auto-create with a best-guess type; users can configure details later.\n providers[providerId] = { type: providerId };\n }\n\n const entry = providers[providerId]!;\n const existingKeys = Array.isArray(entry.apiKeys)\n ? [...(entry.apiKeys as Array<Record<string, unknown>>)]\n : [];\n const label = input.label ?? 'default';\n\n existingKeys.push({\n label,\n apiKey: keyValue,\n createdAt: new Date().toISOString(),\n });\n\n entry.apiKeys = existingKeys;\n entry.apiKey = undefined;\n\n if (input.setActive !== false) {\n entry.activeKey = label;\n }\n\n providers[providerId] = entry;\n\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n\n const sourceName = input.envVar ? `env:${input.envVar}` : 'direct key';\n return {\n status: 'ok',\n message:\n `\u2713 API key stored for \"${providerId}\" from ${sourceName}. ` +\n `Now add models to favorites with favorite_manage to use them in fallback chains.`,\n };\n}\n", "import { AGENT_CATALOG } from '../coordination/agents/index.js';\nimport { phaseForRole, resolveSubagentModelTarget } from '../coordination/model-matrix.js';\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport type { FallbackManageToolOptions } from './fallback-manage-tool-options.js';\nimport { parseRefInternal } from './fallback-model-ref-parse.js';\n// \u2500\u2500 8. SYSTEM_CONFIG_VIEW \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const SYSTEM_CONFIG_VIEW_TOOL_NAME = 'system_config_view';\n\nconst SYSTEM_CONFIG_VIEW_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n section: {\n type: 'string',\n enum: ['all', 'providers', 'models', 'fallbacks', 'matrix', 'agents', 'refiner', 'doctor'],\n description:\n 'Which section to show: all (everything), providers (configured providers + keys), ' +\n 'models (favorites + leader), fallbacks (chain + profiles + toggles), ' +\n 'matrix (per-role assignments), agents (every catalog agent with resolved model), ' +\n 'refiner (goal refinement config), doctor (validate config and show issues/warnings). ' +\n 'Default: all.',\n },\n },\n additionalProperties: false,\n};\n\ninterface SystemConfigViewInput {\n section?:\n | 'all'\n | 'providers'\n | 'models'\n | 'fallbacks'\n | 'matrix'\n | 'agents'\n | 'refiner'\n | 'doctor'\n | undefined;\n}\n\ninterface SystemConfigViewOutput {\n status: 'ok';\n message: string;\n}\n\nexport function createSystemConfigViewTool(\n opts: FallbackManageToolOptions,\n): Tool<SystemConfigViewInput, SystemConfigViewOutput> {\n return {\n name: SYSTEM_CONFIG_VIEW_TOOL_NAME,\n description:\n 'Get a comprehensive view of all provider, model, fallback, and matrix configuration. ' +\n 'Shows the complete state across all configurable areas so you can see what is available ' +\n 'and make informed decisions when assigning models, creating fallback profiles, or ' +\n 'managing providers. Use the section parameter to focus on specific areas.',\n usageHint:\n '\"section: all\" for everything. \"section: providers\" for configured providers and key status. ' +\n '\"section: models\" for leader model and favorites. ' +\n '\"section: fallbacks\" for chains, profiles, and toggles. ' +\n '\"section: matrix\" for per-role assignments. ' +\n '\"section: refiner\" for goal refinement config.',\n category: 'Config',\n inputSchema: SYSTEM_CONFIG_VIEW_SCHEMA,\n permission: 'auto',\n mutating: false,\n riskTier: 'safe',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const section = input.section ?? 'all';\n const sections: string[] = [];\n const addSection = (title: string, content: string) => {\n sections.push(`\u2500\u2500 ${title} \u2500\u2500\\n${content}`);\n };\n\n // Always show provider/model header\n addSection('Leader', ` ${config.provider}/${config.model}`);\n\n if (section === 'all' || section === 'providers') {\n const providers = (config.providers ?? {}) as unknown as Record<\n string,\n Record<string, unknown>\n >;\n const ids = Object.keys(providers);\n if (ids.length === 0) {\n addSection('Providers', ' (none configured)');\n } else {\n const lines = ids.sort().map((id) => {\n const e = providers[id] ?? {};\n const type = (e.type as string) ?? '?';\n const models = Array.isArray(e.models)\n ? `[${(e.models as string[]).join(', ')}]`\n : '(all)';\n const hasKey =\n e.apiKey || (Array.isArray(e.apiKeys) && e.apiKeys.length > 0) ? '\u2713' : '\u2717';\n const baseUrl = e.baseUrl ? ` url:${e.baseUrl}` : '';\n const family = e.family ? ` family:${e.family}` : '';\n const envVars = Array.isArray(e.envVars)\n ? ` env:[${(e.envVars as string[]).join(', ')}]`\n : '';\n return ` ${id === config.provider ? '\u2605' : ' '} ${id} (${type}) key:${hasKey} models:${models}${baseUrl}${family}${envVars}`;\n });\n addSection('Providers', lines.join('\\n'));\n }\n }\n\n if (section === 'all' || section === 'models') {\n const favorites = config.favoriteModels ?? [];\n addSection(\n 'Favorites',\n favorites.length > 0\n ? favorites.map((f, i) => ` ${i + 1}. ${f}`).join('\\n')\n : ' (none \u2014 use favorite_manage to add)',\n );\n addSection(\n 'Settings',\n ` fallbackAuto: ${config.fallbackAuto !== false ? 'on' : 'off'}\\n` +\n ` favoriteModelsOnly: ${config.favoriteModelsOnly ? 'on' : 'off'}`,\n );\n }\n\n if (section === 'all' || section === 'fallbacks') {\n const fallbackModels = config.fallbackModels ?? [];\n const profiles = (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n addSection(\n 'Fallback Chain',\n fallbackModels.length > 0\n ? fallbackModels.map((f, i) => ` ${i + 1}. ${f}`).join('\\n')\n : ' (empty \u2014 auto fallback applies when fallbackAuto is on)',\n );\n const profileNames = Object.keys(profiles);\n addSection(\n 'Fallback Profiles',\n profileNames.length > 0\n ? profileNames\n .sort()\n .map((n) => ` ${n} \u2192 ${profiles[n]?.join(' \u2192 ') ?? '(empty)'}`)\n .join('\\n')\n : ' (none)',\n );\n }\n\n if (section === 'all' || section === 'matrix') {\n const matrix = (config.modelMatrix ?? {}) as Record<string, Record<string, unknown>>;\n const keys = Object.keys(matrix);\n addSection(\n 'Model Matrix (role assignments)',\n keys.length > 0\n ? keys\n .sort()\n .map((k) => ` ${k} \u2192 ${JSON.stringify(matrix[k])}`)\n .join('\\n')\n : ' (empty \u2014 all roles use the leader model)',\n );\n }\n\n if (section === 'all' || section === 'agents') {\n const roleNames = Object.keys(AGENT_CATALOG).sort();\n const lines = roleNames.map((role) => {\n const phase = phaseForRole(role) ?? '?';\n const target = resolveSubagentModelTarget(config, role);\n const model = target?.provider\n ? `${target.provider}/${target.model ?? '(default)'}`\n : `${config.provider}/${config.model ?? '(leader)'}`;\n const src = target?.diversified\n ? ' (diversified)'\n : target?.source === 'matrix'\n ? ` (matrix:${target.matrixSource ?? '?'})`\n : '';\n return ` ${role.padEnd(24)} ${phase.padEnd(14)} ${model}${src}`;\n });\n addSection(\n `Agent Models (${roleNames.length} roles)`,\n lines.length > 0\n ? ` ${'ROLE'.padEnd(24)} ${'PHASE'.padEnd(14)} RESOLVED MODEL\\n` + lines.join('\\n')\n : ' (no agents in catalog)',\n );\n }\n\n if (section === 'all' || section === 'doctor') {\n const issues: string[] = [];\n const warnings: string[] = [];\n const ok: string[] = [];\n const providers = (config.providers ?? {}) as unknown as Record<\n string,\n Record<string, unknown>\n >;\n const favorites = config.favoriteModels ?? [];\n const profiles = (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n const chain = config.fallbackModels ?? [];\n const matrix = (config.modelMatrix ?? {}) as Record<string, Record<string, unknown>>;\n\n // 1. Check favorites against provider model lists\n for (const fav of favorites) {\n const p = parseRefInternal(fav);\n if (!p.model) {\n issues.push(`Favorite \"${fav}\" has no model (empty or whitespace-only reference)`);\n continue;\n }\n const provId = p.provider ?? config.provider;\n const model = p.model;\n const prov = providers[provId];\n if (!prov) {\n warnings.push(`Favorite \"${fav}\" references unknown provider \"${provId}\"`);\n continue;\n }\n const provModels = prov.models as string[] | undefined;\n if (provModels && provModels.length > 0 && !provModels.includes(model)) {\n warnings.push(\n `Favorite \"${fav}\" \u2014 model \"${model}\" not in ${provId} model list (${provModels.join(', ')})`,\n );\n } else {\n ok.push(`Favorite \"${fav}\" \u2014 provider ${provId} is configured`);\n }\n }\n\n // 2. Check fallback chain entries\n for (const entry of chain) {\n const p = parseRefInternal(entry);\n if (!p.model) {\n issues.push(`Chain entry \"${entry}\" has no model (empty or whitespace-only reference)`);\n continue;\n }\n const provId = p.provider ?? config.provider;\n if (!providers[provId] && provId !== config.provider) {\n issues.push(`Chain entry \"${entry}\" references unknown provider \"${provId}\"`);\n } else {\n ok.push(`Chain entry \"${entry}\" \u2014 provider OK`);\n }\n }\n\n // 3. Check fallback profile entries\n for (const [pname, pchain] of Object.entries(profiles)) {\n if (!pchain || pchain.length === 0) {\n warnings.push(`Profile \"${pname}\" is empty`);\n continue;\n }\n for (const entry of pchain) {\n const p = parseRefInternal(entry);\n if (!p.model) {\n issues.push(\n `Profile \"${pname}\" entry \"${entry}\" has no model (empty or whitespace-only reference)`,\n );\n continue;\n }\n const provId = p.provider ?? config.provider;\n if (!providers[provId] && provId !== config.provider) {\n issues.push(\n `Profile \"${pname}\" entry \"${entry}\" references unknown provider \"${provId}\"`,\n );\n }\n }\n }\n\n // 4. Check matrix assignments\n for (const [key, entry] of Object.entries(matrix)) {\n const eProvider = (entry.provider as string) ?? config.provider;\n const eModel = entry.model as string | undefined;\n if (eModel) {\n const provData = providers[eProvider];\n if (!provData && eProvider !== config.provider) {\n issues.push(`Matrix \"${key}\" references unknown provider \"${eProvider}\"`);\n }\n const provModels = provData?.models as string[] | undefined;\n if (provModels && provModels.length > 0 && !provModels.includes(eModel)) {\n warnings.push(`Matrix \"${key}\" \u2014 model \"${eModel}\" not in ${eProvider} model list`);\n }\n }\n // Check fallbackProfile reference\n const eProfile = entry.fallbackProfile as string | undefined;\n if (eProfile && !profiles[eProfile]) {\n issues.push(`Matrix \"${key}\" references unknown fallback profile \"${eProfile}\"`);\n }\n }\n\n // 5. Check leader provider\n if (!providers[config.provider] && Object.keys(providers).length > 0) {\n warnings.push(`Leader provider \"${config.provider}\" has no explicit config entry`);\n }\n\n // 6. Summary\n const summary =\n ` \u2713 ${ok.length} checks passed\\n` +\n ` \u26A0 ${warnings.length} warnings\\n` +\n ` \u2717 ${issues.length} issues`;\n const lines: string[] = [summary, ''];\n if (warnings.length > 0) {\n lines.push('\u2500\u2500 Warnings \u2500\u2500');\n lines.push(...warnings.map((w) => ` \u26A0 ${w}`));\n lines.push('');\n }\n if (issues.length > 0) {\n lines.push('\u2500\u2500 Issues \u2500\u2500');\n lines.push(...issues.map((i) => ` \u2717 ${i}`));\n lines.push('');\n }\n if (warnings.length === 0 && issues.length === 0 && ok.length > 0) {\n lines.push(' All checks passed \u2014 configuration is healthy.');\n }\n addSection('Configuration Doctor', lines.join('\\n'));\n }\n\n if (section === 'all' || section === 'refiner') {\n const ref = config.autonomy;\n addSection(\n 'Goal Refinement',\n ` refinerProvider: ${ref?.refinerProvider ?? '(same as leader)'}\\n` +\n ` refinerModel: ${ref?.refinerModel ?? '(default for provider)'}\\n` +\n ` refinerFallbackProfile: ${ref?.refinerFallbackProfile ?? '(none)'}`,\n );\n }\n\n return { status: 'ok', message: sections.join('\\n\\n') };\n },\n };\n}\n", "/**\n * LLM-accessible tools covering every provider/model/fallback configurable area\n * in the system: favorites, fallback chains & profiles, provider management,\n * API key handling, leader model, per-role model assignment, and system view.\n *\n * DESIGN: Every operation that accepts a provider/model reference validates\n * the entry against the user's `favoriteModels` list FIRST. This means all\n * fallback additions, profiles, and role assignments are restricted to\n * user-curated favorites \u2014 the LLM cannot add arbitrary unknown models.\n *\n * Exceptions:\n * - Removing entries (chain, profile, favorites) works on any existing entry.\n * - Listing/viewing works unconditionally.\n * - The active leader model itself is not restricted (it's already set).\n *\n * Tools (8 total):\n * favorite_manage \u2014 List, add, remove favorite models.\n * fallback_chain_manage \u2014 View, add, insert, remove, clear the active chain.\n * fallback_profile_manage \u2014 List, create/update, delete named profiles.\n * agent_model_assign \u2014 Assign model/profile to role/phase/* in the matrix.\n * provider_manage \u2014 List, add, configure, remove provider entries.\n * provider_key_set \u2014 Set API key via env var, direct key, or interactive prompt.\n * leader_model_set \u2014 View/set leader model, derive from profile, toggle settings.\n * system_config_view \u2014 Comprehensive view + validation doctor for full config.\n *\n * Usage from an agent:\n * ```\n * favorite_manage({ action: \"list\" })\n * favorite_manage({ action: \"add\", model: \"anthropic/claude-sonnet-4\" })\n * fallback_chain_manage({ action: \"add\", model: \"anthropic/claude-haiku-3\" })\n * fallback_profile_manage({ action: \"set\", name: \"fast\", chain: [\"openai/gpt-4o-mini\"] })\n * agent_model_assign({ role: \"security-scanner\", provider: \"anthropic\", model: \"claude-haiku-3\" })\n * provider_key_set({ provider: \"openai\", envVar: \"OPENAI_API_KEY\" })\n * leader_model_set({ action: \"show\" })\n * system_config_view({ section: \"all\" })\n * ```\n */\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport { isValidMatrixKey } from '../coordination/model-matrix.js';\nimport {\n isFavoriteRef,\n notFavoriteError,\n profileList,\n} from './fallback-manage-helpers.js';\nimport { createFallbackChainManageTool } from './fallback-chain-manage-tool.js';\nimport { createFavoriteManageTool } from './fallback-favorite-manage-tool.js';\nimport { parseRefInternal } from './fallback-model-ref-parse.js';\nimport type { FallbackManageToolOptions } from './fallback-manage-tool-options.js';\nimport { storeProviderKey } from './fallback-provider-key-store.js';\nimport { createSystemConfigViewTool } from './fallback-system-config-view-tool.js';\n\n// \u2500\u2500 Public types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport { FALLBACK_CHAIN_MANAGE_TOOL_NAME } from './fallback-chain-manage-tool.js';\nexport const FALLBACK_PROFILE_MANAGE_TOOL_NAME = 'fallback_profile_manage';\nexport const AGENT_MODEL_ASSIGN_TOOL_NAME = 'agent_model_assign';\nexport { FAVORITE_MANAGE_TOOL_NAME } from './fallback-favorite-manage-tool.js';\nexport * from './fallback-system-config-view-tool.js';\nexport type { FallbackManageToolOptions } from './fallback-manage-tool-options.js';\n\n// \u2500\u2500 3. FALLBACK_PROFILE_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst FALLBACK_PROFILE_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'set', 'delete'],\n description: 'Operation: list (show all profiles), set (create/update), delete (remove a profile).',\n },\n name: {\n type: 'string',\n description:\n 'Profile name (e.g. \"fast\", \"economy\", \"reliable\"). Required for \"set\" and \"delete\".',\n },\n chain: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Ordered list of model references for the profile. ' +\n 'Each entry must be a favorite model. Required for \"set\". Example: [\"anthropic/claude-haiku-3\", \"openai/gpt-4o-mini\"].',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface FallbackProfileInput {\n action: 'list' | 'set' | 'delete';\n name?: string | undefined;\n chain?: string[] | undefined;\n}\n\ninterface FallbackProfileOutput {\n status: 'ok' | 'error';\n message: string;\n profiles?: Record<string, string[]>;\n}\n\nfunction createFallbackProfileManageTool(opts: FallbackManageToolOptions): Tool<FallbackProfileInput, FallbackProfileOutput> {\n return {\n name: FALLBACK_PROFILE_MANAGE_TOOL_NAME,\n description:\n 'Manage named fallback profiles. A profile is a reusable, ordered list of ' +\n 'model references that can be assigned to agent roles. Every entry in a profile ' +\n 'must be a FAVORITE model \u2014 add it via favorite_manage first. ' +\n 'Use /setmodel or agent_model_assign to assign a profile to a role.',\n usageHint:\n '\"list\" to see all profiles. ' +\n '\"set\" with name and chain (array of model refs) to create or replace a profile. ' +\n '\"delete\" with name to remove a profile.',\n category: 'Config',\n inputSchema: FALLBACK_PROFILE_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const profiles = { ...profileList(config) };\n\n if (input.action === 'list') {\n const names = Object.keys(profiles);\n if (names.length === 0) {\n return {\n status: 'ok',\n message: 'No fallback profiles. Create one with \"set\".',\n profiles: {},\n };\n }\n const msg = names\n .sort()\n .map((name) => ` ${name} \u2192 ${profiles[name]?.join(' \u2192 ') || '(empty)'}`)\n .join('\\n');\n return { status: 'ok', message: `Fallback profiles:\\n${msg}`, profiles: { ...profiles } };\n }\n\n if (input.action === 'set') {\n if (!input.name) {\n return { status: 'error', message: 'Provide \"name\" for the profile (e.g. \"fast\").' };\n }\n if (!input.chain || input.chain.length === 0) {\n return { status: 'error', message: 'Provide \"chain\" \u2014 a non-empty array of model references.' };\n }\n // Validate every entry against favorites\n const invalid: string[] = [];\n for (const ref of input.chain) {\n if (!isFavoriteRef(ref, config)) {\n invalid.push(ref);\n }\n }\n if (invalid.length > 0) {\n return {\n status: 'error',\n message:\n `The following entries are not in your favorites list:\\n ${invalid.join('\\n ')}\\n\\n` +\n 'Add them first with favorite_manage({ action: \"add\", model: \"<ref>\" }).',\n };\n }\n profiles[input.name] = [...input.chain];\n await opts.updateConfig((cfg) => {\n cfg.fallbackProfiles = profiles;\n });\n return {\n status: 'ok',\n message: `\u2713 Profile \"${input.name}\" \u2192 ${input.chain.join(' \u2192 ')}`,\n profiles: { ...profiles },\n };\n }\n\n if (input.action === 'delete') {\n if (!input.name) {\n return { status: 'error', message: 'Provide \"name\" of the profile to delete.' };\n }\n if (!(input.name in profiles)) {\n return { status: 'error', message: `Profile \"${input.name}\" not found.` };\n }\n delete profiles[input.name];\n await opts.updateConfig((cfg) => {\n cfg.fallbackProfiles = profiles;\n });\n return {\n status: 'ok',\n message: `\u2713 Deleted profile: ${input.name}`,\n profiles: { ...profiles },\n };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\n// \u2500\u2500 4. AGENT_MODEL_ASSIGN \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst AGENT_MODEL_ASSIGN_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n role: {\n type: 'string',\n description:\n 'Matrix key: a catalog role (e.g. \"security-scanner\", \"bug-hunter\"), a phase ' +\n 'name (e.g. \"review\", \"implementation\"), or \"*\" for the fleet-wide default.',\n },\n provider: {\n type: 'string',\n description:\n 'Provider id (e.g. \"anthropic\", \"openai\"). When omitted, the leader provider is used. ' +\n 'The provider.model combination must be in your favorites list.',\n },\n model: {\n type: 'string',\n description:\n 'Model id (e.g. \"claude-haiku-3\", \"gpt-4o-mini\"). When omitted together with provider, ' +\n 'the role falls back to the leader model. Must be in your favorites list.',\n },\n profile: {\n type: 'string',\n description:\n 'Named fallback profile to assign (e.g. \"fast\", \"economy\"). Alternative to provider+model. ' +\n 'When set, the first profile entry becomes the primary model and the rest are the fallback chain.',\n },\n clear: {\n type: 'boolean',\n description:\n 'Set to true to remove the matrix entry for this role (it will fall through to phase/*/leader).',\n },\n },\n // Flattened from a top-level oneOf \u2014 Anthropic-family endpoints reject\n // top-level combinators (omniroute 400: \"input_schema does not support\n // oneOf, allOf, or anyOf at the top level\"). Combination rules are\n // enforced in the handler instead.\n required: ['role'],\n additionalProperties: false,\n};\n\ninterface AgentModelAssignInput {\n role: string;\n provider?: string | undefined;\n model?: string | undefined;\n profile?: string | undefined;\n clear?: boolean | undefined;\n}\n\ninterface AgentModelAssignOutput {\n status: 'ok' | 'error';\n message: string;\n role?: string;\n}\n\nfunction createAgentModelAssignTool(opts: FallbackManageToolOptions): Tool<AgentModelAssignInput, AgentModelAssignOutput> {\n return {\n name: AGENT_MODEL_ASSIGN_TOOL_NAME,\n description:\n 'Assign a provider/model or a fallback profile to a specific agent role, phase, ' +\n 'or the fleet-wide default. This is the LLM-accessible equivalent of /setmodel set. ' +\n 'The provider+model combination must be in your favorites list (unless only clearing). ' +\n 'Resolution precedence: exact role \u2192 phase \u2192 * \u2192 leader model.',\n usageHint:\n 'Use \"list\" as role to see current assignments. ' +\n 'Set with role + model, or role + provider + model, or role + profile. ' +\n 'Set role + clear=true to remove a matrix entry. ' +\n 'The provider/model must be a favorite.',\n category: 'Config',\n inputSchema: AGENT_MODEL_ASSIGN_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n\n // Reject conflicting combination rules \u2014 only one mode at a time\n const modes = [input.clear ? 'clear' : null, input.profile ? 'profile' : null, input.model ? 'model' : null].filter(Boolean);\n if (modes.length > 1) {\n return {\n status: 'error',\n message: `Conflicting assignment modes: ${modes.join(' + ')}. ` +\n 'Use exactly one: clear=true, profile=\"name\", or model=\"name\" (optionally with provider).',\n };\n }\n\n // Special case: \"list\" role shows current matrix\n if (input.role === 'list') {\n const matrix = (config.modelMatrix ?? {}) as Record<string, unknown>;\n const keys = Object.keys(matrix);\n if (keys.length === 0) {\n return { status: 'ok', message: 'No matrix assignments. All roles use the leader model.' };\n }\n const msg = keys.sort().map((k) => ` ${k} \u2192 ${JSON.stringify(matrix[k])}`).join('\\n');\n return { status: 'ok', message: `Model matrix (${keys.length} entries):\\n${msg}` };\n }\n\n // Validate key\n if (!isValidMatrixKey(input.role)) {\n return {\n status: 'error',\n message:\n `\"${input.role}\" is not a valid matrix key. Use a catalog role (e.g. \"security-scanner\"), ` +\n 'a phase (e.g. \"review\"), or \"*\" for the fleet-wide default.',\n };\n }\n\n // Clear entry\n if (input.clear) {\n const matrix = { ...((config.modelMatrix ?? {}) as Record<string, unknown>) };\n if (!(input.role in matrix)) {\n return { status: 'ok', message: `No matrix entry for \"${input.role}\" to clear.` };\n }\n delete matrix[input.role];\n await opts.updateConfig((cfg) => {\n cfg.modelMatrix = matrix;\n });\n return { status: 'ok', message: `\u2713 Cleared matrix entry for \"${input.role}\".` };\n }\n\n // Show current assignment for this role\n if (!input.model && !input.profile && !input.provider) {\n const matrix = (config.modelMatrix ?? {}) as Record<string, unknown>;\n const entry = matrix[input.role];\n if (!entry) {\n return { status: 'ok', message: `No specific assignment for \"${input.role}\". It uses the leader model or phase/* fallback.` };\n }\n return { status: 'ok', message: `\"${input.role}\" \u2192 ${JSON.stringify(entry)}` };\n }\n\n // Assign profile (no model required)\n if (input.profile && !input.model) {\n const profiles = profileList(config);\n if (!profiles[input.profile]) {\n return { status: 'error', message: `Profile \"${input.profile}\" not found. Create it with fallback_profile_manage first.` };\n }\n const matrix = { ...((config.modelMatrix ?? {}) as Record<string, unknown>) };\n matrix[input.role] = { fallbackProfile: input.profile };\n await opts.updateConfig((cfg) => {\n cfg.modelMatrix = matrix;\n });\n return { status: 'ok', message: `\u2713 \"${input.role}\" \u2192 profile: ${input.profile}` };\n }\n\n // Assign provider+model (must be a favorite)\n if (input.model) {\n const effectiveProvider = input.provider ?? config.provider;\n const ref = `${effectiveProvider}/${input.model}`;\n if (!isFavoriteRef(ref, config)) {\n return { status: 'error', message: notFavoriteError(ref, config) };\n }\n const matrix = { ...((config.modelMatrix ?? {}) as Record<string, unknown>) };\n const previousRuntime = (matrix[input.role] as Record<string, unknown>)?.modelRuntime;\n matrix[input.role] = input.provider\n ? { provider: input.provider, model: input.model, ...(previousRuntime ? { modelRuntime: previousRuntime } : {}) }\n : { model: input.model, ...(previousRuntime ? { modelRuntime: previousRuntime } : {}) };\n await opts.updateConfig((cfg) => {\n cfg.modelMatrix = matrix;\n });\n const display = input.provider ? `${input.provider}/${input.model}` : `${input.model} (leader provider)`;\n return { status: 'ok', message: `\u2713 \"${input.role}\" \u2192 ${display}` };\n }\n\n return { status: 'error', message: 'Provide model, profile, or clear=true for the role assignment.' };\n },\n };\n}\n\n// \u2500\u2500 5. Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// \u2500\u2500 5. PROVIDER_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PROVIDER_MANAGE_TOOL_NAME = 'provider_manage';\n\nconst PROVIDER_MANAGE_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'add', 'configure', 'remove'],\n description:\n 'Operation: list (show all providers), add (add a new provider config), ' +\n 'configure (update fields of an existing provider), remove (delete a provider config).',\n },\n provider: {\n type: 'string',\n description: 'Provider id (e.g. \"openai\", \"anthropic\"). Required for all actions except list.',\n },\n type: {\n type: 'string',\n description: 'Provider type (e.g. \"openai\", \"anthropic\"). Required for \"add\".',\n },\n models: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Model list to restrict visibility for this provider. Optional for add/configure.',\n },\n baseUrl: {\n type: 'string',\n description: 'Custom base URL (e.g. for self-hosted endpoints). Optional.',\n },\n family: {\n type: 'string',\n description:\n 'Wire-family override (e.g. \"openai\", \"openai-compatible\", \"anthropic\"). ' +\n 'When set, the provider can be constructed without a catalog entry.',\n },\n envVars: {\n type: 'array',\n items: { type: 'string' },\n description: 'Custom env var names to probe when apiKey is missing. Optional.',\n },\n autoDiscoverModels: {\n type: 'boolean',\n description: 'Auto-fetch model list from {baseUrl}/models. Optional.',\n },\n apiKey: {\n type: 'string',\n description:\n '**NOT RECOMMENDED** \u2014 use provider_key_set instead. ' +\n 'The LLM output may contain this value; use env var references for safety.',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface ProviderManageInput {\n action: 'list' | 'add' | 'configure' | 'remove';\n provider?: string | undefined;\n type?: string | undefined;\n models?: string[] | undefined;\n baseUrl?: string | undefined;\n family?: string | undefined;\n envVars?: string[] | undefined;\n autoDiscoverModels?: boolean | undefined;\n apiKey?: string | undefined;\n}\n\ninterface ProviderManageOutput {\n status: 'ok' | 'error';\n message: string;\n providers?: string[];\n}\n\nfunction createProviderManageTool(opts: FallbackManageToolOptions): Tool<ProviderManageInput, ProviderManageOutput> {\n return {\n name: PROVIDER_MANAGE_TOOL_NAME,\n description:\n 'View or configure provider entries. List all configured providers with their ' +\n 'type, model lists, base URL, and key status. Add new providers, update their ' +\n 'settings, or remove unused ones. API keys should be set via provider_key_set ' +\n 'instead of passing them here \u2014 they are visible in the LLM output.',\n usageHint:\n '\"list\" to see all providers. \"add\" with provider id and type to create. ' +\n '\"configure\" to update models, baseUrl, family, or envVars. ' +\n '\"remove\" to delete a provider. Use provider_key_set for API key management.',\n category: 'Config',\n inputSchema: PROVIDER_MANAGE_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const providers = {\n ...((config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>),\n };\n const leaderProvider: string = config.provider ?? '';\n\n if (input.action === 'list') {\n const ids = Object.keys(providers);\n if (ids.length === 0) {\n return { status: 'ok', message: 'No providers configured.', providers: [] };\n }\n const msg = ids.sort().map((id) => {\n const entry = providers[id] ?? {};\n const type = (entry.type as string) ?? '(unknown)';\n const models = Array.isArray(entry.models) ? (entry.models as string[]).join(', ') : '(all)';\n const hasKey = entry.apiKey ? '\u2713' : entry.apiKeys ? '\u2713' : '\u2717';\n const prefix = id === leaderProvider ? '\u2605 ' : ' ';\n const baseUrl = entry.baseUrl ? ` url:${entry.baseUrl}` : '';\n const family = entry.family ? ` family:${entry.family}` : '';\n return ` ${prefix}${id} (${type}) key:${hasKey} models:[${models}]${baseUrl}${family}`;\n }).join('\\n');\n return {\n status: 'ok',\n message: `Providers (leader: ${leaderProvider}):\\n${msg}`,\n providers: ids,\n };\n }\n\n if (input.action === 'add') {\n if (!input.provider || !input.type) {\n return { status: 'error', message: 'Provide \"provider\" (id) and \"type\" to add a provider.' };\n }\n if (providers[input.provider]) {\n return { status: 'error', message: `Provider \"${input.provider}\" already exists. Use \"configure\" to update.` };\n }\n const entry: Record<string, unknown> = { type: input.type };\n if (input.models) entry.models = input.models;\n if (input.baseUrl) entry.baseUrl = input.baseUrl;\n if (input.family) entry.family = input.family;\n if (input.envVars) entry.envVars = input.envVars;\n if (input.autoDiscoverModels !== undefined) entry.autoDiscoverModels = input.autoDiscoverModels;\n if (input.apiKey) entry.apiKey = input.apiKey;\n providers[input.provider] = entry;\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n return { status: 'ok', message: `\u2713 Added provider: ${input.provider} (type: ${input.type})` };\n }\n\n if (input.action === 'configure') {\n if (!input.provider) {\n return { status: 'error', message: 'Provide \"provider\" id to configure.' };\n }\n if (!providers[input.provider]) {\n return { status: 'error', message: `Provider \"${input.provider}\" not found. Use \"add\" first or check \"list\".` };\n }\n const entry: Record<string, unknown> = { ...providers[input.provider] };\n if (input.models !== undefined) entry.models = input.models;\n if (input.baseUrl !== undefined) entry.baseUrl = input.baseUrl || undefined;\n if (input.family !== undefined) entry.family = input.family || undefined;\n if (input.envVars !== undefined) entry.envVars = input.envVars;\n if (input.autoDiscoverModels !== undefined) entry.autoDiscoverModels = input.autoDiscoverModels;\n if (input.apiKey !== undefined) entry.apiKey = input.apiKey || undefined;\n providers[input.provider] = entry;\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n const updated = Object.keys({ ...entry }).filter((k) => k !== 'apiKey').join(', ');\n return { status: 'ok', message: `\u2713 Updated ${input.provider}: ${updated}` };\n }\n\n if (input.action === 'remove') {\n if (!input.provider) {\n return { status: 'error', message: 'Provide \"provider\" id to remove.' };\n }\n if (!providers[input.provider]) {\n return { status: 'error', message: `Provider \"${input.provider}\" not found.` };\n }\n if (input.provider === leaderProvider) {\n return { status: 'error', message: `Cannot remove the active leader provider \"${input.provider}\". Switch the leader first.` };\n }\n delete providers[input.provider];\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n return { status: 'ok', message: `\u2713 Removed provider: ${input.provider}` };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\n// \u2500\u2500 6. PROVIDER_KEY_SET \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PROVIDER_KEY_SET_TOOL_NAME = 'provider_key_set';\n\nconst PROVIDER_KEY_SET_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n provider: {\n type: 'string',\n description: 'Provider id (e.g. \"openai\", \"anthropic\"). Required.',\n },\n key: {\n type: 'string',\n description:\n 'The API key value. When provided directly, it is stored as the provider\\'s ' +\n 'primary key. \u26A0\uFE0F This value is visible to the LLM \u2014 for secrets, omit this field ' +\n 'and use envVar instead, or provide the key through the interactive prompt.',\n },\n envVar: {\n type: 'string',\n description:\n 'Environment variable name that contains the key (e.g. \"OPENAI_API_KEY\"). ' +\n 'The key is read from the environment at tool execution time \u2014 the value is never ' +\n 'visible to the LLM. Preferred over passing the key directly.',\n },\n label: {\n type: 'string',\n description:\n 'Optional label for the key entry (e.g. \"work\", \"personal\"). Useful when managing multiple keys.',\n },\n setActive: {\n type: 'boolean',\n description: 'Whether to make this the active key. Default: true.',\n },\n },\n // Flattened from a top-level oneOf \u2014 Anthropic-family endpoints reject\n // top-level combinators (omniroute 400). Combination rules are enforced\n // in the handler instead.\n required: ['provider'],\n additionalProperties: false,\n};\n\ninterface ProviderKeySetInput {\n provider: string;\n key?: string | undefined;\n envVar?: string | undefined;\n label?: string | undefined;\n setActive?: boolean | undefined;\n}\n\ninterface ProviderKeySetOutput {\n status: 'ok' | 'error' | 'needs_key';\n message: string;\n}\n\nfunction createProviderKeySetTool(opts: FallbackManageToolOptions): Tool<ProviderKeySetInput, ProviderKeySetOutput> {\n return {\n name: PROVIDER_KEY_SET_TOOL_NAME,\n description:\n 'Set the API key for a provider. For security, prefer using envVar (reads from ' +\n 'environment variable, value never visible to the LLM) over passing the key directly. ' +\n 'When neither key nor envVar is provided, the tool returns a prompt for interactive key entry \u2014 ' +\n 'the UI will present an input field and the key is stored without LLM visibility.\\n\\n' +\n 'After setting a key, the provider becomes usable for model assignments and fallback chains. ' +\n 'Add its models to favorites with favorite_manage to unlock them for fallback/profile use.',\n usageHint:\n 'Preferred: provider_key_set({ provider: \"openai\", envVar: \"OPENAI_API_KEY\" }). ' +\n 'For interactive input: provider_key_set({ provider: \"openai\" }) \u2014 the UI will prompt. ' +\n 'Direct key: provider_key_set({ provider: \"openai\", key: \"sk-...\" }) \u2014 visible to LLM.',\n category: 'Config',\n inputSchema: PROVIDER_KEY_SET_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const providers = {\n ...((config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>),\n };\n\n // Reject when both key and envVar are supplied \u2014 ambiguous intent\n if (input.key && input.envVar) {\n return {\n status: 'error',\n message: 'Provide either key (direct, visible to LLM) OR envVar (reads from environment, ' +\n 'never visible to LLM), not both. Use envVar for security.',\n };\n }\n\n // If no key or envVar is given, request interactive input\n if (!input.key && !input.envVar) {\n // Interactive input via host callback \u2014 LLM never sees the value\n if (opts.requestInput) {\n try {\n const value = await opts.requestInput(\n `Enter API key for \"${input.provider}\" (will be stored securely, LLM will not see it):`,\n );\n if (!value || value.trim().length === 0) {\n return { status: 'error', message: 'No key was entered. Operation cancelled.' };\n }\n return storeProviderKey(providers, input, value.trim(), opts);\n } catch (err) {\n return {\n status: 'error',\n message: `Interactive input failed or was cancelled: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n // No interactive callback \u2014 return a status the host can intercept\n return {\n status: 'needs_key',\n message:\n `To set the API key for \"${input.provider}\", use provider_key_set ` +\n `with either:\\n` +\n ` 1. envVar: \"${input.provider.toUpperCase()}_API_KEY\" (reads from env, LLM never sees it)\\n` +\n ` 2. key: \"sk-...\" (pass directly, visible to LLM)\\n\\n` +\n `Interactive key entry is handled by the UI \u2014 enter your key through the prompt surface.`,\n };\n }\n\n // Read from environment variable\n if (input.envVar) {\n const envValue = process.env[input.envVar];\n if (!envValue) {\n return {\n status: 'error',\n message: `Environment variable \"${input.envVar}\" is not set or empty. ` +\n `Set it first or use a different envVar.`,\n };\n }\n return storeProviderKey(providers, input, envValue, opts);\n }\n\n // Key provided directly\n if (input.key) {\n return storeProviderKey(providers, input, input.key, opts);\n }\n\n return { status: 'error', message: 'Unexpected \u2014 no key source available.' };\n },\n };\n}\n\n// \u2500\u2500 7. LEADER_MODEL_SET \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const LEADER_MODEL_SET_TOOL_NAME = 'leader_model_set';\n\nconst LEADER_MODEL_SET_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['show', 'set', 'profile', 'toggle'],\n description:\n 'Operation: show (current leader + toggles), set (change provider/model), ' +\n 'profile (set from a fallback profile), toggle (change fallbackAuto/favoriteModelsOnly).',\n },\n provider: {\n type: 'string',\n description: 'Provider id for the leader (e.g. \"anthropic\", \"openai\"). Required for \"set\".',\n },\n model: {\n type: 'string',\n description: 'Model id for the leader (e.g. \"claude-sonnet-4-20250514\"). Required for \"set\".',\n },\n profile: {\n type: 'string',\n description: 'Fallback profile name to derive the leader + chain from. Required for \"profile\".',\n },\n toggle: {\n type: 'string',\n enum: ['fallbackAuto', 'favoriteModelsOnly'],\n description: 'Which toggle to change. Required for \"toggle\".',\n },\n value: {\n type: 'boolean',\n description: 'New value for the toggle. Required for \"toggle\".',\n },\n },\n additionalProperties: false,\n};\n\ninterface LeaderModelSetInput {\n action: 'show' | 'set' | 'profile' | 'toggle';\n provider?: string | undefined;\n model?: string | undefined;\n profile?: string | undefined;\n toggle?: 'fallbackAuto' | 'favoriteModelsOnly' | undefined;\n value?: boolean | undefined;\n}\n\ninterface LeaderModelSetOutput {\n status: 'ok' | 'error';\n message: string;\n}\n\nfunction createLeaderModelSetTool(opts: FallbackManageToolOptions): Tool<LeaderModelSetInput, LeaderModelSetOutput> {\n return {\n name: LEADER_MODEL_SET_TOOL_NAME,\n description:\n 'View or change the leader provider/model and system toggles. The leader is the ' +\n 'primary model used for the main agent interactions. ' +\n '\"set\" changes it directly. \"profile\" derives it from a named fallback profile ' +\n '(first entry becomes leader, rest become the fallback chain). ' +\n '\"toggle\" controls fallbackAuto (smart default fallback) and favoriteModelsOnly ' +\n '(restrict auto-fallback to favorites only).',\n usageHint:\n '\"show\" to see current state. \"set\" with provider+model to change. ' +\n '\"profile\" with name to derive from a profile. ' +\n '\"toggle\" with toggle name and value to change a boolean setting.',\n category: 'Config',\n inputSchema: LEADER_MODEL_SET_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n\n if (input.action === 'show') {\n const lines: string[] = [\n ` ${'leader'}: ${config.provider}/${config.model}`,\n ` ${'fallbackAuto'}: ${config.fallbackAuto !== false ? 'on' : 'off'}`,\n ` ${'favoriteModelsOnly'}: ${config.favoriteModelsOnly ? 'on' : 'off'}`,\n '',\n ` ${'fallback models'}: ${(config.fallbackModels ?? []).length > 0 ? (config.fallbackModels ?? []).join(' \u2192 ') : 'empty (auto fallback)'}`,\n ` ${'favorites'}: ${(config.favoriteModels ?? []).length > 0 ? `${(config.favoriteModels ?? []).length} models` : '(none)'}`,\n ` ${'refiner'}: ${config.autonomy?.refinerProvider ? `${config.autonomy.refinerProvider}/${config.autonomy.refinerModel ?? '(default model)'}` : '(same as leader)'}`,\n ];\n return { status: 'ok', message: lines.join('\\n') };\n }\n\n if (input.action === 'set') {\n if (!input.provider || !input.model) {\n return { status: 'error', message: 'Provide \"provider\" and \"model\" for the leader.' };\n }\n await opts.updateConfig((cfg) => {\n cfg.provider = input.provider;\n cfg.model = input.model;\n });\n return { status: 'ok', message: `\u2713 Leader \u2192 ${input.provider}/${input.model}` };\n }\n\n if (input.action === 'profile') {\n if (!input.profile) {\n return { status: 'error', message: 'Provide \"profile\" name to derive the leader from.' };\n }\n const profiles = (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n const chain = profiles[input.profile];\n if (!chain || chain.length === 0) {\n return { status: 'error', message: `Profile \"${input.profile}\" not found or empty.` };\n }\n // Parse first entry as leader provider/model\n const first = chain[0]!;\n const p = parseRefInternal(first);\n const provider = p.provider ?? config.provider;\n const model = p.model;\n if (!model) {\n return { status: 'error', message: `Cannot parse \"${first}\" as a valid model reference.` };\n }\n const rest = chain.slice(1);\n await opts.updateConfig((cfg) => {\n cfg.provider = provider;\n cfg.model = model;\n cfg.fallbackModels = rest;\n });\n return {\n status: 'ok',\n message: `\u2713 Leader \u2192 ${provider}/${model} (profile: ${input.profile})` +\n (rest.length > 0 ? `\\n Fallback chain: ${rest.join(' \u2192 ')}` : ''),\n };\n }\n\n if (input.action === 'toggle') {\n if (!input.toggle || input.value === undefined) {\n return { status: 'error', message: 'Provide \"toggle\" (fallbackAuto | favoriteModelsOnly) and \"value\" (boolean).' };\n }\n await opts.updateConfig((cfg) => {\n if (input.toggle === 'fallbackAuto') {\n cfg.fallbackAuto = input.value;\n } else if (input.toggle === 'favoriteModelsOnly') {\n cfg.favoriteModelsOnly = input.value;\n }\n });\n return {\n status: 'ok',\n message: `\u2713 ${input.toggle} \u2192 ${input.value ? 'on' : 'off'}`,\n };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\n// \u2500\u2500 Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Create all 8 provider/model/fallback management tools that LLMs can call.\n *\n * Register them all in the tool registry:\n * ```ts\n * const tools = createFallbackManageTools({ getConfig, updateConfig });\n * for (const tool of tools) toolRegistry.register(tool);\n * ```\n */\nexport function createFallbackManageTools(opts: FallbackManageToolOptions): Tool[] {\n return [\n createFavoriteManageTool(opts),\n createFallbackChainManageTool(opts),\n createFallbackProfileManageTool(opts),\n createAgentModelAssignTool(opts),\n createProviderManageTool(opts),\n createProviderKeySetTool(opts),\n createLeaderModelSetTool(opts),\n createSystemConfigViewTool(opts),\n ];\n}\n", "/** 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 * Well-known tool capabilities used for authorization decisions.\n *\n * These are the preferred values for `Tool.capabilities`.\n * New capabilities should be added here with clear documentation.\n *\n * Philosophy (2026-06+):\n * - Prefer capabilities over exact tool name matching.\n * - Subagent guards and future policies should primarily key off capabilities.\n * - Name-based denylists are legacy and will be phased down.\n */\nexport const ToolCapabilities = {\n /** Can execute arbitrary commands in the user's shell (the `bash` tool). */\n SHELL_ARBITRARY: 'shell.arbitrary',\n\n /** Can execute a restricted set of commands (the `exec` tool). */\n SHELL_RESTRICTED: 'shell.restricted',\n\n /** Can run a restricted project formatter/linter-style command. */\n SHELL_EXEC: 'shell.exec',\n\n /** Can read files inside the project (and possibly outside via symlinks if not guarded). */\n FS_READ: 'fs.read',\n\n /** Can write / modify / delete files inside the project. */\n FS_WRITE: 'fs.write',\n\n /** Can write files outside the current project root (very high risk). */\n FS_WRITE_OUTSIDE_PROJECT: 'fs.write.outside-project',\n\n /** Can perform outbound network requests. */\n NET_OUTBOUND: 'net.outbound',\n\n /** Can mutate in-memory session todos only. */\n SESSION_TODO: 'session.todo',\n\n /** Can mutate in-memory session mode only. */\n SESSION_MODE: 'session.mode',\n\n /** Can inspect registered tool metadata. */\n TOOL_META: 'tool.meta',\n\n /** Can invoke arbitrary registered tools through a meta-tool. */\n TOOL_MUTATE_ANY: 'tool.mutate.any',\n\n /** Can read persistent memory. */\n MEMORY_READ: 'memory.read',\n\n /** Can write persistent memory. */\n MEMORY_WRITE: 'memory.write',\n\n /** Can delete persistent memory. */\n MEMORY_DELETE: 'memory.delete',\n\n /** Proxies tools from external MCP servers (unknown capability). */\n MCP_PROXY: 'mcp.proxy',\n\n /** Can spawn or manage subagents / multi-agent tasks. */\n SUBAGENT_SPAWN: 'subagent.spawn',\n\n /** Can inspect fleet/subagent coordination state without mutating it. */\n COORDINATION_FLEET_READ: 'coordination.fleet.read',\n\n /** Can publish attributed, schema-checked events onto the fleet bus. */\n COORDINATION_FLEET_EMIT: 'coordination.fleet.emit',\n\n /** Can submit a task-local structured result to the parent Director. */\n COORDINATION_RESULT_SUBMIT: 'coordination.result.submit',\n\n /** Can read or write inter-agent mailbox messages. */\n COORDINATION_MAIL: 'coordination.mail',\n\n /** Can schedule, inspect, or cancel in-session cron jobs. */\n COORDINATION_CRON: 'coordination.cron',\n\n /** Can mutate global or session configuration / trust state. */\n CONFIG_MUTATE: 'config.mutate',\n\n /** Can install packages or run package managers with side effects. */\n PACKAGE_INSTALL: 'package.install',\n} as const;\n\nexport type ToolCapability = (typeof ToolCapabilities)[keyof typeof ToolCapabilities];\n\n/**\n * Set of capabilities that are considered dangerous for subagents by default.\n * Subagents should not receive these capabilities unless the leader explicitly\n * allows the specific tool at spawn time.\n */\nexport const DANGEROUS_FOR_SUBAGENTS: readonly ToolCapability[] = [\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,\n ToolCapabilities.TOOL_MUTATE_ANY,\n ToolCapabilities.MEMORY_WRITE,\n ToolCapabilities.MEMORY_DELETE,\n ToolCapabilities.MCP_PROXY,\n ToolCapabilities.SUBAGENT_SPAWN,\n ToolCapabilities.CONFIG_MUTATE,\n ToolCapabilities.PACKAGE_INSTALL,\n];\n\n/**\n * Wide capability allowlist for subagents that the user has authorized to act\n * with full developer power (the CLI fleet host applies this to any subagent\n * that isn't given an explicit, narrower grant). It covers everything needed to\n * do real work end-to-end \u2014 read, write/edit inside the project, outbound\n * network, all shell/build/install capabilities, session todos, tool metadata, and read-only\n * memory lookup \u2014 so a delegated coding or build agent runs the same toolchain\n * the leader would, without per-tool confirmation it cannot answer.\n *\n * Deliberately EXCLUDED (require an explicit per-spawn `allowedCapabilities`\n * grant, because they escape the task's blast radius rather than perform it):\n * - `fs.write.outside-project` \u2014 writing outside the repo (e.g. ~/.ssh).\n * - `tool.mutate.any` \u2014 arbitrary meta-tool dispatch.\n * - `memory.write` / `memory.delete` \u2014 persistent memory mutation.\n * - `mcp.proxy` \u2014 third-party MCP tools (also hard-blocked by name).\n * - `subagent.spawn` \u2014 recursive delegation (the baseline prompt forbids it).\n * - `config.mutate` \u2014 rewriting trust/config is privilege escalation, not work.\n */\nexport const WIDE_SUBAGENT_CAPABILITIES: readonly ToolCapability[] = [\n ToolCapabilities.FS_READ,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.NET_OUTBOUND,\n ToolCapabilities.SESSION_TODO,\n ToolCapabilities.TOOL_META,\n ToolCapabilities.MEMORY_READ,\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.PACKAGE_INSTALL,\n // Read-only fleet visibility (fleet_status) \u2014 peer awareness has no blast\n // radius and every fleet worker should coordinate around its peers.\n ToolCapabilities.COORDINATION_FLEET_READ,\n ToolCapabilities.COORDINATION_RESULT_SUBMIT,\n];\n\n/**\n * Check if a tool (or its capabilities array) includes any dangerous capability\n * for subagent execution.\n */\nexport function hasDangerousCapabilityForSubagents(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability));\n}\n\n/**\n * Check if a tool declares a specific capability (or any of the provided ones).\n */\nexport function hasCapability(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n capability: ToolCapability | ToolCapability[],\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n const toCheck = Array.isArray(capability) ? capability : [capability];\n return toCheck.some((c) => caps.includes(c));\n}\n\n/**\n * Returns the intersection of a tool's capabilities with the dangerous set.\n * Useful for logging and audit trails.\n */\nexport function getDangerousCapabilities(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): ToolCapability[] {\n if (!toolOrCaps) return [];\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.filter((c): c is ToolCapability =>\n DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability),\n );\n}\n", "import type { MCPServerConfig } from '../types/config.js';\n\n/**\n * Built-in MCP server presets available to all WrongStack users out of the box.\n * These servers must be explicitly enabled in config (disabled by default).\n *\n * To enable: set `mcpServers: { serverName: { enabled: true } }` in your config.\n *\n * Some servers require environment variables or additional config \u2014 see notes below.\n *\n * Transport types:\n * stdio \u2014 spawns a local npm package binary via child_process\n * sse \u2014 HTTP SSE endpoint (client POSTs requests)\n * streamable-http \u2014 session-based HTTP with NDJSON responses\n */\n\n/** Filesystem access: read, write, list, search, tree. Good for exploring projects. */\nexport const filesystemServer = (): MCPServerConfig => ({\n name: 'filesystem',\n description: 'Read, write, and navigate the local filesystem (read-heavy tools)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],\n permission: 'confirm',\n});\n\n/** GitHub API: issues, PRs, repos, search, file operations. Requires GITHUB_PERSONAL_ACCESS_TOKEN. */\nexport const githubServer = (): MCPServerConfig => ({\n name: 'github',\n description:\n 'GitHub API \u2014 issues, PRs, repos, search, file ops (requires GITHUB_PERSONAL_ACCESS_TOKEN)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n passthroughEnv: ['GITHUB_PERSONAL_ACCESS_TOKEN', 'GITHUB_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Context7 \u2014 codebase-aware documentation and Q&A using context from your code.\n * Live documentation for any library, grounded in your actual versions.\n */\nexport const context7Server = (): MCPServerConfig => ({\n name: 'context7',\n description: 'Codebase-aware documentation and Q&A (context7.ai)',\n transport: 'streamable-http',\n url: 'https://mcp.context7.com/mcp',\n permission: 'confirm',\n});\n\n/**\n * Brave Search \u2014 web search via Brave Browser's API.\n * Requires BRAVE_SEARCH_API_KEY. Free tier: 2,000 queries/month.\n * Sign up at https://api.search.brave.com/\n */\nexport const braveSearchServer = (): MCPServerConfig => ({\n name: 'brave-search',\n description: 'Web search (Brave). Requires BRAVE_SEARCH_API_KEY \u2014 free tier 2k queries/month',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n passthroughEnv: ['BRAVE_SEARCH_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Block (Block, Inc.) \u2014 Postgres database access via SQL.\n * Useful for running queries against a connected database during development.\n */\nexport const blockServer = (): MCPServerConfig => ({\n name: 'block',\n description: 'Postgres database access via SQL (Block MCP server)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-block'],\n permission: 'confirm',\n});\n\n/**\n * EverArt \u2014 AI image generation via various providers.\n * Requires EVERART_API_KEY.\n */\nexport const everArtServer = (): MCPServerConfig => ({\n name: 'everart',\n description: 'AI image generation (EverArt). Requires EVERART_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-everart'],\n passthroughEnv: ['EVERART_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Slack \u2014 messaging, channels, search.\n * Requires SLACK_BOT_TOKEN and either SLACK_TEAM_ID or SLACK_USER_TOKEN.\n */\nexport const slackServer = (): MCPServerConfig => ({\n name: 'slack',\n description: 'Slack \u2014 messaging, channels, search. Requires SLACK_BOT_TOKEN + SLACK_TEAM_ID',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-slack'],\n passthroughEnv: ['SLACK_BOT_TOKEN', 'SLACK_TEAM_ID'],\n permission: 'confirm',\n});\n\n/**\n * AWS knowledge base \u2014 EC2, S3, Lambda, IAM, CloudFormation, cost management.\n * Requires AWS access key + secret in environment.\n */\nexport const awsServer = (): MCPServerConfig => ({\n name: 'aws',\n description: 'AWS \u2014 EC2, S3, Lambda, IAM, CloudFormation, costs. Requires AWS credentials',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-aws'],\n passthroughEnv: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_REGION', 'AWS_SESSION_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Google Maps \u2014 directions, distance matrix, geocoding, places.\n * Requires GOOGLE_MAPS_API_KEY.\n */\nexport const googleMapsServer = (): MCPServerConfig => ({\n name: 'google-maps',\n description: 'Google Maps \u2014 directions, geocoding, places. Requires GOOGLE_MAPS_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-google-maps'],\n passthroughEnv: ['GOOGLE_MAPS_API_KEY'],\n permission: 'confirm',\n});\n\n/** Sentinel \u2014 security vulnerability scanning (sentinel-labs). */\nexport const sentinelServer = (): MCPServerConfig => ({\n name: 'sentinel',\n description: 'Security vulnerability scanning (Sentinel)',\n transport: 'streamable-http',\n url: 'https://mcp.sentinel.ai',\n permission: 'deny', // security tool \u2014 require explicit confirmation\n});\n\n/**\n * Z.AI Vision MCP \u2014 image understanding fallback for text-only models.\n * Requires Z_AI_API_KEY. Tools are read-only and safe to run automatically.\n */\nexport const zaiVisionServer = (): MCPServerConfig => ({\n name: 'zai-vision',\n description: 'Z.AI Vision MCP \u2014 image analysis and screenshot understanding',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@z_ai/mcp-server@latest'],\n env: { Z_AI_MODE: 'ZAI' },\n passthroughEnv: ['Z_AI_API_KEY'],\n allowedTools: [\n 'image_analysis',\n 'extract_text_from_screenshot',\n 'diagnose_error_screenshot',\n 'understand_technical_diagram',\n 'analyze_data_visualization',\n 'ui_diff_check',\n ],\n permission: 'auto',\n});\n\n/**\n * Playwright \u2014 browser automation: navigate, click, type, screenshot, evaluate JS.\n * Spawns a headless Chromium browser via @modelcontextprotocol/server-playwright.\n * Tools can read and interact with live web pages \u2014 permission defaults to\n * `confirm` because form submission / DOM mutation is possible.\n */\nexport const playwrightServer = (): MCPServerConfig => ({\n name: 'playwright',\n description:\n 'Browser automation \u2014 navigate, screenshot, click, type, evaluate JS (headless Chromium)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-playwright'],\n permission: 'confirm',\n});\n\n/**\n * MiniMax Token Plan MCP \u2014 search + understand_image.\n * This preset exposes only the read-only image understanding tool by default.\n * Requires MINIMAX_API_KEY and uvx on PATH.\n */\nexport const miniMaxVisionServer = (): MCPServerConfig => ({\n name: 'minimax-vision',\n description: 'MiniMax MCP \u2014 image understanding via understand_image',\n transport: 'stdio',\n command: 'uvx',\n args: ['minimax-coding-plan-mcp', '-y'],\n env: {\n MINIMAX_MCP_BASE_PATH: './.wrongstack/minimax-output',\n MINIMAX_API_HOST: 'https://api.minimax.io',\n MINIMAX_API_RESOURCE_MODE: 'url',\n },\n passthroughEnv: ['MINIMAX_API_KEY'],\n allowedTools: ['understand_image'],\n permission: 'auto',\n});\n\n/**\n * SSH Manager \u2014 remote SSH execution, file transfer, tunnels, health checks, and deployment ops.\n * Server credentials are intentionally NOT embedded here. Configure hosts via mcp-ssh-manager's\n * env/TOML config (for example SSH_SERVER_<NAME>_HOST, USER, KEYPATH/PASSWORD) or ssh-agent.\n */\nexport const sshManagerServer = (): MCPServerConfig => ({\n name: 'ssh',\n description:\n 'Remote SSH management \u2014 execute commands, transfer files, tunnels, health checks (mcp-ssh-manager)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', 'mcp-ssh-manager'],\n env: {\n MCP_SSH_COMPACT_JSON: 'true',\n MCP_SSH_DEFAULT_TIMEOUT: '120000',\n },\n permission: 'confirm',\n requestTimeoutMs: 180_000,\n});\n\n/** Everything bundled \u2014 full set of built-in servers. Useful for `wstack mcp add --all`. */\nexport const allServers = (): Record<string, MCPServerConfig> => ({\n filesystem: { ...filesystemServer(), enabled: false },\n github: { ...githubServer(), enabled: false },\n context7: { ...context7Server(), enabled: false },\n 'brave-search': { ...braveSearchServer(), enabled: false },\n block: { ...blockServer(), enabled: false },\n everart: { ...everArtServer(), enabled: false },\n slack: { ...slackServer(), enabled: false },\n aws: { ...awsServer(), enabled: false },\n 'google-maps': { ...googleMapsServer(), enabled: false },\n sentinel: { ...sentinelServer(), enabled: false },\n 'zai-vision': { ...zaiVisionServer(), enabled: false },\n 'minimax-vision': { ...miniMaxVisionServer(), enabled: false },\n playwright: { ...playwrightServer(), enabled: false },\n ssh: { ...sshManagerServer(), enabled: false },\n});\n", "import * as fs from 'node:fs/promises';\nimport { atomicWrite } from './atomic-write.js';\n\nexport type JsonObject = Record<string, unknown>;\nexport type JsonPathSegment = string | number;\nexport type JsonPath = readonly JsonPathSegment[];\n\nexport async function readJsonObjectFile(filePath: string): Promise<JsonObject> {\n try {\n const parsed = JSON.parse(await fs.readFile(filePath, 'utf8')) as unknown;\n return isJsonObject(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport async function jsonObjectFileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function writeJsonObjectFile(filePath: string, value: JsonObject): Promise<void> {\n await atomicWrite(filePath, JSON.stringify(value, null, 2), { mode: 0o600 });\n}\n\nexport async function updateJsonObjectFile(\n filePath: string,\n mutator: (config: JsonObject) => void | JsonObject | Promise<void | JsonObject>,\n): Promise<JsonObject> {\n const config = await readJsonObjectFile(filePath);\n const maybeNext = await mutator(config);\n const next = maybeNext && isJsonObject(maybeNext) ? maybeNext : config;\n await writeJsonObjectFile(filePath, next);\n return next;\n}\n\nexport function getJsonPath(root: unknown, path: JsonPath): unknown {\n let current = root;\n for (const segment of path) {\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) return undefined;\n current = current[segment];\n continue;\n }\n if (!isJsonObject(current)) return undefined;\n current = current[segment];\n }\n return current;\n}\n\nexport function setJsonPath(root: JsonObject, path: JsonPath, value: unknown): JsonObject {\n if (path.length === 0) {\n if (!isJsonObject(value)) throw new Error('Root config value must be an object');\n return value;\n }\n const parent = ensureJsonParent(root, path);\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent)) throw new Error(`Cannot set numeric segment ${leaf} on non-array parent`);\n parent[leaf] = value;\n } else {\n if (!isJsonObject(parent)) throw new Error(`Cannot set property ${leaf} on non-object parent`);\n parent[leaf] = value;\n }\n return root;\n}\n\nexport function removeJsonPath(root: JsonObject, path: JsonPath): boolean {\n if (path.length === 0) return false;\n const parent = getJsonPath(root, path.slice(0, -1));\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent) || leaf < 0 || leaf >= parent.length) return false;\n parent.splice(leaf, 1);\n return true;\n }\n if (!isJsonObject(parent) || !(leaf in parent)) return false;\n delete parent[leaf];\n return true;\n}\n\nexport async function setJsonPathInFile(filePath: string, path: JsonPath, value: unknown): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => setJsonPath(config, path, value));\n}\n\nexport async function removeJsonPathInFile(filePath: string, path: JsonPath): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => {\n removeJsonPath(config, path);\n });\n}\n\nexport function isJsonObject(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction lastPathSegment(path: JsonPath): JsonPathSegment {\n const segment = path[path.length - 1];\n /* v8 ignore next -- defensive: callers guard path.length === 0 before here */\n if (segment === undefined) throw new Error('Invalid empty JSON path');\n return segment;\n}\n\nfunction ensureJsonParent(root: JsonObject, path: JsonPath): JsonObject | unknown[] {\n let current: JsonObject | unknown[] = root;\n for (let i = 0; i < path.length - 1; i += 1) {\n const segment = path[i];\n const nextSegment = path[i + 1];\n /* v8 ignore next -- defensive: sparse-array paths are never produced by callers */\n if (segment === undefined) throw new Error('Invalid empty JSON path segment');\n const nextContainer = typeof nextSegment === 'number' ? [] : {};\n\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) throw new Error(`Cannot traverse numeric segment ${segment} on non-array parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n } else {\n if (!isJsonObject(current)) throw new Error(`Cannot traverse property ${segment} on non-object parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n }\n }\n return current;\n}\n", "import type { FileHandle } from 'node:fs/promises';\nimport {\n type AtomicWriteOptions,\n createPersistencePrimitives,\n type FileLockOptions,\n} from '@wrongstack/persistence';\nimport { FsError } from '../types/errors.js';\n\nexport type { AtomicWriteOptions, FileLockOptions } from '@wrongstack/persistence';\n\nconst primitives = createPersistencePrimitives({\n createLockTimeoutError: ({ targetPath, timeoutMs }) =>\n new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n }),\n});\n\nexport const atomicWrite: (\n targetPath: string,\n content: string | Uint8Array,\n opts?: AtomicWriteOptions,\n) => Promise<void> = primitives.atomicWrite;\n/**\n * Atomic replace that streams its new contents instead of taking them as one\n * buffer. Use when the replacement is large enough that materializing it would\n * itself be the memory problem (log rotation, tail compaction).\n */\nexport const atomicReplaceWithWriter: <T>(\n targetPath: string,\n write: (handle: FileHandle) => Promise<T>,\n opts?: AtomicWriteOptions,\n) => Promise<T> = primitives.atomicReplaceWithWriter;\nexport const ensureDir: (dir: string) => Promise<void> = primitives.ensureDir;\nexport const withFileLock: <T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts?: FileLockOptions,\n) => Promise<T> = primitives.withFileLock;\n", "import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { ToolCapabilities } from '../security/capabilities.js';\n/**\n * `mcp_control` \u2014 LLM-driven MCP server lifecycle management.\n *\n * The model calls this tool to:\n * list \u2014 see all known servers (running or not) without starting any\n * search \u2014 filter the server catalog by name or description keyword\n * enable \u2014 start a server and register its tools\n * disable \u2014 stop a server and unregister its tools\n * restart \u2014 stop then re-start a running server\n *\n * This is the primary mechanism by which the LLM autonomously extends its\n * own capabilities at runtime \u2014 e.g. \"I need GitHub access, let me enable it.\"\n */\nimport { allServers } from '../infrastructure/mcp-servers.js';\nimport { readJsonObjectFile, setJsonPath, updateJsonObjectFile } from '../utils/config-json.js';\nimport type { Config, JSONSchema, MCPServerConfig, Tool } from '../index.js';\nexport interface MCPRegistryHandle {\n start(cfg: MCPServerConfig): Promise<void>;\n stop(name: string): Promise<void>;\n restart(name: string): Promise<void>;\n describe(): {\n name: string;\n state: string;\n toolCount: number;\n enabled: boolean;\n tools?: string[];\n }[];\n list(): { name: string; state: string; toolCount: number; tools?: string[] }[];\n /**\n * Register all cached tools for a server without restarting it.\n * No-op if the server is not connected or tools are already active.\n * Used in token-saving mode to temporarily expose MCP tools.\n */\n activateServer?(name: string): void;\n /**\n * Unregister all tools for a server without disconnecting it.\n * Returns the number of tools that were deactivated.\n * Used in token-saving mode to hide MCP tools after use.\n */\n deactivateServer?(name: string): number;\n /**\n * Check whether a server's tools are currently registered.\n */\n isActivated?(name: string): boolean;\n}\n\nexport interface CreateMcpControlToolOptions {\n /**\n * Read the current config object. The tool never mutates this directly \u2014\n * writes go to the global config file via `configPath`.\n */\n getConfig: () => Config;\n /**\n * Path to the active profile config for atomic config writes.\n */\n configPath: string;\n /**\n * Live MCP registry for runtime start/stop/restart. The tool calls these\n * immediately so the LLM sees the result of its action in the same turn.\n */\n registry: MCPRegistryHandle;\n}\n\nexport function createMcpControlTool(opts: CreateMcpControlToolOptions): Tool {\n const { getConfig, configPath, registry } = opts;\n\n const inputSchema: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'search', 'enable', 'disable', 'restart', 'activate', 'deactivate'],\n description: 'The management action to perform. activate/deactivate toggle tool registration ephemerally without disconnecting.',\n },\n /** Filter for `search`. Matches server name or description case-insensitively. */\n query: {\n type: 'string',\n description: 'Search term for `search` action. Matches server name or description.',\n },\n /** Target server name for `enable`, `disable`, `restart`, `activate`, `deactivate`. */\n server: {\n type: 'string',\n description: 'Server name (e.g. \"github\", \"filesystem\", \"brave-search\").',\n },\n },\n required: ['action'],\n };\n\n return {\n name: 'mcp_control',\n description:\n 'Manage MCP server lifecycle: list available servers, search by name or capability, enable or disable servers at runtime, restart running servers. Use activate/deactivate to ephemerally toggle tool registration without disconnecting \u2014 ideal for token-saving mode where MCP tools are lazy-loaded on demand. NOTE: `enable`/`restart` start a server process, which for the built-in stdio presets runs `npx -y <package>` \u2014 i.e. it fetches and executes an npm package from the network. Treat it as code execution.',\n category: 'mcp',\n permission: 'confirm',\n mutating: true,\n // `enable`/`restart` spawn a server process that, for the stdio presets,\n // fetches and runs an npm package (`npx -y <pkg>`) \u2014 effectively remote\n // code execution. Marking the tool destructive preserves risk metadata for\n // UI/audit surfaces; YOLO itself still auto-approves unless an explicit\n // deny rule blocks the call. Read-only actions (list/search) ride the same\n // tool but are cheap to confirm/trust once when YOLO is off.\n riskTier: 'destructive',\n capabilities: [ToolCapabilities.CONFIG_MUTATE],\n inputSchema,\n async execute(raw) {\n const input = raw as { action: string; query?: string | undefined; server?: string | undefined };\n return mcpControlDispatch(input, { getConfig, configPath, registry });\n },\n };\n}\n\n// \u2500\u2500 Dispatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function mcpControlDispatch(\n input: { action: string; query?: string | undefined; server?: string | undefined },\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const { action, query, server } = input;\n\n switch (action) {\n case 'list': return renderList(deps);\n case 'search': return renderSearch(query ?? '', deps);\n case 'enable': return server ? runEnable(server, deps) : '`server` is required for enable.';\n case 'disable': return server ? runDisable(server, deps) : '`server` is required for disable.';\n case 'restart': return server ? runRestart(server, deps) : '`server` is required for restart.';\n case 'activate': return server ? runActivate(server, deps) : '`server` is required for activate.';\n case 'deactivate': return server ? runDeactivate(server, deps) : '`server` is required for deactivate.';\n default:\n return `Unknown action \"${action}\". Use one of: list, search, enable, disable, restart, activate, deactivate.`;\n }\n}\n\n// \u2500\u2500 Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function renderList(deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle }): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const live = deps.registry.describe();\n\n if (Object.keys(configured).length === 0) {\n return [\n 'No MCP servers configured.',\n ' Use `mcp_control({ action: \"search\" })` to see available presets,',\n ' then `mcp_control({ action: \"enable\", server: \"<name>\" })` to add one.',\n ].join('\\n');\n }\n\n const lines: string[] = [];\n const liveMap = new Map(live.map((s) => [s.name, s]));\n\n for (const [name, cfg] of Object.entries(configured)) {\n const liveInfo = liveMap.get(name);\n const toolCount = liveInfo ? ` (${liveInfo.toolCount} tools)` : '';\n const stateStr = liveInfo ? badge(liveInfo.state) : dim('\u25CB not loaded');\n const enabled = cfg.enabled === false\n ? `${dim('disabled')} `\n : `${green('\u25CF enabled')} `;\n lines.push(` ${bold(name)} ${enabled}${stateStr}${toolCount}`);\n if (cfg.description) lines.push(` ${dim(cfg.description)}`);\n }\n\n lines.push('');\n lines.push(dim(' Use `mcp_control({ action: \"search\", query: \"<keyword>\" })` to find servers.'));\n lines.push(dim(' Use `mcp_control({ action: \"enable\", server: \"<name>\" })` to start a server.'));\n return lines.join('\\n');\n}\n\nasync function renderSearch(\n query: string,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const all = allServers();\n const q = query.toLowerCase();\n\n const configuredNames = new Set(Object.keys(configured));\n\n // Match against configured servers first, then remaining presets\n const configuredEntries = Object.entries(configured).filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const unconfiguredEntries = Object.entries(all)\n .filter(([name]) => !configuredNames.has(name))\n .filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const lines: string[] = [];\n\n if (configuredEntries.length > 0) {\n lines.push(bold('Configured servers matching \"') + query + '\":');\n for (const [name, cfg] of configuredEntries) {\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}`);\n }\n lines.push('');\n }\n\n if (unconfiguredEntries.length > 0) {\n lines.push(bold('Available presets matching \"') + query + '\":');\n for (const [name, cfg] of unconfiguredEntries) {\n const warn = cfg.permission === 'deny' ? red(' \u26A0 confirm required') : '';\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}${warn}`);\n }\n lines.push('');\n }\n\n if (configuredEntries.length === 0 && unconfiguredEntries.length === 0) {\n return `No servers match \"${query}\". Try a shorter keyword or \\`mcp_control({ action: \"list\" })\\`.`;\n }\n\n const total = configuredEntries.length + unconfiguredEntries.length;\n lines.push(dim(` ${total} server${total !== 1 ? 's' : ''} shown. Run \\`enable\\` on one to activate it.`));\n return lines.join('\\n');\n}\n\nasync function runEnable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for enable. Example: { action: \"enable\", server: \"github\" }';\n\n const all = allServers();\n const configured = deps.getConfig().mcpServers ?? {};\n\n // Resolve the target config \u2014 it may be a preset not yet in config\n const cfg = configured[name] ?? all[name];\n if (!cfg) {\n const known = Object.keys(all).join(', ');\n return `Unknown server \"${name}\". Available presets: ${known}`;\n }\n\n // Write to config (add or update) using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n setJsonPath(full, ['mcpServers', name], { ...current[name], ...cfg, enabled: true });\n });\n\n // Start the server in the registry\n try {\n const live = deps.registry.describe().find((s) => s.name === name);\n if (live && live.state === 'connected') {\n return `${green('\u25CF')} Server \"${name}\" is already running (${live.toolCount} tools registered).`;\n }\n await deps.registry.start({ ...cfg, enabled: true });\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Enabled and started')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Failed to start')} \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\nasync function runDisable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for disable. Example: { action: \"disable\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not in config. Add it with \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\`.`;\n }\n\n // Write to config using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n const existing = expectDefined(current[name]);\n setJsonPath(full, ['mcpServers', name], { ...existing, enabled: false });\n });\n\n // Stop the running server\n try {\n await deps.registry.stop(name);\n return `${yellow('\u25CB Disabled')} \"${name}\". It will not be started on next boot.`;\n } catch {\n return `${yellow('\u25CB Disabled')} \"${name}\" (it was not running). Config updated.`;\n }\n}\n\nasync function runRestart(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for restart. Example: { action: \"restart\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not configured. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n\n try {\n await deps.registry.restart(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Restarted')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Restart failed')} for \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\n/**\n * Ephemerally activate a server's tools without writing to config or\n * restarting the connection. The server must already be connected (lazy mode).\n * Calls `registry.activateServer()` when available; falls back to a message\n * if the registry doesn't support ephemeral activation.\n */\nasync function runActivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for activate.';\n if (!deps.registry.activateServer) {\n return `Registry does not support ephemeral activation. Use \\`enable\\` to start \"${name}\" instead.`;\n }\n const live = deps.registry.describe().find((s) => s.name === name);\n if (!live) {\n return `Server \"${name}\" is not registered. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n if (live.state !== 'connected') {\n return `Server \"${name}\" is not connected (state: ${live.state}). Use \\`enable\\` to start it first.`;\n }\n if (deps.registry.isActivated?.(name)) {\n return `${green('\u25CF')} Server \"${name}\" tools are already active. Use \\`deactivate\\` to hide them.`;\n }\n deps.registry.activateServer(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Activated')} \"${name}\" \u2014 ${updated?.toolCount ?? 0} tool(s) now registered. Use \\`mcp_control({ action: \"deactivate\", server: \"${name}\" })\\` to hide them when done.`;\n}\n\n/**\n * Ephemerally deactivate a server's tools without disconnecting.\n * Calls `registry.deactivateServer()` when available.\n */\nasync function runDeactivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for deactivate.';\n if (!deps.registry.deactivateServer) {\n return `Registry does not support ephemeral deactivation. Use \\`disable\\` to stop \"${name}\" instead.`;\n }\n if (!deps.registry.isActivated?.(name)) {\n return `Server \"${name}\" tools are not currently active.`;\n }\n const count = deps.registry.deactivateServer(name);\n return `${yellow('\u25CB Deactivated')} \"${name}\" \u2014 ${count} tool(s) unregistered. Server stays connected.`;\n}\n\n// \u2500\u2500 Config helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function getConfiguredMcpServers(deps: { getConfig: () => Config; configPath: string }): Promise<Record<string, MCPServerConfig>> {\n const diskConfig = await readJsonObjectFile(deps.configPath);\n if (isMcpServerRecord(diskConfig.mcpServers)) return diskConfig.mcpServers;\n return deps.getConfig().mcpServers ?? {};\n}\n\nfunction isMcpServerRecord(value: unknown): value is Record<string, MCPServerConfig> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n// \u2500\u2500 Colour helpers (no dep on core color \u2014 inline) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bold(s: string) { return `\\x1b[1m${s}\\x1b[0m`; }\nfunction dim(s: string) { return `\\x1b[2m${s}\\x1b[0m`; }\nfunction green(s: string) { return `\\x1b[32m${s}\\x1b[0m`; }\nfunction yellow(s: string){ return `\\x1b[33m${s}\\x1b[0m`; }\nfunction red(s: string) { return `\\x1b[31m${s}\\x1b[0m`; }\n\nfunction badge(state: string): string {\n switch (state) {\n case 'connected': return green('\u25CF connected');\n case 'connecting': return `\\x1b[36m\u25D0 connecting\\x1b[0m`;\n case 'reconnecting': return `\\x1b[36m\u25D1 reconnecting\\x1b[0m`;\n case 'disconnected': return dim('\u25CB disconnected');\n case 'failed': return red('\u2717 failed');\n default: return dim(state);\n }\n}\n", "/**\n * Provider-wire tool name constraints.\n *\n * Anthropic-family endpoints (including gateways that translate to the\n * Anthropic wire, e.g. OmniRoute routing to `cc/...` models) validate every\n * tool name against `^[a-zA-Z0-9_-]{1,128}$` and reject the whole request\n * with a 400 (`tools.N.custom.name: String should match pattern ...`) when\n * one name contains a dot, colon, space, or exceeds 128 chars. MCP server\n * names and remote MCP tool names are user/third-party controlled, so the\n * qualified `mcp__<server>__<tool>` names must be sanitized at registration\n * time \u2014 the registry, permission policy, and provider wire all see the\n * same sanitized name, so no reverse mapping is needed on the response\n * path. The wrapped tool still calls the remote server with the ORIGINAL\n * tool name.\n */\n\nexport const WIRE_TOOL_NAME_MAX_LENGTH = 128;\nexport const WIRE_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,128}$/;\n\n/**\n * Coerce an arbitrary string into a provider-safe tool name: every char\n * outside `[a-zA-Z0-9_-]` becomes `_`, and the result is clamped to 128\n * chars (clamped from the end so namespace prefixes like `mcp__server__`\n * survive). Empty input falls back to `'tool'`.\n */\nexport function sanitizeWireToolName(name: string): string {\n const replaced = name.replace(/[^a-zA-Z0-9_-]/g, '_');\n const clamped = replaced.slice(0, WIRE_TOOL_NAME_MAX_LENGTH);\n return clamped.length > 0 ? clamped : 'tool';\n}\n\n/** Sanitized `mcp__<server>__` namespace prefix for a server's tools. */\nexport function mcpServerToolPrefix(serverName: string): string {\n return `mcp__${sanitizeWireToolName(serverName)}__`;\n}\n\n/**\n * Build the qualified registry/wire name for an MCP tool. Both the server\n * segment and the tool segment are sanitized independently (so the `__`\n * separators stay intact for prefix matching), then the whole name is\n * clamped to the 128-char wire limit.\n */\nexport function mcpQualifiedToolName(serverName: string, toolName: string): string {\n return sanitizeWireToolName(\n `${mcpServerToolPrefix(serverName)}${sanitizeWireToolName(toolName)}`,\n );\n}\n", "import type { JSONSchema, ToolRegistry } from '../index.js';\nimport { ToolCapabilities } from '../security/capabilities.js';\nimport { mcpQualifiedToolName, mcpServerToolPrefix } from '../utils/tool-name.js';\nimport type { MCPRegistryHandle } from './mcp-control.js';\nimport type { Tool } from '../types/tool.js';\n\n/**\n * `mcp_use` \u2014 meta-tool for ephemeral MCP tool calls in token-saving mode.\n *\n * Instead of the 4-step manual cycle (list \u2192 activate \u2192 use \u2192 deactivate),\n * the model calls this single tool. It:\n * 1. Activates the server's tools in the registry\n * 2. Calls the requested tool with the provided input\n * 3. Returns the result\n * 4. Deactivates the server's tools\n *\n * The tool is registered only when features.lazyMcp is active so the model\n * always has a way to reach MCP tools without them being in the prompt.\n */\n\nexport interface CreateMcpUseToolOptions {\n /** Live MCP registry handle (activate/deactivate/describe). */\n registry: MCPRegistryHandle;\n /** Tool registry \u2014 needed to resolve and call MCP tools by name. */\n toolRegistry: ToolRegistry;\n}\n\nexport function createMcpUseTool(opts: CreateMcpUseToolOptions): Tool {\n const { registry, toolRegistry } = opts;\n\n const inputSchema: JSONSchema = {\n type: 'object',\n properties: {\n server: {\n type: 'string',\n description: 'MCP server name (e.g. \"github\", \"filesystem\", \"brave-search\"). Use mcp_control list or search first to discover available servers.',\n },\n tool: {\n type: 'string',\n description: 'Tool name on the MCP server to call (without the mcp__server__ prefix \u2014 just the bare tool name).',\n },\n input: {\n type: 'object',\n description: 'JSON input to pass to the tool. Use the tool\\'s own input schema \u2014 check with mcp_control describe or the server\\'s documentation.',\n properties: {},\n additionalProperties: true,\n },\n },\n required: ['server', 'tool', 'input'],\n };\n\n return {\n name: 'mcp_use',\n description:\n 'Call an MCP tool on a lazy-loaded server. Activates the server temporarily, calls the tool, returns the result, and deactivates. Use this instead of the manual activate\u2192use\u2192deactivate cycle. First call mcp_control list/search to find the right server and tool name.',\n category: 'mcp',\n permission: 'confirm',\n mutating: true,\n riskTier: 'standard',\n capabilities: [ToolCapabilities.MCP_PROXY],\n inputSchema,\n async execute(raw) {\n const input = raw as {\n server: string;\n tool: string;\n input?: Record<string, unknown> | undefined;\n };\n\n const { server: serverName, tool: toolName, input: toolInput } = input;\n\n // Validate server exists\n const servers = registry.describe();\n const serverInfo = servers.find((s) => s.name === serverName);\n if (!serverInfo) {\n return `Server \"${serverName}\" not found. Available: ${servers.map((s) => s.name).join(', ') || 'none'}.`;\n }\n if (serverInfo.state !== 'connected') {\n return `Server \"${serverName}\" is not connected (state: ${serverInfo.state}). Use \\`mcp_control({ action: \"enable\", server: \"${serverName}\" })\\` first.`;\n }\n\n // Activate server tools\n if (registry.activateServer) {\n registry.activateServer(serverName);\n }\n\n try {\n // Resolve the qualified tool name\n const qualifiedName = mcpQualifiedToolName(serverName, toolName);\n const mcpTool = toolRegistry.get(qualifiedName);\n if (!mcpTool) {\n // Tool not found \u2014 list available tools for helpful error\n const allTools = toolRegistry\n .list()\n .filter((t) => t.name.startsWith(mcpServerToolPrefix(serverName)))\n .map((t) => t.name.replace(mcpServerToolPrefix(serverName), ''));\n const hint =\n allTools.length > 0\n ? `Available tools on \"${serverName}\": ${allTools.join(', ')}.`\n : `No tools found on \"${serverName}\". The server may not have published any tools.`;\n return `Tool \"${toolName}\" not found on server \"${serverName}\". ${hint}`;\n }\n\n // Call the tool \u2014 we need to create a minimal Context and ExecuteOptions.\n // The tool executor normally provides these; since we're calling a tool\n // from inside another tool we create minimal stubs that let the tool\n // execute its MCP transport call without needing the full agent context.\n const result = await mcpTool.execute(toolInput ?? {}, {} as never, {} as never);\n return result;\n } finally {\n // Always deactivate, even if the tool call threw\n if (registry.deactivateServer) {\n registry.deactivateServer(serverName);\n }\n }\n },\n };\n}\n", "import type { FallbackChain } from '../core/fallback-profile-manager.js';\nimport { evaluateModelCalendar } from '../core/model-availability-calendar.js';\nimport { isTextBlock } from '../types/blocks.js';\nimport type { Config } from '../types/config.js';\nimport type { Message } from '../types/messages.js';\nimport type {\n OneShotLLMInput,\n OneShotLLMResult,\n OneShotOrchestratorOptions,\n} from '../types/one-shot-llm.js';\nimport {\n isFallbackWorthy,\n type Provider,\n ProviderError,\n type Request,\n type Response,\n} from '../types/provider.js';\nimport { estimateRequestTokens } from '../utils/token-estimate.js';\n\n/**\n * Default timeout for one-shot LLM calls when the caller doesn't specify one.\n */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Default max output tokens when the caller doesn't specify.\n */\nconst DEFAULT_MAX_TOKENS = 1024;\n\ntype CallAttempt =\n | { response: Response; error?: never; fallbackEligible: false }\n | { response?: never; error: unknown; fallbackEligible: boolean };\n\n/**\n * OneShotOrchestrator \u2014 a stateless, reusable utility for making single\n * LLM calls with provider resolution, fallback chains, and structured results.\n *\n * Usage:\n * ```ts\n * const oneShot = new OneShotOrchestrator({ buildProvider, getConfig });\n * const result = await oneShot.call({\n * system: 'You are a helpful assistant.',\n * userPrompt: 'Summarize this conversation.',\n * model: 'deepseek-chat',\n * fallbackModels: ['anthropic/claude-haiku'],\n * });\n * console.log(result.text);\n * ```\n *\n * Every method is stateless \u2014 a single instance can be shared across\n * the entire process lifetime.\n */\nexport class OneShotOrchestrator {\n private readonly opts: OneShotOrchestratorOptions;\n\n constructor(opts: OneShotOrchestratorOptions) {\n this.opts = opts;\n }\n\n /**\n * Make a one-shot LLM call. Resolves provider+model, applies fallback\n * chain on transient errors, and returns a structured result.\n *\n * Never throws \u2014 all errors are captured in `OneShotLLMResult.error`.\n */\n async call(input: OneShotLLMInput): Promise<OneShotLLMResult> {\n const startedAt = performance.now();\n const config = this.opts.getConfig();\n\n // \u2500\u2500 1. Resolve target provider + model \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const target = this.resolveTarget(input, config);\n if (!target) {\n return {\n text: '',\n model: input.model ?? config.model ?? 'unknown',\n provider: input.providerId ?? config.provider ?? 'unknown',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback: false,\n error: 'No provider or model could be resolved. Check your config.',\n };\n }\n\n let provider: Provider;\n try {\n provider = await this.opts.buildProvider(target.providerId, target.model);\n } catch (err) {\n return {\n text: '',\n model: target.model,\n provider: target.providerId,\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback: false,\n error: `Cannot build provider \"${target.providerId}\": ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // \u2500\u2500 2. Build the request \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const request = this.buildRequest(input, target.model);\n const signal = this.resolveSignal(input);\n\n // \u2500\u2500 3. Build fallback chain \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const chain = this.resolveFallbackChain(input, config, target);\n\n // \u2500\u2500 4. Attempt the call with fallback rotation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const tracker = this.opts.statusTracker;\n let servingProviderId = provider.id;\n let servingModel = target.model;\n let fromFallback = false;\n let lastError: unknown;\n let fallbackEligible = false;\n\n // Check if the primary target is blocked\n if (\n (tracker && !tracker.isAvailable(target.providerId, target.model)) ||\n !evaluateModelCalendar(config.modelAvailabilitySchedule, target.providerId, target.model)\n .allowed\n ) {\n this.opts.logger?.debug(\n `one-shot: primary \"${target.providerId}/${target.model}\" is blocked \u2014 trying fallback`,\n );\n // Fall through to the fallback chain\n } else {\n const primaryAttempt = await this.tryCall(\n provider,\n request,\n signal,\n target.providerId,\n target.model,\n );\n const result = primaryAttempt.response;\n lastError = primaryAttempt.error;\n fallbackEligible = primaryAttempt.fallbackEligible;\n\n if (result) {\n tracker?.recordSuccess(target.providerId, target.model);\n servingProviderId = provider.id;\n servingModel = target.model;\n return this.buildResult(result, servingProviderId, servingModel, false, startedAt);\n }\n\n if (!fallbackEligible || chain.length === 0) {\n return this.buildErrorResult(lastError, target.providerId, target.model, false, startedAt);\n }\n }\n\n // \u2500\u2500 4b. Fallback chain \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Estimate request tokens lazily \u2014 only reached when the primary call\n // failed or was blocked. Used to pre-filter fallback entries whose context\n // window is provably too small, avoiding a guaranteed context_overflow.\n const estimatedTokens = estimateRequestTokens(request.messages, request.system, []).total;\n\n // Filter blocked entries from the chain\n const usableChain = tracker\n ? chain.filter((e) => tracker.isAvailable(e.providerId, e.model))\n : chain;\n\n for (const entry of usableChain) {\n if (\n !evaluateModelCalendar(config.modelAvailabilitySchedule, entry.providerId, entry.model)\n .allowed\n )\n continue;\n // Re-check availability right before attempting \u2014 a concurrent failure\n // may have pushed this entry into the waiting room since the chain was\n // filtered. Skipping here avoids a wasted provider call.\n if (tracker && !tracker.isAvailable(entry.providerId, entry.model)) {\n continue;\n }\n if (entry.providerId === provider.id && entry.model === target.model) continue;\n\n let fbProvider: Provider;\n try {\n fbProvider = await this.opts.buildProvider(entry.providerId, entry.model);\n } catch (err) {\n lastError = err;\n continue;\n }\n\n // Pre-filter: skip entries whose context window is provably too small\n // for the current request. A guaranteed context_overflow is not\n // fallback-worthy and would surface as an error, wasting the call.\n const fbMaxContext = fbProvider.capabilities.maxContext;\n if (\n typeof fbMaxContext === 'number' &&\n Number.isFinite(fbMaxContext) &&\n fbMaxContext > 0 &&\n estimatedTokens > fbMaxContext\n ) {\n this.opts.logger?.debug(\n `one-shot: skipping \"${entry.providerId}/${entry.model}\" \u2014 context window ` +\n `(${fbMaxContext}) is smaller than request tokens (${estimatedTokens})`,\n );\n continue;\n }\n\n servingProviderId = fbProvider.id;\n servingModel = entry.model;\n const attempt = await this.tryCall(\n fbProvider,\n this.buildRequest(input, entry.model),\n signal,\n entry.providerId,\n entry.model,\n );\n if (attempt.response) {\n tracker?.recordSuccess(entry.providerId, entry.model);\n fromFallback = true;\n return this.buildResult(attempt.response, servingProviderId, servingModel, true, startedAt);\n }\n\n lastError = attempt.error;\n // Do NOT break on a non-fallback-eligible error from a chain entry.\n // Only the primary's eligibility (checked above at the gate) decides\n // whether we enter the chain at all. A stale entry (deleted model \u2192\n // 404 \u2192 invalid_request) must not abort every healthy entry after it.\n // Mirrors the agent-loop fix in fallback-model.ts (lines 464\u2013481).\n }\n\n // Total failure \u2014 all providers exhausted or non-retryable error.\n return this.buildErrorResult(\n lastError,\n servingProviderId,\n servingModel,\n fromFallback,\n startedAt,\n );\n }\n\n // \u2500\u2500 Private helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve the target provider + model from input + config.\n * Priority: role-based routing > explicit providerId+model > defaults.\n */\n private resolveTarget(\n input: OneShotLLMInput,\n config: import('../types/config.js').Config,\n ): { providerId: string; model: string } | undefined {\n // Role-based routing via ModelRouter (highest priority)\n if (input.role && this.opts.modelRouter) {\n const pick = this.opts.modelRouter.pickForTask(input.role, '');\n if (pick) {\n return { providerId: pick.provider, model: pick.model };\n }\n }\n\n // Explicit providerId + model\n if (input.providerId && input.model) {\n return { providerId: input.providerId, model: input.model };\n }\n\n // Model only \u2014 use default provider\n if (input.model) {\n return { providerId: config.provider, model: input.model };\n }\n\n // Provider only \u2014 use default model\n if (input.providerId) {\n return { providerId: input.providerId, model: config.model };\n }\n\n // Neither \u2014 use session defaults\n if (config.provider && config.model) {\n return { providerId: config.provider, model: config.model };\n }\n\n return undefined;\n }\n\n /**\n * Build a Provider Request from the input.\n */\n private buildRequest(input: OneShotLLMInput, model: string): Request {\n const messages: Message[] = [...(input.messages ?? [])];\n if (input.userPrompt) {\n messages.push({ role: 'user', content: input.userPrompt });\n }\n\n const system = asTextBlocks(input.system);\n\n return {\n model,\n ...(system.length > 0 ? { system } : {}),\n messages,\n maxTokens: input.maxTokens ?? DEFAULT_MAX_TOKENS,\n ...(input.temperature !== undefined ? { temperature: input.temperature } : {}),\n ...(input.responseFormat ? { responseFormat: input.responseFormat } : {}),\n };\n }\n\n /**\n * Resolve the abort signal. Provider calls always receive the per-call\n * timeout, composed with external cancellation when the caller supplies it.\n */\n private resolveSignal(input: OneShotLLMInput): AbortSignal {\n const timeoutSignal = AbortSignal.timeout(input.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n return input.signal ? AbortSignal.any([input.signal, timeoutSignal]) : timeoutSignal;\n }\n\n /**\n * Build the fallback model chain from input + config + current target.\n * The injected {@link OneShotOrchestratorOptions.fallbackProfileManager}\n * is the only allowed manager \u2014 OneShot never owns a private snapshot\n * so a live `ConfigStore` change reaches every call without rebuilding\n * the manager.\n */\n private resolveFallbackChain(\n input: OneShotLLMInput,\n config: Config,\n target: { providerId: string; model: string },\n ): FallbackChain {\n const mgr = this.opts.fallbackProfileManager;\n\n // Explicit chain wins\n if (input.fallbackModels && input.fallbackModels.length > 0) {\n return mgr.resolveRefs(input.fallbackModels, target);\n }\n\n // Config-level fallbackModels \u2014 independent of fallbackAuto\n if (config.fallbackModels && config.fallbackModels.length > 0) {\n return mgr.resolveRefs(config.fallbackModels, target);\n }\n\n // Smart default from config (only when auto-derivation is enabled)\n if (config.fallbackAuto !== false) {\n return mgr.resolveEffective({\n fallbackAuto: true,\n exclude: target,\n });\n }\n\n return Object.freeze([]) as FallbackChain;\n }\n\n /** Attempt a provider call while preserving the actual failure for callers. */\n private async tryCall(\n provider: Provider,\n request: Request,\n signal: AbortSignal,\n providerId?: string,\n model?: string,\n ): Promise<CallAttempt> {\n try {\n return {\n response: await provider.complete(request, { signal }),\n fallbackEligible: false,\n };\n } catch (err) {\n // Record the failure in the tracker\n if (err instanceof ProviderError && providerId && model) {\n this.opts.statusTracker?.recordFailure(\n providerId,\n model,\n err.kind,\n err.status,\n err.describe(),\n { retryAfterMs: err.body?.retryAfterMs },\n );\n }\n return {\n error: err,\n fallbackEligible:\n !signal.aborted && (!(err instanceof ProviderError) || isFallbackWorthy(err.kind)),\n };\n }\n }\n\n /** Build a success result from a provider Response. */\n private buildResult(\n response: Response,\n servingProviderId: string,\n servingModel: string,\n fromFallback: boolean,\n startedAt: number,\n ): OneShotLLMResult {\n const textBlocks = response.content.filter(isTextBlock);\n const text = textBlocks\n .map((b) => b.text)\n .join('\\n')\n .trim();\n return {\n text: text || '(empty response)',\n model: response.model ?? servingModel,\n provider: servingProviderId,\n tokens: {\n input: response.usage?.input ?? 0,\n output: response.usage?.output ?? 0,\n total: (response.usage?.input ?? 0) + (response.usage?.output ?? 0),\n },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback,\n stopReason: response.stopReason,\n };\n }\n\n /** Build a total-failure error result. */\n private buildErrorResult(\n error: unknown,\n servingProviderId: string,\n servingModel: string,\n fromFallback: boolean,\n startedAt: number,\n ): OneShotLLMResult {\n return {\n text: '',\n model: servingModel,\n provider: servingProviderId,\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback,\n error: error instanceof Error ? error.message : String(error ?? 'Unknown error'),\n };\n }\n}\n\n/**\n * Normalize system prompt to TextBlock[].\n */\nfunction asTextBlocks(\n system: string | import('../types/blocks.js').TextBlock[] | undefined,\n): import('../types/blocks.js').TextBlock[] {\n if (!system) return [];\n if (Array.isArray(system)) return system;\n return [{ type: 'text', text: system }];\n}\n", "import type { JSONSchema, Tool } from '../types/tool.js';\nimport type { OneShotLLMInput, OneShotLLMResult, OneShotOrchestratorOptions } from '../types/one-shot-llm.js';\nimport { OneShotOrchestrator } from '../execution/one-shot-llm.js';\n\n/**\n * Tool name for the one-shot LLM tool.\n * Register in ToolRegistry as `llm` so any agent can call it.\n */\nexport const ONE_SHOT_LLM_TOOL_NAME = 'llm';\n\n/**\n * Options for creating the LLM tool.\n * Mirrors OneShotOrchestratorOptions \u2014 the tool wraps an internal orchestrator.\n * When `defaultProvider` and `defaultModel` are not set, callers MUST\n * provide `providerId` and `model` explicitly.\n */\nexport interface CreateOneShotLLMToolOptions {\n buildProvider: OneShotOrchestratorOptions['buildProvider'];\n getConfig: OneShotOrchestratorOptions['getConfig'];\n /** Shared live FallbackProfileManager \u2014 required. */\n fallbackProfileManager: OneShotOrchestratorOptions['fallbackProfileManager'];\n modelRouter?: OneShotOrchestratorOptions['modelRouter'];\n logger?: OneShotOrchestratorOptions['logger'];\n /**\n * Default provider to use when the caller doesn't specify one.\n * When absent, callers MUST provide `providerId` explicitly.\n */\n defaultProvider?: string | undefined;\n /**\n * Default model to use when the caller doesn't specify one.\n * When absent, callers MUST provide `model` explicitly.\n */\n defaultModel?: string | undefined;\n}\n\n/**\n * JSON Schema for the llm tool input.\n */\nconst INPUT_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n system: {\n type: 'string',\n description: 'System prompt guiding the LLM behaviour.',\n },\n userPrompt: {\n type: 'string',\n description: 'Single user turn \u2014 appended as a user-role message.',\n },\n messages: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n role: {\n type: 'string',\n enum: ['system', 'user', 'assistant', 'tool'],\n description: 'Message author role.',\n },\n content: {\n type: 'string',\n description: 'Message text content.',\n },\n },\n required: ['role', 'content'],\n additionalProperties: true,\n },\n description: 'Conversation messages for few-shot examples or multi-turn context. Appended before userPrompt when both are set.',\n },\n model: {\n type: 'string',\n description: 'Model id (e.g. \"deepseek-chat\", \"gpt-4o-mini\"). Defaults to session model.',\n },\n providerId: {\n type: 'string',\n description: 'Provider id (e.g. \"anthropic\", \"openai\"). Defaults to session provider.',\n },\n role: {\n type: 'string',\n description: 'Roster role for model-matrix routing. Overrides model/providerId.',\n },\n fallbackModels: {\n type: 'array',\n items: { type: 'string' },\n description: 'Explicit fallback model chain (e.g. [\"anthropic/claude-haiku\", \"openai/gpt-4o-mini\"]). Resolved named profiles from FallbackProfileManager are passed here.',\n },\n maxTokens: {\n type: 'number',\n description: 'Maximum output tokens (default 1024).',\n },\n responseFormat: {\n oneOf: [\n { type: 'string', enum: ['text', 'json_object'], description: 'Simple response format.' },\n {\n type: 'object',\n properties: {\n type: { type: 'string', enum: ['json_schema'], description: 'Structured JSON output.' },\n json_schema: {\n type: 'object',\n description: 'JSON Schema definition for the structured output.',\n },\n },\n required: ['type'],\n additionalProperties: false,\n },\n ],\n description: 'Response format: \"text\" (default), \"json_object\", or { type: \"json_schema\", json_schema: {...} }.',\n },\n temperature: {\n type: 'number',\n description: 'Sampling temperature.',\n },\n timeoutMs: {\n type: 'number',\n description: 'Hard timeout in ms (default 30s).',\n },\n },\n};\n\n/**\n * Create the `llm` tool \u2014 a general-purpose one-shot LLM invocation tool\n * that any agent can call. Wraps OneShotOrchestrator internally for\n * provider resolution, fallback chain support, and structured results.\n *\n * Usage from an agent:\n * ```\n * llm({\n * system: \"You are a helpful assistant.\",\n * userPrompt: \"Summarize this conversation.\",\n * model: \"deepseek-chat\",\n * maxTokens: 1024,\n * })\n * ```\n *\n * Register with the ToolRegistry and it becomes available everywhere:\n * ```ts\n * toolRegistry.register(createOneShotLLMTool({ buildProvider, getConfig }));\n * ```\n */\nexport function createOneShotLLMTool(opts: CreateOneShotLLMToolOptions): Tool<OneShotLLMInput, OneShotLLMResult> {\n const orchestrator = new OneShotOrchestrator({\n buildProvider: opts.buildProvider,\n getConfig: opts.getConfig,\n fallbackProfileManager: opts.fallbackProfileManager,\n modelRouter: opts.modelRouter,\n logger: opts.logger,\n });\n\n return {\n name: ONE_SHOT_LLM_TOOL_NAME,\n description:\n 'Make a one-shot LLM call with a system prompt and user input. ' +\n 'Supports provider selection, model routing by role, fallback chains, and timeout. ' +\n 'Returns the response text, model info, token usage, and whether a fallback was used. ' +\n 'Use this for summarization, classification, extraction, and any single-turn LLM task.',\n usageHint:\n 'Provide `system` for the instruction and `userPrompt` for the input. ' +\n 'Either set `model`+`providerId`, or have defaults configured on the tool. ' +\n 'Set `fallbackModels` for resilience. ' +\n 'Check `error` on the result for failure details.',\n inputSchema: INPUT_SCHEMA,\n permission: 'auto',\n mutating: false,\n\n async execute(\n input: OneShotLLMInput,\n _ctx,\n { signal }: { signal: AbortSignal },\n ): Promise<OneShotLLMResult> {\n // If the caller didn't provide model/providerId, check for tool-level defaults.\n // This prevents silent fallback to session config which may not be intended.\n if (!input.model && !input.providerId && !opts.defaultModel && !opts.defaultProvider) {\n return {\n text: '',\n model: '',\n provider: '',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: 0,\n fromFallback: false,\n error:\n 'Either provide `model` and `providerId` in the call, or configure ' +\n 'defaultProvider/defaultModel when creating the tool. The `llm` tool ' +\n 'does not infer provider/model from the session by default.',\n };\n }\n\n // Apply defaults when caller omits model/providerId but defaults are configured.\n const effectiveInput: OneShotLLMInput = {\n ...input,\n signal: input.signal ? AbortSignal.any([input.signal, signal]) : signal,\n model: input.model ?? opts.defaultModel,\n providerId: input.providerId ?? opts.defaultProvider,\n };\n\n return orchestrator.call(effectiveInput);\n },\n };\n}\n", "/**\n * Minimal JSON Schema validator \u2014 covers the subset needed for plugin\n * configSchema validation and tool inputSchema sanity checks. Intentionally\n * small (~80 lines, zero deps) and tolerant: unknown keywords are ignored so\n * authors can mix in non-standard extensions without breaking validation.\n *\n * NOT for full JSON Schema 2020-12 conformance. If a plugin needs $ref,\n * conditional schemas, format validation, or anything else exotic, it should\n * bring its own ajv-based validator and call this only for the cheap path.\n */\nimport type { JSONSchema } from '../types/tool.js';\n\nexport interface ValidationError {\n path: string;\n message: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n errors: ValidationError[];\n}\n\nexport function validateAgainstSchema(value: unknown, schema: JSONSchema): ValidationResult {\n const errors: ValidationError[] = [];\n walk(value, schema, '', errors, 0);\n return { ok: errors.length === 0, errors };\n}\n\n/**\n * Maximum nesting depth before the validator stops recursing and reports a\n * \"schema too deep\" error. Deeply nested input (e.g. batch_tool_use with 100\n * nested calls \u2192 tool_use \u2192 input) can otherwise hit `RangeError: Maximum\n * call stack size exceeded` and crash the tool executor.\n *\n * 64 is generous: real-world tool schemas rarely nest beyond 5-6 levels, and\n * even pathological inputs (deeply recursive JSON) stay well under this.\n * The limit is a safety net against unbounded recursion, not a tight bound.\n */\nconst MAX_SCHEMA_DEPTH = 64;\n\nfunction walk(\n value: unknown,\n schema: JSONSchema,\n path: string,\n errors: ValidationError[],\n depth: number,\n): void {\n // P2 #8 (before-release.md): cap recursion depth to prevent\n // `RangeError: Maximum call stack size exceeded` on deeply nested input.\n // Push a validation error and stop descending \u2014 the caller still gets a\n // usable (ok: false) result instead of a crash.\n if (depth > MAX_SCHEMA_DEPTH) {\n errors.push({\n path: path || '<root>',\n message: `schema nesting exceeds maximum depth (${MAX_SCHEMA_DEPTH})`,\n });\n return;\n }\n if (schema.enum !== undefined) {\n if (!enumIncludes(schema.enum, value)) {\n errors.push({\n path: path || '<root>',\n message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`,\n });\n return;\n }\n }\n\n if (typeof schema.type === 'string') {\n if (!checkType(value, schema.type)) {\n errors.push({\n path: path || '<root>',\n message: `expected ${schema.type}, got ${describeType(value)} (${previewValue(value)})`,\n });\n return;\n }\n }\n\n if (schema.type === 'object' && isPlainObject(value)) {\n const obj = value as Record<string, unknown>;\n for (const req of schema.required ?? []) {\n if (!(req in obj)) {\n const expected = schema.properties?.[req]?.type;\n errors.push({\n path: joinPath(path, req),\n message: `required property missing${typeof expected === 'string' ? ` (expected ${expected})` : ''}`,\n });\n }\n }\n if (schema.properties) {\n for (const [key, subSchema] of Object.entries(schema.properties)) {\n if (key in obj) {\n walk(obj[key], subSchema, joinPath(path, key), errors, depth + 1);\n }\n }\n }\n }\n\n if (schema.type === 'array' && Array.isArray(value) && schema.items) {\n for (let i = 0; i < value.length; i++) {\n walk(value[i], schema.items as JSONSchema, `${path}[${i}]`, errors, depth + 1);\n }\n }\n}\n\nexport interface CoercionResult {\n value: unknown;\n /** True when at least one leaf was rewritten. */\n changed: boolean;\n}\n\n/**\n * Best-effort, lossless coercion of a value toward a JSON Schema. Models \u2014\n * especially through OpenAI-compatible proxies \u2014 frequently deliver\n * arguments with the right *content* in the wrong *type*: numbers and\n * booleans encoded as strings (\"5\", \"true\"), scalars where a string is\n * expected, or a whole nested object serialized into a JSON string.\n *\n * Only conversions that cannot lose information are applied:\n * - string \u2192 number/integer when the whole trimmed string parses cleanly\n * - string \"true\"/\"false\" \u2192 boolean\n * - number/boolean \u2192 string when a string is expected\n * - JSON-serialized string \u2192 object/array when the parse yields that shape\n * Recurses into `properties`/`items`. Returns the (possibly new) value and\n * whether anything changed \u2014 callers should re-validate before trusting it.\n */\nexport function coerceAgainstSchema(value: unknown, schema: JSONSchema): CoercionResult {\n return coerceWalk(value, schema, 0);\n}\n\nfunction coerceWalk(value: unknown, schema: JSONSchema, depth: number): CoercionResult {\n if (depth > MAX_SCHEMA_DEPTH) return { value, changed: false };\n\n const type = typeof schema.type === 'string' ? schema.type : undefined;\n\n // Leaf conversions (only when the current type does NOT already match).\n if (type && !checkType(value, type)) {\n if (type === 'string' && (typeof value === 'number' || typeof value === 'boolean')) {\n return { value: String(value), changed: true };\n }\n if ((type === 'number' || type === 'integer') && typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed !== '' && /^-?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/.test(trimmed)) {\n const num = Number(trimmed);\n if (!Number.isNaN(num) && (type === 'number' || Number.isInteger(num))) {\n return { value: num, changed: true };\n }\n }\n return { value, changed: false };\n }\n if (type === 'boolean' && typeof value === 'string') {\n const lowered = value.trim().toLowerCase();\n if (lowered === 'true') return { value: true, changed: true };\n if (lowered === 'false') return { value: false, changed: true };\n return { value, changed: false };\n }\n if ((type === 'object' || type === 'array') && typeof value === 'string') {\n // A nested structure serialized into a string (double-encoded args).\n try {\n const parsed: unknown = JSON.parse(value);\n if (checkType(parsed, type)) {\n // Recurse so leaves inside the revived structure also coerce.\n return { value: coerceWalk(parsed, schema, depth + 1).value, changed: true };\n }\n } catch {\n // fall through \u2014 leave as-is, validation will report it\n }\n return { value, changed: false };\n }\n return { value, changed: false };\n }\n\n // Structural recursion.\n if (type === 'object' && isPlainObject(value) && schema.properties) {\n const obj = value as Record<string, unknown>;\n let changed = false;\n const out: Record<string, unknown> = { ...obj };\n for (const [key, subSchema] of Object.entries(schema.properties)) {\n if (!(key in obj)) continue;\n const r = coerceWalk(obj[key], subSchema, depth + 1);\n if (r.changed) {\n out[key] = r.value;\n changed = true;\n }\n }\n return changed ? { value: out, changed } : { value, changed: false };\n }\n\n if (type === 'array' && Array.isArray(value) && schema.items) {\n let changed = false;\n const out = value.map((item) => {\n const r = coerceWalk(item, schema.items as JSONSchema, depth + 1);\n if (r.changed) changed = true;\n return r.value;\n });\n return changed ? { value: out, changed } : { value, changed: false };\n }\n\n return { value, changed: false };\n}\n\nfunction checkType(value: unknown, type: string): boolean {\n switch (type) {\n case 'string':\n return typeof value === 'string';\n case 'number':\n return typeof value === 'number' && !Number.isNaN(value);\n case 'integer':\n return typeof value === 'number' && Number.isInteger(value);\n case 'boolean':\n return typeof value === 'boolean';\n case 'null':\n return value === null;\n case 'array':\n return Array.isArray(value);\n case 'object':\n return isPlainObject(value);\n default:\n return true;\n }\n}\n\nfunction isPlainObject(v: unknown): boolean {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction describeType(v: unknown): string {\n if (v === null) return 'null';\n if (Array.isArray(v)) return 'array';\n return typeof v;\n}\n\n/** Short serialized preview of the offending value for error messages. */\nfunction previewValue(v: unknown): string {\n try {\n const s = JSON.stringify(v);\n if (s === undefined) return String(v);\n return s.length > 80 ? `${s.slice(0, 80)}\u2026` : s;\n } catch {\n return String(v);\n }\n}\n\nfunction joinPath(parent: string, key: string): string {\n if (!parent) return key;\n return `${parent}.${key}`;\n}\n\nfunction enumIncludes(values: readonly unknown[], value: unknown): boolean {\n if (value === null || typeof value !== 'object') return values.includes(value);\n return values.some((candidate) => deepEqual(candidate, value));\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (a === null || b === null) return a === b;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));\n }\n if (typeof a === 'object' && typeof b === 'object') {\n const ak = Object.keys(a as object);\n const bk = Object.keys(b as object);\n if (ak.length !== bk.length) return false;\n return ak.every((k) =>\n deepEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]),\n );\n }\n return false;\n}\n", "import type { ToolRegistry } from '../registry/tool-registry.js';\nimport { ToolCapabilities } from '../security/capabilities.js';\nimport type { Config, PluginConfig } from '../types/config.js';\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport { validateAgainstSchema } from '../utils/json-schema-validate.js';\n\nexport const PLUGIN_MANAGER_TOOL_NAME = 'plugin_manager';\n\nexport interface PluginManagerCatalogEntry {\n name: string;\n description: string;\n risk: 'low' | 'medium' | 'high';\n defaultState: 'active' | 'inactive';\n canDisable: boolean;\n /** Alternative config/discovery names, such as an official package specifier. */\n aliases?: readonly string[] | undefined;\n}\n\nexport interface PluginManagerMutationResult {\n ok: boolean;\n message: string;\n restartRequired?: boolean | undefined;\n}\n\nexport interface CreatePluginManagerToolOptions {\n /** Re-read on every call so config changes made during the session are visible. */\n getConfig: () => Config;\n /** Built-in/official discovery catalog supplied by the host. */\n catalog: readonly PluginManagerCatalogEntry[];\n /** Live registry used to discover and invoke tools registered by loaded plugins. */\n toolRegistry: ToolRegistry;\n /** Persist an enable/disable decision in the host's active config. */\n setEnabled: (plugin: string, enabled: boolean) => Promise<PluginManagerMutationResult>;\n}\n\ninterface PluginManagerInput {\n action: 'list' | 'search' | 'describe' | 'enable' | 'disable' | 'use';\n plugin?: string | undefined;\n query?: string | undefined;\n state?: 'all' | 'enabled' | 'disabled' | undefined;\n tool?: string | undefined;\n input?: Record<string, unknown> | undefined;\n}\n\ninterface PluginToolView {\n name: string;\n description: string;\n inputSchema: JSONSchema;\n permission: 'auto' | 'confirm' | 'deny';\n enabled: boolean;\n}\n\ninterface PluginView {\n name: string;\n description: string;\n risk: 'low' | 'medium' | 'high' | 'custom';\n enabled: boolean;\n stateSource: 'config' | 'default' | 'feature_flag';\n canDisable: boolean;\n managerControl: 'allowed' | 'locked';\n aliases: string[];\n callableNow: boolean;\n tools: PluginToolView[];\n}\n\nconst INPUT_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'search', 'describe', 'enable', 'disable', 'use'],\n description:\n 'Operation. list: inventory with optional state filter. search: find plugins by need/query. describe: inspect one plugin, managerControl, callableNow, and full tool schemas. enable/disable: persist boot state (often restartRequired). use: inspect or invoke a tool from a plugin already loaded in this session.',\n },\n plugin: {\n type: 'string',\n description:\n 'Plugin name or unambiguous alias. Required for describe, enable, disable, and use.',\n },\n query: {\n type: 'string',\n description:\n 'Free-text query over plugin names, aliases, descriptions, and registered tool metadata. Required for search.',\n },\n state: {\n type: 'string',\n enum: ['all', 'enabled', 'disabled'],\n description:\n 'Optional list/search filter. enabled/disabled means effective boot state, not whether plugin code can be hot-loaded in the current session. Defaults to all.',\n },\n tool: {\n type: 'string',\n description:\n 'Registered plugin tool to invoke when action=\"use\". Omit to receive the available tool schemas first.',\n },\n input: {\n type: 'object',\n description:\n 'Exact JSON input for the selected plugin tool when action=\"use\". Read the schema returned by describe or use-without-tool first; do not guess fields.',\n properties: {},\n additionalProperties: true,\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\nconst USAGE_HINT = [\n 'Always discover before mutating: never enable a guessed plugin name.',\n 'Workflow: (1) search with a capability/need query, or list with an optional state filter;',\n '(2) describe the chosen plugin and inspect enabled, managerControl, callableNow, and tools[].inputSchema;',\n '(3) if disabled, enable only when managerControl=\"allowed\"\u2014never work around \"locked\"; when restartRequired=true, tell the user the plugin cannot be used until WrongStack restarts;',\n '(4) call use with only plugin to refresh/inspect callable tool schemas;',\n '(5) call use again with the exact tool name and schema-valid input.',\n 'Examples: search={\"action\":\"search\",\"query\":\"release notes\"}; describe={\"action\":\"describe\",\"plugin\":\"release-notes-generator\"}; inspect-use={\"action\":\"use\",\"plugin\":\"release-notes-generator\"}; invoke-use={\"action\":\"use\",\"plugin\":\"release-notes-generator\",\"tool\":\"generate_release_notes\",\"input\":{\"to\":\"HEAD\"}}.',\n 'use works only for tools loaded now. If the result is needs_direct_call, call the returned tool directly so its confirm/deny/destructive policy runs.',\n 'disable also normally affects the next boot, not already-loaded code.',\n].join(' ');\n\nexport function createPluginManagerTool(opts: CreatePluginManagerToolOptions): Tool {\n return {\n name: PLUGIN_MANAGER_TOOL_NAME,\n description:\n 'Manage WrongStack plugins through a guarded discovery-first workflow. Search the host catalog, inspect effective state and live plugin-owned tool schemas, persist allowed enable/disable changes, and invoke tools from plugins already loaded in this session. This does not install arbitrary packages or bypass plugin/tool permissions.',\n usageHint: USAGE_HINT,\n selection: {\n doNotUseWhen:\n 'installing a new npm package, editing plugin-specific options, changing per-plugin LLM routing, or bypassing a managerControl lock/tool permission',\n },\n category: 'Config',\n inputSchema: INPUT_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n subjectKey: 'plugin',\n capabilities: [\n ToolCapabilities.TOOL_META,\n ToolCapabilities.TOOL_MUTATE_ANY,\n ToolCapabilities.CONFIG_MUTATE,\n ],\n icon: 'settings',\n validate(input) {\n const value = input as PluginManagerInput;\n const errors: string[] = [];\n if (value.action === 'search' && !value.query?.trim()) {\n errors.push('query is required when action=\"search\"');\n }\n if (\n ['describe', 'enable', 'disable', 'use'].includes(value.action) &&\n !value.plugin?.trim()\n ) {\n errors.push(`plugin is required when action=\"${value.action}\"`);\n }\n if (value.action === 'use' && value.tool && value.input === undefined) {\n errors.push('input is required when action=\"use\" includes a tool');\n }\n return errors;\n },\n async execute(rawInput, ctx, executeOpts) {\n const input = rawInput as PluginManagerInput;\n const views = buildPluginViews(opts);\n\n if (input.action === 'list' || input.action === 'search') {\n const needle = input.action === 'search' ? input.query!.trim().toLowerCase() : '';\n const state = input.state ?? 'all';\n const matches = views.filter((view) => {\n if (state !== 'all' && view.enabled !== (state === 'enabled')) return false;\n if (!needle) return true;\n const haystack = [\n view.name,\n ...view.aliases,\n view.description,\n ...view.tools.flatMap((tool) => [tool.name, tool.description]),\n ]\n .join('\\n')\n .toLowerCase();\n return haystack.includes(needle);\n });\n return {\n status: 'ok',\n action: input.action,\n count: matches.length,\n plugins: matches.map(compactView),\n };\n }\n\n const resolved = resolvePlugin(input.plugin!, views);\n if ('error' in resolved) return { status: 'error', message: resolved.error };\n const plugin = resolved.plugin;\n\n if (input.action === 'describe') {\n return { status: 'ok', action: 'describe', plugin };\n }\n\n if (input.action === 'enable' || input.action === 'disable') {\n const enabled = input.action === 'enable';\n if (plugin.managerControl === 'locked') {\n return {\n status: 'error',\n code: 'plugin_manager_locked',\n message:\n `Plugin \"${plugin.name}\" is locked against LLM enable/disable changes. ` +\n 'Only the user can change it with /plugin or update pluginManager.locked.',\n };\n }\n if (!enabled && !plugin.canDisable) {\n return {\n status: 'error',\n message: `Plugin \"${plugin.name}\" is locked and cannot be disabled.`,\n };\n }\n if (plugin.enabled === enabled && plugin.stateSource !== 'feature_flag') {\n return {\n status: 'ok',\n action: input.action,\n changed: false,\n restartRequired: false,\n message: `Plugin \"${plugin.name}\" is already ${enabled ? 'enabled' : 'disabled'}.`,\n };\n }\n const result = await opts.setEnabled(plugin.name, enabled);\n return {\n status: result.ok ? 'ok' : 'error',\n action: input.action,\n changed: result.ok,\n restartRequired: result.restartRequired ?? result.ok,\n message: result.message,\n };\n }\n\n if (!plugin.enabled) {\n return {\n status: 'error',\n message: `Plugin \"${plugin.name}\" is disabled. Enable it first; newly enabled plugins become callable after restart.`,\n };\n }\n if (!input.tool) {\n return {\n status: 'ok',\n action: 'use',\n ready: plugin.callableNow,\n message: plugin.callableNow\n ? `Choose one of the loaded tools registered by \"${plugin.name}\".`\n : `Plugin \"${plugin.name}\" has no callable tool loaded in this session. It may be hook/command-only or require a restart/configuration.`,\n plugin,\n };\n }\n\n const selected = plugin.tools.find((tool) => tool.name === input.tool);\n if (!selected) {\n return {\n status: 'error',\n message: `Tool \"${input.tool}\" is not registered by plugin \"${plugin.name}\" in this session.`,\n availableTools: plugin.tools.map((tool) => tool.name),\n };\n }\n if (!selected.enabled) {\n return {\n status: 'error',\n message: `Tool \"${selected.name}\" is registered but disabled by the tool configuration.`,\n };\n }\n\n const tool = opts.toolRegistry.get(selected.name);\n if (!tool || !ownerMatches(opts.toolRegistry.ownerOf(selected.name), plugin)) {\n return {\n status: 'error',\n message: `Tool \"${selected.name}\" is no longer available from \"${plugin.name}\".`,\n };\n }\n if (tool.permission !== 'auto' || tool.riskTier === 'destructive') {\n return {\n status: 'needs_direct_call',\n message:\n `Tool \"${tool.name}\" requires the normal permission path (${tool.permission}, risk=${tool.riskTier ?? 'standard'}). ` +\n 'Call it directly so WrongStack can apply its own approval and policy checks.',\n directCall: { tool: tool.name, input: input.input ?? {}, inputSchema: tool.inputSchema },\n };\n }\n\n const nestedInput = input.input ?? {};\n const validation = validateAgainstSchema(nestedInput, tool.inputSchema);\n if (!validation.ok) {\n return {\n status: 'error',\n message: `Invalid input for plugin tool \"${tool.name}\".`,\n errors: validation.errors,\n inputSchema: tool.inputSchema,\n };\n }\n const crossFieldErrors = tool.validate?.(nestedInput) ?? [];\n if (crossFieldErrors.length > 0) {\n return {\n status: 'error',\n message: `Invalid input for plugin tool \"${tool.name}\".`,\n errors: crossFieldErrors,\n inputSchema: tool.inputSchema,\n };\n }\n\n const result = await tool.execute(nestedInput, ctx, executeOpts);\n return { status: 'ok', action: 'use', plugin: plugin.name, tool: tool.name, result };\n },\n };\n}\n\nfunction buildPluginViews(opts: CreatePluginManagerToolOptions): PluginView[] {\n const config = opts.getConfig();\n const configured = config.plugins ?? [];\n const catalog = [...opts.catalog];\n const knownNames = new Set(catalog.flatMap((entry) => [entry.name, ...(entry.aliases ?? [])]));\n\n for (const item of configured) {\n const name = pluginConfigName(item);\n if (!knownNames.has(name)) {\n catalog.push({\n name,\n description: 'User-configured plugin (not present in the built-in discovery catalog).',\n risk: 'medium',\n defaultState: 'inactive',\n canDisable: true,\n });\n knownNames.add(name);\n }\n }\n\n return catalog\n .map((entry): PluginView => {\n const aliases = [...(entry.aliases ?? [])];\n const names = new Set([entry.name, ...aliases]);\n const configuredEntry = configured.find((item) => names.has(pluginConfigName(item)));\n const globallyDisabled = config.features?.plugins === false;\n const enabled = globallyDisabled\n ? false\n : configuredEntry === undefined\n ? entry.defaultState === 'active'\n : typeof configuredEntry === 'string' || configuredEntry.enabled !== false;\n const stateSource = globallyDisabled\n ? 'feature_flag'\n : configuredEntry === undefined\n ? 'default'\n : 'config';\n const tools = pluginTools(opts.toolRegistry, entry.name, aliases);\n const managerControl = isManagerLocked(config, entry.name, aliases) ? 'locked' : 'allowed';\n return {\n name: entry.name,\n description: entry.description,\n risk: entry.risk,\n enabled,\n stateSource,\n canDisable: entry.canDisable,\n managerControl,\n aliases,\n callableNow: enabled && tools.some((tool) => tool.enabled),\n tools,\n };\n })\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\nfunction isManagerLocked(config: Config, name: string, aliases: readonly string[]): boolean {\n const locked = new Set(\n (config.pluginManager?.locked ?? []).map((entry) => entry.trim().toLowerCase()),\n );\n if (locked.has('*')) return true;\n return [name, ...aliases].some((entry) => locked.has(entry.toLowerCase()));\n}\n\nfunction pluginTools(\n registry: ToolRegistry,\n name: string,\n aliases: readonly string[],\n): PluginToolView[] {\n const plugin = { name, aliases };\n const active = registry\n .listWithOwner()\n .filter(({ owner }) => ownerMatches(owner, plugin))\n .map(({ tool }) => toolView(tool, true));\n const disabled = registry\n .listDisabled()\n .filter(({ owner }) => ownerMatches(owner, plugin))\n .map(({ tool }) => toolView(tool, false));\n return [...active, ...disabled].sort((a, b) => a.name.localeCompare(b.name));\n}\n\nfunction toolView(tool: Tool, enabled: boolean): PluginToolView {\n return {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n permission: tool.permission,\n enabled,\n };\n}\n\nfunction ownerMatches(\n owner: string | undefined,\n plugin: { name: string; aliases: readonly string[] },\n): boolean {\n if (!owner) return false;\n const names = new Set([plugin.name, ...plugin.aliases]);\n const segments = owner.split('+');\n return segments.length > 0 && segments.every((segment) => names.has(segment));\n}\n\nfunction resolvePlugin(\n input: string,\n views: PluginView[],\n): { plugin: PluginView } | { error: string } {\n const needle = input.trim().toLowerCase();\n const exact = views.find(\n (view) =>\n view.name.toLowerCase() === needle ||\n view.aliases.some((alias) => alias.toLowerCase() === needle),\n );\n if (exact) return { plugin: exact };\n const partial = views.filter(\n (view) =>\n view.name.toLowerCase().includes(needle) ||\n view.aliases.some((alias) => alias.toLowerCase().includes(needle)),\n );\n if (partial.length === 1) return { plugin: partial[0]! };\n if (partial.length > 1) {\n return {\n error: `Plugin name \"${input}\" is ambiguous. Matches: ${partial.map((view) => view.name).join(', ')}.`,\n };\n }\n return { error: `Plugin \"${input}\" was not found. Use plugin_manager search first.` };\n}\n\nfunction compactView(view: PluginView): Omit<PluginView, 'tools'> & { tools: string[] } {\n return { ...view, tools: view.tools.map((tool) => tool.name) };\n}\n\nfunction pluginConfigName(item: string | PluginConfig): string {\n return typeof item === 'string' ? item : item.name;\n}\n"],
5
- "mappings": "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",
6
- "names": ["path", "readFileSync", "statSync", "path", "fileURLToPath", "path", "projectHash", "existsSync", "readFileSync", "path", "readFileSync", "path", "readFileSync", "readFileSync", "path", "readFileSync", "readFileSync", "fileURLToPath", "readFileSync", "isDirectory", "statSync", "BENCHMARK_ENGINEER_META", "MEMORY_CURATOR_META", "FLEET_COORDINATOR_META", "PLUGIN_AUTHOR_META", "TOOL_AUTHOR_META", "fs", "path", "path", "INPUT_SCHEMA", "path", "INPUT_SCHEMA", "tool", "result"]
7
- }