Skip to main content

Plugin SDK and Lifecycle

The main SDK for plugin authors is @codebolt/plugin-sdk. It is not the same as the client SDK used for custom frontends. Plugins are server-side extensions that connect back to the application runtime.

Core Runtime Model

The default export is a singleton PluginClient:

import plugin from '@codebolt/plugin-sdk';

The PluginClient establishes two WebSocket connections to the server:

  1. Channel 1 (/plugin) — command/response pattern via cliLib modules (same as agents use)
  2. Channel 2 (/multiplexed) — real-time push events via SocketConnectionManager

This dual-channel design gives plugins both request/response capabilities and live event streaming.

Plugin Context

When onStart fires, the plugin receives context:

interface PluginContext {
pluginId: string; // Unique plugin identifier
pluginDir: string; // Absolute path to plugin directory
manifest: any; // Parsed codebolt.plugin manifest from package.json
}

Lifecycle Hooks

import plugin from '@codebolt/plugin-sdk';

// Called when WebSocket connection is ready (before start message)
plugin.onReady(async () => {
console.log('WebSocket connected');
});

// Called when server sends pluginStartMessage with context
plugin.onStart(async (ctx) => {
console.log(`Started: ${ctx.pluginId} in ${ctx.pluginDir}`);
// Register providers, set up listeners, load config, etc.
});

// Called when server requests shutdown (before process kill)
plugin.onStop(async () => {
console.log('Stopping - cleaning up resources');
// Unregister providers, close connections, save state
});

// Listen to any raw WebSocket message (advanced use)
plugin.onRawMessage(async (message) => {
console.log('Raw message:', message);
});

Lifecycle sequence:

Process spawned → WebSocket connects → onReady()
→ Server sends pluginStartMessage → onStart(ctx)
→ ... plugin operates ...
→ Server sends pluginStopMessage → onStop()
→ Process receives SIGTERM → exit

Access Patterns

The SDK provides three main ways to interact with the application:

1. WebSocket Modules (cliLib)

Direct runtime modules for server operations. These use the /plugin WebSocket channel:

CategoryModules
Filesystem & Projectfs, git, project, projectStructure, codebaseSearch, codemap, environment
Terminal & Executionterminal
Chat & Communicationchat, browser
AI & LLMllm, llmProvider
Data & Stateknowledge, vectordb, kvStore, memory, cbstate
Tasks & Worktask, thread, todo, job
UIdynamicPanel
Integrationscalendar, mail, mcp, hook, eventLog
Plugin-specificgateway, executionGateway, llmProvider
Debuggingdebug

Example:

// Read a file
const content = await plugin.fs.readFile('/path/to/file');

// Run a terminal command
const result = await plugin.terminal.executeCommand('npm test');

// Store persistent config
await plugin.kvStore.set('config', JSON.stringify(myConfig), {
instanceId: 'my-plugin',
namespace: 'config'
});

2. HTTP APIs

REST-style wrappers for stable CRUD operations:

APIPurpose
chatApiChat message operations
tasksApiTask CRUD
threadsApiThread management
projectsApiProject operations
systemApiSystem info & control
gitApiGit operations
jobsApiJob management
knowledgeApiKnowledge base
environmentsApiEnvironment management
fileApi / fileReadApiFile operations
calendarApiCalendar events
mailApiMail operations
kvStoreApiKey-value store
vectordbApiVector database
todosApiTodo items
hooksApiHook management

Example:

// Create a task via HTTP API
await plugin.tasksApi.create({ title: 'My Task', status: 'open' });

// Get project info
const project = await plugin.projectsApi.getActive();

3. Multiplexed Sockets (Real-time Push)

Subscribe to live event streams via the /multiplexed channel:

SocketEvents For
chatChat messages, typing indicators
tasksTask state changes
jobsJob progress updates
shellTerminal output streams
browserBrowser state changes
knowledgeKnowledge base updates
eventLogApplication events
projectStructureFile tree changes
editorEditor state
lspLanguage server events
systemAlertSystem notifications
backgroundAgentBackground agent status
capabilityCapability changes
orchestratorAgent orchestration events
agentDebugAgent debug info
aiTerminalAI terminal output

Example:

// Subscribe to chat events
plugin.sockets.chat.on('message', (msg) => {
console.log('New chat message:', msg);
});

// Subscribe to task updates
plugin.sockets.tasks.on('update', (task) => {
console.log('Task updated:', task);
});

Notifications

The SDK provides notification helpers:

plugin.notify.info('Plugin connected successfully');
plugin.notify.error('Failed to connect to external API');
plugin.notify.warn('Rate limit approaching');

Plugin-Specific Modules

These modules are unique to plugins (not available to agents):

Gateway (Chat Gateway Plugins)

plugin.gateway.registerChannel(request)
plugin.gateway.routeMessage(message)
plugin.gateway.onReply(callback)
plugin.gateway.onMessageToChannel(callback)
plugin.gateway.unregisterChannel()

Execution Gateway

plugin.executionGateway.claim()
plugin.executionGateway.relinquish()
plugin.executionGateway.onRequest(callback)
plugin.executionGateway.sendReply(requestId, result)
plugin.executionGateway.subscribe()
plugin.executionGateway.onNotification(callback)

LLM Provider

plugin.llmProvider.register(manifest)
plugin.llmProvider.unregister(providerId)
plugin.llmProvider.onCompletionRequest(callback)
plugin.llmProvider.onStreamRequest(callback)
plugin.llmProvider.onLoginRequest(callback)
plugin.llmProvider.sendChunk(requestId, chunk)
plugin.llmProvider.sendReply(requestId, response)
plugin.llmProvider.sendError(requestId, error)

Narrative (Workspace Sync)

plugin.narrative.importUnifiedBundle(params) // Import .tar.gz workspace bundle
plugin.narrative.exportUnifiedBundle(params) // Export workspace as bundle
plugin.narrative.createSnapshot(params) // Snapshot current state
plugin.narrative.checkoutSnapshot(params) // Restore from snapshot

Dynamic Panel

plugin.dynamicPanel.open(panelId, title, html, opts?)
plugin.dynamicPanel.update(panelId, html)
plugin.dynamicPanel.close(panelId)
plugin.dynamicPanel.send(panelId, data)
plugin.dynamicPanel.list()
plugin.dynamicPanel.onMessage(panelId, handler)
plugin.dynamicPanel.offMessage(panelId)

Client SDK vs Plugin SDK

@codebolt/client-sdk@codebolt/plugin-sdk
PurposeBuild standalone UIsExtend the application runtime
RunsIn browser/electron rendererAs a server-side child process
ConnectionConnects as a clientConnects as a trusted extension
AccessLimited to client-facing APIsFull access to all server subsystems

Triggers and Startup

TriggerBehaviorUse When
startupAuto-starts on server bootAlways-on integrations (LLM providers, cloud bridges)
manualUser must click StartOn-demand integrations (Telegram bot, Slack bot)
eventStarts when application event firesReactive plugins

See Also