File operations
Write, read, move, delete, search, list, patch, and transfer files inside the sandbox container.
SandboxHandle exposes file operation methods that cover reading, writing, patching, searching, and transferring files. All paths are inside the container.
writeFile
Write a UTF-8 string to a path inside the container. Creates parent directories automatically.
await sb.writeFile("/workspace/src/index.ts", 'export const VERSION = "1.0.0";\n');
await sb.writeFile("/tmp/config.json", JSON.stringify({ debug: true }));readFile
Read a file from the container as a UTF-8 string:
const source = await sb.readFile("/workspace/src/index.ts");
console.log(source);
// Use the content in subsequent steps
const config = JSON.parse(await sb.readFile("/tmp/config.json"));moveFile
Move or rename a file inside the container:
await sb.exec("mkdir -p /workspace/dist");
await sb.moveFile("/workspace/src/index.ts", "/workspace/dist/index.ts");deleteFile
Delete a file from the container:
await sb.deleteFile("/workspace/src/util.ts");searchFiles
Search for files matching a glob pattern. Returns an array of matching paths:
const tsFiles = await sb.searchFiles("*.ts", "/workspace/src");
console.log(tsFiles);
// ["/workspace/src/index.ts", "/workspace/src/util.ts"]The second argument is the base path to search from. Defaults to / if omitted.
listDirectory
List entries in a directory. Returns metadata for each entry:
const entries = await sb.listDirectory("/workspace/dist");
console.log(entries.map((e) => e.path));
// ["/workspace/dist/index.ts"]
// Control recursion depth
const all = await sb.listDirectory("/workspace", { depth: 3 });createDirectory
Create a directory (and all parents) inside the container without running exec:
await sb.createDirectory("/workspace/src");
await sb.createDirectory("/workspace/dist");deleteDirectory
Delete a directory from the container:
await sb.deleteDirectory("/workspace/tmp");getFileInfo
Return metadata for a file or directory — size, type, mode, owner, and timestamps:
const info = await sb.getFileInfo("/workspace/src/index.ts");
console.log(info.size); // bytes
console.log(info.type); // "file" | "directory" | "symlink"
console.log(info.mode); // unix permission bits
console.log(info.modified_at); // ISO timestampreplaceInFiles
Replace a substring in one or more files in a single API call. More efficient than readFile → string replace → writeFile for targeted edits:
await sb.replaceInFiles([
{ path: "/app/config.json", old: "localhost", new: "0.0.0.0" },
{ path: "/app/src/version.ts", old: "0.0.0", new: "1.2.3" },
]);transfer
Copy a file from this sandbox into another sandbox. Useful after fork() to move results between containers:
const fork = await sb.fork("after-build");
await fork.exec("npm run build");
await fork.transfer("/app/dist/bundle.js", sb); // copy back to original
await fork.close();Pattern: patch a file
Use replaceInFiles for in-place text replacements — no exec/sed needed:
await sb.writeFile("/workspace/src/index.ts", 'export const VERSION = "0.0.0";\n');
await sb.replaceInFiles([{ path: "/workspace/src/index.ts", old: "0.0.0", new: "1.2.3" }]);
const patched = await sb.readFile("/workspace/src/index.ts");
console.log(patched.trim()); // 'export const VERSION = "1.2.3";'Pattern: write a generated script and run it
const script = `
import sys
print(f"Python {sys.version.split()[0]}")
`.trim();
await sb.writeFile("/tmp/script.py", script);
await sb.exec("python3 /tmp/script.py").pipe(process.stdout);File ops in the workflow builder
writeFile, readFile, deleteFile, and moveFile are available in SandboxBuilder for use in @alineo-labs/workflow (createDirectory, deleteDirectory, getFileInfo, replaceInFiles, searchFiles, listDirectory, and transfer are not queueable — call them directly on a SandboxHandle outside the workflow builder). readFile takes an extra as argument to store the result in vars:
await workflow(client)
.sandbox({ image: "node:22", resources: { cpu: "500m", memory: "256Mi" } }, (sb) => {
sb.writeFile("/tmp/hello.txt", "hello\n");
sb.exec("cat /tmp/hello.txt").pipe(process.stdout);
sb.readFile("/tmp/hello.txt", "greeting"); // → vars["greeting"]
sb.moveFile("/tmp/hello.txt", "/tmp/moved.txt");
sb.deleteFile("/tmp/moved.txt");
})
.result();