Claude Code Guide

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.

View the Project on GitHub ytrofr/claude-code-guide

Monitor Tool — Streaming Background Process Events

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.


What it does

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"

Monitor vs ScheduleWakeup — decision matrix

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.


Usage patterns

Build watching

1. Start build in background
2. Monitor the task to stream compiler output
3. React when build succeeds or fails

Deploy streaming

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

Long database operations

1. Start migration in background
2. Monitor for per-table progress
3. React if an error line appears

File tailing (wrap tail -F)

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")

Inter-agent bus streaming

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.


Anti-patterns


Interaction with ScheduleWakeup and cache windows

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.


Combining Monitor with inter-project coordination

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'

OTEL interaction

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.


See also


Last updated: 2026-04-20. Compatible with Claude Code 2.1.111+.