import { spawn } from "node:child_process"; function formatSpawnError(error: Error & { code?: unknown }): string { const code = typeof error.code === "string" ? `${error.code}: ` : ""; return `spawn error: ${code}${error.message}`.trim(); } export async function runOmpCommand( binary: string, args: string[], timeoutMs: number, ): Promise<{ code: number | null; stdout: string; stderr: string }> { return new Promise((resolve) => { let stdout = ""; let stderr = ""; let settled = false; let timer: NodeJS.Timeout | undefined; const finish = (result: { code: number | null; stdout: string; stderr: string }) => { if (settled) return; settled = true; if (timer) clearTimeout(timer); resolve(result); }; /* FNXC:OmpAcp 2026-07-11-23:35: Windows installers/npm-style shims can expose `omp.cmd` or `omp.bat` on PATH; Node cannot direct-spawn those batch wrappers without the command shell. Keep Unix/macOS on direct spawn. */ const child = spawn(binary, args, { stdio: ["ignore", "pipe", "pipe"], shell: process.platform === "win32", }); timer = setTimeout(() => { try { child.kill("SIGKILL"); } catch { // best effort } finish({ code: 124, stdout, stderr }); }, timeoutMs); child.stdout?.on("data", (c: Buffer) => { stdout += c.toString("utf-8"); }); child.stderr?.on("data", (c: Buffer) => { stderr += c.toString("utf-8"); }); child.once("error", (error: Error & { code?: unknown }) => { const diagnostic = formatSpawnError(error); stderr = stderr ? `${stderr}\n${diagnostic}` : diagnostic; finish({ code: 127, stdout, stderr }); }); child.once("close", (code) => { finish({ code, stdout, stderr }); }); }); }