muonroi-cli 1.8.4 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (562) hide show
  1. package/LICENSE +17 -5
  2. package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
  3. package/dist/packages/agent-harness-core/src/driver.js +46 -0
  4. package/dist/packages/agent-harness-core/src/event-filter.js +11 -0
  5. package/dist/packages/agent-harness-core/src/event-redact.js +7 -0
  6. package/dist/packages/agent-harness-core/src/event-tee.d.ts +64 -0
  7. package/dist/packages/agent-harness-core/src/event-tee.js +104 -0
  8. package/dist/packages/agent-harness-core/src/mcp-server.d.ts +25 -0
  9. package/dist/packages/agent-harness-core/src/mcp-server.js +169 -21
  10. package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
  11. package/dist/packages/agent-harness-core/src/protocol.d.ts +90 -4
  12. package/dist/packages/agent-harness-core/src/protocol.js +15 -0
  13. package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
  14. package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
  15. package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
  16. package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
  17. package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
  18. package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
  19. package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
  20. package/dist/packages/agent-harness-opentui/src/install.js +10 -0
  21. package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
  22. package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
  23. package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
  24. package/dist/src/agent-harness/mock-model.d.ts +38 -0
  25. package/dist/src/agent-harness/mock-model.js +69 -3
  26. package/dist/src/agent-harness/test-spawn.js +31 -0
  27. package/dist/src/chat/chat-keychain.d.ts +7 -12
  28. package/dist/src/chat/chat-keychain.js +19 -86
  29. package/dist/src/cli/config/screen-providers.js +1 -1
  30. package/dist/src/cli/cost-forensics.d.ts +10 -0
  31. package/dist/src/cli/cost-forensics.js +18 -3
  32. package/dist/src/cli/keys-bundle.d.ts +1 -1
  33. package/dist/src/cli/keys-bundle.js +1 -1
  34. package/dist/src/cli/keys.d.ts +10 -47
  35. package/dist/src/cli/keys.js +31 -399
  36. package/dist/src/council/clarifier.d.ts +31 -3
  37. package/dist/src/council/clarifier.js +220 -32
  38. package/dist/src/council/context.js +49 -15
  39. package/dist/src/council/debate-checkpoint.d.ts +129 -0
  40. package/dist/src/council/debate-checkpoint.js +176 -0
  41. package/dist/src/council/debate-planner.js +54 -5
  42. package/dist/src/council/debate-summary.d.ts +25 -0
  43. package/dist/src/council/debate-summary.js +85 -0
  44. package/dist/src/council/debate.d.ts +169 -2
  45. package/dist/src/council/debate.js +1265 -135
  46. package/dist/src/council/index.d.ts +108 -1
  47. package/dist/src/council/index.js +670 -197
  48. package/dist/src/council/leader.d.ts +26 -0
  49. package/dist/src/council/leader.js +150 -9
  50. package/dist/src/council/llm.d.ts +94 -0
  51. package/dist/src/council/llm.js +348 -55
  52. package/dist/src/council/panel-select.d.ts +30 -0
  53. package/dist/src/council/panel-select.js +82 -0
  54. package/dist/src/council/planner.js +40 -0
  55. package/dist/src/council/preflight.d.ts +17 -0
  56. package/dist/src/council/preflight.js +50 -2
  57. package/dist/src/council/prompts.d.ts +39 -4
  58. package/dist/src/council/prompts.js +256 -69
  59. package/dist/src/council/stance-recall.d.ts +42 -0
  60. package/dist/src/council/stance-recall.js +57 -0
  61. package/dist/src/council/strip-think.d.ts +17 -0
  62. package/dist/src/council/strip-think.js +33 -0
  63. package/dist/src/council/types.d.ts +138 -0
  64. package/dist/src/ee/artifact-cache.d.ts +16 -0
  65. package/dist/src/ee/artifact-cache.js +32 -0
  66. package/dist/src/ee/auth.d.ts +20 -0
  67. package/dist/src/ee/auth.js +54 -2
  68. package/dist/src/ee/bridge.d.ts +10 -0
  69. package/dist/src/ee/bridge.js +58 -0
  70. package/dist/src/ee/client.js +109 -21
  71. package/dist/src/ee/ee-onboarding.js +6 -26
  72. package/dist/src/ee/export-transcripts.d.ts +1 -0
  73. package/dist/src/ee/export-transcripts.js +8 -10
  74. package/dist/src/ee/extract-session.js +29 -0
  75. package/dist/src/ee/extract-style.d.ts +58 -0
  76. package/dist/src/ee/extract-style.js +270 -0
  77. package/dist/src/ee/recall-ledger.d.ts +9 -0
  78. package/dist/src/ee/recall-ledger.js +3 -0
  79. package/dist/src/ee/scope.d.ts +1 -0
  80. package/dist/src/ee/scope.js +26 -1
  81. package/dist/src/ee/search.d.ts +7 -0
  82. package/dist/src/ee/search.js +24 -0
  83. package/dist/src/ee/transcript-emit.js +2 -0
  84. package/dist/src/ee/types.d.ts +22 -0
  85. package/dist/src/ee/who-am-i-brain.d.ts +35 -0
  86. package/dist/src/ee/who-am-i-brain.js +220 -0
  87. package/dist/src/ee/who-am-i.d.ts +10 -3
  88. package/dist/src/ee/who-am-i.js +12 -0
  89. package/dist/src/ee/workflow-event.d.ts +48 -0
  90. package/dist/src/ee/workflow-event.js +81 -0
  91. package/dist/src/flow/compaction/compress.d.ts +3 -3
  92. package/dist/src/flow/compaction/compress.js +58 -8
  93. package/dist/src/flow/compaction/extract.d.ts +4 -7
  94. package/dist/src/flow/compaction/extract.js +50 -10
  95. package/dist/src/flow/compaction/index.d.ts +14 -1
  96. package/dist/src/flow/compaction/index.js +96 -3
  97. package/dist/src/flow/compaction/input-guard.d.ts +24 -0
  98. package/dist/src/flow/compaction/input-guard.js +43 -0
  99. package/dist/src/flow/compaction/progress.d.ts +35 -0
  100. package/dist/src/flow/compaction/progress.js +35 -0
  101. package/dist/src/flow/fold-planning.d.ts +36 -0
  102. package/dist/src/flow/fold-planning.js +83 -0
  103. package/dist/src/flow/hierarchy.d.ts +146 -0
  104. package/dist/src/flow/hierarchy.js +427 -0
  105. package/dist/src/flow/index.d.ts +1 -0
  106. package/dist/src/flow/index.js +2 -0
  107. package/dist/src/flow/run-artifacts.d.ts +102 -0
  108. package/dist/src/flow/run-artifacts.js +208 -0
  109. package/dist/src/generated/version.d.ts +1 -1
  110. package/dist/src/generated/version.js +1 -1
  111. package/dist/src/gsd/assessment-schema.d.ts +44 -0
  112. package/dist/src/gsd/assessment-schema.js +134 -0
  113. package/dist/src/gsd/capability-registry.d.ts +45 -0
  114. package/dist/src/gsd/capability-registry.js +337 -0
  115. package/dist/src/gsd/complexity-assessor.d.ts +39 -0
  116. package/dist/src/gsd/complexity-assessor.js +152 -0
  117. package/dist/src/gsd/config-bridge.d.ts +7 -0
  118. package/dist/src/gsd/config-bridge.js +114 -0
  119. package/dist/src/gsd/config-loader.d.ts +27 -0
  120. package/dist/src/gsd/config-loader.js +50 -0
  121. package/dist/src/gsd/council-context.d.ts +44 -0
  122. package/dist/src/gsd/council-context.js +114 -0
  123. package/dist/src/gsd/ee-closure.d.ts +28 -0
  124. package/dist/src/gsd/ee-closure.js +49 -0
  125. package/dist/src/gsd/flags.d.ts +66 -0
  126. package/dist/src/gsd/flags.js +102 -0
  127. package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
  128. package/dist/src/gsd/gsd-dispatch.js +131 -0
  129. package/dist/src/gsd/gsd-runtime.d.ts +22 -0
  130. package/dist/src/gsd/gsd-runtime.js +37 -0
  131. package/dist/src/gsd/host-adapter.d.ts +11 -0
  132. package/dist/src/gsd/host-adapter.js +29 -0
  133. package/dist/src/gsd/index.d.ts +24 -1
  134. package/dist/src/gsd/index.js +27 -0
  135. package/dist/src/gsd/loop-host-contract.d.ts +21 -0
  136. package/dist/src/gsd/loop-host-contract.js +39 -0
  137. package/dist/src/gsd/loop-host.d.ts +69 -0
  138. package/dist/src/gsd/loop-host.js +245 -0
  139. package/dist/src/gsd/loop-resolver.d.ts +36 -0
  140. package/dist/src/gsd/loop-resolver.js +79 -0
  141. package/dist/src/gsd/model-tier.d.ts +13 -0
  142. package/dist/src/gsd/model-tier.js +45 -0
  143. package/dist/src/gsd/mutation-gate.d.ts +16 -0
  144. package/dist/src/gsd/mutation-gate.js +41 -0
  145. package/dist/src/gsd/native-roadmap.d.ts +89 -0
  146. package/dist/src/gsd/native-roadmap.js +343 -0
  147. package/dist/src/gsd/native-state.d.ts +47 -0
  148. package/dist/src/gsd/native-state.js +220 -0
  149. package/dist/src/gsd/paths.d.ts +23 -0
  150. package/dist/src/gsd/paths.js +66 -0
  151. package/dist/src/gsd/phase-dag.d.ts +12 -0
  152. package/dist/src/gsd/phase-dag.js +94 -0
  153. package/dist/src/gsd/phase-sync.d.ts +42 -0
  154. package/dist/src/gsd/phase-sync.js +321 -0
  155. package/dist/src/gsd/pil-gate-context.d.ts +13 -0
  156. package/dist/src/gsd/pil-gate-context.js +64 -0
  157. package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
  158. package/dist/src/gsd/pil-gate-critic.js +74 -0
  159. package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
  160. package/dist/src/gsd/plan-council-prompts.js +79 -0
  161. package/dist/src/gsd/plan-council.d.ts +44 -0
  162. package/dist/src/gsd/plan-council.js +283 -0
  163. package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
  164. package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
  165. package/dist/src/gsd/product-workspace.d.ts +13 -0
  166. package/dist/src/gsd/product-workspace.js +124 -0
  167. package/dist/src/gsd/ship-bridge.d.ts +25 -0
  168. package/dist/src/gsd/ship-bridge.js +65 -0
  169. package/dist/src/gsd/state-document.d.ts +40 -0
  170. package/dist/src/gsd/state-document.js +163 -0
  171. package/dist/src/gsd/verdict-schema.d.ts +39 -0
  172. package/dist/src/gsd/verdict-schema.js +144 -0
  173. package/dist/src/gsd/verify-context.d.ts +22 -0
  174. package/dist/src/gsd/verify-context.js +27 -0
  175. package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
  176. package/dist/src/gsd/verify-council-prompts.js +85 -0
  177. package/dist/src/gsd/verify-council.d.ts +25 -0
  178. package/dist/src/gsd/verify-council.js +119 -0
  179. package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
  180. package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
  181. package/dist/src/gsd/workflow-engine.d.ts +60 -0
  182. package/dist/src/gsd/workflow-engine.js +207 -0
  183. package/dist/src/gsd/workflow-tools.d.ts +13 -0
  184. package/dist/src/gsd/workflow-tools.js +277 -0
  185. package/dist/src/headless/council-answers.js +4 -0
  186. package/dist/src/hooks/index.js +1 -1
  187. package/dist/src/index.js +172 -270
  188. package/dist/src/lsp/builtins.js +3 -1
  189. package/dist/src/lsp/manager.d.ts +5 -1
  190. package/dist/src/lsp/manager.js +249 -3
  191. package/dist/src/lsp/npm-cache.d.ts +11 -1
  192. package/dist/src/lsp/npm-cache.js +17 -1
  193. package/dist/src/lsp/runtime.d.ts +6 -1
  194. package/dist/src/lsp/runtime.js +17 -1
  195. package/dist/src/lsp/types.d.ts +83 -1
  196. package/dist/src/lsp/types.js +10 -0
  197. package/dist/src/maintain/pr-builder.js +23 -13
  198. package/dist/src/mcp/auto-setup.js +57 -32
  199. package/dist/src/mcp/client-pool.js +44 -16
  200. package/dist/src/mcp/lsp-tools.d.ts +5 -1
  201. package/dist/src/mcp/lsp-tools.js +93 -2
  202. package/dist/src/mcp/mcp-keychain.d.ts +3 -5
  203. package/dist/src/mcp/mcp-keychain.js +9 -49
  204. package/dist/src/mcp/research-onboarding.js +8 -7
  205. package/dist/src/mcp/runtime.js +34 -2
  206. package/dist/src/mcp/setup-guide-text.d.ts +1 -1
  207. package/dist/src/mcp/setup-guide-text.js +22 -2
  208. package/dist/src/mcp/tools-server.d.ts +10 -0
  209. package/dist/src/mcp/tools-server.js +10 -2
  210. package/dist/src/models/catalog-client.d.ts +87 -0
  211. package/dist/src/models/catalog-client.js +105 -38
  212. package/dist/src/models/catalog.json +528 -265
  213. package/dist/src/models/registry.d.ts +22 -7
  214. package/dist/src/models/registry.js +73 -10
  215. package/dist/src/ops/doctor.js +1 -1
  216. package/dist/src/orchestrator/ask-user.d.ts +61 -0
  217. package/dist/src/orchestrator/ask-user.js +65 -0
  218. package/dist/src/orchestrator/auto-commit.js +1 -1
  219. package/dist/src/orchestrator/batch-turn-runner.js +2 -2
  220. package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
  221. package/dist/src/orchestrator/cache-prefix.js +83 -0
  222. package/dist/src/orchestrator/compact-request.d.ts +32 -0
  223. package/dist/src/orchestrator/compact-request.js +41 -0
  224. package/dist/src/orchestrator/compaction.d.ts +12 -3
  225. package/dist/src/orchestrator/compaction.js +35 -15
  226. package/dist/src/orchestrator/council-manager.d.ts +12 -3
  227. package/dist/src/orchestrator/council-manager.js +74 -32
  228. package/dist/src/orchestrator/council-request.d.ts +49 -0
  229. package/dist/src/orchestrator/council-request.js +62 -0
  230. package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
  231. package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
  232. package/dist/src/orchestrator/error-utils.d.ts +29 -0
  233. package/dist/src/orchestrator/error-utils.js +132 -24
  234. package/dist/src/orchestrator/grounding-check.js +39 -1
  235. package/dist/src/orchestrator/interactive-pause.d.ts +26 -0
  236. package/dist/src/orchestrator/interactive-pause.js +36 -0
  237. package/dist/src/orchestrator/message-processor.d.ts +4 -0
  238. package/dist/src/orchestrator/message-processor.js +268 -41
  239. package/dist/src/orchestrator/orchestrator.d.ts +64 -3
  240. package/dist/src/orchestrator/orchestrator.js +823 -120
  241. package/dist/src/orchestrator/preprocessor.js +3 -3
  242. package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
  243. package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
  244. package/dist/src/orchestrator/prompts.js +17 -17
  245. package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
  246. package/dist/src/orchestrator/reactive-delegation.js +59 -0
  247. package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
  248. package/dist/src/orchestrator/retry-classifier.js +46 -2
  249. package/dist/src/orchestrator/safety-askcard.d.ts +1 -1
  250. package/dist/src/orchestrator/safety-askcard.js +5 -2
  251. package/dist/src/orchestrator/safety-intercept.d.ts +50 -0
  252. package/dist/src/orchestrator/safety-intercept.js +62 -0
  253. package/dist/src/orchestrator/scope-reminder.js +1 -1
  254. package/dist/src/orchestrator/session-experience.d.ts +2 -1
  255. package/dist/src/orchestrator/session-experience.js +2 -1
  256. package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
  257. package/dist/src/orchestrator/should-run-gate.js +18 -0
  258. package/dist/src/orchestrator/stall-watchdog.d.ts +31 -3
  259. package/dist/src/orchestrator/stall-watchdog.js +65 -10
  260. package/dist/src/orchestrator/stream-runner.d.ts +13 -3
  261. package/dist/src/orchestrator/stream-runner.js +115 -49
  262. package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
  263. package/dist/src/orchestrator/sub-agent-cap.js +16 -1
  264. package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
  265. package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
  266. package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
  267. package/dist/src/orchestrator/subagent-compactor.js +126 -15
  268. package/dist/src/orchestrator/tool-engine.d.ts +41 -0
  269. package/dist/src/orchestrator/tool-engine.js +846 -66
  270. package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
  271. package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
  272. package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
  273. package/dist/src/orchestrator/turn-watchdog.d.ts +44 -0
  274. package/dist/src/orchestrator/turn-watchdog.js +84 -0
  275. package/dist/src/pil/agent-operating-contract.d.ts +1 -1
  276. package/dist/src/pil/agent-operating-contract.js +6 -4
  277. package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
  278. package/dist/src/pil/cheap-model-playbook.js +5 -1
  279. package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
  280. package/dist/src/pil/cheap-model-workbooks.js +1 -1
  281. package/dist/src/pil/discovery-types.d.ts +1 -0
  282. package/dist/src/pil/discovery.d.ts +1 -1
  283. package/dist/src/pil/discovery.js +18 -13
  284. package/dist/src/pil/layer1-intent.d.ts +18 -6
  285. package/dist/src/pil/layer1-intent.js +66 -757
  286. package/dist/src/pil/layer15-context-scan.js +15 -1
  287. package/dist/src/pil/layer1_5-complexity-size.d.ts +7 -0
  288. package/dist/src/pil/layer1_5-complexity-size.js +31 -5
  289. package/dist/src/pil/layer3-ee-injection.js +23 -8
  290. package/dist/src/pil/layer4-gsd.js +69 -16
  291. package/dist/src/pil/layer5-context.js +7 -3
  292. package/dist/src/pil/layer6-output.d.ts +23 -0
  293. package/dist/src/pil/layer6-output.js +5 -1
  294. package/dist/src/pil/llm-classify.d.ts +111 -5
  295. package/dist/src/pil/llm-classify.js +421 -189
  296. package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
  297. package/dist/src/pil/native-capabilities-workbook.js +8 -0
  298. package/dist/src/pil/pipeline.js +36 -2
  299. package/dist/src/pil/repo-grounding-probe.d.ts +15 -0
  300. package/dist/src/pil/repo-grounding-probe.js +136 -0
  301. package/dist/src/pil/repo-structure-hints.d.ts +7 -0
  302. package/dist/src/pil/repo-structure-hints.js +45 -0
  303. package/dist/src/pil/response-tools.js +5 -3
  304. package/dist/src/pil/schema.d.ts +1 -0
  305. package/dist/src/pil/schema.js +2 -0
  306. package/dist/src/pil/types.d.ts +18 -0
  307. package/dist/src/playbook/directives.d.ts +4 -0
  308. package/dist/src/playbook/directives.js +17 -5
  309. package/dist/src/product-loop/artifact-io.js +4 -0
  310. package/dist/src/product-loop/backlog-builder.d.ts +14 -1
  311. package/dist/src/product-loop/backlog-builder.js +30 -6
  312. package/dist/src/product-loop/criteria-seed.d.ts +51 -0
  313. package/dist/src/product-loop/criteria-seed.js +200 -0
  314. package/dist/src/product-loop/discovery-context-format.js +3 -1
  315. package/dist/src/product-loop/discovery-ecosystem.js +4 -1
  316. package/dist/src/product-loop/discovery-interview.d.ts +9 -0
  317. package/dist/src/product-loop/discovery-interview.js +60 -12
  318. package/dist/src/product-loop/discovery-recommender.js +2 -1
  319. package/dist/src/product-loop/discovery-schema.js +19 -2
  320. package/dist/src/product-loop/discovery-triage.d.ts +23 -0
  321. package/dist/src/product-loop/discovery-triage.js +109 -0
  322. package/dist/src/product-loop/gather.js +150 -2
  323. package/dist/src/product-loop/ideal-trace.d.ts +7 -0
  324. package/dist/src/product-loop/ideal-trace.js +64 -0
  325. package/dist/src/product-loop/index.d.ts +13 -1
  326. package/dist/src/product-loop/index.js +340 -52
  327. package/dist/src/product-loop/loop-driver.d.ts +7 -0
  328. package/dist/src/product-loop/loop-driver.js +330 -106
  329. package/dist/src/product-loop/phase-plan.d.ts +21 -0
  330. package/dist/src/product-loop/phase-plan.js +81 -6
  331. package/dist/src/product-loop/phase-rituals.d.ts +3 -0
  332. package/dist/src/product-loop/phase-rituals.js +8 -3
  333. package/dist/src/product-loop/phase-runner.js +39 -12
  334. package/dist/src/product-loop/plan-adherence-review.d.ts +26 -0
  335. package/dist/src/product-loop/plan-adherence-review.js +144 -0
  336. package/dist/src/product-loop/sprint-runner.d.ts +173 -0
  337. package/dist/src/product-loop/sprint-runner.js +863 -19
  338. package/dist/src/product-loop/types.d.ts +61 -5
  339. package/dist/src/providers/adapter.d.ts +1 -1
  340. package/dist/src/providers/adapter.js +3 -4
  341. package/dist/src/providers/anthropic.d.ts +9 -8
  342. package/dist/src/providers/anthropic.js +13 -47
  343. package/dist/src/providers/auth/browser-flow.d.ts +1 -1
  344. package/dist/src/providers/auth/browser-flow.js +1 -1
  345. package/dist/src/providers/auth/grok-oauth.d.ts +1 -0
  346. package/dist/src/providers/auth/grok-oauth.js +30 -5
  347. package/dist/src/providers/auth/openai-oauth.d.ts +1 -0
  348. package/dist/src/providers/auth/openai-oauth.js +15 -1
  349. package/dist/src/providers/auth/registry.js +0 -34
  350. package/dist/src/providers/auth/token-store.d.ts +9 -9
  351. package/dist/src/providers/auth/token-store.js +8 -67
  352. package/dist/src/providers/auth/types.d.ts +9 -1
  353. package/dist/src/providers/auth/types.js +1 -1
  354. package/dist/src/providers/capabilities.d.ts +24 -5
  355. package/dist/src/providers/capabilities.js +42 -24
  356. package/dist/src/providers/endpoints.d.ts +2 -2
  357. package/dist/src/providers/endpoints.js +11 -10
  358. package/dist/src/providers/env-store.d.ts +17 -0
  359. package/dist/src/providers/env-store.js +228 -0
  360. package/dist/src/providers/keychain.d.ts +22 -18
  361. package/dist/src/providers/keychain.js +127 -140
  362. package/dist/src/providers/mcp-vision-bridge.js +56 -146
  363. package/dist/src/providers/openai-compatible.js +8 -1
  364. package/dist/src/providers/pricing.d.ts +2 -2
  365. package/dist/src/providers/pricing.js +3 -13
  366. package/dist/src/providers/runtime.d.ts +43 -3
  367. package/dist/src/providers/runtime.js +88 -14
  368. package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
  369. package/dist/src/providers/strategies/base.strategy.js +24 -1
  370. package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
  371. package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
  372. package/dist/src/providers/strategies/registry.js +4 -4
  373. package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
  374. package/dist/src/providers/strategies/thinking-mode.js +288 -1
  375. package/dist/src/providers/strategies/xai.strategy.js +27 -0
  376. package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
  377. package/dist/src/providers/strategies/zai.strategy.js +44 -0
  378. package/dist/src/providers/types.d.ts +5 -6
  379. package/dist/src/providers/types.js +2 -2
  380. package/dist/src/providers/vision-backend.d.ts +47 -0
  381. package/dist/src/providers/vision-backend.js +258 -0
  382. package/dist/src/providers/vision-proxy.d.ts +22 -9
  383. package/dist/src/providers/vision-proxy.js +63 -132
  384. package/dist/src/providers/warm.d.ts +65 -0
  385. package/dist/src/providers/warm.js +145 -0
  386. package/dist/src/providers/wire-debug.js +95 -0
  387. package/dist/src/router/decide.d.ts +13 -0
  388. package/dist/src/router/decide.js +138 -36
  389. package/dist/src/router/peak-hour.d.ts +38 -0
  390. package/dist/src/router/peak-hour.js +107 -0
  391. package/dist/src/router/step-router.js +3 -2
  392. package/dist/src/router/warm.js +4 -5
  393. package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
  394. package/dist/src/scaffold/continuation-prompt.js +26 -0
  395. package/dist/src/scaffold/point-to-existing.d.ts +21 -0
  396. package/dist/src/scaffold/point-to-existing.js +25 -0
  397. package/dist/src/self-qa/agentic-loop.js +6 -5
  398. package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
  399. package/dist/src/{ui/state → state}/active-run.js +21 -0
  400. package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
  401. package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
  402. package/dist/src/state/turn-trace.d.ts +43 -0
  403. package/dist/src/state/turn-trace.js +32 -0
  404. package/dist/src/storage/db.js +2 -1
  405. package/dist/src/storage/index.d.ts +1 -1
  406. package/dist/src/storage/index.js +1 -1
  407. package/dist/src/storage/interaction-log.d.ts +1 -1
  408. package/dist/src/storage/migrations.js +71 -1
  409. package/dist/src/storage/sessions.d.ts +28 -10
  410. package/dist/src/storage/sessions.js +78 -21
  411. package/dist/src/storage/transcript-view.js +1 -1
  412. package/dist/src/storage/transcript.d.ts +51 -0
  413. package/dist/src/storage/transcript.js +340 -15
  414. package/dist/src/tools/file.d.ts +15 -0
  415. package/dist/src/tools/file.js +32 -0
  416. package/dist/src/tools/git-safety.d.ts +19 -0
  417. package/dist/src/tools/git-safety.js +168 -0
  418. package/dist/src/tools/native-tools.d.ts +1 -1
  419. package/dist/src/tools/native-tools.js +81 -1
  420. package/dist/src/tools/registry.d.ts +20 -0
  421. package/dist/src/tools/registry.js +576 -23
  422. package/dist/src/tools/research.d.ts +29 -0
  423. package/dist/src/tools/research.js +233 -0
  424. package/dist/src/types/index.d.ts +147 -4
  425. package/dist/src/ui/app.js +0 -0
  426. package/dist/src/ui/cards/product-status-card.js +1 -1
  427. package/dist/src/ui/components/agent-rail-activities.d.ts +26 -0
  428. package/dist/src/ui/components/agent-rail-activities.js +47 -0
  429. package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
  430. package/dist/src/ui/components/bubble-body-guard.js +50 -0
  431. package/dist/src/ui/components/compact-progress-card.d.ts +24 -0
  432. package/dist/src/ui/components/compact-progress-card.js +42 -0
  433. package/dist/src/ui/components/context-rail.d.ts +26 -0
  434. package/dist/src/ui/components/context-rail.js +33 -0
  435. package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
  436. package/dist/src/ui/components/council-conclusion-card.js +420 -0
  437. package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
  438. package/dist/src/ui/components/council-debate-pill.js +34 -0
  439. package/dist/src/ui/components/council-info-card.js +2 -2
  440. package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
  441. package/dist/src/ui/components/council-leader-bubble.js +21 -11
  442. package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
  443. package/dist/src/ui/components/council-message-bubble.js +16 -15
  444. package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
  445. package/dist/src/ui/components/council-phase-timeline.js +66 -17
  446. package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
  447. package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
  448. package/dist/src/ui/components/council-question-card.js +13 -12
  449. package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
  450. package/dist/src/ui/components/council-rail-rounds.js +57 -0
  451. package/dist/src/ui/components/council-round-group.d.ts +38 -0
  452. package/dist/src/ui/components/council-round-group.js +88 -0
  453. package/dist/src/ui/components/council-status-list.d.ts +3 -1
  454. package/dist/src/ui/components/council-status-list.js +36 -24
  455. package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
  456. package/dist/src/ui/components/council-synthesis-banner.js +20 -5
  457. package/dist/src/ui/components/halt-recovery-card.js +9 -5
  458. package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
  459. package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
  460. package/dist/src/ui/components/message-view.d.ts +15 -0
  461. package/dist/src/ui/components/message-view.js +50 -1
  462. package/dist/src/ui/components/prompt-box.js +18 -16
  463. package/dist/src/ui/components/session-tree-card.d.ts +14 -0
  464. package/dist/src/ui/components/session-tree-card.js +46 -0
  465. package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
  466. package/dist/src/ui/components/slash-inline-menu.js +26 -5
  467. package/dist/src/ui/components/task-list-panel.d.ts +14 -1
  468. package/dist/src/ui/components/task-list-panel.js +22 -2
  469. package/dist/src/ui/components/tool-group.d.ts +15 -3
  470. package/dist/src/ui/components/tool-group.js +69 -11
  471. package/dist/src/ui/containers/modals-layer.d.ts +4 -2
  472. package/dist/src/ui/containers/modals-layer.js +2 -2
  473. package/dist/src/ui/council-harness-event.d.ts +57 -0
  474. package/dist/src/ui/council-harness-event.js +46 -0
  475. package/dist/src/ui/heartbeat-debug.d.ts +29 -0
  476. package/dist/src/ui/heartbeat-debug.js +45 -0
  477. package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
  478. package/dist/src/ui/mcp-modal.js +2 -4
  479. package/dist/src/ui/modals/api-key-modal.js +1 -1
  480. package/dist/src/ui/modals/connect-modal.js +4 -3
  481. package/dist/src/ui/modals/model-picker-modal.d.ts +8 -18
  482. package/dist/src/ui/modals/model-picker-modal.js +8 -10
  483. package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
  484. package/dist/src/ui/modals/session-picker-modal.js +3 -5
  485. package/dist/src/ui/picker-providers.d.ts +1 -1
  486. package/dist/src/ui/picker-providers.js +1 -1
  487. package/dist/src/ui/primitives/index.d.ts +1 -0
  488. package/dist/src/ui/primitives/index.js +2 -0
  489. package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
  490. package/dist/src/ui/primitives/semantic-primitives.js +81 -0
  491. package/dist/src/ui/slash/compact.js +5 -7
  492. package/dist/src/ui/slash/cost.js +1 -1
  493. package/dist/src/ui/slash/council.js +19 -1
  494. package/dist/src/ui/slash/debug.d.ts +3 -31
  495. package/dist/src/ui/slash/debug.js +9 -20
  496. package/dist/src/ui/slash/ee.js +81 -0
  497. package/dist/src/ui/slash/ideal.d.ts +6 -2
  498. package/dist/src/ui/slash/ideal.js +97 -7
  499. package/dist/src/ui/slash/menu-items.d.ts +7 -0
  500. package/dist/src/ui/slash/menu-items.js +23 -20
  501. package/dist/src/ui/slash/registry.d.ts +2 -0
  502. package/dist/src/ui/slash/registry.js +4 -0
  503. package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
  504. package/dist/src/ui/status-bar/cache-hit.js +9 -0
  505. package/dist/src/ui/status-bar/index.d.ts +1 -1
  506. package/dist/src/ui/status-bar/index.js +7 -3
  507. package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
  508. package/dist/src/ui/status-bar/usd-meter.js +6 -4
  509. package/dist/src/ui/theme.d.ts +1 -0
  510. package/dist/src/ui/theme.js +2 -0
  511. package/dist/src/ui/types.d.ts +7 -0
  512. package/dist/src/ui/use-app-logic.js +0 -0
  513. package/dist/src/ui/utils/agent-activities.d.ts +39 -0
  514. package/dist/src/ui/utils/agent-activities.js +96 -0
  515. package/dist/src/ui/utils/format.d.ts +14 -0
  516. package/dist/src/ui/utils/format.js +23 -3
  517. package/dist/src/ui/utils/group-tool-entries.d.ts +26 -0
  518. package/dist/src/ui/utils/group-tool-entries.js +111 -0
  519. package/dist/src/ui/utils/tool-summary.d.ts +21 -0
  520. package/dist/src/ui/utils/tool-summary.js +91 -0
  521. package/dist/src/usage/downgrade.js +2 -2
  522. package/dist/src/usage/product-ledger.js +2 -2
  523. package/dist/src/utils/event-loop-monitor.d.ts +85 -0
  524. package/dist/src/utils/event-loop-monitor.js +107 -0
  525. package/dist/src/utils/install-manager.js +2 -1
  526. package/dist/src/utils/llm-deadline.d.ts +14 -0
  527. package/dist/src/utils/llm-deadline.js +19 -0
  528. package/dist/src/utils/logger.js +2 -2
  529. package/dist/src/utils/loop-profiler.d.ts +102 -0
  530. package/dist/src/utils/loop-profiler.js +202 -0
  531. package/dist/src/utils/permission-mode.js +5 -3
  532. package/dist/src/utils/redactor.js +1 -1
  533. package/dist/src/utils/settings.d.ts +180 -5
  534. package/dist/src/utils/settings.js +271 -31
  535. package/dist/src/utils/side-question.d.ts +1 -2
  536. package/dist/src/utils/side-question.js +2 -2
  537. package/dist/src/utils/visible-retry.d.ts +11 -0
  538. package/dist/src/utils/visible-retry.js +10 -1
  539. package/dist/src/verify/entrypoint.d.ts +1 -1
  540. package/dist/src/verify/entrypoint.js +52 -17
  541. package/dist/src/verify/orchestrator.d.ts +1 -1
  542. package/dist/src/verify/orchestrator.js +20 -3
  543. package/dist/src/verify/recipes.d.ts +13 -0
  544. package/dist/src/verify/recipes.js +15 -0
  545. package/package.json +134 -132
  546. package/dist/src/cli/bw-vault.d.ts +0 -55
  547. package/dist/src/cli/bw-vault.js +0 -133
  548. package/dist/src/mcp/ee-tools.d.ts +0 -46
  549. package/dist/src/mcp/ee-tools.js +0 -193
  550. package/dist/src/providers/auth/gcloud.d.ts +0 -28
  551. package/dist/src/providers/auth/gcloud.js +0 -102
  552. package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
  553. package/dist/src/providers/auth/gemini-oauth.js +0 -472
  554. package/dist/src/providers/gemini.d.ts +0 -11
  555. package/dist/src/providers/gemini.js +0 -45
  556. package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
  557. package/dist/src/providers/siliconflow-sse-repair.js +0 -177
  558. package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
  559. package/dist/src/providers/strategies/google.strategy.js +0 -174
  560. package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
  561. package/dist/src/ui/containers/chat-feed.d.ts +0 -40
  562. package/dist/src/ui/containers/chat-feed.js +0 -66
@@ -48,7 +48,7 @@
48
48
  // - A4 (tool_call write-ahead) — persistToolCallWriteAhead
49
49
  // - A5 (message_seq write-ahead) — persistMessageWriteAhead
50
50
  // - O1 (providerOptions shape forensics) — extractProviderOptionsShape
51
- // - siliconflow reasoning-strip — turnCaps.sanitizeHistory
51
+ // - reasoning-strip (provider quirk) — turnCaps.sanitizeHistory
52
52
  import { getCachedAuthToken, getCachedServerBaseUrl } from "../ee/auth.js";
53
53
  import { routeModel } from "../ee/bridge.js";
54
54
  import { getMistakeDetector } from "../ee/mistake-detector.js";
@@ -57,20 +57,26 @@ import * as phaseTracker from "../ee/phase-tracker.js";
57
57
  import { buildScope as buildScopeForVeto } from "../ee/scope.js";
58
58
  import { fireTrajectoryEvent } from "../ee/session-trajectory.js";
59
59
  import { getTenantId as getTenantIdForVeto } from "../ee/tenant.js";
60
+ import { assessComplexity } from "../gsd/complexity-assessor.js";
61
+ import { isComplexityAssessorEnabled, isGsdNativeEnabled, isPilGateEnrichEnabled } from "../gsd/flags.js";
62
+ import { getGsdLoopHost } from "../gsd/loop-host.js";
63
+ import { readState, syncWorkflowContext } from "../gsd/workflow-engine.js";
60
64
  import { applyPilSuffix, getResponseToolSet, } from "../pil/index.js";
65
+ import { isContinuationPhrase } from "../pil/layer1-intent.js";
61
66
  import { loadKeyForProvider } from "../providers/keychain.js";
62
67
  import { getVisionGuidanceForTextOnly, } from "../providers/mcp-vision-bridge.js";
63
68
  import { detectProviderForModel, resolveModelRuntime, } from "../providers/runtime.js";
64
- import { needsVisionProxy, proxyVision } from "../providers/vision-proxy.js";
69
+ import { canHandleImagesForTextOnlyModel, needsVisionProxy, planImageHandlingForTextOnlyModel, proxyVision, } from "../providers/vision-proxy.js";
65
70
  import { decideStepRouting, eeSamrGuidance, getStepRouterConfig } from "../router/step-router.js";
66
71
  import { routerStore } from "../router/store.js";
67
- import { getNextMessageSequence, logInteraction, persistMessageWriteAhead, } from "../storage/index.js";
68
- import { isDebugEnabled } from "../ui/slash/debug.js";
69
- import { statusBarStore } from "../ui/status-bar/store.js";
72
+ import { statusBarStore } from "../state/status-bar-store.js";
73
+ import { isDebugEnabled } from "../state/turn-trace.js";
74
+ import { getLastApprovedPlan, getNextMessageSequence, logInteraction, persistMessageWriteAhead, } from "../storage/index.js";
70
75
  import { isProviderDisabled, loadValidSubAgents, } from "../utils/settings.js";
71
76
  import { prepareTurnContext } from "./preprocessor.js";
72
77
  import { applyModelConstraints, buildSystemPromptParts } from "./prompts.js";
73
78
  import { parseBudgetOverride, resetSessionStep, } from "./scope-ceiling.js";
79
+ import { shouldRunGate } from "./should-run-gate.js";
74
80
  import { executeToolEngine } from "./tool-engine.js";
75
81
  /**
76
82
  * F2 — approximate the char cost of the FIXED prompt envelope (system +
@@ -107,6 +113,50 @@ function computeEnvelopeChars(system, tools) {
107
113
  * guidance entries it stays informed until new entries arrive.
108
114
  */
109
115
  const _injectedGuidanceSha = new Map();
116
+ /**
117
+ * Single-shot leader-tier LLM runner for the GSD complexity assessor
118
+ * (Task 4 `assessComplexity`). Mirrors the orchestrator's own council LLM
119
+ * construction (`createCouncilLLM` — see `runCouncil` / `runProductLoop` in
120
+ * orchestrator.ts) so the assessor call auto-records usage as
121
+ * `source=council` (no cost-leak) instead of a bespoke unaccounted call.
122
+ * Leader model resolution goes ONLY through `resolvePlanCouncilLeader` —
123
+ * Zero Hardcode Rule, no literal model/provider IDs here.
124
+ */
125
+ function buildLeaderAssessorRunner(deps, sessionModel) {
126
+ return async (prompt) => {
127
+ const { createCouncilLLM } = await import("../council/llm.js");
128
+ const { resolvePlanCouncilLeader } = await import("../council/leader.js");
129
+ const leader = await resolvePlanCouncilLeader(sessionModel);
130
+ const stats = { calls: 0, startMs: Date.now(), phases: [] };
131
+ const llm = createCouncilLLM(deps.bash, deps.mode, deps.session?.id, stats);
132
+ // Small budget — this is a single classification, not a synthesis.
133
+ return llm.generate(leader.modelId, "You are a task complexity assessor.", prompt, 512, undefined, AbortSignal.timeout(PIL_GATE_DEADLINE_MS));
134
+ };
135
+ }
136
+ /**
137
+ * Turn-start PIL gate budget: the assessor + heavy-tier critics run BEFORE the
138
+ * model message is assembled, so they must be short — a slow gate call would
139
+ * delay every turn, not just heavy ones. `createCouncilLLM.generate` has no
140
+ * per-call timeout of its own (`llm.ts:331` defaults to 5 minutes), so this
141
+ * deadline is threaded explicitly as the `signal` arg on every gate call.
142
+ */
143
+ const PIL_GATE_DEADLINE_MS = 2500;
144
+ /**
145
+ * Heavy-tier gate critic runner (Task 4 `runGateCritics`). Reuses the council
146
+ * LLM (billed `source=council`, no cost leak) with the same tight deadline as
147
+ * the assessor — three critics run in parallel via `Promise.all` inside
148
+ * `runGateCritics`, each individually bounded by this signal.
149
+ */
150
+ function buildGateCriticRunner(deps, sessionModel) {
151
+ return async (prompt) => {
152
+ const { createCouncilLLM } = await import("../council/llm.js");
153
+ const { resolvePlanCouncilLeader } = await import("../council/leader.js");
154
+ const leader = await resolvePlanCouncilLeader(sessionModel);
155
+ const stats = { calls: 0, startMs: Date.now(), phases: [] };
156
+ const llm = createCouncilLLM(deps.bash, deps.mode, deps.session?.id, stats);
157
+ return llm.generate(leader.modelId, "You are a prompt-enrichment critic.", prompt, 512, undefined, AbortSignal.timeout(PIL_GATE_DEADLINE_MS));
158
+ };
159
+ }
110
160
  /**
111
161
  * MessageProcessor — extracted streaming turn loop.
112
162
  *
@@ -316,6 +366,89 @@ export class MessageProcessor {
316
366
  yield res.value;
317
367
  }
318
368
  const { pilCtx, _stepCeiling, _pilStart, _naturalCeiling, _ceilingTaskType, _ceilingSize } = prepResult;
369
+ const cwd = deps.bash.getCwd();
370
+ if (isGsdNativeEnabled() &&
371
+ shouldRunGate(pilCtx, () => {
372
+ try {
373
+ return readState(cwd).phase;
374
+ }
375
+ catch (err) {
376
+ // Missing/corrupt .planning state is the normal "no active run" case, not an error.
377
+ console.error(`[pil-gate] readState failed while checking resume phase (treating as no active run): ${err.message}`);
378
+ return null;
379
+ }
380
+ })) {
381
+ try {
382
+ const sessionModel = deps.session?.model ?? "unknown";
383
+ let depth = pilCtx.modelDepthTier ?? pilCtx.complexityTier ?? "standard";
384
+ // Leader-tier assessor enrichment: OVERRIDES the fast-classifier depth
385
+ // before it's written to SDK STATE.md. `assessComplexity` itself never
386
+ // throws (every internal step is caught, degrading to `priorDepth`),
387
+ // but this inner try/catch is defensive fail-open insurance so even an
388
+ // unexpected throw here keeps `depth` at its fast-classifier value —
389
+ // syncWorkflowContext below is never skipped because of the assessor.
390
+ let brief = "";
391
+ if (isComplexityAssessorEnabled()) {
392
+ try {
393
+ const { buildGateContextBundle } = await import("../gsd/pil-gate-context.js");
394
+ const bundle = buildGateContextBundle({
395
+ cwd,
396
+ conversationDigest: deps.buildRecentTurnsSummary(),
397
+ brainData: pilCtx._brainData,
398
+ });
399
+ const assessed = await assessComplexity({
400
+ cwd,
401
+ raw: pilCtx.raw,
402
+ priorDepth: depth,
403
+ confidence: pilCtx.confidence,
404
+ bundle,
405
+ sessionModelId: sessionModel,
406
+ runAssessor: buildLeaderAssessorRunner(deps, sessionModel), // single-shot leader call
407
+ });
408
+ depth = assessed.depth;
409
+ // Keep the native depth slot authoritative: write the assessed depth
410
+ // back to pilCtx.modelDepthTier so every downstream consumer that reads
411
+ // it (tool-engine depthTier -> gsd tool registration + gsd_verify depth
412
+ // + layer-derived tiering) sees the SAME value the mutation gate reads
413
+ // from STATE.md. Without this, the gate (readState().depth) and gsd_verify
414
+ // (pilCtx.modelDepthTier) diverge on any assessor override. Same pilCtx
415
+ // ref, and this block runs before executeToolEngine in the same turn.
416
+ pilCtx.modelDepthTier = depth;
417
+ if (assessed.assessed)
418
+ pilCtx.gsdAutoCouncil = assessed.autoCouncil;
419
+ if (isPilGateEnrichEnabled() && assessed.enrichedPrompt) {
420
+ let verdict = assessed.quality?.verdict ?? "enriched";
421
+ brief = assessed.enrichedPrompt;
422
+ if (depth === "heavy") {
423
+ const { runGateCritics } = await import("../gsd/pil-gate-critic.js");
424
+ const critiqued = await runGateCritics({
425
+ draftBrief: brief,
426
+ draftVerdict: verdict,
427
+ bundle,
428
+ runCritic: buildGateCriticRunner(deps, sessionModel),
429
+ });
430
+ verdict = critiqued.verdict;
431
+ brief = critiqued.brief;
432
+ }
433
+ if (verdict === "adequate")
434
+ brief = "";
435
+ }
436
+ }
437
+ catch (assessErr) {
438
+ brief = "";
439
+ console.error(`[pil-gate] enrichment failed, using raw prompt: ${assessErr.message}`);
440
+ }
441
+ }
442
+ if (brief) {
443
+ pilCtx.enriched = `[PIL Gate brief]\n${brief.slice(0, 1500)}\n\n${pilCtx.enriched}`;
444
+ }
445
+ getGsdLoopHost().ensureHost(cwd, sessionModel);
446
+ syncWorkflowContext(cwd, sessionModel, depth);
447
+ }
448
+ catch (err) {
449
+ console.error(`[gsd-loop-host] turn sync failed: ${err.message}`);
450
+ }
451
+ }
319
452
  // Track whether forced-finalize is needed (set by stopWhen when the
320
453
  // ceiling fires). Read AFTER the streamText fullStream finishes.
321
454
  const _ceilingHit = false;
@@ -332,8 +465,8 @@ export class MessageProcessor {
332
465
  enrichedMessage = `[PIL fallback: ${pilCtx.fallbackReason} — classification/routing may be inaccurate or layers skipped; using raw input.]\n\n${enrichedMessage}`;
333
466
  }
334
467
  deps.setPilActive(pilCtx.taskType !== null);
335
- deps.setPilEnrichmentDelta(pilCtx.metrics?.suffixInstructionTokens ?? Math.round((enrichedMessage.length - userMessage.length) / 4));
336
- const _pilEnrichmentDeltaSnapshot = pilCtx.metrics?.suffixInstructionTokens ?? Math.round((enrichedMessage.length - userMessage.length) / 4);
468
+ deps.setPilEnrichmentDelta(pilCtx.metrics?.suffixInstructionTokens ?? Math.round(((enrichedMessage ?? "").length - userMessage.length) / 4));
469
+ const _pilEnrichmentDeltaSnapshot = pilCtx.metrics?.suffixInstructionTokens ?? Math.round(((enrichedMessage ?? "").length - userMessage.length) / 4);
337
470
  // P1 Item 3 wiring: phase-boundary detection. setPhase returns a snapshot
338
471
  // of the prior phase iff the phase NAME just changed. We classify the
339
472
  // outcome (pass/fail/abandoned/null) and fire phase-outcome to the EE
@@ -423,9 +556,17 @@ export class MessageProcessor {
423
556
  const turnStartMs = Date.now();
424
557
  let turnModelId = deps.modelId;
425
558
  let taskHash = null;
559
+ let routeReason = null;
560
+ const historyHasImages = deps.messages.some((m) => Array.isArray(m.content) && m.content.some((p) => p.type === "image"));
561
+ const turnHasImages = (images?.length ?? 0) > 0;
562
+ let visionUnavailableNotice = null;
426
563
  const _routeStart = Date.now();
427
564
  try {
428
565
  const { decide } = await import("../router/decide.js");
566
+ const compactionMsg = deps.messages.find((m) => typeof m.content === "string" && m.content.startsWith("[Context checkpoint summary]"));
567
+ const compactionSummary = compactionMsg && typeof compactionMsg.content === "string"
568
+ ? compactionMsg.content.slice("[Context checkpoint summary]".length).trim()
569
+ : null;
429
570
  const routeDecision = await decide(userMessage, {
430
571
  tenantId: "local",
431
572
  cwd: deps.bash.getCwd(),
@@ -441,6 +582,11 @@ export class MessageProcessor {
441
582
  projectSize: deps.estimateProjectSize(),
442
583
  filesTouched: deps.countFilesTouched(),
443
584
  mode: deps.mode,
585
+ turnIndex: deps.messages.filter((m) => m.role === "user").length,
586
+ messageCount: deps.messages.length,
587
+ compactionCount: deps.getCompactionStats().count,
588
+ totalSavedTokens: deps.getCompactionStats().totalSaved,
589
+ compactionSummary,
444
590
  },
445
591
  });
446
592
  if (routeDecision.model && routeDecision.model !== "HALT") {
@@ -449,14 +595,15 @@ export class MessageProcessor {
449
595
  // images to text, so there's no need to switch to a vision-capable
450
596
  // (and usually pricier / rate-limited) model.
451
597
  const defaultHasVisionProxy = needsVisionProxy(deps.modelId);
452
- const historyHasImages = deps.messages.some((m) => Array.isArray(m.content) && m.content.some((p) => p.type === "image"));
453
- const turnHasImages = (images?.length ?? 0) > 0;
454
- const skipVisionRoute = defaultHasVisionProxy && (turnHasImages || historyHasImages);
598
+ const imagesOnTurn = turnHasImages || historyHasImages;
599
+ const canHandleImages = !defaultHasVisionProxy || !imagesOnTurn || (await canHandleImagesForTextOnlyModel(deps.modelId));
600
+ const skipVisionRoute = defaultHasVisionProxy && imagesOnTurn && canHandleImages;
455
601
  if (!skipVisionRoute) {
456
602
  turnModelId = routeDecision.model;
457
603
  }
458
604
  }
459
605
  taskHash = routeDecision.taskHash ?? null;
606
+ routeReason = routeDecision.reason ?? null;
460
607
  // Update status bar with router switch info. Also reset back to the
461
608
  // session default when the router does NOT switch on this turn —
462
609
  // otherwise the bar stays "stuck" showing the previously-routed model
@@ -487,14 +634,39 @@ export class MessageProcessor {
487
634
  taskHash = eeRoute?.taskHash ?? null;
488
635
  }
489
636
  }
637
+ if (needsVisionProxy(turnModelId) && (turnHasImages || historyHasImages)) {
638
+ const imageCount = turnHasImages ? images.length : 1;
639
+ const plan = await planImageHandlingForTextOnlyModel({
640
+ primaryModelId: turnModelId,
641
+ imageCount,
642
+ });
643
+ if (plan.strategy === "native_model") {
644
+ turnModelId = plan.fallback.modelId;
645
+ routeReason = routeReason ? `${routeReason}; vision-native-fallback` : "vision-native-fallback";
646
+ yield {
647
+ type: "content",
648
+ content: `[Vision: routed to ${plan.fallback.modelId} — no proxy backend; using native image support]\n`,
649
+ };
650
+ }
651
+ else if (plan.strategy === "unavailable") {
652
+ visionUnavailableNotice = plan.notice;
653
+ }
654
+ }
490
655
  // Interaction log: model routing
491
656
  try {
492
657
  if (deps.session) {
658
+ const promoted = turnModelId !== deps.modelId;
493
659
  logInteraction(deps.session.id, "routing", {
494
660
  model: turnModelId,
661
+ eventSubtype: promoted ? "promoted" : "default",
495
662
  data: {
496
663
  defaultModel: deps.modelId,
497
664
  routedModel: turnModelId,
665
+ promoted,
666
+ // promo-cap(...) tag appears here when the promotion ceiling clamped
667
+ // an EE premium pick down to balanced — queryable via event_subtype +
668
+ // data.reason to audit cost-leak prevention (session 89b34ce9a4e8 class).
669
+ reason: routeReason,
498
670
  taskHash,
499
671
  pilTaskType: pilCtx.taskType ?? null,
500
672
  pilIntentKind: pilCtx.intentKind ?? null,
@@ -509,13 +681,31 @@ export class MessageProcessor {
509
681
  const turnProviderId = detectProviderForModel(turnModelId);
510
682
  let turnProvider;
511
683
  if (turnProviderId !== deps.providerId) {
684
+ const disabled = isProviderDisabled(turnProviderId);
512
685
  // Even if the key is reachable, skip disabled providers
513
- const turnKey = !isProviderDisabled(turnProviderId)
514
- ? await loadKeyForProvider(turnProviderId).catch(() => null)
515
- : null;
516
- if (turnKey) {
517
- const { createProviderFactory } = await import("../providers/runtime.js");
518
- turnProvider = createProviderFactory(turnProviderId, { apiKey: turnKey }).factory;
686
+ const turnKey = !disabled ? await loadKeyForProvider(turnProviderId).catch(() => null) : null;
687
+ // An OAuth-capable provider may be authenticated by subscription tokens
688
+ // (no env API key). Detect that so the turn can still run over OAuth.
689
+ let hasOAuth = false;
690
+ if (!disabled) {
691
+ try {
692
+ const { getOAuthProviderConfig } = await import("../providers/auth/registry.js");
693
+ const cfg = await getOAuthProviderConfig(turnProviderId);
694
+ const tokens = cfg ? await cfg.loadTokensWithRefresh().catch(() => null) : null;
695
+ hasOAuth = !!tokens?.accessToken;
696
+ }
697
+ catch {
698
+ hasOAuth = false;
699
+ }
700
+ }
701
+ if (turnKey || hasOAuth) {
702
+ // OAuth XOR API key: the ASYNC factory injects OAuth (codex baseURL +
703
+ // Bearer headers) when tokens exist for this provider, otherwise it
704
+ // uses the env key. Using the sync factory here was the cross-provider
705
+ // shadowing bug (it shipped a stale sk-proj key to api.openai.com).
706
+ const { createProviderFactoryAsync } = await import("../providers/runtime.js");
707
+ const built = await createProviderFactoryAsync(turnProviderId, turnKey ? { apiKey: turnKey } : {});
708
+ turnProvider = built.factory;
519
709
  }
520
710
  else {
521
711
  // Router's provider unreachable or disabled — fall back to a non-disabled provider
@@ -566,10 +756,38 @@ export class MessageProcessor {
566
756
  // still carry image parts — otherwise sending the conversation back to a
567
757
  // text-only provider (e.g. DeepSeek) fails with "unknown variant
568
758
  // `image_url`" once history contains an image from a prior turn.
569
- if (needsVisionProxy(turnModelId)) {
570
- const historyHasImages = deps.messages.some((m) => Array.isArray(m.content) && m.content.some((p) => p.type === "image"));
571
- const turnHasImages = (images?.length ?? 0) > 0;
572
- if (turnHasImages || historyHasImages) {
759
+ if (needsVisionProxy(turnModelId) && (turnHasImages || historyHasImages)) {
760
+ const stripImagesFromMessages = (msgs) => msgs.map((m) => {
761
+ if (!Array.isArray(m.content))
762
+ return m;
763
+ const textParts = m.content.filter((p) => p.type === "text");
764
+ const joined = textParts.map((p) => p.text ?? "").join("\n");
765
+ return { ...m, content: joined || "[image removed — vision unavailable]" };
766
+ });
767
+ if (visionUnavailableNotice) {
768
+ yield {
769
+ type: "content",
770
+ content: "[Vision: cannot analyze images — no vision API key or vision model available]\n",
771
+ };
772
+ if (historyHasImages) {
773
+ deps.setMessages(stripImagesFromMessages(deps.messages).map((m) => {
774
+ if (m.role !== "user" || typeof m.content !== "string")
775
+ return m;
776
+ return { ...m, content: `${m.content}\n\n${visionUnavailableNotice}` };
777
+ }));
778
+ }
779
+ if (turnHasImages) {
780
+ userModelMessage = {
781
+ role: "user",
782
+ content: `${messageForDb}\n\n${visionUnavailableNotice}`,
783
+ };
784
+ userEnrichedMessage = {
785
+ role: "user",
786
+ content: `${messageForModel}\n\n${visionUnavailableNotice}`,
787
+ };
788
+ }
789
+ }
790
+ else {
573
791
  try {
574
792
  if (historyHasImages) {
575
793
  const historyResult = await proxyVision(deps.messages, turnModelId, signal);
@@ -588,25 +806,23 @@ export class MessageProcessor {
588
806
  userEnrichedMessage = proxyResult.messages[1];
589
807
  yield {
590
808
  type: "content",
591
- content: `[Vision proxy: ${proxyResult.imageCount} image(s) ${turnModelId} via SiliconFlow]\n`,
809
+ content: `[Vision proxy: ${proxyResult.imageCount} image(s) analyzed for ${turnModelId}]\n`,
592
810
  };
593
811
  }
594
812
  }
595
813
  }
596
- catch {
597
- yield { type: "content", content: "[Vision proxy: failed, images dropped]\n" };
814
+ catch (err) {
815
+ const errMsg = err instanceof Error ? err.message : String(err);
816
+ console.warn(`[vision-proxy] message path failed: ${errMsg}`);
817
+ const notice = visionUnavailableNotice ?? `[vision unavailable: ${errMsg}]`;
818
+ yield { type: "content", content: "[Vision proxy: failed — images not sent to model]\n" };
819
+ if (historyHasImages) {
820
+ deps.setMessages(stripImagesFromMessages(deps.messages));
821
+ }
598
822
  if (turnHasImages) {
599
- userModelMessage = { role: "user", content: messageForDb };
600
- userEnrichedMessage = { role: "user", content: messageForModel };
823
+ userModelMessage = { role: "user", content: `${messageForDb}\n\n${notice}` };
824
+ userEnrichedMessage = { role: "user", content: `${messageForModel}\n\n${notice}` };
601
825
  }
602
- // Strip image parts from history as a last-resort fallback so the
603
- // request doesn't blow up at the provider serialization layer.
604
- deps.setMessages(deps.messages.map((m) => {
605
- if (!Array.isArray(m.content))
606
- return m;
607
- const filtered = m.content.filter((p) => p.type !== "image");
608
- return { ...m, content: filtered };
609
- }));
610
826
  }
611
827
  }
612
828
  }
@@ -666,12 +882,13 @@ export class MessageProcessor {
666
882
  .slice(0, 10)
667
883
  .map((p) => ` - ee_feedback(id="${p.id}", collection="${p.collection ?? "?"}", verdict=followed|ignored|noise)`);
668
884
  const more = pending.length > 10 ? `\n ...and ${pending.length - 10} more` : "";
669
- const recallContent = `⚠️ MANDATORY: Rate ${pending.length} unrated EE hint(s) before proceeding.\n` +
670
- `You MUST call ee_feedback for each hint below BEFORE doing anything else this turn.\n` +
671
- `This is not optional the Experience Engine brain learns from these ratings.\n` +
672
- `Verdict: followed (you used the hint) | ignored (not relevant) | noise (wrong/stale).\n` +
885
+ const recallContent = `↳ ${pending.length} earlier EE hint(s) still unrated. Rate the one(s) you actually ` +
886
+ `acted on so the brain keeps what helped this does NOT block the task; batch the ` +
887
+ `ee_feedback call(s) alongside your work, don't stall the user's request on it.\n` +
888
+ `Verdict: followed (you used it) | ignored (topical, didn't apply) | noise (wrong — needs reason).\n` +
673
889
  `${hintLines.join("\n")}${more}\n` +
674
- `First output MUST be the ee_feedback call(s) then proceed with the task.`;
890
+ `Rate once and move on a hint you can't judge yet, leave for later; re-rating the same ` +
891
+ `id does not help. If the brain is unreachable the verdict is queued, so never retry-loop on it.`;
675
892
  const sid = deps.session?.id ?? "_anon";
676
893
  const { createHash: _recallHash } = await import("node:crypto");
677
894
  const recallSha = _recallHash("sha256").update(recallContent).digest("hex").slice(0, 16);
@@ -706,7 +923,7 @@ export class MessageProcessor {
706
923
  const system = applyModelConstraints(applyPilSuffix(`${systemParts.staticPrefix}${playwrightGuidance}${systemParts.dynamicSuffix}`, pilCtx, _hasResponseTools), turnModelId);
707
924
  // Tool-turn system: same template as system but with toolTurn-prefix
708
925
  const toolTurnSystem = applyModelConstraints(applyPilSuffix(`${toolTurnParts.staticPrefix}${playwrightGuidance}${toolTurnParts.dynamicSuffix}`, pilCtx, _hasResponseTools), turnModelId);
709
- const runtime = resolveModelRuntime(provider, turnModelId);
926
+ const runtime = resolveModelRuntime(turnModelId);
710
927
  const modelInfo = runtime.modelInfo;
711
928
  // SAMR: Step-Aware Model Routing — downgrade to fast model for tool-execution
712
929
  // steps after the initial reasoning step. The premium model decides WHAT to do;
@@ -739,7 +956,7 @@ export class MessageProcessor {
739
956
  const stepRouterDecision = decideStepRouting(turnModelId, deps.providerId, stepRouterCfg);
740
957
  const stepRouterPhase = stepRouterDecision.phase2ModelId ? "phase1" : "done";
741
958
  const phase2Runtime = stepRouterDecision.phase2ModelId
742
- ? resolveModelRuntime(provider, stepRouterDecision.phase2ModelId)
959
+ ? resolveModelRuntime(stepRouterDecision.phase2ModelId)
743
960
  : null;
744
961
  if (stepRouterDecision.phase2ModelId && _debugOn) {
745
962
  _debugSteps.push({
@@ -749,7 +966,17 @@ export class MessageProcessor {
749
966
  output_summary: stepRouterDecision.reason,
750
967
  });
751
968
  }
752
- deps.setPlanContext(null);
969
+ // Phase 5 continuation fix: do not clear planContext on bare "tiếp tục"/"continue".
970
+ // Re-hydrate from persisted approved plan if needed (cross-process or after abort).
971
+ const _isCont = isContinuationPhrase(userMessage);
972
+ if (!_isCont) {
973
+ deps.setPlanContext(null);
974
+ }
975
+ else if (!deps.getPlanContext()) {
976
+ const _p = getLastApprovedPlan(deps.session?.id ?? "");
977
+ if (_p)
978
+ deps.setPlanContext(_p);
979
+ }
753
980
  const attemptedOverflowRecovery = false;
754
981
  // Stream-retry state: track how many transient retries have been attempted
755
982
  // for the current turn. Reset to 0 on each new user turn (we're in processMessage).
@@ -4,9 +4,14 @@ import { type ScheduleDaemonStatus, type StoredSchedule } from "../tools/schedul
4
4
  import type { AgentMode, ChatEntry, SessionInfo, SessionSnapshot, StreamChunk, SubagentStatus, TaskListSnapshot, TaskRequest, ToolResult, VerifyRecipe } from "../types/index.js";
5
5
  import { type SandboxMode, type SandboxSettings } from "../utils/settings.js";
6
6
  import { type SideQuestionResult } from "../utils/side-question.js";
7
- import { type AgentOptions, type ProcessMessageObserver } from "./agent-options.js";
7
+ import { type AgentOptions, type LegacyProvider, type ProcessMessageObserver } from "./agent-options.js";
8
+ import type { AskUserAskInfo } from "./ask-user.js";
8
9
  import type { SafetyOverrideAskInfo, SafetyOverrideVerdict } from "./safety-askcard.js";
9
10
  import type { ToolLoopCapAsk } from "./tool-loop-cap.js";
11
+ /** Deterministic fallback title: truncated first user message, or "" when the
12
+ * message is empty or a JSON-ish payload (so the caller leaves title = NULL
13
+ * and the picker renders a clean "(untitled)" instead of a literal "{}"). */
14
+ export declare function fallbackTitle(userMessage: string): string;
10
15
  export declare class Agent {
11
16
  private provider;
12
17
  private providerId;
@@ -25,6 +30,8 @@ export declare class Agent {
25
30
  private steerDrain;
26
31
  private maxToolRounds;
27
32
  private hardMaxToolRounds;
33
+ /** Original hard ceiling at construction — bounds auto-compaction extension. */
34
+ private _initialHardMaxToolRounds;
28
35
  private mode;
29
36
  private modelId;
30
37
  private maxTokens;
@@ -83,6 +90,9 @@ export declare class Agent {
83
90
  private _turnUserGoalExcerpt;
84
91
  /** Compaction statistics tracking count and total tokens saved. */
85
92
  private _compactionStats;
93
+ /** Token count immediately after the last successful compaction (or null if none yet this
94
+ * session). Used by the cross-turn anti-thrash guard in postTurnCompact. */
95
+ private _lastCompactionTokensAfter;
86
96
  /**
87
97
  * Pinned message sequences. A pinned user message is preserved verbatim across
88
98
  * compaction — it is re-injected as a system note immediately after the
@@ -93,6 +103,8 @@ export declare class Agent {
93
103
  /** One-shot cwd note injected at the start of the next processMessage turn after setCwd(). Cleared after injection. */
94
104
  private _pendingCwdNote;
95
105
  private _crossTurnDedup;
106
+ private _lastTurnToolChars;
107
+ private _turnLoadOrdinal;
96
108
  private _readBudget;
97
109
  constructor(apiKey: string | undefined, baseURL?: string, model?: string, maxToolRounds?: number, options?: AgentOptions);
98
110
  /**
@@ -110,6 +122,22 @@ export declare class Agent {
110
122
  text: string;
111
123
  }[]) | null): void;
112
124
  getActiveRunId(): string | null;
125
+ /**
126
+ * Point the agent at `model`, re-resolving the provider when the new model
127
+ * belongs to a different one.
128
+ *
129
+ * EVERY path that changes `this.modelId` must go through here. Changing the
130
+ * id alone leaves `providerId` / `provider` / `baseURL` / `apiKey` describing
131
+ * the PREVIOUS provider, so the next turn POSTs the new model to the old
132
+ * provider's endpoint — which rejects it as unknown (session 0c6728ba1a25:
133
+ * `gpt-5.4` sent to api.x.ai → 404 "The model gpt-5.4 does not exist", a
134
+ * wiring bug that reads like a bad model name). `setMode` used to do exactly
135
+ * that; it now calls this too.
136
+ *
137
+ * Session persistence is NOT done here — callers own that, because setMode
138
+ * writes mode+model together.
139
+ */
140
+ private _applyModelId;
113
141
  setModel(model: string): void;
114
142
  getMode(): AgentMode;
115
143
  getSandboxMode(): SandboxMode;
@@ -123,6 +151,12 @@ export declare class Agent {
123
151
  setApiKey(apiKey: string, baseURL?: string): void;
124
152
  setProviderAndKey(providerId: ProviderId, apiKey: string, baseURL?: string): void;
125
153
  getProviderId(): ProviderId;
154
+ /**
155
+ * Expose the provider factory for external callers (e.g., /compact slash command,
156
+ * sub-agent spawning) that need to make LLM calls outside the normal processMessage flow.
157
+ * Throws if no provider is configured.
158
+ */
159
+ getProvider(): LegacyProvider;
126
160
  getCwd(): string;
127
161
  setCwd(dir: string): void;
128
162
  getMessages(): ModelMessage[];
@@ -143,8 +177,22 @@ export declare class Agent {
143
177
  cleanup(): Promise<void>;
144
178
  private _toolLoopCapHandler;
145
179
  setToolLoopCapHandler(fn: ToolLoopCapAsk | null): void;
180
+ /**
181
+ * Extend the absolute hard-cap ceiling when the turn is being sustained by
182
+ * AUTO-COMPACTION (a productive long task, not a runaway). Rationale: each
183
+ * auto-compacted round resets context to O(N) input, so it is cheap — the
184
+ * hard cap's cost-runaway purpose is already served by the compaction. We
185
+ * grant `maxToolRounds/2` more headroom per compaction, bounded to at most
186
+ * one extra auto-recover budget's worth above the ORIGINAL ceiling so a
187
+ * genuinely wedged turn (which trips the pattern guard, not this path) can
188
+ * never grow the cap without limit. Called from the tool-engine auto-recover
189
+ * branch after a successful compaction.
190
+ */
191
+ extendHardCeilingForAutoCompaction(): void;
146
192
  private _safetyOverrideHandler;
147
193
  setSafetyOverrideHandler(fn: ((block: SafetyOverrideAskInfo) => Promise<SafetyOverrideVerdict>) | null): void;
194
+ private _askUserHandler;
195
+ setAskUserHandler(fn: ((info: AskUserAskInfo) => Promise<string>) | null): void;
148
196
  respondToToolApproval(approvalId: string, approved: boolean): void;
149
197
  clearHistory(): Promise<void>;
150
198
  startNewSession(): SessionSnapshot | null;
@@ -166,6 +214,13 @@ export declare class Agent {
166
214
  unpinMessageBySeq(seq: number): boolean;
167
215
  getPinnedSeqs(): number[];
168
216
  getChatEntries(): ChatEntry[];
217
+ /**
218
+ * The session tree this TUI currently hosts: the root conversation plus every
219
+ * rotation / sub-agent descendant, with per-session metadata. Content from
220
+ * these sessions is already merged into the transcript on resume; this exposes
221
+ * WHICH sessions produced it so the rail can show the multi-session structure.
222
+ */
223
+ getSessionTree(): import("../storage/transcript.js").SessionChainNode[];
169
224
  getLastTodoSnapshot(): TaskListSnapshot | null;
170
225
  getSessionSnapshot(): SessionSnapshot | null;
171
226
  onSubagentStatus(listener: (status: SubagentStatus | null) => void): () => void;
@@ -195,15 +250,21 @@ export declare class Agent {
195
250
  private _resolveModelForTask;
196
251
  private compactForContext;
197
252
  private postTurnCompact;
198
- respondToCouncilQuestion(questionId: string, answer: string): void;
253
+ respondToCouncilQuestion(questionId: string, answer: string, questionText?: string): void;
199
254
  respondToCouncilPreflight(preflightId: string, approved: boolean): void;
200
255
  runCouncilV2(topic: string, options?: {
201
256
  skipClarification?: boolean;
202
257
  observer?: ProcessMessageObserver;
203
258
  userModelMessage?: ModelMessage;
259
+ /**
260
+ * convene_council path — forwarded into runCouncil so the post-debate
261
+ * decision surface is suppressed and the synthesis is returned to the
262
+ * calling agent (no CLI-hardcoded post-council branch).
263
+ */
264
+ convenePath?: boolean;
204
265
  }): AsyncGenerator<StreamChunk, void, unknown>;
205
266
  runProductLoopV1(payload: {
206
- subcommand: "start" | "status" | "resume" | "abort" | "ship";
267
+ subcommand: "start" | "status" | "resume" | "abort" | "ship" | "review";
207
268
  idea?: string;
208
269
  runId?: string;
209
270
  flags: {