Forward-port #2911 for #2909 and exercise the real adapter lifecycle with a recorded process boundary, including unavailable Node and invalid overrides. Co-authored-by: DavidHLP <lysf15520112973@163.com>
8.9 KiB
.pi — Pi Coding Agent Integration
This directory contains the Pi adapter for ECC — a thin extension that connects the @earendil-works/pi-coding-agent terminal coding agent to ECC's canonical skills, prompts, and lifecycle hooks.
Design Principle
ECC's canonical assets—skills, agents, commands, and hooks—remain the single source of truth. This adapter contains only the integration logic. No copies, no duplication.
What This Provides
- ECC's skills from
./skills/— available in Pi as/skill:<name> - ECC's commands from
./commands/— available in Pi as/<name> - ECC's engineering rules from
./rules/common/— injected into Pi's system prompt on every turn, so coding style, testing, security, git workflow, and code-review standards apply in Pi as they do in other harnesses - Session lifecycle hooks — ECC's SessionStart and SessionEnd hooks, run through ECC's own
run-with-flags.js, soECC_HOOK_PROFILEandECC_DISABLED_HOOKSkeep working under Pi - Session context injection — whatever ECC's SessionStart hook returns as
additionalContextis folded into Pi's system prompt for the next turn /ecc-doctor— diagnostic command to verify the integration
Verified against Pi 0.84.1: a global install exposes 285 skills and 94 commands, resolved
directly from skills/ and commands/, with no generated copies.
Installation
Option 1: Global Installation (Recommended)
# Install ECC as a Pi package
pi install git:github.com/affaan-m/ECC
# Or from a local checkout
pi install /path/to/ECC
# Or project-local only
pi install -l /path/to/ECC
# Verify
pi list
Then inside Pi, run /ecc-doctor to confirm skills, commands, and hooks are available.
To uninstall:
pi remove git:github.com/affaan-m/ECC
Option 2: Zero-Install (Existing Claude Code Users)
If you already have ECC installed for Claude Code, point Pi at the same canonical directories
from ~/.pi/agent/settings.json:
{
"skills": ["~/.claude/skills"],
"prompts": ["~/.claude/commands"]
}
This gives you skills and commands directly. It does not include the lifecycle hook adapter
or /ecc-doctor — use Option 1 for the full integration.
How It Works
The extensions/index.ts file handles:
- Skill and command mounting — Pi reads
./skillsand./commandsdirectly via thepikey inpackage.json. No transformation is needed: ECC'sSKILL.mdfiles already follow the Agent Skills standard Pi implements, and ECC's command frontmatter (description,argument-hint) is already Pi's prompt-template format - Lifecycle hooks — Maps Pi's
session_startto ECC'ssession:starthook (scripts/hooks/session-start.js) and Pi'ssession_shutdownto ECC'ssession:end:markerhook (scripts/hooks/session-end-marker.js), both invoked throughscripts/hooks/run-with-flags.jsso ECC's profile and disable flags are honored - Rule injection — Reads ECC's portable engineering rules from the canonical
rules/common/directory at runtime and appends them to the system prompt inside an<ecc-engineering-rules>block on every turn. Nothing is copied into.pi/.agents.md,hooks.md, andperformance.mdare excluded on purpose: they describe Claude Code primitives Pi does not have (Task/TodoWrite delegation, Claude hook event types, thinking-budget toggles), so injecting them would point the model at tools that are not there. Language-specific rules underrules/<language>/are not injected in this first adapter. SetECC_PI_RULESto0,false,off,none, ordisabledto turn injection off;/ecc-doctorreports the current state and the injected size - Context injection — Parses
hookSpecificOutput.additionalContextfrom the SessionStart hook and appends it to the system prompt on the nextbefore_agent_start, wrapped in an<ecc-session-context>block. Non-JSON hook output is tolerated, not treated as an error - Hook isolation — Failing, missing, slow, or misconfigured hooks degrade to a warning and never terminate the Pi session. Hook execution is bounded by a timeout and an output limit
- Package resolution — Resolves hook scripts from the installed package via
__dirname, never fromprocess.cwd(), so a global install works from any project directory. Hooks still run in the user's project directory, so project detection stays correct
All hook execution is non-shell (execFile without shell interpretation), so paths containing
spaces, tabs, or shell metacharacters are safe.
Hook runtime selection uses the host process.execPath only under Node.
Without an override, compiled OMP/Bun falls back to node instead of
recursively launching the OMP binary as a hook runner. Set ECC_HOOK_NODE to
an explicit absolute Node executable path when node is not available on
PATH.
Relative values are rejected when the hook runs and surfaced as a warning.
Scope
Intentionally out of scope for this first adapter (to be added independently):
- Subagent conversion and chains (need the
pi-subagentscompanion package) - Structured approval gates (need
@juicesharp/rpiv-ask-user-question) - Persistent todos (need
@juicesharp/rpiv-todo) - Profile-based resource filtering
- MCP translation — see below; no translation turned out to be necessary
ECC works in Pi without any of these. Skills and commands are fully available today.
These capabilities are provided by existing community Pi packages rather than by
anything ECC would need to write. This adapter deliberately does not bundle or
auto-install them: bundling would ship third-party code that executes with full
user permissions in every ECC install, and would make optional capabilities
mandatory. Install whichever you want yourself — /ecc-doctor reports which are
present and prints the exact pi install command for the ones that are not.
MCP
Pi core has no MCP surface by design. The community pi-mcp-adapter package
adds one, and it reads the standard mcpServers format from .mcp.json and
~/.config/mcp/mcp.json — which is exactly the format ECC already uses in
.mcp.json and mcp-configs/mcp-servers.json.
Verified against pi-mcp-adapter 2.21.2: copying ECC's mcp-configs/mcp-servers.json
to a project's .mcp.json registers Pi's mcp tool and /mcp command with all
35 ECC servers discovered, alongside this adapter's own /ecc-doctor. No
translation layer is needed and no ECC change is required.
pi install npm:pi-mcp-adapter
cp mcp-configs/mcp-servers.json /path/to/project/.mcp.json
ECC neither installs nor depends on that package. Two caveats: the adapter's
first run against a new config performs initialization that blocks in
non-interactive (-p) mode, so run it once interactively before using it
headless; and only server discovery was verified, not live tool invocation,
which needs real credentials for each server.
Security
- Pi extensions run with the same OS permissions as the Pi process
- This adapter does not auto-commit, push, merge, or deploy
- Hooks are executed without a shell, preventing command injection
- Hook failures are isolated and cannot silently authorize blocked operations
Troubleshooting
Skills or commands not showing up
Cause: the package's resources are disabled, or a project-local install has not been
trusted. Pi asks before trusting a project folder that carries its own .pi/ resources.
Fix: run pi config and confirm the ECC package's skills and prompts are enabled
(Tab switches between user and project scope). Then confirm the package itself is
registered with pi list.
/ecc-doctor not found or reports missing package root
Cause: Extension not loaded or package installed incorrectly.
Fix:
- Run
pi listto confirm ECC is registered - Restart Pi: exit and reopen the session
- Run
/ecc-doctoragain
/ecc-doctor prints the resolved package root, the skill and command counts it found, the
hook runner path, the active hook profile, and which optional companion packages are present.
A NOT FOUND line points at the specific path that failed to resolve.
Hooks not firing
Cause: the extension is not loaded, or the hooks are gated off by an ECC hook profile.
Fix:
- Confirm
pi listshows ECC and that/ecc-doctorreports the hook runner as found - Check
ECC_HOOK_PROFILEandECC_DISABLED_HOOKS—/ecc-doctorprints both. A hook listed inECC_DISABLED_HOOKSis skipped by design - Restart Pi so the extension reloads
Notes
- The
.pi/extensions/directory is the only place for adapter code - Skills and commands are defined in the repo root (
skills/,commands/) and referenced by Pi - MCP is not bundled, but ECC's MCP configs load in Pi through the community
pi-mcp-adapter— see MCP above - This adapter was tested against Pi v0.84.1