diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 1a381309a7..a0fa6591b5 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -553,6 +553,62 @@ function Show-NpmCertHint { return $true } +function Write-NpmDebugLogTail { + # On failure npm prints only a terse summary to stdout/stderr; the real + # evidence (postinstall script stderr like Electron's install.js, network + # traces, EBUSY retries) lives in npm's own debug log under + # \_logs\-debug-0.log. The bootstrap installer's + # streaming sink only captures what WE emit, so on any npm failure this + # helper locates that debug log and replays its tail into our output + # stream -- making the bootstrap log a self-contained diagnosis instead + # of "exit 1, details in a file on a VM nobody can reach". + param( + [string]$NpmOutput, + [int]$TailLines = 200 + ) + $logPath = $null + # Preferred: npm names the exact file in its failure summary. + if ($NpmOutput -and $NpmOutput -match "A complete log of this run can be found in:\s*(?[^\r\n]+)") { + $candidate = $Matches['path'].Trim() + if (Test-Path -LiteralPath $candidate) { $logPath = $candidate } + } + # Fallback (covers --silent runs, truncated output): newest debug log in + # npm's cache _logs directory. + if (-not $logPath) { + try { + $npm = Resolve-NpmCmd + if ($npm) { + $prevEAPLocal = $ErrorActionPreference + $ErrorActionPreference = "Continue" + $cacheDir = (& $npm config get cache 2>$null | Select-Object -Last 1) + $ErrorActionPreference = $prevEAPLocal + if ($cacheDir) { + $logsDir = Join-Path ("$cacheDir").Trim() "_logs" + if (Test-Path -LiteralPath $logsDir) { + $newest = Get-ChildItem -LiteralPath $logsDir -Filter "*-debug-*.log" -ErrorAction SilentlyContinue | + Sort-Object LastWriteTime -Descending | Select-Object -First 1 + if ($newest) { $logPath = $newest.FullName } + } + } + } + } catch { } + } + if (-not $logPath) { + Write-Warn "npm debug log could not be located -- no further npm detail available" + return + } + $tail = $null + try { + $tail = Get-Content -LiteralPath $logPath -Tail $TailLines -ErrorAction Stop + } catch { + Write-Warn "Could not read npm debug log ${logPath}: $($_.Exception.Message)" + return + } + Write-Warn "---- npm debug log: last $TailLines lines of $logPath ----" + foreach ($line in $tail) { Write-Host " $line" -ForegroundColor DarkGray } + Write-Warn "---- end npm debug log ----" +} + # --- Ensure-mode helpers --- function Resolve-NpmCmd { @@ -620,6 +676,9 @@ function Install-AgentBrowser { Remove-Item $npmLog -Force -ErrorAction SilentlyContinue Write-Err "npm install -g failed (exit $npmExit): $npmDetail" Show-NpmCertHint $npmDetail | Out-Null + # This install runs with --silent, so $npmDetail is often near-empty; + # npm's debug log is the only place the real error survives. + Write-NpmDebugLogTail -NpmOutput $npmDetail throw "npm install failed" } Remove-Item $npmLog -Force -ErrorAction SilentlyContinue @@ -2973,6 +3032,7 @@ function Install-NodeDeps { } Write-Info " Full log: $logPath" Show-NpmCertHint $errText | Out-Null + Write-NpmDebugLogTail -NpmOutput $errText } } Write-Info "Run manually later: cd `"$installDir`"; npm install" @@ -3344,6 +3404,10 @@ function Install-Desktop { Try-RestoreElectronDist -InstallDir $InstallDir | Out-Null } else { Show-NpmCertHint ($npmOut -join "`n") | Out-Null + # Replay npm's own debug log into our stream: the terse + # summary above rarely contains the postinstall stderr + # (e.g. Electron's install.js) that explains the failure. + Write-NpmDebugLogTail -NpmOutput ($npmOut -join "`n") throw "desktop workspace npm install failed (exit $code) -- see lines above for cause" } } else { @@ -3465,6 +3529,10 @@ function Install-Desktop { foreach ($line in $snippet -split "`n") { Write-Host " $line" -ForegroundColor DarkGray } Write-Info " Full log: $buildLog" } + # `npm run pack` failures (lifecycle script exits) also land in + # npm's debug log; replay it so the bootstrap log carries the + # full evidence even when $buildLog's tail cuts off the cause. + Write-NpmDebugLogTail -NpmOutput $errText throw "apps/desktop build failed (exit $code)" } Write-Success "Desktop app built"