Skip to content

cmux-next: thread minimap matches the Codex rail; bookmarks show and jump - #20560

Closed
teamleaderleo wants to merge 46 commits into
feat-cmux-nextfrom
feat/thread-minimap-codex
Closed

teamleaderleo wants to merge 46 commits into
feat-cmux-nextfrom
feat/thread-minimap-codex

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

The agent chat's thread minimap now behaves like the Codex desktop app's prompt rail, measured frame by frame from 60 Hz recordings of Codex.app (26.930). Bookmarks show on the rail, toggle from the rail, the card and the prompt's own row, and two new palette actions jump between them.

Depends on #20556 (bookmarks stored in acpmux). This branch merges feat/acpmux-turn-bookmarks and reads marks only through its bookmarks.ts API, so #20556 lands first.

What changed

  • Rail: shows from 4 prompts, only with ≥48 px left of the column (was 2 and 28 px). It sits 16 px in from the transcript's left edge, vertically centered, fixed. Rows are a fixed 10 px pitch, 36 px wide to hit, with 2 × 6 px ticks; past 64 rows or 70% of the window the rail scrolls with 2.5rem edge fades. Every prompt on screen is "current" (brighter, 6 px); the hovered or focused row draws in the text color. Colors are theme tokens (muted text at 40%, text at 60%, text), which give the SPEC's #3d3d3d / ~#747474 / #dadada in the dark reference theme.
  • Hover: no delay; rows magnify 26/20/14/10 px in 160 ms on Codex's linear() spring (~0.8% overshoot), all rows at once, and ease back in 150 ms on leave (was 50/35 ms).
  • Preview card: opens 250 ms after the pointer reaches the rail, instantly if one closed <300 ms ago, closes 100 ms after leaving; appears and disappears in one frame and moves straight to the hovered row. 320 px wide, 12 px radius, flush right of the row: the prompt on one line, the bookmark button, up to 3 answer lines.
  • Keyboard: every row is a tab stop, and a clicked row takes focus (as in Codex), so Tab goes on from the rail. A focused row grows to 26 px with no neighbor magnification and opens its card at once; Escape closes it; Return/Space jumps.
  • Click to jump: the prompt's bubble lands 35 px below the transcript's top. A JS scroll on cubic-bezier(0.35, 0.05, 0, 1) takes ~400 ms for ~650 px; an unmounted (virtualized) target jumps at once. The bubble then fades from a highlight to its own fill over 1400 ms on cubic-bezier(0.23, 1, 0.32, 1).
  • Scrub: dragging on the rail jumps the transcript to each row crossed, with no tick transition; the drag's click is swallowed.
  • Bookmarks: a bookmarked tick is drawn at full opacity with a 2 × 2 px dot 2 px past its end; the card shows a filled icon. Beyond Codex: a click on the dot's spot toggles the mark (the hovered row shows a faint dot there), the prompt row's hover actions gain a bookmark button, and Previous Bookmarked Prompt / Next Bookmarked Prompt are command palette actions with no default key.
  • Previous/Next Turn keep Ctrl-Opt-Up/Down. Codex uses Option-Up/Down, but a default key change needs a design call, so none changed here. The step now scrolls on Codex's 200 ms cubic-bezier(0.30, 0.20, 0, 1) with no highlight.
  • Reduce Motion (system or the app's): magnification, card and highlight are instant, the scroll jumps.
  • The parity dev page (threadMinimap/parity.html) now replays the Codex reference thread through the real transcript; the gallery entry agent-pane.thread-minimap shows the hover card and a bookmarked variant.

Brief vs Codex: the brief said hover "expands into the list of prompts". Codex does not do that: ticks magnify like the Dock and a preview card opens. This follows Codex.

Short-prompt density (Leo 10-14)

Leo asked whether the rail shows enough prompt highlights at once with short prompts. It does: density matches Codex by construction, and the measurements agree.

Setup:

  • a cmux NEXT DEV build of fc30853 on a capture mini, in a 1280x820 window;
  • the new debug seed debug.agent_pane seed_rows {"count":180,"fixture":"short"}: 60 turns of "Reply with only the word ok and the number N." / "ok N", the same content as the Codex reference chat;
  • Codex 26.930 measured from the reference recording, at the same window size.

The Codex frames are in the private archive (references/codex-prompt-rail-2026-10-14/), not here.

Codex cmux (this PR)
Px per turn 156 153.5
Turns per viewport 4.2 4.07
Rail rows / tick 10 px rows, 6x2 px tick same
Rail cap (70% of height) 57 rows 57 rows
Lit ticks mid-thread / bottom 5 / 4 5 / 5
Lit per frame while scrolling 4-6 (5 in 61% of frames) 4-6 (5 in 93% of frames)

The one-tick difference at the bottom comes from where each thread's last scroll position falls. The rest of the rail is the same: the pitch, the cap and the rule that every turn intersecting the viewport is lit.

One difference that isn't density: our rest and current ticks are about 25/255 lighter than Codex's in dark mode (the --agent-muted/--agent-text tokens). That's left as is here and noted as a follow-up.

Light and dark, mid-thread:

ours light middle

ours dark middle

At the bottom:

ours light bottom

ours dark bottom

Hovering the rail mid-thread:

ours dark hover middle

Scrolling through, as a 12-frame strip and a clip:

strip ours scroll

ours dark scroll

Full quality: ours-dark-scroll.mp4

Evidence

Captures: tagged DEV builds from the fleet's Mac builder (head 82f7d7b, base 2e420aa), recorded with real HID input on the capture mini that recorded the Codex reference, same window frame, 20-prompt mock chat. Host names blurred.

The Codex-vs-cmux side-by-side clips (hover, click to jump, scrub, bookmark, keyboard, Previous/Next Turn) are reference captures of another app, so they live only in the private screenshots archive (manaflow-ai/cmux-app-screenshots references/codex-prompt-rail-2026-10-14/), not here. The measured numbers are in the Codex reference spec in the same archive.

Before (feat-cmux-next) and after (this PR) in the cmux NEXT DEV app: hover, click, bookmark, keyboard.

base-vs-head

base-vs-head.mp4

Verification:

  • Web regression tests, failing first (jsdom): thresholds, card timing (fake timers), Tab/Escape/Return, scrub, the bookmark dot and row button, the bookmark steps. Red at 2261f9c (1 pass, 8 fail) → green (9 pass); with acpmux: prompt bookmarks persist in the session #20556 merged, 35 pass across 9 files. The clicked row taking focus (found in the capture: WebKit does not focus a clicked button, so Tab left the rail): red at bd45ad5 → green at 82f7d7b (rail 8/8; current, turn keys and bookmarks 13/13).
  • WebKit browser test thread-minimap-motion.test.ts (CI only): at 82f7d7b, the click curve, the landing and highlight, and Reduce Motion passed in react-apps-check. The hover check now seeks the transition instead of sampling frames, because CI's headless WebKit paced frames unevenly (a72dc7e). That rewrite has not run in WebKit yet: since then react-apps-check stops at bun run check on a base formatting red in test/ime-composition-keys.test.ts, which this PR does not touch.
  • Swift (fleet): AgentPaneTranscriptStepTests red at 2261f9c (does not compile: no AgentTranscriptStep), green at c6a863f (2/2). Full suites at c6a863f: 296/297 pass. NowPlayingCardTests fails; this PR does not touch that sidebar card. AcpmuxBundleReplacedTests was skipped by the same-tree guard. Release compile: BUILD SUCCEEDED at c6a863f and again at the merged head 568dba6.
  • bun run check, ui-rules, gen-strings --check, gallery coverage and play, action exports regenerated on the fleet after the latest base merge (568dba6). The base merge's direct.ts conflict is resolved as the union: the attach kinds list keeps acpmux: prompt bookmarks persist in the session #20556's BOOKMARKS_KIND and gains the base's OFFER_KINDS. acpmux: prompt bookmarks persist in the session #20556 will need the same resolution. check-system-blue, crash_ratchet, check-app-size, check-test-notification-centers and lint-ios-package-conventions are clean. check-no-godfiles passes on every touched Swift file (the catalog split keeps AgentActionCatalog at 375 lines). check-concurrency: 1 base red in ControlWorkspaceInfoCache.swift, not touched here.
  • Other reds on this PR, none in its files: web/ server shards 1/4 and 3/4 (Cloud namespace, admin audit and Stack invitation tests, which also fail locally on this tree), src/pages/settings/categories.test.ts, Tour the app (runner worktree error), batch-queue debounce (cancelled).

Changelog

Changed: the thread minimap magnifies, previews and jumps like the Codex app; bookmarks show a dot and can be jumped to

Showcase

d1 rest

d2 hover

d3 clicked

d4 left

c2 card marked

r1 row

dot toggle frames

Full quality: dot-toggle-frames.mp4

Open the live gallery

🤖 Generated with Claude Code

teamleaderleo and others added 8 commits October 14, 2026 01:43
Behavior tests for _acpmux/bookmark_get and _acpmux/bookmark_set before
they exist: restart, prompt-only seqs, fork, transfer, peer forwarding,
the pane relay's scope and params, and the minimap popover's store.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
_acpmux/bookmark_get and _acpmux/bookmark_set keep the thread minimap's
marks in SessionMeta.bookmarks: seqs of the chat's user_message records,
checked against its log and capped at 1000. A change logs a mux
bookmarks record, as tags do, so attached panes hear it; the chat keeps
its place in the session list. A fork carries the marks of the prompts
it copies under its own seqs; a move carries them (the log keeps its
seqs) and the source keeps none. Peers' chats forward to their owner.

The pane relay allows both methods for a chat in the pane's scope with
only sessionId, seq and bookmarked. The minimap's store reads them from
acpmux, toggles optimistically with rollback, and imports this pane's
old localStorage marks for the chat once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…(red)

Behavior tests for the rail's thresholds, hover magnification, card timing,
keyboard focus, scrub, the bookmark dot and row button, and the bookmark
steps, plus a WebKit motion test and the Swift action/page-event test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…jump

The rail now follows the Codex desktop app's measured behavior: it shows
from 4 prompts with 48 px left of the column, 16 px in and centered, with
10 px x 36 px rows and 6 px ticks that scroll past 64 rows or 70% of the
window. Hover magnifies the rows (26/20/14/10 px) in 160 ms on Codex's
spring, the preview card opens after 250 ms (at once within 300 ms of a
close, or on keyboard focus) and closes 100 ms after leaving. A click
scrolls on cubic-bezier(0.35, 0.05, 0, 1) (~400 ms for ~650 px), landing
the bubble 35 px below the top, and highlights it for 1400 ms; an
unmounted target jumps. Dragging scrubs. Every row is a tab stop.

Bookmarks show as a 2 px dot past the tick (a click on its spot toggles
it), in the card, and in a new button on the prompt's own row. Previous
and Next Bookmarked Prompt are palette actions with no default key; the
turn steps keep Ctrl-Opt-Up/Down, now on Codex's 200 ms scroll curve.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bookmarks now live in acpmux (#20556). The rail's dot, its clickable
spot, the card button and the prompt row's button read and toggle them
through bookmarks.ts's useBookmarks/promptSeq (threadMinimap/promptMarks.ts),
and show only for prompts acpmux has logged. Tests set a bookmark
transport and use user-<seq> prompt ids.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Generated by scripts/measure/export-action-surfaces.sh on the fleet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…for acpmux (red)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo teamleaderleo added the hold cmux-next batch queue: keep this PR out of the batch (docs/ci/cmux-next-batch.md) label Oct 14, 2026
@cursor

cursor Bot commented Oct 14, 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.

@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 14, 2026 10:27 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: a75da261-6f48-4c4b-bc86-32bff1154839

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

… holds them

set_bookmark changes, logs and saves the marks under the chat's move
lock, so concurrent sets log in the order they change the marks and a
move begins before or after a change. The prompt check scans the log on
a blocking thread. The pane forgets an old localStorage mark only once
bookmark_set succeeds for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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

@blacksmith-sh

This comment has been minimized.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 60c9dc1: 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=pr20560 -f ref=feat/thread-minimap-codex -f platform=macos -f backend_mode=local

Pending: CI is running on 60c9dc1bb8 (run); the result below was for 1d86039b30 and no longer applies.

Last result: Unclear: web / react-apps-check failed: no known signature; failed step: Check webview test shards.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); it is rewritten when this head's CI completes.

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 204546c; does not block
red: web / react-apps-check (2); no finished base run on 204546c to compare; do not merge until green; see lane-rules
red: web / react-apps-check (3); no finished base run on 204546c to compare; do not merge until green; see lane-rules
red: web / react-apps-check (4); no finished base run on 204546c to compare; do not merge until green; see lane-rules

CI fast guards failed on 1d86039b30 (https://github.com/manaflow-ai/cmux/actions/runs/39367009785). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

CI fast guards failed on a89c04f26e (https://github.com/manaflow-ai/cmux/actions/runs/38707624203). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally. This comment is updated in place on each push.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

cmux-next tour of 82f7d7b55f77364aac1706e70677a4ea14717828 (run)

The tour job failed before the tour ran (build or setup); the run log has the output.

The tour produced no media.

Tours are data in scripts/cmux-next/media/tours: add a step or a tour file to show your feature.

teamleaderleo and others added 3 commits October 14, 2026 04:14
WebKit does not focus a clicked button, so in the app Tab after a click
left the rail for the transcript. Codex's rail (Chromium) focuses it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 14, 2026 11:24 — with GitHub Actions Inactive
…amples

CI's headless WebKit paced frames unevenly, so a sample 40 ms into the
transition could come long after it ended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 14, 2026 12:11 — with GitHub Actions Inactive
…ead-minimap-codex

# Conflicts:
#	webviews/src/agent-session/acpmux/direct.ts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 14, 2026 12:43 — with GitHub Actions Inactive
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 15, 2026 08:42 — with GitHub Actions Inactive
The flag cleared on a 0 ms timer, which a slow frame could run between the
pointerup and its click, so the drag's click jumped (CI web shard 2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 15, 2026 09:45 — with GitHub Actions Inactive
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

#22228 carries this branch forward: it merges current feat-cmux-next into it (conflicts in App.tsx, ThreadMinimap.tsx, ActionCatalog.xcstrings, actions.md) and fixes what still measured worse than Codex in a 60-turn chat (band lag while scrolling, 466 ms card, far jumps landing 262 px off, older pages moving the band 163 px). I'll close this one once #22228 lands.

@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 20, 2026 02:41 — with GitHub Actions Inactive
@greptile-apps

greptile-apps Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The changes affect navigation and bookmarking within agent-chat transcripts.

The PR should not merge yet because a minimap jump can keep scrolling after the user switches chats.

Findings

  1. P1 Old jump moves another chat ▶
  2. P2 Rail ends get clipped ▶
  3. P2 Keyboard leaves preview open ▶
  4. P2 Cancelled click stays pressed ▶
  5. P2 First keyboard jump disappears ▶
  6. P2 Widening loses rail position ▶
  7. P2 Rail ignores animations off ▶

Summary

The PR changes the thread minimap to a fixed-pitch prompt rail with previews, scrolling, keyboard navigation, and scrubbing.

  • The prompt rail previews, tracks, and jumps between chat prompts.
  • The command palette can jump to the previous or next bookmarked prompt.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Palette["Command palette"] --> Step["Transcript step"]
  Rail["Rail click or scrub"] --> Jump["Jump to prompt"]
  Step --> Jump
  Jump --> Scroll["Scroll transcript"]
  Dot["Rail dot"] --> Marks["Session bookmarks"]
  Card["Preview button"] --> Marks
  Row["Prompt row button"] --> Marks
  Marks --> Rail
Loading

Reviews (4) · Last reviewed commit: "chore(next): PR autofix at 1d86039b308d" · Reviewed by Greptile

Comment on lines +130 to +138
const target = () =>
Math.min(turnScrollTop(turn, live.current.tops), Math.max(0, live.current.total - node.clientHeight));
const row = mountedRow(node, turn.id);
const to = target();
if (how === "scrub" || !row || reducedMotion()) {
stopScroll(node);
node.scrollTop = to;
} else if (how === "step") animateScroll(node, target, STEP_MS, STEP_CURVE);
else animateScroll(node, target, jumpDuration(to - node.scrollTop), JUMP_CURVE);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Old jump moves another chat

Switching chats during a minimap jump leaves the old scroll running. target() keeps the old turn but reads the new chat's layout through live.current. Because VirtualTranscript reuses the same scroller, later frames overwrite the new chat's opening position. Stop the animation when sessionId changes and when the minimap unmounts.

Comment on lines +111 to +115
const windowHeight = globalThis.innerHeight || viewportHeight;
const onScreen = visibleTurns(turns, layout.tops, layout.totalHeight, scrollTop, viewportHeight);
const active = hovered ?? current;
const turn: MinimapTurn | undefined = hovered === undefined ? undefined : turns[hovered];
const shown = turns.length >= MIN_PROMPTS && gutter(width) >= MIN_GUTTER;
const height = railHeight(turns.length, windowHeight);
const overflow = turns.length * ROW_PITCH > height;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Rail ends get clipped

The rail's height uses innerHeight, but its position uses viewportHeight. The header and expanded composer leave less room for the transcript. A 600 px webview can therefore produce a 420 px rail in a transcript shorter than 420 px. Its top becomes negative, clipping the end rows and their click targets. Cap the rail against the transcript's available height too.

Comment on lines +372 to +380
<div
ref={card}
id={cardId}
className="acpmux-minimap__card"
style={{ transform: `translate3d(${RAIL_LEFT + ROW_WIDTH}px, ${cardTop}px, 0)` }}
onPointerLeave={(event) => {
// Back onto the rail keeps it (its row takes over); anywhere else it goes.
if (!within(rail.current, event.relatedTarget)) intend(null);
}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Keyboard leaves preview open

Moving the card outside the nav drops its keyboard dismissal path. Tab from the last rail row into the bookmark button, then Tab out: the nav leaves the card open, and the card has no onBlur to close it. Escape on that button also misses the handler attached to ticks. Close the card when focus leaves it and handle Escape within it.

Comment on lines +325 to +339
onPointerDown={(event) => {
if (event.button !== 0 || event.pointerType === "touch") return;
pressing.current = true;
swallowClick.current = false;
scrub.current = { pointer: event.pointerId, y: event.clientY, moved: false };
}}
onPointerMove={(event) => {
const state = scrub.current;
if (!state) return;
if (!state.moved) {
if (Math.abs(event.clientY - state.y) < SCRUB_SLOP) return;
state.moved = true;
setScrubbing(true);
// Captured only once it is a drag, so a plain click still lands on its row.
event.currentTarget.setPointerCapture?.(state.pointer);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Cancelled click stays pressed

Pressing a row, moving horizontally outside the rail, and releasing leaves pressing.current and scrub.current set. Pointer capture starts only after 3 px of vertical movement, so the list misses that release. Later keyboard focus is ignored, and returning the pointer can start a scrub without a pressed button. Track releases outside the list or otherwise clear the press when it ends.

Comment on lines +244 to +246
if (swallowClick.current) {
swallowClick.current = false;
return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 First keyboard jump disappears

swallowClick can consume a later keyboard jump instead of the drag's click. A scrub captures the pointer on the list, so its ending click can target the list rather than a tick. That click never reaches actions.click, leaving the flag set. The next Enter or Space on a tick then does nothing. Consume the ending pointer click at the list, or limit suppression to that pointer click.

if (rowTop >= node.scrollTop && rowTop + ROW_PITCH <= node.scrollTop + height) return;
node.scrollTop = Math.max(0, rowTop - height / 3);
setListTop(node.scrollTop);
}, [onScreen.first, overflow, height, hovered, focused]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Widening loses rail position

When a narrow pane becomes wide enough to show the rail, it mounts a fresh list. This effect previously skipped the hidden rail because list.current was null. Since neither shown nor width is a dependency, an unchanged height and current prompt do not rerun it. Long chats reopen the rail at the first prompt instead of the reader's position. Run the effect when the rail becomes visible.

- plans/cmux-next/action-surfaces.json
- plans/cmux-next/actions.md

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39360247633
width: 50.5px;
font: 13px -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
margin: 0;
animation: acpmux-minimap-in 150ms cubic-bezier(0.23, 1, 0.32, 1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Rail ignores animations off

The rail still fades in when ui.animationSpeed is off. This new animation uses a fixed 150 ms duration, and only the system Reduce Motion setting disables it. The app sends zero motion durations when animations are off, but this rule ignores those values. Use the app's motion setting for the rail's entrance too.

@cursor

cursor Bot commented Oct 20, 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.

@blacksmith-sh

blacksmith-sh Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Found 38 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpuitnn_ji/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmpza42zzp1/summary-missing.json (live):/summary-missing.json (live): View Logs
test/agent-pane-history-paging.test.ts/agent-pane-history-paging.test View Logs
test/agent-pane-history-paging.test.ts/agent-pane-history-paging.test View Logs
test/agent-pane-no-capsules.test.ts/agent-pane-no-capsules.test View Logs
test/agent-pane-no-capsules.test.ts/agent-pane-no-capsules.test View Logs
test/chat-find.test.ts/chat-find.test View Logs
test/chat-find.test.ts/chat-find.test View Logs
test/composer-caret-focus.test.ts/composer-caret-focus.test View Logs
test/composer-caret-focus.test.ts/composer-caret-focus.test View Logs

...and 28 more test failures. View all on Blacksmith: run 39368818708, run 39368818670

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

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

From the subsession-visibility lane, which owns the thread minimap work now: this PR's content is already on feat-cmux-next.

#22879 follows up with Leo's feedback. Nothing here is left to adopt, so this PR is superseded. I'm leaving the close to its owner.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

owner: 01a15ba2-88b0-7880-a07f-1f6bd7f401ed on cosmic-gray

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Adopting this orphan for live-reload-loop-dd. Next: check base against the transcript-density and scroll-jitter changes, then one base merge, conflicts, gallery before/after, review. [live-reload-loop-dd]

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Closing as superseded. This branch landed as #22228 (d85ec8a), a squash of every commit here through bcace27b5f2 plus about 15 follow-up fixes: the band tracks every frame, jumps land, the card delay is 250 ms, Escape goes through ui/escapeDismiss, and there are new gallery states. Later PRs built on it: #22784 (the minimap spans the transcript's height), #22879 (it lights the current position), and the density and scroll-jitter work.

Current feat-cmux-next has both halves of this PR: the Codex-style minimap (ThreadMinimap.tsx, ScrollMap.tsx, PreviewCard.tsx) and bookmarks that show and jump (agentPane.previousBookmarkedPrompt/nextBookmarkedPrompt). A trial merge conflicts in 8 files, and every conflict is an older version of a hunk that base has since rewritten. The parts that merge cleanly add nothing, so nothing here is lost by closing.

[live-reload-loop-0f]

Agent session: cosmic-gray

This branch had an error being deployed

1 failed (outdated) and 1 inactive deployments
cmux-tui-merge-tree — 60c9dc1b Deployed Oct 20, 2026 by manaflow-cmux-pr-autofix[bot]
artifacts — b3d13c82 Deployed Oct 20, 2026 by manaflow-cmux-pr-autofix[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hold cmux-next batch queue: keep this PR out of the batch (docs/ci/cmux-next-batch.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant