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 8576dd5763..8a08c3fc13 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -74,6 +74,7 @@ export function Prompt(props: PromptProps) { const renderer = useRenderer() const { theme, syntax } = useTheme() const kv = useKV() + const [autoaccept, setAutoaccept] = kv.signal("permission_auto_accept", false) function promptModelWarning() { toast.show({ @@ -157,6 +158,16 @@ export function Prompt(props: PromptProps) { command.register(() => { return [ + { + title: "Toggle autoaccept permissions", + value: "permission.auto_accept.toggle", + keybind: "permission_auto_accept_toggle", + category: "Permission", + onSelect: (dialog) => { + setAutoaccept(!autoaccept() as any) + dialog.clear() + }, + }, { title: "Clear prompt", value: "prompt.clear", @@ -973,23 +984,30 @@ export function Prompt(props: PromptProps) { cursorColor={theme.text} syntaxStyle={syntax()} /> - - - {store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current().name)}{" "} - - - - - {local.model.parsed().model} - - {local.model.parsed().provider} - - · - - {local.model.variant.current()} + + + + {store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current().name)}{" "} + + + + + {local.model.parsed().model} - - + {local.model.parsed().provider} + + · + + {local.model.variant.current()} + + + + + + + + auto-accept + diff --git a/packages/opencode/src/cli/cmd/tui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx index eb8ed2d9bb..2ad41d3482 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sync.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sync.tsx @@ -25,6 +25,7 @@ import { createSimpleContext } from "./helper" import type { Snapshot } from "@/snapshot" import { useExit } from "./exit" import { useArgs } from "./args" +import { useKV } from "./kv" import { batch, onMount } from "solid-js" import { Log } from "@/util/log" import type { Path } from "@opencode-ai/sdk" @@ -103,6 +104,8 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ }) const sdk = useSDK() + const kv = useKV() + const [autoaccept] = kv.signal("permission_auto_accept", false) sdk.event.listen((e) => { const event = e.details @@ -127,6 +130,13 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ case "permission.asked": { const request = event.properties + if (autoaccept()) { + sdk.client.permission.reply({ + reply: "once", + requestID: request.id, + }) + break + } const requests = store.permission[request.sessionID] if (!requests) { setStore("permission", request.sessionID, [request]) @@ -423,6 +433,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ get ready() { return store.status !== "loading" }, + session: { get(sessionID: string) { const match = Binary.search(store.session, sessionID, (s) => s.id) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index a231a53007..1f6ca484ce 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -818,7 +818,12 @@ export namespace Config { command_list: z.string().optional().default("ctrl+p").describe("List available commands"), agent_list: z.string().optional().default("a").describe("List agents"), agent_cycle: z.string().optional().default("tab").describe("Next agent"), - agent_cycle_reverse: z.string().optional().default("shift+tab").describe("Previous agent"), + agent_cycle_reverse: z.string().optional().default("none").describe("Previous agent"), + permission_auto_accept_toggle: z + .string() + .optional() + .default("shift+tab") + .describe("Toggle auto-accept mode for permissions"), variant_cycle: z.string().optional().default("ctrl+t").describe("Cycle model variants"), input_clear: z.string().optional().default("ctrl+c").describe("Clear input field"), input_paste: z.string().optional().default("ctrl+v").describe("Paste from clipboard"),