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
# Force a fresh worktree instead of reusing the latest session
macbox --prompt "fix the build" --new-worktree
# 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
# Keep Claude isolated from host ~/.claude (requires ANTHROPIC_API_KEY)
macbox --prompt "fix the build" --no-host-claude-profile
# 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" --trace
# Machine-readable management output
macbox sessions list --json
# Subcommand help (plain + JSON)
macbox workspace new --help
macbox sessions show --help --jsonSubcommand help is available in two forms:
macbox <group> <subcommand> --helpmacbox <group> help <subcommand>
When combined with --json, help output is machine-readable using these
schemas:
macbox.sessions.usage.v1macbox.profiles.usage.v1macbox.presets.usage.v1macbox.workspace.usage.v1
macbox 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 avoids granting sandbox access to your
host home directory. For Claude, macbox auto-enables host-claude unless you
pass --no-host-claude-profile.
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-claude
macbox profiles help showProfiles 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.host-claude(auto-enabled for Claude by default): grants read/write access to~/.claudefor Claude CLI session/auth state. Disable with--no-host-claude-profile.
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
macbox presets help show# Run with a preset - ap
8000
plies 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. If you do not
pass --worktree or --session, macbox may reuse the latest session worktree
for the resolved agent. Use --new-worktree to force a fresh worktree.
macbox sessions list
macbox sessions list --repo . # current repo only
macbox sessions list --json # machine-readable output
macbox sessions help showmacbox 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-feature
# Subcommand help
macbox workspace help newmacbox workspace list # workspaces for current repo
macbox workspace show <id>
macbox workspace show --help --jsonThe alias macbox ws is shorthand for macbox workspace.
macbox workspace open <id> # prints session info
macbox workspace help openWorkspaces 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 # In
6906
tel (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