opencode-tui-usage
v2.3.0
Published
OpenCode TUI sidebar: precise prompt-cache, token, cost, context, tools, skills, speed & sub-agent usage. English/USD only.
Readme
opencode-tui-usage
A native OpenCode V2 sidebar plugin for prompt-cache, token, cost, context, model, tool, skill, speed, and sub-agent usage. English and USD only.
The plugin is precision-first: API-reported values stay precise. Derived role,
tool, and skill token estimates, cache savings, and live streaming speed are
labeled est. / ~est and kept separate from precise totals.
Legacy version
opencode-tui-usage@latest is the maintained OpenCode V2 release. OpenCode V1
users can install the latest legacy 0.x release with
opencode-tui-usage@v0. Its source is available from the V1 Git tags.
Installation
Add opencode-tui-usage to the plugins array in global
~/.config/opencode/cli.json:
{
"plugins": ["opencode-tui-usage"]
}Panel
The sidebar supports eight independently collapsible sections. Data-dependent Tools, Skills, and Agents sections appear only when relevant:
| Section | Contents | Precision |
| --- | --- | --- |
| Cache | Last-turn hit rate and trend, lifetime hit rate, cache age against configured, built-in, or default TTL policy | Precise except provider TTL policy |
| Context | Active used/limit, staged-revert boundary, explicit compaction state/reason, role breakdown | Fill precise; roles est. |
| Session | Own-session lifetime tokens and reported cost, last-turn cost, cache savings | Tokens and reported costs precise; savings estimated |
| Model | Display name, selectable model and variant, provider, family, compact ↔ context / ↑ input / ↓ output limits, active ModelInfo.cost[] pricing tier | Precise |
| Tools | Aligned running, failed, and total call counts with input/result token footprint | Counts precise; tokens ~est |
| Skills | Aligned skill name, load count, and token footprint | Counts precise; tokens ~est |
| Speed | Live state, last/average speed, trend, live-observed TTFT, retries | Historical speed and TTFT API-derived; live speed estimated |
| Agents | All nested descendants in one creation-ordered list, own usage, identity/model, session ID suffix, live status | Precise |
Agent status indicators are:
| Glyph | Meaning |
| --- | --- |
| animated Braille spinner | Running |
| ✓ | Succeeded |
| × | Failed |
| ■ | Interrupted |
| ○ | Idle or unknown |
Running takes precedence over the last recorded outcome. Every running agent uses the same one-cell animated Braille spinner. All descendants appear in a flat list, newest created first. Agent rows use two lines: the first shows status, agent name, and active context usage; the second shows model, an optional non-default variant, a five-character session-ID suffix, average speed when enabled and space permits, and nonzero API-reported cost. Click the agent name or model name to open that session. Click the ID suffix to copy the complete ID. Click the model row in the Model section to open OpenCode's built-in model picker.
Data Semantics
- Lifetime tokens and cost come from each session's authoritative V2
SessionInfo. Descendant usage is never folded into a child's own values. - Active context comes from
session.context()and is additionally bounded by a staged revert. - Descendants are discovered recursively with
session.list({ parentID })and synchronized into the TUI data store for reactive status. - Model pricing uses the generic
ModelInfo.cost[]tiers and their configured prompt thresholds. Prompt-tier selection uses input, cache-read, and cache-write tokens. Context Fill continues to use all five reported token fields. - Session, last-turn, and sub-agent costs are API-reported. Cache savings use the current active rate and lifetime cache-read tokens, so they are estimates and can include reads from before compaction.
- Tools come from all assistant tool content, including
skillcalls. Skills expand completed V2skillcalls and first-class skill messages when available. - Historical TTFT is not invented. TTFT appears only for turns whose first output was observed live.
- Raw tool inputs, outputs, errors, provider state, and metadata are never displayed or written to the timeline.
Configuration
Fold state uses V2 namespaced durable plugin storage and synchronizes across TUI
instances. Configure other settings with native OpenCode plugin options. For a
terminal-wide setup, add the object form to global ~/.config/opencode/cli.json:
{
"$schema": "https://opencode.ai/v2/cli.json",
"plugins": [
{
"package": "opencode-tui-usage",
"options": {
"display": { "sidebarPosition": "bottom" },
},
},
],
}The same object form works in global or project opencode.json or
opencode.jsonc when server or project scope is appropriate. OpenCode reloads
the plugin after valid changes to those files.
Plugin-owned JSONC files remain supported for backward compatibility. When no
non-empty inline options object is supplied, the preferred path is:
~/.config/opencode/opencode-tui-usage.jsonInline options and plugin-owned files are alternatives, never merged. A
non-empty inline object—including one containing only future or unknown
keys—uses inline configuration and completes omitted values from built-in
defaults. Missing, empty, or non-object inline options use the external files.
At startup, the plugin uses the preferred file when it is valid; otherwise it
uses opencode-tui-usage.config.json beside the installed plugin. If neither
file is valid, it uses its built-in defaults.
Configuration accepts JSONC syntax, including comments and trailing commas.
Files may contain only the settings to override; unspecified settings use their
defaults. See the configuration reference for every option and
opencode-tui-usage.config.example.json
for a complete example. opencode-tui-usage.config.schema.json
is the machine-readable description of the supported shape.
OpenCode reloads inline configuration after a valid OpenCode config save.
Plugin-owned file changes apply automatically, including a change to
display.sidebarPosition. While the plugin is running, an invalid external
save leaves the last valid configuration active until the file is fixed.
To hide OpenCode's built-in Context section when this plugin supplies the same
information, disable that built-in plugin in ~/.config/opencode/cli.json:
{
"plugins": ["-opencode.sidebar.context", "opencode-tui-usage"]
}Development and testing
Prepare a local checkout:
git clone https://gitlab.com/nomaed/opencode-tui-usage.git
cd opencode-tui-usage
bun installbun install runs the prepare build. The build creates dist/, which Git
ignores. Use one of these local directory targets in cli.json:
| Target | Loaded code | Use |
| --- | --- | --- |
| "/absolute/path/to/opencode-tui-usage" | Source entrypoints index.ts and tui.tsx | Source development |
| "/absolute/path/to/opencode-tui-usage/dist" | Compiled JavaScript | Package-output testing |
For example, this configuration loads the local source:
{
"plugins": ["/absolute/path/to/opencode-tui-usage"]
}Local plugin targets are directories. Do not point OpenCode directly to
index.ts, tui.tsx, or a compiled entrypoint file.
Run the checks or create an npm package archive as needed:
bun run check
bun pm packbun pm pack also runs the prepare build. npm tarballs include dist/
because package.json lists it under files.
The package provides two native OpenCode V2 plugin entrypoints:
.: server plugin./tui: terminal UI plugin registeringsidebar.content
It also exports ./tui-panel for its reusable panel components.
License
MIT.
