@@ -2425,6 +2425,17 @@ if ($isInteractive) {
24252425 }
24262426 catch { Write-Verbose " Failed to parse user-settings.json: $_ " }
24272427 }
2428+ # Recovery: if theme.json is missing (cache cleared or cleaning program), re-download it
2429+ if (-not $themeName ) {
2430+ try {
2431+ $configUrl = " $repo_root /$repo_name /main/theme.json"
2432+ Invoke-RestMethod - Uri $configUrl - OutFile $profileConfigPath - TimeoutSec 5 - ErrorAction Stop
2433+ $cfg = Get-Content $profileConfigPath - Raw | ConvertFrom-Json
2434+ if ($cfg.theme.name ) { $themeName = $cfg.theme.name }
2435+ if ($cfg.theme.url ) { $themeUrl = $cfg.theme.url }
2436+ }
2437+ catch { Write-Verbose " Could not recover theme.json from repo: $_ " }
2438+ }
24282439 if (-not $themeName ) {
24292440 Write-Verbose " No theme.json found in cache. Run Update-Profile or setup.ps1 to configure the OMP theme."
24302441 }
@@ -2451,9 +2462,9 @@ if ($isInteractive) {
24512462 }
24522463 }
24532464 if ($localThemePath -and (Test-Path $localThemePath )) {
2454- # Ensure OMP always uses our theme, even if its internal cache is invalidated
2455- $env: POSH_THEME = $localThemePath
2456- # Cache the OMP init script so we don't shell out every startup
2465+ # Resolve OMP's internal cache directory (used for stale cache cleanup below)
2466+ $ompInternalDir = ( Resolve-Path ( Join-Path $ env: LOCALAPPDATA ' Packages\ohmyposh.cli_*\LocalCache\Local\oh-my-posh ' ) - ErrorAction SilentlyContinue | Select-Object - First 1 ).Path
2467+ # Cache the OMP init script so we don't shell out every startup.
24572468 # Header tracks both OMP version AND theme path so a theme switch invalidates the cache.
24582469 # PERF: Defer `oh-my-posh version` (~2-3s) until we know the cache is missing/stale.
24592470 # When the cache exists, validate using only the theme path portion of the header
@@ -2463,13 +2474,31 @@ if ($isInteractive) {
24632474 if (Test-Path $ompCachePath ) {
24642475 $fileSize = (Get-Item $ompCachePath ).Length
24652476 if ($fileSize -gt 0 ) {
2466- $cacheContent = Get-Content $ompCachePath - First 1
2467- # Fast check: just verify the header references the correct theme path
2468- if ($cacheContent -match ' ^# OMP_CACHE: .+ \| ' -and $cacheContent.EndsWith ($localThemePath )) {
2469- $cacheValid = $true
2477+ $cacheContent = Get-Content $ompCachePath - Raw
2478+ $firstLine = ($cacheContent -split " `n " , 2 )[0 ]
2479+ # Fast check: verify header references correct theme path
2480+ if ($firstLine -match ' ^# OMP_CACHE: .+ \| ' -and $firstLine.EndsWith ($localThemePath )) {
2481+ # Also verify that the OMP internal init file referenced in the cache still exists.
2482+ # Cleaning programs (CCleaner, BleachBit) often wipe LocalCache directories,
2483+ # deleting OMP's internal init script and breaking the cached redirect.
2484+ $ompInternalPath = [regex ]::Match($cacheContent , " & '([^']+)'" ).Groups[1 ].Value
2485+ if ($ompInternalPath -and (Test-Path - LiteralPath $ompInternalPath )) {
2486+ $cacheValid = $true
2487+ }
2488+ }
2489+ }
2490+ if (-not $cacheValid ) {
2491+ Remove-Item $ompCachePath - Force - ErrorAction SilentlyContinue
2492+ # OMP bakes the theme into its binary cache (omp.cache) during `init --config`.
2493+ # POSH_THEME env var is NOT respected by `print primary` - only --config during init matters.
2494+ # When our cache is invalid (cleaner wiped the internal init file, or theme changed),
2495+ # clear all OMP binary/session caches so the regenerated init bakes in the correct theme.
2496+ if ($ompInternalDir ) {
2497+ Remove-Item (Join-Path $ompInternalDir ' omp.cache' ) - Force - ErrorAction SilentlyContinue
2498+ Get-ChildItem $ompInternalDir - Filter ' pwsh.*.omp.cache' - ErrorAction SilentlyContinue |
2499+ Remove-Item - Force - ErrorAction SilentlyContinue
24702500 }
24712501 }
2472- if (-not $cacheValid ) { Remove-Item $ompCachePath - Force - ErrorAction SilentlyContinue }
24732502 }
24742503 if (-not $cacheValid ) {
24752504 # Only pay the cost of `oh-my-posh version` when we need to regenerate the cache
0 commit comments