A live usage dashboard for OpenCode, served by a single Python file — no framework, no build step, no dependencies.
- Single file:
opencode_dashboard.pyis the whole server and page. - Token-first: every chart, bar and heatmap shows tokens used — Input vs Output (incl. reasoning) vs Cache — with day-vs-day and model-vs-model comparisons.
- Auto-refreshing (30s, paused in background tabs); shows Today/7d/30d summary, per-day stacked token bars, tokens by file/subsystem, tokens per git commit, model universal comparison, records, and a GitHub-style 52-week token heatmap.
- Time-range presets (7/30/90 days, 1 year, all time) with period-over-period deltas, plus Split-reasoning and 100%-share toggles.
- Click to filter: days, models, agents, files, subsystems, commits. Hover or focus for tooltips.
- Resource-light: local stats are cached and re-aggregated only when the database file changes; idle polling costs ~1 ms per request. The server shuts itself down once every dashboard window is closed.
- Standalone app: the included
OpenCode Dashboard.commandlauncher opens a dedicated Chrome window and shuts the server down when the last window closes.
- Python 3.9+
- An OpenCode installation (it reads the SQLite db that OpenCode maintains)
- Chrome (optional, for the
.commandlauncher's dedicated window)
python3 opencode_dashboard.py --port 8765
# open http://localhost:8765Or double-click OpenCode Dashboard.command for a dedicated app window.
| Flag | Default | Description |
|---|---|---|
db |
~/.local/share/opencode/opencode.db |
Path to the OpenCode SQLite database (positional argument) |
--port |
8765 |
HTTP port to serve on |
--idle-timeout |
0 |
Shut the server down after N seconds with no requests (0 = off) |
--quiet |
— | Suppress per-request logging |
GET /api/stats— local SQLite token stats as JSON (always a well-formed payload, even on errors)GET /api/session/<id>— prompts for one session (loaded on demand when you open a session row)GET /— the dashboard pagePOST /api/close?wid=<window-id>— stop the server once the last dashboard window closes
Copy opencode_dashboard.py (and, optionally, the .command launcher) to any machine with Python 3 and an OpenCode db. Point it at that db and you're done. Everything — HTML, CSS, JS, SVG charts, KPI math, HTTP server, graceful shutdown — lives in one importable file you can read end to end.
The Export button offers JSON (full token payload) or CSV (per-day date,messages,sessions,tokens_in,tokens_out,tokens_reasoning,tokens_cache,tokens_total).
- The server binds to
127.0.0.1only and serves no network-exposed endpoints. POST /api/closevalidates theOriginheader, blocking cross-site (CSRF / DNS-rebinding) requests.- All database-derived text is HTML-escaped and JSON-safe-embedded, including session titles and prompts (the payload is escaped so a malicious title cannot break out of the page's script tag).
python3 -m pytest tests/ -q # tests need pytest
ruff check . # lintCI (.github/workflows/ci.yml) runs ruff, a compile check, and the test suite on Python 3.9/3.11/3.13.
- Reasoning tokens are merged into Output by default ("Output incl. reasoning") — use the Split reasoning toggle to see Output vs Reasoning separately; cached tokens always show separately.
- The session table shows
Input | Output | Cache | Totalexplicitly, plus burn rate (tokens/min) in the detail modal. - The session table shows the most recent 500 sessions to keep the payload bounded; full history remains in the charts and activity heatmap.
