Plugin Runtime
Plugin Runtime protocol schemas
Plugin Runtime Management Protocol
Defines the protocol for dynamic plugin loading, unloading, and discovery
at runtime. Addresses the "Dynamic Loading" gap in the microkernel architecture
by enabling plugins to be loaded and unloaded without restarting the kernel.
Inspired by:
-
OSGi Dynamic Module System (bundle lifecycle)
-
Kubernetes Operator pattern (reconciliation loop)
-
VS Code Extension Host (activation events)
This protocol enables:
-
Runtime load/unload of plugins without kernel restart
-
Plugin discovery from registries and local filesystem
-
Activation events (load plugin only when needed)
-
Safe unload with dependency awareness
Source: packages/spec/src/kernel/plugin-runtime.zod.ts
TypeScript Usage
import { ActivationEventSchema, DynamicLoadRequestSchema, DynamicPluginOperationSchema, DynamicPluginResultSchema, DynamicUnloadRequestSchema, PluginSourceSchema } from '@objectstack/spec/kernel';
import type { ActivationEvent, DynamicLoadRequest, DynamicPluginOperation, DynamicPluginResult, DynamicUnloadRequest, PluginSource } from '@objectstack/spec/kernel';
// Validate data
const result = ActivationEventSchema.parse(data);ActivationEvent
Lazy activation trigger for a dynamic plugin
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| type | Enum<'onCommand' | 'onRoute' | 'onObject' | 'onEvent' | 'onService' | 'onSchedule' | 'onStartup' | 'onMetadataType' | 'onView'> | ✅ | Trigger type for lazy activation |
| pattern | string | ✅ | Match pattern for the activation trigger |
DynamicLoadRequest
Request to dynamically load a plugin at runtime
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| pluginId | string | ✅ | Unique plugin identifier |
| source | { type: Enum<'npm' | 'local' | 'url' | 'registry' | 'git'>; location: string; version?: string; integrity?: string } | ✅ | Plugin source location for dynamic resolution |
| activationEvents | { type: Enum<'onCommand' | 'onRoute' | 'onObject' | 'onEvent' | 'onService' | 'onSchedule' | 'onStartup' | 'onMetadataType' | 'onView'>; pattern: string }[] | optional | Lazy activation triggers; if omitted plugin starts immediately |
| config | Record<string, any> | optional | Runtime configuration overrides |
| priority | integer | ✅ | Loading priority (lower is higher) |
| sandbox | boolean | ✅ | Run in an isolated sandbox |
| timeout | integer | ✅ | Maximum time to complete loading in ms |
DynamicPluginOperation
Runtime plugin operation type
Allowed Values
loadunloadreloadenabledisable
DynamicPluginResult
Result of a dynamic plugin operation
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| success | boolean | ✅ | |
| operation | Enum<'load' | 'unload' | 'reload' | 'enable' | 'disable'> | ✅ | Runtime plugin operation type |
| pluginId | string | ✅ | |
| durationMs | integer | optional | |
| version | string | optional | |
| error | { code: string; message: string; details?: Record<string, any> } | optional | |
| warnings | string[] | optional |
DynamicUnloadRequest
Request to dynamically unload a plugin at runtime
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| pluginId | string | ✅ | Plugin to unload |
| strategy | Enum<'graceful' | 'forceful' | 'drain'> | ✅ | How to handle in-flight work during unload |
| timeout | integer | ✅ | Maximum time to complete unloading in ms |
| cleanupCache | boolean | ✅ | Remove cached code and assets after unload |
| dependentAction | Enum<'cascade' | 'warn' | 'block'> | ✅ | How to handle plugins that depend on this one |
PluginSource
Plugin source location for dynamic resolution
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| type | Enum<'npm' | 'local' | 'url' | 'registry' | 'git'> | ✅ | Plugin source type |
| location | string | ✅ | Package name, file path, URL, or git repository |
| version | string | optional | Semver version range (e.g., "^1.0.0") |
| integrity | string | optional | Subresource Integrity hash (e.g., "sha384-...") |