fix(cli): preserve WSL cwd through the Windows bridge (#6965) (#7640)

* fix(cli): preserve WSL cwd through the Windows bridge (#6965)

# Conflicts:
#	src/cli/index.test.ts
#	src/cli/index.ts

* fix(cli): preserve bridge exit codes (#6965)

* fix(cli): harden WSL cwd bridge compatibility

* chore(cli): align cwd tests with main

* fix(cli): repair deleted WSL cwd before path conversion

* chore: preserve main formatting after merge

---------

Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
This commit is contained in:
Rod Boev
2026-07-13 15:44:32 -07:00
committed by GitHub
co-authored by Brennan Benson Brennan Benson
parent 53a09afbef
commit f90cd6ebc9
5 changed files with 110 additions and 28 deletions
+31 -2
View File
@@ -194,8 +194,15 @@ describe('WslCliInstaller', () => {
)
expect(wsl.getBridge()).toBe(_internals.buildWslBridgeScript())
const installCommand = wsl.calls.find((command) => command.includes('cat > "$command_tmp"'))
expect(installCommand).toBeDefined()
expect(installCommand).toContain("legacy_command_path='/home/alice/.local/bin/orca'")
expect(installCommand).toContain('rm -f "$legacy_command_path"')
// Why: the new bridge accepts the old launcher's positional arguments, so
// publishing it first keeps interrupted upgrades usable.
const bridgePublishIndex = installCommand?.indexOf('mv -f "$bridge_tmp"') ?? -1
const launcherPublishIndex = installCommand?.indexOf('mv -f "$command_tmp"') ?? -1
expect(bridgePublishIndex).toBeGreaterThan(-1)
expect(bridgePublishIndex).toBeLessThan(launcherPublishIndex)
expect(installCommand).toContain('[ ! -L "$legacy_command_path" ]')
})
@@ -296,12 +303,34 @@ describe('WslCliInstaller', () => {
'Orca WSL CLI requires Windows interop and could not find powershell.exe.'
)
expect(launcher).toContain('"$ORCA_POWERSHELL" -NoProfile -ExecutionPolicy Bypass -File')
expect(launcher).toContain('"$ORCA_WIN_LAUNCHER" "$@"')
expect(launcher).toContain('ORCA_WSL_CWD=$(pwd -P 2>/dev/null) || {')
expect(launcher).toContain('ORCA_WSL_CWD=/')
expect(launcher).toContain('cd /')
expect(launcher).toContain('ORCA_WSL_CWD_WIN=$(wslpath -w "$ORCA_WSL_CWD")')
expect(launcher.indexOf('ORCA_WSL_CWD=$(pwd -P')).toBeLessThan(
launcher.indexOf('ORCA_BRIDGE_PS1_WIN=$(wslpath')
)
expect(launcher).toContain('"$ORCA_WIN_LAUNCHER" -WslCwd "$ORCA_WSL_CWD_WIN" "$@"')
expect(launcher).not.toContain('-Command')
expect(bridge).toContain('[CmdletBinding(PositionalBinding=$false)]')
expect(bridge).toContain('[Parameter(Mandatory=$true, Position=0)]')
expect(bridge).toContain('[string]$WslCwd')
expect(bridge).toContain('[Parameter(ValueFromRemainingArguments=$true)]')
expect(bridge).toContain('if ([string]::IsNullOrEmpty($WslCwd))')
expect(bridge).toContain('$env:ORCA_CLI_CWD = $WslCwd')
expect(bridge).toContain('Push-Location -LiteralPath (Split-Path -Parent $OrcaLauncher)')
expect(bridge).toContain('& $OrcaLauncher @ForwardArgs')
const nullExitCodeBranch = bridge.indexOf('if ($null -eq $LASTEXITCODE)')
const invocationFailureBranch = bridge.indexOf('if (-not $?)')
expect(nullExitCodeBranch).toBeGreaterThan(-1)
// Why: native launchers can set a non-zero LASTEXITCODE while $? is false;
// checking the native status first preserves that specific exit code.
expect(nullExitCodeBranch).toBeLessThan(invocationFailureBranch)
expect(bridge).toContain('$exitCode = $LASTEXITCODE')
expect(bridge).toContain('Remove-Item Env:ORCA_CLI_CWD -ErrorAction SilentlyContinue')
expect(bridge).toContain('catch')
expect(bridge).toContain('exit 1')
expect(bridge).toContain('$exitCode = 1')
expect(bridge).toContain('exit $exitCode')
})
it('wraps WSL bash scripts as a single encoded command line', () => {
+28 -8
View File
@@ -20,34 +20,54 @@ else
echo "Orca WSL CLI requires Windows interop and could not find powershell.exe." >&2
exit 1
fi
# Why: a shell can outlive a deleted worktree; keep explicit CLI selectors and
# help usable, and repair cwd before any WSL interop tool tries to resolve it.
ORCA_WSL_CWD=$(pwd -P 2>/dev/null) || {
ORCA_WSL_CWD=/
cd /
}
ORCA_BRIDGE_PS1_WIN=$(wslpath -w "$ORCA_BRIDGE_PS1")
exec "$ORCA_POWERSHELL" -NoProfile -ExecutionPolicy Bypass -File "$ORCA_BRIDGE_PS1_WIN" "$ORCA_WIN_LAUNCHER" "$@"
ORCA_WSL_CWD_WIN=$(wslpath -w "$ORCA_WSL_CWD")
exec "$ORCA_POWERSHELL" -NoProfile -ExecutionPolicy Bypass -File "$ORCA_BRIDGE_PS1_WIN" "$ORCA_WIN_LAUNCHER" -WslCwd "$ORCA_WSL_CWD_WIN" "$@"
`
}
export function buildWslBridgeScript(): string {
return `${BRIDGE_MANAGED_MARKER}
[CmdletBinding(PositionalBinding=$false)]
param(
[Parameter(Mandatory=$true)]
[Parameter(Mandatory=$true, Position=0)]
[string]$OrcaLauncher,
[string]$WslCwd,
[Parameter(ValueFromRemainingArguments=$true)]
[string[]]$ForwardArgs
)
$exitCode = 0
try {
if ([string]::IsNullOrEmpty($WslCwd)) {
Remove-Item Env:ORCA_CLI_CWD -ErrorAction SilentlyContinue
} else {
$env:ORCA_CLI_CWD = $WslCwd
}
Push-Location -LiteralPath (Split-Path -Parent $OrcaLauncher)
& $OrcaLauncher @ForwardArgs
if (-not $?) {
exit 1
}
if ($null -eq $LASTEXITCODE) {
exit 0
if (-not $?) {
$exitCode = 1
} else {
$exitCode = 0
}
} else {
$exitCode = $LASTEXITCODE
}
exit $LASTEXITCODE
} catch {
Write-Error $_
exit 1
$exitCode = 1
}
exit $exitCode
`
}