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

6.3 KiB

Phase 2: Interactive TUI - Context

Gathered: 2026-03-21 Status: Ready for planning

## Phase Boundary

Real-time sortable connection table with filtering, keyboard controls, and summary header using ratatui. Replaces the Phase 1 streaming stdout output with a full interactive TUI. CSV logging, documentation, packaging, and macOS backend are separate phases.

## Implementation Decisions

Table layout and columns

  • D-01: Default column set (8 columns): Proto, Local Addr:Port, Remote Addr:Port, PID, Process, State, Rate In, Rate Out, RTT
  • D-02: Addresses displayed as combined addr:port in a single column (e.g., 192.168.1.5:443). IPv6 abbreviated where possible.
  • D-03: PID and Process Name as separate columns (not combined like nginx (1234))
  • D-04: Additional columns (Bytes In/Out, Packets In/Out) available via toggle key (c), not shown by default
  • D-05: Narrow terminals (< ~120 cols) handled by truncating addresses and process names with ellipsis. Columns stay, content gets trimmed.

Keyboard interaction

  • D-06: Two sorting methods available simultaneously:
    • Mnemonic single-key shortcuts: r = rate in, R = rate out, p = PID, n = process name, s = state, t = RTT, a = local addr, A = remote addr, P = protocol. Press same key again to toggle asc/desc.
    • Tab to navigate column headers, Enter to sort by selected column. More discoverable for new users.
  • D-07: / opens filter-as-you-type mode. Table filters live as you type. Matches IP, port, or process name. Esc clears the filter. Like vim's / search.
  • D-08: Standard keyboard shortcuts: q / Ctrl-C quit, ? help overlay, arrows / j/k scroll rows, / filter, c toggle columns.
  • D-09: No detail pane. Table is the sole view. All relevant data visible in columns.

Color and visual treatment

  • D-10: Bandwidth color coding uses intensity-based single color (dim to bright). Low bandwidth = dim text, high bandwidth = bright/bold. No multi-color heat map.
  • D-11: New connections get a subtle green background highlight for one refresh cycle. Closing connections get a red background highlight for one cycle before removal. (Implements D-13 from Phase 1.)
  • D-12: Pre-existing/partial connections (from /proc/net/tcp bootstrap) indicated with asterisk on process name (e.g., nginx*). Help overlay explains the asterisk.

Summary header

  • D-13: Header is 3-4 lines: connection counts with TCP/UDP breakdown, aggregate bandwidth in/out, separator line. Like top's load average line — quick glance stats.
  • D-14: Active sort column and filter shown in a bottom status bar (vim-style), NOT in the header. E.g., Sort: Rate In ↓ Filter: nginx
  • D-15: Header stays pure aggregate stats. Status bar at bottom for UI state (sort, filter, help hint).

Claude's Discretion

  • Exact ratatui widget composition and layout structure
  • Terminal initialization/restoration details
  • Internal event loop architecture (how TUI rendering interleaves with data updates)
  • Column width ratios and resize behavior
  • Exact intensity gradient thresholds for bandwidth display
  • Help overlay content and layout
  • How to integrate clap CLI args with the existing main.rs event loop
## Specific Ideas
  • The tool should feel like htop for network connections — familiar keyboard model, information-dense but not cluttered.
  • Phase 1 deferred a toggle between human-readable and raw byte display via keypress — this is now in scope for Phase 2 (could be part of the c column toggle or a separate key).
  • Phase 1's output.rs has pure formatting helpers (format_bytes, format_rate, format_rtt) that should be reused for TUI cell rendering.

<canonical_refs>

Canonical References

Downstream agents MUST read these before planning or implementing.

Data model and integration points

  • tcptop/src/model.rs — ConnectionRecord, ConnectionKey, Protocol, TcpState structs with all displayable fields
  • tcptop/src/aggregator.rs — ConnectionTable with update() and tick() methods; tick() returns (active, closed) tuples
  • tcptop/src/main.rs — Current event loop with tokio::select! on rx.recv(), tick.tick(), and signal handlers
  • tcptop/src/output.rs — Formatting helpers (format_bytes, format_rate, format_rtt) to reuse in TUI

Dependencies and config

  • Cargo.toml (workspace root) — Workspace dependencies; ratatui + crossterm need to be added
  • tcptop/Cargo.toml — Userspace crate deps; clap 4.6 with derive is available but unused
  • .planning/REQUIREMENTS.md — DISP-01 through DISP-08, FILT-01 through FILT-04
  • CLAUDE.md §Technology Stack — Ratatui 0.30.x, Crossterm 0.28.x+, clap 4.6.x recommendations

</canonical_refs>

<code_context>

Existing Code Insights

Reusable Assets

  • output.rs: format_bytes(u64), format_rate(f64), format_rtt(Option<u32>) — pure formatting, no I/O, reuse directly in TUI cells
  • model.rs: ConnectionRecord has all fields needed for display (rate_in/out, rtt_us, is_partial, is_closed)
  • model.rs: TcpState::as_str() for state column display

Established Patterns

  • Tokio async event loop with select! on collector channel + periodic tick — TUI render fits naturally into the tick branch
  • mpsc channel (4096 buffer) from collector to aggregator — no changes needed
  • ConnectionTable::tick() returns (Vec<&ConnectionRecord>, Vec<ConnectionRecord>) — active refs + owned closed records

Integration Points

  • Replace tcptop::output::print_tick() call in main.rs with TUI rendering
  • Add crossterm terminal init/restore around the event loop
  • Add crossterm event polling (keyboard input) as a new branch in the select! loop
  • clap derive structs in main.rs for CLI flags (--port, --pid, --process, --interface, --tcp, --udp, --interval)

</code_context>

## Deferred Ideas
  • UDP flow idle timeout configurable via CLI flag — Phase 3 or backlog
  • --batch or --once mode preserving stdout output — evaluate in Phase 3
  • Reverse DNS resolution for remote IPs — v2 requirement (DISP-V2-01)
  • Connection duration/age display — v2 requirement (DISP-V2-02)
  • Freeze/pause display with 'p' key — v2 requirement (DISP-V2-03)

Phase: 02-interactive-tui Context gathered: 2026-03-21