Skip to content

Navigation Menu

Sign in
Sign up

Daemon Guide

ops-release edited this page Sep 9, 2026 · 72 revisions

Daemon Guide

The background engine that keeps claude-ops fast.

Version Manager Services Pre-warm

Note

ops-daemon is a single launchd-managed process that supervises seven sub-services. It replaced per-service launchd agents in v0.5.0, then gained briefing-pre-warm (v0.6.0) and early-install (v0.8.0).


What the daemon does

flowchart LR
 D[ops-daemon] --> B[briefing-pre-warm<br/>every 2 min]
 D --> W[wacli-sync<br/>continuous]
 D --> M[memory-extractor<br/>every 30 min]
 D --> I[inbox-digest<br/>every 4 hours]
 D --> S[store-health<br/>daily 9am]
 D --> C[competitor-intel<br/>weekly Mon 10am]
 D --> L[message-listener<br/>continuous]
 B --> BC[daemon-cache.json]
 W --> WH[~/.wacli/.health]
 M --> ME[memories/]
 I --> IL[inbox log]
 S --> SR[store-health report]
 C --> CR[competitor report]
 L --> LL[message log]
 classDef svc fill:#6366f1,color:#fff,stroke:#4338ca
 classDef out fill:#22c55e,color:#fff,stroke:#15803d
 classDef root fill:#8b5cf6,color:#fff,stroke:#6d28d9
 class D root
 class B,W,M,I,S,C,L svc
 class BC,WH,ME,IL,SR,CR,LL out
Loading
Service Cadence Purpose
briefing-pre-warm every 2 min Runs bin/ops-gather and caches dashboard data for /ops:go
wacli-sync continuous Keeps WhatsApp Web connection alive, auto-backfills @lid chats
memory-extractor every 30 min Haiku 4.5 summarizes new wacli + gog data into memories/
inbox-digest every 4 hours Ranks unread messages across channels, writes digest
store-health daily at 09:00 Shopify inventory / order / fulfillment sanity check
competitor-intel weekly Mon 10:00 Scrapes competitor signals, writes weekly brief
message-listener continuous Polls wacli/Telegram for new messages, writes to local event log

Important

All services are local-only. message-listener never sends messages outbound on its own — it only writes to a log that the daemon reads. See Privacy and Security for the exact list of network targets.


Early install strategy (v0.8.0)

Pre-v0.8.0 the daemon was installed at Step 5b — after channels, MCPs, and registry. That meant users waited ~10s for their first /ops:go because the cache was empty.

v0.8.0 moved daemon install to Step 2c, immediately after CLIs. The briefing-pre-warm service starts working the moment the plist loads, and continues to warm the cache while the rest of the setup wizard runs.

sequenceDiagram
 autonumber
 participant U as User
 participant W as Setup Wizard
 participant D as ops-daemon
 participant G as ops-gather
 participant C as /ops:go
 U->>W: /ops:setup
 W->>W: Step 1 · Pick sections
 W->>W: Step 2 · Install CLIs
 W->>D: Step 2c · Install daemon (early!)
 activate D
 D->>G: briefing-pre-warm tick #1
 G-->>D: registry, PRs, CI, unread, revenue...
 Note over W,D: Wizard continues in parallel
 W->>W: Step 3 · Configure channels (60–180s)
 D->>G: briefing-pre-warm tick #2 (+2 min)
 W->>W: Step 4 · MCPs · 5 · Registry · 6 · Prefs
 D->>G: briefing-pre-warm tick #N
 W->>W: Step 5b · Reconcile daemon services
 W-->>U: Setup complete
 U->>C: /ops:go
 C->>D: read daemon-cache.json
 D-->>C: cached data (<3s)
 deactivate D
Loading

Tip

By the time the wizard finishes, the cache has 3–8 warm-up cycles banked. /ops:go loads from cache in under 3 seconds instead of cold-gathering in 10+.


Health file contract

Two health files, one per concern.

~/.wacli/.health

Written by wacli-sync on every successful poll.

{
 "status": "ok",
 "last_sync": "2026年04月14日T07:45:00Z",
 "wacli_pid": 12345,
 "message_count": 1420
}
Field Meaning
status ok · degraded · down
last_sync ISO timestamp of last successful WhatsApp poll
wacli_pid PID of the running wacli process
message_count Total messages in local SQLite DB

daemon-health.json

Written by the supervisor. Lives at ~/.claude/plugins/data/ops-ops-marketplace/daemon-health.json.

{
 "supervisor_pid": 54321,
 "uptime_seconds": 87442,
 "services": {
 "briefing-pre-warm": { "status": "ok", "last_run": "2026年04月14日T07:44:12Z" },
 "wacli-sync": { "status": "ok", "last_run": "2026年04月14日T07:45:00Z" },
 "memory-extractor": { "status": "ok", "last_run": "2026年04月14日T07:30:04Z" },
 "inbox-digest": { "status": "ok", "last_run": "2026年04月14日T04:00:00Z" },
 "store-health": { "status": "ok", "last_run": "2026年04月14日T09:00:00Z" },
 "competitor-intel": { "status": "idle", "next_run": "2026年04月21日T10:00:00Z" },
 "message-listener": { "status": "ok", "last_event": "2026年04月14日T07:44:58Z" }
 }
}

PreToolUse hook — ops-pretool-wacli-health

hooks/whatsapp-health-check.sh (registered in hooks.json) fires before any wacli command. It reads ~/.wacli/.health and:

Condition Behavior
status === "ok" AND last_sync < 10 min Proceeds silently
status === "degraded" OR last_sync >= 10 min Surfaces warning + restart instructions
Health file missing Surfaces "daemon not running" + install instructions

Warning

The hook fails closed. Skills warn instead of silently retrying with stale auth. This is intentional — per Rule 3 and the privacy policy, users must see every health regression rather than get misleading "no new messages" results.


Brain layer · briefing cache

bin/ops-brain runs inside briefing-pre-warm. Every 2 minutes it:

  1. Calls bin/ops-gather — which probes registry projects, GitHub PRs, CI, AWS ECS, Shopify, Klaviyo, Meta Ads, unread counts, GSD phases
  2. Writes the result to daemon-cache.json
  3. Detects urgent patterns (your name mentions, "urgent", "ASAP", "fire", "down", "broken") in unread messages
  4. Flips the urgent_flag in daemon-health.json so /ops:go can surface them instantly

Result: /ops:go reads one cached JSON file instead of spawning 8 parallel gather scripts.


Service reconciliation (Step 5b)

After channels + registry are configured, Step 5b reconciles the daemon:

  • Adds wacli-sync if WhatsApp is configured
  • Adds message-listener if WhatsApp OR Telegram is configured
  • Adds inbox-digest if >=2 channels are configured
  • Adds store-health if Shopify is configured
  • Adds competitor-intel if /ops:marketing is selected
  • Verifies all services launch, prints a green-check summary

Because the daemon was installed at Step 2c with a minimal service list, Step 5b's job is to add channel-dependent services — not reinstall everything from scratch.


Start · stop · restart

launchd (recommended — survives reboots)

# Start (first-time install or after edits)
launchctl load ~/Library/LaunchAgents/com.claude-ops.daemon.plist
# Stop
launchctl unload ~/Library/LaunchAgents/com.claude-ops.daemon.plist
# Force restart (common fix for stuck services)
launchctl kickstart -k gui/$UID/com.claude-ops.daemon
# Check status
launchctl list | grep claude-ops

Foreground (debug mode)

~/.claude/plugins/cache/ops-marketplace/ops/<version>/scripts/ops-daemon.sh start
~/.claude/plugins/cache/.../scripts/ops-daemon.sh status
~/.claude/plugins/cache/.../scripts/ops-daemon.sh stop

Via the plugin

/ops:setup daemon # re-install, regenerate plist with current paths
/ops:doctor # auto-repair (runs ops-autofix + kicks the daemon)

Logs

Primary log location:

~/.claude/plugins/data/ops-ops-marketplace/logs/ops-daemon.log

Follow live:

tail -f ~/.claude/plugins/data/ops-ops-marketplace/logs/ops-daemon.log

Filter by service:

grep briefing-pre-warm ~/.claude/plugins/data/ops-ops-marketplace/logs/ops-daemon.log
grep memory-extractor ~/.claude/plugins/data/ops-ops-marketplace/logs/ops-daemon.log

Note

Logs are rotated at 10 MB with 3 backup files kept. Nothing in the log file is ever transmitted off-machine — see Privacy and Security.


What the daemon does NOT do

Explicit list of non-behaviors
  • No telemetry. No phone-home, no crash reports, no usage metrics.
  • No outbound network except to the user's own configured APIs (Anthropic for Haiku calls, WhatsApp's servers via wacli, the user's Shopify store, etc.)
  • No sending messages unless a skill (running in an interactive Claude Code session) explicitly calls send_message with user confirmation.
  • No disk-wide scans. Every read is a targeted path: registry projects, ~/.wacli/, ~/.claude/plugins/data/ops-ops-marketplace/.
  • No credential harvesting post-setup. Auto-scan runs only inside /ops:setup.

Troubleshooting cross-reference

Symptom See
/ops:go is slow (>10s) Troubleshooting#daemon — pre-warm cache not updating
launchctl load fails Troubleshooting#daemon — launchd errors
wacli health degraded warning Troubleshooting#daemon — health file stale
Memories not extracting Troubleshooting#memories-not-extracting + Memories System
Still stuck Run /ops:doctor --verbose

See also

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /