@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,375 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * GRD Commands/PlanPhase — multi-candidate plan scaffolding (v0.4 Phase 2).
5
+ *
6
+ * Parses a planner subprocess's marker-fenced output and writes N
7
+ * PLAN-i.md files to the phase directory atomically. Fail-closed by
8
+ * default: if the planner returned a count other than N, NO files are
9
+ * written. Pass --allow-partial-candidates to write what was found and
10
+ * warn loudly.
11
+ *
12
+ * Marker format the planner is told to emit (in commands/plan-phase.md
13
+ * <multi_candidate> block):
14
+ *
15
+ * <<<PLAN-1>>>
16
+ * ... full plan content (YAML frontmatter + body) ...
17
+ * <<</PLAN-1>>>
18
+ * <<<PLAN-2>>>
19
+ * ...
20
+ * <<</PLAN-2>>>
21
+ *
22
+ * When N === 1, this command is a no-op for the planner prompt
23
+ * (commands/plan-phase.md suppresses the <multi_candidate> block) and
24
+ * the planner writes a bare PLAN.md via its Write tool, as in v0.3.x.
25
+ *
26
+ * Public surface:
27
+ * - parsePlanCandidates(text, expectedN) — pure parser
28
+ * - writePlanCandidates(phaseDir, blocks) — atomic batched writer
29
+ * - cmdPlanPhase(cwd, phaseNum, opts, raw) — CLI entry
30
+ *
31
+ * Exit codes:
32
+ * 0 — success (N files written)
33
+ * 1 — validation failure (count mismatch, marker parse error)
34
+ * 2 — invocation error (phase not found, input unreadable)
35
+ */
36
+
37
+ const fs = require('fs') as typeof import('fs');
38
+ const path = require('path') as typeof import('path');
39
+
40
+ const {
41
+ findPhaseDir,
42
+ getMilestoneInfo,
43
+ loadConfig,
44
+ resolveEffortKnob,
45
+ output,
46
+ error,
47
+ }: {
48
+ findPhaseDir: (phasesDir: string, phaseArg: string) => string | null;
49
+ getMilestoneInfo: (cwd: string) => { version: string };
50
+ loadConfig: (cwd: string) => import('../types').GrdConfig;
51
+ resolveEffortKnob: (
52
+ config: import('../types').GrdConfig,
53
+ knob: import('../types').EffortKnobName
54
+ ) => number;
55
+ output: (result: unknown, raw: boolean, rawValue?: unknown) => never;
56
+ error: (message: string) => never;
57
+ } = require('../utils');
58
+
59
+ const {
60
+ atomicWriteFileSync,
61
+ }: {
62
+ atomicWriteFileSync: (filePath: string, data: string) => void;
63
+ } = require('../autopilot-waves');
64
+
65
+ // ─── Types ──────────────────────────────────────────────────────────────────
66
+
67
+ export interface PlanCandidateBlock {
68
+ index: number;
69
+ content: string;
70
+ }
71
+
72
+ export type ParseResult =
73
+ | { ok: true; blocks: PlanCandidateBlock[] }
74
+ | { ok: false; reason: string; foundIndices: number[] };
75
+
76
+ export interface WriteResult {
77
+ written: string[];
78
+ }
79
+
80
+ export interface PlanPhaseOptions {
81
+ candidates: number;
82
+ inputFile?: string;
83
+ allowPartial?: boolean;
84
+ }
85
+
86
+ // ─── Marker parsing ────────────────────────────────────────────────────────
87
+
88
+ const OPEN_RE = /^<<<PLAN-(\d+)>>>\s*$/;
89
+ const CLOSE_RE = /^<<<\/PLAN-(\d+)>>>\s*$/;
90
+
91
+ /**
92
+ * Parse marker-fenced PLAN blocks from planner output.
93
+ *
94
+ * Returns ok: true with sorted unique blocks when the count of valid
95
+ * <<<PLAN-i>>>...<<</PLAN-i>>> pairs equals expectedN AND the indices
96
+ * cover 1..expectedN exactly. Anything else returns ok: false with a
97
+ * reason and the list of indices that were found (for diagnostics).
98
+ *
99
+ * Rejects: duplicate indices, mismatched open/close pairs, nested
100
+ * blocks, blocks with index 0 or > expectedN.
101
+ */
102
+ export function parsePlanCandidates(text: string, expectedN: number): ParseResult {
103
+ if (expectedN < 1) {
104
+ return { ok: false, reason: 'expectedN must be >= 1', foundIndices: [] };
105
+ }
106
+
107
+ const lines: string[] = text.split('\n');
108
+ const blocks: PlanCandidateBlock[] = [];
109
+ let currentIndex: number | null = null;
110
+ let currentBuffer: string[] = [];
111
+
112
+ for (let i = 0; i < lines.length; i++) {
113
+ const line: string = lines[i];
114
+ const openMatch = line.match(OPEN_RE);
115
+ const closeMatch = line.match(CLOSE_RE);
116
+
117
+ if (openMatch) {
118
+ if (currentIndex !== null) {
119
+ return {
120
+ ok: false,
121
+ reason: `nested <<<PLAN-${openMatch[1]}>>> opened while <<<PLAN-${currentIndex}>>> still open (line ${i + 1})`,
122
+ foundIndices: blocks.map((b) => b.index),
123
+ };
124
+ }
125
+ currentIndex = parseInt(openMatch[1], 10);
126
+ currentBuffer = [];
127
+ } else if (closeMatch) {
128
+ const closeIndex: number = parseInt(closeMatch[1], 10);
129
+ if (currentIndex === null) {
130
+ return {
131
+ ok: false,
132
+ reason: `unexpected <<</PLAN-${closeIndex}>>> with no matching open (line ${i + 1})`,
133
+ foundIndices: blocks.map((b) => b.index),
134
+ };
135
+ }
136
+ if (closeIndex !== currentIndex) {
137
+ return {
138
+ ok: false,
139
+ reason: `mismatched <<</PLAN-${closeIndex}>>> for open <<<PLAN-${currentIndex}>>> (line ${i + 1})`,
140
+ foundIndices: blocks.map((b) => b.index),
141
+ };
142
+ }
143
+ blocks.push({ index: currentIndex, content: currentBuffer.join('\n') });
144
+ currentIndex = null;
145
+ currentBuffer = [];
146
+ } else if (currentIndex !== null) {
147
+ currentBuffer.push(line);
148
+ }
149
+ }
150
+
151
+ if (currentIndex !== null) {
152
+ return {
153
+ ok: false,
154
+ reason: `<<<PLAN-${currentIndex}>>> never closed`,
155
+ foundIndices: blocks.map((b) => b.index),
156
+ };
157
+ }
158
+
159
+ const indices: number[] = blocks.map((b) => b.index);
160
+
161
+ if (blocks.length !== expectedN) {
162
+ return {
163
+ ok: false,
164
+ reason: `expected ${expectedN} PLAN block(s), found ${blocks.length}`,
165
+ foundIndices: indices,
166
+ };
167
+ }
168
+
169
+ const seen: Set<number> = new Set();
170
+ for (const idx of indices) {
171
+ if (seen.has(idx)) {
172
+ return { ok: false, reason: `duplicate PLAN-${idx} block`, foundIndices: indices };
173
+ }
174
+ seen.add(idx);
175
+ }
176
+
177
+ for (let i = 1; i <= expectedN; i++) {
178
+ if (!seen.has(i)) {
179
+ return {
180
+ ok: false,
181
+ reason: `missing PLAN-${i} block (expected 1..${expectedN})`,
182
+ foundIndices: indices,
183
+ };
184
+ }
185
+ }
186
+
187
+ blocks.sort((a, b) => a.index - b.index);
188
+ return { ok: true, blocks };
189
+ }
190
+
191
+ // ─── File writing ──────────────────────────────────────────────────────────
192
+
193
+ /**
194
+ * Write each block to `<phaseDir>/PLAN-<i>.md` atomically. Writes are
195
+ * batched: every file's content is materialized to disk via
196
+ * atomicWriteFileSync. Callers are expected to have already validated
197
+ * that the phase directory exists.
198
+ */
199
+ export function writePlanCandidates(
200
+ phaseDir: string,
201
+ blocks: PlanCandidateBlock[]
202
+ ): WriteResult {
203
+ if (!fs.existsSync(phaseDir)) {
204
+ throw new Error(`phase directory not found: ${phaseDir}`);
205
+ }
206
+ const written: string[] = [];
207
+ for (const block of blocks) {
208
+ const filename: string = `PLAN-${block.index}.md`;
209
+ const filePath: string = path.join(phaseDir, filename);
210
+ atomicWriteFileSync(filePath, block.content);
211
+ written.push(filePath);
212
+ }
213
+ return { written };
214
+ }
215
+
216
+ // ─── CLI entry ─────────────────────────────────────────────────────────────
217
+
218
+ interface CmdResult {
219
+ phase: string;
220
+ phaseDir: string;
221
+ candidates: number;
222
+ blocksFound: number;
223
+ written: string[];
224
+ ok: boolean;
225
+ reason?: string;
226
+ }
227
+
228
+ /**
229
+ * `gd plan-phase <N> --candidates K [--input FILE] [--allow-partial-candidates]`
230
+ *
231
+ * Reads planner output text from --input (or stdin if no --input given),
232
+ * parses K marker-fenced PLAN blocks, and writes them as PLAN-1.md ...
233
+ * PLAN-K.md in the phase directory. Fail-closed on count mismatch
234
+ * unless --allow-partial-candidates is set.
235
+ *
236
+ * Default candidate count resolves from
237
+ * `resolveEffortKnob(config, 'candidates_per_plan_phase')` per
238
+ * v0.4 Phase 1.
239
+ */
240
+ export function cmdPlanPhase(
241
+ cwd: string,
242
+ phaseNum: string,
243
+ opts: PlanPhaseOptions,
244
+ raw: boolean
245
+ ): void {
246
+ const milestone = getMilestoneInfo(cwd);
247
+ const phasesDir: string = path.join(
248
+ cwd,
249
+ '.planning',
250
+ 'milestones',
251
+ milestone.version,
252
+ 'phases'
253
+ );
254
+ const phaseDirName: string | null = findPhaseDir(phasesDir, phaseNum);
255
+ if (!phaseDirName) {
256
+ error(`phase ${phaseNum} not found under ${phasesDir}`);
257
+ }
258
+ const phaseDir: string = path.join(phasesDir, phaseDirName as string);
259
+
260
+ // Resolve N: explicit --candidates wins; else fall back to effort knob.
261
+ let expectedN: number = opts.candidates;
262
+ if (!Number.isInteger(expectedN) || expectedN < 1) {
263
+ const cfg = loadConfig(cwd);
264
+ expectedN = resolveEffortKnob(cfg, 'candidates_per_plan_phase');
265
+ }
266
+ if (expectedN > 9) {
267
+ error(`--candidates ${expectedN} exceeds the v0.4 sanity bound of 9`);
268
+ }
269
+
270
+ // Read planner output: --input file path, or stdin if absent.
271
+ const plannerText: string = readPlannerInput(opts.inputFile);
272
+
273
+ const parsed: ParseResult = parsePlanCandidates(plannerText, expectedN);
274
+
275
+ if (!parsed.ok && !opts.allowPartial) {
276
+ const result: CmdResult = {
277
+ phase: phaseNum,
278
+ phaseDir,
279
+ candidates: expectedN,
280
+ blocksFound: parsed.foundIndices.length,
281
+ written: [],
282
+ ok: false,
283
+ reason: parsed.reason,
284
+ };
285
+ // Fail-closed: emit JSON / raw on stdout so the caller can see the
286
+ // structured failure, then exit with code 1.
287
+ if (raw) {
288
+ process.stdout.write(`plan-candidates failed: ${parsed.reason}\n`);
289
+ } else {
290
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
291
+ }
292
+ process.exit(1);
293
+ }
294
+
295
+ // --allow-partial-candidates: extract whatever valid blocks we can.
296
+ let blocks: PlanCandidateBlock[];
297
+ if (parsed.ok) {
298
+ blocks = parsed.blocks;
299
+ } else {
300
+ // Re-parse with relaxed validation: any well-formed block counts.
301
+ blocks = extractPartialBlocks(plannerText);
302
+ process.stderr.write(
303
+ `Warning: --allow-partial-candidates active. Planner returned ${blocks.length} valid block(s) instead of ${expectedN}. Writing what was found.\n`
304
+ );
305
+ }
306
+
307
+ const writeRes: WriteResult = writePlanCandidates(phaseDir, blocks);
308
+
309
+ const result: CmdResult = {
310
+ phase: phaseNum,
311
+ phaseDir,
312
+ candidates: expectedN,
313
+ blocksFound: blocks.length,
314
+ written: writeRes.written,
315
+ ok: true,
316
+ };
317
+ output(result, raw, writeRes.written.join('\n'));
318
+ }
319
+
320
+ /**
321
+ * Read planner output text from an explicit file or stdin. error() is
322
+ * `never` so callers can treat the return as definitely-string.
323
+ */
324
+ function readPlannerInput(inputFile: string | undefined): string {
325
+ if (inputFile) {
326
+ try {
327
+ return fs.readFileSync(inputFile, 'utf-8');
328
+ } catch (e) {
329
+ error(`failed to read --input ${inputFile}: ${(e as Error).message}`);
330
+ throw new Error('unreachable', { cause: e });
331
+ }
332
+ }
333
+ try {
334
+ return fs.readFileSync(0, 'utf-8');
335
+ } catch (e) {
336
+ error(`failed to read planner output from stdin: ${(e as Error).message}`);
337
+ throw new Error('unreachable', { cause: e });
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Extract every well-formed <<<PLAN-i>>>...<<</PLAN-i>>> block without
343
+ * enforcing count/index coverage. Used only on the
344
+ * --allow-partial-candidates path.
345
+ */
346
+ function extractPartialBlocks(text: string): PlanCandidateBlock[] {
347
+ const lines: string[] = text.split('\n');
348
+ const blocks: PlanCandidateBlock[] = [];
349
+ let currentIndex: number | null = null;
350
+ let buffer: string[] = [];
351
+
352
+ for (const line of lines) {
353
+ const openMatch = line.match(OPEN_RE);
354
+ const closeMatch = line.match(CLOSE_RE);
355
+ if (openMatch) {
356
+ currentIndex = parseInt(openMatch[1], 10);
357
+ buffer = [];
358
+ } else if (closeMatch) {
359
+ if (currentIndex !== null && parseInt(closeMatch[1], 10) === currentIndex) {
360
+ blocks.push({ index: currentIndex, content: buffer.join('\n') });
361
+ }
362
+ currentIndex = null;
363
+ buffer = [];
364
+ } else if (currentIndex !== null) {
365
+ buffer.push(line);
366
+ }
367
+ }
368
+ return blocks;
369
+ }
370
+
371
+ module.exports = {
372
+ parsePlanCandidates,
373
+ writePlanCandidates,
374
+ cmdPlanPhase,
375
+ };
@@ -0,0 +1,319 @@
1
+ 'use strict';
2
+
3
+ /** GRD Commands/Progress -- Project progress rendering in json, table, and bar formats */
4
+
5
+
6
+ import type { MilestoneInfo } from '../types';
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const {
11
+ output,
12
+ getMilestoneInfo,
13
+ }: {
14
+ output: (result: unknown, raw: boolean, rawValue?: unknown) => never;
15
+ getMilestoneInfo: (cwd: string) => MilestoneInfo;
16
+ } = require('../utils');
17
+ const {
18
+ phasesDir: getPhasesDirPath,
19
+ planningDir: getPlanningDir,
20
+ }: {
21
+ phasesDir: (cwd: string) => string;
22
+ planningDir: (cwd: string) => string;
23
+ } = require('../paths');
24
+ const {
25
+ readCachedState,
26
+ }: {
27
+ readCachedState: (statePath: string) => string | null;
28
+ } = require('./phase-info');
29
+ const {
30
+ loadConfig,
31
+ }: {
32
+ loadConfig: (cwd: string) => { survey?: { staleness_days?: number }; [key: string]: unknown };
33
+ } = require('../utils');
34
+
35
+ // ─── Domain Types ────────────────────────────────────────────────────────────
36
+
37
+ interface PhaseProgress {
38
+ number: string;
39
+ name: string;
40
+ plans: number;
41
+ summaries: number;
42
+ status: string;
43
+ }
44
+
45
+ // ─── Progress Render ─────────────────────────────────────────────────────────
46
+
47
+ /** Render project progress in the specified format (json, table, or bar). */
48
+ function cmdProgressRender(cwd: string, format: string, raw: boolean): void {
49
+ const phasesDir = getPhasesDirPath(cwd) as string;
50
+ const milestone = getMilestoneInfo(cwd);
51
+ const phases: PhaseProgress[] = [];
52
+ let totalPlans = 0;
53
+ let totalSummaries = 0;
54
+
55
+ try {
56
+ const dirs: string[] = fs
57
+ .readdirSync(phasesDir, { withFileTypes: true })
58
+ .filter((e: { isDirectory: () => boolean }) => e.isDirectory())
59
+ .map((e: { name: string }) => e.name)
60
+ .sort((a: string, b: string) => {
61
+ const aNum = parseFloat((a.match(/^(\d+(?:\.\d+)?)/) || ['0'])[1] || '0');
62
+ const bNum = parseFloat((b.match(/^(\d+(?:\.\d+)?)/) || ['0'])[1] || '0');
63
+ return aNum - bNum;
64
+ });
65
+
66
+ for (const dir of dirs) {
67
+ const dm = dir.match(/^(\d+(?:\.\d+)?)-?(.*)/);
68
+ const phaseNum = dm ? dm[1] : dir;
69
+ const phaseName = dm && dm[2] ? dm[2].replace(/-/g, ' ') : '';
70
+ const phaseFiles: string[] = fs.readdirSync(path.join(phasesDir, dir));
71
+ const plans = phaseFiles.filter(
72
+ (f: string) => f.endsWith('-PLAN.md') || f === 'PLAN.md'
73
+ ).length;
74
+ const summaries = phaseFiles.filter(
75
+ (f: string) => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md'
76
+ ).length;
77
+ totalPlans += plans;
78
+ totalSummaries += summaries;
79
+
80
+ let status: string;
81
+ if (plans === 0) status = 'Pending';
82
+ else if (summaries >= plans) status = 'Complete';
83
+ else if (summaries > 0) status = 'In Progress';
84
+ else status = 'Planned';
85
+
86
+ phases.push({ number: phaseNum, name: phaseName, plans, summaries, status });
87
+ }
88
+ } catch {
89
+ /* phases dir may not exist */
90
+ }
91
+
92
+ const percent = totalPlans > 0 ? Math.round((totalSummaries / totalPlans) * 100) : 0;
93
+
94
+ // Check research file staleness
95
+ let stalenessDays = 30;
96
+ try {
97
+ const cfg = loadConfig(cwd);
98
+ if (cfg.survey && typeof cfg.survey.staleness_days === 'number') {
99
+ stalenessDays = cfg.survey.staleness_days;
100
+ }
101
+ } catch {
102
+ // Config unavailable — use default
103
+ }
104
+ const stalenessMs = stalenessDays * 24 * 60 * 60 * 1000;
105
+ const now = Date.now();
106
+ const staleResearchFiles: string[] = [];
107
+ const planningBase = getPlanningDir(cwd);
108
+ const researchFilesToCheck: string[] = [
109
+ path.join(planningBase, 'research', 'LANDSCAPE.md'),
110
+ ];
111
+ try {
112
+ const milestonesBase = path.join(planningBase, 'milestones');
113
+ const msDirs = (fs.readdirSync(milestonesBase) as string[]).filter((d: string) => {
114
+ try { return fs.statSync(path.join(milestonesBase, d)).isDirectory(); } catch { return false; }
115
+ });
116
+ for (const ms of msDirs) {
117
+ // Codex r3 P2: survey output is LANDSCAPE.md (path helpers'
118
+ // canonical name); SUMMARY.md is a phase artifact, not a
119
+ // research artifact, so it would never trigger staleness.
120
+ researchFilesToCheck.push(path.join(milestonesBase, ms, 'research', 'LANDSCAPE.md'));
121
+ }
122
+ } catch {
123
+ // milestones dir may not exist
124
+ }
125
+ for (const resFile of researchFilesToCheck) {
126
+ try {
127
+ const stat = fs.statSync(resFile);
128
+ if (now - stat.mtimeMs > stalenessMs) {
129
+ staleResearchFiles.push(path.relative(cwd, resFile));
130
+ }
131
+ } catch {
132
+ // File doesn't exist — not stale, just absent
133
+ }
134
+ }
135
+
136
+ // Parse active blockers from STATE.md
137
+ const blockerItems: string[] = [];
138
+ try {
139
+ const statePath = path.join(getPlanningDir(cwd), 'STATE.md');
140
+ const stateContent = readCachedState(statePath) || '';
141
+ const blockersSection = stateContent.match(/## Blockers\s*\n([\s\S]*?)(?=\n##|$)/i);
142
+ if (blockersSection) {
143
+ const blockersText = blockersSection[1].trim();
144
+ if (blockersText && blockersText !== 'None.' && blockersText !== 'None') {
145
+ const items = blockersText.match(/^-\s+(.+)$/gm) || [];
146
+ for (const item of items) blockerItems.push(item.replace(/^-\s+/, '').trim());
147
+ }
148
+ }
149
+ } catch {
150
+ /* STATE.md may not exist */
151
+ }
152
+
153
+ if (format === 'table') {
154
+ const barWidth = 10;
155
+ const filled = Math.round((percent / 100) * barWidth);
156
+ const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(barWidth - filled);
157
+ let out = `# ${milestone.version} ${milestone.name}\n\n`;
158
+ out += `**Progress:** [${bar}] ${totalSummaries}/${totalPlans} plans (${percent}%)\n\n`;
159
+ if (blockerItems.length > 0) {
160
+ out += `> **BLOCKED** \u2014 ${blockerItems.length} active blocker(s):\n`;
161
+ for (const b of blockerItems) out += `> - ${b}\n`;
162
+ out += `\n`;
163
+ }
164
+ if (staleResearchFiles.length > 0) {
165
+ out += `## Research Freshness Warnings\n\n`;
166
+ out += `The following research files are older than ${stalenessDays} days. Run \`/grd:survey\` to refresh:\n\n`;
167
+ for (const f of staleResearchFiles) out += `- \`${f}\`\n`;
168
+ out += `\n`;
169
+ }
170
+ out += `| Phase | Name | Plans | Status |\n|-------|------|-------|--------|\n`;
171
+ for (const p of phases)
172
+ out += `| ${p.number} | ${p.name} | ${p.summaries}/${p.plans} | ${p.status} |\n`;
173
+ output({ rendered: out }, raw, out);
174
+ } else if (format === 'bar') {
175
+ const barWidth = 20;
176
+ const filled = Math.round((percent / 100) * barWidth);
177
+ const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(barWidth - filled);
178
+ const text = `[${bar}] ${totalSummaries}/${totalPlans} plans (${percent}%)`;
179
+ output({ bar: text, percent, completed: totalSummaries, total: totalPlans }, raw, text);
180
+ } else {
181
+ const humanSummary = `${milestone.version} ${milestone.name}: ${totalSummaries}/${totalPlans} plans (${percent}%)`;
182
+ output(
183
+ {
184
+ milestone_version: milestone.version,
185
+ milestone_name: milestone.name,
186
+ phases,
187
+ total_plans: totalPlans,
188
+ total_summaries: totalSummaries,
189
+ percent,
190
+ active_blockers: blockerItems.length,
191
+ blocker_items: blockerItems,
192
+ stale_research_files: staleResearchFiles,
193
+ staleness_threshold_days: stalenessDays,
194
+ },
195
+ raw,
196
+ humanSummary
197
+ );
198
+ }
199
+ }
200
+
201
+ // ─── Research Gap Detector ───────────────────────────────────────────────────
202
+
203
+ interface MustConsiderPaper {
204
+ title: string;
205
+ keywords: string[];
206
+ }
207
+
208
+ interface PhaseGapRow {
209
+ phase: string;
210
+ cited: string[];
211
+ missing: string[];
212
+ }
213
+
214
+ interface ResearchGapsResult {
215
+ must_consider_count: number;
216
+ phases_scanned: number;
217
+ coverage: PhaseGapRow[];
218
+ uncited_global: string[];
219
+ }
220
+
221
+ /**
222
+ * Scan all phase RESEARCH.md and PLAN.md files for citations of must-consider
223
+ * papers listed in .planning/config.json `must_consider_papers`. Reports a
224
+ * per-phase coverage table showing which papers are cited vs. missing.
225
+ */
226
+ function cmdResearchGaps(cwd: string, raw: boolean): void {
227
+ const planningDir = getPlanningDir(cwd) as string;
228
+ const configPath = path.join(planningDir, 'config.json');
229
+ let mustConsider: MustConsiderPaper[] = [];
230
+ if (fs.existsSync(configPath)) {
231
+ try {
232
+ const cfg = JSON.parse(fs.readFileSync(configPath, 'utf-8') as string) as Record<string, unknown>;
233
+ const raw_papers = cfg['must_consider_papers'];
234
+ if (Array.isArray(raw_papers)) {
235
+ mustConsider = (raw_papers as Array<Record<string, unknown>>).map((p) => ({
236
+ title: String(p['title'] ?? ''),
237
+ keywords: Array.isArray(p['keywords']) ? (p['keywords'] as string[]).map(String) : [],
238
+ })).filter((p) => p.title.length > 0);
239
+ }
240
+ } catch { /* ignore parse errors */ }
241
+ }
242
+
243
+ if (mustConsider.length === 0) {
244
+ output({ must_consider_count: 0, phases_scanned: 0, coverage: [], uncited_global: [], note: 'No must_consider_papers in .planning/config.json' }, raw, 'No must_consider_papers configured. Add them to .planning/config.json to use research-gaps.');
245
+ return;
246
+ }
247
+
248
+ // Gather phase directories
249
+ const milestonesBase = path.join(planningDir, 'milestones');
250
+ const phaseDirs: { phaseId: string; dir: string }[] = [];
251
+ if (fs.existsSync(milestonesBase)) {
252
+ try {
253
+ for (const ms of (fs.readdirSync(milestonesBase) as string[])) {
254
+ const phasesBase = path.join(milestonesBase, ms, 'phases');
255
+ if (!fs.existsSync(phasesBase)) continue;
256
+ try {
257
+ for (const ph of (fs.readdirSync(phasesBase) as string[])) {
258
+ phaseDirs.push({ phaseId: `${ms}/${ph}`, dir: path.join(phasesBase, ph) });
259
+ }
260
+ } catch { /* skip */ }
261
+ }
262
+ } catch { /* skip */ }
263
+ }
264
+
265
+ const coverage: PhaseGapRow[] = [];
266
+ const globalCited = new Set<string>();
267
+
268
+ for (const { phaseId, dir } of phaseDirs) {
269
+ // Codex r3 P2: phase plans are typically prefixed like
270
+ // `01-01-PLAN.md`, not bare `PLAN.md`. Include all *-PLAN.md and
271
+ // *-RESEARCH.md files so citation scanning matches the real layout.
272
+ const candidates: string[] = [];
273
+ try {
274
+ for (const f of fs.readdirSync(dir) as string[]) {
275
+ if (f === 'RESEARCH.md' || f === 'PLAN.md' || /-PLAN\.md$/.test(f) || /-RESEARCH\.md$/.test(f)) {
276
+ candidates.push(path.join(dir, f));
277
+ }
278
+ }
279
+ } catch { /* skip */ }
280
+ let phaseText = '';
281
+ for (const c of candidates) {
282
+ if (fs.existsSync(c)) {
283
+ try { phaseText += ' ' + (fs.readFileSync(c, 'utf-8') as string).toLowerCase(); } catch { /* skip */ }
284
+ }
285
+ }
286
+ if (!phaseText.trim()) continue;
287
+
288
+ const cited: string[] = [];
289
+ const missing: string[] = [];
290
+ for (const paper of mustConsider) {
291
+ const allTerms = [paper.title, ...paper.keywords].map((t) => t.toLowerCase());
292
+ const isCited = allTerms.some((term) => phaseText.includes(term));
293
+ if (isCited) {
294
+ cited.push(paper.title);
295
+ globalCited.add(paper.title);
296
+ } else {
297
+ missing.push(paper.title);
298
+ }
299
+ }
300
+ coverage.push({ phase: phaseId, cited, missing });
301
+ }
302
+
303
+ const uncited_global = mustConsider.map((p) => p.title).filter((t) => !globalCited.has(t));
304
+ const result: ResearchGapsResult = {
305
+ must_consider_count: mustConsider.length,
306
+ phases_scanned: coverage.length,
307
+ coverage,
308
+ uncited_global,
309
+ };
310
+
311
+ const summary = uncited_global.length === 0
312
+ ? `All ${mustConsider.length} must-consider papers cited across ${coverage.length} phases`
313
+ : `${uncited_global.length}/${mustConsider.length} papers uncited in any phase`;
314
+ output(result, raw, summary);
315
+ }
316
+
317
+ // ─── Exports ─────────────────────────────────────────────────────────────────
318
+
319
+ module.exports = { cmdProgressRender, cmdResearchGaps };