loop-sandbox
July 27, 2026 ยท View on GitHub
Ephemeral worktree isolation for Loop Engineering. Divert agent execution into an isolated git worktree, capture their changes as a reviewable .patch file, and instantly destroy the sandbox.
Why loop-sandbox?
Unattended AI agents (loops) running directly in your main working tree can cause damage, overwrite untracked files, or make it incredibly tedious to untangle failed execution attempts.
loop-sandbox solves this by providing ephemeral worktree isolation:
- It automatically creates an isolated git worktree for the agent to run in.
- The agent runs its command, interacting with the codebase completely naturally.
- When the command finishes,
loop-sandboxautomatically captures the agent's edits (including new untracked files) into a clean.patchfile. - It nukes the worktree, keeping your main repo completely clean.
A human can then safely review the patch and apply it with one keystroke.
Warning
Isolation Limits: This is not a containerized air-gap. The agent process retains full filesystem and network access. It can escape the worktree (e.g. ../../), and changes outside the worktree or to .gitignored files will not be captured in the patch. This tool is complementary to docs/safety.md and does not replace OS-level sandboxing for hostile code.
Installation
npm install -g @cobusgreyling/loop-sandbox
# or run directly via npx
npx @cobusgreyling/loop-sandbox run -- <command>
Important
Required Gitignores: You must add the following to your project's .gitignore to prevent patches and worktree manifests from being committed:
.loop-sandbox/
.loop-worktrees/
Usage
loop-sandbox <command> [options]
Commands
| Command | Description |
|---|---|
run [opts] -- <cmd> | Run an agent command inside the isolated sandbox |
review / list | List isolated patches ready for human review |
Options for run
| Option | Description |
|---|---|
--shell | Forces shell: true (for bash -c, etc.). On Windows, npm-installed .cmd shims (npx, tsc, ...) that fail with ENOENT are automatically retried through a shell, so this is rarely needed there. |
--base <branch> | The base branch for the worktree (defaults to current HEAD) |
--lock-paths <globs> | Comma-separated globs to hold a loop-worktree advisory lock on for the run's duration, so a scheduled loop can't touch the same paths concurrently. Off by default -- see Multi-loop safety below. |
--lock-owner <name> | Lock owner name (defaults to the run's generated id) |
--lock-ttl <dur> | e.g. 30m -- passed through to loop-worktree's --ttl |
--lock-wait <dur> | e.g. 5m -- passed through to loop-worktree's --wait |
Examples
Running a tool via an agent:
# Safely let an agent run your linter/formatter without polluting your working tree
npx @cobusgreyling/loop-sandbox run -- npx my-agent
Running a shell command:
npx @cobusgreyling/loop-sandbox run --shell -- bash -c "echo 'hello' > test.txt"
Running alongside a scheduled loop that touches the same files:
npx @cobusgreyling/loop-sandbox run --lock-paths "src/**,docs/**" -- npx my-agent
Reviewing and applying patches:
# List all patches the sandbox caught
npx @cobusgreyling/loop-sandbox review
# Example output:
# === Loop Sandbox Patches ===
# ๐ sandbox-82f1e394.patch (1.2 KB)
# Apply: git apply .loop-sandbox/patches/sandbox-82f1e394.patch
How it works
Under the hood, loop-sandbox leverages @cobusgreyling/loop-worktree and native git worktree primitives. It creates a temporary branch from your current HEAD, spawns your process with its cwd set to the isolated tree, runs git diff --cached to generate the patch, and uses git worktree remove --force to clean up.
Multi-loop safety
A sandbox run is not, by itself, protected against a scheduled loop editing
the same files at the same time -- --lock-paths opts a run into
loop-worktree's advisory lock (acquired before the worktree is created,
released once the run finishes) so a colliding scheduled loop's own lock
call fails loudly instead of racing silently. See
docs/multi-loop.md for the wider convention this
follows.