Parcourir la source

permissions disallow support (#1627)

Aiden Cline il y a 6 mois
Parent
commit
a48274f82b

+ 1 - 1
packages/opencode/src/config/config.ts

@@ -224,7 +224,7 @@ export namespace Config {
   })
   export type Layout = z.infer<typeof Layout>
 
-  export const Permission = z.union([z.literal("ask"), z.literal("allow")])
+  export const Permission = z.union([z.literal("ask"), z.literal("allow"), z.literal("deny")])
   export type Permission = z.infer<typeof Permission>
 
   export const Info = z

+ 1 - 1
packages/opencode/src/session/index.ts

@@ -728,7 +728,7 @@ export namespace Session {
 
     const enabledTools = pipe(
       mode.tools,
-      mergeDeep(ToolRegistry.enabled(input.providerID, input.modelID)),
+      mergeDeep(await ToolRegistry.enabled(input.providerID, input.modelID)),
       mergeDeep(input.tools ?? {}),
     )
     for (const item of await ToolRegistry.tools(input.providerID, input.modelID)) {

+ 7 - 2
packages/opencode/src/tool/bash.ts

@@ -93,7 +93,7 @@ export const BashTool = Tool.define("bash", {
 
       // always allow cd if it passes above check
       if (!needsAsk && command[0] !== "cd") {
-        const ask = (() => {
+        const action = (() => {
           for (const [pattern, value] of Object.entries(permissions)) {
             const match = Wildcard.match(node.text, pattern)
             log.info("checking", { text: node.text.trim(), pattern, match })
@@ -101,7 +101,12 @@ export const BashTool = Tool.define("bash", {
           }
           return "ask"
         })()
-        if (ask === "ask") needsAsk = true
+        if (action === "deny") {
+          throw new Error(
+            "The user has specifically restricted access to this command, you are not allowed to execute it.",
+          )
+        }
+        if (action === "ask") needsAsk = true
       }
     }
 

+ 20 - 10
packages/opencode/src/tool/registry.ts

@@ -11,6 +11,7 @@ import { TodoWriteTool, TodoReadTool } from "./todo"
 import { WebFetchTool } from "./webfetch"
 import { WriteTool } from "./write"
 import { InvalidTool } from "./invalid"
+import { Config } from "../config/config"
 
 export namespace ToolRegistry {
   const ALL = [
@@ -65,11 +66,19 @@ export namespace ToolRegistry {
     return result
   }
 
-  export function enabled(_providerID: string, modelID: string): Record<string, boolean> {
+  export async function enabled(_providerID: string, modelID: string): Promise<Record<string, boolean>> {
+    const cfg = await Config.get()
+    const result: Record<string, boolean> = {}
+
+    if (cfg.permission?.edit === "deny") {
+      result["edit"] = false
+      result["patch"] = false
+      result["write"] = false
+    }
+
     if (modelID.toLowerCase().includes("claude")) {
-      return {
-        patch: false,
-      }
+      result["patch"] = false
+      return result
     }
 
     if (
@@ -79,13 +88,14 @@ export namespace ToolRegistry {
       modelID.includes("o3") ||
       modelID.includes("codex")
     ) {
-      return {
-        patch: false,
-        todowrite: false,
-        todoread: false,
-      }
+      result["patch"] = false
+      result["todowrite"] = false
+      result["todoread"] = false
+
+      return result
     }
-    return {}
+
+    return result
   }
 
   function sanitizeGeminiParameters(schema: z.ZodTypeAny, visited = new Set()): z.ZodTypeAny {