Releases: streamingfast/sbox
Releases · streamingfast/sbox
v1.5.0
Added
sbox run --startup-delayflag to delay agent startup inside the sandbox. If set to0, waits forever without starting the agent (useful for attaching a shell and debugging). Otherwise accepts a Go duration (e.g.30s,5m).sbox loop --confirmationsflag to configure the number of consecutive goal completions required (default: 2). Also configurable vialoop_confirmationsin global config (~/.config/sbox/config.yaml) orsbox.yaml.sbox loop <prompt>command: runs the agent in a loop until the goal described by the prompt is completed- Same
--backendand--agentsupport assbox run - Augments the prompt with loop instructions so the agent knows to assess and work toward the goal
- Agent writes
.sbox/loop.completionwhen the goal is reached - Loop stops after the agent confirms completion the required number of consecutive times
- Same
Fixed
sbox loopnow stops immediately when the agent exits with an error or is killed, instead of continuing to loopsbox loopnow stops the sandbox when the loop exits (completion, error, or Ctrl+C), preventing the container from running in the background- Fix container backend not producing output in loop/prompt mode due to TTY allocation (
-it) mangling stream-json output - Transfer
tui.jsonfrom~/.config/opencode/tui.jsonto.sbox/(host→sandbox) and from.sbox/tui.jsonto agent home (sandbox entrypoint) for OpenCode - OpenCode state persistence across
sbox stopandsbox run --recreate~/.config/opencodesynced to.sbox/opencode-cache/on stop/recreate; restored on next run~/.local/share/opencodesynced to.sbox/opencode-share-cache/on stop/recreate; restored after initial file seeding so cached auth/session data takes precedence
v1.4.0
Added
- OpenCode support as an alternative AI agent to Claude
--agentflag forsbox runto select the AI agent type (claudeoropencode)agentfield insbox.yamlto configure agent per-projectagentfield in project config (persisted when using--agentflag)default_agentfield in global config (~/.config/sbox/config.yaml)sbox agentcommand group for managing the default AI agentsbox agent list— show available agentssbox agent set <agent>— set default agent globallysbox agent show— show current default agent
- Agent resolution priority: CLI flag > sbox.yaml > project config > global config > default (claude)
- Entrypoint automatically detects and launches the configured agent (claude or opencode)
- Sandbox/container names now include agent type:
sbox-<agent>-<workspace>(e.g.,sbox-opencode-myproject)- This allows running different agents for the same workspace
- Sandbox name is automatically regenerated when switching agents
- Previous sandboxes named
sbox-claude-<workspace>will be automatically detected for Claude agent
- Agent-specific Docker sandbox templates:
- Claude agent uses
docker/sandbox-templates:claude-code - OpenCode agent uses
docker/sandbox-templates:opencode - Template is automatically selected based on the configured agent
- Claude agent uses
- Agent abstraction via
AgentSpecinterface for extensibility- Encapsulates agent-specific behavior (binary name, wrapper name, template image, config directory, binary discovery, exec args)
- Template builder generates agent-specific wrapper scripts (e.g.,
claude-wrapperoropencode-wrapper) - Wrapper script automatically renames agent binary to
<name>-realand symlinks to wrapper for proper initialization - Template hash includes agent type to ensure separate template images for different agents
- Entrypoint uses agent-specific config directories (
.claudefor Claude,.config/opencodefor OpenCode) - Agent setup (CLAUDE.md/AGENTS.md, agents, plugins) works with appropriate config directory per agent
- Container backend uses agent-specific volume names (
sbox-claude-*vssbox-opencode-*) - Container backend mounts agent config directory based on agent type (
.claudeor.opencode) - Settings.json mount location is agent-aware
- Template build pre-creates agent config directory with proper ownership to avoid permission issues with volume mounts
- OpenCode agent uses appropriate command-line arguments (no
--dangerously-skip-permissionsflag) - Entrypoint passes workspace path to OpenCode when no arguments provided
- Config now supports agent-specific home directories (
opencode_homedefaults to~/.config/opencode,claude_homedefaults to~/.claude) - Plugins and agents are loaded from agent-specific home directories (
~/.config/opencodefor OpenCode,~/.claudefor Claude) - Settings.json files mounted from appropriate agent home directory
- Container config directory matches host XDG conventions (
.config/opencodefor OpenCode) - OpenCode config file (
~/.config/opencode/opencode.json) is automatically prepared via.sbox/directory:- If no config exists, a default one is created with full permissions
- Existing config is loaded and permissions are automatically set to
{"*": "allow"}for sandbox/container environment - All other user config fields (like
model, preferences, etc.) are preserved - Ensures OpenCode runs with full permissions in the isolated environment
- OpenCode authentication file (
~/.local/share/opencode/auth.json) is automatically copied if present:- Shares local authentication credentials with the sandbox/container
- Enables seamless OpenCode usage without re-authentication
- Copied to
/home/agent/.local/share/opencode/auth.jsonin the container
- CLAUDE.md/AGENTS.md concatenation works for both agents:
- Same walking and concatenation logic for all agents
- Claude: Final file placed at
~/.claude/CLAUDE.md - OpenCode: Final file placed at
~/.config/opencode/AGENTS.md - Discovers and merges all CLAUDE.md and AGENTS.md files from parent directories
- Includes backend-specific context (sandbox vs container)
- Symlink deduplication: If CLAUDE.md is a symlink to AGENTS.md (or vice versa), only includes the file once
- Renamed functions for clarity:
setupCLAUDEMD→setupRules,prepareCLAUDEMD→prepareRules
Fixed
- OpenCode config file preparation now correctly preserves all user fields (like
model, preferences, etc.) while only adding/overriding thepermissionfield for sandbox safety
v1.3.3
v1.3.2
Added
cppprofile for C/C++ development (Boost, libc++, libstdc++, autoconf, automake, libtool, ninja-build, libzstd-dev, zlib1g-dev)
Changed
- Sensitive environment variables (KEY, TOKEN, SECRET, PASSWORD, etc.) are now masked in
sbox infoandsbox env listoutput
Fixed
- Fix Docker image tag format to include
vprefix for semantic versions (e.g.,v1.3.1instead of1.3.1) to match published image tags
v1.3.1
v1.3.0
Added
firehoseprofile for blockchain data streaming (substreams, firecore, fireeth, dummy-blockchain, grpcurl)- Embedded documentation now instructs agents to:
- Treat
.sbox/directory as read-only (managed by sbox) - Use
/tmp/for temporary clones and downloads to avoid cluttering the workspace
- Treat
Changed
sbox profile addandsbox profile removenow accept multiple profiles (e.g.,sbox profile add go rust)
Fixed
sbox stop --rmnow removes stopped sandboxes/containers (previously only worked on running ones)- Replace deprecated
--load-local-templatewith--pull-template neverfor Docker Desktop 4.61+
v1.2.0
Added
- Named volume persistence for container backend (
sbox-claude-<hash>) to persist.claudefolder across sessions - Claude state caching for sandbox backend
- Entire
.claudefolder is synced to.sbox/claude-cache/onsbox stop - Cache is restored on sandbox creation, preserving auth across recreations
- Automatically saves cache before
sbox run --recreate - Uses
rsyncfor efficient synchronization - Preserves: credentials, settings, projects, plugins, agents, shell-snapshots, todos, etc.
- Entire
- Platform-aware Docker socket mounting for container backend
- macOS: Checks
~/.docker/run/docker.sockfirst, then/var/run/docker.sock - Linux: Uses
/var/run/docker.sock SBOX_DOCKER_SOCKETenvironment variable for explicit path override
- macOS: Checks
sbox infonow shows both create and run commands for sandbox backendjavascriptprofile for JavaScript/TypeScript development (installs pnpm and yarn)- Backend-specific context instructions embedded in CLAUDE.md/AGENTS.md hierarchy
- Sandbox backend: Documents MicroVM environment, native Docker access, persistence behavior
- Container backend: Documents Docker socket requirements, sudo usage, volume mount caveats
- Both include instructions for Docker, Docker Compose, and Testcontainers usage
Changed
- Refactored CLI commands to use shared
WorkspaceContextfor config loading - Added
Capitalize()method toBackendTypefor consistent display formatting - Added
SaveCache()andCleanup()methods toBackendinterface for proper encapsulation
v1.1.0
Added
- Backend abstraction to support multiple container execution backends
- Sandbox backend (default): Uses Docker sandbox MicroVM for enhanced isolation
- Container backend: Uses standard Docker containers with named volume persistence
--backendflag forsbox runto select the backend type (sandboxorcontainer)backendfield insbox.yamlto configure backend per-projectbackendfield in project config (persisted when using--backendflag)default_backendfield in global config (~/.config/sbox/config.yaml)- Named volume persistence for container backend (
sbox-claude-<hash>) to persist.claudefolder across sessions sbox infonow displays the configured backend type for each projectsbox stop --rm --allnow removes persistence volumes for container backend projects
Changed
- CLI commands (
shell,stop,info) now automatically detect the backend from project configuration - Backend resolution priority: CLI flag > sbox.yaml > project config > global config > default (sandbox)
v1.0.0
Added
- Multi-architecture support for dev builds (auto-detects amd64/arm64 from Docker)
--debugflag forsbox runto enable debug output from docker sandbox commandsMakefilewithbuild-imagetarget for building the sbox binary image locally
Changed
- Renamed config file from
.sboxtosbox.yamlto avoid conflict with.sbox/directory - Template images now use
CMDinstead ofENTRYPOINTfor docker sandbox compatibility- Docker sandbox requires its own entrypoint to manage container lifecycle
- Setting
ENTRYPOINTcaused containers to be killed (SIGKILL/exit 137) - The
sbox entrypointcommand now runs viaCMDafter sandbox initialization
- Migrated from container-based Docker sandbox to MicroVM-based Docker sandbox
docker psreplaced withdocker sandbox lsfor sandbox discoverydocker execreplaced withdocker sandbox execfor shell connectionsdocker stop/rmreplaced withdocker sandbox stop/rmfor sandbox lifecycle--mount-docker-socketflag is now ignored (Docker is automatically available in MicroVM sandboxes)- Mount introspection (
CheckBrokenMounts,CheckMountMismatch) disabled for MicroVM sandboxes
Added
substreamsprofile for blockchain development with Substreams and Firehose Core CLIs- Automatically includes
rustprofile as a dependency - Installs
substreamsCLI fromghcr.io/streamingfast/substreams:latest - Installs
firecoreCLI fromghcr.io/streamingfast/firehose-core:latest - Installs
bufCLI (latest) andprotoc(latest) for protobuf development
- Automatically includes
sbox envcommand group for managing environment variables passed to the sandboxsbox env add FOO=bar BAZ— add explicit values or host passthrough variablessbox env add --global TOKEN— add to global config (shared across all projects)sbox env remove FOO BAZ— remove by name (use--globalfor global config)sbox env list— show all vars with source labels ([global],[project],[sbox.yaml])- Project-specific envs override global ones;
sbox.yamlfile overrides global sbox infonow shows environment variables with their source
- Profile dependency support - profiles can now declare dependencies on other profiles
- Agent sharing via
--agentsCLI flag (converts~/.claude/agents/*.mdto JSON) - Plugin sharing via
--plugin-dirflag (each installed plugin is mounted separately) --recreateflag forsbox runto force rebuild the template image and recreate the sandbox- Mount mismatch detection with
--recreatesuggestion - Docker command display in
sbox info --allflag tosbox infoto list all known projects--workspace/-wflag tosbox infoto specify workspace directorysbox authcommand for configuring API key shared across all sandboxes- Prompts for Anthropic API key and stores it as a global environment variable
- API key is automatically passed to all sandbox sessions via
-e ANTHROPIC_API_KEY=... --statusflag to check if API key is configured--logoutflag to remove stored API key
Changed
sbox stop --rmno longer removes project configuration (profiles, envs, etc.)- Previously
--rmdeleted both the sandbox and all project config data - Now
--rmonly removes the Docker sandbox container - Use
sbox stop --rm --allto also remove project configuration (with confirmation prompt)
- Previously
sbox infonow shows current project info by default (use--allfor all projects)
Fixed
- Consolidated
--rebuildand--recreateflags into single--recreateflag--recreatenow both rebuilds the template image and recreates the sandbox
- Rust profile now installs to system-wide location (
/usr/local/cargo,/usr/local/rustup)- Previously installed to
/root/.cargowhich wasn't accessible to the sandboxagentuser - Fixed
chmodto include write permissions (a+rwx) sorustupoperations work (uses/usr/local/rustup/tmp/) cargo,rustc, andrustupcommands now work correctly inside the sandbox
- Previously installed to
- Integration tests now run as
agentuser to match the sandbox environment and catch permission issues - Authentication now uses API key via environment variable instead of credentials file mounting
- Simpler and more reliable than the previous OAuth/credentials.json approach
- API key stored in global config and passed as
-e ANTHROPIC_API_KEY=...to all sandboxes
Removed
sbox statuscommand (consolidated intosbox info)