code-as-plan 2.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 (188) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja-JP.md +834 -0
  3. package/README.ko-KR.md +823 -0
  4. package/README.md +1006 -0
  5. package/README.pt-BR.md +452 -0
  6. package/README.zh-CN.md +800 -0
  7. package/agents/cap-brainstormer.md +154 -0
  8. package/agents/cap-debugger.md +221 -0
  9. package/agents/cap-prototyper.md +170 -0
  10. package/agents/cap-reviewer.md +230 -0
  11. package/agents/cap-tester.md +193 -0
  12. package/bin/install.js +5002 -0
  13. package/cap/bin/gsd-tools.cjs +1141 -0
  14. package/cap/bin/lib/arc-scanner.cjs +341 -0
  15. package/cap/bin/lib/cap-feature-map.cjs +506 -0
  16. package/cap/bin/lib/cap-session.cjs +191 -0
  17. package/cap/bin/lib/cap-stack-docs.cjs +598 -0
  18. package/cap/bin/lib/cap-tag-scanner.cjs +458 -0
  19. package/cap/bin/lib/commands.cjs +959 -0
  20. package/cap/bin/lib/config.cjs +466 -0
  21. package/cap/bin/lib/convention-reader.cjs +180 -0
  22. package/cap/bin/lib/core.cjs +1230 -0
  23. package/cap/bin/lib/feature-aggregator.cjs +422 -0
  24. package/cap/bin/lib/frontmatter.cjs +336 -0
  25. package/cap/bin/lib/init.cjs +1442 -0
  26. package/cap/bin/lib/manifest-generator.cjs +381 -0
  27. package/cap/bin/lib/milestone.cjs +252 -0
  28. package/cap/bin/lib/model-profiles.cjs +68 -0
  29. package/cap/bin/lib/monorepo-context.cjs +224 -0
  30. package/cap/bin/lib/monorepo-migrator.cjs +507 -0
  31. package/cap/bin/lib/phase.cjs +888 -0
  32. package/cap/bin/lib/profile-output.cjs +952 -0
  33. package/cap/bin/lib/profile-pipeline.cjs +539 -0
  34. package/cap/bin/lib/roadmap.cjs +329 -0
  35. package/cap/bin/lib/security.cjs +382 -0
  36. package/cap/bin/lib/session-manager.cjs +290 -0
  37. package/cap/bin/lib/skeleton-generator.cjs +177 -0
  38. package/cap/bin/lib/state.cjs +1031 -0
  39. package/cap/bin/lib/template.cjs +222 -0
  40. package/cap/bin/lib/test-detector.cjs +61 -0
  41. package/cap/bin/lib/uat.cjs +282 -0
  42. package/cap/bin/lib/verify.cjs +888 -0
  43. package/cap/bin/lib/workspace-detector.cjs +369 -0
  44. package/cap/bin/lib/workstream.cjs +491 -0
  45. package/cap/commands/gsd/workstreams.md +63 -0
  46. package/cap/references/arc-standard.md +315 -0
  47. package/cap/references/cap-agent-architecture.md +102 -0
  48. package/cap/references/cap-gitignore-template +9 -0
  49. package/cap/references/cap-zero-deps.md +158 -0
  50. package/cap/references/checkpoints.md +778 -0
  51. package/cap/references/continuation-format.md +249 -0
  52. package/cap/references/decimal-phase-calculation.md +64 -0
  53. package/cap/references/feature-map-template.md +25 -0
  54. package/cap/references/git-integration.md +295 -0
  55. package/cap/references/git-planning-commit.md +38 -0
  56. package/cap/references/model-profile-resolution.md +36 -0
  57. package/cap/references/model-profiles.md +139 -0
  58. package/cap/references/phase-argument-parsing.md +61 -0
  59. package/cap/references/planning-config.md +202 -0
  60. package/cap/references/questioning.md +162 -0
  61. package/cap/references/session-template.json +8 -0
  62. package/cap/references/tdd.md +263 -0
  63. package/cap/references/ui-brand.md +160 -0
  64. package/cap/references/user-profiling.md +681 -0
  65. package/cap/references/verification-patterns.md +612 -0
  66. package/cap/references/workstream-flag.md +58 -0
  67. package/cap/templates/DEBUG.md +164 -0
  68. package/cap/templates/UAT.md +265 -0
  69. package/cap/templates/UI-SPEC.md +100 -0
  70. package/cap/templates/VALIDATION.md +76 -0
  71. package/cap/templates/claude-md.md +122 -0
  72. package/cap/templates/codebase/architecture.md +255 -0
  73. package/cap/templates/codebase/concerns.md +310 -0
  74. package/cap/templates/codebase/conventions.md +307 -0
  75. package/cap/templates/codebase/integrations.md +280 -0
  76. package/cap/templates/codebase/stack.md +186 -0
  77. package/cap/templates/codebase/structure.md +285 -0
  78. package/cap/templates/codebase/testing.md +480 -0
  79. package/cap/templates/config.json +44 -0
  80. package/cap/templates/context.md +352 -0
  81. package/cap/templates/continue-here.md +78 -0
  82. package/cap/templates/copilot-instructions.md +7 -0
  83. package/cap/templates/debug-subagent-prompt.md +91 -0
  84. package/cap/templates/dev-preferences.md +21 -0
  85. package/cap/templates/discovery.md +146 -0
  86. package/cap/templates/discussion-log.md +63 -0
  87. package/cap/templates/milestone-archive.md +123 -0
  88. package/cap/templates/milestone.md +115 -0
  89. package/cap/templates/phase-prompt.md +610 -0
  90. package/cap/templates/planner-subagent-prompt.md +117 -0
  91. package/cap/templates/project.md +186 -0
  92. package/cap/templates/requirements.md +231 -0
  93. package/cap/templates/research-project/ARCHITECTURE.md +204 -0
  94. package/cap/templates/research-project/FEATURES.md +147 -0
  95. package/cap/templates/research-project/PITFALLS.md +200 -0
  96. package/cap/templates/research-project/STACK.md +120 -0
  97. package/cap/templates/research-project/SUMMARY.md +170 -0
  98. package/cap/templates/research.md +552 -0
  99. package/cap/templates/retrospective.md +54 -0
  100. package/cap/templates/roadmap.md +202 -0
  101. package/cap/templates/state.md +176 -0
  102. package/cap/templates/summary-complex.md +59 -0
  103. package/cap/templates/summary-minimal.md +41 -0
  104. package/cap/templates/summary-standard.md +48 -0
  105. package/cap/templates/summary.md +248 -0
  106. package/cap/templates/user-profile.md +146 -0
  107. package/cap/templates/user-setup.md +311 -0
  108. package/cap/templates/verification-report.md +322 -0
  109. package/cap/workflows/add-phase.md +112 -0
  110. package/cap/workflows/add-tests.md +351 -0
  111. package/cap/workflows/add-todo.md +158 -0
  112. package/cap/workflows/audit-milestone.md +340 -0
  113. package/cap/workflows/audit-uat.md +109 -0
  114. package/cap/workflows/autonomous.md +891 -0
  115. package/cap/workflows/check-todos.md +177 -0
  116. package/cap/workflows/cleanup.md +152 -0
  117. package/cap/workflows/complete-milestone.md +767 -0
  118. package/cap/workflows/diagnose-issues.md +231 -0
  119. package/cap/workflows/discovery-phase.md +289 -0
  120. package/cap/workflows/discuss-phase-assumptions.md +653 -0
  121. package/cap/workflows/discuss-phase.md +1049 -0
  122. package/cap/workflows/do.md +104 -0
  123. package/cap/workflows/execute-phase.md +846 -0
  124. package/cap/workflows/execute-plan.md +514 -0
  125. package/cap/workflows/fast.md +105 -0
  126. package/cap/workflows/forensics.md +265 -0
  127. package/cap/workflows/health.md +181 -0
  128. package/cap/workflows/help.md +660 -0
  129. package/cap/workflows/insert-phase.md +130 -0
  130. package/cap/workflows/list-phase-assumptions.md +178 -0
  131. package/cap/workflows/list-workspaces.md +56 -0
  132. package/cap/workflows/manager.md +362 -0
  133. package/cap/workflows/map-codebase.md +377 -0
  134. package/cap/workflows/milestone-summary.md +223 -0
  135. package/cap/workflows/new-milestone.md +486 -0
  136. package/cap/workflows/new-project.md +1250 -0
  137. package/cap/workflows/new-workspace.md +237 -0
  138. package/cap/workflows/next.md +97 -0
  139. package/cap/workflows/node-repair.md +92 -0
  140. package/cap/workflows/note.md +156 -0
  141. package/cap/workflows/pause-work.md +176 -0
  142. package/cap/workflows/plan-milestone-gaps.md +273 -0
  143. package/cap/workflows/plan-phase.md +859 -0
  144. package/cap/workflows/plant-seed.md +169 -0
  145. package/cap/workflows/pr-branch.md +129 -0
  146. package/cap/workflows/profile-user.md +450 -0
  147. package/cap/workflows/progress.md +507 -0
  148. package/cap/workflows/quick.md +757 -0
  149. package/cap/workflows/remove-phase.md +155 -0
  150. package/cap/workflows/remove-workspace.md +90 -0
  151. package/cap/workflows/research-phase.md +82 -0
  152. package/cap/workflows/resume-project.md +326 -0
  153. package/cap/workflows/review.md +228 -0
  154. package/cap/workflows/session-report.md +146 -0
  155. package/cap/workflows/settings.md +283 -0
  156. package/cap/workflows/ship.md +228 -0
  157. package/cap/workflows/stats.md +60 -0
  158. package/cap/workflows/transition.md +671 -0
  159. package/cap/workflows/ui-phase.md +302 -0
  160. package/cap/workflows/ui-review.md +165 -0
  161. package/cap/workflows/update.md +323 -0
  162. package/cap/workflows/validate-phase.md +174 -0
  163. package/cap/workflows/verify-phase.md +254 -0
  164. package/cap/workflows/verify-work.md +637 -0
  165. package/commands/cap/annotate.md +165 -0
  166. package/commands/cap/brainstorm.md +238 -0
  167. package/commands/cap/debug.md +297 -0
  168. package/commands/cap/init.md +262 -0
  169. package/commands/cap/iterate.md +234 -0
  170. package/commands/cap/prototype.md +281 -0
  171. package/commands/cap/refresh-docs.md +37 -0
  172. package/commands/cap/review.md +272 -0
  173. package/commands/cap/scan.md +249 -0
  174. package/commands/cap/start.md +234 -0
  175. package/commands/cap/status.md +189 -0
  176. package/commands/cap/test.md +250 -0
  177. package/hooks/dist/gsd-check-update.js +114 -0
  178. package/hooks/dist/gsd-context-monitor.js +156 -0
  179. package/hooks/dist/gsd-prompt-guard.js +96 -0
  180. package/hooks/dist/gsd-statusline.js +119 -0
  181. package/hooks/dist/gsd-workflow-guard.js +94 -0
  182. package/package.json +51 -0
  183. package/scripts/base64-scan.sh +262 -0
  184. package/scripts/build-hooks.js +82 -0
  185. package/scripts/cap-removal-checklist.md +202 -0
  186. package/scripts/prompt-injection-scan.sh +198 -0
  187. package/scripts/run-tests.cjs +29 -0
  188. package/scripts/secret-scan.sh +227 -0
@@ -0,0 +1,202 @@
1
+ # CAP v2.0 -- GSD Removal Checklist
2
+
3
+ <!-- @gsd-context This document defines the COMPLETE removal plan for transitioning from GSD to CAP. It is NOT executed during prototyping -- it documents what gets removed when the clean break is made. -->
4
+ <!-- @gsd-decision Removal is documented as a checklist, not executed during prototype. This allows the current GSD infrastructure to keep working during development while clearly defining the target end state. -->
5
+
6
+ <!-- @gsd-todo(ref:AC-71) All /gsd:* commands shall be removed from the codebase -->
7
+ <!-- @gsd-todo(ref:AC-72) All gsd-* agent files shall be removed from the agents/ directory -->
8
+ <!-- @gsd-todo(ref:AC-73) Explicitly killed agents: gsd-discuss, gsd-planner, gsd-milestone-*, gsd-executor, gsd-annotator, and all discuss/plan phase agents -->
9
+ <!-- @gsd-todo(ref:AC-74) Artifacts no longer created or referenced: ROADMAP.md, REQUIREMENTS.md, STATE.md, MILESTONES.md, VERIFICATION.md, PLAN.md -->
10
+ <!-- @gsd-todo(ref:AC-75) CODE-INVENTORY.md evolved into enriched FEATURE-MAP.md -- standalone file removed -->
11
+ <!-- @gsd-todo(ref:AC-76) bin/install.js updated to reference CAP branding and commands -->
12
+ <!-- @gsd-todo(ref:AC-77) package.json name updated to cap (or code-as-plan fallback) -->
13
+
14
+ ---
15
+
16
+ ## 1. Agent Files to Remove (AC-72, AC-73)
17
+
18
+ The following agent files in `agents/` shall be deleted:
19
+
20
+ ### Explicitly Killed Agents (AC-73)
21
+
22
+ These agents represent the discuss/plan workflow that CAP eliminates:
23
+
24
+ - [ ] `agents/gsd-planner.md` -- replaced by Feature Map + cap-prototyper
25
+ - [ ] `agents/gsd-executor.md` -- replaced by cap-prototyper (prototype/iterate modes)
26
+ - [ ] `agents/gsd-annotator.md` -- replaced by cap-prototyper (annotate mode)
27
+ - [ ] `agents/gsd-brainstormer.md` -- replaced by cap-brainstormer
28
+ - [ ] `agents/gsd-roadmapper.md` -- ROADMAP.md no longer exists
29
+ - [ ] `agents/gsd-plan-checker.md` -- no plan phase to check
30
+ - [ ] `agents/gsd-reviewer.md` -- replaced by cap-reviewer
31
+ - [ ] `agents/gsd-tester.md` -- replaced by cap-tester
32
+ - [ ] `agents/gsd-debugger.md` -- replaced by cap-debugger
33
+
34
+ ### Supporting Agents to Remove
35
+
36
+ - [ ] `agents/gsd-advisor-researcher.md`
37
+ - [ ] `agents/gsd-arc-executor.md`
38
+ - [ ] `agents/gsd-arc-planner.md`
39
+ - [ ] `agents/gsd-assumptions-analyzer.md`
40
+ - [ ] `agents/gsd-code-planner.md`
41
+ - [ ] `agents/gsd-codebase-mapper.md`
42
+ - [ ] `agents/gsd-integration-checker.md`
43
+ - [ ] `agents/gsd-nyquist-auditor.md`
44
+ - [ ] `agents/gsd-phase-researcher.md`
45
+ - [ ] `agents/gsd-project-researcher.md`
46
+ - [ ] `agents/gsd-prototyper.md`
47
+ - [ ] `agents/gsd-research-synthesizer.md`
48
+ - [ ] `agents/gsd-ui-auditor.md`
49
+ - [ ] `agents/gsd-ui-checker.md`
50
+ - [ ] `agents/gsd-ui-researcher.md`
51
+ - [ ] `agents/gsd-user-profiler.md`
52
+ - [ ] `agents/gsd-verifier.md`
53
+
54
+ **Agents to KEEP (CAP v2.0 agent set per AC-67):**
55
+ - `agents/cap-brainstormer.md`
56
+ - `agents/cap-prototyper.md`
57
+ - `agents/cap-tester.md`
58
+ - `agents/cap-reviewer.md`
59
+ - `agents/cap-debugger.md`
60
+
61
+ ---
62
+
63
+ ## 2. Command Files to Remove (AC-71)
64
+
65
+ All files in `commands/gsd/` shall be deleted. Current GSD commands:
66
+
67
+ - [ ] `commands/gsd/add-backlog.md`
68
+ - [ ] `commands/gsd/add-phase.md`
69
+ - [ ] `commands/gsd/add-tests.md`
70
+ - [ ] `commands/gsd/add-todo.md`
71
+ - [ ] `commands/gsd/annotate.md`
72
+ - [ ] `commands/gsd/audit-milestone.md`
73
+ - [ ] `commands/gsd/audit-uat.md`
74
+ - [ ] `commands/gsd/autonomous.md`
75
+ - [ ] `commands/gsd/brainstorm.md`
76
+ - [ ] `commands/gsd/check-todos.md`
77
+ - [ ] `commands/gsd/cleanup.md`
78
+ - [ ] `commands/gsd/complete-milestone.md`
79
+ - [ ] `commands/gsd/debug.md`
80
+ - [ ] `commands/gsd/deep-plan.md`
81
+ - [ ] `commands/gsd/discuss-phase.md`
82
+ - [ ] `commands/gsd/do.md`
83
+ - [ ] `commands/gsd/execute-phase.md`
84
+ - [ ] `commands/gsd/extract-plan.md`
85
+ - [ ] `commands/gsd/fast.md`
86
+ - [ ] `commands/gsd/forensics.md`
87
+ - [ ] All remaining `commands/gsd/*.md` files
88
+
89
+ **Commands to KEEP (CAP v2.0 command set):**
90
+ - `commands/cap/init.md`
91
+ - `commands/cap/brainstorm.md`
92
+ - `commands/cap/prototype.md`
93
+ - `commands/cap/iterate.md`
94
+ - `commands/cap/annotate.md`
95
+ - `commands/cap/scan.md`
96
+ - `commands/cap/test.md`
97
+ - `commands/cap/review.md`
98
+ - `commands/cap/debug.md`
99
+ - `commands/cap/status.md`
100
+ - `commands/cap/start.md`
101
+ - `commands/cap/refresh-docs.md`
102
+
103
+ ---
104
+
105
+ ## 3. Artifact References to Remove (AC-74)
106
+
107
+ These planning artifacts shall no longer be created or referenced anywhere in the codebase:
108
+
109
+ - [ ] `ROADMAP.md` -- eliminated; features are in FEATURE-MAP.md
110
+ - [ ] `REQUIREMENTS.md` -- eliminated; ACs are in FEATURE-MAP.md
111
+ - [ ] `STATE.md` -- eliminated; state is in SESSION.json
112
+ - [ ] `MILESTONES.md` -- eliminated; no milestone concept in CAP
113
+ - [ ] `VERIFICATION.md` -- eliminated; review output goes to .cap/REVIEW.md
114
+ - [ ] `PLAN.md` -- eliminated; code is the plan
115
+ - [ ] `CODE-INVENTORY.md` -- evolved into FEATURE-MAP.md (AC-75)
116
+
117
+ ### Files to grep and update:
118
+ - [ ] `CLAUDE.md` -- remove all references to gsd:* commands and GSD workflow
119
+ - [ ] `cap/references/arc-standard.md` -- update @gsd-* references to @cap-* or archive
120
+ - [ ] Any README or documentation referencing GSD commands
121
+
122
+ ---
123
+
124
+ ## 4. Package Configuration Changes (AC-76, AC-77)
125
+
126
+ ### package.json updates (AC-77)
127
+
128
+ ```json
129
+ {
130
+ "name": "cap",
131
+ "description": "CAP (Code As Plan) -- AI-native development where code IS the plan",
132
+ "bin": {
133
+ "cap": "bin/install.js"
134
+ },
135
+ "keywords": [
136
+ "cap",
137
+ "code-as-plan",
138
+ "claude",
139
+ "claude-code",
140
+ "ai",
141
+ "development-workflow"
142
+ ]
143
+ }
144
+ ```
145
+
146
+ Fallback name if `cap` is taken on npm: `code-as-plan`
147
+
148
+ ### bin/install.js updates (AC-76)
149
+
150
+ - [ ] Update branding strings from "GSD" / "Get Shit Done" to "CAP" / "Code As Plan"
151
+ - [ ] Update command references from `/gsd:*` to `/cap:*`
152
+ - [ ] Update binary name from `cap-cc` to `cap`
153
+ - [ ] Update repository URLs if repo is renamed
154
+
155
+ ### npm files array update (AC-99)
156
+
157
+ ```json
158
+ {
159
+ "files": [
160
+ "bin",
161
+ "commands/cap",
162
+ "cap",
163
+ "agents",
164
+ "hooks/dist",
165
+ "scripts"
166
+ ]
167
+ }
168
+ ```
169
+
170
+ Note: `commands/cap` instead of `commands` to exclude `commands/gsd/` from distribution.
171
+
172
+ ---
173
+
174
+ ## 5. Distribution Changes (AC-97, AC-98, AC-99)
175
+
176
+ - [ ] Package installable via `npx cap@latest` (AC-97)
177
+ - [ ] Build uses esbuild following `scripts/build-hooks.js` pattern (AC-98)
178
+ - [ ] npm `files` array includes: bin, commands/cap, agents, hooks/dist, scripts (AC-99)
179
+
180
+ ---
181
+
182
+ ## 6. Post-Removal Verification
183
+
184
+ After executing the removal:
185
+
186
+ 1. [ ] `ls agents/` shows only 5 cap-* files
187
+ 2. [ ] `ls commands/` shows only `commands/cap/` directory
188
+ 3. [ ] `grep -r "gsd:" commands/ agents/` returns no results
189
+ 4. [ ] `grep -r "ROADMAP\|REQUIREMENTS\|STATE\.md\|MILESTONES\|VERIFICATION\|PLAN\.md" commands/ agents/` returns no results
190
+ 5. [ ] `npm test` passes
191
+ 6. [ ] `npx cap@latest` installs and runs
192
+ 7. [ ] `/cap:init` creates correct structure
193
+ 8. [ ] `/cap:scan` detects tags correctly
194
+
195
+ ---
196
+
197
+ ## Execution Notes
198
+
199
+ - This removal should be executed as a SINGLE atomic operation (one commit)
200
+ - All tests must be updated to reference CAP instead of GSD before removal
201
+ - The `.planning/` directory contents are NOT part of the distributed package and can remain as historical reference
202
+ - The `cap/` directory name is a legacy artifact that may be renamed in a future pass (low priority)
@@ -0,0 +1,198 @@
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
+ 'get-shit-done/bin/lib/security.cjs'
76
+ 'hooks/gsd-prompt-guard.js'
77
+ 'SECURITY.md'
78
+ )
79
+
80
+ is_allowlisted() {
81
+ local file="$1"
82
+ for allowed in "${ALLOWLIST[@]}"; do
83
+ if [[ "$file" == *"$allowed" ]]; then
84
+ return 0
85
+ fi
86
+ done
87
+ return 1
88
+ }
89
+
90
+ # ─── File Collection ─────────────────────────────────────────────────────────
91
+
92
+ collect_files() {
93
+ local mode="$1"
94
+ shift
95
+
96
+ case "$mode" in
97
+ --diff)
98
+ local base="${1:-origin/main}"
99
+ # Get changed files in the diff, filter to scannable extensions
100
+ git diff --name-only --diff-filter=ACMR "$base"...HEAD 2>/dev/null \
101
+ | grep -E '\.(md|cjs|js|json|yml|yaml|sh)$' || true
102
+ ;;
103
+ --file)
104
+ if [[ -f "$1" ]]; then
105
+ echo "$1"
106
+ else
107
+ echo "Error: file not found: $1" >&2
108
+ exit 2
109
+ fi
110
+ ;;
111
+ --dir)
112
+ local dir="$1"
113
+ if [[ ! -d "$dir" ]]; then
114
+ echo "Error: directory not found: $dir" >&2
115
+ exit 2
116
+ fi
117
+ find "$dir" -type f \( -name '*.md' -o -name '*.cjs' -o -name '*.js' -o -name '*.json' -o -name '*.yml' -o -name '*.yaml' -o -name '*.sh' \) \
118
+ ! -path '*/node_modules/*' ! -path '*/.git/*' ! -path '*/dist/*' 2>/dev/null || true
119
+ ;;
120
+ --stdin)
121
+ cat
122
+ ;;
123
+ *)
124
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path> | --stdin" >&2
125
+ exit 2
126
+ ;;
127
+ esac
128
+ }
129
+
130
+ # ─── Scanner ─────────────────────────────────────────────────────────────────
131
+
132
+ scan_file() {
133
+ local file="$1"
134
+ local found=0
135
+
136
+ if is_allowlisted "$file"; then
137
+ return 0
138
+ fi
139
+
140
+ for pattern in "${PATTERNS[@]}"; do
141
+ # Use grep -iE for case-insensitive extended regex
142
+ # -n for line numbers, -c for count mode first to check
143
+ local matches
144
+ matches=$(grep -inE -e "$pattern" "$file" 2>/dev/null || true)
145
+ if [[ -n "$matches" ]]; then
146
+ if [[ $found -eq 0 ]]; then
147
+ echo "FAIL: $file"
148
+ found=1
149
+ fi
150
+ echo "$matches" | while IFS= read -r line; do
151
+ echo " $line"
152
+ done
153
+ fi
154
+ done
155
+
156
+ return $found
157
+ }
158
+
159
+ # ─── Main ────────────────────────────────────────────────────────────────────
160
+
161
+ main() {
162
+ if [[ $# -eq 0 ]]; then
163
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path>" >&2
164
+ exit 2
165
+ fi
166
+
167
+ local mode="$1"
168
+ shift
169
+
170
+ local files
171
+ files=$(collect_files "$mode" "$@")
172
+
173
+ if [[ -z "$files" ]]; then
174
+ echo "prompt-injection-scan: no files to scan"
175
+ exit 0
176
+ fi
177
+
178
+ local total=0
179
+ local failed=0
180
+
181
+ while IFS= read -r file; do
182
+ [[ -z "$file" ]] && continue
183
+ total=$((total + 1))
184
+ if ! scan_file "$file"; then
185
+ failed=$((failed + 1))
186
+ fi
187
+ done <<< "$files"
188
+
189
+ echo ""
190
+ echo "prompt-injection-scan: scanned $total files, $failed with findings"
191
+
192
+ if [[ $failed -gt 0 ]]; then
193
+ exit 1
194
+ fi
195
+ exit 0
196
+ }
197
+
198
+ main "$@"
@@ -0,0 +1,29 @@
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
+ try {
23
+ execFileSync(process.execPath, ['--test', ...files], {
24
+ stdio: 'inherit',
25
+ env: { ...process.env },
26
+ });
27
+ } catch (err) {
28
+ process.exit(err.status || 1);
29
+ }
@@ -0,0 +1,227 @@
1
+ #!/usr/bin/env bash
2
+ # secret-scan.sh — Check files for accidentally committed secrets/credentials
3
+ #
4
+ # Usage:
5
+ # scripts/secret-scan.sh --diff origin/main # CI mode: scan changed files
6
+ # scripts/secret-scan.sh --file path/to/file # Scan a single file
7
+ # scripts/secret-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
+ # ─── Secret Patterns ─────────────────────────────────────────────────────────
16
+ # Format: "LABEL:::REGEX"
17
+ # Each entry is a human label paired with a POSIX extended regex.
18
+
19
+ SECRET_PATTERNS=(
20
+ # AWS
21
+ "AWS Access Key:::AKIA[0-9A-Z]{16}"
22
+ "AWS Secret Key:::aws_secret_access_key[[:space:]]*=[[:space:]]*[A-Za-z0-9/+=]{40}"
23
+
24
+ # OpenAI / Anthropic / AI providers
25
+ "OpenAI API Key:::sk-[A-Za-z0-9]{20,}"
26
+ "Anthropic API Key:::sk-ant-[A-Za-z0-9_-]{20,}"
27
+
28
+ # GitHub
29
+ "GitHub PAT:::ghp_[A-Za-z0-9]{36}"
30
+ "GitHub OAuth:::gho_[A-Za-z0-9]{36}"
31
+ "GitHub App Token:::ghs_[A-Za-z0-9]{36}"
32
+ "GitHub Fine-grained PAT:::github_pat_[A-Za-z0-9_]{20,}"
33
+
34
+ # Stripe
35
+ "Stripe Secret Key:::sk_live_[A-Za-z0-9]{24,}"
36
+ "Stripe Publishable Key:::pk_live_[A-Za-z0-9]{24,}"
37
+
38
+ # Generic patterns
39
+ "Private Key Header:::-----BEGIN[[:space:]]+(RSA|EC|DSA|OPENSSH)?[[:space:]]*PRIVATE[[:space:]]+KEY-----"
40
+ "Generic API Key Assignment:::api[_-]?key[[:space:]]*[:=][[:space:]]*['\"][A-Za-z0-9_-]{20,}['\"]"
41
+ "Generic Secret Assignment:::secret[[:space:]]*[:=][[:space:]]*['\"][A-Za-z0-9_-]{20,}['\"]"
42
+ "Generic Token Assignment:::token[[:space:]]*[:=][[:space:]]*['\"][A-Za-z0-9_-]{20,}['\"]"
43
+ "Generic Password Assignment:::password[[:space:]]*[:=][[:space:]]*['\"][^'\"]{8,}['\"]"
44
+
45
+ # Slack
46
+ "Slack Bot Token:::xoxb-[0-9]{10,}-[A-Za-z0-9]{20,}"
47
+ "Slack Webhook:::hooks\.slack\.com/services/T[A-Z0-9]{8,}/B[A-Z0-9]{8,}/[A-Za-z0-9]{24}"
48
+
49
+ # Google
50
+ "Google API Key:::AIza[A-Za-z0-9_-]{35}"
51
+
52
+ # NPM
53
+ "NPM Token:::npm_[A-Za-z0-9]{36}"
54
+
55
+ # .env file content (key=value with sensitive-looking keys)
56
+ "Env Variable Leak:::(DATABASE_URL|DB_PASSWORD|REDIS_URL|MONGO_URI|JWT_SECRET|SESSION_SECRET|ENCRYPTION_KEY)[[:space:]]*=[[:space:]]*[^[:space:]]{8,}"
57
+ )
58
+
59
+ # ─── Ignorelist ──────────────────────────────────────────────────────────────
60
+
61
+ IGNOREFILE=".secretscanignore"
62
+ IGNORED_FILES=()
63
+
64
+ load_ignorelist() {
65
+ if [[ -f "$IGNOREFILE" ]]; then
66
+ while IFS= read -r line; do
67
+ [[ "$line" =~ ^[[:space:]]*# ]] && continue
68
+ [[ -z "${line// }" ]] && continue
69
+ IGNORED_FILES+=("$line")
70
+ done < "$IGNOREFILE"
71
+ fi
72
+ }
73
+
74
+ is_ignored() {
75
+ local file="$1"
76
+ if [[ ${#IGNORED_FILES[@]} -eq 0 ]]; then
77
+ return 1
78
+ fi
79
+ for pattern in "${IGNORED_FILES[@]}"; do
80
+ # Support glob-style matching
81
+ # shellcheck disable=SC2254
82
+ case "$file" in
83
+ $pattern) return 0 ;;
84
+ esac
85
+ done
86
+ return 1
87
+ }
88
+
89
+ # ─── Skip Rules ──────────────────────────────────────────────────────────────
90
+
91
+ should_skip_file() {
92
+ local file="$1"
93
+ # Skip binary files
94
+ case "$file" in
95
+ *.png|*.jpg|*.jpeg|*.gif|*.ico|*.woff|*.woff2|*.ttf|*.eot|*.otf) return 0 ;;
96
+ *.zip|*.tar|*.gz|*.bz2|*.xz|*.7z) return 0 ;;
97
+ *.pdf|*.doc|*.docx|*.xls|*.xlsx) return 0 ;;
98
+ esac
99
+ # Skip lockfiles and node_modules
100
+ case "$file" in
101
+ */node_modules/*) return 0 ;;
102
+ */package-lock.json) return 0 ;;
103
+ */yarn.lock) return 0 ;;
104
+ */pnpm-lock.yaml) return 0 ;;
105
+ esac
106
+ # Skip the scan scripts themselves and test files
107
+ case "$file" in
108
+ */secret-scan.sh) return 0 ;;
109
+ */security-scan.test.cjs) return 0 ;;
110
+ esac
111
+ return 1
112
+ }
113
+
114
+ # ─── File Collection ─────────────────────────────────────────────────────────
115
+
116
+ collect_files() {
117
+ local mode="$1"
118
+ shift
119
+
120
+ case "$mode" in
121
+ --diff)
122
+ local base="${1:-origin/main}"
123
+ git diff --name-only --diff-filter=ACMR "$base"...HEAD 2>/dev/null \
124
+ | grep -vE '\.(png|jpg|jpeg|gif|ico|woff|woff2|ttf|eot|otf|zip|tar|gz|pdf)$' || true
125
+ ;;
126
+ --file)
127
+ if [[ -f "$1" ]]; then
128
+ echo "$1"
129
+ else
130
+ echo "Error: file not found: $1" >&2
131
+ exit 2
132
+ fi
133
+ ;;
134
+ --dir)
135
+ local dir="$1"
136
+ if [[ ! -d "$dir" ]]; then
137
+ echo "Error: directory not found: $dir" >&2
138
+ exit 2
139
+ fi
140
+ find "$dir" -type f ! -path '*/node_modules/*' ! -path '*/.git/*' ! -path '*/dist/*' \
141
+ ! -name '*.png' ! -name '*.jpg' ! -name '*.gif' ! -name '*.woff*' 2>/dev/null || true
142
+ ;;
143
+ --stdin)
144
+ cat
145
+ ;;
146
+ *)
147
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path> | --stdin" >&2
148
+ exit 2
149
+ ;;
150
+ esac
151
+ }
152
+
153
+ # ─── Scanner ─────────────────────────────────────────────────────────────────
154
+
155
+ scan_file() {
156
+ local file="$1"
157
+ local found=0
158
+
159
+ if is_ignored "$file"; then
160
+ return 0
161
+ fi
162
+
163
+ for entry in "${SECRET_PATTERNS[@]}"; do
164
+ local label="${entry%%:::*}"
165
+ local pattern="${entry#*:::}"
166
+
167
+ local matches
168
+ matches=$(grep -nE -e "$pattern" "$file" 2>/dev/null || true)
169
+ if [[ -n "$matches" ]]; then
170
+ if [[ $found -eq 0 ]]; then
171
+ echo "FAIL: $file"
172
+ found=1
173
+ fi
174
+ echo "$matches" | while IFS= read -r line; do
175
+ echo " [$label] $line"
176
+ done
177
+ fi
178
+ done
179
+
180
+ return $found
181
+ }
182
+
183
+ # ─── Main ────────────────────────────────────────────────────────────────────
184
+
185
+ main() {
186
+ if [[ $# -eq 0 ]]; then
187
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path>" >&2
188
+ exit 2
189
+ fi
190
+
191
+ load_ignorelist
192
+
193
+ local mode="$1"
194
+ shift
195
+
196
+ local files
197
+ files=$(collect_files "$mode" "$@")
198
+
199
+ if [[ -z "$files" ]]; then
200
+ echo "secret-scan: no files to scan"
201
+ exit 0
202
+ fi
203
+
204
+ local total=0
205
+ local failed=0
206
+
207
+ while IFS= read -r file; do
208
+ [[ -z "$file" ]] && continue
209
+ if should_skip_file "$file"; then
210
+ continue
211
+ fi
212
+ total=$((total + 1))
213
+ if ! scan_file "$file"; then
214
+ failed=$((failed + 1))
215
+ fi
216
+ done <<< "$files"
217
+
218
+ echo ""
219
+ echo "secret-scan: scanned $total files, $failed with findings"
220
+
221
+ if [[ $failed -gt 0 ]]; then
222
+ exit 1
223
+ fi
224
+ exit 0
225
+ }
226
+
227
+ main "$@"