claude-flow 3.6.4 → 3.6.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow",
3
- "version": "3.6.4",
3
+ "version": "3.6.5",
4
4
  "description": "Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -804,5 +804,74 @@ export const embeddingsTools = [
804
804
  };
805
805
  },
806
806
  },
807
+ // --- RaBitQ 1-bit quantized vector index ---
808
+ {
809
+ name: 'embeddings_rabitq_build',
810
+ description: 'Build RaBitQ 1-bit quantized index from stored embeddings (32× compression). Pre-filters candidates via Hamming scan before exact rerank.',
811
+ category: 'embeddings',
812
+ inputSchema: {
813
+ type: 'object',
814
+ properties: {
815
+ force: { type: 'boolean', description: 'Force rebuild even if index exists' },
816
+ },
817
+ },
818
+ handler: async (params) => {
819
+ const { buildRabitqIndex } = await import('../memory/rabitq-index.js');
820
+ return buildRabitqIndex({ force: params.force });
821
+ },
822
+ },
823
+ {
824
+ name: 'embeddings_rabitq_search',
825
+ description: 'Search via RaBitQ quantized index (fast Hamming scan). Returns candidate IDs for reranking.',
826
+ category: 'embeddings',
827
+ inputSchema: {
828
+ type: 'object',
829
+ properties: {
830
+ query: { type: 'string', description: 'Search query text' },
831
+ k: { type: 'number', description: 'Number of results (default: 10)' },
832
+ namespace: { type: 'string', description: 'Filter by namespace' },
833
+ },
834
+ required: ['query'],
835
+ },
836
+ handler: async (params) => {
837
+ const { validateText: vt } = await import('./validate-input.js');
838
+ const v = vt(params.query, 'query');
839
+ if (!v.valid)
840
+ return { success: false, error: v.error };
841
+ const { searchRabitq } = await import('../memory/rabitq-index.js');
842
+ const { generateEmbedding } = await import('../memory/memory-initializer.js');
843
+ const queryEmb = await generateEmbedding(params.query);
844
+ const results = await searchRabitq(queryEmb.embedding, {
845
+ k: params.k || 10,
846
+ namespace: params.namespace,
847
+ });
848
+ if (!results) {
849
+ return { success: false, error: 'RaBitQ index not built. Call embeddings_rabitq_build first.' };
850
+ }
851
+ return {
852
+ success: true,
853
+ results: results.map(r => ({
854
+ id: r.id.substring(0, 12),
855
+ key: r.key,
856
+ namespace: r.namespace,
857
+ distance: Math.round(r.distance * 10000) / 10000,
858
+ })),
859
+ count: results.length,
860
+ };
861
+ },
862
+ },
863
+ {
864
+ name: 'embeddings_rabitq_status',
865
+ description: 'Get RaBitQ quantized index status — availability, vector count, compression ratio',
866
+ category: 'embeddings',
867
+ inputSchema: {
868
+ type: 'object',
869
+ properties: {},
870
+ },
871
+ handler: async () => {
872
+ const { getRabitqStatus } = await import('../memory/rabitq-index.js');
873
+ return { success: true, ...getRabitqStatus() };
874
+ },
875
+ },
807
876
  ];
808
877
  //# sourceMappingURL=embeddings-tools.js.map
@@ -2479,20 +2479,25 @@ export const hooksPatternStore = {
2479
2479
  }
2480
2480
  const success = reasoningResult?.success || storeResult.success;
2481
2481
  const controller = reasoningResult?.controller || (storeResult.success ? 'bridge-store' : 'none');
2482
+ const hasEmbedding = !!storeResult.embedding || controller === 'reasoningBank' || controller === 'bridge-fallback';
2482
2483
  return {
2483
2484
  patternId: reasoningResult?.patternId || storeResult.id || patternId,
2484
2485
  pattern,
2485
2486
  type,
2486
2487
  confidence,
2487
2488
  indexed: success,
2488
- hnswIndexed: success && (!!storeResult.embedding || controller === 'reasoningBank'),
2489
+ hnswIndexed: success && hasEmbedding,
2489
2490
  embedding: storeResult.embedding,
2490
2491
  timestamp,
2491
2492
  controller,
2492
- implementation: controller === 'reasoningBank' ? 'reasoning-bank-controller' : (storeResult.success ? 'real-hnsw-indexed' : 'memory-only'),
2493
+ implementation: (controller === 'reasoningBank' || controller === 'bridge-fallback')
2494
+ ? 'reasoning-bank-controller'
2495
+ : (storeResult.success ? 'real-hnsw-indexed' : 'memory-only'),
2493
2496
  note: controller === 'reasoningBank'
2494
2497
  ? 'Pattern stored via ReasoningBank controller with HNSW indexing'
2495
- : (storeResult.success ? 'Pattern stored with vector embedding for semantic search' : (storeResult.error || 'Store function unavailable')),
2498
+ : controller === 'bridge-fallback'
2499
+ ? 'Pattern stored via bridge with embedding and HNSW indexing'
2500
+ : (storeResult.success ? 'Pattern stored with vector embedding for semantic search' : (storeResult.error || 'Store function unavailable')),
2496
2501
  };
2497
2502
  },
2498
2503
  };
@@ -37,6 +37,7 @@ export declare function bridgeStoreEntry(options: {
37
37
  dimensions: number;
38
38
  model: string;
39
39
  };
40
+ rawEmbedding?: number[];
40
41
  guarded?: boolean;
41
42
  cached?: boolean;
42
43
  attested?: boolean;
@@ -381,6 +381,7 @@ export async function bridgeStoreEntry(options) {
381
381
  success: true,
382
382
  id,
383
383
  embedding: embeddingJson ? { dimensions, model } : undefined,
384
+ rawEmbedding: embeddingJson ? JSON.parse(embeddingJson) : undefined,
384
385
  guarded: true,
385
386
  cached: true,
386
387
  attested: true,
@@ -460,10 +461,11 @@ export async function bridgeSearchEntries(options) {
460
461
  bm25ScoreVal = Math.min(bm25ScoreVal / 10, 1.0);
461
462
  }
462
463
  // Reciprocal rank fusion: combine semantic and BM25
463
- // Weight: 0.7 semantic + 0.3 BM25 (semantic preferred when embeddings available)
464
- const score = queryEmbedding
464
+ // Weight: 0.7 semantic + 0.3 BM25 when both embeddings present
465
+ // Fall back to BM25-only when either query or row lacks an embedding
466
+ const score = semanticScore > 0
465
467
  ? (0.7 * semanticScore + 0.3 * bm25ScoreVal)
466
- : bm25ScoreVal; // BM25-only when no embeddings
468
+ : bm25ScoreVal;
467
469
  if (score >= threshold) {
468
470
  // Phase 4: ExplainableRecall provenance
469
471
  const provenance = queryEmbedding
@@ -971,15 +973,31 @@ export async function bridgeStorePattern(options) {
971
973
  return { success: true, patternId, controller: 'reasoningBank' };
972
974
  }
973
975
  // Fallback: store via bridge SQL
976
+ const patternValue = JSON.stringify({ pattern: options.pattern, type: options.type, confidence: options.confidence, metadata: options.metadata });
974
977
  const result = await bridgeStoreEntry({
975
978
  key: patternId,
976
- value: JSON.stringify({ pattern: options.pattern, type: options.type, confidence: options.confidence, metadata: options.metadata }),
979
+ value: patternValue,
977
980
  namespace: 'pattern',
978
981
  generateEmbeddingFlag: true,
979
982
  tags: [options.type, 'reasoning-pattern'],
980
983
  dbPath: options.dbPath,
981
984
  });
982
- return result ? { success: true, patternId: result.id, controller: 'bridge-fallback' } : null;
985
+ if (!result)
986
+ return null;
987
+ // Add to HNSW index for fast semantic search (bridgeStoreEntry stores SQL only)
988
+ if (result.rawEmbedding) {
989
+ try {
990
+ const { addToHNSWIndex } = await import('./memory-initializer.js');
991
+ await addToHNSWIndex(result.id, result.rawEmbedding, {
992
+ id: result.id,
993
+ key: patternId,
994
+ namespace: 'pattern',
995
+ content: patternValue,
996
+ });
997
+ }
998
+ catch { /* HNSW is best-effort */ }
999
+ }
1000
+ return { success: true, patternId: result.id, controller: 'bridge-fallback' };
983
1001
  }
984
1002
  catch {
985
1003
  return null;
@@ -1689,8 +1689,19 @@ export async function storeEntry(options) {
1689
1689
  const bridge = await getBridge();
1690
1690
  if (bridge) {
1691
1691
  const bridgeResult = await bridge.bridgeStoreEntry(options);
1692
- if (bridgeResult)
1692
+ if (bridgeResult) {
1693
+ // Keep HNSW index in sync with bridge-stored entries
1694
+ if (bridgeResult.rawEmbedding && bridgeResult.success) {
1695
+ const ns = options.namespace || 'default';
1696
+ await addToHNSWIndex(bridgeResult.id, bridgeResult.rawEmbedding, {
1697
+ id: bridgeResult.id,
1698
+ key: options.key,
1699
+ namespace: ns,
1700
+ content: options.value,
1701
+ }).catch(() => { });
1702
+ }
1693
1703
  return bridgeResult;
1704
+ }
1694
1705
  }
1695
1706
  // Fallback: raw sql.js
1696
1707
  const { key, value, namespace = 'default', generateEmbeddingFlag = true, tags = [], ttl, dbPath: customPath, upsert = false } = options;
@@ -1799,7 +1810,51 @@ export async function searchEntries(options) {
1799
1810
  // Generate query embedding
1800
1811
  const queryEmb = await generateEmbedding(query);
1801
1812
  const queryEmbedding = queryEmb.embedding;
1802
- // Try HNSW search first (150x faster)
1813
+ // Try RaBitQ pre-filter first (32× compressed Hamming scan)
1814
+ try {
1815
+ const { searchRabitq } = await import('./rabitq-index.js');
1816
+ const rabitqCandidates = await searchRabitq(queryEmbedding, { k: limit * 2, namespace: effectiveNamespace });
1817
+ if (rabitqCandidates && rabitqCandidates.length > 0) {
1818
+ // Rerank candidates with exact cosine similarity from SQLite
1819
+ const initSqlJs = (await import('sql.js')).default;
1820
+ const SQL = await initSqlJs();
1821
+ const fileBuffer = fs.readFileSync(dbPath);
1822
+ const db = new SQL.Database(fileBuffer);
1823
+ const reranked = [];
1824
+ for (const candidate of rabitqCandidates) {
1825
+ const stmt = db.prepare('SELECT content, embedding FROM memory_entries WHERE id = ? AND status = ?');
1826
+ stmt.bind([candidate.id, 'active']);
1827
+ if (stmt.step()) {
1828
+ const [content, embeddingJson] = stmt.get();
1829
+ let score = 0;
1830
+ if (embeddingJson) {
1831
+ try {
1832
+ const embedding = JSON.parse(embeddingJson);
1833
+ score = cosineSim(queryEmbedding, embedding);
1834
+ }
1835
+ catch { /* skip */ }
1836
+ }
1837
+ if (score >= threshold) {
1838
+ reranked.push({
1839
+ id: candidate.id.substring(0, 12),
1840
+ key: candidate.key || candidate.id.substring(0, 15),
1841
+ content: (content || '').substring(0, 60) + ((content || '').length > 60 ? '...' : ''),
1842
+ score,
1843
+ namespace: candidate.namespace,
1844
+ });
1845
+ }
1846
+ }
1847
+ stmt.free();
1848
+ }
1849
+ db.close();
1850
+ if (reranked.length > 0) {
1851
+ reranked.sort((a, b) => b.score - a.score);
1852
+ return { success: true, results: reranked.slice(0, limit), searchTime: Date.now() - startTime };
1853
+ }
1854
+ }
1855
+ }
1856
+ catch { /* RaBitQ unavailable, fall through */ }
1857
+ // Try HNSW search (150x faster than brute-force)
1803
1858
  const hnswResults = await searchHNSWIndex(queryEmbedding, { k: limit, namespace: effectiveNamespace });
1804
1859
  if (hnswResults && hnswResults.length > 0) {
1805
1860
  // Filter by threshold
@@ -0,0 +1,60 @@
1
+ /**
2
+ * RaBitQ Index — 1-bit quantized vector pre-filter (32× compression)
3
+ *
4
+ * Wraps @ruvector/rabitq-wasm to provide Hamming-scan pre-filtering
5
+ * over quantized embeddings. Candidates are reranked with exact cosine
6
+ * similarity from the full-precision source (HNSW or SQLite).
7
+ *
8
+ * Lifecycle:
9
+ * 1. build() — bulk-load all embeddings from SQLite into the WASM index
10
+ * 2. search() — fast Hamming scan → candidate ids → caller reranks
11
+ * 3. rebuild() — called when entry count drifts >20% from last build
12
+ */
13
+ /**
14
+ * Build or rebuild the RaBitQ index from SQLite embeddings.
15
+ * Returns entry count or 0 if RaBitQ is unavailable.
16
+ */
17
+ export declare function buildRabitqIndex(options?: {
18
+ dbPath?: string;
19
+ dimensions?: number;
20
+ force?: boolean;
21
+ }): Promise<{
22
+ success: boolean;
23
+ vectorCount: number;
24
+ dimensions: number;
25
+ compressionRatio: number;
26
+ buildTimeMs: number;
27
+ wasmVersion?: string;
28
+ error?: string;
29
+ }>;
30
+ /**
31
+ * Search the RaBitQ index for candidate IDs.
32
+ * Returns null if index not built or unavailable.
33
+ * Caller is responsible for reranking with exact similarity.
34
+ */
35
+ export declare function searchRabitq(queryEmbedding: number[], options?: {
36
+ k?: number;
37
+ namespace?: string;
38
+ }): Promise<Array<{
39
+ id: string;
40
+ key: string;
41
+ namespace: string;
42
+ distance: number;
43
+ position: number;
44
+ }> | null>;
45
+ /**
46
+ * Check if the RaBitQ index needs rebuilding.
47
+ */
48
+ export declare function shouldRebuildRabitq(currentEntryCount: number): Promise<boolean>;
49
+ /**
50
+ * Get RaBitQ index status.
51
+ */
52
+ export declare function getRabitqStatus(): {
53
+ available: boolean;
54
+ initialized: boolean;
55
+ vectorCount: number;
56
+ dimensions: number;
57
+ builtAt: number | null;
58
+ compressionRatio: number;
59
+ };
60
+ //# sourceMappingURL=rabitq-index.d.ts.map
@@ -0,0 +1,226 @@
1
+ /**
2
+ * RaBitQ Index — 1-bit quantized vector pre-filter (32× compression)
3
+ *
4
+ * Wraps @ruvector/rabitq-wasm to provide Hamming-scan pre-filtering
5
+ * over quantized embeddings. Candidates are reranked with exact cosine
6
+ * similarity from the full-precision source (HNSW or SQLite).
7
+ *
8
+ * Lifecycle:
9
+ * 1. build() — bulk-load all embeddings from SQLite into the WASM index
10
+ * 2. search() — fast Hamming scan → candidate ids → caller reranks
11
+ * 3. rebuild() — called when entry count drifts >20% from last build
12
+ */
13
+ import * as fs from 'fs';
14
+ import * as path from 'path';
15
+ const RABITQ_SEED = 42n;
16
+ const RABITQ_RERANK_FACTOR = 20;
17
+ const REBUILD_DRIFT_THRESHOLD = 0.2; // rebuild when count drifts >20%
18
+ let rabitqState = null;
19
+ let rabitqInitializing = false;
20
+ async function loadRabitqModule() {
21
+ try {
22
+ const mod = await import('@ruvector/rabitq-wasm');
23
+ // Node.js: use initSync with the WASM bytes
24
+ const { createRequire } = await import('module');
25
+ const require = createRequire(import.meta.url);
26
+ const wasmPath = require.resolve('@ruvector/rabitq-wasm/ruvector_rabitq_wasm_bg.wasm');
27
+ const wasmBytes = fs.readFileSync(wasmPath);
28
+ mod.initSync({ module: wasmBytes });
29
+ return {
30
+ RabitqIndex: mod.RabitqIndex,
31
+ initSync: mod.initSync,
32
+ version: mod.version,
33
+ };
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ /**
40
+ * Build or rebuild the RaBitQ index from SQLite embeddings.
41
+ * Returns entry count or 0 if RaBitQ is unavailable.
42
+ */
43
+ export async function buildRabitqIndex(options) {
44
+ if (rabitqInitializing) {
45
+ return { success: false, vectorCount: 0, dimensions: 0, compressionRatio: 0, buildTimeMs: 0, error: 'Build already in progress' };
46
+ }
47
+ rabitqInitializing = true;
48
+ const startTime = Date.now();
49
+ try {
50
+ const mod = await loadRabitqModule();
51
+ if (!mod) {
52
+ rabitqInitializing = false;
53
+ return { success: false, vectorCount: 0, dimensions: 0, compressionRatio: 0, buildTimeMs: 0, error: '@ruvector/rabitq-wasm not available' };
54
+ }
55
+ const dimensions = options?.dimensions ?? 384;
56
+ const swarmDir = path.resolve(process.cwd(), '.swarm');
57
+ const dbPath = options?.dbPath ? path.resolve(options.dbPath) : path.join(swarmDir, 'memory.db');
58
+ if (!fs.existsSync(dbPath)) {
59
+ rabitqInitializing = false;
60
+ return { success: false, vectorCount: 0, dimensions, compressionRatio: 0, buildTimeMs: 0, error: 'Database not found' };
61
+ }
62
+ // Load embeddings from SQLite
63
+ const initSqlJs = (await import('sql.js')).default;
64
+ const SQL = await initSqlJs();
65
+ const fileBuffer = fs.readFileSync(dbPath);
66
+ const db = new SQL.Database(fileBuffer);
67
+ const result = db.exec(`
68
+ SELECT id, key, namespace, embedding
69
+ FROM memory_entries
70
+ WHERE status = 'active' AND embedding IS NOT NULL
71
+ LIMIT 50000
72
+ `);
73
+ const entries = [];
74
+ const vectors = [];
75
+ if (result[0]?.values) {
76
+ for (const row of result[0].values) {
77
+ const [id, key, ns, embeddingJson] = row;
78
+ if (!embeddingJson)
79
+ continue;
80
+ try {
81
+ const embedding = JSON.parse(embeddingJson);
82
+ if (embedding.length !== dimensions)
83
+ continue;
84
+ entries.push({ id: String(id), key: key || String(id), namespace: ns || 'default' });
85
+ vectors.push(...embedding);
86
+ }
87
+ catch {
88
+ // skip invalid
89
+ }
90
+ }
91
+ }
92
+ db.close();
93
+ if (entries.length < 2) {
94
+ rabitqInitializing = false;
95
+ return { success: false, vectorCount: entries.length, dimensions, compressionRatio: 0, buildTimeMs: Date.now() - startTime, error: 'Need at least 2 vectors to build RaBitQ index' };
96
+ }
97
+ // Build the RaBitQ index
98
+ const flatVectors = new Float32Array(vectors);
99
+ const index = mod.RabitqIndex.build(flatVectors, dimensions, RABITQ_SEED, RABITQ_RERANK_FACTOR);
100
+ // Free old index if exists
101
+ if (rabitqState?.index) {
102
+ try {
103
+ rabitqState.index.free();
104
+ }
105
+ catch { /* already freed */ }
106
+ }
107
+ rabitqState = {
108
+ index,
109
+ entries,
110
+ dimensions,
111
+ builtAt: Date.now(),
112
+ vectorCount: entries.length,
113
+ };
114
+ // Persist metadata for fast reload hint
115
+ try {
116
+ const metaPath = path.join(swarmDir, 'rabitq.meta.json');
117
+ fs.writeFileSync(metaPath, JSON.stringify({
118
+ vectorCount: entries.length,
119
+ dimensions,
120
+ builtAt: rabitqState.builtAt,
121
+ wasmVersion: mod.version(),
122
+ }));
123
+ }
124
+ catch { /* best-effort */ }
125
+ const rawBytes = entries.length * dimensions * 4; // f32 = 4 bytes
126
+ const quantizedBytes = entries.length * Math.ceil(dimensions / 8); // 1 bit per dim
127
+ const compressionRatio = rawBytes / Math.max(quantizedBytes, 1);
128
+ rabitqInitializing = false;
129
+ return {
130
+ success: true,
131
+ vectorCount: entries.length,
132
+ dimensions,
133
+ compressionRatio: Math.round(compressionRatio * 10) / 10,
134
+ buildTimeMs: Date.now() - startTime,
135
+ wasmVersion: mod.version(),
136
+ };
137
+ }
138
+ catch (error) {
139
+ rabitqInitializing = false;
140
+ return {
141
+ success: false,
142
+ vectorCount: 0,
143
+ dimensions: 0,
144
+ compressionRatio: 0,
145
+ buildTimeMs: Date.now() - startTime,
146
+ error: error instanceof Error ? error.message : String(error),
147
+ };
148
+ }
149
+ }
150
+ /**
151
+ * Search the RaBitQ index for candidate IDs.
152
+ * Returns null if index not built or unavailable.
153
+ * Caller is responsible for reranking with exact similarity.
154
+ */
155
+ export async function searchRabitq(queryEmbedding, options) {
156
+ if (!rabitqState?.index)
157
+ return null;
158
+ try {
159
+ const query = new Float32Array(queryEmbedding);
160
+ if (query.length !== rabitqState.dimensions)
161
+ return null;
162
+ const k = options?.k ?? 10;
163
+ // Get more candidates than needed for namespace filtering + rerank
164
+ const expandedK = Math.min(k * 3, rabitqState.vectorCount);
165
+ const rawResults = rabitqState.index.search(query, expandedK);
166
+ const results = [];
167
+ for (const hit of rawResults) {
168
+ const pos = hit.id; // row index from build()
169
+ const entry = rabitqState.entries[pos];
170
+ if (!entry)
171
+ continue;
172
+ // Namespace filter
173
+ if (options?.namespace && options.namespace !== 'all' && entry.namespace !== options.namespace) {
174
+ continue;
175
+ }
176
+ results.push({
177
+ id: entry.id,
178
+ key: entry.key,
179
+ namespace: entry.namespace,
180
+ distance: hit.distance,
181
+ position: pos,
182
+ });
183
+ // Free WASM SearchResult to prevent leak
184
+ try {
185
+ hit.free();
186
+ }
187
+ catch { /* already freed */ }
188
+ if (results.length >= k)
189
+ break;
190
+ }
191
+ // Free remaining SearchResults
192
+ for (const hit of rawResults) {
193
+ try {
194
+ hit.free();
195
+ }
196
+ catch { /* already freed or used */ }
197
+ }
198
+ return results;
199
+ }
200
+ catch {
201
+ return null;
202
+ }
203
+ }
204
+ /**
205
+ * Check if the RaBitQ index needs rebuilding.
206
+ */
207
+ export async function shouldRebuildRabitq(currentEntryCount) {
208
+ if (!rabitqState)
209
+ return currentEntryCount >= 10; // Build if we have enough vectors
210
+ const drift = Math.abs(currentEntryCount - rabitqState.vectorCount) / Math.max(rabitqState.vectorCount, 1);
211
+ return drift > REBUILD_DRIFT_THRESHOLD;
212
+ }
213
+ /**
214
+ * Get RaBitQ index status.
215
+ */
216
+ export function getRabitqStatus() {
217
+ return {
218
+ available: rabitqState !== null,
219
+ initialized: rabitqState !== null,
220
+ vectorCount: rabitqState?.vectorCount ?? 0,
221
+ dimensions: rabitqState?.dimensions ?? 384,
222
+ builtAt: rabitqState?.builtAt ?? null,
223
+ compressionRatio: rabitqState ? Math.round((rabitqState.dimensions * 4) / Math.ceil(rabitqState.dimensions / 8) * 10) / 10 : 0,
224
+ };
225
+ }
226
+ //# sourceMappingURL=rabitq-index.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.6.4",
3
+ "version": "3.6.5",
4
4
  "type": "module",
5
5
  "description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",
@@ -97,23 +97,24 @@
97
97
  "@claude-flow/mcp": "^3.0.0-alpha.8",
98
98
  "@claude-flow/shared": "^3.0.0-alpha.7",
99
99
  "@noble/ed25519": "^2.1.0",
100
+ "@ruvector/rabitq-wasm": "^0.1.0",
100
101
  "semver": "^7.6.0"
101
102
  },
102
103
  "optionalDependencies": {
103
104
  "@claude-flow/aidefence": "^3.0.2",
104
- "@claude-flow/security": "^3.0.0-alpha.1",
105
105
  "@claude-flow/codex": "^3.0.0-alpha.8",
106
106
  "@claude-flow/embeddings": "^3.0.0-alpha.12",
107
107
  "@claude-flow/guidance": "^3.0.0-alpha.1",
108
108
  "@claude-flow/memory": "^3.0.0-alpha.12",
109
109
  "@claude-flow/plugin-gastown-bridge": "^0.1.3",
110
+ "@claude-flow/security": "^3.0.0-alpha.1",
110
111
  "@ruvector/attention": "^0.1.32",
111
112
  "@ruvector/attention-darwin-arm64": "0.1.32",
113
+ "@ruvector/diskann": "^0.1.0",
112
114
  "@ruvector/learning-wasm": "^0.1.29",
113
115
  "@ruvector/router": "^0.1.30",
114
116
  "@ruvector/ruvllm-wasm": "^2.0.2",
115
117
  "@ruvector/rvagent-wasm": "^0.1.0",
116
- "@ruvector/diskann": "^0.1.0",
117
118
  "@ruvector/sona": "^0.1.5",
118
119
  "agentdb": "^3.0.0-alpha.11",
119
120
  "agentic-flow": "^3.0.0-alpha.1"