- TypeScript 100%
| components/ui | ||
| dist | ||
| hooks | ||
| lib | ||
| .gitignore | ||
| app.tsx | ||
| components.json | ||
| package-lock.json | ||
| package.json | ||
| PLUGIN_OVERVIEW.md | ||
| README.md | ||
| server.ts | ||
| tsconfig.json | ||
bb-plugin-opencode-usage
A BB plugin that totals your local OpenCode usage — tokens, sessions, messages and cost — in a panel under the sidebar's thread list.
server.ts— the backend: opens opencode's SQLite store read-only and exposes oneusage_statsRPC that aggregates assistant messages over a caller-chosen window. Results are cached for a few seconds so a burst of frontend polls does not hammer the database.app.tsx— the frontend: a content script that mounts the panel into the sidebar footer (below the thread list, above the footer icon row) with a window picker (1m / 1h / 12h / 30d), an auto-refresh cycle (15 s … 5 min, or manual) and a per-model breakdown. It hides itself when the sidebar collapses to a narrow rail.components/,hooks/,lib/— vendored shadcn components.PLUGIN_OVERVIEW.md— the store listing text: a longer version ofbb.descriptionthat the plugin detail page shows under it. See Store listing.
Nothing leaves the machine: the plugin reads a local SQLite file read-only and needs no account, API key, or external service.
Requirements
- BB 0.47 or later.
- An opencode database at
~/.local/share/opencode/opencode.db(or$XDG_DATA_HOME/opencode/opencode.db). When the file is missing or unreadable the panel reports the store as unavailable instead of failing.
What the numbers mean
Input, output and reasoning tokens come straight from the usage opencode records on each assistant message, alongside cache reads and writes. Cost is the USD figure opencode stored, and is 0 when the provider reports no pricing. Models are grouped by provider and model id, ordered by total tokens.
UI components
components/ui/ is vendored source you own (the shadcn model): edit the
files freely — they never update out from under you. Add more from the BB
component registry (the full shadcn set, version-matched to your BB install
via the pinned ref in components.json):
npx shadcn add @bb/select @bb/table
Run npm install once before bb plugin build — the vendored components'
npm deps bundle into your dist. React, and BB-shimmed packages like the
radix portal primitives and sonner (import { toast } from "sonner"
reaches BB's own toaster), are provided by the BB app at runtime and never
bundled. Every shimmed package is declared in devDependencies at the
host's version so those imports typecheck; keep them there (never in
dependencies, which would bundle a second copy), and bb plugin types
repins declared packages alongside the SDK; unused packages may be removed. Ship dist/ (npm tarball or committed for
git installs) so people installing your plugin never need npm.
Manifest
package.json is the plugin manifest. Notable fields:
bb.server— backend entry (required).bb.app— frontend entry. Delete it,app.tsx,components/,hooks/, andlib/for a headless plugin.bb.skills— skill roots; omitted here, so BB readsskills/. Each directory with aSKILL.mdis one skill, named after the directory.bb.nameandbb.description— required human-facing identity.bb.branding— required; declareiconas a BB icon name or a plugin-relative compact SVG, or declarelogo.light(with optionallogo.dark). Logo assets must be relative.svg,.png, or.webpfiles.engines.bb— supported bb app version range.engines.bbPluginSdk— the lowest plugin SDK you need (scaffold:>=0.6.79). BB reads this as a floor, not a ceiling: a later SDK in the same major still loads your plugin.dependencies— every package your source imports that BB does not provide.bb plugin buildinlines them intodist/, and git installs resolve this list alone, so a build-required package here rather than indevDependenciesis what keeps your plugin installable.devDependenciesis for types and tooling only (BB shims React, the portal primitives, and@get-bb/plugin-sdkat runtime — never bundle them).
Run bb plugin build before publishing git/npm installs. It writes
dist/server.js + server.meta.json and app.js / app.css /
app.meta.json. Each *.meta.json stamps SDK major/version,
artifactFormatVersion, pluginId, pluginVersion, and
builtWith so managed installs can verify the artifacts.
Store listing
Two texts describe the plugin in the store. bb.description in package.json
is the one-sentence hook on every browse card and the lead paragraph on the
detail page; keep it under about 140 characters. PLUGIN_OVERVIEW.md is the
same claim at length, shown in an Overview section under that paragraph.
Rewrite the scaffold's copy for your plugin, and update it whenever
bb.description changes, so the two never disagree.
The submission to the public BB Community marketplace requires the file. Keep
it under 4000 characters (aim for 700 to 1800) and use headings, paragraphs,
emphasis, code, blockquotes, lists, thematic breaks, and absolute https links
only — raw HTML, images, tables, footnotes, and task lists are rejected. Do
not open with a # title or repeat bb.description verbatim; the page
shows both directly above.
Install
From this directory (bb plugin new already ran the install; a fresh clone
needs it):
npm install
bb plugin install .
After editing sources, reload:
bb plugin reload opencode-usage
Or let bb plugin dev rebuild and reload on every save.
Reload
The panel has no settings; after editing sources just reload:
bb plugin reload opencode-usage
Types & API reference
The plugin API ships as the npm package @get-bb/plugin-sdk, pinned to an
exact version in devDependencies (0.6.79 — the SDK of the BB
that scaffolded this plugin). After npm install, the full surface is on disk
at:
node_modules/@get-bb/plugin-sdk/bundled-types/bb-plugin-sdk.d.ts # backend
node_modules/@get-bb/plugin-sdk/bundled-types/bb-plugin-sdk-app.d.ts # frontend
Your editor and tsc resolve @get-bb/plugin-sdk there through ordinary node
resolution — no path mapping. These are readable declarations: open them for an
exact signature.
The SDK surface grows with every BB release, so the pin has to track the BB you actually run:
bb plugin types # sync this plugin's SDK surface to the running BB
bb plugin types --check # CI: fail when it does not match
Ask BB to write plugins for you: the bb-plugin-authoring skill documents
the whole surface with examples.
Confused by the API, or need something the types don't explain? Clone the BB repo and read the source: https://github.com/get-bb/bb.