Skip to main content

Plugin System Overview

Omniscribe's plugin system allows you to add support for new AI coding assistants. Each provider plugin teaches Omniscribe how to detect, launch, and interact with a specific CLI tool.

Plugin Types​

TypeDescription
providerBackend logic: CLI detection, command building, status parsing
frontendUI contributions: settings sections, themes, status renderers
bothCombined provider + frontend in a single package

Most provider plugins use type both since they need both backend logic and custom UI.

Architecture: Backend + Frontend Split​

A plugin has two independent lifecycles:

Backend (Electron Main Process)​

The backend plugin class extends BaseProviderPlugin and runs inside NestJS. It handles:

  • CLI detection — Is the AI tool installed? What version? Is the user authenticated?
  • Command building — What shell command starts a session? How to resume/fork?
  • Status parsing — Parse terminal output to detect session state (idle, working, needs input)
  • Usage data — Fetch and format API usage metrics (optional)
  • Session history — Read past session records from disk (optional)

Frontend (React Renderer)​

The frontend activation function runs in the React app and registers UI contributions:

  • Settings sections — Custom configuration panels in the settings page
  • Status renderers — Provider-specific icons and status indicators
  • Usage panels — Custom usage data visualization
  • Themes — Custom color themes
  • Terminal actions — Buttons in the terminal header
  • Menu items — Entries in action bar and "more" menus

Lifecycle Flow​

App Startup
→ Plugin loader reads manifest from package.json
→ Validates manifest, instantiates plugin class
→ Runs detectCli() to check if the AI tool is available
→ Calls activate(context) on the backend plugin

Frontend Ready (WebSocket connected)
→ Core sends plugin list to frontend
→ Frontend dynamically imports the plugin's frontend module
→ Calls frontendActivate(context) with registration methods
→ Plugin registers UI contributions via context.registerXxx()

Capabilities System​

Provider plugins declare their optional features via capabilities:

get capabilities(): ProviderCapabilities {
return {
supportsMcp: true, // Can provide MCP config
supportsUsage: true, // Can fetch usage data
supportsSessionHistory: false, // Can read past sessions
supportedOperations: new Set(['resume', 'continue']),
};
}

The core only calls optional methods when their corresponding capability is enabled. This allows minimal providers to implement just 3 methods while full-featured providers can implement all 10+.

Plugin SDK (@omniscribe/ui)​

Plugin frontend code imports UI components from @omniscribe/ui, which provides access to the same design system as the core app:

  • UI components — Button, Card, Badge, Tooltip, Popover, Dialog, Select, Tabs, etc.
  • Utilities — cn() for class name merging
  • Socket helpers — emitAsync(), getSocket() for backend communication
  • Shared components — UsageCard, ProgressBar

Reference Implementations​

Two complete reference plugins ship with Omniscribe:

  • provider-claude — Full-featured Claude Code integration (all capabilities enabled)
  • provider-codex — OpenAI Codex integration (simpler, no session history)

Next Steps​