muonroi-cli 1.8.4 → 1.8.5

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 (458) 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-tee.d.ts +48 -0
  5. package/dist/packages/agent-harness-core/src/event-tee.js +77 -0
  6. package/dist/packages/agent-harness-core/src/mcp-server.d.ts +11 -0
  7. package/dist/packages/agent-harness-core/src/mcp-server.js +87 -15
  8. package/dist/packages/agent-harness-core/src/protocol.d.ts +66 -2
  9. package/dist/packages/agent-harness-core/src/protocol.js +15 -0
  10. package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
  11. package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
  12. package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
  13. package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
  14. package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
  15. package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
  16. package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
  17. package/dist/packages/agent-harness-opentui/src/install.js +10 -0
  18. package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
  19. package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
  20. package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
  21. package/dist/src/agent-harness/mock-model.d.ts +28 -0
  22. package/dist/src/agent-harness/mock-model.js +63 -1
  23. package/dist/src/agent-harness/test-spawn.js +31 -0
  24. package/dist/src/cli/config/screen-providers.js +1 -1
  25. package/dist/src/cli/cost-forensics.d.ts +10 -0
  26. package/dist/src/cli/cost-forensics.js +18 -3
  27. package/dist/src/cli/keys-bundle.d.ts +1 -1
  28. package/dist/src/cli/keys-bundle.js +1 -1
  29. package/dist/src/cli/keys.d.ts +2 -2
  30. package/dist/src/cli/keys.js +19 -81
  31. package/dist/src/council/clarifier.d.ts +28 -2
  32. package/dist/src/council/clarifier.js +81 -15
  33. package/dist/src/council/context.js +49 -15
  34. package/dist/src/council/debate-checkpoint.d.ts +129 -0
  35. package/dist/src/council/debate-checkpoint.js +176 -0
  36. package/dist/src/council/debate-planner.js +51 -3
  37. package/dist/src/council/debate-summary.d.ts +25 -0
  38. package/dist/src/council/debate-summary.js +85 -0
  39. package/dist/src/council/debate.d.ts +169 -2
  40. package/dist/src/council/debate.js +1210 -134
  41. package/dist/src/council/index.d.ts +85 -1
  42. package/dist/src/council/index.js +634 -196
  43. package/dist/src/council/leader.d.ts +26 -0
  44. package/dist/src/council/leader.js +150 -9
  45. package/dist/src/council/llm.d.ts +32 -0
  46. package/dist/src/council/llm.js +231 -38
  47. package/dist/src/council/panel-select.d.ts +30 -0
  48. package/dist/src/council/panel-select.js +72 -0
  49. package/dist/src/council/planner.js +23 -0
  50. package/dist/src/council/preflight.d.ts +7 -0
  51. package/dist/src/council/preflight.js +14 -2
  52. package/dist/src/council/prompts.d.ts +30 -3
  53. package/dist/src/council/prompts.js +234 -64
  54. package/dist/src/council/stance-recall.d.ts +42 -0
  55. package/dist/src/council/stance-recall.js +57 -0
  56. package/dist/src/council/strip-think.d.ts +17 -0
  57. package/dist/src/council/strip-think.js +33 -0
  58. package/dist/src/council/types.d.ts +128 -0
  59. package/dist/src/ee/artifact-cache.d.ts +16 -0
  60. package/dist/src/ee/artifact-cache.js +32 -0
  61. package/dist/src/ee/auth.d.ts +1 -0
  62. package/dist/src/ee/auth.js +15 -2
  63. package/dist/src/ee/bridge.d.ts +10 -0
  64. package/dist/src/ee/bridge.js +58 -0
  65. package/dist/src/ee/client.js +81 -18
  66. package/dist/src/ee/export-transcripts.d.ts +1 -0
  67. package/dist/src/ee/export-transcripts.js +8 -10
  68. package/dist/src/ee/extract-session.js +29 -0
  69. package/dist/src/ee/extract-style.d.ts +58 -0
  70. package/dist/src/ee/extract-style.js +270 -0
  71. package/dist/src/ee/recall-ledger.d.ts +9 -0
  72. package/dist/src/ee/recall-ledger.js +3 -0
  73. package/dist/src/ee/scope.d.ts +1 -0
  74. package/dist/src/ee/scope.js +26 -1
  75. package/dist/src/ee/search.d.ts +7 -0
  76. package/dist/src/ee/search.js +24 -0
  77. package/dist/src/ee/transcript-emit.js +2 -0
  78. package/dist/src/ee/types.d.ts +22 -0
  79. package/dist/src/ee/who-am-i-brain.d.ts +35 -0
  80. package/dist/src/ee/who-am-i-brain.js +220 -0
  81. package/dist/src/ee/who-am-i.d.ts +10 -3
  82. package/dist/src/ee/who-am-i.js +12 -0
  83. package/dist/src/ee/workflow-event.d.ts +48 -0
  84. package/dist/src/ee/workflow-event.js +81 -0
  85. package/dist/src/flow/compaction/compress.d.ts +3 -3
  86. package/dist/src/flow/compaction/compress.js +45 -8
  87. package/dist/src/flow/compaction/extract.d.ts +4 -7
  88. package/dist/src/flow/compaction/extract.js +50 -10
  89. package/dist/src/flow/compaction/index.d.ts +13 -1
  90. package/dist/src/flow/compaction/index.js +70 -3
  91. package/dist/src/flow/compaction/input-guard.d.ts +24 -0
  92. package/dist/src/flow/compaction/input-guard.js +43 -0
  93. package/dist/src/flow/fold-planning.d.ts +36 -0
  94. package/dist/src/flow/fold-planning.js +83 -0
  95. package/dist/src/flow/hierarchy.d.ts +146 -0
  96. package/dist/src/flow/hierarchy.js +427 -0
  97. package/dist/src/flow/index.d.ts +1 -0
  98. package/dist/src/flow/index.js +2 -0
  99. package/dist/src/flow/run-artifacts.d.ts +102 -0
  100. package/dist/src/flow/run-artifacts.js +208 -0
  101. package/dist/src/generated/version.d.ts +1 -1
  102. package/dist/src/generated/version.js +1 -1
  103. package/dist/src/gsd/assessment-schema.d.ts +44 -0
  104. package/dist/src/gsd/assessment-schema.js +134 -0
  105. package/dist/src/gsd/capability-registry.d.ts +45 -0
  106. package/dist/src/gsd/capability-registry.js +337 -0
  107. package/dist/src/gsd/complexity-assessor.d.ts +39 -0
  108. package/dist/src/gsd/complexity-assessor.js +152 -0
  109. package/dist/src/gsd/config-bridge.d.ts +7 -0
  110. package/dist/src/gsd/config-bridge.js +114 -0
  111. package/dist/src/gsd/config-loader.d.ts +27 -0
  112. package/dist/src/gsd/config-loader.js +50 -0
  113. package/dist/src/gsd/council-context.d.ts +44 -0
  114. package/dist/src/gsd/council-context.js +114 -0
  115. package/dist/src/gsd/ee-closure.d.ts +28 -0
  116. package/dist/src/gsd/ee-closure.js +49 -0
  117. package/dist/src/gsd/flags.d.ts +55 -0
  118. package/dist/src/gsd/flags.js +83 -0
  119. package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
  120. package/dist/src/gsd/gsd-dispatch.js +131 -0
  121. package/dist/src/gsd/gsd-runtime.d.ts +22 -0
  122. package/dist/src/gsd/gsd-runtime.js +37 -0
  123. package/dist/src/gsd/host-adapter.d.ts +11 -0
  124. package/dist/src/gsd/host-adapter.js +29 -0
  125. package/dist/src/gsd/index.d.ts +24 -1
  126. package/dist/src/gsd/index.js +27 -0
  127. package/dist/src/gsd/loop-host-contract.d.ts +21 -0
  128. package/dist/src/gsd/loop-host-contract.js +39 -0
  129. package/dist/src/gsd/loop-host.d.ts +69 -0
  130. package/dist/src/gsd/loop-host.js +245 -0
  131. package/dist/src/gsd/loop-resolver.d.ts +36 -0
  132. package/dist/src/gsd/loop-resolver.js +79 -0
  133. package/dist/src/gsd/model-tier.d.ts +13 -0
  134. package/dist/src/gsd/model-tier.js +45 -0
  135. package/dist/src/gsd/mutation-gate.d.ts +16 -0
  136. package/dist/src/gsd/mutation-gate.js +41 -0
  137. package/dist/src/gsd/native-roadmap.d.ts +89 -0
  138. package/dist/src/gsd/native-roadmap.js +343 -0
  139. package/dist/src/gsd/native-state.d.ts +47 -0
  140. package/dist/src/gsd/native-state.js +220 -0
  141. package/dist/src/gsd/paths.d.ts +23 -0
  142. package/dist/src/gsd/paths.js +66 -0
  143. package/dist/src/gsd/phase-dag.d.ts +12 -0
  144. package/dist/src/gsd/phase-dag.js +94 -0
  145. package/dist/src/gsd/phase-sync.d.ts +42 -0
  146. package/dist/src/gsd/phase-sync.js +321 -0
  147. package/dist/src/gsd/pil-gate-context.d.ts +13 -0
  148. package/dist/src/gsd/pil-gate-context.js +64 -0
  149. package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
  150. package/dist/src/gsd/pil-gate-critic.js +74 -0
  151. package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
  152. package/dist/src/gsd/plan-council-prompts.js +79 -0
  153. package/dist/src/gsd/plan-council.d.ts +44 -0
  154. package/dist/src/gsd/plan-council.js +251 -0
  155. package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
  156. package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
  157. package/dist/src/gsd/product-workspace.d.ts +13 -0
  158. package/dist/src/gsd/product-workspace.js +124 -0
  159. package/dist/src/gsd/ship-bridge.d.ts +25 -0
  160. package/dist/src/gsd/ship-bridge.js +65 -0
  161. package/dist/src/gsd/state-document.d.ts +40 -0
  162. package/dist/src/gsd/state-document.js +163 -0
  163. package/dist/src/gsd/verdict-schema.d.ts +39 -0
  164. package/dist/src/gsd/verdict-schema.js +144 -0
  165. package/dist/src/gsd/verify-context.d.ts +22 -0
  166. package/dist/src/gsd/verify-context.js +27 -0
  167. package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
  168. package/dist/src/gsd/verify-council-prompts.js +85 -0
  169. package/dist/src/gsd/verify-council.d.ts +25 -0
  170. package/dist/src/gsd/verify-council.js +119 -0
  171. package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
  172. package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
  173. package/dist/src/gsd/workflow-engine.d.ts +60 -0
  174. package/dist/src/gsd/workflow-engine.js +207 -0
  175. package/dist/src/gsd/workflow-tools.d.ts +13 -0
  176. package/dist/src/gsd/workflow-tools.js +277 -0
  177. package/dist/src/hooks/index.js +1 -1
  178. package/dist/src/index.js +44 -11
  179. package/dist/src/maintain/pr-builder.js +23 -13
  180. package/dist/src/mcp/auto-setup.js +57 -32
  181. package/dist/src/mcp/client-pool.js +1 -1
  182. package/dist/src/mcp/ee-tools.js +1 -0
  183. package/dist/src/mcp/research-onboarding.js +8 -7
  184. package/dist/src/mcp/runtime.js +34 -2
  185. package/dist/src/models/catalog-client.d.ts +87 -0
  186. package/dist/src/models/catalog-client.js +105 -38
  187. package/dist/src/models/catalog.json +528 -265
  188. package/dist/src/models/registry.d.ts +22 -7
  189. package/dist/src/models/registry.js +73 -10
  190. package/dist/src/ops/doctor.js +1 -1
  191. package/dist/src/orchestrator/auto-commit.js +1 -1
  192. package/dist/src/orchestrator/batch-turn-runner.js +2 -2
  193. package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
  194. package/dist/src/orchestrator/cache-prefix.js +83 -0
  195. package/dist/src/orchestrator/compact-request.d.ts +32 -0
  196. package/dist/src/orchestrator/compact-request.js +41 -0
  197. package/dist/src/orchestrator/compaction.d.ts +10 -0
  198. package/dist/src/orchestrator/compaction.js +27 -7
  199. package/dist/src/orchestrator/council-manager.d.ts +12 -3
  200. package/dist/src/orchestrator/council-manager.js +65 -24
  201. package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
  202. package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
  203. package/dist/src/orchestrator/error-utils.d.ts +29 -0
  204. package/dist/src/orchestrator/error-utils.js +132 -24
  205. package/dist/src/orchestrator/grounding-check.js +39 -1
  206. package/dist/src/orchestrator/message-processor.js +242 -33
  207. package/dist/src/orchestrator/orchestrator.d.ts +39 -3
  208. package/dist/src/orchestrator/orchestrator.js +651 -102
  209. package/dist/src/orchestrator/preprocessor.js +1 -1
  210. package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
  211. package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
  212. package/dist/src/orchestrator/prompts.js +17 -17
  213. package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
  214. package/dist/src/orchestrator/reactive-delegation.js +59 -0
  215. package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
  216. package/dist/src/orchestrator/retry-classifier.js +46 -2
  217. package/dist/src/orchestrator/safety-intercept.d.ts +45 -0
  218. package/dist/src/orchestrator/safety-intercept.js +55 -0
  219. package/dist/src/orchestrator/scope-reminder.js +1 -1
  220. package/dist/src/orchestrator/session-experience.d.ts +2 -1
  221. package/dist/src/orchestrator/session-experience.js +2 -1
  222. package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
  223. package/dist/src/orchestrator/should-run-gate.js +18 -0
  224. package/dist/src/orchestrator/stall-watchdog.d.ts +24 -3
  225. package/dist/src/orchestrator/stall-watchdog.js +47 -13
  226. package/dist/src/orchestrator/stream-runner.js +62 -29
  227. package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
  228. package/dist/src/orchestrator/sub-agent-cap.js +16 -1
  229. package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
  230. package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
  231. package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
  232. package/dist/src/orchestrator/subagent-compactor.js +126 -15
  233. package/dist/src/orchestrator/tool-engine.d.ts +22 -0
  234. package/dist/src/orchestrator/tool-engine.js +620 -56
  235. package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
  236. package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
  237. package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
  238. package/dist/src/orchestrator/turn-watchdog.d.ts +37 -0
  239. package/dist/src/orchestrator/turn-watchdog.js +55 -0
  240. package/dist/src/pil/agent-operating-contract.d.ts +1 -1
  241. package/dist/src/pil/agent-operating-contract.js +1 -1
  242. package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
  243. package/dist/src/pil/cheap-model-playbook.js +5 -1
  244. package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
  245. package/dist/src/pil/cheap-model-workbooks.js +1 -1
  246. package/dist/src/pil/discovery-types.d.ts +1 -0
  247. package/dist/src/pil/discovery.js +16 -11
  248. package/dist/src/pil/layer1-intent.d.ts +18 -6
  249. package/dist/src/pil/layer1-intent.js +66 -757
  250. package/dist/src/pil/layer15-context-scan.js +15 -1
  251. package/dist/src/pil/layer3-ee-injection.js +23 -8
  252. package/dist/src/pil/layer4-gsd.js +69 -16
  253. package/dist/src/pil/layer5-context.js +7 -3
  254. package/dist/src/pil/layer6-output.d.ts +23 -0
  255. package/dist/src/pil/layer6-output.js +5 -1
  256. package/dist/src/pil/llm-classify.d.ts +33 -2
  257. package/dist/src/pil/llm-classify.js +123 -131
  258. package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
  259. package/dist/src/pil/native-capabilities-workbook.js +1 -0
  260. package/dist/src/pil/pipeline.js +34 -2
  261. package/dist/src/pil/response-tools.js +5 -3
  262. package/dist/src/pil/schema.d.ts +1 -0
  263. package/dist/src/pil/schema.js +2 -0
  264. package/dist/src/pil/types.d.ts +18 -0
  265. package/dist/src/playbook/directives.d.ts +4 -0
  266. package/dist/src/playbook/directives.js +17 -5
  267. package/dist/src/product-loop/backlog-builder.d.ts +14 -1
  268. package/dist/src/product-loop/backlog-builder.js +30 -6
  269. package/dist/src/product-loop/discovery-context-format.js +3 -1
  270. package/dist/src/product-loop/discovery-ecosystem.js +4 -1
  271. package/dist/src/product-loop/discovery-interview.js +32 -3
  272. package/dist/src/product-loop/discovery-schema.js +5 -1
  273. package/dist/src/product-loop/ideal-trace.d.ts +7 -0
  274. package/dist/src/product-loop/ideal-trace.js +64 -0
  275. package/dist/src/product-loop/index.d.ts +13 -1
  276. package/dist/src/product-loop/index.js +333 -52
  277. package/dist/src/product-loop/loop-driver.d.ts +7 -0
  278. package/dist/src/product-loop/loop-driver.js +310 -99
  279. package/dist/src/product-loop/phase-plan.d.ts +5 -0
  280. package/dist/src/product-loop/phase-plan.js +39 -2
  281. package/dist/src/product-loop/phase-runner.js +9 -1
  282. package/dist/src/product-loop/sprint-runner.d.ts +111 -0
  283. package/dist/src/product-loop/sprint-runner.js +559 -16
  284. package/dist/src/product-loop/types.d.ts +36 -5
  285. package/dist/src/providers/adapter.d.ts +1 -1
  286. package/dist/src/providers/adapter.js +3 -4
  287. package/dist/src/providers/auth/browser-flow.d.ts +1 -1
  288. package/dist/src/providers/auth/browser-flow.js +1 -1
  289. package/dist/src/providers/auth/openai-oauth.js +1 -1
  290. package/dist/src/providers/auth/registry.js +0 -34
  291. package/dist/src/providers/auth/token-store.js +4 -1
  292. package/dist/src/providers/auth/types.d.ts +1 -1
  293. package/dist/src/providers/auth/types.js +1 -1
  294. package/dist/src/providers/capabilities.d.ts +24 -5
  295. package/dist/src/providers/capabilities.js +42 -24
  296. package/dist/src/providers/endpoints.d.ts +2 -2
  297. package/dist/src/providers/endpoints.js +11 -10
  298. package/dist/src/providers/keychain.d.ts +1 -1
  299. package/dist/src/providers/keychain.js +7 -9
  300. package/dist/src/providers/mcp-vision-bridge.js +56 -146
  301. package/dist/src/providers/openai-compatible.js +8 -1
  302. package/dist/src/providers/pricing.d.ts +2 -2
  303. package/dist/src/providers/pricing.js +3 -13
  304. package/dist/src/providers/runtime.d.ts +27 -2
  305. package/dist/src/providers/runtime.js +78 -15
  306. package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
  307. package/dist/src/providers/strategies/base.strategy.js +24 -1
  308. package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
  309. package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
  310. package/dist/src/providers/strategies/registry.js +4 -4
  311. package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
  312. package/dist/src/providers/strategies/thinking-mode.js +280 -1
  313. package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
  314. package/dist/src/providers/strategies/zai.strategy.js +44 -0
  315. package/dist/src/providers/types.d.ts +5 -6
  316. package/dist/src/providers/types.js +2 -2
  317. package/dist/src/providers/vision-backend.d.ts +47 -0
  318. package/dist/src/providers/vision-backend.js +258 -0
  319. package/dist/src/providers/vision-proxy.d.ts +22 -9
  320. package/dist/src/providers/vision-proxy.js +63 -132
  321. package/dist/src/providers/wire-debug.js +95 -0
  322. package/dist/src/router/decide.d.ts +13 -0
  323. package/dist/src/router/decide.js +138 -36
  324. package/dist/src/router/peak-hour.d.ts +38 -0
  325. package/dist/src/router/peak-hour.js +107 -0
  326. package/dist/src/router/step-router.js +3 -2
  327. package/dist/src/router/warm.js +4 -5
  328. package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
  329. package/dist/src/scaffold/continuation-prompt.js +26 -0
  330. package/dist/src/scaffold/point-to-existing.d.ts +21 -0
  331. package/dist/src/scaffold/point-to-existing.js +25 -0
  332. package/dist/src/self-qa/agentic-loop.js +3 -3
  333. package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
  334. package/dist/src/{ui/state → state}/active-run.js +21 -0
  335. package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
  336. package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
  337. package/dist/src/state/turn-trace.d.ts +43 -0
  338. package/dist/src/state/turn-trace.js +32 -0
  339. package/dist/src/storage/db.js +2 -1
  340. package/dist/src/storage/index.d.ts +1 -1
  341. package/dist/src/storage/index.js +1 -1
  342. package/dist/src/storage/interaction-log.d.ts +1 -1
  343. package/dist/src/storage/migrations.js +71 -1
  344. package/dist/src/storage/sessions.d.ts +28 -10
  345. package/dist/src/storage/sessions.js +78 -21
  346. package/dist/src/storage/transcript-view.js +1 -1
  347. package/dist/src/storage/transcript.d.ts +51 -0
  348. package/dist/src/storage/transcript.js +284 -13
  349. package/dist/src/tools/file.d.ts +15 -0
  350. package/dist/src/tools/file.js +32 -0
  351. package/dist/src/tools/native-tools.js +5 -0
  352. package/dist/src/tools/registry.d.ts +3 -0
  353. package/dist/src/tools/registry.js +460 -22
  354. package/dist/src/tools/research.d.ts +29 -0
  355. package/dist/src/tools/research.js +233 -0
  356. package/dist/src/types/index.d.ts +118 -3
  357. package/dist/src/ui/app.js +0 -0
  358. package/dist/src/ui/cards/product-status-card.js +1 -1
  359. package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
  360. package/dist/src/ui/components/bubble-body-guard.js +50 -0
  361. package/dist/src/ui/components/context-rail.d.ts +26 -0
  362. package/dist/src/ui/components/context-rail.js +33 -0
  363. package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
  364. package/dist/src/ui/components/council-conclusion-card.js +420 -0
  365. package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
  366. package/dist/src/ui/components/council-debate-pill.js +34 -0
  367. package/dist/src/ui/components/council-info-card.js +2 -2
  368. package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
  369. package/dist/src/ui/components/council-leader-bubble.js +21 -11
  370. package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
  371. package/dist/src/ui/components/council-message-bubble.js +16 -15
  372. package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
  373. package/dist/src/ui/components/council-phase-timeline.js +49 -15
  374. package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
  375. package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
  376. package/dist/src/ui/components/council-question-card.js +12 -12
  377. package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
  378. package/dist/src/ui/components/council-rail-rounds.js +57 -0
  379. package/dist/src/ui/components/council-round-group.d.ts +38 -0
  380. package/dist/src/ui/components/council-round-group.js +88 -0
  381. package/dist/src/ui/components/council-status-list.d.ts +3 -1
  382. package/dist/src/ui/components/council-status-list.js +36 -24
  383. package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
  384. package/dist/src/ui/components/council-synthesis-banner.js +20 -5
  385. package/dist/src/ui/components/halt-recovery-card.js +9 -5
  386. package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
  387. package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
  388. package/dist/src/ui/components/prompt-box.js +18 -16
  389. package/dist/src/ui/components/session-tree-card.d.ts +14 -0
  390. package/dist/src/ui/components/session-tree-card.js +46 -0
  391. package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
  392. package/dist/src/ui/components/slash-inline-menu.js +26 -5
  393. package/dist/src/ui/components/task-list-panel.d.ts +14 -1
  394. package/dist/src/ui/components/task-list-panel.js +22 -2
  395. package/dist/src/ui/containers/modals-layer.d.ts +2 -1
  396. package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
  397. package/dist/src/ui/mcp-modal.js +2 -4
  398. package/dist/src/ui/modals/api-key-modal.js +1 -1
  399. package/dist/src/ui/modals/connect-modal.js +4 -3
  400. package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
  401. package/dist/src/ui/modals/session-picker-modal.js +3 -5
  402. package/dist/src/ui/picker-providers.d.ts +1 -1
  403. package/dist/src/ui/picker-providers.js +1 -1
  404. package/dist/src/ui/primitives/index.d.ts +1 -0
  405. package/dist/src/ui/primitives/index.js +2 -0
  406. package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
  407. package/dist/src/ui/primitives/semantic-primitives.js +81 -0
  408. package/dist/src/ui/slash/compact.js +5 -7
  409. package/dist/src/ui/slash/cost.js +1 -1
  410. package/dist/src/ui/slash/council.js +19 -1
  411. package/dist/src/ui/slash/debug.d.ts +3 -31
  412. package/dist/src/ui/slash/debug.js +9 -20
  413. package/dist/src/ui/slash/ideal.d.ts +6 -2
  414. package/dist/src/ui/slash/ideal.js +97 -7
  415. package/dist/src/ui/slash/menu-items.d.ts +7 -0
  416. package/dist/src/ui/slash/menu-items.js +12 -18
  417. package/dist/src/ui/slash/registry.d.ts +2 -0
  418. package/dist/src/ui/slash/registry.js +4 -0
  419. package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
  420. package/dist/src/ui/status-bar/cache-hit.js +9 -0
  421. package/dist/src/ui/status-bar/index.d.ts +1 -1
  422. package/dist/src/ui/status-bar/index.js +7 -3
  423. package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
  424. package/dist/src/ui/status-bar/usd-meter.js +6 -4
  425. package/dist/src/ui/theme.d.ts +1 -0
  426. package/dist/src/ui/theme.js +2 -0
  427. package/dist/src/ui/types.d.ts +7 -0
  428. package/dist/src/ui/use-app-logic.js +0 -0
  429. package/dist/src/ui/utils/format.d.ts +14 -0
  430. package/dist/src/ui/utils/format.js +23 -3
  431. package/dist/src/usage/downgrade.js +2 -2
  432. package/dist/src/usage/product-ledger.js +2 -2
  433. package/dist/src/utils/install-manager.js +2 -1
  434. package/dist/src/utils/logger.js +2 -2
  435. package/dist/src/utils/permission-mode.js +5 -3
  436. package/dist/src/utils/redactor.js +1 -1
  437. package/dist/src/utils/settings.d.ts +153 -5
  438. package/dist/src/utils/settings.js +233 -29
  439. package/dist/src/utils/visible-retry.d.ts +11 -0
  440. package/dist/src/utils/visible-retry.js +10 -1
  441. package/dist/src/verify/entrypoint.d.ts +1 -1
  442. package/dist/src/verify/entrypoint.js +1 -1
  443. package/dist/src/verify/recipes.d.ts +13 -0
  444. package/dist/src/verify/recipes.js +15 -0
  445. package/package.json +135 -132
  446. package/dist/src/providers/auth/gcloud.d.ts +0 -28
  447. package/dist/src/providers/auth/gcloud.js +0 -102
  448. package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
  449. package/dist/src/providers/auth/gemini-oauth.js +0 -472
  450. package/dist/src/providers/gemini.d.ts +0 -11
  451. package/dist/src/providers/gemini.js +0 -45
  452. package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
  453. package/dist/src/providers/siliconflow-sse-repair.js +0 -177
  454. package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
  455. package/dist/src/providers/strategies/google.strategy.js +0 -174
  456. package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
  457. package/dist/src/ui/containers/chat-feed.d.ts +0 -40
  458. package/dist/src/ui/containers/chat-feed.js +0 -66
package/dist/src/index.js CHANGED
@@ -163,7 +163,7 @@ async function hasOAuthForModel(modelId) {
163
163
  * Supported splash providers — mirrors SPLASH_PROVIDERS in ui/app.tsx.
164
164
  * The wizard only surfaces these; other providers still work programmatically.
165
165
  */
166
- const WIZARD_PROVIDERS = ["deepseek", "siliconflow"];
166
+ const WIZARD_PROVIDERS = ["deepseek", "zai", "opencode-go", "xai"];
167
167
  async function firstRunWizard(currentModel) {
168
168
  let rl;
169
169
  try {
@@ -335,7 +335,7 @@ async function firstRunWizard(currentModel) {
335
335
  return null;
336
336
  }
337
337
  }
338
- async function startInteractive(apiKey, baseURL, model, maxToolRounds, batchApi, session, initialMessage, permissionMode = "safe", injectHalt = false) {
338
+ async function startInteractive(apiKey, baseURL, model, maxToolRounds, batchApi, session, initialMessage, permissionMode = "safe", injectHalt = false, injectHaltSprint = false) {
339
339
  // ── Plan 00-07 boot order ──────────────────────────────────────────────────
340
340
  // 1. redactor.installGlobalPatches() — already at top of file (line 6).
341
341
  // 2. loadConfig + loadUsage (validates storage paths, logs usage cap state).
@@ -416,6 +416,14 @@ async function startInteractive(apiKey, baseURL, model, maxToolRounds, batchApi,
416
416
  const { relaunchWithSession } = await import("./ui/utils/relaunch.js");
417
417
  const renderer = await createCliRenderer({
418
418
  exitOnCtrlC: false,
419
+ // OpenTUI defaults openConsoleOnError:true — its process-level
420
+ // unhandledRejection/uncaughtException handler then calls console.show(),
421
+ // which focuses the debug console overlay and captures ALL keypresses.
422
+ // The overlay's keybindings have no hide/close action, so a stray rejection
423
+ // (e.g. a provider dropping a streaming socket) traps the user in a console
424
+ // they cannot dismiss. We surface errors in-band instead — keep it off.
425
+ // Toggle it deliberately with F12 (wired below).
426
+ openConsoleOnError: false,
419
427
  // We manage SIGINT ourselves (orchestrator abort → agent cleanup → renderer destroy).
420
428
  // Prevent OpenTUI from registering its own SIGINT/SIGTERM handler which would
421
429
  // call renderer.destroy() prematurely and race with our orderly shutdown.
@@ -426,10 +434,29 @@ async function startInteractive(apiKey, baseURL, model, maxToolRounds, batchApi,
426
434
  alternateKeys: true,
427
435
  },
428
436
  });
437
+ // Agent-mode: hand the renderer to the harness so it can snapshot the ACTUAL
438
+ // rendered cell grid (colors + attributes) via VisualFrame, not just the
439
+ // semantic tree. No-op outside agent-mode (runtime undefined).
440
+ {
441
+ const agentRt = globalThis.__muonroiAgentRuntime;
442
+ agentRt?.attachRenderer?.(renderer);
443
+ }
429
444
  // The TUI now owns the terminal — route fatal-handler behaviour away from
430
445
  // process.exit(1) (see the unhandledRejection handler above). Cleared in
431
446
  // restoreTerminalSync() the moment we begin tearing the terminal back down.
432
447
  setTuiActive(true);
448
+ // Deliberate debug-console toggle. With openConsoleOnError:false the overlay
449
+ // never auto-pops, so F12 is the ONLY way in — and, crucially, back out:
450
+ // console.toggle() hides it when it is visible+focused, so it can never trap.
451
+ try {
452
+ renderer.keyInput?.on("keypress", (key) => {
453
+ if (key?.name === "f12")
454
+ renderer.console.toggle();
455
+ });
456
+ }
457
+ catch {
458
+ /* keyInput/console are best-effort dev affordances — never block boot */
459
+ }
433
460
  /**
434
461
  * Restore terminal to main-screen mode before the process exits.
435
462
  *
@@ -616,6 +643,7 @@ async function startInteractive(apiKey, baseURL, model, maxToolRounds, batchApi,
616
643
  maxToolRounds,
617
644
  version: packageJson.version,
618
645
  injectHalt,
646
+ injectHaltSprint,
619
647
  },
620
648
  initialMessage,
621
649
  onExit,
@@ -852,6 +880,7 @@ program
852
880
  .option("--agent-fake-clock", "Use deterministic frame-counter clock")
853
881
  .option("--mock-llm <dir>", "Use fixture-based mock LLM from <dir> instead of real provider (E2E testing)")
854
882
  .option("--inject-halt", "TEST SEAM: render a synthetic halt recovery card after boot (harness E2E only)")
883
+ .option("--inject-halt-sprint", "TEST SEAM: render a synthetic sprint-failed recovery card after boot (harness E2E only)")
855
884
  .action(async (message, options) => {
856
885
  // Agent-mode: start the sidechannel runtime BEFORE any TUI or model work.
857
886
  // The runtime is exposed on globalThis so the renderer wiring (Task 1.6c)
@@ -978,11 +1007,10 @@ program
978
1007
  }
979
1008
  changeDirectoryOrExit(options.directory);
980
1009
  // Boot model registry BEFORE any key resolution path runs —
981
- // detectProviderForModel consults the catalog's alias map to route e.g.
982
- // "deepseek-v4-flash" to provider "siliconflow". With an empty registry
983
- // it falls back to a prefix match ("deepseek") and the CLI loads the
984
- // wrong provider's key. Affects both runBackgroundDelegation and the
985
- // main interactive/headless path below.
1010
+ // detectProviderForModel consults the catalog's alias map to route model
1011
+ // ids to the correct provider. With an empty registry it falls back to a
1012
+ // prefix match and the CLI may load the wrong provider's key. Affects both
1013
+ // runBackgroundDelegation and the main interactive/headless path below.
986
1014
  let catalogLoadFailed = false;
987
1015
  await loadCatalog().catch(() => {
988
1016
  catalogLoadFailed = true;
@@ -1049,10 +1077,15 @@ program
1049
1077
  // so each request doesn't re-probe.
1050
1078
  const { detectEEClientMode, describeMode } = await import("./ee/client-mode.js");
1051
1079
  detectEEClientMode()
1052
- .then((info) => {
1080
+ .then(async (info) => {
1053
1081
  if (process.env.MUONROI_EE_DEBUG === "1") {
1054
1082
  console.error(`[muonroi-cli] ${describeMode(info)}`);
1055
1083
  }
1084
+ // WhoAmI thin-client fallback: once the mode is cached, derive the working-style
1085
+ // profile from the behavioral brain and prime the sync cache so the PIL picks it
1086
+ // up from the next turn. Fire-and-forget, fail-open — never blocks boot.
1087
+ const { warmWhoAmIFromBrain } = await import("./ee/bridge.js");
1088
+ await warmWhoAmIFromBrain();
1056
1089
  })
1057
1090
  .catch(() => { });
1058
1091
  // Patch zod-to-json-schema for Zod v4 compat (fixes tool calls for DeepSeek etc.)
@@ -1130,7 +1163,7 @@ program
1130
1163
  return;
1131
1164
  }
1132
1165
  const initialMessage = message.length > 0 ? message.join(" ") : undefined;
1133
- await startInteractive(config.apiKey, config.baseURL, config.model, config.maxToolRounds, options.batchApi === true, options.session, initialMessage, options.permission, options.injectHalt === true);
1166
+ await startInteractive(config.apiKey, config.baseURL, config.model, config.maxToolRounds, options.batchApi === true, options.session, initialMessage, options.permission, options.injectHalt === true, options.injectHaltSprint === true);
1134
1167
  });
1135
1168
  program
1136
1169
  .command("models")
@@ -1254,7 +1287,7 @@ keys
1254
1287
  });
1255
1288
  keys
1256
1289
  .command("login <provider>")
1257
- .description("Log in to a provider via OAuth subscription (supported: openai, google/agy, xai). 'google'/'agy' now uses agy client creds.")
1290
+ .description("Log in to a provider via OAuth subscription (supported: openai, xai).")
1258
1291
  .action(async (provider) => {
1259
1292
  const { runKeysLogin } = await import("./cli/keys.js");
1260
1293
  await runKeysLogin(provider);
@@ -1391,7 +1424,7 @@ usage
1391
1424
  const mcp = program.command("mcp").description("Manage MCP server configuration");
1392
1425
  mcp
1393
1426
  .command("setup-research")
1394
- .description("Configure web research MCP servers (context7, fetch, tavily)")
1427
+ .description("Configure web research (native fetch_url + web_search; optional MCPs for context7/muonroi-docs)")
1395
1428
  .action(async () => {
1396
1429
  const rl = createInterface({ input: process.stdin, output: process.stderr });
1397
1430
  const ask = (q) => new Promise((resolve) => rl.question(q, (a) => resolve(a)));
@@ -186,9 +186,13 @@ async function squashSinceMarker(cwd, markerSha, title) {
186
186
  }
187
187
  }
188
188
  // ─── PR body prompt ───────────────────────────────────────────────────────────
189
- const PR_BODY_SYSTEM = "You are a developer writing a GitHub pull request body. " +
190
- "Output ONLY the markdown body no preamble, no code fences wrapping the whole output. " +
191
- "Follow the template exactly. Be concise.";
189
+ const PR_BODY_SYSTEM = "You are a senior engineer writing the description for your own pull request. " +
190
+ "Write for a busy reviewer: they should understand what this PR does, why it exists, and how to verify it " +
191
+ "within thirty seconds of reading — before they open a single file. " +
192
+ "Write in plain, confident prose. Prefer specific claims ('caps retry backoff at 30s') over vague ones " +
193
+ "('improves retry handling'). Never restate filenames or diffs mechanically — explain intent and effect. " +
194
+ "Do not pad, do not apologize, and do not invent changes that are not evidenced by the task data or diff. " +
195
+ "Output ONLY the finished markdown body — no preamble, no commentary, and no code fence wrapping the whole output.";
192
196
  function buildPrBodyPrompt(task, diff, intel, result, filesOutsideRadius) {
193
197
  const diffSnippet = diff.length > 8192 ? `${diff.slice(0, 8192)}\n...[diff truncated to 8KB]` : diff;
194
198
  const descriptionSummary = task.description.length > 600 ? `${task.description.slice(0, 597)}…` : task.description;
@@ -199,29 +203,35 @@ function buildPrBodyPrompt(task, diff, intel, result, filesOutsideRadius) {
199
203
  ? `\n## Review Concerns\n${result.reviewConcerns.map((c) => `- ${c}`).join("\n")}`
200
204
  : "";
201
205
  return [
202
- "Generate a PR body for the following maintenance task.",
203
- "Use the template below. Replace each placeholder with real content.",
206
+ "Write the pull request body for the maintenance task below.",
207
+ "Use exactly the section structure described here, in this order. Render real content for every section — no placeholders, no angle brackets in the output.",
204
208
  "Output ONLY the rendered markdown body — nothing else.",
205
209
  "",
206
- "## Template",
210
+ "## Structure",
207
211
  "---",
208
212
  "## Summary",
209
- "<copy task description verbatimtrim to 3-5 sentences>",
213
+ "Two to four sentences a reviewer can read in isolation: what problem this PR solves, why it matters now, and the shape of the fix. Ground it in the task description, but rewrite it as prose do not paste the task text verbatim.",
210
214
  "",
211
215
  "## What changed",
212
- "<bullet list inferred from diff hunks focus on user-visible behavior, not file mechanics>",
216
+ "Three to six bullets describing observable behavior changes, ordered most-significant first. Each bullet states an effect ('X now does Y', 'Z no longer happens when W'), not a file operation. Infer these from the diff hunks; mention a file path only when it clarifies scope. If the diff is trivially small, two bullets are fine — do not pad.",
213
217
  "",
214
218
  "## Test plan",
215
- "<bullet list from acceptance_criteria + regression tests run>",
219
+ "One bullet per acceptance criterion, phrased as a verifiable check the reviewer could repeat. Then list the regression tests that were run. If something was NOT verified, say so plainly rather than omitting it.",
216
220
  outsideSection ? "## Files outside declared impact radius" : "",
217
- outsideSection ? "<list filesOutsideRadius>" : "",
221
+ outsideSection
222
+ ? "List each file from the task data below, and for each add a short honest note on why it was touched (or 'reason unclear from diff' if you cannot tell). These files deserve extra reviewer scrutiny — do not downplay them."
223
+ : "",
218
224
  concernsSection ? "## Review Concerns" : "",
219
- concernsSection ? "<list reviewConcerns — these are non-blocking, for reviewer awareness>" : "",
225
+ concernsSection
226
+ ? "List each concern from the task data verbatim, one bullet each. These are non-blocking flags for reviewer awareness — preserve their meaning, do not soften or editorialize."
227
+ : "",
220
228
  "## Related",
221
- "- Impact radius: <first 5 entries from impactRadius>",
222
- "- Regression tests run: <first 5 entries from regressionTests>",
229
+ "- Impact radius: the first 5 entries from the impact radius in the task data",
230
+ "- Regression tests run: the first 5 entries from the regression tests in the task data",
223
231
  "---",
224
232
  "",
233
+ "Rules: British understatement over marketing tone. No emoji. No headers beyond those specified. Keep the whole body under ~350 words unless the concerns/outside-radius sections force it longer.",
234
+ "",
225
235
  "## Task data",
226
236
  `Kind: ${task.kind}`,
227
237
  `Title: ${task.title}`,
@@ -27,6 +27,27 @@ function removeDeprecatedToolsMcp(servers) {
27
27
  console.error("[mcp:auto-setup] removed deprecated self-spawned muonroi-tools server — its tools are now native in-process builtins");
28
28
  return true;
29
29
  }
30
+ /**
31
+ * Remove deprecated external MCP servers that are no longer seeded by default.
32
+ *
33
+ * - memory: superseded by native Experience Engine (ee_query + ee_write)
34
+ * - playwright: heavy browser automation; native research tools (fetch_url/web_search) cover most needs. Can be added manually.
35
+ * - figma: requires API key + specific workflow; removed from defaults. Can be added manually if needed.
36
+ */
37
+ function removeDeprecatedExternalMcps(servers) {
38
+ const idsToRemove = new Set(["memory", "playwright", "figma"]);
39
+ let removed = false;
40
+ for (let i = servers.length - 1; i >= 0; i--) {
41
+ if (idsToRemove.has(servers[i].id)) {
42
+ servers.splice(i, 1);
43
+ removed = true;
44
+ }
45
+ }
46
+ if (removed) {
47
+ console.error("[mcp:auto-setup] removed deprecated external MCPs (memory/playwright/figma). Use native EE for memory; fetch_url + web_search for research. Add playwright/figma manually only if full integration required.");
48
+ }
49
+ return removed;
50
+ }
30
51
  const DEFAULT_CONFIGS = [
31
52
  {
32
53
  // Authoritative source for the Muonroi ecosystem (BB/.NET template recipes,
@@ -39,31 +60,6 @@ const DEFAULT_CONFIGS = [
39
60
  transport: "http",
40
61
  url: "https://docs-mcp.muonroi.com/mcp",
41
62
  },
42
- {
43
- id: "playwright",
44
- label: "Playwright",
45
- enabled: true,
46
- transport: "stdio",
47
- command: "npx",
48
- args: ["-y", "@playwright/mcp"],
49
- },
50
- {
51
- id: "memory",
52
- label: "Memory",
53
- enabled: false,
54
- transport: "stdio",
55
- command: "npx",
56
- args: ["-y", "@modelcontextprotocol/server-memory"],
57
- },
58
- {
59
- id: "figma",
60
- label: "Figma",
61
- enabled: false,
62
- transport: "stdio",
63
- command: "npx",
64
- args: ["-y", "figma-developer-mcp", "--stdio"],
65
- env: { FIGMA_API_KEY: "" },
66
- },
67
63
  {
68
64
  id: "context7",
69
65
  label: "Context7 (Library Docs)",
@@ -71,21 +67,24 @@ const DEFAULT_CONFIGS = [
71
67
  transport: "http",
72
68
  url: "https://mcp.context7.com/mcp",
73
69
  },
70
+ // fetch and tavily are now provided as *native* builtins (fetch_url / web_search).
71
+ // The external MCP versions are kept in the catalog for users who explicitly want them,
72
+ // but are no longer enabled by default for the inner agent.
74
73
  {
75
74
  id: "fetch",
76
- label: "Fetch (URL → markdown)",
77
- enabled: true,
75
+ label: "Fetch (URL → markdown) [MCP legacy]",
76
+ enabled: false,
78
77
  transport: "stdio",
79
- command: "npx",
80
- args: ["-y", "mcp-fetch-server"],
78
+ command: "bun",
79
+ args: ["x", "-y", "mcp-fetch-server"],
81
80
  },
82
81
  {
83
82
  id: "tavily",
84
- label: "Tavily Web Search",
83
+ label: "Tavily Web Search [MCP legacy]",
85
84
  enabled: false,
86
85
  transport: "stdio",
87
- command: "npx",
88
- args: ["-y", "tavily-mcp"],
86
+ command: "bun",
87
+ args: ["x", "-y", "tavily-mcp"],
89
88
  env: { TAVILY_API_KEY: "" },
90
89
  },
91
90
  ];
@@ -108,10 +107,36 @@ function migrateServers(servers) {
108
107
  }
109
108
  return changed;
110
109
  }
110
+ /**
111
+ * Migrate any legacy "npx" stdio entries (from older default seeds or manual config)
112
+ * to "bun x" form. npx shims frequently produce immediate "Connection closed"
113
+ * under Bun on Windows; bun x gives clean stdio pipes. Idempotent.
114
+ */
115
+ function migrateNpxToBunx(servers) {
116
+ let changed = false;
117
+ for (const server of servers) {
118
+ if (server.transport === "stdio" && server.command === "npx") {
119
+ server.command = "bun";
120
+ const rest = (server.args ?? []).filter((a) => a !== "-y");
121
+ server.args = ["x", "-y", ...rest];
122
+ changed = true;
123
+ }
124
+ }
125
+ if (changed) {
126
+ console.error("[mcp:auto-setup] migrated legacy npx-based MCP servers to bun x (fixes Connection closed on Bun/Windows)");
127
+ }
128
+ return changed;
129
+ }
111
130
  export function ensureDefaultMcpServers() {
112
131
  try {
113
132
  const existing = loadMcpServers();
114
133
  let dirty = migrateServers(existing);
134
+ // Upgrade legacy npx runners (most important fix for "Connection closed" during warm-up).
135
+ if (migrateNpxToBunx(existing))
136
+ dirty = true;
137
+ // Remove deprecated external MCPs (memory/playwright/figma) — replaced by native or manual opt-in.
138
+ if (removeDeprecatedExternalMcps(existing))
139
+ dirty = true;
115
140
  // muonroi-tools is no longer self-spawned by the CLI — its capabilities
116
141
  // (ee_query/ee_feedback/ee_health/usage_forensics/lsp_query/setup_guide/
117
142
  // selfverify_*) are NATIVE in-process builtins now (src/tools/native-tools.ts).
@@ -237,7 +237,7 @@ export async function acquireMcpTools(servers, opts) {
237
237
  * evicted by getOrConnect so a real turn retries.
238
238
  */
239
239
  export async function warmMcpClients(servers, syncAndLog = false) {
240
- const validServers = servers.filter(s => s.enabled && validateMcpServerConfig(s).ok);
240
+ const validServers = servers.filter((s) => s.enabled && validateMcpServerConfig(s).ok);
241
241
  if (syncAndLog && validServers.length > 0) {
242
242
  console.log(`[MCP] Warming up ${validServers.length} server(s)...`);
243
243
  }
@@ -140,6 +140,7 @@ export function registerEETools(server, deps = {}) {
140
140
  id: clearedId,
141
141
  verdict: result.verdict,
142
142
  ...(result.reason ? { reason: result.reason } : {}),
143
+ ...(result.queued ? { queued: true } : {}),
143
144
  pendingRemaining: ledger.pendingCount(),
144
145
  });
145
146
  }
@@ -53,10 +53,10 @@ async function promptForKeyWithRetry(io) {
53
53
  return null;
54
54
  }
55
55
  export async function runResearchOnboarding(io) {
56
- io.log("\nWeb research is available via MCP servers:\n");
57
- io.log(" - context7 - version-pinned library docs (free, no key)\n");
58
- io.log(" - fetch - URL to markdown extraction (free, no key)\n");
59
- io.log(" - tavily - LLM-tuned web search (free tier 1k/mo, needs API key)\n");
56
+ io.log("\nWeb research tools (native builtins):\n");
57
+ io.log(" - fetch_url fetch any public URL and return clean markdown/text (always available)\n");
58
+ io.log(" - web_search — Tavily-powered web search (free tier, needs API key)\n");
59
+ io.log(" - context7 / muonroi-docs still available via MCP (library + ecosystem docs)\n");
60
60
  io.log("\nTip: if you keep keys in Bitwarden, run `muonroi-cli mcp import-bw tavily` instead.\n\n");
61
61
  const yn = (await io.askYesNo("Enable Tavily web search now? [Y/n]: ")).trim().toLowerCase();
62
62
  let tavilyEnabled = false;
@@ -85,9 +85,10 @@ export async function runResearchMigrationPrompt(io) {
85
85
  if (settings.webResearchPrompted === true) {
86
86
  return { shown: false, tavilyEnabled: false };
87
87
  }
88
- io.log("\nNew: web research is available.\n");
89
- io.log(" - context7 (library docs) and fetch (URL extraction) - already enabled.\n");
90
- io.log(" - Tavily web search needs a free API key (tavily.com).\n\n");
88
+ io.log("\nNew: web research tools are available natively.\n");
89
+ io.log(" - fetch_url (URL markdown) is always available.\n");
90
+ io.log(" - web_search (Tavily) needs a free API key (tavily.com).\n");
91
+ io.log(" - context7 + muonroi-docs remain as optional MCP for specialized docs.\n\n");
91
92
  const choice = (await io.askChoice("Set up Tavily now? [Y/n/never]: ")).trim().toLowerCase();
92
93
  let tavilyEnabled = false;
93
94
  if (choice === "y" || choice === "yes" || choice === "") {
@@ -65,11 +65,34 @@ function stripMcpInputSchema(tool) {
65
65
  inputSchema: jsonSchema(LAZY_MCP_INPUT_SCHEMA),
66
66
  };
67
67
  }
68
+ function getMcpStdioRunner() {
69
+ // Prefer Bun's runner because:
70
+ // - The CLI is launched via `bun run`
71
+ // - npx .cmd shims have been observed to cause immediate "Connection closed"
72
+ // (MCPClientError) for StdioClientTransport on Windows + Bun (see probe results).
73
+ // - bun x resolves + spawns package bins with clean stdio pipes.
74
+ return { command: "bun", prefixArgs: ["x", "-y"] };
75
+ }
76
+ /**
77
+ * Upgrade legacy "npx" (or npm exec) invocations recorded in user settings
78
+ * to the bun-based runner. This heals persisted configs from before the fix
79
+ * without requiring the user to re-run setup.
80
+ */
81
+ function normalizeStdioCommand(command, args) {
82
+ const a = args ?? [];
83
+ if (command === "npx" || (command === "npm" && a[0] === "exec")) {
84
+ const r = getMcpStdioRunner();
85
+ const pkgArgs = a.filter((x) => x !== "-y");
86
+ return { command: r.command, args: [...r.prefixArgs, ...pkgArgs] };
87
+ }
88
+ return { command, args: a };
89
+ }
68
90
  function toTransport(server, authProvider) {
69
91
  if (server.transport === "stdio") {
92
+ const { command, args } = normalizeStdioCommand(server.command ?? "", server.args);
70
93
  return new StdioClientTransport({
71
- command: server.command ?? "",
72
- args: server.args,
94
+ command,
95
+ args,
73
96
  env: server.env ? { ...getDefaultEnvironment(), ...server.env } : undefined,
74
97
  cwd: server.cwd,
75
98
  stderr: "pipe",
@@ -111,6 +134,15 @@ export async function connectOneServer(rawServer, opts) {
111
134
  // Hydrate env vars from the OS keychain before spawning — e.g. inject
112
135
  // TAVILY_API_KEY for the tavily MCP if stored via the research-onboarding wizard.
113
136
  const server = await hydrateServerEnv(rawServer);
137
+ // Fast-fail for servers that require keys but have none. Prevents "Connection closed"
138
+ // with zero actionable info. The server binary may start and list tools, but first
139
+ // use would fail — better to give clear guidance at warmup time.
140
+ if (server.id === "tavily") {
141
+ const key = server.env?.TAVILY_API_KEY;
142
+ if (!key || key.length < 16) {
143
+ throw new Error("Tavily is enabled but TAVILY_API_KEY is missing. Run `muonroi-cli mcp setup-research` or `muonroi-cli mcp key tavily`, or disable the server in /mcp config.");
144
+ }
145
+ }
114
146
  let authProvider;
115
147
  let cleanup;
116
148
  if (server.transport !== "stdio" && opts?.onOAuthRequired) {
@@ -7,6 +7,68 @@ export declare function getCatalogUrl(): string;
7
7
  * and a 401 from a key-protected catalog simply triggers the static fallback.
8
8
  */
9
9
  export declare function getCatalogHeaders(): Record<string, string>;
10
+ /** One peak window within a provider's local timezone (end_hour exclusive). */
11
+ export interface CatalogPeakHourWindow {
12
+ start_hour: number;
13
+ end_hour: number;
14
+ }
15
+ /** Peak-hour rule for a provider — sourced from vendor docs via catalog API. */
16
+ export interface CatalogProviderPeakHour {
17
+ source_url: string;
18
+ source_verified_at?: string;
19
+ timezone: string;
20
+ /** Single window — used when `windows` is absent (e.g. Z.ai 14–18). */
21
+ start_hour?: number;
22
+ end_hour?: number;
23
+ /** Multiple peak windows (e.g. DeepSeek official: 09–12 and 14–18 UTC+8). */
24
+ windows?: CatalogPeakHourWindow[];
25
+ sensitive_model_ids: string[];
26
+ fallback_model_id: string;
27
+ switch_fallback_providers?: string[];
28
+ peak_quota_multiplier?: number;
29
+ off_peak_quota_multiplier?: number;
30
+ policy_basis?: "official" | "heuristic";
31
+ policy_note?: string;
32
+ }
33
+ export interface CatalogProviderPolicy {
34
+ peak_hour?: CatalogProviderPeakHour;
35
+ }
36
+ /** Default council debate slot — one role mapped to a provider + model. */
37
+ export interface CatalogCouncilParticipant {
38
+ role: "implement" | "verify" | "research";
39
+ provider: string;
40
+ tier?: "fast" | "balanced" | "premium";
41
+ model_id?: string;
42
+ }
43
+ export interface CatalogCouncilRouting {
44
+ /** Default true — spread implement/verify/research across providers when user has no roleModels. */
45
+ prefer_multi_provider?: boolean;
46
+ participants?: CatalogCouncilParticipant[];
47
+ }
48
+ /** One vision-backend slot for the text-only model proxy layer. */
49
+ export interface CatalogVisionProxySlot {
50
+ provider: string;
51
+ model_id: string;
52
+ }
53
+ export interface CatalogVisionProxyRouting {
54
+ default?: CatalogVisionProxySlot;
55
+ ocr?: CatalogVisionProxySlot;
56
+ design?: CatalogVisionProxySlot;
57
+ fallback_chain?: CatalogVisionProxySlot[];
58
+ }
59
+ export interface CatalogRouting {
60
+ switch_provider_order?: string[];
61
+ council?: CatalogCouncilRouting;
62
+ vision_proxy?: CatalogVisionProxyRouting;
63
+ }
64
+ export interface CatalogDocument {
65
+ version: string;
66
+ updated_at: string;
67
+ description?: string;
68
+ models: CatalogModel[];
69
+ routing?: CatalogRouting;
70
+ provider_policies?: Record<string, CatalogProviderPolicy>;
71
+ }
10
72
  export interface CatalogModel {
11
73
  id: string;
12
74
  name: string;
@@ -21,16 +83,39 @@ export interface CatalogModel {
21
83
  reasoning: boolean;
22
84
  thinking_type?: string | null;
23
85
  supports_effort?: boolean;
86
+ /** Provider pins temperature to this exact value (e.g. Moonshot/Kimi = 1). */
87
+ fixed_temperature?: number | null;
24
88
  description: string;
25
89
  aliases?: string[];
26
90
  default_reasoning_effort?: string | null;
27
91
  supports_vision?: boolean;
92
+ /** When false, model is selectable via -m but skipped by tier routing. */
93
+ tier_routing?: boolean;
94
+ /** Additional tiers for automatic routing (primary tier remains `tier`). */
95
+ routing_tiers?: string[];
96
+ roles?: string[];
97
+ /**
98
+ * Part E — model has NATIVE online web research (its own web_search / browsing
99
+ * / Live Search), not just codebase read. Source of truth for whether the
100
+ * council research phase can trust this model for online facts. Per-model
101
+ * (audited), NOT per-provider. Absent → treated as false (safe: forces the
102
+ * add-in fallback + a degraded-confidence log). Never inferred from provider.
103
+ */
104
+ native_web_research?: boolean;
105
+ /**
106
+ * Optional mechanism hint for HOW native web research is activated:
107
+ * "live-search" (xAI) | "web-tool" | "browsing" (OpenAI Responses web_search)
108
+ * | null. Advisory only — `native_web_research` is the gate.
109
+ */
110
+ web_research_kind?: string | null;
28
111
  }
29
112
  /**
30
113
  * Best-effort validation for the REMOTE catalog: a transient bad response must
31
114
  * never break the CLI, so an invalid payload returns null and the caller falls
32
115
  * through to the trusted bundled catalog.
33
116
  */
117
+ export declare function safeValidateCatalogDocument(raw: unknown): CatalogDocument | null;
118
+ /** @deprecated Use safeValidateCatalogDocument — kept for callers that only need models. */
34
119
  export declare function safeValidateCatalog(raw: unknown): CatalogModel[] | null;
35
120
  /**
36
121
  * Strict validation for a STATIC (bundled) catalog that is present on disk: a
@@ -38,6 +123,8 @@ export declare function safeValidateCatalog(raw: unknown): CatalogModel[] | null
38
123
  * throw loudly with the validation issues rather than silently skipping it
39
124
  * (which would mask the defect as a confusing "cannot find catalog" later).
40
125
  */
126
+ export declare function validateStaticCatalogDocument(raw: unknown, source: string): CatalogDocument;
41
127
  export declare function validateStaticCatalog(raw: unknown, source: string): CatalogModel[];
128
+ export declare function fetchCatalogDocument(): Promise<CatalogDocument>;
42
129
  export declare function fetchCatalog(): Promise<CatalogModel[]>;
43
130
  export declare function catalogModelToModelInfo(m: CatalogModel): ModelInfo;