Conversation
…ile hop On win32, a resolved mcode.cmd currently prefers the sibling mcode.ps1 via powershell -NoProfile -File, then falls back to dirname(cmd)/node_modules. Two field failure modes on real installs (anonymized deployment report): - PowerShell 5.1 binds flag-shaped tokens (-input, --cwd, ...) as its own named parameters under -File, breaking the exec argv entirely - with the .ps1 renamed away, the fallback accepts whatever cli.js sits next to the PATH shim; when an old install (0.2.x) provides that shim while a newer official install exists, resolution silently picks the stale entry, which lacks current exec flags Resolution now prefers a directly spawnable node entry, picking the NEWEST cli.js across the candidate layouts (shim sibling, official lib/node_modules, official root node_modules) by package version; the powershell -File hop remains only as a documented last resort when no node entry exists anywhere. POSIX resolution is unchanged. checks/win-launcher.check.mjs covers the mixed-install matrix by faking the win32 layout + PATH/PATHEXT from POSIX (resolution is pure filesystem probing); real-Windows behavior is exercised by the repository's windows CI job.
…wsh first From a full field debugging report on a real Windows deployment (anonymized): - executablePath probed the empty PATHEXT extension first for bare names, resolving mcode to the extensionless POSIX shim shipped beside mcode.cmd — spawn then fails with ENOENT. Bare names now match PATHEXT variants only; commands that already carry an extension (pwsh.exe) still probe directly. - the candidate pool for the node entry now includes the staged-installer layout releases/<version>/node_modules/@minimax-ai/code/cli.js — the same entry .mcode-launcher.cmd targets. A stale flat node_modules (0.2.x) beside a current releases/<v> now loses the version comparison instead of winning by proximity. - the last-resort PowerShell hop prefers pwsh.exe (PS7): PS 5.1 binds flag-shaped argv as its own named parameters under -File and does not forward piped stdin through the nested invocation (field-verified pair)
|
Substantially expanded after receiving the reporter's full field debugging notes (Windows 11 / PowerShell 5.1 + pwsh 7.6.6 / Node 26 / mcode 0.4.12; identities sanitized). Their four findings, mapped to this PR:
New regressions reproduce the reporter's exact on-disk layout from POSIX (extensionless shim + mcode.cmd + ps1 + stale flat node_modules + releases/0.4.12): red 3/3 on the previous head, green after. Suite now 10/10 launcher tests, 92/92 plugin-wide, packaged smoke 1/1, byte-reproducible rebuild. The reporter also supplied maintainer-runnable repro commands for the PS 5.1/PS7 pair and the direct |
The field-layout test probed mcode.CMD (uppercase PATHEXT) against a lowercase mcode.cmd fixture — Windows filesystems are case-insensitive so the behavior is fine in production, but the Linux CI runner simulating win32 is case-sensitive and resolution returned null. PATHEXT in the test now matches the fixture files; assertion gains an explicit non-null guard.
hetaoBackend
left a comment
There was a problem hiding this comment.
Request changes for exact current head 67980640498827fd2f7feec688127eb79e2ca4f4.
Two Windows-launcher correctness/evidence blockers remain:
-
The resolver does not follow the authoritative active release.
src/mcode-location.mjs:53-70enumerates everyreleases/*directory and chooses the numerically largest parsed package version. It never resolves a launcher/current pointer, and theparseIntcomparison does not implement SemVer or define stable-versus-prerelease/tie behavior. A retained beta/newer directory or rollback can therefore select a different CLI from the release the installed launcher would run.checks/win-launcher.check.mjs:103-112currently locks in highest-numeric-directory behavior rather than testing the active release contract. Resolve the authoritative active target, or document and implement a complete version/channel/tie policy with rollback tests. -
The Windows-specific test is not run on Windows.
checks/win-launcher.check.mjs:5-9says real Windows behavior is covered by repository CI, but.github/workflows/dynamic-workflow.yml:37-48runs onlychecks/process-tree.check.mjsin the Windows job. The launcher suite currently runs under POSIX while merely injectingplatform: win32, so it does not exercise Windows path, PATHEXT, filesystem, or spawn semantics. Runwin-launcher.check.mjsin the Windows job and preferably add an end-to-end fakecli.jsspawn with spaces and flag-shaped argv.
I confirmed the good parts: .cmd and PATHEXT probing, npm-prefix layout, separated argv with shell:false, PowerShell fallback only when no Node entry is found, source/dist sync, and the existing exact-head CI are sound. [code]smith is skipped and was not used as evidence.
What changes
Fixes Windows mcode launcher resolution in
mcode-location.mjs— two failure modes observed on a real Windows deployment (details anonymized; a user's debugging session was shared with us verbatim):-Filehop. A resolvedmcode.cmdwith a siblingmcode.ps1is invoked aspowershell -NoProfile -File mcode.ps1 exec --input - --cwd .... Under-File, PowerShell binds flag-shaped tokens (-input,--cwd,--timeout …) as its own named parameters, so the exec argv never reaches the CLI — parameter-binding errors on every invocation. (The user's attempted--%stop-parsing cannot help: it affects interactive command lines, not-Fileargument passing.).ps1renamed away (the user's workaround), resolution falls back todirname(mcode.cmd)/node_modules/@minimax-ai/code/cli.js— the npm-global layout, whichever version sits there. On a machine with an old install (0.2.x, missing current exec flags) providing the PATH shim while a newer official install exists, resolution silently picked the 0.2.x entry and every exec call died on an unknown flag. The user eventually junction-linked the newcli.jsinto the expected path — a workaround this PR makes unnecessary.The fix
.ps1hop: collect candidatecli.jslocations (shim siblingnode_modules, officiallib/node_modules, official rootnode_modules) and pick the newest by package version — mixed installs resolve to the freshest CLI regardless of which install owns the PATH shim.powershell -Filehop remains only as a documented last resort when no node entry exists in any layout.Test evidence
checks/win-launcher.check.mjs(7 tests): the mixed-install matrix is reproduced from POSIX by faking the win32 on-disk layout and passingplatform:'win32'+ controlledPATH/PATHEXT(resolution is pure filesystem probing): ps1-present-with-old-sibling + newer official → direct node entry of the newest; ps1 renamed + stale sibling → newest official, never the stale one; newest-wins regardless of origin; single npm layout; ps1 last resort preserved (with-NoProfile,-File,<launcher>argv pinned); no-entry error message preserved; POSIX unchanged.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.