gsd-code-first 1.0.3 → 1.1.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.
- package/agents/gsd-arc-executor.md +1 -1
- package/agents/gsd-arc-planner.md +1 -1
- package/agents/gsd-reviewer.md +299 -0
- package/agents/gsd-tester.md +261 -0
- package/bin/install.js +4 -5
- package/commands/gsd/add-tests.md +20 -0
- package/commands/gsd/iterate.md +4 -3
- package/commands/gsd/prototype.md +293 -24
- package/commands/gsd/review-code.md +249 -0
- package/get-shit-done/bin/gsd-tools.cjs +13 -0
- package/get-shit-done/bin/lib/test-detector.cjs +61 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd:prototype
|
|
3
|
-
description:
|
|
4
|
-
argument-hint: "[path] [--phases N]"
|
|
3
|
+
description: PRD-driven prototype pipeline — ingests PRD, extracts acceptance criteria, confirms with user, then spawns gsd-prototyper to build annotated code scaffold with @gsd-todo(ref:AC-N) tags. Supports --prd for explicit PRD path, --interactive for step-by-step mode, and --non-interactive for CI pipelines.
|
|
4
|
+
argument-hint: "[path] [--phases N] [--prd <path>] [--interactive] [--non-interactive]"
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Write
|
|
@@ -10,16 +10,27 @@ allowed-tools:
|
|
|
10
10
|
- Task
|
|
11
11
|
- Glob
|
|
12
12
|
- Grep
|
|
13
|
+
- AskUserQuestion
|
|
13
14
|
---
|
|
14
15
|
|
|
15
16
|
<objective>
|
|
16
|
-
Spawns the `gsd-prototyper` agent to build working prototype code with `@gsd-tags` embedded following the ARC annotation standard.
|
|
17
|
+
Spawns the `gsd-prototyper` agent to build working prototype code with `@gsd-tags` embedded following the ARC annotation standard. Before spawning the agent, this command ingests a PRD (Product Requirements Document), extracts acceptance criteria semantically, presents them to the user for confirmation, and enriches the gsd-prototyper Task() prompt with the confirmed AC list so each acceptance criterion becomes a `@gsd-todo(ref:AC-N)` tag in the prototype code.
|
|
18
|
+
|
|
19
|
+
On completion, automatically runs `extract-tags` to produce `.planning/prototype/CODE-INVENTORY.md`.
|
|
17
20
|
|
|
18
21
|
**Arguments:**
|
|
19
22
|
- `path` — target directory for prototype output (defaults to project root if omitted)
|
|
20
23
|
- `--phases N` — scope the prototype to specific phase numbers from ROADMAP.md (e.g., `--phases 2` or `--phases 2,3`); only requirements belonging to those phases will be prototyped
|
|
24
|
+
- `--prd <path>` — explicit path to a PRD file; takes priority over auto-detection
|
|
25
|
+
- `--interactive` — pause after each iteration in the autonomous loop to show progress and ask whether to continue
|
|
26
|
+
- `--non-interactive` — skip the AC confirmation gate and auto-approve (for CI/headless pipelines)
|
|
27
|
+
|
|
28
|
+
**PRD resolution priority chain:**
|
|
29
|
+
1. `--prd <path>` flag — use the specified file
|
|
30
|
+
2. Auto-detect `.planning/PRD.md` — use if present
|
|
31
|
+
3. Paste prompt — ask user to paste PRD content via AskUserQuestion
|
|
21
32
|
|
|
22
|
-
|
|
33
|
+
**Key guarantee:** Each acceptance criterion from the PRD becomes exactly one `@gsd-todo(ref:AC-N)` tag in the prototype code, enabling the extract-tags completeness check.
|
|
23
34
|
</objective>
|
|
24
35
|
|
|
25
36
|
<context>
|
|
@@ -32,25 +43,283 @@ $ARGUMENTS
|
|
|
32
43
|
|
|
33
44
|
<process>
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
## Step 0: Parse flags
|
|
47
|
+
|
|
48
|
+
Check `$ARGUMENTS` for the following flags:
|
|
49
|
+
|
|
50
|
+
- **`--prd <path>`** — if present, note the path value that follows `--prd` as `prd_path`
|
|
51
|
+
- **`--interactive`** — if present, set `interactive_mode = true`
|
|
52
|
+
- **`--non-interactive`** — if present, set `non_interactive_mode = true`
|
|
53
|
+
- **`--phases N`** — if present, note the value for passing to gsd-prototyper
|
|
54
|
+
|
|
55
|
+
Log the parsed flags so the user can confirm the invocation was understood.
|
|
56
|
+
|
|
57
|
+
## Step 1: Resolve PRD content
|
|
58
|
+
|
|
59
|
+
Resolve `prd_content` using the following priority chain. All three paths produce the same `prd_content` variable for downstream processing. Log which resolution path was used.
|
|
60
|
+
|
|
61
|
+
**Priority 1 — `--prd <path>` flag is present:**
|
|
62
|
+
|
|
63
|
+
Read the file at `<path>` using the Read tool.
|
|
64
|
+
|
|
65
|
+
If the file does not exist, STOP and report:
|
|
66
|
+
> "prototype failed at step 1: PRD file not found at `<path>`. Check the path and try again."
|
|
67
|
+
|
|
68
|
+
Log: "PRD source: --prd flag (`<path>`)"
|
|
69
|
+
|
|
70
|
+
**Priority 2 — `--prd` is NOT present, check for `.planning/PRD.md`:**
|
|
71
|
+
|
|
72
|
+
Run:
|
|
73
|
+
```bash
|
|
74
|
+
test -f .planning/PRD.md && echo "exists" || echo "missing"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If the result is `"exists"`: Read `.planning/PRD.md` using the Read tool.
|
|
78
|
+
|
|
79
|
+
Log: "PRD source: auto-detected .planning/PRD.md"
|
|
80
|
+
|
|
81
|
+
**Priority 3 — neither `--prd` nor `.planning/PRD.md` is present:**
|
|
82
|
+
|
|
83
|
+
Use AskUserQuestion:
|
|
84
|
+
> "No PRD file found at `.planning/PRD.md`. You can:
|
|
85
|
+
> - Paste your full PRD content below, OR
|
|
86
|
+
> - Type `skip` to run without a PRD (backward-compatible behavior — prototype uses PROJECT.md and REQUIREMENTS.md only)
|
|
87
|
+
>
|
|
88
|
+
> Paste PRD content or type 'skip':"
|
|
89
|
+
|
|
90
|
+
If the user types `skip`: proceed directly to Step 4 without PRD context (no AC extraction, no confirmation gate, standard prototype spawn behavior).
|
|
91
|
+
|
|
92
|
+
If the user pastes content: use that as `prd_content`. If the content is longer than 5000 characters, confirm: "Received N characters of PRD content. Proceeding to acceptance criteria extraction."
|
|
93
|
+
|
|
94
|
+
Log: "PRD source: pasted content"
|
|
95
|
+
|
|
96
|
+
## Step 2: Extract acceptance criteria
|
|
97
|
+
|
|
98
|
+
**Skip this step if the user typed `skip` in Step 1.**
|
|
99
|
+
|
|
100
|
+
Using the PRD content obtained in Step 1, extract all acceptance criteria semantically. Apply the following extraction prompt to `prd_content`:
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
Extract all acceptance criteria, requirements, and success conditions from the following PRD.
|
|
105
|
+
Output format — one per line:
|
|
106
|
+
AC-1: [description in imperative form]
|
|
107
|
+
AC-2: [description in imperative form]
|
|
108
|
+
...
|
|
109
|
+
|
|
110
|
+
Rules:
|
|
111
|
+
- Include ACs from prose paragraphs, bullet lists, tables, and user stories
|
|
112
|
+
- Normalize user stories to acceptance criteria form ("User can..." → "Users can...")
|
|
113
|
+
- If the PRD has explicit numbered/labeled ACs, preserve their intent but renumber sequentially
|
|
114
|
+
- If no explicit ACs exist, infer them from goals and scope sections
|
|
115
|
+
- Output ONLY the numbered list — no headers, no commentary
|
|
116
|
+
|
|
117
|
+
PRD content:
|
|
118
|
+
[prd_content]
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
Store the resulting numbered list as `ac_list`. Count the total: `ac_count = N`.
|
|
123
|
+
|
|
124
|
+
## Step 3: Confirmation gate
|
|
125
|
+
|
|
126
|
+
**Skip this step if the user typed `skip` in Step 1.**
|
|
127
|
+
|
|
128
|
+
Check if `--non-interactive` is present in `$ARGUMENTS`.
|
|
129
|
+
|
|
130
|
+
**If `--non-interactive` IS present:**
|
|
131
|
+
|
|
132
|
+
Log: "Auto-approving N acceptance criteria (--non-interactive mode)." and proceed to Step 4.
|
|
133
|
+
|
|
134
|
+
**If `--non-interactive` is NOT present:**
|
|
135
|
+
|
|
136
|
+
Display the numbered AC list to the user clearly:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Found N acceptance criteria from PRD:
|
|
140
|
+
|
|
141
|
+
AC-1: [description]
|
|
142
|
+
AC-2: [description]
|
|
143
|
+
...
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Then use AskUserQuestion:
|
|
147
|
+
> "Found N acceptance criteria from PRD. Review the list above. Proceed with prototype generation? [yes / provide corrections]"
|
|
148
|
+
|
|
149
|
+
- If the user says `yes`, `y`, or `approve`: proceed to Step 4.
|
|
150
|
+
- If the user provides corrections or changes: incorporate the corrections into `ac_list`, re-display the updated list, and repeat the confirmation question (loop back to the start of this step with the updated list). Continue until the user approves.
|
|
151
|
+
|
|
152
|
+
**IMPORTANT:** There is NO code path that reaches Step 4 without explicit approval or `--non-interactive`. The confirmation gate is mandatory.
|
|
153
|
+
|
|
154
|
+
## Step 4: Spawn gsd-prototyper (first pass)
|
|
155
|
+
|
|
156
|
+
Spawn the `gsd-prototyper` agent via the Task tool.
|
|
157
|
+
|
|
158
|
+
**If PRD was provided (user did NOT type `skip`):**
|
|
159
|
+
|
|
160
|
+
Pass the following enriched context in the Task() prompt:
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
$ARGUMENTS
|
|
164
|
+
|
|
165
|
+
**Acceptance criteria to implement as @gsd-todo tags:**
|
|
166
|
+
[paste ac_list here — the full numbered list from Step 2/3]
|
|
167
|
+
|
|
168
|
+
For each acceptance criterion listed above, create exactly one @gsd-todo tag with `ref:AC-N` metadata in the prototype code where N is the criterion number. The tag must appear on a dedicated comment line (not trailing).
|
|
169
|
+
|
|
170
|
+
Example:
|
|
171
|
+
// @gsd-todo(ref:AC-1) User can run /gsd:prototype with PRD auto-detection at .planning/PRD.md
|
|
172
|
+
// @gsd-todo(ref:AC-3, priority:high) User is prompted to paste PRD content if no file is found
|
|
173
|
+
|
|
174
|
+
The @gsd-todo(ref:AC-N) tags are the primary completeness tracking mechanism. Every AC in the list above must have exactly one corresponding tag in the prototype code.
|
|
175
|
+
|
|
176
|
+
The agent will also:
|
|
177
|
+
- Read `get-shit-done/references/arc-standard.md` for the ARC tag standard
|
|
178
|
+
- Read `PROJECT.md`, `REQUIREMENTS.md`, and `ROADMAP.md` for project context and requirement IDs
|
|
179
|
+
- If `--phases N` is present in the arguments, filter to only requirements for those phases
|
|
180
|
+
- Plan and create prototype files with `@gsd-tags` embedded in comments
|
|
181
|
+
- Write `.planning/prototype/PROTOTYPE-LOG.md` capturing files created, decisions made, and open todos
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**If PRD was skipped (user typed `skip`):**
|
|
185
|
+
|
|
186
|
+
Pass only `$ARGUMENTS` as context (standard prototype spawn behavior):
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
$ARGUMENTS
|
|
190
|
+
|
|
191
|
+
The agent will:
|
|
192
|
+
- Read `get-shit-done/references/arc-standard.md` for the ARC tag standard
|
|
193
|
+
- Read `PROJECT.md`, `REQUIREMENTS.md`, and `ROADMAP.md` for project context and requirement IDs
|
|
194
|
+
- If `--phases N` is present in the arguments, filter to only requirements for those phases
|
|
195
|
+
- Plan and create prototype files with `@gsd-tags` embedded in comments
|
|
196
|
+
- Write `.planning/prototype/PROTOTYPE-LOG.md` capturing files created, decisions made, and open todos
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Wait for gsd-prototyper to complete and note its summary output (files created, total tags embedded, breakdown by tag type).
|
|
200
|
+
|
|
201
|
+
## Step 5: Run extract-tags
|
|
202
|
+
|
|
203
|
+
Auto-run extract-tags to produce CODE-INVENTORY.md from the annotated prototype:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" extract-tags --format md --output .planning/prototype/CODE-INVENTORY.md
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
This scans all prototype files for `@gsd-tags` and writes `.planning/prototype/CODE-INVENTORY.md` grouped by tag type and file, with summary statistics and a phase reference index.
|
|
210
|
+
|
|
211
|
+
**If PRD was provided (user did NOT type `skip`):**
|
|
212
|
+
|
|
213
|
+
Count AC-linked todos:
|
|
214
|
+
```bash
|
|
215
|
+
grep -c "ref:AC-" .planning/prototype/CODE-INVENTORY.md 2>/dev/null || echo "0"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Log: "AC todos remaining: N" (where N is the grep count).
|
|
219
|
+
|
|
220
|
+
If N is 0 and `ac_count > 0`, warn: "Warning: no AC-linked @gsd-todo tags found in CODE-INVENTORY.md. The prototype may not have implemented the accepted AC list. Check that gsd-prototyper received the AC list and used `ref:AC-N` metadata in @gsd-todo tags."
|
|
221
|
+
|
|
222
|
+
**If PRD was skipped:**
|
|
223
|
+
|
|
224
|
+
Log: "No PRD-linked todos to track."
|
|
225
|
+
|
|
226
|
+
**Show the user the results:**
|
|
227
|
+
- Files created (from gsd-prototyper summary)
|
|
228
|
+
- Total @gsd-tags embedded (from gsd-prototyper summary)
|
|
229
|
+
- AC todos remaining (if PRD was provided): N of ac_count
|
|
230
|
+
- Path to PROTOTYPE-LOG.md: `.planning/prototype/PROTOTYPE-LOG.md`
|
|
231
|
+
- Path to CODE-INVENTORY.md: `.planning/prototype/CODE-INVENTORY.md`
|
|
232
|
+
|
|
233
|
+
## Step 6 — Autonomous iteration loop
|
|
234
|
+
|
|
235
|
+
**Skip this step entirely if no PRD was provided** (user typed 'skip' in Step 1). In that case, proceed directly to Step 7.
|
|
236
|
+
|
|
237
|
+
Initialize iteration counter: `ITERATION=0`
|
|
238
|
+
Maximum iterations: 5 (hard cap per D-05)
|
|
239
|
+
|
|
240
|
+
**Loop start:**
|
|
241
|
+
|
|
242
|
+
Check the AC_REMAINING count from Step 5 (or from the previous iteration's recount).
|
|
243
|
+
|
|
244
|
+
**If AC_REMAINING is 0:** Log "All PRD acceptance criteria resolved after [ITERATION] iteration(s)." and proceed to Step 7.
|
|
245
|
+
|
|
246
|
+
**If ITERATION equals 5:** Log "Hard iteration cap (5) reached. [AC_REMAINING] AC-linked todos remain unresolved." and proceed to Step 7.
|
|
247
|
+
|
|
248
|
+
**Otherwise, run one iteration:**
|
|
249
|
+
|
|
250
|
+
**6a.** Increment ITERATION counter.
|
|
251
|
+
|
|
252
|
+
**6b.** Log: "--- Iteration [ITERATION]/5 --- ([AC_REMAINING] AC todos remaining)"
|
|
253
|
+
|
|
254
|
+
**6c. Spawn gsd-code-planner** via Task tool:
|
|
255
|
+
- Pass `.planning/prototype/CODE-INVENTORY.md` as primary input
|
|
256
|
+
- The code-planner reads `@gsd-todo` tags as the task backlog
|
|
257
|
+
- Wait for plan to be produced in `.planning/prototype/`
|
|
258
|
+
|
|
259
|
+
**6d. Auto-approve the inner plan.** Log: "Auto-approving iteration plan (autonomous prototype mode)."
|
|
260
|
+
Do NOT use AskUserQuestion here — the outer confirmation gate (Step 3) already captured user intent. Inner plans are always auto-approved per research recommendation.
|
|
261
|
+
|
|
262
|
+
**6e. Spawn executor** based on ARC mode:
|
|
263
|
+
```bash
|
|
264
|
+
ARC_ENABLED=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get arc.enabled 2>/dev/null || echo "true")
|
|
265
|
+
```
|
|
266
|
+
- If ARC_ENABLED is "true": spawn `gsd-arc-executor` via Task tool
|
|
267
|
+
- If ARC_ENABLED is "false": spawn `gsd-executor` via Task tool
|
|
268
|
+
- Pass the plan path from `.planning/prototype/` as context
|
|
269
|
+
- Wait for executor to complete
|
|
270
|
+
|
|
271
|
+
**6f. Re-run extract-tags** to refresh CODE-INVENTORY.md:
|
|
272
|
+
```bash
|
|
273
|
+
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" extract-tags --format md --output .planning/prototype/CODE-INVENTORY.md
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**6g. Recount AC-linked todos:**
|
|
277
|
+
```bash
|
|
278
|
+
AC_REMAINING=$(grep -c "ref:AC-" .planning/prototype/CODE-INVENTORY.md 2>/dev/null || echo "0")
|
|
279
|
+
```
|
|
280
|
+
Log: "AC todos remaining after iteration [ITERATION]: [AC_REMAINING]"
|
|
281
|
+
|
|
282
|
+
**6h. --interactive pause point** (per D-10, implements PRD-06):
|
|
283
|
+
Check if `--interactive` is present in `$ARGUMENTS`.
|
|
284
|
+
|
|
285
|
+
**If --interactive IS present:**
|
|
286
|
+
Display iteration summary to the user:
|
|
287
|
+
- "Iteration [ITERATION] complete."
|
|
288
|
+
- "Files changed this iteration: [list from executor summary]"
|
|
289
|
+
- "@gsd-todo count remaining: [AC_REMAINING]"
|
|
290
|
+
- "Iterations remaining: [5 - ITERATION]"
|
|
291
|
+
|
|
292
|
+
Then use AskUserQuestion: "Continue to next iteration? [yes / stop / redirect: instructions]"
|
|
293
|
+
- If `yes`, `y`, or `continue`: loop back to Loop start
|
|
294
|
+
- If `stop`: Log "Stopping at user request." and proceed to Step 7
|
|
295
|
+
- If `redirect: <instructions>`: incorporate user instructions into the next iteration's code-planner context, then loop back
|
|
296
|
+
|
|
297
|
+
**If --interactive is NOT present:** loop back to Loop start silently (per D-11, fully autonomous).
|
|
298
|
+
|
|
299
|
+
**Loop end** (reached via AC_REMAINING=0, hard cap, or user stop in --interactive mode).
|
|
300
|
+
|
|
301
|
+
## Step 7 — Final report
|
|
302
|
+
|
|
303
|
+
Display completion summary to the user:
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
prototype complete.
|
|
307
|
+
|
|
308
|
+
PRD source: [--prd flag | auto-detected .planning/PRD.md | pasted content | none]
|
|
309
|
+
Acceptance criteria: [total ACs found] total, [resolved] resolved, [AC_REMAINING] remaining
|
|
310
|
+
Iterations used: [ITERATION] of 5 maximum
|
|
311
|
+
Executor: [gsd-arc-executor | gsd-executor]
|
|
312
|
+
|
|
313
|
+
Artifacts:
|
|
314
|
+
- Prototype log: .planning/prototype/PROTOTYPE-LOG.md
|
|
315
|
+
- Code inventory: .planning/prototype/CODE-INVENTORY.md
|
|
316
|
+
- Iteration plans: .planning/prototype/*.md
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**If AC_REMAINING > 0:**
|
|
320
|
+
```
|
|
321
|
+
Note: [AC_REMAINING] acceptance criteria remain as @gsd-todo tags.
|
|
322
|
+
Run /gsd:iterate to continue implementation, or /gsd:prototype --interactive to step through remaining items.
|
|
323
|
+
```
|
|
55
324
|
|
|
56
325
|
</process>
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd:review-code
|
|
3
|
+
description: Two-stage prototype code review -- spec compliance check (Stage 1) then code quality evaluation (Stage 2). Runs test suite, spawns gsd-reviewer, writes REVIEW-CODE.md with actionable next steps.
|
|
4
|
+
argument-hint: "[--non-interactive]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Bash
|
|
9
|
+
- Task
|
|
10
|
+
- Glob
|
|
11
|
+
- Grep
|
|
12
|
+
- AskUserQuestion
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<objective>
|
|
16
|
+
Orchestrates a two-stage code review of the current prototype: Stage 1 checks spec compliance (do the PRD acceptance criteria pass?), Stage 2 checks code quality (security, maintainability, error handling, edge cases). Stage 2 only runs if Stage 1 passes.
|
|
17
|
+
|
|
18
|
+
This command:
|
|
19
|
+
1. Detects the test framework and runs the test suite, capturing results
|
|
20
|
+
2. Resolves the acceptance criteria list from CODE-INVENTORY.md, PRD.md, or REQUIREMENTS.md
|
|
21
|
+
3. Spawns the gsd-reviewer agent with all context it needs (test results + AC list + gate instructions)
|
|
22
|
+
4. Reads the resulting REVIEW-CODE.md and presents a formatted summary to the user
|
|
23
|
+
5. Suggests the next action based on Stage 1 result
|
|
24
|
+
|
|
25
|
+
The agent (gsd-reviewer) writes `.planning/prototype/REVIEW-CODE.md`. This command orchestrates and presents results.
|
|
26
|
+
|
|
27
|
+
**Arguments:**
|
|
28
|
+
- `--non-interactive` — skip the final AskUserQuestion prompt (for CI/headless pipelines); still runs full review and writes REVIEW-CODE.md
|
|
29
|
+
</objective>
|
|
30
|
+
|
|
31
|
+
<context>
|
|
32
|
+
$ARGUMENTS
|
|
33
|
+
|
|
34
|
+
@.planning/PROJECT.md
|
|
35
|
+
@.planning/REQUIREMENTS.md
|
|
36
|
+
</context>
|
|
37
|
+
|
|
38
|
+
<process>
|
|
39
|
+
|
|
40
|
+
## Step 0: Parse flags
|
|
41
|
+
|
|
42
|
+
Check `$ARGUMENTS` for the following flags:
|
|
43
|
+
|
|
44
|
+
- **`--non-interactive`** -- if present, set `non_interactive_mode = true`
|
|
45
|
+
|
|
46
|
+
Log the parsed flags so the user can confirm the invocation was understood.
|
|
47
|
+
|
|
48
|
+
## Step 1: Detect test framework and run tests
|
|
49
|
+
|
|
50
|
+
Detect the test framework using Phase 7 infrastructure:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
TEST_INFO=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" detect-test-framework "$PWD")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This returns JSON: `{ "framework": "vitest", "testCommand": "npx vitest run", "filePattern": "**/*.test.{ts,js}" }`.
|
|
57
|
+
|
|
58
|
+
Extract `framework` and `testCommand` from the JSON output:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
FRAMEWORK=$(echo "$TEST_INFO" | node -e "const d=require('fs').readFileSync('/dev/stdin','utf8');console.log(JSON.parse(d).framework)")
|
|
62
|
+
TEST_COMMAND=$(echo "$TEST_INFO" | node -e "const d=require('fs').readFileSync('/dev/stdin','utf8');console.log(JSON.parse(d).testCommand)")
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Run the test suite and capture the full output including exit code:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
TEST_OUTPUT=$(eval "$TEST_COMMAND" 2>&1) || true
|
|
69
|
+
TEST_EXIT=$?
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Log: "Test framework: {FRAMEWORK} | Command: {TEST_COMMAND} | Exit code: {TEST_EXIT}"
|
|
73
|
+
|
|
74
|
+
**Handle the no-tests-found case (Pitfall 4):**
|
|
75
|
+
|
|
76
|
+
After running, check the output for "no test files" / "no tests found" / "found 0 test files" / "no tests matching" patterns:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
echo "$TEST_OUTPUT" | grep -qi "no test\|no tests\|0 test files\|no spec files\|nothing to run" && TESTS_FOUND=false || TESTS_FOUND=true
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If `TESTS_FOUND=false`:
|
|
83
|
+
- Log: "No test files found. Review will proceed without test results. Absence will be noted in REVIEW-CODE.md."
|
|
84
|
+
- Set `tests_run=0`, `tests_passed=0`, `tests_failed=0`
|
|
85
|
+
- Do NOT report "0 tests passed" as a test failure -- absence of tests is distinct from failing tests.
|
|
86
|
+
|
|
87
|
+
If `TESTS_FOUND=true`:
|
|
88
|
+
- Log full test output summary (first 50 lines + last 20 lines if output is long)
|
|
89
|
+
|
|
90
|
+
## Step 2: Resolve AC list for Stage 1
|
|
91
|
+
|
|
92
|
+
Determine the acceptance criteria for Stage 1 spec compliance. Use this resolution priority chain:
|
|
93
|
+
|
|
94
|
+
**Priority 1 -- CODE-INVENTORY.md has AC-linked tags:**
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
AC_COUNT=$(grep -c "ref:AC-" .planning/prototype/CODE-INVENTORY.md 2>/dev/null || echo "0")
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If `AC_COUNT > 0`:
|
|
101
|
+
- Extract AC list from CODE-INVENTORY.md:
|
|
102
|
+
```bash
|
|
103
|
+
grep "ref:AC-" .planning/prototype/CODE-INVENTORY.md | grep -oP "ref:AC-\d+" | sort -u
|
|
104
|
+
```
|
|
105
|
+
- Read `.planning/prototype/CODE-INVENTORY.md` using the Read tool to get full AC descriptions from the @gsd-todo tags
|
|
106
|
+
- Log: "AC source: CODE-INVENTORY.md ({AC_COUNT} AC-linked tags found)"
|
|
107
|
+
- Set `SPEC_AVAILABLE=true`, `AC_SOURCE=code-inventory`
|
|
108
|
+
|
|
109
|
+
**Priority 2 -- PRD.md exists:**
|
|
110
|
+
|
|
111
|
+
If `AC_COUNT` is 0, check for PRD:
|
|
112
|
+
```bash
|
|
113
|
+
test -f .planning/PRD.md && echo "exists" || echo "missing"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
If exists:
|
|
117
|
+
- Read `.planning/PRD.md` using the Read tool
|
|
118
|
+
- Extract ACs using the same semantic extraction as prototype.md Step 2:
|
|
119
|
+
|
|
120
|
+
Extract all acceptance criteria, requirements, and success conditions from the PRD.
|
|
121
|
+
Output format -- one per line:
|
|
122
|
+
AC-1: [description in imperative form]
|
|
123
|
+
AC-2: [description in imperative form]
|
|
124
|
+
|
|
125
|
+
Rules:
|
|
126
|
+
- Include ACs from prose paragraphs, bullet lists, tables, and user stories
|
|
127
|
+
- Normalize user stories to acceptance criteria form
|
|
128
|
+
- If no explicit ACs, infer from goals and scope sections
|
|
129
|
+
- Output ONLY the numbered list -- no headers, no commentary
|
|
130
|
+
|
|
131
|
+
- Log: "AC source: .planning/PRD.md (re-extracted {N} ACs)"
|
|
132
|
+
- Set `SPEC_AVAILABLE=true`, `AC_SOURCE=prd`
|
|
133
|
+
|
|
134
|
+
**Priority 3 -- REQUIREMENTS.md exists:**
|
|
135
|
+
|
|
136
|
+
If no PRD, check REQUIREMENTS.md:
|
|
137
|
+
- Read `.planning/REQUIREMENTS.md` using the Read tool
|
|
138
|
+
- Extract requirements as AC substitutes -- use requirement IDs and descriptions as the AC list
|
|
139
|
+
- Log: "AC source: .planning/REQUIREMENTS.md (using requirements as AC substitutes)"
|
|
140
|
+
- Set `SPEC_AVAILABLE=true`, `AC_SOURCE=requirements`
|
|
141
|
+
|
|
142
|
+
**Priority 4 -- No spec available:**
|
|
143
|
+
|
|
144
|
+
If none of the above:
|
|
145
|
+
- Log: "No spec file found -- spec compliance check (Stage 1) will be skipped. Review will run Stage 2 only."
|
|
146
|
+
- Set `SPEC_AVAILABLE=false`
|
|
147
|
+
|
|
148
|
+
## Step 3: Spawn gsd-reviewer
|
|
149
|
+
|
|
150
|
+
Build the Task() prompt with ALL context gsd-reviewer needs. The prompt must include:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
**Test execution results:**
|
|
154
|
+
Framework: {FRAMEWORK}
|
|
155
|
+
Command run: {TEST_COMMAND}
|
|
156
|
+
Exit code: {TEST_EXIT}
|
|
157
|
+
Tests found: {TESTS_FOUND}
|
|
158
|
+
Output:
|
|
159
|
+
{TEST_OUTPUT}
|
|
160
|
+
|
|
161
|
+
**Acceptance criteria for Stage 1 check ({AC_COUNT} total):**
|
|
162
|
+
{AC_LIST -- one per line, format: AC-N: description}
|
|
163
|
+
|
|
164
|
+
**Stage 1 instruction:**
|
|
165
|
+
For each AC listed above, check whether the code and/or tests satisfy it. Find concrete evidence (file path, line number, or code snippet). If ALL ACs are satisfied, set stage1_result=PASS and proceed to Stage 2 code quality evaluation. If ANY AC is not satisfied, set stage1_result=FAIL, list the failing ACs with reason, and do NOT perform Stage 2.
|
|
166
|
+
|
|
167
|
+
Note: One failing AC is enough to fail Stage 1. There is no threshold -- ALL ACs must pass.
|
|
168
|
+
|
|
169
|
+
**If SPEC_AVAILABLE=false:**
|
|
170
|
+
No spec file (PRD or REQUIREMENTS.md) was found. Skip Stage 1 entirely. Run Stage 2 code quality evaluation only. Note in REVIEW-CODE.md: "Spec compliance check skipped -- no PRD or requirements file found."
|
|
171
|
+
|
|
172
|
+
**Prototype artifact paths:**
|
|
173
|
+
- Code inventory: .planning/prototype/CODE-INVENTORY.md
|
|
174
|
+
- Prototype log: .planning/prototype/PROTOTYPE-LOG.md
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Spawn gsd-reviewer via the Task tool with the prompt above. Wait for the agent to complete -- it will write `.planning/prototype/REVIEW-CODE.md` before returning.
|
|
178
|
+
|
|
179
|
+
## Step 4: Read review results
|
|
180
|
+
|
|
181
|
+
After the Task() call returns, read the review output:
|
|
182
|
+
|
|
183
|
+
Read `.planning/prototype/REVIEW-CODE.md` using the Read tool.
|
|
184
|
+
|
|
185
|
+
Parse the YAML frontmatter to extract:
|
|
186
|
+
- `stage1_result` (PASS / FAIL)
|
|
187
|
+
- `stage2_result` (PASS / FAIL / SKIPPED)
|
|
188
|
+
- `test_framework`, `tests_run`, `tests_passed`, `tests_failed`
|
|
189
|
+
- `ac_total`, `ac_passed`, `ac_failed`
|
|
190
|
+
- `next_steps` array (id, file, severity, action)
|
|
191
|
+
|
|
192
|
+
If REVIEW-CODE.md does not exist after the Task() call, log: "Warning: gsd-reviewer did not produce REVIEW-CODE.md. Check agent output above for errors."
|
|
193
|
+
|
|
194
|
+
## Step 5: Present results to user
|
|
195
|
+
|
|
196
|
+
**If `non_interactive_mode = true`:** Log the summary below and exit without AskUserQuestion.
|
|
197
|
+
|
|
198
|
+
**Otherwise:** Use AskUserQuestion to present a formatted summary and ask the user what to do next.
|
|
199
|
+
|
|
200
|
+
Format the summary as:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
Review complete.
|
|
204
|
+
|
|
205
|
+
--- Stage 1: Spec Compliance ---
|
|
206
|
+
Result: {PASS / FAIL}
|
|
207
|
+
ACs checked: {ac_total} | Passed: {ac_passed} | Failed: {ac_failed}
|
|
208
|
+
{If FAIL: list failing ACs by ID}
|
|
209
|
+
|
|
210
|
+
--- Stage 2: Code Quality ---
|
|
211
|
+
Result: {PASS / FAIL / SKIPPED}
|
|
212
|
+
{If SKIPPED: "Skipped -- Stage 1 failures must be resolved first"}
|
|
213
|
+
|
|
214
|
+
--- Test Results ---
|
|
215
|
+
Framework: {test_framework}
|
|
216
|
+
Tests run: {tests_run} | Passed: {tests_passed} | Failed: {tests_failed}
|
|
217
|
+
{If no tests found: "No test files detected -- test coverage is absent (@gsd-risk noted in REVIEW-CODE.md)"}
|
|
218
|
+
|
|
219
|
+
--- Top Next Steps ---
|
|
220
|
+
{List up to 5 next steps from REVIEW-CODE.md: # | File | Severity | Action}
|
|
221
|
+
|
|
222
|
+
Full review: .planning/prototype/REVIEW-CODE.md
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Then ask:
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
How would you like to proceed?
|
|
229
|
+
|
|
230
|
+
Options:
|
|
231
|
+
- "fix" or "iterate" -- run /gsd:iterate to address the next steps
|
|
232
|
+
- "details" -- I'll show you the full REVIEW-CODE.md content
|
|
233
|
+
- "done" -- accept results and continue
|
|
234
|
+
- "rerun" -- re-run the review after you've made manual changes
|
|
235
|
+
|
|
236
|
+
What's your next step?
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**If Stage 1 passed:** suggest `/gsd:iterate` for improvements or proceed to manual verification steps from REVIEW-CODE.md.
|
|
240
|
+
|
|
241
|
+
**If Stage 1 failed:** recommend fixing the failing ACs first ("Resolve failing ACs before addressing code quality issues") before re-running `/gsd:review-code`.
|
|
242
|
+
|
|
243
|
+
Handle the user's response:
|
|
244
|
+
- "fix", "iterate", or similar: remind user to run `/gsd:iterate` with the REVIEW-CODE.md path for context
|
|
245
|
+
- "details": Read and display the full REVIEW-CODE.md content
|
|
246
|
+
- "done" or any other response: confirm review is complete and exit
|
|
247
|
+
- "rerun": remind user to make their changes first, then re-run `/gsd:review-code`
|
|
248
|
+
|
|
249
|
+
</process>
|
|
@@ -133,6 +133,11 @@
|
|
|
133
133
|
* init milestone-op All context for milestone operations
|
|
134
134
|
* init map-codebase All context for map-codebase workflow
|
|
135
135
|
* init progress All context for progress workflow
|
|
136
|
+
*
|
|
137
|
+
* Test Detection:
|
|
138
|
+
* detect-test-framework [dir] Detect test framework from package.json
|
|
139
|
+
* Outputs: { framework, testCommand, filePattern }
|
|
140
|
+
* Defaults to cwd if dir not provided
|
|
136
141
|
*/
|
|
137
142
|
|
|
138
143
|
const fs = require('fs');
|
|
@@ -942,6 +947,14 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
942
947
|
break;
|
|
943
948
|
}
|
|
944
949
|
|
|
950
|
+
case 'detect-test-framework': {
|
|
951
|
+
const targetDir = args[1] || cwd;
|
|
952
|
+
const testDetector = require('./lib/test-detector.cjs');
|
|
953
|
+
const result = testDetector.detectTestFramework(targetDir);
|
|
954
|
+
core.output(result, raw, `${result.framework}: ${result.testCommand}`);
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
957
|
+
|
|
945
958
|
default:
|
|
946
959
|
error(`Unknown command: ${command}`);
|
|
947
960
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* test-detector.cjs — Test framework auto-detection
|
|
5
|
+
*
|
|
6
|
+
* Reads a project's package.json to determine which test framework is in use.
|
|
7
|
+
* Returns deterministic results with zero external dependencies.
|
|
8
|
+
*
|
|
9
|
+
* @gsd-api detectTestFramework(projectRoot: string)
|
|
10
|
+
* Returns: { framework: string, testCommand: string, filePattern: string }
|
|
11
|
+
* Reads target project's package.json to detect test framework.
|
|
12
|
+
* Falls back to node:test when package.json is absent, invalid, or unrecognized.
|
|
13
|
+
* Detection priority: vitest > jest > mocha > ava > node:test (--test flag) > node:test (fallback)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Detect the test framework used by the project at projectRoot.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} projectRoot - Absolute path to the target project root
|
|
23
|
+
* @returns {{ framework: string, testCommand: string, filePattern: string }}
|
|
24
|
+
*/
|
|
25
|
+
function detectTestFramework(projectRoot) {
|
|
26
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
27
|
+
|
|
28
|
+
if (!fs.existsSync(pkgPath)) {
|
|
29
|
+
return { framework: 'node:test', testCommand: 'node --test', filePattern: '**/*.test.cjs' };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let pkg;
|
|
33
|
+
try {
|
|
34
|
+
pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
35
|
+
} catch {
|
|
36
|
+
return { framework: 'node:test', testCommand: 'node --test', filePattern: '**/*.test.cjs' };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
40
|
+
const testScript = (pkg.scripts && pkg.scripts.test) || '';
|
|
41
|
+
|
|
42
|
+
if (deps.vitest || testScript.includes('vitest')) {
|
|
43
|
+
return { framework: 'vitest', testCommand: 'npx vitest run', filePattern: '**/*.test.{ts,js}' };
|
|
44
|
+
}
|
|
45
|
+
if (deps.jest || testScript.includes('jest')) {
|
|
46
|
+
return { framework: 'jest', testCommand: 'npx jest', filePattern: '**/*.test.{ts,js}' };
|
|
47
|
+
}
|
|
48
|
+
if (deps.mocha || testScript.includes('mocha')) {
|
|
49
|
+
return { framework: 'mocha', testCommand: 'npx mocha', filePattern: '**/*.test.{mjs,cjs,js}' };
|
|
50
|
+
}
|
|
51
|
+
if (deps.ava || testScript.includes('ava')) {
|
|
52
|
+
return { framework: 'ava', testCommand: 'npx ava', filePattern: '**/*.test.{mjs,js}' };
|
|
53
|
+
}
|
|
54
|
+
if (testScript.includes('--test')) {
|
|
55
|
+
return { framework: 'node:test', testCommand: 'node --test', filePattern: '**/*.test.cjs' };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { framework: 'node:test', testCommand: 'node --test', filePattern: '**/*.test.cjs' };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = { detectTestFramework };
|