@ai-hero/sandcastle 0.4.6 → 0.4.8
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 +152 -27
- package/dist/CopyToWorktree.d.ts +9 -0
- package/dist/CopyToWorktree.d.ts.map +1 -0
- package/dist/{CopyToWorkspace.js → CopyToWorktree.js} +9 -3
- package/dist/CopyToWorktree.js.map +1 -0
- package/dist/DockerLifecycle.d.ts +2 -0
- package/dist/DockerLifecycle.d.ts.map +1 -1
- package/dist/DockerLifecycle.js +7 -0
- package/dist/DockerLifecycle.js.map +1 -1
- package/dist/ErrorHandler.d.ts.map +1 -1
- package/dist/ErrorHandler.js +20 -2
- package/dist/ErrorHandler.js.map +1 -1
- package/dist/InitService.d.ts +6 -1
- package/dist/InitService.d.ts.map +1 -1
- package/dist/InitService.js +90 -56
- package/dist/InitService.js.map +1 -1
- package/dist/MountConfig.d.ts +13 -2
- package/dist/MountConfig.d.ts.map +1 -1
- package/dist/Orchestrator.d.ts +1 -1
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +6 -7
- package/dist/Orchestrator.js.map +1 -1
- package/dist/PromptPreprocessor.d.ts +2 -2
- package/dist/PromptPreprocessor.d.ts.map +1 -1
- package/dist/PromptPreprocessor.js +7 -2
- package/dist/PromptPreprocessor.js.map +1 -1
- package/dist/SandboxFactory.d.ts +7 -9
- package/dist/SandboxFactory.d.ts.map +1 -1
- package/dist/SandboxFactory.js +21 -23
- package/dist/SandboxFactory.js.map +1 -1
- package/dist/SandboxLifecycle.d.ts.map +1 -1
- package/dist/SandboxLifecycle.js +33 -9
- package/dist/SandboxLifecycle.js.map +1 -1
- package/dist/SandboxProvider.d.ts +7 -7
- package/dist/SandboxProvider.d.ts.map +1 -1
- package/dist/WorktreeManager.d.ts +3 -3
- package/dist/WorktreeManager.d.ts.map +1 -1
- package/dist/WorktreeManager.js +14 -3
- package/dist/WorktreeManager.js.map +1 -1
- package/dist/createSandbox.d.ts +24 -1
- package/dist/createSandbox.d.ts.map +1 -1
- package/dist/createSandbox.js +227 -131
- package/dist/createSandbox.js.map +1 -1
- package/dist/createWorktree.d.ts +121 -0
- package/dist/createWorktree.d.ts.map +1 -0
- package/dist/createWorktree.js +314 -0
- package/dist/createWorktree.js.map +1 -0
- package/dist/errors.d.ts +101 -6
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +38 -3
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interactive.d.ts +2 -2
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +59 -48
- package/dist/interactive.js.map +1 -1
- package/dist/run.d.ts +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +5 -5
- package/dist/run.js.map +1 -1
- package/dist/sandboxes/daytona.js +4 -4
- package/dist/sandboxes/daytona.js.map +1 -1
- package/dist/sandboxes/docker.d.ts +9 -0
- package/dist/sandboxes/docker.d.ts.map +1 -1
- package/dist/sandboxes/docker.js +15 -5
- package/dist/sandboxes/docker.js.map +1 -1
- package/dist/sandboxes/no-sandbox.js +4 -4
- package/dist/sandboxes/no-sandbox.js.map +1 -1
- package/dist/sandboxes/podman.d.ts +9 -0
- package/dist/sandboxes/podman.d.ts.map +1 -1
- package/dist/sandboxes/podman.js +21 -5
- package/dist/sandboxes/podman.js.map +1 -1
- package/dist/sandboxes/test-isolated.js +5 -5
- package/dist/sandboxes/test-isolated.js.map +1 -1
- package/dist/sandboxes/vercel.js +7 -7
- package/dist/sandboxes/vercel.js.map +1 -1
- package/dist/startSandbox.d.ts +7 -6
- package/dist/startSandbox.d.ts.map +1 -1
- package/dist/startSandbox.js +38 -19
- package/dist/startSandbox.js.map +1 -1
- package/dist/syncIn.js +7 -7
- package/dist/syncIn.js.map +1 -1
- package/dist/syncOut.js +6 -6
- package/dist/syncOut.js.map +1 -1
- package/dist/templates/parallel-planner/implement-prompt.md +2 -2
- package/dist/templates/parallel-planner/main.mts +2 -6
- package/dist/templates/parallel-planner/merge-prompt.md +5 -1
- package/dist/templates/parallel-planner-with-review/implement-prompt.md +2 -2
- package/dist/templates/parallel-planner-with-review/main.mts +28 -62
- package/dist/templates/parallel-planner-with-review/merge-prompt.md +5 -1
- package/dist/templates/sequential-reviewer/main.mts +3 -3
- package/dist/templates/simple-loop/main.mts +2 -2
- package/package.json +1 -1
- package/dist/CopyToWorkspace.d.ts +0 -8
- package/dist/CopyToWorkspace.d.ts.map +0 -1
- package/dist/CopyToWorkspace.js.map +0 -1
- package/dist/templates/blank/.env.example +0 -5
- package/dist/templates/parallel-planner/.env.example +0 -5
- package/dist/templates/parallel-planner-with-review/.env.example +0 -5
- package/dist/templates/sequential-reviewer/.env.example +0 -5
- package/dist/templates/simple-loop/.env.example +0 -5
|
@@ -15,7 +15,11 @@ After all branches are merged, make a single commit summarizing the merge.
|
|
|
15
15
|
|
|
16
16
|
# CLOSE ISSUES
|
|
17
17
|
|
|
18
|
-
For each branch that was merged, close its issue
|
|
18
|
+
For each branch that was merged, close its issue using the following command:
|
|
19
|
+
|
|
20
|
+
`{{CLOSE_TASK_COMMAND}}`
|
|
21
|
+
|
|
22
|
+
Here are all the issues:
|
|
19
23
|
|
|
20
24
|
{{ISSUES}}
|
|
21
25
|
|
|
@@ -6,7 +6,7 @@ Pull in the issue using `{{VIEW_TASK_COMMAND}}`. If it has a parent PRD, pull th
|
|
|
6
6
|
|
|
7
7
|
Only work on the issue specified.
|
|
8
8
|
|
|
9
|
-
Work on branch {{BRANCH}}. Make commits, run tests, and close the issue when done
|
|
9
|
+
Work on branch {{BRANCH}}. Make commits, run tests, and close the issue when done using `{{CLOSE_TASK_COMMAND}}`.
|
|
10
10
|
|
|
11
11
|
# CONTEXT
|
|
12
12
|
|
|
@@ -51,7 +51,7 @@ Keep it concise.
|
|
|
51
51
|
|
|
52
52
|
# THE ISSUE
|
|
53
53
|
|
|
54
|
-
If the task is not complete, leave a comment on the
|
|
54
|
+
If the task is not complete, leave a comment on the issue with what was done.
|
|
55
55
|
|
|
56
56
|
Do not close the issue - this will be done later.
|
|
57
57
|
|
|
@@ -41,10 +41,7 @@ const hooks = {
|
|
|
41
41
|
// Copy node_modules from the host into the worktree before each sandbox
|
|
42
42
|
// starts. Avoids a full npm install from scratch; the hook above handles
|
|
43
43
|
// platform-specific binaries and any packages added since the last copy.
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
// Cap the number of concurrent sandboxes to avoid resource exhaustion.
|
|
47
|
-
const MAX_CONCURRENCY = 4;
|
|
44
|
+
const copyToWorktree = ["node_modules"];
|
|
48
45
|
|
|
49
46
|
// ---------------------------------------------------------------------------
|
|
50
47
|
// Main loop
|
|
@@ -64,9 +61,7 @@ for (let iteration = 1; iteration <= MAX_ITERATIONS; iteration++) {
|
|
|
64
61
|
// -------------------------------------------------------------------------
|
|
65
62
|
const plan = await sandcastle.run({
|
|
66
63
|
hooks,
|
|
67
|
-
copyToWorkspace,
|
|
68
64
|
sandbox: docker(),
|
|
69
|
-
branchStrategy: { type: "merge-to-head" },
|
|
70
65
|
name: "planner",
|
|
71
66
|
// One iteration is enough: the planner just needs to read and reason,
|
|
72
67
|
// not write code.
|
|
@@ -109,75 +104,48 @@ for (let iteration = 1; iteration <= MAX_ITERATIONS; iteration++) {
|
|
|
109
104
|
// and reviewer share the same sandbox instance per branch. The implementer
|
|
110
105
|
// runs first; if it produces commits, the reviewer runs in the same sandbox.
|
|
111
106
|
//
|
|
112
|
-
// A semaphore limits concurrency to MAX_CONCURRENCY sandboxes at once.
|
|
113
107
|
// Promise.allSettled means one failing pipeline doesn't cancel the others.
|
|
114
108
|
// -------------------------------------------------------------------------
|
|
115
109
|
|
|
116
|
-
// Simple semaphore for concurrency limiting
|
|
117
|
-
let running = 0;
|
|
118
|
-
const waiting: Array<() => void> = [];
|
|
119
|
-
const acquire = (): Promise<void> => {
|
|
120
|
-
if (running < MAX_CONCURRENCY) {
|
|
121
|
-
running++;
|
|
122
|
-
return Promise.resolve();
|
|
123
|
-
}
|
|
124
|
-
return new Promise<void>((resolve) => {
|
|
125
|
-
waiting.push(() => {
|
|
126
|
-
running++;
|
|
127
|
-
resolve();
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
};
|
|
131
|
-
const release = () => {
|
|
132
|
-
running--;
|
|
133
|
-
const next = waiting.shift();
|
|
134
|
-
if (next) next();
|
|
135
|
-
};
|
|
136
|
-
|
|
137
110
|
const settled = await Promise.allSettled(
|
|
138
111
|
issues.map(async (issue) => {
|
|
139
|
-
await
|
|
112
|
+
const sandbox = await sandcastle.createSandbox({
|
|
113
|
+
branch: issue.branch,
|
|
114
|
+
sandbox: docker(),
|
|
115
|
+
hooks,
|
|
116
|
+
copyToWorktree,
|
|
117
|
+
});
|
|
118
|
+
|
|
140
119
|
try {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
120
|
+
// Run the implementer
|
|
121
|
+
const implement = await sandbox.run({
|
|
122
|
+
name: "implementer",
|
|
123
|
+
maxIterations: 100,
|
|
124
|
+
agent: sandcastle.claudeCode("claude-sonnet-4-6"),
|
|
125
|
+
promptFile: "./.sandcastle/implement-prompt.md",
|
|
126
|
+
promptArgs: {
|
|
127
|
+
TASK_ID: issue.id,
|
|
128
|
+
ISSUE_TITLE: issue.title,
|
|
129
|
+
BRANCH: issue.branch,
|
|
130
|
+
},
|
|
146
131
|
});
|
|
147
132
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
name: "
|
|
152
|
-
maxIterations:
|
|
133
|
+
// Only review if the implementer produced commits
|
|
134
|
+
if (implement.commits.length > 0) {
|
|
135
|
+
await sandbox.run({
|
|
136
|
+
name: "reviewer",
|
|
137
|
+
maxIterations: 1,
|
|
153
138
|
agent: sandcastle.claudeCode("claude-sonnet-4-6"),
|
|
154
|
-
promptFile: "./.sandcastle/
|
|
139
|
+
promptFile: "./.sandcastle/review-prompt.md",
|
|
155
140
|
promptArgs: {
|
|
156
|
-
TASK_ID: issue.id,
|
|
157
|
-
ISSUE_TITLE: issue.title,
|
|
158
141
|
BRANCH: issue.branch,
|
|
159
142
|
},
|
|
160
143
|
});
|
|
161
|
-
|
|
162
|
-
// Only review if the implementer produced commits
|
|
163
|
-
if (implement.commits.length > 0) {
|
|
164
|
-
await sandbox.run({
|
|
165
|
-
name: "reviewer",
|
|
166
|
-
maxIterations: 1,
|
|
167
|
-
agent: sandcastle.claudeCode("claude-sonnet-4-6"),
|
|
168
|
-
promptFile: "./.sandcastle/review-prompt.md",
|
|
169
|
-
promptArgs: {
|
|
170
|
-
BRANCH: issue.branch,
|
|
171
|
-
},
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return implement;
|
|
176
|
-
} finally {
|
|
177
|
-
await sandbox.close();
|
|
178
144
|
}
|
|
145
|
+
|
|
146
|
+
return implement;
|
|
179
147
|
} finally {
|
|
180
|
-
|
|
148
|
+
await sandbox.close();
|
|
181
149
|
}
|
|
182
150
|
}),
|
|
183
151
|
);
|
|
@@ -228,9 +196,7 @@ for (let iteration = 1; iteration <= MAX_ITERATIONS; iteration++) {
|
|
|
228
196
|
// -------------------------------------------------------------------------
|
|
229
197
|
await sandcastle.run({
|
|
230
198
|
hooks,
|
|
231
|
-
copyToWorkspace,
|
|
232
199
|
sandbox: docker(),
|
|
233
|
-
branchStrategy: { type: "merge-to-head" },
|
|
234
200
|
name: "merger",
|
|
235
201
|
maxIterations: 1,
|
|
236
202
|
agent: sandcastle.claudeCode("claude-sonnet-4-6"),
|
|
@@ -15,7 +15,11 @@ After all branches are merged, make a single commit summarizing the merge.
|
|
|
15
15
|
|
|
16
16
|
# CLOSE ISSUES
|
|
17
17
|
|
|
18
|
-
For each branch that was merged, close its issue
|
|
18
|
+
For each branch that was merged, close its issue using the following command:
|
|
19
|
+
|
|
20
|
+
`{{CLOSE_TASK_COMMAND}}`
|
|
21
|
+
|
|
22
|
+
Here are all the issues:
|
|
19
23
|
|
|
20
24
|
{{ISSUES}}
|
|
21
25
|
|
|
@@ -36,7 +36,7 @@ const hooks = {
|
|
|
36
36
|
// Copy node_modules from the host into the worktree before each sandbox
|
|
37
37
|
// starts. Avoids a full npm install from scratch; the hook above handles
|
|
38
38
|
// platform-specific binaries and any packages added since the last copy.
|
|
39
|
-
const
|
|
39
|
+
const copyToWorktree = ["node_modules"];
|
|
40
40
|
|
|
41
41
|
// ---------------------------------------------------------------------------
|
|
42
42
|
// Main loop
|
|
@@ -57,7 +57,7 @@ for (let iteration = 1; iteration <= MAX_ITERATIONS; iteration++) {
|
|
|
57
57
|
// -------------------------------------------------------------------------
|
|
58
58
|
const implement = await sandcastle.run({
|
|
59
59
|
hooks,
|
|
60
|
-
|
|
60
|
+
copyToWorktree,
|
|
61
61
|
sandbox: docker(),
|
|
62
62
|
branchStrategy: { type: "merge-to-head" },
|
|
63
63
|
name: "implementer",
|
|
@@ -86,7 +86,7 @@ for (let iteration = 1; iteration <= MAX_ITERATIONS; iteration++) {
|
|
|
86
86
|
// -------------------------------------------------------------------------
|
|
87
87
|
await sandcastle.run({
|
|
88
88
|
hooks,
|
|
89
|
-
|
|
89
|
+
copyToWorktree,
|
|
90
90
|
sandbox: docker(),
|
|
91
91
|
branchStrategy: { type: "branch", branch },
|
|
92
92
|
name: "reviewer",
|
|
@@ -28,7 +28,7 @@ await run({
|
|
|
28
28
|
|
|
29
29
|
// Branch strategy — merge-to-head creates a temporary branch for the agent
|
|
30
30
|
// to work on, then merges the result back to HEAD when the run completes.
|
|
31
|
-
// This is required when using
|
|
31
|
+
// This is required when using copyToWorktree, since head mode bind-mounts
|
|
32
32
|
// the host directory directly (no worktree to copy into).
|
|
33
33
|
branchStrategy: { type: "merge-to-head" },
|
|
34
34
|
|
|
@@ -36,7 +36,7 @@ await run({
|
|
|
36
36
|
// starts. This avoids a full npm install from scratch on every iteration.
|
|
37
37
|
// The onSandboxReady hook still runs npm install as a safety net to handle
|
|
38
38
|
// platform-specific binaries and any packages added since the last copy.
|
|
39
|
-
|
|
39
|
+
copyToWorktree: ["node_modules"],
|
|
40
40
|
|
|
41
41
|
// Lifecycle hooks — commands that run inside the sandbox at specific points.
|
|
42
42
|
hooks: {
|
package/package.json
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
/**
|
|
3
|
-
* Copy files and directories from the host repo root to the worktree root,
|
|
4
|
-
* using `cp -R --reflink=auto` for copy-on-write when the filesystem supports it.
|
|
5
|
-
* Missing paths are silently skipped.
|
|
6
|
-
*/
|
|
7
|
-
export declare const copyToWorkspace: (paths: string[], hostRepoDir: string, worktreePath: string) => Effect.Effect<void, never, never>;
|
|
8
|
-
//# sourceMappingURL=CopyToWorkspace.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CopyToWorkspace.d.ts","sourceRoot":"","sources":["../src/CopyToWorkspace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;;GAIG;AACH,eAAO,MAAM,eAAe,mGAyBxB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CopyToWorkspace.js","sourceRoot":"","sources":["../src/CopyToWorkspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,KAAe,EACf,WAAmB,EACnB,YAAoB,EACQ,EAAE,CAC9B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,KAAK,MAAM,YAAY,IAAI,KAAK,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAC9C,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAc,CAAC,MAAM,EAAE,EAAE;YAC1C,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC5D,IAAI,KAAK,EAAE,CAAC;oBACV,0DAA0D;oBAC1D,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE;wBACrC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;oBACpC,CAAC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC"}
|