opencode-dashboard
v0.3.0
Published
Real-time Kanban dashboard that visualizes OpenCode agent activity
Downloads
306
Maintainers
Readme
OpenCode Dashboard
A real-time browser-based Kanban board that visualizes agent activity in OpenCode. Watch beads (tasks) move through agent stages -- from ready to done -- as AI agents work on them. Columns are generated dynamically based on your configured agents.
Installation
- Add the plugin to your OpenCode config:
// opencode.json
{
"plugin": ["opencode-dashboard"]
}OpenCode will install the plugin automatically on next launch.
- Run the setup command to install slash commands and (optionally) agent definitions:
npx opencode-dashboard setupThis will prompt you to choose between global (~/.config/opencode/) or per-project (.opencode/) installation. It copies the /dashboard-start, /dashboard-stop, and /dashboard-status commands, plus the shipped agent definitions. Existing files are never overwritten.
Usage
Start the Dashboard
Use the slash command in OpenCode:
/dashboard-startOr use the CLI directly:
npx opencode-dashboard startThe dashboard will be available at http://localhost:3333.
After the first activation, the dashboard auto-starts on subsequent OpenCode sessions — you don't need to run /dashboard-start again. This works across terminals: if you open a second OpenCode session while the dashboard is already running, it connects automatically.
Check Status
/dashboard-statusOr via CLI:
npx opencode-dashboard statusStop the Dashboard
/dashboard-stopOr via CLI:
npx opencode-dashboard stopThis also disables auto-start — the dashboard will stay dormant on future sessions until you explicitly run /dashboard-start again.
Custom Port
npx opencode-dashboard start --port 4000Or set the DASHBOARD_PORT environment variable.
How It Works
The dashboard has three components:
OpenCode Plugin (plugin/index.ts)
|
| POST /api/plugin/event
v
Bun Server (server/index.ts)
|
| SSE /api/events
v
React Dashboard (dist/)- Plugin -- An OpenCode plugin that hooks into agent lifecycle events, discovers configured agents, tracks bead state via
bd list --json, and pushes structured events to the server. Registers custom tools (dashboard_start,dashboard_stop,dashboard_status,dashboard_open) for controlling the dashboard from within OpenCode. - Server -- A Bun HTTP server that aggregates state from connected plugins, persists it to disk, serves the dashboard frontend, and broadcasts updates to browser clients via Server-Sent Events (SSE). The server automatically shuts down after 5 minutes of inactivity (no connected plugins or browser clients) to avoid leaving orphaned processes. Multiple OpenCode sessions share a single server instance — it only shuts down when all sessions have disconnected.
- Dashboard -- A React SPA that renders a dynamic Kanban board with real-time updates, animated card transitions, and connection resilience.
Kanban Columns
Columns are generated dynamically based on your configured agents. Three fixed columns are always present:
| Column | Description | |--------|-------------| | Ready | Open beads not yet claimed by an agent | | Done | Bead closed successfully | | Error | Bead blocked, failed, or abandoned |
Agent columns appear between Ready and Done, one per discovered agent. For example, if you have orchestrator, pipeline-builder, pipeline-reviewer, and pipeline-committer agents configured, the board will show columns for each of them. Column colors are pulled from the agent's frontmatter color field when available.
Development
Prerequisites
- Bun >= 1.0
- OpenCode with plugin support
- A project using bd (beads) for issue tracking
Clone and Install
git clone https://github.com/GZakhar88/opencode-agents-dashboard.git
cd opencode-agents-dashboard
bun installRunning Locally (Frontend + Server only)
This starts the dashboard UI and server without the OpenCode plugin. Useful for working on the frontend or server code. No OpenCode or bd needed.
# Terminal 1: Start the Bun API server (port 3333)
bun run server
# Terminal 2: Start the Vite dev server with HMR (port 5173)
bun run devOpen http://localhost:5173. The Vite dev server proxies /api/* requests to the Bun server at localhost:3333. The board will show "No projects connected" until a plugin registers — you can test by sending events directly:
# Register a fake plugin
curl -X POST http://localhost:3333/api/plugin/register \
-H 'Content-Type: application/json' \
-d '{"projectPath": "/tmp/test", "projectName": "test-project"}'
# Returns: {"pluginId": "some-uuid"}
# Push an event (use the pluginId from above)
curl -X POST http://localhost:3333/api/plugin/event \
-H 'Content-Type: application/json' \
-d '{"pluginId": "PASTE_ID_HERE", "event": "bead:discovered", "data": {"bead": {"id": "test-1", "title": "Test bead", "status": "open", "priority": "medium"}}}'Running Locally (Full end-to-end with OpenCode)
This connects the plugin to a live OpenCode session so you can test the full pipeline: plugin hooks -> server -> dashboard.
Step 1: Symlink the plugin into your project
From the project directory where you run OpenCode (not this repo):
# Create the plugins directory if it doesn't exist
mkdir -p /path/to/your/project/.opencode/plugins
# Symlink the plugin entry point
ln -sf /path/to/opencode-agents-dashboard/plugin/index.ts \
/path/to/your/project/.opencode/plugins/dashboard.tsOpenCode auto-loads all .ts files from .opencode/plugins/ on startup. The symlink's relative imports resolve from the real file's location, so ../shared/types, ../server/pid, etc. all work.
Step 2: Install commands and agents
# From this repo's directory
bun run bin/cli.ts setupChoose "project" to install into /path/to/your/project/.opencode/, or "global" for ~/.config/opencode/. This copies the /dashboard-start, /dashboard-stop, /dashboard-status commands and agent definitions.
Step 3: Launch OpenCode and start the dashboard
# In your project directory
DASHBOARD_DEBUG=1 opencodeThen in the OpenCode TUI, type /dashboard-start. The plugin will spawn the Bun server and open the dashboard at http://localhost:3333.
DASHBOARD_DEBUG=1 enables verbose plugin logging to stderr — useful for seeing what the plugin is doing.
Step 4: (Optional) Run Vite dev server for frontend HMR
If you're working on the frontend and want hot-reload instead of the pre-built dist/:
# In this repo's directory
bun run devOpen http://localhost:5173 instead of :3333. Vite proxies API calls to the running Bun server.
Cleanup
To disconnect the plugin from your project:
rm /path/to/your/project/.opencode/plugins/dashboard.tsTesting
bun test| File | What it tests |
|------|---------------|
| src/hooks/useBoardState.test.ts | Board state reducer -- all 13 SSE event handlers |
| src/hooks/useEventSource.test.ts | SSE connection, backoff, retry logic |
| src/lib/format.test.ts | Formatting utilities (elapsed time, priority labels) |
| server/state.test.ts | Server state manager (event processing, persistence) |
| server/routes.test.ts | HTTP route handlers (register, event, heartbeat) |
| server/sse.test.ts | SSE client management and broadcasting |
| server/pid.test.ts | PID file and autostart marker management |
| server/diffBeadState.test.ts | Bead snapshot diffing algorithm |
Building
bun run build # Build the frontend (outputs to dist/)
bun run build:check # Run TypeScript type checkingEnvironment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| DASHBOARD_PORT | 3333 | Port for the dashboard server |
| DASHBOARD_DEBUG | (unset) | Set to 1 to enable verbose plugin logging to stderr |
| DASHBOARD_IDLE_TIMEOUT_MS | 300000 (5 min) | Idle auto-shutdown timeout in milliseconds. Set to 0 to disable |
Project Structure
opencode-dashboard/
├── agents/ # Shipped agent definitions (optional install)
│ ├── orchestrator.md
│ ├── pipeline-builder.md
│ ├── pipeline-refactor.md
│ ├── pipeline-reviewer.md
│ └── pipeline-committer.md
├── commands/ # Slash commands (installed via setup)
│ ├── dashboard-start.md
│ ├── dashboard-stop.md
│ └── dashboard-status.md
├── plugin/
│ └── index.ts # Main plugin entry (npm distribution)
├── server/
│ ├── index.ts # Server entry point (Bun.serve)
│ ├── routes.ts # HTTP route handlers (7 endpoints)
│ ├── sse.ts # SSE client management & broadcasting
│ ├── state.ts # State manager (events -> state, persistence)
│ ├── pid.ts # PID file management
│ └── PLUGIN_EVENTS.md # Event reference documentation
├── shared/
│ └── types.ts # Shared TypeScript types
├── bin/
│ └── cli.ts # CLI entry (npx opencode-dashboard)
├── src/ # React frontend source
│ ├── main.tsx
│ ├── App.tsx
│ ├── hooks/ # SSE connection, board state reducer
│ ├── components/ # Kanban board, cards, columns
│ └── lib/ # Utilities, constants, API client
├── plugins/
│ └── dashboard-bridge.ts # Local dev plugin (not published)
└── dist/ # Built frontend (generated by vite build)API Reference
Plugin API (used by the OpenCode plugin)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | /api/plugin/register | Register a plugin instance |
| POST | /api/plugin/event | Push an event |
| POST | /api/plugin/heartbeat | Send heartbeat |
| DELETE | /api/plugin/:id | Deregister a plugin |
Dashboard API (used by the frontend)
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /api/state | Full board state as JSON |
| GET | /api/events | SSE stream for real-time updates |
| GET | /api/health | Server health check |
Tech Stack
- Runtime: Bun
- Frontend: React 19, TypeScript 5.7
- Build: Vite 6
- Styling: Tailwind CSS 3.4, shadcn/ui
- Animation: Framer Motion 11.15
- State: React
useReducerwith SSE-driven updates - Transport: Server-Sent Events (SSE) with exponential backoff
Troubleshooting
Dashboard shows "No projects connected"
- Verify OpenCode is running with the plugin installed.
- Check that agents are configured (in
opencode.json,.opencode/agents/, or~/.config/opencode/agents/). Enable debug logging:DASHBOARD_DEBUG=1 opencode. - Confirm the server is reachable:
curl http://localhost:3333/api/health.
Beads not showing on the board
- Ensure the project uses
bdfor issue tracking (bd listshould return issues). - The plugin runs
bd list --jsonto discover beads. Ifbdis not installed or not initialized in the project, no beads will appear.
Server state persists across restarts
The server saves state to server/.dashboard-state.json. Delete this file to start fresh:
rm server/.dashboard-state.jsonDashboard keeps auto-starting (or won't auto-start)
The plugin stores an autostart marker at ~/.cache/opencode/opencode-dashboard.autostart. To reset auto-start behavior:
# Disable auto-start
rm ~/.cache/opencode/opencode-dashboard.autostart
# Or just run /dashboard-stop — it clears the marker for youIf the dashboard should auto-start but isn't, run /dashboard-start once to re-create the marker.
