param( [int]$ApiPort = 8037, [int]$FallbackApiPort = 8041, [int]$FrontendPort = 3001 ) $ErrorActionPreference = "Stop" $RepoRoot = Split-Path -Parent $MyInvocation.MyCommand.Path $Backend = Join-Path $RepoRoot "backend" $Frontend = Join-Path $RepoRoot "frontend" $RedisDir = Join-Path $Backend "redis" $RedisExe = Join-Path $RedisDir "redis-server.exe" $RedisCli = Join-Path $RedisDir "redis-cli.exe" function Test-PortListening([int]$Port) { $line = netstat -ano | Select-String ":$Port\s+.*LISTENING" | Select-Object -First 1 return [bool]$line } function Ensure-Redis { if (Test-PortListening 6379) { Write-Host '[OK] Redis already listening on 6379' -ForegroundColor Green return } if (-not (Test-Path $RedisExe)) { throw "Redis executable not found: $RedisExe" } Write-Host '[RUN] Starting Redis on 6379 ...' -ForegroundColor Yellow Start-Process -FilePath $RedisExe -ArgumentList "--port 6379" -WorkingDirectory $RedisDir | Out-Null Start-Sleep -Seconds 2 if (-not (Test-PortListening 6379)) { throw "Redis failed: port 6379 not listening" } if (Test-Path $RedisCli) { & $RedisCli -p 6379 ping | Out-Null } Write-Host '[OK] Redis started' -ForegroundColor Green } function Resolve-ApiPort { if (-not (Test-PortListening $ApiPort)) { return $ApiPort } Write-Host ('[WARN] Port {0} is occupied, switching to {1}' -f $ApiPort, $FallbackApiPort) -ForegroundColor Yellow if (Test-PortListening $FallbackApiPort) { throw "Ports $ApiPort and $FallbackApiPort are in use; free one first" } return $FallbackApiPort } Write-Host '== AIAgent one-click start ==' -ForegroundColor Cyan Write-Host "Repo: $RepoRoot" Ensure-Redis $RealApiPort = Resolve-ApiPort $ApiBase = "http://127.0.0.1:$RealApiPort" Write-Host ('[RUN] Starting backend API on {0} ...' -f $RealApiPort) -ForegroundColor Yellow Start-Process powershell -ArgumentList @( "-NoExit", "-Command", "cd '$Backend'; .\venv\Scripts\Activate.ps1; python -m uvicorn app.main:app --host 0.0.0.0 --port $RealApiPort" ) Write-Host '[RUN] Starting Celery worker ...' -ForegroundColor Yellow Start-Process powershell -ArgumentList @( "-NoExit", "-Command", "cd '$Backend'; .\venv\Scripts\Activate.ps1; python -m celery -A app.core.celery_app worker --loglevel=info --pool=threads --concurrency=8" ) Write-Host '[RUN] Starting Celery Beat (scheduler) ...' -ForegroundColor Yellow Start-Process powershell -ArgumentList @( "-NoExit", "-Command", "cd '$Backend'; .\venv\Scripts\Activate.ps1; python -m celery -A app.core.celery_app beat --loglevel=info" ) Write-Host ('[RUN] Starting frontend on {0} (proxy -> {1}) ...' -f $FrontendPort, $ApiBase) -ForegroundColor Yellow Start-Process powershell -ArgumentList @( "-NoExit", "-Command", "`$env:AIAGENT_API_PROXY='$ApiBase'; cd '$Frontend'; pnpm dev --port $FrontendPort" ) Write-Host "" Write-Host '[DONE] Start commands issued (check new PowerShell windows)' -ForegroundColor Green Write-Host "Frontend: http://localhost:$FrontendPort" -ForegroundColor Cyan Write-Host "API docs: $ApiBase/docs" -ForegroundColor Cyan Write-Host "Redis: 127.0.0.1:6379" -ForegroundColor Cyan