Repository navigation
cmux NEXT menus: one row grid for every menu, and a lint for menus with their own paddings - #24295
Conversation
…a lint for menus with their own paddings, and the profile menu on it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-98d9-7e82-ac8f-c5e8f40c3cab&host=cosmic-gray
…tors do Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-98d9-7e82-ac8f-c5e8f40c3cab&host=cosmic-gray
… 15, a state column only with a checkmark, 14 pt icons) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-98d9-7e82-ac8f-c5e8f40c3cab&host=cosmic-gray
…; a state column only in a menu with a checkmark Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-98d9-7e82-ac8f-c5e8f40c3cab&host=cosmic-gray
|
Owned by context-menus on cosmic-gray · session |
|
Owned by an agent session · took over from an earlier session · session |
|
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)
Unclear: CI failed on
Failures:
Matched log linesNot re-run automatically: Written by red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 400cb08; does not block Gallery before/after for
States
Pick other states with a |
|
Bead |
|
Found 10 test failures on Blacksmith runners: Failures
|
…grid; the sidebar themes the profile menu (no CmuxNextApp growth); the highlight links the shortcuts docs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-98d9-7e82-ac8f-c5e8f40c3cab&host=cosmic-gray
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. |
…pressions split over lines Codex review of #24295: surface discovery skipped menus named only *Menu (BrowserDownloadsMenu) and the rules read one line at a time. The rules now run over the whole file, and every run first checks them against examples they must fail and pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-98d9-7e82-ac8f-c5e8f40c3cab&host=cosmic-gray
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. |
|
Orphaned: no activity for 14 h, and no lane holds a lease on it. The orphan sweep could not merge |
|
Review (codex gpt-6-astra xhigh, next-review): SHIP at fe42235 No blocking findings. The metrics consistency check and lint self-tests pass. macOS tests and the full-repository lint could not be verified from this partial snapshot. |
|
Review (codex gpt-6-astra high, next-review): SHIP at 9544e64 No blocking findings. |
|
Review (codex-review-box/gpt-6-astra high, lane-place): SHIP at 2a20673 SHIP No blocking findings. Both menu-metrics checks pass. AppKit build and runtime tests could not run in this Linux box. |
… note The commit reached the branch without a Sidebar-Look: trailer; the note's log is how such a commit is reviewed once (prepush-gate sidebar_owner). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-ab1f035a409b977caceb
|
Review (codex gpt-6-astra high, review-router): SHIP at fc2d495 Scope: the follow-up delta 2a20673..fc2d495 (sidebar owner note logs 350b65e); the earlier SHIP covered 2a20673. The log truthfully describes the supplied sidebar diff: Agent session: agent session |
|
Shipped in:
|
|
The "Sidebar look owner sweep" step of the cmux-next checks names this PR's commit on feat-cmux-next. It scans every commit since 342462c, so every PR's checks print this line (job 123695447456 on #27454): The commit has landed, so a trailer is no longer possible. The fix is an entry for 6c1a5ab in |
|
Why your entry is waited for: #27634 makes the "Pushed commits add no violations" step fail when the sidebar sweep finds a commit with no record. Today the step never fails, because its pipe has no pipefail. Without an entry for 6c1a5ab in |
4367c16 (#24073), 6c1a5ab (#24295) and eb8105b (#27561) reached feat-cmux-next as squash merges without a Sidebar-Look trailer; their branch commits are already logged in sidebar-owner.md. Sidebar-Look: no visual change Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445
…for the Sidebar-Look sweep The CI sweep from 342462c names 4367c16, 6c1a5ab and eb8105b: base's squash merges of PRs whose branch commits are already logged. Log them by their squash sha. Sidebar-Look: no visual change Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445
…bar-Look trailer (#28326) 4367c16 (#24073), 6c1a5ab (#24295) and eb8105b (#27561) reached the base branch without a Sidebar-Look: trailer, so the sidebar owner sweep in cmux-next checks fails every PR whose merge includes them. Logging their shas in sidebar-owner.md is the gate's documented path for such a commit (prepush-gate.py sidebar_owner: "reviewed once instead of failing every later sweep"). Agent-Session: https://cmux.com/deeplink/agent?id=aid-159afad10a5ab45ea16c Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…mmits stay errors (#27632) * test(prepush-gate): a pull request's sidebar sweep warns on a base commit and errors on its own Red on the base: prepush-gate.py has no --own-range ('unrecognized arguments'). On 2026-10-29 two feat-cmux-next commits without a Sidebar-Look record (#24073, #24295) put an ##[error] on every pull request's cmux-next checks, and next-autoland read it as the PR's own red (#27454 and four more PRs). * ci(cmux-next): a pull request's sidebar sweep names a base commit as a warning; its own commits stay errors The "Pushed commits add no violations" step sweeps every commit since 342462c for a Sidebar-Look record. On a pull request run it printed ::error for base commits too: 4367c16 (#24073) and 6c1a5ab (#24295) put an error on every feat-cmux-next pull request's checks, and next-autoland read that line as the PR's own red, so #27454 and four more PRs stayed held. prepush-gate.py --own-range BASE..HEAD (the sweep only): a finding on a commit inside the range is an ::error and fails the sweep as before; one on a commit outside it is a ::warning that names the commit and plans/cmux-next/sidebar- owner.md. cmux-next.yml passes --own-range HEAD^1..HEAD on pull request runs only. A push sweep of feat-cmux-next is unchanged: every commit without a record is still an error there, so the base's debt stays visible on the branch. risk_tier.py classify: normal. Test: test_cmux_next_prepush_gate's new case fails on the base and passes; the whole file passes (40 tests). * ci(cmux-next): own-range on pull_request runs only; the warning carries the whole finding (review of #27632) A workflow_dispatch run (feat-cmux-next, next-batch/*, a PR branch) checks out a branch tip, not GitHub's merge commit, so HEAD^1..HEAD there is the tip commit only: the != push test turned the branch's own debt into warnings. Now == pull_request, as the app-FFI pin step tests. The warning text is the whole finding, % and newlines escaped for the workflow command.
* test(sidebar): cover fold accessibility activation Exercise Done and Show more through AXPress, including row reuse and hidden rows. Native execution is pending the fleet route; this lane has no Swift compiler. Agent-Session: https://cmux.com/deeplink/agent?id=aid-75c97562a83401f2d167 * fix(sidebar): let VoiceOver activate Done and Show more Route AXPress through the same fold action as mouse clicks, rebind the callback when rows are reused, and reject hidden or stale fold elements. Native red/green execution is pending the fleet route. Sidebar-Look: no visual change Agent-Session: https://cmux.com/deeplink/agent?id=aid-75c97562a83401f2d167 * test(sidebar): isolate recycled fold view from live registry Sidebar-Look: no visual change Agent-Session: https://cmux.com/deeplink/agent?id=aid-75c97562a83401f2d167 * test: cover keyboard activation of sidebar disclosure rows Agent-Session: https://cmux.com/deeplink/agent?id=aid-c24cb66e0a77ead34e65 * fix: include sidebar disclosure rows in keyboard walk Agent-Session: https://cmux.com/deeplink/agent?id=aid-c24cb66e0a77ead34e65 * test: use key codes for disclosure navigation events Agent-Session: https://cmux.com/deeplink/agent?id=aid-c24cb66e0a77ead34e65 * fix: stabilize keyboard disclosure focus and tests Agent-Session: https://cmux.com/deeplink/agent?id=aid-c24cb66e0a77ead34e65 * test(sidebar): a fold reload or click elsewhere drops the old fold's focus Covers the two Sol findings on #27961: a removed disclosure that comes back must not bring back its ring, and a click on another disclosure must move keyboard focus off the ringed one so Space acts on the clicked row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445 * fix(sidebar): move fold focus to a clicked disclosure A click on Done or Show more left keyboard focus and its ring on the disclosure the keyboard had reached, so the next Space or Return toggled that one. The click now moves focus to the clicked disclosure without a ring (as a click on a group header does), and a fold row draws its ring only when the keyboard moved focus there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445 Sidebar-Look: no visual change * docs(sidebar): log the fold keyboard commits for the Sidebar-Look sweep 89e3362 and cefa3bc reached the branch without a Sidebar-Look trailer; both are behavior changes that draw only the existing keyboard focus ring on a fold row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445 * docs(sidebar): log base's squash commits of #24073, #24295 and #27561 for the Sidebar-Look sweep The CI sweep from 342462c names 4367c16, 6c1a5ab and eb8105b: base's squash merges of PRs whose branch commits are already logged. Log them by their squash sha. Sidebar-Look: no visual change Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445 * test(sidebar): a tab click must take keyboard focus off a disclosure Red test for the review finding: after the keyboard focuses Show more, a click on a tab row leaves focusedFold set, so Return or Space still toggles the old disclosure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445 * fix(sidebar): a click on a tab or any other row takes focus off a disclosure The .tab mouse-down selected the tab but left focusedFold (and a clicked group header's focus) set, so Return or Space toggled the old disclosure and the arrows walked on from it. Every row kind but a group header or a disclosure now clears the keyboard focus on press, as workspace and item clicks already did: tab, section, empty section, empty group, folder, block and status rows. Sidebar-Look: no visual change Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445 * test(sidebar): drop the tab-row fold test; base deleted sidebar tab rows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Leo, 2026-10-21, forwarding two screenshots from Lawrence: "lawrence sent this... idk if we genearlized the left alignment across all stuff yet". Then, on the sidebar's profile menu: "left alignment on the profile settings dropdown/pop i think is similar...".
What the screenshots show (described here; the images stay private):
cmux NEXT had no shared menu grid. A survey found nine menu surfaces using about seven different grids:
Nothing checked them.
This PR, the first of three:
One source:
schemas/menu-metrics/menu-metrics.jsonis the row grid of every menu: highlight inset and radius, separator inset, state, icon and text columns, and the shortcut column.scripts/cmux-next/gen-menu-metrics.pywrites it intoMenuMetrics.generated.swiftand the--cmux-menu-*CSS tokens indesktop.css(the same pattern as the motion and type scales).--checkruns in thecmux-next checksjob.The values are native macOS menu metrics (the same values cmux NEXT menus: right-click menu rows keep native macOS metrics #24036 adopted for themed rows, Leo on the chat menu: "so much ... padding ... all over the place"):
Every themed NSMenu (right-click, ⋮, the pane [+], the toolbar menus, the palette's NSMenus) reads it through
ThemedMenuRowView. Icon-less rows' text sits on the text column whenever any row of the menu has an icon.The name and color header (workspace and group menus) sits on the grid: the field's box on the rows' highlight edge, the first swatch on the icon column.
The profile menu is themed in the sidebar's scope like the other sidebar menus, so the avatar sits on the icon column and every row's text starts at one x.
A lint:
scripts/cmux-next/check-menu-metrics.pyfails any menu surface (a Swift menu, popup or picker row, item, header, strip or style type, or an editor row) that declares its own horizontal metric, draws its highlight at its own inset, or places a row part at its own x. The surfaces not on the grid yet are listed in itsDEBTset, which only shrinks:PopupRowView,WebPopupHost,PopupStyle);The second PR (
cmux/menu-metrics-panels) moves those and empties the list. The third (cmux/menu-metrics-web) moves the webviews' menus (ui/Menu, the agent pane's context and project menus, the composer menus) onto the CSS tokens and adds the CSS half of the lint. The composer's quick model menu (QuickModelMenu.tsx, modelPicker.css) belongs to another lane and is left out.Icon and text x, before and after (pt from the menu's edge)
Measured on the captures below (first ink pixel from the menu's border; glyph side bearing adds about 1-2 pt to the layout x), and on the layout by
MenuGridTests:ui/Menu, agent pane menus (PR 3)The highlight and separators of the themed NSMenus already sat at 5 and 15 pt, so in these captures only the icon and text columns move. The profile menu before is AppKit's own menu, so that pair also differs in glass and row height; after, it is themed like every other sidebar menu. The glass is unchanged.
Capture: fleet builds of the head
fbe2687820a8(job c6cee7ed4d465766e881f5b6) and of the base139966bc8efe(job c1bad6975a96), driven on a capture mini. Light appearance, with the menus' glass as drawn. The sidebar, pane [+] and tab-strip menus arecmux-ci capturewindow snapshots, and the mini's text check found nothing private in them. The profile menu blocks the app's snapshot call while it is open, so its two stills are screen grabs from a capture slot, cropped to the app's window.Sidebar group menu (right-click on the "cmux-next app" header)
Sidebar group menu, highlight on the first row (Down once)
Pane [+] (new tab) menu
Empty tab strip menu (Split Right, Search Tabs)
Sidebar footer profile menu
Leo-ask: ask-8c953bd096
Leo-ask: ask-63bba70b57 (the menu half; the git repo detection half is with agent-message-style)
Changelog
Changed: Menus line up the same way everywhere: icons in one column, names in the next, shortcuts on the right.
Observed / Not run
gen-menu-metrics.py --check,check-menu-metrics.py(passes; fails on a scratch fixture with a menu row's owntitleX,NSRect(x: 3andinsetBy(dx: 5), andprepush-gate.py(clean).139966bc8efeandfbe2687820a8(the head before the lint-only commitfe42235c), measured above.check-menu-metrics.pyself-test (4 must-fail, 4 must-pass examples, including multilineNSRect, constraint andinsetBycases) and the full run: 141 menu surface files on the grid, 7 in DEBT.47fcda49(surface discovery and one-line scanning in the lint), fixed infe42235c.Follow-up at fec559a (review BLOCK at 8591d00)
Right-click menus went native on the base since the captures above (
e01bdd4694c, Lawrence: "make sure our right click stuff context menu is standard macos ... we don't want ANYTHING custom besides the icons"), so cmux no longer draws its own menu rows. This head keeps rows native and puts them on the grid through their icons:NSMenu.themeRows(in:)fits every ordinary row's image into the grid's square icon box (MenuMetrics.iconSize, 14 pt, shape kept, template and VoiceOver description kept, a second theming changes nothing). AppKit's one image column is then the grid's in every menu, and the profile menu's larger avatar no longer pushes the text column right.ThemedMenuRowView; a new test covers the fit.STYLE_CHECKS, so a red lint warns like the other style guards.check-menu-metrics.pyno longer flags the menu bar status icon (MenuBarIcon) or the Mac screen switch's knob inset, both new on the base and not menu rows.No capture: the captures above predate the native-menu switch on the base; at this head the only visible change is that a menu icon larger than 14 pt (the profile avatar) is drawn in the 14 pt box.
Agent session: agent session
🤖 Generated with Claude Code