Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CC Agent Monitor

Real-time dashboard for monitoring cc-connect on macOS — processes, sessions, token usage, errors, trends, and alerts.

🌏 中文用户README.zh-CN.md · Chinese users: see README.zh-CN.md.

A zero-dependency, raw-socket HTTP server that watches Claude Code + Codex CLI bridges and renders a glass-morphism dashboard with sub-second refresh. Designed to surface the failure modes that hide when you only look at the bridge status (dead sessions, near-limit context, jsonl pollution, watchdog alerts).

dashboard

Why

When you operate cc-connect as a Feishu bridge for Claude Code / Codex, the failure modes that actually matter are not "is the process up" — they are:

  • A session is stuck on a half-acknowledged tool call (Codex 2013)
  • A rollout has been deleted but the session JSON still points at it (Codex 32600)
  • A Claude session has silently grown past 200K context (token budget gone)
  • A Codex .jsonl has bloated to 10 MB and the session is near limit
  • The bridge is alive but its Feishu WebSocket dropped and it is not receiving messages

This dashboard answers all of those in one screen, with a 4-tier refresh architecture so each layer updates at the rate it actually needs.

Features

🎯 4-tier refresh

Tier Interval What Endpoint
Realtime 1 s Marquee + process / token counters GET /api/realtime
Full 5 s Sessions table, error panel, system health GET /api/full
Alerts 30 s Evaluate alert state, dedup, write to file, optional Feishu push internal thread
Snapshots 1 min Persist metrics to SQLite for trend chart GET /api/snapshots

📊 Visual

  • Glass-morphism cards (top): cc-connect / Codex / Claude / Errors
  • 60-LED marquee with sheen animation: process activity per second
  • Token usage bar with real usage.input_tokens (not chars/3.5 estimates — those are off by 3-4×)
  • Session table: click any row to inspect the last N messages of its .jsonl
  • Error panel: original English log + side-by-side Chinese translation for the common Codex/Codex panic patterns
  • Trend charts (Chart.js): context %, CPU, memory, load avg, error count, Feishu connections

🛎 Alerts

  • 🔴 RED — process dead, 9820 HTTP non-200, no Feishu long-poll, Claude session over context window
  • 🟡 YELLOW — Codex/Claude near-limit (≥ 80 %), new level=ERROR in cc-connect log, watchdog stale > 30 min
  • 10-minute dedup (key = scenario + entity) so the master is not spammed
  • Push to Feishu (optional, requires FEISHU_APP_ID/SECRET/OPEN_ID) and always write to monitor.alert (for HEARTBEAT-based delivery)

Quick start

# 1. Drop the files
git clone <this-repo>
cd CC-Agent-Monitor

# 2. Install the launchd service
cp docs/com.cc-agent-monitor.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.cc-agent-monitor.plist
launchctl kickstart -k gui/$(id -u)/com.cc-agent-monitor

# 3. Open the dashboard
open http://localhost:9870/

That's it. No pip install, no virtualenv, no Node. Pure Python 3.8+ standard library.

Configuration

All knobs are environment variables (set them in the plist's EnvironmentVariables dict).

Variable Default Purpose
MONITOR_HOST 0.0.0.0 Bind address
MONITOR_PORT 9870 HTTP port
FEISHU_APP_ID (empty) Enable alert push to Feishu
FEISHU_APP_SECRET (empty) Enable alert push to Feishu
FEISHU_OPEN_ID (empty) Target Feishu user

If any of the three Feishu vars is missing, alerts are written to monitor.alert and the host's HEARTBEAT-based delivery is expected to surface them.

Architecture

                +-------------------+
                |  browser (any)    |
                |  fetch /api/*     |
                +---------+---------+
                          |  HTTP
                          v
+---------------------------------------------------+
|                  server.py                       |
|                                                   |
|  +----------+  +-----------+  +---------+  +----+ |
|  | realtime |  |  alerts   |  |snapshot |  |HTTP| |
|  |  1s loop |  |  30s loop |  | 60s loop|  | rxd| |
|  +----+-----+  +-----+-----+  +----+----+  +----+ |
|       |             |             |              |
|       +-------+-----+-------------+              |
|               |                                  |
|               v                                  |
|        +-------------+                           |
|        | collector.py|                           |
|        |  (stat-only) |                          |
|        +------+------+                           |
+---------------|----------------------------------+
                |
                v
        +-------+-------+--------+----------+
        |  .cc-connect |  .codex |  .claude |  system
        +---------------+--------+----------+

collector.py is stat-only for the 1 s path (os.stat + pgrep) — it never reads file bodies on the hot path, so the cost is sub-millisecond. Heavier reads (.jsonl tail, last_token_usage extraction) are on the 5 s path.

Reading real tokens

Token percentages come straight from the API usage fields, not character estimates:

# Claude (Anthropic): input_tokens does NOT include cache; sum all three
usage = event["message"]["usage"]
tokens = (usage.get("input_tokens", 0) +
          usage.get("cache_read_input_tokens", 0) +
          usage.get("cache_creation_input_tokens", 0))

# Codex (OpenAI): input_tokens DOES include cache; use last_token_usage
if event["type"] == "event_msg" and event["payload"]["type"] == "token_count":
    last = event["payload"]["info"]["last_token_usage"]
    tokens = last["input_tokens"]

chars/3.5 estimation is 3-4× off in both directions (overstates Claude, understates Codex). See docs/token-accuracy.md for measurements.

Development

Adding a new metric

  1. Write a collect_*() function in collector.py returning a JSON-serializable dict. Keep the 1 s path stat-only.
  2. Add the key to the _cache_full dict inside collect_full().
  3. Add a tile in _HTML and a render*() JavaScript function.

The dashboard is one Python file and one HTML string. No build step.

Running tests

# Smoke test the collector (no server)
python3 collector.py

# Verbose server log
MONITOR_DEBUG=1 python3 server.py

Project layout

CC-Agent-Monitor/
├── server.py            # raw-socket HTTP + 4 background threads
├── collector.py         # zero-dep data collection (stat-only hot path)
├── docs/
│   ├── com.cc-agent-monitor.plist
│   └── dashboard.png
├── README.md
├── LICENSE
└── .gitignore

License

MIT — see LICENSE.

Credits

Built for monitoring cc-connect, a Feishu bridge for Claude Code / Codex CLI.

About

Real-time dashboard for monitoring cc-connect (Claude Code / Codex bridge) on macOS — processes, sessions, token usage, errors, trends, and alerts.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages