demo.web.mp4
A polished Terminal User Interface (TUI) frontend for the pi agent, built with Bubble Tea. pi --mode rpc serves as the backend (multi-provider, tools, sessions, compaction), while pitago provides a rich terminal interface communicating over JSONL.
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/cavaldos/pitago/main/script/install.sh | bash
# Windows (PowerShell)
Invoke-WebRequest https://github.com/cavaldos/pitago/releases/latest/download/pitago-windows-amd64.exe -OutFile pitago.exeFrom source:
git clone https://github.com/cavaldos/pitago.git
cd pitago
script/build.sh # outputs bin/pitago (VERSION defaults to git tag/commit)
mkdir -p ~/.local/bin && cp bin/pitago ~/.local/bin/pitago
pitago --version
script/run.sh # or: go run ./src| Platform | Command |
|---|---|
| macOS / Linux | rm ~/.local/bin/pitago (or /usr/local/bin/pitago if you installed with sudo before) |
| Windows | del C:\path\to\pitago.exe — wherever you placed it, on a folder in your PATH |
| Any (reset data) | rm -rf ~/.config/pitago / Remove-Item -Recurse -Force $HOME\.config\pitago — drops saved API keys + recent models |
go run ./src # start in this directory
go run ./src ~/Code/workspace # or open another directory (flags first)
go run ./src -c # resume the most recent session
go run ./src -ne # load no pi extensions (same as `pi -ne`)
go run ./src --update # self-update to the latest GitHub releaseType / to open the command popup. Builtins are intercepted locally and re-implemented over
RPC; extension/prompt/skill commands come from pi's get_commands and run server-side.
| Command | Action |
|---|---|
/model · /recent |
Change model · recent models picker |
/yank /copy /copy-md /copy-tables /copy-code |
Copy the last assistant answer, whole or semantic |
/sidebar · /mouse [on|off] |
Hide/show sidebar · toggle mouse (click + wheel) |
/theme [name] |
Switch theme — picker, or apply directly (pitago --theme one-dark) |
/pet [name|ascii|classic] |
Sidebar pet: picker dialog, or apply directly |
/plugins |
Collapse/expand installed pi plugins in the sidebar |
/thinking |
Toggle thinking level |
/mcp |
MCP server manager: add/remove servers, per-server login, tools, reconnect, exposure, enable/disable |
/tree |
Navigate the session tree like pi: branches, fold, filters, labels, Enter switches branch (Esc Esc on an empty input opens it too) |
/focus [path[:start-end]] |
File tree (neo-tree style) + code view: select lines (v/drag), ask the AI about only those lines |
/trajectory [all|tools|messages] |
Harness-style run trace window (updates live while pi runs) |
/notification [filter] |
Notification history (time + info/error, newest first) |
/settings |
Agent settings, saved to ~/.pi/agent/settings.json |
/pitago-setting |
Pitago hub: agent, skills, prompts, extensions, plugins, MCP, tasks, theme, login |
/login · /logout |
Manage API keys + pi OAuth/subscriptions |
/live |
Attach read-only to a running pi session |
/reload |
Reload extensions |
/new · /resume · /session |
New session · resume picker · session management |
/compact [instructions] |
Compact the context now (an LLM call, can take a while) |
/update |
Check GitHub releases and install the latest |
/quit |
Exit |
| Key | Action |
|---|---|
Enter |
Send (idle) / steer (while running) |
Esc×2 |
Cancel running turn (double-press within 3s — 1st press only arms). Before the model answers, the prompt is taken back: it returns to the input and the model never sees it |
Ctrl+C |
Clear the input — text, a recalled message, the image tray; on an empty input, quit (press twice within 3s) |
Ctrl+N |
New session |
Ctrl+P / Ctrl+R / Alt+1…5 |
Cycle model · recent-models picker · jump to a recent model |
Ctrl+T |
Cycle thinking level (no picker) |
Ctrl+E |
Hide/show sidebar (hide for clean drag-select of chat only) |
Ctrl+Y / Ctrl+O |
Yank last assistant answer · yank picker for any message |
Ctrl+V |
Paste text — or screenshot data (pngpaste/wl-paste/xclip) |
Ctrl+G |
Expand/collapse tool output: write content, read results, diffs |
Backspace |
Empty input + image tray → remove the last [Image N] chip |
↓ (+tray) |
Cursor into the image tray · ←→ pick a chip · ⌫ delete it · Esc back to input |
Tab |
Complete /command or @file |
@ |
Mention a file (fuzzy finder; @*.png/.jpg/.gif/.webp also sends vision) |
↑↓ PgUp PgDn |
Empty input: recall sent messages (Esc clear) · otherwise scroll chat |
Tab |
Toggle plan mode (/complete in the palette, @complete files) |
End |
Jump to the latest message — a hint chip with the same shortcut floats over the transcript while you are scrolled up (click it to jump too) |
Alt+… or Ctrl+↑↓ PgUp PgDn Home End |
Scroll the sidebar |
Mouse wheel |
Hover sidebar to scroll it, the chat otherwise; --mouse=false disables |
Type ! on an empty input to switch the editor into a local shell: Enter runs the line, Esc
leaves the mode and kills the process. Nothing typed in shell mode ever reaches pi — no turn, no
session entry — so the command is yours, not the model's. (!cmd still goes to pi, unchanged.)
| Key | Action |
|---|---|
! (empty input) |
Enter shell mode |
Enter |
Run the line; output lands in the chat as a bash block (stderr included, non-zero exit marked) |
↑↓ / Shift+↑↓ |
Recall an earlier shell command (Esc clears) — never a message sent to pi |
Esc |
Leave shell mode, kill the shell, drop a recalled command |
Ctrl+C |
Interrupt the running command (the shell keeps its cwd); idle, clear the line / double-press quit |
Ctrl+V |
Paste a command (the editor's other keys keep working: chat scroll, sidebar) |
One long-lived shell runs every line with the session cwd, so cd, export and shell variables
persist between commands. The program is $SHELL (see /settings → Pitago → Shell binary for
an override: $SHELL or an absolute path). Commands run one at a time with an empty stdin and no
terminal, so a typo'd quote reports a syntax error, cat/read see end-of-file and sudo/ssh
password prompts fail fast instead of hanging the mode. A block
shows the first 12 output lines (Ctrl+G shows all) and keeps the first 16 KB of a command's output,
so one chatty command cannot slow down typing afterwards.
pi's own !cmd escape (a fresh process per command, output visible to the model) is untouched.
| Action | How |
|---|---|
| Drag-select | With mouse on (default): drag inside the chat — selection is clamped to the chat pane, edge auto-scrolls |
| Select a line | Double-click a chat line |
| Copy a block | Right-click an assistant block for Copy markdown, Copy N code block(s), Copy N table(s), Copy plain text — the menu only lists what the block contains |
| Mouse off | Native terminal selection; toggle at runtime with /mouse off |
| Last answer | Ctrl+Y / /yank / /copy, or /copy-md /copy-tables /copy-code for semantic content |
| Any message | Ctrl+O opens the yank picker |
Whole-message copy preserves raw Markdown, tables, fenced-code languages, and links; partial drag selection copies visible text without ANSI/OSC sequences.
go vet ./... # vet
go build -o /tmp/pitago ./src # build
go test ./... # test
script/test-cicd.sh # what CI runs, locally firstA tag push cross-builds (linux-amd64, darwin-amd64/arm64, windows-amd64) and publishes a GitHub
Release: script/release.sh v0.0.1.
app is a thin MVC shell, components holds pure view primitives, ext and pitago are
separate pure domain layers, builtin is a command surface over RPC, and pirpc/update are
the backend edges. script/check-layers.sh enforces the one-way import graph.
| Doc | What |
|---|---|
| resources/doc/ARCHITECTURE.md | Directory map and the import rules |
| resources/doc/CONFIGURATION.md | Every file under ~/.config/pitago/ |
| resources/doc/LIVE-SESSION.md | Attaching to a running pi session |
| resources/doc/CONTRIBUTING.md | Dev workflow, layers, tests |
| docs/design.md | Design notes: why each decision looks the way it does |
| docs/subagent-surface-hosts.md | Subagent surface hosts |






