@therocketcode/gsd-core 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/.claude-plugin/plugin.json +23 -0
  2. package/GEMINI.md +53 -0
  3. package/LICENSE +21 -0
  4. package/README.ja-JP.md +125 -0
  5. package/README.ko-KR.md +125 -0
  6. package/README.md +144 -0
  7. package/README.pt-BR.md +125 -0
  8. package/README.zh-CN.md +125 -0
  9. package/agents/gsd-advisor-researcher.md +108 -0
  10. package/agents/gsd-ai-researcher.md +114 -0
  11. package/agents/gsd-assumptions-analyzer.md +105 -0
  12. package/agents/gsd-code-fixer.md +668 -0
  13. package/agents/gsd-code-reviewer.md +387 -0
  14. package/agents/gsd-codebase-mapper.md +853 -0
  15. package/agents/gsd-debug-session-manager.md +314 -0
  16. package/agents/gsd-debugger.md +1452 -0
  17. package/agents/gsd-doc-classifier.md +168 -0
  18. package/agents/gsd-doc-synthesizer.md +204 -0
  19. package/agents/gsd-doc-verifier.md +217 -0
  20. package/agents/gsd-doc-writer.md +616 -0
  21. package/agents/gsd-domain-researcher.md +147 -0
  22. package/agents/gsd-eval-auditor.md +191 -0
  23. package/agents/gsd-eval-planner.md +154 -0
  24. package/agents/gsd-executor.md +785 -0
  25. package/agents/gsd-framework-selector.md +160 -0
  26. package/agents/gsd-integration-checker.md +470 -0
  27. package/agents/gsd-intel-updater.md +342 -0
  28. package/agents/gsd-nyquist-auditor.md +203 -0
  29. package/agents/gsd-pattern-mapper.md +335 -0
  30. package/agents/gsd-phase-researcher.md +867 -0
  31. package/agents/gsd-plan-checker.md +978 -0
  32. package/agents/gsd-planner.md +1204 -0
  33. package/agents/gsd-project-researcher.md +611 -0
  34. package/agents/gsd-research-synthesizer.md +259 -0
  35. package/agents/gsd-roadmapper.md +688 -0
  36. package/agents/gsd-security-auditor.md +155 -0
  37. package/agents/gsd-ui-auditor.md +495 -0
  38. package/agents/gsd-ui-checker.md +309 -0
  39. package/agents/gsd-ui-researcher.md +374 -0
  40. package/agents/gsd-user-profiler.md +171 -0
  41. package/agents/gsd-verifier.md +923 -0
  42. package/assets/gsd-logo-2000-transparent.png +0 -0
  43. package/assets/gsd-logo-2000-transparent.svg +17 -0
  44. package/assets/gsd-logo-2000.png +0 -0
  45. package/assets/gsd-logo-2000.svg +21 -0
  46. package/assets/terminal.svg +68 -0
  47. package/bin/install.js +12726 -0
  48. package/bin/lib/ui-safety-gate.cjs +107 -0
  49. package/commands/gsd/add-tests.md +42 -0
  50. package/commands/gsd/ai-integration-phase.md +37 -0
  51. package/commands/gsd/audit-fix.md +34 -0
  52. package/commands/gsd/audit-milestone.md +37 -0
  53. package/commands/gsd/audit-uat.md +24 -0
  54. package/commands/gsd/autonomous.md +48 -0
  55. package/commands/gsd/capture.md +62 -0
  56. package/commands/gsd/cleanup.md +24 -0
  57. package/commands/gsd/code-review.md +59 -0
  58. package/commands/gsd/complete-milestone.md +143 -0
  59. package/commands/gsd/config.md +56 -0
  60. package/commands/gsd/debug.md +52 -0
  61. package/commands/gsd/discover-product.md +65 -0
  62. package/commands/gsd/discuss-phase.md +77 -0
  63. package/commands/gsd/docs-update.md +49 -0
  64. package/commands/gsd/eval-review.md +33 -0
  65. package/commands/gsd/execute-phase.md +66 -0
  66. package/commands/gsd/explore.md +27 -0
  67. package/commands/gsd/extract-learnings.md +23 -0
  68. package/commands/gsd/fast.md +31 -0
  69. package/commands/gsd/forensics.md +57 -0
  70. package/commands/gsd/graphify.md +204 -0
  71. package/commands/gsd/health.md +31 -0
  72. package/commands/gsd/help.md +28 -0
  73. package/commands/gsd/import.md +45 -0
  74. package/commands/gsd/inbox.md +39 -0
  75. package/commands/gsd/ingest-docs.md +42 -0
  76. package/commands/gsd/manager.md +45 -0
  77. package/commands/gsd/map-codebase.md +83 -0
  78. package/commands/gsd/milestone-summary.md +51 -0
  79. package/commands/gsd/model-domain.md +65 -0
  80. package/commands/gsd/mvp-phase.md +45 -0
  81. package/commands/gsd/new-milestone.md +45 -0
  82. package/commands/gsd/new-project.md +47 -0
  83. package/commands/gsd/ns-context.md +23 -0
  84. package/commands/gsd/ns-ideate.md +24 -0
  85. package/commands/gsd/ns-manage.md +29 -0
  86. package/commands/gsd/ns-project.md +22 -0
  87. package/commands/gsd/ns-review.md +26 -0
  88. package/commands/gsd/ns-workflow.md +28 -0
  89. package/commands/gsd/pause-work.md +43 -0
  90. package/commands/gsd/phase.md +56 -0
  91. package/commands/gsd/plan-phase.md +64 -0
  92. package/commands/gsd/plan-review-convergence.md +59 -0
  93. package/commands/gsd/pr-branch.md +26 -0
  94. package/commands/gsd/profile-user.md +46 -0
  95. package/commands/gsd/progress.md +48 -0
  96. package/commands/gsd/quick.md +174 -0
  97. package/commands/gsd/recommend-architecture.md +64 -0
  98. package/commands/gsd/resume-work.md +30 -0
  99. package/commands/gsd/review-backlog.md +63 -0
  100. package/commands/gsd/review.md +42 -0
  101. package/commands/gsd/secure-phase.md +36 -0
  102. package/commands/gsd/settings.md +29 -0
  103. package/commands/gsd/ship.md +24 -0
  104. package/commands/gsd/sketch.md +60 -0
  105. package/commands/gsd/spec-phase.md +63 -0
  106. package/commands/gsd/spike.md +57 -0
  107. package/commands/gsd/stats.md +20 -0
  108. package/commands/gsd/surface.md +155 -0
  109. package/commands/gsd/testing-strategy.md +65 -0
  110. package/commands/gsd/thread.md +24 -0
  111. package/commands/gsd/ui-phase.md +35 -0
  112. package/commands/gsd/ui-review.md +33 -0
  113. package/commands/gsd/ultraplan-phase.md +34 -0
  114. package/commands/gsd/undo.md +35 -0
  115. package/commands/gsd/update.md +49 -0
  116. package/commands/gsd/validate-phase.md +36 -0
  117. package/commands/gsd/verify-work.md +39 -0
  118. package/commands/gsd/workspace.md +52 -0
  119. package/commands/gsd/workstreams.md +70 -0
  120. package/gemini-extension.json +6 -0
  121. package/gsd-core/bin/check-latest-version.cjs +161 -0
  122. package/gsd-core/bin/gsd-tools.cjs +1928 -0
  123. package/gsd-core/bin/lib/active-workstream-store.cjs +291 -0
  124. package/gsd-core/bin/lib/adr-parser.cjs +399 -0
  125. package/gsd-core/bin/lib/agent-command-router.cjs +68 -0
  126. package/gsd-core/bin/lib/artifacts.cjs +51 -0
  127. package/gsd-core/bin/lib/audit.cjs +743 -0
  128. package/gsd-core/bin/lib/check-command-router.cjs +343 -0
  129. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
  130. package/gsd-core/bin/lib/cli-exit.cjs +42 -0
  131. package/gsd-core/bin/lib/clock.cjs +95 -0
  132. package/gsd-core/bin/lib/clusters.cjs +132 -0
  133. package/gsd-core/bin/lib/code-review-flags.cjs +59 -0
  134. package/gsd-core/bin/lib/command-aliases.cjs +809 -0
  135. package/gsd-core/bin/lib/command-arg-projection.cjs +55 -0
  136. package/gsd-core/bin/lib/command-routing-hub.cjs +300 -0
  137. package/gsd-core/bin/lib/commands.cjs +1203 -0
  138. package/gsd-core/bin/lib/config-schema.cjs +29 -0
  139. package/gsd-core/bin/lib/config-types.cjs +19 -0
  140. package/gsd-core/bin/lib/config.cjs +738 -0
  141. package/gsd-core/bin/lib/configuration.cjs +239 -0
  142. package/gsd-core/bin/lib/context-utilization.cjs +48 -0
  143. package/gsd-core/bin/lib/core.cjs +2051 -0
  144. package/gsd-core/bin/lib/decisions.cjs +118 -0
  145. package/gsd-core/bin/lib/docs.cjs +252 -0
  146. package/gsd-core/bin/lib/drift.cjs +364 -0
  147. package/gsd-core/bin/lib/fallow-runner.cjs +115 -0
  148. package/gsd-core/bin/lib/frontmatter.cjs +442 -0
  149. package/gsd-core/bin/lib/gap-checker.cjs +257 -0
  150. package/gsd-core/bin/lib/graphify.cjs +496 -0
  151. package/gsd-core/bin/lib/gsd2-import.cjs +456 -0
  152. package/gsd-core/bin/lib/init-command-router.cjs +62 -0
  153. package/gsd-core/bin/lib/init.cjs +1815 -0
  154. package/gsd-core/bin/lib/install-profiles.cjs +584 -0
  155. package/gsd-core/bin/lib/installer-migration-authoring.cjs +122 -0
  156. package/gsd-core/bin/lib/installer-migration-report.cjs +350 -0
  157. package/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +218 -0
  158. package/gsd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
  159. package/gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
  160. package/gsd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
  161. package/gsd-core/bin/lib/installer-migrations.cjs +823 -0
  162. package/gsd-core/bin/lib/intel.cjs +590 -0
  163. package/gsd-core/bin/lib/learnings.cjs +270 -0
  164. package/gsd-core/bin/lib/legacy-cleanup.cjs +253 -0
  165. package/gsd-core/bin/lib/milestone.cjs +373 -0
  166. package/gsd-core/bin/lib/model-catalog.cjs +154 -0
  167. package/gsd-core/bin/lib/model-profiles.cjs +24 -0
  168. package/gsd-core/bin/lib/observability/event.cjs +51 -0
  169. package/gsd-core/bin/lib/observability/logger.cjs +146 -0
  170. package/gsd-core/bin/lib/observability/redaction.cjs +48 -0
  171. package/gsd-core/bin/lib/package-identity.cjs +35 -0
  172. package/gsd-core/bin/lib/package-legitimacy.cjs +368 -0
  173. package/gsd-core/bin/lib/phase-command-router.cjs +189 -0
  174. package/gsd-core/bin/lib/phase-lifecycle.cjs +74 -0
  175. package/gsd-core/bin/lib/phase.cjs +1307 -0
  176. package/gsd-core/bin/lib/phases-command-router.cjs +43 -0
  177. package/gsd-core/bin/lib/plan-scan.cjs +91 -0
  178. package/gsd-core/bin/lib/planning-workspace.cjs +245 -0
  179. package/gsd-core/bin/lib/profile-output.cjs +1120 -0
  180. package/gsd-core/bin/lib/profile-pipeline.cjs +517 -0
  181. package/gsd-core/bin/lib/project-root.cjs +119 -0
  182. package/gsd-core/bin/lib/prompt-budget.cjs +305 -0
  183. package/gsd-core/bin/lib/research-provider.cjs +137 -0
  184. package/gsd-core/bin/lib/research-store.cjs +167 -0
  185. package/gsd-core/bin/lib/review-reviewer-selection.cjs +121 -0
  186. package/gsd-core/bin/lib/roadmap-command-router.cjs +166 -0
  187. package/gsd-core/bin/lib/roadmap-upgrade.cjs +476 -0
  188. package/gsd-core/bin/lib/roadmap.cjs +600 -0
  189. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +312 -0
  190. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +56 -0
  191. package/gsd-core/bin/lib/runtime-homes.cjs +190 -0
  192. package/gsd-core/bin/lib/runtime-name-policy.cjs +96 -0
  193. package/gsd-core/bin/lib/runtime-slash.cjs +119 -0
  194. package/gsd-core/bin/lib/schema-detect.cjs +159 -0
  195. package/gsd-core/bin/lib/secrets.cjs +34 -0
  196. package/gsd-core/bin/lib/security.cjs +480 -0
  197. package/gsd-core/bin/lib/semver-compare.cjs +42 -0
  198. package/gsd-core/bin/lib/shell-command-projection.cjs +533 -0
  199. package/gsd-core/bin/lib/state-command-router.cjs +160 -0
  200. package/gsd-core/bin/lib/state-document.cjs +259 -0
  201. package/gsd-core/bin/lib/state.cjs +2010 -0
  202. package/gsd-core/bin/lib/surface.cjs +449 -0
  203. package/gsd-core/bin/lib/task-command-router.cjs +85 -0
  204. package/gsd-core/bin/lib/template.cjs +237 -0
  205. package/gsd-core/bin/lib/uat.cjs +297 -0
  206. package/gsd-core/bin/lib/ui-safety-gate.cjs +98 -0
  207. package/gsd-core/bin/lib/update-context.cjs +218 -0
  208. package/gsd-core/bin/lib/validate-command-router.cjs +91 -0
  209. package/gsd-core/bin/lib/validate.cjs +112 -0
  210. package/gsd-core/bin/lib/verification-command-router.cjs +31 -0
  211. package/gsd-core/bin/lib/verification.cjs +193 -0
  212. package/gsd-core/bin/lib/verify-command-router.cjs +44 -0
  213. package/gsd-core/bin/lib/verify.cjs +1451 -0
  214. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +81 -0
  215. package/gsd-core/bin/lib/workstream-inventory.cjs +147 -0
  216. package/gsd-core/bin/lib/workstream-name-policy.cjs +91 -0
  217. package/gsd-core/bin/lib/workstream.cjs +380 -0
  218. package/gsd-core/bin/lib/worktree-base-ref.cjs +325 -0
  219. package/gsd-core/bin/lib/worktree-safety.cjs +943 -0
  220. package/gsd-core/bin/shared/config-defaults.manifest.json +98 -0
  221. package/gsd-core/bin/shared/config-schema.manifest.json +192 -0
  222. package/gsd-core/bin/shared/model-catalog.json +149 -0
  223. package/gsd-core/bin/shared/runtime-aliases.manifest.json +75 -0
  224. package/gsd-core/bin/verify-reapply-patches.cjs +349 -0
  225. package/gsd-core/contexts/dev.md +21 -0
  226. package/gsd-core/contexts/research.md +22 -0
  227. package/gsd-core/contexts/review.md +23 -0
  228. package/gsd-core/references/agent-contracts.md +79 -0
  229. package/gsd-core/references/ai-evals.md +156 -0
  230. package/gsd-core/references/ai-frameworks.md +186 -0
  231. package/gsd-core/references/architecture-decision.md +74 -0
  232. package/gsd-core/references/artifact-types.md +131 -0
  233. package/gsd-core/references/auth-in-tests.md +91 -0
  234. package/gsd-core/references/autonomous-smart-discuss.md +277 -0
  235. package/gsd-core/references/checkpoints.md +814 -0
  236. package/gsd-core/references/common-bug-patterns.md +114 -0
  237. package/gsd-core/references/context-budget.md +85 -0
  238. package/gsd-core/references/continuation-format.md +253 -0
  239. package/gsd-core/references/db-test-isolation.md +54 -0
  240. package/gsd-core/references/debugger-philosophy.md +76 -0
  241. package/gsd-core/references/decimal-phase-calculation.md +64 -0
  242. package/gsd-core/references/doc-conflict-engine.md +91 -0
  243. package/gsd-core/references/domain-modeling.md +80 -0
  244. package/gsd-core/references/domain-probes.md +125 -0
  245. package/gsd-core/references/e2e-tiering.md +35 -0
  246. package/gsd-core/references/execute-mvp-tdd.md +81 -0
  247. package/gsd-core/references/executor-examples.md +110 -0
  248. package/gsd-core/references/few-shot-examples/plan-checker.md +73 -0
  249. package/gsd-core/references/few-shot-examples/verifier.md +109 -0
  250. package/gsd-core/references/flaky-test-checklist.md +22 -0
  251. package/gsd-core/references/gate-prompts.md +100 -0
  252. package/gsd-core/references/gates.md +70 -0
  253. package/gsd-core/references/git-integration.md +298 -0
  254. package/gsd-core/references/git-planning-commit.md +40 -0
  255. package/gsd-core/references/ios-scaffold.md +123 -0
  256. package/gsd-core/references/mandatory-initial-read.md +2 -0
  257. package/gsd-core/references/model-profile-resolution.md +38 -0
  258. package/gsd-core/references/model-profiles.md +245 -0
  259. package/gsd-core/references/mvp-concepts.md +49 -0
  260. package/gsd-core/references/phase-argument-parsing.md +61 -0
  261. package/gsd-core/references/planner-antipatterns.md +89 -0
  262. package/gsd-core/references/planner-chunked.md +49 -0
  263. package/gsd-core/references/planner-gap-closure.md +62 -0
  264. package/gsd-core/references/planner-graphify-auto-update.md +67 -0
  265. package/gsd-core/references/planner-human-verify-mode.md +57 -0
  266. package/gsd-core/references/planner-interface-context.md +62 -0
  267. package/gsd-core/references/planner-load-graph-context.md +36 -0
  268. package/gsd-core/references/planner-mvp-mode.md +53 -0
  269. package/gsd-core/references/planner-reviews.md +39 -0
  270. package/gsd-core/references/planner-revision.md +87 -0
  271. package/gsd-core/references/planner-source-audit.md +73 -0
  272. package/gsd-core/references/planning-config.md +473 -0
  273. package/gsd-core/references/product-discovery.md +49 -0
  274. package/gsd-core/references/project-skills-discovery.md +19 -0
  275. package/gsd-core/references/questioning.md +162 -0
  276. package/gsd-core/references/realistic-test-data.md +44 -0
  277. package/gsd-core/references/research-documentation-lookup.md +29 -0
  278. package/gsd-core/references/research-philosophy.md +29 -0
  279. package/gsd-core/references/research-verification-protocol.md +27 -0
  280. package/gsd-core/references/revision-loop.md +97 -0
  281. package/gsd-core/references/scout-codebase.md +51 -0
  282. package/gsd-core/references/skeleton-template.md +48 -0
  283. package/gsd-core/references/sketch-interactivity.md +41 -0
  284. package/gsd-core/references/sketch-theme-system.md +94 -0
  285. package/gsd-core/references/sketch-tooling.md +45 -0
  286. package/gsd-core/references/sketch-variant-patterns.md +81 -0
  287. package/gsd-core/references/spidr-splitting.md +69 -0
  288. package/gsd-core/references/tdd.md +330 -0
  289. package/gsd-core/references/test-containers.md +55 -0
  290. package/gsd-core/references/test-strategy.md +75 -0
  291. package/gsd-core/references/thinking-models-debug.md +44 -0
  292. package/gsd-core/references/thinking-models-execution.md +50 -0
  293. package/gsd-core/references/thinking-models-planning.md +62 -0
  294. package/gsd-core/references/thinking-models-research.md +50 -0
  295. package/gsd-core/references/thinking-models-verification.md +55 -0
  296. package/gsd-core/references/thinking-partner.md +96 -0
  297. package/gsd-core/references/ui-brand.md +162 -0
  298. package/gsd-core/references/universal-anti-patterns.md +63 -0
  299. package/gsd-core/references/user-profiling.md +681 -0
  300. package/gsd-core/references/user-story-template.md +58 -0
  301. package/gsd-core/references/verification-overrides.md +227 -0
  302. package/gsd-core/references/verification-patterns.md +612 -0
  303. package/gsd-core/references/verify-mvp-mode.md +85 -0
  304. package/gsd-core/references/workstream-flag.md +111 -0
  305. package/gsd-core/references/worktree-branch-check.md +38 -0
  306. package/gsd-core/references/worktree-path-safety.md +67 -0
  307. package/gsd-core/templates/AI-SPEC.md +246 -0
  308. package/gsd-core/templates/DEBUG.md +169 -0
  309. package/gsd-core/templates/README.md +77 -0
  310. package/gsd-core/templates/SECURITY.md +61 -0
  311. package/gsd-core/templates/UAT.md +265 -0
  312. package/gsd-core/templates/UI-SPEC.md +100 -0
  313. package/gsd-core/templates/VALIDATION.md +76 -0
  314. package/gsd-core/templates/adr.md +58 -0
  315. package/gsd-core/templates/claude-md.md +145 -0
  316. package/gsd-core/templates/codebase/architecture.md +255 -0
  317. package/gsd-core/templates/codebase/concerns.md +310 -0
  318. package/gsd-core/templates/codebase/conventions.md +307 -0
  319. package/gsd-core/templates/codebase/integrations.md +280 -0
  320. package/gsd-core/templates/codebase/stack.md +186 -0
  321. package/gsd-core/templates/codebase/structure.md +285 -0
  322. package/gsd-core/templates/codebase/testing.md +480 -0
  323. package/gsd-core/templates/config.json +62 -0
  324. package/gsd-core/templates/context.md +352 -0
  325. package/gsd-core/templates/continue-here.md +78 -0
  326. package/gsd-core/templates/copilot-instructions.md +7 -0
  327. package/gsd-core/templates/debug-subagent-prompt.md +91 -0
  328. package/gsd-core/templates/dev-preferences.md +21 -0
  329. package/gsd-core/templates/discovery.md +146 -0
  330. package/gsd-core/templates/discussion-log.md +63 -0
  331. package/gsd-core/templates/domain-model.md +54 -0
  332. package/gsd-core/templates/milestone-archive.md +123 -0
  333. package/gsd-core/templates/milestone.md +115 -0
  334. package/gsd-core/templates/phase-prompt.md +610 -0
  335. package/gsd-core/templates/planner-subagent-prompt.md +117 -0
  336. package/gsd-core/templates/product-brief.md +55 -0
  337. package/gsd-core/templates/project.md +186 -0
  338. package/gsd-core/templates/requirements.md +231 -0
  339. package/gsd-core/templates/research-project/ARCHITECTURE.md +204 -0
  340. package/gsd-core/templates/research-project/FEATURES.md +147 -0
  341. package/gsd-core/templates/research-project/PITFALLS.md +200 -0
  342. package/gsd-core/templates/research-project/STACK.md +120 -0
  343. package/gsd-core/templates/research-project/SUMMARY.md +170 -0
  344. package/gsd-core/templates/research.md +592 -0
  345. package/gsd-core/templates/retrospective.md +54 -0
  346. package/gsd-core/templates/roadmap.md +202 -0
  347. package/gsd-core/templates/spec.md +307 -0
  348. package/gsd-core/templates/state.md +195 -0
  349. package/gsd-core/templates/summary-complex.md +59 -0
  350. package/gsd-core/templates/summary-minimal.md +41 -0
  351. package/gsd-core/templates/summary-standard.md +48 -0
  352. package/gsd-core/templates/summary.md +248 -0
  353. package/gsd-core/templates/test-strategy.md +50 -0
  354. package/gsd-core/templates/user-profile.md +146 -0
  355. package/gsd-core/templates/user-setup.md +311 -0
  356. package/gsd-core/templates/verification-report.md +322 -0
  357. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -0
  358. package/gsd-core/workflows/add-backlog.md +91 -0
  359. package/gsd-core/workflows/add-phase.md +113 -0
  360. package/gsd-core/workflows/add-tests.md +355 -0
  361. package/gsd-core/workflows/add-todo.md +161 -0
  362. package/gsd-core/workflows/ai-integration-phase.md +295 -0
  363. package/gsd-core/workflows/analyze-dependencies.md +96 -0
  364. package/gsd-core/workflows/audit-fix.md +178 -0
  365. package/gsd-core/workflows/audit-milestone.md +360 -0
  366. package/gsd-core/workflows/audit-uat.md +110 -0
  367. package/gsd-core/workflows/autonomous.md +797 -0
  368. package/gsd-core/workflows/check-todos.md +180 -0
  369. package/gsd-core/workflows/cleanup.md +195 -0
  370. package/gsd-core/workflows/code-review-fix.md +502 -0
  371. package/gsd-core/workflows/code-review.md +658 -0
  372. package/gsd-core/workflows/complete-milestone.md +855 -0
  373. package/gsd-core/workflows/debug.md +237 -0
  374. package/gsd-core/workflows/diagnose-issues.md +245 -0
  375. package/gsd-core/workflows/discover-product.md +112 -0
  376. package/gsd-core/workflows/discovery-phase.md +291 -0
  377. package/gsd-core/workflows/discuss-phase/modes/advisor.md +176 -0
  378. package/gsd-core/workflows/discuss-phase/modes/all.md +28 -0
  379. package/gsd-core/workflows/discuss-phase/modes/analyze.md +44 -0
  380. package/gsd-core/workflows/discuss-phase/modes/auto.md +57 -0
  381. package/gsd-core/workflows/discuss-phase/modes/batch.md +52 -0
  382. package/gsd-core/workflows/discuss-phase/modes/chain.md +98 -0
  383. package/gsd-core/workflows/discuss-phase/modes/default.md +141 -0
  384. package/gsd-core/workflows/discuss-phase/modes/power.md +44 -0
  385. package/gsd-core/workflows/discuss-phase/modes/text.md +55 -0
  386. package/gsd-core/workflows/discuss-phase/templates/checkpoint.json +18 -0
  387. package/gsd-core/workflows/discuss-phase/templates/context.md +136 -0
  388. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +50 -0
  389. package/gsd-core/workflows/discuss-phase-assumptions.md +675 -0
  390. package/gsd-core/workflows/discuss-phase-power.md +291 -0
  391. package/gsd-core/workflows/discuss-phase.md +499 -0
  392. package/gsd-core/workflows/do.md +111 -0
  393. package/gsd-core/workflows/docs-update.md +1176 -0
  394. package/gsd-core/workflows/edit-phase.md +295 -0
  395. package/gsd-core/workflows/eval-review.md +156 -0
  396. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +95 -0
  397. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
  398. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +117 -0
  399. package/gsd-core/workflows/execute-phase.md +1752 -0
  400. package/gsd-core/workflows/execute-plan.md +526 -0
  401. package/gsd-core/workflows/explore.md +146 -0
  402. package/gsd-core/workflows/extract-learnings.md +243 -0
  403. package/gsd-core/workflows/fast.md +124 -0
  404. package/gsd-core/workflows/forensics.md +279 -0
  405. package/gsd-core/workflows/graduation.md +196 -0
  406. package/gsd-core/workflows/health.md +224 -0
  407. package/gsd-core/workflows/help/modes/brief.md +22 -0
  408. package/gsd-core/workflows/help/modes/default.md +50 -0
  409. package/gsd-core/workflows/help/modes/full.md +789 -0
  410. package/gsd-core/workflows/help/modes/topic.md +74 -0
  411. package/gsd-core/workflows/help.md +24 -0
  412. package/gsd-core/workflows/import.md +256 -0
  413. package/gsd-core/workflows/inbox.md +387 -0
  414. package/gsd-core/workflows/ingest-docs.md +340 -0
  415. package/gsd-core/workflows/insert-phase.md +152 -0
  416. package/gsd-core/workflows/list-phase-assumptions.md +178 -0
  417. package/gsd-core/workflows/list-workspaces.md +57 -0
  418. package/gsd-core/workflows/manager.md +393 -0
  419. package/gsd-core/workflows/map-codebase.md +446 -0
  420. package/gsd-core/workflows/milestone-summary.md +224 -0
  421. package/gsd-core/workflows/model-domain.md +162 -0
  422. package/gsd-core/workflows/mvp-phase.md +222 -0
  423. package/gsd-core/workflows/new-milestone.md +635 -0
  424. package/gsd-core/workflows/new-project.md +1555 -0
  425. package/gsd-core/workflows/new-workspace.md +240 -0
  426. package/gsd-core/workflows/next.md +299 -0
  427. package/gsd-core/workflows/node-repair.md +92 -0
  428. package/gsd-core/workflows/note.md +158 -0
  429. package/gsd-core/workflows/pause-work.md +244 -0
  430. package/gsd-core/workflows/plan-milestone-gaps.md +281 -0
  431. package/gsd-core/workflows/plan-phase.md +1814 -0
  432. package/gsd-core/workflows/plan-review-convergence.md +346 -0
  433. package/gsd-core/workflows/plant-seed.md +230 -0
  434. package/gsd-core/workflows/pr-branch.md +157 -0
  435. package/gsd-core/workflows/profile-user.md +453 -0
  436. package/gsd-core/workflows/progress.md +699 -0
  437. package/gsd-core/workflows/quick.md +1017 -0
  438. package/gsd-core/workflows/reapply-patches.md +426 -0
  439. package/gsd-core/workflows/recommend-architecture.md +135 -0
  440. package/gsd-core/workflows/remove-phase.md +156 -0
  441. package/gsd-core/workflows/remove-workspace.md +108 -0
  442. package/gsd-core/workflows/resume-project.md +332 -0
  443. package/gsd-core/workflows/review.md +748 -0
  444. package/gsd-core/workflows/scan.md +107 -0
  445. package/gsd-core/workflows/secure-phase.md +182 -0
  446. package/gsd-core/workflows/session-report.md +146 -0
  447. package/gsd-core/workflows/settings-advanced.md +810 -0
  448. package/gsd-core/workflows/settings-integrations.md +312 -0
  449. package/gsd-core/workflows/settings.md +566 -0
  450. package/gsd-core/workflows/ship.md +405 -0
  451. package/gsd-core/workflows/sketch-wrap-up.md +286 -0
  452. package/gsd-core/workflows/sketch.md +361 -0
  453. package/gsd-core/workflows/spec-phase.md +263 -0
  454. package/gsd-core/workflows/spike-wrap-up.md +307 -0
  455. package/gsd-core/workflows/spike.md +453 -0
  456. package/gsd-core/workflows/stats.md +80 -0
  457. package/gsd-core/workflows/sync-skills.md +182 -0
  458. package/gsd-core/workflows/testing-strategy.md +122 -0
  459. package/gsd-core/workflows/thread.md +222 -0
  460. package/gsd-core/workflows/transition.md +694 -0
  461. package/gsd-core/workflows/ui-phase.md +328 -0
  462. package/gsd-core/workflows/ui-review.md +193 -0
  463. package/gsd-core/workflows/ultraplan-phase.md +199 -0
  464. package/gsd-core/workflows/undo.md +314 -0
  465. package/gsd-core/workflows/update.md +496 -0
  466. package/gsd-core/workflows/validate-phase.md +181 -0
  467. package/gsd-core/workflows/verify-phase.md +544 -0
  468. package/gsd-core/workflows/verify-work.md +781 -0
  469. package/hooks/dist/gsd-check-update-worker.js +108 -0
  470. package/hooks/dist/gsd-check-update.js +66 -0
  471. package/hooks/dist/gsd-config-reload.js +133 -0
  472. package/hooks/dist/gsd-context-monitor.js +195 -0
  473. package/hooks/dist/gsd-cursor-post-tool.js +75 -0
  474. package/hooks/dist/gsd-cursor-session-start.js +52 -0
  475. package/hooks/dist/gsd-graphify-update.sh +158 -0
  476. package/hooks/dist/gsd-phase-boundary.sh +47 -0
  477. package/hooks/dist/gsd-prompt-guard.js +97 -0
  478. package/hooks/dist/gsd-read-guard.js +101 -0
  479. package/hooks/dist/gsd-read-injection-scanner.js +203 -0
  480. package/hooks/dist/gsd-session-state.sh +59 -0
  481. package/hooks/dist/gsd-statusline.js +566 -0
  482. package/hooks/dist/gsd-update-banner.js +138 -0
  483. package/hooks/dist/gsd-validate-commit.sh +57 -0
  484. package/hooks/dist/gsd-workflow-guard.js +167 -0
  485. package/hooks/dist/gsd-worktree-path-guard.js +169 -0
  486. package/hooks/dist/lib/git-cmd.js +150 -0
  487. package/hooks/dist/lib/gsd-graphify-rebuild.sh +65 -0
  488. package/hooks/dist/managed-hooks-registry.cjs +38 -0
  489. package/hooks/gsd-check-update-worker.js +108 -0
  490. package/hooks/gsd-check-update.js +66 -0
  491. package/hooks/gsd-config-reload.js +133 -0
  492. package/hooks/gsd-context-monitor.js +195 -0
  493. package/hooks/gsd-cursor-post-tool.js +75 -0
  494. package/hooks/gsd-cursor-session-start.js +52 -0
  495. package/hooks/gsd-graphify-update.sh +158 -0
  496. package/hooks/gsd-phase-boundary.sh +47 -0
  497. package/hooks/gsd-prompt-guard.js +97 -0
  498. package/hooks/gsd-read-guard.js +101 -0
  499. package/hooks/gsd-read-injection-scanner.js +203 -0
  500. package/hooks/gsd-session-state.sh +59 -0
  501. package/hooks/gsd-statusline.js +566 -0
  502. package/hooks/gsd-update-banner.js +138 -0
  503. package/hooks/gsd-validate-commit.sh +57 -0
  504. package/hooks/gsd-workflow-guard.js +167 -0
  505. package/hooks/gsd-worktree-path-guard.js +169 -0
  506. package/hooks/hooks.json +69 -0
  507. package/hooks/lib/git-cmd.js +150 -0
  508. package/hooks/lib/gsd-graphify-rebuild.sh +65 -0
  509. package/hooks/managed-hooks-registry.cjs +38 -0
  510. package/package.json +115 -0
  511. package/scripts/affected-tests-lib.cjs +542 -0
  512. package/scripts/audit-workflow-script-paths.cjs +73 -0
  513. package/scripts/base64-scan.sh +351 -0
  514. package/scripts/build-hooks.js +247 -0
  515. package/scripts/changeset/README.md +129 -0
  516. package/scripts/changeset/cli.cjs +590 -0
  517. package/scripts/changeset/github-release-notes.cjs +199 -0
  518. package/scripts/changeset/lint.cjs +111 -0
  519. package/scripts/changeset/new.cjs +137 -0
  520. package/scripts/changeset/parse.cjs +114 -0
  521. package/scripts/changeset/render.cjs +34 -0
  522. package/scripts/changeset/serialize.cjs +130 -0
  523. package/scripts/check-alias-drift.cjs +114 -0
  524. package/scripts/check-env.cjs +312 -0
  525. package/scripts/check-npm-integrity.cjs +215 -0
  526. package/scripts/ci-guard-runner.cjs +22 -0
  527. package/scripts/ci-prepare-test-scope.cjs +51 -0
  528. package/scripts/ci-rebase-check.cjs +86 -0
  529. package/scripts/ci-test-scope.cjs +431 -0
  530. package/scripts/command-contract-helpers.cjs +64 -0
  531. package/scripts/diff-touches-shipped-paths.cjs +155 -0
  532. package/scripts/fix-slash-commands.cjs +147 -0
  533. package/scripts/gen-inventory-manifest.cjs +115 -0
  534. package/scripts/gen-research-agents.cjs +276 -0
  535. package/scripts/generate-package-identity.cjs +125 -0
  536. package/scripts/issue-dedupe.cjs +278 -0
  537. package/scripts/lib/allowlist-ratchet.cjs +136 -0
  538. package/scripts/lib/cli-exit.cjs +56 -0
  539. package/scripts/lint-command-contract.cjs +114 -0
  540. package/scripts/lint-descriptions.cjs +87 -0
  541. package/scripts/lint-docs-required.cjs +222 -0
  542. package/scripts/lint-legacy-dir-name.cjs +160 -0
  543. package/scripts/lint-package-identity-drift.cjs +141 -0
  544. package/scripts/lint-pr-check-project-dir.cjs +99 -0
  545. package/scripts/lint-shell-command-projection-drift.cjs +62 -0
  546. package/scripts/lint-skill-deps.cjs +185 -0
  547. package/scripts/lint-test-file-count.allowlist.json +135 -0
  548. package/scripts/lint-test-file-count.cjs +246 -0
  549. package/scripts/mutation-matrix.cjs +222 -0
  550. package/scripts/pr-template-policy.cjs +268 -0
  551. package/scripts/prompt-injection-scan.sh +207 -0
  552. package/scripts/release-notes/discord-release-summary.cjs +373 -0
  553. package/scripts/release-notes/format-github-release-notes.cjs +261 -0
  554. package/scripts/release-tarball-smoke.cjs +629 -0
  555. package/scripts/research-profiles.cjs +149 -0
  556. package/scripts/run-affected-tests.cjs +7 -0
  557. package/scripts/run-cross-platform-tests.cjs +67 -0
  558. package/scripts/run-tests.cjs +315 -0
  559. package/scripts/secret-scan-lint.sh +231 -0
  560. package/scripts/secret-scan.sh +358 -0
  561. package/scripts/setup-branch-protection.sh +236 -0
  562. package/scripts/strip-prose-atrefs.cjs +106 -0
  563. package/scripts/sync-manifest-versions.cjs +119 -0
  564. package/scripts/sync-rulesets.sh +34 -0
  565. package/scripts/sync-runtime-launcher.cjs +399 -0
  566. package/scripts/test-failure-reasons.cjs +34 -0
  567. package/scripts/verify-npm-publish.cjs +240 -0
  568. package/scripts/workflow-policy.cjs +450 -0
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ /**
3
+ * DispatchLogger interface + default implementation — issue #177 (ADR-0174 P1.3).
4
+ *
5
+ * Interface:
6
+ * { onEvent(event: DispatchEvent): void }
7
+ *
8
+ * Default behaviour (createDefaultLogger):
9
+ * 1. Silent on success — no stdout/stderr when result.kind === 'ok'.
10
+ * 2. Structured JSON to stderr on error — one line per dispatch error.
11
+ * 3. Opt-in audit file — when GSD_AUDIT=1 OR config.audit.enabled===true,
12
+ * appends every event (success + error) as one JSON line to
13
+ * .planning/.gsd-trace.jsonl relative to `cwd`. Creates .planning/ if absent.
14
+ * 4. Args redaction — args omitted by default; included when GSD_AUDIT_ARGS=1.
15
+ *
16
+ * No-op logger (createNoOpLogger):
17
+ * Silent on all events. Used as the Hub default when no logger is injected.
18
+ *
19
+ * ADR-457 build-at-publish: the hand-written bin/lib/observability/logger.cjs
20
+ * collapsed to a TypeScript source of truth. Behaviour is preserved
21
+ * byte-for-behaviour from the prior hand-written .cjs; only types are added.
22
+ */
23
+ var __importDefault = (this && this.__importDefault) || function (mod) {
24
+ return (mod && mod.__esModule) ? mod : { "default": mod };
25
+ };
26
+ const node_fs_1 = __importDefault(require("node:fs"));
27
+ const node_path_1 = __importDefault(require("node:path"));
28
+ const redaction_cjs_1 = require("./redaction.cjs");
29
+ const AUDIT_FILE_NAME = '.gsd-trace.jsonl';
30
+ const PLANNING_DIR = '.planning';
31
+ // ─── helpers ─────────────────────────────────────────────────────────────────
32
+ /**
33
+ * Safely serialise a value to JSON, falling back to a placeholder on circular refs.
34
+ */
35
+ function _safeStringify(value) {
36
+ try {
37
+ return JSON.stringify(value);
38
+ }
39
+ catch {
40
+ return JSON.stringify({ _serializationError: true });
41
+ }
42
+ }
43
+ /**
44
+ * Determine whether the audit file should be written to.
45
+ */
46
+ function _isAuditEnabled(config) {
47
+ if (process.env['GSD_AUDIT'] === '1')
48
+ return true;
49
+ if (config && config.audit && config.audit.enabled === true)
50
+ return true;
51
+ return false;
52
+ }
53
+ /**
54
+ * Build the redacted plain object for the audit file.
55
+ * Preserves the full DispatchEvent structure.
56
+ */
57
+ function _toAuditRecord(event) {
58
+ return (0, redaction_cjs_1.redactEvent)(event);
59
+ }
60
+ /**
61
+ * Build the flattened stderr error line.
62
+ *
63
+ * Per ADR-0174 P1.3 contract: { "kind": "<variant>", "traceId": "<uuid>", ...typedPayload }
64
+ * The result's kind is promoted to top-level and the typed payload fields are spread in.
65
+ * The `result` wrapper is removed.
66
+ */
67
+ function _toStderrRecord(event) {
68
+ const redacted = (0, redaction_cjs_1.redactEvent)(event);
69
+ const { result, ...eventWithoutResult } = redacted;
70
+ // Flatten: top-level gets kind + typed payload fields from result
71
+ const resultObj = result;
72
+ const { kind, ...typedPayload } = resultObj;
73
+ return Object.assign({}, eventWithoutResult, { kind }, typedPayload);
74
+ }
75
+ /**
76
+ * Append one JSON line to the audit file.
77
+ * Creates .planning/ directory if it does not exist.
78
+ *
79
+ * Uses synchronous fs API (crash-safe for v1 — dispatch is synchronous).
80
+ */
81
+ function _appendAuditLine(cwd, event) {
82
+ const planningDir = node_path_1.default.join(cwd, PLANNING_DIR);
83
+ // Ensure the directory exists
84
+ if (!node_fs_1.default.existsSync(planningDir)) {
85
+ node_fs_1.default.mkdirSync(planningDir, { recursive: true });
86
+ }
87
+ const auditPath = node_path_1.default.join(planningDir, AUDIT_FILE_NAME);
88
+ node_fs_1.default.appendFileSync(auditPath, _safeStringify(event) + '\n', 'utf8');
89
+ }
90
+ /**
91
+ * Create a no-op logger. All events are silently dropped.
92
+ * This is the Hub's default when no logger is injected by the caller.
93
+ */
94
+ function createNoOpLogger() {
95
+ return {
96
+ onEvent(_event) {
97
+ // intentionally empty
98
+ },
99
+ };
100
+ }
101
+ /**
102
+ * Create the default DispatchLogger.
103
+ */
104
+ function createDefaultLogger({ cwd = process.cwd(), config } = {}) {
105
+ return {
106
+ /**
107
+ * @param event - A DispatchEvent from the Hub.
108
+ */
109
+ onEvent(event) {
110
+ const resultObj = event && event['result'];
111
+ const isOk = resultObj && resultObj['kind'] === 'ok';
112
+ // ── Audit file (both ok and error) ────────────────────────────────────
113
+ if (_isAuditEnabled(config)) {
114
+ try {
115
+ const auditRecord = _toAuditRecord(event);
116
+ _appendAuditLine(cwd, auditRecord);
117
+ }
118
+ catch (auditErr) {
119
+ // Audit errors must not surface to callers
120
+ process.stderr.write(_safeStringify({
121
+ level: 'warn',
122
+ source: 'DispatchLogger',
123
+ message: 'audit file write failed: ' + String(auditErr?.message ?? auditErr),
124
+ }) + '\n');
125
+ }
126
+ }
127
+ // ── Stderr on error ───────────────────────────────────────────────────
128
+ if (!isOk) {
129
+ try {
130
+ const stderrRecord = _toStderrRecord(event);
131
+ process.stderr.write(_safeStringify(stderrRecord) + '\n');
132
+ }
133
+ catch (stderrErr) {
134
+ // Last-resort: we cannot throw from the logger
135
+ process.stderr.write(_safeStringify({
136
+ level: 'warn',
137
+ source: 'DispatchLogger',
138
+ message: 'stderr emit failed: ' + String(stderrErr?.message ?? stderrErr),
139
+ }) + '\n');
140
+ }
141
+ }
142
+ // ── Silent on success (no else branch needed) ─────────────────────────
143
+ },
144
+ };
145
+ }
146
+ module.exports = { createDefaultLogger, createNoOpLogger };
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * Arg redaction policy — issue #177 (ADR-457 build-at-publish: the
4
+ * hand-written bin/lib/observability/redaction.cjs collapsed to a TypeScript
5
+ * source of truth). Behaviour is preserved byte-for-behaviour from the prior
6
+ * hand-written .cjs; only types are added.
7
+ *
8
+ * Privacy default: args are OMITTED from every emitted event (both stderr
9
+ * and file audit). Opt-in: set GSD_AUDIT_ARGS=1 to include args verbatim.
10
+ *
11
+ * This module is deliberately simple and has no side effects — redaction
12
+ * decisions are stateless reads of process.env at call time so that tests
13
+ * can toggle the env var without module-level caching issues.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.shouldIncludeArgs = shouldIncludeArgs;
17
+ exports.redactEvent = redactEvent;
18
+ /**
19
+ * Returns true when the caller has opted in to including args in events.
20
+ * Only GSD_AUDIT_ARGS === '1' enables inclusion; any other value (including
21
+ * empty string, 'true', 'yes') keeps the default of omitting args.
22
+ */
23
+ function shouldIncludeArgs() {
24
+ return process.env.GSD_AUDIT_ARGS === '1';
25
+ }
26
+ /**
27
+ * Return a redacted copy of a DispatchEvent.
28
+ *
29
+ * If args should be omitted (default), strips the `args` field entirely.
30
+ * If args should be included (GSD_AUDIT_ARGS=1), passes the event through
31
+ * unchanged (args were already set by makeDispatchEvent with includeArgs:true,
32
+ * or absent — in which case they stay absent).
33
+ *
34
+ * The original event object is never mutated (it is frozen by makeDispatchEvent).
35
+ *
36
+ * @param event - A DispatchEvent (frozen or plain).
37
+ * @returns A new plain object with the same fields, minus args when redacted.
38
+ */
39
+ function redactEvent(event) {
40
+ if (shouldIncludeArgs()) {
41
+ // Include path: return a shallow copy with args preserved if present
42
+ const copy = Object.assign({}, event);
43
+ return copy;
44
+ }
45
+ // Exclude path: build a copy omitting `args`
46
+ const { args: _dropped, ...rest } = event;
47
+ return rest;
48
+ }
@@ -0,0 +1,35 @@
1
+ // @generated by scripts/generate-package-identity.cjs from package.json — DO NOT EDIT.
2
+ // Single source for GSD package coordinates (issue #498). Regenerate with:
3
+ // node scripts/generate-package-identity.cjs
4
+ 'use strict';
5
+
6
+ const packageName = "@therocketcode/gsd-core";
7
+ const binName = "gsd-core";
8
+ const repoSlug = "TheRocketCodeMX/gsd-core";
9
+ const repoUrl = "https://github.com/TheRocketCodeMX/gsd-core";
10
+ const changelogRawUrl = "https://raw.githubusercontent.com/TheRocketCodeMX/gsd-core/main/CHANGELOG.md";
11
+ const cacheSlug = "therocketcode-gsd-core";
12
+ const updateCacheFileName = "gsd-update-check-therocketcode-gsd-core.json";
13
+
14
+ function formatManualInstall({ packageName, binName, scope, runtime } = {}) {
15
+ const runtimeFlag = runtime ? ` --${runtime}` : '';
16
+ return `npx -y --package=${packageName}@latest -- ${binName}${runtimeFlag} --${scope}`;
17
+ }
18
+
19
+ function manualInstallCommand(opts = {}) {
20
+ return formatManualInstall({ packageName, binName, scope: opts.scope, runtime: opts.runtime });
21
+ }
22
+
23
+ module.exports = Object.freeze({
24
+ packageName,
25
+ // PACKAGE_NAME: back-compat alias for #516-era consumers. Baked here, so it
26
+ // survives the installed tree's synthetic package.json (fixes the #378 undefined).
27
+ PACKAGE_NAME: packageName,
28
+ binName,
29
+ repoSlug,
30
+ repoUrl,
31
+ changelogRawUrl,
32
+ cacheSlug,
33
+ updateCacheFileName,
34
+ manualInstallCommand,
35
+ });
@@ -0,0 +1,368 @@
1
+ "use strict";
2
+ /**
3
+ * Package Legitimacy Module
4
+ *
5
+ * Replaces the bolt-on prose slopcheck gate (which pip-installed `slopcheck`
6
+ * and degraded ALL packages to [ASSUMED] when pip failed) with registry-API
7
+ * verdicts computed in code.
8
+ *
9
+ * Public interface:
10
+ * DEFAULT_THRESHOLDS — baseline thresholds
11
+ * classifyPackage — pure function: signals → { verdict, reasons }
12
+ * checkPackages — async: resolves registry signals and classifies
13
+ * _setHttpGet — test seam: override the HTTP transport (pass null to restore)
14
+ *
15
+ * All network IO is injected via a `registry` client option so that tests
16
+ * never touch the real network (same seam pattern as clock injection).
17
+ *
18
+ * ADR-457 build-at-publish: authored as TypeScript .cts → emits .cjs via tsc.
19
+ */
20
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ var desc = Object.getOwnPropertyDescriptor(m, k);
23
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
24
+ desc = { enumerable: true, get: function() { return m[k]; } };
25
+ }
26
+ Object.defineProperty(o, k2, desc);
27
+ }) : (function(o, m, k, k2) {
28
+ if (k2 === undefined) k2 = k;
29
+ o[k2] = m[k];
30
+ }));
31
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
32
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
33
+ }) : function(o, v) {
34
+ o["default"] = v;
35
+ });
36
+ var __importStar = (this && this.__importStar) || (function () {
37
+ var ownKeys = function(o) {
38
+ ownKeys = Object.getOwnPropertyNames || function (o) {
39
+ var ar = [];
40
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
41
+ return ar;
42
+ };
43
+ return ownKeys(o);
44
+ };
45
+ return function (mod) {
46
+ if (mod && mod.__esModule) return mod;
47
+ var result = {};
48
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
49
+ __setModuleDefault(result, mod);
50
+ return result;
51
+ };
52
+ })();
53
+ const https = __importStar(require("node:https"));
54
+ // ---------------------------------------------------------------------------
55
+ // Constants
56
+ // ---------------------------------------------------------------------------
57
+ const DEFAULT_THRESHOLDS = {
58
+ minAgeDays: 30,
59
+ minWeeklyDownloads: 1000,
60
+ requireRepo: true,
61
+ };
62
+ // Matches common dangerous postinstall execution patterns.
63
+ // Deliberately EXCLUDES bare https?:// (over-fires on legit packages like
64
+ // esbuild/sharp/node-gyp that reference download URLs without executing them).
65
+ // Shell-execution / download-and-exec signatures only:
66
+ const SUSPICIOUS_POSTINSTALL_RE = /(curl |wget |\|\s*(ba)?sh|bash -c|sh -c|node -e|eval|base64 -d|\/etc\/|\.\.\/|~\/|nc |>\s*\/)/i;
67
+ // ---------------------------------------------------------------------------
68
+ // Severity ordering for verdict merging (SLOP > SUS > OK)
69
+ // ---------------------------------------------------------------------------
70
+ const SEVERITY = { OK: 0, SUS: 1, SLOP: 2 };
71
+ function moreSevereVerdict(a, b) {
72
+ return SEVERITY[a] >= SEVERITY[b] ? a : b;
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // classifyPackage — pure, no IO
76
+ // ---------------------------------------------------------------------------
77
+ function classifyPackage(signals, { thresholds = DEFAULT_THRESHOLDS, clock = Date } = {}) {
78
+ const reasons = [];
79
+ // Terminal: package does not exist
80
+ if (signals.exists === false) {
81
+ return { verdict: 'SLOP', reasons: ['does-not-exist'] };
82
+ }
83
+ // Age check
84
+ if (signals.publishedAt == null) {
85
+ reasons.push('unknown-age');
86
+ }
87
+ else {
88
+ const parsed = Date.parse(String(signals.publishedAt));
89
+ if (!Number.isFinite(parsed)) {
90
+ // Unparseable date — treat as unknown
91
+ reasons.push('unknown-age');
92
+ }
93
+ else {
94
+ const ageDays = Math.floor((clock.now() - parsed) / 86_400_000);
95
+ if (ageDays < thresholds.minAgeDays) {
96
+ reasons.push('too-new');
97
+ }
98
+ }
99
+ }
100
+ // Downloads check
101
+ const downloads = signals.weeklyDownloads;
102
+ if (downloads == null) {
103
+ reasons.push('unknown-downloads');
104
+ }
105
+ else if (typeof downloads !== 'number' || !Number.isFinite(downloads)) {
106
+ // Odd type / NaN — treat as unknown
107
+ reasons.push('unknown-downloads');
108
+ }
109
+ else if (downloads < thresholds.minWeeklyDownloads) {
110
+ reasons.push('low-downloads');
111
+ }
112
+ // Repository check
113
+ if (thresholds.requireRepo && !signals.repoUrl) {
114
+ reasons.push('no-repository');
115
+ }
116
+ // Deprecated check
117
+ if (signals.deprecated === true) {
118
+ reasons.push('deprecated');
119
+ }
120
+ // Suspicious postinstall (npm only — but apply whenever postinstall is present)
121
+ if (signals.postinstall != null && typeof signals.postinstall === 'string') {
122
+ if (SUSPICIOUS_POSTINSTALL_RE.test(signals.postinstall)) {
123
+ reasons.push('suspicious-postinstall');
124
+ }
125
+ }
126
+ // Terminal: suspicious postinstall is a slopsquatting execution risk
127
+ if (reasons.includes('suspicious-postinstall')) {
128
+ return { verdict: 'SLOP', reasons };
129
+ }
130
+ const verdict = reasons.length > 0 ? 'SUS' : 'OK';
131
+ return { verdict, reasons };
132
+ }
133
+ // ---------------------------------------------------------------------------
134
+ // Injectable HTTP transport (test seam — W1)
135
+ // ---------------------------------------------------------------------------
136
+ /** The real HTTPS transport — resolves { statusCode, body } */
137
+ function realHttpsGet(url, timeoutMs) {
138
+ return new Promise((resolve, reject) => {
139
+ const req = https.get(url, { headers: { 'User-Agent': 'gsd-core-package-legitimacy/1.0' } }, (res) => {
140
+ const chunks = [];
141
+ res.on('data', (c) => chunks.push(c));
142
+ res.on('end', () => resolve({
143
+ statusCode: res.statusCode ?? 0,
144
+ body: Buffer.concat(chunks).toString('utf8'),
145
+ }));
146
+ res.on('error', reject);
147
+ });
148
+ req.setTimeout(timeoutMs, () => {
149
+ req.destroy(new Error(`timeout after ${timeoutMs}ms`));
150
+ });
151
+ req.on('error', reject);
152
+ });
153
+ }
154
+ /** Module-level transport pointer — overrideable via _setHttpGet for tests */
155
+ let httpsGet = realHttpsGet;
156
+ /**
157
+ * Test seam: replace the HTTP transport. Pass null to restore the real transport.
158
+ * Tests call this before exercising a real-adapter code path; always restore in finally.
159
+ */
160
+ function _setHttpGet(fn) {
161
+ httpsGet = fn ?? realHttpsGet;
162
+ }
163
+ // ---------------------------------------------------------------------------
164
+ // Real registry adapters (not exercised by tests — tests inject fakes)
165
+ // ---------------------------------------------------------------------------
166
+ function degradedSignals() {
167
+ return {
168
+ exists: null,
169
+ publishedAt: null,
170
+ weeklyDownloads: null,
171
+ repoUrl: null,
172
+ deprecated: false,
173
+ postinstall: null,
174
+ };
175
+ }
176
+ async function lookupNpm(name, version) {
177
+ try {
178
+ const resp = await httpsGet(`https://registry.npmjs.org/${encodeURIComponent(name)}`, 5000);
179
+ if (resp.statusCode === 404)
180
+ return { ...degradedSignals(), exists: false };
181
+ if (resp.statusCode < 200 || resp.statusCode >= 300)
182
+ return degradedSignals();
183
+ const data = JSON.parse(resp.body);
184
+ if (data.error)
185
+ return { ...degradedSignals(), exists: false };
186
+ const time = data.time ?? {};
187
+ const allVersions = data.versions ?? {};
188
+ // I3: when a specific version is requested, verify it exists
189
+ if (version !== undefined) {
190
+ if (!(version in allVersions)) {
191
+ return { ...degradedSignals(), exists: false };
192
+ }
193
+ }
194
+ const latestVersion = data['dist-tags']?.latest ?? '';
195
+ const resolvedVersion = version !== undefined ? version : latestVersion;
196
+ const versionMeta = allVersions[resolvedVersion] ?? {};
197
+ const scripts = versionMeta.scripts ??
198
+ {};
199
+ const postinstall = scripts.postinstall ?? null;
200
+ const repoField = versionMeta.repository;
201
+ let repoUrl = null;
202
+ if (typeof repoField === 'string')
203
+ repoUrl = repoField;
204
+ else if (repoField && typeof repoField.url === 'string') {
205
+ repoUrl = repoField.url;
206
+ }
207
+ const deprecated = typeof versionMeta.deprecated === 'string' ? true : false;
208
+ // Fetch weekly download count from the npm downloads API
209
+ let weeklyDownloads = null;
210
+ try {
211
+ const dlResp = await httpsGet(`https://api.npmjs.org/downloads/point/last-week/${encodeURIComponent(name)}`, 5000);
212
+ if (dlResp.statusCode >= 200 && dlResp.statusCode < 300) {
213
+ const dlData = JSON.parse(dlResp.body);
214
+ if (typeof dlData.downloads === 'number') {
215
+ weeklyDownloads = dlData.downloads;
216
+ }
217
+ }
218
+ }
219
+ catch {
220
+ // Degraded: leave weeklyDownloads as null, never throw
221
+ }
222
+ return {
223
+ exists: true,
224
+ publishedAt: time[resolvedVersion] ?? time.created ?? null,
225
+ weeklyDownloads,
226
+ repoUrl,
227
+ deprecated,
228
+ postinstall,
229
+ ecosystem: 'npm',
230
+ };
231
+ }
232
+ catch {
233
+ return degradedSignals();
234
+ }
235
+ }
236
+ async function lookupPypi(name, version) {
237
+ try {
238
+ const resp = await httpsGet(`https://pypi.org/pypi/${encodeURIComponent(name)}/json`, 5000);
239
+ if (resp.statusCode === 404)
240
+ return { ...degradedSignals(), exists: false };
241
+ if (resp.statusCode < 200 || resp.statusCode >= 300)
242
+ return degradedSignals();
243
+ const data = JSON.parse(resp.body);
244
+ const info = data.info ?? {};
245
+ // I3: when a specific version is requested, verify it exists in releases
246
+ const releases = data.releases ?? {};
247
+ if (version !== undefined) {
248
+ if (!(version in releases)) {
249
+ return { ...degradedSignals(), exists: false };
250
+ }
251
+ }
252
+ // Finding 2: when version is provided, derive publishedAt from the
253
+ // version-specific release record rather than the package-level urls[] array
254
+ // (which reflects the latest release, not the requested version).
255
+ let uploadTime = null;
256
+ if (version !== undefined) {
257
+ const versionFiles = releases[version] ?? [];
258
+ uploadTime =
259
+ versionFiles.length > 0
260
+ ? versionFiles[0].upload_time_iso_8601 ?? null
261
+ : null;
262
+ }
263
+ else {
264
+ const urls = data.urls ?? [];
265
+ uploadTime =
266
+ urls.length > 0 ? urls[0].upload_time_iso_8601 ?? null : null;
267
+ }
268
+ const projectUrls = info.project_urls;
269
+ const repoUrl = projectUrls?.['Source'] ??
270
+ projectUrls?.['Homepage'] ??
271
+ info.home_page ??
272
+ null;
273
+ return {
274
+ exists: true,
275
+ publishedAt: uploadTime,
276
+ weeklyDownloads: null, // PyPI weekly downloads require a separate API
277
+ repoUrl: repoUrl || null,
278
+ deprecated: false, // PyPI doesn't have a first-class deprecated field
279
+ postinstall: null, // Not applicable for PyPI
280
+ ecosystem: 'pypi',
281
+ };
282
+ }
283
+ catch {
284
+ return degradedSignals();
285
+ }
286
+ }
287
+ async function lookupCrates(name, version) {
288
+ try {
289
+ const resp = await httpsGet(`https://crates.io/api/v1/crates/${encodeURIComponent(name)}`, 5000);
290
+ if (resp.statusCode === 404)
291
+ return { ...degradedSignals(), exists: false };
292
+ if (resp.statusCode < 200 || resp.statusCode >= 300)
293
+ return degradedSignals();
294
+ const data = JSON.parse(resp.body);
295
+ const krate = data.crate ?? {};
296
+ // I3: when a specific version is requested, verify it exists in versions list
297
+ const versions = data.versions ?? [];
298
+ if (version !== undefined) {
299
+ const found = versions.some((v) => v.num === version);
300
+ if (!found) {
301
+ return { ...degradedSignals(), exists: false };
302
+ }
303
+ }
304
+ const repoUrl = krate.repository ?? null;
305
+ // Finding 2: when version is provided, use the version-specific created_at
306
+ // rather than the package-level crate.created_at (first-ever publish date).
307
+ let created;
308
+ if (version !== undefined) {
309
+ const versionObj = versions.find((v) => v.num === version);
310
+ created = versionObj?.created_at ?? null;
311
+ }
312
+ else {
313
+ created = krate.created_at ?? null;
314
+ }
315
+ // recent_downloads is a 90-day count; normalize to a weekly figure for comparison
316
+ // against minWeeklyDownloads (which is a weekly threshold).
317
+ const rawDownloads = krate.recent_downloads;
318
+ const downloads = (rawDownloads != null && typeof Number(rawDownloads) === 'number' && !isNaN(Number(rawDownloads)))
319
+ ? Math.round(Number(rawDownloads) * 7 / 90)
320
+ : null;
321
+ return {
322
+ exists: true,
323
+ publishedAt: created,
324
+ weeklyDownloads: downloads,
325
+ repoUrl,
326
+ deprecated: false,
327
+ postinstall: null,
328
+ ecosystem: 'crates',
329
+ };
330
+ }
331
+ catch {
332
+ return degradedSignals();
333
+ }
334
+ }
335
+ const realRegistry = {
336
+ async lookup(ecosystem, name, version) {
337
+ switch (ecosystem) {
338
+ case 'npm':
339
+ return lookupNpm(name, version);
340
+ case 'pypi':
341
+ return lookupPypi(name, version);
342
+ case 'crates':
343
+ return lookupCrates(name, version);
344
+ default:
345
+ return degradedSignals();
346
+ }
347
+ },
348
+ };
349
+ // ---------------------------------------------------------------------------
350
+ // checkPackages — orchestrates lookup + classify + slopcheck merge
351
+ // ---------------------------------------------------------------------------
352
+ async function checkPackages({ ecosystem, packages, version }, { registry = realRegistry, clock = Date, thresholds = DEFAULT_THRESHOLDS, slopcheck = null, } = {}) {
353
+ const results = [];
354
+ for (const name of packages) {
355
+ const signals = await registry.lookup(ecosystem, name, version);
356
+ const { verdict: registryVerdict, reasons } = classifyPackage(signals, { thresholds, clock });
357
+ let finalVerdict = registryVerdict;
358
+ if (slopcheck != null) {
359
+ const slopVerdict = await slopcheck.check(ecosystem, name);
360
+ if (slopVerdict != null) {
361
+ finalVerdict = moreSevereVerdict(finalVerdict, slopVerdict);
362
+ }
363
+ }
364
+ results.push({ name, verdict: finalVerdict, signals, reasons });
365
+ }
366
+ return results;
367
+ }
368
+ module.exports = { DEFAULT_THRESHOLDS, classifyPackage, checkPackages, _setHttpGet };