๐งฉ pi-extensions
Personal Pi coding agent extensions, built for my own use and made shareable. Zero build step, zero runtime dependencies โ each extension is plain TypeScript loaded directly by pi.
Extensions
| Package | Use it for |
|---|---|
pi-exit |
/exit alias for pi's built-in /quit. |
pi-plan-mode |
Codex-like read-only /plan mode that writes a Markdown plan you edit before implementation. |
pi-web-fetch |
Browser-grade web_fetch / batch_web_fetch / web_search: clean markdown/HTML/text/JSON extraction, page metadata, GitHub URLs via gh, bounded-concurrency batches, keyless DuckDuckGo search. web_answer returns only the passages that answer a question. |
pi-code-search |
Faster, more reliable code discovery: repo_map / code_search / file_outline / find_definition with a persistent mtime-invalidated symbol cache, gitignore-exact inventory, and import/alias/re-export resolution. |
pi-typesafe |
Calibrated judgments for the agent: typesafe_ask batches typed questions; read_relevant selects exact source ranges; deferred find_code finds implementations by behavior. Advisory web/MCP injection warnings preserve structured results. Environment-only config (TYPESAFE_API_KEY). |
pi-skill-select |
On-demand skill selection: skill_select searches the whole local skill library and returns ranked SKILL.md paths. /skill-search <task> offers offline human discovery and prepares a prompt; scripts/skill-search.mjs serves other agents. |
pi-diagnosis-nudge |
Nudges on tool failures; after two failed revised checks, blocks mutations until a revision-bound diagnostic observation runs. |
pi-done-gate |
Quietly nudges on unverified edits and leftover [DEBUG- tags; measure_command validates repeated, revision-bound benchmark/evaluation observations. |
pi-until |
/until <cmd>: keeps the agent working until a shell predicate exits 0, re-checking at every settle, capped, with a TSV decision log per iteration. |
pi-guardrail |
Stops destructive tool use before it runs: deterministic rules for the 97% that are obviously fine, a TypeSafe judgment for the ambiguous middle, and an Approve / Deny / Suggest-an-alternative dialog for the rest. Refuses the catastrophic set outright. |
pi-router |
Rates how hard the current task is and escalates to a frontier model when it clears a threshold โ once per task, never mid-task, and never downgrading a model you chose. Judged, because the rules measured 7% precision on this repo's own history. |
pi-prompt-coach |
On-demand /improve: probe the repo, rewrite locally with Gemma4, verify intent with TypeSafe, and submit the rewrite with original-prompt fallback. |
pi-subagents |
Off-by-default in-process children: /subagents on to opt in, then the main session orchestrates scout / reviewer / verifier / oracle / worker / researcher (or custom .md types) and synthesizes. Live widget, /subagents to steer or stop. |
pi-review |
On-demand review with judgment behind it: lint_change scores a diff against this repo's standing preferences and commit rules, blast_radius lists the callers outside a diff and the symbols no test mentions, verify_findings drops findings whose own quotation is not in the diff before asking whether the rest hold. |
pi-watch-pr |
watch_pr: one read of a PR's checks on its head commit, merge state and unresolved threads, with a verdict (needs-action / pending / ready / closed). Read-only; ready is not a merge grant. |
pi-jobs |
Pi-native /jobs live logs, background commands and optional PTYs, human takeover, revision-bound exit evidence and opt-in Jev attention watches. No herdr/tmux required. |
pi-workbench |
Live-filtering /ui and /files, read-only /changes with retained review position and Neovim handoff, recoverable drafts and slash-command typo suggestions. |
pi-footer |
Workspace, branch and actual work state first; /footer details reveals accounting/statuses, and /usage [--json] reports per-model active-branch tokens, caching, costs and tool failures. |
pi-toasts |
Extension notify calls become short-lived top-right toasts in TUI mode instead of permanent transcript rows. |
Package dependencies
These packages are published as separate directories but are not fully independent โ some import modules from their siblings, so deleting or renaming one can break another:
pi-workbenchreusespi-code-search's Git-aware file inventory; its optional planning/subagent/footer actions appear only when those commands are loaded.pi-jobsreusespi-workbenchtext sanitization andpi-done-gatecheck detection;pi-diagnosis-nudgealso reusespi-done-gate's check detection. Subagents, jobs and both gates bind evidence to the revision fingerprint inshared/revision.mjs, and consume the shared completed-job evidence adapter.pi-typesafereusespi-code-search's file inventory andpi-guardrail's path policy (policy-bash.mjs,policy-targets.mjs) to decide what a file question may read.pi-plan-modeimportsfetchSmart/formatWebFetchResult/isKnownFormatfrompi-web-fetch'sfetch.mjsandformat.mjs(used to implementplan_fetch_url). Which other tools it allows is decided from their annotations at runtime, not from a sibling name list.readOnlyHint: trueis trusted only for tools this repo registers.pi-skill-select,pi-typesafe,pi-guardrail,pi-router,pi-review,pi-done-gate,pi-diagnosis-nudge,pi-plan-mode,pi-safe-compact,pi-web-fetch,pi-prompt-coach,pi-subagents,pi-jobsand thescripts/classifiers all import from the sharedshared/systemone.mjsโaskSystemOnefor the request,usableNumberfor reading answers โ and from its siblingssystemone-config.mjs(endpoint and key),systemone-request.mjs(validateRequest, the state/question contract),systemone-transport.mjs(deadline and transports) andsystemone-session.mjs(the store that carries Pi's context and token usage). One implementation of each, split by job, so a file stays readable instead of duplicating transport. Inside Pi, that request goes throughclassify()when a TypeSafe System One model is registered, and stays on the direct HTTP transport otherwise. Thescripts/classifiers have no Pi model registry, so they stay on HTTP. Each call also appends a localjev-decisionsession entry (model, question ids, answers, latency, transport, outcome). State and question text stay out of that entry. Seepackages/typesafe/README.md.pi-plan-modeandpi-subagentsboth import the read-only bash allowlist fromshared/bash-policy.mjsat the repo root, and bothpi-plan-modeandpi-guardrailimport the FIFO dialog serializer fromshared/dialog-queue.mjsโ two dialogs open at once stack and hang the tool batch.pi-plan-modeandpi-guardrailparse commands withshared/shell-parse.mjs, which is quote-aware and knows heredocs from shell: one answers "is this provably read-only?", the other "what could this destroy?", and both need to tell operators from literal text.
pi-exit, pi-web-fetch, pi-code-search, pi-skill-select, pi-until, pi-review,
pi-subagents, pi-guardrail, pi-router, pi-safe-compact, pi-prompt-coach,
pi-watch-pr, pi-footer and pi-toasts import no sibling package, only shared/.
pi-done-gate loads none at runtime, but its own tests load pi-jobs's Jobs, so
deleting that package still breaks it.
Install
The research application maps the supplied
workflow research onto these existing extensions. /skill-search <task> now
offers local skill discovery with a reviewable prompt; /workflow <task> connects
investigation, implementation, verification and review through existing tools.
Clone the repo into pi's global extensions directory; pi auto-discovers the
extensions from the pi key in package.json:
git clone https://github.com/matt-riley/pi-extensions ~/.pi/agent/extensions/pi-extensions
cd ~/.pi/agent/extensions/pi-extensions && npm install
npm install is needed because several extensions import typebox. Without
it, npm run verify reports Cannot find package 'typebox' for half the
entrypoints.
then /reload in pi (or restart it). To update later:
git -C ~/.pi/agent/extensions/pi-extensions pull
npm --prefix ~/.pi/agent/extensions/pi-extensions install
then /reload again.
Check the tools are intact (loads the entrypoints through a stub pi, discovers the local skill library, reports whether a TypeSafe key is visible):
npm run verify # offline
npm run verify -- --live # also makes one real TypeSafe call
Prompt templates and workflow skills
pi auto-discovers extensions from pi.extensions, but does not load
pi.prompts or pi.skills from auto-discovered extension directories. Those
resources load from installed packages or explicit settings. Register both in
~/.pi/agent/settings.json:
{
"prompts": ["~/.pi/agent/extensions/pi-extensions/prompts"],
"skills": ["~/.pi/agent/extensions/pi-extensions/.agents/skills"]
}
Without this, the slash-command prompts in prompts/ (/commit,
/review, /debug, /verify-setup, /mine, /triage, /garden, /upgrade, /migrate, /retro, โฆ) are
silently unavailable. Installed Pi packages load the same resources through
the root manifest instead.
Three owned, portable workflows live in .agents/skills/:
| Skill | Entry points | Purpose |
|---|---|---|
implementation-review |
/review, /pr |
Read-only, defect-first review with grounded findings and test-quality checks |
test-driven-development |
/test, feature/bug work |
Behavior-focused tests, independent expectations and tested vertical slices |
interface-design |
/design, /refactor |
Small interfaces that hide complexity; /design proposes without editing |
skill_select and scripts/skill-search.mjs also search these bundled skills
from any working directory. Other applications' skill roots are not searched
unless explicitly included with PI_SKILL_LIBRARY or --root. Keep project-specific
skills under that project's .agents/skills/; do not import another harness's
system collection as an implicit dependency. Prompt skill references are validated
against this checkout on every npm run check, with no home-directory dependency.
Requirements
- Pi 1.4.0 or later. The extensions use the 1.2.0
before_agent_startcontract (messageType,systemPromptOptionssections) and rely on 1.4.0's fixes, such as concurrent extension dialogs.npm run smokerefuses older hosts; extensions themselves can't read the host version. - No added npm dependencies. Imports are pi's
typeboxbuilt-in andnode:core modules. Most packages type-only-import@earendil-works/pi-coding-agent;pi-subagentsalso imports the host SDK at runtime (createAgentSession).
Development
Dev tooling only โ none of it ships with an extension:
| Command | Tool | What it guards |
|---|---|---|
npm run lint |
oxlint | correctness and suspicious patterns, warnings included |
npm run format |
oxfmt | code and JSON at 100 columns |
npm run knip |
knip | unused files, exports and dependencies |
npm run fallow |
fallow | dead code, cycles, dependency hygiene; fallow:report adds duplication and complexity |
npm run coverage |
Node test runner | executable line/function/branch coverage and coverage/lcov.info, without an added dependency |
npm run check runs all four plus tsc --noEmit and the test suite. Every rule
exception is written down in the config next to the rule it disables, so the gate
stays honest instead of collecting suppress-comments.
Classifiers
Three judgments that used to be made from memory in a prompt now live in
scripts/, so the same input gets the same answer twice and every one is
covered by node --test:
| Script | What it decides |
|---|---|
scripts/ci-triage.mjs |
one CI failure โ flaky, regression, infra, configuration or dependency, with its confidence. /triage --ci calls it. |
scripts/promote-corrections.mjs |
a correction I gave more than once โ the cheapest durable fix (test, lint, guardrail, agents, prompt, none) and how well existing guidance already covers it. /mine calls it. |
scripts/memory-check.mjs |
a candidate lore memory โ duplicate, contradiction, refinement or new, naming the memory to update. /retro calls it. |
Each prints rather than applies, takes an injected ask in its tests, and says
when it could not judge instead of inventing a verdict.
Related
- matt-riley/lore โ local-first memory and continuity for the Copilot CLI and pi (installed separately).