Getting Started with DynoCap
Install DynoCap on an Apple Silicon Mac, prepare one project, and run a command inside an isolated Linux guest.
You will:
- Install the CLI with Homebrew, or with curl.
- Check your setup with
dynocap doctor. - Repair it with
dynocap doctor --fix. - Launch a raw sandbox and execute commands over vsock.
- Safely destroy the sandbox.
Prerequisites
- Hardware: Apple Silicon Mac (M1 or newer). Intel Macs are refused by the installers.
- Operating System: macOS 13 (Ventura) or newer.
- Homebrew, for the primary install. The formula also installs
e2fsprogs, which providesmke2fs. That formula is keg-only; DynoCap finds it at/opt/homebrew/opt/e2fsprogs/sbin/mke2fs. - Go 1.22+ (
brew install go) the first time a runtime is prepared. The guest image ships in the release archive, so a Homebrew or curl install does not need Go to copy it. Swift and Node are for a source build and for this repository’s TypeScript packages.
Step 1: Install
DynoCap uses Apple’s Virtualization.framework, which requires the com.apple.security.virtualization entitlement. There is no Apple Developer ID signature. Both installers re-sign the CLI on your Mac with codesign --sign - and the bundled entitlement. Neither installer uses a Homebrew bottle, because a poured bottle would skip that re-sign.
Homebrew
brew install baires/tap/dynocapThat installs the formula from baires/homebrew-tap. On Homebrew 6, this fully qualified name trusts that formula.
Trust it explicitly when you want later commands to use the short name dynocap, such as brew upgrade dynocap:
brew trust --formula baires/tap/dynocapThe formula downloads the versioned release archive, checks its sha256, and re-signs dynocap. Then run doctor in your project, which the formula also prints as a caveat:
dynocap doctor --fixCurl
curl -fsSL https://dynocap.dev/install.sh | shThe site serves scripts/install.sh. The script downloads dynocap-darwin-arm64.tar.gz from the latest GitHub release, checks its sha256, installs it under ~/.local/dynocap, and symlinks ~/.local/bin/dynocap. The checksum catches a truncated download. When gh is installed and logged in, the script also requires a build attestation from baires/dynocap. Its last step is dynocap doctor --fix. If mke2fs is missing, it tells you to run brew install e2fsprogs. If ~/.local/bin is not on PATH, it tells you to add it.
From source
A checkout has no bundled guest image. Building needs Xcode Command Line Tools (Swift 5.9+), Go 1.22+, and mke2fs (brew install e2fsprogs).
./scripts/build-macos.sh
export PATH="$PWD/.build/release:$PATH"Re-run ./scripts/build-macos.sh after every rebuild so the binary stays signed. npm ci is for the repository’s TypeScript packages, not for the CLI.
Step 2: Check Your Setup
Go to your project and run dynocap doctor. It checks the platform, code signing, companion binaries, guest image, runtime, and daemon, and changes nothing:
cd ~/code/my-app
dynocap doctorDoctor reads your project’s files to pick its runtime, the same way clone does:
| File at the project root | Runtime |
|---|---|
package.json |
node:24 |
pyproject.toml, uv.lock, requirements.txt, setup.py, Pipfile |
python:3.14 |
go.mod |
go:1.27 |
On a fresh source build, the guest image and runtime are not built yet. A Homebrew or curl install already contains the guest image, and --fix copies it into your home. Each failure says what is wrong and what to run:
ERROR images The guest image for aarch64 has not been built yet.
Next: Run dynocap doctor --fix to build the guest image (downloads pinned Alpine files; needs Go).
ERROR runtime Runtime python:3.14 is not prepared for aarch64 yet. This project's pyproject.toml needs it.
Next: Run dynocap doctor --fix to prepare python:3.14 (downloads verified inputs; takes a few minutes).
2 required checks failed. Run dynocap doctor --fix to repair them.To prepare a different runtime, pass --runtime, for example dynocap doctor --fix --runtime node:22. Run outside a project, doctor requires no runtime. It lists the prepared ones instead, because raw sandboxes need none.
Step 3: Repair It with doctor --fix
dynocap doctor --fix--fix copies a bundled guest image when the install has one, and builds it otherwise. It prepares your project’s runtime and restarts a daemon left over from an older build. Every download is pinned and verified. It then runs the checks again and ends with Required checks passed.
Doctor finds that prefix from the dynocap binary, whether it is a source checkout or a Homebrew or curl install, so you can run it in any directory. You can also name the project instead of changing directory: dynocap doctor --fix ~/code/my-app.
Tip: After you rebuild
dynocap, rundynocap doctor --fixagain. It restarts the daemon so it runs the new build.
Step 4: Boot a Raw Sandbox
A raw sandbox boots the minimal Alpine Linux image without importing a project workspace.
Start a sandbox named my-first-box:
dynocap run --name my-first-boxOutput:
running my-first-boxBehind the scenes:
- The
dynocapCLI launched the per-user background daemon (~/.dynocap/daemon.sock). - The daemon booted a Linux virtual machine with 1 vCPU and 1024 MB RAM via Virtualization.framework.
- The guest booted its initramfs in under 200ms and launched the internal Go
dynocap-agent. - The agent connected back over
virtio-vsock(guest port 5252).
Verify the sandbox status:
dynocap psYou will see:
NAME/ID KIND PHASE RUNTIME NETWORK TTL RETENTION
my-first-box sandbox running minimal none 29m -Notice that NETWORK is none. The sandbox is completely offline. No network interface exists inside the guest.
Step 5: Execute Commands Inside the Sandbox
Run commands inside your guest with dynocap exec:
dynocap exec my-first-box -- uname -aOutput:
Linux dynocap 6.18.62-0-virt #1-Alpine SMP PREEMPT_DYNAMIC aarch64 LinuxTest running an isolated shell command:
dynocap exec my-first-box -- sh -c "echo 'Hello from DynoCap' && id"Output:
Hello from DynoCap
uid=0(root) gid=0(root) groups=0(root)DynoCap streams stdout and stderr separately, and exits with the exact status code returned by the guest command.
Step 6: Destroy the Sandbox
When your work is done, remove the sandbox:
dynocap rm my-first-box --forceOutput:
removed my-first-boxBecause my-first-box was actively running, --force explicitly confirms discarding running processes. The daemon terminates the virtual machine and cleans up runtime descriptors.
Next Steps
Now that the CLI is installed and a raw sandbox runs, proceed to:
- End-to-End Agent Task Workflow: Copy a project into a task, install from a dependency seed, and export a verified diff. The host checkout is never mounted.
- Interactive Shells & Terminal Sessions: Learn how to attach interactive TTY sessions for live debugging.
This page is also plain Markdown, for agents and for you.