3.3 KiB
sandlot
A CLI for branch-based development using git worktrees and Apple containers. Each branch gets its own worktree and isolated VM.
Concepts
Sandlot is a thin workflow layer over two things: git worktrees and Apple containers. The idea is that spinning up a branch should give you a fully isolated environment — filesystem and runtime — with zero setup. When you're done, use git to merge and sandlot rm to clean up.
A sandlot session is a (worktree, VM) pair tied to a branch. Sessions are created with sandlot new <branch> and destroyed with sandlot rm <branch>.
Tech Stack
- Bun runtime
- Commander for CLI parsing
- Apple container for VMs
Setup
Prerequisites
Install
git clone https://github.com/your/sandlot
cd sandlot
bun install
bun link
This makes sandlot available globally.
CLI
sandlot new <branch>
Create a new session. This:
- Checks out the branch if it exists (local or remote), or creates a new branch from current HEAD
- Creates a git worktree at
.sandlot/<branch>/(relative to the repo root) - Boots an Apple container VM mapped to that worktree
- Drops you into the VM shell
$ sandlot new fix-POST
Creating worktree at .sandlot/fix-POST/
Booting VM...
root@fix-POST:~#
sandlot list
Show all active sessions.
$ sandlot list
BRANCH VM STATUS WORKTREE
fix-POST running .sandlot/fix-POST/
refactor-auth stopped .sandlot/refactor-auth/
sandlot open <branch>
Re-enter an existing session's VM. If the VM is stopped, boots it first.
$ sandlot open fix-POST
Booting VM...
root@fix-POST:~#
sandlot stop <branch>
Stop a session's VM without destroying it. The worktree and branch remain.
sandlot rm <branch>
Tear down a session. Stops the VM, removes the worktree, deletes the local branch. Does not touch the remote branch.
Configuration
Optional sandlot.json at the repo root:
{
"vm": {
"cpus": 4,
"memory": "8GB",
"image": "ubuntu:24.04",
"mounts": {
"/path/to/shared/deps": "/deps"
}
}
}
State
Sandlot tracks sessions in .sandlot/state.json at the repo root:
{
"sessions": {
"fix-POST": {
"branch": "fix-POST",
"worktree": ".sandlot/fix-POST",
"vm_id": "container-abc123",
"created_at": "2026-02-16T10:30:00Z",
"status": "running"
}
}
}
.sandlot/ should be added to .gitignore.
Edge Cases
- Stale VMs: If a VM crashes,
sandlot opendetects the dead VM and reboots it. - Multiple repos: State is per-repo. No global daemon.
- Branch name conflicts: If
.sandlot/<branch>/already exists as a directory but the session state is missing, prompt to clean up or recover.
Non-Goals
- Not a CI/CD tool. No pipelines, no test runners.
- Not a replacement for git. All git state lives in the real repo. Sandlot manages worktrees and VMs only.
- No multi-user collaboration features. This is a single-developer workflow tool.