The complete guide to Claude Code. Opus 4.7, Sonnet 4.6, Haiku 4.5. 1M token context window. 27 hook events. 43 production-tested chapters across 6 topical Parts (Foundation, Workflow, Extension, Context Engineering, Advanced, Reference). Three install tiers. CC 2.1.121+ compatible.
Added in: Claude Code 2.1.98. Current as of 2.1.111+.
The Monitor tool streams events from background scripts. Each stdout line from the monitored process becomes a notification event in your conversation.
When you start a background process with Bash(run_in_background: true), the process runs detached. Previously, you had to periodically Read the output file to check progress. Monitor changes this — it attaches to the background process and streams each stdout line as an event.
User: "Build my project and let me know when it's done"
1. Bash(run_in_background: true): npm run build
→ Returns task_id: "abc123"
2. Monitor(task_id: "abc123")
→ Streams: "Compiling TypeScript..."
→ Streams: "Building 47 modules..."
→ Streams: "Build complete in 34s"
| Scenario | Use | Why |
|---|---|---|
| Tailing build/deploy logs | Monitor | Each stdout line = notification |
| Waiting for long test to finish | Monitor | Notified on process exit |
| Watching streaming fetch output | Monitor | Observable progress lines |
| Log tailing for another process | Monitor | Wrap with tail -F <file> |
| Inter-agent bus live stream | Monitor | tail -F log.jsonl \| jq filter |
| “Check back in 30 min” | ScheduleWakeup | No process to attach to |
| Rate-limit backoff retry | ScheduleWakeup | Time-delayed, cache-window aware |
/loop skill patterns |
ScheduleWakeup | User-approved dynamic pacing |
| Idle loop, no signal to watch | ScheduleWakeup | Default to 1200-1800s delay |
Key difference: Monitor is event-driven (something is producing stdout). ScheduleWakeup is time-driven (you want to check later). They solve different problems — don’t substitute one for the other.
1. Start build in background
2. Monitor the task to stream compiler output
3. React when build succeeds or fails
1. Start deploy script in background (gcloud run deploy, vercel deploy, fly deploy)
2. Monitor for deployment progress, URL assignment, health check results
3. Proceed when "Service is live" appears
1. Start migration in background
2. Monitor for per-table progress
3. React if an error line appears
Monitor streams stdout, not file changes. To watch a log file, wrap it:
Bash(run_in_background: true): tail -F /var/log/app.log
→ task_id: "xyz789"
Monitor(task_id: "xyz789")
When coordinating with another Claude session across projects (see Inter-agent bus), use the canonical wrapper. It tails the shared event log filtered by (.to == me OR .to == base) AND .from != me AND .kind == "msg" — multi-thread safe, self-filtered:
Monitor(
command: "$HOME/shared/inter-agent/bin/talk.sh listen-incoming",
description: "inter-agent bus incoming (all threads, self-filtered)",
persistent: true,
timeout_ms: 3600000
)
Each new incoming message fires as a notification regardless of which thread it lands on. Self-sends are filtered out so you never wake on your own outbound. The session’s identity is auto-resolved via talk.sh.
Don’t roll your own filter without .from != $me — the recipient to == me clause alone matches messages where you also appear in from (broadcast to base, self-tag, threading-system writes), causing the session to wake on its own work. Don’t tail a single thread file (coord-X-Y.md) — that watches one thread, missing messages on other threads where you’re a participant.
tail -F as the background command (see above).command | grep -E 'ERROR|WARN|COMPLETE'.tail -F.ps -ef \| grep -E "<your filter pattern>" \| grep -v grep. No match → re-arm. Bake liveness checks into the wake-on-event design, don’t trust auxiliary indicators.ScheduleWakeup durations under 270s keep the prompt cache warm (5-minute TTL). Durations at exactly 300s are the worst: cache miss without meaningful wait benefit.
Monitor doesn’t interact with cache scheduling at all — it’s event-driven. Use it when you have stdout to stream, not to optimize cache windows.
Monitor is what makes the inter-agent bus feel live: one side posts to log.jsonl, the other side’s Monitor filter surfaces it as a notification within ~100ms of the write. Without Monitor, the pattern degrades to “check /talk list periodically” — workable but not responsive.
Similar pairings:
| Pipeline | Monitor target |
|---|---|
| Self-telemetry (this chapter) | Nothing — telemetry hooks are fire-and-forget, no polling needed |
| Inter-agent bus | talk.sh listen-incoming (canonical wrapper; raw tail -F log.jsonl \| jq only with .from != $me) |
| CI/CD watch | tail -F <pipeline-log> or attach to deploy task |
| Remote log tail | ssh host 'tail -F /var/log/app.log' |
Monitor runs at the hook/tool layer and does not emit OTEL spans itself. If you’re running a local OTLP collector (see Self-telemetry §15), Monitor events won’t show up in Honeycomb/Jaeger — they’re a conversation-level UI primitive, not an API-level request.
The background Bash process inside Monitor may emit OTEL if it’s a subprocess of a CC turn (2.1.98+ auto-propagates TRACEPARENT). But Monitor’s own “stdout line → notification” step is not traced.
Last updated: 2026-04-20. Compatible with Claude Code 2.1.111+.