Sidebar-first AI agent session manager for tmux. It gives each tmux session a persistent status sidebar, keeps a compact summary in the status line, and adds a hierarchical fzf target switcher for fast jumps and cleanup across agent sessions, windows, and panes.
Claude Code and Codex CLI are both integrated through hooks, so their states come from agent lifecycle events rather than fragile process polling. Custom agents can still integrate through status files or collector extensions.
Demo video: demo/full.mp4
- Persistent sidebar in every tmux session
- Hierarchical
fzftarget switcher for quick jumps and close actions - Hook-based Claude Code and Codex tracking
- Wait and park modes for triaging work
- Compact status-line summary with finish notifications
- Works across multi-pane sessions, worktrees, and remote tmux sessions
| Agent | Integration | Status |
|---|---|---|
| Claude Code | Hook-based via hooks/better-hook.sh |
Stable |
| Codex CLI | Hook-based via hooks/codex-hook.sh |
Stable in plugin, hooks still experimental upstream |
| Custom (Aider, Cline, Copilot CLI, etc.) | Status files or collector extensions | Stable |
All agent sessions can run simultaneously across tmux sessions and panes, each tracked independently.
With TPM:
set -g @plugin 'samleeney/tmux-agent-status'Then press prefix + I to install.
On macOS, install a modern Bash before using the sidebar:
brew install bashThe plugin auto-detects Homebrew Bash at /opt/homebrew/bin/bash or /usr/local/bin/bash when macOS launches scripts with the system Bash 3.2.
If Bash is installed somewhere else, set TMUX_AGENT_STATUS_BASH to that path.
By default the plugin:
- Appends the live summary to
status-right - Starts the sidebar collector daemon
- Auto-creates a sidebar in existing and new tmux sessions
- Binds the popup switcher, wait, park, and next-ready actions
Add hooks to ~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "~/.config/tmux/plugins/tmux-agent-status/hooks/better-hook.sh UserPromptSubmit"
}
]
}
],
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "~/.config/tmux/plugins/tmux-agent-status/hooks/better-hook.sh PreToolUse"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "~/.config/tmux/plugins/tmux-agent-status/hooks/better-hook.sh Stop"
}
]
}
],
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "~/.config/tmux/plugins/tmux-agent-status/hooks/better-hook.sh Notification"
}
]
}
]
}
}Claude Code state is tracked entirely through hooks, so the plugin gets precise working/done transitions directly from the agent. If a turn ends while a background task is still running (e.g. a run_in_background Bash command), the Stop payload's background_tasks array keeps the session marked working until a later Stop reports the task finished — so backgrounded work doesn't show a premature green checkmark.
tmux-agent-status supports official Codex hooks.
Enable hooks in ~/.codex/config.toml:
[features]
hooks = trueFor a one-off session, you can also start Codex with codex --enable hooks.
To enable Codex tracking globally, add ~/.codex/hooks.json:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "bash ~/.config/tmux/plugins/tmux-agent-status/hooks/codex-hook.sh SessionStart"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "bash ~/.config/tmux/plugins/tmux-agent-status/hooks/codex-hook.sh UserPromptSubmit"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/.config/tmux/plugins/tmux-agent-status/hooks/codex-hook.sh PreToolUse"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "bash ~/.config/tmux/plugins/tmux-agent-status/hooks/codex-hook.sh Stop"
}
]
}
]
}
}Restart Codex, then run /hooks in the CLI and trust the new command hooks if Codex marks them as pending review. Non-managed command hooks must be trusted before Codex will run them.
Codex state is also hook-based. The handler marks the tmux session or pane working on UserPromptSubmit and PreToolUse, resets it to done on Stop, and seeds resumed sessions on SessionStart.
For repo-local tracking while working on this plugin, put the same hook shape in <repo>/.codex/hooks.json. Codex loads project-local hooks once the project .codex/ layer is trusted.
Integrate any AI coding tool with either of these approaches:
- Write
working,done, orwaitto~/.cache/tmux-agent-status/<session>.status - For pane-level parking or per-pane state, write to
~/.cache/tmux-agent-status/panes/<session>_<pane>.statusand~/.cache/tmux-agent-status/parked/<session>_<pane>.parked - Extend the collector scan in
scripts/lib/collect.shif you want automatic process-based tracking
Default mode is sidebar-first:
- Every tmux session gets a sidebar pane automatically
prefix + Sopens the hierarchicalfzftarget switcherprefix + ofocuses or creates the sidebar in the current window
| Key | Action |
|---|---|
prefix + S |
Open the hierarchical fzf target switcher |
prefix + o |
Focus or create the sidebar |
prefix + N |
Jump to the next inbox item in inbox order |
prefix + W |
Put the current session or pane into timed wait mode |
prefix + p |
Park the current session or pane for later |
The status bar shows live activity:
⚡ agent working⚡ 3 working ⏸ 1 waiting ✓ 2 done✓ All agents ready
Parked sessions stay visible in the sidebar and switcher, but are excluded from the status-line summary.
Inside the popup switcher:
Enterswitches to the selected session, window, or paneTabexpands or collapses the selected session or windowCtrl-Xcloses the selected pane immediatelyCtrl-Xon a window closes that window and all child panes after confirmationCtrl-Xon a session closes that session and all child windows and panes after confirmationCtrl-Pparks or unparks the selected session, window, or paneCtrl-Wopens wait mode for the selected target, or cancels an existing waitCtrl-Rresets tracked state
Inside the sidebar:
x,p, andwperform the same close, park, and wait actions without interfering with popup search input
prefix + N follows the same top-to-bottom order as the INBOX section. The inbox is ordered by session name, then by tmux window order within each session.
Parking, waiting, and closing always apply to the selected scope only:
- selecting a session row affects the whole session
- selecting a window row affects only that window
- selecting a pane row affects only that pane
In multi-window sessions, sidebar and inbox rows labeled with a window name operate on that window, not just the first pane inside it.
set -g @agent-status-key "S"
set -g @agent-sidebar-key "o"
set -g @agent-next-done-key "N"
set -g @agent-wait-key "W"
set -g @agent-park-key "p"
set -g @agent-switcher-style "both" # popup | sidebar | both
set -g @agent-status-display-method "popup" # popup | window
set -g @agent-sidebar-width "42"@agent-switcher-style "both" is the default. It keeps the persistent sidebar and leaves prefix + S as the lightweight popup switcher.
Play a sound when an agent finishes:
set -g @agent-notification-sound "chime"Options: chime (default), bell, fanfare, frog, speech, none.
Launch parallel AI coding sessions with isolated git worktrees:
bash ~/.config/tmux/plugins/tmux-agent-status/scripts/deploy-sessions.sh manifest.jsonEach session gets a deploy/<name> branch, and the plugin tracks the spawned sessions automatically.
Monitor AI agents on remote machines:
./setup-server.sh <session-name> <ssh-host>Works with cloud VMs, GPU boxes, and any SSH-accessible tmux host.
┌──────────────┐ hooks ┌──────────────────────────┐
│ Claude Code ├─────────────►│ ~/.cache/tmux-agent- │
└──────────────┘ │ status/ │
│ <session>.status │
┌──────────────┐ hooks │ panes/*.status │
│ Codex CLI ├─────────────►│ wait/*.wait │
└──────────────┘ │ parked/*.parked │
└─────────────┬────────────┘
┌──────────────┐ status files │
│ Custom agent ├────────────────────────────┘
└──────────────┘
▼
┌──────────────────────────┐
│ sidebar-collector.sh │
│ writes shared cache and │
│ status summary │
└─────────────┬────────────┘
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ sidebar pane │ │ status line │ │ fzf switcher │
└──────────────┘ └──────────────┘ └──────────────┘
- Claude Code support is hook-based
- Codex CLI support is hook-based
- Custom agents can be file-based or process-detected
- The sidebar is the main live view; the
fzfswitcher is the quick jump and close tool
MIT
