@bhargavvc/sdd-cc 1.30.1 → 1.35.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 (242) hide show
  1. package/README.ja-JP.md +144 -110
  2. package/README.ko-KR.md +143 -107
  3. package/README.md +183 -112
  4. package/README.pt-BR.md +90 -52
  5. package/README.zh-CN.md +141 -101
  6. package/agents/sdd-advisor-researcher.md +23 -0
  7. package/agents/sdd-ai-researcher.md +133 -0
  8. package/agents/sdd-code-fixer.md +516 -0
  9. package/agents/sdd-code-reviewer.md +355 -0
  10. package/agents/sdd-codebase-mapper.md +3 -3
  11. package/agents/sdd-debugger.md +17 -5
  12. package/agents/sdd-doc-verifier.md +201 -0
  13. package/agents/sdd-doc-writer.md +602 -0
  14. package/agents/sdd-domain-researcher.md +153 -0
  15. package/agents/sdd-eval-auditor.md +164 -0
  16. package/agents/sdd-eval-planner.md +154 -0
  17. package/agents/sdd-executor.md +87 -4
  18. package/agents/sdd-framework-selector.md +160 -0
  19. package/agents/sdd-intel-updater.md +314 -0
  20. package/agents/sdd-nyquist-auditor.md +1 -1
  21. package/agents/sdd-phase-researcher.md +71 -4
  22. package/agents/sdd-plan-checker.md +100 -6
  23. package/agents/sdd-planner.md +145 -206
  24. package/agents/sdd-project-researcher.md +25 -2
  25. package/agents/sdd-research-synthesizer.md +3 -3
  26. package/agents/sdd-roadmapper.md +6 -6
  27. package/agents/sdd-security-auditor.md +128 -0
  28. package/agents/sdd-ui-auditor.md +43 -3
  29. package/agents/sdd-ui-checker.md +5 -5
  30. package/agents/sdd-ui-researcher.md +27 -4
  31. package/agents/sdd-user-profiler.md +2 -2
  32. package/agents/sdd-verifier.md +142 -22
  33. package/bin/install.js +2145 -545
  34. package/commands/sdd/add-backlog.md +5 -5
  35. package/commands/sdd/add-tests.md +2 -2
  36. package/commands/sdd/ai-integration-phase.md +36 -0
  37. package/commands/sdd/analyze-dependencies.md +34 -0
  38. package/commands/sdd/audit-fix.md +33 -0
  39. package/commands/sdd/autonomous.md +7 -2
  40. package/commands/sdd/cleanup.md +5 -0
  41. package/commands/sdd/code-review-fix.md +52 -0
  42. package/commands/sdd/code-review.md +55 -0
  43. package/commands/sdd/complete-milestone.md +6 -6
  44. package/commands/sdd/debug.md +22 -9
  45. package/commands/sdd/discuss-phase.md +7 -2
  46. package/commands/sdd/do.md +1 -1
  47. package/commands/sdd/docs-update.md +48 -0
  48. package/commands/sdd/eval-review.md +32 -0
  49. package/commands/sdd/execute-phase.md +4 -0
  50. package/commands/sdd/explore.md +27 -0
  51. package/commands/sdd/fast.md +2 -2
  52. package/commands/sdd/from-sdd2.md +45 -0
  53. package/commands/sdd/help.md +2 -0
  54. package/commands/sdd/import.md +36 -0
  55. package/commands/sdd/intel.md +179 -0
  56. package/commands/sdd/join-discord.md +2 -1
  57. package/commands/sdd/manager.md +1 -0
  58. package/commands/sdd/map-codebase.md +3 -3
  59. package/commands/sdd/new-milestone.md +1 -1
  60. package/commands/sdd/new-project.md +5 -1
  61. package/commands/sdd/new-workspace.md +1 -1
  62. package/commands/sdd/next.md +2 -0
  63. package/commands/sdd/plan-milestone-gaps.md +2 -2
  64. package/commands/sdd/plan-phase.md +6 -1
  65. package/commands/sdd/plant-seed.md +1 -1
  66. package/commands/sdd/profile-user.md +1 -1
  67. package/commands/sdd/quick.md +5 -3
  68. package/commands/sdd/reapply-patches.md +230 -42
  69. package/commands/sdd/research-phase.md +3 -3
  70. package/commands/sdd/review-backlog.md +1 -0
  71. package/commands/sdd/review.md +6 -3
  72. package/commands/sdd/scan.md +26 -0
  73. package/commands/sdd/secure-phase.md +35 -0
  74. package/commands/sdd/ship.md +1 -1
  75. package/commands/sdd/thread.md +5 -5
  76. package/commands/sdd/undo.md +34 -0
  77. package/commands/sdd/verify-work.md +1 -1
  78. package/commands/sdd/workstreams.md +17 -11
  79. package/hooks/dist/sdd-check-update.js +33 -8
  80. package/hooks/dist/sdd-context-monitor.js +17 -8
  81. package/hooks/dist/sdd-phase-boundary.sh +27 -0
  82. package/hooks/dist/sdd-prompt-guard.js +1 -0
  83. package/hooks/dist/sdd-read-guard.js +82 -0
  84. package/hooks/dist/sdd-session-state.sh +33 -0
  85. package/hooks/dist/sdd-statusline.js +137 -15
  86. package/hooks/dist/sdd-validate-commit.sh +47 -0
  87. package/hooks/dist/sdd-workflow-guard.js +4 -4
  88. package/hooks/sdd-check-update.js +139 -0
  89. package/hooks/sdd-context-monitor.js +165 -0
  90. package/hooks/sdd-phase-boundary.sh +27 -0
  91. package/hooks/sdd-prompt-guard.js +97 -0
  92. package/hooks/sdd-read-guard.js +82 -0
  93. package/hooks/sdd-session-state.sh +33 -0
  94. package/hooks/sdd-statusline.js +241 -0
  95. package/hooks/sdd-validate-commit.sh +47 -0
  96. package/hooks/sdd-workflow-guard.js +94 -0
  97. package/package.json +3 -3
  98. package/scripts/build-hooks.js +18 -7
  99. package/scripts/prompt-injection-scan.sh +1 -0
  100. package/scripts/rebrand-gsd-to-sdd.sh +221 -220
  101. package/scripts/run-tests.cjs +5 -1
  102. package/scripts/sync-upstream.sh +1 -1
  103. package/sdd/bin/lib/commands.cjs +79 -17
  104. package/sdd/bin/lib/config.cjs +90 -48
  105. package/sdd/bin/lib/core.cjs +452 -87
  106. package/sdd/bin/lib/docs.cjs +267 -0
  107. package/sdd/bin/lib/frontmatter.cjs +381 -336
  108. package/sdd/bin/lib/init.cjs +110 -16
  109. package/sdd/bin/lib/intel.cjs +660 -0
  110. package/sdd/bin/lib/learnings.cjs +378 -0
  111. package/sdd/bin/lib/milestone.cjs +42 -11
  112. package/sdd/bin/lib/model-profiles.cjs +17 -15
  113. package/sdd/bin/lib/phase.cjs +367 -288
  114. package/sdd/bin/lib/profile-output.cjs +106 -10
  115. package/sdd/bin/lib/roadmap.cjs +146 -115
  116. package/sdd/bin/lib/schema-detect.cjs +238 -0
  117. package/sdd/bin/lib/sdd2-import.cjs +511 -0
  118. package/sdd/bin/lib/security.cjs +124 -3
  119. package/sdd/bin/lib/state.cjs +648 -264
  120. package/sdd/bin/lib/template.cjs +8 -4
  121. package/sdd/bin/lib/verify.cjs +209 -28
  122. package/sdd/bin/lib/workstream.cjs +7 -3
  123. package/sdd/bin/sdd-tools.cjs +184 -12
  124. package/sdd/contexts/dev.md +21 -0
  125. package/sdd/contexts/research.md +22 -0
  126. package/sdd/contexts/review.md +22 -0
  127. package/sdd/references/agent-contracts.md +79 -0
  128. package/sdd/references/ai-evals.md +156 -0
  129. package/sdd/references/ai-frameworks.md +186 -0
  130. package/sdd/references/artifact-types.md +113 -0
  131. package/sdd/references/common-bug-patterns.md +114 -0
  132. package/sdd/references/context-budget.md +49 -0
  133. package/sdd/references/continuation-format.md +25 -25
  134. package/sdd/references/domain-probes.md +125 -0
  135. package/sdd/references/few-shot-examples/plan-checker.md +73 -0
  136. package/sdd/references/few-shot-examples/verifier.md +109 -0
  137. package/sdd/references/gate-prompts.md +100 -0
  138. package/sdd/references/gates.md +70 -0
  139. package/sdd/references/git-integration.md +1 -1
  140. package/sdd/references/ios-scaffold.md +123 -0
  141. package/sdd/references/model-profile-resolution.md +2 -0
  142. package/sdd/references/model-profiles.md +24 -18
  143. package/sdd/references/planner-gap-closure.md +62 -0
  144. package/sdd/references/planner-reviews.md +39 -0
  145. package/sdd/references/planner-revision.md +87 -0
  146. package/sdd/references/planning-config.md +252 -0
  147. package/sdd/references/revision-loop.md +97 -0
  148. package/sdd/references/thinking-models-debug.md +44 -0
  149. package/sdd/references/thinking-models-execution.md +50 -0
  150. package/sdd/references/thinking-models-planning.md +62 -0
  151. package/sdd/references/thinking-models-research.md +50 -0
  152. package/sdd/references/thinking-models-verification.md +55 -0
  153. package/sdd/references/thinking-partner.md +96 -0
  154. package/sdd/references/ui-brand.md +4 -4
  155. package/sdd/references/universal-anti-patterns.md +63 -0
  156. package/sdd/references/verification-overrides.md +227 -0
  157. package/sdd/references/workstream-flag.md +56 -3
  158. package/sdd/templates/AI-SPEC.md +246 -0
  159. package/sdd/templates/DEBUG.md +1 -1
  160. package/sdd/templates/SECURITY.md +61 -0
  161. package/sdd/templates/UAT.md +4 -4
  162. package/sdd/templates/VALIDATION.md +4 -4
  163. package/sdd/templates/claude-md.md +32 -9
  164. package/sdd/templates/config.json +4 -0
  165. package/sdd/templates/debug-subagent-prompt.md +1 -1
  166. package/sdd/templates/dev-preferences.md +1 -1
  167. package/sdd/templates/discovery.md +2 -2
  168. package/sdd/templates/phase-prompt.md +1 -1
  169. package/sdd/templates/planner-subagent-prompt.md +3 -3
  170. package/sdd/templates/project.md +1 -1
  171. package/sdd/templates/research.md +1 -1
  172. package/sdd/templates/state.md +2 -2
  173. package/sdd/workflows/add-phase.md +8 -8
  174. package/sdd/workflows/add-tests.md +12 -9
  175. package/sdd/workflows/add-todo.md +5 -3
  176. package/sdd/workflows/ai-integration-phase.md +284 -0
  177. package/sdd/workflows/analyze-dependencies.md +96 -0
  178. package/sdd/workflows/audit-fix.md +157 -0
  179. package/sdd/workflows/audit-milestone.md +11 -11
  180. package/sdd/workflows/audit-uat.md +2 -2
  181. package/sdd/workflows/autonomous.md +195 -27
  182. package/sdd/workflows/check-todos.md +12 -10
  183. package/sdd/workflows/cleanup.md +2 -0
  184. package/sdd/workflows/code-review-fix.md +497 -0
  185. package/sdd/workflows/code-review.md +515 -0
  186. package/sdd/workflows/complete-milestone.md +56 -22
  187. package/sdd/workflows/diagnose-issues.md +10 -3
  188. package/sdd/workflows/discovery-phase.md +5 -3
  189. package/sdd/workflows/discuss-phase-assumptions.md +24 -6
  190. package/sdd/workflows/discuss-phase-power.md +291 -0
  191. package/sdd/workflows/discuss-phase.md +173 -21
  192. package/sdd/workflows/do.md +23 -21
  193. package/sdd/workflows/docs-update.md +1155 -0
  194. package/sdd/workflows/eval-review.md +155 -0
  195. package/sdd/workflows/execute-phase.md +594 -38
  196. package/sdd/workflows/execute-plan.md +67 -96
  197. package/sdd/workflows/explore.md +139 -0
  198. package/sdd/workflows/fast.md +5 -5
  199. package/sdd/workflows/forensics.md +2 -2
  200. package/sdd/workflows/health.md +4 -4
  201. package/sdd/workflows/help.md +122 -119
  202. package/sdd/workflows/import.md +276 -0
  203. package/sdd/workflows/inbox.md +387 -0
  204. package/sdd/workflows/insert-phase.md +7 -7
  205. package/sdd/workflows/list-phase-assumptions.md +4 -4
  206. package/sdd/workflows/list-workspaces.md +2 -2
  207. package/sdd/workflows/manager.md +35 -32
  208. package/sdd/workflows/map-codebase.md +7 -5
  209. package/sdd/workflows/milestone-summary.md +2 -2
  210. package/sdd/workflows/new-milestone.md +17 -9
  211. package/sdd/workflows/new-project.md +50 -25
  212. package/sdd/workflows/new-workspace.md +7 -5
  213. package/sdd/workflows/next.md +67 -11
  214. package/sdd/workflows/note.md +9 -7
  215. package/sdd/workflows/pause-work.md +75 -12
  216. package/sdd/workflows/plan-milestone-gaps.md +8 -8
  217. package/sdd/workflows/plan-phase.md +294 -42
  218. package/sdd/workflows/plant-seed.md +6 -3
  219. package/sdd/workflows/pr-branch.md +42 -14
  220. package/sdd/workflows/profile-user.md +9 -7
  221. package/sdd/workflows/progress.md +45 -45
  222. package/sdd/workflows/quick.md +195 -47
  223. package/sdd/workflows/remove-phase.md +6 -6
  224. package/sdd/workflows/remove-workspace.md +3 -1
  225. package/sdd/workflows/research-phase.md +2 -2
  226. package/sdd/workflows/resume-project.md +12 -12
  227. package/sdd/workflows/review.md +109 -9
  228. package/sdd/workflows/scan.md +102 -0
  229. package/sdd/workflows/secure-phase.md +166 -0
  230. package/sdd/workflows/session-report.md +2 -2
  231. package/sdd/workflows/settings.md +38 -12
  232. package/sdd/workflows/ship.md +21 -9
  233. package/sdd/workflows/stats.md +1 -1
  234. package/sdd/workflows/transition.md +23 -23
  235. package/sdd/workflows/ui-phase.md +15 -7
  236. package/sdd/workflows/ui-review.md +29 -4
  237. package/sdd/workflows/undo.md +314 -0
  238. package/sdd/workflows/update.md +171 -20
  239. package/sdd/workflows/validate-phase.md +6 -4
  240. package/sdd/workflows/verify-phase.md +210 -6
  241. package/sdd/workflows/verify-work.md +83 -9
  242. package/sdd/commands/sdd/workstreams.md +0 -63
@@ -1,220 +1,221 @@
1
- #!/usr/bin/env bash
2
- ##############################################################################
3
- # rebrand-gsd-to-sdd.sh (for sdd-cc repo)
4
- #
5
- # Converts all G.S.D references to S.D.D in the IDE installer package.
6
- # IDEMPOTENT — safe to re-run. Excludes itself from modification.
7
- #
8
- # USAGE: bash scripts/rebrand-gsd-to-sdd.sh
9
- # RUN AFTER: git merge upstream-sync (into main)
10
- ##############################################################################
11
-
12
- set -euo pipefail
13
-
14
- REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
15
- cd "$REPO_ROOT"
16
-
17
- # Build literal strings via hex to avoid self-modification by sed
18
- OLD_LC=$(printf '\x67\x73\x64') # g-s-d
19
- OLD_UC=$(printf '\x47\x53\x44') # G-S-D
20
- NEW_LC="sdd"
21
- NEW_UC="SDD"
22
-
23
- # The old framework directory name (hex-encoded to avoid self-match)
24
- OLD_DIR=$(printf '\x67\x65\x74\x2d\x73\x68\x69\x74\x2d\x64\x6f\x6e\x65') # get-shit-done
25
- NEW_DIR="sdd"
26
-
27
- # Old branding phrases (hex-encoded)
28
- OLD_BRAND1=$(printf '\x47\x65\x74\x20\x53\x68\x69\x74\x20\x44\x6f\x6e\x65') # Get Shit Done
29
- OLD_BRAND2=$(printf '\x47\x65\x74\x20\x53\x74\x75\x66\x66\x20\x44\x6f\x6e\x65') # Get Stuff Done
30
- NEW_BRAND="Spec-Driven Development"
31
-
32
- SELF_NAME="rebrand-$(echo "${OLD_LC}")-to-${NEW_LC}.sh"
33
-
34
- echo "=== ${NEW_UC}-CC Rebrand Script ==="
35
- echo "Working in: $REPO_ROOT"
36
-
37
- # ─── STEP 1: Rename directories ─────────────────────────────────────────────
38
- echo ""
39
- echo "[1/5] Renaming directories..."
40
-
41
- # Rename get-shit-done/ → sdd/
42
- if [ -d "${OLD_DIR}" ] && [ ! -d "${NEW_DIR}" ]; then
43
- echo " ${OLD_DIR}/ -> ${NEW_DIR}/"
44
- mv "${OLD_DIR}" "${NEW_DIR}"
45
- fi
46
-
47
- # Rename commands/gsd/ → commands/sdd/
48
- if [ -d "commands/${OLD_LC}" ] && [ ! -d "commands/${NEW_LC}" ]; then
49
- echo " commands/${OLD_LC}/ -> commands/${NEW_LC}/"
50
- mv "commands/${OLD_LC}" "commands/${NEW_LC}"
51
- fi
52
-
53
- # Rename internal get-shit-done/commands/gsd/ if it exists
54
- if [ -d "${NEW_DIR}/commands/${OLD_LC}" ] && [ ! -d "${NEW_DIR}/commands/${NEW_LC}" ]; then
55
- echo " ${NEW_DIR}/commands/${OLD_LC}/ -> ${NEW_DIR}/commands/${NEW_LC}/"
56
- mv "${NEW_DIR}/commands/${OLD_LC}" "${NEW_DIR}/commands/${NEW_LC}"
57
- fi
58
-
59
- echo " Done."
60
-
61
- # ─── STEP 2: Rename files ───────────────────────────────────────────────────
62
- echo ""
63
- echo "[2/5] Renaming files..."
64
-
65
- find . -not -path './.git/*' -not -path './node_modules/*' \
66
- -not -name "$SELF_NAME" \
67
- \( -name "*${OLD_LC}*" -o -name "*${OLD_UC}*" -o -name "*${OLD_DIR}*" \) \
68
- -type f 2>/dev/null | sort -r | while read -r path; do
69
- dir=$(dirname "$path")
70
- base=$(basename "$path")
71
- newbase=$(echo "$base" | sed "s/${OLD_DIR}/${NEW_DIR}/g; s/${OLD_LC}/${NEW_LC}/g; s/${OLD_UC}/${NEW_UC}/g")
72
- [ "$base" = "$newbase" ] && continue
73
- echo " $path -> $dir/$newbase"
74
- mv "$path" "$dir/$newbase"
75
- done
76
-
77
- echo " Done."
78
-
79
- # ─── STEP 3: Replace content in all files ───────────────────────────────────
80
- echo ""
81
- echo "[3/5] Finding files with content to replace..."
82
-
83
- grep -rl --include="*.md" --include="*.js" --include="*.cjs" \
84
- --include="*.json" --include="*.sh" --include="*.yml" --include="*.yaml" \
85
- -E "${OLD_LC}|${OLD_UC}|${OLD_DIR}" . 2>/dev/null \
86
- | grep -v '\.git/' | grep -v 'node_modules/' \
87
- | grep -v "$SELF_NAME" \
88
- | grep -v 'package-lock.json' \
89
- > /tmp/${NEW_LC}-cc-rebrand-files.txt || true
90
-
91
- FCOUNT=$(wc -l < /tmp/${NEW_LC}-cc-rebrand-files.txt)
92
- echo " Found $FCOUNT files."
93
-
94
- echo " Replacing..."
95
- while IFS= read -r file; do
96
- [ -z "$file" ] && continue
97
-
98
- # Branding phrases first (longest match first)
99
- sed -i \
100
- -e "s/${OLD_BRAND1}/${NEW_BRAND}/g" \
101
- -e "s/${OLD_BRAND2}/${NEW_BRAND}/g" \
102
- "$file"
103
-
104
- # Directory name: get-shit-done → sdd
105
- sed -i \
106
- -e "s/${OLD_DIR}-cc/@bhargavvc\/${NEW_LC}-cc/g" \
107
- -e "s/${OLD_DIR}/${NEW_DIR}/g" \
108
- "$file"
109
-
110
- # Targeted patterns
111
- sed -i \
112
- -e "s/${OLD_LC}:/${NEW_LC}:/g" \
113
- -e "s/${OLD_LC}-/${NEW_LC}-/g" \
114
- -e "s/_${OLD_LC}/_${NEW_LC}/g" \
115
- -e "s/${OLD_LC}_/${NEW_LC}_/g" \
116
- -e "s/\/${OLD_LC}\//\/${NEW_LC}\//g" \
117
- -e "s/\.${OLD_LC}\//\.${NEW_LC}\//g" \
118
- -e "s/\.${OLD_LC}\"/.${NEW_LC}\"/g" \
119
- -e "s/\.${OLD_LC}'/.${NEW_LC}'/g" \
120
- -e "s/\"${OLD_LC}\"/\"${NEW_LC}\"/g" \
121
- -e "s/'${OLD_LC}'/'${NEW_LC}'/g" \
122
- -e "s/@${OLD_LC}\//@${NEW_LC}\//g" \
123
- -e "s/${OLD_UC}_/${NEW_UC}_/g" \
124
- -e "s/\"${OLD_UC}\"/\"${NEW_UC}\"/g" \
125
- -e "s/'${OLD_UC}'/'${NEW_UC}'/g" \
126
- "$file"
127
-
128
- # Variable syntax: {{GSD_ARGS}} → {{SDD_ARGS}}
129
- sed -i \
130
- -e "s/{{${OLD_UC}_ARGS}}/{{${NEW_UC}_ARGS}}/g" \
131
- -e "s/{{${OLD_UC}_/{{${NEW_UC}_/g" \
132
- "$file"
133
-
134
- # Catch-all: remaining standalone instances
135
- sed -i \
136
- -e "s/\b${OLD_LC}\b/${NEW_LC}/g" \
137
- -e "s/\b${OLD_UC}\b/${NEW_UC}/g" \
138
- "$file"
139
-
140
- # Restore @gsd-build (upstream npm scope — must stay)
141
- if grep -q "${NEW_LC}-build" "$file" 2>/dev/null; then
142
- sed -i \
143
- -e "s/@${NEW_LC}-build/@${OLD_LC}-build/g" \
144
- -e "s/${NEW_LC}-build\//${OLD_LC}-build\//g" \
145
- "$file"
146
- fi
147
-
148
- done < /tmp/${NEW_LC}-cc-rebrand-files.txt
149
-
150
- rm -f /tmp/${NEW_LC}-cc-rebrand-files.txt
151
- echo " Done."
152
-
153
- # ─── STEP 4: Fix package.json ───────────────────────────────────────────────
154
- echo ""
155
- echo "[4/5] Updating package.json..."
156
-
157
- if [ -f "package.json" ]; then
158
- # Fix package name and bin
159
- sed -i \
160
- -e 's/"name": *"[^"]*"/"name": "@bhargavvc\/sdd-cc"/' \
161
- -e 's/"sdd-cc-cc"/"sdd-cc"/' \
162
- -e "s/\"${OLD_DIR}-cc\"/\"${NEW_LC}-cc\"/g" \
163
- package.json
164
-
165
- # Fix bin entry: the key might already be partially renamed
166
- # Ensure bin is exactly: "sdd-cc": "bin/install.js"
167
- node -e "
168
- const pkg = require('./package.json');
169
- const fs = require('fs');
170
- pkg.name = '@bhargavvc/sdd-cc';
171
- pkg.bin = { 'sdd-cc': 'bin/install.js' };
172
- pkg.description = pkg.description
173
- .replace(/Get Shit Done/gi, 'Spec-Driven Development')
174
- .replace(/GSD/g, 'SDD')
175
- .replace(/gsd/g, 'sdd');
176
- pkg.repository = { type: 'git', url: 'git+https://github.com/bhargavvc/sdd-cc.git' };
177
- pkg.homepage = 'https://github.com/bhargavvc/sdd-cc';
178
- pkg.bugs = { url: 'https://github.com/bhargavvc/sdd-cc/issues' };
179
- pkg.publishConfig = { access: 'public' };
180
- fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
181
- "
182
- echo " package.json updated."
183
- fi
184
-
185
- echo " Done."
186
-
187
- # ─── STEP 5: Verify ─────────────────────────────────────────────────────────
188
- echo ""
189
- echo "[5/5] Verifying..."
190
-
191
- STALE_COUNT=0
192
-
193
- echo " Checking for stale references..."
194
- # Check markdown and source files for remaining gsd (excluding @gsd-build and this script)
195
- STALE=$(grep -rn "${OLD_LC}\|${OLD_DIR}" \
196
- --include="*.md" --include="*.js" --include="*.cjs" \
197
- . 2>/dev/null \
198
- | grep -v '\.git/' | grep -v 'node_modules/' \
199
- | grep -v "$SELF_NAME" \
200
- | grep -v "@${OLD_LC}-build" \
201
- | grep -v "REBRAND" \
202
- | head -20 || true)
203
-
204
- if [ -n "$STALE" ]; then
205
- echo " WARNING: Stale references found:"
206
- echo "$STALE"
207
- STALE_COUNT=$(echo "$STALE" | wc -l)
208
- else
209
- echo " No stale references found."
210
- fi
211
-
212
- echo ""
213
- echo "=== Rebrand complete ==="
214
- echo " Stale references: $STALE_COUNT"
215
- echo ""
216
- echo " Next steps:"
217
- echo " 1. Review changes: git diff --stat"
218
- echo " 2. Test installer: node bin/install.js --cursor --local"
219
- echo " 3. Commit: git add -A && git commit -m 'rebrand: GSD SDD'"
220
- echo " 4. Publish: npm publish --access public"
1
+ #!/usr/bin/env bash
2
+ ##############################################################################
3
+ # rebrand-gsd-to-sdd.sh (for sdd-cc repo)
4
+ #
5
+ # Converts all G.S.D references to S.D.D in the IDE installer package.
6
+ # IDEMPOTENT — safe to re-run. Excludes itself from modification.
7
+ #
8
+ # USAGE: bash scripts/rebrand-gsd-to-sdd.sh
9
+ # RUN AFTER: git merge upstream-sync (into main)
10
+ ##############################################################################
11
+
12
+ set -eu
13
+ # Note: pipefail removed — grep returns 1 for "no matches" which is normal
14
+
15
+ REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
16
+ cd "$REPO_ROOT"
17
+
18
+ # Build literal strings via hex to avoid self-modification by sed
19
+ OLD_LC=$(printf '\x67\x73\x64') # g-s-d
20
+ OLD_UC=$(printf '\x47\x53\x44') # G-S-D
21
+ NEW_LC="sdd"
22
+ NEW_UC="SDD"
23
+
24
+ # The old framework directory name (hex-encoded to avoid self-match)
25
+ OLD_DIR=$(printf '\x67\x65\x74\x2d\x73\x68\x69\x74\x2d\x64\x6f\x6e\x65') # get-shit-done
26
+ NEW_DIR="sdd"
27
+
28
+ # Old branding phrases (hex-encoded)
29
+ OLD_BRAND1=$(printf '\x47\x65\x74\x20\x53\x68\x69\x74\x20\x44\x6f\x6e\x65') # Get Shit Done
30
+ OLD_BRAND2=$(printf '\x47\x65\x74\x20\x53\x74\x75\x66\x66\x20\x44\x6f\x6e\x65') # Get Stuff Done
31
+ NEW_BRAND="Spec-Driven Development"
32
+
33
+ SELF_NAME="rebrand-$(echo "${OLD_LC}")-to-${NEW_LC}.sh"
34
+
35
+ echo "=== ${NEW_UC}-CC Rebrand Script ==="
36
+ echo "Working in: $REPO_ROOT"
37
+
38
+ # ─── STEP 1: Rename directories ─────────────────────────────────────────────
39
+ echo ""
40
+ echo "[1/5] Renaming directories..."
41
+
42
+ # Rename get-shit-done/ sdd/
43
+ if [ -d "${OLD_DIR}" ] && [ ! -d "${NEW_DIR}" ]; then
44
+ echo " ${OLD_DIR}/ -> ${NEW_DIR}/"
45
+ mv "${OLD_DIR}" "${NEW_DIR}"
46
+ fi
47
+
48
+ # Rename commands/gsd/ commands/sdd/
49
+ if [ -d "commands/${OLD_LC}" ] && [ ! -d "commands/${NEW_LC}" ]; then
50
+ echo " commands/${OLD_LC}/ -> commands/${NEW_LC}/"
51
+ mv "commands/${OLD_LC}" "commands/${NEW_LC}"
52
+ fi
53
+
54
+ # Rename internal get-shit-done/commands/gsd/ if it exists
55
+ if [ -d "${NEW_DIR}/commands/${OLD_LC}" ] && [ ! -d "${NEW_DIR}/commands/${NEW_LC}" ]; then
56
+ echo " ${NEW_DIR}/commands/${OLD_LC}/ -> ${NEW_DIR}/commands/${NEW_LC}/"
57
+ mv "${NEW_DIR}/commands/${OLD_LC}" "${NEW_DIR}/commands/${NEW_LC}"
58
+ fi
59
+
60
+ echo " Done."
61
+
62
+ # ─── STEP 2: Rename files ───────────────────────────────────────────────────
63
+ echo ""
64
+ echo "[2/5] Renaming files..."
65
+
66
+ find . -not -path './.git/*' -not -path './node_modules/*' \
67
+ -not -name "$SELF_NAME" \
68
+ \( -name "*${OLD_LC}*" -o -name "*${OLD_UC}*" -o -name "*${OLD_DIR}*" \) \
69
+ -type f 2>/dev/null | sort -r | while read -r path; do
70
+ dir=$(dirname "$path")
71
+ base=$(basename "$path")
72
+ newbase=$(echo "$base" | sed "s/${OLD_DIR}/${NEW_DIR}/g; s/${OLD_LC}/${NEW_LC}/g; s/${OLD_UC}/${NEW_UC}/g")
73
+ [ "$base" = "$newbase" ] && continue
74
+ echo " $path -> $dir/$newbase"
75
+ mv "$path" "$dir/$newbase"
76
+ done
77
+
78
+ echo " Done."
79
+
80
+ # ─── STEP 3: Replace content in all files ───────────────────────────────────
81
+ echo ""
82
+ echo "[3/5] Finding files with content to replace..."
83
+
84
+ grep -rl --include="*.md" --include="*.js" --include="*.cjs" \
85
+ --include="*.json" --include="*.sh" --include="*.yml" --include="*.yaml" \
86
+ -E "${OLD_LC}|${OLD_UC}|${OLD_DIR}" . 2>/dev/null \
87
+ | grep -v '\.git/' | grep -v 'node_modules/' \
88
+ | grep -v "$SELF_NAME" \
89
+ | grep -v 'package-lock.json' \
90
+ > /tmp/${NEW_LC}-cc-rebrand-files.txt || true
91
+
92
+ FCOUNT=$(wc -l < /tmp/${NEW_LC}-cc-rebrand-files.txt)
93
+ echo " Found $FCOUNT files."
94
+
95
+ echo " Replacing..."
96
+ while IFS= read -r file; do
97
+ [ -z "$file" ] && continue
98
+
99
+ # Branding phrases first (longest match first)
100
+ sed -i \
101
+ -e "s/${OLD_BRAND1}/${NEW_BRAND}/g" \
102
+ -e "s/${OLD_BRAND2}/${NEW_BRAND}/g" \
103
+ "$file"
104
+
105
+ # Directory name: get-shit-done → sdd
106
+ sed -i \
107
+ -e "s/${OLD_DIR}-cc/@bhargavvc\/${NEW_LC}-cc/g" \
108
+ -e "s/${OLD_DIR}/${NEW_DIR}/g" \
109
+ "$file"
110
+
111
+ # Targeted patterns
112
+ sed -i \
113
+ -e "s/${OLD_LC}:/${NEW_LC}:/g" \
114
+ -e "s/${OLD_LC}-/${NEW_LC}-/g" \
115
+ -e "s/_${OLD_LC}/_${NEW_LC}/g" \
116
+ -e "s/${OLD_LC}_/${NEW_LC}_/g" \
117
+ -e "s/\/${OLD_LC}\//\/${NEW_LC}\//g" \
118
+ -e "s/\.${OLD_LC}\//\.${NEW_LC}\//g" \
119
+ -e "s/\.${OLD_LC}\"/.${NEW_LC}\"/g" \
120
+ -e "s/\.${OLD_LC}'/.${NEW_LC}'/g" \
121
+ -e "s/\"${OLD_LC}\"/\"${NEW_LC}\"/g" \
122
+ -e "s/'${OLD_LC}'/'${NEW_LC}'/g" \
123
+ -e "s/@${OLD_LC}\//@${NEW_LC}\//g" \
124
+ -e "s/${OLD_UC}_/${NEW_UC}_/g" \
125
+ -e "s/\"${OLD_UC}\"/\"${NEW_UC}\"/g" \
126
+ -e "s/'${OLD_UC}'/'${NEW_UC}'/g" \
127
+ "$file"
128
+
129
+ # Variable syntax: {{GSD_ARGS}} → {{SDD_ARGS}}
130
+ sed -i \
131
+ -e "s/{{${OLD_UC}_ARGS}}/{{${NEW_UC}_ARGS}}/g" \
132
+ -e "s/{{${OLD_UC}_/{{${NEW_UC}_/g" \
133
+ "$file"
134
+
135
+ # Catch-all: remaining standalone instances
136
+ sed -i \
137
+ -e "s/\b${OLD_LC}\b/${NEW_LC}/g" \
138
+ -e "s/\b${OLD_UC}\b/${NEW_UC}/g" \
139
+ "$file"
140
+
141
+ # Restore @gsd-build (upstream npm scope — must stay)
142
+ if grep -q "${NEW_LC}-build" "$file" 2>/dev/null; then
143
+ sed -i \
144
+ -e "s/@${NEW_LC}-build/@${OLD_LC}-build/g" \
145
+ -e "s/${NEW_LC}-build\//${OLD_LC}-build\//g" \
146
+ "$file"
147
+ fi
148
+
149
+ done < /tmp/${NEW_LC}-cc-rebrand-files.txt
150
+
151
+ rm -f /tmp/${NEW_LC}-cc-rebrand-files.txt
152
+ echo " Done."
153
+
154
+ # ─── STEP 4: Fix package.json ───────────────────────────────────────────────
155
+ echo ""
156
+ echo "[4/5] Updating package.json..."
157
+
158
+ if [ -f "package.json" ]; then
159
+ # Fix package name and bin
160
+ sed -i \
161
+ -e 's/"name": *"[^"]*"/"name": "@bhargavvc\/sdd-cc"/' \
162
+ -e 's/"sdd-cc-cc"/"sdd-cc"/' \
163
+ -e "s/\"${OLD_DIR}-cc\"/\"${NEW_LC}-cc\"/g" \
164
+ package.json
165
+
166
+ # Fix bin entry: the key might already be partially renamed
167
+ # Ensure bin is exactly: "sdd-cc": "bin/install.js"
168
+ node -e "
169
+ const pkg = require('./package.json');
170
+ const fs = require('fs');
171
+ pkg.name = '@bhargavvc/sdd-cc';
172
+ pkg.bin = { 'sdd-cc': 'bin/install.js' };
173
+ pkg.description = pkg.description
174
+ .replace(/Get Shit Done/gi, 'Spec-Driven Development')
175
+ .replace(/GSD/g, 'SDD')
176
+ .replace(/gsd/g, 'sdd');
177
+ pkg.repository = { type: 'git', url: 'git+https://github.com/bhargavvc/sdd-cc.git' };
178
+ pkg.homepage = 'https://github.com/bhargavvc/sdd-cc';
179
+ pkg.bugs = { url: 'https://github.com/bhargavvc/sdd-cc/issues' };
180
+ pkg.publishConfig = { access: 'public' };
181
+ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
182
+ "
183
+ echo " package.json updated."
184
+ fi
185
+
186
+ echo " Done."
187
+
188
+ # ─── STEP 5: Verify ─────────────────────────────────────────────────────────
189
+ echo ""
190
+ echo "[5/5] Verifying..."
191
+
192
+ STALE_COUNT=0
193
+
194
+ echo " Checking for stale references..."
195
+ # Check markdown and source files for remaining gsd (excluding @gsd-build and this script)
196
+ STALE=$(grep -rn "${OLD_LC}\|${OLD_DIR}" \
197
+ --include="*.md" --include="*.js" --include="*.cjs" \
198
+ . 2>/dev/null \
199
+ | grep -v '\.git/' | grep -v 'node_modules/' \
200
+ | grep -v "$SELF_NAME" \
201
+ | grep -v "@${OLD_LC}-build" \
202
+ | grep -v "REBRAND" \
203
+ | head -20 || true)
204
+
205
+ if [ -n "$STALE" ]; then
206
+ echo " WARNING: Stale references found:"
207
+ echo "$STALE"
208
+ STALE_COUNT=$(echo "$STALE" | wc -l)
209
+ else
210
+ echo " No stale references found."
211
+ fi
212
+
213
+ echo ""
214
+ echo "=== Rebrand complete ==="
215
+ echo " Stale references: $STALE_COUNT"
216
+ echo ""
217
+ echo " Next steps:"
218
+ echo " 1. Review changes: git diff --stat"
219
+ echo " 2. Test installer: node bin/install.js --cursor --local"
220
+ echo " 3. Commit: git add -A && git commit -m 'rebrand: GSD → SDD'"
221
+ echo " 4. Publish: npm publish --access public"
@@ -19,8 +19,12 @@ if (files.length === 0) {
19
19
  process.exit(1);
20
20
  }
21
21
 
22
+ const concurrency = process.env.TEST_CONCURRENCY
23
+ ? `--test-concurrency=${process.env.TEST_CONCURRENCY}`
24
+ : '--test-concurrency=4';
25
+
22
26
  try {
23
- execFileSync(process.execPath, ['--test', ...files], {
27
+ execFileSync(process.execPath, ['--test', concurrency, ...files], {
24
28
  stdio: 'inherit',
25
29
  env: { ...process.env },
26
30
  });
@@ -2,7 +2,7 @@
2
2
  ##############################################################################
3
3
  # sync-upstream.sh
4
4
  #
5
- # Syncs the sdd-cc fork with upstream gsd-build/get-shit-done,
5
+ # Syncs the sdd-cc fork with upstream gsd-build/sdd,
6
6
  # then runs the rebrand script.
7
7
  #
8
8
  # USAGE: bash scripts/sync-upstream.sh
@@ -8,6 +8,33 @@ const { safeReadFile, loadConfig, isGitIgnored, execGit, normalizePhaseName, com
8
8
  const { extractFrontmatter } = require('./frontmatter.cjs');
9
9
  const { MODEL_PROFILES } = require('./model-profiles.cjs');
10
10
 
11
+ /**
12
+ * Determine phase status by checking plan/summary counts AND verification state.
13
+ * Introduces "Executed" for phases with all summaries but no passing verification.
14
+ */
15
+ function determinePhaseStatus(plans, summaries, phaseDir, defaultPending) {
16
+ if (plans === 0) return defaultPending;
17
+ if (summaries < plans && summaries > 0) return 'In Progress';
18
+ if (summaries < plans) return 'Planned';
19
+
20
+ // summaries >= plans — check verification
21
+ try {
22
+ const files = fs.readdirSync(phaseDir);
23
+ const verificationFile = files.find(f => f === 'VERIFICATION.md' || f.endsWith('-VERIFICATION.md'));
24
+ if (verificationFile) {
25
+ const content = fs.readFileSync(path.join(phaseDir, verificationFile), 'utf-8');
26
+ if (/status:\s*passed/i.test(content)) return 'Complete';
27
+ if (/status:\s*human_needed/i.test(content)) return 'Needs Review';
28
+ if (/status:\s*gaps_found/i.test(content)) return 'Executed';
29
+ // Verification exists but unrecognized status — treat as executed
30
+ return 'Executed';
31
+ }
32
+ } catch { /* directory read failed — fall through */ }
33
+
34
+ // No verification file — executed but not verified
35
+ return 'Executed';
36
+ }
37
+
11
38
  function cmdGenerateSlug(text, raw) {
12
39
  if (!text) {
13
40
  error('text required for slug generation');
@@ -16,7 +43,8 @@ function cmdGenerateSlug(text, raw) {
16
43
  const slug = text
17
44
  .toLowerCase()
18
45
  .replace(/[^a-z0-9]+/g, '-')
19
- .replace(/^-+|-+$/g, '');
46
+ .replace(/^-+|-+$/g, '')
47
+ .substring(0, 60);
20
48
 
21
49
  const result = { slug };
22
50
  output(result, raw, slug);
@@ -254,7 +282,7 @@ function cmdCommit(cwd, message, files, raw, amend, noVerify) {
254
282
  let branchName = null;
255
283
  if (config.branching_strategy === 'phase') {
256
284
  // Determine which phase we're committing for from the file paths
257
- const phaseMatch = (files || []).join(' ').match(/(\d+)-/);
285
+ const phaseMatch = (files || []).join(' ').match(/(\d+(?:\.\d+)*)-/);
258
286
  if (phaseMatch) {
259
287
  const phaseNum = phaseMatch[1];
260
288
  const phaseInfo = findPhaseInternal(cwd, phaseNum);
@@ -285,11 +313,19 @@ function cmdCommit(cwd, message, files, raw, amend, noVerify) {
285
313
  }
286
314
 
287
315
  // Stage files
288
- const filesToStage = files && files.length > 0 ? files : ['.planning/'];
316
+ const explicitFiles = files && files.length > 0;
317
+ const filesToStage = explicitFiles ? files : ['.planning/'];
289
318
  for (const file of filesToStage) {
290
319
  const fullPath = path.join(cwd, file);
291
320
  if (!fs.existsSync(fullPath)) {
292
- // File was deleted/moved — stage the deletion
321
+ if (explicitFiles) {
322
+ // Caller passed an explicit --files list: missing files are skipped.
323
+ // Staging a deletion here would silently remove tracked planning files
324
+ // (e.g. STATE.md, ROADMAP.md) when they are temporarily absent (#2014).
325
+ continue;
326
+ }
327
+ // Default mode (staging all of .planning/): stage the deletion so
328
+ // removed planning files are not left dangling in the index.
293
329
  execGit(cwd, ['rm', '--cached', '--ignore-unmatch', file]);
294
330
  } else {
295
331
  execGit(cwd, ['add', file]);
@@ -528,11 +564,7 @@ function cmdProgressRender(cwd, format, raw) {
528
564
  totalPlans += plans;
529
565
  totalSummaries += summaries;
530
566
 
531
- let status;
532
- if (plans === 0) status = 'Pending';
533
- else if (summaries >= plans) status = 'Complete';
534
- else if (summaries > 0) status = 'In Progress';
535
- else status = 'Planned';
567
+ const status = determinePhaseStatus(plans, summaries, path.join(phasesDir, dir), 'Pending');
536
568
 
537
569
  phases.push({ number: phaseNum, name: phaseName, plans, summaries, status });
538
570
  }
@@ -741,7 +773,7 @@ function cmdScaffold(cwd, type, options, raw) {
741
773
  switch (type) {
742
774
  case 'context': {
743
775
  filePath = path.join(phaseDir, `${padded}-CONTEXT.md`);
744
- content = `---\nphase: "${padded}"\nname: "${name || phaseInfo?.phase_name || 'Unnamed'}"\ncreated: ${today}\n---\n\n# Phase ${phase}: ${name || phaseInfo?.phase_name || 'Unnamed'} — Context\n\n## Decisions\n\n_Decisions will be captured during /sdd:discuss-phase ${phase}_\n\n## Discretion Areas\n\n_Areas where the executor can use judgment_\n\n## Deferred Ideas\n\n_Ideas to consider later_\n`;
776
+ content = `---\nphase: "${padded}"\nname: "${name || phaseInfo?.phase_name || 'Unnamed'}"\ncreated: ${today}\n---\n\n# Phase ${phase}: ${name || phaseInfo?.phase_name || 'Unnamed'} — Context\n\n## Decisions\n\n_Decisions will be captured during /sdd-discuss-phase ${phase}_\n\n## Discretion Areas\n\n_Areas where the executor can use judgment_\n\n## Deferred Ideas\n\n_Ideas to consider later_\n`;
745
777
  break;
746
778
  }
747
779
  case 'uat': {
@@ -828,18 +860,14 @@ function cmdStats(cwd, format, raw) {
828
860
  totalPlans += plans;
829
861
  totalSummaries += summaries;
830
862
 
831
- let status;
832
- if (plans === 0) status = 'Not Started';
833
- else if (summaries >= plans) status = 'Complete';
834
- else if (summaries > 0) status = 'In Progress';
835
- else status = 'Planned';
863
+ const status = determinePhaseStatus(plans, summaries, path.join(phasesDir, dir), 'Not Started');
836
864
 
837
865
  const existing = phasesByNumber.get(phaseNum);
838
866
  phasesByNumber.set(phaseNum, {
839
867
  number: phaseNum,
840
868
  name: existing?.name || phaseName,
841
- plans,
842
- summaries,
869
+ plans: (existing?.plans || 0) + plans,
870
+ summaries: (existing?.summaries || 0) + summaries,
843
871
  status,
844
872
  });
845
873
  }
@@ -940,6 +968,39 @@ function cmdStats(cwd, format, raw) {
940
968
  }
941
969
  }
942
970
 
971
+ /**
972
+ * Check whether a commit should be allowed based on commit_docs config.
973
+ * When commit_docs is false, rejects commits that stage .planning/ files.
974
+ * Intended for use as a pre-commit hook guard.
975
+ */
976
+ function cmdCheckCommit(cwd, raw) {
977
+ const config = loadConfig(cwd);
978
+
979
+ // If commit_docs is true (or not set), allow all commits
980
+ if (config.commit_docs !== false) {
981
+ output({ allowed: true, reason: 'commit_docs_enabled' }, raw, 'allowed');
982
+ return;
983
+ }
984
+
985
+ // commit_docs is false — check if any .planning/ files are staged
986
+ try {
987
+ const staged = execSync('git diff --cached --name-only', { cwd, encoding: 'utf-8' }).trim();
988
+ const planningFiles = staged.split('\n').filter(f => f.startsWith('.planning/') || f.startsWith('.planning\\'));
989
+
990
+ if (planningFiles.length > 0) {
991
+ error(
992
+ `commit_docs is false but ${planningFiles.length} .planning/ file(s) are staged:\n` +
993
+ planningFiles.map(f => ` ${f}`).join('\n') +
994
+ `\n\nTo unstage: git reset HEAD ${planningFiles.join(' ')}`
995
+ );
996
+ }
997
+ } catch {
998
+ // git diff --cached failed (no staged files or not a git repo) — allow
999
+ }
1000
+
1001
+ output({ allowed: true, reason: 'no_planning_files_staged' }, raw, 'allowed');
1002
+ }
1003
+
943
1004
  module.exports = {
944
1005
  cmdGenerateSlug,
945
1006
  cmdCurrentTimestamp,
@@ -956,4 +1017,5 @@ module.exports = {
956
1017
  cmdTodoMatchPhase,
957
1018
  cmdScaffold,
958
1019
  cmdStats,
1020
+ cmdCheckCommit,
959
1021
  };