From 97cdf11c891ddda0207c4396b7c56401c832d7c3 Mon Sep 17 00:00:00 2001 From: anandlo <157297269+anandlo@users.noreply.github.com> Date: Sun, 16 Aug 2026 16:28:51 -0400 Subject: [PATCH] fix(tui): release keybind suspension when autocomplete unmounts command.keybinds() gates all leader (ctrl+x) chords on suspendCount. Autocomplete show()/hide() increment/decrement it but had no idempotency guard, and the component had no unmount cleanup: if the prompt unmounts while the autocomplete is visible (session switch, permission prompt, agent switch), hide() never runs and suspendCount stays above 0, leaving every command keybind dead until restart. Add idempotency guards to show()/hide() and an onCleanup that releases the suspension on unmount. --- .../src/cli/cmd/tui/component/prompt/autocomplete.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx index cb27edc81..9b30b0024 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx @@ -531,7 +531,7 @@ export function Autocomplete(props: { } function show(mode: "@" | "$" | "/") { - command.keybinds(false) + if (!store.visible) command.keybinds(false) setStore({ visible: mode, index: props.input().cursorOffset, @@ -539,10 +539,17 @@ export function Autocomplete(props: { } function hide() { - command.keybinds(true) + if (store.visible) command.keybinds(true) setStore("visible", false) } + // Clean up on unmount: if autocomplete was visible when the component is + // removed (e.g. session switch), decrement the suspend counter so keybinds + // don't stay permanently blocked. + onCleanup(() => { + if (store.visible) command.keybinds(true) + }) + function clearTriggerRange() { if (store.visible !== "/") return const input = props.input()