فهرست منبع

ignore: ensure new file truncation stuff still works even if external_directoy is set to deny

Aiden Cline 3 ماه پیش
والد
کامیت
3c5043497c
2فایلهای تغییر یافته به همراه78 افزوده شده و 0 حذف شده
  1. 15 0
      packages/opencode/src/agent/agent.ts
  2. 63 0
      packages/opencode/test/agent/agent.test.ts

+ 15 - 0
packages/opencode/src/agent/agent.ts

@@ -209,6 +209,21 @@ export namespace Agent {
       item.options = mergeDeep(item.options, value.options ?? {})
       item.permission = PermissionNext.merge(item.permission, PermissionNext.fromConfig(value.permission ?? {}))
     }
+
+    // Ensure Truncate.DIR is allowed unless explicitly configured
+    for (const name in result) {
+      const agent = result[name]
+      const explicit = agent.permission.some(
+        (r) => r.permission === "external_directory" && r.pattern === Truncate.DIR && r.action === "deny",
+      )
+      if (explicit) continue
+
+      result[name].permission = PermissionNext.merge(
+        result[name].permission,
+        PermissionNext.fromConfig({ external_directory: { [Truncate.DIR]: "allow" } }),
+      )
+    }
+
     return result
   })
 

+ 63 - 0
packages/opencode/test/agent/agent.test.ts

@@ -446,3 +446,66 @@ test("legacy tools config maps write/edit/patch/multiedit to edit permission", a
     },
   })
 })
+
+test("Truncate.DIR is allowed even when user denies external_directory globally", async () => {
+  const { Truncate } = await import("../../src/tool/truncation")
+  await using tmp = await tmpdir({
+    config: {
+      permission: {
+        external_directory: "deny",
+      },
+    },
+  })
+  await Instance.provide({
+    directory: tmp.path,
+    fn: async () => {
+      const build = await Agent.get("build")
+      expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("allow")
+      expect(PermissionNext.evaluate("external_directory", "/some/other/path", build!.permission).action).toBe("deny")
+    },
+  })
+})
+
+test("Truncate.DIR is allowed even when user denies external_directory per-agent", async () => {
+  const { Truncate } = await import("../../src/tool/truncation")
+  await using tmp = await tmpdir({
+    config: {
+      agent: {
+        build: {
+          permission: {
+            external_directory: "deny",
+          },
+        },
+      },
+    },
+  })
+  await Instance.provide({
+    directory: tmp.path,
+    fn: async () => {
+      const build = await Agent.get("build")
+      expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("allow")
+      expect(PermissionNext.evaluate("external_directory", "/some/other/path", build!.permission).action).toBe("deny")
+    },
+  })
+})
+
+test("explicit Truncate.DIR deny is respected", async () => {
+  const { Truncate } = await import("../../src/tool/truncation")
+  await using tmp = await tmpdir({
+    config: {
+      permission: {
+        external_directory: {
+          "*": "deny",
+          [Truncate.DIR]: "deny",
+        },
+      },
+    },
+  })
+  await Instance.provide({
+    directory: tmp.path,
+    fn: async () => {
+      const build = await Agent.get("build")
+      expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("deny")
+    },
+  })
+})