Parity with microsoft/ghc-cli-dashboard
This project is an adaptation of github.com/microsoft/ghc-cli-dashboard (the Copilot CLI usage dashboard, which is also MIT licensed). That page is the maintained tool for GitHub Copilot CLI; this one is the equivalent for OpenCode. This file records what the two do not yet agree on, so the gap is visible rather than implied. See Attribution for how the two relate.
Scoping note: the upstream project targets Copilot CLI’s session store. Items that depend on data only Copilot CLI records are marked as such and are not worth porting unless OpenCode exposes the same thing.
Done here
| Area | Status |
|---|---|
| SQLite extractor, read-only snapshot | yes |
| CSV export, overlap resolution by export timestamp | yes |
| Self-contained offline HTML, Plotly bundled inline | yes |
| Token category definitions kept separate from the headline | yes |
| Design tokens, page shell, responsive layout | yes |
| Okabe-Ito / Viridis chart palette | yes |
| Cost by model, pricing efficiency, reasoning effort | yes, data-gated |
| Insights derived from the data | yes |
| Client-side render layer (re-render without a rebuild) | yes |
| Project / model / provider filters | yes |
| Search, Only, Select all/none, Show more, Reset | yes |
| Provider exclusion cascading to its models | yes |
| Sidebar collapse persisted to localStorage | yes |
| Synthetic sample data, screenshot tooling, browser tests | yes |
Not yet done
Ordered roughly by how much it would matter for this data.
Interaction
- Chart metric toggle (Tokens / Estimated cost). Every chart would need the other value column, its formatter and its axis title. Currently worth little: exports are almost entirely free tier, so the cost view is near-empty. It becomes valuable once paid models are in use.
- Date range presets (7 / 14 / 30 / 90 days / All time), computed relative to the latest date in the loaded exports rather than today. Low value at six days of history, useful on a longer export.
- Trend granularity toggle (Day / Week / Month). Depends on the above.
- Sortable, filterable rows table over the embedded rows, and a CSV download. The rows are already in the page, so this is mostly table plumbing.
Classification
- Vendor-level model colouring. Upstream infers a vendor from the model name prefix (
claude*-> Anthropic,gpt*-> OpenAI, and so on) and colours models by vendor, shared across the ranking, efficiency and mix charts. Here theprovidercolumn is a routing gateway (openrouter,opencode,azure), and the real vendor sits inside the model string (openrouter/google/gemma-4-31b-it). Deciding between colouring by gateway (honest to the data, four colours) and inferring a vendor from the model path (better looking, needs its own mapping table) is still open. Doing it before chart code moves around again is cheapest.
Publishing and sharing
- Build-time redaction. Upstream’s
dashboard.pyaccepts--exclude-project,--omit-task-summaries,--exclude-defaultand--exclude-default-models, so a dashboard can be stripped before sharing. Here the only lever is--include-session-titleat extract time, which is opt-in but cannot remove content afterwards. The generated HTML embeds its source rows either way, so this matters to anyone sharing a file. - Export format versioning. Upstream tracks format versions 1-3 and still loads legacy exports that predate
exported_at/export_format_version, warning when ordering is uncertain. This project writes version 1 and assumes the metadata columns exist.
Repository
- Continuous integration. No workflow runs the suite on push.
CONTRIBUTING.md,SECURITY.md,SUPPORT.md,CODE_OF_CONDUCT.mdare absent; upstream has all four.- Documentation site.
_config.yml,index.mdand front matter on the guides are in place, using the samejust-the-docsremote theme as upstream. It publishes documentation only, never a generated dashboard, because those embed source rows.
Data this project does not collect
Not gaps to close unless OpenCode starts recording the same thing.
- Task summaries and work-pattern views. Upstream reads per-task summaries out of the Copilot CLI store and derives work themes and modes. OpenCode’s store is not read for this.
- Reasoning-effort defaults per model. Upstream knows each model’s default effort so an unset value can be inferred. Here
variantisn/aunless explicitly recorded, which is why the reasoning-effort section usually shows its insufficient-data state.
Structural limits worth knowing
These are properties of the current design, not backlog items, but they bound what future work can do.
- Filter granularity.
extract_usage.pywrites one row per (session, day, provider, model, variant). Client-side filters re-slice at that grain and no finer, so session-level drill-down needs the extractor to emit finer rows. That multiplies row count, which interacts with the next point. - Page size grows with rows. The embedded payload was 1.26MB for 3,811 rows, about 21% of a 5.89MB file, on top of a ~4.85MB bundled Plotly. A long export history will push on this; a row cap with a warning, or dropping the columns filters do not need, is the obvious lever.
- Unexported usage. The dashboard shows whatever the CSVs contain. The extractor runs against a point-in-time snapshot, so a stale CSV renders stale data with a data-through date and nothing else to signal it.