Skip to content

Commit 3c50434

Browse files
committed
ignore: ensure new file truncation stuff still works even if external_directoy is set to deny
1 parent 4d09c56 commit 3c50434

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

packages/opencode/src/agent/agent.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,21 @@ export namespace Agent {
209209
item.options = mergeDeep(item.options, value.options ?? {})
210210
item.permission = PermissionNext.merge(item.permission, PermissionNext.fromConfig(value.permission ?? {}))
211211
}
212+
213+
// Ensure Truncate.DIR is allowed unless explicitly configured
214+
for (const name in result) {
215+
const agent = result[name]
216+
const explicit = agent.permission.some(
217+
(r) => r.permission === "external_directory" && r.pattern === Truncate.DIR && r.action === "deny",
218+
)
219+
if (explicit) continue
220+
221+
result[name].permission = PermissionNext.merge(
222+
result[name].permission,
223+
PermissionNext.fromConfig({ external_directory: { [Truncate.DIR]: "allow" } }),
224+
)
225+
}
226+
212227
return result
213228
})
214229

packages/opencode/test/agent/agent.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,3 +446,66 @@ test("legacy tools config maps write/edit/patch/multiedit to edit permission", a
446446
},
447447
})
448448
})
449+
450+
test("Truncate.DIR is allowed even when user denies external_directory globally", async () => {
451+
const { Truncate } = await import("../../src/tool/truncation")
452+
await using tmp = await tmpdir({
453+
config: {
454+
permission: {
455+
external_directory: "deny",
456+
},
457+
},
458+
})
459+
await Instance.provide({
460+
directory: tmp.path,
461+
fn: async () => {
462+
const build = await Agent.get("build")
463+
expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("allow")
464+
expect(PermissionNext.evaluate("external_directory", "/some/other/path", build!.permission).action).toBe("deny")
465+
},
466+
})
467+
})
468+
469+
test("Truncate.DIR is allowed even when user denies external_directory per-agent", async () => {
470+
const { Truncate } = await import("../../src/tool/truncation")
471+
await using tmp = await tmpdir({
472+
config: {
473+
agent: {
474+
build: {
475+
permission: {
476+
external_directory: "deny",
477+
},
478+
},
479+
},
480+
},
481+
})
482+
await Instance.provide({
483+
directory: tmp.path,
484+
fn: async () => {
485+
const build = await Agent.get("build")
486+
expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("allow")
487+
expect(PermissionNext.evaluate("external_directory", "/some/other/path", build!.permission).action).toBe("deny")
488+
},
489+
})
490+
})
491+
492+
test("explicit Truncate.DIR deny is respected", async () => {
493+
const { Truncate } = await import("../../src/tool/truncation")
494+
await using tmp = await tmpdir({
495+
config: {
496+
permission: {
497+
external_directory: {
498+
"*": "deny",
499+
[Truncate.DIR]: "deny",
500+
},
501+
},
502+
},
503+
})
504+
await Instance.provide({
505+
directory: tmp.path,
506+
fn: async () => {
507+
const build = await Agent.get("build")
508+
expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("deny")
509+
},
510+
})
511+
})

0 commit comments

Comments
 (0)