claude-flow 3.6.17 → 3.6.19
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 +5 -3
- package/v3/@claude-flow/cli/dist/src/index.d.ts +1 -0
- package/v3/@claude-flow/cli/dist/src/index.js +7 -0
- package/v3/@claude-flow/cli/dist/src/log-filters.d.ts +22 -0
- package/v3/@claude-flow/cli/dist/src/log-filters.js +36 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/security-tools.js +65 -4
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +32 -7
- package/v3/@claude-flow/cli/package.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.19",
|
|
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",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"@ruvector/rvf-wasm": "0.1.5",
|
|
74
74
|
"@hono/node-server": ">=1.19.10",
|
|
75
75
|
"flatted": ">=3.4.0",
|
|
76
|
-
"tar": ">=7.5.
|
|
76
|
+
"tar": ">=7.5.11",
|
|
77
77
|
"picomatch": ">=4.0.3",
|
|
78
78
|
"path-to-regexp": ">=8.2.1",
|
|
79
79
|
"undici": ">=7.18.0",
|
|
@@ -81,7 +81,9 @@
|
|
|
81
81
|
"@isaacs/brace-expansion": ">=5.0.1",
|
|
82
82
|
"cacache": ">=20.0.0",
|
|
83
83
|
"make-fetch-happen": ">=15.0.0",
|
|
84
|
-
"express-rate-limit": ">=8.4.1"
|
|
84
|
+
"express-rate-limit": ">=8.4.1",
|
|
85
|
+
"protobufjs": ">=7.5.5",
|
|
86
|
+
"uuid": ">=14.0.0"
|
|
85
87
|
},
|
|
86
88
|
"devDependencies": {
|
|
87
89
|
"@openai/codex": "^0.98.0",
|
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Created with ❤️ by ruv.io
|
|
6
6
|
*/
|
|
7
|
+
// MUST be the first import — installs console filter for the cosmetic
|
|
8
|
+
// "[AgentDB Patch] Controller index not found" warning before any
|
|
9
|
+
// agentic-flow / agentdb code can load. ES module imports are evaluated
|
|
10
|
+
// in source order, so this file runs its side effects before any other
|
|
11
|
+
// import in this module's import graph (including transitive imports of
|
|
12
|
+
// agentic-flow via commands/index.js).
|
|
13
|
+
import './log-filters.js';
|
|
7
14
|
import { readFileSync } from 'fs';
|
|
8
15
|
import { fileURLToPath } from 'url';
|
|
9
16
|
import { dirname, join } from 'path';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console filter for the cosmetic "[AgentDB Patch] Controller index not found"
|
|
3
|
+
* warning emitted by agentic-flow's runtime patch (it expects agentdb v1.x
|
|
4
|
+
* layout but we use v3). This file MUST be imported as the first side-effect
|
|
5
|
+
* import in any entry point so the patch is in place before agentic-flow
|
|
6
|
+
* (and anything that transitively imports it) loads.
|
|
7
|
+
*
|
|
8
|
+
* The previous attempt put the suppression as a top-level code block inside
|
|
9
|
+
* src/index.ts, but ES module imports are evaluated before the file's own
|
|
10
|
+
* top-level code, so transitive imports of agentic-flow were still
|
|
11
|
+
* triggering the warning before the suppression took effect. A dedicated
|
|
12
|
+
* side-effect module imported FIRST avoids that.
|
|
13
|
+
*
|
|
14
|
+
* Tight match: requires BOTH "[AgentDB Patch]" AND "Controller index not
|
|
15
|
+
* found". Other [AgentDB Patch] messages (real issues) flow through.
|
|
16
|
+
* Audit log audit_1776483149979 flagged the previous broad filter as too
|
|
17
|
+
* aggressive — this one is tight enough to be safe.
|
|
18
|
+
*/
|
|
19
|
+
declare const isCosmeticAgentdbPatchNoise: (msg: unknown) => boolean;
|
|
20
|
+
declare const origWarn: (message?: any, ...optionalParams: any[]) => void;
|
|
21
|
+
declare const origLog: (message?: any, ...optionalParams: any[]) => void;
|
|
22
|
+
//# sourceMappingURL=log-filters.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Console filter for the cosmetic "[AgentDB Patch] Controller index not found"
|
|
4
|
+
* warning emitted by agentic-flow's runtime patch (it expects agentdb v1.x
|
|
5
|
+
* layout but we use v3). This file MUST be imported as the first side-effect
|
|
6
|
+
* import in any entry point so the patch is in place before agentic-flow
|
|
7
|
+
* (and anything that transitively imports it) loads.
|
|
8
|
+
*
|
|
9
|
+
* The previous attempt put the suppression as a top-level code block inside
|
|
10
|
+
* src/index.ts, but ES module imports are evaluated before the file's own
|
|
11
|
+
* top-level code, so transitive imports of agentic-flow were still
|
|
12
|
+
* triggering the warning before the suppression took effect. A dedicated
|
|
13
|
+
* side-effect module imported FIRST avoids that.
|
|
14
|
+
*
|
|
15
|
+
* Tight match: requires BOTH "[AgentDB Patch]" AND "Controller index not
|
|
16
|
+
* found". Other [AgentDB Patch] messages (real issues) flow through.
|
|
17
|
+
* Audit log audit_1776483149979 flagged the previous broad filter as too
|
|
18
|
+
* aggressive — this one is tight enough to be safe.
|
|
19
|
+
*/
|
|
20
|
+
const isCosmeticAgentdbPatchNoise = (msg) => {
|
|
21
|
+
const s = String(msg ?? '');
|
|
22
|
+
return s.includes('[AgentDB Patch]') && s.includes('Controller index not found');
|
|
23
|
+
};
|
|
24
|
+
const origWarn = console.warn.bind(console);
|
|
25
|
+
const origLog = console.log.bind(console);
|
|
26
|
+
console.warn = (...args) => {
|
|
27
|
+
if (isCosmeticAgentdbPatchNoise(args[0]))
|
|
28
|
+
return;
|
|
29
|
+
origWarn(...args);
|
|
30
|
+
};
|
|
31
|
+
console.log = (...args) => {
|
|
32
|
+
if (isCosmeticAgentdbPatchNoise(args[0]))
|
|
33
|
+
return;
|
|
34
|
+
origLog(...args);
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=log-filters.js.map
|
|
@@ -18,6 +18,20 @@ const require = createRequire(import.meta.url);
|
|
|
18
18
|
let aidefenceInstance = null;
|
|
19
19
|
// Track if we've attempted install this session
|
|
20
20
|
let installAttempted = false;
|
|
21
|
+
// ADR-093 follow-up: wrapper-level counters for the lightweight aidefence
|
|
22
|
+
// tools (has_pii, is_safe, scan-quick) that bypass the package's own
|
|
23
|
+
// stats tracking. The audit flagged that aidefence_stats stayed at zero
|
|
24
|
+
// regardless of detections from these paths. Stats now combine the
|
|
25
|
+
// underlying defender.getStats() with our wrapper counters so the user
|
|
26
|
+
// sees a true reflection of how often each tool category fired.
|
|
27
|
+
const wrapperStats = {
|
|
28
|
+
hasPiiCalls: 0,
|
|
29
|
+
hasPiiHits: 0,
|
|
30
|
+
isSafeCalls: 0,
|
|
31
|
+
isSafeUnsafeVerdicts: 0,
|
|
32
|
+
quickScanCalls: 0,
|
|
33
|
+
quickScanThreats: 0,
|
|
34
|
+
};
|
|
21
35
|
/**
|
|
22
36
|
* Get or create AIDefence instance (throws if unavailable)
|
|
23
37
|
*/
|
|
@@ -105,13 +119,27 @@ const aidefenceScanTool = {
|
|
|
105
119
|
const defender = await getAIDefence();
|
|
106
120
|
if (quick) {
|
|
107
121
|
const result = defender.quickScan(input);
|
|
122
|
+
// Audit-flagged: quickScan focuses on prompt-injection/jailbreak
|
|
123
|
+
// patterns and missed obvious PII (email + API key). Layer a fast
|
|
124
|
+
// PII check so quick mode catches both threat classes.
|
|
125
|
+
let piiPresent = false;
|
|
126
|
+
try {
|
|
127
|
+
piiPresent = !!defender.hasPII(input);
|
|
128
|
+
}
|
|
129
|
+
catch { /* hasPII unavailable */ }
|
|
130
|
+
const threatDetected = result.threat || piiPresent;
|
|
131
|
+
wrapperStats.quickScanCalls++;
|
|
132
|
+
if (threatDetected)
|
|
133
|
+
wrapperStats.quickScanThreats++;
|
|
108
134
|
return {
|
|
109
135
|
content: [{
|
|
110
136
|
type: 'text',
|
|
111
137
|
text: JSON.stringify({
|
|
112
|
-
safe: !
|
|
113
|
-
threatDetected
|
|
138
|
+
safe: !threatDetected,
|
|
139
|
+
threatDetected,
|
|
114
140
|
confidence: result.confidence,
|
|
141
|
+
piiDetected: piiPresent,
|
|
142
|
+
promptInjectionDetected: result.threat,
|
|
115
143
|
mode: 'quick',
|
|
116
144
|
}, null, 2),
|
|
117
145
|
}],
|
|
@@ -249,11 +277,24 @@ const aidefenceStatsTool = {
|
|
|
249
277
|
content: [{
|
|
250
278
|
type: 'text',
|
|
251
279
|
text: JSON.stringify({
|
|
280
|
+
// Underlying defender stats (from full detect() calls via aidefence_scan/aidefence_analyze)
|
|
252
281
|
detectionCount: stats.detectionCount,
|
|
253
282
|
avgDetectionTimeMs: stats.avgDetectionTimeMs,
|
|
254
283
|
learnedPatterns: stats.learnedPatterns,
|
|
255
284
|
mitigationStrategies: stats.mitigationStrategies,
|
|
256
285
|
avgMitigationEffectiveness: stats.avgMitigationEffectiveness,
|
|
286
|
+
// ADR-093 follow-up: wrapper-level stats for the lightweight
|
|
287
|
+
// tools that bypass the defender's own counters. Audit found
|
|
288
|
+
// these stayed at 0 even after has_pii/is_safe/scan-quick
|
|
289
|
+
// calls — these counters surface real activity.
|
|
290
|
+
wrapper: {
|
|
291
|
+
hasPiiCalls: wrapperStats.hasPiiCalls,
|
|
292
|
+
hasPiiHits: wrapperStats.hasPiiHits,
|
|
293
|
+
isSafeCalls: wrapperStats.isSafeCalls,
|
|
294
|
+
isSafeUnsafeVerdicts: wrapperStats.isSafeUnsafeVerdicts,
|
|
295
|
+
quickScanCalls: wrapperStats.quickScanCalls,
|
|
296
|
+
quickScanThreats: wrapperStats.quickScanThreats,
|
|
297
|
+
},
|
|
257
298
|
}, null, 2),
|
|
258
299
|
}],
|
|
259
300
|
};
|
|
@@ -391,12 +432,29 @@ const aidefenceIsSafeTool = {
|
|
|
391
432
|
}
|
|
392
433
|
const input = args.input;
|
|
393
434
|
try {
|
|
435
|
+
// Route through the singleton so wrapper stats track this call,
|
|
436
|
+
// and so a single defender controls both the prompt-injection model
|
|
437
|
+
// and the PII detector.
|
|
438
|
+
const defender = await getAIDefence();
|
|
394
439
|
const { isSafe } = await import('@claude-flow/aidefence');
|
|
395
|
-
const
|
|
440
|
+
const promptSafe = isSafe(input);
|
|
441
|
+
let piiPresent = false;
|
|
442
|
+
try {
|
|
443
|
+
piiPresent = !!defender.hasPII(input);
|
|
444
|
+
}
|
|
445
|
+
catch { /* hasPII unavailable */ }
|
|
446
|
+
const safe = promptSafe && !piiPresent;
|
|
447
|
+
wrapperStats.isSafeCalls++;
|
|
448
|
+
if (!safe)
|
|
449
|
+
wrapperStats.isSafeUnsafeVerdicts++;
|
|
396
450
|
return {
|
|
397
451
|
content: [{
|
|
398
452
|
type: 'text',
|
|
399
|
-
text: JSON.stringify({
|
|
453
|
+
text: JSON.stringify({
|
|
454
|
+
safe,
|
|
455
|
+
promptSafe,
|
|
456
|
+
piiPresent,
|
|
457
|
+
}, null, 2),
|
|
400
458
|
}],
|
|
401
459
|
};
|
|
402
460
|
}
|
|
@@ -437,6 +495,9 @@ const aidefenceHasPIITool = {
|
|
|
437
495
|
try {
|
|
438
496
|
const defender = await getAIDefence();
|
|
439
497
|
const hasPII = defender.hasPII(input);
|
|
498
|
+
wrapperStats.hasPiiCalls++;
|
|
499
|
+
if (hasPII)
|
|
500
|
+
wrapperStats.hasPiiHits++;
|
|
440
501
|
return {
|
|
441
502
|
content: [{
|
|
442
503
|
type: 'text',
|
|
@@ -1274,15 +1274,40 @@ export async function loadEmbeddingModel(options) {
|
|
|
1274
1274
|
}
|
|
1275
1275
|
}
|
|
1276
1276
|
try {
|
|
1277
|
-
//
|
|
1278
|
-
|
|
1279
|
-
|
|
1277
|
+
// ADR-094: prefer @huggingface/transformers (clears protobufjs <7.5.5
|
|
1278
|
+
// critical RCE chain), fall back to legacy @xenova/transformers.
|
|
1279
|
+
// Inlined here rather than depending on @claude-flow/embeddings to
|
|
1280
|
+
// avoid a circular optional-dep at install time; the logic mirrors
|
|
1281
|
+
// @claude-flow/embeddings/src/transformers-loader.ts.
|
|
1282
|
+
let transformersSource = null;
|
|
1283
|
+
let pipelineFn = null;
|
|
1284
|
+
{
|
|
1285
|
+
const tryLoad = async (specifier) => {
|
|
1286
|
+
try {
|
|
1287
|
+
return (await import(specifier));
|
|
1288
|
+
}
|
|
1289
|
+
catch {
|
|
1290
|
+
return null;
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
const hf = await tryLoad('@huggingface/transformers');
|
|
1294
|
+
if (hf && typeof hf.pipeline === 'function') {
|
|
1295
|
+
pipelineFn = hf.pipeline;
|
|
1296
|
+
transformersSource = '@huggingface/transformers';
|
|
1297
|
+
}
|
|
1298
|
+
else {
|
|
1299
|
+
const xen = await tryLoad('@xenova/transformers');
|
|
1300
|
+
if (xen && typeof xen.pipeline === 'function') {
|
|
1301
|
+
pipelineFn = xen.pipeline;
|
|
1302
|
+
transformersSource = '@xenova/transformers';
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
if (pipelineFn && transformersSource) {
|
|
1280
1307
|
if (verbose) {
|
|
1281
|
-
console.log(
|
|
1308
|
+
console.log(`Loading ONNX embedding model via ${transformersSource} (all-MiniLM-L6-v2)...`);
|
|
1282
1309
|
}
|
|
1283
|
-
|
|
1284
|
-
const { pipeline } = transformers;
|
|
1285
|
-
const embedder = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
|
|
1310
|
+
const embedder = await pipelineFn('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
|
|
1286
1311
|
embeddingModelState = {
|
|
1287
1312
|
loaded: true,
|
|
1288
1313
|
model: embedder,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.19",
|
|
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",
|