Repository navigation
Agent header: the open panel's toggle requires its filled square; Esc closes native Session Info after a click in it - #32704
Conversation
… Esc after a click in native Session Info closes it chat-header-plain-icons (red on base since #32687 added the pressed and hover pill) now refuses a fill at rest and requires one on a pressed tool in the chat header, tab row and floating chat; the gallery's plain-icons play follows, and session-info-open[-accentless] check the open toggle's square and lit ink and nothing behind the other tools, in the default and an accentless dark theme. The bun toggle test asserts the page posted on mount and runs the old host's close script from the Swift template (a SyntaxError in its pre-#32673 form). AgentPaneNativeSessionInfoTests gains the native Esc case: red here, the panel never takes the keyboard on a click. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-7a7568197607c3cdfb81
… so Esc closes it The page's Esc handler closes Session Info only from its toggle or panel; after a click in the App's panel the keyboard stayed in the page (the composer, say), so Esc never reached the panel's cancelOperation. A press on a line, a button, the edge or empty glass now makes the panel first responder (no ring), as a click in the page's panel focused it; when it closes with the keyboard in it, the chat takes the keyboard back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-7a7568197607c3cdfb81
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Gallery before/after for
States
Pick other states with a Unclear: CI failed on
Failures:
Matched log linesNot re-run automatically: Written by red: web / Web status; a job it gathers is red on this change (its line here); do not merge until green; see lane-rules Shipped in:
|
… lint splits selectors at the top level Review follow-up: the hover pill rule (0,4,0) outranked the pressed and menu-open square (0,3,0), so an on toggle under the pointer showed the lighter hover tint, which chat-header-tab-row-surface's pressed-hover case already expects not to happen. The hover pill now excludes [aria-pressed=true] and [data-popup-open]. chat-header-plain-icons splits selector lists at top-level commas (not inside :is or :not), ignores lit states inside :not(...), and asserts the hover fill excludes the pressed state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-7a7568197607c3cdfb81
Bugbot needs on-demand usage enabledBugbot 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
left a comment
There was a problem hiding this comment.
Review (claude-opus-5-5): SHIP at 2d0c2ee
Review (subagent claude-opus-5-5): SHIP at 2d0c2ee. Visual verdict: the pressed header toggle keeps its filled square under the pointer (the hover pill no longer outranks it); no fill at rest. Checked: the static lint matches header.css and requires a pressed fill on all three hosts; the gallery probe compares lit ink correctly; the old-host script regex and escaping; the panel takes first responder on a click (no ring), and tryToPerform reaches cancelOperation; the :not() list is supported in WebKit and Chromium and fixes chat-header-tab-row-surface's pressed-hover case. bun 8/8. Compile check CmuxNext passed at 611bad3 (Swift unchanged since). Follow-ups: dedupe the :not-stripping regex in the lint; focusChat on panel removal also runs when the setting turns off.
…t accepts its form Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-7a7568197607c3cdfb81
|
Found 4 test failures on Blacksmith runners: Failures
|
… with node:vm, not the Function constructor (#32760) Oxlint typescript(no-implied-eval) refused the two `new Function(...)` calls that 419a87a (#32704) added to webviews/test/native-session-info-toggle.test.tsx, so `vp lint` and `vp check` in webviews `bun run check` are red on the feat-cmux-next tip. The test keeps its intent: `new vm.Script` still throws SyntaxError for the pre-#32673 `?.action?(` form, and the real script runs in a new context whose `window` holds the page bridge, as gallery-web-theme-bootstrap.test.ts already does. With `window: {}` instead of the bridge the test fails. bun test test/native-session-info-toggle.test.tsx: 5 pass. bun run check (webviews): exit 1 on the base, exit 0 on this commit.
…prit (#34629) * base red: the Chief teleport chip's tooltip is the themed one (NativeTooltipGuardTests, from 894d34f) 894d34f (Chief teleport: location chip, Teleport menu) set the chip's tooltip with toolTip =, which draws macOS's stock bubble; NativeTooltipGuardTests refuses it (Leo 2026-10-12/20: every hover is themed or gone). It is themedToolTip now (TooltipPresenter draws it). Same text. * base red: the All Themes Playground's sample hover is the themed one (NativeTooltipGuardTests, from c0230ef) c0230ef (Status dots keep their hue at 3:1 in every theme; All Themes Playground) put .help( on each sample, which draws the stock bubble; NativeTooltipGuardTests refuses it. It is .themedHelp( now. Same text. * base red: BrowserChromeIconsTests follows 9d31a6e's one app-wide ⋮ (test only) 9d31a6e (one pane ⋮ size and column, Lawrence msg 19627: "the three vertical dots, there are 2 of them, and they are different sizes") made the browser toolbar's More draw the app's action.more.vertical on purpose, with a chrome-icons allow comment. The test still asked for Chrome's icon there. More joins the buttons that keep cmux's icon, and a new case pins its ⋮. * base red: PaneChromeEvenInsetTests follows 9d31a6e's trailing control column (test only) 9d31a6e put the tab bar's ⋮ center on Metrics.paneTrailingControlCenter, the browser toolbar's ⋮ column (Lawrence msg 19627), instead of as far from the trailing edge as from the top. The test still asked for the old equal gaps (off by 2 pt in every density). It now checks the ⋮ center sits on that column. * base red: the status and unread dot tests read the dot's color in the scope that draws it (test only, after c0230ef) c0230ef (Status dots keep their hue at 3:1 in every theme; user 2026-11-03: "we need to make sure every single theme, all the UI elements are colored properly") made Palette.statusUnread/Attention/Error and notificationBlue theme colors: the system hue with its lightness moved per theme to 3:1 on the rows. The views draw them in performWithTheme; SidebarStatusColorTests, HomeSidebarUnreadDotTests and HomeUnreadBlueDotTests still read them outside any theme scope (the bare system color), so every comparison was off. They now read the expected color with the drawing view's performWithTheme. * base red: SidebarLookContractTests reads the hover close on the trailing column, after cad2620's row gap (test only) cad2620 (#32647, Leo 2026-11-02) moved each row's fill in from the sidebar's edge (6 pt compact, 8 pt comfortable) and kept every trailing mark on the grid's 24 pt line on purpose: "Trailing marks stay on the grid's 24 pt column". The close did not move, but the fill's end moved toward it, so at comfortable density the close ends 7 pt inside the fill, not the 8 pt row inset that theHoverCloseIsTheRowsTrailingX asked for (237 > 236.5). The test now checks that the close centers on the row's trailing column and stays inside its row. Other grid tests pin the column itself. * base red: AgentPaneNativeSessionInfoTests closes its windows and carries .closesItsWindows (from #32646) WindowCleanupCoverageTests asks every suite that opens a window to carry .closesItsWindows (#27236). 9c772fa (#32646) and 419a87a (#32704) opened a window in two tests and never closed it. Each now closes its window in its own teardown, and the suite carries the trait. * base red: AgentPaneChromiumMoveTests carries .closesItsWindows (from #32777) 872ef32 (#32777) added a suite that opens a window per test without the trait WindowCleanupCoverageTests asks for (#27236). Each test already closes its window; the suite now carries .closesItsWindows. * base red: AgentShareTests closes the Invite card's window and carries .closesItsWindows (from #33967) 26fd471 (#33967) opened a window for the Invite People card test and never closed it, in a suite without the trait WindowCleanupCoverageTests asks for (#27236). The test now closes its window, and the suite carries the trait. * base red: ColumnStripPageClipTests carries .closesItsWindows (from #32515) 9593a3a (#32515) added a test that opens a window, in a suite without the trait WindowCleanupCoverageTests asks for (#27236). The test already closes its window; the suite now carries .closesItsWindows. * base red: CookieImportConsentPanelTests closes its windows and carries .closesItsWindows (from #33066) 58ec39f (#33066) added tests that open a parent window and a consent panel and never close them, in a suite without the trait WindowCleanupCoverageTests asks for (#27236). The panel only orders out when it is answered. Each test now closes the panel and its parent in its own teardown, and the suite carries the trait. No source change. * base red: DebugNativeRowToolsFixtureTests carries .closesItsWindows (from #28618) 201e1de (#28618) added tests that open windows, in a suite without the trait WindowCleanupCoverageTests asks for (#27236). Each test already closes its window; the suite now carries .closesItsWindows. * base red: InspectElementNativeCostTests carries .closesItsWindows (from 7f2173f) 7f2173f added a test that opens a window, in a suite without the trait WindowCleanupCoverageTests asks for (#27236). The test already closes its window; the suite now carries .closesItsWindows. * base red: the two window-free suites in KeyboardResizeArrowDirectionTests carry .closesItsWindows (from #34123) 4f13a23 (#34123) put KeyboardResizeShownStepTests and KeyboardResizeTradeSettleTests in a file whose other suites open windows. WindowCleanupCoverageTests (#27236) reads the file, so every top-level suite there carries the trait. These two open no window; the trait only checks that. * base red: SidebarPaneGapTests carries .closesItsWindows (from #28052) 5b91230 (#28052) added tests that open windows, in a suite without the trait WindowCleanupCoverageTests asks for (#27236). Each test already closes its window; the suite now carries .closesItsWindows. * base red: the Link Hint suites close their shell windows and carry .closesItsWindows (from #32537) 67a63bd (#32537) gave the Link Hint test rigs a shell window (and one test a page window) that no test closed, in suites without the trait WindowCleanupCoverageTests asks for (#27236). Each test now closes its rig's windows in its own teardown, and both suites carry the trait. * base red: StatusIndicatorHiddenAncestorTests closes its windows and carries .closesItsWindows (from #34074) c35c2e2 (#34074) added a fixture that opens a window no test closed, in a suite without the trait WindowCleanupCoverageTests asks for (#27236). Each test now closes its fixture's window, and the suite carries the trait. * base red: ScreenshotsRememberedAccessTests carries .closesItsWindows (from efacde9) efacde9 added tests that open windows, in a suite without the trait WindowCleanupCoverageTests asks for (#27236). Each test already closes its window; the suite now carries .closesItsWindows. * base red: TabSwitchWorkBudgetTests sizes its strip for 30 tabs at 9d31a6e's minimum width (test only) 9d31a6e made the narrowest tab keep about four title characters: the minimum inactive width went from 48 to 72 pt compact (Lawrence msg 19596: "all here is ... which is not very helpful"). 30 tabs at 72 pt need 2160 pt, so the test's 1800 pt strip scrolled, and the switch scrolled it (occlusion passes 4 -> 75). The test reads the switch budget of a row where every tab shows, so its strip is now as wide as 30 tabs at the strip's own minimum need. * base red: the omnibar's own field editor pads its line by 2 pt from the start (OmnibarFocusLayoutShiftTests, from 15972f3) 15972f3 ("Palette: the empty field's caret sits at the placeholder's left edge") removed EditorAlignedTextFieldCell's fixed 3 pt shift and draws the resting line at the title rect, with the line padding of the field's editor. The palette's editor is AppKit's shared one, already at the field editor's 2 pt padding. The omnibar hands out its own OmnibarFieldEditor, a new text view at TextKit's 5 pt padding until it first edits. So at rest the address drew 3 pt right of where focus puts it (OmnibarFocusLayoutShiftTests: editing x 3, rest x 6), a layout shift on the first focus (user, 2026-10-27: "after focus on omnibar there is layout shift"). The omnibar's editor now starts at the 2 pt padding a field editor has.
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Summary
Leo (2026-11-02, softened): "the entire point was to have it look good work good HAVE THE TOGGLED HIGHLIGHT". His reference image (the header with its list button highlighted, then the other tools) settled the design: a toggled-on header button gets a filled rounded square (the hover pill's size, a subtle tint) plus the lit ink. Every other button has no fill at rest. #28962 removed only the resting fill.
#32687 already put the pressed and hover square into
header.css. This PR:webviews/test/chat-header-plain-icons.test.tsstill forbade every fill and expected the focus rule's oldbackground:none. It now refuses a fill on any header-tool rule that isn't in a lit state (:hover,[aria-pressed=true],[data-popup-open]). It also requires a pressed fill in the chat header, the tab row and the floating chat. I checked that it goes red if the pressed fill is removed or a resting fill is added.agent-pane.header-tools). Theplain-iconsplay now requires the pressed toggle's square and refuses a fill at rest. Newsession-info-openandsession-info-open-accentlessvariants assert that the open Session Info toggle has a non-transparent background and the lit ink, and that every other tool at rest is transparent. They run in the default theme and in an accentless dark theme, where the ink alone read as off.AgentPaneSessionInfo.actionScriptand runs it against the page bridge, so it would fail on the pre-Session Info: native panel close reaches the page on every host, so the header toggle clears #32673 form. I checked: red with the old template, green now.AgentPaneNativeSessionInfoTests.aClickInThePanelTakesTheKeyboardSoEscClosesItcovers it.Specs:
design/chat-header.md("Header buttons draw no plate, pressed included (cmux#28962)") is updated in a leo-workspace notes PR: pressed = filled rounded square + lit ink, rest = no fill.design/session-info.md: "Its header toggle and Esc (from inside it) close it."References (cmux-design-references ids):
cmux/live/top-right-toolbar-actions,cmux/live/sidebar-session-info-button-strip,cmux/live/toolbar-top-right-stray-line.Out of scope: the native pane toolbar (
PaneToolbarView, Debugchrome.tabs.nativeRowTools, off by default) keeps its ink-only toggled state.Test plan
cd webviews && bun test test/chat-header-plain-icons.test.ts test/native-session-info-toggle.test.tsx: 8 pass (head). The plain-icons lint fails on base at 0f0ebe5 (2 of 3).scripts/web-lint.sh: passes (the type-aware lint is left to CI on this host).cmux-ci compile-check --package CmuxNext. Results in a comment.Observed / Not run
cmux-ci testgoes to the Linux pool, which can't build the AppKit package). No capture.Changelog
Fixed: the open Session Info toggle shows its highlight in every theme, and Esc closes native Session Info after a click inside it.
Agent session: agent session
🤖 Generated with Claude Code
Open in [code]smith · Need help on this PR? Tag
@codesmith-botwith what you need.Summary by cubic
Restores the toggled highlight on the open Session Info toggle in the agent header, and makes Esc close the native Session Info panel after a click inside it.
Header toggle highlight
:not(...).Esc closes native Session Info
Written for commit c831409. Summary will update on new commits.