Agent Status Indicators
Real-time visual indicators showing what AI agents are doing across workspaces.
Agent Status Indicators
Codemux tracks the state of AI agents running in your terminals and shows real-time status indicators in the sidebar and tab bar. This lets you monitor multiple agents across workspaces at a glance.
Status States
| State | Color | Animation | Meaning |
|---|---|---|---|
| Idle | Hidden | None | Agent is not running or has no pending activity |
| Working | Amber | Pulsing dot + activity orb (sidebar) | Agent is actively processing |
| Permission | Red | Pulsing dot | Agent needs user input or approval |
| Review | Green | Static dot | Agent finished work, ready for your review |
| Monitoring | Cyan | None — a steady dot | Agent finished its deliverable but is still watching something (a CI run, a tailed process, a PR poll) |
Priority runs Permission > Working > Monitoring > Review > Idle. If any pane in a workspace needs input, the workspace indicator shows red regardless of what other panes are doing.
Monitoring
Monitoring is the state for an agent that is done with its deliverable but has not stopped — it is babysitting a CI run, tailing a process, or polling a pull request. Before this state existed, such an agent stayed pinned at Working indefinitely, which made a watch loop indistinguishable from real work in progress.
It is deliberately calm. The dot is a steady cyan with no pulse and no spinner, monitoring cards recede in the sidebar like quietly-working ones, and a monitoring workspace never raises the "Needs you" strip.
Monitoring does not hold a turn open. The turn still settles on schedule and a detached agent browser is still released. A live monitor only changes which settled status is displayed — the moment the last monitor ends, the pane falls back to the Review or Idle it would otherwise have shown.
Because it describes a live process rather than finished work, it behaves differently from Review in two ways: it is not persisted (it does not survive a restart, exactly like Working and Permission), and it is not cleared just because you looked at the pane.
Unlike Working and Permission, monitoring workspaces can still be settled and snoozed.
Two ways a pane enters Monitoring
Automatically, with Claude. Claude's SDK reports a task type for the work it launches. Codemux classifies a closed set of them — monitor, monitor_mcp, local_bash, shell — as watch loops. Everything else stays ordinary agent work, and an agent that reports no task type at all behaves exactly as it did before.
Manually, with any provider. An agent with a shell can declare its own watch loop:
codemux monitor start --reason "watching CI for PR #248"
codemux monitor status
codemux monitor stopThe common call takes no arguments — it reads the pane and workspace out of the environment Codemux injects into every agent it launches. This works for terminal agents, Codex, and OpenCode, not just Claude. See the CLI reference.
The Monitoring bar
While a pane is monitoring, a bar appears between the transcript and the composer carrying the reason (if one was given) and a Stop button.
Stop clears Codemux's monitor state, clears any manual flag, and makes a best-effort attempt to interrupt the session. One honest limitation: the interrupt is a turn interrupt, and by the time you see the monitoring badge the turn has usually already settled — at that point the provider offers no way to interrupt an idle session, so a genuinely detached background process can survive Stop. Codemux clears its own state regardless, rather than leave you a dot you cannot dismiss.
Stop is durable: a stopped watch loop is blocked from re-lighting the badge until the next turn boundary.
Two things worth knowing about manual flags: they are per pane, not per agent (two agents sharing a pane share one flag), and nothing polls the claiming process for liveness — a flag set by an agent that then crashes survives until codemux monitor stop, the pane closes, or the app restarts.
Where it shows
The cyan dot appears on the sidebar inbox card, the collapsed rail, the workspace hover card, the tab dot, command palette rows, and the Workspaces overview. One current gap: a settled or snoozed sidebar row shows the dot but no "Monitoring" label line.
A watch loop keeps its card in the transcript but is deliberately left out of the docked subagent activity bar — it is not a subagent doing work.
Where Indicators Appear
Sidebar Workspace Icons
Each workspace in the sidebar shows an aggregate status across all its panes:
- Working — the card's right-hand cluster shows an activity orb plus the word "Working" in amber. The project avatar is never replaced. Sidebar orbs are always the neutral working orb, because the sidebar's status feed carries no tool detail
- Permission / Review — the same right-hand cluster shows a pulsing red dot with "Needs you", or a green check with "Done · review". (The dot-over-the-avatar rendering now applies only to the collapsed rail, where the working dot is static rather than pulsing)
The highest-priority status across all panes wins.
Terminal Tab Headers
Each tab shows the highest-priority status from its panes as a small colored dot next to the tab name.
Terminal Pane Headers
Individual panes show their own status dot in the pane title bar when not idle.
How It Works
Codemux uses a hook-based system to receive terminal-agent lifecycle events:
- On startup, Codemux starts a local HTTP server on a random port (
127.0.0.1:<port>) - Hook registration — Codemux installs entries, plugins, or extensions in each supported agent's own config directory
- During agent work, the agent fires lifecycle events (prompt submitted, tool used, permission needed, work complete)
- The hook script (
~/.codemux/hooks/notify.sh) sends an HTTP request to Codemux's hook server with the event type and session ID - Codemux maps the event to a pane status and updates the UI in real-time
Event Mapping
| Representative events | Status |
|---|---|
UserPromptSubmit, Start, PostToolUse, BeforeAgent | Working |
PermissionRequest, Notification, permission.ask | Permission |
Stop, AfterAgent, agent-turn-complete | Review (or Idle if you're looking at the pane) |
Smart Idle Detection
When an agent finishes (Stop event), Codemux checks whether you're currently viewing that pane:
- Active pane in active workspace — Status clears to Idle (you're already looking at it)
- Background pane or workspace — Status stays as Review until you click on that tab
Supported Agents
- Claude Code — hooks in
~/.claude/settings.json; includes needs-input status and session-ID capture for resume - Codex — hooks in
~/.codex/hooks.json; includes working, review, and needs-input states - Gemini — hooks in
~/.gemini/settings.json; includes working, review, and needs-input states - OpenCode — a Codemux plugin tracks session activity and permission prompts
- Pi — a Codemux extension tracks working and review states; Pi exposes no distinct needs-input event
Codex, Gemini, OpenCode, and Pi integration is installed only when that agent's config directory already exists. Their terminal hooks are Unix-only today; Claude also has a PowerShell notifier on Windows.
Agent Chat
The hook system above is for agents running in a terminal. Agent Chat panes light the same sidebar, tab, and pane indicators directly from the session's own event stream — no hooks required — for every chat provider (Claude, Codex, Cursor, OpenCode), since status is derived from the shared provider event stream rather than anything provider-specific. Streaming maps to Working, a pending approval / plan / question to Permission, and a finished turn to Review (with the same "already looking at it" idle downgrade).
A background command no longer holds the run open. An agent that launched a long-lived background shell command — a dev server, a watcher — used to keep the sidebar spinner, the browser LIVE chip, the subagent activity bar, and the composer's task counter alive indefinitely after the turn had actually finished, because such a process never exits and so never reports completion. Background commands are now tracked separately from real subagents and cannot defer a turn's settlement. As a backstop, a review owed by a thread that has gone completely silent for ten minutes is force-settled; that path is deliberately non-destructive and will not tear down a browser you are watching.
Hook Safety
The hook integrations Codemux installs are designed to leave the agent's other configuration untouched:
- The notification script checks for
CODEMUX_HOOK_PORTandCODEMUX_SESSION_IDenvironment variables before doing anything - Persistent terminals survive an app restart with their old environment. If the inherited hook port is stale, the script automatically retries the current port published at
~/.codemux/hooks/active-port. - If Codemux isn't running, the hook silently exits (no errors, no side effects)
- Hook requests use a 1-second connect timeout and 2-second max time
- Codemux preserves any existing hooks from other tools — it only adds/updates its own entries
Troubleshooting
If status indicators aren't working:
- Check the agent's config for Codemux hooks (
~/.claude/settings.json,~/.codex/hooks.json, or~/.gemini/settings.json), or the installed OpenCode/Pi integration. - Check that
~/.codemux/hooks/notify.shexists and is executable. - If the agent survived an app restart, check that
~/.codemux/hooks/active-portexists; the notifier uses it to recover from the old inherited port. - Restart Codemux — hooks are registered on startup.