@sparkleideas/testing 3.0.0-alpha.7
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 +547 -0
- package/__tests__/framework.test.ts +21 -0
- package/package.json +61 -0
- package/src/fixtures/agent-fixtures.ts +793 -0
- package/src/fixtures/agents.ts +212 -0
- package/src/fixtures/configurations.ts +491 -0
- package/src/fixtures/index.ts +21 -0
- package/src/fixtures/mcp-fixtures.ts +1030 -0
- package/src/fixtures/memory-entries.ts +328 -0
- package/src/fixtures/memory-fixtures.ts +750 -0
- package/src/fixtures/swarm-fixtures.ts +837 -0
- package/src/fixtures/tasks.ts +309 -0
- package/src/helpers/assertion-helpers.ts +616 -0
- package/src/helpers/assertions.ts +286 -0
- package/src/helpers/create-mock.ts +200 -0
- package/src/helpers/index.ts +182 -0
- package/src/helpers/mock-factory.ts +711 -0
- package/src/helpers/setup-teardown.ts +678 -0
- package/src/helpers/swarm-instance.ts +326 -0
- package/src/helpers/test-application.ts +310 -0
- package/src/helpers/test-utils.ts +670 -0
- package/src/index.ts +232 -0
- package/src/mocks/index.ts +29 -0
- package/src/mocks/mock-mcp-client.ts +723 -0
- package/src/mocks/mock-services.ts +793 -0
- package/src/regression/api-contract.ts +473 -0
- package/src/regression/index.ts +46 -0
- package/src/regression/integration-regression.ts +416 -0
- package/src/regression/performance-baseline.ts +356 -0
- package/src/regression/regression-runner.ts +339 -0
- package/src/regression/security-regression.ts +331 -0
- package/src/setup.ts +127 -0
- package/src/v2-compat/api-compat.test.ts +590 -0
- package/src/v2-compat/cli-compat.test.ts +484 -0
- package/src/v2-compat/compatibility-validator.ts +1072 -0
- package/src/v2-compat/hooks-compat.test.ts +602 -0
- package/src/v2-compat/index.ts +58 -0
- package/src/v2-compat/mcp-compat.test.ts +557 -0
- package/src/v2-compat/report-generator.ts +441 -0
- package/tmp.json +0 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,1030 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sparkleideas/testing - MCP Fixtures
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive mock MCP tools, contexts, and server configurations for testing.
|
|
5
|
+
* Supports all MCP protocol operations and Claude-Flow tool integrations.
|
|
6
|
+
*
|
|
7
|
+
* Based on ADR-005 (MCP-first API design) and V3 specifications.
|
|
8
|
+
*/
|
|
9
|
+
import { vi, type Mock } from 'vitest';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* MCP transport types
|
|
13
|
+
*/
|
|
14
|
+
export type MCPTransportType = 'stdio' | 'http' | 'websocket';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* MCP content types
|
|
18
|
+
*/
|
|
19
|
+
export type MCPContentType = 'text' | 'image' | 'resource';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* MCP input schema type (JSON Schema subset)
|
|
23
|
+
*/
|
|
24
|
+
export interface MCPInputSchema {
|
|
25
|
+
type: 'object';
|
|
26
|
+
properties: Record<string, MCPPropertySchema>;
|
|
27
|
+
required?: string[];
|
|
28
|
+
additionalProperties?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* MCP property schema
|
|
33
|
+
*/
|
|
34
|
+
export interface MCPPropertySchema {
|
|
35
|
+
type: 'string' | 'number' | 'boolean' | 'array' | 'object';
|
|
36
|
+
description?: string;
|
|
37
|
+
enum?: unknown[];
|
|
38
|
+
default?: unknown;
|
|
39
|
+
items?: MCPPropertySchema;
|
|
40
|
+
properties?: Record<string, MCPPropertySchema>;
|
|
41
|
+
required?: string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* MCP tool definition
|
|
46
|
+
*/
|
|
47
|
+
export interface MCPTool {
|
|
48
|
+
name: string;
|
|
49
|
+
description: string;
|
|
50
|
+
inputSchema: MCPInputSchema;
|
|
51
|
+
handler?: (params: Record<string, unknown>) => Promise<MCPToolResult>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* MCP tool result
|
|
56
|
+
*/
|
|
57
|
+
export interface MCPToolResult {
|
|
58
|
+
content: MCPContent[];
|
|
59
|
+
isError?: boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* MCP content (text, image, or resource)
|
|
64
|
+
*/
|
|
65
|
+
export type MCPContent = MCPTextContent | MCPImageContent | MCPResourceContent;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* MCP text content
|
|
69
|
+
*/
|
|
70
|
+
export interface MCPTextContent {
|
|
71
|
+
type: 'text';
|
|
72
|
+
text: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* MCP image content
|
|
77
|
+
*/
|
|
78
|
+
export interface MCPImageContent {
|
|
79
|
+
type: 'image';
|
|
80
|
+
data: string;
|
|
81
|
+
mimeType: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* MCP resource content
|
|
86
|
+
*/
|
|
87
|
+
export interface MCPResourceContent {
|
|
88
|
+
type: 'resource';
|
|
89
|
+
resource: {
|
|
90
|
+
uri: string;
|
|
91
|
+
mimeType?: string;
|
|
92
|
+
text?: string;
|
|
93
|
+
blob?: string;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* MCP server configuration
|
|
99
|
+
*/
|
|
100
|
+
export interface MCPServerConfig {
|
|
101
|
+
name: string;
|
|
102
|
+
version: string;
|
|
103
|
+
transport: MCPTransportConfig;
|
|
104
|
+
tools?: MCPTool[];
|
|
105
|
+
resources?: MCPResource[];
|
|
106
|
+
prompts?: MCPPrompt[];
|
|
107
|
+
capabilities?: MCPCapabilities;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* MCP transport configuration
|
|
112
|
+
*/
|
|
113
|
+
export interface MCPTransportConfig {
|
|
114
|
+
type: MCPTransportType;
|
|
115
|
+
port?: number;
|
|
116
|
+
host?: string;
|
|
117
|
+
path?: string;
|
|
118
|
+
timeout?: number;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* MCP resource definition
|
|
123
|
+
*/
|
|
124
|
+
export interface MCPResource {
|
|
125
|
+
uri: string;
|
|
126
|
+
name: string;
|
|
127
|
+
description?: string;
|
|
128
|
+
mimeType?: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* MCP prompt definition
|
|
133
|
+
*/
|
|
134
|
+
export interface MCPPrompt {
|
|
135
|
+
name: string;
|
|
136
|
+
description?: string;
|
|
137
|
+
arguments?: MCPPromptArgument[];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* MCP prompt argument
|
|
142
|
+
*/
|
|
143
|
+
export interface MCPPromptArgument {
|
|
144
|
+
name: string;
|
|
145
|
+
description?: string;
|
|
146
|
+
required?: boolean;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* MCP capabilities
|
|
151
|
+
*/
|
|
152
|
+
export interface MCPCapabilities {
|
|
153
|
+
tools?: boolean;
|
|
154
|
+
resources?: boolean;
|
|
155
|
+
prompts?: boolean;
|
|
156
|
+
logging?: boolean;
|
|
157
|
+
experimental?: Record<string, boolean>;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* MCP request base
|
|
162
|
+
*/
|
|
163
|
+
export interface MCPRequestBase {
|
|
164
|
+
jsonrpc: '2.0';
|
|
165
|
+
id: string | number;
|
|
166
|
+
method: string;
|
|
167
|
+
params?: Record<string, unknown>;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* MCP response base
|
|
172
|
+
*/
|
|
173
|
+
export interface MCPResponseBase<T = unknown> {
|
|
174
|
+
jsonrpc: '2.0';
|
|
175
|
+
id: string | number;
|
|
176
|
+
result?: T;
|
|
177
|
+
error?: MCPError;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* MCP error
|
|
182
|
+
*/
|
|
183
|
+
export interface MCPError {
|
|
184
|
+
code: number;
|
|
185
|
+
message: string;
|
|
186
|
+
data?: unknown;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* MCP server status
|
|
191
|
+
*/
|
|
192
|
+
export interface MCPServerStatus {
|
|
193
|
+
running: boolean;
|
|
194
|
+
transport: MCPTransportType;
|
|
195
|
+
connectedClients: number;
|
|
196
|
+
toolsRegistered: number;
|
|
197
|
+
resourcesRegistered: number;
|
|
198
|
+
promptsRegistered: number;
|
|
199
|
+
requestsHandled: number;
|
|
200
|
+
errorsCount: number;
|
|
201
|
+
uptime: number;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* MCP session context
|
|
206
|
+
*/
|
|
207
|
+
export interface MCPSessionContext {
|
|
208
|
+
sessionId: string;
|
|
209
|
+
clientInfo: {
|
|
210
|
+
name: string;
|
|
211
|
+
version: string;
|
|
212
|
+
};
|
|
213
|
+
capabilities: MCPCapabilities;
|
|
214
|
+
startedAt: Date;
|
|
215
|
+
lastActivity: Date;
|
|
216
|
+
requestCount: number;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Pre-defined MCP tools for Claude-Flow
|
|
221
|
+
*/
|
|
222
|
+
export const mcpTools: Record<string, MCPTool> = {
|
|
223
|
+
// Swarm management tools
|
|
224
|
+
swarmInit: {
|
|
225
|
+
name: 'swarm_init',
|
|
226
|
+
description: 'Initialize a new swarm with specified topology and configuration',
|
|
227
|
+
inputSchema: {
|
|
228
|
+
type: 'object',
|
|
229
|
+
properties: {
|
|
230
|
+
topology: {
|
|
231
|
+
type: 'string',
|
|
232
|
+
description: 'Swarm topology (hierarchical, mesh, adaptive, hierarchical-mesh)',
|
|
233
|
+
enum: ['hierarchical', 'mesh', 'ring', 'star', 'adaptive', 'hierarchical-mesh'],
|
|
234
|
+
},
|
|
235
|
+
maxAgents: {
|
|
236
|
+
type: 'number',
|
|
237
|
+
description: 'Maximum number of agents in the swarm',
|
|
238
|
+
default: 15,
|
|
239
|
+
},
|
|
240
|
+
consensusProtocol: {
|
|
241
|
+
type: 'string',
|
|
242
|
+
description: 'Consensus protocol to use',
|
|
243
|
+
enum: ['raft', 'pbft', 'gossip', 'byzantine'],
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
required: ['topology'],
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
agentSpawn: {
|
|
251
|
+
name: 'agent_spawn',
|
|
252
|
+
description: 'Spawn a new agent with specified type and configuration',
|
|
253
|
+
inputSchema: {
|
|
254
|
+
type: 'object',
|
|
255
|
+
properties: {
|
|
256
|
+
type: {
|
|
257
|
+
type: 'string',
|
|
258
|
+
description: 'Agent type (queen-coordinator, coder, tester, etc.)',
|
|
259
|
+
},
|
|
260
|
+
name: {
|
|
261
|
+
type: 'string',
|
|
262
|
+
description: 'Agent name',
|
|
263
|
+
},
|
|
264
|
+
capabilities: {
|
|
265
|
+
type: 'array',
|
|
266
|
+
description: 'Agent capabilities',
|
|
267
|
+
items: { type: 'string' },
|
|
268
|
+
},
|
|
269
|
+
priority: {
|
|
270
|
+
type: 'number',
|
|
271
|
+
description: 'Agent priority (0-100)',
|
|
272
|
+
default: 50,
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
required: ['type'],
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
taskOrchestrate: {
|
|
280
|
+
name: 'task_orchestrate',
|
|
281
|
+
description: 'Orchestrate a task across multiple agents',
|
|
282
|
+
inputSchema: {
|
|
283
|
+
type: 'object',
|
|
284
|
+
properties: {
|
|
285
|
+
taskName: {
|
|
286
|
+
type: 'string',
|
|
287
|
+
description: 'Name of the task',
|
|
288
|
+
},
|
|
289
|
+
taskType: {
|
|
290
|
+
type: 'string',
|
|
291
|
+
description: 'Type of task (security, coding, testing, review)',
|
|
292
|
+
},
|
|
293
|
+
payload: {
|
|
294
|
+
type: 'object',
|
|
295
|
+
description: 'Task payload',
|
|
296
|
+
},
|
|
297
|
+
agents: {
|
|
298
|
+
type: 'array',
|
|
299
|
+
description: 'List of agent IDs to coordinate',
|
|
300
|
+
items: { type: 'string' },
|
|
301
|
+
},
|
|
302
|
+
parallel: {
|
|
303
|
+
type: 'boolean',
|
|
304
|
+
description: 'Execute tasks in parallel',
|
|
305
|
+
default: true,
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
required: ['taskName', 'taskType'],
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
// Memory tools
|
|
313
|
+
memoryStore: {
|
|
314
|
+
name: 'memory_store',
|
|
315
|
+
description: 'Store a value in memory with optional embedding',
|
|
316
|
+
inputSchema: {
|
|
317
|
+
type: 'object',
|
|
318
|
+
properties: {
|
|
319
|
+
key: {
|
|
320
|
+
type: 'string',
|
|
321
|
+
description: 'Memory key',
|
|
322
|
+
},
|
|
323
|
+
value: {
|
|
324
|
+
type: 'object',
|
|
325
|
+
description: 'Value to store',
|
|
326
|
+
},
|
|
327
|
+
type: {
|
|
328
|
+
type: 'string',
|
|
329
|
+
description: 'Memory type',
|
|
330
|
+
enum: ['short-term', 'long-term', 'semantic', 'episodic'],
|
|
331
|
+
},
|
|
332
|
+
ttl: {
|
|
333
|
+
type: 'number',
|
|
334
|
+
description: 'Time-to-live in milliseconds',
|
|
335
|
+
},
|
|
336
|
+
generateEmbedding: {
|
|
337
|
+
type: 'boolean',
|
|
338
|
+
description: 'Generate vector embedding for semantic search',
|
|
339
|
+
default: false,
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
required: ['key', 'value'],
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
|
|
346
|
+
memorySearch: {
|
|
347
|
+
name: 'memory_search',
|
|
348
|
+
description: 'Search memory using semantic vector search',
|
|
349
|
+
inputSchema: {
|
|
350
|
+
type: 'object',
|
|
351
|
+
properties: {
|
|
352
|
+
query: {
|
|
353
|
+
type: 'string',
|
|
354
|
+
description: 'Search query',
|
|
355
|
+
},
|
|
356
|
+
topK: {
|
|
357
|
+
type: 'number',
|
|
358
|
+
description: 'Number of results to return',
|
|
359
|
+
default: 10,
|
|
360
|
+
},
|
|
361
|
+
threshold: {
|
|
362
|
+
type: 'number',
|
|
363
|
+
description: 'Minimum similarity threshold (0-1)',
|
|
364
|
+
default: 0.7,
|
|
365
|
+
},
|
|
366
|
+
filters: {
|
|
367
|
+
type: 'object',
|
|
368
|
+
description: 'Additional filters',
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
required: ['query'],
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
|
|
375
|
+
// Status tools
|
|
376
|
+
swarmStatus: {
|
|
377
|
+
name: 'swarm_status',
|
|
378
|
+
description: 'Get current swarm status and metrics',
|
|
379
|
+
inputSchema: {
|
|
380
|
+
type: 'object',
|
|
381
|
+
properties: {
|
|
382
|
+
includeMetrics: {
|
|
383
|
+
type: 'boolean',
|
|
384
|
+
description: 'Include detailed metrics',
|
|
385
|
+
default: true,
|
|
386
|
+
},
|
|
387
|
+
includeAgents: {
|
|
388
|
+
type: 'boolean',
|
|
389
|
+
description: 'Include agent details',
|
|
390
|
+
default: false,
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
agentList: {
|
|
397
|
+
name: 'agent_list',
|
|
398
|
+
description: 'List all agents in the swarm',
|
|
399
|
+
inputSchema: {
|
|
400
|
+
type: 'object',
|
|
401
|
+
properties: {
|
|
402
|
+
status: {
|
|
403
|
+
type: 'string',
|
|
404
|
+
description: 'Filter by agent status',
|
|
405
|
+
enum: ['idle', 'busy', 'terminated', 'error', 'all'],
|
|
406
|
+
},
|
|
407
|
+
type: {
|
|
408
|
+
type: 'string',
|
|
409
|
+
description: 'Filter by agent type',
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
|
|
415
|
+
agentMetrics: {
|
|
416
|
+
name: 'agent_metrics',
|
|
417
|
+
description: 'Get metrics for a specific agent',
|
|
418
|
+
inputSchema: {
|
|
419
|
+
type: 'object',
|
|
420
|
+
properties: {
|
|
421
|
+
agentId: {
|
|
422
|
+
type: 'string',
|
|
423
|
+
description: 'Agent ID',
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
required: ['agentId'],
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
|
|
430
|
+
// Neural/Learning tools
|
|
431
|
+
neuralStatus: {
|
|
432
|
+
name: 'neural_status',
|
|
433
|
+
description: 'Get neural learning system status',
|
|
434
|
+
inputSchema: {
|
|
435
|
+
type: 'object',
|
|
436
|
+
properties: {
|
|
437
|
+
includePatterns: {
|
|
438
|
+
type: 'boolean',
|
|
439
|
+
description: 'Include learned patterns summary',
|
|
440
|
+
default: false,
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
|
|
446
|
+
neuralTrain: {
|
|
447
|
+
name: 'neural_train',
|
|
448
|
+
description: 'Trigger neural training with current data',
|
|
449
|
+
inputSchema: {
|
|
450
|
+
type: 'object',
|
|
451
|
+
properties: {
|
|
452
|
+
algorithm: {
|
|
453
|
+
type: 'string',
|
|
454
|
+
description: 'Training algorithm',
|
|
455
|
+
enum: ['ppo', 'dqn', 'a2c', 'sarsa', 'q-learning'],
|
|
456
|
+
},
|
|
457
|
+
epochs: {
|
|
458
|
+
type: 'number',
|
|
459
|
+
description: 'Number of training epochs',
|
|
460
|
+
default: 10,
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
|
|
466
|
+
// GitHub integration tools
|
|
467
|
+
githubSwarm: {
|
|
468
|
+
name: 'github_swarm',
|
|
469
|
+
description: 'Initialize GitHub integration for a repository',
|
|
470
|
+
inputSchema: {
|
|
471
|
+
type: 'object',
|
|
472
|
+
properties: {
|
|
473
|
+
repo: {
|
|
474
|
+
type: 'string',
|
|
475
|
+
description: 'Repository in owner/repo format',
|
|
476
|
+
},
|
|
477
|
+
features: {
|
|
478
|
+
type: 'array',
|
|
479
|
+
description: 'Features to enable',
|
|
480
|
+
items: { type: 'string' },
|
|
481
|
+
default: ['issues', 'prs', 'reviews'],
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
required: ['repo'],
|
|
485
|
+
},
|
|
486
|
+
},
|
|
487
|
+
|
|
488
|
+
codeReview: {
|
|
489
|
+
name: 'code_review',
|
|
490
|
+
description: 'Request code review from swarm agents',
|
|
491
|
+
inputSchema: {
|
|
492
|
+
type: 'object',
|
|
493
|
+
properties: {
|
|
494
|
+
prNumber: {
|
|
495
|
+
type: 'number',
|
|
496
|
+
description: 'Pull request number',
|
|
497
|
+
},
|
|
498
|
+
repo: {
|
|
499
|
+
type: 'string',
|
|
500
|
+
description: 'Repository in owner/repo format',
|
|
501
|
+
},
|
|
502
|
+
focus: {
|
|
503
|
+
type: 'array',
|
|
504
|
+
description: 'Review focus areas',
|
|
505
|
+
items: { type: 'string' },
|
|
506
|
+
default: ['security', 'performance', 'style'],
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
required: ['prNumber', 'repo'],
|
|
510
|
+
},
|
|
511
|
+
},
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Pre-defined MCP resources
|
|
516
|
+
*/
|
|
517
|
+
export const mcpResources: Record<string, MCPResource> = {
|
|
518
|
+
swarmConfig: {
|
|
519
|
+
uri: '@sparkleideas/claude-flow://config/swarm',
|
|
520
|
+
name: 'Swarm Configuration',
|
|
521
|
+
description: 'Current swarm configuration',
|
|
522
|
+
mimeType: 'application/json',
|
|
523
|
+
},
|
|
524
|
+
|
|
525
|
+
agentRegistry: {
|
|
526
|
+
uri: '@sparkleideas/claude-flow://agents/registry',
|
|
527
|
+
name: 'Agent Registry',
|
|
528
|
+
description: 'Registry of all available agent types',
|
|
529
|
+
mimeType: 'application/json',
|
|
530
|
+
},
|
|
531
|
+
|
|
532
|
+
memoryStats: {
|
|
533
|
+
uri: '@sparkleideas/claude-flow://memory/stats',
|
|
534
|
+
name: 'Memory Statistics',
|
|
535
|
+
description: 'Memory system statistics and metrics',
|
|
536
|
+
mimeType: 'application/json',
|
|
537
|
+
},
|
|
538
|
+
|
|
539
|
+
learningPatterns: {
|
|
540
|
+
uri: '@sparkleideas/claude-flow://neural/patterns',
|
|
541
|
+
name: 'Learning Patterns',
|
|
542
|
+
description: 'Learned patterns from ReasoningBank',
|
|
543
|
+
mimeType: 'application/json',
|
|
544
|
+
},
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Pre-defined MCP prompts
|
|
549
|
+
*/
|
|
550
|
+
export const mcpPrompts: Record<string, MCPPrompt> = {
|
|
551
|
+
codeAnalysis: {
|
|
552
|
+
name: 'analyze_code',
|
|
553
|
+
description: 'Analyze code for security, performance, and style issues',
|
|
554
|
+
arguments: [
|
|
555
|
+
{ name: 'language', description: 'Programming language', required: true },
|
|
556
|
+
{ name: 'focus', description: 'Analysis focus area', required: false },
|
|
557
|
+
],
|
|
558
|
+
},
|
|
559
|
+
|
|
560
|
+
taskPlanning: {
|
|
561
|
+
name: 'plan_task',
|
|
562
|
+
description: 'Generate a task execution plan',
|
|
563
|
+
arguments: [
|
|
564
|
+
{ name: 'objective', description: 'Task objective', required: true },
|
|
565
|
+
{ name: 'constraints', description: 'Task constraints', required: false },
|
|
566
|
+
],
|
|
567
|
+
},
|
|
568
|
+
|
|
569
|
+
securityReview: {
|
|
570
|
+
name: 'security_review',
|
|
571
|
+
description: 'Perform security review on code or configuration',
|
|
572
|
+
arguments: [
|
|
573
|
+
{ name: 'target', description: 'Review target (file, directory, config)', required: true },
|
|
574
|
+
{ name: 'severity', description: 'Minimum severity level', required: false },
|
|
575
|
+
],
|
|
576
|
+
},
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Pre-defined MCP server configurations
|
|
581
|
+
*/
|
|
582
|
+
export const mcpServerConfigs: Record<string, MCPServerConfig> = {
|
|
583
|
+
development: {
|
|
584
|
+
name: 'claude-flow-dev',
|
|
585
|
+
version: '3.0.0-alpha',
|
|
586
|
+
transport: {
|
|
587
|
+
type: 'http',
|
|
588
|
+
port: 3000,
|
|
589
|
+
host: 'localhost',
|
|
590
|
+
timeout: 30000,
|
|
591
|
+
},
|
|
592
|
+
tools: Object.values(mcpTools),
|
|
593
|
+
resources: Object.values(mcpResources),
|
|
594
|
+
prompts: Object.values(mcpPrompts),
|
|
595
|
+
capabilities: {
|
|
596
|
+
tools: true,
|
|
597
|
+
resources: true,
|
|
598
|
+
prompts: true,
|
|
599
|
+
logging: true,
|
|
600
|
+
experimental: { streaming: true },
|
|
601
|
+
},
|
|
602
|
+
},
|
|
603
|
+
|
|
604
|
+
production: {
|
|
605
|
+
name: '@sparkleideas/claude-flow',
|
|
606
|
+
version: '3.0.0',
|
|
607
|
+
transport: {
|
|
608
|
+
type: 'http',
|
|
609
|
+
port: 443,
|
|
610
|
+
host: '0.0.0.0',
|
|
611
|
+
timeout: 15000,
|
|
612
|
+
},
|
|
613
|
+
capabilities: {
|
|
614
|
+
tools: true,
|
|
615
|
+
resources: true,
|
|
616
|
+
prompts: true,
|
|
617
|
+
logging: false,
|
|
618
|
+
},
|
|
619
|
+
},
|
|
620
|
+
|
|
621
|
+
stdio: {
|
|
622
|
+
name: 'claude-flow-stdio',
|
|
623
|
+
version: '3.0.0-alpha',
|
|
624
|
+
transport: {
|
|
625
|
+
type: 'stdio',
|
|
626
|
+
timeout: 60000,
|
|
627
|
+
},
|
|
628
|
+
capabilities: {
|
|
629
|
+
tools: true,
|
|
630
|
+
resources: true,
|
|
631
|
+
prompts: true,
|
|
632
|
+
logging: true,
|
|
633
|
+
},
|
|
634
|
+
},
|
|
635
|
+
|
|
636
|
+
websocket: {
|
|
637
|
+
name: 'claude-flow-ws',
|
|
638
|
+
version: '3.0.0-alpha',
|
|
639
|
+
transport: {
|
|
640
|
+
type: 'websocket',
|
|
641
|
+
port: 8080,
|
|
642
|
+
host: 'localhost',
|
|
643
|
+
path: '/mcp',
|
|
644
|
+
timeout: 30000,
|
|
645
|
+
},
|
|
646
|
+
capabilities: {
|
|
647
|
+
tools: true,
|
|
648
|
+
resources: true,
|
|
649
|
+
prompts: true,
|
|
650
|
+
logging: true,
|
|
651
|
+
experimental: { streaming: true, multiplexing: true },
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Pre-defined MCP tool results
|
|
658
|
+
*/
|
|
659
|
+
export const mcpToolResults: Record<string, MCPToolResult> = {
|
|
660
|
+
success: {
|
|
661
|
+
content: [
|
|
662
|
+
{
|
|
663
|
+
type: 'text',
|
|
664
|
+
text: 'Operation completed successfully',
|
|
665
|
+
},
|
|
666
|
+
],
|
|
667
|
+
},
|
|
668
|
+
|
|
669
|
+
swarmInitialized: {
|
|
670
|
+
content: [
|
|
671
|
+
{
|
|
672
|
+
type: 'text',
|
|
673
|
+
text: JSON.stringify({
|
|
674
|
+
swarmId: 'swarm-001',
|
|
675
|
+
topology: 'hierarchical-mesh',
|
|
676
|
+
status: 'active',
|
|
677
|
+
agentCount: 15,
|
|
678
|
+
}),
|
|
679
|
+
},
|
|
680
|
+
],
|
|
681
|
+
},
|
|
682
|
+
|
|
683
|
+
agentSpawned: {
|
|
684
|
+
content: [
|
|
685
|
+
{
|
|
686
|
+
type: 'text',
|
|
687
|
+
text: JSON.stringify({
|
|
688
|
+
agentId: 'agent-coder-001',
|
|
689
|
+
type: 'coder',
|
|
690
|
+
status: 'idle',
|
|
691
|
+
capabilities: ['coding', 'implementation', 'debugging'],
|
|
692
|
+
}),
|
|
693
|
+
},
|
|
694
|
+
],
|
|
695
|
+
},
|
|
696
|
+
|
|
697
|
+
memorySearchResults: {
|
|
698
|
+
content: [
|
|
699
|
+
{
|
|
700
|
+
type: 'text',
|
|
701
|
+
text: JSON.stringify({
|
|
702
|
+
results: [
|
|
703
|
+
{ key: 'pattern-001', score: 0.95 },
|
|
704
|
+
{ key: 'pattern-002', score: 0.88 },
|
|
705
|
+
],
|
|
706
|
+
totalCount: 2,
|
|
707
|
+
latencyMs: 15,
|
|
708
|
+
}),
|
|
709
|
+
},
|
|
710
|
+
],
|
|
711
|
+
},
|
|
712
|
+
|
|
713
|
+
error: {
|
|
714
|
+
content: [
|
|
715
|
+
{
|
|
716
|
+
type: 'text',
|
|
717
|
+
text: 'Operation failed: Invalid parameters',
|
|
718
|
+
},
|
|
719
|
+
],
|
|
720
|
+
isError: true,
|
|
721
|
+
},
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Pre-defined MCP errors
|
|
726
|
+
*/
|
|
727
|
+
export const mcpErrors: Record<string, MCPError> = {
|
|
728
|
+
parseError: {
|
|
729
|
+
code: -32700,
|
|
730
|
+
message: 'Parse error',
|
|
731
|
+
data: { details: 'Invalid JSON received' },
|
|
732
|
+
},
|
|
733
|
+
|
|
734
|
+
invalidRequest: {
|
|
735
|
+
code: -32600,
|
|
736
|
+
message: 'Invalid request',
|
|
737
|
+
data: { details: 'Missing required field' },
|
|
738
|
+
},
|
|
739
|
+
|
|
740
|
+
methodNotFound: {
|
|
741
|
+
code: -32601,
|
|
742
|
+
message: 'Method not found',
|
|
743
|
+
data: { method: 'unknown_method' },
|
|
744
|
+
},
|
|
745
|
+
|
|
746
|
+
invalidParams: {
|
|
747
|
+
code: -32602,
|
|
748
|
+
message: 'Invalid params',
|
|
749
|
+
data: { param: 'topology', expected: 'string' },
|
|
750
|
+
},
|
|
751
|
+
|
|
752
|
+
internalError: {
|
|
753
|
+
code: -32603,
|
|
754
|
+
message: 'Internal error',
|
|
755
|
+
data: { details: 'Unexpected server error' },
|
|
756
|
+
},
|
|
757
|
+
|
|
758
|
+
toolNotFound: {
|
|
759
|
+
code: -32001,
|
|
760
|
+
message: 'Tool not found',
|
|
761
|
+
data: { tool: 'unknown_tool' },
|
|
762
|
+
},
|
|
763
|
+
|
|
764
|
+
resourceNotFound: {
|
|
765
|
+
code: -32002,
|
|
766
|
+
message: 'Resource not found',
|
|
767
|
+
data: { uri: 'unknown://resource' },
|
|
768
|
+
},
|
|
769
|
+
};
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Pre-defined session contexts
|
|
773
|
+
*/
|
|
774
|
+
export const mcpSessionContexts: Record<string, MCPSessionContext> = {
|
|
775
|
+
active: {
|
|
776
|
+
sessionId: 'session-001',
|
|
777
|
+
clientInfo: {
|
|
778
|
+
name: 'claude-code',
|
|
779
|
+
version: '1.0.0',
|
|
780
|
+
},
|
|
781
|
+
capabilities: {
|
|
782
|
+
tools: true,
|
|
783
|
+
resources: true,
|
|
784
|
+
prompts: true,
|
|
785
|
+
},
|
|
786
|
+
startedAt: new Date('2024-01-15T10:00:00Z'),
|
|
787
|
+
lastActivity: new Date(),
|
|
788
|
+
requestCount: 42,
|
|
789
|
+
},
|
|
790
|
+
|
|
791
|
+
new: {
|
|
792
|
+
sessionId: 'session-002',
|
|
793
|
+
clientInfo: {
|
|
794
|
+
name: 'test-client',
|
|
795
|
+
version: '0.1.0',
|
|
796
|
+
},
|
|
797
|
+
capabilities: {
|
|
798
|
+
tools: true,
|
|
799
|
+
},
|
|
800
|
+
startedAt: new Date(),
|
|
801
|
+
lastActivity: new Date(),
|
|
802
|
+
requestCount: 0,
|
|
803
|
+
},
|
|
804
|
+
|
|
805
|
+
expired: {
|
|
806
|
+
sessionId: 'session-003',
|
|
807
|
+
clientInfo: {
|
|
808
|
+
name: 'old-client',
|
|
809
|
+
version: '0.0.1',
|
|
810
|
+
},
|
|
811
|
+
capabilities: {},
|
|
812
|
+
startedAt: new Date('2024-01-01T00:00:00Z'),
|
|
813
|
+
lastActivity: new Date('2024-01-01T01:00:00Z'),
|
|
814
|
+
requestCount: 5,
|
|
815
|
+
},
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
/**
|
|
819
|
+
* Factory function to create MCP tool
|
|
820
|
+
*/
|
|
821
|
+
export function createMCPTool(
|
|
822
|
+
base: keyof typeof mcpTools,
|
|
823
|
+
overrides?: Partial<MCPTool>
|
|
824
|
+
): MCPTool {
|
|
825
|
+
return {
|
|
826
|
+
...mcpTools[base],
|
|
827
|
+
...overrides,
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* Factory function to create MCP server config
|
|
833
|
+
*/
|
|
834
|
+
export function createMCPServerConfig(
|
|
835
|
+
base: keyof typeof mcpServerConfigs = 'development',
|
|
836
|
+
overrides?: Partial<MCPServerConfig>
|
|
837
|
+
): MCPServerConfig {
|
|
838
|
+
return {
|
|
839
|
+
...mcpServerConfigs[base],
|
|
840
|
+
...overrides,
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Factory function to create MCP request
|
|
846
|
+
*/
|
|
847
|
+
export function createMCPRequest(
|
|
848
|
+
method: string,
|
|
849
|
+
params?: Record<string, unknown>,
|
|
850
|
+
overrides?: Partial<MCPRequestBase>
|
|
851
|
+
): MCPRequestBase {
|
|
852
|
+
return {
|
|
853
|
+
jsonrpc: '2.0',
|
|
854
|
+
id: `req-${Date.now()}`,
|
|
855
|
+
method,
|
|
856
|
+
params,
|
|
857
|
+
...overrides,
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* Factory function to create MCP response
|
|
863
|
+
*/
|
|
864
|
+
export function createMCPResponse<T>(
|
|
865
|
+
id: string | number,
|
|
866
|
+
result?: T,
|
|
867
|
+
error?: MCPError
|
|
868
|
+
): MCPResponseBase<T> {
|
|
869
|
+
return {
|
|
870
|
+
jsonrpc: '2.0',
|
|
871
|
+
id,
|
|
872
|
+
result,
|
|
873
|
+
error,
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Factory function to create MCP tool result
|
|
879
|
+
*/
|
|
880
|
+
export function createMCPToolResult(
|
|
881
|
+
text: string,
|
|
882
|
+
isError: boolean = false
|
|
883
|
+
): MCPToolResult {
|
|
884
|
+
return {
|
|
885
|
+
content: [{ type: 'text', text }],
|
|
886
|
+
isError,
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* Factory function to create session context
|
|
892
|
+
*/
|
|
893
|
+
export function createMCPSessionContext(
|
|
894
|
+
base: keyof typeof mcpSessionContexts = 'active',
|
|
895
|
+
overrides?: Partial<MCPSessionContext>
|
|
896
|
+
): MCPSessionContext {
|
|
897
|
+
return {
|
|
898
|
+
...mcpSessionContexts[base],
|
|
899
|
+
...overrides,
|
|
900
|
+
sessionId: overrides?.sessionId ?? `session-${Date.now()}`,
|
|
901
|
+
startedAt: overrides?.startedAt ?? new Date(),
|
|
902
|
+
lastActivity: overrides?.lastActivity ?? new Date(),
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Invalid MCP configurations for error testing
|
|
908
|
+
*/
|
|
909
|
+
export const invalidMCPConfigs = {
|
|
910
|
+
emptyName: {
|
|
911
|
+
...mcpServerConfigs.development,
|
|
912
|
+
name: '',
|
|
913
|
+
},
|
|
914
|
+
|
|
915
|
+
invalidPort: {
|
|
916
|
+
...mcpServerConfigs.development,
|
|
917
|
+
transport: {
|
|
918
|
+
type: 'http' as MCPTransportType,
|
|
919
|
+
port: -1,
|
|
920
|
+
host: 'localhost',
|
|
921
|
+
},
|
|
922
|
+
},
|
|
923
|
+
|
|
924
|
+
missingTransport: {
|
|
925
|
+
name: 'invalid-server',
|
|
926
|
+
version: '1.0.0',
|
|
927
|
+
transport: undefined as unknown as MCPTransportConfig,
|
|
928
|
+
},
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* Mock MCP client interface
|
|
933
|
+
*/
|
|
934
|
+
export interface MockMCPClient {
|
|
935
|
+
connect: Mock<() => Promise<void>>;
|
|
936
|
+
disconnect: Mock<() => Promise<void>>;
|
|
937
|
+
callTool: Mock<(name: string, params: Record<string, unknown>) => Promise<MCPToolResult>>;
|
|
938
|
+
listTools: Mock<() => Promise<MCPTool[]>>;
|
|
939
|
+
readResource: Mock<(uri: string) => Promise<MCPResourceContent>>;
|
|
940
|
+
listResources: Mock<() => Promise<MCPResource[]>>;
|
|
941
|
+
getPrompt: Mock<(name: string, args: Record<string, string>) => Promise<string>>;
|
|
942
|
+
listPrompts: Mock<() => Promise<MCPPrompt[]>>;
|
|
943
|
+
isConnected: Mock<() => boolean>;
|
|
944
|
+
getSessionContext: Mock<() => MCPSessionContext | null>;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Create a mock MCP client
|
|
949
|
+
*/
|
|
950
|
+
export function createMockMCPClient(): MockMCPClient {
|
|
951
|
+
return {
|
|
952
|
+
connect: vi.fn().mockResolvedValue(undefined),
|
|
953
|
+
disconnect: vi.fn().mockResolvedValue(undefined),
|
|
954
|
+
callTool: vi.fn().mockResolvedValue(mcpToolResults.success),
|
|
955
|
+
listTools: vi.fn().mockResolvedValue(Object.values(mcpTools)),
|
|
956
|
+
readResource: vi.fn().mockResolvedValue({
|
|
957
|
+
type: 'resource',
|
|
958
|
+
resource: { uri: 'test://resource', text: '{}' },
|
|
959
|
+
}),
|
|
960
|
+
listResources: vi.fn().mockResolvedValue(Object.values(mcpResources)),
|
|
961
|
+
getPrompt: vi.fn().mockResolvedValue('Generated prompt text'),
|
|
962
|
+
listPrompts: vi.fn().mockResolvedValue(Object.values(mcpPrompts)),
|
|
963
|
+
isConnected: vi.fn().mockReturnValue(true),
|
|
964
|
+
getSessionContext: vi.fn().mockReturnValue(mcpSessionContexts.active),
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Mock MCP server interface
|
|
970
|
+
*/
|
|
971
|
+
export interface MockMCPServer {
|
|
972
|
+
start: Mock<() => Promise<void>>;
|
|
973
|
+
stop: Mock<() => Promise<void>>;
|
|
974
|
+
registerTool: Mock<(tool: MCPTool) => void>;
|
|
975
|
+
registerResource: Mock<(resource: MCPResource) => void>;
|
|
976
|
+
registerPrompt: Mock<(prompt: MCPPrompt) => void>;
|
|
977
|
+
handleRequest: Mock<(request: MCPRequestBase) => Promise<MCPResponseBase>>;
|
|
978
|
+
getStatus: Mock<() => MCPServerStatus>;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
/**
|
|
982
|
+
* Create a mock MCP server
|
|
983
|
+
*/
|
|
984
|
+
export function createMockMCPServer(): MockMCPServer {
|
|
985
|
+
return {
|
|
986
|
+
start: vi.fn().mockResolvedValue(undefined),
|
|
987
|
+
stop: vi.fn().mockResolvedValue(undefined),
|
|
988
|
+
registerTool: vi.fn(),
|
|
989
|
+
registerResource: vi.fn(),
|
|
990
|
+
registerPrompt: vi.fn(),
|
|
991
|
+
handleRequest: vi.fn().mockResolvedValue({
|
|
992
|
+
jsonrpc: '2.0',
|
|
993
|
+
id: 1,
|
|
994
|
+
result: { success: true },
|
|
995
|
+
}),
|
|
996
|
+
getStatus: vi.fn().mockReturnValue({
|
|
997
|
+
running: true,
|
|
998
|
+
transport: 'http',
|
|
999
|
+
connectedClients: 1,
|
|
1000
|
+
toolsRegistered: Object.keys(mcpTools).length,
|
|
1001
|
+
resourcesRegistered: Object.keys(mcpResources).length,
|
|
1002
|
+
promptsRegistered: Object.keys(mcpPrompts).length,
|
|
1003
|
+
requestsHandled: 100,
|
|
1004
|
+
errorsCount: 0,
|
|
1005
|
+
uptime: 3600000,
|
|
1006
|
+
}),
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* Mock transport interface
|
|
1012
|
+
*/
|
|
1013
|
+
export interface MockMCPTransport {
|
|
1014
|
+
send: Mock<(message: string) => Promise<void>>;
|
|
1015
|
+
receive: Mock<() => Promise<string>>;
|
|
1016
|
+
close: Mock<() => Promise<void>>;
|
|
1017
|
+
isOpen: Mock<() => boolean>;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Create a mock MCP transport
|
|
1022
|
+
*/
|
|
1023
|
+
export function createMockMCPTransport(): MockMCPTransport {
|
|
1024
|
+
return {
|
|
1025
|
+
send: vi.fn().mockResolvedValue(undefined),
|
|
1026
|
+
receive: vi.fn().mockResolvedValue('{}'),
|
|
1027
|
+
close: vi.fn().mockResolvedValue(undefined),
|
|
1028
|
+
isOpen: vi.fn().mockReturnValue(true),
|
|
1029
|
+
};
|
|
1030
|
+
}
|