Review runs use a separate, fixed environment: a Medium VM with only the pull
request checkout. Project Setup scripts, Commands, tool hooks, environment
variables, VM size, and Snapshots do not apply to Review.
Let Captain manage it
You do not have to write Setup by hand. Captain inspects your repositories and configures the environment for you.1
Start from settings or chat
Open Settings → Project → Dev environment and click Set up with
Captain — or tell Captain in any thread: “Set up this project’s dev
environment.”
2
Captain writes and saves Setup
Captain reads package manifests, lockfiles, READMEs, and agent instructions
for every attached repository. It chooses lifecycle scripts, useful
commands, and a fitting VM size, then saves Setup for future runs.
3
Captain validates it
Captain starts a fresh validation run, exercises the configured environment,
and fixes Setup if anything fails.
Manual setup
Open a repository from Setup & commands to edit its base branch, lifecycle scripts, per-script timeouts, and named Commands. Tool hooks and VM size are configured on the main Dev environment page. The equivalent Setup object looks like this:What Setup defines
Environment variables and Snapshots are configured alongside Setup and are covered below.
Mental model
Setup is always authoritative. Snapshots cache its results; they do not replace
it. Run preparation reconciles whichever VM Capy obtains with the active Setup
and requested checkout.
How a run becomes ready
Before the agent starts working, Capy:- Allocates a new VM, restores a snapshot, or resumes the thread’s existing VM.
- Loads shared project environment variables. When a VM is prepared for a run you start, your personal variables are layered afterward and override shared variables with the same name.
- Refreshes GitHub credentials and attaches each repository at the requested branch and commit.
- Selects the required Setup path for each repository based on the VM’s saved state, active Setup revision, and current checkout.
- Runs the selected scripts. A Build agent becomes ready only after every blocking script succeeds.
Lifecycle scripts
Each repository has three automatic scripts:
The path is selected per repository:
The same phase runs across independent repositories in parallel, but phases
remain ordered: all selected Initialize work finishes before Startup begins.
Initialize
Use Initialize for work needed to make a clean repository usable:- Install language runtimes, system packages, and global tools
- Authenticate a private package registry before the first dependency fetch
- Install project dependencies
- Compile native dependencies or generate required artifacts
Initialize example
preinstall
hook cannot authenticate the dependency fetch that must happen before the hook
is available.
Update after checkout
Update after checkout is the maintenance phase. It repairs a prepared VM after Capy checks out a different branch or commit. Keep it fast and safe to rerun:- Synchronize dependencies from the current lockfile
- Regenerate code derived from the checkout
- Apply local, idempotent schema preparation needed by the development stack
- Refresh repository-scoped configuration
Update after checkout example
Startup
Startup runs after the selected preparation phase whenever the run needs its services started. Use it for development servers, local databases, and other processes that must be available while the agent works. Startup is blocking, so the script itself must exit. Launch long-running processes in the background and wait until they are ready:Startup example
Execution and failures
Scripts run:- From the corresponding repository directory
- In Bash with
set -e - With shared and applicable personal environment variables loaded
- With root access inside the isolated VM
- With configurable timeouts from 60 to 3600 seconds
Multiple repositories
All repositories in a run share one VM but have separate working directories. Within a lifecycle phase, their scripts execute in parallel. The next phase starts only after the current phase succeeds for every configured repository. Avoid scripts that depend on another repository finishing first. If repositories need the same global tool or system package, make the installation idempotent and safe under concurrent execution. Repository-specific dependency work should stay in that repository’s script.Commands
Commands are named, opt-in actions agents can run while working — build, test, lint, typecheck. They never run automatically during Setup; agents invoke them when relevant.
Keep Commands executable and specific. Prose guidance (“always run lint before committing”) belongs in agent instructions, not Commands.
Tool hooks
Setup can define commands that run before or after specific agent tools. Tool hooks are useful for policy checks and lightweight automatic formatting:bash_run, edit, multi_edit, write, read, glob, grep.
VM size
Small is the default and works for most tasks. Use larger sizes for heavy builds, large test suites, or resource-intensive compilation. Changes apply to the next run.
Environment variables
Configure variables at Settings → Project → Environment variables:- Shared variables are available to every project run.
- Personal variables are available only in project runs you start. A personal value overrides a shared variable with the same name.
.env file.
Snapshots
Environment Snapshots are currently available to select Enterprise customers.
Contact us to request access for your
organization.
- Starts a clean VM at the configured size.
- Injects shared project environment variables and GitHub credentials.
- Clones each configured repository at its base branch.
- Runs Initialize for each repository.
- Removes platform-managed environment files, credentials, session tokens, and transient runtime state before capturing the VM.
- Enable Snapshots — reuse a matching current snapshot, start the first build immediately, or queue it behind a build already in progress.
- Set the rebuild schedule — snapshots refresh automatically every 1, 2, 4, or 8 hours to keep dependencies current.
- Trigger a build manually — rebuild on demand after changing Setup.
- Test a snapshot — run the full capture, restore, and warm-up lifecycle without promoting the result.
- Inspect build history — every build has logs and status (ready, building, stale, or failed).
Snapshots are an optimization, never a requirement: Setup stays the source of truth, and if no current snapshot is available a run falls back to fresh provisioning with the same Setup.
Troubleshooting
Initialize fails
Inspect the failing repository and phase in the VM status menu, then open that repository’s Setup to inspect the configured command. For snapshot builds, inspect the build logs. Common causes are missing package-manager authentication, an interactive installer, an unavailable system package, or a timeout.Update after checkout fails
Run the command against the checked-out branch and current lockfile. Maintenance must be safe to repeat after a failed attempt. Prefer incremental dependency repair over deleting and rebuilding the entire environment.Startup times out
The Startup script must return. Background long-running processes, add a bounded readiness check, and fail clearly when the service never becomes healthy. Also make Startup idempotent so a resumed VM does not accumulate duplicate servers.A snapshot build fails
Open the build from Settings → Project → Dev environment → Build history and inspect the first failed step. Fix Setup, use Test snapshot to exercise the capture and restore lifecycle without promotion, then rebuild.Iterate with Captain
Click Improve with Captain or ask Captain to inspect the failure. Captain can read Setup, the repositories, and build state, save a correction, and start a fresh validation run.Migrating from .capy/settings.json
Repository hooks in .capy/settings.json are deprecated. Once any Setup exists
for the project, those hooks are ignored. Carry over any setup commands and tool
hooks you still need before saving; Captain detects and migrates them when it
configures the project.
The Dev environment page shows whether Setup, deprecated repository hooks, or
default behavior is currently authoritative.
Manage via API
Everything on this page is also scriptable: read and save Setup withGET /setup and PATCH /setup, and control snapshot state through the Snapshots API. See the Setup API overview for the full object shape.