[CmdletBinding()] param( [int]$Port = 8000, [string]$AvdName = "CognitiveAgent_Pixel_Tablet_API36", [switch]$Stop, [switch]$NoEmulator, [switch]$NoBrowser ) $ErrorActionPreference = "Stop" $repositoryRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path $runtimeRoot = Join-Path $repositoryRoot "artifacts\server\android-pad" $pidPath = Join-Path $runtimeRoot "server.json" function Resolve-AndroidTool { param([Parameter(Mandatory = $true)][string]$RelativePath) $sdkCandidates = @( $env:ANDROID_SDK_ROOT, $env:ANDROID_HOME, "D:\Android\Sdk", (Join-Path $env:LOCALAPPDATA "Android\Sdk") ) | Where-Object { $_ } foreach ($sdkRoot in $sdkCandidates) { $candidate = Join-Path $sdkRoot $RelativePath if (Test-Path -LiteralPath $candidate -PathType Leaf) { return (Resolve-Path -LiteralPath $candidate).Path } } throw "Android SDK tool not found: $RelativePath" } function Read-ServerProcess { if (-not (Test-Path -LiteralPath $pidPath -PathType Leaf)) { return $null } try { $record = Get-Content -LiteralPath $pidPath -Raw | ConvertFrom-Json $processInfo = Get-CimInstance Win32_Process ` -Filter "ProcessId = $([int]$record.pid)" ` -ErrorAction SilentlyContinue if (-not $processInfo -or -not $processInfo.CommandLine.Contains("cognitive_agent.server")) { return $null } return Get-Process -Id ([int]$record.pid) -ErrorAction SilentlyContinue } catch { return $null } } $adb = Resolve-AndroidTool "platform-tools\adb.exe" if ($Stop) { $serverProcess = Read-ServerProcess if ($serverProcess) { Stop-Process -Id $serverProcess.Id -Force Write-Host "Stopped Cognitive Agent server (PID $($serverProcess.Id))." } & $adb reverse --remove "tcp:$Port" 2>$null | Out-Null if (Test-Path -LiteralPath $pidPath -PathType Leaf) { Remove-Item -LiteralPath $pidPath -Force } exit 0 } New-Item -ItemType Directory -Force -Path $runtimeRoot | Out-Null $emulator = Resolve-AndroidTool "emulator\emulator.exe" $device = (& $adb devices) | Select-String -Pattern '^(emulator-\d+)\s+device$' | Select-Object -First 1 if (-not $device -and -not $NoEmulator) { Write-Host "Starting Android tablet AVD: $AvdName" Start-Process -FilePath $emulator ` -ArgumentList @("-avd", $AvdName, "-no-snapshot-save") ` -WindowStyle Hidden | Out-Null } if (-not $NoEmulator) { & $adb wait-for-device $deadline = (Get-Date).AddMinutes(3) do { $bootCompleted = (& $adb shell getprop sys.boot_completed 2>$null).Trim() if ($bootCompleted -eq "1") { break } if ((Get-Date) -gt $deadline) { throw "Android emulator boot timed out." } Start-Sleep -Seconds 2 } while ($true) & $adb reverse "tcp:$Port" "tcp:$Port" } $serverProcess = Read-ServerProcess if (-not $serverProcess) { $python = Get-Command python -ErrorAction Stop $oldPythonPath = $env:PYTHONPATH $oldHardware = $env:COGNITIVE_AGENT_HARDWARE_EXECUTION_ENABLED $oldSimulation = $env:COGNITIVE_AGENT_SIMULATED_HARDWARE_ENABLED try { $env:PYTHONPATH = "$repositoryRoot\src;$repositoryRoot\domains\seat\src" $env:COGNITIVE_AGENT_HARDWARE_EXECUTION_ENABLED = "false" $env:COGNITIVE_AGENT_SIMULATED_HARDWARE_ENABLED = "true" $serverProcess = Start-Process -FilePath $python.Source ` -ArgumentList @( "-m", "cognitive_agent.server", "--host", "127.0.0.1", "--port", "$Port" ) ` -WorkingDirectory $repositoryRoot ` -RedirectStandardOutput (Join-Path $runtimeRoot "stdout.log") ` -RedirectStandardError (Join-Path $runtimeRoot "stderr.log") ` -WindowStyle Hidden ` -PassThru } finally { $env:PYTHONPATH = $oldPythonPath $env:COGNITIVE_AGENT_HARDWARE_EXECUTION_ENABLED = $oldHardware $env:COGNITIVE_AGENT_SIMULATED_HARDWARE_ENABLED = $oldSimulation } @{ pid = $serverProcess.Id port = $Port started_at = (Get-Date).ToString("o") } | ConvertTo-Json | Set-Content -LiteralPath $pidPath -Encoding UTF8 Write-Host "Started Cognitive Agent server (PID $($serverProcess.Id))." } $healthUrl = "http://127.0.0.1:$Port/api/health" $deadline = (Get-Date).AddSeconds(45) do { try { $health = Invoke-RestMethod -Uri $healthUrl -TimeoutSec 3 if ($health.status -eq "ok") { break } } catch { if ($serverProcess.HasExited) { throw "Server exited during startup. See $runtimeRoot\stderr.log" } } if ((Get-Date) -gt $deadline) { throw "Server health check timed out: $healthUrl" } Start-Sleep -Milliseconds 750 } while ($true) $padUrl = "http://127.0.0.1:$Port" if (-not $NoEmulator -and -not $NoBrowser) { & $adb shell am start -a android.intent.action.VIEW -d $padUrl | Out-Null } Write-Host "Windows: $padUrl" Write-Host "Android: $padUrl (adb reverse tcp:$Port tcp:$Port)" Write-Host "Simulation: enabled; physical hardware execution: disabled" Write-Host "Stop: .\tools\android_pad_dev.ps1 -Port $Port -Stop"