gsd-remix 1.0.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 (554) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +939 -0
  3. package/README.zh-CN.md +876 -0
  4. package/agents/gsd-advisor-researcher.md +127 -0
  5. package/agents/gsd-ai-researcher.md +133 -0
  6. package/agents/gsd-assumptions-analyzer.md +105 -0
  7. package/agents/gsd-code-fixer.md +517 -0
  8. package/agents/gsd-code-reviewer.md +371 -0
  9. package/agents/gsd-codebase-mapper.md +781 -0
  10. package/agents/gsd-debug-session-manager.md +314 -0
  11. package/agents/gsd-debugger.md +1452 -0
  12. package/agents/gsd-doc-classifier.md +168 -0
  13. package/agents/gsd-doc-synthesizer.md +204 -0
  14. package/agents/gsd-doc-verifier.md +217 -0
  15. package/agents/gsd-doc-writer.md +615 -0
  16. package/agents/gsd-domain-researcher.md +153 -0
  17. package/agents/gsd-eval-auditor.md +191 -0
  18. package/agents/gsd-eval-planner.md +154 -0
  19. package/agents/gsd-executor.md +603 -0
  20. package/agents/gsd-framework-selector.md +160 -0
  21. package/agents/gsd-integration-checker.md +470 -0
  22. package/agents/gsd-intel-updater.md +334 -0
  23. package/agents/gsd-nyquist-auditor.md +203 -0
  24. package/agents/gsd-pattern-mapper.md +335 -0
  25. package/agents/gsd-phase-researcher.md +841 -0
  26. package/agents/gsd-plan-checker.md +978 -0
  27. package/agents/gsd-planner.md +1251 -0
  28. package/agents/gsd-project-researcher.md +677 -0
  29. package/agents/gsd-research-synthesizer.md +247 -0
  30. package/agents/gsd-roadmapper.md +688 -0
  31. package/agents/gsd-security-auditor.md +155 -0
  32. package/agents/gsd-ui-auditor.md +495 -0
  33. package/agents/gsd-ui-checker.md +309 -0
  34. package/agents/gsd-ui-researcher.md +380 -0
  35. package/agents/gsd-user-profiler.md +171 -0
  36. package/agents/gsd-verifier.md +830 -0
  37. package/bin/install.js +7062 -0
  38. package/commands/gsd/add-backlog.md +79 -0
  39. package/commands/gsd/add-phase.md +43 -0
  40. package/commands/gsd/add-tests.md +41 -0
  41. package/commands/gsd/add-todo.md +47 -0
  42. package/commands/gsd/ai-integration-phase.md +36 -0
  43. package/commands/gsd/analyze-dependencies.md +34 -0
  44. package/commands/gsd/audit-fix.md +33 -0
  45. package/commands/gsd/audit-milestone.md +36 -0
  46. package/commands/gsd/audit-uat.md +24 -0
  47. package/commands/gsd/autonomous.md +46 -0
  48. package/commands/gsd/check-todos.md +45 -0
  49. package/commands/gsd/cleanup.md +23 -0
  50. package/commands/gsd/code-review-fix.md +52 -0
  51. package/commands/gsd/code-review.md +55 -0
  52. package/commands/gsd/complete-milestone.md +136 -0
  53. package/commands/gsd/debug.md +263 -0
  54. package/commands/gsd/discuss-phase.md +69 -0
  55. package/commands/gsd/do.md +30 -0
  56. package/commands/gsd/docs-update.md +48 -0
  57. package/commands/gsd/eval-review.md +32 -0
  58. package/commands/gsd/execute-phase.md +63 -0
  59. package/commands/gsd/explore.md +27 -0
  60. package/commands/gsd/extract_learnings.md +22 -0
  61. package/commands/gsd/fast.md +30 -0
  62. package/commands/gsd/forensics.md +56 -0
  63. package/commands/gsd/from-gsd2.md +47 -0
  64. package/commands/gsd/graphify.md +201 -0
  65. package/commands/gsd/health.md +22 -0
  66. package/commands/gsd/help.md +24 -0
  67. package/commands/gsd/import.md +37 -0
  68. package/commands/gsd/inbox.md +38 -0
  69. package/commands/gsd/ingest-docs.md +42 -0
  70. package/commands/gsd/insert-phase.md +32 -0
  71. package/commands/gsd/intel.md +179 -0
  72. package/commands/gsd/join-discord.md +19 -0
  73. package/commands/gsd/list-phase-assumptions.md +46 -0
  74. package/commands/gsd/list-workspaces.md +19 -0
  75. package/commands/gsd/manager.md +40 -0
  76. package/commands/gsd/map-codebase.md +71 -0
  77. package/commands/gsd/milestone-summary.md +51 -0
  78. package/commands/gsd/new-milestone.md +44 -0
  79. package/commands/gsd/new-project.md +46 -0
  80. package/commands/gsd/new-workspace.md +44 -0
  81. package/commands/gsd/next.md +28 -0
  82. package/commands/gsd/note.md +34 -0
  83. package/commands/gsd/pause-work.md +38 -0
  84. package/commands/gsd/plan-milestone-gaps.md +34 -0
  85. package/commands/gsd/plan-phase.md +52 -0
  86. package/commands/gsd/plan-review-convergence.md +52 -0
  87. package/commands/gsd/plant-seed.md +28 -0
  88. package/commands/gsd/pr-branch.md +25 -0
  89. package/commands/gsd/profile-user.md +46 -0
  90. package/commands/gsd/progress.md +25 -0
  91. package/commands/gsd/quick.md +173 -0
  92. package/commands/gsd/reapply-patches.md +331 -0
  93. package/commands/gsd/remove-phase.md +31 -0
  94. package/commands/gsd/remove-workspace.md +26 -0
  95. package/commands/gsd/research-phase.md +195 -0
  96. package/commands/gsd/resume-work.md +40 -0
  97. package/commands/gsd/review-backlog.md +62 -0
  98. package/commands/gsd/review.md +40 -0
  99. package/commands/gsd/scan.md +26 -0
  100. package/commands/gsd/secure-phase.md +35 -0
  101. package/commands/gsd/session-report.md +19 -0
  102. package/commands/gsd/set-profile.md +12 -0
  103. package/commands/gsd/settings.md +36 -0
  104. package/commands/gsd/ship.md +23 -0
  105. package/commands/gsd/sketch-wrap-up.md +31 -0
  106. package/commands/gsd/sketch.md +49 -0
  107. package/commands/gsd/spec-phase.md +62 -0
  108. package/commands/gsd/spike-wrap-up.md +31 -0
  109. package/commands/gsd/spike.md +46 -0
  110. package/commands/gsd/stats.md +18 -0
  111. package/commands/gsd/sync-skills.md +19 -0
  112. package/commands/gsd/thread.md +227 -0
  113. package/commands/gsd/ui-phase.md +34 -0
  114. package/commands/gsd/ui-review.md +32 -0
  115. package/commands/gsd/ultraplan-phase.md +33 -0
  116. package/commands/gsd/undo.md +34 -0
  117. package/commands/gsd/update.md +37 -0
  118. package/commands/gsd/validate-phase.md +35 -0
  119. package/commands/gsd/verify-work.md +38 -0
  120. package/commands/gsd/workstreams.md +69 -0
  121. package/get-shit-done/bin/gsd-tools.cjs +1263 -0
  122. package/get-shit-done/bin/lib/artifacts.cjs +52 -0
  123. package/get-shit-done/bin/lib/audit.cjs +757 -0
  124. package/get-shit-done/bin/lib/commands.cjs +1023 -0
  125. package/get-shit-done/bin/lib/config-schema.cjs +79 -0
  126. package/get-shit-done/bin/lib/config.cjs +463 -0
  127. package/get-shit-done/bin/lib/core.cjs +1794 -0
  128. package/get-shit-done/bin/lib/docs.cjs +267 -0
  129. package/get-shit-done/bin/lib/frontmatter.cjs +379 -0
  130. package/get-shit-done/bin/lib/graphify.cjs +494 -0
  131. package/get-shit-done/bin/lib/gsd2-import.cjs +511 -0
  132. package/get-shit-done/bin/lib/init.cjs +1878 -0
  133. package/get-shit-done/bin/lib/intel.cjs +639 -0
  134. package/get-shit-done/bin/lib/learnings.cjs +378 -0
  135. package/get-shit-done/bin/lib/milestone.cjs +283 -0
  136. package/get-shit-done/bin/lib/model-profiles.cjs +71 -0
  137. package/get-shit-done/bin/lib/phase.cjs +1058 -0
  138. package/get-shit-done/bin/lib/profile-output.cjs +1080 -0
  139. package/get-shit-done/bin/lib/profile-pipeline.cjs +539 -0
  140. package/get-shit-done/bin/lib/roadmap.cjs +523 -0
  141. package/get-shit-done/bin/lib/schema-detect.cjs +238 -0
  142. package/get-shit-done/bin/lib/security.cjs +504 -0
  143. package/get-shit-done/bin/lib/state.cjs +1649 -0
  144. package/get-shit-done/bin/lib/template.cjs +226 -0
  145. package/get-shit-done/bin/lib/uat.cjs +288 -0
  146. package/get-shit-done/bin/lib/verify.cjs +1184 -0
  147. package/get-shit-done/bin/lib/workstream.cjs +495 -0
  148. package/get-shit-done/bin/repair-sdk.cjs +177 -0
  149. package/get-shit-done/contexts/dev.md +21 -0
  150. package/get-shit-done/contexts/research.md +22 -0
  151. package/get-shit-done/contexts/review.md +22 -0
  152. package/get-shit-done/references/agent-contracts.md +79 -0
  153. package/get-shit-done/references/ai-evals.md +156 -0
  154. package/get-shit-done/references/ai-frameworks.md +186 -0
  155. package/get-shit-done/references/artifact-types.md +131 -0
  156. package/get-shit-done/references/autonomous-smart-discuss.md +277 -0
  157. package/get-shit-done/references/checkpoints.md +808 -0
  158. package/get-shit-done/references/common-bug-patterns.md +114 -0
  159. package/get-shit-done/references/context-budget.md +49 -0
  160. package/get-shit-done/references/continuation-format.md +253 -0
  161. package/get-shit-done/references/debugger-philosophy.md +76 -0
  162. package/get-shit-done/references/decimal-phase-calculation.md +64 -0
  163. package/get-shit-done/references/doc-conflict-engine.md +91 -0
  164. package/get-shit-done/references/domain-probes.md +125 -0
  165. package/get-shit-done/references/executor-examples.md +110 -0
  166. package/get-shit-done/references/few-shot-examples/plan-checker.md +73 -0
  167. package/get-shit-done/references/few-shot-examples/verifier.md +109 -0
  168. package/get-shit-done/references/gate-prompts.md +100 -0
  169. package/get-shit-done/references/gates.md +70 -0
  170. package/get-shit-done/references/git-integration.md +295 -0
  171. package/get-shit-done/references/git-planning-commit.md +40 -0
  172. package/get-shit-done/references/ios-scaffold.md +123 -0
  173. package/get-shit-done/references/mandatory-initial-read.md +2 -0
  174. package/get-shit-done/references/model-profile-resolution.md +38 -0
  175. package/get-shit-done/references/model-profiles.md +145 -0
  176. package/get-shit-done/references/phase-argument-parsing.md +61 -0
  177. package/get-shit-done/references/planner-antipatterns.md +89 -0
  178. package/get-shit-done/references/planner-gap-closure.md +62 -0
  179. package/get-shit-done/references/planner-reviews.md +39 -0
  180. package/get-shit-done/references/planner-revision.md +87 -0
  181. package/get-shit-done/references/planner-source-audit.md +73 -0
  182. package/get-shit-done/references/planning-config.md +460 -0
  183. package/get-shit-done/references/project-skills-discovery.md +19 -0
  184. package/get-shit-done/references/questioning.md +162 -0
  185. package/get-shit-done/references/revision-loop.md +97 -0
  186. package/get-shit-done/references/sketch-interactivity.md +41 -0
  187. package/get-shit-done/references/sketch-theme-system.md +94 -0
  188. package/get-shit-done/references/sketch-tooling.md +45 -0
  189. package/get-shit-done/references/sketch-variant-patterns.md +81 -0
  190. package/get-shit-done/references/tdd.md +330 -0
  191. package/get-shit-done/references/thinking-models-debug.md +44 -0
  192. package/get-shit-done/references/thinking-models-execution.md +50 -0
  193. package/get-shit-done/references/thinking-models-planning.md +62 -0
  194. package/get-shit-done/references/thinking-models-research.md +50 -0
  195. package/get-shit-done/references/thinking-models-verification.md +55 -0
  196. package/get-shit-done/references/thinking-partner.md +96 -0
  197. package/get-shit-done/references/ui-brand.md +160 -0
  198. package/get-shit-done/references/universal-anti-patterns.md +63 -0
  199. package/get-shit-done/references/user-profiling.md +681 -0
  200. package/get-shit-done/references/verification-overrides.md +227 -0
  201. package/get-shit-done/references/verification-patterns.md +612 -0
  202. package/get-shit-done/references/workstream-flag.md +111 -0
  203. package/get-shit-done/templates/AI-SPEC.md +246 -0
  204. package/get-shit-done/templates/DEBUG.md +169 -0
  205. package/get-shit-done/templates/README.md +76 -0
  206. package/get-shit-done/templates/SECURITY.md +61 -0
  207. package/get-shit-done/templates/UAT.md +265 -0
  208. package/get-shit-done/templates/UI-SPEC.md +100 -0
  209. package/get-shit-done/templates/VALIDATION.md +76 -0
  210. package/get-shit-done/templates/claude-md.md +145 -0
  211. package/get-shit-done/templates/codebase/architecture.md +255 -0
  212. package/get-shit-done/templates/codebase/concerns.md +310 -0
  213. package/get-shit-done/templates/codebase/conventions.md +307 -0
  214. package/get-shit-done/templates/codebase/integrations.md +280 -0
  215. package/get-shit-done/templates/codebase/stack.md +186 -0
  216. package/get-shit-done/templates/codebase/structure.md +285 -0
  217. package/get-shit-done/templates/codebase/testing.md +480 -0
  218. package/get-shit-done/templates/config.json +56 -0
  219. package/get-shit-done/templates/context.md +352 -0
  220. package/get-shit-done/templates/continue-here.md +78 -0
  221. package/get-shit-done/templates/copilot-instructions.md +7 -0
  222. package/get-shit-done/templates/debug-subagent-prompt.md +91 -0
  223. package/get-shit-done/templates/dev-preferences.md +21 -0
  224. package/get-shit-done/templates/discovery.md +146 -0
  225. package/get-shit-done/templates/discussion-log.md +63 -0
  226. package/get-shit-done/templates/milestone-archive.md +123 -0
  227. package/get-shit-done/templates/milestone.md +115 -0
  228. package/get-shit-done/templates/phase-prompt.md +610 -0
  229. package/get-shit-done/templates/planner-subagent-prompt.md +117 -0
  230. package/get-shit-done/templates/project.md +186 -0
  231. package/get-shit-done/templates/requirements.md +231 -0
  232. package/get-shit-done/templates/research-project/ARCHITECTURE.md +204 -0
  233. package/get-shit-done/templates/research-project/FEATURES.md +147 -0
  234. package/get-shit-done/templates/research-project/PITFALLS.md +200 -0
  235. package/get-shit-done/templates/research-project/STACK.md +120 -0
  236. package/get-shit-done/templates/research-project/SUMMARY.md +170 -0
  237. package/get-shit-done/templates/research.md +592 -0
  238. package/get-shit-done/templates/retrospective.md +54 -0
  239. package/get-shit-done/templates/roadmap.md +202 -0
  240. package/get-shit-done/templates/spec.md +307 -0
  241. package/get-shit-done/templates/state.md +184 -0
  242. package/get-shit-done/templates/summary-complex.md +59 -0
  243. package/get-shit-done/templates/summary-minimal.md +41 -0
  244. package/get-shit-done/templates/summary-standard.md +48 -0
  245. package/get-shit-done/templates/summary.md +248 -0
  246. package/get-shit-done/templates/user-profile.md +146 -0
  247. package/get-shit-done/templates/user-setup.md +311 -0
  248. package/get-shit-done/templates/verification-report.md +322 -0
  249. package/get-shit-done/workflows/add-phase.md +112 -0
  250. package/get-shit-done/workflows/add-tests.md +354 -0
  251. package/get-shit-done/workflows/add-todo.md +160 -0
  252. package/get-shit-done/workflows/ai-integration-phase.md +284 -0
  253. package/get-shit-done/workflows/analyze-dependencies.md +96 -0
  254. package/get-shit-done/workflows/audit-fix.md +175 -0
  255. package/get-shit-done/workflows/audit-milestone.md +340 -0
  256. package/get-shit-done/workflows/audit-uat.md +109 -0
  257. package/get-shit-done/workflows/autonomous.md +789 -0
  258. package/get-shit-done/workflows/check-todos.md +179 -0
  259. package/get-shit-done/workflows/cleanup.md +154 -0
  260. package/get-shit-done/workflows/code-review-fix.md +497 -0
  261. package/get-shit-done/workflows/code-review.md +515 -0
  262. package/get-shit-done/workflows/complete-milestone.md +847 -0
  263. package/get-shit-done/workflows/diagnose-issues.md +238 -0
  264. package/get-shit-done/workflows/discovery-phase.md +291 -0
  265. package/get-shit-done/workflows/discuss-phase-assumptions.md +670 -0
  266. package/get-shit-done/workflows/discuss-phase-power.md +308 -0
  267. package/get-shit-done/workflows/discuss-phase.md +1378 -0
  268. package/get-shit-done/workflows/do.md +110 -0
  269. package/get-shit-done/workflows/docs-update.md +1155 -0
  270. package/get-shit-done/workflows/eval-review.md +155 -0
  271. package/get-shit-done/workflows/execute-phase.md +1677 -0
  272. package/get-shit-done/workflows/execute-plan.md +533 -0
  273. package/get-shit-done/workflows/explore.md +141 -0
  274. package/get-shit-done/workflows/extract_learnings.md +242 -0
  275. package/get-shit-done/workflows/fast.md +105 -0
  276. package/get-shit-done/workflows/forensics.md +265 -0
  277. package/get-shit-done/workflows/graduation.md +195 -0
  278. package/get-shit-done/workflows/health.md +314 -0
  279. package/get-shit-done/workflows/help.md +667 -0
  280. package/get-shit-done/workflows/import.md +246 -0
  281. package/get-shit-done/workflows/inbox.md +387 -0
  282. package/get-shit-done/workflows/ingest-docs.md +328 -0
  283. package/get-shit-done/workflows/insert-phase.md +130 -0
  284. package/get-shit-done/workflows/list-phase-assumptions.md +178 -0
  285. package/get-shit-done/workflows/list-workspaces.md +56 -0
  286. package/get-shit-done/workflows/manager.md +365 -0
  287. package/get-shit-done/workflows/map-codebase.md +393 -0
  288. package/get-shit-done/workflows/milestone-summary.md +223 -0
  289. package/get-shit-done/workflows/new-milestone.md +611 -0
  290. package/get-shit-done/workflows/new-project.md +1391 -0
  291. package/get-shit-done/workflows/new-workspace.md +239 -0
  292. package/get-shit-done/workflows/next.md +220 -0
  293. package/get-shit-done/workflows/node-repair.md +92 -0
  294. package/get-shit-done/workflows/note.md +158 -0
  295. package/get-shit-done/workflows/pause-work.md +243 -0
  296. package/get-shit-done/workflows/plan-milestone-gaps.md +273 -0
  297. package/get-shit-done/workflows/plan-phase.md +1349 -0
  298. package/get-shit-done/workflows/plan-review-convergence.md +254 -0
  299. package/get-shit-done/workflows/plant-seed.md +172 -0
  300. package/get-shit-done/workflows/pr-branch.md +157 -0
  301. package/get-shit-done/workflows/profile-user.md +452 -0
  302. package/get-shit-done/workflows/progress.md +619 -0
  303. package/get-shit-done/workflows/quick.md +970 -0
  304. package/get-shit-done/workflows/remove-phase.md +155 -0
  305. package/get-shit-done/workflows/remove-workspace.md +92 -0
  306. package/get-shit-done/workflows/research-phase.md +89 -0
  307. package/get-shit-done/workflows/resume-project.md +326 -0
  308. package/get-shit-done/workflows/review.md +344 -0
  309. package/get-shit-done/workflows/scan.md +102 -0
  310. package/get-shit-done/workflows/secure-phase.md +166 -0
  311. package/get-shit-done/workflows/session-report.md +146 -0
  312. package/get-shit-done/workflows/settings.md +319 -0
  313. package/get-shit-done/workflows/ship.md +302 -0
  314. package/get-shit-done/workflows/sketch-wrap-up.md +283 -0
  315. package/get-shit-done/workflows/sketch.md +286 -0
  316. package/get-shit-done/workflows/spec-phase.md +262 -0
  317. package/get-shit-done/workflows/spike-wrap-up.md +281 -0
  318. package/get-shit-done/workflows/spike.md +362 -0
  319. package/get-shit-done/workflows/stats.md +60 -0
  320. package/get-shit-done/workflows/sync-skills.md +182 -0
  321. package/get-shit-done/workflows/transition.md +693 -0
  322. package/get-shit-done/workflows/ui-phase.md +323 -0
  323. package/get-shit-done/workflows/ui-review.md +190 -0
  324. package/get-shit-done/workflows/ultraplan-phase.md +189 -0
  325. package/get-shit-done/workflows/undo.md +314 -0
  326. package/get-shit-done/workflows/update.md +587 -0
  327. package/get-shit-done/workflows/validate-phase.md +176 -0
  328. package/get-shit-done/workflows/verify-phase.md +465 -0
  329. package/get-shit-done/workflows/verify-work.md +740 -0
  330. package/hooks/dist/gsd-check-update-worker.js +108 -0
  331. package/hooks/dist/gsd-check-update.js +64 -0
  332. package/hooks/dist/gsd-context-monitor.js +192 -0
  333. package/hooks/dist/gsd-phase-boundary.sh +28 -0
  334. package/hooks/dist/gsd-prompt-guard.js +97 -0
  335. package/hooks/dist/gsd-read-guard.js +82 -0
  336. package/hooks/dist/gsd-read-injection-scanner.js +152 -0
  337. package/hooks/dist/gsd-session-state.sh +34 -0
  338. package/hooks/dist/gsd-statusline.js +293 -0
  339. package/hooks/dist/gsd-validate-commit.sh +48 -0
  340. package/hooks/dist/gsd-workflow-guard.js +94 -0
  341. package/hooks/gsd-check-update-worker.js +108 -0
  342. package/hooks/gsd-check-update.js +64 -0
  343. package/hooks/gsd-context-monitor.js +192 -0
  344. package/hooks/gsd-phase-boundary.sh +28 -0
  345. package/hooks/gsd-prompt-guard.js +97 -0
  346. package/hooks/gsd-read-guard.js +82 -0
  347. package/hooks/gsd-read-injection-scanner.js +152 -0
  348. package/hooks/gsd-session-state.sh +34 -0
  349. package/hooks/gsd-statusline.js +293 -0
  350. package/hooks/gsd-validate-commit.sh +48 -0
  351. package/hooks/gsd-workflow-guard.js +94 -0
  352. package/package.json +59 -0
  353. package/scripts/base64-scan.sh +262 -0
  354. package/scripts/build-hooks.js +95 -0
  355. package/scripts/gen-inventory-manifest.cjs +109 -0
  356. package/scripts/prompt-injection-scan.sh +201 -0
  357. package/scripts/run-tests.cjs +33 -0
  358. package/scripts/secret-scan.sh +227 -0
  359. package/sdk/package-lock.json +1998 -0
  360. package/sdk/package.json +52 -0
  361. package/sdk/prompts/agents/gsd-executor.md +110 -0
  362. package/sdk/prompts/agents/gsd-phase-researcher.md +158 -0
  363. package/sdk/prompts/agents/gsd-plan-checker.md +160 -0
  364. package/sdk/prompts/agents/gsd-planner.md +214 -0
  365. package/sdk/prompts/agents/gsd-project-researcher.md +323 -0
  366. package/sdk/prompts/agents/gsd-research-synthesizer.md +237 -0
  367. package/sdk/prompts/agents/gsd-roadmapper.md +670 -0
  368. package/sdk/prompts/agents/gsd-verifier.md +159 -0
  369. package/sdk/prompts/templates/project.md +186 -0
  370. package/sdk/prompts/templates/requirements.md +231 -0
  371. package/sdk/prompts/templates/research-project/ARCHITECTURE.md +204 -0
  372. package/sdk/prompts/templates/research-project/FEATURES.md +147 -0
  373. package/sdk/prompts/templates/research-project/PITFALLS.md +200 -0
  374. package/sdk/prompts/templates/research-project/STACK.md +120 -0
  375. package/sdk/prompts/templates/research-project/SUMMARY.md +170 -0
  376. package/sdk/prompts/templates/roadmap.md +202 -0
  377. package/sdk/prompts/templates/state.md +175 -0
  378. package/sdk/prompts/workflows/discuss-phase.md +126 -0
  379. package/sdk/prompts/workflows/execute-plan.md +106 -0
  380. package/sdk/prompts/workflows/plan-phase.md +84 -0
  381. package/sdk/prompts/workflows/research-phase.md +45 -0
  382. package/sdk/prompts/workflows/verify-phase.md +142 -0
  383. package/sdk/src/assembled-prompts.test.ts +349 -0
  384. package/sdk/src/cli-transport.test.ts +388 -0
  385. package/sdk/src/cli-transport.ts +130 -0
  386. package/sdk/src/cli.test.ts +383 -0
  387. package/sdk/src/cli.ts +670 -0
  388. package/sdk/src/config.test.ts +168 -0
  389. package/sdk/src/config.ts +177 -0
  390. package/sdk/src/context-engine.test.ts +295 -0
  391. package/sdk/src/context-engine.ts +170 -0
  392. package/sdk/src/context-truncation.test.ts +163 -0
  393. package/sdk/src/context-truncation.ts +233 -0
  394. package/sdk/src/e2e.integration.test.ts +178 -0
  395. package/sdk/src/errors.ts +72 -0
  396. package/sdk/src/event-stream.test.ts +661 -0
  397. package/sdk/src/event-stream.ts +441 -0
  398. package/sdk/src/failure-memory.test.ts +457 -0
  399. package/sdk/src/failure-memory.ts +1324 -0
  400. package/sdk/src/golden/capture.ts +95 -0
  401. package/sdk/src/golden/fixtures/generate-slug.golden.json +1 -0
  402. package/sdk/src/golden/fixtures/profile-sample-sessions/demo-project/sample.jsonl +3 -0
  403. package/sdk/src/golden/fixtures/summary-extract-sample.md +26 -0
  404. package/sdk/src/golden/fixtures/uat-render-checkpoint-sample.md +15 -0
  405. package/sdk/src/golden/golden-integration-covered.ts +30 -0
  406. package/sdk/src/golden/golden-mutation-covered.ts +7 -0
  407. package/sdk/src/golden/golden-policy.test.ts +8 -0
  408. package/sdk/src/golden/golden-policy.ts +112 -0
  409. package/sdk/src/golden/golden.integration.test.ts +373 -0
  410. package/sdk/src/golden/init-golden-normalize.ts +15 -0
  411. package/sdk/src/golden/read-only-golden-rows.ts +77 -0
  412. package/sdk/src/golden/read-only-parity.integration.test.ts +125 -0
  413. package/sdk/src/golden/registry-canonical-commands.ts +31 -0
  414. package/sdk/src/gsd-tools.test.ts +409 -0
  415. package/sdk/src/gsd-tools.ts +595 -0
  416. package/sdk/src/headless-prompts.test.ts +159 -0
  417. package/sdk/src/index.ts +333 -0
  418. package/sdk/src/init-e2e.integration.test.ts +136 -0
  419. package/sdk/src/init-runner.test.ts +783 -0
  420. package/sdk/src/init-runner.ts +735 -0
  421. package/sdk/src/lifecycle-e2e.integration.test.ts +258 -0
  422. package/sdk/src/logger.test.ts +149 -0
  423. package/sdk/src/logger.ts +113 -0
  424. package/sdk/src/milestone-runner.test.ts +421 -0
  425. package/sdk/src/phase-prompt.test.ts +538 -0
  426. package/sdk/src/phase-prompt.ts +264 -0
  427. package/sdk/src/phase-runner-types.test.ts +421 -0
  428. package/sdk/src/phase-runner.integration.test.ts +377 -0
  429. package/sdk/src/phase-runner.test.ts +2333 -0
  430. package/sdk/src/phase-runner.ts +1203 -0
  431. package/sdk/src/plan-parser.test.ts +528 -0
  432. package/sdk/src/plan-parser.ts +427 -0
  433. package/sdk/src/prompt-builder.test.ts +306 -0
  434. package/sdk/src/prompt-builder.ts +193 -0
  435. package/sdk/src/prompt-sanitizer.test.ts +260 -0
  436. package/sdk/src/prompt-sanitizer.ts +71 -0
  437. package/sdk/src/query/QUERY-HANDLERS.md +317 -0
  438. package/sdk/src/query/audit-open.ts +722 -0
  439. package/sdk/src/query/check-auto-mode.test.ts +77 -0
  440. package/sdk/src/query/check-auto-mode.ts +50 -0
  441. package/sdk/src/query/check-completion.test.ts +113 -0
  442. package/sdk/src/query/check-completion.ts +182 -0
  443. package/sdk/src/query/check-gates.test.ts +103 -0
  444. package/sdk/src/query/check-gates.ts +112 -0
  445. package/sdk/src/query/check-ship-ready.test.ts +77 -0
  446. package/sdk/src/query/check-ship-ready.ts +103 -0
  447. package/sdk/src/query/check-verification-status.test.ts +143 -0
  448. package/sdk/src/query/check-verification-status.ts +160 -0
  449. package/sdk/src/query/commit.test.ts +202 -0
  450. package/sdk/src/query/commit.ts +301 -0
  451. package/sdk/src/query/config-gates.test.ts +89 -0
  452. package/sdk/src/query/config-gates.ts +69 -0
  453. package/sdk/src/query/config-mutation.test.ts +365 -0
  454. package/sdk/src/query/config-mutation.ts +497 -0
  455. package/sdk/src/query/config-query.test.ts +161 -0
  456. package/sdk/src/query/config-query.ts +190 -0
  457. package/sdk/src/query/context-history.test.ts +165 -0
  458. package/sdk/src/query/context-history.ts +467 -0
  459. package/sdk/src/query/decomposed-handlers.test.ts +365 -0
  460. package/sdk/src/query/detect-custom-files.ts +97 -0
  461. package/sdk/src/query/detect-phase-type.test.ts +105 -0
  462. package/sdk/src/query/detect-phase-type.ts +141 -0
  463. package/sdk/src/query/docs-init.ts +257 -0
  464. package/sdk/src/query/failure-capture.ts +58 -0
  465. package/sdk/src/query/frontmatter-array.test.ts +14 -0
  466. package/sdk/src/query/frontmatter-mutation.test.ts +259 -0
  467. package/sdk/src/query/frontmatter-mutation.ts +343 -0
  468. package/sdk/src/query/frontmatter.test.ts +281 -0
  469. package/sdk/src/query/frontmatter.ts +397 -0
  470. package/sdk/src/query/helpers.test.ts +426 -0
  471. package/sdk/src/query/helpers.ts +482 -0
  472. package/sdk/src/query/index.ts +586 -0
  473. package/sdk/src/query/init-complex.test.ts +232 -0
  474. package/sdk/src/query/init-complex.ts +578 -0
  475. package/sdk/src/query/init.test.ts +522 -0
  476. package/sdk/src/query/init.ts +1046 -0
  477. package/sdk/src/query/intel.test.ts +90 -0
  478. package/sdk/src/query/intel.ts +404 -0
  479. package/sdk/src/query/normalize-query-command.test.ts +50 -0
  480. package/sdk/src/query/normalize-query-command.ts +56 -0
  481. package/sdk/src/query/phase-lifecycle.test.ts +1126 -0
  482. package/sdk/src/query/phase-lifecycle.ts +1799 -0
  483. package/sdk/src/query/phase-list-queries.test.ts +88 -0
  484. package/sdk/src/query/phase-list-queries.ts +152 -0
  485. package/sdk/src/query/phase-ready.test.ts +65 -0
  486. package/sdk/src/query/phase-ready.ts +158 -0
  487. package/sdk/src/query/phase.test.ts +307 -0
  488. package/sdk/src/query/phase.ts +340 -0
  489. package/sdk/src/query/pipeline.test.ts +169 -0
  490. package/sdk/src/query/pipeline.ts +243 -0
  491. package/sdk/src/query/plan-execution-route.test.ts +166 -0
  492. package/sdk/src/query/plan-execution-route.ts +209 -0
  493. package/sdk/src/query/plan-task-structure.test.ts +65 -0
  494. package/sdk/src/query/plan-task-structure.ts +63 -0
  495. package/sdk/src/query/profile-extract-messages.ts +247 -0
  496. package/sdk/src/query/profile-output.ts +908 -0
  497. package/sdk/src/query/profile-questionnaire-data.ts +181 -0
  498. package/sdk/src/query/profile-sample.ts +184 -0
  499. package/sdk/src/query/profile-scan-sessions.ts +174 -0
  500. package/sdk/src/query/profile.test.ts +74 -0
  501. package/sdk/src/query/profile.ts +337 -0
  502. package/sdk/src/query/progress.test.ts +156 -0
  503. package/sdk/src/query/progress.ts +566 -0
  504. package/sdk/src/query/registry.test.ts +216 -0
  505. package/sdk/src/query/registry.ts +174 -0
  506. package/sdk/src/query/requirements-extract-from-plans.test.ts +58 -0
  507. package/sdk/src/query/requirements-extract-from-plans.ts +86 -0
  508. package/sdk/src/query/roadmap-update-plan-progress.ts +132 -0
  509. package/sdk/src/query/roadmap.test.ts +359 -0
  510. package/sdk/src/query/roadmap.ts +591 -0
  511. package/sdk/src/query/route-next-action.test.ts +61 -0
  512. package/sdk/src/query/route-next-action.ts +345 -0
  513. package/sdk/src/query/runtime-health.ts +7 -0
  514. package/sdk/src/query/schema-detect.ts +189 -0
  515. package/sdk/src/query/skill-manifest.ts +214 -0
  516. package/sdk/src/query/skills.test.ts +80 -0
  517. package/sdk/src/query/skills.ts +62 -0
  518. package/sdk/src/query/state-mutation.test.ts +450 -0
  519. package/sdk/src/query/state-mutation.ts +1444 -0
  520. package/sdk/src/query/state-project-load.ts +109 -0
  521. package/sdk/src/query/state.test.ts +347 -0
  522. package/sdk/src/query/state.ts +397 -0
  523. package/sdk/src/query/summary.test.ts +95 -0
  524. package/sdk/src/query/summary.ts +296 -0
  525. package/sdk/src/query/template.test.ts +180 -0
  526. package/sdk/src/query/template.ts +242 -0
  527. package/sdk/src/query/uat.test.ts +77 -0
  528. package/sdk/src/query/uat.ts +314 -0
  529. package/sdk/src/query/utils.test.ts +82 -0
  530. package/sdk/src/query/utils.ts +92 -0
  531. package/sdk/src/query/validate.test.ts +656 -0
  532. package/sdk/src/query/validate.ts +807 -0
  533. package/sdk/src/query/verify.test.ts +414 -0
  534. package/sdk/src/query/verify.ts +645 -0
  535. package/sdk/src/query/websearch.test.ts +31 -0
  536. package/sdk/src/query/websearch.ts +82 -0
  537. package/sdk/src/query/workspace.test.ts +119 -0
  538. package/sdk/src/query/workspace.ts +131 -0
  539. package/sdk/src/query/workstream.test.ts +51 -0
  540. package/sdk/src/query/workstream.ts +434 -0
  541. package/sdk/src/research-gate.test.ts +190 -0
  542. package/sdk/src/research-gate.ts +94 -0
  543. package/sdk/src/runtime-health.test.ts +176 -0
  544. package/sdk/src/runtime-health.ts +387 -0
  545. package/sdk/src/session-runner.test.ts +98 -0
  546. package/sdk/src/session-runner.ts +299 -0
  547. package/sdk/src/tool-scoping.test.ts +160 -0
  548. package/sdk/src/tool-scoping.ts +61 -0
  549. package/sdk/src/types.ts +917 -0
  550. package/sdk/src/workstream-utils.ts +33 -0
  551. package/sdk/src/ws-flag.test.ts +285 -0
  552. package/sdk/src/ws-transport.test.ts +161 -0
  553. package/sdk/src/ws-transport.ts +93 -0
  554. package/sdk/tsconfig.json +20 -0
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env bash
2
+ # base64-scan.sh — Detect base64-obfuscated prompt injection in source files
3
+ #
4
+ # Extracts base64 blobs >= 40 chars, decodes them, and checks decoded content
5
+ # against the same injection patterns used by prompt-injection-scan.sh.
6
+ #
7
+ # Usage:
8
+ # scripts/base64-scan.sh --diff origin/main # CI mode: scan changed files
9
+ # scripts/base64-scan.sh --file path/to/file # Scan a single file
10
+ # scripts/base64-scan.sh --dir agents/ # Scan all files in a directory
11
+ #
12
+ # Exit codes:
13
+ # 0 = clean
14
+ # 1 = findings detected
15
+ # 2 = usage error
16
+ set -euo pipefail
17
+
18
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
19
+ MIN_BLOB_LENGTH=40
20
+
21
+ # ─── Injection Patterns (decoded content) ────────────────────────────────────
22
+ # Subset of patterns — if someone base64-encoded something, check for the
23
+ # most common injection indicators.
24
+ DECODED_PATTERNS=(
25
+ 'ignore[[:space:]]+(all[[:space:]]+)?previous[[:space:]]+instructions'
26
+ 'you[[:space:]]+are[[:space:]]+now[[:space:]]+'
27
+ 'system[[:space:]]+prompt'
28
+ '</?system>'
29
+ '</?assistant>'
30
+ '\[SYSTEM\]'
31
+ '\[INST\]'
32
+ '<<SYS>>'
33
+ 'override[[:space:]]+(system|safety|security)'
34
+ 'pretend[[:space:]]+(you|to)[[:space:]]'
35
+ 'act[[:space:]]+as[[:space:]]+(a|an|if)'
36
+ 'jailbreak'
37
+ 'bypass[[:space:]]+(safety|content|security)'
38
+ 'eval[[:space:]]*\('
39
+ 'exec[[:space:]]*\('
40
+ 'rm[[:space:]]+-rf'
41
+ 'curl[[:space:]].*\|[[:space:]]*sh'
42
+ 'wget[[:space:]].*\|[[:space:]]*sh'
43
+ )
44
+
45
+ # ─── Ignorelist ──────────────────────────────────────────────────────────────
46
+
47
+ IGNOREFILE=".base64scanignore"
48
+ IGNORED_PATTERNS=()
49
+
50
+ load_ignorelist() {
51
+ if [[ -f "$IGNOREFILE" ]]; then
52
+ while IFS= read -r line; do
53
+ # Skip comments and empty lines
54
+ [[ "$line" =~ ^[[:space:]]*# ]] && continue
55
+ [[ -z "${line// }" ]] && continue
56
+ IGNORED_PATTERNS+=("$line")
57
+ done < "$IGNOREFILE"
58
+ fi
59
+ }
60
+
61
+ is_ignored() {
62
+ local blob="$1"
63
+ if [[ ${#IGNORED_PATTERNS[@]} -eq 0 ]]; then
64
+ return 1
65
+ fi
66
+ for pattern in "${IGNORED_PATTERNS[@]}"; do
67
+ if [[ "$blob" == "$pattern" ]]; then
68
+ return 0
69
+ fi
70
+ done
71
+ return 1
72
+ }
73
+
74
+ # ─── Skip Rules ──────────────────────────────────────────────────────────────
75
+
76
+ should_skip_file() {
77
+ local file="$1"
78
+ # Skip binary files
79
+ case "$file" in
80
+ *.png|*.jpg|*.jpeg|*.gif|*.ico|*.woff|*.woff2|*.ttf|*.eot|*.otf) return 0 ;;
81
+ *.zip|*.tar|*.gz|*.bz2|*.xz|*.7z) return 0 ;;
82
+ *.pdf|*.doc|*.docx|*.xls|*.xlsx) return 0 ;;
83
+ esac
84
+ # Skip lockfiles and node_modules
85
+ case "$file" in
86
+ */node_modules/*) return 0 ;;
87
+ */package-lock.json) return 0 ;;
88
+ */yarn.lock) return 0 ;;
89
+ */pnpm-lock.yaml) return 0 ;;
90
+ esac
91
+ # Skip the scan scripts themselves and test files
92
+ case "$file" in
93
+ */base64-scan.sh) return 0 ;;
94
+ */security-scan.test.cjs) return 0 ;;
95
+ esac
96
+ return 1
97
+ }
98
+
99
+ is_data_uri() {
100
+ local context="$1"
101
+ # data:image/png;base64,... or data:application/font-woff;base64,...
102
+ echo "$context" | grep -qE 'data:[a-zA-Z]+/[a-zA-Z0-9.+-]+;base64,' 2>/dev/null
103
+ }
104
+
105
+ # ─── File Collection ─────────────────────────────────────────────────────────
106
+
107
+ collect_files() {
108
+ local mode="$1"
109
+ shift
110
+
111
+ case "$mode" in
112
+ --diff)
113
+ local base="${1:-origin/main}"
114
+ git diff --name-only --diff-filter=ACMR "$base"...HEAD 2>/dev/null \
115
+ | grep -vE '\.(png|jpg|jpeg|gif|ico|woff|woff2|ttf|eot|otf|zip|tar|gz|pdf)$' || true
116
+ ;;
117
+ --file)
118
+ if [[ -f "$1" ]]; then
119
+ echo "$1"
120
+ else
121
+ echo "Error: file not found: $1" >&2
122
+ exit 2
123
+ fi
124
+ ;;
125
+ --dir)
126
+ local dir="$1"
127
+ if [[ ! -d "$dir" ]]; then
128
+ echo "Error: directory not found: $dir" >&2
129
+ exit 2
130
+ fi
131
+ find "$dir" -type f ! -path '*/node_modules/*' ! -path '*/.git/*' ! -path '*/dist/*' \
132
+ ! -name '*.png' ! -name '*.jpg' ! -name '*.gif' ! -name '*.woff*' 2>/dev/null || true
133
+ ;;
134
+ --stdin)
135
+ cat
136
+ ;;
137
+ *)
138
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path> | --stdin" >&2
139
+ exit 2
140
+ ;;
141
+ esac
142
+ }
143
+
144
+ # ─── Scanner ─────────────────────────────────────────────────────────────────
145
+
146
+ extract_and_check_blobs() {
147
+ local file="$1"
148
+ local found=0
149
+ local line_num=0
150
+
151
+ while IFS= read -r line; do
152
+ line_num=$((line_num + 1))
153
+
154
+ # Skip data URIs — legitimate base64 usage
155
+ if is_data_uri "$line"; then
156
+ continue
157
+ fi
158
+
159
+ # Extract base64-like blobs (alphanumeric + / + = padding, >= MIN_BLOB_LENGTH)
160
+ local blobs
161
+ blobs=$(echo "$line" | grep -oE '[A-Za-z0-9+/]{'"$MIN_BLOB_LENGTH"',}={0,3}' 2>/dev/null || true)
162
+
163
+ if [[ -z "$blobs" ]]; then
164
+ continue
165
+ fi
166
+
167
+ while IFS= read -r blob; do
168
+ [[ -z "$blob" ]] && continue
169
+
170
+ # Check ignorelist
171
+ if [[ ${#IGNORED_PATTERNS[@]} -gt 0 ]] && is_ignored "$blob"; then
172
+ continue
173
+ fi
174
+
175
+ # Try to decode — if it fails, not valid base64
176
+ local decoded
177
+ decoded=$(echo "$blob" | base64 -d 2>/dev/null || echo "")
178
+
179
+ if [[ -z "$decoded" ]]; then
180
+ continue
181
+ fi
182
+
183
+ # Check if decoded content is mostly printable text (not random binary)
184
+ local printable_ratio
185
+ local total_chars=${#decoded}
186
+ if [[ $total_chars -eq 0 ]]; then
187
+ continue
188
+ fi
189
+
190
+ # Count printable ASCII characters
191
+ local printable_count
192
+ printable_count=$(echo -n "$decoded" | tr -cd '[:print:]' | wc -c | tr -d ' ')
193
+ # Skip if less than 70% printable (likely binary data, not obfuscated text)
194
+ if [[ $((printable_count * 100 / total_chars)) -lt 70 ]]; then
195
+ continue
196
+ fi
197
+
198
+ # Scan decoded content against injection patterns
199
+ for pattern in "${DECODED_PATTERNS[@]}"; do
200
+ if echo "$decoded" | grep -iqE "$pattern" 2>/dev/null; then
201
+ if [[ $found -eq 0 ]]; then
202
+ echo "FAIL: $file"
203
+ found=1
204
+ fi
205
+ echo " line $line_num: base64 blob decodes to suspicious content"
206
+ echo " blob: ${blob:0:60}..."
207
+ echo " decoded: ${decoded:0:120}"
208
+ echo " matched: $pattern"
209
+ break
210
+ fi
211
+ done
212
+ done <<< "$blobs"
213
+ done < "$file"
214
+
215
+ return $found
216
+ }
217
+
218
+ # ─── Main ────────────────────────────────────────────────────────────────────
219
+
220
+ main() {
221
+ if [[ $# -eq 0 ]]; then
222
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path>" >&2
223
+ exit 2
224
+ fi
225
+
226
+ load_ignorelist
227
+
228
+ local mode="$1"
229
+ shift
230
+
231
+ local files
232
+ files=$(collect_files "$mode" "$@")
233
+
234
+ if [[ -z "$files" ]]; then
235
+ echo "base64-scan: no files to scan"
236
+ exit 0
237
+ fi
238
+
239
+ local total=0
240
+ local failed=0
241
+
242
+ while IFS= read -r file; do
243
+ [[ -z "$file" ]] && continue
244
+ if should_skip_file "$file"; then
245
+ continue
246
+ fi
247
+ total=$((total + 1))
248
+ if ! extract_and_check_blobs "$file"; then
249
+ failed=$((failed + 1))
250
+ fi
251
+ done <<< "$files"
252
+
253
+ echo ""
254
+ echo "base64-scan: scanned $total files, $failed with findings"
255
+
256
+ if [[ $failed -gt 0 ]]; then
257
+ exit 1
258
+ fi
259
+ exit 0
260
+ }
261
+
262
+ main "$@"
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Copy GSD hooks to dist for installation.
4
+ * Validates JavaScript syntax before copying to prevent shipping broken hooks.
5
+ * See #1107, #1109, #1125, #1161 — a duplicate const declaration shipped
6
+ * in dist and caused PostToolUse hook errors for all users.
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const vm = require('vm');
12
+
13
+ const HOOKS_DIR = path.join(__dirname, '..', 'hooks');
14
+ const DIST_DIR = path.join(HOOKS_DIR, 'dist');
15
+
16
+ // Hooks to copy (pure Node.js, no bundling needed)
17
+ const HOOKS_TO_COPY = [
18
+ 'gsd-check-update-worker.js',
19
+ 'gsd-check-update.js',
20
+ 'gsd-context-monitor.js',
21
+ 'gsd-prompt-guard.js',
22
+ 'gsd-read-guard.js',
23
+ 'gsd-read-injection-scanner.js',
24
+ 'gsd-statusline.js',
25
+ 'gsd-workflow-guard.js',
26
+ // Community hooks (bash, opt-in via .planning/config.json hooks.community)
27
+ 'gsd-session-state.sh',
28
+ 'gsd-validate-commit.sh',
29
+ 'gsd-phase-boundary.sh'
30
+ ];
31
+
32
+ /**
33
+ * Validate JavaScript syntax without executing the file.
34
+ * Catches SyntaxError (duplicate const, missing brackets, etc.)
35
+ * before the hook gets shipped to users.
36
+ */
37
+ function validateSyntax(filePath) {
38
+ const content = fs.readFileSync(filePath, 'utf8');
39
+ try {
40
+ // Use vm.compileFunction to check syntax without executing
41
+ new vm.Script(content, { filename: path.basename(filePath) });
42
+ return null; // No error
43
+ } catch (e) {
44
+ if (e instanceof SyntaxError) {
45
+ return e.message;
46
+ }
47
+ throw e;
48
+ }
49
+ }
50
+
51
+ function build() {
52
+ // Ensure dist directory exists
53
+ if (!fs.existsSync(DIST_DIR)) {
54
+ fs.mkdirSync(DIST_DIR, { recursive: true });
55
+ }
56
+
57
+ let hasErrors = false;
58
+
59
+ // Copy hooks to dist with syntax validation
60
+ for (const hook of HOOKS_TO_COPY) {
61
+ const src = path.join(HOOKS_DIR, hook);
62
+ const dest = path.join(DIST_DIR, hook);
63
+
64
+ if (!fs.existsSync(src)) {
65
+ console.warn(`Warning: ${hook} not found, skipping`);
66
+ continue;
67
+ }
68
+
69
+ // Validate JS syntax before copying (.sh files skip — not Node.js)
70
+ if (hook.endsWith('.js')) {
71
+ const syntaxError = validateSyntax(src);
72
+ if (syntaxError) {
73
+ console.error(`\x1b[31m✗ ${hook}: SyntaxError — ${syntaxError}\x1b[0m`);
74
+ hasErrors = true;
75
+ continue;
76
+ }
77
+ }
78
+
79
+ console.log(`\x1b[32m✓\x1b[0m Copying ${hook}...`);
80
+ fs.copyFileSync(src, dest);
81
+ // Preserve executable bit for shell scripts
82
+ if (hook.endsWith('.sh')) {
83
+ try { fs.chmodSync(dest, 0o755); } catch (e) { /* Windows */ }
84
+ }
85
+ }
86
+
87
+ if (hasErrors) {
88
+ console.error('\n\x1b[31mBuild failed: fix syntax errors above before publishing.\x1b[0m');
89
+ process.exit(1);
90
+ }
91
+
92
+ console.log('\nBuild complete.');
93
+ }
94
+
95
+ build();
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Generates docs/INVENTORY-MANIFEST.json — a structural skeleton of every
6
+ * shipped surface derived entirely from the filesystem. Commit this file;
7
+ * CI re-runs the script and diffs. A non-empty diff means a surface shipped
8
+ * without an INVENTORY.md row.
9
+ *
10
+ * Usage:
11
+ * node scripts/gen-inventory-manifest.cjs # print to stdout
12
+ * node scripts/gen-inventory-manifest.cjs --write # write docs/INVENTORY-MANIFEST.json
13
+ * node scripts/gen-inventory-manifest.cjs --check # exit 1 if committed manifest is stale
14
+ */
15
+
16
+ const fs = require('node:fs');
17
+ const path = require('node:path');
18
+
19
+ const ROOT = path.resolve(__dirname, '..');
20
+ const MANIFEST_PATH = path.join(ROOT, 'docs', 'INVENTORY-MANIFEST.json');
21
+
22
+ const FAMILIES = [
23
+ {
24
+ name: 'agents',
25
+ dir: path.join(ROOT, 'agents'),
26
+ filter: (f) => /^gsd-.*\.md$/.test(f),
27
+ toName: (f) => f.replace(/\.md$/, ''),
28
+ },
29
+ {
30
+ name: 'commands',
31
+ dir: path.join(ROOT, 'commands', 'gsd'),
32
+ filter: (f) => f.endsWith('.md'),
33
+ toName: (f) => '/gsd-' + f.replace(/\.md$/, ''),
34
+ },
35
+ {
36
+ name: 'workflows',
37
+ dir: path.join(ROOT, 'get-shit-done', 'workflows'),
38
+ filter: (f) => f.endsWith('.md'),
39
+ toName: (f) => f,
40
+ },
41
+ {
42
+ name: 'references',
43
+ dir: path.join(ROOT, 'get-shit-done', 'references'),
44
+ filter: (f) => f.endsWith('.md'),
45
+ toName: (f) => f,
46
+ },
47
+ {
48
+ name: 'cli_modules',
49
+ dir: path.join(ROOT, 'get-shit-done', 'bin', 'lib'),
50
+ filter: (f) => f.endsWith('.cjs'),
51
+ toName: (f) => f,
52
+ },
53
+ {
54
+ name: 'hooks',
55
+ dir: path.join(ROOT, 'hooks'),
56
+ filter: (f) => /\.(js|sh)$/.test(f),
57
+ toName: (f) => f,
58
+ },
59
+ ];
60
+
61
+ function buildManifest() {
62
+ const manifest = { generated: new Date().toISOString().slice(0, 10), families: {} };
63
+ for (const { name, dir, filter, toName } of FAMILIES) {
64
+ manifest.families[name] = fs
65
+ .readdirSync(dir)
66
+ .filter((f) => fs.statSync(path.join(dir, f)).isFile() && filter(f))
67
+ .map(toName)
68
+ .sort();
69
+ }
70
+ return manifest;
71
+ }
72
+
73
+ const [, , flag] = process.argv;
74
+
75
+ if (flag === '--check') {
76
+ const committed = JSON.parse(fs.readFileSync(MANIFEST_PATH, 'utf8'));
77
+ const live = buildManifest();
78
+ // Strip the generated date for comparison
79
+ delete committed.generated;
80
+ delete live.generated;
81
+ const committedStr = JSON.stringify(committed, null, 2);
82
+ const liveStr = JSON.stringify(live, null, 2);
83
+ if (committedStr !== liveStr) {
84
+ process.stderr.write(
85
+ 'docs/INVENTORY-MANIFEST.json is stale. Run:\n' +
86
+ ' node scripts/gen-inventory-manifest.cjs --write\n' +
87
+ 'then add a matching row in docs/INVENTORY.md for each new entry.\n\n',
88
+ );
89
+ // Show diff-friendly output
90
+ for (const family of Object.keys(live.families)) {
91
+ const liveSet = new Set(live.families[family]);
92
+ const committedSet = new Set((committed.families || {})[family] || []);
93
+ for (const name of liveSet) {
94
+ if (!committedSet.has(name)) process.stderr.write(' + ' + family + '/' + name + '\n');
95
+ }
96
+ for (const name of committedSet) {
97
+ if (!liveSet.has(name)) process.stderr.write(' - ' + family + '/' + name + '\n');
98
+ }
99
+ }
100
+ process.exit(1);
101
+ }
102
+ process.stdout.write('docs/INVENTORY-MANIFEST.json is up to date.\n');
103
+ } else if (flag === '--write') {
104
+ const manifest = buildManifest();
105
+ fs.writeFileSync(MANIFEST_PATH, JSON.stringify(manifest, null, 2) + '\n');
106
+ process.stdout.write('Wrote ' + MANIFEST_PATH + '\n');
107
+ } else {
108
+ process.stdout.write(JSON.stringify(buildManifest(), null, 2) + '\n');
109
+ }
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env bash
2
+ # prompt-injection-scan.sh — Scan files for prompt injection patterns
3
+ #
4
+ # Usage:
5
+ # scripts/prompt-injection-scan.sh --diff origin/main # CI mode: scan changed .md files
6
+ # scripts/prompt-injection-scan.sh --file path/to/file # Scan a single file
7
+ # scripts/prompt-injection-scan.sh --dir agents/ # Scan all files in a directory
8
+ #
9
+ # Exit codes:
10
+ # 0 = clean
11
+ # 1 = findings detected
12
+ # 2 = usage error
13
+ set -euo pipefail
14
+
15
+ # ─── Patterns ────────────────────────────────────────────────────────────────
16
+ # Each pattern is a POSIX extended regex. Keep alphabetized by category.
17
+
18
+ PATTERNS=(
19
+ # Instruction override
20
+ 'ignore[[:space:]]+(all[[:space:]]+)?(previous|prior|above|earlier|preceding)[[:space:]]+(instructions|prompts|rules|directives|context)'
21
+ 'disregard[[:space:]]+(all[[:space:]]+)?(previous|prior|above)[[:space:]]+(instructions|prompts|rules)'
22
+ 'forget[[:space:]]+(all[[:space:]]+)?(previous|prior|above)[[:space:]]+(instructions|prompts|rules|context)'
23
+ 'override[[:space:]]+(all[[:space:]]+)?(system|previous|safety)[[:space:]]+(instructions|prompts|rules|checks|filters|guards)'
24
+ 'override[[:space:]]+(system|safety|security)[[:space:]]'
25
+
26
+ # Role manipulation
27
+ 'you[[:space:]]+are[[:space:]]+now[[:space:]]+(a|an|my)[[:space:]]'
28
+ 'from[[:space:]]+now[[:space:]]+on[[:space:]]+(you|pretend|act|behave)'
29
+ 'pretend[[:space:]]+(you[[:space:]]+are|to[[:space:]]+be)[[:space:]]'
30
+ 'act[[:space:]]+as[[:space:]]+(a|an|if|my)[[:space:]]'
31
+ 'roleplay[[:space:]]+as[[:space:]]'
32
+ 'assume[[:space:]]+the[[:space:]]+role[[:space:]]+of[[:space:]]'
33
+
34
+ # System prompt extraction
35
+ 'output[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
36
+ 'reveal[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
37
+ 'show[[:space:]]+me[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
38
+ 'print[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
39
+ 'what[[:space:]]+(is|are)[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
40
+ 'repeat[[:space:]]+(your|the|all)[[:space:]]+(system[[:space:]]+)?(prompt|instructions|rules)'
41
+
42
+ # Fake message boundaries
43
+ '</?system>'
44
+ '</?assistant>'
45
+ '</?human>'
46
+ '\[SYSTEM\]'
47
+ '\[/SYSTEM\]'
48
+ '\[INST\]'
49
+ '\[/INST\]'
50
+ '<<SYS>>'
51
+ '<</SYS>>'
52
+
53
+ # Tool call injection / code execution in markdown
54
+ 'eval[[:space:]]*\([[:space:]]*["\x27]'
55
+ 'exec[[:space:]]*\([[:space:]]*["\x27]'
56
+ 'Function[[:space:]]*\([[:space:]]*["\x27].*return'
57
+
58
+ # Jailbreak / DAN patterns
59
+ 'do[[:space:]]+anything[[:space:]]+now'
60
+ 'DAN[[:space:]]+mode'
61
+ 'developer[[:space:]]+mode[[:space:]]+(enabled|output|activated)'
62
+ 'jailbreak'
63
+ 'bypass[[:space:]]+(safety|content|security)[[:space:]]+(filter|check|rule|guard)'
64
+ )
65
+
66
+ # ─── Allowlist ───────────────────────────────────────────────────────────────
67
+ # Files that legitimately discuss injection patterns (security docs, tests, this script)
68
+ ALLOWLIST=(
69
+ 'scripts/prompt-injection-scan.sh'
70
+ 'scripts/base64-scan.sh'
71
+ 'scripts/secret-scan.sh'
72
+ 'tests/security-scan.test.cjs'
73
+ 'tests/security.test.cjs'
74
+ 'tests/prompt-injection-scan.test.cjs'
75
+ 'tests/verify.test.cjs'
76
+ 'get-shit-done/bin/lib/security.cjs'
77
+ 'hooks/gsd-prompt-guard.js'
78
+ 'hooks/gsd-read-injection-scanner.js'
79
+ 'tests/read-injection-scanner.test.cjs'
80
+ 'SECURITY.md'
81
+ )
82
+
83
+ is_allowlisted() {
84
+ local file="$1"
85
+ for allowed in "${ALLOWLIST[@]}"; do
86
+ if [[ "$file" == *"$allowed" ]]; then
87
+ return 0
88
+ fi
89
+ done
90
+ return 1
91
+ }
92
+
93
+ # ─── File Collection ─────────────────────────────────────────────────────────
94
+
95
+ collect_files() {
96
+ local mode="$1"
97
+ shift
98
+
99
+ case "$mode" in
100
+ --diff)
101
+ local base="${1:-origin/main}"
102
+ # Get changed files in the diff, filter to scannable extensions
103
+ git diff --name-only --diff-filter=ACMR "$base"...HEAD 2>/dev/null \
104
+ | grep -E '\.(md|cjs|js|json|yml|yaml|sh)$' || true
105
+ ;;
106
+ --file)
107
+ if [[ -f "$1" ]]; then
108
+ echo "$1"
109
+ else
110
+ echo "Error: file not found: $1" >&2
111
+ exit 2
112
+ fi
113
+ ;;
114
+ --dir)
115
+ local dir="$1"
116
+ if [[ ! -d "$dir" ]]; then
117
+ echo "Error: directory not found: $dir" >&2
118
+ exit 2
119
+ fi
120
+ find "$dir" -type f \( -name '*.md' -o -name '*.cjs' -o -name '*.js' -o -name '*.json' -o -name '*.yml' -o -name '*.yaml' -o -name '*.sh' \) \
121
+ ! -path '*/node_modules/*' ! -path '*/.git/*' ! -path '*/dist/*' 2>/dev/null || true
122
+ ;;
123
+ --stdin)
124
+ cat
125
+ ;;
126
+ *)
127
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path> | --stdin" >&2
128
+ exit 2
129
+ ;;
130
+ esac
131
+ }
132
+
133
+ # ─── Scanner ─────────────────────────────────────────────────────────────────
134
+
135
+ scan_file() {
136
+ local file="$1"
137
+ local found=0
138
+
139
+ if is_allowlisted "$file"; then
140
+ return 0
141
+ fi
142
+
143
+ for pattern in "${PATTERNS[@]}"; do
144
+ # Use grep -iE for case-insensitive extended regex
145
+ # -n for line numbers, -c for count mode first to check
146
+ local matches
147
+ matches=$(grep -inE -e "$pattern" "$file" 2>/dev/null || true)
148
+ if [[ -n "$matches" ]]; then
149
+ if [[ $found -eq 0 ]]; then
150
+ echo "FAIL: $file"
151
+ found=1
152
+ fi
153
+ echo "$matches" | while IFS= read -r line; do
154
+ echo " $line"
155
+ done
156
+ fi
157
+ done
158
+
159
+ return $found
160
+ }
161
+
162
+ # ─── Main ────────────────────────────────────────────────────────────────────
163
+
164
+ main() {
165
+ if [[ $# -eq 0 ]]; then
166
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path>" >&2
167
+ exit 2
168
+ fi
169
+
170
+ local mode="$1"
171
+ shift
172
+
173
+ local files
174
+ files=$(collect_files "$mode" "$@")
175
+
176
+ if [[ -z "$files" ]]; then
177
+ echo "prompt-injection-scan: no files to scan"
178
+ exit 0
179
+ fi
180
+
181
+ local total=0
182
+ local failed=0
183
+
184
+ while IFS= read -r file; do
185
+ [[ -z "$file" ]] && continue
186
+ total=$((total + 1))
187
+ if ! scan_file "$file"; then
188
+ failed=$((failed + 1))
189
+ fi
190
+ done <<< "$files"
191
+
192
+ echo ""
193
+ echo "prompt-injection-scan: scanned $total files, $failed with findings"
194
+
195
+ if [[ $failed -gt 0 ]]; then
196
+ exit 1
197
+ fi
198
+ exit 0
199
+ }
200
+
201
+ main "$@"
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ // Cross-platform test runner — resolves test file globs via Node
3
+ // instead of relying on shell expansion (which fails on Windows PowerShell/cmd).
4
+ // Propagates NODE_V8_COVERAGE so c8 collects coverage from the child process.
5
+ 'use strict';
6
+
7
+ const { readdirSync } = require('fs');
8
+ const { join } = require('path');
9
+ const { execFileSync } = require('child_process');
10
+
11
+ const testDir = join(__dirname, '..', 'tests');
12
+ const files = readdirSync(testDir)
13
+ .filter(f => f.endsWith('.test.cjs'))
14
+ .sort()
15
+ .map(f => join('tests', f));
16
+
17
+ if (files.length === 0) {
18
+ console.error('No test files found in tests/');
19
+ process.exit(1);
20
+ }
21
+
22
+ const concurrency = process.env.TEST_CONCURRENCY
23
+ ? `--test-concurrency=${process.env.TEST_CONCURRENCY}`
24
+ : '--test-concurrency=4';
25
+
26
+ try {
27
+ execFileSync(process.execPath, ['--test', concurrency, ...files], {
28
+ stdio: 'inherit',
29
+ env: { ...process.env },
30
+ });
31
+ } catch (err) {
32
+ process.exit(err.status || 1);
33
+ }