tensorlake 0.5.126 → 0.5.127

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.js CHANGED
@@ -46,7 +46,7 @@ var init_defaults = __esm({
46
46
  "src/defaults.ts"() {
47
47
  "use strict";
48
48
  init_esm_shims();
49
- SDK_VERSION = "0.5.126";
49
+ SDK_VERSION = "0.5.127";
50
50
  API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
51
51
  API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
52
52
  NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
@@ -315,10 +315,10 @@ var init_native_worker_client = __esm({
315
315
  call(handle, method, args, emit) {
316
316
  const id = this.nextId++;
317
317
  let worker;
318
- const promise = new Promise((resolve, reject) => {
318
+ const promise = new Promise((resolve2, reject) => {
319
319
  try {
320
320
  worker = this.getWorker();
321
- this.pending.set(id, { resolve, reject, emit, handle });
321
+ this.pending.set(id, { resolve: resolve2, reject, emit, handle });
322
322
  worker.ref();
323
323
  if (handle) this.register(handle, worker);
324
324
  this.send(worker, {
@@ -421,7 +421,7 @@ var init_native_worker_client = __esm({
421
421
  }
422
422
  };
423
423
  runtimeKey = /* @__PURE__ */ Symbol.for(
424
- `tensorlake.native.worker.${false ? "source" : "0.5.126"}.v1`
424
+ `tensorlake.native.worker.${false ? "source" : "0.5.127"}.v1`
425
425
  );
426
426
  runtimes = globalThis;
427
427
  }
@@ -489,9 +489,9 @@ async function* nativeEventStream(start, context, signal) {
489
489
  let stopped = false;
490
490
  let failure;
491
491
  const notify = () => {
492
- const resolve = wake;
492
+ const resolve2 = wake;
493
493
  wake = void 0;
494
- resolve?.();
494
+ resolve2?.();
495
495
  };
496
496
  const emit = (value) => {
497
497
  if (stopped) return Promise.resolve();
@@ -526,8 +526,8 @@ async function* nativeEventStream(start, context, signal) {
526
526
  } else if (finished) {
527
527
  break;
528
528
  } else {
529
- await new Promise((resolve) => {
530
- wake = resolve;
529
+ await new Promise((resolve2) => {
530
+ wake = resolve2;
531
531
  });
532
532
  }
533
533
  }
@@ -683,7 +683,7 @@ import WebSocket from "ws";
683
683
  async function openTunnelWebSocket(options) {
684
684
  const wsUrl = buildTunnelWsUrl(options.baseUrl, options.remotePort);
685
685
  const timeoutMs = options.connectTimeoutMs ?? DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS;
686
- return new Promise((resolve, reject) => {
686
+ return new Promise((resolve2, reject) => {
687
687
  const socket = new WebSocket(wsUrl, {
688
688
  headers: options.wsHeaders
689
689
  });
@@ -714,7 +714,7 @@ async function openTunnelWebSocket(options) {
714
714
  });
715
715
  };
716
716
  const onOpen = () => {
717
- settle(() => resolve(socket));
717
+ settle(() => resolve2(socket));
718
718
  };
719
719
  const onError = (error) => {
720
720
  fail(new SandboxConnectionError(error.message));
@@ -757,7 +757,7 @@ function normalizeWebSocketData(message) {
757
757
  return Buffer.from(message);
758
758
  }
759
759
  async function relaySocket(localSocket, websocket) {
760
- return new Promise((resolve) => {
760
+ return new Promise((resolve2) => {
761
761
  let settled = false;
762
762
  const keepAliveInterval = setInterval(() => {
763
763
  if (websocket.readyState === WebSocket.OPEN) {
@@ -770,7 +770,7 @@ async function relaySocket(localSocket, websocket) {
770
770
  settled = true;
771
771
  clearInterval(keepAliveInterval);
772
772
  cleanup();
773
- resolve();
773
+ resolve2();
774
774
  };
775
775
  const cleanup = () => {
776
776
  localSocket.removeListener("data", onLocalData);
@@ -848,7 +848,7 @@ async function relaySocket(localSocket, websocket) {
848
848
  });
849
849
  }
850
850
  async function listenServer(server, localPort, localHost) {
851
- await new Promise((resolve, reject) => {
851
+ await new Promise((resolve2, reject) => {
852
852
  const onError = (error) => {
853
853
  server.removeListener("listening", onListening);
854
854
  reject(
@@ -859,7 +859,7 @@ async function listenServer(server, localPort, localHost) {
859
859
  };
860
860
  const onListening = () => {
861
861
  server.removeListener("error", onError);
862
- resolve();
862
+ resolve2();
863
863
  };
864
864
  server.once("error", onError);
865
865
  server.once("listening", onListening);
@@ -885,13 +885,13 @@ function secondsToMillis(seconds) {
885
885
  return Math.round(seconds * 1e3);
886
886
  }
887
887
  async function withTimeout(timeoutMs, operation, timeoutMessage) {
888
- return new Promise((resolve, reject) => {
888
+ return new Promise((resolve2, reject) => {
889
889
  const timer = setTimeout(() => {
890
890
  reject(new SandboxError(timeoutMessage));
891
891
  }, timeoutMs);
892
892
  void operation().then((value) => {
893
893
  clearTimeout(timer);
894
- resolve(value);
894
+ resolve2(value);
895
895
  }).catch((error) => {
896
896
  clearTimeout(timer);
897
897
  reject(error);
@@ -965,8 +965,8 @@ var init_tunnel = __esm({
965
965
  if (this.closeError) {
966
966
  throw this.closeError;
967
967
  }
968
- return new Promise((resolve, reject) => {
969
- this.pendingReads.push({ length, resolve, reject });
968
+ return new Promise((resolve2, reject) => {
969
+ this.pendingReads.push({ length, resolve: resolve2, reject });
970
970
  });
971
971
  }
972
972
  async writeAll(data) {
@@ -977,13 +977,13 @@ var init_tunnel = __esm({
977
977
  throw new SandboxError("desktop tunnel is not connected");
978
978
  }
979
979
  const payload = Buffer.from(data);
980
- await new Promise((resolve, reject) => {
980
+ await new Promise((resolve2, reject) => {
981
981
  this.socket.send(payload, { binary: true }, (error) => {
982
982
  if (error) {
983
983
  reject(new SandboxConnectionError(error.message));
984
984
  return;
985
985
  }
986
- resolve();
986
+ resolve2();
987
987
  });
988
988
  });
989
989
  }
@@ -995,10 +995,10 @@ var init_tunnel = __esm({
995
995
  this.closePromise = Promise.resolve();
996
996
  return this.closePromise;
997
997
  }
998
- this.closePromise = new Promise((resolve) => {
998
+ this.closePromise = new Promise((resolve2) => {
999
999
  const onClose = () => {
1000
1000
  this.socket.removeListener("close", onClose);
1001
- resolve();
1001
+ resolve2();
1002
1002
  };
1003
1003
  this.socket.on("close", onClose);
1004
1004
  this.socket.close();
@@ -1092,13 +1092,13 @@ var init_tunnel = __esm({
1092
1092
  relay.localSocket.destroy();
1093
1093
  relay.websocket?.close();
1094
1094
  }
1095
- this.closePromise = new Promise((resolve, reject) => {
1095
+ this.closePromise = new Promise((resolve2, reject) => {
1096
1096
  this.server.close((error) => {
1097
1097
  if (error) {
1098
1098
  reject(new SandboxError(`failed to close tunnel listener: ${error.message}`));
1099
1099
  return;
1100
1100
  }
1101
- resolve();
1101
+ resolve2();
1102
1102
  });
1103
1103
  });
1104
1104
  return this.closePromise;
@@ -1327,14 +1327,14 @@ function isReconnectableDesktopScreenshotError(error) {
1327
1327
  }
1328
1328
  function createDeferredSignal() {
1329
1329
  let resolveCurrent;
1330
- let promise = new Promise((resolve) => {
1331
- resolveCurrent = resolve;
1330
+ let promise = new Promise((resolve2) => {
1331
+ resolveCurrent = resolve2;
1332
1332
  });
1333
1333
  return {
1334
1334
  resolve() {
1335
1335
  resolveCurrent();
1336
- promise = new Promise((resolve) => {
1337
- resolveCurrent = resolve;
1336
+ promise = new Promise((resolve2) => {
1337
+ resolveCurrent = resolve2;
1338
1338
  });
1339
1339
  },
1340
1340
  wait() {
@@ -1678,7 +1678,7 @@ var init_desktop = __esm({
1678
1678
  validateNonNegativeInteger(delayMs, "double click delay");
1679
1679
  await this.click({ button, x: options?.x, y: options?.y });
1680
1680
  if (delayMs > 0) {
1681
- await new Promise((resolve) => setTimeout(resolve, delayMs));
1681
+ await new Promise((resolve2) => setTimeout(resolve2, delayMs));
1682
1682
  }
1683
1683
  await this.click({ button });
1684
1684
  }
@@ -3144,7 +3144,7 @@ function processUserPayload(user) {
3144
3144
  return user;
3145
3145
  }
3146
3146
  function sleep(ms) {
3147
- return new Promise((resolve) => setTimeout(resolve, ms));
3147
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
3148
3148
  }
3149
3149
  function normalizePtyMessage(message) {
3150
3150
  if (Buffer.isBuffer(message)) return message;
@@ -3165,8 +3165,8 @@ function encodePtyResize(cols, rows) {
3165
3165
  return frame;
3166
3166
  }
3167
3167
  function sendPtyFrame(socket, frame) {
3168
- return new Promise((resolve, reject) => {
3169
- socket.send(frame, (error) => error ? reject(error) : resolve());
3168
+ return new Promise((resolve2, reject) => {
3169
+ socket.send(frame, (error) => error ? reject(error) : resolve2());
3170
3170
  });
3171
3171
  }
3172
3172
  function markBindOutcome(sandbox, outcome) {
@@ -3407,8 +3407,8 @@ var init_sandbox = __esm({
3407
3407
  this.wsUrl = options.wsUrl;
3408
3408
  this.wsHeaders = options.wsHeaders;
3409
3409
  this.killSession = options.killSession;
3410
- this.waitPromise = new Promise((resolve, reject) => {
3411
- this.resolveWait = resolve;
3410
+ this.waitPromise = new Promise((resolve2, reject) => {
3411
+ this.resolveWait = resolve2;
3412
3412
  this.rejectWait = reject;
3413
3413
  });
3414
3414
  }
@@ -3431,7 +3431,7 @@ var init_sandbox = __esm({
3431
3431
  return this.connectPromise;
3432
3432
  }
3433
3433
  this.intentionalDisconnect = false;
3434
- this.connectPromise = new Promise((resolve, reject) => {
3434
+ this.connectPromise = new Promise((resolve2, reject) => {
3435
3435
  let opened = false;
3436
3436
  const socket = new WebSocket2(this.wsUrl, {
3437
3437
  headers: this.wsHeaders
@@ -3441,7 +3441,7 @@ var init_sandbox = __esm({
3441
3441
  try {
3442
3442
  await sendPtyFrame(socket, Buffer.from([PTY_OP_READY]));
3443
3443
  opened = true;
3444
- resolve(this);
3444
+ resolve2(this);
3445
3445
  } catch (error) {
3446
3446
  reject(error);
3447
3447
  }
@@ -4372,7 +4372,7 @@ var init_sandbox = __esm({
4372
4372
  const remainingMs = deadlineMs - Date.now();
4373
4373
  if (remainingMs <= 0) break;
4374
4374
  await new Promise(
4375
- (resolve) => setTimeout(resolve, Math.min(probeIntervalMs, remainingMs))
4375
+ (resolve2) => setTimeout(resolve2, Math.min(probeIntervalMs, remainingMs))
4376
4376
  );
4377
4377
  }
4378
4378
  const detail = lastError instanceof Error ? `: ${lastError.message}` : "";
@@ -4479,7 +4479,7 @@ function validateTimeoutMs(timeoutMs) {
4479
4479
  }
4480
4480
  }
4481
4481
  function sleep2(ms) {
4482
- return new Promise((resolve) => setTimeout(resolve, ms));
4482
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
4483
4483
  }
4484
4484
  function snapshotStatusSatisfiesWaitCondition(status, waitUntil) {
4485
4485
  if (waitUntil === "local_ready") {
@@ -5328,7 +5328,7 @@ function anySignal(signals) {
5328
5328
  return controller.signal;
5329
5329
  }
5330
5330
  function sleep3(ms) {
5331
- return new Promise((resolve) => setTimeout(resolve, ms));
5331
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
5332
5332
  }
5333
5333
  var REQUEST_TIMEOUT_HEADER, HttpClient;
5334
5334
  var init_http = __esm({
@@ -6908,9 +6908,11 @@ init_cloud_client();
6908
6908
 
6909
6909
  // src/filesystem.ts
6910
6910
  init_esm_shims();
6911
- init_defaults();
6912
- import { execFile } from "child_process";
6913
6911
  import { randomBytes } from "crypto";
6912
+
6913
+ // src/mount-cli.ts
6914
+ init_esm_shims();
6915
+ import { execFile } from "child_process";
6914
6916
  import { accessSync, constants } from "fs";
6915
6917
  import { homedir } from "os";
6916
6918
  import { join } from "path";
@@ -6994,60 +6996,25 @@ var ReadOnlyMountNotSupportedError = class extends MountError {
6994
6996
  }
6995
6997
  };
6996
6998
  var CliNotFoundError = class extends MountError {
6997
- constructor(detail) {
6999
+ constructor(detail, command = "fs") {
6998
7000
  super(
6999
- `Mount operations require the Tensorlake CLI (\`tl\`) with \`tl fs\` support: ${detail}. Install or upgrade it with: curl -fsSL https://tensorlake.ai/install.sh | sh`
7001
+ `Mount operations require the Tensorlake CLI (\`tl\`) with \`tl ${command}\` support: ${detail}. Install or upgrade it with: curl -fsSL https://tensorlake.ai/install.sh | sh`
7000
7002
  );
7001
7003
  this.name = "CliNotFoundError";
7002
7004
  }
7003
7005
  };
7004
7006
 
7005
- // src/filesystem.ts
7006
- init_native_sandbox();
7007
- init_sandbox_image();
7007
+ // src/mount-cli.ts
7008
7008
  var execFileAsync = promisify(execFile);
7009
- var FILESYSTEM_REPO_KIND = "filesystem";
7010
- function translateNativeError2(error, notFound) {
7011
- const message = error instanceof Error ? error.message : String(error);
7012
- let payload;
7013
- try {
7014
- payload = JSON.parse(message);
7015
- } catch {
7016
- return error instanceof Error ? error : new FilesystemError(message);
7017
- }
7018
- if (!payload || typeof payload.category !== "string") {
7019
- return error instanceof Error ? error : new FilesystemError(message);
7020
- }
7021
- const detail = typeof payload.message === "string" ? payload.message : message;
7022
- if (payload.category === "connection") {
7023
- return new FilesystemError(detail);
7024
- }
7025
- if (payload.status === 404 && notFound !== void 0) {
7026
- return notFound;
7027
- }
7028
- if (typeof payload.status === "number") {
7029
- return new FilesystemAPIError(payload.status, detail);
7030
- }
7031
- return new FilesystemError(detail);
7032
- }
7033
- async function callNative2(fn, notFound) {
7034
- try {
7035
- return await fn();
7036
- } catch (error) {
7037
- throw translateNativeError2(error, notFound);
7038
- }
7039
- }
7040
- var FsCli = class {
7041
- binary = null;
7042
- envOverrides;
7043
- constructor(envOverrides) {
7009
+ var MountCli = class {
7010
+ constructor(command, envOverrides) {
7011
+ this.command = command;
7044
7012
  this.envOverrides = envOverrides;
7045
7013
  }
7014
+ binary = null;
7046
7015
  async findCli() {
7047
7016
  const candidates = [];
7048
- if (process.env.TENSORLAKE_CLI) {
7049
- candidates.push(process.env.TENSORLAKE_CLI);
7050
- }
7017
+ if (process.env.TENSORLAKE_CLI) candidates.push(process.env.TENSORLAKE_CLI);
7051
7018
  candidates.push("tl");
7052
7019
  const installed = join(homedir(), ".tensorlake", "bin", "tl");
7053
7020
  try {
@@ -7055,27 +7022,26 @@ var FsCli = class {
7055
7022
  candidates.push(installed);
7056
7023
  } catch {
7057
7024
  }
7025
+ const support = this.command === "git" ? "git mount" : "fs";
7026
+ const probe = this.command === "git" ? ["git", "mount", "--help"] : ["fs", "--help"];
7058
7027
  let unsupported = null;
7059
7028
  for (const candidate of candidates) {
7060
7029
  try {
7061
- await execFileAsync(candidate, ["fs", "--help"], { timeout: 15e3 });
7030
+ await execFileAsync(candidate, probe, { timeout: 15e3 });
7062
7031
  return candidate;
7063
7032
  } catch (error) {
7064
- if (error.code !== "ENOENT") {
7065
- unsupported = candidate;
7066
- }
7033
+ if (error.code !== "ENOENT") unsupported = candidate;
7067
7034
  }
7068
7035
  }
7069
7036
  throw new CliNotFoundError(
7070
- unsupported ? `\`tl\` at ${unsupported} does not support \`tl fs\` (upgrade required)` : "`tl` was not found on PATH"
7037
+ unsupported ? `\`tl\` at ${unsupported} does not support \`tl ${support}\` (upgrade required)` : "`tl` was not found on PATH",
7038
+ support
7071
7039
  );
7072
7040
  }
7073
7041
  async run(args, timeoutMs = 3e5) {
7074
- if (this.binary === null) {
7075
- this.binary = await this.findCli();
7076
- }
7042
+ if (this.binary === null) this.binary = await this.findCli();
7077
7043
  try {
7078
- const { stdout } = await execFileAsync(this.binary, ["fs", ...args], {
7044
+ const { stdout } = await execFileAsync(this.binary, [this.command, ...args], {
7079
7045
  timeout: timeoutMs,
7080
7046
  env: { ...process.env, ...this.envOverrides },
7081
7047
  maxBuffer: 16 * 1024 * 1024
@@ -7084,12 +7050,53 @@ var FsCli = class {
7084
7050
  } catch (error) {
7085
7051
  const failure = error;
7086
7052
  if (failure.killed) {
7087
- throw new MountError(`\`tl fs ${args[0]}\` timed out after ${timeoutMs}ms`);
7053
+ throw new MountError(`\`tl ${this.command} ${args[0]}\` timed out after ${timeoutMs}ms`);
7088
7054
  }
7089
7055
  const detail = (failure.stderr || failure.stdout || String(error)).trim();
7090
- throw new MountError(`\`tl fs ${args.join(" ")}\` failed: ${detail}`);
7056
+ throw new MountError(`\`tl ${this.command} ${args.join(" ")}\` failed: ${detail}`);
7091
7057
  }
7092
7058
  }
7059
+ };
7060
+
7061
+ // src/filesystem.ts
7062
+ init_defaults();
7063
+ init_native_sandbox();
7064
+ init_sandbox_image();
7065
+ var FILESYSTEM_REPO_KIND = "filesystem";
7066
+ function translateNativeError2(error, notFound) {
7067
+ const message = error instanceof Error ? error.message : String(error);
7068
+ let payload;
7069
+ try {
7070
+ payload = JSON.parse(message);
7071
+ } catch {
7072
+ return error instanceof Error ? error : new FilesystemError(message);
7073
+ }
7074
+ if (!payload || typeof payload.category !== "string") {
7075
+ return error instanceof Error ? error : new FilesystemError(message);
7076
+ }
7077
+ const detail = typeof payload.message === "string" ? payload.message : message;
7078
+ if (payload.category === "connection") {
7079
+ return new FilesystemError(detail);
7080
+ }
7081
+ if (payload.status === 404 && notFound !== void 0) {
7082
+ return notFound;
7083
+ }
7084
+ if (typeof payload.status === "number") {
7085
+ return new FilesystemAPIError(payload.status, detail);
7086
+ }
7087
+ return new FilesystemError(detail);
7088
+ }
7089
+ async function callNative2(fn, notFound) {
7090
+ try {
7091
+ return await fn();
7092
+ } catch (error) {
7093
+ throw translateNativeError2(error, notFound);
7094
+ }
7095
+ }
7096
+ var FsCli = class extends MountCli {
7097
+ constructor(envOverrides) {
7098
+ super("fs", envOverrides);
7099
+ }
7093
7100
  // Flags always precede a `--` end-of-options separator so caller-supplied
7094
7101
  // names/paths can never be parsed as CLI flags (e.g. a path literally
7095
7102
  // named "--discard" must stay a path, not become the destructive flag).
@@ -7703,9 +7710,146 @@ init_errors();
7703
7710
  init_native_sandbox();
7704
7711
  init_models();
7705
7712
  init_sandbox_image();
7713
+
7714
+ // src/repository-mount.ts
7715
+ init_esm_shims();
7716
+ import { resolve } from "path";
7717
+ function requireNonEmpty(value, name) {
7718
+ if (typeof value !== "string" || value.length === 0) {
7719
+ throw new TypeError(`${name} must be a non-empty string`);
7720
+ }
7721
+ }
7722
+ var GitCli = class extends MountCli {
7723
+ constructor(envOverrides) {
7724
+ super("git", envOverrides);
7725
+ }
7726
+ async mount(target, localPath, options = {}) {
7727
+ requireNonEmpty(target, "target");
7728
+ requireNonEmpty(localPath, "localPath");
7729
+ if (options.workspace !== void 0) requireNonEmpty(options.workspace, "workspace");
7730
+ if (options.readOnly && (options.publish || options.workspace !== void 0) || options.publish && options.workspace !== void 0) {
7731
+ throw new TypeError("readOnly, publish, and workspace are mutually exclusive");
7732
+ }
7733
+ const path4 = resolve(localPath);
7734
+ const args = ["mount"];
7735
+ if (options.readOnly) args.push("--ro");
7736
+ if (options.publish) args.push("--publish");
7737
+ if (options.workspace !== void 0) args.push(`--workspace=${options.workspace}`);
7738
+ args.push("--", target, path4);
7739
+ await this.run(args);
7740
+ return new RepositoryMount(this, target, path4, options.readOnly ?? false);
7741
+ }
7742
+ async unmount(localPath, options = {}) {
7743
+ requireNonEmpty(localPath, "localPath");
7744
+ const args = ["unmount"];
7745
+ if (options.deleteWorkspace) args.push("--delete");
7746
+ if (options.discard) args.push("--discard");
7747
+ args.push("--", resolve(localPath));
7748
+ await this.run(args);
7749
+ }
7750
+ async status(localPath) {
7751
+ const args = ["status", "--json"];
7752
+ if (localPath !== void 0) {
7753
+ requireNonEmpty(localPath, "localPath");
7754
+ args.push("--", resolve(localPath));
7755
+ }
7756
+ const output = await this.run(args, 6e4);
7757
+ let raw;
7758
+ try {
7759
+ const payload = JSON.parse(output);
7760
+ if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
7761
+ throw new Error("expected a JSON object");
7762
+ }
7763
+ raw = payload;
7764
+ } catch {
7765
+ throw new MountError(`\`tl git status --json\` returned invalid JSON: ${output.slice(0, 200)}`);
7766
+ }
7767
+ const stringField = (key) => typeof raw[key] === "string" ? raw[key] : null;
7768
+ return {
7769
+ path: stringField("mountpoint") ?? (localPath === void 0 ? "" : resolve(localPath)),
7770
+ repository: stringField("repository"),
7771
+ reference: stringField("reference"),
7772
+ workspaceId: stringField("workspace"),
7773
+ state: stringField("state"),
7774
+ localChanges: typeof raw.local_changes === "boolean" ? raw.local_changes : null,
7775
+ raw
7776
+ };
7777
+ }
7778
+ async snapshot(path4, message) {
7779
+ const args = ["snapshot"];
7780
+ if (message !== void 0) args.push(`--message=${message}`);
7781
+ args.push("--", path4);
7782
+ await this.run(args);
7783
+ }
7784
+ async sync(path4, target) {
7785
+ const args = ["sync", "--", path4];
7786
+ if (target !== void 0) {
7787
+ requireNonEmpty(target, "target");
7788
+ args.push(target);
7789
+ }
7790
+ await this.run(args);
7791
+ }
7792
+ async rebase(path4, target, failOnConflict) {
7793
+ requireNonEmpty(target, "target");
7794
+ const args = ["rebase"];
7795
+ if (failOnConflict) args.push("--fail-on-conflict");
7796
+ args.push("--", path4, target);
7797
+ await this.run(args);
7798
+ }
7799
+ async promote(path4, branch, merge) {
7800
+ requireNonEmpty(branch, "branch");
7801
+ const args = ["promote"];
7802
+ if (merge) args.push("--merge");
7803
+ args.push("--", path4, branch);
7804
+ await this.run(args);
7805
+ }
7806
+ async prefetch(path4) {
7807
+ await this.run(["prefetch", "--", path4]);
7808
+ }
7809
+ };
7810
+ var RepositoryMount = class {
7811
+ /** @internal Obtain instances via RepositoryClient.mount(). */
7812
+ constructor(cli, target, path4, readOnly) {
7813
+ this.cli = cli;
7814
+ this.target = target;
7815
+ this.path = path4;
7816
+ this.readOnly = readOnly;
7817
+ }
7818
+ /** Inspect workspace state, pending changes, and daemon diagnostics. */
7819
+ async status() {
7820
+ return this.cli.status(this.path);
7821
+ }
7822
+ /** Materialize autosaved edits as a commit; publish mounts also update their branch. */
7823
+ async snapshot(message) {
7824
+ await this.cli.snapshot(this.path, message);
7825
+ }
7826
+ /** Refresh the current source, or switch an unsnapshotted workspace to a new base. */
7827
+ async sync(target) {
7828
+ await this.cli.sync(this.path, target);
7829
+ }
7830
+ /** Replay snapshots and pending edits onto another base. Conflicts become diff3 markers by default. */
7831
+ async rebase(target, options) {
7832
+ await this.cli.rebase(this.path, target, options?.failOnConflict ?? false);
7833
+ }
7834
+ /** Publish the workspace to a branch; merge allows landing when the branch moved. */
7835
+ async promote(branch, options) {
7836
+ await this.cli.promote(this.path, branch, options?.merge ?? false);
7837
+ }
7838
+ /** Download and verify the mounted working set for network-free reads. */
7839
+ async prefetch() {
7840
+ await this.cli.prefetch(this.path);
7841
+ }
7842
+ /** Detach, retaining the private workspace and unpublished state unless explicitly requested. */
7843
+ async unmount(options) {
7844
+ await this.cli.unmount(this.path, options);
7845
+ }
7846
+ };
7847
+
7848
+ // src/repositories.ts
7706
7849
  var RepositoryClient = class _RepositoryClient {
7707
7850
  native;
7708
7851
  requestTimeoutMs;
7852
+ cli;
7709
7853
  constructor(options) {
7710
7854
  this.requestTimeoutMs = resolveRequestTimeoutMs2(options);
7711
7855
  const apiKey = options?.apiKey ?? API_KEY;
@@ -7726,9 +7870,20 @@ var RepositoryClient = class _RepositoryClient {
7726
7870
  null,
7727
7871
  this.requestTimeoutMs / 1e3
7728
7872
  );
7873
+ const context = buildContextFromEnv();
7874
+ const envOverrides = {
7875
+ TENSORLAKE_API_KEY: apiKey,
7876
+ TENSORLAKE_API_URL: options?.apiUrl ?? API_URL
7877
+ };
7878
+ const organizationId = options?.organizationId ?? context.organizationId;
7879
+ const projectId = options?.projectId ?? context.projectId;
7880
+ if (organizationId) envOverrides.TENSORLAKE_ORGANIZATION_ID = organizationId;
7881
+ if (projectId) envOverrides.TENSORLAKE_PROJECT_ID = projectId;
7882
+ this.cli = new GitCli(envOverrides);
7729
7883
  }
7730
7884
  static forCloud(options) {
7731
7885
  return new _RepositoryClient({
7886
+ ...options,
7732
7887
  apiUrl: options?.apiUrl ?? "https://api.tensorlake.ai",
7733
7888
  apiKey: options?.apiKey,
7734
7889
  requestTimeout: options?.requestTimeout,
@@ -7747,12 +7902,30 @@ var RepositoryClient = class _RepositoryClient {
7747
7902
  }
7748
7903
  return new _RepositoryClient({
7749
7904
  apiUrl: context.apiUrl,
7750
- apiKey: context.apiKey
7905
+ apiKey: context.apiKey,
7906
+ organizationId: context.organizationId,
7907
+ projectId: context.projectId
7751
7908
  });
7752
7909
  }
7753
7910
  close() {
7754
7911
  releaseNativeHandle(this.native);
7755
7912
  }
7913
+ /**
7914
+ * Mount `repo[:branch|tag|full-commit][//subtree]` to a local directory.
7915
+ * Requires the separately installed `tl` CLI with mount support. Mounts
7916
+ * live on the machine running Node.js and must be explicitly unmounted.
7917
+ */
7918
+ async mount(target, localPath, options) {
7919
+ return this.cli.mount(target, localPath, options);
7920
+ }
7921
+ /** Detach a local repository mount, optionally deleting its private workspace. */
7922
+ async unmount(localPath, options) {
7923
+ await this.cli.unmount(localPath, options);
7924
+ }
7925
+ /** Inspect a local mount; defaults to the mount containing the current directory. */
7926
+ async mountStatus(localPath) {
7927
+ return this.cli.status(localPath);
7928
+ }
7756
7929
  async url(repo) {
7757
7930
  return callNative(() => this.native.gitRepoUrl(repo));
7758
7931
  }
@@ -8469,16 +8642,16 @@ var FunctionFuture = class _FunctionFuture {
8469
8642
  ))
8470
8643
  );
8471
8644
  } else {
8472
- wait = new Promise((resolve) => {
8645
+ wait = new Promise((resolve2) => {
8473
8646
  let remaining = pending.length;
8474
8647
  for (const future of pending) {
8475
8648
  void internalDurableThen(
8476
8649
  future.result(),
8477
8650
  () => {
8478
8651
  remaining -= 1;
8479
- if (remaining === 0) resolve({ kind: "all_completed" });
8652
+ if (remaining === 0) resolve2({ kind: "all_completed" });
8480
8653
  },
8481
- () => resolve({ kind: "cutoff", future })
8654
+ () => resolve2({ kind: "cutoff", future })
8482
8655
  );
8483
8656
  }
8484
8657
  });
@@ -8514,8 +8687,8 @@ async function waitUntilOrTimeout(promise, timeoutSeconds) {
8514
8687
  try {
8515
8688
  return await internalPromiseRace([
8516
8689
  promise,
8517
- new Promise((resolve) => {
8518
- timer = setTimeout(() => resolve({ kind: "timeout" }), timeoutSeconds * 1e3);
8690
+ new Promise((resolve2) => {
8691
+ timer = setTimeout(() => resolve2({ kind: "timeout" }), timeoutSeconds * 1e3);
8519
8692
  })
8520
8693
  ]);
8521
8694
  } finally {
@@ -9515,8 +9688,8 @@ var LocalRuntime = class {
9515
9688
  let timer;
9516
9689
  try {
9517
9690
  await waitWithAbortSignal(
9518
- new Promise((resolve) => {
9519
- timer = setTimeout(resolve, future.delaySeconds * 1e3);
9691
+ new Promise((resolve2) => {
9692
+ timer = setTimeout(resolve2, future.delaySeconds * 1e3);
9520
9693
  }),
9521
9694
  this.requestContext.signal
9522
9695
  );
@@ -9746,6 +9919,7 @@ export {
9746
9919
  ReadOnlyMountNotSupportedError,
9747
9920
  RemoteAPIError,
9748
9921
  RepositoryClient,
9922
+ RepositoryMount,
9749
9923
  RequestContext,
9750
9924
  RequestExecutionError,
9751
9925
  RequestFailedError,