roost is a terminal multiplexer for AI agent CLIs — pi, Claude Code, Codex, Gemini, opencode, your shell. Quit it, reboot your Mac, run roost — every tab, split, and stacked pane comes back, each agent resumed into its exact session.
No daemon. No detach. roost resurrects the desk, not the sentence being typed on it.
Real chrome, borrowed colors — these are roost's exact glyphs and layout, wearing a dark theme. In your terminal it wears yours: the chrome inherits your theme, always. Token spec: DESIGN-ui.md ↗
0
Daemons to run
6
Agent CLIs, one desk
1.4 MB
The whole binary
1
File of state: workspace.json
01
Quit, reboot, reopen the terminal, run roost. It rebuilds every tab, split, and stacked pane, then resumes each agent into the exact session it was in — right working directory and all. One honest exception: a turn in flight at the moment you quit — the sessions come back, the half-typed sentence doesn't.
02
Agent CLIs already persist their own conversation state and resume by id. So roost persists only the layout tree plus each pane's (adapter, cwd, session-id) — and relaunches processes on demand. No daemon required.
03
Stacked panes collapse to one-line title bars, each carrying a live status badge — working, needs input, waiting, idle, exited. Any number of agents fit in the space of one, and roost rings the bell when a background pane needs you.
04
list, status, spawn, fork, send, read, close, wait — eight verbs, the same binary in client mode, including a send --all broadcast to reach every pane at once. An agent inside a pane can spawn and orchestrate its own workers while you watch the whole fleet live. Authorization is scoped by default, not sandboxed — any in-pane agent with shell access can still reach the fleet token.
05
spawn --input holds the prompt until the pane's first output, so it can never land in a CLI that isn't reading yet. wait --until waiting blocks until the agent settles — and exits 3 on timeout, not 0, so a script chaining wait && read can tell a stall from a finish. Exit codes: 0 ok · 1 runtime · 2 usage · 3 timeout.
06
No client/server protocol, no detach, no scrollback serialization, no process migration. roost is a single foreground process — the hardest parts of a multiplexer simply don't exist here. The release binary is about 1.4 MB.
The layout is cheap, the processes are precious — keep them alive at all cost.
The processes are cheap, the layout × session-id mapping is precious — persist that, relaunch the rest.
A single file — workspace.json — is the whole product, morally. Atomic writes on every change; delete it to start clean.
{ "active_tab": 0, "tabs": [{ "name": "pi-mono", "panes": { "p1": { "adapter": "pi", "cwd": "~/code/pi-mono", "session": "01998e5f…" } } }] }
The core is pure and fully unit-tested — it never touches a PTY, socket, or the filesystem. Real I/O lives at the edges, behind trait boundaries.
Everything's on Alt, so it never fights the agents' own Ctrl bindings. Everything else passes straight through to the focused pane.
Mouse selection needs no chord. Drag to select — it copies on release. Double-click a word, triple-click a line, Shift+click extends. It goes straight to the system clipboard, over SSH too (OSC 52). Alt+c is only for scrollback, or panes where the app underneath already owns the mouse.
A shipped extension reports session ids and exact status over roost's unix socket — no spinner-parsing. roost installs and updates it automatically at startup (opt out with ROOST_NO_EXT_INSTALL).
Hook snippets point Notification / Stop / PreToolUse at the same socket. Session detection falls back to diffing the project's .jsonl dir.
Any $SHELL, relaunched in its saved cwd. Status comes from PTY-output heuristics — bytes flowing means working, the bell means needs-you.
Sessions are filed by date, not by project — ~/.codex/sessions/YYYY/MM/DD/ — so detection can't be scoped to a working directory the way claude's is. Newest file wins.
Scoped per project: a slug from ~/.gemini/projects.json points at that project's chat history, and the session id is read straight out of the newest record.
Every session lives in one global SQLite database, not separate files — so there's no filesystem detection at all. roost resumes only by the session id it already has on record.
Homebrew
Prebuilt binaries, checksum-verified by brew.
mise
Same binaries, no tap — straight from releases.
Releases
v0.1.11, four targets, checked against SHA256SUMS.txt.
Source
cargo install --git, no clone needed.
macOS note: roost's shortcuts live on Alt. Tell your terminal to treat Option as Meta — Terminal.app and iTerm2 need a one-time setting; Ghostty, WezTerm, and kitty already do.
Free and open source. Your agents come home to roost after every reboot.