Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 2 additions & 81 deletions bun.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion packages/opencode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@
"sharp": "0.34.5",
"solid-js": "catalog:",
"strip-ansi": "7.1.2",
"trash": "10",
"tree-sitter-bash": "0.25.0",
"tree-sitter-powershell": "0.25.10",
"turndown": "7.2.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/opencode/src/tool/bash.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Usage notes:
- Edit files: Use Edit (NOT sed/awk)
- Write files: Use Write (NOT echo >/cat <<EOF)
- Communication: Output text directly (NOT echo/printf)
- File deletion: Use the trash tool, NOT `rm`/`del` (rm permanently deletes; trash is reversible)
- File deletion: Avoid permanent deletion commands (`rm`, `rmdir`, `unlink`, `find -delete`, `del`, `erase`, `rd`, `Remove-Item`). Prefer a reversible system trash command when available: on macOS use `trash`; on Linux prefer `gio trash`, then `trash-put`. Check availability first: in POSIX shells use `command -v`, and in PowerShell use `Get-Command`. If no reversible command is available, ask the user before deleting.
- When issuing multiple commands:
- If the commands are independent and can run in parallel, make multiple Bash tool calls in a single message. For example, if you need to run "git status" and "git diff", send a single message with two Bash tool calls in parallel.
- ${chaining}
Expand Down
4 changes: 0 additions & 4 deletions packages/opencode/src/tool/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { AgentTool } from "./agent"
import { AgentListTool } from "./agent-list"
import { AgentOutputTool } from "./agent-output"
import { TodoWriteTool } from "./todo"
import { TrashTool } from "./trash"
import { WebFetchTool } from "./webfetch"
import { WriteTool } from "./write"
import { InvalidTool } from "./invalid"
Expand Down Expand Up @@ -139,7 +138,6 @@ export namespace ToolRegistry {
const greptool = yield* GrepTool
const patchtool = yield* ApplyPatchTool
const skilltool = yield* SkillTool
const trashtool = yield* TrashTool

const state = yield* InstanceState.make<State>(
Effect.fn("ToolRegistry.state")(function* (ctx) {
Expand Down Expand Up @@ -253,7 +251,6 @@ export namespace ToolRegistry {
grep: Tool.init(greptool),
edit: Tool.init(edit),
write: Tool.init(writetool),
trash: Tool.init(trashtool),
agent: Tool.init(agent),
agentList: Tool.init(agentList),
agentOutput: Tool.init(agentOutput),
Expand All @@ -279,7 +276,6 @@ export namespace ToolRegistry {
tool.grep,
tool.edit,
tool.write,
tool.trash,
tool.agent,
tool.agentList,
tool.agentOutput,
Expand Down
63 changes: 0 additions & 63 deletions packages/opencode/src/tool/trash.ts

This file was deleted.

7 changes: 0 additions & 7 deletions packages/opencode/src/tool/trash.txt

This file was deleted.

32 changes: 30 additions & 2 deletions packages/opencode/test/tool/registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,48 @@ async function withMockedConfigInstall<T>(fn: () => Promise<T>): Promise<T> {
}

describe("tool.registry", () => {
test("exposes trash tool", async () => {
test("does not expose built-in trash tool", async () => {
await using tmp = await tmpdir()

await withMockedConfigInstall(async () => {
await Instance.provide({
directory: tmp.path,
fn: async () => {
const ids = await ToolRegistry.ids()
expect(ids).toContain("trash")
expect(ids).not.toContain("trash")
},
})
})
})

test("keeps trash removal contract across prompt and package surfaces", async () => {
const bashDescription = await Bun.file(new URL("../../src/tool/bash.txt", import.meta.url)).text()
expect(bashDescription).not.toContain("trash tool")
expect(bashDescription).toContain("Avoid permanent deletion commands")
expect(bashDescription).toContain("gio trash")
expect(bashDescription).toContain("trash-put")
expect(bashDescription).toContain("Get-Command")

const packageJson = (await Bun.file(new URL("../../package.json", import.meta.url)).json()) as {
dependencies?: Record<string, string>
}
expect(Object.hasOwn(packageJson.dependencies ?? {}, "trash")).toBe(false)

const lockfile = await Bun.file(new URL("../../../../bun.lock", import.meta.url)).text()
const opencodeWorkspaceHeader = ' "packages/opencode": {'
const opencodeWorkspaceStart = lockfile.indexOf(opencodeWorkspaceHeader)
expect(opencodeWorkspaceStart).toBeGreaterThanOrEqual(0)
const afterOpencodeWorkspaceHeader = lockfile.slice(opencodeWorkspaceStart + opencodeWorkspaceHeader.length)
const nextWorkspaceOffset = afterOpencodeWorkspaceHeader.search(/\n "[^"]+": \{/)
const opencodeWorkspaceEnd =
nextWorkspaceOffset === -1
? lockfile.length
: opencodeWorkspaceStart + opencodeWorkspaceHeader.length + nextWorkspaceOffset
const opencodeWorkspaceLockfileSection = lockfile.slice(opencodeWorkspaceStart, opencodeWorkspaceEnd)
expect(opencodeWorkspaceLockfileSection).not.toContain('"trash": "10"')
expect(opencodeWorkspaceLockfileSection).not.toContain('"trash": ["trash@')
})

test("loads tools from .opencode/tool (singular)", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
Expand Down
171 changes: 0 additions & 171 deletions packages/opencode/test/tool/trash.test.ts

This file was deleted.

Loading