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,495 @@
1
+ /**
2
+ * Workstream — CRUD operations for workstream namespacing
3
+ *
4
+ * Workstreams enable parallel milestones by scoping ROADMAP.md, STATE.md,
5
+ * REQUIREMENTS.md, and phases/ into .planning/workstreams/{name}/ directories.
6
+ *
7
+ * When no workstreams/ directory exists, GSD operates in "flat mode" with
8
+ * everything at .planning/ — backward compatible with pre-workstream installs.
9
+ */
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const { output, error, planningPaths, planningRoot, toPosixPath, getMilestoneInfo, generateSlugInternal, setActiveWorkstream, getActiveWorkstream, filterPlanFiles, filterSummaryFiles, readSubdirectories } = require('./core.cjs');
14
+ const { stateExtractField } = require('./state.cjs');
15
+
16
+ // ─── Migration ──────────────────────────────────────────────────────────────
17
+
18
+ /**
19
+ * Migrate flat .planning/ layout to workstream mode.
20
+ * Moves per-workstream files (ROADMAP.md, STATE.md, REQUIREMENTS.md, phases/)
21
+ * into .planning/workstreams/{name}/. Shared files (PROJECT.md, config.json,
22
+ * milestones/, research/, codebase/, todos/) stay in place.
23
+ */
24
+ function migrateToWorkstreams(cwd, workstreamName) {
25
+ if (!workstreamName || /[/\\]/.test(workstreamName) || workstreamName === '.' || workstreamName === '..') {
26
+ throw new Error('Invalid workstream name for migration');
27
+ }
28
+
29
+ const baseDir = planningRoot(cwd);
30
+ const wsDir = path.join(baseDir, 'workstreams', workstreamName);
31
+
32
+ if (fs.existsSync(path.join(baseDir, 'workstreams'))) {
33
+ throw new Error('Already in workstream mode — .planning/workstreams/ exists');
34
+ }
35
+
36
+ const toMove = [
37
+ { name: 'ROADMAP.md', type: 'file' },
38
+ { name: 'STATE.md', type: 'file' },
39
+ { name: 'REQUIREMENTS.md', type: 'file' },
40
+ { name: 'phases', type: 'dir' },
41
+ ];
42
+
43
+ fs.mkdirSync(wsDir, { recursive: true });
44
+
45
+ const filesMoved = [];
46
+ try {
47
+ for (const item of toMove) {
48
+ const src = path.join(baseDir, item.name);
49
+ if (fs.existsSync(src)) {
50
+ const dest = path.join(wsDir, item.name);
51
+ fs.renameSync(src, dest);
52
+ filesMoved.push(item.name);
53
+ }
54
+ }
55
+ } catch (err) {
56
+ for (const name of filesMoved) {
57
+ try { fs.renameSync(path.join(wsDir, name), path.join(baseDir, name)); } catch {}
58
+ }
59
+ try { fs.rmSync(wsDir, { recursive: true }); } catch {}
60
+ try { fs.rmdirSync(path.join(baseDir, 'workstreams')); } catch {}
61
+ throw err;
62
+ }
63
+
64
+ return { migrated: true, workstream: workstreamName, files_moved: filesMoved };
65
+ }
66
+
67
+ // ─── CRUD Commands ──────────────────────────────────────────────────────────
68
+
69
+ function cmdWorkstreamCreate(cwd, name, options, raw) {
70
+ if (!name) {
71
+ error('workstream name required. Usage: workstream create <name>');
72
+ }
73
+
74
+ const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
75
+ if (!slug) {
76
+ error('Invalid workstream name — must contain at least one alphanumeric character');
77
+ }
78
+
79
+ const baseDir = planningRoot(cwd);
80
+ if (!fs.existsSync(baseDir)) {
81
+ error('.planning/ directory not found — run /gsd-new-project first');
82
+ }
83
+
84
+ const wsRoot = path.join(baseDir, 'workstreams');
85
+ const wsDir = path.join(wsRoot, slug);
86
+
87
+ if (fs.existsSync(wsDir) && fs.existsSync(path.join(wsDir, 'STATE.md'))) {
88
+ output({ created: false, error: 'already_exists', workstream: slug, path: toPosixPath(path.relative(cwd, wsDir)) }, raw);
89
+ return;
90
+ }
91
+
92
+ const isFlatMode = !fs.existsSync(wsRoot);
93
+ let migration = null;
94
+ if (isFlatMode && options.migrate !== false) {
95
+ const hasExistingWork = fs.existsSync(path.join(baseDir, 'ROADMAP.md')) ||
96
+ fs.existsSync(path.join(baseDir, 'STATE.md')) ||
97
+ fs.existsSync(path.join(baseDir, 'phases'));
98
+
99
+ if (hasExistingWork) {
100
+ const migrateName = options.migrateName || null;
101
+ let existingWsName;
102
+ if (migrateName) {
103
+ existingWsName = migrateName;
104
+ } else {
105
+ try {
106
+ const milestone = getMilestoneInfo(cwd);
107
+ existingWsName = generateSlugInternal(milestone.name) || 'default';
108
+ } catch {
109
+ existingWsName = 'default';
110
+ }
111
+ }
112
+
113
+ try {
114
+ migration = migrateToWorkstreams(cwd, existingWsName);
115
+ } catch (e) {
116
+ output({ created: false, error: 'migration_failed', message: e.message }, raw);
117
+ return;
118
+ }
119
+ } else {
120
+ fs.mkdirSync(wsRoot, { recursive: true });
121
+ }
122
+ }
123
+
124
+ fs.mkdirSync(wsDir, { recursive: true });
125
+ fs.mkdirSync(path.join(wsDir, 'phases'), { recursive: true });
126
+
127
+ const today = new Date().toISOString().split('T')[0];
128
+ const stateContent = [
129
+ '---',
130
+ `workstream: ${slug}`,
131
+ `created: ${today}`,
132
+ '---',
133
+ '',
134
+ '# Project State',
135
+ '',
136
+ '## Current Position',
137
+ '**Status:** Not started',
138
+ '**Current Phase:** None',
139
+ `**Last Activity:** ${today}`,
140
+ '**Last Activity Description:** Workstream created',
141
+ '',
142
+ '## Progress',
143
+ '**Phases Complete:** 0',
144
+ '**Current Plan:** N/A',
145
+ '',
146
+ '## Session Continuity',
147
+ '**Stopped At:** N/A',
148
+ '**Resume File:** None',
149
+ '',
150
+ ].join('\n');
151
+
152
+ const statePath = path.join(wsDir, 'STATE.md');
153
+ if (!fs.existsSync(statePath)) {
154
+ fs.writeFileSync(statePath, stateContent, 'utf-8');
155
+ }
156
+
157
+ setActiveWorkstream(cwd, slug);
158
+
159
+ const relPath = toPosixPath(path.relative(cwd, wsDir));
160
+ output({
161
+ created: true,
162
+ workstream: slug,
163
+ path: relPath,
164
+ state_path: relPath + '/STATE.md',
165
+ phases_path: relPath + '/phases',
166
+ migration: migration || null,
167
+ active: true,
168
+ }, raw);
169
+ }
170
+
171
+ function cmdWorkstreamList(cwd, raw) {
172
+ const wsRoot = path.join(planningRoot(cwd), 'workstreams');
173
+
174
+ if (!fs.existsSync(wsRoot)) {
175
+ output({ mode: 'flat', workstreams: [], message: 'No workstreams — operating in flat mode' }, raw);
176
+ return;
177
+ }
178
+
179
+ const entries = fs.readdirSync(wsRoot, { withFileTypes: true });
180
+ const workstreams = [];
181
+
182
+ for (const entry of entries) {
183
+ if (!entry.isDirectory()) continue;
184
+
185
+ const wsDir = path.join(wsRoot, entry.name);
186
+ const phasesDir = path.join(wsDir, 'phases');
187
+
188
+ const phaseDirs = readSubdirectories(phasesDir);
189
+ const phaseCount = phaseDirs.length;
190
+ let completedCount = 0;
191
+ for (const d of phaseDirs) {
192
+ try {
193
+ const phaseFiles = fs.readdirSync(path.join(phasesDir, d));
194
+ const plans = filterPlanFiles(phaseFiles);
195
+ const summaries = filterSummaryFiles(phaseFiles);
196
+ if (plans.length > 0 && summaries.length >= plans.length) completedCount++;
197
+ } catch {}
198
+ }
199
+
200
+ let status = 'unknown', currentPhase = null;
201
+ try {
202
+ const stateContent = fs.readFileSync(path.join(wsDir, 'STATE.md'), 'utf-8');
203
+ status = stateExtractField(stateContent, 'Status') || 'unknown';
204
+ currentPhase = stateExtractField(stateContent, 'Current Phase');
205
+ } catch {}
206
+
207
+ workstreams.push({
208
+ name: entry.name,
209
+ path: toPosixPath(path.relative(cwd, wsDir)),
210
+ has_roadmap: fs.existsSync(path.join(wsDir, 'ROADMAP.md')),
211
+ has_state: fs.existsSync(path.join(wsDir, 'STATE.md')),
212
+ status,
213
+ current_phase: currentPhase,
214
+ phase_count: phaseCount,
215
+ completed_phases: completedCount,
216
+ });
217
+ }
218
+
219
+ output({ mode: 'workstream', workstreams, count: workstreams.length }, raw);
220
+ }
221
+
222
+ function cmdWorkstreamStatus(cwd, name, raw) {
223
+ if (!name) error('workstream name required. Usage: workstream status <name>');
224
+ if (/[/\\]/.test(name) || name === '.' || name === '..') error('Invalid workstream name');
225
+
226
+ const wsDir = path.join(planningRoot(cwd), 'workstreams', name);
227
+ if (!fs.existsSync(wsDir)) {
228
+ output({ found: false, workstream: name }, raw);
229
+ return;
230
+ }
231
+
232
+ const p = planningPaths(cwd, name);
233
+ const relPath = toPosixPath(path.relative(cwd, wsDir));
234
+
235
+ const files = {
236
+ roadmap: fs.existsSync(p.roadmap),
237
+ state: fs.existsSync(p.state),
238
+ requirements: fs.existsSync(p.requirements),
239
+ };
240
+
241
+ const phases = [];
242
+ for (const dir of readSubdirectories(p.phases).sort()) {
243
+ try {
244
+ const phaseFiles = fs.readdirSync(path.join(p.phases, dir));
245
+ const plans = filterPlanFiles(phaseFiles);
246
+ const summaries = filterSummaryFiles(phaseFiles);
247
+ phases.push({
248
+ directory: dir,
249
+ status: summaries.length >= plans.length && plans.length > 0 ? 'complete' :
250
+ plans.length > 0 ? 'in_progress' : 'pending',
251
+ plan_count: plans.length,
252
+ summary_count: summaries.length,
253
+ });
254
+ } catch {}
255
+ }
256
+
257
+ let stateInfo = {};
258
+ try {
259
+ const stateContent = fs.readFileSync(p.state, 'utf-8');
260
+ stateInfo = {
261
+ status: stateExtractField(stateContent, 'Status') || 'unknown',
262
+ current_phase: stateExtractField(stateContent, 'Current Phase'),
263
+ last_activity: stateExtractField(stateContent, 'Last Activity'),
264
+ };
265
+ } catch {}
266
+
267
+ output({
268
+ found: true,
269
+ workstream: name,
270
+ path: relPath,
271
+ files,
272
+ phases,
273
+ phase_count: phases.length,
274
+ completed_phases: phases.filter(ph => ph.status === 'complete').length,
275
+ ...stateInfo,
276
+ }, raw);
277
+ }
278
+
279
+ function cmdWorkstreamComplete(cwd, name, options, raw) {
280
+ if (!name) error('workstream name required. Usage: workstream complete <name>');
281
+ if (/[/\\]/.test(name) || name === '.' || name === '..') error('Invalid workstream name');
282
+
283
+ const root = planningRoot(cwd);
284
+ const wsRoot = path.join(root, 'workstreams');
285
+ const wsDir = path.join(wsRoot, name);
286
+
287
+ if (!fs.existsSync(wsDir)) {
288
+ output({ completed: false, error: 'not_found', workstream: name }, raw);
289
+ return;
290
+ }
291
+
292
+ const active = getActiveWorkstream(cwd);
293
+ if (active === name) setActiveWorkstream(cwd, null);
294
+
295
+ const archiveDir = path.join(root, 'milestones');
296
+ const today = new Date().toISOString().split('T')[0];
297
+ let archivePath = path.join(archiveDir, `ws-${name}-${today}`);
298
+ let suffix = 1;
299
+ while (fs.existsSync(archivePath)) {
300
+ archivePath = path.join(archiveDir, `ws-${name}-${today}-${suffix++}`);
301
+ }
302
+
303
+ fs.mkdirSync(archivePath, { recursive: true });
304
+
305
+ const filesMoved = [];
306
+ try {
307
+ const entries = fs.readdirSync(wsDir, { withFileTypes: true });
308
+ for (const entry of entries) {
309
+ fs.renameSync(path.join(wsDir, entry.name), path.join(archivePath, entry.name));
310
+ filesMoved.push(entry.name);
311
+ }
312
+ } catch (err) {
313
+ for (const fname of filesMoved) {
314
+ try { fs.renameSync(path.join(archivePath, fname), path.join(wsDir, fname)); } catch {}
315
+ }
316
+ try { fs.rmSync(archivePath, { recursive: true }); } catch {}
317
+ if (active === name) setActiveWorkstream(cwd, name);
318
+ output({ completed: false, error: 'archive_failed', message: err.message, workstream: name }, raw);
319
+ return;
320
+ }
321
+
322
+ try { fs.rmdirSync(wsDir); } catch {}
323
+
324
+ let remainingWs = 0;
325
+ try {
326
+ remainingWs = fs.readdirSync(wsRoot, { withFileTypes: true }).filter(e => e.isDirectory()).length;
327
+ if (remainingWs === 0) fs.rmdirSync(wsRoot);
328
+ } catch {}
329
+
330
+ output({
331
+ completed: true,
332
+ workstream: name,
333
+ archived_to: toPosixPath(path.relative(cwd, archivePath)),
334
+ remaining_workstreams: remainingWs,
335
+ reverted_to_flat: remainingWs === 0,
336
+ }, raw);
337
+ }
338
+
339
+ // ─── Active Workstream Commands ──────────────────────────────────────────────
340
+
341
+ function cmdWorkstreamSet(cwd, name, raw) {
342
+ if (!name || name === '--clear') {
343
+ if (name !== '--clear') {
344
+ error('Workstream name required. Usage: workstream set <name> (or workstream set --clear to unset)');
345
+ }
346
+ const previous = getActiveWorkstream(cwd);
347
+ setActiveWorkstream(cwd, null);
348
+ output({ active: null, cleared: true, previous: previous || null }, raw);
349
+ return;
350
+ }
351
+
352
+ if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
353
+ output({ active: null, error: 'invalid_name', message: 'Workstream name must be alphanumeric, hyphens, and underscores only' }, raw);
354
+ return;
355
+ }
356
+
357
+ const wsDir = path.join(planningRoot(cwd), 'workstreams', name);
358
+ if (!fs.existsSync(wsDir)) {
359
+ output({ active: null, error: 'not_found', workstream: name }, raw);
360
+ return;
361
+ }
362
+
363
+ setActiveWorkstream(cwd, name);
364
+ output({ active: name, set: true }, raw, name);
365
+ }
366
+
367
+ function cmdWorkstreamGet(cwd, raw) {
368
+ const active = getActiveWorkstream(cwd);
369
+ const wsRoot = path.join(planningRoot(cwd), 'workstreams');
370
+ output({ active, mode: fs.existsSync(wsRoot) ? 'workstream' : 'flat' }, raw, active || 'none');
371
+ }
372
+
373
+ function cmdWorkstreamProgress(cwd, raw) {
374
+ const root = planningRoot(cwd);
375
+ const wsRoot = path.join(root, 'workstreams');
376
+
377
+ if (!fs.existsSync(wsRoot)) {
378
+ output({ mode: 'flat', workstreams: [], message: 'No workstreams — operating in flat mode' }, raw);
379
+ return;
380
+ }
381
+
382
+ const active = getActiveWorkstream(cwd);
383
+ const entries = fs.readdirSync(wsRoot, { withFileTypes: true });
384
+ const workstreams = [];
385
+
386
+ for (const entry of entries) {
387
+ if (!entry.isDirectory()) continue;
388
+
389
+ const wsDir = path.join(wsRoot, entry.name);
390
+ const phasesDir = path.join(wsDir, 'phases');
391
+
392
+ const phaseDirsProgress = readSubdirectories(phasesDir);
393
+ const phaseCount = phaseDirsProgress.length;
394
+ let completedCount = 0, totalPlans = 0, completedPlans = 0;
395
+ for (const d of phaseDirsProgress) {
396
+ try {
397
+ const phaseFiles = fs.readdirSync(path.join(phasesDir, d));
398
+ const plans = filterPlanFiles(phaseFiles);
399
+ const summaries = filterSummaryFiles(phaseFiles);
400
+ totalPlans += plans.length;
401
+ completedPlans += Math.min(summaries.length, plans.length);
402
+ if (plans.length > 0 && summaries.length >= plans.length) completedCount++;
403
+ } catch {}
404
+ }
405
+
406
+ let roadmapPhaseCount = phaseCount;
407
+ try {
408
+ const roadmapContent = fs.readFileSync(path.join(wsDir, 'ROADMAP.md'), 'utf-8');
409
+ const phaseMatches = roadmapContent.match(/^###?\s+Phase\s+\d/gm);
410
+ if (phaseMatches) roadmapPhaseCount = phaseMatches.length;
411
+ } catch {}
412
+
413
+ let status = 'unknown', currentPhase = null;
414
+ try {
415
+ const stateContent = fs.readFileSync(path.join(wsDir, 'STATE.md'), 'utf-8');
416
+ status = stateExtractField(stateContent, 'Status') || 'unknown';
417
+ currentPhase = stateExtractField(stateContent, 'Current Phase');
418
+ } catch {}
419
+
420
+ workstreams.push({
421
+ name: entry.name,
422
+ active: entry.name === active,
423
+ status,
424
+ current_phase: currentPhase,
425
+ phases: `${completedCount}/${roadmapPhaseCount}`,
426
+ plans: `${completedPlans}/${totalPlans}`,
427
+ progress_percent: roadmapPhaseCount > 0 ? Math.round((completedCount / roadmapPhaseCount) * 100) : 0,
428
+ });
429
+ }
430
+
431
+ output({ mode: 'workstream', active, workstreams, count: workstreams.length }, raw);
432
+ }
433
+
434
+ // ─── Collision Detection ────────────────────────────────────────────────────
435
+
436
+ /**
437
+ * Return other workstreams that are NOT complete.
438
+ * Used to detect whether the milestone has active parallel work
439
+ * when a workstream finishes its last phase.
440
+ */
441
+ function getOtherActiveWorkstreams(cwd, excludeWs) {
442
+ const wsRoot = path.join(planningRoot(cwd), 'workstreams');
443
+ if (!fs.existsSync(wsRoot)) return [];
444
+
445
+ const entries = fs.readdirSync(wsRoot, { withFileTypes: true });
446
+ const others = [];
447
+
448
+ for (const entry of entries) {
449
+ if (!entry.isDirectory() || entry.name === excludeWs) continue;
450
+
451
+ const wsDir = path.join(wsRoot, entry.name);
452
+ const statePath = path.join(wsDir, 'STATE.md');
453
+
454
+ let status = 'unknown', currentPhase = null;
455
+ try {
456
+ const content = fs.readFileSync(statePath, 'utf-8');
457
+ status = stateExtractField(content, 'Status') || 'unknown';
458
+ currentPhase = stateExtractField(content, 'Current Phase');
459
+ } catch {}
460
+
461
+ if (status.toLowerCase().includes('milestone complete') ||
462
+ status.toLowerCase().includes('archived')) {
463
+ continue;
464
+ }
465
+
466
+ const phasesDir = path.join(wsDir, 'phases');
467
+ const phaseDirsOther = readSubdirectories(phasesDir);
468
+ const phaseCount = phaseDirsOther.length;
469
+ let completedCount = 0;
470
+ for (const d of phaseDirsOther) {
471
+ try {
472
+ const phaseFiles = fs.readdirSync(path.join(phasesDir, d));
473
+ const plans = filterPlanFiles(phaseFiles);
474
+ const summaries = filterSummaryFiles(phaseFiles);
475
+ if (plans.length > 0 && summaries.length >= plans.length) completedCount++;
476
+ } catch {}
477
+ }
478
+
479
+ others.push({ name: entry.name, status, current_phase: currentPhase, phases: `${completedCount}/${phaseCount}` });
480
+ }
481
+
482
+ return others;
483
+ }
484
+
485
+ module.exports = {
486
+ migrateToWorkstreams,
487
+ cmdWorkstreamCreate,
488
+ cmdWorkstreamList,
489
+ cmdWorkstreamStatus,
490
+ cmdWorkstreamComplete,
491
+ cmdWorkstreamSet,
492
+ cmdWorkstreamGet,
493
+ cmdWorkstreamProgress,
494
+ getOtherActiveWorkstreams,
495
+ };
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Rebuild and reinstall the bundled GSD Remix SDK without depending on the
6
+ * gsd-remix-sdk binary. This is the runtime repair path used when the SDK CLI is
7
+ * missing, stale, or otherwise unable to answer health queries.
8
+ */
9
+
10
+ const fs = require('node:fs');
11
+ const os = require('node:os');
12
+ const path = require('node:path');
13
+ const { spawnSync } = require('node:child_process');
14
+
15
+ const SDK_BIN = 'gsd-remix-sdk';
16
+
17
+ function log(message = '') {
18
+ console.log(message);
19
+ }
20
+
21
+ function fail(message, code = 1) {
22
+ console.error('');
23
+ console.error(`GSD Remix SDK repair failed: ${message}`);
24
+ process.exit(code);
25
+ }
26
+
27
+ function run(command, args, options = {}) {
28
+ log(`> ${command} ${args.join(' ')}`);
29
+ const result = spawnSync(command, args, {
30
+ stdio: 'inherit',
31
+ shell: false,
32
+ ...options,
33
+ });
34
+ if (result.error) {
35
+ fail(result.error.message);
36
+ }
37
+ if (result.status !== 0) {
38
+ fail(`Command failed with exit ${result.status}: ${command} ${args.join(' ')}`);
39
+ }
40
+ }
41
+
42
+ function resolveCommand(command) {
43
+ if (process.platform === 'win32') {
44
+ const result = spawnSync('where', [command], { encoding: 'utf-8' });
45
+ if (result.status === 0 && result.stdout.trim()) {
46
+ return result.stdout.trim().split(/\r?\n/)[0].trim();
47
+ }
48
+ return null;
49
+ }
50
+
51
+ const result = spawnSync('sh', ['-c', `command -v ${command}`], { encoding: 'utf-8' });
52
+ if (result.status === 0 && result.stdout.trim()) {
53
+ return result.stdout.trim();
54
+ }
55
+ return null;
56
+ }
57
+
58
+ function detectShellRc() {
59
+ const shell = process.env.SHELL || '';
60
+ const home = process.env.HOME || '~';
61
+ if (/\/zsh$/.test(shell)) return path.join(home, '.zshrc');
62
+ if (/\/bash$/.test(shell)) return path.join(home, '.bashrc');
63
+ if (/\/fish$/.test(shell)) return path.join(home, '.config', 'fish', 'config.fish');
64
+ return path.join(home, '.profile');
65
+ }
66
+
67
+ function parseVersion(input) {
68
+ const match = String(input).trim().match(/^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
69
+ if (!match) return null;
70
+ return [Number(match[1] || 0), Number(match[2] || 0), Number(match[3] || 0)];
71
+ }
72
+
73
+ function minNodeFromRange(range) {
74
+ const match = String(range || '').trim().match(/^>=\s*(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
75
+ if (!match) return null;
76
+ return [Number(match[1] || 0), Number(match[2] || 0), Number(match[3] || 0)];
77
+ }
78
+
79
+ function compareVersions(left, right) {
80
+ for (let i = 0; i < 3; i += 1) {
81
+ if (left[i] !== right[i]) return left[i] - right[i];
82
+ }
83
+ return 0;
84
+ }
85
+
86
+ function assertNodeSupported(pkg) {
87
+ const required = pkg.engines && pkg.engines.node;
88
+ const minimum = minNodeFromRange(required);
89
+ if (!minimum) return;
90
+
91
+ const actual = parseVersion(process.version);
92
+ if (!actual || compareVersions(actual, minimum) < 0) {
93
+ fail(`Current Node ${process.version} does not satisfy ${required}. Switch Node versions and retry.`);
94
+ }
95
+ }
96
+
97
+ function npmCommand() {
98
+ return process.platform === 'win32' ? 'npm.cmd' : 'npm';
99
+ }
100
+
101
+ function npmPrefix(npmCmd) {
102
+ const result = spawnSync(npmCmd, ['config', 'get', 'prefix'], { encoding: 'utf-8' });
103
+ if (result.status !== 0) return null;
104
+ return (result.stdout || '').trim() || null;
105
+ }
106
+
107
+ function globalModulesDir(prefix) {
108
+ if (!prefix) return null;
109
+ return process.platform === 'win32'
110
+ ? path.join(prefix, 'node_modules')
111
+ : path.join(prefix, 'lib', 'node_modules');
112
+ }
113
+
114
+ function chmodInstalledCli(npmCmd, sdkPackageName) {
115
+ const prefix = npmPrefix(npmCmd);
116
+ const modulesDir = globalModulesDir(prefix);
117
+ if (!modulesDir) return;
118
+
119
+ const cliPath = path.join(modulesDir, sdkPackageName, 'dist', 'cli.js');
120
+ try {
121
+ fs.chmodSync(cliPath, 0o755);
122
+ } catch {
123
+ // Non-fatal. The final PATH verification catches real install failures.
124
+ }
125
+ }
126
+
127
+ function reportOffPath(npmCmd) {
128
+ const prefix = npmPrefix(npmCmd);
129
+ const binDir = prefix
130
+ ? (process.platform === 'win32' ? prefix : path.join(prefix, 'bin'))
131
+ : null;
132
+
133
+ console.error('');
134
+ console.error(`Built and installed ${SDK_BIN}, but it is not visible on PATH.`);
135
+ if (binDir) {
136
+ console.error(`Installed npm binaries are expected under: ${binDir}`);
137
+ if (process.platform !== 'win32') {
138
+ const rc = detectShellRc();
139
+ console.error(`Add it with: echo 'export PATH="${binDir}:$PATH"' >> ${rc}`);
140
+ console.error(`Then run: source ${rc}`);
141
+ }
142
+ }
143
+ console.error(`Verify with: command -v ${SDK_BIN}`);
144
+ process.exit(2);
145
+ }
146
+
147
+ function main() {
148
+ const sdkDir = path.resolve(process.env.GSD_REMIX_SDK_DIR || path.join(__dirname, '..', 'sdk'));
149
+ const packageJsonPath = path.join(sdkDir, 'package.json');
150
+
151
+ if (!fs.existsSync(packageJsonPath)) {
152
+ fail(`Bundled SDK source not found at ${sdkDir}. Re-run npx gsd-remix@latest to refresh runtime assets.`);
153
+ }
154
+
155
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
156
+ assertNodeSupported(pkg);
157
+
158
+ const npmCmd = npmCommand();
159
+ log('GSD Remix SDK repair');
160
+ log(`SDK source: ${sdkDir}`);
161
+ log('');
162
+
163
+ run(npmCmd, ['install'], { cwd: sdkDir });
164
+ run(npmCmd, ['run', 'build'], { cwd: sdkDir });
165
+ run(npmCmd, ['install', '-g', '.'], { cwd: sdkDir });
166
+ chmodInstalledCli(npmCmd, pkg.name || '@gsd-remix/sdk');
167
+
168
+ const resolved = resolveCommand(SDK_BIN);
169
+ if (!resolved) {
170
+ reportOffPath(npmCmd);
171
+ }
172
+
173
+ log('');
174
+ log(`GSD Remix SDK repaired: ${resolved}`);
175
+ }
176
+
177
+ main();
@@ -0,0 +1,21 @@
1
+ # Dev Context Profile
2
+
3
+ Agent output guidance for dev mode. Loaded when `context: dev` is set in config.json.
4
+
5
+ ## Output Style
6
+
7
+ - Concise, action-oriented responses
8
+ - Lead with the code change or command, follow with brief rationale
9
+ - Skip preamble — assume the developer has full context
10
+ - Use inline code references (`file:line`) over prose descriptions
11
+
12
+ ## Focus Areas
13
+
14
+ - Working code that compiles and passes tests
15
+ - Minimal diff — change only what is necessary
16
+ - Flag side effects or breaking changes immediately
17
+ - Surface the next actionable step at the end of every response
18
+
19
+ ## Verbosity
20
+
21
+ Low. One-liner explanations unless the change is non-obvious. Omit background theory, alternative approaches, and caveats that do not affect the current task.