Skip to content

Add persistent in-pane banner for closed-out hera worker tasks - #943

Open
anutron wants to merge 3 commits into
masterfrom
argus/build-a-ux-fix-for-closed-out
Open

Add persistent in-pane banner for closed-out hera worker tasks#943
anutron wants to merge 3 commits into
masterfrom
argus/build-a-ux-fix-for-closed-out

Conversation

@anutron

@anutron anutron commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • heraReattach's existing close-out refusal (dead-session worker/freelance task) now toggles a persistent, in-pane TerminalPane banner instead of only a 15s-TTL footer notice. First Enter arms the banner; a second, immediately-following Enter dismisses it and falls through to the pane's own existing dead-session rendering (replay content, or the placeholder) — no new PTY, process, or emulator is spawned for either press. Further Enters keep toggling.
  • Banner state lives on TerminalPane (closedOutBannerShown), reset by ResetVT() — already called on every hera pane rebind — so leaving and returning to the same closed-out row shows the banner again on the next Enter.
  • No new keybinding: this is a second consecutive Enter press.

Spec

  • OpenSpec change add-hera-closeout-banner created, implemented against, and archived in this PR (openspec/specs/hera-coordination/spec.md's "Enter refuses to restart a dead-session worker awaiting close-out" requirement updated + new scenarios).
  • Frontend parity: TUI-only by design (Hera mutations, including this one, are TUI-only — web/macOS Hera tabs stay read-only); noted explicitly as Non-Goals in the proposal.

Gotchas documented

  • context/knowledge/gotchas/hera-view.md — new add-hera-closeout-banner section: why both Enter presses reach the identical heraReattach call, why the toggle state lives on the pane not the App, why dismissal needs no new rendering path, and why there's no third state (a third press just re-arms the banner).

Test plan

  • internal/tui/terminal: table/unit tests for ShowClosedOutBanner/DismissClosedOutBanner/ClosedOutBannerShown, ResetVT clearing the flag, and Draw() priority over both the placeholder and replay content, plus a defensive "never over a live session" case.
  • internal/tui: SimulationScreen smoke tests — first/second/third Enter toggle behavior with status-bar message assertions, and a leave-and-return test proving the banner resets per visit.
  • make pre-pr run clean: build, vet, fmt-check, lint-pr (0 issues) all pass. vuln fails only on pre-existing Go-stdlib-only CVEs (toolchain, continue-on-error in CI, unrelated to this diff). test-cover-gate passes at 88.7% (run with this sandbox's own ARGUS_TASK_ID/ARGUS_ARCHETYPE/ARGUS_MODEL env vars scrubbed — otherwise they leak into two unrelated internal/agent profile-env subprocess tests, a known pre-existing sandbox-only false failure, confirmed reproducing identically with this diff absent).
  • Touched-package coverage: internal/tui/terminal 96.2%, all new code paths 100%.

🤖 Generated with Claude Code

@anutron
anutron force-pushed the argus/build-a-ux-fix-for-closed-out branch from 9321517 to 09960d2 Compare August 21, 2026 22:07
Enter on a closed-out worker/freelance row used to only set a 15s-TTL
footer notice and leave the pane's own content unchanged. The first
Enter now arms a persistent TerminalPane banner explaining the state;
a second, immediately-following Enter dismisses it and falls through
to the pane's existing dead-session rendering (replay content, or the
placeholder) — no new PTY, process, or emulator is spawned either way.
SetTaskID's eager loadSessionLog call was always undone by the very
next ResetVT call in the standard SetTaskID -> ResetVT -> SetSession
bind sequence every caller uses (bindPane, reconcileOne, onTaskSelect),
regardless of whether the prior session was live. Move the reload into
SetSession itself, the only step that knows the definitive new session
value, fixing the closed-out banner's dismiss-to-replay path (and the
same passive dead-session replay for ordinary panes).
@anutron
anutron force-pushed the argus/build-a-ux-fix-for-closed-out branch from 7bd2116 to 10c3e58 Compare August 23, 2026 04:30
A finished Claude Code session's on-disk log ends with CSI ?1049l
(alt-screen exit) followed by its own "Resume this session with:
claude --resume <uuid>" hint printed to the restored main buffer.
Feeding the full log through the replay emulator faithfully
reconstructs that hint as the terminal's true final state, which
buries the actual conversation the instant alt-screen tears down —
correct emulation, but a much less useful "last known output" view
than intended.

truncateAtFinalAltScreenExit trims the replay's byte window to end
just before the last alt-screen-exit sequence, so asyncReplayRebuild
never processes the teardown or the post-exit hint. Gated by a new
finalFrame parameter (true from EagerReplayBuild, !alive from Draw's
cache-miss kick) so a live session's real-time scrollback — where a
mid-session alt-screen toggle is genuine content, not a teardown to
hide — is never truncated.
@github-actions

Copy link
Copy Markdown

Merging this branch will increase overall coverage

Impacted Packages Coverage Δ 🤖
github.com/drn/argus/internal/tui 83.30% (+0.02%) 👍
github.com/drn/argus/internal/tui/terminal 96.91% (+0.79%) 👍

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/drn/argus/internal/tui/heraactions.go 76.53% (+0.32%) 588 (+8) 450 (+8) 138 👍
github.com/drn/argus/internal/tui/terminal/terminalpane.go 97.17% (+0.85%) 883 (+42) 858 (+48) 25 (-6) 👍

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

Changed unit test files

  • github.com/drn/argus/internal/tui/heraactions_test.go
  • github.com/drn/argus/internal/tui/terminal/closedoutbanner_test.go
  • github.com/drn/argus/internal/tui/terminal/terminalpane_test.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant