#!/usr/bin/env pwsh <# Launch the RyuMusic backend (uvicorn on :8000) and frontend (vite on :5173) in parallel. Stops both on Ctrl-C. #> param( [switch]$ClientOnly, [switch]$ServerOnly ) $ErrorActionPreference = "Stop" $root = Split-Path -Parent $PSCommandPath function Start-Background([string]$label, [string]$cmd, [string]$cwd) { Write-Host "==> $label" -ForegroundColor Cyan $p = Start-Process -FilePath powershell.exe ` -ArgumentList "-NoLogo", "-NoProfile", "-Command", ` "Set-Location -LiteralPath '$cwd'; Write-Host '[$label]' -ForegroundColor Cyan -NoNewline; $cmd" ` -PassThru -WindowStyle Normal return $p } $server = $null $client = $null try { if (-not $ClientOnly) { $server = Start-Background "server" "python -m uvicorn server.main:app --reload --host 0.0.0.0 --port 8000" ` $root } if (-not $ServerOnly) { $client = Start-Background "client" "npm run dev -- --host" ` (Join-Path $root "client") } Write-Host "" Write-Host "press Ctrl-C to stop both" -ForegroundColor Yellow Write-Host "" while ($true) { Start-Sleep -Seconds 1 $serverGone = $null -eq $server -or $server.HasExited $clientGone = $null -eq $client -or $client.HasExited if ($server -and $serverGone) { Write-Host "server exited" -ForegroundColor Red; break } if ($client -and $clientGone) { Write-Host "client exited" -ForegroundColor Red; break } } } finally { foreach ($p in @($server, $client)) { if ($p -and -not $p.HasExited) { try { Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue } catch {} } } }