@ai-hero/sandcastle 0.1.4 → 0.1.6

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
@@ -117,14 +117,14 @@ console.log(result.branch); // target branch name
117
117
 
118
118
  ## How it works
119
119
 
120
- Sandcastle uses a worktree-based architecture for direct, zero-sync agent execution:
120
+ Sandcastle uses a worktree-based architecture for agent execution:
121
121
 
122
- - **Worktree**: Sandcastle creates a git worktree on the host at `.sandcastle/worktrees/`. The worktree is a real checkout of your repo — no copying or bundling required.
122
+ - **Worktree**: Sandcastle creates a git worktree on the host at `.sandcastle/worktrees/`. The worktree is a just a normal `git worktree`.
123
123
  - **Bind-mount**: The worktree directory is bind-mounted into the sandbox container as the agent's working directory. The agent writes directly to the host filesystem through the mount.
124
124
  - **No sync needed**: Because the agent writes directly to the host filesystem, there are no sync-in or sync-out operations. Commits made by the agent are immediately visible on the host.
125
125
  - **Merge back**: After the run completes, the temp worktree branch is fast-forward merged back to the target branch, and the worktree is cleaned up.
126
126
 
127
- This approach eliminates the complexity of patch-based sync and ensures the agent always works with the exact repo state on the host.
127
+ From your point of view, you just run `sandcastle.run({ branch: 'foo' })`, and get a commit on branch `foo` once it's complete. All 100% local.
128
128
 
129
129
  ## Prompts
130
130
 
@@ -167,43 +167,34 @@ for (let iteration = 1; iteration <= MAX_ITERATIONS; iteration++) {
167
167
  continue;
168
168
  }
169
169
 
170
- if (completedBranches.length === 1) {
171
- // Single branch — merge directly without spinning up a merge agent.
172
- const { execSync } = await import("node:child_process");
173
- const branch = completedBranches[0]!;
174
- console.log(`\nSingle branch merging ${branch} directly.`);
175
- execSync(`git merge ${branch}`, { stdio: "inherit" });
176
- console.log("\nBranch merged.");
177
- } else {
178
- // -------------------------------------------------------------------------
179
- // Phase 3: Merge
180
- //
181
- // One sonnet agent merges all completed branches into the current branch,
182
- // resolving any conflicts and running tests to confirm everything still works.
183
- //
184
- // The {{BRANCHES}} and {{ISSUES}} prompt arguments are lists that the agent
185
- // uses to know which branches to merge and which issues to close.
186
- // -------------------------------------------------------------------------
187
- await sandcastle.run({
188
- hooks,
189
- copyToSandbox,
190
- name: "merger",
191
- maxIterations: 10,
192
- // Sonnet is sufficient for merge conflict resolution.
193
- model: "claude-sonnet-4-6",
194
- promptFile: "./.sandcastle/merge-prompt.md",
195
- promptArgs: {
196
- // A markdown list of branch names, one per line.
197
- BRANCHES: completedBranches.map((b) => `- ${b}`).join("\n"),
198
- // A markdown list of issue numbers and titles, one per line.
199
- ISSUES: completedIssues
200
- .map((i) => `- #${i.number}: ${i.title}`)
201
- .join("\n"),
202
- },
203
- });
204
-
205
- console.log("\nBranches merged.");
206
- }
170
+ // -------------------------------------------------------------------------
171
+ // Phase 3: Merge
172
+ //
173
+ // One sonnet agent merges all completed branches into the current branch,
174
+ // resolving any conflicts and running tests to confirm everything still works.
175
+ //
176
+ // The {{BRANCHES}} and {{ISSUES}} prompt arguments are lists that the agent
177
+ // uses to know which branches to merge and which issues to close.
178
+ // -------------------------------------------------------------------------
179
+ await sandcastle.run({
180
+ hooks,
181
+ copyToSandbox,
182
+ name: "merger",
183
+ maxIterations: 10,
184
+ // Sonnet is sufficient for merge conflict resolution.
185
+ model: "claude-sonnet-4-6",
186
+ promptFile: "./.sandcastle/merge-prompt.md",
187
+ promptArgs: {
188
+ // A markdown list of branch names, one per line.
189
+ BRANCHES: completedBranches.map((b) => `- ${b}`).join("\n"),
190
+ // A markdown list of issue numbers and titles, one per line.
191
+ ISSUES: completedIssues
192
+ .map((i) => `- #${i.number}: ${i.title}`)
193
+ .join("\n"),
194
+ },
195
+ });
196
+
197
+ console.log("\nBranches merged.");
207
198
  }
208
199
 
209
200
  console.log("\nAll done.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-hero/sandcastle",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "CLI for orchestrating AI agents in isolated sandbox environments",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",