@mariozechner/pi-coding-agent 0.15.0 → 0.17.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +418 -1106
  3. package/dist/core/agent-session.d.ts +5 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +65 -18
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/compaction.d.ts +30 -5
  8. package/dist/core/compaction.d.ts.map +1 -1
  9. package/dist/core/compaction.js +194 -61
  10. package/dist/core/compaction.js.map +1 -1
  11. package/dist/core/session-manager.d.ts +10 -3
  12. package/dist/core/session-manager.d.ts.map +1 -1
  13. package/dist/core/session-manager.js +78 -28
  14. package/dist/core/session-manager.js.map +1 -1
  15. package/dist/core/tools/truncate.d.ts +6 -2
  16. package/dist/core/tools/truncate.d.ts.map +1 -1
  17. package/dist/core/tools/truncate.js +11 -1
  18. package/dist/core/tools/truncate.js.map +1 -1
  19. package/dist/modes/index.d.ts +3 -1
  20. package/dist/modes/index.d.ts.map +1 -1
  21. package/dist/modes/index.js +2 -2
  22. package/dist/modes/index.js.map +1 -1
  23. package/dist/modes/interactive/components/bash-execution.d.ts +1 -0
  24. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  25. package/dist/modes/interactive/components/bash-execution.js +17 -6
  26. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  27. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  28. package/dist/modes/interactive/components/tool-execution.js +12 -7
  29. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  30. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  31. package/dist/modes/interactive/interactive-mode.js +18 -4
  32. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  33. package/dist/modes/rpc/rpc-client.d.ts +182 -0
  34. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  35. package/dist/modes/rpc/rpc-client.js +362 -0
  36. package/dist/modes/rpc/rpc-client.js.map +1 -0
  37. package/dist/modes/rpc/rpc-mode.d.ts +19 -0
  38. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  39. package/dist/modes/rpc/rpc-mode.js +205 -0
  40. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  41. package/dist/modes/rpc/rpc-types.d.ts +255 -0
  42. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  43. package/dist/modes/rpc/rpc-types.js +8 -0
  44. package/dist/modes/rpc/rpc-types.js.map +1 -0
  45. package/package.json +4 -4
  46. package/dist/modes/rpc-mode.d.ts +0 -21
  47. package/dist/modes/rpc-mode.d.ts.map +0 -1
  48. package/dist/modes/rpc-mode.js +0 -77
  49. package/dist/modes/rpc-mode.js.map +0 -1
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.
71
+ **macOS note:** The binary is unsigned. If blocked, run: `xattr -c ./pi`
65
72
 
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
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
87
-
88
- On Windows, pi requires a bash shell. The following locations are checked in order:
82
+ ### Windows Setup
89
83
 
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.)
84
+ Pi requires a bash shell on Windows. Checked locations (in order):
93
85
 
94
- For most users, installing [Git for Windows](https://git-scm.com/download/win) is sufficient.
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)
95
89
 
96
- ### Custom Shell Path
90
+ For most users, [Git for Windows](https://git-scm.com/download/win) is sufficient.
97
91
 
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,756 +98,228 @@ 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.
101
+ ### API Keys
108
102
 
109
- ## Quick Start
103
+ Set the environment variable for your provider:
110
104
 
111
- ```bash
112
- # Set your API key (see API Keys section)
113
- export ANTHROPIC_API_KEY=sk-ant-...
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` |
114
115
 
115
- # Start the interactive CLI
116
- pi
117
- ```
118
-
119
- Once in the CLI, you can chat with the AI:
120
-
121
- ```
122
- You: Create a simple Express server in src/server.ts
123
- ```
124
-
125
- The agent will use its tools to read, write, and edit files as needed, and execute commands via Bash.
116
+ The `/model` command only shows models for providers with configured API keys.
126
117
 
127
- ## API Keys
128
-
129
- The CLI supports multiple LLM providers. Set the appropriate environment variable for your chosen provider:
130
-
131
- ```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=...
157
- ```
158
-
159
- If no API key is set, the CLI will prompt you to configure one on first run.
160
-
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:
118
+ **OAuth (Claude Pro/Max subscribers):**
166
119
 
167
120
  ```bash
168
121
  pi
169
- # In the interactive session:
170
- /login
171
- # Select "Anthropic (Claude Pro/Max)"
172
- # Authorize in browser
173
- # Paste authorization code
122
+ /login # Select "Anthropic (Claude Pro/Max)", authorize in browser
174
123
  ```
175
124
 
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
180
-
181
- To logout:
182
- ```
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
- }
261
- ```
262
-
263
- ### API Key Resolution
264
-
265
- The `apiKey` field can be either an environment variable name or a literal API key:
266
-
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
270
-
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
274
-
275
- This allows both secure env var usage and literal keys for local servers.
276
-
277
- ### API Override
278
-
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`
282
-
283
- This is useful when a provider supports multiple API standards through the same base URL.
284
-
285
- ### Custom Headers
286
-
287
- You can add custom HTTP headers to bypass Cloudflare bot detection, add authentication tokens, or meet other proxy requirements:
288
-
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
- ```
318
-
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
322
-
323
- ### OpenAI Compatibility Settings
125
+ Tokens stored in `~/.pi/agent/oauth.json` (mode 0600). Use `/logout` to clear.
324
126
 
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:
326
-
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
- ```
352
-
353
- Available `compat` fields (all optional, auto-detected if not set):
354
-
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"` |
361
-
362
- If `compat` is partially set, unspecified fields use auto-detected values.
363
-
364
- ### Authorization Header
365
-
366
- Some providers require an explicit `Authorization: Bearer <token>` header. Set `authHeader: true` to automatically add this header using the resolved `apiKey`:
367
-
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
- }
390
- ```
391
-
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)
404
-
405
- ### Provider Defaults
406
-
407
- When multiple providers are available, pi prefers sensible defaults before falling back to "first available":
408
-
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 |
419
-
420
- ### Live Reload & Errors
421
-
422
- The models.json file is reloaded every time you open the `/model` selector. This means:
423
-
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!
428
-
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.
430
-
431
- ### Example: Adding Ollama Models
432
-
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.
434
-
435
- ## Themes
436
-
437
- Pi supports customizable color themes for the TUI. Two built-in themes are available: `dark` (default) and `light`.
438
-
439
- ### Selecting a Theme
440
-
441
- Use the `/theme` command to interactively select a theme, or edit your settings file:
127
+ ### Quick Start
442
128
 
443
129
  ```bash
444
- # Interactive selector
130
+ export ANTHROPIC_API_KEY=sk-ant-...
445
131
  pi
446
- /theme
447
-
448
- # Or edit ~/.pi/agent/settings.json
449
- {
450
- "theme": "dark" # or "light"
451
- }
452
132
  ```
453
133
 
454
- On first run, Pi auto-detects your terminal background (dark/light) and selects an appropriate theme.
455
-
456
- ### Custom Themes
457
-
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.
459
-
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)
472
-
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)
477
-
478
- Example custom theme:
479
-
480
- ```json
481
- {
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
- ...
492
- }
493
- }
494
- ```
495
-
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:
134
+ Then chat:
533
135
 
534
136
  ```
535
- /export # Auto-generates filename
536
- /export my-session.html # Custom filename
137
+ You: Create a simple Express server in src/server.ts
537
138
  ```
538
139
 
539
- The HTML file includes the full conversation with syntax highlighting and is viewable in any browser.
540
-
541
- ### /session
140
+ The agent reads, writes, and edits files, and executes commands via bash.
542
141
 
543
- Show session information and statistics:
544
-
545
- ```
546
- /session
547
- ```
142
+ ---
548
143
 
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)
144
+ ## Usage
554
145
 
555
- ### /changelog
146
+ ### Slash Commands
556
147
 
557
- Display the full changelog with all version history (newest last):
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 |
558
165
 
559
- ```
560
- /changelog
561
- ```
166
+ ### Editor Features
562
167
 
563
- ### /branch
168
+ **File reference (`@`):** Type `@` to fuzzy-search project files. Respects `.gitignore`.
564
169
 
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
170
+ **Path completion (Tab):** Complete relative paths, `../`, `~/`, etc.
568
171
 
569
- This allows you to explore alternative conversation paths without losing your current session.
172
+ **Drag & drop:** Drag files from your file manager into the terminal.
570
173
 
571
- ```
572
- /branch
573
- ```
174
+ **Multi-line paste:** Pasted content is collapsed to `[paste #N <lines> lines]` but sent in full.
574
175
 
575
- ### /resume
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.
576
177
 
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.
178
+ ### Keyboard Shortcuts
578
179
 
579
- This is equivalent to the `--resume` CLI flag but can be used mid-session.
180
+ **Navigation:**
580
181
 
581
- ```
582
- /resume
583
- ```
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 |
584
188
 
585
- ### /login
189
+ **Editing:**
586
190
 
587
- Login with OAuth to use subscription-based models (Claude Pro/Max):
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 |
588
198
 
589
- ```
590
- /login
591
- ```
199
+ **Other:**
592
200
 
593
- Opens an interactive selector to choose provider, then guides you through the OAuth flow in your browser.
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 |
594
210
 
595
- ### /logout
211
+ ### Bash Mode
596
212
 
597
- Logout from OAuth providers:
213
+ Prefix commands with `!` to execute them and add output to context:
598
214
 
599
215
  ```
600
- /logout
216
+ !ls -la
217
+ !git status
218
+ !cat package.json | jq '.dependencies'
601
219
  ```
602
220
 
603
- Shows a list of logged-in providers to logout from.
604
-
605
- ### /clear
221
+ Output streams in real-time. Press Escape to cancel. Large outputs truncate at 2000 lines / 50KB.
606
222
 
607
- Clear the conversation context and start a fresh session:
223
+ The output becomes part of your next prompt, formatted as:
608
224
 
609
225
  ```
610
- /clear
226
+ Ran `ls -la`
611
227
  ```
612
-
613
- Aborts any in-flight agent work, clears all messages, and creates a new session file.
614
-
615
- ### /copy
616
-
617
- Copy the last agent message to clipboard:
618
-
228
+ <output here>
619
229
  ```
620
- /copy
621
230
  ```
622
231
 
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.
232
+ Run multiple commands before prompting; all outputs are included together.
624
233
 
625
- ### /compact
234
+ ### Image Support
626
235
 
627
- Manually compact the conversation context to reduce token usage:
236
+ Include image paths in your message:
628
237
 
629
238
  ```
630
- /compact # Use default summary instructions
631
- /compact Focus on the API changes # Custom instructions for summary
239
+ You: What's in this screenshot? /path/to/image.png
632
240
  ```
633
241
 
634
- Creates a summary of the conversation so far, replacing the message history with a condensed version. See [Context Compaction](#context-compaction) for details.
635
-
636
- ### /autocompact
242
+ Supported: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`
637
243
 
638
- Toggle automatic context compaction:
639
-
640
- ```
641
- /autocompact
642
- ```
643
-
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.
645
-
646
- ### Custom Slash Commands
647
-
648
- Define reusable prompt templates as Markdown files that appear in the `/` autocomplete.
649
-
650
- **Locations:**
651
- - **Global:** `~/.pi/agent/commands/*.md` - available in all sessions
652
- - **Project:** `.pi/commands/*.md` - project-specific commands
653
-
654
- **File format:**
655
-
656
- ```markdown
657
- ---
658
- description: Review staged git changes
659
244
  ---
660
- Review the staged changes (`git diff --cached`). Focus on:
661
- - Bugs and logic errors
662
- - Security issues
663
- - Error handling gaps
664
- - Code style per AGENTS.md
665
- ```
666
-
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):**
670
-
671
- Commands support positional arguments with quote-aware parsing:
672
-
673
- ```markdown
674
- ---
675
- description: Create a component with features
676
- ---
677
- Create a React component named $1 with these features: $@
678
- ```
679
-
680
- Usage: `/component Button "has onClick handler" "supports disabled"`
681
- - `$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
245
 
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/`
246
+ ## Sessions
695
247
 
696
- **CLI usage:**
248
+ ### Session Management
697
249
 
698
- Custom slash commands also work from the command line:
250
+ Sessions auto-save to `~/.pi/agent/sessions/` organized by working directory.
699
251
 
700
252
  ```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
253
+ pi --continue # Continue most recent session
254
+ pi -c # Short form
736
255
 
737
- ### File Drag & Drop
256
+ pi --resume # Browse and select from past sessions
257
+ pi -r # Short form
738
258
 
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.
259
+ pi --no-session # Ephemeral mode (don't save)
740
260
 
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:
261
+ pi --session /path/to/file.jsonl # Use specific session file
262
+ ```
748
263
 
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
264
+ ### Context Compaction
753
265
 
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
266
+ Long sessions can exhaust context windows. Compaction summarizes older messages while keeping recent ones.
758
267
 
759
- **Visual feedback:**
760
- - Queued messages appear below the chat with "Queued: <message text>"
761
- - Messages disappear from the queue as they're processed
268
+ **Manual:** `/compact` or `/compact Focus on the API changes`
762
269
 
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
270
+ **Automatic:** Enable with `/autocompact`. When enabled, triggers in two cases:
271
+ - **Overflow recovery**: LLM returns context overflow error. Compacts and auto-retries.
272
+ - **Threshold maintenance**: Context exceeds `contextWindow - reserveTokens` after a successful turn. Compacts without retry.
767
273
 
768
- Change queue mode with `/queue` command. Setting is saved in `~/.pi/agent/settings.json`.
274
+ When disabled, neither case triggers automatic compaction (use `/compact` manually if needed).
769
275
 
770
- ### Bash Mode (`!`)
276
+ **How it works:**
277
+ 1. Cut point calculated to keep ~20k tokens of recent messages
278
+ 2. Messages before cut point are summarized
279
+ 3. Summary replaces old messages as "context handoff"
280
+ 4. Previous compaction summaries chain into new ones
771
281
 
772
- Execute shell commands directly and add output to the LLM context by prefixing with `!`:
282
+ **Configuration** (`~/.pi/agent/settings.json`):
773
283
 
284
+ ```json
285
+ {
286
+ "compaction": {
287
+ "enabled": true,
288
+ "reserveTokens": 16384,
289
+ "keepRecentTokens": 20000
290
+ }
291
+ }
774
292
  ```
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
293
 
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)
294
+ > **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.
814
295
 
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)
296
+ ### Branching
821
297
 
822
- ## Project Context Files
298
+ Use `/branch` to explore alternative conversation paths:
823
299
 
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.
300
+ 1. Opens selector showing all your user messages
301
+ 2. Select a message to branch from
302
+ 3. Creates new session with history up to that point
303
+ 4. Selected message placed in editor for modification
825
304
 
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
305
+ ---
833
306
 
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
307
+ ## Configuration
838
308
 
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
309
+ ### Project Context Files
842
310
 
843
- **File preference**: In each directory, `AGENTS.md` is preferred over `CLAUDE.md` if both exist.
311
+ Pi loads `AGENTS.md` (or `CLAUDE.md`) files at startup in this order:
844
312
 
845
- ### What to Include
313
+ 1. **Global:** `~/.pi/agent/AGENTS.md`
314
+ 2. **Parent directories:** Walking up from current directory
315
+ 3. **Current directory:** `./AGENTS.md`
846
316
 
847
- Context files are useful for:
848
- - Project-specific instructions and guidelines
849
- - Common bash commands and workflows
317
+ Use these for:
318
+ - Project instructions and guidelines
319
+ - Common commands and workflows
850
320
  - Architecture documentation
851
- - Coding conventions and style guides
852
- - Dependencies and setup information
321
+ - Coding conventions
853
322
  - Testing instructions
854
- - Repository etiquette (branch naming, merge vs. rebase, etc.)
855
-
856
- ### Example
857
323
 
858
324
  ```markdown
859
325
  # Common Commands
@@ -863,394 +329,272 @@ Context files are useful for:
863
329
  # Code Style
864
330
  - Use TypeScript strict mode
865
331
  - Prefer async/await over promises
866
-
867
- # Workflow
868
- - Always run tests before committing
869
- - Update CHANGELOG.md for user-facing changes
870
332
  ```
871
333
 
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.
334
+ ### Custom Models and Providers
873
335
 
874
- ## Image Support
336
+ Add custom models (Ollama, vLLM, LM Studio, etc.) via `~/.pi/agent/models.json`:
875
337
 
876
- Send images to vision-capable models by providing file paths:
877
-
878
- ```
879
- You: What is in this screenshot? /path/to/image.png
338
+ ```json
339
+ {
340
+ "providers": {
341
+ "ollama": {
342
+ "baseUrl": "http://localhost:11434/v1",
343
+ "apiKey": "OLLAMA_API_KEY",
344
+ "api": "openai-completions",
345
+ "models": [
346
+ {
347
+ "id": "llama-3.1-8b",
348
+ "name": "Llama 3.1 8B (Local)",
349
+ "reasoning": false,
350
+ "input": ["text"],
351
+ "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
352
+ "contextWindow": 128000,
353
+ "maxTokens": 32000
354
+ }
355
+ ]
356
+ }
357
+ }
358
+ }
880
359
  ```
881
360
 
882
- Supported formats: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`
361
+ **Supported APIs:** `openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai`
883
362
 
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.
363
+ **API key resolution:** The `apiKey` field is checked as environment variable name first, then used as literal value.
885
364
 
886
- ## Session Management
365
+ **API override:** Set `api` at provider level (default for all models) or model level (override per model).
887
366
 
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.
367
+ **Custom headers:**
889
368
 
890
- To continue the most recent session:
891
-
892
- ```bash
893
- pi --continue
894
- # or
895
- pi -c
369
+ ```json
370
+ {
371
+ "providers": {
372
+ "custom-proxy": {
373
+ "baseUrl": "https://proxy.example.com/v1",
374
+ "apiKey": "YOUR_API_KEY",
375
+ "api": "anthropic-messages",
376
+ "headers": {
377
+ "User-Agent": "Mozilla/5.0 ...",
378
+ "X-Custom-Auth": "token"
379
+ },
380
+ "models": [...]
381
+ }
382
+ }
383
+ }
896
384
  ```
897
385
 
898
- To browse and select from past sessions:
386
+ **Authorization header:** Set `authHeader: true` to add `Authorization: Bearer <apiKey>` automatically.
899
387
 
900
- ```bash
901
- pi --resume
902
- # or
903
- pi -r
904
- ```
388
+ **OpenAI compatibility (`compat` field):**
389
+
390
+ | Field | Description |
391
+ |-------|-------------|
392
+ | `supportsStore` | Whether provider supports `store` field |
393
+ | `supportsDeveloperRole` | Use `developer` vs `system` role |
394
+ | `supportsReasoningEffort` | Support for `reasoning_effort` parameter |
395
+ | `maxTokensField` | Use `max_completion_tokens` or `max_tokens` |
905
396
 
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
397
+ **Live reload:** The file reloads each time you open `/model`. Edit during session; no restart needed.
911
398
 
912
- Sessions include all conversation messages, tool calls and results, model switches, and thinking level changes.
399
+ **Model selection priority:**
400
+ 1. CLI args (`--provider`, `--model`)
401
+ 2. First from `--models` scope (new sessions only)
402
+ 3. Restored from session (`--continue`, `--resume`)
403
+ 4. Saved default from settings
404
+ 5. First available model with valid API key
913
405
 
914
- To run without saving a session (ephemeral mode):
406
+ ### Themes
407
+
408
+ Built-in themes: `dark` (default), `light`. Auto-detected on first run.
915
409
 
916
410
  ```bash
917
- pi --no-session
411
+ /theme # Interactive selector
918
412
  ```
919
413
 
920
- To use a specific session file instead of auto-generating one:
414
+ **Custom themes:** Create `~/.pi/agent/themes/*.json`. Custom themes support live reload.
921
415
 
922
416
  ```bash
923
- pi --session /path/to/my-session.jsonl
417
+ mkdir -p ~/.pi/agent/themes
418
+ cp $(npm root -g)/@mariozechner/pi-coding-agent/dist/theme/dark.json ~/.pi/agent/themes/my-theme.json
924
419
  ```
925
420
 
926
- ## Context Compaction
421
+ Select with `/theme`, then edit the file. Changes apply on save.
927
422
 
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.
423
+ See [Theme Documentation](docs/theme.md) for all 44 color tokens.
931
424
 
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.
425
+ **VS Code terminal fix:** Set `terminal.integrated.minimumContrastRatio` to `1` for accurate colors.
933
426
 
934
- ### How It Works
427
+ ### Custom Slash Commands
935
428
 
936
- When compaction runs (manually via `/compact` or automatically):
429
+ Define reusable prompts as Markdown files:
937
430
 
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)
431
+ **Locations:**
432
+ - Global: `~/.pi/agent/commands/*.md`
433
+ - Project: `.pi/commands/*.md`
943
434
 
944
- Cut points are always placed at user message boundaries to preserve turn integrity.
435
+ **Format:**
945
436
 
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.
437
+ ```markdown
438
+ ---
439
+ description: Review staged git changes
440
+ ---
441
+ Review the staged changes (`git diff --cached`). Focus on:
442
+ - Bugs and logic errors
443
+ - Security issues
444
+ - Error handling gaps
445
+ ```
947
446
 
948
- ### Manual Compaction
447
+ Filename (without `.md`) becomes the command name. Description shown in autocomplete.
949
448
 
950
- Use `/compact` to manually trigger compaction at any time:
449
+ **Arguments:**
951
450
 
451
+ ```markdown
452
+ ---
453
+ description: Create a component
454
+ ---
455
+ Create a React component named $1 with features: $@
952
456
  ```
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
457
 
961
- Enable auto-compaction with `/autocompact`. When enabled, compaction triggers automatically when context usage exceeds `contextWindow - reserveTokens`.
458
+ Usage: `/component Button "onClick handler" "disabled support"`
459
+ - `$1` = `Button`
460
+ - `$@` = all arguments joined
962
461
 
963
- The context percentage is shown in the footer. When it approaches 100%, auto-compaction kicks in (if enabled) or you should manually compact.
462
+ **Namespacing:** Subdirectories create prefixes. `.pi/commands/frontend/component.md` `/component (project:frontend)`
964
463
 
965
- ### Configuration
464
+ ### Settings File
966
465
 
967
- Power users can tune compaction behavior in `~/.pi/agent/settings.json`:
466
+ `~/.pi/agent/settings.json` stores persistent preferences:
968
467
 
969
468
  ```json
970
469
  {
470
+ "theme": "dark",
471
+ "shellPath": "C:\\path\\to\\bash.exe",
472
+ "queueMode": "one-at-a-time",
971
473
  "compaction": {
972
- "enabled": true,
474
+ "enabled": false,
973
475
  "reserveTokens": 16384,
974
476
  "keepRecentTokens": 20000
975
477
  }
976
478
  }
977
479
  ```
978
480
 
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.
481
+ ---
989
482
 
990
- ## CLI Options
483
+ ## CLI Reference
991
484
 
992
485
  ```bash
993
486
  pi [options] [@files...] [messages...]
994
487
  ```
995
488
 
996
- ### File Arguments (`@file`)
489
+ ### Options
997
490
 
998
- You can include files directly in your initial message using the `@` prefix:
491
+ | Option | Description |
492
+ |--------|-------------|
493
+ | `--provider <name>` | Provider: `anthropic`, `openai`, `google`, `xai`, `groq`, `cerebras`, `openrouter`, `zai`, or custom |
494
+ | `--model <id>` | Model ID |
495
+ | `--api-key <key>` | API key (overrides environment) |
496
+ | `--system-prompt <text\|file>` | Custom system prompt (text or file path) |
497
+ | `--append-system-prompt <text\|file>` | Append to system prompt |
498
+ | `--mode <mode>` | Output mode: `text`, `json`, `rpc` (implies `--print`) |
499
+ | `--print`, `-p` | Non-interactive: process prompt and exit |
500
+ | `--no-session` | Don't save session |
501
+ | `--session <path>` | Use specific session file |
502
+ | `--continue`, `-c` | Continue most recent session |
503
+ | `--resume`, `-r` | Select session to resume |
504
+ | `--models <patterns>` | Comma-separated patterns for Ctrl+P cycling (e.g., `sonnet:high,haiku:low`) |
505
+ | `--tools <tools>` | Comma-separated tool list (default: `read,bash,edit,write`) |
506
+ | `--thinking <level>` | Thinking level: `off`, `minimal`, `low`, `medium`, `high` |
507
+ | `--export <file> [output]` | Export session to HTML |
508
+ | `--help`, `-h` | Show help |
509
+
510
+ ### File Arguments
511
+
512
+ Include files with `@` prefix:
999
513
 
1000
514
  ```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)
515
+ pi @prompt.md "Answer this"
1008
516
  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"
517
+ pi @requirements.md @design.png "Implement this"
1039
518
  ```
1040
519
 
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
520
+ Text files wrapped in `<file name="path">content</file>`. Images attached as base64.
1141
521
 
1142
522
  ### Examples
1143
523
 
1144
524
  ```bash
1145
- # Start interactive mode
525
+ # Interactive mode
1146
526
  pi
1147
527
 
1148
- # Interactive mode with initial prompt (stays running after completion)
528
+ # Interactive with initial prompt
1149
529
  pi "List all .ts files in src/"
1150
530
 
1151
- # Include files in your prompt
1152
- pi @requirements.md @design.png "Implement this feature"
1153
-
1154
- # Non-interactive mode (process prompt and exit)
531
+ # Non-interactive
1155
532
  pi -p "List all .ts files in src/"
1156
533
 
1157
- # Non-interactive with files
1158
- pi -p @code.ts "Review this code for bugs"
534
+ # With files
535
+ pi -p @code.ts "Review this code"
1159
536
 
1160
- # JSON mode - stream all agent events (non-interactive)
1161
- pi --mode json "List all .ts files in src/"
537
+ # JSON event stream
538
+ pi --mode json "List files"
1162
539
 
1163
- # RPC mode - headless operation (see test/rpc-example.ts)
540
+ # RPC mode (headless)
1164
541
  pi --mode rpc --no-session
1165
- # Then send JSON on stdin:
1166
- # {"type":"prompt","message":"List all .ts files"}
1167
- # {"type":"abort"}
1168
542
 
1169
- # Continue previous session
543
+ # Continue session
1170
544
  pi -c "What did we discuss?"
1171
545
 
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
546
+ # Specific model
547
+ pi --provider openai --model gpt-4o "Help me refactor"
1178
548
 
1179
549
  # Model cycling with thinking levels
1180
550
  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
551
 
1186
- # Read-only mode (no file modifications possible)
1187
- pi --tools read,grep,find,ls -p "Review the architecture in src/"
552
+ # Read-only mode
553
+ pi --tools read,grep,find,ls -p "Review the architecture"
1188
554
 
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
555
+ # Export session
556
+ pi --export session.jsonl output.html
1197
557
  ```
1198
558
 
559
+ ---
560
+
1199
561
  ## Tools
1200
562
 
1201
563
  ### Default Tools
1202
564
 
1203
- By default, the agent has access to four core tools:
565
+ | Tool | Description |
566
+ |------|-------------|
567
+ | `read` | Read file contents. Images sent as attachments. Text: first 2000 lines, lines truncated at 2000 chars. Use offset/limit for large files. |
568
+ | `write` | Write/overwrite file. Creates parent directories. |
569
+ | `edit` | Replace exact text in file. Must match exactly including whitespace. Fails if text appears multiple times or not found. |
570
+ | `bash` | Execute command. Returns stdout/stderr. Optional `timeout` parameter. |
1204
571
 
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.
572
+ ### Read-Only Tools
1207
573
 
1208
- **write**
1209
- Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.
574
+ Available via `--tools` flag:
1210
575
 
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.
576
+ | Tool | Description |
577
+ |------|-------------|
578
+ | `grep` | Search file contents (regex or literal). Respects `.gitignore`. |
579
+ | `find` | Search for files by glob pattern. Respects `.gitignore`. |
580
+ | `ls` | List directory contents. Includes dotfiles. |
1213
581
 
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.
582
+ Example: `--tools read,grep,find,ls` for code review without modification.
1216
583
 
1217
- ### Read-Only Exploration Tools
584
+ ### Custom Tools
1218
585
 
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:**
586
+ Pi relies on CLI tools invoked via bash rather than MCP. Create a tool with a README:
1241
587
 
1242
588
  `~/agent-tools/screenshot/README.md`:
1243
589
  ```markdown
1244
590
  # Screenshot Tool
1245
-
1246
591
  Takes a screenshot of your main display.
1247
592
 
1248
593
  ## Usage
1249
594
  ```bash
1250
595
  screenshot.sh
1251
596
  ```
1252
-
1253
- Returns the path to the saved PNG file.
597
+ Returns the path to the saved PNG.
1254
598
  ```
1255
599
 
1256
600
  `~/agent-tools/screenshot/screenshot.sh`:
@@ -1260,117 +604,106 @@ screencapture -x /tmp/screenshot-$(date +%s).png
1260
604
  ls -t /tmp/screenshot-*.png | head -1
1261
605
  ```
1262
606
 
1263
- **In your session:**
1264
- ```
1265
- You: Read ~/agent-tools/screenshot/README.md and use that tool to take a screenshot
1266
- ```
607
+ Usage: "Read ~/agent-tools/screenshot/README.md and take a screenshot"
608
+
609
+ Reference tool READMEs in `AGENTS.md` to make them automatically available.
1267
610
 
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.
611
+ ---
1269
612
 
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
613
+ ## Programmatic Usage
1273
614
 
1274
- **Real-world example:**
615
+ ### RPC Mode
1275
616
 
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".
617
+ For embedding pi in other applications:
1277
618
 
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/
619
+ ```bash
620
+ pi --mode rpc --no-session
621
+ ```
1279
622
 
1280
- ## Security (YOLO by default)
623
+ Send JSON commands on stdin:
624
+ ```json
625
+ {"type":"prompt","message":"List all .ts files"}
626
+ {"type":"abort"}
627
+ ```
1281
628
 
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.
629
+ See [RPC documentation](docs/rpc.md) for full protocol.
1283
630
 
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
631
+ **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
632
 
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
633
+ ### HTML Export
1293
634
 
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
635
+ ```bash
636
+ pi --export session.jsonl # Auto-generated filename
637
+ pi --export session.jsonl output.html # Custom filename
638
+ ```
1299
639
 
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
640
+ Works with both session files and streaming event logs from `--mode json`.
1305
641
 
1306
- This is how I want it to work and I'm not likely to change my stance on this.
642
+ ---
1307
643
 
1308
- Use at your own risk.
644
+ ## Philosophy
1309
645
 
1310
- ## Sub-Agents
646
+ Pi is opinionated about what it won't do. These are intentional design decisions.
1311
647
 
1312
- **pi does not and will not support sub-agents as a built-in feature.** If the agent needs to delegate work, it can:
648
+ ### No MCP
1313
649
 
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
650
+ 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
651
 
1317
- **Why no built-in sub-agents:**
652
+ 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
653
 
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.
654
+ See: [What if you don't need MCP?](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/)
1320
655
 
1321
- If you need parallel work on independent tasks, manually run multiple `pi` sessions in different terminal tabs. You're the orchestrator.
656
+ ### No Sub-Agents
1322
657
 
1323
- ## To-Dos
658
+ 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
659
 
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.
660
+ ### No Built-in To-Dos
1326
661
 
1327
- If you need task tracking, make it stateful by writing to a file:
662
+ To-do lists confuse models more than they help. For task tracking, use a file:
1328
663
 
1329
664
  ```markdown
1330
665
  # TODO.md
1331
-
1332
- - [x] Implement user authentication
1333
- - [x] Add database migrations
1334
- - [ ] Write API documentation
1335
- - [ ] Add rate limiting
666
+ - [x] Implement authentication
667
+ - [ ] Write API docs
1336
668
  ```
1337
669
 
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
670
+ ### No Planning Mode
1341
671
 
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:
672
+ Tell the agent to think through problems without modifying files. For persistent plans, write to a file:
1345
673
 
1346
674
  ```markdown
1347
675
  # PLAN.md
1348
-
1349
676
  ## 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
-
677
+ Refactor auth to support OAuth
1359
678
  ## Current Step
1360
- Working on step 3 - authorization endpoints
679
+ Working on authorization endpoints
1361
680
  ```
1362
681
 
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.
682
+ ### No Permission System (YOLO Mode)
683
+
684
+ Pi runs with full filesystem access and no permission prompts. Why:
685
+ - Permission systems add friction while being easily circumvented
686
+ - Pre-checking for "dangerous" patterns causes latency and false positives
1364
687
 
1365
- ## Background Bash
688
+ **Risks:**
689
+ - Can read, write, delete anything with your user privileges
690
+ - Prompt injection via files or command output can influence behavior
691
+
692
+ **Mitigations:**
693
+ - Run in a container if uncomfortable
694
+ - Don't use on systems with sensitive data you can't afford to lose
1366
695
 
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.
696
+ ### No Background Bash
697
+
698
+ Use `tmux` or similar. Bonus: you can watch the agent interact with CLIs and intervene if needed.
699
+
700
+ ---
1368
701
 
1369
702
  ## Development
1370
703
 
1371
704
  ### Forking / Rebranding
1372
705
 
1373
- All branding (app name, config directory) is configurable via `package.json`:
706
+ Configure via `package.json`:
1374
707
 
1375
708
  ```json
1376
709
  {
@@ -1381,48 +714,27 @@ All branding (app name, config directory) is configurable via `package.json`:
1381
714
  }
1382
715
  ```
1383
716
 
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
717
+ Change `name`, `configDir`, and `bin` field for your fork. Affects CLI banner, config paths, and environment variable names.
1394
718
 
1395
719
  ### Path Resolution
1396
720
 
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`
721
+ Three execution modes: npm install, standalone binary, tsx from source.
1401
722
 
1402
- All path resolution for package assets (package.json, README.md, CHANGELOG.md, themes) must go through `src/paths.ts`:
723
+ **Always use `src/paths.ts`** for package assets:
1403
724
 
1404
725
  ```typescript
1405
- import { getPackageDir, getThemeDir, getPackageJsonPath, getReadmePath, getChangelogPath } from "./paths.js";
726
+ import { getPackageDir, getThemeDir } from "./paths.js";
1406
727
  ```
1407
728
 
1408
- **Never use `__dirname` directly** for resolving package assets. The `paths.ts` module handles the differences between execution modes automatically.
729
+ Never use `__dirname` directly for package assets.
1409
730
 
1410
731
  ### Debug Command
1411
732
 
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
- ```
733
+ `/debug` (hidden) writes rendered lines with ANSI codes to `~/.pi/agent/pi-debug.log` for TUI debugging.
1417
734
 
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
735
+ For architecture and contribution guidelines, see [DEVELOPMENT.md](./DEVELOPMENT.md).
1422
736
 
1423
- ## Development
1424
-
1425
- For architecture details, code organization, and contribution guidelines, see [DEVELOPMENT.md](./DEVELOPMENT.md).
737
+ ---
1426
738
 
1427
739
  ## License
1428
740
 
@@ -1430,5 +742,5 @@ MIT
1430
742
 
1431
743
  ## See Also
1432
744
 
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
745
+ - [@mariozechner/pi-ai](https://www.npmjs.com/package/@mariozechner/pi-ai): Core LLM toolkit
746
+ - [@mariozechner/pi-agent](https://www.npmjs.com/package/@mariozechner/pi-agent): Agent framework