summaryrefslogtreecommitdiffhomepage
path: root/packages/tool-edit-file/src/edit-file.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-21 23:32:23 +0900
committerAdam Malczewski <[email protected]>2026-06-21 23:32:23 +0900
commit7f6fd218ceeb3a1cf9420f5f6cfa4d70da6987bb (patch)
treee706f49d2df591c468fb66febe2a3f29d23cb0bb /packages/tool-edit-file/src/edit-file.ts
parent62ea07f56ff066bbf05041aadf8006cbc65e5c53 (diff)
downloaddispatch-7f6fd218ceeb3a1cf9420f5f6cfa4d70da6987bb.tar.gz
dispatch-7f6fd218ceeb3a1cf9420f5f6cfa4d70da6987bb.zip
feat: remove CWD path containment from file tools
read_file, write_file, and edit_file no longer restrict access to paths outside the working directory. The isPathWithinWorkdir prefix check and symlink hardening have been removed from all three tools. This allows agents to read and write files anywhere on the filesystem, not just within the per-turn cwd. The shell tool already had no such restriction.
Diffstat (limited to 'packages/tool-edit-file/src/edit-file.ts')
-rw-r--r--packages/tool-edit-file/src/edit-file.ts47
1 files changed, 2 insertions, 45 deletions
diff --git a/packages/tool-edit-file/src/edit-file.ts b/packages/tool-edit-file/src/edit-file.ts
index af630aa..36f99e0 100644
--- a/packages/tool-edit-file/src/edit-file.ts
+++ b/packages/tool-edit-file/src/edit-file.ts
@@ -1,5 +1,5 @@
-import { readFile, realpath, writeFile } from "node:fs/promises";
-import { resolve, sep } from "node:path";
+import { readFile, writeFile } from "node:fs/promises";
+import { resolve } from "node:path";
import type { ToolContract, ToolResult } from "@dispatch/kernel";
// --- Pure types ---
@@ -103,12 +103,6 @@ export function computeReplacement(
};
}
-/** Pure: check that a resolved absolute path is within the workdir (prefix check). */
-export function isPathWithinWorkdir(resolvedPath: string, workdir: string): boolean {
- const normalizedWorkdir = workdir.endsWith(sep) ? workdir : workdir + sep;
- return resolvedPath === workdir || resolvedPath.startsWith(normalizedWorkdir);
-}
-
// --- Shell / edge ---
/**
@@ -156,46 +150,9 @@ export function createEditFileTool(workingDirectory: string): ToolContract {
const { path: relPath, oldString, newString, replaceAll } = validated;
- // Effective base: per-turn ctx.cwd overrides the baked workdir.
const effectiveBase = ctx.cwd ? resolve(ctx.cwd) : workdir;
-
- // Resolve the requested path against the effective base.
const resolvedPath = resolve(effectiveBase, relPath);
- // Basic prefix check.
- if (!isPathWithinWorkdir(resolvedPath, effectiveBase)) {
- return {
- content: `Error: Path "${relPath}" is outside the working directory.`,
- isError: true,
- };
- }
-
- // Symlink hardening: realpath both and re-check containment.
- let realResolved: string;
- let realBase: string;
- try {
- [realResolved, realBase] = await Promise.all([
- realpath(resolvedPath),
- realpath(effectiveBase),
- ]);
- } catch (err: unknown) {
- const code = (err as NodeJS.ErrnoException).code;
- if (code === "ENOENT") {
- return { content: `Error: File "${relPath}" not found.`, isError: true };
- }
- return {
- content: `Error accessing file: ${err instanceof Error ? err.message : String(err)}`,
- isError: true,
- };
- }
-
- if (!isPathWithinWorkdir(realResolved, realBase)) {
- return {
- content: `Error: Path "${relPath}" is outside the working directory.`,
- isError: true,
- };
- }
-
// Read the file.
let content: string;
try {