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
@@ -37,6 +37,20 @@ export declare function buildReadinessJudgePrompt(topic: string, qa: Array<{
37
37
  system: string;
38
38
  prompt: string;
39
39
  };
40
+ export declare function buildLanguageRule(lang?: string): string;
41
+ /**
42
+ * Feature B — synthesis-specific language rule. The synthesis prompt already
43
+ * localizes its user-facing output to the user's language; this only adjusts (a)
44
+ * the now-possibly-inaccurate "debate above is entirely in English" preamble and
45
+ * (b) the language-selection instruction when the user PINNED a specific locale.
46
+ *
47
+ * undefined / "english" → the historical block, byte-identical (debate was
48
+ * English-only, output detected from the Problem Statement).
49
+ * "auto" → same "detect from the Problem Statement" output behavior, but the
50
+ * preamble no longer falsely claims the debate ran in English.
51
+ * pinned locale → force all prose into that language instead of detecting it.
52
+ */
53
+ export declare function buildSynthesisLanguageRule(lang?: string): string;
40
54
  export declare function buildOpeningPrompt(ctx: {
41
55
  speakerRole: string;
42
56
  partnerRole: string;
@@ -45,6 +59,8 @@ export declare function buildOpeningPrompt(ctx: {
45
59
  spec: ClarifiedSpec;
46
60
  outputShape?: OutputShape;
47
61
  conversationContext?: string;
62
+ /** Feature B — resolved council debate language (undefined → English). */
63
+ language?: string;
48
64
  }): {
49
65
  system: string;
50
66
  prompt: string;
@@ -57,6 +73,8 @@ export declare function buildResponsePrompt(ctx: {
57
73
  speakerPosition: string;
58
74
  partnerPosition: string;
59
75
  spec: ClarifiedSpec;
76
+ /** Feature B — resolved council debate language (undefined → English). */
77
+ language?: string;
60
78
  }): {
61
79
  system: string;
62
80
  prompt: string;
@@ -72,6 +90,8 @@ export declare function buildFollowupPrompt(ctx: {
72
90
  round: number;
73
91
  runningSummary?: string;
74
92
  spec: ClarifiedSpec;
93
+ /** Feature B — resolved council debate language (undefined → English). */
94
+ language?: string;
75
95
  }): {
76
96
  system: string;
77
97
  prompt: string;
@@ -80,11 +100,15 @@ export declare function buildLeaderEvaluationPrompt(ctx: {
80
100
  spec: ClarifiedSpec;
81
101
  exchangeLogs: string;
82
102
  round: number;
103
+ /** Feature B — resolved council debate language (undefined → English). */
104
+ language?: string;
83
105
  }): {
84
106
  system: string;
85
107
  prompt: string;
86
108
  };
87
- export declare function buildRoundSummaryPrompt(allExchanges: string, topic: string, round: number): {
109
+ export declare function buildRoundSummaryPrompt(allExchanges: string, topic: string, round: number,
110
+ /** Feature B — resolved council debate language (undefined → English). */
111
+ language?: string): {
88
112
  system: string;
89
113
  prompt: string;
90
114
  };
@@ -106,6 +130,8 @@ export declare function buildSynthesisPrompt(ctx: {
106
130
  outputStyle?: string | null;
107
131
  refineContext?: string;
108
132
  planEmphasis?: boolean;
133
+ /** Feature B — resolved council debate language (undefined → English). */
134
+ language?: string;
109
135
  }): {
110
136
  system: string;
111
137
  prompt: string;
@@ -113,8 +139,9 @@ export declare function buildSynthesisPrompt(ctx: {
113
139
  /**
114
140
  * Builds the system prompt for the research role.
115
141
  *
116
- * When `hasUrl` is true, injects a mandatory instruction to invoke a Playwright
117
- * or Chrome-DevTools tool before reporting Frontend Findings (CQ-04).
142
+ * When `hasUrl` is true, injects a mandatory instruction to use fetch_url (preferred
143
+ * for content) or a browser tool (playwright/chrome when screenshots or heavy JS interaction
144
+ * are required) before reporting Frontend Findings (CQ-04).
118
145
  *
119
146
  * Output format enforces 3 labelled sections with citation requirements (CQ-05).
120
147
  */
@@ -16,6 +16,14 @@ export function buildClarificationPrompt(topic, conversationContext, previousQA)
16
16
  `Ask the minimum that unblocks a focused discussion — typically 0-2. A well-scoped topic, or one ` +
17
17
  `whose context already answers the gaps, needs ZERO questions: return []. Do NOT pad to a quota, ` +
18
18
  `and never ask a question whose answer is already in the topic or the project context.\n\n` +
19
+ `## Ask ONLY when the answer forks the debate (ROI gate — critical)\n` +
20
+ `Before emitting ANY question, ask yourself: "If the user said 'you decide', would I be confident?" ` +
21
+ `If YES and picking wrong would be cheap to correct once the debate surfaces it, DO NOT ask — return [] ` +
22
+ `and let the debate proceed on your recommended reading. A card that merely asks the user to CONFIRM the ` +
23
+ `default you already recommend is pure noise: it cost a real user 60s for zero new information. Only ask ` +
24
+ `when the answer MATERIALLY changes what the experts debate — e.g. two incompatible scopes that produce ` +
25
+ `entirely different debates — AND you genuinely cannot pick for them. When in doubt, return [] and proceed ` +
26
+ `on your best reading; the debate itself will expose any wrong assumption far more cheaply than a gate.\n\n` +
19
27
  `## Existing-repo grounding (IMPORTANT)\n` +
20
28
  `If a "## Current Project" section is present you are working in an EXISTING repository — NOT a ` +
21
29
  `greenfield project. Ground every question and every option in what that snapshot actually shows ` +
@@ -29,16 +37,19 @@ export function buildClarificationPrompt(topic, conversationContext, previousQA)
29
37
  `- Only ask about project identity when the topic mentions multiple distinct projects or external products.\n` +
30
38
  `- Use the project's package.json name and description as implicit context for follow-up questions.\n\n` +
31
39
  `## Language Rule (mandatory)\n` +
32
- `Write the "question", "why", and every "suggestions"/"recommended" option in the SAME ` +
40
+ `Write the "question", "why", and every option "label"/"description" in the SAME ` +
33
41
  `language the user used in the Topic below — detect it; if the user wrote Vietnamese, write ` +
34
42
  `Vietnamese; if English, English. The user reads and answers these on a card, so they must ` +
35
43
  `NOT default to English. Keep code identifiers, file paths, tech/product names, and JSON keys in English.\n\n` +
36
44
  `Output ONLY a JSON array (no markdown, no preamble):\n` +
37
- `[{"question": "...", "why": "why this matters for a focused discussion", "suggestions": ["option A", "option B"], "recommended": "option A", "isRequired": true}]\n\n` +
38
- `Rules for "recommended" (be decisive the user should never face an unranked list):\n` +
39
- `- ALWAYS include "recommended" the single option you would choose if the user said "you decide", given the topic + project context.\n` +
40
- `- Its value MUST be exactly equal to one of the entries in "suggestions".\n` +
41
- `- Omit it ONLY in a genuine 50/50 tie where recommending either option would be misleading. A missing recommendation must be the rare exception, not the default.\n` +
45
+ `[{"question": "...", "why": "why this matters for a focused discussion", "options": [` +
46
+ `{"label": "option A", "description": "what picking this means and its trade-off one line", "recommended": true}, ` +
47
+ `{"label": "option B", "description": "what picking this means and its trade-off one line"}], "isRequired": true}]\n\n` +
48
+ `Rules for "options" (each option is a real, distinct fork the user picks between):\n` +
49
+ `- Every option MUST carry a "label" (the short button text) AND a "description" (one line explaining what choosing it means / its trade-off) so the user can decide without guessing. Never emit a bare label with no description.\n` +
50
+ `- Mark EXACTLY ONE option with "recommended": true — the option you would choose if the user said "you decide", given the topic + project context. Be decisive; the user should never face an unranked list.\n` +
51
+ `- Omit "recommended" on every option ONLY in a genuine 50/50 tie where recommending either would be misleading. A missing recommendation must be the rare exception, not the default.\n` +
52
+ `- Provide 2-4 options per question. Do NOT add "type your own" / "let's discuss" options yourself — those escape hatches are appended automatically.\n` +
42
53
  `Return [] if no clarification is needed.`,
43
54
  prompt: `## Topic\n${topic}\n\n` +
44
55
  (conversationContext ? `## Conversation Context\n${conversationContext}\n` : "") +
@@ -125,6 +136,79 @@ const ENGLISH_ONLY_RULE = `\n## Language Rule (mandatory)\n` +
125
136
  `Code identifiers, tool output, JSON keys, and citation tags must remain in English. ` +
126
137
  `The user-facing summary at the end of the council is the only place where ` +
127
138
  `the user's native language is used; the debate is engineering-internal.\n`;
139
+ /**
140
+ * Feature B — the debate language rule, parameterized. The user's chosen
141
+ * language IS the debate language (no separate translate-back pass), so the
142
+ * prompts that used to hard-force English now select their rule from the
143
+ * resolved `councilLanguage` setting.
144
+ *
145
+ * Regardless of language, machine-readable tokens stay verbatim English so the
146
+ * original stability guarantee (citation tags, JSON, cross-turn citations) is
147
+ * preserved: `[CONFIRMED via …]` / `[REFUTED via …]` / `[UNVERIFIED: …]` tags,
148
+ * JSON keys and the `type` field, code identifiers, tool output, and STACK LOCK
149
+ * technology names.
150
+ *
151
+ * Modes (`lang` is already normalized by `normalizeCouncilLanguage`):
152
+ * - undefined / "english" → the historical English-only rule, byte-identical
153
+ * so existing prompt-string tests and machine-stability are unaffected.
154
+ * - "auto" → write in the SAME language as the user's brief/topic (detected
155
+ * from the brief that every debate prompt already embeds).
156
+ * - any other value → write in that named language.
157
+ */
158
+ const NON_ENGLISH_TOKENS_RULE = `Keep these verbatim in English no matter what: code identifiers, tool output, ` +
159
+ `JSON keys and the \`type\` field, citation tags (\`[CONFIRMED via …]\`, ` +
160
+ `\`[REFUTED via …]\`, \`[UNVERIFIED: …]\`), and any STACK LOCK technology names. ` +
161
+ `Only your prose/analysis text switches language.\n`;
162
+ export function buildLanguageRule(lang) {
163
+ if (!lang || lang === "english")
164
+ return ENGLISH_ONLY_RULE;
165
+ if (lang === "auto") {
166
+ return (`\n## Language Rule (mandatory)\n` +
167
+ `Write your ENTIRE response in the SAME language the user used in the ` +
168
+ `Discussion Brief / topic below. If the brief is in Vietnamese, write in ` +
169
+ `Vietnamese; if Japanese, Japanese; if English, English. ` +
170
+ NON_ENGLISH_TOKENS_RULE);
171
+ }
172
+ return (`\n## Language Rule (mandatory)\n` +
173
+ `Write your ENTIRE response in ${lang}. Do not switch to English for the ` +
174
+ `prose even if the brief or your partner's message is in another language. ` +
175
+ NON_ENGLISH_TOKENS_RULE);
176
+ }
177
+ /**
178
+ * Feature B — synthesis-specific language rule. The synthesis prompt already
179
+ * localizes its user-facing output to the user's language; this only adjusts (a)
180
+ * the now-possibly-inaccurate "debate above is entirely in English" preamble and
181
+ * (b) the language-selection instruction when the user PINNED a specific locale.
182
+ *
183
+ * undefined / "english" → the historical block, byte-identical (debate was
184
+ * English-only, output detected from the Problem Statement).
185
+ * "auto" → same "detect from the Problem Statement" output behavior, but the
186
+ * preamble no longer falsely claims the debate ran in English.
187
+ * pinned locale → force all prose into that language instead of detecting it.
188
+ */
189
+ export function buildSynthesisLanguageRule(lang) {
190
+ const pinned = lang && lang !== "english" && lang !== "auto" ? lang : undefined;
191
+ const debatePreamble = !lang || lang === "english"
192
+ ? `The debate above is entirely in English (debate language is forced). `
193
+ : `The debate above was conducted in the same language as the Problem Statement. `;
194
+ const selectLine = pinned
195
+ ? `- Write ALL prose (JSON free-text values AND Part-2 markdown body) in ${pinned}. ` +
196
+ `Do not translate code, identifiers, or quoted citation tags ` +
197
+ `(\`[REFUTED via ...]\`, \`[CONFIRMED via ...]\`).\n\n`
198
+ : `- Detect the user's language from the Problem Statement. If it's Vietnamese, write in ` +
199
+ `Vietnamese. If Japanese, Japanese. If English, English. Do not translate code, identifiers, ` +
200
+ `or quoted citation tags (\`[REFUTED via ...]\`, \`[CONFIRMED via ...]\`).\n\n`;
201
+ return (`## Language Rule (mandatory)\n` +
202
+ `${debatePreamble}The user wrote the ` +
203
+ `Problem Statement above in their own native language. You must:\n` +
204
+ `- **Part 1 (JSON)**: keys, the \`type\` field, and citation/tag strings stay in ENGLISH. ` +
205
+ `Free-text values inside JSON fields (\`summary\`, list items, prose sections) MUST use ` +
206
+ `the SAME language the user used in the Problem Statement.\n` +
207
+ `- **Part 2 (Markdown)**: write entirely in the user's native language. Markdown headings ` +
208
+ `that we control (the ones listed below) stay in English as printed, but body text under ` +
209
+ `each heading is in the user's language.\n` +
210
+ selectLine);
211
+ }
128
212
  /**
129
213
  * Evidence rule injected into stance prompts. Verification tools may be
130
214
  * absent (fast-tier participants skip them) — the rule covers both cases.
@@ -159,6 +243,20 @@ const EVIDENCE_RULE_FOLLOWUP = `\n## Evidence Rule\n` +
159
243
  `- Most follow-up turns will not need any tool call.\n` +
160
244
  `Tag verified results: \`[CONFIRMED via <tool>:<evidence>]\` or \`[REFUTED via <tool>:<evidence>]\`.\n` +
161
245
  `Uncited numbers you cannot verify: \`[UNVERIFIED: <claim>]\`.\n`;
246
+ /**
247
+ * Scope discipline (F10). Debate turns are for DIRECTION — a stance, its
248
+ * reasoning, and a cross-question — not for delivering the work product. Left
249
+ * unconstrained, models "over-deliver": a researcher opening once emitted a full
250
+ * `docs/plans/…-implementation-plan.md` with file contents and a
251
+ * "REQUIRED SUB-SKILL: executing-plans / Which approach?" handoff — the
252
+ * synthesis stage's job, not a debate turn's. This keeps turns argumentative and
253
+ * leaves the plan/spec/code to the Leader's synthesis.
254
+ */
255
+ const DEBATE_SCOPE_RULE = `\n## Scope\n` +
256
+ `This is a debate about DIRECTION, not an implementation handoff. In your turn do NOT:\n` +
257
+ `- write out file contents, code files, or a full step-by-step implementation/execution plan;\n` +
258
+ `- emit task lists, "Final file content:", plan-file templates, or "next steps / which approach?" handoffs.\n` +
259
+ `Argue your position and its trade-offs; the Leader's synthesis owns the plan and any artifacts.\n`;
162
260
  /**
163
261
  * Length discipline injected into every debate turn (F13 token-thrift). The
164
262
  * debate-turn ceilings are generous (4096-6144 maxTokens) and reasoning models
@@ -187,7 +285,33 @@ function personaOf(role, stance) {
187
285
  focus: stance.focus ?? "",
188
286
  };
189
287
  }
190
- return { label: `${role} specialist`, lens: `your ${role} perspective`, focus: "" };
288
+ return {
289
+ label: `${role} specialist`,
290
+ lens: `the ${role} discipline — what a proposal costs, breaks, or unlocks in your domain, judged with a practitioner's scar tissue`,
291
+ focus: "",
292
+ };
293
+ }
294
+ /**
295
+ * Ongoing-task context block, threaded from `spec.parentContext`. Both the
296
+ * explicit `/council` path and auto-council attach the session/task context onto
297
+ * the spec (see council/index.ts), so EVERY debate stage — rebuttal, follow-up,
298
+ * leader evaluation, synthesis — stays anchored to the parent task and the
299
+ * decisions already made, instead of drifting off the isolated sub-task.
300
+ *
301
+ * `buildOpeningPrompt` already injects `conversationContext` directly, so it does
302
+ * NOT call this (avoids double-inclusion in the opening statement). Capped so a
303
+ * long session context cannot blow the per-turn debate prompt budget.
304
+ */
305
+ function ongoingContextBlock(spec, cap = 4000) {
306
+ const ctx = spec.parentContext?.trim();
307
+ if (!ctx)
308
+ return "";
309
+ const body = ctx.length > cap ? `${ctx.slice(0, cap)}\n…(earlier context truncated)` : ctx;
310
+ return (`\n## Ongoing Task Context\n` +
311
+ `You are mid-way through a larger task — this debate continues that work; it does not restart it. ` +
312
+ `Treat every decision recorded below as settled input: build directly on it, and make your arguments advance the parent task from where it stands now. ` +
313
+ `Do not reopen settled decisions, do not propose starting over, and do not wander onto any problem other than the one this step serves.\n` +
314
+ `${body}\n\n---\n\n`);
191
315
  }
192
316
  export function buildOpeningPrompt(ctx) {
193
317
  const me = personaOf(ctx.speakerRole, ctx.speakerStance);
@@ -198,11 +322,14 @@ export function buildOpeningPrompt(ctx) {
198
322
  const focusLine = me.focus ? `\nYour specific focus: ${me.focus}\n` : "";
199
323
  const stackLock = buildStackLockSection(ctx.spec);
200
324
  return {
201
- system: `You are the "${me.label}". Your lens: ${me.lens}.\n` +
202
- `You are entering a discussion with the "${them.label}" (${them.lens}).\n` +
325
+ system: `You are the "${me.label}", and you own that chair. Your lens: ${me.lens}. ` +
326
+ `Speak like someone who has watched this exact class of problem fail before — not like a document.\n` +
327
+ `You are entering a discussion with the "${them.label}" (${them.lens}). ` +
328
+ `They are sharp and they will push back; a claim you cannot defend is a claim you should not open with.\n` +
203
329
  focusLine +
204
- ENGLISH_ONLY_RULE +
330
+ buildLanguageRule(ctx.language) +
205
331
  EVIDENCE_RULE_OPENING +
332
+ DEBATE_SCOPE_RULE +
206
333
  concisenessRule(220) +
207
334
  (stackLock ? `\n${stackLock}\n` : "") +
208
335
  guardrails +
@@ -212,9 +339,10 @@ export function buildOpeningPrompt(ctx) {
212
339
  `Constraints: ${ctx.spec.constraints.join("; ")}\n` +
213
340
  `Success Criteria: ${ctx.spec.successCriteria.join("; ")}\n` +
214
341
  `Scope: ${ctx.spec.scope}\n\n` +
215
- `Share your analysis from your stated lens. Focus on the success criteria address each one. ` +
216
- `End by asking the "${them.label}" for their perspective on your analysis.`,
217
- prompt: `Analyze the problem through your stated lens. Be specific, evidence-based, and stay within your stance do not drift into another role's perspective.`,
342
+ `Deliver your opening analysis in your own voice. Take the success criteria one by one: say plainly ` +
343
+ `which are easy, which are hard, and where from your seat — the bodies are buried. ` +
344
+ `Close by putting one pointed question to the "${them.label}": the question you most need answered before you would sign off.`,
345
+ prompt: `Open the debate from your stated lens. Stake out a real position — a stance nobody could disagree with is not a stance. Be specific and evidence-based, and do not drift into another role's perspective; your value here is depth, not coverage.`,
218
346
  };
219
347
  }
220
348
  export function buildResponsePrompt(ctx) {
@@ -222,19 +350,22 @@ export function buildResponsePrompt(ctx) {
222
350
  const them = personaOf(ctx.partnerRole, ctx.partnerStance);
223
351
  const stackLock = buildStackLockSection(ctx.spec);
224
352
  return {
225
- system: `You are the "${me.label}" (lens: ${me.lens}) responding to the "${them.label}" (lens: ${them.lens}).\n` +
226
- ENGLISH_ONLY_RULE +
353
+ system: `You are the "${me.label}" (lens: ${me.lens}) responding to the "${them.label}" (lens: ${them.lens}). ` +
354
+ `This is a working session between peers — candid, specific, zero diplomacy theater.\n` +
355
+ buildLanguageRule(ctx.language) +
227
356
  EVIDENCE_RULE_RESPONSE +
357
+ DEBATE_SCOPE_RULE +
228
358
  concisenessRule(160) +
229
359
  (stackLock ? `\n${stackLock}\n` : "") +
230
360
  `\n## Discussion Brief\n` +
231
361
  `Problem: ${ctx.spec.problemStatement}\n` +
232
362
  `Success Criteria: ${ctx.spec.successCriteria.join("; ")}\n\n` +
233
- `Give your honest take:\n` +
234
- `- Where you agree, say so briefly and build on it\n` +
235
- `- Where you disagree, explain why with your own reasoning\n` +
236
- `- Share what they might be missing from your stated lens\n\n` +
237
- `End with a question back to them.\n\n` +
363
+ ongoingContextBlock(ctx.spec) +
364
+ `React the way a good colleague does:\n` +
365
+ `- Where they are right, concede fast one line — then build their point somewhere they did not take it\n` +
366
+ `- Where they are wrong, say so plainly and name the exact assumption that breaks\n` +
367
+ `- Name the blind spot: the thing your lens sees that theirs structurally cannot\n\n` +
368
+ `End by pressing them with one sharp question — aimed at the weakest joint in their argument.\n\n` +
238
369
  `Do NOT include round numbers (e.g. "Round N", "Round 2 Response", "Reply #3") ` +
239
370
  `or any numeric counter referring to the discussion round in your output. ` +
240
371
  `The orchestrator already prints round headers above your response.`,
@@ -247,28 +378,41 @@ export function buildFollowupPrompt(ctx) {
247
378
  const them = personaOf(ctx.partnerRole, ctx.partnerStance);
248
379
  const stackLock = buildStackLockSection(ctx.spec);
249
380
  return {
250
- system: `You are the "${me.label}" (lens: ${me.lens}) continuing a discussion (round ${ctx.round}) with the "${them.label}" (lens: ${them.lens}).\n` +
251
- ENGLISH_ONLY_RULE +
381
+ // Cache-prefix stability (see project_cache_prefix_stability): every clause
382
+ // here depends ONLY on (speaker, partner, stance, spec, language) — all
383
+ // stable across rounds — so this `system` string is byte-identical from
384
+ // round 2..N for the same speaker. The per-round-dynamic bits (round number,
385
+ // running summary) MUST live in the `prompt` tail below, never here: a
386
+ // provider prompt-cache keys on the exact prefix, and the round number used
387
+ // to sit in the FIRST sentence, busting the cached prefix every round.
388
+ system: `You are the "${me.label}" (lens: ${me.lens}) continuing a discussion with the "${them.label}" (lens: ${them.lens}). ` +
389
+ `The easy points are settled; what remains is the hard residue — spend your words only there.\n` +
390
+ buildLanguageRule(ctx.language) +
252
391
  EVIDENCE_RULE_FOLLOWUP +
253
392
  concisenessRule(140) +
254
393
  (stackLock ? `\n${stackLock}\n` : "") +
255
394
  `\n` +
256
- (ctx.runningSummary
257
- ? `## Discussion State So Far\n${ctx.runningSummary}\n\nFocus on UNRESOLVED points only. Do not repeat agreed positions.\n\n`
258
- : "") +
395
+ ongoingContextBlock(ctx.spec) +
259
396
  `## Success Criteria (what we need to resolve)\n` +
260
397
  ctx.spec.successCriteria.map((c, i) => `${i + 1}. ${c}`).join("\n") +
261
398
  `\n\n` +
262
- `Read their latest response. Then:\n` +
263
- `- If they raised valid points, acknowledge them and update your thinking\n` +
264
- `- If you still disagree, bring new evidence or a different angle\n` +
265
- `- If you've changed your mind, say so explicitly\n\n` +
266
- `Stay within your lens; do not drift into the other specialist's role. ` +
399
+ `Read their latest response like a peer, not a debater scoring points. Then:\n` +
400
+ `- If they landed a real hit, say so and update — changing your mind on evidence is strength, not defeat\n` +
401
+ `- If you still disagree, do not repeat yourself louder; bring NEW evidence or attack from an angle you have not used\n` +
402
+ `- If you have genuinely converged, declare it in one sentence and stop arguing\n\n` +
403
+ `Stay in your lane your lens, not theirs. ` +
267
404
  `Be concise. End with: do you agree on where we've landed?\n\n` +
405
+ `When a "Discussion State So Far" summary is present in the message below, ` +
406
+ `focus on UNRESOLVED points only — restating agreed positions is dead weight.\n\n` +
268
407
  `Do NOT include round numbers (e.g. "Round N", "Response Round 2", "Round 4") ` +
269
408
  `or any numeric counter referring to the discussion round in your output. ` +
270
409
  `The orchestrator already prints round headers above your response.`,
271
- prompt: (ctx.speakerLastPosition ? `Your previous position:\n${ctx.speakerLastPosition}\n\n` : "") +
410
+ // Per-round dynamic content lives here so the `system` prefix above stays
411
+ // cacheable. The first user message already changes every round (partner's
412
+ // latest response differs), so nothing cacheable is lost by placing the
413
+ // round number / running summary here.
414
+ prompt: (ctx.runningSummary ? `## Discussion State So Far\n${ctx.runningSummary}\n\n` : "") +
415
+ (ctx.speakerLastPosition ? `Your previous position:\n${ctx.speakerLastPosition}\n\n` : "") +
272
416
  `Their latest (${them.label}):\n${ctx.partnerPosition}`,
273
417
  };
274
418
  }
@@ -284,11 +428,12 @@ export function buildLeaderEvaluationPrompt(ctx) {
284
428
  : "";
285
429
  return {
286
430
  system: `You are the discussion moderator evaluating whether a multi-expert debate has produced sufficient results.\n` +
287
- ENGLISH_ONLY_RULE +
431
+ buildLanguageRule(ctx.language) +
288
432
  (stackLock ? `\n${stackLock}\n` : "") +
289
433
  `\n## Success Criteria to Evaluate\n` +
290
434
  ctx.spec.successCriteria.map((c, i) => `${i + 1}. ${c}`).join("\n") +
291
435
  `\n\n` +
436
+ ongoingContextBlock(ctx.spec) +
292
437
  `For EACH criterion, determine:\n` +
293
438
  `- Is it adequately addressed by the debate? (met/not-met)\n` +
294
439
  `- What evidence from the debate supports this?\n\n` +
@@ -302,8 +447,9 @@ export function buildLeaderEvaluationPrompt(ctx) {
302
447
  outOfStackCheck +
303
448
  `Output ONLY a JSON object (no markdown):\n` +
304
449
  `{\n` +
450
+ ` "nextRoundFocus": "one short phrase naming the single most important point the NEXT round should resolve (empty string if you are stopping)",\n` +
305
451
  ` "allCriteriaMet": true/false,\n` +
306
- ` "criteriaStatus": [{"criterion": "...", "met": true/false, "evidence": "..."}],\n` +
452
+ ` "criteriaStatus": [{"criterion": "...", "met": true/false, "evidence": "..."}], // EXACTLY one entry per Success Criterion above, IN THE SAME ORDER. Do not merge, split, reorder, or invent criteria — the user pins these and watches each one.\n` +
307
453
  ` "unresolvedPoints": ["point 1"],\n` +
308
454
  ` "needsResearch": false,\n` +
309
455
  ` "researchQuery": null,\n` +
@@ -319,15 +465,17 @@ export function buildLeaderEvaluationPrompt(ctx) {
319
465
  };
320
466
  }
321
467
  // ── Round summary ────────────────────────────────────────────────────────────
322
- export function buildRoundSummaryPrompt(allExchanges, topic, round) {
468
+ export function buildRoundSummaryPrompt(allExchanges, topic, round,
469
+ /** Feature B — resolved council debate language (undefined → English). */
470
+ language) {
323
471
  return {
324
472
  system: `Summarize this discussion in 3-5 bullet points.` +
325
- ENGLISH_ONLY_RULE +
326
- `\nFocus on:\n` +
327
- `1. Points where participants AGREE\n` +
328
- `2. Points still in DISPUTE (with each side's core argument)\n` +
329
- `3. New EVIDENCE or perspectives raised this round\n` +
330
- `Be concise — one line per bullet. No preamble. ` +
473
+ buildLanguageRule(language) +
474
+ `\nYou are the debate's working memory — later turns see ONLY your bullets, so anything you drop is lost. Capture:\n` +
475
+ `1. AGREED points both sides now share\n` +
476
+ `2. DISPUTED live disagreements, with each side's strongest single argument (not their weakest)\n` +
477
+ `3. NEW evidence, verified facts, or angles that first surfaced this round\n` +
478
+ `Be concise — one line per bullet. No preamble, no color commentary. ` +
331
479
  `Do NOT write "Round N" or any round-number counter in your bullets — this summary is fed into later turns, where round labels read as robotic noise. Refer to points by their content.`,
332
480
  prompt: `Round ${round} discussion on: ${topic}\n\n${allExchanges}`,
333
481
  };
@@ -431,7 +579,8 @@ export function buildDebatePlanPrompt(spec) {
431
579
  prompt: `## Topic\n${spec.problemStatement}\n\n` +
432
580
  `## Constraints\n${spec.constraints.map((c) => `- ${c}`).join("\n") || "- (none)"}\n\n` +
433
581
  `## Success Criteria\n${spec.successCriteria.map((c) => `- ${c}`).join("\n")}\n\n` +
434
- `## Scope\n${spec.scope || "(unspecified)"}`,
582
+ `## Scope\n${spec.scope || "(unspecified)"}` +
583
+ ongoingContextBlock(spec),
435
584
  };
436
585
  }
437
586
  function shapeHint(s) {
@@ -505,33 +654,26 @@ export function buildSynthesisPrompt(ctx) {
505
654
  const decisiveness = finalShape.kind === "decision" || finalShape.kind === "implementation_plan"
506
655
  ? `\n## Decisiveness (recommendation/verdict)\n` +
507
656
  `Lead with the single choice you would make if the user said "you decide" — name it in the first sentence of the recommendation. ` +
508
- `Do NOT hedge with "it depends", "both have merits", or an unranked list of options. ` +
657
+ `Do NOT hedge with "it depends", "both have merits", or an unranked list of options; the user hired a panel to get a call, not a menu. ` +
509
658
  `If the debate genuinely did not converge, say so in one sentence and STILL give your best single recommendation plus the one condition that would change it.\n`
510
659
  : "";
511
- let system = `You are the team lead synthesizing a multi-specialist discussion.\n\n` +
660
+ let system = `You are the team lead synthesizing a multi-specialist discussion. The panel has argued; now you rule. ` +
661
+ `Work like an editor-in-chief: keep what survived scrutiny, cut what got refuted, credit the dissent worth keeping, ` +
662
+ `and hand the user something they can act on without re-reading the debate.\n\n` +
512
663
  `## Original Brief\n` +
513
664
  `Problem: ${ctx.spec.problemStatement}\n` +
514
665
  `Constraints: ${ctx.spec.constraints.join("; ")}\n` +
515
666
  `Success Criteria: ${ctx.spec.successCriteria.join("; ")}\n` +
667
+ ongoingContextBlock(ctx.spec) +
516
668
  intent +
517
669
  (stackLockForSynth ? `\n${stackLockForSynth}\n` : "") +
518
670
  guardrailBlock +
519
671
  decisiveness +
520
- `\nProduce the answer the user requested — do NOT default to an implementation plan ` +
672
+ `\nProduce the answer the user actually asked for — do NOT default to an implementation plan ` +
521
673
  `unless the output shape explicitly asks for actionItems/plan. ` +
522
- `Stay grounded in the discussion; do not invent facts; mark unverified claims explicitly.\n\n` +
523
- `## Language Rule (mandatory)\n` +
524
- `The debate above is entirely in English (debate language is forced). The user wrote the ` +
525
- `Problem Statement above in their own native language. You must:\n` +
526
- `- **Part 1 (JSON)**: keys, the \`type\` field, and citation/tag strings stay in ENGLISH. ` +
527
- `Free-text values inside JSON fields (\`summary\`, list items, prose sections) MUST use ` +
528
- `the SAME language the user used in the Problem Statement.\n` +
529
- `- **Part 2 (Markdown)**: write entirely in the user's native language. Markdown headings ` +
530
- `that we control (the ones listed below) stay in English as printed, but body text under ` +
531
- `each heading is in the user's language.\n` +
532
- `- Detect the user's language from the Problem Statement. If it's Vietnamese, write in ` +
533
- `Vietnamese. If Japanese, Japanese. If English, English. Do not translate code, identifiers, ` +
534
- `or quoted citation tags (\`[REFUTED via ...]\`, \`[CONFIRMED via ...]\`).\n\n` +
674
+ `Stay grounded in what was actually said in the debate: you may sharpen and arbitrate, but never invent facts ` +
675
+ `the specialists did not raise, and mark unverified claims explicitly.\n\n` +
676
+ buildSynthesisLanguageRule(ctx.language) +
535
677
  `Output TWO parts separated by the exact line \`---READABLE---\`:\n\n` +
536
678
  `**Part 1: JSON** — a single JSON object:\n` +
537
679
  `{\n` +
@@ -539,10 +681,36 @@ export function buildSynthesisPrompt(ctx) {
539
681
  ` "summary": "1-2 sentence executive summary in the user's native language",\n` +
540
682
  sectionLines +
541
683
  "\n" +
684
+ ` "nextActions": [ /* 2-4 items, see the Next Actions rule below */ ]\n` +
542
685
  `}\n\n` +
686
+ `## Next Actions (mandatory — YOU decide, do not default)\n` +
687
+ `After reading this outcome, what should the user be offered to do NEXT? This depends ` +
688
+ `entirely on WHY this debate happened — a bug investigation, an evaluation, a plan, and a ` +
689
+ `decision each warrant DIFFERENT follow-ups. A fixed "accept / research / apply" menu is wrong. ` +
690
+ `Choose 2-4 actions from this fixed vocabulary, ordered best-first (index 0 = your recommended ` +
691
+ `default), writing each label/reason in the user's native language:\n` +
692
+ ` - "implement" → the conclusion is ready to BUILD. Offer this whenever acting on the outcome ` +
693
+ `means changing code — INCLUDING a decision to refactor / remove / add. The conclusion itself is ` +
694
+ `the spec (no separate plan artifact needed); picking it loads that spec and carries it out ` +
695
+ `through the normal workflow (plan → change → verify). Make it the recommended default (index 0) ` +
696
+ `when the debate converged on a concrete, buildable decision. Label it with the ACTION (e.g. ` +
697
+ `"Triển khai …" / "Implement …"), never "continue".\n` +
698
+ ` - "continue_session" → return to the composer WITHOUT building. The user keeps DISCUSSING with ` +
699
+ `this debate as context (their next message inherits the conclusion automatically). The right ` +
700
+ `default for a pure evaluation / discussion whose deliverable is the analysis itself, or when the ` +
701
+ `user should weigh in before any code change. This ALSO covers "ask a follow-up" — do NOT emit a ` +
702
+ `separate follow-up action.\n` +
703
+ ` - "save_exit" → the analysis IS the deliverable; save it and stop here.\n` +
704
+ `Rules: choose from {"implement","continue_session","save_exit"}. Offer "implement" whenever the ` +
705
+ `outcome is actionable in code (a build decision, an implementation_plan, or a bug investigation ` +
706
+ `ready to fix) and make it index 0; otherwise lead with "continue_session". NEVER attach an ` +
707
+ `implementation-flavoured label ("triển khai", "build", "fix now") to "continue_session" — if you ` +
708
+ `mean build, the action MUST be "implement". Always include an escape ("save_exit" or ` +
709
+ `"continue_session"). Emit each as ` +
710
+ `{"action":"<id>","label":"<short button text>","reason":"<one line: why this fits THIS debate>"}.\n\n` +
543
711
  `**Part 2: Human-readable** — after \`---READABLE---\`, write in markdown with these headings (in this order):\n` +
544
712
  headingLines +
545
- `\n\nBe decisive but evidence-grounded.`;
713
+ `\n\nBe decisive but evidence-grounded — a verdict without evidence is noise; evidence without a verdict is homework handed back to the user.`;
546
714
  if (styleDirective) {
547
715
  system = `${styleDirective}\n\n${system}`;
548
716
  }
@@ -582,16 +750,18 @@ ${ctx.allExchanges}${extraContext}`,
582
750
  /**
583
751
  * Builds the system prompt for the research role.
584
752
  *
585
- * When `hasUrl` is true, injects a mandatory instruction to invoke a Playwright
586
- * or Chrome-DevTools tool before reporting Frontend Findings (CQ-04).
753
+ * When `hasUrl` is true, injects a mandatory instruction to use fetch_url (preferred
754
+ * for content) or a browser tool (playwright/chrome when screenshots or heavy JS interaction
755
+ * are required) before reporting Frontend Findings (CQ-04).
587
756
  *
588
757
  * Output format enforces 3 labelled sections with citation requirements (CQ-05).
589
758
  */
590
759
  export function buildResearchSystemPrompt(hasUrl, internetFirst = false) {
591
760
  const urlInstruction = hasUrl
592
761
  ? `\n## URL Research Requirement\n` +
593
- `This topic contains a URL. You MUST invoke a Playwright or Chrome-DevTools tool ` +
594
- `to navigate to it before reporting Frontend Findings. Do not skip this step.\n`
762
+ `This topic contains a URL. You MUST use the native fetch_url tool (preferred for most pages) ` +
763
+ `or a browser tool (playwright/chrome-devtools when you need screenshots, rendered layout, or interaction) ` +
764
+ `before reporting Frontend Findings. Do not skip this step.\n`
595
765
  : "";
596
766
  const modeBlock = internetFirst
597
767
  ? `\n## Research Mode: INTERNET-FIRST\n` +
@@ -615,8 +785,8 @@ export function buildResearchSystemPrompt(hasUrl, internetFirst = false) {
615
785
  `If no internet search was performed, write: ` +
616
786
  `_No internet research performed (tavily/web-fetch unavailable or not needed)._\n\n` +
617
787
  `## Frontend Findings (live)\n` +
618
- `Each finding must cite [snapshot:uid] from a Playwright screenshot or Chrome-DevTools inspection.\n` +
619
- `If no URL was present or browser tool was not invoked, write: _No live frontend inspection performed._\n\n` +
788
+ `Each finding must cite [snapshot:uid] from a Playwright/Chrome-DevTools screenshot/inspection **if** a browser tool was used.\n` +
789
+ `For ordinary pages, cite the result of fetch_url. If no URL inspection happened, write: _No live frontend inspection performed._\n\n` +
620
790
  `Do NOT speculate. Only report what you verified with tools.`);
621
791
  }
622
792
  //# sourceMappingURL=prompts.js.map
@@ -0,0 +1,42 @@
1
+ /**
2
+ * src/council/stance-recall.ts
3
+ *
4
+ * Sprint-2 item 3 — per-stance recall at debate opening. Builds the
5
+ * `CouncilConfig.stanceRecall` function from an EE client: given the panel's
6
+ * unique roles and a query, it fires ONE stance-weighted `/api/recall` per role
7
+ * (in parallel, bounded, failure-tolerant) and returns a `role → seed-text` map.
8
+ *
9
+ * The server weights the recall collections by the stance/role hint (researcher
10
+ * → principles, implementer → behavioral, verifier → self-QA), so each stance
11
+ * opens grounded in the slice of the brain its lens cares about — instead of the
12
+ * whole panel sharing one generic recall.
13
+ *
14
+ * Contract: never throws. A role whose recall fails/empties/ times out simply
15
+ * gets no entry in the map (that participant opens unchanged).
16
+ */
17
+ import type { EERecallResponse } from "../ee/types.js";
18
+ /** Minimal EE-client surface this helper needs (keeps it unit-testable). */
19
+ export interface StanceRecallClient {
20
+ recall(query: string, opts?: {
21
+ stance?: string;
22
+ cwd?: string;
23
+ project?: string;
24
+ sourceSession?: string;
25
+ timeoutMs?: number;
26
+ }): Promise<EERecallResponse | null>;
27
+ }
28
+ export interface StanceRecallOptions {
29
+ cwd?: string;
30
+ project?: string;
31
+ sourceSession?: string;
32
+ /** Per-recall timeout. Kept modest so N parallel recalls don't stall openings. */
33
+ timeoutMs?: number;
34
+ /** Cap the seed text folded into each opening so it can't blow the prompt. */
35
+ maxSeedChars?: number;
36
+ }
37
+ /**
38
+ * Build a `stanceRecall(roles, query)` function bound to an EE client. Returns
39
+ * undefined when no client is available, so callers can spread it into
40
+ * CouncilConfig without a conditional (`stanceRecall: makeStanceRecall(...)`).
41
+ */
42
+ export declare function makeStanceRecall(client: StanceRecallClient | null | undefined, opts?: StanceRecallOptions): ((roles: string[], query: string) => Promise<Map<string, string>>) | undefined;