diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx index f42ba15ec0..d3cbdbd436 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx @@ -63,6 +63,7 @@ function init() { useKeyboard((evt) => { if (suspended()) return if (dialog.stack.length > 0) return + if (evt.defaultPrevented) return for (const option of entries()) { if (!isEnabled(option)) continue if (option.keybind && keybind.match(option.keybind, evt)) { @@ -96,7 +97,7 @@ function init() { }) }, keybinds(enabled: boolean) { - setSuspendCount((count) => count + (enabled ? -1 : 1)) + setSuspendCount((count) => Math.max(0, count + (enabled ? -1 : 1))) }, suspended, show() { diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx index e0b5002b61..efe7bcab84 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx @@ -1,5 +1,5 @@ import { createStore } from "solid-js/store" -import { createMemo, For, Match, Show, Switch } from "solid-js" +import { createMemo, For, Match, onCleanup, onMount, Show, Switch } from "solid-js" import { Portal, useKeyboard, useRenderer, useTerminalDimensions, type JSX } from "@opentui/solid" import type { TextareaRenderable } from "@opentui/core" import { useKeybind } from "../../context/keybind" @@ -17,6 +17,7 @@ import { Global } from "@/global" import { useDialog } from "../../ui/dialog" import { getScrollAcceleration } from "../../util/scroll" import { useTuiConfig } from "../../context/tui-config" +import { useCommandDialog } from "../../component/dialog-command" type PermissionStage = "permission" | "always" | "reject" @@ -132,10 +133,14 @@ function TextBody(props: { title: string; description?: string; icon?: string }) export function PermissionPrompt(props: { request: PermissionRequest }) { const sdk = useSDK() const sync = useSync() + const command = useCommandDialog() const [store, setStore] = createStore({ stage: "permission" as PermissionStage, }) + onMount(() => command.keybinds(false)) + onCleanup(() => command.keybinds(true)) + const session = createMemo(() => sync.data.session.find((s) => s.id === props.request.sessionID)) const input = createMemo(() => { diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx index 65989b9f35..7bafdf8d4b 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx @@ -1,5 +1,5 @@ import { createStore } from "solid-js/store" -import { createMemo, createSignal, For, Show } from "solid-js" +import { createMemo, createSignal, For, onCleanup, onMount, Show } from "solid-js" import { useKeyboard } from "@opentui/solid" import type { TextareaRenderable } from "@opentui/core" import { useKeybind } from "../../context/keybind" @@ -9,12 +9,17 @@ import { useSDK } from "../../context/sdk" import { SplitBorder } from "../../component/border" import { useTextareaKeybindings } from "../../component/textarea-keybindings" import { useDialog } from "../../ui/dialog" +import { useCommandDialog } from "../../component/dialog-command" export function QuestionPrompt(props: { request: QuestionRequest }) { const sdk = useSDK() const { theme } = useTheme() const keybind = useKeybind() const bindings = useTextareaKeybindings() + const command = useCommandDialog() + + onMount(() => command.keybinds(false)) + onCleanup(() => command.keybinds(true)) const questions = createMemo(() => props.request.questions) const single = createMemo(() => questions().length === 1 && questions()[0]?.multiple !== true)