@brainbase-labs/cli 0.25.0-eng1209.6 → 0.25.0-eng1209.7

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.
Files changed (2) hide show
  1. package/dist/index.js +27 -18
  2. 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.6",
36011
+ version: "0.25.0-eng1209.7",
36012
36012
  description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
36013
36013
  type: "module",
36014
36014
  bin: {
@@ -80035,6 +80035,9 @@ async function runCommand(command, root, spec, context, additions = {}) {
80035
80035
  };
80036
80036
  child.stdout?.on("data", (chunk2) => capture(stdout, chunk2));
80037
80037
  child.stderr?.on("data", (chunk2) => capture(stderr, chunk2));
80038
+ child.once("exit", () => {
80039
+ terminate(child);
80040
+ });
80038
80041
  child.on("error", (error2) => {
80039
80042
  fail(new BenchmarkCommandExecutionError("command_start_failed", `failed to start ${command.id}: ${error2.message}`, Buffer.concat(stdout), Buffer.concat(stderr), Date.now() - started));
80040
80043
  });
@@ -80413,13 +80416,13 @@ async function copyCandidateOutput(output, manifest, spec, context) {
80413
80416
  }
80414
80417
  return copied;
80415
80418
  }
80416
- async function copyFrozenWorkspace(manifest, spec, context) {
80419
+ async function copyFrozenWorkspace(manifest, spec, context, sourceRoot = spec.workspace_root, preserveUnsafeSymlinks = false) {
80417
80420
  const destinationRoot = fs81.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-workspace-"));
80418
80421
  fs81.chmodSync(destinationRoot, 448);
80419
80422
  context.temporaryRoots.add(destinationRoot);
80420
80423
  for (const frozenFile of manifest) {
80421
80424
  assertBudget(context);
80422
- const source = path88.resolve(spec.workspace_root, safeRelPath(frozenFile.path));
80425
+ const source = path88.resolve(sourceRoot, safeRelPath(frozenFile.path));
80423
80426
  const destination = path88.resolve(destinationRoot, safeRelPath(frozenFile.path));
80424
80427
  if (frozenFile.kind === "symlink") {
80425
80428
  const stat = fs81.lstatSync(source);
@@ -80427,18 +80430,18 @@ async function copyFrozenWorkspace(manifest, spec, context) {
80427
80430
  if (target === null || Buffer.byteLength(target) !== frozenFile.size || sha256(target) !== frozenFile.sha256) {
80428
80431
  throw new BenchmarkPhaseError("evidence_tampered", `workspace changed after it was frozen: ${frozenFile.path}`);
80429
80432
  }
80430
- if (path88.isAbsolute(target)) {
80433
+ if (!preserveUnsafeSymlinks && path88.isAbsolute(target)) {
80431
80434
  throw new BenchmarkPhaseError("unsafe_workspace_symlink", `sandbox evaluator workspace cannot reproduce an absolute symlink: ${frozenFile.path}`);
80432
80435
  }
80433
80436
  const resolvedTarget = path88.resolve(path88.dirname(source), target);
80434
- if (!isWithin(spec.workspace_root, resolvedTarget)) {
80437
+ if (!preserveUnsafeSymlinks && !isWithin(sourceRoot, resolvedTarget)) {
80435
80438
  throw new BenchmarkPhaseError("unsafe_workspace_symlink", `sandbox evaluator workspace symlink escapes the workspace: ${frozenFile.path}`);
80436
80439
  }
80437
80440
  fs81.mkdirSync(path88.dirname(destination), { recursive: true, mode: 448 });
80438
80441
  fs81.symlinkSync(target, destination);
80439
80442
  continue;
80440
80443
  }
80441
- await atomicCopy(source, destination, frozenFile.mode, spec.workspace_root);
80444
+ await atomicCopy(source, destination, frozenFile.mode, sourceRoot);
80442
80445
  const copied = await recordFile(destinationRoot, destination, "workspace");
80443
80446
  if (copied.sha256 !== frozenFile.sha256 || copied.size !== frozenFile.size || copied.mode !== frozenFile.mode) {
80444
80447
  throw new BenchmarkPhaseError("evidence_tampered", `workspace changed after it was frozen: ${frozenFile.path}`);
@@ -80513,7 +80516,7 @@ var CriterionResultSchema = exports_external.object({
80513
80516
  var CriteriaResultFileSchema = exports_external.object({
80514
80517
  criteria: exports_external.array(CriterionResultSchema).max(MAX_CRITERIA_PER_EVALUATOR)
80515
80518
  }).strict();
80516
- function readCriterionResults(resultPath, criterionKeys, allowedEvidenceIds) {
80519
+ function readCriterionResults(resultPath, criterionKeys, allowedEvidenceIds, spec) {
80517
80520
  let opened;
80518
80521
  try {
80519
80522
  opened = openRegularFileNoFollow(resultPath, "criterion result", path88.dirname(resultPath));
@@ -80557,7 +80560,13 @@ function readCriterionResults(resultPath, criterionKeys, allowedEvidenceIds) {
80557
80560
  if (unknownEvidenceIds.length > 0) {
80558
80561
  throw new BenchmarkPhaseError("invalid_criterion_result", "criterion result cites evidence outside the evaluator plan", { unknown_evidence_ids: unknownEvidenceIds });
80559
80562
  }
80560
- return criterionKeys.map((key2) => byKey.get(key2));
80563
+ return criterionKeys.map((key2) => {
80564
+ const criterion = byKey.get(key2);
80565
+ return {
80566
+ ...criterion,
80567
+ explanation: redactCommandOutput(Buffer.from(criterion.explanation), spec).toString("utf8")
80568
+ };
80569
+ });
80561
80570
  } finally {
80562
80571
  fs81.closeSync(opened.fd);
80563
80572
  }
@@ -80580,7 +80589,7 @@ function eventType(event) {
80580
80589
  }
80581
80590
  return;
80582
80591
  }
80583
- async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, frozenEvidence, context) {
80592
+ async function evaluateOne(evaluator, spec, manifest, frozenWorkspaceRoot, finalOutput, trajectory, frozenEvidence, context) {
80584
80593
  const started = Date.now();
80585
80594
  const base2 = {
80586
80595
  id: evaluator.id,
@@ -80653,8 +80662,8 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
80653
80662
  }
80654
80663
  if (evaluator.type === "workspace_assertion") {
80655
80664
  const relative = workspaceRel(evaluator.path);
80656
- assertNoSymlinkTraversal(spec.workspace_root, relative);
80657
- const candidate = path88.resolve(spec.workspace_root, relative);
80665
+ assertNoSymlinkTraversal(frozenWorkspaceRoot, relative);
80666
+ const candidate = path88.resolve(frozenWorkspaceRoot, relative);
80658
80667
  let stat = null;
80659
80668
  try {
80660
80669
  stat = fs81.lstatSync(candidate);
@@ -80675,7 +80684,7 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
80675
80684
  verdict = !exists2;
80676
80685
  if (evaluator.assertion.operator === "sha256") {
80677
80686
  if (stat?.isFile()) {
80678
- const opened = openRegularFileNoFollow(candidate, `workspace assertion ${relative}`, spec.workspace_root);
80687
+ const opened = openRegularFileNoFollow(candidate, `workspace assertion ${relative}`, frozenWorkspaceRoot);
80679
80688
  try {
80680
80689
  actualSha256 = await sha256OfDescriptor(opened.fd);
80681
80690
  verdict = actualSha256 === evaluator.assertion.expected;
@@ -80686,7 +80695,7 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
80686
80695
  }
80687
80696
  if (evaluator.assertion.operator === "contains") {
80688
80697
  if (stat?.isFile()) {
80689
- const opened = openRegularFileNoFollow(candidate, `workspace assertion ${relative}`, spec.workspace_root);
80698
+ const opened = openRegularFileNoFollow(candidate, `workspace assertion ${relative}`, frozenWorkspaceRoot);
80690
80699
  try {
80691
80700
  verdict = readDescriptor(opened.fd).toString("utf8").includes(evaluator.assertion.expected);
80692
80701
  } finally {
@@ -80715,7 +80724,7 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
80715
80724
  let isolatedTestsRoot;
80716
80725
  let privateResultRoot;
80717
80726
  try {
80718
- const evaluatorWorkspace = await copyFrozenWorkspace(manifest, spec, context);
80727
+ const evaluatorWorkspace = await copyFrozenWorkspace(manifest, spec, context, frozenWorkspaceRoot);
80719
80728
  isolatedWorkspace = evaluatorWorkspace;
80720
80729
  isolatedTestsRoot = await copyEvaluatorTests(spec, context);
80721
80730
  const testsPath = evaluatorTestsPath(evaluator, isolatedTestsRoot);
@@ -80741,7 +80750,7 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
80741
80750
  const stderr = await writeLog(spec.logs_root, `${evaluator.id}.stderr.log`, result2.stderr, spec);
80742
80751
  let criterionResults;
80743
80752
  try {
80744
- criterionResults = evaluator.criterion_keys && criterionResultPath ? readCriterionResults(criterionResultPath, evaluator.criterion_keys, evaluator.allowed_evidence_ids ?? []) : undefined;
80753
+ criterionResults = evaluator.criterion_keys && criterionResultPath ? readCriterionResults(criterionResultPath, evaluator.criterion_keys, evaluator.allowed_evidence_ids ?? [], spec) : undefined;
80745
80754
  } catch (error2) {
80746
80755
  const normalized = stableError(error2);
80747
80756
  return {
@@ -80873,12 +80882,12 @@ async function executeEvaluate(spec, context) {
80873
80882
  assertEvaluateOutputBudget(spec, context);
80874
80883
  }
80875
80884
  await verifyRecordsUnchanged(manifest, spec);
80885
+ const frozenWorkspaceRoot = await copyFrozenWorkspace(manifest, spec, context, spec.workspace_root, true);
80876
80886
  for (const reference of spec.references) {
80877
80887
  const referenceOutputs = await copyMaterial(reference, spec.staging_root, spec.tests_root, "tests", false, context);
80878
80888
  outputs.push(...referenceOutputs);
80879
80889
  context.outputs.push(...referenceOutputs);
80880
80890
  }
80881
- const frozenOutputCount = context.outputs.length;
80882
80891
  const evaluators = [];
80883
80892
  const evaluatorOrder = new Map(spec.evaluators.map((evaluator, index) => [evaluator.id, index]));
80884
80893
  const executionOrder = [...spec.evaluators].sort((left, right) => Number(left.type === "sandbox_command") - Number(right.type === "sandbox_command"));
@@ -80886,7 +80895,7 @@ async function executeEvaluate(spec, context) {
80886
80895
  assertBudget(context);
80887
80896
  const started = Date.now();
80888
80897
  try {
80889
- const evaluated = await evaluateOne(evaluator, spec, manifest, finalOutput.buffer.toString("utf8"), trajectory, { finalOutputPath, trajectoryPath }, context);
80898
+ const evaluated = await evaluateOne(evaluator, spec, manifest, frozenWorkspaceRoot, finalOutput.buffer.toString("utf8"), trajectory, { finalOutputPath, trajectoryPath }, context);
80890
80899
  assertBudget(context);
80891
80900
  evaluators.push(evaluated);
80892
80901
  context.evaluators.push(evaluated);
@@ -80941,7 +80950,7 @@ async function executeEvaluate(spec, context) {
80941
80950
  assertEvaluateOutputBudget(spec, context);
80942
80951
  }
80943
80952
  }
80944
- await verifyRecordsUnchanged([...context.inputs, ...context.outputs.slice(0, frozenOutputCount)], spec);
80953
+ await verifyRecordsUnchanged([...context.inputs, ...context.outputs], spec);
80945
80954
  if (!verifyOwnedDirectory(spec.tests_root, "tests", spec) || !verifyOwnedDirectory(spec.logs_root, "logs", spec)) {
80946
80955
  throw new BenchmarkPhaseError("evidence_tampered", "benchmark evaluator changed an owned phase directory marker");
80947
80956
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainbase-labs/cli",
3
- "version": "0.25.0-eng1209.6",
3
+ "version": "0.25.0-eng1209.7",
4
4
  "description": "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
5
5
  "type": "module",
6
6
  "bin": {