@claude-flow/cli 3.32.20 → 3.32.21
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest": {
|
|
3
|
-
"version": "3.32.
|
|
3
|
+
"version": "3.32.21",
|
|
4
4
|
"files": {
|
|
5
5
|
"auto-memory-hook.mjs": "e3e1033b24704992ddef6b31c7fa9dd7fcd9e1af7935dd77ef73402b916b31e6",
|
|
6
6
|
"hook-handler.cjs": "f87ec28684bfc5fd0a54c46bd2a53a3fb037defe71d0ea4b8a5cb88a2cd87a3f",
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
"statusline.cjs": "10f74a1aa9af217d0623c0a9839d82825b0eed31a4707a7531a85c6116869a6c"
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
|
-
"signature": "
|
|
11
|
+
"signature": "/u6cu5Rvxtw6aRDpqL1ZUGcCxrzoRUfDRtDI13Yd8RQres08uHFd1tSWJgDDw+fYYNHvmR/yfJS3Hb9KCccTAQ==",
|
|
12
12
|
"algorithm": "ed25519"
|
|
13
13
|
}
|
package/catalog-manifest.json
CHANGED
|
@@ -111,8 +111,16 @@ const searchCommand = {
|
|
|
111
111
|
action: async (ctx) => {
|
|
112
112
|
const query = ctx.flags.query;
|
|
113
113
|
const namespace = ctx.flags.collection || 'default';
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
// #2790 fix — `||` on a numeric-0 argument returns the fallback,
|
|
115
|
+
// so `--threshold 0` was unreachable. `??` preserves an explicit zero.
|
|
116
|
+
// The flag arrives as a string here (parser produces string for typed
|
|
117
|
+
// options passed via CLI without type coercion in some paths), so we
|
|
118
|
+
// check for undefined explicitly rather than falsy.
|
|
119
|
+
const limit = parseInt(ctx.flags.limit ?? '10', 10);
|
|
120
|
+
const rawThreshold = ctx.flags.threshold;
|
|
121
|
+
const threshold = rawThreshold === undefined || rawThreshold === null
|
|
122
|
+
? 0.5
|
|
123
|
+
: parseFloat(String(rawThreshold));
|
|
116
124
|
const dbPath = ctx.flags['db-path'] || '.swarm/memory.db';
|
|
117
125
|
if (!query) {
|
|
118
126
|
output.printError('Query is required');
|
|
@@ -1006,7 +1014,12 @@ const neuralCommand = {
|
|
|
1006
1014
|
action: async (ctx) => {
|
|
1007
1015
|
const feature = ctx.flags.feature || 'all';
|
|
1008
1016
|
const init = ctx.flags.init;
|
|
1009
|
-
|
|
1017
|
+
// #2790 fix — same `0 || fallback` bug: `--drift-threshold 0` was
|
|
1018
|
+
// silently replaced by 0.3. Use nullish coalescing.
|
|
1019
|
+
const rawDriftThreshold = ctx.flags['drift-threshold'] ?? ctx.flags.driftThreshold;
|
|
1020
|
+
const driftThreshold = rawDriftThreshold === undefined || rawDriftThreshold === null
|
|
1021
|
+
? 0.3
|
|
1022
|
+
: parseFloat(String(rawDriftThreshold));
|
|
1010
1023
|
const decayRate = parseFloat((ctx.flags['decay-rate'] || ctx.flags.decayRate || '0.01'));
|
|
1011
1024
|
const consolidationInterval = parseInt((ctx.flags['consolidation-interval'] || ctx.flags.consolidationInterval || '60000'), 10);
|
|
1012
1025
|
output.writeln();
|
|
@@ -1336,7 +1336,7 @@ const transferFromProjectCommand = {
|
|
|
1336
1336
|
],
|
|
1337
1337
|
action: async (ctx) => {
|
|
1338
1338
|
const sourcePath = ctx.flags.source || ctx.args[0];
|
|
1339
|
-
const minConfidence = ctx.flags.minConfidence
|
|
1339
|
+
const minConfidence = ctx.flags.minConfidence ?? 0.7;
|
|
1340
1340
|
if (!sourcePath) {
|
|
1341
1341
|
output.printError('Source project path is required. Use --source or -s flag.');
|
|
1342
1342
|
return { success: false, exitCode: 1 };
|
|
@@ -2671,7 +2671,7 @@ const coverageRouteCommand = {
|
|
|
2671
2671
|
],
|
|
2672
2672
|
action: async (ctx) => {
|
|
2673
2673
|
const task = ctx.flags.task || ctx.args[0];
|
|
2674
|
-
const threshold = ctx.flags.threshold
|
|
2674
|
+
const threshold = ctx.flags.threshold ?? 80;
|
|
2675
2675
|
const useRuvector = !ctx.flags['no-ruvector'];
|
|
2676
2676
|
if (!task) {
|
|
2677
2677
|
output.printError('Task description is required. Use --task or -t flag.');
|
|
@@ -2891,7 +2891,7 @@ const coverageSuggestCommand = {
|
|
|
2891
2891
|
],
|
|
2892
2892
|
action: async (ctx) => {
|
|
2893
2893
|
const targetPath = ctx.flags.path || ctx.args[0];
|
|
2894
|
-
const threshold = ctx.flags.threshold
|
|
2894
|
+
const threshold = ctx.flags.threshold ?? 80;
|
|
2895
2895
|
const limit = ctx.flags.limit || 20;
|
|
2896
2896
|
if (!targetPath) {
|
|
2897
2897
|
output.printError('Path is required. Use --path or -p flag.');
|
|
@@ -3080,7 +3080,7 @@ const coverageGapsCommand = {
|
|
|
3080
3080
|
{ command: 'claude-flow hooks coverage-gaps --threshold 90', description: 'Stricter threshold' }
|
|
3081
3081
|
],
|
|
3082
3082
|
action: async (ctx) => {
|
|
3083
|
-
const threshold = ctx.flags.threshold
|
|
3083
|
+
const threshold = ctx.flags.threshold ?? 80;
|
|
3084
3084
|
const groupByAgent = ctx.flags['group-by-agent'] !== false;
|
|
3085
3085
|
const criticalOnly = ctx.flags['critical-only'] || false;
|
|
3086
3086
|
const spinner = output.createSpinner({ text: 'Analyzing project coverage gaps...' });
|
|
@@ -369,7 +369,13 @@ const searchCommand = {
|
|
|
369
369
|
const query = ctx.flags.query || ctx.args[0];
|
|
370
370
|
let namespace = ctx.flags.namespace || 'all';
|
|
371
371
|
const limit = ctx.flags.limit || 10;
|
|
372
|
-
|
|
372
|
+
// #2790 fix — `||` discards an explicit `--threshold 0` (falsy) and
|
|
373
|
+
// silently uses the fallback; that made `--threshold 0` return
|
|
374
|
+
// FEWER results than `--threshold 0.01` (non-monotonic). Nullish
|
|
375
|
+
// coalescing preserves an explicit zero. Fallback aligned with the
|
|
376
|
+
// option's declared `default: 0.7` (was `0.3` — the two disagreed
|
|
377
|
+
// and --help advertised a default the code did not honor).
|
|
378
|
+
const threshold = ctx.flags.threshold ?? 0.7;
|
|
373
379
|
const searchType = ctx.flags.type || 'semantic';
|
|
374
380
|
const buildHnsw = (ctx.flags['build-hnsw'] || ctx.flags.buildHnsw);
|
|
375
381
|
const requestedIntent = ctx.flags.intent || 'mixed';
|
|
@@ -430,9 +436,58 @@ const searchCommand = {
|
|
|
430
436
|
output.writeln();
|
|
431
437
|
// Use direct sql.js search with vector similarity
|
|
432
438
|
try {
|
|
433
|
-
const { searchEntries, resolveDbPath: _rdbSearch } = await import('../memory/memory-initializer.js');
|
|
439
|
+
const { searchEntries, listEntries, resolveDbPath: _rdbSearch } = await import('../memory/memory-initializer.js');
|
|
434
440
|
const dbPathSearch = _rdbSearch(ctx.flags.path);
|
|
435
441
|
const useSmart = (ctx.flags.smart || ctx.flags.s);
|
|
442
|
+
// #2790 fix — keyword mode was declared, echoed, and IGNORED (every
|
|
443
|
+
// search ran semantic regardless). Wire it here: list entries in
|
|
444
|
+
// the requested namespace (or all) and substring-match against key
|
|
445
|
+
// + content. Hybrid unions the keyword hits with the semantic hits
|
|
446
|
+
// and dedups by key + namespace.
|
|
447
|
+
let keywordResults = [];
|
|
448
|
+
if (searchType === 'keyword' || searchType === 'hybrid') {
|
|
449
|
+
const list = await listEntries({
|
|
450
|
+
namespace: namespace === 'all' ? undefined : namespace,
|
|
451
|
+
limit: 5000,
|
|
452
|
+
includeContent: true,
|
|
453
|
+
dbPath: dbPathSearch,
|
|
454
|
+
});
|
|
455
|
+
if (list.success) {
|
|
456
|
+
const q = query.toLowerCase();
|
|
457
|
+
keywordResults = list.entries
|
|
458
|
+
.filter((e) => {
|
|
459
|
+
const c = e.content ?? '';
|
|
460
|
+
return e.key.toLowerCase().includes(q) || c.toLowerCase().includes(q);
|
|
461
|
+
})
|
|
462
|
+
.map((e) => {
|
|
463
|
+
const c = e.content ?? '';
|
|
464
|
+
const inKey = e.key.toLowerCase().includes(q);
|
|
465
|
+
// Keyword scoring: 1.0 for key hit, 0.7 for content hit
|
|
466
|
+
return {
|
|
467
|
+
key: e.key,
|
|
468
|
+
score: inKey ? 1.0 : 0.7,
|
|
469
|
+
namespace: e.namespace,
|
|
470
|
+
preview: c.slice(0, 200),
|
|
471
|
+
};
|
|
472
|
+
})
|
|
473
|
+
.sort((a, b) => b.score - a.score)
|
|
474
|
+
.slice(0, limit);
|
|
475
|
+
}
|
|
476
|
+
if (searchType === 'keyword') {
|
|
477
|
+
// Pure-keyword mode returns directly; skip the semantic path entirely.
|
|
478
|
+
if (ctx.flags.format === 'json') {
|
|
479
|
+
output.printJson({ query, searchType, results: keywordResults, searchTime: '0ms' });
|
|
480
|
+
return { success: true, data: keywordResults };
|
|
481
|
+
}
|
|
482
|
+
output.writeln();
|
|
483
|
+
output.printSuccess(`Found ${keywordResults.length} result(s) via keyword substring match`);
|
|
484
|
+
for (const r of keywordResults) {
|
|
485
|
+
output.writeln(` ${r.key} (${r.namespace}, score=${r.score.toFixed(2)}) — ${r.preview.slice(0, 80)}${r.preview.length > 80 ? '…' : ''}`);
|
|
486
|
+
}
|
|
487
|
+
return { success: true, data: keywordResults };
|
|
488
|
+
}
|
|
489
|
+
// Hybrid mode: keyword hits will be MERGED after semantic runs below.
|
|
490
|
+
}
|
|
436
491
|
let results;
|
|
437
492
|
let searchTimeMs;
|
|
438
493
|
let smartStats;
|
|
@@ -513,6 +568,22 @@ const searchCommand = {
|
|
|
513
568
|
}));
|
|
514
569
|
searchTimeMs = searchResult.searchTime;
|
|
515
570
|
}
|
|
571
|
+
// #2790 fix (hybrid mode): union keyword results with semantic
|
|
572
|
+
// results, dedup by (key, namespace), then take top `limit`.
|
|
573
|
+
if (searchType === 'hybrid' && keywordResults.length > 0) {
|
|
574
|
+
const seen = new Set(results.map((r) => `${r.namespace}::${r.key}`));
|
|
575
|
+
for (const k of keywordResults) {
|
|
576
|
+
const id = `${k.namespace}::${k.key}`;
|
|
577
|
+
if (!seen.has(id)) {
|
|
578
|
+
results.push(k);
|
|
579
|
+
seen.add(id);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
// Rerank by score
|
|
583
|
+
results.sort((a, b) => b.score - a.score);
|
|
584
|
+
results = results.slice(0, limit);
|
|
585
|
+
backendLabel = `${backendLabel} + keyword union (#2790)`;
|
|
586
|
+
}
|
|
516
587
|
if (ctx.flags.format === 'json') {
|
|
517
588
|
output.printJson({ query, searchType, results, searchTime: `${searchTimeMs}ms`, ...(smartStats ? { stats: smartStats } : {}) });
|
|
518
589
|
return { success: true, data: results };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.32.
|
|
3
|
+
"version": "3.32.21",
|
|
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",
|