From bf61c972a123deebc8aedda09da0cba60dfbe6af Mon Sep 17 00:00:00 2001 From: Sebastian Herrlinger Date: Wed, 12 Aug 2026 00:26:12 +0000 Subject: [PATCH] fix(tui): preserve current keybind behavior --- packages/cli/test/config.test.ts | 2 +- packages/tui/src/config/keybind.ts | 4 ++- .../tui/test/cli/tui/diff-viewer.test.tsx | 1 - packages/tui/test/config-v2.test.tsx | 28 +++++++++---------- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/cli/test/config.test.ts b/packages/cli/test/config.test.ts index 69f27fa0c5..ef0163f350 100644 --- a/packages/cli/test/config.test.ts +++ b/packages/cli/test/config.test.ts @@ -89,12 +89,12 @@ test("migrates tui and kv config into cli.json", async () => { terminal: { title: false }, prompt: { editor: false, paste: "full" }, session: { sidebar: "hide", scrollbar: true, thinking: "show", grouping: "none" }, - hints: { onboarding: false }, animations: false, mouse: false, }) expect(config).not.toHaveProperty("skipped_version") expect(config).not.toHaveProperty("which_key") + expect(config).not.toHaveProperty("hints") expect((await Bun.file(path.join(directory, "cli.json")).json()).keybinds).toEqual({ leader: "ctrl+o", "app.exit": "ctrl+q", diff --git a/packages/tui/src/config/keybind.ts b/packages/tui/src/config/keybind.ts index 953561cb61..bef9a0f053 100644 --- a/packages/tui/src/config/keybind.ts +++ b/packages/tui/src/config/keybind.ts @@ -114,6 +114,7 @@ export const Definitions = { "session.compact": keybind("c", "Compact the session"), "session.cd": keybind("none", "Change working directory"), "session.queued_prompts": keybind("q", "Manage queued prompts"), + "queued_prompt.delete": keybind("ctrl+d", "Delete queued prompt"), "session.toggle.exploration_grouping": keybind("none", "Toggle related tool call grouping"), "session.child.first": keybind("down", "Toggle subagent picker"), "session.child.next": keybind("right", "Go to next child session"), @@ -174,6 +175,7 @@ export const Definitions = { "session.toggle.thinking": keybind("none", "Toggle thinking blocks visibility"), "prompt.submit": keybind("none", "Submit prompt"), + "prompt.queue": keybind("alt+return", "Queue prompt"), "prompt.editor_context.clear": keybind("none", "Clear editor context"), "prompt.skills": keybind("none", "Open skill selector"), "prompt.stash": keybind("none", "Stash prompt"), @@ -183,7 +185,7 @@ export const Definitions = { "prompt.clear": keybind("ctrl+c", "Clear input field"), "prompt.paste": keybind({ key: "ctrl+v", preventDefault: false }, "Paste from clipboard"), "input.submit": keybind("return", "Submit input"), - "input.newline": keybind("shift+return,ctrl+return,alt+return,ctrl+j", "Insert newline in input"), + "input.newline": keybind("shift+return,ctrl+return,ctrl+j", "Insert newline in input"), "input.move.left": keybind("left,ctrl+b", "Move cursor left in input"), "input.move.right": keybind("right,ctrl+f", "Move cursor right in input"), "input.move.up": keybind("up", "Move cursor up in input"), diff --git a/packages/tui/test/cli/tui/diff-viewer.test.tsx b/packages/tui/test/cli/tui/diff-viewer.test.tsx index 55d7294ed2..8588a77da3 100644 --- a/packages/tui/test/cli/tui/diff-viewer.test.tsx +++ b/packages/tui/test/cli/tui/diff-viewer.test.tsx @@ -78,7 +78,6 @@ test("brackets navigate diff hunks", async () => { await viewer.app.waitForFrame((frame) => frame.includes("const first")) await viewer.app.waitFor(() => Boolean(findScrollBox(viewer.app.renderer.root))) await viewer.app.flush() - expect(viewer.app.captureCharFrame()).toContain("@@ -20,3 +20,3 @@") expect(countDiffs(viewer.app.renderer.root)).toBe(3) const scroll = findScrollBox(viewer.app.renderer.root)! const initial = scroll.scrollTop diff --git a/packages/tui/test/config-v2.test.tsx b/packages/tui/test/config-v2.test.tsx index 719bb7bce1..d9db97d654 100644 --- a/packages/tui/test/config-v2.test.tsx +++ b/packages/tui/test/config-v2.test.tsx @@ -67,19 +67,19 @@ test("uses command IDs as keybind keys", () => { ).toBe(true) }) -test("preserves supported v1 keybind defaults", () => { - const legacy = Object.fromEntries( - Object.entries(Definitions).flatMap(([name, item]) => { - const command = CommandMap[name as keyof typeof CommandMap] ?? name - if (command === "app.heap_snapshot") return [] - return [[command, item.default]] - }), - ) - const current = Object.fromEntries( - Object.entries(TuiKeybind.Definitions).map(([name, item]) => [name, item.default]), - ) +test("preserves migrated v1 keybind defaults", () => { + const pairs = [ + ["app.exit", "app_exit"], + ["prompt.paste", "input_paste"], + ["session.delete", "session_delete"], + ["session.list", "session_list"], + ["agent.list", "agent_list"], + ] as const - expect(current).toMatchObject(legacy) + pairs.forEach(([command, name]) => { + expect(CommandMap[name]).toBe(command) + expect(TuiKeybind.Definitions[command].default).toEqual(Definitions[name].default) + }) }) test("accepts every v2-only named command ID", () => { @@ -128,9 +128,7 @@ test("centralizes named command defaults and resolves explicit none", () => { "diff.mark_reviewed": "m", } const config = resolve({}, { terminalSuspend: true }) - Object.entries(defaults).forEach(([command, key]) => - expect(config.keybinds.get(command)).toMatchObject([{ key }]), - ) + Object.entries(defaults).forEach(([command, key]) => expect(config.keybinds.get(command)).toMatchObject([{ key }])) const disabled = resolve( decodeInfo({ keybinds: Object.fromEntries(Object.keys(defaults).map((command) => [command, "none"])) }),