@claude-flow/cli 3.38.19 → 3.38.20
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,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest": {
|
|
3
|
-
"version": "3.38.
|
|
3
|
+
"version": "3.38.20",
|
|
4
4
|
"files": {
|
|
5
5
|
"auto-memory-hook.mjs": "85fe05c757421c52137c0bc8545a0896bab6b4714538c2a11d1d0835bfcc8c1c",
|
|
6
6
|
"hook-handler.cjs": "dae295fb9ae2626b89899c19a20cc911541af82b52d2eeb9b214d618b96e9a86",
|
|
7
7
|
"intelligence.cjs": "30e42ed7ec4ca5a94ac54fdb1330d2d47ac5f3fdeeef207753574723a9e77b5c",
|
|
8
|
-
"statusline.cjs": "
|
|
8
|
+
"statusline.cjs": "4a48353b4f1566fa4379b00fd0321b6676a22b6cc91fbbd8380ac5183d619468"
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
|
-
"signature": "
|
|
11
|
+
"signature": "XrmLYCSWusInkReUHieYqHKPPC8/0TKovnPNWAdPvxDEhHezvy+BkkVyk7Y62HClcy7a4+PP2G4mJ1kaPLJ7Bw==",
|
|
12
12
|
"algorithm": "ed25519"
|
|
13
13
|
}
|
|
@@ -556,6 +556,68 @@ function getLocalSecurity(cliSecurity) {
|
|
|
556
556
|
return base;
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
+
// Cached pattern count. The store is routinely >10MB (14.5MB / 1277 patterns on
|
|
560
|
+
// the machine this was diagnosed on, costing 53ms to read+parse), and the
|
|
561
|
+
// statusline re-renders on every prompt, so the parse is keyed on the file's
|
|
562
|
+
// mtime+size and reused until the store actually changes.
|
|
563
|
+
const PATTERN_COUNT_CACHE = path.join(os.tmpdir(), 'ruflo-statusline-patterns-' + require('crypto').createHash('md5').update(CWD).digest('hex').slice(0, 8) + '.json');
|
|
564
|
+
|
|
565
|
+
function countPatternsCached(file) {
|
|
566
|
+
let stat;
|
|
567
|
+
try { stat = fs.statSync(file); } catch { return 0; }
|
|
568
|
+
const key = stat.mtimeMs + ':' + stat.size;
|
|
569
|
+
|
|
570
|
+
try {
|
|
571
|
+
const memo = JSON.parse(fs.readFileSync(PATTERN_COUNT_CACHE, 'utf-8'));
|
|
572
|
+
if (memo && memo[file] && memo[file].key === key) return memo[file].count;
|
|
573
|
+
} catch { /* no memo yet, or unreadable — fall through and recount */ }
|
|
574
|
+
|
|
575
|
+
let count = 0;
|
|
576
|
+
try {
|
|
577
|
+
const raw = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
578
|
+
if (Array.isArray(raw)) count = raw.length;
|
|
579
|
+
else if (raw && Array.isArray(raw.patterns)) count = raw.patterns.length;
|
|
580
|
+
else if (raw && typeof raw === 'object') count = Object.keys(raw).length;
|
|
581
|
+
} catch { return 0; }
|
|
582
|
+
|
|
583
|
+
try {
|
|
584
|
+
let memo = {};
|
|
585
|
+
try { memo = JSON.parse(fs.readFileSync(PATTERN_COUNT_CACHE, 'utf-8')) || {}; } catch { /* start fresh */ }
|
|
586
|
+
memo[file] = { key, count };
|
|
587
|
+
fs.writeFileSync(PATTERN_COUNT_CACHE, JSON.stringify(memo));
|
|
588
|
+
} catch { /* cache is an optimisation, never a requirement */ }
|
|
589
|
+
|
|
590
|
+
return count;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// `system` is nominally CLI-populated, but the pattern store is on disk, so a
|
|
594
|
+
// dead CLI must not render as "no learning". Without this, every candidate in
|
|
595
|
+
// resolveCliBinCandidates() failing (a source-only marketplace checkout, or an
|
|
596
|
+
// npx fetch that dies in a workspace root) silently degraded the brain to a
|
|
597
|
+
// hardcoded 0% while the overlaid segments beside it kept showing live data —
|
|
598
|
+
// indistinguishable from a genuine zero. Same reasoning as getLocalAgentDB(),
|
|
599
|
+
// which had to start reading locally after the statusline reported "Vectors 0"
|
|
600
|
+
// on a database holding thousands.
|
|
601
|
+
function getLocalIntelligence(current) {
|
|
602
|
+
const base = (current && typeof current === 'object') ? current : {};
|
|
603
|
+
if (typeof base.intelligencePct === 'number' && base.intelligencePct > 0) return base;
|
|
604
|
+
|
|
605
|
+
for (const file of [
|
|
606
|
+
path.join(CWD, '.claude-flow', 'neural', 'patterns.json'),
|
|
607
|
+
path.join(os.homedir(), '.claude-flow', 'neural', 'patterns.json'),
|
|
608
|
+
]) {
|
|
609
|
+
const n = countPatternsCached(file);
|
|
610
|
+
if (n > 0) {
|
|
611
|
+
base.intelligencePct = Math.min(100, Math.floor(n / 10));
|
|
612
|
+
return base;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// No CLI value and no local store: unknown, which is not the same as zero.
|
|
617
|
+
base.intelligencePct = null;
|
|
618
|
+
return base;
|
|
619
|
+
}
|
|
620
|
+
|
|
559
621
|
// Overlay every locally-derived block onto the CLI data (mutates in place).
|
|
560
622
|
function applyLocalOverlays(data) {
|
|
561
623
|
data.adrs = getLocalADRCount();
|
|
@@ -566,6 +628,7 @@ function applyLocalOverlays(data) {
|
|
|
566
628
|
// Security overlay: recompute freshness from disk on every render so cached
|
|
567
629
|
// CLI JSON can never freeze the pill at PENDING. See getLocalSecurity() above.
|
|
568
630
|
data.security = getLocalSecurity(data.security);
|
|
631
|
+
data.system = getLocalIntelligence(data.system);
|
|
569
632
|
return data;
|
|
570
633
|
}
|
|
571
634
|
|
|
@@ -579,7 +642,7 @@ function buildLocalFallback() {
|
|
|
579
642
|
v3Progress: { domainsCompleted: 0, totalDomains: 5, dddProgress: 0, patternsLearned: 0, sessionsCompleted: 0 },
|
|
580
643
|
security: { status: 'NONE', findings: 0, cvesFixed: 0, totalCves: 0 },
|
|
581
644
|
swarm: { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false },
|
|
582
|
-
system: { memoryMB: memMB, contextPct: 0, intelligencePct:
|
|
645
|
+
system: { memoryMB: memMB, contextPct: 0, intelligencePct: null, subAgents: 0 },
|
|
583
646
|
lastUpdated: new Date().toISOString(),
|
|
584
647
|
});
|
|
585
648
|
}
|
|
@@ -941,7 +1004,11 @@ function generateStatusline() {
|
|
|
941
1004
|
const activeAgents = swarm.activeAgents || 0;
|
|
942
1005
|
const maxAgents = swarm.maxAgents || CONFIG.maxAgents;
|
|
943
1006
|
const coordinationActive = swarm.coordinationActive || false;
|
|
944
|
-
|
|
1007
|
+
// null/undefined means "no source answered", which must not collapse to 0 --
|
|
1008
|
+
// that is exactly the ambiguity this segment used to present.
|
|
1009
|
+
const intelligencePct = (typeof system.intelligencePct === 'number')
|
|
1010
|
+
? system.intelligencePct
|
|
1011
|
+
: null;
|
|
945
1012
|
const memoryMB = system.memoryMB || 0;
|
|
946
1013
|
const subAgents = system.subAgents || 0;
|
|
947
1014
|
const findings = Math.max(0, security.findings || 0);
|
|
@@ -997,14 +1064,14 @@ function generateStatusline() {
|
|
|
997
1064
|
// do next; diagnostic detail moves to `ruflo status --verbose`.
|
|
998
1065
|
const agentsColor = activeAgents > 0 ? c.brightGreen : c.dim;
|
|
999
1066
|
const hooksColor = hooksEnabled > 0 ? c.brightGreen : c.dim;
|
|
1000
|
-
const intellColor = intelligencePct >= 80 ? c.brightGreen : intelligencePct >= 40 ? c.brightYellow : c.dim;
|
|
1067
|
+
const intellColor = intelligencePct === null ? c.dim : intelligencePct >= 80 ? c.brightGreen : intelligencePct >= 40 ? c.brightYellow : c.dim;
|
|
1001
1068
|
const swarmInd = coordinationActive ? c.brightGreen + '◉' + c.reset + ' ' : c.dim + '○' + c.reset + ' ';
|
|
1002
1069
|
const healthAllGreen = (secStatus === 'CLEAN' || secStatus === 'NONE') && findings === 0;
|
|
1003
1070
|
const opsParts = [];
|
|
1004
1071
|
opsParts.push(c.cyan + 'Swarm ' + swarmInd + agentsColor + activeAgents + c.reset + '/' + c.brightWhite + maxAgents + c.reset);
|
|
1005
1072
|
if (subAgents > 0) opsParts.push(c.brightPurple + '👥 ' + subAgents + c.reset);
|
|
1006
1073
|
opsParts.push(c.cyan + 'Hooks ' + hooksColor + hooksEnabled + c.reset + '/' + c.brightWhite + hooksTotal + c.reset);
|
|
1007
|
-
opsParts.push(intellColor + '🧠 ' + intelligencePct + '%' + c.reset);
|
|
1074
|
+
opsParts.push(intellColor + '🧠 ' + (intelligencePct === null ? '—' : intelligencePct + '%') + c.reset);
|
|
1008
1075
|
opsParts.push(c.brightCyan + '💾 ' + memoryMB + 'MB' + c.reset);
|
|
1009
1076
|
// Health: one glyph when green, terse copy when there's something to act on.
|
|
1010
1077
|
if (healthAllGreen) {
|
package/catalog-manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.38.
|
|
3
|
+
"version": "3.38.20",
|
|
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",
|