Pi extension that replicates the obra/superpowers hooks/session-start bash hook for the Pi coding agent.
Pi has no SessionStart hook concept, so this extension performs the equivalent context injection in TypeScript via Pi's extension API.
On the first user prompt of each session, the extension:
- Locates the obra/superpowers plugin root via auto-discovery (see below).
- Reads
skills/using-superpowers/SKILL.mdfrom that plugin. - Detects whether a subagent tool is registered in the current session (see subagent detection).
- Appends an
<EXTREMELY_IMPORTANT>block to the system prompt containing:- The verbatim
using-superpowersSKILL.md content - A Pi platform-adapter section with a Claude Code → Pi tool-name mapping, tailored to whether subagent dispatch is available
- The verbatim
The injection happens once per session via the before_agent_start event. State is reset on session_shutdown so resume / reload re-inject correctly.
This makes superpowers skills (TDD, brainstorming, debugging workflows, code review, etc.) work in Pi the same way they work in Claude Code, Cursor, and Copilot CLI.
# 1. Install the original superpowers plugin (provides the skills)
pi install https://github.com/obra/superpowers
# 2. Install this hook
pi install git:github.com/stormreply/pi-superpowers-hookBoth can be installed project-locally instead of globally with the -l flag:
pi install -l https://github.com/obra/superpowers
pi install -l git:github.com/stormreply/pi-superpowers-hookTo try without persisting:
pi -e git:github.com/stormreply/pi-superpowers-hookAfter installing both packages, run:
pi -p "Does your system prompt contain the literal string '<EXTREMELY_IMPORTANT>'? Reply YES or NO only."Expected output: YES. The agent should now also list superpowers skills (brainstorming, test-driven-development, etc.) in its <available_skills> block.
If the hook cannot find the superpowers plugin, you will see a warning notification on session start and the extension becomes a no-op.
Search order, first match with skills/using-superpowers/SKILL.md wins:
<cwd>/.pi/git/github.com/obra/superpowers— project-local pi install~/.pi/agent/git/github.com/obra/superpowers— global pi install~/.claude/plugins/superpowers— parallel Claude Code setup
The injected block appends a tool-name mapping table to bridge Claude Code conventions to Pi:
| Claude Code | Pi |
|---|---|
| Skill | read (on the skill's SKILL.md path) |
| Read | read |
| Write | write |
| Edit | edit |
| Bash | bash |
| Grep | bash with rg |
| Glob | bash with find or rg --files |
| TodoWrite | (use the todo extension if installed, else track inline) |
| Task tool | the detected subagent tool, or marked unavailable |
Skills are auto-discovered from the cloned superpowers skills/ directory by Pi's package system and listed in the system prompt's <available_skills> block. The agent invokes a skill by read-ing its location path.
Three superpowers skills require subagent dispatch and have no standalone fallback:
subagent-driven-developmentdispatching-parallel-agentsrequesting-code-review
The hook detects a subagent tool at before_agent_start via pi.getAllTools(), in this priority order:
PI_SUPERPOWERS_SUBAGENT_TOOLenv var, if set and matches a registered tool- A tool literally named
subagent
If your subagent extension registers a tool with a different name, set PI_SUPERPOWERS_SUBAGENT_TOOL=<tool-name> before launching pi.
When detected, the adapter block enables those three skills, maps Claude Code's Task tool to the detected tool name, and documents single / parallel / chain invocation patterns plus the standard worker / reviewer builtin agent roster.
When not detected, the adapter block explicitly tells the agent to skip those three skills and to choose the Inline Execution path in writing-plans instead of the subagent-driven path.
Verified compatible subagent extensions (both register a tool named subagent):
nicobailon/pi-subagents—pi install npm:pi-subagents- The official
subagentexample in@mariozechner/pi-coding-agent/examples/extensions/subagent/
In child subagent sessions spawned by pi-subagents, the subagent tool is intentionally absent, so the hook automatically emits the no-subagent adapter block and the child does not attempt to recurse.
The hook reads four optional env vars from process.env:
| Var | Effect |
|---|---|
PI_SUPERPOWERS_DISABLE |
Any non-empty value: extension becomes a no-op for the entire session (no discovery, no injection, no notifications). |
PI_SUPERPOWERS_PLUGIN_ROOT |
Path used as the highest-priority discovery candidate. Relative paths are resolved against the session's cwd; absolute paths are used as-is. Must contain skills/using-superpowers/SKILL.md to qualify. Empty/whitespace is ignored. |
PI_SUPERPOWERS_DEBUG |
Any non-empty value: writes one `[pi-superpowers] injected bytes from , subagentTool=<name |
PI_SUPERPOWERS_SUBAGENT_TOOL |
Override the auto-detected subagent tool name (see Subagent detection). |
Truthy = any non-empty trimmed string. Empty, whitespace, and unset all count as off.
Examples:
# A/B test the agent without superpowers context for one session
PI_SUPERPOWERS_DISABLE=1 pi -p "compare with vs without superpowers"
# Use a development checkout of the plugin
PI_SUPERPOWERS_PLUGIN_ROOT=~/code/superpowers pi
# Trace what the hook injected on each turn
PI_SUPERPOWERS_DEBUG=1 pi 2> /tmp/pi-superpowers-debug.lognpm install
npm test # vitest run (28 tests)
npm run build # tsup → dist/index.js (ESM)
npm run typecheck # tsc --noEmitSource layout:
src/discovery.ts—findPluginRoot()with dependency-injectedhomeDirfor testabilitysrc/detect.ts—detectSubagentTool()pure function, dependency-injectedtoolsandenvsrc/inject.ts—buildContext()reads SKILL.md and builds the injection block (subagent-aware adapter)src/index.ts— Extension entry: hookssession_start,before_agent_start,session_shutdowntest/— vitest tests using real fs viamkdtemp
See docs/plans/2026-05-06-pi-superpowers-hook-design.md for the full design document.
MIT