Compare commits

..

1 Commits

Author SHA1 Message Date
Drew Ritter
43f9791850 fix: read Codex plugin version from manifest (PRI-2240) 2026-06-16 12:13:43 -07:00
31 changed files with 255 additions and 318 deletions

View File

@@ -1,20 +0,0 @@
{
"name": "superpowers-dev",
"interface": {
"displayName": "Superpowers Dev"
},
"plugins": [
{
"name": "superpowers",
"source": {
"source": "url",
"url": "./"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Developer Tools"
}
]
}

View File

@@ -9,7 +9,7 @@
{
"name": "superpowers",
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
"version": "6.0.3",
"version": "6.0.0",
"source": "./",
"author": {
"name": "Jesse Vincent",

View File

@@ -1,7 +1,7 @@
{
"name": "superpowers",
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
"version": "6.0.3",
"version": "6.0.0",
"author": {
"name": "Jesse Vincent",
"email": "jesse@fsck.com"

View File

@@ -1,6 +1,6 @@
{
"name": "superpowers",
"version": "6.0.3",
"version": "6.0.0",
"description": "An agentic skills framework & software development methodology that works: planning, TDD, debugging, and collaboration workflows.",
"author": {
"name": "Jesse Vincent",

View File

@@ -2,7 +2,7 @@
"name": "superpowers",
"displayName": "Superpowers",
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
"version": "6.0.3",
"version": "6.0.0",
"author": {
"name": "Jesse Vincent",
"email": "jesse@fsck.com"

9
.gitignore vendored
View File

@@ -7,7 +7,8 @@ node_modules/
inspo
triage/
# Eval harness lives in its own repository, cloned into evals/ for local
# development (see CLAUDE.md / README.md). It is not part of the published
# plugin, so the whole directory is ignored here.
evals/
# Eval harness — drill ships its own gitignore at evals/.gitignore;
# these are belt-and-suspenders entries for tools that don't recurse.
evals/results/
evals/.venv/
evals/.env

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "evals"]
path = evals
url = git@github.com:prime-radiant-inc/superpowers-evals.git

View File

@@ -1,6 +1,6 @@
{
"name": "superpowers",
"version": "6.0.3",
"version": "6.0.0",
"description": "An agentic skills framework and software development methodology.",
"author": {
"name": "Jesse Vincent",

View File

@@ -101,7 +101,7 @@ Skills are not prose — they are code that shapes agent behavior. If you modify
## Eval harness
Skill-behavior evals live in [superpowers-evals](https://github.com/prime-radiant-inc/superpowers-evals/), cloned into `evals/` see `evals/README.md` for setup. Drill (the harness) drives real tmux sessions of Claude Code / Codex / Gemini CLI and judges skill compliance with an LLM verifier. Plugin-infrastructure tests still live at `tests/`.
Skill-behavior evals live in the `evals/` submodule — after cloning, run `git submodule update --init evals`, then see `evals/README.md`. Drill (the harness) drives real tmux sessions of Claude Code / Codex / Gemini CLI and judges skill compliance with an LLM verifier. Plugin-infrastructure tests still live at `tests/`.
## Understand the Project Before Contributing

View File

@@ -262,7 +262,7 @@ The general contribution process for Superpowers is below. Keep in mind that we
4. Follow the `writing-skills` skill for creating and testing new and modified skills
5. Submit a PR, being sure to fill in the pull request template.
Skill-behavior tests use the drill eval harness from [superpowers-evals](https://github.com/prime-radiant-inc/superpowers-evals/), cloned into `evals/` see `evals/README.md` for setup. Plugin-infrastructure tests live at `tests/` and run via the relevant `run-*.sh` or `npm test`.
Skill-behavior tests use the eval harness submodule at `evals/`. After cloning this repo, run `git submodule update --init evals`, then see `evals/README.md` for setup. Plugin-infrastructure tests live at `tests/` and run via the relevant `run-*.sh` or `npm test`.
See `skills/writing-skills/SKILL.md` for the complete guide.

View File

@@ -1,24 +1,5 @@
# Superpowers Release Notes
## v6.0.3 (2026-06-18)
### Subagent-Driven Development
- **SDD scratch files moved out of `.git/`.** Claude Code treats `.git/` as a protected path and denies agent writes there, so an implementer subagent writing its report into `.git/sdd/` got blocked mid-run. Task briefs, implementer reports, review diffs, and the progress ledger now live in a self-ignoring `.superpowers/sdd/` directory in the working tree — kept out of `git status` and out of commits, and resolved per worktree by a shared `sdd-workspace` helper. One caveat: because the workspace is git-ignored working-tree scratch, `git clean -fdx` will delete the progress ledger; recover from `git log` if that happens. (#1780)
## v6.0.2 (2026-06-16)
### Install Fixes
- **We no longer ship the `evals` submodule.** It broke plugin installs for some users, so the eval harness now lives in its own repo, separate from the published plugin. (#1778, #1774)
## v6.0.1 (2026-06-16)
### Codex Fixes
- **Version display in the brainstorm companion** — packaged Codex plugins ship without a root `package.json`, so the visual companion reported its version as "unknown". `readSuperpowersVersion()` now falls back to `.codex-plugin/plugin.json` when `package.json` is absent.
- **Cleaner Codex plugin sync** — the sync-to-codex script now excludes `.gitmodules` and `.pre-commit-config.yaml`, keeping repo metadata out of the packaged Codex plugin.
## v6.0.0 (2026-06-16)
Superpowers 6.0 is a big release. The headline is a rewrite of how `subagent-driven-development` reviews each task — cheaper, stricter, and harder to game.

1
evals Submodule

Submodule evals added at 70a245c36c

View File

@@ -1,6 +1,6 @@
{
"name": "superpowers",
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
"version": "6.0.3",
"version": "6.0.0",
"contextFileName": "GEMINI.md"
}

View File

@@ -2,7 +2,7 @@
"hooks": {
"SessionStart": [
{
"matcher": "startup|clear|compact",
"matcher": "startup|resume|clear",
"hooks": [
{
"type": "command",

View File

@@ -1,6 +1,6 @@
{
"name": "superpowers",
"version": "6.0.3",
"version": "6.0.0",
"description": "Superpowers skills and runtime bootstrap for coding agents",
"type": "module",
"main": ".opencode/plugins/superpowers.js",

View File

@@ -52,11 +52,9 @@ EXCLUDES=(
"/.gitattributes"
"/.github/"
"/.gitignore"
"/.gitmodules"
"/.kimi-plugin/"
"/.opencode/"
"/.pi/"
"/.pre-commit-config.yaml"
"/.version-bump.json"
"/.worktrees/"
".DS_Store"

View File

@@ -251,7 +251,7 @@ sequences — the single most expensive failure observed. Track progress in
a ledger file, not only in todos.
- At skill start, check for a ledger:
`cat "$(git rev-parse --show-toplevel)/.superpowers/sdd/progress.md"`. Tasks listed there
`cat "$(git rev-parse --git-path sdd)/progress.md"`. Tasks listed there
as complete are DONE — do not re-dispatch them; resume at the first task
not marked complete.
- When a task's review comes back clean, append one line to the ledger in
@@ -260,8 +260,6 @@ a ledger file, not only in todos.
- The ledger is your recovery map: the commits it names exist in git even
when your context no longer remembers creating them. After compaction,
trust the ledger and `git log` over your own recollection.
- `git clean -fdx` will destroy the ledger (it's git-ignored scratch); if
that happens, recover from `git log`.
## Prompt Templates

View File

@@ -5,8 +5,9 @@
# tasks intact.
#
# Usage: review-package BASE HEAD [OUTFILE]
# Default OUTFILE: <repo-root>/.superpowers/sdd/review-<base7>..<head7>.diff
# (named per range, so a re-review after fixes gets a distinct fresh file).
# Default OUTFILE: <git-dir>/sdd/review-<base7>..<head7>.diff — unique per
# repo instance and per range, so concurrent sessions cannot collide and a
# re-review after fixes always gets a distinctly named fresh file.
set -euo pipefail
if [ $# -lt 2 ] || [ $# -gt 3 ]; then
@@ -23,7 +24,9 @@ git rev-parse --verify --quiet "$head" >/dev/null || { echo "bad HEAD: $head" >&
if [ $# -eq 3 ]; then
out=$3
else
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace")
dir=$(git rev-parse --git-path sdd)
mkdir -p "$dir"
dir=$(cd "$dir" && pwd)
out="$dir/review-$(git rev-parse --short "$base")..$(git rev-parse --short "$head").diff"
fi

View File

@@ -1,22 +0,0 @@
#!/usr/bin/env bash
# Resolve and ensure the working-tree directory SDD uses for its short-lived
# artifacts: task briefs, implementer reports, review packages, and the
# progress ledger. Print the directory's absolute path.
#
# The workspace lives in the working tree (not under .git/) because Claude Code
# treats .git/ as a protected path and denies agent writes there — which blocks
# an implementer subagent from writing its report file. A self-ignoring
# .gitignore keeps the workspace out of `git status` and out of accidental
# commits without modifying any tracked file.
#
# Single source of truth for the workspace location, so task-brief and
# review-package cannot drift to different directories.
#
# Usage: sdd-workspace
set -euo pipefail
root=$(git rev-parse --show-toplevel)
dir="$root/.superpowers/sdd"
mkdir -p "$dir"
printf '*\n' > "$dir/.gitignore"
cd "$dir" && pwd

View File

@@ -4,8 +4,8 @@
# through the controller's context.
#
# Usage: task-brief PLAN_FILE TASK_NUMBER [OUTFILE]
# Default OUTFILE: <repo-root>/.superpowers/sdd/task-<N>-brief.md
# (per worktree; concurrent runs in the same working tree share it).
# Default OUTFILE: <git-dir>/sdd/task-<N>-brief.md — unique per repo
# instance, so concurrent sessions cannot collide.
set -euo pipefail
if [ $# -lt 2 ] || [ $# -gt 3 ]; then
@@ -20,7 +20,9 @@ n=$2
if [ $# -eq 3 ]; then
out=$3
else
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace")
dir=$(git rev-parse --git-path sdd)
mkdir -p "$dir"
dir=$(cd "$dir" && pwd)
out="$dir/task-${n}-brief.md"
fi

View File

@@ -4,12 +4,85 @@ Skills speak in actions ("dispatch a subagent", "create a todo", "read a file").
| Action skills request | Antigravity CLI equivalent |
|----------------------|----------------------|
| Read a file | `view_file` |
| Create a new file | `write_to_file` |
| Edit a file | `replace_file_content` |
| Edit a file in several places at once | `multi_replace_file_content` |
| Run a shell command | `run_command` |
| Search file contents | `grep_search` |
| Find files by name / list a directory | `list_dir` (no dedicated glob tool — combine `list_dir` with `grep_search`) |
| Fetch a URL | `read_url_content` |
| Search the web | `search_web` |
| Pose a structured question to your human partner | `ask_question` |
| Dispatch a subagent (`Subagent (general-purpose):` template) | `invoke_subagent` with a built-in `TypeName``self` for full-capability work, `research` for read-only (see [Subagent support](#subagent-support)) |
| Multiple parallel dispatches | Multiple entries in one `invoke_subagent` call's `Subagents` array |
| Task tracking ("create a todo", "mark complete") | a **task artifact**`write_to_file` with `IsArtifact: true` and `ArtifactType: "task"` (see [Task tracking](#task-tracking)). **Not** `manage_task`, which manages background processes. |
## Invoking a skill — read its `SKILL.md`
Antigravity surfaces every installed skill's `name` + `description` to you at the
start of each session, but it has **no `Skill`/`activate_skill` tool**. To load a
skill, **read its `SKILL.md` with `view_file`, setting `IsSkillFile: true`** when
the skill applies — e.g. `view_file` on
`.../plugins/superpowers/skills/<skill-name>/SKILL.md` with `IsSkillFile: true`.
(`IsSkillFile` is agy's own signal that you're reading a file to *execute its
instructions*, not to edit or preview it — set it whenever you load a skill.)
This is the blessed skill-loading mechanism on this harness. The general rule
"never read skill files manually" means "don't bypass your platform's
skill-loading mechanism" — and on Antigravity, reading `SKILL.md` *is* that
mechanism. Reading it honors the rule rather than breaking it.
You already know which skills exist and what they're for: their names and
descriptions are in front of you at session start. When a description matches
what you're about to do, read that skill's `SKILL.md` before acting.
## Subagent support
Antigravity dispatches subagents with `invoke_subagent`, passing each one a
`TypeName` in the `Subagents` array. Two `TypeName`s are **built in** — use them
directly, no `define_subagent` needed:
- **`self`** — a full clone of you, with every tool you have (including
`write_to_file`/`replace_file_content`/`run_command`). The safe default for
general-purpose work: implementing, fixing, anything that edits files or runs
commands.
- **`research`** — read-only (file reading, `grep_search`, web/URL fetch; no write
or command access). Use it when you specifically want a subagent that can't make
changes — investigation and read-only review.
Call `define_subagent` only for a custom system prompt or capability mix: set
`enable_write_tools: true` to grant file edits **and** `run_command`,
`enable_subagent_tools` for nested dispatch, `enable_mcp_tools` for MCP. Then
invoke it by the name you gave it. (`manage_subagents` lists/kills running
subagents.)
Skills dispatch with `Subagent (general-purpose):` and either reference a
prompt-template file (e.g. `superpowers:subagent-driven-development`'s
`./implementer-prompt.md`) or supply an inline prompt. On Antigravity:
| Skill dispatch form | Antigravity equivalent |
|---------------------|----------------------|
| An implementer-style `*-prompt.md` template (writes code, runs tests) | Fill the template, then `invoke_subagent` with `TypeName: "self"` and the filled prompt |
| A read-only reviewer template (`task-reviewer`, `code-reviewer`, `requesting-code-review`'s `./code-reviewer.md`) | `invoke_subagent` with `TypeName: "research"` and the filled review template |
| Inline prompt (no template referenced) | `invoke_subagent` with `TypeName: "self"` (or `"research"` if the task only reads) and your inline prompt |
### Prompt filling
Skills provide prompt templates with placeholders like `{WHAT_WAS_IMPLEMENTED}` or
`[FULL TEXT of task]`. Fill all placeholders before passing the complete prompt to
`invoke_subagent`. The prompt template itself contains the agent's role, review
criteria, and expected output format — the subagent will follow it.
### Parallel dispatch
Put multiple entries in a single `invoke_subagent` call's `Subagents` array to run
independent subagent work in parallel. Keep dependent tasks sequential, but do not
serialize independent subagent tasks just to preserve a simpler history.
## Task tracking
Antigravity has **no todo tool** (`manage_task` manages background
Antigravity has **no todo / `TodoWrite` tool** (`manage_task` manages background
processes — `list`/`kill`/`status`/`send_input` — it is *not* a checklist). When a
skill says to create a todo list or track tasks, maintain a **task artifact**: a
markdown checklist saved with `write_to_file` (`IsArtifact: true`,

View File

@@ -0,0 +1,50 @@
# Claude Code Tool Mapping
Skills speak in actions ("dispatch a subagent", "create a todo", "read a file"). On Claude Code these resolve to the tools below.
## Tools
| Action skills request | Claude Code tool |
|----------------------|------------------|
| Read a file | `Read` |
| Create a new file | `Write` |
| Edit a file | `Edit` |
| Run a shell command | `Bash` |
| Search file contents | `Grep` |
| Find files by name | `Glob` |
| Fetch a URL | `WebFetch` |
| Search the web | `WebSearch` |
| Invoke a skill | `Skill` |
| Dispatch a subagent (`Subagent (general-purpose):` template) | `Agent` (older releases named this `Task`) |
| Multiple parallel dispatches | Multiple `Agent` calls in one response |
| Task tracking ("create a todo", "mark complete") | `TaskCreate`, `TaskUpdate`, `TaskList`, `TaskGet`; `TodoWrite` in `claude -p` / Agent SDK unless `CLAUDE_CODE_ENABLE_TASKS=1` is set |
| Background-process / subagent lifecycle (read output, cancel) | `TaskOutput`, `TaskStop` — these are distinct from the todo tools above and apply to running shells, agents, and remote sessions |
## Instructions file
When a skill mentions "your instructions file", on Claude Code this is **`CLAUDE.md`**. Claude Code walks up the directory tree from the current working directory and concatenates every `CLAUDE.md` and `CLAUDE.local.md` it finds along the way. Standard locations:
| Scope | Location |
|-------|----------|
| Project (team-shared) | `./CLAUDE.md` or `./.claude/CLAUDE.md` |
| User global | `~/.claude/CLAUDE.md` |
| Local-private (gitignored) | `./CLAUDE.local.md` |
| Managed policy (org-wide) | `/Library/Application Support/ClaudeCode/CLAUDE.md` (macOS), `/etc/claude-code/CLAUDE.md` (Linux/WSL), `C:\Program Files\ClaudeCode\CLAUDE.md` (Windows) |
CLAUDE.md files can pull in additional content with `@path/to/file` imports (relative or absolute, max five hops deep). Subdirectory `CLAUDE.md` files are also discovered automatically and loaded on-demand when Claude Code reads files in those subdirectories.
Claude Code does **not** read `AGENTS.md` directly. If a project already maintains `AGENTS.md` for other agents, import it from `CLAUDE.md` so both runtimes share the same instructions:
```markdown
@AGENTS.md
## Claude Code
(Claude-Code-specific instructions go here.)
```
For path-scoped rules and larger-project organization, see `.claude/rules/` (rules can be scoped to specific files via `paths` frontmatter and load on demand).
## Personal skills directory
User-level skills live at **`~/.claude/skills/`**. Each skill is a subdirectory containing a `SKILL.md` (with `name` and `description` frontmatter) plus any supporting files. Claude Code does not currently recognize the cross-runtime `~/.agents/skills/` path that Codex, Copilot CLI, and Gemini CLI read; if you're relying on cross-runtime support in the future, verify against the [official skills docs](https://code.claude.com/docs/en/skills).

View File

@@ -1,3 +1,31 @@
# Codex Tool Mapping
Skills speak in actions ("dispatch a subagent", "create a todo", "read a file"). On Codex these resolve to the tools below.
| Action skills request | Codex equivalent |
|----------------------|------------------|
| Read a file | `shell` (e.g., `cat`, `head`, `tail`) — Codex reads files via shell |
| Create / edit / delete a file | `apply_patch` (structured diff for create, update, delete) |
| Run a shell command | `shell` |
| Search file contents | `shell` (e.g., `grep`, `rg`) |
| Find files by name | `shell` (e.g., `find`, `ls`) |
| Fetch a URL | `shell` with `curl` / `wget` — Codex has no native fetch tool |
| Search the web | `web_search` (enabled by default; configurable in `config.toml` via the top-level `web_search` setting — `live`, `cached`, or `disabled`) |
| Invoke a skill | Skills load natively — just follow the instructions |
| Dispatch a subagent (`Subagent (general-purpose):` template) | `spawn_agent` (see [Subagent dispatch requires multi-agent support](#subagent-dispatch-requires-multi-agent-support)) |
| Multiple parallel dispatches | Multiple `spawn_agent` calls in one response |
| Wait for subagent result | `wait_agent` |
| Free up subagent slot when done | `close_agent` |
| Task tracking ("create a todo", "mark complete") | `update_plan` |
## Instructions file
When a skill mentions "your instructions file", on Codex this is **`AGENTS.md`** at the project root. Codex also reads `~/.codex/AGENTS.md` for global context, and an `AGENTS.override.md` (in the project tree or `~/.codex/`) takes precedence when present. Codex walks from the project root down to the current working directory, concatenating `AGENTS.md` files it finds along the way, up to `project_doc_max_bytes` (32 KiB by default).
## Personal skills directory
User-level skills live at **`$CODEX_HOME/skills/`** (default `~/.codex/skills/`). Codex also reads the cross-runtime path **`~/.agents/skills/`** (shared with Copilot CLI and Gemini CLI). When both directories exist at the same scope, Codex loads them both as separate skill catalogs — Codex's docs don't currently document a precedence between them. Each skill is a subdirectory containing a `SKILL.md` (with `name` and `description` frontmatter).
## Subagent dispatch requires multi-agent support
Add to your Codex config (`~/.codex/config.toml`):
@@ -7,7 +35,12 @@ Add to your Codex config (`~/.codex/config.toml`):
multi_agent = true
```
This enables `spawn_agent`, `wait_agent`, and `close_agent` for skills like `dispatching-parallel-agents` and `subagent-driven-development`. When using subagent-driven-development, you should always close implementer and reviewer subagents when they have finished all their work.
This enables `spawn_agent`, `wait_agent`, and `close_agent` for skills like `dispatching-parallel-agents` and `subagent-driven-development`.
Legacy note: Codex builds before `rust-v0.115.0` exposed spawned-agent
waiting as `wait`. Current Codex uses `wait_agent` for spawned agents. The
`wait` name now belongs to code-mode `exec/wait`, which resumes a yielded exec
cell by `cell_id`; it is not the spawned-agent result tool.
## Environment Detection

View File

@@ -0,0 +1,49 @@
# Copilot CLI Tool Mapping
Skills speak in actions ("dispatch a subagent", "create a todo", "read a file"). On Copilot CLI these resolve to the tools below.
| Action skills request | Copilot CLI equivalent |
|----------------------|----------------------|
| Read a file | `view` |
| Create / edit / delete a file | `apply_patch` (Copilot CLI has no separate create/edit/write tools) |
| Run a shell command | `bash` |
| Search file contents | `rg` (ripgrep; Copilot CLI does not expose a `grep` tool) |
| Find files by name | `glob` |
| Fetch a URL | `web_fetch` |
| Search the web | `web_search` |
| Invoke a skill | `skill` |
| Dispatch a subagent (`Subagent (general-purpose):` template) | `task` with `agent_type: "general-purpose"` (other accepted types: `explore`, `task`, `code-review`, `research`, `configure-copilot`) |
| Multiple parallel dispatches | Multiple `task` calls in one response |
| Subagent status/output/control | `read_agent`, `list_agents`, `write_agent` |
| Task tracking ("create a todo", "mark complete") | `update_todo` |
| Enter / exit plan mode | No equivalent — stay in the main session |
## Instructions file
When a skill mentions "your instructions file", on Copilot CLI this is **`AGENTS.md`** at the repository root. If both `AGENTS.md` and `.github/copilot-instructions.md` are present, Copilot reads both.
## Personal skills directory
User-level skills live at **`~/.copilot/skills/`**. Copilot CLI also recognizes the cross-runtime alias **`~/.agents/skills/`**, which is shared with Codex and Gemini CLI. Each skill is a subdirectory containing a `SKILL.md` (with `name` and `description` frontmatter).
## Async shell sessions
Copilot CLI supports persistent async shell sessions:
| Tool | Purpose |
|------|---------|
| `bash` with `mode: "async"` (and optionally `detach: true`) | Start a long-running command in the background; returns a `shellId` |
| `write_bash` | Send input to a running async session |
| `read_bash` | Read output from an async session |
| `stop_bash` | Terminate an async session |
| `list_bash` | List all active shell sessions |
## Additional Copilot CLI tools
| Tool | Purpose |
|------|---------|
| `store_memory` | Persist facts about the codebase for future sessions |
| `report_intent` | Update the UI status line with current intent |
| `sql` | Query the session's SQLite database (todos, metadata) |
| `fetch_copilot_cli_documentation` | Look up Copilot CLI documentation |
| GitHub MCP tools (`github-mcp-server-*`) | Native GitHub API access (issues, PRs, code search) |

View File

@@ -4,9 +4,21 @@ Skills speak in actions ("dispatch a subagent", "create a todo", "read a file").
| Action skills request | Pi equivalent |
| --- | --- |
| Invoke a skill | Pi native skills: load the relevant `SKILL.md` with `read`, or let the human use `/skill:name` |
| Read a file | `read` |
| Create a file | `write` |
| Edit a file | `edit` |
| Run a shell command | `bash` |
| Search file contents | `grep` when active; otherwise `bash` with `rg`/`grep` |
| Find files by name | `find` or `bash` with shell globs |
| List files and subdirectories | `ls` when active; otherwise `bash` with `ls` |
| Dispatch a subagent (`Subagent (general-purpose):` template) | Use an installed subagent tool such as `subagent` from `pi-subagents` if available |
| Task tracking ("create a todo", "mark complete") | Use an installed todo/task tool if available, otherwise track tasks in the plan or `TODO.md` |
## Skills
Pi discovers skills from configured skill directories and installed Pi packages. A Superpowers Pi package should expose `skills/` through its `pi.skills` manifest entry. Pi does not expose Claude Code's `Skill` tool, but the agent should still follow the Superpowers rule: when a skill applies, load and follow it before responding.
## Subagents
Pi core does not ship a standard subagent tool. The `pi-subagents` package is a strong optional companion and provides a `subagent` tool with single-agent, chain, parallel, async, forked-context, and resume/status workflows. If no subagent tool is available, do not fabricate `Task` calls; execute sequentially in the current session or explain that the optional subagent capability is not installed.

View File

@@ -8,13 +8,13 @@
"name": "brainstorm-server-tests",
"version": "1.0.0",
"dependencies": {
"ws": "^8.21.0"
"ws": "^8.19.0"
}
},
"node_modules/ws": {
"version": "8.21.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
"integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"

View File

@@ -5,6 +5,6 @@
"test": "node ws-protocol.test.js && node helper.test.js && node browser-launcher.test.js && node auth.test.js && node branding.test.js && node server.test.js && node lifecycle.test.js && bash start-server.test.sh && bash stop-server.test.sh"
},
"dependencies": {
"ws": "^8.21.0"
"ws": "^8.19.0"
}
}

View File

@@ -74,7 +74,6 @@ done
# List of skill tests to run (fast unit tests)
tests=(
"test-worktree-path-policy.sh"
"test-sdd-workspace.sh"
"test-subagent-driven-development.sh"
)

View File

@@ -1,142 +0,0 @@
#!/usr/bin/env bash
# Tests for the SDD workspace: scripts/sdd-workspace resolves a self-ignoring
# working-tree directory for SDD artifacts, and the SDD scripts write into it.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
SDD_SCRIPTS="$REPO_ROOT/skills/subagent-driven-development/scripts"
FAILURES=0
TEST_ROOT=""
pass() { echo " [PASS] $1"; }
fail() {
echo " [FAIL] $1"
FAILURES=$((FAILURES + 1))
}
cleanup() {
if [[ -n "$TEST_ROOT" && -d "$TEST_ROOT" ]]; then
rm -rf "$TEST_ROOT"
fi
}
main() {
echo "=== Test: sdd-workspace ==="
TEST_ROOT="$(mktemp -d)"
trap cleanup EXIT
# Resolve repo to its physical path so string comparisons match the
# helper's output (git rev-parse --show-toplevel resolves symlinks; on
# macOS mktemp lives under /var -> /private/var).
git init -q -b main "$TEST_ROOT/repo"
local repo
repo="$(cd "$TEST_ROOT/repo" && git rev-parse --show-toplevel)"
local dir
dir="$(cd "$repo" && "$SDD_SCRIPTS/sdd-workspace")"
if [[ "$dir" == "$repo/.superpowers/sdd" ]]; then
pass "prints <repo-root>/.superpowers/sdd"
else
fail "prints <repo-root>/.superpowers/sdd"
echo " got: $dir"
fi
if [[ -f "$repo/.superpowers/sdd/.gitignore" && "$(cat "$repo/.superpowers/sdd/.gitignore")" == "*" ]]; then
pass "self-ignoring .gitignore created with '*'"
else
fail "self-ignoring .gitignore created with '*'"
fi
printf 'x\n' > "$repo/.superpowers/sdd/artifact.md"
local status
status="$(cd "$repo" && git status --porcelain)"
if [[ -z "$status" ]]; then
pass "workspace invisible to git status"
else
fail "workspace invisible to git status"
echo " status: $status"
fi
( cd "$repo" && git add -A )
local staged
staged="$(cd "$repo" && git diff --cached --name-only)"
if [[ -z "$staged" ]]; then
pass "git add -A does not stage the workspace"
else
fail "git add -A does not stage the workspace"
echo " staged: $staged"
fi
cat > "$repo/plan.md" <<'PLAN'
# Plan
## Task 1: First thing
Do the first thing.
PLAN
local brief_out brief_path
brief_out="$(cd "$repo" && "$SDD_SCRIPTS/task-brief" plan.md 1)"
brief_path="$(printf '%s\n' "$brief_out" | sed -n 's/^wrote \(.*\): [0-9][0-9]* lines$/\1/p')"
case "$brief_path" in
"$repo/.superpowers/sdd/"*) pass "task-brief writes its brief under the workspace" ;;
*)
fail "task-brief writes its brief under the workspace"
echo " got: $brief_path"
;;
esac
local git_id=(-c user.email=t@example.com -c user.name=t -c commit.gpgsign=false)
( cd "$repo" \
&& git add plan.md \
&& git "${git_id[@]}" commit -qm c1 \
&& printf 'y\n' > f && git add f \
&& git "${git_id[@]}" commit -qm c2 )
local rp_out rp_path
rp_out="$(cd "$repo" && "$SDD_SCRIPTS/review-package" HEAD~1 HEAD)"
rp_path="$(printf '%s\n' "$rp_out" | sed -n 's/^wrote \(.*\): [0-9].*$/\1/p')"
case "$rp_path" in
"$repo/.superpowers/sdd/"*) pass "review-package writes its diff under the workspace" ;;
*)
fail "review-package writes its diff under the workspace"
echo " got: $rp_path"
;;
esac
# --- Worktree isolation: a linked worktree resolves its own workspace ---
local wt="$TEST_ROOT/wt"
( cd "$repo" && git worktree add -q "$wt" -b wt-feature )
local wt_root wt_dir
wt_root="$(cd "$wt" && git rev-parse --show-toplevel)"
wt_dir="$(cd "$wt" && "$SDD_SCRIPTS/sdd-workspace")"
if [[ "$wt_dir" == "$wt_root/.superpowers/sdd" && "$wt_dir" != "$dir" ]]; then
pass "linked worktree resolves its own distinct workspace"
else
fail "linked worktree resolves its own distinct workspace"
echo " main: $dir"
echo " wt: $wt_dir"
fi
printf 'y\n' > "$wt/.superpowers/sdd/artifact.md"
local wt_status
wt_status="$(cd "$wt" && git status --porcelain)"
if [[ -z "$wt_status" ]]; then
pass "worktree workspace invisible to git status"
else
fail "worktree workspace invisible to git status"
echo " status: $wt_status"
fi
echo ""
if [[ "$FAILURES" -ne 0 ]]; then
echo "FAILED: $FAILURES assertion(s)."
exit 1
fi
echo "PASS"
}
main "$@"

View File

@@ -200,23 +200,6 @@ EOF
.private-journal/
EOF
cat > "$repo/.gitmodules" <<'EOF'
[submodule "evals"]
path = evals
url = git@example.com:example/evals.git
EOF
cat > "$repo/.pre-commit-config.yaml" <<'EOF'
repos:
- repo: local
hooks:
- id: evals-check
name: evals check
entry: echo evals
language: system
files: ^evals/
EOF
if [[ "$with_pure_ignored" == "1" ]]; then
cat >> "$repo/.gitignore" <<'EOF'
ignored-cache/
@@ -294,8 +277,6 @@ EOF
.codex-plugin/plugin.json \
.kimi-plugin/plugin.json \
.gitignore \
.gitmodules \
.pre-commit-config.yaml \
assets/app-icon.png \
assets/superpowers-small.svg \
evals/drill/README.md \
@@ -662,8 +643,6 @@ main() {
assert_not_contains "$preview_section" ".private-journal/leak.txt" "Preview excludes ignored untracked file"
assert_not_contains "$preview_section" "ignored-cache/" "Preview excludes pure ignored directories"
assert_not_contains "$preview_section" "evals/" "Preview excludes eval harness"
assert_not_contains "$preview_section" ".gitmodules" "Preview excludes repo submodule metadata"
assert_not_contains "$preview_section" ".pre-commit-config.yaml" "Preview excludes repo pre-commit config"
assert_not_contains "$preview_output" "Overlay file (.codex-plugin/plugin.json) will be regenerated" "Preview omits overlay regeneration note"
assert_not_contains "$preview_output" "Assets (superpowers-small.svg, app-icon.png) will be seeded from" "Preview omits assets seeding note"
assert_contains "$preview_section" "skills/example/SKILL.md" "Preview reflects dirty tracked destination file"

View File

@@ -1,61 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
MARKETPLACE="$REPO_ROOT/.agents/plugins/marketplace.json"
python3 - "$MARKETPLACE" "$REPO_ROOT" <<'PY'
import json
import sys
from pathlib import Path
marketplace_path = Path(sys.argv[1])
repo_root = Path(sys.argv[2])
if not marketplace_path.exists():
raise AssertionError(".agents/plugins/marketplace.json must exist")
marketplace = json.loads(marketplace_path.read_text(encoding="utf-8"))
def assert_equal(actual, expected, label):
if actual != expected:
raise AssertionError(f"{label}: expected {expected!r}, got {actual!r}")
assert_equal(marketplace.get("name"), "superpowers-dev", "marketplace name")
assert_equal(
marketplace.get("interface", {}).get("displayName"),
"Superpowers Dev",
"marketplace display name",
)
plugins = marketplace.get("plugins")
if not isinstance(plugins, list):
raise AssertionError("plugins must be a list")
matching_plugins = [plugin for plugin in plugins if plugin.get("name") == "superpowers"]
assert_equal(len(matching_plugins), 1, "superpowers plugin entry count")
plugin = matching_plugins[0]
assert_equal(plugin.get("source"), {"source": "url", "url": "./"}, "plugin source")
assert_equal(
plugin.get("policy"),
{"installation": "AVAILABLE", "authentication": "ON_INSTALL"},
"plugin policy",
)
assert_equal(plugin.get("category"), "Developer Tools", "plugin category")
plugin_manifest = repo_root / ".codex-plugin" / "plugin.json"
if not plugin_manifest.exists():
raise AssertionError(".codex-plugin/plugin.json must exist")
manifest = json.loads(plugin_manifest.read_text(encoding="utf-8"))
assert_equal(manifest.get("name"), plugin.get("name"), "plugin manifest name")
assert_equal(
manifest.get("hooks"),
"./hooks/hooks-codex.json",
"Codex hooks manifest",
)
print("Codex marketplace manifest looks good")
PY