# What Files Can Be Copied Using `copyToWorktree` in Sandcastle?

> Learn what files and directories copyToWorktree in Sandcastle can copy from your host repository root, including single files configurations and scripts.

- Repository: [Matt Pocock/sandcastle](https://github.com/mattpocock/sandcastle)
- Tags: how-to-guide
- Published: 2026-05-24

---

**The `copyToWorktree` feature in Sandcastle can copy any files or directories that exist relative to your host repository root, including single files like `.env`, entire directories like `node_modules`, configuration files, and custom scripts, while silently skipping any paths that do not exist.**

The `copyToWorktree` option is a core functionality in the Sandcastle repository (mattpocock/sandcastle) that allows developers to selectively transfer files from their host repository into freshly created worktrees. This feature supports copying single files, entire directories, or any mixture of valid paths to ensure your sandboxed environments have the necessary dependencies and configurations. Understanding which files can be copied and how the mechanism optimizes performance through copy-on-write is essential for effective sandbox workflow management.

## How copyToWorktree Works

The `copyToWorktree` function, implemented in [`CopyToWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CopyToWorktree.ts), walks each supplied path and validates its existence using `existsSync` before attempting any copy operation. If a source path does not exist, the function skips it silently without throwing an error or interrupting the workflow. For valid paths, the system transfers items into the freshly created worktree directory using optimized copy-on-write operations where the filesystem supports them.

## Supported File Types and Paths

You can pass any combination of the following to the `copyToWorktree` array defined in [`CreateWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CreateWorktree.ts):

- **Single files** such as `.env`, [`config.json`](https://github.com/mattpocock/sandcastle/blob/main/config.json), or [`README.md`](https://github.com/mattpocock/sandcastle/blob/main/README.md)
- **Entire directories** like `node_modules` or `scripts/`
- **Nested paths** such as [`scripts/setup.sh`](https://github.com/mattpocock/sandcastle/blob/main/scripts/setup.sh) or [`config/production.json`](https://github.com/mattpocock/sandcastle/blob/main/config/production.json)
- **Custom lists** including text files like [`node_modules.txt`](https://github.com/mattpocock/sandcastle/blob/main/node_modules.txt)

The set of copyable items is entirely user-defined. As implemented in the source, any path that exists relative to the host repository root can be copied into the worktree, while missing paths are ignored without error.

## Copy-On-Write Implementation

In [`CopyToWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CopyToWorktree.ts), the implementation leverages filesystem-level copy-on-write to minimize disk usage and improve execution speed. On macOS, the system executes `cp -cR`, while on Linux it uses `cp -R --reflink=auto`. If the underlying filesystem does not support reflinks, the operation gracefully falls back to a standard recursive copy, ensuring compatibility across different environments.

## Practical Usage Examples

The `copyToWorktree` option is available in three main contexts: creating worktrees, running sandboxed jobs, and interactive sessions.

### Copy Files When Creating a Worktree

When invoking `createWorktree()` from [`CreateWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CreateWorktree.ts), pass an array of relative paths to the `copyToWorktree` parameter:

```typescript
import { createWorktree } from "./createWorktree.js";

await createWorktree({
  cwd: "/path/to/your/repo",
  branchStrategy: "merge-to-head",
  copyToWorktree: [".env", "node_modules", "config.json"],
});

```

### Copy Files in Sandboxed Jobs

The `run()` function accepts the same option for ephemeral sandboxed execution:

```typescript
import { run } from "./run.js";

await run({
  agent: claudeCode("claude-opus-4-7"),
  sandbox: docker(),
  prompt: "Update dependencies",
  copyToWorktree: [".env"],
});

```

### Copy Files in Interactive Sessions

For interactive development sessions, use the option with the `interactive()` function:

```typescript
import { interactive } from "./interactive.js";

await interactive({
  agent: claudeCode("claude-sonnet-3.5"),
  sandbox: noSandbox(),
  prompt: "Explain the project structure",
  copyToWorktree: ["node_modules"],
});

```

## Summary

- **Any existing file or directory** relative to the host repository root can be copied using `copyToWorktree`
- The option is declared in [`CreateWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CreateWorktree.ts) as `copyToWorktree?: string[]` and implemented in [`CopyToWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CopyToWorktree.ts)
- Missing paths are **silently skipped** without errors, making workflows resilient to optional file dependencies
- The system automatically uses **copy-on-write** (`cp -cR` on macOS, `cp -R --reflink=auto` on Linux) for optimal performance with large directories
- Usable across **createWorktree**, **run**, and **interactive** functions as demonstrated in [`CopyToWorktree.test.ts`](https://github.com/mattpocock/sandcastle/blob/main/CopyToWorktree.test.ts)

## Frequently Asked Questions

### What happens if I specify a file that doesn't exist?

If a path listed in the `copyToWorktree` array does not exist in the host repository, the function silently skips that path and continues processing the remaining items. This behavior, implemented in [`CopyToWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CopyToWorktree.ts), ensures your workflows don't fail when optional files are missing.

### Can I copy nested directories or only flat files?

You can copy both nested directories and individual files. The implementation supports paths like [`scripts/setup.sh`](https://github.com/mattpocock/sandcastle/blob/main/scripts/setup.sh) or [`config/nested/production.json`](https://github.com/mattpocock/sandcastle/blob/main/config/nested/production.json), preserving the directory structure when copying into the worktree. Test suites in [`CopyToWorktree.test.ts`](https://github.com/mattpocock/sandcastle/blob/main/CopyToWorktree.test.ts) demonstrate these patterns.

### Is copyToWorktree faster than manual file copying?

Yes. As implemented in [`CopyToWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CopyToWorktree.ts), the feature uses copy-on-write semantics via `cp -cR` (macOS) or `cp -R --reflink=auto` (Linux), which creates deduplicated references rather than duplicating actual data blocks. This significantly reduces disk I/O and time required when copying large directories like `node_modules`, falling back to standard recursive copy only when the filesystem does not support reflinks.

### Where is the copyToWorktree option defined?

The option is declared in [`CreateWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CreateWorktree.ts) as an optional field `copyToWorktree?: string[]` within the configuration object, and the actual copy logic resides in [`CopyToWorktree.ts`](https://github.com/mattpocock/sandcastle/blob/main/CopyToWorktree.ts). According to the Sandcastle source, this option is available whenever creating worktrees, running sandboxed jobs, or starting interactive sessions.