Repository navigation
Conversation
| expiredTerminalContextCount === 0 && | ||
| submissionIntent !== "background" && | ||
| !directAnnotation && | ||
| queuedRunsControlRef.current?.steerNext(false) |
There was a problem hiding this comment.
🔴 Opposite-action shortcut steers queued messages
With an empty composer, Cmd/Ctrl+Enter steers a queued message even when dispatchMode selects Queue. The shortcut's opposite-action mode is ignored, so the message enters the running turn unexpectedly.
Learn more
The composer passes the resolved Queue/Steer action as dispatchMode to onSend. With Follow-up behavior set to Steer, Cmd/Ctrl+Enter selects Queue. The new empty-input branch ignores that choice and promotes a saved message instead. The shortcut therefore changes an existing message's delivery even though the user chose Queue and entered no new message.
Example: Set Follow-up behavior to Steer, queue a message with Cmd/Ctrl+Enter while an agent runs, then press Cmd/Ctrl+Enter again with an empty composer. The queued message is steered into the running turn; the selected Queue action cannot perform that promotion.
Recommended fix: Gate empty-composer promotion on the ordinary unmodified Enter submission, not merely on submissionIntent !== "background". Pass the keyboard action or an explicit promotion intent through ChatComposer to onSend, and keep alternate actions from promoting queued runs.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Fixed in 0641931. The empty-composer steer now requires submissionIntent === "foreground" (plain Enter), so Cmd/Ctrl+Enter, which does the opposite of the default action, never promotes a queued run.
| expiredTerminalContextCount === 0 && | ||
| submissionIntent !== "background" && | ||
| !directAnnotation && | ||
| queuedRunsControlRef.current?.steerNext(false) |
There was a problem hiding this comment.
🟡 Second Enter misses pending queued message
If Enter is pressed again before a queued message reaches the server projection, steerNext sees no saved run. The second Enter does nothing, so the two-Enter flow fails under normal network latency.
Learn more
A queued message first appears as an optimistic row. QueuedRunsControl marks that row pending without a run ID, while steerNext reads only acknowledged runs from the server projection. An Enter received during the gap cannot promote the newly queued message. The delay is particularly visible on remote connections.
Example: Queue the first follow-up and press Enter again before the server response arrives. The queue displays a pending row, but queued[0] is absent and no steer occurs; the user must press Enter a third time after acknowledgment.
Recommended fix: Record promotion intent for a pending queued message and apply it once its server run ID becomes available, or defer the second action until the initial queue command resolves. Ensure retries and failures clear that intent without promoting a different queued message.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Leaving this as is. While the queue send is in flight, sendInFlightRef already drops any second send (ChatView.tsx onSend guard). The only gap left is the short time between the RPC resolving and the projection update arriving. A second Enter in that gap does nothing, and pressing Enter again steers. Deferring a steer until the run appears would add state that has to be cleared on failure and on retry, just to avoid a harmless no-op.
| // Sending an empty composer steers the oldest queued message, so Enter | ||
| // queues a follow-up and Enter again sends it into the running turn. | ||
| if ( | ||
| expiredTerminalContextCount === 0 && | ||
| submissionIntent !== "background" && | ||
| !directAnnotation && | ||
| queuedRunsControlRef.current?.steerNext(false) |
There was a problem hiding this comment.
🔍 Enter interaction lacks verification evidence
The PR leaves the new Enter flow unchecked. Contribution guidance calls for UI evidence and interaction recordings; a focused check would establish the desktop and web behavior.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
Manual check in the web dev build (Codex, Follow-up behavior = Queue, during a running
Not checked: Enter while editing a queued message. |
Queued messages could only be steered into the running turn with the Steer button or
Cmd/Ctrl+Shift+Enter. Pressing Enter in an empty composer did nothing, so the Zed-style "Enter queues, Enter again sends" flow from #1 no longer worked once the queue moved to the server.Fix
ChatViewonSend: when the composer has nothing to send, Enter now calls the queue control's existingsteerNext, the same path asthread.steerQueuedMessage. It promotes the oldest queued run into a steer of the active run.docs/user/composer.mddocuments it.Web and desktop only. Narrow web screens and the mobile app don't send on Enter. Agents already steer through
t3_queue_promote_to_steer.No screenshots: the only visual change is tooltip text.
Test plan
vp linton touched files: no new warningsvp fmt --checkcleantsc --noEmit(apps/web) cleanvp test runonQueuedRunsControl.test.tsxandkeybindings.test.ts: 145 passedBuilt with Claude Opus 5.5 (Claude Code harness in T3 Code).
The PR appears safe to merge; no new actionable issue remains.
What we checked:
ChatViewshows the warning first. It callssteerNextonly in the other branch.Summary
This PR lets Enter in an empty desktop composer steer the oldest queued message.
Reviews (3) · Last reviewed commit: "refactor(web): simplify empty-composer q..." · Reviewed by Greptile