@ai-hero/sandcastle 0.6.6 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -510,7 +510,7 @@ Sandcastle uses a **branch strategy** configured on the sandbox provider to cont
510
510
 
511
511
  - **Head** (`{ type: "head" }`) — The agent writes directly to the host working directory. No worktree, no branch indirection. This is the default for bind-mount providers like `docker()`.
512
512
  - **Merge-to-head** (`{ type: "merge-to-head" }`) — Sandcastle creates a temporary branch in a git worktree. The agent works on the temp branch, and changes are merged back to HEAD when done. The temp branch is cleaned up after merge.
513
- - **Branch** (`{ type: "branch", branch: "foo" }`) — Commits land on an explicitly named branch in a git worktree.
513
+ - **Branch** (`{ type: "branch", branch: "foo" }`) — Commits land on an explicitly named branch in a git worktree. Re-running with the same branch reuses the existing worktree and fast-forwards it from `origin` when safe — see [ADR 0003](docs/adr/0003-reuse-worktree-by-default.md).
514
514
 
515
515
  For bind-mount providers (like Docker), the worktree directory is bind-mounted into the container — the agent writes directly to the host filesystem through the mount, so no sync is needed.
516
516
 
@@ -711,13 +711,19 @@ Scaffolds the `.sandcastle/` config directory and builds the container image. Th
711
711
 
712
712
  Init detects your host package manager (npm, pnpm, yarn, or bun) from a `packageManager` field or lockfile, defaulting to npm. Templates whose `main` file imports a host dependency — the planner templates import [Zod](https://zod.dev) for their `<plan>` output schema — prompt you to install it with that package manager when it isn't already in your `package.json`, so the first `npx tsx .sandcastle/main.ts` doesn't fail with `ERR_MODULE_NOT_FOUND`.
713
713
 
714
- | Option | Required | Default | Description |
715
- | -------------- | -------- | ---------------------------- | ---------------------------------------------------------------------------- |
716
- | `--image-name` | No | `sandcastle:<repo-dir-name>` | Docker image name |
717
- | `--agent` | No | Interactive prompt | Agent to use (`claude-code`, `pi`, `codex`, `cursor`, `opencode`, `copilot`) |
718
- | `--model` | No | Agent's default model | Model to use (e.g. `claude-sonnet-4-6`). Defaults to agent's default |
719
- | `--sandbox` | No | Interactive prompt | Sandbox provider to use (`docker`, `podman`) |
720
- | `--template` | No | Interactive prompt | Template to scaffold (e.g. `blank`, `simple-loop`) |
714
+ Every interactive prompt has a paired `--flag` so the entire init can run non-interactively (e.g. in CI or a scripted setup). When stdin is not a TTY and a required flag is missing, init fails fast with a clear error rather than wedging on a prompt.
715
+
716
+ | Option | Required | Default | Description |
717
+ | ------------------------- | -------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------- |
718
+ | `--image-name` | No | `sandcastle:<repo-dir-name>` | Docker image name |
719
+ | `--agent` | No | Interactive prompt | Agent to use (`claude-code`, `pi`, `codex`, `cursor`, `opencode`, `copilot`) |
720
+ | `--model` | No | Agent's default model | Model to use (e.g. `claude-sonnet-4-6`). Defaults to agent's default |
721
+ | `--sandbox` | No | Interactive prompt | Sandbox provider to use (`docker`, `podman`) |
722
+ | `--template` | No | Interactive prompt | Template to scaffold (e.g. `blank`, `simple-loop`) |
723
+ | `--issue-tracker` | No | Interactive prompt | Issue tracker to use (`github-issues`, `beads`, `custom`) |
724
+ | `--create-label` | No | Interactive prompt | `true` / `false` — whether to create the `Sandcastle` GitHub label (only with `--issue-tracker github-issues`) |
725
+ | `--build-image` | No | Interactive prompt | `true` / `false` — whether to build the sandbox image now (silently ignored with `--issue-tracker custom`) |
726
+ | `--install-template-deps` | No | Interactive prompt | `true` / `false` — whether to install template host deps (e.g. `zod` for the planner templates) |
721
727
 
722
728
  Creates the following files:
723
729
 
@@ -769,7 +775,7 @@ Removes the Podman image.
769
775
 
770
776
  | Option | Type | Default | Description |
771
777
  | -------------------------- | ------------------ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
772
- | `agent` | AgentProvider | — | **Required.** Agent provider (e.g. `claudeCode("claude-opus-4-7")`, `pi("claude-sonnet-4-6")`, `codex("gpt-5.4-mini")`, `cursor("composer-2")`, `opencode("opencode/big-pickle")`, `copilot("claude-sonnet-4.5")`) |
778
+ | `agent` | AgentProvider | — | **Required.** Agent provider (e.g. `claudeCode("claude-opus-4-7")`, `pi("claude-sonnet-4-6")`, `codex("gpt-5.4")`, `cursor("composer-2")`, `opencode("opencode/big-pickle")`, `copilot("claude-sonnet-4.5")`) |
773
779
  | `sandbox` | SandboxProvider | — | **Required.** Sandbox provider (e.g. `docker()`, `podman()`, `docker({ imageName: "sandcastle:local" })`) |
774
780
  | `cwd` | string | `process.cwd()` | Host repo directory — anchor for `.sandcastle/` artifacts and git operations. Relative paths resolve against `process.cwd()`. |
775
781
  | `prompt` | string | — | Inline prompt (mutually exclusive with `promptFile`) |
@@ -841,7 +847,7 @@ You can also continue the last captured session from a result:
841
847
 
842
848
  ```typescript
843
849
  const first = await run({
844
- agent: codex("gpt-5.4-mini"),
850
+ agent: codex("gpt-5.4"),
845
851
  sandbox: docker(),
846
852
  prompt: "Draft a plan",
847
853
  });
@@ -895,11 +901,12 @@ The `claudeCode()` factory accepts an optional second argument for provider-spec
895
901
  agent: claudeCode("claude-opus-4-7", { effort: "high" });
896
902
  ```
897
903
 
898
- | Option | Type | Default | Description |
899
- | ----------------- | --------------------------------------------------------- | ------- | --------------------------------------------------------- |
900
- | `effort` | `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | — | Claude Code reasoning effort level (`max` is Opus only) |
901
- | `env` | `Record<string, string>` | `{}` | Environment variables injected by this agent provider |
902
- | `captureSessions` | `boolean` | `true` | Capture agent session JSONL to host for `claude --resume` |
904
+ | Option | Type | Default | Description |
905
+ | ----------------- | ---------------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
906
+ | `effort` | `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | — | Claude Code reasoning effort level (`max` is Opus only) |
907
+ | `env` | `Record<string, string>` | `{}` | Environment variables injected by this agent provider |
908
+ | `captureSessions` | `boolean` | `true` | Capture agent session JSONL to host for `claude --resume` |
909
+ | `permissionMode` | `"default"` \| `"acceptEdits"` \| `"plan"` \| `"auto"` \| `"dontAsk"` \| `"bypassPermissions"` | — | Maps to Claude's `--permission-mode` flag. When set, replaces Sandcastle's default `--dangerously-skip-permissions` on AFK runs. Use `"auto"` for AI-mediated per-tool approve/deny without bypass. |
903
910
 
904
911
  ### `CodexOptions`
905
912
 
@@ -909,11 +916,12 @@ The `codex()` factory accepts an optional second argument for provider-specific
909
916
  agent: codex("gpt-5.4", { effort: "high" });
910
917
  ```
911
918
 
912
- | Option | Type | Default | Description |
913
- | ----------------- | ---------------------------------------------- | ------- | --------------------------------------------------------- |
914
- | `effort` | `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` | — | Codex reasoning effort level via `model_reasoning_effort` |
915
- | `env` | `Record<string, string>` | `{}` | Environment variables injected by this agent provider |
916
- | `captureSessions` | `boolean` | `true` | Capture Codex rollout JSONL to host for resume |
919
+ | Option | Type | Default | Description |
920
+ | ------------------- | ---------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
921
+ | `effort` | `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` | — | Codex reasoning effort level via `model_reasoning_effort` |
922
+ | `env` | `Record<string, string>` | `{}` | Environment variables injected by this agent provider |
923
+ | `captureSessions` | `boolean` | `true` | Capture Codex rollout JSONL to host for resume |
924
+ | `approvalsReviewer` | `"user"` \| `"auto_review"` | — | Maps to Codex's `approvals_reviewer` config. When `"auto_review"`, swaps `--dangerously-bypass-approvals-and-sandbox` for `-a on-request -s danger-full-access` so the reviewer agent evaluates each approval prompt. |
917
925
 
918
926
  ### `PiOptions`
919
927
 
@@ -1,5 +1,5 @@
1
1
  import { createRequire } from 'node:module';
2
- import { BaseProto, succeed2, Path, TypeId, pipe, mergeAll, provideMerge, makeRunMain, constVoid, try_, BadArgument, effect, CommandExecutor, FileSystem, map3, makeExecutor, scoped2, Terminal, provide2, layerManager, flatten2, stdin, unwrapScoped, flatMap3, make5, async, getOrElse, constUndefined, fail2, unsafeDone, succeed, sync, _void, match, zipRight, acquireRelease, isDone, orElse2, _await, ignore, ExitCode, negate, ProcessId, transduce, ProcessTypeId, drain, identity, tap, forkDaemon, run, fnUntraced, make6 as make6$1, gen, get3, make9, addFinalizer2, scoped, PlatformWorker, serviceOption, WatchBackend, make8, suspend, fromChannel2, fromChannel, asVoid, fromNullable, void_, uninterruptible, makePlatform, WorkerError, as, addFinalizer, interruptible, timeout, catchAllCause, tryPromise, orDie, flatMap, unwrap, SystemError, flatMap4, zip, embedInput, complete, failCause, suspend2, make2, effectify, map, Size, FileDescriptor, asyncScoped, WatchEventUpdate, matchEffect, WatchEventRemove, WatchEventCreate, ensuring, void_2, unsafeMakeLatch, fromEffect, write, unsafeFromArray, ensuring2, fail, FileTypeId, unsafeMakeSemaphore, none, some, Effect_exports, Display } from './chunk-Z7O2WNRU.js';
2
+ import { BaseProto, succeed2, Path, TypeId, pipe, mergeAll, provideMerge, makeRunMain, constVoid, try_, BadArgument, effect, CommandExecutor, FileSystem, map3, makeExecutor, scoped2, Terminal, provide2, layerManager, flatten2, stdin, unwrapScoped, flatMap3, make5, async, getOrElse, constUndefined, fail2, unsafeDone, succeed, sync, _void, match, zipRight, acquireRelease, isDone, orElse2, _await, ignore, ExitCode, negate, ProcessId, transduce, ProcessTypeId, drain, identity, tap, forkDaemon, run, fnUntraced, make6 as make6$1, gen, get3, make9, addFinalizer2, scoped, PlatformWorker, serviceOption, WatchBackend, make8, suspend, fromChannel2, fromChannel, asVoid, fromNullable, void_, uninterruptible, makePlatform, WorkerError, as, addFinalizer, interruptible, timeout, catchAllCause, tryPromise, orDie, flatMap, unwrap, SystemError, flatMap4, zip, embedInput, complete, failCause, suspend2, make2, effectify, map, Size, FileDescriptor, asyncScoped, WatchEventUpdate, matchEffect, WatchEventRemove, WatchEventCreate, ensuring, void_2, unsafeMakeLatch, fromEffect, write, unsafeFromArray, ensuring2, fail, FileTypeId, unsafeMakeSemaphore, none, some, Effect_exports, Display } from './chunk-5VM5QZ26.js';
3
3
  import { __commonJS, __require, __export, __toESM, __reExport } from './chunk-NGBM7T3E.js';
4
4
  import * as ChildProcess from 'child_process';
5
5
  import 'stream';
@@ -25565,5 +25565,5 @@ undici/lib/web/websocket/frame.js:
25565
25565
  */
25566
25566
 
25567
25567
  export { NodeContext_exports, NodeFileSystem_exports2 as NodeFileSystem_exports, NodeRuntime_exports, formatErrorMessage, withFriendlyErrors };
25568
- //# sourceMappingURL=chunk-Q5W3WQVU.js.map
25569
- //# sourceMappingURL=chunk-Q5W3WQVU.js.map
25568
+ //# sourceMappingURL=chunk-52CIJF45.js.map
25569
+ //# sourceMappingURL=chunk-52CIJF45.js.map