@boxes-dev/dvb 1.0.54 → 1.0.55

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/bin/dvb.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b688f344-5d53-57d8-9464-1da40ea2bc02")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4d4f5269-c2cd-5397-a6d4-993b4d24cfdc")}catch(e){}}();
4
4
 
5
5
  var __create = Object.create;
6
6
  var __defProp = Object.defineProperty;
@@ -88683,8 +88683,8 @@ var init_otel = __esm({
88683
88683
  return trimmed && trimmed.length > 0 ? trimmed : void 0;
88684
88684
  };
88685
88685
  readBuildMetadata = () => {
88686
- const rawPackageVersion = "1.0.54";
88687
- const rawGitSha = "9b08274a528c685a1a8720a6c9af9946e2a99af5";
88686
+ const rawPackageVersion = "1.0.55";
88687
+ const rawGitSha = "fd6acb6139b570fb0b4ff18a48c7dfe864bb6513";
88688
88688
  const packageVersion = typeof rawPackageVersion === "string" ? rawPackageVersion : void 0;
88689
88689
  const gitSha = typeof rawGitSha === "string" ? rawGitSha : void 0;
88690
88690
  return { packageVersion, gitSha };
@@ -120672,9 +120672,9 @@ var init_sentry = __esm({
120672
120672
  sentryEnabled = false;
120673
120673
  uncaughtExceptionMonitorInstalled = false;
120674
120674
  readBuildMetadata2 = () => {
120675
- const rawPackageVersion = "1.0.54";
120676
- const rawGitSha = "9b08274a528c685a1a8720a6c9af9946e2a99af5";
120677
- const rawSentryRelease = "boxes-dev-dvb@1.0.54+9b08274a528c685a1a8720a6c9af9946e2a99af5";
120675
+ const rawPackageVersion = "1.0.55";
120676
+ const rawGitSha = "fd6acb6139b570fb0b4ff18a48c7dfe864bb6513";
120677
+ const rawSentryRelease = "boxes-dev-dvb@1.0.55+fd6acb6139b570fb0b4ff18a48c7dfe864bb6513";
120678
120678
  const packageVersion = typeof rawPackageVersion === "string" ? rawPackageVersion : void 0;
120679
120679
  const gitSha = typeof rawGitSha === "string" ? rawGitSha : void 0;
120680
120680
  const sentryRelease = typeof rawSentryRelease === "string" ? rawSentryRelease : void 0;
@@ -197021,7 +197021,7 @@ var init_destroyLocalState = __esm({
197021
197021
  });
197022
197022
 
197023
197023
  // src/devbox/commands/commandProvider.ts
197024
- var MODAL_CONNECT_CAPABILITIES, normalizeBoxKey, resolveRegistryEntry, resolveCommandComputeProvider, assertCommandProviderCapability, hasCommandProviderCapability;
197024
+ var MODAL_CONNECT_CAPABILITIES, MODAL_MOUNT_CAPABILITIES, normalizeBoxKey, resolveRegistryEntry, resolveCommandComputeProvider, assertCommandProviderCapability, hasCommandProviderCapability;
197025
197025
  var init_commandProvider = __esm({
197026
197026
  "src/devbox/commands/commandProvider.ts"() {
197027
197027
  "use strict";
@@ -197033,6 +197033,7 @@ var init_commandProvider = __esm({
197033
197033
  "exec.sessions.list",
197034
197034
  "exec.sessions.kill"
197035
197035
  ]);
197036
+ MODAL_MOUNT_CAPABILITIES = /* @__PURE__ */ new Set(["files.read"]);
197036
197037
  normalizeBoxKey = (value) => {
197037
197038
  if (typeof value !== "string") return null;
197038
197039
  const trimmed = value.trim();
@@ -197090,6 +197091,9 @@ var init_commandProvider = __esm({
197090
197091
  if (provider === "modal" && command === "connect" && MODAL_CONNECT_CAPABILITIES.has(capability)) {
197091
197092
  return;
197092
197093
  }
197094
+ if (provider === "modal" && command === "mount" && MODAL_MOUNT_CAPABILITIES.has(capability)) {
197095
+ return;
197096
+ }
197093
197097
  throw new ProviderCapabilityError({
197094
197098
  provider,
197095
197099
  capability,
@@ -197116,7 +197120,7 @@ var init_commandProvider = __esm({
197116
197120
  });
197117
197121
 
197118
197122
  // src/devbox/commands/init/provider/modalRuntime.ts
197119
- var import_node_crypto8, import_node_path16, import_ws3, SERVICE_BASE_DIR, SERVICE_META_SUFFIX, SERVICE_RUN_SUFFIX, SERVICE_PID_SUFFIX, SERVICE_LOG_SUFFIX, SERVICE_NAME_PATTERN, shellQuote2, MODAL_EXEC_WS_PATH2, MODAL_CONNECT_TOKEN_QUERY2, MODAL_DAEMON_HANDSHAKE_TIMEOUT_MS, MODAL_DAEMON_REQUEST_TIMEOUT_MS, serviceMetaPath, serviceRunnerPath, servicePidPath, serviceLogPath, validateServiceName, isSandboxNotFoundError2, resolveReadPath, buildWsUrlFromConnectToken, decodeBase642, parseJsonRecord2, readCreateConnectToken2, withTimeout2, connectModalDaemonWebSocket, awaitModalDaemonMessage, parseControlError, mapControlSessionRecord, ModalDaemonExecSocket, createModalInitRuntimeClient;
197123
+ var import_node_crypto8, import_node_path16, import_ws3, SERVICE_BASE_DIR, SERVICE_META_SUFFIX, SERVICE_RUN_SUFFIX, SERVICE_PID_SUFFIX, SERVICE_LOG_SUFFIX, SERVICE_NAME_PATTERN, shellQuote2, MODAL_EXEC_WS_PATH2, MODAL_CONNECT_TOKEN_QUERY2, MODAL_DAEMON_HANDSHAKE_TIMEOUT_MS, MODAL_DAEMON_REQUEST_TIMEOUT_MS, MODAL_DAEMON_TTY_HANDSHAKE_TIMEOUT_MS, MODAL_SANDBOX_RESOLVE_TIMEOUT_MS, serviceMetaPath, serviceRunnerPath, servicePidPath, serviceLogPath, validateServiceName, isSandboxNotFoundError2, resolveReadPath, buildWsUrlFromConnectToken, decodeBase642, parseJsonRecord2, readCreateConnectToken2, withTimeout2, connectModalDaemonWebSocket, awaitModalDaemonMessage, parseControlError, mapControlSessionRecord, ModalDaemonExecSocket, createModalInitRuntimeClient;
197120
197124
  var init_modalRuntime = __esm({
197121
197125
  "src/devbox/commands/init/provider/modalRuntime.ts"() {
197122
197126
  "use strict";
@@ -197136,6 +197140,8 @@ var init_modalRuntime = __esm({
197136
197140
  MODAL_CONNECT_TOKEN_QUERY2 = "_modal_connect_token";
197137
197141
  MODAL_DAEMON_HANDSHAKE_TIMEOUT_MS = 1e4;
197138
197142
  MODAL_DAEMON_REQUEST_TIMEOUT_MS = 15e3;
197143
+ MODAL_DAEMON_TTY_HANDSHAKE_TIMEOUT_MS = 3e4;
197144
+ MODAL_SANDBOX_RESOLVE_TIMEOUT_MS = 3e4;
197139
197145
  serviceMetaPath = (service) => `${SERVICE_BASE_DIR}/${service}${SERVICE_META_SUFFIX}`;
197140
197146
  serviceRunnerPath = (service) => `${SERVICE_BASE_DIR}/${service}${SERVICE_RUN_SUFFIX}`;
197141
197147
  servicePidPath = (service) => `${SERVICE_BASE_DIR}/${service}${SERVICE_PID_SUFFIX}`;
@@ -197331,6 +197337,7 @@ var init_modalRuntime = __esm({
197331
197337
  ws = null;
197332
197338
  closed = false;
197333
197339
  pongListeners = /* @__PURE__ */ new Set();
197340
+ handshakeTimer = null;
197334
197341
  emit(type, event = {}) {
197335
197342
  for (const listener of this.listeners[type]) {
197336
197343
  listener(event);
@@ -197341,6 +197348,26 @@ var init_modalRuntime = __esm({
197341
197348
  listener();
197342
197349
  }
197343
197350
  }
197351
+ clearHandshakeTimer() {
197352
+ if (!this.handshakeTimer) {
197353
+ return;
197354
+ }
197355
+ clearTimeout(this.handshakeTimer);
197356
+ this.handshakeTimer = null;
197357
+ }
197358
+ startHandshakeTimer() {
197359
+ this.clearHandshakeTimer();
197360
+ this.handshakeTimer = setTimeout(() => {
197361
+ if (this.closed || this.readyState !== 0) {
197362
+ return;
197363
+ }
197364
+ this.emit("error", {
197365
+ data: new Error("Timed out waiting for modal tty session handshake.")
197366
+ });
197367
+ this.close();
197368
+ }, MODAL_DAEMON_TTY_HANDSHAKE_TIMEOUT_MS);
197369
+ this.handshakeTimer.unref();
197370
+ }
197344
197371
  emitMessagePayload(streamId, payload) {
197345
197372
  if (this.closed) return;
197346
197373
  const framed = new Uint8Array(payload.length + 1);
@@ -197358,6 +197385,7 @@ var init_modalRuntime = __esm({
197358
197385
  const type = typeof message.type === "string" ? message.type : "";
197359
197386
  if (type === "tty_ready") {
197360
197387
  const sessionId = typeof message.sessionId === "string" ? message.sessionId : "";
197388
+ this.clearHandshakeTimer();
197361
197389
  this.readyState = 1;
197362
197390
  this.emit("open");
197363
197391
  this.emit("message", {
@@ -197402,6 +197430,7 @@ var init_modalRuntime = __esm({
197402
197430
  const wsUrl = buildWsUrlFromConnectToken(credentials);
197403
197431
  const ws = new import_ws3.default(wsUrl);
197404
197432
  this.ws = ws;
197433
+ this.startHandshakeTimer();
197405
197434
  ws.on("open", () => {
197406
197435
  try {
197407
197436
  const authPayload = {
@@ -197432,17 +197461,20 @@ var init_modalRuntime = __esm({
197432
197461
  this.emitPong();
197433
197462
  });
197434
197463
  ws.on("error", (error2) => {
197464
+ this.clearHandshakeTimer();
197435
197465
  this.emit("error", {
197436
197466
  data: error2 instanceof Error ? error2 : new Error(String(error2))
197437
197467
  });
197438
197468
  });
197439
197469
  ws.on("close", (code2) => {
197470
+ this.clearHandshakeTimer();
197440
197471
  if (this.closed) return;
197441
197472
  this.closed = true;
197442
197473
  this.readyState = 3;
197443
197474
  this.emit("close", { code: code2 });
197444
197475
  });
197445
197476
  } catch (error2) {
197477
+ this.clearHandshakeTimer();
197446
197478
  const err = error2 instanceof Error ? error2 : new Error(String(error2));
197447
197479
  this.emit("error", { data: err });
197448
197480
  this.close();
@@ -197497,6 +197529,7 @@ var init_modalRuntime = __esm({
197497
197529
  }
197498
197530
  close() {
197499
197531
  if (this.closed) return;
197532
+ this.clearHandshakeTimer();
197500
197533
  this.closed = true;
197501
197534
  this.readyState = 3;
197502
197535
  if (this.ws && this.ws.readyState <= import_ws3.default.OPEN) {
@@ -197575,7 +197608,11 @@ var init_modalRuntime = __esm({
197575
197608
  if (sandboxPromise) return sandboxPromise;
197576
197609
  sandboxPromise = (async () => {
197577
197610
  try {
197578
- const runningSandbox = await modal.sandboxes.fromName(appName, alias);
197611
+ const runningSandbox = await withTimeout2(
197612
+ modal.sandboxes.fromName(appName, alias),
197613
+ MODAL_SANDBOX_RESOLVE_TIMEOUT_MS,
197614
+ "Timed out resolving running modal sandbox by name."
197615
+ );
197579
197616
  sandboxId = runningSandbox.sandboxId;
197580
197617
  return runningSandbox;
197581
197618
  } catch (error2) {
@@ -197584,12 +197621,24 @@ var init_modalRuntime = __esm({
197584
197621
  }
197585
197622
  }
197586
197623
  if (ensureActive) {
197587
- const ensured = await ensureActive(intent);
197624
+ const ensured = await withTimeout2(
197625
+ ensureActive(intent),
197626
+ MODAL_SANDBOX_RESOLVE_TIMEOUT_MS,
197627
+ "Timed out waiting for modal devbox wake."
197628
+ );
197588
197629
  appName = ensured.appName;
197589
197630
  sandboxId = ensured.sandboxId;
197590
- return await modal.sandboxes.fromId(ensured.sandboxId);
197631
+ return await withTimeout2(
197632
+ modal.sandboxes.fromId(ensured.sandboxId),
197633
+ MODAL_SANDBOX_RESOLVE_TIMEOUT_MS,
197634
+ "Timed out resolving modal sandbox after wake."
197635
+ );
197591
197636
  }
197592
- return await modal.sandboxes.fromId(sandboxId);
197637
+ return await withTimeout2(
197638
+ modal.sandboxes.fromId(sandboxId),
197639
+ MODAL_SANDBOX_RESOLVE_TIMEOUT_MS,
197640
+ "Timed out resolving modal sandbox by id."
197641
+ );
197593
197642
  })().catch((error2) => {
197594
197643
  sandboxPromise = null;
197595
197644
  throw error2;
@@ -198552,6 +198601,76 @@ var init_providerClient = __esm({
198552
198601
  }
198553
198602
  });
198554
198603
 
198604
+ // src/devbox/commands/provider/modalCommandContext.ts
198605
+ var resolveModalCommandContext;
198606
+ var init_modalCommandContext = __esm({
198607
+ "src/devbox/commands/provider/modalCommandContext.ts"() {
198608
+ "use strict";
198609
+ init_src();
198610
+ init_auth();
198611
+ init_controlPlane();
198612
+ init_providerClient();
198613
+ resolveModalCommandContext = async (options) => {
198614
+ const config4 = await loadConfig(
198615
+ process.env.HOME ? { homeDir: process.env.HOME } : void 0
198616
+ );
198617
+ const store = await createSecretStore(
198618
+ config4?.tokenStore,
198619
+ process.env.HOME ? { homeDir: process.env.HOME } : void 0
198620
+ );
198621
+ const modalCredentialContext = createProviderCredentialContext({
198622
+ mode: "auto",
198623
+ controlPlaneToken: await store.getControlPlaneToken()
198624
+ });
198625
+ let operationOptions = await resolveModalCommandOperationOptions({
198626
+ credentials: modalCredentialContext,
198627
+ cwd: options.cwd
198628
+ });
198629
+ if (operationOptions.credentialMode === "shared" && (!operationOptions.credentials.modalTokenId || !operationOptions.credentials.modalTokenSecret)) {
198630
+ const controlPlaneToken2 = await ensureControlPlaneToken(
198631
+ store,
198632
+ options.stage
198633
+ );
198634
+ if (controlPlaneToken2) {
198635
+ operationOptions = await resolveModalCommandOperationOptions({
198636
+ credentials: createProviderCredentialContext({
198637
+ mode: "auto",
198638
+ controlPlaneToken: controlPlaneToken2
198639
+ }),
198640
+ cwd: options.cwd
198641
+ });
198642
+ }
198643
+ }
198644
+ let controlPlaneToken = modalCredentialContext.controlPlaneToken;
198645
+ const ensureActive = async (intent) => {
198646
+ if (!controlPlaneToken) {
198647
+ controlPlaneToken = await ensureControlPlaneToken(store, options.stage);
198648
+ }
198649
+ if (!controlPlaneToken) {
198650
+ throw new Error(
198651
+ "Control plane authentication is required to wake modal devboxes. Run `dvb setup` and retry."
198652
+ );
198653
+ }
198654
+ const ensured = await ensureModalDevboxActive2(
198655
+ controlPlaneToken,
198656
+ options.alias,
198657
+ intent
198658
+ );
198659
+ return {
198660
+ appName: ensured.appName,
198661
+ sandboxId: ensured.sandboxId,
198662
+ woke: ensured.woke,
198663
+ wakeSource: ensured.wakeSource
198664
+ };
198665
+ };
198666
+ return {
198667
+ operationOptions,
198668
+ ensureActive
198669
+ };
198670
+ };
198671
+ }
198672
+ });
198673
+
198555
198674
  // src/devbox/commands/sessionUtils.ts
198556
198675
  var AUTO_SESSION_PREFIX, parseAutoSessionSuffix, getNextAutoSessionName, ensureUniqueAutoSessionName, shellQuote3, sanitizeSessionName, buildSessionLogPath, renameSessionLog;
198557
198676
  var init_sessionUtils = __esm({
@@ -198618,7 +198737,6 @@ var init_connect2 = __esm({
198618
198737
  init_src();
198619
198738
  init_daemonClient();
198620
198739
  init_auth();
198621
- init_controlPlane();
198622
198740
  init_logger3();
198623
198741
  init_latency();
198624
198742
  init_osc();
@@ -198627,7 +198745,7 @@ var init_connect2 = __esm({
198627
198745
  init_boxSelect();
198628
198746
  init_commandProvider();
198629
198747
  init_providerClient();
198630
- init_modalLifecycle();
198748
+ init_modalCommandContext();
198631
198749
  init_sessionUtils();
198632
198750
  DEFAULT_TTY_COLS = 80;
198633
198751
  DEFAULT_TTY_ROWS = 24;
@@ -199561,73 +199679,27 @@ var init_connect2 = __esm({
199561
199679
  let networkTargetHost = null;
199562
199680
  if (computeProvider === "modal") {
199563
199681
  stage("Loading modal auth");
199564
- const config4 = await loadConfig(
199565
- process.env.HOME ? { homeDir: process.env.HOME } : void 0
199566
- );
199567
- const store = await createSecretStore(
199568
- config4?.tokenStore,
199569
- process.env.HOME ? { homeDir: process.env.HOME } : void 0
199570
- );
199571
- const modalCredentialContext = createProviderCredentialContext({
199572
- mode: "auto",
199573
- controlPlaneToken: await store.getControlPlaneToken()
199574
- });
199575
- let modalOperationOptions = await resolveModalCommandOperationOptions({
199576
- credentials: modalCredentialContext,
199577
- cwd: process.cwd()
199682
+ const modalContext = await resolveModalCommandContext({
199683
+ alias: spriteAlias,
199684
+ cwd: process.cwd(),
199685
+ stage
199578
199686
  });
199579
- if (modalOperationOptions.credentialMode === "shared" && (!modalOperationOptions.credentials.modalTokenId || !modalOperationOptions.credentials.modalTokenSecret)) {
199580
- const controlPlaneToken2 = await ensureControlPlaneToken(store, stage);
199581
- if (controlPlaneToken2) {
199582
- modalOperationOptions = await resolveModalCommandOperationOptions({
199583
- credentials: createProviderCredentialContext({
199584
- mode: "auto",
199585
- controlPlaneToken: controlPlaneToken2
199586
- }),
199587
- cwd: process.cwd()
199588
- });
199589
- }
199590
- }
199591
- let controlPlaneToken = modalCredentialContext.controlPlaneToken;
199592
199687
  const ensureActive = async (intent) => {
199593
- if (!controlPlaneToken) {
199594
- controlPlaneToken = await ensureControlPlaneToken(store, stage);
199595
- }
199596
- if (!controlPlaneToken) {
199597
- throw new Error(
199598
- "Control plane authentication is required to wake modal devboxes. Run `dvb setup` and retry."
199599
- );
199600
- }
199601
- const ensured = await ensureModalDevboxActive2(
199602
- controlPlaneToken,
199603
- spriteAlias,
199604
- intent
199605
- );
199688
+ const ensured2 = await modalContext.ensureActive(intent);
199606
199689
  return {
199607
- appName: ensured.appName,
199608
- sandboxId: ensured.sandboxId
199690
+ appName: ensured2.appName,
199691
+ sandboxId: ensured2.sandboxId
199609
199692
  };
199610
199693
  };
199611
- stage("Checking modal sandbox");
199612
- const sandbox = await findModalSandbox(
199613
- {
199614
- alias: spriteAlias,
199615
- includeFinished: true
199616
- },
199617
- modalOperationOptions
199618
- );
199619
- let appName = sandbox?.appName ?? "";
199620
- let sandboxId = sandbox?.sandboxId ?? "";
199621
- if (!appName || !sandboxId) {
199622
- const ensured = await ensureActive("shell");
199623
- appName = ensured.appName;
199624
- sandboxId = ensured.sandboxId;
199625
- }
199694
+ stage("Ensuring modal sandbox");
199695
+ const ensured = await ensureActive("shell");
199696
+ const appName = ensured.appName;
199697
+ const sandboxId = ensured.sandboxId;
199626
199698
  client2 = createModalConnectSpritesClient({
199627
199699
  alias: spriteAlias,
199628
199700
  appName,
199629
199701
  sandboxId,
199630
- operationOptions: modalOperationOptions,
199702
+ operationOptions: modalContext.operationOptions,
199631
199703
  ensureActive
199632
199704
  });
199633
199705
  } else {
@@ -202983,7 +203055,7 @@ var init_registry2 = __esm({
202983
203055
  });
202984
203056
 
202985
203057
  // src/devbox/commands/mountSsh.ts
202986
- var import_node_child_process7, import_promises19, import_node_os12, import_node_path23, DEVBOX_SSH_DIR, MOUNT_KEY_PATH, MOUNT_PUBLIC_KEY_PATH, KNOWN_HOSTS_PATH, REMOTE_SSH_DIR, REMOTE_AUTH_KEYS, REMOTE_SSHD_CONFIG, SSHD_SERVICE_NAME, REMOTE_SSH_USER_PATTERN, shellEscape, runCommand4, ensureDevboxSshDir, ensureKnownHostsFile, ensureLocalMountKey, readLocalMountPublicKey, resolveRemoteSshUser, buildSshdConfig, ensureRemoteMountAccess, ensureSshdService;
203058
+ var import_node_child_process7, import_promises19, import_node_os12, import_node_path23, DEVBOX_SSH_DIR, MOUNT_KEY_PATH, MOUNT_PUBLIC_KEY_PATH, KNOWN_HOSTS_PATH, REMOTE_MOUNT_ROOT, REMOTE_SSH_DIR, REMOTE_AUTH_KEYS, REMOTE_SSHD_CONFIG, SSHD_SERVICE_NAME, REMOTE_SSH_USER_PATTERN, shellEscape, runCommand4, ensureDevboxSshDir, ensureKnownHostsFile, ensureLocalMountKey, readLocalMountPublicKey, ensureRemoteMountRoot, resolveRemoteSshUser, buildSshdConfig, ensureRemoteMountAccess, ensureSshdService, getRemoteMountRoot;
202987
203059
  var init_mountSsh = __esm({
202988
203060
  "src/devbox/commands/mountSsh.ts"() {
202989
203061
  "use strict";
@@ -202996,7 +203068,8 @@ var init_mountSsh = __esm({
202996
203068
  MOUNT_KEY_PATH = import_node_path23.default.join(DEVBOX_SSH_DIR, "mount_ed25519");
202997
203069
  MOUNT_PUBLIC_KEY_PATH = `${MOUNT_KEY_PATH}.pub`;
202998
203070
  KNOWN_HOSTS_PATH = import_node_path23.default.join(DEVBOX_SSH_DIR, "known_hosts");
202999
- REMOTE_SSH_DIR = "/home/sprite/.devbox/ssh";
203071
+ REMOTE_MOUNT_ROOT = "/home/sprite";
203072
+ REMOTE_SSH_DIR = `${REMOTE_MOUNT_ROOT}/.devbox/ssh`;
203000
203073
  REMOTE_AUTH_KEYS = `${REMOTE_SSH_DIR}/authorized_keys`;
203001
203074
  REMOTE_SSHD_CONFIG = `${REMOTE_SSH_DIR}/sshd_config`;
203002
203075
  SSHD_SERVICE_NAME = "devbox-sshd";
@@ -203056,6 +203129,25 @@ var init_mountSsh = __esm({
203056
203129
  }
203057
203130
  return trimmed;
203058
203131
  };
203132
+ ensureRemoteMountRoot = async (client2, spriteName) => {
203133
+ const result = await client2.exec(spriteName, [
203134
+ "/bin/bash",
203135
+ "-lc",
203136
+ `test -d ${shellEscape(REMOTE_MOUNT_ROOT)}`
203137
+ ]);
203138
+ if (result.exitCode === 0) {
203139
+ return;
203140
+ }
203141
+ const stderr = result.stderr.trim();
203142
+ const stdout = result.stdout.trim();
203143
+ const combined = [stderr, stdout].filter(Boolean).join("\n");
203144
+ const details = combined ? `
203145
+
203146
+ ${combined}` : "";
203147
+ throw new Error(
203148
+ `Remote mount root "${REMOTE_MOUNT_ROOT}" is missing or inaccessible. Run \`dvb init --resume\` for this devbox before mounting.${details}`
203149
+ );
203150
+ };
203059
203151
  resolveRemoteSshUser = async (client2, spriteName) => {
203060
203152
  const detectScript = [
203061
203153
  "set -euo pipefail",
@@ -203132,9 +203224,9 @@ ${combined}` : "";
203132
203224
  " sudo -n DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openssh-server",
203133
203225
  " fi",
203134
203226
  "fi",
203135
- "sudo -n mkdir -p /home/sprite/.devbox/ssh",
203136
- `sudo -n chown ${shellEscape(sshUser)}:${shellEscape(sshUser)} /home/sprite/.devbox/ssh`,
203137
- "sudo -n chmod 700 /home/sprite/.devbox/ssh",
203227
+ `sudo -n mkdir -p ${shellEscape(REMOTE_SSH_DIR)}`,
203228
+ `sudo -n chown ${shellEscape(sshUser)}:${shellEscape(sshUser)} ${shellEscape(REMOTE_SSH_DIR)}`,
203229
+ `sudo -n chmod 700 ${shellEscape(REMOTE_SSH_DIR)}`,
203138
203230
  ...sshUser === "root" ? [] : [
203139
203231
  `account_status=$(sudo -n passwd -S ${shellEscape(sshUser)} 2>/dev/null | awk '{print $2}' || true)`,
203140
203232
  'if [ "$account_status" = "L" ]; then',
@@ -203205,6 +203297,7 @@ ${combined}` : "";
203205
203297
  });
203206
203298
  }
203207
203299
  };
203300
+ getRemoteMountRoot = () => REMOTE_MOUNT_ROOT;
203208
203301
  }
203209
203302
  });
203210
203303
 
@@ -210772,7 +210865,7 @@ var init_logout = __esm({
210772
210865
  });
210773
210866
 
210774
210867
  // src/devbox/commands/mount.ts
210775
- var import_node_child_process11, import_promises29, import_node_os19, import_node_path35, parseMountArgs, resolveMountDir, commandExists, ensureLocalDependencies, resolveSpriteAlias, runCommand5, forwardSshPort, stopSshPort, unmount, runMount, runUnmount;
210868
+ var import_node_child_process11, import_promises29, import_node_os19, import_node_path35, parseMountArgs, resolveMountDir, commandExists, ensureLocalDependencies, resolveSpritesMountRuntimeClient, resolveModalMountRuntimeClient, resolveMountRuntimeClient, resolveSpriteAlias, runCommand5, forwardSshPort, stopSshPort, resolveMountProviderTarget, unmount, runMount, runUnmount;
210776
210869
  var init_mount = __esm({
210777
210870
  "src/devbox/commands/mount.ts"() {
210778
210871
  "use strict";
@@ -210786,7 +210879,10 @@ var init_mount = __esm({
210786
210879
  init_logger3();
210787
210880
  init_boxSelect();
210788
210881
  init_commandProvider();
210882
+ init_modalRuntime();
210789
210883
  init_mountSsh();
210884
+ init_modalCommandContext();
210885
+ init_modalLifecycle();
210790
210886
  parseMountArgs = (args) => {
210791
210887
  const parsed = {};
210792
210888
  for (const arg of args) {
@@ -210817,6 +210913,86 @@ var init_mount = __esm({
210817
210913
  throw new Error("Missing ssh client.");
210818
210914
  }
210819
210915
  };
210916
+ resolveSpritesMountRuntimeClient = async () => {
210917
+ const config4 = await loadConfig(
210918
+ process.env.HOME ? { homeDir: process.env.HOME } : void 0
210919
+ );
210920
+ const store = await createSecretStore(
210921
+ config4?.tokenStore,
210922
+ process.env.HOME ? { homeDir: process.env.HOME } : void 0
210923
+ );
210924
+ const apiBaseUrl = resolveSpritesApiUrl(config4);
210925
+ const { token } = await ensureSpritesToken(store, void 0, {
210926
+ apiBaseUrl
210927
+ });
210928
+ return createSpritesClient({ apiBaseUrl, token });
210929
+ };
210930
+ resolveModalMountRuntimeClient = async (options, dependencies = {}) => {
210931
+ const resolveModalContext = dependencies.resolveModalContext ?? resolveModalCommandContext;
210932
+ const findSandbox = dependencies.findSandbox ?? findModalSandbox;
210933
+ const createRuntimeClient = dependencies.createRuntimeClient ?? createModalInitRuntimeClient;
210934
+ const modalContext = await resolveModalContext({
210935
+ alias: options.alias,
210936
+ cwd: options.cwd
210937
+ });
210938
+ const sandbox = await findSandbox(
210939
+ {
210940
+ alias: options.alias,
210941
+ includeFinished: true
210942
+ },
210943
+ modalContext.operationOptions
210944
+ );
210945
+ let appName = sandbox?.appName ?? "";
210946
+ let sandboxId = sandbox?.sandboxId ?? "";
210947
+ if (!sandbox || sandbox.status !== "running") {
210948
+ try {
210949
+ const ensured = await modalContext.ensureActive("proxy");
210950
+ appName = ensured.appName;
210951
+ sandboxId = ensured.sandboxId;
210952
+ } catch (error2) {
210953
+ const reason = error2 instanceof Error ? error2.message : String(error2);
210954
+ if (!sandbox) {
210955
+ throw new Error(
210956
+ `No running modal sandbox found named "${options.targetBox}" and it could not be resumed for mount.
210957
+
210958
+ ${reason}`
210959
+ );
210960
+ }
210961
+ throw new Error(
210962
+ `Modal sandbox "${options.targetBox}" is ${sandbox.status} and could not be resumed for mount.
210963
+
210964
+ ${reason}`
210965
+ );
210966
+ }
210967
+ }
210968
+ return createRuntimeClient({
210969
+ alias: options.alias,
210970
+ appName,
210971
+ sandboxId,
210972
+ credentialMode: modalContext.operationOptions.credentialMode,
210973
+ credentials: modalContext.operationOptions.credentials,
210974
+ ...modalContext.operationOptions.cwd ? { cwd: modalContext.operationOptions.cwd } : {},
210975
+ ensureActive: async (intent) => {
210976
+ const ensured = await modalContext.ensureActive(intent);
210977
+ return {
210978
+ appName: ensured.appName,
210979
+ sandboxId: ensured.sandboxId
210980
+ };
210981
+ }
210982
+ });
210983
+ };
210984
+ resolveMountRuntimeClient = async (options, dependencies = {}) => {
210985
+ if (options.provider === "modal") {
210986
+ const resolveModalRuntimeClient = dependencies.resolveModalRuntimeClient ?? (async (modalOptions) => await resolveModalMountRuntimeClient(modalOptions));
210987
+ return await resolveModalRuntimeClient({
210988
+ alias: options.alias,
210989
+ targetBox: options.targetBox,
210990
+ cwd: options.cwd
210991
+ });
210992
+ }
210993
+ const resolveSpritesRuntimeClient = dependencies.resolveSpritesRuntimeClient ?? resolveSpritesMountRuntimeClient;
210994
+ return await resolveSpritesRuntimeClient();
210995
+ };
210820
210996
  resolveSpriteAlias = async (_socketPath, box) => box;
210821
210997
  runCommand5 = (command, args, options = {}) => new Promise((resolve2, reject) => {
210822
210998
  const child = (0, import_node_child_process11.spawn)(command, args, {
@@ -210855,28 +211031,8 @@ var init_mount = __esm({
210855
211031
  throw new Error(`dvbd error: ${response.status}`);
210856
211032
  }
210857
211033
  };
210858
- unmount = async (mountDir) => {
210859
- const command = process.platform === "darwin" ? "diskutil" : "umount";
210860
- const args = process.platform === "darwin" ? ["unmount", mountDir] : [mountDir];
210861
- const exitCode = await runCommand5(command, args);
210862
- if (exitCode !== 0) {
210863
- throw new Error(`Failed to unmount ${mountDir}`);
210864
- }
210865
- };
210866
- runMount = async (args) => {
210867
- const parsed = parseMountArgs(args);
210868
- let targetBox = parsed.box;
210869
- if (!targetBox) {
210870
- const selected = await selectDevbox(
210871
- "Use `dvb mount <box>` to target a specific box."
210872
- );
210873
- if (!selected) return;
210874
- targetBox = selected.box;
210875
- }
210876
- const socketInfo = resolveSocketInfo();
210877
- await ensureDaemonRunning(socketInfo.socketPath);
210878
- await requireDaemonFeatures(socketInfo.socketPath, ["ports.forward"]);
210879
- let spriteAlias = await resolveSpriteAlias(socketInfo.socketPath, targetBox);
211034
+ resolveMountProviderTarget = async (socketPath, targetBox) => {
211035
+ const spriteAlias = await resolveSpriteAlias(socketPath, targetBox);
210880
211036
  let providerLookupBoxes = null;
210881
211037
  try {
210882
211038
  providerLookupBoxes = await listDevboxes();
@@ -210886,14 +211042,14 @@ var init_mount = __esm({
210886
211042
  error: String(error2)
210887
211043
  });
210888
211044
  }
210889
- const providerTarget = await resolveCommandComputeProvider({
211045
+ return await resolveCommandComputeProvider({
210890
211046
  box: spriteAlias,
210891
211047
  boxes: providerLookupBoxes,
210892
211048
  homeDir: process.env.HOME ?? import_node_os19.default.homedir(),
210893
211049
  persistAssumedComputeProvider: async ({ alias, computeProvider }) => {
210894
211050
  try {
210895
211051
  const response = await requestJson3(
210896
- socketInfo.socketPath,
211052
+ socketPath,
210897
211053
  "POST",
210898
211054
  "/registry/upsert",
210899
211055
  DAEMON_TIMEOUT_MS.registry,
@@ -210919,26 +211075,49 @@ var init_mount = __esm({
210919
211075
  }
210920
211076
  }
210921
211077
  });
211078
+ };
211079
+ unmount = async (mountDir) => {
211080
+ const command = process.platform === "darwin" ? "diskutil" : "umount";
211081
+ const args = process.platform === "darwin" ? ["unmount", mountDir] : [mountDir];
211082
+ const exitCode = await runCommand5(command, args);
211083
+ if (exitCode !== 0) {
211084
+ throw new Error(`Failed to unmount ${mountDir}`);
211085
+ }
211086
+ };
211087
+ runMount = async (args) => {
211088
+ const parsed = parseMountArgs(args);
211089
+ let targetBox = parsed.box;
211090
+ if (!targetBox) {
211091
+ const selected = await selectDevbox(
211092
+ "Use `dvb mount <box>` to target a specific box."
211093
+ );
211094
+ if (!selected) return;
211095
+ targetBox = selected.box;
211096
+ }
211097
+ const socketInfo = resolveSocketInfo();
211098
+ await ensureDaemonRunning(socketInfo.socketPath);
211099
+ await requireDaemonFeatures(socketInfo.socketPath, ["ports.forward"]);
211100
+ const providerTarget = await resolveMountProviderTarget(
211101
+ socketInfo.socketPath,
211102
+ targetBox
211103
+ );
210922
211104
  assertCommandProviderCapability({
210923
211105
  provider: providerTarget.computeProvider,
210924
211106
  command: "mount",
210925
211107
  capability: "files.read"
210926
211108
  });
210927
- spriteAlias = providerTarget.alias;
211109
+ const spriteAlias = providerTarget.alias;
210928
211110
  ensureLocalDependencies();
210929
- const config4 = await loadConfig(
210930
- process.env.HOME ? { homeDir: process.env.HOME } : void 0
210931
- );
210932
- const store = await createSecretStore(
210933
- config4?.tokenStore,
210934
- process.env.HOME ? { homeDir: process.env.HOME } : void 0
210935
- );
210936
- const apiBaseUrl = resolveSpritesApiUrl(config4);
210937
- const { token } = await ensureSpritesToken(store, void 0, { apiBaseUrl });
210938
- const client2 = createSpritesClient({ apiBaseUrl, token });
211111
+ const client2 = await resolveMountRuntimeClient({
211112
+ provider: providerTarget.computeProvider,
211113
+ alias: spriteAlias,
211114
+ targetBox,
211115
+ cwd: process.cwd()
211116
+ });
210939
211117
  const { privateKeyPath } = await ensureLocalMountKey();
210940
211118
  const publicKey = await readLocalMountPublicKey();
210941
211119
  const knownHostsPath = await ensureKnownHostsFile();
211120
+ await ensureRemoteMountRoot(client2, spriteAlias);
210942
211121
  const remoteMountAccess = await ensureRemoteMountAccess(
210943
211122
  client2,
210944
211123
  spriteAlias,
@@ -210959,12 +211138,24 @@ var init_mount = __esm({
210959
211138
  "StrictHostKeyChecking=accept-new",
210960
211139
  "-p",
210961
211140
  String(localPort),
210962
- `${remoteMountAccess.sshUser}@localhost:/home/sprite`,
211141
+ `${remoteMountAccess.sshUser}@localhost:${getRemoteMountRoot()}`,
210963
211142
  mountDir
210964
211143
  ];
210965
- const exitCode = await runCommand5("sshfs", sshfsArgs);
210966
- if (exitCode !== 0) {
210967
- throw new Error("sshfs failed to mount.");
211144
+ try {
211145
+ const exitCode = await runCommand5("sshfs", sshfsArgs);
211146
+ if (exitCode !== 0) {
211147
+ throw new Error("sshfs failed to mount.");
211148
+ }
211149
+ } catch (error2) {
211150
+ try {
211151
+ await stopSshPort(socketInfo.socketPath, spriteAlias);
211152
+ } catch (stopError) {
211153
+ logger7.warn("mount_forward_cleanup_failed", {
211154
+ box: spriteAlias,
211155
+ error: String(stopError)
211156
+ });
211157
+ }
211158
+ throw error2;
210968
211159
  }
210969
211160
  console.log(`Mounted ${spriteAlias} at ${mountDir}`);
210970
211161
  };
@@ -210981,10 +211172,11 @@ var init_mount = __esm({
210981
211172
  const socketInfo = resolveSocketInfo();
210982
211173
  await ensureDaemonRunning(socketInfo.socketPath);
210983
211174
  await requireDaemonFeatures(socketInfo.socketPath, ["ports.forward"]);
210984
- const spriteAlias = await resolveSpriteAlias(
211175
+ const providerTarget = await resolveMountProviderTarget(
210985
211176
  socketInfo.socketPath,
210986
211177
  targetBox
210987
211178
  );
211179
+ const spriteAlias = providerTarget.alias;
210988
211180
  const mountDir = resolveMountDir(spriteAlias);
210989
211181
  await unmount(mountDir);
210990
211182
  await stopSshPort(socketInfo.socketPath, spriteAlias);
@@ -215926,4 +216118,4 @@ smol-toml/dist/index.js:
215926
216118
  */
215927
216119
  //# sourceMappingURL=dvb.cjs.map
215928
216120
 
215929
- //# debugId=b688f344-5d53-57d8-9464-1da40ea2bc02
216121
+ //# debugId=4d4f5269-c2cd-5397-a6d4-993b4d24cfdc