Skip to content

cmux NEXT: Session Info opens only when you open it, not over every new chat - #26764

Open
austinywang wants to merge 1 commit into
feat-cmux-nextfrom
feat-cmux-next-26692-location-popover
Open

austinywang wants to merge 1 commit into
feat-cmux-nextfrom
feat-cmux-next-26692-location-popover

Conversation

@austinywang

@austinywang austinywang commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #26692

What was happening

The floating panel listing the chat's machine, folder, repository and branch with a Save button is Session Info (the chat Inspector, inspector/ChatInspector.tsx, Environment section). Its state (inspector/inspectorState.ts) defaulted to open for any chat with no saved state of its own ("Open unless the viewer closed it: a first chat shows it"), a new chat inherited the open state of the chat the pane showed before, and that open was then saved under each new chat. So Session Info appeared by itself over every new agent chat, on top of the chat and its composer, until it was closed by hand.

Every other way it opens (the header toggle, the command palette, a running line's count, a tray row with nowhere else to go) is already a click.

The change

  • A chat with no saved state starts with Session Info closed. It opens only when the viewer opens it.
  • A pane that moves from one chat to another chat with nothing saved shows the new chat closed from its first frame, including a new chat that has no session yet (a harness switch). If the viewer opens it before a new chat's first prompt, the chat keeps it open when its session arrives.
  • A chat's own choice is still kept per pane, and still comes back after a relaunch. Width and section folds still carry over from the last choice.
  • Saved per-chat state now has a version (v: 2). An open: true saved before this change was written by the old default, not by the viewer, so it reads as closed. Chats that already popped Session Info open stop doing so too.

The panel's placement does not change: it floats in the right gutter, or above the composer stack when it lies over the chat (inspectorOverChat / useDockHeight).

Tests and gallery

  • test/inspector-per-pane-state.test.ts: new regression test, "a new chat never opens Session Info by itself, whatever another chat or an old install left". It covers a first chat, a last choice of open in another pane plus the old shared key set to "1", an old unversioned open: true chat, a pane moving from an open chat to a new chat (shownFor and bind), and a harness switch. Existing tests there are updated to the closed default. The module import now goes by file path instead of URL path, because the URL path percent-encodes the space in the fleet's Application Support checkout and the file failed to load there.
  • Tests and gallery plays that relied on the old default now open Session Info the way a viewer does (toggle click or setInspectorOpen(true)): chat-inspector.test.tsx, background-task-arrival.test.tsx, agent-pane-background-tasks.test.ts, chat-inspector-per-pane.test.ts, and the InspectorMotion, scrollbarEdge, ChangesFromCache, WorkflowPane and PullRequestDock (none-session-info) gallery entries.

Changelog

  • Fixed: cmux NEXT no longer opens Session Info (machine, folder, repository, branch, Save) by itself over every new agent chat; it opens only when you click its toggle.

Rebased on feat-cmux-next b4570f16cc (head 60350f8877)

The branch's last merge already carried the base's Inspector → Session Info rename, so the 13 original commits are folded into one commit with the PR's net change. Three files conflicted with the base's per-tab Session Info state (setTab/savedFor) and were merged keeping both sides: sessionInfoState.ts (saves go under the tab's and the chat's keys with v: 2; a tab change while a pane is leaving its chat does not re-bind the chat it left; a chat handed back is read through the tab's own key), App.tsx (imports) and ChangesFromCache.gallery.ts (the base's Show-more preset, then the open-by-click).

  • Fleet webviews tests at 60350f8877, step fb1bf66cb39a6438581a8244 (aws-m4pro-6): 1877 files, every Session Info test passes; 11 files fail, the same 11 that fail on the base b4570f16cc, step ae43f8a934af9e6c9d9c68a2 (aws-m4pro-2): queuePausedState, browser-lane-required, check-icon-scale, check-system-blue, gallery-coverage, hairline-rims, theme-colors, thread-minimap-rail, tooltip-rules, ui-rules, user-message-actions. None is from this PR.
  • Tagged dev build 26692-location-popover from 60350f8877, job c7d43a1cee788d7e188a6499: done, published.
  • Subagent correctness review of the conflict resolution: no findings (posted as a comment).

The receipts below are from the pre-rebase heads.

Red / green

Fleet cmux-ci run --class light --script scripts/ci/run-webviews-tests.sh:

  • Red at ae8b5222622f40c09c20ef8114296dfd860235d9 (the regression test, before the fix), job feb486d0fa498ff147ac547f: test/inspector-per-pane-state.test.ts fails 4 of 12. The new test fails at line 70, expect(open).toBe(false), Received true; the other three are existing tests updated to the closed default.
  • Green at 4e48cabc589c3318b3bef5e0aa799a08f6d837ab, unit, job a21bd65d8bb304502d462c3d (cmux-austin-mini-0): inspector-per-pane-state, chat-inspector, background-task-arrival all pass.
  • Green at 4e48cab, browser chat-inspector-per-pane (chromium and webkit), job 4386ffeb63009a1090079665 (cmux-austin-mini-0): pass. An earlier run, job dd67e3bd8deec09758f02c3d on another fleet Mac, hit the 120s file limit after the chromium case passed; the rerun on another host passed.
  • agent-pane-background-tasks: the inspector cases pass at 4e48cab. One case, "the summary card lists the chat's background tasks: running ones first, the finished folded", fails the same way on the base 17dfb9d320 (job be795030dee344caee9c57f2): the summary card shows the first finished tasks while folded. It is not from this PR, and this PR leaves it as is.

scripts/web-lint.sh passed (webviews, 720.7s).

Observed / Not run

  • Observed: web lint; the subagent correctness review (findings and resolutions posted as a PR comment).
  • Observed: the fleet red/green results above; the tagged dev build 26692-location-popover built from 4e48cab (job aa693f4d87688e3b99718780); CI gallery captures of 4e48cab (Linux Chromium, run https://github.com/manaflow-ai/cmux/actions/runs/40649941380). In the PR-dock states, before shows Session Info over the chat and composer, and after shows the chat with the composer clear.
  • Not run: a real-app macOS capture of the head.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 60350f8: 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=pr26764 -f ref=feat-cmux-next-26692-location-popover -f platform=macos -f backend_mode=local

Probably yours: session-info-placement.test.ts fails here but not on main's latest full suite. Seen on other PRs too (likely flaky): composer-menu-dismiss.test.ts, composer-menu-dismiss.test.ts, composer-menu-dismiss.test.ts and 9 more.

CI failed on 60350f8877 (run 41782317537 attempt 1): 2 code, 1 unknown.

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

Failures:

  • seen on other PRs composer-menu-dismiss.test.ts chromium: agent-pane.composer new-chat-reasoning at 760 px: with a menu open, one press on another c...: failed (job)
  • seen on other PRs composer-menu-dismiss.test.ts chromium: agent-pane.new-tab reasoning-chip at 760 px: with a menu open, one press on another chip o...: failed (job)
  • seen on other PRs composer-menu-dismiss.test.ts webkit: agent-pane.composer new-chat-reasoning at 760 px: with a menu open, one press on another chi...: failed (job)
  • seen on other PRs composer-menu-dismiss.test.ts webkit: agent-pane.new-tab reasoning-chip at 760 px: with a menu open, one press on another chip ope...: failed (job)
  • seen on other PRs thread-minimap-rail.test.tsx a bookmark shows as the tick's dot; the prompt row, dot and card share its state: failed (job)
  • seen on other PRs transcript-chevron-after-label.test.ts agent-pane.claude-desktop-organization#shared at 760px: every chevron starts within 8px after its wo...: failed (job)
  • seen on other PRs transcript-chevron-after-label.test.ts agent-pane.claude-desktop-organization#shared at 420px: every chevron starts within 8px after its wo...: failed (job)
  • new in this PR session-info-placement.test.ts chromium: in a 740px pane it lies over the chat above the composer, and the composer shows whole: failed (job)
  • seen on other PRs new-tab-live-resize.test.ts webkit: the composer page follows a live resize: failed (job)
  • seen on other PRs new-tab-live-resize.test.ts webkit: the threads page follows a live resize: failed (job)
  • ... 3 more in the job logs
Matched log lines
web / react-apps-base-check (6): (fail) chromium: agent-pane.composer new-chat-reasoning at 760 px: with a menu open, one press on another chip opens that one [6348.08ms]
web / react-apps-base-check (7): (fail) webkit: the composer page follows a live resize [5423.79ms]

Not re-run automatically: web / react-apps-base-check (6), web / react-apps-base-check (7), 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: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on 3e4549c to compare; do not merge until green; see lane-rules
red: web / Web status; a job it gathers is red on this change (its line here); do not merge until green; see lane-rules
red: web / react-apps-base-check (6); NEW webview test reds: test/session-info-placement.test.ts > webkit: in a 740px pane it lies over the chat above the composer, and the composer shows whole; test/session-info-placement.test.ts > chromium: in a 740px pane it lies over the chat above the composer, and the composer shows whole; do not merge until green; see lane-rules
red: web / react-apps-base-check (7); NEW webview test reds: test/new-tab-live-resize.test.ts > webkit: the default page follows a live resize; do not merge until green; see lane-rules
red: web / react-apps-check; a job it gathers is red on this change (its line here); do not merge until green; see lane-rules

Tour of 4e48cabc58 (run): no media.

Stale: these images are of 3ca735c; the head is now 60350f8 and a new capture is running.

Gallery before/after for 3ca735c: 16 states rendered, 2 images differ, 3097 more touched states not rendered. Images are in the run's artifact, not on this public PR; the independent review of this head reads them on its own, so the PR needs no hand-made screenshots of these states.

gh run download 41592061608 -R manaflow-ai/cmux -n gallery-advisory-26764-3ca735c2f516eebbb18e459dda4a505fb879b6d2 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.changes-from-cache/rows Apple System Colors changed 5.06% own ChangesFromCache.gallery.ts
agent-pane.changes-from-cache/rows Apple System Colors Light changed 5.04% own ChangesFromCache.gallery.ts
agent-pane.chat-switch/first-chat Apple System Colors Light unchanged 0% own chatSwitch.gallery.ts
agent-pane.chat-switch/first-chat Apple System Colors unchanged 0% own chatSwitch.gallery.ts
agent-pane.chat-switch/second-chat Apple System Colors Light unchanged 0% own chatSwitch.gallery.ts
agent-pane.chat-switch/second-chat Apple System Colors unchanged 0% own chatSwitch.gallery.ts
agent-pane.chat-width/standard Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/standard Apple System Colors unchanged 0% own App.tsx
agent-pane.chat-width/wide Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/wide Apple System Colors unchanged 0% own App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-edge/short-edge Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-edge/short-edge Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-edge/wide-edge Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-edge/wide-edge Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-edge/no-edge Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-edge/no-edge Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-rest-gap/gap-40 Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-rest-gap/gap-40 Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-rest-gap/gap-56 Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-rest-gap/gap-56 Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-rest-gap/gap-72 Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-rest-gap/gap-72 Apple System Colors unchanged 0% own App.tsx
agent-pane.continuation-spacing/shipped Apple System Colors Light unchanged 0% own App.tsx
agent-pane.continuation-spacing/shipped Apple System Colors unchanged 0% own App.tsx
agent-pane.continuation-spacing/two-thirds Apple System Colors Light unchanged 0% own App.tsx
agent-pane.continuation-spacing/two-thirds Apple System Colors unchanged 0% own App.tsx

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

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

blacksmith-sh Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Found 14 test failures on Blacksmith runners:

Failures

Test View Logs
test/composer-menu-dismiss.test.ts/composer-menu-dismiss.test View Logs
test/composer-menu-dismiss.test.ts/composer-menu-dismiss.test View Logs
test/new-tab-live-resize.test.ts/new-tab-live-resize.test View Logs
test/new-tab-live-resize.test.ts/new-tab-live-resize.test View Logs
test/new-tab-live-resize.test.ts/new-tab-live-resize.test View Logs
test/new-tab-live-resize.test.ts/new-tab-live-resize.test View Logs
test/session-chip-browser.test.ts/session-chip-browser.test View Logs
test/session-chip-browser.test.ts/session-chip-browser.test View Logs
test/session-info-placement.test.ts/session-info-placement.test View Logs
test/session-info-placement.test.ts/session-info-placement.test View Logs

...and 4 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

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

@austinywang

Copy link
Copy Markdown
Contributor Author

Correctness review (subagent), head 4e48cab

The reviewer looked for any path that still opens Session Info without a click: the per-pane store defaults, shownFor / bind across chat and harness switches, the old shared OPEN_KEY, saved state from before the fix, and every caller that reveals the Inspector in App.tsx. It found none. Every remaining opener is a user action (header toggle, command palette, running-line count, tray row, Changes or context buttons).

Findings and resolutions:

  1. Medium: a harness switch on an empty new chat goes through bind(""), and that closed a Session Info the viewer had just opened. Fixed in 4e48cab: a bind with no session keeps what the pane shows, and only a switch from one chat's session to a chat with nothing saved shows it closed. The regression test covers it.
  2. Low: useInspectorOpen() with no chat returned the closed copy instead of the bound pane's state. Fixed by the same change: shownFor with no session returns current().
  3. Low: the gallery plays clicked the toggle unconditionally, so a state that was already open would close. Fixed: the plays open Session Info only when it is not shown.
  4. Nit: a misleading comment in background-task-arrival.test.tsx. Fixed.

No open findings.

austinywang added a commit that referenced this pull request Oct 28, 2026
austinywang added a commit that referenced this pull request Oct 28, 2026
austinywang added a commit that referenced this pull request Oct 28, 2026
austinywang added a commit that referenced this pull request Oct 28, 2026
austinywang added a commit that referenced this pull request Oct 28, 2026
austinywang added a commit that referenced this pull request Oct 28, 2026
@austinywang

Copy link
Copy Markdown
Contributor Author

Visual review: FIX (advisory)

Head 4e48cabc589c (base 17dfb9d32057), reviewer claude-opus-5-5 visual-review subagent.

Merge: advisory, no fix finding is on a real-app capture (fleet DEV capture or media tour); Linux, Chromium or WebKit-pane renders of macOS UI never block, confirm on the real app.

Linux Chromium renders show the intended change: Session Info is gone from the PR dock stories that are not about it, and it looks the same where a story opens it. Advisory FIX only because there is no real-app or macOS WebKit capture.

Evidence: linux · fallback fonts · Chromium (component).

Criterion Result
evidence fail
intent pass
layout pass
contrast pass
unintended pass
frames pass
taste n/a

Findings:

  1. fix [evidence] All 32 images are Linux Chromium renders with fallback fonts (gallery-advisory run 40649941380). There is no real-app or macOS WebKit capture of this macOS agent pane. Add a real-app capture of the tagged build 26692-location-popover that shows a new chat with Session Info closed and the composer uncovered, then the same chat after a header-toggle click with Session Info open. (11-after-agent-pane-pr-dock-collapsed-line.png at 0,0 840x840)
  2. note [intent] As intended: the floating Session Info panel that covered the user message, the 'Worked for 4m' row and the chat in before is gone in after. The chat and the PR chip row are fully visible, and the header list toggle shows its inactive weight. The same holds in 12 (dark), 13, 14, 15 and 16. Nothing to change. (11-after-agent-pane-pr-dock-collapsed-line.png at 184,56 640x490)
  3. note [layout] The stories that open Session Info explicitly match before: 23, 24 (none-session-info), 01, 02 (changes-from-cache), 07 to 10 (reopened, resize-handoff), 27, 28 (scrollbar-edge open) and 29, 30 (workflow running). The pairs are pixel-identical or differ only at the sub-pixel level. Placement, width and rows are unchanged. Nothing to change. (23-after-agent-pane-pr-dock-none-session-info.png at 184,56 640x556)
  4. note [frames] The only visible difference in 29 and 30 is the running timer ('4s' to '5s') and the spinner frame on the 'punchy' row. That is capture timing, not this change. If the diff noise matters, pin the gallery clock. (29-after-agent-pane-workflow-pane-running.png at 240,700 530x40)
  5. note [unintended] The 'Browser pane messes the UI state when switching from one workspace to another #130 atlas-web Doc...' chip is cut off at the right edge. Before shows the same cut, and it is the collapsed-line scroll layout, so this is not a regression from this PR. Needs a macOS confirm with the system font, because the chip widths differ from SF. (11-after-agent-pane-pr-dock-collapsed-line.png at 540,562 300x52)
Contact sheet (before | after)

Captures: https://github.com/manaflow-ai/cmux/actions/runs/40649941380

@austinywang austinywang added media-tour Run the cmux-next UI tour (cmux-next-media.yml) on every push media-tour-mac and removed media-tour Run the cmux-next UI tour (cmux-next-media.yml) on every push labels Oct 28, 2026
@austinywang

Copy link
Copy Markdown
Contributor Author

Screenshot evidence for head 4e48cabc589c3318b3bef5e0aa799a08f6d837ab (#26764):

@austinywang austinywang added the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Oct 28, 2026
@austinywang austinywang removed the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Oct 30, 2026
@austinywang

Copy link
Copy Markdown
Contributor Author

Visual review: FIX (advisory)

Head 17d1765576c1 (base 6becf19d87d1), reviewer claude-opus-5-5 visual-review subagent.

Merge: advisory, no fix finding is on a real-app capture (fleet DEV capture or media tour); Linux, Chromium or WebKit-pane renders of macOS UI never block, confirm on the real app.

Gallery renders show no visual change: Session Info looks identical where the play now clicks it open, and new-chat stays closed. Only Linux fallback-font captures exist, so a real-app capture is still required.

Evidence: linux · fallback fonts · Chromium (component).

Criterion Result
evidence fail
intent pass
layout pass
contrast pass
unintended pass
frames pass
taste taste

Findings:

  1. fix [evidence] All 32 states are Linux Chromium renders with fallback fonts, not the macOS system font. Session Info ships in the macOS app, so none of these count as evidence. Get a real-app capture of the head (cmux NEXT DEV build) showing a new agent chat with Session Info closed, then the same chat after a header-toggle click with it open. (31-after-agent-pane-docked-chat-new-chat.png at 0,0 600x1280)
  2. note [unintended] The 01/02 pairs differ only by sub-perceptual pixels (0% changed); the open panel looks the same now that the play clicks it open. Pairs 03-32 are byte-identical, and the docked-chat new-chat state is closed both before and after. No unintended change. (01-after-agent-pane-changes-from-cache-rows.png at 184,56 640x714)
  3. taste [taste] This predates the PR (same in before and in dark 02). Through the panel's translucent material, the user bubble's text ('nd') shows just under the Save button, so Save reads as if it collides with ghost text. Leo should decide whether the floating panel needs a more opaque fill behind its header row. Confirm on a macOS capture. (01-after-agent-pane-changes-from-cache-rows.png at 600,70 220x160)

Captures: https://github.com/manaflow-ai/cmux/actions/runs/40980806460

Images stay in the gallery artifact of the captures run (not uploaded to this public PR).

@austinywang

Copy link
Copy Markdown
Contributor Author

Correctness review (subagent), head 17d1765576c1f2d42cf816cb9bbf0afb5c01dd96

Head c883be8 was brought up to date with feat-cmux-next (merge e277e416). The only conflict was summary/PullRequestDock.gallery.ts, where the base had moved the old PR-dock variants to PullRequestDockComparisons.ts (#26082). I kept the base file and moved this PR's "open Session Info" play onto the none-session-info variant in its new home.

The reviews ran in three rounds on the merged head. Findings and how each was resolved:

  1. Bug: when the host gave the tab a new chat (the handshake reset to an empty snapshot), the pane went from session X to no session to session Y. The store treated that like a harness switch, so Session Info stayed open over the new chat and was then saved open under it. Fixed in 0701057: App.tsx calls startNewInspectorChat() on that reset. A harness switch still keeps the viewer's own open.
  2. Bug: the gallery play for agent-pane.workflow-agent-pane/open-agent still depended on the old default-open behavior. Fixed in 0701057: the play clicks Session Info open first.
  3. Risk: between startNewInspectorChat() and the pane's rebind, a fold, width or Sources change could save "closed" under the chat being left. Fixed in be97c32: nothing is saved under that chat until the pane binds again.
  4. Minor risk: a reconnect of a new chat with no session yet could close a panel the viewer had just opened. Fixed in be97c32: a reconnect calls the reset only when a session was shown.
  5. Risk: a reset that resolved back to the same chat left the "leaving" marker set, so that chat stopped saving. Fixed in 17d1765: a same-session bind while leaving clears the marker and restores the chat's saved state.
  6. Accepted: a direct switch from X to Y (a fork or create in the tab) shows Y closed when Y has nothing saved. That is intended: a new session is a new chat.
  7. Nit, kept: setOpen still writes the old shared open key. A comment now says it is kept only for downgrade. No default reads it.
  8. Residual, not fixed: during a very short window, a reconnect that arrives before a new chat's first frame reads the previous session from snapshotRef and can close an early open. Resetting that ref would affect other handshake logic, so I left it alone.
  9. Nits, no change: a hand-back with storage unavailable leaves the chat closed, and a one-frame closed flash can show on the chat being left.

Tests. bun test test/inspector-per-pane-state.test.ts ran on a Freestyle node VM for each fix:

  • reverting 0701057 fails with startNewChat is not a function;
  • reverting be97c32 fails with Expected true, Received false;
  • reverting 17d1765 fails with Expected true, Received false;
  • with all three fixes in, 13 pass.

The other webview suites and bun run check run in CI. The Freestyle sync covers only part of the repo, so they could not run there.

Checks on the head. Every finished check is green except one, release-notary ("Test What's New highlights and release notes"). It fails on the highlight files inline-pr-pills.md and inspector-error-colours.md, which come from the base and are not in this PR. The same job is red on feat-cmux-next 0da5bc33: https://github.com/manaflow-ai/cmux/actions/runs/40977720201/job/123809774330. On the earlier head, "Familiar intent review warning" failed only because it hit the GitHub API rate limit (infrastructure).

No open correctness findings.

@austinywang austinywang added the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Oct 30, 2026
@austinywang

Copy link
Copy Markdown
Contributor Author

Review (subagent, correctness first): SHIP at 17d1765

Three review rounds ran on this head's changes, and every finding is resolved (see the correctness review comment above). The visual review is advisory: its only fix finding is that the evidence is Linux-only, it found no visual defect, and it does not block. The only red, release-notary, also fails on the base: https://github.com/manaflow-ai/cmux/actions/runs/40977720201/job/123809774330.

@cursor

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

@austinywang

Copy link
Copy Markdown
Contributor Author

Sweep: blocker was a red inherited from base (nightly-guards release-notary failed on base's chat-find-keeps-place.md highlight, not this PR's files; fixed on base since). Merged origin/feat-cmux-next at f8bd6ac cleanly (new head 85e982c). This head needs CI and a review receipt before relabel.

@lawrencecchen

Copy link
Copy Markdown
Contributor

Review (claude-indep-reviewer): SHIP at 85e982c

Checked. I read the full diff from merge-base f8bd6ac189 to this head. That is 13 files, all under webviews/. I also read the code around it: ChatInspector.tsx (bindInspectorPane(paneSession) in a layout effect, useInspectorOpen/useInspectorState callers) and the handshake reset in App.tsx. This head is a clean merge of feat-cmux-next into 17d1765. The PR's own diff is the same as at 17d1765; only the context lines moved.

Correctness. I traced every way the pane moves between chats against inspectorState.ts:

  • Host hands the tab a new chat (newSession and no sessionId): startNewChat sets leaving = X and closes, then the empty snapshot calls bind(undefined), which clears leaving and pane. An open made before the first prompt is then saved under Y by bind(Y), because left is false.
  • Direct X to Y with nothing saved for Y: shownFor(Y) returns closed() from the first frame, and bind(Y) saves it closed.
  • Hand-back of X after the reset: either the same-session branch restores X's saved state and clears leaving, or bind(undefined) and then bind(X) restores it.
  • Harness switch (X, then no session, then Y, with no reset): keeps the viewer's open. This is intended.
  • Reconnect of a new chat with no session yet: does not reset.

No path opens Session Info without a click. While leaving is set, nothing is saved under the chat the pane left. closed() keeps one object per source state, so the useSyncExternalStore snapshots stay stable. The version gate (open && v === 2) reads an older open: true as closed. This also closes chats where the viewer opened Session Info on purpose before the upgrade. It happens once, and the PR body says so. I accept it.

Repo rules. The PR has no Swift and no animation, dialog, shortcut or action-handler changes. It adds no user-facing strings, so it needs no localization audit. The gallery plays open Session Info only when it is closed, so they do not depend on a fixed order.

Tests. The new case in test/inspector-per-pane-state.test.ts covers the first chat, the old shared key, the unversioned saved open, a direct switch, a harness switch, startNewChat, a hand-back and an early open. The PR body records it red on the base (job feb486d0fa498ff147ac547f) and green with the fix.

Compile evidence for this head. A green compile exists for this webviews-only change:

  • web / react-apps-check and its shards (1) to (4) passed.
  • Shard (2) ran "Check webviews (Oxlint, Oxfmt, type check)", which passed.
  • "Test webviews" passed on all four shards.
  • web / Web status, ci-status, pr-capture-check and cmux-next checks passed.

The Swift Release compile is neutral ("shared HQ slot is busy"). This PR changes no Swift, so it does not need that compile.

Red checks: all from the base, none from this PR.

  • nightly-guards / workflow-guard-tests / release-notary: test_every_listed_hook_is_one_glaeda_released_with_the_check fails, which is signing-hook tooling. The nightly-guards workflow is red on almost every run in this time window, including many feat-cmux-next pushes such as ea1a330836, 35c02175a6 and 397ab56025.
  • nightly-guards / Guard status: only reports the red above.
  • defaults guard: ModuleNotFoundError: No module named 'pr_status' in the workflow script. This is not in a file the PR changes.

Risk tier. risk:normal is correct. The PR changes webview UI state logic only. It has no auth, migration, release or user-data deletion changes.

Notes (not blocking).

  • No test covers the one-line App.tsx:8243 call that connects the handshake reset to startNewInspectorChat(). If you remove that line, the store test still passes. A store test does not exercise the handshake.
  • Leftover risk that the author accepted: a reconnect that comes before a new chat's first frame can close an early open for a moment (PR comment, item 8).

@lawrencecchen lawrencecchen removed the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Oct 31, 2026
@lawrencecchen

Copy link
Copy Markdown
Contributor

Merged origin/feat-cmux-next into this branch (merge commit c9ba470, no rebase, no force push). One conflict in webviews/src/agent-session/acpmux/App.tsx at the handshake reset: feat only reformatted the setSnapshot call to several lines; the resolution keeps this PR's { ... startNewInspectorChat(); ... } block and feat's format.

Checks on this head: prepush-gate.py no new violations; vp fmt --check and vp lint on the PR's files pass; bun run typecheck (webviews) passes. The pre-push web lint was skipped with CMUX_WEB_LINT_SKIP_REASON: check:browser-lanes (test/composer-draft-overflow.test.ts:434), vp fmt --check (src/pages/settings/*) and vp lint are red on base 9b6c218 in files this PR does not touch. Web-only change: no Swift/Rust fleet compile. Removed ready-to-land until a fresh review receipt on this head.

@lawrencecchen

Copy link
Copy Markdown
Contributor

Review (claude-reviewer-26764): SHIP at c9ba470

Scope: PR #26764 (webviews only), head c9ba470, merge commit of origin/feat-cmux-next (parent 2) into the PR head 85e982c (parent 1). Read-only review. I did not compile, run tests, edit, push, or change labels. Searches were scoped to /work/wt/resolve-26764.

Verdict: no blocking findings. The merge keeps both sides in full.

Merge resolution (checked, correct)

  • git diff c9ba470b325^2 c9ba470b325 --numstat (the feat side against the merge) is identical to the PR's own change against the merge base f8bd6ac for all 13 PR files. Only these 13 files differ from feat. Nothing else from feat was lost.
  • The only feat-side change to any PR file since the merge base is webviews/src/agent-session/acpmux/App.tsx. For the other 12 PR files, the merge equals the PR head.
  • webviews/src/agent-session/acpmux/App.tsx, feat against merge (the only change): the PR's { ... startNewInspectorChat(); ... } block around the handshake reset, plus the import startNewInspectorChat. Feat's multi-line setSnapshot((previous) => ({ ... })) reformat is kept. The PR's single-line form is gone, which is the intended resolution.
  • The merged App.tsx contains feat's 699-line App.tsx change and the PR's 8-line change. Braces at the handshake block are balanced. reconnect is in scope (let reconnect at App.tsx:8344).

Feat additions since f8bd6ac (no default-open assumption found)

  • Feat-changed galleries (ComposerContext, HostError, ProjectChooser, LaneNoticeBatch, NewTabScreen, contextMenus, stats, FeatureTip): none depends on Session Info opening.
  • Feat-changed tests (changes-status, clickable-cursor, reopened-chat-history, subagent-tray, workflow-tasks, featureTips): none depends on it.
  • Every programmatic open path (setInspectorOpen(true), reveal(...): context command, running-line counts, workflow card, subagent and command rows) is a viewer action. None fires on its own.
  • webviews/test/latency/actions.ts:945: the comment "The flows fixture opens Session Info" is stale. The bench still works, because flowChat closes it first.

PR's own change (inspectorState.ts, App.tsx, galleries, tests)

  • defaults() opens closed. Saved state carries v: 2. Older saved opens read as closed. This matches the intended migration.
  • startNewChat / bind / closed() / leaving: I traced the handshake path. The reset empties the snapshot in the same batch, so bind(undefined) runs first. That clears leaving and pane, so a viewer's open before the first prompt survives. The store tests at inspector-per-pane-state.test.ts:120-143 cover this.
  • No added line is longer than 120 columns.

Non-blocking notes (no fix needed for SHIP)

  1. Coverage gap, App.tsx:8469-8480. The handshake call to startNewInspectorChat() is not tested at the App level. The store-level test covers the store only.
  2. Unconfirmed residual, App.tsx:8200 (receive). A client frame that goes from chat A straight to a frame with no session id does not call startNewChat(). Then bind(undefined) clears pane, and the next chat with no saved state keeps A's open state. I did not confirm that any client or host path sends that frame. If one exists, the new chat opens Session Info by itself, which is the bug cmux NEXT: agent chat location popover (machine/folder/repo/branch) pops up after every chat #26692 describes.
  3. Advisory gallery, summary/PullRequestDockComparisons.ts: the pr-dock compact, collapsed and full variants have no play. They now draw with Session Info closed. This changes screenshots only.

Not run: compile, lint, unit tests, browser lanes, gallery. Checks were by reading the diffs and call sites.

@lawrencecchen lawrencecchen added the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Oct 31, 2026
@lawrencecchen lawrencecchen removed the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Oct 31, 2026
@lawrencecchen

Copy link
Copy Markdown
Contributor

Removed ready-to-land: this PR conflicts with feat-cmux-next (DIRTY), so no merge can take it. Merge feat-cmux-next into the branch, resolve, and get a new receipt at the new head; then add the label again.

@teamleaderleo

Copy link
Copy Markdown
Collaborator

For awareness: this PR has a SHIP review at its head, but GitHub reports it as conflicting with feat-cmux-next, so the lander's update-branch can't merge it and it can't land as is. Files that conflict in a test merge against the current base: webviews/src/agent-session/acpmux/App.tsx, webviews/src/agent-session/acpmux/session-info/ChangesFromCache.gallery.ts, webviews/src/agent-session/acpmux/session-info/SessionInfoMotion.gallery.ts, webviews/src/agent-session/acpmux/session-info/sessionInfoState.ts, webviews/src/agent-session/acpmux/summary/PullRequestDockComparisons.ts, webviews/test/agent-pane-background-tasks.test.ts and 2 more. Once feat-cmux-next is merged into the branch and the conflicts resolved, it needs only a quick review of the resolution before it can land. (From the conflict sweep; no push was made to this PR.)

@austinywang

Copy link
Copy Markdown
Contributor Author

Merged current feat-cmux-next (head 08a0f43)

I merged origin/feat-cmux-next at 5de3c47 into the branch. It is a plain merge, so no force-push was needed.

How the conflicts were resolved

  • inspector/ → session-info/ rename: the PR's change now lives in session-info/sessionInfoState.ts.
    • It saves v: 2 (STORED_VERSION) next to base's sections and more. An older auto-saved open: true now reads as closed; the saved width, folds, sourcesAll and more are kept.
    • defaults() sets open: false.
    • fresh(key, left) combines this PR's rule with base's split-pane rule (agent pane: a chat opened in a split starts with Session Info closed #32763): Session Info starts closed when another chat's session is replaced in the pane, or when the key is split:.
    • startNewSessionInfoChat replaces startNewInspectorChat, and App.tsx's handshake reset calls the new name.
  • Selector rename: every gallery and test now uses .acpmux-session-info instead of .acpmux-chat-inspector. The PR's click-to-open plays are kept.
  • PullRequestDockComparisons.ts: base deleted this file (Agent chat: remove the PR chip row from transcript messages #29614), so the merge follows that.
  • session-info-per-pane-state.test.ts: it now folds Context, which base made open by default (Session Info: Context opens by default #30269).

Correctness review (subagent): FIX, all findings resolved in 08a0f43

  1. Base's test "late root identification retires phantom progress from the inspector" (from fix(agent-pane): show workflow progress in tray and inspector (carry of #27886) #29777) expected Session Info to open by default. Fixed: the test now opens it from the toggle. That test passes 2/2 when run on its own.
  2. The prompt-rail gallery variant session-info-hovered (from Prompt rail: hoverable when the chat column is narrower than its pane #32758) never opened Session Info. Fixed: its play opens Session Info from the header toggle first.
  3. The chat-switch experiment's second chat showed Session Info closed. Fixed: the experiment saves that chat open, so the panel carries across the switch. Also corrected a stale comment in AppWindow.gallery.ts.
  4. Low, robustness only: if React ever batched the handshake's empty snapshot with the returning chat's first frame, bind would not re-run and leaving would stay set. Not changed: the two arrive in separate tasks today. I'm leaving it as a possible follow-up.

The reviewer confirmed the following:

  • Snapshot identity for useSyncExternalStore is stable.
  • The versioning is correct.
  • The App.tsx hunk is correct.
  • No stale Inspector* state exports are left.

Tests run (local bun test, one file at a time; the host was under heavy load, so a few first runs hit 5 s timeouts and passed on rerun):

Test file Result
session-info-per-pane-state 14/14
session-info-split-starts-closed 3/3
session-info.test.tsx 36/36
session-info-surfaces 22/22
session-info-dead-clicks 7/7
session-info-subagent 1/1
subagent-tray 42/42
access-chip-pending-warning 11/11
chat-header-every-tool-acts 2/2
clickable-cursor 6/6
background-task-arrival 7/7
native-session-info-toggle 5/5
session-info-motion 5/5
session-info-reveal 5/5
agent-pane-workflow-progress late-root 2/2; the usage-only tests time out under load on both head and base
  • scripts/web-lint.sh: passes. prepush-gate.py: no new violations.
  • Base red: test/session-info-width-stages.test.ts fails 2 tests both on this head and on base 5de3c47 itself. It is a pure-function test, so this failure is not caused by this PR.

Not run: browser-lane and Playwright tests (reviewed by reading only) and the gallery captures (CI runs those as advisory).

@cursor

cursor Bot commented Nov 3, 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.

@austinywang

Copy link
Copy Markdown
Contributor Author

Ready for review: head 3ca735c

On top of the merge comment above, 3ca735c fixes this PR's only CI red of its own. Base's newer gallery variant agent-pane.workflow-agent-pane#open-agent-in-chat expected Session Info to open by default, so its play now opens it from the toggle the same way its sibling variant does. On this head it is no longer red.

CI on 3ca735c: MERGEABLE, no unresolved review threads. Every remaining red is a base finding, not this PR's:

I have not merged this PR, and I left the labels as they are.

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Review (codex gpt-6.1-sol xhigh, next-review): SHIP at 3ca735c

SHIP at 3ca735c

Visual verdict: no introduced visual regressions across all 16 supplied before/after pairs.

Reviewed state transitions and persistence; 17 store checks passed in a Node adaptation. Bun/browser tests were unavailable locally.

Follow-ups: none

A chat with no saved state starts with Session Info closed, a pane moving
to a new chat shows it closed from its first frame, and saved per-chat
state carries a version so an open written by the old default reads as
closed. Tests and gallery plays that relied on the old default open
Session Info the way a viewer does.

Rebased onto feat-cmux-next b4570f1 as the PR's net change: the
branch's last merge already carried the Inspector -> Session Info rename,
so its original commits are folded into this one. Merged with the base's
per-tab Session Info state: saves go under the tab's and the chat's keys
with the version, a tab change while a pane is leaving its chat does not
re-bind the chat it left, and a chat handed back is read through the
tab's own key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@austinywang
austinywang force-pushed the feat-cmux-next-26692-location-popover branch from 3ca735c to 60350f8 Compare November 4, 2026 05:56
@austinywang

Copy link
Copy Markdown
Contributor Author

Correctness review of the rebase onto feat-cmux-next b4570f16cc (head 60350f8877), by a subagent, independent of the resolution:

  • No findings. All 16 files match the PR's original change, apart from the merge in sessionInfoState.ts. That file keeps both the PR's changes (closed default, v: 2, leaving/startNewChat) and the base's per-tab state (tab/savedFor/setTab).
  • Save path: save() writes v: 2 under both the tab entry and the chat key.
  • Hand-back: a chat handed back is read through savedFor, the tab entry first.
  • setTab while leaving: setTab returns early while a pane is leaving its chat. Without that return, a tab change during a new chat would re-bind the chat being left and show its saved open state.
  • Handshake order in App.tsx: setSessionInfoTab runs before startNewSessionInfoChat, synchronously and before a frame draws. It is safe either way.
  • Base tests: session-info-per-tab-state passes against the merged store. The full fleet run passes every Session Info test (see the PR body).

This branch was previously deployed

3 inactive (2 outdated) deployments
ci-routing-agent — 60350f88 Deployed Nov 4, 2026 by austinywang via cmux-tui tree preflight #109954
artifacts — c9ba470b Deployed Oct 31, 2026 by lawrencecchen via publish tree-addressed cmux-tui #87502
sentry-dsyms — c9ba470b Deployed Oct 31, 2026 by lawrencecchen via upload cmux-tui dSYMs to Sentry #87502
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

media-tour Run the cmux-next UI tour (cmux-next-media.yml) on every push media-tour-mac risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants