Files
openclaw/src/plugin-sdk/windows-spawn.test.ts
Andy Ye 03125c8e13 Validate Codex app-server command overrides (#84417)
Summary:
- The PR rejects Codex app-server command overrides that embed Node/package-manager inline arguments, adds matching doctor diagnostics, regression tests, and a changelog entry.
- Reproducibility: yes. for the scoped malformed override path: current main passes the combined command strin ... ix resolver/doctor live output. I did not establish a live Windows npm-global managed-startup reproduction.

Automerge notes:
- PR branch already contained follow-up commit before automerge: Validate Codex app-server command overrides

Validation:
- ClawSweeper review passed for head 966bcd6617.
- Required merge gates passed before the squash merge.

Prepared head SHA: 966bcd6617
Review: https://github.com/openclaw/openclaw/pull/84417#issuecomment-4494295224

Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
2026-05-22 05:39:02 +00:00

80 lines
2.6 KiB
TypeScript

import { writeFile } from "node:fs/promises";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { createPluginSdkTestHarness } from "./test-helpers.js";
import { materializeWindowsSpawnProgram, resolveWindowsSpawnProgram } from "./windows-spawn.js";
const { createTempDir } = createPluginSdkTestHarness({
cleanup: {
maxRetries: 8,
retryDelay: 8,
},
});
describe("resolveWindowsSpawnProgram", () => {
it("rejects node command strings that include inline entrypoint arguments on Windows", () => {
expect(() =>
resolveWindowsSpawnProgram({
command: "node C:\\Users\\me\\.openclaw\\npm\\node_modules\\@openai\\codex\\bin\\codex.js",
platform: "win32",
env: {},
execPath: "C:\\node\\node.exe",
}),
).toThrow("Windows spawn command must be an executable path only");
});
it("allows executable paths with spaces on Windows", () => {
const resolved = resolveWindowsSpawnProgram({
command: "C:\\Program Files\\OpenAI Codex\\codex.exe",
platform: "win32",
env: {},
execPath: "C:\\node\\node.exe",
});
expect(resolved).toEqual({
command: "C:\\Program Files\\OpenAI Codex\\codex.exe",
leadingArgv: [],
resolution: "direct",
windowsHide: undefined,
});
});
it("fails closed by default for unresolved windows wrappers", async () => {
const dir = await createTempDir("openclaw-windows-spawn-test-");
const shimPath = path.join(dir, "wrapper.cmd");
await writeFile(shimPath, "@ECHO off\r\necho wrapper\r\n", "utf8");
expect(() =>
resolveWindowsSpawnProgram({
command: shimPath,
platform: "win32",
env: { PATH: dir, PATHEXT: ".CMD;.EXE;.BAT" },
execPath: "C:\\node\\node.exe",
}),
).toThrow(/without shell execution/);
});
it("only returns shell fallback when explicitly opted in", async () => {
const dir = await createTempDir("openclaw-windows-spawn-test-");
const shimPath = path.join(dir, "wrapper.cmd");
await writeFile(shimPath, "@ECHO off\r\necho wrapper\r\n", "utf8");
const resolved = resolveWindowsSpawnProgram({
command: shimPath,
platform: "win32",
env: { PATH: dir, PATHEXT: ".CMD;.EXE;.BAT" },
execPath: "C:\\node\\node.exe",
allowShellFallback: true,
});
const invocation = materializeWindowsSpawnProgram(resolved, ["--cwd", "C:\\safe & calc.exe"]);
expect(invocation).toEqual({
command: shimPath,
argv: ["--cwd", "C:\\safe & calc.exe"],
resolution: "shell-fallback",
shell: true,
windowsHide: undefined,
});
});
});