From 7dad7809c4764768fb30603704dc938134286688 Mon Sep 17 00:00:00 2001 From: ZETA <126369952+zeta987@users.noreply.github.com> Date: Tue, 31 Mar 2026 16:03:45 +0800 Subject: [PATCH 1/2] fix: make test suite portable across platforms Replace hardcoded macOS path with fileURLToPath for cross-platform compatibility. Add .cmd wrapper creation and platform-aware PATH separator in test fixtures so the fake codex binary is discoverable on Windows. Add shell and windowsHide options to the test helper run() function to match production behavior. Test results on Windows improve from 12/64 pass to 59/64 pass. Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/commands.test.mjs | 3 ++- tests/fake-codex-fixture.mjs | 12 +++++++++++- tests/helpers.mjs | 5 ++++- tests/runtime.test.mjs | 3 ++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/tests/commands.test.mjs b/tests/commands.test.mjs index a00e8dd..62bea9b 100644 --- a/tests/commands.test.mjs +++ b/tests/commands.test.mjs @@ -2,8 +2,9 @@ import fs from "node:fs"; import path from "node:path"; import test from "node:test"; import assert from "node:assert/strict"; +import { fileURLToPath } from "node:url"; -const ROOT = "/Users/dkundel/code/codex-plugin"; +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const PLUGIN_ROOT = path.join(ROOT, "plugins", "codex"); function read(relativePath) { diff --git a/tests/fake-codex-fixture.mjs b/tests/fake-codex-fixture.mjs index ac7f084..a85fd31 100644 --- a/tests/fake-codex-fixture.mjs +++ b/tests/fake-codex-fixture.mjs @@ -1,4 +1,6 @@ +import fs from "node:fs"; import path from "node:path"; +import process from "node:process"; import { writeExecutable } from "./helpers.mjs"; @@ -507,11 +509,19 @@ rl.on("line", (line) => { }); `; writeExecutable(scriptPath, source); + + // On Windows, npm global binaries are invoked via .cmd wrappers. + // Create a codex.cmd so the fake binary is discoverable by spawn with shell: true. + if (process.platform === "win32") { + const cmdWrapper = `@echo off\r\nnode "%~dp0codex" %*\r\n`; + fs.writeFileSync(path.join(binDir, "codex.cmd"), cmdWrapper, { encoding: "utf8" }); + } } export function buildEnv(binDir) { + const sep = process.platform === "win32" ? ";" : ":"; return { ...process.env, - PATH: `${binDir}:${process.env.PATH}` + PATH: `${binDir}${sep}${process.env.PATH}` }; } diff --git a/tests/helpers.mjs b/tests/helpers.mjs index 799fe3c..4331353 100644 --- a/tests/helpers.mjs +++ b/tests/helpers.mjs @@ -1,6 +1,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import process from "node:process"; import { spawnSync } from "node:child_process"; export function makeTempDir(prefix = "codex-plugin-test-") { @@ -16,7 +17,9 @@ export function run(command, args, options = {}) { cwd: options.cwd, env: options.env, encoding: "utf8", - input: options.input + input: options.input, + shell: process.platform === "win32", + windowsHide: true }); } diff --git a/tests/runtime.test.mjs b/tests/runtime.test.mjs index 43ed17c..56ba6c1 100644 --- a/tests/runtime.test.mjs +++ b/tests/runtime.test.mjs @@ -3,13 +3,14 @@ import path from "node:path"; import test from "node:test"; import assert from "node:assert/strict"; import { spawn } from "node:child_process"; +import { fileURLToPath } from "node:url"; import { buildEnv, installFakeCodex } from "./fake-codex-fixture.mjs"; import { initGitRepo, makeTempDir, run } from "./helpers.mjs"; import { loadBrokerSession } from "../plugins/codex/scripts/lib/broker-lifecycle.mjs"; import { resolveStateDir } from "../plugins/codex/scripts/lib/state.mjs"; -const ROOT = "/Users/dkundel/code/codex-plugin"; +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const PLUGIN_ROOT = path.join(ROOT, "plugins", "codex"); const SCRIPT = path.join(PLUGIN_ROOT, "scripts", "codex-companion.mjs"); const STOP_HOOK = path.join(PLUGIN_ROOT, "scripts", "stop-review-gate-hook.mjs"); From 0eb04378a9bd1813eed66be20819a57f961deb2e Mon Sep 17 00:00:00 2001 From: ZETA <126369952+zeta987@users.noreply.github.com> Date: Tue, 31 Mar 2026 17:31:42 +0800 Subject: [PATCH 2/2] fix: skip shell for absolute-path commands to avoid Windows space-in-path breakage When `process.execPath` resolves to a path with spaces (e.g., `C:\Program Files\nodejs\node.exe`), `shell: true` causes cmd.exe to split the path at the space. Guard with `path.isAbsolute()` so only bare command names (which need `.cmd` shim resolution) use the shell. Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/helpers.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/helpers.mjs b/tests/helpers.mjs index 4331353..945ae0e 100644 --- a/tests/helpers.mjs +++ b/tests/helpers.mjs @@ -18,7 +18,7 @@ export function run(command, args, options = {}) { env: options.env, encoding: "utf8", input: options.input, - shell: process.platform === "win32", + shell: process.platform === "win32" && !path.isAbsolute(command), windowsHide: true }); }