@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,999 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execFileSync } = require('child_process');
6
+ const { execGit, output, error, getMilestoneInfo, loadConfig, findPhaseInternal, generateSlugInternal, } = require('./utils');
7
+ // ─── Internal Helpers ─────────────────────────────────────────────────────────
8
+ /**
9
+ * Compute the worktree directory path for a given milestone and phase.
10
+ * Uses project-local .worktrees/ directory to avoid OS temp cleanup issues.
11
+ * Resolves cwd via realpathSync to handle macOS symlinks.
12
+ */
13
+ function worktreePath(cwd, milestone, phase) {
14
+ const resolvedCwd = fs.realpathSync(cwd);
15
+ return path.join(resolvedCwd, '.worktrees', `grd-worktree-${milestone}-${phase}`);
16
+ }
17
+ /**
18
+ * Ensure .worktrees/ directory exists and is listed in .gitignore.
19
+ */
20
+ function ensureWorktreesDir(cwd) {
21
+ const worktreesDir = path.join(cwd, '.worktrees');
22
+ if (!fs.existsSync(worktreesDir)) {
23
+ fs.mkdirSync(worktreesDir, { recursive: true });
24
+ }
25
+ // Add .worktrees/ to .gitignore if not already present
26
+ const gitignorePath = path.join(cwd, '.gitignore');
27
+ let gitignoreContent = '';
28
+ try {
29
+ gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
30
+ }
31
+ catch (e) {
32
+ if (e.code !== 'ENOENT') {
33
+ // Non-ENOENT errors (EISDIR, EPERM, etc.) are unexpected — re-throw
34
+ throw e;
35
+ }
36
+ // No .gitignore yet — will create
37
+ }
38
+ if (!gitignoreContent.includes('.worktrees')) {
39
+ const newline = gitignoreContent.length > 0 && !gitignoreContent.endsWith('\n') ? '\n' : '';
40
+ try {
41
+ fs.writeFileSync(gitignorePath, gitignoreContent + newline + '.worktrees/\n', 'utf-8');
42
+ }
43
+ catch (e) {
44
+ process.stderr.write('Warning: could not update .gitignore: ' + e.message + '\n');
45
+ return false;
46
+ }
47
+ }
48
+ return true;
49
+ }
50
+ /**
51
+ * Compute the branch name for a worktree using the config template.
52
+ */
53
+ function worktreeBranch(cwd, milestone, phase, slug) {
54
+ const config = loadConfig(cwd);
55
+ const template = config.phase_branch_template || 'grd/{milestone}/{phase}-{slug}';
56
+ return template
57
+ .replace('{milestone}', milestone)
58
+ .replace('{phase}', phase)
59
+ .replace('{slug}', slug || phase);
60
+ }
61
+ /**
62
+ * Compute the milestone branch name using the config template.
63
+ */
64
+ function milestoneBranch(cwd, milestoneVersion) {
65
+ const config = loadConfig(cwd);
66
+ const template = config.milestone_branch_template || 'grd/{milestone}-{slug}';
67
+ const milestone = getMilestoneInfo(cwd);
68
+ const version = milestoneVersion || milestone.version;
69
+ const slug = generateSlugInternal(milestone.name) || 'milestone';
70
+ return template.replace('{milestone}', version).replace('{slug}', slug);
71
+ }
72
+ /**
73
+ * Parse git worktree list --porcelain output into structured entries.
74
+ * Each entry is separated by a blank line and has fields:
75
+ * worktree /path/to/worktree
76
+ * HEAD abc123
77
+ * branch refs/heads/branch-name
78
+ * (optional) locked
79
+ */
80
+ function parsePorcelainWorktrees(porcelainOutput) {
81
+ if (!porcelainOutput || !porcelainOutput.trim())
82
+ return [];
83
+ const blocks = porcelainOutput.trim().split(/\n\n+/);
84
+ const entries = [];
85
+ for (const block of blocks) {
86
+ const lines = block.trim().split('\n');
87
+ const entry = { path: '', head: '', branch: '', locked: false };
88
+ for (const line of lines) {
89
+ if (line.startsWith('worktree ')) {
90
+ entry.path = line.slice('worktree '.length);
91
+ }
92
+ else if (line.startsWith('HEAD ')) {
93
+ entry.head = line.slice('HEAD '.length);
94
+ }
95
+ else if (line.startsWith('branch ')) {
96
+ entry.branch = line.slice('branch '.length).replace('refs/heads/', '');
97
+ }
98
+ else if (line === 'locked') {
99
+ entry.locked = true;
100
+ }
101
+ }
102
+ if (entry.path) {
103
+ entries.push(entry);
104
+ }
105
+ }
106
+ return entries;
107
+ }
108
+ /**
109
+ * Extract phase and milestone from a GRD worktree directory name.
110
+ * Expected format: grd-worktree-{milestone}-{phase}
111
+ */
112
+ function parseWorktreeName(wtPath) {
113
+ const dirName = path.basename(wtPath);
114
+ const match = dirName.match(/^grd-worktree-(.+)-(\d+)$/);
115
+ if (!match)
116
+ return null;
117
+ return { milestone: match[1], phase: match[2] };
118
+ }
119
+ /**
120
+ * Get all GRD-managed worktrees (filtering out main and non-GRD entries).
121
+ * Looks for worktrees in the project-local .worktrees/ directory.
122
+ */
123
+ function getGrdWorktrees(cwd) {
124
+ const listResult = execGit(cwd, ['worktree', 'list', '--porcelain']);
125
+ if (listResult.exitCode !== 0)
126
+ return [];
127
+ const all = parsePorcelainWorktrees(listResult.stdout);
128
+ let resolvedCwd;
129
+ try {
130
+ resolvedCwd = fs.realpathSync(cwd);
131
+ }
132
+ catch {
133
+ return [];
134
+ }
135
+ const worktreesDir = path.join(resolvedCwd, '.worktrees');
136
+ return all
137
+ .filter((wt) => wt.path.startsWith(worktreesDir) && path.basename(wt.path).startsWith('grd-worktree-'))
138
+ .map((wt) => {
139
+ const meta = parseWorktreeName(wt.path);
140
+ return {
141
+ path: wt.path,
142
+ branch: wt.branch,
143
+ phase: meta ? meta.phase : '',
144
+ milestone: meta ? meta.milestone : '',
145
+ locked: wt.locked,
146
+ };
147
+ });
148
+ }
149
+ // ─── CLI Commands ─────────────────────────────────────────────────────────────
150
+ /**
151
+ * Create a new git worktree for a phase.
152
+ *
153
+ * Creates a worktree at {cwd}/.worktrees/grd-worktree-{milestone}-{phase}
154
+ * with a branch following the configured phase_branch_template pattern.
155
+ * Ensures .worktrees/ directory exists and is listed in .gitignore.
156
+ *
157
+ * @param cwd - Project working directory
158
+ * @param options - Worktree creation options (phase, milestone, slug, startPoint, force)
159
+ * @param raw - If true, output raw text instead of JSON
160
+ * @returns void (outputs JSON or raw text to stdout and exits)
161
+ */
162
+ function cmdWorktreeCreate(cwd, options, raw) {
163
+ const { phase, slug, startPoint } = options;
164
+ if (!phase) {
165
+ error('phase is required for worktree create');
166
+ return; // unreachable — error() calls process.exit()
167
+ }
168
+ // Resolve milestone from options or ROADMAP.md
169
+ const milestone = options.milestone || getMilestoneInfo(cwd).version;
170
+ const branchSlug = slug || phase;
171
+ // Ensure .worktrees/ directory exists and is in .gitignore
172
+ ensureWorktreesDir(cwd);
173
+ const wtPath = worktreePath(cwd, milestone, phase);
174
+ const branch = worktreeBranch(cwd, milestone, phase, branchSlug);
175
+ // Check if worktree already exists
176
+ if (fs.existsSync(wtPath)) {
177
+ output({ error: 'Worktree already exists', path: wtPath }, raw);
178
+ return; // unreachable — output() calls process.exit()
179
+ }
180
+ // Verify we are in a git repo
181
+ const revParse = execGit(cwd, ['rev-parse', '--git-dir']);
182
+ if (revParse.exitCode !== 0) {
183
+ output({ error: 'Not a git repository', details: revParse.stderr }, raw);
184
+ return; // unreachable
185
+ }
186
+ // Validate start-point exists if provided
187
+ if (startPoint) {
188
+ const check = execGit(cwd, ['rev-parse', '--verify', startPoint]);
189
+ if (check.exitCode !== 0) {
190
+ output({ error: `Start point '${startPoint}' not found`, details: check.stderr }, raw);
191
+ return; // unreachable
192
+ }
193
+ }
194
+ // Create the worktree with a new branch, optionally from a start point
195
+ const gitArgs = ['worktree', 'add', '-b', branch, wtPath];
196
+ if (startPoint) {
197
+ gitArgs.push(startPoint);
198
+ }
199
+ // Check if branch already exists (before attempting worktree add)
200
+ if (!options.force) {
201
+ const branchCheck = execGit(cwd, [
202
+ 'rev-parse',
203
+ '--verify',
204
+ 'refs/heads/' + branch,
205
+ ]);
206
+ if (branchCheck.exitCode === 0) {
207
+ output({ error: `Branch '${branch}' already exists`, branch }, raw);
208
+ return; // unreachable
209
+ }
210
+ }
211
+ const result = execGit(cwd, gitArgs);
212
+ if (result.exitCode !== 0) {
213
+ output({ error: 'Failed to create worktree', details: result.stderr, branch }, raw);
214
+ return; // unreachable
215
+ }
216
+ const out = {
217
+ path: wtPath,
218
+ branch,
219
+ phase,
220
+ milestone,
221
+ created: new Date().toISOString(),
222
+ };
223
+ if (startPoint) {
224
+ out.start_point = startPoint;
225
+ }
226
+ output(out, raw, `Worktree created: ${out.path} (branch: ${out.branch})`);
227
+ }
228
+ /**
229
+ * Remove a git worktree by phase identifier or direct path.
230
+ *
231
+ * Gracefully handles non-existent worktrees (returns success with already_gone flag).
232
+ * Calls git worktree prune after removal to clean git state.
233
+ *
234
+ * @param cwd - Project working directory
235
+ * @param options - Removal options containing phase, milestone, path, or force flag
236
+ * @param raw - If true, output raw text instead of JSON
237
+ * @returns void (outputs JSON or raw text to stdout and exits)
238
+ */
239
+ function cmdWorktreeRemove(cwd, options, raw) {
240
+ let wtPath;
241
+ if (options.path) {
242
+ wtPath = options.path;
243
+ }
244
+ else if (options.phase) {
245
+ const milestone = options.milestone || getMilestoneInfo(cwd).version;
246
+ wtPath = worktreePath(cwd, milestone, options.phase);
247
+ }
248
+ else {
249
+ error('Either --phase or --path is required for worktree remove. Specify which worktree to remove using --phase <N> or --path <worktree-path>. Example: worktree remove --phase 3. To list active worktrees: grd-tools.js worktree list');
250
+ return; // unreachable — error() calls process.exit()
251
+ }
252
+ // If path does not exist on disk, return graceful response
253
+ if (!fs.existsSync(wtPath)) {
254
+ // Also try to prune from git's perspective
255
+ execGit(cwd, ['worktree', 'prune']);
256
+ output({ removed: true, path: wtPath, already_gone: true }, raw);
257
+ return; // unreachable
258
+ }
259
+ // Try to remove via git worktree remove (--force for GRD-managed temp worktrees)
260
+ const removeResult = execGit(cwd, ['worktree', 'remove', wtPath, '--force'], {
261
+ allowBlocked: true,
262
+ });
263
+ if (removeResult.exitCode !== 0) {
264
+ process.stderr.write('Warning: git worktree remove failed: ' +
265
+ (removeResult.stderr || 'unknown error').trim() +
266
+ '\n');
267
+ }
268
+ // Prune to clean git state
269
+ execGit(cwd, ['worktree', 'prune']);
270
+ // Clean up the temp directory if it still exists
271
+ if (fs.existsSync(wtPath)) {
272
+ fs.rmSync(wtPath, { recursive: true, force: true });
273
+ }
274
+ output({ removed: true, path: wtPath }, raw);
275
+ }
276
+ /**
277
+ * List all active GRD-managed worktrees.
278
+ *
279
+ * Parses git worktree list --porcelain output and filters to only
280
+ * GRD-created worktrees (those in .worktrees/ with grd-worktree- prefix).
281
+ * Returns empty array if no worktrees exist.
282
+ *
283
+ * @param cwd - Project working directory
284
+ * @param raw - If true, output raw text instead of JSON
285
+ * @returns void (outputs JSON or raw text to stdout and exits)
286
+ */
287
+ function cmdWorktreeList(cwd, raw) {
288
+ const worktrees = getGrdWorktrees(cwd);
289
+ output({ worktrees, count: worktrees.length }, raw);
290
+ }
291
+ /**
292
+ * Remove stale worktrees whose disk directories no longer exist.
293
+ *
294
+ * A worktree is stale if its path does not exist on disk or is empty.
295
+ * Locked worktrees are never removed regardless of disk state.
296
+ *
297
+ * @param cwd - Project working directory
298
+ * @param raw - If true, output raw text instead of JSON
299
+ * @returns void (outputs JSON or raw text to stdout and exits)
300
+ */
301
+ function cmdWorktreeRemoveStale(cwd, raw) {
302
+ const worktrees = getGrdWorktrees(cwd);
303
+ const removed = [];
304
+ for (const wt of worktrees) {
305
+ // Never remove locked worktrees
306
+ if (wt.locked)
307
+ continue;
308
+ // Check if path exists and is non-empty
309
+ let isStale = false;
310
+ try {
311
+ if (!fs.existsSync(wt.path)) {
312
+ isStale = true;
313
+ }
314
+ else {
315
+ const entries = fs.readdirSync(wt.path);
316
+ if (entries.length === 0) {
317
+ isStale = true;
318
+ }
319
+ }
320
+ }
321
+ catch {
322
+ isStale = true;
323
+ }
324
+ if (isStale) {
325
+ // Remove from git's worktree tracking
326
+ execGit(cwd, ['worktree', 'remove', wt.path, '--force'], { allowBlocked: true });
327
+ removed.push(wt.path);
328
+ }
329
+ }
330
+ // Final prune to clean any remaining stale references
331
+ execGit(cwd, ['worktree', 'prune']);
332
+ output({ removed, count: removed.length }, raw);
333
+ }
334
+ /**
335
+ * Push worktree branch to remote and create a PR via gh CLI.
336
+ *
337
+ * Both error paths return structured JSON (exit 0) so callers (orchestrators,
338
+ * MCP) receive parseable output rather than a crash.
339
+ *
340
+ * @param cwd - Project working directory
341
+ * @param options - Options object containing phase, milestone, title, body, and base branch
342
+ * @param raw - If true, output raw text instead of JSON
343
+ * @returns void (outputs JSON or raw text to stdout and exits)
344
+ */
345
+ function cmdWorktreePushAndPR(cwd, options, raw) {
346
+ const { phase } = options;
347
+ if (!phase) {
348
+ output({ error: 'phase is required for worktree push-pr' }, raw);
349
+ return; // unreachable
350
+ }
351
+ // Resolve milestone
352
+ const milestone = options.milestone || getMilestoneInfo(cwd).version;
353
+ // Compute worktree path
354
+ const wtPath = worktreePath(cwd, milestone, phase);
355
+ // Verify worktree directory exists on disk
356
+ if (!fs.existsSync(wtPath)) {
357
+ output({ error: `Worktree not found at ${wtPath}`, phase, milestone }, raw);
358
+ return; // unreachable
359
+ }
360
+ // Read the actual branch name from the worktree HEAD (more robust than recomputing)
361
+ const headResult = execGit(wtPath, ['rev-parse', '--abbrev-ref', 'HEAD']);
362
+ const branch = headResult.exitCode === 0 && headResult.stdout
363
+ ? headResult.stdout.trim()
364
+ : worktreeBranch(cwd, milestone, phase, phase); // fallback
365
+ // Derive slug from branch name for title generation
366
+ const phaseInfo = findPhaseInternal(cwd, phase);
367
+ const slug = phaseInfo && phaseInfo.phase_slug
368
+ ? phaseInfo.phase_slug
369
+ : branch.split('/').pop()?.replace(/^\d+-/, '') || phase;
370
+ // Push branch to origin from worktree directory
371
+ const pushResult = execGit(wtPath, ['push', '-u', 'origin', branch], {
372
+ allowBlocked: true,
373
+ });
374
+ if (pushResult.exitCode !== 0) {
375
+ output({
376
+ error: 'Failed to push branch',
377
+ details: pushResult.stderr,
378
+ phase,
379
+ milestone,
380
+ branch,
381
+ }, raw);
382
+ return; // unreachable
383
+ }
384
+ // Resolve base branch
385
+ const config = loadConfig(cwd);
386
+ const baseBranch = options.base || config.base_branch || 'main';
387
+ // Build PR title
388
+ const title = options.title || `Phase ${phase}: ${slug} (${milestone})`;
389
+ // Build PR body
390
+ const body = options.body || `## Phase ${phase}\n\nMilestone: ${milestone}\nBranch: ${branch}\n`;
391
+ // Create PR via gh CLI
392
+ let ghOutput;
393
+ try {
394
+ ghOutput = execFileSync('gh', ['pr', 'create', '--title', title, '--body', body, '--base', baseBranch, '--head', branch], { cwd: wtPath, stdio: 'pipe', encoding: 'utf-8' });
395
+ }
396
+ catch (ghErr) {
397
+ // gh failed — return structured error with push_succeeded flag
398
+ const stderr = ghErr.stderr
399
+ ? String(ghErr.stderr).trim()
400
+ : ghErr.message || 'Unknown gh error';
401
+ output({
402
+ error: 'Failed to create PR via gh CLI',
403
+ details: stderr,
404
+ push_succeeded: true,
405
+ phase,
406
+ milestone,
407
+ branch,
408
+ base: baseBranch,
409
+ title,
410
+ body,
411
+ }, raw);
412
+ return; // unreachable
413
+ }
414
+ // gh pr create outputs the PR URL on stdout
415
+ const prUrl = ghOutput.trim();
416
+ const urlParts = prUrl.split('/');
417
+ const prNumber = urlParts.length > 0 ? urlParts[urlParts.length - 1] : null;
418
+ output({
419
+ pr_url: prUrl,
420
+ pr_number: prNumber,
421
+ branch,
422
+ base: baseBranch,
423
+ title,
424
+ body,
425
+ phase,
426
+ milestone,
427
+ }, raw);
428
+ }
429
+ // ─── Programmatic Helpers (evolve, autopilot) ────────────────────────────────
430
+ /**
431
+ * Create a worktree for the evolve loop.
432
+ * Returns a result object instead of calling output() — suitable for
433
+ * programmatic callers that need the path/branch info.
434
+ *
435
+ * Worktree directory: {cwd}/.worktrees/grd-evolve-{YYYYMMDD-HHmmss}
436
+ * Branch name: grd/evolve/{YYYYMMDD-HHmmss}
437
+ *
438
+ * @param cwd - Project working directory
439
+ * @returns EvolveWorktreeResult with path, branch, baseBranch, and created timestamp, or EvolveWorktreeError with error message
440
+ */
441
+ function createEvolveWorktree(cwd) {
442
+ // Verify git repo
443
+ const revParse = execGit(cwd, ['rev-parse', '--git-dir']);
444
+ if (revParse.exitCode !== 0) {
445
+ return { error: 'Not a git repository' };
446
+ }
447
+ const now = new Date();
448
+ const stamp = now
449
+ .toISOString()
450
+ .replace(/[-:T]/g, '')
451
+ .replace(/\.\d+Z$/, '')
452
+ .slice(0, 15);
453
+ // stamp format: YYYYMMDD + HHmmss (15 chars)
454
+ const tag = `${stamp.slice(0, 8)}-${stamp.slice(8)}`;
455
+ const config = loadConfig(cwd);
456
+ const baseBranch = config.base_branch || 'main';
457
+ ensureWorktreesDir(cwd);
458
+ const resolvedCwd = fs.realpathSync(cwd);
459
+ const wtPath = path.join(resolvedCwd, '.worktrees', `grd-evolve-${tag}`);
460
+ const branch = `grd/evolve/${tag}`;
461
+ if (fs.existsSync(wtPath)) {
462
+ return { error: `Worktree already exists at ${wtPath}` };
463
+ }
464
+ const result = execGit(cwd, ['worktree', 'add', '-b', branch, wtPath, baseBranch]);
465
+ if (result.exitCode !== 0) {
466
+ return { error: `Failed to create worktree: ${result.stderr}` };
467
+ }
468
+ return {
469
+ path: wtPath,
470
+ branch,
471
+ baseBranch,
472
+ created: now.toISOString(),
473
+ };
474
+ }
475
+ /**
476
+ * Remove an evolve worktree and prune git state.
477
+ * Gracefully handles already-removed worktrees.
478
+ */
479
+ function removeEvolveWorktree(cwd, wtPath) {
480
+ if (!fs.existsSync(wtPath)) {
481
+ execGit(cwd, ['worktree', 'prune']);
482
+ return { removed: true, already_gone: true };
483
+ }
484
+ execGit(cwd, ['worktree', 'remove', wtPath, '--force'], { allowBlocked: true });
485
+ execGit(cwd, ['worktree', 'prune']);
486
+ if (fs.existsSync(wtPath)) {
487
+ fs.rmSync(wtPath, { recursive: true, force: true });
488
+ }
489
+ return { removed: true };
490
+ }
491
+ /**
492
+ * Push a worktree branch to remote and create a PR via gh CLI.
493
+ * Returns structured result instead of calling output().
494
+ */
495
+ function pushAndCreatePR(cwd, wtPath, options = {}) {
496
+ // Read branch from worktree HEAD
497
+ const headResult = execGit(wtPath, ['rev-parse', '--abbrev-ref', 'HEAD']);
498
+ if (headResult.exitCode !== 0) {
499
+ return { error: 'Failed to determine worktree branch' };
500
+ }
501
+ const branch = headResult.stdout.trim();
502
+ const config = loadConfig(cwd);
503
+ const baseBranch = options.base || config.base_branch || 'main';
504
+ // Push branch
505
+ const pushResult = execGit(wtPath, ['push', '-u', 'origin', branch], {
506
+ allowBlocked: true,
507
+ });
508
+ if (pushResult.exitCode !== 0) {
509
+ return {
510
+ error: `Failed to push branch: ${pushResult.stderr}`,
511
+ push_succeeded: false,
512
+ };
513
+ }
514
+ const title = options.title || `Evolve: improvements on ${branch}`;
515
+ const body = options.body || `Automated improvements from the evolve loop.\n\nBranch: ${branch}\n`;
516
+ // Create PR via gh CLI
517
+ let ghOutput;
518
+ try {
519
+ ghOutput = execFileSync('gh', ['pr', 'create', '--title', title, '--body', body, '--base', baseBranch, '--head', branch], { cwd: wtPath, stdio: 'pipe', encoding: 'utf-8' });
520
+ }
521
+ catch (ghErr) {
522
+ const stderr = ghErr.stderr
523
+ ? String(ghErr.stderr).trim()
524
+ : ghErr.message || 'Unknown gh error';
525
+ return { error: `Failed to create PR: ${stderr}`, push_succeeded: true };
526
+ }
527
+ return {
528
+ pr_url: ghOutput.trim(),
529
+ branch,
530
+ base: baseBranch,
531
+ };
532
+ }
533
+ // ─── Milestone Branch Operations ──────────────────────────────────────────────
534
+ /**
535
+ * Ensure the milestone branch exists, creating it from baseBranch if needed.
536
+ */
537
+ function cmdWorktreeEnsureMilestoneBranch(cwd, options, raw) {
538
+ const milestoneVersion = options.milestone || getMilestoneInfo(cwd).version;
539
+ const config = loadConfig(cwd);
540
+ const baseBranch = options.baseBranch || config.base_branch || 'main';
541
+ const branch = milestoneBranch(cwd, milestoneVersion);
542
+ // Check if branch already exists
543
+ const check = execGit(cwd, ['rev-parse', '--verify', branch]);
544
+ if (check.exitCode === 0) {
545
+ output({ branch, already_existed: true }, raw);
546
+ return; // unreachable
547
+ }
548
+ // Verify base branch exists
549
+ const baseCheck = execGit(cwd, ['rev-parse', '--verify', baseBranch]);
550
+ if (baseCheck.exitCode !== 0) {
551
+ output({ error: `Base branch '${baseBranch}' not found`, details: baseCheck.stderr }, raw);
552
+ return; // unreachable
553
+ }
554
+ // Create branch without checkout
555
+ const result = execGit(cwd, ['branch', branch, baseBranch]);
556
+ if (result.exitCode !== 0) {
557
+ output({ error: 'Failed to create milestone branch', details: result.stderr }, raw);
558
+ return; // unreachable
559
+ }
560
+ output({ branch, already_existed: false, base_branch: baseBranch }, raw);
561
+ }
562
+ /**
563
+ * Merge a phase branch into the target branch.
564
+ *
565
+ * Target branch is determined by: options.base > config.base_branch > milestone branch.
566
+ * When --base is provided, merges directly into that branch (no milestone branch required).
567
+ * Otherwise falls back to the milestone branch for backward compatibility.
568
+ *
569
+ * Records the current branch, checks out the target branch, merges the
570
+ * phase branch with --no-ff, and restores the original branch. On conflict,
571
+ * aborts the merge and restores the original branch.
572
+ *
573
+ * @param cwd - Project working directory
574
+ * @param options - Merge options including phase, milestone, slug, branch, base, deleteBranch, and strategy
575
+ * @param raw - If true, output raw text instead of JSON
576
+ * @returns void (outputs JSON or raw text to stdout and exits)
577
+ */
578
+ function cmdWorktreeMerge(cwd, options, raw) {
579
+ const { phase, slug, deleteBranch } = options;
580
+ if (!phase) {
581
+ error('phase is required for worktree merge. Usage: worktree merge --phase <N>. Add the --phase flag, e.g.: worktree merge --phase 2');
582
+ return; // unreachable — error() calls process.exit()
583
+ }
584
+ const milestoneVersion = options.milestone || getMilestoneInfo(cwd).version;
585
+ const phaseBranch = options.branch || worktreeBranch(cwd, milestoneVersion, phase, slug || phase);
586
+ // Determine target branch: explicit --base, or milestone branch (with fallback to config base_branch)
587
+ let targetBranch;
588
+ if (options.base) {
589
+ // Explicit base branch — merge directly into it (no milestone branch needed)
590
+ targetBranch = options.base;
591
+ }
592
+ else {
593
+ // Try milestone branch first (backward compat); fall back to config.base_branch
594
+ const msBranch = milestoneBranch(cwd, milestoneVersion);
595
+ const msCheck = execGit(cwd, ['rev-parse', '--verify', msBranch]);
596
+ if (msCheck.exitCode === 0) {
597
+ targetBranch = msBranch;
598
+ }
599
+ else {
600
+ const config = loadConfig(cwd);
601
+ targetBranch = config.base_branch || 'main';
602
+ }
603
+ }
604
+ // Verify target branch exists
605
+ const targetCheck = execGit(cwd, ['rev-parse', '--verify', targetBranch]);
606
+ if (targetCheck.exitCode !== 0) {
607
+ output({ error: `Target branch '${targetBranch}' not found` }, raw);
608
+ return; // unreachable
609
+ }
610
+ // Verify phase branch exists
611
+ const phaseCheck = execGit(cwd, ['rev-parse', '--verify', phaseBranch]);
612
+ if (phaseCheck.exitCode !== 0) {
613
+ output({ error: `Phase branch '${phaseBranch}' not found` }, raw);
614
+ return; // unreachable
615
+ }
616
+ // Record current branch
617
+ const headResult = execGit(cwd, ['rev-parse', '--abbrev-ref', 'HEAD']);
618
+ const originalBranch = headResult.exitCode === 0 ? headResult.stdout.trim() : 'main';
619
+ // Checkout target branch
620
+ const coResult = execGit(cwd, ['checkout', targetBranch]);
621
+ if (coResult.exitCode !== 0) {
622
+ output({
623
+ error: `Failed to checkout target branch '${targetBranch}'`,
624
+ details: coResult.stderr,
625
+ }, raw);
626
+ return; // unreachable
627
+ }
628
+ // Get phase info for merge commit message
629
+ const phaseInfo = findPhaseInternal(cwd, phase);
630
+ const phaseName = phaseInfo ? phaseInfo.phase_name || slug || phase : slug || phase;
631
+ // Merge phase branch with --no-ff
632
+ const mergeResult = execGit(cwd, [
633
+ 'merge',
634
+ '--no-ff',
635
+ phaseBranch,
636
+ '-m',
637
+ `Merge phase ${phase}: ${phaseName}`,
638
+ ]);
639
+ if (mergeResult.exitCode !== 0) {
640
+ // Merge conflict — abort and restore original branch
641
+ execGit(cwd, ['merge', '--abort']);
642
+ const abortRestore = execGit(cwd, ['checkout', originalBranch]);
643
+ if (abortRestore.exitCode !== 0) {
644
+ process.stderr.write(`[grd] WARNING: failed to restore branch ${originalBranch} after merge abort\n`);
645
+ }
646
+ output({
647
+ error: 'Merge conflict',
648
+ details: mergeResult.stderr,
649
+ target_branch: targetBranch,
650
+ phase_branch: phaseBranch,
651
+ }, raw);
652
+ return; // unreachable
653
+ }
654
+ // Optionally delete phase branch
655
+ if (deleteBranch) {
656
+ execGit(cwd, ['branch', '-d', phaseBranch]);
657
+ }
658
+ // Restore original branch
659
+ const restoreResult = execGit(cwd, ['checkout', originalBranch]);
660
+ const restoredBranch = restoreResult.exitCode === 0;
661
+ if (!restoredBranch) {
662
+ process.stderr.write(`[grd] WARNING: failed to restore branch ${originalBranch} after merge\n`);
663
+ }
664
+ output({
665
+ merged: true,
666
+ target_branch: targetBranch,
667
+ phase_branch: phaseBranch,
668
+ phase,
669
+ branch_deleted: !!deleteBranch,
670
+ original_branch_restored: restoredBranch,
671
+ }, raw);
672
+ }
673
+ // ─── Hook Handlers ────────────────────────────────────────────────────────────
674
+ /**
675
+ * Hook handler for WorktreeCreate events from Claude Code.
676
+ *
677
+ * When Claude Code creates a worktree natively (via `isolation: worktree`),
678
+ * this hook fires to optionally rename the branch to GRD's naming convention
679
+ * and log the lifecycle event. No-op when GRD is inactive or branching disabled.
680
+ *
681
+ * @param cwd - Project working directory
682
+ * @param wtPath - Path to the created worktree ($WORKTREE_PATH)
683
+ * @param wtBranch - Branch name of the created worktree ($WORKTREE_BRANCH)
684
+ * @param raw - If true, output raw text instead of JSON
685
+ * @returns void (outputs JSON or raw text to stdout and exits)
686
+ */
687
+ function cmdWorktreeHookCreate(cwd, wtPath, wtBranch, raw) {
688
+ // No-op when GRD is inactive
689
+ if (!fs.existsSync(path.join(cwd, '.planning'))) {
690
+ output({ skipped: true, reason: 'no .planning directory' }, raw);
691
+ return; // unreachable
692
+ }
693
+ // No-op when branching is disabled
694
+ const config = loadConfig(cwd);
695
+ if (config.branching_strategy === 'none') {
696
+ output({ skipped: true, reason: 'branching disabled' }, raw);
697
+ return; // unreachable
698
+ }
699
+ // Check if branch already follows GRD convention (starts with 'grd/')
700
+ if (wtBranch && wtBranch.startsWith('grd/')) {
701
+ output({
702
+ hooked: true,
703
+ worktree_path: wtPath,
704
+ branch: wtBranch,
705
+ renamed: false,
706
+ reason: 'branch already follows GRD convention',
707
+ }, raw);
708
+ return; // unreachable
709
+ }
710
+ // Try to extract phase info from the worktree path for branch rename
711
+ const dirName = path.basename(wtPath || '');
712
+ const phaseMatch = dirName.match(/(\d+)$/);
713
+ if (phaseMatch) {
714
+ const phase = phaseMatch[1];
715
+ try {
716
+ const milestone = getMilestoneInfo(cwd);
717
+ const phaseInfo = findPhaseInternal(cwd, phase);
718
+ const slug = phaseInfo
719
+ ? generateSlugInternal(phaseInfo.phase_slug || phaseInfo.phase_name || '') || phase
720
+ : phase;
721
+ const grdBranch = worktreeBranch(cwd, milestone.version, phase, slug);
722
+ if (grdBranch !== wtBranch) {
723
+ const renameResult = execGit(wtPath, ['branch', '-m', wtBranch, grdBranch]);
724
+ if (renameResult.exitCode === 0) {
725
+ output({
726
+ hooked: true,
727
+ worktree_path: wtPath,
728
+ branch: grdBranch,
729
+ renamed: true,
730
+ original_branch: wtBranch,
731
+ }, raw);
732
+ return; // unreachable
733
+ }
734
+ // Rename failed — log warning to stderr and continue
735
+ process.stderr.write('Warning: branch rename failed: ' +
736
+ (renameResult.stderr || 'git branch rename failed').trim() +
737
+ '\n');
738
+ output({
739
+ hooked: true,
740
+ worktree_path: wtPath,
741
+ branch: wtBranch,
742
+ renamed: false,
743
+ rename_failed: true,
744
+ reason: renameResult.stderr || 'git branch rename failed',
745
+ }, raw);
746
+ return; // unreachable
747
+ }
748
+ }
749
+ catch (_e) {
750
+ // Could not determine milestone/phase info — log creation without rename
751
+ }
752
+ }
753
+ // Default: log creation without rename
754
+ output({
755
+ hooked: true,
756
+ worktree_path: wtPath,
757
+ branch: wtBranch,
758
+ renamed: false,
759
+ }, raw);
760
+ }
761
+ /**
762
+ * Hook handler for WorktreeRemove events from Claude Code.
763
+ *
764
+ * Logs the worktree removal for tracking. Intentionally minimal —
765
+ * Phase 46 will add state cleanup here if needed.
766
+ * No-op when GRD is inactive or branching disabled.
767
+ *
768
+ * @param cwd - Project working directory
769
+ * @param wtPath - Path to the removed worktree ($WORKTREE_PATH)
770
+ * @param wtBranch - Branch name of the removed worktree ($WORKTREE_BRANCH)
771
+ * @param raw - If true, output raw text instead of JSON
772
+ * @returns void (outputs JSON or raw text to stdout and exits)
773
+ */
774
+ function cmdWorktreeHookRemove(cwd, wtPath, wtBranch, raw) {
775
+ // No-op when GRD is inactive
776
+ if (!fs.existsSync(path.join(cwd, '.planning'))) {
777
+ output({ skipped: true, reason: 'no .planning directory' }, raw);
778
+ return; // unreachable
779
+ }
780
+ // No-op when branching is disabled
781
+ const config = loadConfig(cwd);
782
+ if (config.branching_strategy === 'none') {
783
+ output({ skipped: true, reason: 'branching disabled' }, raw);
784
+ return; // unreachable
785
+ }
786
+ const result = {
787
+ hooked: true,
788
+ worktree_path: wtPath,
789
+ branch: wtBranch,
790
+ action: 'remove_logged',
791
+ };
792
+ // Try to extract phase/milestone metadata from the worktree path
793
+ // Expected GRD format: grd-worktree-{milestone}-{phase}
794
+ try {
795
+ const meta = parseWorktreeName(wtPath || '');
796
+ if (meta) {
797
+ result.phase_detected = meta.phase;
798
+ result.milestone_detected = meta.milestone;
799
+ }
800
+ }
801
+ catch (_e) {
802
+ // Best-effort: metadata extraction failure is not an error
803
+ }
804
+ output(result, raw, `Worktree hook: ${result.worktree_path}`);
805
+ }
806
+ // ─── Hook Handlers ────────────────────────────────────────────────────────────
807
+ /**
808
+ * Hook handler for TeammateIdle events.
809
+ * Called when a teammate spawned via Agent tool becomes idle.
810
+ * Supports {continue: false, stopReason: "..."} response to stop the teammate.
811
+ *
812
+ * Environment variables from hook payload:
813
+ * - AGENT_ID: unique identifier of the idle agent
814
+ * - AGENT_TYPE: type of the agent (e.g., "task", "teammate")
815
+ */
816
+ function cmdTeammateIdleHook(_cwd, raw) {
817
+ const agentId = process.env.AGENT_ID || 'unknown';
818
+ const agentType = process.env.AGENT_TYPE || 'unknown';
819
+ // For now, allow all teammates to continue.
820
+ // Future: filter by agent_type to stop non-GRD agents or agents that have completed their work.
821
+ const result = {
822
+ ok: true,
823
+ hook: 'TeammateIdle',
824
+ agent_id: agentId,
825
+ agent_type: agentType,
826
+ action: 'continue',
827
+ };
828
+ if (raw) {
829
+ process.stdout.write(`TeammateIdle: agent=${agentId} type=${agentType} action=continue\n`);
830
+ }
831
+ else {
832
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
833
+ }
834
+ }
835
+ /**
836
+ * Hook handler for TaskCompleted events.
837
+ * Called when a background task completes.
838
+ * Supports {continue: false, stopReason: "..."} response to stop the task.
839
+ *
840
+ * Environment variables from hook payload:
841
+ * - AGENT_ID: unique identifier of the completed task agent
842
+ * - AGENT_TYPE: type of the agent
843
+ */
844
+ function cmdTaskCompletedHook(_cwd, raw) {
845
+ const agentId = process.env.AGENT_ID || 'unknown';
846
+ const agentType = process.env.AGENT_TYPE || 'unknown';
847
+ const result = {
848
+ ok: true,
849
+ hook: 'TaskCompleted',
850
+ agent_id: agentId,
851
+ agent_type: agentType,
852
+ action: 'acknowledged',
853
+ };
854
+ if (raw) {
855
+ process.stdout.write(`TaskCompleted: agent=${agentId} type=${agentType}\n`);
856
+ }
857
+ else {
858
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
859
+ }
860
+ }
861
+ /**
862
+ * Hook handler for InstructionsLoaded events.
863
+ * Called when CLAUDE.md or rules files are loaded.
864
+ * Used for plugin setup verification (e.g., confirm .planning/ exists).
865
+ *
866
+ * Environment variables from hook payload:
867
+ * - AGENT_ID: unique identifier of the agent loading instructions
868
+ * - AGENT_TYPE: type of the agent
869
+ */
870
+ function cmdInstructionsLoadedHook(cwd, raw) {
871
+ const agentId = process.env.AGENT_ID || 'unknown';
872
+ const agentType = process.env.AGENT_TYPE || 'unknown';
873
+ const planningDir = path.join(cwd, '.planning');
874
+ const planningExists = fs.existsSync(planningDir);
875
+ const result = {
876
+ ok: true,
877
+ hook: 'InstructionsLoaded',
878
+ agent_id: agentId,
879
+ agent_type: agentType,
880
+ planning_exists: planningExists,
881
+ };
882
+ if (raw) {
883
+ process.stdout.write(`InstructionsLoaded: agent=${agentId} planning=${planningExists}\n`);
884
+ }
885
+ else {
886
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
887
+ }
888
+ }
889
+ /**
890
+ * Hook handler for StopFailure events (Claude Code v2.1.78+).
891
+ *
892
+ * Fires when a turn ends due to an API-level failure (rate limit, auth failure,
893
+ * network error). GRD uses this to log failures to autopilot.log so the
894
+ * autopilot/evolve retry logic can detect and act on them.
895
+ *
896
+ * Environment variables from hook payload:
897
+ * - STOP_REASON: reason the turn stopped (e.g., "rate_limit", "auth_failure", "api_error")
898
+ * - ERROR_MESSAGE: error message text (optional)
899
+ * - AGENT_ID: unique identifier of the affected agent (optional)
900
+ *
901
+ * Note: allowRead sandbox setting (v2.1.77) can re-allow read access within
902
+ * denyRead regions — relevant for plugin data paths that need to check autopilot.log.
903
+ *
904
+ * @param cwd - Project working directory
905
+ * @param raw - If true, output raw text instead of JSON
906
+ * @returns void (outputs JSON or raw text to stdout)
907
+ */
908
+ function cmdStopFailureHook(cwd, raw) {
909
+ const stopReason = process.env.STOP_REASON || 'unknown';
910
+ const errorMessage = process.env.ERROR_MESSAGE || '';
911
+ const agentId = process.env.AGENT_ID || 'unknown';
912
+ // Check if autopilot.log exists — indicates an active autopilot/evolve session
913
+ const autopilotLogPath = path.join(cwd, '.planning', 'autopilot', 'autopilot.log');
914
+ const autopilotActive = fs.existsSync(autopilotLogPath);
915
+ let logged = false;
916
+ if (autopilotActive) {
917
+ // Append timestamped failure entry to autopilot.log
918
+ const timestamp = new Date().toISOString();
919
+ const logEntry = `[${timestamp}] STOP_FAILURE: reason=${stopReason} error=${errorMessage || '(none)'} agent=${agentId}\n`;
920
+ try {
921
+ fs.appendFileSync(autopilotLogPath, logEntry, 'utf-8');
922
+ logged = true;
923
+ }
924
+ catch (writeErr) {
925
+ process.stderr.write(`[grd] WARNING: failed to write StopFailure to autopilot.log: ${writeErr.message}\n`);
926
+ }
927
+ }
928
+ const result = {
929
+ ok: true,
930
+ hook: 'StopFailure',
931
+ stop_reason: stopReason,
932
+ error_message: errorMessage,
933
+ agent_id: agentId,
934
+ logged,
935
+ };
936
+ if (raw) {
937
+ process.stdout.write(`StopFailure: reason=${stopReason} agent=${agentId} logged=${logged}\n`);
938
+ }
939
+ else {
940
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
941
+ }
942
+ }
943
+ /**
944
+ * Hook handler for PostCompact events (Claude Code v2.1.76+).
945
+ *
946
+ * Fires after context compaction completes. GRD acknowledges the event and
947
+ * continues — this hook is informational only. Future use: could trigger
948
+ * context reload or state refresh to account for compacted history.
949
+ *
950
+ * Environment variables from hook payload:
951
+ * - AGENT_ID: unique identifier of the agent (optional)
952
+ * - AGENT_TYPE: type of the agent (optional)
953
+ *
954
+ * @param _cwd - Project working directory (unused — compaction is informational)
955
+ * @param raw - If true, output raw text instead of JSON
956
+ * @returns void (outputs JSON or raw text to stdout)
957
+ */
958
+ function cmdPostCompactHook(_cwd, raw) {
959
+ const agentId = process.env.AGENT_ID || 'unknown';
960
+ const agentType = process.env.AGENT_TYPE || 'unknown';
961
+ const result = {
962
+ ok: true,
963
+ hook: 'PostCompact',
964
+ agent_id: agentId,
965
+ agent_type: agentType,
966
+ acknowledged: true,
967
+ };
968
+ if (raw) {
969
+ process.stdout.write(`PostCompact: agent=${agentId} type=${agentType} acknowledged=true\n`);
970
+ }
971
+ else {
972
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
973
+ }
974
+ }
975
+ // ─── Exports ──────────────────────────────────────────────────────────────────
976
+ module.exports = {
977
+ worktreePath,
978
+ worktreeBranch,
979
+ ensureWorktreesDir,
980
+ createEvolveWorktree,
981
+ removeEvolveWorktree,
982
+ pushAndCreatePR,
983
+ cmdWorktreeCreate,
984
+ cmdWorktreeRemove,
985
+ cmdWorktreeList,
986
+ cmdWorktreeRemoveStale,
987
+ cmdWorktreePushAndPR,
988
+ milestoneBranch,
989
+ cmdWorktreeEnsureMilestoneBranch,
990
+ cmdWorktreeMerge,
991
+ cmdWorktreeHookCreate,
992
+ cmdWorktreeHookRemove,
993
+ cmdTeammateIdleHook,
994
+ cmdTaskCompletedHook,
995
+ cmdInstructionsLoadedHook,
996
+ cmdStopFailureHook,
997
+ cmdPostCompactHook,
998
+ };
999
+ //# sourceMappingURL=worktree.js.map