Repository navigation
cmux NEXT composer: dictation looks like Claude's: Listening…, a live waveform, a finish key and a lit mic - #22713
Conversation
The field says Listening… until words come and streams partials live; a waveform, a finish key and the lit mic sit beside Send while listening; the finish key stops (keeps the words), never cancels. Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=e8f63fd9-94e8-4878-bcd4-704659aba1f2&host=cosmic-gray
… waveform, a finish key and a lit mic While a session runs, the empty prompt reads "Listening…" in italic (chat composer and New Tab field), the words stream in update by update as before, and before the mic come a waveform of thin bars that follows the mic level and tapers into dots at both ends, and a finish key (Return glyph) that calls dictation.stop, keeping the words. The mic keeps its glyph and lights in the theme accent (an accent-tinted rounded square) instead of turning into a red level meter. Bars move only under the pane's motion gate. Strings dictation.listening and dictation.finish in all 21 locales (machine translations marked needs_review). Gallery: component states (idle, starting, listening, finalizing, finish) and the chat's real composer driven through the bridge (idle, listening empty, listening with words, finalizing). Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=e8f63fd9-94e8-4878-bcd4-704659aba1f2&host=cosmic-gray
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Unclear: CI failed on
Failures:
Matched log linesNot re-run automatically: Written by red: web / Web status; NEW: green on the base b8314d7; do not merge until green; see lane-rules |
build-agent-pane-web.sh inlines every sheet the pane imports; the new dictation sheet goes after the composer sheets so its lit-mic rules win. Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=e8f63fd9-94e8-4878-bcd4-704659aba1f2&host=cosmic-gray
|
Bead |
|
Shipped in:
|
…ish key returns focus to the prompt (#22719) * test(next): the dictation finish key hands the keyboard back to the field (red) The New Tab helper passes `dictating` from the pane's own dictation, as App.tsx will, instead of reading a page-wide flag. Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=e8f63fd9-94e8-4878-bcd4-704659aba1f2&host=cosmic-gray * cmux NEXT composer: dictation's Listening… comes from the pane's own session; the finish key keeps focus Follow-up to #22713's review: the page-wide listening flag in dictation.ts is gone; App.tsx passes `dictating` (isWaitingForWords of its dictation state) to the Composer and the New Tab screen. The finish key puts the keyboard back in the prompt as it goes away, keeps a 4px gap from the mic in the chat bar, WAVE_BARS is private, the stale red-mic comment in styles.css is updated, and the gallery covers 297px and 260px rows. Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=e8f63fd9-94e8-4878-bcd4-704659aba1f2&host=cosmic-gray * test(agent pane): the Dictation key starts the pane's dictation, not macOS's overlay (red) Start Dictation sent up the responder chain from an agent page's web view goes past the pane to NSApplication, which shows macOS's black dictation HUD at WebKit's caret over the composer's corner. Adds the agent.systemDictation Debug toggle (off) and the AgentPaneDictationKey routes the fix uses; the pane does not take the action yet, so the tests fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba2-63d6-7533-b232-21f35d99d2b2&host=cosmic-gray * cmux NEXT agent pane: the Dictation key starts cmux's dictation in the composer The Dictation key (fn, the 🎤 key) and Edit ▸ Start Dictation send startDictation: up the responder chain; NSApplication answered it with macOS's black dictation HUD at WebKit's caret, over the composer's corner. AgentPaneView now takes the action when the first responder is inside it and toggles the pane's own dictation, as the composer's mic does, so a second press finishes it. Terminals, browsers and other panes never reach an agent pane and keep macOS's dictation. The agent.systemDictation Debug toggle (off by default) hands the action back to NSApplication. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba2-63d6-7533-b232-21f35d99d2b2&host=cosmic-gray * test: the dictation finish key's focus check starts from the key itself Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba2-63d6-7533-b232-21f35d99d2b2&host=cosmic-gray --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
While you dictate into the agent chat composer (or the New Tab field), it now looks like Claude's (Leo's Claude Code reference, 2026-10-20). The empty prompt says Listening… in italic, muted. Words stream into the field as they're heard. Before the mic, in the same row, you get a waveform of thin bars that follows the mic level and fades to dots at both ends, then a finish key (the Return glyph) that ends dictation and keeps the text. The mic itself stays a mic, lit as an accent-tinted rounded square. Clicking it again still stops. Before this change, the mic turned into a small red level meter and there was no placeholder or finish control.
Mechanism (webview only; Chief's native composer is another PR):
dictation.tskeeps the level history at 11 samples for the wave. It also keeps a page-wide "starting or listening" flag (useDictationListening), fed by the samedeliverDictationbridge, and addsDictation.finish()→dictation.stop(the host's stop keeps the words; Esc'sdictation.cancelstill drops them).DictationListening.tsxis new:DictationWave(bars whose--levelsets their height, a sine taper so the middle rises most, three resting dots each end) andDictationFinishButton(disabled while finalizing).DictationMicrenders wave, finish key and mic inside the sameHideableChrome/ fit slot. So the hidden-mic setting hides all three, and the narrow-row rule that keeps a pressed mic in the row keeps them too.DictationLevelMeter.tsxis gone.Composer.tsx(+5 lines) andNewTabScreen.tsxswap the placeholder fordictation.listeningwhile the flag is on and mark the field (is-dictating/data-dictation-listening) for the italic.dictation.css(new): the lit mic uses--cmux-accent, which falls back to--agent-accentand then the text color. No hard-coded blue; it's neutral in a theme without an accent. The wave's height transition is insideprefers-reduced-motion: no-preference, and the pane'sdata-agent-motion="off"stops it, so with motion off each level applies at once. The red listening rules instyles.css/composerStates.cssare removed, and the two hover/focus pill exclusions incomposerLocation.cssnow also coverstarting.AgentPaneDictation.payload), anduseDictationsplices each one. A test now checks that partials land before the session ends; no fix was needed.dictation.listeninganddictation.finishare in all 21 locales of the agent pane catalog: English translated, the rest machine translations markedneeds_review.Kept as before:
agentPane.showDictationhide/show, Esc cancel, the Toggle Dictation shortcut and hold-to-talk (native), andaria-label/aria-pressed/aria-busyon the mic.Gallery:
agent-pane.dictation(component) gainsstarting,finish, and a realisticlisteninglevel history. The newagent-pane.composer-dictationdrives the chat's real composer throughcmuxAcpmuxBridge.dictationwith these variants:idle,listening-empty,listening-wordsandfinalizing. That entry is in its own file, away fromcomposer.gallery.ts, which #22667 is editing.Risk: normal (webview UI, no protocol or native change).
Changelog
Changed: Dictation in the agent composer looks like Claude's: "Listening…" in the empty prompt, a live waveform, a finish key that keeps your words, and a lit mic.
Test
webviews/test/new-tab-dictation.test.tsx, 3 new tests: the "Listening…" placeholder shows only while waiting with no words, and partial words stream in live; the mic is pressed and lit beside the wave and finish key, and idle shows the mic alone; the finish key callsdictation.stop(never cancel) and the words stay.DictationButton.test.tsx: the mic keeps its glyph while listening; the finish key callsfinish()and is disabled while finalizing.cmux-ci run --class isolated --script scripts/ci/run-webviews-tests.sh --ref <sha>(results below).Observed / Not run
Fleet,
scripts/ci/run-webviews-tests.sh(whole webviews suite, light class): red 1f55ac4 (step 95f12af47f30af7bd9e9e850) fails the 3 new tests innew-tab-dictation.test.tsx. Green 67f86ea (step ed1107d150f2f73e803d8f41) passesnew-tab-dictation.test.tsxandDictationButton.test.tsx. The same 9 other files fail in both runs (gallery-coverage onChatHeaderInlineStatus, hover-row-sweep, stats-page, tooltip-surface, whats-new-text-selection, agent-pane-column-edges, apps-flow, composer-html-paste-edit, thread-minimap-feel), so those are base failures.The first green run (c145e8b) failed while building the bundles:
build-agent-pane-web.shdidn't ship the newdictation.css. Fixed in 67f86ea, which adds it after the composer sheets.Locally:
bunx vp check --no-fmt(lint + types: 0 errors),vp fmton the changed files,prepush-gate.py(no new violations).scripts/web-lint.shfails only on a basereact-hooks/exhaustive-depswarning atComposer.tsx:461, outside this diff, so I pushed withCMUX_WEB_LINT_SKIP_REASON.Not run: no local build or browser; screenshots come from the gallery advisory run. Not checked in the real app: the italic placeholder, the accent tint per theme, the wave's motion, and the narrow-row fit with the wave present.
Agent session: cosmic-gray
🤖 Generated with Claude Code