connect: row-based chat scrolling, nested tool calls, and a flat startup log - #84
Merged
Merged
Conversation
…p log The transcript viewport sliced by whole entries using estimated heights, so a message taller than the window could never be read: it appeared whole or not at all, and one scroll notch threw all of it away. The estimates also left dead space and phantom "N newer" markers. Everything on screen is now flattened to exact one-line screen rows and the window is a row range over that list, so up arrow brings a message to the top of the frame and reads down through it. Also drops the per-message padding rows to fit more of the conversation on screen. Tool calls no longer stand as their own turns: a call, its result and the collapsed fold nest under the message that produced them. Session milestones (asleep, waking, awake, cancelled) now land in the chat, so a nap between turns stops being an unexplained gap. The startup block's three-level phase tree becomes one flat ten-line log with build and setup output inline, opened with a single arrow instead of three. Live lines carry a pulsing mark.
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
Reworks the
agent session connectchat window: scrolling, how tool calls sit in the conversation, and the sandbox startup block.Scrolling is row-granular. The viewport sliced by whole transcript entries using estimated heights, so a message taller than the window could never be read — it appeared whole or not at all, and one scroll notch threw all of it away. Those estimates also had to leave slack for their own rounding errors, which showed up as dead space and a phantom
… 1 newer (scroll or ↓)marker. Everything on screen (startup block, messages, tool chatter, in-flight sends, the live streaming tail) is now flattened to exact one-line screen rows in a newsrc/ui/transcriptRows.ts, and the window is a row range over that list.↑brings a message to the top of the frame; a message too tall to fit scrolls row-by-row through it before the highlight moves on.TOP_PAD4→2, composer interior 3→1 (it grows as you type). ~5 more content lines on a 24-row terminal.Tool calls nest under their parent message instead of standing as their own turns:
Expanded (ctrl+r or
→) each line keeps the glyph that says what it is —● Bash(pytest -q)then⎿ 3 failed, 41 passed— since the indent already conveys nesting. The live⏺ Running Bash(…)…line nests in exactly the spot its⎿result will land, so nothing jumps when it arrives.The chat is an event log. Session milestones land in the transcript in feed order, so a nap between turns stops being an unexplained gap:
Deliberately a short list (asleep, waking, awake, retry, cancelled) — provisioning detail stays in the startup block rather than burying the chat.
The startup block is one flat log. It was a three-level tree (session → sandbox → phases → each phase's own log tail) drilled into with
→, which hid build output three keystrokes deep and split one chronological story across separate per-phase tails. Now a headline plus the last 10 lines of everything that happened, output inline:Four pieces of drill-down state and the whole modal step-cursor key mode are gone;
→/←show and hide the log.sandboxStepLine,SandboxStep,RUNNING_TAIL_LINESandFINISHED_LOG_LINESare deleted.Live marks pulse. One shared 700ms timer, so every
⏺on screen breathes in step. The blink is a colour swap (bone → grey), not Ink'sdimColor— that emits\x1b[2m, which several terminals drop when a 24-bit foreground is also set, so the blink would have silently done nothing there. The timer only runs while something is in flight.Overflow bugs fixed along the way
Both were the historic failure mode of this file, where a frame taller than the pane scrolls Ink's render region and smears stale rows:
rowViewportcould let the two hidden-count markers exceed a small budget. Now guaranteed never to, with a brute-force test over ~26k input combinations.Test plan
npx tsc --noEmitcleannpx vitest run— 375 passing, with new coverage forrowViewport,itemRows, scroll anchors,snapToEntry,layOutItems,sessionLogText,lastLinesandfitLines