Add live TUI dashboard (--ui) with a scan-flow screenshot#4
Merged
Conversation
`--ui` turns any mode (run/attach/scan) into a full-screen terminal dashboard instead of the scrolling log: one row per traced process with live syscall/event counters and a colour-coded verdict, a feed of recent detections, and an aggregate status bar. It is most useful for `scan`, where many processes are watched at once. Engine (tracer.rs): generalise the output sink from a bare event closure to a `Reporter` trait that also receives per-process `ProcStat` snapshots. `run` keeps its closure API (wrapped in an internal `FnReporter`), while a new `run_with` drives an arbitrary reporter. Progress snapshots are gated behind `Reporter::wants_refresh`, so the plain/JSON/test paths build no snapshots and pay only a counter increment — the hot path is unchanged. Refreshes fire on every detection and process-lifecycle change, throttled to ~20 fps otherwise. UI (ui.rs): a hand-rolled ANSI dashboard — no TUI dependency, so the supply chain stays `nix` + `libc`. Terminal size via a TIOCGWINSZ ioctl; a guard plus a SIGINT/SIGTERM handler always restore the alternate screen and cursor, even on Ctrl-C. The frame renderer is a pure function, unit-tested for width-fit, verdict rendering, and the event feed cap. CLI (wraith.rs): `--ui`/`--dashboard`; the dashboard also honours `--json`. Also: `scan` now excludes its own process and its entire ancestor chain (the shell/terminal that launched it), so a broad `--match` can't attach to — and hang on — the tool that started it. Docs: README gains a hero screenshot of the scan flow (docs/scan-demo.svg, an SVG rendered from a real captured dashboard frame) and a --ui section. 42 unit + 10 end-to-end tests, clippy clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01117vzFc51mLKYnKW2SnWzg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
--uiturns any mode (run/attach/scan) into a full-screen terminal dashboard instead of the scrolling log: one row per traced process with live syscall/event counters and a colour-coded verdict, a feed of recent detections, and an aggregate status bar. It is most useful forscan, where many processes are watched at once.Engine (tracer.rs): generalise the output sink from a bare event closure to a
Reportertrait that also receives per-processProcStatsnapshots.runkeeps its closure API (wrapped in an internalFnReporter), while a newrun_withdrives an arbitrary reporter. Progress snapshots are gated behindReporter::wants_refresh, so the plain/JSON/test paths build no snapshots and pay only a counter increment — the hot path is unchanged. Refreshes fire on every detection and process-lifecycle change, throttled to ~20 fps otherwise.UI (ui.rs): a hand-rolled ANSI dashboard — no TUI dependency, so the supply chain stays
nix+libc. Terminal size via a TIOCGWINSZ ioctl; a guard plus a SIGINT/SIGTERM handler always restore the alternate screen and cursor, even on Ctrl-C. The frame renderer is a pure function, unit-tested for width-fit, verdict rendering, and the event feed cap.CLI (wraith.rs):
--ui/--dashboard; the dashboard also honours--json. Also:scannow excludes its own process and its entire ancestor chain (the shell/terminal that launched it), so a broad--matchcan't attach to — and hang on — the tool that started it.Docs: README gains a hero screenshot of the scan flow (docs/scan-demo.svg, an SVG rendered from a real captured dashboard frame) and a --ui section.
42 unit + 10 end-to-end tests, clippy clean.
Claude-Session: https://claude.ai/code/session_01117vzFc51mLKYnKW2SnWzg