Skip to content

Agent chat: the wave rail draws only the ticks in its view (36 ms to 1.7 ms a frame on a 2,000-row chat) - #25152

Merged
teamleaderleo merged 9 commits into
feat-cmux-nextfrom
rail-opus-rail-minimap-setting
Oct 26, 2026
Merged

teamleaderleo merged 9 commits into
feat-cmux-nextfrom
rail-opus-rail-minimap-setting

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

The compact (wave) rail, which is on by default, now draws only the ticks in its own view. On a 2,000-row chat it used to mount 1,000 tick buttons. Every layout the transcript forced (it measures rows on each commit) then laid all of them out. That cost 36 ms a frame at p95 while scrolling and 44 ms while a reply streamed, which is the lag you can feel.

Leo (2026-10-25): "the mini map VS Code code thing ... I feel like we should have that. Although I don't know if that actually, like, causes potential lag."

This PR measures that lag and removes most of it from the rail that ships. The full-height minimap (#22784) stays off; its numbers are at the end.

Change

  • threadMinimap/tickWindow.ts (new): tickRanges picks the rows to draw.
    • These are the rows in the list's view, 12 past each edge, and the focused, hovered, revealed and card rows, so focus and aria-describedby always have their element.
    • An offset past the list's end (a shorter chat in the same rail) reads as the end, so the rows still draw.
  • ThreadMinimap.tsx TickList: draws those ranges, with an aria-hidden spacer for each gap.
    • The list stays as tall as all of its rows, so its scroll offset, the edge fades, railScrollTop and each row's y are unchanged.
    • The ranges are memoized on their contents, so a streamed token renders no tick (as before).
  • Accessibility: the list is an ol. Each drawn tick sits in a 10 px li with aria-posinset and aria-setsize giving its place among every prompt, drawn or not. Spacers are aria-hidden. The tick buttons, their labels and aria-current are unchanged.
  • Keyboard: ArrowUp/Down and Home/End to a row that isn't drawn yet draw it, then focus it (reveal). Tab and Shift-Tab past the drawn rows do the same, so Tab still walks every prompt.
  • Rows that move (older turns arriving, earlier ones cut): the focused, hovered and card rows resolve through a key-to-row map. The map is built once per change of the ticks, never per token. The render that renumbers the rows already uses their new places, and the state is then set to them.
  • The page-focused tick (a pointer's click focuses one too, without the keyboard's grow or card) is tracked by key from focus and blur on the list. It is always drawn.
  • Placing the list: the layout effect no longer reads list.scrollTop after a commit. It keeps the offset it last set or that the list's scroll event reported (listOffset). A list that no longer overflows (another chat, fewer prompts) goes back to its top.
  • Rendering, layout and accessibility only: tick states, easing, the jump, the data and visibility are unchanged.

Review fixes (gpt-6-astra, CHANGES at a487804)

  1. P1, focus lost on prepend: rows are resolved by key. Test: "older turns arriving above keep focus on the focused prompt's tick". It focuses prompt 300, loads 300 older turns, and checks that focus stays on the same element, now row 300.
  2. P1, blank rail after a long chat: the list resets when it stops overflowing, and tickRanges clamps a stale offset. Tests:
    • "a rail scrolled to the end of a long chat shows every tick of a short one it switches to": a 2,000-turn chat scrolled to the end, then a 5-prompt session, shows ticks 0 to 4.
    • thread-minimap-tick-window.test.ts: the clamp.
  3. P1, list semantics: ol/li with posinset/setsize. Test: "each drawn tick is a list item that names its place among every prompt".
  4. P2, weakened append test: thread-minimap-stream again checks that the drawn ticks are exactly the window's rows before and after a new prompt, and that every tick still in the window is the same element.

Re-review fixes (gpt-6-astra at b979455)

  1. P2, a clicked tick unmounted by scrolling: the page-focused tick is kept by key. Test: "a clicked tick keeps focus while the chat scrolls it out of the rail's window". It clicks the latest tick, scrolls the chat to its top, and checks that the tick is still connected and focused and that ArrowUp goes to the one above it.

  2. P2, a search on every token after a cut: the key-to-row map replaces findIndex, and the state is reconciled. Test: "after earlier turns go, streaming does no search of the ticks, and the card stays on its prompt".

    • Setup: focus the latest tick, cut the first 500 turns, then stream 200 tokens.
    • Result: no tick-list element is visited by findIndex (303,000 visits before the fix). The active tick and the card are still on "Question 1999", now row 1499.
  3. P2 at 3663c32, a stale page-focus key: the key now carries its chat, and is dropped once it names no tick of the chat on the rail (a focused button removed with its chat or prompt may send no blur). Test: "a focused tick that goes away with its chat is not held drawn when the chat comes back". It clicks a tick, swaps in another chat, swaps the first back and scrolls to its top, and checks that the old tick is not drawn.

  4. P2 at 87e959e, a page-focus key outliving a hidden rail: the key holds only while the rail is shown, and is dropped whenever the page's focus is not in the list (a hidden rail, an unmounted list, any removal without a blur). Test: "a focused tick whose rail hides and comes back in the same chat is not held drawn". It clicks the first tick, cuts the same chat to 3 prompts so the rail goes, restores it and scrolls to the end, and checks that tick 0 is not drawn.

  5. P2 at cbe60e2, a remounted list under a stale offset: the cached list offset resets while no list is mounted, so a rail hidden for lack of room (or prompts) is placed from its top again when it comes back. Test: "a scrolled rail hidden for lack of room comes back at its place, its rows drawn". It shrinks a 2,000-turn pane scrolled to the end to 5 px so the rail goes, restores 600 px, and checks that the new list is scrolled to the band with its first and last visible rows (and the latest prompt) drawn.

Each new test fails on the head before its fix and passes now.

All four new tests fail on the previous head (5 fail, 7 pass across the three files) and pass at this head.

Numbers (same harness both ways, re-run at this head)

The bench from #25173 (webviews/bench/thread-minimap-frame-cost.bench.ts, landed): a production build of the pane's dev entry and a stand-in acpmux with 1,000 turns (2,000 rows), Chromium at 1200x800. Each scenario runs for 4 s: idle; a wheel step of -120 every 16 ms; and a reply streaming 30 chunks/s with a new turn every second. Cost is main-thread busy time per painted frame, from a Chrome trace, as the median over 3 rounds. "Before" is base feat-cmux-next at the same commit.

ms per frame, p95 (p50) rail off (before run / after run) before after
idle 0.62 (0.45) / 0.62 (0.41) 0.63 (0.45) 0.63 (0.42)
scroll 18.43 (5.93) / 20.23 (6.05) 53.94 (15.96), 145 frames in 4 s 23.25 (5.07), 242 frames
stream 21.58 (12.07) / 20.35 (11.68) 65.22 (41.56), 95 frames 26.14 (13.05), 237 frames

Extra cost over rail off:

before after
idle, p95 +0.01 +0.01
scroll, p95 +35.5 +3.0 (at 3663c32: +8.5, +4.4)
scroll, mean +0.2
stream, p95 +43.6 +5.8 (at 3663c32: +5.9, +7.5)
stream, mean +2.7
stream, p50 +1.4

Long tasks over 50 ms went from 2–13 per run to 0–1.

Not met: the 1 ms target for scroll and stream. Run to run, p95 moves by 2–3 ms. Across the three 3-round runs of this change, the stream p95 extra was 2.7, 7.8 and 5.8 ms.

  • Probing a forced layout after a text change in the last reply: about 3.2 ms with the rail's list hidden and about 4.1 ms with it drawn, so about 0.9 ms per transcript row measure. This does not shrink with fewer ticks.
  • The li wrapper added for semantics costs little, within noise. Compared 3 rounds each: no wrapper 25.7 ms, display: contents 26.0 ms, block li 28.8 ms at stream p95. I kept the block li, because display: contents drops list semantics in some engines.
  • Getting to 1 ms would mean drawing the ticks as one canvas or SVG layer with one roving focusable button. That would rebuild the tick states and easing that items I and J are changing now, so it is left for after them.

Full-height minimap (#22784), same harness, before this change: +57 ms scroll and +112 ms stream at p95 over rail off. It stays off, and no setting was added.

Captures (dark theme, 1,000-turn chat, compact rail, at this head)

The before and after captures are pixel-identical (PIL ImageChops.difference bbox is None for all three).

  • Before: 1,000 ticks in the DOM, each a button directly in the nav.
  • After: 74 ticks in the DOM, the first an li with posinset 472 and setsize 1000 inside an ol.
before after
at the latest message
scrolled to the middle
hovering a tick (fisheye and card)

Tests

  • New: test/thread-minimap-long-chat.test.tsx (9 tests) and test/thread-minimap-tick-window.test.ts (2 tests).
    • The long-chat test checks that a 2,000-turn chat mounts at most 120 ticks and that the list is as tall as all 2,000 rows.
    • ArrowDown walks every prompt from the first to the last without ever mounting more than 120.
    • Home and End jump across the chat, and Tab and Shift-Tab step 200 rows past the drawn ones.
    • The other new tests are the prepend, short-chat and list-semantics cases above.
  • Updated: thread-minimap-stream (exact window and identity, above). thread-minimap-tiny and thread-minimap-bottom: their jsdom scroll clamp now counts spacer heights.
  • All 24 rail test files: 118 pass, 0 fail. vp lint and vp fmt --check are clean on the touched files.

Size

853 changed lines (802 added, 51 removed): 268 in product code and 585 in tests. Over 800 only through the review-round regression tests. The bench (337 lines) moved to #25173.

Risk

Low to medium. It is limited to the compact rail's DOM: the rows drawn, the list's offset, and the list markup (ol/li where it was a div of buttons). The main risk is a row missing for one frame. That could happen when the browser scrolls the list by more than 12 rows on focus before React renders the new range. The focused row itself is always drawn.

No new timers, observers or animation loops. Per-token work in the rail is O(1) unless older turns arrive. A key lookup (findIndex) runs only when a held row's index no longer matches its prompt, which happens when older turns arrive, never per token.

Overlaps

Agent session: huge-blue

🤖 Generated with Claude Code

teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by rail-opus-01 on huge-blue · session

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 25, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-tpd5j created for this PR by the cmux coordinator.

teamleaderleo added a commit that referenced this pull request Oct 25, 2026
…ort chat, list semantics

Review of #25152 (gpt-6-astra):
- The focused, hovered and card rows resolve by their prompt's key when older
  turns renumber them, so the focused tick stays drawn and keeps focus.
- A list that no longer overflows (another chat, fewer prompts) goes back to its
  top, and tickRanges clamps a stale offset, so the rail never draws blank.
- The list is an ol; each tick sits in a 10 px li (acpmux-minimap__entry) with
  aria-posinset and aria-setsize for its place among every prompt; spacers are
  aria-hidden.
- The append test asserts the exact window and every kept tick's identity again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16f7b-11f6-73e0-8276-7c0e3bb3ead4&host=huge-blue
@teamleaderleo
teamleaderleo force-pushed the rail-opus-rail-minimap-setting branch from a487804 to b979455 Compare October 25, 2026 23:00
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
teamleaderleo added a commit that referenced this pull request Oct 25, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Found 80 test failures on Blacksmith runners:

Failures

Test View Logs
src/pages/settings/claimPaint.test.tsx/claimPaint.test.tsx View Logs
src/pages/settings/claimPaint.test.tsx/claimPaint.test.tsx View Logs
test/accent-glass-invariants.test.ts/accent-glass-invariants.test View Logs
test/accent-glass-invariants.test.ts/accent-glass-invariants.test View Logs
test/agent-pane-agents-pill.test.ts/agent-pane-agents-pill.test View Logs
test/agent-pane-agents-pill.test.ts/agent-pane-agents-pill.test View Logs
test/agent-pane-bottom-stack.test.ts/agent-pane-bottom-stack.test View Logs
test/agent-pane-bottom-stack.test.ts/agent-pane-bottom-stack.test View Logs
test/agent-pane-peer-chat.test.ts/agent-pane-peer-chat.test View Logs
test/agent-pane-peer-chat.test.ts/agent-pane-peer-chat.test View Logs

...and 70 more test failures. View all on Blacksmith

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next fast gates / post cmux-next/fast-gates is red on 13 of 13 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

teamleaderleo added a commit that referenced this pull request Oct 25, 2026
… their prompts by a key map

Re-review of #25152 (gpt-6-astra):
- The tick the page's focus is on (a pointer's click focuses one too, without
  the keyboard's grow or card) is tracked by key from focus and blur on the
  list, and always drawn, so scrolling never unmounts it.
- The focused, hovered and card rows resolve through a key-to-row map built once
  per change of the ticks, and the state is set to the resolved rows, so a cut
  of earlier turns leaves no search per token and the card stays on its prompt.
  This replaces the prepend-only shift of those rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16f7b-11f6-73e0-8276-7c0e3bb3ead4&host=huge-blue
@cursor

cursor Bot commented Oct 25, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review ada4775: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr25152 -f ref=rail-opus-rail-minimap-setting -f platform=macos -f backend_mode=local

Probably yours: accent-glass-invariants.test.ts fails here but not on main's latest full suite. Seen on other PRs too (likely flaky): claimPaint.test.tsx, claimPaint.test.tsx, agent-pane-agents-pill.test.ts and 12 more. This PR merged before its CI finished: fix forward on main.

CI failed on ada47759f3 (run 40347624146 attempt 1): 2 code, 1 unknown.

Job Verdict Why
web / react-apps-base-check (1) code a web test failed
web / react-apps-base-check (4) code a web test failed
web / react-apps-check unknown no known signature; failed step: Check webview test shards

Failures:

  • seen on other PRs claimPaint.test.tsx a pooled Settings page claimed by the host reports its paint once its first screen is in: failed (job)
  • seen on other PRs claimPaint.test.tsx a Settings page loaded fresh reports its first paint once its first screen is in: failed (job)
  • new in this PR accent-glass-invariants.test.ts (unnamed): failed (job)
  • seen on other PRs agent-pane-agents-pill.test.ts by default the running agents sit in the tray above the composer, not in the transcript: failed (job)
  • seen on other PRs agent-pane-bottom-stack.test.ts in a short pane the transcript keeps room and the queue scrolls inside its height: failed (job)
  • seen on other PRs agent-pane-queue-collapse.test.ts a long queue > an opened queue with a two-line row shows whole rows only, no row under another (capt...: failed (job)
  • seen on other PRs agent-pane-queue-collapse.test.ts a long queue > a folded queue with a long row opened shows only whole rows above the fold (capture, ...: failed (job)
  • seen on other PRs agent-pane-suggested-tasks.test.ts messages from other agents > a long message's card shows its first six lines; the chevron or a click...: failed (job)
  • seen on other PRs agent-pane-peer-chat.test.ts a chat on an SSH machine > counts its running turn from the prompt and offers no machine switch mid-...: failed (job)
  • seen on other PRs agent-pane-question-records.test.ts answered live, the card goes and the record takes its place: failed (job)
  • ... 6 more in the job logs
Matched log lines
web / react-apps-base-check (1): (fail) a pooled Settings page claimed by the host reports its paint once its first screen is in [263.85ms]
web / react-apps-base-check (4): (fail) a chat on an SSH machine > counts its running turn from the prompt and offers no machine switch mid-chat [30956.54ms]

Not re-run automatically: web / react-apps-base-check (1), web / react-apps-base-check (4), web / react-apps-check are not machine failures.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

red: web / Web status; NEW: green on the base ab362b8; do not merge until green; see lane-rules
red: web / react-apps-base-check (1); no finished base run on ab362b8 to compare; do not merge until green; see lane-rules
red: web / react-apps-base-check (4); no finished base run on ab362b8 to compare; do not merge until green; see lane-rules
red: web / react-apps-check; no finished base run on ab362b8 to compare; do not merge until green; see lane-rules

Gallery before/after for ada4775: 16 states rendered, 14 images differ, 710 more touched states not rendered. Images are in the run's artifact, not on this public PR.

gh run download 40347623822 -R manaflow-ai/cmux -n gallery-advisory-25152-ada47759f38e227d0de6fe437fa83bf3eb480b95 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.thread-minimap/rest Apple System Colors Light unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/rest Apple System Colors unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/scrubbing Apple System Colors Light unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/scrubbing Apple System Colors unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/seventy-prompts Apple System Colors changed 0.003% own ThreadMinimap.tsx
agent-pane.thread-minimap/seventy-prompts Apple System Colors Light unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/seventy-prompts-bottom Apple System Colors Light changed 0.0011% own ThreadMinimap.tsx
agent-pane.thread-minimap/seventy-prompts-bottom Apple System Colors unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/long-chat Apple System Colors Light unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/long-chat Apple System Colors unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/hovered Apple System Colors Light changed 1.47% own ThreadMinimap.tsx
agent-pane.thread-minimap/hovered Apple System Colors unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/landing Apple System Colors changed 0.657% own ThreadMinimap.tsx
agent-pane.thread-minimap/landing Apple System Colors Light changed 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/bookmarked Apple System Colors Light unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap/bookmarked Apple System Colors unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap-lit/mid-thread Apple System Colors Light changed 0.0029% own ThreadMinimap.tsx
agent-pane.thread-minimap-lit/mid-thread Apple System Colors changed 0.0027% own ThreadMinimap.tsx
agent-pane.thread-minimap-lit/at-the-end Apple System Colors Light unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap-lit/at-the-end Apple System Colors unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap-lit/hovered Apple System Colors Light changed 1.96% own ThreadMinimap.tsx
agent-pane.thread-minimap-lit/hovered Apple System Colors changed 0.812% own ThreadMinimap.tsx
agent-pane.thread-minimap-mark/states Apple System Colors changed 0.003% own ThreadMinimap.tsx
agent-pane.thread-minimap-mark/states Apple System Colors Light changed 0.0029% own ThreadMinimap.tsx
agent-pane.thread-minimap-mark/bookmark-hovered Apple System Colors Light changed 1.7% own ThreadMinimap.tsx
agent-pane.thread-minimap-mark/bookmark-hovered Apple System Colors changed 1.13% own ThreadMinimap.tsx
agent-pane.thread-minimap-mark/rest-hovered Apple System Colors changed 0.573% own ThreadMinimap.tsx
agent-pane.thread-minimap-mark/rest-hovered Apple System Colors Light unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap-narrow/rest Apple System Colors Light unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap-narrow/rest Apple System Colors unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap-narrow/hover Apple System Colors Light unchanged 0% own ThreadMinimap.tsx
agent-pane.thread-minimap-narrow/hover Apple System Colors unchanged 0% own ThreadMinimap.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next fast gates / post cmux-next/fast-gates is red on 20 of 23 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

teamleaderleo and others added 4 commits October 26, 2026 00:22
A 2,000-row chat mounted 1,000 tick buttons, and every layout the transcript
forces laid them all out. The rail now draws the rows in its list's view plus
12 past each edge, and the focused, hovered and described rows; spacers keep the
list as tall as every row. Keys and Tab that move past the drawn rows draw the
row, then focus it. The list's offset is kept from its own scroll and writes, so
a commit reads no layout to place it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16f7b-11f6-73e0-8276-7c0e3bb3ead4&host=huge-blue
…ort chat, list semantics

Review of #25152 (gpt-6-astra):
- The focused, hovered and card rows resolve by their prompt's key when older
  turns renumber them, so the focused tick stays drawn and keeps focus.
- A list that no longer overflows (another chat, fewer prompts) goes back to its
  top, and tickRanges clamps a stale offset, so the rail never draws blank.
- The list is an ol; each tick sits in a 10 px li (acpmux-minimap__entry) with
  aria-posinset and aria-setsize for its place among every prompt; spacers are
  aria-hidden.
- The append test asserts the exact window and every kept tick's identity again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16f7b-11f6-73e0-8276-7c0e3bb3ead4&host=huge-blue
… their prompts by a key map

Re-review of #25152 (gpt-6-astra):
- The tick the page's focus is on (a pointer's click focuses one too, without
  the keyboard's grow or card) is tracked by key from focus and blur on the
  list, and always drawn, so scrolling never unmounts it.
- The focused, hovered and card rows resolve through a key-to-row map built once
  per change of the ticks, and the state is set to the resolved rows, so a cut
  of earlier turns leaves no search per token and the card stays on its prompt.
  This replaces the prepend-only shift of those rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16f7b-11f6-73e0-8276-7c0e3bb3ead4&host=huge-blue
… goes

A focused button removed with its chat or prompt may send no blur. The key now
carries its chat and is dropped once it names no tick of the chat on the rail, so
a returning chat does not hold that tick drawn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16f7b-11f6-73e0-8276-7c0e3bb3ead4&host=huge-blue
teamleaderleo and others added 2 commits October 26, 2026 00:23
…shows and has focus

A rail that hides (fewer prompts than it needs, too little room) removes its
focused button without a blur. The key now holds only while the rail is shown,
and is dropped whenever the page's focus is not in the list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16f7b-11f6-73e0-8276-7c0e3bb3ead4&host=huge-blue
A rail hidden for lack of room (or prompts) unmounts its list, and the next one
mounts at scrollTop 0. The cached offset now resets while no list is mounted, so
the placement effect scrolls the new list to the band and draws its rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16f7b-11f6-73e0-8276-7c0e3bb3ead4&host=huge-blue
@teamleaderleo
teamleaderleo force-pushed the rail-opus-rail-minimap-setting branch from 1c98439 to 072e2e1 Compare October 26, 2026 00:28
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next guards / nightly-guards / workflow-guard-tests / release-notary is red on 17 of 18 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Orphaned: no activity for 14 h, and no lane holds a lease on it. Adopted by the orphan sweep: merged feat-cmux-next in at e3a8e96. A later pass queues it for the merge hub if it is reviewed, small and red only on base reds.

The list item around each tick set its own height: 10px, a raw value the
design-token ratchet refuses. The tick inside it is already a 10 px block
with no margin, so a plain block item is the same height without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1587ac999477cd86120a
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

high-signal review link / link is red on 9 of 13 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

…and card

Hiding the rail cleared the page-focus key but left the keyboard-focused
row, the hovered row and the card's row, so a keyboard-focused tick's
card and grown tick came back with the rail. When the rail goes, those go
and the preview is dismissed; only on the change, so a rail that mounts
hidden cools no hover group. Test: keyboard focus, hide, show at the end:
no card and the old tick is not held drawn (fails without this commit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1587ac999477cd86120a
@teamleaderleo
teamleaderleo merged commit 8c3dac1 into feat-cmux-next Oct 26, 2026
132 of 138 checks passed
@teamleaderleo
teamleaderleo deleted the rail-opus-rail-minimap-setting branch October 26, 2026 15:57
@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

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

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant