A local, single-purpose web app for browsing and triaging your Claude Code sessions. Reads directly from ~/.claude/ — no database, no daemon, no telemetry.
Built because the CLI alone makes it hard to answer questions like:
- "Which sessions are about to be auto-compacted?"
- "How much output have I burned this month, and on which model?"
- "Where's that conversation I had last week about the auth bug?"
- "Can I jump back into that session without remembering the UUID?"
- Grouped by project with one-click
claude --resume(copies the fullcd && claude --resume <id>to clipboard) - Per-session context-fullness bar — shows the latest turn's input tokens as a fraction of the auto-compact threshold (80% of context window). Color-coded green / yellow / red.
compacted ✓badge — appears when/compactran but no new reply has refreshed the context size yet- Cumulative output tokens per session (
1.8M outstyle) - Background-task filter — scheduled SDK/headless runs (
entrypoint=sdk-cli) are hidden by default with a "N background tasks hidden · Show" toggle - Older sessions folded — within each project, sessions older than 10 days collapse behind a "Show N older sessions" button
- Live search with 300ms debounce, returns HTML partials
Full conversation view. thinking and tool_use / tool_result blocks are collapsed by default. Each text block has a ¶ preview toggle in its top-right that renders the raw Markdown into formatted HTML — headings, lists, code blocks, blockquotes, links — mirroring how Claude's output looks in a terminal. Toggle is per-block, lazy-rendered on first click.
xterm.js-backed PTY in the browser. Start a fresh claude session in any project directory, or --resume an existing one. Scrollback is preserved across reconnects.
Recomputed from JSONL on every request (the cached stats-cache.json Claude Code writes is updated lazily and is often stale). Total sessions/messages, first-session date, longest session, daily activity, model usage breakdown (input / output / cache read / cache create), peak-hour distribution.
git clone https://github.com/pattypoem/claude-code-dashboard.git
cd claude-code-dashboard
python3 -m venv venv
venv/bin/pip install -r requirements.txt
venv/bin/python run.pyOpen http://127.0.0.1:5050.
To keep it running across reboots and crashes, drop a LaunchAgent plist into ~/Library/LaunchAgents/ (macOS) with RunAtLoad + KeepAlive.
- Python 3.10+
- Flask 3.0+, Flask-SocketIO 5.3+
- Claude Code installed locally — the app reads
~/.claude/
app/
├── __init__.py # Flask app factory + SocketIO init
├── config.py # Paths, port configuration
├── routes.py # HTTP routes (dashboard, session, stats, terminal, API)
├── data.py # JSONL scanning with mtime caching
├── models.py # Dataclasses: Session, Project, Message, Stats
├── events.py # SocketIO events for the interactive terminal
├── terminal.py # PTY management
├── filters.py # Jinja2 filters (timeago, format_tokens, …)
├── templates/ # Jinja2 templates
└── static/ # CSS, JS, vendor libs (xterm.js, socket.io, marked.js)
A few design choices worth flagging:
- JSONL is the source of truth.
sessions-index.jsonis read only to enrich sessions with summaries and skip sidechains — Claude Code writes JSONL in real time but updates the index lazily. - No client-side framework. Homepage is server-rendered, search returns HTML partials, terminal is plain SocketIO + xterm.js. Markdown preview is the only piece of client-side rendering (marked.js, lazy per block).
- HTML responses are
no-storeso a refresh always shows fresh data.
| Env Variable | Default | Description |
|---|---|---|
CLAUDE_HOME |
~/.claude |
Path to Claude Code data directory |
CC_DASHBOARD_PORT |
5050 |
Server port |
MIT



