demo.web.mp4
▸ 88s walkthrough — plays right here, no download. Want the lightweight loop instead? GIF version
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.
pitago wraps the pi agent in a beautiful terminal interface with:
- Real-time chat with streaming responses
- Sidebar showing session info, model details, token usage, and git status
- Command palette with builtins and extension commands
- File mention support (
@file) - Image send via
@photo.pngor dropping/pasting file paths — orCtrl+Von a copied screenshot (macOS needspngpaste, Linux useswl-paste/xclip). Vision over RPC, max 5 × 8MB. Paths collapse into[Image N]chips;↓moves into the tray,←→picks a chip,⌫deletes it,Escback - Recent models picker
- Clipboard integration (
Ctrl+Yto yank last answer)
- Go ≥ 1.27
piavailable in PATH (or setPI_BINto its path)- An API key for your provider (e.g.
ANTHROPIC_API_KEY), or run/logininside the app to save one to the keystore
curl -fsSL https://raw.githubusercontent.com/cavaldos/pitago/main/script/install.sh | bashInvoke-WebRequest https://github.com/cavaldos/pitago/releases/latest/download/pitago-windows-amd64.exe -OutFile pitago.exe
# move pitago.exe somewhere on your PATH, then: pitago --versionFrom source (requires Go ≥ 1.27):
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 --versionUninstall (if installed into bin):
macOS:
rm ~/.local/bin/pitago # or /usr/local/bin/pitago if you installed with sudo before
rm -rf ~/.config/pitago # optional: remove saved API keys + recent modelsLinux:
rm ~/.local/bin/pitago # or /usr/local/bin/pitago if you installed with sudo before
rm -rf ~/.config/pitago # optional: remove saved API keys + recent modelsWindows (PowerShell):
del C:\path\to\pitago.exe # wherever you placed it (a folder on your PATH)
Remove-Item -Recurse -Force $HOME\.config\pitago # optional: remove saved API keys + recent modelsBuild and run straight from source:
script/run.sh# From the repo root — everything lives under src/
go run ./src
# Open another working directory (flags first, then the path)
go run ./src ~/Code/workspace
go run ./src --cwd ~/Code/workspace
# Resume most recent session
go run ./src -c
# Specify provider and model
go run ./src --provider anthropic --model claude-sonnet-4-20250514
# Don't persist a session
go run ./src --no-session
# Self-update to the latest GitHub release
go run ./src --update # or /update inside the app
# Mouse (sidebar click + wheel scroll) is on by default;
# opt out with --mouse=false for plain highlight-to-copy
go run ./src --mouse=falsePress /live to list the pi sessions running in the current directory and
attach to one of them. It appears live in an EXTERNAL · READ-ONLY view;
/live again or Ctrl+D detaches and you can type prompts normally.
You start the pi sessions yourself; pitago only views them. Two sources are
offered in the same picker: a bridge session (token-level streaming, busy
spinner) and a session file session, which works with any running pi —
no restart, no extension, nothing required of that process. The bridge
extension is installed for you on the first /live.
Full documentation, including what each source can and cannot show: resources/doc/LIVE-SESSION.md.
# Vet
go vet ./...
# Build
go build -o /tmp/pitago ./src
# Test
go test ./...Tag push triggers the release workflow, which cross-builds
(linux-amd64, darwin-amd64/arm64, windows-amd64) and publishes a GitHub Release:
script/test-cicd.sh # check vet + test + builds locally first
script/release.sh v0.0.1| Key | Action |
|---|---|
Enter |
Send (idle) / steer (while running) |
Esc×2 |
Cancel running turn (double-press within 3s — 1st press only arms) |
Ctrl+C |
Quit (press twice within 3s — warning pins to the sidebar corner) |
Ctrl+N |
New session |
Ctrl+P |
Cycle model |
Ctrl+R |
Recent-models picker |
Ctrl+T |
Cycle thinking level (no picker) |
Ctrl+E |
Hide/show sidebar (hide for clean drag-select of chat only) |
Ctrl+Y |
Yank last assistant answer to clipboard (chat-only, no sidebar) |
Ctrl+V |
Paste text — or screenshot data (pngpaste/wl-paste/xclip); errors shown, terminal Cmd+V still works |
Backspace |
Empty input + image tray → remove last [Image N] chip |
↓ (+tray) |
Cursor into the image tray · ←→ pick a chip · ⌫ delete it · Esc back to input |
Ctrl+O |
Yank picker: choose any message to copy (sidebar stays visible) |
Ctrl+G |
Expand/collapse tool output: write content, read results, diffs (collapsed previews like pi) |
Alt+1…5 |
Jump straight to a recent model |
Tab |
Complete /command or @file |
@ |
Mention a file (fuzzy finder, like pi — Tab/Enter completes, text goes to pi raw; @*.png/.jpg/.gif/.webp also sends vision) |
↑↓ PgUp PgDn |
Empty input: recall sent messages (↑ older · ↓ newer · Esc clear) · otherwise scroll chat (single-line input) |
Alt+↑↓ PgUp PgDn Home End or Ctrl+↑↓ PgUp PgDn Home End |
Scroll sidebar (keyboard, always works) |
Mouse wheel |
On by default: hover sidebar to scroll it, chat otherwise; --mouse=false disables |
- With mouse on (default): hold
Option/Shift(terminal-dependent) to select - Or toggle it at runtime with
/mouse(/mouse offfor plain highlight-to-copy), or start with--mouse=false - To copy only chat content (without sidebar): hide the sidebar with
/sidebarorCtrl+E, then select - Or use
Ctrl+Y//yank(/copy) to copy the last assistant answer directly to clipboard - Or press
Ctrl+Oto pick any message to copy — sidebar stays visible - With mouse on: hold
Option/Shift(terminal-dependent) to select
Type / to open the command popup. Two kinds:
(intercepted locally, re-implemented over RPC):
/model— change model/recent— recent models picker/yank//copy— copy last answer to clipboard/sidebar— hide/show sidebar/theme— switch TUI theme (/themeopens picker,/theme gruvboxapplies directly; orpitago --theme one-dark)/pet— pick the sidebar pet./petopens a two-pane dialog in the/modelshape: left = the entry list (18 animals plus theasciiandclassiclooks,▸cursor,●the one in use, type to filter,↑↓move,Enterapplies,Esccancels), right = a live demo of the highlighted entry./pet dragon,/pet asciiand/pet classicapply directly. In the ascii look the sidebar block draws the animal (name inline, 5 rows) and the animals take turns every ~20s; in the classic look it draws the compact animated kaomoji face with the status label on one row (2 rows, noPETtitle) and nothing rotates/plugins— collapse/expand installed pi plugins in the sidebar/mouse— toggle mouse (click sidebar, wheel scroll) at runtime,[on|off]; off for native text selection/update— check GitHub releases + install latest (auto-checks in background, once a day)/thinking— toggle thinking level/tree— session tree, pi-style rows.Enter(or a left click when mouse is on) opens pi's follow-up Tree action menu on the picked row:Jump to message(scrolls the chat to that message and marks it),Copy entry,Fork from here(user rows only — pi's fork rejects any other entry),Back to tree; rows that are not chat messages offerView entry(prints the full entry, e.g. a compaction or a label) instead of the jump.Esc/Ctrl+Creturns to the tree with the same row selected. Real branch navigation (pi'snavigateTree+Summarize branch?) is not possible over RPC — pi 0.87.1 has nonavigate_treecommand — so the menu is local; the tree itself is read-only over RPC/trajectory [all|tools|messages]— harness-style run trace window (numbered steps with time + kind, type to filter,Enterviews the full step in chat)/notification [filter]— browse notification history (time + info/error, newest first; in RAM for the current Pitago run, max 200)/settings— agent settings, pi parity (22 rows: model · thinking · steering · follow-up · auto-compact · auto-retry · theme + skill commands · show images · image width · auto-resize · block images · transport · http timeout · cache warming · hide thinking · cache-miss notices · project trust · quiet startup · telemetry · autocomplete max · tree filter; file rows save to~/.pi/agent/settings.jsonand reconnect pi; dialog shows pi-style position(6/33))/pitago-setting— Pitago settings hub: agent, skills, prompts, extensions, plugins, MCP servers, session tool stats, tasks, theme, login/login//logout— manage logins: API keys + pi OAuth/subscriptions (/login: left providers, right keys + auth —Enteruse/add,⌫delete/disconnect,sshow/hide key,rrename,Ctrl+Pmodel picker,Escclose; stays open, pi reconnects behind)/reload— reload extensions/new— new session/resume— resume picker (like pi: current project, Tab for all)/quit— exit/session— session management
(from pi's get_commands): forwarded to pi as /... prompt text, executed server-side.
The right column (pi session-panel style) shows:
- SESSION — first message + session id
- Model + thinking level
- Context bar (
used/total tkns) - Stats | Tokens —
time,last,speed,turns, context left,in/out/total/cache/cost - Clickable RECENT MODELS and COMMANDS counts
- Collapsible PLUGINS — installed pi packages (
pi list), click the header or/pluginsto collapse/expand - WORKSPACE — git status (branch + per-file
+add -del, refreshed every 10s and after each turn) - Current working directory
Hidden on terminals narrower than 80 columns.
Long content scrolls inside the sidebar (Ctrl/Alt+↑↓ PgUp PgDn Home End, or mouse wheel over it).
Source tree and import rules — see resources/doc/ARCHITECTURE.md.
In short: 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.
~/.config/pitago/keys.json(0600) — saved API keys, several per provider with one active + optional name/added-date (/login,/logout; active key is also written to pi'sauth.jsonso pi sees models)~/.config/pitago/pi_auth.json(0600) — mirrored pi logins (OAuth account/expiry, no secrets) so/loginlists + disconnects subscriptions done in stock pi~/.config/pitago/recent_models.json— recent models (max 5)~/.config/pitago/prefs.json(0600) — display prefs + the last model you picked (currentModel), passed topias--provider/--modelat startup so a new window reopens on it (explicit--provider/--modelflags win); also the sidebar pet (pet, missing = defaultcat) and its look (petStyle:ascii(default) orclassic)~/.config/pitago/theme.json— active TUI theme (25 built-ins: default, one-dark, gruvbox, catppuccin-mocha, dracula… —/themelists all)~/.config/pitago/update.json— last update-check timestamp + tag (24h TTL)/tmp/pitago-pi-stderr.log— pi child stderr






