Commit graph

51 commits

Author SHA1 Message Date
Drew Ritter
2f5dc3b335
Merge pull request #2606 from obra/fix/2429-sdd-repo-resolution
fix(sdd): helpers act on the current directory's repo like git, with -C to override (#2429)
2026-11-02 14:01:03 -08:00
Drew Ritter
862308e2b3
Merge pull request #2605 from obra/fix/2436-task-brief-unclosed-fence
fix(sdd): task-brief refuses a brief that an unclosed code fence would run to EOF (#2436)
2026-11-02 13:50:41 -08:00
Drew Ritter
6aeac7ed95
Merge pull request #2604 from obra/fix/2459-2496-task-brief-headings
fix(sdd): task-brief finds alphanumeric task IDs and explains non-English headings (#2459, #2496)
2026-11-02 13:49:28 -08:00
Jesse Vincent
3735a50d5a fix(sdd): task-brief refuses a brief an unclosed code fence would run to EOF
task-brief ignores Task headings inside fenced code blocks by toggling a
flag on every ``` line. When a plan leaves a fence open (an edit deletes a
closing fence), the flag stays set for the rest of the file, every later
Task heading is invisible, and the requested task's brief runs to EOF.
The script then reported success: #2436 saw a 177-line task come back as
a 1159-line brief holding tasks 6 through 10, handed to an implementer as
its requirements.

The awk now notes whether a Task heading line appears inside the fence
that is still open at EOF. If one does while the requested task is being
captured, the task's end cannot be found, so task-brief deletes the
partial output and exits 4, naming the line where the fence opened. If
the open fence hides the requested heading itself, it names the fence
before the existing not-found error (exit 3), and suppresses the
"use the English word Task" hint, which would otherwise blame the
plan's English headings for what the fence did.

A fence left open that hides no Task heading changes nothing about the
brief, so it is still written, with a warning on stderr. Real plans do
this: in a corpus of 1,288 plans, refusing on any fence left open at EOF
blocked three correct briefs in two plans, each ending in a stray ``` that
hides no task. With this rule every brief in that corpus matches dev's.
An unclosed fence in a later task leaves an earlier task's brief alone.

The plan path reaches awk through the environment rather than -v, which
would interpret the backslashes of a Windows path as escapes. The fence
rule itself is unchanged, so this composes with #2304's CommonMark fence
tracking: a correct parser still cannot close a fence the author never
closed.

Claude-Session: https://claude.ai/code/session_01SHANcr4A71nzuU9et4Fnba
2026-10-23 03:38:19 +00:00
Jesse Vincent
750ba92008 fix(sdd): task-brief says when a plan's task headings are not in English
task-brief recognizes only the English word `Task` in a task heading.
writing-plans' template shows `### Task N:` but never says the word is
machine-read, so a model writing a plan in Spanish writes `## Tarea 1:`.
task-brief and task-start then report "task 1 not found in plan-es.md
(no heading matching 'Task 1')", which reads as "this plan has no task 1"
and sends the controller looking for a task that is on line 3 (#2496).

When a plan has no Task headings at all, task-brief now prints, before the
existing not-found line, that task headings must use the English word
"Task" whatever the plan's language, and lists up to five headings shaped
like tasks (`<word> <id-with-a-digit>`). A plan that has Task headings,
just not the requested one, still gets only the not-found line, so asking
for Task 9 of an eight-task plan stays quiet.

This deliberately does not accept other words. Plans commonly carry
`Phase 1`, `Chunk 2` and `Step 1` headings, and a word-agnostic rule
would turn them into tasks. Keeping the word fixed in the plans
themselves is a writing-plans wording change, which needs evals.

Claude-Session: https://claude.ai/code/session_01SHANcr4A71nzuU9et4Fnba
2026-10-23 03:38:19 +00:00
Jesse Vincent
f75c01fd9b fix(sdd): task-brief recognizes alphanumeric task IDs and matches them whole
task-brief only treated `Task` followed by digits as a task heading, and
found the requested task by splicing TASK_NUMBER into a regex followed
by `([^0-9]|$)`. Plans that number tasks by lane (`### Task A1`,
`### Task B2`) could not be extracted at all: `task-brief plan.md A1`
exits 3 "task A1 not found" (#2459). Among 1,288 distinct plans in Jesse's
own repositories, 19 plans have such headings (262 headings, IDs like A1,
M3a, F.2, W0), and none of those tasks could be briefed.

The same splice made the match a prefix match: Task 6 also took a sibling
Task 6b (#2175), Task 1 took Task 1.1 and 1.2, Task 2.1 took Task 201
because `.` is any character, and an ID like `6(` crashed awk (#2405).

A task heading is now `Task` followed by an ID made of letters and digits,
optionally dot-separated, that contains at least one digit. The digit is
what keeps `## Task Overview` or `#### Task notes` from becoming a task
boundary. awk extracts the heading's ID and compares it to TASK_NUMBER as
a whole string, so TASK_NUMBER never reaches awk as a regex.

A deeper Task heading whose ID extends the requested one with a letter or
dot is a sub-task and stays in the parent's brief, as the prefix match
happened to do before: plans in that corpus nest `#### Task 1a` under
`### Task 1`, and a Task 1 brief without its sub-tasks would lose most of
its requirements. A sub-task's own brief ends at its next sibling. Depth
alone is not the test, because plans also drift from `## Task 1` to
`### Task 2`, and those are siblings.

The heading word stays the English literal `Task`, which is what
writing-plans' template uses. Widening it to any word would turn the
`Phase 1`, `Chunk 2` and `Step 1` headings that plans commonly carry
(308, 182 and 56 of them in the same corpus) into tasks.

Claude-Session: https://claude.ai/code/session_01SHANcr4A71nzuU9et4Fnba
2026-10-23 03:38:19 +00:00
Jesse Vincent
8b0eefc87b fix(sdd): append git's own error line to the no-repo message
sdd-repo ran git with stderr discarded, so every git failure became
"must run from inside the git working tree ... run 'git init'". Where
git refuses a working tree the caller is actually inside (dubious
ownership on another owner's, FAT, network or WSL /mnt/c checkout; git
missing from PATH; the cwd inside .git), that message is false, points
at git init in an existing project, and hides the one line naming the
real fix. dev printed git's fatal, so this was a diagnostic regression.

The shared message stays, and git's first stderr line from whichever
check failed now always follows it as "git said: <line>", with no
per-case branches:

  SDD scripts must run from inside the git working tree ... then rerun.
  git said: fatal: detected dubious ownership in repository at '/r'

Tests: every no-repo assertion now requires the second line (a plain
non-repo dir gives "git said: fatal: not a git repository"), and a new
test simulates dubious ownership with git's GIT_TEST_ASSUME_DIFFERENT_OWNER
knob (no root or second uid needed; it skips if the installed git
ignores the knob).

Claude-Session: https://claude.ai/code/session_01SHANcr4A71nzuU9et4Fnba
2026-10-23 00:21:52 +00:00
Jesse Vincent
0d61007ef6 fix(sdd): act on the cwd's working tree only, drop the plan-repo fallback
sdd-repo fell back to the plan file's repository when the current
directory was outside any repository. That made the plugin-cache case
silently succeed somewhere: an agent that cd'd into the skill directory
and passed an absolute plan path got whichever checkout that path
pointed into. With the plan in the main checkout (where writing-plans
leaves it) and execution in a linked worktree, that is the #2429
wrong-worktree bug again, with exit 0. A real session (sdd-cwd-eval
sdd-A-5) took exactly this path and only landed in the right place
because its plan path happened to be the worktree's.

The SDD and executing-plans helpers now pick their repository the way
git does: the current directory's working tree, or DIR when given -C
DIR. Outside any working tree, sdd-workspace, task-brief,
review-package, task-start and task-done all stop with the shared
message and write nothing, even when the plan's absolute path is inside
a repository. sdd-repo no longer takes PLAN_FILE, since the plan has no
say.

The two "outside any repository ... uses the plan's repository" tests
and the task-start/task-done fallback tests become assertions that the
shared message comes out and nothing is written, in the cwd or the
plan's repository.

Claude-Session: https://claude.ai/code/session_01SHANcr4A71nzuU9et4Fnba
2026-10-23 00:21:52 +00:00
Jesse Vincent
de67241e0a fix(sdd): one no-repo message that puts "run from your working tree" first
sdd-repo's no-repository message told every caller to run 'git init'.
That is the right fix for a new project, but the other way to reach it
is standing in the wrong directory, such as the plugin's own skill
directory after reading "from this skill's directory" literally. There,
'git init' would turn the plugin cache into a repository and hide the
real mistake.

task-start and task-done were worse. They still read HEAD and BASE in
the bare cwd while the brief and ledger went through sdd-repo. From a
non-repo cwd with the plan in a repo that has commits, task-start wrote
the brief into the plan's repo, then printed git's fatal plus "HEAD has
no commit yet ... make an initial commit first" and exited 2. task-done
printed git's fatal. review-package in a repo with no commit said
"bad BASE: HEAD~1".

Every helper that can hit this (sdd-workspace, task-brief,
review-package, task-start, task-done) now stops with the same message
from sdd-repo, naming the current directory and offering init-and-commit
only as the new-project case:

  SDD scripts must run from inside the git working tree you're
  executing in, with at least one commit (current directory: <PWD>).
  If this is a new project, run 'git init' and make a first commit,
  then rerun.

sdd-repo gains --with-commit, which also refuses a repository whose HEAD
has no commit. review-package, task-start and task-done pass it because
they need HEAD as a BASE or a review range; sdd-workspace and task-brief
do not, so a brief can still be written right after git init.
task-start and task-done now read HEAD and BASE with git -C in the
repository sdd-repo names. Resolution is otherwise unchanged: the cwd's
repo, else the plan's, else exit 2. sdd-repo is now executable like its
siblings.

Claude-Session: https://claude.ai/code/session_01SHANcr4A71nzuU9et4Fnba
2026-10-23 00:21:52 +00:00
Jesse Vincent
614d80c29a fix(sdd): pick the scripts' repository deliberately, add -C DIR, explain a missing repo
The SDD helpers found their repository with a bare
`git rev-parse --show-toplevel` in the caller's cwd, and review-package ran
every git command there too. Three reports trace back to that one line:

- #2429: outside any repository (the skill's own directory in a 7.0
  package has no .git), sdd-workspace fed `cd` an empty path. bash 5.2
  treats that as a no-op and wrote the workspace into the cwd after
  printing git's bare fatal; Git Bash failed with "cd: null directory".
  A controller working on worktree B from worktree A had no way to name B.
- #1799: the only way to aim review-package at a worktree was a
  `cd <worktree> ; review-package ...` compound, which harnesses cannot
  allowlist because the path and BASE change on every run.
- #2242: in a greenfield directory with no repository, task-brief and
  sdd-workspace printed git's fatal and then carried on in the cwd (or
  crashed, depending on bash), review-package said "bad BASE: HEAD~1", and
  task-start printed an empty BASE with exit 0.

A new sdd-repo helper is the single place that picks the repository:
the cwd's working tree (or -C DIR's), exactly as git does. Anywhere else
it stops with exit 2 and one shared message.
sdd-workspace and review-package both use it, so they cannot disagree.
The cwd still wins over the plan's location on purpose: writing-plans
leaves the plan uncommitted in the main checkout, so an executor working
in a linked worktree passes the main checkout's plan path, and its
workspace and commits belong to the worktree. Resolving from PLAN_FILE
first (draft #2439) breaks exactly that flow: review-package then diffs
the main checkout and fails with "empty commit range".

sdd-workspace, task-brief and review-package take an optional leading
`-C DIR` that runs them as if started in DIR, as git -C does, so a caller
can name another worktree in one allowlistable command. Each script
resolves its own directory before the cd, so the documented
`bash scripts/review-package` form from the skill directory keeps
working with -C. PR #1809's version cd's first and then fails to find
sdd-workspace (exit 127) in that form.

task-start now refuses (exit 2) to print a BASE when HEAD has no commit,
instead of printing "base: HEAD" or "base: " with exit 0.

Co-authored-by: citizen204 <citizen204@users.noreply.github.com>
Claude-Session: https://claude.ai/code/session_01SHANcr4A71nzuU9et4Fnba
2026-10-23 00:21:52 +00:00
Jesse Vincent
bb3a5aa594 fix(sdd): print a Windows-readable workspace path (#2307)
On Windows, sdd-workspace printed the workspace in MSYS form
(/c/Users/... or /tmp/...). Every helper path derives from that line:
task-brief's "wrote", review-package's diff path, executing-plans'
task-start "brief:". PowerShell resolves /c/Users/x as C:\c\Users\x, so
Test-Path and Get-Content on any of them failed. That is the shell an
agent gets from Claude Code's PowerShell tool and from Copilot CLI on
Windows. Reproduced on Windows 11 from PowerShell and from Claude Code
2.1.308's PowerShell tool.

When cygpath is present (Git Bash, MSYS2, Cygwin), print the path
through `cygpath -m`, which gives C:/Users/.... PowerShell, cmd and
Claude Code's Read tool all accept that form, and so does bash, so the
sibling scripts that build file names on top of it keep working.
Elsewhere the output is unchanged.

Only the printed line changes. The plan-path markers keep pwd -P's
spelling, so workspaces created before this change, including absolute
markers for out-of-repo plans, still match their plans. PR #2369
converted root and the plan path too, which would rewrite those
absolute markers and orphan existing workspaces for out-of-repo plans.

Tests: physical_path in both suites now spells paths the way the
scripts print them, and test-sdd-workspace adds a check that PowerShell
can open the printed workspace and brief paths. That check runs on
Windows and is a no-op elsewhere. On Windows the suites failed 10 and 1
assertions before the fix, and both pass after.

Co-authored-by: hzxxxx <hhuihihiux@users.noreply.github.com>
Claude-Session: https://claude.ai/code/session_01SHANcr4A71nzuU9et4Fnba
2026-10-22 23:26:01 +00:00
Jesse Vincent
49b1db53d8 test(executing-plans): compare the brief path in the scripts' own spelling on Git Bash 2026-09-26 19:30:38 -07:00
Jesse Vincent
c88ba76bdb test(sdd-workspace): compare physical paths so the suite passes on Git Bash
On Windows, git rev-parse --show-toplevel prints C:/Users/... while
the script (and pwd) print /tmp/..., so nine assertions compared two
spellings of the same directory and failed. The script itself was
correct. Normalize the expected paths the same way the script's output
is produced.

From #2149 by @t0domanh.

Co-authored-by: t0domanh <3890425+t0domanh@users.noreply.github.com>
2026-09-26 19:28:31 -07:00
Jesse Vincent
19e54c094b
sdd-workspace: leave an existing .superpowers/sdd/.gitignore alone (#2399)
Based on #2161. Also quotes the empty CDPATH so shellcheck passes (SC1007).

Co-authored-by: aruizcu1989 <192807317+aruizcu1989@users.noreply.github.com>
2026-09-26 16:02:36 -07:00
ada-sen
907ad21ac2
fix(executing-plans): task-done no longer aborts when a passing test prints nothing (#2388)
Under `set -euo pipefail`, task-done extracted the ledger's test-result
field with:

    last=$(grep -v '^[[:space:]]*$' "$log" | tail -n 1)

When the test command passes but the log is empty or blank-only, `grep -v`
matches no lines and exits 1; pipefail propagates that through the
pipeline, and set -e aborts the assignment before the ledger line is
written. A passing task is then silently not recorded: exit 1, no stderr,
no ledger entry — indistinguishable from the failure path the guard exists
to produce.

Make the no-match case non-fatal, falling back to a literal placeholder for
the ledger field:

    last=$(grep -v '^[[:space:]]*$' "$log" | tail -n 1) || last="(no output)"

The failure guard above this line (recording nothing when the test command
itself exits non-zero) is untouched.

Fixes #2385.
2026-09-26 12:36:39 -07:00
Jesse Vincent
2b89c4c3f3
Rebuild executing-plans as a first-class inline execution mode
A cheaper execution mode alongside subagent-driven development: the
session implements every task itself under the same workspace, ledger
and stopping rules, with one fresh whole-branch review on the most
capable model at the end. Helper scripts task-start/task-done keep the
ledger and test log honest; the final fix pass re-grades findings and
fixes Critical/Important under TDD. writing-plans' handoff, SDD's
when-to-use text and two README lines change to match.
2026-09-17 17:14:38 -07:00
Jesse Vincent
6692bd289f fix(sdd): ownership markers stop same-basename plans sharing a workspace
sdd-workspace slugged workspaces by basename alone, so docs/alpha/plan.md
and docs/beta/plan.md resolved to one directory and task-brief silently
overwrote the other plan's brief — the single gitignored source of task
requirements, unrecoverable once clobbered.

Each workspace now records its owning plan in a plan-path marker
(repo-relative in-repo, absolute outside). Lookup keeps basename slugs
and existing behavior for the common case: a markerless workspace is
adopted in place (no migration break for in-flight plans), a marker
naming this plan is a match, and a marker naming a different plan
disambiguates with the plan's parent-directory name, then a counter.
Plan paths are normalized (CDPATH-guarded physical cd) so relative,
absolute, and ../ spellings of one plan share one workspace.

task-brief and review-package delegate to sdd-workspace and need no
changes. SKILL.md's workspace bullet no longer promises the exact
<plan-basename> path, since disambiguated workspaces differ.

Reported by @CRGDan; reproduction and test groundwork by @crisnahine
in PR #2120.

Fixes #2045
2026-09-17 15:51:11 -07:00
Drew Ritter
a2b2d1d5ef
Merge pull request #2134 from obra/fix/sdd-helpers-no-exec-bit
fix(sdd): invoke sdd-workspace via bash so helpers survive stripped exec bits
2026-09-17 15:48:31 -07:00
Jesse Vincent
99f9f00869 fix(sdd): reject empty or non-descendant BASE..HEAD ranges in review-package
When an SDD implementer commits to the wrong branch (#2050), the
BASE..HEAD range handed to review-package is either empty or not rooted
at BASE. Both cases previously produced a review package silently —
an empty one lets the reviewer approve "clean" work that isn't there.

Add two mechanical guards after BASE/HEAD validation, exiting 3 (vs 2
for usage errors) so callers can distinguish range problems:

- git merge-base --is-ancestor BASE HEAD, else "HEAD is not a
  descendant of BASE"
- git rev-list --count BASE..HEAD > 0, else "empty commit range"

Guard shape credits the analysis in closed PR #2082 by @stantheman0128.

Fixes #2050
2026-08-13 00:29:29 +00:00
Jesse Vincent
0be49879b1 fix(sdd): invoke sdd-workspace via bash so helpers survive stripped exec bits
Codex marketplace users hit 'Permission denied' running SDD helpers:
some extractors (Python zipfile) discard Unix mode attributes when
unpacking the package, so task-brief's and review-package's direct exec
of their sibling sdd-workspace fails. Our packaging preserves 0755
(git archive | tar -xpf, asserted by the existing packaging test) — the
bits are lost on the consumer side, which no packaging change can reach.
Invoking the sibling via "${BASH:-bash}" makes the exec bit irrelevant.

TDD: new regression case copies the helpers, chmod -x, runs task-brief
via bash — RED with the reported rc=126 Permission denied, GREEN after.

Reported in #2040 (michaelholcomb-creator). Fixes #2040.
2026-08-13 00:27:52 +00:00
Jesse Vincent
0634449ca6 fix(tests): stop the SDD skill test flaking on timing and prose case
tests/claude-code/test-subagent-driven-development.sh failed
intermittently for two independent reasons:

- Budget mismatch: the file runs 9 prompts with a 90s timeout each
  (810s worst case) inside the runner's 600s per-file ceiling, so slow
  backend days produced spurious timeouts. Raise the runner default to
  900s and fix the help text, which claimed the default was 300.
- Case-sensitive prose matching: the assert helpers grepped free-form
  model output case-sensitively, but models capitalize the skill's own
  headings — observed failures include "Do Not Trust the Report"
  missing pattern "not trust" and a structured answer missing
  "First:.*spec.*compliance". Match case-insensitively in
  assert_contains/assert_not_contains/assert_count/assert_order, widen
  two Test 5 keyword patterns to phrasings observed in real runs, and
  make assert_order dump the output on failure the way assert_contains
  already does, so the next flake is diagnosable.

Observed 3 failures across 4 runs before the change (timeout, two
distinct pattern misses); 3/3 consecutive full runs pass after it.
2026-07-19 12:04:46 -07:00
Jesse Vincent
9816a9cee2 feat(sdd): plan-scoped workspace — one .superpowers/sdd/<plan> dir per plan
sdd-workspace now requires the plan file and resolves
.superpowers/sdd/<plan-basename>/; task-brief and review-package write
into their plan's directory (review-package gains PLAN_FILE as its first
argument). Follow-up plans in the same working tree can no longer collide
with a previous plan's briefs, reports, or ledger.
2026-07-19 12:03:18 -07:00
Jesse Vincent
caf14aac66 test(sdd): wire test-sdd-workspace.sh into the runner; note git clean -fdx
The per-worktree workspace test was added but never registered in
run-skill-tests.sh, so it only ran when invoked by hand. Add it to the
fast unit-test array alongside the other pure-shell test.

Also document, in the Durable Progress section, that the ledger now
lives in git-ignored working-tree scratch, so `git clean -fdx` deletes
it — recover from `git log` if that happens.
2026-06-18 15:44:22 -07:00
Jesse Vincent
667b2c4a2e test(sdd): lock in per-worktree workspace isolation (#1780) 2026-06-18 15:44:22 -07:00
Jesse Vincent
93b8444b51 fix(sdd): write artifacts to working-tree .superpowers/sdd, not .git/ (#1780) 2026-06-18 15:44:22 -07:00
Jesse Vincent
207a12b203 feat(sdd): add sdd-workspace helper for a self-ignoring artifact dir 2026-06-18 15:44:22 -07:00
Drew Ritter
f030d6ef88 Tighten cross-platform tool references 2026-06-16 10:09:43 -07:00
Drew Ritter
d00f4ad442 fix: remove global worktree path fallback (#1476) 2026-06-16 10:09:43 -07:00
Jesse Vincent
a325106502 Address adversarial review findings
- evals/README.md, evals/CLAUDE.md: fix uv install command from
  'uv sync --dev' to 'uv sync --extra dev'. Drill's pyproject.toml
  uses [project.optional-dependencies], so --dev is a no-op for
  pytest/ruff/ty; --extra dev is the correct invocation.
- tests/claude-code/run-skill-tests.sh: drop test-requesting-code-review.sh
  from integration_tests array (file deleted earlier in this branch).
- tests/claude-code/README.md: replace test-requesting-code-review.sh
  section with test-worktree-native-preference.sh (the worktree test
  is kept; the code-review test was lifted into drill).
- docs/testing.md, CLAUDE.md: remove "Copilot CLI" from the harness
  list. evals/backends/ has claude*, codex, gemini configs but no
  copilot.yaml, so the claim was unsupported.

Adversarial review credit: reviewer #2 found four legitimate issues
(uv-sync, run-skill-tests stale ref, README stale ref via #1, and
Copilot CLI fabrication); reviewer #1 found two distinct issues
(run-skill-tests + tests/claude-code/README.md). Reviewer #2 wins
this round.
2026-06-16 10:09:43 -07:00
Jesse Vincent
315ef09ebc tests: annotate three kept bash tests with drill coverage notes
- test-worktree-native-preference.sh: drill covers PRESSURE phase only;
  RED + GREEN baselines have no drill counterpart and are kept so
  the RED-GREEN-REFACTOR validation remains rerunnable end-to-end.
- test-subagent-driven-development-integration.sh: drill covers the
  YAGNI subset (forbidden exports + reviewer-as-gate). Bash adds
  >=3 commits, >=2 subagent dispatches, TodoWrite usage, test file
  existence check, and token-budget telemetry. Kept until drill
  scenario covers those or they are retired.
- test-subagent-driven-development.sh: tests agent's ability to
  *describe* SDD (string matches against expected keywords). Drill
  scenarios test behavior, not description-recall. Kept by design.

Subagent verification recorded in commit messages of subsequent
deletions; gap analyses driving these annotations are also in the
verification subagent reports for the gating sweep.
2026-06-16 10:09:43 -07:00
Jesse Vincent
12ef68d55e tests: remove test-requesting-code-review.sh (covered by drill code-review-catches-planted-bugs)
Subagent verification: every bash assertion (skill invocation,
subagent dispatch, SQL injection flagged, credential handling
flagged, no merge approval) maps to drill verify checks. Drill is
stricter: bundles severity (Critical/Important) into the same
criteria as the finding itself (bash split severity into a separate
test). Setup parity covered (src/db.js with string concat + identity
hash, two commits).

The drill scenario header explicitly says it is the
"cross-harness, semantically-judged replacement for the bash test."
2026-06-16 10:09:43 -07:00
Jesse Vincent
ea8aad8764 tests: remove test-document-review-system.sh (covered by drill spec-reviewer-catches-planted-flaws)
Subagent verification: every bash assertion (TODO in Requirements
section flagged, "specified later" deferral flagged, Issues section
present, did-not-approve verdict) maps to drill verify.criteria
entries. Setup parity covered by setup.assertions (test-feature-design.md
exists with TODO + 'specified later' content). Drill is stricter:
asserts tool-called Agent (subagent dispatch) which the bash test
did not check.
2026-06-16 10:09:43 -07:00
Jesse Vincent
f2cbfbefeb
Release v5.1.0 (#1468)
* docs: add Codex App compatibility design spec (PRI-823)

Design for making using-git-worktrees, finishing-a-development-branch,
and subagent-driven-development skills work in the Codex App's sandboxed
worktree environment. Read-only environment detection via git-dir vs
git-common-dir comparison, ~48 lines across 4 files, zero breaking changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: address spec review feedback for PRI-823

Fix three Important issues from spec review:
- Clarify Step 1.5 placement relative to existing Steps 2/3
- Re-derive environment state at cleanup time instead of relying on
  earlier skill output
- Acknowledge pre-existing Step 5 cleanup inconsistency

Also: precise step references, exact codex-tools.md content, clearer
Integration section update instructions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: address team review feedback for PRI-823 spec

- Add commit SHA + data loss warning to handoff payload (HIGH)
- Add explicit commit step before handoff (HIGH)
- Remove misleading "mark as externally managed" from Path B
- Add executing-plans 1-line edit (was missing)
- Add branch name derivation rules
- Add conditional UI language for non-App environments
- Add sandbox fallback for permission errors
- Add STOP directive after Step 0 reporting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: clarify executing-plans in What Does NOT Change section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add cleanup guard test (#5) and sandbox fallback test (#10) to spec

Both tests address real risk scenarios:
- #5: cleanup guard bug would delete Codex App's own worktree (data loss)
- #10: Local thread sandbox fallback needs manual Codex App validation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add implementation plan for Codex App compatibility (PRI-823)

8 tasks covering: environment detection in using-git-worktrees,
Step 1.5 + cleanup guard in finishing-a-development-branch,
Integration line updates, codex-tools.md docs, automated tests,
and final verification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(codex-tools): add named agent dispatch mapping for Codex (#647)

* fix(writing-skills): correct false 'only two fields' frontmatter claim (#882)

* Replace subagent review loops with lightweight inline self-review

The subagent review loop (dispatching a fresh agent to review plans/specs)
doubled execution time (~25 min overhead) without measurably improving plan
quality. Regression testing across 5 versions (v3.6.0 through v5.0.4) with
5 trials each showed identical plan sizes, task counts, and quality scores
regardless of whether the review loop ran.

Changes:
- writing-plans: Replace subagent Plan Review Loop with inline Self-Review
  checklist (spec coverage, placeholder scan, type consistency)
- writing-plans: Add explicit "No Placeholders" section listing plan failures
  (TBD, vague descriptions, undefined references, "similar to Task N")
- brainstorming: Replace subagent Spec Review Loop with inline Spec Self-Review
  (placeholder scan, internal consistency, scope check, ambiguity check)
- Both skills now use "look at it with fresh eyes" framing

Testing: 5 trials with the new skill show self-review catches 3-5 real bugs
per run (spawn positions, API mismatches, seed bugs, grid indexing) in ~30s
instead of ~25 min. Remaining defects are comparable to the subagent approach.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Revert "Replace subagent review loops with lightweight inline self-review"

This reverts commit bf8f7572eb.

* Reapply "Replace subagent review loops with lightweight inline self-review"

This reverts commit b045fa3950.

* Add v5.0.6 release notes

* Move brainstorm server metadata to .meta/ subdirectory

Metadata files (.server-info, .events, .server.pid, .server.log,
.server-stopped) were stored in the same directory served over HTTP,
making them accessible via the /files/ route. They now live in a .meta/
subdirectory that is not web-accessible.

Also fixes a stale test assertion ("Waiting for Claude" → "Waiting for
the agent").

Reported-By: 吉田仁

* Revert "Move brainstorm server metadata to .meta/ subdirectory"

This reverts commit ab500dade6.

* Separate brainstorm server content and state into peer directories

The session directory now contains two peers: content/ (HTML served to
the browser) and state/ (events, server-info, pid, log). Previously
all files shared a single directory, making server state and user
interaction data accessible over the /files/ HTTP route.

Also fixes stale test assertion ("Waiting for Claude" → "Waiting for
the agent").

Reported-By: 吉田仁

* Fix owner-PID false positive when owner runs as different user

ownerAlive() treated EPERM (permission denied) the same as ESRCH
(process not found), causing the server to self-terminate within 60s
whenever the owner process ran as a different user. This affected WSL
(owner is a Windows process), Tailscale SSH, and any cross-user
scenario.

The fix: `return e.code === 'EPERM'` — if we get permission denied,
the process is alive; we just can't signal it.

Tested on Linux via Tailscale SSH with a root-owned grandparent PID:
- Server survives past the 60s lifecycle check (EPERM = alive)
- Server still shuts down when owner genuinely dies (ESRCH = dead)

Fixes #879

* Fix owner-PID lifecycle monitoring for cross-platform reliability

Two bugs caused the brainstorm server to self-terminate within 60s:

1. ownerAlive() treated EPERM (permission denied) as "process dead".
   When the owner PID belongs to a different user (Tailscale SSH,
   system daemons), process.kill(pid, 0) throws EPERM — but the
   process IS alive. Fixed: return e.code === 'EPERM'.

2. On WSL, the grandparent PID resolves to a short-lived subprocess
   that exits before the first 60s lifecycle check. The PID is
   genuinely dead (ESRCH), so the EPERM fix alone doesn't help.
   Fixed: validate the owner PID at server startup — if it's already
   dead, it was a bad resolution, so disable monitoring and rely on
   the 30-minute idle timeout.

This also removes the Windows/MSYS2-specific OWNER_PID="" carve-out
from start-server.sh, since the server now handles invalid PIDs
generically at startup regardless of platform.

Tested on Linux (magic-kingdom) via Tailscale SSH:
- Root-owned owner PID (EPERM): server survives ✓
- Dead owner PID at startup (WSL sim): monitoring disabled, survives ✓
- Valid owner that dies: server shuts down within 60s ✓

Fixes #879

* Release v5.0.6: inline self-review, brainstorm server restructure, owner-PID fixes

* fix: add Copilot CLI platform detection for sessionStart context injection

Copilot CLI v1.0.11 reads `additionalContext` from sessionStart hook
output, but the session-start script only emits the Claude Code-specific
nested format. Add COPILOT_CLI env var detection so Copilot CLI gets the
SDK-standard top-level `additionalContext` while Claude Code continues
getting `hookSpecificOutput`.

Based on PR #910 by @culinablaz.

* feat: add Copilot CLI tool mapping, docs, and install instructions

- Add references/copilot-tools.md with full tool equivalence table
- Add Copilot CLI to using-superpowers skill platform instructions
- Add marketplace install instructions to README
- Add changelog entry crediting @culinablaz for the hook fix

* fix(opencode): align skills path across bootstrap, runtime, and tests

The bootstrap text advertised a configDir-based skills path that didn't
match the runtime path (resolved relative to the plugin file). Tests
used yet another hardcoded path and referenced a nonexistent lib/ dir.

- Remove misleading skills path from bootstrap text; the agent should
  use the native skill tool, not read files by path
- Fix test setup to create a consistent layout matching the plugin's
  ../../skills resolution
- Export SUPERPOWERS_SKILLS_DIR from setup.sh so tests use a single
  source of truth
- Add regression test that bootstrap doesn't advertise the old path
- Remove broken cp of nonexistent lib/ directory

Fixes #847

* docs: add OpenCode path fix to release notes

* fix(opencode): inject bootstrap as user message instead of system message

Move bootstrap injection from experimental.chat.system.transform to
experimental.chat.messages.transform, prepending to the first user
message instead of adding a system message.

This avoids two issues:
- System messages repeated every turn inflate token usage (#750)
- Multiple system messages break Qwen and other models (#894)

Tested on OpenCode 1.3.2 with Claude Sonnet 4.5 — brainstorming skill
fires correctly on "Let's make a React to do list" prompt.

* docs: update release notes with OpenCode bootstrap change

* docs: add worktree rototill design spec (PRI-974)

Design for detect-and-defer worktree support. Superpowers defers to
native harness worktree systems when available, falls back to manual
git worktree creation when not. Covers Phases 0-2: detection, consent,
native tool preference, finishing state detection, and three bug fixes
(#940, #999, #238).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: address SWE review feedback on worktree rototill spec

- Fix Bug #999 order: merge → verify → remove worktree → delete branch
  (avoids losing work if merge fails after worktree removal)
- Add submodule guard to Step 0 detection (GIT_DIR != GIT_COMMON is also
  true in submodules)
- Preserve global path (~/.config/superpowers/worktrees/) in detection for
  backward compatibility, just stop offering it to new users
- Add step numbering note and implementation notes section
- Expand provenance heuristic to cover global path and manual creation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: honest spec revisions after issue/PR deep dive

- Step 1a is the load-bearing assumption, not just a risk — if it fails,
  the entire design needs rework. TDD validation must be first impl task.
- #1009 resolution depends on Step 1a working, stated explicitly
- #574 honestly deferred, not "partially addressed"
- Add hooks symlink to Step 1b (PR #965 idea, prevents silent hook loss)
- Add stale worktree pruning to Step 5 (PR #1072 idea, one-line self-heal)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add worktree rototill implementation plan (PRI-974)

5 tasks: TDD gate for Step 1a, using-git-worktrees rewrite,
finishing-a-development-branch rewrite, integration updates,
end-to-end validation. Task 1 is a hard gate — if native tool
preference fails RED/GREEN, stop and redesign.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add RED/GREEN validation for native worktree preference (PRI-974)

Gate test for Step 1a — validates agents prefer EnterWorktree over
git worktree add on Claude Code. Must pass before skill rewrite.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: rewrite using-git-worktrees with detect-and-defer (PRI-974)

Step 0: GIT_DIR != GIT_COMMON detection (skip if already isolated)
Step 0 consent: opt-in prompt before creating worktree (#991)
Step 1a: native tool preference (short, first, declarative)
Step 1b: git worktree fallback with hooks symlink and legacy path compat
Submodule guard prevents false detection
Platform-neutral instruction file references (#1049)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: rewrite finishing-a-development-branch with detect-and-defer (PRI-974)

Step 2: environment detection (GIT_DIR != GIT_COMMON) before presenting menu
Detached HEAD: reduced 3-option menu (no merge from detached HEAD)
Provenance-based cleanup: .worktrees/ = ours, anything else = hands off
Bug #940: Option 2 no longer cleans up worktree
Bug #999: merge -> verify -> remove worktree -> delete branch
Bug #238: cd to main repo root before git worktree remove
Stale worktree pruning after removal (git worktree prune)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address spec review findings in both skill rewrites (PRI-974)

using-git-worktrees: submodule guard now says "treat as normal repo"
instead of "proceed to Step 1" (preserves consent flow)
using-git-worktrees: directory priority summaries include global legacy

finishing-a-development-branch: move git branch -d after Step 6 cleanup
to make Bug #999 ordering unambiguous (merge -> worktree remove -> branch delete)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update worktree integration references across skills (PRI-974)

Remove REQUIRED language from executing-plans and subagent-driven-development.
Consent and detection now live inside using-git-worktrees itself.
Fix stale 'created by brainstorming' claim in writing-plans.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: include worktrees/ (non-hidden) in finishing provenance check (PRI-974)

The creation skill supports both .worktrees/ and worktrees/ directories,
but the finishing skill's cleanup only checked .worktrees/. Worktrees
under the non-hidden path would be orphaned on merge or discard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: Step 1a validated through TDD — explicit naming + consent bridge (PRI-974)

Step 1a failed at 2/6 with the spec's original abstract text ("use your
native tool"). Three REFACTOR iterations found what works (50/50 runs):

1. Explicit tool naming — "do you have EnterWorktree, WorktreeCreate..."
   transforms interpretation into factual toolkit check
2. Consent bridge — "user's consent is your authorization" directly
   addresses EnterWorktree's "ONLY when user explicitly asks" guardrail
3. Red Flag entry naming the specific anti-pattern

File split was tested but proven unnecessary — the fix is the Step 1a
text quality, not physical separation of git commands. Control test
with full 240-line skill (all git commands visible) passed 20/20.

Test script updated: supports batch runs (./test.sh green 20), "all"
phase, and checks absence of git worktree add (reliable signal) rather
than presence of EnterWorktree text (agent sometimes omits tool name).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: update spec with TDD findings on Step 1a (PRI-974)

Step 1a's original "deliberately short, abstract" design was disproven
by TDD (2/6 pass rate). Spec now documents the validated approach:
explicit tool naming + consent bridge + red flag (50/50 pass rate).

- Design Principles: updated to reflect explicit naming over abstraction
- Step 1a: replaced abstract text with validated approach, added design
  note explaining the TDD revision and why file splitting was unnecessary
- Risks: Step 1a risk marked RESOLVED with cross-platform validation table
  and residual risk note about upstream tool description dependency

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: honest cross-platform validation table in spec (PRI-974)

Research confirmed Claude Code is currently the only harness with an
agent-callable mid-session worktree tool. All others either create
worktrees before the agent starts (Codex App, Gemini, Cursor) or have
no native support (Codex CLI, OpenCode).

Table now shows: what was actually tested (Claude Code 50/50, Codex CLI
6/6), what was simulated (Codex App 1/1), and what's untested (Gemini,
Cursor, OpenCode). Step 1a is forward-compatible for when other
harnesses add agent-callable tools.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: cross-platform validation on 5 harnesses (PRI-974)

Tested on Gemini CLI (gemini -p) and Cursor Agent (cursor-agent -p):
- Gemini: Step 0 detection 1/1, Step 1b fallback 1/1
- Cursor: Step 0 detection 1/1, Step 1b fallback 1/1

Both correctly identified no native agent-callable worktree tool,
fell through to git worktree add, and performed safety verification.
Both correctly detected existing worktrees and skipped creation.

5 of 6 harnesses now tested. Only OpenCode untested (no CLI access).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove incorrect hooks symlink step from worktree skill

Git worktrees inherit hooks from the main repo automatically via
$GIT_COMMON_DIR — this has been the case since git 2.5 (2015).
The symlink step was based on an incorrect premise from PR #965
and also fails in practice (.git is a file in worktrees, not a dir).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: address PR #1121 review — respect user preference, drop y/n

- Consent prompt: drop "(y/n)" and add escape valve for users who
  have already declared their worktree preference in global or
  project agent instruction files.
- Directory selection: reorder to put declared user preference
  ahead of observed filesystem state, and reframe the default as
  "if no other guidance available".
- Sandbox fallback: require explicitly informing the user that
  the sandbox blocked creation, not just "report accordingly".
- writing-plans: fully qualify the superpowers:using-git-worktrees
  reference.
- Plan doc: mirror the consent-prompt change.

Step 1a native-tool framing and the helper-scripts suggestion are
still outstanding — the first needs a benchmark re-run before softer
phrasing can be adopted without regressing compliance; the second is
exploratory and will get a thread reply.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: soften Step 1a native-tool framing per PR #1121 review

Address obra's comment on explicit step numbers / prescriptive tone.
Drops "STOP HERE if available", the "If YES:" gate, and the "even if /
even if / NO EXCEPTIONS" reinforcement paragraph. Keeps the specific
tool-name anchors (EnterWorktree, WorktreeCreate, /worktree, --worktree),
which the original TDD data showed are load-bearing.

A/B verified against drill harness on the 3 creation/consent scenarios
(consent-flow, creation-from-main, creation-from-main-spec-aware):
baseline explicit wording scored 12/12 criteria, softened wording also
scored 12/12. The "agent used the most appropriate tool" criterion
passed in all 3 softened runs — agents still picked EnterWorktree via
ToolSearch without the imperative framing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: drop instruction file enumeration per PR #1121 review

Jesse flagged that the verbose CLAUDE.md/AGENTS.md/GEMINI.md/.cursorrules
enumeration (a) chews tokens, (b) confuses models that anchor on exact
strings, and (c) is repeated DRY-violatingly across 3+ locations.

Replace with abstract "your instructions" framing in four spots:
- skills/using-git-worktrees/SKILL.md Step 0 → Step 1 transition
- skills/using-git-worktrees/SKILL.md Step 1b Directory Selection
- docs/superpowers/plans/2026-04-06-worktree-rototill.md (both mirror locations)

Same intent, harness-agnostic phrasing, ~half the tokens.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: replace hardcoded /Users/jesse with generic placeholders (#858)

* Remove the deprecated legacy slash commands (#1188)

* fix: prevent subagent-driven-development from pausing every 3 tasks

requesting-code-review had "review after each batch (3 tasks)" for
executing-plans, which leaked into subagent-driven-development as a
check-in cadence. Replaced with flexible "each task or at natural
checkpoints" and added explicit continuous execution directive to
subagent-driven-development.

* Remove Integration sections from skills

These sections don't help with steering and are a legacy of the time
before agents had native skills systems.

* fix(opencode): cache bootstrap content at module level to eliminate per-step file I/O

getBootstrapContent() called fs.existsSync + fs.readFileSync + regex
frontmatter parsing on every agent step with zero caching.  The
experimental.chat.messages.transform hook fires every step in opencode's
agent loop (messages are reloaded from DB each step via
filterCompactedEffect).  A 10-step turn triggered 10 redundant file
reads + 10 regex parses for content that never changes during a session.

Changes:
- Add module-level _bootstrapCache (undefined = not loaded, null = file
  missing) so the first call reads and parses SKILL.md, all subsequent
  calls return the cached string with zero filesystem access
- Cache the null sentinel when SKILL.md is missing, preventing repeated
  fs.existsSync probes
- Add _testing export (resetCache/getCache) for test infrastructure
- Clarify the injection guard comment explaining how it interacts with
  opencode's per-step message reloading
- Add 15 regression tests covering cache behavior, fs call counts,
  injection guard, missing file sentinel, cache reset, and source audit

Fixes #1202

* test(opencode): simplify bootstrap cache coverage

* docs: clarify opencode install caveats

* test(opencode): modernize integration tests

* docs: add Factory Droid installation instructions

* Preserve Codex marketplace metadata

* docs: add README quickstart install links (#1293)

* docs(codex-tools): fix subagent wait mapping to wait_agent

Update the Codex tool mapping so Claude Code 'Task returns result' maps to the current Codex spawned-agent result tool, wait_agent. Also clarify that older Codex builds exposed spawned-agent waiting as wait, while current bare wait is the code-mode exec/wait surface for yielded exec cells.

Verified with Drill:
- codex-tool-mapping-comprehension fails against dev with task_returns_result=wait
- codex-tool-mapping-comprehension passes against this PR with task_returns_result=wait_agent and exec/wait scoped correctly
- codex-subagent-wait-mapping passes against this PR with spawn_agent -> wait_agent -> close_agent and PR963_OK returned

* fix(cursor): run SessionStart hook via run-hook.cmd on Windows

Route Cursor's Windows SessionStart hook through the existing run-hook.cmd dispatcher instead of invoking the extensionless session-start script directly. This avoids Windows opening the extensionless hook file and lets Git Bash run the script as intended.

Also removed an accidental UTF-8 BOM from hooks-cursor.json before merging.

Verified:
- hooks-cursor.json parses as JSON and has no BOM
- command is ./hooks/run-hook.cmd session-start
- CURSOR_PLUGIN_ROOT=/tmp/superpowers ./hooks/run-hook.cmd session-start emits valid Cursor JSON with additional_context

* fix(tests): make SDD integration test actually run its assertions

The SDD integration test silently bailed before printing any verification
results. Three independent bugs caused this:

1. `WORKING_DIR_ESCAPED` was computed from `$SCRIPT_DIR/../..` without
   resolving `..` segments. The resulting "directory" name contained
   literal `..` so `find` was looking in a path that doesn't exist.

2. With `set -euo pipefail`, the `find ... | sort -r | head -1` pipeline
   could exit non-zero (SIGPIPE on the producer when head closes early),
   killing the script silently before assertions ran.

3. The `claude -p` invocation never passed `--plugin-dir`, so it loaded
   the installed plugin instead of the working tree. Local edits to
   skills under test were not actually being tested.

Other adjustments:
- Run claude from inside the unique TEST_PROJECT directory instead of
  from the plugin root, so its session JSONL lives in its own
  `~/.claude/projects/` folder and doesn't race other concurrent
  claude sessions for "most recent file".
- Use the same character-normalization claude does (every non-alphanumeric
  becomes `-`) when computing the session dir name; macOS-resolved
  `/private/var/...` paths and tmp dirs with `.`/`_` in their names need
  this to round-trip correctly.
- Accept either `"name":"Agent"` or `"name":"Task"` in the subagent count
  — the harness renamed the tool but the test wasn't updated.

Verified on this branch: all six verification tests now pass against a
real end-to-end SDD run (skill invoked, 7 subagents dispatched, 6
TodoWrite calls, working code produced, tests pass, no extra features).

* feat: add Gemini CLI subagent support mapping

Map Gemini Task dispatch to @agent-name/@generalist and document parallel subagent dispatch for independent tasks.

* docs: update Codex plugin install guidance (#1288)

* Lift superpowers:code-reviewer agent into the requesting-code-review skill

The plugin had a single named agent (`agents/code-reviewer.md`) used by
two skills, while every other reviewer/implementer subagent in the repo
is dispatched as `general-purpose` with the prompt template living
alongside its skill. That asymmetry had no upside and several costs:

- Two sources of truth for the code review checklist (the agent file
  and `requesting-code-review/code-reviewer.md`), both drifting
  independently.
- `Codex` users could not use the named agent directly; the codex-tools
  reference doc had a workaround section explaining how to flatten the
  named agent into a `worker` dispatch.
- No third-party reliance on `superpowers:code-reviewer` inside this
  repo.

Changes:
- Merge `agents/code-reviewer.md` (persona + checklist) and
  `skills/requesting-code-review/code-reviewer.md` (placeholder
  template) into a single self-contained Task-dispatch template,
  matching the shape of `implementer-prompt.md`,
  `spec-reviewer-prompt.md`, etc.
- Update `skills/requesting-code-review/SKILL.md` and
  `skills/subagent-driven-development/code-quality-reviewer-prompt.md`
  to dispatch `Task (general-purpose)` instead of the named agent.
- Drop the now-obsolete "Named agent dispatch" workaround sections from
  `codex-tools.md` and `copilot-tools.md` — superpowers no longer ships
  any named agents, so those instructions documented nothing.
- Delete `agents/code-reviewer.md` and the empty `agents/` directory.

Tier 3 coverage for the change: a new behavioral test
`tests/claude-code/test-requesting-code-review.sh` plants real bugs
(SQL injection, plaintext password handling, credential logging) into
a tiny project, runs the actual `requesting-code-review` skill against
the working tree, and asserts the dispatched reviewer flags every
planted issue at Critical/Important severity and refuses to approve
the diff.

Verified end-to-end on this branch:
- The new test passes (5/5 assertions; reviewer caught all planted
  bugs and several others).
- The existing SDD integration test still passes (7/7 subagents
  dispatched, all as `general-purpose`; spec compliance still
  rejects extra features; produced code is correct).
- Session JSONLs confirm zero remaining `superpowers:code-reviewer`
  dispatches anywhere in the SDD pipeline.

* Prepare v5.1.0: release notes and version bump

Add v5.1.0 release notes covering:
- Removals: legacy slash commands (/brainstorm, /execute-plan,
  /write-plan), skill Integration sections
- Worktree skills rewrite (PRI-974, PR #1121)
- Contributor guidelines for AI agents
- Codex plugin mirror tooling (PR #1165)
- OpenCode bootstrap caching (#1202)
- SDD pause-every-3-tasks fix; SDD integration test fixes
- Cursor Windows hook routing
- Gemini CLI subagent dispatch mapping
- Skill terminology cleanups
- Install docs (Factory Droid, Codex, quickstart links)

Bumps version 5.0.7 -> 5.1.0 across all declared files via
scripts/bump-version.sh; not yet tagged or released.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Drew Ritter <drewritter@workerbee.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Drew Ritter <drew@primeradiant.com>
Co-authored-by: Blaž Čulina <culina.blaz@nsoft.com>
Co-authored-by: Jesse Vincent <jesse@primeradiant.com>
Co-authored-by: voidborne-d <voidborne-d@users.noreply.github.com>
Co-authored-by: Richard Luo <luo.richard@gmail.com>
Co-authored-by: Drew Ritter <drew@ritter.dev>
Co-authored-by: leonsong09 <59187950+leonsong09@users.noreply.github.com>
Co-authored-by: YuXiang Hong <41331696+starumiQAQ@users.noreply.github.com>
Co-authored-by: Sathvik Gilakamsetty <spacetime1007@gmail.com>
2026-05-04 15:05:01 -07:00
daniel-graham
991e9d4de9 fix: replace bare except with except Exception
Co-authored-by: daniel-graham <daniel-graham@users.noreply.github.com>
2026-03-09 17:10:07 -07:00
Jesse Vincent
69eaf3cf34 Add end-to-end tests for document review system 2026-03-06 14:48:46 -08:00
Jesse Vincent
f57638a747 refactor: restructure specs and plans directories
- Specs (brainstorming output) now go to docs/superpowers/specs/
- Plans (writing-plans output) now go to docs/superpowers/plans/
- User preferences for locations override these defaults
- Update all skill references and test files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-06 13:01:31 -08:00
CL Kao
c7816ee2a6 docs: change main branch red flag to require explicit user consent
Instead of prohibiting main branch work entirely, allow it with explicit
user consent. This is more flexible while still ensuring users are aware
of the implications.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 15:12:50 -08:00
CL Kao
f8dbe7b196 test: add Test 9 - main branch red flag warning
TDD: Test verifies that subagent-driven-development skill warns
against starting implementation directly on main/master branch.
Test expects skill to recommend worktree or feature branch instead.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:41:39 -08:00
CL Kao
93cf2ee84f test: add worktree requirement test for subagent-driven-development
Add Test 8 to verify that using-git-worktrees is mentioned as a required
skill for subagent-driven-development. This test will initially fail per
TDD approach - the skill file needs to be updated to pass this test.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:39:50 -08:00
CL Kao
1872f50b64 fix(tests): handle case variations in skill recognition test
The assertion now matches "subagent-driven-development", "Subagent-Driven
Development", and "Subagent Driven" since Claude's responses may use
different casing and formatting styles.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:34:38 -08:00
Jesse Vincent
faa65e7163 Add token usage analysis to subagent-driven-development test
- Rewrote analyze-token-usage.py to parse main session file correctly
- Extracts usage from toolUseResult fields for each subagent
- Shows breakdown by agent with descriptions
- Integrated into test-subagent-driven-development-integration.sh
- Displays token usage automatically after each test run
2025-12-17 16:44:50 -08:00
Jesse Vincent
24ca8cd9d5 fix: verify skill usage via session transcript not text output
The skill instructions are internal and don't appear in user-facing
output. Updated verification to parse the session JSONL transcript
and check for actual tool usage:
- Skill tool invocation
- Task tool (subagents)
- TodoWrite (tracking)
- Implementation results
2025-12-17 16:44:50 -08:00
Jesse Vincent
8fbeca830a test: use bypassPermissions mode for unrestricted testing
dontAsk mode was auto-denying Write tool. Use bypassPermissions
instead to allow full tool access in this controlled test environment.
2025-12-17 16:44:50 -08:00
Jesse Vincent
67de772d7f test: auto-approve permissions with --permission-mode dontAsk
Headless tests need automatic permission approval to write files.
Using dontAsk mode to auto-approve permissions for test directory.
2025-12-17 16:44:50 -08:00
Jesse Vincent
cf72863792 test: add --add-dir flag for temp directory access
Claude needs explicit permission to access the temp test directory.
Added --add-dir flag to grant access to the test project.
2025-12-17 16:44:50 -08:00
Jesse Vincent
baa23b16bb test: show Claude output in real-time during integration test
Use tee instead of redirection so test output is visible during
execution while still being saved to file for analysis.
2025-12-17 16:44:50 -08:00
Jesse Vincent
0aba33be1c fix: run integration test from superpowers dir to access local dev skills
The superpowers-dev marketplace makes skills available only when running
from the plugin directory. Updated test to run claude from superpowers
directory while working on the test project.
2025-12-17 16:44:50 -08:00
Jesse Vincent
06310d6f5f Fix tests to use --allowed-tools flag
Claude Code headless mode requires --allowed-tools flag to actually
execute tool calls. Without it, Claude only responds as if it's doing
things but doesn't actually use tools.

Changes:
- Updated run_claude helper to accept allowed_tools parameter
- Updated integration test to use --allowed-tools=all
- This enables actual tool execution (Write, Task, Bash, etc.)

Now the integration test should actually execute the workflow instead
of just talking about it.
2025-12-17 16:44:50 -08:00
Jesse Vincent
dc11a093c3 Fix syntax error in integration test
Simplified command substitution to avoid shell parsing issues.
Instead of nested heredoc in command substitution, write prompt
to file first then read it.
2025-12-17 16:44:50 -08:00
Jesse Vincent
fa946ae465 Add integration test for subagent-driven-development
Created full end-to-end integration test that executes a real plan
and verifies the new workflow improvements actually work.

New test: test-subagent-driven-development-integration.sh
- Creates real Node.js test project
- Generates implementation plan (2 tasks)
- Executes using subagent-driven-development skill
- Verifies 8 key behaviors:
  1. Plan read once at beginning (not per task)
  2. Full task text provided to subagents (not file reading)
  3. Subagents perform self-review
  4. Spec compliance review before code quality
  5. Spec reviewer reads code independently
  6. Working implementation produced
  7. Tests pass
  8. No extra features added (spec compliance)

Integration tests are opt-in (--integration flag) due to 10-30 min runtime.

Updated run-skill-tests.sh:
- Added --integration flag
- Separates fast tests from integration tests
- Shows note when integration tests skipped

Updated README with integration test documentation.

Run with:
  ./run-skill-tests.sh                # Fast tests only
  ./run-skill-tests.sh --integration  # Include integration tests
2025-12-17 16:44:50 -08:00