fix(next): Cmd-Return steers in agent chats on the first press
Summary
In cmux next, Cmd-Return in an agent chat did not steer the running turn. It showed "this workspace has no todo items" instead.
The cause: toggleChecklistItemComplete has a default of Cmd-Return. That default was added with workspace checklists in a7a60a35dbb84. It applied everywhere except a terminal and the code editor, so the native key router took Cmd-Return before the composer's keyDown (webviews/src/agent-session/acpmux/Composer.tsx, commandReturn && steerable) saw it. The toggle then found no current item and refused.
The fix adds KeyBindingDefaults.yieldsToWebContent and notWebContent, next to the existing yieldsToTerminal and yieldsToCodeEditor. Where surfaceKind is agent (agent chat, including the agent new-tab page) or page (a browser page), the toggle's default binding steps aside and the key goes to the page. The Todo page and the sidebar checklist keep Cmd-Return. A user's own binding keeps its own when.
schemas/defaults/cmux-next.jsonis regenerated withdefaults_guard.py snapshot(newsteps-aside.yieldsToWebContent).- The
toggleChecklistItemCompleteentry indocs/configuration.mdnow says where the default steps aside.
Second fix: a steer shows as sent from the first press
Takes back #20391: the steer label made the first Cmd-Return look like it had not sent (https://github.com/manaflow-ai/cmux/pull/20391). It removes that PR's "Steering · The agent reads it when its current step ends" label under a steer the agent has not read yet. With it, the first Cmd-Return looked like it had only entered a steer mode, so people pressed again. "Steered · the agent read it" (the read confirmation that PR added) and "Sent now · stopped the turn" stay.
Evidence, from the dogfood chat on tag 22616-cmd-return-steer-fix (acpmux event log):
- The first Cmd-Return's steer was written to Claude Code 0.2 s after the press.
- Claude Code answered
steered2.2 s later, at the end of its current step. - Delivery was already immediate; only the label made it look like it was not.
Change:
SteerMarkdraws nothing for awaitingsteer.- The dead
[data-steer="waiting"]CSS rule is removed, and the gallery note is updated. steer.waitingandsteer.waitingDetailstay in the catalog, unused.
Tests:
webviews/test/agent-pane-queue-steer.test.ts: a steer has no mark while the reply it went into streams, then reads "Steered" once the agent's next message starts. A second steer in the same step leaves both unread until then.
Changelog
Fixed: Cmd-Return in an agent chat steers the running turn again, instead of refusing with "this workspace has no todo items", and the steer shows as sent from the first press.
Testing
Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/ChecklistCommandReturnKeysTests.swift sends Cmd-Return through KeyRouter.decide, the dispatcher's real decision path:
- agent chat →
deliver - browser page →
deliver - Todo page →
toggleChecklistItemComplete
Command: cmux-ci run --class light --script scripts/ci/run-swift-testing-suites.sh --arg=Packages/macOS/CmuxNext --ref <sha> (Xcode 26.6, AWS Macs).
- Red, at 24b85cb7daa8 (test only), step e6aef2f3f7641ecb040d3eee:
theAgentComposerGetsCommandReturnandaWebPageGetsCommandReturnfail (Expectation failed: ... == "deliver").theTodoPageStillTogglespasses. - Green, at 39f222797b58 (head), 4 shards: cbbde3b6a542eaaedce7bd1c, 81f2eff77de6ab3068f0a236, 8349c93bed278e82d452ed5d, 6c93f574c0bb07541677b39e.
ChecklistCommandReturnKeysTestspasses.
Observed / Not run
-
Merged
feat-cmux-nextagain at 69683eb899ab. Base now shows no steer line under another agent's message, so this PR's incoming-card height andagent-pane-suggested-taskschanges were dropped in favor of base. -
Observed: the red and green results above.
-
Observed: the same 17 other suites fail at both the red base and the head; this PR does not cause them.
-
Observed: 7 suites failed only in the green run. They are timing and load failures on shared hosts, unrelated to key routing:
ExtensionsMenuPerformanceTests: 20 ms against a 16 ms budgetSidebarHoverCardDwellTests: manual-clock waitBranchStateResourcesTests: daemon timeoutMotionMasterSwitchSurfaceTestsMoveToNewWindowTestsGhosttyImageStorageLimitTestsVideoWallpaperTests
Four of them passed in the red run.
-
Observed:
python3 -I scripts/ci/defaults_guard.py check-freshpasses on the head. -
Not run: a tagged build with a live Cmd-Return steer in a running agent turn.
-
Merged with
feat-cmux-nextat 1946aae41d61, after https://github.com/manaflow-ai/cmux/pull/22711 landed. That PR is the general rule: a default on Return, Cmd-Return, Shift-Return, Option-Return, Esc or Up steps aside while a text field has the keyboard. It covers internal pages such as the diff viewer's comment composer, which this PR left as a follow-up. The two rules are complementary and both are kept: this PR also yields Cmd-Return on a browser page or agent chat when no native text field is focused. A Chromium page's form field does not settextInputFocus, so only this PR'spagerule hands it Cmd-Return. The only conflict was the adjacent declarations inKeyBindingDefaults.swift.
Review
A correctness review subagent returned FIX for one finding: the defaults snapshot was stale. That is fixed in 39f222797b58. Its other findings confirmed:
- No other Cmd-Return binding wins in an agent or browser page.
- The Quick Composer is a separate panel and was never affected.
- The Todo page keeps the toggle.
This PR changes a defaults snapshot, so it needs an approval from a defaults-call owner (.github/defaults-call-owners.json).
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Cmd-Return in an agent chat steers the running turn again instead of hitting the checklist toggle and refusing with "this workspace has no todo items", and a steer now shows as any sent prompt until the agent reads it.
The checklist toggle's default Cmd-Return binding applied everywhere except terminals and the code editor, so it won in agent chats and browser pages before the page's own handler saw it. Its default now also steps aside when the surface kind is agent or page; the Todo page keeps Cmd-Return, and user-defined bindings are untouched. A steer the agent has not read renders as any sent prompt, with no status label; once read it shows "Steered · the agent read it".
The branch also carries in merged CI fixes: the web-bundles job no longer runs self-tests that could skip the Mac tiers, the fast-tier cache seed runs once per pool (hosted and Blacksmith) in its own lane, and a newer merge no longer replaces a pending media tour run.
Migration
- The defaults snapshot in
schemas/defaults/cmux-next.jsonaddssteps-aside.yieldsToWebContent, so this needs approval from a defaults-call owner.