@brainbase-labs/cli 0.25.0-eng1209.4 → 0.25.0-eng1209.5
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/dist/index.js +104 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -36008,7 +36008,7 @@ function padStart(s, n) {
|
|
|
36008
36008
|
// package.json
|
|
36009
36009
|
var package_default = {
|
|
36010
36010
|
name: "@brainbase-labs/cli",
|
|
36011
|
-
version: "0.25.0-eng1209.
|
|
36011
|
+
version: "0.25.0-eng1209.5",
|
|
36012
36012
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
36013
36013
|
type: "module",
|
|
36014
36014
|
bin: {
|
|
@@ -80234,6 +80234,42 @@ async function workspaceManifest(spec, context) {
|
|
|
80234
80234
|
}
|
|
80235
80235
|
return records.sort((a3, b4) => a3.path.localeCompare(b4.path));
|
|
80236
80236
|
}
|
|
80237
|
+
function treeBytes(root, context) {
|
|
80238
|
+
let totalBytes = 0;
|
|
80239
|
+
const stack = [path88.resolve(root)];
|
|
80240
|
+
while (stack.length > 0) {
|
|
80241
|
+
const directory = stack.pop();
|
|
80242
|
+
const entries = fs81.readdirSync(directory, { withFileTypes: true });
|
|
80243
|
+
for (const entry of entries) {
|
|
80244
|
+
assertBudget(context);
|
|
80245
|
+
const candidate = path88.join(directory, entry.name);
|
|
80246
|
+
const stat = fs81.lstatSync(candidate);
|
|
80247
|
+
if (stat.isDirectory()) {
|
|
80248
|
+
stack.push(candidate);
|
|
80249
|
+
continue;
|
|
80250
|
+
}
|
|
80251
|
+
if (stat.isFile()) {
|
|
80252
|
+
totalBytes += stat.size;
|
|
80253
|
+
continue;
|
|
80254
|
+
}
|
|
80255
|
+
if (stat.isSymbolicLink()) {
|
|
80256
|
+
totalBytes += Buffer.byteLength(fs81.readlinkSync(candidate));
|
|
80257
|
+
continue;
|
|
80258
|
+
}
|
|
80259
|
+
throw new BenchmarkPhaseError("unsafe_path", `evaluate output contains an unsupported filesystem entry: ${path88.relative(root, candidate)}`);
|
|
80260
|
+
}
|
|
80261
|
+
}
|
|
80262
|
+
return totalBytes;
|
|
80263
|
+
}
|
|
80264
|
+
function assertEvaluateOutputBudget(spec, context, additionalBytes = 0) {
|
|
80265
|
+
const actual = treeBytes(spec.logs_root, context) + additionalBytes;
|
|
80266
|
+
if (actual > spec.workspace_limits.max_total_bytes) {
|
|
80267
|
+
throw new BenchmarkPhaseError("workspace_limit_exceeded", "evaluate output bytes exceed the workspace byte limit", {
|
|
80268
|
+
actual,
|
|
80269
|
+
max_total_bytes: spec.workspace_limits.max_total_bytes
|
|
80270
|
+
});
|
|
80271
|
+
}
|
|
80272
|
+
}
|
|
80237
80273
|
function candidateGlob(pattern) {
|
|
80238
80274
|
let source = "^";
|
|
80239
80275
|
for (let index = 0;index < pattern.length; index += 1) {
|
|
@@ -80392,13 +80428,48 @@ async function copyFrozenWorkspace(manifest, spec, context) {
|
|
|
80392
80428
|
}
|
|
80393
80429
|
return destinationRoot;
|
|
80394
80430
|
}
|
|
80395
|
-
function
|
|
80431
|
+
async function copyEvaluatorTests(spec, context) {
|
|
80432
|
+
const destinationRoot = fs81.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-tests-"));
|
|
80433
|
+
fs81.chmodSync(destinationRoot, 448);
|
|
80434
|
+
context.temporaryRoots.add(destinationRoot);
|
|
80435
|
+
const stack = [{ source: spec.tests_root, destination: destinationRoot }];
|
|
80436
|
+
while (stack.length > 0) {
|
|
80437
|
+
assertBudget(context);
|
|
80438
|
+
const current = stack.pop();
|
|
80439
|
+
const entries = fs81.readdirSync(current.source, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
|
|
80440
|
+
for (const entry of entries) {
|
|
80441
|
+
assertBudget(context);
|
|
80442
|
+
const source = path88.join(current.source, entry.name);
|
|
80443
|
+
const destination = path88.join(current.destination, entry.name);
|
|
80444
|
+
const stat = fs81.lstatSync(source);
|
|
80445
|
+
if (stat.isSymbolicLink()) {
|
|
80446
|
+
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains a symlink: ${path88.relative(spec.tests_root, source)}`);
|
|
80447
|
+
}
|
|
80448
|
+
if (stat.isDirectory()) {
|
|
80449
|
+
fs81.mkdirSync(destination, { recursive: true, mode: stat.mode & 511 });
|
|
80450
|
+
stack.push({ source, destination });
|
|
80451
|
+
continue;
|
|
80452
|
+
}
|
|
80453
|
+
if (!stat.isFile()) {
|
|
80454
|
+
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains an unsupported filesystem entry: ${path88.relative(spec.tests_root, source)}`);
|
|
80455
|
+
}
|
|
80456
|
+
await atomicCopy(source, destination, stat.mode & 511, spec.tests_root);
|
|
80457
|
+
const sourceRecord = await recordFile(spec.tests_root, source, "tests");
|
|
80458
|
+
const copiedRecord = await recordFile(destinationRoot, destination, "tests");
|
|
80459
|
+
if (copiedRecord.path !== sourceRecord.path || copiedRecord.sha256 !== sourceRecord.sha256 || copiedRecord.size !== sourceRecord.size || copiedRecord.mode !== sourceRecord.mode) {
|
|
80460
|
+
throw new BenchmarkPhaseError("evidence_tampered", `evaluator reference changed while it was copied: ${sourceRecord.path}`);
|
|
80461
|
+
}
|
|
80462
|
+
}
|
|
80463
|
+
}
|
|
80464
|
+
return destinationRoot;
|
|
80465
|
+
}
|
|
80466
|
+
function evaluatorTestsPath(evaluator, testsRoot) {
|
|
80396
80467
|
if (!evaluator.tests_path)
|
|
80397
|
-
return
|
|
80468
|
+
return testsRoot;
|
|
80398
80469
|
const relative = normalizedRootRelative(evaluator.tests_path);
|
|
80399
|
-
assertNoSymlinkTraversal(
|
|
80400
|
-
const candidate = path88.resolve(
|
|
80401
|
-
if (!isWithin(
|
|
80470
|
+
assertNoSymlinkTraversal(testsRoot, relative);
|
|
80471
|
+
const candidate = path88.resolve(testsRoot, relative);
|
|
80472
|
+
if (!isWithin(testsRoot, candidate) || !fs81.existsSync(candidate)) {
|
|
80402
80473
|
throw new BenchmarkPhaseError("invalid_tests_path", `evaluator tests_path does not exist: ${evaluator.tests_path}`);
|
|
80403
80474
|
}
|
|
80404
80475
|
const stat = fs81.lstatSync(candidate);
|
|
@@ -80623,12 +80694,14 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
|
|
|
80623
80694
|
};
|
|
80624
80695
|
}
|
|
80625
80696
|
let isolatedWorkspace;
|
|
80697
|
+
let isolatedTestsRoot;
|
|
80626
80698
|
let privateResultRoot;
|
|
80627
80699
|
try {
|
|
80628
80700
|
const evaluatorWorkspace = await copyFrozenWorkspace(manifest, spec, context);
|
|
80629
80701
|
isolatedWorkspace = evaluatorWorkspace;
|
|
80630
|
-
|
|
80631
|
-
const
|
|
80702
|
+
isolatedTestsRoot = await copyEvaluatorTests(spec, context);
|
|
80703
|
+
const testsPath = evaluatorTestsPath(evaluator, isolatedTestsRoot);
|
|
80704
|
+
const commandRoot = evaluator.root === "workspace" ? evaluatorWorkspace : isolatedTestsRoot;
|
|
80632
80705
|
const command = { id: evaluator.id, ...evaluator.command };
|
|
80633
80706
|
const environment = {
|
|
80634
80707
|
BRAINBASE_BENCHMARK_WORKSPACE: evaluatorWorkspace,
|
|
@@ -80679,7 +80752,7 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
|
|
|
80679
80752
|
...criterionResults ? { criterion_results: criterionResults } : {}
|
|
80680
80753
|
};
|
|
80681
80754
|
} finally {
|
|
80682
|
-
for (const temporary of [privateResultRoot, isolatedWorkspace]) {
|
|
80755
|
+
for (const temporary of [privateResultRoot, isolatedTestsRoot, isolatedWorkspace]) {
|
|
80683
80756
|
if (!temporary)
|
|
80684
80757
|
continue;
|
|
80685
80758
|
fs81.rmSync(temporary, { recursive: true, force: true });
|
|
@@ -80728,6 +80801,7 @@ async function executeEvaluate(spec, context) {
|
|
|
80728
80801
|
];
|
|
80729
80802
|
outputs.push(...frozenEvidenceRecords);
|
|
80730
80803
|
context.outputs.push(...frozenEvidenceRecords);
|
|
80804
|
+
assertEvaluateOutputBudget(spec, context);
|
|
80731
80805
|
assertBudget(context);
|
|
80732
80806
|
const manifest = await workspaceManifest(spec, context);
|
|
80733
80807
|
const manifestPath2 = path88.join(spec.logs_root, "candidate-workspace-manifest.json");
|
|
@@ -80740,6 +80814,7 @@ async function executeEvaluate(spec, context) {
|
|
|
80740
80814
|
const manifestRecord = await recordFile(spec.logs_root, manifestPath2, "logs");
|
|
80741
80815
|
outputs.push(manifestRecord);
|
|
80742
80816
|
context.outputs.push(manifestRecord);
|
|
80817
|
+
assertEvaluateOutputBudget(spec, context);
|
|
80743
80818
|
for (const artifactRelInput of spec.candidate_artifacts) {
|
|
80744
80819
|
const artifactRel = workspaceRel(artifactRelInput);
|
|
80745
80820
|
assertNoSymlinkTraversal(spec.workspace_root, artifactRel);
|
|
@@ -80757,11 +80832,13 @@ async function executeEvaluate(spec, context) {
|
|
|
80757
80832
|
outputs.push(artifact);
|
|
80758
80833
|
context.outputs.push(artifact);
|
|
80759
80834
|
}
|
|
80835
|
+
assertEvaluateOutputBudget(spec, context);
|
|
80760
80836
|
for (const candidateOutput of spec.candidate_outputs) {
|
|
80761
80837
|
const copied = await copyCandidateOutput(candidateOutput, manifest, spec, context);
|
|
80762
80838
|
outputs.push(...copied);
|
|
80763
80839
|
context.outputs.push(...copied);
|
|
80764
80840
|
}
|
|
80841
|
+
assertEvaluateOutputBudget(spec, context);
|
|
80765
80842
|
if (spec.capture_workspace_archive) {
|
|
80766
80843
|
const regularFiles = manifest.filter((entry) => entry.kind !== "symlink").map((entry) => entry.path);
|
|
80767
80844
|
const archive = path88.join(spec.logs_root, "candidate-workspace.tar.gz");
|
|
@@ -80775,6 +80852,7 @@ async function executeEvaluate(spec, context) {
|
|
|
80775
80852
|
const archiveRecord = await recordFile(spec.logs_root, archive, "logs");
|
|
80776
80853
|
outputs.push(archiveRecord);
|
|
80777
80854
|
context.outputs.push(archiveRecord);
|
|
80855
|
+
assertEvaluateOutputBudget(spec, context);
|
|
80778
80856
|
}
|
|
80779
80857
|
await verifyRecordsUnchanged(manifest, spec);
|
|
80780
80858
|
for (const reference of spec.references) {
|
|
@@ -80833,12 +80911,16 @@ async function executeEvaluate(spec, context) {
|
|
|
80833
80911
|
}
|
|
80834
80912
|
if (requiredResultError)
|
|
80835
80913
|
throw requiredResultError;
|
|
80914
|
+
if (evaluator.type === "sandbox_command") {
|
|
80915
|
+
assertEvaluateOutputBudget(spec, context);
|
|
80916
|
+
}
|
|
80836
80917
|
}
|
|
80837
80918
|
await verifyRecordsUnchanged([...context.inputs, ...context.outputs.slice(0, frozenOutputCount)], spec);
|
|
80838
80919
|
if (!verifyOwnedDirectory(spec.tests_root, "tests", spec) || !verifyOwnedDirectory(spec.logs_root, "logs", spec)) {
|
|
80839
80920
|
throw new BenchmarkPhaseError("evidence_tampered", "benchmark evaluator changed an owned phase directory marker");
|
|
80840
80921
|
}
|
|
80841
80922
|
assertBudget(context);
|
|
80923
|
+
assertEvaluateOutputBudget(spec, context);
|
|
80842
80924
|
evaluators.sort((left, right) => evaluatorOrder.get(left.id) - evaluatorOrder.get(right.id));
|
|
80843
80925
|
return { outputs, evaluators };
|
|
80844
80926
|
}
|
|
@@ -81024,6 +81106,7 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
|
|
|
81024
81106
|
let status = "failed";
|
|
81025
81107
|
let error2;
|
|
81026
81108
|
let context;
|
|
81109
|
+
let validatedSpec;
|
|
81027
81110
|
let resultPathValidated = false;
|
|
81028
81111
|
try {
|
|
81029
81112
|
let bytes;
|
|
@@ -81043,6 +81126,7 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
|
|
|
81043
81126
|
}
|
|
81044
81127
|
identity2 = rawIdentity(raw);
|
|
81045
81128
|
const spec = BenchmarkSpecSchema.parse(raw);
|
|
81129
|
+
validatedSpec = spec;
|
|
81046
81130
|
if (expectedPhase && spec.phase !== expectedPhase) {
|
|
81047
81131
|
throw new BenchmarkPhaseError("phase_mismatch", `the ${expectedPhase} command cannot execute a ${spec.phase} spec`);
|
|
81048
81132
|
}
|
|
@@ -81122,6 +81206,17 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
|
|
|
81122
81206
|
if (!resultPathValidated || !context?.logsOwned) {
|
|
81123
81207
|
return { exitCode: status === "succeeded" ? 0 : 1, result: result2 };
|
|
81124
81208
|
}
|
|
81209
|
+
if (status === "succeeded" && validatedSpec?.phase === "evaluate") {
|
|
81210
|
+
try {
|
|
81211
|
+
const resultBytes = Buffer.byteLength(`${JSON.stringify(result2, null, 2)}
|
|
81212
|
+
`);
|
|
81213
|
+
assertEvaluateOutputBudget(validatedSpec, context, resultBytes);
|
|
81214
|
+
} catch (budgetError) {
|
|
81215
|
+
status = "failed";
|
|
81216
|
+
result2.status = "failed";
|
|
81217
|
+
result2.error = stableError(budgetError);
|
|
81218
|
+
}
|
|
81219
|
+
}
|
|
81125
81220
|
try {
|
|
81126
81221
|
writeJsonAtomic(resultPath, result2);
|
|
81127
81222
|
} catch (writeError) {
|