A terminal board for running and triaging many AI coding-agent sessions in tmux.
Spawn two agents, watch their status, answer the waiting one from the triage queue, and it hands over the next.
Gate Inbox puts every coding agent on your machine in one list with live status, so the session
that is blocked on you is visible without hunting through terminal tabs. Claude Code, Codex and
OpenCode v2 work out of the box and run side by side, each in its own tmux session. Any other CLI
can be added as a [tools.<name>] block in the config.
It is a thin layer over the CLIs you already have. Each session launches your installed tool as-is, so your login, config files, MCP servers and every feature the tool ships carry over unchanged. Gate Inbox reads the panes; it does not sit between you and the model.
- Install. You need tmux 3.1+, git and at least one agent CLI (Claude Code, Codex or
OpenCode). Then run
go install github.com/usestring/gate-inbox@latest, or see Install below. - Start it. Run
gate-inbox, inside tmux or outside it. The welcome card lists which of your agent CLIs are ready, the five keys that matter, and any agents you already have running in tmux.non the card starts your first session. - Agents you already had. Anything you started by hand in tmux shows up on the board as-is.
The board then takes each one over: once it is idle, it is relaunched on the same conversation
as a board session, and a busy one is never interrupted. What a pane kept as-is would miss is
below; settings (
s) has "outside panes" to keep them as-is instead. - The loop.
nstarts an agent,enterfocuses it,ctrl+qcomes back to the list,iwalks everything waiting on you, andhshows every key. - Leaving and coming back.
qquits and the agents keep running. When you start it again, the board offers back only the sessions that died (a reboot, tmux restarting, a crash), never the ones you ended yourself. Stop using it covers stopping for good.
| An agent pane you started by hand, kept as-is... | Relaunched into the board, it... |
|---|---|
| keeps running where it is, in its own window | is ended once idle and resumed on the same conversation as a board session |
| has none of the board's MCP tools (spawn, message, tasks) | gets them |
can't be reached by other sessions or the CLI (send, read, answer, wait, kill) |
can be |
| reports status through the hooks the board registers in your Claude Code user settings (Claude Code only) | reports status through the hooks it is launched with |
lacks the GATE_INBOX_* environment, extension settings and a fresh account token |
gets all three |
| can't be forked, migrated, restarted or revived without a conversation id | can, on its own conversation |
| doesn't get the back-to-board keys or the pane's title and colours | gets them |
keeps the flags and --model it was started with |
is started from your config, so it doesn't keep them |
Gate Inbox runs on Linux and macOS, and on Windows inside WSL2. It needs tmux 3.1+ and git
on PATH, plus at least one agent CLI. Building needs Go 1.27.2+.
git clone https://github.com/usestring/gate-inbox.git
cd gate-inbox
go build -o gate-inbox .Or go install github.com/usestring/gate-inbox@latest, which puts gate-inbox in
$(go env GOPATH)/bin. docs/install.md covers optional dependencies, WSL and
updating.
gate-inboxnstarts an agent in the group under the cursor and focuses it. Type the task.ctrl+qgoes back to the list. Each row shows its status as the agent works.iopens the triage queue, starting with the session that has waited longest.- Answer it. The queue hands you the next one.
hshows every key for the current screen, andsopens settings.
Sessions live in tmux, so quitting the board leaves them running. Start gate-inbox again and it
picks them back up.
Spawn. n starts a session in the selected group. ctrl+n opens the full form (tool, name,
directory, first prompt, group). Agents name their own sessions after the task.
Reuse prompts (experimental). Enable Prompt suggestions under Settings → Experimental
(default off). In the New Session form's prompt field, matching suggestions appear as you type.
ctrl+n / ctrl+p choose among them and ctrl+y inserts the chosen text for editing;
accepting does not launch the session. Suggestions come from the newest 16 MiB of each CLI's
submission log within the past 30 days. A whole prompt or a line in a multi-line prompt must occur
at least four times to qualify. Counting ignores case and repeated whitespace, and each submission
counts once per candidate. The logs are reread in the background every minute. History and matching
stay local; this feature makes no network requests. The hotkey-only snippet menu is unchanged.
See status. Every row shows whether its agent is working, waiting on you, finished or idle,
read from the pane itself. The preview beside the list shows the conversation as You and
Assistant messages, without the tool noise. w filters the list to what needs attention, and
/ searches names, groups, statuses and what the sessions have said.
Triage. i flattens the groups into one queue ordered by what needs a person: waiting first,
then finished, then errored, longest-blocked first inside each. Picking an option in a dialog, or
sending a reply, hands that session back to its agent and opens the next one. ctrl+q moves on
without answering, and ctrl+\ stops triage. alt+\ puts the list away for a full-width drain,
and alt+, hides the key hints.
Triage with the list put away. Answer one session and the next that needs you comes up on its own.
Focus. enter focuses a session in place: keys go to the agent while the list stays beside
it, and ctrl+q comes back. alt+\ hides the list so the pane gets the full width, and
alt+u / alt+end scroll back through its output and return to the live bottom. space
opens the hotkey menu, which sends one of your snippets to the selected session without focusing it; a
lettered snippet also sends on option+shift+<key> in one press, no menu. T opens a shell tab under the
selected agent for builds and one-off commands.
Focus a session, give it the full width, type a multi-line instruction, scroll back through the reply, and ctrl+q out.
| Key | Action |
|---|---|
n / ctrl+n |
New session, quick or with the full form |
space |
Hotkey menu: send a snippet to the selected session |
enter |
Focus the session; ctrl+q returns to the list |
i |
Triage queue; \ hides the list for a full-width drain |
w |
Show only what needs attention |
Y |
Show only one CLI's sessions, cycling through the harnesses on the board |
/ |
Fuzzy search; esc closes the field, deleting the text clears it |
p |
Priority tier for a session or group; each press steps urgent → high → medium → low → none |
M / ctrl+m |
Mute / unmute: keep a session out of triage until unmuted; the row reads muted |
T |
Shell tab under the selected agent |
x / v |
Kill a session to free its RAM / revive it on its own conversation |
: / ctrl+p |
Quick actions: type what you want, enter runs it, and each row shows its key |
h / s |
Key map for the current screen / settings |
Priority defaults to 0 with no marker. Positive levels use green ▲, ▲▲, and ▲▲▲; the negative level (-1) uses a red ▼. Set a level with gate-inbox priority <level> using a number from -1 to 3 or its tier name.
Every binding is a default, and h is where you rebind one. docs/usage.md is
the complete reference.
Every MCP-capable session launches with the Gate Inbox MCP server, so an agent can list the other
sessions, spawn a child, send it a message, read its screen and wait for it to finish. The same
actions are gate-inbox subcommands for a shell inside any session (gate-inbox help). A spawned
child is drawn under its parent, and its questions go to the parent first.
Config lives at ~/.config/gate-inbox/config.toml on Linux and
~/Library/Application Support/gate-inbox/config.toml on macOS, and is created on first run.
GATE_INBOX_HOME points the board at another directory, which then holds the config, the
state.db store and the logs.
Adding a CLI takes a tool block with the patterns its pane shows in each state:
[tools.mytool]
command = "mytool"
default_status = "idle"
rules = [
{ state = "waiting", pattern = "(?m)^\\s*❯\\s+\\d+\\." },
{ state = "working", pattern = "esc to interrupt" },
]Sessions run on tmux's default server as gi_* sessions, and the board never changes a
server-global option. Set tmux_socket to keep them on a server of their own.
docs/configuration.md covers every field: status detection, revive and
fork commands, prompts and MCP registration.
Both are opt-in and talk only to services you run or already use.
Pull requests and tickets. Gate Inbox finds the pull requests and tickets a session is working
on from its branch and its output, and hangs them under the session with their CI and review state.
GitHub goes through your logged-in gh CLI; Linear reads LINEAR_API_KEY from the environment.
A missing credential is not a failure: without LINEAR_API_KEY tickets are still listed, just
without their state. Either source can be turned off outright, which hides its rows:
[integrations.github]
enabled = false
[integrations.linear]
enabled = falseArtifacts. An extension that lets agents publish a report or an HTML page and hand back a link
that opens from any session, whichever CLI it runs. It is off until you enable it, and the store
behind it is a Cloudflare Worker you deploy yourself; see
extension/artifacts/worker/README.md.
[extensions.artifacts]
enabled = trueExtensions are Go code compiled into the binary against the public extension package; the app
package runs the board with whichever extensions a build carries. A build of your own lists its
extensions in app.Options, and carries the artifacts one by listing artifacts.New() from
extension/artifacts. A section an extension refuses switches off that extension alone, and a
section no extension in the build owns is ignored; the board's ? key map and each session's MCP
instructions say which and why. A disabled extension that has a say in
which sessions spawn fails closed: every spawn it would have been asked about is refused, with the
reason, until its section is fixed.
go build -o gate-inbox .
scripts/ci-test.sh # the test suite exactly as CI runs itCONTRIBUTING.md covers sending a change, and SECURITY.md how
to report a vulnerability privately. The recordings above come from tools/demo/record.sh, which
drives vhs against a throwaway board whose sessions run a
scripted stand-in CLI, so no model or account is involved.
Apache-2.0. Gate Inbox is derived from an Apache-2.0 upstream project, where its
session model, tmux passthrough and TUI began. NOTICE names that project, its authors
and the commit this fork started from. LICENSES/MODIFIED-FILES.txt
lists the files changed since, and LICENSES/THIRD-PARTY.md covers
third-party licences.
Quit. q quits the board. Its agents keep running in tmux as gi_<id> sessions and are
picked back up next time.
Stop every agent. gate-inbox park ends every live agent the board started and records the
set. It runs from any shell, and --dry-run prints the plan first. gate-inbox unpark brings
the same sessions back on their conversations. A single one: gate-inbox kill <id>, with the id
from gate-inbox sessions. From inside a managed agent session, gate-inbox stop ends that
session and preserves its row and conversation for an explicit revive. It records an intentional
stop, so startup recovery does not offer it as a lost session. gate-inbox stop --dry-run
verifies the current pane without ending it. Adopted callers with verified pane process ancestry can also stop themselves.
Shared-daemon callers whose pane cannot be verified refuse shutdown. Other adopted panes can be stopped by id from
another session or the board.
Carry on in the plain CLI. In a focused session, alt+y copies the agent's own conversation
id. From that session's working directory:
| CLI | Resume |
|---|---|
| Claude Code | claude --resume <id> |
| Codex | codex resume <id> |
| OpenCode | opencode --session <id> |
Without an id, Claude Code and Codex open their own session picker (claude --resume,
codex resume) so you choose the conversation, and opencode --continue picks up the
directory's most recent one.
Uninstall.
gate-inbox park, then quit the board withq.- Remove the binary:
rm "$(command -v gate-inbox)". - Remove the config and state directory. That's
$GATE_INBOX_HOMEif you set it, otherwise~/.config/gate-inboxon Linux ($XDG_CONFIG_HOME/gate-inboxif that's set) and~/Library/Application Support/gate-inboxon macOS. It holdsconfig.toml,state.db, the log, key bindings, snippets, hook and MCP registration files, and a copy of the binary underbin/. - Remove the launch scripts and pasted images it left in your temp directory:
rm -f "${TMPDIR:-/tmp}"/gi-launch-*.shandrm -rf "${TMPDIR:-/tmp}/gate-inbox-pastes". - Undo the tmux key bindings it added (
ctrl+qandctrl+\, plusalt+ofrom older releases, which act only insidegi_*sessions):tmux unbind-key -n C-q \; unbind-key -n 'C-\' \; unbind-key -n M-o, or restart tmux. If the board didn't exit cleanly,tmux kill-session -t gi_poll-anchorremoves its helper session. If you gave it a private tmux socket,tmux -L <name> kill-serverdoes all of this at once.
Gate Inbox writes nothing to your agent CLIs' own configuration. It hands each session its MCP
server and hooks on the command line. The one exception is migrate, which leaves a
*.handover.jsonl file next to the transcript it moved, under ~/.claude/projects or
~/.codex/sessions.
Gate Inbox is derived from agent-manager, licensed
under Apache-2.0. Thank you to Yoan Wai and the agent-manager contributors for the session model,
tmux passthrough and TUI this project grew from. NOTICE carries the attribution and
the upstream commit this fork started from.


