feat(check): live progress TUI for multi check via PresenterActor (MULTI-1369)#146
Open
RobbieMcKinstry wants to merge 1 commit into
Open
feat(check): live progress TUI for multi check via PresenterActor (MULTI-1369)#146RobbieMcKinstry wants to merge 1 commit into
multi check via PresenterActor (MULTI-1369)#146RobbieMcKinstry wants to merge 1 commit into
Conversation
Contributor
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
a4badc5 to
c219b3c
Compare
…MULTI-1369) Surface what `multi check` is doing *while it runs*. A fourth, display-only Kameo actor (`PresenterActor`) consumes a fire-and-forget `UiEvent` stream emitted by the discovery/execution pipeline at each per-check milestone (queued → started → retrying → settled) and renders progress through a `RenderBackend` chosen at spawn from whether stdout is a TTY: - `InlineTuiBackend` (TTY): a Ratatui inline viewport — a requirement→check tree + progress gauge with per-check spinners and climbing elapsed timers (the liveness signal). Completed requirements flush into permanent scrollback via `insert_before` as they finish, so the viewport only holds in-flight work and the full record persists by end-of-run with no separate reprint. Never uses the alternate screen. - `HeartbeatBackend` (non-TTY): a slow-cadence one-line progress heartbeat on stderr so piped/CI runs show liveness. stdout is left untouched — the reporting actor's byte-for-byte report and 0/1 exit code are preserved exactly as MULTI-1368. - `NullBackend` / `RecordingBackend` (tests): headless. Events are a concrete enum (exhaustiveness, one `Message` impl, no per-message boxing); polymorphism lives on the backend. A separate periodic `Tick` drives redraws so animations keep moving between events. The presenter holds a single `PresenterState` view-model with from-scratch tally scans (retry-safe), and the flushed TTY record reuses the reporting actor's exact text + AND-aggregation, so the TTY scrollback and non-TTY stdout differ only in inter-requirement order (completion vs declaration), never per-requirement content. Terminal restore is covered on all four paths: `on_stop` (normal/error), a panic hook (panic), and an async-signal-safe SIGINT handler (Ctrl-C) that shows the cursor and exits 130. The redraw ticker is owned by the actor and joined on stop. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
c219b3c to
67863eb
Compare
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.

Surface what
multi checkis doing while it runs. A fourth, display-onlyKameo actor (
PresenterActor) consumes a fire-and-forgetUiEventstreamemitted by the discovery/execution pipeline at each per-check milestone
(queued → started → retrying → settled) and renders progress through a
RenderBackendchosen at spawn from whether stdout is a TTY:InlineTuiBackend(TTY): a Ratatui inline viewport — a requirement→checktree + progress gauge with per-check spinners and climbing elapsed timers
(the liveness signal). Completed requirements flush into permanent scrollback
via
insert_beforeas they finish, so the viewport only holds in-flight workand the full record persists by end-of-run with no separate reprint. Never
uses the alternate screen.
HeartbeatBackend(non-TTY): a slow-cadence one-line progress heartbeat onstderr so piped/CI runs show liveness. stdout is left untouched — the
reporting actor's byte-for-byte report and 0/1 exit code are preserved exactly
as MULTI-1368.
NullBackend/RecordingBackend(tests): headless.Events are a concrete enum (exhaustiveness, one
Messageimpl, no per-messageboxing); polymorphism lives on the backend. A separate periodic
Tickdrivesredraws so animations keep moving between events. The presenter holds a single
PresenterStateview-model with from-scratch tally scans (retry-safe), and theflushed TTY record reuses the reporting actor's exact text + AND-aggregation, so
the TTY scrollback and non-TTY stdout differ only in inter-requirement order
(completion vs declaration), never per-requirement content.
Terminal restore is covered on all four paths:
on_stop(normal/error), a panichook (panic), and an async-signal-safe SIGINT handler (Ctrl-C) that shows the
cursor and exits 130. The redraw ticker is owned by the actor and joined on stop.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com