Skip to content

Releases: jonasotoaguilar/opencode-tokenmeter

Release list

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 14 Aug 07:39

v1.1.0 — TokenMeter: progressive disclosure panel, palette settings command, configurable toggle shortcut

TokenMeter 1.1.0 is a feature release that rebuilds the sidebar around progressive disclosure. The panel reads at a glance: yellow section headings (Project, Session, Subagents), a primary token+cost line with the amount in light red, dim secondary metrics, and a nested subagent list with per-agent disclosure chevrons. Settings move out of the panel into a host palette dialog that never loses focus, and a configurable Ctrl+E shortcut expands or collapses every section together.

What changed

Progressive disclosure panel

  • Section titles (Project, Session, Subagents) render in the semantic yellow theme().warning with no icon; leading disclosure chevrons stay in the main text tone.
  • Metrics use a theme-relative tone hierarchy: the primary token+cost line is main text with only the $amount in theme().error; input/output/reason/cache rows and (N tasks) counts use a dim background-relative detail tone; agent names use theme().info.
  • The word spent is gone from the panel — the $ prefix already conveys cost — and the reasoning label is exactly reason.
  • Numbers modes: Compact renders 3 rows (primary + paired input/output + paired reason/cache); Precise renders 5 independent rows (tokens+cost, input, output, reason, cache). Every value stays visible at the 22-column floor.
  • Subagents is hidden entirely while the session has no delegated groups and appears automatically with the first one; the 0 agents · 0 tasks caption never shows.
  • Agent rows are ↳ name (N tasks) ▶ closed / ↳ name (N tasks) ▼ open, with the per-agent chevron trailing the header and metric rows indented beneath the name.
  • Master and section disclosure stay transient; the Subagents expanded preference remains durable.

Palette settings command and dialog

  • TokenMeter: Settings opens a host DialogSelect from the command palette — there is no in-panel settings screen.
  • Selecting an option cycles the preference on the same dialog instance; the dialog is never recreated, so focus and the filter query survive each change.
  • Preferences: Cache (combined/separated), Numbers (compact/precise), Summary (session/project), Subagents (collapsed/expanded), and Shortcut.

Configurable toggle shortcut

  • New command tokenmeter.toggle-sections expands/collapses Project, Session, and Subagents together; bound by default to Ctrl+E.
  • The Shortcut row in Settings cycles Ctrl+ECtrl+Shift+ECtrl+MOff; the choice persists under tokenmeter.toggle.shortcut and re-registers the keymap layer live — no restart.
  • With Off, the command stays visible in the palette but no key triggers it.
  • Both commands use the modern api.keymap.registerLayer({ commands, bindings }); disposers release in api.lifecycle.onDispose.

No version literal, no icon dependencies

  • The sidebar no longer renders a version literal next to the title, and it no longer depends on Nerd Font PUA codepoints: only plain Unicode // glyphs remain. The icon resource set and the stale sidebar screenshot were removed from the repo.

Upgrade

From 1.0.1 (or earlier):

  • Pinned users: change the pin to 1.1.0 in your TUI config, then restart OpenCode.
  • Unpinned users: OpenCode resolves latest on launch — restart OpenCode to pick up 1.1.0.
{
  "$schema": "https://opencode.ai/tui.json",
  "plugin": ["opencode-tokenmeter-tui"]
}

OpenCode installs plugin dependencies automatically — there is no npm install step. To update a cached plugin, remove ~/.cache/opencode/packages/opencode-tokenmeter-tui@latest and restart.

Known issues

  • The global host command palette keeps its own search state per open; TokenMeter cannot influence it (the plugin-owned settings dialog preserves its filter).
  • Biome reports style-level noNonNullAssertion warnings in the test suite (0 errors); one uncovered render branch in section.tsx sits at 93.18% line coverage, well above the 80% gate.
  • Project totals include deleted sessions from the first run of 1.0.0 onward; sessions deleted before the plugin's SQLite store existed are not counted retroactively.

Rollback

1.0.1 remains a fully loadable published version. If 1.1.0 regresses:

  • Users: pin back to 1.0.1 in the TUI config (or remove the plugin entry) and restart; report the failure so a 1.1.1 can be cut.
  • Maintainer: the release pipeline is tag-driven (v1.1.0 → preflight → publish → verify). A regression in 1.1.0 is corrected by cutting 1.1.1, not by re-pointing 1.1.0 — npm versions are immutable. Keep this document as the single release record until the next tag renames it.

v1.0.1

Choose a tag to compare

@github-actions github-actions released this 11 Aug 22:46
f2febf7

v1.0.1 — TokenMeter: fix the unloadable TUI package entrypoints

TokenMeter 1.0.0 published dist/tokenmeter.js with no exports map. OpenCode resolves npm TUI plugins exclusively through exports["./tui"], so the published package never loaded: the sidebar never appeared. 1.0.1 ships the contract-compliant entrypoint pair, the regression guard that makes the defect impossible to republish silently, and the plugin skill's now-mandatory entrypoint contract.

What changed

The package loads again: dist/tui.js + dist/tui.d.ts via exports["./tui"]

  • The build now produces exactly dist/tui.js — the same OpenTUI Solid-transform bundle (real effect/insert/insertNode reactive bindings, external host runtimes) — plus a deterministic dist/tui.d.ts declaration emitted from the source entry by the project's own TypeScript during bun run build (no new dependency).
  • package.json declares main/types and an exports map: "./tui" (and ".", pointing at the same pair for legacy resolvers) → dist/tui.js + dist/tui.d.ts.
  • The obsolete dist/tokenmeter.js path is gone. No compatibility alias is kept.
  • Runtime dependencies are unchanged: @opentui/core, @opentui/solid, and solid-js remain external runtime packages provided by the TUI host and shipped in dependencies.

The defect cannot silently return

  • test/artifact.test.ts now asserts the dist surface (exactly tui.js + tui.d.ts, never tokenmeter.js or index.*), the manifest exports shape, the declaration content, and the bun pm pack --dry-run tarball listing. A stale artifact or a missing exports["./tui"] fails CI before any publish.

The plugin skill enforces the entrypoint contract

  • The opencode-plugin skill documents the four possible artifact pairs and when each applies: TUI-only (tui.js/tui.d.tsexports["./tui"], registered in tui.json), server/runtime-only (index.js/index.d.tsexports["."] or exports["./runtime"], registered in opencode.json), dual (both pairs, two configs), and forbids shipping index.* in a TUI-only package.

The panel shows its new version

  • The sidebar title row renders TokenMeter 1.0.1; DESIGN.md, PRD, README, and the render/unit tests now describe the current UI.

Upgrade

From 1.0.0 (unloadable):

  • Pinned users: change the pin to 1.0.1 in your TUI config, then restart OpenCode.
  • Unpinned users: OpenCode resolves latest on launch — restart OpenCode to pick up 1.0.1.

Both cases:

{
  "$schema": "https://opencode.ai/tui.json",
  "plugin": ["opencode-tokenmeter-tui"]
}

OpenCode installs plugin dependencies automatically — there is no npm install step.

Known issues

  • The sidebar glyphs are Nerd Font PUA codepoints: without a Nerd Font active in the terminal they degrade to missing characters. Every number still renders and the panel never crashes.
  • The cache breakdown row (R<read>|W<write>) needs roughly 36 terminal columns of sidebar width; narrower sidebars omit the breakdown row rather than overflow.
  • Project totals include deleted sessions from the first run of 1.0.0 onward; sessions deleted before the plugin's SQLite store existed are not counted retroactively.
  • The opencode-tokenmeter-tui@1.0.0-bootstrap.0 placeholder (if still present on npm under the bootstrap dist-tag) is not loadable and should never be pinned; remove the bootstrap dist-tag after this stable release per docs/release-security.md.

Rollback

There is no functional npm version before 1.0.1: 1.0.0 was publishable but unloadable, and the 1.0.0-bootstrap.0 placeholder is not a usable plugin. If 1.0.1 regresses:

  • Users: unpin or revert to the last working version you actually ran locally, or remove the plugin entry until a fix ships; report the failure so a 1.0.2 can be cut.
  • Maintainer: the release pipeline is tag-driven (v1.0.1 → preflight → publish → verify). A regression in 1.0.1 is corrected by cutting 1.0.2, not by re-pointing 1.0.1 — npm versions are immutable. Keep this document as the single release record until the next tag renames it.