From 859cf30ffff2db19ef2d3fa7d05353e08cf3e4c0 Mon Sep 17 00:00:00 2001 From: ranxianglei Date: Sun, 17 May 2026 01:51:47 +0800 Subject: [PATCH] fix(tui): allow session interrupt (ESC) when dialog is open When a permission dialog or other dialog is open, all keybindings including session_interrupt were disabled by the command palette matcher. This trapped users in an infinite dialog loop: dismiss dialog -> model retries tool -> new dialog opens. Split session.interrupt into its own useBindings call without the dialog guard, and remove the input.focused check in the handler so ESC works even when the input is blurred by a dialog. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../src/cli/cmd/tui/component/prompt/index.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index c80daf9cff5f..709b121c168e 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -471,7 +471,6 @@ export function Prompt(props: PromptProps) { enabled: status().type !== "idle", run: () => { if (auto()?.visible) return - if (!input.focused) return // TODO: this should be its own command if (store.mode === "shell") { setStore("mode", "normal") @@ -628,6 +627,14 @@ export function Prompt(props: PromptProps) { commands: promptCommands(), })) + // session.interrupt must always be reachable, even when a dialog is open. + // Without this, pressing ESC when a permission prompt is showing would only + // dismiss the dialog — the model then retries the tool and re-opens it, + // trapping the user in an infinite dialog loop. + useBindings(() => ({ + bindings: tuiConfig.keybinds.gather("prompt.interrupt", ["session.interrupt"]), + })) + useBindings(() => ({ enabled: command.matcher, bindings: tuiConfig.keybinds.gather("prompt.palette", [ @@ -637,7 +644,6 @@ export function Prompt(props: PromptProps) { "prompt.stash", "prompt.stash.pop", "prompt.stash.list", - "session.interrupt", "workspace.set", ]), }))