From d425723249c4bdf691ccc76308b17ed148ea0b5d Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Wed, 5 Nov 2025 16:09:36 -0600 Subject: [PATCH] ask instead of throwing tool error if file is outside cwd --- packages/opencode/src/tool/edit.ts | 14 +++++++++++++- packages/opencode/src/tool/patch.ts | 14 +++++++++++++- packages/opencode/src/tool/read.ts | 15 ++++++++++++++- packages/opencode/src/tool/write.ts | 14 +++++++++++++- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/packages/opencode/src/tool/edit.ts b/packages/opencode/src/tool/edit.ts index 7429c44b..ba3d2c0b 100644 --- a/packages/opencode/src/tool/edit.ts +++ b/packages/opencode/src/tool/edit.ts @@ -37,7 +37,19 @@ export const EditTool = Tool.define("edit", { const filePath = path.isAbsolute(params.filePath) ? params.filePath : path.join(Instance.directory, params.filePath) if (!Filesystem.contains(Instance.directory, filePath)) { - throw new Error(`File ${filePath} is not in the current working directory`) + const parentDir = path.dirname(filePath) + await Permission.ask({ + type: "external-directory", + pattern: parentDir, + sessionID: ctx.sessionID, + messageID: ctx.messageID, + callID: ctx.callID, + title: `Edit file outside working directory: ${filePath}`, + metadata: { + filepath: filePath, + parentDir, + }, + }) } const agent = await Agent.get(ctx.agent) diff --git a/packages/opencode/src/tool/patch.ts b/packages/opencode/src/tool/patch.ts index 118e0840..f76b9474 100644 --- a/packages/opencode/src/tool/patch.ts +++ b/packages/opencode/src/tool/patch.ts @@ -54,7 +54,19 @@ export const PatchTool = Tool.define("patch", { const filePath = path.resolve(Instance.directory, hunk.path) if (!Filesystem.contains(Instance.directory, filePath)) { - throw new Error(`File ${filePath} is not in the current working directory`) + const parentDir = path.dirname(filePath) + await Permission.ask({ + type: "external-directory", + pattern: parentDir, + sessionID: ctx.sessionID, + messageID: ctx.messageID, + callID: ctx.callID, + title: `Patch file outside working directory: ${filePath}`, + metadata: { + filepath: filePath, + parentDir, + }, + }) } switch (hunk.type) { diff --git a/packages/opencode/src/tool/read.ts b/packages/opencode/src/tool/read.ts index bc89dae2..963636fd 100644 --- a/packages/opencode/src/tool/read.ts +++ b/packages/opencode/src/tool/read.ts @@ -9,6 +9,7 @@ import { Filesystem } from "../util/filesystem" import { Instance } from "../project/instance" import { Provider } from "../provider/provider" import { Identifier } from "../id/id" +import { Permission } from "../permission" const DEFAULT_READ_LIMIT = 2000 const MAX_LINE_LENGTH = 2000 @@ -28,7 +29,19 @@ export const ReadTool = Tool.define("read", { const title = path.relative(Instance.worktree, filepath) if (!ctx.extra?.["bypassCwdCheck"] && !Filesystem.contains(Instance.directory, filepath)) { - throw new Error(`File ${filepath} is not in the current working directory`) + const parentDir = path.dirname(filepath) + await Permission.ask({ + type: "external-directory", + pattern: parentDir, + sessionID: ctx.sessionID, + messageID: ctx.messageID, + callID: ctx.callID, + title: `Access file outside working directory: ${filepath}`, + metadata: { + filepath, + parentDir, + }, + }) } const file = Bun.file(filepath) diff --git a/packages/opencode/src/tool/write.ts b/packages/opencode/src/tool/write.ts index a4b00100..acaa1239 100644 --- a/packages/opencode/src/tool/write.ts +++ b/packages/opencode/src/tool/write.ts @@ -20,7 +20,19 @@ export const WriteTool = Tool.define("write", { async execute(params, ctx) { const filepath = path.isAbsolute(params.filePath) ? params.filePath : path.join(Instance.directory, params.filePath) if (!Filesystem.contains(Instance.directory, filepath)) { - throw new Error(`File ${filepath} is not in the current working directory`) + const parentDir = path.dirname(filepath) + await Permission.ask({ + type: "external-directory", + pattern: parentDir, + sessionID: ctx.sessionID, + messageID: ctx.messageID, + callID: ctx.callID, + title: `Write file outside working directory: ${filepath}`, + metadata: { + filepath, + parentDir, + }, + }) } const file = Bun.file(filepath)