fix: recover local Readest launcher

This commit is contained in:
akai
2026-07-10 12:52:06 +08:00
parent da756eed47
commit acb7dd4c93
2 changed files with 67 additions and 3 deletions
+43 -3
View File
@@ -1,5 +1,5 @@
param(
[string]$Remote = "origin",
[string]$Remote = "akai-tools",
[string]$Branch = "codex/readest-inline-review-mode",
[switch]$SkipPull,
[switch]$CheckOnly,
@@ -62,14 +62,54 @@ function Stop-OldReadestDev {
ForEach-Object {
Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue
}
$portConnection = Get-NetTCPConnection -State Listen -LocalPort 3000 -ErrorAction SilentlyContinue |
Select-Object -First 1
if (-not $portConnection) {
return
}
$ownerPid = $portConnection.OwningProcess
$processLineage = @()
$lineagePid = $ownerPid
while ($lineagePid -and $processLineage.Count -lt 8) {
$lineageProcess = Get-CimInstance Win32_Process -Filter "ProcessId = $lineagePid" -ErrorAction SilentlyContinue
if (-not $lineageProcess) {
break
}
$processLineage += $lineageProcess
$lineagePid = $lineageProcess.ParentProcessId
}
$isReadestDev = $processLineage | Where-Object {
$_.Name -ieq "Readest.exe" -or
($_.CommandLine -and
$_.CommandLine -match "(?i)readest" -and
$_.CommandLine -match "(?i)next(.+?)dev|start-server\.js|@readest/readest-app|tauri(.+?)dev")
}
if (-not $isReadestDev) {
$owner = $processLineage | Select-Object -First 1
$ownerDescription = if ($owner.CommandLine) { $owner.CommandLine } else { "$($owner.Name) (PID $ownerPid)" }
throw "Port 3000 is occupied by an unrelated process: $ownerDescription. Stop it or launch Readest after freeing port 3000."
}
Write-Host "Stopping old Readest/Next listener on port 3000 (PID $ownerPid)." -ForegroundColor Yellow
Stop-Process -Id $ownerPid -Force -ErrorAction SilentlyContinue
for ($attempt = 0; $attempt -lt 20; $attempt++) {
Start-Sleep -Milliseconds 250
if (-not (Get-NetTCPConnection -State Listen -LocalPort 3000 -ErrorAction SilentlyContinue)) {
return
}
}
throw "Port 3000 is still occupied after stopping the old Readest/Next process. Close the old development terminal and try again."
}
function Assert-CleanWorktree {
$status = (& git -C $RepoRoot status --porcelain)
$status = @(& git -C $RepoRoot status --porcelain --untracked-files=no --ignore-submodules=dirty)
if ($status) {
Write-Host ""
Write-Host "Local changes were found. The launcher will not pull or overwrite them:" -ForegroundColor Yellow
& git -C $RepoRoot status --short
$status | ForEach-Object { Write-Host $_ }
throw "Commit, stash, or discard local changes before launching the latest organization version."
}
}
+24
View File
@@ -0,0 +1,24 @@
$ErrorActionPreference = "Stop"
$ScriptPath = Join-Path $PSScriptRoot "open-readest-latest.ps1"
$ScriptText = Get-Content -LiteralPath $ScriptPath -Raw
function Assert-Match {
param(
[string]$Pattern,
[string]$Message
)
if ($ScriptText -notmatch $Pattern) {
throw $Message
}
}
Assert-Match '\[string\]\$Remote\s*=\s*"akai-tools"' "Launcher must pull from akai-tools by default."
Assert-Match 'status\s+--porcelain\s+--untracked-files=no\s+--ignore-submodules=dirty' "Clean check must ignore runtime logs and dirty submodule contents."
Assert-Match 'Get-NetTCPConnection[^\r\n]*-LocalPort\s+3000' "Launcher must inspect the Tauri dev port before starting."
Assert-Match 'Stop-Process[^\r\n]*-Id\s+\$ownerPid' "Launcher must stop an old Readest/Next process that owns port 3000."
Assert-Match 'Port 3000 is occupied' "Launcher must report an actionable error for an unrelated port owner."
Assert-Match 'Port 3000 is still occupied' "Launcher must wait for the previous dev server to release the port."
Write-Host "open-readest-latest launcher checks passed."