$ErrorActionPreference = "Stop" Set-StrictMode -Version Latest $RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path $RuntimeDir = Join-Path $RepoRoot ".runtime" $Services = @( @{ Name = "web" Port = 3000 Url = "http://localhost:3000" }, @{ Name = "api" Port = 3001 Url = "http://localhost:3001/health" }, @{ Name = "extra" Port = 3002 Url = "http://localhost:3002/health" } ) function Get-PidFilePath([string]$Name) { return Join-Path $RuntimeDir "$Name.pid" } function Get-ListenerOwners([int]$Port) { try { return @(Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction Stop | Select-Object -ExpandProperty OwningProcess -Unique) } catch { return @() } } function Test-Url([string]$Url) { try { $response = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec 3 return $response.StatusCode } catch { return $null } } Write-Host "SentAI local status" -ForegroundColor Cyan Write-Host "Repo: $RepoRoot" Write-Host "" foreach ($service in $Services) { [array]$owners = @(Get-ListenerOwners $service.Port) $statusCode = Test-Url $service.Url $pidFile = Get-PidFilePath $service.Name $pidText = if (Test-Path $pidFile) { (Get-Content $pidFile | Select-Object -First 1) } else { "-" } $ownerText = if ($owners.Count -gt 0) { $owners -join ", " } else { "-" } $httpText = if ($statusCode) { $statusCode } else { "-" } Write-Host "$($service.Name.PadRight(6)) port=$($service.Port) pid-file=$pidText owners=$ownerText http=$httpText" }