Personal tooling for opencode and Command Code, kept in one repo. Each subdirectory is an independent package — Cargo crates, npm plugins, and CLIs — sharing no code; coupling is by installed binaries and published plugins (via env vars such as CMDUSE_BIN / MPC_BIN / REQSHAPE_BIN, each defaulting to the global command name), never by a relative path. This repo was formerly the standalone cmduse repo plus five sibling repos, now folded together at the root.
| Project | Dir | What it is |
|---|---|---|
| cmduse | core/ · cmduse/ · opencode-plugin/ |
Everything Command Code usage: the cmd-usage CLI (cmduse / ocuse), the shared cmduse-core, and the opencode plugin (@jeffreyjyz/opencode-command-code). |
mpc |
oc-cmd-compare/ |
Compare model pricing across OpenCode Go and Command Code plans. |
reqshape |
reqshape/ |
Measure the shape of your requests from opencode's own history, then price it against any model. |
| opencode-context | opencode-context/ |
opencode plugin: a /context dialog plus a context_breakdown tool showing where the window went. |
| opencode-shell-rc | opencode-shell-rc/ |
opencode plugin: make the agent's non-interactive zsh load your aliases and functions via a fast ZDOTDIR shim. |
| opencode-session-dir | opencode-session-dir/ |
opencode plugin: bind extra working directories to a single session, durably across restarts. |
Everything Command Code (commandcode.ai) usage lives under core/ + cmduse/ + opencode-plugin/: a terminal dashboard with a built-in MCP server, and an opencode provider. One Cargo workspace shares the plan table and window math via cmduse-core; the opencode plugin is a separate TS package that registers the providers and delegates usage rendering to the cmduse CLI. The three opencode-* plugins are opencode v2 plugins (server half, and a TUI half where needed). See each project's AGENTS.md for design rules and the traps found the hard way.
| Component | Crate / dir | Install | Docs |
|---|---|---|---|
cmduse CLI |
cmduse/ (crate cmd-usage, bin cmduse) |
crates.io · brew | cmduse/README.md · man page |
ocuse (same crate) |
cmduse/ (bin ocuse) |
same crate as cmduse |
OpenCode Go/Zen usage — Go's own usage endpoint plus local data — see below |
| Shared core | core/ (crate cmduse-core) |
crates.io | docs.rs/cmduse-core · versioned on its own 2.x line, not as a pair with the CLI |
| opencode plugin | opencode-plugin/ (@jeffreyjyz/opencode-command-code) |
npm | opencode-plugin/src/index.ts |
brew install JeffreyJYZ/tap/cmduse # macOS + Linux, prebuilt binary (no cargo)
cargo binstall cmd-usage # any platform, prebuilt from the release
cargo install cmd-usage # build from source (any platform)Then run cmduse for the live dashboard, or cmduse plans / cmduse models.
cmduse model [--days N | --since ISO] [--json] reports local per-model usage; without a window it is all-time, so pass one when you mean a billing period. --json includes source and since. There is no account-side per-model endpoint (the API only exposes totals), so local logs are the only per-model source and may miss other machines or harnesses.
cargo build --bin cmdusedev builds the same program under a different name, so a local build never shadows the Homebrew-installed cmduse. Tools that shell out can target it via CMDUSE_BIN=/path/to/cmdusedev. Full usage, config, and statusline docs live in cmduse/README.md.
cargo build # all Rust crates
cargo test # core + cli (host tests)
cargo fmt --all -- --check # formatting (CI gate)
cargo clippy --all-targets -- -D warnings
cargo package -p cmduse-core --allow-dirty # ships plans.json+gating.json
bun install # every TS package (npm workspaces)
bun test # workspace tests, incl. opencode conformance vectors
bun run extract # regen core/gating.json (needs CLI)Shared truth lives in core/: plans.json (plan table/caps), gating.json (model categories + per-plan access), conformance.json (behavior vectors). core/build.rs bakes plans/gating into Rust consts; the opencode plugin's model-gating layer imports gating.json and asserts the gating subset of the vectors (usage/window math is the Rust core's alone since plugin 0.2.0).
Providers (command-code-anthropic, command-code-openai), a live gated model list, /cmd-usage (TUI slash command), and the cmd_usage and mpc_prices tools — for both opencode v1 (≥1.18.29) and v2 (≥2.0.0) from one package.
Requires the cmduse CLI (usage windows/pace rendering live in the Rust core — the plugin spawns it):
brew install JeffreyJYZ/tap/cmduseThe cmd_usage tool spawns cmduse; the mpc_prices tool (per-model price comparison across the Command Code and OpenCode Go plans) spawns mpc:
bun add -g @jeffreyjyz/mpcInstall (opencode v2 uses plugins; v1's singular plugin is auto-normalized):
{
"plugins": ["@jeffreyjyz/opencode-command-code"]
}Auth, in host order: opencode's own connection — /connect and pick "Command Code" (or the CMD_API_KEY env method) — then our fallback ~/.commandcode/auth.json from cmd login. With no credential at all the providers stay activation: "auto", so a later /connect lights them up without a restart.
Vision models (Claude, Gemini, GPT, Qwen, the DeepSeek -vision- ones) accept image attachments; text-only models do not. The per-model list is generated from Command Code's own CLI table — the listing API publishes no capabilities.
While a session uses a command-code* model — or an OpenCode Go/Zen one — the session sidebar grows a section (toggle with ctrl+x b):
- plan, price and monthly credits used
- 5-hour and weekly windows: used / cap, percent used and elapsed, reset countdown; when the current burn rate would reach the cap before the reset it says
cap in …instead of the elapsed share, and an over-cap window is flaggedLIMIT EXCEEDED(both new in 0.3.12) - this period's requests and spend
- the active model: tier, monthly allowance, $/M rates on one line (in/out plus cache read, and cache write when the model has one), Intelligence, Tok/s (new in 0.2.5)
- the cheapest plan that serves it (
Min plan), from Command Code's own model table — the column their docs name as the access rule; shown only when the tier is unknown (new in 0.3.2, fallback-only since 0.3.6) - the active model's own period usage — requests, plus spend and its share of the session when the harness records them (new in 0.2.9, spend share in 0.3.15; labelled
Usage (this model)) - a running promotion on the active model (
Deal: badge plus expiry, new in 0.3.14) - this session's own totals (
Session), so mid-conversation you see what the conversation has cost rather than only the period-to-date figure (new in 0.3.12) - on OpenCode Go/Zen sessions: the same shape from
ocuse— the three windows come from OpenCode Go's own usage endpoint (the numbersopencode.ai/consoleshows: the 5-hourrollingblock, the Monday-anchored week, the billing month, each with the server's reset), and the per-model spend,Usage (this model)andSessionfigures come from opencode's own store, plus rates and benchmarks from mpc's OpenCode side (new in 0.3.12). The allowance shown is the selected Go plan's limit: Go and Go Plus share token prices but grant different per-model limits, and the endpoint reports percentages rather than a plan id, so set it (below). A free/unbounded model readsAllowance: ∞rather than a money figure. With no Go key, no network, or--no-api, the windows fall back to the local estimate — each window's share of the model's per-model allowance (5h 20%, weekly 50%, monthly 100%), with the 5-hour/Weekly reset derived from the oldest request still inside the window — and the panel then shows money rows rather than the account's shares.
Usage comes from the cmduse CLI (polled every 5s); the model catalog comes from mpc --json, cached for 1h and re-read on every poll, so a new model or promotion reaches a running panel — install it with bun link in the oc-cmd-compare package, or the section keeps the model name and the store-backed rows and simply omits the catalog rows (tier, rates, allowance). The model's own usage is read from opencode's message store (~/.local/share/opencode/opencode.db, read-only); CommandCode is subscription-billed, so spend appears only when the harness priced the turns (a free or unpriced model keeps requests only). Non-CommandCode models show nothing.
Both blocks remember their last reading, so a remount or a session switch repaints instead of blanking while the next poll runs. The per-model figure is keyed by model, so switching models shows that model's own row (or nothing yet) rather than the previous model's numbers. A network outage is handled the same way: cmduse -1 --json exits 0 even with the account API unreachable, carrying an error and the defaults ("Free", no windows) — the panel detects that and keeps the last good reading instead of flickering, and the model block keeps its last catalog so the model part does not vanish while mpc is unreachable (new in 0.3.18).
The section is plain text unless you ask for colour. To turn it on, write ~/.config/opencode/command-code.json:
{ "colors": true, "ocPlan": "go-plus" }CMD_COLORS=1 (or 0) overrides colour for a single run; ocPlan is the OpenCode Go plan the panel reads per-model limits from — go (default) or go-plus, since the two share token prices but grant different limits and nothing local records which one you have (CMD_OC_PLAN=go|go-plus overrides it per run). An unknown plan falls back to go with a warning. The file is re-read every few seconds, so flipping it lands on the next poll without a restart.
opencode is told each model's published $/1M rates, so its own cost display (and any accounting built on it) works for CommandCode models instead of showing $0.
For the fastest startup, pin the plugin to an exact version in opencode.json:
{ "plugins": ["@jeffreyjyz/opencode-command-code@<version>"] }A bare name makes opencode re-resolve @latest (a registry round-trip) on every start; a pinned specifier is cached as-is, and the plugin's own provider is versioned with it. Take <version> from npm view @jeffreyjyz/opencode-command-code version — never copy a number into this page.
ocuse tracks what you actually ran on OpenCode Go (the Go subscription) and OpenCode Zen (pay-as-you-go), using the same CLI shape as cmduse:
ocuse # watch: live frame (colour, gauges, spend-burst sparkline)
ocuse -1 # one-shot dashboard
ocuse --json
ocuse daily|hourly|session
ocuse model [id]
ocuse plans # the docs catalogue: both plans' limits and rates
ocuse statusline
ocuse mcp # MCP stdio serverTwo differences from cmduse are worth knowing up front, both from upstream:
- Go has a usage API, and
ocusereads it.GET https://opencode.ai/zen/go/v1/usage(the credential/connectstored, orOCUSE_API_KEY/OPENCODE_API_KEY) answers the console's three meters —rolling(5-hour),weeklyandmonthly, each a percent and a reset instant. Those are the only window figures that agree withopencode.ai/console, because the server's windows are not local ones: its 5-hour window is a block with its own reset, its week is anchored to Monday 00:00 UTC, its month is the subscription anniversary, and it meters with its own price basis. Everything else — per-model totals,daily/hourly, the model table — comes from local usage: opencode.db, which recordscost, tokens and the model for every request, for both providers. With no key, no network, or--no-api, the windows fall back to a local estimate and the dashboard says so. - Go's allowance is per model, not per account: each model has a monthly dollar limit, with windows of 5h = 20%, weekly = 50%, monthly = 100%. The dashboard shows each model against its own limit, and the header's window lines sum the caps of the models you used. Go ships two plans — Go ($10/mo) and Go Plus ($40/mo) — with the same token prices but different per-model limits; nothing local records which one you have (the subscription lives in the console, and the usage endpoint reports percentages rather than a plan id), so select it with
--plan go|go-plus(defaultgo).
The monthly period comes from the endpoint's own reset instant when it answers (the billing anniversary, which is why the dashboard reads Go billing month); without it the default is the calendar month, --period-start YYYY-MM-DD pins a real one and --window all|<n>d reports other ranges (inference from your first Go request exists behind --infer-anniversary, but it guesses wrong on sparse history).
Limits and rates come from core/zen.json, regenerated with bun scripts/extract-zen.ts from OpenCode's own docs sources.
The watch frame is cmduse's: the same palette, severity-coloured gauges (green <70%, yellow 70–90%, red ≥90%), an over-cap window flagged LIMIT EXCEEDED, and in-place redraw, so resizing or a shrinking frame never scrolls. A model over any of its own windows carries the same flag beside its name — Go meters per model and per window, so being over the 5-hour cap counts like being over the month — and every row ends with that model's share of the period's spend. A spend-burst sparkline appears once the 5-hour window moves between refreshes (delta spend, not the cumulative figure — that only ever rises). Every subcommand colours the same way — daily, hourly, session, model, plans and statusline included, with secondary text dimmed and figures in cyan. --plain, NO_COLOR and a piped stdout drop the colour and the gauges, so scripted output stays escape-free.
cmduse mcp runs an MCP stdio server (hand-rolled JSON-RPC, no extra deps) exposing seven tools: usage (dashboard), plans (comparison table), models (live gated list), daily, hourly, session (by project) and model (by model) — the same output the CLI subcommands print, with auth and ~/.commandcode/auth.json shared.
Zed (~/.config/zed/settings.json):
{
"context_servers": {
"cmduse": { "source": "custom", "command": "cmduse", "args": ["mcp"] }
}
}Any other MCP host: run cmduse mcp as a stdio server. The opencode plugin doesn't need it — it registers its own providers and spawns cmduse directly.
MIT — each package ships its own: cmduse/LICENSE-MIT, core/LICENSE-MIT, and a LICENSE in every TypeScript package (opencode-plugin, oc-cmd-compare, reqshape, opencode-context, opencode-shell-rc, opencode-session-dir).