# ZCLAW Full Stack Start Script # Starts: ChromeDriver (optional) -> OpenFang Gateway (optional) -> Tauri Desktop param( [switch]$NoBrowser, [switch]$NoGateway, [switch]$Dev, [switch]$Help, [switch]$Stop, [switch]$DesktopOnly ) $ErrorActionPreference = "Continue" $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path # Colors function info { param($msg) Write-Host "[INFO] $msg" -ForegroundColor Cyan } function ok { param($msg) Write-Host "[OK] $msg" -ForegroundColor Green } function warn { param($msg) Write-Host "[WARN] $msg" -ForegroundColor Yellow } function err { param($msg) Write-Host "[ERROR] $msg" -ForegroundColor Red } if ($Help) { Write-Host @" ZCLAW Full Stack Start Script ============================== Usage: .\start-all.ps1 [options] Options: -DesktopOnly Start desktop only (skip all external services) -NoBrowser Skip ChromeDriver -NoGateway Skip OpenFang Gateway -Dev Development mode (hot reload) -Stop Stop all services -Help Show this help Quick Commands: pnpm start # Start all services pnpm desktop # Start desktop only "@ exit 0 } # Stop all services if ($Stop) { info "Stopping all ZCLAW services..." # Stop ChromeDriver Get-Process -Name "chromedriver" -ErrorAction SilentlyContinue | Stop-Process -Force ok "ChromeDriver stopped" # Stop OpenFang (if running via openfang CLI) if (Get-Command openfang -ErrorAction SilentlyContinue) { openfang gateway stop 2>$null ok "OpenFang Gateway stopped" } # Stop Tauri/ZClaw Get-Process -Name "ZClaw" -ErrorAction SilentlyContinue | Stop-Process -Force Get-Process -Name "desktop" -ErrorAction SilentlyContinue | Stop-Process -Force ok "ZCLAW Desktop stopped" # Kill any process on port 1420 $port1420 = netstat -ano | Select-String ":1420.*LISTENING" if ($port1420) { $pid1420 = ($port1420 -split '\s+')[-1] if ($pid1420 -match '^\d+$') { Stop-Process -Id $pid1420 -Force -ErrorAction SilentlyContinue ok "Killed process on port 1420 (PID: $pid1420)" } } ok "All services stopped" exit 0 } Write-Host "" Write-Host "===============================================" -ForegroundColor Magenta Write-Host " ZCLAW - OpenFang Desktop Client" -ForegroundColor Magenta Write-Host "===============================================" -ForegroundColor Magenta Write-Host "" # Track processes for cleanup $Jobs = @() function Cleanup { info "Cleaning up..." foreach ($job in $Jobs) { if ($job -and !$job.HasExited) { info "Stopping $($job.ProcessName) (PID: $($job.Id))" try { $job.Kill() } catch {} } } } trap { Cleanup; break } Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action { Cleanup } | Out-Null # Skip external services if DesktopOnly if ($DesktopOnly) { $NoBrowser = $true $NoGateway = $true } # 1. ChromeDriver (optional) if (-not $NoBrowser) { info "Checking ChromeDriver..." $existing = Get-Process -Name "chromedriver" -ErrorAction SilentlyContinue if ($existing) { ok "ChromeDriver already running (PID: $($existing.Id))" } else { $chromedriver = Get-Command chromedriver -ErrorAction SilentlyContinue if ($chromedriver) { ok "ChromeDriver found: $($chromedriver.Source)" info "Starting ChromeDriver on port 4444..." $proc = Start-Process -FilePath "chromedriver" -ArgumentList "--port=4444" -PassThru -WindowStyle Hidden $Jobs += $proc Start-Sleep -Milliseconds 500 if ($proc.HasExited) { warn "ChromeDriver exited. Check if port 4444 is in use." } else { ok "ChromeDriver started (PID: $($proc.Id))" } } else { warn "ChromeDriver not found. Browser automation disabled." info "Download: https://chromedriver.chromium.org/downloads" } } } else { info "Skipping ChromeDriver" } Write-Host "" # 2. OpenFang Gateway (optional) if (-not $NoGateway) { info "Checking OpenFang Gateway..." $gatewayUp = $false try { $r = Invoke-WebRequest -Uri "http://127.0.0.1:4200/health" -TimeoutSec 2 -ErrorAction SilentlyContinue if ($r.StatusCode -eq 200) { $gatewayUp = $true } } catch {} if ($gatewayUp) { ok "OpenFang Gateway running on port 4200" } else { if (Get-Command openfang -ErrorAction SilentlyContinue) { info "Starting OpenFang Gateway..." $proc = Start-Process -FilePath "openfang" -ArgumentList "gateway", "start" -PassThru $Jobs += $proc info "Waiting for gateway..." $wait = 0 while ($wait -lt 30) { try { $r = Invoke-WebRequest -Uri "http://127.0.0.1:4200/health" -TimeoutSec 1 -ErrorAction SilentlyContinue if ($r.StatusCode -eq 200) { ok "OpenFang Gateway started" break } } catch {} Start-Sleep -Seconds 1 $wait++ Write-Host -NoNewline "." } Write-Host "" if ($wait -ge 30) { warn "Gateway did not respond within 30s" } } else { warn "OpenFang CLI not found. Gateway not started." info "The app will run in standalone mode." } } } else { info "Skipping OpenFang Gateway" } Write-Host "" # 3. Tauri Desktop info "Starting ZCLAW Desktop..." Set-Location "$ScriptDir/desktop" # Check if port 1420 is in use $port1420 = netstat -ano | Select-String ":1420.*LISTENING" if ($port1420) { $pid1420 = ($port1420 -split '\s+')[-1] if ($pid1420 -match '^\d+$') { warn "Port 1420 is in use by PID $pid1420. Killing..." Stop-Process -Id $pid1420 -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 1 } } if ($Dev) { info "Development mode enabled" pnpm tauri dev } else { $exe = "src-tauri\target\release\ZClaw.exe" if (Test-Path $exe) { info "Starting built application..." Start-Process $exe ok "ZCLAW Desktop started" } else { info "Built app not found, using dev mode..." pnpm tauri dev } } if ($Dev) { Write-Host "" info "Press Ctrl+C to stop all services..." try { while ($true) { Start-Sleep -Seconds 1 } } finally { Cleanup } }