sandlot/SPEC.md
2026-02-17 08:15:03 -08:00

132 lines
3.2 KiB
Markdown

# sandlot
A CLI for branch-based development using git worktrees and Lima VMs. Each branch gets its own worktree and isolated VM.
## Concepts
**Sandlot** is a thin workflow layer over two things: git worktrees and [Lima](https://github.com/lima-vm/lima). 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](https://bun.sh) runtime
- [Commander](https://github.com/tj/commander.js) for CLI parsing
- [Lima](https://github.com/lima-vm/lima) for VMs
## Setup
### Prerequisites
- macOS on Apple Silicon
- [Bun](https://bun.sh) installed
- Git installed
- [Lima](https://github.com/lima-vm/lima) installed (`brew install lima`)
### Install
```bash
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:
1. Checks out the branch if it exists (local or remote), or creates a new branch from current HEAD
2. Creates a git worktree at `.sandlot/<branch>/` (relative to the repo root)
3. Boots a Lima VM mapped to that worktree
4. 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:
```json
{
"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:
```json
{
"sessions": {
"fix-POST": {
"branch": "fix-POST",
"worktree": ".sandlot/fix-POST",
"vm_id": "sandlot-fix-POST",
"created_at": "2026-02-16T10:30:00Z",
"status": "running"
}
}
}
```
`.sandlot/` should be added to `.gitignore`.
## Edge Cases
- **Stale VMs**: If a VM crashes, `sandlot open` detects 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.