authorgravatar for 154429365+Rishet11@users.noreply.github.comRishet11 <154429365+Rishet11@users.noreply.github.com> 2026-08-24 16:16:06+05:30
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-24 03:46:06-07:00
log04df98db4c90790fb5171426894baa3bca57a935
treea1d44cfaa81b4034396137678856dbb8596deb41
parent6a2608292dd7ba01516112c276e475e6b64e4e2c
signature Signed by PGP key B5690EEEBB952194

fix(server): honor auto-accept edits for the OpenCode provider (#7100)


2 files changed, 51 insertions(+), 1 deletions(-)

apps/server/src/provider/opencodeRuntime.permissions.test.ts created+44
...@@ -0,0 +1,44 @@
1import * as NodeAssert from "node:assert/strict";
2
3import { describe, it } from "vite-plus/test";
4
5import { buildOpenCodePermissionRules } from "./opencodeRuntime.ts";
6
7function actionFor(
8 runtimeMode: Parameters<typeof buildOpenCodePermissionRules>[0],
9 permission: string,
10) {
11 return buildOpenCodePermissionRules(runtimeMode).find((rule) => rule.permission === permission)
12 ?.action;
13}
14
15describe("buildOpenCodePermissionRules", () => {
16 it("pre-approves edits once the user has chosen to auto-accept them", () => {
17 NodeAssert.equal(actionFor("auto-accept-edits", "edit"), "allow");
18 });
19
20 it("still asks before editing when approval is required", () => {
21 NodeAssert.equal(actionFor("approval-required", "edit"), "ask");
22 });
23
24 // Documented in docs/user/permission-modes.md: providers without an AI
25 // reviewer, OpenCode among them, fall back to Supervised for "auto".
26 it("leaves auto asking, as the docs say it does without a reviewer", () => {
27 NodeAssert.equal(actionFor("auto", "edit"), "ask");
28 });
29
30 it("keeps asking for everything else in the auto modes", () => {
31 for (const runtimeMode of ["auto-accept-edits", "auto"] as const) {
32 NodeAssert.equal(actionFor(runtimeMode, "bash"), "ask");
33 NodeAssert.equal(actionFor(runtimeMode, "webfetch"), "ask");
34 NodeAssert.equal(actionFor(runtimeMode, "external_directory"), "ask");
35 NodeAssert.equal(actionFor(runtimeMode, "*"), "ask");
36 }
37 });
38
39 it("allows everything only under full access", () => {
40 NodeAssert.deepEqual(buildOpenCodePermissionRules("full-access"), [
41 { permission: "*", pattern: "*", action: "allow" },
42 ]);
43 });
44});
apps/server/src/provider/opencodeRuntime.ts+7-1
...@@ -373,10 +373,16 @@ export function buildOpenCodePermissionRules(runtimeMode: RuntimeMode): Permissi...@@ -373,10 +373,16 @@ export function buildOpenCodePermissionRules(runtimeMode: RuntimeMode): Permissi
373 return [{ permission: "*", pattern: "*", action: "allow" }];373 return [{ permission: "*", pattern: "*", action: "allow" }];
374 }374 }
375375
376 // "Auto-accept edits" is documented as "auto-approve edits, ask before other
377 // actions", so prompting for every edit ignores the mode the user picked.
378 // "auto" is left asking on purpose: the docs say providers without an AI
379 // reviewer, OpenCode among them, fall back to Supervised for that mode.
380 const editAction = runtimeMode === "auto-accept-edits" ? "allow" : "ask";
381
376 return [382 return [
377 { permission: "*", pattern: "*", action: "ask" },383 { permission: "*", pattern: "*", action: "ask" },
378 { permission: "bash", pattern: "*", action: "ask" },384 { permission: "bash", pattern: "*", action: "ask" },
379 { permission: "edit", pattern: "*", action: "ask" },385 { permission: "edit", pattern: "*", action: editAction },
380 { permission: "webfetch", pattern: "*", action: "ask" },386 { permission: "webfetch", pattern: "*", action: "ask" },
381 { permission: "websearch", pattern: "*", action: "ask" },387 { permission: "websearch", pattern: "*", action: "ask" },
382 { permission: "codesearch", pattern: "*", action: "ask" },388 { permission: "codesearch", pattern: "*", action: "ask" },