bitfab 0.54.0 → 0.54.2

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.cjs CHANGED
@@ -51,7 +51,7 @@ var __version__, __packageName__;
51
51
  var init_version_generated = __esm({
52
52
  "src/version.generated.ts"() {
53
53
  "use strict";
54
- __version__ = "0.54.0";
54
+ __version__ = "0.54.2";
55
55
  __packageName__ = "bitfab";
56
56
  }
57
57
  });
@@ -195,6 +195,206 @@ var init_errors = __esm({
195
195
  }
196
196
  });
197
197
 
198
+ // src/gitCommand.ts
199
+ function isUnrefable(value) {
200
+ return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
201
+ }
202
+ function unrefStream(stream) {
203
+ if (isUnrefable(stream)) {
204
+ stream.unref();
205
+ }
206
+ }
207
+ function terminate(child) {
208
+ if (child.pid && process.platform !== "win32") {
209
+ try {
210
+ process.kill(-child.pid, "SIGTERM");
211
+ return;
212
+ } catch {
213
+ child.kill("SIGTERM");
214
+ return;
215
+ }
216
+ }
217
+ child.kill("SIGTERM");
218
+ }
219
+ async function gitRunner(options) {
220
+ let spawn;
221
+ try {
222
+ ;
223
+ ({ spawn } = await import("child_process"));
224
+ } catch {
225
+ return null;
226
+ }
227
+ return (dir, args, env) => new Promise((resolve) => {
228
+ let child;
229
+ try {
230
+ child = spawn("git", args, {
231
+ cwd: dir,
232
+ detached: process.platform !== "win32",
233
+ stdio: ["ignore", "pipe", "pipe"],
234
+ ...env ? { env: { ...process.env, ...env } } : {}
235
+ });
236
+ } catch {
237
+ resolve(null);
238
+ return;
239
+ }
240
+ const chunks = [];
241
+ let size = 0;
242
+ let overflow = false;
243
+ let exitCode = null;
244
+ let done = false;
245
+ const timers = [];
246
+ const schedule = (callback, ms) => {
247
+ const timer = setTimeout(callback, ms);
248
+ if (!options.keepProcessAlive) {
249
+ timer.unref();
250
+ }
251
+ timers.push(timer);
252
+ };
253
+ const finish = () => {
254
+ if (done) {
255
+ return;
256
+ }
257
+ done = true;
258
+ for (const timer of timers) {
259
+ clearTimeout(timer);
260
+ }
261
+ child.stdout?.destroy();
262
+ child.stderr?.destroy();
263
+ resolve(
264
+ exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
265
+ );
266
+ };
267
+ child.stdout?.on("data", (chunk) => {
268
+ size += chunk.length;
269
+ if (size > options.maxBuffer) {
270
+ overflow = true;
271
+ terminate(child);
272
+ return;
273
+ }
274
+ chunks.push(chunk);
275
+ });
276
+ child.stderr?.resume();
277
+ child.on("error", () => {
278
+ exitCode = null;
279
+ finish();
280
+ });
281
+ child.on("exit", (code) => {
282
+ exitCode = code;
283
+ schedule(finish, EXIT_GRACE_MS);
284
+ });
285
+ child.on("close", (code) => {
286
+ exitCode = code ?? exitCode;
287
+ finish();
288
+ });
289
+ schedule(() => terminate(child), options.timeoutMs);
290
+ if (!options.keepProcessAlive) {
291
+ child.unref();
292
+ unrefStream(child.stdout);
293
+ unrefStream(child.stderr);
294
+ }
295
+ });
296
+ }
297
+ var EXIT_GRACE_MS;
298
+ var init_gitCommand = __esm({
299
+ "src/gitCommand.ts"() {
300
+ "use strict";
301
+ EXIT_GRACE_MS = 500;
302
+ }
303
+ });
304
+
305
+ // src/gitState.ts
306
+ function sha(value) {
307
+ const trimmed = value?.trim();
308
+ return trimmed && SHA_PATTERN.test(trimmed) ? trimmed : null;
309
+ }
310
+ function text(value) {
311
+ const trimmed = value?.trim();
312
+ return trimmed ? trimmed : null;
313
+ }
314
+ function isEmptyGitState(state) {
315
+ return Object.values(state).every((value) => value === null);
316
+ }
317
+ async function resolveGitState(cwd) {
318
+ const git = await gitRunner({
319
+ timeoutMs: GIT_TIMEOUT_MS,
320
+ maxBuffer: GIT_MAX_BUFFER,
321
+ keepProcessAlive: true
322
+ });
323
+ if (!git) {
324
+ return null;
325
+ }
326
+ const run = async (args, env) => (await git(cwd, args, env))?.trim() ?? null;
327
+ const [refs, email, branch] = await Promise.all([
328
+ run(["rev-parse", "--show-toplevel", "HEAD", "HEAD^{tree}"]),
329
+ run(["config", "user.email"]),
330
+ run(["symbolic-ref", "--short", "-q", "HEAD"])
331
+ ]);
332
+ const [root, commitSha, baseSha] = (refs ?? "").split("\n");
333
+ if (!root) {
334
+ return null;
335
+ }
336
+ const state = {
337
+ githubEmail: text(email),
338
+ branch: text(branch),
339
+ commitSha: sha(commitSha),
340
+ baseSha: sha(baseSha),
341
+ experimentSha: await resolveWorkingTreeSha(run, root.trim())
342
+ };
343
+ return isEmptyGitState(state) ? null : state;
344
+ }
345
+ async function resolveWorkingTreeSha(run, root) {
346
+ let indexPath;
347
+ let cleanup;
348
+ try {
349
+ const { mkdtemp, rm } = await import("fs/promises");
350
+ const { join } = await import("path");
351
+ const { tmpdir } = await import("os");
352
+ const dir = await mkdtemp(join(tmpdir(), "bitfab-git-"));
353
+ indexPath = join(dir, "index");
354
+ cleanup = () => rm(dir, { recursive: true, force: true });
355
+ } catch {
356
+ return null;
357
+ }
358
+ try {
359
+ const env = { GIT_INDEX_FILE: indexPath };
360
+ if (await run(["read-tree", "HEAD"], env) === null) {
361
+ return null;
362
+ }
363
+ if (await run(["add", "-A", "--", root], env) === null) {
364
+ return null;
365
+ }
366
+ return sha(await run(["write-tree"], env));
367
+ } catch {
368
+ return null;
369
+ } finally {
370
+ await cleanup().catch(() => {
371
+ });
372
+ }
373
+ }
374
+ function resolvedGitState() {
375
+ if (typeof process === "undefined" || process.env?.[DISABLE_ENV]) {
376
+ return Promise.resolve(null);
377
+ }
378
+ let cwd;
379
+ try {
380
+ cwd = process.cwd?.() ?? ".";
381
+ } catch {
382
+ return Promise.resolve(null);
383
+ }
384
+ return resolveGitState(cwd).catch(() => null);
385
+ }
386
+ var GIT_TIMEOUT_MS, GIT_MAX_BUFFER, DISABLE_ENV, SHA_PATTERN;
387
+ var init_gitState = __esm({
388
+ "src/gitState.ts"() {
389
+ "use strict";
390
+ init_gitCommand();
391
+ GIT_TIMEOUT_MS = 3e4;
392
+ GIT_MAX_BUFFER = 1024 * 1024;
393
+ DISABLE_ENV = "BITFAB_DISABLE_GIT_STATE";
394
+ SHA_PATTERN = /^[0-9a-f]{40}$/;
395
+ }
396
+ });
397
+
198
398
  // src/asyncStorage.ts
199
399
  function registerAsyncLocalStorageClass(cls) {
200
400
  if (!AsyncLocalStorageClass) {
@@ -1955,6 +2155,7 @@ var init_http = __esm({
1955
2155
  init_compress();
1956
2156
  init_constants();
1957
2157
  init_errors();
2158
+ init_gitState();
1958
2159
  init_replayContext();
1959
2160
  init_serializePayload();
1960
2161
  init_simulationPlan();
@@ -2566,6 +2767,10 @@ var init_http = __esm({
2566
2767
  if (onlyWithAssertions) {
2567
2768
  payload.onlyWithAssertions = true;
2568
2769
  }
2770
+ const git = await resolvedGitState();
2771
+ if (git && !isEmptyGitState(git)) {
2772
+ payload.git = git;
2773
+ }
2569
2774
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
2570
2775
  return this.request("/api/sdk/replay/start", payload, {
2571
2776
  timeout
@@ -2913,112 +3118,6 @@ var init_randomUuid = __esm({
2913
3118
  }
2914
3119
  });
2915
3120
 
2916
- // src/gitCommand.ts
2917
- function isUnrefable(value) {
2918
- return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
2919
- }
2920
- function unrefStream(stream) {
2921
- if (isUnrefable(stream)) {
2922
- stream.unref();
2923
- }
2924
- }
2925
- function terminate(child) {
2926
- if (child.pid && process.platform !== "win32") {
2927
- try {
2928
- process.kill(-child.pid, "SIGTERM");
2929
- return;
2930
- } catch {
2931
- child.kill("SIGTERM");
2932
- return;
2933
- }
2934
- }
2935
- child.kill("SIGTERM");
2936
- }
2937
- async function gitRunner(options) {
2938
- let spawn;
2939
- try {
2940
- ;
2941
- ({ spawn } = await import("child_process"));
2942
- } catch {
2943
- return null;
2944
- }
2945
- return (dir, args) => new Promise((resolve) => {
2946
- let child;
2947
- try {
2948
- child = spawn("git", args, {
2949
- cwd: dir,
2950
- detached: process.platform !== "win32",
2951
- stdio: ["ignore", "pipe", "pipe"]
2952
- });
2953
- } catch {
2954
- resolve(null);
2955
- return;
2956
- }
2957
- const chunks = [];
2958
- let size = 0;
2959
- let overflow = false;
2960
- let exitCode = null;
2961
- let done = false;
2962
- const timers = [];
2963
- const schedule = (callback, ms) => {
2964
- const timer = setTimeout(callback, ms);
2965
- if (!options.keepProcessAlive) {
2966
- timer.unref();
2967
- }
2968
- timers.push(timer);
2969
- };
2970
- const finish = () => {
2971
- if (done) {
2972
- return;
2973
- }
2974
- done = true;
2975
- for (const timer of timers) {
2976
- clearTimeout(timer);
2977
- }
2978
- child.stdout?.destroy();
2979
- child.stderr?.destroy();
2980
- resolve(
2981
- exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null
2982
- );
2983
- };
2984
- child.stdout?.on("data", (chunk) => {
2985
- size += chunk.length;
2986
- if (size > options.maxBuffer) {
2987
- overflow = true;
2988
- terminate(child);
2989
- return;
2990
- }
2991
- chunks.push(chunk);
2992
- });
2993
- child.stderr?.resume();
2994
- child.on("error", () => {
2995
- exitCode = null;
2996
- finish();
2997
- });
2998
- child.on("exit", (code) => {
2999
- exitCode = code;
3000
- schedule(finish, EXIT_GRACE_MS);
3001
- });
3002
- child.on("close", (code) => {
3003
- exitCode = code ?? exitCode;
3004
- finish();
3005
- });
3006
- schedule(() => terminate(child), options.timeoutMs);
3007
- if (!options.keepProcessAlive) {
3008
- child.unref();
3009
- unrefStream(child.stdout);
3010
- unrefStream(child.stderr);
3011
- }
3012
- });
3013
- }
3014
- var EXIT_GRACE_MS;
3015
- var init_gitCommand = __esm({
3016
- "src/gitCommand.ts"() {
3017
- "use strict";
3018
- EXIT_GRACE_MS = 500;
3019
- }
3020
- });
3021
-
3022
3121
  // src/mockOverride.ts
3023
3122
  function resolveMockValue(value, ctx) {
3024
3123
  return typeof value === "function" ? value(ctx) : value;
@@ -5320,9 +5419,9 @@ function assertSurfacesCompatible(requested, resolved2, parentSurface, traceFunc
5320
5419
  init_gitCommand();
5321
5420
  init_readEnv();
5322
5421
  var EXPLICIT_SHA_ENV = "BITFAB_COMMIT_SHA";
5323
- var DISABLE_ENV = "BITFAB_DISABLE_COMMIT_REF";
5324
- var GIT_TIMEOUT_MS = 2e3;
5325
- var GIT_MAX_BUFFER = 1024 * 1024;
5422
+ var DISABLE_ENV2 = "BITFAB_DISABLE_COMMIT_REF";
5423
+ var GIT_TIMEOUT_MS2 = 2e3;
5424
+ var GIT_MAX_BUFFER2 = 1024 * 1024;
5326
5425
  var VERCEL_PROVIDER_HOSTS = {
5327
5426
  github: "github.com",
5328
5427
  gitlab: "gitlab.com",
@@ -5378,9 +5477,9 @@ var PLATFORM_ENVS = [
5378
5477
  ];
5379
5478
  var COMMIT_REF_ENV_NAMES = [
5380
5479
  EXPLICIT_SHA_ENV,
5381
- DISABLE_ENV,
5480
+ DISABLE_ENV2,
5382
5481
  ...PLATFORM_ENVS.flatMap(
5383
- ([sha, branch]) => branch === null ? [sha] : [sha, branch]
5482
+ ([sha2, branch]) => branch === null ? [sha2] : [sha2, branch]
5384
5483
  ),
5385
5484
  "GITHUB_SERVER_URL",
5386
5485
  "GITHUB_REPOSITORY",
@@ -5425,7 +5524,7 @@ function normalizeRemote(raw) {
5425
5524
  }
5426
5525
  function resolveCommitRefFromEnv(env) {
5427
5526
  const explicit = read(env, EXPLICIT_SHA_ENV);
5428
- const platform = PLATFORM_ENVS.find(([sha]) => read(env, sha) !== null);
5527
+ const platform = PLATFORM_ENVS.find(([sha2]) => read(env, sha2) !== null);
5429
5528
  if (!platform) {
5430
5529
  if (explicit === null) {
5431
5530
  return null;
@@ -5449,16 +5548,16 @@ function resolveCommitRefFromEnv(env) {
5449
5548
  }
5450
5549
  async function resolveCommitRefFromGit(cwd) {
5451
5550
  const git = await gitRunner({
5452
- timeoutMs: GIT_TIMEOUT_MS,
5453
- maxBuffer: GIT_MAX_BUFFER,
5551
+ timeoutMs: GIT_TIMEOUT_MS2,
5552
+ maxBuffer: GIT_MAX_BUFFER2,
5454
5553
  keepProcessAlive: false
5455
5554
  });
5456
5555
  if (!git) {
5457
5556
  return null;
5458
5557
  }
5459
5558
  const run = async (args) => (await git(cwd, args))?.trim() ?? null;
5460
- const sha = await run(["rev-parse", "HEAD"]);
5461
- if (!sha) {
5559
+ const sha2 = await run(["rev-parse", "HEAD"]);
5560
+ if (!sha2) {
5462
5561
  return null;
5463
5562
  }
5464
5563
  const [branch, status, remote, roots] = await Promise.all([
@@ -5468,7 +5567,7 @@ async function resolveCommitRefFromGit(cwd) {
5468
5567
  run(["rev-list", "--max-parents=0", "HEAD"])
5469
5568
  ]);
5470
5569
  return {
5471
- sha,
5570
+ sha: sha2,
5472
5571
  branch: branch || null,
5473
5572
  dirty: status === null ? null : status.length > 0,
5474
5573
  remote: normalizeRemote(remote),
@@ -5492,7 +5591,7 @@ function startCommitRefResolution() {
5492
5591
  if (resolved || gitStarted) {
5493
5592
  return;
5494
5593
  }
5495
- if (read(readEnv, DISABLE_ENV) !== null) {
5594
+ if (read(readEnv, DISABLE_ENV2) !== null) {
5496
5595
  resolved = true;
5497
5596
  return;
5498
5597
  }
@@ -7073,14 +7172,14 @@ function modelLabel(model) {
7073
7172
  }
7074
7173
  function summarizeGenerate(result, model) {
7075
7174
  const content = Array.isArray(result.content) ? result.content : [];
7076
- const text = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
7175
+ const text2 = typeof result.text === "string" ? result.text : content.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
7077
7176
  const toolCalls = content.filter((p) => p.type === "tool-call").map((p) => ({
7078
7177
  toolCallId: p.toolCallId,
7079
7178
  toolName: p.toolName,
7080
7179
  input: p.input ?? p.args
7081
7180
  }));
7082
7181
  const summary = {
7083
- text,
7182
+ text: text2,
7084
7183
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
7085
7184
  usage: result.usage,
7086
7185
  finishReason: result.finishReason
@@ -7092,7 +7191,7 @@ function summarizeGenerate(result, model) {
7092
7191
  }
7093
7192
  function accumulateStream(source, onComplete, model) {
7094
7193
  const reader = source.getReader();
7095
- let text = "";
7194
+ let text2 = "";
7096
7195
  const toolCalls = [];
7097
7196
  let usage;
7098
7197
  let finishReason;
@@ -7114,7 +7213,7 @@ function accumulateStream(source, onComplete, model) {
7114
7213
  }
7115
7214
  }
7116
7215
  onComplete({
7117
- text,
7216
+ text: text2,
7118
7217
  toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
7119
7218
  usage,
7120
7219
  finishReason,
@@ -7159,7 +7258,7 @@ function accumulateStream(source, onComplete, model) {
7159
7258
  }
7160
7259
  try {
7161
7260
  if (part?.type === "text-delta") {
7162
- text += part.delta ?? part.textDelta ?? "";
7261
+ text2 += part.delta ?? part.textDelta ?? "";
7163
7262
  } else if (part?.type === "tool-call") {
7164
7263
  toolCalls.push({
7165
7264
  toolCallId: part.toolCallId,
@@ -9648,7 +9747,7 @@ async function settle(value) {
9648
9747
  }
9649
9748
  async function aiSdk(result) {
9650
9749
  const r = result ?? {};
9651
- const [text, usage, totalUsage, finishReason, toolCalls, toolResults] = await Promise.all([
9750
+ const [text2, usage, totalUsage, finishReason, toolCalls, toolResults] = await Promise.all([
9652
9751
  settle(r.text),
9653
9752
  settle(r.usage),
9654
9753
  settle(r.totalUsage),
@@ -9657,7 +9756,7 @@ async function aiSdk(result) {
9657
9756
  settle(r.toolResults)
9658
9757
  ]);
9659
9758
  return {
9660
- text,
9759
+ text: text2,
9661
9760
  usage: totalUsage ?? usage,
9662
9761
  finishReason,
9663
9762
  toolCalls,