@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,806 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * GRD Long-Term Roadmap Operations -- LONG-TERM-ROADMAP.md parsing, validation,
5
+ * generation, display formatting, and CRUD operations.
6
+ *
7
+ * Implements a flat LT-N milestone format where each LT milestone maps to
8
+ * one or more normal milestones in ROADMAP.md.
9
+ *
10
+ * Depends on: lib/frontmatter.ts (extractFrontmatter)
11
+ */
12
+
13
+
14
+ import type { FrontmatterObject } from './types';
15
+
16
+ const {
17
+ extractFrontmatter,
18
+ }: {
19
+ extractFrontmatter: (content: string) => FrontmatterObject;
20
+ } = require('./frontmatter');
21
+
22
+ // ─── Domain Types ─────────────────────────────────────────────────────────────
23
+
24
+ /**
25
+ * An entry in the normal milestone list, with optional note (e.g., "planned").
26
+ */
27
+ interface NormalMilestoneEntry {
28
+ version: string;
29
+ note?: string;
30
+ }
31
+
32
+ /**
33
+ * A parsed LT milestone from LONG-TERM-ROADMAP.md.
34
+ */
35
+ interface LtMilestone {
36
+ id: string;
37
+ name: string;
38
+ status: string;
39
+ goal: string;
40
+ normal_milestones: NormalMilestoneEntry[];
41
+ }
42
+
43
+ /**
44
+ * A parsed LONG-TERM-ROADMAP.md document.
45
+ */
46
+ interface LongTermRoadmap {
47
+ frontmatter: FrontmatterObject;
48
+ milestones: LtMilestone[];
49
+ refinement_history: RefinementHistoryEntry[];
50
+ }
51
+
52
+ /**
53
+ * A single refinement history table row.
54
+ */
55
+ interface RefinementHistoryEntry {
56
+ date: string;
57
+ action: string;
58
+ details: string;
59
+ }
60
+
61
+ /**
62
+ * Validation result from validateLongTermRoadmap.
63
+ */
64
+ interface ValidationResult {
65
+ valid: boolean;
66
+ errors: string[];
67
+ warnings: string[];
68
+ }
69
+
70
+ /**
71
+ * Result of adding an LT milestone: updated content and new ID.
72
+ */
73
+ interface AddLtMilestoneResult {
74
+ content: string;
75
+ id: string;
76
+ }
77
+
78
+ /**
79
+ * Error result from CRUD operations.
80
+ */
81
+ interface ErrorResult {
82
+ error: string;
83
+ }
84
+
85
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
86
+
87
+ /**
88
+ * Extract a bold field value from text.
89
+ * @param text - Section text to search
90
+ * @param fieldName - Bold field name (e.g., 'Status', 'Goal')
91
+ * @returns The field value, or null if not found
92
+ */
93
+ function extractBoldField(text: string, fieldName: string): string | null {
94
+ const pattern = new RegExp(`\\*\\*${fieldName}:\\*\\*\\s*(.+)`, 'i');
95
+ const match = text.match(pattern);
96
+ return match ? match[1].trim() : null;
97
+ }
98
+
99
+ // ─── Refinement History ──────────────────────────────────────────────────────
100
+
101
+ /**
102
+ * Parse the refinement history table from content.
103
+ * @param content - Full markdown content
104
+ * @returns Array of { date, action, details } objects
105
+ */
106
+ function parseRefinementHistory(content: string): RefinementHistoryEntry[] {
107
+ const sectionMatch = content.match(/^##\s+Refinement History/m);
108
+ if (!sectionMatch || sectionMatch.index === undefined) return [];
109
+
110
+ const afterHeading = content.slice(sectionMatch.index + sectionMatch[0].length);
111
+
112
+ const lines = afterHeading.split('\n');
113
+ const entries: RefinementHistoryEntry[] = [];
114
+ let pastHeader = false;
115
+
116
+ for (const line of lines) {
117
+ const trimmed = line.trim();
118
+ if (trimmed.startsWith('#')) break;
119
+ if (trimmed.startsWith('|') && trimmed.includes('Date') && trimmed.includes('Action')) {
120
+ continue;
121
+ }
122
+ if (trimmed.match(/^\|[\s-|]+\|$/)) {
123
+ pastHeader = true;
124
+ continue;
125
+ }
126
+ if (pastHeader && trimmed.startsWith('|')) {
127
+ const cells = trimmed
128
+ .split('|')
129
+ .map((c) => c.trim())
130
+ .filter((c) => c !== '');
131
+ if (cells.length >= 3) {
132
+ entries.push({
133
+ date: cells[0],
134
+ action: cells[1],
135
+ details: cells[2],
136
+ });
137
+ }
138
+ }
139
+ }
140
+
141
+ return entries;
142
+ }
143
+
144
+ /**
145
+ * Append a row to the Refinement History markdown table.
146
+ * @param content - Raw LONG-TERM-ROADMAP.md content
147
+ * @param action - Action description
148
+ * @param details - Details of what was changed
149
+ * @returns Updated content string
150
+ */
151
+ function updateRefinementHistory(content: string, action: string, details: string): string {
152
+ const sectionMatch = content.match(/^##\s+Refinement History/m);
153
+ if (!sectionMatch || sectionMatch.index === undefined) return content;
154
+
155
+ const today = new Date().toISOString().split('T')[0];
156
+ const newRow = `| ${today} | ${action} | ${details} |`;
157
+
158
+ const afterSection = content.slice(sectionMatch.index);
159
+ const lines = afterSection.split('\n');
160
+
161
+ let lastTableLineIdx = -1;
162
+ let inTable = false;
163
+
164
+ for (let i = 0; i < lines.length; i++) {
165
+ const trimmed = lines[i].trim();
166
+ if (i > 0 && trimmed.startsWith('#')) break;
167
+ if (trimmed.startsWith('|')) {
168
+ inTable = true;
169
+ lastTableLineIdx = i;
170
+ } else if (inTable && trimmed === '') {
171
+ break;
172
+ }
173
+ }
174
+
175
+ if (lastTableLineIdx === -1) return content;
176
+
177
+ const beforeSection = content.slice(0, sectionMatch.index);
178
+ lines.splice(lastTableLineIdx + 1, 0, newRow);
179
+
180
+ return beforeSection + lines.join('\n');
181
+ }
182
+
183
+ // ─── Normal Milestone List Parsing ───────────────────────────────────────────
184
+
185
+ /**
186
+ * Parse comma-separated normal milestone list from field text.
187
+ * e.g. "v0.0.5, v0.2.0 (planned)" -> [{ version: 'v0.0.5' }, { version: 'v0.2.0', note: 'planned' }]
188
+ * Also handles "(none yet)" -> []
189
+ * @param fieldText - The field text after "Normal milestones:"
190
+ * @returns Array of { version, note? } objects
191
+ */
192
+ function parseNormalMilestoneList(fieldText: string | null | undefined): NormalMilestoneEntry[] {
193
+ if (!fieldText || fieldText.trim() === '' || /\(none\s*yet\)/i.test(fieldText)) return [];
194
+
195
+ return fieldText
196
+ .split(',')
197
+ .map((s) => s.trim())
198
+ .filter((s) => s !== '')
199
+ .map((s): NormalMilestoneEntry => {
200
+ const noteMatch = s.match(/^(v[\d.]+)\s*\(([^)]+)\)$/);
201
+ if (noteMatch) {
202
+ return { version: noteMatch[1], note: noteMatch[2] };
203
+ }
204
+ const versionMatch = s.match(/^(v[\d.]+)$/);
205
+ if (versionMatch) {
206
+ return { version: versionMatch[1] };
207
+ }
208
+ return { version: s };
209
+ });
210
+ }
211
+
212
+ /**
213
+ * Format normal milestone list back to string.
214
+ * @param milestones - Array of { version, note? }
215
+ * @returns Formatted string
216
+ */
217
+ function formatNormalMilestoneList(milestones: NormalMilestoneEntry[] | null | undefined): string {
218
+ if (!milestones || milestones.length === 0) return '(none yet)';
219
+ return milestones.map((m) => (m.note ? `${m.version} (${m.note})` : m.version)).join(', ');
220
+ }
221
+
222
+ // ─── LT Milestone Parsing ────────────────────────────────────────────────────
223
+
224
+ /**
225
+ * Parse a single ## LT-N: section into a structured object.
226
+ * @param sectionText - Text of the section (after the ## heading)
227
+ * @param id - The LT id (e.g., 'LT-1')
228
+ * @param name - The name from the heading
229
+ * @returns Parsed LT milestone
230
+ */
231
+ function parseLtMilestone(sectionText: string, id: string, name: string): LtMilestone {
232
+ const status = extractBoldField(sectionText, 'Status') || 'planned';
233
+ const goal = extractBoldField(sectionText, 'Goal') || '';
234
+ const normalField = extractBoldField(sectionText, 'Normal milestones');
235
+ const normal_milestones = parseNormalMilestoneList(normalField);
236
+
237
+ return {
238
+ id,
239
+ name,
240
+ status,
241
+ goal,
242
+ normal_milestones,
243
+ };
244
+ }
245
+
246
+ /**
247
+ * Parse LONG-TERM-ROADMAP.md content into structured object (flat format).
248
+ * @param content - Raw markdown content
249
+ * @returns Parsed roadmap with frontmatter, milestones[], refinement_history[]
250
+ */
251
+ function parseLongTermRoadmap(content: unknown): LongTermRoadmap | null {
252
+ if (!content || typeof content !== 'string') return null;
253
+
254
+ const frontmatter = extractFrontmatter(content);
255
+
256
+ // Match all ## LT-N: headings
257
+ const ltPattern = /^##\s+(LT-(\d+)):\s*(.+)/gm;
258
+ const milestones: LtMilestone[] = [];
259
+ const matches: Array<{
260
+ id: string;
261
+ num: number;
262
+ name: string;
263
+ index: number;
264
+ fullMatch: string;
265
+ }> = [];
266
+ let match: RegExpExecArray | null;
267
+
268
+ while ((match = ltPattern.exec(content)) !== null) {
269
+ matches.push({
270
+ id: match[1],
271
+ num: parseInt(match[2], 10),
272
+ name: match[3].trim(),
273
+ index: match.index,
274
+ fullMatch: match[0],
275
+ });
276
+ }
277
+
278
+ if (matches.length === 0 && Object.keys(frontmatter).length === 0) return null;
279
+
280
+ for (let i = 0; i < matches.length; i++) {
281
+ const startIdx = matches[i].index + matches[i].fullMatch.length;
282
+ // Find next ## heading (any ## heading, not just LT-)
283
+ const rest = content.slice(startIdx);
284
+ const nextH2 = rest.match(/^##\s/m);
285
+ const endIdx = nextH2 && nextH2.index !== undefined ? startIdx + nextH2.index : content.length;
286
+
287
+ const sectionText = content.slice(startIdx, endIdx).trim();
288
+ milestones.push(parseLtMilestone(sectionText, matches[i].id, matches[i].name));
289
+ }
290
+
291
+ const refinement_history = parseRefinementHistory(content);
292
+
293
+ return {
294
+ frontmatter,
295
+ milestones,
296
+ refinement_history,
297
+ };
298
+ }
299
+
300
+ // ─── Validation ──────────────────────────────────────────────────────────────
301
+
302
+ const VALID_STATUSES: string[] = ['completed', 'active', 'planned'];
303
+
304
+ /**
305
+ * Validate a parsed long-term roadmap object.
306
+ * @param parsed - Parsed roadmap from parseLongTermRoadmap
307
+ * @returns Validation result with errors and warnings
308
+ */
309
+ function validateLongTermRoadmap(parsed: LongTermRoadmap | null): ValidationResult {
310
+ const errors: string[] = [];
311
+ const warnings: string[] = [];
312
+
313
+ if (!parsed) {
314
+ return { valid: false, errors: ['Parsed roadmap is null or undefined'], warnings: [] };
315
+ }
316
+
317
+ if (!parsed.frontmatter || !parsed.frontmatter.project) {
318
+ errors.push('Missing required frontmatter field: project');
319
+ }
320
+
321
+ if (!parsed.milestones || parsed.milestones.length === 0) {
322
+ errors.push('No LT milestones found');
323
+ } else {
324
+ const ids = new Set<string>();
325
+ let activeCount = 0;
326
+
327
+ for (const ms of parsed.milestones) {
328
+ // Duplicate ID check
329
+ if (ids.has(ms.id)) {
330
+ errors.push(`Duplicate milestone ID: ${ms.id}`);
331
+ }
332
+ ids.add(ms.id);
333
+
334
+ // Goal required
335
+ if (!ms.goal || ms.goal.trim() === '') {
336
+ errors.push(`${ms.id} (${ms.name}) is missing goal`);
337
+ }
338
+
339
+ // Valid status
340
+ if (!VALID_STATUSES.includes(ms.status)) {
341
+ errors.push(
342
+ `${ms.id} has invalid status: ${ms.status}. Valid: ${VALID_STATUSES.join(', ')}`
343
+ );
344
+ }
345
+
346
+ if (ms.status === 'active') activeCount++;
347
+ }
348
+
349
+ if (activeCount > 1) {
350
+ warnings.push(
351
+ `Multiple active LT milestones (${activeCount}). Consider having only one active.`
352
+ );
353
+ }
354
+
355
+ if (activeCount === 0 && parsed.milestones.some((m) => m.status !== 'completed')) {
356
+ warnings.push('No active LT milestone found');
357
+ }
358
+ }
359
+
360
+ return {
361
+ valid: errors.length === 0,
362
+ errors,
363
+ warnings,
364
+ };
365
+ }
366
+
367
+ // ─── Generation ──────────────────────────────────────────────────────────────
368
+
369
+ /**
370
+ * Generate LONG-TERM-ROADMAP.md content from structured milestone data.
371
+ * @param milestones - Array of LT milestones
372
+ * @param projectName - Project name for frontmatter
373
+ * @returns Complete LONG-TERM-ROADMAP.md content
374
+ */
375
+ function generateLongTermRoadmap(milestones: LtMilestone[], projectName: string): string {
376
+ const today = new Date().toISOString().split('T')[0];
377
+ const lines: string[] = [];
378
+
379
+ lines.push('---');
380
+ lines.push(`project: ${projectName}`);
381
+ lines.push(`created: ${today}`);
382
+ lines.push(`last_refined: ${today}`);
383
+ lines.push('---');
384
+ lines.push('');
385
+ lines.push(`# Long-Term Roadmap: ${projectName}`);
386
+ lines.push('');
387
+
388
+ for (const ms of milestones) {
389
+ lines.push(`## ${ms.id}: ${ms.name}`);
390
+ lines.push(`**Status:** ${ms.status}`);
391
+ lines.push(`**Goal:** ${ms.goal}`);
392
+ lines.push(`**Normal milestones:** ${formatNormalMilestoneList(ms.normal_milestones)}`);
393
+ lines.push('');
394
+ }
395
+
396
+ lines.push('## Refinement History');
397
+ lines.push('');
398
+ lines.push('| Date | Action | Details |');
399
+ lines.push('|------|--------|---------|');
400
+ lines.push(`| ${today} | Initial roadmap | Created ${milestones.length} LT milestones |`);
401
+ lines.push('');
402
+
403
+ return lines.join('\n');
404
+ }
405
+
406
+ // ─── Display Formatting ─────────────────────────────────────────────────────
407
+
408
+ /**
409
+ * Format parsed long-term roadmap for human-readable display.
410
+ * @param parsed - Parsed roadmap from parseLongTermRoadmap
411
+ * @returns Formatted display string
412
+ */
413
+ function formatLongTermRoadmap(parsed: LongTermRoadmap | null): string {
414
+ if (!parsed) return '';
415
+
416
+ const lines: string[] = [];
417
+ const project = (parsed.frontmatter?.project as string | undefined) || 'Unknown Project';
418
+
419
+ lines.push(`Long-Term Roadmap: ${project}`);
420
+ lines.push('');
421
+
422
+ if (parsed.milestones && parsed.milestones.length > 0) {
423
+ for (const ms of parsed.milestones) {
424
+ const icon =
425
+ ms.status === 'completed' ? '[done]' : ms.status === 'active' ? '[active]' : '[planned]';
426
+ const normalList = formatNormalMilestoneList(ms.normal_milestones);
427
+ lines.push(`${icon} ${ms.id}: ${ms.name}`);
428
+ lines.push(` ${ms.goal}`);
429
+ lines.push(` Normal milestones: ${normalList}`);
430
+ lines.push('');
431
+ }
432
+ }
433
+
434
+ return lines.join('\n');
435
+ }
436
+
437
+ // ─── Shipped Version Detection ───────────────────────────────────────────────
438
+
439
+ /**
440
+ * Extract shipped versions from ROADMAP.md content.
441
+ * Looks for `(shipped YYYY-MM-DD)` pattern in milestone bullet list.
442
+ * @param roadmapContent - Raw ROADMAP.md content
443
+ * @returns Array of shipped version strings
444
+ */
445
+ function extractShippedVersions(roadmapContent: string | null | undefined): string[] {
446
+ if (!roadmapContent) return [];
447
+
448
+ const versions: string[] = [];
449
+ const pattern = /^-\s+(v[\d.]+)\b.*\(shipped\s+\d{4}-\d{2}-\d{2}\)/gm;
450
+ let match: RegExpExecArray | null;
451
+ while ((match = pattern.exec(roadmapContent)) !== null) {
452
+ versions.push(match[1]);
453
+ }
454
+ return versions;
455
+ }
456
+
457
+ // ─── ID Helpers ──────────────────────────────────────────────────────────────
458
+
459
+ /**
460
+ * Compute the next LT-N id from parsed roadmap.
461
+ * @param parsed - Parsed roadmap (or null)
462
+ * @returns Next LT id (e.g., 'LT-3')
463
+ */
464
+ function nextLtId(parsed: LongTermRoadmap | null | undefined): string {
465
+ if (!parsed || !parsed.milestones || parsed.milestones.length === 0) return 'LT-1';
466
+
467
+ const maxNum = Math.max(
468
+ ...parsed.milestones.map((m) => {
469
+ const numMatch = m.id.match(/LT-(\d+)/);
470
+ return numMatch ? parseInt(numMatch[1], 10) : 0;
471
+ })
472
+ );
473
+ return `LT-${maxNum + 1}`;
474
+ }
475
+
476
+ // ─── CRUD Operations ─────────────────────────────────────────────────────────
477
+
478
+ /**
479
+ * Append a new LT milestone before the Refinement History section.
480
+ * @param content - Raw LONG-TERM-ROADMAP.md content
481
+ * @param name - LT milestone name
482
+ * @param goal - LT milestone goal
483
+ * @returns Updated content and new ID
484
+ */
485
+ function addLtMilestone(content: string, name: string, goal: string): AddLtMilestoneResult {
486
+ const parsed = parseLongTermRoadmap(content);
487
+ const id = nextLtId(parsed);
488
+
489
+ const newSection = [
490
+ `## ${id}: ${name}`,
491
+ `**Status:** planned`,
492
+ `**Goal:** ${goal}`,
493
+ `**Normal milestones:** (none yet)`,
494
+ '',
495
+ ].join('\n');
496
+
497
+ // Insert before Refinement History
498
+ const historyMatch = content.match(/^##\s+Refinement History/m);
499
+ if (historyMatch && historyMatch.index !== undefined) {
500
+ const before = content.slice(0, historyMatch.index);
501
+ const after = content.slice(historyMatch.index);
502
+ return { content: before + newSection + '\n' + after, id };
503
+ }
504
+
505
+ // No history section, append at end
506
+ return { content: content.trimEnd() + '\n\n' + newSection + '\n', id };
507
+ }
508
+
509
+ /**
510
+ * Remove an LT milestone section. Protected: refuses if any linked normal milestone is shipped.
511
+ * @param content - Raw LONG-TERM-ROADMAP.md content
512
+ * @param id - LT milestone ID (e.g., 'LT-2')
513
+ * @param roadmapContent - Optional ROADMAP.md content for shipped detection
514
+ * @returns Updated content, or { error } if protected
515
+ */
516
+ function removeLtMilestone(
517
+ content: string,
518
+ id: string,
519
+ roadmapContent?: string
520
+ ): string | ErrorResult {
521
+ const parsed = parseLongTermRoadmap(content);
522
+ if (!parsed) return { error: 'Could not parse LONG-TERM-ROADMAP.md' };
523
+
524
+ const ms = parsed.milestones.find((m) => m.id === id);
525
+ if (!ms) return { error: `${id} not found` };
526
+
527
+ // Protection: check if any linked normal milestones are shipped
528
+ if (roadmapContent && ms.normal_milestones.length > 0) {
529
+ const shipped = extractShippedVersions(roadmapContent);
530
+ const shippedLinked = ms.normal_milestones.filter((m) => shipped.includes(m.version));
531
+ if (shippedLinked.length > 0) {
532
+ return {
533
+ error: `Cannot remove ${id}: linked milestone(s) ${shippedLinked.map((m) => m.version).join(', ')} already shipped`,
534
+ };
535
+ }
536
+ }
537
+
538
+ // Also refuse if status is completed
539
+ if (ms.status === 'completed') {
540
+ return { error: `Cannot remove ${id}: status is completed` };
541
+ }
542
+
543
+ // Find and remove the section
544
+ const escapedId = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
545
+ const sectionPattern = new RegExp(`^##\\s+${escapedId}:\\s*[^\\n]+`, 'm');
546
+ const sectionMatch = content.match(sectionPattern);
547
+ if (!sectionMatch || sectionMatch.index === undefined) {
548
+ return { error: `${id} section not found in content` };
549
+ }
550
+
551
+ const startIdx = sectionMatch.index;
552
+ const afterHeading = content.slice(startIdx + sectionMatch[0].length);
553
+ const nextH2 = afterHeading.match(/^##\s/m);
554
+ const endIdx =
555
+ nextH2 && nextH2.index !== undefined
556
+ ? startIdx + sectionMatch[0].length + nextH2.index
557
+ : content.length;
558
+
559
+ const result = content.slice(0, startIdx) + content.slice(endIdx);
560
+ return result;
561
+ }
562
+
563
+ /**
564
+ * Update fields of an LT milestone in-place.
565
+ * @param content - Raw LONG-TERM-ROADMAP.md content
566
+ * @param id - LT milestone ID
567
+ * @param updates - Fields to update: name, goal, status
568
+ * @returns Updated content, or { error }
569
+ */
570
+ function updateLtMilestone(
571
+ content: string,
572
+ id: string,
573
+ updates: Partial<Pick<LtMilestone, 'name' | 'goal' | 'status'>>
574
+ ): string | ErrorResult {
575
+ const parsed = parseLongTermRoadmap(content);
576
+ if (!parsed) return { error: 'Could not parse LONG-TERM-ROADMAP.md' };
577
+
578
+ const ms = parsed.milestones.find((m) => m.id === id);
579
+ if (!ms) return { error: `${id} not found` };
580
+
581
+ if (updates.status && !VALID_STATUSES.includes(updates.status)) {
582
+ return { error: `Invalid status: ${updates.status}. Valid: ${VALID_STATUSES.join(', ')}` };
583
+ }
584
+
585
+ let result = content;
586
+
587
+ // Update heading name
588
+ if (updates.name) {
589
+ const escapedId = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
590
+ const headingPattern = new RegExp(`^(##\\s+${escapedId}:\\s*)(.+)$`, 'm');
591
+ result = result.replace(headingPattern, `$1${updates.name}`);
592
+ }
593
+
594
+ // Update status
595
+ if (updates.status) {
596
+ // Find this milestone's section and update status within it
597
+ const escapedId = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
598
+ const sectionStart = result.match(new RegExp(`^##\\s+${escapedId}:`, 'm'));
599
+ if (sectionStart && sectionStart.index !== undefined) {
600
+ const afterSection = result.slice(sectionStart.index);
601
+ const nextH2 = afterSection.match(/\n##\s/);
602
+ const sectionEnd =
603
+ nextH2 && nextH2.index !== undefined ? sectionStart.index + nextH2.index : result.length;
604
+ const section = result.slice(sectionStart.index, sectionEnd);
605
+ const updatedSection = section.replace(
606
+ /\*\*Status:\*\*\s*.+/,
607
+ `**Status:** ${updates.status}`
608
+ );
609
+ result = result.slice(0, sectionStart.index) + updatedSection + result.slice(sectionEnd);
610
+ }
611
+ }
612
+
613
+ // Update goal
614
+ if (updates.goal) {
615
+ const escapedId = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
616
+ const sectionStart = result.match(new RegExp(`^##\\s+${escapedId}:`, 'm'));
617
+ if (sectionStart && sectionStart.index !== undefined) {
618
+ const afterSection = result.slice(sectionStart.index);
619
+ const nextH2 = afterSection.match(/\n##\s/);
620
+ const sectionEnd =
621
+ nextH2 && nextH2.index !== undefined ? sectionStart.index + nextH2.index : result.length;
622
+ const section = result.slice(sectionStart.index, sectionEnd);
623
+ const updatedSection = section.replace(/\*\*Goal:\*\*\s*.+/, `**Goal:** ${updates.goal}`);
624
+ result = result.slice(0, sectionStart.index) + updatedSection + result.slice(sectionEnd);
625
+ }
626
+ }
627
+
628
+ return result;
629
+ }
630
+
631
+ /**
632
+ * Link a normal milestone version to an LT milestone.
633
+ * @param content - Raw LONG-TERM-ROADMAP.md content
634
+ * @param id - LT milestone ID
635
+ * @param version - Normal milestone version (e.g., 'v0.2.0')
636
+ * @param note - Optional note (e.g., 'planned')
637
+ * @returns Updated content, or { error }
638
+ */
639
+ function linkNormalMilestone(
640
+ content: string,
641
+ id: string,
642
+ version: string,
643
+ note?: string
644
+ ): string | ErrorResult {
645
+ const parsed = parseLongTermRoadmap(content);
646
+ if (!parsed) return { error: 'Could not parse LONG-TERM-ROADMAP.md' };
647
+
648
+ const ms = parsed.milestones.find((m) => m.id === id);
649
+ if (!ms) return { error: `${id} not found` };
650
+
651
+ // Check if already linked
652
+ if (ms.normal_milestones.some((m) => m.version === version)) {
653
+ return { error: `${version} is already linked to ${id}` };
654
+ }
655
+
656
+ const newEntry: NormalMilestoneEntry = note ? { version, note } : { version };
657
+ const updatedList = [...ms.normal_milestones, newEntry];
658
+ const newField = formatNormalMilestoneList(updatedList);
659
+
660
+ // Replace the Normal milestones field in this section
661
+ return replaceFieldInSection(content, id, 'Normal milestones', newField);
662
+ }
663
+
664
+ /**
665
+ * Unlink a normal milestone version from an LT milestone.
666
+ * Protected: refuses if the normal milestone is shipped.
667
+ * @param content - Raw LONG-TERM-ROADMAP.md content
668
+ * @param id - LT milestone ID
669
+ * @param version - Normal milestone version
670
+ * @param roadmapContent - Optional ROADMAP.md for shipped detection
671
+ * @returns Updated content, or { error }
672
+ */
673
+ function unlinkNormalMilestone(
674
+ content: string,
675
+ id: string,
676
+ version: string,
677
+ roadmapContent?: string
678
+ ): string | ErrorResult {
679
+ const parsed = parseLongTermRoadmap(content);
680
+ if (!parsed) return { error: 'Could not parse LONG-TERM-ROADMAP.md' };
681
+
682
+ const ms = parsed.milestones.find((m) => m.id === id);
683
+ if (!ms) return { error: `${id} not found` };
684
+
685
+ if (!ms.normal_milestones.some((m) => m.version === version)) {
686
+ return { error: `${version} is not linked to ${id}` };
687
+ }
688
+
689
+ // Protection: check if shipped
690
+ if (roadmapContent) {
691
+ const shipped = extractShippedVersions(roadmapContent);
692
+ if (shipped.includes(version)) {
693
+ return { error: `Cannot unlink ${version} from ${id}: milestone is already shipped` };
694
+ }
695
+ }
696
+
697
+ const updatedList = ms.normal_milestones.filter((m) => m.version !== version);
698
+ const newField = formatNormalMilestoneList(updatedList);
699
+
700
+ return replaceFieldInSection(content, id, 'Normal milestones', newField);
701
+ }
702
+
703
+ /**
704
+ * Find an LT milestone by ID.
705
+ * @param content - Raw LONG-TERM-ROADMAP.md content
706
+ * @param id - LT milestone ID
707
+ * @returns Parsed milestone, or null
708
+ */
709
+ function getLtMilestoneById(content: string, id: string): LtMilestone | null {
710
+ const parsed = parseLongTermRoadmap(content);
711
+ if (!parsed) return null;
712
+ return parsed.milestones.find((m) => m.id === id) || null;
713
+ }
714
+
715
+ /**
716
+ * Auto-group existing ROADMAP.md milestones into a single LT-1 milestone.
717
+ * All shipped + active milestones go into LT-1.
718
+ * @param roadmapContent - Raw ROADMAP.md content
719
+ * @param projectName - Project name
720
+ * @returns Generated LONG-TERM-ROADMAP.md content
721
+ */
722
+ function initFromRoadmap(roadmapContent: string, projectName: string): string {
723
+ const shipped = extractShippedVersions(roadmapContent);
724
+
725
+ // Also find non-shipped milestones from the bullet list
726
+ const allVersions: string[] = [];
727
+ const bulletPattern = /^-\s+(v[\d.]+)\b/gm;
728
+ let match: RegExpExecArray | null;
729
+ while ((match = bulletPattern.exec(roadmapContent)) !== null) {
730
+ allVersions.push(match[1]);
731
+ }
732
+
733
+ const normalMilestones: NormalMilestoneEntry[] = allVersions.map((v) => {
734
+ if (shipped.includes(v)) {
735
+ return { version: v };
736
+ }
737
+ return { version: v, note: 'planned' };
738
+ });
739
+
740
+ const hasShipped = shipped.length > 0;
741
+ const status = hasShipped ? 'active' : 'planned';
742
+
743
+ const milestones: LtMilestone[] = [
744
+ {
745
+ id: 'LT-1',
746
+ name: 'Initial Milestone Group',
747
+ status,
748
+ goal: 'Auto-grouped from existing ROADMAP.md milestones',
749
+ normal_milestones: normalMilestones,
750
+ },
751
+ ];
752
+
753
+ return generateLongTermRoadmap(milestones, projectName);
754
+ }
755
+
756
+ // ─── Internal Helpers ────────────────────────────────────────────────────────
757
+
758
+ /**
759
+ * Replace a bold field value within a specific LT milestone section.
760
+ * @param content - Full LONG-TERM-ROADMAP.md content
761
+ * @param id - LT milestone ID
762
+ * @param fieldName - Bold field name
763
+ * @param newValue - New field value
764
+ * @returns Updated content
765
+ */
766
+ function replaceFieldInSection(
767
+ content: string,
768
+ id: string,
769
+ fieldName: string,
770
+ newValue: string
771
+ ): string {
772
+ const escapedId = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
773
+ const sectionStart = content.match(new RegExp(`^##\\s+${escapedId}:`, 'm'));
774
+ if (!sectionStart || sectionStart.index === undefined) return content;
775
+
776
+ const afterSection = content.slice(sectionStart.index);
777
+ const nextH2 = afterSection.match(/\n##\s/);
778
+ const sectionEnd =
779
+ nextH2 && nextH2.index !== undefined ? sectionStart.index + nextH2.index : content.length;
780
+
781
+ const section = content.slice(sectionStart.index, sectionEnd);
782
+ const fieldPattern = new RegExp(`\\*\\*${fieldName}:\\*\\*\\s*.+`);
783
+ const updatedSection = section.replace(fieldPattern, `**${fieldName}:** ${newValue}`);
784
+
785
+ return content.slice(0, sectionStart.index) + updatedSection + content.slice(sectionEnd);
786
+ }
787
+
788
+ module.exports = {
789
+ updateRefinementHistory,
790
+ parseNormalMilestoneList,
791
+ formatNormalMilestoneList,
792
+ parseLtMilestone,
793
+ parseLongTermRoadmap,
794
+ validateLongTermRoadmap,
795
+ generateLongTermRoadmap,
796
+ formatLongTermRoadmap,
797
+ extractShippedVersions,
798
+ nextLtId,
799
+ addLtMilestone,
800
+ removeLtMilestone,
801
+ updateLtMilestone,
802
+ linkNormalMilestone,
803
+ unlinkNormalMilestone,
804
+ getLtMilestoneById,
805
+ initFromRoadmap,
806
+ };