| name | add-agent |
| description | Add a new AI coding agent to Agent Sandbox. Creates all required files (Dockerfile, templates, CI, docs) and wires the agent into the CLI, proxy, and build system. |
Scaffold Agent Support
This skill generates all the files needed to add a new AI coding agent to Agent Sandbox. It follows the established patterns from Claude, Copilot, and Codex implementations.
Arguments
The skill takes a single argument: the agent name (lowercase, no spaces). Example: gemini, opencode, factory.
Process
Step 1: Gather Information
Ask the user for the following (skip any already provided):
- Agent name (from argument)
- Display name - human-readable name for comments and labels (e.g., "Google Gemini CLI")
- Project URL - link to the agent's GitHub repo or website (for README table)
- Installation method - how to install the agent binary/CLI
- npm package (like Claude and Copilot)
- direct binary download from GitHub releases (like Codex)
- curl installer script
- pip package
- go install
- Package identifier - npm package name, GitHub releases URL pattern, pip package, go module, or download URL
- Version detection source - how CI detects new releases
- npm registry (Claude, Copilot):
npm view {package} version
- GitHub releases API (Codex):
gh api repos/{owner}/{repo}/releases/latest --jq .tag_name
- Note any tag prefix that needs stripping (e.g., Codex uses
rust-v prefix)
- Version variable name - env var for build.sh (e.g.,
GEMINI_VERSION)
- Config directory - where the agent stores its config in the container (e.g.,
/home/dev/.gemini)
- Default config files - any config files to bake into the image (e.g., Codex bakes
config.toml to disable its internal sandbox)
- Internal sandbox - does the agent have its own sandboxing (Landlock, seccomp, etc.) that should be disabled inside our container? If so, how to disable it.
- Required API domains - domains the agent needs to reach (API, auth/OAuth, CDN)
- Authentication method - how users authenticate (API key env var, OAuth flow, device code, etc.)
- Auto-approve flag - the CLI flag for unattended/yolo mode (e.g.,
--dangerously-skip-permissions, --yolo, --full-auto)
- VS Code extension ID - if one exists (e.g.,
github.copilot-chat), or "none" for CLI-only agents
- JetBrains plugin ID - if one exists (e.g.,
com.anthropic.code.plugin), or "none"
- Agent-specific environment variables - any env vars the agent needs at runtime
- Does the agent need Node.js? - whether to install Node.js in the Dockerfile (only if the base image doesn't include it and the agent needs it)
Step 2: Create Files
Generate all files listed below. Read the reference files first to match the exact format and structure.
2.1: Dockerfile
Create images/agents/{agent}/Dockerfile.
Pattern:
ARG BASE_IMAGE=agent-sandbox-base:local + FROM ${BASE_IMAGE}
- Optional extra packages block (same pattern as existing agents)
- Install Node.js if needed (copy pattern from Copilot Dockerfile)
- As root: create config directory and
~/.local/bin if installing a binary there
- Copy any default config files (e.g.,
COPY config.toml /home/dev/.{agent}/config.toml)
USER dev
- Set
ENV PATH="/home/dev/.local/bin:$PATH" if installing to ~/.local/bin
- Install the agent (method depends on installation type)
- For direct binary downloads: use
ARG TARGETARCH for multi-arch, prefer musl (statically linked) over gnu variants
- Add labels:
org.opencontainers.image.description and version label
If the agent needs default config files, create them alongside the Dockerfile (e.g., images/agents/{agent}/config.toml).
2.2: Agent Compose Layer
Create internal/embeddata/templates/{agent}/cli/agent.yml.
This is a compose overlay that layers on top of the shared internal/embeddata/templates/compose/base.yml. It contains only agent-specific configuration. Read an existing agent.yml for the exact format.
Contents:
- Managed-by comment header
services.proxy.volumes: [] (required placeholder for compose merge)
services.agent.image - the GHCR image reference
services.agent.volumes - agent-specific state and history volumes
services.agent.environment - agent-specific env vars (if any)
- Named volume declarations at the bottom
Do NOT include proxy config, HTTP_PROXY, HTTPS_PROXY, capabilities, or other shared settings. Those live in base.yml.
2.3: devcontainer.json
Create internal/embeddata/templates/{agent}/devcontainer/devcontainer.json.
This file references a layered array of compose files. Read an existing devcontainer.json for the exact format.
Key points:
dockerComposeFile is an array of 5 paths pointing into .agent-sandbox/compose/:
base.yml, agent.{name}.yml, mode.devcontainer.yml, user.override.yml, user.agent.{name}.override.yml
service: "agent"
workspaceFolder: "/workspace"
- VS Code settings section with port forwarding disabled and security settings
- VS Code extensions array if applicable, or omit for CLI-only agents
- JetBrains settings section with proxy configuration
- JetBrains plugins array if applicable
remoteUser: "dev"
overrideCommand: false
2.4: Update Agent Registry
Edit cli/lib/agent.bash:
- Add the new agent to
supported_agents_display() (space-separated string)
- Add the new agent to
supported_agents() (printf list)
- Add the new agent to
select_agent() (option list)
- Add the new agent to the
validate_agent() case statement
2.5: Update CLI Compose Scaffolding
Edit cli/lib/cli-compose.bash:
- If the agent has host-side config that users might want to mount (like Claude's
CLAUDE.md and settings.json), add a conditional block in scaffold_cli_agent_override_if_missing() following the Claude pattern. This adds commented-out volume entries to user.agent.{name}.override.yml.
- Skip this for agents without meaningful host-side config.
2.6: Update BATS Tests
Two test files reference the agent list string:
- Edit
cli/test/init/init.bats: update the "rejects invalid --agent value" assertion to include the new agent name.
- Edit
cli/test/switch/switch.bats:
- Update the "switch rejects invalid --agent value" assertion(s) to include the new agent name.
- Update the
stub select_option call in "switch prompts for agent when --agent is omitted" to include the new agent in the argument list.
Both assertions and the stub match the output of supported_agents_display() / select_agent().
2.7: Update Proxy Service Domains and Known Agents
Two files in the proxy image need updating:
images/proxy/service_catalog.py: add a new entry to the SIMPLE_SERVICE_HOSTS dict.
Guidelines:
- Place alphabetically among existing entries
- Prefer wildcards over listing subdomains individually (e.g.,
*.openai.com covers api.openai.com, auth.openai.com, regional endpoints)
- Only use separate entries for different TLDs (e.g.,
chatgpt.com is separate from openai.com)
- Include both API domains and auth/OAuth domains so authentication works through the proxy
If the service needs rule-level semantics (repo scoping, method narrowing beyond the generic readonly mapping), add a dedicated expander function following the GitHub pattern instead of using SIMPLE_SERVICE_HOSTS.
images/proxy/render-policy: add the new agent name to the KNOWN_AGENTS set. This script renders the effective proxy policy at startup and validates the AGENTBOX_ACTIVE_AGENT env var against this set. If the agent is missing, the proxy will refuse to start with an "Unknown agent" error.
2.8: Update build.sh
Edit images/build.sh to add:
- Default env var at top (e.g.,
: "${GEMINI_VERSION:=latest}")
- Extra packages env var (e.g.,
: "${GEMINI_EXTRA_PACKAGES:=}")
build_{agent}() function following the pattern of existing agent build functions
- Add to the case statement (both specific target and
all target)
- Update usage text (first line and examples)
2.9: Agent Documentation
Create docs/agents/{agent}.md following this structure (see docs/agents/codex.md for exact format):
- Header:
# {Display Name} Sandbox Template
- One-liner: "Run {display name} in a network-locked container..."
- Link: "See the main README for installation, architecture overview, and configuration options."
- Setup section: Auth instructions covering all supported auth methods. Note any gotchas (e.g., account-level settings that must be enabled).
- Usage section: How to start the agent, including the auto-approve flag. Include
agentbox compose down for stopping.
- Required Network Policy section: Show the
services: YAML snippet with the agent's service name.
2.10: Update Project README
Edit README.md:
- Add row to the "Supported agents" table with the agent name, project URL, and status columns (CLI, VS Code, JetBrains). New agents are typically
:large_blue_circle: Preview for CLI and devcontainer modes.
- Add link to
docs/{agent}/README.md in the "Agent-specific setup" section
Step 3: CI/CD Workflows
Create the CI files directly in .github/workflows/. They follow a clear pattern and can be written without drafting.
3.1: Build Job
Edit .github/workflows/build-images.yml:
- Add
{AGENT}_IMAGE_NAME env var (e.g., GEMINI_IMAGE_NAME)
- Add
build-{agent} job following the pattern of build-codex (for GitHub releases) or build-copilot (for npm)
- Version detection depends on the source:
- npm:
npm view {package} version
- GitHub releases:
gh api repos/{owner}/{repo}/releases/latest --jq .tag_name with any tag prefix stripping via sed
- Add to summary job
needs array
- Add agent version and digest to summary output table
3.2: Version Check Workflow
Create .github/workflows/check-{agent}-version.yml following the pattern of existing version check workflows.
- Pick the next available daily cron slot (current: Claude 6am UTC, Copilot 7am, Codex 8am)
- Match the version source to the build job (npm or GitHub releases)
- Tag prefix:
{agent}- for the GHCR tag check
- Trigger
build-images.yml if the version tag doesn't exist in GHCR
Step 4: Verify
After creating all files:
- List all files created/modified
- Note any manual steps needed
- Remind user to:
- Build and test locally:
./images/build.sh {agent}
- Verify the binary works:
docker run --rm agent-sandbox-{agent}:local {agent} --version
- Test init flow:
agentbox init --agent {agent} --mode cli --path /tmp/test-project
- Run CLI tests:
go test ./...
- Test proxy enforcement after starting containers:
- Allowed domain returns 200:
curl -x http://proxy:8080 https://{api-domain}
- Blocked domain returns 403:
curl -x http://proxy:8080 https://example.com
- Test auth flow inside the container
Reference Files
When generating files, read these for the exact patterns:
images/agents/claude/Dockerfile (npm install pattern)
images/agents/copilot/Dockerfile (npm install with Node.js pattern)
images/agents/codex/Dockerfile (direct binary download pattern, multi-arch, config file baking)
images/agents/codex/config.toml (baked config file example)
internal/embeddata/templates/compose/base.yml (shared compose base layer with proxy and agent skeleton)
internal/embeddata/templates/compose/mode.devcontainer.yml (devcontainer mode overlay)
internal/embeddata/templates/claude/cli/agent.yml (agent compose layer with env vars)
internal/embeddata/templates/copilot/cli/agent.yml (simplest agent compose layer)
internal/embeddata/templates/claude/devcontainer/devcontainer.json (devcontainer with extensions and JetBrains plugins)
internal/embeddata/templates/codex/devcontainer/devcontainer.json (CLI-only agent, no extensions)
internal/runtime/agents.go (agent registry: supported list and validation)
internal/scaffold/init.go (CLI and devcontainer init flow entrypoints)
internal/scaffold/devcontainer.go (devcontainer JSON rendering and merge behavior)
internal/cli/init_test.go (init command assertions and prompting expectations)
internal/cli/switch_test.go (switch command assertions and agent validation coverage)
images/proxy/addons/enforcer.py (service domains, alphabetical ordering)
images/proxy/render-policy (KNOWN_AGENTS set, policy rendering validation)
images/build.sh (build functions and case statement)
docs/agents/codex.md (simplest agent doc, CLI-only)
docs/agents/copilot.md (agent doc with IDE notes)
README.md (supported agents table and setup links)
.github/workflows/build-images.yml (build jobs)
.github/workflows/check-codex-version.yml (GitHub releases version check)
.github/workflows/check-copilot-version.yml (npm version check)