param( [switch]$FrontendOnly, [switch]$BackendOnly, [switch]$AdminOnly, [switch]$McpOnly, [switch]$WithMcp ) $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent $MyInvocation.MyCommand.Path if (@($FrontendOnly, $BackendOnly, $AdminOnly, $McpOnly).Where({ $_ }).Count -gt 1) { throw "Use only one of -FrontendOnly, -BackendOnly, -AdminOnly, or -McpOnly." } function Stop-RepoShells { param( [string[]]$CommandPatterns ) $shells = Get-CimInstance Win32_Process | Where-Object { $commandLine = $_.CommandLine ($_.Name -in @("powershell.exe", "pwsh.exe")) -and $_.CommandLine -and $commandLine.Contains($repoRoot) -and ($CommandPatterns | Where-Object { $commandLine.Contains($_) }).Count -gt 0 } foreach ($shell in $shells) { try { Stop-Process -Id $shell.ProcessId -Force -ErrorAction Stop Write-Host "[stop] Closed matching shell (PID $($shell.ProcessId))." -ForegroundColor Yellow } catch { Write-Warning "[stop] Failed to close matching shell (PID $($shell.ProcessId)): $($_.Exception.Message)" } } } function Stop-PortOwner { param( [int]$Port, [string]$Label ) $connections = Get-NetTCPConnection -LocalPort $Port -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique if (-not $connections) { Write-Host "[stop] No process is listening on port $Port ($Label)." -ForegroundColor DarkGray return } foreach ($processId in $connections) { if ($processId -le 0 -or $processId -eq $PID) { continue } try { Stop-Process -Id $processId -Force -ErrorAction Stop Write-Host "[stop] Stopped $Label on port $Port (PID $processId)." -ForegroundColor Yellow } catch { Write-Warning "[stop] Failed to stop $Label on port $Port (PID $processId): $($_.Exception.Message)" } } } function Stop-Frontend { Stop-RepoShells -CommandPatterns @("start-frontend.ps1", "dev.ps1", "-Only frontend") Stop-PortOwner -Port 4321 -Label "frontend" } function Stop-Backend { Stop-RepoShells -CommandPatterns @("start-backend.ps1", "dev.ps1", "-Only backend") Stop-PortOwner -Port 5150 -Label "backend" } function Stop-Admin { Stop-RepoShells -CommandPatterns @("start-admin.ps1", "dev.ps1", "-Only admin") Stop-PortOwner -Port 4322 -Label "admin" } function Stop-Mcp { Stop-RepoShells -CommandPatterns @("start-mcp.ps1", "dev.ps1", "-Only mcp") Stop-PortOwner -Port 5151 -Label "MCP" } if ($FrontendOnly) { Stop-Frontend exit 0 } if ($BackendOnly) { Stop-Backend exit 0 } if ($AdminOnly) { Stop-Admin exit 0 } if ($McpOnly) { Stop-Mcp exit 0 } Write-Host "[stop] Stopping frontend, admin, and backend services..." -ForegroundColor Cyan Stop-Frontend Stop-Admin Stop-Backend if ($WithMcp) { Stop-Mcp } Write-Host "[stop] Requested services have been stopped." -ForegroundColor Green