cmux NEXT composer: a Codex look of the same composer, two dots to switch (New Tab, and on hover in a chat)

Merged
TE
15d ago
+778-53

The composer gets a second look, Codex's, of the same one composer, picked with two dots: the first dot is Claude's look (today's composer, still the default), the second is Codex's. The two dots sit first under every New Tab page. Split for size: the same dots on hover in a chat's composer bottom area are #24395, stacked on this one.

Leo-ask: ask-5a69bb86d3
Leo-ask: ask-7fcf472bf8

Leo's words:

  • "lawrence likes the codex way i think we can have as option... the composer looks"
  • "this is the codex composer. i guess we could make the alternative composer like codex. first dot claude, second dot codex. since it's just all looks anyways. first 2 dots minimal on the new tab page, and then when you're in a chat you can also switch the dots if you hover on that bottom area. e.g. there's space down here, and also dead space in codex's thing"
  • (part) "we can have the alt composer like chatgpt styled but for now just have "minimal" be the claude thing"

What changes

  • One composer, two looks (composerLook.ts, composerLook.css). claude is the composer as it was: nothing in its drawing changes. codex lays out the same controls the way Codex desktop does. The box holds one row under the prompt, with + and the mode on the left and the context ring, the model and effort, the mic and Send on the right. On a new chat and on New Tab, the folder and computer strip becomes a tray tucked under the box's top edge. ComposerBox, Composer and NewTabScreen read the look and set data-composer-look="codex", so it stays one component with a layout attribute.
  • New Tab dots (newtab/PageDots.tsx). The first two dots under the page are the looks: Claude, then Codex. They show on every New Tab page; on Minimal with the style dots widget off (its default) they are the only dots: "first 2 dots minimal on the new tab page". A look dot switches the look only, in place, on every page style (this answers the Codex review at aa20d0e4: on Classic it used to switch the whole page to Minimal). The dots are two groups in one row: the looks, always marking the current look, then, with the style dots on (always on the other styles), the page styles exactly as the style switch had them, Minimal among them, marking the page's style.
  • Every New Tab page draws the look. Minimal, Default, Composer, Threads and Console through NewTabScreen. Classic (NewTabPage, two lines: useComposerLook and data-composer-look) lays out its box's row in Codex's order: the mode first, then the project and agent, and the model by Send. Cards with Codex's look draws the chat composer's box with the project strip as Codex's tray, instead of its pill.
  • The choice persists in localStorage (cmux.composer.look), shared across chats, panes and launches through the storage event, the way the transcript's wrap choice already works. A localStorage.clear() (a storage event with a null key) returns the look to the default. There was no existing setting for this.
  • StyleSwitch's dots are now DotSwitch over any option list. StyleSwitch keeps its API and behaviour (its tests are unchanged and pass).

Kept: our glass and colours. Full access takes the theme accent, never Codex's orange. Send stays our plain glyph with no disc. The two switcher dots are the only dots added, and there is no status dot. Not touched: what Claude's look draws, the model menu internals (#24224), the queue and the mode menu. No default flips: Claude's look stays the default.

Gallery

There is a new entry, agent-pane.composer-look: claude-chat, codex-chat, codex-new-chat, newtab-claude, newtab-codex, newtab-classic-codex and newtab-cards-codex. (claude-chat-dots and codex-chat-dots come with #24395.) It also has two alternates for the Codex look: codex-new-chat-alt-plain-strip (Codex's row, with the strip left as plain text over the box) and codex-new-chat-alt-text-row (the tray, with the row as quiet text and no mode glyph). Pick: codex-chat / codex-new-chat, the tray. It is closest to Codex's references, and the row keeps the mode's symbol, which Leo asked for on 10-21 ("(!) Full access").

Before/after: https://cmux-lawrences-mac-mini.tail137216.ts.net:18796/compare/composer-look-codex-dot/?entry=agent-pane.composer-look. agent-pane.new-tab#minimal-default now shows the two dots and nothing else changes; its play now asserts exactly two dots.

Evidence

  • test/composer-look-dots.test.ts (real Chromium on the gallery stage). Command: CMUX_BROWSER_TESTS=1 bun test test/composer-look-dots.test.ts, run on huge-blue.
    • The New Tab test was committed first (53239869a6c). It failed on that commit because New Tab had no look dots.
    • The Classic and Cards test was committed before its fix (9e8cf4f4a3b). Run against aa20d0e4's code it fails (1 pass, 1 fail): picking Codex on Classic leaves Classic, so .acpmux-newtab[data-composer-look="codex"] never shows.
    • At the head: 2 pass, 0 fail (14 expects). On Classic, the Codex dot keeps the page Classic, with Classic's style dot still marked and Minimal still offered. The box takes Codex's look, which also holds after a reload. Cards draws the tray (.nt-above), with no .nt-toolbar pill and the model in the box. On Minimal, the pick sets data-composer-look="codex" and survives a reload.
  • These still pass at the head: new-tab-style-switch (3), new-tab-style-dots (2), new-tab-minimal-default (6), composer-claude-split (18), new-tab-widget-edit (5), new-tab-no-dots (1) and suggestion-lists-float (3).
  • popup-escape: "a 600x400 window sends the commands list past its edge" fails the same way on base 487876a066f (a base red). The other 4 pass.
  • vp check (format, lint and type-aware lint over 2352 files) is clean at the head. check:system-blue, check:text-focus, check:layers, check:motion-scale, check:status-glyphs, check:dialog-keys and check:switch-fetches pass. There is no repeated key in the changed catalog.
  • cmux-ci compile-check --ref f6052c8f474870c7d4e146a6f6ec610aa63acc2e --app passed (job c191fd6d2300fbd13a05d760, 62 s).

Observed / Not run

  • No native capture: this is webview-only UI, and the screenshots come from the gallery. No capture: webview-only (agent pane web page); gallery entry agent-pane.composer-look.
  • About 830 changed lines, 132 of them the one new catalog string's 21 translations. The in-chat dots moved to #24395 to stay near the ~800 guide.

Overlap: #20598 (open, the New Tab style switch as a Debug Settings choice) touches the same dots; this PR keeps StyleSwitch's API for it. #24314 also edits NewTabPage.tsx and NewTabScreen.tsx, in different hunks (an import and a hook near the top).

Changelog

  • Added: A Codex look for the composer, picked with the first two dots on any New Tab page. Claude's look stays the default.

Agent session: cosmic-gray

🤖 Generated with Claude Code