From fd37d5b54e029a1d082373baccdb56a922af4b8f Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Mon, 12 Jan 2026 16:46:32 -0600 Subject: [PATCH] tweak: truncation dir perm --- packages/opencode/src/agent/agent.ts | 12 ++++++++---- packages/opencode/src/tool/truncation.ts | 1 + packages/opencode/test/agent/agent.test.ts | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/opencode/src/agent/agent.ts b/packages/opencode/src/agent/agent.ts index fffc20426..ea9d3e3ba 100644 --- a/packages/opencode/src/agent/agent.ts +++ b/packages/opencode/src/agent/agent.ts @@ -50,6 +50,7 @@ export namespace Agent { external_directory: { "*": "ask", [Truncate.DIR]: "allow", + [Truncate.GLOB]: "allow", }, question: "deny", // mirrors github.com/github/gitignore Node.gitignore pattern for .env files @@ -124,6 +125,7 @@ export namespace Agent { read: "allow", external_directory: { [Truncate.DIR]: "allow", + [Truncate.GLOB]: "allow", }, }), user, @@ -213,14 +215,16 @@ export namespace Agent { // 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", - ) + const explicit = agent.permission.some((r) => { + if (r.permission !== "external_directory") return false + if (r.action !== "deny") return false + return r.pattern === Truncate.DIR || r.pattern === Truncate.GLOB + }) if (explicit) continue result[name].permission = PermissionNext.merge( result[name].permission, - PermissionNext.fromConfig({ external_directory: { [Truncate.DIR]: "allow" } }), + PermissionNext.fromConfig({ external_directory: { [Truncate.DIR]: "allow", [Truncate.GLOB]: "allow" } }), ) } diff --git a/packages/opencode/src/tool/truncation.ts b/packages/opencode/src/tool/truncation.ts index 133c57d3d..a876705d7 100644 --- a/packages/opencode/src/tool/truncation.ts +++ b/packages/opencode/src/tool/truncation.ts @@ -10,6 +10,7 @@ export namespace Truncate { export const MAX_LINES = 2000 export const MAX_BYTES = 50 * 1024 export const DIR = path.join(Global.Path.data, "tool-output") + export const GLOB = path.join(DIR, "*") const RETENTION_MS = 7 * 24 * 60 * 60 * 1000 // 7 days export type Result = { content: string; truncated: false } | { content: string; truncated: true; outputPath: string } diff --git a/packages/opencode/test/agent/agent.test.ts b/packages/opencode/test/agent/agent.test.ts index 68833c794..45f674c18 100644 --- a/packages/opencode/test/agent/agent.test.ts +++ b/packages/opencode/test/agent/agent.test.ts @@ -461,6 +461,7 @@ test("Truncate.DIR is allowed even when user denies external_directory globally" 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", Truncate.GLOB, build!.permission).action).toBe("allow") expect(PermissionNext.evaluate("external_directory", "/some/other/path", build!.permission).action).toBe("deny") }, }) @@ -484,6 +485,7 @@ test("Truncate.DIR is allowed even when user denies external_directory per-agent 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", Truncate.GLOB, build!.permission).action).toBe("allow") expect(PermissionNext.evaluate("external_directory", "/some/other/path", build!.permission).action).toBe("deny") }, }) @@ -506,6 +508,7 @@ test("explicit Truncate.DIR deny is respected", async () => { fn: async () => { const build = await Agent.get("build") expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("deny") + expect(PermissionNext.evaluate("external_directory", Truncate.GLOB, build!.permission).action).toBe("deny") }, }) })