An opinionated, containerized environment for running TUI coding agents in YOLO mode, with Chrome and Flutter integrations, selective persistence, and isolated GPG-signed commits.
Supports Claude Code, OpenCode, Codex, and Pi, selectable per launch. It is geared toward Rust, Python, TypeScript, and Dart/Flutter development. A global context file is symlinked into each agent config so the agent is aware of the sandbox's capabilities and constraints.
- Chrome integration - host Chrome control for web development.
- Flutter integration - in-container SDK and host bridge for native/device Flutter work.
- GPG setup - verified Git commits from inside the workcell.
- Docker installed
- macOS, Linux, or WSL2
Optional integrations have their own host requirements:
- Chrome integration requires Google Chrome and
socat. - Flutter bridge integration requires the Flutter SDK and at least one configured target on the host.
- GPG signing requires
GIT_AUTHOR_NAME,GIT_AUTHOR_EMAIL, andGPG_SIGNING=trueinconfig.sh.
Add this to your ~/.zshrc:
alias workcell="/path/to/agent-workcell/cli.sh"Replace /path/to/agent-workcell with the actual path to this repository, then reload your shell:
source ~/.zshrcRun the workcell with a selected agent to build its sandbox image on demand:
workcell run opencodeSee Run Agents below for the other agent commands. Each harness has its own native authentication flow when credentials are needed.
Copy the config template before enabling optional integrations:
cp config.template.sh config.shThen follow the focused setup guide you need:
config.sh is gitignored so personal paths, ports, and identities are not committed.
# Build all agent images
workcell build
# Or build one agent image plus the shared base
workcell build piworkcell build runs docker compose build from the workcell repository root, so it works even
when you invoke workcell from another directory. workcell build all builds all four agent
images; targeted builds accept claude, opencode, codex, or pi.
Navigate to any project directory and run:
# Normal mode
workcell run claude
workcell run opencode
workcell run codex
workcell run pi # Pi does not use permission prompts by default
# YOLO mode (no permission prompts)
workcell run claude --yolo
workcell run opencode --yolo
workcell run codex --yolo
# Firewalled mode (restricted network access)
workcell run codex --firewalled
# With a prompt
workcell run claude --yolo -p "fix the tests"
# Pass agent-specific arguments
workcell run claude --resume
workcell run opencode run "summarize the repo"
workcell run codex "fix the tests"
workcell run pi -p "summarize the repo"The first positional arg after run selects the agent and is required: claude, opencode,
codex, or pi. Each agent uses its own sandbox image and persistent Docker volume, plus a
shared GPG volume. If the selected image is missing, workcell run <agent> builds that agent image
and the shared base automatically.
--with-chrome and --with-flutter are mutually exclusive. --port exposes container dev
servers to the host in all modes. In Flutter mode, use --bridge-port to select the host Flutter
bridge port. If the Flutter project is in a workspace subdirectory, pass
--flutter-project-dir ./gui.
--yolo maps to each agent's native bypass where one exists:
- claude:
--dangerously-skip-permissions - opencode:
{"permission":"allow"}injected throughOPENCODE_CONFIG_CONTENT - codex:
--dangerously-bypass-approvals-and-sandbox - pi: ignored because Pi does not ask for permissions by default; the container is the permission boundary
Running workcell or workcell run without an agent exits with a usage error instead of choosing
an agent implicitly.
workcell run codex --yoloSee Integrations for Chrome, Flutter, and port examples.
# Chrome enabled for web development
workcell run claude --with-chrome
workcell run codex --yolo --with-chrome --port 3000
# Expose container dev-server ports to the host
workcell run opencode --port 3000
workcell run codex --port 3000 --port 5173
# Start Chrome independently on the host
workcell start-chrome
workcell start-chrome --restart
workcell start-chrome --port 9333 --profile "Profile 1"
# Flutter native/device bridge
workcell run claude --with-flutter
workcell run codex --with-flutter --bridge-port 8765
workcell run codex --with-flutter --flutter-project-dir ./gui
workcell run codex --with-flutter --bridge-port 8766 --port 3000
# Start the Flutter bridge independently on the host
workcell start-flutter-bridge
workcell start-flutter-bridge --port 8766 --project ~/my-flutter-app
workcell start-flutter-bridge --flutter-project-dir ./guiSee Chrome integration and Flutter integration for setup details.
workcell settings claude
workcell settings opencode
workcell settings codex
workcell settings piThese commands open an agent's config file in vi inside the workcell Docker volume. The agent
argument is required to avoid accidentally editing the wrong file.
workcell gpg-new
workcell gpg-export --file my-key-backup.asc
workcell gpg-import --file my-key-backup.asc
workcell gpg-revoke --file revoke.asc
workcell gpg-eraseSee GPG setup for key setup, backup, and rotation guidance.
workcell opencode-sessions-export
workcell opencode-sessions-importThese commands export and import OpenCode sessions between the Docker volume and
.workcell/opencode-sessions/.
# Open a shell in a specific volume
workcell volume-shell codex
workcell volume-shell gpg
# Backup all workcell volumes
workcell volume-backup --file agent-workcell-bkp.tgz
# Restore all workcell volumes from backup
workcell volume-restore --file agent-workcell-bkp.tgz
# Remove a specific volume scope, or all scopes
workcell volume-rm codex
workcell volume-rm allVolume commands affect the persisted user data described below.
- Your current directory is mounted at
/workspaces/<project-name>inside the container. - Workspace-local workcell files for the current project live under
.workcell/. - Claude session history for the project is stored in
.workcell/claude-sessions/. - OpenCode session history and storage persist in the Docker volume under
~/.local/share/opencode/. - Codex auth, config, history, logs, and session data persist under
~/.codex/, with project conversation files bind-mounted into.workcell/codex-sessions/. - Pi auth, settings, packages/extensions, and the persisted Pi install prefix live in the Docker
volume under
~/.pi/agent/, with project sessions bind-mounted into.workcell/pi-sessions/. - Agent settings, credentials, Rust toolchains, Node versions, and language caches persist in the
selected agent's Docker volume (
agent-workcell-claude,agent-workcell-opencode,agent-workcell-codex, oragent-workcell-pi). - GPG keys persist in the shared
agent-workcell-gpgDocker volume. - The container runs as a non-root
agentuser. - Filesystem access is isolated to the mounted project directory.
- Host services are reachable from the container through
host.docker.internal. - Dev server ports can be exposed with
--port <port>. /opt/agent-context.mdis symlinked as~/.claude/CLAUDE.md,~/.config/opencode/AGENTS.md,~/.codex/AGENTS.md, and~/.pi/agent/AGENTS.md; focused tool-specific context docs are available at/opt/agent-context-web.mdand/opt/agent-context-flutter.md.
User-level data is split across per-agent Docker volumes. The selected agent volume is mounted at
/home/agent/persist inside the container, and the shared GPG volume is mounted at
/home/agent/persist/.gnupg.
Volumes:
agent-workcell-claudeagent-workcell-opencodeagent-workcell-codexagent-workcell-piagent-workcell-gpg(shared signing keys only)
Important persisted paths include:
~/.claude/- Claude Code credentials, settings, and global context.~/.config/opencode/- OpenCode configuration and global context.~/.local/state/opencode/- OpenCode local UI state.~/.local/share/opencode/- OpenCode auth, logs, database, and storage.~/.codex/- Codex auth, config, history, logs, and global context.~/.pi/agent/- Pi settings, auth, packages/extensions, persisted Pi install prefix, and global context. Current-project Pi sessions are bind-mounted from.workcell/pi-sessions/.~/.rustup/and~/.cargo/- Rust toolchains, registry cache, and installed binaries.~/.gnupg/- GPG keys for commit signing when enabled; stored inagent-workcell-gpg.~/.nvm/- Node.js versions and global npm packages.~/.flutter/- Flutter CLI config and version state.~/.pub-cache/- Dart pub package cache shared across projects.
Image-owned tool binaries and SDKs, including Flutter under /opt/flutter-sdk, Claude Code
version payloads, OpenCode, the default Pi install under /opt/pi, and protobuf CLIs, update with
the sandbox image. The entrypoint sets up symlinks so each tool still sees its expected home
directory paths without using stale persisted binary copies. Pi runs on the active nvm Node at
runtime. Pi package/extension updates persist under ~/.pi/agent/; the entrypoint seeds Pi's
own install prefix under ~/.pi/agent/self/ from the image on first run, so native pi update
self-updates write to the persisted volume instead of ephemeral /opt/pi. Once a persisted Pi
copy exists, the sandbox keeps using it and leaves further version upgrades to explicit user-run
pi update commands.
Security note. Agent credentials are stored as plaintext inside Docker volumes. Treat
agent-workcell-*volumes and their backups as sensitive.
Each project gets a .workcell/ directory for project-scoped agent state:
.workcell/artifacts/- temporary agent artifacts such as screenshots, logs, traces, and generated previews. Agents may create optional subdirectories such asscreenshots/,logs/, andmockups/when that helps organize related files. Use timestamped filenames such asscreenshots/20260429-132400-home-page.png..workcell/claude-sessions/- bind-mounted Claude project sessions..workcell/opencode-sessions/- exported OpenCode session backups..workcell/codex-sessions/- workspace-local Codex conversation files..workcell/pi-sessions/- bind-mounted Pi project sessions..workcell/.env- optional workspace-local environment variables to define for sandboxed agents..workcell/tasks/- multi-agent task files and scratch notes..workcell/flutter-config.json- project-local Flutter bridge launch and connection settings when Flutter integration is used.
Example .workcell/ layout:
.workcell/
├── .gitignore
├── .env
├── artifacts/
│ ├── screenshots/
│ ├── logs/
│ └── mockups/
├── claude-sessions/
├── codex-sessions/
├── opencode-sessions/
├── pi-sessions/
├── tasks/
└── flutter-config.json
On first run, the launcher creates .workcell/.gitignore if it does not already exist:
.DS_Store
.env
flutter-config.json
artifacts/When .workcell/.env exists, workcell run <agent> parses it as dotenv-style KEY=VALUE
entries and passes the values into the sandboxed agent environment. Blank lines and comments are
ignored, export KEY=VALUE is accepted, quoted values are unquoted, and invalid lines stop the
launch with an error. Launcher-controlled variables such as the selected agent, timezone, exposed
ports, and integration settings take precedence over duplicate names in .workcell/.env.
It is recommended to gitignore .workcell/ in the parent project repository. If you want version
control for local agent state, initialize a separate Git repository inside .workcell/.
OpenCode stores its live session database in the Docker volume. Export sessions to workspace-local JSON files before removing the volume. See OpenCode sessions.
| Category | Tools |
|---|---|
| Languages | Node.js LTS through nvm, Python 3.11, Rust stable |
| Node.js | nvm, npm, npx |
| Agents | claude, opencode, codex, pi |
| Python | pyright, ruff, playwright, matplotlib, numpy |
| Browser | Chrome automation support |
| Flutter SDK | flutter, dart — tests, analysis, formatting, pub (in-container, no host setup) |
| Flutter Bridge | flutterctl — launch, hot-reload, screenshots, and macOS-hosted macOS/iOS Simulator UI automation via host bridge |
| Protobuf | protoc, buf, protoc-gen-dart, protoc-gen-prost, grpcurl |
| Database | psql |
| Utilities | git, curl, wget, jq, yq, ripgrep, fd |
Use --firewalled to restrict network access to essential agent and tooling domains:
- Anthropic API
- OpenAI / Codex
- OpenCode, including Zen and Go
- Pi
- JavaScript and TypeScript package registries
- Dart and Flutter package registry
- Rust package registries and docs
- GitHub
This reduces the risk of data exfiltration while still allowing agents to fetch docs and install packages.
agent-workcell/
├── README.md
├── docs/
│ ├── chrome-integration.md
│ ├── flutter-integration.md
│ └── gpg-setup.md
├── docker-compose.yml
├── cli.sh
├── config.template.sh
├── config.sh
├── scripts/
│ ├── run_sandbox.sh
│ ├── start-chrome-debug.sh
│ ├── start-flutter-bridge.sh
│ └── flutter-bridge.py
└── sandbox/
├── agent-context.md
├── agent-context-web.md
├── agent-context-flutter.md
├── agent-init/
│ ├── claude.sh
│ ├── codex.sh
│ ├── opencode.sh
│ └── pi.sh
├── dockerfiles/
│ ├── base.Dockerfile
│ ├── claude.Dockerfile
│ ├── codex.Dockerfile
│ ├── opencode.Dockerfile
│ └── pi.Dockerfile
├── entrypoint.sh
├── init-firewall.sh
├── browser-tools/
└── flutter-tools/
This project is licensed under the Apache License, Version 2.0.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion by you shall be licensed as Apache-2.0 without any additional terms or conditions.