opencode icon indicating copy to clipboard operation
opencode copied to clipboard

Plugin API for custom sidebar panels

Open z80dev opened this issue 4 weeks ago • 4 comments

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/sidebar returns 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

z80dev avatar Dec 22 '25 17:12 z80dev