Skip to content

Repository files navigation

ccmon — claude code monitor

ccmon screenshot

Interactive TUI for active Claude Code agents and subagents. Two-pane picker: list on the left, live-tailing transcript preview on the right. Select one and a new terminal tab opens with a live viewer of that session — for tmux-backed sessions you actually attach and can drive it.

What it shows

Walks ~/.claude/projects/ and lists:

  • agent — top-level sessions (<project>/<session>.jsonl)
  • subagent — Task-tool subagent runs (<project>/<session>/subagents/agent-*.jsonl)

Sorted live → running → others, newest first within each group. Default age cutoff is 6h (override with CCMON_MAX_AGE_HOURS). The list re-scans every couple of seconds while open, so agents started after launch show up without a restart (your selection, filter, and preview scroll position are kept).

Swarm teammates (from claude-swarm / agent teams) are detected too, and each row is labelled with its teammate name so you can tell them apart.

Usage

ccmon                  # interactive TUI picker
ccmon --list           # plain-text list, non-interactive
ccmon spawn [PATH]     # launch claude in a new Ghostty window wrapped in a named tmux session

TUI keys

key action
/ / PgUp / PgDn move selection
type letters filter list (summary + project + agent-type + teammate/team name)
delete filter char
enter attach to selected (tmux attach for live, transcript tailer otherwise)
esc / q / ctrl-c quit

Picker behavior

Each entry has one of three states, detected by scanning ps for running claude processes and cross-referencing their TTY with tmux list-panes across every tmux socket (the default server plus any named -L sockets, which is where claude-swarm runs each swarm). Normal sessions are matched by --session-id <UUID>; swarm teammates (which carry --agent-name/--team-name instead) are matched by their transcript's agentName/teamName:

  • ● live — running claude process whose TTY is a tmux pane. Selecting splits the current terminal pane (sends Cmd+D) and runs tmux attach -t <session> (tmux -L <socket> attach … for a swarm socket) — a real attach: typing drives the same claude.
  • ○ running — running claude process not inside tmux. Selecting splits the current pane and opens the transcript tailer (read-only — you can see what it's doing live, but there's no PTY to attach to since it was spawned in a raw terminal).
  • · stale — historical session; transcript tailer only.

Making agents attachable

If you launch claude directly in Ghostty, it's ○ running but not attachable. To make it real-attachable, launch it inside tmux. The ccmon spawn helper does this for you:

cd ~/repos/job-search-app
ccmon spawn               # opens new Ghostty: `tmux new-session -s claude-job-search-app claude`

You can also just use plain tmux — any naming convention works since detection is by PID+TTY, not by session name. Sessions on any tmux socket are found, so claude-swarm teammates are attachable the same way (via their swarm's -L socket).

Install

Homebrew (recommended)

brew install adamclark64/tap/ccmon

(Requires the adamclark64/homebrew-tap tap; the formula in homebrew/ccmon.rb is auto-updated on every release.)

From crates.io

cargo install ccmon

From source

cargo install --path .

Runtime deps

  • jq (used by the transcript viewer; degrades to raw tail -f if absent)
  • tmux (required for live attach)
  • macOS Accessibility permission for your terminal app (so ccmon can send Cmd+D to split the pane). First run will silently fail to split if permission isn't granted — ccmon prints the manual command as fallback. Grant via System Settings → Privacy & Security → Accessibility → enable your terminal (Ghostty, iTerm, etc).
  • Any terminal that maps Cmd+D to "split right" (Ghostty default, iTerm2 default, Warp default).

About

TUI monitor for Claude Code agents & subagents — list, watch, and attach

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages