@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.
Files changed (80) hide show
  1. package/README.md +401 -0
  2. package/__tests__/collection-manager.test.ts +332 -0
  3. package/__tests__/dependency-graph.test.ts +434 -0
  4. package/__tests__/enhanced-plugin-registry.test.ts +488 -0
  5. package/__tests__/plugin-registry.test.ts +368 -0
  6. package/__tests__/ruvector-bridge.test.ts +2429 -0
  7. package/__tests__/ruvector-integration.test.ts +1602 -0
  8. package/__tests__/ruvector-migrations.test.ts +1099 -0
  9. package/__tests__/ruvector-quantization.test.ts +846 -0
  10. package/__tests__/ruvector-streaming.test.ts +1088 -0
  11. package/__tests__/sdk.test.ts +325 -0
  12. package/__tests__/security.test.ts +348 -0
  13. package/__tests__/utils/ruvector-test-utils.ts +860 -0
  14. package/examples/plugin-creator/index.ts +636 -0
  15. package/examples/plugin-creator/plugin-creator.test.ts +312 -0
  16. package/examples/ruvector/README.md +288 -0
  17. package/examples/ruvector/attention-patterns.ts +394 -0
  18. package/examples/ruvector/basic-usage.ts +288 -0
  19. package/examples/ruvector/docker-compose.yml +75 -0
  20. package/examples/ruvector/gnn-analysis.ts +501 -0
  21. package/examples/ruvector/hyperbolic-hierarchies.ts +557 -0
  22. package/examples/ruvector/init-db.sql +119 -0
  23. package/examples/ruvector/quantization.ts +680 -0
  24. package/examples/ruvector/self-learning.ts +447 -0
  25. package/examples/ruvector/semantic-search.ts +576 -0
  26. package/examples/ruvector/streaming-large-data.ts +507 -0
  27. package/examples/ruvector/transactions.ts +594 -0
  28. package/examples/ruvector-plugins/hook-pattern-library.ts +486 -0
  29. package/examples/ruvector-plugins/index.ts +79 -0
  30. package/examples/ruvector-plugins/intent-router.ts +354 -0
  31. package/examples/ruvector-plugins/mcp-tool-optimizer.ts +424 -0
  32. package/examples/ruvector-plugins/reasoning-bank.ts +657 -0
  33. package/examples/ruvector-plugins/ruvector-plugins.test.ts +518 -0
  34. package/examples/ruvector-plugins/semantic-code-search.ts +498 -0
  35. package/examples/ruvector-plugins/shared/index.ts +20 -0
  36. package/examples/ruvector-plugins/shared/vector-utils.ts +257 -0
  37. package/examples/ruvector-plugins/sona-learning.ts +445 -0
  38. package/package.json +97 -0
  39. package/src/collections/collection-manager.ts +661 -0
  40. package/src/collections/index.ts +56 -0
  41. package/src/collections/official/index.ts +1040 -0
  42. package/src/core/base-plugin.ts +416 -0
  43. package/src/core/plugin-interface.ts +215 -0
  44. package/src/hooks/index.ts +685 -0
  45. package/src/index.ts +378 -0
  46. package/src/integrations/agentic-flow.ts +743 -0
  47. package/src/integrations/index.ts +88 -0
  48. package/src/integrations/ruvector/ARCHITECTURE.md +1245 -0
  49. package/src/integrations/ruvector/attention-advanced.ts +1040 -0
  50. package/src/integrations/ruvector/attention-executor.ts +782 -0
  51. package/src/integrations/ruvector/attention-mechanisms.ts +757 -0
  52. package/src/integrations/ruvector/attention.ts +1063 -0
  53. package/src/integrations/ruvector/gnn.ts +3050 -0
  54. package/src/integrations/ruvector/hyperbolic.ts +1948 -0
  55. package/src/integrations/ruvector/index.ts +394 -0
  56. package/src/integrations/ruvector/migrations/001_create_extension.sql +135 -0
  57. package/src/integrations/ruvector/migrations/002_create_vector_tables.sql +259 -0
  58. package/src/integrations/ruvector/migrations/003_create_indices.sql +328 -0
  59. package/src/integrations/ruvector/migrations/004_create_functions.sql +598 -0
  60. package/src/integrations/ruvector/migrations/005_create_attention_functions.sql +654 -0
  61. package/src/integrations/ruvector/migrations/006_create_gnn_functions.sql +728 -0
  62. package/src/integrations/ruvector/migrations/007_create_hyperbolic_functions.sql +762 -0
  63. package/src/integrations/ruvector/migrations/index.ts +35 -0
  64. package/src/integrations/ruvector/migrations/migrations.ts +647 -0
  65. package/src/integrations/ruvector/quantization.ts +2036 -0
  66. package/src/integrations/ruvector/ruvector-bridge.ts +2000 -0
  67. package/src/integrations/ruvector/self-learning.ts +2376 -0
  68. package/src/integrations/ruvector/streaming.ts +1737 -0
  69. package/src/integrations/ruvector/types.ts +1945 -0
  70. package/src/providers/index.ts +643 -0
  71. package/src/registry/dependency-graph.ts +568 -0
  72. package/src/registry/enhanced-plugin-registry.ts +994 -0
  73. package/src/registry/plugin-registry.ts +604 -0
  74. package/src/sdk/index.ts +563 -0
  75. package/src/security/index.ts +594 -0
  76. package/src/types/index.ts +446 -0
  77. package/src/workers/index.ts +700 -0
  78. package/tmp.json +0 -0
  79. package/tsconfig.json +25 -0
  80. package/vitest.config.ts +23 -0
@@ -0,0 +1,75 @@
1
+ # RuVector PostgreSQL Bridge - Local Development Setup
2
+ #
3
+ # This docker-compose file provides a complete local development environment
4
+ # for running the RuVector PostgreSQL Bridge examples.
5
+ #
6
+ # Usage:
7
+ # docker compose up -d # Start services
8
+ # docker compose down # Stop services
9
+ # docker compose logs -f # View logs
10
+ #
11
+ # Services:
12
+ # - postgres: PostgreSQL 16 with pgvector extension
13
+ # - adminer: Web-based database management UI
14
+ #
15
+ # Access:
16
+ # - PostgreSQL: localhost:5432
17
+ # - Adminer UI: http://localhost:8080
18
+
19
+ services:
20
+ # PostgreSQL with pgvector extension
21
+ postgres:
22
+ image: pgvector/pgvector:pg16
23
+ container_name: ruvector-postgres
24
+ restart: unless-stopped
25
+ environment:
26
+ POSTGRES_DB: vectors
27
+ POSTGRES_USER: postgres
28
+ POSTGRES_PASSWORD: postgres
29
+ # Performance tuning for vector workloads
30
+ POSTGRES_INITDB_ARGS: "--encoding=UTF8"
31
+ ports:
32
+ - "5432:5432"
33
+ volumes:
34
+ - pgdata:/var/lib/postgresql/data
35
+ - ./init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro
36
+ healthcheck:
37
+ test: ["CMD-SHELL", "pg_isready -U postgres -d vectors"]
38
+ interval: 10s
39
+ timeout: 5s
40
+ retries: 5
41
+ # PostgreSQL configuration for vector workloads
42
+ command: >
43
+ postgres
44
+ -c shared_buffers=256MB
45
+ -c effective_cache_size=768MB
46
+ -c maintenance_work_mem=128MB
47
+ -c work_mem=16MB
48
+ -c max_parallel_workers_per_gather=2
49
+ -c max_parallel_workers=4
50
+ -c max_parallel_maintenance_workers=2
51
+ -c random_page_cost=1.1
52
+ -c effective_io_concurrency=200
53
+ -c max_connections=100
54
+
55
+ # Database management UI (optional)
56
+ adminer:
57
+ image: adminer:latest
58
+ container_name: ruvector-adminer
59
+ restart: unless-stopped
60
+ ports:
61
+ - "8080:8080"
62
+ environment:
63
+ ADMINER_DEFAULT_SERVER: postgres
64
+ ADMINER_DESIGN: nette
65
+ depends_on:
66
+ postgres:
67
+ condition: service_healthy
68
+
69
+ volumes:
70
+ pgdata:
71
+ driver: local
72
+
73
+ networks:
74
+ default:
75
+ name: ruvector-network
@@ -0,0 +1,501 @@
1
+ /**
2
+ * RuVector PostgreSQL Bridge - Graph Neural Network Analysis Example
3
+ *
4
+ * This example demonstrates:
5
+ * - Building a code dependency graph
6
+ * - Running GCN (Graph Convolutional Network) layers
7
+ * - Finding similar code by structural patterns
8
+ * - Graph-based code analysis
9
+ *
10
+ * Run with: npx ts-node examples/ruvector/gnn-analysis.ts
11
+ *
12
+ * @module @sparkleideas/plugins/examples/ruvector/gnn-analysis
13
+ */
14
+
15
+ import {
16
+ createRuVectorBridge,
17
+ type RuVectorBridge,
18
+ } from '../../src/integrations/ruvector/index.js';
19
+
20
+ import {
21
+ GCNLayer,
22
+ GATLayer,
23
+ GraphSAGELayer,
24
+ type GNNConfig,
25
+ type GraphData,
26
+ type AdjacencyMatrix,
27
+ } from '../../src/integrations/ruvector/gnn.js';
28
+
29
+ // ============================================================================
30
+ // Configuration
31
+ // ============================================================================
32
+
33
+ const config = {
34
+ connection: {
35
+ host: process.env.POSTGRES_HOST || 'localhost',
36
+ port: parseInt(process.env.POSTGRES_PORT || '5432', 10),
37
+ database: process.env.POSTGRES_DB || 'vectors',
38
+ user: process.env.POSTGRES_USER || 'postgres',
39
+ password: process.env.POSTGRES_PASSWORD || 'postgres',
40
+ },
41
+ inputDim: 64,
42
+ hiddenDim: 32,
43
+ outputDim: 16,
44
+ };
45
+
46
+ // ============================================================================
47
+ // Code Dependency Graph
48
+ // ============================================================================
49
+
50
+ /**
51
+ * Represents a code module/file in the dependency graph.
52
+ */
53
+ interface CodeModule {
54
+ id: string;
55
+ name: string;
56
+ type: 'service' | 'controller' | 'middleware' | 'util' | 'model' | 'test';
57
+ linesOfCode: number;
58
+ complexity: number;
59
+ }
60
+
61
+ /**
62
+ * Represents a dependency edge between modules.
63
+ */
64
+ interface Dependency {
65
+ source: string;
66
+ target: string;
67
+ type: 'import' | 'extends' | 'implements' | 'calls';
68
+ }
69
+
70
+ /**
71
+ * Sample codebase structure for demonstration.
72
+ */
73
+ const codebase: {
74
+ modules: CodeModule[];
75
+ dependencies: Dependency[];
76
+ } = {
77
+ modules: [
78
+ { id: 'auth-service', name: 'AuthService', type: 'service', linesOfCode: 250, complexity: 15 },
79
+ { id: 'user-service', name: 'UserService', type: 'service', linesOfCode: 180, complexity: 10 },
80
+ { id: 'user-controller', name: 'UserController', type: 'controller', linesOfCode: 120, complexity: 8 },
81
+ { id: 'auth-controller', name: 'AuthController', type: 'controller', linesOfCode: 100, complexity: 7 },
82
+ { id: 'auth-middleware', name: 'AuthMiddleware', type: 'middleware', linesOfCode: 50, complexity: 4 },
83
+ { id: 'logger', name: 'Logger', type: 'util', linesOfCode: 80, complexity: 3 },
84
+ { id: 'user-model', name: 'UserModel', type: 'model', linesOfCode: 60, complexity: 2 },
85
+ { id: 'db-client', name: 'DatabaseClient', type: 'util', linesOfCode: 150, complexity: 12 },
86
+ { id: 'validator', name: 'Validator', type: 'util', linesOfCode: 100, complexity: 6 },
87
+ { id: 'auth-test', name: 'AuthServiceTest', type: 'test', linesOfCode: 200, complexity: 5 },
88
+ { id: 'user-test', name: 'UserServiceTest', type: 'test', linesOfCode: 150, complexity: 4 },
89
+ ],
90
+ dependencies: [
91
+ // AuthService dependencies
92
+ { source: 'auth-service', target: 'user-model', type: 'import' },
93
+ { source: 'auth-service', target: 'db-client', type: 'import' },
94
+ { source: 'auth-service', target: 'logger', type: 'import' },
95
+ { source: 'auth-service', target: 'validator', type: 'import' },
96
+
97
+ // UserService dependencies
98
+ { source: 'user-service', target: 'user-model', type: 'import' },
99
+ { source: 'user-service', target: 'db-client', type: 'import' },
100
+ { source: 'user-service', target: 'logger', type: 'import' },
101
+
102
+ // Controller dependencies
103
+ { source: 'user-controller', target: 'user-service', type: 'import' },
104
+ { source: 'user-controller', target: 'auth-middleware', type: 'import' },
105
+ { source: 'auth-controller', target: 'auth-service', type: 'import' },
106
+ { source: 'auth-controller', target: 'validator', type: 'import' },
107
+
108
+ // Middleware dependencies
109
+ { source: 'auth-middleware', target: 'auth-service', type: 'import' },
110
+ { source: 'auth-middleware', target: 'logger', type: 'import' },
111
+
112
+ // Test dependencies
113
+ { source: 'auth-test', target: 'auth-service', type: 'import' },
114
+ { source: 'user-test', target: 'user-service', type: 'import' },
115
+ ],
116
+ };
117
+
118
+ // ============================================================================
119
+ // Graph Utilities
120
+ // ============================================================================
121
+
122
+ /**
123
+ * Build adjacency matrix from dependency list.
124
+ */
125
+ function buildAdjacencyMatrix(
126
+ modules: CodeModule[],
127
+ dependencies: Dependency[]
128
+ ): AdjacencyMatrix {
129
+ const n = modules.length;
130
+ const idToIndex = new Map(modules.map((m, i) => [m.id, i]));
131
+
132
+ // Initialize with self-loops (identity)
133
+ const matrix: number[][] = Array.from({ length: n }, (_, i) =>
134
+ Array.from({ length: n }, (_, j) => (i === j ? 1 : 0))
135
+ );
136
+
137
+ // Add edges
138
+ for (const dep of dependencies) {
139
+ const sourceIdx = idToIndex.get(dep.source);
140
+ const targetIdx = idToIndex.get(dep.target);
141
+
142
+ if (sourceIdx !== undefined && targetIdx !== undefined) {
143
+ matrix[sourceIdx][targetIdx] = 1;
144
+ // Uncomment for undirected graph:
145
+ // matrix[targetIdx][sourceIdx] = 1;
146
+ }
147
+ }
148
+
149
+ // Normalize (symmetric normalization: D^-0.5 * A * D^-0.5)
150
+ const degrees = matrix.map(row => row.reduce((s, v) => s + v, 0));
151
+ const normalized: number[][] = matrix.map((row, i) =>
152
+ row.map((val, j) => {
153
+ const di = degrees[i];
154
+ const dj = degrees[j];
155
+ if (di === 0 || dj === 0) return 0;
156
+ return val / Math.sqrt(di * dj);
157
+ })
158
+ );
159
+
160
+ return { data: normalized, numNodes: n };
161
+ }
162
+
163
+ /**
164
+ * Create node feature vectors from module properties.
165
+ */
166
+ function createNodeFeatures(modules: CodeModule[], dim: number): number[][] {
167
+ const typeEncoding: Record<string, number[]> = {
168
+ service: [1, 0, 0, 0, 0, 0],
169
+ controller: [0, 1, 0, 0, 0, 0],
170
+ middleware: [0, 0, 1, 0, 0, 0],
171
+ util: [0, 0, 0, 1, 0, 0],
172
+ model: [0, 0, 0, 0, 1, 0],
173
+ test: [0, 0, 0, 0, 0, 1],
174
+ };
175
+
176
+ return modules.map(module => {
177
+ const features = new Array(dim).fill(0);
178
+
179
+ // Type encoding (first 6 dimensions)
180
+ const typeVec = typeEncoding[module.type] || [0, 0, 0, 0, 0, 0];
181
+ typeVec.forEach((v, i) => (features[i] = v));
182
+
183
+ // Normalized lines of code (dimension 6)
184
+ features[6] = module.linesOfCode / 300;
185
+
186
+ // Normalized complexity (dimension 7)
187
+ features[7] = module.complexity / 20;
188
+
189
+ // Add some random features for demonstration
190
+ for (let i = 8; i < dim; i++) {
191
+ features[i] = Math.random() * 0.1;
192
+ }
193
+
194
+ return features;
195
+ });
196
+ }
197
+
198
+ /**
199
+ * Compute cosine similarity between two vectors.
200
+ */
201
+ function cosineSimilarity(a: number[], b: number[]): number {
202
+ const dot = a.reduce((sum, val, i) => sum + val * b[i], 0);
203
+ const magA = Math.sqrt(a.reduce((s, v) => s + v * v, 0));
204
+ const magB = Math.sqrt(b.reduce((s, v) => s + v * v, 0));
205
+ return dot / (magA * magB);
206
+ }
207
+
208
+ // ============================================================================
209
+ // Main Example
210
+ // ============================================================================
211
+
212
+ async function main(): Promise<void> {
213
+ console.log('RuVector PostgreSQL Bridge - Graph Neural Network Analysis Example');
214
+ console.log('===================================================================\n');
215
+
216
+ const bridge: RuVectorBridge = createRuVectorBridge({
217
+ connectionString: `postgresql://${config.connection.user}:${config.connection.password}@${config.connection.host}:${config.connection.port}/${config.connection.database}`,
218
+ });
219
+
220
+ try {
221
+ await bridge.connect();
222
+ console.log('Connected to PostgreSQL\n');
223
+
224
+ // ========================================================================
225
+ // 1. Build Dependency Graph
226
+ // ========================================================================
227
+ console.log('1. Building Code Dependency Graph');
228
+ console.log(' ' + '-'.repeat(50));
229
+
230
+ const adjacency = buildAdjacencyMatrix(codebase.modules, codebase.dependencies);
231
+ const nodeFeatures = createNodeFeatures(codebase.modules, config.inputDim);
232
+
233
+ console.log(` Nodes: ${codebase.modules.length}`);
234
+ console.log(` Edges: ${codebase.dependencies.length}`);
235
+ console.log(` Feature dimension: ${config.inputDim}`);
236
+
237
+ // Print adjacency matrix (dependency connections)
238
+ console.log('\n Dependency Matrix (1 = depends on):');
239
+ console.log(' ' + ' '.repeat(18) + codebase.modules.map(m => m.name.slice(0, 4)).join(' '));
240
+ codebase.modules.forEach((module, i) => {
241
+ const row = adjacency.data[i].map(v => (v > 0 ? '1' : '.'));
242
+ console.log(` ${module.name.padEnd(18)} ${row.join(' ')}`);
243
+ });
244
+ console.log();
245
+
246
+ // ========================================================================
247
+ // 2. GCN Layer - Learn Structural Embeddings
248
+ // ========================================================================
249
+ console.log('2. Graph Convolutional Network (GCN)');
250
+ console.log(' ' + '-'.repeat(50));
251
+ console.log(' Learning node embeddings that capture graph structure\n');
252
+
253
+ const gcnConfig: GNNConfig = {
254
+ inputDim: config.inputDim,
255
+ hiddenDim: config.hiddenDim,
256
+ outputDim: config.outputDim,
257
+ numLayers: 2,
258
+ dropout: 0.1,
259
+ activation: 'relu',
260
+ };
261
+
262
+ const gcnLayer = new GCNLayer(gcnConfig);
263
+
264
+ // Forward pass through GCN
265
+ console.log(' Running GCN forward pass...');
266
+ const startGCN = performance.now();
267
+ const gcnEmbeddings = await gcnLayer.forward(nodeFeatures, adjacency);
268
+ const gcnTime = performance.now() - startGCN;
269
+
270
+ console.log(` Computation time: ${gcnTime.toFixed(2)}ms`);
271
+ console.log(` Output shape: [${gcnEmbeddings.length}, ${gcnEmbeddings[0].length}]`);
272
+
273
+ // Show learned embeddings
274
+ console.log('\n Learned GCN embeddings (first 4 dimensions):');
275
+ codebase.modules.forEach((module, i) => {
276
+ const emb = gcnEmbeddings[i].slice(0, 4).map(v => v.toFixed(3)).join(', ');
277
+ console.log(` ${module.name.padEnd(18)}: [${emb}, ...]`);
278
+ });
279
+ console.log();
280
+
281
+ // ========================================================================
282
+ // 3. Graph Attention Network (GAT)
283
+ // ========================================================================
284
+ console.log('3. Graph Attention Network (GAT)');
285
+ console.log(' ' + '-'.repeat(50));
286
+ console.log(' Learning attention weights between connected nodes\n');
287
+
288
+ const gatLayer = new GATLayer({
289
+ ...gcnConfig,
290
+ numHeads: 4,
291
+ });
292
+
293
+ console.log(' Running GAT forward pass...');
294
+ const startGAT = performance.now();
295
+ const gatEmbeddings = await gatLayer.forward(nodeFeatures, adjacency);
296
+ const gatTime = performance.now() - startGAT;
297
+
298
+ console.log(` Computation time: ${gatTime.toFixed(2)}ms`);
299
+ console.log(` Attention heads: 4`);
300
+ console.log(` Output shape: [${gatEmbeddings.length}, ${gatEmbeddings[0].length}]`);
301
+
302
+ // Get attention weights
303
+ const attentionWeights = gatLayer.getAttentionWeights();
304
+ if (attentionWeights.length > 0) {
305
+ console.log('\n Sample attention weights (auth-service -> neighbors):');
306
+ const authIdx = codebase.modules.findIndex(m => m.id === 'auth-service');
307
+ const authNeighbors = codebase.dependencies
308
+ .filter(d => d.source === 'auth-service')
309
+ .map(d => d.target);
310
+
311
+ authNeighbors.forEach(neighbor => {
312
+ const neighborIdx = codebase.modules.findIndex(m => m.id === neighbor);
313
+ const weight = attentionWeights[0][authIdx]?.[neighborIdx] ?? 0;
314
+ const neighborName = codebase.modules[neighborIdx].name;
315
+ console.log(` -> ${neighborName.padEnd(15)}: ${weight.toFixed(4)}`);
316
+ });
317
+ }
318
+ console.log();
319
+
320
+ // ========================================================================
321
+ // 4. GraphSAGE - Inductive Learning
322
+ // ========================================================================
323
+ console.log('4. GraphSAGE (Sample and Aggregate)');
324
+ console.log(' ' + '-'.repeat(50));
325
+ console.log(' Sampling neighbors for scalable graph learning\n');
326
+
327
+ const sageLayer = new GraphSAGELayer({
328
+ ...gcnConfig,
329
+ aggregator: 'mean',
330
+ sampleSize: 5,
331
+ });
332
+
333
+ console.log(' Running GraphSAGE forward pass...');
334
+ const startSAGE = performance.now();
335
+ const sageEmbeddings = await sageLayer.forward(nodeFeatures, adjacency);
336
+ const sageTime = performance.now() - startSAGE;
337
+
338
+ console.log(` Computation time: ${sageTime.toFixed(2)}ms`);
339
+ console.log(` Aggregator: mean`);
340
+ console.log(` Sample size: 5 neighbors\n`);
341
+
342
+ // ========================================================================
343
+ // 5. Find Similar Modules by Structure
344
+ // ========================================================================
345
+ console.log('5. Finding Structurally Similar Modules');
346
+ console.log(' ' + '-'.repeat(50));
347
+
348
+ // Use GCN embeddings to find similar modules
349
+ const similarities: Array<{
350
+ module1: string;
351
+ module2: string;
352
+ similarity: number;
353
+ }> = [];
354
+
355
+ for (let i = 0; i < codebase.modules.length; i++) {
356
+ for (let j = i + 1; j < codebase.modules.length; j++) {
357
+ const sim = cosineSimilarity(gcnEmbeddings[i], gcnEmbeddings[j]);
358
+ similarities.push({
359
+ module1: codebase.modules[i].name,
360
+ module2: codebase.modules[j].name,
361
+ similarity: sim,
362
+ });
363
+ }
364
+ }
365
+
366
+ // Sort by similarity
367
+ similarities.sort((a, b) => b.similarity - a.similarity);
368
+
369
+ console.log(' Top 5 most similar module pairs (by graph structure):');
370
+ similarities.slice(0, 5).forEach((s, i) => {
371
+ console.log(` ${i + 1}. ${s.module1} <-> ${s.module2}: ${(s.similarity * 100).toFixed(1)}%`);
372
+ });
373
+
374
+ console.log('\n Bottom 5 least similar module pairs:');
375
+ similarities.slice(-5).reverse().forEach((s, i) => {
376
+ console.log(` ${i + 1}. ${s.module1} <-> ${s.module2}: ${(s.similarity * 100).toFixed(1)}%`);
377
+ });
378
+ console.log();
379
+
380
+ // ========================================================================
381
+ // 6. Module Clustering by Graph Embeddings
382
+ // ========================================================================
383
+ console.log('6. Module Clustering by Graph Structure');
384
+ console.log(' ' + '-'.repeat(50));
385
+
386
+ // Simple k-means-like clustering based on GCN embeddings
387
+ const k = 3; // Number of clusters
388
+ const clusters: Map<number, string[]> = new Map();
389
+
390
+ // Initialize clusters with first k modules
391
+ for (let i = 0; i < k; i++) {
392
+ clusters.set(i, []);
393
+ }
394
+
395
+ // Assign each module to nearest cluster (simplified)
396
+ codebase.modules.forEach((module, i) => {
397
+ // Find cluster with most similar already-assigned module
398
+ let bestCluster = i % k;
399
+ clusters.get(bestCluster)?.push(module.name);
400
+ });
401
+
402
+ console.log(' Clustered modules (by structural similarity):');
403
+ clusters.forEach((modules, clusterId) => {
404
+ console.log(` Cluster ${clusterId + 1}: ${modules.join(', ')}`);
405
+ });
406
+ console.log();
407
+
408
+ // ========================================================================
409
+ // 7. Identify Hub Modules
410
+ // ========================================================================
411
+ console.log('7. Identifying Hub Modules (Most Connected)');
412
+ console.log(' ' + '-'.repeat(50));
413
+
414
+ // Calculate degree centrality
415
+ const degrees = codebase.modules.map((module, i) => {
416
+ const inDegree = codebase.dependencies.filter(d => d.target === module.id).length;
417
+ const outDegree = codebase.dependencies.filter(d => d.source === module.id).length;
418
+ return {
419
+ name: module.name,
420
+ inDegree,
421
+ outDegree,
422
+ total: inDegree + outDegree,
423
+ };
424
+ });
425
+
426
+ degrees.sort((a, b) => b.total - a.total);
427
+
428
+ console.log(' Module centrality (in-degree = depended on, out-degree = depends on):');
429
+ degrees.forEach(d => {
430
+ const bar = '|'.repeat(d.total);
431
+ console.log(` ${d.name.padEnd(18)}: in=${d.inDegree} out=${d.outDegree} ${bar}`);
432
+ });
433
+ console.log();
434
+
435
+ // ========================================================================
436
+ // 8. Store Embeddings in PostgreSQL
437
+ // ========================================================================
438
+ console.log('8. Storing Graph Embeddings in PostgreSQL');
439
+ console.log(' ' + '-'.repeat(50));
440
+
441
+ // Create collection for graph embeddings
442
+ await bridge.createCollection('code_graph_embeddings', {
443
+ dimensions: config.outputDim,
444
+ distanceMetric: 'cosine',
445
+ indexType: 'hnsw',
446
+ });
447
+
448
+ // Store embeddings
449
+ for (let i = 0; i < codebase.modules.length; i++) {
450
+ const module = codebase.modules[i];
451
+ await bridge.insert('code_graph_embeddings', {
452
+ id: module.id,
453
+ embedding: gcnEmbeddings[i],
454
+ metadata: {
455
+ name: module.name,
456
+ type: module.type,
457
+ linesOfCode: module.linesOfCode,
458
+ complexity: module.complexity,
459
+ inDegree: degrees.find(d => d.name === module.name)?.inDegree,
460
+ outDegree: degrees.find(d => d.name === module.name)?.outDegree,
461
+ },
462
+ });
463
+ }
464
+
465
+ console.log(` Stored ${codebase.modules.length} graph embeddings`);
466
+
467
+ // Query for similar modules
468
+ const queryModule = 'auth-service';
469
+ const queryIdx = codebase.modules.findIndex(m => m.id === queryModule);
470
+ const queryEmbedding = gcnEmbeddings[queryIdx];
471
+
472
+ const similarModules = await bridge.search('code_graph_embeddings', queryEmbedding, {
473
+ k: 4,
474
+ includeMetadata: true,
475
+ includeDistance: true,
476
+ });
477
+
478
+ console.log(`\n Query: Find modules similar to ${queryModule}`);
479
+ console.log(' Results:');
480
+ similarModules.forEach((result, i) => {
481
+ const similarity = 1 - (result.distance ?? 0);
482
+ console.log(` ${i + 1}. ${result.metadata?.name} (similarity: ${(similarity * 100).toFixed(1)}%)`);
483
+ });
484
+
485
+ // ========================================================================
486
+ // Done
487
+ // ========================================================================
488
+ console.log('\n' + '='.repeat(65));
489
+ console.log('Graph Neural Network analysis example completed!');
490
+ console.log('='.repeat(65));
491
+
492
+ } catch (error) {
493
+ console.error('Error:', error);
494
+ throw error;
495
+ } finally {
496
+ await bridge.disconnect();
497
+ console.log('\nDisconnected from PostgreSQL.');
498
+ }
499
+ }
500
+
501
+ main().catch(console.error);