opencode
opencode copied to clipboard
Plugin API for custom sidebar panels
Summary
Provide an API that allows plugins to register custom sections/panels in the sidebar.
Motivation
Currently, plugins can extend OpenCode with tools, hooks, agents, and MCP configs - but have no way to surface custom UI in the sidebar. The sidebar is entirely controlled by OpenCode internals (MCPs, context usage, todos, etc.).
For plugins like oh-my-opencode, there are several things we'd want to display:
- Background agent task status (running/completed/failed)
- Custom metrics or state tracked by hooks
- Plugin-specific configuration status
- Agent availability/health indicators
Implemented API
// In @opencode-ai/plugin
interface SidebarPanelItem {
label: string
value?: string
status?: "success" | "warning" | "error" | "info"
}
interface SidebarPanel {
id: string
title: string
items: SidebarPanelItem[] | (() => SidebarPanelItem[])
}
interface Hooks {
// ... existing hooks
sidebar?: SidebarPanel[] | (() => SidebarPanel[])
}
Usage Example
import { definePlugin } from "@opencode-ai/plugin"
export default definePlugin({
name: "my-plugin",
hooks: {
sidebar: [
{
id: "status",
title: "My Plugin Status",
items: [
{ label: "Version", value: "1.0.0" },
{ label: "Status", value: "Active", status: "success" }
]
}
]
}
})
Dynamic Updates
Both sidebar and items can be functions for dynamic content. The sidebar polls every 5 seconds for updates:
hooks: {
sidebar: () => [{
id: "metrics",
title: "Live Metrics",
items: () => [
{ label: "Requests", value: String(requestCount) },
{ label: "Last Update", value: new Date().toLocaleTimeString() }
]
}]
}
Implementation Details
-
Server endpoint:
GET /plugin/sidebarreturns aggregated panels from all plugins - UI: Plugin panels render in the sidebar with collapse/expand support
- Polling: 5-second refresh interval with proper cleanup
- Error isolation: Individual plugin failures are logged but don't affect others