OpenCode TUI status plugin plus a TypeScript diagnostic renderer. The plugin shows ChatGPT/OpenAI account usage limits in OpenCode's right-side prompt slots without injecting anything into the model prompt or conversation transcript.
OpenCode TUI prompt footer slot:
Build · gpt-5.5 openai ⎇ feature +10 -20 ?3 ↑1 ↓5 · 5h 23% · weekly 4%
- OpenCode-first.
npm run install:opencodebuilds and installs the compiled OpenCode plugin artifact. - UI-only. Status text is rendered in OpenCode's TUI slots, not sent to the model.
- TypeScript-only runtime. Bash, MJS,
jq, and shell widget/theme compatibility were removed. - Fail-open. Missing auth, network errors, or unexpected payloads silently hide the affected status fragment.
- Node.js 22+.
- OpenCode with TUI plugin support.
git clone https://github.com/uplift-labs/ai-cli-status-bar.git
cd ai-cli-status-bar
npm ci
npm run install:opencode
The installer compiles TypeScript into dist/, stages runtime files in
~/.local/share/ai-cli-status-bar/, writes an ai-statusbar Node shim in
~/.local/bin/, copies the compiled TUI plugin into
${OPENCODE_CONFIG_DIR:-~/.config/opencode}/plugins/ai-cli-status-bar/, and
patches ${OPENCODE_TUI_CONFIG:-${OPENCODE_CONFIG_DIR:-~/.config/opencode}/tui.json}:
{
"plugin": ["./plugins/ai-cli-status-bar/plugin"]
}The installer also adds missing @opentui/core, @opentui/solid, and
solid-js dependencies to the same config directory's package.json while
preserving existing versions.
Restart OpenCode after installing so it reloads the plugin.
npm run build
node dist/cli/install.js --scope=project --project-dir=/path/to/your/repo
Files land in <repo>/.uplift/ai-cli-status-bar/, the shim is written to
<repo>/.uplift/bin/ai-statusbar, and the plugin is copied to
<repo>/.opencode/plugins/ai-cli-status-bar/ with <repo>/.opencode/tui.json
patched to load it.
OpenCode itself uses the TUI plugin directly. The diagnostic entrypoint remains for manual checks and tests:
node dist/cli/ai-statusbar.js --adapter=opencode < tests/fixtures/opencode/tp-wham-usage.json
- Git branch and status:
+/-tracked line diff,?untracked file count, and↑/↓ahead/behind against the configured upstream. 5hand weekly account usage percentages fromhttps://chatgpt.com/backend-api/wham/usage.- Optional terminal title state: idle, working, waiting, done, or error.
The git widget shows ?N only when untracked files exist. It always shows
↑N ↓N when the current branch has an upstream; branches without upstream show
no upstream instead. The plugin never runs git fetch; behind counts reflect
the local remote-tracking ref OpenCode already has.
Successful usage responses are cached for 5 minutes by default in a shared
filesystem cache so multiple OpenCode windows do not stampede the usage endpoint.
Tune with AISB_OPENCODE_USAGE_CACHE_MS,
AISB_OPENCODE_USAGE_FAILURE_BACKOFF_MS, AISB_OPENCODE_USAGE_TIMEOUT_MS, and
AISB_OPENCODE_USAGE_CACHE_FILE.
Disable terminal title/bell side effects with:
AISB_OPENCODE_TAB_STATUS=0 opencode
See adapters/opencode/README.md and docs/OPENCODE_TAB_STATUS.md for details.
The OpenCode plugin is configured with environment variables:
| Variable | Effect |
|---|---|
AISB_OPENCODE_USAGE_CACHE_MS |
Successful usage cache TTL. |
AISB_OPENCODE_USAGE_FAILURE_BACKOFF_MS |
Backoff after failed usage requests. |
AISB_OPENCODE_USAGE_TIMEOUT_MS |
Usage request timeout. |
AISB_OPENCODE_USAGE_CACHE_FILE |
Override shared usage cache path. |
AISB_OPENCODE_GIT_TIMEOUT_MS |
Git command timeout. |
AISB_OPENCODE_GIT_STATUS_CACHE_MS |
Git status cache TTL. |
AISB_OPENCODE_BRANCH_REFRESH_MS |
Git status refresh interval. |
AISB_OPENCODE_TAB_STATUS |
Set to 0 or off to disable terminal title and bell side effects. |
AISB_OPENCODE_TAB_SOUND |
Comma-separated sound events: waiting, complete, or off. |
AISB_OPENCODE_TAB_TEMPLATE |
Terminal title template, default {icon} {project}. |
The diagnostic renderer supports AISB_DISABLE, AISB_THEME,
AISB_DISABLE_WIDGET_<NAME>, AISB_CTX_WARN, AISB_CTX_CRIT,
AISB_TASK_MAX_LEN, and NO_COLOR.
src/adapters/opencode/plugin/index.tsx
| TypeScript build
v
dist/adapters/opencode/plugin/index.js
| OpenCode TUI slots + event subscriptions
v
OpenCode renders UI-only status text
The diagnostic renderer follows the same canonical data contract used by tests:
dist/cli/ai-statusbar.js --adapter=opencode
| stdin usage payload
v
src/adapters/opencode/adapt.ts
| canonical ai-statusbar/v1 object
v
src/core/render.ts -> rendered line
npm ci
npm test # build + node:test TypeScript suite
npm run typecheck # TypeScript typecheck
npm run package # build npm release tarball under dist/