@sparkleideas/plugins 3.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +401 -0
- package/__tests__/collection-manager.test.ts +332 -0
- package/__tests__/dependency-graph.test.ts +434 -0
- package/__tests__/enhanced-plugin-registry.test.ts +488 -0
- package/__tests__/plugin-registry.test.ts +368 -0
- package/__tests__/ruvector-bridge.test.ts +2429 -0
- package/__tests__/ruvector-integration.test.ts +1602 -0
- package/__tests__/ruvector-migrations.test.ts +1099 -0
- package/__tests__/ruvector-quantization.test.ts +846 -0
- package/__tests__/ruvector-streaming.test.ts +1088 -0
- package/__tests__/sdk.test.ts +325 -0
- package/__tests__/security.test.ts +348 -0
- package/__tests__/utils/ruvector-test-utils.ts +860 -0
- package/examples/plugin-creator/index.ts +636 -0
- package/examples/plugin-creator/plugin-creator.test.ts +312 -0
- package/examples/ruvector/README.md +288 -0
- package/examples/ruvector/attention-patterns.ts +394 -0
- package/examples/ruvector/basic-usage.ts +288 -0
- package/examples/ruvector/docker-compose.yml +75 -0
- package/examples/ruvector/gnn-analysis.ts +501 -0
- package/examples/ruvector/hyperbolic-hierarchies.ts +557 -0
- package/examples/ruvector/init-db.sql +119 -0
- package/examples/ruvector/quantization.ts +680 -0
- package/examples/ruvector/self-learning.ts +447 -0
- package/examples/ruvector/semantic-search.ts +576 -0
- package/examples/ruvector/streaming-large-data.ts +507 -0
- package/examples/ruvector/transactions.ts +594 -0
- package/examples/ruvector-plugins/hook-pattern-library.ts +486 -0
- package/examples/ruvector-plugins/index.ts +79 -0
- package/examples/ruvector-plugins/intent-router.ts +354 -0
- package/examples/ruvector-plugins/mcp-tool-optimizer.ts +424 -0
- package/examples/ruvector-plugins/reasoning-bank.ts +657 -0
- package/examples/ruvector-plugins/ruvector-plugins.test.ts +518 -0
- package/examples/ruvector-plugins/semantic-code-search.ts +498 -0
- package/examples/ruvector-plugins/shared/index.ts +20 -0
- package/examples/ruvector-plugins/shared/vector-utils.ts +257 -0
- package/examples/ruvector-plugins/sona-learning.ts +445 -0
- package/package.json +97 -0
- package/src/collections/collection-manager.ts +661 -0
- package/src/collections/index.ts +56 -0
- package/src/collections/official/index.ts +1040 -0
- package/src/core/base-plugin.ts +416 -0
- package/src/core/plugin-interface.ts +215 -0
- package/src/hooks/index.ts +685 -0
- package/src/index.ts +378 -0
- package/src/integrations/agentic-flow.ts +743 -0
- package/src/integrations/index.ts +88 -0
- package/src/integrations/ruvector/ARCHITECTURE.md +1245 -0
- package/src/integrations/ruvector/attention-advanced.ts +1040 -0
- package/src/integrations/ruvector/attention-executor.ts +782 -0
- package/src/integrations/ruvector/attention-mechanisms.ts +757 -0
- package/src/integrations/ruvector/attention.ts +1063 -0
- package/src/integrations/ruvector/gnn.ts +3050 -0
- package/src/integrations/ruvector/hyperbolic.ts +1948 -0
- package/src/integrations/ruvector/index.ts +394 -0
- package/src/integrations/ruvector/migrations/001_create_extension.sql +135 -0
- package/src/integrations/ruvector/migrations/002_create_vector_tables.sql +259 -0
- package/src/integrations/ruvector/migrations/003_create_indices.sql +328 -0
- package/src/integrations/ruvector/migrations/004_create_functions.sql +598 -0
- package/src/integrations/ruvector/migrations/005_create_attention_functions.sql +654 -0
- package/src/integrations/ruvector/migrations/006_create_gnn_functions.sql +728 -0
- package/src/integrations/ruvector/migrations/007_create_hyperbolic_functions.sql +762 -0
- package/src/integrations/ruvector/migrations/index.ts +35 -0
- package/src/integrations/ruvector/migrations/migrations.ts +647 -0
- package/src/integrations/ruvector/quantization.ts +2036 -0
- package/src/integrations/ruvector/ruvector-bridge.ts +2000 -0
- package/src/integrations/ruvector/self-learning.ts +2376 -0
- package/src/integrations/ruvector/streaming.ts +1737 -0
- package/src/integrations/ruvector/types.ts +1945 -0
- package/src/providers/index.ts +643 -0
- package/src/registry/dependency-graph.ts +568 -0
- package/src/registry/enhanced-plugin-registry.ts +994 -0
- package/src/registry/plugin-registry.ts +604 -0
- package/src/sdk/index.ts +563 -0
- package/src/security/index.ts +594 -0
- package/src/types/index.ts +446 -0
- package/src/workers/index.ts +700 -0
- package/tmp.json +0 -0
- package/tsconfig.json +25 -0
- package/vitest.config.ts +23 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Plugin Implementation
|
|
3
|
+
*
|
|
4
|
+
* Abstract base class that provides common plugin functionality.
|
|
5
|
+
* Plugins should extend this class for easier implementation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { EventEmitter } from 'events';
|
|
9
|
+
import type {
|
|
10
|
+
PluginMetadata,
|
|
11
|
+
PluginContext,
|
|
12
|
+
PluginLifecycleState,
|
|
13
|
+
PluginConfig,
|
|
14
|
+
ILogger,
|
|
15
|
+
IEventBus,
|
|
16
|
+
ServiceContainer,
|
|
17
|
+
AgentTypeDefinition,
|
|
18
|
+
TaskTypeDefinition,
|
|
19
|
+
MCPToolDefinition,
|
|
20
|
+
CLICommandDefinition,
|
|
21
|
+
MemoryBackendFactory,
|
|
22
|
+
HookDefinition,
|
|
23
|
+
WorkerDefinition,
|
|
24
|
+
LLMProviderDefinition,
|
|
25
|
+
HealthCheckResult,
|
|
26
|
+
} from '../types/index.js';
|
|
27
|
+
import type { IPlugin } from './plugin-interface.js';
|
|
28
|
+
import { PLUGIN_EVENTS } from './plugin-interface.js';
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Base Plugin
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Abstract base class for plugins.
|
|
36
|
+
*
|
|
37
|
+
* Provides:
|
|
38
|
+
* - Lifecycle management
|
|
39
|
+
* - Logging and event emission
|
|
40
|
+
* - Configuration access
|
|
41
|
+
* - Service container access
|
|
42
|
+
* - Default implementations for optional methods
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* class MyPlugin extends BasePlugin {
|
|
47
|
+
* constructor() {
|
|
48
|
+
* super({
|
|
49
|
+
* name: 'my-plugin',
|
|
50
|
+
* version: '1.0.0',
|
|
51
|
+
* description: 'My custom plugin'
|
|
52
|
+
* });
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* protected async onInitialize(): Promise<void> {
|
|
56
|
+
* this.logger.info('Plugin initialized');
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* registerMCPTools(): MCPToolDefinition[] {
|
|
60
|
+
* return [{
|
|
61
|
+
* name: 'my-tool',
|
|
62
|
+
* description: 'My custom tool',
|
|
63
|
+
* inputSchema: { type: 'object', properties: {} },
|
|
64
|
+
* handler: async (input) => ({
|
|
65
|
+
* content: [{ type: 'text', text: 'Hello!' }]
|
|
66
|
+
* })
|
|
67
|
+
* }];
|
|
68
|
+
* }
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export abstract class BasePlugin extends EventEmitter implements IPlugin {
|
|
73
|
+
// =========================================================================
|
|
74
|
+
// Properties
|
|
75
|
+
// =========================================================================
|
|
76
|
+
|
|
77
|
+
public readonly metadata: PluginMetadata;
|
|
78
|
+
private _state: PluginLifecycleState = 'uninitialized';
|
|
79
|
+
private _context: PluginContext | null = null;
|
|
80
|
+
private _initTime: Date | null = null;
|
|
81
|
+
|
|
82
|
+
// =========================================================================
|
|
83
|
+
// Constructor
|
|
84
|
+
// =========================================================================
|
|
85
|
+
|
|
86
|
+
constructor(metadata: PluginMetadata) {
|
|
87
|
+
super();
|
|
88
|
+
this.metadata = Object.freeze(metadata);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// =========================================================================
|
|
92
|
+
// State Management
|
|
93
|
+
// =========================================================================
|
|
94
|
+
|
|
95
|
+
get state(): PluginLifecycleState {
|
|
96
|
+
return this._state;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
protected setState(state: PluginLifecycleState): void {
|
|
100
|
+
const previousState = this._state;
|
|
101
|
+
this._state = state;
|
|
102
|
+
this.emit('stateChange', { previousState, currentState: state });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// =========================================================================
|
|
106
|
+
// Context Accessors
|
|
107
|
+
// =========================================================================
|
|
108
|
+
|
|
109
|
+
protected get context(): PluginContext {
|
|
110
|
+
if (!this._context) {
|
|
111
|
+
throw new Error(`Plugin ${this.metadata.name} not initialized`);
|
|
112
|
+
}
|
|
113
|
+
return this._context;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
protected get config(): PluginConfig {
|
|
117
|
+
return this.context.config;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
protected get logger(): ILogger {
|
|
121
|
+
return this.context.logger;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
protected get eventBus(): IEventBus {
|
|
125
|
+
return this.context.eventBus;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
protected get services(): ServiceContainer {
|
|
129
|
+
return this.context.services;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
protected get settings(): Record<string, unknown> {
|
|
133
|
+
return this.config.settings;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// =========================================================================
|
|
137
|
+
// Lifecycle Implementation
|
|
138
|
+
// =========================================================================
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Initialize the plugin.
|
|
142
|
+
* Subclasses should override onInitialize() instead of this method.
|
|
143
|
+
*/
|
|
144
|
+
async initialize(context: PluginContext): Promise<void> {
|
|
145
|
+
if (this._state !== 'uninitialized') {
|
|
146
|
+
throw new Error(`Plugin ${this.metadata.name} already initialized`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
this.setState('initializing');
|
|
150
|
+
this._context = context;
|
|
151
|
+
this._initTime = new Date();
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
// Validate dependencies
|
|
155
|
+
await this.validateDependencies();
|
|
156
|
+
|
|
157
|
+
// Validate configuration
|
|
158
|
+
await this.validateConfig();
|
|
159
|
+
|
|
160
|
+
// Call subclass initialization
|
|
161
|
+
await this.onInitialize();
|
|
162
|
+
|
|
163
|
+
this.setState('initialized');
|
|
164
|
+
this.eventBus.emit(PLUGIN_EVENTS.INITIALIZED, { plugin: this.metadata.name });
|
|
165
|
+
} catch (error) {
|
|
166
|
+
this.setState('error');
|
|
167
|
+
this.eventBus.emit(PLUGIN_EVENTS.ERROR, {
|
|
168
|
+
plugin: this.metadata.name,
|
|
169
|
+
error: error instanceof Error ? error.message : String(error),
|
|
170
|
+
});
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Shutdown the plugin.
|
|
177
|
+
* Subclasses should override onShutdown() instead of this method.
|
|
178
|
+
*/
|
|
179
|
+
async shutdown(): Promise<void> {
|
|
180
|
+
if (this._state !== 'initialized' && this._state !== 'error') {
|
|
181
|
+
return; // Already shutdown or never initialized
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
this.setState('shutting-down');
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
await this.onShutdown();
|
|
188
|
+
this.setState('shutdown');
|
|
189
|
+
this.eventBus.emit(PLUGIN_EVENTS.SHUTDOWN, { plugin: this.metadata.name });
|
|
190
|
+
} catch (error) {
|
|
191
|
+
this.setState('error');
|
|
192
|
+
throw error;
|
|
193
|
+
} finally {
|
|
194
|
+
this._context = null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Health check implementation.
|
|
200
|
+
* Subclasses can override onHealthCheck() for custom checks.
|
|
201
|
+
*/
|
|
202
|
+
async healthCheck(): Promise<HealthCheckResult> {
|
|
203
|
+
const checks: Record<string, { healthy: boolean; message?: string; latencyMs?: number }> = {};
|
|
204
|
+
|
|
205
|
+
// Check state
|
|
206
|
+
const stateHealthy = this._state === 'initialized';
|
|
207
|
+
checks['state'] = {
|
|
208
|
+
healthy: stateHealthy,
|
|
209
|
+
message: stateHealthy ? 'Plugin initialized' : `State: ${this._state}`,
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
// Run custom health checks
|
|
213
|
+
const startTime = Date.now();
|
|
214
|
+
try {
|
|
215
|
+
const customChecks = await this.onHealthCheck();
|
|
216
|
+
Object.assign(checks, customChecks);
|
|
217
|
+
} catch (error) {
|
|
218
|
+
checks['custom'] = {
|
|
219
|
+
healthy: false,
|
|
220
|
+
message: error instanceof Error ? error.message : 'Health check failed',
|
|
221
|
+
latencyMs: Date.now() - startTime,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const allHealthy = Object.values(checks).every(c => c.healthy);
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
healthy: allHealthy,
|
|
229
|
+
status: allHealthy ? 'healthy' : 'unhealthy',
|
|
230
|
+
checks,
|
|
231
|
+
timestamp: new Date(),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// =========================================================================
|
|
236
|
+
// Lifecycle Hooks (Override in subclasses)
|
|
237
|
+
// =========================================================================
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Called during initialization.
|
|
241
|
+
* Override this in subclasses to add initialization logic.
|
|
242
|
+
*/
|
|
243
|
+
protected async onInitialize(): Promise<void> {
|
|
244
|
+
// Default: no-op
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Called during shutdown.
|
|
249
|
+
* Override this in subclasses to add cleanup logic.
|
|
250
|
+
*/
|
|
251
|
+
protected async onShutdown(): Promise<void> {
|
|
252
|
+
// Default: no-op
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Called during health check.
|
|
257
|
+
* Override this in subclasses to add custom health checks.
|
|
258
|
+
*/
|
|
259
|
+
protected async onHealthCheck(): Promise<Record<string, { healthy: boolean; message?: string }>> {
|
|
260
|
+
return {};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// =========================================================================
|
|
264
|
+
// Validation
|
|
265
|
+
// =========================================================================
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Validate plugin dependencies are available.
|
|
269
|
+
*/
|
|
270
|
+
protected async validateDependencies(): Promise<void> {
|
|
271
|
+
const deps = this.metadata.dependencies ?? [];
|
|
272
|
+
for (const dep of deps) {
|
|
273
|
+
// Dependencies are validated by the PluginManager
|
|
274
|
+
// This hook allows plugins to do additional checks
|
|
275
|
+
this.logger.debug(`Dependency validated: ${dep}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Validate plugin configuration.
|
|
281
|
+
* Override this in subclasses to add config validation.
|
|
282
|
+
*/
|
|
283
|
+
protected async validateConfig(): Promise<void> {
|
|
284
|
+
// Default: no-op
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// =========================================================================
|
|
288
|
+
// Extension Points (Override in subclasses as needed)
|
|
289
|
+
// =========================================================================
|
|
290
|
+
|
|
291
|
+
registerAgentTypes?(): AgentTypeDefinition[];
|
|
292
|
+
registerTaskTypes?(): TaskTypeDefinition[];
|
|
293
|
+
registerMCPTools?(): MCPToolDefinition[];
|
|
294
|
+
registerCLICommands?(): CLICommandDefinition[];
|
|
295
|
+
registerMemoryBackends?(): MemoryBackendFactory[];
|
|
296
|
+
registerHooks?(): HookDefinition[];
|
|
297
|
+
registerWorkers?(): WorkerDefinition[];
|
|
298
|
+
registerProviders?(): LLMProviderDefinition[];
|
|
299
|
+
|
|
300
|
+
// =========================================================================
|
|
301
|
+
// Utility Methods
|
|
302
|
+
// =========================================================================
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Get setting value with type safety.
|
|
306
|
+
*/
|
|
307
|
+
protected getSetting<T>(key: string, defaultValue?: T): T | undefined {
|
|
308
|
+
const value = this.settings[key];
|
|
309
|
+
if (value === undefined) return defaultValue;
|
|
310
|
+
return value as T;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Get uptime in milliseconds.
|
|
315
|
+
*/
|
|
316
|
+
protected getUptime(): number {
|
|
317
|
+
if (!this._initTime) return 0;
|
|
318
|
+
return Date.now() - this._initTime.getTime();
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Create a child logger with context.
|
|
323
|
+
*/
|
|
324
|
+
protected createChildLogger(context: Record<string, unknown>): ILogger {
|
|
325
|
+
return this.logger.child({ plugin: this.metadata.name, ...context });
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// ============================================================================
|
|
330
|
+
// Simple Plugin (for quick one-off plugins)
|
|
331
|
+
// ============================================================================
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Configuration for creating a simple plugin.
|
|
335
|
+
*/
|
|
336
|
+
export interface SimplePluginConfig {
|
|
337
|
+
metadata: PluginMetadata;
|
|
338
|
+
onInitialize?: (context: PluginContext) => Promise<void>;
|
|
339
|
+
onShutdown?: () => Promise<void>;
|
|
340
|
+
agentTypes?: AgentTypeDefinition[];
|
|
341
|
+
taskTypes?: TaskTypeDefinition[];
|
|
342
|
+
mcpTools?: MCPToolDefinition[];
|
|
343
|
+
cliCommands?: CLICommandDefinition[];
|
|
344
|
+
hooks?: HookDefinition[];
|
|
345
|
+
workers?: WorkerDefinition[];
|
|
346
|
+
providers?: LLMProviderDefinition[];
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Create a simple plugin from configuration.
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```typescript
|
|
354
|
+
* const myPlugin = createSimplePlugin({
|
|
355
|
+
* metadata: { name: 'my-plugin', version: '1.0.0' },
|
|
356
|
+
* mcpTools: [{
|
|
357
|
+
* name: 'hello',
|
|
358
|
+
* description: 'Say hello',
|
|
359
|
+
* inputSchema: { type: 'object', properties: {} },
|
|
360
|
+
* handler: async () => ({ content: [{ type: 'text', text: 'Hello!' }] })
|
|
361
|
+
* }]
|
|
362
|
+
* });
|
|
363
|
+
* ```
|
|
364
|
+
*/
|
|
365
|
+
export function createSimplePlugin(config: SimplePluginConfig): IPlugin {
|
|
366
|
+
return new SimplePlugin(config) as IPlugin;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
class SimplePlugin extends BasePlugin {
|
|
370
|
+
private readonly _config: SimplePluginConfig;
|
|
371
|
+
|
|
372
|
+
constructor(config: SimplePluginConfig) {
|
|
373
|
+
super(config.metadata);
|
|
374
|
+
this._config = config;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
protected async onInitialize(): Promise<void> {
|
|
378
|
+
if (this._config.onInitialize) {
|
|
379
|
+
await this._config.onInitialize(this.context);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
protected async onShutdown(): Promise<void> {
|
|
384
|
+
if (this._config.onShutdown) {
|
|
385
|
+
await this._config.onShutdown();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
override registerAgentTypes(): AgentTypeDefinition[] {
|
|
390
|
+
return this._config.agentTypes ?? [];
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
override registerTaskTypes(): TaskTypeDefinition[] {
|
|
394
|
+
return this._config.taskTypes ?? [];
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
override registerMCPTools(): MCPToolDefinition[] {
|
|
398
|
+
return this._config.mcpTools ?? [];
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
override registerCLICommands(): CLICommandDefinition[] {
|
|
402
|
+
return this._config.cliCommands ?? [];
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
override registerHooks(): HookDefinition[] {
|
|
406
|
+
return this._config.hooks ?? [];
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
override registerWorkers(): WorkerDefinition[] {
|
|
410
|
+
return this._config.workers ?? [];
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
override registerProviders(): LLMProviderDefinition[] {
|
|
414
|
+
return this._config.providers ?? [];
|
|
415
|
+
}
|
|
416
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Plugin Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract that all plugins must implement.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
PluginMetadata,
|
|
9
|
+
PluginContext,
|
|
10
|
+
PluginLifecycleState,
|
|
11
|
+
AgentTypeDefinition,
|
|
12
|
+
TaskTypeDefinition,
|
|
13
|
+
MCPToolDefinition,
|
|
14
|
+
CLICommandDefinition,
|
|
15
|
+
MemoryBackendFactory,
|
|
16
|
+
HookDefinition,
|
|
17
|
+
WorkerDefinition,
|
|
18
|
+
LLMProviderDefinition,
|
|
19
|
+
HealthCheckResult,
|
|
20
|
+
} from '../types/index.js';
|
|
21
|
+
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Plugin Interface
|
|
24
|
+
// ============================================================================
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Core plugin interface that all plugins must implement.
|
|
28
|
+
*
|
|
29
|
+
* Plugins provide extensibility across multiple domains:
|
|
30
|
+
* - Agent types and task definitions
|
|
31
|
+
* - MCP tools for Claude interaction
|
|
32
|
+
* - CLI commands for terminal interface
|
|
33
|
+
* - Memory backends for storage
|
|
34
|
+
* - Hooks for lifecycle events
|
|
35
|
+
* - Workers for parallel execution
|
|
36
|
+
* - LLM providers for model access
|
|
37
|
+
*/
|
|
38
|
+
export interface IPlugin {
|
|
39
|
+
/** Plugin metadata (name, version, etc.) */
|
|
40
|
+
readonly metadata: PluginMetadata;
|
|
41
|
+
|
|
42
|
+
/** Current lifecycle state */
|
|
43
|
+
readonly state: PluginLifecycleState;
|
|
44
|
+
|
|
45
|
+
// =========================================================================
|
|
46
|
+
// Lifecycle Methods
|
|
47
|
+
// =========================================================================
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Initialize the plugin with context.
|
|
51
|
+
* Called once when the plugin is loaded.
|
|
52
|
+
*/
|
|
53
|
+
initialize(context: PluginContext): Promise<void>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Shutdown the plugin gracefully.
|
|
57
|
+
* Called when the plugin is being unloaded.
|
|
58
|
+
*/
|
|
59
|
+
shutdown(): Promise<void>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Check plugin health.
|
|
63
|
+
* Called periodically for monitoring.
|
|
64
|
+
*/
|
|
65
|
+
healthCheck?(): Promise<HealthCheckResult>;
|
|
66
|
+
|
|
67
|
+
// =========================================================================
|
|
68
|
+
// Extension Point Registration
|
|
69
|
+
// =========================================================================
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Register agent type definitions.
|
|
73
|
+
* Called during initialization to collect agent types.
|
|
74
|
+
*/
|
|
75
|
+
registerAgentTypes?(): AgentTypeDefinition[];
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Register task type definitions.
|
|
79
|
+
* Called during initialization to collect task types.
|
|
80
|
+
*/
|
|
81
|
+
registerTaskTypes?(): TaskTypeDefinition[];
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Register MCP tool definitions.
|
|
85
|
+
* Called during initialization to expose tools to Claude.
|
|
86
|
+
*/
|
|
87
|
+
registerMCPTools?(): MCPToolDefinition[];
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Register CLI command definitions.
|
|
91
|
+
* Called during initialization to extend the CLI.
|
|
92
|
+
*/
|
|
93
|
+
registerCLICommands?(): CLICommandDefinition[];
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Register memory backend factories.
|
|
97
|
+
* Called during initialization to add storage options.
|
|
98
|
+
*/
|
|
99
|
+
registerMemoryBackends?(): MemoryBackendFactory[];
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Register hook definitions.
|
|
103
|
+
* Called during initialization to add lifecycle hooks.
|
|
104
|
+
*/
|
|
105
|
+
registerHooks?(): HookDefinition[];
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Register worker definitions.
|
|
109
|
+
* Called during initialization to add worker types.
|
|
110
|
+
*/
|
|
111
|
+
registerWorkers?(): WorkerDefinition[];
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Register LLM provider definitions.
|
|
115
|
+
* Called during initialization to add model providers.
|
|
116
|
+
*/
|
|
117
|
+
registerProviders?(): LLMProviderDefinition[];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// Plugin Factory
|
|
122
|
+
// ============================================================================
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Factory function type for creating plugin instances.
|
|
126
|
+
*/
|
|
127
|
+
export type PluginFactory = () => IPlugin | Promise<IPlugin>;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Plugin module export interface.
|
|
131
|
+
* Plugins should export a default factory or plugin instance.
|
|
132
|
+
*/
|
|
133
|
+
export interface PluginModule {
|
|
134
|
+
default: IPlugin | PluginFactory;
|
|
135
|
+
metadata?: PluginMetadata;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ============================================================================
|
|
139
|
+
// Plugin Events
|
|
140
|
+
// ============================================================================
|
|
141
|
+
|
|
142
|
+
export const PLUGIN_EVENTS = {
|
|
143
|
+
LOADING: 'plugin:loading',
|
|
144
|
+
LOADED: 'plugin:loaded',
|
|
145
|
+
INITIALIZING: 'plugin:initializing',
|
|
146
|
+
INITIALIZED: 'plugin:initialized',
|
|
147
|
+
SHUTTING_DOWN: 'plugin:shutting-down',
|
|
148
|
+
SHUTDOWN: 'plugin:shutdown',
|
|
149
|
+
ERROR: 'plugin:error',
|
|
150
|
+
HEALTH_CHECK: 'plugin:health-check',
|
|
151
|
+
} as const;
|
|
152
|
+
|
|
153
|
+
export type PluginEvent = typeof PLUGIN_EVENTS[keyof typeof PLUGIN_EVENTS];
|
|
154
|
+
|
|
155
|
+
// ============================================================================
|
|
156
|
+
// Plugin Validation
|
|
157
|
+
// ============================================================================
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Validate plugin metadata.
|
|
161
|
+
*/
|
|
162
|
+
export function validatePluginMetadata(metadata: unknown): metadata is PluginMetadata {
|
|
163
|
+
if (!metadata || typeof metadata !== 'object') return false;
|
|
164
|
+
|
|
165
|
+
const m = metadata as Record<string, unknown>;
|
|
166
|
+
|
|
167
|
+
if (typeof m.name !== 'string' || m.name.length === 0) return false;
|
|
168
|
+
if (typeof m.version !== 'string' || !/^\d+\.\d+\.\d+/.test(m.version)) return false;
|
|
169
|
+
|
|
170
|
+
if (m.description !== undefined && typeof m.description !== 'string') return false;
|
|
171
|
+
if (m.author !== undefined && typeof m.author !== 'string') return false;
|
|
172
|
+
|
|
173
|
+
if (m.dependencies !== undefined) {
|
|
174
|
+
if (!Array.isArray(m.dependencies)) return false;
|
|
175
|
+
if (!m.dependencies.every(d => typeof d === 'string')) return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Validate plugin interface.
|
|
183
|
+
*/
|
|
184
|
+
export function validatePlugin(plugin: unknown): plugin is IPlugin {
|
|
185
|
+
if (!plugin || typeof plugin !== 'object') return false;
|
|
186
|
+
|
|
187
|
+
const p = plugin as Record<string, unknown>;
|
|
188
|
+
|
|
189
|
+
// Check required properties
|
|
190
|
+
if (!validatePluginMetadata(p.metadata)) return false;
|
|
191
|
+
if (typeof p.state !== 'string') return false;
|
|
192
|
+
if (typeof p.initialize !== 'function') return false;
|
|
193
|
+
if (typeof p.shutdown !== 'function') return false;
|
|
194
|
+
|
|
195
|
+
// Check optional methods are functions if present
|
|
196
|
+
const optionalMethods = [
|
|
197
|
+
'healthCheck',
|
|
198
|
+
'registerAgentTypes',
|
|
199
|
+
'registerTaskTypes',
|
|
200
|
+
'registerMCPTools',
|
|
201
|
+
'registerCLICommands',
|
|
202
|
+
'registerMemoryBackends',
|
|
203
|
+
'registerHooks',
|
|
204
|
+
'registerWorkers',
|
|
205
|
+
'registerProviders',
|
|
206
|
+
];
|
|
207
|
+
|
|
208
|
+
for (const method of optionalMethods) {
|
|
209
|
+
if (p[method] !== undefined && typeof p[method] !== 'function') {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return true;
|
|
215
|
+
}
|