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 de2a75dc46..6d8727bfd2 100644
--- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
@@ -161,6 +161,7 @@ export function Prompt(props: PromptProps) {
const { theme, syntax } = useTheme()
const kv = useKV()
const animationsEnabled = createMemo(() => kv.get("animations_enabled", true))
+ const [autoaccept, setAutoaccept] = kv.signal<"none" | "edit">("permission_auto_accept", "edit")
const list = createMemo(() => props.placeholders?.normal ?? [])
const shell = createMemo(() => props.placeholders?.shell ?? [])
const fileContextEnabled = createMemo(() => kv.get("file_context_enabled", true))
@@ -408,6 +409,15 @@ export function Prompt(props: PromptProps) {
const promptCommands = createMemo(() =>
[
+ {
+ name: "permission.auto_accept.toggle",
+ title: autoaccept() === "none" ? "Enable autoedit" : "Disable autoedit",
+ category: "Agent",
+ run: () => {
+ setAutoaccept(() => (autoaccept() === "none" ? "edit" : "none"))
+ dialog.clear()
+ },
+ },
{
title: "Clear prompt",
name: "prompt.clear",
@@ -1598,6 +1608,11 @@ export function Prompt(props: PromptProps) {
{props.right}
+
+
+ autoedit
+
+
diff --git a/packages/opencode/src/cli/cmd/tui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx
index 9f8a384f77..cad5fa2a20 100644
--- a/packages/opencode/src/cli/cmd/tui/context/sync.tsx
+++ b/packages/opencode/src/cli/cmd/tui/context/sync.tsx
@@ -27,11 +27,11 @@ 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 * as Log from "@opencode-ai/core/util/log"
import { emptyConsoleState, type ConsoleState } from "@/config/console-state"
import path from "path"
-import { useKV } from "./kv"
import { aggregateFailures } from "./aggregate-failures"
export const { use: useSync, provider: SyncProvider } = createSimpleContext({
@@ -111,6 +111,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
const project = useProject()
const sdk = useSDK()
const kv = useKV()
+ const [autoaccept] = kv.signal<"none" | "edit">("permission_auto_accept", "edit")
const fullSyncedSessions = new Set()
@@ -152,6 +153,13 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
case "permission.asked": {
const request = event.properties
+ if (autoaccept() === "edit" && request.permission === "edit") {
+ sdk.client.permission.reply({
+ reply: "once",
+ requestID: request.id,
+ })
+ break
+ }
const requests = store.permission[request.sessionID]
if (!requests) {
setStore("permission", request.sessionID, [request])
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
index b5e8e10283..d29a167950 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -650,6 +650,8 @@ export function Session() {
{
title: sidebarVisible() ? "Hide sidebar" : "Show sidebar",
value: "session.sidebar.toggle",
+ search: "toggle sidebar",
+ keybind: "sidebar_toggle",
category: "Session",
run: () => {
batch(() => {
@@ -663,6 +665,8 @@ export function Session() {
{
title: conceal() ? "Disable code concealment" : "Enable code concealment",
value: "session.toggle.conceal",
+ search: "toggle code concealment",
+ keybind: "messages_toggle_conceal" as any,
category: "Session",
run: () => {
setConceal((prev) => !prev)
@@ -672,6 +676,7 @@ export function Session() {
{
title: showTimestamps() ? "Hide timestamps" : "Show timestamps",
value: "session.toggle.timestamps",
+ search: "toggle timestamps",
category: "Session",
slash: {
name: "timestamps",
@@ -685,6 +690,8 @@ export function Session() {
{
title: showThinking() ? "Hide thinking" : "Show thinking",
value: "session.toggle.thinking",
+ search: "toggle thinking",
+ keybind: "display_thinking",
category: "Session",
slash: {
name: "thinking",
@@ -698,6 +705,8 @@ export function Session() {
{
title: showDetails() ? "Hide tool details" : "Show tool details",
value: "session.toggle.actions",
+ search: "toggle tool details",
+ keybind: "tool_details",
category: "Session",
run: () => {
setShowDetails((prev) => !prev)
@@ -705,8 +714,10 @@ export function Session() {
},
},
{
- title: "Toggle session scrollbar",
+ title: showScrollbar() ? "Hide session scrollbar" : "Show session scrollbar",
value: "session.toggle.scrollbar",
+ search: "toggle session scrollbar",
+ keybind: "scrollbar_toggle",
category: "Session",
run: () => {
setShowScrollbar((prev) => !prev)
diff --git a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
index a791aebc30..b7e11a3d65 100644
--- a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
+++ b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
@@ -46,6 +46,7 @@ export interface DialogSelectOption {
title: string
value: T
description?: string
+ search?: string
footer?: JSX.Element | string
category?: string
categoryView?: JSX.Element
@@ -121,8 +122,8 @@ export function DialogSelect(props: DialogSelectProps) {
// users typically search by the item name, and not its category.
const result = fuzzysort
.go(needle, options, {
- keys: ["title", "category"],
- scoreFn: (r) => r[0].score * 2 + r[1].score,
+ keys: ["title", "category", "search"],
+ scoreFn: (r) => r[0].score * 2 + r[1].score + r[2].score,
})
.map((x) => x.obj)