gsd-remix 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 (554) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +939 -0
  3. package/README.zh-CN.md +876 -0
  4. package/agents/gsd-advisor-researcher.md +127 -0
  5. package/agents/gsd-ai-researcher.md +133 -0
  6. package/agents/gsd-assumptions-analyzer.md +105 -0
  7. package/agents/gsd-code-fixer.md +517 -0
  8. package/agents/gsd-code-reviewer.md +371 -0
  9. package/agents/gsd-codebase-mapper.md +781 -0
  10. package/agents/gsd-debug-session-manager.md +314 -0
  11. package/agents/gsd-debugger.md +1452 -0
  12. package/agents/gsd-doc-classifier.md +168 -0
  13. package/agents/gsd-doc-synthesizer.md +204 -0
  14. package/agents/gsd-doc-verifier.md +217 -0
  15. package/agents/gsd-doc-writer.md +615 -0
  16. package/agents/gsd-domain-researcher.md +153 -0
  17. package/agents/gsd-eval-auditor.md +191 -0
  18. package/agents/gsd-eval-planner.md +154 -0
  19. package/agents/gsd-executor.md +603 -0
  20. package/agents/gsd-framework-selector.md +160 -0
  21. package/agents/gsd-integration-checker.md +470 -0
  22. package/agents/gsd-intel-updater.md +334 -0
  23. package/agents/gsd-nyquist-auditor.md +203 -0
  24. package/agents/gsd-pattern-mapper.md +335 -0
  25. package/agents/gsd-phase-researcher.md +841 -0
  26. package/agents/gsd-plan-checker.md +978 -0
  27. package/agents/gsd-planner.md +1251 -0
  28. package/agents/gsd-project-researcher.md +677 -0
  29. package/agents/gsd-research-synthesizer.md +247 -0
  30. package/agents/gsd-roadmapper.md +688 -0
  31. package/agents/gsd-security-auditor.md +155 -0
  32. package/agents/gsd-ui-auditor.md +495 -0
  33. package/agents/gsd-ui-checker.md +309 -0
  34. package/agents/gsd-ui-researcher.md +380 -0
  35. package/agents/gsd-user-profiler.md +171 -0
  36. package/agents/gsd-verifier.md +830 -0
  37. package/bin/install.js +7062 -0
  38. package/commands/gsd/add-backlog.md +79 -0
  39. package/commands/gsd/add-phase.md +43 -0
  40. package/commands/gsd/add-tests.md +41 -0
  41. package/commands/gsd/add-todo.md +47 -0
  42. package/commands/gsd/ai-integration-phase.md +36 -0
  43. package/commands/gsd/analyze-dependencies.md +34 -0
  44. package/commands/gsd/audit-fix.md +33 -0
  45. package/commands/gsd/audit-milestone.md +36 -0
  46. package/commands/gsd/audit-uat.md +24 -0
  47. package/commands/gsd/autonomous.md +46 -0
  48. package/commands/gsd/check-todos.md +45 -0
  49. package/commands/gsd/cleanup.md +23 -0
  50. package/commands/gsd/code-review-fix.md +52 -0
  51. package/commands/gsd/code-review.md +55 -0
  52. package/commands/gsd/complete-milestone.md +136 -0
  53. package/commands/gsd/debug.md +263 -0
  54. package/commands/gsd/discuss-phase.md +69 -0
  55. package/commands/gsd/do.md +30 -0
  56. package/commands/gsd/docs-update.md +48 -0
  57. package/commands/gsd/eval-review.md +32 -0
  58. package/commands/gsd/execute-phase.md +63 -0
  59. package/commands/gsd/explore.md +27 -0
  60. package/commands/gsd/extract_learnings.md +22 -0
  61. package/commands/gsd/fast.md +30 -0
  62. package/commands/gsd/forensics.md +56 -0
  63. package/commands/gsd/from-gsd2.md +47 -0
  64. package/commands/gsd/graphify.md +201 -0
  65. package/commands/gsd/health.md +22 -0
  66. package/commands/gsd/help.md +24 -0
  67. package/commands/gsd/import.md +37 -0
  68. package/commands/gsd/inbox.md +38 -0
  69. package/commands/gsd/ingest-docs.md +42 -0
  70. package/commands/gsd/insert-phase.md +32 -0
  71. package/commands/gsd/intel.md +179 -0
  72. package/commands/gsd/join-discord.md +19 -0
  73. package/commands/gsd/list-phase-assumptions.md +46 -0
  74. package/commands/gsd/list-workspaces.md +19 -0
  75. package/commands/gsd/manager.md +40 -0
  76. package/commands/gsd/map-codebase.md +71 -0
  77. package/commands/gsd/milestone-summary.md +51 -0
  78. package/commands/gsd/new-milestone.md +44 -0
  79. package/commands/gsd/new-project.md +46 -0
  80. package/commands/gsd/new-workspace.md +44 -0
  81. package/commands/gsd/next.md +28 -0
  82. package/commands/gsd/note.md +34 -0
  83. package/commands/gsd/pause-work.md +38 -0
  84. package/commands/gsd/plan-milestone-gaps.md +34 -0
  85. package/commands/gsd/plan-phase.md +52 -0
  86. package/commands/gsd/plan-review-convergence.md +52 -0
  87. package/commands/gsd/plant-seed.md +28 -0
  88. package/commands/gsd/pr-branch.md +25 -0
  89. package/commands/gsd/profile-user.md +46 -0
  90. package/commands/gsd/progress.md +25 -0
  91. package/commands/gsd/quick.md +173 -0
  92. package/commands/gsd/reapply-patches.md +331 -0
  93. package/commands/gsd/remove-phase.md +31 -0
  94. package/commands/gsd/remove-workspace.md +26 -0
  95. package/commands/gsd/research-phase.md +195 -0
  96. package/commands/gsd/resume-work.md +40 -0
  97. package/commands/gsd/review-backlog.md +62 -0
  98. package/commands/gsd/review.md +40 -0
  99. package/commands/gsd/scan.md +26 -0
  100. package/commands/gsd/secure-phase.md +35 -0
  101. package/commands/gsd/session-report.md +19 -0
  102. package/commands/gsd/set-profile.md +12 -0
  103. package/commands/gsd/settings.md +36 -0
  104. package/commands/gsd/ship.md +23 -0
  105. package/commands/gsd/sketch-wrap-up.md +31 -0
  106. package/commands/gsd/sketch.md +49 -0
  107. package/commands/gsd/spec-phase.md +62 -0
  108. package/commands/gsd/spike-wrap-up.md +31 -0
  109. package/commands/gsd/spike.md +46 -0
  110. package/commands/gsd/stats.md +18 -0
  111. package/commands/gsd/sync-skills.md +19 -0
  112. package/commands/gsd/thread.md +227 -0
  113. package/commands/gsd/ui-phase.md +34 -0
  114. package/commands/gsd/ui-review.md +32 -0
  115. package/commands/gsd/ultraplan-phase.md +33 -0
  116. package/commands/gsd/undo.md +34 -0
  117. package/commands/gsd/update.md +37 -0
  118. package/commands/gsd/validate-phase.md +35 -0
  119. package/commands/gsd/verify-work.md +38 -0
  120. package/commands/gsd/workstreams.md +69 -0
  121. package/get-shit-done/bin/gsd-tools.cjs +1263 -0
  122. package/get-shit-done/bin/lib/artifacts.cjs +52 -0
  123. package/get-shit-done/bin/lib/audit.cjs +757 -0
  124. package/get-shit-done/bin/lib/commands.cjs +1023 -0
  125. package/get-shit-done/bin/lib/config-schema.cjs +79 -0
  126. package/get-shit-done/bin/lib/config.cjs +463 -0
  127. package/get-shit-done/bin/lib/core.cjs +1794 -0
  128. package/get-shit-done/bin/lib/docs.cjs +267 -0
  129. package/get-shit-done/bin/lib/frontmatter.cjs +379 -0
  130. package/get-shit-done/bin/lib/graphify.cjs +494 -0
  131. package/get-shit-done/bin/lib/gsd2-import.cjs +511 -0
  132. package/get-shit-done/bin/lib/init.cjs +1878 -0
  133. package/get-shit-done/bin/lib/intel.cjs +639 -0
  134. package/get-shit-done/bin/lib/learnings.cjs +378 -0
  135. package/get-shit-done/bin/lib/milestone.cjs +283 -0
  136. package/get-shit-done/bin/lib/model-profiles.cjs +71 -0
  137. package/get-shit-done/bin/lib/phase.cjs +1058 -0
  138. package/get-shit-done/bin/lib/profile-output.cjs +1080 -0
  139. package/get-shit-done/bin/lib/profile-pipeline.cjs +539 -0
  140. package/get-shit-done/bin/lib/roadmap.cjs +523 -0
  141. package/get-shit-done/bin/lib/schema-detect.cjs +238 -0
  142. package/get-shit-done/bin/lib/security.cjs +504 -0
  143. package/get-shit-done/bin/lib/state.cjs +1649 -0
  144. package/get-shit-done/bin/lib/template.cjs +226 -0
  145. package/get-shit-done/bin/lib/uat.cjs +288 -0
  146. package/get-shit-done/bin/lib/verify.cjs +1184 -0
  147. package/get-shit-done/bin/lib/workstream.cjs +495 -0
  148. package/get-shit-done/bin/repair-sdk.cjs +177 -0
  149. package/get-shit-done/contexts/dev.md +21 -0
  150. package/get-shit-done/contexts/research.md +22 -0
  151. package/get-shit-done/contexts/review.md +22 -0
  152. package/get-shit-done/references/agent-contracts.md +79 -0
  153. package/get-shit-done/references/ai-evals.md +156 -0
  154. package/get-shit-done/references/ai-frameworks.md +186 -0
  155. package/get-shit-done/references/artifact-types.md +131 -0
  156. package/get-shit-done/references/autonomous-smart-discuss.md +277 -0
  157. package/get-shit-done/references/checkpoints.md +808 -0
  158. package/get-shit-done/references/common-bug-patterns.md +114 -0
  159. package/get-shit-done/references/context-budget.md +49 -0
  160. package/get-shit-done/references/continuation-format.md +253 -0
  161. package/get-shit-done/references/debugger-philosophy.md +76 -0
  162. package/get-shit-done/references/decimal-phase-calculation.md +64 -0
  163. package/get-shit-done/references/doc-conflict-engine.md +91 -0
  164. package/get-shit-done/references/domain-probes.md +125 -0
  165. package/get-shit-done/references/executor-examples.md +110 -0
  166. package/get-shit-done/references/few-shot-examples/plan-checker.md +73 -0
  167. package/get-shit-done/references/few-shot-examples/verifier.md +109 -0
  168. package/get-shit-done/references/gate-prompts.md +100 -0
  169. package/get-shit-done/references/gates.md +70 -0
  170. package/get-shit-done/references/git-integration.md +295 -0
  171. package/get-shit-done/references/git-planning-commit.md +40 -0
  172. package/get-shit-done/references/ios-scaffold.md +123 -0
  173. package/get-shit-done/references/mandatory-initial-read.md +2 -0
  174. package/get-shit-done/references/model-profile-resolution.md +38 -0
  175. package/get-shit-done/references/model-profiles.md +145 -0
  176. package/get-shit-done/references/phase-argument-parsing.md +61 -0
  177. package/get-shit-done/references/planner-antipatterns.md +89 -0
  178. package/get-shit-done/references/planner-gap-closure.md +62 -0
  179. package/get-shit-done/references/planner-reviews.md +39 -0
  180. package/get-shit-done/references/planner-revision.md +87 -0
  181. package/get-shit-done/references/planner-source-audit.md +73 -0
  182. package/get-shit-done/references/planning-config.md +460 -0
  183. package/get-shit-done/references/project-skills-discovery.md +19 -0
  184. package/get-shit-done/references/questioning.md +162 -0
  185. package/get-shit-done/references/revision-loop.md +97 -0
  186. package/get-shit-done/references/sketch-interactivity.md +41 -0
  187. package/get-shit-done/references/sketch-theme-system.md +94 -0
  188. package/get-shit-done/references/sketch-tooling.md +45 -0
  189. package/get-shit-done/references/sketch-variant-patterns.md +81 -0
  190. package/get-shit-done/references/tdd.md +330 -0
  191. package/get-shit-done/references/thinking-models-debug.md +44 -0
  192. package/get-shit-done/references/thinking-models-execution.md +50 -0
  193. package/get-shit-done/references/thinking-models-planning.md +62 -0
  194. package/get-shit-done/references/thinking-models-research.md +50 -0
  195. package/get-shit-done/references/thinking-models-verification.md +55 -0
  196. package/get-shit-done/references/thinking-partner.md +96 -0
  197. package/get-shit-done/references/ui-brand.md +160 -0
  198. package/get-shit-done/references/universal-anti-patterns.md +63 -0
  199. package/get-shit-done/references/user-profiling.md +681 -0
  200. package/get-shit-done/references/verification-overrides.md +227 -0
  201. package/get-shit-done/references/verification-patterns.md +612 -0
  202. package/get-shit-done/references/workstream-flag.md +111 -0
  203. package/get-shit-done/templates/AI-SPEC.md +246 -0
  204. package/get-shit-done/templates/DEBUG.md +169 -0
  205. package/get-shit-done/templates/README.md +76 -0
  206. package/get-shit-done/templates/SECURITY.md +61 -0
  207. package/get-shit-done/templates/UAT.md +265 -0
  208. package/get-shit-done/templates/UI-SPEC.md +100 -0
  209. package/get-shit-done/templates/VALIDATION.md +76 -0
  210. package/get-shit-done/templates/claude-md.md +145 -0
  211. package/get-shit-done/templates/codebase/architecture.md +255 -0
  212. package/get-shit-done/templates/codebase/concerns.md +310 -0
  213. package/get-shit-done/templates/codebase/conventions.md +307 -0
  214. package/get-shit-done/templates/codebase/integrations.md +280 -0
  215. package/get-shit-done/templates/codebase/stack.md +186 -0
  216. package/get-shit-done/templates/codebase/structure.md +285 -0
  217. package/get-shit-done/templates/codebase/testing.md +480 -0
  218. package/get-shit-done/templates/config.json +56 -0
  219. package/get-shit-done/templates/context.md +352 -0
  220. package/get-shit-done/templates/continue-here.md +78 -0
  221. package/get-shit-done/templates/copilot-instructions.md +7 -0
  222. package/get-shit-done/templates/debug-subagent-prompt.md +91 -0
  223. package/get-shit-done/templates/dev-preferences.md +21 -0
  224. package/get-shit-done/templates/discovery.md +146 -0
  225. package/get-shit-done/templates/discussion-log.md +63 -0
  226. package/get-shit-done/templates/milestone-archive.md +123 -0
  227. package/get-shit-done/templates/milestone.md +115 -0
  228. package/get-shit-done/templates/phase-prompt.md +610 -0
  229. package/get-shit-done/templates/planner-subagent-prompt.md +117 -0
  230. package/get-shit-done/templates/project.md +186 -0
  231. package/get-shit-done/templates/requirements.md +231 -0
  232. package/get-shit-done/templates/research-project/ARCHITECTURE.md +204 -0
  233. package/get-shit-done/templates/research-project/FEATURES.md +147 -0
  234. package/get-shit-done/templates/research-project/PITFALLS.md +200 -0
  235. package/get-shit-done/templates/research-project/STACK.md +120 -0
  236. package/get-shit-done/templates/research-project/SUMMARY.md +170 -0
  237. package/get-shit-done/templates/research.md +592 -0
  238. package/get-shit-done/templates/retrospective.md +54 -0
  239. package/get-shit-done/templates/roadmap.md +202 -0
  240. package/get-shit-done/templates/spec.md +307 -0
  241. package/get-shit-done/templates/state.md +184 -0
  242. package/get-shit-done/templates/summary-complex.md +59 -0
  243. package/get-shit-done/templates/summary-minimal.md +41 -0
  244. package/get-shit-done/templates/summary-standard.md +48 -0
  245. package/get-shit-done/templates/summary.md +248 -0
  246. package/get-shit-done/templates/user-profile.md +146 -0
  247. package/get-shit-done/templates/user-setup.md +311 -0
  248. package/get-shit-done/templates/verification-report.md +322 -0
  249. package/get-shit-done/workflows/add-phase.md +112 -0
  250. package/get-shit-done/workflows/add-tests.md +354 -0
  251. package/get-shit-done/workflows/add-todo.md +160 -0
  252. package/get-shit-done/workflows/ai-integration-phase.md +284 -0
  253. package/get-shit-done/workflows/analyze-dependencies.md +96 -0
  254. package/get-shit-done/workflows/audit-fix.md +175 -0
  255. package/get-shit-done/workflows/audit-milestone.md +340 -0
  256. package/get-shit-done/workflows/audit-uat.md +109 -0
  257. package/get-shit-done/workflows/autonomous.md +789 -0
  258. package/get-shit-done/workflows/check-todos.md +179 -0
  259. package/get-shit-done/workflows/cleanup.md +154 -0
  260. package/get-shit-done/workflows/code-review-fix.md +497 -0
  261. package/get-shit-done/workflows/code-review.md +515 -0
  262. package/get-shit-done/workflows/complete-milestone.md +847 -0
  263. package/get-shit-done/workflows/diagnose-issues.md +238 -0
  264. package/get-shit-done/workflows/discovery-phase.md +291 -0
  265. package/get-shit-done/workflows/discuss-phase-assumptions.md +670 -0
  266. package/get-shit-done/workflows/discuss-phase-power.md +308 -0
  267. package/get-shit-done/workflows/discuss-phase.md +1378 -0
  268. package/get-shit-done/workflows/do.md +110 -0
  269. package/get-shit-done/workflows/docs-update.md +1155 -0
  270. package/get-shit-done/workflows/eval-review.md +155 -0
  271. package/get-shit-done/workflows/execute-phase.md +1677 -0
  272. package/get-shit-done/workflows/execute-plan.md +533 -0
  273. package/get-shit-done/workflows/explore.md +141 -0
  274. package/get-shit-done/workflows/extract_learnings.md +242 -0
  275. package/get-shit-done/workflows/fast.md +105 -0
  276. package/get-shit-done/workflows/forensics.md +265 -0
  277. package/get-shit-done/workflows/graduation.md +195 -0
  278. package/get-shit-done/workflows/health.md +314 -0
  279. package/get-shit-done/workflows/help.md +667 -0
  280. package/get-shit-done/workflows/import.md +246 -0
  281. package/get-shit-done/workflows/inbox.md +387 -0
  282. package/get-shit-done/workflows/ingest-docs.md +328 -0
  283. package/get-shit-done/workflows/insert-phase.md +130 -0
  284. package/get-shit-done/workflows/list-phase-assumptions.md +178 -0
  285. package/get-shit-done/workflows/list-workspaces.md +56 -0
  286. package/get-shit-done/workflows/manager.md +365 -0
  287. package/get-shit-done/workflows/map-codebase.md +393 -0
  288. package/get-shit-done/workflows/milestone-summary.md +223 -0
  289. package/get-shit-done/workflows/new-milestone.md +611 -0
  290. package/get-shit-done/workflows/new-project.md +1391 -0
  291. package/get-shit-done/workflows/new-workspace.md +239 -0
  292. package/get-shit-done/workflows/next.md +220 -0
  293. package/get-shit-done/workflows/node-repair.md +92 -0
  294. package/get-shit-done/workflows/note.md +158 -0
  295. package/get-shit-done/workflows/pause-work.md +243 -0
  296. package/get-shit-done/workflows/plan-milestone-gaps.md +273 -0
  297. package/get-shit-done/workflows/plan-phase.md +1349 -0
  298. package/get-shit-done/workflows/plan-review-convergence.md +254 -0
  299. package/get-shit-done/workflows/plant-seed.md +172 -0
  300. package/get-shit-done/workflows/pr-branch.md +157 -0
  301. package/get-shit-done/workflows/profile-user.md +452 -0
  302. package/get-shit-done/workflows/progress.md +619 -0
  303. package/get-shit-done/workflows/quick.md +970 -0
  304. package/get-shit-done/workflows/remove-phase.md +155 -0
  305. package/get-shit-done/workflows/remove-workspace.md +92 -0
  306. package/get-shit-done/workflows/research-phase.md +89 -0
  307. package/get-shit-done/workflows/resume-project.md +326 -0
  308. package/get-shit-done/workflows/review.md +344 -0
  309. package/get-shit-done/workflows/scan.md +102 -0
  310. package/get-shit-done/workflows/secure-phase.md +166 -0
  311. package/get-shit-done/workflows/session-report.md +146 -0
  312. package/get-shit-done/workflows/settings.md +319 -0
  313. package/get-shit-done/workflows/ship.md +302 -0
  314. package/get-shit-done/workflows/sketch-wrap-up.md +283 -0
  315. package/get-shit-done/workflows/sketch.md +286 -0
  316. package/get-shit-done/workflows/spec-phase.md +262 -0
  317. package/get-shit-done/workflows/spike-wrap-up.md +281 -0
  318. package/get-shit-done/workflows/spike.md +362 -0
  319. package/get-shit-done/workflows/stats.md +60 -0
  320. package/get-shit-done/workflows/sync-skills.md +182 -0
  321. package/get-shit-done/workflows/transition.md +693 -0
  322. package/get-shit-done/workflows/ui-phase.md +323 -0
  323. package/get-shit-done/workflows/ui-review.md +190 -0
  324. package/get-shit-done/workflows/ultraplan-phase.md +189 -0
  325. package/get-shit-done/workflows/undo.md +314 -0
  326. package/get-shit-done/workflows/update.md +587 -0
  327. package/get-shit-done/workflows/validate-phase.md +176 -0
  328. package/get-shit-done/workflows/verify-phase.md +465 -0
  329. package/get-shit-done/workflows/verify-work.md +740 -0
  330. package/hooks/dist/gsd-check-update-worker.js +108 -0
  331. package/hooks/dist/gsd-check-update.js +64 -0
  332. package/hooks/dist/gsd-context-monitor.js +192 -0
  333. package/hooks/dist/gsd-phase-boundary.sh +28 -0
  334. package/hooks/dist/gsd-prompt-guard.js +97 -0
  335. package/hooks/dist/gsd-read-guard.js +82 -0
  336. package/hooks/dist/gsd-read-injection-scanner.js +152 -0
  337. package/hooks/dist/gsd-session-state.sh +34 -0
  338. package/hooks/dist/gsd-statusline.js +293 -0
  339. package/hooks/dist/gsd-validate-commit.sh +48 -0
  340. package/hooks/dist/gsd-workflow-guard.js +94 -0
  341. package/hooks/gsd-check-update-worker.js +108 -0
  342. package/hooks/gsd-check-update.js +64 -0
  343. package/hooks/gsd-context-monitor.js +192 -0
  344. package/hooks/gsd-phase-boundary.sh +28 -0
  345. package/hooks/gsd-prompt-guard.js +97 -0
  346. package/hooks/gsd-read-guard.js +82 -0
  347. package/hooks/gsd-read-injection-scanner.js +152 -0
  348. package/hooks/gsd-session-state.sh +34 -0
  349. package/hooks/gsd-statusline.js +293 -0
  350. package/hooks/gsd-validate-commit.sh +48 -0
  351. package/hooks/gsd-workflow-guard.js +94 -0
  352. package/package.json +59 -0
  353. package/scripts/base64-scan.sh +262 -0
  354. package/scripts/build-hooks.js +95 -0
  355. package/scripts/gen-inventory-manifest.cjs +109 -0
  356. package/scripts/prompt-injection-scan.sh +201 -0
  357. package/scripts/run-tests.cjs +33 -0
  358. package/scripts/secret-scan.sh +227 -0
  359. package/sdk/package-lock.json +1998 -0
  360. package/sdk/package.json +52 -0
  361. package/sdk/prompts/agents/gsd-executor.md +110 -0
  362. package/sdk/prompts/agents/gsd-phase-researcher.md +158 -0
  363. package/sdk/prompts/agents/gsd-plan-checker.md +160 -0
  364. package/sdk/prompts/agents/gsd-planner.md +214 -0
  365. package/sdk/prompts/agents/gsd-project-researcher.md +323 -0
  366. package/sdk/prompts/agents/gsd-research-synthesizer.md +237 -0
  367. package/sdk/prompts/agents/gsd-roadmapper.md +670 -0
  368. package/sdk/prompts/agents/gsd-verifier.md +159 -0
  369. package/sdk/prompts/templates/project.md +186 -0
  370. package/sdk/prompts/templates/requirements.md +231 -0
  371. package/sdk/prompts/templates/research-project/ARCHITECTURE.md +204 -0
  372. package/sdk/prompts/templates/research-project/FEATURES.md +147 -0
  373. package/sdk/prompts/templates/research-project/PITFALLS.md +200 -0
  374. package/sdk/prompts/templates/research-project/STACK.md +120 -0
  375. package/sdk/prompts/templates/research-project/SUMMARY.md +170 -0
  376. package/sdk/prompts/templates/roadmap.md +202 -0
  377. package/sdk/prompts/templates/state.md +175 -0
  378. package/sdk/prompts/workflows/discuss-phase.md +126 -0
  379. package/sdk/prompts/workflows/execute-plan.md +106 -0
  380. package/sdk/prompts/workflows/plan-phase.md +84 -0
  381. package/sdk/prompts/workflows/research-phase.md +45 -0
  382. package/sdk/prompts/workflows/verify-phase.md +142 -0
  383. package/sdk/src/assembled-prompts.test.ts +349 -0
  384. package/sdk/src/cli-transport.test.ts +388 -0
  385. package/sdk/src/cli-transport.ts +130 -0
  386. package/sdk/src/cli.test.ts +383 -0
  387. package/sdk/src/cli.ts +670 -0
  388. package/sdk/src/config.test.ts +168 -0
  389. package/sdk/src/config.ts +177 -0
  390. package/sdk/src/context-engine.test.ts +295 -0
  391. package/sdk/src/context-engine.ts +170 -0
  392. package/sdk/src/context-truncation.test.ts +163 -0
  393. package/sdk/src/context-truncation.ts +233 -0
  394. package/sdk/src/e2e.integration.test.ts +178 -0
  395. package/sdk/src/errors.ts +72 -0
  396. package/sdk/src/event-stream.test.ts +661 -0
  397. package/sdk/src/event-stream.ts +441 -0
  398. package/sdk/src/failure-memory.test.ts +457 -0
  399. package/sdk/src/failure-memory.ts +1324 -0
  400. package/sdk/src/golden/capture.ts +95 -0
  401. package/sdk/src/golden/fixtures/generate-slug.golden.json +1 -0
  402. package/sdk/src/golden/fixtures/profile-sample-sessions/demo-project/sample.jsonl +3 -0
  403. package/sdk/src/golden/fixtures/summary-extract-sample.md +26 -0
  404. package/sdk/src/golden/fixtures/uat-render-checkpoint-sample.md +15 -0
  405. package/sdk/src/golden/golden-integration-covered.ts +30 -0
  406. package/sdk/src/golden/golden-mutation-covered.ts +7 -0
  407. package/sdk/src/golden/golden-policy.test.ts +8 -0
  408. package/sdk/src/golden/golden-policy.ts +112 -0
  409. package/sdk/src/golden/golden.integration.test.ts +373 -0
  410. package/sdk/src/golden/init-golden-normalize.ts +15 -0
  411. package/sdk/src/golden/read-only-golden-rows.ts +77 -0
  412. package/sdk/src/golden/read-only-parity.integration.test.ts +125 -0
  413. package/sdk/src/golden/registry-canonical-commands.ts +31 -0
  414. package/sdk/src/gsd-tools.test.ts +409 -0
  415. package/sdk/src/gsd-tools.ts +595 -0
  416. package/sdk/src/headless-prompts.test.ts +159 -0
  417. package/sdk/src/index.ts +333 -0
  418. package/sdk/src/init-e2e.integration.test.ts +136 -0
  419. package/sdk/src/init-runner.test.ts +783 -0
  420. package/sdk/src/init-runner.ts +735 -0
  421. package/sdk/src/lifecycle-e2e.integration.test.ts +258 -0
  422. package/sdk/src/logger.test.ts +149 -0
  423. package/sdk/src/logger.ts +113 -0
  424. package/sdk/src/milestone-runner.test.ts +421 -0
  425. package/sdk/src/phase-prompt.test.ts +538 -0
  426. package/sdk/src/phase-prompt.ts +264 -0
  427. package/sdk/src/phase-runner-types.test.ts +421 -0
  428. package/sdk/src/phase-runner.integration.test.ts +377 -0
  429. package/sdk/src/phase-runner.test.ts +2333 -0
  430. package/sdk/src/phase-runner.ts +1203 -0
  431. package/sdk/src/plan-parser.test.ts +528 -0
  432. package/sdk/src/plan-parser.ts +427 -0
  433. package/sdk/src/prompt-builder.test.ts +306 -0
  434. package/sdk/src/prompt-builder.ts +193 -0
  435. package/sdk/src/prompt-sanitizer.test.ts +260 -0
  436. package/sdk/src/prompt-sanitizer.ts +71 -0
  437. package/sdk/src/query/QUERY-HANDLERS.md +317 -0
  438. package/sdk/src/query/audit-open.ts +722 -0
  439. package/sdk/src/query/check-auto-mode.test.ts +77 -0
  440. package/sdk/src/query/check-auto-mode.ts +50 -0
  441. package/sdk/src/query/check-completion.test.ts +113 -0
  442. package/sdk/src/query/check-completion.ts +182 -0
  443. package/sdk/src/query/check-gates.test.ts +103 -0
  444. package/sdk/src/query/check-gates.ts +112 -0
  445. package/sdk/src/query/check-ship-ready.test.ts +77 -0
  446. package/sdk/src/query/check-ship-ready.ts +103 -0
  447. package/sdk/src/query/check-verification-status.test.ts +143 -0
  448. package/sdk/src/query/check-verification-status.ts +160 -0
  449. package/sdk/src/query/commit.test.ts +202 -0
  450. package/sdk/src/query/commit.ts +301 -0
  451. package/sdk/src/query/config-gates.test.ts +89 -0
  452. package/sdk/src/query/config-gates.ts +69 -0
  453. package/sdk/src/query/config-mutation.test.ts +365 -0
  454. package/sdk/src/query/config-mutation.ts +497 -0
  455. package/sdk/src/query/config-query.test.ts +161 -0
  456. package/sdk/src/query/config-query.ts +190 -0
  457. package/sdk/src/query/context-history.test.ts +165 -0
  458. package/sdk/src/query/context-history.ts +467 -0
  459. package/sdk/src/query/decomposed-handlers.test.ts +365 -0
  460. package/sdk/src/query/detect-custom-files.ts +97 -0
  461. package/sdk/src/query/detect-phase-type.test.ts +105 -0
  462. package/sdk/src/query/detect-phase-type.ts +141 -0
  463. package/sdk/src/query/docs-init.ts +257 -0
  464. package/sdk/src/query/failure-capture.ts +58 -0
  465. package/sdk/src/query/frontmatter-array.test.ts +14 -0
  466. package/sdk/src/query/frontmatter-mutation.test.ts +259 -0
  467. package/sdk/src/query/frontmatter-mutation.ts +343 -0
  468. package/sdk/src/query/frontmatter.test.ts +281 -0
  469. package/sdk/src/query/frontmatter.ts +397 -0
  470. package/sdk/src/query/helpers.test.ts +426 -0
  471. package/sdk/src/query/helpers.ts +482 -0
  472. package/sdk/src/query/index.ts +586 -0
  473. package/sdk/src/query/init-complex.test.ts +232 -0
  474. package/sdk/src/query/init-complex.ts +578 -0
  475. package/sdk/src/query/init.test.ts +522 -0
  476. package/sdk/src/query/init.ts +1046 -0
  477. package/sdk/src/query/intel.test.ts +90 -0
  478. package/sdk/src/query/intel.ts +404 -0
  479. package/sdk/src/query/normalize-query-command.test.ts +50 -0
  480. package/sdk/src/query/normalize-query-command.ts +56 -0
  481. package/sdk/src/query/phase-lifecycle.test.ts +1126 -0
  482. package/sdk/src/query/phase-lifecycle.ts +1799 -0
  483. package/sdk/src/query/phase-list-queries.test.ts +88 -0
  484. package/sdk/src/query/phase-list-queries.ts +152 -0
  485. package/sdk/src/query/phase-ready.test.ts +65 -0
  486. package/sdk/src/query/phase-ready.ts +158 -0
  487. package/sdk/src/query/phase.test.ts +307 -0
  488. package/sdk/src/query/phase.ts +340 -0
  489. package/sdk/src/query/pipeline.test.ts +169 -0
  490. package/sdk/src/query/pipeline.ts +243 -0
  491. package/sdk/src/query/plan-execution-route.test.ts +166 -0
  492. package/sdk/src/query/plan-execution-route.ts +209 -0
  493. package/sdk/src/query/plan-task-structure.test.ts +65 -0
  494. package/sdk/src/query/plan-task-structure.ts +63 -0
  495. package/sdk/src/query/profile-extract-messages.ts +247 -0
  496. package/sdk/src/query/profile-output.ts +908 -0
  497. package/sdk/src/query/profile-questionnaire-data.ts +181 -0
  498. package/sdk/src/query/profile-sample.ts +184 -0
  499. package/sdk/src/query/profile-scan-sessions.ts +174 -0
  500. package/sdk/src/query/profile.test.ts +74 -0
  501. package/sdk/src/query/profile.ts +337 -0
  502. package/sdk/src/query/progress.test.ts +156 -0
  503. package/sdk/src/query/progress.ts +566 -0
  504. package/sdk/src/query/registry.test.ts +216 -0
  505. package/sdk/src/query/registry.ts +174 -0
  506. package/sdk/src/query/requirements-extract-from-plans.test.ts +58 -0
  507. package/sdk/src/query/requirements-extract-from-plans.ts +86 -0
  508. package/sdk/src/query/roadmap-update-plan-progress.ts +132 -0
  509. package/sdk/src/query/roadmap.test.ts +359 -0
  510. package/sdk/src/query/roadmap.ts +591 -0
  511. package/sdk/src/query/route-next-action.test.ts +61 -0
  512. package/sdk/src/query/route-next-action.ts +345 -0
  513. package/sdk/src/query/runtime-health.ts +7 -0
  514. package/sdk/src/query/schema-detect.ts +189 -0
  515. package/sdk/src/query/skill-manifest.ts +214 -0
  516. package/sdk/src/query/skills.test.ts +80 -0
  517. package/sdk/src/query/skills.ts +62 -0
  518. package/sdk/src/query/state-mutation.test.ts +450 -0
  519. package/sdk/src/query/state-mutation.ts +1444 -0
  520. package/sdk/src/query/state-project-load.ts +109 -0
  521. package/sdk/src/query/state.test.ts +347 -0
  522. package/sdk/src/query/state.ts +397 -0
  523. package/sdk/src/query/summary.test.ts +95 -0
  524. package/sdk/src/query/summary.ts +296 -0
  525. package/sdk/src/query/template.test.ts +180 -0
  526. package/sdk/src/query/template.ts +242 -0
  527. package/sdk/src/query/uat.test.ts +77 -0
  528. package/sdk/src/query/uat.ts +314 -0
  529. package/sdk/src/query/utils.test.ts +82 -0
  530. package/sdk/src/query/utils.ts +92 -0
  531. package/sdk/src/query/validate.test.ts +656 -0
  532. package/sdk/src/query/validate.ts +807 -0
  533. package/sdk/src/query/verify.test.ts +414 -0
  534. package/sdk/src/query/verify.ts +645 -0
  535. package/sdk/src/query/websearch.test.ts +31 -0
  536. package/sdk/src/query/websearch.ts +82 -0
  537. package/sdk/src/query/workspace.test.ts +119 -0
  538. package/sdk/src/query/workspace.ts +131 -0
  539. package/sdk/src/query/workstream.test.ts +51 -0
  540. package/sdk/src/query/workstream.ts +434 -0
  541. package/sdk/src/research-gate.test.ts +190 -0
  542. package/sdk/src/research-gate.ts +94 -0
  543. package/sdk/src/runtime-health.test.ts +176 -0
  544. package/sdk/src/runtime-health.ts +387 -0
  545. package/sdk/src/session-runner.test.ts +98 -0
  546. package/sdk/src/session-runner.ts +299 -0
  547. package/sdk/src/tool-scoping.test.ts +160 -0
  548. package/sdk/src/tool-scoping.ts +61 -0
  549. package/sdk/src/types.ts +917 -0
  550. package/sdk/src/workstream-utils.ts +33 -0
  551. package/sdk/src/ws-flag.test.ts +285 -0
  552. package/sdk/src/ws-transport.test.ts +161 -0
  553. package/sdk/src/ws-transport.ts +93 -0
  554. package/sdk/tsconfig.json +20 -0
@@ -0,0 +1,397 @@
1
+ /**
2
+ * State query handlers — STATE.md loading, field extraction, and snapshots.
3
+ *
4
+ * Ported from get-shit-done/bin/lib/state.cjs and core.cjs.
5
+ * Provides `state json` / `state.json` (rebuilt frontmatter JSON, `stateJson`), `state.get`
6
+ * (field/section extraction), and state-snapshot (structured snapshot).
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { stateJson, stateGet, stateSnapshot } from './state.js';
11
+ *
12
+ * const loaded = await stateJson([], '/project');
13
+ * // { data: { gsd_state_version: '1.0', milestone: 'v3.0', ... } }
14
+ *
15
+ * const field = await stateGet(['Status'], '/project');
16
+ * // { data: { Status: 'executing' } }
17
+ *
18
+ * const snap = await stateSnapshot([], '/project');
19
+ * // { data: { current_phase: '10', status: 'executing', decisions: [...], ... } }
20
+ * ```
21
+ */
22
+
23
+ import { readFile, readdir } from 'node:fs/promises';
24
+ import { join } from 'node:path';
25
+ import { extractFrontmatter, stripFrontmatter } from './frontmatter.js';
26
+ import { stateExtractField, planningPaths, escapeRegex } from './helpers.js';
27
+ import { getMilestoneInfo, extractCurrentMilestone } from './roadmap.js';
28
+ import type { QueryHandler } from './utils.js';
29
+
30
+ // ─── Internal helpers ──────────────────────────────────────────────────────
31
+
32
+ /**
33
+ * Build a filter function that checks if a phase directory belongs to the current milestone.
34
+ *
35
+ * Port of getMilestonePhaseFilter from core.cjs lines 1409-1442.
36
+ */
37
+ export async function getMilestonePhaseFilter(projectDir: string): Promise<((dirName: string) => boolean) & { phaseCount: number }> {
38
+ const milestonePhaseNums = new Set<string>();
39
+ try {
40
+ const roadmapContent = await readFile(planningPaths(projectDir).roadmap, 'utf-8');
41
+ const roadmap = await extractCurrentMilestone(roadmapContent, projectDir);
42
+ const phasePattern = /#{2,4}\s*Phase\s+([\w][\w.-]*)\s*:/gi;
43
+ let m: RegExpExecArray | null;
44
+ while ((m = phasePattern.exec(roadmap)) !== null) {
45
+ milestonePhaseNums.add(m[1]);
46
+ }
47
+ } catch { /* intentionally empty */ }
48
+
49
+ if (milestonePhaseNums.size === 0) {
50
+ const passAllFn = (_dirName: string): boolean => true;
51
+ const passAll = passAllFn as typeof passAllFn & { phaseCount: number };
52
+ passAll.phaseCount = 0;
53
+ return passAll;
54
+ }
55
+
56
+ const normalized = new Set<string>(
57
+ [...milestonePhaseNums].map(n => (n.replace(/^0+/, '') || '0').toLowerCase())
58
+ );
59
+
60
+ const isDirInMilestone = ((dirName: string): boolean => {
61
+ // Try numeric match first
62
+ const m = dirName.match(/^0*(\d+[A-Za-z]?(?:\.\d+)*)/);
63
+ if (m && normalized.has(m[1].toLowerCase())) return true;
64
+ // Try custom ID match
65
+ const customMatch = dirName.match(/^([A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)*)/);
66
+ if (customMatch && normalized.has(customMatch[1].toLowerCase())) return true;
67
+ return false;
68
+ }) as ((dirName: string) => boolean) & { phaseCount: number };
69
+
70
+ isDirInMilestone.phaseCount = milestonePhaseNums.size;
71
+ return isDirInMilestone;
72
+ }
73
+
74
+ /**
75
+ * Build state frontmatter from STATE.md body content and disk scanning.
76
+ *
77
+ * Port of buildStateFrontmatter from state.cjs lines 650-760.
78
+ * HIGH complexity: extracts fields, scans disk, computes progress.
79
+ */
80
+ export async function buildStateFrontmatter(bodyContent: string, projectDir: string): Promise<Record<string, unknown>> {
81
+ const currentPhase = stateExtractField(bodyContent, 'Current Phase');
82
+ const currentPhaseName = stateExtractField(bodyContent, 'Current Phase Name');
83
+ const currentPlan = stateExtractField(bodyContent, 'Current Plan');
84
+ const totalPhasesRaw = stateExtractField(bodyContent, 'Total Phases');
85
+ const totalPlansRaw = stateExtractField(bodyContent, 'Total Plans in Phase');
86
+ const status = stateExtractField(bodyContent, 'Status');
87
+ const progressRaw = stateExtractField(bodyContent, 'Progress');
88
+ const lastActivity = stateExtractField(bodyContent, 'Last Activity');
89
+ const stoppedAt = stateExtractField(bodyContent, 'Stopped At') || stateExtractField(bodyContent, 'Stopped at');
90
+ const pausedAt = stateExtractField(bodyContent, 'Paused At');
91
+
92
+ let milestone: string | null = null;
93
+ let milestoneName: string | null = null;
94
+ try {
95
+ const info = await getMilestoneInfo(projectDir);
96
+ milestone = info.version;
97
+ milestoneName = info.name;
98
+ } catch { /* intentionally empty */ }
99
+
100
+ let totalPhases: number | null = totalPhasesRaw ? parseInt(totalPhasesRaw, 10) : null;
101
+ let completedPhases: number | null = null;
102
+ let totalPlans: number | null = totalPlansRaw ? parseInt(totalPlansRaw, 10) : null;
103
+ let completedPlans: number | null = null;
104
+
105
+ try {
106
+ const phasesDir = planningPaths(projectDir).phases;
107
+ const isDirInMilestone = await getMilestonePhaseFilter(projectDir);
108
+ const entries = await readdir(phasesDir, { withFileTypes: true });
109
+ const phaseDirs = entries
110
+ .filter(e => e.isDirectory())
111
+ .map(e => e.name)
112
+ .filter(isDirInMilestone);
113
+
114
+ let diskTotalPlans = 0;
115
+ let diskTotalSummaries = 0;
116
+ let diskCompletedPhases = 0;
117
+
118
+ for (const dir of phaseDirs) {
119
+ const files = await readdir(join(phasesDir, dir));
120
+ const plans = files.filter(f => /-PLAN\.md$/i.test(f)).length;
121
+ const summaries = files.filter(f => /-SUMMARY\.md$/i.test(f)).length;
122
+ diskTotalPlans += plans;
123
+ diskTotalSummaries += summaries;
124
+ if (plans > 0 && summaries >= plans) diskCompletedPhases++;
125
+ }
126
+
127
+ totalPhases = isDirInMilestone.phaseCount > 0
128
+ ? Math.max(phaseDirs.length, isDirInMilestone.phaseCount)
129
+ : phaseDirs.length;
130
+ completedPhases = diskCompletedPhases;
131
+ totalPlans = diskTotalPlans;
132
+ completedPlans = diskTotalSummaries;
133
+ } catch { /* intentionally empty */ }
134
+
135
+ // Derive percent from disk counts (ground truth)
136
+ let progressPercent: number | null = null;
137
+ if (totalPlans !== null && totalPlans > 0 && completedPlans !== null) {
138
+ progressPercent = Math.min(100, Math.round(completedPlans / totalPlans * 100));
139
+ } else if (progressRaw) {
140
+ const pctMatch = progressRaw.match(/(\d+)%/);
141
+ if (pctMatch) progressPercent = parseInt(pctMatch[1], 10);
142
+ }
143
+
144
+ // Normalize status
145
+ let normalizedStatus = status || 'unknown';
146
+ const statusLower = (status || '').toLowerCase();
147
+ if (statusLower.includes('paused') || statusLower.includes('stopped') || pausedAt) {
148
+ normalizedStatus = 'paused';
149
+ } else if (statusLower.includes('executing') || statusLower.includes('in progress')) {
150
+ normalizedStatus = 'executing';
151
+ } else if (statusLower.includes('planning') || statusLower.includes('ready to plan')) {
152
+ normalizedStatus = 'planning';
153
+ } else if (statusLower.includes('discussing')) {
154
+ normalizedStatus = 'discussing';
155
+ } else if (statusLower.includes('verif')) {
156
+ normalizedStatus = 'verifying';
157
+ } else if (statusLower.includes('complete') || statusLower.includes('done')) {
158
+ normalizedStatus = 'completed';
159
+ } else if (statusLower.includes('ready to execute')) {
160
+ normalizedStatus = 'executing';
161
+ }
162
+
163
+ const fm: Record<string, unknown> = { gsd_state_version: '1.0' };
164
+
165
+ if (milestone) fm.milestone = milestone;
166
+ if (milestoneName) fm.milestone_name = milestoneName;
167
+ if (currentPhase) fm.current_phase = currentPhase;
168
+ if (currentPhaseName) fm.current_phase_name = currentPhaseName;
169
+ if (currentPlan) fm.current_plan = currentPlan;
170
+ fm.status = normalizedStatus;
171
+ if (stoppedAt) fm.stopped_at = stoppedAt;
172
+ if (pausedAt) fm.paused_at = pausedAt;
173
+ fm.last_updated = new Date().toISOString();
174
+ if (lastActivity) fm.last_activity = lastActivity;
175
+
176
+ const progress: Record<string, unknown> = {};
177
+ if (totalPhases !== null) progress.total_phases = totalPhases;
178
+ if (completedPhases !== null) progress.completed_phases = completedPhases;
179
+ if (totalPlans !== null) progress.total_plans = totalPlans;
180
+ if (completedPlans !== null) progress.completed_plans = completedPlans;
181
+ if (progressPercent !== null) progress.percent = progressPercent;
182
+ if (Object.keys(progress).length > 0) fm.progress = progress;
183
+
184
+ return fm;
185
+ }
186
+
187
+ // ─── Exported handlers ─────────────────────────────────────────────────────
188
+
189
+ /**
190
+ * Query handler for `state json` / `state.json` (CJS `cmdStateJson`).
191
+ *
192
+ * Reads STATE.md, rebuilds frontmatter from body + disk scanning.
193
+ * Returns cached frontmatter-only fields (stopped_at, paused_at) when not in body.
194
+ *
195
+ * Port of cmdStateJson from state.cjs lines 872-901.
196
+ *
197
+ * @param args - Unused
198
+ * @param projectDir - Project root directory
199
+ * @returns QueryResult with rebuilt state frontmatter
200
+ */
201
+ export const stateJson: QueryHandler = async (_args, projectDir) => {
202
+ const statePath = planningPaths(projectDir).state;
203
+
204
+ let content: string;
205
+ try {
206
+ content = await readFile(statePath, 'utf-8');
207
+ } catch {
208
+ return { data: { error: 'STATE.md not found' } };
209
+ }
210
+
211
+ const existingFm = extractFrontmatter(content);
212
+ const body = stripFrontmatter(content);
213
+
214
+ // Always rebuild from body + disk so progress reflects current state
215
+ const built = await buildStateFrontmatter(body, projectDir);
216
+
217
+ // Preserve frontmatter-only fields that cannot be recovered from body
218
+ if (existingFm && existingFm.stopped_at && !built.stopped_at) {
219
+ built.stopped_at = existingFm.stopped_at;
220
+ }
221
+ if (existingFm && existingFm.paused_at && !built.paused_at) {
222
+ built.paused_at = existingFm.paused_at;
223
+ }
224
+
225
+ // Preserve existing non-unknown status when body-derived is 'unknown'
226
+ if (built.status === 'unknown' && existingFm && existingFm.status && existingFm.status !== 'unknown') {
227
+ built.status = existingFm.status;
228
+ }
229
+
230
+ return { data: built };
231
+ };
232
+
233
+ /**
234
+ * Query handler for state.get.
235
+ *
236
+ * Reads STATE.md and extracts a specific field or section.
237
+ * Returns full content when no field specified.
238
+ *
239
+ * Port of cmdStateGet from state.cjs lines 72-113.
240
+ *
241
+ * @param args - args[0] is optional field/section name
242
+ * @param projectDir - Project root directory
243
+ * @returns QueryResult with field value or full content
244
+ */
245
+ export const stateGet: QueryHandler = async (args, projectDir) => {
246
+ const statePath = planningPaths(projectDir).state;
247
+
248
+ let content: string;
249
+ try {
250
+ content = await readFile(statePath, 'utf-8');
251
+ } catch {
252
+ return { data: { error: 'STATE.md not found' } };
253
+ }
254
+
255
+ const section = args[0];
256
+ if (!section) {
257
+ return { data: { content } };
258
+ }
259
+
260
+ const fieldEscaped = escapeRegex(section);
261
+
262
+ // Check for **field:** value (bold format)
263
+ const boldPattern = new RegExp(`\\*\\*${fieldEscaped}:\\*\\*\\s*(.*)`, 'i');
264
+ const boldMatch = content.match(boldPattern);
265
+ if (boldMatch) {
266
+ return { data: { [section]: boldMatch[1].trim() } };
267
+ }
268
+
269
+ // Check for field: value (plain format)
270
+ const plainPattern = new RegExp(`^${fieldEscaped}:\\s*(.*)`, 'im');
271
+ const plainMatch = content.match(plainPattern);
272
+ if (plainMatch) {
273
+ return { data: { [section]: plainMatch[1].trim() } };
274
+ }
275
+
276
+ // Check for ## Section
277
+ const sectionPattern = new RegExp(`##\\s*${fieldEscaped}\\s*\n([\\s\\S]*?)(?=\\n##|$)`, 'i');
278
+ const sectionMatch = content.match(sectionPattern);
279
+ if (sectionMatch) {
280
+ return { data: { [section]: sectionMatch[1].trim() } };
281
+ }
282
+
283
+ return { data: { error: `Section or field "${section}" not found` } };
284
+ };
285
+
286
+ /**
287
+ * Query handler for state-snapshot.
288
+ *
289
+ * Returns a structured snapshot of project state with decisions, blockers, and session.
290
+ *
291
+ * Port of cmdStateSnapshot from state.cjs lines 546-641.
292
+ *
293
+ * @param args - Unused
294
+ * @param projectDir - Project root directory
295
+ * @returns QueryResult with structured snapshot
296
+ */
297
+ export const stateSnapshot: QueryHandler = async (_args, projectDir) => {
298
+ const statePath = planningPaths(projectDir).state;
299
+
300
+ let content: string;
301
+ try {
302
+ content = await readFile(statePath, 'utf-8');
303
+ } catch {
304
+ return { data: { error: 'STATE.md not found' } };
305
+ }
306
+
307
+ // Extract basic fields
308
+ const currentPhase = stateExtractField(content, 'Current Phase');
309
+ const currentPhaseName = stateExtractField(content, 'Current Phase Name');
310
+ const totalPhasesRaw = stateExtractField(content, 'Total Phases');
311
+ const currentPlan = stateExtractField(content, 'Current Plan');
312
+ const totalPlansRaw = stateExtractField(content, 'Total Plans in Phase');
313
+ const status = stateExtractField(content, 'Status');
314
+ const progressRaw = stateExtractField(content, 'Progress');
315
+ const lastActivity = stateExtractField(content, 'Last Activity');
316
+ const lastActivityDesc = stateExtractField(content, 'Last Activity Description');
317
+ const pausedAt = stateExtractField(content, 'Paused At');
318
+
319
+ // Parse numeric fields
320
+ const totalPhases = totalPhasesRaw ? parseInt(totalPhasesRaw, 10) : null;
321
+ const totalPlansInPhase = totalPlansRaw ? parseInt(totalPlansRaw, 10) : null;
322
+ // Match gsd-tools `cmdStateSnapshot` (state.cjs): parseInt(progressRaw.replace('%',''), 10) — NaN → null
323
+ let progressPercent: number | null = null;
324
+ if (progressRaw) {
325
+ const n = parseInt(progressRaw.replace(/%/g, ''), 10);
326
+ progressPercent = Number.isFinite(n) ? n : null;
327
+ }
328
+
329
+ // Extract decisions table
330
+ const decisions: Array<{ phase: string; summary: string; rationale: string }> = [];
331
+ const decisionsMatch = content.match(/##\s*Decisions Made[\s\S]*?\n\|[^\n]+\n\|[-|\s]+\n([\s\S]*?)(?=\n##|\n$|$)/i);
332
+ if (decisionsMatch) {
333
+ const tableBody = decisionsMatch[1];
334
+ const rows = tableBody.trim().split('\n').filter(r => r.includes('|'));
335
+ for (const row of rows) {
336
+ const cells = row.split('|').map(c => c.trim()).filter(Boolean);
337
+ if (cells.length >= 3) {
338
+ decisions.push({
339
+ phase: cells[0],
340
+ summary: cells[1],
341
+ rationale: cells[2],
342
+ });
343
+ }
344
+ }
345
+ }
346
+
347
+ // Extract blockers list
348
+ const blockers: string[] = [];
349
+ const blockersMatch = content.match(/##\s*Blockers\s*\n([\s\S]*?)(?=\n##|$)/i);
350
+ if (blockersMatch) {
351
+ const blockersSection = blockersMatch[1];
352
+ const items = blockersSection.match(/^-\s+(.+)$/gm) || [];
353
+ for (const item of items) {
354
+ blockers.push(item.replace(/^-\s+/, '').trim());
355
+ }
356
+ }
357
+
358
+ // Extract session info
359
+ const session: { last_date: string | null; stopped_at: string | null; resume_file: string | null } = {
360
+ last_date: null,
361
+ stopped_at: null,
362
+ resume_file: null,
363
+ };
364
+
365
+ const sessionMatch = content.match(/##\s*Session\s*\n([\s\S]*?)(?=\n##|$)/i);
366
+ if (sessionMatch) {
367
+ const sessionSection = sessionMatch[1];
368
+ const lastDateMatch = sessionSection.match(/\*\*Last Date:\*\*\s*(.+)/i)
369
+ || sessionSection.match(/^Last Date:\s*(.+)/im);
370
+ const stoppedAtMatch = sessionSection.match(/\*\*Stopped At:\*\*\s*(.+)/i)
371
+ || sessionSection.match(/^Stopped At:\s*(.+)/im);
372
+ const resumeFileMatch = sessionSection.match(/\*\*Resume File:\*\*\s*(.+)/i)
373
+ || sessionSection.match(/^Resume File:\s*(.+)/im);
374
+
375
+ if (lastDateMatch) session.last_date = lastDateMatch[1].trim();
376
+ if (stoppedAtMatch) session.stopped_at = stoppedAtMatch[1].trim();
377
+ if (resumeFileMatch) session.resume_file = resumeFileMatch[1].trim();
378
+ }
379
+
380
+ const result = {
381
+ current_phase: currentPhase,
382
+ current_phase_name: currentPhaseName,
383
+ total_phases: totalPhases,
384
+ current_plan: currentPlan,
385
+ total_plans_in_phase: totalPlansInPhase,
386
+ status,
387
+ progress_percent: progressPercent,
388
+ last_activity: lastActivity,
389
+ last_activity_desc: lastActivityDesc,
390
+ decisions,
391
+ blockers,
392
+ paused_at: pausedAt,
393
+ session,
394
+ };
395
+
396
+ return { data: result };
397
+ };
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Tests for summary / history digest handlers.
3
+ */
4
+
5
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
6
+ import { mkdtemp, writeFile, mkdir, rm } from 'node:fs/promises';
7
+ import { join } from 'node:path';
8
+ import { tmpdir } from 'node:os';
9
+
10
+ import { summaryExtract, historyDigest } from './summary.js';
11
+
12
+ describe('summaryExtract', () => {
13
+ let tmpDir: string;
14
+
15
+ beforeEach(async () => {
16
+ tmpDir = await mkdtemp(join(tmpdir(), 'gsd-sum-'));
17
+ await mkdir(join(tmpDir, '.planning', 'phases', '01-x'), { recursive: true });
18
+ });
19
+
20
+ afterEach(async () => {
21
+ await rm(tmpDir, { recursive: true, force: true });
22
+ });
23
+
24
+ it('returns structured fields from SUMMARY frontmatter (CJS parity)', async () => {
25
+ const rel = '.planning/phases/01-x/01-SUMMARY.md';
26
+ await writeFile(
27
+ join(tmpDir, '.planning', 'phases', '01-x', '01-SUMMARY.md'),
28
+ [
29
+ '---',
30
+ 'phase: "01"',
31
+ 'name: Test Phase',
32
+ 'one-liner: From YAML',
33
+ 'key-files:',
34
+ ' - a.ts',
35
+ 'key-decisions:',
36
+ ' - "Choice: because reasons"',
37
+ 'patterns-established:',
38
+ ' - "Pattern one"',
39
+ 'tech-stack:',
40
+ ' added:',
41
+ ' - vitest',
42
+ 'requirements-completed:',
43
+ ' - R1',
44
+ '---',
45
+ '',
46
+ '# Summary',
47
+ '',
48
+ '**Body one-liner ignored when FM has one-liner**',
49
+ '',
50
+ ].join('\n'),
51
+ 'utf-8',
52
+ );
53
+ const r = await summaryExtract([rel], tmpDir);
54
+ const data = r.data as Record<string, unknown>;
55
+ expect(data.path).toBe(rel);
56
+ expect(data.one_liner).toBe('From YAML');
57
+ expect(data.key_files).toEqual(['a.ts']);
58
+ expect(data.requirements_completed).toEqual(['R1']);
59
+ expect(Array.isArray(data.decisions)).toBe(true);
60
+ });
61
+
62
+ it('filters with --fields', async () => {
63
+ const rel = '.planning/phases/01-x/01-SUMMARY.md';
64
+ await writeFile(
65
+ join(tmpDir, '.planning', 'phases', '01-x', '01-SUMMARY.md'),
66
+ ['---', 'phase: "01"', 'one-liner: X', 'key-files:', ' - z.ts', '---', ''].join('\n'),
67
+ 'utf-8',
68
+ );
69
+ const r = await summaryExtract([rel, '--fields', 'path,one_liner'], tmpDir);
70
+ const data = r.data as Record<string, unknown>;
71
+ expect(Object.keys(data).sort()).toEqual(['one_liner', 'path'].sort());
72
+ expect(data.one_liner).toBe('X');
73
+ });
74
+ });
75
+
76
+ describe('historyDigest', () => {
77
+ let tmpDir: string;
78
+
79
+ beforeEach(async () => {
80
+ tmpDir = await mkdtemp(join(tmpdir(), 'gsd-hist-'));
81
+ await mkdir(join(tmpDir, '.planning'), { recursive: true });
82
+ });
83
+
84
+ afterEach(async () => {
85
+ await rm(tmpDir, { recursive: true, force: true });
86
+ });
87
+
88
+ it('returns digest object for project without phases', async () => {
89
+ const r = await historyDigest([], tmpDir);
90
+ const data = r.data as Record<string, unknown>;
91
+ expect(data.phases).toEqual({});
92
+ expect(data.decisions).toEqual([]);
93
+ expect(data.tech_stack).toEqual([]);
94
+ });
95
+ });