@therocketcode/gsd-core 1.4.0

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 (568) hide show
  1. package/.claude-plugin/plugin.json +23 -0
  2. package/GEMINI.md +53 -0
  3. package/LICENSE +21 -0
  4. package/README.ja-JP.md +125 -0
  5. package/README.ko-KR.md +125 -0
  6. package/README.md +144 -0
  7. package/README.pt-BR.md +125 -0
  8. package/README.zh-CN.md +125 -0
  9. package/agents/gsd-advisor-researcher.md +108 -0
  10. package/agents/gsd-ai-researcher.md +114 -0
  11. package/agents/gsd-assumptions-analyzer.md +105 -0
  12. package/agents/gsd-code-fixer.md +668 -0
  13. package/agents/gsd-code-reviewer.md +387 -0
  14. package/agents/gsd-codebase-mapper.md +853 -0
  15. package/agents/gsd-debug-session-manager.md +314 -0
  16. package/agents/gsd-debugger.md +1452 -0
  17. package/agents/gsd-doc-classifier.md +168 -0
  18. package/agents/gsd-doc-synthesizer.md +204 -0
  19. package/agents/gsd-doc-verifier.md +217 -0
  20. package/agents/gsd-doc-writer.md +616 -0
  21. package/agents/gsd-domain-researcher.md +147 -0
  22. package/agents/gsd-eval-auditor.md +191 -0
  23. package/agents/gsd-eval-planner.md +154 -0
  24. package/agents/gsd-executor.md +785 -0
  25. package/agents/gsd-framework-selector.md +160 -0
  26. package/agents/gsd-integration-checker.md +470 -0
  27. package/agents/gsd-intel-updater.md +342 -0
  28. package/agents/gsd-nyquist-auditor.md +203 -0
  29. package/agents/gsd-pattern-mapper.md +335 -0
  30. package/agents/gsd-phase-researcher.md +867 -0
  31. package/agents/gsd-plan-checker.md +978 -0
  32. package/agents/gsd-planner.md +1204 -0
  33. package/agents/gsd-project-researcher.md +611 -0
  34. package/agents/gsd-research-synthesizer.md +259 -0
  35. package/agents/gsd-roadmapper.md +688 -0
  36. package/agents/gsd-security-auditor.md +155 -0
  37. package/agents/gsd-ui-auditor.md +495 -0
  38. package/agents/gsd-ui-checker.md +309 -0
  39. package/agents/gsd-ui-researcher.md +374 -0
  40. package/agents/gsd-user-profiler.md +171 -0
  41. package/agents/gsd-verifier.md +923 -0
  42. package/assets/gsd-logo-2000-transparent.png +0 -0
  43. package/assets/gsd-logo-2000-transparent.svg +17 -0
  44. package/assets/gsd-logo-2000.png +0 -0
  45. package/assets/gsd-logo-2000.svg +21 -0
  46. package/assets/terminal.svg +68 -0
  47. package/bin/install.js +12726 -0
  48. package/bin/lib/ui-safety-gate.cjs +107 -0
  49. package/commands/gsd/add-tests.md +42 -0
  50. package/commands/gsd/ai-integration-phase.md +37 -0
  51. package/commands/gsd/audit-fix.md +34 -0
  52. package/commands/gsd/audit-milestone.md +37 -0
  53. package/commands/gsd/audit-uat.md +24 -0
  54. package/commands/gsd/autonomous.md +48 -0
  55. package/commands/gsd/capture.md +62 -0
  56. package/commands/gsd/cleanup.md +24 -0
  57. package/commands/gsd/code-review.md +59 -0
  58. package/commands/gsd/complete-milestone.md +143 -0
  59. package/commands/gsd/config.md +56 -0
  60. package/commands/gsd/debug.md +52 -0
  61. package/commands/gsd/discover-product.md +65 -0
  62. package/commands/gsd/discuss-phase.md +77 -0
  63. package/commands/gsd/docs-update.md +49 -0
  64. package/commands/gsd/eval-review.md +33 -0
  65. package/commands/gsd/execute-phase.md +66 -0
  66. package/commands/gsd/explore.md +27 -0
  67. package/commands/gsd/extract-learnings.md +23 -0
  68. package/commands/gsd/fast.md +31 -0
  69. package/commands/gsd/forensics.md +57 -0
  70. package/commands/gsd/graphify.md +204 -0
  71. package/commands/gsd/health.md +31 -0
  72. package/commands/gsd/help.md +28 -0
  73. package/commands/gsd/import.md +45 -0
  74. package/commands/gsd/inbox.md +39 -0
  75. package/commands/gsd/ingest-docs.md +42 -0
  76. package/commands/gsd/manager.md +45 -0
  77. package/commands/gsd/map-codebase.md +83 -0
  78. package/commands/gsd/milestone-summary.md +51 -0
  79. package/commands/gsd/model-domain.md +65 -0
  80. package/commands/gsd/mvp-phase.md +45 -0
  81. package/commands/gsd/new-milestone.md +45 -0
  82. package/commands/gsd/new-project.md +47 -0
  83. package/commands/gsd/ns-context.md +23 -0
  84. package/commands/gsd/ns-ideate.md +24 -0
  85. package/commands/gsd/ns-manage.md +29 -0
  86. package/commands/gsd/ns-project.md +22 -0
  87. package/commands/gsd/ns-review.md +26 -0
  88. package/commands/gsd/ns-workflow.md +28 -0
  89. package/commands/gsd/pause-work.md +43 -0
  90. package/commands/gsd/phase.md +56 -0
  91. package/commands/gsd/plan-phase.md +64 -0
  92. package/commands/gsd/plan-review-convergence.md +59 -0
  93. package/commands/gsd/pr-branch.md +26 -0
  94. package/commands/gsd/profile-user.md +46 -0
  95. package/commands/gsd/progress.md +48 -0
  96. package/commands/gsd/quick.md +174 -0
  97. package/commands/gsd/recommend-architecture.md +64 -0
  98. package/commands/gsd/resume-work.md +30 -0
  99. package/commands/gsd/review-backlog.md +63 -0
  100. package/commands/gsd/review.md +42 -0
  101. package/commands/gsd/secure-phase.md +36 -0
  102. package/commands/gsd/settings.md +29 -0
  103. package/commands/gsd/ship.md +24 -0
  104. package/commands/gsd/sketch.md +60 -0
  105. package/commands/gsd/spec-phase.md +63 -0
  106. package/commands/gsd/spike.md +57 -0
  107. package/commands/gsd/stats.md +20 -0
  108. package/commands/gsd/surface.md +155 -0
  109. package/commands/gsd/testing-strategy.md +65 -0
  110. package/commands/gsd/thread.md +24 -0
  111. package/commands/gsd/ui-phase.md +35 -0
  112. package/commands/gsd/ui-review.md +33 -0
  113. package/commands/gsd/ultraplan-phase.md +34 -0
  114. package/commands/gsd/undo.md +35 -0
  115. package/commands/gsd/update.md +49 -0
  116. package/commands/gsd/validate-phase.md +36 -0
  117. package/commands/gsd/verify-work.md +39 -0
  118. package/commands/gsd/workspace.md +52 -0
  119. package/commands/gsd/workstreams.md +70 -0
  120. package/gemini-extension.json +6 -0
  121. package/gsd-core/bin/check-latest-version.cjs +161 -0
  122. package/gsd-core/bin/gsd-tools.cjs +1928 -0
  123. package/gsd-core/bin/lib/active-workstream-store.cjs +291 -0
  124. package/gsd-core/bin/lib/adr-parser.cjs +399 -0
  125. package/gsd-core/bin/lib/agent-command-router.cjs +68 -0
  126. package/gsd-core/bin/lib/artifacts.cjs +51 -0
  127. package/gsd-core/bin/lib/audit.cjs +743 -0
  128. package/gsd-core/bin/lib/check-command-router.cjs +343 -0
  129. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
  130. package/gsd-core/bin/lib/cli-exit.cjs +42 -0
  131. package/gsd-core/bin/lib/clock.cjs +95 -0
  132. package/gsd-core/bin/lib/clusters.cjs +132 -0
  133. package/gsd-core/bin/lib/code-review-flags.cjs +59 -0
  134. package/gsd-core/bin/lib/command-aliases.cjs +809 -0
  135. package/gsd-core/bin/lib/command-arg-projection.cjs +55 -0
  136. package/gsd-core/bin/lib/command-routing-hub.cjs +300 -0
  137. package/gsd-core/bin/lib/commands.cjs +1203 -0
  138. package/gsd-core/bin/lib/config-schema.cjs +29 -0
  139. package/gsd-core/bin/lib/config-types.cjs +19 -0
  140. package/gsd-core/bin/lib/config.cjs +738 -0
  141. package/gsd-core/bin/lib/configuration.cjs +239 -0
  142. package/gsd-core/bin/lib/context-utilization.cjs +48 -0
  143. package/gsd-core/bin/lib/core.cjs +2051 -0
  144. package/gsd-core/bin/lib/decisions.cjs +118 -0
  145. package/gsd-core/bin/lib/docs.cjs +252 -0
  146. package/gsd-core/bin/lib/drift.cjs +364 -0
  147. package/gsd-core/bin/lib/fallow-runner.cjs +115 -0
  148. package/gsd-core/bin/lib/frontmatter.cjs +442 -0
  149. package/gsd-core/bin/lib/gap-checker.cjs +257 -0
  150. package/gsd-core/bin/lib/graphify.cjs +496 -0
  151. package/gsd-core/bin/lib/gsd2-import.cjs +456 -0
  152. package/gsd-core/bin/lib/init-command-router.cjs +62 -0
  153. package/gsd-core/bin/lib/init.cjs +1815 -0
  154. package/gsd-core/bin/lib/install-profiles.cjs +584 -0
  155. package/gsd-core/bin/lib/installer-migration-authoring.cjs +122 -0
  156. package/gsd-core/bin/lib/installer-migration-report.cjs +350 -0
  157. package/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +218 -0
  158. package/gsd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
  159. package/gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
  160. package/gsd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
  161. package/gsd-core/bin/lib/installer-migrations.cjs +823 -0
  162. package/gsd-core/bin/lib/intel.cjs +590 -0
  163. package/gsd-core/bin/lib/learnings.cjs +270 -0
  164. package/gsd-core/bin/lib/legacy-cleanup.cjs +253 -0
  165. package/gsd-core/bin/lib/milestone.cjs +373 -0
  166. package/gsd-core/bin/lib/model-catalog.cjs +154 -0
  167. package/gsd-core/bin/lib/model-profiles.cjs +24 -0
  168. package/gsd-core/bin/lib/observability/event.cjs +51 -0
  169. package/gsd-core/bin/lib/observability/logger.cjs +146 -0
  170. package/gsd-core/bin/lib/observability/redaction.cjs +48 -0
  171. package/gsd-core/bin/lib/package-identity.cjs +35 -0
  172. package/gsd-core/bin/lib/package-legitimacy.cjs +368 -0
  173. package/gsd-core/bin/lib/phase-command-router.cjs +189 -0
  174. package/gsd-core/bin/lib/phase-lifecycle.cjs +74 -0
  175. package/gsd-core/bin/lib/phase.cjs +1307 -0
  176. package/gsd-core/bin/lib/phases-command-router.cjs +43 -0
  177. package/gsd-core/bin/lib/plan-scan.cjs +91 -0
  178. package/gsd-core/bin/lib/planning-workspace.cjs +245 -0
  179. package/gsd-core/bin/lib/profile-output.cjs +1120 -0
  180. package/gsd-core/bin/lib/profile-pipeline.cjs +517 -0
  181. package/gsd-core/bin/lib/project-root.cjs +119 -0
  182. package/gsd-core/bin/lib/prompt-budget.cjs +305 -0
  183. package/gsd-core/bin/lib/research-provider.cjs +137 -0
  184. package/gsd-core/bin/lib/research-store.cjs +167 -0
  185. package/gsd-core/bin/lib/review-reviewer-selection.cjs +121 -0
  186. package/gsd-core/bin/lib/roadmap-command-router.cjs +166 -0
  187. package/gsd-core/bin/lib/roadmap-upgrade.cjs +476 -0
  188. package/gsd-core/bin/lib/roadmap.cjs +600 -0
  189. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +312 -0
  190. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +56 -0
  191. package/gsd-core/bin/lib/runtime-homes.cjs +190 -0
  192. package/gsd-core/bin/lib/runtime-name-policy.cjs +96 -0
  193. package/gsd-core/bin/lib/runtime-slash.cjs +119 -0
  194. package/gsd-core/bin/lib/schema-detect.cjs +159 -0
  195. package/gsd-core/bin/lib/secrets.cjs +34 -0
  196. package/gsd-core/bin/lib/security.cjs +480 -0
  197. package/gsd-core/bin/lib/semver-compare.cjs +42 -0
  198. package/gsd-core/bin/lib/shell-command-projection.cjs +533 -0
  199. package/gsd-core/bin/lib/state-command-router.cjs +160 -0
  200. package/gsd-core/bin/lib/state-document.cjs +259 -0
  201. package/gsd-core/bin/lib/state.cjs +2010 -0
  202. package/gsd-core/bin/lib/surface.cjs +449 -0
  203. package/gsd-core/bin/lib/task-command-router.cjs +85 -0
  204. package/gsd-core/bin/lib/template.cjs +237 -0
  205. package/gsd-core/bin/lib/uat.cjs +297 -0
  206. package/gsd-core/bin/lib/ui-safety-gate.cjs +98 -0
  207. package/gsd-core/bin/lib/update-context.cjs +218 -0
  208. package/gsd-core/bin/lib/validate-command-router.cjs +91 -0
  209. package/gsd-core/bin/lib/validate.cjs +112 -0
  210. package/gsd-core/bin/lib/verification-command-router.cjs +31 -0
  211. package/gsd-core/bin/lib/verification.cjs +193 -0
  212. package/gsd-core/bin/lib/verify-command-router.cjs +44 -0
  213. package/gsd-core/bin/lib/verify.cjs +1451 -0
  214. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +81 -0
  215. package/gsd-core/bin/lib/workstream-inventory.cjs +147 -0
  216. package/gsd-core/bin/lib/workstream-name-policy.cjs +91 -0
  217. package/gsd-core/bin/lib/workstream.cjs +380 -0
  218. package/gsd-core/bin/lib/worktree-base-ref.cjs +325 -0
  219. package/gsd-core/bin/lib/worktree-safety.cjs +943 -0
  220. package/gsd-core/bin/shared/config-defaults.manifest.json +98 -0
  221. package/gsd-core/bin/shared/config-schema.manifest.json +192 -0
  222. package/gsd-core/bin/shared/model-catalog.json +149 -0
  223. package/gsd-core/bin/shared/runtime-aliases.manifest.json +75 -0
  224. package/gsd-core/bin/verify-reapply-patches.cjs +349 -0
  225. package/gsd-core/contexts/dev.md +21 -0
  226. package/gsd-core/contexts/research.md +22 -0
  227. package/gsd-core/contexts/review.md +23 -0
  228. package/gsd-core/references/agent-contracts.md +79 -0
  229. package/gsd-core/references/ai-evals.md +156 -0
  230. package/gsd-core/references/ai-frameworks.md +186 -0
  231. package/gsd-core/references/architecture-decision.md +74 -0
  232. package/gsd-core/references/artifact-types.md +131 -0
  233. package/gsd-core/references/auth-in-tests.md +91 -0
  234. package/gsd-core/references/autonomous-smart-discuss.md +277 -0
  235. package/gsd-core/references/checkpoints.md +814 -0
  236. package/gsd-core/references/common-bug-patterns.md +114 -0
  237. package/gsd-core/references/context-budget.md +85 -0
  238. package/gsd-core/references/continuation-format.md +253 -0
  239. package/gsd-core/references/db-test-isolation.md +54 -0
  240. package/gsd-core/references/debugger-philosophy.md +76 -0
  241. package/gsd-core/references/decimal-phase-calculation.md +64 -0
  242. package/gsd-core/references/doc-conflict-engine.md +91 -0
  243. package/gsd-core/references/domain-modeling.md +80 -0
  244. package/gsd-core/references/domain-probes.md +125 -0
  245. package/gsd-core/references/e2e-tiering.md +35 -0
  246. package/gsd-core/references/execute-mvp-tdd.md +81 -0
  247. package/gsd-core/references/executor-examples.md +110 -0
  248. package/gsd-core/references/few-shot-examples/plan-checker.md +73 -0
  249. package/gsd-core/references/few-shot-examples/verifier.md +109 -0
  250. package/gsd-core/references/flaky-test-checklist.md +22 -0
  251. package/gsd-core/references/gate-prompts.md +100 -0
  252. package/gsd-core/references/gates.md +70 -0
  253. package/gsd-core/references/git-integration.md +298 -0
  254. package/gsd-core/references/git-planning-commit.md +40 -0
  255. package/gsd-core/references/ios-scaffold.md +123 -0
  256. package/gsd-core/references/mandatory-initial-read.md +2 -0
  257. package/gsd-core/references/model-profile-resolution.md +38 -0
  258. package/gsd-core/references/model-profiles.md +245 -0
  259. package/gsd-core/references/mvp-concepts.md +49 -0
  260. package/gsd-core/references/phase-argument-parsing.md +61 -0
  261. package/gsd-core/references/planner-antipatterns.md +89 -0
  262. package/gsd-core/references/planner-chunked.md +49 -0
  263. package/gsd-core/references/planner-gap-closure.md +62 -0
  264. package/gsd-core/references/planner-graphify-auto-update.md +67 -0
  265. package/gsd-core/references/planner-human-verify-mode.md +57 -0
  266. package/gsd-core/references/planner-interface-context.md +62 -0
  267. package/gsd-core/references/planner-load-graph-context.md +36 -0
  268. package/gsd-core/references/planner-mvp-mode.md +53 -0
  269. package/gsd-core/references/planner-reviews.md +39 -0
  270. package/gsd-core/references/planner-revision.md +87 -0
  271. package/gsd-core/references/planner-source-audit.md +73 -0
  272. package/gsd-core/references/planning-config.md +473 -0
  273. package/gsd-core/references/product-discovery.md +49 -0
  274. package/gsd-core/references/project-skills-discovery.md +19 -0
  275. package/gsd-core/references/questioning.md +162 -0
  276. package/gsd-core/references/realistic-test-data.md +44 -0
  277. package/gsd-core/references/research-documentation-lookup.md +29 -0
  278. package/gsd-core/references/research-philosophy.md +29 -0
  279. package/gsd-core/references/research-verification-protocol.md +27 -0
  280. package/gsd-core/references/revision-loop.md +97 -0
  281. package/gsd-core/references/scout-codebase.md +51 -0
  282. package/gsd-core/references/skeleton-template.md +48 -0
  283. package/gsd-core/references/sketch-interactivity.md +41 -0
  284. package/gsd-core/references/sketch-theme-system.md +94 -0
  285. package/gsd-core/references/sketch-tooling.md +45 -0
  286. package/gsd-core/references/sketch-variant-patterns.md +81 -0
  287. package/gsd-core/references/spidr-splitting.md +69 -0
  288. package/gsd-core/references/tdd.md +330 -0
  289. package/gsd-core/references/test-containers.md +55 -0
  290. package/gsd-core/references/test-strategy.md +75 -0
  291. package/gsd-core/references/thinking-models-debug.md +44 -0
  292. package/gsd-core/references/thinking-models-execution.md +50 -0
  293. package/gsd-core/references/thinking-models-planning.md +62 -0
  294. package/gsd-core/references/thinking-models-research.md +50 -0
  295. package/gsd-core/references/thinking-models-verification.md +55 -0
  296. package/gsd-core/references/thinking-partner.md +96 -0
  297. package/gsd-core/references/ui-brand.md +162 -0
  298. package/gsd-core/references/universal-anti-patterns.md +63 -0
  299. package/gsd-core/references/user-profiling.md +681 -0
  300. package/gsd-core/references/user-story-template.md +58 -0
  301. package/gsd-core/references/verification-overrides.md +227 -0
  302. package/gsd-core/references/verification-patterns.md +612 -0
  303. package/gsd-core/references/verify-mvp-mode.md +85 -0
  304. package/gsd-core/references/workstream-flag.md +111 -0
  305. package/gsd-core/references/worktree-branch-check.md +38 -0
  306. package/gsd-core/references/worktree-path-safety.md +67 -0
  307. package/gsd-core/templates/AI-SPEC.md +246 -0
  308. package/gsd-core/templates/DEBUG.md +169 -0
  309. package/gsd-core/templates/README.md +77 -0
  310. package/gsd-core/templates/SECURITY.md +61 -0
  311. package/gsd-core/templates/UAT.md +265 -0
  312. package/gsd-core/templates/UI-SPEC.md +100 -0
  313. package/gsd-core/templates/VALIDATION.md +76 -0
  314. package/gsd-core/templates/adr.md +58 -0
  315. package/gsd-core/templates/claude-md.md +145 -0
  316. package/gsd-core/templates/codebase/architecture.md +255 -0
  317. package/gsd-core/templates/codebase/concerns.md +310 -0
  318. package/gsd-core/templates/codebase/conventions.md +307 -0
  319. package/gsd-core/templates/codebase/integrations.md +280 -0
  320. package/gsd-core/templates/codebase/stack.md +186 -0
  321. package/gsd-core/templates/codebase/structure.md +285 -0
  322. package/gsd-core/templates/codebase/testing.md +480 -0
  323. package/gsd-core/templates/config.json +62 -0
  324. package/gsd-core/templates/context.md +352 -0
  325. package/gsd-core/templates/continue-here.md +78 -0
  326. package/gsd-core/templates/copilot-instructions.md +7 -0
  327. package/gsd-core/templates/debug-subagent-prompt.md +91 -0
  328. package/gsd-core/templates/dev-preferences.md +21 -0
  329. package/gsd-core/templates/discovery.md +146 -0
  330. package/gsd-core/templates/discussion-log.md +63 -0
  331. package/gsd-core/templates/domain-model.md +54 -0
  332. package/gsd-core/templates/milestone-archive.md +123 -0
  333. package/gsd-core/templates/milestone.md +115 -0
  334. package/gsd-core/templates/phase-prompt.md +610 -0
  335. package/gsd-core/templates/planner-subagent-prompt.md +117 -0
  336. package/gsd-core/templates/product-brief.md +55 -0
  337. package/gsd-core/templates/project.md +186 -0
  338. package/gsd-core/templates/requirements.md +231 -0
  339. package/gsd-core/templates/research-project/ARCHITECTURE.md +204 -0
  340. package/gsd-core/templates/research-project/FEATURES.md +147 -0
  341. package/gsd-core/templates/research-project/PITFALLS.md +200 -0
  342. package/gsd-core/templates/research-project/STACK.md +120 -0
  343. package/gsd-core/templates/research-project/SUMMARY.md +170 -0
  344. package/gsd-core/templates/research.md +592 -0
  345. package/gsd-core/templates/retrospective.md +54 -0
  346. package/gsd-core/templates/roadmap.md +202 -0
  347. package/gsd-core/templates/spec.md +307 -0
  348. package/gsd-core/templates/state.md +195 -0
  349. package/gsd-core/templates/summary-complex.md +59 -0
  350. package/gsd-core/templates/summary-minimal.md +41 -0
  351. package/gsd-core/templates/summary-standard.md +48 -0
  352. package/gsd-core/templates/summary.md +248 -0
  353. package/gsd-core/templates/test-strategy.md +50 -0
  354. package/gsd-core/templates/user-profile.md +146 -0
  355. package/gsd-core/templates/user-setup.md +311 -0
  356. package/gsd-core/templates/verification-report.md +322 -0
  357. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -0
  358. package/gsd-core/workflows/add-backlog.md +91 -0
  359. package/gsd-core/workflows/add-phase.md +113 -0
  360. package/gsd-core/workflows/add-tests.md +355 -0
  361. package/gsd-core/workflows/add-todo.md +161 -0
  362. package/gsd-core/workflows/ai-integration-phase.md +295 -0
  363. package/gsd-core/workflows/analyze-dependencies.md +96 -0
  364. package/gsd-core/workflows/audit-fix.md +178 -0
  365. package/gsd-core/workflows/audit-milestone.md +360 -0
  366. package/gsd-core/workflows/audit-uat.md +110 -0
  367. package/gsd-core/workflows/autonomous.md +797 -0
  368. package/gsd-core/workflows/check-todos.md +180 -0
  369. package/gsd-core/workflows/cleanup.md +195 -0
  370. package/gsd-core/workflows/code-review-fix.md +502 -0
  371. package/gsd-core/workflows/code-review.md +658 -0
  372. package/gsd-core/workflows/complete-milestone.md +855 -0
  373. package/gsd-core/workflows/debug.md +237 -0
  374. package/gsd-core/workflows/diagnose-issues.md +245 -0
  375. package/gsd-core/workflows/discover-product.md +112 -0
  376. package/gsd-core/workflows/discovery-phase.md +291 -0
  377. package/gsd-core/workflows/discuss-phase/modes/advisor.md +176 -0
  378. package/gsd-core/workflows/discuss-phase/modes/all.md +28 -0
  379. package/gsd-core/workflows/discuss-phase/modes/analyze.md +44 -0
  380. package/gsd-core/workflows/discuss-phase/modes/auto.md +57 -0
  381. package/gsd-core/workflows/discuss-phase/modes/batch.md +52 -0
  382. package/gsd-core/workflows/discuss-phase/modes/chain.md +98 -0
  383. package/gsd-core/workflows/discuss-phase/modes/default.md +141 -0
  384. package/gsd-core/workflows/discuss-phase/modes/power.md +44 -0
  385. package/gsd-core/workflows/discuss-phase/modes/text.md +55 -0
  386. package/gsd-core/workflows/discuss-phase/templates/checkpoint.json +18 -0
  387. package/gsd-core/workflows/discuss-phase/templates/context.md +136 -0
  388. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +50 -0
  389. package/gsd-core/workflows/discuss-phase-assumptions.md +675 -0
  390. package/gsd-core/workflows/discuss-phase-power.md +291 -0
  391. package/gsd-core/workflows/discuss-phase.md +499 -0
  392. package/gsd-core/workflows/do.md +111 -0
  393. package/gsd-core/workflows/docs-update.md +1176 -0
  394. package/gsd-core/workflows/edit-phase.md +295 -0
  395. package/gsd-core/workflows/eval-review.md +156 -0
  396. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +95 -0
  397. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
  398. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +117 -0
  399. package/gsd-core/workflows/execute-phase.md +1752 -0
  400. package/gsd-core/workflows/execute-plan.md +526 -0
  401. package/gsd-core/workflows/explore.md +146 -0
  402. package/gsd-core/workflows/extract-learnings.md +243 -0
  403. package/gsd-core/workflows/fast.md +124 -0
  404. package/gsd-core/workflows/forensics.md +279 -0
  405. package/gsd-core/workflows/graduation.md +196 -0
  406. package/gsd-core/workflows/health.md +224 -0
  407. package/gsd-core/workflows/help/modes/brief.md +22 -0
  408. package/gsd-core/workflows/help/modes/default.md +50 -0
  409. package/gsd-core/workflows/help/modes/full.md +789 -0
  410. package/gsd-core/workflows/help/modes/topic.md +74 -0
  411. package/gsd-core/workflows/help.md +24 -0
  412. package/gsd-core/workflows/import.md +256 -0
  413. package/gsd-core/workflows/inbox.md +387 -0
  414. package/gsd-core/workflows/ingest-docs.md +340 -0
  415. package/gsd-core/workflows/insert-phase.md +152 -0
  416. package/gsd-core/workflows/list-phase-assumptions.md +178 -0
  417. package/gsd-core/workflows/list-workspaces.md +57 -0
  418. package/gsd-core/workflows/manager.md +393 -0
  419. package/gsd-core/workflows/map-codebase.md +446 -0
  420. package/gsd-core/workflows/milestone-summary.md +224 -0
  421. package/gsd-core/workflows/model-domain.md +162 -0
  422. package/gsd-core/workflows/mvp-phase.md +222 -0
  423. package/gsd-core/workflows/new-milestone.md +635 -0
  424. package/gsd-core/workflows/new-project.md +1555 -0
  425. package/gsd-core/workflows/new-workspace.md +240 -0
  426. package/gsd-core/workflows/next.md +299 -0
  427. package/gsd-core/workflows/node-repair.md +92 -0
  428. package/gsd-core/workflows/note.md +158 -0
  429. package/gsd-core/workflows/pause-work.md +244 -0
  430. package/gsd-core/workflows/plan-milestone-gaps.md +281 -0
  431. package/gsd-core/workflows/plan-phase.md +1814 -0
  432. package/gsd-core/workflows/plan-review-convergence.md +346 -0
  433. package/gsd-core/workflows/plant-seed.md +230 -0
  434. package/gsd-core/workflows/pr-branch.md +157 -0
  435. package/gsd-core/workflows/profile-user.md +453 -0
  436. package/gsd-core/workflows/progress.md +699 -0
  437. package/gsd-core/workflows/quick.md +1017 -0
  438. package/gsd-core/workflows/reapply-patches.md +426 -0
  439. package/gsd-core/workflows/recommend-architecture.md +135 -0
  440. package/gsd-core/workflows/remove-phase.md +156 -0
  441. package/gsd-core/workflows/remove-workspace.md +108 -0
  442. package/gsd-core/workflows/resume-project.md +332 -0
  443. package/gsd-core/workflows/review.md +748 -0
  444. package/gsd-core/workflows/scan.md +107 -0
  445. package/gsd-core/workflows/secure-phase.md +182 -0
  446. package/gsd-core/workflows/session-report.md +146 -0
  447. package/gsd-core/workflows/settings-advanced.md +810 -0
  448. package/gsd-core/workflows/settings-integrations.md +312 -0
  449. package/gsd-core/workflows/settings.md +566 -0
  450. package/gsd-core/workflows/ship.md +405 -0
  451. package/gsd-core/workflows/sketch-wrap-up.md +286 -0
  452. package/gsd-core/workflows/sketch.md +361 -0
  453. package/gsd-core/workflows/spec-phase.md +263 -0
  454. package/gsd-core/workflows/spike-wrap-up.md +307 -0
  455. package/gsd-core/workflows/spike.md +453 -0
  456. package/gsd-core/workflows/stats.md +80 -0
  457. package/gsd-core/workflows/sync-skills.md +182 -0
  458. package/gsd-core/workflows/testing-strategy.md +122 -0
  459. package/gsd-core/workflows/thread.md +222 -0
  460. package/gsd-core/workflows/transition.md +694 -0
  461. package/gsd-core/workflows/ui-phase.md +328 -0
  462. package/gsd-core/workflows/ui-review.md +193 -0
  463. package/gsd-core/workflows/ultraplan-phase.md +199 -0
  464. package/gsd-core/workflows/undo.md +314 -0
  465. package/gsd-core/workflows/update.md +496 -0
  466. package/gsd-core/workflows/validate-phase.md +181 -0
  467. package/gsd-core/workflows/verify-phase.md +544 -0
  468. package/gsd-core/workflows/verify-work.md +781 -0
  469. package/hooks/dist/gsd-check-update-worker.js +108 -0
  470. package/hooks/dist/gsd-check-update.js +66 -0
  471. package/hooks/dist/gsd-config-reload.js +133 -0
  472. package/hooks/dist/gsd-context-monitor.js +195 -0
  473. package/hooks/dist/gsd-cursor-post-tool.js +75 -0
  474. package/hooks/dist/gsd-cursor-session-start.js +52 -0
  475. package/hooks/dist/gsd-graphify-update.sh +158 -0
  476. package/hooks/dist/gsd-phase-boundary.sh +47 -0
  477. package/hooks/dist/gsd-prompt-guard.js +97 -0
  478. package/hooks/dist/gsd-read-guard.js +101 -0
  479. package/hooks/dist/gsd-read-injection-scanner.js +203 -0
  480. package/hooks/dist/gsd-session-state.sh +59 -0
  481. package/hooks/dist/gsd-statusline.js +566 -0
  482. package/hooks/dist/gsd-update-banner.js +138 -0
  483. package/hooks/dist/gsd-validate-commit.sh +57 -0
  484. package/hooks/dist/gsd-workflow-guard.js +167 -0
  485. package/hooks/dist/gsd-worktree-path-guard.js +169 -0
  486. package/hooks/dist/lib/git-cmd.js +150 -0
  487. package/hooks/dist/lib/gsd-graphify-rebuild.sh +65 -0
  488. package/hooks/dist/managed-hooks-registry.cjs +38 -0
  489. package/hooks/gsd-check-update-worker.js +108 -0
  490. package/hooks/gsd-check-update.js +66 -0
  491. package/hooks/gsd-config-reload.js +133 -0
  492. package/hooks/gsd-context-monitor.js +195 -0
  493. package/hooks/gsd-cursor-post-tool.js +75 -0
  494. package/hooks/gsd-cursor-session-start.js +52 -0
  495. package/hooks/gsd-graphify-update.sh +158 -0
  496. package/hooks/gsd-phase-boundary.sh +47 -0
  497. package/hooks/gsd-prompt-guard.js +97 -0
  498. package/hooks/gsd-read-guard.js +101 -0
  499. package/hooks/gsd-read-injection-scanner.js +203 -0
  500. package/hooks/gsd-session-state.sh +59 -0
  501. package/hooks/gsd-statusline.js +566 -0
  502. package/hooks/gsd-update-banner.js +138 -0
  503. package/hooks/gsd-validate-commit.sh +57 -0
  504. package/hooks/gsd-workflow-guard.js +167 -0
  505. package/hooks/gsd-worktree-path-guard.js +169 -0
  506. package/hooks/hooks.json +69 -0
  507. package/hooks/lib/git-cmd.js +150 -0
  508. package/hooks/lib/gsd-graphify-rebuild.sh +65 -0
  509. package/hooks/managed-hooks-registry.cjs +38 -0
  510. package/package.json +115 -0
  511. package/scripts/affected-tests-lib.cjs +542 -0
  512. package/scripts/audit-workflow-script-paths.cjs +73 -0
  513. package/scripts/base64-scan.sh +351 -0
  514. package/scripts/build-hooks.js +247 -0
  515. package/scripts/changeset/README.md +129 -0
  516. package/scripts/changeset/cli.cjs +590 -0
  517. package/scripts/changeset/github-release-notes.cjs +199 -0
  518. package/scripts/changeset/lint.cjs +111 -0
  519. package/scripts/changeset/new.cjs +137 -0
  520. package/scripts/changeset/parse.cjs +114 -0
  521. package/scripts/changeset/render.cjs +34 -0
  522. package/scripts/changeset/serialize.cjs +130 -0
  523. package/scripts/check-alias-drift.cjs +114 -0
  524. package/scripts/check-env.cjs +312 -0
  525. package/scripts/check-npm-integrity.cjs +215 -0
  526. package/scripts/ci-guard-runner.cjs +22 -0
  527. package/scripts/ci-prepare-test-scope.cjs +51 -0
  528. package/scripts/ci-rebase-check.cjs +86 -0
  529. package/scripts/ci-test-scope.cjs +431 -0
  530. package/scripts/command-contract-helpers.cjs +64 -0
  531. package/scripts/diff-touches-shipped-paths.cjs +155 -0
  532. package/scripts/fix-slash-commands.cjs +147 -0
  533. package/scripts/gen-inventory-manifest.cjs +115 -0
  534. package/scripts/gen-research-agents.cjs +276 -0
  535. package/scripts/generate-package-identity.cjs +125 -0
  536. package/scripts/issue-dedupe.cjs +278 -0
  537. package/scripts/lib/allowlist-ratchet.cjs +136 -0
  538. package/scripts/lib/cli-exit.cjs +56 -0
  539. package/scripts/lint-command-contract.cjs +114 -0
  540. package/scripts/lint-descriptions.cjs +87 -0
  541. package/scripts/lint-docs-required.cjs +222 -0
  542. package/scripts/lint-legacy-dir-name.cjs +160 -0
  543. package/scripts/lint-package-identity-drift.cjs +141 -0
  544. package/scripts/lint-pr-check-project-dir.cjs +99 -0
  545. package/scripts/lint-shell-command-projection-drift.cjs +62 -0
  546. package/scripts/lint-skill-deps.cjs +185 -0
  547. package/scripts/lint-test-file-count.allowlist.json +135 -0
  548. package/scripts/lint-test-file-count.cjs +246 -0
  549. package/scripts/mutation-matrix.cjs +222 -0
  550. package/scripts/pr-template-policy.cjs +268 -0
  551. package/scripts/prompt-injection-scan.sh +207 -0
  552. package/scripts/release-notes/discord-release-summary.cjs +373 -0
  553. package/scripts/release-notes/format-github-release-notes.cjs +261 -0
  554. package/scripts/release-tarball-smoke.cjs +629 -0
  555. package/scripts/research-profiles.cjs +149 -0
  556. package/scripts/run-affected-tests.cjs +7 -0
  557. package/scripts/run-cross-platform-tests.cjs +67 -0
  558. package/scripts/run-tests.cjs +315 -0
  559. package/scripts/secret-scan-lint.sh +231 -0
  560. package/scripts/secret-scan.sh +358 -0
  561. package/scripts/setup-branch-protection.sh +236 -0
  562. package/scripts/strip-prose-atrefs.cjs +106 -0
  563. package/scripts/sync-manifest-versions.cjs +119 -0
  564. package/scripts/sync-rulesets.sh +34 -0
  565. package/scripts/sync-runtime-launcher.cjs +399 -0
  566. package/scripts/test-failure-reasons.cjs +34 -0
  567. package/scripts/verify-npm-publish.cjs +240 -0
  568. package/scripts/workflow-policy.cjs +450 -0
@@ -0,0 +1,476 @@
1
+ "use strict";
2
+ /**
3
+ * Roadmap Upgrade — Migration tool for converting legacy 'Phase N' phase IDs
4
+ * to milestone-prefixed 'Phase M-NN' form.
5
+ *
6
+ * ADR-457 build-at-publish: the hand-written bin/lib/roadmap-upgrade.cjs collapsed
7
+ * to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
8
+ * from the prior hand-written .cjs; only types are added.
9
+ */
10
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
+ };
13
+ const node_fs_1 = __importDefault(require("node:fs"));
14
+ const node_path_1 = __importDefault(require("node:path"));
15
+ const node_child_process_1 = require("node:child_process");
16
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
17
+ const planningWorkspace = require("./planning-workspace.cjs");
18
+ const { planningDir } = planningWorkspace;
19
+ // ─── Regex helpers ────────────────────────────────────────────────────────────
20
+ // Matches legacy phase headings: ### Phase N: Name (also decimal: Phase 2.1:)
21
+ // Captures: (hashes)(spaces)(phase-number)(rest-of-line)
22
+ const LEGACY_PHASE_HEADING_RE = /^(#{2,4})\s*(?:\[[^\]]+\]\s*)?Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:(.*)/i;
23
+ // Matches already-migrated phase headings: ### Phase M-NN: Name
24
+ const MIGRATED_PHASE_HEADING_RE = /^#{2,4}\s*(?:\[[^\]]+\]\s*)?Phase\s+\d+-\d{2}\s*:/i;
25
+ // Matches milestone section headings: ## v1.0, ## Roadmap v2.0, ## ✅ v1.0, ## [GSD] v1.0, etc.
26
+ // The optional bracket-token prefix (e.g., [GSD]) must be tested before the emoji group.
27
+ const MILESTONE_HEADING_RE = /^##\s+(?:\[[^\]]+\]\s+|Roadmap\s+|[✅🚧]\s*)?v(\d+)\.(\d+)(?:\s|:)/iu;
28
+ // ─── Pure computation helpers ─────────────────────────────────────────────────
29
+ /**
30
+ * Parse the ROADMAP.md content and build a list of phase entries with their
31
+ * enclosing milestone major version.
32
+ *
33
+ * Returns an array of:
34
+ * { lineIndex, headingLine, milestoneInt, legacyPhaseNum, phaseName }
35
+ */
36
+ function parseRoadmapPhases(lines) {
37
+ const results = [];
38
+ let currentMilestoneInt = null;
39
+ for (let i = 0; i < lines.length; i++) {
40
+ const line = lines[i];
41
+ const milestoneMatch = line.match(MILESTONE_HEADING_RE);
42
+ if (milestoneMatch) {
43
+ currentMilestoneInt = parseInt(milestoneMatch[1], 10);
44
+ continue;
45
+ }
46
+ if (MIGRATED_PHASE_HEADING_RE.test(line)) {
47
+ // Already-migrated heading found — caller will detect this
48
+ results.push({ lineIndex: i, headingLine: line, alreadyMigrated: true });
49
+ continue;
50
+ }
51
+ const phaseMatch = line.match(LEGACY_PHASE_HEADING_RE);
52
+ if (phaseMatch) {
53
+ results.push({
54
+ lineIndex: i,
55
+ headingLine: line,
56
+ milestoneInt: currentMilestoneInt,
57
+ legacyPhaseNum: phaseMatch[2],
58
+ phaseName: phaseMatch[3].trim(),
59
+ hashes: phaseMatch[1],
60
+ alreadyMigrated: false,
61
+ });
62
+ }
63
+ }
64
+ return results;
65
+ }
66
+ /**
67
+ * Assign sub-indices within each milestone, building a per-entry mapping.
68
+ *
69
+ * Input: array from parseRoadmapPhases (non-migrated entries only).
70
+ * Returns: Map<lineIndex, { newId, milestoneInt, subIndex }>
71
+ *
72
+ * Keyed by `lineIndex` (the unique position of the heading line in ROADMAP.md)
73
+ * so that identical legacy phase numbers in different milestones (e.g., two
74
+ * `Phase 1` headings in v1.0 and v2.0) each get their own correct M-NN ID
75
+ * instead of the later milestone's mapping overwriting the earlier one.
76
+ *
77
+ * Sub-indices are 1-based and sequential within each milestone.
78
+ */
79
+ function assignSubIndices(phaseEntries) {
80
+ const milestoneCounters = new Map(); // milestoneInt → counter
81
+ const mapping = new Map(); // lineIndex → { newId, milestoneInt, subIndex }
82
+ for (const entry of phaseEntries) {
83
+ if (entry.alreadyMigrated)
84
+ continue;
85
+ const m = entry.milestoneInt;
86
+ if (m === null || m === undefined)
87
+ continue;
88
+ const counter = (milestoneCounters.get(m) || 0) + 1;
89
+ milestoneCounters.set(m, counter);
90
+ const subIndex = String(counter).padStart(2, '0');
91
+ const newId = `${m}-${subIndex}`;
92
+ mapping.set(entry.lineIndex, { newId, milestoneInt: m, subIndex: counter, legacyPhaseNum: entry.legacyPhaseNum });
93
+ }
94
+ return mapping;
95
+ }
96
+ /**
97
+ * Read a phase directory name and return its numeric token (stripping project_code prefix).
98
+ * e.g. "GSD-01-setup" → "01", "01-setup" → "01", "02-implement" → "02", "02.1-hotfix" → "02.1"
99
+ */
100
+ function extractPhaseNumFromDir(dirName) {
101
+ // Strip optional project_code prefix: "GSD-01-setup" → "01-setup"
102
+ const stripped = dirName.replace(/^[A-Z]{1,6}-(?=\d)/i, '');
103
+ // Matches: digits + optional letter + optional decimal suffix, followed by '-' or end.
104
+ // e.g. "02.1-hotfix" → "02.1", "01-setup" → "01"
105
+ const m = stripped.match(/^(\d+[A-Z]?(?:\.\d+)*)(?:-|$)/i);
106
+ return m ? m[1] : null;
107
+ }
108
+ /**
109
+ * Build the new directory name from old name and new phase ID.
110
+ * old: "01-setup" newId: "1-02" projectCode: "GSD" → "GSD-01-02-setup"
111
+ * old: "01-setup" newId: "1-02" projectCode: null → "01-02-setup"
112
+ * old: "GSD-01-setup" newId: "1-02" projectCode: "GSD" → "GSD-01-02-setup"
113
+ */
114
+ function buildNewDirName(oldDirName, newId, projectCode) {
115
+ // Strip existing project_code prefix
116
+ const stripped = oldDirName.replace(/^[A-Z]{1,6}-(?=\d)/i, '');
117
+ // Extract slug: everything after "NN-" (the old phase num, including decimal like 02.1)
118
+ const slugMatch = stripped.match(/^\d+[A-Z]?(?:\.\d+)*-(.*)/i);
119
+ const slug = slugMatch ? slugMatch[1] : stripped;
120
+ // Build M-NN prefix (zero-pad both parts)
121
+ const [milestoneStr, subStr] = newId.split('-');
122
+ const milestoneInt = parseInt(milestoneStr, 10);
123
+ const paddedMilestone = String(milestoneInt).padStart(2, '0');
124
+ const newBase = slug ? `${paddedMilestone}-${subStr}-${slug}` : `${paddedMilestone}-${subStr}`;
125
+ return projectCode ? `${projectCode}-${newBase}` : newBase;
126
+ }
127
+ // ─── computeMigrationPlan ─────────────────────────────────────────────────────
128
+ /**
129
+ * Compute a migration plan without touching the filesystem.
130
+ */
131
+ function computeMigrationPlan(cwd, options = {}) {
132
+ void options;
133
+ const pDir = planningDir(cwd);
134
+ const roadmapPath = node_path_1.default.join(pDir, 'ROADMAP.md');
135
+ const configPath = node_path_1.default.join(pDir, 'config.json');
136
+ const phasesDir = node_path_1.default.join(pDir, 'phases');
137
+ // ── Check config for existing convention ─────────────────────────────────
138
+ let configData = {};
139
+ try {
140
+ configData = JSON.parse(node_fs_1.default.readFileSync(configPath, 'utf8'));
141
+ }
142
+ catch { /* config may not exist */ }
143
+ if (configData['phase_id_convention'] === 'milestone-prefixed') {
144
+ return { alreadyMigrated: true, phases: [], roadmapEdits: [], crossRefEdits: [] };
145
+ }
146
+ const projectCode = typeof configData['project_code'] === 'string' ? configData['project_code'] : null;
147
+ // ── Read ROADMAP.md ───────────────────────────────────────────────────────
148
+ let roadmapContent = '';
149
+ try {
150
+ roadmapContent = node_fs_1.default.readFileSync(roadmapPath, 'utf8');
151
+ }
152
+ catch {
153
+ throw new Error(`ROADMAP.md not found at ${roadmapPath}`);
154
+ }
155
+ const lines = roadmapContent.split('\n');
156
+ const parsedPhases = parseRoadmapPhases(lines);
157
+ // Check for any already-migrated headings
158
+ const hasAnyMigrated = parsedPhases.some(e => e.alreadyMigrated);
159
+ if (hasAnyMigrated) {
160
+ return { alreadyMigrated: true, phases: [], roadmapEdits: [], crossRefEdits: [] };
161
+ }
162
+ const legacyPhases = parsedPhases.filter(e => !e.alreadyMigrated);
163
+ const idMapping = assignSubIndices(legacyPhases);
164
+ // Secondary lookup: (milestoneInt, normalizedLegacyNum) → newId
165
+ // Used for directory renames and checklist rewrites where line position is unknown.
166
+ // For simplicity, each milestone gets its own Map from legacy num → newId.
167
+ const milestoneIdMap = new Map(); // milestoneInt → Map<normalizedLegacyNum, newId>
168
+ for (const [, entry] of idMapping) {
169
+ if (!milestoneIdMap.has(entry.milestoneInt)) {
170
+ milestoneIdMap.set(entry.milestoneInt, new Map());
171
+ }
172
+ const mMap = milestoneIdMap.get(entry.milestoneInt);
173
+ const legacyNum = entry.legacyPhaseNum;
174
+ // Register integer forms (covers plain numeric and letter-suffix IDs)
175
+ const intPart = parseInt(legacyNum, 10);
176
+ const paddedLegacy = String(intPart).padStart(2, '0');
177
+ const unpaddedLegacy = String(intPart);
178
+ mMap.set(paddedLegacy, entry.newId);
179
+ mMap.set(unpaddedLegacy, entry.newId);
180
+ // Also register the original form and padded-integer+decimal form
181
+ // so decimal IDs like "2.1" / "02.1" round-trip correctly.
182
+ mMap.set(legacyNum, entry.newId);
183
+ const dotIdx = legacyNum.indexOf('.');
184
+ if (dotIdx !== -1) {
185
+ const decimalSuffix = legacyNum.slice(dotIdx); // e.g. ".1"
186
+ mMap.set(paddedLegacy + decimalSuffix, entry.newId);
187
+ mMap.set(unpaddedLegacy + decimalSuffix, entry.newId);
188
+ }
189
+ }
190
+ // ── Read existing phase directories ───────────────────────────────────────
191
+ let existingDirs = [];
192
+ try {
193
+ existingDirs = node_fs_1.default.readdirSync(phasesDir).filter(d => {
194
+ try {
195
+ return node_fs_1.default.statSync(node_path_1.default.join(phasesDir, d)).isDirectory();
196
+ }
197
+ catch {
198
+ return false;
199
+ }
200
+ });
201
+ }
202
+ catch { /* phases dir may not exist */ }
203
+ // ── Build phase rename pairs ───────────────────────────────────────────────
204
+ // Flat ordered list of (legacyPhaseNum, newId) in ROADMAP order, for dir matching.
205
+ const orderedMappings = [...idMapping.values()].map(e => ({
206
+ legacyPhaseNum: e.legacyPhaseNum,
207
+ newId: e.newId,
208
+ milestoneInt: e.milestoneInt,
209
+ _used: false,
210
+ }));
211
+ // Note: if the same legacy phase number appears in multiple milestones (the exact legacy
212
+ // ambiguity this tool is designed to resolve), directories are matched in ROADMAP document
213
+ // order — the first ROADMAP occurrence of a given number claims the first matching disk dir.
214
+ // This is the only unambiguous assignment strategy for flat dirs that carry no milestone
215
+ // context. The dry-run output shows the complete rename plan so users can review before
216
+ // applying with --apply.
217
+ const phases = [];
218
+ for (const dirName of existingDirs) {
219
+ const phaseNum = extractPhaseNumFromDir(dirName);
220
+ if (!phaseNum)
221
+ continue;
222
+ const intPart = parseInt(phaseNum, 10);
223
+ const paddedPhaseNum = String(intPart).padStart(2, '0');
224
+ const unpaddedPhaseNum = String(intPart);
225
+ // For decimal IDs like "02.1", also try "2.1"
226
+ const dotIdx = phaseNum.indexOf('.');
227
+ const decimalUnpadded = dotIdx !== -1 ? unpaddedPhaseNum + phaseNum.slice(dotIdx) : null;
228
+ // Find the first unused mapping whose legacy number matches (exact, padded, unpadded, or decimal)
229
+ const found = orderedMappings.find(m => !m._used && (m.legacyPhaseNum === phaseNum ||
230
+ m.legacyPhaseNum === paddedPhaseNum ||
231
+ m.legacyPhaseNum === unpaddedPhaseNum ||
232
+ (decimalUnpadded && m.legacyPhaseNum === decimalUnpadded)));
233
+ if (!found)
234
+ continue;
235
+ found._used = true;
236
+ const newDirName = buildNewDirName(dirName, found.newId, projectCode);
237
+ if (newDirName !== dirName) {
238
+ phases.push({
239
+ oldId: phaseNum,
240
+ newId: found.newId,
241
+ oldDir: dirName,
242
+ newDir: newDirName,
243
+ });
244
+ }
245
+ }
246
+ // ── Build ROADMAP.md line edits ────────────────────────────────────────────
247
+ const roadmapEdits = [];
248
+ for (const entry of legacyPhases) {
249
+ // Use lineIndex as the canonical key (not legacyPhaseNum, which may collide across milestones)
250
+ const mapping = idMapping.get(entry.lineIndex);
251
+ if (!mapping)
252
+ continue;
253
+ // Rewrite heading line: "### Phase N: Name" → "### Phase M-NN: Name"
254
+ const oldLine = lines[entry.lineIndex];
255
+ const newLine = oldLine.replace(/^(#{2,4}\s*(?:\[[^\]]+\]\s*)?Phase\s+)\d+[A-Z]?(?:\.\d+)*(\s*:)/i, `$1${mapping.newId}$2`);
256
+ if (newLine !== oldLine) {
257
+ roadmapEdits.push({ lineIndex: entry.lineIndex, from: oldLine, to: newLine });
258
+ }
259
+ }
260
+ // Rewrite checklist lines in ROADMAP.md — use milestone context to resolve collisions.
261
+ let currentChecklistMilestone = null;
262
+ for (let i = 0; i < lines.length; i++) {
263
+ const line = lines[i];
264
+ // Track enclosing milestone section for context-aware lookup
265
+ const milestoneHeadingMatch = line.match(MILESTONE_HEADING_RE);
266
+ if (milestoneHeadingMatch) {
267
+ currentChecklistMilestone = parseInt(milestoneHeadingMatch[1], 10);
268
+ }
269
+ // Already in roadmapEdits? skip
270
+ if (roadmapEdits.some(e => e.lineIndex === i))
271
+ continue;
272
+ // Match checklist items: "- [ ] **Phase N:**" or "- [x] Phase N:" (also decimal)
273
+ const checklistMatch = line.match(/^(\s*-\s*\[[ x]\]\s*\*{0,2}Phase\s+)(\d+[A-Z]?(?:\.\d+)*)(\s*[:\s*])/i);
274
+ if (checklistMatch) {
275
+ const legacyNum = checklistMatch[2];
276
+ const cIntPart = parseInt(legacyNum, 10);
277
+ const paddedLegacy = String(cIntPart).padStart(2, '0');
278
+ const unpaddedLegacy = String(cIntPart);
279
+ const cDotIdx = legacyNum.indexOf('.');
280
+ const paddedLegacyDecimal = cDotIdx !== -1 ? paddedLegacy + legacyNum.slice(cDotIdx) : null;
281
+ // Prefer milestone-context lookup (avoids collision across milestones)
282
+ let newId;
283
+ if (currentChecklistMilestone !== null && milestoneIdMap.has(currentChecklistMilestone)) {
284
+ const mMap = milestoneIdMap.get(currentChecklistMilestone);
285
+ newId = mMap.get(legacyNum) || mMap.get(paddedLegacy) || mMap.get(unpaddedLegacy);
286
+ if (!newId && paddedLegacyDecimal)
287
+ newId = mMap.get(paddedLegacyDecimal);
288
+ }
289
+ if (!newId) {
290
+ // Fallback: use ordered flat list (no milestone collision in this roadmap)
291
+ const found = orderedMappings.find(m => m.legacyPhaseNum === legacyNum ||
292
+ m.legacyPhaseNum === paddedLegacy ||
293
+ m.legacyPhaseNum === unpaddedLegacy ||
294
+ (paddedLegacyDecimal && m.legacyPhaseNum === paddedLegacyDecimal));
295
+ if (found)
296
+ newId = found.newId;
297
+ }
298
+ if (newId) {
299
+ const newLine = line.replace(/^(\s*-\s*\[[ x]\]\s*\*{0,2}Phase\s+)\d+[A-Z]?(?:\.\d+)*(\s*[:\s*])/i, `$1${newId}$2`);
300
+ if (newLine !== line) {
301
+ roadmapEdits.push({ lineIndex: i, from: line, to: newLine });
302
+ }
303
+ }
304
+ }
305
+ }
306
+ // ── Build cross-ref edits for STATE.md and PROJECT.md ────────────────────
307
+ const crossRefEdits = [];
308
+ const crossRefFiles = ['STATE.md', 'PROJECT.md'];
309
+ for (const fileName of crossRefFiles) {
310
+ const filePath = node_path_1.default.join(pDir, fileName);
311
+ if (!node_fs_1.default.existsSync(filePath))
312
+ continue;
313
+ const fileContent = node_fs_1.default.readFileSync(filePath, 'utf8');
314
+ // Iterate using orderedMappings (ROADMAP order) — idMapping is now keyed by lineIndex.
315
+ for (const m of orderedMappings) {
316
+ const legacyNum = m.legacyPhaseNum;
317
+ const xIntPart = parseInt(legacyNum, 10);
318
+ const paddedNum = String(xIntPart).padStart(2, '0');
319
+ const unpaddedNum = String(xIntPart);
320
+ // Decimal suffix (e.g. ".1" from "2.1") — preserve in cross-ref patterns
321
+ const xDotIdx = legacyNum.indexOf('.');
322
+ const decimalSuffix = xDotIdx !== -1 ? legacyNum.slice(xDotIdx) : '';
323
+ // Rewrite project_code-prefixed references: "GSD-01-" → "GSD-01-02-"
324
+ if (projectCode) {
325
+ const [milestoneStr, subStr] = m.newId.split('-');
326
+ const paddedMilestone = String(parseInt(milestoneStr, 10)).padStart(2, '0');
327
+ const prefixedNew = `${projectCode}-${paddedMilestone}-${subStr}-`;
328
+ // Try both padded and original forms as old prefix
329
+ for (const oldNum of new Set([paddedNum + decimalSuffix, unpaddedNum + decimalSuffix, paddedNum, unpaddedNum])) {
330
+ const prefixedOld = `${projectCode}-${oldNum}-`;
331
+ if (fileContent.includes(prefixedOld)) {
332
+ crossRefEdits.push({ file: fileName, from: prefixedOld, to: prefixedNew });
333
+ }
334
+ }
335
+ }
336
+ // Rewrite prose references: "Phase 1:" → "Phase 1-01:", "Phase 2.1:" → "Phase 1-02:"
337
+ const proseOldPatterns = new Set([
338
+ `Phase ${unpaddedNum}${decimalSuffix}:`,
339
+ `Phase ${paddedNum}${decimalSuffix}:`,
340
+ `Phase ${legacyNum}:`,
341
+ ]);
342
+ for (const proseOld of proseOldPatterns) {
343
+ if (fileContent.includes(proseOld)) {
344
+ const proseNew = `Phase ${m.newId}:`;
345
+ crossRefEdits.push({ file: fileName, from: proseOld, to: proseNew });
346
+ }
347
+ }
348
+ }
349
+ }
350
+ return {
351
+ alreadyMigrated: false,
352
+ phases,
353
+ roadmapEdits,
354
+ crossRefEdits,
355
+ };
356
+ }
357
+ // ─── applyMigration ───────────────────────────────────────────────────────────
358
+ /**
359
+ * Apply the migration plan computed by computeMigrationPlan().
360
+ *
361
+ * @param cwd
362
+ * @param plan
363
+ * @param options
364
+ * @param options.dryRun - Print plan and exit without mutating. (default true)
365
+ */
366
+ function applyMigration(cwd, plan, options = {}) {
367
+ const dryRun = options.dryRun !== false; // default true
368
+ if (plan.alreadyMigrated) {
369
+ return { alreadyMigrated: true };
370
+ }
371
+ if (dryRun) {
372
+ process.stdout.write(JSON.stringify(plan, null, 2) + '\n');
373
+ return { dryRun: true };
374
+ }
375
+ // ── Real run: verify clean working tree ───────────────────────────────────
376
+ let gitStatus;
377
+ try {
378
+ gitStatus = (0, node_child_process_1.execSync)('git status --porcelain', { cwd, encoding: 'utf8', windowsHide: true });
379
+ }
380
+ catch (err) {
381
+ throw new Error(`git status failed: ${err.message}`);
382
+ }
383
+ if (gitStatus.trim().length > 0) {
384
+ throw new Error('Working tree is dirty. Commit or stash changes before migrating.');
385
+ }
386
+ // Capture HEAD sha for rollback
387
+ let headSha;
388
+ try {
389
+ headSha = (0, node_child_process_1.execSync)('git rev-parse HEAD', { cwd, encoding: 'utf8', windowsHide: true }).trim();
390
+ }
391
+ catch (err) {
392
+ throw new Error(`git rev-parse HEAD failed: ${err.message}`);
393
+ }
394
+ const pDir = planningDir(cwd);
395
+ const phasesDir = node_path_1.default.join(pDir, 'phases');
396
+ const roadmapPath = node_path_1.default.join(pDir, 'ROADMAP.md');
397
+ const configPath = node_path_1.default.join(pDir, 'config.json');
398
+ const renamedDirs = [];
399
+ const editedFiles = [];
400
+ try {
401
+ // 1. Rename phase directories
402
+ for (const phaseEntry of plan.phases) {
403
+ const oldPath = node_path_1.default.join(phasesDir, phaseEntry.oldDir);
404
+ const newPath = node_path_1.default.join(phasesDir, phaseEntry.newDir);
405
+ if (node_fs_1.default.existsSync(oldPath)) {
406
+ node_fs_1.default.renameSync(oldPath, newPath);
407
+ renamedDirs.push(`${phaseEntry.oldDir} → ${phaseEntry.newDir}`);
408
+ }
409
+ }
410
+ // 2. Rewrite ROADMAP.md phase headings
411
+ if (plan.roadmapEdits.length > 0) {
412
+ const roadmapContent = node_fs_1.default.readFileSync(roadmapPath, 'utf8');
413
+ const lines = roadmapContent.split('\n');
414
+ // Sort edits by lineIndex to apply in order
415
+ const sortedEdits = [...plan.roadmapEdits].sort((a, b) => a.lineIndex - b.lineIndex);
416
+ for (const edit of sortedEdits) {
417
+ if (lines[edit.lineIndex] === edit.from) {
418
+ lines[edit.lineIndex] = edit.to;
419
+ }
420
+ }
421
+ node_fs_1.default.writeFileSync(roadmapPath, lines.join('\n'), 'utf8');
422
+ editedFiles.push('ROADMAP.md');
423
+ }
424
+ // 3. Rewrite cross-refs in STATE.md and PROJECT.md
425
+ const crossRefsByFile = new Map();
426
+ for (const edit of plan.crossRefEdits) {
427
+ if (!crossRefsByFile.has(edit.file)) {
428
+ crossRefsByFile.set(edit.file, []);
429
+ }
430
+ crossRefsByFile.get(edit.file).push(edit);
431
+ }
432
+ for (const [fileName, edits] of crossRefsByFile) {
433
+ const filePath = node_path_1.default.join(pDir, fileName);
434
+ if (!node_fs_1.default.existsSync(filePath))
435
+ continue;
436
+ let content = node_fs_1.default.readFileSync(filePath, 'utf8');
437
+ let changed = false;
438
+ for (const edit of edits) {
439
+ if (content.includes(edit.from)) {
440
+ // Replace all occurrences
441
+ content = content.split(edit.from).join(edit.to);
442
+ changed = true;
443
+ }
444
+ }
445
+ if (changed) {
446
+ node_fs_1.default.writeFileSync(filePath, content, 'utf8');
447
+ editedFiles.push(fileName);
448
+ }
449
+ }
450
+ // 4. Update config.json: set phase_id_convention to 'milestone-prefixed'
451
+ let configData = {};
452
+ try {
453
+ configData = JSON.parse(node_fs_1.default.readFileSync(configPath, 'utf8'));
454
+ }
455
+ catch { /* config may not exist yet */ }
456
+ configData['phase_id_convention'] = 'milestone-prefixed';
457
+ node_fs_1.default.writeFileSync(configPath, JSON.stringify(configData, null, 2) + '\n', 'utf8');
458
+ editedFiles.push('config.json');
459
+ }
460
+ catch (err) {
461
+ // Rollback via git reset --hard + git clean
462
+ try {
463
+ (0, node_child_process_1.execSync)(`git reset --hard ${headSha}`, { cwd, stdio: 'pipe', windowsHide: true });
464
+ (0, node_child_process_1.execSync)('git clean -fd .planning/phases/', { cwd, stdio: 'pipe', windowsHide: true });
465
+ }
466
+ catch {
467
+ // Swallow rollback errors — surface original error
468
+ }
469
+ throw new Error(`Migration failed (rolled back to ${headSha}): ${err.message}`);
470
+ }
471
+ return { applied: true, renamedDirs, editedFiles };
472
+ }
473
+ module.exports = {
474
+ computeMigrationPlan,
475
+ applyMigration,
476
+ };