claude-garage
v0.4.0
Published
Multiple Claude agents driving you crazy? Park them all in one garage: a needs-input queue that follows you across projects, a full-screen terminal TUI, and a browser wall with diff review. tmux owns the sessions; close the app and nothing dies.
Downloads
844
Maintainers
Readme
Multiple Claude agents driving you crazy? Park them all in one
garage. A needs-input queue that follows you across every project (a
jumps to whoever's waiting), file-by-file diff review, and tmux-owned
sessions that outlive the tool — reboot the Mac, tmux attach still works.
▶ 60-second reveal — the web wall, needs-input triage, diff review, and the pit pet, beat by beat:
https://github.com/user-attachments/assets/b19defa0-a60d-4082-9ca5-9b8ce9480b18
Why
Running multiple Claude Code sessions across multiple projects means juggling terminal windows and editor windows. There is no single place to see:
- which one is blocked waiting for your input — right now, anywhere. The real pain isn't window count, it's attention routing.
- what each session changed, reviewable without hunting
- which sessions exist, per project, without them dying the moment you close a terminal or reboot
claude-garage is that single place: the garage your agents are parked in, built around four things that rarely coexist.
- 🚨 Needs-input triage as a first-class queue. Blocked sessions sort
first everywhere, light up amber, and count into the header badge, the
tab title, and the TUI's status strip;
ajumps to whichever agent is waiting, across every project, on either surface. - 🔌 Real terminals that survive the tool. tmux owns every session, not
the app. Close the terminal, kill the daemon, reboot the Mac:
tmux attach -t garage/<workspace>/<label>still works, dead sessions restore with their full conversation (claude --resume) in one keypress, andtpops a live session into its own OS terminal window alongside the wall. - 📋 File-by-file diff review with an editor jump — in the web wall.
Per-workspace or per-worktree changes (committed and uncommitted), a
full-screen review mode with viewed-tracking, and
oto open your editor at the exact line. (The TUI doesn't have review mode yet — it's on the Roadmap.) - 🖥️ Every session of a project visible at once. Not a switcher: the
web wall renders every session in a workspace as a live terminal
simultaneously (split/resize/maximize/detach); the TUI groups sessions
into named views (
d/D/Tab) with a 6-tile grid and an overflow rail for the rest.
Quick start
npx claude-garage tuiA full-screen terminal wall, right in your terminal. Starts the daemon if
one isn't already running; 1–9 switch workspaces, Enter engages the
focused terminal (keys go to the agent byte-exact — Alt+arrows, paste,
everything), Ctrl+G hands keys back to the garage, a jumps to whoever's
waited longest, ? for the full keymap. Quitting the TUI leaves the daemon
and every tmux session running. It's also light: ~5ms input latency, ~2%
CPU, and a 2.4MB binary (measured on the ratatui port — see
openspec/changes/archive/2026-08-31-p9-ratatui-port/verification.md).
Since p10–p12, the TUI also groups sessions into views (d detaches the
focused one into its own view or rejoins it to the default, D moves it to
a chosen group, Tab cycles views), shows a dim auto-subtitle under each
session's label straight from Claude Code's own terminal-title updates (zero
config), and tracks context pressure: a per-tile meter plus a 5h/7-day
usage chip in the strip, fed by a one-keypress I install of a chaining
statusline wrapper (any statusline you already have keeps running). Closing
a plain session tears it down; closing a worktree session keeps its branch
and points you at the web wall to merge or discard it.
Prefer a browser?
npx claude-garageOpens the web wall at http://127.0.0.1:4747 — the companion surface, with
diff review and the worktree finish flow (see Web wall). Both
commands start the same daemon and see the same tmux sessions, so you can
run either one, or both, at once.
Requirements
- macOS (Linux support is on the Roadmap)
- Node.js ≥ 20
- tmux ≥ 3.2 (garage offers to
brew installit if missing) - Claude Code CLI on
PATH - Rust — not required on Apple Silicon. The TUI ships as a prebuilt
arm64binary in the npm package. On an Intel Mac,claude-garage tuibuilds it once from source the first time you run it ifcargois onPATH(rustup.rs); withoutcargoyou get an actionable error naming exactly what's missing, not a crash. The web wall never needs Rust.
Hooks (recommended): status updates poll every 2s by default. Click
install hooks for me in the web wall's banner (or press I in the TUI
for the statusline half of the story) for instant detection. The daemon
merges Claude Code's hooks/statusline into ~/.claude/settings.json (backup
kept, idempotent).
Local-only by design
Everything runs on your machine and stays there.
- The daemon binds to
127.0.0.1only. Nothing listens on your network. - No telemetry, no analytics, no accounts. garage collects nothing and phones home to no one.
- All state is a single local file (
~/.garage/state.json) plus your own tmux server and git repos. - Your sessions talk to Claude exactly as they would without garage. Both the TUI and the web wall are viewers, not a middleman.
Session states
| Glyph | State | Meaning |
|---|---|---|
| ● | needs-input | Claude is waiting on you: permission, question, plan approval. Never fades; sorts first everywhere. |
| ◐ | working | Claude is running. |
| ✓ | done | Finished a turn since you last looked (fades after 2 min). |
| ○ | idle | Waiting for you to ask, not to answer. |
| ⟳ | restorable | tmux died (reboot?). One keypress/click resurrects the conversation. |
Web wall
The browser companion (npx claude-garage, http://127.0.0.1:4747) carries
the features the TUI doesn't have yet:
- 🎨 Diff review: the changes pane and full-screen review mode described
in Why —
Tab/j/k/r/v/o, see Keybindings. - 🌳 Worktree finish flow: spawn a worktree session from either surface
(
Nin the TUI, the worktree toggle here), but merge / discard / keep on close is web-only for now — the TUI always keeps the branch and tells you to finish it here. - 🎨 Themes: garage, claude dark, claude light, or follow the OS. Terminals re-skin in place, full ANSI palettes included.
- 🔔 Notifications: badge + tab title in-app, opt-in browser
notifications (click to jump) when the tab is hidden, and a macOS
notification when no page is open (clickable with
terminal-notifier).
The pit pet 🐈
An optional ASCII companion on the key strip whose mood is the wall:
asleep when all is quiet, watching while agents run, sprinting toward the
rail with a ! the moment a session needs you (click it, that's the a
jump), hiding in a box if the daemon drops, and celebrating when the last
blocked session is answered. Clicking it when nothing is wrong pets it.
It appreciates this.
Arthur Papito Segan
Turn it on (or off again) anytime in ⚙ settings under pit pet. It's off by default: nobody gets a surprise Papito. Each species plays its state in character:
| Pet | Personality | |---|---| | Arthur (shop cat) | saunters, barely deigns to bounce, ignores about 40% of your strolls, and celebrates by kneading in place. Cats don't jump for joy in front of you | | Papito (rubber duck) | deadpan: waddles, never bounces, and alerts with a single motionless stare; celebration is exactly one flap | | Segan (pit pup) | maximum enthusiasm: fastest runner, biggest bounce, and celebrates with zoomies across the strip |
In the TUI the pet lives at the right end of the bottom strip, beside
the keys chip, as a one-row sprite (=o.o=, <(o )___, (·ᴥ·)), same
moods, same manners. It speaks right next to itself:
you're doing great!! (·ᴥ·) keys → garage. Press P to
cycle Arthur → Papito → Segan → off; the choice is remembered. Click the
pet while it's alert to jump to the blocked session, click it otherwise to
pet it. TUI pets also talk: every few minutes, in character, the strip
gets a line like "water. now. i'm not asking." (Arthur), "acceptable."
(Papito) or "you're doing great!!" (Segan). They notice long days, late
nights, and a usage window running hot, and they never interrupt a session
that needs you. Set GARAGE_PET_ASCII=1 if your font lacks ᴥ.
Restarting
Two things go stale under a running wall: the garage daemon itself (after
a npm upgrade) and the claude binary inside every session (after
Anthropic ships a release — Claude Code shows "update available", but a
running session keeps the old process until it's restarted).
claude-garage restartRestarts the daemon only. Sessions are untouched; the TUI and web wall reconnect on their own through the existing SSE reconnect.
claude-garage restart --sessionsRestarts the daemon, then respawns every idle/done session in place —
tmux respawn-pane -k running claude --resume <id> in the same tmux
session, so the tile, its title and the conversation all survive. Sessions
that are working or needs-input are skipped and listed rather than
losing an in-flight turn; --all restarts those too.
In the TUI: r r restarts the focused session (press twice — the
first press warns if it's busy), r a restarts every idle/done session
in the focused workspace, r d restarts the daemon. ? lists all three.
In the web wall: the ↻ in a cell's hover controls restarts that
session, with the same two-click confirmation.
Upgrading the garage package itself is still npx claude-garage@latest tui.
Keybindings
The TUI's full keymap (claude-garage tui, also shown in-app with ?).
Bindings apply at the garage layer; Enter hands your keystrokes to the
focused session byte-exact until Ctrl+G takes them back.
Terminal: Ghostty, iTerm2, kitty and WezTerm pass every Claude Code
binding through, Shift+Enter included. macOS Terminal.app speaks neither
the kitty keyboard protocol nor modifyOtherKeys, so Shift+Enter can't be
told apart from Enter there; either switch terminals or add a Terminal.app
key mapping (Settings → Profiles → Keyboard) for Shift+Return that sends
\033[13;2u. Option+Enter and Ctrl+J work everywhere.
| Key | Action |
|---|---|
| 1–9 | focus workspace |
| [ / ] | cycle focused tile |
| Enter | engage focused tile (restore it when restorable) |
| Ctrl+G | disengage (while engaged) |
| m | maximize / restore focused tile |
| t | open focused session in a new terminal window (macOS) |
| a | jump to longest-waiting blocked session |
| A | triage queue |
| n / N | spawn session / worktree session |
| R | restore all restorable sessions in workspace |
| I | install statusline feed for context meters |
| x x | close focused session (press twice) |
| r r | restart focused session — resumes on the current claude binary |
| r a | restart idle/done sessions in workspace |
| r d | restart the daemon (sessions untouched) |
| X X | remove focused workspace (sessions keep running) |
| X K | remove focused workspace AND kill its sessions |
| w | add workspace |
| d | detach focused session to its own view, or rejoin main |
| D | move focused session to another view / new group |
| Tab | cycle the focused workspace's views |
| ? | toggle this help |
| q | quit (tmux sessions keep running) |
The web wall has its own compact keymap for its own features (grid
navigation plus diff review) — press ? there for the full list:
1–9 workspace, [/] cycle terminal, a jump, \ split cell, m
maximize, Tab/j/k/r/v/o for the changes pane and review mode,
Ctrl+` releases keys back to the browser wall.
How it works
tmux (persistence, source of truth)
└─ small Node daemon (spawn / list / bridge / diff / hooks / statusline)
├─ Rust terminal wall (ratatui + crossterm — `claude-garage tui`)
└─ browser web wall (React + xterm.js — `npx claude-garage`)The daemon is a thin Fastify process that shells out to tmux/git/claude
rather than re-implementing them; diffs are computed read-only; hook and
statusline events are token-authed. Both UIs are viewers over the same
daemon: the web wall over SSE + WebSockets, the TUI over HTTP/SSE for state
and direct tmux attach PTYs for the terminals themselves — no WebSocket
terminal bridge in the TUI path. tmux is the registry: garage can be deleted
and your sessions won't notice.
Development
npm install
npm run dev # daemon :4747 + Vite :5173 (web wall)
npm test # node:test suite (status, poller, hooks, layout, views)
npm run build:tui # cargo build --release; copies the binary into wall/distwall/ is a separate Rust workspace with its own unit and e2e suites
(cd wall && cargo test; e2e harnesses under wall/test/e2e).
Built through spec-driven phases (openspec/), each verified
end-to-end on a real system.
Roadmap
claude-garage attach: adopt an existing tmux session onto the wall- Review mode in the TUI (the web wall's file-by-file diff review, ported)
- Linux support
- Phone push (ntfy/webhook) for when you're away from the machine
- View renaming
License
MIT © Saiful Islam
claude-garage is a community project, not affiliated with or endorsed by Anthropic. "Claude" and "Claude Code" are Anthropic trademarks.
