# pi-plugins
Aviram's portable Pi setup plus the Pi extensions and themes it installs.
The main use case is agentic setup sync: point an agent at this repo and ask it to make a machine's Pi configuration match this setup. The agent should use `setup/` as the source of truth, preserve local/private values as placeholders, and verify the result.
## Replicate this setup with an agent
Give an agent this repo and ask: **โConfigure Pi on this computer from this repository. Default to the full portable setup, but first inspect what is already installed and ask me which parts to keep, omit, or customize. Apply the result safely and verify it.โ**
The agent's completion contract is:
- the target machine has the selected subset of Aviram's Pi defaults, packages, extension configs, agent definitions, and operating instructions;
- unrelated existing settings and credentials remain intact unless the user explicitly chose replacement;
- private values stay localโnothing secret is copied from another machine, printed in chat, or committed;
- the agent verifies the effective installation and reports what changed, what was preserved, and what still needs local input.
Unless the user asks for a narrower scope, default to a **full portable sync**: settings defaults, package list, bundled extensions/themes, non-secret extension configs, agent definitions, and portable operating instructions. On a machine with existing config, full sync still means merge-and-preserveโnot blind replacement. Authentication, private endpoints, credentials, and machine-specific paths always require local choices. Every part can be excluded or customized during questioning.
### Guided agent workflow
1. **Inspect before asking or editing**
- Read this README, `setup/README.md`, `setup/settings.example.json`, and the repo-root `AGENTS.md`. Inspect the available filenames under `setup/configs/`, `setup/agents/`, and `setup/skills/`; after scope is chosen, read the selected files. Read `setup/AGENTS.md` and `setup/CODING_CONVENTIONS.md` before explaining the agent-behavior option.
- Check `node --version`, `npm --version`, `git --version`, and `pi --version`. If Pi is missing, ask before installing it with `npm install -g --ignore-scripts @earendil-works/pi-coding-agent`.
- Detect existing target files under `~/.pi/agent/` and `~/.pi/`. Inspect ordinary JSON and instruction files as needed. **Do not use raw file reads, `cat`, `grep`, or similar content-printing commands on `auth.json`, `mcp-adapter.json` (or a legacy `mcp.json`), or `web-search.json`.** Inspect only structural key paths with a targeted script such as the one below.
- Discover whether this is fresh or existing setup; do not ask questions the filesystem already answers.
```bash
node <<'NODE'
const fs = require("node:fs");
const os = require("node:os");
const path = require("node:path");
const files = {
"auth.json": path.join(os.homedir(), ".pi/agent/auth.json"),
"mcp-adapter.json": path.join(os.homedir(), ".pi/agent/mcp-adapter.json"),
"mcp.json (legacy)": path.join(os.homedir(), ".pi/agent/mcp.json"),
"web-search.json": path.join(os.homedir(), ".pi/web-search.json"),
};
function keyPaths(value, prefix = "", out = []) {
if (Array.isArray(value)) { out.push(`${prefix}[]`); return out; }
if (value && typeof value === "object") {
for (const key of Object.keys(value)) keyPaths(value[key], prefix ? `${prefix}.${key}` : key, out);
} else if (prefix) out.push(prefix);
return out;
}
for (const [label, file] of Object.entries(files)) {
if (!fs.existsSync(file)) continue;
const shape = keyPaths(JSON.parse(fs.readFileSync(file, "utf8")));
console.log(`${label}: ${shape.join(", ")}`);
}
NODE
```
2. **Guide the user through full vs. partial sync**
First summarize what was discovered on the target machine and make a recommendation:
- recommend **full portable sync** when Pi is fresh or the user wants this machine to match Aviram's setup closely;
- recommend **partial sync** when the target already has intentional model, theme, agent, or integration choices, or the user wants only specific capabilities;
- offer **dry run** when the user wants to inspect the proposed delta before anything changes.
Never ask โfull or partial?โ without explaining what that choice would change on this machine. Ask the smallest useful set of grouped questions, skipping choices the user already answered. When partial sync is plausible, include the part selection with the scope question when the interface supports it; otherwise ask one focused follow-up:
- **Change strategy:** merge and preserve existing values (recommended when config exists), replace selected files after timestamped backups, or dry run only.
- **Sync scope:** full portable sync (default), or choose parts. In a full sync, ask what to opt out of rather than forcing the user to select every item.
- **Existing conflicts:** for each selected part whose target differs, apply Aviram's portable default, preserve the current value, or customize it.
- **Agent behavior:** apply `setup/AGENTS.md` with its `CODING_CONVENTIONS.md` companion and the Luna-backed `Explore` override; preserve current behavior; or choose these individually.
- **Optional integrations:** configure web search, MCP servers, browser tools, image generation, or none. Preserve working local integrations by default.
When the user chooses parts, explain and offer these independently:
- **Pi defaults** โ default provider/model, thinking level, enabled model cycle, theme, telemetry, and message delivery behavior.
- **Packages and resources** โ the installed helper packages plus this repo's extensions and its `graphite` and `deep-focus-pi` themes.
- **Extension tuning** โ non-secret settings such as subagent concurrency, rendering mode, GPT fast mode, aliases, and MCP tool-catalog behavior.
- **Agent behavior** โ global operating instructions, appended system guidance, and the read-only Explore agent on GPT-5.6 Luna with medium thinking.
- **Integrations** โ web search, MCP/browser connections, and image generation; these may require target-local paths, login, or secrets.
If the user chooses a category rather than full sync, continue to the individual items in that category and use the descriptions under [Resources included](#resources-included) to explain their purpose. Do not force all extensions or configs in a selected category.
Default normal installs to Git package sources tracking `@main`. Ask about local development paths only when the user is working from a local clone. Preserve existing authentication; if none is usable, guide the user to provider `/login` or local environment-variable authentication. Never ask for a raw credential in chat.
3. **Translate the answers into an explicit plan**
- Name every target file that will be created, merged, replaced, or left alone.
- Name every package that will be installed or updated.
- Explain any unresolved placeholder or machine-specific path before applying it.
- Pause only for destructive replacement, credential/authentication work performed as the user, or another genuinely external side effect. Reversible merges and package preparation may proceed after the choices are clear.
4. **Apply the selected profile safely**
- Before changing an existing file, create a timestamped backup beside it.
- For `settings.json`, preserve unknown keys, merge nested objects, and union package entries by package identity instead of duplicating them. Apply model, thinking, theme, telemetry, and delivery defaults only when selected.
- For files under `setup/configs/`, merge or replace per file; do not assume every extension config is wanted in a custom profile.
- Copy selected agent definitions to `~/.pi/agent/agents/`. Merge instruction files semantically so existing rules are not duplicated.
- Copy selected global skills to `~/.agents/skills/`; each skill is a directory containing `SKILL.md`.
- For the selected upstream design skills, run `bash setup/install-external-skills.sh`; it installs the recorded selection globally for Claude Code, Codex, and Pi. See [external skills](setup/README.md#external-skills).
- Do not overwrite working `auth.json`, `mcp-adapter.json`, or `web-search.json`. If only a legacy `~/.pi/agent/mcp.json` exists, `pi-mcp-adapter` 3.x no longer reads it: rename it with `mv ~/.pi/agent/mcp.json ~/.pi/agent/mcp-adapter.json` (merge the two if both exist). Start from an example only when the integration is selected and no usable local file exists.
| Portable source | Target | Apply when |
| --- | --- | --- |
| `setup/settings.example.json` | `~/.pi/agent/settings.json` | Normal installed setup; merge selected defaults when a file exists |
| `setup/settings.local.example.json` | `~/.pi/agent/settings.json` | Local development only, after replacing the absolute-path placeholders |
| `setup/configs/*.json` | `~/.pi/agent/` | The matching extension/config is selected |
| `setup/agents/*.md` | `~/.pi/agent/agents/` | The matching agent override is selected |
| `setup/skills/*` | `~/.agents/skills/` | The matching global skill is selected |
| `setup/install-external-skills.sh` | Shared global skills for Claude Code, Codex, and Pi | The upstream design skill selection is wanted |
| `setup/AGENTS.md` | `~/.agents/AGENTS.md`, with `~/.pi/agent/AGENTS.md`, `~/.claude/CLAUDE.md` and `~/.codex/AGENTS.md` as symlinks onto it | Aviram's operating posture is selected; an existing file at a symlink path is backed up first |
| `setup/CODING_CONVENTIONS.md` | `~/.agents/CODING_CONVENTIONS.md` | Always, whenever `AGENTS.md` is copied โ it references this file by name |
| `setup/auth.example.json` | `~/.pi/agent/auth.json` | API-key-via-environment auth is selected and no auth file should be preserved |
| `setup/mcp-adapter.example.json` | `~/.pi/agent/mcp-adapter.json` | MCP/browser integration is selected; fill placeholders locally |
| `setup/web-search.example.json` | `~/.pi/web-search.json` | Web search is selected; fill the provider secret locally |
| `setup/models.example.json` | `~/.pi/agent/models.json` | A custom provider override is actually needed; the current full profile intentionally keeps this template empty |
5. **Install and reconcile packages**
- Use the package list in `setup/settings.example.json` as the normal source of truth.
- Install missing packages with `pi install <source>` and reconcile installed Git packages with `pi update --extensions` when appropriate.
- Package installation does **not** copy the files under `setup/`; perform both the package and file-merge steps.
6. **Verify the effective setup**
- Parse every JSON file changed without printing credential-bearing contents.
- Run `pi list` and compare package identities with the selected package list.
- Run `pi --list-models`; for the full profile confirm `openai/gpt-6-astra`, `openai/gpt-6.1-sol`, `openai/gpt-5.6-luna`, `openai/gpt-6-luna`, `anthropic/claude-opus-5-5`, `anthropic/claude-opus-5-5-full`, `anthropic/claude-fable-5-1`, and `anthropic/claude-sonnet-5-5` are available. Confirm the configured model cycle contains only Opus 5.5 at high, Opus 5.5 full-window at high, Astra at medium, Sol 6.1 at high, Fable 5.1 at max, and Sonnet 5.5 at xhigh; Astra and Sol report 272K context, both Luna generations report 270K, Opus 5.5 and Sonnet 5.5 report 300K, Fable 5.1 and the Opus 5.5 full-window alias report 1M, and `model-aliases.json` gives the OpenAI models a 1,050,000-token target window and the Anthropic models a 1,000,000-token one.
- Confirm each selected config, instruction, and agent file exists at its target path. For the goal-controller profile, confirm `checker.model: openai/gpt-6-luna` and `checker.thinking: medium`; for the Explore override, confirm `model: openai/gpt-5.6-luna` and `thinking: medium` without displaying unrelated local content.
- Search copied files for unresolved markers such as `<...>` and `/ABSOLUTE/PATH/TO`; report them rather than inventing values.
- Restart Pi or run `/reload` after changing settings, instruction files, or agent definitions.
- When editing this repository itself, also run `npm run verify:structure` and the secret-safety scans from the `sync-pi-setup` skill.
The final report must state: selected strategy/profile/integrations, packages installed or preserved, files created/merged/replaced plus backup paths, defaults applied or preserved, unresolved local placeholders, and verification results.
## Setup defaults
The normal setup template is [`setup/settings.example.json`](setup/settings.example.json). It sets:
```json
{
"defaultProvider": "anthropic",
"defaultModel": "claude-opus-5-5-full",
"defaultThinkingLevel": "high",
"enabledModels": [
"anthropic/claude-opus-5-5:high",
"anthropic/claude-opus-5-5-full:high",
"openai/gpt-6-astra:medium",
"openai/gpt-6.1-sol:high",
"anthropic/claude-fable-5-1:max",
"anthropic/claude-sonnet-5-5:xhigh"
],
"theme": "graphite",
"pi-image-gen": {
"defaultModel": "gpt-image-2.5-sunburst"
}
}
```
The setup makes `anthropic/claude-opus-5-5-full` the default at high thinking, so a session starts on the planning window. The model cycle contains Opus 5.5 at high twice, Astra at medium, Sol 6.1 at high, Fable 5.1 at max, and Sonnet 5.5 at xhigh. The two Opus 5.5 entries are a plan/execute pair: plan and figure things out on `claude-opus-5-5-full`, which exposes the whole 1,000,000-token window, then switch to `claude-opus-5-5`, which compacts at 300,000, to execute. Fable 5.1 is unrestricted. The Luna helper models remain selectable outside the quick-switch cycle. [`setup/configs/model-aliases.json`](setup/configs/model-aliases.json) defines visible operating windows of 272,000 tokens for Astra and Sol, 270,000 for both Luna generations, and 300,000 for Opus 5.5 and Sonnet 5.5; Fable 5.1 and the Opus 5.5 full-window alias have no visible boundary. Pi starts automatic compaction one configured response reserve below the visible window; a tool loop that reaches the edge first triggers native compact-and-retry. Delegated calls and Pi-owned summaries retain the existing target windows: 1,050,000 for OpenAI and 1,000,000 for Anthropic.
[`setup/configs/goal-controller.config.json`](setup/configs/goal-controller.config.json) pins Aviram's goal checker to `openai/gpt-6-luna` at `medium`, regardless of the active session model. This is a setup-specific override; the goal-controller package still defaults both checker fields to `inherit`.
[`setup/configs/advisor-consult.json`](setup/configs/advisor-consult.json) sets the advisor to `openai/gpt-6-astra` at `max`, so it comes from a different model family than the Opus sessions that call it. The setup config overrides only model and thinking; the advisor-consult package default stays Fable 5.1 at `xhigh`, and the config is read on every consult, so editing it needs no reload.
The installed `@gotgenes/pi-subagents` package hardcodes its built-in `Explore` agent to Claude Haiku. [`setup/agents/Explore.md`](setup/agents/Explore.md) is the portable same-name override: it keeps Explore read-only, uses `openai/gpt-5.6-luna` with medium thinking, and asks for conclusion-first, evidence-backed findings.
The setup installs these package sources:
```json
[
"npm:pi-mcp-adapter",
"npm:@gotgenes/pi-subagents",
"git:github.com/doodledood/manifest-dev@main",
"git:github.com/doodledood/pi-plugins@main",
"npm:@juicesharp/rpiv-ask-user-question",
"npm:@juicesharp/rpiv-todo",
"npm:pi-web-access",
"npm:@amaster.ai/pi-image-gen"
]
```
## Reference recipe: fresh full profile
Use this recipe only after the user selects the full profile and inspection confirms there is no Pi setup to preserve. HTTPS cloning is the portable default; use SSH only when the target already has GitHub SSH access.
```bash
set -euo pipefail
command -v pi >/dev/null || { echo "Pi is not installed; return to the prerequisite step." >&2; exit 1; }
if { [ -d "$HOME/.pi/agent" ] && [ -n "$(find "$HOME/.pi/agent" -mindepth 1 -maxdepth 2 -type f -print -quit 2>/dev/null)" ]; } || [ -e "$HOME/.pi/web-search.json" ]; then
echo "Existing Pi state detected; stop and use the merge recipe." >&2
exit 1
fi
git clone https://github.com/doodledood/pi-plugins.git
cd pi-plugins
mkdir -p ~/.pi/agent/agents ~/.pi ~/.agents/skills ~/.claude ~/.codex
cp setup/settings.example.json ~/.pi/agent/settings.json
cp setup/configs/*.json ~/.pi/agent/
cp setup/agents/*.md ~/.pi/agent/agents/
cp -R setup/skills/* ~/.agents/skills/
cp setup/AGENTS.md ~/.agents/AGENTS.md
cp setup/CODING_CONVENTIONS.md ~/.agents/CODING_CONVENTIONS.md
for f in ~/.pi/agent/AGENTS.md ~/.claude/CLAUDE.md ~/.codex/AGENTS.md; do
[ -e "$f" ] && [ ! -L "$f" ] && mv "$f" "$f.bak.$(date +%Y%m%d%H%M%S)"
ln -sfn ~/.agents/AGENTS.md "$f"
done
```
Choose authentication rather than assuming it:
- For provider subscription auth, start Pi and use `/login`; do not create `auth.json` from the API-key example.
- For environment-based OpenAI auth, copy `setup/auth.example.json` to `~/.pi/agent/auth.json`, set mode `0600`, and have the user provide `OPENAI_API_KEY` in their local environment.
- Copy `mcp-adapter.example.json` and `web-search.example.json` only for integrations the user selected. Their placeholders must be filled locally before those integrations can work.
- Do not copy `models.example.json` for the normal full profile; it is intentionally empty. Dual-window behavior for Astra, Sol, and both Luna generations comes from `configs/model-aliases.json`.
Install the selected packages:
```bash
for pkg in \
npm:pi-mcp-adapter \
npm:@gotgenes/pi-subagents \
git:github.com/doodledood/manifest-dev@main \
git:github.com/doodledood/pi-plugins@main \
npm:@juicesharp/rpiv-ask-user-question \
npm:@juicesharp/rpiv-todo \
npm:pi-web-access \
npm:@amaster.ai/pi-image-gen
do
pi install "$pkg"
done
pi list
```
Later, `pi update --extensions` reconciles installed Git checkouts to their configured refs.
## Reference recipe: merge into an existing setup
Merge is the default when target configuration exists. Do not run the fresh-profile copy block over an existing machine.
1. Back up each file that the selected plan will touch, using a shared timestamp. At minimum, back up `settings.json` before any `pi install` command because package installation updates that file.
2. Merge selected settings structurally. Preserve unknown keys and current defaults that the user chose to keep; union the package list without duplicate npm package names, Git repository identities, or local paths. Remove obsolete `models.json` context-window overrides for Sol or Luna when adopting the full profile; the selected `model-aliases.json` config now owns their dual-window behavior.
3. Install only missing selected packages. `pi install` updates the package entry while preserving unrelated settings.
4. Compare each selected `setup/configs/*.json` file with its target and merge extension settings intentionally. When MCP server names differ, update the matching `prior` keys in `mcp-tool-loadout.json`.
5. Copy the Explore definition only if the user selected the Luna-backed override. Copy selected global skills from `setup/skills/` to `~/.agents/skills/` as whole skill directories, backing up any same-named skill first. Merge `AGENTS.md` by concept rather than blindly appending duplicate rules, into `~/.agents/AGENTS.md`, and copy `CODING_CONVENTIONS.md` alongside it so its reference resolves. Then make `~/.pi/agent/AGENTS.md`, `~/.claude/CLAUDE.md` and `~/.codex/AGENTS.md` symlinks onto that file: if any of them is a real file with local rules, merge those rules into `~/.agents/AGENTS.md` first, back the file up with the shared timestamp, and replace it with the symlink โ one file, read by Pi, Claude Code and Codex alike. If the target machine still has a `~/.pi/agent/APPEND_SYSTEM.md` from an earlier sync, fold anything it still carries into `AGENTS.md` and remove it โ the posture now lives in one file.
6. Preserve existing auth and private integration files. If a selected integration is absent, create its local file from the example and leave unresolved private values for the user to fill locally.
The full-profile defaults available for an explicit merge are:
- `defaultProvider: "anthropic"`
- `defaultModel: "claude-opus-5-5-full"`
- `defaultThinkingLevel: "high"`
- the `enabledModels` list from `setup/settings.example.json`
- `enableInstallTelemetry: false`
- `followUpMode: "all"` and `steeringMode: "all"`
- `theme: "graphite"`
- `pi-image-gen.defaultModel: "gpt-image-2.5-sunburst"`
- the non-secret extension configs under `setup/configs/`
- the agent behavior files selected during questioning
## Local development setup
Use [`setup/settings.local.example.json`](setup/settings.local.example.json) only when editing this repo locally. Replace every `/ABSOLUTE/PATH/TO/pi-plugins` placeholder with the clone path. Normal installed setups should use the upstream Git source from `setup/settings.example.json`.
## Resources included
Use these descriptions when guiding a partial sync. The user may select individual packages/resources; dependencies required by a selected feature should be included automatically and explained.
### External helper packages
- `pi-mcp-adapter` โ connects configured MCP servers to Pi.
- `@gotgenes/pi-subagents` โ foreground/background specialized agents with custom agent definitions.
- `doodledood/manifest-dev` โ figure-out, planning, execution, review, and PR workflow skills.
- `@juicesharp/rpiv-ask-user-question` โ structured question UI for guided decisions.
- `@juicesharp/rpiv-todo` โ persistent task-list tooling for multi-step work.
- `pi-web-access` โ web search, content fetching, and source-backed library research.
- `@amaster.ai/pi-image-gen` โ image generation and image editing.
- `doodledood/pi-plugins` โ this repo's extension and theme bundle listed below.
### Agents
- `Explore` โ setup-only global override for `@gotgenes/pi-subagents`; read-only exploration on `openai/gpt-5.6-luna` with medium thinking and evidence-oriented reporting. Copy it from `setup/agents/Explore.md` to `~/.pi/agent/agents/Explore.md`.
### Extensions
- `advisor-consult` โ independent second-opinion advisor tool.
- `btw` โ `/btw` side conversations with separate child history and a shared project workspace; the aside persists under the parent session so its spend stays countable.
- `cache-optimization` โ prompt-cache diagnostics and TTL keepalive.
- `context-breakdown` โ `/context` command for context-window usage breakdown.
- `goal-controller` โ checker-only long-running goal controller; Aviram's portable config pins its checker to `openai/gpt-6-luna` at `medium` while the extension default remains `inherit`.
- `gpt-fast-toggle` โ OpenAI GPT priority service-tier toggle; Pi prices priority turns itself.
- `mcp-tool-loadout` โ compact MCP catalog and cache-safe schema loading.
- `message-stash` โ single-slot input draft stash.
- `model-aliases` โ selector-visible custom model aliases with separate visible and provider-target context windows; dual-window aliases enforce the visible edge through Pi's native compact-and-retry path. The portable setup defines Astra and Sol as 272K/1.05M aliases, both Luna generations as 270K/1.05M aliases, Opus 5.5 as a 300K/1M alias beside an unrestricted 1M one, Sonnet 5.5 as a 300K/1M alias, and Fable 5.1 as an unrestricted 1M one.
- `openai-max-output-floor` โ prevents OpenAI min-output-token 400s near context limits.
- `openai-tts` โ local OpenAI Speech API text-to-speech tool.
- `panel` โ `/panel` parallel multi-model consultation: independent panelists answer over a fork of the live conversation, returned as attributed fallible opinions.
- `simple-statusline` โ compact Pi footer/statusline, including whole-session-tree cost (this session plus every run it spawned) and the `/cost` breakdown.
- `skill-argument-hints` โ argument hints for skill commands.
- `tool-activity-renderer` โ Graphite-style rows for the built-in tools: present-tense shimmer while a tool runs, past tense and a right-aligned result when it lands, finished rows fading back, exploratory runs folding into one "Explored โฆ" line, word-level diff emphasis, a live working line above the editor, and thinking's inline code plus the narration between tool calls drawn in the quieter thinking tone, so only the reply reads at full brightness.
- `widget-dock` โ folds the todo and subagent widgets above the editor into one summary line; `alt+w` expands them.
### Themes
- `graphite` โ the default: calm graphite neutrals, one blue accent, and color reserved for state. Pairs with `tool-activity-renderer`.
- `deep-focus-pi` โ the previous default, kept for anyone who prefers it.
### Skills
- `deletion-pass` โ portable global audit skill. Runs an ordered "deletion pass" (question requirements, delete or absorb parts, simplify only what survives, accelerate/automate last) over a plan, design, architecture, or process and reports what to cut and what to question โ audit only, it never rewrites the artifact. Ships as a setup template; copy `setup/skills/deletion-pass/` to `~/.agents/skills/deletion-pass/` to install it at the user level.
- Emil Kowalski's design skills โ eleven selected upstream skills installed by [`setup/install-external-skills.sh`](setup/install-external-skills.sh) for Claude Code, Codex, and Pi. Their content remains upstream; see [installation and updates](setup/README.md#external-skills).
Global skills are intentionally not packaged as installable Pi *package* resources (no `packages/skills`, no `pi.skills`). Portable global skills ship under `setup/skills/` and are copied to the user level during replication, like `setup/agents/`. Manifest Dev is supplied by its separately installed package. The project-local [`sync-pi-setup`](.agents/skills/sync-pi-setup/SKILL.md) skill syncs local Pi setup changes back into `setup/`; its content lives under `.agents/skills/` and is symlinked into `.claude/skills/` for Claude-style discovery.
## Prime Agent setup
[Prime Agent](https://app.primeintellect.ai/prime-agent) is an independently developed fork of Pi's codebase โ it still carries the inherited `@earendil-works/pi-*` package identifiers โ with its own CLI (`prime-agent`), config dir (`~/.prime/agent`), and package commands. The extensions in this repo load in it unchanged; what differs is how sources are declared and updated.
This section documents the Prime Agent setup actually in use, not a second full portable sync. For the wider profile (models, theme, agents, integrations) follow the Pi guidance above and translate `~/.pi/agent/` to `~/.prime/agent/`.
Install Prime Agent itself with `curl -fsSL https://app.primeintellect.ai/prime-agent/install.sh | sh`.
### What this setup installs
`manifest-dev` whole, and only two extensions from this repo โ the statusline and the cache work โ rather than the full bundle:
```json
{
"packages": [
"git:github.com/doodledood/manifest-dev",
{
"source": "git:github.com/doodledood/pi-plugins",
"extensions": [
"packages/extensions/simple-statusline/extensions/simple-statusline.ts",
"packages/extensions/cache-optimization/extensions/cache-optimization.ts"
],
"skills": [],
"prompts": [],
"themes": []
}
]
}
```
```bash
prime-agent package install git:github.com/doodledood/manifest-dev
prime-agent package install git:github.com/doodledood/pi-plugins # then narrow it with the filter above
prime-agent package list
```
### Git sources must be ref-less
Write `git:github.com/doodledood/pi-plugins`, not `...@main` โ the opposite of the Pi snippets elsewhere in this README. Prime Agent 0.7.0 parses any ref as `pinned: true` and skips pinned sources in both `package update` and the startup update notice, so a `@main` source silently never updates while `package update` still prints `Updated packages`. A ref-less source tracks the default branch and reconciles normally.
Pi is not affected the same way: its update path deliberately includes pinned git refs, so `@main` keeps working there. Only Pi's startup "packages have updates" notice skips them, which is why `setup/settings.example.json` can keep its `@main` entries.
### Updating
In 0.7.0 the two halves are separate commands โ the top level is self-only and rejects package targets:
```bash
prime-agent package update # extensions/packages only
prime-agent update # Prime Agent itself; restarts the daemon and resumes live sessions
```
Run packages first, because a self-update restarts the background daemon and ends the command. Run `package update` from a neutral working directory, never `$HOME`: Prime Agent's project config path (`.prime/agent/settings.json`) resolves to the global settings file when the cwd is the home directory, so every package is collected twice and the concurrent git checkouts race on `.git/index.lock`.
A wrapper that gets both halves right:
```zsh
upgrade-prime-agent() {
local rc=0
(cd -q / && prime-agent package update) || rc=$?
prime-agent update "$@" || rc=$?
return $rc
}
```
## Installing individual resources
Install the root bundle when you want all included extensions and the themes:
```bash
pi install git:github.com/doodledood/pi-plugins@main
```
To load only one resource from the Git repo, use package filters in `~/.pi/agent/settings.json`. For example, BTW's package-root entry is:
```json
{
"packages": [
{
"source": "git:github.com/doodledood/pi-plugins@main",
"extensions": ["packages/extensions/btw/index.ts"],
"prompts": [],
"themes": []
}
]
}
```
Theme-only example:
```json
{
"packages": [
{
"source": "git:github.com/doodledood/pi-plugins@main",
"extensions": [],
"prompts": [],
"themes": ["packages/themes/graphite/themes/graphite.json"]
}
]
}
```
Do not rely on undocumented Git subdirectory install syntax. These Pi examples track `@main` so installs follow the latest version. Pin a specific commit only when intentionally using a frozen snapshot. Prime Agent is the exception โ drop the ref entirely there, see [Prime Agent setup](#prime-agent-setup).
## Security
Pi extensions execute with local user permissions, and skills can instruct the model to take actions. Review packages and skills before installing or invoking them.
Do not commit live local state: credentials, OAuth state, sessions, caches, logs, raw `auth.json`, filled MCP URLs, API keys, generated package caches, or `node_modules`. Templates/examples should use placeholders or environment-variable references.
See [`docs/security.md`](docs/security.md).
## Development
```bash
npm install
npm run verify:structure
npm run typecheck
npm test
```
`npm run verify` runs structure checks, typechecks, and package test suites, including BTW's deterministic child-runtime and TUI coverage.