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
@@ -31,26 +31,21 @@ export const SLASH_MENU_ITEMS = [
31
31
  { id: "providers", label: "providers", description: "Manage providers + API keys (enable/disable, set default)" },
32
32
  { id: "compact", label: "compact", description: "Compact conversation context" },
33
33
  { id: "clear", label: "clear", description: "Clear conversation and start fresh" },
34
- { id: "ideal", label: "ideal", description: "Product Ideal Loop — autonomous build from idea to ship" },
34
+ { id: "ideal", label: "ideal", description: "Product Ideal Loop — from idea to shipped product, autonomously" },
35
35
  { id: "council", label: "council", description: "Multi-model adversarial debate" },
36
36
  // ── Hidden (still functional when typed in full) ───────────────────────
37
37
  { id: "help", label: "help", description: "Show available commands", hidden: true },
38
- { id: "config", label: "config", description: "Open provider and council configuration", hidden: true },
39
38
  { id: "remote-control", label: "remote-control", description: "Remote control", hidden: true },
40
- { id: "agents", label: "agents", description: "Manage custom sub-agents", hidden: true },
41
- { id: "schedule", label: "schedule", description: "View scheduled runs", hidden: true },
42
39
  { id: "mcp", label: "mcp", description: "Manage MCP servers", hidden: true },
43
40
  { id: "sandbox", label: "sandbox", description: "Select shell sandbox mode", hidden: true },
44
41
  { id: "wallet", label: "wallet", description: "Wallet and payment settings", hidden: true },
45
42
  { id: "models", label: "models", description: "Alias of /providers", hidden: true },
46
43
  { id: "new", label: "new session", description: "Start a new session", hidden: true },
47
- { id: "sessions", label: "sessions", description: "List recent sessions to resume", hidden: true },
44
+ { id: "resume", label: "resume", description: "List recent sessions to resume" },
48
45
  { id: "commit-push", label: "commit & push", description: "Commit and push", hidden: true },
49
46
  { id: "commit-pr", label: "commit & pr", description: "Commit and open PR", hidden: true },
50
47
  { id: "review", label: "review", description: "Review recent changes", hidden: true },
51
48
  { id: "verify", label: "verify", description: "Run local verification", hidden: true },
52
- { id: "skills", label: "skills", description: "Manage skills", hidden: true },
53
- { id: "btw", label: "btw", description: "Ask a side question without interrupting", hidden: true },
54
49
  { id: "update", label: "update", description: "Update muonroi-cli to the latest version", hidden: true },
55
50
  { id: "cost", label: "cost", description: "Show session cost breakdown", hidden: true },
56
51
  { id: "ee", label: "ee", description: "Experience Engine status and controls", hidden: true },
@@ -74,21 +69,20 @@ export const SLASH_MENU_ITEMS = [
74
69
  { id: "pin", label: "pin", description: "Pin a user message so it survives compaction", hidden: true },
75
70
  { id: "unpin", label: "unpin", description: "Remove a pinned message by sequence number", hidden: true },
76
71
  { id: "pins", label: "pins", description: "List currently pinned message sequences", hidden: true },
77
- { id: "ee-stats", label: "ee stats", description: "Knowledge base statistics", hidden: true },
78
- { id: "ee-gates", label: "ee gates", description: "Quality gate checklist", hidden: true },
79
- { id: "ee-evolve", label: "ee evolve", description: "Trigger EE evolution cycle", hidden: true },
80
- { id: "ee-user", label: "ee user", description: "Current EE user identity", hidden: true },
81
- { id: "ee-search", label: "ee search", description: "Semantic search across knowledge base", hidden: true },
82
- { id: "ee-timeline", label: "ee timeline", description: "Principle evolution for a topic", hidden: true },
83
- { id: "ee-graph", label: "ee graph", description: "Principle relationship graph", hidden: true },
84
- { id: "ee-route", label: "ee route", description: "Route task to workflow", hidden: true },
85
- { id: "ee-context-on", label: "ee-context on", description: "Enable BB-aware EE context injection", hidden: true },
86
- { id: "ee-context-off", label: "ee-context off", description: "Disable BB-aware EE context injection", hidden: true },
87
- { id: "ee-context-status", label: "ee-context status", description: "Show current BB-context setting", hidden: true },
88
72
  { id: "export", label: "export", description: "Export entire conversation to a .txt file", hidden: true },
89
73
  { id: "status", label: "status", description: "Show Agile sprint progress dashboard", hidden: true },
90
74
  { id: "ponytail", label: "ponytail", description: "Toggle Lazy Senior AI Mode (on/off/status)", hidden: false },
91
75
  ];
92
76
  /** Items shown in the splash autocomplete + /help listing. */
93
77
  export const VISIBLE_SLASH_MENU_ITEMS = SLASH_MENU_ITEMS.filter((m) => !m.hidden);
78
+ /**
79
+ * Arrow-navigation order for the empty-query ("just /") dropdown: primary
80
+ * surface first, then the hidden commands. The dropdown renders a scrolling
81
+ * viewport, so listing the full set here makes every command reachable by
82
+ * arrow keys without cluttering the top of the list (primary stays on top).
83
+ */
84
+ export const SLASH_MENU_ITEMS_ARROW_ORDER = [
85
+ ...VISIBLE_SLASH_MENU_ITEMS,
86
+ ...SLASH_MENU_ITEMS.filter((m) => m.hidden),
87
+ ];
94
88
  //# sourceMappingURL=menu-items.js.map
@@ -23,6 +23,8 @@ export interface SlashContext {
23
23
  export type SlashHandler = (args: string[], ctx: SlashContext) => Promise<string> | string;
24
24
  /** Register a slash command handler. */
25
25
  export declare function registerSlash(name: string, handler: SlashHandler): void;
26
+ /** Unregister a slash command handler (used for tests). */
27
+ export declare function unregisterSlash(name: string): void;
26
28
  /**
27
29
  * Dispatch a slash command by name.
28
30
  * Returns null if command not registered (caller falls back to legacy switch).
@@ -9,6 +9,10 @@ const registry = new Map();
9
9
  export function registerSlash(name, handler) {
10
10
  registry.set(name, handler);
11
11
  }
12
+ /** Unregister a slash command handler (used for tests). */
13
+ export function unregisterSlash(name) {
14
+ registry.delete(name);
15
+ }
12
16
  /**
13
17
  * Dispatch a slash command by name.
14
18
  * Returns null if command not registered (caller falls back to legacy switch).
@@ -0,0 +1,6 @@
1
+ /** Cache-hit ratio = cache_read / total input (cumulative). `in_tokens` already
2
+ * includes cache-read tokens (verified: usage_events cache_read ⊆ input_tokens). */
3
+ export declare function computeCacheHitPct(s: {
4
+ in_tokens: number;
5
+ cache_read_tokens: number;
6
+ }): number | null;
@@ -0,0 +1,9 @@
1
+ /** Cache-hit ratio = cache_read / total input (cumulative). `in_tokens` already
2
+ * includes cache-read tokens (verified: usage_events cache_read ⊆ input_tokens). */
3
+ export function computeCacheHitPct(s) {
4
+ if (s.in_tokens <= 0)
5
+ return null;
6
+ const pct = (s.cache_read_tokens / s.in_tokens) * 100;
7
+ return Math.max(0, Math.min(100, Math.round(pct)));
8
+ }
9
+ //# sourceMappingURL=cache-hit.js.map
@@ -7,7 +7,7 @@
7
7
  * Subscribes to statusBarStore for live updates (no polling).
8
8
  */
9
9
  import * as React from "react";
10
- import { type SprintProgressSegment, type StatusBarState } from "./store.js";
10
+ import { type SprintProgressSegment, type StatusBarState } from "../../state/status-bar-store.js";
11
11
  /**
12
12
  * Format a SprintProgressSegment into the StatusBar display string.
13
13
  * Format: Sprint N/M · X/Y stories · Z%
@@ -9,7 +9,8 @@ import { jsx as _jsx } from "@opentui/react/jsx-runtime";
9
9
  */
10
10
  import { Semantic } from "@muonroi/agent-harness-opentui";
11
11
  import * as React from "react";
12
- import { statusBarStore } from "./store.js";
12
+ import { statusBarStore } from "../../state/status-bar-store.js";
13
+ import { computeCacheHitPct } from "./cache-hit.js";
13
14
  import { TierBadge } from "./tier-badge.js";
14
15
  import { UsdMeter } from "./usd-meter.js";
15
16
  function useStatusBarState() {
@@ -57,7 +58,11 @@ export function renderStatusBar(s) {
57
58
  : s.ctx_tokens !== undefined
58
59
  ? ` [ctx: ${fmtTokens(s.ctx_tokens)}]`
59
60
  : "";
60
- const tokenStr = `↑${fmtTokens(s.in_tokens)} ↓${fmtTokens(s.out_tokens)}${s.cache_read_tokens ? ` ⊚${fmtTokens(s.cache_read_tokens)}` : ""}${ctxFill}`;
61
+ const hitPct = computeCacheHitPct(s);
62
+ const cacheSeg = s.cache_read_tokens
63
+ ? ` ⊚${fmtTokens(s.cache_read_tokens)}${hitPct !== null ? ` ${hitPct}%` : ""}`
64
+ : "";
65
+ const tokenStr = `↑${fmtTokens(s.in_tokens)} ↓${fmtTokens(s.out_tokens)}${cacheSeg}${ctxFill}`;
61
66
  const ee = EE_DOT[s.ee_status] ?? EE_DOT.unknown;
62
67
  const slots = [
63
68
  React.createElement("text", { key: "pm", fg: "#5c9cf5", "data-testid": "slot-provider-model" }, modelLabel),
@@ -66,7 +71,6 @@ export function renderStatusBar(s) {
66
71
  React.createElement(UsdMeter, {
67
72
  key: "usd",
68
73
  session_usd: s.session_usd,
69
- month_usd: s.month_usd,
70
74
  current_pct: s.current_pct,
71
75
  }),
72
76
  React.createElement("text", { key: "ee", fg: ee.color, "data-testid": "slot-ee" }, ee.symbol),
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * src/ui/status-bar/usd-meter.tsx
3
3
  *
4
- * USD meter sub-component: session + month with threshold color escalation.
5
- * white < 50%, cyan >= 50%, yellow >= 80%, red >= 100%.
4
+ * USD meter sub-component: session spend with threshold color escalation.
5
+ * white < 50%, cyan >= 50%, yellow >= 80%, red >= 100%. The month total is
6
+ * intentionally NOT shown here (redundant on the status bar); it remains in the
7
+ * store and is surfaced on demand via `/cost`.
6
8
  */
7
9
  import * as React from "react";
8
10
  export interface UsdMeterProps {
9
11
  session_usd: number;
10
- month_usd: number;
11
12
  current_pct: number;
12
13
  }
13
- export declare function UsdMeter({ session_usd, month_usd, current_pct }: UsdMeterProps): React.ReactElement;
14
+ export declare function UsdMeter({ session_usd, current_pct }: UsdMeterProps): React.ReactElement;
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * src/ui/status-bar/usd-meter.tsx
3
3
  *
4
- * USD meter sub-component: session + month with threshold color escalation.
5
- * white < 50%, cyan >= 50%, yellow >= 80%, red >= 100%.
4
+ * USD meter sub-component: session spend with threshold color escalation.
5
+ * white < 50%, cyan >= 50%, yellow >= 80%, red >= 100%. The month total is
6
+ * intentionally NOT shown here (redundant on the status bar); it remains in the
7
+ * store and is surfaced on demand via `/cost`.
6
8
  */
7
9
  import * as React from "react";
8
- export function UsdMeter({ session_usd, month_usd, current_pct }) {
10
+ export function UsdMeter({ session_usd, current_pct }) {
9
11
  const color = current_pct >= 100 ? "red" : current_pct >= 80 ? "yellow" : current_pct >= 50 ? "cyan" : "white";
10
- const text = `session: $${session_usd.toFixed(2)} | month: $${month_usd.toFixed(2)}`;
12
+ const text = `session: $${session_usd.toFixed(2)}`;
11
13
  return React.createElement("text", { fg: color, "data-testid": "usd-meter", "data-pct": current_pct }, text);
12
14
  }
13
15
  //# sourceMappingURL=usd-meter.js.map
@@ -65,6 +65,7 @@ export declare const dark: {
65
65
  readonly syntaxRegex: "#d16969";
66
66
  readonly syntaxTag: "#569cd6";
67
67
  readonly syntaxAttr: "#9cdcfe";
68
+ readonly overlay: "#000000cc";
68
69
  readonly councilLeaderBorder: "#666666";
69
70
  readonly councilSynthesisBorder: "#5c9cf5";
70
71
  readonly councilInfoCardBorder: "#4a4a4a";
@@ -65,6 +65,8 @@ export const dark = {
65
65
  syntaxRegex: "#d16969",
66
66
  syntaxTag: "#569cd6",
67
67
  syntaxAttr: "#9cdcfe",
68
+ // ── Overlay / modal backdrop ─────────────────────────────────────────────
69
+ overlay: "#000000cc",
68
70
  // ── Council bubble tokens ────────────────────────────────────────────────
69
71
  councilLeaderBorder: "#666666",
70
72
  councilSynthesisBorder: "#5c9cf5",
@@ -63,6 +63,13 @@ export interface AppStartupConfig {
63
63
  * Never set this in production — only passed via --inject-halt CLI flag.
64
64
  */
65
65
  injectHalt?: boolean;
66
+ /**
67
+ * TEST SEAM (A): when true, dispatch a synthetic `sprint_failed` halt chunk
68
+ * (Resume / Retry / Skip verify / Abort) after first idle. Lets harness E2E
69
+ * specs verify the sprint-break recovery card without a real mid-run failure.
70
+ * Never set this in production — only passed via --inject-halt-sprint.
71
+ */
72
+ injectHaltSprint?: boolean;
66
73
  }
67
74
  export interface AppProps {
68
75
  agent: Agent;
Binary file
@@ -35,4 +35,18 @@ export declare function buildPreflightQuestion(pf: {
35
35
  model: string;
36
36
  }>;
37
37
  }): CouncilQuestionData;
38
+ /**
39
+ * F5 — the council entrypoint (council/index.ts) emits `leader`+`panel`+`topic`
40
+ * together exactly once, at the START of each debate; every later `council_meta`
41
+ * patch is partial (a lone roundBudget / researchMode / successCriteria /
42
+ * criteriaMet). That combination is the strongest new-council signal — stronger
43
+ * than a topic change, which misses a re-run on the SAME topic (auto-council
44
+ * re-firing on a phase, or a fresh /council after an Esc that skipped
45
+ * clearLiveTurnUi) and leaks the prior council's pinned criteria into the rail as
46
+ * stale ○ rows. The rail resets its meta+rounds on this.
47
+ */
48
+ export declare function isCouncilStartPatch(patch: {
49
+ leader?: string;
50
+ panel?: string[];
51
+ }): boolean;
38
52
  export declare function mapCouncilCardKey(key: KeyEvent): CouncilCardKey | null;
@@ -41,6 +41,13 @@ export function formatAnswerForLog(ans, ctx) {
41
41
  return verb;
42
42
  // Single line — labels carry value + rationale tail; keep echo to the value.
43
43
  const valueOnly = label.split("—")[0].trim().replace(/\s+/g, " ");
44
+ // Internal snake_case action ids (continue_session, save_exit, generate_plan,
45
+ // ask_followup…) are routing tokens the user should NEVER see. When the value
46
+ // is such an id, echo the human label alone instead of "continue_session · …".
47
+ // Short human verbs (accept, skip, override) have no underscore and keep the
48
+ // value-prefixed forensics form below.
49
+ if (/_/.test(verb))
50
+ return valueOnly || verb;
44
51
  if (ctx?.questionId) {
45
52
  return `${verb} · ${ctx.questionId}=${valueOnly}`;
46
53
  }
@@ -89,15 +96,28 @@ export function buildPreflightQuestion(pf) {
89
96
  questionId: pf.preflightId,
90
97
  phase: "preflight",
91
98
  question: `Approve discussion plan for: ${pf.problemStatement}`,
92
- context: pf.participants.length > 0 ? `Participants: ${pf.participants.map((p) => p.role).join(", ")}` : undefined,
99
+ context: pf.participants.length > 0 ? `Panel: ${pf.participants.map((p) => p.model).join(", ")}` : undefined,
93
100
  options: [
94
- { label: "Approve", value: "approve", kind: "choice", description: "Start the debate now" },
95
- { label: "Reject", value: "reject", kind: "choice", description: "Cancel and rewrite the topic" },
101
+ { label: "Approve", value: "approve", kind: "choice", description: "Looks good — start the debate" },
102
+ { label: "Reject", value: "reject", kind: "choice", description: "Hold off — go back and rephrase the topic" },
96
103
  ],
97
104
  isRequired: true,
98
105
  defaultIndex: 0,
99
106
  };
100
107
  }
108
+ /**
109
+ * F5 — the council entrypoint (council/index.ts) emits `leader`+`panel`+`topic`
110
+ * together exactly once, at the START of each debate; every later `council_meta`
111
+ * patch is partial (a lone roundBudget / researchMode / successCriteria /
112
+ * criteriaMet). That combination is the strongest new-council signal — stronger
113
+ * than a topic change, which misses a re-run on the SAME topic (auto-council
114
+ * re-firing on a phase, or a fresh /council after an Esc that skipped
115
+ * clearLiveTurnUi) and leaks the prior council's pinned criteria into the rail as
116
+ * stale ○ rows. The rail resets its meta+rounds on this.
117
+ */
118
+ export function isCouncilStartPatch(patch) {
119
+ return !!patch.leader && !!patch.panel;
120
+ }
101
121
  export function mapCouncilCardKey(key) {
102
122
  if (key.name === "up")
103
123
  return { kind: "up" };
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * Plan 06 (status bar) subscribes to DowngradeEvent for UI updates.
9
9
  */
10
- import { getModelByTier } from "../models/registry.js";
10
+ import { getRoutedModelByTier } from "../router/peak-hour.js";
11
11
  import { getDefaultProvider } from "../utils/settings.js";
12
12
  function buildDowngradeChain() {
13
13
  const provider = getDefaultProvider() ?? undefined;
@@ -15,7 +15,7 @@ function buildDowngradeChain() {
15
15
  const seen = new Set();
16
16
  const chain = [];
17
17
  for (const tier of tiers) {
18
- const m = getModelByTier(tier, provider);
18
+ const m = getRoutedModelByTier(tier, provider);
19
19
  if (m && !seen.has(m.id)) {
20
20
  chain.push(m.id);
21
21
  seen.add(m.id);
@@ -24,12 +24,12 @@ async function ensureDirectory(filePath) {
24
24
  export async function appendProductLedger(productRunId, entry, homeOverride) {
25
25
  const filePath = getProductLedgerPath(productRunId, homeOverride);
26
26
  await ensureDirectory(filePath);
27
- // Ensure file exists for lockfile to target
27
+ // Ensure file exists for lockfile to target without truncating it concurrently
28
28
  try {
29
29
  await fs.access(filePath);
30
30
  }
31
31
  catch {
32
- await fs.writeFile(filePath, "");
32
+ await fs.appendFile(filePath, "");
33
33
  }
34
34
  const releaseLock = await lockfile.lock(filePath, {
35
35
  retries: { retries: 10, minTimeout: 10, maxTimeout: 100 },
@@ -194,7 +194,8 @@ export function detectInstallMethod(homeDir = os.homedir()) {
194
194
  }
195
195
  // Not under node_modules and not launched by node/bun → standalone binary.
196
196
  const exeBase = ((process.execPath || "").replace(/\\/g, "/").split("/").pop() ?? "").toLowerCase();
197
- if (!modPath.includes("/node_modules/") && !/^(node|bun)(\.exe)?$/.test(exeBase)) {
197
+ const isNodeOrBunRunner = /^(node|bun)(\.exe|-[\d.]+)?$/i.test(exeBase);
198
+ if (!modPath.includes("/node_modules/") && !isNodeOrBunRunner) {
198
199
  return "compiled";
199
200
  }
200
201
  // Linked/source build run from a git checkout (e.g. `bun link`, a symlinked
@@ -1,6 +1,6 @@
1
- import * as fs from "fs";
2
- import * as path from "path";
1
+ import fs from "fs";
3
2
  import * as os from "os";
3
+ import * as path from "path";
4
4
  const LEVEL_WEIGHTS = {
5
5
  debug: 0,
6
6
  info: 1,
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * safe - Every tool call prompts the user for approval.
5
5
  * auto-edit - File operation tools (read/write/edit/grep/list) auto-approve;
6
- * shell execution and computer tools still require confirmation.
6
+ * shell execution auto-approves for non-dangerous commands;
7
+ * computer tools still require confirmation.
7
8
  * yolo - All tool calls auto-approve without any prompting.
8
9
  */
9
10
  import { appendDecisionLog } from "../usage/decision-log.js";
@@ -217,8 +218,9 @@ export function toolNeedsApproval(toolName, mode, context) {
217
218
  return false;
218
219
  }
219
220
  if (mode === "auto-edit") {
220
- if (toolName === "bash" && dangerous(context?.command))
221
- return true;
221
+ // bash auto-approves when non-dangerous; only dangerous bash needs approval
222
+ if (toolName === "bash")
223
+ return dangerous(context?.command);
222
224
  return !AUTO_EDIT_ALLOWED.has(toolName);
223
225
  }
224
226
  // "safe" — always confirm; dangerous patterns explicitly require (no bypass)
@@ -34,7 +34,7 @@ const STATIC_PATTERNS = [
34
34
  },
35
35
  // Environment variable assignments for common API keys
36
36
  {
37
- pattern: /(ANTHROPIC_API_KEY|OPENAI_API_KEY|GOOGLE_API_KEY|DEEPSEEK_API_KEY)\s*=\s*\S+/g,
37
+ pattern: /(ANTHROPIC_API_KEY|OPENAI_API_KEY|DEEPSEEK_API_KEY)\s*=\s*\S+/g,
38
38
  replacement: "$1=***REDACTED***",
39
39
  },
40
40
  // Authorization Bearer header
@@ -4,6 +4,17 @@ import type { ProviderId } from "../providers/types.js";
4
4
  import type { AgentMode, ReasoningEffort } from "../types/index.js";
5
5
  import { type ShellSettings } from "./shell.js";
6
6
  export type ModelRole = "leader" | "implement" | "verify" | "research";
7
+ export type PeakHourMode = "downgrade" | "switch";
8
+ export interface PeakHourPolicy {
9
+ /** Default true — peak-hour routing active. */
10
+ enabled?: boolean;
11
+ /**
12
+ * downgrade: same-provider only (per catalog provider_policies.peak_hour).
13
+ * switch: try catalog switch_fallback_providers first.
14
+ * Default: switch.
15
+ */
16
+ mode?: PeakHourMode;
17
+ }
7
18
  export declare function getCatalogDefaultModel(): string;
8
19
  export type TelegramStreamingMode = "off" | "partial";
9
20
  export type CouncilExperienceMode = "off" | "advisory" | "enforcing";
@@ -101,6 +112,9 @@ export interface UserSettings {
101
112
  autoCompactAfterTurn?: boolean;
102
113
  /** Minimum % of context window to trigger post-turn auto-compact (default 0.25 = 25%, range 0.05-0.50). */
103
114
  autoCompactThresholdPct?: number;
115
+ /** Minimum new tokens accumulated since the last compaction before another
116
+ * post-turn compaction may fire. Prevents cache-reset thrash. Default 20000. */
117
+ autoCompactMinNewTokens?: number;
104
118
  roleModels?: Partial<Record<ModelRole, string>>;
105
119
  councilRounds?: number;
106
120
  autoCouncil?: boolean;
@@ -118,6 +132,26 @@ export interface UserSettings {
118
132
  * preserving legacy behavior).
119
133
  */
120
134
  autoCouncilMinRoles?: number;
135
+ /**
136
+ * Whether an auto-triggered council/debate runs the pre-debate clarification
137
+ * interview (model-designed askcards) before debating, instead of jumping
138
+ * straight into the debate on the bare prompt. Default true — a broad request
139
+ * like "dùng debate mode thảo luận lên plan" is exactly the kind of ambiguous
140
+ * scope the interview is meant to chốt first (prevents the debate drifting /
141
+ * "lan man"). The clarifier is ROI-gated and returns 0 cards on already-detailed
142
+ * topics, so enabling it is safe. Set false (or env MUONROI_AUTOCOUNCIL_CLARIFY=0)
143
+ * to restore the old skip-clarification behaviour.
144
+ */
145
+ autoCouncilClarify?: boolean;
146
+ /**
147
+ * When true (default), auto-council is skipped if the current session model is
148
+ * a reasoning model (catalog `reasoning: true`). Reasoning models already
149
+ * perform an internal self-debate via extended thinking, so running an
150
+ * explicit multi-role council on the same prompt is usually low-ROI and
151
+ * expensive. Set false (or env MUONROI_AUTOCOUNCIL_SKIP_REASONING=0) to force
152
+ * council even for reasoning models.
153
+ */
154
+ autoCouncilSkipReasoning?: boolean;
121
155
  councilPreferMultiProvider?: boolean;
122
156
  /** EE involvement level in council debates. Default: advisory. CQ-19. */
123
157
  councilExperienceMode?: CouncilExperienceMode;
@@ -132,6 +166,20 @@ export interface UserSettings {
132
166
  * decide structure and quality, not throughput.
133
167
  */
134
168
  councilCostAware?: boolean;
169
+ /**
170
+ * Language the council debate is conducted in (Feature B). The chosen language
171
+ * IS the debate language — no separate translate-back pass, so no extra LLM
172
+ * rounds. Values:
173
+ * - "auto" (default) — debate + conclusion follow the language of the user's
174
+ * prompt/brief (they type Vietnamese → the debate runs in Vietnamese).
175
+ * - "english" — force the historical English-only debate (citation tags,
176
+ * JSON, cross-turn citations stay maximally machine-stable).
177
+ * - any other free-text locale label (e.g. "vietnamese", "日本語") — pin the
178
+ * debate to that language regardless of the prompt's language.
179
+ * Citation tags, JSON keys, the `type` field, code identifiers, and STACK LOCK
180
+ * technology names always stay verbatim English regardless of this setting.
181
+ */
182
+ councilLanguage?: string;
135
183
  /** Set true after the user has been prompted (or skipped) the web-research onboarding. */
136
184
  webResearchPrompted?: boolean;
137
185
  /** Set true after the user has been prompted (or skipped) the first-run Experience Engine setup. */
@@ -151,13 +199,13 @@ export interface UserSettings {
151
199
  providers?: {
152
200
  anthropic?: ProviderKeyConfig;
153
201
  openai?: ProviderKeyConfig;
154
- google?: ProviderKeyConfig;
155
202
  deepseek?: ProviderKeyConfig;
156
- siliconflow?: ProviderKeyConfig;
157
203
  xai?: ProviderKeyConfig;
158
204
  ollama?: {
159
205
  baseURL?: string;
160
206
  };
207
+ zai?: ProviderKeyConfig;
208
+ "opencode-go"?: ProviderKeyConfig;
161
209
  };
162
210
  /** Providers the user has explicitly disabled in the model picker (still configured but hidden). */
163
211
  disabledProviders?: ProviderId[];
@@ -187,6 +235,11 @@ export interface UserSettings {
187
235
  /** Switch back to premium for final synthesis. Default: false. */
188
236
  premiumSynthesis?: boolean;
189
237
  };
238
+ /**
239
+ * Peak-hour routing for Z.ai (14:00–18:00 UTC+8 per docs) and DeepSeek
240
+ * (pro→flash downgrade in the same window to ease concurrency pressure).
241
+ */
242
+ peakHourPolicy?: PeakHourPolicy;
190
243
  /**
191
244
  * Reporter auto-fire settings (B2).
192
245
  * Controls whether the reporter posts to Discord automatically on sprint
@@ -216,6 +269,27 @@ export interface UserSettings {
216
269
  * Default 400_000 (~100k tokens).
217
270
  */
218
271
  topLevelToolBudgetChars?: number;
272
+ /**
273
+ * Router tier-promotion cap. The session's default model is treated as the
274
+ * user's cost ceiling: the EE router may DOWNGRADE per turn (cheaper model)
275
+ * but may not promote to a HIGHER tier than this setting allows without an
276
+ * explicit opt-in.
277
+ *
278
+ * - `"off"`: never promote beyond the default model's own tier.
279
+ * - `"balanced"` (default): allow promotion up to balanced, never premium.
280
+ * Routine tasks the EE brain over-classifies as premium get clamped to
281
+ * balanced (or to the default model when the provider has no balanced
282
+ * option — e.g. DeepSeek native only has fast + premium).
283
+ * - `"any"`: restore legacy behavior (router may promote to any tier).
284
+ *
285
+ * Evidence: session 89b34ce9a4e8 — default deepseek-v4-flash (fast tier),
286
+ * stored session.model=flash, but EE warm path returned premium for a
287
+ * routine "check và commit files" task → 47/47 turns silently ran on
288
+ * deepseek-v4-pro ($0.353) instead of flash (~$0.06). The per-turn routing
289
+ * override never flowed through setModel so the sessions row stayed flash
290
+ * ("session.model lie"). Default cap="balanced" prevents that silent leak.
291
+ */
292
+ routingPromoteMax?: "off" | "balanced" | "any";
219
293
  }
220
294
  export interface ProjectSettings {
221
295
  model?: string;
@@ -279,6 +353,7 @@ export declare function loadPaymentSettings(): Required<PaymentSettings>;
279
353
  export declare function savePaymentSettings(partial: PaymentSettings): void;
280
354
  export declare function isAutoCompactAfterTurnEnabled(): boolean;
281
355
  export declare function getAutoCompactThresholdPct(): number;
356
+ export declare function getAutoCompactMinNewTokens(): number;
282
357
  /**
283
358
  * Per-invocation cap on cumulative tool-output chars inside a `task`
284
359
  * sub-agent. See orchestrator/sub-agent-cap.ts for the tiered compression
@@ -294,6 +369,21 @@ export declare function getSubAgentBudgetChars(): number;
294
369
  * Default 120_000 (2 min). Env override: MUONROI_PROVIDER_STALL_TIMEOUT_MS.
295
370
  */
296
371
  export declare function getProviderStallTimeoutMs(): number;
372
+ /**
373
+ * No-forward-progress watchdog timeout (ms) for streaming model calls. Distinct
374
+ * from the stall watchdog: the stall watchdog re-arms on ANY stream chunk —
375
+ * including a reasoning model's `reasoning-delta` chunks — so a model stuck in an
376
+ * endless chain-of-thought keeps petting it and it NEVER fires (observed live
377
+ * 2026-07-10: a deepseek-v4-flash sub-agent churned reasoning for 30+ min, 1.4M
378
+ * input tokens, ZERO text/tool output, and the 2-min stall watchdog never tripped
379
+ * because reasoning chunks kept arriving). This second watchdog is petted ONLY on
380
+ * REAL forward progress (a text-delta or a tool-call), so a runaway-reasoning /
381
+ * no-output loop is aborted while a legitimately long reasoning burst that DOES
382
+ * eventually emit text/tools survives. Set generously above a normal reasoning
383
+ * burst. Range 30_000–1_800_000; 0 disables. Default 300_000 (5 min). Env
384
+ * override: MUONROI_PROVIDER_PROGRESS_TIMEOUT_MS.
385
+ */
386
+ export declare function getProviderProgressTimeoutMs(): number;
297
387
  /**
298
388
  * Number of times to AUTOMATICALLY re-issue a streaming model call after the
299
389
  * stall watchdog fires WITHOUT any chunk having arrived (a time-to-first-byte
@@ -337,21 +427,48 @@ export declare function getSubAgentCompactKeepLast(): number;
337
427
  * top-level loops typically carry more useful early context.
338
428
  * Env override: MUONROI_TOP_LEVEL_COMPACT_THRESHOLD_CHARS.
339
429
  */
340
- export declare function getTopLevelCompactThresholdChars(): number;
430
+ export declare function getTopLevelCompactThresholdChars(contextWindowTokens?: number): number;
431
+ /**
432
+ * Compaction hysteresis factor for the top-level loop. Once B4 compaction has
433
+ * fired within a turn, the compacted prefix is FROZEN and only new messages are
434
+ * appended (keeping the provider prompt-cache prefix byte-stable) until the
435
+ * cumulative size grows past `lastTriggerChars * factor` — then it re-compacts.
436
+ *
437
+ * Why: measured on session 1afb2728e67a — a 24-step turn re-ran compaction every
438
+ * step, and each step's sliding keepLast boundary flipped one more tool result
439
+ * verbatim→stub, breaking the cache prefix at that position. 63% of that
440
+ * session's FRESH input came from 5 such compaction-induced cache breaks.
441
+ * Holding the boundary between compactions trades a higher peak input for far
442
+ * fewer cache-break re-bills.
443
+ *
444
+ * Range 1.0–3.0. Default 1.15 (re-compact at +15% growth). `1.0` or env `0`
445
+ * disables hysteresis → legacy per-step compaction.
446
+ * Env override: MUONROI_COMPACT_HYSTERESIS.
447
+ */
448
+ export declare function getTopLevelCompactHysteresis(): number;
341
449
  /**
342
450
  * Phase B4 — number of trailing tool turns kept verbatim during top-level
343
451
  * compaction. Higher than sub-agent default because top-level agents make
344
452
  * decisions across longer horizons.
345
453
  * Env override: MUONROI_TOP_LEVEL_COMPACT_KEEP_LAST.
346
454
  */
347
- export declare function getTopLevelCompactKeepLast(): number;
455
+ export declare function getTopLevelCompactKeepLast(contextWindowTokens?: number): number;
456
+ /**
457
+ * O2 — byte budget for the verbatim tail (last keepLast turns) in top-level B4
458
+ * compaction. The keepLast shrink is otherwise fill-ratio based, so on a
459
+ * large-context model a read-heavy tail stays verbatim at ~50% fill, pinning
460
+ * each tool round at 60-80K input (measured on July-8 sessions). This caps the
461
+ * tail's actual chars, shrinking keepLast further (floor 2) when the kept tool
462
+ * results are large. 0 disables. Env: MUONROI_TOP_LEVEL_COMPACT_TAIL_BUDGET_CHARS.
463
+ */
464
+ export declare function getTopLevelCompactTailBudgetChars(contextWindowTokens?: number): number;
348
465
  /**
349
466
  * Per-turn cap on cumulative tool-output chars inside the top-level
350
467
  * orchestrator agentic loop. Same tiered compression as the sub-agent cap,
351
468
  * higher default so single-tool turns are unaffected. Env override:
352
469
  * MUONROI_TOP_LEVEL_TOOL_BUDGET_CHARS.
353
470
  */
354
- export declare function getTopLevelToolBudgetChars(maxRounds?: number): number;
471
+ export declare function getTopLevelToolBudgetChars(maxRounds?: number, contextWindowTokens?: number): number;
355
472
  export declare function getRoleModel(role: ModelRole): string | undefined;
356
473
  export declare function getRoleModels(): Partial<Record<ModelRole, string>>;
357
474
  export declare function getCouncilRounds(): number;
@@ -361,10 +478,41 @@ export declare function normalizeAutoCouncilConfidence(val: unknown): number;
361
478
  /** Pure validator extracted for testability; clamps user input to a sane range. */
362
479
  export declare function normalizeAutoCouncilMinRoles(val: unknown): number;
363
480
  export declare function getAutoCouncilConfidence(): number;
481
+ /**
482
+ * Whether the auto-council path runs the pre-debate clarification interview
483
+ * (model-designed askcards) before debating. Default true so a broadly-scoped
484
+ * "debate mode" request is clarified first. Env override wins over the user
485
+ * setting for quick dev toggling; env "0"/"false" disables, "1"/"true" enables.
486
+ */
487
+ export declare function isAutoCouncilClarifyEnabled(): boolean;
488
+ /**
489
+ * Whether auto-council should be skipped when the session model is a reasoning
490
+ * model. Default true. Env override wins over the user setting for quick dev
491
+ * toggling; env "0"/"false" disables the skip (forces council), "1"/"true"
492
+ * enables the skip.
493
+ */
494
+ export declare function isAutoCouncilSkipReasoning(): boolean;
364
495
  export declare function getAutoCouncilMinRoles(): number;
365
496
  export declare function isCouncilMultiProviderPreferred(): boolean;
366
497
  export declare function getCouncilExperienceMode(): CouncilExperienceMode;
498
+ export declare function normalizePeakHourPolicy(raw: unknown): PeakHourPolicy;
499
+ export declare function getPeakHourPolicy(): PeakHourPolicy;
367
500
  export declare function isCouncilCostAware(): boolean;
501
+ /**
502
+ * Normalize a raw councilLanguage value (Feature B). Trims + lowercases the two
503
+ * reserved modes ("auto", "english"); any other non-empty string is preserved
504
+ * as-is (trimmed) so locale labels keep the user's exact casing (e.g. "日本語").
505
+ * Empty / non-string → "auto".
506
+ */
507
+ export declare function normalizeCouncilLanguage(raw: unknown): string;
508
+ export declare function getCouncilLanguage(): string;
509
+ /**
510
+ * Router tier-promotion ceiling. See UserSettings.routingPromoteMax.
511
+ * Default "balanced" — router may promote up to balanced but never silently
512
+ * to premium. Validated to the three allowed values; any unknown value
513
+ * falls back to the default.
514
+ */
515
+ export declare function getRoutingPromoteMax(): "off" | "balanced" | "any";
368
516
  export declare function getDisabledProviders(): ProviderId[];
369
517
  export declare function isProviderDisabled(provider: ProviderId): boolean;
370
518
  export declare function setProviderDisabled(provider: ProviderId, disabled: boolean): ProviderId[];