Repository navigation
fix(tui): keep completion footer mounted on finish=tool-calls - #2679
Merged
Merged
Conversation
The scrollable transcript's last row (▣ Mode · model) flickered away for a frame when a toolcall flipped to completed: mid-loop finish="tool-calls" unmounted the footer, and height growth could leave sticky bottom one row short. Keep the live last row mounted and re-snap after layout in follow mode.
A global id-order scan treated every later mid-loop tool-calls step as trailing after turn 1 and re-hid the live last footer on turn 2+. Key the prior-final check on parentID and count aborted rows as owning the turn footer.
Drop the sticky-follow half of this change and the Orchestrator-era trailing-row suppression. The footer is the transcript's last row and must stay mounted whenever the message is last — including mid-loop finish= "tool-calls" steps. Orchestrator is gone, so that gate has no remaining purpose and only caused the one-frame hole.
Extract isFinalAssistantFinish so the footer predicate and the duration gate agree on what a settled turn step is. Rename the length/cancelled test to say "settled non-tool-calls finish" — length is final under that rule — and point it at the non-last path it actually exercises. Refresh the spec commit range.
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.
Summary
▣ Mode · model · duration) is the scroll area's last row and must stay visible as a stable last line. It was being unmounted for a frame (and for the whole tool window) whenever the last assistant message'sfinishbecame"tool-calls".showFootergated onprops.last && finish !== "tool-calls". Writingfinish = "tool-calls"atfinish-step(actor tools write it even before the tool part flips tocompleted) made the<Match when={showFooter()}>drop the row until the next assistant message mounted.finish="tool-calls"steps. Duration still renders only whenfinishis set and ≠"tool-calls".Changes
packages/cli/src/cli/cmd/tui/util/assistant-footer.ts— pureshouldShowAssistantFooterpredicate (recovering || aborted || isFinal || isLast)packages/cli/src/cli/cmd/tui/routes/session/index.tsx— wireAssistantMessage.showFooterthrough the predicatepackages/cli/test/cli/tui/assistant-footer.test.ts— 7 regression cases, including "keeps the last row mounted after finish=tool-calls"Sticky-scroll / follow-bottom re-snap is intentionally out of scope for this PR.
Verification
bun run typecheck(packages/cli): PASSbun test ./test/cli/tui/ ./test/cli/cmd/tui/(packages/cli): PASS — 362 tests, 0 fail