UI Extensions
A UI extension is a plugin that renders an interactive panel inside the Codebolt app. The panel is a plain HTML file — you can use any markup, styles, and JavaScript. Codebolt renders it in a sandboxed iframe and provides a messaging bridge for bidirectional communication with your plugin backend.
When to Write a UI Extension
- You need a settings or configuration panel for your plugin.
- You want a dashboard showing agent metrics, task progress, or system status.
- You're building a domain-specific view (DB browser, design token viewer, channel configuration).
- You need a human-in-the-loop workflow (approval dialogs, review panels).
How It Works
- Your plugin declares a UI path in
package.json. - The Codebolt app discovers plugins with UIs and shows an "Open" button.
- When the user clicks "Open", the server fetches the HTML, injects a messaging bridge, and serves it.
- The app renders the HTML in a sandboxed iframe.
- Your plugin backend and the panel communicate via bidirectional messaging.
- If the plugin isn't running, the server auto-starts it when the UI is opened.
Plugin Configuration
Declare the HTML file path in your plugin's package.json:
{
"name": "my-plugin",
"version": "1.0.0",
"main": "dist/index.js",
"codebolt": {
"plugin": {
"ui": {
"path": "./ui/default/index.html"
},
"triggers": [{ "type": "manual" }]
}
}
}
codebolt.plugin.ui.path— path to the HTML file, relative to the plugin directory.- The panel ID is automatically derived:
plugin-ui-my-plugin.
Panel-Side API (codeboltPlugin)
Codebolt injects a global codeboltPlugin object into your HTML — no imports needed.
| Method | Direction | Description |
|---|---|---|
codeboltPlugin.sendMessage(data) | Panel to Plugin | Send a JSON message to the plugin backend |
codeboltPlugin.onMessage(handler) | Plugin to Panel | Register a handler for incoming messages |
codeboltPlugin.offMessage(handler) | — | Remove a previously registered handler |
codeboltPlugin.pluginId | — | The plugin's ID (read-only) |
Plugin Backend API
The Plugin SDK provides methods for the backend to communicate with the panel:
| Method | Direction | Description |
|---|---|---|
plugin.dynamicPanel.send(panelId, data) | Plugin to Panel | Send a JSON message to the panel |
plugin.dynamicPanel.onMessage(panelId, handler) | Panel to Plugin | Listen for messages from the panel |
plugin.dynamicPanel.offMessage(panelId) | — | Remove the message handler |
Asset Serving
The server injects a <base> tag into your HTML so relative paths resolve correctly. CSS, JS, and images within your plugin directory are served automatically.
You can use any frontend framework — just build it to static HTML, CSS, and JS files.
Under the Hood
Discovery
The server scans three locations for plugins:
- Built-in plugins shipped with Codebolt.
- Global plugins at
~/.codebolt/plugins/. - Per-project plugins at
.codeboltPlugins/.
Plugins with codebolt.plugin.ui.path in their package.json are marked as having a UI.
Serving
When the user opens a plugin UI:
- The app requests
GET /pluginui/:pluginId. - The server resolves the HTML file path from the plugin manifest.
- If the plugin isn't running, the server starts it as a child process.
- The server registers a panel subscription so messages route to the plugin.
- The server injects the
codeboltPluginbridge script and a<base>tag. - The HTML is returned to the app.
Rendering
The app renders the HTML in a sandboxed iframe:
sandbox="allow-scripts allow-forms allow-same-origin"
Message Routing
Panel HTML (iframe)
│ codeboltPlugin.sendMessage(data)
▼
DynamicPanelComponent → WebSocket → Server → Plugin Process
│ plugin.dynamicPanel.onMessage(panelId, handler)
The return path is the reverse: plugin.dynamicPanel.send() → server → WebSocket → iframe → codeboltPlugin.onMessage().
Security
- Path traversal prevention — resolved file paths must stay within the plugin directory.
- Iframe sandboxing — scripts, forms, and same-origin only; no navigation, popups, or modals.
- Plugin isolation — each plugin runs as a separate child process with its own token.
See Also
- Build Your First UI Extension — step-by-step tutorial
- Dynamic Panels — the panel system overview
- Plugins Overview — plugin development overview