muonroi-cli 1.8.4 → 1.9.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 (562) hide show
  1. package/LICENSE +17 -5
  2. package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
  3. package/dist/packages/agent-harness-core/src/driver.js +46 -0
  4. package/dist/packages/agent-harness-core/src/event-filter.js +11 -0
  5. package/dist/packages/agent-harness-core/src/event-redact.js +7 -0
  6. package/dist/packages/agent-harness-core/src/event-tee.d.ts +64 -0
  7. package/dist/packages/agent-harness-core/src/event-tee.js +104 -0
  8. package/dist/packages/agent-harness-core/src/mcp-server.d.ts +25 -0
  9. package/dist/packages/agent-harness-core/src/mcp-server.js +169 -21
  10. package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
  11. package/dist/packages/agent-harness-core/src/protocol.d.ts +90 -4
  12. package/dist/packages/agent-harness-core/src/protocol.js +15 -0
  13. package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
  14. package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
  15. package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
  16. package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
  17. package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
  18. package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
  19. package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
  20. package/dist/packages/agent-harness-opentui/src/install.js +10 -0
  21. package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
  22. package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
  23. package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
  24. package/dist/src/agent-harness/mock-model.d.ts +38 -0
  25. package/dist/src/agent-harness/mock-model.js +69 -3
  26. package/dist/src/agent-harness/test-spawn.js +31 -0
  27. package/dist/src/chat/chat-keychain.d.ts +7 -12
  28. package/dist/src/chat/chat-keychain.js +19 -86
  29. package/dist/src/cli/config/screen-providers.js +1 -1
  30. package/dist/src/cli/cost-forensics.d.ts +10 -0
  31. package/dist/src/cli/cost-forensics.js +18 -3
  32. package/dist/src/cli/keys-bundle.d.ts +1 -1
  33. package/dist/src/cli/keys-bundle.js +1 -1
  34. package/dist/src/cli/keys.d.ts +10 -47
  35. package/dist/src/cli/keys.js +31 -399
  36. package/dist/src/council/clarifier.d.ts +31 -3
  37. package/dist/src/council/clarifier.js +220 -32
  38. package/dist/src/council/context.js +49 -15
  39. package/dist/src/council/debate-checkpoint.d.ts +129 -0
  40. package/dist/src/council/debate-checkpoint.js +176 -0
  41. package/dist/src/council/debate-planner.js +54 -5
  42. package/dist/src/council/debate-summary.d.ts +25 -0
  43. package/dist/src/council/debate-summary.js +85 -0
  44. package/dist/src/council/debate.d.ts +169 -2
  45. package/dist/src/council/debate.js +1265 -135
  46. package/dist/src/council/index.d.ts +108 -1
  47. package/dist/src/council/index.js +670 -197
  48. package/dist/src/council/leader.d.ts +26 -0
  49. package/dist/src/council/leader.js +150 -9
  50. package/dist/src/council/llm.d.ts +94 -0
  51. package/dist/src/council/llm.js +348 -55
  52. package/dist/src/council/panel-select.d.ts +30 -0
  53. package/dist/src/council/panel-select.js +82 -0
  54. package/dist/src/council/planner.js +40 -0
  55. package/dist/src/council/preflight.d.ts +17 -0
  56. package/dist/src/council/preflight.js +50 -2
  57. package/dist/src/council/prompts.d.ts +39 -4
  58. package/dist/src/council/prompts.js +256 -69
  59. package/dist/src/council/stance-recall.d.ts +42 -0
  60. package/dist/src/council/stance-recall.js +57 -0
  61. package/dist/src/council/strip-think.d.ts +17 -0
  62. package/dist/src/council/strip-think.js +33 -0
  63. package/dist/src/council/types.d.ts +138 -0
  64. package/dist/src/ee/artifact-cache.d.ts +16 -0
  65. package/dist/src/ee/artifact-cache.js +32 -0
  66. package/dist/src/ee/auth.d.ts +20 -0
  67. package/dist/src/ee/auth.js +54 -2
  68. package/dist/src/ee/bridge.d.ts +10 -0
  69. package/dist/src/ee/bridge.js +58 -0
  70. package/dist/src/ee/client.js +109 -21
  71. package/dist/src/ee/ee-onboarding.js +6 -26
  72. package/dist/src/ee/export-transcripts.d.ts +1 -0
  73. package/dist/src/ee/export-transcripts.js +8 -10
  74. package/dist/src/ee/extract-session.js +29 -0
  75. package/dist/src/ee/extract-style.d.ts +58 -0
  76. package/dist/src/ee/extract-style.js +270 -0
  77. package/dist/src/ee/recall-ledger.d.ts +9 -0
  78. package/dist/src/ee/recall-ledger.js +3 -0
  79. package/dist/src/ee/scope.d.ts +1 -0
  80. package/dist/src/ee/scope.js +26 -1
  81. package/dist/src/ee/search.d.ts +7 -0
  82. package/dist/src/ee/search.js +24 -0
  83. package/dist/src/ee/transcript-emit.js +2 -0
  84. package/dist/src/ee/types.d.ts +22 -0
  85. package/dist/src/ee/who-am-i-brain.d.ts +35 -0
  86. package/dist/src/ee/who-am-i-brain.js +220 -0
  87. package/dist/src/ee/who-am-i.d.ts +10 -3
  88. package/dist/src/ee/who-am-i.js +12 -0
  89. package/dist/src/ee/workflow-event.d.ts +48 -0
  90. package/dist/src/ee/workflow-event.js +81 -0
  91. package/dist/src/flow/compaction/compress.d.ts +3 -3
  92. package/dist/src/flow/compaction/compress.js +58 -8
  93. package/dist/src/flow/compaction/extract.d.ts +4 -7
  94. package/dist/src/flow/compaction/extract.js +50 -10
  95. package/dist/src/flow/compaction/index.d.ts +14 -1
  96. package/dist/src/flow/compaction/index.js +96 -3
  97. package/dist/src/flow/compaction/input-guard.d.ts +24 -0
  98. package/dist/src/flow/compaction/input-guard.js +43 -0
  99. package/dist/src/flow/compaction/progress.d.ts +35 -0
  100. package/dist/src/flow/compaction/progress.js +35 -0
  101. package/dist/src/flow/fold-planning.d.ts +36 -0
  102. package/dist/src/flow/fold-planning.js +83 -0
  103. package/dist/src/flow/hierarchy.d.ts +146 -0
  104. package/dist/src/flow/hierarchy.js +427 -0
  105. package/dist/src/flow/index.d.ts +1 -0
  106. package/dist/src/flow/index.js +2 -0
  107. package/dist/src/flow/run-artifacts.d.ts +102 -0
  108. package/dist/src/flow/run-artifacts.js +208 -0
  109. package/dist/src/generated/version.d.ts +1 -1
  110. package/dist/src/generated/version.js +1 -1
  111. package/dist/src/gsd/assessment-schema.d.ts +44 -0
  112. package/dist/src/gsd/assessment-schema.js +134 -0
  113. package/dist/src/gsd/capability-registry.d.ts +45 -0
  114. package/dist/src/gsd/capability-registry.js +337 -0
  115. package/dist/src/gsd/complexity-assessor.d.ts +39 -0
  116. package/dist/src/gsd/complexity-assessor.js +152 -0
  117. package/dist/src/gsd/config-bridge.d.ts +7 -0
  118. package/dist/src/gsd/config-bridge.js +114 -0
  119. package/dist/src/gsd/config-loader.d.ts +27 -0
  120. package/dist/src/gsd/config-loader.js +50 -0
  121. package/dist/src/gsd/council-context.d.ts +44 -0
  122. package/dist/src/gsd/council-context.js +114 -0
  123. package/dist/src/gsd/ee-closure.d.ts +28 -0
  124. package/dist/src/gsd/ee-closure.js +49 -0
  125. package/dist/src/gsd/flags.d.ts +66 -0
  126. package/dist/src/gsd/flags.js +102 -0
  127. package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
  128. package/dist/src/gsd/gsd-dispatch.js +131 -0
  129. package/dist/src/gsd/gsd-runtime.d.ts +22 -0
  130. package/dist/src/gsd/gsd-runtime.js +37 -0
  131. package/dist/src/gsd/host-adapter.d.ts +11 -0
  132. package/dist/src/gsd/host-adapter.js +29 -0
  133. package/dist/src/gsd/index.d.ts +24 -1
  134. package/dist/src/gsd/index.js +27 -0
  135. package/dist/src/gsd/loop-host-contract.d.ts +21 -0
  136. package/dist/src/gsd/loop-host-contract.js +39 -0
  137. package/dist/src/gsd/loop-host.d.ts +69 -0
  138. package/dist/src/gsd/loop-host.js +245 -0
  139. package/dist/src/gsd/loop-resolver.d.ts +36 -0
  140. package/dist/src/gsd/loop-resolver.js +79 -0
  141. package/dist/src/gsd/model-tier.d.ts +13 -0
  142. package/dist/src/gsd/model-tier.js +45 -0
  143. package/dist/src/gsd/mutation-gate.d.ts +16 -0
  144. package/dist/src/gsd/mutation-gate.js +41 -0
  145. package/dist/src/gsd/native-roadmap.d.ts +89 -0
  146. package/dist/src/gsd/native-roadmap.js +343 -0
  147. package/dist/src/gsd/native-state.d.ts +47 -0
  148. package/dist/src/gsd/native-state.js +220 -0
  149. package/dist/src/gsd/paths.d.ts +23 -0
  150. package/dist/src/gsd/paths.js +66 -0
  151. package/dist/src/gsd/phase-dag.d.ts +12 -0
  152. package/dist/src/gsd/phase-dag.js +94 -0
  153. package/dist/src/gsd/phase-sync.d.ts +42 -0
  154. package/dist/src/gsd/phase-sync.js +321 -0
  155. package/dist/src/gsd/pil-gate-context.d.ts +13 -0
  156. package/dist/src/gsd/pil-gate-context.js +64 -0
  157. package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
  158. package/dist/src/gsd/pil-gate-critic.js +74 -0
  159. package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
  160. package/dist/src/gsd/plan-council-prompts.js +79 -0
  161. package/dist/src/gsd/plan-council.d.ts +44 -0
  162. package/dist/src/gsd/plan-council.js +283 -0
  163. package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
  164. package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
  165. package/dist/src/gsd/product-workspace.d.ts +13 -0
  166. package/dist/src/gsd/product-workspace.js +124 -0
  167. package/dist/src/gsd/ship-bridge.d.ts +25 -0
  168. package/dist/src/gsd/ship-bridge.js +65 -0
  169. package/dist/src/gsd/state-document.d.ts +40 -0
  170. package/dist/src/gsd/state-document.js +163 -0
  171. package/dist/src/gsd/verdict-schema.d.ts +39 -0
  172. package/dist/src/gsd/verdict-schema.js +144 -0
  173. package/dist/src/gsd/verify-context.d.ts +22 -0
  174. package/dist/src/gsd/verify-context.js +27 -0
  175. package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
  176. package/dist/src/gsd/verify-council-prompts.js +85 -0
  177. package/dist/src/gsd/verify-council.d.ts +25 -0
  178. package/dist/src/gsd/verify-council.js +119 -0
  179. package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
  180. package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
  181. package/dist/src/gsd/workflow-engine.d.ts +60 -0
  182. package/dist/src/gsd/workflow-engine.js +207 -0
  183. package/dist/src/gsd/workflow-tools.d.ts +13 -0
  184. package/dist/src/gsd/workflow-tools.js +277 -0
  185. package/dist/src/headless/council-answers.js +4 -0
  186. package/dist/src/hooks/index.js +1 -1
  187. package/dist/src/index.js +172 -270
  188. package/dist/src/lsp/builtins.js +3 -1
  189. package/dist/src/lsp/manager.d.ts +5 -1
  190. package/dist/src/lsp/manager.js +249 -3
  191. package/dist/src/lsp/npm-cache.d.ts +11 -1
  192. package/dist/src/lsp/npm-cache.js +17 -1
  193. package/dist/src/lsp/runtime.d.ts +6 -1
  194. package/dist/src/lsp/runtime.js +17 -1
  195. package/dist/src/lsp/types.d.ts +83 -1
  196. package/dist/src/lsp/types.js +10 -0
  197. package/dist/src/maintain/pr-builder.js +23 -13
  198. package/dist/src/mcp/auto-setup.js +57 -32
  199. package/dist/src/mcp/client-pool.js +44 -16
  200. package/dist/src/mcp/lsp-tools.d.ts +5 -1
  201. package/dist/src/mcp/lsp-tools.js +93 -2
  202. package/dist/src/mcp/mcp-keychain.d.ts +3 -5
  203. package/dist/src/mcp/mcp-keychain.js +9 -49
  204. package/dist/src/mcp/research-onboarding.js +8 -7
  205. package/dist/src/mcp/runtime.js +34 -2
  206. package/dist/src/mcp/setup-guide-text.d.ts +1 -1
  207. package/dist/src/mcp/setup-guide-text.js +22 -2
  208. package/dist/src/mcp/tools-server.d.ts +10 -0
  209. package/dist/src/mcp/tools-server.js +10 -2
  210. package/dist/src/models/catalog-client.d.ts +87 -0
  211. package/dist/src/models/catalog-client.js +105 -38
  212. package/dist/src/models/catalog.json +528 -265
  213. package/dist/src/models/registry.d.ts +22 -7
  214. package/dist/src/models/registry.js +73 -10
  215. package/dist/src/ops/doctor.js +1 -1
  216. package/dist/src/orchestrator/ask-user.d.ts +61 -0
  217. package/dist/src/orchestrator/ask-user.js +65 -0
  218. package/dist/src/orchestrator/auto-commit.js +1 -1
  219. package/dist/src/orchestrator/batch-turn-runner.js +2 -2
  220. package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
  221. package/dist/src/orchestrator/cache-prefix.js +83 -0
  222. package/dist/src/orchestrator/compact-request.d.ts +32 -0
  223. package/dist/src/orchestrator/compact-request.js +41 -0
  224. package/dist/src/orchestrator/compaction.d.ts +12 -3
  225. package/dist/src/orchestrator/compaction.js +35 -15
  226. package/dist/src/orchestrator/council-manager.d.ts +12 -3
  227. package/dist/src/orchestrator/council-manager.js +74 -32
  228. package/dist/src/orchestrator/council-request.d.ts +49 -0
  229. package/dist/src/orchestrator/council-request.js +62 -0
  230. package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
  231. package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
  232. package/dist/src/orchestrator/error-utils.d.ts +29 -0
  233. package/dist/src/orchestrator/error-utils.js +132 -24
  234. package/dist/src/orchestrator/grounding-check.js +39 -1
  235. package/dist/src/orchestrator/interactive-pause.d.ts +26 -0
  236. package/dist/src/orchestrator/interactive-pause.js +36 -0
  237. package/dist/src/orchestrator/message-processor.d.ts +4 -0
  238. package/dist/src/orchestrator/message-processor.js +268 -41
  239. package/dist/src/orchestrator/orchestrator.d.ts +64 -3
  240. package/dist/src/orchestrator/orchestrator.js +823 -120
  241. package/dist/src/orchestrator/preprocessor.js +3 -3
  242. package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
  243. package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
  244. package/dist/src/orchestrator/prompts.js +17 -17
  245. package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
  246. package/dist/src/orchestrator/reactive-delegation.js +59 -0
  247. package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
  248. package/dist/src/orchestrator/retry-classifier.js +46 -2
  249. package/dist/src/orchestrator/safety-askcard.d.ts +1 -1
  250. package/dist/src/orchestrator/safety-askcard.js +5 -2
  251. package/dist/src/orchestrator/safety-intercept.d.ts +50 -0
  252. package/dist/src/orchestrator/safety-intercept.js +62 -0
  253. package/dist/src/orchestrator/scope-reminder.js +1 -1
  254. package/dist/src/orchestrator/session-experience.d.ts +2 -1
  255. package/dist/src/orchestrator/session-experience.js +2 -1
  256. package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
  257. package/dist/src/orchestrator/should-run-gate.js +18 -0
  258. package/dist/src/orchestrator/stall-watchdog.d.ts +31 -3
  259. package/dist/src/orchestrator/stall-watchdog.js +65 -10
  260. package/dist/src/orchestrator/stream-runner.d.ts +13 -3
  261. package/dist/src/orchestrator/stream-runner.js +115 -49
  262. package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
  263. package/dist/src/orchestrator/sub-agent-cap.js +16 -1
  264. package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
  265. package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
  266. package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
  267. package/dist/src/orchestrator/subagent-compactor.js +126 -15
  268. package/dist/src/orchestrator/tool-engine.d.ts +41 -0
  269. package/dist/src/orchestrator/tool-engine.js +846 -66
  270. package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
  271. package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
  272. package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
  273. package/dist/src/orchestrator/turn-watchdog.d.ts +44 -0
  274. package/dist/src/orchestrator/turn-watchdog.js +84 -0
  275. package/dist/src/pil/agent-operating-contract.d.ts +1 -1
  276. package/dist/src/pil/agent-operating-contract.js +6 -4
  277. package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
  278. package/dist/src/pil/cheap-model-playbook.js +5 -1
  279. package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
  280. package/dist/src/pil/cheap-model-workbooks.js +1 -1
  281. package/dist/src/pil/discovery-types.d.ts +1 -0
  282. package/dist/src/pil/discovery.d.ts +1 -1
  283. package/dist/src/pil/discovery.js +18 -13
  284. package/dist/src/pil/layer1-intent.d.ts +18 -6
  285. package/dist/src/pil/layer1-intent.js +66 -757
  286. package/dist/src/pil/layer15-context-scan.js +15 -1
  287. package/dist/src/pil/layer1_5-complexity-size.d.ts +7 -0
  288. package/dist/src/pil/layer1_5-complexity-size.js +31 -5
  289. package/dist/src/pil/layer3-ee-injection.js +23 -8
  290. package/dist/src/pil/layer4-gsd.js +69 -16
  291. package/dist/src/pil/layer5-context.js +7 -3
  292. package/dist/src/pil/layer6-output.d.ts +23 -0
  293. package/dist/src/pil/layer6-output.js +5 -1
  294. package/dist/src/pil/llm-classify.d.ts +111 -5
  295. package/dist/src/pil/llm-classify.js +421 -189
  296. package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
  297. package/dist/src/pil/native-capabilities-workbook.js +8 -0
  298. package/dist/src/pil/pipeline.js +36 -2
  299. package/dist/src/pil/repo-grounding-probe.d.ts +15 -0
  300. package/dist/src/pil/repo-grounding-probe.js +136 -0
  301. package/dist/src/pil/repo-structure-hints.d.ts +7 -0
  302. package/dist/src/pil/repo-structure-hints.js +45 -0
  303. package/dist/src/pil/response-tools.js +5 -3
  304. package/dist/src/pil/schema.d.ts +1 -0
  305. package/dist/src/pil/schema.js +2 -0
  306. package/dist/src/pil/types.d.ts +18 -0
  307. package/dist/src/playbook/directives.d.ts +4 -0
  308. package/dist/src/playbook/directives.js +17 -5
  309. package/dist/src/product-loop/artifact-io.js +4 -0
  310. package/dist/src/product-loop/backlog-builder.d.ts +14 -1
  311. package/dist/src/product-loop/backlog-builder.js +30 -6
  312. package/dist/src/product-loop/criteria-seed.d.ts +51 -0
  313. package/dist/src/product-loop/criteria-seed.js +200 -0
  314. package/dist/src/product-loop/discovery-context-format.js +3 -1
  315. package/dist/src/product-loop/discovery-ecosystem.js +4 -1
  316. package/dist/src/product-loop/discovery-interview.d.ts +9 -0
  317. package/dist/src/product-loop/discovery-interview.js +60 -12
  318. package/dist/src/product-loop/discovery-recommender.js +2 -1
  319. package/dist/src/product-loop/discovery-schema.js +19 -2
  320. package/dist/src/product-loop/discovery-triage.d.ts +23 -0
  321. package/dist/src/product-loop/discovery-triage.js +109 -0
  322. package/dist/src/product-loop/gather.js +150 -2
  323. package/dist/src/product-loop/ideal-trace.d.ts +7 -0
  324. package/dist/src/product-loop/ideal-trace.js +64 -0
  325. package/dist/src/product-loop/index.d.ts +13 -1
  326. package/dist/src/product-loop/index.js +340 -52
  327. package/dist/src/product-loop/loop-driver.d.ts +7 -0
  328. package/dist/src/product-loop/loop-driver.js +330 -106
  329. package/dist/src/product-loop/phase-plan.d.ts +21 -0
  330. package/dist/src/product-loop/phase-plan.js +81 -6
  331. package/dist/src/product-loop/phase-rituals.d.ts +3 -0
  332. package/dist/src/product-loop/phase-rituals.js +8 -3
  333. package/dist/src/product-loop/phase-runner.js +39 -12
  334. package/dist/src/product-loop/plan-adherence-review.d.ts +26 -0
  335. package/dist/src/product-loop/plan-adherence-review.js +144 -0
  336. package/dist/src/product-loop/sprint-runner.d.ts +173 -0
  337. package/dist/src/product-loop/sprint-runner.js +863 -19
  338. package/dist/src/product-loop/types.d.ts +61 -5
  339. package/dist/src/providers/adapter.d.ts +1 -1
  340. package/dist/src/providers/adapter.js +3 -4
  341. package/dist/src/providers/anthropic.d.ts +9 -8
  342. package/dist/src/providers/anthropic.js +13 -47
  343. package/dist/src/providers/auth/browser-flow.d.ts +1 -1
  344. package/dist/src/providers/auth/browser-flow.js +1 -1
  345. package/dist/src/providers/auth/grok-oauth.d.ts +1 -0
  346. package/dist/src/providers/auth/grok-oauth.js +30 -5
  347. package/dist/src/providers/auth/openai-oauth.d.ts +1 -0
  348. package/dist/src/providers/auth/openai-oauth.js +15 -1
  349. package/dist/src/providers/auth/registry.js +0 -34
  350. package/dist/src/providers/auth/token-store.d.ts +9 -9
  351. package/dist/src/providers/auth/token-store.js +8 -67
  352. package/dist/src/providers/auth/types.d.ts +9 -1
  353. package/dist/src/providers/auth/types.js +1 -1
  354. package/dist/src/providers/capabilities.d.ts +24 -5
  355. package/dist/src/providers/capabilities.js +42 -24
  356. package/dist/src/providers/endpoints.d.ts +2 -2
  357. package/dist/src/providers/endpoints.js +11 -10
  358. package/dist/src/providers/env-store.d.ts +17 -0
  359. package/dist/src/providers/env-store.js +228 -0
  360. package/dist/src/providers/keychain.d.ts +22 -18
  361. package/dist/src/providers/keychain.js +127 -140
  362. package/dist/src/providers/mcp-vision-bridge.js +56 -146
  363. package/dist/src/providers/openai-compatible.js +8 -1
  364. package/dist/src/providers/pricing.d.ts +2 -2
  365. package/dist/src/providers/pricing.js +3 -13
  366. package/dist/src/providers/runtime.d.ts +43 -3
  367. package/dist/src/providers/runtime.js +88 -14
  368. package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
  369. package/dist/src/providers/strategies/base.strategy.js +24 -1
  370. package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
  371. package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
  372. package/dist/src/providers/strategies/registry.js +4 -4
  373. package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
  374. package/dist/src/providers/strategies/thinking-mode.js +288 -1
  375. package/dist/src/providers/strategies/xai.strategy.js +27 -0
  376. package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
  377. package/dist/src/providers/strategies/zai.strategy.js +44 -0
  378. package/dist/src/providers/types.d.ts +5 -6
  379. package/dist/src/providers/types.js +2 -2
  380. package/dist/src/providers/vision-backend.d.ts +47 -0
  381. package/dist/src/providers/vision-backend.js +258 -0
  382. package/dist/src/providers/vision-proxy.d.ts +22 -9
  383. package/dist/src/providers/vision-proxy.js +63 -132
  384. package/dist/src/providers/warm.d.ts +65 -0
  385. package/dist/src/providers/warm.js +145 -0
  386. package/dist/src/providers/wire-debug.js +95 -0
  387. package/dist/src/router/decide.d.ts +13 -0
  388. package/dist/src/router/decide.js +138 -36
  389. package/dist/src/router/peak-hour.d.ts +38 -0
  390. package/dist/src/router/peak-hour.js +107 -0
  391. package/dist/src/router/step-router.js +3 -2
  392. package/dist/src/router/warm.js +4 -5
  393. package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
  394. package/dist/src/scaffold/continuation-prompt.js +26 -0
  395. package/dist/src/scaffold/point-to-existing.d.ts +21 -0
  396. package/dist/src/scaffold/point-to-existing.js +25 -0
  397. package/dist/src/self-qa/agentic-loop.js +6 -5
  398. package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
  399. package/dist/src/{ui/state → state}/active-run.js +21 -0
  400. package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
  401. package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
  402. package/dist/src/state/turn-trace.d.ts +43 -0
  403. package/dist/src/state/turn-trace.js +32 -0
  404. package/dist/src/storage/db.js +2 -1
  405. package/dist/src/storage/index.d.ts +1 -1
  406. package/dist/src/storage/index.js +1 -1
  407. package/dist/src/storage/interaction-log.d.ts +1 -1
  408. package/dist/src/storage/migrations.js +71 -1
  409. package/dist/src/storage/sessions.d.ts +28 -10
  410. package/dist/src/storage/sessions.js +78 -21
  411. package/dist/src/storage/transcript-view.js +1 -1
  412. package/dist/src/storage/transcript.d.ts +51 -0
  413. package/dist/src/storage/transcript.js +340 -15
  414. package/dist/src/tools/file.d.ts +15 -0
  415. package/dist/src/tools/file.js +32 -0
  416. package/dist/src/tools/git-safety.d.ts +19 -0
  417. package/dist/src/tools/git-safety.js +168 -0
  418. package/dist/src/tools/native-tools.d.ts +1 -1
  419. package/dist/src/tools/native-tools.js +81 -1
  420. package/dist/src/tools/registry.d.ts +20 -0
  421. package/dist/src/tools/registry.js +576 -23
  422. package/dist/src/tools/research.d.ts +29 -0
  423. package/dist/src/tools/research.js +233 -0
  424. package/dist/src/types/index.d.ts +147 -4
  425. package/dist/src/ui/app.js +0 -0
  426. package/dist/src/ui/cards/product-status-card.js +1 -1
  427. package/dist/src/ui/components/agent-rail-activities.d.ts +26 -0
  428. package/dist/src/ui/components/agent-rail-activities.js +47 -0
  429. package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
  430. package/dist/src/ui/components/bubble-body-guard.js +50 -0
  431. package/dist/src/ui/components/compact-progress-card.d.ts +24 -0
  432. package/dist/src/ui/components/compact-progress-card.js +42 -0
  433. package/dist/src/ui/components/context-rail.d.ts +26 -0
  434. package/dist/src/ui/components/context-rail.js +33 -0
  435. package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
  436. package/dist/src/ui/components/council-conclusion-card.js +420 -0
  437. package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
  438. package/dist/src/ui/components/council-debate-pill.js +34 -0
  439. package/dist/src/ui/components/council-info-card.js +2 -2
  440. package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
  441. package/dist/src/ui/components/council-leader-bubble.js +21 -11
  442. package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
  443. package/dist/src/ui/components/council-message-bubble.js +16 -15
  444. package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
  445. package/dist/src/ui/components/council-phase-timeline.js +66 -17
  446. package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
  447. package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
  448. package/dist/src/ui/components/council-question-card.js +13 -12
  449. package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
  450. package/dist/src/ui/components/council-rail-rounds.js +57 -0
  451. package/dist/src/ui/components/council-round-group.d.ts +38 -0
  452. package/dist/src/ui/components/council-round-group.js +88 -0
  453. package/dist/src/ui/components/council-status-list.d.ts +3 -1
  454. package/dist/src/ui/components/council-status-list.js +36 -24
  455. package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
  456. package/dist/src/ui/components/council-synthesis-banner.js +20 -5
  457. package/dist/src/ui/components/halt-recovery-card.js +9 -5
  458. package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
  459. package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
  460. package/dist/src/ui/components/message-view.d.ts +15 -0
  461. package/dist/src/ui/components/message-view.js +50 -1
  462. package/dist/src/ui/components/prompt-box.js +18 -16
  463. package/dist/src/ui/components/session-tree-card.d.ts +14 -0
  464. package/dist/src/ui/components/session-tree-card.js +46 -0
  465. package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
  466. package/dist/src/ui/components/slash-inline-menu.js +26 -5
  467. package/dist/src/ui/components/task-list-panel.d.ts +14 -1
  468. package/dist/src/ui/components/task-list-panel.js +22 -2
  469. package/dist/src/ui/components/tool-group.d.ts +15 -3
  470. package/dist/src/ui/components/tool-group.js +69 -11
  471. package/dist/src/ui/containers/modals-layer.d.ts +4 -2
  472. package/dist/src/ui/containers/modals-layer.js +2 -2
  473. package/dist/src/ui/council-harness-event.d.ts +57 -0
  474. package/dist/src/ui/council-harness-event.js +46 -0
  475. package/dist/src/ui/heartbeat-debug.d.ts +29 -0
  476. package/dist/src/ui/heartbeat-debug.js +45 -0
  477. package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
  478. package/dist/src/ui/mcp-modal.js +2 -4
  479. package/dist/src/ui/modals/api-key-modal.js +1 -1
  480. package/dist/src/ui/modals/connect-modal.js +4 -3
  481. package/dist/src/ui/modals/model-picker-modal.d.ts +8 -18
  482. package/dist/src/ui/modals/model-picker-modal.js +8 -10
  483. package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
  484. package/dist/src/ui/modals/session-picker-modal.js +3 -5
  485. package/dist/src/ui/picker-providers.d.ts +1 -1
  486. package/dist/src/ui/picker-providers.js +1 -1
  487. package/dist/src/ui/primitives/index.d.ts +1 -0
  488. package/dist/src/ui/primitives/index.js +2 -0
  489. package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
  490. package/dist/src/ui/primitives/semantic-primitives.js +81 -0
  491. package/dist/src/ui/slash/compact.js +5 -7
  492. package/dist/src/ui/slash/cost.js +1 -1
  493. package/dist/src/ui/slash/council.js +19 -1
  494. package/dist/src/ui/slash/debug.d.ts +3 -31
  495. package/dist/src/ui/slash/debug.js +9 -20
  496. package/dist/src/ui/slash/ee.js +81 -0
  497. package/dist/src/ui/slash/ideal.d.ts +6 -2
  498. package/dist/src/ui/slash/ideal.js +97 -7
  499. package/dist/src/ui/slash/menu-items.d.ts +7 -0
  500. package/dist/src/ui/slash/menu-items.js +23 -20
  501. package/dist/src/ui/slash/registry.d.ts +2 -0
  502. package/dist/src/ui/slash/registry.js +4 -0
  503. package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
  504. package/dist/src/ui/status-bar/cache-hit.js +9 -0
  505. package/dist/src/ui/status-bar/index.d.ts +1 -1
  506. package/dist/src/ui/status-bar/index.js +7 -3
  507. package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
  508. package/dist/src/ui/status-bar/usd-meter.js +6 -4
  509. package/dist/src/ui/theme.d.ts +1 -0
  510. package/dist/src/ui/theme.js +2 -0
  511. package/dist/src/ui/types.d.ts +7 -0
  512. package/dist/src/ui/use-app-logic.js +0 -0
  513. package/dist/src/ui/utils/agent-activities.d.ts +39 -0
  514. package/dist/src/ui/utils/agent-activities.js +96 -0
  515. package/dist/src/ui/utils/format.d.ts +14 -0
  516. package/dist/src/ui/utils/format.js +23 -3
  517. package/dist/src/ui/utils/group-tool-entries.d.ts +26 -0
  518. package/dist/src/ui/utils/group-tool-entries.js +111 -0
  519. package/dist/src/ui/utils/tool-summary.d.ts +21 -0
  520. package/dist/src/ui/utils/tool-summary.js +91 -0
  521. package/dist/src/usage/downgrade.js +2 -2
  522. package/dist/src/usage/product-ledger.js +2 -2
  523. package/dist/src/utils/event-loop-monitor.d.ts +85 -0
  524. package/dist/src/utils/event-loop-monitor.js +107 -0
  525. package/dist/src/utils/install-manager.js +2 -1
  526. package/dist/src/utils/llm-deadline.d.ts +14 -0
  527. package/dist/src/utils/llm-deadline.js +19 -0
  528. package/dist/src/utils/logger.js +2 -2
  529. package/dist/src/utils/loop-profiler.d.ts +102 -0
  530. package/dist/src/utils/loop-profiler.js +202 -0
  531. package/dist/src/utils/permission-mode.js +5 -3
  532. package/dist/src/utils/redactor.js +1 -1
  533. package/dist/src/utils/settings.d.ts +180 -5
  534. package/dist/src/utils/settings.js +271 -31
  535. package/dist/src/utils/side-question.d.ts +1 -2
  536. package/dist/src/utils/side-question.js +2 -2
  537. package/dist/src/utils/visible-retry.d.ts +11 -0
  538. package/dist/src/utils/visible-retry.js +10 -1
  539. package/dist/src/verify/entrypoint.d.ts +1 -1
  540. package/dist/src/verify/entrypoint.js +52 -17
  541. package/dist/src/verify/orchestrator.d.ts +1 -1
  542. package/dist/src/verify/orchestrator.js +20 -3
  543. package/dist/src/verify/recipes.d.ts +13 -0
  544. package/dist/src/verify/recipes.js +15 -0
  545. package/package.json +134 -132
  546. package/dist/src/cli/bw-vault.d.ts +0 -55
  547. package/dist/src/cli/bw-vault.js +0 -133
  548. package/dist/src/mcp/ee-tools.d.ts +0 -46
  549. package/dist/src/mcp/ee-tools.js +0 -193
  550. package/dist/src/providers/auth/gcloud.d.ts +0 -28
  551. package/dist/src/providers/auth/gcloud.js +0 -102
  552. package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
  553. package/dist/src/providers/auth/gemini-oauth.js +0 -472
  554. package/dist/src/providers/gemini.d.ts +0 -11
  555. package/dist/src/providers/gemini.js +0 -45
  556. package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
  557. package/dist/src/providers/siliconflow-sse-repair.js +0 -177
  558. package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
  559. package/dist/src/providers/strategies/google.strategy.js +0 -174
  560. package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
  561. package/dist/src/ui/containers/chat-feed.d.ts +0 -40
  562. package/dist/src/ui/containers/chat-feed.js +0 -66
@@ -0,0 +1,176 @@
1
+ /**
2
+ * src/council/debate-checkpoint.ts
3
+ *
4
+ * C (mid-debate checkpoint) — persist the CB-1 council debate's per-round state
5
+ * so a break mid-debate (provider 5xx on round 5, host crash, cap breach) can
6
+ * resume from the last completed round instead of re-running the whole debate.
7
+ *
8
+ * The debate accumulates all state in RAM (`exchangeLogs`, `active`,
9
+ * `runningSummary`, `archive`, convergence trackers). Without a checkpoint a
10
+ * break loses every round — a 5-round multi-provider debate must restart from
11
+ * round 1. This module owns the on-disk snapshot: `runDebate` writes it after
12
+ * each completed round and deletes it on normal completion; the resume path
13
+ * reads it and seeds `runDebate` so it skips research + openings + completed
14
+ * rounds.
15
+ *
16
+ * File: `<checkpointDir>/debate-checkpoint.json` (checkpointDir = the run dir,
17
+ * `.muonroi-flow/runs/<runId>`). Written atomically (tmp + rename) so a crash
18
+ * mid-write can never leave a half-JSON file.
19
+ */
20
+ import { promises as fs } from "node:fs";
21
+ import * as path from "node:path";
22
+ /** Bump when the checkpoint shape changes incompatibly so stale files are ignored. */
23
+ export const DEBATE_CHECKPOINT_VERSION = 1;
24
+ export const DEBATE_CHECKPOINT_FILE = "debate-checkpoint.json";
25
+ /** Build the serializable checkpoint payload from live debate state. */
26
+ export function buildDebateCheckpoint(input) {
27
+ return {
28
+ version: DEBATE_CHECKPOINT_VERSION,
29
+ problemStatement: input.problemStatement,
30
+ participantModels: input.active.map((p) => p.model),
31
+ roundCount: input.roundCount,
32
+ maxRounds: input.maxRounds,
33
+ exchangeLogs: [...input.exchangeLogs.entries()].map(([k, v]) => [k, [...v]]),
34
+ runningSummary: input.runningSummary,
35
+ researchFindings: input.researchFindings,
36
+ active: input.active,
37
+ archive: input.archive,
38
+ lastCriteriaMet: [...input.lastCriteriaMet],
39
+ bestCriteriaMetCount: input.bestCriteriaMetCount,
40
+ roundsSinceProgress: input.roundsSinceProgress,
41
+ nextTopic: input.nextTopic,
42
+ savedAt: input.savedAt,
43
+ };
44
+ }
45
+ /** Rehydrate `exchangeLogs` from the serialized entry tuples. */
46
+ export function restoreExchangeLogs(cp) {
47
+ return new Map(cp.exchangeLogs.map(([k, v]) => [k, [...v]]));
48
+ }
49
+ /**
50
+ * Whether `cp` describes the debate that is about to run. Guards against
51
+ * splicing a stale checkpoint (different question, re-resolved panel) into a
52
+ * fresh debate. Participant order is not significant; the model SET must match.
53
+ */
54
+ export function checkpointMatches(cp, problemStatement, participantModels) {
55
+ if (cp.version !== DEBATE_CHECKPOINT_VERSION)
56
+ return false;
57
+ if (cp.roundCount < 1)
58
+ return false; // nothing useful to resume from
59
+ if (cp.problemStatement !== problemStatement)
60
+ return false;
61
+ const a = [...cp.participantModels].sort();
62
+ const b = [...participantModels].sort();
63
+ if (a.length !== b.length)
64
+ return false;
65
+ return a.every((m, i) => m === b[i]);
66
+ }
67
+ /**
68
+ * Atomically write the checkpoint to `<dir>/debate-checkpoint.json`.
69
+ * Non-fatal: a checkpoint write failure must never break the live debate — it
70
+ * only forfeits resumability for that round. Logs with context (No-Silent-Catch).
71
+ */
72
+ export async function writeDebateCheckpoint(dir, cp) {
73
+ const finalPath = path.join(dir, DEBATE_CHECKPOINT_FILE);
74
+ const tmpPath = `${finalPath}.${process.pid}.tmp`;
75
+ try {
76
+ await fs.mkdir(dir, { recursive: true });
77
+ await fs.writeFile(tmpPath, JSON.stringify(cp), "utf8");
78
+ await fs.rename(tmpPath, finalPath);
79
+ }
80
+ catch (err) {
81
+ console.error(`[debate-checkpoint] write failed (dir=${dir}, round=${cp.roundCount}): ${err?.message}`);
82
+ // Best-effort cleanup of the temp file; ignore if it never got created.
83
+ await fs.rm(tmpPath, { force: true }).catch(() => { });
84
+ }
85
+ }
86
+ /**
87
+ * Read + parse the checkpoint. Returns null when absent or unparseable (a
88
+ * corrupt checkpoint must not crash resume — the debate just runs fresh).
89
+ */
90
+ export async function readDebateCheckpoint(dir) {
91
+ const finalPath = path.join(dir, DEBATE_CHECKPOINT_FILE);
92
+ let raw;
93
+ try {
94
+ raw = await fs.readFile(finalPath, "utf8");
95
+ }
96
+ catch (err) {
97
+ if (err?.code !== "ENOENT") {
98
+ console.error(`[debate-checkpoint] read failed (dir=${dir}): ${err?.message}`);
99
+ }
100
+ return null;
101
+ }
102
+ try {
103
+ const parsed = JSON.parse(raw);
104
+ if (parsed?.version !== DEBATE_CHECKPOINT_VERSION)
105
+ return null;
106
+ return parsed;
107
+ }
108
+ catch (err) {
109
+ console.error(`[debate-checkpoint] parse failed (dir=${dir}): ${err?.message}`);
110
+ return null;
111
+ }
112
+ }
113
+ /**
114
+ * Delete the checkpoint (debate completed normally, or the run was aborted).
115
+ * Non-fatal — a leftover checkpoint is only re-validated (and discarded on
116
+ * mismatch) on the next resume, never silently mis-applied.
117
+ */
118
+ export async function deleteDebateCheckpoint(dir) {
119
+ const finalPath = path.join(dir, DEBATE_CHECKPOINT_FILE);
120
+ try {
121
+ await fs.rm(finalPath, { force: true });
122
+ }
123
+ catch (err) {
124
+ console.error(`[debate-checkpoint] delete failed (dir=${dir}): ${err?.message}`);
125
+ }
126
+ }
127
+ // ── Debate inputs (C-v2 cross-session resume) ────────────────────────────────
128
+ export const DEBATE_INPUTS_FILE = "debate-inputs.json";
129
+ /** Atomically persist the debate inputs. Non-fatal on failure (forfeits cross-session resume only). */
130
+ export async function writeDebateInputs(dir, inputs) {
131
+ const finalPath = path.join(dir, DEBATE_INPUTS_FILE);
132
+ const tmpPath = `${finalPath}.${process.pid}.tmp`;
133
+ try {
134
+ await fs.mkdir(dir, { recursive: true });
135
+ await fs.writeFile(tmpPath, JSON.stringify(inputs), "utf8");
136
+ await fs.rename(tmpPath, finalPath);
137
+ }
138
+ catch (err) {
139
+ console.error(`[debate-checkpoint] inputs write failed (dir=${dir}): ${err?.message}`);
140
+ await fs.rm(tmpPath, { force: true }).catch(() => { });
141
+ }
142
+ }
143
+ /** Read the debate inputs. Returns null when absent/unparseable/version-mismatched. */
144
+ export async function readDebateInputs(dir) {
145
+ const finalPath = path.join(dir, DEBATE_INPUTS_FILE);
146
+ let raw;
147
+ try {
148
+ raw = await fs.readFile(finalPath, "utf8");
149
+ }
150
+ catch (err) {
151
+ if (err?.code !== "ENOENT") {
152
+ console.error(`[debate-checkpoint] inputs read failed (dir=${dir}): ${err?.message}`);
153
+ }
154
+ return null;
155
+ }
156
+ try {
157
+ const parsed = JSON.parse(raw);
158
+ if (parsed?.version !== DEBATE_CHECKPOINT_VERSION)
159
+ return null;
160
+ return parsed;
161
+ }
162
+ catch (err) {
163
+ console.error(`[debate-checkpoint] inputs parse failed (dir=${dir}): ${err?.message}`);
164
+ return null;
165
+ }
166
+ }
167
+ /** Delete the debate inputs (debate + scoping finished, or run aborted). Non-fatal. */
168
+ export async function deleteDebateInputs(dir) {
169
+ try {
170
+ await fs.rm(path.join(dir, DEBATE_INPUTS_FILE), { force: true });
171
+ }
172
+ catch (err) {
173
+ console.error(`[debate-checkpoint] inputs delete failed (dir=${dir}): ${err?.message}`);
174
+ }
175
+ }
176
+ //# sourceMappingURL=debate-checkpoint.js.map
@@ -3,6 +3,7 @@ import { z } from "zod";
3
3
  import { loadKeyForProvider } from "../providers/keychain.js";
4
4
  import { createProviderFactory, detectProviderForModel, resolveModelRuntime } from "../providers/runtime.js";
5
5
  import { withDeadlineRace, withTimeoutSignal } from "../utils/llm-deadline.js";
6
+ import { logger } from "../utils/logger.js";
6
7
  import { getProviderStallTimeoutMs } from "../utils/settings.js";
7
8
  import { tracedGenerate } from "./llm.js";
8
9
  import { buildDebatePlanPrompt } from "./prompts.js";
@@ -94,6 +95,37 @@ function injectAuditorStance(plan, eeWarnings, experienceMode) {
94
95
  }
95
96
  return { ...plan, stances };
96
97
  }
98
+ /**
99
+ * PIL task types whose deliverable is understanding/evaluation of something that
100
+ * already exists — never a build. The user asked to assess, not to implement.
101
+ */
102
+ const ANALYSIS_TASK_TYPES = new Set(["analyze"]);
103
+ function isAnalysisTaskType(taskType) {
104
+ return !!taskType && ANALYSIS_TASK_TYPES.has(taskType);
105
+ }
106
+ /**
107
+ * Deterministic backstop for post-debate drift (session c4f78752a316).
108
+ *
109
+ * PIL is the authoritative intent classifier. When it says the request is
110
+ * analysis/evaluation, the leader LLM must not be allowed to silently reshape the
111
+ * debate into an `implementation_plan` — that shape makes the post-debate AskCard
112
+ * default to "generate_plan" (build a plan) via pickPostDebateRecommendation,
113
+ * which is the wrong next step for a request that only wanted an assessment.
114
+ *
115
+ * The prompt already asks the leader to honor the intent (soft), but LLMs drift;
116
+ * this coerces a drifted shape back to "evaluation" so the synthesis stays the
117
+ * deliverable and the default action becomes save_exit. Non-implementation shapes
118
+ * are left untouched.
119
+ */
120
+ function enforceAnalysisIntentShape(plan, taskType) {
121
+ if (!isAnalysisTaskType(taskType))
122
+ return plan;
123
+ if (plan.outputShape.kind !== "implementation_plan")
124
+ return plan;
125
+ logger.info("orchestrator", `[debate-planner] PIL taskType=${taskType} (analysis) but leader chose implementation_plan; ` +
126
+ "coercing outputShape.kind→evaluation to honor analysis intent");
127
+ return { ...plan, outputShape: { ...plan.outputShape, kind: "evaluation" } };
128
+ }
97
129
  export async function* planDebate(spec, leaderModelId, llm, eeWarnings, // CQ-13: experience snippets to seed prompt
98
130
  experienceMode, // CQ-14: controls Experience Auditor injection
99
131
  taskType, // CQ-11: task type from PIL (e.g. "architecture", "bugfix")
@@ -101,6 +133,10 @@ complexityTier, // CQ-11: complexity tier from PIL (e.g. "heavy", "medium", "lig
101
133
  signal) {
102
134
  const eeSnippets = eeWarnings?.map((w) => w.text).filter(Boolean) ?? [];
103
135
  const { system: baseSystem, prompt } = buildDebatePlanPrompt(spec);
136
+ // Every return path funnels through here: auditor + product-stance injection,
137
+ // plus the deterministic analysis-intent backstop (applied first so a coerced
138
+ // shape doesn't get a spurious product stance injected for it).
139
+ const finalizePlan = (plan) => ensureProductStance(injectAuditorStance(enforceAnalysisIntentShape(plan, taskType), eeWarnings, experienceMode));
104
140
  // Build calibration context from PIL metadata
105
141
  const pilCalibration = [];
106
142
  if (taskType)
@@ -111,6 +147,18 @@ signal) {
111
147
  if (pilCalibration.length > 0) {
112
148
  system += `\n\n## Task Context (from PIL)\n${pilCalibration.join("\n")}`;
113
149
  }
150
+ // Hard intent lock (steers stances AND shape). PIL already classified this as
151
+ // analysis; the deterministic backstop in finalizePlan enforces it regardless,
152
+ // but steering the leader here keeps the whole roster/synthesis on-intent.
153
+ if (isAnalysisTaskType(taskType)) {
154
+ system +=
155
+ `\n\n## INTENT LOCK (authoritative)\n` +
156
+ `PIL classified this request as ANALYSIS/EVALUATION (taskType=${taskType}). The user wants to ` +
157
+ `understand and assess what ALREADY exists — not to build anything. ` +
158
+ `outputShape.kind MUST be "evaluation" or "investigation" — NEVER "implementation_plan". ` +
159
+ `Do NOT propose building, implementing, scaffolding, or "I'll spec that in vN". ` +
160
+ `Stances must be analyst/critic/investigator voices, not implementers.`;
161
+ }
114
162
  if (eeSnippets.length > 0) {
115
163
  system += `\n\n## Experience Warnings (from brain)\nNote these past mistakes when designing debate stances:\n${eeSnippets.map((s) => `- ${s}`).join("\n")}`;
116
164
  }
@@ -129,8 +177,9 @@ signal) {
129
177
  try {
130
178
  const providerId = detectProviderForModel(leaderModelId);
131
179
  const key = await loadKeyForProvider(providerId);
132
- const { factory } = createProviderFactory(providerId, { apiKey: key });
133
- const runtime = resolveModelRuntime(factory, leaderModelId);
180
+ // Registers the leader provider's factory so resolveModelRuntime can derive it.
181
+ createProviderFactory(providerId, { apiKey: key });
182
+ const runtime = resolveModelRuntime(leaderModelId);
134
183
  // Bound attempt-1: a wedged provider response here would freeze the whole
135
184
  // council/loop silently (no streamText stall watchdog covers generateObject).
136
185
  // On timeout this rejects → caught below → retry (guarded) → fallback plan.
@@ -158,7 +207,7 @@ signal) {
158
207
  outputShape,
159
208
  plannedRounds,
160
209
  };
161
- return ensureProductStance(injectAuditorStance(plan, eeWarnings, experienceMode));
210
+ return finalizePlan(plan);
162
211
  }
163
212
  // Invalid even with schema — fall through to retry with a sanitize-failure message
164
213
  throw new Error("Sanitize check failed: stances.length < 2 or outputShape is null");
@@ -180,7 +229,7 @@ signal) {
180
229
  });
181
230
  const retryParsed = parsePlan(retryRaw);
182
231
  if (retryParsed)
183
- return ensureProductStance(injectAuditorStance(retryParsed, eeWarnings, experienceMode));
232
+ return finalizePlan(retryParsed);
184
233
  }
185
234
  catch (retryErr) {
186
235
  yield {
@@ -190,7 +239,7 @@ signal) {
190
239
  }
191
240
  }
192
241
  // All attempts exhausted — return fallback
193
- return ensureProductStance(injectAuditorStance(FALLBACK_PLAN, eeWarnings, experienceMode));
242
+ return finalizePlan(FALLBACK_PLAN);
194
243
  }
195
244
  function parsePlan(raw) {
196
245
  try {
@@ -0,0 +1,25 @@
1
+ /**
2
+ * src/council/debate-summary.ts
3
+ *
4
+ * Fallback debate-summary synthesis.
5
+ *
6
+ * The /ideal research phase persists the debate into `research.md` +
7
+ * `delegations.md` from `DebateState.runningSummary`. But a debate that returns
8
+ * after opening statements (e.g. the leader routes straight to the preflight
9
+ * gate without evaluation rounds) leaves `runningSummary` empty — and the whole
10
+ * debate (opening positions, design/impl reasoning) was silently dropped from
11
+ * the canonical artifacts, surviving only in TUI scrollback.
12
+ *
13
+ * This builds a faithful fallback from the participants' latest positions
14
+ * (`active[]`), falling back to per-round archive excerpts, so the research
15
+ * artifact ALWAYS captures the debate. Pure + synchronous → unit-testable.
16
+ */
17
+ import type { DebateState } from "./types.js";
18
+ /**
19
+ * Return a markdown summary of the debate suitable for `research.md` /
20
+ * `delegations.md`. Prefers `state.runningSummary` when present; otherwise
21
+ * synthesizes one from `active[]` positions, then `archive[]` excerpts. Returns
22
+ * "" only when there is genuinely nothing to show (no summary, no positions, no
23
+ * archive) — callers keep their existing "(no summary produced)" placeholder.
24
+ */
25
+ export declare function resolveDebateSummary(state: Pick<DebateState, "runningSummary" | "active" | "archive">): string;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * src/council/debate-summary.ts
3
+ *
4
+ * Fallback debate-summary synthesis.
5
+ *
6
+ * The /ideal research phase persists the debate into `research.md` +
7
+ * `delegations.md` from `DebateState.runningSummary`. But a debate that returns
8
+ * after opening statements (e.g. the leader routes straight to the preflight
9
+ * gate without evaluation rounds) leaves `runningSummary` empty — and the whole
10
+ * debate (opening positions, design/impl reasoning) was silently dropped from
11
+ * the canonical artifacts, surviving only in TUI scrollback.
12
+ *
13
+ * This builds a faithful fallback from the participants' latest positions
14
+ * (`active[]`), falling back to per-round archive excerpts, so the research
15
+ * artifact ALWAYS captures the debate. Pure + synchronous → unit-testable.
16
+ */
17
+ /** Cap so the fallback can't balloon the artifact; per-position + overall. */
18
+ const PER_POSITION_CHARS = 4000;
19
+ const TOTAL_CHARS = 16000;
20
+ /**
21
+ * Return a markdown summary of the debate suitable for `research.md` /
22
+ * `delegations.md`. Prefers `state.runningSummary` when present; otherwise
23
+ * synthesizes one from `active[]` positions, then `archive[]` excerpts. Returns
24
+ * "" only when there is genuinely nothing to show (no summary, no positions, no
25
+ * archive) — callers keep their existing "(no summary produced)" placeholder.
26
+ */
27
+ export function resolveDebateSummary(state) {
28
+ const running = state.runningSummary?.trim();
29
+ if (running)
30
+ return running;
31
+ const fromPositions = summarizeFromActive(state.active);
32
+ if (fromPositions)
33
+ return fromPositions;
34
+ return summarizeFromArchive(state.archive);
35
+ }
36
+ function speakerLabel(role, stanceName) {
37
+ return stanceName?.trim() ? `${stanceName} (${role})` : role;
38
+ }
39
+ function summarizeFromActive(active) {
40
+ if (!Array.isArray(active) || active.length === 0)
41
+ return "";
42
+ const parts = [
43
+ "_(Synthesized from participants' final positions — the debate produced no running summary.)_",
44
+ "",
45
+ ];
46
+ let total = 0;
47
+ for (const p of active) {
48
+ const position = (p.position ?? "").trim();
49
+ if (!position)
50
+ continue;
51
+ const clipped = position.length > PER_POSITION_CHARS ? `${position.slice(0, PER_POSITION_CHARS)}…` : position;
52
+ const block = `### ${speakerLabel(p.role, p.stance?.name)}\n\n${clipped}`;
53
+ if (total + block.length > TOTAL_CHARS) {
54
+ parts.push("_(remaining positions truncated)_");
55
+ break;
56
+ }
57
+ parts.push(block, "");
58
+ total += block.length;
59
+ }
60
+ // Only the header + no real positions → nothing worth persisting.
61
+ return parts.length > 2 ? parts.join("\n").trimEnd() : "";
62
+ }
63
+ function summarizeFromArchive(archive) {
64
+ if (!Array.isArray(archive) || archive.length === 0)
65
+ return "";
66
+ const parts = [
67
+ "_(Synthesized from per-round debate excerpts — the debate produced no running summary.)_",
68
+ "",
69
+ ];
70
+ let total = 0;
71
+ for (const e of archive) {
72
+ const excerpt = (e.excerpt ?? "").trim();
73
+ if (!excerpt)
74
+ continue;
75
+ const block = `### Round ${e.round} — ${speakerLabel(e.role, e.stanceName)}\n\n${excerpt}`;
76
+ if (total + block.length > TOTAL_CHARS) {
77
+ parts.push("_(remaining excerpts truncated)_");
78
+ break;
79
+ }
80
+ parts.push(block, "");
81
+ total += block.length;
82
+ }
83
+ return parts.length > 2 ? parts.join("\n").trimEnd() : "";
84
+ }
85
+ //# sourceMappingURL=debate-summary.js.map
@@ -1,5 +1,5 @@
1
- import type { StreamChunk } from "../types/index.js";
2
- import type { ClarifiedSpec, CouncilConfig, CouncilLLM, DebateState } from "./types.js";
1
+ import type { CouncilQuestionOption, StreamChunk } from "../types/index.js";
2
+ import type { ClarifiedSpec, CouncilConfig, CouncilLLM, DebateStance, DebateState, IsolatedTaskRunner, QuestionResponder } from "./types.js";
3
3
  /**
4
4
  * Resolve the initial round budget + hard ceiling from the plan's output-shape kind
5
5
  * and the planner-proposed round count. Pure + exported for unit testing the cap.
@@ -9,5 +9,172 @@ export declare function resolveDebateRoundBudget(planKind: string | undefined, p
9
9
  effectiveCeiling: number;
10
10
  kindCapped: boolean;
11
11
  };
12
+ export declare function researchWithFallback(llm: CouncilLLM, primaryModel: string, topic: string, conversationContext: string, signal: AbortSignal | undefined, traceCb: (t: string) => void, options: {
13
+ internetFirst?: boolean;
14
+ }, fallbackPool: string[], runIsolatedTask?: IsolatedTaskRunner): Promise<string>;
12
15
  export declare function runDebate(spec: ClarifiedSpec, config: CouncilConfig, llm: CouncilLLM): AsyncGenerator<StreamChunk, DebateState, unknown>;
13
16
  export declare function evaluateResearchNeed(spec: ClarifiedSpec, leaderModelId: string, conversationContext: string, llm: CouncilLLM, costAware?: boolean): AsyncGenerator<StreamChunk, boolean, unknown>;
17
+ /**
18
+ * F3b — robustly extract the leader-evaluation JSON object from a model's raw
19
+ * output. Replaces a greedy `/\{[\s\S]*\}/` match that could swallow prose,
20
+ * multiple objects, or a trailing partial object into an unparseable span.
21
+ *
22
+ * Strategy: strip code fences, then brace-scan and return the LAST fully
23
+ * balanced top-level `{…}` object (the eval schema is emitted last, after any
24
+ * chain-of-thought prose). Returns null only when no balanced object exists.
25
+ * Deterministic, no LLM call. Braces inside string values are rare in the
26
+ * machine-emitted eval payload; a real tokenizer would be overkill here.
27
+ */
28
+ export declare function extractEvalJson(raw: string): string | null;
29
+ /**
30
+ * Format a speaker list as newline-joined "Name — lens" rows for the composing
31
+ * placeholder (A: live debate preview). Prefers the concrete `focus`, falls back
32
+ * to the one-sentence `lens`, then to bare name. Dedups identical rows so a
33
+ * speaker in multiple pairs renders once. Returns undefined when nothing useful
34
+ * is available so the UI falls back to label-only.
35
+ */
36
+ /**
37
+ * Project a leader evaluation's `criteriaStatus` onto the PINNED spec criteria,
38
+ * returning a boolean[] index-aligned to `pinned` (B2/B3). The eval prompt asks
39
+ * for one entry per criterion in order, so index alignment is the primary path;
40
+ * when the model drifts (wrong count/order) we fall back to a case-insensitive
41
+ * substring match either direction, defaulting unmatched criteria to not-met so
42
+ * a hallucinated "all met" never silently marks an untouched criterion done.
43
+ */
44
+ export declare function alignCriteriaMet(pinned: string[], status: Array<{
45
+ criterion?: string;
46
+ met?: boolean;
47
+ }>): boolean[];
48
+ /**
49
+ * B5 leader-conductor visibility. Default ON; opt out with
50
+ * MUONROI_LEADER_CONDUCTOR=0 (fallback = pre-B5 behavior, no directive/verdict
51
+ * messages — keeps headless/legacy transcripts unchanged).
52
+ */
53
+ export declare function leaderConductorEnabled(): boolean;
54
+ /**
55
+ * B4 leader auto-remedy. When pinned criteria remain unmet at the round budget's
56
+ * end, the leader auto-extends toward them (up to the hard ceiling) instead of
57
+ * stopping at the initial plan — "done = all criteria met", ceiling is a managed
58
+ * budget. Default ON under the conductor; opt out with
59
+ * MUONROI_COUNCIL_AUTO_REMEDY=0 (fallback = only leader-requested extensions).
60
+ */
61
+ export declare function leaderAutoRemedyEnabled(): boolean;
62
+ /**
63
+ * #3 — grounding-verify pass. When a debate ends with weak evidence density
64
+ * (< GROUNDING_VERIFY_THRESHOLD, i.e. debaters barely tagged any [CONFIRMED]/
65
+ * [REFUTED] claims — the common case since each debater is capped at
66
+ * stepCountIs(2)), an isolated explore sub-agent verifies the load-bearing
67
+ * claims against the codebase and emits authoritative tags that raise the
68
+ * density metric council uses for confidence. Default ON when an isolated-task
69
+ * bridge is wired; opt out with MUONROI_COUNCIL_GROUNDING_VERIFY=0.
70
+ */
71
+ export declare function groundingVerifyEnabled(): boolean;
72
+ /**
73
+ * #3 — run an isolated explore sub-agent that fact-checks the debate's
74
+ * load-bearing claims and emits `[CONFIRMED via file:line]` / `[REFUTED via …]`
75
+ * tags (the exact shape `countCitations` recognises). Returns the tagged output
76
+ * on success, or "" on any failure (caller only folds it in when it actually
77
+ * raised the citation count).
78
+ */
79
+ export declare function runGroundingVerify(runIsolatedTask: IsolatedTaskRunner, model: string, problemStatement: string, exchangeText: string, traceCb: (t: string) => void): Promise<string>;
80
+ /**
81
+ * B4: does auto-remedy want to extend the budget this round? True while pinned
82
+ * criteria remain unmet AND progress is still being made (a new criterion was
83
+ * met within the last 2 rounds). A stuck debate (roundsSinceProgress ≥ 2) returns
84
+ * false so the ceiling isn't burned chasing a criterion that isn't moving.
85
+ */
86
+ export declare function autoRemedyWantsExtend(pinnedUnmet: number, roundsSinceProgress: number): boolean;
87
+ /**
88
+ * B4: the diagnostic closing-remedy line for a debate that ended with unmet
89
+ * pinned criteria — distinguishes a stuck criterion (needs evidence/rescope)
90
+ * from a genuine ceiling hit (needs a higher budget) from an ordinary early
91
+ * stop, so the leader's final word is an actionable next move, not a shrug.
92
+ */
93
+ export declare function diagnoseUnmetRemedy(opts: {
94
+ stuck: boolean;
95
+ atCeiling: boolean;
96
+ effectiveCeiling: number;
97
+ roundsSinceProgress: number;
98
+ }): string;
99
+ /**
100
+ * B4 interactive escalation. When the debate is about to stop with pinned
101
+ * criteria unmet AND auto-remedy can't help (stuck / at ceiling), hand the
102
+ * decision to the user instead of silently synthesizing a partial outcome.
103
+ * Default ON under the conductor; opt out with MUONROI_COUNCIL_ESCALATE=0
104
+ * (fallback = diagnostic closing verdict only, no askcard).
105
+ */
106
+ export declare function leaderEscalationEnabled(): boolean;
107
+ /**
108
+ * B4: should we interrupt to ask the user at this stop boundary? True only when
109
+ * pinned criteria remain unmet AND the leader can no longer self-remedy — it is
110
+ * stuck (no progress for ≥2 rounds) or has hit the round ceiling. While progress
111
+ * is still being made under the ceiling, auto-remedy handles it silently and we
112
+ * don't nag the user.
113
+ */
114
+ export declare function escalationWanted(opts: {
115
+ pinnedUnmet: number;
116
+ stuck: boolean;
117
+ atCeiling: boolean;
118
+ }): boolean;
119
+ /**
120
+ * B4: the three escalation choices. When the debate is already at the absolute
121
+ * safety ceiling, the "extend" option degrades to a disabled-looking accept
122
+ * (label says so) — we never let the user push past ABSOLUTE_MAX_ROUNDS.
123
+ */
124
+ export declare function buildEscalationOptions(unmetCount: number, atAbsoluteMax: boolean): CouncilQuestionOption[];
125
+ /**
126
+ * B4: emit the escalation askcard and resolve the user's choice. Yields the
127
+ * council_question chunk (rendered by the same consumer as clarifier/post-debate
128
+ * askcards), awaits the responder, echoes the choice, and returns the decision.
129
+ * `grantedRounds` is pre-computed here (bounded by ABSOLUTE_MAX_ROUNDS) so the
130
+ * caller only mutates loop state. Any unmatched / empty answer is treated as
131
+ * "accept" — never a silent hang.
132
+ */
133
+ export declare function runEscalationPrompt(opts: {
134
+ respondToQuestion: QuestionResponder;
135
+ openCriteria: string[];
136
+ pinnedUnmet: number;
137
+ stuck: boolean;
138
+ atAbsoluteMax: boolean;
139
+ currentMax: number;
140
+ }): AsyncGenerator<StreamChunk, {
141
+ action: "extend" | "accept" | "rescope";
142
+ grantedRounds: number;
143
+ }, unknown>;
144
+ /** One-line criterion label for directive/verdict bodies. */
145
+ export declare function shortCriterion(c: string, max?: number): string;
146
+ /**
147
+ * B5: build the leader's pre-round DIRECTIVE body — the round goal plus the
148
+ * criteria still unmet going into this round. `metSoFar` is the prior round's
149
+ * aligned criteriaMet (empty before round 1 → everything is unmet).
150
+ */
151
+ export declare function buildLeaderDirective(round: number, criteria: string[], metSoFar: boolean[], focus?: string): string;
152
+ /**
153
+ * B5: build the leader's post-round VERDICT body — per-criterion ✓/○ against the
154
+ * pinned outcome, the leader's reason, and the focus it hands to the next round.
155
+ */
156
+ export declare function buildLeaderVerdict(criteria: string[], met: boolean[], reason: string, nextFocus?: string): string;
157
+ export declare function formatSpeakerRoster(list: Array<{
158
+ stance?: DebateStance;
159
+ model: string;
160
+ }>): string | undefined;
161
+ export declare function countCitations(text: string): number;
162
+ /**
163
+ * Evidence density = verified / (verified + unverified).
164
+ *
165
+ * Previous definition was `citations / total-sentences`, which fundamentally
166
+ * couldn't exceed ~0.05 because most debate sentences are not citable claims
167
+ * (opinions, transitions, questions). Session ea13da132dec hit "Low
168
+ * confidence 0.00" despite having 2 real [CONFIRMED via web_fetch] tags
169
+ * because they were drowned in ~700 sentences of debate prose.
170
+ *
171
+ * New definition only counts claims that participants explicitly FLAGGED as
172
+ * needing evidence — either by verifying them ([CONFIRMED]/[REFUTED]) or by
173
+ * marking them unverified ([UNVERIFIED:…]). This measures how much of the
174
+ * debate's own factual claim-tagging was actually backed up.
175
+ *
176
+ * If participants tagged zero claims, density is 0 — no evidence awareness
177
+ * shown, low confidence is correct. This biases participants (via the
178
+ * EVIDENCE_RULE prompt) to either verify or explicitly mark unverified.
179
+ */
180
+ export declare function computeEvidenceDensity(text: string): number;