opencode-tui-usage
opencode-tui-usage

A single OpenCode TUI sidebar plugin that unifies prompt-cache, token, cost,
context, tools, skills, speed and sub-agent usage into one coherent panel.
English and USD only. Precision first: anything that cannot be grounded in
API-reported data is clearly flagged as an estimate (est. / ~est) and never
contributes to a precise total.
It merges and replaces the overlapping functionality of
opencode-cache-hit (modular
architecture, sub-agent rollup, cache TTL, JSONL timeline) and
opencode-visual-cache
(persisted fold state, estimated role distribution, loaded-skills detection).
Install
You can install the plugin either globally (for all TUI sessions) or locally (on a per-project basis).
Global Installation
To enable the plugin globally across all your projects, add it to your global TUI configuration file at ~/.config/opencode/tui.json:
{
"plugin": ["opencode-tui-usage@latest"]
}Per-Project Installation
To enable the plugin only for a specific project, create or modify the local TUI configuration file at .opencode/tui.json in your project's root directory:
{
"plugin": ["opencode-tui-usage@latest"]
}Start OpenCode and open the TUI sidebar; the panel registers automatically and appears once the session has usage data.
Panel layout
One collapsible panel with eight independently collapsible sections. The organizing principle is cumulative (lifetime) data is separate from current (context-window) data, which also resolves undo/fork semantics cleanly.
| # | Section | What it shows | Precision |
|---|---|---|---|
| 1 | Cache | last-turn Hit% bar + trend; session Total Hit; cache TTL age (color-coded) | precise |
| 2 | Context | precise Fill used / limit (pct%); compaction indicator; estimated role breakdown (System / User / Tool calls / Tool out / Reasoning / Other) |
fill + compaction precise; breakdown est. |
| 3 | Session | cumulative Input (Miss) / Output / C.Read / C.Write / Reason; cumulative Cost + Last-turn cost; cache Saved $ |
precise |
| 4 | Model | provider, model, pricing ($/M in, /M cache, /M out); >200K tiered-pricing indicator; click to open the model picker |
precise |
| 5 | Tools | per-tool call counts | precise |
| 6 | Skills | loaded skill names + load counts + ~est token footprint |
names/counts precise; tokens estimate |
| 7 | Speed | Now / Last / Avg tok/s, trend sparkline, TTFT | precise-ish (from part timestamps) |
| 8 | Agents | sub-agent rollup (aggregate tokens + cost) + per-agent rows; click a row to open that sub-agent's session | precise |
When the whole panel is collapsed, the title row shows the last-turn Hit% (or total sub-agent cost when there is no main session data yet).
Interactive elements
Some rows respond to the mouse (they highlight on hover):
- Model (§4): click to open the model picker (the same dialog as the
/modelsslash command), so you can switch the active model without leaving the panel. After you switch, the displayed model updates once the switch is recorded — opencode does not expose the picker's pre-submit selection to plugins, so it cannot update before you send a query. - Agents (§8): click a sub-agent row to open that sub-agent's session and read its log.
Token terminology
Each assistant turn reports tokens: { input, output, reasoning, cache: { read, write } }:
- C.Read =
cache.read— prompt tokens served from cache (cheap). - Input (Miss) =
input— fresh prompt tokens billed at full input price. - C.Write =
cache.write— tokens written into the cache this turn. - Output =
output; Reason =reasoning. - Hit % =
read / (read + input).
Context role breakdown
Under Section 2 (Context), the plugin estimates the breakdown of tokens occupied by different roles in the active context window:
- System: System instructions, core agent guidelines, and tool definitions.
- User: User queries, instructions, and uploaded files / workspace context.
- Tool calls: Raw inputs and parameters sent to tools.
- Tool out: Outputs, results, or errors returned from executed tools.
- Reasoning: Internal reasoning / chain-of-thought tokens generated by reasoning models (e.g., DeepSeek R1, OpenAI o1/o3).
- Other: Spawned sub-agent workspace tasks, along with formatting wrappers, metadata, and estimation variance.
Note: Individual categories are calculated using character-to-token heuristic estimators (labeled as est.), while the overall context fill total is 100% precise. To keep the UI clean, any category occupying less than 0.05% of the total context is automatically hidden.
Configuration
Two distinct mechanisms:
- Fold / collapse state is persisted via
api.kvand survives restarts. No config needed — just expand/collapse sections in the TUI. - Everything else is a JSON config file. Preferred path:
~/.config/opencode/opencode-tui-usage.json(survives plugin updates); fallback: plugin-rootopencode-tui-usage.config.json. Edits are picked up when the parent session changes (no full reload required).
Section visibility (whether a section is rendered at all) is controlled by
display.sections.* in the config; section fold (expanded vs collapsed) is the
kv-persisted state. The two are independent.
See opencode-tui-usage.config.example.json
for all options:
{
"display": {
"panelBorder": true,
"contextBreakdownEstimate": true, // §2 estimated role breakdown (default on)
"contextBreakdownTokens": false, // If true, shows raw token values instead of percentages (default false)
"sections": {
// section visibility (not fold state)
"cache": true,
"context": true,
"usage": true,
"model": true,
"tools": true,
"skills": true,
"speed": true,
"agents": true,
},
},
"cost": { "decimals": 4, "minDisplay": 0.0001 }, // USD only
"cacheTTL": {
"enabled": true,
"providers": {
"anthropic": "5m",
"openai": "5m",
"deepseek": "2h",
"google": "1h",
},
},
"timeline": {
// opt-in JSONL export, OFF by default
"enabled": false,
"dir": "",
"rotateMaxBytes": 16777216,
"retainRotated": 5,
"maxAgeDays": 30,
"maxLogFiles": 20,
"toolSummary": { "allTools": true, "bash": false },
},
}Notes:
- Cache TTL colors: green while
elapsed < TTL, yellowTTL ≤ elapsed < 2×, red≥ 2×. Built-in default 5m; per-provider overrides parse durations like30s,5m,1.5h,2h. A unitless value is interpreted as seconds (e.g."300"= 5 minutes). - Timeline JSONL export is secure-by-default (
toolSummary.bash: false) — bash inputs may leak credentials and are only truncated, not sanitized. - Tiered pricing: when the current context exceeds 200K tokens and the model
exposes
experimentalOver200Kpricing, displayed rates and the savings estimate switch to the tiered rates (the reported cost is already correct regardless).
Undo / revert / fork
- Context fill (§2) and last-turn Hit% (§1) read the live message list, so
/undo, revert-to-point and fork are reflected automatically — context fill shrinks when history is rolled back. - Session usage and cumulative cost (§3) read DB aggregates, which are cumulative and do not roll back — correct, because spend is not refunded.
- Forks appear as separate session ids; child-session sync keys off
parentID, so a fork surfaces as its own session rather than corrupting the parent totals.
Development
bun install
bun test # run the test suite
bunx tsc --noEmit # typecheckCredits & license
MIT. Derived from the MIT-licensed
opencode-cache-hit by
zhumengzhu and
opencode-visual-cache by
Hotakus. The cache-TTL display is inspired by
opencode-cache-timer by
nero-sensei.