superpowers-mcp 6.0.3 → 6.2.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.
- package/README.ja.md +15 -2
- package/README.ko.md +15 -2
- package/README.md +21 -2
- package/README.zh-TW.md +22 -3
- package/out/server.js +1 -1
- package/package.json +1 -1
- package/skills/brainstorming/SKILL.md +1 -9
- package/skills/brainstorming/scripts/stop-server.ps1 +11 -3
- package/skills/brainstorming/visual-companion.md +7 -0
- package/skills/dispatching-parallel-agents/SKILL.md +0 -18
- package/skills/executing-plans/SKILL.md +6 -12
- package/skills/finishing-a-development-branch/SKILL.md +64 -105
- package/skills/receiving-code-review/SKILL.md +0 -8
- package/skills/requesting-code-review/SKILL.md +6 -14
- package/skills/subagent-driven-development/SKILL.md +314 -228
- package/skills/subagent-driven-development/implementer-prompt.md +6 -3
- package/skills/subagent-driven-development/re-review-prompt.md +106 -0
- package/skills/subagent-driven-development/scripts/review-package +11 -9
- package/skills/subagent-driven-development/scripts/review-package.ps1 +17 -10
- package/skills/subagent-driven-development/scripts/sdd-workspace +26 -8
- package/skills/subagent-driven-development/scripts/sdd-workspace.ps1 +29 -4
- package/skills/subagent-driven-development/scripts/task-brief +4 -3
- package/skills/subagent-driven-development/scripts/task-brief.ps1 +5 -4
- package/skills/subagent-driven-development/task-reviewer-prompt.md +3 -5
- package/skills/systematic-debugging/SKILL.md +1 -14
- package/skills/systematic-debugging/find-polluter.ps1 +20 -4
- package/skills/test-driven-development/SKILL.md +10 -61
- package/skills/test-driven-development/writing-good-tests.md +198 -0
- package/skills/using-git-worktrees/SKILL.md +9 -44
- package/skills/using-superpowers/references/antigravity-tools.md +1 -1
- package/skills/using-superpowers/references/codex-tools.md +1 -1
- package/skills/using-superpowers/references/gemini-tools.md +44 -32
- package/skills/verification-before-completion/SKILL.md +0 -19
- package/skills/writing-plans/SKILL.md +0 -6
- package/skills/writing-skills/SKILL.md +1 -11
- package/skills/test-driven-development/testing-anti-patterns.md +0 -299
- package/skills/using-superpowers/references/copilot-tools.md +0 -42
|
@@ -106,9 +106,12 @@ Subagent (general-purpose):
|
|
|
106
106
|
|
|
107
107
|
## After Review Findings
|
|
108
108
|
|
|
109
|
-
If
|
|
110
|
-
the
|
|
111
|
-
|
|
109
|
+
If the task review finds issues, you will be resumed with the findings.
|
|
110
|
+
Fix them, re-run the tests that cover the amended code, and append a fix
|
|
111
|
+
report to your report file: what you changed, the covering tests you
|
|
112
|
+
ran, the command, and the output. Reviewers will not re-run tests for
|
|
113
|
+
you — your report is the test evidence. Then reply with the same short
|
|
114
|
+
status contract as your first report.
|
|
112
115
|
|
|
113
116
|
## Report Format
|
|
114
117
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Scoped Re-Review Prompt Template
|
|
2
|
+
|
|
3
|
+
Use this template when dispatching a re-review after a fix round. The
|
|
4
|
+
re-reviewer verifies the findings were addressed and checks the fix diff for
|
|
5
|
+
new breakage. It is not a fresh review — the full review already happened.
|
|
6
|
+
|
|
7
|
+
**Purpose:** Verify each finding from the previous review was addressed, and
|
|
8
|
+
that the fix itself broke nothing.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Subagent (general-purpose):
|
|
12
|
+
description: "Re-review Task N fix round R"
|
|
13
|
+
model: [MODEL — REQUIRED: choose per SKILL.md Model Selection; an omitted
|
|
14
|
+
model silently inherits the session's most expensive one]
|
|
15
|
+
prompt: |
|
|
16
|
+
You are re-reviewing one task's fix round. A previous review produced
|
|
17
|
+
findings; an implementer has attempted to fix them. Your job is to
|
|
18
|
+
verdict each finding and inspect the fix diff — nothing else.
|
|
19
|
+
|
|
20
|
+
## The Task
|
|
21
|
+
|
|
22
|
+
Read the task brief: [BRIEF_FILE]
|
|
23
|
+
|
|
24
|
+
## The Findings Under Verification
|
|
25
|
+
|
|
26
|
+
[FINDINGS]
|
|
27
|
+
|
|
28
|
+
## The Fix
|
|
29
|
+
|
|
30
|
+
Read the implementer's report (fix reports are appended at the end):
|
|
31
|
+
[REPORT_FILE]
|
|
32
|
+
|
|
33
|
+
**Fix base:** [FIX_BASE_SHA] (the head the previous review saw)
|
|
34
|
+
**Head:** [HEAD_SHA]
|
|
35
|
+
**Diff file:** [DIFF_FILE]
|
|
36
|
+
|
|
37
|
+
Read the diff file once — it contains the fix commits, a stat summary,
|
|
38
|
+
and the fix diff with surrounding context. Do not re-run git commands.
|
|
39
|
+
If the diff file is missing, fetch the diff yourself:
|
|
40
|
+
`git diff --stat [FIX_BASE_SHA]..[HEAD_SHA]` and
|
|
41
|
+
`git diff [FIX_BASE_SHA]..[HEAD_SHA]`.
|
|
42
|
+
|
|
43
|
+
Your review is read-only on this checkout. Do not mutate the working
|
|
44
|
+
tree, the index, HEAD, or branch state in any way.
|
|
45
|
+
|
|
46
|
+
## Scope
|
|
47
|
+
|
|
48
|
+
Your scope is the findings list and the fix diff. Verdict every finding.
|
|
49
|
+
Inspect the fix diff for new problems the fix itself introduced. Do NOT
|
|
50
|
+
re-review code the fix did not touch: if you notice an issue entirely
|
|
51
|
+
outside the fix diff, report it under Out-of-Scope Observations — it
|
|
52
|
+
does not block this task and does not extend the loop. A broad
|
|
53
|
+
whole-branch review happens after all tasks are complete.
|
|
54
|
+
|
|
55
|
+
## Tests
|
|
56
|
+
|
|
57
|
+
The implementer re-ran the tests covering the amended code and appended
|
|
58
|
+
the results to the report file. Treat the report as unverified claims:
|
|
59
|
+
confirm the fix report names the covering tests and shows their output,
|
|
60
|
+
and verify the claims against the diff. Do not re-run the suite to
|
|
61
|
+
confirm their report. Run a test only when reading the code raises a
|
|
62
|
+
specific doubt that no existing run answers — and then a focused test,
|
|
63
|
+
never a package-wide suite.
|
|
64
|
+
|
|
65
|
+
## Output Format
|
|
66
|
+
|
|
67
|
+
Your final message is the report itself: begin directly with the first
|
|
68
|
+
finding's verdict. Every line is a verdict, a finding with file:line,
|
|
69
|
+
or a check you ran — no preamble, no process narration.
|
|
70
|
+
|
|
71
|
+
### Finding Verdicts
|
|
72
|
+
|
|
73
|
+
For each finding in The Findings Under Verification, in order:
|
|
74
|
+
- **[finding one-liner]** — ADDRESSED | NOT ADDRESSED, with file:line
|
|
75
|
+
evidence. "Attempted" is not addressed: the specific defect must no
|
|
76
|
+
longer exist.
|
|
77
|
+
|
|
78
|
+
### New Breakage in the Fix Diff
|
|
79
|
+
|
|
80
|
+
Anything the fix itself broke or introduced, with severity
|
|
81
|
+
(Critical/Important/Minor) and file:line. "None" if clean.
|
|
82
|
+
|
|
83
|
+
### Out-of-Scope Observations
|
|
84
|
+
|
|
85
|
+
Issues you noticed entirely outside the fix diff. Non-blocking; the
|
|
86
|
+
controller ledgers these for the final review. "None" if none.
|
|
87
|
+
|
|
88
|
+
### Verdict
|
|
89
|
+
|
|
90
|
+
**Fix round:** [All findings addressed, no new Critical/Important
|
|
91
|
+
breakage | Findings remain open] — list the open ones.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Placeholders:**
|
|
95
|
+
- `[MODEL]` — REQUIRED: reviewer model per SKILL.md Model Selection; scoped
|
|
96
|
+
re-reviews of small fix diffs take a cheap-to-mid tier
|
|
97
|
+
- `[BRIEF_FILE]` — the task brief file (same file the implementer worked from)
|
|
98
|
+
- `[FINDINGS]` — the Critical/Important findings and spec gaps from the
|
|
99
|
+
previous review, copied verbatim, one per bullet
|
|
100
|
+
- `[REPORT_FILE]` — the implementer's report file (fix reports appended)
|
|
101
|
+
- `[FIX_BASE_SHA]` — the head the previous review saw
|
|
102
|
+
- `[HEAD_SHA]` — current commit
|
|
103
|
+
- `[DIFF_FILE]` — the path `scripts/review-package PLAN_FILE FIX_BASE HEAD` printed
|
|
104
|
+
|
|
105
|
+
**Re-reviewer returns:** per-finding verdicts (ADDRESSED / NOT ADDRESSED),
|
|
106
|
+
new breakage in the fix diff, out-of-scope observations, and a round verdict.
|
|
@@ -4,26 +4,28 @@
|
|
|
4
4
|
# call. Using the recorded per-task BASE (not HEAD~1) keeps multi-commit
|
|
5
5
|
# tasks intact.
|
|
6
6
|
#
|
|
7
|
-
# Usage: review-package BASE HEAD [OUTFILE]
|
|
8
|
-
# Default OUTFILE: <repo-root>/.superpowers/sdd
|
|
7
|
+
# Usage: review-package PLAN_FILE BASE HEAD [OUTFILE]
|
|
8
|
+
# Default OUTFILE: <repo-root>/.superpowers/sdd/<plan-basename>/review-<base7>..<head7>.diff
|
|
9
9
|
# (named per range, so a re-review after fixes gets a distinct fresh file).
|
|
10
10
|
set -euo pipefail
|
|
11
11
|
|
|
12
|
-
if [ $# -lt
|
|
13
|
-
echo "usage: review-package BASE HEAD [OUTFILE]" >&2
|
|
12
|
+
if [ $# -lt 3 ] || [ $# -gt 4 ]; then
|
|
13
|
+
echo "usage: review-package PLAN_FILE BASE HEAD [OUTFILE]" >&2
|
|
14
14
|
exit 2
|
|
15
15
|
fi
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
plan=$1
|
|
18
|
+
base=$2
|
|
19
|
+
head=$3
|
|
20
|
+
[ -f "$plan" ] || { echo "no such plan file: $plan" >&2; exit 2; }
|
|
19
21
|
|
|
20
22
|
git rev-parse --verify --quiet "$base" >/dev/null || { echo "bad BASE: $base" >&2; exit 2; }
|
|
21
23
|
git rev-parse --verify --quiet "$head" >/dev/null || { echo "bad HEAD: $head" >&2; exit 2; }
|
|
22
24
|
|
|
23
|
-
if [ $# -eq
|
|
24
|
-
out=$
|
|
25
|
+
if [ $# -eq 4 ]; then
|
|
26
|
+
out=$4
|
|
25
27
|
else
|
|
26
|
-
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace")
|
|
28
|
+
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace" "$plan")
|
|
27
29
|
out="$dir/review-$(git rev-parse --short "$base")..$(git rev-parse --short "$head").diff"
|
|
28
30
|
fi
|
|
29
31
|
|
|
@@ -1,34 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env pwsh
|
|
2
2
|
# Generate a review package: commit list, stat summary, and net diff.
|
|
3
|
-
# Usage: ./review-package.ps1 BASE HEAD [OUTFILE]
|
|
3
|
+
# Usage: ./review-package.ps1 PLAN_FILE BASE HEAD [OUTFILE]
|
|
4
|
+
# Default OUTFILE: <repo-root>/.superpowers/sdd/<plan-basename>/review-<base7>..<head7>.diff
|
|
4
5
|
|
|
5
6
|
$ErrorActionPreference = "Stop"
|
|
6
7
|
|
|
7
|
-
if ($args.Count -lt
|
|
8
|
-
|
|
8
|
+
if ($args.Count -lt 3 -or $args.Count -gt 4) {
|
|
9
|
+
[Console]::Error.WriteLine("usage: review-package.ps1 PLAN_FILE BASE HEAD [OUTFILE]")
|
|
9
10
|
exit 2
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
$
|
|
13
|
-
$
|
|
13
|
+
$plan = $args[0]
|
|
14
|
+
$base = $args[1]
|
|
15
|
+
$head = $args[2]
|
|
16
|
+
|
|
17
|
+
if (-not (Test-Path -LiteralPath $plan -PathType Leaf)) {
|
|
18
|
+
[Console]::Error.WriteLine("no such plan file: $plan")
|
|
19
|
+
exit 2
|
|
20
|
+
}
|
|
14
21
|
|
|
15
22
|
& git rev-parse --verify --quiet $base *> $null
|
|
16
23
|
if ($LASTEXITCODE -ne 0) {
|
|
17
|
-
|
|
24
|
+
[Console]::Error.WriteLine("bad BASE: $base")
|
|
18
25
|
exit 2
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
& git rev-parse --verify --quiet $head *> $null
|
|
22
29
|
if ($LASTEXITCODE -ne 0) {
|
|
23
|
-
|
|
30
|
+
[Console]::Error.WriteLine("bad HEAD: $head")
|
|
24
31
|
exit 2
|
|
25
32
|
}
|
|
26
33
|
|
|
27
|
-
if ($args.Count -eq
|
|
28
|
-
$out = $args[
|
|
34
|
+
if ($args.Count -eq 4) {
|
|
35
|
+
$out = $args[3]
|
|
29
36
|
} else {
|
|
30
37
|
$scriptDir = Split-Path -Parent $PSCommandPath
|
|
31
|
-
$dir = (& (Join-Path $scriptDir "sdd-workspace.ps1")).Trim()
|
|
38
|
+
$dir = (& (Join-Path $scriptDir "sdd-workspace.ps1") $plan | Select-Object -First 1).Trim()
|
|
32
39
|
$baseShort = (& git rev-parse --short $base).Trim()
|
|
33
40
|
$headShort = (& git rev-parse --short $head).Trim()
|
|
34
41
|
$out = Join-Path $dir "review-$baseShort..$headShort.diff"
|
|
@@ -1,22 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Resolve and ensure the working-tree directory SDD uses for
|
|
3
|
-
# artifacts: task briefs, implementer reports, review packages,
|
|
4
|
-
# progress ledger. Print the directory's absolute path.
|
|
2
|
+
# Resolve and ensure the working-tree directory SDD uses for one plan's
|
|
3
|
+
# short-lived artifacts: task briefs, implementer reports, review packages,
|
|
4
|
+
# and the progress ledger. Print the plan directory's absolute path.
|
|
5
|
+
#
|
|
6
|
+
# One directory per plan (.superpowers/sdd/<plan-basename>/) so a follow-up
|
|
7
|
+
# plan in the same working tree can never read or overwrite another plan's
|
|
8
|
+
# artifacts. A stale ledger misread as current progress makes controllers
|
|
9
|
+
# skip whole task sequences — plan-scoping removes that failure structurally.
|
|
5
10
|
#
|
|
6
11
|
# The workspace lives in the working tree (not under .git/) because Claude Code
|
|
7
12
|
# treats .git/ as a protected path and denies agent writes there — which blocks
|
|
8
13
|
# an implementer subagent from writing its report file. A self-ignoring
|
|
9
|
-
# .gitignore
|
|
10
|
-
# commits without modifying any tracked file.
|
|
14
|
+
# .gitignore at .superpowers/sdd/ keeps every plan's workspace out of
|
|
15
|
+
# `git status` and out of accidental commits without modifying any tracked file.
|
|
11
16
|
#
|
|
12
17
|
# Single source of truth for the workspace location, so task-brief and
|
|
13
18
|
# review-package cannot drift to different directories.
|
|
14
19
|
#
|
|
15
|
-
# Usage: sdd-workspace
|
|
20
|
+
# Usage: sdd-workspace PLAN_FILE
|
|
16
21
|
set -euo pipefail
|
|
17
22
|
|
|
23
|
+
if [ $# -ne 1 ]; then
|
|
24
|
+
echo "usage: sdd-workspace PLAN_FILE" >&2
|
|
25
|
+
exit 2
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
plan=$1
|
|
29
|
+
[ -f "$plan" ] || { echo "no such plan file: $plan" >&2; exit 2; }
|
|
30
|
+
|
|
31
|
+
slug=$(basename "$plan" .md)
|
|
32
|
+
[ -n "$slug" ] && [ "$slug" != "." ] && [ "$slug" != ".." ] \
|
|
33
|
+
|| { echo "cannot derive a workspace name from: $plan" >&2; exit 2; }
|
|
34
|
+
|
|
18
35
|
root=$(git rev-parse --show-toplevel)
|
|
19
|
-
|
|
36
|
+
base="$root/.superpowers/sdd"
|
|
37
|
+
dir="$base/$slug"
|
|
20
38
|
mkdir -p "$dir"
|
|
21
|
-
printf '*\n' > "$
|
|
39
|
+
printf '*\n' > "$base/.gitignore"
|
|
22
40
|
cd "$dir" && pwd
|
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env pwsh
|
|
2
|
-
# Resolve and ensure the working-tree directory SDD uses for
|
|
3
|
-
#
|
|
2
|
+
# Resolve and ensure the working-tree directory SDD uses for one plan's
|
|
3
|
+
# short-lived artifacts: task briefs, implementer reports, review packages,
|
|
4
|
+
# and the progress ledger. Print the plan directory's absolute path.
|
|
5
|
+
#
|
|
6
|
+
# One directory per plan (.superpowers/sdd/<plan-basename>/) so a follow-up
|
|
7
|
+
# plan in the same working tree can never read or overwrite another plan's
|
|
8
|
+
# artifacts.
|
|
9
|
+
#
|
|
10
|
+
# Usage: ./sdd-workspace.ps1 PLAN_FILE
|
|
4
11
|
|
|
5
12
|
$ErrorActionPreference = "Stop"
|
|
6
13
|
|
|
14
|
+
if ($args.Count -ne 1) {
|
|
15
|
+
[Console]::Error.WriteLine("usage: sdd-workspace.ps1 PLAN_FILE")
|
|
16
|
+
exit 2
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
$plan = $args[0]
|
|
20
|
+
if (-not (Test-Path -LiteralPath $plan -PathType Leaf)) {
|
|
21
|
+
[Console]::Error.WriteLine("no such plan file: $plan")
|
|
22
|
+
exit 2
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
$slug = [System.IO.Path]::GetFileName($plan) -replace '\.md$', ''
|
|
26
|
+
if ([string]::IsNullOrEmpty($slug) -or $slug -eq "." -or $slug -eq "..") {
|
|
27
|
+
[Console]::Error.WriteLine("cannot derive a workspace name from: $plan")
|
|
28
|
+
exit 2
|
|
29
|
+
}
|
|
30
|
+
|
|
7
31
|
$root = (& git rev-parse --show-toplevel).Trim()
|
|
8
|
-
$
|
|
32
|
+
$base = Join-Path $root ".superpowers/sdd"
|
|
33
|
+
$dir = Join-Path $base $slug
|
|
9
34
|
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
10
|
-
Set-Content -Path (Join-Path $
|
|
35
|
+
Set-Content -Path (Join-Path $base ".gitignore") -Value "*" -NoNewline -Encoding ascii
|
|
11
36
|
(Resolve-Path $dir).Path
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
# through the controller's context.
|
|
5
5
|
#
|
|
6
6
|
# Usage: task-brief PLAN_FILE TASK_NUMBER [OUTFILE]
|
|
7
|
-
# Default OUTFILE: <repo-root>/.superpowers/sdd
|
|
8
|
-
# (per worktree; concurrent runs
|
|
7
|
+
# Default OUTFILE: <repo-root>/.superpowers/sdd/<plan-basename>/task-<N>-brief.md
|
|
8
|
+
# (per plan and per worktree; concurrent runs of the SAME plan in the same
|
|
9
|
+
# working tree share it).
|
|
9
10
|
set -euo pipefail
|
|
10
11
|
|
|
11
12
|
if [ $# -lt 2 ] || [ $# -gt 3 ]; then
|
|
@@ -20,7 +21,7 @@ n=$2
|
|
|
20
21
|
if [ $# -eq 3 ]; then
|
|
21
22
|
out=$3
|
|
22
23
|
else
|
|
23
|
-
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace")
|
|
24
|
+
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace" "$plan")
|
|
24
25
|
out="$dir/task-${n}-brief.md"
|
|
25
26
|
fi
|
|
26
27
|
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env pwsh
|
|
2
2
|
# Extract one task's full text from an implementation plan.
|
|
3
3
|
# Usage: ./task-brief.ps1 PLAN_FILE TASK_NUMBER [OUTFILE]
|
|
4
|
+
# Default OUTFILE: <repo-root>/.superpowers/sdd/<plan-basename>/task-<N>-brief.md
|
|
4
5
|
|
|
5
6
|
$ErrorActionPreference = "Stop"
|
|
6
7
|
|
|
7
8
|
if ($args.Count -lt 2 -or $args.Count -gt 3) {
|
|
8
|
-
|
|
9
|
+
[Console]::Error.WriteLine("usage: task-brief.ps1 PLAN_FILE TASK_NUMBER [OUTFILE]")
|
|
9
10
|
exit 2
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
$plan = $args[0]
|
|
13
14
|
$taskNumber = $args[1]
|
|
14
15
|
if (-not (Test-Path -LiteralPath $plan -PathType Leaf)) {
|
|
15
|
-
|
|
16
|
+
[Console]::Error.WriteLine("no such plan file: $plan")
|
|
16
17
|
exit 2
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -20,7 +21,7 @@ if ($args.Count -eq 3) {
|
|
|
20
21
|
$out = $args[2]
|
|
21
22
|
} else {
|
|
22
23
|
$scriptDir = Split-Path -Parent $PSCommandPath
|
|
23
|
-
$dir = (& (Join-Path $scriptDir "sdd-workspace.ps1")).Trim()
|
|
24
|
+
$dir = (& (Join-Path $scriptDir "sdd-workspace.ps1") $plan | Select-Object -First 1).Trim()
|
|
24
25
|
$out = Join-Path $dir "task-$taskNumber-brief.md"
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -43,7 +44,7 @@ foreach ($line in [System.IO.File]::ReadLines((Resolve-Path -LiteralPath $plan).
|
|
|
43
44
|
|
|
44
45
|
Set-Content -Path $out -Value $selected -Encoding utf8
|
|
45
46
|
if ((-not (Test-Path -LiteralPath $out)) -or ((Get-Item -LiteralPath $out).Length -eq 0)) {
|
|
46
|
-
|
|
47
|
+
[Console]::Error.WriteLine("task $taskNumber not found in $plan (no heading matching 'Task $taskNumber')")
|
|
47
48
|
exit 3
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -179,11 +179,9 @@ Subagent (general-purpose):
|
|
|
179
179
|
- `[BASE_SHA]` — commit before this task
|
|
180
180
|
- `[HEAD_SHA]` — current commit
|
|
181
181
|
- `[DIFF_FILE]` — REQUIRED: the path the controller wrote the review
|
|
182
|
-
package to (`scripts/review-package BASE HEAD`, or
|
|
183
|
-
|
|
182
|
+
package to (`scripts/review-package PLAN_FILE BASE HEAD`, or
|
|
183
|
+
`scripts/review-package.ps1 PLAN_FILE BASE HEAD` on Windows PowerShell,
|
|
184
|
+
prints the unique path it wrote; the package never enters the controller's context)
|
|
184
185
|
|
|
185
186
|
**Reviewer returns:** Spec Compliance verdict (✅/❌/⚠️), Strengths, Issues
|
|
186
187
|
(Critical/Important/Minor), Task quality verdict
|
|
187
|
-
|
|
188
|
-
A fix dispatch can address spec gaps and quality findings together;
|
|
189
|
-
re-review after fixes covers both verdicts.
|
|
@@ -7,8 +7,6 @@ description: Use when encountering any bug, test failure, or unexpected behavior
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Random fixes waste time and create new bugs. Quick patches mask underlying issues.
|
|
11
|
-
|
|
12
10
|
**Core principle:** ALWAYS find root cause before attempting fixes. Symptom fixes are failure.
|
|
13
11
|
|
|
14
12
|
**Violating the letter of this process is violating the spirit of debugging.**
|
|
@@ -188,6 +186,7 @@ You MUST complete each phase before proceeding to the next.
|
|
|
188
186
|
- Test passes now?
|
|
189
187
|
- No other tests broken?
|
|
190
188
|
- Issue actually resolved?
|
|
189
|
+
- Use the `superpowers:verification-before-completion` skill before claiming success
|
|
191
190
|
|
|
192
191
|
4. **If Fix Doesn't Work**
|
|
193
192
|
- STOP
|
|
@@ -282,15 +281,3 @@ These techniques are part of systematic debugging and available in this director
|
|
|
282
281
|
- **`root-cause-tracing.md`** - Trace bugs backward through call stack to find original trigger
|
|
283
282
|
- **`defense-in-depth.md`** - Add validation at multiple layers after finding root cause
|
|
284
283
|
- **`condition-based-waiting.md`** - Replace arbitrary timeouts with condition polling
|
|
285
|
-
|
|
286
|
-
**Related skills:**
|
|
287
|
-
- **superpowers:test-driven-development** - For creating failing test case (Phase 4, Step 1)
|
|
288
|
-
- **superpowers:verification-before-completion** - Verify fix worked before claiming success
|
|
289
|
-
|
|
290
|
-
## Real-World Impact
|
|
291
|
-
|
|
292
|
-
From debugging sessions:
|
|
293
|
-
- Systematic approach: 15-30 minutes to fix
|
|
294
|
-
- Random fixes approach: 2-3 hours of thrashing
|
|
295
|
-
- First-time fix rate: 95% vs 40%
|
|
296
|
-
- New bugs introduced: Near zero vs common
|
|
@@ -17,10 +17,26 @@ Write-Output "Searching for test that creates: $pollutionCheck"
|
|
|
17
17
|
Write-Output "Test pattern: $testPattern"
|
|
18
18
|
Write-Output ""
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
# Accept the pattern written with or without a leading ./ (or .\)
|
|
21
|
+
$testPattern = $testPattern -replace '^\.[/\\]', ''
|
|
22
|
+
|
|
23
|
+
# '**/' can't match zero directory levels in a -like comparison, so a
|
|
24
|
+
# pattern like src/**/*.test.ts would skip src/top.test.ts; also try the
|
|
25
|
+
# pattern with '**/' collapsed to cover files directly under the base
|
|
26
|
+
# directory.
|
|
27
|
+
$patterns = @($testPattern)
|
|
28
|
+
$collapsed = $testPattern -replace '\*\*[/\\]', ''
|
|
29
|
+
if ($collapsed -ne $testPattern) { $patterns += $collapsed }
|
|
30
|
+
|
|
31
|
+
$root = (Get-Location).Path.Replace('\', '/')
|
|
32
|
+
$testFiles = @(Get-ChildItem -Path . -File -Recurse -ErrorAction SilentlyContinue | Where-Object {
|
|
33
|
+
$full = $_.FullName.Replace('\', '/')
|
|
34
|
+
$hit = $false
|
|
35
|
+
foreach ($p in $patterns) {
|
|
36
|
+
if ($full -like "$root/$p") { $hit = $true; break }
|
|
37
|
+
}
|
|
38
|
+
$hit
|
|
39
|
+
} | Sort-Object FullName -Unique)
|
|
24
40
|
|
|
25
41
|
$total = $testFiles.Count
|
|
26
42
|
Write-Output "Found $total test files"
|
|
@@ -203,69 +203,25 @@ Next failing test for next feature.
|
|
|
203
203
|
| **Clear** | Name describes behavior | `test('test1')` |
|
|
204
204
|
| **Shows intent** | Demonstrates desired API | Obscures what code should do |
|
|
205
205
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
- Might test wrong thing
|
|
212
|
-
- Might test implementation, not behavior
|
|
213
|
-
- Might miss edge cases you forgot
|
|
214
|
-
- You never saw it catch the bug
|
|
215
|
-
|
|
216
|
-
Test-first forces you to see the test fail, proving it actually tests something.
|
|
217
|
-
|
|
218
|
-
**"I already manually tested all the edge cases"**
|
|
219
|
-
|
|
220
|
-
Manual testing is ad-hoc. You think you tested everything but:
|
|
221
|
-
- No record of what you tested
|
|
222
|
-
- Can't re-run when code changes
|
|
223
|
-
- Easy to forget cases under pressure
|
|
224
|
-
- "It worked when I tried it" ≠ comprehensive
|
|
225
|
-
|
|
226
|
-
Automated tests are systematic. They run the same way every time.
|
|
227
|
-
|
|
228
|
-
**"Deleting X hours of work is wasteful"**
|
|
229
|
-
|
|
230
|
-
Sunk cost fallacy. The time is already gone. Your choice now:
|
|
231
|
-
- Delete and rewrite with TDD (X more hours, high confidence)
|
|
232
|
-
- Keep it and add tests after (30 min, low confidence, likely bugs)
|
|
233
|
-
|
|
234
|
-
The "waste" is keeping code you can't trust. Working code without real tests is technical debt.
|
|
235
|
-
|
|
236
|
-
**"TDD is dogmatic, being pragmatic means adapting"**
|
|
237
|
-
|
|
238
|
-
TDD IS pragmatic:
|
|
239
|
-
- Finds bugs before commit (faster than debugging after)
|
|
240
|
-
- Prevents regressions (tests catch breaks immediately)
|
|
241
|
-
- Documents behavior (tests show how to use code)
|
|
242
|
-
- Enables refactoring (change freely, tests catch breaks)
|
|
243
|
-
|
|
244
|
-
"Pragmatic" shortcuts = debugging in production = slower.
|
|
245
|
-
|
|
246
|
-
**"Tests after achieve the same goals - it's spirit not ritual"**
|
|
247
|
-
|
|
248
|
-
No. Tests-after answer "What does this do?" Tests-first answer "What should this do?"
|
|
249
|
-
|
|
250
|
-
Tests-after are biased by your implementation. You test what you built, not what's required. You verify remembered edge cases, not discovered ones.
|
|
251
|
-
|
|
252
|
-
Tests-first force edge case discovery before implementing. Tests-after verify you remembered everything (you didn't).
|
|
253
|
-
|
|
254
|
-
30 minutes of tests after ≠ TDD. You get coverage, lose proof tests work.
|
|
206
|
+
When writing or changing any test, read [writing-good-tests.md](writing-good-tests.md) for the rules that keep tests honest:
|
|
207
|
+
- Name the production change that would make the test fail — before writing it
|
|
208
|
+
- Assert on real behavior, never on mock behavior
|
|
209
|
+
- Keep test-only code in test utilities, out of production classes
|
|
210
|
+
- Understand a dependency's side effects before mocking it
|
|
255
211
|
|
|
256
212
|
## Common Rationalizations
|
|
257
213
|
|
|
258
214
|
| Excuse | Reality |
|
|
259
215
|
|--------|---------|
|
|
260
216
|
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
|
|
261
|
-
| "I'll test after" | Tests
|
|
262
|
-
| "Tests after achieve same goals" | Tests-after
|
|
263
|
-
| "Already manually tested" |
|
|
264
|
-
| "Deleting X hours is wasteful" | Sunk cost fallacy. Keeping
|
|
217
|
+
| "I'll test after" | Tests written after pass immediately — which proves nothing. They may test the wrong thing, test the implementation instead of the behavior, or miss the edge case you forgot. You never watched it fail, so you never proved it can catch the bug. Test-first forces that failure. |
|
|
218
|
+
| "Tests after achieve same goals (spirit not ritual)" | Tests-after answer "what does this do?"; tests-first answer "what should this do?" Tests written after are biased by the code you already wrote — you verify the cases you remembered, not the ones you'd have discovered. Coverage without proof the tests work. |
|
|
219
|
+
| "Already manually tested" | Manual testing is ad-hoc: no record of what you covered, no way to re-run it when the code changes, easy to forget cases under pressure. "Worked when I tried it" ≠ comprehensive. Automated tests run the same way every time. |
|
|
220
|
+
| "Deleting X hours is wasteful" | Sunk cost fallacy — that time is already spent either way. The real choice: rewrite with TDD (high confidence) vs. keep it and bolt tests on after (low confidence, likely bugs). Keeping code you can't trust is the waste. |
|
|
265
221
|
| "Keep as reference, write tests first" | You'll adapt it. That's testing after. Delete means delete. |
|
|
266
222
|
| "Need to explore first" | Fine. Throw away exploration, start with TDD. |
|
|
267
223
|
| "Test hard = design unclear" | Listen to test. Hard to test = hard to use. |
|
|
268
|
-
| "TDD will slow me down" | TDD
|
|
224
|
+
| "TDD will slow me down" | TDD IS the pragmatic path: catches bugs before commit, prevents regressions, lets you refactor without fear. "Pragmatic" shortcuts mean debugging in production — slower, not faster. |
|
|
269
225
|
| "Manual test faster" | Manual doesn't prove edge cases. You'll re-test every change. |
|
|
270
226
|
| "Existing code has no tests" | You're improving it. Add tests for existing code. |
|
|
271
227
|
|
|
@@ -354,13 +310,6 @@ Bug found? Write failing test reproducing it. Follow TDD cycle. Test proves fix
|
|
|
354
310
|
|
|
355
311
|
Never fix bugs without a test.
|
|
356
312
|
|
|
357
|
-
## Testing Anti-Patterns
|
|
358
|
-
|
|
359
|
-
When adding mocks or test utilities, read [testing-anti-patterns.md](testing-anti-patterns.md) to avoid common pitfalls:
|
|
360
|
-
- Testing mock behavior instead of real behavior
|
|
361
|
-
- Adding test-only methods to production classes
|
|
362
|
-
- Mocking without understanding dependencies
|
|
363
|
-
|
|
364
313
|
## Final Rule
|
|
365
314
|
|
|
366
315
|
```
|