cmux NEXT agent chat: the compact prompt rail is back, and it lights the last prompts at the end of a chat
Leo-ask: ask-50f889c053
Leo-ask: ask-8dbc4a81e1
Takes back #23735: its off default hid the rail Leo wants; he asked for the compact rail back with its bottom fixed, not for no rail ("I didn't want the mini map"). off stays as a dogfood arm, and the list keeps #23735's overflow: hidden.
Takes back #22784: its full-height map (a dash per message under a view box) is deleted, not just un-defaulted. Leo, 2026-10-21: "Why did you turn it into a whole mini map? ... I didn't want the mini map."
In progress: fleet test run and gallery before/after are pending; links follow.
What Leo saw
On the nightly, the agent chat's left-edge prompt rail (#22228, the Codex rail) "felt short". He explained: "it wouldn't show the highlighted bottom text where I was scrolling at the bottom, and it just didn't go to the bottom. It didn't show the bottom bits being highlighted." Then #22784 replaced the rail with a full-height minimap, and #23735 turned the minimap off.
Cause
A rail with more prompts than its room (64 rows or 70% of the window) scrolls its own list and fades 2.5rem at an edge with more rows past it. To keep the lit band in view, it checked only the band's first row. So as the reader neared the end of a long chat, the list stopped moving once that first row was anywhere in the list. The band's later rows, which include the chat's last prompts, sat under the bottom fade or past the rail's end. Leo's chats are long, so his rail always scrolls.
Change
thread-minimap-layoutdefaults tocompact(#22228's rail). Thefullarm is gone withScrollMap.tsx,mapGeometry.ts, its CSS, its two tests and its gallery notes. Afulloverride stored before this change falls back tocompact.railListTop(model.ts) places the rail's list so the whole band shows clear of both fades. When the band holds the chat's last prompt, the list scrolls to its end, where no fade covers the last rows. When it holds the first prompt, the list scrolls to its start. Otherwise the list moves as little as it can (likeblock: "nearest"), so a steady scroll carries the rail along with the band instead of jumping it.- The wave: at rest, a row coming on screen brightens over the motion scale's micro step (120 ms) and a row leaving dims, so the band glides down the rail instead of flicking row by row. Lit rows are now the text at 75% (was 60%) over the resting 40%. Hover, scrub and Reduce Motion still switch at once.
- The rail itself is #22228's: same geometry, fisheye, card, click and scrub.
Tests
webviews/test/thread-minimap-default-compact.test.tsx (replaces thread-minimap-default-off):
- the shipped arm is
compact, the arms are exactlycompactandoff, and a storedfullfalls back; visibleTurns: atscrollTop = 0the first turn is lit; atscrollTop = maxthe last is, even when the last reply fills the view;railListTop: the list sits at its end for a band on the last prompt and at its start for one on the first, keeps a band two rows short of the end clear of the fade, leaves a band that is already clear alone, and moves by at most a row as the band steps;- an 80-prompt chat with no override draws the compact rail. At the transcript's max scroll, the last tick is lit and the list is at its end with no bottom fade. Back at 0, the first tick is lit with no top fade;
- with
off, no marks and Previous Turn still steps; - CSS: the band's opacity transition at rest, lit at 75% or more, none under Reduce Motion.
thread-minimap-motion reads the bar's transition as a list now: at rest it also transitions opacity.
Red/green: pending on the fleet (scripts/ci/run-webviews-tests.sh): the new test at 4fd67de22b9 (test only) and the minimap suites at the head.
Observed / Not run
- Observed: the pre-commit formatter on the touched files;
pr-overlapfound no overlapping open PR. - Not run yet: the fleet test runs above, gallery before/after, and a scroll recording.
Changelog
- Fixed: the agent chat's prompt rail is back, and scrolled to the end of a long chat it lights and shows the last prompts.
Webview only; no Swift change.
Agent session: cosmic-gray
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Brings back the compact prompt rail as the agent chat's thread minimap and fixes it so the last prompts in a long chat show lit at the end, even with the pointer resting on the rail.
thread-minimap-layoutnow defaults tocompact(wasoff);fulland the full-height map are deleted, and a storedfulloverride falls back tocompact.- The lit band tracks the scroll to the pixel, and the rail's list keeps the whole band clear of its edge fades, so at the end of a chat the last rows show lit instead of sitting under the bottom fade. The list follows the band even while a row is hovered (it used to hold still, leaving the last prompts unlit); the row under a resting pointer becomes the hovered one, and the on-screen prompts stay lit while hovering. Scrubbing still holds the list still.
- At rest the lit band glides: rows brighten over the 120 ms motion micro step as they come on screen and dim as they leave. The glide applies only without Reduce Motion, which switches every row at once, as do hover and scrub. Lit rows are 75% text brightness (was 60%).
Webview only; no Swift change.