@therocketcode/gsd-core 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/.claude-plugin/plugin.json +23 -0
  2. package/GEMINI.md +53 -0
  3. package/LICENSE +21 -0
  4. package/README.ja-JP.md +125 -0
  5. package/README.ko-KR.md +125 -0
  6. package/README.md +144 -0
  7. package/README.pt-BR.md +125 -0
  8. package/README.zh-CN.md +125 -0
  9. package/agents/gsd-advisor-researcher.md +108 -0
  10. package/agents/gsd-ai-researcher.md +114 -0
  11. package/agents/gsd-assumptions-analyzer.md +105 -0
  12. package/agents/gsd-code-fixer.md +668 -0
  13. package/agents/gsd-code-reviewer.md +387 -0
  14. package/agents/gsd-codebase-mapper.md +853 -0
  15. package/agents/gsd-debug-session-manager.md +314 -0
  16. package/agents/gsd-debugger.md +1452 -0
  17. package/agents/gsd-doc-classifier.md +168 -0
  18. package/agents/gsd-doc-synthesizer.md +204 -0
  19. package/agents/gsd-doc-verifier.md +217 -0
  20. package/agents/gsd-doc-writer.md +616 -0
  21. package/agents/gsd-domain-researcher.md +147 -0
  22. package/agents/gsd-eval-auditor.md +191 -0
  23. package/agents/gsd-eval-planner.md +154 -0
  24. package/agents/gsd-executor.md +785 -0
  25. package/agents/gsd-framework-selector.md +160 -0
  26. package/agents/gsd-integration-checker.md +470 -0
  27. package/agents/gsd-intel-updater.md +342 -0
  28. package/agents/gsd-nyquist-auditor.md +203 -0
  29. package/agents/gsd-pattern-mapper.md +335 -0
  30. package/agents/gsd-phase-researcher.md +867 -0
  31. package/agents/gsd-plan-checker.md +978 -0
  32. package/agents/gsd-planner.md +1204 -0
  33. package/agents/gsd-project-researcher.md +611 -0
  34. package/agents/gsd-research-synthesizer.md +259 -0
  35. package/agents/gsd-roadmapper.md +688 -0
  36. package/agents/gsd-security-auditor.md +155 -0
  37. package/agents/gsd-ui-auditor.md +495 -0
  38. package/agents/gsd-ui-checker.md +309 -0
  39. package/agents/gsd-ui-researcher.md +374 -0
  40. package/agents/gsd-user-profiler.md +171 -0
  41. package/agents/gsd-verifier.md +923 -0
  42. package/assets/gsd-logo-2000-transparent.png +0 -0
  43. package/assets/gsd-logo-2000-transparent.svg +17 -0
  44. package/assets/gsd-logo-2000.png +0 -0
  45. package/assets/gsd-logo-2000.svg +21 -0
  46. package/assets/terminal.svg +68 -0
  47. package/bin/install.js +12726 -0
  48. package/bin/lib/ui-safety-gate.cjs +107 -0
  49. package/commands/gsd/add-tests.md +42 -0
  50. package/commands/gsd/ai-integration-phase.md +37 -0
  51. package/commands/gsd/audit-fix.md +34 -0
  52. package/commands/gsd/audit-milestone.md +37 -0
  53. package/commands/gsd/audit-uat.md +24 -0
  54. package/commands/gsd/autonomous.md +48 -0
  55. package/commands/gsd/capture.md +62 -0
  56. package/commands/gsd/cleanup.md +24 -0
  57. package/commands/gsd/code-review.md +59 -0
  58. package/commands/gsd/complete-milestone.md +143 -0
  59. package/commands/gsd/config.md +56 -0
  60. package/commands/gsd/debug.md +52 -0
  61. package/commands/gsd/discover-product.md +65 -0
  62. package/commands/gsd/discuss-phase.md +77 -0
  63. package/commands/gsd/docs-update.md +49 -0
  64. package/commands/gsd/eval-review.md +33 -0
  65. package/commands/gsd/execute-phase.md +66 -0
  66. package/commands/gsd/explore.md +27 -0
  67. package/commands/gsd/extract-learnings.md +23 -0
  68. package/commands/gsd/fast.md +31 -0
  69. package/commands/gsd/forensics.md +57 -0
  70. package/commands/gsd/graphify.md +204 -0
  71. package/commands/gsd/health.md +31 -0
  72. package/commands/gsd/help.md +28 -0
  73. package/commands/gsd/import.md +45 -0
  74. package/commands/gsd/inbox.md +39 -0
  75. package/commands/gsd/ingest-docs.md +42 -0
  76. package/commands/gsd/manager.md +45 -0
  77. package/commands/gsd/map-codebase.md +83 -0
  78. package/commands/gsd/milestone-summary.md +51 -0
  79. package/commands/gsd/model-domain.md +65 -0
  80. package/commands/gsd/mvp-phase.md +45 -0
  81. package/commands/gsd/new-milestone.md +45 -0
  82. package/commands/gsd/new-project.md +47 -0
  83. package/commands/gsd/ns-context.md +23 -0
  84. package/commands/gsd/ns-ideate.md +24 -0
  85. package/commands/gsd/ns-manage.md +29 -0
  86. package/commands/gsd/ns-project.md +22 -0
  87. package/commands/gsd/ns-review.md +26 -0
  88. package/commands/gsd/ns-workflow.md +28 -0
  89. package/commands/gsd/pause-work.md +43 -0
  90. package/commands/gsd/phase.md +56 -0
  91. package/commands/gsd/plan-phase.md +64 -0
  92. package/commands/gsd/plan-review-convergence.md +59 -0
  93. package/commands/gsd/pr-branch.md +26 -0
  94. package/commands/gsd/profile-user.md +46 -0
  95. package/commands/gsd/progress.md +48 -0
  96. package/commands/gsd/quick.md +174 -0
  97. package/commands/gsd/recommend-architecture.md +64 -0
  98. package/commands/gsd/resume-work.md +30 -0
  99. package/commands/gsd/review-backlog.md +63 -0
  100. package/commands/gsd/review.md +42 -0
  101. package/commands/gsd/secure-phase.md +36 -0
  102. package/commands/gsd/settings.md +29 -0
  103. package/commands/gsd/ship.md +24 -0
  104. package/commands/gsd/sketch.md +60 -0
  105. package/commands/gsd/spec-phase.md +63 -0
  106. package/commands/gsd/spike.md +57 -0
  107. package/commands/gsd/stats.md +20 -0
  108. package/commands/gsd/surface.md +155 -0
  109. package/commands/gsd/testing-strategy.md +65 -0
  110. package/commands/gsd/thread.md +24 -0
  111. package/commands/gsd/ui-phase.md +35 -0
  112. package/commands/gsd/ui-review.md +33 -0
  113. package/commands/gsd/ultraplan-phase.md +34 -0
  114. package/commands/gsd/undo.md +35 -0
  115. package/commands/gsd/update.md +49 -0
  116. package/commands/gsd/validate-phase.md +36 -0
  117. package/commands/gsd/verify-work.md +39 -0
  118. package/commands/gsd/workspace.md +52 -0
  119. package/commands/gsd/workstreams.md +70 -0
  120. package/gemini-extension.json +6 -0
  121. package/gsd-core/bin/check-latest-version.cjs +161 -0
  122. package/gsd-core/bin/gsd-tools.cjs +1928 -0
  123. package/gsd-core/bin/lib/active-workstream-store.cjs +291 -0
  124. package/gsd-core/bin/lib/adr-parser.cjs +399 -0
  125. package/gsd-core/bin/lib/agent-command-router.cjs +68 -0
  126. package/gsd-core/bin/lib/artifacts.cjs +51 -0
  127. package/gsd-core/bin/lib/audit.cjs +743 -0
  128. package/gsd-core/bin/lib/check-command-router.cjs +343 -0
  129. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
  130. package/gsd-core/bin/lib/cli-exit.cjs +42 -0
  131. package/gsd-core/bin/lib/clock.cjs +95 -0
  132. package/gsd-core/bin/lib/clusters.cjs +132 -0
  133. package/gsd-core/bin/lib/code-review-flags.cjs +59 -0
  134. package/gsd-core/bin/lib/command-aliases.cjs +809 -0
  135. package/gsd-core/bin/lib/command-arg-projection.cjs +55 -0
  136. package/gsd-core/bin/lib/command-routing-hub.cjs +300 -0
  137. package/gsd-core/bin/lib/commands.cjs +1203 -0
  138. package/gsd-core/bin/lib/config-schema.cjs +29 -0
  139. package/gsd-core/bin/lib/config-types.cjs +19 -0
  140. package/gsd-core/bin/lib/config.cjs +738 -0
  141. package/gsd-core/bin/lib/configuration.cjs +239 -0
  142. package/gsd-core/bin/lib/context-utilization.cjs +48 -0
  143. package/gsd-core/bin/lib/core.cjs +2051 -0
  144. package/gsd-core/bin/lib/decisions.cjs +118 -0
  145. package/gsd-core/bin/lib/docs.cjs +252 -0
  146. package/gsd-core/bin/lib/drift.cjs +364 -0
  147. package/gsd-core/bin/lib/fallow-runner.cjs +115 -0
  148. package/gsd-core/bin/lib/frontmatter.cjs +442 -0
  149. package/gsd-core/bin/lib/gap-checker.cjs +257 -0
  150. package/gsd-core/bin/lib/graphify.cjs +496 -0
  151. package/gsd-core/bin/lib/gsd2-import.cjs +456 -0
  152. package/gsd-core/bin/lib/init-command-router.cjs +62 -0
  153. package/gsd-core/bin/lib/init.cjs +1815 -0
  154. package/gsd-core/bin/lib/install-profiles.cjs +584 -0
  155. package/gsd-core/bin/lib/installer-migration-authoring.cjs +122 -0
  156. package/gsd-core/bin/lib/installer-migration-report.cjs +350 -0
  157. package/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +218 -0
  158. package/gsd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
  159. package/gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
  160. package/gsd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
  161. package/gsd-core/bin/lib/installer-migrations.cjs +823 -0
  162. package/gsd-core/bin/lib/intel.cjs +590 -0
  163. package/gsd-core/bin/lib/learnings.cjs +270 -0
  164. package/gsd-core/bin/lib/legacy-cleanup.cjs +253 -0
  165. package/gsd-core/bin/lib/milestone.cjs +373 -0
  166. package/gsd-core/bin/lib/model-catalog.cjs +154 -0
  167. package/gsd-core/bin/lib/model-profiles.cjs +24 -0
  168. package/gsd-core/bin/lib/observability/event.cjs +51 -0
  169. package/gsd-core/bin/lib/observability/logger.cjs +146 -0
  170. package/gsd-core/bin/lib/observability/redaction.cjs +48 -0
  171. package/gsd-core/bin/lib/package-identity.cjs +35 -0
  172. package/gsd-core/bin/lib/package-legitimacy.cjs +368 -0
  173. package/gsd-core/bin/lib/phase-command-router.cjs +189 -0
  174. package/gsd-core/bin/lib/phase-lifecycle.cjs +74 -0
  175. package/gsd-core/bin/lib/phase.cjs +1307 -0
  176. package/gsd-core/bin/lib/phases-command-router.cjs +43 -0
  177. package/gsd-core/bin/lib/plan-scan.cjs +91 -0
  178. package/gsd-core/bin/lib/planning-workspace.cjs +245 -0
  179. package/gsd-core/bin/lib/profile-output.cjs +1120 -0
  180. package/gsd-core/bin/lib/profile-pipeline.cjs +517 -0
  181. package/gsd-core/bin/lib/project-root.cjs +119 -0
  182. package/gsd-core/bin/lib/prompt-budget.cjs +305 -0
  183. package/gsd-core/bin/lib/research-provider.cjs +137 -0
  184. package/gsd-core/bin/lib/research-store.cjs +167 -0
  185. package/gsd-core/bin/lib/review-reviewer-selection.cjs +121 -0
  186. package/gsd-core/bin/lib/roadmap-command-router.cjs +166 -0
  187. package/gsd-core/bin/lib/roadmap-upgrade.cjs +476 -0
  188. package/gsd-core/bin/lib/roadmap.cjs +600 -0
  189. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +312 -0
  190. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +56 -0
  191. package/gsd-core/bin/lib/runtime-homes.cjs +190 -0
  192. package/gsd-core/bin/lib/runtime-name-policy.cjs +96 -0
  193. package/gsd-core/bin/lib/runtime-slash.cjs +119 -0
  194. package/gsd-core/bin/lib/schema-detect.cjs +159 -0
  195. package/gsd-core/bin/lib/secrets.cjs +34 -0
  196. package/gsd-core/bin/lib/security.cjs +480 -0
  197. package/gsd-core/bin/lib/semver-compare.cjs +42 -0
  198. package/gsd-core/bin/lib/shell-command-projection.cjs +533 -0
  199. package/gsd-core/bin/lib/state-command-router.cjs +160 -0
  200. package/gsd-core/bin/lib/state-document.cjs +259 -0
  201. package/gsd-core/bin/lib/state.cjs +2010 -0
  202. package/gsd-core/bin/lib/surface.cjs +449 -0
  203. package/gsd-core/bin/lib/task-command-router.cjs +85 -0
  204. package/gsd-core/bin/lib/template.cjs +237 -0
  205. package/gsd-core/bin/lib/uat.cjs +297 -0
  206. package/gsd-core/bin/lib/ui-safety-gate.cjs +98 -0
  207. package/gsd-core/bin/lib/update-context.cjs +218 -0
  208. package/gsd-core/bin/lib/validate-command-router.cjs +91 -0
  209. package/gsd-core/bin/lib/validate.cjs +112 -0
  210. package/gsd-core/bin/lib/verification-command-router.cjs +31 -0
  211. package/gsd-core/bin/lib/verification.cjs +193 -0
  212. package/gsd-core/bin/lib/verify-command-router.cjs +44 -0
  213. package/gsd-core/bin/lib/verify.cjs +1451 -0
  214. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +81 -0
  215. package/gsd-core/bin/lib/workstream-inventory.cjs +147 -0
  216. package/gsd-core/bin/lib/workstream-name-policy.cjs +91 -0
  217. package/gsd-core/bin/lib/workstream.cjs +380 -0
  218. package/gsd-core/bin/lib/worktree-base-ref.cjs +325 -0
  219. package/gsd-core/bin/lib/worktree-safety.cjs +943 -0
  220. package/gsd-core/bin/shared/config-defaults.manifest.json +98 -0
  221. package/gsd-core/bin/shared/config-schema.manifest.json +192 -0
  222. package/gsd-core/bin/shared/model-catalog.json +149 -0
  223. package/gsd-core/bin/shared/runtime-aliases.manifest.json +75 -0
  224. package/gsd-core/bin/verify-reapply-patches.cjs +349 -0
  225. package/gsd-core/contexts/dev.md +21 -0
  226. package/gsd-core/contexts/research.md +22 -0
  227. package/gsd-core/contexts/review.md +23 -0
  228. package/gsd-core/references/agent-contracts.md +79 -0
  229. package/gsd-core/references/ai-evals.md +156 -0
  230. package/gsd-core/references/ai-frameworks.md +186 -0
  231. package/gsd-core/references/architecture-decision.md +74 -0
  232. package/gsd-core/references/artifact-types.md +131 -0
  233. package/gsd-core/references/auth-in-tests.md +91 -0
  234. package/gsd-core/references/autonomous-smart-discuss.md +277 -0
  235. package/gsd-core/references/checkpoints.md +814 -0
  236. package/gsd-core/references/common-bug-patterns.md +114 -0
  237. package/gsd-core/references/context-budget.md +85 -0
  238. package/gsd-core/references/continuation-format.md +253 -0
  239. package/gsd-core/references/db-test-isolation.md +54 -0
  240. package/gsd-core/references/debugger-philosophy.md +76 -0
  241. package/gsd-core/references/decimal-phase-calculation.md +64 -0
  242. package/gsd-core/references/doc-conflict-engine.md +91 -0
  243. package/gsd-core/references/domain-modeling.md +80 -0
  244. package/gsd-core/references/domain-probes.md +125 -0
  245. package/gsd-core/references/e2e-tiering.md +35 -0
  246. package/gsd-core/references/execute-mvp-tdd.md +81 -0
  247. package/gsd-core/references/executor-examples.md +110 -0
  248. package/gsd-core/references/few-shot-examples/plan-checker.md +73 -0
  249. package/gsd-core/references/few-shot-examples/verifier.md +109 -0
  250. package/gsd-core/references/flaky-test-checklist.md +22 -0
  251. package/gsd-core/references/gate-prompts.md +100 -0
  252. package/gsd-core/references/gates.md +70 -0
  253. package/gsd-core/references/git-integration.md +298 -0
  254. package/gsd-core/references/git-planning-commit.md +40 -0
  255. package/gsd-core/references/ios-scaffold.md +123 -0
  256. package/gsd-core/references/mandatory-initial-read.md +2 -0
  257. package/gsd-core/references/model-profile-resolution.md +38 -0
  258. package/gsd-core/references/model-profiles.md +245 -0
  259. package/gsd-core/references/mvp-concepts.md +49 -0
  260. package/gsd-core/references/phase-argument-parsing.md +61 -0
  261. package/gsd-core/references/planner-antipatterns.md +89 -0
  262. package/gsd-core/references/planner-chunked.md +49 -0
  263. package/gsd-core/references/planner-gap-closure.md +62 -0
  264. package/gsd-core/references/planner-graphify-auto-update.md +67 -0
  265. package/gsd-core/references/planner-human-verify-mode.md +57 -0
  266. package/gsd-core/references/planner-interface-context.md +62 -0
  267. package/gsd-core/references/planner-load-graph-context.md +36 -0
  268. package/gsd-core/references/planner-mvp-mode.md +53 -0
  269. package/gsd-core/references/planner-reviews.md +39 -0
  270. package/gsd-core/references/planner-revision.md +87 -0
  271. package/gsd-core/references/planner-source-audit.md +73 -0
  272. package/gsd-core/references/planning-config.md +473 -0
  273. package/gsd-core/references/product-discovery.md +49 -0
  274. package/gsd-core/references/project-skills-discovery.md +19 -0
  275. package/gsd-core/references/questioning.md +162 -0
  276. package/gsd-core/references/realistic-test-data.md +44 -0
  277. package/gsd-core/references/research-documentation-lookup.md +29 -0
  278. package/gsd-core/references/research-philosophy.md +29 -0
  279. package/gsd-core/references/research-verification-protocol.md +27 -0
  280. package/gsd-core/references/revision-loop.md +97 -0
  281. package/gsd-core/references/scout-codebase.md +51 -0
  282. package/gsd-core/references/skeleton-template.md +48 -0
  283. package/gsd-core/references/sketch-interactivity.md +41 -0
  284. package/gsd-core/references/sketch-theme-system.md +94 -0
  285. package/gsd-core/references/sketch-tooling.md +45 -0
  286. package/gsd-core/references/sketch-variant-patterns.md +81 -0
  287. package/gsd-core/references/spidr-splitting.md +69 -0
  288. package/gsd-core/references/tdd.md +330 -0
  289. package/gsd-core/references/test-containers.md +55 -0
  290. package/gsd-core/references/test-strategy.md +75 -0
  291. package/gsd-core/references/thinking-models-debug.md +44 -0
  292. package/gsd-core/references/thinking-models-execution.md +50 -0
  293. package/gsd-core/references/thinking-models-planning.md +62 -0
  294. package/gsd-core/references/thinking-models-research.md +50 -0
  295. package/gsd-core/references/thinking-models-verification.md +55 -0
  296. package/gsd-core/references/thinking-partner.md +96 -0
  297. package/gsd-core/references/ui-brand.md +162 -0
  298. package/gsd-core/references/universal-anti-patterns.md +63 -0
  299. package/gsd-core/references/user-profiling.md +681 -0
  300. package/gsd-core/references/user-story-template.md +58 -0
  301. package/gsd-core/references/verification-overrides.md +227 -0
  302. package/gsd-core/references/verification-patterns.md +612 -0
  303. package/gsd-core/references/verify-mvp-mode.md +85 -0
  304. package/gsd-core/references/workstream-flag.md +111 -0
  305. package/gsd-core/references/worktree-branch-check.md +38 -0
  306. package/gsd-core/references/worktree-path-safety.md +67 -0
  307. package/gsd-core/templates/AI-SPEC.md +246 -0
  308. package/gsd-core/templates/DEBUG.md +169 -0
  309. package/gsd-core/templates/README.md +77 -0
  310. package/gsd-core/templates/SECURITY.md +61 -0
  311. package/gsd-core/templates/UAT.md +265 -0
  312. package/gsd-core/templates/UI-SPEC.md +100 -0
  313. package/gsd-core/templates/VALIDATION.md +76 -0
  314. package/gsd-core/templates/adr.md +58 -0
  315. package/gsd-core/templates/claude-md.md +145 -0
  316. package/gsd-core/templates/codebase/architecture.md +255 -0
  317. package/gsd-core/templates/codebase/concerns.md +310 -0
  318. package/gsd-core/templates/codebase/conventions.md +307 -0
  319. package/gsd-core/templates/codebase/integrations.md +280 -0
  320. package/gsd-core/templates/codebase/stack.md +186 -0
  321. package/gsd-core/templates/codebase/structure.md +285 -0
  322. package/gsd-core/templates/codebase/testing.md +480 -0
  323. package/gsd-core/templates/config.json +62 -0
  324. package/gsd-core/templates/context.md +352 -0
  325. package/gsd-core/templates/continue-here.md +78 -0
  326. package/gsd-core/templates/copilot-instructions.md +7 -0
  327. package/gsd-core/templates/debug-subagent-prompt.md +91 -0
  328. package/gsd-core/templates/dev-preferences.md +21 -0
  329. package/gsd-core/templates/discovery.md +146 -0
  330. package/gsd-core/templates/discussion-log.md +63 -0
  331. package/gsd-core/templates/domain-model.md +54 -0
  332. package/gsd-core/templates/milestone-archive.md +123 -0
  333. package/gsd-core/templates/milestone.md +115 -0
  334. package/gsd-core/templates/phase-prompt.md +610 -0
  335. package/gsd-core/templates/planner-subagent-prompt.md +117 -0
  336. package/gsd-core/templates/product-brief.md +55 -0
  337. package/gsd-core/templates/project.md +186 -0
  338. package/gsd-core/templates/requirements.md +231 -0
  339. package/gsd-core/templates/research-project/ARCHITECTURE.md +204 -0
  340. package/gsd-core/templates/research-project/FEATURES.md +147 -0
  341. package/gsd-core/templates/research-project/PITFALLS.md +200 -0
  342. package/gsd-core/templates/research-project/STACK.md +120 -0
  343. package/gsd-core/templates/research-project/SUMMARY.md +170 -0
  344. package/gsd-core/templates/research.md +592 -0
  345. package/gsd-core/templates/retrospective.md +54 -0
  346. package/gsd-core/templates/roadmap.md +202 -0
  347. package/gsd-core/templates/spec.md +307 -0
  348. package/gsd-core/templates/state.md +195 -0
  349. package/gsd-core/templates/summary-complex.md +59 -0
  350. package/gsd-core/templates/summary-minimal.md +41 -0
  351. package/gsd-core/templates/summary-standard.md +48 -0
  352. package/gsd-core/templates/summary.md +248 -0
  353. package/gsd-core/templates/test-strategy.md +50 -0
  354. package/gsd-core/templates/user-profile.md +146 -0
  355. package/gsd-core/templates/user-setup.md +311 -0
  356. package/gsd-core/templates/verification-report.md +322 -0
  357. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -0
  358. package/gsd-core/workflows/add-backlog.md +91 -0
  359. package/gsd-core/workflows/add-phase.md +113 -0
  360. package/gsd-core/workflows/add-tests.md +355 -0
  361. package/gsd-core/workflows/add-todo.md +161 -0
  362. package/gsd-core/workflows/ai-integration-phase.md +295 -0
  363. package/gsd-core/workflows/analyze-dependencies.md +96 -0
  364. package/gsd-core/workflows/audit-fix.md +178 -0
  365. package/gsd-core/workflows/audit-milestone.md +360 -0
  366. package/gsd-core/workflows/audit-uat.md +110 -0
  367. package/gsd-core/workflows/autonomous.md +797 -0
  368. package/gsd-core/workflows/check-todos.md +180 -0
  369. package/gsd-core/workflows/cleanup.md +195 -0
  370. package/gsd-core/workflows/code-review-fix.md +502 -0
  371. package/gsd-core/workflows/code-review.md +658 -0
  372. package/gsd-core/workflows/complete-milestone.md +855 -0
  373. package/gsd-core/workflows/debug.md +237 -0
  374. package/gsd-core/workflows/diagnose-issues.md +245 -0
  375. package/gsd-core/workflows/discover-product.md +112 -0
  376. package/gsd-core/workflows/discovery-phase.md +291 -0
  377. package/gsd-core/workflows/discuss-phase/modes/advisor.md +176 -0
  378. package/gsd-core/workflows/discuss-phase/modes/all.md +28 -0
  379. package/gsd-core/workflows/discuss-phase/modes/analyze.md +44 -0
  380. package/gsd-core/workflows/discuss-phase/modes/auto.md +57 -0
  381. package/gsd-core/workflows/discuss-phase/modes/batch.md +52 -0
  382. package/gsd-core/workflows/discuss-phase/modes/chain.md +98 -0
  383. package/gsd-core/workflows/discuss-phase/modes/default.md +141 -0
  384. package/gsd-core/workflows/discuss-phase/modes/power.md +44 -0
  385. package/gsd-core/workflows/discuss-phase/modes/text.md +55 -0
  386. package/gsd-core/workflows/discuss-phase/templates/checkpoint.json +18 -0
  387. package/gsd-core/workflows/discuss-phase/templates/context.md +136 -0
  388. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +50 -0
  389. package/gsd-core/workflows/discuss-phase-assumptions.md +675 -0
  390. package/gsd-core/workflows/discuss-phase-power.md +291 -0
  391. package/gsd-core/workflows/discuss-phase.md +499 -0
  392. package/gsd-core/workflows/do.md +111 -0
  393. package/gsd-core/workflows/docs-update.md +1176 -0
  394. package/gsd-core/workflows/edit-phase.md +295 -0
  395. package/gsd-core/workflows/eval-review.md +156 -0
  396. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +95 -0
  397. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
  398. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +117 -0
  399. package/gsd-core/workflows/execute-phase.md +1752 -0
  400. package/gsd-core/workflows/execute-plan.md +526 -0
  401. package/gsd-core/workflows/explore.md +146 -0
  402. package/gsd-core/workflows/extract-learnings.md +243 -0
  403. package/gsd-core/workflows/fast.md +124 -0
  404. package/gsd-core/workflows/forensics.md +279 -0
  405. package/gsd-core/workflows/graduation.md +196 -0
  406. package/gsd-core/workflows/health.md +224 -0
  407. package/gsd-core/workflows/help/modes/brief.md +22 -0
  408. package/gsd-core/workflows/help/modes/default.md +50 -0
  409. package/gsd-core/workflows/help/modes/full.md +789 -0
  410. package/gsd-core/workflows/help/modes/topic.md +74 -0
  411. package/gsd-core/workflows/help.md +24 -0
  412. package/gsd-core/workflows/import.md +256 -0
  413. package/gsd-core/workflows/inbox.md +387 -0
  414. package/gsd-core/workflows/ingest-docs.md +340 -0
  415. package/gsd-core/workflows/insert-phase.md +152 -0
  416. package/gsd-core/workflows/list-phase-assumptions.md +178 -0
  417. package/gsd-core/workflows/list-workspaces.md +57 -0
  418. package/gsd-core/workflows/manager.md +393 -0
  419. package/gsd-core/workflows/map-codebase.md +446 -0
  420. package/gsd-core/workflows/milestone-summary.md +224 -0
  421. package/gsd-core/workflows/model-domain.md +162 -0
  422. package/gsd-core/workflows/mvp-phase.md +222 -0
  423. package/gsd-core/workflows/new-milestone.md +635 -0
  424. package/gsd-core/workflows/new-project.md +1555 -0
  425. package/gsd-core/workflows/new-workspace.md +240 -0
  426. package/gsd-core/workflows/next.md +299 -0
  427. package/gsd-core/workflows/node-repair.md +92 -0
  428. package/gsd-core/workflows/note.md +158 -0
  429. package/gsd-core/workflows/pause-work.md +244 -0
  430. package/gsd-core/workflows/plan-milestone-gaps.md +281 -0
  431. package/gsd-core/workflows/plan-phase.md +1814 -0
  432. package/gsd-core/workflows/plan-review-convergence.md +346 -0
  433. package/gsd-core/workflows/plant-seed.md +230 -0
  434. package/gsd-core/workflows/pr-branch.md +157 -0
  435. package/gsd-core/workflows/profile-user.md +453 -0
  436. package/gsd-core/workflows/progress.md +699 -0
  437. package/gsd-core/workflows/quick.md +1017 -0
  438. package/gsd-core/workflows/reapply-patches.md +426 -0
  439. package/gsd-core/workflows/recommend-architecture.md +135 -0
  440. package/gsd-core/workflows/remove-phase.md +156 -0
  441. package/gsd-core/workflows/remove-workspace.md +108 -0
  442. package/gsd-core/workflows/resume-project.md +332 -0
  443. package/gsd-core/workflows/review.md +748 -0
  444. package/gsd-core/workflows/scan.md +107 -0
  445. package/gsd-core/workflows/secure-phase.md +182 -0
  446. package/gsd-core/workflows/session-report.md +146 -0
  447. package/gsd-core/workflows/settings-advanced.md +810 -0
  448. package/gsd-core/workflows/settings-integrations.md +312 -0
  449. package/gsd-core/workflows/settings.md +566 -0
  450. package/gsd-core/workflows/ship.md +405 -0
  451. package/gsd-core/workflows/sketch-wrap-up.md +286 -0
  452. package/gsd-core/workflows/sketch.md +361 -0
  453. package/gsd-core/workflows/spec-phase.md +263 -0
  454. package/gsd-core/workflows/spike-wrap-up.md +307 -0
  455. package/gsd-core/workflows/spike.md +453 -0
  456. package/gsd-core/workflows/stats.md +80 -0
  457. package/gsd-core/workflows/sync-skills.md +182 -0
  458. package/gsd-core/workflows/testing-strategy.md +122 -0
  459. package/gsd-core/workflows/thread.md +222 -0
  460. package/gsd-core/workflows/transition.md +694 -0
  461. package/gsd-core/workflows/ui-phase.md +328 -0
  462. package/gsd-core/workflows/ui-review.md +193 -0
  463. package/gsd-core/workflows/ultraplan-phase.md +199 -0
  464. package/gsd-core/workflows/undo.md +314 -0
  465. package/gsd-core/workflows/update.md +496 -0
  466. package/gsd-core/workflows/validate-phase.md +181 -0
  467. package/gsd-core/workflows/verify-phase.md +544 -0
  468. package/gsd-core/workflows/verify-work.md +781 -0
  469. package/hooks/dist/gsd-check-update-worker.js +108 -0
  470. package/hooks/dist/gsd-check-update.js +66 -0
  471. package/hooks/dist/gsd-config-reload.js +133 -0
  472. package/hooks/dist/gsd-context-monitor.js +195 -0
  473. package/hooks/dist/gsd-cursor-post-tool.js +75 -0
  474. package/hooks/dist/gsd-cursor-session-start.js +52 -0
  475. package/hooks/dist/gsd-graphify-update.sh +158 -0
  476. package/hooks/dist/gsd-phase-boundary.sh +47 -0
  477. package/hooks/dist/gsd-prompt-guard.js +97 -0
  478. package/hooks/dist/gsd-read-guard.js +101 -0
  479. package/hooks/dist/gsd-read-injection-scanner.js +203 -0
  480. package/hooks/dist/gsd-session-state.sh +59 -0
  481. package/hooks/dist/gsd-statusline.js +566 -0
  482. package/hooks/dist/gsd-update-banner.js +138 -0
  483. package/hooks/dist/gsd-validate-commit.sh +57 -0
  484. package/hooks/dist/gsd-workflow-guard.js +167 -0
  485. package/hooks/dist/gsd-worktree-path-guard.js +169 -0
  486. package/hooks/dist/lib/git-cmd.js +150 -0
  487. package/hooks/dist/lib/gsd-graphify-rebuild.sh +65 -0
  488. package/hooks/dist/managed-hooks-registry.cjs +38 -0
  489. package/hooks/gsd-check-update-worker.js +108 -0
  490. package/hooks/gsd-check-update.js +66 -0
  491. package/hooks/gsd-config-reload.js +133 -0
  492. package/hooks/gsd-context-monitor.js +195 -0
  493. package/hooks/gsd-cursor-post-tool.js +75 -0
  494. package/hooks/gsd-cursor-session-start.js +52 -0
  495. package/hooks/gsd-graphify-update.sh +158 -0
  496. package/hooks/gsd-phase-boundary.sh +47 -0
  497. package/hooks/gsd-prompt-guard.js +97 -0
  498. package/hooks/gsd-read-guard.js +101 -0
  499. package/hooks/gsd-read-injection-scanner.js +203 -0
  500. package/hooks/gsd-session-state.sh +59 -0
  501. package/hooks/gsd-statusline.js +566 -0
  502. package/hooks/gsd-update-banner.js +138 -0
  503. package/hooks/gsd-validate-commit.sh +57 -0
  504. package/hooks/gsd-workflow-guard.js +167 -0
  505. package/hooks/gsd-worktree-path-guard.js +169 -0
  506. package/hooks/hooks.json +69 -0
  507. package/hooks/lib/git-cmd.js +150 -0
  508. package/hooks/lib/gsd-graphify-rebuild.sh +65 -0
  509. package/hooks/managed-hooks-registry.cjs +38 -0
  510. package/package.json +115 -0
  511. package/scripts/affected-tests-lib.cjs +542 -0
  512. package/scripts/audit-workflow-script-paths.cjs +73 -0
  513. package/scripts/base64-scan.sh +351 -0
  514. package/scripts/build-hooks.js +247 -0
  515. package/scripts/changeset/README.md +129 -0
  516. package/scripts/changeset/cli.cjs +590 -0
  517. package/scripts/changeset/github-release-notes.cjs +199 -0
  518. package/scripts/changeset/lint.cjs +111 -0
  519. package/scripts/changeset/new.cjs +137 -0
  520. package/scripts/changeset/parse.cjs +114 -0
  521. package/scripts/changeset/render.cjs +34 -0
  522. package/scripts/changeset/serialize.cjs +130 -0
  523. package/scripts/check-alias-drift.cjs +114 -0
  524. package/scripts/check-env.cjs +312 -0
  525. package/scripts/check-npm-integrity.cjs +215 -0
  526. package/scripts/ci-guard-runner.cjs +22 -0
  527. package/scripts/ci-prepare-test-scope.cjs +51 -0
  528. package/scripts/ci-rebase-check.cjs +86 -0
  529. package/scripts/ci-test-scope.cjs +431 -0
  530. package/scripts/command-contract-helpers.cjs +64 -0
  531. package/scripts/diff-touches-shipped-paths.cjs +155 -0
  532. package/scripts/fix-slash-commands.cjs +147 -0
  533. package/scripts/gen-inventory-manifest.cjs +115 -0
  534. package/scripts/gen-research-agents.cjs +276 -0
  535. package/scripts/generate-package-identity.cjs +125 -0
  536. package/scripts/issue-dedupe.cjs +278 -0
  537. package/scripts/lib/allowlist-ratchet.cjs +136 -0
  538. package/scripts/lib/cli-exit.cjs +56 -0
  539. package/scripts/lint-command-contract.cjs +114 -0
  540. package/scripts/lint-descriptions.cjs +87 -0
  541. package/scripts/lint-docs-required.cjs +222 -0
  542. package/scripts/lint-legacy-dir-name.cjs +160 -0
  543. package/scripts/lint-package-identity-drift.cjs +141 -0
  544. package/scripts/lint-pr-check-project-dir.cjs +99 -0
  545. package/scripts/lint-shell-command-projection-drift.cjs +62 -0
  546. package/scripts/lint-skill-deps.cjs +185 -0
  547. package/scripts/lint-test-file-count.allowlist.json +135 -0
  548. package/scripts/lint-test-file-count.cjs +246 -0
  549. package/scripts/mutation-matrix.cjs +222 -0
  550. package/scripts/pr-template-policy.cjs +268 -0
  551. package/scripts/prompt-injection-scan.sh +207 -0
  552. package/scripts/release-notes/discord-release-summary.cjs +373 -0
  553. package/scripts/release-notes/format-github-release-notes.cjs +261 -0
  554. package/scripts/release-tarball-smoke.cjs +629 -0
  555. package/scripts/research-profiles.cjs +149 -0
  556. package/scripts/run-affected-tests.cjs +7 -0
  557. package/scripts/run-cross-platform-tests.cjs +67 -0
  558. package/scripts/run-tests.cjs +315 -0
  559. package/scripts/secret-scan-lint.sh +231 -0
  560. package/scripts/secret-scan.sh +358 -0
  561. package/scripts/setup-branch-protection.sh +236 -0
  562. package/scripts/strip-prose-atrefs.cjs +106 -0
  563. package/scripts/sync-manifest-versions.cjs +119 -0
  564. package/scripts/sync-rulesets.sh +34 -0
  565. package/scripts/sync-runtime-launcher.cjs +399 -0
  566. package/scripts/test-failure-reasons.cjs +34 -0
  567. package/scripts/verify-npm-publish.cjs +240 -0
  568. package/scripts/workflow-policy.cjs +450 -0
@@ -0,0 +1,399 @@
1
+ 'use strict';
2
+ /**
3
+ * sync-runtime-launcher.cjs
4
+ *
5
+ * Idempotent transform: for every gsd-core/workflows/*.md (and subdirs),
6
+ * rewrite all bash/sh/shell fenced blocks to:
7
+ * 1. Strip ALL old resolver forms from every bash block (GSD_TOOLS=,
8
+ * GSD_SDK=, the if/elif/else/fi resolver, _GSD_SHIM_NAME=, and any
9
+ * previously-inserted gsd_run preamble).
10
+ * 2. Replace $GSD_SDK tokens with gsd_run (idempotent).
11
+ * 3. Insert the canonical preamble at the TOP of ONLY the FIRST bash block
12
+ * (document order) that contains a gsd_run call. All other bash blocks
13
+ * keep their gsd_run calls with NO preamble. (Define once per file,
14
+ * use across blocks — original footprint.)
15
+ *
16
+ * Run: node scripts/sync-runtime-launcher.cjs
17
+ */
18
+
19
+ const fs = require('node:fs');
20
+ const path = require('node:path');
21
+
22
+ const WORKFLOWS_DIR = path.join(__dirname, '..', 'gsd-core', 'workflows');
23
+ const SNIPPET_FILE = path.join(WORKFLOWS_DIR, '_runtime-launcher.snippet.sh');
24
+
25
+ // Read canonical preamble (full content of snippet file)
26
+ function loadPreamble() {
27
+ const raw = fs.readFileSync(SNIPPET_FILE, 'utf8');
28
+ const lines = raw.split('\n');
29
+ // Strip trailing empty line (trailing newline produces an empty last element)
30
+ const content = lines[lines.length - 1] === '' ? lines.slice(0, -1) : lines;
31
+ if (content.length < 1) {
32
+ throw new Error(`_runtime-launcher.snippet.sh is empty`);
33
+ }
34
+ return content;
35
+ }
36
+
37
+ /**
38
+ * Collect all .md files recursively.
39
+ */
40
+ function collectFiles(dir) {
41
+ const results = [];
42
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
43
+ const full = path.join(dir, entry.name);
44
+ if (entry.isDirectory()) {
45
+ results.push(...collectFiles(full));
46
+ } else if (entry.isFile() && entry.name.endsWith('.md')) {
47
+ results.push(full);
48
+ }
49
+ }
50
+ return results;
51
+ }
52
+
53
+ /**
54
+ * Given the lines of a bash block (without fence markers), strip all resolver
55
+ * boilerplate (old and new preamble forms) and replace $GSD_SDK tokens.
56
+ * Does NOT insert preamble — that is done by the file-level transform.
57
+ *
58
+ * Returns the stripped lines array.
59
+ */
60
+ function stripAndReplace(lines, preamble) {
61
+ let result = lines.slice();
62
+
63
+ // Step 1: Remove ALL resolver boilerplate lines (including existing preamble).
64
+ result = removeResolverLines(result, preamble);
65
+
66
+ // Step 2: Replace $GSD_SDK tokens with gsd_run
67
+ result = result.map((line) => replaceGsdSdk(line));
68
+
69
+ return result;
70
+ }
71
+
72
+ /**
73
+ * Remove resolver boilerplate lines from a block.
74
+ *
75
+ * Patterns to remove:
76
+ * A) Multi-line if block:
77
+ * GSD_TOOLS="...gsd-tools.cjs" (or ...${_GSD_SHIM_NAME})
78
+ * if [ -f "$GSD_TOOLS" ]; then
79
+ * ...
80
+ * fi
81
+ *
82
+ * B) One-liner form:
83
+ * GSD_TOOLS=...; if [ -f "$GSD_TOOLS" ]; then GSD_SDK=...; elif ...; else ...; fi
84
+ *
85
+ * C) _GSD_SHIM_NAME= line
86
+ *
87
+ * D) Bare GSD_SDK= line
88
+ *
89
+ * E) The canonical preamble comment line (so we strip old inserted preambles too)
90
+ *
91
+ * F) The gsd_run() function definitions that are part of the preamble
92
+ * (so previously-inserted preambles are stripped and will be re-inserted
93
+ * exactly once at the right location)
94
+ */
95
+ function removeResolverLines(lines, preamble) {
96
+ const result = [];
97
+ let i = 0;
98
+
99
+ while (i < lines.length) {
100
+ const line = lines[i];
101
+ const trimmed = line.trim();
102
+
103
+ // B) One-liner form: GSD_TOOLS=... ; if ... GSD_SDK=... fi
104
+ if (
105
+ /^GSD_TOOLS=.*gsd-tools\.cjs.*;\s*if\s+\[/.test(trimmed) ||
106
+ /^GSD_TOOLS=.*\/\$\{_GSD_SHIM_NAME\}.*;\s*if\s+\[/.test(trimmed)
107
+ ) {
108
+ // Skip the whole one-liner, and any adjacent SDK comment above it
109
+ const lastIdx = result.length - 1;
110
+ if (lastIdx >= 0 && isSdkComment(result[lastIdx])) {
111
+ result.pop();
112
+ }
113
+ i++;
114
+ continue;
115
+ }
116
+
117
+ // C) _GSD_SHIM_NAME= line
118
+ if (/^_GSD_SHIM_NAME=/.test(trimmed)) {
119
+ // Check if there's a canonical preamble comment just before it
120
+ const lastIdx = result.length - 1;
121
+ if (lastIdx >= 0 && isCanonicalPreambleComment(result[lastIdx])) {
122
+ result.pop();
123
+ } else if (lastIdx >= 0 && isSdkComment(result[lastIdx])) {
124
+ result.pop();
125
+ }
126
+ i++;
127
+ continue;
128
+ }
129
+
130
+ // A) Multi-line form: starts with GSD_TOOLS=...gsd-tools.cjs or GSD_TOOLS=...${_GSD_SHIM_NAME}
131
+ if (
132
+ /^GSD_TOOLS=.*gsd-tools\.cjs"$/.test(trimmed) ||
133
+ /^GSD_TOOLS=.*\/\$\{_GSD_SHIM_NAME\}"$/.test(trimmed)
134
+ ) {
135
+ // Check if there's a canonical preamble comment just before it (preamble already installed)
136
+ // or an old SDK comment — either way, remove the whole block
137
+ const lastIdx = result.length - 1;
138
+ if (lastIdx >= 0 && (isCanonicalPreambleComment(result[lastIdx]) || isSdkComment(result[lastIdx]))) {
139
+ result.pop();
140
+ }
141
+
142
+ // Consume the if block that follows (if it exists)
143
+ const ahead = lines[i + 1] ? lines[i + 1].trim() : '';
144
+ if (/^if\s+\[\s+-f\s+"\$GSD_TOOLS"\s*\]/.test(ahead)) {
145
+ // Consume until matching `fi`
146
+ i += 2; // skip GSD_TOOLS= and `if [...]`
147
+ let depth = 1;
148
+ while (i < lines.length && depth > 0) {
149
+ const t = lines[i].trim();
150
+ if (/^if\s+/.test(t)) depth++;
151
+ if (/^fi(\s|$)/.test(t)) {
152
+ depth--;
153
+ if (depth === 0) {
154
+ i++;
155
+ break;
156
+ }
157
+ }
158
+ i++;
159
+ }
160
+ // After fi, skip a blank line if present
161
+ if (i < lines.length && lines[i].trim() === '') {
162
+ i++;
163
+ }
164
+ continue;
165
+ } else {
166
+ // Just skip the GSD_TOOLS= line
167
+ i++;
168
+ continue;
169
+ }
170
+ }
171
+
172
+ // D) Bare GSD_SDK= line (not inside an if block, defensive)
173
+ if (/^GSD_SDK=/.test(trimmed) && !/gsd_run/.test(trimmed)) {
174
+ i++;
175
+ continue;
176
+ }
177
+
178
+ // E+F) Strip lines that are part of the canonical preamble (to remove previously-inserted preambles).
179
+ // We match the canonical preamble comment, _GSD_SHIM_NAME (handled above at C),
180
+ // and gsd_run() function definition lines.
181
+ if (isCanonicalPreambleComment(trimmed.startsWith('#') ? line : '')) {
182
+ // Start of a previously-inserted canonical preamble — skip preamble lines
183
+ // by consuming lines that match the preamble array in order.
184
+ // Check how many consecutive lines match the preamble.
185
+ let matchLen = 0;
186
+ for (let p = 0; p < preamble.length; p++) {
187
+ if (lines[i + p] === preamble[p]) {
188
+ matchLen++;
189
+ } else {
190
+ break;
191
+ }
192
+ }
193
+ if (matchLen === preamble.length) {
194
+ // Exact preamble match — skip all preamble lines
195
+ i += matchLen;
196
+ // Skip trailing blank line if present
197
+ if (i < lines.length && lines[i].trim() === '') {
198
+ i++;
199
+ }
200
+ continue;
201
+ }
202
+ // Partial match or just the comment — still remove the comment line
203
+ i++;
204
+ continue;
205
+ }
206
+
207
+ result.push(line);
208
+ i++;
209
+ }
210
+
211
+ return result;
212
+ }
213
+
214
+ /**
215
+ * Returns true if the line looks like an old SDK resolver comment (to be removed).
216
+ * Must NOT match the new canonical preamble comment.
217
+ */
218
+ function isSdkComment(line) {
219
+ // The new canonical preamble comment starts with "# Runtime launcher:" — preserve it.
220
+ if (isCanonicalPreambleComment(line)) return false;
221
+ return /^\s*#\s*SDK resolution/.test(line) || /^\s*#.*prefer local.*gsd-tools/.test(line);
222
+ }
223
+
224
+ /**
225
+ * Returns true if the line is the new canonical preamble comment.
226
+ * This identifies the start of the new multi-line canonical preamble.
227
+ */
228
+ function isCanonicalPreambleComment(line) {
229
+ return /^\s*#\s*Runtime launcher:.*prefer local gsd-tools\.cjs.*installed gsd-tools on PATH/.test(line);
230
+ }
231
+
232
+ /**
233
+ * Replace all $GSD_SDK tokens with gsd_run in a line.
234
+ * Handles: $GSD_SDK, ${GSD_SDK} forms.
235
+ */
236
+ function replaceGsdSdk(line) {
237
+ return line.replace(/\$\{?GSD_SDK\}?(?=\s|$|;|"|'|\))/g, 'gsd_run');
238
+ }
239
+
240
+ /**
241
+ * Ensure the canonical preamble appears at the top of the block.
242
+ * Rules:
243
+ * - Skip leading blank lines
244
+ * - Check if preamble lines 0..N-1 already match at the scan position
245
+ * - If not, insert preamble at the top (after leading blanks)
246
+ * - Idempotent: if preamble already present, do nothing
247
+ */
248
+ function insertPreamble(lines, preamble) {
249
+ // Find insertion point: skip blanks only
250
+ let scanIdx = 0;
251
+ while (scanIdx < lines.length && lines[scanIdx].trim() === '') scanIdx++;
252
+
253
+ // Check if preamble already present at scanIdx
254
+ let alreadyPresent = preamble.length > 0;
255
+ for (let p = 0; p < preamble.length; p++) {
256
+ if (lines[scanIdx + p] !== preamble[p]) {
257
+ alreadyPresent = false;
258
+ break;
259
+ }
260
+ }
261
+
262
+ if (alreadyPresent) return lines; // idempotent
263
+
264
+ // Insert preamble at scanIdx (after leading blanks)
265
+ const insertAt = scanIdx;
266
+ const before = lines.slice(0, insertAt);
267
+ const after = lines.slice(insertAt);
268
+
269
+ return [...before, ...preamble, ...after];
270
+ }
271
+
272
+ /**
273
+ * Transform a single markdown file's content.
274
+ * Returns new content string, or null if no changes needed.
275
+ *
276
+ * Strategy:
277
+ * 1. Parse all shell blocks, strip resolver boilerplate from each.
278
+ * 2. Find the FIRST block (document order) that has a gsd_run call.
279
+ * 3. Insert preamble into that block only.
280
+ * 4. Reconstruct the file.
281
+ *
282
+ * Handles both column-0 fences (```bash) and indented fences ( ```bash).
283
+ */
284
+ function transformFile(content, preamble) {
285
+ const allLines = content.split('\n');
286
+
287
+ // --- Pass 1: identify all shell blocks and their positions ---
288
+ // Each entry: { openIdx, closeIdx, blockLines, isShell }
289
+ // We'll reconstruct by replacing block lines in-place.
290
+
291
+ const shellBlockRanges = []; // { openLineIdx, contentStart, contentEnd, closingLineIdx }
292
+ let i = 0;
293
+
294
+ while (i < allLines.length) {
295
+ const line = allLines[i];
296
+ const fenceOpen = line.match(/^(\s*)```(\w+)?\s*$/);
297
+ if (!fenceOpen) { i++; continue; }
298
+
299
+ const indent = fenceOpen[1];
300
+ const lang = (fenceOpen[2] || '').toLowerCase();
301
+ const isShellBlock = ['bash', 'sh', 'shell', 'zsh', ''].includes(lang);
302
+ const closingPattern = new RegExp('^' + escapeRegExp(indent) + '```\\s*$');
303
+
304
+ const openLineIdx = i;
305
+ i++;
306
+ const contentStart = i;
307
+
308
+ while (i < allLines.length && !closingPattern.test(allLines[i])) {
309
+ i++;
310
+ }
311
+ const contentEnd = i; // exclusive
312
+ const closingLineIdx = i < allLines.length ? i : -1;
313
+ if (i < allLines.length) i++;
314
+
315
+ if (isShellBlock) {
316
+ shellBlockRanges.push({ openLineIdx, contentStart, contentEnd, closingLineIdx });
317
+ }
318
+ }
319
+
320
+ if (shellBlockRanges.length === 0) return null;
321
+
322
+ // --- Pass 2: transform each block ---
323
+ // Build a new lines array by splicing in transformed block contents.
324
+ // Process ranges in reverse order so indices stay valid.
325
+
326
+ const outputLines = allLines.slice();
327
+ let changed = false;
328
+ let firstGsdRunBlockIdx = -1; // index into shellBlockRanges of the first gsd_run block (after strip)
329
+
330
+ // First: strip + replace in all blocks, find first gsd_run block
331
+ const strippedBlocks = shellBlockRanges.map((range) => {
332
+ const blockLines = outputLines.slice(range.contentStart, range.contentEnd);
333
+ const stripped = stripAndReplace(blockLines, preamble);
334
+ return stripped;
335
+ });
336
+
337
+ // Find the first block that has a gsd_run call (after stripping)
338
+ for (let bi = 0; bi < strippedBlocks.length; bi++) {
339
+ if (strippedBlocks[bi].some((l) => /\bgsd_run\b/.test(l))) {
340
+ firstGsdRunBlockIdx = bi;
341
+ break;
342
+ }
343
+ }
344
+
345
+ // Insert preamble into the first gsd_run block only
346
+ const finalBlocks = strippedBlocks.map((stripped, bi) => {
347
+ if (bi === firstGsdRunBlockIdx) {
348
+ return insertPreamble(stripped, preamble);
349
+ }
350
+ return stripped;
351
+ });
352
+
353
+ // --- Pass 3: splice back into output (reverse order to preserve indices) ---
354
+ for (let bi = shellBlockRanges.length - 1; bi >= 0; bi--) {
355
+ const range = shellBlockRanges[bi];
356
+ const originalBlock = allLines.slice(range.contentStart, range.contentEnd);
357
+ const newBlock = finalBlocks[bi];
358
+
359
+ if (originalBlock.join('\n') !== newBlock.join('\n')) {
360
+ changed = true;
361
+ }
362
+
363
+ // Replace contentStart..contentEnd with newBlock
364
+ outputLines.splice(range.contentStart, range.contentEnd - range.contentStart, ...newBlock);
365
+ }
366
+
367
+ if (!changed) return null;
368
+
369
+ return outputLines.join('\n');
370
+ }
371
+
372
+ function escapeRegExp(str) {
373
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
374
+ }
375
+
376
+ // Main
377
+ function main() {
378
+ const preamble = loadPreamble();
379
+ const files = collectFiles(WORKFLOWS_DIR);
380
+
381
+ let transformedCount = 0;
382
+ let unchangedCount = 0;
383
+
384
+ for (const f of files) {
385
+ const content = fs.readFileSync(f, 'utf8');
386
+ const result = transformFile(content, preamble);
387
+ if (result !== null) {
388
+ fs.writeFileSync(f, result, 'utf8');
389
+ transformedCount++;
390
+ console.log(`transformed: ${path.relative(WORKFLOWS_DIR, f)}`);
391
+ } else {
392
+ unchangedCount++;
393
+ }
394
+ }
395
+
396
+ console.log(`\nDone. ${transformedCount} files transformed, ${unchangedCount} unchanged.`);
397
+ }
398
+
399
+ main();
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ const TEST_GATE_REASON = Object.freeze({
4
+ PASS: 'pass',
5
+ TEST_FAILURE: 'test_failure',
6
+ INFRA_FAILURE: 'infra_failure',
7
+ UNKNOWN_FAILURE: 'unknown_failure',
8
+ });
9
+
10
+ /**
11
+ * Classify gsd-test style output + exit code into a typed reason.
12
+ * @param {{exitCode:number, output?:string}} input
13
+ * @returns {{ok:boolean, reason:string}}
14
+ */
15
+ function classifyTestGateResult(input) {
16
+ const exitCode = Number(input?.exitCode ?? 0);
17
+ const output = String(input?.output ?? '');
18
+
19
+ if (exitCode === 0) return { ok: true, reason: TEST_GATE_REASON.PASS };
20
+
21
+ // gsd-test/gsd-test-summary infrastructure class (exit 2)
22
+ if (exitCode === 2 || /infrastructure failure|worktree\.Construct/i.test(output)) {
23
+ return { ok: false, reason: TEST_GATE_REASON.INFRA_FAILURE };
24
+ }
25
+
26
+ // test failures (non-zero plus explicit FAIL lines)
27
+ if (/\bFAIL\b|\d+\s+failures?\)|failed\)/i.test(output)) {
28
+ return { ok: false, reason: TEST_GATE_REASON.TEST_FAILURE };
29
+ }
30
+
31
+ return { ok: false, reason: TEST_GATE_REASON.UNKNOWN_FAILURE };
32
+ }
33
+
34
+ module.exports = { TEST_GATE_REASON, classifyTestGateResult };
@@ -0,0 +1,240 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * verify-npm-publish.cjs — verifies a freshly-published npm version is
6
+ * retrievable, tolerating registry/CDN propagation lag via bounded retry.
7
+ * Fixes #623. Used by both Verify-publish steps in .github/workflows/release.yml.
8
+ */
9
+
10
+ const cp = require('node:child_process');
11
+ const { ExitError, runMain } = require('./lib/cli-exit.cjs');
12
+
13
+ // ---- Constants ---------------------------------------------------------------
14
+
15
+ const REASON = Object.freeze({
16
+ OK_VERSION_LIVE: 'ok_version_live',
17
+ FAIL_VERSION_NOT_FOUND: 'fail_version_not_found',
18
+ });
19
+
20
+ // ---- Sleep -------------------------------------------------------------------
21
+
22
+ const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
23
+
24
+ // ---- npm fetchers ------------------------------------------------------------
25
+
26
+ function defaultFetchVersion(pkg, version) {
27
+ try {
28
+ const out = cp.execFileSync('npm', ['view', `${pkg}@${version}`, 'version'],
29
+ { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
30
+ return out || null;
31
+ } catch { return null; }
32
+ }
33
+
34
+ function defaultFetchDistTag(pkg, distTag) {
35
+ try {
36
+ const out = cp.execFileSync('npm', ['view', pkg, 'dist-tags', '--json'],
37
+ { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
38
+ const tags = JSON.parse(out);
39
+ return (tags && typeof tags === 'object' && tags[distTag]) || null;
40
+ } catch { return null; }
41
+ }
42
+
43
+ // ---- Core async function (unit-tested seam) ----------------------------------
44
+
45
+ async function verifyPublish({
46
+ pkg,
47
+ version,
48
+ distTag = null,
49
+ fetchVersion = defaultFetchVersion,
50
+ fetchDistTag = defaultFetchDistTag,
51
+ maxAttempts = 20,
52
+ intervalMs = 5000,
53
+ sleep = defaultSleep,
54
+ }) {
55
+ let attempts = 0;
56
+
57
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
58
+ const found = fetchVersion(pkg, version);
59
+ attempts++;
60
+
61
+ if (found === version) {
62
+ // Version confirmed live — optionally resolve dist-tag informally
63
+ let distTagResult = null;
64
+
65
+ if (distTag && typeof distTag === 'string' && distTag.length > 0) {
66
+ let pointsTo = null;
67
+
68
+ for (let dt = 1; dt <= maxAttempts; dt++) {
69
+ const tagVal = fetchDistTag(pkg, distTag);
70
+ if (tagVal !== null) {
71
+ pointsTo = tagVal;
72
+ break;
73
+ }
74
+ if (dt < maxAttempts) {
75
+ await sleep(intervalMs);
76
+ }
77
+ }
78
+
79
+ distTagResult = {
80
+ name: distTag,
81
+ points_to: pointsTo,
82
+ matches: pointsTo === version,
83
+ };
84
+ }
85
+
86
+ return {
87
+ ok: true,
88
+ reason: REASON.OK_VERSION_LIVE,
89
+ pkg,
90
+ version,
91
+ attempts,
92
+ distTag: distTagResult,
93
+ };
94
+ }
95
+
96
+ // Not found yet — sleep before retry (but not after the final attempt)
97
+ if (attempt < maxAttempts) {
98
+ await sleep(intervalMs);
99
+ }
100
+ }
101
+
102
+ return {
103
+ ok: false,
104
+ reason: REASON.FAIL_VERSION_NOT_FOUND,
105
+ pkg,
106
+ version,
107
+ attempts,
108
+ distTag: null,
109
+ };
110
+ }
111
+
112
+ // ---- Argument parsing --------------------------------------------------------
113
+
114
+ function parseArgs(argv) {
115
+ const opts = {
116
+ pkg: null,
117
+ version: null,
118
+ distTag: null,
119
+ maxAttempts: 20,
120
+ intervalMs: 5000,
121
+ json: false,
122
+ };
123
+
124
+ const args = argv.slice();
125
+ while (args.length > 0) {
126
+ const arg = args.shift();
127
+
128
+ if (arg === '--help' || arg === '-h') {
129
+ process.stdout.write(
130
+ 'Usage: node scripts/verify-npm-publish.cjs --package <pkg> --version <ver> [options]\n' +
131
+ '\n' +
132
+ 'Options:\n' +
133
+ ' --package <s> npm package name (required)\n' +
134
+ ' --version <s> version to verify (required)\n' +
135
+ ' --dist-tag <s> dist-tag to report (optional, informational only)\n' +
136
+ ' --max-attempts <n> max retry attempts (default: 20)\n' +
137
+ ' --interval-ms <n> ms between retries (default: 5000)\n' +
138
+ ' --json emit structured JSON output\n' +
139
+ ' --help, -h show this help\n'
140
+ );
141
+ throw new ExitError(0);
142
+ } else if (arg === '--package') {
143
+ const val = args.shift();
144
+ if (!val || val.startsWith('-')) {
145
+ throw new ExitError(2, 'error: --package requires a value');
146
+ }
147
+ opts.pkg = val;
148
+ } else if (arg === '--version') {
149
+ const val = args.shift();
150
+ if (!val || val.startsWith('-')) {
151
+ throw new ExitError(2, 'error: --version requires a value');
152
+ }
153
+ opts.version = val;
154
+ } else if (arg === '--dist-tag') {
155
+ const val = args.shift();
156
+ if (!val || val.startsWith('-')) {
157
+ throw new ExitError(2, 'error: --dist-tag requires a value');
158
+ }
159
+ opts.distTag = val;
160
+ } else if (arg === '--max-attempts') {
161
+ const val = args.shift();
162
+ if (!val || val.startsWith('-')) {
163
+ throw new ExitError(2, 'error: --max-attempts requires a value');
164
+ }
165
+ const n = parseInt(val, 10);
166
+ if (isNaN(n) || n < 1) {
167
+ throw new ExitError(2, 'error: --max-attempts must be a positive integer');
168
+ }
169
+ opts.maxAttempts = n;
170
+ } else if (arg === '--interval-ms') {
171
+ const val = args.shift();
172
+ if (!val || val.startsWith('-')) {
173
+ throw new ExitError(2, 'error: --interval-ms requires a value');
174
+ }
175
+ const n = parseInt(val, 10);
176
+ if (isNaN(n) || n < 0) {
177
+ throw new ExitError(2, 'error: --interval-ms must be a non-negative integer');
178
+ }
179
+ opts.intervalMs = n;
180
+ } else if (arg === '--json') {
181
+ opts.json = true;
182
+ } else {
183
+ throw new ExitError(2, `unknown argument: ${arg}`);
184
+ }
185
+ }
186
+
187
+ if (!opts.pkg) {
188
+ throw new ExitError(2, 'error: --package is required');
189
+ }
190
+ if (!opts.version) {
191
+ throw new ExitError(2, 'error: --version is required');
192
+ }
193
+
194
+ return opts;
195
+ }
196
+
197
+ // ---- Main entry point --------------------------------------------------------
198
+
199
+ async function main() {
200
+ const opts = parseArgs(process.argv.slice(2));
201
+ const result = await verifyPublish({
202
+ pkg: opts.pkg,
203
+ version: opts.version,
204
+ distTag: opts.distTag,
205
+ maxAttempts: opts.maxAttempts,
206
+ intervalMs: opts.intervalMs,
207
+ });
208
+
209
+ if (opts.json) {
210
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
211
+ } else {
212
+ if (result.ok) {
213
+ process.stdout.write(
214
+ `✓ Verified: ${result.pkg}@${result.version} is live on npm (after ${result.attempts} attempt(s))\n`
215
+ );
216
+ if (result.distTag) {
217
+ process.stdout.write(`✓ ${result.distTag.name} tag points to: ${result.distTag.points_to}\n`);
218
+ if (!result.distTag.matches) {
219
+ process.stdout.write(
220
+ `::warning::${result.distTag.name} dist-tag points to ${result.distTag.points_to}, expected ${result.version}\n`
221
+ );
222
+ }
223
+ }
224
+ } else {
225
+ process.stdout.write(
226
+ `::error::Published version verification failed. ${result.pkg}@${result.version} not found after ${result.attempts} attempt(s)\n`
227
+ );
228
+ }
229
+ }
230
+
231
+ return result.ok ? 0 : 1;
232
+ }
233
+
234
+ // ---- Guard -------------------------------------------------------------------
235
+
236
+ if (require.main === module) {
237
+ runMain(main);
238
+ }
239
+
240
+ module.exports = { verifyPublish, parseArgs, REASON, defaultFetchVersion, defaultFetchDistTag };