@opengsd/gsd-core 1.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (503) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja-JP.md +870 -0
  3. package/README.ko-KR.md +861 -0
  4. package/README.md +301 -0
  5. package/README.pt-BR.md +492 -0
  6. package/README.zh-CN.md +842 -0
  7. package/agents/gsd-advisor-researcher.md +127 -0
  8. package/agents/gsd-ai-researcher.md +133 -0
  9. package/agents/gsd-assumptions-analyzer.md +105 -0
  10. package/agents/gsd-code-fixer.md +668 -0
  11. package/agents/gsd-code-reviewer.md +387 -0
  12. package/agents/gsd-codebase-mapper.md +853 -0
  13. package/agents/gsd-debug-session-manager.md +314 -0
  14. package/agents/gsd-debugger.md +1452 -0
  15. package/agents/gsd-doc-classifier.md +168 -0
  16. package/agents/gsd-doc-synthesizer.md +204 -0
  17. package/agents/gsd-doc-verifier.md +217 -0
  18. package/agents/gsd-doc-writer.md +615 -0
  19. package/agents/gsd-domain-researcher.md +153 -0
  20. package/agents/gsd-eval-auditor.md +191 -0
  21. package/agents/gsd-eval-planner.md +154 -0
  22. package/agents/gsd-executor.md +772 -0
  23. package/agents/gsd-framework-selector.md +160 -0
  24. package/agents/gsd-integration-checker.md +470 -0
  25. package/agents/gsd-intel-updater.md +342 -0
  26. package/agents/gsd-nyquist-auditor.md +203 -0
  27. package/agents/gsd-pattern-mapper.md +335 -0
  28. package/agents/gsd-phase-researcher.md +928 -0
  29. package/agents/gsd-plan-checker.md +978 -0
  30. package/agents/gsd-planner.md +1218 -0
  31. package/agents/gsd-project-researcher.md +677 -0
  32. package/agents/gsd-research-synthesizer.md +255 -0
  33. package/agents/gsd-roadmapper.md +688 -0
  34. package/agents/gsd-security-auditor.md +155 -0
  35. package/agents/gsd-ui-auditor.md +495 -0
  36. package/agents/gsd-ui-checker.md +309 -0
  37. package/agents/gsd-ui-researcher.md +380 -0
  38. package/agents/gsd-user-profiler.md +171 -0
  39. package/agents/gsd-verifier.md +917 -0
  40. package/bin/install.js +10936 -0
  41. package/bin/lib/ui-safety-gate.cjs +107 -0
  42. package/commands/gsd/add-tests.md +42 -0
  43. package/commands/gsd/ai-integration-phase.md +37 -0
  44. package/commands/gsd/audit-fix.md +34 -0
  45. package/commands/gsd/audit-milestone.md +37 -0
  46. package/commands/gsd/audit-uat.md +24 -0
  47. package/commands/gsd/autonomous.md +46 -0
  48. package/commands/gsd/capture.md +62 -0
  49. package/commands/gsd/cleanup.md +24 -0
  50. package/commands/gsd/code-review.md +59 -0
  51. package/commands/gsd/complete-milestone.md +143 -0
  52. package/commands/gsd/config.md +56 -0
  53. package/commands/gsd/debug.md +52 -0
  54. package/commands/gsd/discuss-phase.md +76 -0
  55. package/commands/gsd/docs-update.md +49 -0
  56. package/commands/gsd/eval-review.md +33 -0
  57. package/commands/gsd/execute-phase.md +64 -0
  58. package/commands/gsd/explore.md +27 -0
  59. package/commands/gsd/extract-learnings.md +23 -0
  60. package/commands/gsd/fast.md +31 -0
  61. package/commands/gsd/forensics.md +57 -0
  62. package/commands/gsd/graphify.md +199 -0
  63. package/commands/gsd/health.md +31 -0
  64. package/commands/gsd/help.md +28 -0
  65. package/commands/gsd/import.md +41 -0
  66. package/commands/gsd/inbox.md +39 -0
  67. package/commands/gsd/ingest-docs.md +42 -0
  68. package/commands/gsd/manager.md +45 -0
  69. package/commands/gsd/map-codebase.md +83 -0
  70. package/commands/gsd/milestone-summary.md +51 -0
  71. package/commands/gsd/mvp-phase.md +45 -0
  72. package/commands/gsd/new-milestone.md +45 -0
  73. package/commands/gsd/new-project.md +47 -0
  74. package/commands/gsd/ns-context.md +23 -0
  75. package/commands/gsd/ns-ideate.md +24 -0
  76. package/commands/gsd/ns-manage.md +29 -0
  77. package/commands/gsd/ns-project.md +22 -0
  78. package/commands/gsd/ns-review.md +26 -0
  79. package/commands/gsd/ns-workflow.md +28 -0
  80. package/commands/gsd/pause-work.md +43 -0
  81. package/commands/gsd/phase.md +56 -0
  82. package/commands/gsd/plan-phase.md +62 -0
  83. package/commands/gsd/plan-review-convergence.md +59 -0
  84. package/commands/gsd/pr-branch.md +26 -0
  85. package/commands/gsd/profile-user.md +46 -0
  86. package/commands/gsd/progress.md +47 -0
  87. package/commands/gsd/quick.md +174 -0
  88. package/commands/gsd/resume-work.md +30 -0
  89. package/commands/gsd/review-backlog.md +63 -0
  90. package/commands/gsd/review.md +41 -0
  91. package/commands/gsd/secure-phase.md +36 -0
  92. package/commands/gsd/settings.md +29 -0
  93. package/commands/gsd/ship.md +24 -0
  94. package/commands/gsd/sketch.md +60 -0
  95. package/commands/gsd/spec-phase.md +63 -0
  96. package/commands/gsd/spike.md +57 -0
  97. package/commands/gsd/stats.md +19 -0
  98. package/commands/gsd/surface.md +155 -0
  99. package/commands/gsd/thread.md +24 -0
  100. package/commands/gsd/ui-phase.md +35 -0
  101. package/commands/gsd/ui-review.md +33 -0
  102. package/commands/gsd/ultraplan-phase.md +34 -0
  103. package/commands/gsd/undo.md +35 -0
  104. package/commands/gsd/update.md +48 -0
  105. package/commands/gsd/validate-phase.md +36 -0
  106. package/commands/gsd/verify-work.md +39 -0
  107. package/commands/gsd/workspace.md +52 -0
  108. package/commands/gsd/workstreams.md +70 -0
  109. package/get-shit-done/bin/check-latest-version.cjs +106 -0
  110. package/get-shit-done/bin/gsd-tools.cjs +1676 -0
  111. package/get-shit-done/bin/lib/active-workstream-store.cjs +302 -0
  112. package/get-shit-done/bin/lib/adr-parser.cjs +394 -0
  113. package/get-shit-done/bin/lib/agent-command-router.cjs +65 -0
  114. package/get-shit-done/bin/lib/artifacts.cjs +53 -0
  115. package/get-shit-done/bin/lib/audit.cjs +755 -0
  116. package/get-shit-done/bin/lib/check-command-router.cjs +333 -0
  117. package/get-shit-done/bin/lib/cjs-command-router-adapter.cjs +118 -0
  118. package/get-shit-done/bin/lib/clock.cjs +96 -0
  119. package/get-shit-done/bin/lib/clusters.cjs +135 -0
  120. package/get-shit-done/bin/lib/code-review-flags.cjs +74 -0
  121. package/get-shit-done/bin/lib/command-aliases.cjs +815 -0
  122. package/get-shit-done/bin/lib/command-arg-projection.cjs +62 -0
  123. package/get-shit-done/bin/lib/command-routing-hub.cjs +388 -0
  124. package/get-shit-done/bin/lib/commands.cjs +1188 -0
  125. package/get-shit-done/bin/lib/config-schema.cjs +31 -0
  126. package/get-shit-done/bin/lib/config.cjs +728 -0
  127. package/get-shit-done/bin/lib/configuration.cjs +248 -0
  128. package/get-shit-done/bin/lib/context-utilization.cjs +47 -0
  129. package/get-shit-done/bin/lib/core.cjs +2121 -0
  130. package/get-shit-done/bin/lib/decisions.cjs +116 -0
  131. package/get-shit-done/bin/lib/docs.cjs +270 -0
  132. package/get-shit-done/bin/lib/drift.cjs +388 -0
  133. package/get-shit-done/bin/lib/fallow-runner.cjs +109 -0
  134. package/get-shit-done/bin/lib/frontmatter.cjs +389 -0
  135. package/get-shit-done/bin/lib/gap-checker.cjs +205 -0
  136. package/get-shit-done/bin/lib/graphify.cjs +592 -0
  137. package/get-shit-done/bin/lib/gsd2-import.cjs +514 -0
  138. package/get-shit-done/bin/lib/init-command-router.cjs +58 -0
  139. package/get-shit-done/bin/lib/init.cjs +2112 -0
  140. package/get-shit-done/bin/lib/install-profiles.cjs +603 -0
  141. package/get-shit-done/bin/lib/installer-migration-authoring.cjs +117 -0
  142. package/get-shit-done/bin/lib/installer-migration-report.cjs +354 -0
  143. package/get-shit-done/bin/lib/installer-migrations/000-first-time-baseline.cjs +220 -0
  144. package/get-shit-done/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +41 -0
  145. package/get-shit-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +80 -0
  146. package/get-shit-done/bin/lib/installer-migrations.cjs +778 -0
  147. package/get-shit-done/bin/lib/intel.cjs +708 -0
  148. package/get-shit-done/bin/lib/learnings.cjs +421 -0
  149. package/get-shit-done/bin/lib/milestone.cjs +314 -0
  150. package/get-shit-done/bin/lib/model-catalog.cjs +212 -0
  151. package/get-shit-done/bin/lib/model-profiles.cjs +31 -0
  152. package/get-shit-done/bin/lib/observability/event.cjs +82 -0
  153. package/get-shit-done/bin/lib/observability/logger.cjs +174 -0
  154. package/get-shit-done/bin/lib/observability/redaction.cjs +50 -0
  155. package/get-shit-done/bin/lib/package-identity.cjs +31 -0
  156. package/get-shit-done/bin/lib/phase-command-router.cjs +191 -0
  157. package/get-shit-done/bin/lib/phase-lifecycle.cjs +80 -0
  158. package/get-shit-done/bin/lib/phase.cjs +1607 -0
  159. package/get-shit-done/bin/lib/phases-command-router.cjs +39 -0
  160. package/get-shit-done/bin/lib/plan-scan.cjs +97 -0
  161. package/get-shit-done/bin/lib/planning-workspace.cjs +238 -0
  162. package/get-shit-done/bin/lib/profile-output.cjs +1141 -0
  163. package/get-shit-done/bin/lib/profile-pipeline.cjs +539 -0
  164. package/get-shit-done/bin/lib/project-root.cjs +112 -0
  165. package/get-shit-done/bin/lib/prompt-budget.cjs +399 -0
  166. package/get-shit-done/bin/lib/review-reviewer-selection.cjs +125 -0
  167. package/get-shit-done/bin/lib/roadmap-command-router.cjs +28 -0
  168. package/get-shit-done/bin/lib/roadmap.cjs +650 -0
  169. package/get-shit-done/bin/lib/runtime-artifact-layout.cjs +301 -0
  170. package/get-shit-done/bin/lib/runtime-homes.cjs +222 -0
  171. package/get-shit-done/bin/lib/runtime-name-policy.cjs +83 -0
  172. package/get-shit-done/bin/lib/runtime-slash.cjs +112 -0
  173. package/get-shit-done/bin/lib/schema-detect.cjs +165 -0
  174. package/get-shit-done/bin/lib/secrets.cjs +32 -0
  175. package/get-shit-done/bin/lib/security.cjs +600 -0
  176. package/get-shit-done/bin/lib/semver-compare.cjs +35 -0
  177. package/get-shit-done/bin/lib/shell-command-projection.cjs +500 -0
  178. package/get-shit-done/bin/lib/state-command-router.cjs +252 -0
  179. package/get-shit-done/bin/lib/state-document.cjs +263 -0
  180. package/get-shit-done/bin/lib/state.cjs +2038 -0
  181. package/get-shit-done/bin/lib/surface.cjs +470 -0
  182. package/get-shit-done/bin/lib/task-command-router.cjs +81 -0
  183. package/get-shit-done/bin/lib/template.cjs +228 -0
  184. package/get-shit-done/bin/lib/uat.cjs +289 -0
  185. package/get-shit-done/bin/lib/update-context.cjs +209 -0
  186. package/get-shit-done/bin/lib/validate-command-router.cjs +83 -0
  187. package/get-shit-done/bin/lib/validate.cjs +92 -0
  188. package/get-shit-done/bin/lib/verify-command-router.cjs +40 -0
  189. package/get-shit-done/bin/lib/verify.cjs +1511 -0
  190. package/get-shit-done/bin/lib/workstream-inventory-builder.cjs +74 -0
  191. package/get-shit-done/bin/lib/workstream-inventory.cjs +146 -0
  192. package/get-shit-done/bin/lib/workstream-name-policy.cjs +94 -0
  193. package/get-shit-done/bin/lib/workstream.cjs +389 -0
  194. package/get-shit-done/bin/lib/worktree-safety.cjs +985 -0
  195. package/get-shit-done/bin/shared/config-defaults.manifest.json +97 -0
  196. package/get-shit-done/bin/shared/config-schema.manifest.json +175 -0
  197. package/get-shit-done/bin/shared/model-catalog.json +122 -0
  198. package/get-shit-done/bin/shared/runtime-aliases.manifest.json +75 -0
  199. package/get-shit-done/bin/verify-reapply-patches.cjs +352 -0
  200. package/get-shit-done/contexts/dev.md +21 -0
  201. package/get-shit-done/contexts/research.md +22 -0
  202. package/get-shit-done/contexts/review.md +23 -0
  203. package/get-shit-done/references/agent-contracts.md +79 -0
  204. package/get-shit-done/references/ai-evals.md +156 -0
  205. package/get-shit-done/references/ai-frameworks.md +186 -0
  206. package/get-shit-done/references/artifact-types.md +131 -0
  207. package/get-shit-done/references/autonomous-smart-discuss.md +277 -0
  208. package/get-shit-done/references/checkpoints.md +814 -0
  209. package/get-shit-done/references/common-bug-patterns.md +114 -0
  210. package/get-shit-done/references/context-budget.md +85 -0
  211. package/get-shit-done/references/continuation-format.md +253 -0
  212. package/get-shit-done/references/debugger-philosophy.md +76 -0
  213. package/get-shit-done/references/decimal-phase-calculation.md +64 -0
  214. package/get-shit-done/references/doc-conflict-engine.md +91 -0
  215. package/get-shit-done/references/domain-probes.md +125 -0
  216. package/get-shit-done/references/execute-mvp-tdd.md +81 -0
  217. package/get-shit-done/references/executor-examples.md +110 -0
  218. package/get-shit-done/references/few-shot-examples/plan-checker.md +73 -0
  219. package/get-shit-done/references/few-shot-examples/verifier.md +109 -0
  220. package/get-shit-done/references/gate-prompts.md +100 -0
  221. package/get-shit-done/references/gates.md +70 -0
  222. package/get-shit-done/references/git-integration.md +298 -0
  223. package/get-shit-done/references/git-planning-commit.md +40 -0
  224. package/get-shit-done/references/ios-scaffold.md +123 -0
  225. package/get-shit-done/references/mandatory-initial-read.md +2 -0
  226. package/get-shit-done/references/model-profile-resolution.md +38 -0
  227. package/get-shit-done/references/model-profiles.md +245 -0
  228. package/get-shit-done/references/mvp-concepts.md +49 -0
  229. package/get-shit-done/references/phase-argument-parsing.md +61 -0
  230. package/get-shit-done/references/planner-antipatterns.md +89 -0
  231. package/get-shit-done/references/planner-chunked.md +49 -0
  232. package/get-shit-done/references/planner-gap-closure.md +62 -0
  233. package/get-shit-done/references/planner-graphify-auto-update.md +67 -0
  234. package/get-shit-done/references/planner-human-verify-mode.md +57 -0
  235. package/get-shit-done/references/planner-interface-context.md +62 -0
  236. package/get-shit-done/references/planner-mvp-mode.md +53 -0
  237. package/get-shit-done/references/planner-reviews.md +39 -0
  238. package/get-shit-done/references/planner-revision.md +87 -0
  239. package/get-shit-done/references/planner-source-audit.md +73 -0
  240. package/get-shit-done/references/planning-config.md +471 -0
  241. package/get-shit-done/references/project-skills-discovery.md +19 -0
  242. package/get-shit-done/references/questioning.md +162 -0
  243. package/get-shit-done/references/revision-loop.md +97 -0
  244. package/get-shit-done/references/scout-codebase.md +51 -0
  245. package/get-shit-done/references/skeleton-template.md +48 -0
  246. package/get-shit-done/references/sketch-interactivity.md +41 -0
  247. package/get-shit-done/references/sketch-theme-system.md +94 -0
  248. package/get-shit-done/references/sketch-tooling.md +45 -0
  249. package/get-shit-done/references/sketch-variant-patterns.md +81 -0
  250. package/get-shit-done/references/spidr-splitting.md +69 -0
  251. package/get-shit-done/references/tdd.md +330 -0
  252. package/get-shit-done/references/thinking-models-debug.md +44 -0
  253. package/get-shit-done/references/thinking-models-execution.md +50 -0
  254. package/get-shit-done/references/thinking-models-planning.md +62 -0
  255. package/get-shit-done/references/thinking-models-research.md +50 -0
  256. package/get-shit-done/references/thinking-models-verification.md +55 -0
  257. package/get-shit-done/references/thinking-partner.md +96 -0
  258. package/get-shit-done/references/ui-brand.md +160 -0
  259. package/get-shit-done/references/universal-anti-patterns.md +63 -0
  260. package/get-shit-done/references/user-profiling.md +681 -0
  261. package/get-shit-done/references/user-story-template.md +58 -0
  262. package/get-shit-done/references/verification-overrides.md +227 -0
  263. package/get-shit-done/references/verification-patterns.md +612 -0
  264. package/get-shit-done/references/verify-mvp-mode.md +85 -0
  265. package/get-shit-done/references/workstream-flag.md +111 -0
  266. package/get-shit-done/references/worktree-path-safety.md +89 -0
  267. package/get-shit-done/templates/AI-SPEC.md +246 -0
  268. package/get-shit-done/templates/DEBUG.md +169 -0
  269. package/get-shit-done/templates/README.md +77 -0
  270. package/get-shit-done/templates/SECURITY.md +61 -0
  271. package/get-shit-done/templates/UAT.md +265 -0
  272. package/get-shit-done/templates/UI-SPEC.md +100 -0
  273. package/get-shit-done/templates/VALIDATION.md +76 -0
  274. package/get-shit-done/templates/claude-md.md +145 -0
  275. package/get-shit-done/templates/codebase/architecture.md +255 -0
  276. package/get-shit-done/templates/codebase/concerns.md +310 -0
  277. package/get-shit-done/templates/codebase/conventions.md +307 -0
  278. package/get-shit-done/templates/codebase/integrations.md +280 -0
  279. package/get-shit-done/templates/codebase/stack.md +186 -0
  280. package/get-shit-done/templates/codebase/structure.md +285 -0
  281. package/get-shit-done/templates/codebase/testing.md +480 -0
  282. package/get-shit-done/templates/config.json +62 -0
  283. package/get-shit-done/templates/context.md +352 -0
  284. package/get-shit-done/templates/continue-here.md +78 -0
  285. package/get-shit-done/templates/copilot-instructions.md +7 -0
  286. package/get-shit-done/templates/debug-subagent-prompt.md +91 -0
  287. package/get-shit-done/templates/dev-preferences.md +21 -0
  288. package/get-shit-done/templates/discovery.md +146 -0
  289. package/get-shit-done/templates/discussion-log.md +63 -0
  290. package/get-shit-done/templates/milestone-archive.md +123 -0
  291. package/get-shit-done/templates/milestone.md +115 -0
  292. package/get-shit-done/templates/phase-prompt.md +610 -0
  293. package/get-shit-done/templates/planner-subagent-prompt.md +117 -0
  294. package/get-shit-done/templates/project.md +186 -0
  295. package/get-shit-done/templates/requirements.md +231 -0
  296. package/get-shit-done/templates/research-project/ARCHITECTURE.md +204 -0
  297. package/get-shit-done/templates/research-project/FEATURES.md +147 -0
  298. package/get-shit-done/templates/research-project/PITFALLS.md +200 -0
  299. package/get-shit-done/templates/research-project/STACK.md +120 -0
  300. package/get-shit-done/templates/research-project/SUMMARY.md +170 -0
  301. package/get-shit-done/templates/research.md +592 -0
  302. package/get-shit-done/templates/retrospective.md +54 -0
  303. package/get-shit-done/templates/roadmap.md +202 -0
  304. package/get-shit-done/templates/spec.md +307 -0
  305. package/get-shit-done/templates/state.md +195 -0
  306. package/get-shit-done/templates/summary-complex.md +59 -0
  307. package/get-shit-done/templates/summary-minimal.md +41 -0
  308. package/get-shit-done/templates/summary-standard.md +48 -0
  309. package/get-shit-done/templates/summary.md +248 -0
  310. package/get-shit-done/templates/user-profile.md +146 -0
  311. package/get-shit-done/templates/user-setup.md +311 -0
  312. package/get-shit-done/templates/verification-report.md +322 -0
  313. package/get-shit-done/workflows/_runtime-launcher.snippet.sh +1 -0
  314. package/get-shit-done/workflows/add-backlog.md +91 -0
  315. package/get-shit-done/workflows/add-phase.md +113 -0
  316. package/get-shit-done/workflows/add-tests.md +355 -0
  317. package/get-shit-done/workflows/add-todo.md +161 -0
  318. package/get-shit-done/workflows/ai-integration-phase.md +295 -0
  319. package/get-shit-done/workflows/analyze-dependencies.md +96 -0
  320. package/get-shit-done/workflows/audit-fix.md +178 -0
  321. package/get-shit-done/workflows/audit-milestone.md +358 -0
  322. package/get-shit-done/workflows/audit-uat.md +110 -0
  323. package/get-shit-done/workflows/autonomous.md +795 -0
  324. package/get-shit-done/workflows/check-todos.md +180 -0
  325. package/get-shit-done/workflows/cleanup.md +155 -0
  326. package/get-shit-done/workflows/code-review-fix.md +502 -0
  327. package/get-shit-done/workflows/code-review.md +656 -0
  328. package/get-shit-done/workflows/complete-milestone.md +855 -0
  329. package/get-shit-done/workflows/debug.md +232 -0
  330. package/get-shit-done/workflows/diagnose-issues.md +241 -0
  331. package/get-shit-done/workflows/discovery-phase.md +291 -0
  332. package/get-shit-done/workflows/discuss-phase/modes/advisor.md +176 -0
  333. package/get-shit-done/workflows/discuss-phase/modes/all.md +28 -0
  334. package/get-shit-done/workflows/discuss-phase/modes/analyze.md +44 -0
  335. package/get-shit-done/workflows/discuss-phase/modes/auto.md +57 -0
  336. package/get-shit-done/workflows/discuss-phase/modes/batch.md +52 -0
  337. package/get-shit-done/workflows/discuss-phase/modes/chain.md +98 -0
  338. package/get-shit-done/workflows/discuss-phase/modes/default.md +141 -0
  339. package/get-shit-done/workflows/discuss-phase/modes/power.md +44 -0
  340. package/get-shit-done/workflows/discuss-phase/modes/text.md +55 -0
  341. package/get-shit-done/workflows/discuss-phase/templates/checkpoint.json +18 -0
  342. package/get-shit-done/workflows/discuss-phase/templates/context.md +136 -0
  343. package/get-shit-done/workflows/discuss-phase/templates/discussion-log.md +50 -0
  344. package/get-shit-done/workflows/discuss-phase-assumptions.md +675 -0
  345. package/get-shit-done/workflows/discuss-phase-power.md +291 -0
  346. package/get-shit-done/workflows/discuss-phase.md +499 -0
  347. package/get-shit-done/workflows/do.md +111 -0
  348. package/get-shit-done/workflows/docs-update.md +1162 -0
  349. package/get-shit-done/workflows/edit-phase.md +295 -0
  350. package/get-shit-done/workflows/eval-review.md +156 -0
  351. package/get-shit-done/workflows/execute-phase/steps/codebase-drift-gate.md +82 -0
  352. package/get-shit-done/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
  353. package/get-shit-done/workflows/execute-phase/steps/post-merge-gate.md +117 -0
  354. package/get-shit-done/workflows/execute-phase.md +1709 -0
  355. package/get-shit-done/workflows/execute-plan.md +526 -0
  356. package/get-shit-done/workflows/explore.md +144 -0
  357. package/get-shit-done/workflows/extract-learnings.md +243 -0
  358. package/get-shit-done/workflows/fast.md +124 -0
  359. package/get-shit-done/workflows/forensics.md +279 -0
  360. package/get-shit-done/workflows/graduation.md +196 -0
  361. package/get-shit-done/workflows/health.md +224 -0
  362. package/get-shit-done/workflows/help/modes/brief.md +22 -0
  363. package/get-shit-done/workflows/help/modes/default.md +50 -0
  364. package/get-shit-done/workflows/help/modes/full.md +784 -0
  365. package/get-shit-done/workflows/help/modes/topic.md +74 -0
  366. package/get-shit-done/workflows/help.md +24 -0
  367. package/get-shit-done/workflows/import.md +254 -0
  368. package/get-shit-done/workflows/inbox.md +387 -0
  369. package/get-shit-done/workflows/ingest-docs.md +339 -0
  370. package/get-shit-done/workflows/insert-phase.md +152 -0
  371. package/get-shit-done/workflows/list-phase-assumptions.md +178 -0
  372. package/get-shit-done/workflows/list-workspaces.md +57 -0
  373. package/get-shit-done/workflows/manager.md +393 -0
  374. package/get-shit-done/workflows/map-codebase.md +444 -0
  375. package/get-shit-done/workflows/milestone-summary.md +224 -0
  376. package/get-shit-done/workflows/mvp-phase.md +222 -0
  377. package/get-shit-done/workflows/new-milestone.md +635 -0
  378. package/get-shit-done/workflows/new-project.md +1555 -0
  379. package/get-shit-done/workflows/new-workspace.md +240 -0
  380. package/get-shit-done/workflows/next.md +299 -0
  381. package/get-shit-done/workflows/node-repair.md +92 -0
  382. package/get-shit-done/workflows/note.md +158 -0
  383. package/get-shit-done/workflows/pause-work.md +244 -0
  384. package/get-shit-done/workflows/plan-milestone-gaps.md +281 -0
  385. package/get-shit-done/workflows/plan-phase.md +1809 -0
  386. package/get-shit-done/workflows/plan-review-convergence.md +346 -0
  387. package/get-shit-done/workflows/plant-seed.md +230 -0
  388. package/get-shit-done/workflows/pr-branch.md +157 -0
  389. package/get-shit-done/workflows/profile-user.md +453 -0
  390. package/get-shit-done/workflows/progress.md +699 -0
  391. package/get-shit-done/workflows/quick.md +1039 -0
  392. package/get-shit-done/workflows/reapply-patches.md +426 -0
  393. package/get-shit-done/workflows/remove-phase.md +156 -0
  394. package/get-shit-done/workflows/remove-workspace.md +108 -0
  395. package/get-shit-done/workflows/resume-project.md +332 -0
  396. package/get-shit-done/workflows/review.md +623 -0
  397. package/get-shit-done/workflows/scan.md +105 -0
  398. package/get-shit-done/workflows/secure-phase.md +180 -0
  399. package/get-shit-done/workflows/session-report.md +146 -0
  400. package/get-shit-done/workflows/settings-advanced.md +620 -0
  401. package/get-shit-done/workflows/settings-integrations.md +312 -0
  402. package/get-shit-done/workflows/settings.md +552 -0
  403. package/get-shit-done/workflows/ship.md +356 -0
  404. package/get-shit-done/workflows/sketch-wrap-up.md +286 -0
  405. package/get-shit-done/workflows/sketch.md +361 -0
  406. package/get-shit-done/workflows/spec-phase.md +262 -0
  407. package/get-shit-done/workflows/spike-wrap-up.md +307 -0
  408. package/get-shit-done/workflows/spike.md +453 -0
  409. package/get-shit-done/workflows/stats.md +80 -0
  410. package/get-shit-done/workflows/sync-skills.md +182 -0
  411. package/get-shit-done/workflows/thread.md +222 -0
  412. package/get-shit-done/workflows/transition.md +694 -0
  413. package/get-shit-done/workflows/ui-phase.md +328 -0
  414. package/get-shit-done/workflows/ui-review.md +193 -0
  415. package/get-shit-done/workflows/ultraplan-phase.md +199 -0
  416. package/get-shit-done/workflows/undo.md +314 -0
  417. package/get-shit-done/workflows/update.md +443 -0
  418. package/get-shit-done/workflows/validate-phase.md +179 -0
  419. package/get-shit-done/workflows/verify-phase.md +544 -0
  420. package/get-shit-done/workflows/verify-work.md +781 -0
  421. package/hooks/dist/gsd-check-update-worker.js +95 -0
  422. package/hooks/dist/gsd-check-update.js +64 -0
  423. package/hooks/dist/gsd-context-monitor.js +195 -0
  424. package/hooks/dist/gsd-graphify-update.sh +158 -0
  425. package/hooks/dist/gsd-phase-boundary.sh +47 -0
  426. package/hooks/dist/gsd-prompt-guard.js +97 -0
  427. package/hooks/dist/gsd-read-guard.js +101 -0
  428. package/hooks/dist/gsd-read-injection-scanner.js +203 -0
  429. package/hooks/dist/gsd-session-state.sh +59 -0
  430. package/hooks/dist/gsd-statusline.js +548 -0
  431. package/hooks/dist/gsd-update-banner.js +134 -0
  432. package/hooks/dist/gsd-validate-commit.sh +57 -0
  433. package/hooks/dist/gsd-workflow-guard.js +166 -0
  434. package/hooks/dist/lib/git-cmd.js +150 -0
  435. package/hooks/dist/lib/gsd-graphify-rebuild.sh +65 -0
  436. package/hooks/gsd-check-update-worker.js +95 -0
  437. package/hooks/gsd-check-update.js +64 -0
  438. package/hooks/gsd-context-monitor.js +195 -0
  439. package/hooks/gsd-graphify-update.sh +158 -0
  440. package/hooks/gsd-phase-boundary.sh +47 -0
  441. package/hooks/gsd-prompt-guard.js +97 -0
  442. package/hooks/gsd-read-guard.js +101 -0
  443. package/hooks/gsd-read-injection-scanner.js +203 -0
  444. package/hooks/gsd-session-state.sh +59 -0
  445. package/hooks/gsd-statusline.js +548 -0
  446. package/hooks/gsd-update-banner.js +134 -0
  447. package/hooks/gsd-validate-commit.sh +57 -0
  448. package/hooks/gsd-workflow-guard.js +166 -0
  449. package/hooks/lib/git-cmd.js +150 -0
  450. package/hooks/lib/gsd-graphify-rebuild.sh +65 -0
  451. package/hooks/managed-hooks-registry.cjs +34 -0
  452. package/package.json +102 -0
  453. package/scripts/affected-tests-lib.cjs +541 -0
  454. package/scripts/audit-workflow-script-paths.cjs +73 -0
  455. package/scripts/base64-scan.sh +339 -0
  456. package/scripts/build-hooks.js +236 -0
  457. package/scripts/changeset/README.md +129 -0
  458. package/scripts/changeset/cli.cjs +392 -0
  459. package/scripts/changeset/github-release-notes.cjs +199 -0
  460. package/scripts/changeset/lint.cjs +110 -0
  461. package/scripts/changeset/new.cjs +137 -0
  462. package/scripts/changeset/parse.cjs +114 -0
  463. package/scripts/changeset/render.cjs +34 -0
  464. package/scripts/changeset/serialize.cjs +130 -0
  465. package/scripts/check-alias-drift.cjs +108 -0
  466. package/scripts/check-env.cjs +302 -0
  467. package/scripts/check-npm-integrity.cjs +209 -0
  468. package/scripts/ci-guard-runner.cjs +16 -0
  469. package/scripts/ci-prepare-test-scope.cjs +46 -0
  470. package/scripts/ci-rebase-check.cjs +85 -0
  471. package/scripts/ci-test-scope.cjs +302 -0
  472. package/scripts/command-contract-helpers.cjs +64 -0
  473. package/scripts/diff-touches-shipped-paths.cjs +147 -0
  474. package/scripts/fix-slash-commands.cjs +147 -0
  475. package/scripts/gen-inventory-manifest.cjs +109 -0
  476. package/scripts/generate-package-identity.cjs +104 -0
  477. package/scripts/lint-command-contract.cjs +108 -0
  478. package/scripts/lint-descriptions.cjs +83 -0
  479. package/scripts/lint-docs-required.cjs +222 -0
  480. package/scripts/lint-no-source-grep-extras.cjs +81 -0
  481. package/scripts/lint-no-source-grep.cjs +174 -0
  482. package/scripts/lint-package-identity-drift.cjs +141 -0
  483. package/scripts/lint-pr-check-project-dir.cjs +98 -0
  484. package/scripts/lint-shared-module-handsync.cjs +388 -0
  485. package/scripts/lint-shell-command-projection-drift.cjs +57 -0
  486. package/scripts/lint-skill-deps.cjs +180 -0
  487. package/scripts/lint-test-file-count.allowlist.json +36 -0
  488. package/scripts/lint-test-file-count.cjs +190 -0
  489. package/scripts/pr-template-policy.cjs +268 -0
  490. package/scripts/prompt-injection-scan.sh +203 -0
  491. package/scripts/release-tarball-smoke.cjs +627 -0
  492. package/scripts/run-affected-tests.cjs +6 -0
  493. package/scripts/run-cross-platform-tests.cjs +63 -0
  494. package/scripts/run-tests.cjs +282 -0
  495. package/scripts/secret-scan-lint.sh +231 -0
  496. package/scripts/secret-scan.sh +358 -0
  497. package/scripts/setup-branch-protection.sh +236 -0
  498. package/scripts/shared-module-handsync-allowlist.json +183 -0
  499. package/scripts/strip-prose-atrefs.cjs +106 -0
  500. package/scripts/sync-rulesets.sh +34 -0
  501. package/scripts/sync-runtime-launcher.cjs +402 -0
  502. package/scripts/test-failure-reasons.cjs +34 -0
  503. package/scripts/workflow-policy.cjs +450 -0
@@ -0,0 +1,117 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+
5
+ function requireNonEmptyString(record, field, source) {
6
+ if (typeof record[field] !== 'string' || record[field].trim() === '') {
7
+ throw new Error(`migration record must include a non-empty ${field}: ${source}`);
8
+ }
9
+ }
10
+
11
+ function validateStringArray(record, field, source) {
12
+ if (record[field] === undefined) return;
13
+ if (
14
+ !Array.isArray(record[field]) ||
15
+ record[field].length === 0 ||
16
+ record[field].some((value) => typeof value !== 'string' || value.trim() === '')
17
+ ) {
18
+ throw new Error(`migration record ${field} must be a non-empty string array when provided: ${source}`);
19
+ }
20
+ }
21
+
22
+ function requireStringArray(record, field, source) {
23
+ if (
24
+ !Array.isArray(record[field]) ||
25
+ record[field].length === 0 ||
26
+ record[field].some((value) => typeof value !== 'string' || value.trim() === '')
27
+ ) {
28
+ throw new Error(`migration record ${field} must be a non-empty string array: ${source}`);
29
+ }
30
+ }
31
+
32
+ function recordSource(record, fallback) {
33
+ return fallback || (record && typeof record.id === 'string' && record.id.trim() ? record.id : '<unknown>');
34
+ }
35
+
36
+ function validateInstallerMigrationRecord(record, source) {
37
+ const displaySource = recordSource(record, source);
38
+ if (!record || typeof record !== 'object') {
39
+ throw new Error(`migration record must export an object: ${displaySource}`);
40
+ }
41
+
42
+ // Authoring contract follows docs/installer-migrations.md#authoring-workflow
43
+ // and docs/adr/0008-installer-migration-module.md#decision.
44
+ requireNonEmptyString(record, 'id', displaySource);
45
+ requireNonEmptyString(record, 'title', displaySource);
46
+ requireNonEmptyString(record, 'description', displaySource);
47
+ requireNonEmptyString(record, 'introducedIn', displaySource);
48
+ if (typeof record.destructive !== 'boolean') {
49
+ throw new Error(`migration record must declare destructive as a boolean: ${displaySource}`);
50
+ }
51
+ validateStringArray(record, 'runtimes', displaySource);
52
+ requireStringArray(record, 'scopes', displaySource);
53
+ if (typeof record.plan !== 'function') {
54
+ throw new Error(`migration record must include a plan function: ${displaySource}`);
55
+ }
56
+
57
+ return record;
58
+ }
59
+
60
+ function actionSource(migration, action) {
61
+ const migrationId = migration && typeof migration.id === 'string' ? migration.id : '<unknown>';
62
+ const relPath = action && typeof action.relPath === 'string' ? action.relPath : '<unknown>';
63
+ return `${migrationId} ${relPath}`;
64
+ }
65
+
66
+ function requireActionEvidence(action, field, migration) {
67
+ if (typeof action[field] !== 'string' || action[field].trim() === '') {
68
+ throw new Error(`migration action ${action.type} must include ${field}: ${actionSource(migration, action)}`);
69
+ }
70
+ }
71
+
72
+ function validateSafeRelPath(relPath, migration, actionType) {
73
+ const source = actionSource(migration, { relPath });
74
+ const normalized = relPath.replace(/\\/g, '/');
75
+ if (path.isAbsolute(normalized) || path.win32.isAbsolute(normalized)) {
76
+ throw new Error(`migration action ${actionType} relPath must stay inside configDir: ${source}`);
77
+ }
78
+ const segments = normalized.split('/');
79
+ if (segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
80
+ throw new Error(`migration action ${actionType} relPath must stay inside configDir: ${source}`);
81
+ }
82
+ }
83
+
84
+ function validateInstallerMigrationActions(actions, migration) {
85
+ if (!Array.isArray(actions)) {
86
+ throw new Error(`migration ${migration.id} plan must return an array`);
87
+ }
88
+
89
+ for (const action of actions) {
90
+ if (!action || typeof action !== 'object') {
91
+ throw new Error(`migration action must be an object: ${migration.id}`);
92
+ }
93
+ if (typeof action.type !== 'string' || action.type.trim() === '') {
94
+ throw new Error(`migration action must include a non-empty type: ${migration.id}`);
95
+ }
96
+ if (typeof action.relPath !== 'string' || action.relPath.trim() === '') {
97
+ throw new Error(`migration action ${action.type} must include a non-empty relPath: ${migration.id}`);
98
+ }
99
+ validateSafeRelPath(action.relPath, migration, action.type);
100
+ // Ownership and runtime-contract evidence are required by
101
+ // docs/installer-migrations.md#action-types and
102
+ // docs/adr/0008-installer-migration-module.md#runtime-contract-decision.
103
+ if (action.type === 'remove-managed' || action.type === 'rewrite-json') {
104
+ requireActionEvidence(action, 'ownershipEvidence', migration);
105
+ }
106
+ if (action.type === 'rewrite-json' && (typeof migration.runtimeContract !== 'string' || migration.runtimeContract.trim() === '')) {
107
+ throw new Error(`migration action rewrite-json requires migration runtimeContract: ${actionSource(migration, action)}`);
108
+ }
109
+ }
110
+
111
+ return actions;
112
+ }
113
+
114
+ module.exports = {
115
+ validateInstallerMigrationActions,
116
+ validateInstallerMigrationRecord,
117
+ };
@@ -0,0 +1,354 @@
1
+ 'use strict';
2
+
3
+ // Resolution environment variable surface for #3541 — when the installer
4
+ // runs without a TTY (typical /gsd:update path via Claude Code or any
5
+ // scripted update), prompt-user migration actions cannot be answered
6
+ // interactively. We resolve them by classification:
7
+ // - Stale SDK build artifacts (get-shit-done/sdk/{dist,src}/gsd-*):
8
+ // default `remove`. Fresh install supplies replacements.
9
+ // - User-facing skill anchors (skills/gsd-*/SKILL.md): default `keep`.
10
+ // User-owned content is preserved.
11
+ // Anything else: fall through to the hard assertion with an improved,
12
+ // grouped, actionable error message.
13
+ //
14
+ // docs/installer-migrations.md#prompt-user-resolution for the spec.
15
+ const RESOLUTION_ENV_VAR = 'GSD_INSTALLER_MIGRATION_RESOLVE';
16
+ const VALID_CHOICES = ['keep', 'remove'];
17
+
18
+ function installerMigrationActionLabel(action) {
19
+ if (!action || !action.type) return 'skipped';
20
+ if (action.type === 'backup-and-remove') return 'backed up and removed';
21
+ if (action.type === 'remove-managed') return 'removed';
22
+ if (action.type === 'rewrite-json') return action.deleteIfEmpty ? 'rewrote or removed' : 'rewrote';
23
+ if (action.type === 'record-baseline') return 'recorded';
24
+ if (action.type === 'baseline-preserve-user') return 'preserved';
25
+ if (action.type === 'preserve-user') return 'preserved';
26
+ if (action.type === 'prompt-user') return 'blocked';
27
+ return 'skipped';
28
+ }
29
+
30
+ function blockedInstallerMigrationActions(result) {
31
+ if (result && Array.isArray(result.blocked)) return result.blocked;
32
+ const plan = result && result.plan;
33
+ if (plan && Array.isArray(plan.blocked)) return plan.blocked;
34
+ return [];
35
+ }
36
+
37
+ function baselineSummaryLabel(count, noun) {
38
+ return `${count} ${noun}${count === 1 ? '' : 's'}`;
39
+ }
40
+
41
+ function baselineSummaryRow(type, actions) {
42
+ const count = actions.length;
43
+ if (type === 'record-baseline') {
44
+ return {
45
+ label: 'recorded',
46
+ relPath: baselineSummaryLabel(count, 'managed baseline file'),
47
+ reason: 'first-time baseline scan',
48
+ action: { type: 'record-baseline-summary', count, actions },
49
+ };
50
+ }
51
+ return {
52
+ label: 'preserved',
53
+ relPath: baselineSummaryLabel(count, 'user baseline file'),
54
+ reason: 'first-time baseline scan',
55
+ action: { type: 'baseline-preserve-user-summary', count, actions },
56
+ };
57
+ }
58
+
59
+ function summarizeInstallerMigrationResult(result) {
60
+ const plan = result && result.plan;
61
+ const actions = plan && Array.isArray(plan.actions) ? plan.actions : [];
62
+ const blocked = blockedInstallerMigrationActions(result);
63
+ const blockedSet = new Set(blocked);
64
+ const rows = [];
65
+ const baselineIndexes = new Map();
66
+ const baselineActions = new Map();
67
+
68
+ for (const action of actions) {
69
+ const type = action && action.type;
70
+ if (type === 'record-baseline' || type === 'baseline-preserve-user') {
71
+ if (!baselineActions.has(type)) {
72
+ baselineActions.set(type, []);
73
+ baselineIndexes.set(type, rows.length);
74
+ rows.push(null);
75
+ }
76
+ baselineActions.get(type).push(action);
77
+ continue;
78
+ }
79
+
80
+ rows.push({
81
+ label: blockedSet.has(action) ? 'blocked' : installerMigrationActionLabel(action),
82
+ relPath: action.relPath,
83
+ reason: action.reason || '',
84
+ action,
85
+ });
86
+ }
87
+
88
+ // Phase 4 requires action reporting without flooding first-time baseline installs:
89
+ // docs/installer-migrations.md#phase-4-installupdate-integration.
90
+ for (const [type, baselineRows] of baselineActions) {
91
+ rows[baselineIndexes.get(type)] = baselineSummaryRow(type, baselineRows);
92
+ }
93
+
94
+ return {
95
+ hasReportableActions: actions.length > 0 || blocked.length > 0,
96
+ blocked,
97
+ rows,
98
+ };
99
+ }
100
+
101
+ // #3628: explicit whitelist of bundled hook files shipped in the npm
102
+ // distribution under `hooks/`. The classifier-based auto-removal of these
103
+ // files at first-time-baseline scan (added in #3610) is restricted to this
104
+ // set — a shape regex like `^hooks/gsd-[^/]+\.(?:js|sh|cjs|mjs)$` also
105
+ // matches user-authored custom hooks and retired bundled hooks from prior
106
+ // versions, and auto-removing those is silent data loss.
107
+ //
108
+ // The bug-3628 regression guard asserts this Set stays aligned with the
109
+ // on-disk `hooks/` directory in both directions: whitelist-but-missing
110
+ // AND shipped-but-not-whitelisted both fail CI.
111
+ const BUNDLED_GSD_HOOK_FILES = Object.freeze(new Set([
112
+ 'hooks/gsd-check-update-worker.js',
113
+ 'hooks/gsd-check-update.js',
114
+ 'hooks/gsd-context-monitor.js',
115
+ 'hooks/gsd-graphify-update.sh',
116
+ 'hooks/gsd-phase-boundary.sh',
117
+ 'hooks/gsd-prompt-guard.js',
118
+ 'hooks/gsd-read-guard.js',
119
+ 'hooks/gsd-read-injection-scanner.js',
120
+ 'hooks/gsd-session-state.sh',
121
+ 'hooks/gsd-statusline.js',
122
+ 'hooks/gsd-update-banner.js',
123
+ 'hooks/gsd-validate-commit.sh',
124
+ 'hooks/gsd-workflow-guard.js',
125
+ ]));
126
+
127
+ // Classify a blocked prompt-user action into one of the safe-default
128
+ // categories. Returns null when no safe default applies — caller must
129
+ // fall back to the hard assertion / interactive prompt for those.
130
+ //
131
+ // Stale SDK build artifacts live under get-shit-done/sdk/{dist,src}/
132
+ // and are regenerated on every install, so removing them is lossless.
133
+ // User-facing skill anchors are the .md files that surface as commands
134
+ // to the user — these are user-owned and must be kept.
135
+ function classifyPromptUserAction(action) {
136
+ const relPath = action && action.relPath;
137
+ if (typeof relPath !== 'string' || !relPath) return null;
138
+ if (/^get-shit-done\/sdk\/(dist|src)\//.test(relPath)) {
139
+ return { category: 'stale-sdk-build-artifact', choice: 'remove' };
140
+ }
141
+ if (/^skills\/gsd-[^/]+\/SKILL\.md$/.test(relPath)) {
142
+ return { category: 'user-facing-skill', choice: 'keep' };
143
+ }
144
+ // #3610 / #3628: bundled GSD hooks shipped under `hooks/`. The whitelist
145
+ // is the explicit set of filenames in the npm distribution — files that
146
+ // match the shape but are NOT in the whitelist (user-authored hooks,
147
+ // retired hooks from prior versions) fall through to the block-or-prompt
148
+ // flow so the user retains control. On a first-time-baseline scan the
149
+ // installer can safely remove whitelisted hooks because it is about to
150
+ // write the fresh bundled versions in their place.
151
+ if (BUNDLED_GSD_HOOK_FILES.has(relPath)) {
152
+ return { category: 'bundled-gsd-hook', choice: 'remove' };
153
+ }
154
+ return null;
155
+ }
156
+
157
+ // Convert a blocked prompt-user action into a concrete plan action.
158
+ // `keep` → baseline-preserve-user (idempotent — already on disk).
159
+ // `remove` → backup-and-remove (safe: keeps a rollback copy in the
160
+ // migration journal under gsd-migration-journal/<runId>-backups/).
161
+ function materializeResolution(action, choice) {
162
+ const base = {
163
+ migrationId: action.migrationId,
164
+ migrationChecksum: action.migrationChecksum,
165
+ relPath: action.relPath,
166
+ reason: action.reason,
167
+ classification: action.classification,
168
+ originalHash: action.originalHash || null,
169
+ currentHash: action.currentHash || null,
170
+ requestedType: 'prompt-user',
171
+ };
172
+ if (choice === 'keep') {
173
+ return { ...base, type: 'baseline-preserve-user' };
174
+ }
175
+ // 'remove'
176
+ return { ...base, type: 'backup-and-remove', backupRelPath: null };
177
+ }
178
+
179
+ function normalizeResolutionChoice(rawValue) {
180
+ if (typeof rawValue !== 'string') return null;
181
+ const normalized = rawValue.trim().toLowerCase();
182
+ return VALID_CHOICES.includes(normalized) ? normalized : null;
183
+ }
184
+
185
+ function actionSupportsChoice(action, choice) {
186
+ if (!action || !choice) return false;
187
+ if (!Array.isArray(action.choices) || action.choices.length === 0) {
188
+ return VALID_CHOICES.includes(choice);
189
+ }
190
+ return action.choices.includes(choice);
191
+ }
192
+
193
+ // Resolve prompt-user actions when stdin is not a TTY. Mutates the
194
+ // passed result so:
195
+ // - resolved actions are appended to plan.actions in their concrete
196
+ // form (baseline-preserve-user / backup-and-remove);
197
+ // - result.blocked and plan.blocked are filtered to actions that
198
+ // could NOT be safely defaulted (caller must still handle those).
199
+ // Returns { result, resolutions } where `resolutions` is the structured
200
+ // log of every defaulted resolution.
201
+ function resolveInstallerMigrationPromptsForNonTty(result, options = {}) {
202
+ if (!result || typeof result !== 'object') {
203
+ return { result, resolutions: [] };
204
+ }
205
+ const blocked = blockedInstallerMigrationActions(result);
206
+ if (blocked.length === 0) {
207
+ return { result, resolutions: [] };
208
+ }
209
+ const isTty = options.isTty === true;
210
+ if (isTty) {
211
+ // Honour interactive prompting paths (not implemented yet — the
212
+ // hard throw is still the right behaviour for TTY runs); resolver
213
+ // only fires when the installer cannot interactively ask.
214
+ return { result, resolutions: [] };
215
+ }
216
+
217
+ const env =
218
+ options && options.env && typeof options.env === 'object'
219
+ ? options.env
220
+ : process.env;
221
+ const envChoice = normalizeResolutionChoice(env && env[RESOLUTION_ENV_VAR]);
222
+ const resolutions = [];
223
+ const unresolved = [];
224
+
225
+ for (const action of blocked) {
226
+ if (action && action.type === 'prompt-user') {
227
+ let category = null;
228
+ let choice = null;
229
+ let source = null;
230
+ if (envChoice && actionSupportsChoice(action, envChoice)) {
231
+ category = 'operator-override';
232
+ choice = envChoice;
233
+ source = RESOLUTION_ENV_VAR;
234
+ } else {
235
+ const classification = classifyPromptUserAction(action);
236
+ if (classification) {
237
+ category = classification.category;
238
+ choice = classification.choice;
239
+ source = 'non-tty-default';
240
+ }
241
+ }
242
+
243
+ if (choice) {
244
+ const resolved = materializeResolution(action, choice);
245
+ // Replace the original prompt-user action in-place when present so
246
+ // applyInstallerMigrationPlan never sees an unsupported action type.
247
+ // Fallback to append only when the blocked action did not originate
248
+ // from plan.actions (defensive).
249
+ if (result.plan && Array.isArray(result.plan.actions)) {
250
+ const idx = result.plan.actions.indexOf(action);
251
+ if (idx >= 0) {
252
+ result.plan.actions[idx] = resolved;
253
+ } else {
254
+ result.plan.actions.push(resolved);
255
+ }
256
+ }
257
+ resolutions.push({
258
+ relPath: action.relPath,
259
+ category,
260
+ choice,
261
+ reason: action.reason,
262
+ resolvedActionType: resolved.type,
263
+ source,
264
+ });
265
+ continue;
266
+ }
267
+ }
268
+ unresolved.push(action);
269
+ }
270
+
271
+ // Mutate both the top-level and plan.blocked surfaces so downstream
272
+ // callers (assertInstallerMigrationsUnblocked, summarizers) see the
273
+ // post-resolution state.
274
+ if (Array.isArray(result.blocked)) {
275
+ result.blocked = unresolved;
276
+ }
277
+ if (result.plan && Array.isArray(result.plan.blocked)) {
278
+ result.plan.blocked = unresolved;
279
+ }
280
+
281
+ return { result, resolutions };
282
+ }
283
+
284
+ // Group blocked prompt-user actions by their `reason` so the operator
285
+ // sees one summary line per cause instead of N path lines for the
286
+ // same underlying issue.
287
+ function groupBlockedByReason(blocked) {
288
+ const byReason = new Map();
289
+ for (const action of blocked) {
290
+ const reason = (action && action.reason) || 'no reason given';
291
+ if (!byReason.has(reason)) byReason.set(reason, []);
292
+ byReason.get(reason).push(action);
293
+ }
294
+ return byReason;
295
+ }
296
+
297
+ function describeChoicesForActions(blocked) {
298
+ const choiceSet = new Set();
299
+ for (const action of blocked) {
300
+ if (action && Array.isArray(action.choices)) {
301
+ for (const choice of action.choices) choiceSet.add(choice);
302
+ }
303
+ }
304
+ if (choiceSet.size === 0) {
305
+ for (const fallback of VALID_CHOICES) choiceSet.add(fallback);
306
+ }
307
+ return [...choiceSet];
308
+ }
309
+
310
+ function buildBlockedErrorMessage(blocked) {
311
+ const byReason = groupBlockedByReason(blocked);
312
+ const totalFiles = blocked.length;
313
+ const choices = describeChoicesForActions(blocked);
314
+
315
+ const lines = [
316
+ `installer migration blocked pending user choice: ${totalFiles} file${totalFiles === 1 ? '' : 's'} need a decision`,
317
+ ` choices: [${choices.join(', ')}]`,
318
+ ];
319
+ for (const [reason, actions] of byReason) {
320
+ lines.push(` - ${actions.length} file${actions.length === 1 ? '' : 's'}: ${reason}`);
321
+ // Show up to 3 sample paths so operators can spot which files are
322
+ // affected without dumping a thousand-line wall when SDK build
323
+ // artifacts leak.
324
+ const sample = actions.slice(0, 3).map((a) => a.relPath);
325
+ if (sample.length > 0) {
326
+ lines.push(` e.g. ${sample.join(', ')}${actions.length > sample.length ? `, ... (+${actions.length - sample.length} more)` : ''}`);
327
+ }
328
+ }
329
+ lines.push(
330
+ ` resolve non-interactively by setting ${RESOLUTION_ENV_VAR}=<choice> ` +
331
+ `(or run the installer in a TTY to be prompted per file).`
332
+ );
333
+ return lines.join('\n');
334
+ }
335
+
336
+ function assertInstallerMigrationsUnblocked(result) {
337
+ const blocked = blockedInstallerMigrationActions(result);
338
+ if (blocked.length === 0) return;
339
+ const message = buildBlockedErrorMessage(blocked);
340
+ const error = new Error(message);
341
+ error.blocked = blocked;
342
+ error.blockedByReason = Object.fromEntries(groupBlockedByReason(blocked));
343
+ error.resolutionEnvVar = RESOLUTION_ENV_VAR;
344
+ throw error;
345
+ }
346
+
347
+ module.exports = {
348
+ RESOLUTION_ENV_VAR,
349
+ BUNDLED_GSD_HOOK_FILES,
350
+ assertInstallerMigrationsUnblocked,
351
+ classifyPromptUserAction,
352
+ resolveInstallerMigrationPromptsForNonTty,
353
+ summarizeInstallerMigrationResult,
354
+ };
@@ -0,0 +1,220 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const BASELINE_MIGRATION_ID = '2026-05-11-first-time-baseline-scan';
7
+
8
+ // Runtime install surfaces must stay aligned with:
9
+ // - docs/installer-migrations.md#runtime-configuration-contract-registry
10
+ // - docs/ARCHITECTURE.md#runtime-install-contract-matrix
11
+ //
12
+ // The registry rows are based on each runtime's upstream loader docs where
13
+ // available. Source-limited rows are intentionally conservative: scan generated
14
+ // files GSD materializes, but do not infer ownership of undocumented host config.
15
+ const RUNTIME_SURFACES = {
16
+ claude: ['get-shit-done', 'commands/gsd', 'skills', 'agents', 'hooks', 'settings.json'],
17
+ codex: ['get-shit-done', 'skills', 'agents', 'hooks', 'config.toml', 'hooks.json'],
18
+ gemini: ['get-shit-done', 'commands/gsd', 'hooks'],
19
+ opencode: ['get-shit-done', 'command', 'skills', 'agents'],
20
+ kilo: ['get-shit-done', 'command', 'skills', 'agents'],
21
+ copilot: ['get-shit-done', 'skills', 'agents'],
22
+ antigravity: ['get-shit-done', 'skills', 'agents'],
23
+ cursor: ['get-shit-done', 'skills', 'agents'],
24
+ windsurf: ['get-shit-done', 'skills', 'agents', 'rules'],
25
+ augment: ['get-shit-done', 'skills', 'agents'],
26
+ trae: ['get-shit-done', 'skills', 'agents', 'rules'],
27
+ qwen: ['get-shit-done', 'skills', 'agents'],
28
+ hermes: ['get-shit-done', 'skills/gsd', 'agents'],
29
+ cline: ['get-shit-done', 'skills', 'agents'],
30
+ codebuddy: ['get-shit-done', 'skills', 'agents'],
31
+ };
32
+
33
+ const COMMON_SURFACES = ['get-shit-done', 'skills', 'agents', 'hooks'];
34
+ const INTERNAL_TOP_LEVEL_NAMES = new Set([
35
+ 'gsd-file-manifest.json',
36
+ 'gsd-install-state.json',
37
+ 'gsd-migration-backups',
38
+ 'gsd-migration-journal',
39
+ ]);
40
+ const USER_OWNED_PATHS = new Set([
41
+ 'get-shit-done/USER-PROFILE.md',
42
+ 'commands/gsd/dev-preferences.md',
43
+ 'skills/gsd-dev-preferences/SKILL.md',
44
+ ]);
45
+ let knownGeneratedAgentNames = null;
46
+
47
+ function normalizeRelPath(relPath) {
48
+ return relPath.replace(/\\/g, '/').replace(/^\/+/, '');
49
+ }
50
+
51
+ function baselineInstallSurfaces(runtime) {
52
+ if (runtime && RUNTIME_SURFACES[runtime]) return RUNTIME_SURFACES[runtime];
53
+ return COMMON_SURFACES;
54
+ }
55
+
56
+ function walkFiles(root, relDir, files) {
57
+ const dir = path.join(root, relDir);
58
+ if (!fs.existsSync(dir)) return;
59
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
60
+ for (const entry of entries) {
61
+ const relPath = path.posix.join(relDir, entry.name);
62
+ if (relDir === '' && INTERNAL_TOP_LEVEL_NAMES.has(entry.name)) continue;
63
+ const fullPath = path.join(root, relPath);
64
+ if (entry.isDirectory()) {
65
+ walkFiles(root, relPath, files);
66
+ } else if (entry.isFile()) {
67
+ files.add(normalizeRelPath(relPath));
68
+ }
69
+ }
70
+ }
71
+
72
+ function scanBaselineFiles(configDir, runtime) {
73
+ const relPaths = new Set();
74
+ for (const surface of baselineInstallSurfaces(runtime)) {
75
+ const normalized = normalizeRelPath(surface);
76
+ const fullPath = path.join(configDir, normalized);
77
+ if (!fs.existsSync(fullPath)) continue;
78
+ const stat = fs.statSync(fullPath);
79
+ if (stat.isDirectory()) {
80
+ walkFiles(configDir, normalized, relPaths);
81
+ } else if (stat.isFile() && !INTERNAL_TOP_LEVEL_NAMES.has(normalized)) {
82
+ relPaths.add(normalized);
83
+ }
84
+ }
85
+ return [...relPaths];
86
+ }
87
+
88
+ function isUserOwnedBaselinePath(relPath) {
89
+ if (USER_OWNED_PATHS.has(relPath)) return true;
90
+ const parts = relPath.split('/');
91
+ if (parts[0] === 'skills' && parts[1] && !parts[1].startsWith('gsd-')) return true;
92
+ if (parts[0] === 'agents' && parts[1] && !parts[1].startsWith('gsd-')) return true;
93
+ return false;
94
+ }
95
+
96
+ function listKnownGeneratedAgentNames() {
97
+ if (knownGeneratedAgentNames) return knownGeneratedAgentNames;
98
+
99
+ knownGeneratedAgentNames = new Set();
100
+ const agentsDir = path.resolve(__dirname, '..', '..', '..', '..', 'agents');
101
+ try {
102
+ for (const entry of fs.readdirSync(agentsDir, { withFileTypes: true })) {
103
+ if (entry.isFile() && entry.name.startsWith('gsd-') && entry.name.endsWith('.md')) {
104
+ knownGeneratedAgentNames.add(entry.name.replace(/\.md$/, ''));
105
+ }
106
+ }
107
+ } catch {
108
+ // If the source agent directory is unavailable, fail closed and treat
109
+ // GSD-looking agent files as user-choice artifacts.
110
+ }
111
+
112
+ return knownGeneratedAgentNames;
113
+ }
114
+
115
+ function isKnownGeneratedAgentPath(relPath, runtime) {
116
+ const parts = relPath.split('/');
117
+ if (parts.length !== 2 || parts[0] !== 'agents') return false;
118
+ const fileName = parts[1];
119
+ const extension = path.posix.extname(fileName);
120
+ if (extension !== '.md' && !(runtime === 'codex' && extension === '.toml')) return false;
121
+
122
+ const agentName = fileName.slice(0, -extension.length);
123
+ return listKnownGeneratedAgentNames().has(agentName);
124
+ }
125
+
126
+ function isStaleGsdLookingPath(relPath) {
127
+ const baseName = path.posix.basename(relPath);
128
+ if (/^gsd[-_]/.test(baseName)) return true;
129
+ const parts = relPath.split('/');
130
+ if ((parts[0] === 'skills' || parts[0] === 'agents') && parts[1] && parts[1].startsWith('gsd-')) {
131
+ return true;
132
+ }
133
+ return false;
134
+ }
135
+
136
+ function baselineActionRank(action) {
137
+ if (action.type === 'record-baseline') return 0;
138
+ if (action.type === 'baseline-preserve-user') return 1;
139
+ return 2;
140
+ }
141
+
142
+ module.exports = {
143
+ id: BASELINE_MIGRATION_ID,
144
+ title: 'Record first-time installer migration baseline',
145
+ description: 'Classify existing install surfaces before destructive installer migrations run.',
146
+ introducedIn: '1.50.0',
147
+ scopes: ['global', 'local'],
148
+ destructive: false,
149
+ plan: ({ configDir, runtime, baselineScan, classifyArtifact }) => {
150
+ if (!baselineScan) return [];
151
+
152
+ const actions = [];
153
+ for (const relPath of scanBaselineFiles(configDir, runtime)) {
154
+ // docs/installer-migrations.md#baseline-preserve-user keeps user-owned
155
+ // artifacts out of destructive migration flow; classify later only when
156
+ // ownership is not already known.
157
+ if (isUserOwnedBaselinePath(relPath)) {
158
+ actions.push({
159
+ type: 'baseline-preserve-user',
160
+ relPath,
161
+ reason: 'known user-owned artifact preserved by first-time migration baseline',
162
+ classification: 'user-owned',
163
+ originalHash: null,
164
+ currentHash: null,
165
+ });
166
+ continue;
167
+ }
168
+
169
+ const artifact = classifyArtifact(relPath);
170
+ if (artifact.classification === 'managed-pristine' || artifact.classification === 'managed-modified') {
171
+ actions.push({
172
+ type: 'record-baseline',
173
+ relPath,
174
+ reason: 'existing manifest-managed file included in first-time migration baseline',
175
+ });
176
+ continue;
177
+ }
178
+
179
+ const currentHash = artifact.currentHash;
180
+ if (isKnownGeneratedAgentPath(relPath, runtime)) {
181
+ actions.push({
182
+ type: 'record-baseline',
183
+ relPath,
184
+ reason: 'known installer-generated agent included in first-time migration baseline',
185
+ classification: artifact.classification,
186
+ originalHash: artifact.originalHash,
187
+ currentHash,
188
+ });
189
+ continue;
190
+ }
191
+
192
+ if (isStaleGsdLookingPath(relPath)) {
193
+ actions.push({
194
+ type: 'prompt-user',
195
+ relPath,
196
+ reason: 'GSD-looking file is not proven manifest-managed and needs explicit user choice',
197
+ classification: 'stale-gsd-looking',
198
+ originalHash: artifact.originalHash,
199
+ currentHash,
200
+ prompt: 'Choose whether to remove this stale-looking GSD artifact or keep it as user-owned.',
201
+ choices: ['keep', 'remove'],
202
+ });
203
+ continue;
204
+ }
205
+
206
+ actions.push({
207
+ type: 'baseline-preserve-user',
208
+ relPath,
209
+ reason: 'unknown install-surface file preserved by first-time migration baseline',
210
+ classification: artifact.classification,
211
+ originalHash: artifact.originalHash,
212
+ currentHash,
213
+ });
214
+ }
215
+
216
+ return actions.sort((left, right) =>
217
+ baselineActionRank(left) - baselineActionRank(right) || left.relPath.localeCompare(right.relPath)
218
+ );
219
+ },
220
+ };