@opengsd/gsd-core 1.2.0 → 1.3.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 (532) hide show
  1. package/README.ja-JP.md +46 -791
  2. package/README.ko-KR.md +44 -780
  3. package/README.md +42 -218
  4. package/README.pt-BR.md +47 -414
  5. package/README.zh-CN.md +46 -763
  6. package/agents/gsd-ai-researcher.md +2 -2
  7. package/agents/gsd-debug-session-manager.md +1 -1
  8. package/agents/gsd-debugger.md +8 -8
  9. package/agents/gsd-doc-writer.md +7 -6
  10. package/agents/gsd-domain-researcher.md +15 -2
  11. package/agents/gsd-eval-auditor.md +1 -1
  12. package/agents/gsd-eval-planner.md +2 -2
  13. package/agents/gsd-executor.md +21 -8
  14. package/agents/gsd-framework-selector.md +1 -1
  15. package/agents/gsd-intel-updater.md +4 -4
  16. package/agents/gsd-phase-researcher.md +19 -6
  17. package/agents/gsd-plan-checker.md +3 -3
  18. package/agents/gsd-planner.md +36 -23
  19. package/agents/gsd-project-researcher.md +13 -0
  20. package/agents/gsd-research-synthesizer.md +6 -2
  21. package/agents/gsd-roadmapper.md +6 -6
  22. package/agents/gsd-ui-researcher.md +16 -3
  23. package/agents/gsd-user-profiler.md +2 -2
  24. package/agents/gsd-verifier.md +8 -8
  25. package/assets/gsd-logo-2000-transparent.png +0 -0
  26. package/assets/gsd-logo-2000-transparent.svg +17 -0
  27. package/assets/gsd-logo-2000.png +0 -0
  28. package/assets/gsd-logo-2000.svg +21 -0
  29. package/assets/terminal.svg +68 -0
  30. package/bin/install.js +255 -103
  31. package/commands/gsd/add-tests.md +1 -1
  32. package/commands/gsd/ai-integration-phase.md +3 -3
  33. package/commands/gsd/audit-fix.md +1 -1
  34. package/commands/gsd/audit-milestone.md +1 -1
  35. package/commands/gsd/audit-uat.md +1 -1
  36. package/commands/gsd/autonomous.md +2 -2
  37. package/commands/gsd/capture.md +6 -6
  38. package/commands/gsd/cleanup.md +1 -1
  39. package/commands/gsd/code-review.md +1 -1
  40. package/commands/gsd/complete-milestone.md +2 -2
  41. package/commands/gsd/config.md +3 -3
  42. package/commands/gsd/debug.md +1 -1
  43. package/commands/gsd/discuss-phase.md +5 -4
  44. package/commands/gsd/docs-update.md +1 -1
  45. package/commands/gsd/eval-review.md +2 -2
  46. package/commands/gsd/execute-phase.md +2 -2
  47. package/commands/gsd/explore.md +1 -1
  48. package/commands/gsd/extract-learnings.md +2 -2
  49. package/commands/gsd/fast.md +1 -1
  50. package/commands/gsd/forensics.md +1 -1
  51. package/commands/gsd/graphify.md +9 -9
  52. package/commands/gsd/health.md +1 -1
  53. package/commands/gsd/help.md +2 -2
  54. package/commands/gsd/import.md +5 -5
  55. package/commands/gsd/inbox.md +1 -1
  56. package/commands/gsd/ingest-docs.md +4 -4
  57. package/commands/gsd/manager.md +3 -3
  58. package/commands/gsd/map-codebase.md +1 -1
  59. package/commands/gsd/milestone-summary.md +1 -1
  60. package/commands/gsd/mvp-phase.md +4 -4
  61. package/commands/gsd/new-milestone.md +5 -5
  62. package/commands/gsd/new-project.md +5 -5
  63. package/commands/gsd/pause-work.md +2 -2
  64. package/commands/gsd/phase.md +4 -4
  65. package/commands/gsd/plan-phase.md +2 -2
  66. package/commands/gsd/plan-review-convergence.md +4 -4
  67. package/commands/gsd/pr-branch.md +1 -1
  68. package/commands/gsd/profile-user.md +2 -2
  69. package/commands/gsd/progress.md +4 -4
  70. package/commands/gsd/quick.md +1 -1
  71. package/commands/gsd/resume-work.md +1 -1
  72. package/commands/gsd/review.md +3 -2
  73. package/commands/gsd/secure-phase.md +1 -1
  74. package/commands/gsd/settings.md +1 -1
  75. package/commands/gsd/ship.md +2 -2
  76. package/commands/gsd/sketch.md +7 -7
  77. package/commands/gsd/spec-phase.md +2 -2
  78. package/commands/gsd/spike.md +3 -3
  79. package/commands/gsd/stats.md +1 -1
  80. package/commands/gsd/surface.md +4 -4
  81. package/commands/gsd/thread.md +1 -1
  82. package/commands/gsd/ui-phase.md +2 -2
  83. package/commands/gsd/ui-review.md +2 -2
  84. package/commands/gsd/ultraplan-phase.md +2 -2
  85. package/commands/gsd/undo.md +3 -3
  86. package/commands/gsd/update.md +3 -3
  87. package/commands/gsd/validate-phase.md +1 -1
  88. package/commands/gsd/verify-work.md +2 -2
  89. package/commands/gsd/workspace.md +4 -4
  90. package/{get-shit-done → gsd-core}/bin/check-latest-version.cjs +1 -1
  91. package/{get-shit-done → gsd-core}/bin/gsd-tools.cjs +50 -4
  92. package/gsd-core/bin/lib/active-workstream-store.cjs +291 -0
  93. package/gsd-core/bin/lib/adr-parser.cjs +399 -0
  94. package/gsd-core/bin/lib/agent-command-router.cjs +68 -0
  95. package/gsd-core/bin/lib/artifacts.cjs +51 -0
  96. package/gsd-core/bin/lib/audit.cjs +743 -0
  97. package/gsd-core/bin/lib/check-command-router.cjs +342 -0
  98. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
  99. package/gsd-core/bin/lib/clock.cjs +95 -0
  100. package/gsd-core/bin/lib/clusters.cjs +128 -0
  101. package/gsd-core/bin/lib/code-review-flags.cjs +59 -0
  102. package/gsd-core/bin/lib/command-aliases.cjs +809 -0
  103. package/gsd-core/bin/lib/command-arg-projection.cjs +55 -0
  104. package/gsd-core/bin/lib/command-routing-hub.cjs +300 -0
  105. package/gsd-core/bin/lib/commands.cjs +1202 -0
  106. package/gsd-core/bin/lib/config-schema.cjs +29 -0
  107. package/gsd-core/bin/lib/config-types.cjs +19 -0
  108. package/gsd-core/bin/lib/config.cjs +714 -0
  109. package/{get-shit-done → gsd-core}/bin/lib/configuration.cjs +76 -85
  110. package/gsd-core/bin/lib/context-utilization.cjs +48 -0
  111. package/gsd-core/bin/lib/core.cjs +2007 -0
  112. package/{get-shit-done → gsd-core}/bin/lib/decisions.cjs +9 -7
  113. package/gsd-core/bin/lib/docs.cjs +252 -0
  114. package/gsd-core/bin/lib/drift.cjs +364 -0
  115. package/gsd-core/bin/lib/fallow-runner.cjs +115 -0
  116. package/gsd-core/bin/lib/frontmatter.cjs +442 -0
  117. package/gsd-core/bin/lib/gap-checker.cjs +257 -0
  118. package/gsd-core/bin/lib/graphify.cjs +496 -0
  119. package/gsd-core/bin/lib/gsd2-import.cjs +456 -0
  120. package/gsd-core/bin/lib/init-command-router.cjs +62 -0
  121. package/gsd-core/bin/lib/init.cjs +1799 -0
  122. package/gsd-core/bin/lib/install-profiles.cjs +526 -0
  123. package/gsd-core/bin/lib/installer-migration-authoring.cjs +122 -0
  124. package/gsd-core/bin/lib/installer-migration-report.cjs +347 -0
  125. package/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +218 -0
  126. package/gsd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
  127. package/gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
  128. package/gsd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
  129. package/gsd-core/bin/lib/installer-migrations.cjs +784 -0
  130. package/gsd-core/bin/lib/intel.cjs +607 -0
  131. package/gsd-core/bin/lib/learnings.cjs +270 -0
  132. package/gsd-core/bin/lib/legacy-cleanup.cjs +253 -0
  133. package/gsd-core/bin/lib/milestone.cjs +373 -0
  134. package/gsd-core/bin/lib/model-catalog.cjs +154 -0
  135. package/gsd-core/bin/lib/model-profiles.cjs +24 -0
  136. package/gsd-core/bin/lib/observability/event.cjs +51 -0
  137. package/gsd-core/bin/lib/observability/logger.cjs +146 -0
  138. package/{get-shit-done → gsd-core}/bin/lib/observability/redaction.cjs +19 -21
  139. package/{get-shit-done → gsd-core}/bin/lib/package-identity.cjs +5 -1
  140. package/gsd-core/bin/lib/phase-command-router.cjs +189 -0
  141. package/gsd-core/bin/lib/phase-lifecycle.cjs +74 -0
  142. package/gsd-core/bin/lib/phase.cjs +1307 -0
  143. package/gsd-core/bin/lib/phases-command-router.cjs +43 -0
  144. package/{get-shit-done → gsd-core}/bin/lib/plan-scan.cjs +18 -24
  145. package/gsd-core/bin/lib/planning-workspace.cjs +245 -0
  146. package/gsd-core/bin/lib/profile-output.cjs +1120 -0
  147. package/gsd-core/bin/lib/profile-pipeline.cjs +517 -0
  148. package/gsd-core/bin/lib/project-root.cjs +119 -0
  149. package/gsd-core/bin/lib/prompt-budget.cjs +305 -0
  150. package/gsd-core/bin/lib/review-reviewer-selection.cjs +121 -0
  151. package/gsd-core/bin/lib/roadmap-command-router.cjs +166 -0
  152. package/gsd-core/bin/lib/roadmap-upgrade.cjs +491 -0
  153. package/gsd-core/bin/lib/roadmap.cjs +600 -0
  154. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +254 -0
  155. package/gsd-core/bin/lib/runtime-homes.cjs +169 -0
  156. package/gsd-core/bin/lib/runtime-name-policy.cjs +96 -0
  157. package/gsd-core/bin/lib/runtime-slash.cjs +119 -0
  158. package/{get-shit-done → gsd-core}/bin/lib/schema-detect.cjs +20 -26
  159. package/gsd-core/bin/lib/secrets.cjs +34 -0
  160. package/gsd-core/bin/lib/security.cjs +407 -0
  161. package/gsd-core/bin/lib/semver-compare.cjs +42 -0
  162. package/gsd-core/bin/lib/shell-command-projection.cjs +524 -0
  163. package/gsd-core/bin/lib/state-command-router.cjs +160 -0
  164. package/{get-shit-done → gsd-core}/bin/lib/state-document.cjs +78 -82
  165. package/gsd-core/bin/lib/state.cjs +2010 -0
  166. package/gsd-core/bin/lib/surface.cjs +406 -0
  167. package/gsd-core/bin/lib/task-command-router.cjs +85 -0
  168. package/gsd-core/bin/lib/template.cjs +237 -0
  169. package/gsd-core/bin/lib/uat.cjs +297 -0
  170. package/gsd-core/bin/lib/ui-safety-gate.cjs +98 -0
  171. package/gsd-core/bin/lib/update-context.cjs +218 -0
  172. package/gsd-core/bin/lib/validate-command-router.cjs +91 -0
  173. package/gsd-core/bin/lib/validate.cjs +112 -0
  174. package/gsd-core/bin/lib/verify-command-router.cjs +44 -0
  175. package/gsd-core/bin/lib/verify.cjs +1451 -0
  176. package/{get-shit-done → gsd-core}/bin/lib/workstream-inventory-builder.cjs +19 -12
  177. package/gsd-core/bin/lib/workstream-inventory.cjs +147 -0
  178. package/{get-shit-done → gsd-core}/bin/lib/workstream-name-policy.cjs +28 -31
  179. package/gsd-core/bin/lib/workstream.cjs +380 -0
  180. package/gsd-core/bin/lib/worktree-safety.cjs +912 -0
  181. package/{get-shit-done → gsd-core}/bin/shared/config-defaults.manifest.json +1 -0
  182. package/{get-shit-done → gsd-core}/bin/shared/config-schema.manifest.json +17 -1
  183. package/{get-shit-done → gsd-core}/bin/shared/model-catalog.json +27 -0
  184. package/{get-shit-done → gsd-core}/references/artifact-types.md +1 -1
  185. package/{get-shit-done → gsd-core}/references/checkpoints.md +1 -1
  186. package/{get-shit-done → gsd-core}/references/few-shot-examples/plan-checker.md +2 -2
  187. package/{get-shit-done → gsd-core}/references/few-shot-examples/verifier.md +12 -12
  188. package/{get-shit-done → gsd-core}/references/model-profile-resolution.md +1 -1
  189. package/{get-shit-done → gsd-core}/references/mvp-concepts.md +1 -1
  190. package/{get-shit-done → gsd-core}/references/planner-graphify-auto-update.md +2 -2
  191. package/{get-shit-done → gsd-core}/references/planner-human-verify-mode.md +1 -1
  192. package/{get-shit-done → gsd-core}/references/planner-mvp-mode.md +1 -1
  193. package/{get-shit-done → gsd-core}/references/ui-brand.md +4 -2
  194. package/{get-shit-done → gsd-core}/references/verification-patterns.md +1 -1
  195. package/gsd-core/references/worktree-branch-check.md +38 -0
  196. package/{get-shit-done → gsd-core}/references/worktree-path-safety.md +4 -26
  197. package/{get-shit-done → gsd-core}/templates/README.md +2 -2
  198. package/{get-shit-done → gsd-core}/templates/codebase/structure.md +10 -10
  199. package/{get-shit-done → gsd-core}/templates/copilot-instructions.md +1 -1
  200. package/{get-shit-done → gsd-core}/templates/phase-prompt.md +10 -10
  201. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -0
  202. package/{get-shit-done → gsd-core}/workflows/add-backlog.md +1 -1
  203. package/{get-shit-done → gsd-core}/workflows/add-phase.md +1 -1
  204. package/{get-shit-done → gsd-core}/workflows/add-tests.md +1 -1
  205. package/{get-shit-done → gsd-core}/workflows/add-todo.md +1 -1
  206. package/{get-shit-done → gsd-core}/workflows/ai-integration-phase.md +4 -4
  207. package/{get-shit-done → gsd-core}/workflows/audit-fix.md +2 -2
  208. package/{get-shit-done → gsd-core}/workflows/audit-milestone.md +3 -1
  209. package/{get-shit-done → gsd-core}/workflows/audit-uat.md +1 -1
  210. package/{get-shit-done → gsd-core}/workflows/autonomous.md +10 -8
  211. package/{get-shit-done → gsd-core}/workflows/check-todos.md +1 -1
  212. package/{get-shit-done → gsd-core}/workflows/cleanup.md +44 -4
  213. package/{get-shit-done → gsd-core}/workflows/code-review-fix.md +4 -4
  214. package/{get-shit-done → gsd-core}/workflows/code-review.md +6 -4
  215. package/{get-shit-done → gsd-core}/workflows/complete-milestone.md +2 -2
  216. package/{get-shit-done → gsd-core}/workflows/debug.md +7 -2
  217. package/{get-shit-done → gsd-core}/workflows/diagnose-issues.md +6 -2
  218. package/{get-shit-done → gsd-core}/workflows/discovery-phase.md +5 -5
  219. package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/advisor.md +5 -5
  220. package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/auto.md +1 -1
  221. package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/chain.md +1 -1
  222. package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/power.md +1 -1
  223. package/{get-shit-done → gsd-core}/workflows/discuss-phase-assumptions.md +4 -4
  224. package/{get-shit-done → gsd-core}/workflows/discuss-phase.md +6 -6
  225. package/{get-shit-done → gsd-core}/workflows/do.md +1 -1
  226. package/{get-shit-done → gsd-core}/workflows/docs-update.md +19 -5
  227. package/{get-shit-done → gsd-core}/workflows/edit-phase.md +1 -1
  228. package/{get-shit-done → gsd-core}/workflows/eval-review.md +3 -3
  229. package/{get-shit-done → gsd-core}/workflows/execute-phase/steps/codebase-drift-gate.md +16 -3
  230. package/{get-shit-done → gsd-core}/workflows/execute-phase/steps/post-merge-gate.md +1 -1
  231. package/{get-shit-done → gsd-core}/workflows/execute-phase.md +89 -57
  232. package/{get-shit-done → gsd-core}/workflows/execute-plan.md +8 -8
  233. package/{get-shit-done → gsd-core}/workflows/explore.md +5 -3
  234. package/{get-shit-done → gsd-core}/workflows/extract-learnings.md +1 -1
  235. package/{get-shit-done → gsd-core}/workflows/forensics.md +1 -1
  236. package/{get-shit-done → gsd-core}/workflows/graduation.md +1 -1
  237. package/{get-shit-done → gsd-core}/workflows/health.md +1 -1
  238. package/{get-shit-done → gsd-core}/workflows/help/modes/default.md +3 -3
  239. package/{get-shit-done → gsd-core}/workflows/help/modes/full.md +6 -6
  240. package/{get-shit-done → gsd-core}/workflows/import.md +3 -1
  241. package/{get-shit-done → gsd-core}/workflows/ingest-docs.md +5 -5
  242. package/{get-shit-done → gsd-core}/workflows/insert-phase.md +1 -1
  243. package/{get-shit-done → gsd-core}/workflows/list-workspaces.md +1 -1
  244. package/{get-shit-done → gsd-core}/workflows/manager.md +3 -3
  245. package/{get-shit-done → gsd-core}/workflows/map-codebase.md +3 -1
  246. package/{get-shit-done → gsd-core}/workflows/milestone-summary.md +1 -1
  247. package/{get-shit-done → gsd-core}/workflows/mvp-phase.md +7 -7
  248. package/{get-shit-done → gsd-core}/workflows/new-milestone.md +5 -5
  249. package/{get-shit-done → gsd-core}/workflows/new-project.md +8 -8
  250. package/{get-shit-done → gsd-core}/workflows/new-workspace.md +1 -1
  251. package/{get-shit-done → gsd-core}/workflows/next.md +1 -1
  252. package/{get-shit-done → gsd-core}/workflows/pause-work.md +1 -1
  253. package/{get-shit-done → gsd-core}/workflows/plan-milestone-gaps.md +1 -1
  254. package/{get-shit-done → gsd-core}/workflows/plan-phase.md +29 -28
  255. package/{get-shit-done → gsd-core}/workflows/plan-review-convergence.md +10 -10
  256. package/{get-shit-done → gsd-core}/workflows/plant-seed.md +1 -1
  257. package/{get-shit-done → gsd-core}/workflows/profile-user.md +11 -11
  258. package/{get-shit-done → gsd-core}/workflows/progress.md +1 -1
  259. package/{get-shit-done → gsd-core}/workflows/quick.md +7 -29
  260. package/{get-shit-done → gsd-core}/workflows/reapply-patches.md +2 -2
  261. package/{get-shit-done → gsd-core}/workflows/remove-phase.md +1 -1
  262. package/{get-shit-done → gsd-core}/workflows/remove-workspace.md +1 -1
  263. package/{get-shit-done → gsd-core}/workflows/resume-project.md +2 -2
  264. package/{get-shit-done → gsd-core}/workflows/review.md +110 -2
  265. package/{get-shit-done → gsd-core}/workflows/scan.md +3 -1
  266. package/{get-shit-done → gsd-core}/workflows/secure-phase.md +5 -3
  267. package/{get-shit-done → gsd-core}/workflows/settings-advanced.md +196 -6
  268. package/{get-shit-done → gsd-core}/workflows/settings-integrations.md +2 -2
  269. package/{get-shit-done → gsd-core}/workflows/settings.md +16 -2
  270. package/{get-shit-done → gsd-core}/workflows/ship.md +56 -4
  271. package/{get-shit-done → gsd-core}/workflows/sketch-wrap-up.md +1 -1
  272. package/{get-shit-done → gsd-core}/workflows/sketch.md +5 -5
  273. package/{get-shit-done → gsd-core}/workflows/spec-phase.md +2 -2
  274. package/{get-shit-done → gsd-core}/workflows/spike-wrap-up.md +1 -1
  275. package/{get-shit-done → gsd-core}/workflows/spike.md +1 -1
  276. package/{get-shit-done → gsd-core}/workflows/stats.md +1 -1
  277. package/{get-shit-done → gsd-core}/workflows/sync-skills.md +3 -3
  278. package/{get-shit-done → gsd-core}/workflows/thread.md +1 -1
  279. package/{get-shit-done → gsd-core}/workflows/transition.md +2 -2
  280. package/{get-shit-done → gsd-core}/workflows/ui-phase.md +5 -5
  281. package/{get-shit-done → gsd-core}/workflows/ui-review.md +3 -3
  282. package/{get-shit-done → gsd-core}/workflows/ultraplan-phase.md +1 -1
  283. package/{get-shit-done → gsd-core}/workflows/undo.md +2 -2
  284. package/{get-shit-done → gsd-core}/workflows/update.md +41 -16
  285. package/{get-shit-done → gsd-core}/workflows/validate-phase.md +5 -3
  286. package/{get-shit-done → gsd-core}/workflows/verify-phase.md +4 -4
  287. package/{get-shit-done → gsd-core}/workflows/verify-work.md +7 -7
  288. package/hooks/dist/gsd-check-update-worker.js +16 -3
  289. package/hooks/dist/gsd-check-update.js +7 -5
  290. package/hooks/dist/gsd-context-monitor.js +2 -2
  291. package/hooks/dist/gsd-statusline.js +39 -21
  292. package/hooks/dist/gsd-update-banner.js +6 -2
  293. package/hooks/dist/gsd-worktree-path-guard.js +169 -0
  294. package/hooks/dist/managed-hooks-registry.cjs +35 -0
  295. package/hooks/gsd-check-update-worker.js +16 -3
  296. package/hooks/gsd-check-update.js +7 -5
  297. package/hooks/gsd-context-monitor.js +2 -2
  298. package/hooks/gsd-statusline.js +39 -21
  299. package/hooks/gsd-update-banner.js +6 -2
  300. package/hooks/gsd-worktree-path-guard.js +169 -0
  301. package/hooks/managed-hooks-registry.cjs +1 -0
  302. package/package.json +17 -11
  303. package/scripts/affected-tests-lib.cjs +1 -1
  304. package/scripts/base64-scan.sh +12 -0
  305. package/scripts/build-hooks.js +5 -1
  306. package/scripts/changeset/cli.cjs +2 -2
  307. package/scripts/changeset/github-release-notes.cjs +1 -1
  308. package/scripts/changeset/lint.cjs +1 -1
  309. package/scripts/check-alias-drift.cjs +8 -8
  310. package/scripts/check-env.cjs +5 -1
  311. package/scripts/ci-test-scope.cjs +34 -9
  312. package/scripts/command-contract-helpers.cjs +1 -1
  313. package/scripts/fix-slash-commands.cjs +5 -5
  314. package/scripts/gen-inventory-manifest.cjs +3 -3
  315. package/scripts/generate-package-identity.cjs +28 -7
  316. package/scripts/lib/allowlist-ratchet.cjs +136 -0
  317. package/scripts/lint-command-contract.cjs +1 -1
  318. package/scripts/lint-legacy-dir-name.cjs +156 -0
  319. package/scripts/lint-package-identity-drift.cjs +8 -8
  320. package/scripts/lint-pr-check-project-dir.cjs +0 -1
  321. package/scripts/lint-shell-command-projection-drift.cjs +1 -1
  322. package/scripts/lint-skill-deps.cjs +1 -1
  323. package/scripts/lint-test-file-count.allowlist.json +129 -32
  324. package/scripts/lint-test-file-count.cjs +85 -30
  325. package/scripts/mutation-matrix.cjs +219 -0
  326. package/scripts/prompt-injection-scan.sh +5 -1
  327. package/scripts/release-notes/format-github-release-notes.cjs +256 -0
  328. package/scripts/release-tarball-smoke.cjs +9 -9
  329. package/scripts/run-tests.cjs +34 -2
  330. package/scripts/strip-prose-atrefs.cjs +2 -2
  331. package/scripts/sync-runtime-launcher.cjs +2 -2
  332. package/scripts/verify-npm-publish.cjs +252 -0
  333. package/get-shit-done/bin/lib/active-workstream-store.cjs +0 -302
  334. package/get-shit-done/bin/lib/adr-parser.cjs +0 -394
  335. package/get-shit-done/bin/lib/agent-command-router.cjs +0 -65
  336. package/get-shit-done/bin/lib/artifacts.cjs +0 -53
  337. package/get-shit-done/bin/lib/audit.cjs +0 -755
  338. package/get-shit-done/bin/lib/check-command-router.cjs +0 -333
  339. package/get-shit-done/bin/lib/cjs-command-router-adapter.cjs +0 -118
  340. package/get-shit-done/bin/lib/clock.cjs +0 -96
  341. package/get-shit-done/bin/lib/clusters.cjs +0 -135
  342. package/get-shit-done/bin/lib/code-review-flags.cjs +0 -74
  343. package/get-shit-done/bin/lib/command-aliases.cjs +0 -815
  344. package/get-shit-done/bin/lib/command-arg-projection.cjs +0 -62
  345. package/get-shit-done/bin/lib/command-routing-hub.cjs +0 -388
  346. package/get-shit-done/bin/lib/commands.cjs +0 -1188
  347. package/get-shit-done/bin/lib/config-schema.cjs +0 -31
  348. package/get-shit-done/bin/lib/config.cjs +0 -728
  349. package/get-shit-done/bin/lib/context-utilization.cjs +0 -47
  350. package/get-shit-done/bin/lib/core.cjs +0 -2121
  351. package/get-shit-done/bin/lib/docs.cjs +0 -270
  352. package/get-shit-done/bin/lib/drift.cjs +0 -388
  353. package/get-shit-done/bin/lib/fallow-runner.cjs +0 -109
  354. package/get-shit-done/bin/lib/frontmatter.cjs +0 -389
  355. package/get-shit-done/bin/lib/gap-checker.cjs +0 -205
  356. package/get-shit-done/bin/lib/graphify.cjs +0 -592
  357. package/get-shit-done/bin/lib/gsd2-import.cjs +0 -514
  358. package/get-shit-done/bin/lib/init-command-router.cjs +0 -58
  359. package/get-shit-done/bin/lib/init.cjs +0 -2112
  360. package/get-shit-done/bin/lib/install-profiles.cjs +0 -603
  361. package/get-shit-done/bin/lib/installer-migration-authoring.cjs +0 -117
  362. package/get-shit-done/bin/lib/installer-migration-report.cjs +0 -354
  363. package/get-shit-done/bin/lib/installer-migrations/000-first-time-baseline.cjs +0 -220
  364. package/get-shit-done/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +0 -41
  365. package/get-shit-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +0 -80
  366. package/get-shit-done/bin/lib/installer-migrations.cjs +0 -778
  367. package/get-shit-done/bin/lib/intel.cjs +0 -708
  368. package/get-shit-done/bin/lib/learnings.cjs +0 -421
  369. package/get-shit-done/bin/lib/milestone.cjs +0 -314
  370. package/get-shit-done/bin/lib/model-catalog.cjs +0 -212
  371. package/get-shit-done/bin/lib/model-profiles.cjs +0 -31
  372. package/get-shit-done/bin/lib/observability/event.cjs +0 -82
  373. package/get-shit-done/bin/lib/observability/logger.cjs +0 -174
  374. package/get-shit-done/bin/lib/phase-command-router.cjs +0 -191
  375. package/get-shit-done/bin/lib/phase-lifecycle.cjs +0 -80
  376. package/get-shit-done/bin/lib/phase.cjs +0 -1607
  377. package/get-shit-done/bin/lib/phases-command-router.cjs +0 -39
  378. package/get-shit-done/bin/lib/planning-workspace.cjs +0 -238
  379. package/get-shit-done/bin/lib/profile-output.cjs +0 -1141
  380. package/get-shit-done/bin/lib/profile-pipeline.cjs +0 -539
  381. package/get-shit-done/bin/lib/project-root.cjs +0 -112
  382. package/get-shit-done/bin/lib/prompt-budget.cjs +0 -399
  383. package/get-shit-done/bin/lib/review-reviewer-selection.cjs +0 -125
  384. package/get-shit-done/bin/lib/roadmap-command-router.cjs +0 -28
  385. package/get-shit-done/bin/lib/roadmap.cjs +0 -650
  386. package/get-shit-done/bin/lib/runtime-artifact-layout.cjs +0 -301
  387. package/get-shit-done/bin/lib/runtime-homes.cjs +0 -222
  388. package/get-shit-done/bin/lib/runtime-name-policy.cjs +0 -83
  389. package/get-shit-done/bin/lib/runtime-slash.cjs +0 -112
  390. package/get-shit-done/bin/lib/secrets.cjs +0 -32
  391. package/get-shit-done/bin/lib/security.cjs +0 -600
  392. package/get-shit-done/bin/lib/semver-compare.cjs +0 -35
  393. package/get-shit-done/bin/lib/shell-command-projection.cjs +0 -500
  394. package/get-shit-done/bin/lib/state-command-router.cjs +0 -252
  395. package/get-shit-done/bin/lib/state.cjs +0 -2038
  396. package/get-shit-done/bin/lib/surface.cjs +0 -470
  397. package/get-shit-done/bin/lib/task-command-router.cjs +0 -81
  398. package/get-shit-done/bin/lib/template.cjs +0 -228
  399. package/get-shit-done/bin/lib/uat.cjs +0 -289
  400. package/get-shit-done/bin/lib/update-context.cjs +0 -209
  401. package/get-shit-done/bin/lib/validate-command-router.cjs +0 -83
  402. package/get-shit-done/bin/lib/validate.cjs +0 -92
  403. package/get-shit-done/bin/lib/verify-command-router.cjs +0 -40
  404. package/get-shit-done/bin/lib/verify.cjs +0 -1511
  405. package/get-shit-done/bin/lib/workstream-inventory.cjs +0 -146
  406. package/get-shit-done/bin/lib/workstream.cjs +0 -389
  407. package/get-shit-done/bin/lib/worktree-safety.cjs +0 -985
  408. package/get-shit-done/workflows/_runtime-launcher.snippet.sh +0 -1
  409. package/scripts/lint-no-source-grep-extras.cjs +0 -81
  410. package/scripts/lint-no-source-grep.cjs +0 -174
  411. package/scripts/lint-shared-module-handsync.cjs +0 -388
  412. package/scripts/shared-module-handsync-allowlist.json +0 -183
  413. /package/{get-shit-done → gsd-core}/bin/shared/runtime-aliases.manifest.json +0 -0
  414. /package/{get-shit-done → gsd-core}/bin/verify-reapply-patches.cjs +0 -0
  415. /package/{get-shit-done → gsd-core}/contexts/dev.md +0 -0
  416. /package/{get-shit-done → gsd-core}/contexts/research.md +0 -0
  417. /package/{get-shit-done → gsd-core}/contexts/review.md +0 -0
  418. /package/{get-shit-done → gsd-core}/references/agent-contracts.md +0 -0
  419. /package/{get-shit-done → gsd-core}/references/ai-evals.md +0 -0
  420. /package/{get-shit-done → gsd-core}/references/ai-frameworks.md +0 -0
  421. /package/{get-shit-done → gsd-core}/references/autonomous-smart-discuss.md +0 -0
  422. /package/{get-shit-done → gsd-core}/references/common-bug-patterns.md +0 -0
  423. /package/{get-shit-done → gsd-core}/references/context-budget.md +0 -0
  424. /package/{get-shit-done → gsd-core}/references/continuation-format.md +0 -0
  425. /package/{get-shit-done → gsd-core}/references/debugger-philosophy.md +0 -0
  426. /package/{get-shit-done → gsd-core}/references/decimal-phase-calculation.md +0 -0
  427. /package/{get-shit-done → gsd-core}/references/doc-conflict-engine.md +0 -0
  428. /package/{get-shit-done → gsd-core}/references/domain-probes.md +0 -0
  429. /package/{get-shit-done → gsd-core}/references/execute-mvp-tdd.md +0 -0
  430. /package/{get-shit-done → gsd-core}/references/executor-examples.md +0 -0
  431. /package/{get-shit-done → gsd-core}/references/gate-prompts.md +0 -0
  432. /package/{get-shit-done → gsd-core}/references/gates.md +0 -0
  433. /package/{get-shit-done → gsd-core}/references/git-integration.md +0 -0
  434. /package/{get-shit-done → gsd-core}/references/git-planning-commit.md +0 -0
  435. /package/{get-shit-done → gsd-core}/references/ios-scaffold.md +0 -0
  436. /package/{get-shit-done → gsd-core}/references/mandatory-initial-read.md +0 -0
  437. /package/{get-shit-done → gsd-core}/references/model-profiles.md +0 -0
  438. /package/{get-shit-done → gsd-core}/references/phase-argument-parsing.md +0 -0
  439. /package/{get-shit-done → gsd-core}/references/planner-antipatterns.md +0 -0
  440. /package/{get-shit-done → gsd-core}/references/planner-chunked.md +0 -0
  441. /package/{get-shit-done → gsd-core}/references/planner-gap-closure.md +0 -0
  442. /package/{get-shit-done → gsd-core}/references/planner-interface-context.md +0 -0
  443. /package/{get-shit-done → gsd-core}/references/planner-reviews.md +0 -0
  444. /package/{get-shit-done → gsd-core}/references/planner-revision.md +0 -0
  445. /package/{get-shit-done → gsd-core}/references/planner-source-audit.md +0 -0
  446. /package/{get-shit-done → gsd-core}/references/planning-config.md +0 -0
  447. /package/{get-shit-done → gsd-core}/references/project-skills-discovery.md +0 -0
  448. /package/{get-shit-done → gsd-core}/references/questioning.md +0 -0
  449. /package/{get-shit-done → gsd-core}/references/revision-loop.md +0 -0
  450. /package/{get-shit-done → gsd-core}/references/scout-codebase.md +0 -0
  451. /package/{get-shit-done → gsd-core}/references/skeleton-template.md +0 -0
  452. /package/{get-shit-done → gsd-core}/references/sketch-interactivity.md +0 -0
  453. /package/{get-shit-done → gsd-core}/references/sketch-theme-system.md +0 -0
  454. /package/{get-shit-done → gsd-core}/references/sketch-tooling.md +0 -0
  455. /package/{get-shit-done → gsd-core}/references/sketch-variant-patterns.md +0 -0
  456. /package/{get-shit-done → gsd-core}/references/spidr-splitting.md +0 -0
  457. /package/{get-shit-done → gsd-core}/references/tdd.md +0 -0
  458. /package/{get-shit-done → gsd-core}/references/thinking-models-debug.md +0 -0
  459. /package/{get-shit-done → gsd-core}/references/thinking-models-execution.md +0 -0
  460. /package/{get-shit-done → gsd-core}/references/thinking-models-planning.md +0 -0
  461. /package/{get-shit-done → gsd-core}/references/thinking-models-research.md +0 -0
  462. /package/{get-shit-done → gsd-core}/references/thinking-models-verification.md +0 -0
  463. /package/{get-shit-done → gsd-core}/references/thinking-partner.md +0 -0
  464. /package/{get-shit-done → gsd-core}/references/universal-anti-patterns.md +0 -0
  465. /package/{get-shit-done → gsd-core}/references/user-profiling.md +0 -0
  466. /package/{get-shit-done → gsd-core}/references/user-story-template.md +0 -0
  467. /package/{get-shit-done → gsd-core}/references/verification-overrides.md +0 -0
  468. /package/{get-shit-done → gsd-core}/references/verify-mvp-mode.md +0 -0
  469. /package/{get-shit-done → gsd-core}/references/workstream-flag.md +0 -0
  470. /package/{get-shit-done → gsd-core}/templates/AI-SPEC.md +0 -0
  471. /package/{get-shit-done → gsd-core}/templates/DEBUG.md +0 -0
  472. /package/{get-shit-done → gsd-core}/templates/SECURITY.md +0 -0
  473. /package/{get-shit-done → gsd-core}/templates/UAT.md +0 -0
  474. /package/{get-shit-done → gsd-core}/templates/UI-SPEC.md +0 -0
  475. /package/{get-shit-done → gsd-core}/templates/VALIDATION.md +0 -0
  476. /package/{get-shit-done → gsd-core}/templates/claude-md.md +0 -0
  477. /package/{get-shit-done → gsd-core}/templates/codebase/architecture.md +0 -0
  478. /package/{get-shit-done → gsd-core}/templates/codebase/concerns.md +0 -0
  479. /package/{get-shit-done → gsd-core}/templates/codebase/conventions.md +0 -0
  480. /package/{get-shit-done → gsd-core}/templates/codebase/integrations.md +0 -0
  481. /package/{get-shit-done → gsd-core}/templates/codebase/stack.md +0 -0
  482. /package/{get-shit-done → gsd-core}/templates/codebase/testing.md +0 -0
  483. /package/{get-shit-done → gsd-core}/templates/config.json +0 -0
  484. /package/{get-shit-done → gsd-core}/templates/context.md +0 -0
  485. /package/{get-shit-done → gsd-core}/templates/continue-here.md +0 -0
  486. /package/{get-shit-done → gsd-core}/templates/debug-subagent-prompt.md +0 -0
  487. /package/{get-shit-done → gsd-core}/templates/dev-preferences.md +0 -0
  488. /package/{get-shit-done → gsd-core}/templates/discovery.md +0 -0
  489. /package/{get-shit-done → gsd-core}/templates/discussion-log.md +0 -0
  490. /package/{get-shit-done → gsd-core}/templates/milestone-archive.md +0 -0
  491. /package/{get-shit-done → gsd-core}/templates/milestone.md +0 -0
  492. /package/{get-shit-done → gsd-core}/templates/planner-subagent-prompt.md +0 -0
  493. /package/{get-shit-done → gsd-core}/templates/project.md +0 -0
  494. /package/{get-shit-done → gsd-core}/templates/requirements.md +0 -0
  495. /package/{get-shit-done → gsd-core}/templates/research-project/ARCHITECTURE.md +0 -0
  496. /package/{get-shit-done → gsd-core}/templates/research-project/FEATURES.md +0 -0
  497. /package/{get-shit-done → gsd-core}/templates/research-project/PITFALLS.md +0 -0
  498. /package/{get-shit-done → gsd-core}/templates/research-project/STACK.md +0 -0
  499. /package/{get-shit-done → gsd-core}/templates/research-project/SUMMARY.md +0 -0
  500. /package/{get-shit-done → gsd-core}/templates/research.md +0 -0
  501. /package/{get-shit-done → gsd-core}/templates/retrospective.md +0 -0
  502. /package/{get-shit-done → gsd-core}/templates/roadmap.md +0 -0
  503. /package/{get-shit-done → gsd-core}/templates/spec.md +0 -0
  504. /package/{get-shit-done → gsd-core}/templates/state.md +0 -0
  505. /package/{get-shit-done → gsd-core}/templates/summary-complex.md +0 -0
  506. /package/{get-shit-done → gsd-core}/templates/summary-minimal.md +0 -0
  507. /package/{get-shit-done → gsd-core}/templates/summary-standard.md +0 -0
  508. /package/{get-shit-done → gsd-core}/templates/summary.md +0 -0
  509. /package/{get-shit-done → gsd-core}/templates/user-profile.md +0 -0
  510. /package/{get-shit-done → gsd-core}/templates/user-setup.md +0 -0
  511. /package/{get-shit-done → gsd-core}/templates/verification-report.md +0 -0
  512. /package/{get-shit-done → gsd-core}/workflows/analyze-dependencies.md +0 -0
  513. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/all.md +0 -0
  514. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/analyze.md +0 -0
  515. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/batch.md +0 -0
  516. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/default.md +0 -0
  517. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/text.md +0 -0
  518. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/templates/checkpoint.json +0 -0
  519. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/templates/context.md +0 -0
  520. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/templates/discussion-log.md +0 -0
  521. /package/{get-shit-done → gsd-core}/workflows/discuss-phase-power.md +0 -0
  522. /package/{get-shit-done → gsd-core}/workflows/execute-phase/steps/per-plan-worktree-gate.md +0 -0
  523. /package/{get-shit-done → gsd-core}/workflows/fast.md +0 -0
  524. /package/{get-shit-done → gsd-core}/workflows/help/modes/brief.md +0 -0
  525. /package/{get-shit-done → gsd-core}/workflows/help/modes/topic.md +0 -0
  526. /package/{get-shit-done → gsd-core}/workflows/help.md +0 -0
  527. /package/{get-shit-done → gsd-core}/workflows/inbox.md +0 -0
  528. /package/{get-shit-done → gsd-core}/workflows/list-phase-assumptions.md +0 -0
  529. /package/{get-shit-done → gsd-core}/workflows/node-repair.md +0 -0
  530. /package/{get-shit-done → gsd-core}/workflows/note.md +0 -0
  531. /package/{get-shit-done → gsd-core}/workflows/pr-branch.md +0 -0
  532. /package/{get-shit-done → gsd-core}/workflows/session-report.md +0 -0
@@ -1,13 +1,19 @@
1
- 'use strict';
2
-
1
+ "use strict";
3
2
  /**
4
3
  * Schema Drift Detection — detects schema-relevant file changes and verifies
5
- * that the appropriate database push command was executed during a phase.
4
+ * that the appropriate database push command was executed during a phase
5
+ * (ADR-457 build-at-publish: the hand-written bin/lib/schema-detect.cjs
6
+ * collapsed to a TypeScript source of truth). Behaviour is preserved
7
+ * byte-for-behaviour from the prior hand-written .cjs; only types are added.
8
+ *
6
9
  * This module does not read the filesystem directly.
7
10
  */
8
-
9
- // ─── ORM Patterns ───────────────────────────────────────────────────────────
10
- const SCHEMA_PATTERNS = [
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ORM_INFO = exports.SCHEMA_PATTERNS = void 0;
13
+ exports.detectSchemaFiles = detectSchemaFiles;
14
+ exports.detectSchemaOrm = detectSchemaOrm;
15
+ exports.checkSchemaDrift = checkSchemaDrift;
16
+ exports.SCHEMA_PATTERNS = [
11
17
  { pattern: /^src\/collections\/.*\.ts$/, orm: 'payload' },
12
18
  { pattern: /^src\/globals\/.*\.ts$/, orm: 'payload' },
13
19
  { pattern: /^prisma\/schema\.prisma$/, orm: 'prisma' },
@@ -19,9 +25,7 @@ const SCHEMA_PATTERNS = [
19
25
  { pattern: /^src\/entities\/.*\.ts$/, orm: 'typeorm' },
20
26
  { pattern: /^src\/migrations\/.*\.ts$/, orm: 'typeorm' },
21
27
  ];
22
-
23
- // ─── Push Commands & Evidence Patterns ──────────────────────────────────────
24
- const ORM_INFO = {
28
+ exports.ORM_INFO = {
25
29
  payload: {
26
30
  pushCommand: 'npx payload migrate',
27
31
  envHint: 'CI=true PAYLOAD_MIGRATING=true npx payload migrate',
@@ -53,14 +57,12 @@ const ORM_INFO = {
53
57
  evidencePatterns: [/typeorm\s+migration:run/i, /typeorm\s+schema:sync/i],
54
58
  },
55
59
  };
56
-
57
- // ─── Public API ──────────────────────────────────────────────────────────────
58
60
  function detectSchemaFiles(files) {
59
61
  const matches = [];
60
62
  const orms = new Set();
61
63
  for (const rawFile of files) {
62
64
  const file = rawFile.replace(/\\/g, '/');
63
- for (const { pattern, orm } of SCHEMA_PATTERNS) {
65
+ for (const { pattern, orm } of exports.SCHEMA_PATTERNS) {
64
66
  if (pattern.test(file)) {
65
67
  matches.push(rawFile);
66
68
  orms.add(orm);
@@ -74,11 +76,9 @@ function detectSchemaFiles(files) {
74
76
  orms: [...orms],
75
77
  };
76
78
  }
77
-
78
79
  function detectSchemaOrm(ormName) {
79
- return ORM_INFO[ormName] || null;
80
+ return exports.ORM_INFO[ormName] || null;
80
81
  }
81
-
82
82
  function checkSchemaDrift(changedFiles, executionLog, options = {}) {
83
83
  const { skipCheck = false } = options;
84
84
  const detection = detectSchemaFiles(changedFiles);
@@ -95,7 +95,7 @@ function checkSchemaDrift(changedFiles, executionLog, options = {}) {
95
95
  const pushedOrms = new Set();
96
96
  const unpushedOrms = [];
97
97
  for (const orm of detection.orms) {
98
- const info = ORM_INFO[orm];
98
+ const info = exports.ORM_INFO[orm];
99
99
  if (!info)
100
100
  continue;
101
101
  const hasPushEvidence = info.evidencePatterns.some(p => p.test(executionLog));
@@ -106,6 +106,8 @@ function checkSchemaDrift(changedFiles, executionLog, options = {}) {
106
106
  unpushedOrms.push(orm);
107
107
  }
108
108
  }
109
+ // Suppress unused variable warning — pushedOrms tracks for conceptual clarity
110
+ void pushedOrms;
109
111
  const driftDetected = unpushedOrms.length > 0;
110
112
  if (!driftDetected) {
111
113
  return {
@@ -119,10 +121,10 @@ function checkSchemaDrift(changedFiles, executionLog, options = {}) {
119
121
  }
120
122
  const pushCommands = unpushedOrms
121
123
  .map(orm => {
122
- const info = ORM_INFO[orm];
124
+ const info = exports.ORM_INFO[orm];
123
125
  return info ? ` ${orm}: ${info.envHint || info.pushCommand}` : null;
124
126
  })
125
- .filter(Boolean)
127
+ .filter((x) => x !== null)
126
128
  .join('\n');
127
129
  const message = [
128
130
  'Schema drift detected: schema-relevant files changed but no database push was executed.',
@@ -155,11 +157,3 @@ function checkSchemaDrift(changedFiles, executionLog, options = {}) {
155
157
  message,
156
158
  };
157
159
  }
158
-
159
- module.exports = {
160
- SCHEMA_PATTERNS,
161
- ORM_INFO,
162
- detectSchemaFiles,
163
- detectSchemaOrm,
164
- checkSchemaDrift,
165
- };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * Secrets handling — masking convention for API keys and other
4
+ * credentials managed via /gsd-settings-integrations (ADR-457 build-at-publish:
5
+ * the hand-written bin/lib/secrets.cjs collapsed to a TypeScript source of
6
+ * truth). Behaviour is preserved byte-for-behaviour from the prior hand-written
7
+ * .cjs; only types are added.
8
+ *
9
+ * This module does not read the filesystem.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SECRET_CONFIG_KEYS = void 0;
13
+ exports.isSecretKey = isSecretKey;
14
+ exports.maskSecret = maskSecret;
15
+ exports.maskIfSecret = maskIfSecret;
16
+ exports.SECRET_CONFIG_KEYS = new Set([
17
+ 'brave_search',
18
+ 'firecrawl',
19
+ 'exa_search',
20
+ ]);
21
+ function isSecretKey(keyPath) {
22
+ return exports.SECRET_CONFIG_KEYS.has(keyPath);
23
+ }
24
+ function maskSecret(value) {
25
+ if (value === null || value === undefined || value === '')
26
+ return '(unset)';
27
+ const s = String(value);
28
+ if (s.length < 8)
29
+ return '****';
30
+ return '****' + s.slice(-4);
31
+ }
32
+ function maskIfSecret(keyPath, value) {
33
+ return isSecretKey(keyPath) ? maskSecret(value) : value;
34
+ }
@@ -0,0 +1,407 @@
1
+ "use strict";
2
+ /**
3
+ * Security — Input validation, path traversal prevention, and prompt injection guards
4
+ *
5
+ * This module centralizes security checks for GSD tooling. Because GSD generates
6
+ * markdown files that become LLM system prompts (agent instructions, workflow state,
7
+ * phase plans), any user-controlled text that flows into these files is a potential
8
+ * indirect prompt injection vector.
9
+ *
10
+ * Threat model:
11
+ * 1. Path traversal: user-supplied file paths escape the project directory
12
+ * 2. Prompt injection: malicious text in arguments/PRDs embeds LLM instructions
13
+ * 3. Shell metacharacter injection: user text interpreted by shell
14
+ * 4. JSON injection: malformed JSON crashes or corrupts state
15
+ * 5. Regex DoS: crafted input causes catastrophic backtracking
16
+ *
17
+ * ADR-457 build-at-publish: the hand-written bin/lib/security.cjs collapsed
18
+ * to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
19
+ * from the prior hand-written .cjs; only types are added.
20
+ */
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.MARKDOWN_LINK_PATTERNS = exports.INJECTION_PATTERNS = void 0;
26
+ exports.validatePath = validatePath;
27
+ exports.requireSafePath = requireSafePath;
28
+ exports.scanForInjection = scanForInjection;
29
+ exports.sanitizeForPrompt = sanitizeForPrompt;
30
+ exports.sanitizeForDisplay = sanitizeForDisplay;
31
+ exports.validateShellArg = validateShellArg;
32
+ exports.safeJsonParse = safeJsonParse;
33
+ exports.validatePhaseNumber = validatePhaseNumber;
34
+ exports.validateFieldName = validateFieldName;
35
+ exports.validatePromptStructure = validatePromptStructure;
36
+ exports.scanEntropyAnomalies = scanEntropyAnomalies;
37
+ const node_fs_1 = __importDefault(require("node:fs"));
38
+ const node_path_1 = __importDefault(require("node:path"));
39
+ // ─── Path Traversal Prevention ──────────────────────────────────────────────
40
+ /**
41
+ * Validate that a file path resolves within an allowed base directory.
42
+ * Prevents path traversal attacks via ../ sequences, symlinks, or absolute paths.
43
+ */
44
+ function validatePath(filePath, baseDir, opts = {}) {
45
+ if (!filePath || typeof filePath !== 'string') {
46
+ return { safe: false, resolved: '', error: 'Empty or invalid file path' };
47
+ }
48
+ if (!baseDir || typeof baseDir !== 'string') {
49
+ return { safe: false, resolved: '', error: 'Empty or invalid base directory' };
50
+ }
51
+ if (filePath.includes('\0')) {
52
+ return { safe: false, resolved: '', error: 'Path contains null bytes' };
53
+ }
54
+ let resolvedBase;
55
+ try {
56
+ resolvedBase = node_fs_1.default.realpathSync(node_path_1.default.resolve(baseDir));
57
+ }
58
+ catch {
59
+ resolvedBase = node_path_1.default.resolve(baseDir);
60
+ }
61
+ let resolvedPath;
62
+ if (node_path_1.default.isAbsolute(filePath)) {
63
+ if (!opts.allowAbsolute) {
64
+ return { safe: false, resolved: '', error: 'Absolute paths not allowed' };
65
+ }
66
+ resolvedPath = node_path_1.default.resolve(filePath);
67
+ }
68
+ else {
69
+ resolvedPath = node_path_1.default.resolve(baseDir, filePath);
70
+ }
71
+ try {
72
+ resolvedPath = node_fs_1.default.realpathSync(resolvedPath);
73
+ }
74
+ catch {
75
+ const parentDir = node_path_1.default.dirname(resolvedPath);
76
+ try {
77
+ const realParent = node_fs_1.default.realpathSync(parentDir);
78
+ resolvedPath = node_path_1.default.join(realParent, node_path_1.default.basename(resolvedPath));
79
+ }
80
+ catch {
81
+ // Parent doesn't exist either — keep the resolved path as-is
82
+ }
83
+ }
84
+ const normalizedBase = resolvedBase + node_path_1.default.sep;
85
+ const normalizedPath = resolvedPath + node_path_1.default.sep;
86
+ if (resolvedPath !== resolvedBase && !normalizedPath.startsWith(normalizedBase)) {
87
+ return {
88
+ safe: false,
89
+ resolved: resolvedPath,
90
+ error: `Path escapes allowed directory: ${resolvedPath} is outside ${resolvedBase}`,
91
+ };
92
+ }
93
+ return { safe: true, resolved: resolvedPath };
94
+ }
95
+ /**
96
+ * Validate a file path and throw on traversal attempt.
97
+ * Convenience wrapper around validatePath for use in CLI commands.
98
+ */
99
+ function requireSafePath(filePath, baseDir, label, opts = {}) {
100
+ const result = validatePath(filePath, baseDir, opts);
101
+ if (!result.safe) {
102
+ throw new Error(`${label || 'Path'} validation failed: ${result.error}`);
103
+ }
104
+ return result.resolved;
105
+ }
106
+ // ─── Prompt Injection Detection ────────────────────────────────────────────────────
107
+ /**
108
+ * Patterns that indicate prompt injection attempts in user-supplied text.
109
+ * These patterns catch common indirect prompt injection techniques where
110
+ * an attacker embeds LLM instructions in text that will be read by an agent.
111
+ *
112
+ * Note: This is defense-in-depth — not a complete solution. The primary defense
113
+ * is proper input/output boundaries in agent prompts.
114
+ */
115
+ exports.INJECTION_PATTERNS = [
116
+ // Direct instruction override attempts
117
+ /ignore\s+(all\s+)?previous\s+instructions/i,
118
+ /ignore\s+(all\s+)?above\s+instructions/i,
119
+ /disregard\s+(all\s+)?previous/i,
120
+ /forget\s+(all\s+)?(your\s+)?instructions/i,
121
+ /override\s+(system|previous)\s+(prompt|instructions)/i,
122
+ // Role/identity manipulation
123
+ /you\s+are\s+now\s+(?:a|an|the)\s+/i,
124
+ /act\s+as\s+(?:a|an|the)\s+(?!plan|phase|wave)/i,
125
+ /pretend\s+(?:you(?:'re| are)\s+|to\s+be\s+)/i,
126
+ /from\s+now\s+on,?\s+you\s+(?:are|will|should|must)/i,
127
+ // System prompt extraction
128
+ /(?:print|output|reveal|show|display|repeat)\s+(?:your\s+)?(?:system\s+)?(?:prompt|instructions)/i,
129
+ /what\s+(?:are|is)\s+your\s+(?:system\s+)?(?:prompt|instructions)/i,
130
+ // Hidden instruction markers (XML/HTML tags that mimic system messages)
131
+ // Note: <instructions> is excluded — GSD uses it as legitimate prompt structure
132
+ // Requires > to close the tag (not just whitespace) to avoid matching generic types like Promise<User | null>
133
+ /<\/?(?:system|assistant|human)>/i,
134
+ /\[SYSTEM\]/i,
135
+ /\[\/?(INST)\]/i,
136
+ /<<\s*SYS\s*>>/i,
137
+ // Exfiltration attempts
138
+ /(?:send|post|fetch|curl|wget)\s+(?:to|from)\s+https?:\/\//i,
139
+ /(?:base64|btoa|encode)\s+(?:and\s+)?(?:send|exfiltrate|output)/i,
140
+ // Tool manipulation
141
+ /(?:run|execute|call|invoke)\s+(?:the\s+)?(?:bash|shell|exec|spawn)\s+(?:tool|command)/i,
142
+ ];
143
+ // Explicit safe-list for data: MIME types that are benign in link targets.
144
+ // Note: image/svg+xml is intentionally NOT in this list (SVG can host <script>).
145
+ const DATA_URI_SAFE_MIME_RE = /^data:(image\/(png|jpe?g|gif|webp|bmp|ico|avif|heic)|font\/(woff2?|otf|ttf))(;[^,]*)?,/i;
146
+ exports.MARKDOWN_LINK_PATTERNS = [
147
+ {
148
+ pattern: /\]\(\s*javascript:/i,
149
+ ruleId: 'MD-LINK-JS-SCHEME',
150
+ },
151
+ {
152
+ pattern: /\]\(\s*data:/i,
153
+ ruleId: 'MD-LINK-DATA-SCHEME',
154
+ safePredicate: (line) => {
155
+ const m = line.match(/\]\(\s*(data:[^)]*)/i);
156
+ if (!m)
157
+ return false;
158
+ return DATA_URI_SAFE_MIME_RE.test(m[1]);
159
+ },
160
+ },
161
+ {
162
+ pattern: /\]\(\s*https?:\/\/[^/\s]+:[^/@\s]+@/i,
163
+ ruleId: 'MD-LINK-USERINFO',
164
+ },
165
+ {
166
+ pattern: /[?&](token|access_token|id_token|refresh_token|api_key|apikey|secret|password|client_secret|code)=/i,
167
+ ruleId: 'MD-LINK-TOKEN-IN-QUERY',
168
+ },
169
+ ];
170
+ const OBFUSCATION_PATTERN_ENTRIES = [
171
+ {
172
+ pattern: /\b(\w\s){4,}\w\b/,
173
+ message: 'Character-spacing obfuscation pattern detected (e.g. "i g n o r e")',
174
+ },
175
+ {
176
+ pattern: /<\/?(system|human|assistant|user)\s*>/i,
177
+ message: 'Delimiter injection pattern: <system>/<human>/<assistant>/<user> tag detected',
178
+ },
179
+ {
180
+ pattern: /0x[0-9a-fA-F]{16,}/,
181
+ message: 'Long hex sequence detected — possible encoded payload',
182
+ },
183
+ ];
184
+ /**
185
+ * Scan text for potential prompt injection patterns.
186
+ * Returns an array of findings (empty = clean).
187
+ */
188
+ function scanForInjection(text, opts = {}) {
189
+ if (!text || typeof text !== 'string') {
190
+ return { clean: true, findings: [], structuredFindings: [] };
191
+ }
192
+ const findings = [];
193
+ const structuredFindings = [];
194
+ for (const pattern of exports.INJECTION_PATTERNS) {
195
+ if (pattern.test(text)) {
196
+ findings.push(`Matched injection pattern: ${pattern.source}`);
197
+ }
198
+ }
199
+ for (const entry of OBFUSCATION_PATTERN_ENTRIES) {
200
+ if (entry.pattern.test(text)) {
201
+ findings.push(entry.message);
202
+ }
203
+ }
204
+ const lines = text.split('\n');
205
+ for (const entry of exports.MARKDOWN_LINK_PATTERNS) {
206
+ for (let i = 0; i < lines.length; i++) {
207
+ const line = lines[i];
208
+ const m = line.match(entry.pattern);
209
+ if (!m)
210
+ continue;
211
+ if (entry.safePredicate && entry.safePredicate(line))
212
+ continue;
213
+ const matchText = m[0];
214
+ findings.push(`Matched markdown link pattern [${entry.ruleId}]: ${matchText}`);
215
+ structuredFindings.push({
216
+ ruleId: entry.ruleId,
217
+ file: opts.file,
218
+ line: i + 1,
219
+ match: matchText,
220
+ });
221
+ }
222
+ }
223
+ if (opts.strict) {
224
+ // Check for suspicious Unicode that could hide instructions
225
+ // (zero-width chars, RTL override, homoglyph attacks)
226
+ if (/[\u200B-\u200F\u2028-\u202F\uFEFF\u00AD]/.test(text)) {
227
+ findings.push('Contains suspicious zero-width or invisible Unicode characters');
228
+ }
229
+ // Layer 1: Unicode tag block U+E0000–E007F (2025 supply-chain attack vector)
230
+ // These characters are invisible and can embed hidden instructions
231
+ if (/[\uDB40\uDC00-\uDB40\uDC7F]/u.test(text) || /[\u{E0000}-\u{E007F}]/u.test(text)) {
232
+ findings.push('Contains Unicode tag block characters (U+E0000–E007F) — invisible instruction injection vector');
233
+ }
234
+ // Check for extremely long strings that could be prompt stuffing.
235
+ // Normalize CRLF → LF before measuring so Windows checkouts don't inflate the count.
236
+ const normalizedLength = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n').length;
237
+ if (normalizedLength > 50000) {
238
+ findings.push(`Suspicious text length: ${normalizedLength} chars (potential prompt stuffing)`);
239
+ }
240
+ }
241
+ return { clean: findings.length === 0, findings, structuredFindings };
242
+ }
243
+ /**
244
+ * Sanitize text that will be embedded in agent prompts or planning documents.
245
+ * Strips known injection markers while preserving legitimate content.
246
+ */
247
+ function sanitizeForPrompt(text) {
248
+ if (!text || typeof text !== 'string')
249
+ return text;
250
+ let sanitized = text;
251
+ // Strip zero-width characters that could hide instructions
252
+ sanitized = sanitized.replace(/[\u200B-\u200F\u2028-\u202F\uFEFF\u00AD]/g, '');
253
+ // Neutralize XML/HTML tags that mimic system boundaries
254
+ // Note: <instructions> is excluded — GSD uses it as legitimate prompt structure
255
+ sanitized = sanitized.replace(/<(\/?)\s*(?:system|assistant|human|user)\s*>/gi, (_, slash) => `<${slash || ''}system-text>`);
256
+ // Neutralize [SYSTEM] / [INST] / [/INST] markers
257
+ sanitized = sanitized.replace(/\[(\/?)(SYSTEM|INST)\]/gi, (_, slash, tag) => `[${slash}${tag.toUpperCase()}-TEXT]`);
258
+ // Neutralize <<SYS>> and <</SYS>> markers (Llama-style delimiters)
259
+ sanitized = sanitized.replace(/<<\/?\s*SYS\s*>>/gi, '«SYS-TEXT»');
260
+ return sanitized;
261
+ }
262
+ /**
263
+ * Sanitize text that will be displayed back to the user.
264
+ * Removes protocol-like leak markers that should never surface in checkpoints.
265
+ */
266
+ function sanitizeForDisplay(text) {
267
+ if (!text || typeof text !== 'string')
268
+ return text;
269
+ let sanitized = sanitizeForPrompt(text);
270
+ const protocolLeakPatterns = [
271
+ /^\s*(?:assistant|user|system)\s+to=[^:\s]+:[^\n]+$/i,
272
+ /^\s*<\|(?:assistant|user|system)[^|]*\|>\s*$/i,
273
+ ];
274
+ sanitized = sanitized
275
+ .split('\n')
276
+ .filter(line => !protocolLeakPatterns.some(pattern => pattern.test(line)))
277
+ .join('\n');
278
+ return sanitized;
279
+ }
280
+ // ─── Shell Safety ───────────────────────────────────────────────────────────────────────
281
+ /**
282
+ * Validate that a string is safe to use as a shell argument when quoted.
283
+ */
284
+ function validateShellArg(value, label) {
285
+ if (!value || typeof value !== 'string') {
286
+ throw new Error(`${label || 'Argument'}: empty or invalid value`);
287
+ }
288
+ if (value.includes('\0')) {
289
+ throw new Error(`${label || 'Argument'}: contains null bytes`);
290
+ }
291
+ if (/[$`]/.test(value) && /\$\(|`/.test(value)) {
292
+ throw new Error(`${label || 'Argument'}: contains potential command substitution`);
293
+ }
294
+ return value;
295
+ }
296
+ // ─── JSON Safety ──────────────────────────────────────────────────────────────────────────
297
+ /**
298
+ * Safely parse JSON with error handling and optional size limits.
299
+ */
300
+ function safeJsonParse(text, opts = {}) {
301
+ const maxLength = opts.maxLength || 1048576;
302
+ const label = opts.label || 'JSON';
303
+ if (!text || typeof text !== 'string') {
304
+ return { ok: false, error: `${label}: empty or invalid input` };
305
+ }
306
+ if (text.length > maxLength) {
307
+ return { ok: false, error: `${label}: input exceeds ${maxLength} byte limit (got ${text.length})` };
308
+ }
309
+ try {
310
+ const value = JSON.parse(text);
311
+ return { ok: true, value };
312
+ }
313
+ catch (err) {
314
+ const msg = err instanceof Error ? err.message : String(err);
315
+ return { ok: false, error: `${label}: parse error — ${msg}` };
316
+ }
317
+ }
318
+ // ─── Phase/Argument Validation ─────────────────────────────────────────────────────────
319
+ /**
320
+ * Validate a phase number argument.
321
+ */
322
+ function validatePhaseNumber(phase) {
323
+ if (!phase || typeof phase !== 'string') {
324
+ return { valid: false, error: 'Phase number is required' };
325
+ }
326
+ const trimmed = phase.trim();
327
+ if (/^\d{1,4}[A-Z]?(?:\.\d{1,3})*$/i.test(trimmed)) {
328
+ return { valid: true, normalized: trimmed };
329
+ }
330
+ if (/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+){1,4}$/i.test(trimmed) && trimmed.length <= 30) {
331
+ return { valid: true, normalized: trimmed };
332
+ }
333
+ return { valid: false, error: `Invalid phase number format: "${trimmed}"` };
334
+ }
335
+ /**
336
+ * Validate a STATE.md field name to prevent injection into regex patterns.
337
+ */
338
+ function validateFieldName(field) {
339
+ if (!field || typeof field !== 'string') {
340
+ return { valid: false, error: 'Field name is required' };
341
+ }
342
+ if (/^[A-Za-z][A-Za-z0-9 _.\-/]{0,60}$/.test(field)) {
343
+ return { valid: true };
344
+ }
345
+ return { valid: false, error: `Invalid field name: "${field}"` };
346
+ }
347
+ // ─── Layer 3: Structural Schema Validation ──────────────────────────────────────────────────────────────────────────
348
+ const KNOWN_VALID_TAGS = new Set([
349
+ 'objective', 'process', 'step', 'success_criteria', 'critical_rules',
350
+ 'available_agent_types', 'purpose', 'required_reading',
351
+ ]);
352
+ /**
353
+ * Validate the XML structure of a prompt file.
354
+ */
355
+ function validatePromptStructure(text, fileType) {
356
+ if (!text || typeof text !== 'string') {
357
+ return { valid: true, violations: [] };
358
+ }
359
+ if (fileType !== 'agent' && fileType !== 'workflow') {
360
+ return { valid: true, violations: [] };
361
+ }
362
+ const violations = [];
363
+ const tagRegex = /<([A-Za-z][A-Za-z0-9_-]*)/g;
364
+ let match;
365
+ while ((match = tagRegex.exec(text)) !== null) {
366
+ const tag = match[1].toLowerCase();
367
+ if (!KNOWN_VALID_TAGS.has(tag)) {
368
+ violations.push(`Unknown XML tag in ${fileType} file: <${tag}>`);
369
+ }
370
+ }
371
+ return { valid: violations.length === 0, violations };
372
+ }
373
+ // ─── Layer 4: Paragraph-Level Entropy Anomaly Detection ─────────────────────────────────────────────────────────────────────
374
+ function shannonEntropy(text) {
375
+ if (!text || text.length === 0)
376
+ return 0;
377
+ const freq = {};
378
+ for (const ch of text) {
379
+ freq[ch] = (freq[ch] || 0) + 1;
380
+ }
381
+ const len = text.length;
382
+ let entropy = 0;
383
+ for (const count of Object.values(freq)) {
384
+ const p = count / len;
385
+ entropy -= p * Math.log2(p);
386
+ }
387
+ return entropy;
388
+ }
389
+ /**
390
+ * Scan text for paragraphs with anomalously high Shannon entropy.
391
+ */
392
+ function scanEntropyAnomalies(text) {
393
+ if (!text || typeof text !== 'string') {
394
+ return { clean: true, findings: [] };
395
+ }
396
+ const findings = [];
397
+ const paragraphs = text.split(/\n\n+/);
398
+ for (const para of paragraphs) {
399
+ if (para.length <= 50)
400
+ continue;
401
+ const entropy = shannonEntropy(para);
402
+ if (entropy > 5.5) {
403
+ findings.push(`High-entropy paragraph detected (${entropy.toFixed(2)} bits/char) — possible encoded payload`);
404
+ }
405
+ }
406
+ return { clean: findings.length === 0, findings };
407
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * Shared semver comparison utility (ADR-457 pilot: first hand-written
4
+ * bin/lib/*.cjs collapsed to a TypeScript source of truth).
5
+ *
6
+ * Logic is preserved byte-for-behaviour from the prior hand-written
7
+ * `gsd-core/bin/lib/semver-compare.cjs`; only types are added. The
8
+ * normalization policy here is locked by `tests/semver-compare.test.cjs` and
9
+ * consumed by update-check, statusline dev-install detection, and changeset
10
+ * range compare (`scripts/changeset/cli.cjs`).
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.toNumericTuple = toNumericTuple;
14
+ exports.compareSemverCore = compareSemverCore;
15
+ exports.isSemverNewer = isSemverNewer;
16
+ exports.isStableTripletSemver = isStableTripletSemver;
17
+ function toNumericTuple(input) {
18
+ const cleaned = String(input == null ? '' : input).trim().replace(/^v/, '');
19
+ const base = cleaned.replace(/[-+].*$/, '');
20
+ const parts = base.split('.');
21
+ const major = Number.parseInt(parts[0], 10) || 0;
22
+ const minor = Number.parseInt(parts[1], 10) || 0;
23
+ const patch = Number.parseInt(parts[2], 10) || 0;
24
+ return [major, minor, patch];
25
+ }
26
+ function compareSemverCore(a, b) {
27
+ const [a0, a1, a2] = toNumericTuple(a);
28
+ const [b0, b1, b2] = toNumericTuple(b);
29
+ if (a0 !== b0)
30
+ return a0 > b0 ? 1 : -1;
31
+ if (a1 !== b1)
32
+ return a1 > b1 ? 1 : -1;
33
+ if (a2 !== b2)
34
+ return a2 > b2 ? 1 : -1;
35
+ return 0;
36
+ }
37
+ function isSemverNewer(a, b) {
38
+ return compareSemverCore(a, b) > 0;
39
+ }
40
+ function isStableTripletSemver(v) {
41
+ return /^\d+\.\d+\.\d+$/.test(String(v || '').replace(/^v/, ''));
42
+ }