@brainbase-labs/cli 0.25.0-eng1209.2 → 0.25.0-eng1209.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +70 -14
  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.2",
36011
+ version: "0.25.0-eng1209.4",
36012
36012
  description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
36013
36013
  type: "module",
36014
36014
  bin: {
@@ -78486,7 +78486,7 @@ var MAX_REMOTE_INPUT_BYTES = 2 * 1024 * 1024 * 1024;
78486
78486
  var MAX_ARCHIVE_EXTRACTED_BYTES = 2 * 1024 * 1024 * 1024;
78487
78487
  var MAX_ARCHIVE_SCAN_BYTES = 2 * 1024 * 1024 * 1024;
78488
78488
  var MAX_SANDBOX_COMMANDS = 20;
78489
- var MAX_CRITERIA_PER_EVALUATOR = 100;
78489
+ var MAX_CRITERIA_PER_EVALUATOR = 200;
78490
78490
  var MAX_CRITERIA_RESULT_BYTES = 1024 * 1024;
78491
78491
  var MAX_CRITERION_EXPLANATION_LENGTH = 16384;
78492
78492
  var MAX_CRITERION_EVIDENCE_IDS = 100;
@@ -79114,10 +79114,15 @@ async function verifyRecordsUnchanged(records, spec) {
79114
79114
  const relative = safeRelPath(record3.path);
79115
79115
  assertNoSymlinkTraversal(root, relative);
79116
79116
  const candidate = path88.resolve(root, relative);
79117
- if (!isWithin(root, candidate) || !fs81.existsSync(candidate)) {
79117
+ if (!isWithin(root, candidate)) {
79118
+ throw new BenchmarkPhaseError("evidence_tampered", `evidence was removed during evaluation: ${record3.root}:${record3.path}`);
79119
+ }
79120
+ let stat;
79121
+ try {
79122
+ stat = fs81.lstatSync(candidate);
79123
+ } catch {
79118
79124
  throw new BenchmarkPhaseError("evidence_tampered", `evidence was removed during evaluation: ${record3.root}:${record3.path}`);
79119
79125
  }
79120
- const stat = fs81.lstatSync(candidate);
79121
79126
  if (record3.kind === "symlink") {
79122
79127
  const target = stat.isSymbolicLink() ? fs81.readlinkSync(candidate) : null;
79123
79128
  if (target === null || Buffer.byteLength(target) !== record3.size || sha256(target) !== record3.sha256) {
@@ -79212,6 +79217,15 @@ function removeRemoteHydrationInputs(spec) {
79212
79217
  removedSources.add(material.source);
79213
79218
  }
79214
79219
  }
79220
+ function removePrivateHydrationSourcesBeforeSetup(spec, context) {
79221
+ removeRemoteHydrationInputs(spec);
79222
+ for (const temporary of context.temporaryRoots) {
79223
+ fs81.rmSync(temporary, { recursive: true, force: true });
79224
+ }
79225
+ context.temporaryRoots.clear();
79226
+ context.verifiedInputs.clear();
79227
+ context.preparedArchiveFiles.clear();
79228
+ }
79215
79229
  async function downloadInputReference(stagingRoot, input, context) {
79216
79230
  const cacheKey = inputCacheKey(input);
79217
79231
  const cached2 = context.verifiedInputs.get(cacheKey);
@@ -80100,6 +80114,7 @@ async function executeHydrate(spec, context) {
80100
80114
  throw error2;
80101
80115
  }
80102
80116
  }
80117
+ removePrivateHydrationSourcesBeforeSetup(spec, context);
80103
80118
  for (const command of spec.setup_commands) {
80104
80119
  assertBudget(context);
80105
80120
  let result2;
@@ -80155,7 +80170,6 @@ async function executeHydrate(spec, context) {
80155
80170
  }
80156
80171
  outputs.splice(0, outputs.length, ...finalOutputs);
80157
80172
  context.outputs.splice(0, context.outputs.length, ...finalOutputs);
80158
- removeRemoteHydrationInputs(spec);
80159
80173
  assertBudget(context);
80160
80174
  return outputs;
80161
80175
  }
@@ -80346,12 +80360,6 @@ async function copyCandidateOutput(output, manifest, spec, context) {
80346
80360
  return copied;
80347
80361
  }
80348
80362
  async function copyFrozenWorkspace(manifest, spec, context) {
80349
- for (const entry of manifest) {
80350
- assertBudget(context);
80351
- if (entry.kind === "symlink") {
80352
- throw new BenchmarkPhaseError("unsupported_workspace_symlink", `sandbox evaluator workspace cannot safely reproduce symlink: ${entry.path}`);
80353
- }
80354
- }
80355
80363
  const destinationRoot = fs81.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-workspace-"));
80356
80364
  fs81.chmodSync(destinationRoot, 448);
80357
80365
  context.temporaryRoots.add(destinationRoot);
@@ -80359,6 +80367,23 @@ async function copyFrozenWorkspace(manifest, spec, context) {
80359
80367
  assertBudget(context);
80360
80368
  const source = path88.resolve(spec.workspace_root, safeRelPath(frozenFile.path));
80361
80369
  const destination = path88.resolve(destinationRoot, safeRelPath(frozenFile.path));
80370
+ if (frozenFile.kind === "symlink") {
80371
+ const stat = fs81.lstatSync(source);
80372
+ const target = stat.isSymbolicLink() ? fs81.readlinkSync(source) : null;
80373
+ if (target === null || Buffer.byteLength(target) !== frozenFile.size || sha256(target) !== frozenFile.sha256) {
80374
+ throw new BenchmarkPhaseError("evidence_tampered", `workspace changed after it was frozen: ${frozenFile.path}`);
80375
+ }
80376
+ if (path88.isAbsolute(target)) {
80377
+ throw new BenchmarkPhaseError("unsafe_workspace_symlink", `sandbox evaluator workspace cannot reproduce an absolute symlink: ${frozenFile.path}`);
80378
+ }
80379
+ const resolvedTarget = path88.resolve(path88.dirname(source), target);
80380
+ if (!isWithin(spec.workspace_root, resolvedTarget)) {
80381
+ throw new BenchmarkPhaseError("unsafe_workspace_symlink", `sandbox evaluator workspace symlink escapes the workspace: ${frozenFile.path}`);
80382
+ }
80383
+ fs81.mkdirSync(path88.dirname(destination), { recursive: true, mode: 448 });
80384
+ fs81.symlinkSync(target, destination);
80385
+ continue;
80386
+ }
80362
80387
  await atomicCopy(source, destination, frozenFile.mode, spec.workspace_root);
80363
80388
  const copied = await recordFile(destinationRoot, destination, "workspace");
80364
80389
  if (copied.sha256 !== frozenFile.sha256 || copied.size !== frozenFile.size || copied.mode !== frozenFile.mode) {
@@ -80510,7 +80535,21 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
80510
80535
  }
80511
80536
  verdict = regexResult.exitCode === 0;
80512
80537
  }
80513
- return { ...base2, status: verdict ? "passed" : "failed", verdict, duration_ms: Date.now() - started };
80538
+ return {
80539
+ ...base2,
80540
+ status: verdict ? "passed" : "failed",
80541
+ verdict,
80542
+ duration_ms: Date.now() - started,
80543
+ details: {
80544
+ operator: assertion.operator,
80545
+ actual_size_bytes: Buffer.byteLength(finalOutput),
80546
+ ...assertion.operator === "exact" ? {
80547
+ expected_size_bytes: Buffer.byteLength(assertion.expected),
80548
+ actual_sha256: sha256(finalOutput),
80549
+ expected_sha256: sha256(assertion.expected)
80550
+ } : {}
80551
+ }
80552
+ };
80514
80553
  }
80515
80554
  if (evaluator.type === "trajectory_assertion") {
80516
80555
  const count = trajectory.filter((event) => eventType(event) === evaluator.event_type).length;
@@ -80540,6 +80579,7 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
80540
80579
  }
80541
80580
  const exists2 = stat !== null;
80542
80581
  let verdict = false;
80582
+ let actualSha256;
80543
80583
  if (evaluator.assertion.operator === "exists")
80544
80584
  verdict = exists2;
80545
80585
  if (evaluator.assertion.operator === "not_exists")
@@ -80548,7 +80588,8 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
80548
80588
  if (stat?.isFile()) {
80549
80589
  const opened = openRegularFileNoFollow(candidate, `workspace assertion ${relative}`, spec.workspace_root);
80550
80590
  try {
80551
- verdict = await sha256OfDescriptor(opened.fd) === evaluator.assertion.expected;
80591
+ actualSha256 = await sha256OfDescriptor(opened.fd);
80592
+ verdict = actualSha256 === evaluator.assertion.expected;
80552
80593
  } finally {
80553
80594
  fs81.closeSync(opened.fd);
80554
80595
  }
@@ -80564,7 +80605,22 @@ async function evaluateOne(evaluator, spec, manifest, finalOutput, trajectory, f
80564
80605
  }
80565
80606
  }
80566
80607
  }
80567
- return { ...base2, status: verdict ? "passed" : "failed", verdict, duration_ms: Date.now() - started };
80608
+ return {
80609
+ ...base2,
80610
+ status: verdict ? "passed" : "failed",
80611
+ verdict,
80612
+ duration_ms: Date.now() - started,
80613
+ details: {
80614
+ operator: evaluator.assertion.operator,
80615
+ path: relative,
80616
+ exists: exists2,
80617
+ ...stat ? {
80618
+ actual_kind: stat.isFile() ? "file" : stat.isDirectory() ? "directory" : "other",
80619
+ actual_size_bytes: stat.size
80620
+ } : {},
80621
+ ...actualSha256 ? { actual_sha256: actualSha256 } : {}
80622
+ }
80623
+ };
80568
80624
  }
80569
80625
  let isolatedWorkspace;
80570
80626
  let privateResultRoot;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainbase-labs/cli",
3
- "version": "0.25.0-eng1209.2",
3
+ "version": "0.25.0-eng1209.4",
4
4
  "description": "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
5
5
  "type": "module",
6
6
  "bin": {