@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,636 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Creator Plugin
|
|
3
|
+
*
|
|
4
|
+
* A meta-plugin that creates new plugins with various configurations.
|
|
5
|
+
* Demonstrates all plugin SDK capabilities including tools, hooks, workers,
|
|
6
|
+
* swarm integration, and security features.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { pluginCreatorPlugin } from '@sparkleideas/plugins/examples/plugin-creator';
|
|
11
|
+
* import { getDefaultRegistry } from '@sparkleideas/plugins';
|
|
12
|
+
*
|
|
13
|
+
* await getDefaultRegistry().register(pluginCreatorPlugin);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
PluginBuilder,
|
|
19
|
+
MCPToolBuilder,
|
|
20
|
+
HookBuilder,
|
|
21
|
+
WorkerBuilder,
|
|
22
|
+
HookEvent,
|
|
23
|
+
HookPriority,
|
|
24
|
+
WorkerFactory,
|
|
25
|
+
Security,
|
|
26
|
+
type PluginMetadata,
|
|
27
|
+
type MCPToolDefinition,
|
|
28
|
+
type HookDefinition,
|
|
29
|
+
type WorkerDefinition,
|
|
30
|
+
type AgentTypeDefinition,
|
|
31
|
+
type IPlugin,
|
|
32
|
+
} from '../../src/index.js';
|
|
33
|
+
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Plugin Creator Types
|
|
36
|
+
// ============================================================================
|
|
37
|
+
|
|
38
|
+
export interface PluginTemplate {
|
|
39
|
+
readonly name: string;
|
|
40
|
+
readonly description: string;
|
|
41
|
+
readonly category: 'tools' | 'hooks' | 'workers' | 'swarm' | 'full';
|
|
42
|
+
readonly features: string[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface CreatePluginOptions {
|
|
46
|
+
readonly name: string;
|
|
47
|
+
readonly version?: string;
|
|
48
|
+
readonly description?: string;
|
|
49
|
+
readonly author?: string;
|
|
50
|
+
readonly template?: string;
|
|
51
|
+
readonly features?: {
|
|
52
|
+
tools?: boolean;
|
|
53
|
+
hooks?: boolean;
|
|
54
|
+
workers?: boolean;
|
|
55
|
+
swarm?: boolean;
|
|
56
|
+
security?: boolean;
|
|
57
|
+
providers?: boolean;
|
|
58
|
+
};
|
|
59
|
+
readonly toolNames?: string[];
|
|
60
|
+
readonly hookEvents?: HookEvent[];
|
|
61
|
+
readonly workerTypes?: string[];
|
|
62
|
+
readonly agentTypes?: string[];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface GeneratedPlugin {
|
|
66
|
+
readonly plugin: IPlugin;
|
|
67
|
+
readonly code: string;
|
|
68
|
+
readonly metadata: PluginMetadata;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Plugin Templates
|
|
73
|
+
// ============================================================================
|
|
74
|
+
|
|
75
|
+
export const PLUGIN_TEMPLATES: Record<string, PluginTemplate> = {
|
|
76
|
+
'minimal': {
|
|
77
|
+
name: 'Minimal Plugin',
|
|
78
|
+
description: 'A bare-bones plugin with just metadata',
|
|
79
|
+
category: 'tools',
|
|
80
|
+
features: [],
|
|
81
|
+
},
|
|
82
|
+
'tool-plugin': {
|
|
83
|
+
name: 'Tool Plugin',
|
|
84
|
+
description: 'Plugin focused on MCP tools',
|
|
85
|
+
category: 'tools',
|
|
86
|
+
features: ['tools'],
|
|
87
|
+
},
|
|
88
|
+
'hooks-plugin': {
|
|
89
|
+
name: 'Hooks Plugin',
|
|
90
|
+
description: 'Plugin focused on lifecycle hooks',
|
|
91
|
+
category: 'hooks',
|
|
92
|
+
features: ['hooks'],
|
|
93
|
+
},
|
|
94
|
+
'worker-plugin': {
|
|
95
|
+
name: 'Worker Plugin',
|
|
96
|
+
description: 'Plugin with worker pool integration',
|
|
97
|
+
category: 'workers',
|
|
98
|
+
features: ['workers'],
|
|
99
|
+
},
|
|
100
|
+
'swarm-plugin': {
|
|
101
|
+
name: 'Swarm Plugin',
|
|
102
|
+
description: 'Plugin with swarm coordination capabilities',
|
|
103
|
+
category: 'swarm',
|
|
104
|
+
features: ['swarm', 'workers', 'hooks'],
|
|
105
|
+
},
|
|
106
|
+
'full-featured': {
|
|
107
|
+
name: 'Full Featured Plugin',
|
|
108
|
+
description: 'Complete plugin with all capabilities',
|
|
109
|
+
category: 'full',
|
|
110
|
+
features: ['tools', 'hooks', 'workers', 'swarm', 'security', 'providers'],
|
|
111
|
+
},
|
|
112
|
+
'security-focused': {
|
|
113
|
+
name: 'Security Focused Plugin',
|
|
114
|
+
description: 'Plugin with security features and validation',
|
|
115
|
+
category: 'tools',
|
|
116
|
+
features: ['tools', 'hooks', 'security'],
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// Code Generators
|
|
122
|
+
// ============================================================================
|
|
123
|
+
|
|
124
|
+
function generateToolCode(toolName: string): { definition: MCPToolDefinition; code: string } {
|
|
125
|
+
const sanitizedName = Security.validateString(toolName, {
|
|
126
|
+
pattern: /^[a-z][a-z0-9-]*$/,
|
|
127
|
+
maxLength: 50,
|
|
128
|
+
}) ?? 'custom-tool';
|
|
129
|
+
|
|
130
|
+
const definition: MCPToolDefinition = {
|
|
131
|
+
name: sanitizedName,
|
|
132
|
+
description: `Generated tool: ${sanitizedName}`,
|
|
133
|
+
inputSchema: {
|
|
134
|
+
type: 'object',
|
|
135
|
+
properties: {
|
|
136
|
+
input: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
description: 'Input for the tool',
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
required: ['input'],
|
|
142
|
+
},
|
|
143
|
+
handler: async (params) => ({
|
|
144
|
+
content: [{
|
|
145
|
+
type: 'text',
|
|
146
|
+
text: `Tool ${sanitizedName} executed with: ${JSON.stringify(params)}`,
|
|
147
|
+
}],
|
|
148
|
+
}),
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const code = `
|
|
152
|
+
const ${camelCase(sanitizedName)}Tool = new MCPToolBuilder('${sanitizedName}')
|
|
153
|
+
.withDescription('Generated tool: ${sanitizedName}')
|
|
154
|
+
.addStringParam('input', 'Input for the tool', { required: true })
|
|
155
|
+
.withHandler(async (params) => ({
|
|
156
|
+
content: [{ type: 'text', text: \`Tool ${sanitizedName} executed with: \${JSON.stringify(params)}\` }]
|
|
157
|
+
}))
|
|
158
|
+
.build();
|
|
159
|
+
`;
|
|
160
|
+
|
|
161
|
+
return { definition, code };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function generateHookCode(event: HookEvent): { definition: HookDefinition; code: string } {
|
|
165
|
+
const definition: HookDefinition = {
|
|
166
|
+
event,
|
|
167
|
+
priority: HookPriority.Normal,
|
|
168
|
+
name: `${event}-handler`,
|
|
169
|
+
description: `Handler for ${event} event`,
|
|
170
|
+
handler: async (ctx) => {
|
|
171
|
+
console.log(`Hook triggered: ${event}`, ctx.data);
|
|
172
|
+
return { success: true };
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const code = `
|
|
177
|
+
const ${camelCase(event)}Hook = new HookBuilder(HookEvent.${getEventEnumName(event)})
|
|
178
|
+
.withName('${event}-handler')
|
|
179
|
+
.withDescription('Handler for ${event} event')
|
|
180
|
+
.withPriority(HookPriority.Normal)
|
|
181
|
+
.withHandler(async (ctx) => {
|
|
182
|
+
console.log('Hook triggered: ${event}', ctx.data);
|
|
183
|
+
return { success: true };
|
|
184
|
+
})
|
|
185
|
+
.build();
|
|
186
|
+
`;
|
|
187
|
+
|
|
188
|
+
return { definition, code };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function generateWorkerCode(workerType: string): { definition: WorkerDefinition; code: string } {
|
|
192
|
+
const validTypes = ['coder', 'reviewer', 'tester', 'researcher', 'planner', 'coordinator', 'security', 'performance'];
|
|
193
|
+
const type = validTypes.includes(workerType) ? workerType : 'specialized';
|
|
194
|
+
|
|
195
|
+
let definition: WorkerDefinition;
|
|
196
|
+
let factoryMethod: string;
|
|
197
|
+
|
|
198
|
+
switch (type) {
|
|
199
|
+
case 'coder':
|
|
200
|
+
definition = WorkerFactory.createCoder(`${workerType}-worker`);
|
|
201
|
+
factoryMethod = 'createCoder';
|
|
202
|
+
break;
|
|
203
|
+
case 'reviewer':
|
|
204
|
+
definition = WorkerFactory.createReviewer(`${workerType}-worker`);
|
|
205
|
+
factoryMethod = 'createReviewer';
|
|
206
|
+
break;
|
|
207
|
+
case 'tester':
|
|
208
|
+
definition = WorkerFactory.createTester(`${workerType}-worker`);
|
|
209
|
+
factoryMethod = 'createTester';
|
|
210
|
+
break;
|
|
211
|
+
case 'researcher':
|
|
212
|
+
definition = WorkerFactory.createResearcher(`${workerType}-worker`);
|
|
213
|
+
factoryMethod = 'createResearcher';
|
|
214
|
+
break;
|
|
215
|
+
case 'planner':
|
|
216
|
+
definition = WorkerFactory.createPlanner(`${workerType}-worker`);
|
|
217
|
+
factoryMethod = 'createPlanner';
|
|
218
|
+
break;
|
|
219
|
+
case 'coordinator':
|
|
220
|
+
definition = WorkerFactory.createCoordinator(`${workerType}-worker`);
|
|
221
|
+
factoryMethod = 'createCoordinator';
|
|
222
|
+
break;
|
|
223
|
+
case 'security':
|
|
224
|
+
definition = WorkerFactory.createSecurity(`${workerType}-worker`);
|
|
225
|
+
factoryMethod = 'createSecurity';
|
|
226
|
+
break;
|
|
227
|
+
case 'performance':
|
|
228
|
+
definition = WorkerFactory.createPerformance(`${workerType}-worker`);
|
|
229
|
+
factoryMethod = 'createPerformance';
|
|
230
|
+
break;
|
|
231
|
+
default:
|
|
232
|
+
definition = WorkerFactory.createSpecialized(`${workerType}-worker`, ['custom']);
|
|
233
|
+
factoryMethod = 'createSpecialized';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const code = factoryMethod === 'createSpecialized'
|
|
237
|
+
? `const ${camelCase(workerType)}Worker = WorkerFactory.${factoryMethod}('${workerType}-worker', ['custom']);`
|
|
238
|
+
: `const ${camelCase(workerType)}Worker = WorkerFactory.${factoryMethod}('${workerType}-worker');`;
|
|
239
|
+
|
|
240
|
+
return { definition, code };
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function generateAgentTypeCode(agentType: string): { definition: AgentTypeDefinition; code: string } {
|
|
244
|
+
const sanitizedType = Security.validateString(agentType, {
|
|
245
|
+
pattern: /^[a-z][a-z0-9-]*$/,
|
|
246
|
+
maxLength: 50,
|
|
247
|
+
}) ?? 'custom-agent';
|
|
248
|
+
|
|
249
|
+
const definition: AgentTypeDefinition = {
|
|
250
|
+
type: sanitizedType,
|
|
251
|
+
name: `${sanitizedType} Agent`,
|
|
252
|
+
description: `Generated agent type: ${sanitizedType}`,
|
|
253
|
+
capabilities: ['general'],
|
|
254
|
+
model: 'claude-sonnet-4-20250514',
|
|
255
|
+
systemPrompt: `You are a ${sanitizedType} agent.`,
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const code = `
|
|
259
|
+
const ${camelCase(sanitizedType)}Agent: AgentTypeDefinition = {
|
|
260
|
+
type: '${sanitizedType}',
|
|
261
|
+
name: '${sanitizedType} Agent',
|
|
262
|
+
description: 'Generated agent type: ${sanitizedType}',
|
|
263
|
+
capabilities: ['general'],
|
|
264
|
+
model: 'claude-sonnet-4-20250514',
|
|
265
|
+
systemPrompt: 'You are a ${sanitizedType} agent.',
|
|
266
|
+
};
|
|
267
|
+
`;
|
|
268
|
+
|
|
269
|
+
return { definition, code };
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ============================================================================
|
|
273
|
+
// Plugin Generator
|
|
274
|
+
// ============================================================================
|
|
275
|
+
|
|
276
|
+
export function generatePlugin(options: CreatePluginOptions): GeneratedPlugin {
|
|
277
|
+
const {
|
|
278
|
+
name,
|
|
279
|
+
version = '1.0.0',
|
|
280
|
+
description = `Generated plugin: ${name}`,
|
|
281
|
+
author = 'Plugin Creator',
|
|
282
|
+
template = 'minimal',
|
|
283
|
+
features = {},
|
|
284
|
+
toolNames = [],
|
|
285
|
+
hookEvents = [],
|
|
286
|
+
workerTypes = [],
|
|
287
|
+
agentTypes = [],
|
|
288
|
+
} = options;
|
|
289
|
+
|
|
290
|
+
// Validate plugin name
|
|
291
|
+
const validName = Security.validateString(name, {
|
|
292
|
+
pattern: /^[a-z][a-z0-9-]*$/,
|
|
293
|
+
minLength: 3,
|
|
294
|
+
maxLength: 50,
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
if (!validName) {
|
|
298
|
+
throw new Error('Invalid plugin name. Use lowercase letters, numbers, and hyphens.');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Get template features
|
|
302
|
+
const templateConfig = PLUGIN_TEMPLATES[template] ?? PLUGIN_TEMPLATES['minimal'];
|
|
303
|
+
const enabledFeatures = {
|
|
304
|
+
tools: features.tools ?? templateConfig.features.includes('tools'),
|
|
305
|
+
hooks: features.hooks ?? templateConfig.features.includes('hooks'),
|
|
306
|
+
workers: features.workers ?? templateConfig.features.includes('workers'),
|
|
307
|
+
swarm: features.swarm ?? templateConfig.features.includes('swarm'),
|
|
308
|
+
security: features.security ?? templateConfig.features.includes('security'),
|
|
309
|
+
providers: features.providers ?? templateConfig.features.includes('providers'),
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
// Generate components
|
|
313
|
+
const tools: MCPToolDefinition[] = [];
|
|
314
|
+
const hooks: HookDefinition[] = [];
|
|
315
|
+
const workers: WorkerDefinition[] = [];
|
|
316
|
+
const agents: AgentTypeDefinition[] = [];
|
|
317
|
+
const codeBlocks: string[] = [];
|
|
318
|
+
|
|
319
|
+
// Import statements
|
|
320
|
+
codeBlocks.push(`import {
|
|
321
|
+
PluginBuilder,${enabledFeatures.tools ? '\n MCPToolBuilder,' : ''}${enabledFeatures.hooks ? '\n HookBuilder,\n HookEvent,\n HookPriority,' : ''}${enabledFeatures.workers ? '\n WorkerFactory,' : ''}${enabledFeatures.security ? '\n Security,' : ''}
|
|
322
|
+
type IPlugin,${enabledFeatures.workers ? '\n type WorkerDefinition,' : ''}${agents.length > 0 ? '\n type AgentTypeDefinition,' : ''}
|
|
323
|
+
} from '@sparkleideas/plugins';
|
|
324
|
+
`);
|
|
325
|
+
|
|
326
|
+
// Generate tools
|
|
327
|
+
if (enabledFeatures.tools) {
|
|
328
|
+
const defaultTools = toolNames.length > 0 ? toolNames : ['default-tool'];
|
|
329
|
+
for (const toolName of defaultTools) {
|
|
330
|
+
const { definition, code } = generateToolCode(toolName);
|
|
331
|
+
tools.push(definition);
|
|
332
|
+
codeBlocks.push(code);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Generate hooks
|
|
337
|
+
if (enabledFeatures.hooks) {
|
|
338
|
+
const defaultEvents = hookEvents.length > 0 ? hookEvents : [HookEvent.SessionStart, HookEvent.PostTaskComplete];
|
|
339
|
+
for (const event of defaultEvents) {
|
|
340
|
+
const { definition, code } = generateHookCode(event);
|
|
341
|
+
hooks.push(definition);
|
|
342
|
+
codeBlocks.push(code);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Generate workers
|
|
347
|
+
if (enabledFeatures.workers) {
|
|
348
|
+
const defaultWorkers = workerTypes.length > 0 ? workerTypes : ['coder', 'tester'];
|
|
349
|
+
for (const workerType of defaultWorkers) {
|
|
350
|
+
const { definition, code } = generateWorkerCode(workerType);
|
|
351
|
+
workers.push(definition);
|
|
352
|
+
codeBlocks.push(code);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Generate agents (for swarm plugins)
|
|
357
|
+
if (enabledFeatures.swarm) {
|
|
358
|
+
const defaultAgents = agentTypes.length > 0 ? agentTypes : ['coordinator', 'worker'];
|
|
359
|
+
for (const agentType of defaultAgents) {
|
|
360
|
+
const { definition, code } = generateAgentTypeCode(agentType);
|
|
361
|
+
agents.push(definition);
|
|
362
|
+
codeBlocks.push(code);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Build the plugin
|
|
367
|
+
const builder = new PluginBuilder(validName, version)
|
|
368
|
+
.withDescription(description)
|
|
369
|
+
.withAuthor(author);
|
|
370
|
+
|
|
371
|
+
if (tools.length > 0) builder.withMCPTools(tools);
|
|
372
|
+
if (hooks.length > 0) builder.withHooks(hooks);
|
|
373
|
+
if (workers.length > 0) builder.withWorkers(workers);
|
|
374
|
+
if (agents.length > 0) builder.withAgentTypes(agents);
|
|
375
|
+
|
|
376
|
+
const plugin = builder.build();
|
|
377
|
+
|
|
378
|
+
// Generate plugin builder code
|
|
379
|
+
codeBlocks.push(`
|
|
380
|
+
// Create the plugin
|
|
381
|
+
const ${camelCase(validName)}Plugin = new PluginBuilder('${validName}', '${version}')
|
|
382
|
+
.withDescription('${description}')
|
|
383
|
+
.withAuthor('${author}')${tools.length > 0 ? `
|
|
384
|
+
.withMCPTools([${tools.map(t => camelCase(t.name) + 'Tool').join(', ')}])` : ''}${hooks.length > 0 ? `
|
|
385
|
+
.withHooks([${hooks.map(h => camelCase(h.event) + 'Hook').join(', ')}])` : ''}${workers.length > 0 ? `
|
|
386
|
+
.withWorkers([${workers.map(w => camelCase(w.name.replace('-worker', '')) + 'Worker').join(', ')}])` : ''}${agents.length > 0 ? `
|
|
387
|
+
.withAgentTypes([${agents.map(a => camelCase(a.type) + 'Agent').join(', ')}])` : ''}
|
|
388
|
+
.build();
|
|
389
|
+
|
|
390
|
+
export default ${camelCase(validName)}Plugin;
|
|
391
|
+
`);
|
|
392
|
+
|
|
393
|
+
return {
|
|
394
|
+
plugin,
|
|
395
|
+
code: codeBlocks.join('\n'),
|
|
396
|
+
metadata: plugin.metadata,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// ============================================================================
|
|
401
|
+
// Helper Functions
|
|
402
|
+
// ============================================================================
|
|
403
|
+
|
|
404
|
+
function camelCase(str: string): string {
|
|
405
|
+
return str
|
|
406
|
+
.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase())
|
|
407
|
+
.replace(/^./, (chr) => chr.toLowerCase());
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function getEventEnumName(event: HookEvent): string {
|
|
411
|
+
// Mapping from HookEvent enum values to their TypeScript enum names
|
|
412
|
+
const mapping: Record<string, string> = {
|
|
413
|
+
// Tool lifecycle (from types/index.ts HookEvent enum)
|
|
414
|
+
'hook:pre-tool-use': 'PreToolUse',
|
|
415
|
+
'hook:post-tool-use': 'PostToolUse',
|
|
416
|
+
// Session lifecycle
|
|
417
|
+
'hook:session-start': 'SessionStart',
|
|
418
|
+
'hook:session-end': 'SessionEnd',
|
|
419
|
+
'hook:session-restore': 'SessionRestore',
|
|
420
|
+
// Task execution
|
|
421
|
+
'hook:pre-task-execute': 'PreTaskExecute',
|
|
422
|
+
'hook:post-task-complete': 'PostTaskComplete',
|
|
423
|
+
'hook:task-failed': 'TaskFailed',
|
|
424
|
+
// File operations
|
|
425
|
+
'hook:pre-file-write': 'PreFileWrite',
|
|
426
|
+
'hook:post-file-write': 'PostFileWrite',
|
|
427
|
+
'hook:pre-file-delete': 'PreFileDelete',
|
|
428
|
+
// Command execution
|
|
429
|
+
'hook:pre-command': 'PreCommand',
|
|
430
|
+
'hook:post-command': 'PostCommand',
|
|
431
|
+
// Agent operations
|
|
432
|
+
'hook:agent-spawned': 'AgentSpawned',
|
|
433
|
+
'hook:agent-terminated': 'AgentTerminated',
|
|
434
|
+
// Memory operations
|
|
435
|
+
'hook:pre-memory-store': 'PreMemoryStore',
|
|
436
|
+
'hook:post-memory-store': 'PostMemoryStore',
|
|
437
|
+
// Learning
|
|
438
|
+
'hook:pattern-detected': 'PatternDetected',
|
|
439
|
+
'hook:strategy-updated': 'StrategyUpdated',
|
|
440
|
+
// Plugin lifecycle
|
|
441
|
+
'hook:plugin-loaded': 'PluginLoaded',
|
|
442
|
+
'hook:plugin-unloaded': 'PluginUnloaded',
|
|
443
|
+
};
|
|
444
|
+
return mapping[event] ?? event;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// ============================================================================
|
|
448
|
+
// Plugin Creator Plugin
|
|
449
|
+
// ============================================================================
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* The Plugin Creator Plugin itself - demonstrates all capabilities.
|
|
453
|
+
*/
|
|
454
|
+
export const pluginCreatorPlugin = new PluginBuilder('plugin-creator', '1.0.0')
|
|
455
|
+
.withDescription('A meta-plugin that creates new plugins with various configurations')
|
|
456
|
+
.withAuthor('Claude Flow Team')
|
|
457
|
+
.withTags(['meta', 'generator', 'developer-tools'])
|
|
458
|
+
.withMCPTools([
|
|
459
|
+
// Tool: Create Plugin
|
|
460
|
+
new MCPToolBuilder('create-plugin')
|
|
461
|
+
.withDescription('Create a new plugin with specified options')
|
|
462
|
+
.addStringParam('name', 'Plugin name (lowercase, hyphens allowed)', { required: true })
|
|
463
|
+
.addStringParam('version', 'Plugin version', { default: '1.0.0' })
|
|
464
|
+
.addStringParam('description', 'Plugin description')
|
|
465
|
+
.addStringParam('template', 'Template to use', {
|
|
466
|
+
enum: Object.keys(PLUGIN_TEMPLATES),
|
|
467
|
+
default: 'minimal',
|
|
468
|
+
})
|
|
469
|
+
.addBooleanParam('includeTools', 'Include MCP tools', { default: false })
|
|
470
|
+
.addBooleanParam('includeHooks', 'Include lifecycle hooks', { default: false })
|
|
471
|
+
.addBooleanParam('includeWorkers', 'Include workers', { default: false })
|
|
472
|
+
.addBooleanParam('includeSwarm', 'Include swarm capabilities', { default: false })
|
|
473
|
+
.withHandler(async (params) => {
|
|
474
|
+
try {
|
|
475
|
+
const result = generatePlugin({
|
|
476
|
+
name: params.name as string,
|
|
477
|
+
version: params.version as string,
|
|
478
|
+
description: params.description as string,
|
|
479
|
+
template: params.template as string,
|
|
480
|
+
features: {
|
|
481
|
+
tools: params.includeTools as boolean,
|
|
482
|
+
hooks: params.includeHooks as boolean,
|
|
483
|
+
workers: params.includeWorkers as boolean,
|
|
484
|
+
swarm: params.includeSwarm as boolean,
|
|
485
|
+
},
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
return {
|
|
489
|
+
content: [{
|
|
490
|
+
type: 'text',
|
|
491
|
+
text: `✅ Plugin "${result.metadata.name}" created successfully!\n\n` +
|
|
492
|
+
`**Metadata:**\n` +
|
|
493
|
+
`- Name: ${result.metadata.name}\n` +
|
|
494
|
+
`- Version: ${result.metadata.version}\n` +
|
|
495
|
+
`- Description: ${result.metadata.description}\n\n` +
|
|
496
|
+
`**Generated Code:**\n\`\`\`typescript\n${result.code}\n\`\`\``,
|
|
497
|
+
}],
|
|
498
|
+
};
|
|
499
|
+
} catch (error) {
|
|
500
|
+
return {
|
|
501
|
+
content: [{
|
|
502
|
+
type: 'text',
|
|
503
|
+
text: `❌ Error creating plugin: ${error instanceof Error ? error.message : String(error)}`,
|
|
504
|
+
}],
|
|
505
|
+
isError: true,
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
})
|
|
509
|
+
.build(),
|
|
510
|
+
|
|
511
|
+
// Tool: List Templates
|
|
512
|
+
new MCPToolBuilder('list-plugin-templates')
|
|
513
|
+
.withDescription('List available plugin templates')
|
|
514
|
+
.withHandler(async () => {
|
|
515
|
+
const templateList = Object.entries(PLUGIN_TEMPLATES)
|
|
516
|
+
.map(([key, tmpl]) =>
|
|
517
|
+
`- **${key}**: ${tmpl.name}\n ${tmpl.description}\n Features: ${tmpl.features.join(', ') || 'none'}`
|
|
518
|
+
)
|
|
519
|
+
.join('\n\n');
|
|
520
|
+
|
|
521
|
+
return {
|
|
522
|
+
content: [{
|
|
523
|
+
type: 'text',
|
|
524
|
+
text: `📦 **Available Plugin Templates:**\n\n${templateList}`,
|
|
525
|
+
}],
|
|
526
|
+
};
|
|
527
|
+
})
|
|
528
|
+
.build(),
|
|
529
|
+
|
|
530
|
+
// Tool: Generate Tool
|
|
531
|
+
new MCPToolBuilder('generate-tool')
|
|
532
|
+
.withDescription('Generate a single MCP tool definition')
|
|
533
|
+
.addStringParam('name', 'Tool name', { required: true })
|
|
534
|
+
.addStringParam('description', 'Tool description')
|
|
535
|
+
.addStringParam('params', 'Comma-separated parameter names')
|
|
536
|
+
.withHandler(async (params) => {
|
|
537
|
+
const { definition, code } = generateToolCode(params.name as string);
|
|
538
|
+
|
|
539
|
+
return {
|
|
540
|
+
content: [{
|
|
541
|
+
type: 'text',
|
|
542
|
+
text: `🔧 **Generated Tool: ${definition.name}**\n\n` +
|
|
543
|
+
`**Code:**\n\`\`\`typescript\n${code}\n\`\`\``,
|
|
544
|
+
}],
|
|
545
|
+
};
|
|
546
|
+
})
|
|
547
|
+
.build(),
|
|
548
|
+
|
|
549
|
+
// Tool: Generate Hook
|
|
550
|
+
new MCPToolBuilder('generate-hook')
|
|
551
|
+
.withDescription('Generate a lifecycle hook definition')
|
|
552
|
+
.addStringParam('event', 'Hook event type', {
|
|
553
|
+
required: true,
|
|
554
|
+
enum: Object.values(HookEvent),
|
|
555
|
+
})
|
|
556
|
+
.addStringParam('priority', 'Hook priority', {
|
|
557
|
+
enum: ['Critical', 'High', 'Normal', 'Low', 'Deferred'],
|
|
558
|
+
default: 'Normal',
|
|
559
|
+
})
|
|
560
|
+
.withHandler(async (params) => {
|
|
561
|
+
const { definition, code } = generateHookCode(params.event as HookEvent);
|
|
562
|
+
|
|
563
|
+
return {
|
|
564
|
+
content: [{
|
|
565
|
+
type: 'text',
|
|
566
|
+
text: `🎣 **Generated Hook: ${definition.name}**\n\n` +
|
|
567
|
+
`Event: ${definition.event}\n` +
|
|
568
|
+
`Priority: ${definition.priority}\n\n` +
|
|
569
|
+
`**Code:**\n\`\`\`typescript\n${code}\n\`\`\``,
|
|
570
|
+
}],
|
|
571
|
+
};
|
|
572
|
+
})
|
|
573
|
+
.build(),
|
|
574
|
+
|
|
575
|
+
// Tool: Generate Worker
|
|
576
|
+
new MCPToolBuilder('generate-worker')
|
|
577
|
+
.withDescription('Generate a worker definition')
|
|
578
|
+
.addStringParam('type', 'Worker type', {
|
|
579
|
+
required: true,
|
|
580
|
+
enum: ['coder', 'reviewer', 'tester', 'researcher', 'planner', 'coordinator', 'security', 'performance', 'specialized'],
|
|
581
|
+
})
|
|
582
|
+
.addStringParam('capabilities', 'Comma-separated capabilities')
|
|
583
|
+
.withHandler(async (params) => {
|
|
584
|
+
const { definition, code } = generateWorkerCode(params.type as string);
|
|
585
|
+
|
|
586
|
+
return {
|
|
587
|
+
content: [{
|
|
588
|
+
type: 'text',
|
|
589
|
+
text: `👷 **Generated Worker: ${definition.name}**\n\n` +
|
|
590
|
+
`Type: ${definition.type}\n` +
|
|
591
|
+
`Capabilities: ${definition.capabilities.join(', ')}\n` +
|
|
592
|
+
`Max Concurrent Tasks: ${definition.maxConcurrentTasks}\n` +
|
|
593
|
+
`Timeout: ${definition.timeout}ms\n\n` +
|
|
594
|
+
`**Code:**\n\`\`\`typescript\n${code}\n\`\`\``,
|
|
595
|
+
}],
|
|
596
|
+
};
|
|
597
|
+
})
|
|
598
|
+
.build(),
|
|
599
|
+
])
|
|
600
|
+
.withHooks([
|
|
601
|
+
// Hook: Log plugin creation
|
|
602
|
+
new HookBuilder(HookEvent.PostToolUse)
|
|
603
|
+
.withName('plugin-creator-logger')
|
|
604
|
+
.withDescription('Log plugin creation events')
|
|
605
|
+
.withPriority(HookPriority.Low)
|
|
606
|
+
.withHandler(async (ctx) => {
|
|
607
|
+
const data = ctx.data as { toolName?: string } | undefined;
|
|
608
|
+
// Only log if this is from the create-plugin tool
|
|
609
|
+
if (data?.toolName === 'create-plugin') {
|
|
610
|
+
console.log('[Plugin Creator] Plugin created:', ctx.data);
|
|
611
|
+
}
|
|
612
|
+
return { success: true };
|
|
613
|
+
})
|
|
614
|
+
.build(),
|
|
615
|
+
])
|
|
616
|
+
.withWorkers([
|
|
617
|
+
WorkerFactory.createCoder('plugin-code-generator', ['code-generation', 'typescript']),
|
|
618
|
+
])
|
|
619
|
+
.onInitialize(async (ctx) => {
|
|
620
|
+
ctx.logger.info('Plugin Creator initialized');
|
|
621
|
+
ctx.logger.info(`Available templates: ${Object.keys(PLUGIN_TEMPLATES).join(', ')}`);
|
|
622
|
+
})
|
|
623
|
+
.build();
|
|
624
|
+
|
|
625
|
+
// ============================================================================
|
|
626
|
+
// Exports
|
|
627
|
+
// ============================================================================
|
|
628
|
+
|
|
629
|
+
export default pluginCreatorPlugin;
|
|
630
|
+
|
|
631
|
+
export {
|
|
632
|
+
generateToolCode,
|
|
633
|
+
generateHookCode,
|
|
634
|
+
generateWorkerCode,
|
|
635
|
+
generateAgentTypeCode,
|
|
636
|
+
};
|