Skip to content

cmux NEXT menus: no wasted gutter or padding in any menu, field menus as wide as their field, the History menu is glass - #28611

Merged
teamleaderleo merged 7 commits into
feat-cmux-nextfrom
lane/ux-settings-menus-2
Nov 1, 2026
Merged

teamleaderleo merged 7 commits into
feat-cmux-nextfrom
lane/ux-settings-menus-2

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

Leo: "look for wastage" (2026-10-30)

Draft: the first commit measures every menu in a real browser (red first). The fixes, the measured table and the stills follow.

Changelog

none

Agent session: agent session

🤖 Generated with Claude Code


Summary by cubic

Menus now share the AppKit grid, removing excess padding and aligning checks and labels; field menus match their trigger width and can grow for long rows.

  • Select and the saved environment Host menu open at the field’s leading edge; long options stay on one line.
  • The History page menu uses glass, and a new check flags oversized menu checks and row gaps.
  • Browser tests measure covered menus in Chromium and WebKit and report other gallery menus.

Written for commit 9d12d78. Summary will update on new commits.

View guided diff Turn on auto-fix

… for the menus it covers (red first)

Leo: "look for wastage"; "THERE'S SO MUCH BULLSHIT PADDING AND WHATNOT LIKE ALL OVER THE
FUCKIGN PLACE"; "misaligned checkmark :( can we all audit the checkmarks and whatnot".

test/support/menuGeometry.ts measures every open role=menu in a real browser: one text line
per menu at AppKit's x (15, 22, or the icon column + 20), checks centred at 10, one-line rows on
--ds-control-row, a field trigger's menu at its leading edge and at least as wide, and glass
(alpha under 0.9 over a blur). settings-select-menu-browser.test.ts holds the menus this rule
covers to it in Chromium and WebKit (and writes their 2x stills) and reports every other
*Menu*.gallery variant. New gallery states: the IconPicker tone menu, a ContextMenu with
checked, unchecked and plain rows, and the saved environment Host select open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
…ir field; the History menu is glass

Leo: "look for wastage"; "THERE'S SO MUCH BULLSHIT PADDING AND WHATNOT LIKE ALL OVER THE
FUCKIGN PLACE"; "there's so much unnecessary padding that you just duplicate"; "misaligned
checkmark :( can we all audit the checkmarks and whatnot"; "STOP DOING SOLID. WE HAVE GLASS, SO
JUST USE GLASS."

- Every Menu and ContextMenu popup (ui/popupSurface.css, all hosts, the agent pane too): the
  highlight 5 in, rows on the row token with no extra padding, the check on the state column at
  10 in its glyph's box, labels at 15 (22 with a state column, 42 or 35 after an icon), one text
  line per menu. #28530's select-only rules move down to it. The model picker, Claude Code's mode
  menu and the Changes scope lists keep their trailing checks.
- ContextMenu: a toggle row's check is .ui-menu-check (no 16px slot), so checked, unchecked and
  plain rows start their labels on one line; icons lose their inline 16px box.
- MenuPopup matchTrigger and MenuButton fieldTrigger (data-field-trigger): the menu opens at the
  field's leading edge, at least as wide (--anchor-width). Select and the saved environment Host
  field use it.
- The History page menu (PageMenu) is .ui-popup.ui-glass with the menu glass tokens, rows on the
  row token; check-glass-never-opaque requires glass on .page-menu.
- scripts/check-menu-gutters.ts (check:menu-gutters, next to check:design-tokens): a menu check
  wider than 12 or a row gap over 6 fails unless it says menu-gutter-allow: <reason>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
@blacksmith-sh

blacksmith-sh Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Found 4 test failures on Blacksmith runners:

Failures

Test View Logs
test/composer-return-sends.test.tsx/composer-return-sends.test.tsx View Logs
test/composer-return-sends.test.tsx/composer-return-sends.test.tsx View Logs
test/new-tab-composer-layout.test.tsx/new-tab-composer-layout.test.tsx View Logs
test/new-tab-composer-layout.test.tsx/new-tab-composer-layout.test.tsx View Logs

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

@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 9d12d78: 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=pr28611 -f ref=lane/ux-settings-menus-2 -f platform=macos -f backend_mode=local

Gallery before/after for 9d12d78: 16 states rendered, 0 images differ, 2902 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 41352140230 -R manaflow-ai/cmux -n gallery-advisory-28611-9d12d78fe5cc91f79de94b6e116bbcd0ddecacc3 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.access-offer/turn-no-credits Apple System Colors Light unchanged 0% own styles.css
agent-pane.access-offer/turn-no-credits Apple System Colors unchanged 0% own styles.css
agent-pane.access-offer/turn-low-credits Apple System Colors Light unchanged 0% own styles.css
agent-pane.access-offer/turn-low-credits Apple System Colors unchanged 0% own styles.css
agent-pane.access-offer/turn-no-offer Apple System Colors Light unchanged 0% own styles.css
agent-pane.access-offer/turn-no-offer Apple System Colors unchanged 0% own styles.css
agent-pane.add-project-panel/environment Apple System Colors Light unchanged 0% own styles.css
agent-pane.add-project-panel/environment Apple System Colors unchanged 0% own styles.css
agent-pane.add-project-panel/sources Apple System Colors Light unchanged 0% own styles.css
agent-pane.add-project-panel/sources Apple System Colors unchanged 0% own styles.css
agent-pane.add-project-panel/directory Apple System Colors Light unchanged 0% own styles.css
agent-pane.add-project-panel/directory Apple System Colors unchanged 0% own styles.css
agent-pane.add-project-panel/keyboard Apple System Colors Light unchanged 0% own styles.css
agent-pane.add-project-panel/keyboard Apple System Colors unchanged 0% own styles.css
agent-pane.add-project-panel/browse-error Apple System Colors Light unchanged 0% own styles.css
agent-pane.add-project-panel/browse-error Apple System Colors unchanged 0% own styles.css
agent-pane.all-chats-list/page-failed Apple System Colors Light unchanged 0% own styles.css
agent-pane.all-chats-list/page-failed Apple System Colors unchanged 0% own styles.css
agent-pane.all-chats-list/page-recovered Apple System Colors Light unchanged 0% own styles.css
agent-pane.all-chats-list/page-recovered Apple System Colors unchanged 0% own styles.css
agent-pane.all-chats-list/long-values Apple System Colors Light unchanged 0% own styles.css
agent-pane.all-chats-list/long-values Apple System Colors unchanged 0% own styles.css
agent-pane.all-chats-list/page-empty Apple System Colors Light unchanged 0% own styles.css
agent-pane.all-chats-list/page-empty Apple System Colors unchanged 0% own styles.css
agent-pane.all-chats-loading/first-page Apple System Colors Light unchanged 0% own styles.css
agent-pane.all-chats-loading/first-page Apple System Colors unchanged 0% own styles.css
agent-pane.all-chats-loading/indexing Apple System Colors Light unchanged 0% own styles.css
agent-pane.all-chats-loading/indexing Apple System Colors unchanged 0% own styles.css
agent-pane.all-chats-loading/loaded Apple System Colors Light unchanged 0% own styles.css
agent-pane.all-chats-loading/loaded Apple System Colors unchanged 0% own styles.css
agent-pane.all-chats-loading/empty Apple System Colors Light unchanged 0% own styles.css
agent-pane.all-chats-loading/empty Apple System Colors unchanged 0% own styles.css

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

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

CI failed on 9d12d78fe5 (run 41352140447 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 (4) code a web test failed
web / react-apps-check unknown no known signature; failed step: Check webview test shards

Failures:

  • seen on other PRs new-tab-send-button.test.tsx classic: a terminal-only spelling waits for its pending image and sends as a prompt: failed (job)
  • seen on other PRs ? screen: a terminal-only spelling waits for its pending image and sends as a prompt: failed (job)
  • seen on other PRs composer-return-sends.test.tsx a terminal-only spelling waits for its pending image and sends as an attachment prompt: failed (job)
  • seen on other PRs new-tab-composer-layout.test.tsx Codex slash commands are available before the first message and selecting one keeps its arguments: failed (job)
Matched log lines
web / react-apps-base-check (6): (fail) classic: a terminal-only spelling waits for its pending image and sends as a prompt [2301.12ms]
web / react-apps-base-check (4): (fail) a terminal-only spelling waits for its pending image and sends as an attachment prompt [2454.90ms]

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

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

red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: red check: Checks job structure is not red on the base c026ef2; 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 (4); NEW webview test reds: test/new-tab-field-on-art.test.ts > the New Tab field on a wallpaper theme in webkit > a suggestion row is a menu row: the same height, corners and inset; test/new-tab-field-on-art.test.ts > the New Tab field on a wallpaper theme in chromium > a suggestion row is a menu row: the same height, corners and inset; do not merge until green; see lane-rules
red: web / react-apps-base-check (6); NEW webview test reds: test/glass-never-opaque.test.ts > every overlay surface is glass, never opaque; 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

Shipped in:

…s History menu

The menu grid now leaves out only menus whose rows are Claude Code's mode rows
(.acpmux-access-item), so the agent pane's options menu (AgentOptionsMenu, plain radio
rows in .acpmux-access-menu) takes it: its labels were at 18 and 30 with the check at 18.
Group labels sit on the menu's text line. The agent pane still is now that options menu
(the composer's folder menu is a Popover + Combobox listbox, not a menu).

popup-surface.test.ts lists the History page menu with the glass surfaces (its markup is
.page-menu.ui-popup.ui-glass); subtle-elevation.test.ts drops .page-menu's own shadow (it
casts .ui-popup's drop).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
design-surfaces.json: base's session-info surface beside the PR's menus.
package.json: base's check pieces with the PR's check:menu-gutters.
styles.css: base's default cursor on the project browse row, the PR's
menu icon gap. Menu.tsx: base's data-popup-open beside the PR's
data-field-trigger.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639
@teamleaderleo
teamleaderleo marked this pull request as ready for review November 1, 2026 02:06
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): SHIP at 0ed0b27

SHIP at 0ed0b27

Visual verdict: no images; Leo tries the build

  1. [P2] [follow-up] webviews/src/pages/shared/pageBase.css:59: .page-menu loses to .ui-popup.ui-glass in glass.css, so History uses the plain 60% tint and 20px blur instead of the intended 78% tint and 32px blur. Increase selector specificity and verify the computed tokens.
  2. [P2] [follow-up] review/pr.body:1: No after screenshots were supplied. Capture the changed menus for visual review.

Changed TypeScript/CSS syntax checks and gutter-checker assertions passed. Browser tests were unavailable: the box lacks Bun, project dependencies, and browser engines.

Follow-ups:

  • Fix History’s menu-glass selector specificity.
  • Capture and review after screenshots.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

15 issues found across 28 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="webviews/src/pages/shared/pageBase.css">

<violation number="1" location="webviews/src/pages/shared/pageBase.css:66">
P3: This removes the menu's drop shadow, but History does not load `popupSurface.css` to set the popup elevation. Set `--glass-elevation: var(--elevation-2)` on `.page-menu`.</violation>

<violation number="2" location="webviews/src/pages/shared/pageBase.css:76">
P3: This row minimum stays 28px at every interface scale, unlike the shared scaled row token. Multiply `--ds-control-row` by `var(--cmux-interface-scale, 1)`.</violation>
</file>

<file name=".github/design-surfaces.json">

<violation number="1" location=".github/design-surfaces.json:45">
P3: This reformat of the `session-rail` `paths` array is unrelated to the menus change and breaks the file's inline style for single-entry arrays. Restore the original one-line form to keep the diff focused.</violation>
</file>

<file name="webviews/src/ui/Menu.tsx">

<violation number="1" location="webviews/src/ui/Menu.tsx:295">
P3: The doc says a `matchTrigger` menu starts at the trigger's leading edge, but nothing enforces it. With `align="end"` the popup extends before the leading edge. Either pass `"start"` to the Positioner when `matchTrigger` is set, or narrow the doc to say the menu is at least as wide as the trigger.</violation>
</file>

<file name="webviews/src/ui/popupSurface.css">

<violation number="1" location="webviews/src/ui/popupSurface.css:282">
P3: Removing `width: 12px` from the shared `:where(.ui-menu-check)` rule also changes menus this PR excludes from the grid. `.acpmux-scope-list` checks have no width of their own, so their 12px box is gone even though the changes.css comment says that list is unchanged. Restore the base width, or give the scope-list check an explicit width.</violation>

<violation number="2" location="webviews/src/ui/popupSurface.css:371">
P3: The 28px shortcut gap is added after the row's 6px flex gap, leaving at least 34px before shortcut text and needlessly widening menus. Subtract the flex gap here.</violation>
</file>

<file name="webviews/scripts/check-menu-gutters.ts">

<violation number="1" location="webviews/scripts/check-menu-gutters.ts:15">
P2: `CHECK` and `ROW` require a prefix before `-menu-`, so bare `.menu-item` and `.menu-check` are never linted. `styles.css` line 745 sets `gap: 10px` on `.menu-item`, and it passes silently. Match the bare class names too.</violation>

<violation number="2" location="webviews/scripts/check-menu-gutters.ts:33">
P2: `pixels` misses real widths. It reads `calc(8px * 2)` as 8, and it skips `rem` and `em` units entirely, so `width: 1rem` is never flagged. Either convert `rem`/`em` at 16px or document these as known gaps in the allow rule.</violation>

<violation number="3" location="webviews/scripts/check-menu-gutters.ts:35">
P2: `pixels()` does not evaluate `calc()`: `width: calc(8px * 2)` reads as 8px and escapes the 12px check. Evaluate the expression or conservatively flag calculations that can exceed the limit.</violation>

<violation number="4" location="webviews/scripts/check-menu-gutters.ts:60">
P3: This applies the row-gap limit to check-only selectors too, so `.ui-menu-check { gap: 8px; }` fails unnecessarily. Require `isRow` when checking the 6px gap.</violation>
</file>

<file name="webviews/test/settings-select-menu-browser.test.ts">

<violation number="1" location="webviews/test/settings-select-menu-browser.test.ts:1">
P2: The `1200` header is clamped to the 900 s default ceiling by `scripts/ci/run-webviews-tests.sh`, so this file still gets killed at 900 s. The new suite's per-test budgets (480 s + 600 s per engine + 900 s report) cannot fit in one file. Move the `every other menu gallery variant` report test into its own `*.test.ts` file, or otherwise bring the file within 900 s.</violation>

<violation number="2" location="webviews/test/settings-select-menu-browser.test.ts:336">
P2: Dark-scheme findings are computed and printed but never added to `failures`, so the dark pass of the still menus cannot fail the test. The same menus are asserted when FAST_CHECKS_OUT is unset, so the check's strength depends on that env var. Push findings for both schemes, or remove the dark pass if it is only for screenshots.</violation>
</file>

<file name="webviews/test/support/menuGeometry.ts">

<violation number="1" location="webviews/test/support/menuGeometry.ts:62">
P2: `trigger` is chosen page-wide with `.at(-1)`, so an open submenu opener later in the DOM replaces the field trigger. The field-width and field-edge checks then silently skip the field menu. Select the field trigger specifically, or tie the trigger to each popup via `aria-controls`.</violation>

<violation number="2" location="webviews/test/support/menuGeometry.ts:77">
P2: The label lookup checks `closest(NOT_TEXT)` on ancestors outside the row. If the popup sits under an `aria-hidden` or `-tag`/`-meta`-classed wrapper, every label is skipped and `menuFindings` passes the menu with no checks. Scope the match to the row.</violation>
</file>

<file name="webviews/package.json">

<violation number="1" location="webviews/package.json:11">
P2: This adds `check:menu-gutters` to the CI-run `check:pieces` chain, despite the repository's explicit no-new-CI-gates rule. Keep it out of this chain or obtain an exception.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic


/** The largest px length in a value (`16px`, `calc(8px * 2)` reads 8); null without one. */
function pixels(value: string): number | null {
const all = [...value.matchAll(/(-?[\d.]+)px/g)].map((match) => Number(match[1]));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: pixels misses real widths. It reads calc(8px * 2) as 8, and it skips rem and em units entirely, so width: 1rem is never flagged. Either convert rem/em at 16px or document these as known gaps in the allow rule.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/scripts/check-menu-gutters.ts, line 33:

<comment>`pixels` misses real widths. It reads `calc(8px * 2)` as 8, and it skips `rem` and `em` units entirely, so `width: 1rem` is never flagged. Either convert `rem`/`em` at 16px or document these as known gaps in the allow rule.</comment>

<file context>
@@ -0,0 +1,84 @@
+
+/** The largest px length in a value (`16px`, `calc(8px * 2)` reads 8); null without one. */
+function pixels(value: string): number | null {
+  const all = [...value.matchAll(/(-?[\d.]+)px/g)].map((match) => Number(match[1]));
+  if (all.length === 0) return /^0$/.test(value.trim()) ? 0 : null;
+  return Math.max(...all);
</file context>

Comment on lines +15 to +16
const CHECK = /\.(?:ui-menu-check|[\w-]*-menu-check)(?![\w-])/;
const ROW = /\.[\w-]*-menu-item(?![\w-])/;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: CHECK and ROW require a prefix before -menu-, so bare .menu-item and .menu-check are never linted. styles.css line 745 sets gap: 10px on .menu-item, and it passes silently. Match the bare class names too.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/scripts/check-menu-gutters.ts, line 15:

<comment>`CHECK` and `ROW` require a prefix before `-menu-`, so bare `.menu-item` and `.menu-check` are never linted. `styles.css` line 745 sets `gap: 10px` on `.menu-item`, and it passes silently. Match the bare class names too.</comment>

<file context>
@@ -0,0 +1,84 @@
+
+const SRC = join(dirname(fileURLToPath(import.meta.url)), "../src");
+const ALLOW = /menu-gutter-allow:\s*\S/;
+const CHECK = /\.(?:ui-menu-check|[\w-]*-menu-check)(?![\w-])/;
+const ROW = /\.[\w-]*-menu-item(?![\w-])/;
+const WIDTH = /^(?:width|min-width|flex-basis|inline-size|min-inline-size)$/;
</file context>
Suggested change
const CHECK = /\.(?:ui-menu-check|[\w-]*-menu-check)(?![\w-])/;
const ROW = /\.[\w-]*-menu-item(?![\w-])/;
const CHECK = /\.(?:[\w-]*-)?menu-check(?![\w-])/;
const ROW = /\.(?:[\w-]*-)?menu-item(?![\w-])/;

: "") +
(findings.length ? ` FINDINGS: ${findings.join("; ")}` : ""),
);
if (colorScheme !== "dark")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Dark-scheme findings are computed and printed but never added to failures, so the dark pass of the still menus cannot fail the test. The same menus are asserted when FAST_CHECKS_OUT is unset, so the check's strength depends on that env var. Push findings for both schemes, or remove the dark pass if it is only for screenshots.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/test/settings-select-menu-browser.test.ts, line 336:

<comment>Dark-scheme findings are computed and printed but never added to `failures`, so the dark pass of the still menus cannot fail the test. The same menus are asserted when FAST_CHECKS_OUT is unset, so the check's strength depends on that env var. Push findings for both schemes, or remove the dark pass if it is only for screenshots.</comment>

<file context>
@@ -261,4 +263,113 @@ await requireBrowserLane("settings-select-menu-browser.test.ts", async () => {
+                    : "") +
+                  (findings.length ? ` FINDINGS: ${findings.join("; ")}` : ""),
+              );
+              if (colorScheme !== "dark")
+                failures.push(...findings.map((f) => `${entry}/${variant} ${menu.name}: ${f}`));
+            }
</file context>

@@ -1,4 +1,4 @@
// cmux-web-test-timeout: 600
// cmux-web-test-timeout: 1200

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The 1200 header is clamped to the 900 s default ceiling by scripts/ci/run-webviews-tests.sh, so this file still gets killed at 900 s. The new suite's per-test budgets (480 s + 600 s per engine + 900 s report) cannot fit in one file. Move the every other menu gallery variant report test into its own *.test.ts file, or otherwise bring the file within 900 s.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/test/settings-select-menu-browser.test.ts, line 1:

<comment>The `1200` header is clamped to the 900 s default ceiling by `scripts/ci/run-webviews-tests.sh`, so this file still gets killed at 900 s. The new suite's per-test budgets (480 s + 600 s per engine + 900 s report) cannot fit in one file. Move the `every other menu gallery variant` report test into its own `*.test.ts` file, or otherwise bring the file within 900 s.</comment>

<file context>
@@ -1,4 +1,4 @@
-// cmux-web-test-timeout: 600
+// cmux-web-test-timeout: 1200
 // l10n-allow-file: browser test diagnostics, not shipped UI.
 // Leo 2026-10-30, on Settings > Updates with the Update Channel menu open: "look for wastage".
</file context>

Comment thread webviews/src/pages/shared/pageBase.css Resolved
:where(.ui-menu-check) {
display: inline-flex;
align-items: center;
width: 12px;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Removing width: 12px from the shared :where(.ui-menu-check) rule also changes menus this PR excludes from the grid. .acpmux-scope-list checks have no width of their own, so their 12px box is gone even though the changes.css comment says that list is unchanged. Restore the base width, or give the scope-list check an explicit width.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/ui/popupSurface.css, line 282:

<comment>Removing `width: 12px` from the shared `:where(.ui-menu-check)` rule also changes menus this PR excludes from the grid. `.acpmux-scope-list` checks have no width of their own, so their 12px box is gone even though the changes.css comment says that list is unchanged. Restore the base width, or give the scope-list check an explicit width.</comment>

<file context>
@@ -279,7 +279,6 @@
   display: inline-flex;
   align-items: center;
-  width: 12px;
   justify-content: center;
   line-height: 1;
 }
</file context>

const px = pixels(value);
if (px === null) continue;
const tooWide = isCheck && WIDTH.test(prop) && px > 12;
const tooFar = GAP.test(prop) && px > 6;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: This applies the row-gap limit to check-only selectors too, so .ui-menu-check { gap: 8px; } fails unnecessarily. Require isRow when checking the 6px gap.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/scripts/check-menu-gutters.ts, line 60:

<comment>This applies the row-gap limit to check-only selectors too, so `.ui-menu-check { gap: 8px; }` fails unnecessarily. Require `isRow` when checking the 6px gap.</comment>

<file context>
@@ -0,0 +1,84 @@
+      const px = pixels(value);
+      if (px === null) continue;
+      const tooWide = isCheck && WIDTH.test(prop) && px > 12;
+      const tooFar = GAP.test(prop) && px > 6;
+      if (!tooWide && !tooFar) continue;
+      const line = lineOf(bodyStart + d.index);
</file context>

calc(var(--cmux-menu-trailing) - var(--cmux-menu-highlight-inset));
}
.ui-popup:is(.ui-menu, .ui-context-menu):not(.acpmux-quick-menu, .acpmux-scope-list, :has(.acpmux-access-item)) .ui-menu-shortcut {
padding-inline-start: var(--cmux-menu-shortcut-gap);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: The 28px shortcut gap is added after the row's 6px flex gap, leaving at least 34px before shortcut text and needlessly widening menus. Subtract the flex gap here.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/ui/popupSurface.css, line 371:

<comment>The 28px shortcut gap is added after the row's 6px flex gap, leaving at least 34px before shortcut text and needlessly widening menus. Subtract the flex gap here.</comment>

<file context>
@@ -296,6 +295,97 @@
+    calc(var(--cmux-menu-trailing) - var(--cmux-menu-highlight-inset));
+}
+.ui-popup:is(.ui-menu, .ui-context-menu):not(.acpmux-quick-menu, .acpmux-scope-list, :has(.acpmux-access-item)) .ui-menu-shortcut {
+  padding-inline-start: var(--cmux-menu-shortcut-gap);
+}
+.ui-popup:is(.ui-menu, .ui-context-menu):not(.acpmux-quick-menu, .acpmux-scope-list, :has(.acpmux-access-item)) .ui-separator {
</file context>
Suggested change
padding-inline-start: var(--cmux-menu-shortcut-gap);
padding-inline-start: calc(var(--cmux-menu-shortcut-gap) - var(--cmux-menu-icon-gap));

align-items: center;
box-sizing: border-box;
width: 100%;
min-height: var(--ds-control-row);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: This row minimum stays 28px at every interface scale, unlike the shared scaled row token. Multiply --ds-control-row by var(--cmux-interface-scale, 1).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/pages/shared/pageBase.css, line 76:

<comment>This row minimum stays 28px at every interface scale, unlike the shared scaled row token. Multiply `--ds-control-row` by `var(--cmux-interface-scale, 1)`.</comment>

<file context>
@@ -50,25 +50,36 @@ input {
+  align-items: center;
+  box-sizing: border-box;
   width: 100%;
+  min-height: var(--ds-control-row);
   text-align: left;
   border: 0;
</file context>
Suggested change
min-height: var(--ds-control-row);
min-height: calc(var(--ds-control-row) * var(--cmux-interface-scale, 1));

border: 1px solid var(--page-separator);
box-shadow: var(--elevation-2);
padding: var(--cmux-menu-highlight-inset);
border: 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: This removes the menu's drop shadow, but History does not load popupSurface.css to set the popup elevation. Set --glass-elevation: var(--elevation-2) on .page-menu.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/pages/shared/pageBase.css, line 66:

<comment>This removes the menu's drop shadow, but History does not load `popupSurface.css` to set the popup elevation. Set `--glass-elevation: var(--elevation-2)` on `.page-menu`.</comment>

<file context>
@@ -50,25 +50,36 @@ input {
-  border: 1px solid var(--page-separator);
-  box-shadow: var(--elevation-2);
+  padding: var(--cmux-menu-highlight-inset);
+  border: 0;
+  border-radius: var(--ui-popup-radius, 8px);
   outline: none;
</file context>

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Orphaned: no activity for 13 h, and no lane holds a lease on it. The orphan sweep could not merge feat-cmux-next in: conflicts in .github/design-surfaces.json, webviews/package.json, webviews/src/agent-session/acpmux/styles.css. Listed for a lane to resolve.

# Conflicts:
#	.github/design-surfaces.json
#	webviews/package.json
#	webviews/src/agent-session/acpmux/styles.css
… wrapping them (painting titles)

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

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

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5): SHIP at 9d12d78

Delta review of the feat-cmux-next merge (design-surfaces.json, package.json check:pieces, acpmux styles.css: both sides kept) and 9d12d78 (field-menu max-width no longer capped at 420px, so Appearance painting titles stay one row; fixes settings-select-menu-browser after the merge).

Follow-ups:

  • [follow-up] SavedEnvironmentPanel host menu (matchTrigger) can now widen to the window for a very long host name instead of ellipsizing; cap .acpmux-env-host-menu if it matters.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (independent Codex gpt-6.1-sol, high, via the review router; full diff from merge base c026ef2 to this head): BLOCK at 9d12d78.

[P2] [blocking] webviews/src/ui/ContextMenu.tsx:325 - Removing the inline MENU_ICON sizing leaves the agent-pane fallback context menu’s .ui-menu-check and .ui-menu-icon without fixed state/icon columns; the pane explicitly does not load ui.css, and its local stylesheet has no equivalent icon sizing, so checked and unchecked labels shift and icons use intrinsic widths. Restore the inline sizing or add the shared menu geometry rules to the pane stylesheet.

@teamleaderleo
teamleaderleo merged commit a8a7992 into feat-cmux-next Nov 1, 2026
187 of 194 checks passed
@teamleaderleo
teamleaderleo deleted the lane/ux-settings-menus-2 branch November 1, 2026 22:01
teamleaderleo added a commit that referenced this pull request Nov 1, 2026
… base replay's (#31382)

react-apps-base-check replays the head's red files on the base, then prints
guards_new_reds.py's verdict. The bun (fail) lines in its log are the base
replay's: tests that fail on the base too, which the verdict excuses as
warnings. classify_failures read those as the job's failures, so #28611's
report listed the two composer tests the base also failed (getClientRects)
and named neither test that was its own (new-tab-field-on-art in chromium
and webkit, glass-never-opaque).

A base-check job's failures are now the verdict's ##[error] file > test
lines, with the webviews/ root so a red in a file the PR changes is
yours; with none, no base-replay test is listed.


Agent-Session: https://cmux.com/deeplink/agent?id=aid-2f629b93d5a20c58e6f8

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Nov 2, 2026
…ng checks

#28611 (now on base) excludes .acpmux-scope-list from the shared menu grid; this
PR's rules matched it and moved ScopeMenu's and ChatFilterMenu's checks to the
leading state column. Exclude it here too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-90f18511b4bf53b41d20
teamleaderleo added a commit that referenced this pull request Nov 2, 2026
…ory menu is glass) (#31482)

new-tab-field-on-art held New Tab and omnibox suggestion rows to a context menu item's corners
and inset. Since #28611 menus keep AppKit's 5 inset and radius 5 (design/grid.md 5.3) while
popups with rows on the 4 grid keep --ui-row-radius (4) and the 4 popup padding, so the test now
reads those tokens. glass-never-opaque: .page-menu is glass since #28611, so its OVERLAY_PENDING
entry is stale and goes.


Agent-Session: https://cmux.com/deeplink/agent?id=aid-2f629b93d5a20c58e6f8

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@lawrencecchen

Copy link
Copy Markdown
Contributor

Leo (teamleaderleo): this PR added check:menu-gutters to webviews check:pieces, but not to the feat-cmux-next warn branch of ci-web's Check webviews step. Thus the check did not run on feat, and "Checks job structure" (tests/test_cmux_next_checks_workflow.py) in cmux-next checks is red at the tip. The fix is in #31628 (warn-only, as the other style checks).

lawrencecchen added a commit that referenced this pull request Nov 2, 2026
…#28611) (#31628)

#28611 (a8a7992) added check:menu-gutters to webviews/package.json's
check:pieces but not to the warn branch of ci-web's "Check webviews" step,
so on feat-cmux-next (CMUX_NEXT_STYLE_GUARDS=warn) the check never ran.
tests/test_cmux_next_checks_workflow.py (the "Checks job structure" step of
cmux-next checks) refuses that, and is red at the tip. The warn loop now runs
it in package.json's order, warn-only like the other style checks; no new
gate.

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 9d12d78f Deployed Nov 1, 2026 by teamleaderleo via cmux-tui tree preflight #97571
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants