cmux NEXT webviews: fail hand-set popup roles and raw design values in new code outside ui/
Part of the cmux NEXT design-system pass (Leo: "there's just tons of design systems related stuff for spacing gutters icons etc whatever like we don't yet feel "designed" yet"). This is the lint piece: new code outside webviews/src/ui/ can no longer hand-roll a popup widget or write a raw design value, while today's tree passes on a shrinking allowlist.
What changes
1. hand-set-role in scripts/check-ui-review.ts (fails)
- Flags
role="menu" | "menuitem" | "menuitemradio" | "menuitemcheckbox" | "listbox" | "option" | "dialog" | "tablist" | "tab"written in TSX outsidesrc/ui/: a JSX attribute (including a conditional such asrole={x ? "option" : undefined}) or arole: "option"property in a props object.querySelector('[role="menu"]')strings, other roles (group,alert,status),src/ui/, tests and gallery files are not flagged. - Fingerprint
<role>|<tag or props>|<enclosing component>, so moving lines does not churn the allowlist. - Today's 55 occurrences (DiffToolbar, BranchBasePicker, the slash/palette/file-search listboxes, New Tab, History, Apps, the inspector tabs, and others) are in
ui-review-allowlist.jsonl. The checker's own scan generated them. hand-set-roleis the one rule inFAILING_RULES. A new occurrence fails, and so does a stale entry (the code is fixed but the entry is still listed), so the list only shrinks. The copy and row rules still only warn, as before.check:ui-reviewis already incheck:pieces, so this adds no CI job or step.
2. Token literals in scripts/check-design-tokens.ts (fails, same ratchet)
The existing per-file baseline ratchet now also counts, in CSS and in TSX inline style={{}} objects:
| kind | flagged | allowed |
|---|---|---|
| color | raw #hex, rgb/rgba/hsl/hsla/hwb/lab/lch/oklab/oklch/color() | var() and its fallback, a colour function or color-mix that takes a token, masks, --x: token definitions |
| spacing | margin*, inset*, top/right/bottom/left (padding/gap as before) | 0/4/8/12/16/24/32 + 40/48/56 layout gaps (abs value, so -4px is fine) |
| radius | border-radius* | 0/4/6/8/12/16, >= 999px capsules, tokens (menu 5 comes from --cmux-menu-*) |
| font-weight | anything else, bold, and 700 | 400, 600, normal, var(); 700 for monograms lives in the baseline |
| duration | a literal transition/animation duration other than 0 | var(--cmux-motion-*) |
| easing | cubic-bezier(), ease, ease-in, ease-out, ease-in-out | var(--cmux-ease-out), linear |
- The token file
pages/shared/desktop.cssand generated CSS are not scanned for the new kinds. Font sizes stay with the existing type-scale ratchet (scripts/cmux-next/check-type-scale.py), which already counts every literal font size; this PR does not duplicate it. - Baseline: the 1,463 existing rows are byte-for-byte unchanged; 1,107 new rows record today's counts (spacing 2,220 occurrences incl. padding/gap, radius 415, font-weight 186, color 57, duration 40, easing 34). These match the static audit's totals (radius 403, font-weight 185, raw colour 87 including about 30 mask stops that are not colours).
How a migration PR shrinks the lists
After moving a surface onto ui/ and tokens, run from webviews/:
bun scripts/check-ui-review.ts --shrink-allowlist && bun scripts/check-design-tokens.ts --update-baseline
--shrink-allowlist drops only stale entries and never adds one; --update-baseline refuses to grow any count. Both checks fail until the fixed entries are removed, so no list ever grows back.
Overlap
- #33595 (icon-scale check) also edits
check-design-tokens.ts(howheightis judged for icon boxes) and the baseline. The two changes are in separate functions; whichever lands second rebases and re-runs--update-baseline. - The parallel grid migration PRs will remove rows; each one runs the command above.
Tests
test/check-ui-review.test.ts: positive (JSX, conditional, props object, every role), negative (other roles, selector strings, ui/, gallery, tests, .ts), allowlisted passes, new fails, stale entry fails until --shrink-allowlist, shrinking never adds, today's tree passes. test/design-tokens.test.ts: each kind positive and negative, var/fallback/token-composing colour, TSX inline styles, ratchet new/allowlisted/shrink.
Observed / Not run
- Ran on the fleet (
cmux-ci test): both test files,bun scripts/check-ui-review.ts,bun scripts/check-design-tokens.ts,vp check --no-fmt --no-lint. 64 tests pass, both checkers pass on today's tree, no type errors. vp fmt --checkclean. No runtime or rendering code changes, so no Performance table and no captures; no new loops, timers or observers.
Changelog
none
Agent session: agent session
🤖 Generated with Claude Code
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Adds two failing design-system lint rules so new code outside webviews/src/ui/ can't hand-roll a popup widget or write a raw design value.
hand-set-role in check-ui-review.ts
- Flags
menu,menuitem*,listbox,option,dialog,tablist, andtabroles set in TSX outsidesrc/ui/(tests, gallery, andui/files exempt). - Today's 55 occurrences are allowlisted by file + fingerprint; a new finding or a stale entry fails the check, while the copy and row rules still warn.
bun scripts/check-ui-review.ts --shrink-allowlistdrops stale entries and never adds.
Token literals in check-design-tokens.ts
- Flags raw color literals, off-scale spacing/radius/font-weight, and non-token durations/easings in CSS and TSX inline
style={{}}objects. - The baseline was re-recorded against the current base, so it includes rows from surfaces that landed since (the next-step card, conversation margins, settings radii).
bun scripts/check-design-tokens.ts --update-baselinere-records counts and refuses to grow any, so a count can only shrink.