@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,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RuVector Plugins Test Suite
|
|
3
|
+
*
|
|
4
|
+
* Tests for all RuVector-powered plugins.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
8
|
+
import type {
|
|
9
|
+
ReasoningTrajectory,
|
|
10
|
+
ReasoningStep,
|
|
11
|
+
CodeChunk,
|
|
12
|
+
CodeSearchResult,
|
|
13
|
+
LearningPattern,
|
|
14
|
+
AdaptationResult,
|
|
15
|
+
Intent,
|
|
16
|
+
IntentHandler,
|
|
17
|
+
RouteResult,
|
|
18
|
+
ToolUsagePattern,
|
|
19
|
+
ToolSequence,
|
|
20
|
+
OptimizationSuggestion,
|
|
21
|
+
HookPattern,
|
|
22
|
+
PatternMatch,
|
|
23
|
+
HookRecommendation,
|
|
24
|
+
} from './index.js';
|
|
25
|
+
|
|
26
|
+
// Type tests for ReasoningBank
|
|
27
|
+
describe('ReasoningBank Types', () => {
|
|
28
|
+
it('should have correct ReasoningStep structure', () => {
|
|
29
|
+
const step: ReasoningStep = {
|
|
30
|
+
thought: 'Analyzing the problem',
|
|
31
|
+
action: 'Search for patterns',
|
|
32
|
+
observation: 'Found matching patterns',
|
|
33
|
+
reward: 0.8,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
expect(step.thought).toBeDefined();
|
|
37
|
+
expect(step.action).toBeDefined();
|
|
38
|
+
expect(step.observation).toBeDefined();
|
|
39
|
+
expect(typeof step.reward).toBe('number');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should have correct ReasoningTrajectory structure', () => {
|
|
43
|
+
const trajectory: ReasoningTrajectory = {
|
|
44
|
+
id: 'traj-001',
|
|
45
|
+
task: 'Debug authentication flow',
|
|
46
|
+
steps: [
|
|
47
|
+
{
|
|
48
|
+
thought: 'Check auth middleware',
|
|
49
|
+
action: 'Read auth.ts',
|
|
50
|
+
observation: 'Found token validation issue',
|
|
51
|
+
reward: 0.9,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
outcome: 'success',
|
|
55
|
+
totalReward: 0.9,
|
|
56
|
+
timestamp: Date.now(),
|
|
57
|
+
metadata: { category: 'debugging' },
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
expect(trajectory.id).toBe('traj-001');
|
|
61
|
+
expect(trajectory.outcome).toBe('success');
|
|
62
|
+
expect(trajectory.steps.length).toBe(1);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should allow optional metadata', () => {
|
|
66
|
+
const trajectory: ReasoningTrajectory = {
|
|
67
|
+
id: 'traj-002',
|
|
68
|
+
task: 'Simple task',
|
|
69
|
+
steps: [],
|
|
70
|
+
outcome: 'success',
|
|
71
|
+
totalReward: 1.0,
|
|
72
|
+
timestamp: Date.now(),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
expect(trajectory.metadata).toBeUndefined();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Type tests for SemanticCodeSearch
|
|
80
|
+
describe('SemanticCodeSearch Types', () => {
|
|
81
|
+
it('should have correct CodeChunk structure', () => {
|
|
82
|
+
const chunk: CodeChunk = {
|
|
83
|
+
id: 'chunk-001',
|
|
84
|
+
content: 'function hello() { return "world"; }',
|
|
85
|
+
filePath: '/src/utils.ts',
|
|
86
|
+
startLine: 10,
|
|
87
|
+
endLine: 12,
|
|
88
|
+
language: 'typescript',
|
|
89
|
+
symbols: ['hello'],
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
expect(chunk.id).toBe('chunk-001');
|
|
93
|
+
expect(chunk.language).toBe('typescript');
|
|
94
|
+
expect(chunk.symbols).toContain('hello');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should have correct CodeSearchResult structure', () => {
|
|
98
|
+
const result: CodeSearchResult = {
|
|
99
|
+
chunk: {
|
|
100
|
+
id: 'chunk-002',
|
|
101
|
+
content: 'class UserService {}',
|
|
102
|
+
filePath: '/src/services/user.ts',
|
|
103
|
+
startLine: 1,
|
|
104
|
+
endLine: 50,
|
|
105
|
+
language: 'typescript',
|
|
106
|
+
symbols: ['UserService'],
|
|
107
|
+
},
|
|
108
|
+
score: 0.95,
|
|
109
|
+
highlights: ['UserService'],
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
expect(result.score).toBeGreaterThan(0);
|
|
113
|
+
expect(result.chunk.symbols).toContain('UserService');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should allow optional symbols and metadata', () => {
|
|
117
|
+
const chunk: CodeChunk = {
|
|
118
|
+
id: 'chunk-003',
|
|
119
|
+
content: '# Comment only',
|
|
120
|
+
filePath: '/src/config.py',
|
|
121
|
+
startLine: 1,
|
|
122
|
+
endLine: 1,
|
|
123
|
+
language: 'python',
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
expect(chunk.symbols).toBeUndefined();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Type tests for SONA Learning
|
|
131
|
+
describe('SONALearning Types', () => {
|
|
132
|
+
it('should have correct LearningPattern structure', () => {
|
|
133
|
+
const pattern: LearningPattern = {
|
|
134
|
+
id: 'pattern-001',
|
|
135
|
+
category: 'code-review',
|
|
136
|
+
input: 'Review this function for bugs',
|
|
137
|
+
output: 'Found null pointer dereference',
|
|
138
|
+
embedding: new Float32Array([0.1, 0.2, 0.3]),
|
|
139
|
+
adapterId: 'adapter-001',
|
|
140
|
+
quality: 0.92,
|
|
141
|
+
usageCount: 15,
|
|
142
|
+
lastUsed: Date.now(),
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
expect(pattern.category).toBe('code-review');
|
|
146
|
+
expect(pattern.quality).toBeGreaterThan(0.9);
|
|
147
|
+
expect(pattern.embedding).toBeInstanceOf(Float32Array);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should have correct AdaptationResult structure', () => {
|
|
151
|
+
const result: AdaptationResult = {
|
|
152
|
+
patternId: 'pattern-002',
|
|
153
|
+
adapterId: 'adapter-002',
|
|
154
|
+
improvement: 0.15,
|
|
155
|
+
newQuality: 0.87,
|
|
156
|
+
latencyMs: 0.05,
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
expect(result.improvement).toBeGreaterThan(0);
|
|
160
|
+
expect(result.latencyMs).toBeLessThan(1);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Type tests for Intent Router
|
|
165
|
+
describe('IntentRouter Types', () => {
|
|
166
|
+
it('should have correct Intent structure', () => {
|
|
167
|
+
const intent: Intent = {
|
|
168
|
+
id: 'intent-coding',
|
|
169
|
+
name: 'coding',
|
|
170
|
+
description: 'Code writing and implementation',
|
|
171
|
+
examples: [
|
|
172
|
+
'Write a function to sort an array',
|
|
173
|
+
'Implement the login feature',
|
|
174
|
+
'Create a new component',
|
|
175
|
+
],
|
|
176
|
+
priority: 1,
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
expect(intent.examples.length).toBeGreaterThan(0);
|
|
180
|
+
expect(intent.priority).toBe(1);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should have correct IntentHandler structure', () => {
|
|
184
|
+
const handler: IntentHandler = {
|
|
185
|
+
intentId: 'intent-coding',
|
|
186
|
+
agentType: 'coder',
|
|
187
|
+
tools: ['Edit', 'Write', 'Read'],
|
|
188
|
+
confidence: 0.95,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
expect(handler.tools).toContain('Edit');
|
|
192
|
+
expect(handler.confidence).toBeGreaterThan(0.9);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should have correct RouteResult structure', () => {
|
|
196
|
+
const result: RouteResult = {
|
|
197
|
+
intent: {
|
|
198
|
+
id: 'intent-testing',
|
|
199
|
+
name: 'testing',
|
|
200
|
+
description: 'Testing and validation',
|
|
201
|
+
examples: ['Write tests', 'Run test suite'],
|
|
202
|
+
priority: 2,
|
|
203
|
+
},
|
|
204
|
+
handler: {
|
|
205
|
+
intentId: 'intent-testing',
|
|
206
|
+
agentType: 'tester',
|
|
207
|
+
tools: ['Bash', 'Read'],
|
|
208
|
+
confidence: 0.88,
|
|
209
|
+
},
|
|
210
|
+
confidence: 0.88,
|
|
211
|
+
alternatives: [],
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
expect(result.handler.agentType).toBe('tester');
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// Type tests for MCP Tool Optimizer
|
|
219
|
+
describe('MCPToolOptimizer Types', () => {
|
|
220
|
+
it('should have correct ToolUsagePattern structure', () => {
|
|
221
|
+
const pattern: ToolUsagePattern = {
|
|
222
|
+
id: 'usage-001',
|
|
223
|
+
toolSequence: ['Read', 'Edit', 'Bash'],
|
|
224
|
+
context: 'fixing-bug',
|
|
225
|
+
successRate: 0.92,
|
|
226
|
+
avgDuration: 5000,
|
|
227
|
+
usageCount: 50,
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
expect(pattern.toolSequence).toHaveLength(3);
|
|
231
|
+
expect(pattern.successRate).toBeGreaterThan(0.9);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('should have correct ToolSequence structure', () => {
|
|
235
|
+
const sequence: ToolSequence = {
|
|
236
|
+
tools: ['Glob', 'Grep', 'Read'],
|
|
237
|
+
confidence: 0.85,
|
|
238
|
+
reasoning: 'Search, then filter, then read details',
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
expect(sequence.tools[0]).toBe('Glob');
|
|
242
|
+
expect(sequence.reasoning).toBeDefined();
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('should have correct OptimizationSuggestion structure', () => {
|
|
246
|
+
const suggestion: OptimizationSuggestion = {
|
|
247
|
+
currentSequence: ['Read', 'Read', 'Read'],
|
|
248
|
+
suggestedSequence: ['Glob', 'Read'],
|
|
249
|
+
expectedImprovement: 0.3,
|
|
250
|
+
reasoning: 'Use Glob to find files first, then Read targeted files',
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
expect(suggestion.expectedImprovement).toBeGreaterThan(0);
|
|
254
|
+
expect(suggestion.suggestedSequence.length).toBeLessThan(
|
|
255
|
+
suggestion.currentSequence.length
|
|
256
|
+
);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// Type tests for Hook Pattern Library
|
|
261
|
+
describe('HookPatternLibrary Types', () => {
|
|
262
|
+
it('should have correct HookPattern structure', () => {
|
|
263
|
+
const pattern: HookPattern = {
|
|
264
|
+
id: 'hook-format-ts',
|
|
265
|
+
filePattern: '*.ts',
|
|
266
|
+
operation: 'save',
|
|
267
|
+
hookType: 'pre',
|
|
268
|
+
command: 'prettier --write',
|
|
269
|
+
successRate: 0.98,
|
|
270
|
+
usageCount: 200,
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
expect(pattern.hookType).toBe('pre');
|
|
274
|
+
expect(pattern.successRate).toBeGreaterThan(0.95);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('should have correct PatternMatch structure', () => {
|
|
278
|
+
const match: PatternMatch = {
|
|
279
|
+
pattern: {
|
|
280
|
+
id: 'hook-lint',
|
|
281
|
+
filePattern: '*.js',
|
|
282
|
+
operation: 'commit',
|
|
283
|
+
hookType: 'pre',
|
|
284
|
+
command: 'eslint --fix',
|
|
285
|
+
successRate: 0.95,
|
|
286
|
+
usageCount: 100,
|
|
287
|
+
},
|
|
288
|
+
score: 0.92,
|
|
289
|
+
reasoning: 'High success rate for JavaScript linting',
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
expect(match.score).toBeGreaterThan(0.9);
|
|
293
|
+
expect(match.reasoning).toBeDefined();
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('should have correct HookRecommendation structure', () => {
|
|
297
|
+
const recommendation: HookRecommendation = {
|
|
298
|
+
filePath: '/src/app.tsx',
|
|
299
|
+
operation: 'save',
|
|
300
|
+
recommendations: [
|
|
301
|
+
{
|
|
302
|
+
pattern: {
|
|
303
|
+
id: 'hook-format-tsx',
|
|
304
|
+
filePattern: '*.tsx',
|
|
305
|
+
operation: 'save',
|
|
306
|
+
hookType: 'pre',
|
|
307
|
+
command: 'prettier --write',
|
|
308
|
+
successRate: 0.97,
|
|
309
|
+
usageCount: 150,
|
|
310
|
+
},
|
|
311
|
+
score: 0.95,
|
|
312
|
+
reasoning: 'TSX files benefit from auto-formatting',
|
|
313
|
+
},
|
|
314
|
+
],
|
|
315
|
+
confidence: 0.95,
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
expect(recommendation.recommendations.length).toBeGreaterThan(0);
|
|
319
|
+
expect(recommendation.confidence).toBeGreaterThan(0.9);
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Integration type tests
|
|
324
|
+
describe('Plugin Integration Types', () => {
|
|
325
|
+
it('should export all plugin types', async () => {
|
|
326
|
+
// Dynamic import to verify exports work
|
|
327
|
+
const exports = await import('./index.js');
|
|
328
|
+
|
|
329
|
+
expect(exports.reasoningBankPlugin).toBeDefined();
|
|
330
|
+
expect(exports.semanticCodeSearchPlugin).toBeDefined();
|
|
331
|
+
expect(exports.sonaLearningPlugin).toBeDefined();
|
|
332
|
+
expect(exports.intentRouterPlugin).toBeDefined();
|
|
333
|
+
expect(exports.mcpToolOptimizerPlugin).toBeDefined();
|
|
334
|
+
expect(exports.hookPatternLibraryPlugin).toBeDefined();
|
|
335
|
+
expect(exports.registerAllRuVectorPlugins).toBeDefined();
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
it('should export all class instances', async () => {
|
|
339
|
+
const exports = await import('./index.js');
|
|
340
|
+
|
|
341
|
+
expect(exports.ReasoningBank).toBeDefined();
|
|
342
|
+
expect(exports.SemanticCodeSearch).toBeDefined();
|
|
343
|
+
expect(exports.SONALearning).toBeDefined();
|
|
344
|
+
expect(exports.IntentRouter).toBeDefined();
|
|
345
|
+
expect(exports.MCPToolOptimizer).toBeDefined();
|
|
346
|
+
expect(exports.HookPatternLibrary).toBeDefined();
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
// Plugin metadata tests
|
|
351
|
+
describe('Plugin Metadata', () => {
|
|
352
|
+
it('reasoningBankPlugin should have correct metadata', async () => {
|
|
353
|
+
const { reasoningBankPlugin } = await import('./index.js');
|
|
354
|
+
const metadata = reasoningBankPlugin.metadata;
|
|
355
|
+
|
|
356
|
+
expect(metadata.id).toBe('ruvector-reasoning-bank');
|
|
357
|
+
expect(metadata.name).toBe('RuVector Reasoning Bank');
|
|
358
|
+
expect(metadata.version).toBeDefined();
|
|
359
|
+
expect(metadata.capabilities).toContain('vector-search');
|
|
360
|
+
expect(metadata.capabilities).toContain('learning');
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it('semanticCodeSearchPlugin should have correct metadata', async () => {
|
|
364
|
+
const { semanticCodeSearchPlugin } = await import('./index.js');
|
|
365
|
+
const metadata = semanticCodeSearchPlugin.metadata;
|
|
366
|
+
|
|
367
|
+
expect(metadata.id).toBe('ruvector-semantic-code-search');
|
|
368
|
+
expect(metadata.name).toBe('RuVector Semantic Code Search');
|
|
369
|
+
expect(metadata.capabilities).toContain('code-search');
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
it('sonaLearningPlugin should have correct metadata', async () => {
|
|
373
|
+
const { sonaLearningPlugin } = await import('./index.js');
|
|
374
|
+
const metadata = sonaLearningPlugin.metadata;
|
|
375
|
+
|
|
376
|
+
expect(metadata.id).toBe('ruvector-sona-learning');
|
|
377
|
+
expect(metadata.name).toBe('RuVector SONA Learning');
|
|
378
|
+
expect(metadata.capabilities).toContain('learning');
|
|
379
|
+
expect(metadata.capabilities).toContain('adaptation');
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('intentRouterPlugin should have correct metadata', async () => {
|
|
383
|
+
const { intentRouterPlugin } = await import('./index.js');
|
|
384
|
+
const metadata = intentRouterPlugin.metadata;
|
|
385
|
+
|
|
386
|
+
expect(metadata.id).toBe('ruvector-intent-router');
|
|
387
|
+
expect(metadata.name).toBe('RuVector Intent Router');
|
|
388
|
+
expect(metadata.capabilities).toContain('routing');
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
it('mcpToolOptimizerPlugin should have correct metadata', async () => {
|
|
392
|
+
const { mcpToolOptimizerPlugin } = await import('./index.js');
|
|
393
|
+
const metadata = mcpToolOptimizerPlugin.metadata;
|
|
394
|
+
|
|
395
|
+
expect(metadata.id).toBe('ruvector-mcp-tool-optimizer');
|
|
396
|
+
expect(metadata.name).toBe('RuVector MCP Tool Optimizer');
|
|
397
|
+
expect(metadata.capabilities).toContain('optimization');
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it('hookPatternLibraryPlugin should have correct metadata', async () => {
|
|
401
|
+
const { hookPatternLibraryPlugin } = await import('./index.js');
|
|
402
|
+
const metadata = hookPatternLibraryPlugin.metadata;
|
|
403
|
+
|
|
404
|
+
expect(metadata.id).toBe('ruvector-hook-pattern-library');
|
|
405
|
+
expect(metadata.name).toBe('RuVector Hook Pattern Library');
|
|
406
|
+
expect(metadata.capabilities).toContain('hooks');
|
|
407
|
+
expect(metadata.capabilities).toContain('patterns');
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// MCP Tool definitions tests
|
|
412
|
+
describe('MCP Tool Definitions', () => {
|
|
413
|
+
it('reasoningBankPlugin should define expected tools', async () => {
|
|
414
|
+
const { reasoningBankPlugin } = await import('./index.js');
|
|
415
|
+
const tools = reasoningBankPlugin.tools || [];
|
|
416
|
+
const toolNames = tools.map((t) => t.name);
|
|
417
|
+
|
|
418
|
+
expect(toolNames).toContain('reasoning-store');
|
|
419
|
+
expect(toolNames).toContain('reasoning-retrieve');
|
|
420
|
+
expect(toolNames).toContain('reasoning-judge');
|
|
421
|
+
expect(toolNames).toContain('reasoning-distill');
|
|
422
|
+
expect(toolNames).toContain('reasoning-stats');
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
it('semanticCodeSearchPlugin should define expected tools', async () => {
|
|
426
|
+
const { semanticCodeSearchPlugin } = await import('./index.js');
|
|
427
|
+
const tools = semanticCodeSearchPlugin.tools || [];
|
|
428
|
+
const toolNames = tools.map((t) => t.name);
|
|
429
|
+
|
|
430
|
+
expect(toolNames).toContain('code-index');
|
|
431
|
+
expect(toolNames).toContain('code-search');
|
|
432
|
+
expect(toolNames).toContain('code-similar');
|
|
433
|
+
expect(toolNames).toContain('code-stats');
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('sonaLearningPlugin should define expected tools', async () => {
|
|
437
|
+
const { sonaLearningPlugin } = await import('./index.js');
|
|
438
|
+
const tools = sonaLearningPlugin.tools || [];
|
|
439
|
+
const toolNames = tools.map((t) => t.name);
|
|
440
|
+
|
|
441
|
+
expect(toolNames).toContain('sona-learn');
|
|
442
|
+
expect(toolNames).toContain('sona-retrieve');
|
|
443
|
+
expect(toolNames).toContain('sona-feedback');
|
|
444
|
+
expect(toolNames).toContain('sona-stats');
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
it('intentRouterPlugin should define expected tools', async () => {
|
|
448
|
+
const { intentRouterPlugin } = await import('./index.js');
|
|
449
|
+
const tools = intentRouterPlugin.tools || [];
|
|
450
|
+
const toolNames = tools.map((t) => t.name);
|
|
451
|
+
|
|
452
|
+
expect(toolNames).toContain('intent-route');
|
|
453
|
+
expect(toolNames).toContain('intent-register');
|
|
454
|
+
expect(toolNames).toContain('intent-stats');
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
it('mcpToolOptimizerPlugin should define expected tools', async () => {
|
|
458
|
+
const { mcpToolOptimizerPlugin } = await import('./index.js');
|
|
459
|
+
const tools = mcpToolOptimizerPlugin.tools || [];
|
|
460
|
+
const toolNames = tools.map((t) => t.name);
|
|
461
|
+
|
|
462
|
+
expect(toolNames).toContain('tool-optimize');
|
|
463
|
+
expect(toolNames).toContain('tool-suggest-next');
|
|
464
|
+
expect(toolNames).toContain('tool-stats');
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
it('hookPatternLibraryPlugin should define expected tools', async () => {
|
|
468
|
+
const { hookPatternLibraryPlugin } = await import('./index.js');
|
|
469
|
+
const tools = hookPatternLibraryPlugin.tools || [];
|
|
470
|
+
const toolNames = tools.map((t) => t.name);
|
|
471
|
+
|
|
472
|
+
expect(toolNames).toContain('hook-recommend');
|
|
473
|
+
expect(toolNames).toContain('hook-record');
|
|
474
|
+
expect(toolNames).toContain('hook-stats');
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
// Hook definitions tests
|
|
479
|
+
describe('Hook Definitions', () => {
|
|
480
|
+
it('reasoningBankPlugin should define learning hooks', async () => {
|
|
481
|
+
const { reasoningBankPlugin } = await import('./index.js');
|
|
482
|
+
const hooks = reasoningBankPlugin.hooks || [];
|
|
483
|
+
|
|
484
|
+
expect(hooks.length).toBeGreaterThan(0);
|
|
485
|
+
const hookEvents = hooks.map((h) => h.event);
|
|
486
|
+
expect(hookEvents).toContain('PostTaskComplete');
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
it('intentRouterPlugin should define routing hooks', async () => {
|
|
490
|
+
const { intentRouterPlugin } = await import('./index.js');
|
|
491
|
+
const hooks = intentRouterPlugin.hooks || [];
|
|
492
|
+
|
|
493
|
+
expect(hooks.length).toBeGreaterThan(0);
|
|
494
|
+
const hookEvents = hooks.map((h) => h.event);
|
|
495
|
+
expect(hookEvents).toContain('PreTaskExecute');
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it('mcpToolOptimizerPlugin should define optimization hooks', async () => {
|
|
499
|
+
const { mcpToolOptimizerPlugin } = await import('./index.js');
|
|
500
|
+
const hooks = mcpToolOptimizerPlugin.hooks || [];
|
|
501
|
+
|
|
502
|
+
expect(hooks.length).toBeGreaterThan(0);
|
|
503
|
+
const hookEvents = hooks.map((h) => h.event);
|
|
504
|
+
expect(hookEvents).toContain('PostToolCall');
|
|
505
|
+
expect(hookEvents).toContain('PostTaskComplete');
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it('hookPatternLibraryPlugin should define file operation hooks', async () => {
|
|
509
|
+
const { hookPatternLibraryPlugin } = await import('./index.js');
|
|
510
|
+
const hooks = hookPatternLibraryPlugin.hooks || [];
|
|
511
|
+
|
|
512
|
+
expect(hooks.length).toBeGreaterThan(0);
|
|
513
|
+
const hookEvents = hooks.map((h) => h.event);
|
|
514
|
+
expect(hookEvents).toContain('PreFileWrite');
|
|
515
|
+
expect(hookEvents).toContain('PostFileWrite');
|
|
516
|
+
expect(hookEvents).toContain('PreCommand');
|
|
517
|
+
});
|
|
518
|
+
});
|