@bitfab/sdk 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-LQ32JQNZ.js → chunk-BEAGKWXY.js} +241 -21
  3. package/dist/chunk-BEAGKWXY.js.map +1 -0
  4. package/dist/{chunk-OF5GWNGU.js → chunk-IHAB7SPF.js} +3 -2
  5. package/dist/{chunk-OF5GWNGU.js.map → chunk-IHAB7SPF.js.map} +1 -1
  6. package/dist/{chunk-P2AZ7RUM.js → chunk-ITIMJ24H.js} +3 -3
  7. package/dist/chunk-ITIMJ24H.js.map +1 -0
  8. package/dist/{chunk-DP3QEGTV.js → chunk-THKLMOHS.js} +110 -13
  9. package/dist/chunk-THKLMOHS.js.map +1 -0
  10. package/dist/{chunk-MM4A6UWJ.js → chunk-VAIXHJ7O.js} +2 -2
  11. package/dist/{chunk-MM4A6UWJ.js.map → chunk-VAIXHJ7O.js.map} +1 -1
  12. package/dist/{http-UA54C2J2.js → http-6Y3IQQ2Z.js} +2 -2
  13. package/dist/{http-WBNDRQIV.js → http-KZU56HZA.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-RUONYMHD.js → replay-LZ7DIY5L.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-DP3QEGTV.js.map +0 -1
  29. package/dist/chunk-LQ32JQNZ.js.map +0 -1
  30. package/dist/chunk-P2AZ7RUM.js.map +0 -1
  31. /package/dist/{http-UA54C2J2.js.map → http-6Y3IQQ2Z.js.map} +0 -0
  32. /package/dist/{http-WBNDRQIV.js.map → http-KZU56HZA.js.map} +0 -0
  33. /package/dist/{replay-RUONYMHD.js.map → replay-LZ7DIY5L.js.map} +0 -0
package/dist/node.cjs CHANGED
@@ -88,7 +88,7 @@ var __version__, __packageName__;
88
88
  var init_version_generated = __esm({
89
89
  "src/version.generated.ts"() {
90
90
  "use strict";
91
- __version__ = "0.52.4";
91
+ __version__ = "0.52.5";
92
92
  __packageName__ = "@bitfab/sdk";
93
93
  }
94
94
  });
@@ -1128,7 +1128,7 @@ var init_otel = __esm({
1128
1128
  if (this.onDelivered === void 0) {
1129
1129
  return;
1130
1130
  }
1131
- const refs = spans.map((span) => span.ref).filter((ref) => ref !== void 0);
1131
+ const refs = spans.map((span) => span.ref).filter((ref2) => ref2 !== void 0);
1132
1132
  if (refs.length === 0) {
1133
1133
  return;
1134
1134
  }
@@ -1385,9 +1385,9 @@ function parseRetryAfterMs(header) {
1385
1385
  }
1386
1386
  return Math.max(0, at - Date.now());
1387
1387
  }
1388
- function carrierMeta(operation, payload, ref) {
1388
+ function carrierMeta(operation, payload, ref2) {
1389
1389
  return {
1390
- ref,
1390
+ ref: ref2,
1391
1391
  name: carrierName(operation, payload),
1392
1392
  startTime: payloadTimestamp(payload, "started_at"),
1393
1393
  endTime: payloadTimestamp(payload, "ended_at"),
@@ -1632,22 +1632,22 @@ var init_http = __esm({
1632
1632
  return reports;
1633
1633
  }
1634
1634
  /** Build a carrier's meta and record what it adds to its trace's expected set. */
1635
- recordedMeta(operation, payload, ref) {
1636
- this.recordSubmittedCarrier(ref);
1637
- return carrierMeta(operation, payload, ref);
1635
+ recordedMeta(operation, payload, ref2) {
1636
+ this.recordSubmittedCarrier(ref2);
1637
+ return carrierMeta(operation, payload, ref2);
1638
1638
  }
1639
- recordSubmittedCarrier(ref) {
1640
- if (ref === void 0) {
1639
+ recordSubmittedCarrier(ref2) {
1640
+ if (ref2 === void 0) {
1641
1641
  return;
1642
1642
  }
1643
- const delivery = this.traceDeliveries.get(ref.traceId);
1643
+ const delivery = this.traceDeliveries.get(ref2.traceId);
1644
1644
  if (delivery === void 0) {
1645
1645
  return;
1646
1646
  }
1647
- if (ref.spanId === void 0) {
1647
+ if (ref2.spanId === void 0) {
1648
1648
  delivery.closed = true;
1649
1649
  } else {
1650
- delivery.submittedSpanIds.add(ref.spanId);
1650
+ delivery.submittedSpanIds.add(ref2.spanId);
1651
1651
  }
1652
1652
  }
1653
1653
  /**
@@ -1673,15 +1673,15 @@ var init_http = __esm({
1673
1673
  }
1674
1674
  }
1675
1675
  recordDeliveredCarriers(refs) {
1676
- for (const ref of refs) {
1677
- const delivery = this.traceDeliveries.get(ref.traceId);
1676
+ for (const ref2 of refs) {
1677
+ const delivery = this.traceDeliveries.get(ref2.traceId);
1678
1678
  if (delivery === void 0) {
1679
1679
  continue;
1680
1680
  }
1681
- if (ref.spanId === void 0) {
1681
+ if (ref2.spanId === void 0) {
1682
1682
  delivery.closingAcked = true;
1683
1683
  } else {
1684
- delivery.ackedSpanIds.add(ref.spanId);
1684
+ delivery.ackedSpanIds.add(ref2.spanId);
1685
1685
  }
1686
1686
  }
1687
1687
  }
@@ -1711,9 +1711,9 @@ var init_http = __esm({
1711
1711
  */
1712
1712
  async waitForPendingRequests(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS2) {
1713
1713
  const deadline = Date.now() + Math.max(timeoutMs, 0);
1714
- const settled = await this.settleDeferredWork(timeoutMs);
1714
+ const settled2 = await this.settleDeferredWork(timeoutMs);
1715
1715
  const flushed = await this.traceTransport?.flush(Math.max(0, deadline - Date.now())) ?? true;
1716
- return settled && flushed;
1716
+ return settled2 && flushed;
1717
1717
  }
1718
1718
  /**
1719
1719
  * Flush and permanently close this client's tracing transport. Idempotent:
@@ -1726,14 +1726,14 @@ var init_http = __esm({
1726
1726
  }
1727
1727
  const deadline = Date.now() + Math.max(timeoutMs, 0);
1728
1728
  this.closing = (async () => {
1729
- const settled = await this.settleDeferredWork(
1729
+ const settled2 = await this.settleDeferredWork(
1730
1730
  Math.max(0, deadline - Date.now())
1731
1731
  );
1732
1732
  this.closed = true;
1733
1733
  const transport = this.traceTransport;
1734
1734
  this.traceTransport = void 0;
1735
1735
  const shutdownOk = await transport?.shutdown(Math.max(0, deadline - Date.now())) ?? true;
1736
- return settled && shutdownOk;
1736
+ return settled2 && shutdownOk;
1737
1737
  })();
1738
1738
  return this.closing;
1739
1739
  }
@@ -2344,6 +2344,112 @@ var init_randomUuid = __esm({
2344
2344
  }
2345
2345
  });
2346
2346
 
2347
+ // src/gitCommand.ts
2348
+ function isUnrefable(value) {
2349
+ return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
2350
+ }
2351
+ function unrefStream(stream) {
2352
+ if (isUnrefable(stream)) {
2353
+ stream.unref();
2354
+ }
2355
+ }
2356
+ function terminate(child) {
2357
+ if (child.pid && process.platform !== "win32") {
2358
+ try {
2359
+ process.kill(-child.pid, "SIGTERM");
2360
+ return;
2361
+ } catch {
2362
+ child.kill("SIGTERM");
2363
+ return;
2364
+ }
2365
+ }
2366
+ child.kill("SIGTERM");
2367
+ }
2368
+ async function gitRunner(options) {
2369
+ let spawn;
2370
+ try {
2371
+ ;
2372
+ ({ spawn } = await import("child_process"));
2373
+ } catch {
2374
+ return null;
2375
+ }
2376
+ return (dir, args) => new Promise((resolve) => {
2377
+ let child;
2378
+ try {
2379
+ child = spawn("git", args, {
2380
+ cwd: dir,
2381
+ detached: process.platform !== "win32",
2382
+ stdio: ["ignore", "pipe", "pipe"]
2383
+ });
2384
+ } catch {
2385
+ resolve(null);
2386
+ return;
2387
+ }
2388
+ const chunks = [];
2389
+ let size = 0;
2390
+ let overflow = false;
2391
+ let exitCode = null;
2392
+ let done = false;
2393
+ const timers = [];
2394
+ const schedule = (callback, ms) => {
2395
+ const timer = setTimeout(callback, ms);
2396
+ if (!options.keepProcessAlive) {
2397
+ timer.unref();
2398
+ }
2399
+ timers.push(timer);
2400
+ };
2401
+ const finish = () => {
2402
+ if (done) {
2403
+ return;
2404
+ }
2405
+ done = true;
2406
+ for (const timer of timers) {
2407
+ clearTimeout(timer);
2408
+ }
2409
+ child.stdout?.destroy();
2410
+ child.stderr?.destroy();
2411
+ resolve(
2412
+ exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
2413
+ );
2414
+ };
2415
+ child.stdout?.on("data", (chunk) => {
2416
+ size += chunk.length;
2417
+ if (size > options.maxBuffer) {
2418
+ overflow = true;
2419
+ terminate(child);
2420
+ return;
2421
+ }
2422
+ chunks.push(chunk);
2423
+ });
2424
+ child.stderr?.resume();
2425
+ child.on("error", () => {
2426
+ exitCode = null;
2427
+ finish();
2428
+ });
2429
+ child.on("exit", (code) => {
2430
+ exitCode = code;
2431
+ schedule(finish, EXIT_GRACE_MS);
2432
+ });
2433
+ child.on("close", (code) => {
2434
+ exitCode = code ?? exitCode;
2435
+ finish();
2436
+ });
2437
+ schedule(() => terminate(child), options.timeoutMs);
2438
+ if (!options.keepProcessAlive) {
2439
+ child.unref();
2440
+ unrefStream(child.stdout);
2441
+ unrefStream(child.stderr);
2442
+ }
2443
+ });
2444
+ }
2445
+ var EXIT_GRACE_MS;
2446
+ var init_gitCommand = __esm({
2447
+ "src/gitCommand.ts"() {
2448
+ "use strict";
2449
+ EXIT_GRACE_MS = 500;
2450
+ }
2451
+ });
2452
+
2347
2453
  // src/mockOverride.ts
2348
2454
  function resolveMockValue(value, ctx) {
2349
2455
  return typeof value === "function" ? value(ctx) : value;
@@ -2400,37 +2506,33 @@ async function readCodeChangeFile() {
2400
2506
  }
2401
2507
  }
2402
2508
  async function captureCodeChangeFromGit(cwd, label) {
2403
- let execFile;
2404
2509
  let readFile;
2405
2510
  try {
2406
2511
  ;
2407
- ({ execFile } = await import("child_process"));
2408
2512
  ({ readFile } = await import("fs/promises"));
2409
2513
  } catch {
2410
2514
  return null;
2411
2515
  }
2412
- const git = (dir, args) => new Promise((resolve) => {
2413
- execFile(
2414
- "git",
2415
- args,
2416
- // 30s timeout so a hung git (e.g. a network-touching ref op) can't
2417
- // block the whole replay indefinitely.
2418
- { cwd: dir, maxBuffer: 64 * 1024 * 1024, timeout: 3e4 },
2419
- (err, stdout) => resolve(err ? null : stdout)
2420
- );
2516
+ const git = await gitRunner({
2517
+ timeoutMs: 3e4,
2518
+ maxBuffer: 64 * 1024 * 1024,
2519
+ keepProcessAlive: true
2421
2520
  });
2521
+ if (!git) {
2522
+ return null;
2523
+ }
2422
2524
  try {
2423
2525
  const root = (await git(cwd, ["rev-parse", "--show-toplevel"]))?.trim();
2424
2526
  if (!root) {
2425
2527
  return null;
2426
2528
  }
2427
- const resolved = await resolveBase(git, root);
2428
- if (!resolved) {
2529
+ const resolved2 = await resolveBase(git, root);
2530
+ if (!resolved2) {
2429
2531
  return null;
2430
2532
  }
2431
- const { base, fromTrunk } = resolved;
2432
- const blobBytes = async (ref, path) => {
2433
- const out = await git(root, ["cat-file", "-s", `${ref}:${path}`]);
2533
+ const { base, fromTrunk } = resolved2;
2534
+ const blobBytes = async (ref2, path) => {
2535
+ const out = await git(root, ["cat-file", "-s", `${ref2}:${path}`]);
2434
2536
  const n = out ? Number.parseInt(out.trim(), 10) : Number.NaN;
2435
2537
  return Number.isFinite(n) ? n : 0;
2436
2538
  };
@@ -2522,8 +2624,8 @@ async function resolveBase(git, root) {
2522
2624
  }
2523
2625
  return await refExists(git, root, "HEAD") ? { base: "HEAD", fromTrunk: false } : null;
2524
2626
  }
2525
- async function refExists(git, root, ref) {
2526
- return await git(root, ["rev-parse", "--verify", `${ref}^{object}`]) !== null;
2627
+ async function refExists(git, root, ref2) {
2628
+ return await git(root, ["rev-parse", "--verify", `${ref2}^{object}`]) !== null;
2527
2629
  }
2528
2630
  async function readWorkingFile(readFile, root, path) {
2529
2631
  try {
@@ -2558,6 +2660,7 @@ var MAX_FILES, MAX_FILE_BYTES, MAX_TOTAL_BYTES, TRUNK_CANDIDATES, NUL;
2558
2660
  var init_codeChange = __esm({
2559
2661
  "src/codeChange.ts"() {
2560
2662
  "use strict";
2663
+ init_gitCommand();
2561
2664
  MAX_FILES = 60;
2562
2665
  MAX_FILE_BYTES = 5e5;
2563
2666
  MAX_TOTAL_BYTES = 2e6;
@@ -2762,9 +2865,9 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2762
2865
  const originalSpanId = serverItem.originalSpanId ?? serverItem.sourceSpanId;
2763
2866
  try {
2764
2867
  if (includeDbBranchLease && !lease && !leaseError) {
2765
- let resolved;
2868
+ let resolved2;
2766
2869
  try {
2767
- resolved = await httpClient.resolveDbBranchLease(
2870
+ resolved2 = await httpClient.resolveDbBranchLease(
2768
2871
  testRunId,
2769
2872
  originalTraceId,
2770
2873
  dbBranchSettings,
@@ -2778,10 +2881,10 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2778
2881
  cause
2779
2882
  );
2780
2883
  }
2781
- lease = resolved.lease ?? void 0;
2782
- leaseError = resolved.leaseError ?? void 0;
2783
- dbSnapshotRef = resolved.dbSnapshotRef ?? dbSnapshotRef;
2784
- dbBranchTimings = resolved.timings ?? dbBranchTimings;
2884
+ lease = resolved2.lease ?? void 0;
2885
+ leaseError = resolved2.leaseError ?? void 0;
2886
+ dbSnapshotRef = resolved2.dbSnapshotRef ?? dbSnapshotRef;
2887
+ dbBranchTimings = resolved2.timings ?? dbBranchTimings;
2785
2888
  }
2786
2889
  if (leaseError) {
2787
2890
  throw new DbBranchReplayError(
@@ -4564,24 +4667,239 @@ function mixedTracingError(enteredApi, entered, enclosing, traceFunctionKey) {
4564
4667
  `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]}`
4565
4668
  );
4566
4669
  }
4567
- function assertSurfacesCompatible(requested, resolved, parentSurface, traceFunctionKey) {
4670
+ function assertSurfacesCompatible(requested, resolved2, parentSurface, traceFunctionKey) {
4568
4671
  if (requested === "inherit" || requested === "neutral") {
4569
4672
  return;
4570
4673
  }
4571
- if (resolved === void 0 || parentSurface === void 0) {
4674
+ if (resolved2 === void 0 || parentSurface === void 0) {
4572
4675
  return;
4573
4676
  }
4574
- if (parentSurface === resolved) {
4677
+ if (parentSurface === resolved2) {
4575
4678
  return;
4576
4679
  }
4577
4680
  throw mixedTracingError(
4578
- SURFACE_API[resolved],
4579
- resolved,
4681
+ SURFACE_API[resolved2],
4682
+ resolved2,
4580
4683
  parentSurface,
4581
4684
  traceFunctionKey
4582
4685
  );
4583
4686
  }
4584
4687
 
4688
+ // src/commitRef.ts
4689
+ init_gitCommand();
4690
+ init_readEnv();
4691
+ var EXPLICIT_SHA_ENV = "BITFAB_COMMIT_SHA";
4692
+ var DISABLE_ENV = "BITFAB_DISABLE_COMMIT_REF";
4693
+ var GIT_TIMEOUT_MS = 2e3;
4694
+ var GIT_MAX_BUFFER = 1024 * 1024;
4695
+ var VERCEL_PROVIDER_HOSTS = {
4696
+ github: "github.com",
4697
+ gitlab: "gitlab.com",
4698
+ bitbucket: "bitbucket.org"
4699
+ };
4700
+ function read(env, name) {
4701
+ if (name === null) {
4702
+ return null;
4703
+ }
4704
+ const value = env(name)?.trim();
4705
+ return value ? value : null;
4706
+ }
4707
+ function remoteFrom(...names) {
4708
+ return (env) => {
4709
+ const parts = names.map((name) => read(env, name));
4710
+ if (parts.some((part) => part === null)) {
4711
+ return null;
4712
+ }
4713
+ return normalizeRemote(parts.join("/"));
4714
+ };
4715
+ }
4716
+ function vercelRemote(env) {
4717
+ const provider = read(env, "VERCEL_GIT_PROVIDER")?.toLowerCase() ?? "";
4718
+ const host = VERCEL_PROVIDER_HOSTS[provider];
4719
+ const owner = read(env, "VERCEL_GIT_REPO_OWNER");
4720
+ const slug = read(env, "VERCEL_GIT_REPO_SLUG");
4721
+ if (!host || !owner || !slug) {
4722
+ return null;
4723
+ }
4724
+ return `${host}/${owner}/${slug}`;
4725
+ }
4726
+ function noRemote() {
4727
+ return null;
4728
+ }
4729
+ var PLATFORM_ENVS = [
4730
+ ["VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF", vercelRemote],
4731
+ [
4732
+ "GITHUB_SHA",
4733
+ "GITHUB_REF_NAME",
4734
+ remoteFrom("GITHUB_SERVER_URL", "GITHUB_REPOSITORY")
4735
+ ],
4736
+ ["RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH", noRemote],
4737
+ ["RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH", noRemote],
4738
+ ["SOURCE_VERSION", null, noRemote],
4739
+ ["CF_PAGES_COMMIT_SHA", "CF_PAGES_BRANCH", noRemote],
4740
+ ["CI_COMMIT_SHA", "CI_COMMIT_REF_NAME", remoteFrom("CI_REPOSITORY_URL")],
4741
+ [
4742
+ "BUILD_SOURCEVERSION",
4743
+ "BUILD_SOURCEBRANCHNAME",
4744
+ remoteFrom("BUILD_REPOSITORY_URI")
4745
+ ],
4746
+ ["CIRCLE_SHA1", "CIRCLE_BRANCH", remoteFrom("CIRCLE_REPOSITORY_URL")]
4747
+ ];
4748
+ var COMMIT_REF_ENV_NAMES = [
4749
+ EXPLICIT_SHA_ENV,
4750
+ DISABLE_ENV,
4751
+ ...PLATFORM_ENVS.flatMap(
4752
+ ([sha, branch]) => branch === null ? [sha] : [sha, branch]
4753
+ ),
4754
+ "GITHUB_SERVER_URL",
4755
+ "GITHUB_REPOSITORY",
4756
+ "CI_REPOSITORY_URL",
4757
+ "BUILD_REPOSITORY_URI",
4758
+ "CIRCLE_REPOSITORY_URL",
4759
+ "VERCEL_GIT_PROVIDER",
4760
+ "VERCEL_GIT_REPO_OWNER",
4761
+ "VERCEL_GIT_REPO_SLUG"
4762
+ ];
4763
+ function normalizeRemote(raw) {
4764
+ const value = raw?.trim();
4765
+ if (!value) {
4766
+ return null;
4767
+ }
4768
+ let host = "";
4769
+ let path = value;
4770
+ if (value.includes("://")) {
4771
+ try {
4772
+ const parsed = new URL(value);
4773
+ host = parsed.hostname;
4774
+ path = parsed.pathname;
4775
+ } catch {
4776
+ return null;
4777
+ }
4778
+ } else {
4779
+ const separator = value.indexOf(":");
4780
+ if (separator !== -1) {
4781
+ const head = value.slice(0, separator);
4782
+ host = head.slice(head.lastIndexOf("@") + 1);
4783
+ path = value.slice(separator + 1);
4784
+ }
4785
+ }
4786
+ path = path.replace(/^\/+|\/+$/g, "");
4787
+ if (path.endsWith(".git")) {
4788
+ path = path.slice(0, -".git".length).replace(/\/+$/, "");
4789
+ }
4790
+ if (!host) {
4791
+ return path || null;
4792
+ }
4793
+ return path ? `${host}/${path}` : host;
4794
+ }
4795
+ function resolveCommitRefFromEnv(env) {
4796
+ const explicit = read(env, EXPLICIT_SHA_ENV);
4797
+ const platform = PLATFORM_ENVS.find(([sha]) => read(env, sha) !== null);
4798
+ if (!platform) {
4799
+ if (explicit === null) {
4800
+ return null;
4801
+ }
4802
+ return {
4803
+ sha: explicit,
4804
+ branch: null,
4805
+ dirty: null,
4806
+ remote: null,
4807
+ rootSha: null
4808
+ };
4809
+ }
4810
+ const [shaEnv, branchEnv, readRemote] = platform;
4811
+ return {
4812
+ sha: explicit ?? read(env, shaEnv),
4813
+ branch: read(env, branchEnv),
4814
+ dirty: null,
4815
+ remote: readRemote(env),
4816
+ rootSha: null
4817
+ };
4818
+ }
4819
+ async function resolveCommitRefFromGit(cwd) {
4820
+ const git = await gitRunner({
4821
+ timeoutMs: GIT_TIMEOUT_MS,
4822
+ maxBuffer: GIT_MAX_BUFFER,
4823
+ keepProcessAlive: false
4824
+ });
4825
+ if (!git) {
4826
+ return null;
4827
+ }
4828
+ const run = async (args) => (await git(cwd, args))?.trim() ?? null;
4829
+ const sha = await run(["rev-parse", "HEAD"]);
4830
+ if (!sha) {
4831
+ return null;
4832
+ }
4833
+ const [branch, status, remote, roots] = await Promise.all([
4834
+ run(["symbolic-ref", "--short", "-q", "HEAD"]),
4835
+ run(["status", "--porcelain"]),
4836
+ run(["remote", "get-url", "origin"]),
4837
+ run(["rev-list", "--max-parents=0", "HEAD"])
4838
+ ]);
4839
+ return {
4840
+ sha,
4841
+ branch: branch || null,
4842
+ dirty: status === null ? null : status.length > 0,
4843
+ remote: normalizeRemote(remote),
4844
+ rootSha: roots ? roots.split(/\s+/).sort()[0] ?? null : null
4845
+ };
4846
+ }
4847
+ function commitRefWire(ref2) {
4848
+ return {
4849
+ sha: ref2.sha,
4850
+ branch: ref2.branch,
4851
+ dirty: ref2.dirty,
4852
+ remote: ref2.remote,
4853
+ root_sha: ref2.rootSha
4854
+ };
4855
+ }
4856
+ var resolved = false;
4857
+ var ref = null;
4858
+ var gitStarted = false;
4859
+ var settled = Promise.resolve();
4860
+ function startCommitRefResolution() {
4861
+ if (resolved || gitStarted) {
4862
+ return;
4863
+ }
4864
+ if (read(readEnv, DISABLE_ENV) !== null) {
4865
+ resolved = true;
4866
+ return;
4867
+ }
4868
+ const fromEnv = resolveCommitRefFromEnv(readEnv);
4869
+ if (fromEnv) {
4870
+ ref = fromEnv;
4871
+ resolved = true;
4872
+ return;
4873
+ }
4874
+ gitStarted = true;
4875
+ if (typeof process === "undefined") {
4876
+ resolved = true;
4877
+ return;
4878
+ }
4879
+ let cwd;
4880
+ try {
4881
+ cwd = process.cwd?.() ?? ".";
4882
+ } catch {
4883
+ resolved = true;
4884
+ return;
4885
+ }
4886
+ settled = resolveCommitRefFromGit(cwd).then(
4887
+ (fromGit) => {
4888
+ if (!resolved) {
4889
+ ref = fromGit;
4890
+ resolved = true;
4891
+ }
4892
+ },
4893
+ () => {
4894
+ resolved = true;
4895
+ }
4896
+ );
4897
+ }
4898
+ function currentCommitRef() {
4899
+ startCommitRefResolution();
4900
+ return ref;
4901
+ }
4902
+
4585
4903
  // src/client.ts
4586
4904
  init_constants();
4587
4905
 
@@ -5074,11 +5392,11 @@ var BitfabLangGraphCallbackHandler = class {
5074
5392
  this.invocations.set(invocation.rootRunId, invocation);
5075
5393
  }
5076
5394
  if (!willHide) {
5077
- let resolved = parentSpan;
5078
- while (resolved?.hidden === true) {
5079
- resolved = resolved.parentId ? this.runToSpan.get(resolved.parentId) : void 0;
5395
+ let resolved2 = parentSpan;
5396
+ while (resolved2?.hidden === true) {
5397
+ resolved2 = resolved2.parentId ? this.runToSpan.get(resolved2.parentId) : void 0;
5080
5398
  }
5081
- effectiveParentId = resolved ? resolved.spanId : invocation.activeContext?.spanId ?? null;
5399
+ effectiveParentId = resolved2 ? resolved2.spanId : invocation.activeContext?.spanId ?? null;
5082
5400
  } else {
5083
5401
  effectiveParentId = parentRunId ?? null;
5084
5402
  }
@@ -6578,6 +6896,7 @@ var Bitfab = class {
6578
6896
  validateDbSnapshotConfig(config.dbSnapshot);
6579
6897
  }
6580
6898
  this.dbSnapshot = config.dbSnapshot;
6899
+ startCommitRefResolution();
6581
6900
  this.httpClient = new HttpClient({
6582
6901
  apiKey: () => this.resolveApiKey(),
6583
6902
  serviceUrl: this.serviceUrl,
@@ -7671,15 +7990,15 @@ var Bitfab = class {
7671
7990
  );
7672
7991
  }
7673
7992
  return runWithSpanStack(newStack, async () => {
7674
- const resolved = await resolution;
7675
- if (resolved.matched) {
7993
+ const resolved2 = await resolution;
7994
+ if (resolved2.matched) {
7676
7995
  void sendSpan({
7677
- result: resolved.output,
7996
+ result: resolved2.output,
7678
7997
  mocked: true,
7679
7998
  mockTarget: "output",
7680
7999
  mockSource: "override"
7681
8000
  });
7682
- return resolved.output;
8001
+ return resolved2.output;
7683
8002
  }
7684
8003
  if (shouldMockWithBaseStrategy && !mockSpan) {
7685
8004
  throw new BitfabError(
@@ -7915,6 +8234,10 @@ var Bitfab = class {
7915
8234
  if (params.dbSnapshotRef) {
7916
8235
  rawTrace.db_snapshot_ref = params.dbSnapshotRef;
7917
8236
  }
8237
+ const commitRef = currentCommitRef();
8238
+ if (commitRef) {
8239
+ rawTrace.commit_ref = commitRefWire(commitRef);
8240
+ }
7918
8241
  if (params.ingestionType) {
7919
8242
  rawTrace.ingestion_type = params.ingestionType;
7920
8243
  }