From ea5352677d33084d03a7e225eb1948f09d3b1d57 Mon Sep 17 00:00:00 2001 From: Christo Todorov Date: Fri, 4 Sep 2026 16:54:11 -0400 Subject: [PATCH 1/3] feat(composer): choose whether Enter queues or steers while a turn runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enter always queued behind the running turn, and steering meant finding the queued message and clicking Send now. Which of those is the common case depends on how you work, so it is now a setting: Settings β†’ General β†’ Enter While Running. ⌘/Ctrl+Enter always does the other one, so neither action becomes unreachable whichever way the default is set. Same rule for a modified click on the send button. `message.enqueue` gained an optional `steer` flag rather than the client chaining enqueue β†’ steer: between those two the turn can end and drain the queue, leaving the steer with nothing to find. 🌸 Shipped with Kanna β€” https://kanna.sh Co-Authored-By: Kanna Kanna-Agent: claude/opus[1m] --- src/client/app/settings/GeneralSection.tsx | 24 +++++++++- src/client/app/settings/registry.ts | 6 +++ src/client/app/useSendMessage.ts | 5 ++- src/client/components/chat-ui/ChatInput.tsx | 20 ++++++--- src/server/app-settings.test.ts | 21 +++++++++ src/server/app-settings.ts | 12 +++++ src/server/ws-router.test.ts | 49 +++++++++++++++++++++ src/server/ws-router.ts | 7 +++ src/shared/protocol.ts | 7 +++ src/shared/submit-mode.test.ts | 16 +++++++ src/shared/submit-mode.ts | 13 ++++++ src/shared/types.ts | 9 ++++ 12 files changed, 181 insertions(+), 8 deletions(-) create mode 100644 src/shared/submit-mode.test.ts create mode 100644 src/shared/submit-mode.ts diff --git a/src/client/app/settings/GeneralSection.tsx b/src/client/app/settings/GeneralSection.tsx index 3ed9e8bb3..a226e048d 100644 --- a/src/client/app/settings/GeneralSection.tsx +++ b/src/client/app/settings/GeneralSection.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react" import { Monitor, Moon, Sun } from "lucide-react" import { ANALYTICS_STATIC_EVENT_NAMES, ANALYTICS_STATIC_PROPERTY_NAMES } from "../../../shared/analytics" import type { EditorPreset } from "../../../shared/protocol" -import { DEFAULT_NEW_PROJECTS_DIRECTORY } from "../../../shared/types" +import { DEFAULT_NEW_PROJECTS_DIRECTORY, type SubmitWhileRunning } from "../../../shared/types" import { EDITOR_OPTIONS, EditorIcon } from "../../components/editor-icons" import { Button } from "../../components/ui/button" import { Dialog, DialogBody, DialogContent, DialogFooter, DialogTitle } from "../../components/ui/dialog" @@ -86,6 +86,7 @@ export function GeneralSection({ const [editorCommandDraft, setEditorCommandDraft] = useState(editorCommandTemplate) const newProjectsDirectory = appSettings?.newProjectsDirectory ?? DEFAULT_NEW_PROJECTS_DIRECTORY const [newProjectsDirectoryDraft, setNewProjectsDirectoryDraft] = useState(newProjectsDirectory) + const submitWhileRunning = appSettings?.submitWhileRunning ?? "queue" const transcriptWindow = appSettings?.transcript?.windowAssistantMessages ?? DEFAULT_TRANSCRIPT_WINDOW_ASSISTANT_MESSAGES const [transcriptWindowDraft, setTranscriptWindowDraft] = useState(String(transcriptWindow)) const [appSettingsError, setAppSettingsError] = useState(null) @@ -320,6 +321,27 @@ export function GeneralSection({ + + + +