fix(server): discover Windows ports without PowerShell [WIP] - #9520
fix(server): discover Windows ports without PowerShell [WIP]#9520UtkarshUsername wants to merge 17 commits into
Conversation
Apply exponential backoff when the sidecar fails and the spawned fallback serves instead, so a stalled sidecar no longer hot-loops PowerShell. Skip pid 0 in the Rust process table so one kernel entry cannot fail the whole event decode. Revert the Windows sidecar packaging added for the removed native dependency.
|
Note 🤖 GPT-6 Astra (preview) responding on behalf of Theo This note is part of an automated cleanup pass. Carryover from #6254 at 920f8251d9: retain listener-to-PID/process-name mapping and the interrupted-scan case, where a later scan must run normally. Check degraded discovery with a previously found non-common port so it does not disappear only because fallback probes common ports. Its old single-flight test does not start the first fork before awaiting the second scan, so do not copy that test unchanged. Keep terminal ownership fresh when reusing listener data. |
c9abc35 to
674d991
Compare
SunkenInTime
left a comment
There was a problem hiding this comment.
Tested this draft on Windows x64 in a dedicated worktree at c27fa4e1b131311051d609a344ca2c6f5e7262a2, including its incremental diff over #9476. Requesting changes for finding 1.
-
P2: reject failed or truncated PowerShell results before replacing the snapshot. At PortScanner.ts:547, stdout is parsed without checking
result.codeorresult.stdoutTruncated. ProcessRunner returns nonzero exits as ordinary results, and this call uses truncation mode. Starting with a valid listener, an exit-1/empty-stdout result clears it and resets cooldown; the next immediate scan launches PowerShell again. Truncated output has the same problem. Two added regression cases fail: expected one retained listener and two total launches, received zero listeners and three launches. Validate exit status and completeness before parsing, route invalid results through the existing failure branch, and add both cases to the suite. -
Separate existing Windows issue: rapid terminal restart followed by close crashes with
Signals not supported on windows.The adapter, node-pty dependency, and explicit signal path predate these PRs; a standalone reproduction also fails. This needs a separate close-before-ready fix and is not the reason for requesting changes here. -
Nonblocking cleanup: add direct response, timeout, interruption, and restart coverage for the new client command. Consider sharing its repeated request lifecycle machinery. Also consider matching #9476's backoff when native discovery fails but PowerShell succeeds: this scanner resets failures and resumes PowerShell every scan, which may be an intentional compatibility choice.
Existing validation passes: bun fmt, bun lint, bun typecheck, 144 focused TypeScript tests, 18 Rust tests, Rust formatting, and release build. Native probes verified IPv4/IPv6 ownership and closed-listener removal; real PTY/RPC checks verified Node activity, terminal ownership, Ctrl+C, and port removal. The two additional failure cases above fail. This was not an installer, sustained CPU, or separate #9520 frontend acceptance run.
Blueprint review and design report includes numbered findings, the required correction, architecture, and full evidence. Download the evidence bundle and regression cases.
What Changed
windowsListenerscommand to the existing native resource-monitor sidecarGetExtendedTcpTableDepends on #9476. The local branches are managed as a
gh-stackchain. GitHub cannot base this upstream PR directly on the parent branch because both contribution branches live in a fork.Why
Windows preview discovery currently launches
Get-NetTCPConnectionevery three seconds and performs oneGet-Processcall per listener. On affected systems, those WMI-backed commands overlap, consume sustained CPU, and spin the fans.The resource-monitor sidecar already ships with the server and owns native process telemetry. Reading the Windows TCP table there removes PowerShell from the normal path without adding another native dependency. The fallback remains available for environments without a compatible sidecar, but failures no longer create an unbounded retry loop.
Closes #5900.
Checklist
Verification:
vp test run apps/server/src/preview/PortScanner.test.ts apps/server/src/resourceTelemetry/NativeTelemetryClient.test.ts apps/server/src/diagnostics/ProcessDiagnostics.test.ts apps/server/src/resourceTelemetry/Model.test.ts apps/server/src/resourceTelemetry/ResourceTelemetry.test.ts apps/server/src/resourceTelemetry/ResourceTelemetryHistory.test.ts(62 passed)git diff --checkModel: GPT-5 | Harness: Codex / T3 Code
Note
Discover Windows ports and process tables via native sidecar instead of PowerShell
processTableandwindowsListenerscommands to the resource-monitor sidecar, reading TCP listeners via the Windows IP Helper API (GetExtendedTcpTable) and process relationships via the sysinfo crate, bypassing PowerShell entirely on the happy pathRESOURCE_MONITOR_PROTOCOL_VERSIONfrom 2 to 4 across contracts, the sidecar, and all test fixtures; adds typed request/response schemas for both new commandsNativeTelemetryClient(NativeTelemetryClient.ts) exposesprocessTableandwindowsListenerseffects with 5-second response timeouts and pending-request cleanup on sidecar failurePortScanner(PortScanner.ts) now tries native listener discovery first, falling back to the PowerShell probe with capped exponential backoff (3s → 60s) and retaining the last successful fallback snapshot across failed retriesTerminalManager(Manager.ts) prefers native process-table snapshots for subprocess inspection, falls back to spawned PowerShell data on failure, and backs off polling delay (doubling up to 60s) after consecutive snapshot failuresRESOURCE_MONITOR_PROTOCOL_VERSIONconstant in resourceTelemetry.ts and main.rs must ship together. Windows fallback path still shells out to PowerShell when native discovery fails, so PowerShell removal is partial.Macroscope summarized 674d991. (Automatic summaries will resume when PR exits draft mode or review begins).