gsd-opencode 1.30.0 → 1.33.1

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 (113) hide show
  1. package/agents/gsd-debugger.md +0 -1
  2. package/agents/gsd-doc-verifier.md +207 -0
  3. package/agents/gsd-doc-writer.md +608 -0
  4. package/agents/gsd-executor.md +22 -1
  5. package/agents/gsd-phase-researcher.md +41 -0
  6. package/agents/gsd-plan-checker.md +82 -0
  7. package/agents/gsd-planner.md +123 -194
  8. package/agents/gsd-security-auditor.md +129 -0
  9. package/agents/gsd-ui-auditor.md +40 -0
  10. package/agents/gsd-user-profiler.md +2 -2
  11. package/agents/gsd-verifier.md +84 -18
  12. package/commands/gsd/gsd-add-backlog.md +1 -1
  13. package/commands/gsd/gsd-analyze-dependencies.md +34 -0
  14. package/commands/gsd/gsd-autonomous.md +6 -2
  15. package/commands/gsd/gsd-cleanup.md +5 -0
  16. package/commands/gsd/gsd-debug.md +24 -21
  17. package/commands/gsd/gsd-discuss-phase.md +7 -2
  18. package/commands/gsd/gsd-docs-update.md +48 -0
  19. package/commands/gsd/gsd-execute-phase.md +4 -0
  20. package/commands/gsd/gsd-help.md +2 -0
  21. package/commands/gsd/gsd-join-discord.md +2 -1
  22. package/commands/gsd/gsd-manager.md +1 -0
  23. package/commands/gsd/gsd-new-project.md +4 -0
  24. package/commands/gsd/gsd-plan-phase.md +5 -0
  25. package/commands/gsd/gsd-quick.md +5 -3
  26. package/commands/gsd/gsd-reapply-patches.md +171 -39
  27. package/commands/gsd/gsd-research-phase.md +2 -12
  28. package/commands/gsd/gsd-review-backlog.md +1 -0
  29. package/commands/gsd/gsd-review.md +3 -2
  30. package/commands/gsd/gsd-secure-phase.md +35 -0
  31. package/commands/gsd/gsd-set-profile.md +0 -1
  32. package/commands/gsd/gsd-thread.md +1 -1
  33. package/commands/gsd/gsd-workstreams.md +7 -2
  34. package/get-shit-done/bin/gsd-tools.cjs +42 -8
  35. package/get-shit-done/bin/lib/commands.cjs +68 -14
  36. package/get-shit-done/bin/lib/config.cjs +18 -10
  37. package/get-shit-done/bin/lib/core.cjs +383 -80
  38. package/get-shit-done/bin/lib/docs.cjs +267 -0
  39. package/get-shit-done/bin/lib/frontmatter.cjs +47 -2
  40. package/get-shit-done/bin/lib/init.cjs +85 -5
  41. package/get-shit-done/bin/lib/milestone.cjs +21 -0
  42. package/get-shit-done/bin/lib/model-profiles.cjs +2 -0
  43. package/get-shit-done/bin/lib/phase.cjs +232 -189
  44. package/get-shit-done/bin/lib/profile-output.cjs +97 -1
  45. package/get-shit-done/bin/lib/roadmap.cjs +137 -113
  46. package/get-shit-done/bin/lib/schema-detect.cjs +238 -0
  47. package/get-shit-done/bin/lib/security.cjs +5 -3
  48. package/get-shit-done/bin/lib/state.cjs +366 -44
  49. package/get-shit-done/bin/lib/verify.cjs +158 -14
  50. package/get-shit-done/bin/lib/workstream.cjs +6 -2
  51. package/get-shit-done/references/agent-contracts.md +79 -0
  52. package/get-shit-done/references/artifact-types.md +113 -0
  53. package/get-shit-done/references/context-budget.md +49 -0
  54. package/get-shit-done/references/continuation-format.md +15 -15
  55. package/get-shit-done/references/domain-probes.md +125 -0
  56. package/get-shit-done/references/gate-prompts.md +100 -0
  57. package/get-shit-done/references/model-profiles.md +2 -2
  58. package/get-shit-done/references/planner-gap-closure.md +62 -0
  59. package/get-shit-done/references/planner-reviews.md +39 -0
  60. package/get-shit-done/references/planner-revision.md +87 -0
  61. package/get-shit-done/references/planning-config.md +15 -0
  62. package/get-shit-done/references/revision-loop.md +97 -0
  63. package/get-shit-done/references/ui-brand.md +2 -2
  64. package/get-shit-done/references/universal-anti-patterns.md +58 -0
  65. package/get-shit-done/references/workstream-flag.md +56 -3
  66. package/get-shit-done/templates/SECURITY.md +61 -0
  67. package/get-shit-done/templates/VALIDATION.md +3 -3
  68. package/get-shit-done/templates/claude-md.md +27 -4
  69. package/get-shit-done/templates/config.json +4 -0
  70. package/get-shit-done/templates/debug-subagent-prompt.md +2 -6
  71. package/get-shit-done/templates/planner-subagent-prompt.md +2 -10
  72. package/get-shit-done/workflows/add-phase.md +2 -2
  73. package/get-shit-done/workflows/add-todo.md +1 -1
  74. package/get-shit-done/workflows/analyze-dependencies.md +96 -0
  75. package/get-shit-done/workflows/audit-milestone.md +8 -12
  76. package/get-shit-done/workflows/autonomous.md +158 -13
  77. package/get-shit-done/workflows/check-todos.md +2 -2
  78. package/get-shit-done/workflows/complete-milestone.md +13 -4
  79. package/get-shit-done/workflows/diagnose-issues.md +8 -6
  80. package/get-shit-done/workflows/discovery-phase.md +1 -1
  81. package/get-shit-done/workflows/discuss-phase-assumptions.md +24 -6
  82. package/get-shit-done/workflows/discuss-phase-power.md +291 -0
  83. package/get-shit-done/workflows/discuss-phase.md +153 -20
  84. package/get-shit-done/workflows/docs-update.md +1093 -0
  85. package/get-shit-done/workflows/execute-phase.md +362 -66
  86. package/get-shit-done/workflows/execute-plan.md +1 -1
  87. package/get-shit-done/workflows/help.md +9 -6
  88. package/get-shit-done/workflows/insert-phase.md +2 -2
  89. package/get-shit-done/workflows/manager.md +27 -26
  90. package/get-shit-done/workflows/map-codebase.md +10 -32
  91. package/get-shit-done/workflows/new-milestone.md +14 -8
  92. package/get-shit-done/workflows/new-project.md +48 -25
  93. package/get-shit-done/workflows/next.md +1 -1
  94. package/get-shit-done/workflows/note.md +1 -1
  95. package/get-shit-done/workflows/pause-work.md +73 -10
  96. package/get-shit-done/workflows/plan-milestone-gaps.md +2 -2
  97. package/get-shit-done/workflows/plan-phase.md +184 -32
  98. package/get-shit-done/workflows/progress.md +20 -20
  99. package/get-shit-done/workflows/quick.md +102 -84
  100. package/get-shit-done/workflows/research-phase.md +2 -6
  101. package/get-shit-done/workflows/resume-project.md +4 -4
  102. package/get-shit-done/workflows/review.md +56 -3
  103. package/get-shit-done/workflows/secure-phase.md +154 -0
  104. package/get-shit-done/workflows/settings.md +13 -2
  105. package/get-shit-done/workflows/ship.md +13 -4
  106. package/get-shit-done/workflows/transition.md +6 -6
  107. package/get-shit-done/workflows/ui-phase.md +4 -14
  108. package/get-shit-done/workflows/ui-review.md +25 -7
  109. package/get-shit-done/workflows/update.md +165 -16
  110. package/get-shit-done/workflows/validate-phase.md +1 -11
  111. package/get-shit-done/workflows/verify-phase.md +127 -6
  112. package/get-shit-done/workflows/verify-work.md +69 -21
  113. package/package.json +1 -1
@@ -12,7 +12,9 @@ permissions:
12
12
  ---
13
13
 
14
14
  <objective>
15
- After a GSD update wipes and reinstalls files, this command merges user's previously saved local modifications back into the new version. Uses intelligent comparison to handle cases where the upstream file also changed.
15
+ After a GSD update wipes and reinstalls files, this command merges user's previously saved local modifications back into the new version. Uses three-way comparison (pristine baseline, user-modified backup, newly installed version) to reliably distinguish user customizations from version drift.
16
+
17
+ **Critical invariant:** Every file in `gsd-local-patches/` was backed up because the installer's hash comparison detected it was modified. The workflow must NEVER conclude "no custom content" for any backed-up file — that is a logical contradiction. When in doubt, classify as CONFLICT requiring user review, not SKIP.
16
18
  </objective>
17
19
 
18
20
  <process>
@@ -22,19 +24,90 @@ After a GSD update wipes and reinstalls files, this command merges user's previo
22
24
  Check for local patches directory:
23
25
 
24
26
  ```bash
25
- # Global install — detect runtime config directory
26
- if [ -d "$HOME/.config/opencode/gsd-local-patches" ]; then
27
- PATCHES_DIR="$HOME/.config/opencode/gsd-local-patches"
28
- elif [ -d "$HOME/.opencode/gsd-local-patches" ]; then
29
- PATCHES_DIR="$HOME/.opencode/gsd-local-patches"
30
- elif [ -d "$HOME/.gemini/gsd-local-patches" ]; then
31
- PATCHES_DIR="$HOME/.gemini/gsd-local-patches"
32
- else
33
- PATCHES_DIR="$HOME/.OpenCode/gsd-local-patches"
27
+ expand_home() {
28
+ case "$1" in
29
+ "~/"*) printf '%s/%s\n' "$HOME" "${1#~/}" ;;
30
+ *) printf '%s\n' "$1" ;;
31
+ esac
32
+ }
33
+
34
+ PATCHES_DIR=""
35
+
36
+ # Env overrides first — covers custom config directories used with --config-dir
37
+ if [ -n "$KILO_CONFIG_DIR" ]; then
38
+ candidate="$(expand_home "$KILO_CONFIG_DIR")/gsd-local-patches"
39
+ if [ -d "$candidate" ]; then
40
+ PATCHES_DIR="$candidate"
41
+ fi
42
+ elif [ -n "$KILO_CONFIG" ]; then
43
+ candidate="$(dirname "$(expand_home "$KILO_CONFIG")")/gsd-local-patches"
44
+ if [ -d "$candidate" ]; then
45
+ PATCHES_DIR="$candidate"
46
+ fi
47
+ elif [ -n "$XDG_CONFIG_HOME" ]; then
48
+ candidate="$(expand_home "$XDG_CONFIG_HOME")/kilo/gsd-local-patches"
49
+ if [ -d "$candidate" ]; then
50
+ PATCHES_DIR="$candidate"
51
+ fi
52
+ fi
53
+
54
+ if [ -z "$PATCHES_DIR" ] && [ -n "$OPENCODE_CONFIG_DIR" ]; then
55
+ candidate="$(expand_home "$OPENCODE_CONFIG_DIR")/gsd-local-patches"
56
+ if [ -d "$candidate" ]; then
57
+ PATCHES_DIR="$candidate"
58
+ fi
59
+ elif [ -z "$PATCHES_DIR" ] && [ -n "$OPENCODE_CONFIG" ]; then
60
+ candidate="$(dirname "$(expand_home "$OPENCODE_CONFIG")")/gsd-local-patches"
61
+ if [ -d "$candidate" ]; then
62
+ PATCHES_DIR="$candidate"
63
+ fi
64
+ elif [ -z "$PATCHES_DIR" ] && [ -n "$XDG_CONFIG_HOME" ]; then
65
+ candidate="$(expand_home "$XDG_CONFIG_HOME")/opencode/gsd-local-patches"
66
+ if [ -d "$candidate" ]; then
67
+ PATCHES_DIR="$candidate"
68
+ fi
69
+ fi
70
+
71
+ if [ -z "$PATCHES_DIR" ] && [ -n "$GEMINI_CONFIG_DIR" ]; then
72
+ candidate="$(expand_home "$GEMINI_CONFIG_DIR")/gsd-local-patches"
73
+ if [ -d "$candidate" ]; then
74
+ PATCHES_DIR="$candidate"
75
+ fi
76
+ fi
77
+
78
+ if [ -z "$PATCHES_DIR" ] && [ -n "$CODEX_HOME" ]; then
79
+ candidate="$(expand_home "$CODEX_HOME")/gsd-local-patches"
80
+ if [ -d "$candidate" ]; then
81
+ PATCHES_DIR="$candidate"
82
+ fi
83
+ fi
84
+
85
+ if [ -z "$PATCHES_DIR" ] && [ -n "$CLAUDE_CONFIG_DIR" ]; then
86
+ candidate="$(expand_home "$CLAUDE_CONFIG_DIR")/gsd-local-patches"
87
+ if [ -d "$candidate" ]; then
88
+ PATCHES_DIR="$candidate"
89
+ fi
90
+ fi
91
+
92
+ # Global install — detect runtime config directory defaults
93
+ if [ -z "$PATCHES_DIR" ]; then
94
+ if [ -d "$HOME/.config/kilo/gsd-local-patches" ]; then
95
+ PATCHES_DIR="$HOME/.config/kilo/gsd-local-patches"
96
+ elif [ -d "$HOME/.config/opencode/gsd-local-patches" ]; then
97
+ PATCHES_DIR="$HOME/.config/opencode/gsd-local-patches"
98
+ elif [ -d "$HOME/.opencode/gsd-local-patches" ]; then
99
+ PATCHES_DIR="$HOME/.opencode/gsd-local-patches"
100
+ elif [ -d "$HOME/.gemini/gsd-local-patches" ]; then
101
+ PATCHES_DIR="$HOME/.gemini/gsd-local-patches"
102
+ elif [ -d "$HOME/.codex/gsd-local-patches" ]; then
103
+ PATCHES_DIR="$HOME/.codex/gsd-local-patches"
104
+ else
105
+ PATCHES_DIR="$HOME/.OpenCode/gsd-local-patches"
106
+ fi
34
107
  fi
35
108
  # Local install fallback — check all runtime directories
36
109
  if [ ! -d "$PATCHES_DIR" ]; then
37
- for dir in .config/opencode .opencode .gemini .OpenCode; do
110
+ for dir in .config/kilo .kilo .config/opencode .opencode .gemini .codex .OpenCode; do
38
111
  if [ -d "./$dir/gsd-local-patches" ]; then
39
112
  PATCHES_DIR="./$dir/gsd-local-patches"
40
113
  break
@@ -54,7 +127,43 @@ after modifying any GSD workflow, command, or agent files.
54
127
  ```
55
128
  Exit.
56
129
 
57
- ## Step 2: Show patch summary
130
+ ## Step 2: Determine baseline for three-way comparison
131
+
132
+ The quality of the merge depends on having a **pristine baseline** — the original unmodified version of each file from the pre-update GSD release. This enables three-way comparison:
133
+ - **Pristine baseline** (original GSD file before any user edits)
134
+ - **User's version** (backed up in `gsd-local-patches/`)
135
+ - **New version** (freshly installed after update)
136
+
137
+ Check for baseline sources in priority order:
138
+
139
+ ### Option A: Git history (most reliable)
140
+ If the config directory is a git repository:
141
+ ```bash
142
+ CONFIG_DIR=$(dirname "$PATCHES_DIR")
143
+ if git -C "$CONFIG_DIR" rev-parse --git-dir >/dev/null 2>&1; then
144
+ HAS_GIT=true
145
+ fi
146
+ ```
147
+ When `HAS_GIT=true`, use `git log` to find the commit where GSD was originally installed (before user edits). For each file, the pristine baseline can be extracted with:
148
+ ```bash
149
+ git -C "$CONFIG_DIR" log --diff-filter=A --format="%H" -- "{file_path}"
150
+ ```
151
+ This gives the commit that first added the file (the install commit). Extract the pristine version:
152
+ ```bash
153
+ git -C "$CONFIG_DIR" show {install_commit}:{file_path}
154
+ ```
155
+
156
+ ### Option B: Pristine snapshot directory
157
+ Check if a `gsd-pristine/` directory exists alongside `gsd-local-patches/`:
158
+ ```bash
159
+ PRISTINE_DIR="$CONFIG_DIR/gsd-pristine"
160
+ ```
161
+ If it exists, the installer saved pristine copies at install time. Use these as the baseline.
162
+
163
+ ### Option C: No baseline available (two-way fallback)
164
+ If neither git history nor pristine snapshots are available, fall back to two-way comparison — but with **strengthened heuristics** (see Step 3).
165
+
166
+ ## Step 3: Show patch summary
58
167
 
59
168
  ```
60
169
  ## Local Patches to Reapply
@@ -62,6 +171,7 @@ Exit.
62
171
  **Backed up from:** v{from_version}
63
172
  **Current version:** {read VERSION file}
64
173
  **Files modified:** {count}
174
+ **Merge strategy:** {three-way (git) | three-way (pristine) | two-way (enhanced)}
65
175
 
66
176
  | # | File | Status |
67
177
  |---|------|--------|
@@ -69,37 +179,57 @@ Exit.
69
179
  | 2 | {file_path} | Pending |
70
180
  ```
71
181
 
72
- ## Step 3: Merge each file
182
+ ## Step 4: Merge each file
73
183
 
74
184
  For each file in `backup-meta.json`:
75
185
 
76
186
  1. **read the backed-up version** (user's modified copy from `gsd-local-patches/`)
77
187
  2. **read the newly installed version** (current file after update)
78
- 3. **Compare and merge:**
188
+ 3. **If available, read the pristine baseline** (from git history or `gsd-pristine/`)
79
189
 
80
- - If the new file is identical to the backed-up file: skip (modification was incorporated upstream)
81
- - If the new file differs: identify the user's modifications and apply them to the new version
190
+ ### Three-way merge (when baseline is available)
82
191
 
83
- **Merge strategy:**
84
- - read both versions fully
85
- - Identify sections the user added or modified (look for additions, not just differences from path replacement)
86
- - Apply user's additions/modifications to the new version
87
- - If a section the user modified was also changed upstream: flag as conflict, show both versions, ask user which to keep
192
+ Compare the three versions to isolate changes:
193
+ - **User changes** = diff(pristine → user's version) — these are the customizations to preserve
194
+ - **Upstream changes** = diff(pristine new version) these are version updates to accept
88
195
 
89
- 4. **write merged result** to the installed location
90
- 5. **Report status:**
91
- - `Merged` user modifications applied cleanly
92
- - `Skipped` modification already in upstream
93
- - `Conflict` user chose resolution
196
+ **Merge rules:**
197
+ - Sections changed only by user → apply user's version
198
+ - Sections changed only by upstream → accept upstream version
199
+ - Sections changed by both flag as CONFLICT, show both, ask user
200
+ - Sections unchanged by either → use new version (identical to all three)
94
201
 
95
- ## Step 4: Update manifest
202
+ ### Two-way merge (fallback when no baseline)
96
203
 
97
- After reapplying, regenerate the file manifest so future updates correctly detect these as user modifications:
204
+ When no pristine baseline is available, use these **strengthened heuristics**:
98
205
 
206
+ **CRITICAL RULE: Every file in this backup directory was explicitly detected as modified by the installer's SHA-256 hash comparison. "No custom content" is never a valid conclusion.**
207
+
208
+ For each file:
209
+ a. read both versions completely
210
+ b. Identify ALL differences, then classify each as:
211
+ - **Mechanical drift** — path substitutions (e.g. `/Users/xxx/.OpenCode/` → `$HOME/.OpenCode/`), variable additions (`${GSD_WS}`, `${AGENT_SKILLS_*}`), error handling additions (`|| true`)
212
+ - **User customization** — added steps/sections, removed sections, reordered content, changed behavior, added frontmatter fields, modified instructions
213
+
214
+ c. **If ANY differences remain after filtering out mechanical drift → those are user customizations. Merge them.**
215
+ d. **If ALL differences appear to be mechanical drift → still flag as CONFLICT.** The installer's hash check already proved this file was modified. Ask the user: "This file appears to only have path/variable differences. Were there intentional customizations?" Do NOT silently skip.
216
+
217
+ ### Git-enhanced two-way merge
218
+
219
+ When the config directory is a git repo but the pristine install commit can't be found, use commit history to identify user changes:
99
220
  ```bash
100
- # The manifest will be regenerated on next /gsd-update
101
- # For now, just note which files were modified
221
+ # Find non-update commits that touched this file
222
+ git -C "$CONFIG_DIR" log --oneline --no-merges -- "{file_path}" | grep -v "gsd:update\|GSD update\|gsd-install"
102
223
  ```
224
+ Each matching commit represents an intentional user modification. Use the commit messages and diffs to understand what was changed and why.
225
+
226
+ 4. **write merged result** to the installed location
227
+ 5. **Report status per file:**
228
+ - `Merged` — user modifications applied cleanly (show summary of what was preserved)
229
+ - `Conflict` — user reviewed and chose resolution
230
+ - `Incorporated` — user's modification was already adopted upstream (only valid when pristine baseline confirms this)
231
+
232
+ **Never report `Skipped — no custom content`.** If a file is in the backup, it has custom content.
103
233
 
104
234
  ## Step 5: Cleanup option
105
235
 
@@ -112,11 +242,11 @@ Ask user:
112
242
  ```
113
243
  ## Patches Reapplied
114
244
 
115
- | # | File | Status |
116
- |---|------|--------|
117
- | 1 | {file_path} | Merged |
118
- | 2 | {file_path} | Skipped (already upstream) |
119
- | 3 | {file_path} | Conflict resolved |
245
+ | # | File | Result | User Changes Preserved |
246
+ |---|------|--------|----------------------|
247
+ | 1 | {file_path} | Merged | Added step X, modified section Y |
248
+ | 2 | {file_path} | Incorporated | Already in upstream v{version} |
249
+ | 3 | {file_path} | Conflict resolved | User chose: keep custom section |
120
250
 
121
251
  {count} file(s) updated. Your local modifications are active again.
122
252
  ```
@@ -124,8 +254,10 @@ Ask user:
124
254
  </process>
125
255
 
126
256
  <success_criteria>
127
- - [ ] All backed-up patches processed
128
- - [ ] User modifications merged into new version
129
- - [ ] Conflicts resolved with user input
130
- - [ ] Status reported for each file
257
+ - [ ] All backed-up patches processed — zero files left unhandled
258
+ - [ ] No file classified as "no custom content" or "SKIP" — every backed-up file is definitionally modified
259
+ - [ ] Three-way merge used when pristine baseline available (git history or gsd-pristine/)
260
+ - [ ] User modifications identified and merged into new version
261
+ - [ ] Conflicts surfaced to user with both versions shown
262
+ - [ ] Status reported for each file with summary of what was preserved
131
263
  </success_criteria>
@@ -140,12 +140,7 @@ write to: .planning/phases/${PHASE}-{slug}/${PHASE}-RESEARCH.md
140
140
  ```
141
141
 
142
142
  ```
143
- task(
144
- prompt=filled_prompt,
145
- subagent_type="gsd-phase-researcher",
146
- model="{researcher_model}",
147
- description="Research Phase {phase}"
148
- )
143
+ @gsd-phase-researcher filled_prompt
149
144
  ```
150
145
 
151
146
  ## 5. Handle Agent Return
@@ -176,12 +171,7 @@ Continue research for Phase {phase_number}: {phase_name}
176
171
  ```
177
172
 
178
173
  ```
179
- task(
180
- prompt=continuation_prompt,
181
- subagent_type="gsd-phase-researcher",
182
- model="{researcher_model}",
183
- description="Continue research Phase {phase}"
184
- )
174
+ @gsd-phase-researcher continuation_prompt
185
175
  ```
186
176
 
187
177
  </process>
@@ -5,6 +5,7 @@ permissions:
5
5
  read: true
6
6
  write: true
7
7
  bash: true
8
+ question: true
8
9
  ---
9
10
 
10
11
  <objective>
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: gsd-review
3
3
  description: Request cross-AI peer review of phase plans from external AI CLIs
4
- argument-hint: "--phase N [--gemini] [--OpenCode] [--codex] [--all]"
4
+ argument-hint: "--phase N [--gemini] [--OpenCode] [--codex] [--opencode] [--all]"
5
5
  permissions:
6
6
  read: true
7
7
  write: true
@@ -11,7 +11,7 @@ permissions:
11
11
  ---
12
12
 
13
13
  <objective>
14
- Invoke external AI CLIs (Gemini, OpenCode, Codex) to independently review phase plans.
14
+ Invoke external AI CLIs (Gemini, OpenCode, Codex, OpenCode) to independently review phase plans.
15
15
  Produces a structured REVIEWS.md with per-reviewer feedback that can be fed back into
16
16
  planning via /gsd-plan-phase --reviews.
17
17
 
@@ -29,6 +29,7 @@ Phase number: extracted from $ARGUMENTS (required)
29
29
  - `--gemini` — Include Gemini CLI review
30
30
  - `--OpenCode` — Include OpenCode CLI review (uses separate session)
31
31
  - `--codex` — Include Codex CLI review
32
+ - `--opencode` — Include OpenCode review (uses model from user's OpenCode config)
32
33
  - `--all` — Include all available CLIs
33
34
  </context>
34
35
 
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: gsd-secure-phase
3
+ description: Retroactively verify threat mitigations for a completed phase
4
+ argument-hint: "[phase number]"
5
+ permissions:
6
+ read: true
7
+ write: true
8
+ edit: true
9
+ bash: true
10
+ glob: true
11
+ grep: true
12
+ task: true
13
+ question: true
14
+ ---
15
+ <objective>
16
+ Verify threat mitigations for a completed phase. Three states:
17
+ - (A) SECURITY.md exists — audit and verify mitigations
18
+ - (B) No SECURITY.md, PLAN.md with threat model exists — run from artifacts
19
+ - (C) Phase not executed — exit with guidance
20
+
21
+ Output: updated SECURITY.md.
22
+ </objective>
23
+
24
+ <execution_context>
25
+ @$HOME/.config/opencode/get-shit-done/workflows/secure-phase.md
26
+ </execution_context>
27
+
28
+ <context>
29
+ Phase: $ARGUMENTS — optional, defaults to last completed phase.
30
+ </context>
31
+
32
+ <process>
33
+ Execute @$HOME/.config/opencode/get-shit-done/workflows/secure-phase.md.
34
+ Preserve all workflow gates.
35
+ </process>
@@ -2,7 +2,6 @@
2
2
  name: gsd-set-profile
3
3
  description: Switch model profile for GSD agents (simple/smart/genius/inherit)
4
4
  argument-hint: <profile (simple|smart|genius|inherit)>
5
- model: haiku
6
5
  permissions:
7
6
  bash: true
8
7
  ---
@@ -62,7 +62,7 @@ Create a new thread:
62
62
 
63
63
  1. Generate slug from description:
64
64
  ```bash
65
- SLUG=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" generate-slug "$ARGUMENTS")
65
+ SLUG=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" generate-slug "$ARGUMENTS" --raw)
66
66
  ```
67
67
 
68
68
  2. Create the threads directory if needed:
@@ -1,12 +1,15 @@
1
1
  ---
2
2
  name: gsd-workstreams
3
3
  description: Manage parallel workstreams — list, create, switch, status, progress, complete, and resume
4
+ permissions:
5
+ read: true
6
+ bash: true
4
7
  ---
5
8
 
6
9
  # /gsd-workstreams
7
10
 
8
11
  <objective>
9
- Manage parallel workstreams for concurrent milestone work.
12
+ Manage parallel workstreams for concurrent milestone work.
10
13
  </objective>
11
14
 
12
15
  ## Usage
@@ -47,7 +50,9 @@ Display detailed phase breakdown and state information.
47
50
 
48
51
  ### switch
49
52
  Run: `node "$GSD_TOOLS" workstream set <name> --raw --cwd "$CWD"`
50
- Also set `GSD_WORKSTREAM` env var for the current session.
53
+ Also set `GSD_WORKSTREAM` for the current session when the runtime supports it.
54
+ If the runtime exposes a session identifier, GSD also stores the active workstream
55
+ session-locally so concurrent sessions do not overwrite each other.
51
56
 
52
57
  ### progress
53
58
  Run: `node "$GSD_TOOLS" workstream progress --raw --cwd "$CWD"`
@@ -93,6 +93,7 @@
93
93
  * verify commits <h1> [h2] ... Batch verify commit hashes
94
94
  * verify artifacts <plan-file> Check must_haves.artifacts
95
95
  * verify key-links <plan-file> Check must_haves.key_links
96
+ * verify schema-drift <phase> [--skip] Detect schema file changes without push
96
97
  *
97
98
  * Template Fill:
98
99
  * template fill summary --phase N Create pre-filled SUMMARY.md
@@ -133,6 +134,9 @@
133
134
  * init milestone-op All context for milestone operations
134
135
  * init map-codebase All context for map-codebase workflow
135
136
  * init progress All context for progress workflow
137
+ *
138
+ * Documentation:
139
+ * docs-init Project context for docs-update workflow
136
140
  */
137
141
 
138
142
  const fs = require('fs');
@@ -152,6 +156,7 @@ const frontmatter = require('./lib/frontmatter.cjs');
152
156
  const profilePipeline = require('./lib/profile-pipeline.cjs');
153
157
  const profileOutput = require('./lib/profile-output.cjs');
154
158
  const workstream = require('./lib/workstream.cjs');
159
+ const docs = require('./lib/docs.cjs');
155
160
 
156
161
  // ─── Arg parsing helpers ──────────────────────────────────────────────────────
157
162
 
@@ -230,7 +235,7 @@ async function main() {
230
235
  }
231
236
 
232
237
  // Optional workstream override for parallel milestone work.
233
- // Priority: --ws flag > GSD_WORKSTREAM env var > active-workstream file > null (flat mode)
238
+ // Priority: --ws flag > GSD_WORKSTREAM env var > session-scoped pointer > shared legacy pointer > null
234
239
  const wsEqArg = args.find(arg => arg.startsWith('--ws='));
235
240
  const wsIdx = args.indexOf('--ws');
236
241
  let ws = null;
@@ -274,7 +279,7 @@ async function main() {
274
279
  const command = args[0];
275
280
 
276
281
  if (!command) {
277
- error('Usage: gsd-tools <command> [args] [--raw] [--pick <field>] [--cwd <path>] [--ws <name>]\nCommands: state, resolve-model, find-phase, commit, verify-summary, verify, frontmatter, template, generate-slug, current-timestamp, list-todos, verify-path-exists, config-ensure-section, config-new-project, init, workstream');
282
+ error('Usage: gsd-tools <command> [args] [--raw] [--pick <field>] [--cwd <path>] [--ws <name>]\nCommands: state, resolve-model, find-phase, commit, verify-summary, verify, frontmatter, template, generate-slug, current-timestamp, list-todos, verify-path-exists, config-ensure-section, config-new-project, init, workstream, docs-init');
278
283
  }
279
284
 
280
285
  // Multi-repo guard: resolve project root for commands that read/write .planning/.
@@ -394,6 +399,14 @@ async function runCommand(command, args, cwd, raw) {
394
399
  state.cmdSignalWaiting(cwd, type, question, options, p, raw);
395
400
  } else if (subcommand === 'signal-resume') {
396
401
  state.cmdSignalResume(cwd, raw);
402
+ } else if (subcommand === 'planned-phase') {
403
+ const { phase: p, name, plans } = parseNamedArgs(args, ['phase', 'name', 'plans']);
404
+ state.cmdStatePlannedPhase(cwd, p, plans !== null ? parseInt(plans, 10) : null, raw);
405
+ } else if (subcommand === 'validate') {
406
+ state.cmdStateValidate(cwd, raw);
407
+ } else if (subcommand === 'sync') {
408
+ const { verify } = parseNamedArgs(args, [], ['verify']);
409
+ state.cmdStateSync(cwd, { verify }, raw);
397
410
  } else {
398
411
  state.cmdStateLoad(cwd, raw);
399
412
  }
@@ -425,6 +438,11 @@ async function runCommand(command, args, cwd, raw) {
425
438
  break;
426
439
  }
427
440
 
441
+ case 'check-commit': {
442
+ commands.cmdCheckCommit(cwd, raw);
443
+ break;
444
+ }
445
+
428
446
  case 'commit-to-subrepo': {
429
447
  const message = args[1];
430
448
  const filesIndex = args.indexOf('--files');
@@ -498,8 +516,11 @@ async function runCommand(command, args, cwd, raw) {
498
516
  verify.cmdVerifyArtifacts(cwd, args[2], raw);
499
517
  } else if (subcommand === 'key-links') {
500
518
  verify.cmdVerifyKeyLinks(cwd, args[2], raw);
519
+ } else if (subcommand === 'schema-drift') {
520
+ const skipFlag = args.includes('--skip');
521
+ verify.cmdVerifySchemaDrift(cwd, args[2], skipFlag, raw);
501
522
  } else {
502
- error('Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links');
523
+ error('Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links, schema-drift');
503
524
  }
504
525
  break;
505
526
  }
@@ -570,8 +591,10 @@ async function runCommand(command, args, cwd, raw) {
570
591
  includeArchived: args.includes('--include-archived'),
571
592
  };
572
593
  phase.cmdPhasesList(cwd, options, raw);
594
+ } else if (subcommand === 'clear') {
595
+ milestone.cmdPhasesClear(cwd, raw);
573
596
  } else {
574
- error('Unknown phases subcommand. Available: list');
597
+ error('Unknown phases subcommand. Available: list, clear');
575
598
  }
576
599
  break;
577
600
  }
@@ -712,12 +735,16 @@ async function runCommand(command, args, cwd, raw) {
712
735
  case 'init': {
713
736
  const workflow = args[1];
714
737
  switch (workflow) {
715
- case 'execute-phase':
716
- init.cmdInitExecutePhase(cwd, args[2], raw);
738
+ case 'execute-phase': {
739
+ const { validate: epValidate } = parseNamedArgs(args, [], ['validate']);
740
+ init.cmdInitExecutePhase(cwd, args[2], raw, { validate: epValidate });
717
741
  break;
718
- case 'plan-phase':
719
- init.cmdInitPlanPhase(cwd, args[2], raw);
742
+ }
743
+ case 'plan-phase': {
744
+ const { validate: ppValidate } = parseNamedArgs(args, [], ['validate']);
745
+ init.cmdInitPlanPhase(cwd, args[2], raw, { validate: ppValidate });
720
746
  break;
747
+ }
721
748
  case 'new-project':
722
749
  init.cmdInitNewProject(cwd, raw);
723
750
  break;
@@ -910,6 +937,13 @@ async function runCommand(command, args, cwd, raw) {
910
937
  break;
911
938
  }
912
939
 
940
+ // ─── Documentation ────────────────────────────────────────────────────
941
+
942
+ case 'docs-init': {
943
+ docs.cmdDocsInit(cwd, raw);
944
+ break;
945
+ }
946
+
913
947
  default:
914
948
  error(`Unknown command: ${command}`);
915
949
  }