Files
Zachary D. Rowitsch 38e6dcc34a chore: archive v1.0 phase directories to milestones/v1.0-phases/
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 01:33:15 -04:00

199 lines
10 KiB
Markdown

---
phase: 02-interactive-tui
plan: 02
type: execute
wave: 2
depends_on: ["02-01"]
files_modified:
- tcptop/src/tui/app.rs
- tcptop/src/tui/draw.rs
- tcptop/src/tui/event.rs
- tcptop/src/main.rs
autonomous: false
requirements:
- DISP-03
- DISP-07
- FILT-01
- FILT-02
- FILT-03
- FILT-04
must_haves:
truths:
- "User can sort the table by any column using mnemonic keys (r/R/p/n/s/t/a/A/P) and Tab+Enter"
- "User can press '/' to enter filter mode, type to filter live by IP/port/process, Esc to clear"
- "User can launch with --port 443 and see only connections on port 443"
- "User can launch with --pid 1234 or --process nginx to see only matching connections"
- "User can launch with --tcp or --udp to see only one protocol"
- "User can launch with --interface eth0 to see only that interface (logged as warning if not yet wired to collector)"
artifacts:
- path: "tcptop/src/tui/event.rs"
provides: "Full keyboard handler with sort keys, filter mode, Tab/Enter navigation"
contains: "toggle_sort"
- path: "tcptop/src/tui/app.rs"
provides: "Filter and sort logic"
contains: "filter_records"
- path: "tcptop/src/main.rs"
provides: "CLI filters wired to App"
contains: "CliFilters"
key_links:
- from: "tcptop/src/main.rs"
to: "tcptop/src/tui/app.rs"
via: "CliFilters struct populated from Cli args"
pattern: "cli_filters"
- from: "tcptop/src/tui/event.rs"
to: "tcptop/src/tui/app.rs"
via: "toggle_sort and input_mode changes"
pattern: "toggle_sort"
---
<objective>
Verify and polish the interactive features: sorting, filtering, CLI flags, and visual polish. Ensure all keyboard interactions work correctly and CLI filter flags actually filter connections.
Purpose: Complete the interactive experience -- sorting, searching, and CLI-level filtering make the tool useful for investigating specific connections.
Output: Fully interactive TUI where all keyboard shortcuts and CLI flags work as specified in D-01 through D-15.
</objective>
<execution_context>
@/Users/zrowitsch/local_src/tcptop/.claude/get-shit-done/workflows/execute-plan.md
@/Users/zrowitsch/local_src/tcptop/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/02-interactive-tui/02-CONTEXT.md
@.planning/phases/02-interactive-tui/02-RESEARCH.md
@.planning/phases/02-interactive-tui/02-01-SUMMARY.md
</context>
<tasks>
<task type="auto">
<name>Task 1: Verify and fix sorting, filtering, and keyboard interactions</name>
<read_first>
- tcptop/src/tui/app.rs (App struct, sort_records, filter_records, toggle_sort from Plan 01)
- tcptop/src/tui/event.rs (handle_event from Plan 01)
- tcptop/src/tui/draw.rs (draw functions from Plan 01)
- tcptop/src/main.rs (event loop wiring from Plan 01)
- .planning/phases/02-interactive-tui/02-CONTEXT.md (D-06 sort spec, D-07 filter spec)
</read_first>
<files>tcptop/src/tui/app.rs, tcptop/src/tui/event.rs, tcptop/src/tui/draw.rs</files>
<action>
Read all TUI source files created by Plan 01 and verify every decision from CONTEXT.md is implemented correctly. Fix any gaps or bugs:
1. **Sort verification (D-06, DISP-03):**
- Verify `toggle_sort()` toggles asc/desc when same column, switches column when different
- Verify `sort_records()` handles ALL SortColumn variants including LocalAddr and RemoteAddr (format as `addr:port` string then compare alphabetically)
- Verify Tab cycles `selected_header_col` correctly through visible columns (9 default, 13 with extras)
- Verify Enter maps `selected_header_col` index to the correct SortColumn enum
- The sort arrow indicator in the header must show on the CORRECT column matching `app.sort_column`
2. **Filter verification (D-07, DISP-07):**
- Verify filter-as-you-type works: in Filter mode, each char appended to `filter_text`, table re-filters on next tick
- Verify Esc clears `filter_text` AND resets to Normal mode
- Verify Enter keeps `filter_text` but switches to Normal mode (per D-07 vim-like behavior)
- Verify filter matches case-insensitively against: local addr, local port, remote addr, remote port, and process name
- Verify TableState selection is clamped after filter reduces the list (Pitfall 4 from research)
3. **CLI filter verification (FILT-01 through FILT-04):**
- Verify `filter_records()` applies CLI filters BEFORE the live filter:
- `port` filter: matches if local_port == port OR remote_port == port (FILT-01)
- `pid` filter: matches if record.pid == pid (FILT-02)
- `process` filter: case-insensitive substring match on process_name (FILT-02)
- `tcp_only`: filter to Protocol::Tcp only (FILT-04)
- `udp_only`: filter to Protocol::Udp only (FILT-04)
- For FILT-03 (--interface): add a `log::warn!("--interface filtering not yet connected to collector; will be available when collector supports per-interface attachment")` in main.rs if `cli.interface.is_some()`. The flag is accepted but interface-level filtering requires collector changes that are deferred.
4. **Visual polish:**
- Verify header shows TCP/UDP breakdown counts (per D-13): count how many records have Protocol::Tcp vs Protocol::Udp
- Verify status bar shows filter text when in Filter mode (per D-14)
- Verify help overlay lists ALL keybindings including the asterisk explanation (per D-12)
- Verify partial connections show asterisk: `"nginx*"` not `"nginx [PARTIAL]"` (per D-12)
5. **Edge cases:**
- Empty connection list: header shows "0 connections (0 TCP, 0 UDP)", table shows empty state, no crash
- Filter that matches nothing: table shows no rows, selection clamped to None
- Both --tcp and --udp specified: show nothing (logical AND, both can't be true). Add note: this is correct behavior -- the flags are mutually exclusive by nature.
If any of the above is missing from Plan 01's output, implement it. If already correct, move on.
</action>
<verify>
<automated>cd /Users/zrowitsch/local_src/tcptop && cargo check 2>&1 | tail -5</automated>
</verify>
<acceptance_criteria>
- tcptop/src/tui/app.rs `sort_records` handles all SortColumn variants (grep for each: `SortColumn::Proto`, `SortColumn::LocalAddr`, `SortColumn::RemoteAddr`, `SortColumn::Pid`, `SortColumn::Process`, `SortColumn::State`, `SortColumn::RateIn`, `SortColumn::RateOut`, `SortColumn::Rtt`)
- tcptop/src/tui/app.rs `filter_records` checks `cli_filters.port` against both `local_port` and `remote_port`
- tcptop/src/tui/app.rs `filter_records` checks `cli_filters.pid`
- tcptop/src/tui/app.rs `filter_records` checks `cli_filters.process` with case-insensitive match
- tcptop/src/tui/app.rs `filter_records` checks `cli_filters.tcp_only` and `cli_filters.udp_only`
- tcptop/src/tui/event.rs contains `KeyCode::Tab` handling
- tcptop/src/tui/event.rs contains `KeyCode::Enter` handling for header column sort
- tcptop/src/tui/draw.rs header rendering includes TCP and UDP count breakdown
- tcptop/src/tui/draw.rs help overlay contains `"* next to process name"` or similar asterisk explanation
- `cargo check` succeeds (exit code 0)
</acceptance_criteria>
<done>All sorting keys work (9 mnemonic shortcuts + Tab/Enter header navigation per D-06). Filter-as-you-type works with Esc clear and Enter keep (per D-07). CLI filters (--port, --pid, --process, --tcp, --udp) correctly filter connections. --interface flag accepted with warning log. Help overlay complete with asterisk explanation.</done>
</task>
<task type="checkpoint:human-verify" gate="blocking">
<name>Task 2: Verify TUI on Linux VM</name>
<files>none</files>
<action>
Human verification of the complete interactive TUI on a real Linux system with live network traffic.
What was built across Plans 01 and 02:
- Live connection table with 9 columns (Proto, Local Addr:Port, Remote Addr:Port, PID, Process, State, Rate In, Rate Out, RTT)
- Summary header with connection counts (TCP/UDP breakdown) and aggregate bandwidth
- Status bar showing sort column/direction and filter text
- Keyboard shortcuts: q/Ctrl-C quit, r/R/p/n/s/t/a/A/P sort, Tab/Enter header sort, j/k/arrows scroll, / filter, ? help, c toggle columns
- Bandwidth color coding (dim to bright based on rate)
- New connection green highlight, closing connection red highlight
- CLI flags: --port, --pid, --process, --tcp, --udp, --interval
Steps to verify:
1. Sync code to dev-debian VM (see .claude/memory/reference_dev_debian.md)
2. Build: `cargo xtask build-ebpf && cargo build`
3. Run: `sudo ./target/debug/tcptop`
4. Verify table shows live connections with all 9 columns
5. Verify header shows connection count with TCP/UDP breakdown and bandwidth totals
6. Press 'r' to sort by Rate In -- verify sort arrow appears, rows reorder
7. Press 'r' again -- verify sort direction toggles (ascending)
8. Press Tab a few times, then Enter -- verify column header highlights and sorts
9. Press '/' and type a process name (e.g., "ssh") -- verify table filters live
10. Press Esc -- verify filter clears
11. Press 'c' -- verify extra columns appear (Bytes In, Bytes Out, Pkts In, Pkts Out)
12. Press '?' -- verify help overlay appears with all keybindings
13. Press 'q' -- verify clean exit, terminal restored
14. Run with flags: `sudo ./target/debug/tcptop --port 22` -- verify only port 22 connections shown
15. Run with flags: `sudo ./target/debug/tcptop --tcp` -- verify only TCP connections shown
16. Run with flags: `sudo ./target/debug/tcptop --interval 2` -- verify slower refresh
</action>
<verify>Human visual and interactive verification on Linux VM</verify>
<done>Human confirms TUI renders correctly, all keyboard shortcuts work, CLI flags filter as expected, and terminal restores on exit. Type "approved" to continue or describe issues.</done>
</task>
</tasks>
<verification>
- `cargo check` passes
- All keyboard shortcuts from D-06 through D-08 functional
- CLI flags from FILT-01 through FILT-04 accepted and applied
- Table sorts correctly by all columns
- Filter-as-you-type works with Esc clear
- Visual verification on Linux VM confirms layout, colors, and interactions
</verification>
<success_criteria>
- User can sort by any column via keyboard (DISP-03)
- User can filter live with '/' search (DISP-07)
- CLI flags --port, --pid, --process, --tcp, --udp filter connections (FILT-01 through FILT-04)
- --interface flag accepted (FILT-03, warning logged since collector doesn't support per-interface yet)
- Human verification on Linux VM passes
</success_criteria>
<output>
After completion, create `.planning/phases/02-interactive-tui/02-02-SUMMARY.md`
</output>