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.cjs CHANGED
@@ -49,7 +49,7 @@ var init_defaults = __esm({
49
49
  "src/defaults.ts"() {
50
50
  "use strict";
51
51
  init_cjs_shims();
52
- SDK_VERSION = "0.5.126";
52
+ SDK_VERSION = "0.5.127";
53
53
  API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
54
54
  API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
55
55
  NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
@@ -318,10 +318,10 @@ var init_native_worker_client = __esm({
318
318
  call(handle, method, args, emit) {
319
319
  const id = this.nextId++;
320
320
  let worker;
321
- const promise = new Promise((resolve, reject) => {
321
+ const promise = new Promise((resolve2, reject) => {
322
322
  try {
323
323
  worker = this.getWorker();
324
- this.pending.set(id, { resolve, reject, emit, handle });
324
+ this.pending.set(id, { resolve: resolve2, reject, emit, handle });
325
325
  worker.ref();
326
326
  if (handle) this.register(handle, worker);
327
327
  this.send(worker, {
@@ -424,7 +424,7 @@ var init_native_worker_client = __esm({
424
424
  }
425
425
  };
426
426
  runtimeKey = /* @__PURE__ */ Symbol.for(
427
- `tensorlake.native.worker.${false ? "source" : "0.5.126"}.v1`
427
+ `tensorlake.native.worker.${false ? "source" : "0.5.127"}.v1`
428
428
  );
429
429
  runtimes = globalThis;
430
430
  }
@@ -492,9 +492,9 @@ async function* nativeEventStream(start, context, signal) {
492
492
  let stopped = false;
493
493
  let failure;
494
494
  const notify = () => {
495
- const resolve = wake;
495
+ const resolve2 = wake;
496
496
  wake = void 0;
497
- resolve?.();
497
+ resolve2?.();
498
498
  };
499
499
  const emit = (value) => {
500
500
  if (stopped) return Promise.resolve();
@@ -529,8 +529,8 @@ async function* nativeEventStream(start, context, signal) {
529
529
  } else if (finished) {
530
530
  break;
531
531
  } else {
532
- await new Promise((resolve) => {
533
- wake = resolve;
532
+ await new Promise((resolve2) => {
533
+ wake = resolve2;
534
534
  });
535
535
  }
536
536
  }
@@ -684,7 +684,7 @@ var init_models = __esm({
684
684
  async function openTunnelWebSocket(options) {
685
685
  const wsUrl = buildTunnelWsUrl(options.baseUrl, options.remotePort);
686
686
  const timeoutMs = options.connectTimeoutMs ?? DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS;
687
- return new Promise((resolve, reject) => {
687
+ return new Promise((resolve2, reject) => {
688
688
  const socket = new import_ws.default(wsUrl, {
689
689
  headers: options.wsHeaders
690
690
  });
@@ -715,7 +715,7 @@ async function openTunnelWebSocket(options) {
715
715
  });
716
716
  };
717
717
  const onOpen = () => {
718
- settle(() => resolve(socket));
718
+ settle(() => resolve2(socket));
719
719
  };
720
720
  const onError = (error) => {
721
721
  fail(new SandboxConnectionError(error.message));
@@ -758,7 +758,7 @@ function normalizeWebSocketData(message) {
758
758
  return Buffer.from(message);
759
759
  }
760
760
  async function relaySocket(localSocket, websocket) {
761
- return new Promise((resolve) => {
761
+ return new Promise((resolve2) => {
762
762
  let settled = false;
763
763
  const keepAliveInterval = setInterval(() => {
764
764
  if (websocket.readyState === import_ws.default.OPEN) {
@@ -771,7 +771,7 @@ async function relaySocket(localSocket, websocket) {
771
771
  settled = true;
772
772
  clearInterval(keepAliveInterval);
773
773
  cleanup();
774
- resolve();
774
+ resolve2();
775
775
  };
776
776
  const cleanup = () => {
777
777
  localSocket.removeListener("data", onLocalData);
@@ -849,7 +849,7 @@ async function relaySocket(localSocket, websocket) {
849
849
  });
850
850
  }
851
851
  async function listenServer(server, localPort, localHost) {
852
- await new Promise((resolve, reject) => {
852
+ await new Promise((resolve2, reject) => {
853
853
  const onError = (error) => {
854
854
  server.removeListener("listening", onListening);
855
855
  reject(
@@ -860,7 +860,7 @@ async function listenServer(server, localPort, localHost) {
860
860
  };
861
861
  const onListening = () => {
862
862
  server.removeListener("error", onError);
863
- resolve();
863
+ resolve2();
864
864
  };
865
865
  server.once("error", onError);
866
866
  server.once("listening", onListening);
@@ -886,13 +886,13 @@ function secondsToMillis(seconds) {
886
886
  return Math.round(seconds * 1e3);
887
887
  }
888
888
  async function withTimeout(timeoutMs, operation, timeoutMessage) {
889
- return new Promise((resolve, reject) => {
889
+ return new Promise((resolve2, reject) => {
890
890
  const timer = setTimeout(() => {
891
891
  reject(new SandboxError(timeoutMessage));
892
892
  }, timeoutMs);
893
893
  void operation().then((value) => {
894
894
  clearTimeout(timer);
895
- resolve(value);
895
+ resolve2(value);
896
896
  }).catch((error) => {
897
897
  clearTimeout(timer);
898
898
  reject(error);
@@ -968,8 +968,8 @@ var init_tunnel = __esm({
968
968
  if (this.closeError) {
969
969
  throw this.closeError;
970
970
  }
971
- return new Promise((resolve, reject) => {
972
- this.pendingReads.push({ length, resolve, reject });
971
+ return new Promise((resolve2, reject) => {
972
+ this.pendingReads.push({ length, resolve: resolve2, reject });
973
973
  });
974
974
  }
975
975
  async writeAll(data) {
@@ -980,13 +980,13 @@ var init_tunnel = __esm({
980
980
  throw new SandboxError("desktop tunnel is not connected");
981
981
  }
982
982
  const payload = Buffer.from(data);
983
- await new Promise((resolve, reject) => {
983
+ await new Promise((resolve2, reject) => {
984
984
  this.socket.send(payload, { binary: true }, (error) => {
985
985
  if (error) {
986
986
  reject(new SandboxConnectionError(error.message));
987
987
  return;
988
988
  }
989
- resolve();
989
+ resolve2();
990
990
  });
991
991
  });
992
992
  }
@@ -998,10 +998,10 @@ var init_tunnel = __esm({
998
998
  this.closePromise = Promise.resolve();
999
999
  return this.closePromise;
1000
1000
  }
1001
- this.closePromise = new Promise((resolve) => {
1001
+ this.closePromise = new Promise((resolve2) => {
1002
1002
  const onClose = () => {
1003
1003
  this.socket.removeListener("close", onClose);
1004
- resolve();
1004
+ resolve2();
1005
1005
  };
1006
1006
  this.socket.on("close", onClose);
1007
1007
  this.socket.close();
@@ -1095,13 +1095,13 @@ var init_tunnel = __esm({
1095
1095
  relay.localSocket.destroy();
1096
1096
  relay.websocket?.close();
1097
1097
  }
1098
- this.closePromise = new Promise((resolve, reject) => {
1098
+ this.closePromise = new Promise((resolve2, reject) => {
1099
1099
  this.server.close((error) => {
1100
1100
  if (error) {
1101
1101
  reject(new SandboxError(`failed to close tunnel listener: ${error.message}`));
1102
1102
  return;
1103
1103
  }
1104
- resolve();
1104
+ resolve2();
1105
1105
  });
1106
1106
  });
1107
1107
  return this.closePromise;
@@ -1329,14 +1329,14 @@ function isReconnectableDesktopScreenshotError(error) {
1329
1329
  }
1330
1330
  function createDeferredSignal() {
1331
1331
  let resolveCurrent;
1332
- let promise = new Promise((resolve) => {
1333
- resolveCurrent = resolve;
1332
+ let promise = new Promise((resolve2) => {
1333
+ resolveCurrent = resolve2;
1334
1334
  });
1335
1335
  return {
1336
1336
  resolve() {
1337
1337
  resolveCurrent();
1338
- promise = new Promise((resolve) => {
1339
- resolveCurrent = resolve;
1338
+ promise = new Promise((resolve2) => {
1339
+ resolveCurrent = resolve2;
1340
1340
  });
1341
1341
  },
1342
1342
  wait() {
@@ -1681,7 +1681,7 @@ var init_desktop = __esm({
1681
1681
  validateNonNegativeInteger(delayMs, "double click delay");
1682
1682
  await this.click({ button, x: options?.x, y: options?.y });
1683
1683
  if (delayMs > 0) {
1684
- await new Promise((resolve) => setTimeout(resolve, delayMs));
1684
+ await new Promise((resolve2) => setTimeout(resolve2, delayMs));
1685
1685
  }
1686
1686
  await this.click({ button });
1687
1687
  }
@@ -3146,7 +3146,7 @@ function processUserPayload(user) {
3146
3146
  return user;
3147
3147
  }
3148
3148
  function sleep(ms) {
3149
- return new Promise((resolve) => setTimeout(resolve, ms));
3149
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
3150
3150
  }
3151
3151
  function normalizePtyMessage(message) {
3152
3152
  if (Buffer.isBuffer(message)) return message;
@@ -3167,8 +3167,8 @@ function encodePtyResize(cols, rows) {
3167
3167
  return frame;
3168
3168
  }
3169
3169
  function sendPtyFrame(socket, frame) {
3170
- return new Promise((resolve, reject) => {
3171
- socket.send(frame, (error) => error ? reject(error) : resolve());
3170
+ return new Promise((resolve2, reject) => {
3171
+ socket.send(frame, (error) => error ? reject(error) : resolve2());
3172
3172
  });
3173
3173
  }
3174
3174
  function markBindOutcome(sandbox, outcome) {
@@ -3410,8 +3410,8 @@ var init_sandbox = __esm({
3410
3410
  this.wsUrl = options.wsUrl;
3411
3411
  this.wsHeaders = options.wsHeaders;
3412
3412
  this.killSession = options.killSession;
3413
- this.waitPromise = new Promise((resolve, reject) => {
3414
- this.resolveWait = resolve;
3413
+ this.waitPromise = new Promise((resolve2, reject) => {
3414
+ this.resolveWait = resolve2;
3415
3415
  this.rejectWait = reject;
3416
3416
  });
3417
3417
  }
@@ -3434,7 +3434,7 @@ var init_sandbox = __esm({
3434
3434
  return this.connectPromise;
3435
3435
  }
3436
3436
  this.intentionalDisconnect = false;
3437
- this.connectPromise = new Promise((resolve, reject) => {
3437
+ this.connectPromise = new Promise((resolve2, reject) => {
3438
3438
  let opened = false;
3439
3439
  const socket = new import_ws2.default(this.wsUrl, {
3440
3440
  headers: this.wsHeaders
@@ -3444,7 +3444,7 @@ var init_sandbox = __esm({
3444
3444
  try {
3445
3445
  await sendPtyFrame(socket, Buffer.from([PTY_OP_READY]));
3446
3446
  opened = true;
3447
- resolve(this);
3447
+ resolve2(this);
3448
3448
  } catch (error) {
3449
3449
  reject(error);
3450
3450
  }
@@ -4375,7 +4375,7 @@ var init_sandbox = __esm({
4375
4375
  const remainingMs = deadlineMs - Date.now();
4376
4376
  if (remainingMs <= 0) break;
4377
4377
  await new Promise(
4378
- (resolve) => setTimeout(resolve, Math.min(probeIntervalMs, remainingMs))
4378
+ (resolve2) => setTimeout(resolve2, Math.min(probeIntervalMs, remainingMs))
4379
4379
  );
4380
4380
  }
4381
4381
  const detail = lastError instanceof Error ? `: ${lastError.message}` : "";
@@ -4482,7 +4482,7 @@ function validateTimeoutMs(timeoutMs) {
4482
4482
  }
4483
4483
  }
4484
4484
  function sleep2(ms) {
4485
- return new Promise((resolve) => setTimeout(resolve, ms));
4485
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
4486
4486
  }
4487
4487
  function snapshotStatusSatisfiesWaitCondition(status, waitUntil) {
4488
4488
  if (waitUntil === "local_ready") {
@@ -5326,7 +5326,7 @@ function anySignal(signals) {
5326
5326
  return controller.signal;
5327
5327
  }
5328
5328
  function sleep3(ms) {
5329
- return new Promise((resolve) => setTimeout(resolve, ms));
5329
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
5330
5330
  }
5331
5331
  var import_undici, REQUEST_TIMEOUT_HEADER, HttpClient;
5332
5332
  var init_http = __esm({
@@ -6314,9 +6314,9 @@ var require_libc = __commonJS({
6314
6314
  // src/native-binding.ts
6315
6315
  function packageRoot() {
6316
6316
  const parent = (0, import_node_url.fileURLToPath)(new URL("../", importMetaUrl));
6317
- if (fs.existsSync(import_node_path.default.join(parent, "package.json"))) return parent;
6317
+ if (fs.existsSync(import_node_path2.default.join(parent, "package.json"))) return parent;
6318
6318
  const grandparent = (0, import_node_url.fileURLToPath)(new URL("../../", importMetaUrl));
6319
- if (fs.existsSync(import_node_path.default.join(grandparent, "package.json"))) return grandparent;
6319
+ if (fs.existsSync(import_node_path2.default.join(grandparent, "package.json"))) return grandparent;
6320
6320
  return parent;
6321
6321
  }
6322
6322
  function linuxLibcFamily(options) {
@@ -6339,7 +6339,7 @@ function nativeTargetId(platform = process.platform, arch = process.arch, option
6339
6339
  function nativeBindingPath(options = {}) {
6340
6340
  const platform = options.platform ?? process.platform;
6341
6341
  const arch = options.arch ?? process.arch;
6342
- return import_node_path.default.join(
6342
+ return import_node_path2.default.join(
6343
6343
  options.packageRoot ?? packageRoot(),
6344
6344
  "dist",
6345
6345
  "native",
@@ -6372,7 +6372,7 @@ function loadNative() {
6372
6372
  }
6373
6373
  return require2(packageEntry);
6374
6374
  }
6375
- var import_libc, fs, import_node_module2, import_node_path, import_node_url, NATIVE_PACKAGES, cachedLinuxLibc;
6375
+ var import_libc, fs, import_node_module2, import_node_path2, import_node_url, NATIVE_PACKAGES, cachedLinuxLibc;
6376
6376
  var init_native_binding = __esm({
6377
6377
  "src/native-binding.ts"() {
6378
6378
  "use strict";
@@ -6380,7 +6380,7 @@ var init_native_binding = __esm({
6380
6380
  import_libc = __toESM(require_libc(), 1);
6381
6381
  fs = __toESM(require("fs"), 1);
6382
6382
  import_node_module2 = require("module");
6383
- import_node_path = __toESM(require("path"), 1);
6383
+ import_node_path2 = __toESM(require("path"), 1);
6384
6384
  import_node_url = require("url");
6385
6385
  NATIVE_PACKAGES = {
6386
6386
  "darwin-arm64": "tensorlake-native-darwin-arm64",
@@ -6438,9 +6438,9 @@ function buildContextFromEnv() {
6438
6438
  };
6439
6439
  }
6440
6440
  function defaultRegisteredName(dockerfilePath) {
6441
- const parsed = import_node_path2.default.parse(dockerfilePath);
6441
+ const parsed = import_node_path3.default.parse(dockerfilePath);
6442
6442
  if (parsed.name.toLowerCase() === "dockerfile") {
6443
- const parentName = import_node_path2.default.basename(import_node_path2.default.dirname(dockerfilePath)).trim();
6443
+ const parentName = import_node_path3.default.basename(import_node_path3.default.dirname(dockerfilePath)).trim();
6444
6444
  return parentName || "sandbox-image";
6445
6445
  }
6446
6446
  return parsed.name || "sandbox-image";
@@ -6530,24 +6530,24 @@ async function createSandboxImage(source, options = {}, deps = {}) {
6530
6530
  }
6531
6531
  let resolvedContext;
6532
6532
  if (options.contextDir != null) {
6533
- resolvedContext = import_node_path2.default.resolve(options.contextDir);
6533
+ resolvedContext = import_node_path3.default.resolve(options.contextDir);
6534
6534
  } else if (imageRequiresContext(source)) {
6535
6535
  throw new Error(
6536
6536
  "This image reads files from the host (via COPY/ADD or a RUN bind mount), so it needs a build context. Pass `contextDir` pointing at the directory that contains those sources; they resolve relative to it, like `docker build <contextDir>`."
6537
6537
  );
6538
6538
  } else {
6539
- tempContextDir = (0, import_node_fs.mkdtempSync)(import_node_path2.default.join(import_node_os.default.tmpdir(), "tl-build-context-"));
6539
+ tempContextDir = (0, import_node_fs2.mkdtempSync)(import_node_path3.default.join(import_node_os2.default.tmpdir(), "tl-build-context-"));
6540
6540
  resolvedContext = tempContextDir;
6541
6541
  }
6542
- dockerfilePath = import_node_path2.default.join(resolvedContext, "Dockerfile");
6542
+ dockerfilePath = import_node_path3.default.join(resolvedContext, "Dockerfile");
6543
6543
  let text = dockerfileContent(source);
6544
6544
  if (!text.endsWith("\n")) text += "\n";
6545
6545
  dockerfileText = text;
6546
6546
  nativeContextDir = resolvedContext;
6547
6547
  effectiveName = options.registeredName ?? source.name;
6548
6548
  } else if (typeof source === "string") {
6549
- const resolvedPath = import_node_path2.default.resolve(source);
6550
- if (!(0, import_node_fs.existsSync)(resolvedPath)) {
6549
+ const resolvedPath = import_node_path3.default.resolve(source);
6550
+ if (!(0, import_node_fs2.existsSync)(resolvedPath)) {
6551
6551
  throw new Error(`Dockerfile not found: ${source}`);
6552
6552
  }
6553
6553
  dockerfilePath = resolvedPath;
@@ -6624,7 +6624,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
6624
6624
  return result;
6625
6625
  } finally {
6626
6626
  if (tempContextDir != null) {
6627
- (0, import_node_fs.rmSync)(tempContextDir, { recursive: true, force: true });
6627
+ (0, import_node_fs2.rmSync)(tempContextDir, { recursive: true, force: true });
6628
6628
  }
6629
6629
  }
6630
6630
  }
@@ -6773,7 +6773,7 @@ async function listSandboxImages() {
6773
6773
  }
6774
6774
  }
6775
6775
  async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
6776
- const parsed = (0, import_node_util.parseArgs)({
6776
+ const parsed = (0, import_node_util2.parseArgs)({
6777
6777
  args: argv,
6778
6778
  allowPositionals: true,
6779
6779
  options: {
@@ -6825,7 +6825,7 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
6825
6825
  );
6826
6826
  }
6827
6827
  async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
6828
- const parsed = (0, import_node_util.parseArgs)({
6828
+ const parsed = (0, import_node_util2.parseArgs)({
6829
6829
  args: argv,
6830
6830
  allowPositionals: true,
6831
6831
  options: {
@@ -6876,15 +6876,15 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
6876
6876
  { emit: ndjsonStdoutEmit, _allowPat: true }
6877
6877
  );
6878
6878
  }
6879
- var import_node_path2, import_node_os, import_node_fs, import_node_util, cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2;
6879
+ var import_node_path3, import_node_os2, import_node_fs2, import_node_util2, cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2;
6880
6880
  var init_sandbox_image = __esm({
6881
6881
  "src/sandbox-image.ts"() {
6882
6882
  "use strict";
6883
6883
  init_cjs_shims();
6884
- import_node_path2 = __toESM(require("path"), 1);
6885
- import_node_os = __toESM(require("os"), 1);
6886
- import_node_fs = require("fs");
6887
- import_node_util = require("util");
6884
+ import_node_path3 = __toESM(require("path"), 1);
6885
+ import_node_os2 = __toESM(require("os"), 1);
6886
+ import_node_fs2 = require("fs");
6887
+ import_node_util2 = require("util");
6888
6888
  init_cloud_client();
6889
6889
  init_image();
6890
6890
  init_native_binding();
@@ -6922,6 +6922,7 @@ __export(index_exports, {
6922
6922
  ReadOnlyMountNotSupportedError: () => ReadOnlyMountNotSupportedError,
6923
6923
  RemoteAPIError: () => RemoteAPIError,
6924
6924
  RepositoryClient: () => RepositoryClient,
6925
+ RepositoryMount: () => RepositoryMount,
6925
6926
  RequestContext: () => RequestContext,
6926
6927
  RequestExecutionError: () => RequestExecutionError,
6927
6928
  RequestFailedError: () => RequestFailedError,
@@ -6969,13 +6970,15 @@ init_cloud_client();
6969
6970
 
6970
6971
  // src/filesystem.ts
6971
6972
  init_cjs_shims();
6972
- var import_node_child_process = require("child_process");
6973
6973
  var import_node_crypto2 = require("crypto");
6974
- var import_node_fs2 = require("fs");
6975
- var import_node_os2 = require("os");
6976
- var import_node_path3 = require("path");
6977
- var import_node_util2 = require("util");
6978
- init_defaults();
6974
+
6975
+ // src/mount-cli.ts
6976
+ init_cjs_shims();
6977
+ var import_node_child_process = require("child_process");
6978
+ var import_node_fs = require("fs");
6979
+ var import_node_os = require("os");
6980
+ var import_node_path = require("path");
6981
+ var import_node_util = require("util");
6979
6982
 
6980
6983
  // src/filesystem-models.ts
6981
6984
  init_cjs_shims();
@@ -7055,18 +7058,72 @@ var ReadOnlyMountNotSupportedError = class extends MountError {
7055
7058
  }
7056
7059
  };
7057
7060
  var CliNotFoundError = class extends MountError {
7058
- constructor(detail) {
7061
+ constructor(detail, command = "fs") {
7059
7062
  super(
7060
- `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`
7063
+ `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`
7061
7064
  );
7062
7065
  this.name = "CliNotFoundError";
7063
7066
  }
7064
7067
  };
7065
7068
 
7069
+ // src/mount-cli.ts
7070
+ var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
7071
+ var MountCli = class {
7072
+ constructor(command, envOverrides) {
7073
+ this.command = command;
7074
+ this.envOverrides = envOverrides;
7075
+ }
7076
+ binary = null;
7077
+ async findCli() {
7078
+ const candidates = [];
7079
+ if (process.env.TENSORLAKE_CLI) candidates.push(process.env.TENSORLAKE_CLI);
7080
+ candidates.push("tl");
7081
+ const installed = (0, import_node_path.join)((0, import_node_os.homedir)(), ".tensorlake", "bin", "tl");
7082
+ try {
7083
+ (0, import_node_fs.accessSync)(installed, import_node_fs.constants.F_OK);
7084
+ candidates.push(installed);
7085
+ } catch {
7086
+ }
7087
+ const support = this.command === "git" ? "git mount" : "fs";
7088
+ const probe = this.command === "git" ? ["git", "mount", "--help"] : ["fs", "--help"];
7089
+ let unsupported = null;
7090
+ for (const candidate of candidates) {
7091
+ try {
7092
+ await execFileAsync(candidate, probe, { timeout: 15e3 });
7093
+ return candidate;
7094
+ } catch (error) {
7095
+ if (error.code !== "ENOENT") unsupported = candidate;
7096
+ }
7097
+ }
7098
+ throw new CliNotFoundError(
7099
+ unsupported ? `\`tl\` at ${unsupported} does not support \`tl ${support}\` (upgrade required)` : "`tl` was not found on PATH",
7100
+ support
7101
+ );
7102
+ }
7103
+ async run(args, timeoutMs = 3e5) {
7104
+ if (this.binary === null) this.binary = await this.findCli();
7105
+ try {
7106
+ const { stdout } = await execFileAsync(this.binary, [this.command, ...args], {
7107
+ timeout: timeoutMs,
7108
+ env: { ...process.env, ...this.envOverrides },
7109
+ maxBuffer: 16 * 1024 * 1024
7110
+ });
7111
+ return stdout;
7112
+ } catch (error) {
7113
+ const failure = error;
7114
+ if (failure.killed) {
7115
+ throw new MountError(`\`tl ${this.command} ${args[0]}\` timed out after ${timeoutMs}ms`);
7116
+ }
7117
+ const detail = (failure.stderr || failure.stdout || String(error)).trim();
7118
+ throw new MountError(`\`tl ${this.command} ${args.join(" ")}\` failed: ${detail}`);
7119
+ }
7120
+ }
7121
+ };
7122
+
7066
7123
  // src/filesystem.ts
7124
+ init_defaults();
7067
7125
  init_native_sandbox();
7068
7126
  init_sandbox_image();
7069
- var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process.execFile);
7070
7127
  var FILESYSTEM_REPO_KIND = "filesystem";
7071
7128
  function translateNativeError2(error, notFound) {
7072
7129
  const message = error instanceof Error ? error.message : String(error);
@@ -7098,58 +7155,9 @@ async function callNative2(fn, notFound) {
7098
7155
  throw translateNativeError2(error, notFound);
7099
7156
  }
7100
7157
  }
7101
- var FsCli = class {
7102
- binary = null;
7103
- envOverrides;
7158
+ var FsCli = class extends MountCli {
7104
7159
  constructor(envOverrides) {
7105
- this.envOverrides = envOverrides;
7106
- }
7107
- async findCli() {
7108
- const candidates = [];
7109
- if (process.env.TENSORLAKE_CLI) {
7110
- candidates.push(process.env.TENSORLAKE_CLI);
7111
- }
7112
- candidates.push("tl");
7113
- const installed = (0, import_node_path3.join)((0, import_node_os2.homedir)(), ".tensorlake", "bin", "tl");
7114
- try {
7115
- (0, import_node_fs2.accessSync)(installed, import_node_fs2.constants.F_OK);
7116
- candidates.push(installed);
7117
- } catch {
7118
- }
7119
- let unsupported = null;
7120
- for (const candidate of candidates) {
7121
- try {
7122
- await execFileAsync(candidate, ["fs", "--help"], { timeout: 15e3 });
7123
- return candidate;
7124
- } catch (error) {
7125
- if (error.code !== "ENOENT") {
7126
- unsupported = candidate;
7127
- }
7128
- }
7129
- }
7130
- throw new CliNotFoundError(
7131
- unsupported ? `\`tl\` at ${unsupported} does not support \`tl fs\` (upgrade required)` : "`tl` was not found on PATH"
7132
- );
7133
- }
7134
- async run(args, timeoutMs = 3e5) {
7135
- if (this.binary === null) {
7136
- this.binary = await this.findCli();
7137
- }
7138
- try {
7139
- const { stdout } = await execFileAsync(this.binary, ["fs", ...args], {
7140
- timeout: timeoutMs,
7141
- env: { ...process.env, ...this.envOverrides },
7142
- maxBuffer: 16 * 1024 * 1024
7143
- });
7144
- return stdout;
7145
- } catch (error) {
7146
- const failure = error;
7147
- if (failure.killed) {
7148
- throw new MountError(`\`tl fs ${args[0]}\` timed out after ${timeoutMs}ms`);
7149
- }
7150
- const detail = (failure.stderr || failure.stdout || String(error)).trim();
7151
- throw new MountError(`\`tl fs ${args.join(" ")}\` failed: ${detail}`);
7152
- }
7160
+ super("fs", envOverrides);
7153
7161
  }
7154
7162
  // Flags always precede a `--` end-of-options separator so caller-supplied
7155
7163
  // names/paths can never be parsed as CLI flags (e.g. a path literally
@@ -7764,9 +7772,146 @@ init_errors();
7764
7772
  init_native_sandbox();
7765
7773
  init_models();
7766
7774
  init_sandbox_image();
7775
+
7776
+ // src/repository-mount.ts
7777
+ init_cjs_shims();
7778
+ var import_node_path4 = require("path");
7779
+ function requireNonEmpty(value, name) {
7780
+ if (typeof value !== "string" || value.length === 0) {
7781
+ throw new TypeError(`${name} must be a non-empty string`);
7782
+ }
7783
+ }
7784
+ var GitCli = class extends MountCli {
7785
+ constructor(envOverrides) {
7786
+ super("git", envOverrides);
7787
+ }
7788
+ async mount(target, localPath, options = {}) {
7789
+ requireNonEmpty(target, "target");
7790
+ requireNonEmpty(localPath, "localPath");
7791
+ if (options.workspace !== void 0) requireNonEmpty(options.workspace, "workspace");
7792
+ if (options.readOnly && (options.publish || options.workspace !== void 0) || options.publish && options.workspace !== void 0) {
7793
+ throw new TypeError("readOnly, publish, and workspace are mutually exclusive");
7794
+ }
7795
+ const path3 = (0, import_node_path4.resolve)(localPath);
7796
+ const args = ["mount"];
7797
+ if (options.readOnly) args.push("--ro");
7798
+ if (options.publish) args.push("--publish");
7799
+ if (options.workspace !== void 0) args.push(`--workspace=${options.workspace}`);
7800
+ args.push("--", target, path3);
7801
+ await this.run(args);
7802
+ return new RepositoryMount(this, target, path3, options.readOnly ?? false);
7803
+ }
7804
+ async unmount(localPath, options = {}) {
7805
+ requireNonEmpty(localPath, "localPath");
7806
+ const args = ["unmount"];
7807
+ if (options.deleteWorkspace) args.push("--delete");
7808
+ if (options.discard) args.push("--discard");
7809
+ args.push("--", (0, import_node_path4.resolve)(localPath));
7810
+ await this.run(args);
7811
+ }
7812
+ async status(localPath) {
7813
+ const args = ["status", "--json"];
7814
+ if (localPath !== void 0) {
7815
+ requireNonEmpty(localPath, "localPath");
7816
+ args.push("--", (0, import_node_path4.resolve)(localPath));
7817
+ }
7818
+ const output = await this.run(args, 6e4);
7819
+ let raw;
7820
+ try {
7821
+ const payload = JSON.parse(output);
7822
+ if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
7823
+ throw new Error("expected a JSON object");
7824
+ }
7825
+ raw = payload;
7826
+ } catch {
7827
+ throw new MountError(`\`tl git status --json\` returned invalid JSON: ${output.slice(0, 200)}`);
7828
+ }
7829
+ const stringField = (key) => typeof raw[key] === "string" ? raw[key] : null;
7830
+ return {
7831
+ path: stringField("mountpoint") ?? (localPath === void 0 ? "" : (0, import_node_path4.resolve)(localPath)),
7832
+ repository: stringField("repository"),
7833
+ reference: stringField("reference"),
7834
+ workspaceId: stringField("workspace"),
7835
+ state: stringField("state"),
7836
+ localChanges: typeof raw.local_changes === "boolean" ? raw.local_changes : null,
7837
+ raw
7838
+ };
7839
+ }
7840
+ async snapshot(path3, message) {
7841
+ const args = ["snapshot"];
7842
+ if (message !== void 0) args.push(`--message=${message}`);
7843
+ args.push("--", path3);
7844
+ await this.run(args);
7845
+ }
7846
+ async sync(path3, target) {
7847
+ const args = ["sync", "--", path3];
7848
+ if (target !== void 0) {
7849
+ requireNonEmpty(target, "target");
7850
+ args.push(target);
7851
+ }
7852
+ await this.run(args);
7853
+ }
7854
+ async rebase(path3, target, failOnConflict) {
7855
+ requireNonEmpty(target, "target");
7856
+ const args = ["rebase"];
7857
+ if (failOnConflict) args.push("--fail-on-conflict");
7858
+ args.push("--", path3, target);
7859
+ await this.run(args);
7860
+ }
7861
+ async promote(path3, branch, merge) {
7862
+ requireNonEmpty(branch, "branch");
7863
+ const args = ["promote"];
7864
+ if (merge) args.push("--merge");
7865
+ args.push("--", path3, branch);
7866
+ await this.run(args);
7867
+ }
7868
+ async prefetch(path3) {
7869
+ await this.run(["prefetch", "--", path3]);
7870
+ }
7871
+ };
7872
+ var RepositoryMount = class {
7873
+ /** @internal Obtain instances via RepositoryClient.mount(). */
7874
+ constructor(cli, target, path3, readOnly) {
7875
+ this.cli = cli;
7876
+ this.target = target;
7877
+ this.path = path3;
7878
+ this.readOnly = readOnly;
7879
+ }
7880
+ /** Inspect workspace state, pending changes, and daemon diagnostics. */
7881
+ async status() {
7882
+ return this.cli.status(this.path);
7883
+ }
7884
+ /** Materialize autosaved edits as a commit; publish mounts also update their branch. */
7885
+ async snapshot(message) {
7886
+ await this.cli.snapshot(this.path, message);
7887
+ }
7888
+ /** Refresh the current source, or switch an unsnapshotted workspace to a new base. */
7889
+ async sync(target) {
7890
+ await this.cli.sync(this.path, target);
7891
+ }
7892
+ /** Replay snapshots and pending edits onto another base. Conflicts become diff3 markers by default. */
7893
+ async rebase(target, options) {
7894
+ await this.cli.rebase(this.path, target, options?.failOnConflict ?? false);
7895
+ }
7896
+ /** Publish the workspace to a branch; merge allows landing when the branch moved. */
7897
+ async promote(branch, options) {
7898
+ await this.cli.promote(this.path, branch, options?.merge ?? false);
7899
+ }
7900
+ /** Download and verify the mounted working set for network-free reads. */
7901
+ async prefetch() {
7902
+ await this.cli.prefetch(this.path);
7903
+ }
7904
+ /** Detach, retaining the private workspace and unpublished state unless explicitly requested. */
7905
+ async unmount(options) {
7906
+ await this.cli.unmount(this.path, options);
7907
+ }
7908
+ };
7909
+
7910
+ // src/repositories.ts
7767
7911
  var RepositoryClient = class _RepositoryClient {
7768
7912
  native;
7769
7913
  requestTimeoutMs;
7914
+ cli;
7770
7915
  constructor(options) {
7771
7916
  this.requestTimeoutMs = resolveRequestTimeoutMs2(options);
7772
7917
  const apiKey = options?.apiKey ?? API_KEY;
@@ -7787,9 +7932,20 @@ var RepositoryClient = class _RepositoryClient {
7787
7932
  null,
7788
7933
  this.requestTimeoutMs / 1e3
7789
7934
  );
7935
+ const context = buildContextFromEnv();
7936
+ const envOverrides = {
7937
+ TENSORLAKE_API_KEY: apiKey,
7938
+ TENSORLAKE_API_URL: options?.apiUrl ?? API_URL
7939
+ };
7940
+ const organizationId = options?.organizationId ?? context.organizationId;
7941
+ const projectId = options?.projectId ?? context.projectId;
7942
+ if (organizationId) envOverrides.TENSORLAKE_ORGANIZATION_ID = organizationId;
7943
+ if (projectId) envOverrides.TENSORLAKE_PROJECT_ID = projectId;
7944
+ this.cli = new GitCli(envOverrides);
7790
7945
  }
7791
7946
  static forCloud(options) {
7792
7947
  return new _RepositoryClient({
7948
+ ...options,
7793
7949
  apiUrl: options?.apiUrl ?? "https://api.tensorlake.ai",
7794
7950
  apiKey: options?.apiKey,
7795
7951
  requestTimeout: options?.requestTimeout,
@@ -7808,12 +7964,30 @@ var RepositoryClient = class _RepositoryClient {
7808
7964
  }
7809
7965
  return new _RepositoryClient({
7810
7966
  apiUrl: context.apiUrl,
7811
- apiKey: context.apiKey
7967
+ apiKey: context.apiKey,
7968
+ organizationId: context.organizationId,
7969
+ projectId: context.projectId
7812
7970
  });
7813
7971
  }
7814
7972
  close() {
7815
7973
  releaseNativeHandle(this.native);
7816
7974
  }
7975
+ /**
7976
+ * Mount `repo[:branch|tag|full-commit][//subtree]` to a local directory.
7977
+ * Requires the separately installed `tl` CLI with mount support. Mounts
7978
+ * live on the machine running Node.js and must be explicitly unmounted.
7979
+ */
7980
+ async mount(target, localPath, options) {
7981
+ return this.cli.mount(target, localPath, options);
7982
+ }
7983
+ /** Detach a local repository mount, optionally deleting its private workspace. */
7984
+ async unmount(localPath, options) {
7985
+ await this.cli.unmount(localPath, options);
7986
+ }
7987
+ /** Inspect a local mount; defaults to the mount containing the current directory. */
7988
+ async mountStatus(localPath) {
7989
+ return this.cli.status(localPath);
7990
+ }
7817
7991
  async url(repo) {
7818
7992
  return callNative(() => this.native.gitRepoUrl(repo));
7819
7993
  }
@@ -8530,16 +8704,16 @@ var FunctionFuture = class _FunctionFuture {
8530
8704
  ))
8531
8705
  );
8532
8706
  } else {
8533
- wait = new Promise((resolve) => {
8707
+ wait = new Promise((resolve2) => {
8534
8708
  let remaining = pending.length;
8535
8709
  for (const future of pending) {
8536
8710
  void internalDurableThen(
8537
8711
  future.result(),
8538
8712
  () => {
8539
8713
  remaining -= 1;
8540
- if (remaining === 0) resolve({ kind: "all_completed" });
8714
+ if (remaining === 0) resolve2({ kind: "all_completed" });
8541
8715
  },
8542
- () => resolve({ kind: "cutoff", future })
8716
+ () => resolve2({ kind: "cutoff", future })
8543
8717
  );
8544
8718
  }
8545
8719
  });
@@ -8575,8 +8749,8 @@ async function waitUntilOrTimeout(promise, timeoutSeconds) {
8575
8749
  try {
8576
8750
  return await internalPromiseRace([
8577
8751
  promise,
8578
- new Promise((resolve) => {
8579
- timer = setTimeout(() => resolve({ kind: "timeout" }), timeoutSeconds * 1e3);
8752
+ new Promise((resolve2) => {
8753
+ timer = setTimeout(() => resolve2({ kind: "timeout" }), timeoutSeconds * 1e3);
8580
8754
  })
8581
8755
  ]);
8582
8756
  } finally {
@@ -9576,8 +9750,8 @@ var LocalRuntime = class {
9576
9750
  let timer;
9577
9751
  try {
9578
9752
  await waitWithAbortSignal(
9579
- new Promise((resolve) => {
9580
- timer = setTimeout(resolve, future.delaySeconds * 1e3);
9753
+ new Promise((resolve2) => {
9754
+ timer = setTimeout(resolve2, future.delaySeconds * 1e3);
9581
9755
  }),
9582
9756
  this.requestContext.signal
9583
9757
  );
@@ -9808,6 +9982,7 @@ init_models();
9808
9982
  ReadOnlyMountNotSupportedError,
9809
9983
  RemoteAPIError,
9810
9984
  RepositoryClient,
9985
+ RepositoryMount,
9811
9986
  RequestContext,
9812
9987
  RequestExecutionError,
9813
9988
  RequestFailedError,