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
@@ -1,6 +1,6 @@
1
1
  import { runPipeline } from "../pil/pipeline.js";
2
- import { getSessionLastTask, recordSessionLastTask, resolveCeiling } from "./scope-ceiling.js";
3
2
  import { logger } from "../utils/logger.js";
3
+ import { getSessionLastTask, recordSessionLastTask, resolveCeiling } from "./scope-ceiling.js";
4
4
  export async function* prepareTurnContext(deps, userMessage, _budgetOverride) {
5
5
  // PIL: enrich prompt before pushing to messages (D-01, D-03, D-04)
6
6
  // Promise.race timeout of 200ms is inside runPipeline — fail-open guaranteed
@@ -0,0 +1,26 @@
1
+ /**
2
+ * src/orchestrator/proactive-compact-detector.ts
3
+ *
4
+ * Detect when the agent (main or sub) proactively emits a /compact request
5
+ * in its assistant text, per the guidance we injected in pre-warn and past-budget
6
+ * reminders. Pattern (exact on its own line, as instructed):
7
+ * /compact <short instructions on what to focus on after compaction>
8
+ *
9
+ * When detected:
10
+ * - Extract the instructions (trimmed).
11
+ * - Caller can then:
12
+ * 1. Emit the __COMPACT__-style signal (or call deliberateCompact).
13
+ * 2. Inject a resume directive on the next turn: "Compact done. Resume previous task focusing on: <instructions>. Continue the work until complete."
14
+ * 3. Do NOT stop the task.
15
+ *
16
+ * Precision: only matches leading /compact at start of line (after optional whitespace),
17
+ * followed by optional instructions. Ignores mentions inside code blocks or prose.
18
+ * Uses only stdlib (no extra deps). 1-line core after regex compile.
19
+ */
20
+ export interface ProactiveCompactRequest {
21
+ detected: boolean;
22
+ instructions: string | null;
23
+ }
24
+ export declare function detectProactiveCompactRequest(text: string): ProactiveCompactRequest;
25
+ /** Build the exact resume text the agent should see after a proactive compact. */
26
+ export declare function buildCompactResumeMessage(instructions: string | null): string;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * src/orchestrator/proactive-compact-detector.ts
3
+ *
4
+ * Detect when the agent (main or sub) proactively emits a /compact request
5
+ * in its assistant text, per the guidance we injected in pre-warn and past-budget
6
+ * reminders. Pattern (exact on its own line, as instructed):
7
+ * /compact <short instructions on what to focus on after compaction>
8
+ *
9
+ * When detected:
10
+ * - Extract the instructions (trimmed).
11
+ * - Caller can then:
12
+ * 1. Emit the __COMPACT__-style signal (or call deliberateCompact).
13
+ * 2. Inject a resume directive on the next turn: "Compact done. Resume previous task focusing on: <instructions>. Continue the work until complete."
14
+ * 3. Do NOT stop the task.
15
+ *
16
+ * Precision: only matches leading /compact at start of line (after optional whitespace),
17
+ * followed by optional instructions. Ignores mentions inside code blocks or prose.
18
+ * Uses only stdlib (no extra deps). 1-line core after regex compile.
19
+ */
20
+ /** Matches "/compact ..." at start of a line (allows leading ws). Captures the rest. */
21
+ const PROACTIVE_RE = /^\s*\/compact\s*(.*)$/m;
22
+ export function detectProactiveCompactRequest(text) {
23
+ if (!text || typeof text !== "string")
24
+ return { detected: false, instructions: null };
25
+ const m = PROACTIVE_RE.exec(text);
26
+ if (!m)
27
+ return { detected: false, instructions: null };
28
+ const raw = (m[1] || "").trim();
29
+ return { detected: true, instructions: raw.length > 0 ? raw : null };
30
+ }
31
+ /** Build the exact resume text the agent should see after a proactive compact. */
32
+ export function buildCompactResumeMessage(instructions) {
33
+ const focus = instructions && instructions.trim().length > 0 ? instructions.trim() : "the original task";
34
+ return `Compact done. Resume previous task focusing on: ${focus}. Continue the work until complete. Do not stop.`;
35
+ }
36
+ //# sourceMappingURL=proactive-compact-detector.js.map
@@ -276,18 +276,14 @@ WORKFLOW:
276
276
  8. Run tests or builds with bash to confirm correctness
277
277
  9. Use search_web or search_x when you need up-to-date information
278
278
 
279
- DEFAULT DELEGATION POLICY:
280
- - Prefer the task tool by default for code review, code quality analysis, architecture research, root-cause investigation, bug triage, verification, or any request that likely needs reading multiple files before acting.
281
- - Prefer delegate for longer-running read-only exploration when you can keep making progress without blocking.
282
- - Use the explore sub-agent for read-only investigation, reviews, research, and "how does this work?" tasks.
283
- - Use the general sub-agent for delegated work that may need editing files, running commands, or producing a concrete implementation.
284
- - Use the verify sub-agent for sandbox-aware build, test, app boot, and smoke validation work.
285
- - Use the computer sub-agent for host desktop interaction workflows that need screenshots, clicks, typing, keypresses, or scrolling.
286
- - Use a matching custom sub-agent when the task fits one of the configured specializations.
287
- - Never use delegate for tasks that should edit files or make shell changes.
288
- - When a background delegation is running, do not wait idly and do not spam delegation_list(). Continue useful work.
289
- - Do not wait for the user to explicitly ask for a sub-agent when delegation would clearly help.
290
- - Skip delegation only when the task is trivial, single-file, or you already have the exact answer.
279
+ DEFAULT DELEGATION POLICY (critical for avoiding stalls/timeouts):
280
+ - For ANY research, exploration, review, architecture investigation, "how does X work", or read-only analysis you MUST use \`delegate\` (background) with the explore agent. This spawns a true non-blocking background job.
281
+ - Use \`task\` (foreground, blocking) ONLY for short, focused, low-round work that must return immediately into the current turn (e.g. quick edit + verify in <10-15 rounds). Using task for research WILL block the main session and frequently causes "model not responding" / stall timeouts on the provider.
282
+ - Prefer delegate + explore for anything that needs reading many files or long reasoning.
283
+ - Use general sub-agent only when edits/commands are required.
284
+ - Never use delegate for write/edit/shell changes.
285
+ - After launching a background delegate, continue useful work. Check results later with delegation_read / list only when needed.
286
+ - The model choosing task for long research is a common mistake that leads to timeouts — prefer delegate.
291
287
 
292
288
  WRITING A GOOD DELEGATION PROMPT (the sub-agent sees ONLY what you put in the prompt field — it does NOT share your context):
293
289
  - GOAL: state the one concrete question or outcome the sub must deliver.
@@ -296,9 +292,10 @@ WRITING A GOOD DELEGATION PROMPT (the sub-agent sees ONLY what you put in the pr
296
292
  - When fanning out several sub-agents in parallel, give each a NON-overlapping scope so their syntheses compose instead of duplicating.
297
293
 
298
294
  EXAMPLES:
299
- - "review this change" -> delegate to explore first
300
- - "research how auth works" -> delegate to explore first
301
- - "investigate why this test fails" -> delegate to explore first, then continue with findings
295
+ - "review this change" -> delegate (background explore) first
296
+ - "research how auth works" -> delegate (background explore) first
297
+ - "investigate why this test fails" -> delegate (background) to explore first, then continue with findings
298
+ - Long multi-file analysis or "review the sub-session spawn mechanism" -> ALWAYS delegate, never task
302
299
  - "refactor this module" -> delegate a focused part to general when helpful
303
300
  - "verify this feature locally" -> use verify
304
301
  - "open the host app and click through it" -> use computer
@@ -316,7 +313,7 @@ IMPORTANT:
316
313
  - Use write_file only for new files or when most of the file is changing. For very large files (>500 lines), split into multiple edit_file calls or write smaller chunks.
317
314
  - Use read_file instead of cat/head/tail for reading files.
318
315
  - When the user asks for an automated recurring or one-time run, use the schedule tools instead of only describing the setup.
319
- - If you have worked for a long time or hit a tool execution limit, DO NOT tell the user to move to a new session. Instead, advise them to run the \`/compact\` command to free up memory before continuing.
316
+ - Long tasks never need to stop for context. Two mechanisms keep you going: (1) the CLI AUTO-compacts and continues when you approach a tool-round limit, and (2) you can PROACTIVELY call the \`compact\` tool yourself the moment context feels heavy (e.g. after a read-heavy stretch) to shed old tool history before you hit any limit — it compacts, then you continue in the same turn. Older tool results stay rehydratable via ee_query "tool-artifact id=…". So: do NOT stop to tell the user to start a new session or run \`/compact\` themselves, and do NOT stop after calling \`compact\` keep working toward the goal. Only present your final answer when the task is genuinely finished.
320
317
  - Use the experience brain actively (it is how you stop repeating mistakes across sessions): at the start of an unfamiliar or risky step call ee_query to recall past lessons, and after acting on a recalled \`[id col]\` rate it with ee_feedback. The MOMENT you hit a mistake / error / dead-end and find the working fix, call ee_write to save the lesson (the pitfall AND the fix, concise and generalizable) — it is embedded immediately and recallable via ee_query in this and future sessions. Saving a hard-won fix is part of doing the work, not optional.
321
318
  - Commit your own work as you go (in any git repo, without being asked): use the git_commit tool — YOU write the commit message — the moment a cohesive, working chunk passes its checks, and after EACH step of a multi-step plan. Prefer several small, logically-scoped commits with clear messages (describe WHAT changed) over one catch-all at the end. git_commit stages only the files you wrote, excludes secrets/artifacts, and appends the "Coding by - Muonroi-CLI" attribution for you. (Any commit you instead make by hand via bash must still end with that attribution line, verbatim, on its own final line.)
322
319
  - After creating a recurring schedule, check the daemon status and start it with \`schedule_daemon_start\` if needed.
@@ -331,10 +328,13 @@ TOKEN BUDGET:
331
328
  WORKFLOW RULES:
332
329
  - RESEARCH FIRST: Always prioritize research before proposing edits. DeepSeek and other models have knowledge cutoffs; do not assume you know the exact codebase structure or latest external libraries. Use 'grep', 'lsp', and 'read_file' to search the local codebase. Use MCP tools (like web search or documentation readers) to research external knowledge, APIs, or libraries. Use 'delegate' for deep background research. Read before you write.
333
330
  - CLARIFY GRAY AREAS: If the user's request is ambiguous or leaves critical design decisions unspecified, STOP and ask the user for clarification before writing code. Do not hallucinate requirements.
331
+ - PRIORITIZE RECENT CONTEXT OVER HISTORY: When receiving short, ambiguous, or general continuation prompts from the user (such as "implement nhé", "tiếp tục", "go ahead", "tiếp tục nhé"), ALWAYS prioritize the most recently discussed design decisions, proposals, or topics from the immediate preceding turn(s). Do not regress or default back to earlier, older, or already completed tasks/topics that dominated the earlier parts of the session.
332
+ - BATCH ALL TOOL CALLS — HARD RULE: You MUST combine every independent tool call (read_file, grep, bash, etc.) you know you need into ONE parallel batch in your FIRST tool turn. Do NOT spread them across sequential rounds. Each extra LLM round re-sends the full ~17K system prompt + accumulated context, costing $0.003-$0.006 and inflating input 3-5x for NO new signal. If your first batch cannot cover all the reads/exploration needed, use delegate (explore) instead — do NOT scatter reads across 3+ rounds.
333
+ - MAX 2 LLM ROUND TRIPS per user message: round 1 = batch all reads/exploration; round 2 = follow-up only if a result from round 1 genuinely requires a NEW read you could not have anticipated. If you need round 3, you violated the batching rule — stop and use delegate (explore) instead.
334
+ - COST AWARENESS: Every tool round after round 1 burns $0.004-$0.006 for ZERO new signal — the system prompt is unchanged, only tool outputs grew. If you have 8+ tool calls, they MUST all go in round 1, not spread across 3-8 rounds.
334
335
 
335
336
  SELF-LIMIT:
336
337
  - When you've read 5+ files and haven't concluded, summarize findings and propose next step instead of reading more.
337
- - BATCH TOOL CALLS: You MUST combine and invoke independent tool calls in parallel (e.g. read multiple files, or run grep and read a file concurrently) in a SINGLE turn. Do not wait for the result of one tool call before invoking another if you already know both are needed. This dramatically reduces conversation turns, roundtrip latency, and input token accumulation.
338
338
  - BATCH BASH COMMANDS: Combine independent commands into ONE bash call (a; b; c) rather than sequential single calls — each separate call adds ~500 tokens of overhead and prevents prompt-cache reuse across the session.
339
339
  - Read only specific file sections (start_line/end_line) instead of whole files.
340
340
  - When a clear direction emerges from the first 2-3 tool results, act on it — don't over-investigate.`,
@@ -0,0 +1,39 @@
1
+ /**
2
+ * src/orchestrator/reactive-delegation.ts
3
+ *
4
+ * Reactive sub-session escalation — the deterministic complement to the upfront
5
+ * LLM router (`classifySubSessionAction`).
6
+ *
7
+ * Why this exists (measured, 2026-07-09): the upfront router mis-routes
8
+ * read-heavy work to DIRECT_ANSWER two ways —
9
+ * 1. Semantic blind spot: the live deepseek-v4-flash classifier answers the
10
+ * exact prompt "đánh giá phân tích council feature" with DIRECT_ANSWER
11
+ * ("no multi-step tool actions needed"), yet that turn ran 13 read_file
12
+ * calls. Analysis/review phrasing reads as "no tools" to the router.
13
+ * 2. Silent degrade: on a dead key / EE-down the classifier returns null and
14
+ * the caller falls back to DIRECT_ANSWER — so isolation never fires exactly
15
+ * when infra is degraded (reproduced on session 50aa048a6303).
16
+ *
17
+ * Both failures are a PREDICTION problem (guessing tool cost from the prompt).
18
+ * This module instead reacts to OBSERVED load: the per-turn cumulative
19
+ * tool-output byte count from the top-level cap (`wrapToolSetWithCap` state).
20
+ * Once a turn demonstrably burns through heavy tool output, the NEXT turn on
21
+ * the same session is escalated to an isolated sub-session regardless of what
22
+ * the router predicted — the mechanism self-corrects after the first heavy turn
23
+ * instead of relying on a fragile upfront guess. No regex/keyword heuristic
24
+ * (respects the no-regex classification rule) — the signal is real execution.
25
+ */
26
+ /**
27
+ * Cumulative tool-output chars a turn must exceed for the NEXT turn to escalate
28
+ * to a sub-session. Env-tunable via `MUONROI_REACTIVE_DELEGATE_CHARS`; set to 0
29
+ * to disable reactive escalation entirely.
30
+ */
31
+ export declare function getReactiveDelegationThresholdChars(): number;
32
+ /**
33
+ * True when the previous turn's observed tool-output load justifies escalating
34
+ * the current turn to an isolated sub-session. Threshold 0 disables it.
35
+ *
36
+ * Pure — the caller owns the "only override a DIRECT_ANSWER route" policy so
37
+ * ROTATE_SESSION (a deliberate topic switch) is never hijacked.
38
+ */
39
+ export declare function shouldReactivelyEscalate(prevTurnToolChars: number, threshold?: number): boolean;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * src/orchestrator/reactive-delegation.ts
3
+ *
4
+ * Reactive sub-session escalation — the deterministic complement to the upfront
5
+ * LLM router (`classifySubSessionAction`).
6
+ *
7
+ * Why this exists (measured, 2026-07-09): the upfront router mis-routes
8
+ * read-heavy work to DIRECT_ANSWER two ways —
9
+ * 1. Semantic blind spot: the live deepseek-v4-flash classifier answers the
10
+ * exact prompt "đánh giá phân tích council feature" with DIRECT_ANSWER
11
+ * ("no multi-step tool actions needed"), yet that turn ran 13 read_file
12
+ * calls. Analysis/review phrasing reads as "no tools" to the router.
13
+ * 2. Silent degrade: on a dead key / EE-down the classifier returns null and
14
+ * the caller falls back to DIRECT_ANSWER — so isolation never fires exactly
15
+ * when infra is degraded (reproduced on session 50aa048a6303).
16
+ *
17
+ * Both failures are a PREDICTION problem (guessing tool cost from the prompt).
18
+ * This module instead reacts to OBSERVED load: the per-turn cumulative
19
+ * tool-output byte count from the top-level cap (`wrapToolSetWithCap` state).
20
+ * Once a turn demonstrably burns through heavy tool output, the NEXT turn on
21
+ * the same session is escalated to an isolated sub-session regardless of what
22
+ * the router predicted — the mechanism self-corrects after the first heavy turn
23
+ * instead of relying on a fragile upfront guess. No regex/keyword heuristic
24
+ * (respects the no-regex classification rule) — the signal is real execution.
25
+ */
26
+ /** Default: ~120k chars of cumulative tool output ≈ ~30k tokens — clearly a
27
+ * multi-tool "heavy" turn, well above a 1–2 tool light turn. Matches the
28
+ * sub-agent cap's default budget so "heavy enough to cap" == "heavy enough to
29
+ * isolate next time". */
30
+ const DEFAULT_REACTIVE_DELEGATE_CHARS = 120_000;
31
+ /**
32
+ * Cumulative tool-output chars a turn must exceed for the NEXT turn to escalate
33
+ * to a sub-session. Env-tunable via `MUONROI_REACTIVE_DELEGATE_CHARS`; set to 0
34
+ * to disable reactive escalation entirely.
35
+ */
36
+ export function getReactiveDelegationThresholdChars() {
37
+ const raw = process.env.MUONROI_REACTIVE_DELEGATE_CHARS;
38
+ if (raw !== undefined && raw.trim() !== "") {
39
+ const n = Number(raw);
40
+ if (Number.isFinite(n) && n >= 0)
41
+ return n;
42
+ }
43
+ return DEFAULT_REACTIVE_DELEGATE_CHARS;
44
+ }
45
+ /**
46
+ * True when the previous turn's observed tool-output load justifies escalating
47
+ * the current turn to an isolated sub-session. Threshold 0 disables it.
48
+ *
49
+ * Pure — the caller owns the "only override a DIRECT_ANSWER route" policy so
50
+ * ROTATE_SESSION (a deliberate topic switch) is never hijacked.
51
+ */
52
+ export function shouldReactivelyEscalate(prevTurnToolChars, threshold = getReactiveDelegationThresholdChars()) {
53
+ if (!Number.isFinite(prevTurnToolChars) || prevTurnToolChars <= 0)
54
+ return false;
55
+ if (threshold <= 0)
56
+ return false;
57
+ return prevTurnToolChars >= threshold;
58
+ }
59
+ //# sourceMappingURL=reactive-delegation.js.map
@@ -7,7 +7,8 @@ export interface TransientCheck {
7
7
  *
8
8
  * Transient:
9
9
  * - Network-level errors: ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN,
10
- * "fetch failed", "Unable to connect", "socket hang up", "network"
10
+ * "fetch failed", "Unable to connect", "socket hang up", "network",
11
+ * "socket connection was closed unexpectedly" (Bun stream drop)
11
12
  * - HTTP 408 (request timeout), 425 (too early), 429 (rate limit), 5xx
12
13
  * - TypeError with "fetch failed" message (browser/bun/node fetch layer)
13
14
  * - AbortSignal.timeout firing (err.name === "TimeoutError")
@@ -1,11 +1,34 @@
1
1
  import { APICallError } from "@ai-sdk/provider";
2
+ import { isProviderThinkingDegraded, markProviderThinkingDegrade } from "../providers/strategies/thinking-mode.js";
2
3
  import { STALL_ABORT_REASON } from "./stall-watchdog.js";
4
+ /**
5
+ * Detect the generic, spec-undocumented param rejection from the z.ai GLM
6
+ * coding endpoint (HTTP 400 code 1210 "Invalid API parameter") and the
7
+ * opencode-go Console Go proxy (HTTP 400 invalid_request "Upstream request
8
+ * failed"). z.ai does NOT publish the exact constraint (verified 2026-07-02 vs
9
+ * docs.z.ai/api-reference/api-code — 1210 is an intentionally generic bucket),
10
+ * so no client transform can guarantee prevention. These are matched narrowly
11
+ * (400 + specific phrasing) so ordinary 400s stay non-transient.
12
+ */
13
+ function isProviderParamReject(err) {
14
+ const status = APICallError.isInstance(err)
15
+ ? err.statusCode
16
+ : (err?.statusCode ??
17
+ err?.status);
18
+ if (status !== 400)
19
+ return false;
20
+ const message = err instanceof Error ? err.message : String(err);
21
+ const body = APICallError.isInstance(err) && typeof err.responseBody === "string" ? err.responseBody : "";
22
+ const hay = `${message}\n${body}`;
23
+ return /invalid api parameter|upstream request failed|unexpected end of JSON input|code"?\s*:?\s*1210/i.test(hay);
24
+ }
3
25
  /**
4
26
  * Classifies a stream error as transient (safe to retry) or non-transient.
5
27
  *
6
28
  * Transient:
7
29
  * - Network-level errors: ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN,
8
- * "fetch failed", "Unable to connect", "socket hang up", "network"
30
+ * "fetch failed", "Unable to connect", "socket hang up", "network",
31
+ * "socket connection was closed unexpectedly" (Bun stream drop)
9
32
  * - HTTP 408 (request timeout), 425 (too early), 429 (rate limit), 5xx
10
33
  * - TypeError with "fetch failed" message (browser/bun/node fetch layer)
11
34
  * - AbortSignal.timeout firing (err.name === "TimeoutError")
@@ -38,6 +61,19 @@ export function classifyStreamError(err, depth = 0) {
38
61
  if (e.name === "TimeoutError") {
39
62
  return { transient: true, reason: "timeout-error" };
40
63
  }
64
+ // z.ai / opencode-go generic param reject (1210 / "Upstream request failed"):
65
+ // give EXACTLY ONE retry with a degraded-but-valid body. The first sighting
66
+ // latches thinking OFF (markProviderThinkingDegrade) so the rebuilt request
67
+ // (factory re-invoked by withStreamRetry) sends the validator-safe shape;
68
+ // parallel tool_calls are already split by the transform. If it STILL rejects
69
+ // after we've degraded, stop retrying — the cause is beyond our client fix.
70
+ if (isProviderParamReject(err)) {
71
+ if (isProviderThinkingDegraded()) {
72
+ return { transient: false, reason: "provider-param-reject-after-degrade" };
73
+ }
74
+ markProviderThinkingDegrade();
75
+ return { transient: true, reason: "provider-param-reject-degrade-retry" };
76
+ }
41
77
  // AI SDK APICallError with statusCode
42
78
  if (APICallError.isInstance(err)) {
43
79
  const status = err.statusCode;
@@ -61,6 +97,10 @@ export function classifyStreamError(err, depth = 0) {
61
97
  }
62
98
  }
63
99
  const message = typeof e.message === "string" ? e.message : "";
100
+ // Rate limits (including wrapped messages from proxies like "Console Go")
101
+ if (/rate limit|rate-limited|429|too many requests/i.test(message)) {
102
+ return { transient: true, reason: "rate-limit-message" };
103
+ }
64
104
  // Malformed function/tool name errors — non-transient (own handler elsewhere)
65
105
  if (/invalid.*function.*name|function.*name.*invalid|malformed.*tool|NoSuchTool/i.test(message)) {
66
106
  return { transient: false, reason: "malformed-tool-name" };
@@ -86,7 +126,11 @@ function isTransientStatusCode(code) {
86
126
  return code === 408 || code === 425 || code === 429 || (code >= 500 && code <= 599);
87
127
  }
88
128
  function isTransientMessage(message) {
89
- return /ECONNREFUSED|ETIMEDOUT|ECONNRESET|EAI_AGAIN|fetch failed|Unable to connect|network|socket hang up/i.test(message);
129
+ // "socket connection was closed unexpectedly" is Bun's fetch phrasing when a
130
+ // provider drops a streaming response mid-flight — a transient network drop,
131
+ // not a client error. Left unclassified it escapes as an unhandledRejection,
132
+ // which OpenTUI's handleError turns into an un-dismissable console overlay.
133
+ return /ECONNREFUSED|ETIMEDOUT|ECONNRESET|EAI_AGAIN|fetch failed|Unable to connect|network|socket hang up|socket connection was closed|socket.*closed unexpectedly/i.test(message);
90
134
  }
91
135
  /**
92
136
  * Parse Retry-After header value to milliseconds.
@@ -0,0 +1,45 @@
1
+ /**
2
+ * safety-intercept.ts — pure decision helpers for the tool-engine safety-block
3
+ * interceptor (tool-engine.ts). Extracted so the block-parse and the
4
+ * permission-mode policy are unit-testable in isolation from the giant
5
+ * executeToolEngine generator.
6
+ *
7
+ * Flow context: bash.execute / registry precheck emit a tool result whose text
8
+ * starts with `BLOCKED (<kind>): <reason>`. The tool-engine joins output+error,
9
+ * parses it here, and decides whether to auto-block, auto-allow (yolo), or show
10
+ * the safety-override askcard via deps.askSafetyOverride.
11
+ */
12
+ import type { PermissionMode } from "../utils/permission-mode.js";
13
+ import type { SafetyBlockKind } from "./safety-askcard.js";
14
+ export interface ParsedSafetyBlock {
15
+ kind: SafetyBlockKind;
16
+ reason: string;
17
+ }
18
+ /**
19
+ * Parse a joined tool-result text into a safety block, or null when the text
20
+ * is not a BLOCKED marker.
21
+ *
22
+ * Tolerant of leading whitespace: when bash.execute returns `{error: "BLOCKED
23
+ * (...)"}` with no `output`, the joined text is the raw marker — but a result
24
+ * shape that carries an empty-string `output` produces a leading "\n" before
25
+ * the marker, which an anchored `/^BLOCKED/` would miss and silently drop the
26
+ * askcard (hard-stop with no prompt). Stripping leading whitespace first makes
27
+ * the parse robust to both shapes while still requiring the marker at the head
28
+ * of the (trimmed) text — so a command whose normal output merely mentions
29
+ * "BLOCKED (...)" mid-stream is not mistaken for a real block.
30
+ */
31
+ export declare function parseSafetyBlock(outputText: string): ParsedSafetyBlock | null;
32
+ /**
33
+ * Whether a parsed block should be auto-allowed (allow-once) without showing
34
+ * the askcard, given the active permission mode.
35
+ *
36
+ * Policy (confirmed with the user):
37
+ * - `yolo` auto-allows lower-severity blocks (`git-safety`, `dangerous`) so
38
+ * the "don't ask me" mode actually stops asking for routine guardrails.
39
+ * - `catastrophic` ALWAYS shows the askcard, even in yolo — an irreversible
40
+ * destroyer (rm -rf /dev, mkfs, sudo …) must never run unattended.
41
+ * - `empty-bash` is handled separately (auto-block, no card) and never
42
+ * reaches this policy.
43
+ * - `safe` / `auto-edit` always show the card for any real block.
44
+ */
45
+ export declare function shouldAutoAllowYolo(kind: SafetyBlockKind, mode: PermissionMode): boolean;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * safety-intercept.ts — pure decision helpers for the tool-engine safety-block
3
+ * interceptor (tool-engine.ts). Extracted so the block-parse and the
4
+ * permission-mode policy are unit-testable in isolation from the giant
5
+ * executeToolEngine generator.
6
+ *
7
+ * Flow context: bash.execute / registry precheck emit a tool result whose text
8
+ * starts with `BLOCKED (<kind>): <reason>`. The tool-engine joins output+error,
9
+ * parses it here, and decides whether to auto-block, auto-allow (yolo), or show
10
+ * the safety-override askcard via deps.askSafetyOverride.
11
+ */
12
+ /**
13
+ * Parse a joined tool-result text into a safety block, or null when the text
14
+ * is not a BLOCKED marker.
15
+ *
16
+ * Tolerant of leading whitespace: when bash.execute returns `{error: "BLOCKED
17
+ * (...)"}` with no `output`, the joined text is the raw marker — but a result
18
+ * shape that carries an empty-string `output` produces a leading "\n" before
19
+ * the marker, which an anchored `/^BLOCKED/` would miss and silently drop the
20
+ * askcard (hard-stop with no prompt). Stripping leading whitespace first makes
21
+ * the parse robust to both shapes while still requiring the marker at the head
22
+ * of the (trimmed) text — so a command whose normal output merely mentions
23
+ * "BLOCKED (...)" mid-stream is not mistaken for a real block.
24
+ */
25
+ export function parseSafetyBlock(outputText) {
26
+ if (typeof outputText !== "string")
27
+ return null;
28
+ const match = outputText.replace(/^\s+/, "").match(/^BLOCKED \(([^)]+)\):\s*(.*)/);
29
+ if (!match)
30
+ return null;
31
+ return { kind: match[1], reason: match[2] ?? "" };
32
+ }
33
+ /**
34
+ * Whether a parsed block should be auto-allowed (allow-once) without showing
35
+ * the askcard, given the active permission mode.
36
+ *
37
+ * Policy (confirmed with the user):
38
+ * - `yolo` auto-allows lower-severity blocks (`git-safety`, `dangerous`) so
39
+ * the "don't ask me" mode actually stops asking for routine guardrails.
40
+ * - `catastrophic` ALWAYS shows the askcard, even in yolo — an irreversible
41
+ * destroyer (rm -rf /dev, mkfs, sudo …) must never run unattended.
42
+ * - `empty-bash` is handled separately (auto-block, no card) and never
43
+ * reaches this policy.
44
+ * - `safe` / `auto-edit` always show the card for any real block.
45
+ */
46
+ export function shouldAutoAllowYolo(kind, mode) {
47
+ if (mode !== "yolo")
48
+ return false;
49
+ if (kind === "catastrophic")
50
+ return false;
51
+ if (kind === "empty-bash")
52
+ return false;
53
+ return true;
54
+ }
55
+ //# sourceMappingURL=safety-intercept.js.map
@@ -229,7 +229,7 @@ export function buildCheckpointReminder(iteration, hasEECheckpoint) {
229
229
  * compared `stripped.length` (a message count, ~tens) against a char-scaled
230
230
  * threshold (~156000), so the warning could never fire — session 2b7a10219499.
231
231
  */
232
- export function shouldPreWarnCompaction(promptChars, thresholdChars, ratio = 0.78) {
232
+ export function shouldPreWarnCompaction(promptChars, thresholdChars, ratio = 0.6) {
233
233
  if (thresholdChars <= 0 || promptChars <= 0)
234
234
  return false;
235
235
  return promptChars >= Math.floor(thresholdChars * ratio);
@@ -27,6 +27,7 @@ export interface ElisionRecord {
27
27
  chars: number;
28
28
  /** prepareStep step number at which it was elided. */
29
29
  step: number;
30
+ summary?: string;
30
31
  }
31
32
  export interface SessionExperience {
32
33
  compactions: number;
@@ -40,7 +41,7 @@ export interface SessionExperience {
40
41
  /** Record that B3/B4 compaction actually elided something at `step`. */
41
42
  export declare function recordCompaction(step: number): void;
42
43
  /** Record a single tool output the compactor rewrote into a stub. */
43
- export declare function recordElision(toolCallId: string, toolName: string, chars: number, step: number): void;
44
+ export declare function recordElision(toolCallId: string, toolName: string, chars: number, step: number, summary?: string): void;
44
45
  /**
45
46
  * Record an ee_query rehydrate of an elided artifact, tagged by where it came
46
47
  * from. `unavailable` means the agent asked for an artifact that was neither in
@@ -38,7 +38,7 @@ export function recordCompaction(step) {
38
38
  state.lastCompactionStep = Number.isFinite(step) ? step : state.lastCompactionStep;
39
39
  }
40
40
  /** Record a single tool output the compactor rewrote into a stub. */
41
- export function recordElision(toolCallId, toolName, chars, step) {
41
+ export function recordElision(toolCallId, toolName, chars, step, summary) {
42
42
  if (!toolCallId)
43
43
  return;
44
44
  state.elisions.push({
@@ -46,6 +46,7 @@ export function recordElision(toolCallId, toolName, chars, step) {
46
46
  toolName: toolName || "",
47
47
  chars: Number.isFinite(chars) && chars > 0 ? Math.floor(chars) : 0,
48
48
  step: Number.isFinite(step) ? step : 0,
49
+ summary,
49
50
  });
50
51
  // FIFO trim — keep the most recent MAX_ELISIONS.
51
52
  if (state.elisions.length > MAX_ELISIONS) {
@@ -0,0 +1,5 @@
1
+ export declare function shouldRunGate(pilCtx: {
2
+ intentKind?: string | null;
3
+ resumeDigest?: string | null;
4
+ activeRunId?: string | null;
5
+ }, readPhase: () => string | null): boolean;
@@ -0,0 +1,18 @@
1
+ // Keep the gate off pure chitchat, but ON for a resumed heavy task the classifier
2
+ // mislabels as chitchat (continuation phrases — preprocessor.ts:118-134). Reading
3
+ // STATE.md phase is the resume signal (execute phase = an active run).
4
+ export function shouldRunGate(pilCtx, readPhase) {
5
+ if (pilCtx.intentKind !== "chitchat")
6
+ return true;
7
+ if (pilCtx.resumeDigest || pilCtx.activeRunId)
8
+ return true;
9
+ try {
10
+ return readPhase() === "execute";
11
+ }
12
+ catch (err) {
13
+ // Missing/corrupt .planning is the normal "no active run" case, not an error — treat as no run.
14
+ console.error(`[pil-gate] shouldRunGate readPhase failed (treating as no active run): ${err.message}`);
15
+ return false;
16
+ }
17
+ }
18
+ //# sourceMappingURL=should-run-gate.js.map
@@ -21,13 +21,34 @@
21
21
  export interface StallWatchdog {
22
22
  /** Combine this into the streamText abortSignal. */
23
23
  readonly signal: AbortSignal;
24
- /** Call on every received stream chunk to reset the stall timer. */
24
+ /** Call on every received stream chunk to reset the any-activity stall timer. */
25
25
  pet(): void;
26
- /** Stop the timer (call when the stream completes or errors). Idempotent. */
26
+ /**
27
+ * Call ONLY on real forward-progress chunks (a text-delta or a tool-call) to
28
+ * reset the no-forward-progress timer. No-op when the watchdog was created
29
+ * without a progressTimeoutMs. This is what makes the guard catch a reasoning
30
+ * model stuck in an endless chain-of-thought: `pet()` (called on EVERY chunk,
31
+ * including reasoning-delta) keeps the any-activity timer alive, but the
32
+ * progress timer only survives if actual output flows.
33
+ */
34
+ petProgress(): void;
35
+ /** Stop the timers (call when the stream completes or errors). Idempotent. */
27
36
  dispose(): void;
28
37
  /** True iff the watchdog aborted the stream because of a stall. */
29
38
  fired(): boolean;
30
39
  }
40
+ /** Options for the second (no-forward-progress) timer of a stall watchdog. */
41
+ export interface StallWatchdogProgressOpts {
42
+ /**
43
+ * If > 0, arm a SECOND timer that is reset only by petProgress() (real
44
+ * output), not by pet() (any chunk). Aborts the same signal when no forward
45
+ * progress happens for this long — catching runaway reasoning that keeps the
46
+ * any-activity timer alive with reasoning-delta chunks. <= 0 disables it.
47
+ */
48
+ progressTimeoutMs: number;
49
+ /** Called when the no-forward-progress timer fires (before abort). */
50
+ onProgressFire?: () => void;
51
+ }
31
52
  export declare const STALL_ABORT_REASON = "provider-stall";
32
53
  /** User-facing message surfaced when the stall watchdog fires. */
33
54
  export declare const STALL_ERROR_MESSAGE: string;
@@ -109,4 +130,4 @@ export declare function shouldContinueAfterMidLoopStall(s: MidLoopStallState): b
109
130
  * (1-based): 500 → 1000 → 2000 → 4000 → 4000.
110
131
  */
111
132
  export declare function stallRepromptBackoffMs(attempt: number): number;
112
- export declare function createStallWatchdog(timeoutMs: number, onFire?: () => void): StallWatchdog;
133
+ export declare function createStallWatchdog(timeoutMs: number, onFire?: () => void, progressOpts?: StallWatchdogProgressOpts): StallWatchdog;