claude-flow 3.5.77 → 3.5.78
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 +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/security.js +1 -1
- package/v3/@claude-flow/cli/dist/src/mcp-server.js +4 -5
- package/v3/@claude-flow/cli/dist/src/mcp-tools/performance-tools.js +2 -6
- package/v3/@claude-flow/cli/dist/src/ruvector/coverage-router.js +6 -4
- package/v3/@claude-flow/cli/dist/src/ruvector/diff-classifier.js +4 -3
- package/v3/@claude-flow/cli/dist/src/update/checker.js +5 -4
- 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.5.
|
|
3
|
+
"version": "3.5.78",
|
|
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",
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Created with ❤️ by ruv.io
|
|
6
6
|
*/
|
|
7
7
|
import { output } from '../output.js';
|
|
8
|
+
import { execSync } from 'node:child_process';
|
|
8
9
|
// Scan subcommand
|
|
9
10
|
const scanCommand = {
|
|
10
11
|
name: 'scan',
|
|
@@ -337,7 +338,6 @@ const threatsCommand = {
|
|
|
337
338
|
// Check for .env files committed to git
|
|
338
339
|
const checkEnvInGit = () => {
|
|
339
340
|
try {
|
|
340
|
-
const { execSync } = require('child_process');
|
|
341
341
|
const tracked = execSync('git ls-files --cached', { cwd: rootDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
342
342
|
const envFiles = tracked.split('\n').filter((f) => /(?:^|\/)\.env(?:\.|$)/.test(f));
|
|
343
343
|
for (const envFile of envFiles) {
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
* @version 3.0.0
|
|
18
18
|
*/
|
|
19
19
|
import { EventEmitter } from 'events';
|
|
20
|
+
import { execFileSync } from 'child_process';
|
|
21
|
+
import { request as httpRequestFn } from 'http';
|
|
20
22
|
import { randomUUID } from 'crypto';
|
|
21
23
|
import * as path from 'path';
|
|
22
24
|
import * as fs from 'fs';
|
|
@@ -572,13 +574,11 @@ export class MCPServerManager extends EventEmitter {
|
|
|
572
574
|
// Verify it's actually a node process (guards against PID reuse)
|
|
573
575
|
// DA-CRIT-3: Use execFileSync to prevent command injection via PID values
|
|
574
576
|
try {
|
|
575
|
-
const { execFileSync } = require('child_process');
|
|
576
577
|
const safePid = String(Math.floor(Math.abs(pid)));
|
|
577
578
|
let cmdline = '';
|
|
578
579
|
try {
|
|
579
580
|
// Try /proc on Linux
|
|
580
|
-
|
|
581
|
-
cmdline = readFileSync(`/proc/${safePid}/cmdline`, 'utf8');
|
|
581
|
+
cmdline = fs.readFileSync(`/proc/${safePid}/cmdline`, 'utf8');
|
|
582
582
|
}
|
|
583
583
|
catch {
|
|
584
584
|
// Fall back to ps on macOS/other
|
|
@@ -608,8 +608,7 @@ export class MCPServerManager extends EventEmitter {
|
|
|
608
608
|
async httpRequest(url, method, timeout) {
|
|
609
609
|
return new Promise((resolve, reject) => {
|
|
610
610
|
const urlObj = new URL(url);
|
|
611
|
-
const
|
|
612
|
-
const req = http.request({
|
|
611
|
+
const req = httpRequestFn({
|
|
613
612
|
hostname: urlObj.hostname,
|
|
614
613
|
port: urlObj.port,
|
|
615
614
|
path: urlObj.pathname,
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { getProjectCwd } from './types.js';
|
|
15
15
|
import { validateIdentifier } from './validate-input.js';
|
|
16
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
16
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, readdirSync } from 'node:fs';
|
|
17
17
|
import { join } from 'node:path';
|
|
18
18
|
import * as os from 'node:os';
|
|
19
19
|
// Storage paths
|
|
@@ -183,7 +183,6 @@ export const performanceTools = [
|
|
|
183
183
|
readFileSync(probeFile);
|
|
184
184
|
diskLatencyMs = Math.round((performance.now() - t0) * 100) / 100;
|
|
185
185
|
try {
|
|
186
|
-
const { unlinkSync } = require('node:fs');
|
|
187
186
|
unlinkSync(probeFile);
|
|
188
187
|
}
|
|
189
188
|
catch { /* best-effort */ }
|
|
@@ -421,7 +420,6 @@ export const performanceTools = [
|
|
|
421
420
|
.sort((a, b) => b.percentOfTotal - a.percentOfTotal);
|
|
422
421
|
// Cleanup probe file
|
|
423
422
|
try {
|
|
424
|
-
const { unlinkSync } = require('node:fs');
|
|
425
423
|
unlinkSync(join(getPerfDir(), '.profile-probe'));
|
|
426
424
|
}
|
|
427
425
|
catch { /* ok */ }
|
|
@@ -472,7 +470,6 @@ export const performanceTools = [
|
|
|
472
470
|
readFileSync(probe);
|
|
473
471
|
diskLatencyBefore = Math.round((performance.now() - t0) * 100) / 100;
|
|
474
472
|
try {
|
|
475
|
-
const { unlinkSync } = require('node:fs');
|
|
476
473
|
unlinkSync(probe);
|
|
477
474
|
}
|
|
478
475
|
catch { /* ok */ }
|
|
@@ -517,10 +514,9 @@ export const performanceTools = [
|
|
|
517
514
|
if (aggressive) {
|
|
518
515
|
try {
|
|
519
516
|
const dir = getPerfDir();
|
|
520
|
-
const { readdirSync, unlinkSync: ul } = require('node:fs');
|
|
521
517
|
const probes = readdirSync(dir).filter((f) => f.startsWith('.'));
|
|
522
518
|
probes.forEach((f) => { try {
|
|
523
|
-
|
|
519
|
+
unlinkSync(join(dir, f));
|
|
524
520
|
}
|
|
525
521
|
catch { /* ok */ } });
|
|
526
522
|
if (probes.length > 0)
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
* - TTL-based caching of coverage data
|
|
7
7
|
* - Singleton router instance
|
|
8
8
|
*/
|
|
9
|
+
import * as pathMod from 'node:path';
|
|
10
|
+
import { existsSync } from 'node:fs';
|
|
11
|
+
import { readFile } from 'node:fs/promises';
|
|
9
12
|
// ============================================================================
|
|
10
13
|
// Caching for Performance
|
|
11
14
|
// ============================================================================
|
|
@@ -378,7 +381,8 @@ export async function coverageGaps(options = {}) {
|
|
|
378
381
|
* Returns null if path is invalid or attempts traversal
|
|
379
382
|
*/
|
|
380
383
|
function validateProjectPath(inputPath) {
|
|
381
|
-
|
|
384
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires -- sync function, top-level import at file head
|
|
385
|
+
const { resolve, normalize, isAbsolute } = pathMod;
|
|
382
386
|
// Default to cwd if not provided
|
|
383
387
|
const basePath = inputPath || process.cwd();
|
|
384
388
|
// Normalize and resolve the path
|
|
@@ -417,9 +421,7 @@ async function loadProjectCoverage(projectRoot, skipCache) {
|
|
|
417
421
|
return cached.report;
|
|
418
422
|
}
|
|
419
423
|
}
|
|
420
|
-
const {
|
|
421
|
-
const { readFile } = require('fs/promises');
|
|
422
|
-
const { join, normalize } = require('path');
|
|
424
|
+
const { join, normalize } = pathMod;
|
|
423
425
|
// Try common coverage locations (all relative to validated root)
|
|
424
426
|
const coverageLocations = [
|
|
425
427
|
['coverage', 'coverage-final.json'],
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Diff Classifier for Change Analysis
|
|
3
3
|
*/
|
|
4
|
+
import { execFileSync, execFile } from 'node:child_process';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
4
6
|
const DEFAULT_CONFIG = {
|
|
5
7
|
maxDiffSize: 10000,
|
|
6
8
|
classifyByImpact: true,
|
|
@@ -344,7 +346,7 @@ export function getGitDiffNumstat(ref = 'HEAD') {
|
|
|
344
346
|
if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
|
|
345
347
|
return cached.files;
|
|
346
348
|
}
|
|
347
|
-
|
|
349
|
+
// execFileSync imported at top level
|
|
348
350
|
try {
|
|
349
351
|
// SECURITY: Use execFileSync with args array instead of shell string
|
|
350
352
|
// This prevents command injection via the ref parameter
|
|
@@ -417,8 +419,7 @@ export async function getGitDiffNumstatAsync(ref = 'HEAD') {
|
|
|
417
419
|
if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
|
|
418
420
|
return cached.files;
|
|
419
421
|
}
|
|
420
|
-
|
|
421
|
-
const { promisify } = require('util');
|
|
422
|
+
// execFile + promisify imported at top level
|
|
422
423
|
const execFileAsync = promisify(execFile);
|
|
423
424
|
try {
|
|
424
425
|
// SECURITY: Use execFile with args array instead of shell string
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Queries npm registry and compares versions
|
|
4
4
|
*/
|
|
5
5
|
import * as semver from 'semver';
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
6
7
|
import { shouldCheckForUpdates, recordCheck, getCachedVersions } from './rate-limiter.js';
|
|
7
8
|
const DEFAULT_CONFIG = {
|
|
8
9
|
enabled: true,
|
|
@@ -88,10 +89,10 @@ export function getInstalledVersion(packageName) {
|
|
|
88
89
|
];
|
|
89
90
|
for (const modulePath of possiblePaths) {
|
|
90
91
|
try {
|
|
91
|
-
// Use
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
const pkg =
|
|
92
|
+
// Use createRequire for ESM-compatible package.json loading
|
|
93
|
+
const esmRequire = createRequire(import.meta.url);
|
|
94
|
+
const resolved = esmRequire.resolve(modulePath, { paths: [process.cwd()] });
|
|
95
|
+
const pkg = esmRequire(resolved);
|
|
95
96
|
return pkg.version;
|
|
96
97
|
}
|
|
97
98
|
catch {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.78",
|
|
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",
|