@opengsd/get-shit-done-redux 1.0.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 (1466) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja-JP.md +870 -0
  3. package/README.ko-KR.md +861 -0
  4. package/README.md +300 -0
  5. package/README.pt-BR.md +492 -0
  6. package/README.zh-CN.md +842 -0
  7. package/agents/gsd-advisor-researcher.md +127 -0
  8. package/agents/gsd-ai-researcher.md +133 -0
  9. package/agents/gsd-assumptions-analyzer.md +105 -0
  10. package/agents/gsd-code-fixer.md +668 -0
  11. package/agents/gsd-code-reviewer.md +387 -0
  12. package/agents/gsd-codebase-mapper.md +853 -0
  13. package/agents/gsd-debug-session-manager.md +314 -0
  14. package/agents/gsd-debugger.md +1452 -0
  15. package/agents/gsd-doc-classifier.md +168 -0
  16. package/agents/gsd-doc-synthesizer.md +204 -0
  17. package/agents/gsd-doc-verifier.md +217 -0
  18. package/agents/gsd-doc-writer.md +615 -0
  19. package/agents/gsd-domain-researcher.md +153 -0
  20. package/agents/gsd-eval-auditor.md +191 -0
  21. package/agents/gsd-eval-planner.md +154 -0
  22. package/agents/gsd-executor.md +774 -0
  23. package/agents/gsd-framework-selector.md +160 -0
  24. package/agents/gsd-integration-checker.md +470 -0
  25. package/agents/gsd-intel-updater.md +342 -0
  26. package/agents/gsd-nyquist-auditor.md +203 -0
  27. package/agents/gsd-pattern-mapper.md +335 -0
  28. package/agents/gsd-phase-researcher.md +928 -0
  29. package/agents/gsd-plan-checker.md +978 -0
  30. package/agents/gsd-planner.md +1278 -0
  31. package/agents/gsd-project-researcher.md +677 -0
  32. package/agents/gsd-research-synthesizer.md +247 -0
  33. package/agents/gsd-roadmapper.md +688 -0
  34. package/agents/gsd-security-auditor.md +155 -0
  35. package/agents/gsd-ui-auditor.md +495 -0
  36. package/agents/gsd-ui-checker.md +309 -0
  37. package/agents/gsd-ui-researcher.md +380 -0
  38. package/agents/gsd-user-profiler.md +171 -0
  39. package/agents/gsd-verifier.md +917 -0
  40. package/bin/gsd-sdk.js +37 -0
  41. package/bin/install.js +11468 -0
  42. package/bin/lib/ui-safety-gate.cjs +107 -0
  43. package/commands/gsd/add-tests.md +42 -0
  44. package/commands/gsd/ai-integration-phase.md +37 -0
  45. package/commands/gsd/audit-fix.md +34 -0
  46. package/commands/gsd/audit-milestone.md +37 -0
  47. package/commands/gsd/audit-uat.md +24 -0
  48. package/commands/gsd/autonomous.md +46 -0
  49. package/commands/gsd/capture.md +62 -0
  50. package/commands/gsd/cleanup.md +24 -0
  51. package/commands/gsd/code-review.md +59 -0
  52. package/commands/gsd/complete-milestone.md +143 -0
  53. package/commands/gsd/config.md +58 -0
  54. package/commands/gsd/debug.md +52 -0
  55. package/commands/gsd/discuss-phase.md +76 -0
  56. package/commands/gsd/docs-update.md +49 -0
  57. package/commands/gsd/eval-review.md +33 -0
  58. package/commands/gsd/execute-phase.md +64 -0
  59. package/commands/gsd/explore.md +27 -0
  60. package/commands/gsd/extract-learnings.md +23 -0
  61. package/commands/gsd/fast.md +31 -0
  62. package/commands/gsd/forensics.md +57 -0
  63. package/commands/gsd/graphify.md +199 -0
  64. package/commands/gsd/health.md +31 -0
  65. package/commands/gsd/help.md +28 -0
  66. package/commands/gsd/import.md +41 -0
  67. package/commands/gsd/inbox.md +39 -0
  68. package/commands/gsd/ingest-docs.md +42 -0
  69. package/commands/gsd/manager.md +45 -0
  70. package/commands/gsd/map-codebase.md +83 -0
  71. package/commands/gsd/milestone-summary.md +51 -0
  72. package/commands/gsd/mvp-phase.md +45 -0
  73. package/commands/gsd/new-milestone.md +45 -0
  74. package/commands/gsd/new-project.md +47 -0
  75. package/commands/gsd/ns-context.md +23 -0
  76. package/commands/gsd/ns-ideate.md +24 -0
  77. package/commands/gsd/ns-manage.md +29 -0
  78. package/commands/gsd/ns-project.md +22 -0
  79. package/commands/gsd/ns-review.md +26 -0
  80. package/commands/gsd/ns-workflow.md +28 -0
  81. package/commands/gsd/pause-work.md +43 -0
  82. package/commands/gsd/phase.md +56 -0
  83. package/commands/gsd/plan-phase.md +62 -0
  84. package/commands/gsd/plan-review-convergence.md +59 -0
  85. package/commands/gsd/pr-branch.md +26 -0
  86. package/commands/gsd/profile-user.md +46 -0
  87. package/commands/gsd/progress.md +46 -0
  88. package/commands/gsd/quick.md +174 -0
  89. package/commands/gsd/resume-work.md +30 -0
  90. package/commands/gsd/review-backlog.md +63 -0
  91. package/commands/gsd/review.md +41 -0
  92. package/commands/gsd/secure-phase.md +36 -0
  93. package/commands/gsd/settings.md +29 -0
  94. package/commands/gsd/ship.md +24 -0
  95. package/commands/gsd/sketch.md +60 -0
  96. package/commands/gsd/spec-phase.md +63 -0
  97. package/commands/gsd/spike.md +57 -0
  98. package/commands/gsd/stats.md +19 -0
  99. package/commands/gsd/surface.md +155 -0
  100. package/commands/gsd/thread.md +24 -0
  101. package/commands/gsd/ui-phase.md +35 -0
  102. package/commands/gsd/ui-review.md +33 -0
  103. package/commands/gsd/ultraplan-phase.md +34 -0
  104. package/commands/gsd/undo.md +35 -0
  105. package/commands/gsd/update.md +48 -0
  106. package/commands/gsd/validate-phase.md +36 -0
  107. package/commands/gsd/verify-work.md +39 -0
  108. package/commands/gsd/workspace.md +52 -0
  109. package/commands/gsd/workstreams.md +70 -0
  110. package/get-shit-done/bin/check-latest-version.cjs +104 -0
  111. package/get-shit-done/bin/gsd-tools.cjs +1630 -0
  112. package/get-shit-done/bin/lib/active-workstream-store.cjs +85 -0
  113. package/get-shit-done/bin/lib/adr-parser.cjs +394 -0
  114. package/get-shit-done/bin/lib/artifacts.cjs +53 -0
  115. package/get-shit-done/bin/lib/audit.cjs +755 -0
  116. package/get-shit-done/bin/lib/cjs-command-router-adapter.cjs +39 -0
  117. package/get-shit-done/bin/lib/cjs-sdk-bridge.cjs +136 -0
  118. package/get-shit-done/bin/lib/clusters.cjs +135 -0
  119. package/get-shit-done/bin/lib/code-review-flags.cjs +74 -0
  120. package/get-shit-done/bin/lib/command-aliases.generated.cjs +824 -0
  121. package/get-shit-done/bin/lib/command-routing-hub.cjs +239 -0
  122. package/get-shit-done/bin/lib/commands.cjs +1035 -0
  123. package/get-shit-done/bin/lib/config-schema.cjs +31 -0
  124. package/get-shit-done/bin/lib/config.cjs +704 -0
  125. package/get-shit-done/bin/lib/configuration.generated.cjs +253 -0
  126. package/get-shit-done/bin/lib/context-utilization.cjs +47 -0
  127. package/get-shit-done/bin/lib/core.cjs +1922 -0
  128. package/get-shit-done/bin/lib/decisions.cjs +19 -0
  129. package/get-shit-done/bin/lib/decisions.generated.cjs +121 -0
  130. package/get-shit-done/bin/lib/docs.cjs +270 -0
  131. package/get-shit-done/bin/lib/drift.cjs +388 -0
  132. package/get-shit-done/bin/lib/fallow-runner.cjs +109 -0
  133. package/get-shit-done/bin/lib/frontmatter.cjs +389 -0
  134. package/get-shit-done/bin/lib/gap-checker.cjs +205 -0
  135. package/get-shit-done/bin/lib/graphify.cjs +592 -0
  136. package/get-shit-done/bin/lib/gsd2-import.cjs +514 -0
  137. package/get-shit-done/bin/lib/init-command-router.cjs +174 -0
  138. package/get-shit-done/bin/lib/init.cjs +2096 -0
  139. package/get-shit-done/bin/lib/install-profiles.cjs +603 -0
  140. package/get-shit-done/bin/lib/installer-migration-authoring.cjs +117 -0
  141. package/get-shit-done/bin/lib/installer-migration-report.cjs +354 -0
  142. package/get-shit-done/bin/lib/installer-migrations/000-first-time-baseline.cjs +220 -0
  143. package/get-shit-done/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +41 -0
  144. package/get-shit-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +80 -0
  145. package/get-shit-done/bin/lib/installer-migrations.cjs +776 -0
  146. package/get-shit-done/bin/lib/intel.cjs +643 -0
  147. package/get-shit-done/bin/lib/learnings.cjs +379 -0
  148. package/get-shit-done/bin/lib/milestone.cjs +314 -0
  149. package/get-shit-done/bin/lib/model-catalog.cjs +136 -0
  150. package/get-shit-done/bin/lib/model-profiles.cjs +25 -0
  151. package/get-shit-done/bin/lib/phase-command-router.cjs +226 -0
  152. package/get-shit-done/bin/lib/phase.cjs +1490 -0
  153. package/get-shit-done/bin/lib/phases-command-router.cjs +97 -0
  154. package/get-shit-done/bin/lib/plan-scan.cjs +26 -0
  155. package/get-shit-done/bin/lib/plan-scan.generated.cjs +97 -0
  156. package/get-shit-done/bin/lib/planning-workspace.cjs +415 -0
  157. package/get-shit-done/bin/lib/profile-output.cjs +1130 -0
  158. package/get-shit-done/bin/lib/profile-pipeline.cjs +539 -0
  159. package/get-shit-done/bin/lib/project-root.generated.cjs +117 -0
  160. package/get-shit-done/bin/lib/prompt-budget.cjs +399 -0
  161. package/get-shit-done/bin/lib/review-reviewer-selection.cjs +125 -0
  162. package/get-shit-done/bin/lib/roadmap-command-router.cjs +99 -0
  163. package/get-shit-done/bin/lib/roadmap.cjs +642 -0
  164. package/get-shit-done/bin/lib/runtime-artifact-layout.cjs +301 -0
  165. package/get-shit-done/bin/lib/runtime-homes.cjs +185 -0
  166. package/get-shit-done/bin/lib/runtime-slash.cjs +109 -0
  167. package/get-shit-done/bin/lib/schema-detect.cjs +21 -0
  168. package/get-shit-done/bin/lib/schema-detect.generated.cjs +170 -0
  169. package/get-shit-done/bin/lib/secrets.cjs +20 -0
  170. package/get-shit-done/bin/lib/secrets.generated.cjs +37 -0
  171. package/get-shit-done/bin/lib/security.cjs +504 -0
  172. package/get-shit-done/bin/lib/shell-command-projection.cjs +552 -0
  173. package/get-shit-done/bin/lib/state-command-router.cjs +346 -0
  174. package/get-shit-done/bin/lib/state-document.cjs +12 -0
  175. package/get-shit-done/bin/lib/state-document.generated.cjs +127 -0
  176. package/get-shit-done/bin/lib/state.cjs +1940 -0
  177. package/get-shit-done/bin/lib/surface.cjs +430 -0
  178. package/get-shit-done/bin/lib/template.cjs +228 -0
  179. package/get-shit-done/bin/lib/uat.cjs +289 -0
  180. package/get-shit-done/bin/lib/validate-command-router.cjs +129 -0
  181. package/get-shit-done/bin/lib/verify-command-router.cjs +122 -0
  182. package/get-shit-done/bin/lib/verify.cjs +1458 -0
  183. package/get-shit-done/bin/lib/workstream-inventory-builder.generated.cjs +79 -0
  184. package/get-shit-done/bin/lib/workstream-inventory.cjs +132 -0
  185. package/get-shit-done/bin/lib/workstream-name-policy.cjs +19 -0
  186. package/get-shit-done/bin/lib/workstream-name-policy.generated.cjs +61 -0
  187. package/get-shit-done/bin/lib/workstream.cjs +374 -0
  188. package/get-shit-done/bin/lib/worktree-safety.cjs +985 -0
  189. package/get-shit-done/bin/verify-reapply-patches.cjs +336 -0
  190. package/get-shit-done/contexts/dev.md +21 -0
  191. package/get-shit-done/contexts/research.md +22 -0
  192. package/get-shit-done/contexts/review.md +23 -0
  193. package/get-shit-done/references/agent-contracts.md +79 -0
  194. package/get-shit-done/references/ai-evals.md +156 -0
  195. package/get-shit-done/references/ai-frameworks.md +186 -0
  196. package/get-shit-done/references/artifact-types.md +131 -0
  197. package/get-shit-done/references/autonomous-smart-discuss.md +277 -0
  198. package/get-shit-done/references/checkpoints.md +814 -0
  199. package/get-shit-done/references/common-bug-patterns.md +114 -0
  200. package/get-shit-done/references/context-budget.md +85 -0
  201. package/get-shit-done/references/continuation-format.md +253 -0
  202. package/get-shit-done/references/debugger-philosophy.md +76 -0
  203. package/get-shit-done/references/decimal-phase-calculation.md +64 -0
  204. package/get-shit-done/references/doc-conflict-engine.md +91 -0
  205. package/get-shit-done/references/domain-probes.md +125 -0
  206. package/get-shit-done/references/execute-mvp-tdd.md +81 -0
  207. package/get-shit-done/references/executor-examples.md +110 -0
  208. package/get-shit-done/references/few-shot-examples/plan-checker.md +73 -0
  209. package/get-shit-done/references/few-shot-examples/verifier.md +109 -0
  210. package/get-shit-done/references/gate-prompts.md +100 -0
  211. package/get-shit-done/references/gates.md +70 -0
  212. package/get-shit-done/references/git-integration.md +298 -0
  213. package/get-shit-done/references/git-planning-commit.md +40 -0
  214. package/get-shit-done/references/ios-scaffold.md +123 -0
  215. package/get-shit-done/references/mandatory-initial-read.md +2 -0
  216. package/get-shit-done/references/model-profile-resolution.md +38 -0
  217. package/get-shit-done/references/model-profiles.md +245 -0
  218. package/get-shit-done/references/mvp-concepts.md +49 -0
  219. package/get-shit-done/references/phase-argument-parsing.md +61 -0
  220. package/get-shit-done/references/planner-antipatterns.md +89 -0
  221. package/get-shit-done/references/planner-chunked.md +49 -0
  222. package/get-shit-done/references/planner-gap-closure.md +62 -0
  223. package/get-shit-done/references/planner-graphify-auto-update.md +67 -0
  224. package/get-shit-done/references/planner-human-verify-mode.md +57 -0
  225. package/get-shit-done/references/planner-mvp-mode.md +53 -0
  226. package/get-shit-done/references/planner-reviews.md +39 -0
  227. package/get-shit-done/references/planner-revision.md +87 -0
  228. package/get-shit-done/references/planner-source-audit.md +73 -0
  229. package/get-shit-done/references/planning-config.md +471 -0
  230. package/get-shit-done/references/project-skills-discovery.md +19 -0
  231. package/get-shit-done/references/questioning.md +162 -0
  232. package/get-shit-done/references/revision-loop.md +97 -0
  233. package/get-shit-done/references/scout-codebase.md +51 -0
  234. package/get-shit-done/references/skeleton-template.md +48 -0
  235. package/get-shit-done/references/sketch-interactivity.md +41 -0
  236. package/get-shit-done/references/sketch-theme-system.md +94 -0
  237. package/get-shit-done/references/sketch-tooling.md +45 -0
  238. package/get-shit-done/references/sketch-variant-patterns.md +81 -0
  239. package/get-shit-done/references/spidr-splitting.md +69 -0
  240. package/get-shit-done/references/tdd.md +330 -0
  241. package/get-shit-done/references/thinking-models-debug.md +44 -0
  242. package/get-shit-done/references/thinking-models-execution.md +50 -0
  243. package/get-shit-done/references/thinking-models-planning.md +62 -0
  244. package/get-shit-done/references/thinking-models-research.md +50 -0
  245. package/get-shit-done/references/thinking-models-verification.md +55 -0
  246. package/get-shit-done/references/thinking-partner.md +96 -0
  247. package/get-shit-done/references/ui-brand.md +160 -0
  248. package/get-shit-done/references/universal-anti-patterns.md +63 -0
  249. package/get-shit-done/references/user-profiling.md +681 -0
  250. package/get-shit-done/references/user-story-template.md +58 -0
  251. package/get-shit-done/references/verification-overrides.md +227 -0
  252. package/get-shit-done/references/verification-patterns.md +612 -0
  253. package/get-shit-done/references/verify-mvp-mode.md +85 -0
  254. package/get-shit-done/references/workstream-flag.md +111 -0
  255. package/get-shit-done/references/worktree-path-safety.md +89 -0
  256. package/get-shit-done/templates/AI-SPEC.md +246 -0
  257. package/get-shit-done/templates/DEBUG.md +169 -0
  258. package/get-shit-done/templates/README.md +77 -0
  259. package/get-shit-done/templates/SECURITY.md +61 -0
  260. package/get-shit-done/templates/UAT.md +265 -0
  261. package/get-shit-done/templates/UI-SPEC.md +100 -0
  262. package/get-shit-done/templates/VALIDATION.md +76 -0
  263. package/get-shit-done/templates/claude-md.md +145 -0
  264. package/get-shit-done/templates/codebase/architecture.md +255 -0
  265. package/get-shit-done/templates/codebase/concerns.md +310 -0
  266. package/get-shit-done/templates/codebase/conventions.md +307 -0
  267. package/get-shit-done/templates/codebase/integrations.md +280 -0
  268. package/get-shit-done/templates/codebase/stack.md +186 -0
  269. package/get-shit-done/templates/codebase/structure.md +285 -0
  270. package/get-shit-done/templates/codebase/testing.md +480 -0
  271. package/get-shit-done/templates/config.json +62 -0
  272. package/get-shit-done/templates/context.md +352 -0
  273. package/get-shit-done/templates/continue-here.md +78 -0
  274. package/get-shit-done/templates/copilot-instructions.md +7 -0
  275. package/get-shit-done/templates/debug-subagent-prompt.md +91 -0
  276. package/get-shit-done/templates/dev-preferences.md +21 -0
  277. package/get-shit-done/templates/discovery.md +146 -0
  278. package/get-shit-done/templates/discussion-log.md +63 -0
  279. package/get-shit-done/templates/milestone-archive.md +123 -0
  280. package/get-shit-done/templates/milestone.md +115 -0
  281. package/get-shit-done/templates/phase-prompt.md +610 -0
  282. package/get-shit-done/templates/planner-subagent-prompt.md +117 -0
  283. package/get-shit-done/templates/project.md +186 -0
  284. package/get-shit-done/templates/requirements.md +231 -0
  285. package/get-shit-done/templates/research-project/ARCHITECTURE.md +204 -0
  286. package/get-shit-done/templates/research-project/FEATURES.md +147 -0
  287. package/get-shit-done/templates/research-project/PITFALLS.md +200 -0
  288. package/get-shit-done/templates/research-project/STACK.md +120 -0
  289. package/get-shit-done/templates/research-project/SUMMARY.md +170 -0
  290. package/get-shit-done/templates/research.md +592 -0
  291. package/get-shit-done/templates/retrospective.md +54 -0
  292. package/get-shit-done/templates/roadmap.md +202 -0
  293. package/get-shit-done/templates/spec.md +307 -0
  294. package/get-shit-done/templates/state.md +184 -0
  295. package/get-shit-done/templates/summary-complex.md +59 -0
  296. package/get-shit-done/templates/summary-minimal.md +41 -0
  297. package/get-shit-done/templates/summary-standard.md +48 -0
  298. package/get-shit-done/templates/summary.md +248 -0
  299. package/get-shit-done/templates/user-profile.md +146 -0
  300. package/get-shit-done/templates/user-setup.md +311 -0
  301. package/get-shit-done/templates/verification-report.md +322 -0
  302. package/get-shit-done/workflows/add-backlog.md +101 -0
  303. package/get-shit-done/workflows/add-phase.md +123 -0
  304. package/get-shit-done/workflows/add-tests.md +365 -0
  305. package/get-shit-done/workflows/add-todo.md +171 -0
  306. package/get-shit-done/workflows/ai-integration-phase.md +305 -0
  307. package/get-shit-done/workflows/analyze-dependencies.md +96 -0
  308. package/get-shit-done/workflows/audit-fix.md +188 -0
  309. package/get-shit-done/workflows/audit-milestone.md +368 -0
  310. package/get-shit-done/workflows/audit-uat.md +120 -0
  311. package/get-shit-done/workflows/autonomous.md +805 -0
  312. package/get-shit-done/workflows/check-todos.md +190 -0
  313. package/get-shit-done/workflows/cleanup.md +165 -0
  314. package/get-shit-done/workflows/code-review-fix.md +512 -0
  315. package/get-shit-done/workflows/code-review.md +666 -0
  316. package/get-shit-done/workflows/complete-milestone.md +865 -0
  317. package/get-shit-done/workflows/debug.md +242 -0
  318. package/get-shit-done/workflows/diagnose-issues.md +251 -0
  319. package/get-shit-done/workflows/discovery-phase.md +291 -0
  320. package/get-shit-done/workflows/discuss-phase/modes/advisor.md +175 -0
  321. package/get-shit-done/workflows/discuss-phase/modes/all.md +28 -0
  322. package/get-shit-done/workflows/discuss-phase/modes/analyze.md +44 -0
  323. package/get-shit-done/workflows/discuss-phase/modes/auto.md +56 -0
  324. package/get-shit-done/workflows/discuss-phase/modes/batch.md +52 -0
  325. package/get-shit-done/workflows/discuss-phase/modes/chain.md +97 -0
  326. package/get-shit-done/workflows/discuss-phase/modes/default.md +141 -0
  327. package/get-shit-done/workflows/discuss-phase/modes/power.md +44 -0
  328. package/get-shit-done/workflows/discuss-phase/modes/text.md +55 -0
  329. package/get-shit-done/workflows/discuss-phase/templates/checkpoint.json +18 -0
  330. package/get-shit-done/workflows/discuss-phase/templates/context.md +136 -0
  331. package/get-shit-done/workflows/discuss-phase/templates/discussion-log.md +50 -0
  332. package/get-shit-done/workflows/discuss-phase-assumptions.md +685 -0
  333. package/get-shit-done/workflows/discuss-phase-power.md +291 -0
  334. package/get-shit-done/workflows/discuss-phase.md +499 -0
  335. package/get-shit-done/workflows/do.md +122 -0
  336. package/get-shit-done/workflows/docs-update.md +1172 -0
  337. package/get-shit-done/workflows/edit-phase.md +305 -0
  338. package/get-shit-done/workflows/eval-review.md +166 -0
  339. package/get-shit-done/workflows/execute-phase/steps/codebase-drift-gate.md +81 -0
  340. package/get-shit-done/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
  341. package/get-shit-done/workflows/execute-phase/steps/post-merge-gate.md +116 -0
  342. package/get-shit-done/workflows/execute-phase.md +1717 -0
  343. package/get-shit-done/workflows/execute-plan.md +536 -0
  344. package/get-shit-done/workflows/explore.md +154 -0
  345. package/get-shit-done/workflows/extract-learnings.md +253 -0
  346. package/get-shit-done/workflows/fast.md +124 -0
  347. package/get-shit-done/workflows/forensics.md +289 -0
  348. package/get-shit-done/workflows/graduation.md +206 -0
  349. package/get-shit-done/workflows/health.md +234 -0
  350. package/get-shit-done/workflows/help/modes/brief.md +22 -0
  351. package/get-shit-done/workflows/help/modes/default.md +50 -0
  352. package/get-shit-done/workflows/help/modes/full.md +784 -0
  353. package/get-shit-done/workflows/help/modes/topic.md +74 -0
  354. package/get-shit-done/workflows/help.md +24 -0
  355. package/get-shit-done/workflows/import.md +264 -0
  356. package/get-shit-done/workflows/inbox.md +387 -0
  357. package/get-shit-done/workflows/ingest-docs.md +339 -0
  358. package/get-shit-done/workflows/insert-phase.md +162 -0
  359. package/get-shit-done/workflows/list-phase-assumptions.md +178 -0
  360. package/get-shit-done/workflows/list-workspaces.md +67 -0
  361. package/get-shit-done/workflows/manager.md +403 -0
  362. package/get-shit-done/workflows/map-codebase.md +454 -0
  363. package/get-shit-done/workflows/milestone-summary.md +234 -0
  364. package/get-shit-done/workflows/mvp-phase.md +232 -0
  365. package/get-shit-done/workflows/new-milestone.md +645 -0
  366. package/get-shit-done/workflows/new-project.md +1487 -0
  367. package/get-shit-done/workflows/new-workspace.md +250 -0
  368. package/get-shit-done/workflows/next.md +231 -0
  369. package/get-shit-done/workflows/node-repair.md +92 -0
  370. package/get-shit-done/workflows/note.md +158 -0
  371. package/get-shit-done/workflows/pause-work.md +254 -0
  372. package/get-shit-done/workflows/plan-milestone-gaps.md +291 -0
  373. package/get-shit-done/workflows/plan-phase.md +1800 -0
  374. package/get-shit-done/workflows/plan-review-convergence.md +340 -0
  375. package/get-shit-done/workflows/plant-seed.md +240 -0
  376. package/get-shit-done/workflows/pr-branch.md +157 -0
  377. package/get-shit-done/workflows/profile-user.md +463 -0
  378. package/get-shit-done/workflows/progress.md +660 -0
  379. package/get-shit-done/workflows/quick.md +1049 -0
  380. package/get-shit-done/workflows/reapply-patches.md +426 -0
  381. package/get-shit-done/workflows/remove-phase.md +166 -0
  382. package/get-shit-done/workflows/remove-workspace.md +118 -0
  383. package/get-shit-done/workflows/resume-project.md +342 -0
  384. package/get-shit-done/workflows/review.md +633 -0
  385. package/get-shit-done/workflows/scan.md +115 -0
  386. package/get-shit-done/workflows/secure-phase.md +190 -0
  387. package/get-shit-done/workflows/session-report.md +146 -0
  388. package/get-shit-done/workflows/settings-advanced.md +590 -0
  389. package/get-shit-done/workflows/settings-integrations.md +292 -0
  390. package/get-shit-done/workflows/settings.md +545 -0
  391. package/get-shit-done/workflows/ship.md +366 -0
  392. package/get-shit-done/workflows/sketch-wrap-up.md +296 -0
  393. package/get-shit-done/workflows/sketch.md +371 -0
  394. package/get-shit-done/workflows/spec-phase.md +262 -0
  395. package/get-shit-done/workflows/spike-wrap-up.md +317 -0
  396. package/get-shit-done/workflows/spike.md +463 -0
  397. package/get-shit-done/workflows/stats.md +90 -0
  398. package/get-shit-done/workflows/sync-skills.md +182 -0
  399. package/get-shit-done/workflows/thread.md +232 -0
  400. package/get-shit-done/workflows/transition.md +704 -0
  401. package/get-shit-done/workflows/ui-phase.md +338 -0
  402. package/get-shit-done/workflows/ui-review.md +203 -0
  403. package/get-shit-done/workflows/ultraplan-phase.md +209 -0
  404. package/get-shit-done/workflows/undo.md +314 -0
  405. package/get-shit-done/workflows/update.md +664 -0
  406. package/get-shit-done/workflows/validate-phase.md +189 -0
  407. package/get-shit-done/workflows/verify-phase.md +554 -0
  408. package/get-shit-done/workflows/verify-work.md +791 -0
  409. package/hooks/dist/gsd-check-update-worker.js +117 -0
  410. package/hooks/dist/gsd-check-update.js +64 -0
  411. package/hooks/dist/gsd-context-monitor.js +192 -0
  412. package/hooks/dist/gsd-graphify-update.sh +158 -0
  413. package/hooks/dist/gsd-phase-boundary.sh +47 -0
  414. package/hooks/dist/gsd-prompt-guard.js +97 -0
  415. package/hooks/dist/gsd-read-guard.js +101 -0
  416. package/hooks/dist/gsd-read-injection-scanner.js +152 -0
  417. package/hooks/dist/gsd-session-state.sh +59 -0
  418. package/hooks/dist/gsd-statusline.js +537 -0
  419. package/hooks/dist/gsd-update-banner.js +134 -0
  420. package/hooks/dist/gsd-validate-commit.sh +57 -0
  421. package/hooks/dist/gsd-workflow-guard.js +94 -0
  422. package/hooks/dist/lib/git-cmd.js +150 -0
  423. package/hooks/dist/lib/gsd-graphify-rebuild.sh +65 -0
  424. package/hooks/gsd-check-update-worker.js +117 -0
  425. package/hooks/gsd-check-update.js +64 -0
  426. package/hooks/gsd-context-monitor.js +192 -0
  427. package/hooks/gsd-graphify-update.sh +158 -0
  428. package/hooks/gsd-phase-boundary.sh +47 -0
  429. package/hooks/gsd-prompt-guard.js +97 -0
  430. package/hooks/gsd-read-guard.js +101 -0
  431. package/hooks/gsd-read-injection-scanner.js +152 -0
  432. package/hooks/gsd-session-state.sh +59 -0
  433. package/hooks/gsd-statusline.js +537 -0
  434. package/hooks/gsd-update-banner.js +134 -0
  435. package/hooks/gsd-validate-commit.sh +57 -0
  436. package/hooks/gsd-workflow-guard.js +94 -0
  437. package/hooks/lib/git-cmd.js +150 -0
  438. package/hooks/lib/gsd-graphify-rebuild.sh +65 -0
  439. package/package.json +98 -0
  440. package/scripts/audit-workflow-script-paths.cjs +73 -0
  441. package/scripts/base64-scan.sh +262 -0
  442. package/scripts/build-hooks.js +227 -0
  443. package/scripts/changeset/cli.cjs +408 -0
  444. package/scripts/changeset/github-release-notes.cjs +198 -0
  445. package/scripts/changeset/lint.cjs +110 -0
  446. package/scripts/changeset/new.cjs +137 -0
  447. package/scripts/changeset/parse.cjs +114 -0
  448. package/scripts/changeset/render.cjs +34 -0
  449. package/scripts/changeset/serialize.cjs +130 -0
  450. package/scripts/command-contract-helpers.cjs +64 -0
  451. package/scripts/diff-touches-shipped-paths.cjs +147 -0
  452. package/scripts/fix-slash-commands.cjs +147 -0
  453. package/scripts/gen-inventory-manifest.cjs +109 -0
  454. package/scripts/lint-command-contract.cjs +108 -0
  455. package/scripts/lint-descriptions.cjs +83 -0
  456. package/scripts/lint-docs-required.cjs +222 -0
  457. package/scripts/lint-no-source-grep-extras.cjs +81 -0
  458. package/scripts/lint-no-source-grep.cjs +174 -0
  459. package/scripts/lint-pr-check-project-dir.cjs +98 -0
  460. package/scripts/lint-shared-module-handsync.cjs +331 -0
  461. package/scripts/lint-shell-command-projection-drift.cjs +57 -0
  462. package/scripts/lint-skill-deps.cjs +180 -0
  463. package/scripts/lint-test-file-count.allowlist.json +35 -0
  464. package/scripts/lint-test-file-count.cjs +190 -0
  465. package/scripts/pr-template-policy.cjs +268 -0
  466. package/scripts/prompt-injection-scan.sh +203 -0
  467. package/scripts/release-tarball-smoke.cjs +677 -0
  468. package/scripts/run-tests.cjs +178 -0
  469. package/scripts/secret-scan.sh +229 -0
  470. package/scripts/shared-module-handsync-allowlist.json +145 -0
  471. package/scripts/strip-prose-atrefs.cjs +106 -0
  472. package/scripts/sync-rulesets.sh +34 -0
  473. package/scripts/verify-tarball-sdk-dist.sh +69 -0
  474. package/sdk/dist/cli-transport.d.ts +19 -0
  475. package/sdk/dist/cli-transport.d.ts.map +1 -0
  476. package/sdk/dist/cli-transport.js +104 -0
  477. package/sdk/dist/cli-transport.js.map +1 -0
  478. package/sdk/dist/cli.d.ts +46 -0
  479. package/sdk/dist/cli.d.ts.map +1 -0
  480. package/sdk/dist/cli.js +511 -0
  481. package/sdk/dist/cli.js.map +1 -0
  482. package/sdk/dist/config.d.ts +108 -0
  483. package/sdk/dist/config.d.ts.map +1 -0
  484. package/sdk/dist/config.js +116 -0
  485. package/sdk/dist/config.js.map +1 -0
  486. package/sdk/dist/configuration/index.d.ts +85 -0
  487. package/sdk/dist/configuration/index.d.ts.map +1 -0
  488. package/sdk/dist/configuration/index.js +257 -0
  489. package/sdk/dist/configuration/index.js.map +1 -0
  490. package/sdk/dist/context-engine.d.ts +49 -0
  491. package/sdk/dist/context-engine.d.ts.map +1 -0
  492. package/sdk/dist/context-engine.js +142 -0
  493. package/sdk/dist/context-engine.js.map +1 -0
  494. package/sdk/dist/context-truncation.d.ts +33 -0
  495. package/sdk/dist/context-truncation.d.ts.map +1 -0
  496. package/sdk/dist/context-truncation.js +197 -0
  497. package/sdk/dist/context-truncation.js.map +1 -0
  498. package/sdk/dist/errors.d.ts +46 -0
  499. package/sdk/dist/errors.d.ts.map +1 -0
  500. package/sdk/dist/errors.js +64 -0
  501. package/sdk/dist/errors.js.map +1 -0
  502. package/sdk/dist/event-stream.d.ts +53 -0
  503. package/sdk/dist/event-stream.d.ts.map +1 -0
  504. package/sdk/dist/event-stream.js +321 -0
  505. package/sdk/dist/event-stream.js.map +1 -0
  506. package/sdk/dist/golden/capture.d.ts +15 -0
  507. package/sdk/dist/golden/capture.d.ts.map +1 -0
  508. package/sdk/dist/golden/capture.js +67 -0
  509. package/sdk/dist/golden/capture.js.map +1 -0
  510. package/sdk/dist/golden/golden-integration-covered.d.ts +6 -0
  511. package/sdk/dist/golden/golden-integration-covered.d.ts.map +1 -0
  512. package/sdk/dist/golden/golden-integration-covered.js +30 -0
  513. package/sdk/dist/golden/golden-integration-covered.js.map +1 -0
  514. package/sdk/dist/golden/golden-mutation-covered.d.ts +7 -0
  515. package/sdk/dist/golden/golden-mutation-covered.d.ts.map +1 -0
  516. package/sdk/dist/golden/golden-mutation-covered.js +17 -0
  517. package/sdk/dist/golden/golden-mutation-covered.js.map +1 -0
  518. package/sdk/dist/golden/golden-policy.d.ts +10 -0
  519. package/sdk/dist/golden/golden-policy.d.ts.map +1 -0
  520. package/sdk/dist/golden/golden-policy.js +98 -0
  521. package/sdk/dist/golden/golden-policy.js.map +1 -0
  522. package/sdk/dist/golden/init-golden-normalize.d.ts +8 -0
  523. package/sdk/dist/golden/init-golden-normalize.d.ts.map +1 -0
  524. package/sdk/dist/golden/init-golden-normalize.js +14 -0
  525. package/sdk/dist/golden/init-golden-normalize.js.map +1 -0
  526. package/sdk/dist/golden/read-only-golden-rows.d.ts +20 -0
  527. package/sdk/dist/golden/read-only-golden-rows.d.ts.map +1 -0
  528. package/sdk/dist/golden/read-only-golden-rows.js +67 -0
  529. package/sdk/dist/golden/read-only-golden-rows.js.map +1 -0
  530. package/sdk/dist/golden/registry-canonical-commands.d.ts +6 -0
  531. package/sdk/dist/golden/registry-canonical-commands.d.ts.map +1 -0
  532. package/sdk/dist/golden/registry-canonical-commands.js +30 -0
  533. package/sdk/dist/golden/registry-canonical-commands.js.map +1 -0
  534. package/sdk/dist/gsd-tools-error.d.ts +23 -0
  535. package/sdk/dist/gsd-tools-error.d.ts.map +1 -0
  536. package/sdk/dist/gsd-tools-error.js +29 -0
  537. package/sdk/dist/gsd-tools-error.js.map +1 -0
  538. package/sdk/dist/gsd-tools.d.ts +97 -0
  539. package/sdk/dist/gsd-tools.d.ts.map +1 -0
  540. package/sdk/dist/gsd-tools.js +168 -0
  541. package/sdk/dist/gsd-tools.js.map +1 -0
  542. package/sdk/dist/gsd-transport-policy.d.ts +10 -0
  543. package/sdk/dist/gsd-transport-policy.d.ts.map +1 -0
  544. package/sdk/dist/gsd-transport-policy.js +32 -0
  545. package/sdk/dist/gsd-transport-policy.js.map +1 -0
  546. package/sdk/dist/gsd-transport.d.ts +39 -0
  547. package/sdk/dist/gsd-transport.d.ts.map +1 -0
  548. package/sdk/dist/gsd-transport.js +78 -0
  549. package/sdk/dist/gsd-transport.js.map +1 -0
  550. package/sdk/dist/index.d.ts +127 -0
  551. package/sdk/dist/index.d.ts.map +1 -0
  552. package/sdk/dist/index.js +300 -0
  553. package/sdk/dist/index.js.map +1 -0
  554. package/sdk/dist/init-runner.d.ts +90 -0
  555. package/sdk/dist/init-runner.d.ts.map +1 -0
  556. package/sdk/dist/init-runner.js +613 -0
  557. package/sdk/dist/init-runner.js.map +1 -0
  558. package/sdk/dist/logger.d.ts +50 -0
  559. package/sdk/dist/logger.d.ts.map +1 -0
  560. package/sdk/dist/logger.js +70 -0
  561. package/sdk/dist/logger.js.map +1 -0
  562. package/sdk/dist/model-catalog.d.ts +31 -0
  563. package/sdk/dist/model-catalog.d.ts.map +1 -0
  564. package/sdk/dist/model-catalog.js +31 -0
  565. package/sdk/dist/model-catalog.js.map +1 -0
  566. package/sdk/dist/phase-prompt.d.ts +72 -0
  567. package/sdk/dist/phase-prompt.d.ts.map +1 -0
  568. package/sdk/dist/phase-prompt.js +213 -0
  569. package/sdk/dist/phase-prompt.js.map +1 -0
  570. package/sdk/dist/phase-runner.d.ts +145 -0
  571. package/sdk/dist/phase-runner.d.ts.map +1 -0
  572. package/sdk/dist/phase-runner.js +1206 -0
  573. package/sdk/dist/phase-runner.js.map +1 -0
  574. package/sdk/dist/plan-parser.d.ts +55 -0
  575. package/sdk/dist/plan-parser.d.ts.map +1 -0
  576. package/sdk/dist/plan-parser.js +389 -0
  577. package/sdk/dist/plan-parser.js.map +1 -0
  578. package/sdk/dist/planning-journal.d.ts +64 -0
  579. package/sdk/dist/planning-journal.d.ts.map +1 -0
  580. package/sdk/dist/planning-journal.js +88 -0
  581. package/sdk/dist/planning-journal.js.map +1 -0
  582. package/sdk/dist/planning-runtime.d.ts +67 -0
  583. package/sdk/dist/planning-runtime.d.ts.map +1 -0
  584. package/sdk/dist/planning-runtime.js +58 -0
  585. package/sdk/dist/planning-runtime.js.map +1 -0
  586. package/sdk/dist/project-root/index.d.ts +46 -0
  587. package/sdk/dist/project-root/index.d.ts.map +1 -0
  588. package/sdk/dist/project-root/index.js +138 -0
  589. package/sdk/dist/project-root/index.js.map +1 -0
  590. package/sdk/dist/prompt-builder.d.ts +44 -0
  591. package/sdk/dist/prompt-builder.d.ts.map +1 -0
  592. package/sdk/dist/prompt-builder.js +180 -0
  593. package/sdk/dist/prompt-builder.js.map +1 -0
  594. package/sdk/dist/prompt-sanitizer.d.ts +35 -0
  595. package/sdk/dist/prompt-sanitizer.d.ts.map +1 -0
  596. package/sdk/dist/prompt-sanitizer.js +101 -0
  597. package/sdk/dist/prompt-sanitizer.js.map +1 -0
  598. package/sdk/dist/query/active-workstream-store.d.ts +7 -0
  599. package/sdk/dist/query/active-workstream-store.d.ts.map +1 -0
  600. package/sdk/dist/query/active-workstream-store.js +56 -0
  601. package/sdk/dist/query/active-workstream-store.js.map +1 -0
  602. package/sdk/dist/query/agent-failure-classifier.d.ts +38 -0
  603. package/sdk/dist/query/agent-failure-classifier.d.ts.map +1 -0
  604. package/sdk/dist/query/agent-failure-classifier.js +83 -0
  605. package/sdk/dist/query/agent-failure-classifier.js.map +1 -0
  606. package/sdk/dist/query/audit-open.d.ts +46 -0
  607. package/sdk/dist/query/audit-open.d.ts.map +1 -0
  608. package/sdk/dist/query/audit-open.js +662 -0
  609. package/sdk/dist/query/audit-open.js.map +1 -0
  610. package/sdk/dist/query/check-auto-mode.d.ts +13 -0
  611. package/sdk/dist/query/check-auto-mode.d.ts.map +1 -0
  612. package/sdk/dist/query/check-auto-mode.js +40 -0
  613. package/sdk/dist/query/check-auto-mode.js.map +1 -0
  614. package/sdk/dist/query/check-completion.d.ts +10 -0
  615. package/sdk/dist/query/check-completion.d.ts.map +1 -0
  616. package/sdk/dist/query/check-completion.js +157 -0
  617. package/sdk/dist/query/check-completion.js.map +1 -0
  618. package/sdk/dist/query/check-decision-coverage.d.ts +33 -0
  619. package/sdk/dist/query/check-decision-coverage.d.ts.map +1 -0
  620. package/sdk/dist/query/check-decision-coverage.js +472 -0
  621. package/sdk/dist/query/check-decision-coverage.js.map +1 -0
  622. package/sdk/dist/query/check-gates.d.ts +10 -0
  623. package/sdk/dist/query/check-gates.d.ts.map +1 -0
  624. package/sdk/dist/query/check-gates.js +89 -0
  625. package/sdk/dist/query/check-gates.js.map +1 -0
  626. package/sdk/dist/query/check-ship-ready.d.ts +17 -0
  627. package/sdk/dist/query/check-ship-ready.d.ts.map +1 -0
  628. package/sdk/dist/query/check-ship-ready.js +121 -0
  629. package/sdk/dist/query/check-ship-ready.js.map +1 -0
  630. package/sdk/dist/query/check-verification-status.d.ts +10 -0
  631. package/sdk/dist/query/check-verification-status.d.ts.map +1 -0
  632. package/sdk/dist/query/check-verification-status.js +142 -0
  633. package/sdk/dist/query/check-verification-status.js.map +1 -0
  634. package/sdk/dist/query/command-aliases.generated.d.ts +31 -0
  635. package/sdk/dist/query/command-aliases.generated.d.ts.map +1 -0
  636. package/sdk/dist/query/command-aliases.generated.js +133 -0
  637. package/sdk/dist/query/command-aliases.generated.js.map +1 -0
  638. package/sdk/dist/query/command-catalog.d.ts +9 -0
  639. package/sdk/dist/query/command-catalog.d.ts.map +1 -0
  640. package/sdk/dist/query/command-catalog.js +17 -0
  641. package/sdk/dist/query/command-catalog.js.map +1 -0
  642. package/sdk/dist/query/command-definition.d.ts +19 -0
  643. package/sdk/dist/query/command-definition.d.ts.map +1 -0
  644. package/sdk/dist/query/command-definition.js +44 -0
  645. package/sdk/dist/query/command-definition.js.map +1 -0
  646. package/sdk/dist/query/command-family-handlers.d.ts +3 -0
  647. package/sdk/dist/query/command-family-handlers.d.ts.map +1 -0
  648. package/sdk/dist/query/command-family-handlers.js +101 -0
  649. package/sdk/dist/query/command-family-handlers.js.map +1 -0
  650. package/sdk/dist/query/command-manifest.d.ts +2 -0
  651. package/sdk/dist/query/command-manifest.d.ts.map +1 -0
  652. package/sdk/dist/query/command-manifest.init.d.ts +6 -0
  653. package/sdk/dist/query/command-manifest.init.d.ts.map +1 -0
  654. package/sdk/dist/query/command-manifest.init.js +23 -0
  655. package/sdk/dist/query/command-manifest.init.js.map +1 -0
  656. package/sdk/dist/query/command-manifest.js +17 -0
  657. package/sdk/dist/query/command-manifest.js.map +1 -0
  658. package/sdk/dist/query/command-manifest.non-family.d.ts +9 -0
  659. package/sdk/dist/query/command-manifest.non-family.d.ts.map +1 -0
  660. package/sdk/dist/query/command-manifest.non-family.js +60 -0
  661. package/sdk/dist/query/command-manifest.non-family.js.map +1 -0
  662. package/sdk/dist/query/command-manifest.phase.d.ts +6 -0
  663. package/sdk/dist/query/command-manifest.phase.d.ts.map +1 -0
  664. package/sdk/dist/query/command-manifest.phase.js +16 -0
  665. package/sdk/dist/query/command-manifest.phase.js.map +1 -0
  666. package/sdk/dist/query/command-manifest.phases.d.ts +7 -0
  667. package/sdk/dist/query/command-manifest.phases.d.ts.map +1 -0
  668. package/sdk/dist/query/command-manifest.phases.js +10 -0
  669. package/sdk/dist/query/command-manifest.phases.js.map +1 -0
  670. package/sdk/dist/query/command-manifest.roadmap.d.ts +6 -0
  671. package/sdk/dist/query/command-manifest.roadmap.d.ts.map +1 -0
  672. package/sdk/dist/query/command-manifest.roadmap.js +10 -0
  673. package/sdk/dist/query/command-manifest.roadmap.js.map +1 -0
  674. package/sdk/dist/query/command-manifest.state.d.ts +9 -0
  675. package/sdk/dist/query/command-manifest.state.d.ts.map +1 -0
  676. package/sdk/dist/query/command-manifest.state.js +30 -0
  677. package/sdk/dist/query/command-manifest.state.js.map +1 -0
  678. package/sdk/dist/query/command-manifest.types.d.ts +12 -0
  679. package/sdk/dist/query/command-manifest.types.d.ts.map +1 -0
  680. package/sdk/dist/query/command-manifest.types.js +2 -0
  681. package/sdk/dist/query/command-manifest.types.js.map +1 -0
  682. package/sdk/dist/query/command-manifest.validate.d.ts +6 -0
  683. package/sdk/dist/query/command-manifest.validate.d.ts.map +1 -0
  684. package/sdk/dist/query/command-manifest.validate.js +10 -0
  685. package/sdk/dist/query/command-manifest.validate.js.map +1 -0
  686. package/sdk/dist/query/command-manifest.verify.d.ts +6 -0
  687. package/sdk/dist/query/command-manifest.verify.d.ts.map +1 -0
  688. package/sdk/dist/query/command-manifest.verify.js +16 -0
  689. package/sdk/dist/query/command-manifest.verify.js.map +1 -0
  690. package/sdk/dist/query/command-static-catalog-domain.d.ts +3 -0
  691. package/sdk/dist/query/command-static-catalog-domain.d.ts.map +1 -0
  692. package/sdk/dist/query/command-static-catalog-domain.js +110 -0
  693. package/sdk/dist/query/command-static-catalog-domain.js.map +1 -0
  694. package/sdk/dist/query/command-static-catalog-foundation.d.ts +7 -0
  695. package/sdk/dist/query/command-static-catalog-foundation.d.ts.map +1 -0
  696. package/sdk/dist/query/command-static-catalog-foundation.js +106 -0
  697. package/sdk/dist/query/command-static-catalog-foundation.js.map +1 -0
  698. package/sdk/dist/query/command-topology.d.ts +32 -0
  699. package/sdk/dist/query/command-topology.d.ts.map +1 -0
  700. package/sdk/dist/query/command-topology.js +66 -0
  701. package/sdk/dist/query/command-topology.js.map +1 -0
  702. package/sdk/dist/query/commands-list.d.ts +14 -0
  703. package/sdk/dist/query/commands-list.d.ts.map +1 -0
  704. package/sdk/dist/query/commands-list.js +18 -0
  705. package/sdk/dist/query/commands-list.js.map +1 -0
  706. package/sdk/dist/query/commit.d.ts +179 -0
  707. package/sdk/dist/query/commit.d.ts.map +1 -0
  708. package/sdk/dist/query/commit.js +632 -0
  709. package/sdk/dist/query/commit.js.map +1 -0
  710. package/sdk/dist/query/config-gates.d.ts +12 -0
  711. package/sdk/dist/query/config-gates.d.ts.map +1 -0
  712. package/sdk/dist/query/config-gates.js +66 -0
  713. package/sdk/dist/query/config-gates.js.map +1 -0
  714. package/sdk/dist/query/config-mutation.d.ts +86 -0
  715. package/sdk/dist/query/config-mutation.d.ts.map +1 -0
  716. package/sdk/dist/query/config-mutation.js +602 -0
  717. package/sdk/dist/query/config-mutation.js.map +1 -0
  718. package/sdk/dist/query/config-query.d.ts +57 -0
  719. package/sdk/dist/query/config-query.d.ts.map +1 -0
  720. package/sdk/dist/query/config-query.js +277 -0
  721. package/sdk/dist/query/config-query.js.map +1 -0
  722. package/sdk/dist/query/config-schema.d.ts +19 -0
  723. package/sdk/dist/query/config-schema.d.ts.map +1 -0
  724. package/sdk/dist/query/config-schema.js +26 -0
  725. package/sdk/dist/query/config-schema.js.map +1 -0
  726. package/sdk/dist/query/decisions.d.ts +58 -0
  727. package/sdk/dist/query/decisions.d.ts.map +1 -0
  728. package/sdk/dist/query/decisions.js +165 -0
  729. package/sdk/dist/query/decisions.js.map +1 -0
  730. package/sdk/dist/query/detect-custom-files.d.ts +11 -0
  731. package/sdk/dist/query/detect-custom-files.d.ts.map +1 -0
  732. package/sdk/dist/query/detect-custom-files.js +89 -0
  733. package/sdk/dist/query/detect-custom-files.js.map +1 -0
  734. package/sdk/dist/query/detect-phase-type.d.ts +9 -0
  735. package/sdk/dist/query/detect-phase-type.d.ts.map +1 -0
  736. package/sdk/dist/query/detect-phase-type.js +124 -0
  737. package/sdk/dist/query/detect-phase-type.js.map +1 -0
  738. package/sdk/dist/query/docs-init.d.ts +26 -0
  739. package/sdk/dist/query/docs-init.d.ts.map +1 -0
  740. package/sdk/dist/query/docs-init.js +231 -0
  741. package/sdk/dist/query/docs-init.js.map +1 -0
  742. package/sdk/dist/query/fallow-audit.d.ts +44 -0
  743. package/sdk/dist/query/fallow-audit.d.ts.map +1 -0
  744. package/sdk/dist/query/fallow-audit.js +44 -0
  745. package/sdk/dist/query/fallow-audit.js.map +1 -0
  746. package/sdk/dist/query/frontmatter-mutation.d.ts +77 -0
  747. package/sdk/dist/query/frontmatter-mutation.d.ts.map +1 -0
  748. package/sdk/dist/query/frontmatter-mutation.js +299 -0
  749. package/sdk/dist/query/frontmatter-mutation.js.map +1 -0
  750. package/sdk/dist/query/frontmatter.d.ts +93 -0
  751. package/sdk/dist/query/frontmatter.d.ts.map +1 -0
  752. package/sdk/dist/query/frontmatter.js +364 -0
  753. package/sdk/dist/query/frontmatter.js.map +1 -0
  754. package/sdk/dist/query/helpers.d.ts +194 -0
  755. package/sdk/dist/query/helpers.d.ts.map +1 -0
  756. package/sdk/dist/query/helpers.js +540 -0
  757. package/sdk/dist/query/helpers.js.map +1 -0
  758. package/sdk/dist/query/index.d.ts +8 -0
  759. package/sdk/dist/query/index.d.ts.map +1 -0
  760. package/sdk/dist/query/index.js +6 -0
  761. package/sdk/dist/query/index.js.map +1 -0
  762. package/sdk/dist/query/init-complex.d.ts +47 -0
  763. package/sdk/dist/query/init-complex.d.ts.map +1 -0
  764. package/sdk/dist/query/init-complex.js +735 -0
  765. package/sdk/dist/query/init-complex.js.map +1 -0
  766. package/sdk/dist/query/init.d.ts +106 -0
  767. package/sdk/dist/query/init.d.ts.map +1 -0
  768. package/sdk/dist/query/init.js +1228 -0
  769. package/sdk/dist/query/init.js.map +1 -0
  770. package/sdk/dist/query/intel.d.ts +43 -0
  771. package/sdk/dist/query/intel.d.ts.map +1 -0
  772. package/sdk/dist/query/intel.js +416 -0
  773. package/sdk/dist/query/intel.js.map +1 -0
  774. package/sdk/dist/query/mutation-event-decorator.d.ts +5 -0
  775. package/sdk/dist/query/mutation-event-decorator.d.ts.map +1 -0
  776. package/sdk/dist/query/mutation-event-decorator.js +28 -0
  777. package/sdk/dist/query/mutation-event-decorator.js.map +1 -0
  778. package/sdk/dist/query/mutation-event-mapper.d.ts +4 -0
  779. package/sdk/dist/query/mutation-event-mapper.d.ts.map +1 -0
  780. package/sdk/dist/query/mutation-event-mapper.js +70 -0
  781. package/sdk/dist/query/mutation-event-mapper.js.map +1 -0
  782. package/sdk/dist/query/mvp.d.ts +113 -0
  783. package/sdk/dist/query/mvp.d.ts.map +1 -0
  784. package/sdk/dist/query/mvp.js +225 -0
  785. package/sdk/dist/query/mvp.js.map +1 -0
  786. package/sdk/dist/query/phase-filesystem-adapter.d.ts +4 -0
  787. package/sdk/dist/query/phase-filesystem-adapter.d.ts.map +1 -0
  788. package/sdk/dist/query/phase-filesystem-adapter.js +33 -0
  789. package/sdk/dist/query/phase-filesystem-adapter.js.map +1 -0
  790. package/sdk/dist/query/phase-lifecycle-policy.d.ts +34 -0
  791. package/sdk/dist/query/phase-lifecycle-policy.d.ts.map +1 -0
  792. package/sdk/dist/query/phase-lifecycle-policy.js +138 -0
  793. package/sdk/dist/query/phase-lifecycle-policy.js.map +1 -0
  794. package/sdk/dist/query/phase-lifecycle.d.ts +116 -0
  795. package/sdk/dist/query/phase-lifecycle.d.ts.map +1 -0
  796. package/sdk/dist/query/phase-lifecycle.js +1823 -0
  797. package/sdk/dist/query/phase-lifecycle.js.map +1 -0
  798. package/sdk/dist/query/phase-list-queries.d.ts +20 -0
  799. package/sdk/dist/query/phase-list-queries.d.ts.map +1 -0
  800. package/sdk/dist/query/phase-list-queries.js +129 -0
  801. package/sdk/dist/query/phase-list-queries.js.map +1 -0
  802. package/sdk/dist/query/phase-ready.d.ts +9 -0
  803. package/sdk/dist/query/phase-ready.d.ts.map +1 -0
  804. package/sdk/dist/query/phase-ready.js +132 -0
  805. package/sdk/dist/query/phase-ready.js.map +1 -0
  806. package/sdk/dist/query/phase-roadmap-mutation.d.ts +25 -0
  807. package/sdk/dist/query/phase-roadmap-mutation.d.ts.map +1 -0
  808. package/sdk/dist/query/phase-roadmap-mutation.js +76 -0
  809. package/sdk/dist/query/phase-roadmap-mutation.js.map +1 -0
  810. package/sdk/dist/query/phase-uat-passed.d.ts +46 -0
  811. package/sdk/dist/query/phase-uat-passed.d.ts.map +1 -0
  812. package/sdk/dist/query/phase-uat-passed.js +238 -0
  813. package/sdk/dist/query/phase-uat-passed.js.map +1 -0
  814. package/sdk/dist/query/phase.d.ts +104 -0
  815. package/sdk/dist/query/phase.d.ts.map +1 -0
  816. package/sdk/dist/query/phase.js +617 -0
  817. package/sdk/dist/query/phase.js.map +1 -0
  818. package/sdk/dist/query/pipeline.d.ts +53 -0
  819. package/sdk/dist/query/pipeline.d.ts.map +1 -0
  820. package/sdk/dist/query/pipeline.js +198 -0
  821. package/sdk/dist/query/pipeline.js.map +1 -0
  822. package/sdk/dist/query/plan-scan.d.ts +14 -0
  823. package/sdk/dist/query/plan-scan.d.ts.map +1 -0
  824. package/sdk/dist/query/plan-scan.js +70 -0
  825. package/sdk/dist/query/plan-scan.js.map +1 -0
  826. package/sdk/dist/query/plan-task-structure.d.ts +9 -0
  827. package/sdk/dist/query/plan-task-structure.d.ts.map +1 -0
  828. package/sdk/dist/query/plan-task-structure.js +59 -0
  829. package/sdk/dist/query/plan-task-structure.js.map +1 -0
  830. package/sdk/dist/query/profile-extract-messages.d.ts +40 -0
  831. package/sdk/dist/query/profile-extract-messages.d.ts.map +1 -0
  832. package/sdk/dist/query/profile-extract-messages.js +195 -0
  833. package/sdk/dist/query/profile-extract-messages.js.map +1 -0
  834. package/sdk/dist/query/profile-output.d.ts +11 -0
  835. package/sdk/dist/query/profile-output.d.ts.map +1 -0
  836. package/sdk/dist/query/profile-output.js +873 -0
  837. package/sdk/dist/query/profile-output.js.map +1 -0
  838. package/sdk/dist/query/profile-questionnaire-data.d.ts +21 -0
  839. package/sdk/dist/query/profile-questionnaire-data.d.ts.map +1 -0
  840. package/sdk/dist/query/profile-questionnaire-data.js +171 -0
  841. package/sdk/dist/query/profile-questionnaire-data.js.map +1 -0
  842. package/sdk/dist/query/profile-sample.d.ts +22 -0
  843. package/sdk/dist/query/profile-sample.d.ts.map +1 -0
  844. package/sdk/dist/query/profile-sample.js +136 -0
  845. package/sdk/dist/query/profile-sample.js.map +1 -0
  846. package/sdk/dist/query/profile-scan-sessions.d.ts +49 -0
  847. package/sdk/dist/query/profile-scan-sessions.d.ts.map +1 -0
  848. package/sdk/dist/query/profile-scan-sessions.js +137 -0
  849. package/sdk/dist/query/profile-scan-sessions.js.map +1 -0
  850. package/sdk/dist/query/profile.d.ts +61 -0
  851. package/sdk/dist/query/profile.d.ts.map +1 -0
  852. package/sdk/dist/query/profile.js +307 -0
  853. package/sdk/dist/query/profile.js.map +1 -0
  854. package/sdk/dist/query/progress.d.ts +77 -0
  855. package/sdk/dist/query/progress.d.ts.map +1 -0
  856. package/sdk/dist/query/progress.js +481 -0
  857. package/sdk/dist/query/progress.js.map +1 -0
  858. package/sdk/dist/query/prompt-budget.d.ts +14 -0
  859. package/sdk/dist/query/prompt-budget.d.ts.map +1 -0
  860. package/sdk/dist/query/prompt-budget.js +417 -0
  861. package/sdk/dist/query/prompt-budget.js.map +1 -0
  862. package/sdk/dist/query/query-cli-adapter.d.ts +8 -0
  863. package/sdk/dist/query/query-cli-adapter.d.ts.map +1 -0
  864. package/sdk/dist/query/query-cli-adapter.js +32 -0
  865. package/sdk/dist/query/query-cli-adapter.js.map +1 -0
  866. package/sdk/dist/query/query-cli-output.d.ts +9 -0
  867. package/sdk/dist/query/query-cli-output.d.ts.map +1 -0
  868. package/sdk/dist/query/query-cli-output.js +28 -0
  869. package/sdk/dist/query/query-cli-output.js.map +1 -0
  870. package/sdk/dist/query/query-command-diagnosis.d.ts +6 -0
  871. package/sdk/dist/query/query-command-diagnosis.d.ts.map +1 -0
  872. package/sdk/dist/query/query-command-diagnosis.js +6 -0
  873. package/sdk/dist/query/query-command-diagnosis.js.map +1 -0
  874. package/sdk/dist/query/query-command-resolution-strategy.d.ts +29 -0
  875. package/sdk/dist/query/query-command-resolution-strategy.d.ts.map +1 -0
  876. package/sdk/dist/query/query-command-resolution-strategy.js +103 -0
  877. package/sdk/dist/query/query-command-resolution-strategy.js.map +1 -0
  878. package/sdk/dist/query/query-command-semantics.d.ts +7 -0
  879. package/sdk/dist/query/query-command-semantics.d.ts.map +1 -0
  880. package/sdk/dist/query/query-command-semantics.js +7 -0
  881. package/sdk/dist/query/query-command-semantics.js.map +1 -0
  882. package/sdk/dist/query/query-dispatch-contract.d.ts +21 -0
  883. package/sdk/dist/query/query-dispatch-contract.d.ts.map +1 -0
  884. package/sdk/dist/query/query-dispatch-contract.js +2 -0
  885. package/sdk/dist/query/query-dispatch-contract.js.map +1 -0
  886. package/sdk/dist/query/query-dispatch-error-mapper.d.ts +6 -0
  887. package/sdk/dist/query/query-dispatch-error-mapper.d.ts.map +1 -0
  888. package/sdk/dist/query/query-dispatch-error-mapper.js +6 -0
  889. package/sdk/dist/query/query-dispatch-error-mapper.js.map +1 -0
  890. package/sdk/dist/query/query-dispatch-formatting.d.ts +6 -0
  891. package/sdk/dist/query/query-dispatch-formatting.d.ts.map +1 -0
  892. package/sdk/dist/query/query-dispatch-formatting.js +6 -0
  893. package/sdk/dist/query/query-dispatch-formatting.js.map +1 -0
  894. package/sdk/dist/query/query-dispatch-observability.d.ts +2 -0
  895. package/sdk/dist/query/query-dispatch-observability.d.ts.map +1 -0
  896. package/sdk/dist/query/query-dispatch-observability.js +7 -0
  897. package/sdk/dist/query/query-dispatch-observability.js.map +1 -0
  898. package/sdk/dist/query/query-dispatch.d.ts +48 -0
  899. package/sdk/dist/query/query-dispatch.d.ts.map +1 -0
  900. package/sdk/dist/query/query-dispatch.js +175 -0
  901. package/sdk/dist/query/query-dispatch.js.map +1 -0
  902. package/sdk/dist/query/query-error-details-schema.d.ts +19 -0
  903. package/sdk/dist/query/query-error-details-schema.d.ts.map +1 -0
  904. package/sdk/dist/query/query-error-details-schema.js +10 -0
  905. package/sdk/dist/query/query-error-details-schema.js.map +1 -0
  906. package/sdk/dist/query/query-error-taxonomy.d.ts +38 -0
  907. package/sdk/dist/query/query-error-taxonomy.d.ts.map +1 -0
  908. package/sdk/dist/query/query-error-taxonomy.js +74 -0
  909. package/sdk/dist/query/query-error-taxonomy.js.map +1 -0
  910. package/sdk/dist/query/query-fallback-bridge-adapter.d.ts +14 -0
  911. package/sdk/dist/query/query-fallback-bridge-adapter.d.ts.map +1 -0
  912. package/sdk/dist/query/query-fallback-bridge-adapter.js +33 -0
  913. package/sdk/dist/query/query-fallback-bridge-adapter.js.map +1 -0
  914. package/sdk/dist/query/query-fallback-executor.d.ts +11 -0
  915. package/sdk/dist/query/query-fallback-executor.d.ts.map +1 -0
  916. package/sdk/dist/query/query-fallback-executor.js +31 -0
  917. package/sdk/dist/query/query-fallback-executor.js.map +1 -0
  918. package/sdk/dist/query/query-fallback-output-classifier.d.ts +6 -0
  919. package/sdk/dist/query/query-fallback-output-classifier.d.ts.map +1 -0
  920. package/sdk/dist/query/query-fallback-output-classifier.js +27 -0
  921. package/sdk/dist/query/query-fallback-output-classifier.js.map +1 -0
  922. package/sdk/dist/query/query-fallback-policy.d.ts +6 -0
  923. package/sdk/dist/query/query-fallback-policy.d.ts.map +1 -0
  924. package/sdk/dist/query/query-fallback-policy.js +7 -0
  925. package/sdk/dist/query/query-fallback-policy.js.map +1 -0
  926. package/sdk/dist/query/query-native-dispatch-adapter.d.ts +7 -0
  927. package/sdk/dist/query/query-native-dispatch-adapter.d.ts.map +1 -0
  928. package/sdk/dist/query/query-native-dispatch-adapter.js +6 -0
  929. package/sdk/dist/query/query-native-dispatch-adapter.js.map +1 -0
  930. package/sdk/dist/query/query-policy-capability.d.ts +10 -0
  931. package/sdk/dist/query/query-policy-capability.d.ts.map +1 -0
  932. package/sdk/dist/query/query-policy-capability.js +17 -0
  933. package/sdk/dist/query/query-policy-capability.js.map +1 -0
  934. package/sdk/dist/query/query-runtime-context.d.ts +19 -0
  935. package/sdk/dist/query/query-runtime-context.d.ts.map +1 -0
  936. package/sdk/dist/query/query-runtime-context.js +31 -0
  937. package/sdk/dist/query/query-runtime-context.js.map +1 -0
  938. package/sdk/dist/query/query-unknown-command-hints.d.ts +2 -0
  939. package/sdk/dist/query/query-unknown-command-hints.d.ts.map +1 -0
  940. package/sdk/dist/query/query-unknown-command-hints.js +6 -0
  941. package/sdk/dist/query/query-unknown-command-hints.js.map +1 -0
  942. package/sdk/dist/query/registry-assembly-descriptor.d.ts +12 -0
  943. package/sdk/dist/query/registry-assembly-descriptor.d.ts.map +1 -0
  944. package/sdk/dist/query/registry-assembly-descriptor.js +61 -0
  945. package/sdk/dist/query/registry-assembly-descriptor.js.map +1 -0
  946. package/sdk/dist/query/registry-assembly-invariants.d.ts +30 -0
  947. package/sdk/dist/query/registry-assembly-invariants.d.ts.map +1 -0
  948. package/sdk/dist/query/registry-assembly-invariants.js +77 -0
  949. package/sdk/dist/query/registry-assembly-invariants.js.map +1 -0
  950. package/sdk/dist/query/registry-assembly.d.ts +10 -0
  951. package/sdk/dist/query/registry-assembly.d.ts.map +1 -0
  952. package/sdk/dist/query/registry-assembly.js +53 -0
  953. package/sdk/dist/query/registry-assembly.js.map +1 -0
  954. package/sdk/dist/query/registry.d.ts +90 -0
  955. package/sdk/dist/query/registry.d.ts.map +1 -0
  956. package/sdk/dist/query/registry.js +129 -0
  957. package/sdk/dist/query/registry.js.map +1 -0
  958. package/sdk/dist/query/requirements-extract-from-plans.d.ts +9 -0
  959. package/sdk/dist/query/requirements-extract-from-plans.d.ts.map +1 -0
  960. package/sdk/dist/query/requirements-extract-from-plans.js +76 -0
  961. package/sdk/dist/query/requirements-extract-from-plans.js.map +1 -0
  962. package/sdk/dist/query/roadmap-update-plan-progress.d.ts +11 -0
  963. package/sdk/dist/query/roadmap-update-plan-progress.d.ts.map +1 -0
  964. package/sdk/dist/query/roadmap-update-plan-progress.js +124 -0
  965. package/sdk/dist/query/roadmap-update-plan-progress.js.map +1 -0
  966. package/sdk/dist/query/roadmap.d.ts +160 -0
  967. package/sdk/dist/query/roadmap.d.ts.map +1 -0
  968. package/sdk/dist/query/roadmap.js +982 -0
  969. package/sdk/dist/query/roadmap.js.map +1 -0
  970. package/sdk/dist/query/route-next-action.d.ts +9 -0
  971. package/sdk/dist/query/route-next-action.d.ts.map +1 -0
  972. package/sdk/dist/query/route-next-action.js +318 -0
  973. package/sdk/dist/query/route-next-action.js.map +1 -0
  974. package/sdk/dist/query/schema-detect.d.ts +21 -0
  975. package/sdk/dist/query/schema-detect.d.ts.map +1 -0
  976. package/sdk/dist/query/schema-detect.js +146 -0
  977. package/sdk/dist/query/schema-detect.js.map +1 -0
  978. package/sdk/dist/query/secrets.d.ts +27 -0
  979. package/sdk/dist/query/secrets.d.ts.map +1 -0
  980. package/sdk/dist/query/secrets.js +42 -0
  981. package/sdk/dist/query/secrets.js.map +1 -0
  982. package/sdk/dist/query/skill-manifest.d.ts +50 -0
  983. package/sdk/dist/query/skill-manifest.d.ts.map +1 -0
  984. package/sdk/dist/query/skill-manifest.js +171 -0
  985. package/sdk/dist/query/skill-manifest.js.map +1 -0
  986. package/sdk/dist/query/skills.d.ts +27 -0
  987. package/sdk/dist/query/skills.d.ts.map +1 -0
  988. package/sdk/dist/query/skills.js +137 -0
  989. package/sdk/dist/query/skills.js.map +1 -0
  990. package/sdk/dist/query/state-document.d.ts +14 -0
  991. package/sdk/dist/query/state-document.d.ts.map +1 -0
  992. package/sdk/dist/query/state-document.js +110 -0
  993. package/sdk/dist/query/state-document.js.map +1 -0
  994. package/sdk/dist/query/state-mutation.d.ts +224 -0
  995. package/sdk/dist/query/state-mutation.d.ts.map +1 -0
  996. package/sdk/dist/query/state-mutation.js +1635 -0
  997. package/sdk/dist/query/state-mutation.js.map +1 -0
  998. package/sdk/dist/query/state-project-load.d.ts +23 -0
  999. package/sdk/dist/query/state-project-load.d.ts.map +1 -0
  1000. package/sdk/dist/query/state-project-load.js +75 -0
  1001. package/sdk/dist/query/state-project-load.js.map +1 -0
  1002. package/sdk/dist/query/state.d.ts +78 -0
  1003. package/sdk/dist/query/state.d.ts.map +1 -0
  1004. package/sdk/dist/query/state.js +443 -0
  1005. package/sdk/dist/query/state.js.map +1 -0
  1006. package/sdk/dist/query/summary.d.ts +18 -0
  1007. package/sdk/dist/query/summary.d.ts.map +1 -0
  1008. package/sdk/dist/query/summary.js +249 -0
  1009. package/sdk/dist/query/summary.js.map +1 -0
  1010. package/sdk/dist/query/template.d.ts +46 -0
  1011. package/sdk/dist/query/template.d.ts.map +1 -0
  1012. package/sdk/dist/query/template.js +210 -0
  1013. package/sdk/dist/query/template.js.map +1 -0
  1014. package/sdk/dist/query/uat.d.ts +42 -0
  1015. package/sdk/dist/query/uat.d.ts.map +1 -0
  1016. package/sdk/dist/query/uat.js +339 -0
  1017. package/sdk/dist/query/uat.js.map +1 -0
  1018. package/sdk/dist/query/utils.d.ts +59 -0
  1019. package/sdk/dist/query/utils.d.ts.map +1 -0
  1020. package/sdk/dist/query/utils.js +74 -0
  1021. package/sdk/dist/query/utils.js.map +1 -0
  1022. package/sdk/dist/query/validate.d.ts +67 -0
  1023. package/sdk/dist/query/validate.d.ts.map +1 -0
  1024. package/sdk/dist/query/validate.js +1001 -0
  1025. package/sdk/dist/query/validate.js.map +1 -0
  1026. package/sdk/dist/query/verify.d.ts +98 -0
  1027. package/sdk/dist/query/verify.d.ts.map +1 -0
  1028. package/sdk/dist/query/verify.js +593 -0
  1029. package/sdk/dist/query/verify.js.map +1 -0
  1030. package/sdk/dist/query/websearch.d.ts +24 -0
  1031. package/sdk/dist/query/websearch.d.ts.map +1 -0
  1032. package/sdk/dist/query/websearch.js +68 -0
  1033. package/sdk/dist/query/websearch.js.map +1 -0
  1034. package/sdk/dist/query/workspace.d.ts +62 -0
  1035. package/sdk/dist/query/workspace.d.ts.map +1 -0
  1036. package/sdk/dist/query/workspace.js +104 -0
  1037. package/sdk/dist/query/workspace.js.map +1 -0
  1038. package/sdk/dist/query/workstream-inventory.d.ts +24 -0
  1039. package/sdk/dist/query/workstream-inventory.d.ts.map +1 -0
  1040. package/sdk/dist/query/workstream-inventory.js +120 -0
  1041. package/sdk/dist/query/workstream-inventory.js.map +1 -0
  1042. package/sdk/dist/query/workstream.d.ts +35 -0
  1043. package/sdk/dist/query/workstream.d.ts.map +1 -0
  1044. package/sdk/dist/query/workstream.js +298 -0
  1045. package/sdk/dist/query/workstream.js.map +1 -0
  1046. package/sdk/dist/query/worktree.d.ts +9 -0
  1047. package/sdk/dist/query/worktree.d.ts.map +1 -0
  1048. package/sdk/dist/query/worktree.js +79 -0
  1049. package/sdk/dist/query/worktree.js.map +1 -0
  1050. package/sdk/dist/query-command-executor.d.ts +22 -0
  1051. package/sdk/dist/query-command-executor.d.ts.map +1 -0
  1052. package/sdk/dist/query-command-executor.js +22 -0
  1053. package/sdk/dist/query-command-executor.js.map +1 -0
  1054. package/sdk/dist/query-execution-policy.d.ts +24 -0
  1055. package/sdk/dist/query-execution-policy.d.ts.map +1 -0
  1056. package/sdk/dist/query-execution-policy.js +27 -0
  1057. package/sdk/dist/query-execution-policy.js.map +1 -0
  1058. package/sdk/dist/query-failure-classification.d.ts +9 -0
  1059. package/sdk/dist/query-failure-classification.d.ts.map +1 -0
  1060. package/sdk/dist/query-failure-classification.js +32 -0
  1061. package/sdk/dist/query-failure-classification.js.map +1 -0
  1062. package/sdk/dist/query-gsd-tools-path.d.ts +2 -0
  1063. package/sdk/dist/query-gsd-tools-path.d.ts.map +1 -0
  1064. package/sdk/dist/query-gsd-tools-path.js +2 -0
  1065. package/sdk/dist/query-gsd-tools-path.js.map +1 -0
  1066. package/sdk/dist/query-gsd-tools-runtime.d.ts +20 -0
  1067. package/sdk/dist/query-gsd-tools-runtime.d.ts.map +1 -0
  1068. package/sdk/dist/query-gsd-tools-runtime.js +47 -0
  1069. package/sdk/dist/query-gsd-tools-runtime.js.map +1 -0
  1070. package/sdk/dist/query-hotpath-methods.d.ts +19 -0
  1071. package/sdk/dist/query-hotpath-methods.d.ts.map +1 -0
  1072. package/sdk/dist/query-hotpath-methods.js +34 -0
  1073. package/sdk/dist/query-hotpath-methods.js.map +1 -0
  1074. package/sdk/dist/query-native-direct-adapter.d.ts +20 -0
  1075. package/sdk/dist/query-native-direct-adapter.d.ts.map +1 -0
  1076. package/sdk/dist/query-native-direct-adapter.js +52 -0
  1077. package/sdk/dist/query-native-direct-adapter.js.map +1 -0
  1078. package/sdk/dist/query-native-hotpath-adapter.d.ts +15 -0
  1079. package/sdk/dist/query-native-hotpath-adapter.d.ts.map +1 -0
  1080. package/sdk/dist/query-native-hotpath-adapter.js +32 -0
  1081. package/sdk/dist/query-native-hotpath-adapter.js.map +1 -0
  1082. package/sdk/dist/query-raw-output-projection.d.ts +6 -0
  1083. package/sdk/dist/query-raw-output-projection.d.ts.map +1 -0
  1084. package/sdk/dist/query-raw-output-projection.js +86 -0
  1085. package/sdk/dist/query-raw-output-projection.js.map +1 -0
  1086. package/sdk/dist/query-runtime-bridge.d.ts +61 -0
  1087. package/sdk/dist/query-runtime-bridge.d.ts.map +1 -0
  1088. package/sdk/dist/query-runtime-bridge.js +144 -0
  1089. package/sdk/dist/query-runtime-bridge.js.map +1 -0
  1090. package/sdk/dist/query-subprocess-adapter.d.ts +18 -0
  1091. package/sdk/dist/query-subprocess-adapter.d.ts.map +1 -0
  1092. package/sdk/dist/query-subprocess-adapter.js +92 -0
  1093. package/sdk/dist/query-subprocess-adapter.js.map +1 -0
  1094. package/sdk/dist/query-tools-error-factory.d.ts +16 -0
  1095. package/sdk/dist/query-tools-error-factory.d.ts.map +1 -0
  1096. package/sdk/dist/query-tools-error-factory.js +33 -0
  1097. package/sdk/dist/query-tools-error-factory.js.map +1 -0
  1098. package/sdk/dist/research-gate.d.ts +24 -0
  1099. package/sdk/dist/research-gate.d.ts.map +1 -0
  1100. package/sdk/dist/research-gate.js +70 -0
  1101. package/sdk/dist/research-gate.js.map +1 -0
  1102. package/sdk/dist/runtime-bridge-sync/index.d.ts +96 -0
  1103. package/sdk/dist/runtime-bridge-sync/index.d.ts.map +1 -0
  1104. package/sdk/dist/runtime-bridge-sync/index.js +109 -0
  1105. package/sdk/dist/runtime-bridge-sync/index.js.map +1 -0
  1106. package/sdk/dist/runtime-bridge-sync/worker.d.ts +2 -0
  1107. package/sdk/dist/runtime-bridge-sync/worker.d.ts.map +1 -0
  1108. package/sdk/dist/runtime-bridge-sync/worker.js +180 -0
  1109. package/sdk/dist/runtime-bridge-sync/worker.js.map +1 -0
  1110. package/sdk/dist/runtime-gate.d.ts +14 -0
  1111. package/sdk/dist/runtime-gate.d.ts.map +1 -0
  1112. package/sdk/dist/runtime-gate.js +48 -0
  1113. package/sdk/dist/runtime-gate.js.map +1 -0
  1114. package/sdk/dist/sdk-package-compatibility.d.ts +38 -0
  1115. package/sdk/dist/sdk-package-compatibility.d.ts.map +1 -0
  1116. package/sdk/dist/sdk-package-compatibility.js +90 -0
  1117. package/sdk/dist/sdk-package-compatibility.js.map +1 -0
  1118. package/sdk/dist/session-runner.d.ts +40 -0
  1119. package/sdk/dist/session-runner.d.ts.map +1 -0
  1120. package/sdk/dist/session-runner.js +274 -0
  1121. package/sdk/dist/session-runner.js.map +1 -0
  1122. package/sdk/dist/tool-scoping.d.ts +31 -0
  1123. package/sdk/dist/tool-scoping.d.ts.map +1 -0
  1124. package/sdk/dist/tool-scoping.js +54 -0
  1125. package/sdk/dist/tool-scoping.js.map +1 -0
  1126. package/sdk/dist/types.d.ts +794 -0
  1127. package/sdk/dist/types.d.ts.map +1 -0
  1128. package/sdk/dist/types.js +77 -0
  1129. package/sdk/dist/types.js.map +1 -0
  1130. package/sdk/dist/workstream-inventory/builder.d.ts +88 -0
  1131. package/sdk/dist/workstream-inventory/builder.d.ts.map +1 -0
  1132. package/sdk/dist/workstream-inventory/builder.js +84 -0
  1133. package/sdk/dist/workstream-inventory/builder.js.map +1 -0
  1134. package/sdk/dist/workstream-name-policy.d.ts +37 -0
  1135. package/sdk/dist/workstream-name-policy.d.ts.map +1 -0
  1136. package/sdk/dist/workstream-name-policy.js +53 -0
  1137. package/sdk/dist/workstream-name-policy.js.map +1 -0
  1138. package/sdk/dist/workstream-utils.d.ts +23 -0
  1139. package/sdk/dist/workstream-utils.d.ts.map +1 -0
  1140. package/sdk/dist/workstream-utils.js +34 -0
  1141. package/sdk/dist/workstream-utils.js.map +1 -0
  1142. package/sdk/dist/ws-transport.d.ts +32 -0
  1143. package/sdk/dist/ws-transport.d.ts.map +1 -0
  1144. package/sdk/dist/ws-transport.js +84 -0
  1145. package/sdk/dist/ws-transport.js.map +1 -0
  1146. package/sdk/package-lock.json +2530 -0
  1147. package/sdk/package.json +77 -0
  1148. package/sdk/prompts/templates/project.md +186 -0
  1149. package/sdk/prompts/templates/requirements.md +231 -0
  1150. package/sdk/prompts/templates/research-project/ARCHITECTURE.md +204 -0
  1151. package/sdk/prompts/templates/research-project/FEATURES.md +147 -0
  1152. package/sdk/prompts/templates/research-project/PITFALLS.md +200 -0
  1153. package/sdk/prompts/templates/research-project/STACK.md +120 -0
  1154. package/sdk/prompts/templates/research-project/SUMMARY.md +170 -0
  1155. package/sdk/prompts/templates/roadmap.md +202 -0
  1156. package/sdk/prompts/templates/state.md +175 -0
  1157. package/sdk/shared/config-defaults.manifest.json +75 -0
  1158. package/sdk/shared/config-schema.manifest.json +151 -0
  1159. package/sdk/shared/model-catalog.json +122 -0
  1160. package/sdk/src/assembled-prompts.test.ts +349 -0
  1161. package/sdk/src/bug-3589-planning-paths-validation.test.ts +89 -0
  1162. package/sdk/src/bug-3591-gsdtools-runtime-workstream.test.ts +179 -0
  1163. package/sdk/src/cli-transport.test.ts +388 -0
  1164. package/sdk/src/cli-transport.ts +130 -0
  1165. package/sdk/src/cli.test.ts +426 -0
  1166. package/sdk/src/cli.ts +589 -0
  1167. package/sdk/src/config.test.ts +277 -0
  1168. package/sdk/src/config.ts +202 -0
  1169. package/sdk/src/configuration/index.test.ts +318 -0
  1170. package/sdk/src/configuration/index.ts +325 -0
  1171. package/sdk/src/context-engine.test.ts +295 -0
  1172. package/sdk/src/context-engine.ts +170 -0
  1173. package/sdk/src/context-truncation.test.ts +163 -0
  1174. package/sdk/src/context-truncation.ts +233 -0
  1175. package/sdk/src/e2e.integration.test.ts +181 -0
  1176. package/sdk/src/errors.ts +72 -0
  1177. package/sdk/src/event-stream.test.ts +661 -0
  1178. package/sdk/src/event-stream.ts +441 -0
  1179. package/sdk/src/golden/capture.ts +95 -0
  1180. package/sdk/src/golden/fixtures/generate-slug.golden.json +1 -0
  1181. package/sdk/src/golden/fixtures/profile-sample-sessions/demo-project/sample.jsonl +3 -0
  1182. package/sdk/src/golden/fixtures/summary-extract-sample.md +26 -0
  1183. package/sdk/src/golden/fixtures/uat-render-checkpoint-sample.md +15 -0
  1184. package/sdk/src/golden/golden-integration-covered.ts +30 -0
  1185. package/sdk/src/golden/golden-mutation-covered.ts +17 -0
  1186. package/sdk/src/golden/golden-policy.test.ts +8 -0
  1187. package/sdk/src/golden/golden-policy.ts +120 -0
  1188. package/sdk/src/golden/golden.integration.test.ts +1031 -0
  1189. package/sdk/src/golden/init-golden-normalize.ts +15 -0
  1190. package/sdk/src/golden/read-only-golden-rows.ts +77 -0
  1191. package/sdk/src/golden/read-only-parity.integration.test.ts +133 -0
  1192. package/sdk/src/golden/registry-canonical-commands.ts +31 -0
  1193. package/sdk/src/gsd-tools-error.test.ts +21 -0
  1194. package/sdk/src/gsd-tools-error.ts +65 -0
  1195. package/sdk/src/gsd-tools.test.ts +472 -0
  1196. package/sdk/src/gsd-tools.ts +237 -0
  1197. package/sdk/src/gsd-transport-policy.test.ts +34 -0
  1198. package/sdk/src/gsd-transport-policy.ts +48 -0
  1199. package/sdk/src/gsd-transport.test.ts +299 -0
  1200. package/sdk/src/gsd-transport.ts +118 -0
  1201. package/sdk/src/index.ts +366 -0
  1202. package/sdk/src/init-e2e.integration.test.ts +138 -0
  1203. package/sdk/src/init-runner.test.ts +740 -0
  1204. package/sdk/src/init-runner.ts +734 -0
  1205. package/sdk/src/lifecycle-e2e.integration.test.ts +258 -0
  1206. package/sdk/src/logger.test.ts +149 -0
  1207. package/sdk/src/logger.ts +113 -0
  1208. package/sdk/src/milestone-runner.test.ts +421 -0
  1209. package/sdk/src/model-catalog.ts +70 -0
  1210. package/sdk/src/phase-prompt.ts +259 -0
  1211. package/sdk/src/phase-runner.integration.test.ts +377 -0
  1212. package/sdk/src/phase-runner.test.ts +3660 -0
  1213. package/sdk/src/phase-runner.ts +1442 -0
  1214. package/sdk/src/plan-parser.test.ts +579 -0
  1215. package/sdk/src/plan-parser.ts +431 -0
  1216. package/sdk/src/planning-journal.test.ts +70 -0
  1217. package/sdk/src/planning-journal.ts +153 -0
  1218. package/sdk/src/planning-runtime.test.ts +29 -0
  1219. package/sdk/src/planning-runtime.ts +100 -0
  1220. package/sdk/src/project-root/index.test.ts +186 -0
  1221. package/sdk/src/project-root/index.ts +144 -0
  1222. package/sdk/src/prompt-builder.test.ts +318 -0
  1223. package/sdk/src/prompt-builder.ts +218 -0
  1224. package/sdk/src/prompt-sanitizer.test.ts +260 -0
  1225. package/sdk/src/prompt-sanitizer.ts +116 -0
  1226. package/sdk/src/query/QUERY-HANDLERS.md +349 -0
  1227. package/sdk/src/query/active-workstream-store.ts +50 -0
  1228. package/sdk/src/query/agent-failure-classifier.test.ts +157 -0
  1229. package/sdk/src/query/agent-failure-classifier.ts +105 -0
  1230. package/sdk/src/query/audit-open.ts +722 -0
  1231. package/sdk/src/query/check-auto-mode.test.ts +77 -0
  1232. package/sdk/src/query/check-auto-mode.ts +49 -0
  1233. package/sdk/src/query/check-completion.test.ts +113 -0
  1234. package/sdk/src/query/check-completion.ts +182 -0
  1235. package/sdk/src/query/check-decision-coverage.test.ts +519 -0
  1236. package/sdk/src/query/check-decision-coverage.ts +554 -0
  1237. package/sdk/src/query/check-gates.test.ts +103 -0
  1238. package/sdk/src/query/check-gates.ts +112 -0
  1239. package/sdk/src/query/check-ship-ready.test.ts +303 -0
  1240. package/sdk/src/query/check-ship-ready.ts +136 -0
  1241. package/sdk/src/query/check-verification-status.test.ts +143 -0
  1242. package/sdk/src/query/check-verification-status.ts +160 -0
  1243. package/sdk/src/query/command-aliases.generated.ts +154 -0
  1244. package/sdk/src/query/command-catalog.ts +31 -0
  1245. package/sdk/src/query/command-definition.test.ts +47 -0
  1246. package/sdk/src/query/command-definition.ts +70 -0
  1247. package/sdk/src/query/command-family-handlers.ts +123 -0
  1248. package/sdk/src/query/command-manifest.init.ts +24 -0
  1249. package/sdk/src/query/command-manifest.non-family.ts +86 -0
  1250. package/sdk/src/query/command-manifest.phase.ts +17 -0
  1251. package/sdk/src/query/command-manifest.phases.ts +11 -0
  1252. package/sdk/src/query/command-manifest.roadmap.ts +11 -0
  1253. package/sdk/src/query/command-manifest.state.ts +31 -0
  1254. package/sdk/src/query/command-manifest.ts +17 -0
  1255. package/sdk/src/query/command-manifest.types.ts +13 -0
  1256. package/sdk/src/query/command-manifest.validate.ts +11 -0
  1257. package/sdk/src/query/command-manifest.verify.ts +17 -0
  1258. package/sdk/src/query/command-resolution.test.ts +70 -0
  1259. package/sdk/src/query/command-seam-coverage.test.ts +118 -0
  1260. package/sdk/src/query/command-static-catalog-domain.ts +111 -0
  1261. package/sdk/src/query/command-static-catalog-foundation.ts +111 -0
  1262. package/sdk/src/query/command-topology.test.ts +28 -0
  1263. package/sdk/src/query/command-topology.ts +114 -0
  1264. package/sdk/src/query/commands-list.test.ts +36 -0
  1265. package/sdk/src/query/commands-list.ts +19 -0
  1266. package/sdk/src/query/commit.test.ts +485 -0
  1267. package/sdk/src/query/commit.ts +717 -0
  1268. package/sdk/src/query/config-gates.test.ts +89 -0
  1269. package/sdk/src/query/config-gates.ts +69 -0
  1270. package/sdk/src/query/config-mutation.test.ts +598 -0
  1271. package/sdk/src/query/config-mutation.ts +705 -0
  1272. package/sdk/src/query/config-query.test.ts +472 -0
  1273. package/sdk/src/query/config-query.ts +314 -0
  1274. package/sdk/src/query/config-schema.ts +35 -0
  1275. package/sdk/src/query/decisions.test.ts +221 -0
  1276. package/sdk/src/query/decisions.ts +196 -0
  1277. package/sdk/src/query/decomposed-handlers.test.ts +431 -0
  1278. package/sdk/src/query/detect-custom-files.test.ts +115 -0
  1279. package/sdk/src/query/detect-custom-files.ts +96 -0
  1280. package/sdk/src/query/detect-phase-type.test.ts +105 -0
  1281. package/sdk/src/query/detect-phase-type.ts +141 -0
  1282. package/sdk/src/query/docs-init.ts +258 -0
  1283. package/sdk/src/query/fallow-audit.ts +88 -0
  1284. package/sdk/src/query/frontmatter-array.test.ts +14 -0
  1285. package/sdk/src/query/frontmatter-mutation.test.ts +259 -0
  1286. package/sdk/src/query/frontmatter-mutation.ts +328 -0
  1287. package/sdk/src/query/frontmatter.test.ts +326 -0
  1288. package/sdk/src/query/frontmatter.ts +395 -0
  1289. package/sdk/src/query/helpers.test.ts +615 -0
  1290. package/sdk/src/query/helpers.ts +566 -0
  1291. package/sdk/src/query/index-thin-seam.test.ts +16 -0
  1292. package/sdk/src/query/index.ts +9 -0
  1293. package/sdk/src/query/init-complex.test.ts +788 -0
  1294. package/sdk/src/query/init-complex.ts +815 -0
  1295. package/sdk/src/query/init-workstream-milestone-op.test.ts +321 -0
  1296. package/sdk/src/query/init.test.ts +791 -0
  1297. package/sdk/src/query/init.ts +1335 -0
  1298. package/sdk/src/query/intel.test.ts +90 -0
  1299. package/sdk/src/query/intel.ts +404 -0
  1300. package/sdk/src/query/mutation-event-decorator.test.ts +45 -0
  1301. package/sdk/src/query/mutation-event-decorator.ts +37 -0
  1302. package/sdk/src/query/mutation-event-mapper.test.ts +33 -0
  1303. package/sdk/src/query/mutation-event-mapper.ts +102 -0
  1304. package/sdk/src/query/mvp.test.ts +335 -0
  1305. package/sdk/src/query/mvp.ts +292 -0
  1306. package/sdk/src/query/normalize-query-command.test.ts +102 -0
  1307. package/sdk/src/query/phase-filesystem-adapter.ts +35 -0
  1308. package/sdk/src/query/phase-lifecycle-policy.ts +171 -0
  1309. package/sdk/src/query/phase-lifecycle.test.ts +1971 -0
  1310. package/sdk/src/query/phase-lifecycle.ts +2210 -0
  1311. package/sdk/src/query/phase-list-queries.test.ts +88 -0
  1312. package/sdk/src/query/phase-list-queries.ts +152 -0
  1313. package/sdk/src/query/phase-ready.test.ts +65 -0
  1314. package/sdk/src/query/phase-ready.ts +159 -0
  1315. package/sdk/src/query/phase-roadmap-mutation.ts +82 -0
  1316. package/sdk/src/query/phase-uat-passed.test.ts +593 -0
  1317. package/sdk/src/query/phase-uat-passed.ts +297 -0
  1318. package/sdk/src/query/phase.test.ts +693 -0
  1319. package/sdk/src/query/phase.ts +741 -0
  1320. package/sdk/src/query/pipeline.test.ts +169 -0
  1321. package/sdk/src/query/pipeline.ts +243 -0
  1322. package/sdk/src/query/plan-scan.test.ts +35 -0
  1323. package/sdk/src/query/plan-scan.ts +82 -0
  1324. package/sdk/src/query/plan-task-structure.test.ts +65 -0
  1325. package/sdk/src/query/plan-task-structure.ts +63 -0
  1326. package/sdk/src/query/policy-convergence.test.ts +28 -0
  1327. package/sdk/src/query/profile-extract-messages.ts +247 -0
  1328. package/sdk/src/query/profile-output.ts +929 -0
  1329. package/sdk/src/query/profile-questionnaire-data.ts +181 -0
  1330. package/sdk/src/query/profile-sample.ts +184 -0
  1331. package/sdk/src/query/profile-scan-sessions.ts +174 -0
  1332. package/sdk/src/query/profile.test.ts +136 -0
  1333. package/sdk/src/query/profile.ts +337 -0
  1334. package/sdk/src/query/progress.test.ts +156 -0
  1335. package/sdk/src/query/progress.ts +566 -0
  1336. package/sdk/src/query/prompt-budget.ts +556 -0
  1337. package/sdk/src/query/query-cli-adapter.test.ts +79 -0
  1338. package/sdk/src/query/query-cli-adapter.ts +39 -0
  1339. package/sdk/src/query/query-cli-output.test.ts +33 -0
  1340. package/sdk/src/query/query-cli-output.ts +35 -0
  1341. package/sdk/src/query/query-command-diagnosis.test.ts +22 -0
  1342. package/sdk/src/query/query-command-diagnosis.ts +5 -0
  1343. package/sdk/src/query/query-command-resolution-strategy.test.ts +34 -0
  1344. package/sdk/src/query/query-command-resolution-strategy.ts +121 -0
  1345. package/sdk/src/query/query-command-semantics.test.ts +22 -0
  1346. package/sdk/src/query/query-command-semantics.ts +22 -0
  1347. package/sdk/src/query/query-dispatch-contract.ts +30 -0
  1348. package/sdk/src/query/query-dispatch-error-mapper.ts +5 -0
  1349. package/sdk/src/query/query-dispatch-formatting.ts +5 -0
  1350. package/sdk/src/query/query-dispatch-observability.ts +6 -0
  1351. package/sdk/src/query/query-dispatch.test.ts +699 -0
  1352. package/sdk/src/query/query-dispatch.ts +243 -0
  1353. package/sdk/src/query/query-error-details-schema.ts +29 -0
  1354. package/sdk/src/query/query-error-taxonomy.test.ts +39 -0
  1355. package/sdk/src/query/query-error-taxonomy.ts +117 -0
  1356. package/sdk/src/query/query-fallback-bridge-adapter.test.ts +32 -0
  1357. package/sdk/src/query/query-fallback-bridge-adapter.ts +54 -0
  1358. package/sdk/src/query/query-fallback-executor.test.ts +82 -0
  1359. package/sdk/src/query/query-fallback-executor.ts +44 -0
  1360. package/sdk/src/query/query-fallback-output-classifier.test.ts +36 -0
  1361. package/sdk/src/query/query-fallback-output-classifier.ts +31 -0
  1362. package/sdk/src/query/query-fallback-policy.test.ts +13 -0
  1363. package/sdk/src/query/query-fallback-policy.ts +11 -0
  1364. package/sdk/src/query/query-native-dispatch-adapter.ts +16 -0
  1365. package/sdk/src/query/query-policy-capability.test.ts +10 -0
  1366. package/sdk/src/query/query-policy-capability.ts +26 -0
  1367. package/sdk/src/query/query-policy-snapshot.test.ts +9 -0
  1368. package/sdk/src/query/query-registry-capability.test.ts +14 -0
  1369. package/sdk/src/query/query-runtime-context.ts +44 -0
  1370. package/sdk/src/query/query-unknown-command-hints.test.ts +9 -0
  1371. package/sdk/src/query/query-unknown-command-hints.ts +5 -0
  1372. package/sdk/src/query/registry-assembly-descriptor.ts +87 -0
  1373. package/sdk/src/query/registry-assembly-invariants.ts +127 -0
  1374. package/sdk/src/query/registry-assembly.test.ts +138 -0
  1375. package/sdk/src/query/registry-assembly.ts +78 -0
  1376. package/sdk/src/query/registry.test.ts +208 -0
  1377. package/sdk/src/query/registry.ts +142 -0
  1378. package/sdk/src/query/requirements-extract-from-plans.test.ts +58 -0
  1379. package/sdk/src/query/requirements-extract-from-plans.ts +86 -0
  1380. package/sdk/src/query/roadmap-update-plan-progress.test.ts +233 -0
  1381. package/sdk/src/query/roadmap-update-plan-progress.ts +159 -0
  1382. package/sdk/src/query/roadmap.test.ts +1250 -0
  1383. package/sdk/src/query/roadmap.ts +1131 -0
  1384. package/sdk/src/query/route-next-action.test.ts +61 -0
  1385. package/sdk/src/query/route-next-action.ts +345 -0
  1386. package/sdk/src/query/schema-detect.ts +189 -0
  1387. package/sdk/src/query/secrets.test.ts +66 -0
  1388. package/sdk/src/query/secrets.ts +43 -0
  1389. package/sdk/src/query/skill-manifest.test.ts +62 -0
  1390. package/sdk/src/query/skill-manifest.ts +216 -0
  1391. package/sdk/src/query/skills.test.ts +234 -0
  1392. package/sdk/src/query/skills.ts +143 -0
  1393. package/sdk/src/query/state-document.test.ts +197 -0
  1394. package/sdk/src/query/state-document.ts +129 -0
  1395. package/sdk/src/query/state-mutation.test.ts +1210 -0
  1396. package/sdk/src/query/state-mutation.ts +1814 -0
  1397. package/sdk/src/query/state-project-load.ts +80 -0
  1398. package/sdk/src/query/state.test.ts +616 -0
  1399. package/sdk/src/query/state.ts +476 -0
  1400. package/sdk/src/query/sub-repos-root.integration.test.ts +79 -0
  1401. package/sdk/src/query/summary.test.ts +95 -0
  1402. package/sdk/src/query/summary.ts +296 -0
  1403. package/sdk/src/query/template.test.ts +180 -0
  1404. package/sdk/src/query/template.ts +242 -0
  1405. package/sdk/src/query/uat.test.ts +77 -0
  1406. package/sdk/src/query/uat.ts +365 -0
  1407. package/sdk/src/query/utils.test.ts +82 -0
  1408. package/sdk/src/query/utils.ts +106 -0
  1409. package/sdk/src/query/validate.test.ts +924 -0
  1410. package/sdk/src/query/validate.ts +1054 -0
  1411. package/sdk/src/query/verify.test.ts +414 -0
  1412. package/sdk/src/query/verify.ts +656 -0
  1413. package/sdk/src/query/websearch.test.ts +31 -0
  1414. package/sdk/src/query/websearch.ts +82 -0
  1415. package/sdk/src/query/workspace.test.ts +120 -0
  1416. package/sdk/src/query/workspace.ts +145 -0
  1417. package/sdk/src/query/workstream-inventory.ts +143 -0
  1418. package/sdk/src/query/workstream.test.ts +153 -0
  1419. package/sdk/src/query/workstream.ts +324 -0
  1420. package/sdk/src/query/worktree.ts +84 -0
  1421. package/sdk/src/query-command-executor.ts +31 -0
  1422. package/sdk/src/query-execution-policy.test.ts +52 -0
  1423. package/sdk/src/query-execution-policy.ts +46 -0
  1424. package/sdk/src/query-failure-classification.test.ts +23 -0
  1425. package/sdk/src/query-failure-classification.ts +42 -0
  1426. package/sdk/src/query-gsd-tools-path.ts +1 -0
  1427. package/sdk/src/query-gsd-tools-runtime.ts +89 -0
  1428. package/sdk/src/query-hotpath-methods.ts +48 -0
  1429. package/sdk/src/query-native-direct-adapter.test.ts +35 -0
  1430. package/sdk/src/query-native-direct-adapter.ts +70 -0
  1431. package/sdk/src/query-native-hotpath-adapter.test.ts +43 -0
  1432. package/sdk/src/query-native-hotpath-adapter.ts +45 -0
  1433. package/sdk/src/query-raw-output-projection.test.ts +39 -0
  1434. package/sdk/src/query-raw-output-projection.ts +93 -0
  1435. package/sdk/src/query-runtime-bridge.test.ts +150 -0
  1436. package/sdk/src/query-runtime-bridge.ts +215 -0
  1437. package/sdk/src/query-runtime-seam-coverage.test.ts +20 -0
  1438. package/sdk/src/query-subprocess-adapter.test.ts +84 -0
  1439. package/sdk/src/query-subprocess-adapter.ts +146 -0
  1440. package/sdk/src/query-tools-error-factory.test.ts +35 -0
  1441. package/sdk/src/query-tools-error-factory.ts +76 -0
  1442. package/sdk/src/research-gate.test.ts +190 -0
  1443. package/sdk/src/research-gate.ts +94 -0
  1444. package/sdk/src/runtime-bridge-options.test.ts +33 -0
  1445. package/sdk/src/runtime-bridge-sync/index.test.ts +164 -0
  1446. package/sdk/src/runtime-bridge-sync/index.ts +154 -0
  1447. package/sdk/src/runtime-bridge-sync/projectdir-regression.test.ts +150 -0
  1448. package/sdk/src/runtime-bridge-sync/worker.ts +224 -0
  1449. package/sdk/src/runtime-gate.test.ts +84 -0
  1450. package/sdk/src/runtime-gate.ts +52 -0
  1451. package/sdk/src/sdk-package-compatibility.test.ts +97 -0
  1452. package/sdk/src/sdk-package-compatibility.ts +141 -0
  1453. package/sdk/src/session-runner.test.ts +164 -0
  1454. package/sdk/src/session-runner.ts +327 -0
  1455. package/sdk/src/tool-scoping.test.ts +160 -0
  1456. package/sdk/src/tool-scoping.ts +61 -0
  1457. package/sdk/src/types.ts +927 -0
  1458. package/sdk/src/workflow-agent-skills-consistency.test.ts +98 -0
  1459. package/sdk/src/workstream-inventory/builder.test.ts +241 -0
  1460. package/sdk/src/workstream-inventory/builder.ts +170 -0
  1461. package/sdk/src/workstream-name-policy.ts +57 -0
  1462. package/sdk/src/workstream-utils.ts +36 -0
  1463. package/sdk/src/ws-flag.test.ts +285 -0
  1464. package/sdk/src/ws-transport.test.ts +161 -0
  1465. package/sdk/src/ws-transport.ts +93 -0
  1466. package/sdk/tsconfig.json +20 -0
@@ -0,0 +1,1490 @@
1
+ /**
2
+ * Phase — Phase CRUD, query, and lifecycle operations
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { escapeRegex, loadConfig, normalizePhaseName, phaseMarkdownRegexSource, comparePhaseNum, findPhaseInternal, getArchivedPhaseDirs, generateSlugInternal, getMilestonePhaseFilter, stripShippedMilestones, extractCurrentMilestone, replaceInCurrentMilestone, toPosixPath, output, error, readSubdirectories, phaseTokenMatches, ERROR_REASON } = require('./core.cjs');
8
+ const { platformWriteSync, platformReadSync, platformEnsureDir } = require('./shell-command-projection.cjs');
9
+ const { planningDir, withPlanningLock } = require('./planning-workspace.cjs');
10
+ const { extractFrontmatter } = require('./frontmatter.cjs');
11
+ const { writeStateMd, readModifyWriteStateMd, stateExtractField, stateReplaceField, stateReplaceFieldWithFallback, updatePerformanceMetricsSection } = require('./state.cjs');
12
+ const { formatGsdSlash, resolveRuntime } = require('./runtime-slash.cjs');
13
+
14
+ // #2893 — strict canonical filter: `{padded_phase}-{NN}-PLAN.md` or `PLAN.md`.
15
+ // Documented in agents/gsd-planner.md (write_phase_prompt step). The wider
16
+ // "looks like a plan but isn't canonical" probe below is used to surface a
17
+ // loud warning instead of silently returning zero plans.
18
+ const isCanonicalPlanFile = (f) => f.endsWith('-PLAN.md') || f === 'PLAN.md';
19
+
20
+ // Any .md file with PLAN anywhere in the basename — the diagnostic net for
21
+ // catching agent deviations like `01-PLAN-01-foundation.md` (#2893).
22
+ // Excludes derivative files (`-PLAN-OUTLINE.md`, `*.pre-bounce.md`, etc.) that
23
+ // the planner legitimately produces alongside canonical plans.
24
+ const PLAN_OUTLINE_RE = /-PLAN-OUTLINE\.md$/i;
25
+ const PLAN_PRE_BOUNCE_RE = /-PLAN.*\.pre-bounce\.md$/i;
26
+ const looksLikePlanFile = (f) =>
27
+ /\.md$/i.test(f)
28
+ && /PLAN/i.test(f)
29
+ && !PLAN_OUTLINE_RE.test(f)
30
+ && !PLAN_PRE_BOUNCE_RE.test(f);
31
+
32
+ /**
33
+ * Detect plan-shaped files that the canonical filter would reject. Returns
34
+ * a warning string when offenders exist, else null. Centralised so every
35
+ * read site (phase-plan-index, phases list --type plans, find-phase) emits
36
+ * the same message.
37
+ *
38
+ * @param {string[]} dirFiles — readdirSync output for one phase directory
39
+ * @param {string[]} matchedFiles — what the canonical filter accepted
40
+ * @returns {string|null}
41
+ */
42
+ function describeNonCanonicalPlans(dirFiles, matchedFiles) {
43
+ const matched = new Set(matchedFiles);
44
+ const offenders = dirFiles.filter((f) => looksLikePlanFile(f) && !matched.has(f));
45
+ if (offenders.length === 0) return null;
46
+ return (
47
+ `Found ${offenders.length} plan-shaped file(s) in this phase that don't match the canonical ` +
48
+ `naming convention "{padded_phase}-{NN}-PLAN.md" (or bare "PLAN.md") and were skipped: ` +
49
+ offenders.map((f) => `"${f}"`).join(', ') +
50
+ `. Rename to the canonical form (e.g. "01-01-PLAN.md") so the executor can detect them. ` +
51
+ `See agents/gsd-planner.md write_phase_prompt step for the full contract.`
52
+ );
53
+ }
54
+
55
+ function extractCanonicalPlanId(filename) {
56
+ const base = filename.replace(/-PLAN\.md$/i, '').replace(/-SUMMARY\.md$/i, '').replace(/\.md$/i, '');
57
+ const parts = base.split('-').filter(Boolean);
58
+ const tokenRe = /^\d+[A-Z]?(?:\.\d+)*$/i;
59
+ const phaseIdx = parts.findIndex(p => tokenRe.test(p));
60
+ if (phaseIdx >= 0 && phaseIdx + 1 < parts.length && tokenRe.test(parts[phaseIdx + 1])) {
61
+ return `${parts[phaseIdx]}-${parts[phaseIdx + 1]}`;
62
+ }
63
+ return base;
64
+ }
65
+
66
+ function cmdPhasesList(cwd, options, raw) {
67
+ const phasesDir = path.join(planningDir(cwd), 'phases');
68
+ const { type, phase, includeArchived } = options;
69
+
70
+ // If no phases directory, return empty
71
+ if (!fs.existsSync(phasesDir)) {
72
+ if (type) {
73
+ output({ files: [], count: 0 }, raw, '');
74
+ } else {
75
+ output({ directories: [], count: 0 }, raw, '');
76
+ }
77
+ return;
78
+ }
79
+
80
+ try {
81
+ // Get all phase directories
82
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
83
+ let dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
84
+
85
+ // Include archived phases if requested
86
+ if (includeArchived) {
87
+ const archived = getArchivedPhaseDirs(cwd);
88
+ for (const a of archived) {
89
+ dirs.push(`${a.name} [${a.milestone}]`);
90
+ }
91
+ }
92
+
93
+ // Sort numerically (handles integers, decimals, letter-suffix, hybrids)
94
+ dirs.sort((a, b) => comparePhaseNum(a, b));
95
+
96
+ // If filtering by phase number
97
+ if (phase) {
98
+ const normalized = normalizePhaseName(phase);
99
+ const match = dirs.find(d => phaseTokenMatches(d, normalized));
100
+ if (!match) {
101
+ output({ files: [], count: 0, phase_dir: null, error: 'Phase not found' }, raw, '');
102
+ return;
103
+ }
104
+ dirs = [match];
105
+ }
106
+
107
+ // If listing files of a specific type
108
+ if (type) {
109
+ const files = [];
110
+ const warnings = [];
111
+ for (const dir of dirs) {
112
+ const dirPath = path.join(phasesDir, dir);
113
+ const dirFiles = fs.readdirSync(dirPath);
114
+
115
+ let filtered;
116
+ if (type === 'plans') {
117
+ filtered = dirFiles.filter(isCanonicalPlanFile);
118
+ // #2893 — surface plan-shaped files the canonical filter rejected
119
+ // so callers (executor init, etc.) don't silently see zero plans.
120
+ const w = describeNonCanonicalPlans(dirFiles, filtered);
121
+ if (w) warnings.push(`${dir}: ${w}`);
122
+ } else if (type === 'summaries') {
123
+ filtered = dirFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
124
+ } else {
125
+ filtered = dirFiles;
126
+ }
127
+
128
+ files.push(...filtered.sort());
129
+ }
130
+
131
+ const result = {
132
+ files,
133
+ count: files.length,
134
+ phase_dir: phase ? dirs[0].replace(/^\d+(?:\.\d+)*-?/, '') : null,
135
+ };
136
+ if (warnings.length) result.warning = warnings.join(' | ');
137
+ output(result, raw, files.join('\n'));
138
+ return;
139
+ }
140
+
141
+ // Default: list directories
142
+ output({ directories: dirs, count: dirs.length }, raw, dirs.join('\n'));
143
+ } catch (e) {
144
+ error('Failed to list phases: ' + e.message);
145
+ }
146
+ }
147
+
148
+ function cmdPhaseNextDecimal(cwd, basePhase, raw) {
149
+ const phasesDir = path.join(planningDir(cwd), 'phases');
150
+ const normalized = normalizePhaseName(basePhase);
151
+
152
+ try {
153
+ let baseExists = false;
154
+ const decimalSet = new Set();
155
+
156
+ // Scan directory names for existing decimal phases
157
+ if (fs.existsSync(phasesDir)) {
158
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
159
+ const dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
160
+ baseExists = dirs.some(d => phaseTokenMatches(d, normalized));
161
+
162
+ const dirPattern = new RegExp(`^(?:[A-Z]{1,6}-)?${escapeRegex(normalized)}\\.(\\d+)`);
163
+ for (const dir of dirs) {
164
+ const match = dir.match(dirPattern);
165
+ if (match) decimalSet.add(parseInt(match[1], 10));
166
+ }
167
+ }
168
+
169
+ // Also scan ROADMAP.md for phase entries that may not have directories yet
170
+ const roadmapPath = path.join(planningDir(cwd), 'ROADMAP.md');
171
+ if (fs.existsSync(roadmapPath)) {
172
+ try {
173
+ const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
174
+ // #3537: padding-tolerant on both sides — `0*${escapeRegex(...)}`
175
+ // tolerated extra padding but not missing.
176
+ const phasePattern = new RegExp(
177
+ `#{2,4}\\s*Phase\\s+${phaseMarkdownRegexSource(normalized)}\\.(\\d+)\\s*:`, 'gi'
178
+ );
179
+ let pm;
180
+ while ((pm = phasePattern.exec(roadmapContent)) !== null) {
181
+ decimalSet.add(parseInt(pm[1], 10));
182
+ }
183
+ } catch { /* ROADMAP.md read failure is non-fatal */ }
184
+ }
185
+
186
+ // Build sorted list of existing decimals
187
+ const existingDecimals = Array.from(decimalSet)
188
+ .sort((a, b) => a - b)
189
+ .map(n => `${normalized}.${n}`);
190
+
191
+ // Calculate next decimal
192
+ let nextDecimal;
193
+ if (decimalSet.size === 0) {
194
+ nextDecimal = `${normalized}.1`;
195
+ } else {
196
+ nextDecimal = `${normalized}.${Math.max(...decimalSet) + 1}`;
197
+ }
198
+
199
+ output(
200
+ {
201
+ found: baseExists,
202
+ base_phase: normalized,
203
+ next: nextDecimal,
204
+ existing: existingDecimals,
205
+ },
206
+ raw,
207
+ nextDecimal
208
+ );
209
+ } catch (e) {
210
+ error('Failed to calculate next decimal phase: ' + e.message);
211
+ }
212
+ }
213
+
214
+ function getRoadmapModeForPhase(cwd, phaseNum) {
215
+ const roadmapPath = path.join(planningDir(cwd), 'ROADMAP.md');
216
+ if (!fs.existsSync(roadmapPath)) return null;
217
+
218
+ const rawContent = fs.readFileSync(roadmapPath, 'utf-8');
219
+ const milestoneContent = extractCurrentMilestone(rawContent, cwd);
220
+ const fullContent = stripShippedMilestones(rawContent);
221
+ const escapedPhase = phaseMarkdownRegexSource(phaseNum);
222
+ const phaseHeader = new RegExp(`#{2,4}\\s*Phase\\s+${escapedPhase}\\s*:`, 'i');
223
+
224
+ for (const content of [milestoneContent, fullContent]) {
225
+ const headerMatch = content.match(phaseHeader);
226
+ if (!headerMatch || headerMatch.index === undefined) continue;
227
+
228
+ const sectionStart = headerMatch.index;
229
+ const rest = content.slice(sectionStart);
230
+ const nextHeader = rest.slice(headerMatch[0].length).match(/\n#{2,4}\s+Phase\s+\S/i);
231
+ const sectionEnd = nextHeader ? sectionStart + headerMatch[0].length + nextHeader.index : content.length;
232
+ const section = content.slice(sectionStart, sectionEnd);
233
+ const modeMatch = section.match(/\*\*Mode(?::\*\*|\*\*:)\s*([^\n]+)/i);
234
+ if (modeMatch) return modeMatch[1].trim().toLowerCase();
235
+ }
236
+
237
+ return null;
238
+ }
239
+
240
+ function cmdPhaseMvpMode(cwd, args, raw) {
241
+ const phaseNum = args[0];
242
+ if (!phaseNum) {
243
+ error('Usage: phase.mvp-mode <phase-number> [--cli-flag]', ERROR_REASON.USAGE);
244
+ }
245
+
246
+ const cliFlagPresent = args.includes('--cli-flag');
247
+ const roadmapMode = getRoadmapModeForPhase(cwd, phaseNum);
248
+ const config = loadConfig(cwd);
249
+ const configMvpMode = Boolean(config.mvp_mode);
250
+
251
+ let active = false;
252
+ let source = 'none';
253
+ if (cliFlagPresent) {
254
+ active = true;
255
+ source = 'cli_flag';
256
+ } else if (roadmapMode === 'mvp') {
257
+ active = true;
258
+ source = 'roadmap';
259
+ } else if (configMvpMode) {
260
+ active = true;
261
+ source = 'config';
262
+ }
263
+
264
+ output({
265
+ active,
266
+ source,
267
+ roadmap_mode: roadmapMode,
268
+ config_mvp_mode: configMvpMode,
269
+ cli_flag_present: cliFlagPresent,
270
+ }, raw);
271
+ }
272
+
273
+ function cmdFindPhase(cwd, phase, raw) {
274
+ if (!phase) {
275
+ error('phase identifier required');
276
+ }
277
+
278
+ const planBase = planningDir(cwd);
279
+ const normalized = normalizePhaseName(phase);
280
+ const notFound = { found: false, directory: null, phase_number: null, phase_name: null, plans: [], summaries: [], searched_directories: [] };
281
+
282
+ // Build candidate search dirs: flat layout first, then milestone-archive layout.
283
+ const searchDirs = [];
284
+ const flatPhasesDir = path.join(planBase, 'phases');
285
+ if (fs.existsSync(flatPhasesDir)) searchDirs.push(flatPhasesDir);
286
+ try {
287
+ const milestonesDir = path.join(planBase, 'milestones');
288
+ const entries = fs.readdirSync(milestonesDir, { withFileTypes: true })
289
+ .filter(e => e.isDirectory() && /^v\d+.*-phases$/.test(e.name))
290
+ .sort((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true }));
291
+ for (const e of entries) {
292
+ searchDirs.push(path.join(milestonesDir, e.name));
293
+ }
294
+ } catch { /* no milestones dir */ }
295
+
296
+ notFound.searched_directories = searchDirs.map((searchDir) =>
297
+ toPosixPath(path.join(path.relative(cwd, planBase), path.relative(planBase, searchDir))));
298
+
299
+ for (const searchDir of searchDirs) {
300
+ try {
301
+ const entries = fs.readdirSync(searchDir, { withFileTypes: true });
302
+ const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort((a, b) => comparePhaseNum(a, b));
303
+
304
+ const match = dirs.find(d => phaseTokenMatches(d, normalized));
305
+ if (!match) continue;
306
+
307
+ // Extract phase number — supports project-code-prefixed (CK-01-name), numeric (01-name), and custom IDs
308
+ const dirMatch = match.match(/^(?:[A-Z]{1,6}-)(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i)
309
+ || match.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i);
310
+ const phaseNumber = dirMatch ? dirMatch[1] : normalized;
311
+ const phaseName = dirMatch && dirMatch[2] ? dirMatch[2] : null;
312
+
313
+ const phaseDir = path.join(searchDir, match);
314
+ const phaseFiles = fs.readdirSync(phaseDir);
315
+ const plans = phaseFiles.filter(isCanonicalPlanFile).sort();
316
+ const summaries = phaseFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md').sort();
317
+ // #2893 — same diagnostic as phase-plan-index for consistency.
318
+ const planNamingWarning = describeNonCanonicalPlans(phaseFiles, plans);
319
+
320
+ const result = {
321
+ found: true,
322
+ directory: toPosixPath(path.join(path.relative(cwd, planBase), path.relative(planBase, searchDir), match)),
323
+ phase_number: phaseNumber,
324
+ phase_name: phaseName,
325
+ plans,
326
+ summaries,
327
+ };
328
+ if (planNamingWarning) result.warning = planNamingWarning;
329
+
330
+ output(result, raw, result.directory);
331
+ return;
332
+ } catch { continue; }
333
+ }
334
+
335
+ output(notFound, raw, '');
336
+ }
337
+
338
+ function extractObjective(content) {
339
+ const m = content.match(/<objective>\s*\n?\s*(.+)/);
340
+ return m ? m[1].trim() : null;
341
+ }
342
+
343
+ function cmdPhasePlanIndex(cwd, phase, raw) {
344
+ if (!phase) {
345
+ error('phase required for phase-plan-index');
346
+ }
347
+
348
+ const phasesDir = path.join(planningDir(cwd), 'phases');
349
+ const normalized = normalizePhaseName(phase);
350
+
351
+ // Find phase directory
352
+ let phaseDir = null;
353
+ let phaseDirName = null;
354
+ try {
355
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
356
+ const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort((a, b) => comparePhaseNum(a, b));
357
+ const match = dirs.find(d => phaseTokenMatches(d, normalized));
358
+ if (match) {
359
+ phaseDir = path.join(phasesDir, match);
360
+ phaseDirName = match;
361
+ }
362
+ } catch {
363
+ // phases dir doesn't exist
364
+ }
365
+
366
+ if (!phaseDir) {
367
+ output({ phase: normalized, error: 'Phase not found', plans: [], waves: {}, incomplete: [], has_checkpoints: false }, raw);
368
+ return;
369
+ }
370
+
371
+ // Get all files in phase directory
372
+ const phaseFiles = fs.readdirSync(phaseDir);
373
+ const planFiles = phaseFiles.filter(isCanonicalPlanFile).sort();
374
+ const summaryFiles = phaseFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
375
+ // #2893 — surface plan-shaped files the canonical filter rejected so a
376
+ // misnamed plan never silently produces plan_count: 0 at executor init.
377
+ const planNamingWarning = describeNonCanonicalPlans(phaseFiles, planFiles);
378
+
379
+ // Build set of plan IDs with summaries
380
+ const completedPlanIds = new Set(
381
+ summaryFiles.flatMap(s => {
382
+ const exact = s.replace('-SUMMARY.md', '').replace('SUMMARY.md', '');
383
+ const canonical = extractCanonicalPlanId(s);
384
+ return canonical === exact ? [exact] : [exact, canonical];
385
+ })
386
+ );
387
+
388
+ // ── Pass 1: parse each plan file ─────────────────────────────────────────
389
+
390
+ const rawPlans = [];
391
+
392
+ for (const planFile of planFiles) {
393
+ const planId = planFile.replace('-PLAN.md', '').replace('PLAN.md', '');
394
+ const planPath = path.join(phaseDir, planFile);
395
+ const content = fs.readFileSync(planPath, 'utf-8');
396
+ const fm = extractFrontmatter(content);
397
+
398
+ // Count tasks: XML <task> tags (canonical) or ## Task N markdown (legacy)
399
+ const xmlTasks = content.match(/<task[\s>]/gi) || [];
400
+ const mdTasks = content.match(/##\s*Task\s*\d+/gi) || [];
401
+ const taskCount = xmlTasks.length || mdTasks.length;
402
+
403
+ // Parse wave as integer — use nullish handling so wave: 0 is preserved.
404
+ // parseInt returns NaN for missing/non-numeric values; fall back to null
405
+ // (meaning "no declared wave") so downstream can apply the topo default.
406
+ const parsedWave = parseInt(fm.wave, 10);
407
+ const declaredWave = Number.isNaN(parsedWave) ? null : parsedWave;
408
+
409
+ // Parse depends_on — normalise to string[]
410
+ let dependsOn = [];
411
+ const fmDeps = fm['depends_on'];
412
+ if (Array.isArray(fmDeps)) {
413
+ dependsOn = fmDeps.map(String);
414
+ } else if (typeof fmDeps === 'string' && fmDeps.trim() !== '') {
415
+ dependsOn = [fmDeps];
416
+ }
417
+
418
+ // Parse autonomous (default true if not specified)
419
+ let autonomous = true;
420
+ if (fm.autonomous !== undefined) {
421
+ autonomous = fm.autonomous === 'true' || fm.autonomous === true;
422
+ }
423
+
424
+ // Parse files_modified (underscore is canonical; also accept hyphenated for compat)
425
+ let filesModified = [];
426
+ const fmFiles = fm['files_modified'] || fm['files-modified'];
427
+ if (fmFiles) {
428
+ filesModified = Array.isArray(fmFiles) ? fmFiles : [fmFiles];
429
+ }
430
+
431
+ const hasSummary = completedPlanIds.has(planId) || completedPlanIds.has(extractCanonicalPlanId(planFile));
432
+
433
+ rawPlans.push({
434
+ id: planId,
435
+ declaredWave,
436
+ dependsOn,
437
+ autonomous,
438
+ objective: extractObjective(content) || fm.objective || null,
439
+ filesModified,
440
+ taskCount,
441
+ hasSummary,
442
+ });
443
+ }
444
+
445
+ // ── Pass 2: topological level assignment via depends_on DAG ──────────────
446
+
447
+ // Build a map from plan ID → raw plan for fast lookup.
448
+ // Deps that reference plans outside this phase are treated as external and ignored.
449
+ const planMap = new Map(rawPlans.map(p => [p.id, p]));
450
+ // Secondary index: canonical prefix → full plan ID, so depends_on: ['03-01'] resolves
451
+ // to '03-01-auth-hardening-PLAN.md'-derived ID '03-01-auth-hardening' (k015).
452
+ const canonicalToId = new Map(rawPlans.map(p => [extractCanonicalPlanId(p.id), p.id]));
453
+
454
+ // Kahn's algorithm — compute in-degree and adjacency for in-phase deps only.
455
+ const level = new Map();
456
+ const inDeg = new Map();
457
+ const adj = new Map();
458
+
459
+ for (const p of rawPlans) {
460
+ if (!inDeg.has(p.id)) inDeg.set(p.id, 0);
461
+ if (!adj.has(p.id)) adj.set(p.id, []);
462
+ for (const dep of p.dependsOn) {
463
+ // Accept both full-stem ('03-01-auth-hardening') and canonical-prefix ('03-01') forms.
464
+ const resolvedDep = planMap.has(dep) ? dep : canonicalToId.get(dep);
465
+ if (!resolvedDep) continue; // external dep — ignore
466
+ if (!adj.has(resolvedDep)) adj.set(resolvedDep, []);
467
+ adj.get(resolvedDep).push(p.id);
468
+ inDeg.set(p.id, (inDeg.get(p.id) ?? 0) + 1);
469
+ }
470
+ }
471
+
472
+ // Start with nodes that have no in-phase dependencies.
473
+ const queue = [];
474
+ for (const p of rawPlans) {
475
+ if ((inDeg.get(p.id) ?? 0) === 0) {
476
+ queue.push(p.id);
477
+ level.set(p.id, 0);
478
+ }
479
+ }
480
+
481
+ let visited = 0;
482
+ while (queue.length > 0) {
483
+ const cur = queue.shift();
484
+ visited++;
485
+ const curLevel = level.get(cur);
486
+ for (const dep of (adj.get(cur) ?? [])) {
487
+ const newLevel = curLevel + 1;
488
+ if (newLevel > (level.get(dep) ?? -1)) {
489
+ level.set(dep, newLevel);
490
+ }
491
+ inDeg.set(dep, inDeg.get(dep) - 1);
492
+ if (inDeg.get(dep) === 0) {
493
+ queue.push(dep);
494
+ }
495
+ }
496
+ }
497
+
498
+ // Cycle detection — any node not visited has a cycle.
499
+ if (visited < rawPlans.length) {
500
+ const cycleNodes = rawPlans.filter(p => !level.has(p.id)).map(p => p.id);
501
+ error(`depends_on cycle detected in phase ${normalized} — cycle involves: ${cycleNodes.join(', ')}`);
502
+ return;
503
+ }
504
+
505
+ // ── Pass 3: determine lowest bucket key and build output ─────────────────
506
+
507
+ // If any plan has declared wave: 0, the lowest level maps to "0"; otherwise "1".
508
+ const anyWaveZero = rawPlans.some(p => p.declaredWave === 0);
509
+ const levelOffset = anyWaveZero ? 0 : 1;
510
+
511
+ const plans = [];
512
+ const waves = {};
513
+ const incomplete = [];
514
+ let hasCheckpoints = false;
515
+ const warnings = [];
516
+
517
+ for (const raw of rawPlans) {
518
+ if (!raw.autonomous) {
519
+ hasCheckpoints = true;
520
+ }
521
+ if (!raw.hasSummary) {
522
+ incomplete.push(raw.id);
523
+ }
524
+
525
+ // Computed wave = topological level + offset (so lowest level → 0 or 1).
526
+ const computedWave = (level.get(raw.id) ?? 0) + levelOffset;
527
+
528
+ // The effective wave used for bucketing is always the computed topo level.
529
+ // If the plan declared a wave that disagrees, emit a non-fatal warning.
530
+ const effectiveWave = computedWave;
531
+ if (raw.declaredWave !== null && raw.declaredWave !== computedWave) {
532
+ warnings.push(
533
+ `Plan ${raw.id}: declared wave: ${raw.declaredWave} but depends_on DAG places it in wave ${computedWave}`,
534
+ );
535
+ }
536
+
537
+ const plan = {
538
+ id: raw.id,
539
+ wave: effectiveWave,
540
+ depends_on: raw.dependsOn,
541
+ autonomous: raw.autonomous,
542
+ objective: raw.objective,
543
+ files_modified: raw.filesModified,
544
+ task_count: raw.taskCount,
545
+ has_summary: raw.hasSummary,
546
+ };
547
+
548
+ plans.push(plan);
549
+
550
+ const waveKey = String(effectiveWave);
551
+ if (!waves[waveKey]) {
552
+ waves[waveKey] = [];
553
+ }
554
+ waves[waveKey].push(raw.id);
555
+ }
556
+
557
+ const result = {
558
+ phase: normalized,
559
+ plans,
560
+ waves,
561
+ incomplete,
562
+ has_checkpoints: hasCheckpoints,
563
+ };
564
+ if (planNamingWarning) result.warning = planNamingWarning;
565
+ if (warnings.length > 0) result.warnings = warnings;
566
+
567
+ output(result, raw);
568
+ }
569
+
570
+ function cmdPhaseAdd(cwd, description, raw, customId) {
571
+ if (!description) {
572
+ error('description required for phase add');
573
+ }
574
+
575
+ const config = loadConfig(cwd);
576
+ const roadmapPath = path.join(planningDir(cwd), 'ROADMAP.md');
577
+ if (!fs.existsSync(roadmapPath)) {
578
+ error('ROADMAP.md not found');
579
+ }
580
+
581
+ const slug = generateSlugInternal(description);
582
+
583
+ // Wrap entire read-modify-write in lock to prevent concurrent corruption
584
+ const { newPhaseId, dirName } = withPlanningLock(cwd, () => {
585
+ const rawContent = fs.readFileSync(roadmapPath, 'utf-8');
586
+ const content = extractCurrentMilestone(rawContent, cwd);
587
+
588
+ // Optional project code prefix (e.g., 'CK' → 'CK-01-foundation')
589
+ const projectCode = config.project_code || '';
590
+ const prefix = projectCode ? `${projectCode}-` : '';
591
+
592
+ let _newPhaseId;
593
+ let _dirName;
594
+
595
+ if (customId || config.phase_naming === 'custom') {
596
+ // Custom phase naming: use provided ID or generate from description
597
+ _newPhaseId = customId || slug.toUpperCase().replace(/-/g, '-');
598
+ if (!_newPhaseId) error('--id required when phase_naming is "custom"');
599
+ _dirName = `${prefix}${_newPhaseId}-${slug}`;
600
+ } else {
601
+ // Sequential mode: find highest integer phase number from two sources:
602
+ // 1. ROADMAP.md (current milestone only)
603
+ // 2. .planning/phases/ on disk (orphan directories not tracked in roadmap)
604
+ // Skip 999.x backlog phases — they live outside the active sequence
605
+ const phasePattern = /#{2,4}\s*Phase\s+(\d+)[A-Z]?(?:\.\d+)*:/gi;
606
+ let maxPhase = 0;
607
+ let m;
608
+ while ((m = phasePattern.exec(content)) !== null) {
609
+ const num = parseInt(m[1], 10);
610
+ if (num === 999) continue; // backlog phases use 999.x numbering
611
+ if (num > maxPhase) maxPhase = num;
612
+ }
613
+
614
+ // Also scan .planning/phases/ for orphan directories not tracked in ROADMAP.
615
+ // Directory names follow: [PREFIX-]NN-slug (e.g. 03-api or CK-05-old-feature).
616
+ // Strip the optional project_code prefix before extracting the leading integer.
617
+ const phasesOnDisk = path.join(planningDir(cwd), 'phases');
618
+ if (fs.existsSync(phasesOnDisk)) {
619
+ const dirNumPattern = /^(?:[A-Z][A-Z0-9]*-)?(\d+)-/;
620
+ for (const entry of fs.readdirSync(phasesOnDisk)) {
621
+ const match = entry.match(dirNumPattern);
622
+ if (!match) continue;
623
+ const num = parseInt(match[1], 10);
624
+ if (num === 999) continue; // skip backlog orphans
625
+ if (num > maxPhase) maxPhase = num;
626
+ }
627
+ }
628
+
629
+ _newPhaseId = maxPhase + 1;
630
+ const paddedNum = String(_newPhaseId).padStart(2, '0');
631
+ _dirName = `${prefix}${paddedNum}-${slug}`;
632
+ }
633
+
634
+ const dirPath = path.join(planningDir(cwd), 'phases', _dirName);
635
+
636
+ // Create directory with .gitkeep so git tracks empty folders
637
+ platformEnsureDir(dirPath);
638
+ platformWriteSync(path.join(dirPath, '.gitkeep'), '');
639
+
640
+ // Build phase entry
641
+ const dependsOn = config.phase_naming === 'custom' ? '' : `\n**Depends on:** Phase ${typeof _newPhaseId === 'number' ? _newPhaseId - 1 : 'TBD'}`;
642
+ const phaseEntry = `\n### Phase ${_newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run ${formatGsdSlash('plan-phase', resolveRuntime(cwd))} ${_newPhaseId} to break down)\n`;
643
+
644
+ // Find insertion point: before last "---" or at end
645
+ let updatedContent;
646
+ const lastSeparator = rawContent.lastIndexOf('\n---');
647
+ if (lastSeparator > 0) {
648
+ updatedContent = rawContent.slice(0, lastSeparator) + phaseEntry + rawContent.slice(lastSeparator);
649
+ } else {
650
+ updatedContent = rawContent + phaseEntry;
651
+ }
652
+
653
+ platformWriteSync(roadmapPath, updatedContent);
654
+ return { newPhaseId: _newPhaseId, dirName: _dirName };
655
+ });
656
+
657
+ const result = {
658
+ phase_number: typeof newPhaseId === 'number' ? newPhaseId : String(newPhaseId),
659
+ padded: typeof newPhaseId === 'number' ? String(newPhaseId).padStart(2, '0') : String(newPhaseId),
660
+ name: description,
661
+ slug,
662
+ directory: toPosixPath(path.join(path.relative(cwd, planningDir(cwd)), 'phases', dirName)),
663
+ naming_mode: config.phase_naming,
664
+ };
665
+
666
+ output(result, raw, result.padded);
667
+ }
668
+
669
+ function cmdPhaseAddBatch(cwd, descriptions, raw) {
670
+ if (!Array.isArray(descriptions) || descriptions.length === 0) {
671
+ error('descriptions array required for phase add-batch');
672
+ }
673
+ const config = loadConfig(cwd);
674
+ const roadmapPath = path.join(planningDir(cwd), 'ROADMAP.md');
675
+ if (!fs.existsSync(roadmapPath)) { error('ROADMAP.md not found'); }
676
+ const projectCode = config.project_code || '';
677
+ const prefix = projectCode ? `${projectCode}-` : '';
678
+
679
+ const results = withPlanningLock(cwd, () => {
680
+ let rawContent = fs.readFileSync(roadmapPath, 'utf-8');
681
+ const content = extractCurrentMilestone(rawContent, cwd);
682
+ let maxPhase = 0;
683
+ if (config.phase_naming !== 'custom') {
684
+ const phasePattern = /#{2,4}\s*Phase\s+(\d+)[A-Z]?(?:\.\d+)*:/gi;
685
+ let m;
686
+ while ((m = phasePattern.exec(content)) !== null) {
687
+ const num = parseInt(m[1], 10);
688
+ if (num === 999) continue;
689
+ if (num > maxPhase) maxPhase = num;
690
+ }
691
+ const phasesOnDisk = path.join(planningDir(cwd), 'phases');
692
+ if (fs.existsSync(phasesOnDisk)) {
693
+ const dirNumPattern = /^(?:[A-Z][A-Z0-9]*-)?(\d+)-/;
694
+ for (const entry of fs.readdirSync(phasesOnDisk)) {
695
+ const match = entry.match(dirNumPattern);
696
+ if (!match) continue;
697
+ const num = parseInt(match[1], 10);
698
+ if (num === 999) continue;
699
+ if (num > maxPhase) maxPhase = num;
700
+ }
701
+ }
702
+ }
703
+ const added = [];
704
+ for (const description of descriptions) {
705
+ const slug = generateSlugInternal(description);
706
+ let newPhaseId, dirName;
707
+ if (config.phase_naming === 'custom') {
708
+ newPhaseId = slug.toUpperCase().replace(/-/g, '-');
709
+ dirName = `${prefix}${newPhaseId}-${slug}`;
710
+ } else {
711
+ maxPhase += 1;
712
+ newPhaseId = maxPhase;
713
+ dirName = `${prefix}${String(newPhaseId).padStart(2, '0')}-${slug}`;
714
+ }
715
+ const dirPath = path.join(planningDir(cwd), 'phases', dirName);
716
+ platformEnsureDir(dirPath);
717
+ platformWriteSync(path.join(dirPath, '.gitkeep'), '');
718
+ const dependsOn = config.phase_naming === 'custom' ? '' : `\n**Depends on:** Phase ${typeof newPhaseId === 'number' ? newPhaseId - 1 : 'TBD'}`;
719
+ const phaseEntry = `\n### Phase ${newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run ${formatGsdSlash('plan-phase', resolveRuntime(cwd))} ${newPhaseId} to break down)\n`;
720
+ const lastSeparator = rawContent.lastIndexOf('\n---');
721
+ rawContent = lastSeparator > 0
722
+ ? rawContent.slice(0, lastSeparator) + phaseEntry + rawContent.slice(lastSeparator)
723
+ : rawContent + phaseEntry;
724
+ added.push({
725
+ phase_number: typeof newPhaseId === 'number' ? newPhaseId : String(newPhaseId),
726
+ padded: typeof newPhaseId === 'number' ? String(newPhaseId).padStart(2, '0') : String(newPhaseId),
727
+ name: description,
728
+ slug,
729
+ directory: toPosixPath(path.join(path.relative(cwd, planningDir(cwd)), 'phases', dirName)),
730
+ naming_mode: config.phase_naming,
731
+ });
732
+ }
733
+ platformWriteSync(roadmapPath, rawContent);
734
+ return added;
735
+ });
736
+ output({ phases: results, count: results.length }, raw);
737
+ }
738
+
739
+ function cmdPhaseInsert(cwd, afterPhase, description, raw) {
740
+ if (!afterPhase || !description) {
741
+ error('after-phase and description required for phase insert');
742
+ }
743
+
744
+ const roadmapPath = path.join(planningDir(cwd), 'ROADMAP.md');
745
+ if (!fs.existsSync(roadmapPath)) {
746
+ error('ROADMAP.md not found');
747
+ }
748
+
749
+ const slug = generateSlugInternal(description);
750
+
751
+ // Wrap entire read-modify-write in lock to prevent concurrent corruption
752
+ const { decimalPhase, dirName } = withPlanningLock(cwd, () => {
753
+ const rawContent = fs.readFileSync(roadmapPath, 'utf-8');
754
+ const content = extractCurrentMilestone(rawContent, cwd);
755
+
756
+ // Normalize input then route through canonical padding-tolerant fragment
757
+ // (#3537). The prior hand-rolled `0*${unpadded}` worked for the integer
758
+ // base but duplicated logic — funnel it through the shared helper.
759
+ const normalizedAfter = normalizePhaseName(afterPhase);
760
+ const afterPhaseEscaped = phaseMarkdownRegexSource(normalizedAfter);
761
+ const targetPattern = new RegExp(`#{2,4}\\s*Phase\\s+${afterPhaseEscaped}:`, 'i');
762
+ const headingMatch = targetPattern.test(content);
763
+
764
+ // #3815: also recognise the checked-bullet phase format used by projects
765
+ // that list phases as `- [ ] **Phase N: name**` or `- [ ] Phase N: name`
766
+ // (both bold and plain variants). Mirrors phaseRemove / phaseComplete.
767
+ //
768
+ // Bullet-style only activates when there are NO heading-style phases in the
769
+ // milestone content. A bullet entry in a hybrid (headings + bullets) ROADMAP
770
+ // means the detail section is missing — that is the #3098 case and must keep
771
+ // producing the "missing a detail section" error.
772
+ const bulletPattern = new RegExp(
773
+ `-\\s*\\[[ x]\\]\\s*(?:\\*\\*)?Phase\\s+${afterPhaseEscaped}[:\\s]`,
774
+ 'i',
775
+ );
776
+ const anyHeadingPattern = /#{2,4}\s*Phase\s+\d/i;
777
+ const roadmapHasHeadingPhases = anyHeadingPattern.test(content);
778
+ const isBulletStyle = !headingMatch && bulletPattern.test(content) && !roadmapHasHeadingPhases;
779
+
780
+ if (!headingMatch && !isBulletStyle) {
781
+ // Bug #3098 parity: when the ROADMAP uses heading-style phases and only
782
+ // the summary checklist exists for this phase (no `### Phase N:` detail
783
+ // section), point the user at the missing detail section.
784
+ const checklistPattern = new RegExp(
785
+ `-\\s*\\[[ x]\\]\\s*(?:\\*\\*)?Phase\\s+${afterPhaseEscaped}[:\\s]`,
786
+ 'i',
787
+ );
788
+ if (checklistPattern.test(content)) {
789
+ error(`Phase ${afterPhase} exists in roadmap summary but is missing a detail section (### Phase ${afterPhase}: ...).`);
790
+ }
791
+ error(`Phase ${afterPhase} not found in ROADMAP.md`);
792
+ }
793
+
794
+ // Calculate next decimal by scanning both directories AND ROADMAP.md entries
795
+ const phasesDir = path.join(planningDir(cwd), 'phases');
796
+ const normalizedBase = normalizePhaseName(afterPhase);
797
+ const decimalSet = new Set();
798
+
799
+ try {
800
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
801
+ const dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
802
+ const decimalPattern = new RegExp(`^(?:[A-Z]{1,6}-)?${escapeRegex(normalizedBase)}\\.(\\d+)`);
803
+ for (const dir of dirs) {
804
+ const dm = dir.match(decimalPattern);
805
+ if (dm) decimalSet.add(parseInt(dm[1], 10));
806
+ }
807
+ } catch { /* intentionally empty */ }
808
+
809
+ // Also scan ROADMAP.md content (already loaded) for decimal entries.
810
+ // #3537: padding-tolerant fragment so un-padded `Phase 2.7:` is found
811
+ // when caller passes the padded base `02`.
812
+ const rmPhasePattern = new RegExp(
813
+ `#{2,4}\\s*Phase\\s+${phaseMarkdownRegexSource(normalizedBase)}\\.(\\d+)\\s*:`, 'gi'
814
+ );
815
+ let rmMatch;
816
+ while ((rmMatch = rmPhasePattern.exec(rawContent)) !== null) {
817
+ decimalSet.add(parseInt(rmMatch[1], 10));
818
+ }
819
+
820
+ const nextDecimal = decimalSet.size === 0 ? 1 : Math.max(...decimalSet) + 1;
821
+ const _decimalPhase = `${normalizedBase}.${nextDecimal}`;
822
+ // Optional project code prefix
823
+ const insertConfig = loadConfig(cwd);
824
+ const projectCode = insertConfig.project_code || '';
825
+ const pfx = projectCode ? `${projectCode}-` : '';
826
+ const _dirName = `${pfx}${_decimalPhase}-${slug}`;
827
+ const dirPath = path.join(planningDir(cwd), 'phases', _dirName);
828
+
829
+ // Create directory with .gitkeep so git tracks empty folders
830
+ platformEnsureDir(dirPath);
831
+ platformWriteSync(path.join(dirPath, '.gitkeep'), '');
832
+
833
+ let updatedContent;
834
+
835
+ if (isBulletStyle) {
836
+ // #3815: Insert in checked-bullet format, mirroring the style of the
837
+ // surrounding entries. Detect whether the matched bullet uses bold
838
+ // (`**Phase N: …**`) to preserve file-internal format consistency.
839
+ const boldBulletPattern = new RegExp(
840
+ `-\\s*\\[[ x]\\]\\s*\\*\\*Phase\\s+${afterPhaseEscaped}:`,
841
+ 'i',
842
+ );
843
+ const useBold = boldBulletPattern.test(content);
844
+ const phaseLabel = useBold
845
+ ? `**Phase ${_decimalPhase}: ${description}**`
846
+ : `Phase ${_decimalPhase}: ${description}`;
847
+ const bulletEntry = `\n- [ ] ${phaseLabel}`;
848
+
849
+ // Locate the target bullet line in the raw content
850
+ const targetBulletPattern = new RegExp(
851
+ `(-\\s*\\[[ x]\\]\\s*(?:\\*\\*)?Phase\\s+${afterPhaseEscaped}[:\\s][^\\n]*)`,
852
+ 'i',
853
+ );
854
+ const bulletMatchResult = rawContent.match(targetBulletPattern);
855
+ if (!bulletMatchResult) {
856
+ error(`Could not find Phase ${afterPhase} bullet line`);
857
+ }
858
+
859
+ const bulletLineEnd = rawContent.indexOf(bulletMatchResult[0]) + bulletMatchResult[0].length;
860
+ const afterBullet = rawContent.slice(bulletLineEnd);
861
+ const nextBulletMatch = afterBullet.match(/\n-\s*\[[ x]\]\s*(?:\*\*)?Phase\s+\d/i);
862
+
863
+ let insertIdx;
864
+ if (nextBulletMatch) {
865
+ insertIdx = bulletLineEnd + nextBulletMatch.index;
866
+ } else {
867
+ insertIdx = bulletLineEnd;
868
+ }
869
+
870
+ updatedContent = rawContent.slice(0, insertIdx) + bulletEntry + rawContent.slice(insertIdx);
871
+ } else {
872
+ // Heading-style insert (original path)
873
+ // Build phase entry
874
+ const phaseEntry = `\n### Phase ${_decimalPhase}: ${description} (INSERTED)\n\n**Goal:** [Urgent work - to be planned]\n**Requirements**: TBD\n**Depends on:** Phase ${afterPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run ${formatGsdSlash('plan-phase', resolveRuntime(cwd))} ${_decimalPhase} to break down)\n`;
875
+
876
+ // Insert after the target phase section
877
+ const headerPattern = new RegExp(`(#{2,4}\\s*Phase\\s+${afterPhaseEscaped}:[^\\n]*\\n)`, 'i');
878
+ const headerMatch = rawContent.match(headerPattern);
879
+ if (!headerMatch) {
880
+ error(`Could not find Phase ${afterPhase} header`);
881
+ }
882
+
883
+ const headerIdx = rawContent.indexOf(headerMatch[0]);
884
+ const afterHeader = rawContent.slice(headerIdx + headerMatch[0].length);
885
+ // #3691: `\d` → `\d[\d.]*` so decimal phase headings (e.g. `### Phase 02.3:`) are
886
+ // recognised as section boundaries.
887
+ const nextPhaseMatch = afterHeader.match(/\n#{2,4}\s+Phase\s+\d[\d.]*/i);
888
+
889
+ let insertIdx;
890
+ if (nextPhaseMatch) {
891
+ insertIdx = headerIdx + headerMatch[0].length + nextPhaseMatch.index;
892
+ } else {
893
+ insertIdx = rawContent.length;
894
+ }
895
+
896
+ updatedContent = rawContent.slice(0, insertIdx) + phaseEntry + rawContent.slice(insertIdx);
897
+ }
898
+
899
+ platformWriteSync(roadmapPath, updatedContent);
900
+ return { decimalPhase: _decimalPhase, dirName: _dirName };
901
+ });
902
+
903
+ const result = {
904
+ phase_number: decimalPhase,
905
+ after_phase: afterPhase,
906
+ name: description,
907
+ slug,
908
+ directory: toPosixPath(path.join(path.relative(cwd, planningDir(cwd)), 'phases', dirName)),
909
+ };
910
+
911
+ output(result, raw, decimalPhase);
912
+ }
913
+
914
+ /**
915
+ * Renumber sibling decimal phases after a decimal phase is removed.
916
+ * e.g. removing 06.2 → 06.3 becomes 06.2, 06.4 becomes 06.3, etc.
917
+ * Returns { renamedDirs, renamedFiles }.
918
+ */
919
+ function renameDecimalPhases(phasesDir, baseInt, removedDecimal) {
920
+ const renamedDirs = [], renamedFiles = [];
921
+ // Capture the zero-padded prefix (e.g. "06" from "06.3-slug") so the renamed
922
+ // directory preserves the original padding format.
923
+ const decPattern = new RegExp(`^(0*${baseInt})\\.(\\d+)-(.+)$`);
924
+ const dirs = readSubdirectories(phasesDir, true);
925
+ const toRename = dirs
926
+ .map(dir => { const m = dir.match(decPattern); return m ? { dir, prefix: m[1], oldDecimal: parseInt(m[2], 10), slug: m[3] } : null; })
927
+ .filter(item => item && item.oldDecimal > removedDecimal)
928
+ .sort((a, b) => b.oldDecimal - a.oldDecimal); // descending to avoid conflicts
929
+
930
+ for (const item of toRename) {
931
+ const newDecimal = item.oldDecimal - 1;
932
+ const oldPhaseId = `${baseInt}.${item.oldDecimal}`;
933
+ const newPhaseId = `${baseInt}.${newDecimal}`;
934
+ const newDirName = `${item.prefix}.${newDecimal}-${item.slug}`;
935
+ fs.renameSync(path.join(phasesDir, item.dir), path.join(phasesDir, newDirName));
936
+ renamedDirs.push({ from: item.dir, to: newDirName });
937
+ for (const f of fs.readdirSync(path.join(phasesDir, newDirName))) {
938
+ if (f.includes(oldPhaseId)) {
939
+ const newFileName = f.replace(oldPhaseId, newPhaseId);
940
+ fs.renameSync(path.join(phasesDir, newDirName, f), path.join(phasesDir, newDirName, newFileName));
941
+ renamedFiles.push({ from: f, to: newFileName });
942
+ }
943
+ }
944
+ }
945
+ return { renamedDirs, renamedFiles };
946
+ }
947
+
948
+ /**
949
+ * Renumber all integer phases after removedInt.
950
+ * e.g. removing phase 5 → phase 6 becomes 5, phase 7 becomes 6, etc.
951
+ * Returns { renamedDirs, renamedFiles }.
952
+ */
953
+ function renameIntegerPhases(phasesDir, removedInt) {
954
+ const renamedDirs = [], renamedFiles = [];
955
+ const dirs = readSubdirectories(phasesDir, true);
956
+ const toRename = dirs
957
+ .map(dir => {
958
+ const m = dir.match(/^(\d+)([A-Z])?(?:\.(\d+))?-(.+)$/i);
959
+ if (!m) return null;
960
+ const dirInt = parseInt(m[1], 10);
961
+ return (dirInt > removedInt && dirInt < 999) ? { dir, oldInt: dirInt, letter: m[2] ? m[2].toUpperCase() : '', decimal: m[3] ? parseInt(m[3], 10) : null, slug: m[4] } : null;
962
+ })
963
+ .filter(Boolean)
964
+ .sort((a, b) => a.oldInt !== b.oldInt ? b.oldInt - a.oldInt : (b.decimal || 0) - (a.decimal || 0));
965
+
966
+ for (const item of toRename) {
967
+ const newInt = item.oldInt - 1;
968
+ const newPadded = String(newInt).padStart(2, '0');
969
+ const oldPadded = String(item.oldInt).padStart(2, '0');
970
+ const letterSuffix = item.letter || '';
971
+ const decimalSuffix = item.decimal !== null ? `.${item.decimal}` : '';
972
+ const oldPrefix = `${oldPadded}${letterSuffix}${decimalSuffix}`;
973
+ const newPrefix = `${newPadded}${letterSuffix}${decimalSuffix}`;
974
+ const newDirName = `${newPrefix}-${item.slug}`;
975
+ fs.renameSync(path.join(phasesDir, item.dir), path.join(phasesDir, newDirName));
976
+ renamedDirs.push({ from: item.dir, to: newDirName });
977
+ for (const f of fs.readdirSync(path.join(phasesDir, newDirName))) {
978
+ if (f.startsWith(oldPrefix)) {
979
+ const newFileName = newPrefix + f.slice(oldPrefix.length);
980
+ fs.renameSync(path.join(phasesDir, newDirName, f), path.join(phasesDir, newDirName, newFileName));
981
+ renamedFiles.push({ from: f, to: newFileName });
982
+ }
983
+ }
984
+ }
985
+ return { renamedDirs, renamedFiles };
986
+ }
987
+
988
+ function decrementRoadmapPhaseNumber(raw, removedInt) {
989
+ const num = parseInt(raw, 10);
990
+ if (!Number.isInteger(num) || num <= removedInt || num >= 999) return raw;
991
+ return String(num - 1);
992
+ }
993
+
994
+ function decrementRoadmapPhaseToken(raw, removedInt) {
995
+ const match = String(raw).match(/^(\d+)(\.\d+)?$/);
996
+ if (!match) return raw;
997
+ const num = parseInt(match[1], 10);
998
+ if (!Number.isInteger(num) || num <= removedInt || num >= 999) return raw;
999
+ return `${num - 1}${match[2] || ''}`;
1000
+ }
1001
+
1002
+ function decrementRoadmapPaddedPhaseNumber(raw, removedInt) {
1003
+ const num = parseInt(raw, 10);
1004
+ if (!Number.isInteger(num) || num <= removedInt || num >= 999) return raw;
1005
+ return String(num - 1).padStart(raw.length, '0');
1006
+ }
1007
+
1008
+ /**
1009
+ * Remove a phase section from ROADMAP.md and renumber all subsequent integer phases.
1010
+ */
1011
+ function updateRoadmapAfterPhaseRemoval(roadmapPath, targetPhase, isDecimal, removedInt, cwd) {
1012
+ // Wrap entire read-modify-write in lock to prevent concurrent corruption
1013
+ withPlanningLock(cwd, () => {
1014
+ let content = fs.readFileSync(roadmapPath, 'utf-8');
1015
+ const escaped = escapeRegex(targetPhase);
1016
+
1017
+ // #3601: the end-of-section lookahead is depth-aware. It captures the
1018
+ // hash count of the header being removed and stops only at a subsequent
1019
+ // header of the SAME depth, whether integer or decimal. This preserves
1020
+ // two existing contracts:
1021
+ //
1022
+ // (#3601 case) Remove `### Phase 2:` and stop at `### Phase 2.1:` —
1023
+ // `Phase 2.1` is a peer-level decimal phase (depth 3) and must be
1024
+ // preserved.
1025
+ //
1026
+ // (#3355 case) Remove `### Phase 27:` and continue past
1027
+ // `#### Phase 27.1:` (depth 4 — a child of Phase 27) until the next
1028
+ // depth-3 header. The child decimal is part of the integer phase
1029
+ // being removed.
1030
+ //
1031
+ // The `(?!#)` negative lookahead after the backreference prevents the
1032
+ // depth-3 match from being satisfied by a depth-4+ header that starts
1033
+ // with the same three hashes.
1034
+ content = content.replace(new RegExp(`\\n?(?<h>#{2,4})\\s*Phase\\s+${escaped}\\s*:[\\s\\S]*?(?=\\n\\k<h>(?!#)\\s+Phase\\s+[^\\n:]+\\s*:|$)`, 'i'), '');
1035
+ content = content.replace(new RegExp(`\\n?-\\s*\\[[ x]\\]\\s*.*Phase\\s+${escaped}[:\\s][^\\n]*`, 'gi'), '');
1036
+ content = content.replace(new RegExp(`\\n?\\|\\s*${escaped}\\.?\\s[^|]*\\|[^\\n]*`, 'gi'), '');
1037
+
1038
+ if (!isDecimal) {
1039
+ content = content.replace(
1040
+ /(#{2,4}\s*Phase\s+)(\d+(?:\.\d+)?)(\s*:)/gi,
1041
+ (_match, prefix, num, suffix) => `${prefix}${decrementRoadmapPhaseToken(num, removedInt)}${suffix}`
1042
+ );
1043
+ content = content.replace(
1044
+ /(-\s*\[[ x]\]\s*.*?Phase\s+)(\d+)(\s*:|\s+)/gi,
1045
+ (_match, prefix, num, suffix) => `${prefix}${decrementRoadmapPhaseNumber(num, removedInt)}${suffix}`
1046
+ );
1047
+ content = content.replace(
1048
+ /(\|\s*)(\d+)(\.\s)/g,
1049
+ (_match, prefix, num, suffix) => `${prefix}${decrementRoadmapPhaseNumber(num, removedInt)}${suffix}`
1050
+ );
1051
+ // #3602: extend the suffix lookahead so slugged plan filenames like
1052
+ // `07-01-cherry-pick-foundation-PLAN.md` match too. The previous
1053
+ // pattern only allowed a compact `-(PLAN|SUMMARY).md` immediately
1054
+ // after the plan number (or no suffix at all); a slug between the
1055
+ // number and the `-PLAN.md` / `-SUMMARY.md` suffix made the
1056
+ // lookahead fail and left the stale `07-01-` prefix in ROADMAP
1057
+ // text while the on-disk file was already renamed to `06-01-…`.
1058
+ // The slug segment `(?:-[A-Za-z][A-Za-z0-9-]*)*` allows any number
1059
+ // of kebab-case tokens before the canonical PLAN/SUMMARY suffix.
1060
+ content = content.replace(
1061
+ /(?<![0-9-])(\d{2})-(\d{2})(?=(?:(?:-[A-Za-z][A-Za-z0-9-]*)*-(?:PLAN|SUMMARY)\.md)|(?![0-9-]))/g,
1062
+ (_match, phaseNum, planNum) => `${decrementRoadmapPaddedPhaseNumber(phaseNum, removedInt)}-${planNum}`
1063
+ );
1064
+ content = content.replace(
1065
+ /(\*\*Depends on\*\*\s*:\s*Phase\s+)(\d+(?:\.\d+)?)\b/gi,
1066
+ (_match, prefix, num) => `${prefix}${decrementRoadmapPhaseToken(num, removedInt)}`
1067
+ );
1068
+ content = content.replace(
1069
+ /(Depends on:\*\*\s*Phase\s+)(\d+(?:\.\d+)?)\b/gi,
1070
+ (_match, prefix, num) => `${prefix}${decrementRoadmapPhaseToken(num, removedInt)}`
1071
+ );
1072
+ }
1073
+
1074
+ platformWriteSync(roadmapPath, content);
1075
+ });
1076
+ }
1077
+
1078
+ function cmdPhaseRemove(cwd, targetPhase, options, raw) {
1079
+ if (!targetPhase) error('phase number required for phase remove');
1080
+
1081
+ const roadmapPath = path.join(planningDir(cwd), 'ROADMAP.md');
1082
+ const phasesDir = path.join(planningDir(cwd), 'phases');
1083
+
1084
+ if (!fs.existsSync(roadmapPath)) error('ROADMAP.md not found');
1085
+
1086
+ const normalized = normalizePhaseName(targetPhase);
1087
+ const isDecimal = targetPhase.includes('.');
1088
+ const force = options.force || false;
1089
+
1090
+ // Find target directory
1091
+ const targetDir = readSubdirectories(phasesDir, true)
1092
+ .find(d => phaseTokenMatches(d, normalized)) || null;
1093
+
1094
+ // Guard against removing executed work
1095
+ if (targetDir && !force) {
1096
+ const files = fs.readdirSync(path.join(phasesDir, targetDir));
1097
+ const summaries = files.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
1098
+ if (summaries.length > 0) {
1099
+ error(`Phase ${targetPhase} has ${summaries.length} executed plan(s). Use --force to remove anyway.`);
1100
+ }
1101
+ }
1102
+
1103
+ if (targetDir) fs.rmSync(path.join(phasesDir, targetDir), { recursive: true, force: true });
1104
+
1105
+ // Renumber subsequent phases on disk
1106
+ let renamedDirs = [], renamedFiles = [];
1107
+ try {
1108
+ const renamed = isDecimal
1109
+ ? renameDecimalPhases(phasesDir, parseInt(normalized.split('.')[0], 10), parseInt(normalized.split('.')[1], 10))
1110
+ : renameIntegerPhases(phasesDir, parseInt(normalized, 10));
1111
+ renamedDirs = renamed.renamedDirs;
1112
+ renamedFiles = renamed.renamedFiles;
1113
+ } catch { /* intentionally empty */ }
1114
+
1115
+ // Update ROADMAP.md
1116
+ updateRoadmapAfterPhaseRemoval(roadmapPath, targetPhase, isDecimal, parseInt(normalized, 10), cwd);
1117
+
1118
+ // Update STATE.md phase count atomically (#P4.4)
1119
+ const statePath = path.join(planningDir(cwd), 'STATE.md');
1120
+ if (fs.existsSync(statePath)) {
1121
+ readModifyWriteStateMd(statePath, (stateContent) => {
1122
+ const totalRaw = stateExtractField(stateContent, 'Total Phases');
1123
+ if (totalRaw) {
1124
+ stateContent = stateReplaceField(stateContent, 'Total Phases', String(parseInt(totalRaw, 10) - 1)) || stateContent;
1125
+ }
1126
+ const ofMatch = stateContent.match(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i);
1127
+ if (ofMatch) {
1128
+ stateContent = stateContent.replace(/(\bof\s+)(\d+)(\s*(?:\(|phases?))/i, `$1${parseInt(ofMatch[2], 10) - 1}$3`);
1129
+ }
1130
+ return stateContent;
1131
+ }, cwd);
1132
+ }
1133
+
1134
+ output({
1135
+ removed: targetPhase,
1136
+ directory_deleted: targetDir,
1137
+ renamed_directories: renamedDirs,
1138
+ renamed_files: renamedFiles,
1139
+ roadmap_updated: true,
1140
+ state_updated: fs.existsSync(statePath),
1141
+ }, raw);
1142
+ }
1143
+
1144
+ function cmdPhaseComplete(cwd, phaseNum, raw) {
1145
+ if (!phaseNum) {
1146
+ error('phase number required for phase complete');
1147
+ }
1148
+
1149
+ const roadmapPath = path.join(planningDir(cwd), 'ROADMAP.md');
1150
+ const statePath = path.join(planningDir(cwd), 'STATE.md');
1151
+ const phasesDir = path.join(planningDir(cwd), 'phases');
1152
+ const normalized = normalizePhaseName(phaseNum);
1153
+ const today = new Date().toISOString().split('T')[0];
1154
+
1155
+ // Verify phase info
1156
+ const phaseInfo = findPhaseInternal(cwd, phaseNum);
1157
+ if (!phaseInfo) {
1158
+ error(`Phase ${phaseNum} not found`);
1159
+ }
1160
+
1161
+ const planCount = phaseInfo.plans.length;
1162
+ const summaryCount = phaseInfo.summaries.length;
1163
+ let requirementsUpdated = false;
1164
+
1165
+ // Check for unresolved verification debt (non-blocking warnings)
1166
+ const warnings = [];
1167
+ try {
1168
+ const phaseFullDir = path.join(cwd, phaseInfo.directory);
1169
+ const phaseFiles = fs.readdirSync(phaseFullDir);
1170
+
1171
+ for (const file of phaseFiles.filter(f => f.includes('-UAT') && f.endsWith('.md'))) {
1172
+ const content = fs.readFileSync(path.join(phaseFullDir, file), 'utf-8');
1173
+ if (/result: pending/.test(content)) warnings.push(`${file}: has pending tests`);
1174
+ if (/result: blocked/.test(content)) warnings.push(`${file}: has blocked tests`);
1175
+ if (/status: partial/.test(content)) warnings.push(`${file}: testing incomplete (partial)`);
1176
+ if (/status: diagnosed/.test(content)) warnings.push(`${file}: has diagnosed gaps`);
1177
+ }
1178
+
1179
+ for (const file of phaseFiles.filter(f => f.includes('-VERIFICATION') && f.endsWith('.md'))) {
1180
+ const content = fs.readFileSync(path.join(phaseFullDir, file), 'utf-8');
1181
+ if (/status: human_needed/.test(content)) warnings.push(`${file}: needs human verification`);
1182
+ if (/status: gaps_found/.test(content)) warnings.push(`${file}: has unresolved gaps`);
1183
+ }
1184
+ } catch {}
1185
+
1186
+ // Update ROADMAP.md and REQUIREMENTS.md atomically under lock
1187
+ if (fs.existsSync(roadmapPath)) {
1188
+ withPlanningLock(cwd, () => {
1189
+ let roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
1190
+
1191
+ // Checkbox: - [ ] Phase N: → - [x] Phase N: (...completed DATE)
1192
+ // #3537: padding-tolerant fragment so the caller-resolved padded id
1193
+ // matches un-padded ROADMAP prose.
1194
+ const phaseEscaped = phaseMarkdownRegexSource(phaseNum);
1195
+ const checkboxPattern = new RegExp(
1196
+ `(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${phaseEscaped}[:\\s][^\\n]*)`,
1197
+ 'i'
1198
+ );
1199
+ roadmapContent = roadmapContent.replace(checkboxPattern, `$1x$2 (completed ${today})`);
1200
+
1201
+ // Progress table: update Status to Complete, add date (handles 4 or 5 column tables)
1202
+ const tableRowPattern = new RegExp(
1203
+ `^(\\|\\s*${phaseEscaped}\\.?\\s[^|]*(?:\\|[^\\n]*))$`,
1204
+ 'im'
1205
+ );
1206
+ roadmapContent = roadmapContent.replace(tableRowPattern, (fullRow) => {
1207
+ const cells = fullRow.split('|').slice(1, -1);
1208
+ if (cells.length === 5) {
1209
+ // 5-col: Phase | Milestone | Plans | Status | Completed
1210
+ cells[2] = ` ${summaryCount}/${planCount} `;
1211
+ cells[3] = ' Complete ';
1212
+ cells[4] = ` ${today} `;
1213
+ } else if (cells.length === 4) {
1214
+ // 4-col: Phase | Plans | Status | Completed
1215
+ cells[1] = ` ${summaryCount}/${planCount} `;
1216
+ cells[2] = ' Complete ';
1217
+ cells[3] = ` ${today} `;
1218
+ }
1219
+ return '|' + cells.join('|') + '|';
1220
+ });
1221
+
1222
+ // Update plan count in phase section.
1223
+ // Use direct .replace() rather than replaceInCurrentMilestone() so this
1224
+ // works when the current milestone section is itself inside a <details>
1225
+ // block (the standard /gsd:new-project layout). replaceInCurrentMilestone
1226
+ // scopes to content after the last </details>, which misses content inside
1227
+ // the current milestone's own <details> wrapper (#2005).
1228
+ // The phase-scoped heading pattern is specific enough to avoid matching
1229
+ // archived phases (which belong to different milestones).
1230
+ const planCountPattern = new RegExp(
1231
+ `(#{2,4}\\s*Phase\\s+${phaseEscaped}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,
1232
+ 'i'
1233
+ );
1234
+ roadmapContent = roadmapContent.replace(
1235
+ planCountPattern,
1236
+ `$1${summaryCount}/${planCount} plans complete`
1237
+ );
1238
+
1239
+ // Mark completed plan checkboxes (safety net for missed per-plan updates)
1240
+ // Handles both plain IDs ("- [ ] 01-01-PLAN.md") and bold-wrapped IDs ("- [ ] **01-01**")
1241
+ for (const summaryFile of phaseInfo.summaries) {
1242
+ const planId = summaryFile.replace('-SUMMARY.md', '').replace('SUMMARY.md', '');
1243
+ if (!planId) continue;
1244
+ const planEscaped = escapeRegex(planId);
1245
+ const planCheckboxPattern = new RegExp(
1246
+ `(-\\s*\\[) (\\]\\s*(?:\\*\\*)?${planEscaped}(?:\\*\\*)?)`,
1247
+ 'i'
1248
+ );
1249
+ roadmapContent = roadmapContent.replace(planCheckboxPattern, '$1x$2');
1250
+ }
1251
+
1252
+ platformWriteSync(roadmapPath, roadmapContent);
1253
+
1254
+ // Update REQUIREMENTS.md traceability for this phase's requirements
1255
+ const reqPath = path.join(planningDir(cwd), 'REQUIREMENTS.md');
1256
+ if (fs.existsSync(reqPath)) {
1257
+ // Extract the current phase section from roadmap (scoped to avoid cross-phase matching).
1258
+ // #3537: padding-tolerant fragment so an un-padded `Phase 2.7:` heading
1259
+ // is found when caller resolved to padded `02.7`.
1260
+ const phaseEsc = phaseMarkdownRegexSource(phaseNum);
1261
+ const currentMilestoneRoadmap = extractCurrentMilestone(roadmapContent, cwd);
1262
+ const phaseSectionMatch = currentMilestoneRoadmap.match(
1263
+ new RegExp(`(#{2,4}\\s*Phase\\s+${phaseEsc}[:\\s][\\s\\S]*?)(?=#{2,4}\\s*Phase\\s+|$)`, 'i')
1264
+ );
1265
+
1266
+ const sectionText = phaseSectionMatch ? phaseSectionMatch[1] : '';
1267
+ // Accept all bold/colon variants (#2769) — the previous pattern only
1268
+ // matched **Requirements:** (colon inside bold) and silently skipped
1269
+ // **Requirements**: (colon outside), preventing the matching REQ-IDs
1270
+ // from being ticked off in REQUIREMENTS.md on phase completion.
1271
+ const reqMatch = sectionText.match(/\*\*Requirements:?\*\*[^\S\n]*:?[^\S\n]*([^\n]+)/i);
1272
+
1273
+ let reqContent = fs.readFileSync(reqPath, 'utf-8');
1274
+
1275
+ if (reqMatch) {
1276
+ const reqIds = reqMatch[1].replace(/[\[\]]/g, '').split(/[,\s]+/).map(r => r.trim()).filter(Boolean);
1277
+
1278
+ for (const reqId of reqIds) {
1279
+ const reqEscaped = escapeRegex(reqId);
1280
+ // Update checkbox: - [ ] **REQ-ID** → - [x] **REQ-ID**
1281
+ reqContent = reqContent.replace(
1282
+ new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${reqEscaped}\\*\\*)`, 'gi'),
1283
+ '$1x$2'
1284
+ );
1285
+ // Update traceability table: | REQ-ID | Phase N | Pending/In Progress | → | REQ-ID | Phase N | Complete |
1286
+ reqContent = reqContent.replace(
1287
+ new RegExp(`(\\|\\s*${reqEscaped}\\s*\\|[^|]+\\|)\\s*(?:Pending|In Progress)\\s*(\\|)`, 'gi'),
1288
+ '$1 Complete $2'
1289
+ );
1290
+ }
1291
+ }
1292
+
1293
+ // Scan body for all **REQ-ID** patterns, warn about any missing from the Traceability table.
1294
+ // Always runs regardless of whether the roadmap has a Requirements: line.
1295
+ const bodyReqIds = [];
1296
+ const bodyReqPattern = /\*\*([A-Z][A-Z0-9]*-\d+)\*\*/g;
1297
+ let bodyMatch;
1298
+ while ((bodyMatch = bodyReqPattern.exec(reqContent)) !== null) {
1299
+ const id = bodyMatch[1];
1300
+ if (!bodyReqIds.includes(id)) bodyReqIds.push(id);
1301
+ }
1302
+
1303
+ // Collect REQ-IDs present in the Traceability section only, to avoid
1304
+ // picking up IDs from other tables in the document.
1305
+ const traceabilityHeadingMatch = reqContent.match(/^#{1,6}\s+Traceability\b/im);
1306
+ const traceabilitySection = traceabilityHeadingMatch
1307
+ ? reqContent.slice(traceabilityHeadingMatch.index)
1308
+ : '';
1309
+ const tableReqIds = new Set();
1310
+ const tableRowPattern = /^\|\s*([A-Z][A-Z0-9]*-\d+)\s*\|/gm;
1311
+ let tableMatch;
1312
+ while ((tableMatch = tableRowPattern.exec(traceabilitySection)) !== null) {
1313
+ tableReqIds.add(tableMatch[1]);
1314
+ }
1315
+
1316
+ const unregistered = bodyReqIds.filter(id => !tableReqIds.has(id));
1317
+ if (unregistered.length > 0) {
1318
+ warnings.push(
1319
+ `REQUIREMENTS.md: ${unregistered.length} REQ-ID(s) found in body but missing from Traceability table: ${unregistered.join(', ')} — add them manually to keep traceability in sync`
1320
+ );
1321
+ }
1322
+
1323
+ platformWriteSync(reqPath, reqContent);
1324
+ requirementsUpdated = true;
1325
+ }
1326
+ });
1327
+ }
1328
+
1329
+ // Find next phase — check both filesystem AND roadmap
1330
+ // Phases may be defined in ROADMAP.md but not yet scaffolded to disk,
1331
+ // so a filesystem-only scan would incorrectly report is_last_phase:true
1332
+ let nextPhaseNum = null;
1333
+ let nextPhaseName = null;
1334
+ let isLastPhase = true;
1335
+
1336
+ try {
1337
+ const isDirInMilestone = getMilestonePhaseFilter(cwd);
1338
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
1339
+ const dirs = entries.filter(e => e.isDirectory()).map(e => e.name)
1340
+ .filter(isDirInMilestone)
1341
+ .sort((a, b) => comparePhaseNum(a, b));
1342
+
1343
+ // Find the next phase directory after current
1344
+ // Skip backlog phases (999.x) — they are parked ideas, not sequential work (#2129)
1345
+ for (const dir of dirs) {
1346
+ const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i);
1347
+ if (dm) {
1348
+ if (/^999(?:\.|$)/.test(dm[1])) continue;
1349
+ if (comparePhaseNum(dm[1], phaseNum) > 0) {
1350
+ nextPhaseNum = dm[1];
1351
+ nextPhaseName = dm[2] || null;
1352
+ isLastPhase = false;
1353
+ break;
1354
+ }
1355
+ }
1356
+ }
1357
+ } catch { /* intentionally empty */ }
1358
+
1359
+ // Fallback: if filesystem found no next phase, check ROADMAP.md
1360
+ // for phases that are defined but not yet planned (no directory on disk)
1361
+ if (isLastPhase && fs.existsSync(roadmapPath)) {
1362
+ try {
1363
+ const roadmapForPhases = extractCurrentMilestone(fs.readFileSync(roadmapPath, 'utf-8'), cwd);
1364
+ const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi;
1365
+ let pm;
1366
+ while ((pm = phasePattern.exec(roadmapForPhases)) !== null) {
1367
+ if (comparePhaseNum(pm[1], phaseNum) > 0) {
1368
+ nextPhaseNum = pm[1];
1369
+ nextPhaseName = pm[2].replace(/\(INSERTED\)/i, '').trim().toLowerCase().replace(/\s+/g, '-');
1370
+ isLastPhase = false;
1371
+ break;
1372
+ }
1373
+ }
1374
+ } catch { /* intentionally empty */ }
1375
+ }
1376
+
1377
+ // Update STATE.md atomically — hold lock across read-modify-write (#P4.4).
1378
+ // Previously read outside the lock; a crash between the ROADMAP update
1379
+ // (locked above) and this write left ROADMAP/STATE inconsistent.
1380
+ if (fs.existsSync(statePath)) {
1381
+ readModifyWriteStateMd(statePath, (stateContent) => {
1382
+ // Update Current Phase — preserve "X of Y (Name)" compound format
1383
+ const phaseValue = nextPhaseNum || phaseNum;
1384
+ const existingPhaseField = stateExtractField(stateContent, 'Current Phase')
1385
+ || stateExtractField(stateContent, 'Phase');
1386
+ let newPhaseValue = String(phaseValue);
1387
+ if (existingPhaseField) {
1388
+ const totalMatch = existingPhaseField.match(/of\s+(\d+)/);
1389
+ const nameMatch = existingPhaseField.match(/\(([^)]+)\)/);
1390
+ if (totalMatch) {
1391
+ const total = totalMatch[1];
1392
+ const nameStr = nextPhaseName ? ` (${nextPhaseName.replace(/-/g, ' ')})` : (nameMatch ? ` (${nameMatch[1]})` : '');
1393
+ newPhaseValue = `${phaseValue} of ${total}${nameStr}`;
1394
+ }
1395
+ }
1396
+ stateContent = stateReplaceFieldWithFallback(stateContent, 'Current Phase', 'Phase', newPhaseValue);
1397
+
1398
+ // Update Current Phase Name
1399
+ if (nextPhaseName) {
1400
+ stateContent = stateReplaceFieldWithFallback(stateContent, 'Current Phase Name', null, nextPhaseName.replace(/-/g, ' '));
1401
+ }
1402
+
1403
+ // Update Status
1404
+ stateContent = stateReplaceFieldWithFallback(stateContent, 'Status', null,
1405
+ isLastPhase ? 'Milestone complete' : 'Ready to plan');
1406
+
1407
+ // Update Current Plan
1408
+ stateContent = stateReplaceFieldWithFallback(stateContent, 'Current Plan', 'Plan', 'Not started');
1409
+
1410
+ // Update Last Activity
1411
+ stateContent = stateReplaceFieldWithFallback(stateContent, 'Last Activity', 'Last activity', today);
1412
+
1413
+ // Update Last Activity Description
1414
+ stateContent = stateReplaceFieldWithFallback(stateContent, 'Last Activity Description', null,
1415
+ `Phase ${phaseNum} complete${nextPhaseNum ? `, transitioned to Phase ${nextPhaseNum}` : ''}`);
1416
+
1417
+ // Increment Completed Phases counter (#956)
1418
+ const completedRaw = stateExtractField(stateContent, 'Completed Phases');
1419
+ if (completedRaw) {
1420
+ const newCompleted = parseInt(completedRaw, 10) + 1;
1421
+ stateContent = stateReplaceField(stateContent, 'Completed Phases', String(newCompleted)) || stateContent;
1422
+
1423
+ // Recalculate percent based on completed / total (#956)
1424
+ const totalRaw = stateExtractField(stateContent, 'Total Phases');
1425
+ if (totalRaw) {
1426
+ const totalPhases = parseInt(totalRaw, 10);
1427
+ if (totalPhases > 0) {
1428
+ const newPercent = Math.round((newCompleted / totalPhases) * 100);
1429
+ stateContent = stateReplaceField(stateContent, 'Progress', `${newPercent}%`) || stateContent;
1430
+ stateContent = stateContent.replace(
1431
+ /(percent:\s*)\d+/,
1432
+ `$1${newPercent}`
1433
+ );
1434
+ }
1435
+ }
1436
+ }
1437
+
1438
+ // Gate 4: Update Performance Metrics section (#1627)
1439
+ stateContent = updatePerformanceMetricsSection(stateContent, cwd, phaseNum, planCount, summaryCount);
1440
+
1441
+ return stateContent;
1442
+ }, cwd);
1443
+ }
1444
+
1445
+ // Auto-prune STATE.md on phase boundary when configured (#2087)
1446
+ let autoPruned = false;
1447
+ try {
1448
+ const configPath = path.join(planningDir(cwd), 'config.json');
1449
+ if (fs.existsSync(configPath)) {
1450
+ const rawConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
1451
+ const autoPruneEnabled = rawConfig.workflow && rawConfig.workflow.auto_prune_state === true;
1452
+ if (autoPruneEnabled && fs.existsSync(statePath)) {
1453
+ const { cmdStatePrune } = require('./state.cjs');
1454
+ cmdStatePrune(cwd, { keepRecent: '3', dryRun: false, silent: true }, true);
1455
+ autoPruned = true;
1456
+ }
1457
+ }
1458
+ } catch { /* intentionally empty — auto-prune is best-effort */ }
1459
+
1460
+ const result = {
1461
+ completed_phase: phaseNum,
1462
+ phase_name: phaseInfo.phase_name,
1463
+ plans_executed: `${summaryCount}/${planCount}`,
1464
+ next_phase: nextPhaseNum,
1465
+ next_phase_name: nextPhaseName,
1466
+ is_last_phase: isLastPhase,
1467
+ date: today,
1468
+ roadmap_updated: fs.existsSync(roadmapPath),
1469
+ state_updated: fs.existsSync(statePath),
1470
+ requirements_updated: requirementsUpdated,
1471
+ auto_pruned: autoPruned,
1472
+ warnings,
1473
+ has_warnings: warnings.length > 0,
1474
+ };
1475
+
1476
+ output(result, raw);
1477
+ }
1478
+
1479
+ module.exports = {
1480
+ cmdPhasesList,
1481
+ cmdPhaseNextDecimal,
1482
+ cmdFindPhase,
1483
+ cmdPhasePlanIndex,
1484
+ cmdPhaseAdd,
1485
+ cmdPhaseAddBatch,
1486
+ cmdPhaseMvpMode,
1487
+ cmdPhaseInsert,
1488
+ cmdPhaseRemove,
1489
+ cmdPhaseComplete,
1490
+ };