mirror of
https://github.com/obra/superpowers.git
synced 2026-06-14 22:59:06 +08:00
Compare commits
7 Commits
docs-porti
...
codex/trim
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22b1eeec69 | ||
|
|
9d3e68a5ad | ||
|
|
81c3052416 | ||
|
|
c879454a0d | ||
|
|
ff213eb2cf | ||
|
|
da00e59958 | ||
|
|
deceaec78d |
13
README.md
13
README.md
@@ -4,7 +4,7 @@ Superpowers is a complete software development methodology for your coding agent
|
|||||||
|
|
||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
Give your agent Superpowers: [Claude Code](#claude-code), [Codex App](#codex-app), [Codex CLI](#codex-cli), [Cursor](#cursor), [Factory Droid](#factory-droid), [Gemini CLI](#gemini-cli), [GitHub Copilot CLI](#github-copilot-cli), [OpenCode](#opencode), [Pi](#pi).
|
Give your agent Superpowers: [Claude Code](#claude-code), [Antigravity](#antigravity), [Codex App](#codex-app), [Codex CLI](#codex-cli), [Cursor](#cursor), [Factory Droid](#factory-droid), [Gemini CLI](#gemini-cli), [GitHub Copilot CLI](#github-copilot-cli), [OpenCode](#opencode), [Pi](#pi).
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
@@ -60,6 +60,17 @@ The Superpowers marketplace provides Superpowers and some other related plugins
|
|||||||
/plugin install superpowers@superpowers-marketplace
|
/plugin install superpowers@superpowers-marketplace
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Antigravity
|
||||||
|
|
||||||
|
Install Superpowers as a plugin from this repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
agy plugin install https://github.com/obra/superpowers
|
||||||
|
```
|
||||||
|
|
||||||
|
Antigravity runs the plugin's session-start hook, so Superpowers is active from
|
||||||
|
the first message. Reinstall with the same command to update.
|
||||||
|
|
||||||
### Codex App
|
### Codex App
|
||||||
|
|
||||||
Superpowers is available via the [official Codex plugin marketplace](https://github.com/openai/plugins).
|
Superpowers is available via the [official Codex plugin marketplace](https://github.com/openai/plugins).
|
||||||
|
|||||||
@@ -755,10 +755,9 @@ Two rules this enforces, which you must respect:
|
|||||||
- Don't write per-OS variants of the hook script. One extensionless bash script
|
- Don't write per-OS variants of the hook script. One extensionless bash script
|
||||||
plus the polyglot wrapper covers all three platforms.
|
plus the polyglot wrapper covers all three platforms.
|
||||||
|
|
||||||
`hooks/run-hook.cmd` itself is the authoritative implementation — read it.
|
`hooks/run-hook.cmd` itself is the authoritative implementation — read it. See
|
||||||
(`docs/windows/polyglot-hooks.md` covers the background and rationale but
|
`docs/windows/polyglot-hooks.md` for the background and rationale behind the
|
||||||
describes an earlier per-script `.cmd`/`.sh` variant, so trust the code over that
|
dispatcher pattern.
|
||||||
doc where they differ.)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Cross-Platform Polyglot Hooks for Claude Code
|
# Cross-Platform Polyglot Hooks for Claude Code
|
||||||
|
|
||||||
Claude Code plugins need hooks that work on Windows, macOS, and Linux. This document explains the polyglot wrapper technique that makes this possible.
|
Claude Code plugins need hooks that work on Windows, macOS, and Linux. This document describes the single generic dispatcher pattern used in `hooks/run-hook.cmd`.
|
||||||
|
|
||||||
|
> **Authoritative source:** `hooks/run-hook.cmd` is the canonical implementation. When this document and the code diverge, trust the code.
|
||||||
|
|
||||||
## The Problem
|
## The Problem
|
||||||
|
|
||||||
@@ -10,52 +12,22 @@ Claude Code runs hook commands through the system's default shell:
|
|||||||
|
|
||||||
This creates several challenges:
|
This creates several challenges:
|
||||||
|
|
||||||
1. **Script execution**: Windows CMD can't execute `.sh` files directly - it tries to open them in a text editor
|
1. **Script execution**: Windows CMD can't execute `.sh` files directly
|
||||||
2. **Path format**: Windows uses backslashes (`C:\path`), Unix uses forward slashes (`/path`)
|
2. **Path format**: Windows uses backslashes (`C:\path`), Unix uses forward slashes (`/path`)
|
||||||
3. **Environment variables**: `$VAR` syntax doesn't work in CMD
|
3. **Environment variables**: `$VAR` syntax doesn't work in CMD
|
||||||
4. **No `bash` in PATH**: Even with Git Bash installed, `bash` isn't in the PATH when CMD runs
|
4. **`.sh` auto-prepend**: Claude Code on Windows automatically prepends `bash` to any command that contains `.sh` in its path — this interferes with the dispatcher if scripts have extensions
|
||||||
|
|
||||||
## The Solution: Polyglot `.cmd` Wrapper
|
## The Solution: Extensionless Scripts + Single Generic Dispatcher
|
||||||
|
|
||||||
A polyglot script is valid syntax in multiple languages simultaneously. Our wrapper is valid in both CMD and bash:
|
The repo uses one generic `run-hook.cmd` dispatcher for all hooks. Hook scripts are **extensionless** (`session-start`, not `session-start.sh`). This is deliberate: it prevents Claude Code's Windows auto-detection from prepending `bash` to the dispatcher command and breaking it.
|
||||||
|
|
||||||
```cmd
|
### File Structure
|
||||||
: << 'CMDBLOCK'
|
|
||||||
@echo off
|
|
||||||
"C:\Program Files\Git\bin\bash.exe" -l -c "\"$(cygpath -u \"$CLAUDE_PLUGIN_ROOT\")/hooks/session-start.sh\""
|
|
||||||
exit /b
|
|
||||||
CMDBLOCK
|
|
||||||
|
|
||||||
# Unix shell runs from here
|
|
||||||
"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh"
|
|
||||||
```
|
|
||||||
|
|
||||||
### How It Works
|
|
||||||
|
|
||||||
#### On Windows (CMD.exe)
|
|
||||||
|
|
||||||
1. `: << 'CMDBLOCK'` - CMD sees `:` as a label (like `:label`) and ignores `<< 'CMDBLOCK'`
|
|
||||||
2. `@echo off` - Suppresses command echoing
|
|
||||||
3. The bash.exe command runs with:
|
|
||||||
- `-l` (login shell) to get proper PATH with Unix utilities
|
|
||||||
- `cygpath -u` converts Windows path to Unix format (`C:\foo` → `/c/foo`)
|
|
||||||
4. `exit /b` - Exits the batch script, stopping CMD here
|
|
||||||
5. Everything after `CMDBLOCK` is never reached by CMD
|
|
||||||
|
|
||||||
#### On Unix (bash/sh)
|
|
||||||
|
|
||||||
1. `: << 'CMDBLOCK'` - `:` is a no-op, `<< 'CMDBLOCK'` starts a heredoc
|
|
||||||
2. Everything until `CMDBLOCK` is consumed by the heredoc (ignored)
|
|
||||||
3. `# Unix shell runs from here` - Comment
|
|
||||||
4. The script runs directly with the Unix path
|
|
||||||
|
|
||||||
## File Structure
|
|
||||||
|
|
||||||
```
|
```
|
||||||
hooks/
|
hooks/
|
||||||
├── hooks.json # Points to the .cmd wrapper
|
├── hooks.json # Points to run-hook.cmd with extensionless script name
|
||||||
├── session-start.cmd # Polyglot wrapper (cross-platform entry point)
|
├── run-hook.cmd # Cross-platform dispatcher (the polyglot wrapper)
|
||||||
└── session-start.sh # Actual hook logic (bash script)
|
└── session-start # Actual hook logic — extensionless bash script
|
||||||
```
|
```
|
||||||
|
|
||||||
### hooks.json
|
### hooks.json
|
||||||
@@ -65,11 +37,12 @@ hooks/
|
|||||||
"hooks": {
|
"hooks": {
|
||||||
"SessionStart": [
|
"SessionStart": [
|
||||||
{
|
{
|
||||||
"matcher": "startup|resume|clear|compact",
|
"matcher": "startup|clear|compact",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.cmd\""
|
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start",
|
||||||
|
"async": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -78,41 +51,63 @@ hooks/
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: The path must be quoted because `${CLAUDE_PLUGIN_ROOT}` may contain spaces on Windows (e.g., `C:\Program Files\...`).
|
The path is quoted because `${CLAUDE_PLUGIN_ROOT}` may contain spaces.
|
||||||
|
|
||||||
## Requirements
|
## How `run-hook.cmd` Works at a High Level
|
||||||
|
|
||||||
### Windows
|
`run-hook.cmd` is a polyglot script: Windows treats the first block as batch
|
||||||
- **Git for Windows** must be installed (provides `bash.exe` and `cygpath`)
|
commands, while Unix shells treat that block as a no-op heredoc and continue
|
||||||
- Default installation path: `C:\Program Files\Git\bin\bash.exe`
|
after it.
|
||||||
- If Git is installed elsewhere, the wrapper needs modification
|
|
||||||
|
|
||||||
### Unix (macOS/Linux)
|
Do not copy an implementation from this document. Read `hooks/run-hook.cmd`
|
||||||
- Standard bash or sh shell
|
directly when changing the dispatcher, and run `tests/hooks/test-session-start.sh`
|
||||||
- The `.cmd` file must have execute permission (`chmod +x`)
|
afterward.
|
||||||
|
|
||||||
|
### How it works on Windows (CMD.exe)
|
||||||
|
|
||||||
|
1. The batch section validates the script name and resolves the hook directory
|
||||||
|
from the dispatcher's own location.
|
||||||
|
2. It tries bash in three places:
|
||||||
|
- `C:\Program Files\Git\bin\bash.exe`
|
||||||
|
- `C:\Program Files (x86)\Git\bin\bash.exe`
|
||||||
|
- `bash` on `PATH` (MSYS2, Cygwin, or a non-default Git install)
|
||||||
|
3. If bash is found, it runs the named extensionless hook script from the hooks
|
||||||
|
directory.
|
||||||
|
4. If no bash is found, the dispatcher exits `0` silently — the plugin
|
||||||
|
continues working, it just skips the hook.
|
||||||
|
5. `exit /b` stops CMD before it reaches the Unix section.
|
||||||
|
|
||||||
|
### How it works on Unix (bash/sh)
|
||||||
|
|
||||||
|
1. `: << 'CMDBLOCK'` opens a heredoc on a no-op command.
|
||||||
|
2. The entire CMD batch block is consumed by the heredoc and ignored.
|
||||||
|
3. After `CMDBLOCK`, bash resolves the script directory and `exec`s the named
|
||||||
|
extensionless script directly.
|
||||||
|
|
||||||
|
### Key design decisions
|
||||||
|
|
||||||
|
| Decision | Why |
|
||||||
|
|----------|-----|
|
||||||
|
| Extensionless scripts | Prevents Claude Code's Windows `.sh`-auto-prepend from interfering with the dispatcher command |
|
||||||
|
| No `-l` (login shell) | Not needed; hook scripts should be self-contained and not depend on login-shell PATH setup |
|
||||||
|
| No `cygpath` | Bash receives the Windows path directly and handles it correctly; `cygpath` was needed by the old `-c "..."` invocation pattern, not by direct exec |
|
||||||
|
| Silent exit on no-bash | Avoids breaking the plugin for users who don't have Git for Windows; hook context injection is skipped gracefully |
|
||||||
|
|
||||||
## Writing Cross-Platform Hook Scripts
|
## Writing Cross-Platform Hook Scripts
|
||||||
|
|
||||||
Your actual hook logic goes in the `.sh` file. To ensure it works on Windows (via Git Bash):
|
Your hook logic goes in the extensionless script file. A few portable patterns:
|
||||||
|
|
||||||
### Do:
|
### Do
|
||||||
- Use pure bash builtins when possible
|
- Use pure bash builtins when possible
|
||||||
- Use `$(command)` instead of backticks
|
- Use `$(command)` instead of backticks
|
||||||
- Quote all variable expansions: `"$VAR"`
|
- Quote all variable expansions: `"$VAR"`
|
||||||
- Use `printf` or here-docs for output
|
|
||||||
|
|
||||||
### Avoid:
|
### Avoid
|
||||||
- External commands that may not be in PATH (sed, awk, grep)
|
- Relying on PATH-dependent tools without fallbacks (the hook runs without `-l`, so login-shell PATH is not set)
|
||||||
- If you must use them, they're available in Git Bash but ensure PATH is set up (use `bash -l`)
|
- Giving scripts a `.sh` extension — this triggers Claude Code's Windows auto-prepend
|
||||||
|
|
||||||
### Example: JSON Escaping Without sed/awk
|
### Example: JSON escaping without external tools
|
||||||
|
|
||||||
Instead of:
|
|
||||||
```bash
|
|
||||||
escaped=$(echo "$content" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | awk '{printf "%s\\n", $0}')
|
|
||||||
```
|
|
||||||
|
|
||||||
Use pure bash:
|
|
||||||
```bash
|
```bash
|
||||||
escape_for_json() {
|
escape_for_json() {
|
||||||
local input="$1"
|
local input="$1"
|
||||||
@@ -133,80 +128,21 @@ escape_for_json() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Reusable Wrapper Pattern
|
|
||||||
|
|
||||||
For plugins with multiple hooks, you can create a generic wrapper that takes the script name as an argument:
|
|
||||||
|
|
||||||
### run-hook.cmd
|
|
||||||
```cmd
|
|
||||||
: << 'CMDBLOCK'
|
|
||||||
@echo off
|
|
||||||
set "SCRIPT_DIR=%~dp0"
|
|
||||||
set "SCRIPT_NAME=%~1"
|
|
||||||
"C:\Program Files\Git\bin\bash.exe" -l -c "cd \"$(cygpath -u \"%SCRIPT_DIR%\")\" && \"./%SCRIPT_NAME%\""
|
|
||||||
exit /b
|
|
||||||
CMDBLOCK
|
|
||||||
|
|
||||||
# Unix shell runs from here
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
||||||
SCRIPT_NAME="$1"
|
|
||||||
shift
|
|
||||||
"${SCRIPT_DIR}/${SCRIPT_NAME}" "$@"
|
|
||||||
```
|
|
||||||
|
|
||||||
### hooks.json using the reusable wrapper
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"hooks": {
|
|
||||||
"SessionStart": [
|
|
||||||
{
|
|
||||||
"matcher": "startup",
|
|
||||||
"hooks": [
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start.sh"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"PreToolUse": [
|
|
||||||
{
|
|
||||||
"matcher": "Bash",
|
|
||||||
"hooks": [
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" validate-bash.sh"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### "bash is not recognized"
|
### "bash is not recognized"
|
||||||
CMD can't find bash. The wrapper uses the full path `C:\Program Files\Git\bin\bash.exe`. If Git is installed elsewhere, update the path.
|
|
||||||
|
|
||||||
### "cygpath: command not found" or "dirname: command not found"
|
CMD couldn't find bash in any of the three locations the dispatcher tries. The dispatcher exits silently (0) rather than erroring, so the hook is skipped. Install Git for Windows at the standard path or ensure `bash` is on `PATH`.
|
||||||
Bash isn't running as a login shell. Ensure `-l` flag is used.
|
|
||||||
|
|
||||||
### Path has weird `\/` in it
|
### Hook runs on Unix but does nothing on Windows
|
||||||
`${CLAUDE_PLUGIN_ROOT}` expanded to a Windows path ending with backslash, then `/hooks/...` was appended. Use `cygpath` to convert the entire path.
|
|
||||||
|
|
||||||
### Script opens in text editor instead of running
|
Check that the script filename is **extensionless** in `hooks.json`. A command like `run-hook.cmd session-start.sh` can trigger Claude Code's `.sh` auto-detection and bypass the intended CMD dispatcher path, or just try to run a non-existent `session-start.sh` script.
|
||||||
The hooks.json is pointing directly to the `.sh` file. Point to the `.cmd` wrapper instead.
|
|
||||||
|
|
||||||
### Works in terminal but not as hook
|
### Hook doesn't fire at all
|
||||||
Claude Code may run hooks differently. Test by simulating the hook environment:
|
|
||||||
```powershell
|
Verify the `matcher` in `hooks.json` matches the event type your harness emits. Claude Code uses `startup|clear|compact`; Codex uses `startup|resume|clear`. Check `hooks-codex.json` for the Codex variant.
|
||||||
$env:CLAUDE_PLUGIN_ROOT = "C:\path\to\plugin"
|
|
||||||
cmd /c "C:\path\to\plugin\hooks\session-start.cmd"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Related Issues
|
## Related Issues
|
||||||
|
|
||||||
- [anthropics/claude-code#9758](https://github.com/anthropics/claude-code/issues/9758) - .sh scripts open in editor on Windows
|
- [anthropics/claude-code#9758](https://github.com/anthropics/claude-code/issues/9758) — `.sh` scripts open in editor on Windows
|
||||||
- [anthropics/claude-code#3417](https://github.com/anthropics/claude-code/issues/3417) - Hooks don't work on Windows
|
- [anthropics/claude-code#3417](https://github.com/anthropics/claude-code/issues/3417) — Hooks don't work on Windows
|
||||||
- [anthropics/claude-code#6023](https://github.com/anthropics/claude-code/issues/6023) - CLAUDE_PROJECT_DIR not found
|
|
||||||
|
|||||||
@@ -107,10 +107,23 @@ if [[ -z "$OWNER_PID" || "$OWNER_PID" == "1" ]]; then
|
|||||||
OWNER_PID="$PPID"
|
OWNER_PID="$PPID"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Windows/MSYS2: Node.js cannot see POSIX PIDs from the MSYS2 namespace.
|
||||||
|
# Passing a PID node cannot verify causes server to log owner-pid-invalid
|
||||||
|
# and self-terminate at the 60-second lifecycle check. Clear it so the
|
||||||
|
# watchdog is disabled and the idle timeout becomes the only shutdown trigger.
|
||||||
|
case "${OSTYPE:-}" in
|
||||||
|
msys*|cygwin*|mingw*) OWNER_PID="" ;;
|
||||||
|
esac
|
||||||
|
if [[ -n "${MSYSTEM:-}" ]]; then
|
||||||
|
OWNER_PID=""
|
||||||
|
fi
|
||||||
|
|
||||||
# Foreground mode for environments that reap detached/background processes.
|
# Foreground mode for environments that reap detached/background processes.
|
||||||
if [[ "$FOREGROUND" == "true" ]]; then
|
if [[ "$FOREGROUND" == "true" ]]; then
|
||||||
echo "$$" > "$PID_FILE"
|
env BRAINSTORM_DIR="$SESSION_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" BRAINSTORM_OWNER_PID="$OWNER_PID" node server.cjs &
|
||||||
env BRAINSTORM_DIR="$SESSION_DIR" BRAINSTORM_HOST="$BIND_HOST" BRAINSTORM_URL_HOST="$URL_HOST" BRAINSTORM_OWNER_PID="$OWNER_PID" node server.cjs
|
SERVER_PID=$!
|
||||||
|
echo "$SERVER_PID" > "$PID_FILE"
|
||||||
|
wait "$SERVER_PID"
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -123,16 +123,6 @@ git branch -d <feature-branch>
|
|||||||
```bash
|
```bash
|
||||||
# Push branch
|
# Push branch
|
||||||
git push -u origin <feature-branch>
|
git push -u origin <feature-branch>
|
||||||
|
|
||||||
# Create PR
|
|
||||||
gh pr create --title "<title>" --body "$(cat <<'EOF'
|
|
||||||
## Summary
|
|
||||||
<2-3 bullets of what changed>
|
|
||||||
|
|
||||||
## Test Plan
|
|
||||||
- [ ] <verification steps>
|
|
||||||
EOF
|
|
||||||
)"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Do NOT clean up worktree** — user needs it alive to iterate on PR feedback.
|
**Do NOT clean up worktree** — user needs it alive to iterate on PR feedback.
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ If CLAUDE.md, GEMINI.md, or AGENTS.md says "don't use TDD" and a skill says "alw
|
|||||||
|
|
||||||
## Platform Adaptation
|
## Platform Adaptation
|
||||||
|
|
||||||
Skills speak in actions ("dispatch a subagent", "create a todo", "read a file") rather than naming any one runtime's tools. For per-platform tool equivalents and instructions-file conventions, see [claude-code-tools.md](references/claude-code-tools.md), [codex-tools.md](references/codex-tools.md), [copilot-tools.md](references/copilot-tools.md), [gemini-tools.md](references/gemini-tools.md), and [pi-tools.md](references/pi-tools.md). Gemini CLI users get the tool mapping loaded automatically via GEMINI.md.
|
Skills speak in actions ("dispatch a subagent", "create a todo", "read a file") rather than naming any one runtime's tools. For per-platform tool equivalents and instructions-file conventions, see [claude-code-tools.md](references/claude-code-tools.md), [codex-tools.md](references/codex-tools.md), [copilot-tools.md](references/copilot-tools.md), [gemini-tools.md](references/gemini-tools.md), [pi-tools.md](references/pi-tools.md), and [antigravity-tools.md](references/antigravity-tools.md). Gemini CLI users get the tool mapping loaded automatically via GEMINI.md.
|
||||||
|
|
||||||
# Using Skills
|
# Using Skills
|
||||||
|
|
||||||
|
|||||||
96
skills/using-superpowers/references/antigravity-tools.md
Normal file
96
skills/using-superpowers/references/antigravity-tools.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# Antigravity CLI (`agy`) Tool Mapping
|
||||||
|
|
||||||
|
Skills speak in actions ("dispatch a subagent", "create a todo", "read a file"). On the Antigravity CLI (`agy`) these resolve to the tools below.
|
||||||
|
|
||||||
|
| 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 (`spec-reviewer`, `code-quality-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 / `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`,
|
||||||
|
`ArtifactMetadata.ArtifactType: "task"`), edited with `replace_file_content` /
|
||||||
|
`multi_replace_file_content` as you go.
|
||||||
|
|
||||||
|
At the start of any multi-step task, create the task artifact listing every step of
|
||||||
|
your plan. As you complete each step, edit the artifact to mark it done (`- [x]`).
|
||||||
|
If the plan changes, update the checklist. Keep it current — it is your source of
|
||||||
|
truth for what remains; once the conversation gets long, re-read it before starting
|
||||||
|
each step.
|
||||||
16
tests/antigravity/run-tests.sh
Executable file
16
tests/antigravity/run-tests.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Run all Antigravity (agy) integration tests.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
echo "=== Antigravity integration tests ==="
|
||||||
|
|
||||||
|
for t in "$SCRIPT_DIR"/test-*.sh; do
|
||||||
|
echo
|
||||||
|
echo ">>> $t"
|
||||||
|
bash "$t"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=== All Antigravity tests passed ==="
|
||||||
53
tests/antigravity/test-antigravity-tools.sh
Executable file
53
tests/antigravity/test-antigravity-tools.sh
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Validate the Antigravity (agy) integration. agy installs the existing plugin
|
||||||
|
# directly (`agy plugin install <repo-url>`): it loads the bundled skills and
|
||||||
|
# runs the SessionStart hook for bootstrap, so there is no agy-specific scaffold
|
||||||
|
# to test. What IS agy-specific is the tool mapping — agy has no `Skill` tool and
|
||||||
|
# loads skills by reading SKILL.md with view_file — and SKILL.md pointing at it.
|
||||||
|
#
|
||||||
|
# Mirrors tests/pi/test-pi-extension.mjs's "tools reference documents
|
||||||
|
# harness-specific mappings" check. CI-safe: does not require `agy` installed.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
|
||||||
|
MAPPING="$REPO_ROOT/skills/using-superpowers/references/antigravity-tools.md"
|
||||||
|
SKILL="$REPO_ROOT/skills/using-superpowers/SKILL.md"
|
||||||
|
|
||||||
|
fail() { echo "FAIL: $*" >&2; exit 1; }
|
||||||
|
|
||||||
|
echo "test-antigravity-tools: checking Antigravity tool mapping"
|
||||||
|
|
||||||
|
# --- Mapping exists ---------------------------------------------------------
|
||||||
|
[ -f "$MAPPING" ] || fail "tool mapping missing at $MAPPING"
|
||||||
|
|
||||||
|
# --- Skill-load mechanism: view_file on SKILL.md (IsSkillFile), no Skill tool -
|
||||||
|
grep -qiE "view_file" "$MAPPING" \
|
||||||
|
|| fail "mapping does not document view_file as the file/skill-read tool"
|
||||||
|
grep -qiE "SKILL\.md" "$MAPPING" \
|
||||||
|
|| fail "mapping does not document reading SKILL.md as the skill-load path"
|
||||||
|
grep -q "IsSkillFile" "$MAPPING" \
|
||||||
|
|| fail "mapping does not document setting IsSkillFile when loading a skill"
|
||||||
|
|
||||||
|
# --- Core action→tool mappings are documented -------------------------------
|
||||||
|
for tool in write_to_file replace_file_content run_command grep_search invoke_subagent; do
|
||||||
|
grep -q "$tool" "$MAPPING" \
|
||||||
|
|| fail "mapping does not document the '$tool' tool"
|
||||||
|
done
|
||||||
|
|
||||||
|
# --- Subagents use the built-in self/research types -------------------------
|
||||||
|
grep -q '`self`' "$MAPPING" \
|
||||||
|
|| fail "mapping does not document the built-in 'self' subagent type"
|
||||||
|
grep -q '`research`' "$MAPPING" \
|
||||||
|
|| fail "mapping does not document the built-in 'research' subagent type"
|
||||||
|
|
||||||
|
# --- Task tracking documents the 'task' artifact mechanism ------------------
|
||||||
|
grep -qE 'ArtifactType.*task|task. artifact' "$MAPPING" \
|
||||||
|
|| fail "mapping does not document task tracking as a 'task' artifact"
|
||||||
|
|
||||||
|
# --- SKILL.md Platform Adaptation links the mapping -------------------------
|
||||||
|
grep -q "antigravity-tools.md" "$SKILL" \
|
||||||
|
|| fail "SKILL.md Platform Adaptation does not reference antigravity-tools.md"
|
||||||
|
|
||||||
|
echo "PASS: Antigravity tool mapping valid (view_file skill-load, agy tools, SKILL.md link)"
|
||||||
Reference in New Issue
Block a user