fix: Windows: openclaw plugins install fails with spawn EINVAL

Fixes #7631
This commit is contained in:
0xlin2023
2026-03-06 23:01:52 +08:00
committed by Ayaan Zaidi
parent 6a9deb21b8
commit d000316d19
2 changed files with 22 additions and 1 deletions

View File

@@ -1,5 +1,6 @@
import type { ChildProcess } from "node:child_process";
import { EventEmitter } from "node:events";
import fs from "node:fs";
import process from "node:process";
import { describe, expect, it, vi } from "vitest";
import { attachChildProcessBridge } from "./child-process-bridge.js";
@@ -77,6 +78,20 @@ describe("runCommandWithTimeout", () => {
expect(result.stdout.trim()).toMatch(/^\d+\.\d+\.\d+$/);
},
);
it.runIf(process.platform === "win32")(
"falls back to npm.cmd when npm-cli.js is unavailable",
async () => {
const existsSpy = vi.spyOn(fs, "existsSync").mockReturnValue(false);
try {
const result = await runCommandWithTimeout(["npm", "--version"], { timeoutMs: 10_000 });
expect(result.code).toBe(0);
expect(result.stdout.trim()).toMatch(/^\d+\.\d+\.\d+$/);
} finally {
existsSpy.mockRestore();
}
},
);
});
describe("attachChildProcessBridge", () => {

View File

@@ -58,7 +58,13 @@ function resolveNpmArgvForWindows(argv: string[]): string[] | null {
const nodeDir = path.dirname(process.execPath);
const cliPath = path.join(nodeDir, "node_modules", "npm", "bin", cliName);
if (!fs.existsSync(cliPath)) {
return null;
// Bun-based runs don't ship npm-cli.js next to process.execPath.
// Fall back to npm.cmd/npx.cmd so we still route through cmd wrapper
// (avoids direct .cmd spawn EINVAL on patched Node).
const command = argv[0] ?? "";
const ext = path.extname(command).toLowerCase();
const shimmedCommand = ext ? command : `${command}.cmd`;
return [shimmedCommand, ...argv.slice(1)];
}
return [process.execPath, cliPath, ...argv.slice(1)];
}