diff --git a/install.ps1 b/install.ps1 index 2ba6e8c..e4e7f12 100644 --- a/install.ps1 +++ b/install.ps1 @@ -127,17 +127,23 @@ $wrapperTarget = Join-Path $claude 'cship-statusline.ps1' Copy-Item (Join-Path $assets 'cship-statusline.ps1') $wrapperTarget -Force Write-Ok "cship-statusline.ps1 -> $claude" -# --- 4. Locate pwsh --------------------------------------------------------- +# --- 4. Locate a PowerShell host -------------------------------------------- +# Prefer PowerShell 7 (pwsh). If it isn't installed, fall back to Windows +# PowerShell 5.1 (powershell.exe) which ships with every Windows install and +# runs the wrapper correctly - so the statusline works out of the box instead +# of pointing at a non-existent pwsh.exe and silently rendering nothing. $pwsh = (Get-Command pwsh -ErrorAction SilentlyContinue).Source +if (-not $pwsh -and (Test-Path 'C:\Program Files\PowerShell\7\pwsh.exe')) { + $pwsh = 'C:\Program Files\PowerShell\7\pwsh.exe' +} if (-not $pwsh) { - $fallback = 'C:\Program Files\PowerShell\7\pwsh.exe' - if (Test-Path $fallback) { - $pwsh = $fallback - } else { - Write-Warn "PowerShell 7 (pwsh) not found. Install it, then re-run this script." - Write-Warn " winget install --id Microsoft.PowerShell -e" - $pwsh = $fallback # write the conventional path so it works once pwsh is installed + $pwsh = (Get-Command powershell -ErrorAction SilentlyContinue).Source + if (-not $pwsh) { + $pwsh = Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe' } + Write-Warn "PowerShell 7 (pwsh) not found - using Windows PowerShell 5.1." + Write-Warn " For sharper rendering, install PS7 and re-run this script:" + Write-Warn " winget install --id Microsoft.PowerShell -e" } $pwshFwd = $pwsh.Replace('\', '/') $wrapperFwd = $wrapperTarget.Replace('\', '/') @@ -160,7 +166,27 @@ if ($settings.PSObject.Properties.Name -contains 'statusLine') { } $settings | ConvertTo-Json -Depth 20 | Set-Content $settingsPath -Encoding UTF8 -Write-Ok "settings.json statusLine wired to detected pwsh" +Write-Ok "settings.json statusLine wired to $([IO.Path]::GetFileName($pwsh))" + +# --- 5b. End-to-end self-test ----------------------------------------------- +# Actually run the configured host + wrapper against a sample Status payload so +# a broken host path (the classic "no statusline appears" failure) is caught +# here rather than silently at runtime, where Claude Code just shows nothing. +$sample = '{"hook_event_name":"Status","model":{"display_name":"Opus"},' + + '"workspace":{"current_dir":"' + ($claude -replace '\\','/') + '",' + + '"project_dir":"' + ($claude -replace '\\','/') + '"},' + + '"context_window":{"used_tokens":1000}}' +try { + $probe = $sample | & $pwsh -NoProfile -ExecutionPolicy Bypass -File $wrapperTarget 2>$null + if ([string]::IsNullOrWhiteSpace(($probe -join ''))) { + Write-Warn "Self-test produced no output - the statusline may not render." + Write-Warn " Check that '$pwsh' runs and that cship.exe is present." + } else { + Write-Ok "Self-test passed - statusline renders." + } +} catch { + Write-Warn "Self-test could not run the host: $($_.Exception.Message)" +} # --- 6. Nerd Font (safety net, per-user) ------------------------------------ if ($SkipFont) {