claude-flow 3.6.16 → 3.6.18

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.16",
3
+ "version": "3.6.18",
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,33 @@
4
4
  *
5
5
  * Created with ❤️ by ruv.io
6
6
  */
7
+ // MUST run before any agentic-flow / agentdb imports — this file is
8
+ // imported by every entry point (bin/cli.js, ruflo/bin/ruflo.js via
9
+ // dist/src/index.js, and tests). Patching the console here ensures the
10
+ // suppression applies regardless of how the CLI was invoked. Previously
11
+ // the suppression lived only in bin/cli.js, so the ruflo wrapper (which
12
+ // imports dist/src/index.js directly) leaked the cosmetic warning.
13
+ //
14
+ // Tight match: requires BOTH "[AgentDB Patch]" AND "Controller index not
15
+ // found" so other [AgentDB Patch] messages (real issues) still flow.
16
+ {
17
+ const _isCosmeticAgentdbPatchNoise = (msg) => {
18
+ const s = String(msg ?? '');
19
+ return s.includes('[AgentDB Patch]') && s.includes('Controller index not found');
20
+ };
21
+ const _origWarn = console.warn.bind(console);
22
+ const _origLog = console.log.bind(console);
23
+ console.warn = (...args) => {
24
+ if (_isCosmeticAgentdbPatchNoise(args[0]))
25
+ return;
26
+ _origWarn(...args);
27
+ };
28
+ console.log = (...args) => {
29
+ if (_isCosmeticAgentdbPatchNoise(args[0]))
30
+ return;
31
+ _origLog(...args);
32
+ };
33
+ }
7
34
  import { readFileSync } from 'fs';
8
35
  import { fileURLToPath } from 'url';
9
36
  import { dirname, join } from 'path';
@@ -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',
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.6.16",
3
+ "version": "3.6.18",
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",
@@ -84,7 +84,7 @@
84
84
  "test": "vitest run",
85
85
  "test:plugin-store": "npx tsx src/plugins/tests/standalone-test.ts",
86
86
  "test:pattern-store": "npx tsx src/transfer/store/tests/standalone-test.ts",
87
- "postinstall": "node -e \"const{existsSync,cpSync,readdirSync}=require('fs');const{join,dirname}=require('path');try{const r=require.resolve('agentdb');const base=r.includes('dist/src')?join(dirname(r),'..','..'):(r.includes('dist')?join(dirname(r),'..'):dirname(r));const s=join(base,'dist','src','controllers');const t=join(base,'dist','controllers');if(existsSync(s)&&!existsSync(t)){cpSync(s,t,{recursive:true});}}catch{}\"",
87
+ "postinstall": "node -e \"const{existsSync,cpSync,readdirSync,statSync}=require('fs');const{join,dirname}=require('path');try{const r=require.resolve('agentdb');const base=r.includes('dist/src')?join(dirname(r),'..','..'):(r.includes('dist')?join(dirname(r),'..'):dirname(r));const srcDist=join(base,'dist','src');if(!existsSync(srcDist))process.exit(0);for(const e of readdirSync(srcDist)){const s=join(srcDist,e);const t=join(base,'dist',e);try{if(statSync(s).isDirectory()&&!existsSync(t)){cpSync(s,t,{recursive:true});}}catch{}}}catch{}\"",
88
88
  "prepublishOnly": "cp ../../../README.md ./README.md",
89
89
  "release": "npm version prerelease --preid=alpha && npm run publish:all",
90
90
  "publish:all": "./scripts/publish.sh"