Unterm
Advanced usage

Recipes for getting more out of Unterm

Every command here was run against a real Unterm before it was written down. Copy, paste, adjust the names.

Agents

Connect Unterm to your agents

Registers Unterm as an MCP server with every agent it finds, adds a short note to their global context (CLAUDE.md, AGENTS.md, GEMINI.md) and wires the lifecycle hooks that report their state.

unterm-cli setup-ai --dry-run   # what would change
unterm-cli setup-ai             # register with every agent found

Limit it with --client claude-code (repeatable); undo everything with --remove.

Ask who needs you — from a script

The same inbox as Ctrl Shift A, on the command line. With --json it feeds a status bar, a notifier or a cron job.

unterm-cli agent inbox

# just the ones waiting on you
unterm-cli --json agent inbox \
  | jq -r '.items[] | select(.state=="waiting") | "\(.agent): \(.task_hint // .pane_title)"'
What it prints
PANE       AGENT     STATE      FOR     TAB   TASK
3      ✋   codex     waiting    23s     2     Partition the ledger tables
4      ✓   claude    done       13s     3     Fix the flaky checkout e2e test
2      ⚡   claude    working    27s     1     Add rate limiting to /v1/charge

codex: Partition the ledger tables

States are waiting, done, working and idle, sorted waiting-first.

Precise agent status with official hooks

Unterm reads an agent's state from its title and screen. Its own hooks (Claude Code hooks, Codex notify, Aider's notification command) are more precise: they say “waiting” the moment the agent asks.

unterm-cli agent enable-hooks --dry-run
unterm-cli agent enable-hooks

setup-ai already does this; this is the hooks alone, and --remove takes them out.

Run one task on several agents, merge the best

Each member gets its own git worktree, branch and tab. Compare the diffs, run your checks in each worktree, merge one and discard the rest.

cd ~/code/payments-api
unterm-cli fleet launch --cwd "$PWD" --agents claude,codex \
  -- "add an idempotency key to POST /v1/charge"

unterm-cli review diff    --fleet add-an-idempotency-key --member 1 --stat
unterm-cli review verify  --fleet add-an-idempotency-key --member 1 --command "cargo test"
unterm-cli review merge   --fleet add-an-idempotency-key --member 1
unterm-cli review discard --fleet add-an-idempotency-key --member 2
unterm-cli fleet clean add-an-idempotency-key
What it prints
fleet add-an-idempotency-key launched — 2 member(s)
  claude    fleet/add-an-idempotency-key-1  ~/code/payments-api.fleet/add-an-idempotency-key-1
  codex     fleet/add-an-idempotency-key-2  ~/code/payments-api.fleet/add-an-idempotency-key-2
  +?     -0     idempotency.rs (new)
verification verify-1790326294259-0 queued: cargo test
merged fleet/add-an-idempotency-key-1 — staged in ~/code/payments-api (commit it yourself)
member 2 of add-an-idempotency-key discarded
fleet add-an-idempotency-key cleaned

The merge is a squash left staged in your repo — the commit is yours. A member's uncommitted edits are included. Pass --cwd when you launch from a shell; without it the fleet uses the focused pane's folder.

Let an agent suggest, not type

The command appears as ghost text in the pane. You press Tab to take it or keep typing to ignore it — nothing runs without you.

unterm-cli session suggest post --rationale "tests passed" \
  -- "git push origin feat/rate-limit"
unterm-cli session suggest list
What it prints
Suggestion: sg_1790324293038_1
Status: queued
SUGGESTION               PANE     AGENT      TEXT
sg_1790324293038_1       5        anonymous  git push origin feat/rate-limit

session suggest list shows what is pending; cancel withdraws one.

Scripting

Open a tab, run something, read the result

For a script that needs a real shell with your environment: create a tab in the right folder, run a command and wait for it to finish, then read the screen.

P=$(unterm-cli session create --cwd ~/code/infra | awk '/^Pane:/{print $2}')
unterm-cli exec wait --pane-id $P --timeout-ms 600000 -- "git log --oneline -3 && ls"
unterm-cli session text --pane-id $P | tail -20
What it prints
2f1cf7d (HEAD -> main) init
README.md

exec wait returns the command's output when it exits; exec run fires and forgets.

Split a pane from outside

Put a log tail or a test watcher under the pane you are working in, without touching the mouse.

unterm-cli session split --direction down --size-percent 35 --cwd ~/code/web-dashboard
What it prints
Pane: 6
Title: /bin/zsh
Direction: down

Directions are right, left, down and up.

Several Unterm instances

Each running Unterm has a name — alpha, bravo, … — and every CLI command can be aimed at one.

unterm-cli instance set-title "payments on-call"
unterm-cli instance list
unterm-cli --instance bravo agent inbox
unterm-cli instance set-title --clear
What it prints
Title: payments on-call
ID        PID      MCP     HTTP    CWD                      TITLE
alpha     1383     49173   19877                            payments on-call

Without --instance, commands go to the active instance.

Speak MCP directly

Line-delimited JSON-RPC over TCP on 127.0.0.1. The port and a token are in the instance file; log in first, then call any of the 151 methods.

J=~/.unterm/server.json      # %USERPROFILE%\.unterm\server.json on Windows
PORT=$(jq .mcp_port $J); TOKEN=$(jq -r .auth_token $J)
{ printf '{"jsonrpc":"2.0","id":1,"method":"auth.login","params":{"token":"%s"}}\n' "$TOKEN"
  printf '{"jsonrpc":"2.0","id":2,"method":"agent.status"}\n'
  sleep 1; } | nc 127.0.0.1 "$PORT"
What it prints
{"id":1,"jsonrpc":"2.0","result":{"status":"ok"}}
{"id":2,"jsonrpc":"2.0","result":{"agents":[{"agent":"codex","pane_id":3,"state":"waiting",…},…],"enabled":true}}

unterm-cli reference lists every method; MCP clients can use the unterm-cli mcp-stdio bridge instead.

Keep and share

Hand a pane's history to a model

Plain text, no escape codes: the last N lines, or the whole session as Markdown with its project and shell recorded at the top.

unterm-cli scrollback --pane-id 2 --tail 200 > last-run.txt
unterm-cli session export --pane-id 2 -o session.md
What it prints
---
unterm_session_id: e2320821-38dc-4148-b94f-9bd4eef56357
tab_id: 2
project_path: ~/code/payments-api
project_slug: payments-api

Add --escapes to keep colours; --start-line/--end-line pick a range.

Take a screenshot of a whole scrollback

One tall PNG of everything a pane printed, rendered off-screen, so it works while the window is covered.

unterm-cli screenshot --scrollback --pane-id 2 -o pane.png

--max-rows caps it; on macOS, --scroll-app Safari does the same for another app's window.

Record a session to Markdown

Commands and their output, redacted and kept next to the project in .unterm/sessions — which Unterm tells git to ignore.

unterm-cli session record start
# … work in the pane …
unterm-cli session record stop
unterm-cli sessions list
unterm-cli sessions read <session-id>
What it prints
Session id: next-core-5-1790324289544601
Block count: 4
Markdown: ~/code/infra/.unterm/sessions/1790324289544601/tab-5-1790324289544601.md
Exit reason: recording_stopped

sessions list --project <slug> narrows it to one project.

Save your tabs, bring them back

A named set of tabs and their folders. Restore it after a reboot, or on another day's work.

unterm-cli workspace save morning
unterm-cli workspace restore morning --dry-run
unterm-cli workspace restore morning
What it prints
Workspace: morning
Sessions: 6
Workspace: morning
Planned: 6

--dry-run shows what would open without opening it.

Set it up your way

A separate identity per project

A profile carries tokens, a git identity and SSH keys. Secrets live in the system keychain and appear as environment variables only in that profile's tabs.

unterm-cli profile create "Work — Acme" --accent "#E8B34B"
unterm-cli profile set-secret "Work — Acme" GITHUB_TOKEN     # asks for the value
unterm-cli session create --cwd ~/code/acme --profile work-acme
What it prints
Created profile "Work — Acme"
  ID:    work-acme
Stored GITHUB_TOKEN in keychain for profile work-acme

macOS asks once for keychain access the first time a profile's secret is read. Pipe from a password manager with --from-stdin.

An administrator window on Windows

Open the command palette and choose “New Administrator Window”. Windows asks through UAC, then opens a separate, elevated Unterm.

It shares nothing with your normal window — no Core, no MCP server, no settings page — so nothing running as you can type into an elevated shell. Its title starts with “Administrator:”.

Tune it

Settings live in ~/.unterm/unterm.conf. A few worth knowing:

font_size = 14

[window]
padding_left = 16
padding_right = 16
backdrop = "mica"        # Windows 11

[cockpit]
done_hold_secs = 30      # how long a finished agent stays marked

unterm-cli settings open opens the settings page in your browser instead.

Keys worth learning

The full list, with anything you have rebound, is unterm-cli show-keys.

CtrlShiftP Command palette
CtrlShiftA Agent inbox
CtrlShiftAltA Launch a fleet
CtrlShiftS Quick select: copy a path, hash or URL by its label
CtrlShiftJ Composer: write a long prompt, send it when the pane is idle
CtrlShiftG Git panel
CtrlShiftD / E Split right / down
CtrlShiftZ Zoom the focused pane

CLI reference · MCP reference · See every feature