# SourceVault one-line installer for Windows (via WSL2 + Ubuntu): # # irm https://sourcevault.ai/install.ps1 | iex # # SourceVault runs inside WSL2 Ubuntu on Windows (native Windows is not a # supported target). This script: # 1. checks that WSL2 is available — and installs it if not (needs an # elevated shell + one reboot, then re-run this same command), # 2. finds the Ubuntu distro (any Ubuntu-* release; installs one if absent), # 3. enables systemd inside WSL (required for SourceVault's services), # 4. hands off to the Linux installer (https://sourcevault.ai/install.sh) # inside Ubuntu, and only reports success once the dashboard answers, # 5. installs a per-user logon auto-start so WSL (and SourceVault) come # back up after every Windows reboot. # # Hard-won rules (each from a real machine): # - the body lives in a function and never calls a bare `exit`: under # `irm | iex` an exit closes the PowerShell window and its instructions, # - wsl.exe output is UTF-16 unless WSL_UTF8=1; parse nothing without it, # - the distro is usually named "Ubuntu-24.04"-style, NOT "Ubuntu" — every # `wsl -d` uses the resolved name, # - success is claimed only on positive proof (the health endpoint), never # on wsl.exe exit codes. function Install-SourceVault { $ErrorActionPreference = "Stop" $env:WSL_UTF8 = "1" function Say([string]$msg) { Write-Host "[sourcevault] $msg" -ForegroundColor Cyan } function Warn([string]$msg) { Write-Host "[sourcevault] $msg" -ForegroundColor Red } function CleanWsl([string]$text) { if ($null -eq $text) { "" } else { $text -replace "`0", "" } } # ---- 1. WSL present? ------------------------------------------------------- $wsl = Get-Command wsl.exe -ErrorAction SilentlyContinue if (-not $wsl) { Warn "WSL is not available on this system. Windows 10 21H2+ or Windows 11 is required." return } wsl.exe --status *> $null if ($LASTEXITCODE -ne 0) { Say "WSL2 is not installed yet. Installing it now (this needs Administrator rights)…" Say "If this fails, open an elevated PowerShell and run: wsl --install -d Ubuntu" wsl.exe --install -d Ubuntu Say "" Say "WSL2 installation started. REBOOT when prompted, open Ubuntu once to" Say "create your Linux user, then re-run this same command:" Say " irm https://sourcevault.ai/install.ps1 | iex" return } # ---- 2. Find the Ubuntu distro (its real name) ----------------------------- # `wsl --install -d Ubuntu` typically registers "Ubuntu-24.04"-style names. # Matching "Ubuntu" but then calling `wsl -d Ubuntu` was a live failure: # every later step hit WSL_E_DISTRO_NOT_FOUND. $distroList = (CleanWsl ((wsl.exe -l -q) -join "`n")) -split "`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ } $distro = $distroList | Where-Object { $_ -match "^Ubuntu" } | Select-Object -First 1 if (-not $distro) { Say "Installing the Ubuntu distro…" wsl.exe --install -d Ubuntu Say "" Say "Open Ubuntu once to create your Linux user, then re-run:" Say " irm https://sourcevault.ai/install.ps1 | iex" return } Say "Using WSL distro: $distro" # ---- 3. systemd enabled inside WSL? ---------------------------------------- Say "Ensuring systemd is enabled inside WSL (SourceVault runs as systemd user services)…" wsl.exe -d $distro -u root bash -c "grep -q 'systemd=true' /etc/wsl.conf 2>/dev/null || printf '[boot]\nsystemd=true\n' >> /etc/wsl.conf" wsl.exe -d $distro bash -c "command -v systemctl >/dev/null && systemctl is-system-running --quiet 2>/dev/null" *> $null if ($LASTEXITCODE -ne 0) { Say "Restarting WSL so systemd takes effect…" wsl.exe --shutdown Start-Sleep -Seconds 3 } # ---- 4. Hand off to the Linux installer ------------------------------------ Say "Running the SourceVault Linux installer inside ${distro}…" wsl.exe -d $distro bash -c "curl -fsSL https://sourcevault.ai/install.sh | bash" # Success is what ANSWERS, not what exited zero: wsl.exe exit codes proved # unreliable through this pipeline on real hardware (a distro-name failure # once sailed past the exit-code guard and printed success over an install # that never ran). WSL2 forwards localhost, so a healthy install serves the # health endpoint to Windows within a few seconds. $healthy = $false foreach ($attempt in 1..12) { try { $null = Invoke-RestMethod -Uri "http://localhost:9000/health" -TimeoutSec 5 $healthy = $true break } catch { Start-Sleep -Seconds 5 } } if (-not $healthy) { Warn "The dashboard is not answering on http://localhost:9000 — the install did not complete." Warn "Scroll up for the installer's output, or see https://sourcevault.ai/install/" Warn "Common causes: the Linux installer needs your sudo password (run it inside" Warn "Ubuntu directly: curl -fsSL https://sourcevault.ai/install.sh | bash), or the" Warn "service is still starting — retry: irm https://sourcevault.ai/install.ps1 | iex" return } # ---- 5. Start WSL (and SourceVault) at Windows logon ----------------------- # A per-user Startup-folder script needs no Administrator rights. It boots # the distro silently at logon; with systemd as the distro's init (and # lingering enabled by the Linux installer), the distro stays up and # SourceVault's services come up with it — service-like from Windows' view. try { $startup = [Environment]::GetFolderPath("Startup") $vbs = Join-Path $startup "SourceVault-WSL-autostart.vbs" "CreateObject(""Wscript.Shell"").Run ""wsl.exe -d $distro --exec /bin/true"", 0" | Set-Content -Path $vbs -Encoding ASCII Say "Auto-start installed: WSL (and SourceVault) starts at Windows logon." Say " (To remove it, delete: $vbs)" } catch { Warn "Could not install the logon auto-start ($($_.Exception.Message))." Warn "After a Windows reboot, open Ubuntu (or run wsl -d $distro) once to start SourceVault." } Say "" Say "Done! Open the dashboard at http://localhost:9000/dashboard/ (installable as a desktop app)" Say "(WSL2 forwards localhost automatically — it works straight from your Windows browser.)" Say "" Say "Your dashboard login token (from Windows):" Say " wsl -d $distro -- sh -c `"grep -h DASHBOARD_TOKEN ~/.config/sourcevault/sourcevault.env ~/.config/systemd/user/sourcevault.env 2>/dev/null`"" } Install-SourceVault