pi-code

extensionmaintained

Claude Code experience for the pi coding agent: reads your .claude config (rules, commands, skills, hooks, output styles, MCP servers, agents) and adds todo, checkpoints, memory, web, and subagents

by · v1.0.2 · published 2d ago

$ pi install npm:pi-code
downloads/mo
0
stars
5
last push
2d ago
open issues
1

Signals

license: MITtestspi manifest: missinginstall size: —deps: 0peer deps: 0

Download trend

3.1K downloads · last 12 weeks (weekly)

README

pi-code

npm npm GitHub
Coverage Quality Gate Status
Reliability Rating Maintainability Rating Security Rating

Claude Code experience for the pi coding agent, in one package. Point pi at a project that already has a .claude/ directory and it reads your existing config: rules, commands, skills, hooks, output styles, MCP servers, and agents. It also adds the Claude Code features pi lacks: a todo overlay, checkpoints, memory, web search, and subagents.

What a repository ships is treated as untrusted until you approve it: project MCP servers, hooks, agents, rules, output styles, commands and skills load only once you say yes.

pi-code demo

Install

pi install npm:pi-code       # from npm
pi install -l npm:pi-code    # project-local instead, writes .pi/settings.json

Other sources:

pi install git:github.com/ilovepixelart/pi-code
pi install ./pi-code         # local checkout, then /reload after edits

One pi install and everything below loads on the next start. pi list shows what is installed, pi config toggles individual resources, and pi update pi-code upgrades it. Each feature is an extension under extensions/.

What it does

FeatureReads / providesExtension
Global + project rules~/.claude/rules, .claude/rules (+ paths: frontmatter scoping)claude-rules.ts
Custom slash commands.claude/commands/**/*.md (namespaced /dir:name), $ARGUMENTS/$1, !`cmd` bash output, @file inlining, allowed-tools/argument-hint frontmatter (model is parsed but not yet applied); project commands gated on approvalcommands.ts
Skills.claude/skills → pi skill discovery, project skills gated on approval (pi reads name, description, disable-model-invocation; allowed-tools is inert in pi's loader)skills.ts
Hooks.claude/settings.json hooks: PreToolUse (blocks, rewrites input via updatedInput), PostToolUse (feedback and additionalContext land next to the tool result), PostToolUseFailure, SessionStart (context injection), UserPromptSubmit (blocks and injects context), Stop (a block continues the conversation), SubagentStart/SubagentStop, PreCompact, PostCompact, SessionEnd; Claude matcher semantics incl. mcp__server__tool names; payloads carry session_id, transcript_path, cwd, permission_mode, efforthooks.ts
Output styles.claude/output-styles + active outputStyle; Claude replace semantics with keep-coding-instructions; bundled Explanatory/Learning/Proactive; /output-style [name]output-styles.ts
CLAUDE.md @importsresolves @path imports pi's native loader skips; loads CLAUDE.local.md (approval-gated)context-imports.ts
MCP serversuser ~/.claude.json (incl. per-project projects[cwd] local scope), ~/.pi/agent/mcp.json; project .mcp.json, .pi/mcp.json (once approved; enabledMcpjsonServers/disabledMcpjsonServers/enableAllProjectMcpServers honored, consent keys only from non-repo settings); stdio/HTTP/SSE by type; ${VAR:-default} expansion; MCP_TIMEOUT/MCP_TOOL_TIMEOUT; tools refresh on list_changedmcp.ts
Project trustprompts before loading project config (MCP servers, hooks, agents, rules, output styles, commands, skills) that pi would otherwise trust silentlyinternal/project-approval.ts
Subagents / Taskbuiltin Explore/Plan/general-purpose agents, ~/.claude/agents and ~/.pi/agent/agents, plus project .claude/agents and .pi/agents; agent roster with descriptions in the system prompt; skills preload; background runs with cancel and resumesubagent/
Plan modeplan_mode_complete tool, exact tool snapshot/restoreplan-mode/
Todo listpersistent overlay, status machine, compaction-safetodo.ts
Checkpoints / rewindshadow-repo snapshots; restore overwrites checkpointed files, keeps files created later; 100 per session, repos pruned after 30 daysgit-checkpoint.ts
Persistent memoryper-project memories, index injected each session within Claude's 200-line/25KB bound; a save that would overflow it reports whymemory.ts
WebSearch / WebFetchkey-free DuckDuckGo search, SSRF-guarded fetchweb.ts
AskUserQuestion1-4 questions per call (asked in sequence), each with header, single- or multiSelect options, plus free-textquestion.ts
StatuslineClaude statusLine command contract (stdin JSON, padding, refreshInterval); built-in turn state + session cost fallbackstatus-line.ts
Notificationsvendored examplenotify.ts

CLAUDE.md itself needs no extension: pi loads CLAUDE.md / AGENTS.md context files natively (global + walking cwd to root). context-imports.ts only adds the @import resolution pi's loader lacks, appending the imported files without re-injecting the base.

extensions/internal/ holds shared modules pi's loader must not treat as extensions: output-guard.ts (context-budget truncation), web-transport.ts (DNS-pinned fetch), project-approval.ts (the trust decision above), command-file.ts (slash-command parsing and dynamic content), and the shared-bus contracts mcp-alias.ts, plan-mode-state.ts and subagent-events.ts. The extensions use them; only internal/ keeps them out of pi's extension scan.

Vendored bases (question, notify, status-line) come from pi's MIT example extensions (see LICENSE).

Development

npm install
npm run check           # biome + strict tsc + vitest, the whole gate
scripts/e2e.sh          # quick smoke of the real pi TUI via tmux (needs a working model)
scripts/e2e-full.sh     # every README feature end to end, model turns included (5-15 min)
scripts/record-demos.sh # re-records demos/*.tape with vhs at low thinking

Extensions live in extensions/, tests in tests/. Install a local checkout with pi install ./pi-code, then /reload after edits.