oclaw/runtime/operations/scripts/status_all.ps1
oliver 4a23b715a2 重构仓库目录为统一的 runtime 分层并清理历史 openclaw 残留。
本次迁移将网关/通道/工具/技能/脚本与协议资源集中到新结构,统一路径常量与脚本转发机制,减少顶层噪音并保证运行与测试行为一致。

Made-with: Cursor
2026-04-25 01:24:23 +08:00

140 lines
4.9 KiB
PowerShell

param(
[string]$BindHost = "127.0.0.1",
[int]$Port = 8787,
[switch]$WithWeixin = $false,
[switch]$WithWikiWorker = $false,
[string]$WeixinChannelId = "oclaw-weixin"
)
$ErrorActionPreference = "Stop"
function Write-Step([string]$msg) {
Write-Host "==> $msg" -ForegroundColor Cyan
}
function Warn([string]$msg) {
Write-Host "[WARN] $msg" -ForegroundColor Yellow
}
$runDir = Join-Path $PSScriptRoot ".run"
$null = New-Item -ItemType Directory -Force -Path $runDir -ErrorAction SilentlyContinue
$gwPidFile = Join-Path $runDir "gateway.pid"
$desktopPidFile = Join-Path $runDir "desktop.pid"
Write-Step "URLs"
Write-Host "Admin: http://$BindHost`:$Port/admin"
Write-Host "Chat: http://$BindHost`:$Port/chat"
Write-Host "WS: ws://$BindHost`:$Port/ws"
Write-Host ""
Write-Step "PID files"
if (Test-Path $gwPidFile) {
$gwPid = (Get-Content $gwPidFile -ErrorAction SilentlyContinue | Select-Object -First 1)
Write-Host "gateway.pid: $gwPidFile => $gwPid"
} else {
Warn "gateway.pid not found: $gwPidFile"
}
if (Test-Path $desktopPidFile) {
$deskPid = (Get-Content $desktopPidFile -ErrorAction SilentlyContinue | Select-Object -First 1)
Write-Host "desktop.pid: $desktopPidFile => $deskPid"
} else {
Warn "desktop.pid not found: $desktopPidFile"
}
Write-Host ""
Write-Step "Port listener"
try {
$conns = Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction SilentlyContinue
if (-not $conns) {
Warn "No listener on port $Port"
exit 0
}
$pids = $conns | Select-Object -ExpandProperty OwningProcess -Unique
Write-Host "Listening on port $Port; OwningProcess: $($pids -join ', ')"
# Self-heal: if we have a single owning pid and no gateway.pid, write it back.
if (-not (Test-Path $gwPidFile)) {
$pidList = @()
foreach ($x in @($pids)) {
$n = 0
if ([int]::TryParse([string]$x, [ref]$n) -and $n -gt 0) {
$pidList += $n
}
}
if ($pidList.Count -eq 1) {
$procId = [int]$pidList[0]
try {
$null = Get-Process -Id $procId -ErrorAction Stop
Set-Content -Path $gwPidFile -Value "$procId" -Encoding ascii
Write-Host "Wrote gateway.pid => $procId" -ForegroundColor Green
} catch {
Warn "Cannot verify process for PID=$procId; not writing pid file."
}
} else {
# Heuristic: try to pick the gateway python/uvicorn process.
$candidates = @()
foreach ($p in $pidList) {
try {
$proc = Get-Process -Id $p -ErrorAction Stop
$name = [string]$proc.ProcessName
} catch {
continue
}
$cmd = ""
try {
$wmi = Get-CimInstance Win32_Process -Filter "ProcessId=$p" -ErrorAction SilentlyContinue
if ($wmi -and $wmi.CommandLine) { $cmd = [string]$wmi.CommandLine }
} catch {
$cmd = ""
}
if ($cmd) {
$low = ([string]$cmd).ToLowerInvariant()
} else {
$low = ""
}
$score = 0
if ($name -match "python") { $score += 2 }
if ($low -match "uvicorn") { $score += 2 }
if ($low -match "src\.ops") { $score += 2 }
if ($low -match "gateway\s+start") { $score += 2 }
if ($low -match "fastapi_app") { $score += 1 }
$candidates += [pscustomobject]@{ Pid = [int]$p; Name = $name; Score = [int]$score; Cmd = $cmd }
}
$best = $candidates | Sort-Object -Property Score -Descending | Select-Object -First 1
if ($best -and $best.Score -ge 2) {
try {
$null = Get-Process -Id $best.Pid -ErrorAction Stop
Set-Content -Path $gwPidFile -Value "$($best.Pid)" -Encoding ascii
Write-Host "Wrote gateway.pid => $($best.Pid) ($($best.Name))" -ForegroundColor Green
} catch {
Warn "Cannot verify process for PID=$($best.Pid); not writing pid file."
}
} else {
Warn "Multiple owning processes for port $Port; cannot confidently pick gateway PID."
}
}
}
} catch {
Warn "Get-NetTCPConnection failed: $($_.Exception.Message)"
}
if ($WithWeixin) {
Write-Host ""
Write-Step "Weixin sidecar"
try {
& "$PSScriptRoot/weixin_status.ps1" -ChannelId $WeixinChannelId
} catch {
Warn "weixin status failed: $($_.Exception.Message)"
}
}
if ($WithWikiWorker) {
Write-Host ""
Write-Step "Wiki worker"
try {
& "$PSScriptRoot/status_wiki_worker.ps1"
} catch {
Warn "wiki worker status failed: $($_.Exception.Message)"
}
}