@claude-flow/cli 3.38.6 → 3.38.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/.claude/helpers/helpers.manifest.json +3 -3
- package/.claude/helpers/intelligence.cjs +6 -1
- package/catalog-manifest.json +2 -2
- package/dist/src/mcp-tools/memory-tools.js +24 -7
- package/dist/src/memory/memory-bridge.d.ts +19 -10
- package/dist/src/memory/memory-bridge.js +18 -9
- package/dist/src/memory/memory-initializer.d.ts +1 -0
- package/dist/src/memory/memory-initializer.js +18 -8
- package/package.json +1 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest": {
|
|
3
|
-
"version": "3.38.
|
|
3
|
+
"version": "3.38.7",
|
|
4
4
|
"files": {
|
|
5
5
|
"auto-memory-hook.mjs": "85fe05c757421c52137c0bc8545a0896bab6b4714538c2a11d1d0835bfcc8c1c",
|
|
6
6
|
"hook-handler.cjs": "dae295fb9ae2626b89899c19a20cc911541af82b52d2eeb9b214d618b96e9a86",
|
|
7
|
-
"intelligence.cjs": "
|
|
7
|
+
"intelligence.cjs": "30e42ed7ec4ca5a94ac54fdb1330d2d47ac5f3fdeeef207753574723a9e77b5c",
|
|
8
8
|
"statusline.cjs": "0457fe53f8cd2c56458ff178392536a5868efd1a573665fa43bc01d2d95ca677"
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
|
-
"signature": "
|
|
11
|
+
"signature": "FgH/N1oH9kP+lac4BmyUWUmAamnyfQzYgIt3b/xGeL2PJgOLGvPbuKF1DTpnzRHONcsAViViVt0dWKF6Q3LqAw==",
|
|
12
12
|
"algorithm": "ed25519"
|
|
13
13
|
}
|
|
@@ -830,11 +830,16 @@ function consolidate() {
|
|
|
830
830
|
pageRanks = computePageRank(nodes, edges, 0.85, 30);
|
|
831
831
|
}
|
|
832
832
|
|
|
833
|
-
// 6. Write updated graph
|
|
833
|
+
// 6. Write updated graph. #2920 follow-up: include contentFingerprint so
|
|
834
|
+
// init()'s cache-hit gate (line ~511) doesn't unconditionally miss on the
|
|
835
|
+
// very next init after a consolidate — without this, nodeCount alone
|
|
836
|
+
// matched but contentFingerprint was undefined here vs a real hash in
|
|
837
|
+
// init()'s own write, forcing a full rebuild every time.
|
|
834
838
|
writeJSON(GRAPH_PATH, {
|
|
835
839
|
version: 1,
|
|
836
840
|
updatedAt: Date.now(),
|
|
837
841
|
nodeCount: Object.keys(nodes).length,
|
|
842
|
+
contentFingerprint: storeFingerprint(store),
|
|
838
843
|
nodes,
|
|
839
844
|
edges,
|
|
840
845
|
pageRanks,
|
package/catalog-manifest.json
CHANGED
|
@@ -203,6 +203,23 @@ async function getMemoryFunctions() {
|
|
|
203
203
|
checkMemoryInitialization,
|
|
204
204
|
};
|
|
205
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* #2922: every `backend:` field in this file's tool responses used to be the
|
|
208
|
+
* hardcoded literal `'sql.js + HNSW'` regardless of which search path was
|
|
209
|
+
* actually active — most of the time that's the bridge doing a brute-force
|
|
210
|
+
* cosine scan, not HNSW. This reports the real algorithm via the same
|
|
211
|
+
* capability probe `getHNSWStatus()` already exposes.
|
|
212
|
+
*/
|
|
213
|
+
async function describeBackend() {
|
|
214
|
+
try {
|
|
215
|
+
const { getHNSWStatus } = await import('../memory/memory-initializer.js');
|
|
216
|
+
const status = getHNSWStatus();
|
|
217
|
+
return status.algorithm === 'hnsw' ? 'sql.js + HNSW' : 'sqlite (bridge, brute-force cosine)';
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return 'sqlite';
|
|
221
|
+
}
|
|
222
|
+
}
|
|
206
223
|
/**
|
|
207
224
|
* Ensure memory database is initialized and migrate legacy data if needed.
|
|
208
225
|
* #1606: Wrapped in try/catch to prevent process-level crashes that kill
|
|
@@ -318,7 +335,7 @@ export const memoryTools = [
|
|
|
318
335
|
hasEmbedding: !!result.embedding,
|
|
319
336
|
embeddingDimensions: result.embedding?.dimensions || null,
|
|
320
337
|
provenanceType: provenanceType || 'unknown',
|
|
321
|
-
backend:
|
|
338
|
+
backend: await describeBackend(),
|
|
322
339
|
storeTime: `${duration.toFixed(2)}ms`,
|
|
323
340
|
error: result.error,
|
|
324
341
|
};
|
|
@@ -371,7 +388,7 @@ export const memoryTools = [
|
|
|
371
388
|
accessCount: result.entry.accessCount,
|
|
372
389
|
hasEmbedding: result.entry.hasEmbedding,
|
|
373
390
|
found: true,
|
|
374
|
-
backend:
|
|
391
|
+
backend: await describeBackend(),
|
|
375
392
|
};
|
|
376
393
|
}
|
|
377
394
|
return {
|
|
@@ -584,7 +601,7 @@ export const memoryTools = [
|
|
|
584
601
|
namespace,
|
|
585
602
|
deleted: result.deleted,
|
|
586
603
|
hnswIndexInvalidated: result.deleted,
|
|
587
|
-
backend:
|
|
604
|
+
backend: await describeBackend(),
|
|
588
605
|
};
|
|
589
606
|
}
|
|
590
607
|
catch (error) {
|
|
@@ -641,7 +658,7 @@ export const memoryTools = [
|
|
|
641
658
|
total: result.total,
|
|
642
659
|
limit,
|
|
643
660
|
offset,
|
|
644
|
-
backend:
|
|
661
|
+
backend: await describeBackend(),
|
|
645
662
|
};
|
|
646
663
|
}
|
|
647
664
|
catch (error) {
|
|
@@ -685,7 +702,7 @@ export const memoryTools = [
|
|
|
685
702
|
? `${((withEmbeddings / allEntries.total) * 100).toFixed(1)}%`
|
|
686
703
|
: '0%',
|
|
687
704
|
namespaces,
|
|
688
|
-
backend:
|
|
705
|
+
backend: await describeBackend(),
|
|
689
706
|
version: status.version || '3.0.0',
|
|
690
707
|
features: status.features || {
|
|
691
708
|
vectorEmbeddings: true,
|
|
@@ -736,7 +753,7 @@ export const memoryTools = [
|
|
|
736
753
|
success: true,
|
|
737
754
|
message: 'Migration completed',
|
|
738
755
|
migrated: Object.keys(legacyStore.entries).length,
|
|
739
|
-
backend:
|
|
756
|
+
backend: await describeBackend(),
|
|
740
757
|
};
|
|
741
758
|
},
|
|
742
759
|
},
|
|
@@ -1149,7 +1166,7 @@ export const memoryTools = [
|
|
|
1149
1166
|
bytes += e.size || 0;
|
|
1150
1167
|
}
|
|
1151
1168
|
return {
|
|
1152
|
-
backend:
|
|
1169
|
+
backend: await describeBackend(),
|
|
1153
1170
|
entries: all.total ?? all.entries.length,
|
|
1154
1171
|
size: bytes,
|
|
1155
1172
|
namespaces: Object.entries(nsCounts).map(([name, entries]) => ({ name, entries })),
|
|
@@ -209,21 +209,29 @@ export declare function bridgeLoadEmbeddingModel(dbPath?: string): Promise<{
|
|
|
209
209
|
loadTime?: number;
|
|
210
210
|
} | null>;
|
|
211
211
|
/**
|
|
212
|
-
* Get
|
|
212
|
+
* Get vector search status from AgentDB v3's SQLite-backed store.
|
|
213
213
|
* Returns null if unavailable.
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
*
|
|
215
|
+
* #2922: previously named `bridgeGetHNSWStatus` and unconditionally returned
|
|
216
|
+
* `available: true` whenever a DB connection succeeded — but the search this
|
|
217
|
+
* status describes (`bridgeSearchBruteForceCosine`, below) is a full-table
|
|
218
|
+
* SELECT + brute-force cosine scan, not an HNSW index lookup. Renamed and
|
|
219
|
+
* given an explicit `algorithm` field so callers can't mistake "vector
|
|
220
|
+
* search works" for "vector search is HNSW-accelerated".
|
|
221
|
+
*/
|
|
222
|
+
export declare function bridgeGetVectorSearchStatus(dbPath?: string): Promise<{
|
|
216
223
|
available: boolean;
|
|
217
224
|
initialized: boolean;
|
|
218
225
|
entryCount: number;
|
|
219
226
|
dimensions: number;
|
|
227
|
+
algorithm: 'brute-force-cosine';
|
|
220
228
|
} | null>;
|
|
221
229
|
/**
|
|
222
|
-
* Search
|
|
223
|
-
*
|
|
224
|
-
*
|
|
230
|
+
* Search AgentDB v3's embedder + SQLite entries via a full-table scan and
|
|
231
|
+
* brute-force cosine similarity. NOT HNSW-accelerated — see #2922. Returns
|
|
232
|
+
* null if unavailable.
|
|
225
233
|
*/
|
|
226
|
-
export declare function
|
|
234
|
+
export declare function bridgeSearchBruteForceCosine(queryEmbedding: number[], options?: {
|
|
227
235
|
k?: number;
|
|
228
236
|
namespace?: string;
|
|
229
237
|
threshold?: number;
|
|
@@ -235,10 +243,11 @@ export declare function bridgeSearchHNSW(queryEmbedding: number[], options?: {
|
|
|
235
243
|
namespace: string;
|
|
236
244
|
}> | null>;
|
|
237
245
|
/**
|
|
238
|
-
* Add entry to the bridge's database with embedding.
|
|
239
|
-
*
|
|
246
|
+
* Add entry to the bridge's database with embedding. No HNSW index is built
|
|
247
|
+
* or updated here — see #2922; the embedding is only stored for a later
|
|
248
|
+
* brute-force scan. Returns null if unavailable.
|
|
240
249
|
*/
|
|
241
|
-
export declare function
|
|
250
|
+
export declare function bridgeAddEmbedding(id: string, embedding: number[], entry: {
|
|
242
251
|
id: string;
|
|
243
252
|
key: string;
|
|
244
253
|
namespace: string;
|
|
@@ -1478,10 +1478,17 @@ export async function bridgeLoadEmbeddingModel(dbPath) {
|
|
|
1478
1478
|
}
|
|
1479
1479
|
// ===== Phase 3: HNSW bridge =====
|
|
1480
1480
|
/**
|
|
1481
|
-
* Get
|
|
1481
|
+
* Get vector search status from AgentDB v3's SQLite-backed store.
|
|
1482
1482
|
* Returns null if unavailable.
|
|
1483
|
+
*
|
|
1484
|
+
* #2922: previously named `bridgeGetHNSWStatus` and unconditionally returned
|
|
1485
|
+
* `available: true` whenever a DB connection succeeded — but the search this
|
|
1486
|
+
* status describes (`bridgeSearchBruteForceCosine`, below) is a full-table
|
|
1487
|
+
* SELECT + brute-force cosine scan, not an HNSW index lookup. Renamed and
|
|
1488
|
+
* given an explicit `algorithm` field so callers can't mistake "vector
|
|
1489
|
+
* search works" for "vector search is HNSW-accelerated".
|
|
1483
1490
|
*/
|
|
1484
|
-
export async function
|
|
1491
|
+
export async function bridgeGetVectorSearchStatus(dbPath) {
|
|
1485
1492
|
const registry = await getRegistry(dbPath);
|
|
1486
1493
|
if (!registry)
|
|
1487
1494
|
return null;
|
|
@@ -1503,6 +1510,7 @@ export async function bridgeGetHNSWStatus(dbPath) {
|
|
|
1503
1510
|
initialized: true,
|
|
1504
1511
|
entryCount,
|
|
1505
1512
|
dimensions: 384,
|
|
1513
|
+
algorithm: 'brute-force-cosine',
|
|
1506
1514
|
};
|
|
1507
1515
|
}
|
|
1508
1516
|
catch {
|
|
@@ -1510,11 +1518,11 @@ export async function bridgeGetHNSWStatus(dbPath) {
|
|
|
1510
1518
|
}
|
|
1511
1519
|
}
|
|
1512
1520
|
/**
|
|
1513
|
-
* Search
|
|
1514
|
-
*
|
|
1515
|
-
*
|
|
1521
|
+
* Search AgentDB v3's embedder + SQLite entries via a full-table scan and
|
|
1522
|
+
* brute-force cosine similarity. NOT HNSW-accelerated — see #2922. Returns
|
|
1523
|
+
* null if unavailable.
|
|
1516
1524
|
*/
|
|
1517
|
-
export async function
|
|
1525
|
+
export async function bridgeSearchBruteForceCosine(queryEmbedding, options, dbPath) {
|
|
1518
1526
|
const registry = await getRegistry(dbPath);
|
|
1519
1527
|
if (!registry)
|
|
1520
1528
|
return null;
|
|
@@ -1576,10 +1584,11 @@ export async function bridgeSearchHNSW(queryEmbedding, options, dbPath) {
|
|
|
1576
1584
|
}
|
|
1577
1585
|
}
|
|
1578
1586
|
/**
|
|
1579
|
-
* Add entry to the bridge's database with embedding.
|
|
1580
|
-
*
|
|
1587
|
+
* Add entry to the bridge's database with embedding. No HNSW index is built
|
|
1588
|
+
* or updated here — see #2922; the embedding is only stored for a later
|
|
1589
|
+
* brute-force scan. Returns null if unavailable.
|
|
1581
1590
|
*/
|
|
1582
|
-
export async function
|
|
1591
|
+
export async function bridgeAddEmbedding(id, embedding, entry, dbPath) {
|
|
1583
1592
|
const registry = await getRegistry(dbPath);
|
|
1584
1593
|
if (!registry)
|
|
1585
1594
|
return null;
|
|
@@ -750,7 +750,7 @@ export async function addToHNSWIndex(id, embedding, entry) {
|
|
|
750
750
|
// ADR-053: Try AgentDB v3 bridge first
|
|
751
751
|
const bridge = await getBridge();
|
|
752
752
|
if (bridge) {
|
|
753
|
-
const bridgeResult = await bridge.
|
|
753
|
+
const bridgeResult = await bridge.bridgeAddEmbedding(id, embedding, entry);
|
|
754
754
|
if (bridgeResult === true)
|
|
755
755
|
return true;
|
|
756
756
|
}
|
|
@@ -780,7 +780,7 @@ export async function searchHNSWIndex(queryEmbedding, options) {
|
|
|
780
780
|
// ADR-053: Try AgentDB v3 bridge first
|
|
781
781
|
const bridge = await getBridge();
|
|
782
782
|
if (bridge) {
|
|
783
|
-
const bridgeResult = await bridge.
|
|
783
|
+
const bridgeResult = await bridge.bridgeSearchBruteForceCosine(queryEmbedding, options);
|
|
784
784
|
if (bridgeResult)
|
|
785
785
|
return bridgeResult;
|
|
786
786
|
}
|
|
@@ -826,14 +826,23 @@ export async function searchHNSWIndex(queryEmbedding, options) {
|
|
|
826
826
|
* Get HNSW index status
|
|
827
827
|
*/
|
|
828
828
|
export function getHNSWStatus() {
|
|
829
|
-
//
|
|
829
|
+
// #2922: this branch previously reported `available: true` whenever the
|
|
830
|
+
// bridge was loaded, on the theory that "AgentDB v3 is HNSW-equivalent" —
|
|
831
|
+
// but the bridge's actual search path (bridgeSearchBruteForceCosine, see
|
|
832
|
+
// memory-bridge.ts) does a full-table SELECT + brute-force cosine loop and
|
|
833
|
+
// never touches @ruvector/core or an HNSW index, regardless of whether
|
|
834
|
+
// ruvector-core itself is installed. `available` here means "an HNSW
|
|
835
|
+
// index is the one actually searched", matching what this function's own
|
|
836
|
+
// name promises — that's false while the bridge is the active path, so
|
|
837
|
+
// this no longer claims otherwise. Vector search itself still works via
|
|
838
|
+
// the bridge; `algorithm` tells callers it's brute-force, not HNSW.
|
|
830
839
|
if (_bridge && _bridge !== null) {
|
|
831
|
-
// Bridge is loaded — HNSW-equivalent is available via AgentDB v3
|
|
832
840
|
return {
|
|
833
|
-
available:
|
|
834
|
-
initialized:
|
|
841
|
+
available: false,
|
|
842
|
+
initialized: false,
|
|
835
843
|
entryCount: hnswIndex?.entries.size ?? 0,
|
|
836
|
-
dimensions: hnswIndex?.dimensions ?? 384
|
|
844
|
+
dimensions: hnswIndex?.dimensions ?? 384,
|
|
845
|
+
algorithm: 'brute-force-cosine',
|
|
837
846
|
};
|
|
838
847
|
}
|
|
839
848
|
// #2356: `available` now reflects real capability (index already loaded OR
|
|
@@ -845,7 +854,8 @@ export function getHNSWStatus() {
|
|
|
845
854
|
available: hnswIndex !== null || isRuvectorCoreResolvable(),
|
|
846
855
|
initialized: hnswIndex?.initialized ?? false,
|
|
847
856
|
entryCount: hnswIndex?.entries.size ?? 0,
|
|
848
|
-
dimensions: hnswIndex?.dimensions ?? 384
|
|
857
|
+
dimensions: hnswIndex?.dimensions ?? 384,
|
|
858
|
+
algorithm: 'hnsw',
|
|
849
859
|
};
|
|
850
860
|
}
|
|
851
861
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.38.
|
|
3
|
+
"version": "3.38.7",
|
|
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",
|