From 9fff6e2b4f7ffb6e2ce06455df6e75e789184448 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Thu, 13 Aug 2026 14:12:39 -0400 Subject: [PATCH] fix(tui): prioritize composer keybinds (#42384) --- packages/tui/src/routes/session/composer/index.tsx | 1 + .../tui/src/routes/session/composer/shell-tab.tsx | 14 +------------- .../src/routes/session/composer/subagents-tab.tsx | 1 + packages/tui/test/cli/tui/composer-keymap.test.tsx | 10 ++++++---- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/packages/tui/src/routes/session/composer/index.tsx b/packages/tui/src/routes/session/composer/index.tsx index 08d3d22473..04fbf59330 100644 --- a/packages/tui/src/routes/session/composer/index.tsx +++ b/packages/tui/src/routes/session/composer/index.tsx @@ -94,6 +94,7 @@ export function Composer(props: ComposerProps) { Keymap.createLayer(() => ({ mode: "composer", enabled: () => props.open, + priority: 1, commands: [ { bind: "left", title: "Previous tab", group: "Composer", run: () => switchTab(-1) }, { bind: "right", title: "Next tab", group: "Composer", run: () => switchTab(1) }, diff --git a/packages/tui/src/routes/session/composer/shell-tab.tsx b/packages/tui/src/routes/session/composer/shell-tab.tsx index b4edfd6d10..81a8acd088 100644 --- a/packages/tui/src/routes/session/composer/shell-tab.tsx +++ b/packages/tui/src/routes/session/composer/shell-tab.tsx @@ -23,19 +23,6 @@ export function ShellTab(props: { sessionID: string }) { const selectedEntry = createMemo(() => entries()[store.selected]) - const keymap = Keymap.use() - createEffect(() => { - if (!composer.active("shell")) return - const cleanup = keymap.intercept("key", ({ event, consume }) => { - if (event.name !== "d" || !event.ctrl) return - if (!shortcuts.list("composer.shell.kill").includes("ctrl+d")) return - if (!selectedEntry()) return - consume() - keymap.dispatch("composer.shell.kill") - }) - onCleanup(cleanup) - }) - createEffect(() => { if (store.selected >= entries().length) setStore("selected", Math.max(0, entries().length - 1)) }) @@ -63,6 +50,7 @@ export function ShellTab(props: { sessionID: string }) { Keymap.createLayer(() => ({ mode: "composer", enabled: () => composer.active("shell"), + priority: 1, commands: [ { id: "composer.shell.up", diff --git a/packages/tui/src/routes/session/composer/subagents-tab.tsx b/packages/tui/src/routes/session/composer/subagents-tab.tsx index 964003e494..0d35ea5e3f 100644 --- a/packages/tui/src/routes/session/composer/subagents-tab.tsx +++ b/packages/tui/src/routes/session/composer/subagents-tab.tsx @@ -164,6 +164,7 @@ export function SubagentsTab(props: { sessionID: string }) { Keymap.createLayer(() => ({ mode: "composer", enabled: () => composer.active("subagents"), + priority: 1, commands: [ { id: "composer.subagent.up", diff --git a/packages/tui/test/cli/tui/composer-keymap.test.tsx b/packages/tui/test/cli/tui/composer-keymap.test.tsx index 534db4d70f..0e00ef2ba6 100644 --- a/packages/tui/test/cli/tui/composer-keymap.test.tsx +++ b/packages/tui/test/cli/tui/composer-keymap.test.tsx @@ -95,7 +95,6 @@ async function renderComposer( - @@ -107,6 +106,7 @@ async function renderComposer( + @@ -173,11 +173,13 @@ test("disabled shell bindings have no component fallbacks", async () => { } }) -test("shell kill binding overrides app exit", async () => { - const composer = await renderComposer("shell", {}, true) +test("configured composer bindings work with a focused textarea", async () => { + const composer = await renderComposer("subagents", { "composer.shell.kill": "ctrl+u" }, true) try { + composer.app.mockInput.pressArrow("right") + await composer.app.renderOnce() expect(composer.app.captureCharFrame()).toContain("bun test") - composer.app.mockInput.pressKey("d", { ctrl: true }) + composer.app.mockInput.pressKey("u", { ctrl: true }) await wait(() => composer.removed.length === 1) expect(composer.removed).toEqual(["sh-a"]) } finally {