@bachi/pi-coder

A complete Pi coding-agent environment: 30 TUI extensions, 3 themes and the global config files that make them work together.

Packages

Package details

extensiontheme

Install @bachi/pi-coder from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@bachi/pi-coder
Package
@bachi/pi-coder
Version
2.3.0
Published
Oct 1, 2026
Downloads
3,709/mo · 1,654/wk
Author
bachi
License
MIT
Types
extension, theme
Size
2.6 MB
Dependencies
0 dependencies · 3 peers
Pi manifest JSON
{
  "image": "https://cdn.jsdelivr.net/gh/jayli/pi-coder@main/assets/demo-server-https.gif",
  "themes": [
    "./themes"
  ],
  "extensions": [
    "./extensions"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

@bachi/pi-coder

A complete Pi coding-agent environment packaged for npm: 30 extensions, 3 themes, and the global config files that make them work together.

This is a working setup, not a collection of demos. Every extension is used daily, and each one documents the pi internals it depends on in its own file header — including the failure that motivated it and the things that look like they could be simplified but cannot be.

Watch it work — demo-server-https.gif: a four-item task list worked end to end, with the thinking line, collapsed bash runs, inline diff and statusline progress. GitHub will not embed it (7.3 MB, over the 5 MiB limit of the image proxy it routes every off-domain image through), so the link opens it in the browser.

What it looks like

A startup header, a one-line statusline, a ❯ prompt, and a diff renderer that paints whole lines.

The header's title line is pi v0.99.2 (deepseek-flash-qd with max effort) — the version followed by the current model and thinking level, read live so /model and shift+tab are reflected on the next frame.

The startup list is pruned entirely — [Context], [Skills], [Prompts], [Extensions] and [Themes] are all dropped, leaving nothing above the transcript. The statusline's second line is written by other extensions (plan-mode first, then cwd-statusline and rewind) through ctx.ui.setStatus(), so it grows with whatever you have installed.

Colors come from the active theme rather than from hardcoded values, so /theme repaints everything on the next frame.

The pi-coder-ayu theme

Install

pi install npm:@bachi/pi-coder

Extensions and themes are loaded straight from the package (see the pi manifest in package.json) — there is nothing to configure. Restart pi, then check pi list or run pi config to see every resource with its enable/disable toggle.

Companion packages

This environment is built around three packages that are deliberately not bundled — they are heavy, they have their own release cycles, and pi-subagents needs settings.json entries that only make sense once it is installed:

pi install npm:pi-web-access              # pi_web_search / fetch_content / source_check / get_search_content
pi install npm:pi-subagents               # subagent / bg_wait / scripted workflows
pi install git:github.com/jayli/superpowers   # the skills the global AGENTS.md and plan mode refer to

All three are already listed in the shipped config/settings.json's packages array, which is what pi reads to install them.

superpowers is a pi package, not a skills directory. It carries both an extension (a one-time persistent injection of the using-superpowers bootstrap) and 15 skills (brainstorming, systematic-debugging, test-driven-development, writing-plans, …), and pi pulls it to ~/.pi/agent/git/github.com/jayli/superpowers/. That replaced the older manual arrangement — skills copied into ~/.agents/skills/ and found by pi's native scan — so there is nothing to copy by hand any more. Two extensions behave differently without it: plan-mode's brainstorming mutual-exclusion gate can never fire (it detects a read of a brainstorming/SKILL.md path), and verify-loop's completion discipline has no verification-before-completion skill to point at.

Without pi-web-access and pi-subagents two more degrade instead of failing: recap cannot tell whether a background subagent is still running (it treats the failed probe as "none"), and below-editor-after-statusline usually has nothing to move.

What you get

Extensions

Extension What it does
bash-command-collapse.ts Overrides bash: a • status dot (dim while running, green on success, red on failure), then the command behind a Run prefix on at most 2 visual lines ending in …, with results hanging off the same tree and a single └ on the first real output line (a failed command's Command exited with code N is detected by shape and painted error, expanded or not). No background and no boundary blank lines, hard-wrap at the column budget, shell syntax highlighting. The shape and its 25 render assertions are in bash-command-collapse/render.test.ts.
read-path-collapse.ts Overrides read's title row: the same • dot and no-background shell as the bash block, results indented to the Read column, and long paths on one line with the ellipsis at the front and the file name kept whole.
tool-diff.ts Overrides edit/write: Claude Code style full-line diff backgrounds, line-number gutter, inline and syntax highlighting.
thinking-collapse.ts Thinking blocks render as one continuous horizontally scrolling line labelled Think: .
user-message-bar/ A ▏ (U+258F) plus one space at the head of every line of a user message box, including the blank padding lines, in the theme's accent color. The glyph replaces the one column of left padding and the extra indent is taken back out of the trailing padding, so background, width and wrap positions stay as they were.
prompt-editor.ts A ❯ gutter in the editor, Claude Code style ! bash mode, plus a blank line between the autocomplete list and the statusline.
fenceless-code-block/ Markdown code blocks lose their fences (syntax colors kept, no background added).
codemode-tree/ Renders the built-in codemode tool block as the same tree the bash and read blocks use: • codemode → syntax-highlighted script on │ → result tree with one └ . The dot is three-state (white running, green success, red failure) and is the only outcome lamp now that the background is gone. It gets codemode's execution logic by running pi's own createCodemodeExtension() against a Proxy that captures the registered definition, so the schema stays the same object reference pi's MCP extension checks. Needs pi 0.99.1 and the shipped settings.json's -builtin:codemode + +codemode pair. PI_CODEMODE_TREE=off removes the tool entirely rather than restoring the built-in.
statusline/ Replaces the footer: model/thinking level, context usage, git branch and diff stat, plus a second line for extension statuses and a reserved last line for the background-task dock.
startup-logo/ Static header logo whose title line carries the version, the current model and thinking level (pi v0.99.2 (deepseek-flash-qd with max effort), read live so /model and shift+tab follow on the next frame) and the shortened cwd, every line indented one column and width-clamped because pi-tui throws on an over-wide line; prunes the entire startup resource list ([Context]/[Skills]/[Prompts]/[Extensions]/[Themes]).
working-indicator/ Semantic working message (Tools Calling, Editing, Writing, Reading, Thinking) with per-segment token counts and elapsed time, plus a Subagent watchdog reviewing message for the window where pi-subagents' watchdog blocks after agent_end and the spinner would otherwise turn unexplained.
simple-task/ Task list driven by task_set / task_update / task_get and /tasks; state rides the session log, never the repo. All three tools use renderShell: "self", so their blocks carry no background and no boundary blank lines, with one leading space per line — the same shell as the bash and read blocks.
recap/ /recap (idempotent: re-running it while the summary is on screen does nothing), plus an automatic summary above the editor after 10s of idling.
rewind/ Shadow-git checkpoints and /rewind (or Esc Esc) to restore code and/or conversation.
ask-user-question/ An ask_user_question tool: up to 4 questions with 2–4 described options plus a free-text row, answered in the terminal. Its block uses renderShell: "self", so it carries no background and no boundary blank lines.
auto-default-model/ Writes every model switch to settings.json — the Ctrl+S step, automated.
subagent-log-guard/ Stops [pi-subagents] stderr diagnostics from corrupting the TUI.
cwd-statusline.ts Prints the full working directory as a second statusline line.
below-editor-after-statusline.ts Moves belowEditor widgets underneath the statusline.
folder-history.ts Persists command history per working directory and injects it into the editor's native ↑/↓.
theme-command.ts /theme with live preview: arrow keys preview, Enter persists, Esc cancels.
plan-mode/ Claude Code style plan mode plus a three-state permission mode (dangerous / bypass / plan). shift+tab walks the fixed cycle dangerous → bypass → plan → dangerous; /plan only ever toggles plan (never lands on dangerous), --plan starts in it. dangerous switches the seatbelt delete boundary off at runtime, bypass (the default) keeps it on, plan is read-only exploration with edit/write dropped and write-shaped bash blocked. The model's own enter_plan_mode carries all the routing criteria in its tool description, asks for consent first — a two-option dialog where 直接实施 (or Esc) skips planning — and is skipped entirely when the brainstorming skill was already loaded this run. exit_plan_mode submits the plan for approval — full markdown, a slug that names the document and an optional summary — and the three-way dialog either writes .pi/plans/<date>-<slug>.md and implements it, writes the document only, or rejects. There is no execute phase and no progress table of its own; the model builds a task list itself if one is warranted.
memory/ Claude Code style auto-memory: memory_write / memory_read / memory_forget / memory_search plus /memory (status, open folder, show index, per-project toggle). One file per memory under ~/.pi/agent/memory/<project-slug>/ with CC-compatible frontmatter, and a MEMORY.md index the extension derives mechanically after every write — the model never hand-maintains it, so "wrote a memory but never updated the index" cannot happen. Injected through systemPromptOptions.sections.memory (discipline text + index), which survives compaction. PI_MEMORY=off disables it.
background-tasks/ Minimal run_in_background for pi, which ships no background-execution primitive: run_in_background / background_output (incremental reads) / background_kill plus /background (list, details + log tail, kill). A terminal state injects a <background-task-notification> and wakes the model — no polling. Tasks live and die with the pi session (killAll() on shutdown; detached only to kill the whole process group). Running tasks also get a dock line at the very bottom of the footer (⚙ bg_1 running 12s · command…), which freezes while a prompt is open so it cannot drag your scrollback down. Background commands bypass the seatbelt delete boundary the foreground bash tool runs inside — the tool descriptions and /background say so. PI_BACKGROUND_TASKS=off disables it, PI_BACKGROUND_TASKS_DOCK=off only the dock line.
core-rules/ Re-pushes the distilled global rules (~/.pi/agent/AGENTS.core.md, shipped as config/AGENTS.core.md) to the end of the context at session start, after a compaction and whenever the content changed — the full AGENTS.md sits at the front of the system prompt, where its recency decays. Nothing is injected when nothing changed.
verify-loop/ Verification discipline as code, mirroring two Claude Code mechanisms on pi's agent_before_settle boundary. The gate: when a turn settles after file changes with no bash command run after them, it injects a visible message and forces one more turn (cap 2, counted from the projection, not memory). /goal: a completion condition evaluated after every turn by one tool-less model call (met / not_met / impossible, fail-open), with no-progress detection, an 8-continuation cap and resume support. PI_VERIFY_LOOP=off|notify|block switches the gate.
sandbox-boundary/ The non-shell half of the delete boundary: bash runs inside a seatbelt profile, but write / edit are direct fs calls, so apply_patch's *** Delete File: lines are checked on the tool_call hook instead. Shares one whitelist and one persistent allowlist with the bash side.
init-command.ts Claude Code style /init: update CLAUDE.md, else AGENTS.md, else create AGENTS.md.
clear-command.ts /clear as an alias of /new.
exit-command.ts exit, quit or bye on an otherwise empty prompt quits pi; /exit too.

Themes

pi-coder-1337 (the default here, ported from Codex CLI's built-in 1337), pi-coder-catppuccin and pi-coder-ayu — reference-only palettes whose colors entries point at vars, plus two custom diff-background tokens that tool-diff.ts reads. vars keeps only what a slot still references (35 / 31 / 27 entries). Details in docs/themes.md.

All three are laid out side by side in the palette reference: every variable and slot assignment, plus a terminal preview you can switch between the three themes.

Commands

/ask /background /bash-preview /bash-timeout /clear /exit /goal /init /memory /plan /plan-status /recap /rewind /sandbox-boundary /tasks /theme

/mcp is not one of them: MCP is pi's own built-in extension (builtin:mcp) since pi 0.99.1, and this package no longer ships an MCP extension of its own — the retired implementation conflicted with the built-in over the /mcp registration. See docs/extensions.md.

Esc Esc opens /rewind (requires doubleEscapeAction: "none", which the shipped config sets).

Environment switches

Every switch is an environment variable, so it can be scoped per project or set in a shell alias. An unset variable means "on"; off always disables. The full table is in docs/extensions.md — highlights:

Variable Default Effect
PI_AUTO_DEFAULT_MODEL=off on Do not persist model switches to settings.json.
PI_BACKGROUND_TASKS=off on Disable the background-task tools and /background; PI_BACKGROUND_TASKS_DIR moves the log root (used for test isolation), PI_BACKGROUND_TASKS_DOCK=off removes only the statusline dock line, PI_BACKGROUND_TASKS_WORKTREE=off runs every task in the working directory instead of an isolated git worktree.
PI_BASH_STREAM=on off Use pi's native streaming for bash instead of the collapse path.
PI_CODEMODE_TREE=off on Do not register codemode; with the shipped -builtin:codemode setting this removes the tool entirely rather than restoring pi's built-in rendering.
PI_CORE_RULES=off on Do not re-inject the distilled global rules into the context.
PI_DESTRUCTIVE_GUARD on block rejects the confirm tier too, notify only reports what it would have caught, off disables the gate.
PI_FENCELESS_CODE=off on Keep Markdown code fences.
PI_LOGO=off on Do not install the startup header.
PI_MEMORY=off on Disable auto-memory entirely; PI_MEMORY_DIR moves the memory root (used for test isolation).
PI_PLAN_MODE=off on Disable plan mode entirely (PI_PLAN_MODE_AUTO=off only disables the model's enter_plan_mode tool, PI_PLAN_MODE_CONSENT=off only its consent dialog).
PI_READ_COLLAPSE=off on Keep pi's built-in read title row.
PI_SANDBOX=off on Disable the delete boundary (both the bash seatbelt profile and the apply_patch gate); also off automatically off macOS. PI_SANDBOX_EXTRA_WRITE adds delete roots, PI_SANDBOX_ALLOWLIST moves the persistent allowlist file.
PI_SUBAGENT_LOG_GUARD=notify drop Show [pi-subagents] diagnostics through ctx.ui.notify instead of dropping them.
PI_VERIFY_LOOP block The verification gate's force: off disables it, notify reports without forcing a continuation. PI_VERIFY_PATTERN=strict narrows "verification" to test/build/lint shapes; PI_VERIFY_EVALUATOR_MODEL picks the /goal evaluator model.

Global config files

Five files in config/ are not package resources — pi reads them from ~/.pi/agent/, so copy the ones you want by hand. pi installs the package under ~/.pi/agent/npm/node_modules/@bachi/pi-coder (project installs go to .pi/npm/node_modules/):

PKG=~/.pi/agent/npm/node_modules/@bachi/pi-coder

cp "$PKG/config/AGENTS.md"          ~/.pi/agent/AGENTS.md          # global working rules
cp "$PKG/config/AGENTS.core.md"     ~/.pi/agent/AGENTS.core.md     # the distilled core `core-rules` re-injects; missing means it silently does nothing
cp "$PKG/config/settings.json"      ~/.pi/agent/settings.json      # read this first!
cp "$PKG/config/web-search.json"    ~/.pi/agent/web-search.json    # required by pi-web-access
mkdir -p ~/.pi/agent/themes
cp "$PKG/themes/"*.json             ~/.pi/agent/themes/            # optional: also shipped as a package theme

If you already copied these extensions into ~/.pi/agent/extensions/, remove that copy first. pi loads both sources, the second registration of bash, read, edit, write and the rest conflicts, and pi refuses to start with Tool "bash" conflicts with ....

Read config/settings.json before copying it. It overwrites your settings wholesale, and two of its entries are machine-specific:

  • npmCommand pins pnpm --config.node-linker=hoisted. Remove it if you do not have pnpm, or pi install will fail.
  • doubleEscapeAction: "none" hands Esc-Esc to the rewind extension instead of pi's built-in tree navigator.

config/models.json and config/mcp.json are not shipped: provider registrations point at a local gateway and the MCP file holds absolute paths of local server executables, so both belong to the machine that runs them. MCP servers are configured in ~/.pi/agent/mcp.json or a project .pi/mcp.json, which pi's built-in builtin:mcp reads. See docs/configuration.md.

Requirements

  • pi 0.85.1 or newer (the extensions are written against this version's internals), Node 22.19+. 29 of the 30 entries load with errors: [] through pi's own loader on 0.85.1 and 0.87.1; all 30 do on 0.99.1 and 0.99.2. The one that needs 0.99.1 is codemode-tree/, which captures the built-in codemode tool through createCodemodeExtension() — a function that only exists from 0.99.1 on, so on an older pi that single entry fails to load and the rest are unaffected.
  • MCP needs pi 0.99.1, which is where builtin:mcp arrived. This package no longer ships an MCP extension, so on an older pi there are simply no MCP tools.
  • macOS or Linux. Nothing is Windows-specific, but it is untested there.
  • Optional but assumed by a few extensions: pi-web-access (the web tools), pi-subagents (subagent events, fleet status line) and superpowers (the skills plan-mode's brainstorming gate and verify-loop's completion discipline refer to). All three are listed in the shipped config/settings.json's packages array.

Documentation

Document Contents
docs/installation.md Install, verify, upgrade, uninstall, and the local-checkout workflow.
docs/configuration.md Every shipped config file, what was removed from the snapshot, and why.
docs/extensions.md Reference for all 30 extensions: commands, switches, caveats, storage.
docs/themes.md Theme files, the custom tokens, and the rules that make them load.
Palette reference Chinese. Every variable and slot assignment for the three themes, with a terminal preview that switches between them.
docs/development.md Running the 1334 unit tests, verifying against a real pi, publishing.
docs/handbook.zh.md Chinese. The original handbook this package was extracted from: the author's machine, gateway setup, and the full rationale behind every design decision.

Development

npm test        # node --test, 1334 tests

The pure-logic modules are deliberately free of @earendil-works/pi-* imports so they run under plain node --test; see docs/development.md for the layout rules, the tmux verification procedure and the traps this codebase documents.

License

MIT — see LICENSE.