Sandcastle
Orchestrate sandboxed AI coding agents with a single sandcastle.run() call and merge their branch commits back.
- Source repo
- mattpocock/sandcastle
- Stars
- ★ 8.8k
- Last updated
- today
- License
- MIT
- Primary language
- TypeScript
- FA score
- 54/100 · Major gaps
At a glance
- How it runs
- Works with
- Universal · cross-platform
- Cost
- Free software; you pay for model usage
- Setup effort
- Medium · a few setup steps
- You'll need
- Typical use
- Engineering teams that want to launch several AFK coding agents in parallel
- Not a fit if
- Teams that want a turnkey GUI rather than writing TypeScript orchestration code
- Users on systems without a supported process-sandbox mechanism
- Non-engineers who prefer a visual console over code and CLI
- Source review
- 54/100 · Major gaps
What does this agent do, and when should you use it?
Sandcastle is a TypeScript library for orchestrating AI coding agents inside isolated sandboxes. You invoke an agent with one sandcastle.run() call; Sandcastle handles sandboxing under a configurable branch strategy and merges the commits made on those branches back. It is provider-agnostic: native sandboxes use your OS's own process sandbox (Bubblewrap on Linux and WSL2, Seatbelt on macOS), image-based providers cover Docker and Podman, and cloud providers include Daytona, E2B, Fly.io Sprites, Modal and Vercel, with room for custom ones. The docs are organized one page per major term, covering core concepts, sandbox providers, branch strategies, agent providers and sessions, iterations, structured output, prompts, hooks, init, run logs, and the run()/createSandbox() and CLI references. It targets parallel AFK agents, review pipelines, and orchestration of your own agents.
From TypeScript, a caller invokes sandcastle.run() and creates or selects a sandbox via createSandbox(); Sandcastle prepares an isolated branch per agent according to the branch strategy and executes the agent inside a sandbox — a native OS process sandbox (Bubblewrap/Seatbelt), an image-based provider (Docker/Podman), or a cloud provider (Daytona, E2B, Fly.io Sprites, Modal, Vercel). Execution supports iterations, structured output, prompts, hooks and run-log display, and commits produced on the agent's branch are merged back. The docs also include a CLI command reference and an init flow for setting up a project.
- Engineering teams that want to launch several AFK coding agents in parallel
- Turning code review into a pipeline where agents change code on sandboxed branches before merge or review
- Teams already standardized on Docker or Podman that want agent work isolated in image-based sandboxes
- Developers who want to run agents remotely through Daytona, E2B, Modal or Vercel
- Teams orchestrating their own agents into existing CI or internal tooling with TypeScript
How do you install or deploy this agent?
Inside a project directory, install and build:
npm install
npm run build # Bundle with tsup
npm test # Run tests with vitest
npm run typecheck # Type-checkThe README does not publish an npm package name or a versioned install command beyond this development flow, so confirm the package's release status before relying on it. Native sandboxes require the OS mechanism (Bubblewrap on Linux/WSL2, Seatbelt on macOS); image and cloud providers require Docker/Podman or the respective cloud account and credentials.
How do you use this agent?
The core usage is calling sandcastle.run() in your own TypeScript code and letting Sandcastle own sandboxing and branch merging:
import { sandcastle } from "sandcastle";
await sandcastle.run({
// see docs/guide/run.md and docs/guide/core-concepts.md for options
});The README does not include a complete runnable options example, so read the docs in order: docs/guide/getting-started.md (prerequisites and quick start), core-concepts.md, sandbox-providers.md, branch-strategies.md, agent-providers.md. CLI commands are in docs/guide/cli.md, initialization in docs/guide/init.md, and the docs are published at aihero.dev/sandcastle.
What are this agent's strengths and limitations?
- Provider-agnostic by design: agent and sandbox providers are swappable across native, image-based and cloud paths
- Native sandboxes reuse OS process isolation (Bubblewrap/Seatbelt), so no container runtime is required for that path
- Branch strategy is part of the orchestration: agents work on separate branches whose commits merge back, aiding parallelism and review
- Covers the execution surface — iterations, structured output, prompts, hooks and run logs — rather than just launching a process
- MIT licensed, with docs organized one page per term plus a glossary
- The primary entry point is a TypeScript library, so adopters write orchestration code instead of using a finished product
- Several sandbox providers (Daytona, E2B, Fly.io Sprites, Modal, Vercel) require third-party cloud accounts and credentials
- Native sandboxing differs by platform (Bubblewrap vs Seatbelt), so behavior is not uniform across operating systems
- The README omits a package-name install command and a complete minimal example, so onboarding depends on reading docs/guide
- No GitHub topics are listed, so ecosystem and community signals must be assessed independently
How does this agent compare with similar options?
Key facts side by side with the most closely related agents.
| Agent | Source review | Form / cost | Stars | Updated | Language | Full support on |
|---|---|---|---|---|---|---|
| Sandcastle This agent | 54 · Major gaps | Library / SDKFree + model costs | ★ 8.8k | today | TypeScript | — |
| Warren | 76 · Good | Self-hosted serviceFree + model costs | ★ 513 | 19d ago | TypeScript | Claude Code |
| Omnigent | 62 · Some gaps | CLIFree + model costs | ★ 11k | today | Python | ChatGPT · Codex · Claude Code · Claude.ai · OpenAI API · Claude API |
| Best of Agent Harnesses | 75 · Good | MCP serverFree + model costs | ★ 1.4k | 1d ago | Python | Claude Code · Claude API |
How does FollowAgents rate this agent?
Why each dimension lost points
least_privilege: native bwrap/seatbelt give a private home, read-only system dirs and hidden credentials, and explicitly never fall back to noSandbox(), but network egress is fully open including host localhost, so capped at 2. user_confirmation: noSandbox() in run() has no runtime confirmation; ADR-0015 makes the import itself the opt-in and pushes risk to the caller, so 1. data_flow_transparency: docs explain env, logins, git identity and session copy paths, but keys in .sandcastle/.env are forwarded into the sandbox (stated for E2B), leaving an exfiltration surface, so 2. sensitive_data_handling: private home and env allowlist are good, but seatbelt does not promise Keychain isolation and .env secrets are forwarded, so 2. dependency_security: many peer/dev deps use caret ranges with no lockfile or audit evidence in the files, so 1. external_effects: run() merges commits back to branches and cloud providers create/delete remote resources with no default dry-run or confirmation, so 1. rollback: ADR-0017 shows syncOut previously lost a whole run's commits on base mismatch; the ref fix helps but there is no general rollback/undo API, so 1. source_attribution: MIT and author are present, but publisher is unverified and the package name @ai-hero/sandcastle differs from repo mattpocock/sandcastle, so 1.
self_consistency: README, sandbox-providers.md, ADRs and package.json exports largely agree on provider list and import paths, but README mentions Daytona while the provider table omits it, a minor inconsistency, so 2. dependency_availability: cloud providers rely on optional peer deps (e2b, modal, @fly/sprites, @vercel/sandbox, @daytona/sdk) the user must install, with wide version ranges, so 1. failure_messages: docs show NativeSandboxUnavailableError with fixCommand, idle-timeout errors and sudo rejection, and tests assert error text, so 2.
audience_and_scenarios: covers parallel AFK agents, review pipelines and multiple providers with a clear audience, so 2. capability_boundaries: docs describe each provider's isolation strength and limits (no PID namespace, setsid escape, no root, no interactive) in detail, so 3. trigger_precision: run() triggering depends on completion signal and idle timeout with no explicit trigger conditions or idempotency notes, so 1. environment_fit: supports Linux/WSL2/macOS/Windows(WSL2) and many cloud providers, but macOS needs 14+ and Ubuntu 24.04 needs AppArmor config, so 2.
information_architecture: docs/guide has one page per term plus a glossary, clearly structured, so 2. install_notes: README has npm install/build/test and each provider has install notes, so 2. naming_stability: package name @ai-hero/sandcastle differs from repo name sandcastle, and ADRs show AnySandboxProvider deprecated and interactive() to be removed in v1, so the API is in flux, 1. examples_and_faq: many code examples and custom-provider examples, but no dedicated FAQ, so 2. known_limitations: the Containment section and ADRs enumerate limitations thoroughly, so 3. license: full MIT LICENSE file, so 3. versioning_changelog: changesets are used but no CHANGELOG file is present and version 0.13.0 is pre-1.0, so 1. maintenance_responsibility: no SECURITY.md, no maintainer commitment, publisher unverified, so 1.
output_usability: run() returns completionSignal, commits, iterations and sessionFilePath, structured and usable, so 2. marginal_value: adds sandbox orchestration and branch merging on top of existing agent CLIs, a clear increment, though similar tools exist, so 2. cost_benefit: cloud providers carry timeout/billing risk (E2B 1-hour cap, Modal default 1 hour) and docs do not quantify cost, so 1.
claim_traceability: README provider claims map to docs and package.json exports, but some claims (e.g. Daytona) lack a matching doc page, so 1. cross_source_corroboration: README, guide, ADRs and tests partly corroborate each other (bwrap behavior is tested), but there is no independent third-party verification, so 1. fact_inference_separation: docs are mostly design statements and ADRs separate decisions from consequences well, but the research doc permissions-systemic-fix.md mixes in speculation ('in order of likelihood'), so 1.
- noSandbox() lets run() execute the agent with host privileges with no runtime confirmation; the caller owns the risk.
- Native sandboxes have fully open network egress including host localhost; seatbelt does not promise Keychain isolation and setsid processes can escape the process group.
- Cloud providers rely on optional peer dependencies with wide version ranges that users must install and pin; no lockfile or dependency audit evidence is in the files.
- Package name @ai-hero/sandcastle differs from repo mattpocock/sandcastle and the publisher is unverified; verify provenance before installing.
- run() merges commits back to branches and creates/deletes cloud resources with no default dry-run or rollback API; ADR-0017 records a past defect that lost a whole run's commits.
- Version 0.13.0 is pre-1.0 with a moving API (AnySandboxProvider deprecated, interactive() slated for removal); upgrade with care.
Recent releases
Latest entries from the project's GitHub Releases. Notes are quoted from upstream as written, not rewritten or tested by FollowAgents.
-
Release notes excerpt
Minor Changes - d99fff8: Add an E2B isolated sandbox provider, e2b() from @ai-hero/sandcastle/sandboxes/e2b. It needs the optional e2b peer dependency and E2B_API_KEY (or the apiKey option). Use a template that ships your agent's CLI, such as e2b({ template: "claude" }). - 8783573: Add modal(), an isolated sandbox provider for [Modal](https://modal.com) sandboxes, at @ai-hero/sandcastle/sandboxes/modal. Install modal (an optional peer dependency) and set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET, or pass tokenId and tokenSecret. By default it builds a `node:24-bookwo …View on GitHub ↗ -
Release notes excerpt
Highlights - Native sandboxes. bwrap() (Linux and WSL2) and seatbelt() (macOS) run the agent in an OS sandbox with no container and no image. They are now the documented default. sandcastle init --sandbox bwrap scaffolds a project that needs no Dockerfile. - Resume for more agents. Copilot, Cursor and OpenCode sessions can now be resumed; OpenCode can also fork. - sandboxId on the sandbox handle (the container name on Docker and Podman, the sandbox's name or id on Vercel and Daytona), and capDrop for Docker and Podman. …View on GitHub ↗ -
Release notes excerpt
Minor Changes - 1e15922: Bump default Claude Code model from claude-opus-4-7 to claude-opus-4-8. The new default applies to the DEFAULT_MODEL constant, the claude-code agent entry surfaced by sandcastle init, and the scaffolded templates (blank, parallel-planner, parallel-planner-with-review). Passing an explicit model to claudeCode(...) is unaffected. …View on GitHub ↗