fix(windows): avoid unspawnable Deep Scan launchers - #367
Conversation
ting-hong-shieh
left a comment
There was a problem hiding this comment.
I validated exact head 8eb9493d and a conflict-resolved replay of its single commit onto current main at 216212b7.
The exact head passes the three focused launcher tests (11 assertions), generated-model check, TypeScript check, build, Prettier, and whitespace check. The replay passes the four focused launcher tests inherited from the PR and current main (15 assertions), generated-model check, TypeScript check, build, Prettier, and whitespace check.
The replay also exposes one relative-path regression that the existing tests do not cover. The inline note includes the reproduction and a tested fix direction. These were local unit and static checks on macOS; I did not run a native Windows process or use credentials or an external API.
| ): string { | ||
| const configured = environmentValue(environment, "CODEX_CLI_PATH"); | ||
| if (configured !== undefined && isSpawnableCodexPath(configured, platform)) { | ||
| return configured; |
There was a problem hiding this comment.
Please preserve current main's absolute-path normalization when resolving this conflict. pluginExecutionEnvironment() now delegates to resolveCodexCommand(environment), which turns a relative CODEX_CLI_PATH into an absolute path before passing it to a nested worker. This helper instead returns the trimmed relative value unchanged on non-Windows platforms, and does the same for a relative .exe or .com path on Windows. The worker can then resolve that value from a different working directory and fail to launch Codex.
On the conflict-resolved replay at 216212b7, resolveNestedCodexPath({ CODEX_CLI_PATH: "./bin/codex" }, "linux") returned "./bin/codex" instead of resolve("./bin/codex"). Normalizing an accepted override with the platform-specific path resolver made this reproduction and all four focused launcher tests pass. Please retain that normalization and add relative-path coverage for accepted non-Windows and Windows executables.
Summary
CODEX_CLI_PATHat the nested Deep Scan MCP environment boundary..cmdshims that require a shell, and protectedWindowsAppsbinaries.resolveCodexCommand()platform-binary resolver instead of adding another launcher resolver.Root cause
Deep Scan workers inherit
CODEX_CLI_PATHthrough the plugin MCP environment. Before this change, any non-empty value bypassed the canonical npm platform-binary resolver. On Windows that value can be the extensionless npm shim or a protected MSIXWindowsAppsexecutable;CodexExecpasses it directly tochild_process.spawnwithout a shell, which can fail withspawn EPERMeven when the installed@openai/codexplatform package contains a valid executable.This keeps case-insensitive Windows environment propagation intact, preserves explicit spawnable
.exe/.comlaunchers, and uses the existing bundled platform executable when the inherited value cannot be launched.Related: CLI-18410, codex#35872.
Validation
bun test tests-ts/runtime.test.ts --test-name-pattern 'bundled Codex through|explicit Codex executable override|spawnable Windows'— 3 passedpnpm run typespnpm run buildpnpm run formatpnpm pack --pack-destination ../../distpnpm run test:package— validated the installed package and a nested worker without globalcodexThe full
runtime.test.tsmodule was also attempted, but this host reports/and/homeas UID 65534, so 24 unrelated trusted-owner tests fail closed. The launcher-focused tests and package smoke pass without weakening those checks.