Skip to content
mrizzbenPublic

About

Phone-sized TUI for stalking your coding agents from the your phone. Watches pi, Claude Code, Codex & co across tmux, shows what they're doing right now, keeps a ledger of every session — and when one stalls waiting on you, answers it straight from your phone screen. Built on │ Rust + OpenTUI for the 30-column portrait life.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

portagent

A phone-sized terminal UI that watches any coding agents running on a box and keeps track of what they are doing — built for people who check in from a phone (Termius, Blink, iSH, any mobile ssh client) while Claude Code, Codex, aider, opencode or another agent works on their desktop.

portagent · 1▸ 0%                      08:14 ◐ 2s
● claude·… 3m12s 12%  Bash: cargo test --test auth
────────────────────────────────────────────────────────
· repo  2h04m  Bash: cargo test --test auth
j/k nav · ⏎ detail · q quit

One row per live agent: status dot, name+repo, how long it has been running, CPU, and what it is doing right now (the last tool call or message, from its session transcript). Finished sessions from today sit below in dim — the "keep track" view.

Press ⏎ for the detail screen: pid, cpu/mem, repo, full cwd, session age, the current request, and the recent transcript as a scrollable log.

claude · portagent
● running · pid 50423 · 3m12s
cpu 12% · mem 1%
repo: portagent
cwd: /Users/you/codebase/portagent
req: fix the flaky auth test
────────────────────────────────
03:12 tool Bash: cargo test --test auth
03:13 msg  Running 42 tests, 3 failed…
03:15 tool Edit: auth.rs
▾ scroll · esc back

Status legend

Glyph Meaning
● green turn in progress, or agent active in the last 90s
○ yellow alive but idle (waiting for input)
⌨ yellow idle and in a tmux pane — answer it with i
✗ red last turn ended in error
· dim a finished session from today (history)

Answering agents

When an agent finishes a turn it waits for your next line of input. If it runs inside a tmux pane, portagent can deliver your answer: the row shows a ⌨, and pressing i opens a text box at the bottom of the screen.

portagent · 2▸ 78%                    11:13 ◐ 2s
⌨ pi·port… 3h10m 78%  what should the plan be?
⌨ pi·revi… 2h53m  0%  what should the plan be?
────────────────────────────────────────────────
· pa-ans  35s  what should the plan be?
i answer · j/k nav · ⏎ detail · q quit

Type the answer and press ⏎ — it is delivered with tmux send-keys to the pane hosting that agent (the pane is found by walking the agent's process ancestry against tmux list-panes), so the agent reads it exactly as if you had typed in its window. esc cancels.

Agents not running in tmux show ○ idle and say so in the detail view — answer those in their own terminal.

Why it works well on a phone

  • Small screen first: every row and string is width-truncated before it is drawn, so a 30×12 portrait terminal never overflows or wraps.
  • Diff rendering (OpenTUI): only changed cells produce ANSI output, so each 2s refresh over a slow mobile ssh link is a few dozen bytes, not a full redraw.
  • No fragile key chords: single letters (j k q r h), Enter, Esc, and 1-9 to jump straight to an agent. Mouse tap/scroll also works where supported (disable with --no-mouse).
  • Bare-Escape handling: Esc is recognized even when the terminal sends it alone (50ms disambiguation window, so arrow keys still work when sequences arrive split over a laggy link).
  • Resize-safe: rotate the phone or open the soft keyboard mid-session; it re-sizes on the next tick.
  • Tidy exit: quitting restores your terminal and prints the current picture, so the last thing on screen is still useful.

Install

cargo install --path .
# binary: ~/.cargo/bin/portagent  (~900KB)

Or build and copy the binary anywhere (it has no runtime deps beyond the system's ps, and lsof on macOS for the working directory).

A terminal with truecolor (Termius, iTerm2, WezTerm, Ghostty…) shows the full palette; without it OpenTUI falls back to 256/16 colors automatically.

Reaching your machine from a phone

portagent runs on the box your agents run on — from a phone you ssh into it, so you need a route there and an SSH client app:

  1. A VPN between phone and machine. Easiest is Tailscale (free for personal use) on both — no port forwarding, no public IP, works from any network. Plain port-forwarding or a WireGuard tunnel works too.
  2. An SSH terminal app:
    • iOS: Termius (free tier is plenty), Blink, Secure Shellfish
    • Android: Termius, JuiceSSH, ConnectBot
  3. Connect: ssh box 'portagent' — or save the box as a host in the app and tap in. portagent --once is a nice scrollback-friendly one-shot if you don't want a live screen.

Usage

portagent                      # live TUI (auto-refresh every 2s)
portagent -i 5                 # slower polling for a laggy link
portagent --once               # scan once, print, exit — quick check
portagent --today              # today's session history, exit
portagent --no-mouse           # some mobile terminals lack mouse support
portagent --no-alt-screen      # render in scrollback instead of alt screen
portagent --retention 7        # keep ledger entries for 7 days (default 14)
portagent --data-dir /path     # override ledger location

From a phone:

ssh box 'portagent'                 # live monitor
ssh box 'portagent --once'          # one snapshot, readable in scrollback

Keys

Key Action
j / ↓ / Tab next agent
k / ↑ / ⇧Tab previous agent
⏎ / l / → agent detail
esc / h / ← back (in detail) / quit (in list)
i answer the selected agent (when it shows ⌨)
1-9 jump to agent N
r rescan now
q / ctrl-c quit

What it monitors

A process-table scan for known agents — matched by process name or command line, so native binaries, node …/cli.js invocations and bash-wrapper setups are all caught:

claude · codex · aider · opencode · gemini · cursor · pi · generic long-running node / python / bun agent scripts.

For Claude Code, Codex and pi it additionally tails the session transcripts (~/.claude/projects/…, ~/.codex/sessions/…, ~/.pi/agent/sessions/…) to show the last user request, the current tool call, and whether a turn is in progress. Agents without a known transcript format still get full process rows (cpu, mem, duration, repo).

Adding an agent family

Detection lives in src/agents.rs (detect_kind); transcript parsing per agent goes in src/transcript.rs (Claude, Codex and pi are the reference implementations — all three are append-only JSONL, tailed cheaply at 96KB).

The ledger

Every session is remembered in ~/.portagent/ledger.json ($PORTAGENT_HOME to override): first/last seen, end time, peak CPU, last message. Closed sessions are kept for 14 days (--retention <days>), capped at 500 entries.

$ portagent --today
portagent — today 2026-08-15
● claude     3m12s · portagent      Bash: cargo test --test auth
· codex      2h04m · ended 1h ago · website         Added contact form

The plain-text --once / --today modes double as cron-friendly check-ins.

How it works

ps (etime, macOS+Linux) ──► detection ──► transcript tail ──► ledger
        │                                              │
        └────────────── UI (OpenTUI diff render) ◄──────┘
  • Process scan every interval (default 2s); transcripts read the last 96KB of the newest session file, so huge sessions stay cheap.
  • Status logic: turn in progress or activity within 90s → running; quiet with a closed turn → idle; errored turn end → error.
  • Subagent (isSidechain) chatter is skipped — phone screens get the main thread's story.

Layout notes

The UI assumes ~30 columns × ~12 rows (hard minimum 10×3). At 44+ columns it shows more of the message preview; below that it drops CPU from the row (it stays in detail). History rows collapse to · name duration message.

Development

cargo test          # unit tests: ps/etime parsing, detection, transcripts, ledger, truncation
cargo clippy        # zero warnings

The TUI is also exercised with a pty harness: rendering, key handling, detail view, narrow width (30×12), number-key jump, and mid-run resize all exit cleanly with no panics.

About

Phone-sized TUI for stalking your coding agents from the your phone. Watches pi, Claude Code, Codex & co across tmux, shows what they're doing right now, keeps a ledger of every session — and when one stalls waiting on you, answers it straight from your phone screen. Built on │ Rust + OpenTUI for the 30-column portrait life.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages