fix(tui): restore composer shell kill shortcut (#42366)

This commit is contained in:
Kit Langton
2026-08-13 13:40:47 -04:00
committed by GitHub
parent fb8b4c4ce6
commit 2cf20e660e
2 changed files with 46 additions and 2 deletions
@@ -23,6 +23,19 @@ 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))
})
@@ -23,7 +23,11 @@ const sessions = {
const shells = [shell("sh-a", "bun test"), shell("sh-b", "bun dev")]
async function renderComposer(defaultTab: "subagents" | "shell", keybinds: Partial<TuiKeybind.Keybinds>) {
async function renderComposer(
defaultTab: "subagents" | "shell",
keybinds: Partial<TuiKeybind.Keybinds>,
focusedTextarea = false,
) {
const events = createEventStream()
const interrupted: string[] = []
const removed: string[] = []
@@ -69,7 +73,21 @@ async function renderComposer(defaultTab: "subagents" | "shell", keybinds: Parti
.then(() => wait(() => data.session.status("child-a") === "running"))
.then(() => ready.resolve(), ready.reject)
})
return <Composer sessionID="parent" open={true} defaultTab={defaultTab} onClose={() => closed++} />
return (
<>
{focusedTextarea && <textarea focused={true} initialValue="draft" />}
<Composer sessionID="parent" open={true} defaultTab={defaultTab} onClose={() => closed++} />
</>
)
}
function AppExit() {
Keymap.createLayer(() => ({
mode: "global",
commands: [{ id: "app.exit", title: "Exit", group: "System", run: () => {} }],
}))
Keymap.createLayer(() => ({ bindings: ["app.exit"] }))
return null
}
const app = await testRender(
@@ -77,6 +95,7 @@ async function renderComposer(defaultTab: "subagents" | "shell", keybinds: Parti
<TestTuiContexts directory={directory}>
<ConfigProvider config={createTuiResolvedConfig({ keybinds })}>
<Keymap.Provider>
<AppExit />
<ClientProvider api={createApi(calls.fetch)}>
<DataProvider>
<LocationProvider>
@@ -154,6 +173,18 @@ test("disabled shell bindings have no component fallbacks", async () => {
}
})
test("shell kill binding overrides app exit", async () => {
const composer = await renderComposer("shell", {}, true)
try {
expect(composer.app.captureCharFrame()).toContain("bun test")
composer.app.mockInput.pressKey("d", { ctrl: true })
await wait(() => composer.removed.length === 1)
expect(composer.removed).toEqual(["sh-a"])
} finally {
composer.app.renderer.destroy()
}
})
function session(id: string, title: string, parentID?: string) {
return {
id,