Repository navigation
feat: Windows Adapter, Interactive TUI, and Smart Socket Analysis - #2
Conversation
…s and periodic data refresh.
…ies, including user, network, and service details.
…ons and documentation.
…ocess lookup by port on Windows.
… for process socket information.
…se builds, and code coverage.
… and code coverage.
There was a problem hiding this comment.
Pull request overview
This PR introduces significant cross-platform enhancements to witr-rs by adding Windows support, an interactive TUI for real-time process monitoring, and enriched socket state analysis. The changes establish a unified architecture across Windows, Linux, and macOS platforms while expanding CI/CD coverage to include multiple Linux distributions and explicit Apple Silicon support.
Key changes:
- Windows Native Support: Complete Windows adapter implementation using
netstatandtasklistcommands for process inspection, service detection, and network analysis - Interactive TUI: New terminal UI with tree view visualization, watch mode for real-time monitoring, and search/filter capabilities powered by ratatui and crossterm
- Smart Socket Analysis: Enhanced
SocketInfomodel providing human-readable explanations and workarounds for various socket states (TIME_WAIT, CLOSE_WAIT, etc.)
Reviewed changes
Copilot reviewed 33 out of 34 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
src/tui/mod.rs, src/tui/app.rs, src/tui/ui.rs, src/tui/run.rs |
New TUI module implementing interactive process monitoring with tree view, search filtering, and real-time updates |
src/core/models/socket.rs |
Enhanced SocketInfo with explanation/workaround fields and state enrichment logic for network diagnostics |
src/core/models/process.rs |
Extended Process model with socket list, CPU usage, and memory usage fields |
src/adapters/system.rs |
Refactored to use RefCell for interior mutability and unified socket info collection across platforms |
src/adapters/proc/windows/*.rs |
New Windows implementations for network parsing, service detection, and user ownership using native commands |
src/adapters/proc/linux/socketstate.rs, src/adapters/proc/darwin/socketstate.rs |
Updated to return SocketInfo objects instead of strings for consistency |
src/adapters/source/windows/service.rs |
Windows service detection using tasklist and sc commands |
src/main.rs |
Added watch mode CLI flag and logic to launch TUI for specified processes |
src/lib.rs |
Exposed new tui module as public API |
.github/workflows/ci.yml |
Enhanced CI with Linux distro matrix testing (Arch, Fedora) and Apple Silicon build targets |
Cargo.toml, Cargo.lock |
Added ratatui and crossterm dependencies for TUI functionality |
README.md |
Updated documentation with watch mode examples and feature status |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| sys: RefCell<System>, | ||
| } | ||
|
|
||
| impl RealSystem { | ||
| pub fn new() -> Self { | ||
| let mut sys = System::new_all(); | ||
| sys.refresh_all(); | ||
| Self { sys } | ||
| Self { | ||
| sys: RefCell::new(sys), |
There was a problem hiding this comment.
Using RefCell to wrap the entire System object introduces runtime borrow checking overhead and potential panic risks if multiple borrows occur. While this enables interior mutability for the refresh operations, it's error-prone. Consider refactoring the SystemProvider trait to allow mutable methods, or use RefCell more selectively only for the fields that need mutation. Also, ensure all borrows are properly scoped to avoid holding references longer than necessary.
| } | ||
|
|
||
| pub fn get_socket_state(_pid: u32) -> HashMap<u64, String> { | ||
| pub fn get_socket_state(_pid: u32) -> HashMap<u64, SocketInfo> { |
There was a problem hiding this comment.
The socket state parsing returns HashMap<u64, SocketInfo> but the old implementation returned HashMap<u64, String>. This is a breaking API change. While the PR description mentions "Architecture Refactor", ensure that all consumers of this API are updated accordingly. The stub implementation at the end of the file has been updated correctly, which is good.
| pub fn get_socket_state(_pid: u32) -> HashMap<u64, SocketInfo> { | |
| pub fn get_socket_state(_pid: u32) -> HashMap<u64, String> { |
| let output = "COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME | ||
| main 123 user 10u IPv4 0x... 0t0 TCP 127.0.0.1:8080 (LISTEN) | ||
| main 123 user 20u IPv4 0x... 0t0 TCP 127.0.0.1:5432 (ESTABLISHED) | ||
| main 123 user 20u IPv4 0x... 0t0 TCP 127.0.0.1:5432->1.1.1.1:80 (ESTABLISHED) |
There was a problem hiding this comment.
The test data was updated to show "127.0.0.1:5432->1.1.1.1:80" but the comment on line 25 states "NAME field format: 127.0.0.1:5432->127.0.0.1:5433 (ESTABLISHED)". This inconsistency between the comment and test data could cause confusion. Update the comment to match the test data or vice versa.
| @@ -3,10 +3,6 @@ use crate::core::models::InspectionResult; | |||
| use colored::Colorize; | |||
|
|
|||
| pub fn print_report(results: &[InspectionResult], colors: &ColorScheme) { | |||
There was a problem hiding this comment.
The removal of the header lines for the security report might make the output less clear when security scanning is performed. The removed lines provided clear visual separation and identification of the report type. Consider whether this removal was intentional, and if so, ensure the calling code or context provides adequate framing for the security report output.
| pub fn print_report(results: &[InspectionResult], colors: &ColorScheme) { | |
| pub fn print_report(results: &[InspectionResult], colors: &ColorScheme) { | |
| println!("{}", "=== Security Scan Report ===".bold()); | |
| println!(); |
|
|
||
| **Production Ready** - All core features implemented and tested. | ||
|
|
||
| ### Completed Features |
There was a problem hiding this comment.
The README.md has a line marker "0 |----" at line 179 which appears to be a diff artifact or formatting error. This should be removed as it's not valid markdown content and will render incorrectly.
| */ | ||
|
|
||
| // Placeholder to indicate Global Mode is active but limited | ||
| app.title = " Witr-RS Global Monitor (Detail Fetch Disabled - CPU Optimized) ".to_string(); |
There was a problem hiding this comment.
The message "Detail Fetch Disabled - CPU Optimized" uses inconsistent terminology. The comment on line 89 says "resource intensive" and "optimize performance later", but the user-facing message says "CPU Optimized" which implies it's a feature rather than a limitation. Consider making the message more transparent, such as "Global Monitor (Optimization in Progress)" or "Global Monitor - Process Details Coming Soon".
| fn test_parse_tcp_states() { | ||
| let content = " sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode | ||
| 0: 0100007F:1F90 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 21623 1 0000000000000000 100 0 0 10 0 | ||
| 0: 00000000:1F90 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 21623 1 0000000000000000 100 0 0 10 0 |
There was a problem hiding this comment.
The test data shows a local address of "0100007F:1F90" in the old code which was changed to "00000000:1F90" (representing 0.0.0.0:8080 instead of 127.0.0.1:8080). This changes the test's semantic meaning - LISTEN on 0.0.0.0 means listening on all interfaces, while 127.0.0.1 means localhost only. Ensure this change is intentional and doesn't mask a parsing issue.
| 0: 00000000:1F90 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 21623 1 0000000000000000 100 0 0 10 0 | |
| 0: 0100007F:1F90 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 21623 1 0000000000000000 100 0 0 10 0 |
| if let Some(s) = states.get(&24159) { | ||
| assert_eq!(s.state, "ESTABLISHED"); | ||
| assert_eq!(s.port, 631); // 0277 hex -> 631 | ||
| } |
There was a problem hiding this comment.
The test comment states "0277 hex -> 631" but should verify the calculation is correct. 0x0277 = 2256 + 716 + 7 = 631 decimal. This is correct. However, the assertion only checks the state and port, but doesn't verify the local_addr format which the new implementation now provides. Consider adding assertions for local_addr and remote_addr to ensure the parsing is complete.
| "Global Watch Mode is currently disabled/WIP (Performance Optimization pending)." | ||
| ); | ||
| eprintln!("Please specify a process target (PID, Name, or Port)."); | ||
| eprintln!("Usage: witr-rs <NAME> --watch OR witr-rs -p <PID> --watch"); |
There was a problem hiding this comment.
The error messages use inconsistent quoting styles. Line 75 says "Global Watch Mode is currently disabled/WIP" without quotes around the mode name, while line 79 uses escaped quotes in "witr-rs --watch". Consider using consistent formatting for better readability, such as using backticks or quotes consistently for command-line arguments and mode names.
| "Global Watch Mode is currently disabled/WIP (Performance Optimization pending)." | |
| ); | |
| eprintln!("Please specify a process target (PID, Name, or Port)."); | |
| eprintln!("Usage: witr-rs <NAME> --watch OR witr-rs -p <PID> --watch"); | |
| "Global `watch` mode is currently disabled/WIP (performance optimizations pending)." | |
| ); | |
| eprintln!("Please specify a process target (PID, Name, or Port)."); | |
| eprintln!("Usage: `witr-rs <NAME> --watch` OR `witr-rs -p <PID> --watch`"); |
| artifact_name: witr-rs.exe | ||
| asset_name: witr-rs-windows-amd64.exe | ||
| - os: macos-latest | ||
| - os: macos-14 # Intel build on M1 runner |
There was a problem hiding this comment.
The CI workflow is configured to use "macos-14" which is an Apple Silicon (M1) runner, but the comment on line 111 says "Intel build on M1 runner". This is contradictory - macOS-14 runners are Apple Silicon (ARM64) by default, not Intel. If you want to build for x86_64 on an Apple Silicon runner, you need to ensure proper cross-compilation setup. Verify that building x86_64-apple-darwin on macos-14 works correctly, or consider using macos-13 for Intel builds.
| - os: macos-14 # Intel build on M1 runner | |
| - os: macos-14 # x86_64 (Intel-compatible) build on Apple Silicon runner |
Summary
This PR significantly expands
witr-rscapabilities by introducing a robust Windows adapter, an interactive Terminal UI (TUI), and "Smart Socket Analysis" for detailed network diagnostics. It also solidifies the project's stability with a comprehensive, cross-platform CI/CD pipeline supporting Windows, Linux (including Arch/Fedora), and macOS (Intel & Apple Silicon).Key Features
netstat,tasklist).SocketInfomodel providing human-readable Explanations and Workarounds for socket states (e.g.,TIME_WAIT).Technical Enhancements
x86_64andaarch64.SocketInforeturn types across Windows, Linux, and macOS adapters to ensure consistent core logic executionQuality Assurance
cargo clippy(linting) andcargo fmt.netstat -anoparsing).