ворса✻
Run your agents in lightweight VMs on macOS. Super fast containers, with the hardware-level security enforcement of virtual machines. Opinionated workflow built on workmux and tmux. Just one command to get started.
Quick Start | Why bopca? | Installation | Usage | Documentation
$ brew install cboone/tap/bopca # Install
$ cd ~/Development/my-repo # Open your repo
$ bopca # Run bopca
# A fresh container builds and runs, your repo is mounted,
# tmux opens, and workmux and your agents are ready to go.See Usage and Getting Started for more.
Note
TL;DR: It's fast af. It's optimized for two workflows, single agent and multi-parallel singles, duos, or swarms. Rather than go wide and provide something for everyone, bopca goes deep and provides a lot for a few.
Or: Do you like workmux or other tmux-based parallel development workflows using Git worktrees? bopca is the easiest way to add hardware-level security.
There are many ways to keep your system safe from errant LLMs. This is the way I do it: as simple and lightweight and automatic as possible. bopca integrates with workmux and tmux, so with one command my whole dev environment is loaded and ready to go.
It takes advantage of macOS 26's enhancements to the Virtualization framework and the Containerization package. An optimized Linux kernel with a lightweight init system allow for sub-second startups. bopca adds to that with customizable containers and great defaults, easy configuration, and tools to help you manage your containers.
The container mirrors your host filesystem layout: your workspace is mounted at its actual host path, the worktrees directory is where it should be, and $HOME inside the container matches your host $HOME. This means your configs and muscle memory all work unchanged. bopca both pays attention to your workmux.yaml and provides matching options: configure the panes that open in tmux on launch and the commands that run in them.
If you prefer a simpler workflow, always or on a per-repo basis, bopca works great out of the box too, no additional tooling needed. It works as well with one repo and one LLM as it does with many repos, many worktrees, and many agents each. Your choice.
Read more about the basic workflow, the underlying technology, security benefits, configurable security levels, and how bopca compares to other approaches. Also take a look at the current limitations and the roadmap.
All the docs are available here as well as on bopca.sh. Shell completions and man bopca work too, once it's installed.
You need:
- Apple Silicon
- macOS 26 Tahoe (sorry, Liquid Glass, I know, I know)
- A subscription or API key for Claude Code or any one of the model providers that OpenCode supports
- Apple's
containertool (either installed automatically by Homebrew or manually by downloading a binary)
brew install cboone/tap/bopcacontainer installs automatically.
curl -fsSL https://raw.githubusercontent.com/cboone/bopca/main/scripts/install.sh | shThe script installs the binary, shell completions, and man pages.
Required: Install container by downloading a binary.
Download the latest release binary from GitHub Releases:
curl -fsSL https://github.com/cboone/bopca/releases/latest/download/bopca-darwin-arm64.tar.gz | tar xz
mv bopca ~/.local/bin/Required: Install container by downloading a binary.
go install github.com/cboone/bopcaRequired: Install container by downloading a binary.
Note: go install only installs the binary. For shell completions and man pages, see the detailed installation instructions.
git clone https://github.com/cboone/bopca
cd bopca
make build
cp ./bin/bopca ~/.local/binFor a full installation including completions and man pages:
make install-allDefaults | Basic workflows | Configuration | Networking
$ cd ~/Development/my-repo # Open your repo
$ bopca # Run bopcaThe first time you run bopca, it builds your container image (read more about the containers, what they include, and how to customize them), runs it, mounts your repo at its actual host path, and drops you into zsh inside a tmux session. Claude Code and OpenCode are installed and ready.
Your home directory paths are mounted into the container too, so your shell config, Git config, SSH keys, and agent credentials all work as expected. No setup needed. By default your workspace (the repo directory you launch from) is mounted read-only, and your worktrees directory is mounted read-write. Another detail that makes it easier to run your agents in YOLO mode without worrying too much. (You should always worry a little.)
Out of the box, bopca automatically infers as much about your repo and workflow setup as it can. It tries to determine the toolchain(s) your project needs, for example; if it can't, you can always specify toolchains explicitly with --toolchains or via configuration to match your needs.
bopca is optimized for two basic workflows. (Though many permutations are possible.) One is parallel development: multiple features branches, each in their own worktree and tmux window, one or more agents per branch / worktree / window. The other is more focused: working directly in the repo (no worktrees), with one or more agents working on the branch you have checked out.
For most projects / repos, I do some variation of this. (See below for customization options.) This is the workflow I've been using for a while now; bopca adds layers of security on top of it, with minimal additional overhead.
# Open the repo.
$ cd ~/Development/safety-third
# Run bopca: Container runs, workspace mounts
# read-only and worktrees mount read-write, personal
# config mounts, shell opens with tmux running and
# the set of panes I've configured for that repo
# open and the default commands running. `claude`
# is configured to run in YOLO mode.
$ bopca
# Create a new feature branch inside a new worktree.
# Open a tmux window with that repo's pane configuration
# open and default commands running.
$ workmux add feature/have-fun
# Open the worktree in VSCode outside the container.
$ code
# Get to work. Use workmux to manage branches, worktrees,
# and tmux windows.Sometimes I just need to get a thing done in a repo, no major project or multi-agent interaction involved. If there's a repo in which I always want to work this way, it's easy to save this as the default in the project-level config. If it's just a one-off task, that's easy too.
# Open the repo.
$ cd ~/Development/safety-third
# Run bopca in non-worktree mode.
# zsh opens in your workspace mounted read-write.
# Normal development, just safer.
$ bopca --no-worktrees
# Open the repo in VSCode outside the container.
$ code
# Get to work.You can dial in your settings via command options or in project-level or user-level config files.
# .bopca.yaml
tmux: falsebopca follows workmux's pane config format.
# .bopca.yaml
startup_panes:
- command: claude
focus: true
- split: vertical # No command specified means zsh
percentage: 25Use YOLO mode to skip agent permission prompts. When enabled, bopca injects shell wrappers in the container so agent commands like claude automatically run with their permission-skipping flags. On the first run in a repo, bopca asks your preference and remembers it per-repo.
# Enable for this run
$ bopca --yoloFor more safety, turn it off and use the default agent behavior.
# Disable for this run
$ bopca --bardo
$ bopca --safely-ask-for-permissionSee Configuration for all options.
One of the nice things about using Apple's container system is that your container gets its own local network address automatically. If you configure the container tool's DNS system, you get automatic hostnames based on the name of your repo.
Complete the one-time DNS setup:
sudo container system dns create test
container system property set dns.domain testOnce you've done this, bopca will recognize that your system is configured and will make your container available at:
http://my-repo.test
Just make sure your server is listening to the normal ports for what you're doing (443 for https, for example). No port forwarding needed.
See Networking and Configuration for more.
| Getting Started | Installation, requirements, and first run |
| About | Project motivations, goals, and design principles |
| Commands | Full command and option reference |
| Comparisons | How bopca compares to other sandboxing approaches |
| Configuration | YAML configuration options |
| Containers | Container details, base image, and pre-installed tools |
| Development | Development setup and guidelines |
| Integrations | VSCode, tmux, and workmux |
| Networking | DNS hostnames and container networking |
| Roadmap | Future plans and feature roadmap |
| Security | Security model and secret scanning |
| Security Levels | The containerized agent security spectrum |
| Technology | Virtualization framework and security benefits |
| Troubleshooting | Common issues and solutions |
| Workflows | Common usage patterns and examples |
macOS only: Requires macOS 26 Tahoe on Apple Silicon.
Linux containers only: Apple's Virtualization framework currently only supports Linux containers (not macOS containers, though that's a common request).
Networking: Controls over networking are limited, due to the current limitations of the container tool. If you're concerned about exfiltration from your repo, there are manual steps you can take. See Networking Access Control for more.
Secrets management: bopca integrates gitleaks to help you prevent leaking secrets, but currently doesn't provide any method to safely inject secrets. See the Roadmap for future improvements in this regard.
File Issues or create Discussions to share your ideas and let me know about any bugs you've found. Thanks!
Contributions are welcome! See Development and Contributing for development setup and guidelines.
In the Dungeon Crawler Carl series, by Matt Dinniman, Bopca Protectors are gnome-like aliens that guard the dungeon safe rooms. Stout, green, hairy, shaggy, and smelling of moss.✻ (Here's a fan illustration.) This is where I stole the name from. But it turns out there's an even more interesting backstory to it.
The name bopca comes from the word Вӧрса, a forest spirit in Komi mythology. (The Komi peoples have lived in the northeastern-most corner of Europe, at the western edge of the Urals, since at least the first millennium BCE.) It's a Komi word, and since it's written in Cyrillic, it's properly pronounced something like "versa", or [ˈvɘr.sa].
Vorsa is the Komi parallel of the Slavic Leshy. A creature of folktales, they were protectors of the forests, taking the forms of gods, giants, shepherds, animals, mosses, and other forest spirits. Fierce when protecting the forest, benevolent and just with those entering it peacefully.
I am not Komi, nor Slavic. I do not speak any of the relevant languages. I have not even been to that part of the world. This is, therefore, pure cultural appropriation, and all I can say in my defense is that I thought I was appropriating the name of a fictional alien race who really should wash their hands more often.
MIT License. TL;DR: Do whatever you want with this software, just keep the copyright notice included. The authors aren't liable if something goes wrong.
