@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,1139 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * GRD Evolve -- Orchestrator
5
+ *
6
+ * Main evolve iteration loop, iteration step handling, evolution notes,
7
+ * and todos integration. Prompt templates are in ./_prompts.ts.
8
+ *
9
+ * @dependencies ./types, ./state, ./discovery, ./scoring, ./_prompts,
10
+ * ../utils, ../autopilot, ../worktree
11
+ */
12
+
13
+ import type {
14
+ WorkItem,
15
+ WorkGroup,
16
+ EvolveState,
17
+ EvolveGroupState,
18
+ EvolveOptions,
19
+ EvolveResult,
20
+ GroupOutcome,
21
+ GroupDiscoveryResult,
22
+ IterationResult,
23
+ DryRunIterationResult,
24
+ IterationContext,
25
+ IterationStepResult,
26
+ IterationFeedback,
27
+ HandleIterationReturn,
28
+ WorktreeInfo,
29
+ EvolutionNotesData,
30
+ HistoryEntry,
31
+ InfiniteEvolveOptions,
32
+ InfiniteEvolveResult,
33
+ InfiniteEvolveCycleResult,
34
+ } from './types';
35
+ import type {
36
+ AutoplanOptions,
37
+ AutoplanResult,
38
+ MultiMilestoneOptions,
39
+ MultiMilestoneResult,
40
+ GrdConfig,
41
+ } from '../types';
42
+
43
+ const fs = require('fs');
44
+ const path = require('path');
45
+ const {
46
+ loadConfig,
47
+ MODEL_PROFILES,
48
+ resolveModelForAgent,
49
+ }: {
50
+ loadConfig: (cwd: string) => GrdConfig;
51
+ MODEL_PROFILES: Record<string, Record<string, string>>;
52
+ resolveModelForAgent: (
53
+ config: GrdConfig,
54
+ agentType: string,
55
+ cwd?: string,
56
+ options?: { effectiveTierOverride?: import('../types').ModelTier }
57
+ ) => string;
58
+ } = require('../utils');
59
+ import type { Scheduler } from '../scheduler';
60
+ const {
61
+ createScheduler,
62
+ }: {
63
+ createScheduler: (config: import('../types').SchedulerConfig | undefined) => Scheduler | null;
64
+ } = require('../scheduler');
65
+ const {
66
+ execGit,
67
+ }: {
68
+ execGit: (
69
+ cwd: string,
70
+ args: string[],
71
+ opts?: { allowBlocked?: boolean }
72
+ ) => { exitCode: number; stdout: string; stderr: string };
73
+ } = require('../utils');
74
+ const {
75
+ spawnClaudeAsync,
76
+ }: {
77
+ spawnClaudeAsync: (
78
+ cwd: string,
79
+ prompt: string,
80
+ opts?: {
81
+ captureOutput?: boolean;
82
+ model?: string;
83
+ maxTurns?: number;
84
+ timeout?: number;
85
+ outputFormat?: string;
86
+ captureStderr?: boolean;
87
+ }
88
+ ) => Promise<{
89
+ exitCode: number;
90
+ stdout?: string;
91
+ stderr?: string;
92
+ timedOut: boolean;
93
+ }>;
94
+ } = require('../autopilot');
95
+ const {
96
+ createEvolveWorktree,
97
+ removeEvolveWorktree,
98
+ pushAndCreatePR,
99
+ }: {
100
+ createEvolveWorktree: (cwd: string) => {
101
+ path: string;
102
+ branch: string;
103
+ baseBranch: string;
104
+ error?: string;
105
+ };
106
+ removeEvolveWorktree: (cwd: string, wtPath: string) => { removed: boolean; error?: string };
107
+ pushAndCreatePR: (
108
+ cwd: string,
109
+ wtPath: string,
110
+ opts?: { base?: string }
111
+ ) => { pr_url?: string; error?: string };
112
+ } = require('../worktree');
113
+ const {
114
+ DEFAULT_PICK_PCT,
115
+ readEvolveState,
116
+ writeEvolveState,
117
+ }: {
118
+ DEFAULT_PICK_PCT: number;
119
+ readEvolveState: (cwd: string) => EvolveGroupState | EvolveState | null;
120
+ writeEvolveState: (cwd: string, state: EvolveGroupState | EvolveState) => void;
121
+ } = require('./state');
122
+ const {
123
+ runGroupDiscovery,
124
+ }: {
125
+ runGroupDiscovery: (
126
+ cwd: string,
127
+ previousState: EvolveGroupState | EvolveState | null,
128
+ pickPct?: number,
129
+ opts?: import('./types').DiscoveryOptions
130
+ ) => Promise<GroupDiscoveryResult>;
131
+ } = require('./discovery');
132
+ const {
133
+ buildBatchExecutePrompt,
134
+ buildBatchReviewPrompt,
135
+ }: {
136
+ buildBatchExecutePrompt: (groups: WorkGroup[], iterationNum?: number) => string;
137
+ buildBatchReviewPrompt: (groups: WorkGroup[]) => string;
138
+ } = require('./_prompts');
139
+ const {
140
+ runAutoplan,
141
+ }: {
142
+ runAutoplan: (cwd: string, options?: AutoplanOptions) => Promise<AutoplanResult>;
143
+ } = require('../autoplan');
144
+ const {
145
+ runMultiMilestoneAutopilot,
146
+ }: {
147
+ runMultiMilestoneAutopilot: (
148
+ cwd: string,
149
+ options?: MultiMilestoneOptions
150
+ ) => Promise<MultiMilestoneResult>;
151
+ } = require('../autopilot');
152
+ const {
153
+ runGenomeSnapshot,
154
+ GenomeSplitIndexError,
155
+ }: {
156
+ runGenomeSnapshot: (cwd: string) => {
157
+ action: 'created' | 'appended';
158
+ snapshot_date: string;
159
+ path: string;
160
+ };
161
+ GenomeSplitIndexError: new (msg: string) => Error;
162
+ } = require('../genome');
163
+ const {
164
+ getEffectiveTierForDispatch,
165
+ }: {
166
+ getEffectiveTierForDispatch: (opts: {
167
+ agentType: string;
168
+ prompt: string;
169
+ config: GrdConfig;
170
+ scheduler: { getStates(): Map<string, import('../types').BackendUsageState> } | null;
171
+ schedulerConfig?: import('../types').SchedulerConfig;
172
+ superpowersConfig?: import('../types').SuperpowersConfig;
173
+ modelProfiles: Record<string, Record<string, string>>;
174
+ }) => import('../types').ModelTier;
175
+ } = require('../backend');
176
+
177
+ // ─── Evolve Loop Helpers ─────────────────────────────────────────────────────
178
+
179
+ /**
180
+ * Run a single iteration step: discover groups, set up worktree if needed,
181
+ * batch-execute, and batch-review.
182
+ */
183
+ async function _runIterationStep(iterCtx: IterationContext): Promise<IterationStepResult> {
184
+ const { state, effectivePickPct, dryRun, timeoutMs, maxTurns, cwd, log, scheduler } = iterCtx;
185
+
186
+ let { useWorktree, worktreeInfo, executionCwd } = iterCtx;
187
+
188
+ // 1. Discover and group (on executionCwd so we see evolved code)
189
+ const discovery: GroupDiscoveryResult = await runGroupDiscovery(
190
+ executionCwd,
191
+ state,
192
+ effectivePickPct,
193
+ { timeoutMs, scheduler }
194
+ );
195
+ log(
196
+ `Discovered ${discovery.all_items_count} new + ${discovery.merged_items_count - discovery.all_items_count} carried-over = ${discovery.merged_items_count} total items, ${discovery.groups_count} groups, selected ${discovery.selected_groups.length}`
197
+ );
198
+
199
+ if (dryRun) {
200
+ return {
201
+ discovery,
202
+ outcomes: [],
203
+ worktreeInfo,
204
+ executionCwd,
205
+ feedback: null,
206
+ useWorktree,
207
+ isDryRun: true,
208
+ };
209
+ }
210
+
211
+ if (discovery.selected_groups.length === 0) {
212
+ return {
213
+ discovery,
214
+ outcomes: null,
215
+ worktreeInfo,
216
+ executionCwd,
217
+ feedback: null,
218
+ useWorktree,
219
+ isDryRun: false,
220
+ };
221
+ }
222
+
223
+ // Create worktree on first non-dry-run iteration if enabled
224
+ if (useWorktree && !worktreeInfo) {
225
+ const wtResult = createEvolveWorktree(cwd);
226
+ if (wtResult.error) {
227
+ log(`Worktree creation failed: ${wtResult.error}. Continuing without isolation.`);
228
+ useWorktree = false;
229
+ } else {
230
+ worktreeInfo = wtResult;
231
+ executionCwd = wtResult.path;
232
+ log(`Created worktree at ${wtResult.path} (branch: ${wtResult.branch})`);
233
+ }
234
+ }
235
+
236
+ // 2. All groups are executable — product-ideation items are real feature work
237
+ const outcomes: GroupOutcome[] = [];
238
+ const allGroups: WorkGroup[] = discovery.selected_groups;
239
+ // Cap items per batch to keep subprocess focused (max 10 items for tight discover→execute cycles)
240
+ const MAX_BATCH_ITEMS: number = 10;
241
+ let cappedGroups: WorkGroup[] = allGroups;
242
+ let totalItems: number = allGroups.reduce((sum, g) => sum + g.items.length, 0);
243
+ if (totalItems > MAX_BATCH_ITEMS) {
244
+ cappedGroups = [];
245
+ let runningTotal: number = 0;
246
+ for (const group of allGroups) {
247
+ if (runningTotal + group.items.length <= MAX_BATCH_ITEMS) {
248
+ cappedGroups.push(group);
249
+ runningTotal += group.items.length;
250
+ } else if (runningTotal === 0) {
251
+ // Always include at least one group, but cap its items
252
+ const cappedItems = group.items.slice(0, MAX_BATCH_ITEMS);
253
+ cappedGroups.push({ ...group, items: cappedItems });
254
+ runningTotal += cappedItems.length;
255
+ break;
256
+ } else {
257
+ break;
258
+ }
259
+ }
260
+ totalItems = runningTotal;
261
+ // Mark excluded groups as skipped so they don't vanish from tracking
262
+ const cappedIds = new Set(cappedGroups.map((g) => g.id));
263
+ for (const group of allGroups) {
264
+ if (!cappedIds.has(group.id)) {
265
+ outcomes.push({
266
+ group: group.id,
267
+ status: 'skip',
268
+ step: 'execute',
269
+ reason: 'batch item cap exceeded',
270
+ });
271
+ }
272
+ }
273
+ log(
274
+ `Capped batch from ${allGroups.reduce((s, g) => s + g.items.length, 0)} to ${totalItems} items (max ${MAX_BATCH_ITEMS}), ${allGroups.length - cappedGroups.length} groups deferred`
275
+ );
276
+ }
277
+ log(`Batch-executing ${cappedGroups.length} groups (${totalItems} items) in one subprocess`);
278
+
279
+ const { autoCommit, iterationNum } = iterCtx;
280
+ const executePrompt: string = buildBatchExecutePrompt(cappedGroups, iterationNum);
281
+ // Resolve the effective model for the executor dispatch. The Spec 4 chain
282
+ // (complexity → budget pressure → tier) picks the right model; SONNET_MODEL
283
+ // remains the baseline if no profile is configured.
284
+ const evolveConfig: GrdConfig = loadConfig(cwd);
285
+ const executeTier = getEffectiveTierForDispatch({
286
+ agentType: 'grd-executor',
287
+ prompt: executePrompt,
288
+ config: evolveConfig,
289
+ scheduler,
290
+ schedulerConfig: evolveConfig.scheduler,
291
+ superpowersConfig: evolveConfig.superpowers,
292
+ modelProfiles: MODEL_PROFILES,
293
+ });
294
+ const executeModel: string = resolveModelForAgent(evolveConfig, 'grd-executor', cwd, {
295
+ effectiveTierOverride: executeTier,
296
+ });
297
+ const execResult = scheduler
298
+ ? await scheduler.spawn(executePrompt, {
299
+ model: executeModel,
300
+ timeout: timeoutMs,
301
+ maxTurns,
302
+ cwd: executionCwd,
303
+ workItemId: `evolve-iter-${iterationNum}-execute`,
304
+ agentType: 'grd-executor',
305
+ })
306
+ : await spawnClaudeAsync(executionCwd, executePrompt, {
307
+ model: executeModel,
308
+ timeout: timeoutMs,
309
+ maxTurns,
310
+ captureStderr: true,
311
+ });
312
+
313
+ let feedback: IterationFeedback | null = null;
314
+
315
+ if (execResult.exitCode !== 0) {
316
+ const reason: string = execResult.timedOut ? 'timeout' : `exit ${execResult.exitCode}`;
317
+ log(`Batch execute FAILED (${reason})`);
318
+ if (execResult.stderr) {
319
+ const stderrTail: string = execResult.stderr.trim().split('\n').slice(-10).join('\n');
320
+ log(`Subprocess stderr (last 10 lines):\n${stderrTail}`);
321
+ }
322
+ for (const group of cappedGroups) {
323
+ outcomes.push({ group: group.id, status: 'fail', step: 'execute', reason });
324
+ }
325
+ } else {
326
+ // Read feedback JSON written by the subprocess
327
+ const feedbackPath: string = path.join(
328
+ executionCwd,
329
+ '.planning',
330
+ `evolve-iteration-${iterationNum}.json`
331
+ );
332
+ try {
333
+ const raw: string = fs.readFileSync(feedbackPath, 'utf-8');
334
+ feedback = JSON.parse(raw) as IterationFeedback;
335
+ fs.unlinkSync(feedbackPath);
336
+ log(
337
+ `Read iteration feedback: ${(feedback.decisions || []).length} decisions, ${(feedback.patterns || []).length} patterns, ${(feedback.takeaways || []).length} takeaways`
338
+ );
339
+ } catch {
340
+ log(`No iteration feedback file found (subprocess may not have written it)`);
341
+ }
342
+
343
+ // Check if the subprocess actually changed source code files (not just markdown/docs)
344
+ const CODE_DIFF_FILTER: string[] = [
345
+ '--',
346
+ '*.ts',
347
+ '*.js',
348
+ '*.tsx',
349
+ '*.jsx',
350
+ '*.py',
351
+ '*.rs',
352
+ '*.go',
353
+ '*.java',
354
+ '*.json',
355
+ ];
356
+ const diffCheck = execGit(executionCwd, ['diff', '--stat', 'HEAD', ...CODE_DIFF_FILTER]);
357
+ const hasStagedChanges = execGit(executionCwd, [
358
+ 'diff',
359
+ '--cached',
360
+ '--stat',
361
+ ...CODE_DIFF_FILTER,
362
+ ]);
363
+ const hasCodeChanges: boolean =
364
+ (diffCheck.stdout || '').trim().length > 0 ||
365
+ (hasStagedChanges.stdout || '').trim().length > 0;
366
+
367
+ if (!hasCodeChanges) {
368
+ // Discard non-code changes (markdown stubs, todo files, etc.)
369
+ // Only revert .planning/ and docs/ — avoid wiping user's uncommitted work
370
+ execGit(executionCwd, ['checkout', '--', '.planning/', 'docs/']);
371
+ execGit(executionCwd, ['clean', '-fd', '--', '.planning/', 'docs/']);
372
+ log(
373
+ `Batch execute completed but NO source code changes were made — discarding markdown-only changes and marking as skip`
374
+ );
375
+ for (const group of cappedGroups) {
376
+ outcomes.push({
377
+ group: group.id,
378
+ status: 'skip',
379
+ step: 'execute',
380
+ reason: 'no source code changes',
381
+ });
382
+ }
383
+ } else {
384
+ log(`Batch execute completed (code changes detected)`);
385
+
386
+ log(`Running single review for all ${cappedGroups.length} groups`);
387
+ const reviewPrompt: string = buildBatchReviewPrompt(cappedGroups);
388
+ // Resolve the effective model for the reviewer dispatch, reusing the
389
+ // already-loaded evolveConfig (Spec 4 chain mirrors the execute dispatch).
390
+ const reviewTier = getEffectiveTierForDispatch({
391
+ agentType: 'grd-verifier',
392
+ prompt: reviewPrompt,
393
+ config: evolveConfig,
394
+ scheduler,
395
+ schedulerConfig: evolveConfig.scheduler,
396
+ superpowersConfig: evolveConfig.superpowers,
397
+ modelProfiles: MODEL_PROFILES,
398
+ });
399
+ const reviewModel: string = resolveModelForAgent(evolveConfig, 'grd-verifier', cwd, {
400
+ effectiveTierOverride: reviewTier,
401
+ });
402
+ const reviewResult = scheduler
403
+ ? await scheduler.spawn(reviewPrompt, {
404
+ model: reviewModel,
405
+ timeout: timeoutMs,
406
+ maxTurns,
407
+ cwd: executionCwd,
408
+ workItemId: `evolve-iter-${iterationNum}-review`,
409
+ agentType: 'grd-verifier',
410
+ })
411
+ : await spawnClaudeAsync(executionCwd, reviewPrompt, {
412
+ model: reviewModel,
413
+ timeout: timeoutMs,
414
+ maxTurns,
415
+ });
416
+
417
+ if (reviewResult.exitCode !== 0) {
418
+ const reason: string = reviewResult.timedOut ? 'timeout' : `exit ${reviewResult.exitCode}`;
419
+ log(`Batch review FAILED (${reason}) — execution changes kept`);
420
+ } else {
421
+ log(`Batch review completed`);
422
+ }
423
+
424
+ for (const group of cappedGroups) {
425
+ outcomes.push({ group: group.id, status: 'pass' });
426
+ }
427
+
428
+ // Auto-commit if enabled
429
+ if (autoCommit) {
430
+ const themes: string = cappedGroups.map((g) => g.theme || g.id).join(', ');
431
+ const commitMsg: string = `evolve(iteration-${iterationNum}): ${themes}`;
432
+ execGit(executionCwd, ['add', '-A']);
433
+ const commitResult = execGit(executionCwd, ['commit', '-m', commitMsg]);
434
+ if (commitResult.exitCode === 0) {
435
+ log(`Auto-committed: ${commitMsg}`);
436
+ } else {
437
+ log(`Auto-commit failed: ${(commitResult.stderr || '').trim()}`);
438
+ }
439
+ }
440
+ }
441
+ }
442
+
443
+ return {
444
+ discovery,
445
+ outcomes,
446
+ worktreeInfo,
447
+ executionCwd,
448
+ useWorktree,
449
+ isDryRun: false,
450
+ feedback,
451
+ };
452
+ }
453
+
454
+ /**
455
+ * Process the result of a single iteration step.
456
+ */
457
+ function _handleIterationResult(
458
+ stepResult: IterationStepResult,
459
+ prevState: EvolveGroupState | null,
460
+ iterNum: number,
461
+ effectivePickPct: number,
462
+ cwd: string
463
+ ): HandleIterationReturn {
464
+ const { discovery, outcomes, feedback } = stepResult;
465
+
466
+ // Write evolution notes (always to original cwd)
467
+ writeEvolutionNotes(cwd, {
468
+ iteration: iterNum,
469
+ items: discovery.selected_groups.flatMap((g) => g.items),
470
+ outcomes: (outcomes || []).flatMap((o) => {
471
+ const group = discovery.selected_groups.find((g) => g.id === o.group);
472
+ if (!group) return [{ item: o.group, status: o.status, step: o.step, reason: o.reason }];
473
+ return group.items.map((it) => ({
474
+ item: it.title,
475
+ status: o.status,
476
+ step: o.step,
477
+ reason: o.reason,
478
+ }));
479
+ }),
480
+ decisions: feedback?.decisions || [],
481
+ patterns: feedback?.patterns || [],
482
+ takeaways: feedback?.takeaways || [],
483
+ });
484
+
485
+ // Compute completed and failed groups
486
+ const milestone: string = prevState ? prevState.milestone : '';
487
+ const newlyCompleted: WorkGroup[] = (outcomes || [])
488
+ .filter((o) => o.status === 'pass')
489
+ .map((o) => discovery.selected_groups.find((g) => g.id === o.group))
490
+ .filter((g): g is WorkGroup => g !== undefined)
491
+ .map((g) => ({ ...g, status: 'completed' }));
492
+ // Accumulate completed groups across iterations (for dedup in future discoveries)
493
+ const prevCompleted: WorkGroup[] = prevState?.completed_groups || [];
494
+ const completedIds = new Set<string>(prevCompleted.map((g) => g.id));
495
+ const completedGroups: WorkGroup[] = [
496
+ ...prevCompleted,
497
+ ...newlyCompleted.filter((g) => !completedIds.has(g.id)),
498
+ ];
499
+ const newlyFailed: WorkGroup[] = (outcomes || [])
500
+ .filter((o) => o.status === 'fail')
501
+ .map((o) => discovery.selected_groups.find((g) => g.id === o.group))
502
+ .filter((g): g is WorkGroup => g !== undefined)
503
+ .map((g) => ({ ...g, status: 'failed' }));
504
+ // Accumulate failed groups across iterations (like completed_groups)
505
+ const prevFailed: WorkGroup[] = prevState?.failed_groups || [];
506
+ const failedIds = new Set<string>(prevFailed.map((g) => g.id));
507
+ const failedGroups: WorkGroup[] = [
508
+ ...prevFailed,
509
+ ...newlyFailed.filter((g) => !failedIds.has(g.id)),
510
+ ];
511
+
512
+ // Build new state
513
+ const historyEntry: HistoryEntry = {
514
+ iteration: iterNum,
515
+ timestamp: new Date().toISOString(),
516
+ selected_count: discovery.selected_groups.length,
517
+ completed_count: newlyCompleted.length,
518
+ failed_count: newlyFailed.length,
519
+ };
520
+ const newState: EvolveGroupState = {
521
+ iteration: iterNum,
522
+ timestamp: new Date().toISOString(),
523
+ milestone,
524
+ pick_pct: effectivePickPct,
525
+ selected_groups: discovery.selected_groups,
526
+ remaining_groups: discovery.remaining_groups,
527
+ completed_groups: completedGroups,
528
+ failed_groups: failedGroups,
529
+ all_items_count: discovery.all_items_count,
530
+ groups_count: discovery.groups_count,
531
+ history: prevState ? [...(prevState.history || []), historyEntry] : [historyEntry],
532
+ };
533
+
534
+ const iterResult: IterationResult = {
535
+ iteration: iterNum,
536
+ status: 'completed',
537
+ groups_attempted: (outcomes || []).length,
538
+ groups_passed: newlyCompleted.length,
539
+ groups_failed: newlyFailed.length,
540
+ remaining_groups: discovery.remaining_groups.length,
541
+ };
542
+
543
+ return { newState, iterResult };
544
+ }
545
+
546
+ // ─── Todos Integration ───────────────────────────────────────────────────────
547
+
548
+ /**
549
+ * Create or append evolution notes to .planning/EVOLUTION.md.
550
+ */
551
+ function writeEvolutionNotes(cwd: string, iterationData: EvolutionNotesData): void {
552
+ const filePath: string = path.join(cwd, '.planning', 'EVOLUTION.md');
553
+ const { iteration, items, outcomes, decisions, patterns, takeaways } = iterationData;
554
+
555
+ // Create file with header if it doesn't exist
556
+ if (!fs.existsSync(filePath)) {
557
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
558
+ fs.writeFileSync(filePath, '# Evolution Notes\n\n');
559
+ }
560
+
561
+ const lines: string[] = [];
562
+ lines.push(`## Iteration ${iteration}`);
563
+ lines.push(`_${new Date().toISOString()}_\n`);
564
+
565
+ // Items Attempted
566
+ lines.push('### Items Attempted\n');
567
+ if (items.length === 0) {
568
+ lines.push('None\n');
569
+ } else {
570
+ for (let i = 0; i < items.length; i++) {
571
+ const item: WorkItem = items[i];
572
+ process.stderr.write(`[evolve] Writing item ${i + 1}/${items.length}: ${item.title}\n`);
573
+ const outcome = outcomes.find((o) => o.item === item.title);
574
+ const status: string = outcome ? outcome.status : 'unknown';
575
+ lines.push(`- **${item.title}** — ${status}`);
576
+ }
577
+ lines.push('');
578
+ }
579
+
580
+ // Decisions Made
581
+ lines.push('### Decisions Made\n');
582
+ if (decisions.length === 0) {
583
+ lines.push('None\n');
584
+ } else {
585
+ for (let i = 0; i < decisions.length; i++) {
586
+ process.stderr.write(`[evolve] Writing decision ${i + 1}/${decisions.length}\n`);
587
+ lines.push(`- ${decisions[i]}`);
588
+ }
589
+ lines.push('');
590
+ }
591
+
592
+ // Patterns Discovered
593
+ lines.push('### Patterns Discovered\n');
594
+ if (patterns.length === 0) {
595
+ lines.push('None\n');
596
+ } else {
597
+ for (let i = 0; i < patterns.length; i++) {
598
+ process.stderr.write(`[evolve] Writing pattern ${i + 1}/${patterns.length}\n`);
599
+ lines.push(`- ${patterns[i]}`);
600
+ }
601
+ lines.push('');
602
+ }
603
+
604
+ // Takeaways
605
+ lines.push('### Takeaways\n');
606
+ if (takeaways.length === 0) {
607
+ lines.push('None\n');
608
+ } else {
609
+ for (let i = 0; i < takeaways.length; i++) {
610
+ process.stderr.write(`[evolve] Writing takeaway ${i + 1}/${takeaways.length}\n`);
611
+ lines.push(`- ${takeaways[i]}`);
612
+ }
613
+ lines.push('');
614
+ }
615
+
616
+ lines.push('---\n');
617
+
618
+ fs.appendFileSync(filePath, lines.join('\n'));
619
+ }
620
+
621
+ // ─── Main Orchestrator ──────────────────────────────────────────────────────
622
+
623
+ /**
624
+ * Main evolve orchestration loop.
625
+ */
626
+ async function runEvolve(cwd: string, options: EvolveOptions = {}): Promise<EvolveResult> {
627
+ const {
628
+ iterations = 1,
629
+ pickPct,
630
+ timeout,
631
+ maxTurns,
632
+ dryRun = false,
633
+ autoCommit = true,
634
+ createPr = true,
635
+ } = options;
636
+ const effectivePickPct: number = pickPct !== undefined ? pickPct : DEFAULT_PICK_PCT;
637
+ const DEFAULT_TIMEOUT_MINUTES: number = 180;
638
+ const timeoutMs: number = timeout ? timeout * 60 * 1000 : DEFAULT_TIMEOUT_MINUTES * 60 * 1000;
639
+ const unlimited: boolean = iterations === 0;
640
+
641
+ // Auto-detect worktree usage from config if not explicitly set
642
+ let useWorktree: boolean = options.useWorktree !== undefined ? options.useWorktree : false;
643
+ const evolveConfig: GrdConfig = loadConfig(cwd);
644
+ if (options.useWorktree === undefined) {
645
+ useWorktree = evolveConfig.branching_strategy !== 'none';
646
+ }
647
+
648
+ const evolveScheduler = createScheduler(evolveConfig.scheduler);
649
+ if (evolveScheduler) {
650
+ evolveScheduler.loadPersistedState(path.join(cwd, '.planning'));
651
+ }
652
+
653
+ // Set up logging (same pattern as autopilot.js)
654
+ const logFile: string = path.join(cwd, '.planning', 'autopilot', 'evolve.log');
655
+ fs.mkdirSync(path.dirname(logFile), { recursive: true });
656
+ const log = (msg: string): void => {
657
+ const line: string = `[${new Date().toISOString()}] ${msg}\n`;
658
+ process.stderr.write(`[evolve] ${msg}\n`);
659
+ fs.appendFileSync(logFile, line);
660
+ };
661
+
662
+ // Discovery runs on executionCwd so it sees evolved code after each iteration.
663
+ // On the first iteration (before worktree exists), this equals cwd.
664
+ let executionCwd: string = cwd;
665
+ let worktreeInfo: WorktreeInfo | null = null;
666
+
667
+ const results: Array<IterationResult | DryRunIterationResult> = [];
668
+ let state: EvolveGroupState | EvolveState | null = readEvolveState(cwd);
669
+ let iterCount: number = 0;
670
+
671
+ while (unlimited || iterCount < iterations) {
672
+ const iterNum: number = state ? state.iteration + 1 : 1;
673
+ log(`Starting iteration ${iterNum}`);
674
+
675
+ const stepResult: IterationStepResult = await _runIterationStep({
676
+ executionCwd,
677
+ state,
678
+ useWorktree,
679
+ worktreeInfo,
680
+ effectivePickPct,
681
+ dryRun,
682
+ timeoutMs,
683
+ maxTurns,
684
+ cwd,
685
+ log,
686
+ autoCommit,
687
+ iterationNum: iterNum,
688
+ scheduler: evolveScheduler,
689
+ });
690
+
691
+ // Propagate mutable worktree state back from the step
692
+ useWorktree = stepResult.useWorktree;
693
+ worktreeInfo = stepResult.worktreeInfo;
694
+ executionCwd = stepResult.executionCwd;
695
+
696
+ if (stepResult.isDryRun) {
697
+ const { discovery } = stepResult;
698
+ const groupsPerIter: number = discovery.selected_groups.length;
699
+ results.push({
700
+ iteration: iterNum,
701
+ status: 'dry-run' as const,
702
+ groups: discovery.groups.map((g) => ({
703
+ id: g.id,
704
+ priority: g.priority,
705
+ item_count: g.items.length,
706
+ effort: g.effort,
707
+ })),
708
+ total_items: discovery.all_items_count,
709
+ total_groups: discovery.groups_count,
710
+ groups_per_iteration: groupsPerIter,
711
+ estimated_iterations:
712
+ groupsPerIter > 0 ? Math.ceil(discovery.groups_count / groupsPerIter) : 0,
713
+ });
714
+ break; // dry-run always exits after one iteration
715
+ }
716
+
717
+ if (stepResult.outcomes === null) {
718
+ log('No groups to process. Done.');
719
+ break;
720
+ }
721
+
722
+ const { newState, iterResult } = _handleIterationResult(
723
+ stepResult,
724
+ state as EvolveGroupState | null,
725
+ iterNum,
726
+ effectivePickPct,
727
+ cwd
728
+ );
729
+
730
+ state = newState;
731
+ writeEvolveState(cwd, state);
732
+ results.push(iterResult);
733
+
734
+ iterCount++;
735
+ }
736
+
737
+ // Post-loop: push + PR + cleanup if worktree was used
738
+ let prInfo: { pr_url?: string; error?: string } | null = null;
739
+ if (worktreeInfo) {
740
+ // Check if there are any commits on the worktree branch
741
+ const logResult = execGit(worktreeInfo.path, [
742
+ 'log',
743
+ `${worktreeInfo.baseBranch}..HEAD`,
744
+ '--oneline',
745
+ ]);
746
+ const hasCommits: boolean = logResult.exitCode === 0 && logResult.stdout.trim().length > 0;
747
+
748
+ if (hasCommits && createPr) {
749
+ log(`Pushing worktree branch and creating PR...`);
750
+ prInfo = pushAndCreatePR(cwd, worktreeInfo.path, {
751
+ base: worktreeInfo.baseBranch,
752
+ });
753
+ if (prInfo.error) {
754
+ log(`PR creation failed: ${prInfo.error}`);
755
+ } else {
756
+ log(`PR created: ${prInfo.pr_url}`);
757
+ }
758
+ } else if (!hasCommits) {
759
+ log('No commits on worktree branch, skipping PR.');
760
+ } else {
761
+ log('PR creation disabled via config.');
762
+ }
763
+
764
+ // Clean up worktree
765
+ const removeResult = removeEvolveWorktree(cwd, worktreeInfo.path);
766
+ log(`Worktree cleanup: ${removeResult.removed ? 'removed' : 'failed'}`);
767
+ }
768
+
769
+ log(`Done: ${results.length} iteration(s) completed`);
770
+
771
+ if (evolveScheduler) {
772
+ evolveScheduler.persistState(path.join(cwd, '.planning'));
773
+ }
774
+
775
+ const returnValue: EvolveResult = {
776
+ iterations_completed: results.length,
777
+ results,
778
+ evolution_notes_path: path.join('.planning', 'EVOLUTION.md'),
779
+ };
780
+ if (worktreeInfo) {
781
+ returnValue.worktree = { path: worktreeInfo.path, branch: worktreeInfo.branch };
782
+ }
783
+ if (prInfo && !prInfo.error) {
784
+ returnValue.pr = prInfo;
785
+ }
786
+ return returnValue;
787
+ }
788
+
789
+ /**
790
+ * Write discovered groups as todo files into .planning/milestones/anonymous/todos/pending/.
791
+ */
792
+ function writeDiscoveriesToTodos(cwd: string, groups: WorkGroup[]): number {
793
+ if (!groups || groups.length === 0) return 0;
794
+
795
+ const pendingDir: string = path.join(
796
+ cwd,
797
+ '.planning',
798
+ 'milestones',
799
+ 'anonymous',
800
+ 'todos',
801
+ 'pending'
802
+ );
803
+ fs.mkdirSync(pendingDir, { recursive: true });
804
+
805
+ // Get existing files to support idempotency
806
+ let existingFiles: Set<string>;
807
+ try {
808
+ existingFiles = new Set(fs.readdirSync(pendingDir) as string[]);
809
+ } catch {
810
+ existingFiles = new Set();
811
+ }
812
+
813
+ let created: number = 0;
814
+ const now: string = new Date().toISOString();
815
+
816
+ for (const group of groups) {
817
+ // Derive a stable filename from the group id (replace / with -)
818
+ const idSlug: string = group.id.replace(/\//g, '-').replace(/[^a-z0-9-]/gi, '-');
819
+ const filename: string = `evolve-${idSlug}.md`;
820
+
821
+ if (existingFiles.has(filename)) {
822
+ continue; // Already exists — skip
823
+ }
824
+
825
+ const itemCount: number = Array.isArray(group.items) ? group.items.length : 0;
826
+ const itemList: string = Array.isArray(group.items)
827
+ ? group.items.map((i) => `- **${i.title}**: ${i.description}`).join('\n')
828
+ : '';
829
+
830
+ const content: string = [
831
+ '---',
832
+ `title: "${group.theme || group.id}"`,
833
+ `created: "${now}"`,
834
+ `area: "${group.dimension || 'unknown'}"`,
835
+ `source: evolve-discovery`,
836
+ '---',
837
+ '',
838
+ `## ${group.theme || group.id}`,
839
+ '',
840
+ `**${itemCount} item${itemCount !== 1 ? 's' : ''}** discovered by evolve loop.`,
841
+ '',
842
+ itemList,
843
+ ].join('\n');
844
+
845
+ fs.writeFileSync(path.join(pendingDir, filename), content + '\n');
846
+ existingFiles.add(filename);
847
+ created++;
848
+ }
849
+
850
+ return created;
851
+ }
852
+
853
+ // ─── Infinite Evolve Loop ────────────────────────────────────────────────────
854
+
855
+ /**
856
+ * Run the infinite evolve loop: discover -> autoplan -> autopilot -> repeat.
857
+ *
858
+ * Each cycle:
859
+ * 1. Discover improvements via evolve's discovery engine
860
+ * 2. Create a milestone from discoveries via autoplan
861
+ * 3. Execute all phases in that milestone via autopilot
862
+ * 4. Repeat until maxCycles reached, time budget exhausted, or no discoveries remain
863
+ *
864
+ * Safety: maxCycles cap (default 10), optional timeBudget, dry-run preview.
865
+ */
866
+ async function runInfiniteEvolve(
867
+ cwd: string,
868
+ options: InfiniteEvolveOptions = {}
869
+ ): Promise<InfiniteEvolveResult> {
870
+ const maxCycles: number = options.maxCycles ?? 10;
871
+ const timeBudget: number = options.timeBudget ?? 0; // 0 = unlimited
872
+ const effectivePickPct: number = options.pickPct ?? DEFAULT_PICK_PCT;
873
+ const dryRun: boolean = options.dryRun ?? false;
874
+ const maxTurns: number | undefined = options.maxTurns;
875
+ const model: string | undefined = options.model;
876
+ const maxMilestones: number = options.maxMilestones ?? 1;
877
+
878
+ // Set up logging
879
+ const logFile: string = path.join(cwd, '.planning', 'autopilot', 'infinite-evolve.log');
880
+ fs.mkdirSync(path.dirname(logFile), { recursive: true });
881
+ const log = (msg: string): void => {
882
+ const line: string = `[${new Date().toISOString()}] ${msg}\n`;
883
+ process.stderr.write(`[infinite-evolve] ${msg}\n`);
884
+ fs.appendFileSync(logFile, line);
885
+ };
886
+
887
+ const startTime: number = Date.now();
888
+ const cycleResults: InfiniteEvolveCycleResult[] = [];
889
+ let totalGroupsDiscovered: number = 0;
890
+ let totalItemsDiscovered: number = 0;
891
+ let stoppedAt: string | null = null;
892
+ // Cached once per evolve invocation; auto_genome_snapshot is opt-in
893
+ // and read inside the cycle loop below (Tier-2 #8 follow-up).
894
+ const evolveConfig: GrdConfig = loadConfig(cwd);
895
+
896
+ log(
897
+ `Starting infinite evolve loop: maxCycles=${maxCycles}, timeBudget=${timeBudget}min, pickPct=${effectivePickPct}, dryRun=${dryRun}`
898
+ );
899
+
900
+ for (let cycle = 0; cycle < maxCycles; cycle++) {
901
+ // Check time budget
902
+ if (timeBudget > 0) {
903
+ const elapsedMs: number = Date.now() - startTime;
904
+ if (elapsedMs > timeBudget * 60 * 1000) {
905
+ stoppedAt = `Time budget exhausted (${Math.round(elapsedMs / 60000)}min of ${timeBudget}min)`;
906
+ log(stoppedAt);
907
+ break;
908
+ }
909
+ }
910
+
911
+ log(`=== Cycle ${cycle + 1}/${maxCycles} ===`);
912
+
913
+ // Step 1: Discovery
914
+ log('Step 1: Running discovery...');
915
+ const state: EvolveGroupState | EvolveState | null = readEvolveState(cwd);
916
+ let discovery: GroupDiscoveryResult;
917
+ try {
918
+ const infiniteTimeoutMs: number | undefined = options.timeout
919
+ ? options.timeout * 60 * 1000
920
+ : undefined;
921
+ discovery = await runGroupDiscovery(cwd, state, effectivePickPct, {
922
+ timeoutMs: infiniteTimeoutMs,
923
+ });
924
+ } catch (err) {
925
+ const reason: string = `Discovery failed: ${(err as Error).message}`;
926
+ log(reason);
927
+ cycleResults.push({
928
+ cycle: cycle + 1,
929
+ discovery_groups: 0,
930
+ discovery_items: 0,
931
+ autoplan_status: 'skipped',
932
+ autopilot_status: 'skipped',
933
+ reason,
934
+ });
935
+ stoppedAt = reason;
936
+ break;
937
+ }
938
+
939
+ const groupCount: number = discovery.selected_groups.length;
940
+ const itemCount: number = discovery.selected_groups.reduce((sum, g) => sum + g.items.length, 0);
941
+ totalGroupsDiscovered += groupCount;
942
+ totalItemsDiscovered += itemCount;
943
+ log(`Discovered ${groupCount} groups (${itemCount} items)`);
944
+
945
+ if (groupCount === 0) {
946
+ stoppedAt = 'No improvements discovered';
947
+ log(stoppedAt);
948
+ cycleResults.push({
949
+ cycle: cycle + 1,
950
+ discovery_groups: 0,
951
+ discovery_items: 0,
952
+ autoplan_status: 'skipped',
953
+ autopilot_status: 'skipped',
954
+ reason: stoppedAt,
955
+ });
956
+ break;
957
+ }
958
+
959
+ if (dryRun) {
960
+ log(`[DRY RUN] Would create milestone from ${groupCount} groups (${itemCount} items)`);
961
+ cycleResults.push({
962
+ cycle: cycle + 1,
963
+ discovery_groups: groupCount,
964
+ discovery_items: itemCount,
965
+ autoplan_status: 'dry-run',
966
+ autopilot_status: 'dry-run',
967
+ });
968
+ // Dry run exits after one cycle to show what would happen
969
+ break;
970
+ }
971
+
972
+ // Step 2: Autoplan -- create milestone from discoveries
973
+ log('Step 2: Running autoplan...');
974
+ const autoplanGroups: AutoplanOptions['groups'] = discovery.selected_groups.map((g) => ({
975
+ id: g.id,
976
+ theme: g.theme,
977
+ dimension: g.dimension,
978
+ items: g.items.map((item) => ({
979
+ title: item.title,
980
+ description: item.description,
981
+ effort: item.effort,
982
+ })),
983
+ priority: g.priority,
984
+ effort: g.effort,
985
+ }));
986
+
987
+ let autoplanResult: AutoplanResult;
988
+ try {
989
+ autoplanResult = await runAutoplan(cwd, {
990
+ groups: autoplanGroups,
991
+ dryRun: false,
992
+ timeout: options.timeout,
993
+ maxTurns,
994
+ model,
995
+ });
996
+ } catch (err) {
997
+ const reason: string = `Autoplan failed: ${(err as Error).message}`;
998
+ log(reason);
999
+ cycleResults.push({
1000
+ cycle: cycle + 1,
1001
+ discovery_groups: groupCount,
1002
+ discovery_items: itemCount,
1003
+ autoplan_status: 'failed',
1004
+ autopilot_status: 'skipped',
1005
+ reason,
1006
+ });
1007
+ continue; // Try next cycle
1008
+ }
1009
+
1010
+ if (autoplanResult.status === 'failed') {
1011
+ const reason: string = `Autoplan failed: ${autoplanResult.reason || 'unknown'}`;
1012
+ log(reason);
1013
+ cycleResults.push({
1014
+ cycle: cycle + 1,
1015
+ discovery_groups: groupCount,
1016
+ discovery_items: itemCount,
1017
+ autoplan_status: 'failed',
1018
+ autopilot_status: 'skipped',
1019
+ reason,
1020
+ });
1021
+ continue; // Try next cycle
1022
+ }
1023
+
1024
+ log(
1025
+ `Autoplan completed: milestone "${autoplanResult.milestone_name}" (${autoplanResult.groups_count} groups, ${autoplanResult.items_count} items)`
1026
+ );
1027
+
1028
+ // Step 3: Autopilot -- execute newly created milestone phases
1029
+ log('Step 3: Running multi-milestone autopilot...');
1030
+ let autopilotResult: MultiMilestoneResult;
1031
+ try {
1032
+ autopilotResult = await runMultiMilestoneAutopilot(cwd, {
1033
+ dryRun: false,
1034
+ timeout: options.timeout,
1035
+ maxTurns,
1036
+ model,
1037
+ maxMilestones,
1038
+ });
1039
+ } catch (err) {
1040
+ const reason: string = `Autopilot failed: ${(err as Error).message}`;
1041
+ log(reason);
1042
+ cycleResults.push({
1043
+ cycle: cycle + 1,
1044
+ discovery_groups: groupCount,
1045
+ discovery_items: itemCount,
1046
+ autoplan_status: 'completed',
1047
+ autopilot_status: 'failed',
1048
+ reason,
1049
+ });
1050
+ continue; // Try next cycle
1051
+ }
1052
+
1053
+ // codex r4 P2 on PR #40 (Tier-3 #10): multi-milestone autopilot now
1054
+ // exposes `converged_at` for graceful convergence. Map convergence
1055
+ // to a distinct 'converged' status so evolve does not classify it
1056
+ // as a failed run.
1057
+ const autopilotStatus: string = autopilotResult.stopped_at
1058
+ ? 'failed'
1059
+ : autopilotResult.converged_at
1060
+ ? 'converged'
1061
+ : 'completed';
1062
+ if (autopilotResult.stopped_at) {
1063
+ log(
1064
+ `Autopilot stopped: ${autopilotResult.stopped_at} (${autopilotResult.milestones_completed}/${autopilotResult.milestones_attempted} milestones)`
1065
+ );
1066
+ } else if (autopilotResult.converged_at) {
1067
+ log(
1068
+ `Autopilot converged early: ${autopilotResult.converged_at} (${autopilotResult.milestones_completed}/${autopilotResult.milestones_attempted} milestones)`
1069
+ );
1070
+ } else {
1071
+ log(
1072
+ `Autopilot completed: ${autopilotResult.milestones_completed} milestones, ${autopilotResult.total_phases_completed} phases`
1073
+ );
1074
+ }
1075
+
1076
+ cycleResults.push({
1077
+ cycle: cycle + 1,
1078
+ discovery_groups: groupCount,
1079
+ discovery_items: itemCount,
1080
+ autoplan_status: 'completed',
1081
+ autopilot_status: autopilotStatus,
1082
+ reason: autopilotResult.stopped_at ?? autopilotResult.converged_at ?? undefined,
1083
+ });
1084
+
1085
+ // Tier-2 #8 auto-genome follow-up: append a deterministic snapshot
1086
+ // to .planning/GENOME.md at the end of each successful cycle, if
1087
+ // the user opted in via config.evolve.auto_genome_snapshot. Append-
1088
+ // only; split-index files are surfaced via warning and skipped.
1089
+ if (
1090
+ evolveConfig.evolve?.auto_genome_snapshot === true &&
1091
+ (autopilotStatus === 'completed' || autopilotStatus === 'converged')
1092
+ ) {
1093
+ try {
1094
+ const snap = runGenomeSnapshot(cwd);
1095
+ log(`Genome snapshot ${snap.action} for cycle ${cycle + 1}: ${snap.path}`);
1096
+ } catch (err) {
1097
+ if (err instanceof GenomeSplitIndexError) {
1098
+ log(`Genome snapshot skipped (split-index): ${err.message}`);
1099
+ } else {
1100
+ log(`Genome snapshot failed (non-blocking): ${String(err)}`);
1101
+ }
1102
+ }
1103
+ }
1104
+ }
1105
+
1106
+ // Summary — codex r5 P2 on PR #40: a graceful 'converged' cycle is
1107
+ // SUCCESSFUL (the autopilot intentionally stopped early because the
1108
+ // project's ontology stabilised). Count it toward cycles_completed
1109
+ // alongside 'completed'. Failure / skipped / dry-run are still excluded.
1110
+ const cyclesCompleted: number = cycleResults.filter(
1111
+ (c) =>
1112
+ c.autoplan_status === 'completed' &&
1113
+ (c.autopilot_status === 'completed' || c.autopilot_status === 'converged')
1114
+ ).length;
1115
+
1116
+ log(
1117
+ `Infinite evolve done: ${cyclesCompleted}/${cycleResults.length} cycles completed, ${totalGroupsDiscovered} groups, ${totalItemsDiscovered} items`
1118
+ );
1119
+
1120
+ return {
1121
+ cycles_completed: cyclesCompleted,
1122
+ cycles_attempted: cycleResults.length,
1123
+ stopped_at: stoppedAt,
1124
+ cycle_results: cycleResults,
1125
+ total_groups_discovered: totalGroupsDiscovered,
1126
+ total_items_discovered: totalItemsDiscovered,
1127
+ };
1128
+ }
1129
+
1130
+ // ─── Exports ────────────────────────────────────────────────────────────────
1131
+
1132
+ module.exports = {
1133
+ _runIterationStep,
1134
+ _handleIterationResult,
1135
+ writeEvolutionNotes,
1136
+ writeDiscoveriesToTodos,
1137
+ runEvolve,
1138
+ runInfiniteEvolve,
1139
+ };