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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow",
3
- "version": "3.6.17",
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.0",
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,7 @@
4
4
  *
5
5
  * Created with ❤️ by ruv.io
6
6
  */
7
+ import './log-filters.js';
7
8
  export declare const VERSION: string;
8
9
  export interface CLIOptions {
9
10
  name?: string;
@@ -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: !result.threat,
113
- threatDetected: result.threat,
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 safe = isSafe(input);
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({ safe }, null, 2),
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
- // Try to import @xenova/transformers for ONNX embeddings
1278
- const transformers = await import('@xenova/transformers').catch(() => null);
1279
- if (transformers) {
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('Loading ONNX embedding model (all-MiniLM-L6-v2)...');
1308
+ console.log(`Loading ONNX embedding model via ${transformersSource} (all-MiniLM-L6-v2)...`);
1282
1309
  }
1283
- // Use small, fast model for local embeddings
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.17",
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",