Skip to content

cmux NEXT composer: no pill at rest, hover pills one button, press shrinks a hair - #22107

Merged
teamleaderleo merged 7 commits into
feat-cmux-nextfrom
leo/composer-chip-hover-pill
Oct 19, 2026
Merged

teamleaderleo merged 7 commits into
feat-cmux-nextfrom
leo/composer-chip-hover-pill

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

The composer's buttons now behave like the Claude app's dropdown chips (the "Bypass permissions" chip is the reference):

  • At rest: model, effort, mode, +, the mic, Plan, Steer and the fast toggle show their icon or label with no pill. The model, effort and mode pills used to draw a 6% fill at rest. That fill came from polish(cmux-next): round composer pills and highlights #21391 (04d7f6a, "round composer pills and highlights"). Plan, when on, is accent text with no fill or ring.
  • Hover: a soft pill on the one button under the pointer (fine pointers only). The same pill shows while that button's menu is open and on keyboard focus (with the focus outline), for every button, + and the fast toggle included. + and the other menu buttons used to draw a brighter 16% fill and a ring when open.
  • Press: the button keeps its hover pill. The brighter, tinted press tones are gone: --acpmux-composer-press / --acpmux-row-press (from the cg-composer click polish), the mic's deeper red, Plan's deeper accent and the fast toggle's press. Instead the chip draws at 0.975 scale with a 4% opacity dip the moment it goes down. It holds while the button is down, including on chips that open their menu on press, and springs back over 140 ms with a slight overshoot on release, the fast toggle too. Nothing lingers. With Reduce Motion there is no shrink.
  • The composer box still never highlights on hover, and fix(agent pane): a composer picker keeps its pressed tone on the first frame of a click #21976's first-frame tone for an opening picker is kept.

The press is a transform, so it moves no layout. composer-chip-press.test.ts now measures the layout box (the drawn centre plus the offset size), and counts a move only at a whole pixel. This PR also folds in #21986's stricter no-move check, which now runs for every press, and its EffortPicker comment fix.

Testing

All runs on Huge Blue (Chromium and WebKit), CMUX_BROWSER_TESTS=1 bun test <file> in webviews/ after node scripts/pages/gen-strings.mjs.

  • test/composer-quiet-chips.test.ts test/no-system-blue.test.ts at the failing-test commit 6d7c554 (the new tests over f01d4f8's CSS): 30 pass, 10 fail. The open + chip drew a 24% ring. Plan on drew a pill at rest. The fast toggle got no pill on keyboard focus, and its transition dropped transform and opacity. A separate -t "a press" run showed the model chip losing its shrink while held in Chromium (scale back to 1 after 300 ms).
  • At the fix head dd28946: composer-quiet-chips 34 pass, composer-chip-press 52 pass, newtab-quiet-focus 22 pass, no-system-blue 6 pass, composer-row-layout 27 pass, composer-row-rhythm and quiet-access-chip pass.
  • composer-footer-plain fails 12 of 18, the same 12 at f01d4f8. It expects the plain footer off by default, but cmux-next composer: no pill at rest; the hover wash only (plain footer is the default) #22050 turned it on (base finding).

Observed / Not run

  • Observed: the red and green runs above.
  • Not run: captures. The gallery CI job screenshots the composer entries, including the new agent-pane.composer quiet-chips variant.

Changelog

Changed: Composer buttons show no pill at rest; hovering, focusing or opening one gives it a soft pill, and a press shrinks it slightly and springs back, with no flash

🤖 Generated with Claude Code


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


Summary by cubic

Makes the composer's buttons match the Claude app's dropdown chips: no pill at rest, a soft pill on the one button under a fine pointer, and a press that draws the chip at 0.975 with a 4% opacity dip before springing back over 140 ms.

  • Removes the 6% resting fill the model, effort, and mode pills drew, plus the brighter, tinted press tones for the mic, Plan, Steer, and the fast toggle, so a press no longer flashes.
  • The press is a transform, so it moves no layout; the stricter no-move check from test(composer chips): the no-move check runs for every press #21986 now runs for every press and measures the layout box.
  • Folds in the EffortPicker comment fix.
  • Updates composer-quiet-chips, composer-footer-plain, and composer-chip-press tests to assert the new rest, hover, and press states.

Written for commit f01d4f8. Summary will update on new commits.

View guided diff Turn on auto-fix

teamleaderleo and others added 3 commits October 19, 2026 12:38
…shrinks a hair (failing)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ks a hair and springs back

The Claude app's dropdown chips: at rest each control shows its icon or
label with no pill; the pointer gives the one button under it a soft
pill; a press keeps that pill (no brighter or tinted press tone) and
draws the chip at 0.975 with a 4% dip, springing back over 140 ms.
The composer box still never highlights. The resting fill came from
#21391 (04d7f6a); the tinted press tones from the cg-composer
click polish (composerStates.css, row-press).

Folds in #21986's stricter no-move check, measured on the layout box
now that the press is a transform.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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

@blacksmith-sh

blacksmith-sh Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
NEXT post-publication dependency contract/NEXT post-publication dependency contract View Logs

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

@greptile-apps

greptile-apps Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Low impact] No new blocking issue was found; the remaining animation-setting issue is non-blocking.

Findings

  1. P2 Chips ignore animations off ▶

Summary

Composer buttons lose their resting pills and use a soft hover fill with a small press shrink.

  • Composer buttons stay plain until someone hovers, focuses, opens, or presses them.
  • The EffortPicker note now puts the check mark after each option.

Reviews (4) · Last reviewed commit: "fix(next): every composer chip holds its..." · Reviewed by Greptile

Comment on lines 172 to +178
.acpmux-mic,
.acpmux-fast {
transition:
background-color var(--agent-motion-hover) var(--agent-ease-out),
color var(--agent-motion-hover) var(--agent-ease-out),
transform var(--acpmux-press-release) var(--acpmux-press-spring),
opacity var(--acpmux-press-release) var(--agent-ease-out);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Fast toggle snaps back

The production bundle loads composerLocation.css after composerStates.css. Its later .acpmux-fast rule replaces this new transition with one that only covers colors. The button still shrinks, but it jumps straight back on release instead of springing back. Remove the duplicate rule or add transform and opacity there too.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines 165 to 168
:is(.acpmux-picker-button, .acpmux-plan, .acpmux-steer, .acpmux-mic, .acpmux-fast):active {
transform: scale(0.975);
opacity: 0.96;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Model press ends early

In Chromium, opening the model picker focuses its search field and clears :active. This new rule then drops the shrink while the mouse is still held. The existing [data-press-active] marker preserves the held press, but the shrink ignores it. Apply the shrink and immediate press timing to that marker too, so opening the menu does not end the feedback early.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

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

Review dd28946: 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=pr22107 -f ref=leo/composer-chip-hover-pill -f platform=macos -f backend_mode=local

Unclear: web / react-apps-check (1) failed: no known signature; failed step: Check webviews (Oxlint, Oxfmt, type check).

CI failed on dd28946e3e (run 39337318842 attempt 1): 3 unknown.

Job Verdict Why
web / react-apps-check (1) unknown no known signature; failed step: Check webviews (Oxlint, Oxfmt, type check)
web / react-apps-check (2) unknown no known signature; failed step: Check webviews (Oxlint, Oxfmt, type check)
web / react-apps-check unknown no known signature; failed step: Check webview test shards

Not re-run automatically: web / react-apps-check (1), web / react-apps-check (2), 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: web / Web status; do not merge until green; see lane-rules
red: web / react-apps-check; do not merge until green; see lane-rules
red: web / react-apps-check (1); do not merge until green; see lane-rules
red: web / react-apps-check (2); do not merge until green; see lane-rules

CI fast guards failed on dd28946e3e (https://github.com/manaflow-ai/cmux/actions/runs/39337318842). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally.

- vp fmt webviews/test/composer-chip-press.test.ts
- vp fmt webviews/test/composer-quiet-chips.test.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39314002474
/* Core Animation's easeOut, which the native fades use. */
--agent-ease-out: cubic-bezier(0, 0, 0.58, 1);
/* A pressed chip's spring back to full size: quick, with a slight overshoot. */
--acpmux-press-release: 140ms;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Chips ignore animations off

The new release spring ignores ui.animationSpeed. When a user turns animations off, the host sends zero motion durations, but --acpmux-press-release stays at 140ms. Chips still spring back after each press. Derive this duration from the host’s motion settings so turning animations off stops the spring too.

teamleaderleo and others added 2 commits October 19, 2026 14:58
…s looks

composer-quiet-chips now covers +, the mode chip, the fast bolt and Plan on
(the picker rail's plan stage), keyboard focus on each bar button, and a press
held past the release spring on every chip, plus that the release eases the
shrink back. no-system-blue expects Plan on to draw no pill. A new
agent-pane.composer quiet-chips gallery variant shows the bolt on at rest.

Red at f01d4f8 on Huge Blue (Chromium + WebKit): the open + chip draws a
24% ring, Plan on and the gallery's Plan stage draw a pill at rest, the bolt
gets no pill on keyboard focus and its transition drops transform/opacity, and
the model chip (opens on pointerdown) loses its press while held in Chromium.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l open or focused

- The press shrink keys on [data-press-active] as well as :active, with the
  same 0s press duration: a chip that opens its menu on pointerdown (the model
  picker) lost :active in Chromium and sprang back while still held.
- The fast bolt's own reduced-motion transition (background and color only)
  loaded after composerStates.css and dropped the press's transform/opacity
  spring; it is gone, so the bolt eases like the other chips.
- + and the combobox pickers, open or pressed, take the hover's pill with no
  edge instead of the 16% open fill and 24% ring, as model, effort and mode do.
- Keyboard focus gives every bar button (+, model, effort, mode, mic, Plan,
  Steer, the bolt) the hover pill beside its focus outline; the bolt now gets
  the bar's focus outline too.
- Plan on is accent ink with no pill at rest; hovered or focused it takes the
  soft pill and keeps its accent ink.

composer-chip-press measures a move as a whole pixel (the held shrink's drawn
centre can round a subpixel off) and its picker-rail test now expects no fill
at rest; newtab-quiet-focus expects the hover wash on keyboard focus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo merged commit b966806 into feat-cmux-next Oct 19, 2026
@teamleaderleo
teamleaderleo deleted the leo/composer-chip-hover-pill branch October 19, 2026 23:14
teamleaderleo added a commit that referenced this pull request Oct 19, 2026
…landed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Oct 19, 2026
)

* test(cmux-next): compact model menu with Effort and Account rows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(cmux-next): Claude Code style model menu with an Account switcher

The model chip opens a short rounded menu headed "Model · this session":
the harness's top models with number keys 1-9, the check at the trailing
edge, Effort and Account submenus, and More models for the full picker
(typing a letter opens it searching). The chip is a quiet "Opus 5.5 Medium"
label and the separate effort chip goes away.

Account lists the acpmux routes that serve the chat (_acpmux/route/list)
and switches the chat's route (_acpmux/chat/route.set, after-turn), which
restarts the harness and resumes the same session.

Debug Settings choice agent.modelMenu: compact (default) or full.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cmux-next): compact model menu review fixes

- Cmd-Ctrl-M and automation over the open compact menu open the full picker
  in its place instead of closing it again.
- Effort carries fast mode / service tier, which the bolt drops in a narrow row.
- The chip names a held effort pick, and shortens the effort to "Med" in a
  narrow row instead of dropping it.
- A switch acpmux refuses is named on the Account row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(next): PR autofix at 24433c4

- regenerated schemas/settings-export/settings-schema.sources.sha256

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39184653174

* Model menu: a gallery entry, the ui-allow for its number keys, no English error

QuickModelMenu gets a quick-menu variant in the model picker's gallery
entry (gallery coverage), its 1-9 and letter keys a ui-allow reason as
the access menu's, and the Account list's not-connected error a code
instead of English (pane-english).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(model menu): a harness rail, More models as a submenu, type to filter

Leo 2026-10-18: the model menu keeps a rail of harnesses (Starred,
Claude, Codex, others) beside Claude Code's list: numbered models,
Effort, More models (a submenu ending in Add harness…), then Account.
Typing filters the list in place, with no search field. Red until the
menu changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Model menu: a harness rail beside Claude Code's list, More models as a submenu, type to filter

Leo 2026-10-18: the compact model menu keeps a rail of harnesses on its
left (Starred when any model is starred, then Claude, Codex and the
others); a tab shows that harness's top models in place, numbered 1-9
with the check on the running one. Below them, in Claude Code's order:
Effort, More models (a submenu of the harness's other models, ending in
Add harness…), then Account. Effort and Account belong to the chat's
harness, so another harness's tab shows neither. Typing filters every
harness's models in place, with no search field; Backspace takes a
letter back. No effort warning or usage badge. A pick in another
harness starts a chat there, as the full picker's does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Model menu review: the rail and filter survive re-renders; keys stay in the menu

Review of #22005:
- The tab and the typed filter reset only as the menu opens (in render),
  not on every composer render: a streaming chat threw them away.
- Typing moves keyboard focus to the first row left, so a row the filter
  unmounts (Effort, Account, a model) does not drop the next key.
- The rail's tabs are buttons beside the list, not rows of it: Up and
  Down stay in the list, Left and Right move along the rail.
- While filtering, a digit is part of the query ("gpt 5"); Enter picks
  the highlighted match. 1-9 still pick when nothing is typed.
- A signed-out harness's tab offers Log In, as the full picker does.
The re-render, digit and rail tests fail on the previous commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Model menu: the rail is a fieldset (jsx-a11y prefer-tag-over-role)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(next): PR autofix at 1df95bf

- regenerated Packages/macOS/CmuxNext/ci-target-graph.json
- vp fmt webviews/src/agent-session/acpmux/replyHref.ts
- vp fmt webviews/src/pages/markdown/README.md
- vp fmt webviews/src/pages/markdown/links.ts
- vp fmt webviews/test/markdown-cmux-app-links.test.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39212058491

* chore(ci): regenerate the CmuxNext target graph after the base merge

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(next): PR autofix at 10cad23

- regenerated Packages/macOS/CmuxNext/ci-target-graph.json

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39312436953

* test(acpmux): filtered model rows show no number keys

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(acpmux): model menu review fixes

Filtered rows show no number keys (a digit narrows the filter), an
account switch with no acpmux client fails instead of reporting success,
and a late switch answer for another chat leaves this one alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(composer): model and effort chips are plain at rest, a small rect on hover and focus (failing)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): model and effort chips are plain at rest, a small rect on hover and focus

The model, effort and access chips drew a filled capsule at rest. They are
now plain text and icon; hover, keyboard focus and an open menu draw the
existing wash as a 7px rect (the mode and Plan chips' radius), never a
capsule (Leo 2026-10-19).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(composer): the picker rail's chips are plain at rest, not tonal capsules

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(agent pane): the composer chips leave the capsule allowlist

They are small-radius rects now, so the no-capsules check covers them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(model menu): the rail's round tabs are circles (50%), not 999px capsules

agent-pane-no-capsules flagged the 999px radius; the 32px square tab is a
true circle with 50%.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(next): PR autofix at 238a897

- vp fmt webviews/test/composer-chip-plain-rest.test.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39326155412

* test(model menu): a filtered row the keyboard moved to keeps focus across re-renders

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(model menu): a re-render keeps the filtered row the keyboard moved to

The compact menu refocused its first row whenever families changed, and
ModelPicker builds a new families object on every composer render. While
a reply streamed, a row picked with the arrow keys jumped back to the
first match, so Enter could pick the wrong model. Focus now moves to the
first row only when the filter changes or the focused row is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(next): the chips' hover and focus background is the pill #22107 landed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-autofix[bot] <cmux-autofix[bot]@users.noreply.github.com>
teamleaderleo added a commit that referenced this pull request Oct 19, 2026
…ws only with the focused ring

The New Tab button row is .nt-pickers, not .acpmux-composer-bar, so every
bar-scoped rule skipped it: the plain footer look (data-footer-look, the
default), #22107's hover, press and keyboard-focus pills and outline, and
#22114's glass focus rim. The row now takes the chat's footer look and the
same state rules.

The caret and the focused ring now follow one state: pageKey.ts marks the
root data-page-inactive while the page is not the key one (window blur,
hidden, document without focus), and then a focused field hides its caret
and every composer draws its resting ring. A key or press on the page, or the
window's focus, brings both back.

Gallery: composer-rest/hover/open/focus/keyboard/background variants for the
chat composer and the New Tab page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

teamleaderleo added a commit that referenced this pull request Oct 20, 2026
…ows only with the focused ring (#22216)

* test(composer): one caret, focus and chip behavior in the chat and New Tab composers (failing)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): New Tab gets the chat's chip states, and the caret shows only with the focused ring

The New Tab button row is .nt-pickers, not .acpmux-composer-bar, so every
bar-scoped rule skipped it: the plain footer look (data-footer-look, the
default), #22107's hover, press and keyboard-focus pills and outline, and
#22114's glass focus rim. The row now takes the chat's footer look and the
same state rules.

The caret and the focused ring now follow one state: pageKey.ts marks the
root data-page-inactive while the page is not the key one (window blur,
hidden, document without focus), and then a focused field hides its caret
and every composer draws its resting ring. A key or press on the page, or the
window's focus, brings both back.

Gallery: composer-rest/hover/open/focus/keyboard/background variants for the
chat composer and the New Tab page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(composer): read the glass rim in WebKit's shadow order too

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(composer): vp fmt the caret and focus test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): a chip a click focused does not lift the New Tab glass rim; test a key marks the page key

From review: the chat card lifts only for its prompt or keyboard focus, so the
New Tab card does the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(composer): the glass rim check runs where the engine draws the rim

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Oct 20, 2026
…l again (#22322)

* test(agent pane): the composer chips' pill is a capsule by design again

#22005 first made the model, effort and access chips 7px rects and took
them off the capsule allowlist. Its last commit then took #22107's pill
for their hover and focus background (composer-chip-plain-rest), but the
allowlist stayed short, so agent-pane-no-capsules flags styles.css's
999px. composer-chip-plain-rest stays red on the composer bar until the
fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer chips): the composer and New Tab chips draw #22107's pill again

#22005 set the chips in the composer bar to 7px rects. Its last commit
then took #22107's pill for their hover, focus and open background, but
left the 7px behind. So composer-chip-plain-rest has been red on the
composer since, and on the New Tab box since #22216 put .nt-pickers on
the same rule. The rule now draws the 999px pill that styles.css and
composer-chip-press already expect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Oct 20, 2026
…othing (#22353)

* test(composer): focus draws no ring or glass rim, and a press changes nothing (failing)

Leo 2026-10-19: the glass focus ring flashes on the composer, and he does
not want the mousedown/mouseup click feedback. The tests now assert that a
focused chat or New Tab composer draws its resting rim (over art too, and
on the strip and queue edges), that the caret alone shows focus, and that
a press on a composer chip changes neither its transform nor its opacity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): no focus ring or glass rim, and no press shrink or dip

Leo 2026-10-19: "the fucking stupid glass focus ring keeps flashing it's
bad on the composer i dont like and i dont like the click feedback
mousedown mouseup situation let's not do the thing for now".

Focus: the focused edge token is now the resting edge, so a focused chat
or New Tab composer, its strip and its queue draw the resting rim. The
glass focus rim from #22114 (extended to New Tab in #22216), the shell
mode's brighter focused ring and New Tab's own focus-within step are gone.
The caret still hides while the page is not key. Increase Contrast keeps
its shared focus ring.

Press: the 0.975 shrink and 4% dip from #22107 and their spring-back
transitions are gone. #22107's hover pill and keyboard-focus pill stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Oct 20, 2026
…box; mode, model, effort and context ring in a quiet row under it) (#22285)

* test(composer): one caret, focus and chip behavior in the chat and New Tab composers (failing)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): New Tab gets the chat's chip states, and the caret shows only with the focused ring

The New Tab button row is .nt-pickers, not .acpmux-composer-bar, so every
bar-scoped rule skipped it: the plain footer look (data-footer-look, the
default), #22107's hover, press and keyboard-focus pills and outline, and
#22114's glass focus rim. The row now takes the chat's footer look and the
same state rules.

The caret and the focused ring now follow one state: pageKey.ts marks the
root data-page-inactive while the page is not the key one (window blur,
hidden, document without focus), and then a focused field hides its caret
and every composer draws its resting ring. A key or press on the page, or the
window's focus, brings both back.

Gallery: composer-rest/hover/open/focus/keyboard/background variants for the
chat composer and the New Tab page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(composer): read the glass rim in WebKit's shadow order too

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(composer): vp fmt the caret and focus test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): a chip a click focused does not lift the New Tab glass rim; test a key marks the page key

From review: the chat card lifts only for its prompt or keyboard focus, so the
New Tab card does the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(composer): the glass rim check runs where the engine draws the rim

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* cmux NEXT composer: Claude Code's split, mode/model/effort in a quiet row under the box

Leo 2026-10-19: follow Claude Code. Under the plain footer look (the default)
the box keeps +, the prompt, the mic and Send or Stop; the permission mode
(left) and the model and effort (right) sit in a quiet row under it
(ComposerFoot.tsx), in the chat composer and on the New Tab page alike. The
mic never leaves a row. + names itself Add in the shared tooltip. The mode
menu's check sits at the trailing edge in its number's place. Send is the
theme's ink, no iMessage blue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: the mic stays at every width; row steps measure both composer rows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* composer: the quiet row ends on the context ring; New Tab mic gallery states

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* composer: the quiet row keeps the model and effort right without a mode; split test measures chips

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: row rhythm and plain footer measure the split rows; the plain look is the default

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* composer: the context ring holds its place before usage, so the quiet row never shifts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: the location strip's control check reads both composer rows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style: oxfmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: rhythm per composer row; Tab reaches the model from the quiet row; gallery covers ComposerFoot

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* composer: the row fit follows the footer look toggled live; an inert ring draws no hover pill; the quiet row widens with a narrow box

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(next): PR autofix at 15a8255

- webviews/test/composer-row-rhythm.test.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39357323337

* test: Tab from the prompt reaches the model chip in the quiet row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(next): PR autofix at cfb38b8

- webviews/test/composer-footer-plain.test.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39358917109

* chore(next): PR autofix at 36bb517

- webviews/src/agent-session/acpmux/newtab/NewTabScreen.tsx

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39365778871

* test(new tab): on Cards the suggestions leave the quiet row's chips reachable

The menu-over-suggestions harness takes ?template=cards, the app's default
page, which draws Claude Code's split: the mode, model and effort sit in the
quiet row under the box. Each menu test runs there too, and a new test asks
that the suggestions open under the quiet row with every chip still taking
its own press (greptile on #22285, NewTabScreen.tsx:894). Red until the
suggestions anchor under the whole composer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(new tab): the suggestions hang under the quiet row, not over it

With the split, the mode, model and effort sit under .nt-box, and the
suggestions opened 6 px under the box, over them: a click on a chip picked
a suggestion. The popover (both the Popover anchor and useEscapingPopup) now
anchors on the whole .nt-composer when the split draws, and a press in the
quiet row keeps the suggestions as one in the box does. Cards' pill keeps
the box anchor: its toolbar steps aside while Search suggests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): Full access in the quiet row draws in the model chip's color

The quiet row tinted Full access's shield with --acpmux-warning, which
undoes Leo's quiet permission chip (2026-10-18, #21744): the chip draws in
the model chip's color, its shield's "!" names the risk, and the menu keeps
the warning color where the mode is chosen. quiet-access-chip asserts that
and was red on Chromium and WebKit. The shield still shows for Full access.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(composer): the fast bolt sits in the quiet row with the split

With Claude Code's split (the plain footer, on by default) the bolt leaves
the box with the chips: it follows the model and effort in the quiet row
and comes before the context ring, while the box keeps the mic and Send.
The old test looked for it in the box's trailing cluster.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(composer): before any use the quiet row's context ring is off, not absent

Claude Code's split keeps the context ring's place in the quiet row from
the first frame, so the first usage report moves nothing (hq#1957). Leo's
"no context ring before any use" (2026-10-13) now reads as no reading: the
ring is disabled and draws only its track. The old test counted no ring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: the New Tab split checks read the Default template now that Cards is the default

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(new tab): Cards with the agent's chips draws the split, and the mic stays in Search

Cards, the first dot, draws Claude Code's split when the agent's chips are
there: the project strip heads the card, the box holds the prompt, the mic
and Send, and the mode, model and effort sit in the quiet row under it. No
pill toolbar draws, so Search, which hides that toolbar, never hides the mic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: the split's quiet row in the scroll, ring and Cards menu checks

- new-tab-scroll: All chats is the only scroller at 400 px; at 360 the
  quiet row's 32 px puts the list at its two-row floor, where the page
  scrolls by design.
- composer-footer-essentials: before use the ring draws only its track (the
  fixture reports zero use, so the ring is not disabled).
- new-tab-menu-over-suggestions: on Cards only the model menu reaches over
  the suggestions; the effort and access menus open clear of them (CI on
  dbc55ac measured no overlap and no misses).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(new tab): stub the observers the split's quiet row fits with

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(new tab): Cards with the split draws no create row

The app always passes the chips and the plain footer is on by default, so
Cards draws the split, and NewTabScreen gated the create row on !pill: the
row came back on the default page. Red until the gate names Cards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(new tab): Cards draws no create row with the split either

The create row was gated on !pill, and pill is now Cards with the split
off. In the app the chips are always there and the plain footer is on, so
the default page showed New Terminal, New Browser Tab and New Chat again.
The gate names the template.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: the split's rows in turn-cycle, footer-essentials and narrow panes

- composer-turn-cycle: calm() reads both rows. The box's row has no
  chips now, so the lock and status-chip checks read the quiet row as
  well, which may hold its one context ring. The ring is also measured
  across the cycle.
- composer-footer-essentials: the ring check needs at least one ring.
- narrow-layouts: New Tab's Default template (chips beside the mic, wide
  type) and the chat composer with the plain footer off keep the
  single-row case measured at every width.
- Gallery notes for template-cards and template-cards-search describe the
  split.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(narrow panes): the single-row stage keeps the plain footer off

Turning the setting back on after the play redrew the composer while the
stage's own hover checks measured it (layout shift 0.013). Each variant
loads its own page, so the setting can stay off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): a short pane's dock spills upward, so Stop keeps Send's place

With the split, the composer is 32 px taller (the quiet row under the box).
In a 300 px pane with a queued prompt, the float dock's content outgrew its
max-height and ran past the pane's bottom, so Stop drew 13 px below where
Send sat (composer-row-layout). The dock now packs its content at the
bottom, so what doesn't fit spills over the transcript instead.
narrow-layouts' single-row stage also lets the footer swap settle before
its measured hover.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): the composer form, not the dock, packs at the bottom

The dock holds one form, which shrinks to the dock's max-height, so the
overflow was inside the form. A probe on Blacksmith Linux (run
39390110264) showed it: queued, the box sat 13 px lower (174-265 against
161-252), with the queue at its 34 px floor. The form now packs its queue,
box and quiet row at the bottom, so what doesn't fit spills upward.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(composer): put the dock back; row-layout measures a pane the split fits

Packing the form at the bottom made a short pane's queue spill over the
pull request dock above it, which agent-pane-bottom-stack forbids. The
stack's base rules come back unchanged. composer-row-layout measures Send
and Stop in a 340 px pane: at 300 px, with a queued prompt, the dock is at
its floor and the split's 32 px quiet row doesn't fit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-autofix[bot] <cmux-autofix[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant