feat: add Windows platform support#83
Conversation
- Add sysinfo dependency for Windows process info collection - Implement map_pid_to_sysinfo_open_paths for Windows - Implement get_process_info using sysinfo on Windows - Implement get_listening_ports using netstat on Windows - Add Windows-specific file_identity using size+mtime - Fix cmd_has_binary to handle Windows paths and .exe suffix
Port process info collection, port discovery, file identity, and open-path resolution to Windows using sysinfo crate and netstat. Based on upstream PR graykode#83 by csvkse with API fixes for sysinfo 0.32. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
graykode
left a comment
There was a problem hiding this comment.
thanks for tackling Windows. security pass is clean — sysinfo + a hardcoded netstat -ano invocation, no new network/shell-injection/dotfile surface. a few correctness things before this can land:
-
get_process_infowill report cpu_pct ~= 0 forever on Windows. sysinfo'sProcess::cpu_usage()is a delta between refreshes — the docs explicitly say "this value will be 0 unless you call refresh_processes at least twice" with at leastMINIMUM_CPU_UPDATE_INTERVALbetween them. each tick this code doesSystem::new()+ onerefresh_processes_specifics(...), so cpu_usage stays at 0 every tick. that breakshas_active_descendant(cpu_pct > cpu_thresholdnever fires) and the Working/Waiting threshold inapp.rs. fix is either to keep a long-livedSystembetween ticks and refresh twice, or to compute CPU% fromproc.run_time()/ lifetime ticks like the linux path does. as-is, every Windows session will look idle. -
cmd_has_binarychange leaks Windows semantics into linux/macOS. the old impl wastok.rsplit('/').next() == name(case-sensitive, no.exestrip). the new impl splits on\too, strips.exe, and useseq_ignore_ascii_case. those are the right rules on Windows but they silently change matching on every other platform —Claudeandclaude.exenow matchclaudeon linux/macOS. please gate the windows-only bits behind#[cfg(windows)](or split into two impls), so non-windows behavior is unchanged. -
doc comment on
cmd_has_binaryis misleading. it says "Also accepts process name on Windows when command is empty," but the function doesn't do that — theproc.name()fallback lives inget_process_info. either move the comment or reword it.
minor:
src/collector/process.rs:332clippy nit:rsplit(|c| c == '/' || c == '\\')→rsplit(['/', '\\']).map_pid_to_sysinfo_open_pathsreturns an emptypathsvec because sysinfo 0.32 has nofd_list. the comment is honest about that, but it does mean the open-file discovery fallback that lsof/libproc provide is gone — Claude session discovery on Windows leans entirely oncwd+sessions/{PID}.json. worth a one-line note in README/AGENTS.md that this is a known Windows limitation.netstat -anois parsed by skipping 4 header lines and matchingLISTENING. that's correct on en-US Windows 10/11 but could break on locales that translate the state column. fine for v1, just a heads-up.
overall the shape of the port/process plumbing is right — main blocker is the cpu% issue, second is the unintentional global change to cmd_has_binary. happy to re-review once those are addressed.
|
heads up — #89 (yangbinbin48) is doing essentially the same thing in parallel. nearly identical sysinfo plumbing, same before approving I'd like the two correctness items from the earlier review to be addressed in commits on this branch (so the PR author stays consistent rather than me pushing on top):
if it's easier I can push the patches directly (maintainerCanModify is on), but I'd rather you take them so the commit history stays cleanly attributed to you. let me know either way. |
|
closing as a duplicate of #89, which covers the same Windows core (sysinfo + netstat) and additionally extends the codex.rs side. plan is to land #89 as the Windows base, then take the dist/release-infrastructure pieces from #90 separately. really appreciate the work though — a couple of details from this PR are still useful and I'll fold them into #89 during review:
thanks for kicking this off! |
Summary
Test plan