From dbebbeddfce2a74791cfed8e273614d7dc5a487f Mon Sep 17 00:00:00 2001 From: Dustin <204417361+Koraji95-coder@users.noreply.github.com> Date: Sat, 23 May 2026 16:20:33 -0500 Subject: [PATCH] fix(start.ps1): handle WOW64 ProgramFiles redirection in candidate discovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surfaced by smoke-testing this PR on a fresh foundry-side checkout. PowerShell sometimes runs as a 32-bit (WOW64) process on 64-bit Windows — e.g., from certain shell-chain configurations (Git Bash → pwsh through specific launchers, or some 32-bit IDE-spawned shells). In that mode `$env:ProgramFiles` is redirected to `C:\Program Files (x86)` by Windows, so the existing two-entry loop: foreach ($root in @($env:LOCALAPPDATA, ${env:ProgramFiles}, ${env:ProgramFiles(x86)})) produced TWO identical `C:\Program Files (x86)\hermes\hermes-agent` candidates AND silently missed the real `C:\Program Files\hermes\hermes-agent` where MSI-installed hermes-agent actually lives. Two changes: 1. Add `${env:ProgramW6432}` to the loop. ProgramW6432 is the canonical override that Windows guarantees points at the 64-bit Program Files regardless of process bitness. On a native 64-bit process, it equals `$env:ProgramFiles` (so we may pick up a duplicate, handled below). On a WOW64 process, it's the only way to reach `C:\Program Files`. 2. Add `$candidates = $candidates | Select-Object -Unique` after the list is built. Collapses any same-path collisions regardless of which env-var combination caused them — defensive against future env-var weirdness too (constrained sandboxes, custom Windows builds). Verified end-to-end: - BEFORE the fix, smoke test on a WOW64 pwsh 7.5.4 showed candidates 3 + 4 both = `C:\Program Files (x86)\hermes\hermes-agent`. Real `C:\Program Files` never checked. - AFTER the fix, same shell shows 5 distinct candidates: USERPROFILE, LOCALAPPDATA, ProgramW6432 (`C:\Program Files`), ProgramFiles(x86), sibling. Co-Authored-By: Claude Opus 4.7 (1M context) --- start.ps1 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/start.ps1 b/start.ps1 index 619c37f2..af61f14b 100644 --- a/start.ps1 +++ b/start.ps1 @@ -103,10 +103,16 @@ if (-not $AgentDir) { # stays unguarded; the dev-checkout sibling is path-derived, not env-based. $candidates = @() $candidates += (Join-Path $env:USERPROFILE '.hermes\hermes-agent') - foreach ($root in @($env:LOCALAPPDATA, ${env:ProgramFiles}, ${env:ProgramFiles(x86)})) { + foreach ($root in @($env:LOCALAPPDATA, ${env:ProgramW6432}, ${env:ProgramFiles}, ${env:ProgramFiles(x86)})) { if ($root) { $candidates += (Join-Path $root 'hermes\hermes-agent') } } $candidates += (Join-Path (Split-Path -Parent $RepoRoot) 'hermes-agent') + # De-dup: when running in a WOW64 (32-bit-on-64-bit) PowerShell process, + # $env:ProgramFiles is redirected to C:\Program Files (x86), so without + # $env:ProgramW6432 (the canonical 64-bit override) we'd miss the real + # C:\Program Files\hermes\hermes-agent AND duplicate the x86 entry. + # Select-Object -Unique collapses any collisions regardless of cause. + $candidates = $candidates | Select-Object -Unique foreach ($c in $candidates) { if (Test-Path (Join-Path $c 'hermes_cli') -PathType Container) { $AgentDir = $c; break } }