Live monitoring for Claude Code sessions and their background tasks (background shells, subagents, workflows) — a single static Go binary with a web panel and a TUI. IDE- and harness-independent: it reads Claude Code's official hook events and on-disk state, and never slows down or breaks a session.
Outside the Claude Desktop app, Claude Code gives no visual surface for the
background work happening inside a session. ccmon reconstructs that view
from Claude Code's official hooks plus on-disk transcripts, so you can watch
every session on your machine — and the tasks inside it — from a browser or a
terminal.
Claude Code hooks call ccmon emit on every event; emit appends a generic
JSON line to an append-only spool (~/.ccmon/events/YYYY-MM-DD.jsonl). A pure
reducer derives session/task state from those events. ccmon serve (HTTP +
SSE + embedded panel) and ccmon tui both consume the same core. When serve
is running, emit sends it a 100 ms best-effort nudge for near-instant
updates; otherwise fsnotify picks up changes within a few seconds. Nothing is
lost if no component is running — the spool is the source of truth. See the
full design in docs/superpowers/specs/2026-07-17-ccmon-design.md.
Requires Go 1.22+.
go install github.com/BahtiyarB/ccmon/cmd/ccmon@latestThis drops ccmon (or ccmon.exe on Windows) into $(go env GOPATH)\bin.
Make sure that directory is on your PATH. To build from source instead:
git clone https://github.com/BahtiyarB/ccmon
cd ccmon
go build -o ccmon ./cmd/ccmonThree commands:
ccmon install # add the hooks to ~/.claude/settings.json (backs up + idempotent)
ccmon doctor # verify: binary, hooks, spool, ~/.claude — every line should be OK
ccmon serve # start the panel on 127.0.0.1:<auto-port>, then open it in a browserPrefer the terminal? Run ccmon tui instead of ccmon serve — it needs no
server. Start a Claude Code session in any terminal or IDE and watch its
sessions and background tasks appear live.
Note: ccmon doctor exits 0 once the five core checks pass (binary, hooks,
spool writable, ~/.claude, spool integrity). The "serve running" line is
informational: while ccmon serve is down it prints as i (info), not ✗,
and never affects the exit code — so a clean install reports success even
before you start the panel.
Upgrading? Re-run ccmon install after updating the binary. It is idempotent
and refreshes the hook set in place — new releases can add hooks (e.g. Workflow
run tracking) that an older install did not register.
Run ccmon serve and open the printed URL to see the live panel.
Background tasks show up in the panel within the design targets — ≤2 s on
the nudge path (server running) and ≤5 s on the fsnotify path — and emit
runs within its ~200 ms budget while always exiting 0, so it never delays a
Claude Code session. A fixture-driven local run measured 510 ms nudge-path,
311 ms fsnotify-path, and a 191 ms emit median (all within target); see
docs/smoke-2026-07-17.md for the full transcript.
| Key | Action |
|---|---|
↑/↓ (or k/j) |
Navigate tasks |
Enter |
Focus / expand |
Tab |
Toggle running ↔ finished list |
s |
Toggle the session-grouped view |
o |
Open the selected task's output in your editor |
q / Ctrl+C |
Quit |
Ctrl+Bbackground gap: backgrounding a running shell withCtrl+Bhas no instant hook, so aPreToolUse(Bash)whosePostToolUsenever arrives stays shown as a running shell (this is the correct, honest behavior).- Transcript enrichment is best-effort: the
~/.claude/projects/*.jsonlschema is not an official contract; if it changes, only title/model enrichment is lost — hook-based monitoring is unaffected. - Workflow hooks depend on Claude Code version:
TaskCreated/TaskCompletedmapping targets Claude Code 2.1.201; older/newer versions may differ. - Read-only, localhost-only: v1 monitors only (no stop/kill), binds only to
127.0.0.1, and has no auth. - Pre-v1.3 subagent records have no names/badges: subagent events recorded
before v1.3 carry no
output_ref, so their transcript cannot be located — those tasks get no derived name, token/tool counts, or ghost-idle badge. They are not backfilled and age out naturally under the 7-day spool retention; sessions recorded from v1.3 on are unaffected. Deriving task identity from the hooktool_use_id(rather thanoutput_ref) would close this gap and is a possible v2 change — documented here, not implemented.
ccmon uninstallRemoves only the entries ccmon install added; every other hook in your
settings.json is left byte-for-byte intact. The .bak backup taken at first
install is left in place.
MIT — see LICENSE.