muonroi-cli 1.8.3 → 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 (477) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +133 -122
  3. package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
  4. package/dist/packages/agent-harness-core/src/driver.js +46 -0
  5. package/dist/packages/agent-harness-core/src/event-tee.d.ts +48 -0
  6. package/dist/packages/agent-harness-core/src/event-tee.js +77 -0
  7. package/dist/packages/agent-harness-core/src/mcp-server.d.ts +11 -0
  8. package/dist/packages/agent-harness-core/src/mcp-server.js +87 -15
  9. package/dist/packages/agent-harness-core/src/protocol.d.ts +66 -2
  10. package/dist/packages/agent-harness-core/src/protocol.js +15 -0
  11. package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
  12. package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
  13. package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
  14. package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
  15. package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
  16. package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
  17. package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
  18. package/dist/packages/agent-harness-opentui/src/install.js +10 -0
  19. package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
  20. package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
  21. package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
  22. package/dist/src/agent-harness/mock-model.d.ts +28 -0
  23. package/dist/src/agent-harness/mock-model.js +63 -1
  24. package/dist/src/agent-harness/test-spawn.js +31 -0
  25. package/dist/src/cli/config/screen-providers.js +1 -1
  26. package/dist/src/cli/cost-forensics.d.ts +10 -0
  27. package/dist/src/cli/cost-forensics.js +30 -15
  28. package/dist/src/cli/keys-bundle.d.ts +1 -1
  29. package/dist/src/cli/keys-bundle.js +1 -1
  30. package/dist/src/cli/keys.d.ts +2 -2
  31. package/dist/src/cli/keys.js +19 -81
  32. package/dist/src/council/clarifier.d.ts +28 -2
  33. package/dist/src/council/clarifier.js +81 -15
  34. package/dist/src/council/context.js +49 -15
  35. package/dist/src/council/debate-checkpoint.d.ts +129 -0
  36. package/dist/src/council/debate-checkpoint.js +176 -0
  37. package/dist/src/council/debate-planner.js +51 -3
  38. package/dist/src/council/debate-summary.d.ts +25 -0
  39. package/dist/src/council/debate-summary.js +85 -0
  40. package/dist/src/council/debate.d.ts +169 -2
  41. package/dist/src/council/debate.js +1210 -134
  42. package/dist/src/council/index.d.ts +85 -1
  43. package/dist/src/council/index.js +634 -196
  44. package/dist/src/council/leader.d.ts +26 -0
  45. package/dist/src/council/leader.js +150 -9
  46. package/dist/src/council/llm.d.ts +32 -0
  47. package/dist/src/council/llm.js +231 -38
  48. package/dist/src/council/panel-select.d.ts +30 -0
  49. package/dist/src/council/panel-select.js +72 -0
  50. package/dist/src/council/planner.js +23 -0
  51. package/dist/src/council/preflight.d.ts +7 -0
  52. package/dist/src/council/preflight.js +14 -2
  53. package/dist/src/council/prompts.d.ts +30 -3
  54. package/dist/src/council/prompts.js +254 -84
  55. package/dist/src/council/stance-recall.d.ts +42 -0
  56. package/dist/src/council/stance-recall.js +57 -0
  57. package/dist/src/council/strip-think.d.ts +17 -0
  58. package/dist/src/council/strip-think.js +33 -0
  59. package/dist/src/council/types.d.ts +128 -0
  60. package/dist/src/ee/artifact-cache.d.ts +16 -0
  61. package/dist/src/ee/artifact-cache.js +32 -0
  62. package/dist/src/ee/auth.d.ts +1 -0
  63. package/dist/src/ee/auth.js +15 -2
  64. package/dist/src/ee/bridge.d.ts +10 -0
  65. package/dist/src/ee/bridge.js +58 -0
  66. package/dist/src/ee/client.js +81 -18
  67. package/dist/src/ee/export-transcripts.d.ts +1 -0
  68. package/dist/src/ee/export-transcripts.js +8 -10
  69. package/dist/src/ee/extract-session.js +29 -0
  70. package/dist/src/ee/extract-style.d.ts +58 -0
  71. package/dist/src/ee/extract-style.js +270 -0
  72. package/dist/src/ee/recall-ledger.d.ts +9 -0
  73. package/dist/src/ee/recall-ledger.js +3 -0
  74. package/dist/src/ee/scope.d.ts +1 -0
  75. package/dist/src/ee/scope.js +26 -1
  76. package/dist/src/ee/search.d.ts +7 -0
  77. package/dist/src/ee/search.js +24 -0
  78. package/dist/src/ee/transcript-emit.js +2 -0
  79. package/dist/src/ee/types.d.ts +22 -0
  80. package/dist/src/ee/who-am-i-brain.d.ts +35 -0
  81. package/dist/src/ee/who-am-i-brain.js +220 -0
  82. package/dist/src/ee/who-am-i.d.ts +10 -3
  83. package/dist/src/ee/who-am-i.js +12 -0
  84. package/dist/src/ee/workflow-event.d.ts +48 -0
  85. package/dist/src/ee/workflow-event.js +81 -0
  86. package/dist/src/flow/compaction/compress.d.ts +3 -3
  87. package/dist/src/flow/compaction/compress.js +45 -8
  88. package/dist/src/flow/compaction/extract.d.ts +4 -7
  89. package/dist/src/flow/compaction/extract.js +50 -10
  90. package/dist/src/flow/compaction/index.d.ts +13 -1
  91. package/dist/src/flow/compaction/index.js +70 -3
  92. package/dist/src/flow/compaction/input-guard.d.ts +24 -0
  93. package/dist/src/flow/compaction/input-guard.js +43 -0
  94. package/dist/src/flow/fold-planning.d.ts +36 -0
  95. package/dist/src/flow/fold-planning.js +83 -0
  96. package/dist/src/flow/hierarchy.d.ts +146 -0
  97. package/dist/src/flow/hierarchy.js +427 -0
  98. package/dist/src/flow/index.d.ts +1 -0
  99. package/dist/src/flow/index.js +2 -0
  100. package/dist/src/flow/run-artifacts.d.ts +102 -0
  101. package/dist/src/flow/run-artifacts.js +208 -0
  102. package/dist/src/generated/version.d.ts +1 -1
  103. package/dist/src/generated/version.js +1 -1
  104. package/dist/src/gsd/assessment-schema.d.ts +44 -0
  105. package/dist/src/gsd/assessment-schema.js +134 -0
  106. package/dist/src/gsd/capability-registry.d.ts +45 -0
  107. package/dist/src/gsd/capability-registry.js +337 -0
  108. package/dist/src/gsd/complexity-assessor.d.ts +39 -0
  109. package/dist/src/gsd/complexity-assessor.js +152 -0
  110. package/dist/src/gsd/config-bridge.d.ts +7 -0
  111. package/dist/src/gsd/config-bridge.js +114 -0
  112. package/dist/src/gsd/config-loader.d.ts +27 -0
  113. package/dist/src/gsd/config-loader.js +50 -0
  114. package/dist/src/gsd/council-context.d.ts +44 -0
  115. package/dist/src/gsd/council-context.js +114 -0
  116. package/dist/src/gsd/ee-closure.d.ts +28 -0
  117. package/dist/src/gsd/ee-closure.js +49 -0
  118. package/dist/src/gsd/flags.d.ts +55 -0
  119. package/dist/src/gsd/flags.js +83 -0
  120. package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
  121. package/dist/src/gsd/gsd-dispatch.js +131 -0
  122. package/dist/src/gsd/gsd-runtime.d.ts +22 -0
  123. package/dist/src/gsd/gsd-runtime.js +37 -0
  124. package/dist/src/gsd/host-adapter.d.ts +11 -0
  125. package/dist/src/gsd/host-adapter.js +29 -0
  126. package/dist/src/gsd/index.d.ts +24 -1
  127. package/dist/src/gsd/index.js +27 -0
  128. package/dist/src/gsd/loop-host-contract.d.ts +21 -0
  129. package/dist/src/gsd/loop-host-contract.js +39 -0
  130. package/dist/src/gsd/loop-host.d.ts +69 -0
  131. package/dist/src/gsd/loop-host.js +245 -0
  132. package/dist/src/gsd/loop-resolver.d.ts +36 -0
  133. package/dist/src/gsd/loop-resolver.js +79 -0
  134. package/dist/src/gsd/model-tier.d.ts +13 -0
  135. package/dist/src/gsd/model-tier.js +45 -0
  136. package/dist/src/gsd/mutation-gate.d.ts +16 -0
  137. package/dist/src/gsd/mutation-gate.js +41 -0
  138. package/dist/src/gsd/native-roadmap.d.ts +89 -0
  139. package/dist/src/gsd/native-roadmap.js +343 -0
  140. package/dist/src/gsd/native-state.d.ts +47 -0
  141. package/dist/src/gsd/native-state.js +220 -0
  142. package/dist/src/gsd/paths.d.ts +23 -0
  143. package/dist/src/gsd/paths.js +66 -0
  144. package/dist/src/gsd/phase-dag.d.ts +12 -0
  145. package/dist/src/gsd/phase-dag.js +94 -0
  146. package/dist/src/gsd/phase-sync.d.ts +42 -0
  147. package/dist/src/gsd/phase-sync.js +321 -0
  148. package/dist/src/gsd/pil-gate-context.d.ts +13 -0
  149. package/dist/src/gsd/pil-gate-context.js +64 -0
  150. package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
  151. package/dist/src/gsd/pil-gate-critic.js +74 -0
  152. package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
  153. package/dist/src/gsd/plan-council-prompts.js +79 -0
  154. package/dist/src/gsd/plan-council.d.ts +44 -0
  155. package/dist/src/gsd/plan-council.js +251 -0
  156. package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
  157. package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
  158. package/dist/src/gsd/product-workspace.d.ts +13 -0
  159. package/dist/src/gsd/product-workspace.js +124 -0
  160. package/dist/src/gsd/ship-bridge.d.ts +25 -0
  161. package/dist/src/gsd/ship-bridge.js +65 -0
  162. package/dist/src/gsd/state-document.d.ts +40 -0
  163. package/dist/src/gsd/state-document.js +163 -0
  164. package/dist/src/gsd/verdict-schema.d.ts +39 -0
  165. package/dist/src/gsd/verdict-schema.js +144 -0
  166. package/dist/src/gsd/verify-context.d.ts +22 -0
  167. package/dist/src/gsd/verify-context.js +27 -0
  168. package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
  169. package/dist/src/gsd/verify-council-prompts.js +85 -0
  170. package/dist/src/gsd/verify-council.d.ts +25 -0
  171. package/dist/src/gsd/verify-council.js +119 -0
  172. package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
  173. package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
  174. package/dist/src/gsd/workflow-engine.d.ts +60 -0
  175. package/dist/src/gsd/workflow-engine.js +207 -0
  176. package/dist/src/gsd/workflow-tools.d.ts +13 -0
  177. package/dist/src/gsd/workflow-tools.js +277 -0
  178. package/dist/src/hooks/index.js +1 -1
  179. package/dist/src/index.js +44 -11
  180. package/dist/src/maintain/pr-builder.js +23 -13
  181. package/dist/src/mcp/auto-setup.js +57 -32
  182. package/dist/src/mcp/client-pool.js +1 -1
  183. package/dist/src/mcp/ee-tools.js +1 -0
  184. package/dist/src/mcp/oauth-callback.js +2 -2
  185. package/dist/src/mcp/research-onboarding.js +8 -7
  186. package/dist/src/mcp/runtime.js +34 -2
  187. package/dist/src/mcp/setup-guide-text.d.ts +1 -1
  188. package/dist/src/mcp/setup-guide-text.js +77 -76
  189. package/dist/src/models/catalog-client.d.ts +87 -0
  190. package/dist/src/models/catalog-client.js +105 -38
  191. package/dist/src/models/catalog.json +528 -265
  192. package/dist/src/models/registry.d.ts +22 -7
  193. package/dist/src/models/registry.js +73 -10
  194. package/dist/src/ops/doctor.js +8 -8
  195. package/dist/src/orchestrator/auto-commit.js +1 -1
  196. package/dist/src/orchestrator/batch-turn-runner.js +2 -2
  197. package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
  198. package/dist/src/orchestrator/cache-prefix.js +83 -0
  199. package/dist/src/orchestrator/compact-request.d.ts +32 -0
  200. package/dist/src/orchestrator/compact-request.js +41 -0
  201. package/dist/src/orchestrator/compaction.d.ts +10 -0
  202. package/dist/src/orchestrator/compaction.js +27 -7
  203. package/dist/src/orchestrator/council-manager.d.ts +12 -3
  204. package/dist/src/orchestrator/council-manager.js +65 -24
  205. package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
  206. package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
  207. package/dist/src/orchestrator/error-utils.d.ts +29 -0
  208. package/dist/src/orchestrator/error-utils.js +132 -24
  209. package/dist/src/orchestrator/grounding-check.js +39 -1
  210. package/dist/src/orchestrator/message-processor.js +242 -33
  211. package/dist/src/orchestrator/orchestrator.d.ts +39 -3
  212. package/dist/src/orchestrator/orchestrator.js +651 -102
  213. package/dist/src/orchestrator/preprocessor.js +1 -1
  214. package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
  215. package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
  216. package/dist/src/orchestrator/prompts.js +159 -159
  217. package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
  218. package/dist/src/orchestrator/reactive-delegation.js +59 -0
  219. package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
  220. package/dist/src/orchestrator/retry-classifier.js +46 -2
  221. package/dist/src/orchestrator/safety-intercept.d.ts +45 -0
  222. package/dist/src/orchestrator/safety-intercept.js +55 -0
  223. package/dist/src/orchestrator/scope-reminder.js +1 -1
  224. package/dist/src/orchestrator/session-experience.d.ts +2 -1
  225. package/dist/src/orchestrator/session-experience.js +2 -1
  226. package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
  227. package/dist/src/orchestrator/should-run-gate.js +18 -0
  228. package/dist/src/orchestrator/stall-watchdog.d.ts +24 -3
  229. package/dist/src/orchestrator/stall-watchdog.js +47 -13
  230. package/dist/src/orchestrator/stream-runner.js +62 -29
  231. package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
  232. package/dist/src/orchestrator/sub-agent-cap.js +16 -1
  233. package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
  234. package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
  235. package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
  236. package/dist/src/orchestrator/subagent-compactor.js +126 -15
  237. package/dist/src/orchestrator/tool-engine.d.ts +26 -0
  238. package/dist/src/orchestrator/tool-engine.js +669 -56
  239. package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
  240. package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
  241. package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
  242. package/dist/src/orchestrator/turn-watchdog.d.ts +37 -0
  243. package/dist/src/orchestrator/turn-watchdog.js +55 -0
  244. package/dist/src/pil/agent-operating-contract.d.ts +1 -1
  245. package/dist/src/pil/agent-operating-contract.js +1 -1
  246. package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
  247. package/dist/src/pil/cheap-model-playbook.js +5 -1
  248. package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
  249. package/dist/src/pil/cheap-model-workbooks.js +1 -1
  250. package/dist/src/pil/discovery-types.d.ts +1 -0
  251. package/dist/src/pil/discovery.js +16 -11
  252. package/dist/src/pil/layer1-intent.d.ts +18 -6
  253. package/dist/src/pil/layer1-intent.js +66 -757
  254. package/dist/src/pil/layer15-context-scan.js +15 -1
  255. package/dist/src/pil/layer2_5-ponytail.js +8 -8
  256. package/dist/src/pil/layer3-ee-injection.js +23 -8
  257. package/dist/src/pil/layer4-gsd.js +69 -16
  258. package/dist/src/pil/layer5-context.js +7 -3
  259. package/dist/src/pil/layer6-output.d.ts +23 -0
  260. package/dist/src/pil/layer6-output.js +5 -1
  261. package/dist/src/pil/llm-classify.d.ts +33 -2
  262. package/dist/src/pil/llm-classify.js +123 -131
  263. package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
  264. package/dist/src/pil/native-capabilities-workbook.js +1 -0
  265. package/dist/src/pil/pipeline.js +34 -2
  266. package/dist/src/pil/response-tools.js +5 -3
  267. package/dist/src/pil/schema.d.ts +1 -0
  268. package/dist/src/pil/schema.js +2 -0
  269. package/dist/src/pil/types.d.ts +18 -0
  270. package/dist/src/playbook/directives.d.ts +4 -0
  271. package/dist/src/playbook/directives.js +17 -5
  272. package/dist/src/product-loop/backlog-builder.d.ts +14 -1
  273. package/dist/src/product-loop/backlog-builder.js +30 -6
  274. package/dist/src/product-loop/discovery-context-format.js +3 -1
  275. package/dist/src/product-loop/discovery-ecosystem.js +4 -1
  276. package/dist/src/product-loop/discovery-interview.js +32 -3
  277. package/dist/src/product-loop/discovery-schema.js +5 -1
  278. package/dist/src/product-loop/done-gate.js +3 -3
  279. package/dist/src/product-loop/ideal-trace.d.ts +7 -0
  280. package/dist/src/product-loop/ideal-trace.js +64 -0
  281. package/dist/src/product-loop/index.d.ts +13 -1
  282. package/dist/src/product-loop/index.js +333 -52
  283. package/dist/src/product-loop/loop-driver.d.ts +7 -0
  284. package/dist/src/product-loop/loop-driver.js +327 -116
  285. package/dist/src/product-loop/phase-plan.d.ts +5 -0
  286. package/dist/src/product-loop/phase-plan.js +39 -2
  287. package/dist/src/product-loop/phase-runner.js +9 -1
  288. package/dist/src/product-loop/progress-snapshot.js +4 -4
  289. package/dist/src/product-loop/sprint-runner.d.ts +111 -0
  290. package/dist/src/product-loop/sprint-runner.js +559 -16
  291. package/dist/src/product-loop/types.d.ts +36 -5
  292. package/dist/src/providers/adapter.d.ts +1 -1
  293. package/dist/src/providers/adapter.js +3 -4
  294. package/dist/src/providers/auth/browser-flow.d.ts +1 -1
  295. package/dist/src/providers/auth/browser-flow.js +1 -1
  296. package/dist/src/providers/auth/openai-oauth.js +1 -1
  297. package/dist/src/providers/auth/registry.js +0 -34
  298. package/dist/src/providers/auth/token-store.js +4 -1
  299. package/dist/src/providers/auth/types.d.ts +1 -1
  300. package/dist/src/providers/auth/types.js +1 -1
  301. package/dist/src/providers/capabilities.d.ts +24 -5
  302. package/dist/src/providers/capabilities.js +42 -24
  303. package/dist/src/providers/endpoints.d.ts +2 -2
  304. package/dist/src/providers/endpoints.js +11 -10
  305. package/dist/src/providers/keychain.d.ts +1 -1
  306. package/dist/src/providers/keychain.js +7 -9
  307. package/dist/src/providers/mcp-vision-bridge.js +82 -172
  308. package/dist/src/providers/openai-compatible.js +8 -1
  309. package/dist/src/providers/pricing.d.ts +2 -2
  310. package/dist/src/providers/pricing.js +3 -13
  311. package/dist/src/providers/runtime.d.ts +27 -2
  312. package/dist/src/providers/runtime.js +78 -15
  313. package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
  314. package/dist/src/providers/strategies/base.strategy.js +24 -1
  315. package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
  316. package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
  317. package/dist/src/providers/strategies/registry.js +4 -4
  318. package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
  319. package/dist/src/providers/strategies/thinking-mode.js +280 -1
  320. package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
  321. package/dist/src/providers/strategies/zai.strategy.js +44 -0
  322. package/dist/src/providers/types.d.ts +5 -6
  323. package/dist/src/providers/types.js +2 -2
  324. package/dist/src/providers/vision-backend.d.ts +47 -0
  325. package/dist/src/providers/vision-backend.js +258 -0
  326. package/dist/src/providers/vision-proxy.d.ts +22 -9
  327. package/dist/src/providers/vision-proxy.js +63 -132
  328. package/dist/src/providers/wire-debug.js +95 -0
  329. package/dist/src/reporter/index.js +1 -1
  330. package/dist/src/router/decide.d.ts +13 -0
  331. package/dist/src/router/decide.js +138 -36
  332. package/dist/src/router/peak-hour.d.ts +38 -0
  333. package/dist/src/router/peak-hour.js +107 -0
  334. package/dist/src/router/step-router.js +3 -2
  335. package/dist/src/router/warm.js +4 -5
  336. package/dist/src/scaffold/bb-ecosystem-apply.js +47 -47
  337. package/dist/src/scaffold/bb-quality-gate.js +5 -5
  338. package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
  339. package/dist/src/scaffold/continuation-prompt.js +86 -60
  340. package/dist/src/scaffold/init-new.js +453 -453
  341. package/dist/src/scaffold/point-to-existing.d.ts +21 -0
  342. package/dist/src/scaffold/point-to-existing.js +25 -0
  343. package/dist/src/self-qa/agentic-loop.js +22 -22
  344. package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
  345. package/dist/src/{ui/state → state}/active-run.js +21 -0
  346. package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
  347. package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
  348. package/dist/src/state/turn-trace.d.ts +43 -0
  349. package/dist/src/state/turn-trace.js +32 -0
  350. package/dist/src/storage/db.js +2 -1
  351. package/dist/src/storage/index.d.ts +1 -1
  352. package/dist/src/storage/index.js +1 -1
  353. package/dist/src/storage/interaction-log.d.ts +1 -1
  354. package/dist/src/storage/interaction-log.js +5 -5
  355. package/dist/src/storage/migrations.js +196 -126
  356. package/dist/src/storage/session-experience-store.js +4 -4
  357. package/dist/src/storage/sessions.d.ts +28 -10
  358. package/dist/src/storage/sessions.js +112 -55
  359. package/dist/src/storage/transcript-view.js +1 -1
  360. package/dist/src/storage/transcript.d.ts +51 -0
  361. package/dist/src/storage/transcript.js +383 -112
  362. package/dist/src/storage/usage.js +14 -14
  363. package/dist/src/storage/workspaces.js +12 -12
  364. package/dist/src/tools/file.d.ts +15 -0
  365. package/dist/src/tools/file.js +32 -0
  366. package/dist/src/tools/native-tools.js +5 -0
  367. package/dist/src/tools/registry.d.ts +3 -0
  368. package/dist/src/tools/registry.js +460 -22
  369. package/dist/src/tools/research.d.ts +29 -0
  370. package/dist/src/tools/research.js +233 -0
  371. package/dist/src/types/index.d.ts +118 -3
  372. package/dist/src/ui/app.js +0 -0
  373. package/dist/src/ui/cards/product-status-card.js +1 -1
  374. package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
  375. package/dist/src/ui/components/bubble-body-guard.js +50 -0
  376. package/dist/src/ui/components/context-rail.d.ts +26 -0
  377. package/dist/src/ui/components/context-rail.js +33 -0
  378. package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
  379. package/dist/src/ui/components/council-conclusion-card.js +420 -0
  380. package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
  381. package/dist/src/ui/components/council-debate-pill.js +34 -0
  382. package/dist/src/ui/components/council-info-card.js +2 -2
  383. package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
  384. package/dist/src/ui/components/council-leader-bubble.js +21 -11
  385. package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
  386. package/dist/src/ui/components/council-message-bubble.js +16 -15
  387. package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
  388. package/dist/src/ui/components/council-phase-timeline.js +49 -15
  389. package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
  390. package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
  391. package/dist/src/ui/components/council-question-card.js +12 -12
  392. package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
  393. package/dist/src/ui/components/council-rail-rounds.js +57 -0
  394. package/dist/src/ui/components/council-round-group.d.ts +38 -0
  395. package/dist/src/ui/components/council-round-group.js +88 -0
  396. package/dist/src/ui/components/council-status-list.d.ts +3 -1
  397. package/dist/src/ui/components/council-status-list.js +36 -24
  398. package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
  399. package/dist/src/ui/components/council-synthesis-banner.js +20 -5
  400. package/dist/src/ui/components/halt-recovery-card.js +9 -5
  401. package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
  402. package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
  403. package/dist/src/ui/components/prompt-box.js +18 -16
  404. package/dist/src/ui/components/session-tree-card.d.ts +14 -0
  405. package/dist/src/ui/components/session-tree-card.js +46 -0
  406. package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
  407. package/dist/src/ui/components/slash-inline-menu.js +26 -5
  408. package/dist/src/ui/components/task-list-panel.d.ts +14 -1
  409. package/dist/src/ui/components/task-list-panel.js +22 -2
  410. package/dist/src/ui/containers/modals-layer.d.ts +2 -1
  411. package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
  412. package/dist/src/ui/mcp-modal.js +2 -4
  413. package/dist/src/ui/modals/api-key-modal.js +1 -1
  414. package/dist/src/ui/modals/connect-modal.js +4 -3
  415. package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
  416. package/dist/src/ui/modals/session-picker-modal.js +3 -5
  417. package/dist/src/ui/picker-providers.d.ts +1 -1
  418. package/dist/src/ui/picker-providers.js +1 -1
  419. package/dist/src/ui/primitives/index.d.ts +1 -0
  420. package/dist/src/ui/primitives/index.js +2 -0
  421. package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
  422. package/dist/src/ui/primitives/semantic-primitives.js +81 -0
  423. package/dist/src/ui/slash/compact.js +5 -7
  424. package/dist/src/ui/slash/cost.js +1 -1
  425. package/dist/src/ui/slash/council-inspect.js +4 -4
  426. package/dist/src/ui/slash/council.js +19 -1
  427. package/dist/src/ui/slash/debug.d.ts +3 -31
  428. package/dist/src/ui/slash/debug.js +9 -20
  429. package/dist/src/ui/slash/ideal.d.ts +6 -2
  430. package/dist/src/ui/slash/ideal.js +97 -7
  431. package/dist/src/ui/slash/menu-items.d.ts +7 -0
  432. package/dist/src/ui/slash/menu-items.js +12 -18
  433. package/dist/src/ui/slash/registry.d.ts +2 -0
  434. package/dist/src/ui/slash/registry.js +4 -0
  435. package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
  436. package/dist/src/ui/status-bar/cache-hit.js +9 -0
  437. package/dist/src/ui/status-bar/index.d.ts +1 -1
  438. package/dist/src/ui/status-bar/index.js +7 -3
  439. package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
  440. package/dist/src/ui/status-bar/usd-meter.js +6 -4
  441. package/dist/src/ui/theme.d.ts +1 -0
  442. package/dist/src/ui/theme.js +2 -0
  443. package/dist/src/ui/types.d.ts +7 -0
  444. package/dist/src/ui/use-app-logic.js +0 -0
  445. package/dist/src/ui/utils/format.d.ts +14 -0
  446. package/dist/src/ui/utils/format.js +23 -3
  447. package/dist/src/usage/downgrade.js +2 -2
  448. package/dist/src/usage/product-ledger.js +2 -2
  449. package/dist/src/utils/clipboard-image.js +23 -23
  450. package/dist/src/utils/install-manager.js +14 -11
  451. package/dist/src/utils/logger.js +2 -2
  452. package/dist/src/utils/permission-mode.js +5 -3
  453. package/dist/src/utils/redactor.js +1 -1
  454. package/dist/src/utils/settings.d.ts +153 -5
  455. package/dist/src/utils/settings.js +233 -29
  456. package/dist/src/utils/side-question.js +2 -2
  457. package/dist/src/utils/skills.js +3 -3
  458. package/dist/src/utils/visible-retry.d.ts +11 -0
  459. package/dist/src/utils/visible-retry.js +10 -1
  460. package/dist/src/verify/entrypoint.d.ts +1 -1
  461. package/dist/src/verify/entrypoint.js +1 -1
  462. package/dist/src/verify/recipes.d.ts +13 -0
  463. package/dist/src/verify/recipes.js +15 -0
  464. package/package.json +135 -132
  465. package/dist/src/providers/auth/gcloud.d.ts +0 -28
  466. package/dist/src/providers/auth/gcloud.js +0 -102
  467. package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
  468. package/dist/src/providers/auth/gemini-oauth.js +0 -472
  469. package/dist/src/providers/gemini.d.ts +0 -11
  470. package/dist/src/providers/gemini.js +0 -45
  471. package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
  472. package/dist/src/providers/siliconflow-sse-repair.js +0 -177
  473. package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
  474. package/dist/src/providers/strategies/google.strategy.js +0 -174
  475. package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
  476. package/dist/src/ui/containers/chat-feed.d.ts +0 -40
  477. package/dist/src/ui/containers/chat-feed.js +0 -66
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 muonroi
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 muonroi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,122 +1,133 @@
1
- <p align="center">
2
- <h1 align="center">muonroi-cli</h1>
3
- <p align="center">
4
- <em>An AI coding agent where models argue with each other before answering.</em>
5
- </p>
6
- <p align="center">
7
- <a href="https://github.com/muonroi/muonroi-cli/actions/workflows/ci-matrix.yml"><img alt="CI" src="https://github.com/muonroi/muonroi-cli/actions/workflows/ci-matrix.yml/badge.svg"></a>
8
- <a href="https://www.npmjs.com/package/muonroi-cli"><img alt="npm" src="https://img.shields.io/npm/v/muonroi-cli.svg"></a>
9
- <img alt="Providers" src="https://img.shields.io/badge/providers-7%20supported-blue">
10
- <img alt="License" src="https://img.shields.io/badge/license-MIT-yellow">
11
- <img alt="Runtime" src="https://img.shields.io/badge/runtime-Bun%201.3%2B-orange">
12
- </p>
13
- </p>
14
-
15
- ---
16
-
17
- > Routes each task to the optimal model, runs adversarial multi-model debates for high-stakes decisions, and persists behavioral memory across sessions. Bring your own API keys. Total cost: ~$5/month.
18
-
19
- <p align="center">
20
- <img src="https://raw.githubusercontent.com/muonroi/muonroi-cli/master/docs/demo.gif" alt="Council debate — REST vs gRPC decision" width="840" />
21
- </p>
22
-
23
- ## Quick Start
24
-
25
- ### Install
26
-
27
- **Recommended — prebuilt standalone binary (zero runtime deps, no prereqs):**
28
-
29
- Linux / macOS:
30
- ```bash
31
- curl -fsSL https://raw.githubusercontent.com/muonroi/muonroi-cli/master/install.sh | bash
32
- ```
33
-
34
- Windows PowerShell:
35
- ```powershell
36
- irm https://raw.githubusercontent.com/muonroi/muonroi-cli/master/install.ps1 | iex
37
- ```
38
-
39
- The installers download a `bun --compile` binary from GitHub Releases — single executable, all native deps bundled, no Node/Bun/build tools required.
40
-
41
- **Bun runtime (requires Bun ≥ 1.x):**
42
- ```bash
43
- bun add -g muonroi-cli
44
- muonroi-cli
45
- ```
46
-
47
- > **⚠ Why no `npm install -g`?** The TUI engine (`@opentui/core`) uses Bun-only `import ... with { type: "file" }` for Tree-sitter syntax highlight queries (`.scm` files). Node ESM cannot load these, so running under bare Node throws `ERR_UNKNOWN_FILE_EXTENSION`. Use the standalone installer (above) or `bun add -g`.
48
-
49
- ### First run
50
-
51
- On first launch the CLI shows a wizard that:
52
- 1. Lists supported providers (currently **DeepSeek** and **SiliconFlow**).
53
- 2. Offers four ways to add credentials: paste an API key, import an encrypted bundle (`keys export`/`keys import`), sync from Bitwarden, or skip and add later via `/providers` inside the TUI.
54
-
55
- After setup, role routing auto-balances across enabled providers:
56
-
57
- ```json
58
- // ~/.muonroi-cli/user-settings.json (generated by the wizardedit if needed)
59
- {
60
- "defaultProvider": "deepseek",
61
- "providers": {
62
- "deepseek": { "enabled": true },
63
- "siliconflow": { "enabled": true }
64
- },
65
- "roleModels": {
66
- "leader": "deepseek-v4-pro",
67
- "implement": "deepseek-v4-flash",
68
- "verify": "deepseek-v4-pro",
69
- "research": "deepseek-v4-flash"
70
- }
71
- }
72
- ```
73
-
74
- ### Moving keys between devices
75
-
76
- ```bash
77
- # Source device — encrypts every stored key into one passphrase-protected file
78
- muonroi-cli keys export ~/muonroi-keys.json
79
-
80
- # Move the file via any channel (USB, Drive, AirDrop, email...)
81
-
82
- # Target device — same passphrase rehydrates the OS keychain
83
- muonroi-cli keys import ~/muonroi-keys.json
84
- ```
85
-
86
- Inside the TUI press `/providers` then `B` to sync directly from a Bitwarden vault instead.
87
-
88
- ### Updates
89
-
90
- The CLI checks npm once per day on startup and prompts when a newer version is available. Set `autoUpdate: true` in `user-settings.json` to skip the prompt and update silently. Manual: `muonroi-cli update`.
91
-
92
- ## Documentation
93
-
94
- Full documentation at **[docs.muonroi.com/docs/cli](https://docs.muonroi.com/docs/cli/overview)**
95
-
96
- | Topic | Link |
97
- |---|---|
98
- | Overview & architecture | [CLI Overview](https://docs.muonroi.com/docs/cli/overview) |
99
- | Multi-Model Council | [Council Debate Guide](https://docs.muonroi.com/docs/cli/guides/council-debate) |
100
- | Prompt Intelligence Layer | [PIL Pipeline Guide](https://docs.muonroi.com/docs/cli/guides/pil-pipeline) |
101
- | Experience Engine | [Experience Engine Guide](https://docs.muonroi.com/docs/cli/guides/experience-engine) |
102
- | Agent Harness | [Agent Harness Guide](https://docs.muonroi.com/docs/cli/guides/agent-harness) |
103
- | Settings reference | [CLI Settings Reference](https://docs.muonroi.com/docs/cli/reference/cli-settings-reference) |
104
- | Commands reference | [Commands Reference](https://docs.muonroi.com/docs/cli/reference/commands-reference) |
105
- | Providers reference | [Providers Reference](https://docs.muonroi.com/docs/cli/reference/providers-reference) |
106
-
107
- ## Development
108
-
109
- ```bash
110
- git clone https://github.com/muonroi/muonroi-cli.git
111
- cd muonroi-cli && bun install
112
-
113
- bun run dev # run from source
114
- bun run typecheck # type check
115
- bun run test # vitest
116
- bun run lint # biome check
117
- bun run build:binary # standalone binary
118
- ```
119
-
120
- ## License
121
-
122
- MIT
1
+ <p align="center">
2
+ <h1 align="center">muonroi-cli</h1>
3
+ <p align="center">
4
+ <em>An AI coding agent where models argue with each other before answering.</em>
5
+ </p>
6
+ <p align="center">
7
+ <a href="https://github.com/muonroi/muonroi-cli/actions/workflows/ci-matrix.yml"><img alt="CI" src="https://github.com/muonroi/muonroi-cli/actions/workflows/ci-matrix.yml/badge.svg"></a>
8
+ <a href="https://www.npmjs.com/package/muonroi-cli"><img alt="npm" src="https://img.shields.io/npm/v/muonroi-cli.svg"></a>
9
+ <img alt="Providers" src="https://img.shields.io/badge/providers-7%20supported-blue">
10
+ <img alt="License" src="https://img.shields.io/badge/license-MIT-yellow">
11
+ <img alt="Runtime" src="https://img.shields.io/badge/runtime-Bun%201.3%2B-orange">
12
+ </p>
13
+ </p>
14
+
15
+ ---
16
+
17
+ > Routes each task to the optimal model, runs adversarial multi-model debates for high-stakes decisions, and persists behavioral memory across sessions. Bring your own API keys. Total cost: ~$5/month.
18
+
19
+ <p align="center">
20
+ <img src="https://raw.githubusercontent.com/muonroi/muonroi-cli/master/docs/demo.gif" alt="Council debate — REST vs gRPC decision" width="840" />
21
+ </p>
22
+
23
+ ## Quick Start
24
+
25
+ ### Install
26
+
27
+ **Recommended — install globally via NPM (requires Node.js 20) or Bun (requires Bun ≥ 1.x):**
28
+
29
+ Using NPM:
30
+ ```bash
31
+ npm install -g muonroi-cli
32
+ ```
33
+
34
+ Using Bun:
35
+ ```bash
36
+ bun add -g muonroi-cli
37
+ ```
38
+
39
+ Once installed, run:
40
+ ```bash
41
+ muonroi-cli
42
+ ```
43
+
44
+ **Alternative — Prebuilt standalone binary (requires access to the GitHub repository):**
45
+
46
+ Linux / macOS:
47
+ ```bash
48
+ # Note: Requires github authorization if the repository is private
49
+ curl -fsSL https://raw.githubusercontent.com/muonroi/muonroi-cli/master/install.sh | bash
50
+ ```
51
+
52
+ Windows PowerShell:
53
+ ```powershell
54
+ # Note: Requires github authorization if the repository is private
55
+ irm https://raw.githubusercontent.com/muonroi/muonroi-cli/master/install.ps1 | iex
56
+ ```
57
+
58
+ The installers download a `bun --compile` binary from GitHub Releases single executable, all native deps bundled, no Node/Bun/build tools required.
59
+
60
+ ### First run
61
+
62
+ On first launch the CLI shows a wizard that:
63
+ 1. Lists supported providers (currently **DeepSeek** and **SiliconFlow**).
64
+ 2. Offers four ways to add credentials: paste an API key, import an encrypted bundle (`keys export`/`keys import`), sync from Bitwarden, or skip and add later via `/providers` inside the TUI.
65
+
66
+ After setup, role routing auto-balances across enabled providers:
67
+
68
+ ```json
69
+ // ~/.muonroi-cli/user-settings.json (generated by the wizard — edit if needed)
70
+ {
71
+ "defaultProvider": "deepseek",
72
+ "providers": {
73
+ "deepseek": { "enabled": true },
74
+ "siliconflow": { "enabled": true }
75
+ },
76
+ "roleModels": {
77
+ "leader": "deepseek-v4-pro",
78
+ "implement": "deepseek-v4-flash",
79
+ "verify": "deepseek-v4-pro",
80
+ "research": "deepseek-v4-flash"
81
+ }
82
+ }
83
+ ```
84
+
85
+ ### Moving keys between devices
86
+
87
+ ```bash
88
+ # Source device — encrypts every stored key into one passphrase-protected file
89
+ muonroi-cli keys export ~/muonroi-keys.json
90
+
91
+ # Move the file via any channel (USB, Drive, AirDrop, email...)
92
+
93
+ # Target device — same passphrase rehydrates the OS keychain
94
+ muonroi-cli keys import ~/muonroi-keys.json
95
+ ```
96
+
97
+ Inside the TUI press `/providers` then `B` to sync directly from a Bitwarden vault instead.
98
+
99
+ ### Updates
100
+
101
+ The CLI checks npm once per day on startup and prompts when a newer version is available. Set `autoUpdate: true` in `user-settings.json` to skip the prompt and update silently. Manual: `muonroi-cli update`.
102
+
103
+ ## Documentation
104
+
105
+ Full documentation at **[docs.muonroi.com/docs/cli](https://docs.muonroi.com/docs/cli/overview)**
106
+
107
+ | Topic | Link |
108
+ |---|---|
109
+ | Overview & architecture | [CLI Overview](https://docs.muonroi.com/docs/cli/overview) |
110
+ | Multi-Model Council | [Council Debate Guide](https://docs.muonroi.com/docs/cli/guides/council-debate) |
111
+ | Prompt Intelligence Layer | [PIL Pipeline Guide](https://docs.muonroi.com/docs/cli/guides/pil-pipeline) |
112
+ | Experience Engine | [Experience Engine Guide](https://docs.muonroi.com/docs/cli/guides/experience-engine) |
113
+ | Agent Harness | [Agent Harness Guide](https://docs.muonroi.com/docs/cli/guides/agent-harness) |
114
+ | Settings reference | [CLI Settings Reference](https://docs.muonroi.com/docs/cli/reference/cli-settings-reference) |
115
+ | Commands reference | [Commands Reference](https://docs.muonroi.com/docs/cli/reference/commands-reference) |
116
+ | Providers reference | [Providers Reference](https://docs.muonroi.com/docs/cli/reference/providers-reference) |
117
+
118
+ ## Development
119
+
120
+ ```bash
121
+ git clone https://github.com/muonroi/muonroi-cli.git
122
+ cd muonroi-cli && bun install
123
+
124
+ bun run dev # run from source
125
+ bun run typecheck # type check
126
+ bun run test # vitest
127
+ bun run lint # biome check
128
+ bun run build:binary # standalone binary
129
+ ```
130
+
131
+ ## License
132
+
133
+ MIT
@@ -1,5 +1,13 @@
1
1
  import { type Predicate } from "./predicate.js";
2
- import type { LiveEvent, LiveFrame, UINode } from "./protocol.js";
2
+ import type { LiveEvent, LiveFrame, UINode, VisualFrame } from "./protocol.js";
3
+ import { type VisualQualityReport } from "./visual-quality.js";
4
+ /** A single decoded cell from the rendered grid (returned by `visual_cell`). */
5
+ export type VisualCell = {
6
+ char: string;
7
+ fg: string;
8
+ bg: string;
9
+ attrs: number;
10
+ };
3
11
  type WaitConditionIdle = {
4
12
  idle: true;
5
13
  };
@@ -31,6 +39,9 @@ type DriverDeps = {
31
39
  type Ingested = {
32
40
  kind: "frame";
33
41
  frame: LiveFrame;
42
+ } | {
43
+ kind: "visual";
44
+ frame: VisualFrame;
34
45
  } | {
35
46
  kind: "idle";
36
47
  } | {
@@ -69,6 +80,21 @@ export type Driver = {
69
80
  */
70
81
  events: (filter?: EventFilter) => AsyncIterable<LiveEvent>;
71
82
  render_text: () => string;
83
+ /** Latest VisualFrame — the ACTUAL rendered cell grid (colors + attributes),
84
+ * or null if the TUI has not emitted one (renderer not attached). */
85
+ snapshot_visual: () => VisualFrame | null;
86
+ /** Render the visual grid as plain text (what a human reads on screen) —
87
+ * faithful to the rendered characters, unlike render_text (semantic tree). */
88
+ render_visual: () => string;
89
+ /** Decode the cell at (row, col) — char + fg/bg hex + attribute bits — from
90
+ * the latest VisualFrame, accounting for wide (2-col) glyphs. Null if out of
91
+ * range or no visual frame yet. */
92
+ visual_cell: (row: number, col: number) => VisualCell | null;
93
+ /** Programmatic visual-quality heuristics over the latest VisualFrame:
94
+ * near-empty-row ratio, blank-row runs, whitespace density, and mojibake —
95
+ * the exact "messy render" signals the semantic tree is blind to. Null if no
96
+ * visual frame yet. */
97
+ visual_quality: () => VisualQualityReport | null;
72
98
  _ingest: (m: Ingested) => void;
73
99
  /** Called when the TUI exits. Cleanly terminates all active `events()` iterables. */
74
100
  _closeAllSubscribers: () => void;
@@ -1,5 +1,6 @@
1
1
  import { evaluatePredicate, predicateSchema } from "./predicate.js";
2
2
  import { matchSelector } from "./selector.js";
3
+ import { computeVisualQuality } from "./visual-quality.js";
3
4
  // ---------------------------------------------------------------------------
4
5
  // Constants
5
6
  // ---------------------------------------------------------------------------
@@ -12,6 +13,7 @@ const PER_SUBSCRIBER_QUEUE_CAP = 256;
12
13
  // ---------------------------------------------------------------------------
13
14
  export function createDriver(deps) {
14
15
  let latestFrame = null;
16
+ let latestVisualFrame = null;
15
17
  let lastIdleAt = -1;
16
18
  const eventBuffer = [];
17
19
  const waiters = new Set();
@@ -276,10 +278,54 @@ export function createDriver(deps) {
276
278
  return "(no frame)";
277
279
  return latestFrame.nodes.map((n) => renderNode(n, 0)).join("\n");
278
280
  },
281
+ snapshot_visual() {
282
+ return latestVisualFrame;
283
+ },
284
+ render_visual() {
285
+ if (!latestVisualFrame)
286
+ return "(no visual frame)";
287
+ return latestVisualFrame.lines
288
+ .map((ln) => ln.spans
289
+ .map((s) => s.text)
290
+ .join("")
291
+ .replace(/\s+$/, ""))
292
+ .join("\n");
293
+ },
294
+ visual_cell(row, col) {
295
+ const frame = latestVisualFrame;
296
+ if (!frame)
297
+ return null;
298
+ const line = frame.lines[row];
299
+ if (!line)
300
+ return null;
301
+ // Walk spans accumulating display columns; a wide glyph spans 2 columns
302
+ // but its span.width already reflects that, so index within the run by
303
+ // string position while tracking the column cursor.
304
+ let colCursor = 0;
305
+ for (const span of line.spans) {
306
+ const chars = [...span.text];
307
+ for (const ch of chars) {
308
+ // A char occupies span.width / chars.length columns on average; for
309
+ // the common width===text-length case this is 1. Round to stay integral.
310
+ const chCols = Math.max(1, Math.round(span.width / Math.max(1, chars.length)));
311
+ if (col >= colCursor && col < colCursor + chCols) {
312
+ return { char: ch, fg: span.fg, bg: span.bg, attrs: span.attrs };
313
+ }
314
+ colCursor += chCols;
315
+ }
316
+ }
317
+ return null;
318
+ },
319
+ visual_quality() {
320
+ return latestVisualFrame ? computeVisualQuality(latestVisualFrame) : null;
321
+ },
279
322
  _ingest(m) {
280
323
  if (m.kind === "frame") {
281
324
  latestFrame = m.frame;
282
325
  }
326
+ else if (m.kind === "visual") {
327
+ latestVisualFrame = m.frame;
328
+ }
283
329
  else if (m.kind === "idle") {
284
330
  lastIdleAt = Date.now();
285
331
  }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * event-tee.ts — optional JSONL sink for harness LiveEvents.
3
+ *
4
+ * Why: the MCP wake mechanism that re-invokes an external agent is a background
5
+ * task (e.g. a milestone watcher), which is a SEPARATE process from the MCP
6
+ * server. That watcher can only read files — it cannot reach the in-process
7
+ * driver that holds the real UI. So a generic, reusable milestone watcher needs
8
+ * the harness to persist events to a file it can tail.
9
+ *
10
+ * The DB only records debate-END rows (synthesis/debate_complete), so a
11
+ * DB-poll watcher is blind to mid-flight modal pauses (askcard-open) that never
12
+ * write a DB row. Teeing every LiveEvent to a JSONL file closes that gap for
13
+ * ANY event kind.
14
+ *
15
+ * Ephemeral events (toast, disconnect, retry, ee-*) flash and vanish before an
16
+ * agent can wake + render, so for those kinds — and ONLY those — we attach a
17
+ * plain-text visual snapshot captured at emit time, so the watcher's wake
18
+ * payload carries the exact frame. Persistent states (askcard, post-debate
19
+ * card) stay put, so the agent renders them fresh on demand; embedding a stale
20
+ * snapshot for those would be worse, not better.
21
+ *
22
+ * Gated entirely behind MUONROI_HARNESS_EVENT_LOG — unset means zero behavior
23
+ * change (clean checkouts are byte-identical to before this file existed).
24
+ */
25
+ import type { LiveEvent } from "./protocol.js";
26
+ /**
27
+ * Event kinds that flash and disappear before an agent can wake + render.
28
+ * Only these carry an at-emit visual snapshot in the teed line.
29
+ */
30
+ export declare const EPHEMERAL_KINDS: ReadonlySet<string>;
31
+ /** One teed JSONL record. */
32
+ export interface TeedEventLine {
33
+ ts: number;
34
+ kind: string;
35
+ event: LiveEvent;
36
+ /** Present only for EPHEMERAL_KINDS — plain-text visual frame at emit time. */
37
+ visualText?: string;
38
+ }
39
+ /**
40
+ * Build an event-tee sink. Returns null when MUONROI_HARNESS_EVENT_LOG is unset
41
+ * or blank (no-op path — caller skips it entirely).
42
+ *
43
+ * @param getVisualText - lazily renders the current visual frame to plain text
44
+ * (driver.render_visual). Called ONLY for ephemeral kinds, so persistent
45
+ * events pay nothing.
46
+ * @param envValue - value of MUONROI_HARNESS_EVENT_LOG (injectable for tests).
47
+ */
48
+ export declare function createEventTee(getVisualText: () => string | null, envValue?: string): ((event: LiveEvent) => void) | null;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * event-tee.ts — optional JSONL sink for harness LiveEvents.
3
+ *
4
+ * Why: the MCP wake mechanism that re-invokes an external agent is a background
5
+ * task (e.g. a milestone watcher), which is a SEPARATE process from the MCP
6
+ * server. That watcher can only read files — it cannot reach the in-process
7
+ * driver that holds the real UI. So a generic, reusable milestone watcher needs
8
+ * the harness to persist events to a file it can tail.
9
+ *
10
+ * The DB only records debate-END rows (synthesis/debate_complete), so a
11
+ * DB-poll watcher is blind to mid-flight modal pauses (askcard-open) that never
12
+ * write a DB row. Teeing every LiveEvent to a JSONL file closes that gap for
13
+ * ANY event kind.
14
+ *
15
+ * Ephemeral events (toast, disconnect, retry, ee-*) flash and vanish before an
16
+ * agent can wake + render, so for those kinds — and ONLY those — we attach a
17
+ * plain-text visual snapshot captured at emit time, so the watcher's wake
18
+ * payload carries the exact frame. Persistent states (askcard, post-debate
19
+ * card) stay put, so the agent renders them fresh on demand; embedding a stale
20
+ * snapshot for those would be worse, not better.
21
+ *
22
+ * Gated entirely behind MUONROI_HARNESS_EVENT_LOG — unset means zero behavior
23
+ * change (clean checkouts are byte-identical to before this file existed).
24
+ */
25
+ import { appendFileSync } from "node:fs";
26
+ /**
27
+ * Event kinds that flash and disappear before an agent can wake + render.
28
+ * Only these carry an at-emit visual snapshot in the teed line.
29
+ */
30
+ export const EPHEMERAL_KINDS = new Set([
31
+ "toast",
32
+ "disconnect",
33
+ "stream-retry",
34
+ "ee-timeout",
35
+ "ee-error",
36
+ "grounding-flag",
37
+ ]);
38
+ /**
39
+ * Build an event-tee sink. Returns null when MUONROI_HARNESS_EVENT_LOG is unset
40
+ * or blank (no-op path — caller skips it entirely).
41
+ *
42
+ * @param getVisualText - lazily renders the current visual frame to plain text
43
+ * (driver.render_visual). Called ONLY for ephemeral kinds, so persistent
44
+ * events pay nothing.
45
+ * @param envValue - value of MUONROI_HARNESS_EVENT_LOG (injectable for tests).
46
+ */
47
+ export function createEventTee(getVisualText, envValue) {
48
+ const path = (envValue ?? "").trim();
49
+ if (!path)
50
+ return null;
51
+ return (event) => {
52
+ // The idle sentinel arrives as { t: "idle" } — never here. Guard anyway so
53
+ // a malformed event can't crash the ingest loop.
54
+ const kind = event.kind;
55
+ if (typeof kind !== "string")
56
+ return;
57
+ const line = { ts: Date.now(), kind, event };
58
+ if (EPHEMERAL_KINDS.has(kind)) {
59
+ try {
60
+ const visual = getVisualText();
61
+ if (visual)
62
+ line.visualText = visual;
63
+ }
64
+ catch (err) {
65
+ // A visual-render failure must not drop the event record itself.
66
+ console.error(`[event-tee] visual snapshot failed for kind=${kind}: ${err?.message}`);
67
+ }
68
+ }
69
+ try {
70
+ appendFileSync(path, `${JSON.stringify(line)}\n`);
71
+ }
72
+ catch (err) {
73
+ console.error(`[event-tee] append failed (path=${path}, kind=${kind}): ${err?.message}`);
74
+ }
75
+ };
76
+ }
77
+ //# sourceMappingURL=event-tee.js.map
@@ -13,6 +13,7 @@
13
13
  */
14
14
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
15
15
  import { type Driver } from "./driver.js";
16
+ import type { LiveEvent } from "./protocol.js";
16
17
  /**
17
18
  * The result returned by a HarnessSpawn implementation.
18
19
  * Both the POSIX fd-3/4 and Windows named-pipe transports satisfy this shape.
@@ -95,6 +96,16 @@ export declare function registerAsyncTools(server: McpServer, getDriver: () => D
95
96
  export declare function createMcpHarnessServer({ spawn }: {
96
97
  spawn: HarnessSpawn;
97
98
  }): McpServer;
99
+ /**
100
+ * Build the onLine sidechannel handler: parse each JSON line, ingest frames /
101
+ * visuals / idle / events into the driver, and tee events to the optional JSONL
102
+ * sink. Extracted (and exported) so the frame/event/tee wiring is unit-testable
103
+ * without a live TUI or an MCP protocol handshake.
104
+ *
105
+ * @param driver the driver to ingest into (only _ingest is used).
106
+ * @param eventTee optional sink from createEventTee (null → no tee).
107
+ */
108
+ export declare function makeLineHandler(driver: Pick<Driver, "_ingest">, eventTee: ((event: LiveEvent) => void) | null): (line: string) => void;
98
109
  /**
99
110
  * Run the MCP harness driver over stdio with the OpenTUI spawn implementation
100
111
  * injected by the consumer.