A CLI that runs AI coding agents in a macOS sandbox using git worktrees for isolation.
- Creates git worktrees for isolated agent sessions
- Runs agents inside a macOS Seatbelt sandbox via
sandbox-exec - Manages sandbox profiles for composable capability control
- Persists sessions for resuming previous configurations
100% macOS-native. No Docker, no cloud, CLI-first.
Note:
sandbox-execis deprecated by Apple, but still present on macOS today and used by tools in the wild. If Apple removes it in the future, the same policy can be applied by a signed helper using the underlying sandbox APIs.
- macOS
git/usr/bin/sandbox-exec(present on current macOS releases)
Download the latest release from GitHub:
curl -fsSL https://github.com/srdjan/macbox/releases/latest/download/install.sh | bashOr install manually:
# Download binary and profiles
curl -fsSL -o /tmp/macbox https://github.com/srdjan/macbox/releases/latest/download/macbox
curl -fsSL -o /tmp/profiles.tar.gz https://github.com/srdjan/macbox/releases/latest/download/profiles.tar.gz
# Install to /usr/local (requires sudo)
sudo install -m 755 /tmp/macbox /usr/local/bin/macbox
sudo mkdir -p /usr/local/share/macbox
sudo tar -xzf /tmp/profiles.tar.gz -C /usr/local/share/macbox
# Or install to ~/.local (no sudo)
install -m 755 /tmp/macbox ~/.local/bin/macbox
mkdir -p ~/.local/share/macbox
tar -xzf /tmp/profiles.tar.gz -C ~/.local/share/macboxYou can override profile search with MACBOX_PROFILES_DIR=/path/to/profiles.
The --prompt flag is required. Agent is resolved from: preset > macbox.json defaults > auto-detect.
# Direct prompt - runs in pipe mode and exits when done
macbox --prompt "fix the build"
macbox --prompt "refactor the auth module"
# With a preset for a complete workflow configuration
macbox --preset fullstack-typescript --prompt "add dark mode support"
# Pass extra flags through to the agent after --
macbox --prompt "fix the build" -- --verboseAuthentication is automatic: macbox checks for credentials on first use and runs the agent's setup flow if needed.
All advanced flags are accepted but hidden from primary help. Use macbox --help-all to see the full reference.
# Named worktree
macbox --prompt "fix the build" --worktree my-feature
# From a specific branch
macbox --prompt "fix the build" --branch feature/login
# Custom executable (if your agent isn't on PATH)
macbox --prompt "fix the build" --cmd /opt/homebrew/bin/claude
# Compose additional profiles into the sandbox
macbox --prompt "fix the build" --profile host-tools
macbox --prompt "fix the build" --profile host-tools,host-ssh
# Collect sandbox denial logs
macbox --prompt "fix the build" --tracemacbox clean --worktree ai
macbox clean --allInside the sandbox:
HOMEis set to<worktree>/.macbox/homeXDG_CONFIG_HOMEis set to<worktree>/.macbox/home/.configXDG_CACHE_HOMEis set to<worktree>/.macbox/cacheTMPDIRis set to<worktree>/.macbox/tmpPATHis set to/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbinDENO_DIRis set to<worktree>/.macbox/cache/denoNPM_CONFIG_CACHEis set to<worktree>/.macbox/cache/npmYARN_CACHE_FOLDERis set to<worktree>/.macbox/cache/yarnPNPM_HOMEis set to<worktree>/.macbox/home/.local/share/pnpmGIT_CONFIG_GLOBALis set to<worktree>/.macbox/home/.gitconfigGIT_CONFIG_SYSTEMis set to/dev/null- Read/exec of system paths is allowed (including Homebrew)
- Read/write is limited to:
- The worktree path
- The repo's git dirs needed for worktree operation (
git-common-dir+git-dir) /devand a minimal temp area
Network is allowed by default. Disable it with --block-network (alias: --no-network).
macbox defaults to a "friendly" sandbox: network + subprocess execution are allowed, while file writes are restricted to the worktree and a few safe temp roots.
Override capabilities per run:
--allow-network/--block-network(alias:--no-network)--allow-exec/--block-exec--allow-fs-read <p1[,p2...]>- additional read-only paths--allow-fs-rw <p1[,p2...]>- additional writable paths (triggers a warning if outside worktree/git dirs)
Examples:
# Disable network
macbox --prompt "fix the build" --block-network
# Add read-only host toolchain paths
macbox --prompt "fix the build" --allow-fs-read=/usr/local,/opt/homebrew
# Add a writable scratch path (discouraged)
macbox --prompt "fix the build" --allow-fs-rw=/tmp/my-scratchSome toolchains are installed in user-owned locations (e.g. ~/.local/bin, ~/.nvm, ~/.asdf).
By default, macbox does not grant sandbox access to your host home directory.
When you choose to relax that, compose profile snippets via --profile name[,name2...].
Profile search order:
$MACBOX_PROFILES_DIR/<name>.json(if set)~/.config/macbox/profiles/<name>.json- Bundled profiles next to the binary (or
<prefix>/share/macbox/profiles)
You can also pass a direct file path (e.g. --profile ./myprofile.json).
List and inspect profiles:
macbox profiles list
macbox profiles show host-tools
macbox profiles show agent-claudeProfiles can grant write access outside the worktree. macbox warns on stderr when a profile adds writes outside the worktree/git dirs.
macbox ships bundled profiles that are auto-applied based on the resolved agent:
agent-claude: enables Mach service lookups (so Keychain/system IPC works).agent-codex: enables Mach service lookups.CODEX_HOME=$HOME/.codexis set by macbox's environment setup (env.ts), not by the profile itself.
Presets bundle agent configuration, profiles, capabilities, and environment variables into reusable templates. Use them to define complete development workflow configurations.
macbox presets list
macbox presets show fullstack-typescript# Run with a preset - applies agent, profiles, capabilities, and env vars
macbox --preset fullstack-typescript --prompt "add dark mode support"
# CLI flags override preset defaults
macbox --preset fullstack-typescript --prompt "fix the build" --block-networkmacbox ships with one example preset:
fullstack-typescript: Node.js and Deno toolchains,host-toolsprofile,NODE_ENV=development
Create or edit preset JSON files directly in ~/.config/macbox/presets/:
{
"name": "my-preset",
"description": "My custom development preset",
"agent": "claude",
"profiles": ["host-tools", "host-ssh"],
"capabilities": {
"network": true,
"exec": true,
"extraReadPaths": ["/opt/homebrew", "~/.nvm"],
"extraWritePaths": []
},
"env": {
"NODE_ENV": "development"
},
"worktreePrefix": "ai-mypreset",
"startPoint": "main"
}Preset search order:
$MACBOX_PRESETS_DIR/<name>.json(if set)~/.config/macbox/presets/<name>.json- Bundled presets next to the binary (or
<prefix>/share/macbox/presets)
Preset fields:
name: Preset identifier (string)description: Human-readable description (string, optional)agent:claude,codex, orcustom(optional, defaults to auto-detect)profiles: Array of profile names to compose (optional)capabilities: Network, exec, and filesystem permissions (optional)network: boolean (default: true)exec: boolean (default: true)extraReadPaths: array of additional read-only pathsextraWritePaths: array of additional writable paths
env: Environment variables to inject into the sandbox (optional, object)worktreePrefix: Default worktree name prefix (optional, e.g.ai-mypresetbecomesai-mypreset-1)startPoint: Default git ref for new worktrees (optional, default:HEAD)
macbox persists a session record per repo/worktree so you can quickly re-open a sandbox with the same defaults.
Sessions are stored under <base>/sessions/<repoId>/<worktree>.json (default base: ~/.local/share/macbox).
You can pass --session to reuse a saved worktree and defaults.
macbox sessions list
macbox sessions list --repo . # current repo onlymacbox sessions show latest # latest session (global)
macbox sessions show latest --repo . # latest for this repo
macbox sessions show <repoId/worktreeName>macbox sessions clean --repo . # delete sessions for current repo
macbox sessions clean --all # delete all sessions
macbox sessions delete <id> # delete a specific sessionWorkspaces provide named worktrees with associated session metadata. They are lightweight records that map a human-readable name to a worktree and session.
# Create a workspace
macbox workspace new --name feature-auth
# With a preset
macbox workspace new --preset fullstack-typescript --name my-featuremacbox workspace list # workspaces for current repo
macbox workspace show <id>The alias macbox ws is shorthand for macbox workspace.
macbox workspace open <id> # prints session infoWorkspaces are stored under <base>/workspaces/<repoId>/<workspaceId>.json.
Configure project-level defaults by creating a macbox.json file at your repo root:
{
"schema": "macbox.config.v1",
"defaults": {
"agent": "claude",
"preset": "fullstack-typescript",
"profiles": ["host-tools"]
}
}The defaults section supports:
agent: Default agent (claude,codex, orcustom)preset: Default preset nameprofiles: Array of additional profile names to compose
Seatbelt violations do not reliably appear on stderr/stdout - they're recorded in the macOS unified log.
--debug enables (debug deny) in the generated SBPL profile so denials are logged by the system. This is useful when you want to inspect logs yourself.
--trace includes everything --debug does, plus:
- After the command exits, queries the unified log for sandbox denial events
- Writes the output to
<worktree>/.macbox/logs/sandbox-violations.log
Git worktrees store metadata outside the worktree (under the main repo's .git/).
To keep git status/commit working inside the sandbox, macbox allows access to:
git rev-parse --git-common-dirgit rev-parse --git-dir
These are limited to this repo only (not your whole home directory).
For autonomous iteration over PRDs with quality gates and multi-agent collaboration, use ralph-cli:
# Ralph orchestrates multiple macbox invocations
ralph prd.json --gate "typecheck:deno check src/main.ts" --gate "test:deno test -A"Ralph is a separate tool that wraps macbox for complex autonomous workflows.
Requires Deno.
deno task dev -- --helpOr run directly:
deno run -A src/main.ts --help# Run an agent (--prompt is required)
deno run -A src/main.ts --prompt "fix the build"
deno run -A src/main.ts --preset fullstack-typescript --prompt "add dark mode"
# List sessions
deno run -A src/main.ts sessions list --repo .
# Workspaces
deno run -A src/main.ts workspace new --name my-feature
deno run -A src/main.ts ws listCompile a standalone macOS binary:
deno task compile:mac # default (current arch)
deno task compile:mac-arm # Apple Silicon (aarch64)
deno task compile:mac-x64 # Intel (x86_64)
deno task compile:mac-universal # Universal binary (both archs via lipo)Install using the install script:
sudo ./scripts/install.sh
# or without sudo:
PREFIX="$HOME/.local" ./scripts/install.sh