Skip to content

fix(windows): prefer real executables over .cmd shims when resolving coding-agent CLIs - #7595

Closed
OrangerXu wants to merge 2 commits into
lidge-jun:devfrom
OrangerXu:fix/cmd-shim-empty-args
Closed

OrangerXu wants to merge 2 commits into
lidge-jun:devfrom
OrangerXu:fix/cmd-shim-empty-args

Conversation

@OrangerXu

@OrangerXu OrangerXu commented Oct 23, 2026 •

Copy link
Copy Markdown

Fixes #7518.

What

  • whichFromPath (Windows) now scans the entire PATH for a real .exe before falling back to any .cmd/.bat. Previously the first match won per directory with .cmd tried first, so a dispatcher shim anywhere ahead of the executable routed the spawn through cmd.exe /d /s /c — and an empty-string argument does not survive that hop (the shim body forwards via powershell.exe -- %*, where it is lost again). The CLI then reads the next flag as the empty argument's value. This is the resolution-level fix the issue prefers: it fixes the whole class, not just qoder, and keeps argument boundaries intact with no cmd.exe hop at all.
  • The Qoder CN profile tries qoderclicn (the real executable) before qodercn (the installer's .cmd dispatcher). They live in different directories (entry\qodercn.cmd vs bin\qoderclicn\qoderclicn.exe), so PATH-wide .exe preference alone cannot reach it — the profile has to name it first. The issue's control experiment B shows re-quoting alone cannot fix this, so both changes are needed.

Why both

With the old resolution, the qoder adapter's deliberate --setting-sources "" (and --tools "") were lost and every qoder-cn turn aborted with Invalid setting source: "--max-turns" before contacting any model.

Tests

New tests/adapters/coding-agent-binary-resolution.test.ts (real temp dirs on PATH, Windows-only, skipped elsewhere): same-directory .exe beats .cmd; an .exe further down the PATH beats an earlier .cmd; a lone .cmd and a lone .bat still resolve. Plus a profile-order assertion. The existing qoder suite's isolation test now expects ["qoderclicn", "qodercn"] — qoder-adapter.test.ts 116/116, qoder-spawn-readmission 3/3, qoder-live-models all green locally.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • Required local validation passed; commands, results, and any full-suite exception are documented.

  • I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Bug Fixes
    • Windows command discovery now checks for .exe files across PATH before resolving .cmd, .bat, or extensionless entries. Script-based commands remain available when no .exe is found.
    • Qoder CN now tries qoderclicn before qodercn, improving command selection when launching the adapter.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Oct 23, 2026
@github-actions github-actions Bot changed the title fix(windows): prefer real executables over .cmd shims when resolving coding-agent CLIs [WRONG BRANCH] fix(windows): prefer real executables over .cmd shims when resolving coding-agent CLIs Oct 23, 2026
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • review readiness checklist open (0/4 boxes ticked).

What to do

  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ Required local validation passed; commands, results, and any full-suite exception are documented.
  • ⬜ I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

This PR stays in draft until every box above is ticked.

@github-actions
github-actions Bot marked this pull request as draft October 23, 2026 05:56
@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@OrangerXu
OrangerXu changed the base branch from main to dev October 23, 2026 05:59
@github-actions github-actions Bot changed the title [WRONG BRANCH] fix(windows): prefer real executables over .cmd shims when resolving coding-agent CLIs fix(windows): prefer real executables over .cmd shims when resolving coding-agent CLIs Oct 23, 2026
@OrangerXu OrangerXu closed this Oct 23, 2026
@OrangerXu
OrangerXu force-pushed the fix/cmd-shim-empty-args branch from 5d287fb to c51b0b4 Compare October 23, 2026 06:00
…coding-agent CLIs

A .cmd dispatcher forwards through cmd.exe (and often PowerShell), and an
empty-string argument does not survive that hop: the CLI reads the next
flag as the empty argument's value. For the qoder CN adapter that was
fatal -- '--setting-sources ""' became '--setting-sources --max-turns'
and every turn died with 'Invalid setting source: "--max-turns"' on the
official installer layout, where qodercn resolves to the .cmd dispatcher.

whichFromPath now scans the whole PATH for an .exe before falling back to
any .cmd/.bat, and the Qoder CN profile tries the real qoderclicn
executable before the qodercn dispatcher (they live in different
directories, so PATH order alone cannot prefer the executable).

Fixes lidge-jun#7518
@OrangerXu OrangerXu reopened this Oct 23, 2026

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This overlaps the already-open fix #7527 for #7518; please compare against its current head 89b25a7ba1 before continuing an independent resolver change. That PR prefers a native executable across a profile's candidate names, preserves PATH directory precedence, and refuses an unverified batch-only forwarding chain. It also has real Windows native-argv controls.

Two changes are needed in this draft at 4db7da31402c1bf380ddb49fff85dbfd9c71cd66:

  1. tests/adapters/coding-agent-binary-resolution.test.ts is new, but neither the test-layout map nor the expected-layout fixture is changed. Register it in both current owners as required by AGENTS.md, or reuse the canonical fix's existing tests if this contribution is superseded. The changed source area's structure contract also needs to be reviewed/updated in the same patch.
  2. whichFromPath now lets a later PATH directory's executable override an earlier directory's same-name wrapper. That changes command-selection semantics for every coding-agent profile, beyond preferring .exe beside its shim. Explain/obtain agreement on that policy difference from #7527; fixture success for the new preference does not establish compatibility with deliberately selected earlier wrappers. A dispatcher-only install still runs without inspecting whether it drops the required empty arguments, so the original failure class also remains for that supported fallback.

Please keep this Draft and converge the scope/ownership with #7527 rather than landing two competing resolver contracts. I have not run native Windows tests or certified a live Qoder installation. This review does not authorize such a run or take over your branch.

@lidge-jun

Copy link
Copy Markdown
Owner

Triage note (2026-10-24, against dev at 2494848).

Superseded: by #7527 / 9534c0c94b; its cross-directory precedence also contradicts dev’s documented contract at src/adapters/coding-agent/profile.ts:78.

Still needed on dev: no — #7527, commit 9534c0c94b, already implements native-candidate preference and dispatcher safeguards. See src/adapters/coding-agent/profile.ts:107 and src/adapters/coding-agent/turn.ts:312.

Exact-head CI at triage time: 4db7da3 — reported checks pass; Cross-platform CI, Catalog async contracts and React Doctor are action_required. lane=all on exact head: no.

A maintainer will decide on closing this; no action needed from you.

@lidge-jun

Copy link
Copy Markdown
Owner

Closing as superseded by #7527 (9534c0c94b), which already prefers native executables over .cmd shims (src/adapters/coding-agent/profile.ts:107, dispatcher safeguards at src/adapters/coding-agent/turn.ts:312). The cross-directory precedence proposed here would contradict the documented contract at src/adapters/coding-agent/profile.ts:78. Thank you for the report and patch, @OrangerXu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug][Windows]: .cmd-resolved CLIs lose empty-string args — qoder setting-sources swallows max-turns, every turn fails with Invalid setting source

3 participants