Skip to content

Commit 9d9830b

Browse files
committed
no breaking changes
1 parent 6ac33dd commit 9d9830b

31 files changed

Lines changed: 121 additions & 133 deletions

packages/opencode/src/cli/cmd/agent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { EOL } from "os"
1515
import type { Argv } from "yargs"
1616
type AgentMode = "all" | "primary" | "subagent"
1717

18-
const AVAILABLE_TOOLS = ["shell", "read", "write", "edit", "glob", "grep", "webfetch", "task", "todowrite"]
18+
const AVAILABLE_TOOLS = ["bash", "read", "write", "edit", "glob", "grep", "webfetch", "task", "todowrite"]
1919

2020
const AgentCreateCommand = cmd({
2121
command: "create",

packages/opencode/src/config/agent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const normalize = (agent: Schema.Schema.Type<typeof AgentSchema>): Schema.Schema
9191
continue
9292
}
9393
if (ShellToolID.normalize(tool) === ShellToolID.id) {
94-
permission.shell = action
94+
permission.bash = action
9595
continue
9696
}
9797
permission[tool] = action

packages/opencode/src/config/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ export const layer = Layer.effect(
672672
continue
673673
}
674674
if (ShellToolID.normalize(tool) === ShellToolID.id) {
675-
perms.shell = action
675+
perms.bash = action
676676
continue
677677
}
678678
perms[tool] = action

packages/opencode/src/config/permission.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const InputObject = Schema.StructWithRest(
2828
glob: Schema.optional(Rule),
2929
grep: Schema.optional(Rule),
3030
list: Schema.optional(Rule),
31-
shell: Schema.optional(Rule),
31+
bash: Schema.optional(Rule),
3232
task: Schema.optional(Rule),
3333
external_directory: Schema.optional(Rule),
3434
todowrite: Schema.optional(Action),

packages/opencode/src/session/llm.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,6 @@ function resolveTools(input: Pick<StreamInput, "tools" | "agent" | "permission"
460460
return Record.filter(input.tools, (_, k) => {
461461
const userTool = input.user.tools?.[k]
462462
if (userTool !== undefined) return userTool !== false && !disabled.has(k)
463-
if (k === ShellToolID.id && input.user.tools?.[ShellToolID.legacy] === false) return false
464463
return !disabled.has(k)
465464
})
466465
}

packages/opencode/src/tool/shell/id.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,14 @@ export namespace ShellKind {
1919
}
2020

2121
export namespace ShellToolID {
22-
export const id = "shell"
23-
export const legacy = "bash"
22+
export const id = "bash"
2423
export type ID = typeof id
2524

2625
export function has(value: string): value is ID {
2726
return value === id
2827
}
2928

3029
export function normalize(value: string) {
31-
return value === legacy ? id : value
30+
return value
3231
}
3332
}

packages/opencode/test/acp/event-subscription.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ describe("acp.agent event subscription", () => {
431431
properties: {
432432
id: "perm_1",
433433
sessionID: sessionA,
434-
permission: "shell",
434+
permission: "bash",
435435
patterns: ["*"],
436436
metadata: {},
437437
always: [],
@@ -490,7 +490,7 @@ describe("acp.agent event subscription", () => {
490490
properties: {
491491
id: "perm_a",
492492
sessionID: sessionA,
493-
permission: "shell",
493+
permission: "bash",
494494
patterns: ["*"],
495495
metadata: {},
496496
always: [],
@@ -549,7 +549,7 @@ describe("acp.agent event subscription", () => {
549549
controller.push(
550550
toolEvent(sessionId, cwd, {
551551
callID: "call_1",
552-
tool: "shell",
552+
tool: "bash",
553553
status: "running",
554554
input,
555555
metadata: { output },
@@ -581,7 +581,7 @@ describe("acp.agent event subscription", () => {
581581
controller.push(
582582
toolEvent(sessionId, cwd, {
583583
callID: "call_bash",
584-
tool: "shell",
584+
tool: "bash",
585585
status: "running",
586586
input: { command: "echo hi", description: "run command" },
587587
metadata: { output: "hi\n" },
@@ -635,7 +635,7 @@ describe("acp.agent event subscription", () => {
635635
{
636636
type: "tool",
637637
callID: "call_1",
638-
tool: "shell",
638+
tool: "bash",
639639
state: {
640640
status: "running",
641641
input,
@@ -652,7 +652,7 @@ describe("acp.agent event subscription", () => {
652652
controller.push(
653653
toolEvent(sessionId, cwd, {
654654
callID: "call_1",
655-
tool: "shell",
655+
tool: "bash",
656656
status: "running",
657657
input,
658658
metadata: { output: "hi\nthere\n" },
@@ -686,7 +686,7 @@ describe("acp.agent event subscription", () => {
686686
controller.push(
687687
toolEvent(sessionId, cwd, {
688688
callID: "call_1",
689-
tool: "shell",
689+
tool: "bash",
690690
status: "running",
691691
input,
692692
metadata: { output: "a" },
@@ -695,7 +695,7 @@ describe("acp.agent event subscription", () => {
695695
controller.push(
696696
toolEvent(sessionId, cwd, {
697697
callID: "call_1",
698-
tool: "shell",
698+
tool: "bash",
699699
status: "pending",
700700
input,
701701
raw: '{"command":"echo hello"}',
@@ -704,7 +704,7 @@ describe("acp.agent event subscription", () => {
704704
controller.push(
705705
toolEvent(sessionId, cwd, {
706706
callID: "call_1",
707-
tool: "shell",
707+
tool: "bash",
708708
status: "running",
709709
input,
710710
metadata: { output: "a" },

packages/opencode/test/cli/tui/transcript.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ describe("transcript", () => {
172172
messageID: "msg_123",
173173
type: "tool",
174174
callID: "call_1",
175-
tool: "shell",
175+
tool: "bash",
176176
state: {
177177
status: "completed",
178178
input: { command: "ls" },
@@ -197,7 +197,7 @@ describe("transcript", () => {
197197
messageID: "msg_123",
198198
type: "tool",
199199
callID: "call_1",
200-
tool: "shell",
200+
tool: "bash",
201201
state: {
202202
status: "completed",
203203
input: { command: "echo '```hello```'" },
@@ -222,7 +222,7 @@ describe("transcript", () => {
222222
messageID: "msg_123",
223223
type: "tool",
224224
callID: "call_1",
225-
tool: "shell",
225+
tool: "bash",
226226
state: {
227227
status: "completed",
228228
input: { command: "ls" },
@@ -245,7 +245,7 @@ describe("transcript", () => {
245245
messageID: "msg_123",
246246
type: "tool",
247247
callID: "call_1",
248-
tool: "shell",
248+
tool: "bash",
249249
state: {
250250
status: "error",
251251
input: { command: "invalid" },

packages/opencode/test/config/config.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,7 +1617,7 @@ test("merges legacy tools with existing permission config", async () => {
16171617
const config = await load()
16181618
expect(config.agent?.["test"]?.permission).toEqual({
16191619
glob: "allow",
1620-
shell: "allow",
1620+
bash: "allow",
16211621
})
16221622
},
16231623
})
@@ -1668,15 +1668,14 @@ test("permission config preserves user key order", async () => {
16681668
})
16691669
})
16701670

1671-
test("permission config preserves shell and legacy bash order", async () => {
1671+
test("permission config preserves bash key", async () => {
16721672
await using tmp = await tmpdir({
16731673
init: async (dir) => {
16741674
await Filesystem.write(
16751675
path.join(dir, "opencode.json"),
16761676
JSON.stringify({
16771677
$schema: "https://opencode.ai/config.json",
16781678
permission: {
1679-
shell: "deny",
16801679
bash: "allow",
16811680
},
16821681
}),
@@ -1687,9 +1686,8 @@ test("permission config preserves shell and legacy bash order", async () => {
16871686
directory: tmp.path,
16881687
fn: async () => {
16891688
const config = await load()
1690-
expect(Object.keys(config.permission!)).toEqual(["shell", "bash"])
1689+
expect(Object.keys(config.permission!)).toEqual(["bash"])
16911690
expect(config.permission).toEqual({
1692-
shell: "deny",
16931691
bash: "allow",
16941692
})
16951693
},

packages/opencode/test/permission/next.test.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,14 @@ function withProvided(dir: string) {
7878

7979
test("fromConfig - string value becomes wildcard rule", () => {
8080
const result = Permission.fromConfig({ bash: "allow" })
81-
expect(result).toEqual([{ permission: "shell", pattern: "*", action: "allow" }])
81+
expect(result).toEqual([{ permission: "bash", pattern: "*", action: "allow" }])
8282
})
8383

8484
test("fromConfig - object value converts to rules array", () => {
8585
const result = Permission.fromConfig({ bash: { "*": "allow", rm: "deny" } })
8686
expect(result).toEqual([
87-
{ permission: "shell", pattern: "*", action: "allow" },
88-
{ permission: "shell", pattern: "rm", action: "deny" },
87+
{ permission: "bash", pattern: "*", action: "allow" },
88+
{ permission: "bash", pattern: "rm", action: "deny" },
8989
])
9090
})
9191

@@ -96,32 +96,32 @@ test("fromConfig - mixed string and object values", () => {
9696
webfetch: "ask",
9797
})
9898
expect(result).toEqual([
99-
{ permission: "shell", pattern: "*", action: "allow" },
100-
{ permission: "shell", pattern: "rm", action: "deny" },
99+
{ permission: "bash", pattern: "*", action: "allow" },
100+
{ permission: "bash", pattern: "rm", action: "deny" },
101101
{ permission: "edit", pattern: "*", action: "allow" },
102102
{ permission: "webfetch", pattern: "*", action: "ask" },
103103
])
104104
})
105105

106-
test("fromConfig - shell and legacy bash normalize to shell in key order", () => {
106+
test("fromConfig - custom key remains separate from bash", () => {
107107
const result = Permission.fromConfig({
108-
shell: "deny",
108+
custom: "deny",
109109
bash: "allow",
110110
})
111111
expect(result).toEqual([
112-
{ permission: "shell", pattern: "*", action: "deny" },
113-
{ permission: "shell", pattern: "*", action: "allow" },
112+
{ permission: "custom", pattern: "*", action: "deny" },
113+
{ permission: "bash", pattern: "*", action: "allow" },
114114
])
115115
expect(Permission.evaluate("bash", "ls", result).action).toBe("allow")
116-
expect(Permission.evaluate("shell", "ls", result).action).toBe("allow")
116+
expect(Permission.evaluate("custom", "ls", result).action).toBe("deny")
117117
})
118118

119-
test("fromConfig - legacy bash rules coexist with canonical shell rules", () => {
119+
test("fromConfig - custom rules do not affect bash rules", () => {
120120
const result = Permission.fromConfig({
121-
shell: { "rm *": "deny" },
121+
custom: { "rm *": "deny" },
122122
bash: { "*": "allow", "rm *": "ask" },
123123
})
124-
expect(Permission.evaluate("shell", "rm foo", result).action).toBe("ask")
124+
expect(Permission.evaluate("custom", "rm foo", result).action).toBe("deny")
125125
expect(Permission.evaluate("bash", "rm foo", result).action).toBe("ask")
126126
})
127127

@@ -158,8 +158,8 @@ test("fromConfig - preserves top-level config key order", () => {
158158
const wildcardFirst = Permission.fromConfig({ "*": "deny", bash: "allow" })
159159
const specificFirst = Permission.fromConfig({ bash: "allow", "*": "deny" })
160160

161-
expect(wildcardFirst.map((r) => r.permission)).toEqual(["*", "shell"])
162-
expect(specificFirst.map((r) => r.permission)).toEqual(["shell", "*"])
161+
expect(wildcardFirst.map((r) => r.permission)).toEqual(["*", "bash"])
162+
expect(specificFirst.map((r) => r.permission)).toEqual(["bash", "*"])
163163

164164
expect(Permission.evaluate("bash", "ls", wildcardFirst).action).toBe("allow")
165165
expect(Permission.evaluate("bash", "ls", specificFirst).action).toBe("deny")
@@ -178,7 +178,7 @@ test("fromConfig - top-level ordering is not sorted by wildcard specificity", ()
178178
edit: "deny",
179179
"mcp_*": "allow",
180180
})
181-
expect(ruleset.map((r) => r.permission)).toEqual(["shell", "*", "edit", "mcp_*"])
181+
expect(ruleset.map((r) => r.permission)).toEqual(["bash", "*", "edit", "mcp_*"])
182182
})
183183

184184
test("fromConfig - sub-pattern insertion order inside a tool key is preserved", () => {
@@ -304,9 +304,9 @@ test("evaluate - exact pattern match", () => {
304304
expect(result.action).toBe("deny")
305305
})
306306

307-
test("evaluate - shell matches legacy bash rules", () => {
308-
const result = Permission.evaluate("shell", "rm", [{ permission: "bash", pattern: "rm", action: "deny" }])
309-
expect(result.action).toBe("deny")
307+
test("evaluate - custom tool does not match bash rules", () => {
308+
const result = Permission.evaluate("custom", "rm", [{ permission: "bash", pattern: "rm", action: "deny" }])
309+
expect(result.action).toBe("ask")
310310
})
311311

312312
test("evaluate - wildcard pattern match", () => {

0 commit comments

Comments
 (0)