Extension Platform
Overview
OpenConduit has a first-class extension system modeled loosely after VS Code's contribution model. Extensions declare what they provide via a manifest — the runtime activates them and routes their contributions into the appropriate registries.
What Extensions Can Do Today
- Contribute sidebar panels via the ActivityBar (Phase 1 & 2 of #38 — live in
@openconduit/corev2.0.0+) - Register commands (show in command palette, bind keyboard shortcuts)
- Register slash commands (inline
/commandautocomplete in the chat input) - Contribute settings (schema-driven UI in the Settings panel)
- Add bottom panel tabs
- Add notification messages (via
addNotificationover IPC) - Use the
ExtensionAPIin anactivate(api)hook to read/write conversations, settings, UI state, and shared stores (#55) - Register AI tools that the language model can call — implemented as plain renderer-side JavaScript functions, no MCP server required
- Contribute main views that replace the chat pane with a full-screen component (e.g. Compare Models)
- Contribute split pane views rendered alongside chat in the right split pane
- Contribute secondary sidebar panels as additional tabs in the far-right panel
- Contribute status bar items rendered in the bottom status bar (Phase 3 — left or right aligned)
- Register Zustand store slices accessible to other extensions via
extensionRegistry.getStore(id)(Phase 3) - Attach message badges — per-message annotations rendered as pills in the message metadata row (Phase 3)
- Register conversation modes — plug in a custom send pipeline that replaces the default single-model send path (Phase 3)
How It Works
- An extension is a bundled JavaScript file (
dist/index.js) installed touserData/extensions/<id>/alongside amanifest.json. - On startup (and after a marketplace install)
loadInstalledExtensions()scans that directory, reads each bundle via the preload bridge, wraps it in a Blob URL, and dynamicallyimport()s it. - Each bundle calls
window.__openConduit.extensionRegistry.registerExtension(manifest, contributions)to declare its panels and other contributions. ActivityBarand other consumers subscribe to the registry and re-render reactively when a new extension registers.
Built-in Extensions
First-party features are implemented as built-in extensions registered at module-load time:
| Extension ID | Panel |
|---|---|
openconduit.personas | Personas panel (order 20) |
Registration APIs in Place
| Feature | Status |
|---|---|
extensionRegistry + ActivityBarContribution | ✅ Live — sidebar panel contributions |
commandRegistry + CommandContribution | ✅ Live — command palette + keybindings |
slashCommandRegistry + SlashCommand | ✅ Live — chat input / autocomplete |
settingsRegistry + SettingsContribution | ✅ Live — schema-driven settings UI |
bottomPanelRegistry + BottomPanelTab | ✅ Live — bottom panel tab registration |
addNotification in uiStore | ✅ Live — AppNotification.source carries extension id |
ExtensionAPI + activate(api) | ✅ Live — full runtime API surface (#55) |
api.tools.register() + contributes.tools | ✅ Live — renderer-side AI tool contributions |
MainViewContribution + contributes.mainViews | ✅ Live — full-pane view replacing ChatArea (#56) |
SplitPaneViewContribution + contributes.splitPaneViews | ✅ Live — right split pane views (#56) |
SecondarySidebarPanelContribution + contributes.secondarySidebarPanels | ✅ Live — secondary sidebar tabs (#56) |
StatusBarItemContribution + contributes.statusBarItems | ✅ Live — bottom status bar items, left/right aligned (#38 Phase 3) |
StoreSliceContribution + contributes.stores | ✅ Live — shared Zustand store slices (#38 Phase 3) |
MessageBadgeContribution + contributes.messageBadges | ✅ Live — per-message badge annotations (#38 Phase 3) |
ConversationModeContribution + contributes.conversationModes | ✅ Live — custom send pipeline override (#38 Phase 3) |
See Extension Manifest, Activity Bar, Commands, Slash Commands, Settings, Bottom Panel, View Contributions, Extension API, and Tool Contributions for the API reference.
