| 23 | limit: z.coerce.number().describe("The number of lines to read (defaults to 2000)").optional(), |
| 24 | }), |
| 25 | async execute(params, ctx) { |
| 26 | let filepath = params.filePath |
| 27 | if (!path.isAbsolute(filepath)) { |
| 28 | filepath = path.join(process.cwd(), filepath) |
| 29 | } |
| 30 | const title = path.relative(Instance.worktree, filepath) |
| 31 | const agent = await Agent.get(ctx.agent) |
| 32 | |
| 33 | if (!ctx.extra?.["bypassCwdCheck"] && !Filesystem.contains(Instance.directory, filepath)) { |
| 34 | const parentDir = path.dirname(filepath) |
| 35 | if (!(await Permission.isBypassEnabled())) { |
| 36 | if (agent.permission.external_directory === "ask") { |
| 37 | await Permission.ask({ |
| 38 | type: "external_directory", |
| 39 | pattern: [parentDir, path.join(parentDir, "*")], |
| 40 | sessionID: ctx.sessionID, |
| 41 | messageID: ctx.messageID, |
| 42 | callID: ctx.callID, |
| 43 | title: `Access file outside working directory: ${filepath}`, |
| 44 | metadata: { |
| 45 | filepath, |
| 46 | parentDir, |
| 47 | }, |
| 48 | }) |
| 49 | } else if (agent.permission.external_directory === "deny") { |
| 50 | throw new Permission.RejectedError( |
| 51 | ctx.sessionID, |
| 52 | "external_directory", |
| 53 | ctx.callID, |
| 54 | { |
| 55 | filepath: filepath, |
| 56 | parentDir, |
| 57 | }, |
| 58 | `File ${filepath} is not in the current working directory`, |
| 59 | ) |
| 60 | } |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | const block = iife(() => { |
| 65 | const whitelist = [".env.sample", ".example"] |
| 66 | |
| 67 | if (whitelist.some((w) => filepath.endsWith(w))) return false |
| 68 | if (filepath.includes(".env")) return true |
| 69 | |
| 70 | return false |
| 71 | }) |
| 72 | |
| 73 | if (block) { |
| 74 | throw new Error(`The user has blocked you from reading ${filepath}, DO NOT make further attempts to read it`) |
| 75 | } |
| 76 | |
| 77 | const file = Bun.file(filepath) |
| 78 | if (!(await file.exists())) { |
| 79 | const dir = path.dirname(filepath) |
| 80 | const base = path.basename(filepath) |
| 81 | |
| 82 | const dirEntries = fs.readdirSync(dir) |