Releases: mattpocock/sandcastle
v0.5.10
Patch Changes
- 95d63a4: Apply
:zSELinux label by default on Docker bind mounts, matching the existing Podman behavior. AddsselinuxLabeloption toDockerOptions("z"|"Z"|false, default"z"). Extracts sharedformatVolumeMountfrom Podman provider intosrc/mountUtils.tsso both providers use the same volume-mount formatter. - 9bf43df: Auto-create parent directories for file-target bind mounts under
/home/agent. When a user mount targets a single file whose sandbox-side parent directory may not exist in the image (e.g./home/agent/.codex/auth.json), both Docker and Podman providers now runmkdir -p+chownon the parent at container start. File mounts whose parent is outside/home/agentfail at config time with a clear error and remediation guidance. - adbb3cc: Add
variantoption to theopencodeagent provider for controlling reasoning effort via opencode's--variantCLI flag.
v0.5.8
Patch Changes
- 7400ead: Add a short hint to the
parallel-plannerandparallel-planner-with-reviewplan prompts noting that the issues list is already filtered, so the planner agent is less likely to requery and pick up issues outside the configured filter. - 21b6442: Fix Windows hosts emitting backslash separators for in-container paths during session capture/resume and
copyPaths.sandboxSessionStore,defaultSessionPathsLayer, andstartSandbox'scopyPathsnow use POSIX joins for paths that target the Linux container, sodocker cp/podman cpno longer reject them on Windows.
v0.5.7
Patch Changes
- 904ad82: Fix
PromptError: Prompt argument "{{TASK_ID}}" has no matching value in promptArgsthrown on every iteration of thesimple-loop,sequential-reviewer, andparallel-planner*merge flows aftersandcastle init. TheVIEW_TASK_COMMANDandCLOSE_TASK_COMMANDregistry values used to embed{{TASK_ID}}, which got baked into prompts whose runtime promptArgs do not includeTASK_ID. They now use a plain<ID>placeholder for the agent to fill in from surrounding context.
v0.5.6
Patch Changes
- 54b5111: Add
timeouts.copyToWorktreeMsoption to override the host-to-worktree copy timeout (default: 60 000 ms). - d8484ca: Surface fallback
cp -Rfailures fromcopyToWorktreeas a typedCopyToWorktreeErrorinstead of silently swallowing them - b6cc84f: Fix
WorktreeManager.pruneStaledeleting active worktrees when.sandcastle(or any ancestor of the repo directory) is a symlink.git worktree listreturns canonicalized paths, so the un-canonicalized prefix never matched the active set and parallelcreateSandbox()calls would wipe each other's worktrees mid-run, surfacing asspawn /bin/sh ENOENT. - 26920ca: Fix
branchStrategy.baseBranchbeing silently dropped when callingsandcastle.run()with a worktree-based sandbox. New branches now correctly fork from the requestedbaseBranchinstead of the host's HEAD. - bbb0f39: Fix
encodeProjectPathto handle Windows paths by replacing backslashes with hyphens and stripping drive-letter colons, producing a valid single directory-name component on Windows. - b2123e4: Add optional
timeoutMsfield to hook objects, allowing per-hook timeout overrides with fallback to the default 60s - a658fcc: Update Quick Start install command to recommend
--save-devand note that Sandcastle is a dev/CI tool - 425b77e: Use APFS clonefile (
cp -cR) on macOS for copy-to-worktree instead of GNU--reflink=auto, giving Mac users instant copy-on-write on APFS volumes
v0.5.5
v0.5.4
Patch Changes
-
9c8516d: Surface agent error details in
AgentErrorwhen stderr is empty. Error events emitted to stdout by Codex and Pi, plus OpenCode's result text, are now parsed and included in the error message instead of being dropped. -
b2cc893: Show context window size per iteration in the run summary. Each iteration with usage data emits a
Context window: NNNkline (tokens rounded up to the nearest 1000) in both terminal and log-to-file mode. -
2843c1b: Support
baseBranchwhen creating sandboxes, so new branches can be forked from a specified ref. Available both oncreateSandboxand in the named branch strategy. -
d860e84: Fix Beads Dockerfile build failure on arm64 hosts (e.g. Apple Silicon). The image now builds on both amd64 and arm64.
-
fdd9b9e: Fix built-in review prompt templates so they respect the configured source branch instead of always diffing against
main. -
cfbeb67: Fix parallel-planner-with-review template to capture reviewer result and merge commits from both implementer and reviewer runs
-
eb03260: Fix transient worktree creation failure when
branch.autoSetupMergeorpush.autoSetupRemoteis enabled globally -
4032e64: Inline prompts (
prompt: "...") are now passed to the agent literally — no{{KEY}}substitution, no!`command`expansion, no built-in{{SOURCE_BRANCH}}/{{TARGET_BRANCH}}injection. Fixes #453: callers that build inline prompts from arbitrary content (issue bodies, PR descriptions) no longer fail when that content happens to contain{{...}}. PassingpromptArgsalongside an inline prompt is now an error; usepromptFileto opt into template behavior. -
6bc4d74: Fix
PromptPreprocessorexecuting!`...`patterns that arrive viapromptArgssubstitution. Argument values are now treated as inert data: only shell blocks written in the raw template are executed. Previously, any caller passing text throughpromptArgs(issue titles, bodies, docs excerpts, etc.) could hit spurious command execution — or, with untrusted inputs, remote shell execution — because the preprocessor scanned the fully-assembled prompt after substitution. -
359907e: Add
onAgentStreamEventoption tologgingin log-to-file mode. The callback receives eachtextchunk andtoolCallemitted by the agent, with the iteration number and a timestamp, so callers can forward the agent's output stream to an external observability system. Errors thrown by the callback are swallowed so a broken forwarder cannot kill the run. -
ce1bf1b: Support tilde expansion in
sandboxPathfor Docker and Podman mount configs.Users can now write
sandboxPath: "~/.npm"and it expands to/home/agent/.npminside the sandbox. The expansion uses the provider's declaredsandboxHomedir("/home/agent"for Docker and Podman). Using~insandboxPathwith a provider that has nosandboxHomedirthrows a descriptive error at mount resolution time.
v0.5.1
Patch Changes
- ba6121e: Add a
cwdoption tocreateSandbox(),createWorktree(),run(), andinteractive(). When provided,cwdreplacesprocess.cwd()as the host repo directory used for worktrees,.sandcastle/.env, logs, patches, and git operations, letting you drive Sandcastle from outside the target repo. Relative paths resolve againstprocess.cwd(); absolute paths pass through. ACwdErroris raised when the path does not exist or is not a directory. - f872268: Fix session capture, which always failed with "Could not find the file". Sandcastle was looking for session JSONLs under a
sessions/subdirectory that Claude Code does not actually use.
v0.5.0
Minor Changes
- 800e743: Restructure hooks API to group by execution location (
hostvssandbox). The old flathooks: { onSandboxReady }shape is replaced withhooks: { host?: { onWorktreeReady?, onSandboxReady? }, sandbox?: { onSandboxReady? } }. Host hooks run on the developer's machine; sandbox hooks run inside the container. Breaking change (pre-1.0).
Patch Changes
- 4515aa9: Add
copyFileInandcopyFileOutmethods toBindMountSandboxHandlefor moving individual files between the host and the sandbox. Docker usesdocker cp, Podman usespodman cp, and the newtestBindMount()provider uses a plain filesystem copy. - 3aa9d9a: Fix Podman sandbox failing on macOS when host UID differs from 1000 by chowning /home/agent to the host UID:GID after container start, matching Docker provider behavior.
- 0a84413: Breaking: Replace
RunResult.iterationsRunwithRunResult.iterations: IterationResult[]. EachIterationResultcarries an optionalsessionIdextracted from Claude Code's stream-json init line. Consumers needing the iteration count should readiterations.length. Non-Claude agent providers producesessionId: undefined. The same change applies toOrchestrateResult,SandboxRunResult, andWorktreeRunResult. - 85eb071: Add session capture and resume for Claude Code:
- Capture: after each iteration, the agent's session is saved to the host at
~/.claude/projects/<encoded>/sessions/<id>.jsonlso it can be replayed or inspected locally with Claude Code's usual tooling. AddscaptureSessionsoption toclaudeCode()(defaulttrue) andsessionFilePathtoIterationResult. - Resume: adds
resumeSessionoption torun()for continuing a prior Claude Code conversation in a new sandbox run. Incompatible withmaxIterations > 1. - Exposes the underlying
SessionStoreinterface andtransferSessionhelper for users who want to move sessions between the host and a sandbox directly.
- Capture: after each iteration, the agent's session is saved to the host at
v0.4.8
Patch Changes
- c8cfcc6: Add timeout to the isolated provider
copyPathsloop instartSandbox. The entire copy loop is now wrapped withwithTimeout(120s), producing aCopyToWorktreeTimeoutErroron expiry, consistent with the per-step timeout pattern used elsewhere in the sandbox lifecycle. - bab11e9: Add
networkoption to Docker and Podman sandbox providers for custom container networking - a2c580f: Make Dockerfile generation aware of the selected backlog manager. When "beads" is chosen, the Dockerfile installs beads CLI tools instead of GitHub CLI.
- a2fd5ad: Generate
.env.exampledynamically duringsandcastle initbased on selected agent and backlog manager instead of copying a static file from the template directory. - 20741fe: Fix parallel-planner templates to use {{CLOSE_TASK_COMMAND}} placeholder instead of hardcoded "close the issue" language, and replace "GitHub issue" with backlog-agnostic wording
- b7880ec: Make
prompt/promptFileoptional ininteractive()— when neither is provided, the agent TUI launches with no initial prompt (the full prompt pipeline is skipped). - aea1131: Add per-step timeouts across the sandbox lifecycle. Every lifecycle step is now wrapped with
Effect.timeoutFailvia awithTimeoututility, producing a step-specific tagged error on expiry. Breaking:TimeoutErrorrenamed toAgentIdleTimeoutErrorwithtimeoutMsfield replacingidleTimeoutSeconds. - c261079: Support relative paths in MountConfig for bind-mount sandbox providers.
hostPathrelative paths resolve fromprocess.cwd(), andsandboxPathrelative paths resolve from the sandbox repo directory. - d13acc3: Remove unnecessary
copyToWorktreeandbranchStrategyfrom planner and merger agents in parallel planner templates. These lightweight agents (maxIterations: 1) now default to head mode, avoiding the overhead of copying node_modules into worktrees. - 0f8a99a: Remove semaphore concurrency limiter from parallel-planner-with-review template. Issue pipelines now run concurrently via Promise.allSettled without a concurrency cap, matching the parallel-planner template.
- bf23e83: Rename workspace terminology back to worktree across the codebase. All public API types and functions renamed from
Workspace*toWorktree*(e.g.createWorktree(),Worktree,WorktreeBranchStrategy).copyToWorkspacerenamed tocopyToWorktree.sandboxWorkspacePathrenamed tosandboxRepoPathandSANDBOX_WORKSPACE_DIRtoSANDBOX_REPO_DIRfor sandbox-internal paths. Source files renamed accordingly (WorktreeManager.ts,CopyToWorktree.ts,createWorktree.ts).