Get started
DeveloperPlugin SDK

Build plugins that feel native

Community plugins used to look like they were bolted on. The SDK overhaul changes that: every plugin now gets the glass design system, unified chat components, and server-side storage out of the box.

10 April 20267 min read
Abstract geometric puzzle pieces assembling into a glowing glass panel with purple and cyan crystalline surfaces

If you have built a Quox plugin in the last year, you know the problem. Your UI looked like a different product. Your chat sidebar was a copy of a copy. Your data disappeared when users cleared their browser. The platform gave you a container but not a toolkit.

This is what we set out to fix with the Plugin SDK overhaul. The goal was not just a cleaner API surface: it was to make the gap between a first-party Quox component and a community plugin invisible to the end user.

The result is a set of changes that run from the design system down to storage. If you build plugins, here is exactly what changed and how to use it.

The problem: 14 sidebars and no design system

When we audited the plugin ecosystem, we found 14 separate implementations of what was functionally the same component: a chat sidebar that let users talk to an agent in the context of the plugin's view. Each one had been written from scratch. Each one had slightly different spacing, different scroll behaviour, different loading states.

None of them used the glass design system because the glass design system was not exposed to plugins.

The deeper problem was architectural. Plugin code ran in a sandboxed React context. It had access to its own component tree and a narrow plugin API, but the platform's component library, GlassPanel, GlassPill, the tab bar, the progress ring, was compiled into the host bundle and not reachable. A plugin that wanted to match the dashboard's visual language had to reverse-engineer it by hand.

Storage was the other failure point. Plugins used localStorage for persistence. That worked well enough until a user cleared their browser, switched devices, or logged in from a new machine. The data was gone. For plugins that tracked state across sessions, configuration, user preferences, run history, this was a real problem for anyone running Quox in an enterprise context.

The model: externalise the design system at runtime

The solution we reached for is the same model Grafana uses for its plugin ecosystem. Grafana ships @grafana/ui as a versioned component library that plugins declare as a peer dependency. At build time, the dependency is externalised, the plugin bundle does not include a copy of it. At runtime, the host application provides the library through a shared global.

We did the same thing with the Quox glass design system. The platform now exposes it at window.__quoxGlass. Plugin bundles declare @quox/glass as an external peer dependency. The SDK build config handles the externalisation automatically, so plugin developers do not need to configure anything, they import from @quox/glass as normal, and at runtime the platform provides it.

This keeps plugin bundles small and ensures all plugins on the same platform version get identical, pixel-consistent components. The design system is maintained in one place. It versions with the platform. Plugins get it for free.

What was built

AgentChatSidebar. One component replaces all 14 sidebar implementations. Pass it an agentId, optional contextBuilder function, and suggestions. Auth, workspace context, and LLM routing are handled automatically. The contextBuilder prop is a function that receives the current plugin state and returns a string. This gets injected into the agent's system context so the agent knows what the user is looking at.

AgentChatPanel. The full ChatTab wrapper for plugins that want a rich, multi-tab chat interface rather than a narrow sidebar. Auto-wires auth, workspace, and LLM routing the same way. Use this when the chat experience is the primary view of your plugin, not a secondary panel beside other content.

@quox/glass via window.__quoxGlass. Six components are now available to every plugin at runtime, with more to follow:

  • GlassPanel: frosted glass card with border and backdrop blur
  • GlassPill: status badge with accent colour and subtle glow
  • GlassTabBar: tab navigation with active state and transition
  • ProgressRing: circular progress indicator with configurable radius
  • Sparkline: lightweight inline chart for metric trend display
  • MarkdownContent: styled markdown renderer matching dashboard prose

Runtime agent registration. Plugin manifests can now declare agents, personas, and delegator keywords. When the plugin installs, the platform registers the agents automatically, no manual wiring required. The agent is available in every context where the platform routes delegation, including the CommanderQ assistant. Delegator keywords let users trigger your agent through natural language.

If your manifest declares keywords: ["analyse my data", "run analysis"], the platform routes those phrases to your agent without any additional configuration.

Server-side plugin storage. Plugin data now lives in SQLite on the server, not in the browser's localStorage. Data survives browser clears, is consistent across devices, and is backed up as part of the standard platform backup cycle. The API is the same key-value interface: replace localStorage.setItem with pluginApi.storage.set.

New pluginApi methods.

  • pluginApi.navigate(path): navigate to any dashboard route from plugin code
  • pluginApi.getUser(): get the current authenticated user and workspace
  • pluginApi.chat.openSidebar(agentId): programmatically open a chat sidebar for a given agent

Before and after

AreaBeforeAfter
Chat sidebar14 hand-rolled copies per plugin, no shared logic, inconsistent UX<AgentChatSidebar agentId="..." suggestions={[...]} />, one line
Design system accessRaw React only. No glass panels, no pills, no charts. Plugins looked foreign.window.__quoxGlass exposes GlassPanel, GlassPill, ProgressRing, Sparkline, and more at runtime
StoragelocalStorage. Cleared on browser reset, invisible across devices.SQLite via pluginApi.storage. Survives browser clears, works across sessions.
Agent registrationManual wiring, no install-time delegation, no persona supportManifest declares agents, personas, delegator keywords. Platform registers on install.
NavigationNo programmatic navigation from plugin codepluginApi.navigate(), pluginApi.chat.openSidebar(), pluginApi.getUser()

What a plugin developer writes now

This is a complete plugin view. No custom sidebar code, no hand-rolled glass components, no localStorage calls. The design system components come from the platform. The chat component wires itself.

jsx
const { AgentChatSidebar, GlassPanel, GlassPill, COLORS } = window.__quoxGlass;

function MyPluginView() {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 300px' }}>
      <GlassPanel>
        <h2>My data view</h2>
      </GlassPanel>
      <AgentChatSidebar
        agentId="my-agent"
        suggestions={['Show me the data', 'Run analysis']}
      />
    </div>
  );
}

The GlassPanel uses the same frosted glass treatment as every other card in the dashboard. The AgentChatSidebar connects to the LLM routing layer, handles auth, and renders with consistent spacing and typography. There is nothing in this component tree that a user would identify as "third-party".

The /quox-plugin skill: scaffold to install without leaving your editor

One addition that has meaningfully changed the development loop is the /quox-plugin skill for Claude Code. It handles the full plugin development lifecycle from inside your editor session.

  1. Scaffold. Generates the plugin directory structure, manifest, entry point, and example view. Follows the current SDK conventions automatically.
  2. Develop. Provides component suggestions, manifest editing, and debugging guidance. Knows which glass components are available and how the plugin API works.
  3. Build. Runs the SDK build with correct externalisation config. Confirms that @quox/glass is excluded from the bundle as expected.
  4. Install. Installs the built plugin into a running QuoxCORE instance and verifies registration. Shows the plugin in the marketplace listing if configured.

The skill is available to any developer running Claude Code against a Quox repository. It is the fastest path from idea to installed plugin, typically under ten minutes for a basic data-and-chat layout.

What comes next

The SDK overhaul is the foundation. A few things are coming in the near term.

  • AgentChatPage. A full-screen chat plugin type for plugins where the agent conversation is the entire experience, not a sidebar panel. Useful for specialised assistants that need the full viewport.
  • More glass components. The current six components cover the most common plugin patterns. The next batch covers data tables, timeline views, and notification toasts, the components that most frequently get hand-rolled in plugin code today.
  • Marketplace publishing from the CLI. The /quox-plugin skill will gain a publish step that handles version bumps, changelogs, and submission to the Quox Marketplace without leaving Claude Code. The SDK build already produces the required manifest format, the publish step just needs the submission API wired up.

The updated SDK is in private preview and is not on npm yet. The documentation covers the manifest format, the available glass components, and the plugin API in full. If you have an existing plugin, the migration guide covers the three main changes: replacing localStorage calls, swapping in AgentChatSidebar, and updating your manifest for agent registration.

Get started

Deploy QuoxCORE, free, self-hosted

AI agent orchestration with built-in governance. Docker Compose up and running in under five minutes.