豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit eb4f251

Browse files
Reuvenruvnet
andcommitted
fix: eliminate 17 remaining bare require() calls in ESM modules (v3.5.78)
Replace runtime require() with ESM imports across 6 files: - diff-classifier.ts: child_process, util → top-level imports - coverage-router.ts: fs, path, fs/promises → top-level imports - performance-tools.ts: unlinkSync, readdirSync → extend existing import - mcp-server.ts: execFileSync, readFileSync, http → use existing imports - update/checker.ts: require.resolve → createRequire pattern - security.ts: execSync → top-level import Same bug class as #1559 — bare require() crashes in ESM packages. Co-Authored-By: claude-flow <ruv@ruv.net>
1 parent 0d248b3 commit eb4f251

File tree

9 files changed

+30
-28
lines changed

9 files changed

+30
-28
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "claude-flow",
3-
"version": "3.5.77",
3+
"version": "3.5.78",
44
"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",
55
"main": "dist/index.js",
66
"type": "module",

ruflo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ruflo",
3-
"version": "3.5.77",
3+
"version": "3.5.78",
44
"description": "Ruflo - Enterprise AI agent orchestration platform. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
55
"main": "bin/ruflo.js",
66
"type": "module",

v3/@claude-flow/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@claude-flow/cli",
3-
"version": "3.5.77",
3+
"version": "3.5.78",
44
"type": "module",
55
"description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
66
"main": "dist/src/index.js",

v3/@claude-flow/cli/src/commands/security.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import type { Command, CommandContext, CommandResult } from '../types.js';
99
import { output } from '../output.js';
10+
import { execSync } from 'node:child_process';
1011

1112
// Scan subcommand
1213
const scanCommand: Command = {
@@ -353,7 +354,6 @@ const threatsCommand: Command = {
353354
// Check for .env files committed to git
354355
const checkEnvInGit = () => {
355356
try {
356-
const { execSync } = require('child_process');
357357
const tracked = execSync('git ls-files --cached', { cwd: rootDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
358358
const envFiles = tracked.split('\n').filter((f: string) => /(?:^|\/)\.env(?:\.|$)/.test(f));
359359
for (const envFile of envFiles) {

v3/@claude-flow/cli/src/mcp-server.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
*/
1919

2020
import { EventEmitter } from 'events';
21-
import { spawn, ChildProcess } from 'child_process';
22-
import { createServer, Server } from 'http';
21+
import { spawn, ChildProcess, execFileSync } from 'child_process';
22+
import { createServer, Server, request as httpRequestFn } from 'http';
2323
import { randomUUID } from 'crypto';
2424
import * as path from 'path';
2525
import * as fs from 'fs';
@@ -713,13 +713,11 @@ export class MCPServerManager extends EventEmitter {
713713
// Verify it's actually a node process (guards against PID reuse)
714714
// DA-CRIT-3: Use execFileSync to prevent command injection via PID values
715715
try {
716-
const { execFileSync } = require('child_process') as typeof import('child_process');
717716
const safePid = String(Math.floor(Math.abs(pid)));
718717
let cmdline = '';
719718
try {
720719
// Try /proc on Linux
721-
const { readFileSync } = require('fs') as typeof import('fs');
722-
cmdline = readFileSync(`/proc/${safePid}/cmdline`, 'utf8');
720+
cmdline = fs.readFileSync(`/proc/${safePid}/cmdline`, 'utf8');
723721
} catch {
724722
// Fall back to ps on macOS/other
725723
try {
@@ -750,9 +748,8 @@ export class MCPServerManager extends EventEmitter {
750748
): Promise<any> {
751749
return new Promise((resolve, reject) => {
752750
const urlObj = new URL(url);
753-
const http = require('http');
754751

755-
const req = http.request(
752+
const req = httpRequestFn(
756753
{
757754
hostname: urlObj.hostname,
758755
port: urlObj.port,

v3/@claude-flow/cli/src/mcp-tools/performance-tools.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import { type MCPTool, getProjectCwd } from './types.js';
1616
import { validateIdentifier } from './validate-input.js';
17-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
17+
import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, readdirSync } from 'node:fs';
1818
import { join } from 'node:path';
1919
import * as os from 'node:os';
2020

@@ -222,7 +222,7 @@ export const performanceTools: MCPTool[] = [
222222
writeFileSync(probeFile, payload);
223223
readFileSync(probeFile);
224224
diskLatencyMs = Math.round((performance.now() - t0) * 100) / 100;
225-
try { const { unlinkSync } = require('node:fs'); unlinkSync(probeFile); } catch { /* best-effort */ }
225+
try { unlinkSync(probeFile); } catch { /* best-effort */ }
226226
} catch { /* disk probe failed, leave -1 */ }
227227

228228
// Check stored benchmark history for slow operations
@@ -464,7 +464,7 @@ export const performanceTools: MCPTool[] = [
464464
.sort((a, b) => b.percentOfTotal - a.percentOfTotal);
465465

466466
// Cleanup probe file
467-
try { const { unlinkSync } = require('node:fs'); unlinkSync(join(getPerfDir(), '.profile-probe')); } catch { /* ok */ }
467+
try { unlinkSync(join(getPerfDir(), '.profile-probe')); } catch { /* ok */ }
468468

469469
return {
470470
success: true,
@@ -514,7 +514,7 @@ export const performanceTools: MCPTool[] = [
514514
writeFileSync(probe, Buffer.alloc(4096, 0x42));
515515
readFileSync(probe);
516516
diskLatencyBefore = Math.round((performance.now() - t0) * 100) / 100;
517-
try { const { unlinkSync } = require('node:fs'); unlinkSync(probe); } catch { /* ok */ }
517+
try { unlinkSync(probe); } catch { /* ok */ }
518518
} catch { /* ok */ }
519519

520520
const optimizations: Array<{ action: string; applied: boolean; effect?: string; recommendation?: string }> = [];
@@ -559,9 +559,8 @@ export const performanceTools: MCPTool[] = [
559559
if (aggressive) {
560560
try {
561561
const dir = getPerfDir();
562-
const { readdirSync, unlinkSync: ul } = require('node:fs');
563562
const probes = readdirSync(dir).filter((f: string) => f.startsWith('.'));
564-
probes.forEach((f: string) => { try { ul(join(dir, f)); } catch { /* ok */ } });
563+
probes.forEach((f: string) => { try { unlinkSync(join(dir, f)); } catch { /* ok */ } });
565564
if (probes.length > 0) optimizations.push({ action: 'clear-probe-files', applied: true, effect: `Removed ${probes.length} probe file(s)` });
566565
} catch { /* ok */ }
567566
}

v3/@claude-flow/cli/src/ruvector/coverage-router.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
* - Singleton router instance
88
*/
99

10+
import * as pathMod from 'node:path';
11+
import { existsSync } from 'node:fs';
12+
import { readFile } from 'node:fs/promises';
13+
1014
// ============================================================================
1115
// Caching for Performance
1216
// ============================================================================
@@ -488,7 +492,8 @@ export async function coverageGaps(
488492
* Returns null if path is invalid or attempts traversal
489493
*/
490494
function validateProjectPath(inputPath: string | undefined): string | null {
491-
const { resolve, normalize, isAbsolute } = require('path');
495+
// eslint-disable-next-line @typescript-eslint/no-var-requires -- sync function, top-level import at file head
496+
const { resolve, normalize, isAbsolute } = pathMod;
492497

493498
// Default to cwd if not provided
494499
const basePath = inputPath || process.cwd();
@@ -536,9 +541,7 @@ async function loadProjectCoverage(projectRoot?: string, skipCache?: boolean): P
536541
}
537542
}
538543

539-
const { existsSync } = require('fs');
540-
const { readFile } = require('fs/promises');
541-
const { join, normalize } = require('path');
544+
const { join, normalize } = pathMod;
542545

543546
// Try common coverage locations (all relative to validated root)
544547
const coverageLocations = [

v3/@claude-flow/cli/src/ruvector/diff-classifier.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
* Diff Classifier for Change Analysis
33
*/
44

5+
import { execFileSync, execFile } from 'node:child_process';
6+
import { promisify } from 'node:util';
7+
58
export interface DiffClassifierConfig {
69
maxDiffSize: number;
710
classifyByImpact: boolean;
@@ -396,7 +399,7 @@ export function getGitDiffNumstat(ref: string = 'HEAD'): DiffFile[] {
396399
return cached.files;
397400
}
398401

399-
const { execFileSync } = require('child_process');
402+
// execFileSync imported at top level
400403
try {
401404
// SECURITY: Use execFileSync with args array instead of shell string
402405
// This prevents command injection via the ref parameter
@@ -471,8 +474,7 @@ export async function getGitDiffNumstatAsync(ref: string = 'HEAD'): Promise<Diff
471474
return cached.files;
472475
}
473476

474-
const { execFile } = require('child_process');
475-
const { promisify } = require('util');
477+
// execFile + promisify imported at top level
476478
const execFileAsync = promisify(execFile);
477479

478480
try {

v3/@claude-flow/cli/src/update/checker.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
import * as semver from 'semver';
7+
import { createRequire } from 'node:module';
78
import { shouldCheckForUpdates, recordCheck, getCachedVersions } from './rate-limiter.js';
89

910
export interface UpdateCheckResult {
@@ -138,10 +139,10 @@ export function getInstalledVersion(packageName: string): string | null {
138139

139140
for (const modulePath of possiblePaths) {
140141
try {
141-
// Use dynamic import with require for package.json
142-
const resolved = require.resolve(modulePath, { paths: [process.cwd()] });
143-
// eslint-disable-next-line @typescript-eslint/no-var-requires
144-
const pkg = require(resolved);
142+
// Use createRequire for ESM-compatible package.json loading
143+
const esmRequire = createRequire(import.meta.url);
144+
const resolved = esmRequire.resolve(modulePath, { paths: [process.cwd()] });
145+
const pkg = esmRequire(resolved);
145146
return pkg.version;
146147
} catch {
147148
continue;

0 commit comments

Comments
 (0)