bitfab 0.52.4 → 0.52.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.
Files changed (33) hide show
  1. package/README.md +2 -0
  2. package/dist/{chunk-IG3CPSRQ.js → chunk-3D7FNJ5R.js} +2 -2
  3. package/dist/{chunk-IG3CPSRQ.js.map → chunk-3D7FNJ5R.js.map} +1 -1
  4. package/dist/{chunk-HKTODDFP.js → chunk-3QXNM62Y.js} +3 -3
  5. package/dist/chunk-3QXNM62Y.js.map +1 -0
  6. package/dist/{chunk-U2D7ACC4.js → chunk-6DRFQJ75.js} +110 -13
  7. package/dist/chunk-6DRFQJ75.js.map +1 -0
  8. package/dist/{chunk-34B7PVAM.js → chunk-CAE7HE4C.js} +3 -2
  9. package/dist/{chunk-34B7PVAM.js.map → chunk-CAE7HE4C.js.map} +1 -1
  10. package/dist/{chunk-AUROMI67.js → chunk-EMRHO6YW.js} +241 -21
  11. package/dist/chunk-EMRHO6YW.js.map +1 -0
  12. package/dist/{http-RFNQ7LSU.js → http-Q6UEKZRF.js} +2 -2
  13. package/dist/{http-F3AXLOJT.js → http-UQT6QVBC.js} +2 -2
  14. package/dist/index.cjs +380 -57
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +10 -2
  17. package/dist/index.d.ts +10 -2
  18. package/dist/index.js +3 -3
  19. package/dist/node.cjs +380 -57
  20. package/dist/node.cjs.map +1 -1
  21. package/dist/node.d.cts +1 -1
  22. package/dist/node.d.ts +1 -1
  23. package/dist/node.js +3 -3
  24. package/dist/{replay-ZOTYMBMD.js → replay-UVSZFZW7.js} +3 -3
  25. package/dist/replayCli.js +2 -2
  26. package/dist/seedCli.js +2 -2
  27. package/package.json +1 -1
  28. package/dist/chunk-AUROMI67.js.map +0 -1
  29. package/dist/chunk-HKTODDFP.js.map +0 -1
  30. package/dist/chunk-U2D7ACC4.js.map +0 -1
  31. /package/dist/{http-F3AXLOJT.js.map → http-Q6UEKZRF.js.map} +0 -0
  32. /package/dist/{http-RFNQ7LSU.js.map → http-UQT6QVBC.js.map} +0 -0
  33. /package/dist/{replay-ZOTYMBMD.js.map → replay-UVSZFZW7.js.map} +0 -0
package/dist/node.cjs CHANGED
@@ -97,7 +97,7 @@ var __version__, __packageName__;
97
97
  var init_version_generated = __esm({
98
98
  "src/version.generated.ts"() {
99
99
  "use strict";
100
- __version__ = "0.52.4";
100
+ __version__ = "0.52.5";
101
101
  __packageName__ = "bitfab";
102
102
  }
103
103
  });
@@ -1137,7 +1137,7 @@ var init_otel = __esm({
1137
1137
  if (this.onDelivered === void 0) {
1138
1138
  return;
1139
1139
  }
1140
- const refs = spans.map((span) => span.ref).filter((ref) => ref !== void 0);
1140
+ const refs = spans.map((span) => span.ref).filter((ref2) => ref2 !== void 0);
1141
1141
  if (refs.length === 0) {
1142
1142
  return;
1143
1143
  }
@@ -1394,9 +1394,9 @@ function parseRetryAfterMs(header) {
1394
1394
  }
1395
1395
  return Math.max(0, at - Date.now());
1396
1396
  }
1397
- function carrierMeta(operation, payload, ref) {
1397
+ function carrierMeta(operation, payload, ref2) {
1398
1398
  return {
1399
- ref,
1399
+ ref: ref2,
1400
1400
  name: carrierName(operation, payload),
1401
1401
  startTime: payloadTimestamp(payload, "started_at"),
1402
1402
  endTime: payloadTimestamp(payload, "ended_at"),
@@ -1641,22 +1641,22 @@ var init_http = __esm({
1641
1641
  return reports;
1642
1642
  }
1643
1643
  /** Build a carrier's meta and record what it adds to its trace's expected set. */
1644
- recordedMeta(operation, payload, ref) {
1645
- this.recordSubmittedCarrier(ref);
1646
- return carrierMeta(operation, payload, ref);
1644
+ recordedMeta(operation, payload, ref2) {
1645
+ this.recordSubmittedCarrier(ref2);
1646
+ return carrierMeta(operation, payload, ref2);
1647
1647
  }
1648
- recordSubmittedCarrier(ref) {
1649
- if (ref === void 0) {
1648
+ recordSubmittedCarrier(ref2) {
1649
+ if (ref2 === void 0) {
1650
1650
  return;
1651
1651
  }
1652
- const delivery = this.traceDeliveries.get(ref.traceId);
1652
+ const delivery = this.traceDeliveries.get(ref2.traceId);
1653
1653
  if (delivery === void 0) {
1654
1654
  return;
1655
1655
  }
1656
- if (ref.spanId === void 0) {
1656
+ if (ref2.spanId === void 0) {
1657
1657
  delivery.closed = true;
1658
1658
  } else {
1659
- delivery.submittedSpanIds.add(ref.spanId);
1659
+ delivery.submittedSpanIds.add(ref2.spanId);
1660
1660
  }
1661
1661
  }
1662
1662
  /**
@@ -1682,15 +1682,15 @@ var init_http = __esm({
1682
1682
  }
1683
1683
  }
1684
1684
  recordDeliveredCarriers(refs) {
1685
- for (const ref of refs) {
1686
- const delivery = this.traceDeliveries.get(ref.traceId);
1685
+ for (const ref2 of refs) {
1686
+ const delivery = this.traceDeliveries.get(ref2.traceId);
1687
1687
  if (delivery === void 0) {
1688
1688
  continue;
1689
1689
  }
1690
- if (ref.spanId === void 0) {
1690
+ if (ref2.spanId === void 0) {
1691
1691
  delivery.closingAcked = true;
1692
1692
  } else {
1693
- delivery.ackedSpanIds.add(ref.spanId);
1693
+ delivery.ackedSpanIds.add(ref2.spanId);
1694
1694
  }
1695
1695
  }
1696
1696
  }
@@ -1720,9 +1720,9 @@ var init_http = __esm({
1720
1720
  */
1721
1721
  async waitForPendingRequests(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS2) {
1722
1722
  const deadline = Date.now() + Math.max(timeoutMs, 0);
1723
- const settled = await this.settleDeferredWork(timeoutMs);
1723
+ const settled2 = await this.settleDeferredWork(timeoutMs);
1724
1724
  const flushed = await this.traceTransport?.flush(Math.max(0, deadline - Date.now())) ?? true;
1725
- return settled && flushed;
1725
+ return settled2 && flushed;
1726
1726
  }
1727
1727
  /**
1728
1728
  * Flush and permanently close this client's tracing transport. Idempotent:
@@ -1735,14 +1735,14 @@ var init_http = __esm({
1735
1735
  }
1736
1736
  const deadline = Date.now() + Math.max(timeoutMs, 0);
1737
1737
  this.closing = (async () => {
1738
- const settled = await this.settleDeferredWork(
1738
+ const settled2 = await this.settleDeferredWork(
1739
1739
  Math.max(0, deadline - Date.now())
1740
1740
  );
1741
1741
  this.closed = true;
1742
1742
  const transport = this.traceTransport;
1743
1743
  this.traceTransport = void 0;
1744
1744
  const shutdownOk = await transport?.shutdown(Math.max(0, deadline - Date.now())) ?? true;
1745
- return settled && shutdownOk;
1745
+ return settled2 && shutdownOk;
1746
1746
  })();
1747
1747
  return this.closing;
1748
1748
  }
@@ -2353,6 +2353,112 @@ var init_randomUuid = __esm({
2353
2353
  }
2354
2354
  });
2355
2355
 
2356
+ // src/gitCommand.ts
2357
+ function isUnrefable(value) {
2358
+ return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
2359
+ }
2360
+ function unrefStream(stream) {
2361
+ if (isUnrefable(stream)) {
2362
+ stream.unref();
2363
+ }
2364
+ }
2365
+ function terminate(child) {
2366
+ if (child.pid && process.platform !== "win32") {
2367
+ try {
2368
+ process.kill(-child.pid, "SIGTERM");
2369
+ return;
2370
+ } catch {
2371
+ child.kill("SIGTERM");
2372
+ return;
2373
+ }
2374
+ }
2375
+ child.kill("SIGTERM");
2376
+ }
2377
+ async function gitRunner(options) {
2378
+ let spawn;
2379
+ try {
2380
+ ;
2381
+ ({ spawn } = await import("child_process"));
2382
+ } catch {
2383
+ return null;
2384
+ }
2385
+ return (dir, args) => new Promise((resolve) => {
2386
+ let child;
2387
+ try {
2388
+ child = spawn("git", args, {
2389
+ cwd: dir,
2390
+ detached: process.platform !== "win32",
2391
+ stdio: ["ignore", "pipe", "pipe"]
2392
+ });
2393
+ } catch {
2394
+ resolve(null);
2395
+ return;
2396
+ }
2397
+ const chunks = [];
2398
+ let size = 0;
2399
+ let overflow = false;
2400
+ let exitCode = null;
2401
+ let done = false;
2402
+ const timers = [];
2403
+ const schedule = (callback, ms) => {
2404
+ const timer = setTimeout(callback, ms);
2405
+ if (!options.keepProcessAlive) {
2406
+ timer.unref();
2407
+ }
2408
+ timers.push(timer);
2409
+ };
2410
+ const finish = () => {
2411
+ if (done) {
2412
+ return;
2413
+ }
2414
+ done = true;
2415
+ for (const timer of timers) {
2416
+ clearTimeout(timer);
2417
+ }
2418
+ child.stdout?.destroy();
2419
+ child.stderr?.destroy();
2420
+ resolve(
2421
+ exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
2422
+ );
2423
+ };
2424
+ child.stdout?.on("data", (chunk) => {
2425
+ size += chunk.length;
2426
+ if (size > options.maxBuffer) {
2427
+ overflow = true;
2428
+ terminate(child);
2429
+ return;
2430
+ }
2431
+ chunks.push(chunk);
2432
+ });
2433
+ child.stderr?.resume();
2434
+ child.on("error", () => {
2435
+ exitCode = null;
2436
+ finish();
2437
+ });
2438
+ child.on("exit", (code) => {
2439
+ exitCode = code;
2440
+ schedule(finish, EXIT_GRACE_MS);
2441
+ });
2442
+ child.on("close", (code) => {
2443
+ exitCode = code ?? exitCode;
2444
+ finish();
2445
+ });
2446
+ schedule(() => terminate(child), options.timeoutMs);
2447
+ if (!options.keepProcessAlive) {
2448
+ child.unref();
2449
+ unrefStream(child.stdout);
2450
+ unrefStream(child.stderr);
2451
+ }
2452
+ });
2453
+ }
2454
+ var EXIT_GRACE_MS;
2455
+ var init_gitCommand = __esm({
2456
+ "src/gitCommand.ts"() {
2457
+ "use strict";
2458
+ EXIT_GRACE_MS = 500;
2459
+ }
2460
+ });
2461
+
2356
2462
  // src/mockOverride.ts
2357
2463
  function resolveMockValue(value, ctx) {
2358
2464
  return typeof value === "function" ? value(ctx) : value;
@@ -2409,37 +2515,33 @@ async function readCodeChangeFile() {
2409
2515
  }
2410
2516
  }
2411
2517
  async function captureCodeChangeFromGit(cwd, label) {
2412
- let execFile;
2413
2518
  let readFile;
2414
2519
  try {
2415
2520
  ;
2416
- ({ execFile } = await import("child_process"));
2417
2521
  ({ readFile } = await import("fs/promises"));
2418
2522
  } catch {
2419
2523
  return null;
2420
2524
  }
2421
- const git = (dir, args) => new Promise((resolve) => {
2422
- execFile(
2423
- "git",
2424
- args,
2425
- // 30s timeout so a hung git (e.g. a network-touching ref op) can't
2426
- // block the whole replay indefinitely.
2427
- { cwd: dir, maxBuffer: 64 * 1024 * 1024, timeout: 3e4 },
2428
- (err, stdout) => resolve(err ? null : stdout)
2429
- );
2525
+ const git = await gitRunner({
2526
+ timeoutMs: 3e4,
2527
+ maxBuffer: 64 * 1024 * 1024,
2528
+ keepProcessAlive: true
2430
2529
  });
2530
+ if (!git) {
2531
+ return null;
2532
+ }
2431
2533
  try {
2432
2534
  const root = (await git(cwd, ["rev-parse", "--show-toplevel"]))?.trim();
2433
2535
  if (!root) {
2434
2536
  return null;
2435
2537
  }
2436
- const resolved = await resolveBase(git, root);
2437
- if (!resolved) {
2538
+ const resolved2 = await resolveBase(git, root);
2539
+ if (!resolved2) {
2438
2540
  return null;
2439
2541
  }
2440
- const { base, fromTrunk } = resolved;
2441
- const blobBytes = async (ref, path) => {
2442
- const out = await git(root, ["cat-file", "-s", `${ref}:${path}`]);
2542
+ const { base, fromTrunk } = resolved2;
2543
+ const blobBytes = async (ref2, path) => {
2544
+ const out = await git(root, ["cat-file", "-s", `${ref2}:${path}`]);
2443
2545
  const n = out ? Number.parseInt(out.trim(), 10) : Number.NaN;
2444
2546
  return Number.isFinite(n) ? n : 0;
2445
2547
  };
@@ -2531,8 +2633,8 @@ async function resolveBase(git, root) {
2531
2633
  }
2532
2634
  return await refExists(git, root, "HEAD") ? { base: "HEAD", fromTrunk: false } : null;
2533
2635
  }
2534
- async function refExists(git, root, ref) {
2535
- return await git(root, ["rev-parse", "--verify", `${ref}^{object}`]) !== null;
2636
+ async function refExists(git, root, ref2) {
2637
+ return await git(root, ["rev-parse", "--verify", `${ref2}^{object}`]) !== null;
2536
2638
  }
2537
2639
  async function readWorkingFile(readFile, root, path) {
2538
2640
  try {
@@ -2567,6 +2669,7 @@ var MAX_FILES, MAX_FILE_BYTES, MAX_TOTAL_BYTES, TRUNK_CANDIDATES, NUL;
2567
2669
  var init_codeChange = __esm({
2568
2670
  "src/codeChange.ts"() {
2569
2671
  "use strict";
2672
+ init_gitCommand();
2570
2673
  MAX_FILES = 60;
2571
2674
  MAX_FILE_BYTES = 5e5;
2572
2675
  MAX_TOTAL_BYTES = 2e6;
@@ -2771,9 +2874,9 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2771
2874
  const originalSpanId = serverItem.originalSpanId ?? serverItem.sourceSpanId;
2772
2875
  try {
2773
2876
  if (includeDbBranchLease && !lease && !leaseError) {
2774
- let resolved;
2877
+ let resolved2;
2775
2878
  try {
2776
- resolved = await httpClient.resolveDbBranchLease(
2879
+ resolved2 = await httpClient.resolveDbBranchLease(
2777
2880
  testRunId,
2778
2881
  originalTraceId,
2779
2882
  dbBranchSettings,
@@ -2787,10 +2890,10 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2787
2890
  cause
2788
2891
  );
2789
2892
  }
2790
- lease = resolved.lease ?? void 0;
2791
- leaseError = resolved.leaseError ?? void 0;
2792
- dbSnapshotRef = resolved.dbSnapshotRef ?? dbSnapshotRef;
2793
- dbBranchTimings = resolved.timings ?? dbBranchTimings;
2893
+ lease = resolved2.lease ?? void 0;
2894
+ leaseError = resolved2.leaseError ?? void 0;
2895
+ dbSnapshotRef = resolved2.dbSnapshotRef ?? dbSnapshotRef;
2896
+ dbBranchTimings = resolved2.timings ?? dbBranchTimings;
2794
2897
  }
2795
2898
  if (leaseError) {
2796
2899
  throw new DbBranchReplayError(
@@ -4573,24 +4676,239 @@ function mixedTracingError(enteredApi, entered, enclosing, traceFunctionKey) {
4573
4676
  `opt-in and opt-out tracing can't be mixed in one call stack: ${enteredApi} (${entered})${subject} was entered inside a ${SURFACE_API[enclosing]} call (${enclosing}). ${MIXED_SURFACE_REMEDY[entered]}`
4574
4677
  );
4575
4678
  }
4576
- function assertSurfacesCompatible(requested, resolved, parentSurface, traceFunctionKey) {
4679
+ function assertSurfacesCompatible(requested, resolved2, parentSurface, traceFunctionKey) {
4577
4680
  if (requested === "inherit" || requested === "neutral") {
4578
4681
  return;
4579
4682
  }
4580
- if (resolved === void 0 || parentSurface === void 0) {
4683
+ if (resolved2 === void 0 || parentSurface === void 0) {
4581
4684
  return;
4582
4685
  }
4583
- if (parentSurface === resolved) {
4686
+ if (parentSurface === resolved2) {
4584
4687
  return;
4585
4688
  }
4586
4689
  throw mixedTracingError(
4587
- SURFACE_API[resolved],
4588
- resolved,
4690
+ SURFACE_API[resolved2],
4691
+ resolved2,
4589
4692
  parentSurface,
4590
4693
  traceFunctionKey
4591
4694
  );
4592
4695
  }
4593
4696
 
4697
+ // src/commitRef.ts
4698
+ init_gitCommand();
4699
+ init_readEnv();
4700
+ var EXPLICIT_SHA_ENV = "BITFAB_COMMIT_SHA";
4701
+ var DISABLE_ENV = "BITFAB_DISABLE_COMMIT_REF";
4702
+ var GIT_TIMEOUT_MS = 2e3;
4703
+ var GIT_MAX_BUFFER = 1024 * 1024;
4704
+ var VERCEL_PROVIDER_HOSTS = {
4705
+ github: "github.com",
4706
+ gitlab: "gitlab.com",
4707
+ bitbucket: "bitbucket.org"
4708
+ };
4709
+ function read(env, name) {
4710
+ if (name === null) {
4711
+ return null;
4712
+ }
4713
+ const value = env(name)?.trim();
4714
+ return value ? value : null;
4715
+ }
4716
+ function remoteFrom(...names) {
4717
+ return (env) => {
4718
+ const parts = names.map((name) => read(env, name));
4719
+ if (parts.some((part) => part === null)) {
4720
+ return null;
4721
+ }
4722
+ return normalizeRemote(parts.join("/"));
4723
+ };
4724
+ }
4725
+ function vercelRemote(env) {
4726
+ const provider = read(env, "VERCEL_GIT_PROVIDER")?.toLowerCase() ?? "";
4727
+ const host = VERCEL_PROVIDER_HOSTS[provider];
4728
+ const owner = read(env, "VERCEL_GIT_REPO_OWNER");
4729
+ const slug = read(env, "VERCEL_GIT_REPO_SLUG");
4730
+ if (!host || !owner || !slug) {
4731
+ return null;
4732
+ }
4733
+ return `${host}/${owner}/${slug}`;
4734
+ }
4735
+ function noRemote() {
4736
+ return null;
4737
+ }
4738
+ var PLATFORM_ENVS = [
4739
+ ["VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF", vercelRemote],
4740
+ [
4741
+ "GITHUB_SHA",
4742
+ "GITHUB_REF_NAME",
4743
+ remoteFrom("GITHUB_SERVER_URL", "GITHUB_REPOSITORY")
4744
+ ],
4745
+ ["RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH", noRemote],
4746
+ ["RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH", noRemote],
4747
+ ["SOURCE_VERSION", null, noRemote],
4748
+ ["CF_PAGES_COMMIT_SHA", "CF_PAGES_BRANCH", noRemote],
4749
+ ["CI_COMMIT_SHA", "CI_COMMIT_REF_NAME", remoteFrom("CI_REPOSITORY_URL")],
4750
+ [
4751
+ "BUILD_SOURCEVERSION",
4752
+ "BUILD_SOURCEBRANCHNAME",
4753
+ remoteFrom("BUILD_REPOSITORY_URI")
4754
+ ],
4755
+ ["CIRCLE_SHA1", "CIRCLE_BRANCH", remoteFrom("CIRCLE_REPOSITORY_URL")]
4756
+ ];
4757
+ var COMMIT_REF_ENV_NAMES = [
4758
+ EXPLICIT_SHA_ENV,
4759
+ DISABLE_ENV,
4760
+ ...PLATFORM_ENVS.flatMap(
4761
+ ([sha, branch]) => branch === null ? [sha] : [sha, branch]
4762
+ ),
4763
+ "GITHUB_SERVER_URL",
4764
+ "GITHUB_REPOSITORY",
4765
+ "CI_REPOSITORY_URL",
4766
+ "BUILD_REPOSITORY_URI",
4767
+ "CIRCLE_REPOSITORY_URL",
4768
+ "VERCEL_GIT_PROVIDER",
4769
+ "VERCEL_GIT_REPO_OWNER",
4770
+ "VERCEL_GIT_REPO_SLUG"
4771
+ ];
4772
+ function normalizeRemote(raw) {
4773
+ const value = raw?.trim();
4774
+ if (!value) {
4775
+ return null;
4776
+ }
4777
+ let host = "";
4778
+ let path = value;
4779
+ if (value.includes("://")) {
4780
+ try {
4781
+ const parsed = new URL(value);
4782
+ host = parsed.hostname;
4783
+ path = parsed.pathname;
4784
+ } catch {
4785
+ return null;
4786
+ }
4787
+ } else {
4788
+ const separator = value.indexOf(":");
4789
+ if (separator !== -1) {
4790
+ const head = value.slice(0, separator);
4791
+ host = head.slice(head.lastIndexOf("@") + 1);
4792
+ path = value.slice(separator + 1);
4793
+ }
4794
+ }
4795
+ path = path.replace(/^\/+|\/+$/g, "");
4796
+ if (path.endsWith(".git")) {
4797
+ path = path.slice(0, -".git".length).replace(/\/+$/, "");
4798
+ }
4799
+ if (!host) {
4800
+ return path || null;
4801
+ }
4802
+ return path ? `${host}/${path}` : host;
4803
+ }
4804
+ function resolveCommitRefFromEnv(env) {
4805
+ const explicit = read(env, EXPLICIT_SHA_ENV);
4806
+ const platform = PLATFORM_ENVS.find(([sha]) => read(env, sha) !== null);
4807
+ if (!platform) {
4808
+ if (explicit === null) {
4809
+ return null;
4810
+ }
4811
+ return {
4812
+ sha: explicit,
4813
+ branch: null,
4814
+ dirty: null,
4815
+ remote: null,
4816
+ rootSha: null
4817
+ };
4818
+ }
4819
+ const [shaEnv, branchEnv, readRemote] = platform;
4820
+ return {
4821
+ sha: explicit ?? read(env, shaEnv),
4822
+ branch: read(env, branchEnv),
4823
+ dirty: null,
4824
+ remote: readRemote(env),
4825
+ rootSha: null
4826
+ };
4827
+ }
4828
+ async function resolveCommitRefFromGit(cwd) {
4829
+ const git = await gitRunner({
4830
+ timeoutMs: GIT_TIMEOUT_MS,
4831
+ maxBuffer: GIT_MAX_BUFFER,
4832
+ keepProcessAlive: false
4833
+ });
4834
+ if (!git) {
4835
+ return null;
4836
+ }
4837
+ const run = async (args) => (await git(cwd, args))?.trim() ?? null;
4838
+ const sha = await run(["rev-parse", "HEAD"]);
4839
+ if (!sha) {
4840
+ return null;
4841
+ }
4842
+ const [branch, status, remote, roots] = await Promise.all([
4843
+ run(["symbolic-ref", "--short", "-q", "HEAD"]),
4844
+ run(["status", "--porcelain"]),
4845
+ run(["remote", "get-url", "origin"]),
4846
+ run(["rev-list", "--max-parents=0", "HEAD"])
4847
+ ]);
4848
+ return {
4849
+ sha,
4850
+ branch: branch || null,
4851
+ dirty: status === null ? null : status.length > 0,
4852
+ remote: normalizeRemote(remote),
4853
+ rootSha: roots ? roots.split(/\s+/).sort()[0] ?? null : null
4854
+ };
4855
+ }
4856
+ function commitRefWire(ref2) {
4857
+ return {
4858
+ sha: ref2.sha,
4859
+ branch: ref2.branch,
4860
+ dirty: ref2.dirty,
4861
+ remote: ref2.remote,
4862
+ root_sha: ref2.rootSha
4863
+ };
4864
+ }
4865
+ var resolved = false;
4866
+ var ref = null;
4867
+ var gitStarted = false;
4868
+ var settled = Promise.resolve();
4869
+ function startCommitRefResolution() {
4870
+ if (resolved || gitStarted) {
4871
+ return;
4872
+ }
4873
+ if (read(readEnv, DISABLE_ENV) !== null) {
4874
+ resolved = true;
4875
+ return;
4876
+ }
4877
+ const fromEnv = resolveCommitRefFromEnv(readEnv);
4878
+ if (fromEnv) {
4879
+ ref = fromEnv;
4880
+ resolved = true;
4881
+ return;
4882
+ }
4883
+ gitStarted = true;
4884
+ if (typeof process === "undefined") {
4885
+ resolved = true;
4886
+ return;
4887
+ }
4888
+ let cwd;
4889
+ try {
4890
+ cwd = process.cwd?.() ?? ".";
4891
+ } catch {
4892
+ resolved = true;
4893
+ return;
4894
+ }
4895
+ settled = resolveCommitRefFromGit(cwd).then(
4896
+ (fromGit) => {
4897
+ if (!resolved) {
4898
+ ref = fromGit;
4899
+ resolved = true;
4900
+ }
4901
+ },
4902
+ () => {
4903
+ resolved = true;
4904
+ }
4905
+ );
4906
+ }
4907
+ function currentCommitRef() {
4908
+ startCommitRefResolution();
4909
+ return ref;
4910
+ }
4911
+
4594
4912
  // src/client.ts
4595
4913
  init_constants();
4596
4914
 
@@ -5083,11 +5401,11 @@ var BitfabLangGraphCallbackHandler = class {
5083
5401
  this.invocations.set(invocation.rootRunId, invocation);
5084
5402
  }
5085
5403
  if (!willHide) {
5086
- let resolved = parentSpan;
5087
- while (resolved?.hidden === true) {
5088
- resolved = resolved.parentId ? this.runToSpan.get(resolved.parentId) : void 0;
5404
+ let resolved2 = parentSpan;
5405
+ while (resolved2?.hidden === true) {
5406
+ resolved2 = resolved2.parentId ? this.runToSpan.get(resolved2.parentId) : void 0;
5089
5407
  }
5090
- effectiveParentId = resolved ? resolved.spanId : invocation.activeContext?.spanId ?? null;
5408
+ effectiveParentId = resolved2 ? resolved2.spanId : invocation.activeContext?.spanId ?? null;
5091
5409
  } else {
5092
5410
  effectiveParentId = parentRunId ?? null;
5093
5411
  }
@@ -6587,6 +6905,7 @@ var Bitfab = class {
6587
6905
  validateDbSnapshotConfig(config.dbSnapshot);
6588
6906
  }
6589
6907
  this.dbSnapshot = config.dbSnapshot;
6908
+ startCommitRefResolution();
6590
6909
  this.httpClient = new HttpClient({
6591
6910
  apiKey: () => this.resolveApiKey(),
6592
6911
  serviceUrl: this.serviceUrl,
@@ -7680,15 +7999,15 @@ var Bitfab = class {
7680
7999
  );
7681
8000
  }
7682
8001
  return runWithSpanStack(newStack, async () => {
7683
- const resolved = await resolution;
7684
- if (resolved.matched) {
8002
+ const resolved2 = await resolution;
8003
+ if (resolved2.matched) {
7685
8004
  void sendSpan({
7686
- result: resolved.output,
8005
+ result: resolved2.output,
7687
8006
  mocked: true,
7688
8007
  mockTarget: "output",
7689
8008
  mockSource: "override"
7690
8009
  });
7691
- return resolved.output;
8010
+ return resolved2.output;
7692
8011
  }
7693
8012
  if (shouldMockWithBaseStrategy && !mockSpan) {
7694
8013
  throw new BitfabError(
@@ -7924,6 +8243,10 @@ var Bitfab = class {
7924
8243
  if (params.dbSnapshotRef) {
7925
8244
  rawTrace.db_snapshot_ref = params.dbSnapshotRef;
7926
8245
  }
8246
+ const commitRef = currentCommitRef();
8247
+ if (commitRef) {
8248
+ rawTrace.commit_ref = commitRefWire(commitRef);
8249
+ }
7927
8250
  if (params.ingestionType) {
7928
8251
  rawTrace.ingestion_type = params.ingestionType;
7929
8252
  }