@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 +0,0 @@
1
- _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
@@ -1,81 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Extended detector for the no-source-grep rule (#2982).
5
- *
6
- * The base lint (scripts/lint-no-source-grep.cjs) only catches the
7
- * direct-chain form: readFileSync(...).includes(...). The much more common
8
- * var-binding form escapes it:
9
- *
10
- * const src = fs.readFileSync(p, 'utf8');
11
- * // ... 50 lines later ...
12
- * assert.ok(src.includes('foo')); // ← still source-grep, lint missed it
13
- *
14
- * This module exposes pure detectors that scan source text and return
15
- * structured violation records. The CLI wrapper (in the base lint) calls
16
- * these for each test file.
17
- *
18
- * Tests assert on the typed VIOLATION enum codes, not on prose messages.
19
- */
20
-
21
- const VIOLATION = Object.freeze({
22
- VAR_FROM_READFILE_USED_IN_TEXT_MATCH: 'var_from_readfile_used_in_text_match',
23
- WRAPPED_ASSERT_OK_MATCH: 'wrapped_assert_ok_match',
24
- });
25
-
26
- const TEXT_MATCH_METHODS = ['includes', 'startsWith', 'endsWith', 'match', 'search'];
27
-
28
- /**
29
- * Single-pass scanner. Tracks variables bound from a readFileSync call,
30
- * then flags any subsequent <var>.<method>( use where method is one of
31
- * TEXT_MATCH_METHODS.
32
- */
33
- function detectVarBindingViolations(src) {
34
- // Pass 1: collect variables bound from readFileSync.
35
- // Matches: const|let|var <name> = [fs.]readFileSync(
36
- const bindRe = /(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:[A-Za-z_$][\w$.]*\.)?readFileSync\s*\(/g;
37
- const boundVars = new Set();
38
- let m;
39
- while ((m = bindRe.exec(src)) !== null) {
40
- boundVars.add(m[1]);
41
- }
42
- if (boundVars.size === 0) return [];
43
-
44
- // Pass 2: find <var>.<method>( on any bound var.
45
- const findings = [];
46
- // Build a regex alternation from the bound var names.
47
- const alt = [...boundVars].map((v) => v.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
48
- const useRe = new RegExp(
49
- `\\b(${alt})\\s*\\.\\s*(${TEXT_MATCH_METHODS.join('|')})\\s*\\(`,
50
- 'g',
51
- );
52
- while ((m = useRe.exec(src)) !== null) {
53
- findings.push({
54
- kind: VIOLATION.VAR_FROM_READFILE_USED_IN_TEXT_MATCH,
55
- variable: m[1],
56
- method: m[2],
57
- });
58
- }
59
- return findings;
60
- }
61
-
62
- /**
63
- * Detects assert.ok(<expr>.match(/.../)) and assert.ok(<expr>.match(<expr>))
64
- * which is the same anti-pattern as assert.match but escapes the simpler
65
- * regex used by the base lint.
66
- */
67
- function detectWrappedAssertOkMatch(src) {
68
- const re = /assert\.ok\s*\(\s*[A-Za-z_$][\w$.]*\.match\s*\(/g;
69
- const findings = [];
70
- let m;
71
- while ((m = re.exec(src)) !== null) {
72
- findings.push({ kind: VIOLATION.WRAPPED_ASSERT_OK_MATCH });
73
- }
74
- return findings;
75
- }
76
-
77
- function detectAll(src) {
78
- return [...detectVarBindingViolations(src), ...detectWrappedAssertOkMatch(src)];
79
- }
80
-
81
- module.exports = { detectVarBindingViolations, detectWrappedAssertOkMatch, detectAll, VIOLATION };
@@ -1,174 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * lint-no-source-grep.cjs
4
- *
5
- * Enforces the "no source-grep tests" rule:
6
- * Tests must NOT read source-code .cjs files with readFileSync to assert string
7
- * presence. That pattern (source-grep theater) proves a literal exists in source,
8
- * not that the runtime behavior is correct.
9
- *
10
- * ALLOWED:
11
- * - require('../get-shit-done/bin/lib/foo.cjs') -- runs the module, not text inspection
12
- * - readFileSync on .md / .json / .txt files -- product-content or config output
13
- * - Files annotated: // allow-test-rule: <reason>
14
- *
15
- * DISALLOWED (without allow-test-rule):
16
- * - readFileSync where the path argument ends in a .cjs filename literal
17
- * - A path constant (e.g. CONFIG_PATH) assigned to a .cjs lib file, used in readFileSync
18
- *
19
- * Exit 0 = clean. Exit 1 = violations found (with diagnostics).
20
- */
21
-
22
- 'use strict';
23
-
24
- const fs = require('fs');
25
- const path = require('path');
26
-
27
- const TESTS_DIR = path.join(__dirname, '..', 'tests');
28
- const ALLOW_ANNOTATION = /\/\/\s*allow-test-rule:\s*\S/;
29
-
30
- // Matches constant definitions that hold a .cjs path in a SOURCE directory.
31
- // Requires a source-dir indicator ('bin', 'lib', 'get-shit-done') to avoid
32
- // flagging temp files like path.join(tmpDir, 'example.cjs').
33
- // const CONFIG_PATH = path.join(__dirname, '..', 'get-shit-done', 'bin', 'lib', 'config-schema.cjs');
34
- const CJS_PATH_CONST_RE = /(?:const|let|var)\s+(\w+)\s*=\s*path\.join\s*\([^)]*(?:'bin'|"bin"|'lib'|"lib"|'get-shit-done'|"get-shit-done")[^)]*['"][^'"]*\.cjs['"]/gm;
35
-
36
- // Matches readFileSync with a named variable as first arg
37
- const READ_WITH_CONST_RE = /readFileSync\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*,/gm;
38
-
39
- // Matches readFileSync with an inline path.join(.cjs) as first arg
40
- const READ_WITH_INLINE_CJS_RE = /readFileSync\s*\([^,)]*path\.join\s*\([^)]*(?:'bin'|"bin"|'lib'|"lib"|'get-shit-done'|"get-shit-done")[^)]*['"][^'"]*\.cjs['"]/;
41
-
42
- /**
43
- * #2962-class violations: raw text matching against process output or file
44
- * content. The rule from CONTRIBUTING.md "Prohibited: Raw Text Matching on
45
- * Test Outputs": tests assert on typed structured fields, never on rendered
46
- * text. Patterns below are the obvious anti-patterns; subtler hidden forms
47
- * (e.g. wrapping the same logic in a parser function) are still forbidden
48
- * by the prose rule but cannot be detected lexically without an AST.
49
- */
50
- const RAW_MATCH_PATTERNS = [
51
- {
52
- re: /assert\.(?:match|doesNotMatch)\s*\(\s*[A-Za-z_$][A-Za-z0-9_$]*\.(?:stdout|stderr)\b/,
53
- label: 'assert.match/doesNotMatch on .stdout/.stderr (emit --json from the SUT and assert on typed fields)',
54
- },
55
- {
56
- re: /\.(?:stdout|stderr)\.(?:includes|startsWith|endsWith)\s*\(/,
57
- label: '.stdout/.stderr substring match (emit --json and assert on typed fields)',
58
- },
59
- {
60
- re: /readFileSync\s*\([^)]*\)\s*\.(?:includes|startsWith|endsWith)\s*\(/,
61
- label: 'readFileSync(...).<includes|startsWith|endsWith> (expose an IR from production code; assert on its fields)',
62
- },
63
- ];
64
-
65
- function setFromMatches(content, re) {
66
- const found = new Set();
67
- let m;
68
- const cloned = new RegExp(re.source, re.flags);
69
- while ((m = cloned.exec(content)) !== null) found.add(m[1]);
70
- return found;
71
- }
72
-
73
- function check(filepath) {
74
- const content = fs.readFileSync(filepath, 'utf-8');
75
- const rel = path.relative(path.join(__dirname, '..'), filepath);
76
-
77
- if (ALLOW_ANNOTATION.test(content)) return null;
78
-
79
- const violations = [];
80
-
81
- // Pattern A: readFileSync(path.join(..., 'foo.cjs'), ...)
82
- if (READ_WITH_INLINE_CJS_RE.test(content)) {
83
- violations.push({
84
- reason: 'readFileSync with inline .cjs path literal',
85
- fix: 'Replace with runGsdTools() behavioral test, or add // allow-test-rule: <reason>',
86
- });
87
- }
88
-
89
- // Pattern B: const FOO_PATH = path.join(..., 'foo.cjs') + readFileSync(FOO_PATH, ...)
90
- const cjsConsts = setFromMatches(content, CJS_PATH_CONST_RE);
91
- if (cjsConsts.size > 0) {
92
- const readConsts = setFromMatches(content, READ_WITH_CONST_RE);
93
- const overlap = [...cjsConsts].filter(c => readConsts.has(c));
94
- if (overlap.length > 0) {
95
- violations.push({
96
- reason: `source .cjs path constant(s) used in readFileSync: ${overlap.join(', ')}`,
97
- fix: 'Replace with runGsdTools() behavioral test, or add // allow-test-rule: <reason>',
98
- });
99
- }
100
- }
101
-
102
- // Patterns C..E: raw text matching against process output or file content.
103
- // See CONTRIBUTING.md "Prohibited: Raw Text Matching on Test Outputs".
104
- for (const { re, label } of RAW_MATCH_PATTERNS) {
105
- if (re.test(content)) {
106
- violations.push({
107
- reason: label,
108
- fix: 'Expose typed IR from production code; assert on structured fields. Or add // allow-test-rule: <reason>',
109
- });
110
- }
111
- }
112
-
113
- // Patterns F..G (#2982): var-binding readFileSync().<text-method>() and
114
- // assert.ok(<expr>.match(...)). These escape the simpler patterns above
115
- // because the bind and the use are on different lines or wrapped.
116
- const extras = require('./lint-no-source-grep-extras.cjs');
117
- const varBindFindings = extras.detectVarBindingViolations(content);
118
- if (varBindFindings.length > 0) {
119
- const samples = varBindFindings.slice(0, 3)
120
- .map((f) => `${f.variable}.${f.method}()`)
121
- .join(', ');
122
- violations.push({
123
- reason: `readFileSync-bound variable used in text-match method: ${samples}${varBindFindings.length > 3 ? `, …+${varBindFindings.length - 3} more` : ''}`,
124
- fix: 'Expose typed IR; assert on structured fields. Or // allow-test-rule: <reason>',
125
- });
126
- }
127
- const wrappedFindings = extras.detectWrappedAssertOkMatch(content);
128
- if (wrappedFindings.length > 0) {
129
- violations.push({
130
- reason: `assert.ok(<expr>.match(...)) — escapes assert.match rule (${wrappedFindings.length} occurrence${wrappedFindings.length > 1 ? 's' : ''})`,
131
- fix: 'Use assert.equal on a typed field, not regex match on text. Or // allow-test-rule: <reason>',
132
- });
133
- }
134
-
135
- if (violations.length === 0) return null;
136
- return { file: rel, violations };
137
- }
138
-
139
- function findTestFiles(dir) {
140
- const results = [];
141
- for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
142
- const full = path.join(dir, entry.name);
143
- if (entry.isDirectory()) {
144
- results.push(...findTestFiles(full));
145
- } else if (entry.name.endsWith('.test.cjs')) {
146
- results.push(full);
147
- }
148
- }
149
- return results;
150
- }
151
-
152
- const testFiles = findTestFiles(TESTS_DIR);
153
-
154
- const violations = testFiles.map(check).filter(Boolean);
155
-
156
- if (violations.length === 0) {
157
- console.log(`ok lint-no-source-grep: ${testFiles.length} test files checked, 0 violations`);
158
- process.exit(0);
159
- }
160
-
161
- const totalIssues = violations.reduce((n, v) => n + v.violations.length, 0);
162
- process.stderr.write(`\nERROR lint-no-source-grep: ${totalIssues} violation(s) across ${violations.length} file(s)\n\n`);
163
- for (const f of violations) {
164
- process.stderr.write(` ${f.file}\n`);
165
- for (const v of f.violations) {
166
- process.stderr.write(` Problem : ${v.reason}\n`);
167
- process.stderr.write(` Fix : ${v.fix}\n`);
168
- }
169
- process.stderr.write('\n');
170
- }
171
- process.stderr.write('See CONTRIBUTING.md "Prohibited: Source-Grep Tests" and\n');
172
- process.stderr.write('"Prohibited: Raw Text Matching on Test Outputs" for guidance.\n');
173
- process.stderr.write('Structural tests that legitimately read source files: add // allow-test-rule: <reason>\n\n');
174
- process.exit(1);
@@ -1,388 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- /**
5
- * Shared Module hand-sync drift lint — Phase 6 of #3524 (#3575).
6
- *
7
- * Scans get-shit-done/bin/lib/ for .cjs files and checks whether a matching
8
- * TypeScript file exists in sdk/src/<name>.ts, sdk/src/query/<name>.ts, or
9
- * sdk/src/<name>/index.ts (excluding *.generated.ts and *.test.ts).
10
- *
11
- * Allowlist entries are keyed by the (cjs, ts) PAIR. An entry with cjs
12
- * `bin/lib/foo.cjs` and ts `sdk/src/foo.ts` only allow-throughs that exact
13
- * pair — a sibling at `sdk/src/query/foo.ts` is still flagged.
14
- *
15
- * Cross-name pairs are also supported when declared in the allowlist
16
- * (for example `verify.cjs` <-> `validate.ts`), so cooperating siblings are
17
- * observable even when basenames differ.
18
- *
19
- * If a pair is found:
20
- * - cooperatingSiblings (matching cjs + ts): accepted silently (exit 0).
21
- * - migrateMeBacklog (matching cjs + ts): emits a WARNING only when
22
- * --warn-all is set; otherwise the pair passes silently. Backlog
23
- * pairs never fail CI.
24
- * - Unlisted pairs (cjs or ts not on either list): ERROR — exit 1.
25
- *
26
- * Usage:
27
- * node scripts/lint-shared-module-handsync.cjs
28
- * node scripts/lint-shared-module-handsync.cjs --root /path/to/repo
29
- * node scripts/lint-shared-module-handsync.cjs --warn-all
30
- * node scripts/lint-shared-module-handsync.cjs --cjs-dir custom/bin/lib --sdk-src custom/sdk/src
31
- */
32
-
33
- const fs = require('fs');
34
- const path = require('path');
35
-
36
- // ---------------------------------------------------------------------------
37
- // Argument parsing
38
- // ---------------------------------------------------------------------------
39
- const args = process.argv.slice(2);
40
- let ROOT = path.resolve(__dirname, '..');
41
- let CJS_DIR = null; // resolved below
42
- let SDK_SRC = null; // resolved below
43
- let SDK_SRC_EXPLICIT = false;
44
- let ALLOWLIST_OVERRIDE = null; // resolved below
45
- let WARN_ALL = false;
46
- let JSON_OUTPUT = false;
47
-
48
- for (let i = 0; i < args.length; i++) {
49
- if (args[i] === '--root' && args[i + 1]) {
50
- ROOT = path.resolve(args[++i]);
51
- } else if (args[i] === '--cjs-dir' && args[i + 1]) {
52
- CJS_DIR = path.resolve(args[++i]);
53
- } else if (args[i] === '--sdk-src' && args[i + 1]) {
54
- SDK_SRC = path.resolve(args[++i]);
55
- SDK_SRC_EXPLICIT = true;
56
- } else if (args[i] === '--allowlist' && args[i + 1]) {
57
- ALLOWLIST_OVERRIDE = path.resolve(args[++i]);
58
- } else if (args[i] === '--warn-all') {
59
- WARN_ALL = true;
60
- } else if (args[i] === '--json') {
61
- JSON_OUTPUT = true;
62
- }
63
- }
64
-
65
- if (!CJS_DIR) CJS_DIR = path.join(ROOT, 'get-shit-done', 'bin', 'lib');
66
- if (!SDK_SRC) SDK_SRC = path.join(ROOT, 'sdk', 'src');
67
-
68
- // ---------------------------------------------------------------------------
69
- // Load allowlist
70
- // When --root is given (e.g. in tests), prefer <ROOT>/scripts/allowlist.json
71
- // so fixture trees can supply their own allowlist. Fall back to the copy
72
- // co-located with this script (default production path).
73
- // ---------------------------------------------------------------------------
74
- const ALLOWLIST_PATH = ALLOWLIST_OVERRIDE
75
- ? ALLOWLIST_OVERRIDE
76
- : fs.existsSync(path.join(ROOT, 'scripts', 'shared-module-handsync-allowlist.json'))
77
- ? path.join(ROOT, 'scripts', 'shared-module-handsync-allowlist.json')
78
- : path.join(__dirname, 'shared-module-handsync-allowlist.json');
79
- let allowlist;
80
- try {
81
- allowlist = JSON.parse(fs.readFileSync(ALLOWLIST_PATH, 'utf8'));
82
- } catch (err) {
83
- process.stderr.write(
84
- `lint-shared-module-handsync: failed to read allowlist at ${ALLOWLIST_PATH}: ${err.message}\n`
85
- );
86
- process.exit(1);
87
- }
88
-
89
- /**
90
- * Pair identity = `${cjs}::${ts}`. Keying on the pair (not just cjs)
91
- * prevents an allowlisted entry from silently passing an unintended
92
- * sibling at a different ts path with the same basename.
93
- *
94
- * @type {Set<string>} pair identities in cooperatingSiblings
95
- */
96
- const cooperatingPairs = new Set(
97
- (allowlist.cooperatingSiblings || []).map((e) => `${e.cjs}::${e.ts}`)
98
- );
99
-
100
- /** @type {Map<string, object>} pair identity -> entry for migrateMeBacklog */
101
- const migrateMap = new Map(
102
- (allowlist.migrateMeBacklog || []).map((e) => [`${e.cjs}::${e.ts}`, e])
103
- );
104
-
105
- /** @type {Map<string, Set<string>>} cjs rel path -> explicit declared ts rel paths */
106
- const explicitTsByCjs = new Map();
107
- for (const entry of [
108
- ...(allowlist.cooperatingSiblings || []),
109
- ...(allowlist.migrateMeBacklog || []),
110
- ]) {
111
- if (!entry || typeof entry.cjs !== 'string' || typeof entry.ts !== 'string') continue;
112
- if (!explicitTsByCjs.has(entry.cjs)) explicitTsByCjs.set(entry.cjs, new Set());
113
- explicitTsByCjs.get(entry.cjs).add(entry.ts);
114
- }
115
-
116
- // ---------------------------------------------------------------------------
117
- // Build SDK name index: name -> array of absolute TS paths
118
- // (excludes *.generated.ts and *.test.ts)
119
- // ---------------------------------------------------------------------------
120
- function buildSdkIndex(sdkSrc) {
121
- const index = new Map(); // name -> [absPath, ...]
122
-
123
- function addEntry(name, absPath) {
124
- if (!index.has(name)) index.set(name, []);
125
- index.get(name).push(absPath);
126
- }
127
-
128
- function walk(dir) {
129
- let entries;
130
- try {
131
- entries = fs.readdirSync(dir, { withFileTypes: true });
132
- } catch (_) {
133
- return;
134
- }
135
- for (const ent of entries) {
136
- const abs = path.join(dir, ent.name);
137
- if (ent.isDirectory()) {
138
- walk(abs);
139
- } else if (ent.isFile() && ent.name.endsWith('.ts') &&
140
- !ent.name.endsWith('.generated.ts') &&
141
- !ent.name.endsWith('.test.ts')) {
142
- const rel = path.relative(sdkSrc, abs);
143
- const parts = rel.split(path.sep);
144
-
145
- // sdk/src/<name>.ts (direct child, not in a subdir)
146
- if (parts.length === 1) {
147
- const name = parts[0].slice(0, -3); // strip .ts
148
- addEntry(name, abs);
149
- }
150
- // sdk/src/<name>/index.ts (one subdir deep, file is index.ts)
151
- else if (parts.length === 2 && parts[1] === 'index.ts') {
152
- const name = parts[0];
153
- addEntry(name, abs);
154
- }
155
- // sdk/src/query/<name>.ts (exactly: query/<something>.ts)
156
- else if (parts.length === 2 && parts[0] === 'query' && parts[1] !== 'index.ts') {
157
- const name = parts[1].slice(0, -3); // strip .ts
158
- addEntry(name, abs);
159
- }
160
- }
161
- }
162
- }
163
-
164
- walk(sdkSrc);
165
- return index;
166
- }
167
-
168
- // ---------------------------------------------------------------------------
169
- // Scan CJS files (direct children only; exclude *.generated.cjs)
170
- // ---------------------------------------------------------------------------
171
- function scanCjsFiles(cjsDir) {
172
- let entries;
173
- try {
174
- entries = fs.readdirSync(cjsDir, { withFileTypes: true });
175
- } catch (err) {
176
- process.stderr.write(
177
- `lint-shared-module-handsync: cannot read CJS dir ${cjsDir}: ${err.message}\n`
178
- );
179
- process.exit(1);
180
- }
181
- return entries
182
- .filter(
183
- (e) =>
184
- e.isFile() &&
185
- e.name.endsWith('.cjs') &&
186
- !e.name.endsWith('.generated.cjs')
187
- )
188
- .map((e) => ({
189
- name: e.name.slice(0, -4), // strip .cjs
190
- absPath: path.join(cjsDir, e.name),
191
- }));
192
- }
193
-
194
- // ---------------------------------------------------------------------------
195
- // Main
196
- // ---------------------------------------------------------------------------
197
- function emitJson(payload) {
198
- process.stdout.write(JSON.stringify(payload) + '\n');
199
- }
200
-
201
- function main() {
202
- // Check that the directories exist
203
- if (!fs.existsSync(CJS_DIR)) {
204
- if (JSON_OUTPUT) {
205
- emitJson({ ok: false, reason: 'cjs_dir_missing', path: CJS_DIR });
206
- } else {
207
- process.stderr.write(
208
- `lint-shared-module-handsync: CJS dir not found: ${CJS_DIR}\n` +
209
- ` Pass --root <repo-root> or --cjs-dir <path> to override.\n`
210
- );
211
- }
212
- process.exit(1);
213
- }
214
- if (!fs.existsSync(SDK_SRC)) {
215
- // SDK tree was retired in ADR-0174 Phase 5.2. In default repo mode this
216
- // lint becomes a no-op success; explicit --sdk-src remains fail-loud.
217
- if (SDK_SRC_EXPLICIT) {
218
- if (JSON_OUTPUT) {
219
- emitJson({ ok: false, reason: 'sdk_src_missing', path: SDK_SRC });
220
- } else {
221
- process.stderr.write(
222
- `lint-shared-module-handsync: SDK src dir not found: ${SDK_SRC}\n` +
223
- ` Pass --root <repo-root> or --sdk-src <path> to override.\n`
224
- );
225
- }
226
- process.exit(1);
227
- }
228
-
229
- if (JSON_OUTPUT) {
230
- emitJson({
231
- ok: true,
232
- reason: 'sdk_retired',
233
- cooperatingCount: 0,
234
- backlogCount: 0,
235
- warnings: [],
236
- });
237
- } else {
238
- process.stdout.write(
239
- 'ok lint-shared-module-handsync: SDK source tree retired; no hand-sync pairs to lint.\n'
240
- );
241
- }
242
- process.exit(0);
243
- }
244
-
245
- const sdkIndex = buildSdkIndex(SDK_SRC);
246
- const cjsFiles = scanCjsFiles(CJS_DIR);
247
-
248
- const errors = [];
249
- const warnings = [];
250
-
251
- function candidateTsPathsFor(relCjs, name) {
252
- const byName = sdkIndex.has(name)
253
- ? sdkIndex
254
- .get(name)
255
- .map((p) => path.relative(ROOT, p).replace(/\\/g, '/'))
256
- : [];
257
-
258
- const declared = explicitTsByCjs.has(relCjs)
259
- ? Array.from(explicitTsByCjs.get(relCjs))
260
- : [];
261
-
262
- const declaredExisting = declared.filter((relTs) => {
263
- const abs = path.join(ROOT, relTs);
264
- return (
265
- relTs.endsWith('.ts') &&
266
- !relTs.endsWith('.generated.ts') &&
267
- !relTs.endsWith('.test.ts') &&
268
- fs.existsSync(abs) &&
269
- fs.statSync(abs).isFile()
270
- );
271
- });
272
-
273
- return Array.from(new Set([...byName, ...declaredExisting]));
274
- }
275
-
276
- for (const { name, absPath } of cjsFiles) {
277
- // Compute relative CJS path and all declared/discovered TS candidates.
278
- const relCjs = path.relative(ROOT, absPath).replace(/\\/g, '/');
279
- const tsPaths = candidateTsPathsFor(relCjs, name);
280
- if (tsPaths.length === 0) continue;
281
-
282
- // Pair-aware matching, per ts sibling. Each ts candidate is classified
283
- // independently against the allowlist so a partially-allowlisted set of
284
- // siblings still surfaces the unauthorized ones. See #3632.
285
- const unauthorizedTs = [];
286
- const backlogTsForCjs = [];
287
- for (const relTs of tsPaths) {
288
- const pairKey = `${relCjs}::${relTs}`;
289
- if (cooperatingPairs.has(pairKey)) continue;
290
- if (migrateMap.has(pairKey)) {
291
- backlogTsForCjs.push(relTs);
292
- continue;
293
- }
294
- unauthorizedTs.push(relTs);
295
- }
296
-
297
- if (unauthorizedTs.length > 0) {
298
- errors.push({ relCjs, tsPaths: unauthorizedTs });
299
- }
300
- if (backlogTsForCjs.length > 0) {
301
- const entry = migrateMap.get(`${relCjs}::${backlogTsForCjs[0]}`);
302
- warnings.push({ relCjs, tsPaths: backlogTsForCjs, entry });
303
- }
304
- }
305
-
306
- // Count cjs files whose pair identity (cjs+ts) is on cooperatingSiblings.
307
- // A file with multiple ts candidates is counted once if any pair matches.
308
- const cooperatingCount = cjsFiles.filter((f) => {
309
- const relCjs = path.relative(ROOT, f.absPath).replace(/\\/g, '/');
310
- return candidateTsPathsFor(relCjs, f.name).some((relTs) =>
311
- cooperatingPairs.has(`${relCjs}::${relTs}`)
312
- );
313
- }).length;
314
-
315
- // -------------------------------------------------------------------------
316
- // Report errors (exit 1)
317
- // -------------------------------------------------------------------------
318
- if (errors.length > 0) {
319
- if (JSON_OUTPUT) {
320
- emitJson({
321
- ok: false,
322
- reason: 'unauthorized_pairs',
323
- errors,
324
- warnings,
325
- cooperatingCount,
326
- });
327
- } else {
328
- process.stderr.write(
329
- `\nERROR lint-shared-module-handsync: ${errors.length} unauthorized hand-sync pair(s) found.\n\n`
330
- );
331
- for (const { relCjs, tsPaths } of errors) {
332
- process.stderr.write(` CJS: ${relCjs}\n`);
333
- for (const ts of tsPaths) {
334
- process.stderr.write(` TS: ${ts}\n`);
335
- }
336
- process.stderr.write('\n');
337
- }
338
- process.stderr.write(
339
- 'To resolve, choose one of:\n' +
340
- ' 1. Migrate to a Shared Module (preferred): create sdk/src/<name>/index.ts as the\n' +
341
- ' source-of-truth, write a generator script (sdk/scripts/gen-<name>.mjs), add a\n' +
342
- ' freshness check, and update CI. See docs/agents/cjs-sdk-seam.md for the pattern.\n' +
343
- ' 2. Add an explicit allowlist entry to scripts/shared-module-handsync-allowlist.json\n' +
344
- ' with a justification explaining why this pair is a legitimate cooperating sibling\n' +
345
- ' rather than a drift anti-pattern. Requires maintainer review via CODEOWNERS.\n\n'
346
- );
347
- }
348
- process.exit(1);
349
- }
350
-
351
- // -------------------------------------------------------------------------
352
- // Report warnings (no exit code change)
353
- // -------------------------------------------------------------------------
354
- if (warnings.length > 0 && WARN_ALL && !JSON_OUTPUT) {
355
- process.stderr.write(
356
- `\nWARNING lint-shared-module-handsync: ${warnings.length} known drift anti-pattern pair(s) in migrateMeBacklog.\n` +
357
- `These are tracked for future Shared Module migration but do not block CI.\n\n`
358
- );
359
- for (const { relCjs, tsPaths, entry } of warnings) {
360
- process.stderr.write(` CJS: ${relCjs}\n`);
361
- for (const ts of tsPaths) {
362
- process.stderr.write(` TS: ${ts}\n`);
363
- }
364
- process.stderr.write(` Tracked: ${entry.trackedIn}\n`);
365
- process.stderr.write(` Hint: ${entry.justification}\n\n`);
366
- }
367
- }
368
-
369
- // -------------------------------------------------------------------------
370
- // Success
371
- // -------------------------------------------------------------------------
372
- if (JSON_OUTPUT) {
373
- emitJson({
374
- ok: true,
375
- cooperatingCount,
376
- backlogCount: warnings.length,
377
- warnings,
378
- });
379
- } else {
380
- process.stdout.write(
381
- `ok lint-shared-module-handsync: no unauthorized hand-sync pairs found` +
382
- ` (${cooperatingCount} cooperating sibling(s), ${warnings.length} backlog pair(s))\n`
383
- );
384
- }
385
- process.exit(0);
386
- }
387
-
388
- main();