JC

jean-couscous/pi-agent

Developer tools
0 stars Quality 57 Trend 20

A Pi coding-agent configuration that runs scripted tool pipelines, ships a personal skill library, and gives each project its own Git identity without touching the global gitconfig.

Overview

A Pi coding-agent configuration that runs scripted tool pipelines, ships a personal skill library, and gives each project its own Git identity without touching the global gitconfig. Pi (@earendil-works/pi-coding-agent) is a terminal coding agent. This repository is a configuration layer on top of an installed Pi: everything Pi loads for every session lives here as files, so the agent's behavior is versionable and reviewable instead of being typed into a chat. Pi's own install, launcher and package directories are not part of this repo. The extensions here were ported from the user-level Claude Code configuration in Jean-Couscous/claude-code. Pi's own runtime directories (install/, bin/, npm/), local state (sessions/, auth.json, github-accounts.json, git/config, trust.json, models-store.json) and tool output (.playwright-mcp/) are not tracked. They belong to the installed Pi or to the machine, and .gitignore keeps them out. See Secrets. 1. On each agent run, extensions/agent-rules.

README

Pi agent configuration

Last reviewed: 2026-10-16

A Pi coding-agent configuration that runs scripted tool pipelines, ships a personal skill library, and gives each project its own Git identity without touching the global gitconfig.

Pi (@earendil-works/pi-coding-agent) is a terminal coding agent. This repository is a configuration layer on top of an installed Pi: everything Pi loads for every session lives here as files, so the agent’s behavior is versionable and reviewable instead of being typed into a chat. Pi’s own install, launcher and package directories are not part of this repo. The extensions here were ported from the user-level Claude Code configuration in Jean-Couscous/claude-code.

What’s here

Path Purpose
APPEND_SYSTEM.md Global instructions loaded into every session
rules/ Seven topic rules, injected into the system prompt on each run
skills/ 39 personal skills in the Agent Skills format
prompts/ Reusable / commands (/rules)
extensions/ Pi extensions: recap (algorithmic conversation compactor), orchestration, recall, transfers, call watchers, Git identity, image previews, advisor, one-liner tool rendering, thinking icon, candy footer
orchestrate/ Python backend behind the orchestrate tool (run.py, cc_tools.py)
install.py Bootstraps this whole setup onto a new machine (see Reusing it)
uninstall.py reverses install.py: backs up, removes the config, and (by default) Pi too (see Reusing it)
settings.json Pi settings: model, env vars, and the extension/skill/prompt lists
mcp.json MCP server definitions (playwright browser tools, Context7 library docs)

Pi’s own runtime directories (install/, bin/, npm/), local state (sessions/, auth.json, github-accounts.json, git/config, trust.json, models-store.json) and tool output (.playwright-mcp/) are not tracked. They belong to the installed Pi or to the machine, and .gitignore keeps them out. See Secrets.

The workflow

A session moves through four layers.

  1. Instructions load. On each agent run, extensions/agent-rules.ts reads every rules/*.md file, appends it to the system prompt, and APPEND_SYSTEM.md is already in context. Rules stay the single source of truth.

  2. A skill is picked. Pi lists the skills/*/SKILL.md descriptions to the model. When the task matches one (Android, Discord bots, userstyles, git/GitHub, READMEs, orchestration, and so on), the model loads that skill’s full text and follows it. Skills are loaded lazily, so the library can be large without bloating every session.

  3. Work is done. For a step that depends on the previous result, the agent uses a normal tool. For a known-in-advance pipeline — loop over files, bulk grep, fetch many URLs, aggregate output — it calls the orchestrate tool once. That runs a Python or shell script, and only the script’s stdout returns to the conversation, capped at 50 KB with the full text left in a temp file. Helper functions in cc_tools.py (read_file, search_files, terminal, web_extract, llm, delegate, …) do the actual work inside the script, under a budget of 200 tool calls (ORCHESTRATE_MAX_CALLS) and $0.50 per delegate (ORCHESTRATE_MAX_USD).

  4. Side layers run in parallel. The watcher extensions count MCP calls; subagent-watch is kept for subagent counting but is not implemented yet, since Pi exposes no subagent tool to count. transfers handles downloads and archives, reporting progress while they run. Git identity is separate: at session start github-account writes ~/.pi/agent/git/config for the project’s account and points GIT_CONFIG_GLOBAL and GH_CONFIG_DIR at it, so every git and gh call the agent makes is attributed correctly with no change to the user’s own ~/.gitconfig.

    Two more tools sit at the same layer. The model can consult the advisor tool for a strategic second opinion: the call sends the current conversation to GLM-5.3 while the executor keeps working at GLM-5.3-flash rates, and the advice comes back as the tool result. Every image the session sees is numbered [image N]: an image path typed or pasted into the prompt (like the CLI’s @path flag) is attached and the path text itself is replaced by a plain [image N] in your message, a read result renders its numbered marker instead of the picture, and /image opens any counted image in the system default viewer with no dependence on terminal image support.

    What the transcript shows is kept short. tool-oneliner.ts re-renders the built-in read/bash/edit/write/find/grep/ls results as one gradient summary line (ctrl+o expands the raw output), and the advisor and sideroom_ask tools render the same way from the shared helper in extensions/lib/oneliner.ts. When thinking is hidden, thinking-icon.ts replaces the “Thinking…” placeholder with a static star; Pi offers no per-message placeholder to animate, only a shared one, so the icon stays still.

Past conversations are searchable too: recall_search and recall_list scan the JSONL transcripts under sessions/. Inside the current session, extensions/recap.ts owns the context window: it overwrites /compact outright (focus text included — the same overwrite pi-vcc used) and every automatic compaction. Instead of Pi’s LLM-written summary it stamps a structured recap — session goal, files touched, commits, unresolved context, user preferences, then a one-line-per-action brief — built purely by extraction, deterministically, in milliseconds. /recap runs one on demand, /recap-search queries old context in chat, and the recap_recall tool searches anything compacted away directly (#N refs in a summary jump straight to it). /recap alone can still shape a summary when needed; compaction config lives in recap-config.json (untracked), where overrideDefaultCompaction: false hands /compact back to Pi core.

Commands

Slash commands contributed by the extensions:

Command What it does
/run Run an orchestration script (same as the orchestrate tool)
/gh-account [status|list|use|default|off|add|remove] Manage the per-project Git identity
/mcp-stats Show MCP call and failure counts for the session
/subagent-stats Subagent counters, not implemented yet (Pi exposes no subagent tool, so it reports 0)
/image Open the image shown as [image N] in the system default viewer
/rules Prompt that reads and summarizes the active rules
/candy Toggle the eye-candy footer (colored pills for model, context meter, tokens/cost, git branch)

Requirements

Tool Why Required
Node.js ≥ 22.19.0 Pi runtime Yes
Python 3 orchestrate backend Yes, for orchestration
ripgrep (rg) search_files inside scripts Yes, for orchestration
aria2c or curl/wget download tool One of them
7-Zip, zip or tar archive / extract tools One of them

Reusing it

The bootstrap installer

install.py sets the whole workflow up from scratch on a new machine, including the npm package declared in settings.json:

# From GitHub, onto the default agent directory (creates ~/.pi/agent on top of
# Pi's runtime); needs Node.js, git and Python 3 in some form
curl -fsSL https://raw.githubusercontent.com/Jean-Couscous/pi-agent/main/install.py -o install.py
python install.py
# Or from an existing checkout of this repo
python install.py --dir ~/.pi/agent

The script checks helper tools (installs them only with --install-system-deps, otherwise prints the commands), installs Pi through the official installer when pi is missing, copies only tracked files so nothing of this machine lands in the new one, npm-installs extensions/sideroom-ask’s dependencies, links extensions/lib against the installed Pi release (typebox included, for the recap core tests), reconciles the npm packages named in settings.json (none today — compaction ships locally in extensions/recap.ts), and reports the two credential files (auth.json, github-accounts.json) it refuses to move on its own. Pass --secrets-from on the old machine’s directory — or copy those two files by hand — to carry the provider keys and Git identities over. Per-machine data (trust.json, sessions/, models-store.json) and Pi’s runtime (install/, bin/, npm/) are never replicated, which is deliberate.

Useful flags:

Flag Effect
--dir PATH install into another agent directory instead of ~/.pi/agent
--update pull the latest config into an already-deployed checkout and reconcile packages
--force overwrite an existing foreign config (timestamped backup first)
--secrets-from PATH copy auth.json, github-accounts.json, mcp-auth.json from a previous setup
--install-system-deps let the script install git/ripgrep/7zip etc. via the system package manager
--skip-pi-install / --skip-packages leave Pi or the npm packages alone

Uninstalling

uninstall.py takes it back off. It first asks for confirmation, then packs a verified backup archive (pi-agent-removed-.zip / .tar.gz, one level above the agent dir) holding every config file plus the deployment’s .git — deleting only after that archive reopens with the expected entry count. The removal covers the tracked config files, the .git, the local dependency folders, the npm package directory, and Pi’s regenerated artifacts (models-store.json, git/config, .playwright-mcp/, recap-config.json); empty folders are pruned away.

By default it also removes Pi itself, matching how it got there: an installer-managed pi has its runtime (install/, bin/, npm/) deleted and the leftover PATH entry reported — the interactive official installer (run it again, choose Uninstall Pi) is the only thing that cleans that up — while an npm-installed pi is removed with npm uninstall -g @earendil-works/pi-coding-agent. --config-only keeps Pi and just strips the config layer.

Personal data is never removed, only listed: auth.json, github-accounts.json, mcp-auth.json, trust.json, sessions/, plus the credentials that live outside the agent dir (~/.config/claude-git/credentials, ~/.config/claude-gh). Tools installed with --install-system-deps (ripgrep, 7-Zip, curl, aria2) are deliberately left installed.

python uninstall.py              # asks, then removes config + Pi
python uninstall.py --config-only   # strip the config, keep Pi working

If Pi is installed elsewhere, PI_CODING_AGENT_DIR points it at this config directory. Reload a running session after editing extensions, skills or prompts:

/reload

How to extend

Add a rule. Drop a *.md file in rules/. It is appended to the system prompt in filename order on the next run — no registration needed.

Add a skill. Create skills//SKILL.md with name and description frontmatter. The description is what the model sees when deciding to load it; make it say what the skill does and when to use it.

Add an extension. Write a *.ts file in extensions/ that default-exports a function taking the Pi ExtensionAPI, then add its path to the extensions array in settings.json. Run /reload.

Add a / command. Either pi.registerCommand in an extension, or a Markdown file in prompts/.

Gotchas

  • orchestrate is a backend, not a sandbox boundary. The script runs with the agent’s own permissions. Treat any script as trusted.
  • ~/.pi/agent/git/config is generated. github-account rewrites it at session start and deletes it on /gh-account off; hand-edits are lost. The credentials file it points at (~/.config/claude-git/credentials) is the opposite: once it names the account user, it is used as it stands and never overwritten.

Secrets

This directory holds real credentials and private transcripts. Before publishing, make sure these are ignored and were never committed:

  • auth.json — provider API keys.
  • github-accounts.json — GitHub usernames, emails and plaintext tokens.
  • git/config — generated Git config; carries the commit identity and the path to the credentials file.
  • sessions/ — full conversation transcripts.
  • trust.json — per-machine trust decisions.

.gitignore already excludes them. If any leaked into a public history, rotate the tokens, don’t just delete the file.

[!WARNING] github-accounts.json stores tokens in plaintext unless a token is written as env:VAR_NAME, which makes it read from an environment variable instead. Prefer that form.

Further reading

View this README on GitHub

Recommended Tools

Try a different keyword or remove a filter.

Install

npx skillfish add jean-couscous/pi-agent