feat(c3): Containers log-follow ([f]) — live tail with pause/resume - #1030
Merged
noonghunna merged 8 commits intoAug 22, 2026
Merged
Conversation
…drill Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Tint token: bold (portable brighter default foreground on light AND dark terminals, no hue shift; bright_white no-ops on already-white themes). Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Tint token: underline (bold renders invisibly on the default foreground in common terminals — manual check on the maintainer rig, 2026-08-16). Follow/paused titles now use the rig's green/yellow state colors so the on/off state reads at a glance; the pause note is yellow with a resume hint and a symmetric green 'follow resumed' note (both display-only, never in the [Y] copy). Co-Authored-By: Claude <noreply@anthropic.com>
RichLog is append-only, so 'the previous batch loses its underline' needs a rewrite: the tick keeps a chronological display model (line/fresh/note) and re-renders #drill-logs from it while the user sits at the tail — earlier fresh lines drop back to plain, only the newest tick's lines stay underlined. While reading history the tick appends plain (no rewrite, no yank) and the next at-tail tick re-renders correctly. State notes (pause/resume) are recorded in the model so re-renders re-emit them in place; the [Y]-copy tail stays plain text. LivePane gains an at_bottom property for the gate. Co-Authored-By: Claude <noreply@anthropic.com>
paulp83
force-pushed
the
feat/c3-container-log-follow
branch
from
August 20, 2026 00:38
2ac259f to
9f7e451
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.
What
Adds a
[f]log-follow (live tail) to c3's Containers view Logs drill: newdocker logslines appear every ~2 s without re-pressing[l], with pause/resume and a live state indicator.How
container_logs(name, tail=200)service call. Nodocker logs -fsubprocess, no new service surface (services.pyuntouched).container-logsworker group withstream_container_logs, so a tick and a manual[l]/navigation snapshot never interleave; cancellation races self-heal via resync.RichLogis append-only, so the tick keeps a chronological display model (plain / newest-batch / state-note) and re-renders the pane from it while the user sits at the tail; while reading history (scrolled up) ticks append plain with no rewrite, and the next at-tail tick re-renders correctly.Live/Live ● following(green) /Live … paused(yellow); pause/resume notes are display-only.[Y]-copy tail stays plain text (markup stripped by the existing buffer; notes usebuffer=False); no background polling when leaving the Containers tab or mode 0 (disarm on leave, re-entry starts off); the followed container dying → death note + disarm; browsing to a different stopped row keeps the mode armed (tick no-ops).tui-core
LivePanegains tail-reader scroll-follow for every consumer: scrolling up stops auto-scroll (history stays readable while lines stream in), scrolling back to the bottom resumes it — gated on both the append-timescroll_endandRichLog.auto_scroll(which otherwise yanks the pane on every write). Plusset_title()and anat_bottomproperty.Tests
TestContainerLogFollow(subprocess-free — injectedFakeRunner, ticks driven by direct_log_follow_tick()calls, no real 2 s waits): binding/context gating, arm/pause/resume/disarm, tick dedupe + quiet-log no-op, resync, moving-underline batch tracking, note survival across re-render, scrolled-up plain append, navigation rebase, death/error disarms.at_bottomtests.f.Verified on a live rig: full c3 suite green (896 passed; the two failures are a pre-existing registry-reps count mismatch that fails at pre-feature commits, and a tab-bar focus timing flake that passes in isolation), plus a read-only live smoke test driving the production app against real docker (arm → 3 real ticks on an actively-logging container → pause → resume → navigate to a quiet container → disarm-on-tab-leave).
Design spec:
docs/superpowers/specs/2026-08-16-c3-container-log-follow-design.md.