fix(discovery): spawn PowerShell install commands natively on Windows#2750
Merged
Conversation
Codex's CLI installer (powershell.exe … irm … | iex) was routed through Git Bash (-l -c), which prepends POSIX dirs to PATH. Inside the PowerShell script, bare `tar` resolved to Git's GNU tar (/usr/bin/tar) instead of Windows bsdtar. GNU tar parses the drive letter in C:\… as a remote host → "Cannot connect to C: resolve failed" → empty extraction → "did not contain the expected package layout". Add is_powershell_command() to detect commands beginning with powershell.exe (case-insensitive) and install_powershell_command() to spawn them natively without the Git Bash wrapper. -Command body is located by a case-insensitive substring search and passed as a single argument so pipes and spaces inside the script are preserved exactly. build_install_command() routes on this predicate; non-PowerShell commands (npm install -g … adapter steps) keep the existing Git Bash path unchanged. All env cleanup (NPM_CONFIG_*, COREPACK_HOME), PATH composition (managed Buzz dirs + inherited), and CREATE_NO_WINDOW are preserved. No login-shell PATH is composed for the native spawn because login_shell_path() is always None on Windows and POSIX-shaped entries must not reach native children. Tests: is_powershell_command detection, build_install_command routing (PS→powershell.exe, non-PS→bash on Windows; always shell on Unix), -Command body preservation (flags forwarded, pipe in single arg). Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…shared helpers - install_powershell_command: find -Command on token boundary (not substring), strip one outer double-quote pair from the body (catalog serialization artifact), so PowerShell receives the bare pipeline instead of a string expression - Extract apply_npm_env / apply_no_window to eliminate duplication between install_shell_command and install_powershell_command - Replace loose contains-checks with exact argv assertions in three tests: test_powershell_command_argv_exact, test_powershell_command_token_boundary_not_substring, test_powershell_command_claude_catalog_dequoted Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On Windows,
install_shell_commandwraps every install command in Git Bash-l -c, including the Windows-specificpowershell.exe … irm https://chatgpt.com/codex/install.ps1 | iexcommand. A Git Bash login shell prepends its POSIX dirs (C:\Program Files\Git\usr\bin) to PATH, so when Codex'sinstall.ps1shells out to baretar -xzf C:\…, it resolves Git's GNU tar (/usr/bin/tar) instead of Windows bundled bsdtar. GNU tar parsesC:as a remote host:Claude's installer doesn't hit the same failure because it doesn't shell out to
tar.Solution
On Windows, detect
powershell.exeinstall commands and spawn them natively (Command::new("powershell.exe")) instead of routing them through Git Bash. The discriminator is a case-insensitive prefix check on the first whitespace-delimited token — minimal and precise.The native spawn preserves everything
install_shell_commandprovides that applies:NPM_CONFIG_*/COREPACKenv strip + managed npm prefix envCREATE_NO_WINDOWso no console flashrun_install_commandThe
-Commandbody is split correctly at the boundary (case-insensitive) and passed as a single argument to preserve pipes and spaces inside the installer script call.Non-PowerShell commands (e.g.
npm install -g …adapter steps) continue through the existing Git Bash path unchanged.Tests
6 unit tests:
is_powershell_commanddetection (positive + negative)-Commandbody preservation (no bash args in native spawn; body is single arg)Full
just desktop-tauri-testsuite: 1627/1627 passing. Windows CI will validate end-to-end.