docs(coding-agent): update README-NEW.md, tui.md, add new docs

- README-NEW.md: add environment variables, philosophy extras (no built-in to-dos, no background bash), session ID support, pi config command, plain git URLs, version pinning
- tui.md: fix hooks->extensions terminology, update Component interface (invalidate required, add wantsKeyRelease)
- Add new docs: settings.md, development.md, json.md
- Add screenshots: tree-view.png, doom-extension.png
This commit is contained in:
Mario Zechner 2026-01-26 02:27:19 +01:00
parent 28ab25b07e
commit 5340862910
7 changed files with 626 additions and 107 deletions

View file

@ -20,12 +20,24 @@ Pi runs in four modes: interactive, print or JSON, RPC for process integration,
- [Quick Start](#quick-start)
- [Providers & Models](#providers--models)
- [Interactive Mode](#interactive-mode)
- [Editor](#editor)
- [Commands](#commands)
- [Keyboard Shortcuts](#keyboard-shortcuts)
- [Message Queue](#message-queue)
- [Sessions](#sessions)
- [Configuration](#configuration)
- [Branching](#branching)
- [Compaction](#compaction)
- [Settings](#settings)
- [Context Files](#context-files)
- [Customization](#customization)
- [CLI Reference](#cli-reference)
- [Prompt Templates](#prompt-templates)
- [Skills](#skills)
- [Extensions](#extensions)
- [Themes](#themes)
- [Pi Packages](#pi-packages)
- [Programmatic Usage](#programmatic-usage)
- [Philosophy](#philosophy)
- [CLI Reference](#cli-reference)
---
@ -91,7 +103,7 @@ See [docs/providers.md](docs/providers.md) for detailed setup instructions.
## Interactive Mode
<img src="docs/images/interactive-mode.png" alt="Interactive Mode" width="600">
<p align="center"><img src="docs/images/interactive-mode.png" alt="Interactive Mode" width="600"></p>
The interface from top to bottom:
@ -134,7 +146,7 @@ Type `/` in the editor to trigger commands. [Extensions](#extensions) can regist
| `/copy` | Copy last assistant message to clipboard |
| `/export [file]` | Export session to HTML file |
| `/share` | Upload as private GitHub gist with shareable HTML link |
| `/reload` | Reload extensions, skills, prompts, themes |
| `/reload` | Reload extensions, skills, prompts, context files (themes hot-reload automatically) |
| `/hotkeys` | Show all keyboard shortcuts |
| `/changelog` | Display version history |
| `/quit`, `/exit` | Quit pi |
@ -157,11 +169,22 @@ See `/hotkeys` for the full list. Customize via `~/.pi/agent/keybindings.json`.
| Ctrl+O | Collapse/expand tool output |
| Ctrl+T | Collapse/expand thinking blocks |
### Message Queue
Submit messages while the agent is working:
- **Enter** queues a *steering* message, delivered after current tool execution (interrupts remaining tools)
- **Alt+Enter** queues a *follow-up* message, delivered only after the agent finishes all work
- **Escape** aborts and restores queued messages to editor
- **Alt+Up** retrieves queued messages back to editor
Configure delivery in [settings](docs/settings.md): `steeringMode` and `followUpMode` can be `"one-at-a-time"` (default, waits for response) or `"all"` (delivers all queued at once).
---
## Sessions
Sessions are stored as JSONL files with a tree structure. Each entry has an `id` and `parentId`, enabling in-place branching without creating new files.
Sessions are stored as JSONL files with a tree structure. Each entry has an `id` and `parentId`, enabling in-place branching without creating new files. See [docs/session.md](docs/session.md) for file format.
### Management
@ -178,6 +201,8 @@ pi --session <path> # Use specific session file or ID
**`/tree`** - Navigate the session tree in-place. Select any previous point, continue from there, and switch between branches. All history preserved in a single file.
<p align="center"><img src="docs/images/tree-view.png" alt="Tree View" width="600"></p>
- Search by typing, page with ←/→
- Filter modes (Ctrl+O): default → no-tools → user-only → labeled-only → all
- Press `l` to label entries as bookmarks
@ -192,71 +217,73 @@ Long sessions can exhaust context windows. Compaction summarizes older messages
**Automatic:** Enabled by default. Triggers on context overflow (recovers and retries) or when approaching the limit (proactive). Configure via `/settings` or `settings.json`.
Compaction is lossy. The full history remains in the JSONL file; use `/tree` to revisit. Customize compaction behavior via [extensions](#extensions).
See [docs/session.md](docs/session.md) for file format and [docs/compaction.md](docs/compaction.md) for internals.
Compaction is lossy. The full history remains in the JSONL file; use `/tree` to revisit. Customize compaction behavior via [extensions](#extensions). See [docs/compaction.md](docs/compaction.md) for internals.
---
## Configuration
## Settings
### Context Files
Use `/settings` to modify common options, or edit JSON files directly:
Pi loads `AGENTS.md` files at startup (global `~/.pi/agent/AGENTS.md`, parent directories, current directory). Use for project instructions, conventions, common commands.
### System Prompt
Replace the default system prompt with `.pi/SYSTEM.md` (project) or `~/.pi/agent/SYSTEM.md` (global). Append without replacing via `APPEND_SYSTEM.md`.
### Custom Models
Add Ollama, vLLM, LM Studio, or proxy endpoints via `~/.pi/agent/models.json`:
```json
{
"providers": {
"ollama": {
"baseUrl": "http://localhost:11434/v1",
"api": "openai-completions",
"models": [{ "id": "llama-3.1-8b", "name": "Llama 3.1 8B", ... }]
}
}
}
```
See [docs/models.md](docs/models.md) for full schema and examples.
### Settings
Global settings in `~/.pi/agent/settings.json`, project overrides in `.pi/settings.json`.
| Location | Scope |
|----------|-------|
| `~/.pi/agent/settings.json` | Global (all projects) |
| `.pi/settings.json` | Project (overrides global) |
See [docs/settings.md](docs/settings.md) for all options.
---
## Context Files
Pi loads `AGENTS.md` (or `CLAUDE.md`) at startup from:
- `~/.pi/agent/AGENTS.md` (global)
- Parent directories (walking up from cwd)
- Current directory
Use for project instructions, conventions, common commands. All matching files are concatenated.
### System Prompt
Replace the default system prompt with `.pi/SYSTEM.md` (project) or `~/.pi/agent/SYSTEM.md` (global). Append without replacing via `APPEND_SYSTEM.md`.
---
## Customization
### Themes
Built-in: `dark`, `light`. Create custom themes in `~/.pi/agent/themes/*.json` with live reload.
See [docs/themes.md](docs/themes.md).
### Prompt Templates
Reusable prompts as Markdown files in `~/.pi/agent/prompts/` or `.pi/prompts/`. Type `/name` to expand.
Reusable prompts as Markdown files. Type `/name` to expand.
See [docs/prompt-templates.md](docs/prompt-templates.md).
```markdown
<!-- ~/.pi/agent/prompts/review.md -->
Review this code for bugs, security issues, and performance problems.
Focus on: {{focus}}
```
Place in `~/.pi/agent/prompts/`, `.pi/prompts/`, or a [pi package](#pi-packages) to share with others. See [docs/prompt-templates.md](docs/prompt-templates.md).
### Skills
On-demand capability packages following the [Agent Skills standard](https://agentskills.io). Place in `~/.pi/agent/skills/` or `.pi/skills/`. Invoke via `/skill:name` or let the agent load them automatically.
On-demand capability packages following the [Agent Skills standard](https://agentskills.io). Invoke via `/skill:name` or let the agent load them automatically.
See [docs/skills.md](docs/skills.md).
```markdown
<!-- ~/.pi/agent/skills/my-skill/SKILL.md -->
# My Skill
Use this skill when the user asks about X.
## Steps
1. Do this
2. Then that
```
Place in `~/.pi/agent/skills/`, `.pi/skills/`, or a [pi package](#pi-packages) to share with others. See [docs/skills.md](docs/skills.md).
### Extensions
TypeScript modules for custom tools, commands, event interception, and UI.
<p align="center"><img src="docs/images/doom-extension.png" alt="Doom Extension" width="600"></p>
TypeScript modules that extend pi with custom tools, commands, keyboard shortcuts, event handlers, and UI components.
```typescript
export default function (pi: ExtensionAPI) {
@ -266,62 +293,67 @@ export default function (pi: ExtensionAPI) {
}
```
Place in `~/.pi/agent/extensions/` or `.pi/extensions/`.
**What's possible:**
- Custom tools (or replace built-in tools entirely)
- Sub-agents and plan mode
- Custom compaction and summarization
- Permission gates and path protection
- Custom editors and UI components
- Status lines, headers, footers
- Git checkpointing and auto-commit
- SSH and sandbox execution
- MCP server integration
- Make pi look like Claude Code
- Games while waiting (yes, Doom runs)
- ...anything you can dream up
See [docs/extensions.md](docs/extensions.md) and [examples/extensions/](examples/extensions/).
Place in `~/.pi/agent/extensions/`, `.pi/extensions/`, or a [pi package](#pi-packages) to share with others. See [docs/extensions.md](docs/extensions.md) and [examples/extensions/](examples/extensions/).
### Themes
Built-in: `dark`, `light`. Themes hot-reload: modify the active theme file and pi immediately applies changes.
Place in `~/.pi/agent/themes/`, `.pi/themes/`, or a [pi package](#pi-packages) to share with others. See [docs/themes.md](docs/themes.md).
### Pi Packages
Bundle and share extensions, skills, prompts, and themes via npm or git:
Bundle and share extensions, skills, prompts, and themes via npm or git.
```bash
pi install npm:@foo/pi-tools
pi install npm:@foo/pi-tools@1.2.3 # pinned version
pi install git:github.com/user/repo
pi install git:github.com/user/repo@v1 # tag or commit
pi install https://github.com/user/repo
pi remove npm:@foo/pi-tools
pi list
pi update
pi update # skips pinned packages
pi config # enable/disable extensions, skills, prompts, themes
```
Packages install to `~/.pi/agent/git/` (git) or global npm. Use `-l` for project-local installs (`.pi/git/`, `.pi/npm/`).
Create a package by adding a `pi` key to `package.json`:
```json
{
"name": "my-pi-package",
"keywords": ["pi-package"],
"pi": {
"extensions": ["./extensions"],
"skills": ["./skills"],
"prompts": ["./prompts"],
"themes": ["./themes"]
}
}
```
Without a `pi` manifest, pi auto-discovers from conventional directories (`extensions/`, `skills/`, `prompts/`, `themes/`).
See [docs/packages.md](docs/packages.md).
---
## CLI Reference
```bash
pi [options] [@files...] [messages...]
```
### Modes
| Flag | Description |
|------|-------------|
| (default) | Interactive mode |
| `-p`, `--print` | Print response and exit |
| `--mode json` | JSON event stream |
| `--mode rpc` | RPC mode for process integration |
### Common Options
| Option | Description |
|--------|-------------|
| `--provider`, `--model` | Select provider and model |
| `--thinking <level>` | `off`, `minimal`, `low`, `medium`, `high` |
| `--models <patterns>` | Patterns for Ctrl+P cycling |
| `-c`, `--continue` | Continue most recent session |
| `-r`, `--resume` | Browse and select session |
| `--tools <list>` | Limit tools (default: `read,bash,edit,write`) |
### File Arguments
```bash
pi @prompt.md "Answer this"
pi @screenshot.png "What's in this image?"
```
See `pi --help` for all options.
---
## Programmatic Usage
### SDK
@ -342,37 +374,162 @@ See [docs/sdk.md](docs/sdk.md) and [examples/sdk/](examples/sdk/).
### RPC Mode
For non-Node.js integrations, use RPC mode over stdin/stdout:
```bash
pi --mode rpc --no-session
pi --mode rpc
```
See [docs/rpc.md](docs/rpc.md) for the protocol.
### HTML Export
```bash
pi --export session.jsonl output.html
```
---
## Philosophy
**No MCP.** Build CLI tools with READMEs (see [Skills](#skills)). [Why?](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/)
Pi is aggressively extensible so it doesn't have to dictate your workflow. Features that other tools bake in can be built with [extensions](#extensions), [skills](#skills), or installed from third-party [pi packages](#pi-packages). This keeps the core minimal while letting you shape pi to fit how you work.
**No sub-agents.** Spawn pi instances via tmux, or build your own with [Extensions](#extensions).
**No MCP.** Build CLI tools with READMEs (see [Skills](#skills)), or build an extension that adds MCP support. [Why?](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/)
**No permission popups.** Run in a container or build your own confirmation flow.
**No sub-agents.** There's many ways to do this. Spawn pi instances via tmux, or build your own with [extensions](#extensions), or install a package that does it your way.
**No plan mode.** Write plans to files, start fresh for implementation.
**No permission popups.** Run in a container, or build your own confirmation flow with [extensions](#extensions) inline with your environment and security requirements.
**No plan mode.** Write plans to files, or build it with [extensions](#extensions), or install a package.
**No built-in to-dos.** They confuse models. Use a TODO.md file, or build your own with [extensions](#extensions).
**No background bash.** Use tmux. Full observability, direct interaction.
Read the [blog post](https://mariozechner.at/posts/2025-11-30-pi-coding-agent/) for the full rationale.
---
## Development
## CLI Reference
See [docs/development.md](docs/development.md) for forking, rebranding, and debugging.
```bash
pi [options] [@files...] [messages...]
```
### Package Commands
```bash
pi install <source> [-l] # Install package, -l for project-local
pi remove <source> [-l] # Remove package
pi update [source] # Update packages (skips pinned)
pi list # List installed packages
pi config # Enable/disable package resources
```
### Modes
| Flag | Description |
|------|-------------|
| (default) | Interactive mode |
| `-p`, `--print` | Print response and exit |
| `--mode json` | Output all events as JSON lines (see [docs/json.md](docs/json.md)) |
| `--mode rpc` | RPC mode for process integration (see [docs/rpc.md](docs/rpc.md)) |
| `--export <in> [out]` | Export session to HTML |
### Model Options
| Option | Description |
|--------|-------------|
| `--provider <name>` | Provider (anthropic, openai, google, etc.) |
| `--model <id>` | Model ID |
| `--api-key <key>` | API key (overrides env vars) |
| `--thinking <level>` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh` |
| `--models <patterns>` | Comma-separated patterns for Ctrl+P cycling |
| `--list-models [search]` | List available models |
### Session Options
| Option | Description |
|--------|-------------|
| `-c`, `--continue` | Continue most recent session |
| `-r`, `--resume` | Browse and select session |
| `--session <path>` | Use specific session file or partial UUID |
| `--session-dir <dir>` | Custom session storage directory |
| `--no-session` | Ephemeral mode (don't save) |
### Tool Options
| Option | Description |
|--------|-------------|
| `--tools <list>` | Enable specific built-in tools (default: `read,bash,edit,write`) |
| `--no-tools` | Disable all built-in tools (extension tools still work) |
Available built-in tools: `read`, `bash`, `edit`, `write`, `grep`, `find`, `ls`
### Resource Options
| Option | Description |
|--------|-------------|
| `-e`, `--extension <source>` | Load extension from path, npm, or git (repeatable) |
| `--no-extensions` | Disable extension discovery |
| `--skill <path>` | Load skill (repeatable) |
| `--no-skills` | Disable skill discovery |
| `--prompt-template <path>` | Load prompt template (repeatable) |
| `--no-prompt-templates` | Disable prompt template discovery |
| `--theme <path>` | Load theme (repeatable) |
| `--no-themes` | Disable theme discovery |
Combine `--no-*` with explicit flags to load exactly what you need, ignoring settings.json (e.g., `--no-extensions -e ./my-ext.ts`).
### Other Options
| Option | Description |
|--------|-------------|
| `--system-prompt <text>` | Replace default prompt (context files and skills still appended) |
| `--append-system-prompt <text>` | Append to system prompt |
| `--verbose` | Force verbose startup |
| `-h`, `--help` | Show help |
| `-v`, `--version` | Show version |
### File Arguments
Prefix files with `@` to include in the message:
```bash
pi @prompt.md "Answer this"
pi -p @screenshot.png "What's in this image?"
pi @code.ts @test.ts "Review these files"
```
### Examples
```bash
# Interactive with initial prompt
pi "List all .ts files in src/"
# Non-interactive
pi -p "Summarize this codebase"
# Different model
pi --provider openai --model gpt-4o "Help me refactor"
# Limit model cycling
pi --models "claude-*,gpt-4o"
# Read-only mode
pi --tools read,grep,find,ls -p "Review the code"
# High thinking level
pi --thinking high "Solve this complex problem"
```
### Environment Variables
| Variable | Description |
|----------|-------------|
| `PI_CODING_AGENT_DIR` | Override config directory (default: `~/.pi/agent`) |
| `PI_SKIP_VERSION_CHECK` | Skip version check at startup |
| `VISUAL`, `EDITOR` | External editor for Ctrl+G |
---
## Contributing & Development
See [CONTRIBUTING.md](../../CONTRIBUTING.md) for guidelines and [docs/development.md](docs/development.md) for setup, forking, and debugging.
---

View file

@ -0,0 +1,69 @@
# Development
See [AGENTS.md](../../../AGENTS.md) for additional guidelines.
## Setup
```bash
git clone https://github.com/badlogic/pi-mono
cd pi-mono
npm install
npm run build
```
Run from source:
```bash
./pi-test.sh
```
## Forking / Rebranding
Configure via `package.json`:
```json
{
"piConfig": {
"name": "pi",
"configDir": ".pi"
}
}
```
Change `name`, `configDir`, and `bin` field for your fork. Affects CLI banner, config paths, and environment variable names.
## Path Resolution
Three execution modes: npm install, standalone binary, tsx from source.
**Always use `src/config.ts`** for package assets:
```typescript
import { getPackageDir, getThemeDir } from "./config.js";
```
Never use `__dirname` directly for package assets.
## Debug Command
`/debug` (hidden) writes to `~/.pi/agent/pi-debug.log`:
- Rendered TUI lines with ANSI codes
- Last messages sent to the LLM
## Testing
```bash
./test.sh # Run non-LLM tests (no API keys needed)
npm test # Run all tests
npm test -- test/specific.test.ts # Run specific test
```
## Project Structure
```
packages/
ai/ # LLM provider abstraction
agent/ # Agent loop and message types
tui/ # Terminal UI components
coding-agent/ # CLI and interactive mode
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

View file

@ -0,0 +1,79 @@
# JSON Event Stream Mode
```bash
pi --mode json "Your prompt"
```
Outputs all session events as JSON lines to stdout. Useful for integrating pi into other tools or custom UIs.
## Event Types
Events are defined in [`AgentSessionEvent`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
```typescript
type AgentSessionEvent =
| AgentEvent
| { type: "auto_compaction_start"; reason: "threshold" | "overflow" }
| { type: "auto_compaction_end"; result: CompactionResult | undefined; aborted: boolean; willRetry: boolean; errorMessage?: string }
| { type: "auto_retry_start"; attempt: number; maxAttempts: number; delayMs: number; errorMessage: string }
| { type: "auto_retry_end"; success: boolean; attempt: number; finalError?: string };
```
Base events from [`AgentEvent`](https://github.com/badlogic/pi-mono/blob/main/packages/agent/src/types.ts#L179):
```typescript
type AgentEvent =
// Agent lifecycle
| { type: "agent_start" }
| { type: "agent_end"; messages: AgentMessage[] }
// Turn lifecycle
| { type: "turn_start" }
| { type: "turn_end"; message: AgentMessage; toolResults: ToolResultMessage[] }
// Message lifecycle
| { type: "message_start"; message: AgentMessage }
| { type: "message_update"; message: AgentMessage; assistantMessageEvent: AssistantMessageEvent }
| { type: "message_end"; message: AgentMessage }
// Tool execution
| { type: "tool_execution_start"; toolCallId: string; toolName: string; args: any }
| { type: "tool_execution_update"; toolCallId: string; toolName: string; args: any; partialResult: any }
| { type: "tool_execution_end"; toolCallId: string; toolName: string; result: any; isError: boolean };
```
## Message Types
Base messages from [`packages/ai/src/types.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/types.ts#L134):
- `UserMessage` (line 134)
- `AssistantMessage` (line 140)
- `ToolResultMessage` (line 152)
Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/messages.ts#L29):
- `BashExecutionMessage` (line 29)
- `CustomMessage` (line 46)
- `BranchSummaryMessage` (line 55)
- `CompactionSummaryMessage` (line 62)
## Output Format
Each line is a JSON object. The first line is the session header:
```json
{"type":"session","version":3,"id":"uuid","timestamp":"...","cwd":"/path"}
```
Followed by events as they occur:
```json
{"type":"agent_start"}
{"type":"turn_start"}
{"type":"message_start","message":{"role":"assistant","content":[],...}}
{"type":"message_update","message":{...},"assistantMessageEvent":{"type":"text_delta","delta":"Hello",...}}
{"type":"message_end","message":{...}}
{"type":"turn_end","message":{...},"toolResults":[]}
{"type":"agent_end","messages":[...]}
```
## Example
```bash
pi --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'
```

View file

@ -0,0 +1,212 @@
# Settings
Pi uses JSON settings files with project settings overriding global settings.
| Location | Scope |
|----------|-------|
| `~/.pi/agent/settings.json` | Global (all projects) |
| `.pi/settings.json` | Project (current directory) |
Edit directly or use `/settings` for common options.
## All Settings
### Model & Thinking
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `defaultProvider` | string | - | Default provider (e.g., `"anthropic"`, `"openai"`) |
| `defaultModel` | string | - | Default model ID |
| `defaultThinkingLevel` | string | - | `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"` |
| `hideThinkingBlock` | boolean | `false` | Hide thinking blocks in output |
| `thinkingBudgets` | object | - | Custom token budgets per thinking level |
#### thinkingBudgets
```json
{
"thinkingBudgets": {
"minimal": 1024,
"low": 4096,
"medium": 10240,
"high": 32768
}
}
```
### UI & Display
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `theme` | string | `"dark"` | Theme name (`"dark"`, `"light"`, or custom) |
| `quietStartup` | boolean | `false` | Hide startup header |
| `collapseChangelog` | boolean | `false` | Show condensed changelog after updates |
| `doubleEscapeAction` | string | `"tree"` | Action for double-escape: `"tree"` or `"fork"` |
| `editorPaddingX` | number | `0` | Horizontal padding for input editor (0-3) |
| `showHardwareCursor` | boolean | `false` | Show terminal cursor |
### Compaction
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `compaction.enabled` | boolean | `true` | Enable auto-compaction |
| `compaction.reserveTokens` | number | `16384` | Tokens reserved for LLM response |
| `compaction.keepRecentTokens` | number | `20000` | Recent tokens to keep (not summarized) |
```json
{
"compaction": {
"enabled": true,
"reserveTokens": 16384,
"keepRecentTokens": 20000
}
}
```
### Branch Summary
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `branchSummary.reserveTokens` | number | `16384` | Tokens reserved for branch summarization |
### Retry
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `retry.enabled` | boolean | `true` | Enable automatic retry on transient errors |
| `retry.maxRetries` | number | `3` | Maximum retry attempts |
| `retry.baseDelayMs` | number | `2000` | Base delay for exponential backoff (2s, 4s, 8s) |
```json
{
"retry": {
"enabled": true,
"maxRetries": 3,
"baseDelayMs": 2000
}
}
```
### Message Delivery
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `steeringMode` | string | `"one-at-a-time"` | How steering messages are sent: `"all"` or `"one-at-a-time"` |
| `followUpMode` | string | `"one-at-a-time"` | How follow-up messages are sent: `"all"` or `"one-at-a-time"` |
### Terminal & Images
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `terminal.showImages` | boolean | `true` | Show images in terminal (if supported) |
| `images.autoResize` | boolean | `true` | Resize images to 2000x2000 max |
| `images.blockImages` | boolean | `false` | Block all images from being sent to LLM |
### Shell
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `shellPath` | string | - | Custom shell path (e.g., for Cygwin on Windows) |
| `shellCommandPrefix` | string | - | Prefix for every bash command (e.g., `"shopt -s expand_aliases"`) |
### Model Cycling
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `enabledModels` | string[] | - | Model patterns for Ctrl+P cycling (same format as `--models` CLI flag) |
```json
{
"enabledModels": ["claude-*", "gpt-4o", "gemini-2*"]
}
```
### Markdown
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `markdown.codeBlockIndent` | string | `" "` | Indentation for code blocks |
### Resources
These settings define where to load extensions, skills, prompts, and themes from.
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `packages` | array | `[]` | npm/git packages to load resources from |
| `extensions` | string[] | `[]` | Local extension file paths or directories |
| `skills` | string[] | `[]` | Local skill file paths or directories |
| `prompts` | string[] | `[]` | Local prompt template paths or directories |
| `themes` | string[] | `[]` | Local theme file paths or directories |
| `enableSkillCommands` | boolean | `true` | Register skills as `/skill:name` commands |
#### packages
String form loads all resources from a package:
```json
{
"packages": ["pi-skills", "@org/my-extension"]
}
```
Object form filters which resources to load:
```json
{
"packages": [
{
"source": "pi-skills",
"skills": ["brave-search", "transcribe"],
"extensions": []
}
]
}
```
See [packages.md](packages.md) for package management details.
## Example
```json
{
"defaultProvider": "anthropic",
"defaultModel": "claude-sonnet-4-20250514",
"defaultThinkingLevel": "medium",
"theme": "dark",
"compaction": {
"enabled": true,
"reserveTokens": 16384,
"keepRecentTokens": 20000
},
"retry": {
"enabled": true,
"maxRetries": 3
},
"enabledModels": ["claude-*", "gpt-4o"],
"packages": ["pi-skills"]
}
```
## Project Overrides
Project settings (`.pi/settings.json`) override global settings. Nested objects are merged:
```json
// ~/.pi/agent/settings.json (global)
{
"theme": "dark",
"compaction": { "enabled": true, "reserveTokens": 16384 }
}
// .pi/settings.json (project)
{
"compaction": { "reserveTokens": 8192 }
}
// Result
{
"theme": "dark",
"compaction": { "enabled": true, "reserveTokens": 8192 }
}
```

View file

@ -2,7 +2,7 @@
# TUI Components
Hooks and custom tools can render custom TUI components for interactive user interfaces. This page covers the component system and available building blocks.
Extensions and custom tools can render custom TUI components for interactive user interfaces. This page covers the component system and available building blocks.
**Source:** [`@mariozechner/pi-tui`](https://github.com/badlogic/pi-mono/tree/main/packages/tui)
@ -14,7 +14,8 @@ All components implement:
interface Component {
render(width: number): string[];
handleInput?(data: string): void;
invalidate?(): void;
wantsKeyRelease?: boolean;
invalidate(): void;
}
```
@ -22,7 +23,8 @@ interface Component {
|--------|-------------|
| `render(width)` | Return array of strings (one per line). Each line **must not exceed `width`**. |
| `handleInput?(data)` | Receive keyboard input when component has focus. |
| `invalidate?()` | Clear cached render state. |
| `wantsKeyRelease?` | If true, component receives key release events (Kitty protocol). Default: false. |
| `invalidate()` | Clear cached render state. Called on theme changes. |
The TUI appends a full SGR reset and OSC 8 reset at the end of each rendered line. Styles do not carry across lines. If you emit multi-line text with styling, reapply styles per line or use `wrapTextWithAnsi()` so styles are preserved for each wrapped line.
@ -84,7 +86,7 @@ Without this propagation, typing with an IME (Chinese, Japanese, Korean, etc.) w
## Using Components
**In hooks** via `ctx.ui.custom()`:
**In extensions** via `ctx.ui.custom()`:
```typescript
pi.on("session_start", async (_event, ctx) => {
@ -337,7 +339,7 @@ class MySelector {
}
```
Usage in a hook:
Usage in an extension:
```typescript
pi.registerCommand("pick", {