@ai-hero/sandcastle 0.5.1 → 0.5.4
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 +93 -62
- package/dist/AgentProvider.d.ts +17 -1
- package/dist/AgentProvider.d.ts.map +1 -1
- package/dist/AgentProvider.js +75 -6
- package/dist/AgentProvider.js.map +1 -1
- package/dist/AgentStreamEmitter.d.ts +36 -0
- package/dist/AgentStreamEmitter.d.ts.map +1 -0
- package/dist/AgentStreamEmitter.js +21 -0
- package/dist/AgentStreamEmitter.js.map +1 -0
- package/dist/Display.js +1 -1
- package/dist/Display.js.map +1 -1
- package/dist/DockerLifecycle.d.ts +0 -10
- package/dist/DockerLifecycle.d.ts.map +1 -1
- package/dist/DockerLifecycle.js +0 -22
- package/dist/DockerLifecycle.js.map +1 -1
- package/dist/InitService.d.ts.map +1 -1
- package/dist/InitService.js +3 -1
- package/dist/InitService.js.map +1 -1
- package/dist/MountConfig.d.ts +1 -2
- package/dist/MountConfig.d.ts.map +1 -1
- package/dist/Orchestrator.d.ts +10 -3
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +79 -12
- package/dist/Orchestrator.js.map +1 -1
- package/dist/PodmanLifecycle.d.ts +0 -10
- package/dist/PodmanLifecycle.d.ts.map +1 -1
- package/dist/PodmanLifecycle.js +0 -22
- package/dist/PodmanLifecycle.js.map +1 -1
- package/dist/PromptArgumentSubstitution.d.ts +6 -0
- package/dist/PromptArgumentSubstitution.d.ts.map +1 -1
- package/dist/PromptArgumentSubstitution.js +32 -6
- package/dist/PromptArgumentSubstitution.js.map +1 -1
- package/dist/PromptPreprocessor.d.ts +8 -0
- package/dist/PromptPreprocessor.d.ts.map +1 -1
- package/dist/PromptPreprocessor.js +13 -9
- package/dist/PromptPreprocessor.js.map +1 -1
- package/dist/PromptResolver.d.ts +13 -1
- package/dist/PromptResolver.d.ts.map +1 -1
- package/dist/PromptResolver.js +3 -2
- package/dist/PromptResolver.js.map +1 -1
- package/dist/SandboxFactory.d.ts +5 -5
- package/dist/SandboxFactory.d.ts.map +1 -1
- package/dist/SandboxFactory.js +20 -10
- package/dist/SandboxFactory.js.map +1 -1
- package/dist/SandboxLifecycle.d.ts +4 -1
- package/dist/SandboxLifecycle.d.ts.map +1 -1
- package/dist/SandboxLifecycle.js +40 -12
- package/dist/SandboxLifecycle.js.map +1 -1
- package/dist/SandboxProvider.d.ts +30 -0
- package/dist/SandboxProvider.d.ts.map +1 -1
- package/dist/SandboxProvider.js +1 -0
- package/dist/SandboxProvider.js.map +1 -1
- package/dist/SessionStore.d.ts +1 -1
- package/dist/SessionStore.d.ts.map +1 -1
- package/dist/SessionStore.js +3 -0
- package/dist/SessionStore.js.map +1 -1
- package/dist/WorktreeManager.d.ts +6 -3
- package/dist/WorktreeManager.d.ts.map +1 -1
- package/dist/WorktreeManager.js +47 -5
- package/dist/WorktreeManager.js.map +1 -1
- package/dist/createSandbox.d.ts +23 -2
- package/dist/createSandbox.d.ts.map +1 -1
- package/dist/createSandbox.js +114 -50
- package/dist/createSandbox.js.map +1 -1
- package/dist/createWorktree.d.ts +23 -0
- package/dist/createWorktree.d.ts.map +1 -1
- package/dist/createWorktree.js +83 -24
- package/dist/createWorktree.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interactive.d.ts +11 -0
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +32 -13
- package/dist/interactive.js.map +1 -1
- package/dist/mountUtils.d.ts +104 -0
- package/dist/mountUtils.d.ts.map +1 -0
- package/dist/mountUtils.js +245 -0
- package/dist/mountUtils.js.map +1 -0
- package/dist/raceAbortSignal.d.ts +18 -0
- package/dist/raceAbortSignal.d.ts.map +1 -0
- package/dist/raceAbortSignal.js +32 -0
- package/dist/raceAbortSignal.js.map +1 -0
- package/dist/run.d.ts +34 -4
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +63 -18
- package/dist/run.js.map +1 -1
- package/dist/sandboxes/docker.d.ts +2 -6
- package/dist/sandboxes/docker.d.ts.map +1 -1
- package/dist/sandboxes/docker.js +44 -78
- package/dist/sandboxes/docker.js.map +1 -1
- package/dist/sandboxes/no-sandbox.d.ts.map +1 -1
- package/dist/sandboxes/no-sandbox.js +9 -1
- package/dist/sandboxes/no-sandbox.js.map +1 -1
- package/dist/sandboxes/podman.d.ts +19 -8
- package/dist/sandboxes/podman.d.ts.map +1 -1
- package/dist/sandboxes/podman.js +49 -87
- package/dist/sandboxes/podman.js.map +1 -1
- package/dist/startSandbox.d.ts.map +1 -1
- package/dist/startSandbox.js +8 -3
- package/dist/startSandbox.js.map +1 -1
- package/dist/templates/parallel-planner/implement-prompt.md +1 -1
- package/dist/templates/parallel-planner-with-review/implement-prompt.md +1 -1
- package/dist/templates/parallel-planner-with-review/main.mts +8 -1
- package/dist/templates/parallel-planner-with-review/review-prompt.md +2 -2
- package/dist/templates/sequential-reviewer/review-prompt.md +2 -2
- package/dist/testSandbox.d.ts.map +1 -1
- package/dist/testSandbox.js +38 -48
- package/dist/testSandbox.js.map +1 -1
- package/dist/testSetup.d.ts +2 -0
- package/dist/testSetup.d.ts.map +1 -0
- package/dist/testSetup.js +29 -0
- package/dist/testSetup.js.map +1 -0
- package/package.json +1 -1
|
@@ -29,11 +29,15 @@ export interface BindMountSandboxHandle {
|
|
|
29
29
|
* without a streaming implementation, neither will work. A buffered/batch
|
|
30
30
|
* implementation that only calls `onLine` after the process exits does NOT
|
|
31
31
|
* satisfy this contract.
|
|
32
|
+
*
|
|
33
|
+
* When `stdin` is set, the implementation pipes the string to the child
|
|
34
|
+
* process's stdin and closes it. This avoids the Linux 128 KB per-arg limit.
|
|
32
35
|
*/
|
|
33
36
|
exec(command: string, options?: {
|
|
34
37
|
onLine?: (line: string) => void;
|
|
35
38
|
cwd?: string;
|
|
36
39
|
sudo?: boolean;
|
|
40
|
+
stdin?: string;
|
|
37
41
|
}): Promise<ExecResult>;
|
|
38
42
|
/**
|
|
39
43
|
* Launch an interactive process inside the sandbox.
|
|
@@ -72,6 +76,12 @@ export interface BindMountSandboxProviderConfig {
|
|
|
72
76
|
readonly name: string;
|
|
73
77
|
/** Environment variables injected by this provider. Merged at launch time. */
|
|
74
78
|
readonly env?: Record<string, string>;
|
|
79
|
+
/**
|
|
80
|
+
* Absolute path to the home directory inside the sandbox (e.g. `"/home/agent"`).
|
|
81
|
+
* Used to expand `~` in user-provided `sandboxPath` mount configs.
|
|
82
|
+
* Set to `undefined` for providers that do not have a fixed home directory.
|
|
83
|
+
*/
|
|
84
|
+
readonly sandboxHomedir?: string;
|
|
75
85
|
/** Create a sandbox handle from the given options. */
|
|
76
86
|
readonly create: (options: BindMountCreateOptions) => Promise<BindMountSandboxHandle>;
|
|
77
87
|
}
|
|
@@ -87,11 +97,15 @@ export interface IsolatedSandboxHandle {
|
|
|
87
97
|
* without a streaming implementation, neither will work. A buffered/batch
|
|
88
98
|
* implementation that only calls `onLine` after the process exits does NOT
|
|
89
99
|
* satisfy this contract.
|
|
100
|
+
*
|
|
101
|
+
* When `stdin` is set, the implementation pipes the string to the child
|
|
102
|
+
* process's stdin and closes it. This avoids the Linux 128 KB per-arg limit.
|
|
90
103
|
*/
|
|
91
104
|
exec(command: string, options?: {
|
|
92
105
|
onLine?: (line: string) => void;
|
|
93
106
|
cwd?: string;
|
|
94
107
|
sudo?: boolean;
|
|
108
|
+
stdin?: string;
|
|
95
109
|
}): Promise<ExecResult>;
|
|
96
110
|
/**
|
|
97
111
|
* Launch an interactive process inside the sandbox.
|
|
@@ -131,6 +145,11 @@ export interface BindMountSandboxProvider {
|
|
|
131
145
|
readonly name: string;
|
|
132
146
|
/** Environment variables injected by this provider. */
|
|
133
147
|
readonly env: Record<string, string>;
|
|
148
|
+
/**
|
|
149
|
+
* Absolute path to the home directory inside the sandbox (e.g. `"/home/agent"`).
|
|
150
|
+
* `undefined` when the provider does not declare a sandbox home directory.
|
|
151
|
+
*/
|
|
152
|
+
readonly sandboxHomedir: string | undefined;
|
|
134
153
|
/** @internal Create a sandbox handle. */
|
|
135
154
|
readonly create: (options: BindMountCreateOptions) => Promise<BindMountSandboxHandle>;
|
|
136
155
|
}
|
|
@@ -155,11 +174,15 @@ export interface NoSandboxHandle {
|
|
|
155
174
|
* Implementations MUST support line-by-line streaming via `onLine`. This is
|
|
156
175
|
* how Sandcastle delivers live feedback to the user and enforces idle timeouts —
|
|
157
176
|
* without a streaming implementation, neither will work.
|
|
177
|
+
*
|
|
178
|
+
* When `stdin` is set, the implementation pipes the string to the child
|
|
179
|
+
* process's stdin and closes it. This avoids the Linux 128 KB per-arg limit.
|
|
158
180
|
*/
|
|
159
181
|
exec(command: string, options?: {
|
|
160
182
|
onLine?: (line: string) => void;
|
|
161
183
|
cwd?: string;
|
|
162
184
|
sudo?: boolean;
|
|
185
|
+
stdin?: string;
|
|
163
186
|
}): Promise<ExecResult>;
|
|
164
187
|
/**
|
|
165
188
|
* Launch an interactive process on the host with inherited stdio.
|
|
@@ -196,6 +219,13 @@ export interface MergeToHeadBranchStrategy {
|
|
|
196
219
|
export interface NamedBranchStrategy {
|
|
197
220
|
readonly type: "branch";
|
|
198
221
|
readonly branch: string;
|
|
222
|
+
/**
|
|
223
|
+
* Git ref to use as the starting point when creating a new branch.
|
|
224
|
+
* Only used when the branch doesn't already exist — ignored otherwise.
|
|
225
|
+
* Callers are responsible for ensuring the ref is current (e.g. `git fetch`).
|
|
226
|
+
* Defaults to `HEAD` when omitted.
|
|
227
|
+
*/
|
|
228
|
+
readonly baseBranch?: string;
|
|
199
229
|
}
|
|
200
230
|
/** Branch strategy for bind-mount providers (all three variants). */
|
|
201
231
|
export type BindMountBranchStrategy = HeadBranchStrategy | MergeToHeadBranchStrategy | NamedBranchStrategy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SandboxProvider.d.ts","sourceRoot":"","sources":["../src/SandboxProvider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,iGAAiG;AACjG,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,8CAA8C;AAC9C,MAAM,WAAW,sBAAsB;IACrC,wDAAwD;IACxD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B
|
|
1
|
+
{"version":3,"file":"SandboxProvider.d.ts","sourceRoot":"","sources":["../src/SandboxProvider.ts"],"names":[],"mappings":"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"}
|
package/dist/SandboxProvider.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SandboxProvider.js","sourceRoot":"","sources":["../src/SandboxProvider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"SandboxProvider.js","sourceRoot":"","sources":["../src/SandboxProvider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+SH;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC5C,MAAsC,EACZ,EAAE,CAAC,CAAC;IAC9B,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;IACrB,cAAc,EAAE,MAAM,CAAC,cAAc;IACrC,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,MAAqC,EACZ,EAAE,CAAC,CAAC;IAC7B,GAAG,EAAE,UAAU;IACf,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CAAC,CAAC"}
|
package/dist/SessionStore.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export declare const hostSessionStore: (cwd: string, projectsDir?: string | unde
|
|
|
40
40
|
* @param handle - The bind-mount sandbox handle for file transfer.
|
|
41
41
|
* @param projectsDir - The sandbox-side path to `~/.claude/projects`.
|
|
42
42
|
*/
|
|
43
|
-
export declare const sandboxSessionStore: (cwd: string, handle: Pick<BindMountSandboxHandle, "copyFileIn" | "copyFileOut">, projectsDir: string) => SessionStore;
|
|
43
|
+
export declare const sandboxSessionStore: (cwd: string, handle: Pick<BindMountSandboxHandle, "copyFileIn" | "copyFileOut" | "exec">, projectsDir: string) => SessionStore;
|
|
44
44
|
/**
|
|
45
45
|
* Transfer a session from one store to another, rewriting `cwd` fields in
|
|
46
46
|
* the JSONL entries from the source store's cwd to the target store's cwd.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionStore.d.ts","sourceRoot":"","sources":["../src/SessionStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAMnE,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,iEAAiE;IACjE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,oEAAoE;IACpE,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAMD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,yBAI7B,CAAC;AAMF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,iEAoB5B,CAAC;AAMF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"SessionStore.d.ts","sourceRoot":"","sources":["../src/SessionStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAMnE,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,iEAAiE;IACjE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,oEAAoE;IACpE,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAMD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,yBAI7B,CAAC;AAMF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,iEAoB5B,CAAC;AAMF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,iIAyC/B,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,eAAe,qEAyB3B,CAAC"}
|
package/dist/SessionStore.js
CHANGED
|
@@ -81,6 +81,9 @@ export const sandboxSessionStore = (cwd, handle, projectsDir) => {
|
|
|
81
81
|
const tmpPath = join(tmpdir(), `sandcastle-session-${id}-${Date.now()}.jsonl`);
|
|
82
82
|
await writeFile(tmpPath, content);
|
|
83
83
|
try {
|
|
84
|
+
// Ensure the sandbox-side project directory exists — `docker cp` /
|
|
85
|
+
// `podman cp` require the destination's parent directory to exist.
|
|
86
|
+
await handle.exec(`mkdir -p ${JSON.stringify(projectDir)}`);
|
|
84
87
|
await handle.copyFileIn(tmpPath, sandboxPath);
|
|
85
88
|
}
|
|
86
89
|
finally {
|
package/dist/SessionStore.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionStore.js","sourceRoot":"","sources":["../src/SessionStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAmBjC,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAU,EAAE;IACvD,+CAA+C;IAC/C,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAClE,OAAO,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,GAAW,EACX,WAAoB,EACN,EAAE;IAChB,MAAM,OAAO,GACX,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE1C,OAAO;QACL,GAAG;QACH,eAAe,EAAE,CAAC,EAAU,EAAU,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC;QACxE,WAAW,EAAE,KAAK,EAAE,EAAU,EAAmB,EAAE;YACjD,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAClE,CAAC;QACD,YAAY,EAAE,KAAK,EAAE,EAAU,EAAE,OAAe,EAAiB,EAAE;YACjE,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,MAAM,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAC5D,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,8EAA8E;AAC9E,8BAA8B;AAC9B,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,GAAW,EACX,
|
|
1
|
+
{"version":3,"file":"SessionStore.js","sourceRoot":"","sources":["../src/SessionStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,13 +21,16 @@ export interface WorktreeInfo {
|
|
|
21
21
|
* - If `branch` is specified, checks out that branch.
|
|
22
22
|
* - If not, creates a temporary `sandcastle/<timestamp>` branch.
|
|
23
23
|
*
|
|
24
|
-
*
|
|
24
|
+
* When `branch` collides with an existing managed worktree:
|
|
25
|
+
* - Clean → reuses the existing worktree.
|
|
26
|
+
* - Dirty (uncommitted changes) → reuses with a console warning (ADR 0003).
|
|
27
|
+
*
|
|
28
|
+
* Collisions with the main working tree or external worktrees always throw.
|
|
25
29
|
*/
|
|
26
30
|
export declare const create: (repoDir: string, opts?: {
|
|
27
31
|
branch?: string | undefined;
|
|
32
|
+
baseBranch?: string | undefined;
|
|
28
33
|
name?: string | undefined;
|
|
29
|
-
/** When false, reuse an existing worktree instead of failing on collision. Default: true. */
|
|
30
|
-
throwOnDuplicateWorktree?: boolean | undefined;
|
|
31
34
|
} | undefined) => Effect.Effect<WorktreeInfo, WorktreeError | WorktreeTimeoutError, FileSystem.FileSystem>;
|
|
32
35
|
/**
|
|
33
36
|
* Returns true if the worktree at `worktreePath` has any uncommitted changes:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorktreeManager.d.ts","sourceRoot":"","sources":["../src/WorktreeManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAe,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"WorktreeManager.d.ts","sourceRoot":"","sources":["../src/WorktreeManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAe,MAAM,aAAa,CAAC;AA0B/E,mEAAmE;AACnE,eAAO,MAAM,YAAY,0BACsB,CAAC;AAsBhD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,uCAMlC,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,gBAAgB,kEAK1B,CAAC;AAEJ,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAsCD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,MAAM;;;;0GAqIhB,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,qBAAqB,wEAK/B,CAAC;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,MAAM,qEAQlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,uGAqEpB,CAAC"}
|
package/dist/WorktreeManager.js
CHANGED
|
@@ -4,6 +4,18 @@ import { execFile } from "node:child_process";
|
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { WorktreeError, WorktreeTimeoutError, withTimeout } from "./errors.js";
|
|
6
6
|
const WORKTREE_TIMEOUT_MS = 30_000;
|
|
7
|
+
/**
|
|
8
|
+
* Git global flags that prevent `git worktree add -b` from writing upstream
|
|
9
|
+
* tracking config to `.git/config`. Without these, a user's global
|
|
10
|
+
* `branch.autoSetupMerge` or `push.autoSetupRemote` can cause a config write
|
|
11
|
+
* that races with other processes holding `.git/config.lock`.
|
|
12
|
+
*/
|
|
13
|
+
const NO_CONFIG_LOCK_FLAGS = [
|
|
14
|
+
"-c",
|
|
15
|
+
"branch.autoSetupMerge=false",
|
|
16
|
+
"-c",
|
|
17
|
+
"push.autoSetupRemote=false",
|
|
18
|
+
];
|
|
7
19
|
/** Format a timestamp as YYYYMMDD-HHMMSS */
|
|
8
20
|
const formatTimestamp = (date) => {
|
|
9
21
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -67,7 +79,11 @@ const listWorktrees = (repoDir) => execGit(["worktree", "list", "--porcelain"],
|
|
|
67
79
|
* - If `branch` is specified, checks out that branch.
|
|
68
80
|
* - If not, creates a temporary `sandcastle/<timestamp>` branch.
|
|
69
81
|
*
|
|
70
|
-
*
|
|
82
|
+
* When `branch` collides with an existing managed worktree:
|
|
83
|
+
* - Clean → reuses the existing worktree.
|
|
84
|
+
* - Dirty (uncommitted changes) → reuses with a console warning (ADR 0003).
|
|
85
|
+
*
|
|
86
|
+
* Collisions with the main working tree or external worktrees always throw.
|
|
71
87
|
*/
|
|
72
88
|
export const create = (repoDir, opts) => Effect.gen(function* () {
|
|
73
89
|
const fs = yield* FileSystem.FileSystem;
|
|
@@ -99,23 +115,49 @@ export const create = (repoDir, opts) => Effect.gen(function* () {
|
|
|
99
115
|
const existing = yield* listWorktrees(repoDir);
|
|
100
116
|
const collision = existing.find((wt) => wt.branch === branch);
|
|
101
117
|
if (collision) {
|
|
102
|
-
|
|
118
|
+
// Only reuse worktrees managed by sandcastle (under .sandcastle/worktrees/)
|
|
119
|
+
const isManagedWorktree = collision.path.startsWith(worktreesDir);
|
|
120
|
+
if (isManagedWorktree) {
|
|
121
|
+
const dirty = yield* hasUncommittedChanges(collision.path);
|
|
122
|
+
if (dirty) {
|
|
123
|
+
console.warn(`Reusing worktree at ${collision.path} (branch '${branch}') — worktree has uncommitted changes`);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
console.log(`Reusing existing worktree at ${collision.path} (branch '${branch}')`);
|
|
127
|
+
}
|
|
103
128
|
return { path: collision.path, branch };
|
|
104
129
|
}
|
|
130
|
+
// Branch is checked out in the main working tree or external worktree
|
|
105
131
|
yield* Effect.fail(new WorktreeError({
|
|
106
132
|
message: `Branch '${branch}' is already checked out in worktree at '${collision.path}'. ` +
|
|
107
133
|
`Use a different branch name, or wait for the other run to finish.`,
|
|
108
134
|
}));
|
|
109
135
|
}
|
|
110
|
-
yield* execGit(["worktree", "add", worktreePath, branch], repoDir).pipe(Effect.catchAll((e) => {
|
|
136
|
+
yield* execGit([...NO_CONFIG_LOCK_FLAGS, "worktree", "add", worktreePath, branch], repoDir).pipe(Effect.catchAll((e) => {
|
|
111
137
|
if (e.message.includes("invalid reference")) {
|
|
112
|
-
return execGit([
|
|
138
|
+
return execGit([
|
|
139
|
+
...NO_CONFIG_LOCK_FLAGS,
|
|
140
|
+
"worktree",
|
|
141
|
+
"add",
|
|
142
|
+
"-b",
|
|
143
|
+
branch,
|
|
144
|
+
worktreePath,
|
|
145
|
+
opts?.baseBranch ?? "HEAD",
|
|
146
|
+
], repoDir);
|
|
113
147
|
}
|
|
114
148
|
return Effect.fail(e);
|
|
115
149
|
}));
|
|
116
150
|
}
|
|
117
151
|
else {
|
|
118
|
-
yield* execGit([
|
|
152
|
+
yield* execGit([
|
|
153
|
+
...NO_CONFIG_LOCK_FLAGS,
|
|
154
|
+
"worktree",
|
|
155
|
+
"add",
|
|
156
|
+
"-b",
|
|
157
|
+
branch,
|
|
158
|
+
worktreePath,
|
|
159
|
+
"HEAD",
|
|
160
|
+
], repoDir).pipe(Effect.catchAll((e) => {
|
|
119
161
|
if (e.message.includes("already checked out") ||
|
|
120
162
|
e.message.includes("already exists")) {
|
|
121
163
|
return Effect.fail(new WorktreeError({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorktreeManager.js","sourceRoot":"","sources":["../src/WorktreeManager.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"WorktreeManager.js","sourceRoot":"","sources":["../src/WorktreeManager.ts"],"names":[],"mappings":"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"}
|
package/dist/createSandbox.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ import type { SandboxProvider } from "./SandboxProvider.js";
|
|
|
9
9
|
export interface CreateSandboxOptions {
|
|
10
10
|
/** Explicit branch for the worktree (required). */
|
|
11
11
|
readonly branch: string;
|
|
12
|
+
/**
|
|
13
|
+
* Ref to fork from when `branch` does not yet exist. Ignored when the branch
|
|
14
|
+
* already exists. Defaults to `HEAD`.
|
|
15
|
+
*/
|
|
16
|
+
readonly baseBranch?: string;
|
|
12
17
|
/** Sandbox provider (e.g. docker({ imageName: "sandcastle:myrepo" })). */
|
|
13
18
|
readonly sandbox: SandboxProvider;
|
|
14
19
|
/**
|
|
@@ -24,8 +29,6 @@ export interface CreateSandboxOptions {
|
|
|
24
29
|
readonly hooks?: SandboxHooks;
|
|
25
30
|
/** Paths relative to the host repo root to copy into the worktree at creation time. */
|
|
26
31
|
readonly copyToWorktree?: string[];
|
|
27
|
-
/** When false, reuse an existing worktree instead of failing on collision. Default: true. */
|
|
28
|
-
readonly throwOnDuplicateWorktree?: boolean;
|
|
29
32
|
/** @internal Test-only overrides to bypass the sandbox provider. */
|
|
30
33
|
readonly _test?: {
|
|
31
34
|
readonly buildSandboxLayer?: (sandboxDir: string) => Layer.Layer<SandboxTag>;
|
|
@@ -50,6 +53,16 @@ export interface SandboxRunOptions {
|
|
|
50
53
|
readonly name?: string;
|
|
51
54
|
/** Logging mode. */
|
|
52
55
|
readonly logging?: LoggingOption;
|
|
56
|
+
/**
|
|
57
|
+
* An `AbortSignal` that cancels the run when aborted.
|
|
58
|
+
*
|
|
59
|
+
* - Pre-aborted signal rejects immediately without setup.
|
|
60
|
+
* - Mid-iteration abort kills the in-flight agent subprocess.
|
|
61
|
+
* - The rejected promise surfaces `signal.reason` verbatim.
|
|
62
|
+
* - The `Sandbox` handle remains usable after abort — call `.run()` again
|
|
63
|
+
* with a fresh signal, or `.close()` to tear down.
|
|
64
|
+
*/
|
|
65
|
+
readonly signal?: AbortSignal;
|
|
53
66
|
}
|
|
54
67
|
export interface SandboxRunResult {
|
|
55
68
|
/** Per-iteration results (use `iterations.length` for the count). */
|
|
@@ -76,6 +89,14 @@ export interface SandboxInteractiveOptions {
|
|
|
76
89
|
readonly promptArgs?: PromptArgs;
|
|
77
90
|
/** Display name for this interactive session. */
|
|
78
91
|
readonly name?: string;
|
|
92
|
+
/**
|
|
93
|
+
* An `AbortSignal` that cancels the interactive session when aborted.
|
|
94
|
+
*
|
|
95
|
+
* - Pre-aborted signal rejects immediately without setup.
|
|
96
|
+
* - The rejected promise surfaces `signal.reason` verbatim.
|
|
97
|
+
* - The `Sandbox` handle remains usable after abort.
|
|
98
|
+
*/
|
|
99
|
+
readonly signal?: AbortSignal;
|
|
79
100
|
}
|
|
80
101
|
export interface SandboxInteractiveResult {
|
|
81
102
|
/** List of commits made during the interactive session. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSandbox.d.ts","sourceRoot":"","sources":["../src/createSandbox.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,EAAO,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAUxD,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"createSandbox.d.ts","sourceRoot":"","sources":["../src/createSandbox.ts"],"names":[],"mappings":"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"}
|
package/dist/createSandbox.js
CHANGED
|
@@ -6,7 +6,8 @@ import { resolveEnv } from "./EnvResolver.js";
|
|
|
6
6
|
import { mergeProviderEnv } from "./mergeProviderEnv.js";
|
|
7
7
|
import { orchestrate } from "./Orchestrator.js";
|
|
8
8
|
import { defaultSessionPathsLayer } from "./SessionPaths.js";
|
|
9
|
-
import {
|
|
9
|
+
import { callbackAgentStreamEmitterLayer, noopAgentStreamEmitterLayer, } from "./AgentStreamEmitter.js";
|
|
10
|
+
import { substitutePromptArgs, validateNoArgsWithInlinePrompt, validateNoBuiltInArgOverride, BUILT_IN_PROMPT_ARG_KEYS, } from "./PromptArgumentSubstitution.js";
|
|
10
11
|
import { resolvePrompt } from "./PromptResolver.js";
|
|
11
12
|
import { preprocessPrompt } from "./PromptPreprocessor.js";
|
|
12
13
|
import { buildLogFilename, printFileDisplayStartup } from "./run.js";
|
|
@@ -29,13 +30,21 @@ const buildSandboxHandle = (ctx, close) => {
|
|
|
29
30
|
branch,
|
|
30
31
|
worktreePath: worktreePath,
|
|
31
32
|
run: async (runOptions) => {
|
|
33
|
+
// If signal is already aborted, reject immediately without any setup
|
|
34
|
+
runOptions.signal?.throwIfAborted();
|
|
32
35
|
const { agent: provider, prompt, promptFile, maxIterations = 1, } = runOptions;
|
|
33
|
-
const
|
|
36
|
+
const resolved = await Effect.runPromise(resolvePrompt({ prompt, promptFile }).pipe(Effect.provide(NodeContext.layer)));
|
|
37
|
+
const rawPrompt = resolved.text;
|
|
38
|
+
const isInlinePrompt = resolved.source === "inline";
|
|
34
39
|
const userArgs = runOptions.promptArgs ?? {};
|
|
35
40
|
const currentHostBranch = await Effect.runPromise(WorktreeManager.getCurrentBranch(hostRepoDir));
|
|
36
41
|
const displayRef = Ref.unsafeMake([]);
|
|
37
42
|
const silentDisplayLayer = SilentDisplay.layer(displayRef);
|
|
38
43
|
const resolvedPrompt = await Effect.runPromise(Effect.gen(function* () {
|
|
44
|
+
if (isInlinePrompt) {
|
|
45
|
+
yield* validateNoArgsWithInlinePrompt(userArgs);
|
|
46
|
+
return rawPrompt;
|
|
47
|
+
}
|
|
39
48
|
yield* validateNoBuiltInArgOverride(userArgs);
|
|
40
49
|
const effectiveArgs = {
|
|
41
50
|
SOURCE_BRANCH: branch,
|
|
@@ -69,21 +78,34 @@ const buildSandboxHandle = (ctx, close) => {
|
|
|
69
78
|
preservedWorktreePath: undefined,
|
|
70
79
|
}))),
|
|
71
80
|
});
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
const agentStreamEmitterLayer = resolvedLogging.type === "file" && resolvedLogging.onAgentStreamEvent
|
|
82
|
+
? callbackAgentStreamEmitterLayer(resolvedLogging.onAgentStreamEvent)
|
|
83
|
+
: noopAgentStreamEmitterLayer;
|
|
84
|
+
const runLayer = Layer.mergeAll(reuseFactoryLayer, runDisplayLayer, defaultSessionPathsLayer, agentStreamEmitterLayer);
|
|
85
|
+
let result;
|
|
86
|
+
try {
|
|
87
|
+
result = await Effect.runPromise(Effect.gen(function* () {
|
|
88
|
+
const display = yield* Display;
|
|
89
|
+
yield* display.intro(runOptions.name ?? "sandcastle");
|
|
90
|
+
return yield* orchestrate({
|
|
91
|
+
hostRepoDir,
|
|
92
|
+
iterations: maxIterations,
|
|
93
|
+
prompt: resolvedPrompt,
|
|
94
|
+
branch,
|
|
95
|
+
provider,
|
|
96
|
+
completionSignal: runOptions.completionSignal,
|
|
97
|
+
idleTimeoutSeconds: runOptions.idleTimeoutSeconds,
|
|
98
|
+
name: runOptions.name,
|
|
99
|
+
signal: runOptions.signal,
|
|
100
|
+
skipPromptExpansion: isInlinePrompt,
|
|
101
|
+
});
|
|
102
|
+
}).pipe(Effect.provide(runLayer)));
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
// If the signal was aborted, surface its reason verbatim
|
|
106
|
+
runOptions.signal?.throwIfAborted();
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
87
109
|
return {
|
|
88
110
|
iterations: result.iterations,
|
|
89
111
|
completionSignal: result.completionSignal,
|
|
@@ -93,6 +115,8 @@ const buildSandboxHandle = (ctx, close) => {
|
|
|
93
115
|
};
|
|
94
116
|
},
|
|
95
117
|
interactive: async (interactiveOptions) => {
|
|
118
|
+
// If signal is already aborted, reject immediately without any setup
|
|
119
|
+
interactiveOptions.signal?.throwIfAborted();
|
|
96
120
|
const { agent: provider, prompt, promptFile } = interactiveOptions;
|
|
97
121
|
if (!provider.buildInteractiveArgs) {
|
|
98
122
|
throw new Error(`Agent provider "${provider.name}" does not support buildInteractiveArgs, required for interactive sessions.`);
|
|
@@ -102,39 +126,79 @@ const buildSandboxHandle = (ctx, close) => {
|
|
|
102
126
|
`The provider must implement the optional interactiveExec method to use interactive().`);
|
|
103
127
|
}
|
|
104
128
|
const interactiveExecFn = providerHandle.interactiveExec.bind(providerHandle);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
let lifecycleResult;
|
|
130
|
+
try {
|
|
131
|
+
lifecycleResult = await Effect.runPromise(Effect.gen(function* () {
|
|
132
|
+
const resolved = yield* resolvePrompt({ prompt, promptFile });
|
|
133
|
+
const rawPrompt = resolved.text;
|
|
134
|
+
const isInlinePrompt = resolved.source === "inline";
|
|
135
|
+
const userArgs = interactiveOptions.promptArgs ?? {};
|
|
136
|
+
const currentHostBranch = yield* WorktreeManager.getCurrentBranch(hostRepoDir);
|
|
137
|
+
let resolvedPrompt;
|
|
138
|
+
if (isInlinePrompt) {
|
|
139
|
+
yield* validateNoArgsWithInlinePrompt(userArgs);
|
|
140
|
+
resolvedPrompt = rawPrompt;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
yield* validateNoBuiltInArgOverride(userArgs);
|
|
144
|
+
const effectiveArgs = {
|
|
145
|
+
SOURCE_BRANCH: branch,
|
|
146
|
+
TARGET_BRANCH: currentHostBranch,
|
|
147
|
+
...userArgs,
|
|
148
|
+
};
|
|
149
|
+
const builtInArgKeysSet = new Set(BUILT_IN_PROMPT_ARG_KEYS);
|
|
150
|
+
resolvedPrompt = yield* substitutePromptArgs(rawPrompt, effectiveArgs, builtInArgKeysSet);
|
|
151
|
+
}
|
|
152
|
+
return yield* withSandboxLifecycle({
|
|
153
|
+
hostRepoDir,
|
|
154
|
+
sandboxRepoDir,
|
|
155
|
+
branch,
|
|
156
|
+
hostWorktreePath: worktreePath,
|
|
157
|
+
applyToHost,
|
|
158
|
+
}, (ctx) => Effect.gen(function* () {
|
|
159
|
+
const fullPrompt = isInlinePrompt
|
|
160
|
+
? resolvedPrompt
|
|
161
|
+
: yield* preprocessPrompt(resolvedPrompt, ctx.sandbox, ctx.sandboxRepoDir);
|
|
162
|
+
const interactiveArgs = provider.buildInteractiveArgs({
|
|
163
|
+
prompt: fullPrompt,
|
|
164
|
+
dangerouslySkipPermissions: true,
|
|
165
|
+
});
|
|
166
|
+
const execPromise = interactiveExecFn(interactiveArgs, {
|
|
167
|
+
stdin: process.stdin,
|
|
168
|
+
stdout: process.stdout,
|
|
169
|
+
stderr: process.stderr,
|
|
170
|
+
cwd: sandboxRepoDir,
|
|
171
|
+
});
|
|
172
|
+
// Race exec with abort signal if provided
|
|
173
|
+
const signal = interactiveOptions.signal;
|
|
174
|
+
const result = yield* Effect.promise(() => {
|
|
175
|
+
if (!signal)
|
|
176
|
+
return execPromise;
|
|
177
|
+
if (signal.aborted)
|
|
178
|
+
return Promise.reject(signal.reason);
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
const onAbort = () => reject(signal.reason);
|
|
181
|
+
signal.addEventListener("abort", onAbort, {
|
|
182
|
+
once: true,
|
|
183
|
+
});
|
|
184
|
+
execPromise.then((r) => {
|
|
185
|
+
signal.removeEventListener("abort", onAbort);
|
|
186
|
+
resolve(r);
|
|
187
|
+
}, (e) => {
|
|
188
|
+
signal.removeEventListener("abort", onAbort);
|
|
189
|
+
reject(e);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
return result.exitCode;
|
|
134
194
|
}));
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
195
|
+
}).pipe(Effect.provide(sandboxLayer), Effect.provide(ClackDisplay.layer), Effect.provide(NodeContext.layer)));
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
// If the signal was aborted, surface its reason verbatim
|
|
199
|
+
interactiveOptions.signal?.throwIfAborted();
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
138
202
|
return {
|
|
139
203
|
commits: lifecycleResult.commits,
|
|
140
204
|
exitCode: lifecycleResult.result,
|
|
@@ -259,7 +323,7 @@ export const createSandbox = async (options) => {
|
|
|
259
323
|
yield* WorktreeManager.pruneStale(hostRepoDir).pipe(Effect.catchAll(() => Effect.void));
|
|
260
324
|
const worktreeInfo = yield* WorktreeManager.create(hostRepoDir, {
|
|
261
325
|
branch,
|
|
262
|
-
|
|
326
|
+
baseBranch: options.baseBranch,
|
|
263
327
|
});
|
|
264
328
|
return { hostRepoDir, worktreeInfo };
|
|
265
329
|
}).pipe(Effect.provide(NodeContext.layer)));
|