Skip to content

Commit 7866dbc

Browse files
authored
fix: avoid truncate permission import cycle (#18292)
1 parent e71a21e commit 7866dbc

4 files changed

Lines changed: 30 additions & 8 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Wildcard } from "@/util/wildcard"
2+
3+
type Rule = {
4+
permission: string
5+
pattern: string
6+
action: "allow" | "deny" | "ask"
7+
}
8+
9+
export function evaluate(permission: string, pattern: string, ...rulesets: Rule[][]): Rule {
10+
const rules = rulesets.flat()
11+
const match = rules.findLast(
12+
(rule) => Wildcard.match(permission, rule.permission) && Wildcard.match(pattern, rule.pattern),
13+
)
14+
return match ?? { action: "ask", permission, pattern: "*" }
15+
}

packages/opencode/src/permission/index.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { Wildcard } from "@/util/wildcard"
1313
import { Deferred, Effect, Layer, Schema, ServiceMap } from "effect"
1414
import os from "os"
1515
import z from "zod"
16+
import { evaluate as evalRule } from "./evaluate"
1617
import { PermissionID } from "./schema"
1718

1819
export namespace PermissionNext {
@@ -125,12 +126,8 @@ export namespace PermissionNext {
125126
}
126127

127128
export function evaluate(permission: string, pattern: string, ...rulesets: Ruleset[]): Rule {
128-
const rules = rulesets.flat()
129-
log.info("evaluate", { permission, pattern, ruleset: rules })
130-
const match = rules.findLast(
131-
(rule) => Wildcard.match(permission, rule.permission) && Wildcard.match(pattern, rule.pattern),
132-
)
133-
return match ?? { action: "ask", permission, pattern: "*" }
129+
log.info("evaluate", { permission, pattern, ruleset: rulesets.flat() })
130+
return evalRule(permission, pattern, ...rulesets)
134131
}
135132

136133
export class Service extends ServiceMap.Service<Service, Interface>()("@opencode/PermissionNext") {}

packages/opencode/src/tool/truncate-effect.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Cause, Duration, Effect, Layer, Schedule, ServiceMap } from "effect"
33
import path from "path"
44
import type { Agent } from "../agent/agent"
55
import { AppFileSystem } from "@/filesystem"
6-
import { PermissionNext } from "../permission"
6+
import { evaluate } from "@/permission/evaluate"
77
import { Identifier } from "../id/id"
88
import { Log } from "../util/log"
99
import { ToolID } from "./schema"
@@ -28,7 +28,7 @@ export namespace TruncateEffect {
2828

2929
function hasTaskTool(agent?: Agent.Info) {
3030
if (!agent?.permission) return false
31-
return PermissionNext.evaluate("task", "*", agent.permission).action !== "deny"
31+
return evaluate("task", "*", agent.permission).action !== "deny"
3232
}
3333

3434
export interface Interface {

packages/opencode/test/tool/truncation.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import { Effect, FileSystem, Layer } from "effect"
44
import { Truncate } from "../../src/tool/truncate"
55
import { TruncateEffect } from "../../src/tool/truncate-effect"
66
import { Identifier } from "../../src/id/id"
7+
import { Process } from "../../src/util/process"
78
import { Filesystem } from "../../src/util/filesystem"
89
import path from "path"
910
import { testEffect } from "../lib/effect"
1011
import { writeFileStringScoped } from "../lib/filesystem"
1112

1213
const FIXTURES_DIR = path.join(import.meta.dir, "fixtures")
14+
const ROOT = path.resolve(import.meta.dir, "..", "..")
1315

1416
describe("Truncate", () => {
1517
describe("output", () => {
@@ -125,6 +127,14 @@ describe("Truncate", () => {
125127
if (result.truncated) throw new Error("expected not truncated")
126128
expect("outputPath" in result).toBe(false)
127129
})
130+
131+
test("loads truncate effect in a fresh process", async () => {
132+
const out = await Process.run([process.execPath, "run", path.join(ROOT, "src", "tool", "truncate-effect.ts")], {
133+
cwd: ROOT,
134+
})
135+
136+
expect(out.code).toBe(0)
137+
}, 20000)
128138
})
129139

130140
describe("cleanup", () => {

0 commit comments

Comments
 (0)