An OpenCode plugin that drives a BUSY Bar hardware display with live AI session status.
┌──────────────────────────────────────────┐
│ ■ my-project session │ ← status dot + session title
│ working │ ← current tool or status
└──────────────────────────────────────────┘
What it does:
- Shows the current session title and status on the 72×16 LED display in real time
- Status dot changes colour: grey (idle) · purple (thinking) · blue (working) · amber (allow?) · green (done) · red (error)
- When OpenCode asks for a tool permission, the display blinks amber and lets you approve from the physical device — scroll the encoder to pick
once / always / reject, press OK to confirm - Receives live push events from OpenCode (no polling needed) via the plugin event API
- OpenCode installed and in
$PATH - Node.js or Bun for
npm install/bun install - A BUSY Bar connected over USB (
10.0.4.20) or Wi-Fi
# Inside any project where you use OpenCode
mkdir -p .opencode/plugins
cd .opencode/plugins
git clone https://github.com/YOUR_ORG/busybar-opencode.git
cd busybar-opencode
npm install # or: bun installThe plugin file lives at
.opencode/plugins/busybar-opencode/.opencode/plugins/busybar.ts. OpenCode scans.opencode/plugins/**/*.tsrecursively, so it will be picked up automatically.
Alternatively, copy just the single plugin file:
mkdir -p .opencode/plugins
curl -o .opencode/plugins/busybar.ts \
https://raw.githubusercontent.com/YOUR_ORG/busybar-opencode/main/.opencode/plugins/busybar.tsIf you copy the single file, make sure protobufjs is available in node_modules (needed for the BUSY Bar WebSocket decoder):
npm install protobufjs # or: bun add protobufjsCreate a .env in your project root (or export them in your shell):
BUSY_BAR_ADDR=http://10.0.4.20 # USB default; change for Wi-Fi
BUSY_HTTP_PASSWORD= # leave empty for USB; set for Wi-FiOptional:
BUSY_DISPLAY_PRIORITY=50
BUSY_APP_NAME=busybar-opencodeSee .env.example for a template.
opencodeOpenCode loads plugins from .opencode/plugins/ automatically. No extra flags needed.
Row 0 (y=0): [dot] session title (up to 13 chars)
Row 1 (y=9): tool name OR status label
| Status | Colour | Label |
|---|---|---|
| idle | grey | waiting |
| thinking | purple | thinking |
| running | blue | working |
| pending (permission) | amber (blinking) | allow? [once] |
| completed | green | done |
| error | red | error |
| Input | Action |
|---|---|
| Encoder CW | Cycle to next reply option (once → always → reject) |
| Encoder CCW | Cycle to previous reply option |
| BACK button | Jump to reject |
| OK button | Send the selected reply to OpenCode |
| Variable | Default | Description |
|---|---|---|
BUSY_BAR_ADDR |
http://10.0.4.20 |
HTTP address of your BUSY Bar |
BUSY_HTTP_PASSWORD |
(empty) | API password (Wi-Fi only; USB needs none) |
BUSY_APP_NAME |
busybar-opencode |
Application name shown in BUSY Bar UI |
BUSY_DISPLAY_PRIORITY |
50 |
Display layer priority (higher = on top) |
Copy and paste the following into OpenCode (or any AI coding assistant) to have it install the plugin automatically in your current project:
Install the busybar-opencode OpenCode plugin in this project.
Steps:
1. Create the directory .opencode/plugins/ if it does not exist.
2. Download the plugin file from:
https://raw.githubusercontent.com/Tresillo2017/busybar-opencode/main/.opencode/plugins/busybar.ts
and save it as .opencode/plugins/busybar.ts
3. Check if protobufjs is already in node_modules. If not, run:
npm install protobufjs (or bun add protobufjs if this project uses Bun)
4. Check if a .env file exists in the project root. If it does not, create one.
Add these lines only if they are not already present:
BUSY_BAR_ADDR=http://10.0.4.20
BUSY_HTTP_PASSWORD=
5. Confirm the plugin file is at .opencode/plugins/busybar.ts and print a
one-line summary of what was done.
Do not modify any existing source files. Do not commit anything.
The plugin is a single TypeScript file loaded by OpenCode at startup. It:
- Subscribes to OpenCode push events (
session.status,permission.asked,permission.replied) via the plugin event API — no database polling. - Opens a WebSocket to the BUSY Bar (
ws://{addr}/api/status/ws) to receive physical encoder and button input, decoded from binary protobuf using an inlined schema. - Sends display updates to the BUSY Bar HTTP API (
POST /api/display/draw).
The protobuf schema is inlined in the plugin file so there are no additional build steps or generated code.
MIT