Skip to content

cmux-next: composer controls stay grouped and steady during a turn (hq#1957 item 15) - #20443

Closed
teamleaderleo wants to merge 13 commits into
feat-cmux-nextfrom
cg-lane-adopt/composer-row
Closed

teamleaderleo wants to merge 13 commits into
feat-cmux-nextfrom
cg-lane-adopt/composer-row

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes the agent composer's controls row and stops the composer from shifting during a turn (hq#1957 item 15; Leo: "this is super weird", "so much layout shift while a subagent runs").

Controls row

  • Before: the permission chip was a fixed 180px wide behind a flex spacer, so "Auto" floated in the middle of the row and left a big gap.
  • Now: plus, model, ring, effort and permission sit together on the left; mic and Send/Stop sit on the right. Free space appears only between the two groups.
  • In a narrow pane, labels give way in order: the permission label goes first (lock icon only), then effort, then model.
  • The footer row (folder, host, branch) can grow but never shrinks. It keeps 12px side and 10px bottom insets, so it is no longer clipped.

Layout shift during a turn

  • The context ring used to appear at turn start. It now holds its slot once a session exists, so a prewarmed new chat shows an inactive ring.
  • Steer (shown when you type during a turn) used to push the mic left. It now comes in to the left of the mic.
  • The queue, permission asks and PR dock already grow upward over the transcript. Send/Stop is the same 32px circle. A mode change moves no other control.
  • Exception: in a narrow (~420px) row, the left cluster may shift when Steer appears, because there is no spare room to reserve.
  • The labels/icons switch has hysteresis: it leaves icon mode only with 4px of clear room, so it cannot flip every frame.

Compact row (Leo: "tonka toys")

  • The left group is "+ · model · effort · access", with even 8px gaps between 28px controls. Hover is a light wash that sits tight to each control.
  • The context ring is no longer in the row. Context usage now shows in the model chip's tooltip ("Opus 5.5 · 42% of context used"). The context details popover and its Compact button are gone from the pane; /compact still works.
  • The "Trusted this chat's…" chip has no slot in the row (op-next-composer-footer-cx is removing it), so the row shows one lock at most.
  • Stop is the same 28px grey circle as Send, with a 7px square. It replaces the large white disc.

Edges (border hunt, op-next-theme)

  • fix(cx-9ah60): sequence agent chat bottom stack without overlap #20303 added a glass shadow and a text-color rim to the composer card. Both are gone. The card keeps one thin Apple-like rim, the 0.5px --acpmux-composer-edge hairline, which appearance.borders = none clears (Leo: a thin Liquid Glass rim is good, don't strip it to zero).
  • Permission cards keep one 0.5px hairline in the same edge color, with no shadow. A test guards that the hairline stays.
  • The permission panel's gallery entry now loads the pane's stylesheets inside .acpmux-shell. Before this, its edge checks measured an unstyled card and passed without testing anything.
  • The New Tab box loses its drop shadow, both at rest and when focused.
  • Keyboard focus still shifts the card's edge toward the accent color. That is a focus state, not a border, so it stays under borders = none.

Verification

  • Edges: CMUX_BROWSER_TESTS=1 bun test test/composer-edges.test.ts was red at 4580bd4 (0/5) and at acab5b5 (New Tab), and is green 6/6 at a585a87. With the real permission card measured (600aa9e), the CSS from before the fix fails 6 of 7 checks and the fix passes 7/7. Of the related composer, New Tab and permission suites, 132 pass and 1 fails: new-tab-chat-title-width, which fails the same way on the base.
  • Compact row: CMUX_BROWSER_TESTS=1 bun test test/composer-row-layout.test.ts test/composer-turn-cycle.test.ts was red at d5fa4a0 (3 pass, 30 fail) and green at 1bebce0. bun test test/composer-*.test.ts passes 53/53. Captures are on big-red at /tmp/cg-lane-adopt-dogfood/compact-{before,after}-*.png.
  • CMUX_BROWSER_TESTS=1 bun test test/composer-row-layout.test.ts: red 0/12 on eddade2, green 12/12.
  • CMUX_BROWSER_TESTS=1 bun test test/composer-turn-cycle.test.ts: red 0/6 on 3979132, green 6/6. It checks that the input and every control stay within 0.5px through idle → running → 1 subagent → 3 subagents → asking → queued → finished.
  • bun test test/composer-row-fit.test.ts (switch hysteresis): red 1/3, green 3/3.
  • bun run check passes; a review subagent found no blockers, and its flip-flop finding is fixed above.
  • Unverified: Chromium only, not WebKit or the native app. I could not reproduce Leo's exact footer clipping outside the gallery.
  • Screenshots (before/after at 420, 720 and 1100px, plus the turn cycle) are on big-red at /tmp/cg-lane-adopt-dogfood/composer-*.png.

Changelog

Fixed: the agent composer's controls form one compact row (stop matches send, no spinner) and no longer shift while a turn or subagent runs.

🤖 Generated with Claude Code

teamleaderleo and others added 4 commits October 13, 2026 21:55
…r inset

hq#1957 composer controls row (item 15). A gallery entry (agent-pane.composer-row) draws
Leo's row (Claude Opus 5.5, ring, Medium, Auto), a long model name, the chat-wide
allowance chip and a queued running turn at 420, 720 and 1100 px. The browser test
measures it: one contiguous left cluster, free space only before mic/Send, no cut label
while the row has room, permission labels cut first and the model last, and the footer
inset from the card's bottom edge.

Red: CMUX_BROWSER_TESTS=1 bun test test/composer-row-layout.test.ts -> 0 pass, 12 fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hq#1957 composer controls row (item 15). The permission chip was a fixed 180 px wide
behind a flex spacer, so the row kept a large empty gap while the model and effort chips
truncated, and below 480 px the model went icon-only before anything else.

- The chips hug their controls (+, model, ring, effort, permission mode, then the granted
  status); mic and Send/Stop keep margin-left: auto. Free space sits only between the two
  clusters. The permission chip stays in the left cluster with the other session settings;
  the right cluster stays the input's own actions.
- A short row drops the permission labels to their lock first (composerRowFit.ts measures
  the row and sets data-fit=icons; hidden labels stay laid out so the decision never
  toggles to measure), then effort shortens, the model last (flex-shrink weights 1e5:1
  with min widths). The 480 px icon-only model and fixed access widths are gone.
- The footer grows with its content (min-height, no fixed height), never shrinks, and keeps
  the bar's 12 px side inset and a 10 px bottom inset inside the card.

The composer-menu-width case that pinned the 180 px chip now checks the contract that
mattered: a mode change moves no other control.

Green: CMUX_BROWSER_TESTS=1 bun test test/composer-row-layout.test.ts -> 12 pass, 0 fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hq#1957 composer controls row (item 15), layout-shift follow-up. A gallery entry
(agent-pane.composer-turn-cycle) opens a chat's first turn idle, before any context usage,
and its cycle play delivers running, one then three subagents, a subagent's permission
ask, a queued prompt and finished through the pane bridge. The browser test checks that
the prompt, controls row, footer and every control keep their boxes within 0.5 px at 420,
720 and 1100 px, and that typing during the turn (Stop -> Steer + Send) moves neither the
mic nor Send.

Red: CMUX_BROWSER_TESTS=1 bun test test/composer-turn-cycle.test.ts -> 0 pass, 6 fail
(the context ring mounts when the turn starts and shifts effort and the permission chip;
Steer lands between the mic and Send and pushes the mic left).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hq#1957 composer controls row (item 15), layout-shift follow-up.

- The context ring holds its slot from the session's start (inert until the first usage
  report, as ContextRing already draws it) instead of mounting when the turn starts, which
  slid effort and the permission chip 34 px right on every chat's first turn.
- Steer comes in at the leading edge of the right cluster, so when typing during a turn
  turns Stop into Steer and Send, the mic and Send keep their places (it used to land
  between them and push the mic left).

The queued-prompt stack, a subagent's permission ask and the PR dock already grow upward
over the transcript; Send and Stop share one 32 px circle.

Green: CMUX_BROWSER_TESTS=1 bun test test/composer-turn-cycle.test.ts -> 6 pass, 0 fail.

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

cursor Bot commented Oct 14, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 72ee1eac-1eae-476b-93b7-fdf939b1c227

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

teamleaderleo and others added 2 commits October 13, 2026 22:10
…xel band (hq#1957 item 15)

Red: bun test test/composer-row-fit.test.ts -> 1 pass, 2 fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#1957 item 15)

Hysteresis on the labels/icons switch so a sub-pixel squeeze cannot flip it every
frame; drops a leftover spacer from the dictation gallery.
Green: bun test test/composer-row-fit.test.ts -> 3 pass.

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

This comment has been minimized.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

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

CI failed on 600aa9e50b (run 38521546922 attempt 1): 1 unknown.

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

Not re-run automatically: web / react-apps-check is not a machine failure.

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.

…ct row)

hq#1957 item 15 compact row. Leo's nightly row reads as toy blocks: a context ring that looks
like a spinner, uneven gaps, two locks (Auto and the "Trusted this chat's..." status chip) and a
large white Stop disc. The row-layout test now checks, at 420, 720 and 1100 px in every
variant: the left cluster's controls sit 8-12 px apart and within 1 px of each other; no ring
or spinner in the row; one lock at most; no granted-status chip; Stop's glyph is a square of
at most 12 px; and Stop takes Send's box (within 0.5 px) and its resting fill. The turn-cycle
test checks no ring or spinner, one lock and no status chip in every phase, and no longer
tracks the ring's slot.

Red: CMUX_BROWSER_TESTS=1 bun test test/composer-row-layout.test.ts test/composer-turn-cycle.test.ts
-> 3 pass, 30 fail (model-effort 36 px apart around the ring, effort-access 2 px; ring in the
row in every phase; 2 locks and the status chip in "granted"; Stop's fill rgb(255,255,255)
against Send's grey).

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

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

CI fast guards failed on 600aa9e50b (https://github.com/manaflow-ai/cmux/actions/runs/38521546922). 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. This comment is updated in place on each push.

…t row)

hq#1957 item 15 compact row. The row is "+ · model · effort · access" on the left and
mic, then Send/Stop on the right, with free space only between the two.

- Gaps: the chips sit the bar's 8 px apart (they were 2 px, plus the ring's 36 px slot), so
  the left cluster's gaps are all 8 px. Model, effort and access are the bar's regular 28 px
  (were 30) with tighter padding.
- Hover: the shared quiet wash (ui.css --ui-hover's fallback, the control's ink at 6% over
  the card; 12% on press) tight to the control, in place of the opaque composer-hover block.
  Mic, Plan and Steer use it too.
- No context ring in the row. This undoes the earlier fixed ring slot. The chat's usage is
  in the model chip's tooltip ("Opus 5.5 · 42% of context used", the existing picker.context
  string), shown while showContextUsage is on. The row's right-click no longer offers
  Hide/Show Context Usage, which has no control to act on now. Compact stays reachable as
  /compact. ContextRing itself and its gallery are kept.
- One lock: the granted-permission status chip (PermissionStatus) is no longer placed in the
  row. The component and its gallery stay. Trust undo and chat-allowance revoke keep their
  other entry points in App.tsx.
- Stop is Send's 28 px circle at its resting fill (the accent at 34% over the base), with a
  7 px square in the text color, not a white disc. Its hover and press step the circle.
- composerRowFit.ts no longer watches the status chip. Galleries drop the ring plays
  (composer context-usage-menu, picker context-details/context-focus).

Green: CMUX_BROWSER_TESTS=1 bun test test/composer-*.test.ts -> 53 pass, 0 fail
(composer-row-layout + composer-turn-cycle: 33 pass, 0 fail). bun run check -> pass.

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

Copy link
Copy Markdown
Collaborator Author

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

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Gallery

Review in feed

1819 states changed: agent-pane.permission-panel/expanded, agent-pane.transcript/long-code, agent-pane.artifact-panel/closed, agent-pane.artifact-panel/markdown, agent-pane.artifact-panel/html, ... · 88 new states · 24 removed states · 53 play checks failed

Diff page and renders (the run's gallery-pr artifact)

State Before · after
agent-pane.permission-panel/expanded (Apple System Colors, chromium)
agent-pane.permission-panel/expanded (Apple System Colors Light, chromium)
agent-pane.transcript/long-code (Apple System Colors, webkit)
agent-pane.permission-panel/expanded (Apple System Colors, chromium)
agent-pane.permission-panel/expanded (Apple System Colors Light, chromium)
agent-pane.artifact-panel/closed (Apple System Colors, chromium)

1813 more on the diff page.

Live preview (follows this branch; start it with scripts/gallery-live.sh up <branch> from an hq checkout):

  • agent-pane.permission-panel/expanded: /wt/cg-lane-adopt-composer-row/?entry=agent-pane.permission-panel#/agent-pane.permission-panel/expanded
  • agent-pane.transcript/long-code: /wt/cg-lane-adopt-composer-row/?entry=agent-pane.transcript#/agent-pane.transcript/long-code
  • agent-pane.artifact-panel/closed: /wt/cg-lane-adopt-composer-row/?entry=agent-pane.artifact-panel#/agent-pane.artifact-panel/closed
  • agent-pane.artifact-panel/markdown: /wt/cg-lane-adopt-composer-row/?entry=agent-pane.artifact-panel#/agent-pane.artifact-panel/markdown
  • agent-pane.artifact-panel/html: /wt/cg-lane-adopt-composer-row/?entry=agent-pane.artifact-panel#/agent-pane.artifact-panel/html
  • agent-pane.permission-panel/allow-once: /wt/cg-lane-adopt-composer-row/?entry=agent-pane.permission-panel#/agent-pane.permission-panel/allow-once
  • 262 more on the diff page

Play checks failed (0 px anchor movement, 0 layout shift, no frame over 33 ms unless the entry gives a reason):

  • agent-pane.artifact-panel/markdown (Apple System Colors, chromium): play: no element for button "Open preview"
  • agent-pane.artifact-panel/html (Apple System Colors, chromium): play: no element for button "Open preview"
  • agent-pane.permission-panel/allow-once (Apple System Colors, chromium): play: waitFor did not hold within 5000 ms
  • agent-pane.permission-panel/allow-once (Apple System Colors Light, chromium): play: waitFor did not hold within 5000 ms
  • agent-pane.permission-panel/allow-once (Apple System Colors, webkit): play: waitFor did not hold within 5000 ms
  • agent-pane.permission-panel/allow-once (Apple System Colors Light, webkit): play: waitFor did not hold within 5000 ms
  • 306 more on the diff page

244 nondeterministic states differed from a second render of the same head (a clock or fixture leak) and are not counted as changes.

481 unchanged · base c5ed567 · head 600aa9e

teamleaderleo and others added 5 commits October 13, 2026 23:05
…lass (hq#1957 border hunt)

Red: CMUX_BROWSER_TESTS=1 bun test test/composer-edges.test.ts -> 0 pass, 5 fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…asured at rest (hq#1957 border hunt)

Red (New Tab box): CMUX_BROWSER_TESTS=1 bun test test/composer-edges.test.ts -> New Tab box: no drop shadow fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ass shadow and rim (hq#1957 border hunt)

The composer card keeps only its --acpmux-composer-edge hairline (clear under
appearance.borders = none); permission cards take the same hairline and no shadow; the New
Tab box loses its drop shadow at rest and on focus. Focus still steps the edge toward the accent.
Green: CMUX_BROWSER_TESTS=1 bun test test/composer-edges.test.ts -> 6 pass.
Related composer/New Tab/permission suites: 132 pass, 1 fail (new-tab-chat-title-width,
fails identically on the base).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#1957 border hunt)

The permission panel's gallery entry loaded only styles.css and sat outside .acpmux-shell, so
the card's edge rules (composerLocation.css, --acpmux-composer-edge) never applied and its edge
checks passed vacuously. The entry now loads the pane's stylesheets inside the shell, and a guard
keeps the card's one .5px hairline (Leo: a thin Liquid Glass rim is good, don't strip it to zero).
Red on the pre-fix CSS (1bebce0): 1 pass, 6 fail. Green: 7 pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- vp fmt webviews/src/agent-session/acpmux/modelPickerLayout.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/38521546851
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Landed via #20454 (squash e2a6fac), which contains this branch's head 3e45222.

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