Skip to content

Fix Windows CLI bridge for cmd launchers#64

Closed
Keesan12 wants to merge 5 commits into
mainfrom
codex/windows-cli-bridge-fix
Closed

Fix Windows CLI bridge for cmd launchers#64
Keesan12 wants to merge 5 commits into
mainfrom
codex/windows-cli-bridge-fix

Conversation

@Keesan12
Copy link
Copy Markdown
Owner

Summary

  • fix Windows CLI bridge handling for .cmd and .bat launchers by resolving them correctly and invoking them through cmd.exe with verbatim arguments
  • use a working call "<tool>.cmd" ... wrapper so MartinLoop can launch Codex and similar Windows shims from governed runs
  • add regression coverage for absolute Windows launcher paths and non-wrapper executables

Verification

  • pnpm --filter @martin/adapters test -- --run tests/claude-cli.test.ts
  • pnpm --filter @martin/adapters lint
  • pnpm build
  • pnpm lint
  • pnpm oss:validate
  • pnpm --filter @martinloop/mcp verify:release
  • live local verification from the built public CLI: a governed --engine codex run against the seeded demo workspace now gets past the original Windows launcher failure and reaches downstream runtime behavior

Notes

  • pnpm test is still intermittently timing out on one existing Windows rollback test in packages/core/tests/runtime.test.ts under full-suite load on this machine. The same test passes in isolation, so I left that unrelated instability out of this PR.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for windowsVerbatimArguments when spawning subprocesses on Windows, and refactors createSpawnPlan to accept a mockable runtime for improved testability. It also adds corresponding unit tests. The reviewer pointed out that using the call command to execute batch files via cmd.exe introduces issues with double-parsing, specifically affecting variable expansion and caret escaping. They suggested wrapping the entire command string in an extra pair of double quotes instead of using call, and provided suggestions to update both the implementation and the test assertions accordingly.

command: process.env.ComSpec || "cmd.exe",
args: ["/d", "/s", "/c", [quoteWindowsCmdArg(resolved), ...args.map(quoteWindowsCmdArg)].join(" ")]
command: runtime.comSpec ?? process.env.ComSpec ?? "cmd.exe",
args: ["/d", "/s", "/c", ["call", quoteWindowsCmdArg(resolved), ...args.map(quoteWindowsCmdArg)].join(" ")],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using call to execute batch files via cmd.exe introduces two major issues with argument parsing:

  1. Variable Expansion: call performs an extra round of variable expansion. If any argument contains % (e.g., %VAR% or %1), cmd.exe will attempt to expand it as a batch variable, which can lead to unexpected behavior or security issues if the arguments contain user-controlled input.
  2. Caret Escaping: call parses carets (^) twice, which can strip or corrupt arguments containing carets.

Instead of using call, the standard and robust way to prevent cmd.exe from stripping quotes under /s is to wrap the entire command string in an extra pair of double quotes (e.g., cmd.exe /d /s /c ""path\to\tool.cmd" "arg1" "arg2""). This avoids the second parsing pass entirely, making argument passing much more reliable and predictable.

Suggested change
args: ["/d", "/s", "/c", ["call", quoteWindowsCmdArg(resolved), ...args.map(quoteWindowsCmdArg)].join(" ")],
args: ["/d", "/s", "/c", '"' + [quoteWindowsCmdArg(resolved), ...args.map(quoteWindowsCmdArg)].join(' ') + '"'],

Comment on lines +398 to +403
args: [
"/d",
"/s",
"/c",
"call \"C:\\Users\\example\\AppData\\Roaming\\npm\\codex.cmd\" \"exec\" \"--color\" \"never\" \"-\""
],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Update the test expectation to match the robust double-quoted command string format instead of the call wrapper.

Suggested change
args: [
"/d",
"/s",
"/c",
"call \"C:\\Users\\example\\AppData\\Roaming\\npm\\codex.cmd\" \"exec\" \"--color\" \"never\" \"-\""
],
args: [
"/d",
"/s",
"/c",
"\"\"C:\\Users\\example\\AppData\\Roaming\\npm\\codex.cmd\" \"exec\" \"--color\" \"never\" \"-\"\""
],

@Keesan12
Copy link
Copy Markdown
Owner Author

Superseded by the clean 0.2.6 release path in #68 and the post-ship follow-up in #69.

@Keesan12 Keesan12 closed this May 27, 2026
@Keesan12 Keesan12 deleted the codex/windows-cli-bridge-fix branch May 27, 2026 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant