@mariozechner/pi-coding-agent 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,55 +1,62 @@
1
1
  # pi
2
2
 
3
- A radically simple and opinionated coding agent with multi-model support (including mid-session switching), a simple yet powerful CLI for headless coding tasks, and many creature comforts you might be used to from other coding agents.
3
+ A terminal-based coding agent with multi-model support, mid-session model switching, and a simple CLI for headless coding tasks.
4
4
 
5
- Works on Linux, macOS, and Windows (needs a bash shell, see [Windows Shell Configuration](#windows-shell-configuration)).
5
+ Works on Linux, macOS, and Windows (requires bash; see [Windows Setup](#windows-setup)).
6
6
 
7
7
  ## Table of Contents
8
8
 
9
- - [Installation](#installation)
10
- - [Windows Shell Configuration](#windows-shell-configuration)
11
- - [Quick Start](#quick-start)
12
- - [API Keys](#api-keys)
13
- - [OAuth Authentication (Optional)](#oauth-authentication-optional)
14
- - [Custom Models and Providers](#custom-models-and-providers)
15
- - [Themes](#themes)
16
- - [Slash Commands](#slash-commands)
17
- - [Editor Features](#editor-features)
18
- - [Project Context Files](#project-context-files)
19
- - [Image Support](#image-support)
20
- - [Session Management](#session-management)
21
- - [Context Compaction](#context-compaction)
22
- - [CLI Options](#cli-options)
23
- - [Tools](#tools)
9
+ - [Getting Started](#getting-started)
10
+ - [Installation](#installation)
11
+ - [Windows Setup](#windows-setup)
12
+ - [API Keys](#api-keys)
13
+ - [Quick Start](#quick-start)
24
14
  - [Usage](#usage)
25
- - [Security (YOLO by default)](#security-yolo-by-default)
26
- - [Sub-Agents](#sub-agents)
27
- - [To-Dos](#to-dos)
28
- - [Planning](#planning)
29
- - [Background Bash](#background-bash)
15
+ - [Slash Commands](#slash-commands)
16
+ - [Editor Features](#editor-features)
17
+ - [Keyboard Shortcuts](#keyboard-shortcuts)
18
+ - [Bash Mode](#bash-mode)
19
+ - [Image Support](#image-support)
20
+ - [Sessions](#sessions)
21
+ - [Session Management](#session-management)
22
+ - [Context Compaction](#context-compaction)
23
+ - [Branching](#branching)
24
+ - [Configuration](#configuration)
25
+ - [Project Context Files](#project-context-files)
26
+ - [Custom Models and Providers](#custom-models-and-providers)
27
+ - [Themes](#themes)
28
+ - [Custom Slash Commands](#custom-slash-commands)
29
+ - [Settings File](#settings-file)
30
+ - [CLI Reference](#cli-reference)
31
+ - [Tools](#tools)
32
+ - [Programmatic Usage](#programmatic-usage)
33
+ - [Philosophy](#philosophy)
30
34
  - [Development](#development)
31
35
  - [License](#license)
32
- - [See Also](#see-also)
33
36
 
34
- ## Installation
37
+ ---
38
+
39
+ ## Getting Started
35
40
 
36
- ### npm (recommended)
41
+ ### Installation
42
+
43
+ **npm (recommended):**
37
44
 
38
45
  ```bash
39
46
  npm install -g @mariozechner/pi-coding-agent
40
47
  ```
41
48
 
42
- ### Standalone Binary
43
-
44
- Pre-built binaries are available on the [GitHub Releases](https://github.com/badlogic/pi-mono/releases) page. Download the archive for your platform:
49
+ **Standalone binary:**
45
50
 
46
- - `pi-darwin-arm64.tar.gz` - macOS Apple Silicon
47
- - `pi-darwin-x64.tar.gz` - macOS Intel
48
- - `pi-linux-x64.tar.gz` - Linux x64
49
- - `pi-linux-arm64.tar.gz` - Linux ARM64
50
- - `pi-windows-x64.zip` - Windows x64
51
+ Download from [GitHub Releases](https://github.com/badlogic/pi-mono/releases):
51
52
 
52
- Extract and run:
53
+ | Platform | Archive |
54
+ |----------|---------|
55
+ | macOS Apple Silicon | `pi-darwin-arm64.tar.gz` |
56
+ | macOS Intel | `pi-darwin-x64.tar.gz` |
57
+ | Linux x64 | `pi-linux-x64.tar.gz` |
58
+ | Linux ARM64 | `pi-linux-arm64.tar.gz` |
59
+ | Windows x64 | `pi-windows-x64.zip` |
53
60
 
54
61
  ```bash
55
62
  # macOS/Linux
@@ -61,41 +68,28 @@ unzip pi-windows-x64.zip
61
68
  pi.exe
62
69
  ```
63
70
 
64
- The archive includes the binary plus supporting files (README, CHANGELOG, themes). Keep them together in the same directory.
65
-
66
- **macOS users**: The binary is not signed. macOS may block it on first run. To fix:
67
- ```bash
68
- xattr -c ./pi
69
- ```
70
-
71
- ### Build Binary from Source
71
+ **macOS note:** The binary is unsigned. If blocked, run: `xattr -c ./pi`
72
72
 
73
- Requires [Bun](https://bun.sh) 1.0+:
73
+ **Build from source** (requires [Bun](https://bun.sh) 1.0+):
74
74
 
75
75
  ```bash
76
76
  git clone https://github.com/badlogic/pi-mono.git
77
- cd pi-mono
78
- npm install
79
- cd packages/coding-agent
80
- npm run build:binary
81
-
82
- # Binary and supporting files are in dist/
77
+ cd pi-mono && npm install
78
+ cd packages/coding-agent && npm run build:binary
83
79
  ./dist/pi
84
80
  ```
85
81
 
86
- ## Windows Shell Configuration
82
+ ### Windows Setup
87
83
 
88
- On Windows, pi requires a bash shell. The following locations are checked in order:
84
+ Pi requires a bash shell on Windows. Checked locations (in order):
89
85
 
90
- 1. **Custom shell path** from `~/.pi/agent/settings.json` (if configured)
91
- 2. **Git Bash** in standard locations (`C:\Program Files\Git\bin\bash.exe`)
92
- 3. **bash.exe on PATH** (Cygwin, MSYS2, WSL, etc.)
86
+ 1. Custom path from `~/.pi/agent/settings.json`
87
+ 2. Git Bash (`C:\Program Files\Git\bin\bash.exe`)
88
+ 3. `bash.exe` on PATH (Cygwin, MSYS2, WSL)
93
89
 
94
- For most users, installing [Git for Windows](https://git-scm.com/download/win) is sufficient.
90
+ For most users, [Git for Windows](https://git-scm.com/download/win) is sufficient.
95
91
 
96
- ### Custom Shell Path
97
-
98
- If you use Cygwin, MSYS2, or have bash in a non-standard location, add the path to your settings:
92
+ **Custom shell path:**
99
93
 
100
94
  ```json
101
95
  // ~/.pi/agent/settings.json
@@ -104,554 +98,337 @@ If you use Cygwin, MSYS2, or have bash in a non-standard location, add the path
104
98
  }
105
99
  ```
106
100
 
107
- Alternatively, ensure your bash is on the system PATH.
108
-
109
- ## Quick Start
110
-
111
- ```bash
112
- # Set your API key (see API Keys section)
113
- export ANTHROPIC_API_KEY=sk-ant-...
114
-
115
- # Start the interactive CLI
116
- pi
117
- ```
118
-
119
- Once in the CLI, you can chat with the AI:
101
+ ### API Keys
120
102
 
121
- ```
122
- You: Create a simple Express server in src/server.ts
123
- ```
103
+ Set the environment variable for your provider:
124
104
 
125
- The agent will use its tools to read, write, and edit files as needed, and execute commands via Bash.
105
+ | Provider | Environment Variable |
106
+ |----------|---------------------|
107
+ | Anthropic | `ANTHROPIC_API_KEY` or `ANTHROPIC_OAUTH_TOKEN` |
108
+ | OpenAI | `OPENAI_API_KEY` |
109
+ | Google | `GEMINI_API_KEY` |
110
+ | Groq | `GROQ_API_KEY` |
111
+ | Cerebras | `CEREBRAS_API_KEY` |
112
+ | xAI | `XAI_API_KEY` |
113
+ | OpenRouter | `OPENROUTER_API_KEY` |
114
+ | ZAI | `ZAI_API_KEY` |
126
115
 
127
- ## API Keys
116
+ The `/model` command only shows models for providers with configured API keys.
128
117
 
129
- The CLI supports multiple LLM providers. Set the appropriate environment variable for your chosen provider:
118
+ **OAuth (Claude Pro/Max subscribers):**
130
119
 
131
120
  ```bash
132
- # Anthropic (Claude)
133
- export ANTHROPIC_API_KEY=sk-ant-...
134
- # Or use OAuth token (retrieved via: claude setup-token)
135
- export ANTHROPIC_OAUTH_TOKEN=...
136
-
137
- # OpenAI (GPT)
138
- export OPENAI_API_KEY=sk-...
139
-
140
- # Google (Gemini)
141
- export GEMINI_API_KEY=...
142
-
143
- # Groq
144
- export GROQ_API_KEY=gsk_...
145
-
146
- # Cerebras
147
- export CEREBRAS_API_KEY=csk-...
148
-
149
- # xAI (Grok)
150
- export XAI_API_KEY=xai-...
151
-
152
- # OpenRouter
153
- export OPENROUTER_API_KEY=sk-or-...
154
-
155
- # ZAI
156
- export ZAI_API_KEY=...
121
+ pi
122
+ /login # Select "Anthropic (Claude Pro/Max)", authorize in browser
157
123
  ```
158
124
 
159
- If no API key is set, the CLI will prompt you to configure one on first run.
125
+ Tokens stored in `~/.pi/agent/oauth.json` (mode 0600). Use `/logout` to clear.
160
126
 
161
- **Note:** The `/model` command only shows models for which API keys are configured in your environment. If you don't see a model you expect, check that you've set the corresponding environment variable.
162
-
163
- ## OAuth Authentication (Optional)
164
-
165
- If you have a Claude Pro/Max subscription, you can use OAuth instead of API keys:
127
+ ### Quick Start
166
128
 
167
129
  ```bash
130
+ export ANTHROPIC_API_KEY=sk-ant-...
168
131
  pi
169
- # In the interactive session:
170
- /login
171
- # Select "Anthropic (Claude Pro/Max)"
172
- # Authorize in browser
173
- # Paste authorization code
174
132
  ```
175
133
 
176
- This gives you:
177
- - Free access to Claude models (included in your subscription)
178
- - No need to manage API keys
179
- - Automatic token refresh
134
+ Then chat:
180
135
 
181
- To logout:
182
136
  ```
183
- /logout
184
- ```
185
-
186
- **Note:** OAuth tokens are stored in `~/.pi/agent/oauth.json` with restricted permissions (0600).
187
-
188
- ## Custom Models and Providers
189
-
190
- You can add custom models and providers (like Ollama, vLLM, LM Studio, or any custom API endpoint) via `~/.pi/agent/models.json`. Supports OpenAI-compatible APIs (`openai-completions`, `openai-responses`), Anthropic Messages API (`anthropic-messages`), and Google Generative AI API (`google-generative-ai`). This file is loaded fresh every time you open the `/model` selector, allowing live updates without restarting.
191
-
192
- ### Configuration File Structure
193
-
194
- ```json
195
- {
196
- "providers": {
197
- "ollama": {
198
- "baseUrl": "http://localhost:11434/v1",
199
- "apiKey": "OLLAMA_API_KEY",
200
- "api": "openai-completions",
201
- "models": [
202
- {
203
- "id": "llama-3.1-8b",
204
- "name": "Llama 3.1 8B (Local)",
205
- "reasoning": false,
206
- "input": ["text"],
207
- "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
208
- "contextWindow": 128000,
209
- "maxTokens": 32000,
210
- "compat": {
211
- "supportsDeveloperRole": false,
212
- "supportsStore": false
213
- }
214
- }
215
- ]
216
- },
217
- "vllm": {
218
- "baseUrl": "http://your-server:8000/v1",
219
- "apiKey": "VLLM_API_KEY",
220
- "api": "openai-completions",
221
- "models": [
222
- {
223
- "id": "custom-model",
224
- "name": "Custom Fine-tuned Model",
225
- "reasoning": false,
226
- "input": ["text", "image"],
227
- "cost": {"input": 0.5, "output": 1.0, "cacheRead": 0, "cacheWrite": 0},
228
- "contextWindow": 32768,
229
- "maxTokens": 8192
230
- }
231
- ]
232
- },
233
- "mixed-api-provider": {
234
- "baseUrl": "https://api.example.com/v1",
235
- "apiKey": "CUSTOM_API_KEY",
236
- "api": "openai-completions",
237
- "models": [
238
- {
239
- "id": "legacy-model",
240
- "name": "Legacy Model",
241
- "reasoning": false,
242
- "input": ["text"],
243
- "cost": {"input": 1.0, "output": 2.0, "cacheRead": 0, "cacheWrite": 0},
244
- "contextWindow": 8192,
245
- "maxTokens": 4096
246
- },
247
- {
248
- "id": "new-model",
249
- "name": "New Model",
250
- "api": "openai-responses",
251
- "reasoning": true,
252
- "input": ["text", "image"],
253
- "cost": {"input": 0.5, "output": 1.0, "cacheRead": 0.1, "cacheWrite": 0.2},
254
- "contextWindow": 128000,
255
- "maxTokens": 32000
256
- }
257
- ]
258
- }
259
- }
260
- }
137
+ You: Create a simple Express server in src/server.ts
261
138
  ```
262
139
 
263
- ### API Key Resolution
140
+ The agent reads, writes, and edits files, and executes commands via bash.
264
141
 
265
- The `apiKey` field can be either an environment variable name or a literal API key:
142
+ ---
266
143
 
267
- 1. First, `pi` checks if an environment variable with that name exists
268
- 2. If found, uses the environment variable's value
269
- 3. Otherwise, treats it as a literal API key
144
+ ## Usage
270
145
 
271
- Examples:
272
- - `"apiKey": "OLLAMA_API_KEY"` → checks `$OLLAMA_API_KEY`, then treats as literal "OLLAMA_API_KEY"
273
- - `"apiKey": "sk-1234..."` → checks `$sk-1234...` (unlikely to exist), then uses literal value
146
+ ### Slash Commands
274
147
 
275
- This allows both secure env var usage and literal keys for local servers.
148
+ | Command | Description |
149
+ |---------|-------------|
150
+ | `/model` | Switch models mid-session (fuzzy search, arrow keys, Enter to select) |
151
+ | `/thinking` | Adjust thinking level for reasoning models (off/minimal/low/medium/high) |
152
+ | `/queue` | Set message queue mode: one-at-a-time (default) or all-at-once |
153
+ | `/export [file]` | Export session to self-contained HTML |
154
+ | `/session` | Show session info: path, message counts, token usage, cost |
155
+ | `/changelog` | Display full version history |
156
+ | `/branch` | Create new conversation branch from a previous message |
157
+ | `/resume` | Switch to a different session (interactive selector) |
158
+ | `/login` | OAuth login for subscription-based models |
159
+ | `/logout` | Clear OAuth tokens |
160
+ | `/clear` | Clear context and start fresh session |
161
+ | `/copy` | Copy last agent message to clipboard |
162
+ | `/compact [instructions]` | Manually compact conversation context |
163
+ | `/autocompact` | Toggle automatic context compaction |
164
+ | `/theme` | Select color theme |
276
165
 
277
- ### API Override
166
+ ### Editor Features
278
167
 
279
- - **Provider-level `api`**: Sets the default API for all models in that provider
280
- - **Model-level `api`**: Overrides the provider default for specific models
281
- - Supported APIs: `openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai`
168
+ **File reference (`@`):** Type `@` to fuzzy-search project files. Respects `.gitignore`.
282
169
 
283
- This is useful when a provider supports multiple API standards through the same base URL.
170
+ **Path completion (Tab):** Complete relative paths, `../`, `~/`, etc.
284
171
 
285
- ### Custom Headers
172
+ **Drag & drop:** Drag files from your file manager into the terminal.
286
173
 
287
- You can add custom HTTP headers to bypass Cloudflare bot detection, add authentication tokens, or meet other proxy requirements:
174
+ **Multi-line paste:** Pasted content is collapsed to `[paste #N <lines> lines]` but sent in full.
288
175
 
289
- ```json
290
- {
291
- "providers": {
292
- "custom-proxy": {
293
- "baseUrl": "https://proxy.example.com/v1",
294
- "apiKey": "YOUR_API_KEY",
295
- "api": "anthropic-messages",
296
- "headers": {
297
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
298
- "X-Custom-Auth": "bearer-token-here"
299
- },
300
- "models": [
301
- {
302
- "id": "claude-sonnet-4",
303
- "name": "Claude Sonnet 4 (Proxied)",
304
- "reasoning": true,
305
- "input": ["text", "image"],
306
- "cost": {"input": 3, "output": 15, "cacheRead": 0.3, "cacheWrite": 3.75},
307
- "contextWindow": 200000,
308
- "maxTokens": 8192,
309
- "headers": {
310
- "X-Model-Specific-Header": "value"
311
- }
312
- }
313
- ]
314
- }
315
- }
316
- }
317
- ```
176
+ **Message queuing:** Submit messages while the agent is working. They queue and process based on `/queue` mode. Press Escape to abort and restore queued messages to editor.
318
177
 
319
- - **Provider-level `headers`**: Applied to all requests for models in that provider
320
- - **Model-level `headers`**: Additional headers for specific models (merged with provider headers)
321
- - Model headers override provider headers when keys conflict
178
+ ### Keyboard Shortcuts
322
179
 
323
- ### OpenAI Compatibility Settings
180
+ **Navigation:**
324
181
 
325
- The `openai-completions` API is implemented by many providers with minor differences (Ollama, vLLM, LiteLLM, llama.cpp, etc.). By default, compatibility settings are auto-detected from the `baseUrl`. For custom proxies or unknown endpoints, you can override these via the `compat` field on models:
182
+ | Key | Action |
183
+ |-----|--------|
184
+ | Arrow keys | Move cursor / browse history (Up when empty) |
185
+ | Option+Left/Right | Move by word |
186
+ | Ctrl+A / Home | Start of line |
187
+ | Ctrl+E / End | End of line |
326
188
 
327
- ```json
328
- {
329
- "providers": {
330
- "litellm": {
331
- "baseUrl": "http://localhost:4000/v1",
332
- "apiKey": "LITELLM_API_KEY",
333
- "api": "openai-completions",
334
- "models": [
335
- {
336
- "id": "gpt-4o",
337
- "name": "GPT-4o (via LiteLLM)",
338
- "reasoning": false,
339
- "input": ["text", "image"],
340
- "cost": {"input": 2.5, "output": 10, "cacheRead": 0, "cacheWrite": 0},
341
- "contextWindow": 128000,
342
- "maxTokens": 16384,
343
- "compat": {
344
- "supportsStore": false
345
- }
346
- }
347
- ]
348
- }
349
- }
350
- }
351
- ```
189
+ **Editing:**
352
190
 
353
- Available `compat` fields (all optional, auto-detected if not set):
191
+ | Key | Action |
192
+ |-----|--------|
193
+ | Enter | Send message |
194
+ | Shift+Enter / Alt+Enter | New line (Ctrl+Enter on WSL) |
195
+ | Ctrl+W / Option+Backspace | Delete word backwards |
196
+ | Ctrl+U | Delete to start of line |
197
+ | Ctrl+K | Delete to end of line |
354
198
 
355
- | Field | Type | Default | Description |
356
- |-------|------|---------|-------------|
357
- | `supportsStore` | boolean | auto | Whether provider supports the `store` field |
358
- | `supportsDeveloperRole` | boolean | auto | Whether provider supports `developer` role (vs `system`) |
359
- | `supportsReasoningEffort` | boolean | auto | Whether provider supports `reasoning_effort` parameter |
360
- | `maxTokensField` | string | auto | Use `"max_completion_tokens"` or `"max_tokens"` |
199
+ **Other:**
361
200
 
362
- If `compat` is partially set, unspecified fields use auto-detected values.
201
+ | Key | Action |
202
+ |-----|--------|
203
+ | Tab | Path completion / accept autocomplete |
204
+ | Escape | Cancel autocomplete / abort streaming |
205
+ | Ctrl+C | Clear editor (first) / exit (second) |
206
+ | Shift+Tab | Cycle thinking level |
207
+ | Ctrl+P | Cycle models (scoped by `--models`) |
208
+ | Ctrl+O | Toggle tool output expansion |
209
+ | Ctrl+T | Toggle thinking block visibility |
363
210
 
364
- ### Authorization Header
211
+ ### Bash Mode
365
212
 
366
- Some providers require an explicit `Authorization: Bearer <token>` header. Set `authHeader: true` to automatically add this header using the resolved `apiKey`:
213
+ Prefix commands with `!` to execute them and add output to context:
367
214
 
368
- ```json
369
- {
370
- "providers": {
371
- "qwen": {
372
- "baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
373
- "apiKey": "QWEN_API_KEY",
374
- "authHeader": true,
375
- "api": "openai-completions",
376
- "models": [
377
- {
378
- "id": "qwen3-coder-plus",
379
- "name": "Qwen3 Coder Plus",
380
- "reasoning": true,
381
- "input": ["text"],
382
- "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
383
- "contextWindow": 1000000,
384
- "maxTokens": 65536
385
- }
386
- ]
387
- }
388
- }
389
- }
215
+ ```
216
+ !ls -la
217
+ !git status
218
+ !cat package.json | jq '.dependencies'
390
219
  ```
391
220
 
392
- When `authHeader: true`, the resolved API key is added as `Authorization: Bearer <apiKey>` to the model headers. This is useful for providers that don't use the standard OpenAI authentication mechanism.
393
-
394
- ### Model Selection Priority
395
-
396
- When starting `pi`, models are selected in this order:
397
-
398
- 1. **CLI args**: `--provider` and `--model` flags
399
- 2. **First from `--models` scope**: If `--models` is provided (skipped when using `--continue` or `--resume`)
400
- 3. **Restored from session**: If using `--continue` or `--resume`
401
- 4. **Saved default**: From `~/.pi/agent/settings.json` (set when you select a model with `/model`)
402
- 5. **First available**: First model with a valid API key
403
- 6. **None**: Allowed in interactive mode (shows error on message submission)
221
+ Output streams in real-time. Press Escape to cancel. Large outputs truncate at 2000 lines / 50KB.
404
222
 
405
- ### Provider Defaults
223
+ The output becomes part of your next prompt, formatted as:
406
224
 
407
- When multiple providers are available, pi prefers sensible defaults before falling back to "first available":
225
+ ```
226
+ Ran `ls -la`
227
+ ```
228
+ <output here>
229
+ ```
230
+ ```
408
231
 
409
- | Provider | Default Model |
410
- |------------|--------------------------|
411
- | anthropic | claude-sonnet-4-5 |
412
- | openai | gpt-5.1-codex |
413
- | google | gemini-2.5-pro |
414
- | openrouter | openai/gpt-5.1-codex |
415
- | xai | grok-4-fast-non-reasoning|
416
- | groq | openai/gpt-oss-120b |
417
- | cerebras | zai-glm-4.6 |
418
- | zai | glm-4.6 |
232
+ Run multiple commands before prompting; all outputs are included together.
419
233
 
420
- ### Live Reload & Errors
234
+ ### Image Support
421
235
 
422
- The models.json file is reloaded every time you open the `/model` selector. This means:
236
+ Include image paths in your message:
423
237
 
424
- - Edit models.json during a session
425
- - Or have the agent write/update it for you
426
- - Use `/model` to see changes immediately
427
- - No restart needed!
238
+ ```
239
+ You: What's in this screenshot? /path/to/image.png
240
+ ```
428
241
 
429
- If the file contains errors (JSON syntax, schema violations, missing fields), the selector shows the exact validation error and file path in red so you can fix it immediately.
242
+ Supported: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`
430
243
 
431
- ### Example: Adding Ollama Models
244
+ ---
432
245
 
433
- See the configuration structure above. Create `~/.pi/agent/models.json` with your Ollama setup, then use `/model` to select your local models. The agent can also help you write this file if you point it to this README.
246
+ ## Sessions
434
247
 
435
- ## Themes
248
+ ### Session Management
436
249
 
437
- Pi supports customizable color themes for the TUI. Two built-in themes are available: `dark` (default) and `light`.
250
+ Sessions auto-save to `~/.pi/agent/sessions/` organized by working directory.
438
251
 
439
- ### Selecting a Theme
252
+ ```bash
253
+ pi --continue # Continue most recent session
254
+ pi -c # Short form
440
255
 
441
- Use the `/theme` command to interactively select a theme, or edit your settings file:
256
+ pi --resume # Browse and select from past sessions
257
+ pi -r # Short form
442
258
 
443
- ```bash
444
- # Interactive selector
445
- pi
446
- /theme
259
+ pi --no-session # Ephemeral mode (don't save)
447
260
 
448
- # Or edit ~/.pi/agent/settings.json
449
- {
450
- "theme": "dark" # or "light"
451
- }
261
+ pi --session /path/to/file.jsonl # Use specific session file
452
262
  ```
453
263
 
454
- On first run, Pi auto-detects your terminal background (dark/light) and selects an appropriate theme.
264
+ ### Context Compaction
455
265
 
456
- ### Custom Themes
266
+ Long sessions can exhaust context windows. Compaction summarizes older messages while keeping recent ones.
457
267
 
458
- Create custom themes in `~/.pi/agent/themes/*.json`. Custom themes support **live editing** - when you select a custom theme, Pi watches the file and automatically reloads when you save changes.
268
+ **Manual:** `/compact` or `/compact Focus on the API changes`
459
269
 
460
- **Workflow for creating themes:**
461
- 1. Copy a built-in theme as a starting point:
462
- ```bash
463
- mkdir -p ~/.pi/agent/themes
464
- # Copy dark theme
465
- cp $(npm root -g)/@mariozechner/pi-coding-agent/dist/theme/dark.json ~/.pi/agent/themes/my-theme.json
466
- # Or copy light theme
467
- cp $(npm root -g)/@mariozechner/pi-coding-agent/dist/theme/light.json ~/.pi/agent/themes/my-theme.json
468
- ```
469
- 2. Use `/theme` to select "my-theme"
470
- 3. Edit `~/.pi/agent/themes/my-theme.json` - changes apply immediately on save
471
- 4. Iterate until satisfied (no need to re-select the theme)
270
+ **Automatic:** Enable with `/autocompact`. Triggers when context exceeds threshold.
472
271
 
473
- See [Theme Documentation](docs/theme.md) for:
474
- - Complete list of 44 color tokens
475
- - Theme format and examples
476
- - Color value formats (hex, RGB, terminal default)
272
+ **How it works:**
273
+ 1. Cut point calculated to keep ~20k tokens of recent messages
274
+ 2. Messages before cut point are summarized
275
+ 3. Summary replaces old messages as "context handoff"
276
+ 4. Previous compaction summaries chain into new ones
477
277
 
478
- Example custom theme:
278
+ **Configuration** (`~/.pi/agent/settings.json`):
479
279
 
480
280
  ```json
481
281
  {
482
- "$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/theme-schema.json",
483
- "name": "my-theme",
484
- "vars": {
485
- "accent": "#00aaff",
486
- "muted": "#6c6c6c"
487
- },
488
- "colors": {
489
- "accent": "accent",
490
- "muted": "muted",
491
- ...
282
+ "compaction": {
283
+ "enabled": true,
284
+ "reserveTokens": 16384,
285
+ "keepRecentTokens": 20000
492
286
  }
493
287
  }
494
288
  ```
495
289
 
496
- ### VS Code Terminal Color Issue
497
-
498
- **Important:** VS Code's integrated terminal has a known issue with rendering truecolor (24-bit RGB) values. By default, it applies a "minimum contrast ratio" adjustment that can make colors look washed out or identical.
499
-
500
- To fix this, set the contrast ratio to 1 in VS Code settings:
501
-
502
- 1. Open Settings (Cmd/Ctrl + ,)
503
- 2. Search for: `terminal.integrated.minimumContrastRatio`
504
- 3. Set to: `1`
505
-
506
- This ensures VS Code renders the exact RGB colors defined in your theme.
507
-
508
- ## Slash Commands
509
-
510
- The CLI supports several commands to control its behavior:
511
-
512
- ### /model
513
-
514
- Switch models mid-session. Opens an interactive selector where you can type to search (by provider or model name), use arrow keys to navigate, Enter to select, or Escape to cancel.
515
-
516
- The selector only displays models for which API keys are configured in your environment (see API Keys section).
517
-
518
- ### /thinking
519
-
520
- Adjust thinking/reasoning level for supported models (Claude Sonnet 4, GPT-5, Gemini 2.5). Opens an interactive selector where you can use arrow keys to navigate, Enter to select, or Escape to cancel.
521
-
522
- ### /queue
523
-
524
- Select message queue mode. Opens an interactive selector where you can choose between:
525
- - **one-at-a-time** (default): Process queued messages one by one. When you submit messages while the agent is processing, they're queued and sent individually after each agent response completes.
526
- - **all**: Process all queued messages at once. All queued messages are injected into the context together before the next agent response.
527
-
528
- The queue mode setting is saved and persists across sessions.
529
-
530
- ### /export [filename]
531
-
532
- Export the current session to a self-contained HTML file:
533
-
534
- ```
535
- /export # Auto-generates filename
536
- /export my-session.html # Custom filename
537
- ```
538
-
539
- The HTML file includes the full conversation with syntax highlighting and is viewable in any browser.
290
+ > **Note:** Compaction is lossy. The agent loses full conversation access afterward. Size tasks to avoid context limits when possible. For critical context, ask the agent to write a summary to a file, then start a new session with that file. The full session history is preserved in the JSONL file; use `/branch` to revisit any previous point.
540
291
 
541
- ### /session
292
+ ### Branching
542
293
 
543
- Show session information and statistics:
294
+ Use `/branch` to explore alternative conversation paths:
544
295
 
545
- ```
546
- /session
547
- ```
296
+ 1. Opens selector showing all your user messages
297
+ 2. Select a message to branch from
298
+ 3. Creates new session with history up to that point
299
+ 4. Selected message placed in editor for modification
548
300
 
549
- Displays:
550
- - Session file path and ID
551
- - Message counts (user, assistant, total)
552
- - Token usage (input, output, cache read/write, total)
553
- - Total cost (if available)
301
+ ---
554
302
 
555
- ### /changelog
303
+ ## Configuration
556
304
 
557
- Display the full changelog with all version history (newest last):
305
+ ### Project Context Files
558
306
 
559
- ```
560
- /changelog
561
- ```
307
+ Pi loads `AGENTS.md` (or `CLAUDE.md`) files at startup in this order:
562
308
 
563
- ### /branch
309
+ 1. **Global:** `~/.pi/agent/AGENTS.md`
310
+ 2. **Parent directories:** Walking up from current directory
311
+ 3. **Current directory:** `./AGENTS.md`
564
312
 
565
- Create a new conversation branch from a previous message. Opens an interactive selector showing all your user messages in chronological order. Select a message to:
566
- 1. Create a new session with all messages before the selected one
567
- 2. Place the selected message in the editor for modification or resubmission
313
+ Use these for:
314
+ - Project instructions and guidelines
315
+ - Common commands and workflows
316
+ - Architecture documentation
317
+ - Coding conventions
318
+ - Testing instructions
568
319
 
569
- This allows you to explore alternative conversation paths without losing your current session.
320
+ ```markdown
321
+ # Common Commands
322
+ - npm run build: Build the project
323
+ - npm test: Run tests
570
324
 
325
+ # Code Style
326
+ - Use TypeScript strict mode
327
+ - Prefer async/await over promises
571
328
  ```
572
- /branch
573
- ```
574
-
575
- ### /resume
576
329
 
577
- Switch to a different session. Opens an interactive selector showing all available sessions. Select a session to load it and continue where you left off.
330
+ ### Custom Models and Providers
578
331
 
579
- This is equivalent to the `--resume` CLI flag but can be used mid-session.
332
+ Add custom models (Ollama, vLLM, LM Studio, etc.) via `~/.pi/agent/models.json`:
580
333
 
581
- ```
582
- /resume
334
+ ```json
335
+ {
336
+ "providers": {
337
+ "ollama": {
338
+ "baseUrl": "http://localhost:11434/v1",
339
+ "apiKey": "OLLAMA_API_KEY",
340
+ "api": "openai-completions",
341
+ "models": [
342
+ {
343
+ "id": "llama-3.1-8b",
344
+ "name": "Llama 3.1 8B (Local)",
345
+ "reasoning": false,
346
+ "input": ["text"],
347
+ "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
348
+ "contextWindow": 128000,
349
+ "maxTokens": 32000
350
+ }
351
+ ]
352
+ }
353
+ }
354
+ }
583
355
  ```
584
356
 
585
- ### /login
357
+ **Supported APIs:** `openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai`
586
358
 
587
- Login with OAuth to use subscription-based models (Claude Pro/Max):
359
+ **API key resolution:** The `apiKey` field is checked as environment variable name first, then used as literal value.
588
360
 
589
- ```
590
- /login
591
- ```
592
-
593
- Opens an interactive selector to choose provider, then guides you through the OAuth flow in your browser.
594
-
595
- ### /logout
361
+ **API override:** Set `api` at provider level (default for all models) or model level (override per model).
596
362
 
597
- Logout from OAuth providers:
363
+ **Custom headers:**
598
364
 
599
- ```
600
- /logout
365
+ ```json
366
+ {
367
+ "providers": {
368
+ "custom-proxy": {
369
+ "baseUrl": "https://proxy.example.com/v1",
370
+ "apiKey": "YOUR_API_KEY",
371
+ "api": "anthropic-messages",
372
+ "headers": {
373
+ "User-Agent": "Mozilla/5.0 ...",
374
+ "X-Custom-Auth": "token"
375
+ },
376
+ "models": [...]
377
+ }
378
+ }
379
+ }
601
380
  ```
602
381
 
603
- Shows a list of logged-in providers to logout from.
382
+ **Authorization header:** Set `authHeader: true` to add `Authorization: Bearer <apiKey>` automatically.
604
383
 
605
- ### /clear
384
+ **OpenAI compatibility (`compat` field):**
606
385
 
607
- Clear the conversation context and start a fresh session:
386
+ | Field | Description |
387
+ |-------|-------------|
388
+ | `supportsStore` | Whether provider supports `store` field |
389
+ | `supportsDeveloperRole` | Use `developer` vs `system` role |
390
+ | `supportsReasoningEffort` | Support for `reasoning_effort` parameter |
391
+ | `maxTokensField` | Use `max_completion_tokens` or `max_tokens` |
608
392
 
609
- ```
610
- /clear
611
- ```
393
+ **Live reload:** The file reloads each time you open `/model`. Edit during session; no restart needed.
612
394
 
613
- Aborts any in-flight agent work, clears all messages, and creates a new session file.
395
+ **Model selection priority:**
396
+ 1. CLI args (`--provider`, `--model`)
397
+ 2. First from `--models` scope (new sessions only)
398
+ 3. Restored from session (`--continue`, `--resume`)
399
+ 4. Saved default from settings
400
+ 5. First available model with valid API key
614
401
 
615
- ### /copy
402
+ ### Themes
616
403
 
617
- Copy the last agent message to clipboard:
404
+ Built-in themes: `dark` (default), `light`. Auto-detected on first run.
618
405
 
619
- ```
620
- /copy
406
+ ```bash
407
+ /theme # Interactive selector
621
408
  ```
622
409
 
623
- Extracts text content from the most recent assistant message and copies it to the system clipboard. Works cross-platform (macOS, Windows, Linux). On Linux, requires `xclip` or `xsel` to be installed.
410
+ **Custom themes:** Create `~/.pi/agent/themes/*.json`. Custom themes support live reload.
624
411
 
625
- ### /compact
626
-
627
- Manually compact the conversation context to reduce token usage:
628
-
629
- ```
630
- /compact # Use default summary instructions
631
- /compact Focus on the API changes # Custom instructions for summary
412
+ ```bash
413
+ mkdir -p ~/.pi/agent/themes
414
+ cp $(npm root -g)/@mariozechner/pi-coding-agent/dist/theme/dark.json ~/.pi/agent/themes/my-theme.json
632
415
  ```
633
416
 
634
- Creates a summary of the conversation so far, replacing the message history with a condensed version. See [Context Compaction](#context-compaction) for details.
417
+ Select with `/theme`, then edit the file. Changes apply on save.
635
418
 
636
- ### /autocompact
637
-
638
- Toggle automatic context compaction:
639
-
640
- ```
641
- /autocompact
642
- ```
419
+ See [Theme Documentation](docs/theme.md) for all 44 color tokens.
643
420
 
644
- When enabled, the agent automatically compacts context when usage exceeds the configured threshold. The current state (enabled/disabled) is shown after toggling. See [Context Compaction](#context-compaction) for details.
421
+ **VS Code terminal fix:** Set `terminal.integrated.minimumContrastRatio` to `1` for accurate colors.
645
422
 
646
423
  ### Custom Slash Commands
647
424
 
648
- Define reusable prompt templates as Markdown files that appear in the `/` autocomplete.
425
+ Define reusable prompts as Markdown files:
649
426
 
650
427
  **Locations:**
651
- - **Global:** `~/.pi/agent/commands/*.md` - available in all sessions
652
- - **Project:** `.pi/commands/*.md` - project-specific commands
428
+ - Global: `~/.pi/agent/commands/*.md`
429
+ - Project: `.pi/commands/*.md`
653
430
 
654
- **File format:**
431
+ **Format:**
655
432
 
656
433
  ```markdown
657
434
  ---
@@ -661,596 +438,159 @@ Review the staged changes (`git diff --cached`). Focus on:
661
438
  - Bugs and logic errors
662
439
  - Security issues
663
440
  - Error handling gaps
664
- - Code style per AGENTS.md
665
441
  ```
666
442
 
667
- The filename (without `.md`) becomes the command name. The optional `description` frontmatter field is shown in autocomplete. If omitted, the first line of content is used.
668
-
669
- **Arguments (bash-style):**
443
+ Filename (without `.md`) becomes the command name. Description shown in autocomplete.
670
444
 
671
- Commands support positional arguments with quote-aware parsing:
445
+ **Arguments:**
672
446
 
673
447
  ```markdown
674
448
  ---
675
- description: Create a component with features
449
+ description: Create a component
676
450
  ---
677
- Create a React component named $1 with these features: $@
451
+ Create a React component named $1 with features: $@
678
452
  ```
679
453
 
680
- Usage: `/component Button "has onClick handler" "supports disabled"`
454
+ Usage: `/component Button "onClick handler" "disabled support"`
681
455
  - `$1` = `Button`
682
- - `$2` = `has onClick handler`
683
- - `$@` = `Button has onClick handler supports disabled`
684
-
685
- **Namespacing:**
686
-
687
- Subdirectories create namespaced commands. A file at `.pi/commands/frontend/component.md` creates `/component` with description showing `(project:frontend)`.
688
-
689
- **Source indicators:**
690
-
691
- Commands show their source in autocomplete:
692
- - `(user)` - from `~/.pi/agent/commands/`
693
- - `(project)` - from `.pi/commands/`
694
- - `(project:subdir)` - from `.pi/commands/subdir/`
695
-
696
- **CLI usage:**
697
-
698
- Custom slash commands also work from the command line:
699
-
700
- ```bash
701
- # Non-interactive mode
702
- pi -p "/review"
703
-
704
- # With arguments
705
- pi -p '/component Button "handles click events"'
706
-
707
- # Interactive mode with initial command
708
- pi "/review"
709
- ```
710
-
711
- ## Editor Features
712
-
713
- The interactive input editor includes several productivity features:
714
-
715
- ### File Reference (`@`)
716
-
717
- Type **`@`** to fuzzy-search for files and folders in your project:
718
- - `@editor` → finds files/folders with "editor" in the name
719
- - `@readme` → finds README files anywhere in the project
720
- - `@src` → finds folders like `src/`, `resources/`, etc.
721
- - Directories are prioritized and shown with trailing `/`
722
- - Autocomplete triggers immediately when you type `@`
723
- - Use **Up/Down arrows** to navigate, **Tab**/**Enter** to select
724
-
725
- Respects `.gitignore` files and skips hidden files/directories.
726
-
727
- ### Path Completion
728
-
729
- Press **Tab** to autocomplete file and directory paths:
730
- - Works with relative paths: `./src/` + Tab → complete files in src/
731
- - Works with parent directories: `../../` + Tab → navigate up and complete
732
- - Works with home directory: `~/Des` + Tab → `~/Desktop/`
733
- - Use **Up/Down arrows** to navigate completion suggestions
734
- - Press **Enter** to select a completion
735
- - Shows matching files and directories as you type
736
-
737
- ### File Drag & Drop
738
-
739
- Drag files from your OS file explorer (Finder on macOS, Explorer on Windows) directly onto the terminal. The file path will be automatically inserted into the editor. Works great with screenshots from macOS screenshot tool.
740
-
741
- ### Multi-line Paste
742
-
743
- Paste multiple lines of text (e.g., code snippets, logs) and they'll be automatically coalesced into a compact `[paste #123 <N> lines]` reference in the editor. The full content is still sent to the model.
744
-
745
- ### Message Queuing
746
-
747
- You can submit multiple messages while the agent is processing without waiting for responses. Messages are queued and processed based on your queue mode setting:
748
-
749
- **One-at-a-time mode (default):**
750
- - Each queued message is processed sequentially with its own response
751
- - Example: Queue "task 1", "task 2", "task 3" → agent completes task 1 → processes task 2 → completes task 2 → processes task 3
752
- - Recommended for most use cases
753
-
754
- **All mode:**
755
- - All queued messages are sent to the model at once in a single context
756
- - Example: Queue "task 1", "task 2", "task 3" → agent receives all three together → responds considering all tasks
757
- - Useful when tasks should be considered together
758
-
759
- **Visual feedback:**
760
- - Queued messages appear below the chat with "Queued: <message text>"
761
- - Messages disappear from the queue as they're processed
762
-
763
- **Abort and restore:**
764
- - Press **Escape** while streaming to abort the current operation
765
- - All queued messages (plus any text in the editor) are restored to the editor
766
- - Allows you to modify or remove queued messages before resubmitting
767
-
768
- Change queue mode with `/queue` command. Setting is saved in `~/.pi/agent/settings.json`.
769
-
770
- ### Bash Mode (`!`)
771
-
772
- Execute shell commands directly and add output to the LLM context by prefixing with `!`:
773
-
774
- ```
775
- !ls -la
776
- !git status
777
- !cat package.json | jq '.dependencies'
778
- ```
779
-
780
- **Features:**
781
- - **Streaming output**: Command output streams in real-time as it executes
782
- - **Multiline commands**: Write complex commands across multiple lines
783
- - **Cancellation**: Press **Escape** to cancel a running command
784
- - **Truncation**: Large outputs are truncated (2000 lines / 50KB) with full output saved to a temp file
785
- - **Preview mode**: Shows last 20 lines by default; press **Ctrl+O** to expand
786
- - **History**: Commands are added to editor history (navigate with Up/Down arrows)
787
- - **Visual feedback**: Editor border turns green in bash mode; cancelled commands show yellow warning
788
-
789
- Output is automatically added to the conversation context, allowing the LLM to see command results without manual copy-paste.
790
-
791
- ### Keyboard Shortcuts
792
-
793
- **Navigation:**
794
- - **Arrow keys**: Move cursor (Up/Down navigate visual lines, Left/Right move by character)
795
- - **Up Arrow** (empty editor): Browse previous prompts (history)
796
- - **Down Arrow** (browsing history): Browse newer prompts or return to empty editor
797
- - **Option+Left** / **Ctrl+Left**: Move word backwards
798
- - **Option+Right** / **Ctrl+Right**: Move word forwards
799
- - **Ctrl+A** / **Home**: Jump to start of line
800
- - **Ctrl+E** / **End**: Jump to end of line
801
-
802
- **Editing:**
803
- - **Enter**: Send message
804
- - **Shift+Enter** / **Alt+Enter**: Insert new line (multi-line input). On WSL, use **Ctrl+Enter** instead.
805
- - **Backspace**: Delete character backwards
806
- - **Delete** (or **Fn+Backspace**): Delete character forwards
807
- - **Ctrl+W** / **Option+Backspace**: Delete word backwards (stops at whitespace or punctuation)
808
- - **Ctrl+U**: Delete to start of line (at line start: merge with previous line)
809
- - **Ctrl+K**: Delete to end of line (at line end: merge with next line)
810
-
811
- **Completion:**
812
- - **Tab**: Path completion / Apply autocomplete selection
813
- - **Escape**: Cancel autocomplete (when autocomplete is active)
814
-
815
- **Other:**
816
- - **Ctrl+C**: Clear editor (first press) / Exit pi (second press)
817
- - **Shift+Tab**: Cycle thinking level (for reasoning-capable models)
818
- - **Ctrl+P**: Cycle models (use `--models` to scope)
819
- - **Ctrl+O**: Toggle tool output expansion (collapsed ↔ full output)
820
- - **Ctrl+T**: Toggle thinking block visibility (shows full content ↔ static "Thinking..." label)
821
-
822
- ## Project Context Files
823
-
824
- The agent automatically loads context from `AGENTS.md` or `CLAUDE.md` files at startup. These files are loaded in hierarchical order to support both global preferences and monorepo structures.
825
-
826
- ### File Locations
827
-
828
- Context files are loaded in this order:
829
-
830
- 1. **Global context**: `~/.pi/agent/AGENTS.md` or `CLAUDE.md`
831
- - Applies to all your coding sessions
832
- - Great for personal coding preferences and workflows
833
-
834
- 2. **Parent directories** (top-most first down to current directory)
835
- - Walks up from current directory to filesystem root
836
- - Each directory can have its own `AGENTS.md` or `CLAUDE.md`
837
- - Perfect for monorepos with shared context at higher levels
838
-
839
- 3. **Current directory**: Your project's `AGENTS.md` or `CLAUDE.md`
840
- - Most specific context, loaded last
841
- - Overwrites or extends parent/global context
842
-
843
- **File preference**: In each directory, `AGENTS.md` is preferred over `CLAUDE.md` if both exist.
844
-
845
- ### What to Include
846
-
847
- Context files are useful for:
848
- - Project-specific instructions and guidelines
849
- - Common bash commands and workflows
850
- - Architecture documentation
851
- - Coding conventions and style guides
852
- - Dependencies and setup information
853
- - Testing instructions
854
- - Repository etiquette (branch naming, merge vs. rebase, etc.)
855
-
856
- ### Example
857
-
858
- ```markdown
859
- # Common Commands
860
- - npm run build: Build the project
861
- - npm test: Run tests
862
-
863
- # Code Style
864
- - Use TypeScript strict mode
865
- - Prefer async/await over promises
866
-
867
- # Workflow
868
- - Always run tests before committing
869
- - Update CHANGELOG.md for user-facing changes
870
- ```
871
-
872
- All context files are automatically included in the system prompt at session start, along with the current date/time and working directory. This ensures the AI has complete project context from the very first message.
873
-
874
- ## Image Support
875
-
876
- Send images to vision-capable models by providing file paths:
877
-
878
- ```
879
- You: What is in this screenshot? /path/to/image.png
880
- ```
881
-
882
- Supported formats: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`
883
-
884
- The image will be automatically encoded and sent with your message. JPEG and PNG are supported across all vision models. Other formats may only be supported by some models.
885
-
886
- ## Session Management
887
-
888
- Sessions are automatically saved in `~/.pi/agent/sessions/` organized by working directory. Each session is stored as a JSONL file with a unique timestamp-based ID.
889
-
890
- To continue the most recent session:
891
-
892
- ```bash
893
- pi --continue
894
- # or
895
- pi -c
896
- ```
897
-
898
- To browse and select from past sessions:
899
-
900
- ```bash
901
- pi --resume
902
- # or
903
- pi -r
904
- ```
905
-
906
- This opens an interactive session selector where you can:
907
- - Type to search through session messages
908
- - Use arrow keys to navigate the list
909
- - Press Enter to resume a session
910
- - Press Escape to cancel
911
-
912
- Sessions include all conversation messages, tool calls and results, model switches, and thinking level changes.
913
-
914
- To run without saving a session (ephemeral mode):
915
-
916
- ```bash
917
- pi --no-session
918
- ```
919
-
920
- To use a specific session file instead of auto-generating one:
456
+ - `$@` = all arguments joined
921
457
 
922
- ```bash
923
- pi --session /path/to/my-session.jsonl
924
- ```
925
-
926
- ## Context Compaction
927
-
928
- > **Note:** Compaction is lossy and should generally be avoided. The agent loses access to the full conversation after compaction. Size your tasks to avoid hitting context limits. Alternatively, when context usage approaches 85-90%, ask the agent to write a summary to a markdown file, iterate until it captures everything important, then start a new session with that file.
929
- >
930
- > That said, compaction does not destroy history. The full session is preserved in the session file with compaction events as markers. You can branch (`/branch`) from any previous message, and branched sessions include the complete history. If compaction missed something, you can ask the agent to read the session file directly.
931
-
932
- Long sessions can exhaust the model's context window. Context compaction summarizes older conversation history while preserving recent messages, allowing sessions to continue indefinitely.
933
-
934
- ### How It Works
935
-
936
- When compaction runs (manually via `/compact` or automatically):
937
-
938
- 1. A **cut point** is calculated to keep approximately `keepRecentTokens` (default: 20k) worth of recent messages
939
- 2. Messages **before** the cut point are sent to the model for summarization
940
- 3. Messages **after** the cut point are kept verbatim
941
- 4. The summary replaces the older messages as a "context handoff" message
942
- 5. If there was a previous compaction, its summary is included as context for the new summary (chaining)
943
-
944
- Cut points are always placed at user message boundaries to preserve turn integrity.
945
-
946
- The summary is displayed in the TUI as a collapsible block (toggle with `o` key). HTML exports also show compaction summaries as collapsible sections.
947
-
948
- ### Manual Compaction
949
-
950
- Use `/compact` to manually trigger compaction at any time:
951
-
952
- ```
953
- /compact # Default summary
954
- /compact Focus on the API changes # Custom instructions guide what to emphasize
955
- ```
956
-
957
- Custom instructions are appended to the default summary prompt, letting you focus the summary on specific aspects of the conversation.
958
-
959
- ### Automatic Compaction
960
-
961
- Enable auto-compaction with `/autocompact`. When enabled, compaction triggers automatically when context usage exceeds `contextWindow - reserveTokens`.
458
+ **Namespacing:** Subdirectories create prefixes. `.pi/commands/frontend/component.md` → `/component (project:frontend)`
962
459
 
963
- The context percentage is shown in the footer. When it approaches 100%, auto-compaction kicks in (if enabled) or you should manually compact.
460
+ ### Settings File
964
461
 
965
- ### Configuration
966
-
967
- Power users can tune compaction behavior in `~/.pi/agent/settings.json`:
462
+ `~/.pi/agent/settings.json` stores persistent preferences:
968
463
 
969
464
  ```json
970
465
  {
466
+ "theme": "dark",
467
+ "shellPath": "C:\\path\\to\\bash.exe",
468
+ "queueMode": "one-at-a-time",
971
469
  "compaction": {
972
- "enabled": true,
470
+ "enabled": false,
973
471
  "reserveTokens": 16384,
974
472
  "keepRecentTokens": 20000
975
473
  }
976
474
  }
977
475
  ```
978
476
 
979
- - **enabled**: Whether auto-compaction is active (toggle with `/autocompact`)
980
- - **reserveTokens**: Token buffer to keep free (default: 16,384). Auto-compaction triggers when `contextTokens > contextWindow - reserveTokens`
981
- - **keepRecentTokens**: How many tokens worth of recent messages to preserve verbatim (default: 20,000). Older messages are summarized.
982
-
983
- ### Supported Modes
984
-
985
- Context compaction works in both interactive and RPC modes:
986
-
987
- - **Interactive**: Use `/compact` and `/autocompact` commands
988
- - **RPC**: Send `{"type":"compact"}` for manual compaction. Auto-compaction emits `{"type":"compaction","auto":true}` events. See [RPC documentation](docs/rpc.md) for details.
477
+ ---
989
478
 
990
- ## CLI Options
479
+ ## CLI Reference
991
480
 
992
481
  ```bash
993
482
  pi [options] [@files...] [messages...]
994
483
  ```
995
484
 
996
- ### File Arguments (`@file`)
485
+ ### Options
997
486
 
998
- You can include files directly in your initial message using the `@` prefix:
487
+ | Option | Description |
488
+ |--------|-------------|
489
+ | `--provider <name>` | Provider: `anthropic`, `openai`, `google`, `xai`, `groq`, `cerebras`, `openrouter`, `zai`, or custom |
490
+ | `--model <id>` | Model ID |
491
+ | `--api-key <key>` | API key (overrides environment) |
492
+ | `--system-prompt <text\|file>` | Custom system prompt (text or file path) |
493
+ | `--append-system-prompt <text\|file>` | Append to system prompt |
494
+ | `--mode <mode>` | Output mode: `text`, `json`, `rpc` (implies `--print`) |
495
+ | `--print`, `-p` | Non-interactive: process prompt and exit |
496
+ | `--no-session` | Don't save session |
497
+ | `--session <path>` | Use specific session file |
498
+ | `--continue`, `-c` | Continue most recent session |
499
+ | `--resume`, `-r` | Select session to resume |
500
+ | `--models <patterns>` | Comma-separated patterns for Ctrl+P cycling (e.g., `sonnet:high,haiku:low`) |
501
+ | `--tools <tools>` | Comma-separated tool list (default: `read,bash,edit,write`) |
502
+ | `--thinking <level>` | Thinking level: `off`, `minimal`, `low`, `medium`, `high` |
503
+ | `--export <file> [output]` | Export session to HTML |
504
+ | `--help`, `-h` | Show help |
505
+
506
+ ### File Arguments
507
+
508
+ Include files with `@` prefix:
999
509
 
1000
510
  ```bash
1001
- # Include a text file in your prompt
1002
- pi @prompt.md "Answer the question"
1003
-
1004
- # Include multiple files
1005
- pi @requirements.md @context.txt "Summarize these"
1006
-
1007
- # Include images (vision-capable models only)
511
+ pi @prompt.md "Answer this"
1008
512
  pi @screenshot.png "What's in this image?"
1009
-
1010
- # Mix text and images
1011
- pi @prompt.md @diagram.png "Explain based on the diagram"
1012
-
1013
- # Files without additional text
1014
- pi @task.md
1015
- ```
1016
-
1017
- **How it works:**
1018
- - All `@file` arguments are combined into the first user message
1019
- - Text files are wrapped in `<file name="path">content</file>` tags
1020
- - Images (`.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`) are attached as base64-encoded attachments
1021
- - Paths support `~` for home directory and relative/absolute paths
1022
- - Empty files are skipped
1023
- - Non-existent files cause an immediate error
1024
-
1025
- **Examples:**
1026
- ```bash
1027
- # All files go into first message, regardless of position
1028
- pi @file1.md @file2.txt "prompt" @file3.md
1029
-
1030
- # This sends:
1031
- # Message 1: file1 + file2 + file3 + "prompt"
1032
- # (Any additional plain text arguments become separate messages)
1033
-
1034
- # Home directory expansion works
1035
- pi @~/Documents/notes.md "Summarize"
1036
-
1037
- # Combine with other options
1038
- pi --print @requirements.md "List the main points"
513
+ pi @requirements.md @design.png "Implement this"
1039
514
  ```
1040
515
 
1041
- **Limitations:**
1042
- - Not supported in `--mode rpc` (will error)
1043
- - Images require vision-capable models (e.g., Claude, GPT-4o, Gemini)
1044
-
1045
- ### Options
1046
-
1047
- **--provider <name>**
1048
- Provider name. Available: `anthropic`, `openai`, `google`, `xai`, `groq`, `cerebras`, `openrouter`, `zai`, plus any custom providers defined in `~/.pi/agent/models.json`.
1049
-
1050
- **--model <id>**
1051
- Model ID. If not specified, uses: (1) saved default from settings, (2) first available model with valid API key, or (3) none (interactive mode only).
1052
-
1053
- **--api-key <key>**
1054
- API key (overrides environment variables)
1055
-
1056
- **--system-prompt <text|file>**
1057
- Custom system prompt. Can be:
1058
- - Inline text: `--system-prompt "You are a helpful assistant"`
1059
- - File path: `--system-prompt ./my-prompt.txt`
1060
-
1061
- If the argument is a valid file path, the file contents will be used as the system prompt. Otherwise, the text is used directly. Project context files and datetime are automatically appended.
1062
-
1063
- **--append-system-prompt <text|file>**
1064
- Append additional text or file contents to the system prompt. Can be:
1065
- - Inline text: `--append-system-prompt "Also consider edge cases"`
1066
- - File path: `--append-system-prompt ./extra-instructions.txt`
1067
-
1068
- If the argument is a valid file path, the file contents will be appended. Otherwise, the text is appended directly. This complements `--system-prompt` for layering custom instructions without replacing the base system prompt. Works in both custom and default system prompts.
1069
-
1070
- **--mode <mode>**
1071
- Output mode for non-interactive usage (implies `--print`). Options:
1072
- - `text` (default): Output only the final assistant message text
1073
- - `json`: Stream all agent events as JSON (one event per line). Events are emitted by `@mariozechner/pi-agent` and include message updates, tool executions, and completions
1074
- - `rpc`: JSON mode plus stdin listener for headless operation. Send JSON commands on stdin: `{"type":"prompt","message":"..."}` or `{"type":"abort"}`. See [test/rpc-example.ts](test/rpc-example.ts) for a complete example
1075
-
1076
- **--print, -p**
1077
- Non-interactive mode: process the prompt(s) and exit. Without this flag, passing a prompt starts interactive mode with the prompt pre-submitted. Similar to Claude's `-p` flag and Codex's `exec` command.
1078
-
1079
- **--no-session**
1080
- Don't save session (ephemeral mode)
1081
-
1082
- **--session <path>**
1083
- Use specific session file path instead of auto-generating one
1084
-
1085
- **--continue, -c**
1086
- Continue the most recent session
1087
-
1088
- **--resume, -r**
1089
- Select a session to resume (opens interactive selector)
1090
-
1091
- **--models <patterns>**
1092
- Comma-separated model patterns for quick cycling with `Ctrl+P`. Matching priority:
1093
- 1. `provider/modelId` exact match (e.g., `openrouter/openai/gpt-5.1-codex`)
1094
- 2. Exact model ID match (e.g., `gpt-5.1-codex`)
1095
- 3. Partial match against model IDs and names (case-insensitive)
1096
-
1097
- When multiple partial matches exist, prefers aliases over dated versions (e.g., `claude-sonnet-4-5` over `claude-sonnet-4-5-20250929`). Without this flag, `Ctrl+P` cycles through all available models.
1098
-
1099
- Each pattern can optionally include a thinking level suffix: `pattern:level` where level is one of `off`, `minimal`, `low`, `medium`, or `high`. When cycling models, the associated thinking level is automatically applied. The first model in the list is used as the initial model when starting a new session.
1100
-
1101
- Examples:
1102
- - `--models openrouter/openai/gpt-5.1-codex` - Exact provider/model match
1103
- - `--models gpt-5.1-codex` - Exact ID match (not `openai/gpt-5.1-codex-mini`)
1104
- - `--models sonnet:high,haiku:low` - Sonnet with high thinking, Haiku with low thinking
1105
- - `--models sonnet,haiku` - Partial match for any model containing "sonnet" or "haiku"
1106
-
1107
- **--tools <tools>**
1108
- Comma-separated list of tools to enable. By default, pi uses `read,bash,edit,write`. This flag allows restricting or changing the available tools.
1109
-
1110
- Available tools:
1111
- - `read` - Read file contents
1112
- - `bash` - Execute bash commands
1113
- - `edit` - Make surgical edits to files
1114
- - `write` - Create or overwrite files
1115
- - `grep` - Search file contents for patterns (read-only, off by default)
1116
- - `find` - Find files by glob pattern (read-only, off by default)
1117
- - `ls` - List directory contents (read-only, off by default)
1118
-
1119
- Examples:
1120
- - `--tools read,grep,find,ls` - Read-only mode for code review/exploration
1121
- - `--tools read,bash` - Only allow reading and bash commands
1122
-
1123
- **--thinking <level>**
1124
- Set thinking level for reasoning-capable models. Valid values: `off`, `minimal`, `low`, `medium`, `high`. Takes highest priority over all other thinking level sources (saved settings, `--models` pattern levels, session restore).
1125
-
1126
- Examples:
1127
- - `--thinking high` - Start with high thinking level
1128
- - `--thinking off` - Disable thinking even if saved setting was different
1129
-
1130
- **--export <file>**
1131
- Export a session file to a self-contained HTML file and exit. Auto-detects format (session manager format or streaming event format). Optionally provide an output filename as the second argument.
1132
-
1133
- **Note:** When exporting streaming event logs (e.g., `pi-output.jsonl` from `--mode json`), the system prompt and tool definitions are not available since they are not recorded in the event stream. The exported HTML will include a notice about this.
1134
-
1135
- Examples:
1136
- - `--export session.jsonl` - Export to `pi-session-session.html`
1137
- - `--export session.jsonl output.html` - Export to custom filename
1138
-
1139
- **--help, -h**
1140
- Show help message
516
+ Text files wrapped in `<file name="path">content</file>`. Images attached as base64.
1141
517
 
1142
518
  ### Examples
1143
519
 
1144
520
  ```bash
1145
- # Start interactive mode
521
+ # Interactive mode
1146
522
  pi
1147
523
 
1148
- # Interactive mode with initial prompt (stays running after completion)
524
+ # Interactive with initial prompt
1149
525
  pi "List all .ts files in src/"
1150
526
 
1151
- # Include files in your prompt
1152
- pi @requirements.md @design.png "Implement this feature"
1153
-
1154
- # Non-interactive mode (process prompt and exit)
527
+ # Non-interactive
1155
528
  pi -p "List all .ts files in src/"
1156
529
 
1157
- # Non-interactive with files
1158
- pi -p @code.ts "Review this code for bugs"
530
+ # With files
531
+ pi -p @code.ts "Review this code"
1159
532
 
1160
- # JSON mode - stream all agent events (non-interactive)
1161
- pi --mode json "List all .ts files in src/"
533
+ # JSON event stream
534
+ pi --mode json "List files"
1162
535
 
1163
- # RPC mode - headless operation (see test/rpc-example.ts)
536
+ # RPC mode (headless)
1164
537
  pi --mode rpc --no-session
1165
- # Then send JSON on stdin:
1166
- # {"type":"prompt","message":"List all .ts files"}
1167
- # {"type":"abort"}
1168
538
 
1169
- # Continue previous session
539
+ # Continue session
1170
540
  pi -c "What did we discuss?"
1171
541
 
1172
- # Use different model
1173
- pi --provider openai --model gpt-4o "Help me refactor this code"
1174
-
1175
- # Limit model cycling to specific models
1176
- pi --models claude-sonnet,claude-haiku,gpt-4o
1177
- # Now Ctrl+P cycles only through those models
542
+ # Specific model
543
+ pi --provider openai --model gpt-4o "Help me refactor"
1178
544
 
1179
545
  # Model cycling with thinking levels
1180
546
  pi --models sonnet:high,haiku:low
1181
- # Starts with sonnet at high thinking, Ctrl+P switches to haiku at low thinking
1182
-
1183
- # Start with specific thinking level
1184
- pi --thinking high "Solve this complex algorithm problem"
1185
547
 
1186
- # Read-only mode (no file modifications possible)
1187
- pi --tools read,grep,find,ls -p "Review the architecture in src/"
548
+ # Read-only mode
549
+ pi --tools read,grep,find,ls -p "Review the architecture"
1188
550
 
1189
- # Oracle-style subagent (bash for git/gh, no file modifications)
1190
- pi --tools read,bash,grep,find,ls \
1191
- --no-session \
1192
- -p "Use bash only for read-only operations. Read issue #74 with gh, then review the implementation"
1193
-
1194
- # Export a session file to HTML
1195
- pi --export ~/.pi/agent/sessions/--myproject--/session.jsonl
1196
- pi --export session.jsonl my-export.html
551
+ # Export session
552
+ pi --export session.jsonl output.html
1197
553
  ```
1198
554
 
555
+ ---
556
+
1199
557
  ## Tools
1200
558
 
1201
559
  ### Default Tools
1202
560
 
1203
- By default, the agent has access to four core tools:
561
+ | Tool | Description |
562
+ |------|-------------|
563
+ | `read` | Read file contents. Images sent as attachments. Text: first 2000 lines, lines truncated at 2000 chars. Use offset/limit for large files. |
564
+ | `write` | Write/overwrite file. Creates parent directories. |
565
+ | `edit` | Replace exact text in file. Must match exactly including whitespace. Fails if text appears multiple times or not found. |
566
+ | `bash` | Execute command. Returns stdout/stderr. Optional `timeout` parameter. |
1204
567
 
1205
- **read**
1206
- Read file contents. Supports text files and images (jpg, png, gif, webp). Images are sent as attachments. For text files, defaults to first 2000 lines. Use offset/limit parameters for large files. Lines longer than 2000 characters are truncated.
568
+ ### Read-Only Tools
1207
569
 
1208
- **write**
1209
- Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.
570
+ Available via `--tools` flag:
1210
571
 
1211
- **edit**
1212
- Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits. Returns an error if the text appears multiple times or isn't found.
572
+ | Tool | Description |
573
+ |------|-------------|
574
+ | `grep` | Search file contents (regex or literal). Respects `.gitignore`. |
575
+ | `find` | Search for files by glob pattern. Respects `.gitignore`. |
576
+ | `ls` | List directory contents. Includes dotfiles. |
1213
577
 
1214
- **bash**
1215
- Execute a bash command in the current working directory. Returns stdout and stderr. Optionally accepts a `timeout` parameter (in seconds) - no default timeout.
578
+ Example: `--tools read,grep,find,ls` for code review without modification.
1216
579
 
1217
- ### Read-Only Exploration Tools
580
+ ### Custom Tools
1218
581
 
1219
- These tools are available via `--tools` flag for read-only code exploration:
1220
-
1221
- **grep**
1222
- Search file contents for a pattern (regex or literal). Returns matching lines with file paths and line numbers. Respects `.gitignore`. Parameters: `pattern` (required), `path`, `glob`, `ignoreCase`, `literal`, `context`, `limit`.
1223
-
1224
- **find**
1225
- Search for files by glob pattern (e.g., `**/*.ts`). Returns matching file paths relative to the search directory. Respects `.gitignore`. Parameters: `pattern` (required), `path`, `limit`.
1226
-
1227
- **ls**
1228
- List directory contents. Returns entries sorted alphabetically with `/` suffix for directories. Includes dotfiles. Parameters: `path`, `limit`.
1229
-
1230
- ### MCP & Adding Your Own Tools
1231
-
1232
- **pi does and will not support MCP.** Instead, it relies on the four built-in tools above and assumes the agent can invoke pre-existing CLI tools or write them on the fly as needed.
1233
-
1234
- **Here's the gist:**
1235
-
1236
- 1. Create a simple CLI tool (any language, any executable)
1237
- 2. Write a concise README.md describing what it does and how to use it
1238
- 3. Tell the agent to read that README
1239
-
1240
- **Minimal example:**
582
+ Pi relies on CLI tools invoked via bash rather than MCP. Create a tool with a README:
1241
583
 
1242
584
  `~/agent-tools/screenshot/README.md`:
1243
585
  ```markdown
1244
586
  # Screenshot Tool
1245
-
1246
587
  Takes a screenshot of your main display.
1247
588
 
1248
589
  ## Usage
1249
590
  ```bash
1250
591
  screenshot.sh
1251
592
  ```
1252
-
1253
- Returns the path to the saved PNG file.
593
+ Returns the path to the saved PNG.
1254
594
  ```
1255
595
 
1256
596
  `~/agent-tools/screenshot/screenshot.sh`:
@@ -1260,117 +600,106 @@ screencapture -x /tmp/screenshot-$(date +%s).png
1260
600
  ls -t /tmp/screenshot-*.png | head -1
1261
601
  ```
1262
602
 
1263
- **In your session:**
1264
- ```
1265
- You: Read ~/agent-tools/screenshot/README.md and use that tool to take a screenshot
1266
- ```
603
+ Usage: "Read ~/agent-tools/screenshot/README.md and take a screenshot"
604
+
605
+ Reference tool READMEs in `AGENTS.md` to make them automatically available.
1267
606
 
1268
- The agent will read the README, understand the tool, and invoke it via bash as needed. If you need a new tool, ask the agent to write it for you.
607
+ ---
1269
608
 
1270
- You can also reference tool READMEs in your `AGENTS.md` files to make them automatically available:
1271
- - Global: `~/.pi/agent/AGENTS.md` - available in all sessions
1272
- - Project-specific: `./AGENTS.md` - available in this project
609
+ ## Programmatic Usage
1273
610
 
1274
- **Real-world example:**
611
+ ### RPC Mode
1275
612
 
1276
- The [exa-search](https://github.com/badlogic/exa-search) tools provide web search capabilities via the Exa API. Built by the agent itself in ~2 minutes. Far from perfect, but functional. Just tell your agent: "Read ~/agent-tools/exa-search/README.md and search for X".
613
+ For embedding pi in other applications:
1277
614
 
1278
- For a detailed walkthrough with more examples, and the reasons for and benefits of this decision, see: https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/
615
+ ```bash
616
+ pi --mode rpc --no-session
617
+ ```
1279
618
 
1280
- ## Security (YOLO by default)
619
+ Send JSON commands on stdin:
620
+ ```json
621
+ {"type":"prompt","message":"List all .ts files"}
622
+ {"type":"abort"}
623
+ ```
1281
624
 
1282
- This agent runs in full YOLO mode and assumes you know what you're doing. It has unrestricted access to your filesystem and can execute any command without permission checks or safety rails.
625
+ See [RPC documentation](docs/rpc.md) for full protocol.
1283
626
 
1284
- **What this means:**
1285
- - No permission prompts for file operations or commands
1286
- - No pre-checking of bash commands for malicious content
1287
- - Full filesystem access - can read, write, or delete anything
1288
- - Can execute any command with your user privileges
627
+ **Node.js/TypeScript:** Consider using `AgentSession` directly from `@mariozechner/pi-coding-agent` instead of subprocess. See [`src/core/agent-session.ts`](src/core/agent-session.ts) and [`src/modes/rpc/rpc-client.ts`](src/modes/rpc/rpc-client.ts).
1289
628
 
1290
- **Why:**
1291
- - Permission systems add massive friction while being easily circumvented
1292
- - Pre-checking tools for "dangerous" patterns introduces latency, false positives, and is ineffective
629
+ ### HTML Export
1293
630
 
1294
- **Prompt injection risks:**
1295
- - By default, pi has no web search or fetch tool
1296
- - However, it can use `curl` or read files from disk
1297
- - Both provide ample surface area for prompt injection attacks
1298
- - Malicious content in files or command outputs can influence behavior
631
+ ```bash
632
+ pi --export session.jsonl # Auto-generated filename
633
+ pi --export session.jsonl output.html # Custom filename
634
+ ```
1299
635
 
1300
- **Mitigations:**
1301
- - Run pi inside a container if you're uncomfortable with full access
1302
- - Use a different tool if you need guardrails
1303
- - Don't use pi on systems with sensitive data you can't afford to lose
1304
- - Fork pi and add all of the above
636
+ Works with both session files and streaming event logs from `--mode json`.
1305
637
 
1306
- This is how I want it to work and I'm not likely to change my stance on this.
638
+ ---
1307
639
 
1308
- Use at your own risk.
640
+ ## Philosophy
1309
641
 
1310
- ## Sub-Agents
642
+ Pi is opinionated about what it won't do. These are intentional design decisions.
1311
643
 
1312
- **pi does not and will not support sub-agents as a built-in feature.** If the agent needs to delegate work, it can:
644
+ ### No MCP
1313
645
 
1314
- 1. Spawn another instance of itself via the `pi` CLI command
1315
- 2. Write a custom tool with a README.md that describes how to invoke pi for specific tasks
646
+ Pi does not support MCP (Model Context Protocol). Instead, it relies on four core tools (read, write, edit, bash) and assumes the agent can invoke CLI tools or write them as needed.
1316
647
 
1317
- **Why no built-in sub-agents:**
648
+ CLI tools are simpler: any executable with a README works. No protocol overhead, no server management. The agent reads the README and uses bash.
1318
649
 
1319
- Context transfer between agents is generally poor. Information gets lost, compressed, or misrepresented when passed through agent boundaries. Direct execution with full context is more effective than delegation with summarized context.
650
+ See: [What if you don't need MCP?](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/)
1320
651
 
1321
- If you need parallel work on independent tasks, manually run multiple `pi` sessions in different terminal tabs. You're the orchestrator.
652
+ ### No Sub-Agents
1322
653
 
1323
- ## To-Dos
654
+ If the agent needs to delegate, it can spawn `pi` via bash or write a custom tool. Built-in sub-agents transfer context poorly; information gets lost or misrepresented. For parallel work, run multiple `pi` sessions in different terminals.
1324
655
 
1325
- **pi does not and will not support built-in to-dos.** In my experience, to-do lists generally confuse models more than they help.
656
+ ### No Built-in To-Dos
1326
657
 
1327
- If you need task tracking, make it stateful by writing to a file:
658
+ To-do lists confuse models more than they help. For task tracking, use a file:
1328
659
 
1329
660
  ```markdown
1330
661
  # TODO.md
1331
-
1332
- - [x] Implement user authentication
1333
- - [x] Add database migrations
1334
- - [ ] Write API documentation
1335
- - [ ] Add rate limiting
662
+ - [x] Implement authentication
663
+ - [ ] Write API docs
1336
664
  ```
1337
665
 
1338
- The agent can read and update this file as needed. Using checkboxes keeps track of what's done and what remains. Simple, visible, and under your control.
1339
-
1340
- ## Planning
666
+ ### No Planning Mode
1341
667
 
1342
- **pi does not and will not have a built-in planning mode.** Telling the agent to think through a problem together with you, without modifying files or executing commands, is generally sufficient.
1343
-
1344
- If you need persistent planning across sessions, write it to a file:
668
+ Tell the agent to think through problems without modifying files. For persistent plans, write to a file:
1345
669
 
1346
670
  ```markdown
1347
671
  # PLAN.md
1348
-
1349
672
  ## Goal
1350
- Refactor authentication system to support OAuth
1351
-
1352
- ## Approach
1353
- 1. Research OAuth 2.0 flows
1354
- 2. Design token storage schema
1355
- 3. Implement authorization server endpoints
1356
- 4. Update client-side login flow
1357
- 5. Add tests
1358
-
673
+ Refactor auth to support OAuth
1359
674
  ## Current Step
1360
- Working on step 3 - authorization endpoints
675
+ Working on authorization endpoints
1361
676
  ```
1362
677
 
1363
- The agent can read, update, and reference the plan as it works. Unlike ephemeral planning modes that only exist within a session, file-based plans persist and can be versioned with your code.
678
+ ### No Permission System (YOLO Mode)
679
+
680
+ Pi runs with full filesystem access and no permission prompts. Why:
681
+ - Permission systems add friction while being easily circumvented
682
+ - Pre-checking for "dangerous" patterns causes latency and false positives
1364
683
 
1365
- ## Background Bash
684
+ **Risks:**
685
+ - Can read, write, delete anything with your user privileges
686
+ - Prompt injection via files or command output can influence behavior
687
+
688
+ **Mitigations:**
689
+ - Run in a container if uncomfortable
690
+ - Don't use on systems with sensitive data you can't afford to lose
1366
691
 
1367
- **pi does not and will not implement background bash execution.** Instead, tell the agent to use `tmux` or something like [tterminal-cp](https://mariozechner.at/posts/2025-08-15-mcp-vs-cli/). Bonus points: you can watch the agent interact with a CLI like a debugger and even intervene if necessary.
692
+ ### No Background Bash
693
+
694
+ Use `tmux` or similar. Bonus: you can watch the agent interact with CLIs and intervene if needed.
695
+
696
+ ---
1368
697
 
1369
698
  ## Development
1370
699
 
1371
700
  ### Forking / Rebranding
1372
701
 
1373
- All branding (app name, config directory) is configurable via `package.json`:
702
+ Configure via `package.json`:
1374
703
 
1375
704
  ```json
1376
705
  {
@@ -1381,48 +710,27 @@ All branding (app name, config directory) is configurable via `package.json`:
1381
710
  }
1382
711
  ```
1383
712
 
1384
- To create a fork with different branding:
1385
- 1. Change `piConfig.name` to your app name (e.g., `"tau"`)
1386
- 2. Change `piConfig.configDir` to your config directory (e.g., `".tau"`)
1387
- 3. Change the `bin` field to your command name: `"bin": { "tau": "dist/cli.js" }`
1388
-
1389
- This affects:
1390
- - CLI banner and help text
1391
- - Config directory (`~/.pi/agent/` → `~/.tau/agent/`)
1392
- - Environment variable name (`PI_CODING_AGENT_DIR` → `TAU_CODING_AGENT_DIR`)
1393
- - All user-facing paths in error messages and documentation
713
+ Change `name`, `configDir`, and `bin` field for your fork. Affects CLI banner, config paths, and environment variable names.
1394
714
 
1395
715
  ### Path Resolution
1396
716
 
1397
- The codebase supports three execution modes:
1398
- - **npm**: Running via `node dist/cli.js` after npm install
1399
- - **Bun binary**: Standalone compiled binary with files alongside
1400
- - **tsx**: Running directly from source via `npx tsx src/cli.ts`
717
+ Three execution modes: npm install, standalone binary, tsx from source.
1401
718
 
1402
- All path resolution for package assets (package.json, README.md, CHANGELOG.md, themes) must go through `src/paths.ts`:
719
+ **Always use `src/paths.ts`** for package assets:
1403
720
 
1404
721
  ```typescript
1405
- import { getPackageDir, getThemeDir, getPackageJsonPath, getReadmePath, getChangelogPath } from "./paths.js";
722
+ import { getPackageDir, getThemeDir } from "./paths.js";
1406
723
  ```
1407
724
 
1408
- **Never use `__dirname` directly** for resolving package assets. The `paths.ts` module handles the differences between execution modes automatically.
725
+ Never use `__dirname` directly for package assets.
1409
726
 
1410
727
  ### Debug Command
1411
728
 
1412
- The `/debug` command is a hidden development feature (not shown in autocomplete) that writes all currently rendered lines with their visible widths and ANSI escape sequences to `~/.pi/agent/pi-debug.log`. This is useful for debugging TUI rendering issues, especially when lines don't extend to the terminal edge or contain unexpected invisible characters.
1413
-
1414
- ```
1415
- /debug
1416
- ```
729
+ `/debug` (hidden) writes rendered lines with ANSI codes to `~/.pi/agent/pi-debug.log` for TUI debugging.
1417
730
 
1418
- The debug log includes:
1419
- - Terminal width at time of capture
1420
- - Total number of rendered lines
1421
- - Each line with its index, visible width, and JSON-escaped content showing all ANSI codes
731
+ For architecture and contribution guidelines, see [DEVELOPMENT.md](./DEVELOPMENT.md).
1422
732
 
1423
- ## Development
1424
-
1425
- For architecture details, code organization, and contribution guidelines, see [DEVELOPMENT.md](./DEVELOPMENT.md).
733
+ ---
1426
734
 
1427
735
  ## License
1428
736
 
@@ -1430,5 +738,5 @@ MIT
1430
738
 
1431
739
  ## See Also
1432
740
 
1433
- - [@mariozechner/pi-ai](https://www.npmjs.com/package/@mariozechner/pi-ai): Core LLM toolkit with multi-provider support
1434
- - [@mariozechner/pi-agent](https://www.npmjs.com/package/@mariozechner/pi-agent): Agent framework with tool execution
741
+ - [@mariozechner/pi-ai](https://www.npmjs.com/package/@mariozechner/pi-ai): Core LLM toolkit
742
+ - [@mariozechner/pi-agent](https://www.npmjs.com/package/@mariozechner/pi-agent): Agent framework