Przeglądaj źródła

core: permission config schema now provides full IntelliSense for all tool permission keys

The permission configuration previously used a generic record type that didn't offer editor completions. Updated the schema to explicitly list all tool permission keys (read, edit, glob, grep, list, bash, task, external_directory, lsp, skill, todowrite, question, webfetch, websearch, codesearch, doom_loop) with proper types, enabling autocomplete when editing permission files.
Dax Raad 18 godzin temu
rodzic
commit
1b92c95425

+ 26 - 9
packages/opencode/src/config/permission.ts

@@ -53,17 +53,34 @@ const InputSchema = Schema.Union([Action, InputObject])
 const normalizeInput = (input: Schema.Schema.Type<typeof InputSchema>): Schema.Schema.Type<typeof InputObject> =>
   typeof input === "string" ? { "*": input } : input
 
-const ACTION_ONLY = new Set(["todowrite", "question", "webfetch", "websearch", "codesearch", "doom_loop"])
-
 const InfoZod = z
-  .union([zod(Action), z.record(z.string(), z.union([zod(Action), z.record(z.string(), zod(Action))]))])
+  .union([
+    zod(Action),
+    z.intersection(
+      z.record(z.string(), zod(Rule)),
+      z
+        .object({
+          read: zod(Rule).optional(),
+          edit: zod(Rule).optional(),
+          glob: zod(Rule).optional(),
+          grep: zod(Rule).optional(),
+          list: zod(Rule).optional(),
+          bash: zod(Rule).optional(),
+          task: zod(Rule).optional(),
+          external_directory: zod(Rule).optional(),
+          todowrite: zod(Action).optional(),
+          question: zod(Action).optional(),
+          webfetch: zod(Action).optional(),
+          websearch: zod(Action).optional(),
+          codesearch: zod(Action).optional(),
+          lsp: zod(Rule).optional(),
+          doom_loop: zod(Action).optional(),
+          skill: zod(Rule).optional(),
+        })
+        .catchall(zod(Rule)),
+    ),
+  ])
   .transform(normalizeInput)
-  .superRefine((input, ctx) => {
-    for (const [key, value] of globalThis.Object.entries(input)) {
-      if (!ACTION_ONLY.has(key) || typeof value === "string") continue
-      ctx.addIssue({ code: "custom", message: `${key} must be a permission action`, path: [key] })
-    }
-  })
 
 export const Info = InputSchema.pipe(
   Schema.decodeTo(InputObject, {

+ 27 - 7
packages/sdk/js/src/v2/gen/types.gen.ts

@@ -1198,15 +1198,35 @@ export type ServerConfig = {
 
 export type PermissionActionConfig = "ask" | "allow" | "deny"
 
+export type PermissionObjectConfig = {
+  [key: string]: PermissionActionConfig
+}
+
+export type PermissionRuleConfig = PermissionActionConfig | PermissionObjectConfig
+
 export type PermissionConfig =
   | PermissionActionConfig
-  | {
-      [key: string]:
-        | PermissionActionConfig
-        | {
-            [key: string]: PermissionActionConfig
-          }
-    }
+  | ({
+      [key: string]: PermissionRuleConfig
+    } & {
+      read?: PermissionRuleConfig
+      edit?: PermissionRuleConfig
+      glob?: PermissionRuleConfig
+      grep?: PermissionRuleConfig
+      list?: PermissionRuleConfig
+      bash?: PermissionRuleConfig
+      task?: PermissionRuleConfig
+      external_directory?: PermissionRuleConfig
+      todowrite?: PermissionActionConfig
+      question?: PermissionActionConfig
+      webfetch?: PermissionActionConfig
+      websearch?: PermissionActionConfig
+      codesearch?: PermissionActionConfig
+      lsp?: PermissionRuleConfig
+      doom_loop?: PermissionActionConfig
+      skill?: PermissionRuleConfig
+      [key: string]: PermissionRuleConfig | PermissionActionConfig | undefined
+    })
 
 export type AgentConfig = {
   model?: string

+ 81 - 15
packages/sdk/openapi.json

@@ -10926,32 +10926,98 @@
         "type": "string",
         "enum": ["ask", "allow", "deny"]
       },
+      "PermissionObjectConfig": {
+        "type": "object",
+        "propertyNames": {
+          "type": "string"
+        },
+        "additionalProperties": {
+          "$ref": "#/components/schemas/PermissionActionConfig"
+        }
+      },
+      "PermissionRuleConfig": {
+        "anyOf": [
+          {
+            "$ref": "#/components/schemas/PermissionActionConfig"
+          },
+          {
+            "$ref": "#/components/schemas/PermissionObjectConfig"
+          }
+        ]
+      },
       "PermissionConfig": {
         "anyOf": [
           {
             "$ref": "#/components/schemas/PermissionActionConfig"
           },
           {
-            "type": "object",
-            "propertyNames": {
-              "type": "string"
-            },
-            "additionalProperties": {
-              "anyOf": [
-                {
-                  "$ref": "#/components/schemas/PermissionActionConfig"
+            "allOf": [
+              {
+                "type": "object",
+                "propertyNames": {
+                  "type": "string"
                 },
-                {
-                  "type": "object",
-                  "propertyNames": {
-                    "type": "string"
+                "additionalProperties": {
+                  "$ref": "#/components/schemas/PermissionRuleConfig"
+                }
+              },
+              {
+                "type": "object",
+                "properties": {
+                  "read": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
                   },
-                  "additionalProperties": {
+                  "edit": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
+                  },
+                  "glob": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
+                  },
+                  "grep": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
+                  },
+                  "list": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
+                  },
+                  "bash": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
+                  },
+                  "task": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
+                  },
+                  "external_directory": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
+                  },
+                  "todowrite": {
+                    "$ref": "#/components/schemas/PermissionActionConfig"
+                  },
+                  "question": {
                     "$ref": "#/components/schemas/PermissionActionConfig"
+                  },
+                  "webfetch": {
+                    "$ref": "#/components/schemas/PermissionActionConfig"
+                  },
+                  "websearch": {
+                    "$ref": "#/components/schemas/PermissionActionConfig"
+                  },
+                  "codesearch": {
+                    "$ref": "#/components/schemas/PermissionActionConfig"
+                  },
+                  "lsp": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
+                  },
+                  "doom_loop": {
+                    "$ref": "#/components/schemas/PermissionActionConfig"
+                  },
+                  "skill": {
+                    "$ref": "#/components/schemas/PermissionRuleConfig"
                   }
+                },
+                "additionalProperties": {
+                  "$ref": "#/components/schemas/PermissionRuleConfig"
                 }
-              ]
-            }
+              }
+            ]
           }
         ]
       },