summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2025-10-24 14:40:36 -0500
committerGitHub <[email protected]>2025-10-24 14:40:36 -0500
commite88b659545245888ee4091a0cc353f4d7bda7327 (patch)
tree4317489a7d017907e27afa8db326be153cb233dd
parent74048ece2d06dd8c3b6f9be46a10ae0c927e13db (diff)
downloadopencode-e88b659545245888ee4091a0cc353f4d7bda7327.tar.gz
opencode-e88b659545245888ee4091a0cc353f4d7bda7327.zip
make plan agent whitelist more conservative (#3424)
-rw-r--r--packages/opencode/src/agent/agent.ts6
-rw-r--r--packages/opencode/test/util/wildcard.test.ts55
2 files changed, 55 insertions, 6 deletions
diff --git a/packages/opencode/src/agent/agent.ts b/packages/opencode/src/agent/agent.ts
index 88e52aadf..3577a9176 100644
--- a/packages/opencode/src/agent/agent.ts
+++ b/packages/opencode/src/agent/agent.ts
@@ -52,9 +52,6 @@ export namespace Agent {
{
edit: "deny",
bash: {
- "awk -i inplace*": "ask",
- "awk --inplace*": "ask",
- "awk*": "allow",
"cut*": "allow",
"diff*": "allow",
"du*": "allow",
@@ -79,9 +76,6 @@ export namespace Agent {
"more*": "allow",
"pwd*": "allow",
"rg*": "allow",
- "sed --in-place*": "ask",
- "sed -i*": "ask",
- "sed -n *": "allow",
"sort --output=*": "ask",
"sort -o *": "ask",
"sort*": "allow",
diff --git a/packages/opencode/test/util/wildcard.test.ts b/packages/opencode/test/util/wildcard.test.ts
new file mode 100644
index 000000000..f7f1e1545
--- /dev/null
+++ b/packages/opencode/test/util/wildcard.test.ts
@@ -0,0 +1,55 @@
+import { test, expect } from "bun:test"
+import { Wildcard } from "../../src/util/wildcard"
+
+test("match handles glob tokens", () => {
+ expect(Wildcard.match("file1.txt", "file?.txt")).toBe(true)
+ expect(Wildcard.match("file12.txt", "file?.txt")).toBe(false)
+ expect(Wildcard.match("foo+bar", "foo+bar")).toBe(true)
+})
+
+test("all picks the most specific pattern", () => {
+ const rules = {
+ "*": "deny",
+ "git *": "ask",
+ "git status": "allow",
+ }
+ expect(Wildcard.all("git status", rules)).toBe("allow")
+ expect(Wildcard.all("git log", rules)).toBe("ask")
+ expect(Wildcard.all("echo hi", rules)).toBe("deny")
+})
+
+test("allStructured matches command sequences", () => {
+ const rules = {
+ "git *": "ask",
+ "git status*": "allow",
+ }
+ expect(Wildcard.allStructured({ head: "git", tail: ["status", "--short"] }, rules)).toBe("allow")
+ expect(Wildcard.allStructured({ head: "npm", tail: ["run", "build", "--watch"] }, { "npm run *": "allow" })).toBe(
+ "allow",
+ )
+ expect(Wildcard.allStructured({ head: "ls", tail: ["-la"] }, rules)).toBeUndefined()
+})
+
+test("allStructured prioritizes flag-specific patterns", () => {
+ const rules = {
+ "find *": "allow",
+ "find * -delete*": "ask",
+ "sort*": "allow",
+ "sort -o *": "ask",
+ }
+ expect(Wildcard.allStructured({ head: "find", tail: ["src", "-delete"] }, rules)).toBe("ask")
+ expect(Wildcard.allStructured({ head: "find", tail: ["src", "-print"] }, rules)).toBe("allow")
+ expect(Wildcard.allStructured({ head: "sort", tail: ["-o", "out.txt"] }, rules)).toBe("ask")
+ expect(Wildcard.allStructured({ head: "sort", tail: ["--reverse"] }, rules)).toBe("allow")
+})
+
+test("allStructured handles sed flags", () => {
+ const rules = {
+ "sed * -i*": "ask",
+ "sed -n*": "allow",
+ }
+ expect(Wildcard.allStructured({ head: "sed", tail: ["-i", "file"] }, rules)).toBe("ask")
+ expect(Wildcard.allStructured({ head: "sed", tail: ["-i.bak", "file"] }, rules)).toBe("ask")
+ expect(Wildcard.allStructured({ head: "sed", tail: ["-n", "1p", "file"] }, rules)).toBe("allow")
+ expect(Wildcard.allStructured({ head: "sed", tail: ["-i", "-n", "/./p", "myfile.txt"] }, rules)).toBe("ask")
+})