# pi-modekit — User Guide

Everything you need to work with **modes** in pi-modekit. If you're a
"vibe coding" person, just read [Day-to-day usage](#day-to-day-usage) and the
[mode lifecycle](#mode-lifecycle) — the rest is for when you want to go deep.

---

## Day-to-day usage

| Key / command | Effect |
|---|---|
| `Tab` | Cycle through modes (default: `plan` ↔ `build`) |
| `Alt+S` | Search modes by name, description, or content |
| `/mode` | Open the mode selector |
| `/mode <name>` | Switch to a mode directly |
| `/modes` | List all modes (with source + description) |
| `pi --start-mode plan` | Start pi in a given mode |

A banner above the input always shows the active mode, its model, and its tools.

## Mode lifecycle

### Create a mode — `/mode add <name>`

1. **Where to save**: Project (`.pi/agents/`) or User (`~/.pi/agent/agents/`)
2. **Starting point**: plan-like (read-only), build-like (full access),
   everything, or empty
3. **Tool checklist** — every tool actually available on your machine, toggled
   with ←/→ or Space; hit the `✔ Create mode "…"` row to finish
4. **Write the instructions** — the mode body opens in an editor, prefilled
   with a sensible template, ready for you to shape

Done: the `.md` file is created, the mode is **activated immediately**, and it
joins the `Tab` cycle.

### Edit a mode — `/mode edit <name>`

Opens the mode file **in pi's editor, in place**. On save:

- the file is overwritten
- if the mode is active, it is **re-applied immediately** (changing `tools:` or
  `model:` in the frontmatter takes effect at once)
- renaming via the `name:` frontmatter line renames the mode (you are told
  clearly)

`/mode edit` (no name) → pick from a list.

### Remove a mode — `/mode remove <name>` (`rm`, `delete`)

- Always asks for **confirmation** before deleting
- The bundled `plan`/`build` kit modes **cannot be deleted** (they live in the
  package) — instead, create your own override: `/mode add plan` and write
  your own content
- If the active mode is removed, the session falls back to “no mode”

## Frontmatter

`name` (required) · `description` (optional) · `tools` (optional) ·
`model` (optional, `provider/model-id`)

```markdown
---
name: review
description: Reviews code, tests allowed
tools: read, grep, find, ls, bash
model: anthropic/claude-sonnet-4-5
---

# MODE: review

Read carefully, give feedback, run the tests — do not edit files.
```

**Load order** (increasing precedence; same name → later wins):
bundled `agents/` → User `~/.pi/agent/agents/` → Project `.pi/agents/`

### Writing good mode instructions
- Say clearly what the mode may and may not do. Short and focused beats long.
- **Declare `tools` explicitly** — behavior relies on the tool set, not on
  promises in prose.
- **Do not end your instructions with a sentence like "switch to build to
  continue"** — it lands in the transcript and leaks into later turns after the
  mode has already changed.
- Instructions are placed at the **end** of the system prompt (where models
  follow best) and re-confirmed by a mode marker on every turn — so keep them
  pointed, not rambling.

## Guard — the "mode actually holds" part

While the active mode cannot both `edit` and `write` (i.e. it is restricted):

| Rule | It protects you from |
|---|---|
| R1 · Delegation | a restricted mode handing work to an unrestricted subagent (the classic escape hatch). Read-only subagents still work. |
| R2 · Shell & writes | `bash`/`powershell` calls, and edits outside plan files, being slipped through. |
| R3 · Secrets | reading `.env` and `.env.*` in a restricted session (`.env.example` is fine). |

The guard inspects the **live tool set**, not the mode switcher's state, so a
plain `pi --tools read,grep,find,ls` run gets the same protection.

> The guard is not a sandbox: a session that already has `edit`/`write`/`bash`
> has pi's full power. For real isolation use a container/VM (see pi's
> `docs/security.md` and `docs/containerization.md`).

## Research tools for restricted modes

All of these are extension tools, so they are **available in every mode** —
`plan` can use them to research thoroughly without a shell:

- **`save_plan`** — writes markdown to `.pi/plans/` or `~/.pi/agent/plans/`.
  This is how `plan` hands the plan to `build`.
- **`web_fetch`** — HTTP **GET** only, for reading a specific URL. Domains
  outside the allowlist need your approval; running unattended, they are
  refused (fail closed).
- **`web_search`** — web search, GET only. DuckDuckGo by default (no key);
  Brave if you set `search.apiKey` in research.json.
- **`npm_info`** — npm package lookups (version/description/homepage/license)
  or registry search, GET only.
- **`git_inspect`** — read-only git history: `log`, `show --stat`,
  `diff --stat`, `status`, `blame`, `ls-files`. Structured parameters (no
  shell), no patch/content dumps; in a restricted session, paths pointing at
  `.env*` files are refused (extends R3).

The `web_fetch` allowlist lives in `~/.pi/agent/research.json`:

```json
{ "allowedDomains": ["github.com", "developer.mozilla.org"] }
```

## FAQ

- **I switched to build but the model still says it can't edit — why?**
  Transcript staleness: earlier "I cannot edit" lines stay in the conversation.
  pi-modekit reduces this with the per-turn mode marker and by not ending mode
  instructions with "switch to build". If it still happens, start a fresh turn
  after switching, or pin a stronger model on the mode.
- **How do I add tools to a mode?** — `/mode edit <name>` → change the `tools:`
  line → save.
- **A mode per project?** — choose "Project" as the save location in
  `/mode add`.
- **I don't want the bundled plan/build.** — create overrides with the same
  names (`/mode add plan`) in User or Project; those win over bundled.
- **Change the Tab key?** — edit `registerShortcut` in
  `extensions/modes/index.ts` (the key declaration line), then `/reload`.
- **Can a tool push code?** — no. Everything is read-only by construction:
  `web_fetch`/`web_search`/`npm_info` are HTTP GET only; `git_inspect` runs a
  fixed read-only subcommand whitelist (no commit/add/push, no shell); plan
  mode has no `bash` at all (guard R2). GitHub data comes from
  `api.github.com` over plain GET, never the `gh` CLI.