diff --git a/src/commands/run.ts b/src/commands/run.ts index 5863a73..2be4566 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -1,4 +1,4 @@ -import { execFile } from "node:child_process"; +import { exec as execCb, execFile } from "node:child_process"; import { mkdir, readFile, statfs, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; @@ -322,14 +322,14 @@ export async function retry(opts: RunOptions): Promise { * Returns a warning string if the tests fail, or null if they pass. */ export async function preflightTestRun(testCmd: string, repoRoot: string): Promise { - const { cmd, args } = parseTestCommand(testCmd); + const { cmd } = parseTestCommand(testCmd); if (!cmd) return null; + const execAsync = promisify(execCb); try { - await execFileAsync(cmd, args, { + await execAsync(testCmd, { cwd: repoRoot, timeout: 60_000, - shell: true, env: { ...process.env, CI: "true" }, }); return null; diff --git a/src/scoring/test-runner.ts b/src/scoring/test-runner.ts index 83c158f..705c867 100644 --- a/src/scoring/test-runner.ts +++ b/src/scoring/test-runner.ts @@ -1,10 +1,10 @@ -import { execFile } from "node:child_process"; +import { exec as execCb } from "node:child_process"; import { access } from "node:fs/promises"; import { join } from "node:path"; import { promisify } from "node:util"; import type { TestResult } from "../types.js"; -const exec = promisify(execFile); +const exec = promisify(execCb); const DEFAULT_TEST_TIMEOUT_MS = 120_000; @@ -65,7 +65,7 @@ export async function runTests( }; } - const { cmd, args } = parseTestCommand(testCmd); + const { cmd } = parseTestCommand(testCmd); if (!cmd) { return { @@ -88,12 +88,12 @@ export async function runTests( } try { - // Use execFile with shell:true for cross-platform command resolution - // while keeping args as an array to prevent injection via arguments. - const { stdout, stderr } = await exec(cmd, args, { + // Use exec (shell string) for cross-platform command resolution (npx, npm, etc.). + // Safety: testCmd is validated by validateTestCommand() which rejects shell operators. + // This avoids the DEP0190 deprecation from execFile + shell:true + args array. + const { stdout, stderr } = await exec(testCmd, { cwd: worktreePath, timeout: timeoutMs, - shell: true, env: { ...process.env, CI: "true" }, }); return { @@ -120,15 +120,6 @@ export async function runTests( }; } - if (typeof e.code === "string" && e.code === "ENOENT") { - return { - agentId, - passed: false, - output: `Command not found: ${cmd}. Is it installed?`, - exitCode: 127, - }; - } - return { agentId, passed: false,