Every panel follows the same shape: a source is sampled by a PowerShell script, transformed into a JSON snapshot, and rendered by an HTML page on Vercel.
Manual trigger Scheduled trigger Session-only trigger Pipeline stages
| Panel | Source | Refresh script | Snapshot |
|---|---|---|---|
| claude.html | ccusage reading ~/.claude/projects/*.jsonl (daily totals + blocks --json for active block & P90 caps) |
refresh-claude-dashboard.ps1 |
data/claude-usage.json |
| agents.html | Frontmatter + body of every *.md in ai-shared-brain/agents/ + git log for last-modified dates |
refresh-agents-dashboard.ps1 |
data/agents.json |
| agents.html (activity) | Agent invocation logs collected over time | sync-agent-logs.ps1 |
data/agent-stats.json |
| brain.html | git log + file counts from ai-shared-brain repo |
refresh-brain-dashboard.ps1 |
data/brain.json |
| mcps.html | claude mcp list + claude mcp get <name> for servers; plugin / skill directories on disk for slash commands |
refresh-mcps-dashboard.ps1 |
data/mcps.json |
| sites.html | Vercel REST API for 5 active projects (deployments, domains, env vars) + curl to each live URL for HTTP 200 | refresh-sites-dashboard.ps1 |
data/sites.json |
| routines.html (cloud) | Anthropic RemoteTrigger list API — token only available inside a Claude Code session |
refresh-routines-dashboard.ps1 |
data/routines.json |
| routines.html (local) | Opted-in Windows scheduled tasks via Get-ScheduledTask |
refresh-local-tasks-dashboard.ps1 |
data/local-tasks.json |
| tasks.html | *.md in ai-shared-brain/tasks/{backlog,in-progress,done}/ — status derived from folder, not frontmatter |
refresh-tasks-dashboard.ps1 |
data/tasks.json |
data/X.json at the head of main.
~/.claude/projects/ JSONL, the brain repo, Windows scheduled tasks, the claude CLI. A serverless function on Vercel can't reach any of those. Running locally and pushing the result is the simpler shape; the script IS the function.
RemoteTrigger API needs the OAuth token that lives inside a running Claude Code process. Mark refreshes that one by hand from inside CC; the unattended scheduler can't reach it. Three possible fixes (build a save-snapshot endpoint that a cloud routine POSTs to, manual-token CLI wrapper, or just live with the manual refresh) — currently option 3.
ccusage statusline in ~/.claude/settings.json for live readout inside Claude Code's CLI; and a "Live session" panel on claude.html that shows P90-calibrated cost/token/message caps from the same JSONL data. Both read the same underlying logs — different presentation. Companion TUI claude-monitor (alias ccm) installed via uv tool install for a richer real-time view in a side terminal.