Quickstart
Ask an agent to find your repository's test command and cite where it is defined. The example uses one job on a private project copy and asks only for a report.
Use an existing Git repository with a tracked README.md, opened at its root. Split needs a checkout with a .git directory; linked worktrees and submodule roots with a .git file are refused. To run the tests afterward, you will need the project's Linux arm64 dependencies.
Install and sign in
You need an Apple Silicon Mac and Docker Sandboxes (sbx) 0.47.0 or newer. In your Mac terminal, install both tools, sign in to Docker Sandboxes, and configure the provider used below:
brew install docker/tap/sbx mcavage/tap/marsh
sbx login
sbx secret set anthropic
The last command configures Anthropic for the Claude job below. Install has other installation methods.
In the same Mac terminal, change to your repository's root and run:
marsh
You are now in Linux at the same project path. The first shell launch may download its VM template. First use of Claude also starts its Kit VM and may download an image of about 600 MB. Allow a few minutes for these cold starts; later launches reuse warm VMs.
Split a task
At the marsh prompt:
split {
tests: claude -p 'Find the command this repository uses to run its tests. Start with README.md, then check the build files and CI configuration. Cite the defining file and line, and explain any required setup. If there is no test command, say what you checked. Do not edit files, run tests, or start other agents.'
} | join --keep
split gives the job a project copy, called a fork. Its container mounts that fork rather than your original project. The copy includes uncommitted work but omits Git-ignored files. Copy-on-write cloning shares unchanged file data where the filesystem supports it.
join prints the job's exit status, report, and any captured changes. Open the cited test definition and install any required Linux dependencies. Then try the test command at the marsh prompt.
Ctrl-C stops the foreground job and its children.
This task normally returns a report without a patch. For a task that changes code, continue with Make independent changes in parallel.
Inspect and clean up
Still at the marsh prompt, inspect what ran:
marsh jobs --tree
marsh results
The tree shows parent-child relationships. Results record exit status, timing, and whether marsh confirmed container deletion.
--keep preserved this split's output. Once you have read it, replace YOUR_SPLIT_ID below with the ID from the first join output line, remove the saved copy, and leave the shell:
marsh splits rm YOUR_SPLIT_ID
exit
Back in your Mac terminal, stop the VMs:
marsh stop
Stop refuses while any marsh shells or jobs remain active. It preserves your project, guest home, and job records.
Run an agent directly
A direct command such as claude -p 'Explain this repository' mounts your original project read-write. The agent can change or delete files; packaged agents run without their own permission prompts or internal sandboxes.
Your own shell commands, including tests, run unconfined in the shell VM. A test started inside a split branch begins in its fork but can write elsewhere in that VM. See the security model.
Agent credentials
The example uses a proxy-managed Anthropic credential. For Codex, configure sbx secret set openai on your Mac before calling codex exec. sbx secret ls lists stored credentials. OAuth options are in Signing in.
Docker Sandboxes adds proxy-managed keys to outgoing requests; containers receive placeholders. Agent logins saved in the guest home are instead readable by other jobs sharing that home.
Make it your shell
Your dotfiles and agent settings live in ~/.marsh/home on your Mac and appear under ~ inside marsh. They survive VM removal. See Set up your marsh home for skills, startup files, and MCP connections. Vim and terminal Emacs are included.
Agents running agents
An agent can call registered commands from its shell tool. Each call starts a child job with its own container and Kit credentials. Try Let an agent farm out work for one bounded subtask.
Run commands side by side
Use fanout { ... } | collect for commands that can safely share files. It creates no project copies, so concurrent writers can interfere with each other. See Fanout and collect.
Continue with Split and join or The shell.