@abelxiaoxing/cadence 1.0.9 → 1.0.11
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 +49 -1
- package/package.json +1 -1
- package/prompts/abel-design.md +14 -2
- package/prompts/abel-implement.md +10 -2
- package/skills/abel-workflow/SKILL.md +36 -0
- package/src/candidate-preflight.ts +237 -90
- package/src/child-session.ts +1 -0
- package/src/contracts.ts +482 -41
- package/src/patch.ts +13 -1
- package/src/result-store.ts +6 -9
- package/src/runtime.ts +66 -10
- package/src/verification-capability.ts +481 -0
|
@@ -15,11 +15,15 @@ import {
|
|
|
15
15
|
} from "node:fs";
|
|
16
16
|
import path from "node:path";
|
|
17
17
|
import {
|
|
18
|
+
type AtomicVerificationContract,
|
|
18
19
|
type CandidateFailure,
|
|
19
20
|
diffWritePaths,
|
|
20
21
|
isValidRelativePath,
|
|
22
|
+
type StructuredVerificationContract,
|
|
21
23
|
type VerificationContract,
|
|
22
24
|
validateVerificationContract,
|
|
25
|
+
verificationInputPaths,
|
|
26
|
+
verificationSteps,
|
|
23
27
|
} from "./contracts.ts";
|
|
24
28
|
import {
|
|
25
29
|
type Bound,
|
|
@@ -28,6 +32,10 @@ import {
|
|
|
28
32
|
isCurrent,
|
|
29
33
|
snapshotDirManifest,
|
|
30
34
|
} from "./file-snapshot.ts";
|
|
35
|
+
import {
|
|
36
|
+
type VerificationRunnerBinding,
|
|
37
|
+
validateVerificationCapability,
|
|
38
|
+
} from "./verification-capability.ts";
|
|
31
39
|
|
|
32
40
|
export type { VerificationContract } from "./contracts.ts";
|
|
33
41
|
|
|
@@ -377,6 +385,7 @@ function validateInput(input: CandidatePreflightInput): {
|
|
|
377
385
|
targets: string[];
|
|
378
386
|
lockPath: string;
|
|
379
387
|
dependencyPath: string;
|
|
388
|
+
verification: StructuredVerificationContract;
|
|
380
389
|
} {
|
|
381
390
|
if (!Buffer.isBuffer(input.diff) || input.diff.length === 0)
|
|
382
391
|
reject("artifact", "invalid-diff-bytes");
|
|
@@ -489,12 +498,16 @@ function validateInput(input: CandidatePreflightInput): {
|
|
|
489
498
|
}
|
|
490
499
|
if (targets.some((target) => !entries.has(target)))
|
|
491
500
|
reject("artifact", "target-baseline-missing");
|
|
492
|
-
for (
|
|
493
|
-
|
|
494
|
-
if (testPath === undefined || !entries.has(testPath))
|
|
501
|
+
for (const verificationPath of verificationInputPaths(verification.value)) {
|
|
502
|
+
if (!entries.has(verificationPath))
|
|
495
503
|
reject("artifact", "verification-baseline-missing");
|
|
496
504
|
}
|
|
497
|
-
return {
|
|
505
|
+
return {
|
|
506
|
+
targets,
|
|
507
|
+
lockPath,
|
|
508
|
+
dependencyPath,
|
|
509
|
+
verification: verification.value,
|
|
510
|
+
};
|
|
498
511
|
}
|
|
499
512
|
|
|
500
513
|
function verifyBaselineAt(root: string, baseline: BaselineEntry[]): void {
|
|
@@ -655,11 +668,18 @@ function sandboxArgs(
|
|
|
655
668
|
checkout: string,
|
|
656
669
|
dependencySource: string,
|
|
657
670
|
dependencyIsDirectory: boolean,
|
|
658
|
-
bunExecutable: string,
|
|
671
|
+
bunExecutable: string | undefined,
|
|
672
|
+
runnerPlan: SandboxRunnerPlan,
|
|
659
673
|
invocation: string[],
|
|
660
674
|
reportSource?: string,
|
|
661
675
|
): string[] {
|
|
662
676
|
const candidate = "/candidate";
|
|
677
|
+
const sandboxPath = [
|
|
678
|
+
...runnerPlan.pathEntries,
|
|
679
|
+
"/usr/bin",
|
|
680
|
+
"/usr/local/bin",
|
|
681
|
+
"/bin",
|
|
682
|
+
].join(":");
|
|
663
683
|
const args = [
|
|
664
684
|
"--unshare-net",
|
|
665
685
|
"--unshare-pid",
|
|
@@ -674,7 +694,7 @@ function sandboxArgs(
|
|
|
674
694
|
"--clearenv",
|
|
675
695
|
"--setenv",
|
|
676
696
|
"PATH",
|
|
677
|
-
|
|
697
|
+
sandboxPath,
|
|
678
698
|
"--setenv",
|
|
679
699
|
"HOME",
|
|
680
700
|
"/nonexistent",
|
|
@@ -685,7 +705,15 @@ function sandboxArgs(
|
|
|
685
705
|
for (const systemPath of ["/usr", "/bin", "/lib", "/lib64", "/etc"]) {
|
|
686
706
|
if (existsSync(systemPath)) args.push("--ro-bind", systemPath, systemPath);
|
|
687
707
|
}
|
|
688
|
-
|
|
708
|
+
if (bunExecutable) {
|
|
709
|
+
args.push("--ro-bind", bunExecutable, SANDBOX_BUN_TARGET);
|
|
710
|
+
}
|
|
711
|
+
if (runnerPlan.mounts.length > 0) {
|
|
712
|
+
args.push("--dir", "/cadence", "--dir", "/cadence/runners");
|
|
713
|
+
for (const mount of runnerPlan.mounts) {
|
|
714
|
+
args.push("--dir", mount.target, "--ro-bind", mount.source, mount.target);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
689
717
|
const dependencyDestination = path.posix.join(candidate, "node_modules");
|
|
690
718
|
const localDependency = path.join(checkout, "node_modules");
|
|
691
719
|
rmSync(localDependency, { recursive: true, force: true });
|
|
@@ -712,6 +740,59 @@ function sandboxArgs(
|
|
|
712
740
|
return args;
|
|
713
741
|
}
|
|
714
742
|
|
|
743
|
+
interface SandboxRunnerPlan {
|
|
744
|
+
mounts: Array<{ source: string; target: string }>;
|
|
745
|
+
pathEntries: string[];
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
function pathWithin(root: string, candidate: string): boolean {
|
|
749
|
+
return candidate === root || candidate.startsWith(`${root}${path.sep}`);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
function sandboxRunnerPlan(
|
|
753
|
+
bindings: readonly VerificationRunnerBinding[],
|
|
754
|
+
): SandboxRunnerPlan {
|
|
755
|
+
const relevant = bindings.filter((binding) => binding.command !== "bun");
|
|
756
|
+
const sources = [
|
|
757
|
+
...new Set(
|
|
758
|
+
relevant.flatMap((binding) =>
|
|
759
|
+
binding.mountSource ? [binding.mountSource] : [],
|
|
760
|
+
),
|
|
761
|
+
),
|
|
762
|
+
]
|
|
763
|
+
.sort(
|
|
764
|
+
(left, right) => left.length - right.length || left.localeCompare(right),
|
|
765
|
+
)
|
|
766
|
+
.filter(
|
|
767
|
+
(source, index, all) =>
|
|
768
|
+
!all.some(
|
|
769
|
+
(candidate, candidateIndex) =>
|
|
770
|
+
candidateIndex !== index &&
|
|
771
|
+
candidate.length < source.length &&
|
|
772
|
+
pathWithin(candidate, source),
|
|
773
|
+
),
|
|
774
|
+
);
|
|
775
|
+
const mounts = sources.map((source, index) => ({
|
|
776
|
+
source,
|
|
777
|
+
target: `/cadence/runners/${index}`,
|
|
778
|
+
}));
|
|
779
|
+
const pathEntries = relevant.map((binding) => {
|
|
780
|
+
if (!binding.mountSource) return path.dirname(binding.executablePath);
|
|
781
|
+
const mount = mounts.find((candidate) =>
|
|
782
|
+
pathWithin(candidate.source, binding.executablePath),
|
|
783
|
+
);
|
|
784
|
+
if (!mount) throw new Error("verification runner mount plan is incomplete");
|
|
785
|
+
const relative = path.relative(
|
|
786
|
+
mount.source,
|
|
787
|
+
path.dirname(binding.executablePath),
|
|
788
|
+
);
|
|
789
|
+
return relative
|
|
790
|
+
? path.posix.join(mount.target, ...relative.split(path.sep))
|
|
791
|
+
: mount.target;
|
|
792
|
+
});
|
|
793
|
+
return { mounts, pathEntries: [...new Set(pathEntries)] };
|
|
794
|
+
}
|
|
795
|
+
|
|
715
796
|
interface StructuredTestReport {
|
|
716
797
|
total: number;
|
|
717
798
|
failed: number;
|
|
@@ -1037,44 +1118,44 @@ function rejectUnapprovedDependencies(
|
|
|
1037
1118
|
}
|
|
1038
1119
|
|
|
1039
1120
|
function normalizeTarget(
|
|
1040
|
-
|
|
1121
|
+
verification: AtomicVerificationContract,
|
|
1041
1122
|
result: CommandResult,
|
|
1042
1123
|
secrets: string[],
|
|
1043
1124
|
report?: StructuredTestReport,
|
|
1044
1125
|
): CandidatePreflightResult {
|
|
1045
|
-
const
|
|
1126
|
+
const vitest = verification.kind === "vitest";
|
|
1046
1127
|
const output = `${result.stdout}\n${result.stderr}`;
|
|
1047
|
-
const count =
|
|
1128
|
+
const count = vitest ? (report?.total ?? 0) : 0;
|
|
1048
1129
|
const identityMatch =
|
|
1049
|
-
|
|
1050
|
-
(
|
|
1051
|
-
?
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1130
|
+
verification.classification !== "expected-red" ||
|
|
1131
|
+
(vitest
|
|
1132
|
+
? (report?.failedAssertions.some((failure) =>
|
|
1133
|
+
failure.includes(verification.expectedFailure ?? ""),
|
|
1134
|
+
) ?? false)
|
|
1135
|
+
: output.includes(verification.expectedFailure ?? ""));
|
|
1055
1136
|
const loadable =
|
|
1056
|
-
|
|
1137
|
+
!vitest ||
|
|
1057
1138
|
((report?.fileErrors.length ?? 0) === 0 && !LOAD_FAILURE.test(output));
|
|
1058
|
-
const enoughTests =
|
|
1139
|
+
const enoughTests = !vitest || count >= verification.minTests;
|
|
1059
1140
|
const accepted =
|
|
1060
|
-
|
|
1141
|
+
verification.classification === "expected-red"
|
|
1061
1142
|
? result.status !== 0 &&
|
|
1062
|
-
(
|
|
1143
|
+
(!vitest || (report?.failed ?? 0) > 0) &&
|
|
1063
1144
|
enoughTests &&
|
|
1064
1145
|
identityMatch &&
|
|
1065
1146
|
loadable
|
|
1066
1147
|
: result.status === 0 &&
|
|
1067
|
-
(
|
|
1148
|
+
(!vitest || report?.success === true) &&
|
|
1068
1149
|
enoughTests &&
|
|
1069
1150
|
loadable;
|
|
1070
1151
|
const details = {
|
|
1071
|
-
commandId:
|
|
1152
|
+
commandId: verification.id,
|
|
1072
1153
|
exitCode: result.status ?? 1,
|
|
1073
1154
|
testCount: count,
|
|
1074
1155
|
identityMatch,
|
|
1075
1156
|
};
|
|
1076
1157
|
if (
|
|
1077
|
-
|
|
1158
|
+
verification.classification === "expected-red" &&
|
|
1078
1159
|
result.status === 0 &&
|
|
1079
1160
|
enoughTests &&
|
|
1080
1161
|
loadable
|
|
@@ -1092,20 +1173,74 @@ function normalizeTarget(
|
|
|
1092
1173
|
}
|
|
1093
1174
|
return {
|
|
1094
1175
|
ok: true,
|
|
1095
|
-
classification:
|
|
1176
|
+
classification: verification.classification,
|
|
1096
1177
|
targets: [],
|
|
1097
1178
|
...details,
|
|
1098
1179
|
checkoutRemoved: true,
|
|
1099
1180
|
};
|
|
1100
1181
|
}
|
|
1101
1182
|
|
|
1102
|
-
function
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1183
|
+
function packageScriptInvocation(
|
|
1184
|
+
packageManager: string,
|
|
1185
|
+
script: string,
|
|
1186
|
+
args: string[],
|
|
1187
|
+
): string[] {
|
|
1188
|
+
switch (packageManager) {
|
|
1189
|
+
case "npm":
|
|
1190
|
+
case "pnpm":
|
|
1191
|
+
return [packageManager, "run", script, "--", ...args];
|
|
1192
|
+
case "yarn":
|
|
1193
|
+
return [packageManager, "run", script, ...args];
|
|
1194
|
+
default:
|
|
1195
|
+
return ["bun", "run", script, ...args];
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
function executableInvocation(
|
|
1200
|
+
runner: Exclude<
|
|
1201
|
+
AtomicVerificationContract,
|
|
1202
|
+
{ kind: "package-script" }
|
|
1203
|
+
>["runner"],
|
|
1204
|
+
args: string[],
|
|
1205
|
+
): string[] {
|
|
1206
|
+
switch (runner.kind) {
|
|
1207
|
+
case "package-script":
|
|
1208
|
+
return packageScriptInvocation(
|
|
1209
|
+
runner.packageManager,
|
|
1210
|
+
runner.script,
|
|
1211
|
+
args,
|
|
1212
|
+
);
|
|
1213
|
+
case "local-binary":
|
|
1214
|
+
return [
|
|
1215
|
+
path.posix.join("/candidate/node_modules/.bin", runner.executable),
|
|
1216
|
+
...args,
|
|
1217
|
+
];
|
|
1218
|
+
case "npx":
|
|
1219
|
+
return ["npx", "--no-install", runner.executable, ...args];
|
|
1220
|
+
case "node":
|
|
1221
|
+
return ["node", runner.script, ...args];
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
function verificationInvocation(
|
|
1226
|
+
verification: AtomicVerificationContract,
|
|
1227
|
+
report: boolean,
|
|
1228
|
+
): string[] {
|
|
1229
|
+
const reporter = report
|
|
1230
|
+
? ["--reporter=json", `--outputFile=${SANDBOX_REPORT_TARGET}`]
|
|
1231
|
+
: [];
|
|
1232
|
+
if (verification.kind === "package-script") {
|
|
1233
|
+
return packageScriptInvocation(
|
|
1234
|
+
verification.packageManager,
|
|
1235
|
+
verification.script,
|
|
1236
|
+
verification.args,
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
1239
|
+
const args =
|
|
1240
|
+
verification.kind === "vitest"
|
|
1241
|
+
? [...verification.testFiles, ...verification.args, ...reporter]
|
|
1242
|
+
: verification.args;
|
|
1243
|
+
return executableInvocation(verification.runner, args);
|
|
1109
1244
|
}
|
|
1110
1245
|
|
|
1111
1246
|
function resolveDependencySource(
|
|
@@ -1297,29 +1432,53 @@ export async function preflightCandidate(
|
|
|
1297
1432
|
await requireRegularGitModes(dependencies, checkout, input.signal);
|
|
1298
1433
|
scanCheckout(checkout);
|
|
1299
1434
|
|
|
1300
|
-
for (const
|
|
1301
|
-
|
|
1435
|
+
for (const verificationPath of verificationInputPaths(
|
|
1436
|
+
validated.verification,
|
|
1437
|
+
)) {
|
|
1438
|
+
const stat = lstatSync(safePath(checkout, verificationPath), {
|
|
1302
1439
|
throwIfNoEntry: false,
|
|
1303
1440
|
});
|
|
1304
1441
|
if (!stat?.isFile() || stat.isSymbolicLink())
|
|
1305
1442
|
reject("artifact", "verification-input-unavailable");
|
|
1306
1443
|
}
|
|
1307
1444
|
|
|
1445
|
+
const capability = validateVerificationCapability(
|
|
1446
|
+
checkout,
|
|
1447
|
+
validated.verification,
|
|
1448
|
+
{ dependencyOwner: root },
|
|
1449
|
+
);
|
|
1450
|
+
if (!capability.ok) {
|
|
1451
|
+
if (capability.diagnostic.kind === "verification-adapter") {
|
|
1452
|
+
reject("verification-adapter", capability.diagnostic.code);
|
|
1453
|
+
}
|
|
1454
|
+
reject("artifact", "invalid-verification-contract");
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1308
1457
|
let bwrap: string;
|
|
1309
|
-
let bunExecutable: string;
|
|
1310
1458
|
try {
|
|
1311
1459
|
bwrap = dependencies.realpath(dependencies.bwrapPath);
|
|
1312
|
-
bunExecutable = resolveBunExecutable(dependencies);
|
|
1313
1460
|
} catch {
|
|
1314
1461
|
reject("environment", "bubblewrap-or-dependency-unavailable");
|
|
1315
1462
|
}
|
|
1463
|
+
const runnerPlan = sandboxRunnerPlan(capability.runnerBindings);
|
|
1464
|
+
const sandboxSecrets = [
|
|
1465
|
+
root,
|
|
1466
|
+
checkout,
|
|
1467
|
+
...runnerPlan.mounts.map((mount) => mount.source),
|
|
1468
|
+
];
|
|
1469
|
+
let bunExecutable =
|
|
1470
|
+
capability.runnerBindings.some((binding) => binding.command === "bun") ||
|
|
1471
|
+
dependencyManifestChanged
|
|
1472
|
+
? resolveBunExecutable(dependencies)
|
|
1473
|
+
: undefined;
|
|
1316
1474
|
|
|
1317
1475
|
const probeArgs = sandboxArgs(
|
|
1318
1476
|
checkout,
|
|
1319
1477
|
dependencySource,
|
|
1320
1478
|
input.dependencyTarget.kind === "dir",
|
|
1321
1479
|
bunExecutable,
|
|
1322
|
-
|
|
1480
|
+
runnerPlan,
|
|
1481
|
+
["/bin/true"],
|
|
1323
1482
|
);
|
|
1324
1483
|
result = await run(
|
|
1325
1484
|
dependencies,
|
|
@@ -1333,15 +1492,17 @@ export async function preflightCandidate(
|
|
|
1333
1492
|
if (result.error || result.status !== 0)
|
|
1334
1493
|
reject("environment", "sandbox-runtime-unavailable", {
|
|
1335
1494
|
exitCode: result.status ?? 1,
|
|
1336
|
-
excerpt: commandExcerpt(result,
|
|
1495
|
+
excerpt: commandExcerpt(result, sandboxSecrets),
|
|
1337
1496
|
});
|
|
1338
1497
|
|
|
1339
1498
|
if (dependencyManifestChanged) {
|
|
1499
|
+
bunExecutable ??= resolveBunExecutable(dependencies);
|
|
1340
1500
|
const dependencyArgs = sandboxArgs(
|
|
1341
1501
|
checkout,
|
|
1342
1502
|
dependencySource,
|
|
1343
1503
|
input.dependencyTarget.kind === "dir",
|
|
1344
1504
|
bunExecutable,
|
|
1505
|
+
runnerPlan,
|
|
1345
1506
|
[
|
|
1346
1507
|
"bun",
|
|
1347
1508
|
"install",
|
|
@@ -1362,81 +1523,67 @@ export async function preflightCandidate(
|
|
|
1362
1523
|
if (input.signal?.aborted) reject("cancelled", "cancelled");
|
|
1363
1524
|
if (result.error || result.status === null)
|
|
1364
1525
|
reject("environment", "bubblewrap-launch-failed", {
|
|
1365
|
-
excerpt: commandExcerpt(result,
|
|
1526
|
+
excerpt: commandExcerpt(result, sandboxSecrets),
|
|
1366
1527
|
});
|
|
1367
1528
|
if (result.status !== 0) {
|
|
1368
1529
|
reject("approval-boundary", "unapproved-dependency-change");
|
|
1369
1530
|
}
|
|
1370
1531
|
}
|
|
1371
1532
|
|
|
1372
|
-
|
|
1373
|
-
|
|
1533
|
+
const steps = verificationSteps(validated.verification);
|
|
1534
|
+
for (const [index, step] of steps.entries()) {
|
|
1535
|
+
const structuredReportPath =
|
|
1536
|
+
step.kind === "vitest"
|
|
1537
|
+
? path.join(temp, `verification-report-${index}.json`)
|
|
1538
|
+
: undefined;
|
|
1539
|
+
if (structuredReportPath) {
|
|
1540
|
+
writeFileSync(structuredReportPath, "", { mode: 0o600 });
|
|
1541
|
+
}
|
|
1542
|
+
const targetArgs = sandboxArgs(
|
|
1374
1543
|
checkout,
|
|
1375
1544
|
dependencySource,
|
|
1376
1545
|
input.dependencyTarget.kind === "dir",
|
|
1377
1546
|
bunExecutable,
|
|
1378
|
-
|
|
1547
|
+
runnerPlan,
|
|
1548
|
+
verificationInvocation(step, structuredReportPath !== undefined),
|
|
1549
|
+
structuredReportPath,
|
|
1379
1550
|
);
|
|
1380
1551
|
result = await run(
|
|
1381
1552
|
dependencies,
|
|
1382
1553
|
checkout,
|
|
1383
1554
|
bwrap,
|
|
1384
|
-
|
|
1555
|
+
targetArgs,
|
|
1385
1556
|
undefined,
|
|
1386
1557
|
input.signal,
|
|
1387
1558
|
);
|
|
1388
1559
|
if (input.signal?.aborted) reject("cancelled", "cancelled");
|
|
1389
|
-
|
|
1560
|
+
requireCurrentHost(input);
|
|
1561
|
+
if (result.error || result.status === null) {
|
|
1390
1562
|
reject("environment", "bubblewrap-launch-failed", {
|
|
1391
|
-
excerpt: commandExcerpt(result,
|
|
1392
|
-
});
|
|
1393
|
-
if (result.status !== 0)
|
|
1394
|
-
reject("artifact", "candidate-check-failed", {
|
|
1395
|
-
commandId: input.verification.id,
|
|
1396
|
-
exitCode: result.status,
|
|
1397
|
-
excerpt: commandExcerpt(result, [root, checkout]),
|
|
1563
|
+
excerpt: commandExcerpt(result, sandboxSecrets),
|
|
1398
1564
|
});
|
|
1565
|
+
}
|
|
1566
|
+
const report = structuredReportPath
|
|
1567
|
+
? structuredTestReport(structuredReportPath)
|
|
1568
|
+
: undefined;
|
|
1569
|
+
const normalized = normalizeTarget(step, result, sandboxSecrets, report);
|
|
1570
|
+
if (!normalized.ok) {
|
|
1571
|
+
outcome =
|
|
1572
|
+
index < steps.length - 1
|
|
1573
|
+
? failed("artifact", "candidate-check-failed", {
|
|
1574
|
+
commandId: step.id,
|
|
1575
|
+
exitCode: normalized.exitCode,
|
|
1576
|
+
testCount: normalized.testCount,
|
|
1577
|
+
identityMatch: normalized.identityMatch,
|
|
1578
|
+
excerpt: normalized.excerpt,
|
|
1579
|
+
})
|
|
1580
|
+
: normalized;
|
|
1581
|
+
break;
|
|
1582
|
+
}
|
|
1583
|
+
if (index === steps.length - 1) {
|
|
1584
|
+
outcome = { ...normalized, targets };
|
|
1585
|
+
}
|
|
1399
1586
|
}
|
|
1400
|
-
|
|
1401
|
-
const structuredReportPath = isStaticCheck(input.verification)
|
|
1402
|
-
? undefined
|
|
1403
|
-
: path.join(temp, "verification-report.json");
|
|
1404
|
-
if (structuredReportPath)
|
|
1405
|
-
writeFileSync(structuredReportPath, "", { mode: 0o600 });
|
|
1406
|
-
const targetInvocation = structuredReportPath
|
|
1407
|
-
? [
|
|
1408
|
-
...input.verification.argv,
|
|
1409
|
-
"--reporter=json",
|
|
1410
|
-
`--outputFile=${SANDBOX_REPORT_TARGET}`,
|
|
1411
|
-
]
|
|
1412
|
-
: input.verification.argv;
|
|
1413
|
-
const targetArgs = sandboxArgs(
|
|
1414
|
-
checkout,
|
|
1415
|
-
dependencySource,
|
|
1416
|
-
input.dependencyTarget.kind === "dir",
|
|
1417
|
-
bunExecutable,
|
|
1418
|
-
targetInvocation,
|
|
1419
|
-
structuredReportPath,
|
|
1420
|
-
);
|
|
1421
|
-
result = await run(
|
|
1422
|
-
dependencies,
|
|
1423
|
-
checkout,
|
|
1424
|
-
bwrap,
|
|
1425
|
-
targetArgs,
|
|
1426
|
-
undefined,
|
|
1427
|
-
input.signal,
|
|
1428
|
-
);
|
|
1429
|
-
if (input.signal?.aborted) reject("cancelled", "cancelled");
|
|
1430
|
-
requireCurrentHost(input);
|
|
1431
|
-
if (result.error || result.status === null)
|
|
1432
|
-
reject("environment", "bubblewrap-launch-failed", {
|
|
1433
|
-
excerpt: commandExcerpt(result, [root, checkout]),
|
|
1434
|
-
});
|
|
1435
|
-
const report = structuredReportPath
|
|
1436
|
-
? structuredTestReport(structuredReportPath)
|
|
1437
|
-
: undefined;
|
|
1438
|
-
const normalized = normalizeTarget(input, result, [root, checkout], report);
|
|
1439
|
-
outcome = normalized.ok ? { ...normalized, targets } : normalized;
|
|
1440
1587
|
} catch (error) {
|
|
1441
1588
|
if (input.signal?.aborted) outcome = failed("cancelled", "cancelled");
|
|
1442
1589
|
else if (error instanceof PreflightFailure)
|
package/src/child-session.ts
CHANGED