@@ -714,27 +714,47 @@ function Set-GitBashEnvVar {
714714 Write-Info " If needed, set HERMES_GIT_BASH_PATH manually to your bash.exe path."
715715}
716716
717+ # The desktop build runs Vite ^8, which refuses to start on Node outside
718+ # `^20.19 || >=22.12` -- older Node lacks node:util.styleText, so `vite build`
719+ # crashes with a SyntaxError that surfaces only as the opaque "Build desktop
720+ # app ... exit code 1" install failure. Returns $true when a `node --version`
721+ # string clears that floor.
722+ function Test-NodeVersionOk {
723+ param ([string ]$Version )
724+ try {
725+ $v = [version ]($Version -replace ' ^v' , ' ' -replace ' -.*$' , ' ' )
726+ } catch {
727+ return $false
728+ }
729+ if ($v.Major -eq 20 -and $v.Minor -ge 19 ) { return $true }
730+ if ($v.Major -ge 22 -and ($v.Major -gt 22 -or $v.Minor -ge 12 )) { return $true }
731+ return $false
732+ }
733+
717734function Test-Node {
718735 Write-Info " Checking Node.js (for browser tools)..."
719736
720737 if (Get-Command node - ErrorAction SilentlyContinue) {
721738 $version = node -- version
722- Write-Success " Node.js $version found"
723- $script :HasNode = $true
724- return $true
739+ if (Test-NodeVersionOk $version ) {
740+ Write-Success " Node.js $version found"
741+ $script :HasNode = $true
742+ return $true
743+ }
744+ Write-Warn " Node.js $version is too old for the desktop build (need ^20.19 or >=22.12)"
725745 }
726746
727- # Check our own managed install from a previous run
747+ # Prefer a Hermes- managed Node from a previous run over a too-old system one.
728748 $managedNode = " $HermesHome \node\node.exe"
729- if (Test-Path $managedNode ) {
749+ if (( Test-Path $managedNode ) -and ( Test-NodeVersionOk ( & $managedNode -- version)) ) {
730750 $version = & $managedNode -- version
731751 $env: Path = " $HermesHome \node;$env: Path "
732752 Write-Success " Node.js $version found (Hermes-managed)"
733753 $script :HasNode = $true
734754 return $true
735755 }
736756
737- Write-Info " Node.js not found -- installing Node.js $NodeVersion LTS..."
757+ Write-Info " Installing Hermes-managed Node.js $NodeVersion LTS..."
738758
739759 # Try the portable-zip path FIRST -- no UAC, no admin, no winget MSI.
740760 # winget install OpenJS.NodeJS.LTS triggers a system-wide MSI install
@@ -1906,16 +1926,17 @@ function Install-Desktop {
19061926 # so an "unpacked" build (electron-builder --dir) is enough — we
19071927 # don't need to produce an NSIS/MSI artifact here.
19081928
1909- if (-not $HasNode ) {
1910- # Cross-process driver mode: each `-Stage NAME` invocation runs in a
1911- # fresh PowerShell process, so $script:HasNode set by Stage-Node
1912- # in the previous process isn't visible. Re-detect rather than
1913- # trusting the global.
1914- if (-not (Get-Command npm - ErrorAction SilentlyContinue)) {
1915- Write-Warn " Skipping desktop build (Node.js / npm not on PATH)"
1916- $script :_StageSkippedReason = " Node.js not available"
1917- return
1918- }
1929+ # Always re-resolve Node here. Stages run in separate PowerShell processes,
1930+ # so $script:HasNode from Stage-Node isn't visible; more importantly Test-Node
1931+ # enforces the build floor (^20.19 || >=22.12) and prepends the Hermes-managed
1932+ # Node to PATH, so the build never runs on a too-old system Node -- the cause
1933+ # of the opaque "Build desktop app ... exit code 1" failure (Vite crashes on
1934+ # old Node).
1935+ Test-Node | Out-Null
1936+ if (-not (Get-Command npm - ErrorAction SilentlyContinue)) {
1937+ Write-Warn " Skipping desktop build (Node.js / npm not on PATH)"
1938+ $script :_StageSkippedReason = " Node.js not available"
1939+ return
19191940 }
19201941
19211942 $desktopDir = " $InstallDir \apps\desktop"
0 commit comments