A VS Code/Cursor extension that combines two sources of truth:
- local OpenCode message history from
~/.local/share/opencode/opencode.db - live provider windows from Anthropic and Codex/OpenAI usage APIs
- a status bar headline with provider summaries (live percent or fallback billing)
- a native dashboard tree view with:
Live Rate LimitsLive BillingMonthly BillingMonthly TokensLocal History- optional
Estimated 7h Diagnostics
- user-selectable local history windows:
1h,7h,24h,7d,30d
- Install from the marketplace, or download a VSIX from GitHub Releases and install it directly.
- For local development, open this folder in VS Code or Cursor and launch the Extension Development Host.
- Local history works immediately as long as
sqlite3is available onPATH. - To install the companion token-tracking plugin, run
OTU: OpenCode Token Usage: Install Tracking Pluginfrom the command palette or the dashboard title actions. - The command copies
opencode-token-usage-tracker.jsinto~/.config/opencode/plugins/. - Restart OpenCode after installation so the tracker plugin is loaded.
Download the latest .vsix asset from the GitHub Releases page:
https://github.com/DongHyunnn/opencode-plugin-token-usage/releases
Build a VSIX locally:
npm install
npm run package:vsixInstall the generated VSIX in VS Code:
code --install-extension ./opencode-token-usage-extension-*.vsixIf the cursor shell command is available on your machine, you can use the same VSIX from Cursor:
cursor --install-extension ./opencode-token-usage-extension-*.vsixConvenience scripts are included:
npm run install:vsix:vscode:dry-run
npm run install:vsix:cursor:dry-runThen run the real install command after packaging:
npm run install:vsix:vscodeor
npm run install:vsix:cursorOnce the extension is published, install it from the VS Code extensions view by searching for OTU: OpenCode Token Usage, or from the CLI with:
code --install-extension DongHyunnn.opencode-token-usage-extensionCursor officially supports extension installation from the Extensions UI. If the cursor shell command is available and the same extension id is resolvable there, the equivalent command is:
cursor --install-extension DongHyunnn.opencode-token-usage-extensionFor Cursor/Open VSX compatibility, publish the same extension to Open VSX and install it from the Open VSX-backed extensions UI in Cursor.
If you want to publish manually after creating your Open VSX namespace and token:
npm run publish:ovsx -- -p "$OVSX_PAT"The release workflow also supports Open VSX publishing when the repository secret OVSX_PAT is configured.
- OpenCode history is read from the local SQLite
messagetable, which already stores provider, model, token, cost, and timestamp metadata. - Anthropic and Codex live windows still come from provider APIs so their rate-limit windows stay authoritative.
- The optional
7hsection is derived from local history and is intentionally labeled as an estimate. - The history reader currently shells out to the local
sqlite3binary, so the host machine needssqlite3available onPATH.
opencodeTokenUsage.databasePathopencodeTokenUsage.openCodeAuthPathopencodeTokenUsage.openCodeConfigPathopencodeTokenUsage.codexAuthPathopencodeTokenUsage.refreshIntervalSecondsopencodeTokenUsage.historyWindowopencodeTokenUsage.showEstimated7h
These paths are machine-scoped because they point to local editor/runtime state.
- Claude (Anthropic): Uses
openCodeAuthPath(~/.local/share/opencode/auth.json), reuses a valid access token until expiry, then refreshes with the stored refresh token. Multiple running extension instances share a single file-backed cache so only one instance hits the API per refresh cycle. - Codex/OpenAI: Reads both
openCodeAuthPathandcodexAuthPath; uses valid OpenCode access first; otherwise tries refresh tokens from either path; otherwise falls back to raw Codex access token only when no refresh path exists. Also uses a shared file-backed cache to deduplicate API calls. - Gemini: Three-tier fallback in order:
- OAuth quota (live rate-limit windows): if
openCodeAuthPathcontains agoogle.type = "oauth"entry from theopencode-gemini-authplugin, the extension callscloudcode-pa.googleapis.com/v1internal:retrieveUserQuotadirectly using that token. If the access token is already valid, quota fetch works directly; if the token is expired, automatic refresh now requires localOTU_GEMINI_OAUTH_CLIENT_IDandOTU_GEMINI_OAUTH_CLIENT_SECRETenvironment variables before the extension will refresh it. - Gemini CLI (live pooled quota): if the
geminiCLI binary is onPATHand authenticated, the extension runsgemini -o json -y /stats modelto read pooled remaining quota. - API key / estimateOnly: if
google.keyis set inopenCodeAuthPathorGOOGLE_API_KEY/GEMINI_API_KEYenv vars are present, the provider appears in the status bar without live quota data. The extension also detects theopencode-gemini-authplugin viaopenCodeConfigPath(~/.config/opencode/opencode.json) and shows estimateOnly in that case.
- Status bar fallback chain:
live percent→vendor billing→estimated local 5h charge. - Diagnostics: Auth failures are categorized as
not configured,expired,refresh failed, orfetch failedto help troubleshooting. Gemini project resolution failures report the specific API error fromloadCodeAssist.
On Windows Subsystem for Linux, the extension automatically translates Windows-style paths (e.g. C:\Users\...) to their WSL mount equivalents (/mnt/c/Users/...). The npm run dev launcher also detects WSL and opens the Extension Development Host via a Remote WSL window if the ms-vscode-remote.remote-wsl extension is installed.
npm install
npm run dev
npm testOpen the folder in VS Code or Cursor and run the extension host from the editor.
- Cursor: open this folder and run the
Run OTU: OpenCode Token Usage Extensionlaunch configuration. - VS Code: same flow; the repo now includes
.vscode/launch.json. - One-command launcher:
npm run dev- Dry-run command resolution:
npm run dev -- --dry-run- CLI alternative:
cursor --extensionDevelopmentPath="$(pwd)"or
code --extensionDevelopmentPath="$(pwd)"In the Extension Development Host, open the OTU: OpenCode Token Usage panel, then run OTU: OpenCode Token Usage: Refresh from the command palette if needed.