Skip to content

Commit 02b1d77

Browse files
Apply PR #12633: feat(tui): add auto-accept mode for permission requests
2 parents 337021e + 5792a80 commit 02b1d77

4 files changed

Lines changed: 41 additions & 4 deletions

File tree

packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ export function Prompt(props: PromptProps) {
195195
const [cursorVersion, setCursorVersion] = createSignal(0)
196196
const currentProviderLabel = createMemo(() => local.model.parsed().provider)
197197
const hasRightContent = createMemo(() => Boolean(props.right))
198+
const [autoaccept, setAutoaccept] = kv.signal<"none" | "edit">("permission_auto_accept", "edit")
198199

199200
function promptModelWarning() {
200201
toast.show({
@@ -316,6 +317,17 @@ export function Prompt(props: PromptProps) {
316317

317318
const promptCommands = createMemo(() =>
318319
[
320+
{
321+
title: autoaccept() === "none" ? "Enable autoedit" : "Disable autoedit",
322+
name: "permission.auto_accept.toggle",
323+
search: "toggle permissions",
324+
keybind: "permission_auto_accept_toggle",
325+
category: "Agent",
326+
run: () => {
327+
setAutoaccept(() => (autoaccept() === "none" ? "edit" : "none"))
328+
dialog.clear()
329+
},
330+
},
319331
{
320332
title: "Clear prompt",
321333
name: "prompt.clear",
@@ -1487,6 +1499,11 @@ export function Prompt(props: PromptProps) {
14871499
{props.right}
14881500
</box>
14891501
</Show>
1502+
<Show when={autoaccept() === "edit"}>
1503+
<text>
1504+
<span style={{ fg: theme.warning }}>autoedit</span>
1505+
</text>
1506+
</Show>
14901507
</box>
14911508
</box>
14921509
</box>

packages/opencode/src/cli/cmd/tui/context/sync.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ import { createSimpleContext } from "./helper"
2727
import type { Snapshot } from "@/snapshot"
2828
import { useExit } from "./exit"
2929
import { useArgs } from "./args"
30+
import { useKV } from "./kv"
3031
import { batch, onMount } from "solid-js"
3132
import * as Log from "@opencode-ai/core/util/log"
3233
import { emptyConsoleState, type ConsoleState } from "@opencode-ai/core/v1/config/console-state"
3334
import path from "path"
34-
import { useKV } from "./kv"
3535
import { aggregateFailures } from "./aggregate-failures"
3636

3737
export const { use: useSync, provider: SyncProvider } = createSimpleContext({
@@ -111,6 +111,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
111111
const project = useProject()
112112
const sdk = useSDK()
113113
const kv = useKV()
114+
const [autoaccept] = kv.signal<"none" | "edit">("permission_auto_accept", "edit")
114115

115116
const fullSyncedSessions = new Set<string>()
116117
const syncingSessions = new Map<string, Promise<void>>()
@@ -160,6 +161,13 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
160161

161162
case "permission.asked": {
162163
const request = event.properties
164+
if (autoaccept() === "edit" && request.permission === "edit") {
165+
sdk.client.permission.reply({
166+
reply: "once",
167+
requestID: request.id,
168+
})
169+
break
170+
}
163171
const requests = store.permission[request.sessionID]
164172
if (!requests) {
165173
setStore("permission", request.sessionID, [request])

packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ export function Session() {
681681
{
682682
title: sidebarVisible() ? "Hide sidebar" : "Show sidebar",
683683
value: "session.sidebar.toggle",
684+
search: "toggle sidebar",
685+
keybind: "sidebar_toggle",
684686
category: "Session",
685687
run: () => {
686688
batch(() => {
@@ -694,6 +696,8 @@ export function Session() {
694696
{
695697
title: conceal() ? "Disable code concealment" : "Enable code concealment",
696698
value: "session.toggle.conceal",
699+
search: "toggle code concealment",
700+
keybind: "messages_toggle_conceal" as any,
697701
category: "Session",
698702
run: () => {
699703
setConceal((prev) => !prev)
@@ -703,6 +707,7 @@ export function Session() {
703707
{
704708
title: showTimestamps() ? "Hide timestamps" : "Show timestamps",
705709
value: "session.toggle.timestamps",
710+
search: "toggle timestamps",
706711
category: "Session",
707712
slash: {
708713
name: "timestamps",
@@ -720,6 +725,8 @@ export function Session() {
720725
return "Expand thinking"
721726
})(),
722727
value: "session.toggle.thinking",
728+
search: "toggle thinking",
729+
keybind: "display_thinking",
723730
category: "Session",
724731
slash: {
725732
name: "thinking",
@@ -733,15 +740,19 @@ export function Session() {
733740
{
734741
title: showDetails() ? "Hide tool details" : "Show tool details",
735742
value: "session.toggle.actions",
743+
search: "toggle tool details",
744+
keybind: "tool_details",
736745
category: "Session",
737746
run: () => {
738747
setShowDetails((prev) => !prev)
739748
dialog.clear()
740749
},
741750
},
742751
{
743-
title: "Toggle session scrollbar",
752+
title: showScrollbar() ? "Hide session scrollbar" : "Show session scrollbar",
744753
value: "session.toggle.scrollbar",
754+
search: "toggle session scrollbar",
755+
keybind: "scrollbar_toggle",
745756
category: "Session",
746757
run: () => {
747758
setShowScrollbar((prev) => !prev)

packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export interface DialogSelectOption<T = any> {
5757
value: T
5858
description?: string
5959
details?: string[]
60+
search?: string
6061
footer?: JSX.Element | string
6162
titleWidth?: number
6263
truncateTitle?: boolean | "left"
@@ -159,8 +160,8 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
159160
// users typically search by the item name, and not its category.
160161
const result = fuzzysort
161162
.go(needle, options, {
162-
keys: ["title", "category"],
163-
scoreFn: (r) => r[0].score * 2 + r[1].score,
163+
keys: ["title", "category", "search"],
164+
scoreFn: (r) => r[0].score * 2 + r[1].score + r[2].score,
164165
})
165166
.map((x) => x.obj)
166167

0 commit comments

Comments
 (0)