@snappedly-tools/shipyard 0.6.0 → 0.7.0-staging.36081473933
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 +64 -165
- package/dist/MountConfig-BHnKnA4h.d.ts +145 -0
- package/dist/{chunk-WAXEMZUV.js → chunk-44I2BL6E.js} +225 -33
- package/dist/chunk-44I2BL6E.js.map +1 -0
- package/dist/{chunk-56TDSWFU.js → chunk-JI3HDDMS.js} +3 -3
- package/dist/{chunk-56TDSWFU.js.map → chunk-JI3HDDMS.js.map} +1 -1
- package/dist/{chunk-FDYOTN55.js → chunk-L6PX5QTU.js} +253 -878
- package/dist/chunk-L6PX5QTU.js.map +1 -0
- package/dist/index.d.ts +117 -97
- package/dist/index.js +322 -344
- package/dist/index.js.map +1 -1
- package/dist/main.js +235 -139
- package/dist/main.js.map +1 -1
- package/dist/sandboxes/docker.d.ts +1 -3
- package/dist/sandboxes/docker.js +2 -4
- package/dist/templates/parallel-planner/main.mts +67 -9
- package/dist/templates/parallel-planner/planner-branch.mts +151 -0
- package/dist/templates/parallel-planner-with-review/main.mts +70 -12
- package/dist/templates/parallel-planner-with-review/planner-branch.mts +151 -0
- package/dist/templates/sequential-reviewer/main.mts +52 -3
- package/dist/templates/simple-loop/main.mts +51 -2
- package/package.json +1 -17
- package/dist/MountConfig-bZoCs4Dd.d.ts +0 -26
- package/dist/SandboxProvider-XJQqEdSf.d.ts +0 -261
- package/dist/chunk-ACD46ZM4.js +0 -136
- package/dist/chunk-ACD46ZM4.js.map +0 -1
- package/dist/chunk-FDYOTN55.js.map +0 -1
- package/dist/chunk-KMGNFXKN.js +0 -38
- package/dist/chunk-KMGNFXKN.js.map +0 -1
- package/dist/chunk-SOJTAJTF.js +0 -78
- package/dist/chunk-SOJTAJTF.js.map +0 -1
- package/dist/chunk-WAXEMZUV.js.map +0 -1
- package/dist/sandboxes/no-sandbox.d.ts +0 -37
- package/dist/sandboxes/no-sandbox.js +0 -4
- package/dist/sandboxes/no-sandbox.js.map +0 -1
- package/dist/sandboxes/vercel.d.ts +0 -104
- package/dist/sandboxes/vercel.js +0 -166
- package/dist/sandboxes/vercel.js.map +0 -1
- package/dist/templates/blank/main.mts +0 -13
- package/dist/templates/blank/prompt.md +0 -12
- package/dist/templates/blank/template.json +0 -4
package/dist/index.js
CHANGED
|
@@ -1,36 +1,25 @@
|
|
|
1
|
-
import { CODEX_MODELS, resolveEnv, formatErrorMessage, buildLogDirectoryName } from './chunk-
|
|
2
|
-
export { CODEX_MODELS, CODEX_REASONING_EFFORTS } from './chunk-
|
|
3
|
-
import { CwdError, resolveCwd, getCurrentBranch, generateTempBranchName, assertNoSymlinkComponents, FileDisplay, ClackDisplay, WorktreeDockerSandboxFactory, SandboxConfig, Display, CLI_NAME, PRODUCT_NAME, pruneStale, create,
|
|
4
|
-
|
|
5
|
-
export { createBindMountSandboxProvider, createIsolatedSandboxProvider } from './chunk-KMGNFXKN.js';
|
|
6
|
-
import { noSandbox } from './chunk-SOJTAJTF.js';
|
|
7
|
-
import './chunk-ACD46ZM4.js';
|
|
1
|
+
import { CODEX_MODELS, resolveEnv, formatErrorMessage, buildLogDirectoryName } from './chunk-JI3HDDMS.js';
|
|
2
|
+
export { CODEX_MODELS, CODEX_REASONING_EFFORTS } from './chunk-JI3HDDMS.js';
|
|
3
|
+
import { CwdError, resolveCwd, getCurrentBranch, generateTempBranchName, assertNoSymlinkComponents, FileDisplay, ClackDisplay, WorktreeDockerSandboxFactory, SandboxConfig, Display, CLI_NAME, PRODUCT_NAME, pruneStale, create, runHostHooks, startSandbox, remove, makeSandboxFromHandle, withSandboxLifecycle, hasUncommittedChanges, shellQuote, registerShutdown, toSessionTransferHandle, SandboxFactory, syncOut, PromptError, CONFIG_DIR, LOGS_DIR, AgentError, SessionCaptureError, PromptExpansionTimeoutError, assertExcludesRepositoryRunner, resolveSafeRelativePath, CopyToWorktreeError, withTimeout, CopyToWorktreeTimeoutError, SilentDisplay, AgentIdleTimeoutError } from './chunk-L6PX5QTU.js';
|
|
4
|
+
export { createIsolatedSandboxProvider } from './chunk-L6PX5QTU.js';
|
|
8
5
|
import { NodeContext, NodeFileSystem } from '@effect/platform-node';
|
|
9
|
-
import { mkdirSync, chmodSync, appendFileSync, constants } from 'fs';
|
|
6
|
+
import { existsSync, mkdirSync, chmodSync, appendFileSync, constants } from 'fs';
|
|
10
7
|
import path, { join, posix, dirname, relative } from 'path';
|
|
11
8
|
import { styleText } from 'util';
|
|
12
9
|
import { Context, Effect, Layer, Clock, Duration, Option, Deferred, Ref, Fiber } from 'effect';
|
|
13
10
|
import { FileSystem } from '@effect/platform';
|
|
14
11
|
import * as clack from '@clack/prompts';
|
|
12
|
+
import { execFile } from 'child_process';
|
|
15
13
|
import { readdir, access, readFile, mkdir, mkdtemp, writeFile, rm, lstat, open, chmod } from 'fs/promises';
|
|
16
14
|
import { homedir, tmpdir } from 'os';
|
|
17
15
|
import { createHmac, timingSafeEqual, createHash, randomUUID } from 'crypto';
|
|
18
16
|
|
|
19
17
|
// src/resumePrecheck.ts
|
|
20
18
|
var assertResumeSessionExists = async (params) => {
|
|
21
|
-
const { provider,
|
|
19
|
+
const { provider, hostRepoDir, resumeSession } = params;
|
|
22
20
|
if (!provider.sessionStorage) {
|
|
23
21
|
throw new Error(`${provider.name} does not support resumeSession`);
|
|
24
22
|
}
|
|
25
|
-
if (sandboxTag === "none") {
|
|
26
|
-
const found = await provider.sessionStorage.findByIdOnHost(resumeSession);
|
|
27
|
-
if (!found.path) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
`resumeSession "${resumeSession}" not found under ${found.searchedRoot}`
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
23
|
const exists = await provider.sessionStorage.existsOnHost(
|
|
35
24
|
hostRepoDir,
|
|
36
25
|
resumeSession
|
|
@@ -424,7 +413,12 @@ var orchestrate = (options) => {
|
|
|
424
413
|
yield* checkAbort();
|
|
425
414
|
yield* display.status(label(`Iteration ${i}/${iterations}`), "info");
|
|
426
415
|
const sandboxResult = yield* factory.withSandbox(
|
|
427
|
-
({
|
|
416
|
+
({
|
|
417
|
+
hostWorktreePath,
|
|
418
|
+
sandboxRepoPath,
|
|
419
|
+
applyToHost,
|
|
420
|
+
sessionTransferHandle
|
|
421
|
+
}, sandbox) => withSandboxLifecycle(
|
|
428
422
|
{
|
|
429
423
|
hostRepoDir,
|
|
430
424
|
sandboxRepoDir: sandboxRepoPath,
|
|
@@ -440,14 +434,14 @@ var orchestrate = (options) => {
|
|
|
440
434
|
(ctx) => Effect.gen(function* () {
|
|
441
435
|
const iterationResumeSession = i === 1 ? options.resumeSession : void 0;
|
|
442
436
|
const iterationForkSession = i === 1 ? options.forkSession : void 0;
|
|
443
|
-
if (iterationResumeSession &&
|
|
437
|
+
if (iterationResumeSession && sessionTransferHandle && provider.sessionStorage) {
|
|
444
438
|
yield* display.status(label("Resuming session"), "info");
|
|
445
439
|
yield* Effect.tryPromise({
|
|
446
440
|
try: () => provider.sessionStorage.resumeIntoSandbox({
|
|
447
441
|
hostCwd: hostRepoDir,
|
|
448
442
|
sandboxCwd: ctx.sandboxRepoDir,
|
|
449
443
|
sessionId: iterationResumeSession,
|
|
450
|
-
handle:
|
|
444
|
+
handle: sessionTransferHandle
|
|
451
445
|
}),
|
|
452
446
|
catch: (e) => new SessionCaptureError({
|
|
453
447
|
message: `Session resume failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
@@ -539,14 +533,14 @@ var orchestrate = (options) => {
|
|
|
539
533
|
yield* display.status(label("Agent stopped"), "info");
|
|
540
534
|
let sessionFilePath;
|
|
541
535
|
let usage = streamUsage;
|
|
542
|
-
if (provider.captureSessions && provider.sessionStorage && sessionId &&
|
|
536
|
+
if (provider.captureSessions && provider.sessionStorage && sessionId && sessionTransferHandle) {
|
|
543
537
|
yield* display.status(label("Capturing session"), "info");
|
|
544
538
|
yield* Effect.tryPromise({
|
|
545
539
|
try: () => provider.sessionStorage.captureToHost({
|
|
546
540
|
hostCwd: hostRepoDir,
|
|
547
541
|
sandboxCwd: ctx.sandboxRepoDir,
|
|
548
542
|
sessionId,
|
|
549
|
-
handle:
|
|
543
|
+
handle: sessionTransferHandle
|
|
550
544
|
}),
|
|
551
545
|
catch: (e) => new SessionCaptureError({
|
|
552
546
|
message: `Session capture failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
@@ -1019,18 +1013,9 @@ async function run(options) {
|
|
|
1019
1013
|
agent: provider
|
|
1020
1014
|
} = options;
|
|
1021
1015
|
validateMaxIterations(maxIterations);
|
|
1022
|
-
const branchStrategy = options.branchStrategy ??
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
throw new Error(
|
|
1026
|
-
"head branch strategy is not supported with isolated providers"
|
|
1027
|
-
);
|
|
1028
|
-
}
|
|
1029
|
-
if (effectiveBranchType === "head" && options.copyToWorktree && options.copyToWorktree.length > 0) {
|
|
1030
|
-
throw new Error(
|
|
1031
|
-
"copyToWorktree is not supported with head branch strategy. In head mode the host working directory is bind-mounted directly."
|
|
1032
|
-
);
|
|
1033
|
-
}
|
|
1016
|
+
const branchStrategy = options.branchStrategy ?? {
|
|
1017
|
+
type: "merge-to-head"
|
|
1018
|
+
};
|
|
1034
1019
|
if (options.resumeSession && maxIterations > 1) {
|
|
1035
1020
|
throw new Error(
|
|
1036
1021
|
"resumeSession cannot be combined with maxIterations > 1. Resume applies to iteration 1 only; multi-iteration resume semantics are not supported."
|
|
@@ -1064,7 +1049,6 @@ async function run(options) {
|
|
|
1064
1049
|
if (options.resumeSession) {
|
|
1065
1050
|
await assertResumeSessionExists({
|
|
1066
1051
|
provider,
|
|
1067
|
-
sandboxTag: options.sandbox.tag,
|
|
1068
1052
|
hostRepoDir,
|
|
1069
1053
|
resumeSession: options.resumeSession
|
|
1070
1054
|
});
|
|
@@ -1096,8 +1080,8 @@ async function run(options) {
|
|
|
1096
1080
|
const currentHostBranch = await Effect.runPromise(
|
|
1097
1081
|
getCurrentBranch(hostRepoDir)
|
|
1098
1082
|
);
|
|
1099
|
-
const resolvedBranch =
|
|
1100
|
-
const targetBranch =
|
|
1083
|
+
const resolvedBranch = branch ?? generateTempBranchName(options.name);
|
|
1084
|
+
const targetBranch = branchStrategy.type === "merge-to-head" ? currentHostBranch : void 0;
|
|
1101
1085
|
const resolvedLogging = options.logging ?? {
|
|
1102
1086
|
type: "file",
|
|
1103
1087
|
path: buildDefaultLogPath(
|
|
@@ -1182,7 +1166,7 @@ async function run(options) {
|
|
|
1182
1166
|
builtInArgKeysSet
|
|
1183
1167
|
);
|
|
1184
1168
|
}
|
|
1185
|
-
const orchestrateBranch =
|
|
1169
|
+
const orchestrateBranch = branch;
|
|
1186
1170
|
const orchestrateResult = yield* orchestrate({
|
|
1187
1171
|
hostRepoDir,
|
|
1188
1172
|
iterations: maxIterations,
|
|
@@ -1333,25 +1317,16 @@ var raceAbortSignal = (effect, signal) => {
|
|
|
1333
1317
|
var interactive = async (options) => {
|
|
1334
1318
|
options.signal?.throwIfAborted();
|
|
1335
1319
|
const { prompt, promptFile, hooks, agent: provider } = options;
|
|
1336
|
-
const resolvedSandbox = options.sandbox
|
|
1337
|
-
const branchStrategy = options.branchStrategy ??
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
"head branch strategy is not supported with isolated providers"
|
|
1341
|
-
);
|
|
1342
|
-
}
|
|
1343
|
-
if (branchStrategy.type === "head" && options.copyToWorktree && options.copyToWorktree.length > 0) {
|
|
1344
|
-
throw new Error(
|
|
1345
|
-
"copyToWorktree is not supported with head branch strategy. In head mode the host working directory is bind-mounted directly."
|
|
1346
|
-
);
|
|
1347
|
-
}
|
|
1320
|
+
const resolvedSandbox = options.sandbox;
|
|
1321
|
+
const branchStrategy = options.branchStrategy ?? {
|
|
1322
|
+
type: "merge-to-head"
|
|
1323
|
+
};
|
|
1348
1324
|
if (!provider.buildInteractiveArgs) {
|
|
1349
1325
|
throw new Error(
|
|
1350
1326
|
`Agent provider "${provider.name}" does not support buildInteractiveArgs, required for interactive sessions.`
|
|
1351
1327
|
);
|
|
1352
1328
|
}
|
|
1353
1329
|
const branch = branchStrategy.type === "branch" ? branchStrategy.branch : void 0;
|
|
1354
|
-
const isHeadMode = branchStrategy.type === "head";
|
|
1355
1330
|
const sandboxProvider = resolvedSandbox;
|
|
1356
1331
|
const inner = Effect.gen(function* () {
|
|
1357
1332
|
const hostRepoDir = yield* resolveCwd(options.cwd);
|
|
@@ -1368,7 +1343,7 @@ var interactive = async (options) => {
|
|
|
1368
1343
|
});
|
|
1369
1344
|
const effectiveEnv = { ...env, ...options.env ?? {} };
|
|
1370
1345
|
const currentHostBranch = yield* getCurrentBranch(hostRepoDir);
|
|
1371
|
-
const resolvedBranch =
|
|
1346
|
+
const resolvedBranch = branch ?? generateTempBranchName(options.name);
|
|
1372
1347
|
let substitutedPrompt = rawPrompt;
|
|
1373
1348
|
if (hasPromptSource && !isInlinePrompt) {
|
|
1374
1349
|
const userArgs = options.promptArgs ?? {};
|
|
@@ -1408,86 +1383,38 @@ var interactive = async (options) => {
|
|
|
1408
1383
|
const userArgs = options.promptArgs ?? {};
|
|
1409
1384
|
yield* validateNoArgsWithInlinePrompt(userArgs);
|
|
1410
1385
|
}
|
|
1411
|
-
const lifecycleBranch =
|
|
1386
|
+
const lifecycleBranch = branch;
|
|
1412
1387
|
yield* d.intro(options.name ?? `${CLI_NAME} interactive`);
|
|
1413
1388
|
yield* d.summary("Interactive Session", {
|
|
1414
1389
|
Agent: options.name ?? provider.name,
|
|
1415
1390
|
Sandbox: sandboxProvider.name,
|
|
1416
1391
|
Branch: resolvedBranch
|
|
1417
1392
|
});
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
Effect.andThen(
|
|
1425
|
-
branch ? create(hostRepoDir, { branch }) : create(hostRepoDir, { name: options.name })
|
|
1426
|
-
)
|
|
1393
|
+
const worktreeInfo = yield* d.taskLog(
|
|
1394
|
+
"Creating worktree",
|
|
1395
|
+
() => pruneStale(hostRepoDir).pipe(
|
|
1396
|
+
Effect.catchAll(() => Effect.void),
|
|
1397
|
+
Effect.andThen(
|
|
1398
|
+
branch ? create(hostRepoDir, { branch }) : create(hostRepoDir, { name: options.name })
|
|
1427
1399
|
)
|
|
1428
|
-
)
|
|
1429
|
-
|
|
1400
|
+
)
|
|
1401
|
+
);
|
|
1430
1402
|
const handle = yield* Effect.gen(function* () {
|
|
1431
|
-
if (
|
|
1432
|
-
|
|
1433
|
-
yield* d.taskLog(
|
|
1434
|
-
"Copying files to worktree",
|
|
1435
|
-
() => copyToWorktree(
|
|
1436
|
-
options.copyToWorktree,
|
|
1437
|
-
hostRepoDir,
|
|
1438
|
-
worktreeInfo.path,
|
|
1439
|
-
options.timeouts?.copyToWorktreeMs
|
|
1440
|
-
)
|
|
1441
|
-
);
|
|
1442
|
-
}
|
|
1443
|
-
if (hooks?.host?.onWorktreeReady?.length) {
|
|
1444
|
-
yield* runHostHooks(hooks.host.onWorktreeReady, worktreeInfo.path);
|
|
1445
|
-
}
|
|
1446
|
-
} else if (hooks?.host?.onWorktreeReady?.length) {
|
|
1447
|
-
yield* runHostHooks(hooks.host.onWorktreeReady, hostRepoDir);
|
|
1448
|
-
}
|
|
1449
|
-
if (sandboxProvider.tag === "none") {
|
|
1450
|
-
const worktreePath = isHeadMode ? hostRepoDir : worktreeInfo.path;
|
|
1451
|
-
return yield* Effect.promise(
|
|
1452
|
-
() => sandboxProvider.create({
|
|
1453
|
-
worktreePath,
|
|
1454
|
-
env: effectiveEnv
|
|
1455
|
-
})
|
|
1456
|
-
);
|
|
1457
|
-
} else if (sandboxProvider.tag === "isolated") {
|
|
1458
|
-
const startResult = yield* d.taskLog(
|
|
1459
|
-
"Starting sandbox",
|
|
1460
|
-
() => startSandbox({
|
|
1461
|
-
provider: sandboxProvider,
|
|
1462
|
-
hostRepoDir: worktreeInfo.path,
|
|
1463
|
-
sourceRepoDir: hostRepoDir,
|
|
1464
|
-
env: effectiveEnv,
|
|
1465
|
-
copyPaths: options.copyToWorktree
|
|
1466
|
-
})
|
|
1467
|
-
);
|
|
1468
|
-
return startResult.handle;
|
|
1469
|
-
} else {
|
|
1470
|
-
const gitPath = join(hostRepoDir, ".git");
|
|
1471
|
-
const rawGitMounts = yield* resolveGitMounts(gitPath);
|
|
1472
|
-
const worktreeOrRepoPath = isHeadMode ? hostRepoDir : worktreeInfo.path;
|
|
1473
|
-
const gitMounts = yield* patchGitMountsForWindows(
|
|
1474
|
-
rawGitMounts,
|
|
1475
|
-
worktreeOrRepoPath,
|
|
1476
|
-
SANDBOX_REPO_DIR
|
|
1477
|
-
);
|
|
1478
|
-
const startResult = yield* d.taskLog(
|
|
1479
|
-
"Starting sandbox",
|
|
1480
|
-
() => startSandbox({
|
|
1481
|
-
provider: sandboxProvider,
|
|
1482
|
-
hostRepoDir,
|
|
1483
|
-
env: effectiveEnv,
|
|
1484
|
-
worktreeOrRepoPath,
|
|
1485
|
-
gitMounts,
|
|
1486
|
-
repoDir: SANDBOX_REPO_DIR
|
|
1487
|
-
})
|
|
1488
|
-
);
|
|
1489
|
-
return startResult.handle;
|
|
1403
|
+
if (hooks?.host?.onWorktreeReady?.length) {
|
|
1404
|
+
yield* runHostHooks(hooks.host.onWorktreeReady, worktreeInfo.path);
|
|
1490
1405
|
}
|
|
1406
|
+
const startResult = yield* d.taskLog(
|
|
1407
|
+
"Starting sandbox",
|
|
1408
|
+
() => startSandbox({
|
|
1409
|
+
provider: sandboxProvider,
|
|
1410
|
+
hostRepoDir: worktreeInfo.path,
|
|
1411
|
+
sourceRepoDir: hostRepoDir,
|
|
1412
|
+
env: effectiveEnv,
|
|
1413
|
+
copyPaths: options.copyToWorktree,
|
|
1414
|
+
copyTimeoutMs: options.timeouts?.copyToWorktreeMs
|
|
1415
|
+
})
|
|
1416
|
+
);
|
|
1417
|
+
return startResult.handle;
|
|
1491
1418
|
}).pipe(
|
|
1492
1419
|
Effect.tapError(
|
|
1493
1420
|
() => worktreeInfo ? remove(worktreeInfo.path).pipe(
|
|
@@ -1504,14 +1431,14 @@ var interactive = async (options) => {
|
|
|
1504
1431
|
const interactiveExecFn = handle.interactiveExec.bind(handle);
|
|
1505
1432
|
const sandbox = makeSandboxFromHandle(handle);
|
|
1506
1433
|
const worktreePath = handle.worktreePath;
|
|
1507
|
-
const applyToHost =
|
|
1434
|
+
const applyToHost = () => syncOut(worktreeInfo.path, handle);
|
|
1508
1435
|
const lifecycleEffect = withSandboxLifecycle(
|
|
1509
1436
|
{
|
|
1510
1437
|
hostRepoDir,
|
|
1511
1438
|
sandboxRepoDir: worktreePath,
|
|
1512
1439
|
hooks,
|
|
1513
1440
|
branch: lifecycleBranch,
|
|
1514
|
-
hostWorktreePath:
|
|
1441
|
+
hostWorktreePath: worktreeInfo.path,
|
|
1515
1442
|
applyToHost,
|
|
1516
1443
|
timeouts: options.timeouts
|
|
1517
1444
|
},
|
|
@@ -1524,7 +1451,7 @@ var interactive = async (options) => {
|
|
|
1524
1451
|
);
|
|
1525
1452
|
const interactiveArgs = provider.buildInteractiveArgs({
|
|
1526
1453
|
prompt: fullPrompt,
|
|
1527
|
-
dangerouslySkipPermissions:
|
|
1454
|
+
dangerouslySkipPermissions: true
|
|
1528
1455
|
});
|
|
1529
1456
|
const result4 = yield* raceAbortSignal(
|
|
1530
1457
|
Effect.promise(
|
|
@@ -1613,7 +1540,7 @@ var buildSandboxHandle = (ctx, close) => {
|
|
|
1613
1540
|
sandboxRepoDir,
|
|
1614
1541
|
sandbox,
|
|
1615
1542
|
providerHandle,
|
|
1616
|
-
|
|
1543
|
+
sessionTransferHandle,
|
|
1617
1544
|
applyToHost,
|
|
1618
1545
|
timeouts,
|
|
1619
1546
|
branchStrategy
|
|
@@ -1644,7 +1571,6 @@ var buildSandboxHandle = (ctx, close) => {
|
|
|
1644
1571
|
if (runOptions.resumeSession) {
|
|
1645
1572
|
await assertResumeSessionExists({
|
|
1646
1573
|
provider,
|
|
1647
|
-
sandboxTag: ctx.providerTag,
|
|
1648
1574
|
hostRepoDir,
|
|
1649
1575
|
resumeSession: runOptions.resumeSession
|
|
1650
1576
|
});
|
|
@@ -1715,7 +1641,7 @@ var buildSandboxHandle = (ctx, close) => {
|
|
|
1715
1641
|
hostWorktreePath: worktreePath,
|
|
1716
1642
|
sandboxRepoPath: sandboxRepoDir,
|
|
1717
1643
|
applyToHost,
|
|
1718
|
-
|
|
1644
|
+
sessionTransferHandle
|
|
1719
1645
|
},
|
|
1720
1646
|
sandbox
|
|
1721
1647
|
).pipe(
|
|
@@ -1935,24 +1861,13 @@ var buildSandboxHandle = (ctx, close) => {
|
|
|
1935
1861
|
var createSandboxFromWorktree = async (options) => {
|
|
1936
1862
|
const { branch, worktreePath, hostRepoDir } = options;
|
|
1937
1863
|
const isTestMode = !!options._test?.buildSandbox;
|
|
1938
|
-
if (options.copyToWorktree && options.copyToWorktree.length > 0 && options.sandbox.tag !== "isolated") {
|
|
1939
|
-
await Effect.runPromise(
|
|
1940
|
-
copyToWorktree(
|
|
1941
|
-
options.copyToWorktree,
|
|
1942
|
-
hostRepoDir,
|
|
1943
|
-
worktreePath,
|
|
1944
|
-
options.timeouts?.copyToWorktreeMs
|
|
1945
|
-
)
|
|
1946
|
-
);
|
|
1947
|
-
}
|
|
1948
1864
|
let providerHandle;
|
|
1949
1865
|
let sandbox;
|
|
1950
1866
|
let sandboxRepoDir;
|
|
1951
|
-
const isIsolated = options.sandbox.tag === "isolated";
|
|
1952
1867
|
if (isTestMode) {
|
|
1953
1868
|
sandbox = options._test.buildSandbox(worktreePath);
|
|
1954
1869
|
sandboxRepoDir = worktreePath;
|
|
1955
|
-
providerHandle = options._test.
|
|
1870
|
+
providerHandle = options._test.sessionTransferHandle;
|
|
1956
1871
|
} else {
|
|
1957
1872
|
const resolvedEnv = await Effect.runPromise(
|
|
1958
1873
|
resolveEnv(hostRepoDir).pipe(Effect.provide(NodeContext.layer))
|
|
@@ -1963,42 +1878,15 @@ var createSandboxFromWorktree = async (options) => {
|
|
|
1963
1878
|
sandboxProviderEnv: options.sandbox.env
|
|
1964
1879
|
});
|
|
1965
1880
|
const provider = options.sandbox;
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
} else if (provider.tag === "none") {
|
|
1976
|
-
startEffect = startSandbox({
|
|
1977
|
-
provider,
|
|
1978
|
-
hostRepoDir,
|
|
1979
|
-
env,
|
|
1980
|
-
worktreeOrRepoPath: worktreePath
|
|
1981
|
-
});
|
|
1982
|
-
} else {
|
|
1983
|
-
startEffect = resolveGitMounts(join(hostRepoDir, ".git")).pipe(
|
|
1984
|
-
Effect.provide(NodeFileSystem.layer),
|
|
1985
|
-
Effect.catchAll(() => Effect.succeed([])),
|
|
1986
|
-
// Patch git mounts for Windows worktree compatibility (ADR-0006)
|
|
1987
|
-
Effect.flatMap(
|
|
1988
|
-
(gitMounts) => patchGitMountsForWindows(gitMounts, worktreePath, SANDBOX_REPO_DIR)
|
|
1989
|
-
),
|
|
1990
|
-
Effect.flatMap(
|
|
1991
|
-
(gitMounts) => startSandbox({
|
|
1992
|
-
provider,
|
|
1993
|
-
hostRepoDir,
|
|
1994
|
-
env,
|
|
1995
|
-
worktreeOrRepoPath: worktreePath,
|
|
1996
|
-
gitMounts,
|
|
1997
|
-
repoDir: SANDBOX_REPO_DIR
|
|
1998
|
-
})
|
|
1999
|
-
)
|
|
2000
|
-
);
|
|
2001
|
-
}
|
|
1881
|
+
const startEffect = startSandbox({
|
|
1882
|
+
provider,
|
|
1883
|
+
hostRepoDir: worktreePath,
|
|
1884
|
+
sourceRepoDir: hostRepoDir,
|
|
1885
|
+
copySourceDir: worktreePath,
|
|
1886
|
+
env,
|
|
1887
|
+
copyPaths: options.copyToWorktree,
|
|
1888
|
+
copyTimeoutMs: options.timeouts?.copyToWorktreeMs
|
|
1889
|
+
});
|
|
2002
1890
|
const startResult = await Effect.runPromise(startEffect);
|
|
2003
1891
|
providerHandle = startResult.handle;
|
|
2004
1892
|
sandbox = startResult.sandbox;
|
|
@@ -2035,9 +1923,9 @@ var createSandboxFromWorktree = async (options) => {
|
|
|
2035
1923
|
)
|
|
2036
1924
|
);
|
|
2037
1925
|
}
|
|
2038
|
-
const applyToHost =
|
|
1926
|
+
const applyToHost = providerHandle ? () => syncOut(worktreePath, providerHandle) : () => Effect.void;
|
|
2039
1927
|
let closed = false;
|
|
2040
|
-
const
|
|
1928
|
+
const sessionTransferHandle = toSessionTransferHandle(providerHandle);
|
|
2041
1929
|
return buildSandboxHandle(
|
|
2042
1930
|
{
|
|
2043
1931
|
branch,
|
|
@@ -2046,8 +1934,7 @@ var createSandboxFromWorktree = async (options) => {
|
|
|
2046
1934
|
sandboxRepoDir,
|
|
2047
1935
|
sandbox,
|
|
2048
1936
|
providerHandle,
|
|
2049
|
-
|
|
2050
|
-
providerTag: options.sandbox.tag,
|
|
1937
|
+
sessionTransferHandle,
|
|
2051
1938
|
applyToHost,
|
|
2052
1939
|
timeouts: options.timeouts,
|
|
2053
1940
|
branchStrategy: options.branchStrategy
|
|
@@ -2063,7 +1950,6 @@ var createSandboxFromWorktree = async (options) => {
|
|
|
2063
1950
|
var createSandbox = async (options) => {
|
|
2064
1951
|
const { branch } = options;
|
|
2065
1952
|
const isTestMode = !!options._test?.buildSandbox;
|
|
2066
|
-
const isIsolated = options.sandbox.tag === "isolated";
|
|
2067
1953
|
const { hostRepoDir, worktreePath, providerHandle, sandbox, sandboxRepoDir } = await Effect.runPromise(
|
|
2068
1954
|
Effect.gen(function* () {
|
|
2069
1955
|
const hostRepoDir2 = yield* resolveCwd(options.cwd);
|
|
@@ -2075,14 +1961,6 @@ var createSandbox = async (options) => {
|
|
|
2075
1961
|
{ branch, baseBranch: options.baseBranch }
|
|
2076
1962
|
);
|
|
2077
1963
|
const prepared = yield* Effect.gen(function* () {
|
|
2078
|
-
if (options.copyToWorktree && options.copyToWorktree.length > 0 && options.sandbox.tag !== "isolated") {
|
|
2079
|
-
yield* copyToWorktree(
|
|
2080
|
-
options.copyToWorktree,
|
|
2081
|
-
hostRepoDir2,
|
|
2082
|
-
worktreePath2,
|
|
2083
|
-
options.timeouts?.copyToWorktreeMs
|
|
2084
|
-
);
|
|
2085
|
-
}
|
|
2086
1964
|
if (options.hooks?.host?.onWorktreeReady?.length) {
|
|
2087
1965
|
yield* runHostHooks(
|
|
2088
1966
|
options.hooks.host.onWorktreeReady,
|
|
@@ -2095,7 +1973,7 @@ var createSandbox = async (options) => {
|
|
|
2095
1973
|
if (isTestMode) {
|
|
2096
1974
|
sandbox2 = options._test.buildSandbox(worktreePath2);
|
|
2097
1975
|
sandboxRepoDir2 = worktreePath2;
|
|
2098
|
-
providerHandle2 = options._test.
|
|
1976
|
+
providerHandle2 = options._test.sessionTransferHandle;
|
|
2099
1977
|
} else {
|
|
2100
1978
|
const resolvedEnv = yield* resolveEnv(hostRepoDir2);
|
|
2101
1979
|
const env = mergeProviderEnv({
|
|
@@ -2104,39 +1982,14 @@ var createSandbox = async (options) => {
|
|
|
2104
1982
|
sandboxProviderEnv: options.sandbox.env
|
|
2105
1983
|
});
|
|
2106
1984
|
const provider = options.sandbox;
|
|
2107
|
-
const startResult = yield*
|
|
1985
|
+
const startResult = yield* startSandbox({
|
|
2108
1986
|
provider,
|
|
2109
1987
|
hostRepoDir: worktreePath2,
|
|
2110
1988
|
sourceRepoDir: hostRepoDir2,
|
|
2111
1989
|
env,
|
|
2112
|
-
copyPaths: options.copyToWorktree
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
hostRepoDir: hostRepoDir2,
|
|
2116
|
-
env,
|
|
2117
|
-
worktreeOrRepoPath: worktreePath2
|
|
2118
|
-
}) : resolveGitMounts(join(hostRepoDir2, ".git")).pipe(
|
|
2119
|
-
Effect.provide(NodeFileSystem.layer),
|
|
2120
|
-
Effect.catchAll(() => Effect.succeed([])),
|
|
2121
|
-
// Patch git mounts for Windows worktree compatibility (ADR-0006)
|
|
2122
|
-
Effect.flatMap(
|
|
2123
|
-
(gitMounts) => patchGitMountsForWindows(
|
|
2124
|
-
gitMounts,
|
|
2125
|
-
worktreePath2,
|
|
2126
|
-
SANDBOX_REPO_DIR
|
|
2127
|
-
)
|
|
2128
|
-
),
|
|
2129
|
-
Effect.flatMap(
|
|
2130
|
-
(gitMounts) => startSandbox({
|
|
2131
|
-
provider,
|
|
2132
|
-
hostRepoDir: hostRepoDir2,
|
|
2133
|
-
env,
|
|
2134
|
-
worktreeOrRepoPath: worktreePath2,
|
|
2135
|
-
gitMounts,
|
|
2136
|
-
repoDir: SANDBOX_REPO_DIR
|
|
2137
|
-
})
|
|
2138
|
-
)
|
|
2139
|
-
);
|
|
1990
|
+
copyPaths: options.copyToWorktree,
|
|
1991
|
+
copyTimeoutMs: options.timeouts?.copyToWorktreeMs
|
|
1992
|
+
});
|
|
2140
1993
|
providerHandle2 = startResult.handle;
|
|
2141
1994
|
sandbox2 = startResult.sandbox;
|
|
2142
1995
|
sandboxRepoDir2 = startResult.worktreePath;
|
|
@@ -2181,7 +2034,7 @@ var createSandbox = async (options) => {
|
|
|
2181
2034
|
return { hostRepoDir: hostRepoDir2, worktreePath: worktreePath2, ...prepared };
|
|
2182
2035
|
}).pipe(Effect.provide(NodeContext.layer))
|
|
2183
2036
|
);
|
|
2184
|
-
const applyToHost =
|
|
2037
|
+
const applyToHost = providerHandle ? () => syncOut(worktreePath, providerHandle) : () => Effect.void;
|
|
2185
2038
|
let closed = false;
|
|
2186
2039
|
const forceCleanup = () => {
|
|
2187
2040
|
console.error(`
|
|
@@ -2211,7 +2064,7 @@ Worktree preserved at ${worktreePath}`);
|
|
|
2211
2064
|
})
|
|
2212
2065
|
);
|
|
2213
2066
|
};
|
|
2214
|
-
const
|
|
2067
|
+
const sessionTransferHandle = toSessionTransferHandle(providerHandle);
|
|
2215
2068
|
return buildSandboxHandle(
|
|
2216
2069
|
{
|
|
2217
2070
|
branch,
|
|
@@ -2220,8 +2073,7 @@ Worktree preserved at ${worktreePath}`);
|
|
|
2220
2073
|
sandboxRepoDir,
|
|
2221
2074
|
sandbox,
|
|
2222
2075
|
providerHandle,
|
|
2223
|
-
|
|
2224
|
-
providerTag: options.sandbox.tag,
|
|
2076
|
+
sessionTransferHandle,
|
|
2225
2077
|
applyToHost,
|
|
2226
2078
|
timeouts: options.timeouts
|
|
2227
2079
|
},
|
|
@@ -2231,6 +2083,82 @@ Worktree preserved at ${worktreePath}`);
|
|
|
2231
2083
|
}
|
|
2232
2084
|
);
|
|
2233
2085
|
};
|
|
2086
|
+
var COPY_TO_WORKTREE_TIMEOUT_MS = 6e4;
|
|
2087
|
+
var getCopyOnWriteFlags = (platform) => platform === "darwin" ? ["-cR"] : ["-R", "--reflink=auto"];
|
|
2088
|
+
var copyToWorktree = (paths, hostRepoDir, worktreePath, timeoutMs) => {
|
|
2089
|
+
const effectiveTimeout = timeoutMs ?? COPY_TO_WORKTREE_TIMEOUT_MS;
|
|
2090
|
+
return Effect.gen(function* () {
|
|
2091
|
+
const cowFlags = getCopyOnWriteFlags(process.platform);
|
|
2092
|
+
for (const relativePath of paths) {
|
|
2093
|
+
let src;
|
|
2094
|
+
let dest;
|
|
2095
|
+
try {
|
|
2096
|
+
assertExcludesRepositoryRunner(relativePath);
|
|
2097
|
+
src = resolveSafeRelativePath(hostRepoDir, relativePath, "copy path");
|
|
2098
|
+
dest = resolveSafeRelativePath(worktreePath, relativePath, "copy path");
|
|
2099
|
+
} catch (error) {
|
|
2100
|
+
return yield* Effect.fail(
|
|
2101
|
+
new CopyToWorktreeError({
|
|
2102
|
+
message: `Refusing unsafe copy path ${relativePath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
2103
|
+
path: relativePath,
|
|
2104
|
+
stderr: error instanceof Error ? error.message : String(error),
|
|
2105
|
+
exitCode: null
|
|
2106
|
+
})
|
|
2107
|
+
);
|
|
2108
|
+
}
|
|
2109
|
+
if (!existsSync(src)) {
|
|
2110
|
+
continue;
|
|
2111
|
+
}
|
|
2112
|
+
yield* Effect.tryPromise({
|
|
2113
|
+
try: async () => {
|
|
2114
|
+
await assertNoSymlinkComponents(hostRepoDir, src, "copy source");
|
|
2115
|
+
await assertNoSymlinkComponents(worktreePath, dest, "copy target");
|
|
2116
|
+
},
|
|
2117
|
+
catch: (error) => new CopyToWorktreeError({
|
|
2118
|
+
message: `Refusing symlinked copy path ${relativePath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
2119
|
+
path: relativePath,
|
|
2120
|
+
stderr: error instanceof Error ? error.message : String(error),
|
|
2121
|
+
exitCode: null
|
|
2122
|
+
})
|
|
2123
|
+
});
|
|
2124
|
+
yield* Effect.async((resume) => {
|
|
2125
|
+
execFile("cp", [...cowFlags, src, dest], (error) => {
|
|
2126
|
+
if (error) {
|
|
2127
|
+
execFile("cp", ["-R", src, dest], (fallbackError, _, stderr) => {
|
|
2128
|
+
if (fallbackError) {
|
|
2129
|
+
resume(
|
|
2130
|
+
Effect.fail(
|
|
2131
|
+
new CopyToWorktreeError({
|
|
2132
|
+
message: `Failed to copy ${relativePath} to worktree: ${stderr || fallbackError.message}`,
|
|
2133
|
+
path: relativePath,
|
|
2134
|
+
stderr: stderr || fallbackError.message,
|
|
2135
|
+
exitCode: typeof fallbackError.code === "number" ? fallbackError.code : null
|
|
2136
|
+
})
|
|
2137
|
+
)
|
|
2138
|
+
);
|
|
2139
|
+
} else {
|
|
2140
|
+
resume(Effect.succeed(void 0));
|
|
2141
|
+
}
|
|
2142
|
+
});
|
|
2143
|
+
} else {
|
|
2144
|
+
resume(Effect.succeed(void 0));
|
|
2145
|
+
}
|
|
2146
|
+
});
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
}).pipe(
|
|
2150
|
+
withTimeout(
|
|
2151
|
+
effectiveTimeout,
|
|
2152
|
+
() => new CopyToWorktreeTimeoutError({
|
|
2153
|
+
message: `Copying files to worktree timed out after ${effectiveTimeout}ms`,
|
|
2154
|
+
timeoutMs: effectiveTimeout,
|
|
2155
|
+
paths
|
|
2156
|
+
})
|
|
2157
|
+
)
|
|
2158
|
+
);
|
|
2159
|
+
};
|
|
2160
|
+
|
|
2161
|
+
// src/createWorktree.ts
|
|
2234
2162
|
var createWorktree = async (options) => {
|
|
2235
2163
|
const branch = options.branchStrategy.type === "branch" ? options.branchStrategy.branch : void 0;
|
|
2236
2164
|
const baseBranch = options.branchStrategy.type === "branch" ? options.branchStrategy.baseBranch : void 0;
|
|
@@ -2277,7 +2205,7 @@ var createWorktree = async (options) => {
|
|
|
2277
2205
|
const worktreeInteractive = async (opts) => {
|
|
2278
2206
|
opts.signal?.throwIfAborted();
|
|
2279
2207
|
const { prompt, promptFile, hooks, agent: provider } = opts;
|
|
2280
|
-
const resolvedSandbox = opts.sandbox
|
|
2208
|
+
const resolvedSandbox = opts.sandbox;
|
|
2281
2209
|
if (!provider.buildInteractiveArgs) {
|
|
2282
2210
|
throw new Error(
|
|
2283
2211
|
`Agent provider "${provider.name}" does not support buildInteractiveArgs, required for interactive sessions.`
|
|
@@ -2320,46 +2248,19 @@ var createWorktree = async (options) => {
|
|
|
2320
2248
|
Sandbox: resolvedSandbox.name,
|
|
2321
2249
|
Branch: worktreeInfo.branch
|
|
2322
2250
|
});
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
hostRepoDir: worktreeInfo.path,
|
|
2337
|
-
sourceRepoDir: hostRepoDir,
|
|
2338
|
-
env: effectiveEnv
|
|
2339
|
-
})
|
|
2340
|
-
);
|
|
2341
|
-
handle = startResult.handle;
|
|
2342
|
-
} else {
|
|
2343
|
-
const gitPath = join(hostRepoDir, ".git");
|
|
2344
|
-
const rawGitMounts = yield* resolveGitMounts(gitPath);
|
|
2345
|
-
const gitMounts = yield* patchGitMountsForWindows(
|
|
2346
|
-
rawGitMounts,
|
|
2347
|
-
worktreeInfo.path,
|
|
2348
|
-
SANDBOX_REPO_DIR
|
|
2349
|
-
);
|
|
2350
|
-
const startResult = yield* d.taskLog(
|
|
2351
|
-
"Starting sandbox",
|
|
2352
|
-
() => startSandbox({
|
|
2353
|
-
provider: resolvedSandbox,
|
|
2354
|
-
hostRepoDir,
|
|
2355
|
-
env: effectiveEnv,
|
|
2356
|
-
worktreeOrRepoPath: worktreeInfo.path,
|
|
2357
|
-
gitMounts,
|
|
2358
|
-
repoDir: SANDBOX_REPO_DIR
|
|
2359
|
-
})
|
|
2360
|
-
);
|
|
2361
|
-
handle = startResult.handle;
|
|
2362
|
-
}
|
|
2251
|
+
const startResult = yield* d.taskLog(
|
|
2252
|
+
"Starting sandbox",
|
|
2253
|
+
() => startSandbox({
|
|
2254
|
+
provider: resolvedSandbox,
|
|
2255
|
+
hostRepoDir: worktreeInfo.path,
|
|
2256
|
+
sourceRepoDir: hostRepoDir,
|
|
2257
|
+
copySourceDir: worktreeInfo.path,
|
|
2258
|
+
env: effectiveEnv,
|
|
2259
|
+
copyPaths: options.copyToWorktree,
|
|
2260
|
+
copyTimeoutMs: options.timeouts?.copyToWorktreeMs
|
|
2261
|
+
})
|
|
2262
|
+
);
|
|
2263
|
+
const handle = startResult.handle;
|
|
2363
2264
|
return yield* Effect.gen(function* () {
|
|
2364
2265
|
if (!handle.interactiveExec) {
|
|
2365
2266
|
throw new Error(
|
|
@@ -2369,7 +2270,7 @@ var createWorktree = async (options) => {
|
|
|
2369
2270
|
const interactiveExecFn = handle.interactiveExec.bind(handle);
|
|
2370
2271
|
const sandbox = makeSandboxFromHandle(handle);
|
|
2371
2272
|
const worktreePath = handle.worktreePath;
|
|
2372
|
-
const applyToHost =
|
|
2273
|
+
const applyToHost = () => syncOut(worktreeInfo.path, handle);
|
|
2373
2274
|
const lifecycleEffect = withSandboxLifecycle(
|
|
2374
2275
|
{
|
|
2375
2276
|
hostRepoDir,
|
|
@@ -2393,7 +2294,7 @@ var createWorktree = async (options) => {
|
|
|
2393
2294
|
);
|
|
2394
2295
|
const interactiveArgs = provider.buildInteractiveArgs({
|
|
2395
2296
|
prompt: fullPrompt,
|
|
2396
|
-
dangerouslySkipPermissions:
|
|
2297
|
+
dangerouslySkipPermissions: true
|
|
2397
2298
|
});
|
|
2398
2299
|
const result3 = yield* raceAbortSignal(
|
|
2399
2300
|
Effect.promise(
|
|
@@ -2456,7 +2357,6 @@ var createWorktree = async (options) => {
|
|
|
2456
2357
|
if (opts.resumeSession) {
|
|
2457
2358
|
await assertResumeSessionExists({
|
|
2458
2359
|
provider,
|
|
2459
|
-
sandboxTag: sandboxProvider.tag,
|
|
2460
2360
|
hostRepoDir,
|
|
2461
2361
|
resumeSession: opts.resumeSession
|
|
2462
2362
|
});
|
|
@@ -2491,47 +2391,19 @@ var createWorktree = async (options) => {
|
|
|
2491
2391
|
builtInArgKeysSet
|
|
2492
2392
|
);
|
|
2493
2393
|
}
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
} else if (sandboxProvider.tag === "none") {
|
|
2506
|
-
const startResult = yield* startSandbox({
|
|
2507
|
-
provider: sandboxProvider,
|
|
2508
|
-
hostRepoDir,
|
|
2509
|
-
env: effectiveEnv,
|
|
2510
|
-
worktreeOrRepoPath: worktreeInfo.path
|
|
2511
|
-
});
|
|
2512
|
-
handle = startResult.handle;
|
|
2513
|
-
sandboxRepoDir = startResult.worktreePath;
|
|
2514
|
-
} else {
|
|
2515
|
-
const gitPath = join(hostRepoDir, ".git");
|
|
2516
|
-
const rawGitMounts = yield* resolveGitMounts(gitPath);
|
|
2517
|
-
const gitMounts = yield* patchGitMountsForWindows(
|
|
2518
|
-
rawGitMounts,
|
|
2519
|
-
worktreeInfo.path,
|
|
2520
|
-
SANDBOX_REPO_DIR
|
|
2521
|
-
);
|
|
2522
|
-
const startResult = yield* startSandbox({
|
|
2523
|
-
provider: sandboxProvider,
|
|
2524
|
-
hostRepoDir,
|
|
2525
|
-
env: effectiveEnv,
|
|
2526
|
-
worktreeOrRepoPath: worktreeInfo.path,
|
|
2527
|
-
gitMounts,
|
|
2528
|
-
repoDir: SANDBOX_REPO_DIR
|
|
2529
|
-
});
|
|
2530
|
-
handle = startResult.handle;
|
|
2531
|
-
sandboxRepoDir = startResult.worktreePath;
|
|
2532
|
-
}
|
|
2394
|
+
const startResult = yield* startSandbox({
|
|
2395
|
+
provider: sandboxProvider,
|
|
2396
|
+
hostRepoDir: worktreeInfo.path,
|
|
2397
|
+
sourceRepoDir: hostRepoDir,
|
|
2398
|
+
copySourceDir: worktreeInfo.path,
|
|
2399
|
+
env: effectiveEnv,
|
|
2400
|
+
copyPaths: options.copyToWorktree,
|
|
2401
|
+
copyTimeoutMs: options.timeouts?.copyToWorktreeMs
|
|
2402
|
+
});
|
|
2403
|
+
const handle = startResult.handle;
|
|
2404
|
+
const sandboxRepoDir = startResult.worktreePath;
|
|
2533
2405
|
const sandbox = makeSandboxFromHandle(handle);
|
|
2534
|
-
const applyToHost =
|
|
2406
|
+
const applyToHost = () => syncOut(worktreeInfo.path, handle);
|
|
2535
2407
|
const resolvedLogging = opts.logging ?? {
|
|
2536
2408
|
type: "file",
|
|
2537
2409
|
path: buildDefaultLogPath(
|
|
@@ -2564,14 +2436,14 @@ var createWorktree = async (options) => {
|
|
|
2564
2436
|
NodeFileSystem.layer
|
|
2565
2437
|
);
|
|
2566
2438
|
})() : ClackDisplay.layer;
|
|
2567
|
-
const
|
|
2439
|
+
const sessionTransferHandle = toSessionTransferHandle(handle);
|
|
2568
2440
|
const reuseFactoryLayer = Layer.succeed(SandboxFactory, {
|
|
2569
2441
|
withSandbox: (makeEffect) => makeEffect(
|
|
2570
2442
|
{
|
|
2571
2443
|
hostWorktreePath: worktreeInfo.path,
|
|
2572
2444
|
sandboxRepoPath: sandboxRepoDir,
|
|
2573
2445
|
applyToHost,
|
|
2574
|
-
|
|
2446
|
+
sessionTransferHandle
|
|
2575
2447
|
},
|
|
2576
2448
|
sandbox
|
|
2577
2449
|
).pipe(
|
|
@@ -2652,13 +2524,28 @@ var createWorktree = async (options) => {
|
|
|
2652
2524
|
}
|
|
2653
2525
|
};
|
|
2654
2526
|
const worktreeCreateSandbox = async (opts) => {
|
|
2527
|
+
if (opts.copyToWorktree?.length) {
|
|
2528
|
+
await Effect.runPromise(
|
|
2529
|
+
copyToWorktree(
|
|
2530
|
+
opts.copyToWorktree,
|
|
2531
|
+
hostRepoDir,
|
|
2532
|
+
worktreeInfo.path,
|
|
2533
|
+
opts.timeouts?.copyToWorktreeMs ?? options.timeouts?.copyToWorktreeMs
|
|
2534
|
+
)
|
|
2535
|
+
);
|
|
2536
|
+
}
|
|
2655
2537
|
return createSandboxFromWorktree({
|
|
2656
2538
|
branch: worktreeInfo.branch,
|
|
2657
2539
|
worktreePath: worktreeInfo.path,
|
|
2658
2540
|
hostRepoDir,
|
|
2659
2541
|
sandbox: opts.sandbox,
|
|
2660
2542
|
hooks: opts.hooks,
|
|
2661
|
-
copyToWorktree:
|
|
2543
|
+
copyToWorktree: [
|
|
2544
|
+
.../* @__PURE__ */ new Set([
|
|
2545
|
+
...options.copyToWorktree ?? [],
|
|
2546
|
+
...opts.copyToWorktree ?? []
|
|
2547
|
+
])
|
|
2548
|
+
],
|
|
2662
2549
|
timeouts: opts.timeouts,
|
|
2663
2550
|
branchStrategy: options.branchStrategy,
|
|
2664
2551
|
_test: opts._test
|
|
@@ -3027,8 +2914,7 @@ var makeClaudeSessionStorage = (options) => {
|
|
|
3027
2914
|
sandboxProjectsDir
|
|
3028
2915
|
);
|
|
3029
2916
|
await writeSandboxFile(handle, sandboxPath, rewritten, "claude-res");
|
|
3030
|
-
}
|
|
3031
|
-
findByIdOnHost: (id) => findClaudeSessionOnHost(id, hostProjectsDir)
|
|
2917
|
+
}
|
|
3032
2918
|
};
|
|
3033
2919
|
};
|
|
3034
2920
|
var makeCodexSessionStorage = (options) => {
|
|
@@ -3066,8 +2952,7 @@ var makeCodexSessionStorage = (options) => {
|
|
|
3066
2952
|
const rewritten = transferCodexSession(jsonl, hostCwd, sandboxCwd);
|
|
3067
2953
|
const target = posix.join(sandboxSessionsDir, located.relativePath);
|
|
3068
2954
|
await writeSandboxFile(handle, target, rewritten, "codex-res");
|
|
3069
|
-
}
|
|
3070
|
-
findByIdOnHost: (id) => findCodexSessionOnHost(id, hostSessionsDir)
|
|
2955
|
+
}
|
|
3071
2956
|
};
|
|
3072
2957
|
};
|
|
3073
2958
|
var parseCodexUsage = (usage) => {
|
|
@@ -3114,7 +2999,7 @@ var parseCodexStreamLine = (line) => {
|
|
|
3114
2999
|
};
|
|
3115
3000
|
var codex = (model, options) => {
|
|
3116
3001
|
const modelId = typeof model === "string" ? model : model.model;
|
|
3117
|
-
const effort = options?.effort ?? (typeof model === "string" ? CONFIGURED_CODEX_MODEL_EFFORTS.get(modelId) : model.effort);
|
|
3002
|
+
const effort = options?.effort === null ? void 0 : options?.effort ?? (typeof model === "string" ? CONFIGURED_CODEX_MODEL_EFFORTS.get(modelId) : model.effort);
|
|
3118
3003
|
return {
|
|
3119
3004
|
name: "codex",
|
|
3120
3005
|
env: options?.env ?? {},
|
|
@@ -3375,7 +3260,18 @@ var createWorkBrief = (input) => {
|
|
|
3375
3260
|
"acceptanceCriteria"
|
|
3376
3261
|
),
|
|
3377
3262
|
exclusions: stringArray(input.exclusions, "exclusions"),
|
|
3378
|
-
risk: enumValue(
|
|
3263
|
+
risk: enumValue(
|
|
3264
|
+
input.risk,
|
|
3265
|
+
["low", "medium", "high", "critical", "unknown"],
|
|
3266
|
+
"risk"
|
|
3267
|
+
),
|
|
3268
|
+
...input.scope === void 0 ? {} : {
|
|
3269
|
+
scope: enumValue(
|
|
3270
|
+
input.scope,
|
|
3271
|
+
["small", "substantial", "unknown"],
|
|
3272
|
+
"scope"
|
|
3273
|
+
)
|
|
3274
|
+
},
|
|
3379
3275
|
verification: parseVerification(input.verification),
|
|
3380
3276
|
unresolvedQuestions: stringArray(
|
|
3381
3277
|
input.unresolvedQuestions,
|
|
@@ -3415,7 +3311,18 @@ var parseWorkBrief = (value) => {
|
|
|
3415
3311
|
"acceptanceCriteria"
|
|
3416
3312
|
),
|
|
3417
3313
|
exclusions: stringArray(value.exclusions, "exclusions"),
|
|
3418
|
-
risk: enumValue(
|
|
3314
|
+
risk: enumValue(
|
|
3315
|
+
value.risk,
|
|
3316
|
+
["low", "medium", "high", "critical", "unknown"],
|
|
3317
|
+
"risk"
|
|
3318
|
+
),
|
|
3319
|
+
...value.scope === void 0 ? {} : {
|
|
3320
|
+
scope: enumValue(
|
|
3321
|
+
value.scope,
|
|
3322
|
+
["small", "substantial", "unknown"],
|
|
3323
|
+
"scope"
|
|
3324
|
+
)
|
|
3325
|
+
},
|
|
3419
3326
|
verification: parseVerification(value.verification),
|
|
3420
3327
|
unresolvedQuestions: stringArray(
|
|
3421
3328
|
value.unresolvedQuestions,
|
|
@@ -3471,6 +3378,28 @@ var parseRepositoryPolicy = (value) => {
|
|
|
3471
3378
|
if (!isRecord(value.worker)) {
|
|
3472
3379
|
throw new ContractValidationError("policy.worker must be an object");
|
|
3473
3380
|
}
|
|
3381
|
+
const workerModels = value.worker.models === void 0 ? void 0 : (() => {
|
|
3382
|
+
if (value.worker.model !== void 0) {
|
|
3383
|
+
throw new ContractValidationError(
|
|
3384
|
+
"policy.worker.model cannot be combined with policy.worker.models"
|
|
3385
|
+
);
|
|
3386
|
+
}
|
|
3387
|
+
if (!isRecord(value.worker.models)) {
|
|
3388
|
+
throw new ContractValidationError(
|
|
3389
|
+
"policy.worker.models must be an object"
|
|
3390
|
+
);
|
|
3391
|
+
}
|
|
3392
|
+
return {
|
|
3393
|
+
routine: nonEmptyString(
|
|
3394
|
+
value.worker.models.routine,
|
|
3395
|
+
"policy.worker.models.routine"
|
|
3396
|
+
),
|
|
3397
|
+
strong: nonEmptyString(
|
|
3398
|
+
value.worker.models.strong,
|
|
3399
|
+
"policy.worker.models.strong"
|
|
3400
|
+
)
|
|
3401
|
+
};
|
|
3402
|
+
})();
|
|
3474
3403
|
if (!Array.isArray(value.checks)) {
|
|
3475
3404
|
throw new ContractValidationError("policy.checks must be an array");
|
|
3476
3405
|
}
|
|
@@ -3564,7 +3493,7 @@ var parseRepositoryPolicy = (value) => {
|
|
|
3564
3493
|
authorization: { required, allowedActors, autoStartRisk },
|
|
3565
3494
|
worker: {
|
|
3566
3495
|
provider: nonEmptyString(value.worker.provider, "policy.worker.provider"),
|
|
3567
|
-
model: nonEmptyString(value.worker.model, "policy.worker.model"),
|
|
3496
|
+
...workerModels === void 0 ? { model: nonEmptyString(value.worker.model, "policy.worker.model") } : { models: workerModels },
|
|
3568
3497
|
sandbox: nonEmptyString(value.worker.sandbox, "policy.worker.sandbox"),
|
|
3569
3498
|
skillRevision: nonEmptyString(
|
|
3570
3499
|
value.worker.skillRevision,
|
|
@@ -3580,6 +3509,16 @@ var createRepositoryPolicy = (input) => parseRepositoryPolicy({
|
|
|
3580
3509
|
contractVersion: WORKFLOW_CONTRACT_VERSION,
|
|
3581
3510
|
...input
|
|
3582
3511
|
});
|
|
3512
|
+
var resolveAgentSelection = (policy, phase2, risk, scope) => {
|
|
3513
|
+
const role = phase2 === "review" && !(risk === "low" && scope === "small") ? "strong" : "routine";
|
|
3514
|
+
const worker = policy.worker;
|
|
3515
|
+
const modelPath = worker.models ? `policy.worker.models.${role}` : "policy.worker.model";
|
|
3516
|
+
return Object.freeze({
|
|
3517
|
+
provider: nonEmptyString(worker.provider, "policy.worker.provider"),
|
|
3518
|
+
model: nonEmptyString(worker.models?.[role] ?? worker.model, modelPath),
|
|
3519
|
+
role
|
|
3520
|
+
});
|
|
3521
|
+
};
|
|
3583
3522
|
var parseCheckEvidence = (value) => {
|
|
3584
3523
|
if (!isRecord(value)) {
|
|
3585
3524
|
throw new ContractValidationError("check evidence must be an object");
|
|
@@ -3718,6 +3657,12 @@ var createAssignment = (input) => {
|
|
|
3718
3657
|
briefHash: brief.hash,
|
|
3719
3658
|
policyRevision: input.policy.revision,
|
|
3720
3659
|
skillRevision: brief.skillRevision,
|
|
3660
|
+
agentSelection: resolveAgentSelection(
|
|
3661
|
+
input.policy,
|
|
3662
|
+
input.phase,
|
|
3663
|
+
brief.risk,
|
|
3664
|
+
brief.scope
|
|
3665
|
+
),
|
|
3721
3666
|
base: brief.base,
|
|
3722
3667
|
head: input.head,
|
|
3723
3668
|
createdAt: nonEmptyString(input.createdAt, "assignment.createdAt")
|
|
@@ -4087,6 +4032,25 @@ var parseAssignment = (value) => {
|
|
|
4087
4032
|
throw new Error("Stored assignment base must be an object");
|
|
4088
4033
|
}
|
|
4089
4034
|
const head = candidate.head;
|
|
4035
|
+
const agentSelection = candidate.agentSelection;
|
|
4036
|
+
let parsedAgentSelection;
|
|
4037
|
+
if (agentSelection !== void 0) {
|
|
4038
|
+
if (typeof agentSelection !== "object" || agentSelection === null || Array.isArray(agentSelection)) {
|
|
4039
|
+
throw new Error("Stored assignment agent selection must be an object");
|
|
4040
|
+
}
|
|
4041
|
+
const selection = agentSelection;
|
|
4042
|
+
if (selection.role !== "routine" && selection.role !== "strong") {
|
|
4043
|
+
throw new Error("Stored assignment agent selection role is invalid");
|
|
4044
|
+
}
|
|
4045
|
+
parsedAgentSelection = {
|
|
4046
|
+
provider: requiredString(
|
|
4047
|
+
selection.provider,
|
|
4048
|
+
"assignment.agentSelection.provider"
|
|
4049
|
+
),
|
|
4050
|
+
model: requiredString(selection.model, "assignment.agentSelection.model"),
|
|
4051
|
+
role: selection.role
|
|
4052
|
+
};
|
|
4053
|
+
}
|
|
4090
4054
|
const revision = (value2, path2) => {
|
|
4091
4055
|
if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) {
|
|
4092
4056
|
throw new Error(`${path2} must be an object`);
|
|
@@ -4130,6 +4094,7 @@ var parseAssignment = (value) => {
|
|
|
4130
4094
|
candidate.skillRevision,
|
|
4131
4095
|
"assignment.skillRevision"
|
|
4132
4096
|
),
|
|
4097
|
+
...parsedAgentSelection === void 0 ? {} : { agentSelection: parsedAgentSelection },
|
|
4133
4098
|
base: revision(base, "assignment.base"),
|
|
4134
4099
|
head: head === void 0 ? void 0 : revision(head, "assignment.head"),
|
|
4135
4100
|
createdAt: requiredString(candidate.createdAt, "assignment.createdAt")
|
|
@@ -4319,9 +4284,6 @@ var PostgresTransaction = class {
|
|
|
4319
4284
|
async one(text2, values, path2) {
|
|
4320
4285
|
return row(await this.client.query(text2, values), path2);
|
|
4321
4286
|
}
|
|
4322
|
-
async optional(text2, values) {
|
|
4323
|
-
return optionalRow(await this.client.query(text2, values));
|
|
4324
|
-
}
|
|
4325
4287
|
async insertEventIfAbsent(event) {
|
|
4326
4288
|
const inserted = await this.client.query(
|
|
4327
4289
|
`INSERT INTO shipyard_events (
|
|
@@ -6049,11 +6011,23 @@ var cancelledResult = (assignment, response, artifacts, message, kind) => ({
|
|
|
6049
6011
|
evidence: response.report.evidence
|
|
6050
6012
|
})
|
|
6051
6013
|
});
|
|
6014
|
+
var sameAgentSelection = (left, right) => left.provider === right.provider && left.model === right.model && left.role === right.role;
|
|
6052
6015
|
var executePhase = async (options) => {
|
|
6053
6016
|
const assignment = deepFreeze(structuredClone(options.assignment));
|
|
6054
6017
|
const trusted = deepFreeze(structuredClone(options.trusted));
|
|
6055
6018
|
const untrusted = deepFreeze(structuredClone(options.untrusted));
|
|
6056
6019
|
const controls = deepFreeze(structuredClone(options.controls));
|
|
6020
|
+
const resolvedSelection = resolveAgentSelection(
|
|
6021
|
+
trusted.policy,
|
|
6022
|
+
assignment.phase,
|
|
6023
|
+
trusted.brief.risk,
|
|
6024
|
+
trusted.brief.scope
|
|
6025
|
+
);
|
|
6026
|
+
const persistedSelection = assignment.agentSelection;
|
|
6027
|
+
if (persistedSelection !== void 0 && !sameAgentSelection(persistedSelection, resolvedSelection)) {
|
|
6028
|
+
throw new Error("Assignment agent selection does not match trusted policy");
|
|
6029
|
+
}
|
|
6030
|
+
const agentSelection = persistedSelection ?? resolvedSelection;
|
|
6057
6031
|
const secretValues = /* @__PURE__ */ new Set();
|
|
6058
6032
|
const controller = new AbortController();
|
|
6059
6033
|
let timedOut = false;
|
|
@@ -6067,6 +6041,7 @@ var executePhase = async (options) => {
|
|
|
6067
6041
|
}, options.controls.timeoutSeconds * 1e3);
|
|
6068
6042
|
const request = {
|
|
6069
6043
|
assignment,
|
|
6044
|
+
agentSelection,
|
|
6070
6045
|
trusted,
|
|
6071
6046
|
untrusted,
|
|
6072
6047
|
controls,
|
|
@@ -6311,6 +6286,23 @@ var executePhase = async (options) => {
|
|
|
6311
6286
|
})
|
|
6312
6287
|
};
|
|
6313
6288
|
};
|
|
6289
|
+
var resolvePhaseAgent = (options, request) => {
|
|
6290
|
+
if (options.resolveAgent === void 0 && request.trusted.policy.worker.models !== void 0) {
|
|
6291
|
+
throw new Error(
|
|
6292
|
+
"An agent resolver is required when repository policy defines worker models"
|
|
6293
|
+
);
|
|
6294
|
+
}
|
|
6295
|
+
const agent = options.resolveAgent === void 0 ? options.agent : options.resolveAgent(request.agentSelection);
|
|
6296
|
+
if (agent === void 0) {
|
|
6297
|
+
throw new Error("The phase engine has no agent for the selected model");
|
|
6298
|
+
}
|
|
6299
|
+
if (agent.name !== request.agentSelection.provider) {
|
|
6300
|
+
throw new Error(
|
|
6301
|
+
`Resolved agent provider "${agent.name}" does not match repository policy provider "${request.agentSelection.provider}"`
|
|
6302
|
+
);
|
|
6303
|
+
}
|
|
6304
|
+
return agent;
|
|
6305
|
+
};
|
|
6314
6306
|
var runResultToResponse = (result3, branch) => {
|
|
6315
6307
|
const commits = result3.commits.map((commit) => commit.sha);
|
|
6316
6308
|
const headSha = commits.at(-1) ?? "";
|
|
@@ -6335,11 +6327,12 @@ var runResultToResponse = (result3, branch) => {
|
|
|
6335
6327
|
};
|
|
6336
6328
|
var createRunPhaseEngineAdapter = (options) => ({
|
|
6337
6329
|
execute: async (request) => {
|
|
6338
|
-
|
|
6330
|
+
const agent = resolvePhaseAgent(options, request);
|
|
6331
|
+
assertToolAllowlistSupport(agent);
|
|
6339
6332
|
const branch = request.checkout.branch;
|
|
6340
6333
|
const baseBranch = request.checkout.immutable ? request.checkout.candidate?.sha ?? request.assignment.base.sha : request.assignment.base.sha;
|
|
6341
6334
|
const result3 = await options.run({
|
|
6342
|
-
agent
|
|
6335
|
+
agent,
|
|
6343
6336
|
sandbox: options.sandbox,
|
|
6344
6337
|
cwd: options.cwd,
|
|
6345
6338
|
prompt: buildPrompt(request),
|
|
@@ -6377,7 +6370,8 @@ var sandboxResultToResponse = (result3, branch) => {
|
|
|
6377
6370
|
};
|
|
6378
6371
|
var createCreateSandboxPhaseEngineAdapter = (options) => ({
|
|
6379
6372
|
execute: async (request) => {
|
|
6380
|
-
|
|
6373
|
+
const agent = resolvePhaseAgent(options, request);
|
|
6374
|
+
assertToolAllowlistSupport(agent);
|
|
6381
6375
|
const branch = request.checkout.branch;
|
|
6382
6376
|
const baseBranch = request.checkout.immutable ? request.checkout.candidate?.sha ?? request.assignment.base.sha : request.assignment.base.sha;
|
|
6383
6377
|
const sandbox = await options.createSandbox({
|
|
@@ -6388,7 +6382,7 @@ var createCreateSandboxPhaseEngineAdapter = (options) => ({
|
|
|
6388
6382
|
});
|
|
6389
6383
|
try {
|
|
6390
6384
|
const result3 = await sandbox.run({
|
|
6391
|
-
agent
|
|
6385
|
+
agent,
|
|
6392
6386
|
prompt: buildPrompt(request),
|
|
6393
6387
|
toolAllowlist: request.controls.toolAllowlist,
|
|
6394
6388
|
maxIterations: request.controls.maxIterations,
|
|
@@ -9030,22 +9024,6 @@ var GitHubIntegration = class {
|
|
|
9030
9024
|
reason: ingest.reason
|
|
9031
9025
|
};
|
|
9032
9026
|
}
|
|
9033
|
-
async recordRejected(input) {
|
|
9034
|
-
const payloadRecord = record(input.payload);
|
|
9035
|
-
const delivery = {
|
|
9036
|
-
deliveryId: input.deliveryId,
|
|
9037
|
-
eventName: input.eventName,
|
|
9038
|
-
repository: payloadRecord ? repositoryName(payloadRecord) ?? "unknown" : "unknown",
|
|
9039
|
-
senderLogin: payloadRecord ? sender(payloadRecord).login : "unknown",
|
|
9040
|
-
receivedAt: this.now(),
|
|
9041
|
-
payloadHash: payloadHash(input.body),
|
|
9042
|
-
payload: input.payload,
|
|
9043
|
-
status: "rejected",
|
|
9044
|
-
reason: input.reason
|
|
9045
|
-
};
|
|
9046
|
-
const stored = await this.options.deliveryStore.recordDeliveryIfAbsent(delivery);
|
|
9047
|
-
if (!stored.inserted) return;
|
|
9048
|
-
}
|
|
9049
9027
|
async rejectStored(delivery, reason) {
|
|
9050
9028
|
await this.options.deliveryStore.updateDelivery({
|
|
9051
9029
|
...delivery,
|
|
@@ -9970,6 +9948,6 @@ var ReleaseIntegration = class {
|
|
|
9970
9948
|
};
|
|
9971
9949
|
var candidateMatchesApproval = (candidate, approval) => sameCandidate(candidate, approval.candidate);
|
|
9972
9950
|
|
|
9973
|
-
export { ContractValidationError, CredentialNotAllowedError, CredentialUnavailableError, CwdError2 as CwdError, GitHubIntegration, GitHubPublication, InMemoryCoordinatorStorage, InMemoryGitHubStore, InMemoryReleaseStore, InMemoryRepairBatchStore, InMemoryTriageStore, LeaseBusyError, LeaseLostError, Output, PostgresCoordinatorStorage, ReleaseIntegration, StructuredOutputError, WORKFLOW_CONTRACT_VERSION, WorkflowCoordinator, WorkflowOperator, candidateMatchesApproval, claudeCode, claudeHostSessionPath, claudeSandboxSessionPath, closeSourceIssue, codex, completeSourceIssue, createAssignment, createCreateSandboxPhaseEngineAdapter, createFakePhaseEngineAdapter, createGitHubIssueBrief, createInMemoryArtifactStore, createRepositoryPolicy, createRunPhaseEngineAdapter, createSandbox, createWorkBrief, createWorktree, defaultInvestigator as defaultTriageInvestigator, encodeProjectPath, evaluateHandoffReadiness, executePhase, findClaudeSessionOnHost, findCodexSessionOnHost, interactive, isAuthorizationAllowed, mergeProtectedCandidate, parseCheckEvidence, parsePhaseResult, parseRepositoryPolicy, parseWorkBrief, prepareHumanHandoff, prepareIndependentReview, processHumanReviewDecision, redact2 as redactOperatorText, releaseCandidateKey, requireTransition, resolveHumanReviewDecision, reviewDecisionFor, run, runAuthorizedImplementation, runBoundedRepair, runIndependentReview, runTriage, scheduleBoundedRepair, transferClaudeSession, transferCodexSession, verifyGitHubWebhookSignature };
|
|
9951
|
+
export { ContractValidationError, CredentialNotAllowedError, CredentialUnavailableError, CwdError2 as CwdError, GitHubIntegration, GitHubPublication, InMemoryCoordinatorStorage, InMemoryGitHubStore, InMemoryReleaseStore, InMemoryRepairBatchStore, InMemoryTriageStore, LeaseBusyError, LeaseLostError, Output, PostgresCoordinatorStorage, ReleaseIntegration, StructuredOutputError, WORKFLOW_CONTRACT_VERSION, WorkflowCoordinator, WorkflowOperator, candidateMatchesApproval, claudeCode, claudeHostSessionPath, claudeSandboxSessionPath, closeSourceIssue, codex, completeSourceIssue, createAssignment, createCreateSandboxPhaseEngineAdapter, createFakePhaseEngineAdapter, createGitHubIssueBrief, createInMemoryArtifactStore, createRepositoryPolicy, createRunPhaseEngineAdapter, createSandbox, createWorkBrief, createWorktree, defaultInvestigator as defaultTriageInvestigator, encodeProjectPath, evaluateHandoffReadiness, executePhase, findClaudeSessionOnHost, findCodexSessionOnHost, interactive, isAuthorizationAllowed, mergeProtectedCandidate, parseCheckEvidence, parsePhaseResult, parseRepositoryPolicy, parseWorkBrief, prepareHumanHandoff, prepareIndependentReview, processHumanReviewDecision, redact2 as redactOperatorText, releaseCandidateKey, requireTransition, resolveAgentSelection, resolveHumanReviewDecision, reviewDecisionFor, run, runAuthorizedImplementation, runBoundedRepair, runIndependentReview, runTriage, scheduleBoundedRepair, transferClaudeSession, transferCodexSession, verifyGitHubWebhookSignature };
|
|
9974
9952
|
//# sourceMappingURL=index.js.map
|
|
9975
9953
|
//# sourceMappingURL=index.js.map
|