@jokerized/getresearchdone 0.4.1

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 (711) hide show
  1. package/.claude-plugin/plugin.json +103 -0
  2. package/README.md +211 -0
  3. package/agents/grd-baseline-assessor.md +684 -0
  4. package/agents/grd-code-reviewer.md +300 -0
  5. package/agents/grd-codebase-mapper.md +355 -0
  6. package/agents/grd-critique-agent.md +119 -0
  7. package/agents/grd-debugger.md +519 -0
  8. package/agents/grd-deep-diver.md +737 -0
  9. package/agents/grd-eval-planner.md +913 -0
  10. package/agents/grd-eval-reporter.md +717 -0
  11. package/agents/grd-executor.md +683 -0
  12. package/agents/grd-feasibility-analyst.md +624 -0
  13. package/agents/grd-integration-checker.md +367 -0
  14. package/agents/grd-knowledge-miner.md +81 -0
  15. package/agents/grd-migrator.md +88 -0
  16. package/agents/grd-phase-researcher.md +697 -0
  17. package/agents/grd-plan-checker.md +443 -0
  18. package/agents/grd-planner.md +1532 -0
  19. package/agents/grd-product-owner.md +562 -0
  20. package/agents/grd-project-researcher.md +513 -0
  21. package/agents/grd-research-synthesizer.md +273 -0
  22. package/agents/grd-roadmapper.md +798 -0
  23. package/agents/grd-surveyor.md +566 -0
  24. package/agents/grd-verifier.md +893 -0
  25. package/bin/gd.js +4 -0
  26. package/bin/gd.ts +227 -0
  27. package/bin/grd-manifest.js +4 -0
  28. package/bin/grd-manifest.ts +286 -0
  29. package/bin/grd-mcp-server.js +4 -0
  30. package/bin/grd-mcp-server.ts +124 -0
  31. package/bin/grd-tools.js +4 -0
  32. package/bin/grd-tools.ts +2471 -0
  33. package/bin/postinstall.js +4 -0
  34. package/bin/postinstall.ts +80 -0
  35. package/commands/add-phase.md +123 -0
  36. package/commands/add-todo.md +87 -0
  37. package/commands/assess-baseline.md +289 -0
  38. package/commands/autopilot.md +100 -0
  39. package/commands/autoplan.md +55 -0
  40. package/commands/check-todos.md +87 -0
  41. package/commands/compare-methods.md +262 -0
  42. package/commands/complete-milestone.md +225 -0
  43. package/commands/debug.md +372 -0
  44. package/commands/deep-dive.md +288 -0
  45. package/commands/discover.md +281 -0
  46. package/commands/discuss-phase.md +188 -0
  47. package/commands/discuss.md +55 -0
  48. package/commands/eval-report.md +310 -0
  49. package/commands/evolve.md +79 -0
  50. package/commands/execute-phase.md +1017 -0
  51. package/commands/feasibility.md +292 -0
  52. package/commands/help.md +407 -0
  53. package/commands/init.md +1508 -0
  54. package/commands/insert-phase.md +113 -0
  55. package/commands/iterate.md +327 -0
  56. package/commands/list-phase-assumptions.md +217 -0
  57. package/commands/long-term-roadmap.md +202 -0
  58. package/commands/map-codebase.md +111 -0
  59. package/commands/migrate.md +159 -0
  60. package/commands/new-milestone.md +169 -0
  61. package/commands/pause-work.md +83 -0
  62. package/commands/plan-milestone-gaps.md +373 -0
  63. package/commands/plan-phase.md +655 -0
  64. package/commands/principles.md +328 -0
  65. package/commands/product-plan.md +319 -0
  66. package/commands/progress.md +481 -0
  67. package/commands/quick.md +167 -0
  68. package/commands/reapply-patches.md +154 -0
  69. package/commands/remove-phase.md +97 -0
  70. package/commands/requirement.md +96 -0
  71. package/commands/resume-project.md +113 -0
  72. package/commands/settings.md +1144 -0
  73. package/commands/survey.md +242 -0
  74. package/commands/sync.md +246 -0
  75. package/commands/tracker-setup.md +322 -0
  76. package/commands/update.md +202 -0
  77. package/commands/verify-phase.md +335 -0
  78. package/commands/verify-work.md +701 -0
  79. package/commands/wireup.md +29 -0
  80. package/dist/bin/gd.d.ts +3 -0
  81. package/dist/bin/gd.d.ts.map +1 -0
  82. package/dist/bin/gd.js +178 -0
  83. package/dist/bin/gd.js.map +1 -0
  84. package/dist/bin/grd-manifest.d.ts +3 -0
  85. package/dist/bin/grd-manifest.d.ts.map +1 -0
  86. package/dist/bin/grd-manifest.js +202 -0
  87. package/dist/bin/grd-manifest.js.map +1 -0
  88. package/dist/bin/grd-mcp-server.d.ts +3 -0
  89. package/dist/bin/grd-mcp-server.d.ts.map +1 -0
  90. package/dist/bin/grd-mcp-server.js +71 -0
  91. package/dist/bin/grd-mcp-server.js.map +1 -0
  92. package/dist/bin/grd-tools.d.ts +3 -0
  93. package/dist/bin/grd-tools.d.ts.map +1 -0
  94. package/dist/bin/grd-tools.js +1680 -0
  95. package/dist/bin/grd-tools.js.map +1 -0
  96. package/dist/bin/postinstall.d.ts +3 -0
  97. package/dist/bin/postinstall.d.ts.map +1 -0
  98. package/dist/bin/postinstall.js +61 -0
  99. package/dist/bin/postinstall.js.map +1 -0
  100. package/dist/lib/autopilot-milestone.d.ts +2 -0
  101. package/dist/lib/autopilot-milestone.d.ts.map +1 -0
  102. package/dist/lib/autopilot-milestone.js +94 -0
  103. package/dist/lib/autopilot-milestone.js.map +1 -0
  104. package/dist/lib/autopilot-pipeline.d.ts +2 -0
  105. package/dist/lib/autopilot-pipeline.d.ts.map +1 -0
  106. package/dist/lib/autopilot-pipeline.js +830 -0
  107. package/dist/lib/autopilot-pipeline.js.map +1 -0
  108. package/dist/lib/autopilot-waves.d.ts +2 -0
  109. package/dist/lib/autopilot-waves.d.ts.map +1 -0
  110. package/dist/lib/autopilot-waves.js +266 -0
  111. package/dist/lib/autopilot-waves.js.map +1 -0
  112. package/dist/lib/autopilot.d.ts +2 -0
  113. package/dist/lib/autopilot.d.ts.map +1 -0
  114. package/dist/lib/autopilot.js +1314 -0
  115. package/dist/lib/autopilot.js.map +1 -0
  116. package/dist/lib/autoplan.d.ts +2 -0
  117. package/dist/lib/autoplan.d.ts.map +1 -0
  118. package/dist/lib/autoplan.js +198 -0
  119. package/dist/lib/autoplan.js.map +1 -0
  120. package/dist/lib/autoresearch.d.ts +2 -0
  121. package/dist/lib/autoresearch.d.ts.map +1 -0
  122. package/dist/lib/autoresearch.js +626 -0
  123. package/dist/lib/autoresearch.js.map +1 -0
  124. package/dist/lib/backend.d.ts +2 -0
  125. package/dist/lib/backend.d.ts.map +1 -0
  126. package/dist/lib/backend.js +1036 -0
  127. package/dist/lib/backend.js.map +1 -0
  128. package/dist/lib/benchmark.d.ts +99 -0
  129. package/dist/lib/benchmark.d.ts.map +1 -0
  130. package/dist/lib/benchmark.js +278 -0
  131. package/dist/lib/benchmark.js.map +1 -0
  132. package/dist/lib/citations.d.ts +2 -0
  133. package/dist/lib/citations.d.ts.map +1 -0
  134. package/dist/lib/citations.js +642 -0
  135. package/dist/lib/citations.js.map +1 -0
  136. package/dist/lib/cleanup.d.ts +2 -0
  137. package/dist/lib/cleanup.d.ts.map +1 -0
  138. package/dist/lib/cleanup.js +1222 -0
  139. package/dist/lib/cleanup.js.map +1 -0
  140. package/dist/lib/cli/adapters.d.ts +10 -0
  141. package/dist/lib/cli/adapters.d.ts.map +1 -0
  142. package/dist/lib/cli/adapters.js +27 -0
  143. package/dist/lib/cli/adapters.js.map +1 -0
  144. package/dist/lib/cli/agent.d.ts +17 -0
  145. package/dist/lib/cli/agent.d.ts.map +1 -0
  146. package/dist/lib/cli/agent.js +53 -0
  147. package/dist/lib/cli/agent.js.map +1 -0
  148. package/dist/lib/cli/index.d.ts +21 -0
  149. package/dist/lib/cli/index.d.ts.map +1 -0
  150. package/dist/lib/cli/index.js +264 -0
  151. package/dist/lib/cli/index.js.map +1 -0
  152. package/dist/lib/cli/output.d.ts +20 -0
  153. package/dist/lib/cli/output.d.ts.map +1 -0
  154. package/dist/lib/cli/output.js +22 -0
  155. package/dist/lib/cli/output.js.map +1 -0
  156. package/dist/lib/cli/scan-dispatch.d.ts +9 -0
  157. package/dist/lib/cli/scan-dispatch.d.ts.map +1 -0
  158. package/dist/lib/cli/scan-dispatch.js +107 -0
  159. package/dist/lib/cli/scan-dispatch.js.map +1 -0
  160. package/dist/lib/cli/tools.d.ts +16 -0
  161. package/dist/lib/cli/tools.d.ts.map +1 -0
  162. package/dist/lib/cli/tools.js +168 -0
  163. package/dist/lib/cli/tools.js.map +1 -0
  164. package/dist/lib/commands/_dashboard-parsers.d.ts +2 -0
  165. package/dist/lib/commands/_dashboard-parsers.d.ts.map +1 -0
  166. package/dist/lib/commands/_dashboard-parsers.js +192 -0
  167. package/dist/lib/commands/_dashboard-parsers.js.map +1 -0
  168. package/dist/lib/commands/analysis.d.ts +2 -0
  169. package/dist/lib/commands/analysis.d.ts.map +1 -0
  170. package/dist/lib/commands/analysis.js +1418 -0
  171. package/dist/lib/commands/analysis.js.map +1 -0
  172. package/dist/lib/commands/assumptions.d.ts +2 -0
  173. package/dist/lib/commands/assumptions.d.ts.map +1 -0
  174. package/dist/lib/commands/assumptions.js +166 -0
  175. package/dist/lib/commands/assumptions.js.map +1 -0
  176. package/dist/lib/commands/blame.d.ts +2 -0
  177. package/dist/lib/commands/blame.d.ts.map +1 -0
  178. package/dist/lib/commands/blame.js +133 -0
  179. package/dist/lib/commands/blame.js.map +1 -0
  180. package/dist/lib/commands/budget.d.ts +2 -0
  181. package/dist/lib/commands/budget.d.ts.map +1 -0
  182. package/dist/lib/commands/budget.js +100 -0
  183. package/dist/lib/commands/budget.js.map +1 -0
  184. package/dist/lib/commands/check-plans.d.ts +2 -0
  185. package/dist/lib/commands/check-plans.d.ts.map +1 -0
  186. package/dist/lib/commands/check-plans.js +190 -0
  187. package/dist/lib/commands/check-plans.js.map +1 -0
  188. package/dist/lib/commands/config.d.ts +2 -0
  189. package/dist/lib/commands/config.d.ts.map +1 -0
  190. package/dist/lib/commands/config.js +188 -0
  191. package/dist/lib/commands/config.js.map +1 -0
  192. package/dist/lib/commands/dashboard.d.ts +2 -0
  193. package/dist/lib/commands/dashboard.d.ts.map +1 -0
  194. package/dist/lib/commands/dashboard.js +466 -0
  195. package/dist/lib/commands/dashboard.js.map +1 -0
  196. package/dist/lib/commands/estimate.d.ts +2 -0
  197. package/dist/lib/commands/estimate.d.ts.map +1 -0
  198. package/dist/lib/commands/estimate.js +148 -0
  199. package/dist/lib/commands/estimate.js.map +1 -0
  200. package/dist/lib/commands/eval-diff.d.ts +2 -0
  201. package/dist/lib/commands/eval-diff.d.ts.map +1 -0
  202. package/dist/lib/commands/eval-diff.js +213 -0
  203. package/dist/lib/commands/eval-diff.js.map +1 -0
  204. package/dist/lib/commands/freshness.d.ts +2 -0
  205. package/dist/lib/commands/freshness.d.ts.map +1 -0
  206. package/dist/lib/commands/freshness.js +163 -0
  207. package/dist/lib/commands/freshness.js.map +1 -0
  208. package/dist/lib/commands/health.d.ts +2 -0
  209. package/dist/lib/commands/health.d.ts.map +1 -0
  210. package/dist/lib/commands/health.js +435 -0
  211. package/dist/lib/commands/health.js.map +1 -0
  212. package/dist/lib/commands/index.d.ts +2 -0
  213. package/dist/lib/commands/index.d.ts.map +1 -0
  214. package/dist/lib/commands/index.js +128 -0
  215. package/dist/lib/commands/index.js.map +1 -0
  216. package/dist/lib/commands/install.d.ts +56 -0
  217. package/dist/lib/commands/install.d.ts.map +1 -0
  218. package/dist/lib/commands/install.js +214 -0
  219. package/dist/lib/commands/install.js.map +1 -0
  220. package/dist/lib/commands/knowhow-aggregator.d.ts +2 -0
  221. package/dist/lib/commands/knowhow-aggregator.d.ts.map +1 -0
  222. package/dist/lib/commands/knowhow-aggregator.js +279 -0
  223. package/dist/lib/commands/knowhow-aggregator.js.map +1 -0
  224. package/dist/lib/commands/knowledge-search.d.ts +2 -0
  225. package/dist/lib/commands/knowledge-search.d.ts.map +1 -0
  226. package/dist/lib/commands/knowledge-search.js +113 -0
  227. package/dist/lib/commands/knowledge-search.js.map +1 -0
  228. package/dist/lib/commands/long-term-roadmap.d.ts +2 -0
  229. package/dist/lib/commands/long-term-roadmap.d.ts.map +1 -0
  230. package/dist/lib/commands/long-term-roadmap.js +272 -0
  231. package/dist/lib/commands/long-term-roadmap.js.map +1 -0
  232. package/dist/lib/commands/patterns.d.ts +91 -0
  233. package/dist/lib/commands/patterns.d.ts.map +1 -0
  234. package/dist/lib/commands/patterns.js +391 -0
  235. package/dist/lib/commands/patterns.js.map +1 -0
  236. package/dist/lib/commands/phase-info.d.ts +2 -0
  237. package/dist/lib/commands/phase-info.d.ts.map +1 -0
  238. package/dist/lib/commands/phase-info.js +509 -0
  239. package/dist/lib/commands/phase-info.js.map +1 -0
  240. package/dist/lib/commands/plan-lint.d.ts +56 -0
  241. package/dist/lib/commands/plan-lint.d.ts.map +1 -0
  242. package/dist/lib/commands/plan-lint.js +481 -0
  243. package/dist/lib/commands/plan-lint.js.map +1 -0
  244. package/dist/lib/commands/plan-phase.d.ts +53 -0
  245. package/dist/lib/commands/plan-phase.d.ts.map +1 -0
  246. package/dist/lib/commands/plan-phase.js +288 -0
  247. package/dist/lib/commands/plan-phase.js.map +1 -0
  248. package/dist/lib/commands/progress.d.ts +2 -0
  249. package/dist/lib/commands/progress.d.ts.map +1 -0
  250. package/dist/lib/commands/progress.js +266 -0
  251. package/dist/lib/commands/progress.js.map +1 -0
  252. package/dist/lib/commands/quality.d.ts +2 -0
  253. package/dist/lib/commands/quality.d.ts.map +1 -0
  254. package/dist/lib/commands/quality.js +80 -0
  255. package/dist/lib/commands/quality.js.map +1 -0
  256. package/dist/lib/commands/rollback.d.ts +2 -0
  257. package/dist/lib/commands/rollback.d.ts.map +1 -0
  258. package/dist/lib/commands/rollback.js +145 -0
  259. package/dist/lib/commands/rollback.js.map +1 -0
  260. package/dist/lib/commands/scan.d.ts +25 -0
  261. package/dist/lib/commands/scan.d.ts.map +1 -0
  262. package/dist/lib/commands/scan.js +28 -0
  263. package/dist/lib/commands/scan.js.map +1 -0
  264. package/dist/lib/commands/search.d.ts +2 -0
  265. package/dist/lib/commands/search.d.ts.map +1 -0
  266. package/dist/lib/commands/search.js +212 -0
  267. package/dist/lib/commands/search.js.map +1 -0
  268. package/dist/lib/commands/select-candidate.d.ts +128 -0
  269. package/dist/lib/commands/select-candidate.d.ts.map +1 -0
  270. package/dist/lib/commands/select-candidate.js +518 -0
  271. package/dist/lib/commands/select-candidate.js.map +1 -0
  272. package/dist/lib/commands/singularity.d.ts +2 -0
  273. package/dist/lib/commands/singularity.d.ts.map +1 -0
  274. package/dist/lib/commands/singularity.js +185 -0
  275. package/dist/lib/commands/singularity.js.map +1 -0
  276. package/dist/lib/commands/slug-timestamp.d.ts +2 -0
  277. package/dist/lib/commands/slug-timestamp.d.ts.map +1 -0
  278. package/dist/lib/commands/slug-timestamp.js +54 -0
  279. package/dist/lib/commands/slug-timestamp.js.map +1 -0
  280. package/dist/lib/commands/tail.d.ts +2 -0
  281. package/dist/lib/commands/tail.d.ts.map +1 -0
  282. package/dist/lib/commands/tail.js +100 -0
  283. package/dist/lib/commands/tail.js.map +1 -0
  284. package/dist/lib/commands/todo.d.ts +2 -0
  285. package/dist/lib/commands/todo.d.ts.map +1 -0
  286. package/dist/lib/commands/todo.js +200 -0
  287. package/dist/lib/commands/todo.js.map +1 -0
  288. package/dist/lib/commands/watch.d.ts +2 -0
  289. package/dist/lib/commands/watch.d.ts.map +1 -0
  290. package/dist/lib/commands/watch.js +72 -0
  291. package/dist/lib/commands/watch.js.map +1 -0
  292. package/dist/lib/complexity.d.ts +55 -0
  293. package/dist/lib/complexity.d.ts.map +1 -0
  294. package/dist/lib/complexity.js +80 -0
  295. package/dist/lib/complexity.js.map +1 -0
  296. package/dist/lib/context/agents.d.ts +2 -0
  297. package/dist/lib/context/agents.d.ts.map +1 -0
  298. package/dist/lib/context/agents.js +344 -0
  299. package/dist/lib/context/agents.js.map +1 -0
  300. package/dist/lib/context/base.d.ts +2 -0
  301. package/dist/lib/context/base.d.ts.map +1 -0
  302. package/dist/lib/context/base.js +81 -0
  303. package/dist/lib/context/base.js.map +1 -0
  304. package/dist/lib/context/execute.d.ts +2 -0
  305. package/dist/lib/context/execute.d.ts.map +1 -0
  306. package/dist/lib/context/execute.js +753 -0
  307. package/dist/lib/context/execute.js.map +1 -0
  308. package/dist/lib/context/index.d.ts +2 -0
  309. package/dist/lib/context/index.d.ts.map +1 -0
  310. package/dist/lib/context/index.js +88 -0
  311. package/dist/lib/context/index.js.map +1 -0
  312. package/dist/lib/context/progress.d.ts +2 -0
  313. package/dist/lib/context/progress.d.ts.map +1 -0
  314. package/dist/lib/context/progress.js +178 -0
  315. package/dist/lib/context/progress.js.map +1 -0
  316. package/dist/lib/context/project.d.ts +2 -0
  317. package/dist/lib/context/project.d.ts.map +1 -0
  318. package/dist/lib/context/project.js +413 -0
  319. package/dist/lib/context/project.js.map +1 -0
  320. package/dist/lib/context/research.d.ts +2 -0
  321. package/dist/lib/context/research.d.ts.map +1 -0
  322. package/dist/lib/context/research.js +466 -0
  323. package/dist/lib/context/research.js.map +1 -0
  324. package/dist/lib/dead-ends.d.ts +28 -0
  325. package/dist/lib/dead-ends.d.ts.map +1 -0
  326. package/dist/lib/dead-ends.js +451 -0
  327. package/dist/lib/dead-ends.js.map +1 -0
  328. package/dist/lib/deps.d.ts +2 -0
  329. package/dist/lib/deps.d.ts.map +1 -0
  330. package/dist/lib/deps.js +630 -0
  331. package/dist/lib/deps.js.map +1 -0
  332. package/dist/lib/discussion.d.ts +2 -0
  333. package/dist/lib/discussion.d.ts.map +1 -0
  334. package/dist/lib/discussion.js +1041 -0
  335. package/dist/lib/discussion.js.map +1 -0
  336. package/dist/lib/drift.d.ts +36 -0
  337. package/dist/lib/drift.d.ts.map +1 -0
  338. package/dist/lib/drift.js +481 -0
  339. package/dist/lib/drift.js.map +1 -0
  340. package/dist/lib/evolve/_dimensions-features.d.ts +2 -0
  341. package/dist/lib/evolve/_dimensions-features.d.ts.map +1 -0
  342. package/dist/lib/evolve/_dimensions-features.js +369 -0
  343. package/dist/lib/evolve/_dimensions-features.js.map +1 -0
  344. package/dist/lib/evolve/_dimensions.d.ts +2 -0
  345. package/dist/lib/evolve/_dimensions.d.ts.map +1 -0
  346. package/dist/lib/evolve/_dimensions.js +358 -0
  347. package/dist/lib/evolve/_dimensions.js.map +1 -0
  348. package/dist/lib/evolve/_product-ideation.d.ts +2 -0
  349. package/dist/lib/evolve/_product-ideation.d.ts.map +1 -0
  350. package/dist/lib/evolve/_product-ideation.js +281 -0
  351. package/dist/lib/evolve/_product-ideation.js.map +1 -0
  352. package/dist/lib/evolve/_prompts.d.ts +2 -0
  353. package/dist/lib/evolve/_prompts.d.ts.map +1 -0
  354. package/dist/lib/evolve/_prompts.js +153 -0
  355. package/dist/lib/evolve/_prompts.js.map +1 -0
  356. package/dist/lib/evolve/cli.d.ts +2 -0
  357. package/dist/lib/evolve/cli.d.ts.map +1 -0
  358. package/dist/lib/evolve/cli.js +224 -0
  359. package/dist/lib/evolve/cli.js.map +1 -0
  360. package/dist/lib/evolve/discovery.d.ts +2 -0
  361. package/dist/lib/evolve/discovery.d.ts.map +1 -0
  362. package/dist/lib/evolve/discovery.js +391 -0
  363. package/dist/lib/evolve/discovery.js.map +1 -0
  364. package/dist/lib/evolve/index.d.ts +2 -0
  365. package/dist/lib/evolve/index.d.ts.map +1 -0
  366. package/dist/lib/evolve/index.js +88 -0
  367. package/dist/lib/evolve/index.js.map +1 -0
  368. package/dist/lib/evolve/orchestrator.d.ts +2 -0
  369. package/dist/lib/evolve/orchestrator.d.ts.map +1 -0
  370. package/dist/lib/evolve/orchestrator.js +851 -0
  371. package/dist/lib/evolve/orchestrator.js.map +1 -0
  372. package/dist/lib/evolve/scoring.d.ts +2 -0
  373. package/dist/lib/evolve/scoring.d.ts.map +1 -0
  374. package/dist/lib/evolve/scoring.js +118 -0
  375. package/dist/lib/evolve/scoring.js.map +1 -0
  376. package/dist/lib/evolve/state.d.ts +2 -0
  377. package/dist/lib/evolve/state.d.ts.map +1 -0
  378. package/dist/lib/evolve/state.js +264 -0
  379. package/dist/lib/evolve/state.js.map +1 -0
  380. package/dist/lib/evolve/types.d.ts +249 -0
  381. package/dist/lib/evolve/types.d.ts.map +1 -0
  382. package/dist/lib/evolve/types.js +3 -0
  383. package/dist/lib/evolve/types.js.map +1 -0
  384. package/dist/lib/frontmatter.d.ts +2 -0
  385. package/dist/lib/frontmatter.d.ts.map +1 -0
  386. package/dist/lib/frontmatter.js +513 -0
  387. package/dist/lib/frontmatter.js.map +1 -0
  388. package/dist/lib/gates.d.ts +2 -0
  389. package/dist/lib/gates.d.ts.map +1 -0
  390. package/dist/lib/gates.js +578 -0
  391. package/dist/lib/gates.js.map +1 -0
  392. package/dist/lib/genome.d.ts +10 -0
  393. package/dist/lib/genome.d.ts.map +1 -0
  394. package/dist/lib/genome.js +368 -0
  395. package/dist/lib/genome.js.map +1 -0
  396. package/dist/lib/got.d.ts +2 -0
  397. package/dist/lib/got.d.ts.map +1 -0
  398. package/dist/lib/got.js +280 -0
  399. package/dist/lib/got.js.map +1 -0
  400. package/dist/lib/invariants.d.ts +2 -0
  401. package/dist/lib/invariants.d.ts.map +1 -0
  402. package/dist/lib/invariants.js +298 -0
  403. package/dist/lib/invariants.js.map +1 -0
  404. package/dist/lib/knowledge.d.ts +2 -0
  405. package/dist/lib/knowledge.d.ts.map +1 -0
  406. package/dist/lib/knowledge.js +658 -0
  407. package/dist/lib/knowledge.js.map +1 -0
  408. package/dist/lib/long-term-roadmap.d.ts +2 -0
  409. package/dist/lib/long-term-roadmap.d.ts.map +1 -0
  410. package/dist/lib/long-term-roadmap.js +602 -0
  411. package/dist/lib/long-term-roadmap.js.map +1 -0
  412. package/dist/lib/markdown-split.d.ts +2 -0
  413. package/dist/lib/markdown-split.d.ts.map +1 -0
  414. package/dist/lib/markdown-split.js +199 -0
  415. package/dist/lib/markdown-split.js.map +1 -0
  416. package/dist/lib/mcp-server.d.ts +2 -0
  417. package/dist/lib/mcp-server.d.ts.map +1 -0
  418. package/dist/lib/mcp-server.js +2424 -0
  419. package/dist/lib/mcp-server.js.map +1 -0
  420. package/dist/lib/metrics.d.ts +16 -0
  421. package/dist/lib/metrics.d.ts.map +1 -0
  422. package/dist/lib/metrics.js +48 -0
  423. package/dist/lib/metrics.js.map +1 -0
  424. package/dist/lib/overstory.d.ts +2 -0
  425. package/dist/lib/overstory.d.ts.map +1 -0
  426. package/dist/lib/overstory.js +211 -0
  427. package/dist/lib/overstory.js.map +1 -0
  428. package/dist/lib/parallel.d.ts +2 -0
  429. package/dist/lib/parallel.d.ts.map +1 -0
  430. package/dist/lib/parallel.js +349 -0
  431. package/dist/lib/parallel.js.map +1 -0
  432. package/dist/lib/paths.d.ts +2 -0
  433. package/dist/lib/paths.d.ts.map +1 -0
  434. package/dist/lib/paths.js +254 -0
  435. package/dist/lib/paths.js.map +1 -0
  436. package/dist/lib/phase-complete-llm.d.ts +22 -0
  437. package/dist/lib/phase-complete-llm.d.ts.map +1 -0
  438. package/dist/lib/phase-complete-llm.js +331 -0
  439. package/dist/lib/phase-complete-llm.js.map +1 -0
  440. package/dist/lib/phase-complete.d.ts +46 -0
  441. package/dist/lib/phase-complete.d.ts.map +1 -0
  442. package/dist/lib/phase-complete.js +278 -0
  443. package/dist/lib/phase-complete.js.map +1 -0
  444. package/dist/lib/phase-io.d.ts +2 -0
  445. package/dist/lib/phase-io.d.ts.map +1 -0
  446. package/dist/lib/phase-io.js +126 -0
  447. package/dist/lib/phase-io.js.map +1 -0
  448. package/dist/lib/phase.d.ts +2 -0
  449. package/dist/lib/phase.d.ts.map +1 -0
  450. package/dist/lib/phase.js +1344 -0
  451. package/dist/lib/phase.js.map +1 -0
  452. package/dist/lib/plan-tournament.d.ts +63 -0
  453. package/dist/lib/plan-tournament.d.ts.map +1 -0
  454. package/dist/lib/plan-tournament.js +353 -0
  455. package/dist/lib/plan-tournament.js.map +1 -0
  456. package/dist/lib/refinement.d.ts +74 -0
  457. package/dist/lib/refinement.d.ts.map +1 -0
  458. package/dist/lib/refinement.js +283 -0
  459. package/dist/lib/refinement.js.map +1 -0
  460. package/dist/lib/requirements.d.ts +2 -0
  461. package/dist/lib/requirements.d.ts.map +1 -0
  462. package/dist/lib/requirements.js +355 -0
  463. package/dist/lib/requirements.js.map +1 -0
  464. package/dist/lib/research-bundle.d.ts +2 -0
  465. package/dist/lib/research-bundle.d.ts.map +1 -0
  466. package/dist/lib/research-bundle.js +246 -0
  467. package/dist/lib/research-bundle.js.map +1 -0
  468. package/dist/lib/roadmap.d.ts +2 -0
  469. package/dist/lib/roadmap.d.ts.map +1 -0
  470. package/dist/lib/roadmap.js +541 -0
  471. package/dist/lib/roadmap.js.map +1 -0
  472. package/dist/lib/sample.d.ts +16 -0
  473. package/dist/lib/sample.d.ts.map +1 -0
  474. package/dist/lib/sample.js +20 -0
  475. package/dist/lib/sample.js.map +1 -0
  476. package/dist/lib/scaffold.d.ts +2 -0
  477. package/dist/lib/scaffold.d.ts.map +1 -0
  478. package/dist/lib/scaffold.js +355 -0
  479. package/dist/lib/scaffold.js.map +1 -0
  480. package/dist/lib/scan/_utils.d.ts +11 -0
  481. package/dist/lib/scan/_utils.d.ts.map +1 -0
  482. package/dist/lib/scan/_utils.js +36 -0
  483. package/dist/lib/scan/_utils.js.map +1 -0
  484. package/dist/lib/scan/base64.d.ts +15 -0
  485. package/dist/lib/scan/base64.d.ts.map +1 -0
  486. package/dist/lib/scan/base64.js +66 -0
  487. package/dist/lib/scan/base64.js.map +1 -0
  488. package/dist/lib/scan/ignorefile.d.ts +30 -0
  489. package/dist/lib/scan/ignorefile.d.ts.map +1 -0
  490. package/dist/lib/scan/ignorefile.js +101 -0
  491. package/dist/lib/scan/ignorefile.js.map +1 -0
  492. package/dist/lib/scan/injection.d.ts +14 -0
  493. package/dist/lib/scan/injection.d.ts.map +1 -0
  494. package/dist/lib/scan/injection.js +39 -0
  495. package/dist/lib/scan/injection.js.map +1 -0
  496. package/dist/lib/scan/patterns.d.ts +17 -0
  497. package/dist/lib/scan/patterns.d.ts.map +1 -0
  498. package/dist/lib/scan/patterns.js +123 -0
  499. package/dist/lib/scan/patterns.js.map +1 -0
  500. package/dist/lib/scan/strip-markdown.d.ts +7 -0
  501. package/dist/lib/scan/strip-markdown.d.ts.map +1 -0
  502. package/dist/lib/scan/strip-markdown.js +38 -0
  503. package/dist/lib/scan/strip-markdown.js.map +1 -0
  504. package/dist/lib/scan/types.d.ts +23 -0
  505. package/dist/lib/scan/types.d.ts.map +1 -0
  506. package/dist/lib/scan/types.js +3 -0
  507. package/dist/lib/scan/types.js.map +1 -0
  508. package/dist/lib/scheduler-wait.d.ts +2 -0
  509. package/dist/lib/scheduler-wait.d.ts.map +1 -0
  510. package/dist/lib/scheduler-wait.js +59 -0
  511. package/dist/lib/scheduler-wait.js.map +1 -0
  512. package/dist/lib/scheduler.d.ts +254 -0
  513. package/dist/lib/scheduler.d.ts.map +1 -0
  514. package/dist/lib/scheduler.js +1147 -0
  515. package/dist/lib/scheduler.js.map +1 -0
  516. package/dist/lib/state.d.ts +2 -0
  517. package/dist/lib/state.d.ts.map +1 -0
  518. package/dist/lib/state.js +744 -0
  519. package/dist/lib/state.js.map +1 -0
  520. package/dist/lib/think.d.ts +18 -0
  521. package/dist/lib/think.d.ts.map +1 -0
  522. package/dist/lib/think.js +317 -0
  523. package/dist/lib/think.js.map +1 -0
  524. package/dist/lib/tracker.d.ts +2 -0
  525. package/dist/lib/tracker.d.ts.map +1 -0
  526. package/dist/lib/tracker.js +1121 -0
  527. package/dist/lib/tracker.js.map +1 -0
  528. package/dist/lib/types.d.ts +1514 -0
  529. package/dist/lib/types.d.ts.map +1 -0
  530. package/dist/lib/types.js +4 -0
  531. package/dist/lib/types.js.map +1 -0
  532. package/dist/lib/utils.d.ts +2 -0
  533. package/dist/lib/utils.d.ts.map +1 -0
  534. package/dist/lib/utils.js +1363 -0
  535. package/dist/lib/utils.js.map +1 -0
  536. package/dist/lib/verify.d.ts +2 -0
  537. package/dist/lib/verify.d.ts.map +1 -0
  538. package/dist/lib/verify.js +1153 -0
  539. package/dist/lib/verify.js.map +1 -0
  540. package/dist/lib/wireup/autofix.d.ts +2 -0
  541. package/dist/lib/wireup/autofix.d.ts.map +1 -0
  542. package/dist/lib/wireup/autofix.js +188 -0
  543. package/dist/lib/wireup/autofix.js.map +1 -0
  544. package/dist/lib/wireup/cli.d.ts +2 -0
  545. package/dist/lib/wireup/cli.d.ts.map +1 -0
  546. package/dist/lib/wireup/cli.js +194 -0
  547. package/dist/lib/wireup/cli.js.map +1 -0
  548. package/dist/lib/wireup/detection.d.ts +47 -0
  549. package/dist/lib/wireup/detection.d.ts.map +1 -0
  550. package/dist/lib/wireup/detection.js +410 -0
  551. package/dist/lib/wireup/detection.js.map +1 -0
  552. package/dist/lib/wireup/discovery.d.ts +2 -0
  553. package/dist/lib/wireup/discovery.d.ts.map +1 -0
  554. package/dist/lib/wireup/discovery.js +934 -0
  555. package/dist/lib/wireup/discovery.js.map +1 -0
  556. package/dist/lib/wireup/execution.d.ts +2 -0
  557. package/dist/lib/wireup/execution.d.ts.map +1 -0
  558. package/dist/lib/wireup/execution.js +573 -0
  559. package/dist/lib/wireup/execution.js.map +1 -0
  560. package/dist/lib/wireup/index.d.ts +2 -0
  561. package/dist/lib/wireup/index.d.ts.map +1 -0
  562. package/dist/lib/wireup/index.js +85 -0
  563. package/dist/lib/wireup/index.js.map +1 -0
  564. package/dist/lib/wireup/orchestrator.d.ts +2 -0
  565. package/dist/lib/wireup/orchestrator.d.ts.map +1 -0
  566. package/dist/lib/wireup/orchestrator.js +366 -0
  567. package/dist/lib/wireup/orchestrator.js.map +1 -0
  568. package/dist/lib/wireup/report.d.ts +47 -0
  569. package/dist/lib/wireup/report.d.ts.map +1 -0
  570. package/dist/lib/wireup/report.js +201 -0
  571. package/dist/lib/wireup/report.js.map +1 -0
  572. package/dist/lib/wireup/scenarios.d.ts +2 -0
  573. package/dist/lib/wireup/scenarios.d.ts.map +1 -0
  574. package/dist/lib/wireup/scenarios.js +516 -0
  575. package/dist/lib/wireup/scenarios.js.map +1 -0
  576. package/dist/lib/wireup/state.d.ts +2 -0
  577. package/dist/lib/wireup/state.d.ts.map +1 -0
  578. package/dist/lib/wireup/state.js +102 -0
  579. package/dist/lib/wireup/state.js.map +1 -0
  580. package/dist/lib/wireup/types.d.ts +376 -0
  581. package/dist/lib/wireup/types.d.ts.map +1 -0
  582. package/dist/lib/wireup/types.js +3 -0
  583. package/dist/lib/wireup/types.js.map +1 -0
  584. package/dist/lib/worktree.d.ts +2 -0
  585. package/dist/lib/worktree.d.ts.map +1 -0
  586. package/dist/lib/worktree.js +999 -0
  587. package/dist/lib/worktree.js.map +1 -0
  588. package/lib/autopilot-milestone.ts +136 -0
  589. package/lib/autopilot-pipeline.ts +1179 -0
  590. package/lib/autopilot-waves.ts +361 -0
  591. package/lib/autopilot.ts +1874 -0
  592. package/lib/autoplan.ts +280 -0
  593. package/lib/autoresearch.js +4 -0
  594. package/lib/autoresearch.ts +886 -0
  595. package/lib/backend.ts +1252 -0
  596. package/lib/benchmark.ts +341 -0
  597. package/lib/citations.ts +760 -0
  598. package/lib/cleanup.ts +1588 -0
  599. package/lib/cli/adapters.ts +41 -0
  600. package/lib/cli/agent.ts +83 -0
  601. package/lib/cli/index.ts +273 -0
  602. package/lib/cli/output.ts +33 -0
  603. package/lib/cli/scan-dispatch.ts +130 -0
  604. package/lib/cli/tools.ts +198 -0
  605. package/lib/commands/_dashboard-parsers.ts +275 -0
  606. package/lib/commands/analysis.ts +1851 -0
  607. package/lib/commands/assumptions.ts +232 -0
  608. package/lib/commands/blame.ts +174 -0
  609. package/lib/commands/budget.ts +148 -0
  610. package/lib/commands/check-plans.ts +233 -0
  611. package/lib/commands/config.ts +287 -0
  612. package/lib/commands/dashboard.ts +680 -0
  613. package/lib/commands/estimate.ts +204 -0
  614. package/lib/commands/eval-diff.ts +252 -0
  615. package/lib/commands/freshness.ts +213 -0
  616. package/lib/commands/health.ts +607 -0
  617. package/lib/commands/index.ts +266 -0
  618. package/lib/commands/install.ts +307 -0
  619. package/lib/commands/knowhow-aggregator.ts +345 -0
  620. package/lib/commands/knowledge-search.ts +153 -0
  621. package/lib/commands/long-term-roadmap.ts +390 -0
  622. package/lib/commands/patterns.ts +465 -0
  623. package/lib/commands/phase-info.ts +698 -0
  624. package/lib/commands/plan-lint.ts +546 -0
  625. package/lib/commands/plan-phase.ts +375 -0
  626. package/lib/commands/progress.ts +319 -0
  627. package/lib/commands/quality.ts +138 -0
  628. package/lib/commands/rollback.ts +195 -0
  629. package/lib/commands/scan.ts +72 -0
  630. package/lib/commands/search.ts +300 -0
  631. package/lib/commands/select-candidate.ts +687 -0
  632. package/lib/commands/singularity.ts +222 -0
  633. package/lib/commands/slug-timestamp.ts +74 -0
  634. package/lib/commands/tail.ts +129 -0
  635. package/lib/commands/todo.ts +273 -0
  636. package/lib/commands/watch.ts +80 -0
  637. package/lib/complexity.ts +117 -0
  638. package/lib/context/agents.ts +505 -0
  639. package/lib/context/base.ts +123 -0
  640. package/lib/context/execute.ts +977 -0
  641. package/lib/context/index.ts +110 -0
  642. package/lib/context/progress.ts +278 -0
  643. package/lib/context/project.ts +531 -0
  644. package/lib/context/research.ts +646 -0
  645. package/lib/dead-ends.ts +506 -0
  646. package/lib/deps.ts +773 -0
  647. package/lib/discussion.ts +1275 -0
  648. package/lib/drift.ts +519 -0
  649. package/lib/evolve/_dimensions-features.ts +525 -0
  650. package/lib/evolve/_dimensions.ts +511 -0
  651. package/lib/evolve/_product-ideation.ts +405 -0
  652. package/lib/evolve/_prompts.ts +178 -0
  653. package/lib/evolve/cli.ts +330 -0
  654. package/lib/evolve/discovery.ts +571 -0
  655. package/lib/evolve/index.ts +105 -0
  656. package/lib/evolve/orchestrator.ts +1139 -0
  657. package/lib/evolve/scoring.ts +167 -0
  658. package/lib/evolve/state.ts +330 -0
  659. package/lib/evolve/types.ts +290 -0
  660. package/lib/frontmatter.ts +615 -0
  661. package/lib/gates.ts +695 -0
  662. package/lib/genome.ts +402 -0
  663. package/lib/got.js +4 -0
  664. package/lib/got.ts +361 -0
  665. package/lib/invariants.ts +378 -0
  666. package/lib/knowledge.ts +768 -0
  667. package/lib/long-term-roadmap.ts +806 -0
  668. package/lib/markdown-split.ts +273 -0
  669. package/lib/mcp-server.ts +3292 -0
  670. package/lib/metrics.ts +49 -0
  671. package/lib/overstory.ts +270 -0
  672. package/lib/parallel.ts +570 -0
  673. package/lib/paths.ts +293 -0
  674. package/lib/phase-complete-llm.ts +376 -0
  675. package/lib/phase-complete.ts +366 -0
  676. package/lib/phase-io.ts +101 -0
  677. package/lib/phase.ts +1981 -0
  678. package/lib/plan-tournament.ts +426 -0
  679. package/lib/refinement.ts +349 -0
  680. package/lib/requirements.ts +469 -0
  681. package/lib/research-bundle.ts +300 -0
  682. package/lib/roadmap.ts +775 -0
  683. package/lib/scaffold.ts +480 -0
  684. package/lib/scan/_utils.ts +37 -0
  685. package/lib/scan/base64.ts +90 -0
  686. package/lib/scan/ignorefile.ts +109 -0
  687. package/lib/scan/injection.ts +67 -0
  688. package/lib/scan/patterns.ts +139 -0
  689. package/lib/scan/strip-markdown.ts +39 -0
  690. package/lib/scan/types.ts +28 -0
  691. package/lib/scheduler-wait.ts +58 -0
  692. package/lib/scheduler.ts +1370 -0
  693. package/lib/state.ts +1000 -0
  694. package/lib/think.ts +365 -0
  695. package/lib/tracker.ts +1591 -0
  696. package/lib/types.ts +1663 -0
  697. package/lib/utils.ts +1479 -0
  698. package/lib/verify.ts +1434 -0
  699. package/lib/wireup/autofix.ts +241 -0
  700. package/lib/wireup/cli.ts +278 -0
  701. package/lib/wireup/detection.ts +542 -0
  702. package/lib/wireup/discovery.ts +1063 -0
  703. package/lib/wireup/execution.ts +686 -0
  704. package/lib/wireup/index.ts +117 -0
  705. package/lib/wireup/orchestrator.ts +519 -0
  706. package/lib/wireup/report.ts +286 -0
  707. package/lib/wireup/scenarios.ts +616 -0
  708. package/lib/wireup/state.ts +139 -0
  709. package/lib/wireup/types.ts +436 -0
  710. package/lib/worktree.ts +1309 -0
  711. package/package.json +67 -0
@@ -0,0 +1,1036 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fs = require('fs');
4
+ const os = require('os');
5
+ const path = require('path');
6
+ const { execFileSync } = require('child_process');
7
+ // --- Constants ---------------------------------------------------------------
8
+ /**
9
+ * List of valid backend identifiers.
10
+ */
11
+ const VALID_BACKENDS = [
12
+ 'claude',
13
+ 'codex',
14
+ 'gemini',
15
+ 'opencode',
16
+ 'overstory',
17
+ 'superpowers',
18
+ 'grd',
19
+ ];
20
+ /**
21
+ * Default model name mappings per backend and tier.
22
+ * Each backend maps the abstract tiers (opus, sonnet, haiku) to concrete
23
+ * model identifiers recognized by that backend's CLI.
24
+ */
25
+ const DEFAULT_BACKEND_MODELS = {
26
+ claude: { opus: 'opus', sonnet: 'sonnet', haiku: 'haiku' },
27
+ codex: {
28
+ opus: 'gpt-5.4',
29
+ sonnet: 'gpt-5.3-codex-spark',
30
+ haiku: 'gpt-5.4-mini',
31
+ },
32
+ gemini: {
33
+ opus: 'gemini-3.1-pro',
34
+ sonnet: 'gemini-3.1-flash',
35
+ haiku: 'gemini-3.1-flash-lite',
36
+ },
37
+ opencode: {
38
+ opus: 'anthropic/claude-opus-4-6',
39
+ sonnet: 'anthropic/claude-sonnet-4-6',
40
+ haiku: 'anthropic/claude-haiku-4-5',
41
+ },
42
+ overstory: { opus: 'opus', sonnet: 'sonnet', haiku: 'haiku' },
43
+ superpowers: { opus: 'opus', sonnet: 'sonnet', haiku: 'haiku' },
44
+ grd: { opus: 'opus', sonnet: 'sonnet', haiku: 'haiku' },
45
+ };
46
+ /**
47
+ * Capability flags per backend. Describes what orchestration features each
48
+ * backend supports. Used to degrade gracefully for backends with limited features.
49
+ */
50
+ const BACKEND_CAPABILITIES = {
51
+ claude: {
52
+ subagents: true,
53
+ parallel: true,
54
+ teams: true,
55
+ hooks: true,
56
+ mcp: true,
57
+ native_worktree_isolation: true,
58
+ effort: true,
59
+ http_hooks: true,
60
+ cron: true,
61
+ smart_approvals: false,
62
+ plan_mode: false,
63
+ sandbox_gvisor: false,
64
+ sandbox_lxc: false,
65
+ mcp_elicitation: true,
66
+ model_overrides: true,
67
+ max_output_tokens: { default: 64000, upper_bound: 128000 },
68
+ },
69
+ codex: {
70
+ subagents: true,
71
+ parallel: true,
72
+ teams: true,
73
+ hooks: true,
74
+ mcp: true,
75
+ native_worktree_isolation: false,
76
+ effort: false,
77
+ http_hooks: false,
78
+ cron: false,
79
+ smart_approvals: true,
80
+ plan_mode: false,
81
+ sandbox_gvisor: false,
82
+ sandbox_lxc: false,
83
+ mcp_elicitation: false,
84
+ model_overrides: true,
85
+ max_output_tokens: null,
86
+ },
87
+ gemini: {
88
+ subagents: true,
89
+ parallel: true,
90
+ teams: false,
91
+ hooks: true,
92
+ mcp: true,
93
+ native_worktree_isolation: false,
94
+ effort: false,
95
+ http_hooks: false,
96
+ cron: false,
97
+ smart_approvals: false,
98
+ plan_mode: true,
99
+ sandbox_gvisor: true,
100
+ sandbox_lxc: false,
101
+ mcp_elicitation: false,
102
+ model_overrides: true,
103
+ max_output_tokens: null,
104
+ },
105
+ opencode: {
106
+ subagents: true,
107
+ parallel: true,
108
+ teams: false,
109
+ hooks: true,
110
+ mcp: true,
111
+ native_worktree_isolation: false,
112
+ effort: false,
113
+ http_hooks: false,
114
+ cron: false,
115
+ smart_approvals: false,
116
+ plan_mode: false,
117
+ sandbox_gvisor: false,
118
+ sandbox_lxc: false,
119
+ mcp_elicitation: false,
120
+ model_overrides: true,
121
+ max_output_tokens: null,
122
+ },
123
+ overstory: {
124
+ subagents: true,
125
+ parallel: true,
126
+ teams: true,
127
+ hooks: false,
128
+ mcp: true,
129
+ native_worktree_isolation: true,
130
+ effort: false,
131
+ http_hooks: false,
132
+ cron: false,
133
+ smart_approvals: false,
134
+ plan_mode: false,
135
+ sandbox_gvisor: false,
136
+ sandbox_lxc: false,
137
+ mcp_elicitation: false,
138
+ model_overrides: true,
139
+ max_output_tokens: null,
140
+ },
141
+ superpowers: {
142
+ subagents: true,
143
+ parallel: true,
144
+ teams: true,
145
+ hooks: true,
146
+ mcp: true,
147
+ native_worktree_isolation: true,
148
+ effort: true,
149
+ http_hooks: false,
150
+ cron: false,
151
+ smart_approvals: false,
152
+ plan_mode: false,
153
+ sandbox_gvisor: false,
154
+ sandbox_lxc: false,
155
+ mcp_elicitation: false,
156
+ model_overrides: true,
157
+ max_output_tokens: null,
158
+ },
159
+ grd: {
160
+ subagents: true,
161
+ parallel: true,
162
+ teams: true,
163
+ hooks: true,
164
+ mcp: true,
165
+ native_worktree_isolation: true,
166
+ effort: false,
167
+ http_hooks: false,
168
+ cron: false,
169
+ smart_approvals: false,
170
+ plan_mode: false,
171
+ sandbox_gvisor: false,
172
+ sandbox_lxc: false,
173
+ mcp_elicitation: false,
174
+ model_overrides: false,
175
+ max_output_tokens: null,
176
+ },
177
+ };
178
+ // --- Effort Level Profiles ---------------------------------------------------
179
+ /**
180
+ * Default effort levels per agent and profile. Mirrors MODEL_PROFILES in utils.ts
181
+ * but for the effort dimension. Effort controls reasoning depth in backends that
182
+ * support it (currently Claude Code v2.1.68+).
183
+ *
184
+ * Design intent (from REQ-92):
185
+ * quality => planners/executors get high (deep reasoning), verifiers get medium
186
+ * balanced => planners get high, executors get medium, verifiers/lightweight agents get low
187
+ * budget => everything low (fast, minimal reasoning)
188
+ */
189
+ const EFFORT_PROFILES = {
190
+ 'grd-planner': { quality: 'high', balanced: 'high', budget: 'low' },
191
+ 'grd-roadmapper': { quality: 'high', balanced: 'medium', budget: 'low' },
192
+ 'grd-executor': { quality: 'high', balanced: 'medium', budget: 'low' },
193
+ 'grd-phase-researcher': { quality: 'high', balanced: 'medium', budget: 'low' },
194
+ 'grd-project-researcher': { quality: 'high', balanced: 'medium', budget: 'low' },
195
+ 'grd-research-synthesizer': { quality: 'medium', balanced: 'medium', budget: 'low' },
196
+ 'grd-debugger': { quality: 'high', balanced: 'medium', budget: 'low' },
197
+ 'grd-codebase-mapper': { quality: 'medium', balanced: 'low', budget: 'low' },
198
+ 'grd-verifier': { quality: 'medium', balanced: 'low', budget: 'low' },
199
+ 'grd-critique-agent': { quality: 'medium', balanced: 'low', budget: 'low' },
200
+ 'grd-plan-checker': { quality: 'medium', balanced: 'medium', budget: 'low' },
201
+ 'grd-integration-checker': { quality: 'medium', balanced: 'medium', budget: 'low' },
202
+ 'grd-surveyor': { quality: 'medium', balanced: 'medium', budget: 'low' },
203
+ 'grd-deep-diver': { quality: 'high', balanced: 'medium', budget: 'low' },
204
+ 'grd-feasibility-analyst': { quality: 'high', balanced: 'medium', budget: 'low' },
205
+ 'grd-eval-planner': { quality: 'high', balanced: 'medium', budget: 'low' },
206
+ 'grd-eval-reporter': { quality: 'medium', balanced: 'medium', budget: 'low' },
207
+ 'grd-product-owner': { quality: 'high', balanced: 'high', budget: 'low' },
208
+ 'grd-baseline-assessor': { quality: 'medium', balanced: 'medium', budget: 'low' },
209
+ 'grd-code-reviewer': { quality: 'high', balanced: 'medium', budget: 'low' },
210
+ };
211
+ /**
212
+ * Resolve the effort level for a given agent type and model profile.
213
+ *
214
+ * Returns the effort level from EFFORT_PROFILES for the given agent and profile.
215
+ * Unknown agent types return 'medium' as a safe default. Unknown profiles
216
+ * fall back to 'balanced', then to 'medium'.
217
+ *
218
+ * @param agentType - Agent type key (e.g., 'grd-executor', 'grd-planner')
219
+ * @param profile - Model profile name ('quality', 'balanced', or 'budget')
220
+ * @returns The effort level string: 'low', 'medium', or 'high'
221
+ */
222
+ function resolveEffortLevel(agentType, profile) {
223
+ const agentEffort = EFFORT_PROFILES[agentType];
224
+ if (!agentEffort)
225
+ return 'medium';
226
+ return agentEffort[profile] || agentEffort['balanced'] || 'medium';
227
+ }
228
+ /**
229
+ * Read and parse .planning/config.json from cwd. Returns parsed object or null.
230
+ * Uses fs.readFileSync directly to avoid circular dependency with lib/utils.js.
231
+ */
232
+ function readConfig(cwd) {
233
+ try {
234
+ const configPath = path.join(cwd, '.planning', 'config.json');
235
+ const raw = fs.readFileSync(configPath, 'utf-8');
236
+ return JSON.parse(raw);
237
+ }
238
+ catch {
239
+ return null;
240
+ }
241
+ }
242
+ /**
243
+ * Check if any environment variable starts with a given prefix.
244
+ */
245
+ function hasEnvPrefix(prefix) {
246
+ return Object.keys(process.env).some((k) => k.startsWith(prefix));
247
+ }
248
+ /**
249
+ * Check if a file exists at a given path.
250
+ */
251
+ function fileExists(filePath) {
252
+ try {
253
+ fs.statSync(filePath);
254
+ return true;
255
+ }
256
+ catch {
257
+ return false;
258
+ }
259
+ }
260
+ // --- Exported Functions ------------------------------------------------------
261
+ /**
262
+ * Detect which AI coding CLI backend is currently running.
263
+ *
264
+ * Detection waterfall (highest to lowest priority):
265
+ * 1. Config override: .planning/config.json `backend` field
266
+ * 2. Environment variables: CLAUDE_CODE_*, CODEX_HOME, GEMINI_CLI_HOME, OPENCODE
267
+ * 3. Filesystem clues: .claude-plugin/plugin.json, .codex/config.toml, etc.
268
+ * 4. Default: 'claude' (backward compatible)
269
+ *
270
+ * Note: The AGENT env var is NOT used for OpenCode detection per PITFALLS.md P5
271
+ * (too generic, may collide with other tools).
272
+ *
273
+ * @param cwd - Absolute path to the project root directory used for config and filesystem detection
274
+ * @returns The detected backend identifier (e.g. 'claude', 'codex', 'gemini', 'opencode')
275
+ */
276
+ function detectBackend(cwd) {
277
+ // Step 1: Config override (highest priority)
278
+ const config = readConfig(cwd);
279
+ if (config && config.backend && VALID_BACKENDS.includes(config.backend)) {
280
+ return config.backend;
281
+ }
282
+ // Step 2: Environment variable detection
283
+ // Superpowers detection (highest env priority — orchestrates other backends)
284
+ if (process.env.SUPERPOWERS_HOME || process.env.SUPERPOWERS_SESSION)
285
+ return 'superpowers';
286
+ // Overstory detection (before Claude — takes priority when both present)
287
+ if (process.env.OVERSTORY_HOME || process.env.OVERSTORY_SESSION)
288
+ return 'overstory';
289
+ if (hasEnvPrefix('CLAUDE_CODE_'))
290
+ return 'claude';
291
+ // CODEX_THREAD_ID: may be deprecated in newer Codex CLI versions (no docs mention
292
+ // as of March 2026), but kept for backward compatibility with older installations.
293
+ if (process.env.CODEX_HOME || process.env.CODEX_THREAD_ID)
294
+ return 'codex';
295
+ if (process.env.GEMINI_CLI_HOME)
296
+ return 'gemini';
297
+ // OpenCode: actively maintained under anomalyco/opencode (original opencode-ai
298
+ // repo archived Sept 2025). OPENCODE_PID is NOT used — it's a process management
299
+ // var, not a presence indicator.
300
+ if (process.env.OPENCODE)
301
+ return 'opencode';
302
+ // Step 3: Filesystem clues
303
+ if (fileExists(path.join(cwd, '.superpowers', 'config.json')))
304
+ return 'superpowers';
305
+ if (fileExists(path.join(cwd, '.overstory', 'config.yaml')))
306
+ return 'overstory';
307
+ if (fileExists(path.join(cwd, '.claude-plugin', 'plugin.json')))
308
+ return 'claude';
309
+ if (fileExists(path.join(cwd, '.codex', 'config.toml')))
310
+ return 'codex';
311
+ if (fileExists(path.join(cwd, '.gemini', 'settings.json')))
312
+ return 'gemini';
313
+ if (fileExists(path.join(cwd, 'opencode.json')))
314
+ return 'opencode';
315
+ // Step 4: Default (backward compatible)
316
+ return 'claude';
317
+ }
318
+ // --- Dynamic Model Detection -------------------------------------------------
319
+ /**
320
+ * Parse `opencode models` stdout into tier-classified model map.
321
+ * Classifies each model ID by keyword patterns:
322
+ * opus tier: /opus/i, /pro/i (non-flash)
323
+ * sonnet tier: /sonnet/i
324
+ * haiku tier: /haiku/i, /flash/i, /mini/i, /spark/i
325
+ *
326
+ * @param stdout - Raw stdout string from the `opencode models` CLI command
327
+ * @returns A DetectedModels map with opus/sonnet/haiku slots filled where matched, or null if no models were matched
328
+ */
329
+ function parseOpenCodeModels(stdout) {
330
+ if (!stdout || typeof stdout !== 'string')
331
+ return null;
332
+ const lines = stdout
333
+ .split('\n')
334
+ .map((l) => l.trim())
335
+ .filter((l) => l && !l.startsWith('Available') && !l.startsWith('---') && !l.startsWith('#'));
336
+ const result = { opus: null, sonnet: null, haiku: null };
337
+ let matched = false;
338
+ for (const line of lines) {
339
+ const model = line.split(/\s+/)[0];
340
+ if (!model || !model.includes('/'))
341
+ continue;
342
+ if (/opus/i.test(model)) {
343
+ if (!result.opus) {
344
+ result.opus = model;
345
+ matched = true;
346
+ }
347
+ }
348
+ else if (/sonnet/i.test(model)) {
349
+ if (!result.sonnet) {
350
+ result.sonnet = model;
351
+ matched = true;
352
+ }
353
+ }
354
+ else if (/haiku/i.test(model)) {
355
+ if (!result.haiku) {
356
+ result.haiku = model;
357
+ matched = true;
358
+ }
359
+ }
360
+ else if (/pro/i.test(model) && !/flash/i.test(model)) {
361
+ if (!result.opus) {
362
+ result.opus = model;
363
+ matched = true;
364
+ }
365
+ }
366
+ else if (/flash/i.test(model) || /mini/i.test(model) || /spark/i.test(model)) {
367
+ if (!result.haiku) {
368
+ result.haiku = model;
369
+ matched = true;
370
+ }
371
+ }
372
+ }
373
+ return matched ? result : null;
374
+ }
375
+ /**
376
+ * Run backend-specific CLI command to detect available models.
377
+ * Currently only OpenCode supports programmatic model listing.
378
+ */
379
+ function detectModels(backend, cwd) {
380
+ if (backend !== 'opencode')
381
+ return null;
382
+ const effectiveCwd = cwd || process.cwd();
383
+ const cfg = readConfig(effectiveCwd);
384
+ const timeouts = cfg?.timeouts;
385
+ const timeout = typeof timeouts?.backend_detect_ms === 'number' ? timeouts.backend_detect_ms : 10000;
386
+ try {
387
+ const stdout = execFileSync('opencode', ['models'], {
388
+ cwd: effectiveCwd,
389
+ timeout,
390
+ encoding: 'utf-8',
391
+ stdio: ['pipe', 'pipe', 'pipe'],
392
+ });
393
+ return parseOpenCodeModels(stdout);
394
+ }
395
+ catch {
396
+ return null;
397
+ }
398
+ }
399
+ const _modelCache = new Map();
400
+ const MODEL_CACHE_TTL_MS = 5 * 60 * 1000;
401
+ /**
402
+ * Get cached detected models for a backend, refreshing if TTL expired.
403
+ */
404
+ function getCachedModels(backend, cwd) {
405
+ const entry = _modelCache.get(backend);
406
+ const now = Date.now();
407
+ if (entry && now - entry.ts < MODEL_CACHE_TTL_MS) {
408
+ return entry.models;
409
+ }
410
+ const models = detectModels(backend, cwd);
411
+ _modelCache.set(backend, { models, ts: now });
412
+ return models;
413
+ }
414
+ /**
415
+ * Clear the model detection cache. Exported for testing.
416
+ */
417
+ function clearModelCache() {
418
+ _modelCache.clear();
419
+ }
420
+ /**
421
+ * Resolve an abstract model tier to a backend-specific model name.
422
+ *
423
+ * Checks config.backend_models for user overrides first, then falls back
424
+ * to DEFAULT_BACKEND_MODELS. Unknown backends fall back to claude mappings.
425
+ * Unknown tiers return undefined.
426
+ *
427
+ * @param backend - The backend identifier (e.g. 'claude', 'codex', 'gemini', 'opencode')
428
+ * @param tier - The abstract model tier to resolve ('opus', 'sonnet', or 'haiku')
429
+ * @param config - Optional parsed config.json object used for user-defined backend_models overrides
430
+ * @param cwd - Optional project root path used for dynamic model detection (opencode only)
431
+ * @returns The backend-specific model name string, or undefined if the tier is not mapped
432
+ */
433
+ function resolveBackendModel(backend, tier, config, cwd) {
434
+ // Check user override from config (highest priority)
435
+ if (config && config.backend_models) {
436
+ const backendModelsConfig = config.backend_models;
437
+ const backendOverrides = backendModelsConfig[backend];
438
+ if (backendOverrides && backendOverrides[tier] !== undefined) {
439
+ return backendOverrides[tier];
440
+ }
441
+ }
442
+ // Check dynamically detected models (middle priority)
443
+ if (cwd) {
444
+ const detected = getCachedModels(backend, cwd);
445
+ if (detected && detected[tier]) {
446
+ return detected[tier];
447
+ }
448
+ }
449
+ // Use built-in defaults, falling back to claude for unknown backends
450
+ const backendModels = DEFAULT_BACKEND_MODELS[backend] || DEFAULT_BACKEND_MODELS.claude;
451
+ return backendModels[tier];
452
+ }
453
+ /**
454
+ * Get capability flags for a backend.
455
+ *
456
+ * Returns an object describing what orchestration features the backend supports.
457
+ * Unknown backends get minimal capabilities (all false) to prevent
458
+ * accidentally enabling features like native_worktree_isolation or effort.
459
+ *
460
+ * @param backend - The backend identifier (e.g. 'claude', 'codex', 'gemini', 'opencode')
461
+ * @returns A BackendCapabilities object describing which orchestration features are supported
462
+ */
463
+ function getBackendCapabilities(backend) {
464
+ if (BACKEND_CAPABILITIES[backend]) {
465
+ return BACKEND_CAPABILITIES[backend];
466
+ }
467
+ // Unknown backend: warn and return minimal capabilities
468
+ process.stderr.write(`[grd] WARNING: unknown backend "${backend}", using minimal capabilities\n`);
469
+ return {
470
+ subagents: true,
471
+ parallel: false,
472
+ teams: false,
473
+ hooks: false,
474
+ mcp: false,
475
+ native_worktree_isolation: false,
476
+ effort: false,
477
+ http_hooks: false,
478
+ cron: false,
479
+ smart_approvals: false,
480
+ plan_mode: false,
481
+ sandbox_gvisor: false,
482
+ sandbox_lxc: false,
483
+ mcp_elicitation: false,
484
+ model_overrides: false,
485
+ max_output_tokens: null,
486
+ };
487
+ }
488
+ // --- WebMCP Detection --------------------------------------------------------
489
+ /**
490
+ * Detect whether Chrome DevTools MCP is available.
491
+ *
492
+ * Detection waterfall (highest to lowest priority):
493
+ * 1. Config override: .planning/config.json `webmcp.enabled` field
494
+ * 2. Environment variables: CHROME_DEVTOOLS_MCP, WEBMCP_AVAILABLE
495
+ * 3. Claude Code MCP settings: ~/.claude.json `mcpServers` key
496
+ * 4. Default: not available
497
+ *
498
+ * @param cwd - Absolute path to the project root directory used for config-based detection
499
+ * @returns A WebMcpResult indicating availability, the detection source, and an optional reason when unavailable
500
+ */
501
+ function detectWebMcp(cwd) {
502
+ // Step 1: Config override (highest priority)
503
+ const config = readConfig(cwd);
504
+ if (config && config.webmcp && typeof config.webmcp === 'object') {
505
+ const webmcp = config.webmcp;
506
+ if (typeof webmcp.enabled === 'boolean') {
507
+ if (webmcp.enabled) {
508
+ return { available: true, source: 'config' };
509
+ }
510
+ return {
511
+ available: false,
512
+ source: 'config',
513
+ reason: 'Disabled via config',
514
+ };
515
+ }
516
+ }
517
+ // Step 2: Environment variable check
518
+ const chromeDevToolsMcp = process.env.CHROME_DEVTOOLS_MCP;
519
+ const webmcpAvailable = process.env.WEBMCP_AVAILABLE;
520
+ if (chromeDevToolsMcp !== undefined) {
521
+ if (chromeDevToolsMcp === 'true' || chromeDevToolsMcp === '1') {
522
+ return { available: true, source: 'env' };
523
+ }
524
+ if (chromeDevToolsMcp === 'false' || chromeDevToolsMcp === '0') {
525
+ return {
526
+ available: false,
527
+ source: 'env',
528
+ reason: 'Disabled via environment variable',
529
+ };
530
+ }
531
+ }
532
+ if (webmcpAvailable !== undefined) {
533
+ if (webmcpAvailable === 'true' || webmcpAvailable === '1') {
534
+ return { available: true, source: 'env' };
535
+ }
536
+ if (webmcpAvailable === 'false' || webmcpAvailable === '0') {
537
+ return {
538
+ available: false,
539
+ source: 'env',
540
+ reason: 'Disabled via environment variable',
541
+ };
542
+ }
543
+ }
544
+ // Step 3: Claude Code MCP settings check (~/.claude.json)
545
+ try {
546
+ const homeDir = os.homedir();
547
+ const claudeConfigPath = path.join(homeDir, '.claude.json');
548
+ const raw = fs.readFileSync(claudeConfigPath, 'utf-8');
549
+ const claudeConfig = JSON.parse(raw);
550
+ if (claudeConfig && claudeConfig.mcpServers) {
551
+ const serverNames = Object.keys(claudeConfig.mcpServers);
552
+ const hasBrowserMcp = serverNames.some((name) => /chrome|devtools|playwright|browser/i.test(name));
553
+ if (hasBrowserMcp) {
554
+ return { available: true, source: 'mcp-config' };
555
+ }
556
+ }
557
+ }
558
+ catch {
559
+ // ~/.claude.json not found or malformed -- continue to default
560
+ }
561
+ // Step 4: Default
562
+ return {
563
+ available: false,
564
+ source: 'default',
565
+ reason: 'Chrome DevTools MCP not detected in config, environment, or MCP server settings',
566
+ };
567
+ }
568
+ // --- Playwright Detection ----------------------------------------------------
569
+ /**
570
+ * Detect whether Playwright MCP is available.
571
+ *
572
+ * Detection waterfall (highest to lowest priority):
573
+ * 1. Config override: .planning/config.json `playwright.enabled` field
574
+ * 2. Environment variable: PLAYWRIGHT_AVAILABLE
575
+ * 3. Claude Code MCP settings: ~/.claude.json `mcpServers` key (playwright name match)
576
+ * 4. Default: not available
577
+ *
578
+ * Mirrors the detectWebMcp() pattern exactly — same try/catch around ~/.claude.json,
579
+ * same config reading via readConfig(cwd), same env var parsing.
580
+ *
581
+ * @param cwd - Absolute path to the project root directory used for config-based detection
582
+ * @returns A PlaywrightResult indicating availability, the detection source, and an optional reason when unavailable
583
+ */
584
+ function detectPlaywright(cwd) {
585
+ // Step 1: Config override (highest priority)
586
+ const config = readConfig(cwd);
587
+ if (config && config.playwright && typeof config.playwright === 'object') {
588
+ const playwright = config.playwright;
589
+ if (typeof playwright.enabled === 'boolean') {
590
+ if (playwright.enabled) {
591
+ return { available: true, source: 'config' };
592
+ }
593
+ return {
594
+ available: false,
595
+ source: 'config',
596
+ reason: 'Disabled via config',
597
+ };
598
+ }
599
+ }
600
+ // Step 2: Environment variable check
601
+ const playwrightAvailable = process.env.PLAYWRIGHT_AVAILABLE;
602
+ if (playwrightAvailable !== undefined) {
603
+ if (playwrightAvailable === 'true' || playwrightAvailable === '1') {
604
+ return { available: true, source: 'env' };
605
+ }
606
+ if (playwrightAvailable === 'false' || playwrightAvailable === '0') {
607
+ return {
608
+ available: false,
609
+ source: 'env',
610
+ reason: 'Disabled via environment variable',
611
+ };
612
+ }
613
+ }
614
+ // Step 3: Claude Code MCP settings check (~/.claude.json)
615
+ try {
616
+ const homeDir = os.homedir();
617
+ const claudeConfigPath = path.join(homeDir, '.claude.json');
618
+ const raw = fs.readFileSync(claudeConfigPath, 'utf-8');
619
+ const claudeConfig = JSON.parse(raw);
620
+ if (claudeConfig && claudeConfig.mcpServers) {
621
+ const serverNames = Object.keys(claudeConfig.mcpServers);
622
+ const hasPlaywrightMcp = serverNames.some((name) => /playwright/i.test(name));
623
+ if (hasPlaywrightMcp) {
624
+ return { available: true, source: 'mcp-config' };
625
+ }
626
+ }
627
+ }
628
+ catch {
629
+ // ~/.claude.json not found or malformed -- continue to default
630
+ }
631
+ // Step 4: Default
632
+ return {
633
+ available: false,
634
+ source: 'default',
635
+ reason: 'Playwright MCP not detected in config, environment, or MCP server settings',
636
+ };
637
+ }
638
+ let _availabilityCache = null;
639
+ const AVAILABILITY_CACHE_TTL_MS = 5 * 60 * 1000;
640
+ /**
641
+ * Dispatchable backends — the four CLIs that discussion.ts can spawn directly.
642
+ * Meta-backends (overstory, superpowers, grd) are probed as unavailable.
643
+ */
644
+ const DISPATCHABLE_BACKENDS = ['claude', 'codex', 'gemini', 'opencode'];
645
+ /**
646
+ * Environment variable that controls the config directory for each backend CLI.
647
+ * When set, the CLI uses the specified directory for auth/credentials instead of default.
648
+ */
649
+ const BACKEND_CONFIG_ENV = {
650
+ claude: 'CLAUDE_CONFIG_DIR',
651
+ codex: 'CODEX_HOME',
652
+ gemini: 'GEMINI_CLI_HOME',
653
+ opencode: 'OPENCODE_CONFIG_DIR',
654
+ };
655
+ /**
656
+ * Files that prove a config directory has valid auth/credentials for a backend.
657
+ * Must be actual credential files, not files created by a bare first-run.
658
+ *
659
+ * Paths are relative to the config dir. Use nested paths for backends that
660
+ * store auth in a subdirectory (e.g. gemini stores creds in <dir>/.gemini/).
661
+ */
662
+ const BACKEND_AUTH_MARKERS = {
663
+ claude: ['credentials.json', '.credentials.json', 'settings.json'],
664
+ codex: ['auth.json'],
665
+ gemini: ['.gemini/oauth_creds.json', '.gemini/google_accounts.json'],
666
+ opencode: ['auth.json', 'config.json'],
667
+ };
668
+ /** Cached config dir discovery result. */
669
+ let _configDirCache = null;
670
+ /**
671
+ * Discover the actual config directory for each backend by scanning the home
672
+ * directory for directories matching ~/.<backend>* that contain auth marker files.
673
+ *
674
+ * Priority:
675
+ * 1. Current env var (e.g. CLAUDE_CONFIG_DIR already set)
676
+ * 2. First ~/.<backend>-* directory containing an auth marker file
677
+ * 3. Default ~/.<backend> if it contains an auth marker file
678
+ * 4. null (no config dir found — use backend's default)
679
+ */
680
+ function discoverBackendConfigDirs() {
681
+ if (_configDirCache)
682
+ return _configDirCache;
683
+ const homeDir = os.homedir();
684
+ const result = {};
685
+ for (const backend of DISPATCHABLE_BACKENDS) {
686
+ const envVar = BACKEND_CONFIG_ENV[backend];
687
+ const markers = BACKEND_AUTH_MARKERS[backend];
688
+ // 1. Check if env var is already set
689
+ if (envVar && process.env[envVar]) {
690
+ result[backend] = process.env[envVar];
691
+ continue;
692
+ }
693
+ // 2. Scan home directory for matching config dirs
694
+ let found = null;
695
+ try {
696
+ const entries = fs.readdirSync(homeDir);
697
+ // Collect candidates: ~/.<backend>-* first (custom profiles), then ~/.<backend> (default)
698
+ const profileDirs = entries
699
+ .filter((e) => e.startsWith(`.${backend}-`))
700
+ .sort();
701
+ const defaultDir = entries.filter((e) => e === `.${backend}`);
702
+ const candidates = [...profileDirs, ...defaultDir]
703
+ .map((e) => path.join(homeDir, e))
704
+ .filter((p) => {
705
+ try {
706
+ return fs.statSync(p).isDirectory();
707
+ }
708
+ catch {
709
+ return false;
710
+ }
711
+ });
712
+ // Check each candidate for auth marker files
713
+ for (const candidate of candidates) {
714
+ const hasAuth = markers.some((marker) => {
715
+ try {
716
+ return fs.statSync(path.join(candidate, marker)).isFile();
717
+ }
718
+ catch {
719
+ return false;
720
+ }
721
+ });
722
+ if (hasAuth) {
723
+ found = candidate;
724
+ break;
725
+ }
726
+ }
727
+ }
728
+ catch {
729
+ // Home dir not readable — skip
730
+ }
731
+ result[backend] = found;
732
+ }
733
+ _configDirCache = result;
734
+ return result;
735
+ }
736
+ /**
737
+ * Clear the config dir discovery cache. Exported for testing.
738
+ */
739
+ function clearConfigDirCache() {
740
+ _configDirCache = null;
741
+ }
742
+ /**
743
+ * Build the environment variables needed to run a backend CLI with the correct
744
+ * config directory. Returns a copy of process.env with the override applied.
745
+ */
746
+ function buildBackendEnv(backend) {
747
+ const env = { ...process.env };
748
+ // Strip Claude session env vars so subprocess doesn't detect nested invocation
749
+ for (const key of Object.keys(env)) {
750
+ if (key === 'CLAUDECODE' || key.startsWith('CLAUDE_CODE_') || key.startsWith('CLAUDECODE_')) {
751
+ delete env[key];
752
+ }
753
+ }
754
+ const configDirs = discoverBackendConfigDirs();
755
+ const configDir = configDirs[backend];
756
+ if (!configDir)
757
+ return env;
758
+ const envVar = BACKEND_CONFIG_ENV[backend];
759
+ if (!envVar)
760
+ return env;
761
+ return { ...env, [envVar]: configDir };
762
+ }
763
+ /**
764
+ * Probe which AI CLI backends are available on PATH.
765
+ *
766
+ * For each of the four dispatchable backends (claude, codex, gemini, opencode),
767
+ * runs `<binary> --version` with a 5-second timeout. Success means available.
768
+ * Meta-backends (overstory, superpowers, grd) are always marked unavailable here.
769
+ *
770
+ * Result is cached for 5 minutes (AVAILABILITY_CACHE_TTL_MS). Call
771
+ * clearAvailabilityCache() to force re-detection in tests.
772
+ *
773
+ * @param cwd - Optional working directory for subprocess (defaults to process.cwd())
774
+ * @returns A map of BackendId to BackendAvailability for all known backends
775
+ */
776
+ function detectAvailableBackends(cwd) {
777
+ const now = Date.now();
778
+ if (_availabilityCache && now - _availabilityCache.ts < AVAILABILITY_CACHE_TTL_MS) {
779
+ return _availabilityCache.result;
780
+ }
781
+ const effectiveCwd = cwd || process.cwd();
782
+ const unavailable = { available: false, version: null };
783
+ const probeCfg = readConfig(effectiveCwd);
784
+ const probeTimeouts = probeCfg?.timeouts;
785
+ const probeTimeout = typeof probeTimeouts?.backend_probe_ms === 'number' ? probeTimeouts.backend_probe_ms : 5000;
786
+ const result = {
787
+ claude: unavailable,
788
+ codex: unavailable,
789
+ gemini: unavailable,
790
+ opencode: unavailable,
791
+ overstory: unavailable,
792
+ superpowers: unavailable,
793
+ grd: unavailable,
794
+ };
795
+ for (const backend of DISPATCHABLE_BACKENDS) {
796
+ try {
797
+ const stdout = execFileSync(backend, ['--version'], {
798
+ cwd: effectiveCwd,
799
+ timeout: probeTimeout,
800
+ encoding: 'utf-8',
801
+ stdio: ['pipe', 'pipe', 'pipe'],
802
+ env: buildBackendEnv(backend),
803
+ });
804
+ result[backend] = {
805
+ available: true,
806
+ version: stdout.trim().split('\n')[0] || null,
807
+ };
808
+ }
809
+ catch {
810
+ result[backend] = { available: false, version: null };
811
+ }
812
+ }
813
+ _availabilityCache = { result, ts: now };
814
+ return result;
815
+ }
816
+ /**
817
+ * Clear the availability detection cache. Exported for testing.
818
+ */
819
+ function clearAvailabilityCache() {
820
+ _availabilityCache = null;
821
+ }
822
+ const _TIER_ORDER = ['opus', 'sonnet', 'haiku'];
823
+ /**
824
+ * Looks up how many tiers to downgrade given the profile, pressure,
825
+ * and complexity. Returns 0, 1, or 2. Pure function — table-driven.
826
+ */
827
+ function _lookupDowngradeCount(profile, pressure, complexity) {
828
+ // quality: only downgrade on critical pressure
829
+ if (profile === 'quality') {
830
+ if (pressure === 'critical')
831
+ return 1;
832
+ return 0;
833
+ }
834
+ // balanced: moderate adaptive downgrade
835
+ if (profile === 'balanced') {
836
+ if (pressure === 'none') {
837
+ if (complexity === 'low')
838
+ return 1;
839
+ return 0;
840
+ }
841
+ if (pressure === 'warning') {
842
+ if (complexity === 'high')
843
+ return 0;
844
+ return 1;
845
+ }
846
+ if (pressure === 'high') {
847
+ if (complexity === 'high')
848
+ return 0;
849
+ if (complexity === 'medium')
850
+ return 1;
851
+ return 2; // low
852
+ }
853
+ if (pressure === 'critical') {
854
+ if (complexity === 'high')
855
+ return 1;
856
+ return 2;
857
+ }
858
+ }
859
+ // frugal: aggressive downgrade
860
+ if (profile === 'frugal') {
861
+ if (pressure === 'none') {
862
+ if (complexity === 'high')
863
+ return 0;
864
+ return 1; // medium or low
865
+ }
866
+ if (pressure === 'warning') {
867
+ if (complexity === 'low')
868
+ return 2;
869
+ return 1;
870
+ }
871
+ // high or critical
872
+ return 2;
873
+ }
874
+ return 0;
875
+ }
876
+ /**
877
+ * Applies a downgrade count to a base tier, floored at the lowest tier.
878
+ * Returns the base tier unchanged if it's not in _TIER_ORDER (passthrough).
879
+ */
880
+ function _applyDowngrade(baseTier, count) {
881
+ const baseIndex = _TIER_ORDER.indexOf(baseTier);
882
+ if (baseIndex === -1)
883
+ return baseTier;
884
+ const targetIndex = Math.min(baseIndex + count, _TIER_ORDER.length - 1);
885
+ return _TIER_ORDER[targetIndex];
886
+ }
887
+ /**
888
+ * Applies an upgrade count to a base tier, capped at the strongest tier.
889
+ * Symmetric to _applyDowngrade. Used for verify-fail retry escalation
890
+ * (Tier-2 #5 of the Ouroboros integration) — when a dispatch is a retry
891
+ * after a verification failure, the agent runs at a stronger tier than
892
+ * the base, capped at opus. Returns the base tier unchanged if it's not
893
+ * in _TIER_ORDER (passthrough).
894
+ *
895
+ * Note: _TIER_ORDER is ordered strongest-to-weakest (opus, sonnet, haiku),
896
+ * so "upgrade" decreases the index.
897
+ */
898
+ function _applyUpgrade(baseTier, count) {
899
+ const baseIndex = _TIER_ORDER.indexOf(baseTier);
900
+ if (baseIndex === -1)
901
+ return baseTier;
902
+ const targetIndex = Math.max(baseIndex - count, 0);
903
+ return _TIER_ORDER[targetIndex];
904
+ }
905
+ /**
906
+ * Computes the effective model tier for an agent dispatch given the
907
+ * base tier (from MODEL_PROFILES), the user's token_profile preference,
908
+ * the current budget pressure level, and the task's complexity level.
909
+ *
910
+ * Pure function. Returns a possibly-downgraded ModelTier. The decision
911
+ * matrix is documented in the spec and implemented in _lookupDowngradeCount.
912
+ */
913
+ function computeEffectiveModelTier(opts) {
914
+ const count = _lookupDowngradeCount(opts.tokenProfile, opts.pressure, opts.complexity);
915
+ return _applyDowngrade(opts.baseTier, count);
916
+ }
917
+ const { estimateComplexity } = require('./complexity');
918
+ const { computeBudgetPressureLevel, logPressureTransition } = require('./scheduler');
919
+ /**
920
+ * Computes the effective model tier for an agent dispatch by running
921
+ * the Spec 4 chain: estimateComplexity → computeBudgetPressureLevel →
922
+ * computeEffectiveModelTier. Returns the tier to pass to
923
+ * resolveModelForAgent as effectiveTierOverride.
924
+ *
925
+ * When scheduler/schedulerConfig/superpowersConfig are null/undefined,
926
+ * returns the base tier unchanged (preserving pre-Spec-4 behavior).
927
+ *
928
+ * @param opts.agentType - Agent type key (e.g. 'grd-executor')
929
+ * @param opts.prompt - The prompt string (used for promptLength)
930
+ * @param opts.config - GrdConfig with model_profile and token_profile fields
931
+ * @param opts.scheduler - Scheduler instance or null when not configured
932
+ * @param opts.schedulerConfig - Scheduler configuration from config.scheduler
933
+ * @param opts.superpowersConfig - Superpowers config from config.superpowers
934
+ * @param opts.modelProfiles - MODEL_PROFILES table (passed in to avoid circular dep)
935
+ * @returns Effective model tier for this dispatch
936
+ */
937
+ function getEffectiveTierForDispatch(opts) {
938
+ const profile = opts.config.model_profile || 'balanced';
939
+ const agentEntry = opts.modelProfiles[opts.agentType];
940
+ const baseTier = ((agentEntry && agentEntry[profile]) || 'sonnet');
941
+ const retryAttempt = opts.retry_attempt && opts.retry_attempt > 0 ? opts.retry_attempt : 0;
942
+ if (!opts.scheduler || !opts.schedulerConfig || !opts.superpowersConfig) {
943
+ // No adaptive chain available — apply retry escalation directly to
944
+ // the base tier so retry_attempt still has an effect.
945
+ return retryAttempt > 0 ? _applyUpgrade(baseTier, retryAttempt) : baseTier;
946
+ }
947
+ const states = opts.scheduler.getStates();
948
+ // Collect recent samples from all priority accounts (most recent first).
949
+ // Spec 4 M2: collect agentType so we can prefer same-agent samples for
950
+ // complexity estimation. Old samples without agentType participate in the
951
+ // global pool only.
952
+ let recentSamples;
953
+ const allSamples = [];
954
+ for (const backend of opts.schedulerConfig.backend_priority) {
955
+ const backendAccounts = opts.superpowersConfig.accounts[backend] || [];
956
+ for (const account of backendAccounts) {
957
+ const stateKey = `${backend}/${account.config_dir}`;
958
+ const state = states.get(stateKey);
959
+ if (!state)
960
+ continue;
961
+ for (const sample of state.samples) {
962
+ allSamples.push({
963
+ duration: sample.duration,
964
+ tokenEstimate: sample.tokenEstimate,
965
+ timestamp: sample.timestamp,
966
+ agentType: sample.agentType,
967
+ });
968
+ }
969
+ }
970
+ }
971
+ if (allSamples.length >= 3) {
972
+ // Spec 4 M2: prefer per-agent samples if we have enough, else fall back
973
+ // to the global tail. Old samples without agentType participate in the
974
+ // global pool only.
975
+ const ownAgentSamples = allSamples.filter((s) => s.agentType === opts.agentType);
976
+ const samplesToUse = ownAgentSamples.length >= 3 ? ownAgentSamples : allSamples;
977
+ // Sort by timestamp descending, take up to 10 most recent
978
+ samplesToUse.sort((a, b) => b.timestamp - a.timestamp);
979
+ recentSamples = samplesToUse.slice(0, 10).map((s) => ({
980
+ duration: s.duration,
981
+ tokenEstimate: s.tokenEstimate,
982
+ }));
983
+ }
984
+ const complexity = estimateComplexity({
985
+ agentType: opts.agentType,
986
+ promptLength: opts.prompt.length,
987
+ recentSamples,
988
+ baselineOverride: opts.config.agent_complexity_overrides?.[opts.agentType],
989
+ heuristics: opts.config.complexity_heuristics,
990
+ });
991
+ const pressure = computeBudgetPressureLevel(states, opts.schedulerConfig.backend_priority, opts.superpowersConfig.accounts, opts.schedulerConfig.budget_pressure_thresholds);
992
+ const tokenProfile = opts.config.token_profile || 'balanced';
993
+ const adaptiveTier = computeEffectiveModelTier({
994
+ baseTier,
995
+ tokenProfile,
996
+ pressure,
997
+ complexity,
998
+ });
999
+ // Verify-fail retry escalation (Tier-2 #5). Applied AFTER adaptive
1000
+ // downgrade so that a retry escalates from whatever tier the adaptive
1001
+ // chain landed on, not from the original baseTier. Capped at opus.
1002
+ const effectiveTier = retryAttempt > 0 ? _applyUpgrade(adaptiveTier, retryAttempt) : adaptiveTier;
1003
+ // Spec 4 Goal #7: log on pressure transitions only (O3: use per-scheduler
1004
+ // sessionKey instead of process.pid to avoid shared state across multiple
1005
+ // createScheduler calls in the same process).
1006
+ logPressureTransition(opts.scheduler.sessionKey, pressure, opts.agentType, baseTier, effectiveTier);
1007
+ return effectiveTier;
1008
+ }
1009
+ // --- Exports -----------------------------------------------------------------
1010
+ module.exports = {
1011
+ VALID_BACKENDS,
1012
+ DEFAULT_BACKEND_MODELS,
1013
+ BACKEND_CAPABILITIES,
1014
+ EFFORT_PROFILES,
1015
+ _applyUpgrade,
1016
+ detectBackend,
1017
+ resolveBackendModel,
1018
+ resolveEffortLevel,
1019
+ getBackendCapabilities,
1020
+ parseOpenCodeModels,
1021
+ detectModels,
1022
+ getCachedModels,
1023
+ clearModelCache,
1024
+ detectWebMcp,
1025
+ detectPlaywright,
1026
+ detectAvailableBackends,
1027
+ clearAvailabilityCache,
1028
+ discoverBackendConfigDirs,
1029
+ clearConfigDirCache,
1030
+ buildBackendEnv,
1031
+ BACKEND_CONFIG_ENV,
1032
+ readConfig,
1033
+ computeEffectiveModelTier,
1034
+ getEffectiveTierForDispatch,
1035
+ };
1036
+ //# sourceMappingURL=backend.js.map