A collection of pi coding-agent extensions.
| Extension | Tools / behavior |
|---|---|
bash.ts |
Overrides built-in bash to run PowerShell 7 (pwsh.exe); injects TERM=dumb so the profile skips interactive init but keeps UTF-8 + mise |
shell-guidance.ts |
Adds system-prompt guidance to use ripgrep for discovery/search and move non-trivial shell logic into temporary Bun scripts; registers no tool |
session-info.ts |
Captures the first user message's date/time and selected model, then reuses those fixed values after model switches and resume |
hashline.ts |
Overrides built-in read, edit, and write together with one shared session-grounding state: numbered snapshots, compact version-tagged patches, vision fallback, and safe full-file writes |
subagent.ts |
subagent - delegates independent investigation, implementation, and review to an isolated tool-using peer or a configured higher-capability advisor |
codegraph.ts |
codegraph_explore - bridges codegraph's MCP tool into a native pi tool (spawns codegraph serve --mcp, lazy, once per session) |
web-search.ts |
web_search, web_fetch via Exa public MCP (https://mcp.exa.ai/mcp, no API key) |
pi install git:github.com/cha133/pi-extensions
# or local path
pi install /absolute/path/to/pi-extensionsOr copy the complete extensions/ tree, including extensions/lib/, into
~/.pi/agent/extensions/ for auto-discovery and /reload.
| Extension | Notes |
|---|---|
bash |
PowerShell 7 at C:\Program Files\PowerShell\7\pwsh.exe (edit the path if needed) |
bun |
bun on PATH |
rg |
rg on PATH |
session-info |
None |
edit |
None (no extra runtime deps; reuses pi's diff helpers) |
read |
A vision model configured in ~/.pi/agent/settings.json for use when the current model cannot consume images |
write |
None; wraps pi's native full-file writer |
subagent |
None; optionally configure peer and advisor models under subagent in ~/.pi/agent/settings.json |
codegraph |
codegraph CLI on PATH; a project must be indexed (codegraph init) for queries to work |
web-search |
Network access to https://mcp.exa.ai/mcp |
Choose any image-capable model already configured in pi and add a vision
object to ~/.pi/agent/settings.json:
{
"vision": {
"provider": "google",
"model": "gemini-2.5-flash"
}
}The provider and model values must identify a model available to pi, and
that model must declare "image" in its supported inputs. The overridden
read tool uses pi's model registry and existing authentication, including built-in providers,
~/.pi/agent/models.json, ~/.pi/agent/auth.json, OAuth, and provider
environment variables. The extension does not store a separate API key.
For text files, read preserves pi's native access checks and limits, then
returns a sixteen-hex whole-file tag and numbered source rows:
[src/example.ts#7A31C9E2D84F106B]
1:export const value = 1;
2:console.log(value);
The edit tool consumes that header and the original line numbers. A single
call may contain several non-overlapping hunks:
[src/example.ts#7A31C9E2D84F106B]
SWAP 1:
+export const value = 2;
INS.POST 2:
+export { value };
SWAP N: or SWAP N.=M: replaces inclusive lines, CUT N or
CUT N.=M deletes them, and INS.PRE N:, INS.POST N:, INS.HEAD:, or
INS.TAIL: inserts literal +TEXT rows. All hunks use the same pre-edit
coordinates and are validated before one write. Only lines actually displayed by
read for that file revision may be replaced, deleted, or used as insertion
anchors. A stale tag, unseen line, invalid range, overlap, or no-op rejects the
entire call. Re-read after a successful edit before issuing another patch. Calls
to edit share Pi's file mutation queue with native write, preventing concurrent
in-process mutations of the same file from overwriting each other. On session resume,
reload, fork, or tree navigation, displayed ranges are rebuilt from successful read
and write results on the active branch. Each persisted tag is checked against the
current file before its coverage is restored, so changed or missing files still require
a fresh read.
write keeps pi's ordinary { path, content } full-file interface and native
directory creation, write queue, cancellation, and rendering. After writing,
it hashes the successfully committed content and returns a fresh [PATH#TAG], allowing
the model to follow with edit using the content it just wrote. If content
is a complete numbered snapshot copied from read, the wrapper removes the
header and LINE: prefixes only after verifying that the rows start at 1 and
are consecutive, the read was not partial, the paths match, and the tag is
still current. Verified copied rewrites preserve the existing BOM, line
endings, and final newline. Ordinary content is never prefix-stripped.
For images when the current model already supports image input, read keeps
pi's native result. Otherwise it sends the native reader's processed image to
the configured fallback model and returns the description. Trusted project
settings may override either vision value with a vision object in
.pi/settings.json. Settings are read on every fallback call, so changing the
selected model does not require /reload. Changes to pi's model or provider
configuration may still require /reload.
For targeted image analysis, read also accepts an optional image object:
{
"path": "screenshot.png",
"image": {
"query": "What does the red error message in the lower-right corner say?",
"detail": "detailed"
}
}query is a natural-language question or instruction, detail is brief,
standard, or detailed. Areas to prioritize should be expressed directly in
query. When the current model supports images, pi's native image result is
left untouched and these arguments remain visible in the tool call context. For
text-only current models, the extension sends them to the configured fallback
vision model.
The subagent tool delegates a self-contained investigation, implementation,
or review task to an
isolated in-memory pi session with its own context and the read, bash, edit,
codegraph_explore, web_search, and web_fetch tools. It is intended
for autonomous investigation, implementation, and advice. The delegated task
must explicitly state whether file modifications are authorized; without that
authorization the subagent remains read-only. Subagents cannot spawn further agents.
With no additional settings, the default peer tier inherits the current
model. Optionally configure either tier under subagent in
~/.pi/agent/settings.json:
{
"subagent": {
"peer": {
"provider": "openai",
"model": "gpt-5.5"
},
"advisor": {
"provider": "anthropic",
"model": "claude-opus-4-6"
}
}
}Both objects are optional. A configured model must already be available to pi;
the in-memory session uses pi's normal model discovery and authentication. Trusted
project settings may override either tier in .pi/settings.json.
The tool accepts a required task and, only when useful, an optional tier.
Omitting tier always selects peer. The advisor option is exposed only when
its configured model exists and differs from the current main model; selecting
that same model as the main model hides the option again. This keeps normal
delegation cheap and prevents a nominal advisor call from silently becoming
another same-model review.
Only the subagent's final report is returned inline to the main model. It inherits the current pi thinking level. Reports larger than 2,000 lines or 50 KB are truncated, and the full output is saved to a temporary file whose path is included in the result.
Every invocation also exports the complete child session to
%TEMP%\pi-subagent-<session-id>.jsonl before shutdown. The result includes
that path so the parent agent or an external investigator can inspect exact
assistant turns, tool calls, tool results, failures, and retries without placing
the full transcript in the parent model's context by default.
Each running subagent occupies one compact two-line tool box in the TUI. The first line shows its tier and task subject; the second shows its latest tool, reasoning, reply, or completion state. Internal tool calls and raw JSON events are not rendered as a nested transcript. Multiple subagent tool calls can run and update their boxes in parallel.
npm install --ignore-scripts
npm test
npm run typecheckdevDependencies exist only for editor types / tsc. At runtime pi provides @earendil-works/pi-* and typebox.
pi-extensions/
├── extensions/ # top-level .ts extension entry points loaded by pi
│ └── lib/ # non-discovered implementations shared by entry points
├── tests/ # Bun regression tests
├── package.json # pi-package manifest + peerDeps (runtime) + devDeps (types/tsc)
├── tsconfig.json # noEmit; strict; NodeNext; types: ["node"]
├── AGENTS.md # agent quick-reference (auto-read by coding agents)
└── README.md # this file