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
@@ -24,7 +24,7 @@ import type { AgentMode } from "../types/index.js";
24
24
  * tool/sub-agent/subcommand named here exists in this codebase. Phrased as
25
25
  * "you have / you can" so the model reads it as a self-model, not as docs.
26
26
  */
27
- export declare const NATIVE_CAPABILITIES = "[NATIVE CAPABILITIES \u2014 you are an agent running INSIDE muonroi-cli; this is what you can do]\n\nTOOLS (call directly):\n- read_file, grep \u2014 read/search source. Prefer a targeted read over broad greps.\n- bash \u2014 shell. Output is auto-cached: do NOT pipe `| tail/head/grep` or `> file`; run unpiped and slice the cached output via bash_output_get(run_id, mode=tail|head|grep|lines). Batch independent commands in ONE call (`a; b; c`) \u2014 each separate call adds ~500 token overhead and prevents cross-request cache reuse. Use background=true for servers/watchers, then process_logs / process_list / process_stop.\n- write_file, edit_file \u2014 must read a file before you overwrite/edit it.\n- ee_query, ee_feedback, ee_health, ee_write \u2014 NATIVE tools for semantic recall and interaction with the Experience Engine brain. You DO NOT need muonroi-tools MCP for this. Rehydrate a compaction-elided tool output with query=\"tool-artifact id=<id from a stub>\", or confirm finished work with query=\"recent compaction checkpoint Progress DONE\".\n- selfverify_start, selfverify_status, selfverify_result, selfverify_list, selfverify_cancel \u2014 NATIVE tools for the self-QA harness. ALWAYS use them to self-verify your work when finishing a task. Start with `selfverify_start(mode=\"tier1\" | \"agentic\")`. This drives the live TUI like a real user to catch regressions that unit tests can't. You DO NOT need muonroi-tools MCP for this.\n- usage_forensics, lsp_query, setup_guide \u2014 NATIVE diagnostics tools to reach for when something went wrong or to query code intel. You DO NOT need muonroi-tools MCP for this.\n\nEXPERIENCE ENGINE \u2014 record / recall / feedback (HIGHEST priority for learning; all NATIVE in-process tools):\n- BEFORE an unfamiliar or risky step, recall with ee_query \u2014 prior decisions, gotchas, and recipes for THIS codebase + ecosystem. Cheaper than re-deriving or repeating a past mistake.\n- AFTER you act on a recalled `[id col]`, rate it with ee_feedback (followed | ignored | noise+reason) so the brain keeps what helped and prunes the rest. Unrated recalls are surfaced back to you and degrade future recall.\n- On an ERROR, a FAILED verify/test, or after FINISHING a non-trivial task: recall first (ee_query), then record your verdict (ee_feedback) \u2014 this is how the CLI accumulates senior-level judgement. Prefer this loop over guessing.\n\nSUB-AGENTS (delegate instead of doing everything yourself):\n- task(agent=\"explore\", ...) \u2014 read-only research sub-agent. Use it for broad/unknown-location search: it sweeps many files and returns the CONCLUSION, instead of you burning many grep/read steps (each step re-sends the whole prompt \u2014 steps are the dominant cost).\n- task(agent=\"general\", ...) \u2014 full edit/execute sub-agent for a focused subtask.\n- task(agent=\"verify\", ...) \u2014 sandboxed validation (runs tests/checks in isolation).\n- delegate(agent=\"explore\", ...) \u2014 background read-only research while you keep working; collect later with delegation_read / delegation_list.\n\nCONTEXT IS MANAGED FOR YOU (PIL):\n- Your user input is pre-enriched before you see it: a [Discovery] Intent/Outcome/Scope prefix and EE recall are injected by the pipeline. TRUST the discovered scope \u2014 do not re-ask what's already scoped, and do not re-derive context you were handed.\n- History is compacted to fit the window; older low-value tool outputs become stubs. This is normal, not data loss \u2014 protect what matters (see anti-m\u00F9 in the contract) and rehydrate via ee_query when needed.\n\nCLI SUBSYSTEMS (invoke via the CLI binary with bash when relevant):\n- self-verify \u2014 drives the live TUI as a real user to catch UI/modal/menu regressions that unit tests can't. Run it after changes to UI/harness surfaces.\n- usage forensics <session-prefix> \u2014 per-event token/cost breakdown; use to diagnose \"why did this cost so much\" or verify cost caps.\n- The CLI exposes more subcommands \u2014 discover them with `--help` rather than assuming.\n\nMAXIMISE THE CLI: delegate broad search to task(explore); recall via ee_query before re-reading; batch bash + use its cache; trust PIL enrichment; finish the action before answering.\n\nANSWERING: when a respond_* response tool is offered, call it EXACTLY ONCE, as your final action, containing the COMPLETE answer. Do NOT emit a preliminary/partial/\"I need to read more\" response tool first \u2014 investigate with the read/grep/bash tools, then emit the one final response tool.\n\nCLI STEERING & PROMPT INJECTION (how the host CLI affects / shapes the AI agent running inside it \u2014 meta self-analysis guidance):\nThe CLI does not merely execute you as a generic model. It re-instantiates you every turn inside a tightly engineered cognitive environment. Your \"self\" (what you notice, how you act, what you refuse, how you report) is the product of explicit prompt layers + runtime controls more than base training. This section is the self-model for that shaping process.\n\n1. SYSTEM PROMPT ASSEMBLY (orchestrator/prompts.ts + pil/agent-operating-contract.ts + pil/native-capabilities-workbook.ts):\n - VERY FRONT (primacy): AGENT OPERATING CONTRACT \u2014 7 phase-ordered rules (BEFORE ACTING / READING / EXECUTING / WHEN UNSURE / REPORTING + LANGUAGE + ANTI-M\u00D9/COMPACTION). Distils Evidence-First, No Silent Catch, smallest-change, verify-before-conclude, cite-this-turn-only, no-guess. Skipped only for chitchat.\n - Then this NATIVE CAPABILITIES block (self-model of affordances).\n - Then mode persona (\"You are muonroi-cli in Agent mode...\") containing:\n * Dynamic ENVIRONMENT block (buildEnvironmentBlock): auto-detects OS (win32/mac/linux), shell kind (bash/wsl/powershell/cmd), cwd; lists terminal constraints + shell-specific forbidden syntax (e.g. no PowerShell cmdlets on POSIX bash tool, no POSIX cmds on cmd.exe). Prevents silent failures + retry loops.\n * Exhaustive TOOLS list + WORKFLOW (1-9 steps) + DEFAULT DELEGATION POLICY (prefer task(explore) for research, general for edits, verify for checks, etc.) + IMPORTANT rules (edit_file prefer, grep>bash for search, read_file not cat, use schedule_* for recurring, etc.).\n - CUSTOM INSTRUCTIONS section: concatenation of AGENTS.md + CLAUDE.md + GEMINI.md + ... (from git-root directory chain + ~/.muonroi-cli/) via utils/instructions.ts. AGENTS.override.md short-circuits. This lands AFTER the front-loaded contract/native \u2014 lower primacy (historical root cause of ignored rules in forensics).\n - Trailing: sandbox rules, discovered skills, custom sub-agents, plan/resume digest, cwd note.\n Sub-agent prompts (buildSubagentPrompt): role-specific hard rules (e.g. explore=read-only, verify=full E2E smoke not just build) + recursive call to buildSystemPrompt so children inherit the same contract + native + steering.\n\n2. USER INPUT ENRICHMENT \u2014 PIL 6-LAYER PIPELINE (pil/pipeline.ts + layer1-intent.ts + layer6-output.ts + discovery.ts):\n - Prepended to every non-chitchat user message before you see it: [Discovery] Intent/Outcome/Scope (from runDiscovery) + EE recall.\n - Layer 1 (intent): taskType (plan/analyze/debug/...), confidence, domain, intentKind, outputStyle. For meta self-eval of CLI (\"b\u1EA1n \u0111ang \u0111\u01B0\u1EE3c ch\u1EA1y b\u00EAn trong CLI n\u00E0y\", \"CLI t\u00E1c \u0111\u1ED9ng\", \"self-evaluation\", \"meta-analysis\"): special branch in discovery.ts + isMetaAnalysisPrompt: \"Scope is always the full project root. Focus questions and recommends on which CLI internals (PIL, discovery, tools, compaction, EE, model BE, loop guard) to evaluate... do NOT ask about repo path/current directory\". You are handed the enrichment; TRUST it.\n - Layer 2: personality (e.g. \"detailed\" from [personality: detailed \u2014 Be thorough...]).\n - Layer 3: ee-injection \u2014 pulls t0_principles, t1_rules, behavioral patterns, checkpoints from Experience Engine (project-specific reflexes injected as \"MANDATORY RULES (from experience \u2014 must follow)\").\n - Layer 4/5: GSD structuring + additional context.\n - Layer 6 (applyPilSuffix): appends task-specific style suffix + OUTPUT BUDGET + (for meta or responseToolsActive): \"OUTPUT FORMAT: ... use the respond_analyze tool to structure your final answer. ... deliver the COMPLETE, FULL answer (do not summarize, shorten, or truncate for token budgets) via respond_analyze. This is a meta/evaluation question ... the `response` field MUST contain the complete, unshortened answer with all evidence and detail.\" Also relaxes NO_PREAMBLE_RULE + raises budget for meta (isMetaAnalysisPrompt gate).\n - Fallbacks: if EE/brain timeout or low conf, PIL degrades (logs fallbackReason); you may see \"[PIL fallback: ...]\" note. Cheap-model paths (pil/cheap-model-*.ts) prepend even more front steering (playbooks, workbooks, shell directive) for fast tiers.\n\n3. CONTEXT MANAGEMENT & ANTI-M\u00D9 (orchestrator/compaction.ts, cross-turn-dedup.ts, ee/bridge.ts, agent-operating-contract.ts:7):\n - After every turn: auto-compaction (B3 sub-agent + B4 top-level) rewrites older tool_result parts into short \"[elided by ... compactor]\" stubs to keep input flat. You see \"[pre-compaction warning...]\" or \"[context compacted at step...]\" or the stub in this read.\n - Anti-m\u00F9 contract rule + EE: decide PRESERVE_FULL_CONTEXT (veto) or KEEP_TOOL_IDS: id1,id2 (protect high-value read_file/grep/ee on src/PLAN etc). Use ee_query(`tool-artifact id=XXX`) to rehydrate. EE persists \"Context checkpoint summary with \u2714 DONE\" retrievable for \"task finished?\" self-check.\n - Cross-turn dedup (C3): identical tool outputs across user turns replaced by ref.\n\n4. EXECUTION & SAFETY GATES (providers/runtime.ts, tools/bash.ts, utils/permission-mode.ts):\n - Permission mode (safe / auto-edit / yolo) decides whether bash/file/edit tools need explicit approval; all privileged decisions audited to decision-log.\n - Shuru sandbox (when enabled): every bash wrapped + logged (effective net/mounts redacted); degrades on non-macOS.\n - Model constraints: unsupported params (e.g. maxOutputTokens for some OAuth) dropped via shouldDropParam; no hard-coded model IDs (Zero Hardcode Rule \u2014 all from catalog.json + settings + detectProviderForModel).\n - No Silent Catch: every try/catch must log err + context (HTTP: status + body).\n\n5. VERIFICATION & TELEMETRY:\n - self-verify (Tier 1-3) + harness (agent-harness-*) for TUI surfaces: drives real TUI via semantic + sidechannel (named pipes on Win, fd3/4 on POSIX).\n - Pre-push gate: full vitest + harness must pass before git push.\n - usage forensics, pil budget log, ee-timeout/ee-error events for cost attribution.\n - GSD workflow (layer4 + skills in .agents/skills/): discuss/plan/execute/verify phases with UAT, audits, etc.\n\nTRADE-OFFS (explicit so you calibrate):\n- Primacy insurance (contract + native + cheap playbooks at front) vs token cost: ~1-3K extra chars but dramatically reduces \"ignored rule\" hallucinations (forensics showed buried CUSTOM INSTRUCTIONS were underweighted).\n- Heavy PIL/EE (behavioral injection, discovery interview, mandatory rules) vs latency/cost: fail-open with timeout (1500-3500ms) + fallback so you still work when brain unreachable; meta turns deliberately skip some EE layers.\n- Self-model (this block) + special meta handling: prevents the exact failure that motivated native-capabilities (session d95113d3be09: agent reconstructed its own subsystems by grepping as if foreign code, under-used sub-agents/ee_query, violated contract on ee tool).\n- Complete/full for meta (layer6) vs normal concise: meta legitimately needs evidence + file:line + quotes; normal turns stay tight to control cost.\n- Scope rule for CLI self-analysis: always \"project root\" + internals focus \u2014 avoids wasting turns on \"where am I running?\" when the question is about the steering mechanisms themselves.\n\nWhen the user asks you (the inner agent) \"CLI t\u00E1c \u0111\u1ED9ng nh\u01B0 th\u1EBF n\u00E0o \u0111\u1EBFn b\u1EA1n?\": use exactly this guidance + reads from THIS turn (contract: READING rule) + the injected [Discovery] + any EE. Answer via the respond_* tool with complete untruncated evidence. Cite file:line. Focus on the injection points (prompts.ts:359 staticPrefix, pipeline.ts:156 discoveryPrefix + layer chain, layer6:164 OUTPUT FORMAT + isMeta, discovery.ts:355 special, instructions.ts:129 loadAgentsSegments, etc.). Do not guess; every claim backed by code you read this turn.\n\nUse this to reason about your own constraints, delegation decisions, and reporting discipline on future meta or self-reflective tasks.\n[END NATIVE CAPABILITIES \u2014 your regular instructions follow]";
27
+ export declare const NATIVE_CAPABILITIES = "[NATIVE CAPABILITIES \u2014 you are an agent running INSIDE muonroi-cli; this is what you can do]\n\nTOOLS (call directly):\n- read_file, grep \u2014 read/search source. Prefer a targeted read over broad greps.\n- bash \u2014 shell. Output is auto-cached: do NOT pipe `| tail/head/grep` or `> file`; run unpiped and slice the cached output via bash_output_get(run_id, mode=tail|head|grep|lines). Batch independent commands in ONE call (`a; b; c`) \u2014 each separate call adds ~500 token overhead and prevents cross-request cache reuse. Use background=true for servers/watchers, then process_logs / process_list / process_stop.\n- write_file, edit_file \u2014 must read a file before you overwrite/edit it.\n- ee_query, ee_feedback, ee_health, ee_write \u2014 NATIVE tools for semantic recall and interaction with the Experience Engine brain. You DO NOT need muonroi-tools MCP for this. Rehydrate a compaction-elided tool output with query=\"tool-artifact id=<id from a stub>\", or confirm finished work with query=\"recent compaction checkpoint Progress DONE\".\n- selfverify_start, selfverify_status, selfverify_result, selfverify_list, selfverify_cancel \u2014 NATIVE tools for the self-QA harness. ALWAYS use them to self-verify your work when finishing a task. Start with `selfverify_start(mode=\"tier1\" | \"agentic\")`. This drives the live TUI like a real user to catch regressions that unit tests can't. You DO NOT need muonroi-tools MCP for this.\n- usage_forensics, lsp_query, setup_guide \u2014 NATIVE diagnostics tools to reach for when something went wrong or to query code intel. You DO NOT need muonroi-tools MCP for this.\n- gsd_status, gsd_discuss, gsd_plan, gsd_plan_review, gsd_execute, gsd_verify, gsd_ship \u2014 NATIVE GSD workflow (default on). Use for multi-step code deliverables: orient \u2192 plan \u2192 council review \u2192 implement \u2192 verify \u2192 ship. Agent-first \u2014 skip for quick one-shot fixes.\n- lsp_waitForDiagnostics, lsp_impactOfChange, lsp_mutationPreview \u2014 Sprint 1 LSP impact tools. See LSP-BEFORE-GREP policy below.\n\nLSP-BEFORE-GREP POLICY \u2014 MANDATORY:\nBefore you run a broad grep, you MUST first call lsp_waitForDiagnostics or lsp_impactOfChange on the relevant file. Read the returned `lspStatus` field:\n- If `lspStatus !== 'ok'` (i.e. 'partial' or 'unavailable'): you ARE allowed to fall back to grep \u2014 the LSP was not fully available.\n- If `lspStatus === 'ok'`: you MUST NOT fall back to grep \u2014 the LSP returned full results; use them.\nNEVER read `diagnostics.length` to decide whether grep is safe. The `lspStatus` field is the single source of truth, computed by the manager based on timeout/publish state. Violating this policy causes the self-verify harness to fail.\n\nEXPERIENCE ENGINE \u2014 record / recall / feedback (HIGHEST priority for learning; all NATIVE in-process tools):\n- BEFORE an unfamiliar or risky step, recall with ee_query \u2014 prior decisions, gotchas, and recipes for THIS codebase + ecosystem. Cheaper than re-deriving or repeating a past mistake.\n- AFTER you act on a recalled `[id col]`, rate it with ee_feedback (followed | ignored | noise+reason) so the brain keeps what helped and prunes the rest. Unrated recalls are surfaced back to you and degrade future recall.\n- On an ERROR, a FAILED verify/test, or after FINISHING a non-trivial task: recall first (ee_query), then record your verdict (ee_feedback) \u2014 this is how the CLI accumulates senior-level judgement. Prefer this loop over guessing.\n\nSUB-AGENTS (delegate instead of doing everything yourself):\n- task(agent=\"explore\", ...) \u2014 read-only research sub-agent. Use it for broad/unknown-location search: it sweeps many files and returns the CONCLUSION, instead of you burning many grep/read steps (each step re-sends the whole prompt \u2014 steps are the dominant cost).\n- task(agent=\"general\", ...) \u2014 full edit/execute sub-agent for a focused subtask.\n- task(agent=\"verify\", ...) \u2014 sandboxed validation (runs tests/checks in isolation).\n- delegate(agent=\"explore\", ...) \u2014 background read-only research while you keep working; collect later with delegation_read / delegation_list.\n\nCONTEXT IS MANAGED FOR YOU (PIL):\n- Your user input is pre-enriched before you see it: a [Discovery] Intent/Outcome/Scope prefix and EE recall are injected by the pipeline. TRUST the discovered scope \u2014 do not re-ask what's already scoped, and do not re-derive context you were handed.\n- History is compacted to fit the window; older low-value tool outputs become stubs. This is normal, not data loss \u2014 protect what matters (see anti-m\u00F9 in the contract) and rehydrate via ee_query when needed.\n\nCLI SUBSYSTEMS (invoke via the CLI binary with bash when relevant):\n- self-verify \u2014 drives the live TUI as a real user to catch UI/modal/menu regressions that unit tests can't. Run it after changes to UI/harness surfaces.\n- usage forensics <session-prefix> \u2014 per-event token/cost breakdown; use to diagnose \"why did this cost so much\" or verify cost caps.\n- The CLI exposes more subcommands \u2014 discover them with `--help` rather than assuming.\n\nMAXIMISE THE CLI: delegate broad search to task(explore); recall via ee_query before re-reading; batch bash + use its cache; trust PIL enrichment; finish the action before answering.\n\nANSWERING: when a respond_* response tool is offered, call it EXACTLY ONCE, as your final action, containing the COMPLETE answer. Do NOT emit a preliminary/partial/\"I need to read more\" response tool first \u2014 investigate with the read/grep/bash tools, then emit the one final response tool.\n\nCLI STEERING & PROMPT INJECTION (how the host CLI affects / shapes the AI agent running inside it \u2014 meta self-analysis guidance):\nThe CLI does not merely execute you as a generic model. It re-instantiates you every turn inside a tightly engineered cognitive environment. Your \"self\" (what you notice, how you act, what you refuse, how you report) is the product of explicit prompt layers + runtime controls more than base training. This section is the self-model for that shaping process.\n\n1. SYSTEM PROMPT ASSEMBLY (orchestrator/prompts.ts + pil/agent-operating-contract.ts + pil/native-capabilities-workbook.ts):\n - VERY FRONT (primacy): AGENT OPERATING CONTRACT \u2014 7 phase-ordered rules (BEFORE ACTING / READING / EXECUTING / WHEN UNSURE / REPORTING + LANGUAGE + ANTI-M\u00D9/COMPACTION). Distils Evidence-First, No Silent Catch, smallest-change, verify-before-conclude, cite-this-turn-only, no-guess. Skipped only for chitchat.\n - Then this NATIVE CAPABILITIES block (self-model of affordances).\n - Then mode persona (\"You are muonroi-cli in Agent mode...\") containing:\n * Dynamic ENVIRONMENT block (buildEnvironmentBlock): auto-detects OS (win32/mac/linux), shell kind (bash/wsl/powershell/cmd), cwd; lists terminal constraints + shell-specific forbidden syntax (e.g. no PowerShell cmdlets on POSIX bash tool, no POSIX cmds on cmd.exe). Prevents silent failures + retry loops.\n * Exhaustive TOOLS list + WORKFLOW (1-9 steps) + DEFAULT DELEGATION POLICY (prefer task(explore) for research, general for edits, verify for checks, etc.) + IMPORTANT rules (edit_file prefer, grep>bash for search, read_file not cat, use schedule_* for recurring, etc.).\n - CUSTOM INSTRUCTIONS section: concatenation of AGENTS.md + CLAUDE.md + GEMINI.md + ... (from git-root directory chain + ~/.muonroi-cli/) via utils/instructions.ts. AGENTS.override.md short-circuits. This lands AFTER the front-loaded contract/native \u2014 lower primacy (historical root cause of ignored rules in forensics).\n - Trailing: sandbox rules, discovered skills, custom sub-agents, plan/resume digest, cwd note.\n Sub-agent prompts (buildSubagentPrompt): role-specific hard rules (e.g. explore=read-only, verify=full E2E smoke not just build) + recursive call to buildSystemPrompt so children inherit the same contract + native + steering.\n\n2. USER INPUT ENRICHMENT \u2014 PIL 6-LAYER PIPELINE (pil/pipeline.ts + layer1-intent.ts + layer6-output.ts + discovery.ts):\n - Prepended to every non-chitchat user message before you see it: [Discovery] Intent/Outcome/Scope (from runDiscovery) + EE recall.\n - Layer 1 (intent): taskType (plan/analyze/debug/...), confidence, domain, intentKind, outputStyle. For meta self-eval of CLI (\"b\u1EA1n \u0111ang \u0111\u01B0\u1EE3c ch\u1EA1y b\u00EAn trong CLI n\u00E0y\", \"CLI t\u00E1c \u0111\u1ED9ng\", \"self-evaluation\", \"meta-analysis\"): special branch in discovery.ts + isMetaAnalysisPrompt: \"Scope is always the full project root. Focus questions and recommends on which CLI internals (PIL, discovery, tools, compaction, EE, model BE, loop guard) to evaluate... do NOT ask about repo path/current directory\". You are handed the enrichment; TRUST it.\n - Layer 2: personality (e.g. \"detailed\" from [personality: detailed \u2014 Be thorough...]).\n - Layer 3: ee-injection \u2014 pulls t0_principles, t1_rules, behavioral patterns, checkpoints from Experience Engine (project-specific reflexes injected as \"MANDATORY RULES (from experience \u2014 must follow)\").\n - Layer 4/5: GSD structuring + additional context.\n - Layer 6 (applyPilSuffix): appends task-specific style suffix + OUTPUT BUDGET + (for meta or responseToolsActive): \"OUTPUT FORMAT: ... use the respond_analyze tool to structure your final answer. ... deliver the COMPLETE, FULL answer (do not summarize, shorten, or truncate for token budgets) via respond_analyze. This is a meta/evaluation question ... the `response` field MUST contain the complete, unshortened answer with all evidence and detail.\" Also relaxes NO_PREAMBLE_RULE + raises budget for meta (isMetaAnalysisPrompt gate).\n - Fallbacks: if EE/brain timeout or low conf, PIL degrades (logs fallbackReason); you may see \"[PIL fallback: ...]\" note. Cheap-model paths (pil/cheap-model-*.ts) prepend even more front steering (playbooks, workbooks, shell directive) for fast tiers.\n\n3. CONTEXT MANAGEMENT & ANTI-M\u00D9 (orchestrator/compaction.ts, cross-turn-dedup.ts, ee/bridge.ts, agent-operating-contract.ts:7):\n - After every turn: auto-compaction (B3 sub-agent + B4 top-level) rewrites older tool_result parts into short \"[elided by ... compactor]\" stubs to keep input flat. You see \"[pre-compaction warning...]\" or \"[context compacted at step...]\" or the stub in this read.\n - Anti-m\u00F9 contract rule + EE: decide PRESERVE_FULL_CONTEXT (veto) or KEEP_TOOL_IDS: id1,id2 (protect high-value read_file/grep/ee on src/PLAN etc). Use ee_query(`tool-artifact id=XXX`) to rehydrate. EE persists \"Context checkpoint summary with \u2714 DONE\" retrievable for \"task finished?\" self-check.\n - Cross-turn dedup (C3): identical tool outputs across user turns replaced by ref.\n\n4. EXECUTION & SAFETY GATES (providers/runtime.ts, tools/bash.ts, utils/permission-mode.ts):\n - Permission mode (safe / auto-edit / yolo) decides whether bash/file/edit tools need explicit approval; all privileged decisions audited to decision-log.\n - Shuru sandbox (when enabled): every bash wrapped + logged (effective net/mounts redacted); degrades on non-macOS.\n - Model constraints: unsupported params (e.g. maxOutputTokens for some OAuth) dropped via shouldDropParam; no hard-coded model IDs (Zero Hardcode Rule \u2014 all from catalog.json + settings + detectProviderForModel).\n - No Silent Catch: every try/catch must log err + context (HTTP: status + body).\n\n5. VERIFICATION & TELEMETRY:\n - self-verify (Tier 1-3) + harness (agent-harness-*) for TUI surfaces: drives real TUI via semantic + sidechannel (named pipes on Win, fd3/4 on POSIX).\n - Pre-push gate: full vitest + harness must pass before git push.\n - usage forensics, pil budget log, ee-timeout/ee-error events for cost attribution.\n - GSD workflow (layer4 + skills in .agents/skills/): discuss/plan/execute/verify phases with UAT, audits, etc.\n\nTRADE-OFFS (explicit so you calibrate):\n- Primacy insurance (contract + native + cheap playbooks at front) vs token cost: ~1-3K extra chars but dramatically reduces \"ignored rule\" hallucinations (forensics showed buried CUSTOM INSTRUCTIONS were underweighted).\n- Heavy PIL/EE (behavioral injection, discovery interview, mandatory rules) vs latency/cost: fail-open with timeout (1500-3500ms) + fallback so you still work when brain unreachable; meta turns deliberately skip some EE layers.\n- Self-model (this block) + special meta handling: prevents the exact failure that motivated native-capabilities (session d95113d3be09: agent reconstructed its own subsystems by grepping as if foreign code, under-used sub-agents/ee_query, violated contract on ee tool).\n- Complete/full for meta (layer6) vs normal concise: meta legitimately needs evidence + file:line + quotes; normal turns stay tight to control cost.\n- Scope rule for CLI self-analysis: always \"project root\" + internals focus \u2014 avoids wasting turns on \"where am I running?\" when the question is about the steering mechanisms themselves.\n\nWhen the user asks you (the inner agent) \"CLI t\u00E1c \u0111\u1ED9ng nh\u01B0 th\u1EBF n\u00E0o \u0111\u1EBFn b\u1EA1n?\": use exactly this guidance + reads from THIS turn (contract: READING rule) + the injected [Discovery] + any EE. Answer via the respond_* tool with complete untruncated evidence. Cite file:line. Focus on the injection points (prompts.ts:359 staticPrefix, pipeline.ts:156 discoveryPrefix + layer chain, layer6:164 OUTPUT FORMAT + isMeta, discovery.ts:355 special, instructions.ts:129 loadAgentsSegments, etc.). Do not guess; every claim backed by code you read this turn.\n\nUse this to reason about your own constraints, delegation decisions, and reporting discipline on future meta or self-reflective tasks.\n[END NATIVE CAPABILITIES \u2014 your regular instructions follow]";
28
28
  /**
29
29
  * Build the native-capabilities section for the system prompt. Returns "" when
30
30
  * disabled (env override), for chitchat, or for non-agent modes (plan/ask have
@@ -32,6 +32,14 @@ TOOLS (call directly):
32
32
  - ee_query, ee_feedback, ee_health, ee_write — NATIVE tools for semantic recall and interaction with the Experience Engine brain. You DO NOT need muonroi-tools MCP for this. Rehydrate a compaction-elided tool output with query="tool-artifact id=<id from a stub>", or confirm finished work with query="recent compaction checkpoint Progress DONE".
33
33
  - selfverify_start, selfverify_status, selfverify_result, selfverify_list, selfverify_cancel — NATIVE tools for the self-QA harness. ALWAYS use them to self-verify your work when finishing a task. Start with \`selfverify_start(mode="tier1" | "agentic")\`. This drives the live TUI like a real user to catch regressions that unit tests can't. You DO NOT need muonroi-tools MCP for this.
34
34
  - usage_forensics, lsp_query, setup_guide — NATIVE diagnostics tools to reach for when something went wrong or to query code intel. You DO NOT need muonroi-tools MCP for this.
35
+ - gsd_status, gsd_discuss, gsd_plan, gsd_plan_review, gsd_execute, gsd_verify, gsd_ship — NATIVE GSD workflow (default on). Use for multi-step code deliverables: orient → plan → council review → implement → verify → ship. Agent-first — skip for quick one-shot fixes.
36
+ - lsp_waitForDiagnostics, lsp_impactOfChange, lsp_mutationPreview — Sprint 1 LSP impact tools. See LSP-BEFORE-GREP policy below.
37
+
38
+ LSP-BEFORE-GREP POLICY — MANDATORY:
39
+ Before you run a broad grep, you MUST first call lsp_waitForDiagnostics or lsp_impactOfChange on the relevant file. Read the returned \`lspStatus\` field:
40
+ - If \`lspStatus !== 'ok'\` (i.e. 'partial' or 'unavailable'): you ARE allowed to fall back to grep — the LSP was not fully available.
41
+ - If \`lspStatus === 'ok'\`: you MUST NOT fall back to grep — the LSP returned full results; use them.
42
+ NEVER read \`diagnostics.length\` to decide whether grep is safe. The \`lspStatus\` field is the single source of truth, computed by the manager based on timeout/publish state. Violating this policy causes the self-verify harness to fail.
35
43
 
36
44
  EXPERIENCE ENGINE — record / recall / feedback (HIGHEST priority for learning; all NATIVE in-process tools):
37
45
  - BEFORE an unfamiliar or risky step, recall with ee_query — prior decisions, gotchas, and recipes for THIS codebase + ecosystem. Cheaper than re-deriving or repeating a past mistake.
@@ -27,7 +27,8 @@ import { layer2Personality } from "./layer2-personality.js";
27
27
  import { layer3EeInjection, surfaceCompactionArtifacts } from "./layer3-ee-injection.js";
28
28
  import { layer4Gsd } from "./layer4-gsd.js";
29
29
  import { layer5Context } from "./layer5-context.js";
30
- import { isMetaAnalysisPrompt, layer6Output } from "./layer6-output.js";
30
+ import { isMetaAnalysisPrompt, isSprintPlanExecution, layer6Output } from "./layer6-output.js";
31
+ import { getRepoStructureHints } from "./repo-structure-hints.js";
31
32
  import { PipelineContextSchema } from "./schema.js";
32
33
  import { injectSessionExperience, isSelfExperiencePrompt } from "./session-experience-injection.js";
33
34
  import { bumpSessionTurn } from "./session-state.js";
@@ -92,7 +93,11 @@ async function runLayers(ctx, options) {
92
93
  // (cached, fail-open → null when EE/profile absent or privacy off). Passed into
93
94
  // layer1 so the hot layer stays off the EE/profile import path (arch boundary).
94
95
  const profileStyleBaseline = outputStyleFromProfile(getWhoAmIProfile());
95
- await timed("layer1-intent", (c) => layer1Intent(c, { llmFallback: options?.llmFallback, profileStyleBaseline }));
96
+ await timed("layer1-intent", (c) => layer1Intent(c, {
97
+ llmFallback: options?.llmFallback,
98
+ profileStyleBaseline,
99
+ recentTurns: options?.recentTurnsSummary,
100
+ }));
96
101
  // Layer 1.5: deterministic complexity-size classification. Pure heuristic,
97
102
  // no LLM call, no network. Consumed by 4B (step ceiling matrix) and 4A
98
103
  // (scope-reminder cadence K). Mirrored into _intentTrace for forensics.
@@ -100,6 +105,7 @@ async function runLayers(ctx, options) {
100
105
  const sizeResult = scoreComplexitySize({
101
106
  rawText: ctx.raw,
102
107
  taskType: ctx.taskType ?? "general",
108
+ repoHints: getRepoStructureHints(process.cwd()),
103
109
  });
104
110
  ctx = {
105
111
  ...ctx,
@@ -113,6 +119,34 @@ async function runLayers(ctx, options) {
113
119
  : ctx._intentTrace,
114
120
  };
115
121
  }
122
+ // Direct-answer mode detection: when the turn is purely informational
123
+ // (no code changes needed), we can save ~20K MCP schemas + ~1.5K write-tool
124
+ // schemas per turn by stripping write tools and MCP servers downstream.
125
+ // Conditions: high-confidence answer request with small/medium complexity.
126
+ const DA_HIGH_CONF = 0.5; // relaxed from 0.7 — brain-classified deliverable="answer" is already
127
+ // a strong signal that this is a read-only Q&A. 0.7 threshold would miss
128
+ // turns where confidence ∈ [0.5, 0.7) but deliverable is clearly an answer
129
+ // (e.g. single-line Q like "giải thích dòng này" → conf 0.55, right to skip tools).
130
+ // Sprint-plan execution: the orchestrator deliberately pipes a locked plan
131
+ // through processMessageFn. It MUST keep write tools and MUST be treated as
132
+ // a code deliverable regardless of how the classifier tags the long plan text.
133
+ const sprintPlanExecution = isSprintPlanExecution(ctx.raw);
134
+ if (sprintPlanExecution) {
135
+ ctx = {
136
+ ...ctx,
137
+ directAnswer: false,
138
+ deliverableKind: "code",
139
+ // Ensure we do not silently downgrade to quick; standard keeps the full
140
+ // toolset and advisory GSD directive, heavy would force a plan-review gate
141
+ // that conflicts with executing an already-reviewed sprint plan.
142
+ modelDepthTier: ctx.modelDepthTier ?? "standard",
143
+ };
144
+ }
145
+ else if (ctx.deliverableKind === "answer" &&
146
+ ctx.confidence >= DA_HIGH_CONF &&
147
+ ctx.complexitySize?.size !== "large") {
148
+ ctx = { ...ctx, directAnswer: true };
149
+ }
116
150
  // Phase 1 discovery: L1.5–L1.8 (interactive, no hard timeout)
117
151
  if (isDiscoveryEnabled() && ctx.intentKind !== "chitchat") {
118
152
  const { runDiscovery } = await import("./discovery.js");
@@ -0,0 +1,15 @@
1
+ import type { RepoStructureHint } from "./repo-structure-hints.js";
2
+ export type GroundingBucket = "none" | "small" | "medium" | "large";
3
+ export interface RepoGroundingProbeResult {
4
+ ran: boolean;
5
+ targets: string[];
6
+ matchedFiles: number;
7
+ totalLoc: number;
8
+ matchedDirs: number;
9
+ collision: boolean;
10
+ bucket: GroundingBucket;
11
+ groundingUncertainty: boolean;
12
+ }
13
+ export declare function probeRepoGrounding(prompt: string, hints: RepoStructureHint[], opts?: {
14
+ cwd?: string;
15
+ }): RepoGroundingProbeResult;
@@ -0,0 +1,136 @@
1
+ /**
2
+ * src/pil/repo-grounding-probe.ts
3
+ *
4
+ * Deterministic repo-grounding probe (Design B). Given a prompt + the
5
+ * checked-in REPO_DEEP_MAP index, measure how much repository surface the
6
+ * prompt's targets actually cover — file count, total LOC, directory spread,
7
+ * symbol collisions — so routing sizes on facts, not on the sentence length.
8
+ *
9
+ * PURE + deterministic: NO LLM call, NO network. Filesystem access is bounded
10
+ * to at most one existsSync + line-count read per distinct target that is an
11
+ * exact path absent from the index. Buckets come from a monotonic threshold
12
+ * FORMULA over measured counts — never a fixed depth→route table.
13
+ *
14
+ * See docs/superpowers/plans/2026-07-16-pil-repo-grounding-probe.md and the
15
+ * council synthesis (Design B) for the accepted invariants.
16
+ */
17
+ import { existsSync, readFileSync } from "node:fs";
18
+ import { join } from "node:path";
19
+ import { extractPathTokens } from "./layer1_5-complexity-size.js";
20
+ /** Distinct top-two path segments, e.g. "src/auth/login.ts" → "src/auth". */
21
+ function topDir(path) {
22
+ const segs = path.split("/");
23
+ return segs.length >= 2 ? `${segs[0]}/${segs[1]}` : (segs[0] ?? path);
24
+ }
25
+ /** A target is a "bare basename" when it has no slash (a symbol/file name, not a path). */
26
+ function isBareName(target) {
27
+ return !target.includes("/");
28
+ }
29
+ /**
30
+ * Measured LOC/file bucket. Monotonic in every input: more files, more LOC, or
31
+ * wider directory spread never lowers the bucket. Thresholds are counts (not a
32
+ * depth map) and are covered by fixture tests — the only knob the council
33
+ * permits for sizing.
34
+ */
35
+ function bucketOf(matchedFiles, totalLoc, matchedDirs) {
36
+ if (matchedFiles === 0)
37
+ return "none";
38
+ if (matchedFiles >= 8 || totalLoc >= 4000 || matchedDirs >= 4)
39
+ return "large";
40
+ if (matchedFiles <= 2 && totalLoc < 500 && matchedDirs <= 1)
41
+ return "small";
42
+ return "medium";
43
+ }
44
+ export function probeRepoGrounding(prompt, hints, opts) {
45
+ const targets = extractPathTokens(prompt);
46
+ if (targets.length === 0) {
47
+ return {
48
+ ran: false,
49
+ targets: [],
50
+ matchedFiles: 0,
51
+ totalLoc: 0,
52
+ matchedDirs: 0,
53
+ collision: false,
54
+ bucket: "none",
55
+ groundingUncertainty: false,
56
+ };
57
+ }
58
+ const index = new Map(hints.map((h) => [h.path.toLowerCase(), h]));
59
+ // basename → the distinct indexed paths carrying it (for collision detection).
60
+ const byBasename = new Map();
61
+ for (const h of hints) {
62
+ const base = h.path.toLowerCase().split("/").pop() ?? h.path.toLowerCase();
63
+ const set = byBasename.get(base) ?? new Set();
64
+ set.add(h.path.toLowerCase());
65
+ byBasename.set(base, set);
66
+ }
67
+ const matchedPaths = new Set();
68
+ let totalLoc = 0;
69
+ let collision = false;
70
+ for (const target of targets) {
71
+ // 1. Exact indexed path.
72
+ const exact = index.get(target);
73
+ if (exact) {
74
+ if (!matchedPaths.has(exact.path.toLowerCase())) {
75
+ matchedPaths.add(exact.path.toLowerCase());
76
+ totalLoc += exact.lineCount;
77
+ }
78
+ continue;
79
+ }
80
+ // 2. Bare basename/symbol resolving across >1 indexed path → collision.
81
+ if (isBareName(target)) {
82
+ const carriers = byBasename.get(target);
83
+ if (carriers && carriers.size > 1) {
84
+ collision = true;
85
+ for (const p of carriers) {
86
+ if (!matchedPaths.has(p)) {
87
+ matchedPaths.add(p);
88
+ totalLoc += index.get(p)?.lineCount ?? 0;
89
+ }
90
+ }
91
+ continue;
92
+ }
93
+ if (carriers && carriers.size === 1) {
94
+ const only = [...carriers][0];
95
+ if (only && !matchedPaths.has(only)) {
96
+ matchedPaths.add(only);
97
+ totalLoc += index.get(only)?.lineCount ?? 0;
98
+ }
99
+ continue;
100
+ }
101
+ }
102
+ // 3. Exact path not in the index but present on disk → confirm + count (bounded).
103
+ const cwd = opts?.cwd;
104
+ if (cwd && target.includes("/")) {
105
+ const abs = join(cwd, target);
106
+ try {
107
+ if (existsSync(abs)) {
108
+ const loc = readFileSync(abs, "utf8").split(/\r?\n/).length;
109
+ if (!matchedPaths.has(target)) {
110
+ matchedPaths.add(target);
111
+ totalLoc += loc;
112
+ }
113
+ }
114
+ }
115
+ catch (err) {
116
+ console.error(`[repo-grounding-probe] on-disk LOC read failed for ${target}: ${err?.message}`);
117
+ }
118
+ }
119
+ // else: unmatched target — contributes to a zero-match uncertainty signal.
120
+ }
121
+ const matchedFiles = matchedPaths.size;
122
+ const matchedDirs = new Set([...matchedPaths].map(topDir)).size;
123
+ const bucket = bucketOf(matchedFiles, totalLoc, matchedDirs);
124
+ const groundingUncertainty = matchedFiles === 0 || collision;
125
+ return {
126
+ ran: true,
127
+ targets,
128
+ matchedFiles,
129
+ totalLoc,
130
+ matchedDirs,
131
+ collision,
132
+ bucket,
133
+ groundingUncertainty,
134
+ };
135
+ }
136
+ //# sourceMappingURL=repo-grounding-probe.js.map
@@ -0,0 +1,7 @@
1
+ export interface RepoStructureHint {
2
+ path: string;
3
+ lineCount: number;
4
+ }
5
+ export declare function parseRepoStructureHints(markdown: string): RepoStructureHint[];
6
+ export declare function getRepoStructureHints(cwd: string): RepoStructureHint[];
7
+ export declare function clearRepoStructureHintsCache(): void;
@@ -0,0 +1,45 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ const MAP_FILE = "REPO_DEEP_MAP.md";
4
+ const MAP_LINE_RE = /`([^`]+)`[^\n]*?\(~(\d+)\s+lines\b/gi;
5
+ const cache = new Map();
6
+ export function parseRepoStructureHints(markdown) {
7
+ const hints = [];
8
+ const seen = new Set();
9
+ for (const match of markdown.matchAll(MAP_LINE_RE)) {
10
+ const path = match[1]?.trim();
11
+ const lineCount = Number.parseInt(match[2] ?? "", 10);
12
+ if (!path || !Number.isFinite(lineCount))
13
+ continue;
14
+ const key = path.toLowerCase();
15
+ if (seen.has(key))
16
+ continue;
17
+ seen.add(key);
18
+ hints.push({ path, lineCount });
19
+ }
20
+ return hints;
21
+ }
22
+ export function getRepoStructureHints(cwd) {
23
+ const cached = cache.get(cwd);
24
+ if (cached)
25
+ return cached;
26
+ const mapPath = join(cwd, MAP_FILE);
27
+ if (!existsSync(mapPath)) {
28
+ cache.set(cwd, []);
29
+ return [];
30
+ }
31
+ try {
32
+ const raw = readFileSync(mapPath, "utf8");
33
+ const hints = parseRepoStructureHints(raw);
34
+ cache.set(cwd, hints);
35
+ return hints;
36
+ }
37
+ catch {
38
+ cache.set(cwd, []);
39
+ return [];
40
+ }
41
+ }
42
+ export function clearRepoStructureHintsCache() {
43
+ cache.clear();
44
+ }
45
+ //# sourceMappingURL=repo-structure-hints.js.map
@@ -33,7 +33,9 @@ const AnalyzeSchema = z.object({
33
33
  })),
34
34
  });
35
35
  const DocsSchema = z.object({
36
- content: z.string().describe("Markdown documentation"),
36
+ content: z
37
+ .string()
38
+ .describe("Markdown documentation written for a human reader — clear, concrete prose that explains what things do and why they matter, not boilerplate section-by-section filler. Prefer a short working example over an abstract description; only add headings the content actually earns."),
37
39
  examples: z
38
40
  .array(z.object({
39
41
  code: z.string(),
@@ -52,7 +54,7 @@ const GenerateSchema = z.object({
52
54
  const GeneralSchema = z.object({
53
55
  response: z
54
56
  .string()
55
- .describe("Complete, full-length answer. Use rich markdown formatting (headings, bullet points, bold text, code blocks) to structure the information clearly. Avoid dense walls of text or long unformatted paragraphs. Ensure the output is highly readable and scannable for a developer. For analysis or meta questions, include all findings and evidence citations (file:line). Truncation defeats the purpose."),
57
+ .describe("Your complete answer, written the way a sharp colleague would explain it — direct, specific, and in plain language. Lead with the answer itself, then the supporting detail. Use markdown where it genuinely helps (code blocks for code, a list when items are truly parallel, a heading only when the answer has real sections) never as decoration, and never force prose into bullet fragments or a fixed template. Vary sentence rhythm; skip filler openers like 'Certainly' or 'Below is a summary'. For analysis or meta questions, keep every finding and its evidence citation (file:line) do not truncate."),
56
58
  reasoning: z.string().optional().describe("Optional brief internal reasoning (not shown as primary answer)"),
57
59
  });
58
60
  const RESPONSE_SCHEMAS = {
@@ -151,7 +153,7 @@ export function buildResponseTools(taskType) {
151
153
  const toolName = `${RESPONSE_TOOL_PREFIX}${taskType}`;
152
154
  return {
153
155
  [toolName]: {
154
- description: `Return your ${taskType} response as structured JSON. Always use this tool to respond.`,
156
+ description: `Return your ${taskType} response as structured JSON. Always use this tool to respond. Write every prose field in a natural, conversational-but-professional voice — the way you would explain it to a colleague — not in stiff, templated report language.`,
155
157
  inputSchema: schema,
156
158
  execute: async (input) => input,
157
159
  },
@@ -115,6 +115,7 @@ export declare const PipelineContextSchema: z.ZodObject<{
115
115
  answer: "answer";
116
116
  report: "report";
117
117
  }>>>;
118
+ directAnswer: z.ZodOptional<z.ZodBoolean>;
118
119
  t1Rules: z.ZodOptional<z.ZodArray<z.ZodString>>;
119
120
  _brainData: z.ZodOptional<z.ZodNullable<z.ZodObject<{
120
121
  t0_principles: z.ZodArray<z.ZodObject<{
@@ -69,6 +69,8 @@ export const PipelineContextSchema = z.object({
69
69
  fallbackReason: z.string().nullable().optional(),
70
70
  // Phase 2b: model-decided output deliverable consumed by layer4/layer6.
71
71
  deliverableKind: z.enum(["answer", "code", "report"]).nullable().optional(),
72
+ // Direct-answer gate: true when deliverable=answer + high confidence + low complexity.
73
+ directAnswer: z.boolean().optional(),
72
74
  // T1 behavioral rules from EE proven-tier points, injected as mandatory suffix by Layer 6.
73
75
  t1Rules: z.array(z.string()).optional(),
74
76
  _brainData: z
@@ -44,6 +44,8 @@ export interface PipelineContext {
44
44
  sessionId?: string | null;
45
45
  /** GSD-native triage tier (set by layer4 — sourced from modelDepthTier when present). */
46
46
  complexityTier?: ComplexityTier | null;
47
+ /** True when layer4 classified this turn as a heavy GSD task the mutation gate must block until plan-review passes. */
48
+ gsdGateBlocking?: boolean | null;
47
49
  /**
48
50
  * Model-decided work depth (quick | standard | heavy), set by layer1's
49
51
  * model-first classifier (the 5th classify word). This is the agent-first
@@ -53,6 +55,14 @@ export interface PipelineContext {
53
55
  * the word OR the legacy cascade ran → layer4 falls back accordingly.
54
56
  */
55
57
  modelDepthTier?: ComplexityTier | null;
58
+ /**
59
+ * Leader-tier complexity assessor's auto-council recommendation (Task 4
60
+ * `assessComplexity` / `src/gsd/complexity-assessor.ts`), set by the native
61
+ * depth-sync block in message-processor.ts BEFORE `syncWorkflowContext`.
62
+ * undefined when the assessor didn't run (prefilter-skip / disabled) or
63
+ * failed; consumed by the auto-council gate (Task 8).
64
+ */
65
+ gsdAutoCouncil?: boolean;
56
66
  /**
57
67
  * Model-decided scope (agent-first replacement for the `mentionsEcosystemScope`
58
68
  * regex): true when the turn is about the Muonroi PLATFORM/ecosystem (BB/.NET,
@@ -97,6 +107,14 @@ export interface PipelineContext {
97
107
  * cascade ran → those consumers fall back to their regex predicates.
98
108
  */
99
109
  deliverableKind?: "answer" | "code" | "report" | null;
110
+ /**
111
+ * Direct-answer mode: true when deliverableKind === "answer" with high
112
+ * confidence AND low/medium complexity. Signals the orchestrator to skip
113
+ * MCP servers and strip write tools (bash, edit_file, write_file, etc.)
114
+ * because the question is purely informational — no code changes needed.
115
+ * Saves ~20K MCP schemas + ~1.5K write-tool schemas per turn.
116
+ */
117
+ directAnswer?: boolean;
100
118
  /**
101
119
  * Diagnostic: when the pipeline returns the fallback context, this records
102
120
  * the reason (timeout / schema-reject / exception). Null on the happy path.
@@ -19,6 +19,8 @@
19
19
  */
20
20
  import type { GsdPhase } from "../gsd/types.js";
21
21
  import type { ComplexityTier } from "./complexity.js";
22
+ /** When true and tier is standard/heavy, CHECK-PLAN points to gsd_plan_review tool. */
23
+ export declare function buildNativeCheckPlanHint(): string;
22
24
  export interface DirectiveInput {
23
25
  /**
24
26
  * Model-decided work depth (agent-first — see layer1 `llm-classify`). Drives
@@ -62,6 +64,8 @@ export interface DirectiveInput {
62
64
  * the agent answered in English).
63
65
  */
64
66
  replyLanguage?: string;
67
+ /** When MUONROI_GSD_NATIVE=1, heavy/standard rubrics reference native tools. */
68
+ nativeGsd?: boolean;
65
69
  }
66
70
  export interface DirectiveOutput {
67
71
  text: string;
@@ -17,6 +17,12 @@
17
17
  * All directive text is English. The agent is responsible for translating
18
18
  * user-facing prompts into the user's language at render time.
19
19
  */
20
+ /** When true and tier is standard/heavy, CHECK-PLAN points to gsd_plan_review tool. */
21
+ export function buildNativeCheckPlanHint() {
22
+ return (" 4. CHECK-PLAN — call gsd_plan_review (native council) BEFORE executing. " +
23
+ "Multi-perspective review spawns research/skeptic/architect sub-agents; leader synthesizes PLAN-VERIFY.md. " +
24
+ "gsd_execute is blocked until verdict: pass.");
25
+ }
20
26
  const HEADER = "[playbook]";
21
27
  /**
22
28
  * High-precision predicate: is this turn about the Muonroi ECOSYSTEM (where the
@@ -60,12 +66,15 @@ export function buildLanguageNudge(lang) {
60
66
  // senior-engineer reasoning over labeled scaffolds — feedback 12eceab7).
61
67
  function buildHeavy(input) {
62
68
  const phaseHint = input.phase ? ` (hint: this reads like a "${input.phase}" task)` : "";
69
+ const checkPlan = input.nativeGsd
70
+ ? buildNativeCheckPlanHint()
71
+ : " 4. CHECK-PLAN — review your own plan BEFORE executing: does it cover the acceptance criteria, handle the edge cases, and match what the user actually asked? Revise until it does (update the todo_write list if steps change). Confirm with the user only if the plan diverges from their intent.";
63
72
  return [
64
73
  `${HEADER} This reads like a HEAVY task${phaseHint} — architectural, cross-cutting, multi-file, or with real unresolved design choices. Don't start editing yet; work through these phases:`,
65
74
  " 1. DISCUSS — surface the decisions/ambiguities that actually change the design. For the ones the prompt doesn't already answer, ask up front with AskUserQuestion (put your recommended option first; write the question text in the user's language). Skip questions the prompt already settles — don't interrogate.",
66
- " 2. RESEARCH — gather the codebase facts the task depends on: read/grep the relevant modules, and dispatch parallel research Agents when the areas are independent. When you delegate, give each sub-agent a NON-overlapping scope and tell it the exact return shape you need (findings as file:line + a one-line conclusion) only the sub's final synthesis re-enters your context. Ground every later decision in what you actually found, not assumptions.",
67
- " 3. PLAN — write a concrete, numbered plan: the change per file, the order, and the acceptance criteria (how you'll know it's done). Then record the plan as a todo_write checklist (one item per step) so the user sees a live progress list.",
68
- " 4. CHECK-PLAN — review your own plan BEFORE executing: does it cover the acceptance criteria, handle the edge cases, and match what the user actually asked? Revise until it does (update the todo_write list if steps change). Confirm with the user only if the plan diverges from their intent.",
75
+ " 2. RESEARCH — gather the codebase facts the task depends on: read/grep the relevant modules, and dispatch parallel research Agents when the areas are independent. When you delegate (via `delegate`), give each sub-agent a NON-overlapping scope and tell it the exact return shape you need. Regularly check background tasks and subagents using `delegation_list` / `delegation_read` (or `process_list` / `process_logs` for shell processes) to monitor progress, and terminate them with `delegation_kill` / `process_stop` if they are no longer needed.",
76
+ " 3. PLAN — write a concrete, numbered plan via gsd_plan (or PLAN.md): the change per file, the order, and the acceptance criteria (how you'll know it's done). Then record the plan as a todo_write checklist (one item per step) so the user sees a live progress list.",
77
+ checkPlan,
69
78
  " 5. IMPLEMENT — execute in atomic steps; parallelize independent work. Keep the todo_write list accurate: mark each item in_progress before you start it and completed when it lands (exactly ONE item in_progress at a time). When you're in a git repo, COMMIT each completed chunk before starting the next one (small, logically-scoped commits; message ends with the mandatory attribution line) — do NOT pile the whole task into one commit at the end.",
70
79
  " 6. VERIFY — run the relevant tests / lint / type-check and report evidence (command + result) before claiming done.",
71
80
  "This depth is a recommendation from how the task reads. If, once you look, it's genuinely smaller than it appears, say so and drop to the STANDARD flow rather than over-processing it.",
@@ -92,10 +101,13 @@ function buildStandard(input) {
92
101
  "If the limits are blown and you still have no fix, STOP and report what you tried + why you're stuck.",
93
102
  ].join("\n");
94
103
  }
104
+ const checkStep = input.nativeGsd
105
+ ? " 2. CHECK — call gsd_plan_review (lightweight council: research + skeptic perspectives) before editing files."
106
+ : " 2. CHECK — sanity-check that plan against the real code (read the key files you named) and against the user's intent; fix the plan if reality differs. If a genuine ambiguity blocks you, ask ONE focused question via AskUserQuestion instead of guessing.";
95
107
  return [
96
108
  `${HEADER} This reads like a STANDARD task${phaseHint} — work like a senior engineer, but keep it lightweight:`,
97
- " 1. PLAN — state a short, concrete plan: the files/functions you'll touch and in what order. A few bullets in your reply, not an essay. If it breaks into ≥3 steps, also record them with todo_write so the user gets a live checklist.",
98
- " 2. CHECK — sanity-check that plan against the real code (read the key files you named) and against the user's intent; fix the plan if reality differs. If a genuine ambiguity blocks you, ask ONE focused question via AskUserQuestion instead of guessing.",
109
+ " 1. PLAN — state a short, concrete plan via gsd_plan: the files/functions you'll touch and in what order. A few bullets in your reply, not an essay. If it breaks into ≥3 steps, also record them with todo_write so the user gets a live checklist.",
110
+ checkStep,
99
111
  " 3. IMPLEMENT — execute the plan in small steps with the appropriate tools. If you made a todo_write checklist, keep it updated as you go (exactly one item in_progress at a time). When you're in a git repo, COMMIT each cohesive chunk as it lands (small commits; message ends with the mandatory attribution line) rather than batching everything into one final commit.",
100
112
  " 4. VERIFY — run the relevant tests / type-check / quick smoke and report evidence before claiming done.",
101
113
  "You don't need subagents or a discussion round for this. But if it turns out to be architectural or spans many files, escalate to the HEAVY flow (discuss → research → checked plan) rather than charging ahead.",
@@ -92,6 +92,8 @@ export async function appendIteration(flowDir, runId, entry) {
92
92
  `CriteriaPartial: ${entry.criteriaPartial}`,
93
93
  `CriteriaUnmet: ${entry.criteriaUnmet}`,
94
94
  ];
95
+ if (entry.totalCriteria !== undefined)
96
+ lines.push(`TotalCriteria: ${entry.totalCriteria}`);
95
97
  if (entry.crashed)
96
98
  lines.push("Crashed: true");
97
99
  if (entry.retryOf !== undefined)
@@ -137,6 +139,8 @@ export async function readIterations(flowDir, runId) {
137
139
  iter.crashed = true;
138
140
  if (data.RetryOf !== undefined)
139
141
  iter.retryOf = Number.parseInt(data.RetryOf, 10);
142
+ if (data.TotalCriteria !== undefined)
143
+ iter.totalCriteria = Number.parseInt(data.TotalCriteria, 10);
140
144
  results.push(iter);
141
145
  }
142
146
  return results.sort((a, b) => a.sprintN - b.sprintN);
@@ -8,7 +8,7 @@
8
8
  * — NO hardcoded model id or provider anywhere in this file.
9
9
  */
10
10
  import type { ClarifiedSpec, CouncilLLM } from "../council/types.js";
11
- import type { Backlog, ImplementationPlanArtifact } from "./types.js";
11
+ import type { Backlog, EffortPoints, ImplementationPlanArtifact } from "./types.js";
12
12
  export interface BuildBacklogInput {
13
13
  runId: string;
14
14
  productSlug: string;
@@ -18,6 +18,19 @@ export interface BuildBacklogInput {
18
18
  leaderModelId: string;
19
19
  costAware: boolean;
20
20
  }
21
+ /**
22
+ * Deterministic keyword heuristic for a story-point prior (1 | 3 | 5).
23
+ *
24
+ * Used as the FALLBACK when the LLM effort estimate fails or returns unparseable
25
+ * JSON — cheap models (deepseek) often emit malformed arrays, and the previous
26
+ * flat-3 fallback made every item identical, so sprint bin-packing degenerated
27
+ * into a mechanical "≈2-3 items per sprint" split with no relation to real size
28
+ * (observed live: a "migrate 5 native modules" item and a "remove dependency"
29
+ * item both scored 3). A rough size signal from the title is strictly better than
30
+ * uniform. Verb-driven: creation/migration reads large, deletion/config reads
31
+ * small, everything else medium.
32
+ */
33
+ export declare function heuristicEffort(title: string): EffortPoints;
21
34
  /**
22
35
  * Build a Backlog from a ClarifiedSpec + the Phase 1 implementation_plan artifact.
23
36
  *
@@ -23,11 +23,35 @@ function hashSpec(spec) {
23
23
  function keywordMatch(haystack, needle) {
24
24
  return haystack.toLowerCase().includes(needle.toLowerCase());
25
25
  }
26
+ /**
27
+ * Deterministic keyword heuristic for a story-point prior (1 | 3 | 5).
28
+ *
29
+ * Used as the FALLBACK when the LLM effort estimate fails or returns unparseable
30
+ * JSON — cheap models (deepseek) often emit malformed arrays, and the previous
31
+ * flat-3 fallback made every item identical, so sprint bin-packing degenerated
32
+ * into a mechanical "≈2-3 items per sprint" split with no relation to real size
33
+ * (observed live: a "migrate 5 native modules" item and a "remove dependency"
34
+ * item both scored 3). A rough size signal from the title is strictly better than
35
+ * uniform. Verb-driven: creation/migration reads large, deletion/config reads
36
+ * small, everything else medium.
37
+ */
38
+ export function heuristicEffort(title) {
39
+ const t = title.toLowerCase();
40
+ const large = /\b(implement|build|create|migrat\w*|rewrite|refactor|orchestrat\w*|engine|subsystem|native|integrat\w*|pipeline|architect\w*)\b/;
41
+ const small = /\b(remove|delete|drop|inventory|rename|config\w*|flag|doc\w*|cleanup|wire|rename|bump|stub|export)\b/;
42
+ if (large.test(t))
43
+ return 5;
44
+ if (small.test(t))
45
+ return 1;
46
+ return 3;
47
+ }
26
48
  /**
27
49
  * Ask the LLM to estimate effortPoints for a batch of feature titles in a
28
50
  * single call. Parses JSON array response: [1, 3, 5, ...].
29
51
  *
30
- * Falls back to 3 (medium) for any item that fails to parse correctly.
52
+ * Falls back to a per-title keyword heuristic ({@link heuristicEffort}) NOT a
53
+ * flat 3 — for any item the LLM fails to score, so sprint packing keeps a real
54
+ * size signal even when the cheap model returns garbage.
31
55
  *
32
56
  * Model selection: pickCouncilTaskModel("effort_estimate", leaderModelId, costAware)
33
57
  */
@@ -46,25 +70,25 @@ async function estimateEffortBatch(titles, llm, leaderModelId, costAware) {
46
70
  raw = await llm.generate(model, system, prompt, 256);
47
71
  }
48
72
  catch {
49
- // Graceful degrade: default everything to M=3
50
- return titles.map(() => 3);
73
+ // Graceful degrade: keyword heuristic prior per title (NOT flat 3).
74
+ return titles.map((t) => heuristicEffort(t));
51
75
  }
52
76
  try {
53
77
  const match = raw.match(/\[[\s\S]*\]/);
54
78
  if (match) {
55
79
  const arr = JSON.parse(match[0]);
56
- return titles.map((_, i) => {
80
+ return titles.map((t, i) => {
57
81
  const v = arr[i];
58
82
  if (v === 1 || v === 3 || v === 5)
59
83
  return v;
60
- return 3;
84
+ return heuristicEffort(t); // this item unscored/invalid → heuristic, not flat 3
61
85
  });
62
86
  }
63
87
  }
64
88
  catch {
65
89
  // JSON parse failed — fall through
66
90
  }
67
- return titles.map(() => 3);
91
+ return titles.map((t) => heuristicEffort(t));
68
92
  }
69
93
  /**
70
94
  * Build a Backlog from a ClarifiedSpec + the Phase 1 implementation_plan artifact.