Worktree Setup
A fresh checkout has none of what git ignores: no node_modules, no .env, no build
cache. The Worktree Setup of a repository fixes that once for every worktree you
create from it, before its agent starts.
Open it from Edit setup… at the foot of the New Worktree dialog, Worktree setup… in a column card’s … menu, or Edit… in Host Settings › Worktrees. The main checkout has a setup of its own: Repository Setup.
The editor has three numbered stages and, under Advanced, the branch prefix.
A worktree's setup
- a worktree is created
- 1 SetupSmart Copy, then the commandsSetup terminal
- its agent starts
- 2 Runeach app on its own portRun button
- you delete the worktree
- 3 Clean updrops what it created, a minute per stepdelete sheet
What runs when a worktree is created, in a Setup terminal you open from the worktree’s header. The agent starts once it succeeds.
Smart Copy
Section titled “Smart Copy”Paths that git ignores and a fresh worktree needs: node_modules, .env, target,
.venv. Each path comes from the main checkout. On APFS, btrfs and XFS it is cloned:
a large node_modules arrives in seconds and shares its blocks with the original until
one side changes them. How worktrees are built explains
the technique.
Click the tag on a row to switch it between copy and link. A link points at the
main checkout’s file, the choice for .env and other secrets you keep in one place. A
linked folder is shared, so npm install in a worktree changes the main checkout too;
the editor says so when you link one.
Smart Copy takes paths that git ignores. Tracked files come with the checkout itself.
Commands
Section titled “Commands”Commands that run in order after Smart Copy, for example npm ci or
uv sync. They run in one shell that starts in the worktree’s root, so cd web as its
own step moves the ones after it. The setup stops at the first step that fails and shows
its exit code. The Setup popover runs it again, and so does Return in its terminal.
Ask the agent to fix the setup in the card’s … menu, or Ask an agent in the
popover, hands the failure to an agent that finds the cause and proposes a fix.
Files whose change means the setup should run again, such as package-lock.json. When
one changes, the worktree’s Setup says so, and Run setup brings it up to date.
One entry per app or service, each with a name (web, api, db) and its Start
steps. The last step keeps running: npm run dev -- --port $OFFSITE_PORT, cargo run,
npm test -- --watch. Stop steps are optional and end what Start left running
outside the terminal, such as docker compose stop.
Every entry runs on its own port from the worktree’s window and knows the ports of the others. The worktree’s header gets a Run button; with several entries, one Run button whose popover lists them. The whole story is on Run apps side by side.
Clean up
Section titled “Clean up”Commands that run when a worktree is deleted: drop the database it created, stop its container, remove its build output. The clean-up gets one minute per step, for the whole run.
A worktree keeps the clean-up steps of the setup it ran. When you change them later, the delete sheet lists every clean-up the worktree owes, ticked, and runs them in the worktree’s folder. A step that fails keeps the worktree and shows the step, its exit code and the last lines of its output, with Delete anyway next to it.
Branch prefix
Section titled “Branch prefix”Under Advanced › Branches. New branches are named <prefix>/<name>, offsite by
default. {github} stands for your GitHub login and {user} for your git user name, so
{github} gives octocat/fix-login-3acea3. An empty prefix means no prefix.
Set it up with an agent
Section titled “Set it up with an agent”Press Choose an agent… at the top of the editor and pick the agent, model and effort. It gets a scratch worktree of the repository, works out how the project installs and runs, and proposes the setup. Your main checkout stays as it is.
The agent fills the form as it goes. It reads the README, the lockfiles and the CI configuration, runs the commands in its scratch worktree, starts every Run entry once to prove it, and names in its summary what the host is missing, such as a toolchain. The badge reads Proposal ready when it is done. Ask for changes in its terminal or edit the lists yourself, then Save: the setup is saved on this host and the agent ends.
Test the setup
Section titled “Test the setup”Test… saves and tries the setup in a scratch worktree: Smart Copy and the commands first, then a Run button per app with its terminal, then Clean up when you finish the test. Everything runs for real, on the scratch worktree’s own ports.
Where the setup lives
Section titled “Where the setup lives”Save keeps the setup on this host, for this repository. It applies to every worktree created from then on, before anything is committed.
The Setup saved page offers Write to repository, which writes
.offsite/worktree.json into the main checkout, uncommitted, so teammates and a new
machine start with the same setup. Lines that look specific to this machine, such as
absolute paths, home paths, nvm use or sudo, are marked before you write.
When the host’s setup and the repository file differ, the host’s setup runs and the editor shows Compare…. Use repository takes the file, Keep host keeps yours.
A repository with a .worktreeinclude file and no setup yet starts with its paths in
Smart Copy.
When the setup changes
Section titled “When the setup changes”Each worktree keeps the setup it was created with, so an edit never changes a worktree in the middle of its work. After an edit, the worktree’s Setup popover offers Review changes: the sheet compares the stages and offers Keep current, Adopt, or Adopt and run setup.
Example: a monorepo
Section titled “Example: a monorepo”A web app, an API and a database, in one .offsite/worktree.json:
{ "include": [ "node_modules", "web/node_modules", "api/node_modules", { "path": ".env", "link": true } ], "setup": ["pnpm install --frozen-lockfile"], "watch": ["pnpm-lock.yaml"], "run": [ { "name": "web", "steps": ["cd web", "API_URL=http://localhost:$OFFSITE_RUN_API_PORT pnpm dev --port $OFFSITE_PORT"] }, { "name": "api", "steps": ["cd api", "DATABASE_PORT=$OFFSITE_RUN_DB_PORT pnpm dev --port $OFFSITE_PORT"] }, { "name": "db", "steps": ["DB_PORT=$OFFSITE_PORT docker compose -p bloom-$OFFSITE_PORT_BASE up db"], "stop": ["docker compose -p bloom-$OFFSITE_PORT_BASE stop db"] } ], "cleanup": ["docker compose -p bloom-$OFFSITE_PORT_BASE down -v"]}Every worktree gets its own database container, named after its port window, and its
web talks to its own api. web comes first because a worktree’s Browser card opens
the first entry’s port.
The file format
Section titled “The file format”| Key | Type | Stage |
|---|---|---|
include | paths, or objects with path and link | Setup · Smart Copy |
setup | commands | Setup · Commands |
watch | file paths | Setup · Watch |
run | entries with name, steps and stop | Run |
cleanup | commands | Clean up |
main | an object with setup, run and watch | the main checkout’s Repository Setup |
For agents
Section titled “For agents”An agent in a worktree can declare the setup it worked out with its
worktree_setup_declare tool, which writes .offsite/worktree.json in that worktree.
Merged into the base, the file is the repository’s shared setup, as described under
Where the setup lives.