@boxes-dev/dvb 1.0.53 → 1.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/bin/dvb.cjs +519 -149
  2. package/dist/bin/dvb.cjs.map +1 -1
  3. package/dist/bin/dvbd.cjs +5 -5
  4. package/dist/devbox/commands/commandProvider.d.ts +6 -1
  5. package/dist/devbox/commands/commandProvider.d.ts.map +1 -1
  6. package/dist/devbox/commands/commandProvider.js +21 -2
  7. package/dist/devbox/commands/commandProvider.js.map +1 -1
  8. package/dist/devbox/commands/connect.d.ts.map +1 -1
  9. package/dist/devbox/commands/connect.js +23 -18
  10. package/dist/devbox/commands/connect.js.map +1 -1
  11. package/dist/devbox/commands/init/finalizeFlow.d.ts.map +1 -1
  12. package/dist/devbox/commands/init/finalizeFlow.js +9 -2
  13. package/dist/devbox/commands/init/finalizeFlow.js.map +1 -1
  14. package/dist/devbox/commands/init/index.d.ts.map +1 -1
  15. package/dist/devbox/commands/init/index.js +1 -0
  16. package/dist/devbox/commands/init/index.js.map +1 -1
  17. package/dist/devbox/commands/init/provider/modalRuntime.d.ts.map +1 -1
  18. package/dist/devbox/commands/init/provider/modalRuntime.js +229 -3
  19. package/dist/devbox/commands/init/provider/modalRuntime.js.map +1 -1
  20. package/dist/devbox/commands/init/provider/types.d.ts +1 -1
  21. package/dist/devbox/commands/init/provider/types.d.ts.map +1 -1
  22. package/dist/devbox/commands/init/remote.d.ts +2 -1
  23. package/dist/devbox/commands/init/remote.d.ts.map +1 -1
  24. package/dist/devbox/commands/init/remote.js +32 -2
  25. package/dist/devbox/commands/init/remote.js.map +1 -1
  26. package/dist/devbox/commands/init/setupPlanFlow.d.ts.map +1 -1
  27. package/dist/devbox/commands/init/setupPlanFlow.js +1 -18
  28. package/dist/devbox/commands/init/setupPlanFlow.js.map +1 -1
  29. package/dist/devbox/commands/provider/modalLifecycle.d.ts +1 -0
  30. package/dist/devbox/commands/provider/modalLifecycle.d.ts.map +1 -1
  31. package/dist/devbox/commands/provider/modalLifecycle.js +17 -0
  32. package/dist/devbox/commands/provider/modalLifecycle.js.map +1 -1
  33. package/dist/devbox/commands/providerClient.d.ts +3 -1
  34. package/dist/devbox/commands/providerClient.d.ts.map +1 -1
  35. package/dist/devbox/commands/providerClient.js +14 -13
  36. package/dist/devbox/commands/providerClient.js.map +1 -1
  37. package/dist/devbox/commands/sessions.d.ts.map +1 -1
  38. package/dist/devbox/commands/sessions.js +110 -30
  39. package/dist/devbox/commands/sessions.js.map +1 -1
  40. package/package.json +1 -1
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]="5b27d1b2-cb5a-5370-b4ca-61330f7946e5")}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]="b688f344-5d53-57d8-9464-1da40ea2bc02")}catch(e){}}();
4
4
 
5
5
  var __create = Object.create;
6
6
  var __defProp = Object.defineProperty;
@@ -21725,7 +21725,7 @@ var require_ProcessDetector = __commonJS({
21725
21725
  exports2.processDetector = void 0;
21726
21726
  var api_1 = require_src();
21727
21727
  var semconv_1 = require_semconv5();
21728
- var os23 = require("os");
21728
+ var os24 = require("os");
21729
21729
  var ProcessDetector = class {
21730
21730
  detect(_config) {
21731
21731
  const attributes = {
@@ -21745,7 +21745,7 @@ var require_ProcessDetector = __commonJS({
21745
21745
  attributes[semconv_1.ATTR_PROCESS_COMMAND] = process.argv[1];
21746
21746
  }
21747
21747
  try {
21748
- const userInfo = os23.userInfo();
21748
+ const userInfo = os24.userInfo();
21749
21749
  attributes[semconv_1.ATTR_PROCESS_OWNER] = userInfo.username;
21750
21750
  } catch (e2) {
21751
21751
  api_1.diag.debug(`error obtaining process owner: ${e2}`);
@@ -37305,7 +37305,7 @@ var require_service_config = __commonJS({
37305
37305
  exports2.validateRetryThrottling = validateRetryThrottling;
37306
37306
  exports2.validateServiceConfig = validateServiceConfig;
37307
37307
  exports2.extractAndSelectServiceConfig = extractAndSelectServiceConfig;
37308
- var os23 = require("os");
37308
+ var os24 = require("os");
37309
37309
  var constants_1 = require_constants9();
37310
37310
  var DURATION_REGEX = /^\d+(\.\d{1,9})?s$/;
37311
37311
  var CLIENT_LANGUAGE_STRING = "node";
@@ -37604,7 +37604,7 @@ var require_service_config = __commonJS({
37604
37604
  if (Array.isArray(validatedConfig.clientHostname)) {
37605
37605
  let hostnameMatched = false;
37606
37606
  for (const hostname2 of validatedConfig.clientHostname) {
37607
- if (hostname2 === os23.hostname()) {
37607
+ if (hostname2 === os24.hostname()) {
37608
37608
  hostnameMatched = true;
37609
37609
  }
37610
37610
  }
@@ -51408,7 +51408,7 @@ var require_subchannel_call = __commonJS({
51408
51408
  Object.defineProperty(exports2, "__esModule", { value: true });
51409
51409
  exports2.Http2SubchannelCall = void 0;
51410
51410
  var http22 = require("http2");
51411
- var os23 = require("os");
51411
+ var os24 = require("os");
51412
51412
  var constants_1 = require_constants9();
51413
51413
  var metadata_1 = require_metadata();
51414
51414
  var stream_decoder_1 = require_stream_decoder();
@@ -51416,7 +51416,7 @@ var require_subchannel_call = __commonJS({
51416
51416
  var constants_2 = require_constants9();
51417
51417
  var TRACER_NAME = "subchannel_call";
51418
51418
  function getSystemErrorName(errno) {
51419
- for (const [name, num] of Object.entries(os23.constants.errno)) {
51419
+ for (const [name, num] of Object.entries(os24.constants.errno)) {
51420
51420
  if (num === errno) {
51421
51421
  return name;
51422
51422
  }
@@ -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.53";
88687
- const rawGitSha = "cf1d2a8bda7651429d5043ead7b5caf47d35e42d";
88686
+ const rawPackageVersion = "1.0.54";
88687
+ const rawGitSha = "9b08274a528c685a1a8720a6c9af9946e2a99af5";
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.53";
120676
- const rawGitSha = "cf1d2a8bda7651429d5043ead7b5caf47d35e42d";
120677
- const rawSentryRelease = "boxes-dev-dvb@1.0.53+cf1d2a8bda7651429d5043ead7b5caf47d35e42d";
120675
+ const rawPackageVersion = "1.0.54";
120676
+ const rawGitSha = "9b08274a528c685a1a8720a6c9af9946e2a99af5";
120677
+ const rawSentryRelease = "boxes-dev-dvb@1.0.54+9b08274a528c685a1a8720a6c9af9946e2a99af5";
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;
@@ -182511,14 +182511,14 @@ var init_simple_client_node = __esm({
182511
182511
  "../common/temp/node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/node-gyp-build.js"(exports2, module2) {
182512
182512
  var fs29 = __require("fs");
182513
182513
  var path38 = __require("path");
182514
- var os23 = __require("os");
182514
+ var os24 = __require("os");
182515
182515
  var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
182516
182516
  var vars = process.config && process.config.variables || {};
182517
182517
  var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
182518
182518
  var abi = process.versions.modules;
182519
182519
  var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
182520
- var arch2 = process.env.npm_config_arch || os23.arch();
182521
- var platform2 = process.env.npm_config_platform || os23.platform();
182520
+ var arch2 = process.env.npm_config_arch || os24.arch();
182521
+ var platform2 = process.env.npm_config_platform || os24.platform();
182522
182522
  var libc = process.env.LIBC || (isAlpine(platform2) ? "musl" : "glibc");
182523
182523
  var armv = process.env.ARM_VERSION || (arch2 === "arm64" ? "8" : vars.arm_version) || "";
182524
182524
  var uv = (process.versions.uv || "").split(".")[0];
@@ -197021,12 +197021,18 @@ var init_destroyLocalState = __esm({
197021
197021
  });
197022
197022
 
197023
197023
  // src/devbox/commands/commandProvider.ts
197024
- var normalizeBoxKey, resolveRegistryEntry, resolveCommandComputeProvider, assertCommandProviderCapability;
197024
+ var MODAL_CONNECT_CAPABILITIES, normalizeBoxKey, resolveRegistryEntry, resolveCommandComputeProvider, assertCommandProviderCapability, hasCommandProviderCapability;
197025
197025
  var init_commandProvider = __esm({
197026
197026
  "src/devbox/commands/commandProvider.ts"() {
197027
197027
  "use strict";
197028
197028
  init_src();
197029
197029
  init_destroyLocalState();
197030
+ MODAL_CONNECT_CAPABILITIES = /* @__PURE__ */ new Set([
197031
+ "exec.sessions.open",
197032
+ "exec.sessions.attach",
197033
+ "exec.sessions.list",
197034
+ "exec.sessions.kill"
197035
+ ]);
197030
197036
  normalizeBoxKey = (value) => {
197031
197037
  if (typeof value !== "string") return null;
197032
197038
  const trimmed = value.trim();
@@ -197081,7 +197087,7 @@ var init_commandProvider = __esm({
197081
197087
  if (provider === "sprites") {
197082
197088
  return;
197083
197089
  }
197084
- if (provider === "modal" && command === "connect" && capability === "exec.sessions.open") {
197090
+ if (provider === "modal" && command === "connect" && MODAL_CONNECT_CAPABILITIES.has(capability)) {
197085
197091
  return;
197086
197092
  }
197087
197093
  throw new ProviderCapabilityError({
@@ -197091,14 +197097,30 @@ var init_commandProvider = __esm({
197091
197097
  message: `dvb ${command} does not support ${provider} devboxes yet.`
197092
197098
  });
197093
197099
  };
197100
+ hasCommandProviderCapability = ({
197101
+ provider,
197102
+ command,
197103
+ capability
197104
+ }) => {
197105
+ try {
197106
+ assertCommandProviderCapability({ provider, command, capability });
197107
+ return true;
197108
+ } catch (error2) {
197109
+ if (error2 instanceof ProviderCapabilityError && error2.code === "unsupported_capability") {
197110
+ return false;
197111
+ }
197112
+ throw error2;
197113
+ }
197114
+ };
197094
197115
  }
197095
197116
  });
197096
197117
 
197097
197118
  // src/devbox/commands/init/provider/modalRuntime.ts
197098
- var 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, serviceMetaPath, serviceRunnerPath, servicePidPath, serviceLogPath, validateServiceName, isSandboxNotFoundError2, resolveReadPath, buildWsUrlFromConnectToken, decodeBase642, parseJsonRecord2, readCreateConnectToken2, ModalDaemonExecSocket, createModalInitRuntimeClient;
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;
197099
197120
  var init_modalRuntime = __esm({
197100
197121
  "src/devbox/commands/init/provider/modalRuntime.ts"() {
197101
197122
  "use strict";
197123
+ import_node_crypto8 = require("node:crypto");
197102
197124
  import_node_path16 = __toESM(require("node:path"), 1);
197103
197125
  init_dist3();
197104
197126
  import_ws3 = __toESM(require("ws"), 1);
@@ -197112,6 +197134,8 @@ var init_modalRuntime = __esm({
197112
197134
  shellQuote2 = (value) => `'${value.replace(/'/g, `'\\''`)}'`;
197113
197135
  MODAL_EXEC_WS_PATH2 = "/ws";
197114
197136
  MODAL_CONNECT_TOKEN_QUERY2 = "_modal_connect_token";
197137
+ MODAL_DAEMON_HANDSHAKE_TIMEOUT_MS = 1e4;
197138
+ MODAL_DAEMON_REQUEST_TIMEOUT_MS = 15e3;
197115
197139
  serviceMetaPath = (service) => `${SERVICE_BASE_DIR}/${service}${SERVICE_META_SUFFIX}`;
197116
197140
  serviceRunnerPath = (service) => `${SERVICE_BASE_DIR}/${service}${SERVICE_RUN_SUFFIX}`;
197117
197141
  servicePidPath = (service) => `${SERVICE_BASE_DIR}/${service}${SERVICE_PID_SUFFIX}`;
@@ -197174,6 +197198,122 @@ var init_modalRuntime = __esm({
197174
197198
  }
197175
197199
  return candidate.createConnectToken.bind(candidate);
197176
197200
  };
197201
+ withTimeout2 = async (promise, timeoutMs, message) => {
197202
+ let timeout = null;
197203
+ try {
197204
+ return await Promise.race([
197205
+ promise,
197206
+ new Promise((_2, reject) => {
197207
+ timeout = setTimeout(() => {
197208
+ reject(new Error(message));
197209
+ }, timeoutMs);
197210
+ timeout.unref();
197211
+ })
197212
+ ]);
197213
+ } finally {
197214
+ if (timeout) {
197215
+ clearTimeout(timeout);
197216
+ }
197217
+ }
197218
+ };
197219
+ connectModalDaemonWebSocket = async (sandbox) => {
197220
+ const resolvedSandbox = await sandbox;
197221
+ const createConnectToken = readCreateConnectToken2(resolvedSandbox);
197222
+ const credentials = await createConnectToken();
197223
+ const wsUrl = buildWsUrlFromConnectToken(credentials);
197224
+ const ws = new import_ws3.default(wsUrl);
197225
+ await withTimeout2(
197226
+ new Promise((resolve2, reject) => {
197227
+ const onOpen = () => {
197228
+ ws.off("error", onError);
197229
+ resolve2();
197230
+ };
197231
+ const onError = (error2) => {
197232
+ ws.off("open", onOpen);
197233
+ reject(error2);
197234
+ };
197235
+ ws.once("open", onOpen);
197236
+ ws.once("error", onError);
197237
+ }),
197238
+ MODAL_DAEMON_HANDSHAKE_TIMEOUT_MS,
197239
+ "Timed out connecting to modal daemon websocket."
197240
+ );
197241
+ return ws;
197242
+ };
197243
+ awaitModalDaemonMessage = async (ws, matcher) => await withTimeout2(
197244
+ new Promise((resolve2, reject) => {
197245
+ const onMessage = (raw) => {
197246
+ const parsed = parseJsonRecord2(raw);
197247
+ if (!parsed) {
197248
+ return;
197249
+ }
197250
+ if (parsed.type === "error") {
197251
+ cleanup();
197252
+ const reason = typeof parsed.message === "string" ? parsed.message : "modal daemon error";
197253
+ reject(new Error(reason));
197254
+ return;
197255
+ }
197256
+ if (!matcher(parsed)) {
197257
+ return;
197258
+ }
197259
+ cleanup();
197260
+ resolve2(parsed);
197261
+ };
197262
+ const onClose = (code2, reason) => {
197263
+ cleanup();
197264
+ reject(
197265
+ new Error(
197266
+ `Modal daemon socket closed (${String(code2)}): ${reason.toString("utf8") || "no reason"}`
197267
+ )
197268
+ );
197269
+ };
197270
+ const onError = (error2) => {
197271
+ cleanup();
197272
+ reject(error2);
197273
+ };
197274
+ const cleanup = () => {
197275
+ ws.off("message", onMessage);
197276
+ ws.off("close", onClose);
197277
+ ws.off("error", onError);
197278
+ };
197279
+ ws.on("message", onMessage);
197280
+ ws.once("close", onClose);
197281
+ ws.once("error", onError);
197282
+ }),
197283
+ MODAL_DAEMON_REQUEST_TIMEOUT_MS,
197284
+ "Timed out waiting for modal daemon response."
197285
+ );
197286
+ parseControlError = (message) => {
197287
+ const errorPayload = message.error && typeof message.error === "object" ? message.error : null;
197288
+ const code2 = errorPayload && typeof errorPayload.code === "string" ? errorPayload.code : null;
197289
+ const text = errorPayload && typeof errorPayload.message === "string" ? errorPayload.message : typeof message.message === "string" ? message.message : "Modal daemon control request failed.";
197290
+ return { code: code2, text };
197291
+ };
197292
+ mapControlSessionRecord = (entry) => {
197293
+ if (!entry || typeof entry !== "object") {
197294
+ return null;
197295
+ }
197296
+ const record = entry;
197297
+ const id = typeof record.id === "string" ? record.id : "";
197298
+ if (!id) {
197299
+ return null;
197300
+ }
197301
+ const command = Array.isArray(record.command) ? record.command.map((part) => String(part)) : void 0;
197302
+ const createdAt = typeof record.createdAt === "string" ? record.createdAt : void 0;
197303
+ const lastActivityAt = typeof record.lastActivityAt === "string" ? record.lastActivityAt : void 0;
197304
+ const tty2 = typeof record.tty === "boolean" ? record.tty : void 0;
197305
+ const isActive = typeof record.isActive === "boolean" ? record.isActive : void 0;
197306
+ const bytesPerSecond = typeof record.bytesPerSecond === "number" ? record.bytesPerSecond : void 0;
197307
+ return {
197308
+ id,
197309
+ ...command ? { command } : {},
197310
+ ...createdAt ? { createdAt } : {},
197311
+ ...lastActivityAt ? { lastActivityAt } : {},
197312
+ ...tty2 !== void 0 ? { tty: tty2 } : {},
197313
+ ...isActive !== void 0 ? { isActive } : {},
197314
+ ...bytesPerSecond !== void 0 ? { bytesPerSecond } : {}
197315
+ };
197316
+ };
197177
197317
  ModalDaemonExecSocket = class {
197178
197318
  constructor(sandbox, options) {
197179
197319
  this.sandbox = sandbox;
@@ -197264,13 +197404,18 @@ var init_modalRuntime = __esm({
197264
197404
  this.ws = ws;
197265
197405
  ws.on("open", () => {
197266
197406
  try {
197267
- this.sendJson({
197407
+ const authPayload = {
197268
197408
  type: "auth",
197269
197409
  mode: "tty",
197270
- command: this.options.cmd,
197271
197410
  cols: this.options.cols,
197272
197411
  rows: this.options.rows
197273
- });
197412
+ };
197413
+ if (this.options.sessionId) {
197414
+ authPayload.sessionId = this.options.sessionId;
197415
+ } else {
197416
+ authPayload.command = this.options.cmd;
197417
+ }
197418
+ this.sendJson(authPayload);
197274
197419
  } catch (error2) {
197275
197420
  this.emit("error", {
197276
197421
  data: error2 instanceof Error ? error2 : new Error(String(error2))
@@ -197326,6 +197471,11 @@ var init_modalRuntime = __esm({
197326
197471
  cb?.();
197327
197472
  return;
197328
197473
  }
197474
+ if (record.type === "detach") {
197475
+ this.sendJson({ type: "detach" });
197476
+ cb?.();
197477
+ return;
197478
+ }
197329
197479
  }
197330
197480
  } catch {
197331
197481
  }
@@ -197696,10 +197846,102 @@ var init_modalRuntime = __esm({
197696
197846
  }
197697
197847
  ];
197698
197848
  };
197849
+ const parseKillTimeoutOption = (value) => {
197850
+ if (!value) return void 0;
197851
+ const trimmed = value.trim().toLowerCase();
197852
+ if (!trimmed) return void 0;
197853
+ const match2 = /^(\d+)(ms|s|m)?$/.exec(trimmed);
197854
+ if (!match2) return void 0;
197855
+ const amount = Number.parseInt(match2[1] ?? "", 10);
197856
+ if (!Number.isFinite(amount) || amount <= 0) {
197857
+ return void 0;
197858
+ }
197859
+ const unit = match2[2] ?? "ms";
197860
+ if (unit === "ms") return amount;
197861
+ if (unit === "s") return amount * 1e3;
197862
+ if (unit === "m") return amount * 6e4;
197863
+ return void 0;
197864
+ };
197865
+ const runControlRequest = async (requestPayload, expectedType) => {
197866
+ const ws = await connectModalDaemonWebSocket(resolveSandbox());
197867
+ const requestId = (0, import_node_crypto8.randomUUID)().replace(/-/g, "");
197868
+ try {
197869
+ ws.send(JSON.stringify({ type: "auth", mode: "control" }));
197870
+ await awaitModalDaemonMessage(
197871
+ ws,
197872
+ (message) => message.type === "control_ready"
197873
+ );
197874
+ ws.send(JSON.stringify({ ...requestPayload, requestId }));
197875
+ return await awaitModalDaemonMessage(
197876
+ ws,
197877
+ (message) => message.type === expectedType && message.requestId === requestId
197878
+ );
197879
+ } finally {
197880
+ if (ws.readyState === import_ws3.default.OPEN) {
197881
+ ws.close();
197882
+ } else if (ws.readyState === import_ws3.default.CONNECTING) {
197883
+ ws.terminate();
197884
+ }
197885
+ }
197886
+ };
197887
+ const listExecSessions2 = async (name) => {
197888
+ requireAlias(name);
197889
+ const response = await runControlRequest(
197890
+ { type: "sessions_list" },
197891
+ "sessions_list_result"
197892
+ );
197893
+ if (response.status !== "ok") {
197894
+ const { text } = parseControlError(response);
197895
+ throw new Error(text);
197896
+ }
197897
+ const records = Array.isArray(response.sessions) ? response.sessions : [];
197898
+ const sessions = [];
197899
+ for (const entry of records) {
197900
+ const mapped = mapControlSessionRecord(entry);
197901
+ if (!mapped) continue;
197902
+ sessions.push(mapped);
197903
+ }
197904
+ return sessions;
197905
+ };
197906
+ const killExecSession = async (name, sessionId, options) => {
197907
+ requireAlias(name);
197908
+ const timeoutMs = parseKillTimeoutOption(options?.timeout);
197909
+ const response = await runControlRequest(
197910
+ {
197911
+ type: "session_kill",
197912
+ sessionId,
197913
+ ...options?.signal ? { signal: options.signal } : {},
197914
+ ...typeof timeoutMs === "number" ? { timeoutMs } : {}
197915
+ },
197916
+ "session_kill_result"
197917
+ );
197918
+ if (response.status !== "ok") {
197919
+ const { code: code2, text } = parseControlError(response);
197920
+ if (code2 === "not_found") {
197921
+ throw new SpritesApiError(
197922
+ 404,
197923
+ "DELETE",
197924
+ `/v1/sprites/${encodeURIComponent(name)}/exec/${encodeURIComponent(sessionId)}`,
197925
+ text
197926
+ );
197927
+ }
197928
+ throw new Error(text);
197929
+ }
197930
+ return Array.isArray(response.events) ? response.events.filter((entry) => entry && typeof entry === "object").map((entry) => entry) : [{ event: "killed", session_id: sessionId }];
197931
+ };
197699
197932
  const openExecSession = (name, options) => {
197700
197933
  requireAlias(name);
197701
197934
  return new ModalDaemonExecSocket(resolveSandbox("shell"), options);
197702
197935
  };
197936
+ const attachExecSession = (name, sessionId) => {
197937
+ requireAlias(name);
197938
+ return new ModalDaemonExecSocket(resolveSandbox(), {
197939
+ cmd: [],
197940
+ tty: true,
197941
+ stdin: true,
197942
+ sessionId
197943
+ });
197944
+ };
197703
197945
  const createCheckpoint = async (_name, options) => {
197704
197946
  const sandbox = await resolveSandbox();
197705
197947
  const image = await sandbox.snapshotFilesystem();
@@ -197718,18 +197960,21 @@ var init_modalRuntime = __esm({
197718
197960
  writeFile: writeFile2,
197719
197961
  readFile: readFile3,
197720
197962
  exec,
197963
+ listExecSessions: listExecSessions2,
197964
+ killExecSession,
197721
197965
  createCheckpoint,
197722
197966
  getService,
197723
197967
  createService,
197724
197968
  startService: startService2,
197725
- openExecSession
197969
+ openExecSession,
197970
+ attachExecSession
197726
197971
  };
197727
197972
  };
197728
197973
  }
197729
197974
  });
197730
197975
 
197731
197976
  // src/devbox/commands/provider/modalLifecycle.ts
197732
- var DEFAULT_APP_NAME, DEFAULT_MODAL_DEVBOX_IMAGE, DEFAULT_TIMEOUT_MS, SANDBOX_LIST_PAGE_LIMIT, FINISHED_STATUS_LABELS, trimEnv3, decodeJwtExpMs, createSafeModalAuthTokenManager, installSafeModalAuthTokenManager, parsePositiveInt, resolveRegions, resolveAppName, resolveModalSandboxTimeoutMs, isNotFoundError, isModalAlreadyExistsError, withModalClient, resolveModalApp, listSandboxesRaw, formatSandboxStatus, isRunningSandbox, resolveImageFromTag, provisionModalSandbox, findModalSandbox, terminateModalSandboxesByAlias;
197977
+ var DEFAULT_APP_NAME, DEFAULT_MODAL_DEVBOX_IMAGE, DEFAULT_TIMEOUT_MS, SANDBOX_LIST_PAGE_LIMIT, MODAL_DAEMON_WRAPPER_PATH, MODAL_DAEMON_SUPERVISOR_ENTRYPOINT, FINISHED_STATUS_LABELS, trimEnv3, decodeJwtExpMs, createSafeModalAuthTokenManager, installSafeModalAuthTokenManager, parsePositiveInt, resolveRegions, resolveAppName, resolveModalSandboxTimeoutMs, isNotFoundError, isModalAlreadyExistsError, withModalClient, resolveModalApp, listSandboxesRaw, formatSandboxStatus, isRunningSandbox, resolveImageFromTag, provisionModalSandbox, findModalSandbox, terminateModalSandboxesByAlias;
197733
197978
  var init_modalLifecycle = __esm({
197734
197979
  "src/devbox/commands/provider/modalLifecycle.ts"() {
197735
197980
  "use strict";
@@ -197739,6 +197984,22 @@ var init_modalLifecycle = __esm({
197739
197984
  DEFAULT_MODAL_DEVBOX_IMAGE = "public.ecr.aws/d8m4p4w9/modal-devbox:latest";
197740
197985
  DEFAULT_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
197741
197986
  SANDBOX_LIST_PAGE_LIMIT = 100;
197987
+ MODAL_DAEMON_WRAPPER_PATH = "/home/sprite/.devbox/daemon/run-daemon.sh";
197988
+ MODAL_DAEMON_SUPERVISOR_ENTRYPOINT = [
197989
+ "/bin/sh",
197990
+ "-lc",
197991
+ [
197992
+ "set -u",
197993
+ `wrapper=${JSON.stringify(MODAL_DAEMON_WRAPPER_PATH)}`,
197994
+ 'until [ -x "$wrapper" ]; do sleep 0.25; done',
197995
+ "while true; do",
197996
+ ' "$wrapper"',
197997
+ " status=$?",
197998
+ ' echo "sprite-daemon exited with status $status; restarting" >&2',
197999
+ " sleep 1",
198000
+ "done"
198001
+ ].join("\n")
198002
+ ];
197742
198003
  FINISHED_STATUS_LABELS = {
197743
198004
  1: "success",
197744
198005
  2: "failure",
@@ -197942,6 +198203,7 @@ var init_modalLifecycle = __esm({
197942
198203
  timeoutSecs,
197943
198204
  name: alias,
197944
198205
  ...regions.length > 0 ? { schedulerPlacement: { regions } } : {},
198206
+ entrypointArgs: MODAL_DAEMON_SUPERVISOR_ENTRYPOINT,
197945
198207
  enableSnapshot: true
197946
198208
  }
197947
198209
  });
@@ -198087,10 +198349,11 @@ var init_providerClient = __esm({
198087
198349
  appName,
198088
198350
  sandboxId,
198089
198351
  operationOptions,
198090
- ensureActive
198352
+ ensureActive,
198353
+ runtimeClient
198091
198354
  }) => {
198092
198355
  assertModalRuntimeCredentialPair(operationOptions);
198093
- const runtime = createModalInitRuntimeClient({
198356
+ const runtime = runtimeClient ?? createModalInitRuntimeClient({
198094
198357
  alias,
198095
198358
  appName,
198096
198359
  sandboxId,
@@ -198107,8 +198370,8 @@ var init_providerClient = __esm({
198107
198370
  writeFile: runtime.writeFile,
198108
198371
  readFile: runtime.readFile,
198109
198372
  exec: runtime.exec,
198110
- listExecSessions: async () => throwModalConnectUnsupported("listExecSessions (modal connect client)"),
198111
- killExecSession: async () => throwModalConnectUnsupported("killExecSession (modal connect client)"),
198373
+ listExecSessions: runtime.listExecSessions,
198374
+ killExecSession: runtime.killExecSession,
198112
198375
  createCheckpoint: runtime.createCheckpoint,
198113
198376
  listServices: async () => throwModalConnectUnsupported("listServices (modal connect client)"),
198114
198377
  getService: runtime.getService,
@@ -198116,7 +198379,7 @@ var init_providerClient = __esm({
198116
198379
  startService: runtime.startService,
198117
198380
  stopService: async () => throwModalConnectUnsupported("stopService (modal connect client)"),
198118
198381
  openExecSession: runtime.openExecSession,
198119
- attachExecSession: () => throwModalConnectUnsupported("attachExecSession (modal connect client)"),
198382
+ attachExecSession: runtime.attachExecSession,
198120
198383
  openProxySocket: () => throwModalConnectUnsupported("openProxySocket (modal connect client)")
198121
198384
  };
198122
198385
  };
@@ -198341,12 +198604,12 @@ var init_sessionUtils = __esm({
198341
198604
  });
198342
198605
 
198343
198606
  // src/devbox/commands/connect.ts
198344
- var import_node_child_process4, import_node_crypto8, import_node_os10, import_node_path17, import_node_readline3, import_promises13, DEFAULT_TTY_COLS, DEFAULT_TTY_ROWS, TERMINAL_INPUT_MODE_RESET, resetTerminalInputModes, openBrowser2, warnSetupStatus, resolveTtyEnv, formatEnvExports, parseEnvSize, readStreamSize, resolveTtySize, resolveSessionEnv, parseReachabilityState, runCommand, checkReachability, watchReachabilityWithScutil, watchReachabilityWithNotifyutil, waitForNetworkOnline, parseConnectArgs, parseConnectTarget, buildLoggingCommand, CONNECT_SHELL_CANDIDATES, resolveConnectShell, confirmNewSession, promptRenameSession, HEARTBEAT_INTERVAL_MS, HEARTBEAT_TIMEOUT_MS, INPUT_PROBE_TIMEOUT_MS, WS_OPEN_STATE, streamExecSession, runConnect;
198607
+ var import_node_child_process4, import_node_crypto9, import_node_os10, import_node_path17, import_node_readline3, import_promises13, DEFAULT_TTY_COLS, DEFAULT_TTY_ROWS, TERMINAL_INPUT_MODE_RESET, resetTerminalInputModes, openBrowser2, warnSetupStatus, resolveTtyEnv, formatEnvExports, parseEnvSize, readStreamSize, resolveTtySize, resolveSessionEnv, parseReachabilityState, runCommand, checkReachability, watchReachabilityWithScutil, watchReachabilityWithNotifyutil, waitForNetworkOnline, parseConnectArgs, parseConnectTarget, buildLoggingCommand, CONNECT_SHELL_CANDIDATES, resolveConnectShell, confirmNewSession, promptRenameSession, HEARTBEAT_INTERVAL_MS, HEARTBEAT_TIMEOUT_MS, INPUT_PROBE_TIMEOUT_MS, WS_OPEN_STATE, streamExecSession, runConnect;
198345
198608
  var init_connect2 = __esm({
198346
198609
  "src/devbox/commands/connect.ts"() {
198347
198610
  "use strict";
198348
198611
  import_node_child_process4 = require("node:child_process");
198349
- import_node_crypto8 = require("node:crypto");
198612
+ import_node_crypto9 = require("node:crypto");
198350
198613
  import_node_os10 = __toESM(require("node:os"), 1);
198351
198614
  import_node_path17 = require("node:path");
198352
198615
  import_node_readline3 = require("node:readline");
@@ -198705,7 +198968,8 @@ var init_connect2 = __esm({
198705
198968
  return { box, session };
198706
198969
  };
198707
198970
  buildLoggingCommand = (logPath, shellCommand) => [
198708
- 'mkdir -p "$HOME/.devbox/logs"',
198971
+ `log_dir=$(dirname ${shellQuote3(logPath)})`,
198972
+ 'mkdir -p "$log_dir"',
198709
198973
  "if command -v script >/dev/null 2>&1; then",
198710
198974
  ` exec script -q -f -a ${shellQuote3(logPath)} -c ${shellQuote3(shellCommand)}`,
198711
198975
  "else",
@@ -199282,22 +199546,17 @@ var init_connect2 = __esm({
199282
199546
  command: "connect",
199283
199547
  capability: "exec.sessions.open"
199284
199548
  });
199285
- const supportsAttachExecSession = computeProvider === "sprites";
199549
+ const supportsAttachExecSession = hasCommandProviderCapability({
199550
+ provider: computeProvider,
199551
+ command: "connect",
199552
+ capability: "exec.sessions.attach"
199553
+ });
199554
+ const supportsListExecSessions = hasCommandProviderCapability({
199555
+ provider: computeProvider,
199556
+ command: "connect",
199557
+ capability: "exec.sessions.list"
199558
+ });
199286
199559
  const supportsResizeControlMessages = computeProvider === "sprites" || computeProvider === "modal";
199287
- if (computeProvider === "modal") {
199288
- if (isDetached) {
199289
- throw new Error(
199290
- "`dvb connect --detach` is not supported for modal devboxes yet."
199291
- );
199292
- }
199293
- if (sessionName) {
199294
- throw new Error(
199295
- "Named sessions are not supported for modal devboxes yet. Re-run without `--name` or `<box>/<session>`."
199296
- );
199297
- }
199298
- autoNameRequested = false;
199299
- shouldLog2 = false;
199300
- }
199301
199560
  let client2;
199302
199561
  let networkTargetHost = null;
199303
199562
  if (computeProvider === "modal") {
@@ -199526,7 +199785,7 @@ var init_connect2 = __esm({
199526
199785
  if (!sessionName) return;
199527
199786
  sessions = await readSessionsSafe(sessions);
199528
199787
  sessionId = sessions[sessionName];
199529
- if (sessionId) {
199788
+ if (sessionId && supportsListExecSessions) {
199530
199789
  const available = await client2.listExecSessions(spriteAlias);
199531
199790
  const match2 = available.find((session) => session.id === sessionId);
199532
199791
  if (!match2 || match2.tty === false) {
@@ -199597,7 +199856,7 @@ var init_connect2 = __esm({
199597
199856
  const weztermPane = process.env.WEZTERM_PANE?.trim() || "";
199598
199857
  const weztermSocket = process.env.WEZTERM_UNIX_SOCKET?.trim() || "";
199599
199858
  const weztermSessionId = weztermPane ? `wezterm:${weztermPane}${weztermSocket ? `:${(0, import_node_path17.basename)(weztermSocket)}` : ""}` : "";
199600
- const terminalSessionId = process.env.DEVBOX_TERM_SESSION_ID?.trim() || weztermSessionId || process.env.TERM_SESSION_ID?.trim() || process.env.ITERM_SESSION_ID?.trim() || `dvb-${(0, import_node_crypto8.randomUUID)()}`;
199859
+ const terminalSessionId = process.env.DEVBOX_TERM_SESSION_ID?.trim() || weztermSessionId || process.env.TERM_SESSION_ID?.trim() || process.env.ITERM_SESSION_ID?.trim() || `dvb-${(0, import_node_crypto9.randomUUID)()}`;
199601
199860
  const execCommand2 = (() => {
199602
199861
  const sessionEnv = resolveSessionEnv(terminalSessionId);
199603
199862
  const ttyEnv = isTty ? resolveTtyEnv(terminalSessionId) : null;
@@ -199866,14 +200125,16 @@ ${message}\r
199866
200125
  console.error("Connection lost. Reconnecting... (Ctrl+C to cancel)");
199867
200126
  reconnectNoticeShown = true;
199868
200127
  }
199869
- if (result.opened === false && sessionId && supportsAttachExecSession) {
200128
+ if (result.opened === false && sessionId && supportsAttachExecSession && supportsListExecSessions) {
199870
200129
  try {
199871
200130
  const available = await client2.listExecSessions(spriteAlias);
199872
200131
  const match2 = available.find((session) => session.id === sessionId);
199873
- if ((!match2 || match2.tty === false) && sessionName) {
199874
- delete sessions[sessionName];
200132
+ if (!match2 || match2.tty === false) {
200133
+ if (sessionName) {
200134
+ delete sessions[sessionName];
200135
+ await writeSpriteSessions(client2, spriteAlias, sessions);
200136
+ }
199875
200137
  sessionId = void 0;
199876
- await writeSpriteSessions(client2, spriteAlias, sessions);
199877
200138
  }
199878
200139
  } catch (error2) {
199879
200140
  logger7.warn("session_lookup_failed", { error: String(error2) });
@@ -201209,11 +201470,11 @@ var init_session3 = __esm({
201209
201470
  });
201210
201471
 
201211
201472
  // src/devbox/commands/init/repo.ts
201212
- var import_node_crypto9, import_node_child_process5, import_node_path21, buildSpawnEnv, runCommand2, runCommandRaw, findRepoRoot, readRepoOrigin, readLocalGitConfigValue, writeLocalGitConfigValue, ensureRepoProjectId, resolveGitCommonDir, readHeadState, readNullSeparatedPaths, readWorktreeState, confirmCopyWorktree, readGlobalGitConfigFiles, mapGlobalGitConfigDestinations;
201473
+ var import_node_crypto10, import_node_child_process5, import_node_path21, buildSpawnEnv, runCommand2, runCommandRaw, findRepoRoot, readRepoOrigin, readLocalGitConfigValue, writeLocalGitConfigValue, ensureRepoProjectId, resolveGitCommonDir, readHeadState, readNullSeparatedPaths, readWorktreeState, confirmCopyWorktree, readGlobalGitConfigFiles, mapGlobalGitConfigDestinations;
201213
201474
  var init_repo2 = __esm({
201214
201475
  "src/devbox/commands/init/repo.ts"() {
201215
201476
  "use strict";
201216
- import_node_crypto9 = require("node:crypto");
201477
+ import_node_crypto10 = require("node:crypto");
201217
201478
  import_node_child_process5 = require("node:child_process");
201218
201479
  import_node_path21 = __toESM(require("node:path"), 1);
201219
201480
  init_dist5();
@@ -201300,7 +201561,7 @@ var init_repo2 = __esm({
201300
201561
  const key = "devbox.projectId";
201301
201562
  const existing = await readLocalGitConfigValue(repoRoot, key);
201302
201563
  if (existing) return existing;
201303
- const created = (0, import_node_crypto9.randomUUID)();
201564
+ const created = (0, import_node_crypto10.randomUUID)();
201304
201565
  await writeLocalGitConfigValue(repoRoot, key, created);
201305
201566
  return created;
201306
201567
  };
@@ -201425,11 +201686,11 @@ var init_weztermMux = __esm({
201425
201686
  });
201426
201687
 
201427
201688
  // src/devbox/commands/init/remote.ts
201428
- var import_node_crypto10, DAEMON_DIR, DAEMON_TARBALL, DAEMON_BUNDLE_DIR, DAEMON_ENTRY, DAEMON_WRAPPER, DAEMON_SERVICE_NAME, DAEMON_CONFIG_FILE, DEFAULT_DAEMON_BASE_URL, DEFAULT_HEARTBEAT_MS, BOOTSTRAP_EXEC_TIMEOUT_MS, BOOTSTRAP_EXEC_HANDSHAKE_TIMEOUT_MS, BASHRC_PATH, ZSHRC_PATH, BASIC_ALIASES_MARKER, LEGACY_BASH_TRAP, SAFE_BASH_TRAP, BASH_HISTORY_BLOCK, ZSH_HISTORY_BLOCK, HISTORY_BLOCK_PATTERN, BASH_HISTORY_LINE_PATTERN, ZSH_HISTORY_LINE_PATTERN, logger8, truncateTail, shellQuote4, expandHome2, execWithLog, writeRemoteFile, readRemoteFile, ensureTrailingNewline, upsertHistoryBlock, patchBashrcContent, patchZshrcContent, bootstrapDevbox, buildWeztermMuxConfig, buildWeztermMuxRunner, patchRemoteRcFile, patchBashrc, patchZshrc, stageRemoteSetupArtifacts, resolveDaemonUrl, fetchDaemonBinary, buildDaemonConfig, buildDaemonWrapperScript, isSameArgs, ensureSpriteDaemonService, installWeztermMux, ensureWeztermMuxService, hasWeztermMuxBinary, isWeztermMuxHealthy, installSpriteDaemon;
201689
+ var import_node_crypto11, DAEMON_DIR, DAEMON_TARBALL, DAEMON_BUNDLE_DIR, DAEMON_ENTRY, DAEMON_WRAPPER, DAEMON_SERVICE_NAME, DAEMON_CONFIG_FILE, MODAL_DAEMON_HEALTH_PORT, DEFAULT_DAEMON_BASE_URL, DEFAULT_HEARTBEAT_MS, BOOTSTRAP_EXEC_TIMEOUT_MS, BOOTSTRAP_EXEC_HANDSHAKE_TIMEOUT_MS, BASHRC_PATH, ZSHRC_PATH, BASIC_ALIASES_MARKER, LEGACY_BASH_TRAP, SAFE_BASH_TRAP, BASH_HISTORY_BLOCK, ZSH_HISTORY_BLOCK, HISTORY_BLOCK_PATTERN, BASH_HISTORY_LINE_PATTERN, ZSH_HISTORY_LINE_PATTERN, logger8, truncateTail, shellQuote4, expandHome2, execWithLog, writeRemoteFile, readRemoteFile, ensureTrailingNewline, upsertHistoryBlock, patchBashrcContent, patchZshrcContent, bootstrapDevbox, buildWeztermMuxConfig, buildWeztermMuxRunner, patchRemoteRcFile, patchBashrc, patchZshrc, stageRemoteSetupArtifacts, resolveDaemonUrl, fetchDaemonBinary, buildDaemonConfig, buildDaemonWrapperScript, isSameArgs, ensureSpriteDaemonService, installWeztermMux, ensureWeztermMuxService, hasWeztermMuxBinary, isWeztermMuxHealthy, installSpriteDaemon;
201429
201690
  var init_remote = __esm({
201430
201691
  "src/devbox/commands/init/remote.ts"() {
201431
201692
  "use strict";
201432
- import_node_crypto10 = require("node:crypto");
201693
+ import_node_crypto11 = require("node:crypto");
201433
201694
  init_src();
201434
201695
  init_weztermMux();
201435
201696
  DAEMON_DIR = "/home/sprite/.devbox/daemon";
@@ -201439,6 +201700,7 @@ var init_remote = __esm({
201439
201700
  DAEMON_WRAPPER = `${DAEMON_DIR}/run-daemon.sh`;
201440
201701
  DAEMON_SERVICE_NAME = "devbox-sprite-daemon";
201441
201702
  DAEMON_CONFIG_FILE = `${DAEMON_DIR}/config.json`;
201703
+ MODAL_DAEMON_HEALTH_PORT = 8080;
201442
201704
  DEFAULT_DAEMON_BASE_URL = process.env.SPRITE_DAEMON_BASE_URL?.trim() || "https://deploy-dev.boxes.dev";
201443
201705
  DEFAULT_HEARTBEAT_MS = 3e4;
201444
201706
  BOOTSTRAP_EXEC_TIMEOUT_MS = 9e4;
@@ -201482,7 +201744,7 @@ var init_remote = __esm({
201482
201744
  return value;
201483
201745
  };
201484
201746
  execWithLog = async (client2, spriteAlias, script, stage, options) => {
201485
- const requestId = (0, import_node_crypto10.randomUUID)();
201747
+ const requestId = (0, import_node_crypto11.randomUUID)();
201486
201748
  const startedAt2 = Date.now();
201487
201749
  logger8.info("sprites_request", {
201488
201750
  requestId,
@@ -201516,7 +201778,7 @@ var init_remote = __esm({
201516
201778
  return result;
201517
201779
  };
201518
201780
  writeRemoteFile = async (client2, spriteAlias, path38, content, stage) => {
201519
- const requestId = (0, import_node_crypto10.randomUUID)();
201781
+ const requestId = (0, import_node_crypto11.randomUUID)();
201520
201782
  logger8.info("sprites_request", {
201521
201783
  requestId,
201522
201784
  method: "writeFile",
@@ -201536,7 +201798,7 @@ var init_remote = __esm({
201536
201798
  });
201537
201799
  };
201538
201800
  readRemoteFile = async (client2, spriteAlias, path38, stage) => {
201539
- const requestId = (0, import_node_crypto10.randomUUID)();
201801
+ const requestId = (0, import_node_crypto11.randomUUID)();
201540
201802
  logger8.info("sprites_request", {
201541
201803
  requestId,
201542
201804
  method: "readFile",
@@ -202074,8 +202336,45 @@ ${canonicalBlock}
202074
202336
  };
202075
202337
  ensureSpriteDaemonService = async ({
202076
202338
  client: client2,
202077
- spriteName
202339
+ spriteName,
202340
+ computeProvider
202078
202341
  }) => {
202342
+ if (computeProvider === "modal") {
202343
+ const script = [
202344
+ "set -euo pipefail",
202345
+ `wrapper=${shellQuote4(DAEMON_WRAPPER)}`,
202346
+ `health_port=${String(MODAL_DAEMON_HEALTH_PORT)}`,
202347
+ 'if [ ! -x "$wrapper" ]; then',
202348
+ ' echo "missing sprite-daemon wrapper" >&2',
202349
+ " exit 1",
202350
+ "fi",
202351
+ "ready=0",
202352
+ "for _ in $(seq 1 120); do",
202353
+ ' if (echo >"/dev/tcp/127.0.0.1/${health_port}") >/dev/null 2>&1; then',
202354
+ " ready=1",
202355
+ " break",
202356
+ " fi",
202357
+ " sleep 0.25",
202358
+ "done",
202359
+ 'if [ "$ready" -ne 1 ]; then',
202360
+ ' echo "sprite-daemon websocket health port not ready" >&2',
202361
+ " exit 1",
202362
+ "fi",
202363
+ "echo ok"
202364
+ ].join("\n");
202365
+ const result = await execWithLog(
202366
+ client2,
202367
+ spriteName,
202368
+ script,
202369
+ "ensure-sprite-daemon"
202370
+ );
202371
+ if (result.exitCode !== 0) {
202372
+ throw new Error(
202373
+ result.stderr || result.stdout || "Sprite daemon health check failed."
202374
+ );
202375
+ }
202376
+ return;
202377
+ }
202079
202378
  const expectedCmd = DAEMON_WRAPPER;
202080
202379
  const expectedArgs = [];
202081
202380
  const existing = await client2.getService(spriteName, DAEMON_SERVICE_NAME);
@@ -202420,7 +202719,7 @@ chmod 755 ${WEZTERM_MUX_RUNNER_PATH}`,
202420
202719
  throw new Error(result.stderr || result.stdout || "Daemon install failed.");
202421
202720
  }
202422
202721
  reportPhase(4, "ensure daemon service");
202423
- await ensureSpriteDaemonService({ client: client2, spriteName });
202722
+ await ensureSpriteDaemonService({ client: client2, spriteName, computeProvider });
202424
202723
  reportPhase(5, "completed");
202425
202724
  };
202426
202725
  }
@@ -204626,11 +204925,11 @@ ${usageText}`;
204626
204925
  });
204627
204926
 
204628
204927
  // src/devbox/commands/init/codex/artifacts.ts
204629
- var import_node_crypto11, import_node_fs11, import_promises23, import_node_path27, import_node_os14, macCopyfileDisabledEnv, SETUP_ARTIFACT_PART_SIZE_BYTES, SETUP_ARTIFACT_PARTS_DIRNAME, SETUP_ARTIFACT_PARTS_DESCRIPTOR_FILENAME, isWithinRepo, normalizeExternalPath, expandHomePath, buildArtifactEntry, buildEntries, copyArtifact, sha256File, readSetupArtifactsPartsDescriptor, createSetupArtifacts;
204928
+ var import_node_crypto12, import_node_fs11, import_promises23, import_node_path27, import_node_os14, macCopyfileDisabledEnv, SETUP_ARTIFACT_PART_SIZE_BYTES, SETUP_ARTIFACT_PARTS_DIRNAME, SETUP_ARTIFACT_PARTS_DESCRIPTOR_FILENAME, isWithinRepo, normalizeExternalPath, expandHomePath, buildArtifactEntry, buildEntries, copyArtifact, sha256File, readSetupArtifactsPartsDescriptor, createSetupArtifacts;
204630
204929
  var init_artifacts = __esm({
204631
204930
  "src/devbox/commands/init/codex/artifacts.ts"() {
204632
204931
  "use strict";
204633
- import_node_crypto11 = require("node:crypto");
204932
+ import_node_crypto12 = require("node:crypto");
204634
204933
  import_node_fs11 = require("node:fs");
204635
204934
  import_promises23 = __toESM(require("node:fs/promises"), 1);
204636
204935
  import_node_path27 = __toESM(require("node:path"), 1);
@@ -204740,7 +205039,7 @@ var init_artifacts = __esm({
204740
205039
  await import_promises23.default.cp(entry.sourcePath, destPath, { recursive: false });
204741
205040
  };
204742
205041
  sha256File = async (filePath) => await new Promise((resolve2, reject) => {
204743
- const hash = (0, import_node_crypto11.createHash)("sha256");
205042
+ const hash = (0, import_node_crypto12.createHash)("sha256");
204744
205043
  const stream = (0, import_node_fs11.createReadStream)(filePath);
204745
205044
  stream.on("data", (chunk) => hash.update(chunk));
204746
205045
  stream.on("error", reject);
@@ -205143,12 +205442,12 @@ var init_progress = __esm({
205143
205442
  });
205144
205443
 
205145
205444
  // src/devbox/commands/init/codex/index.ts
205146
- var import_node_path28, import_node_crypto12, import_promises24, import_node_os15, resolveLocalCodexRoot, readLocalCodexAuthCache, syncLocalCodexAuthCacheToSprite, uploadSetupPlan, runRemoteCodexSetup;
205445
+ var import_node_path28, import_node_crypto13, import_promises24, import_node_os15, resolveLocalCodexRoot, readLocalCodexAuthCache, syncLocalCodexAuthCacheToSprite, uploadSetupPlan, runRemoteCodexSetup;
205147
205446
  var init_codex = __esm({
205148
205447
  "src/devbox/commands/init/codex/index.ts"() {
205149
205448
  "use strict";
205150
205449
  import_node_path28 = __toESM(require("node:path"), 1);
205151
- import_node_crypto12 = require("node:crypto");
205450
+ import_node_crypto13 = require("node:crypto");
205152
205451
  import_promises24 = __toESM(require("node:fs/promises"), 1);
205153
205452
  import_node_os15 = require("node:os");
205154
205453
  init_dist5();
@@ -205389,7 +205688,7 @@ var init_codex = __esm({
205389
205688
  }
205390
205689
  if (splitArtifacts && remoteArtifactsBundlePath) {
205391
205690
  status.stage("Assembling artifacts on remote");
205392
- const assembledTmpPath = `${remoteArtifactsBundlePath}.tmp-assemble-${(0, import_node_crypto12.randomUUID)()}`;
205691
+ const assembledTmpPath = `${remoteArtifactsBundlePath}.tmp-assemble-${(0, import_node_crypto13.randomUUID)()}`;
205393
205692
  const assembleScript = [
205394
205693
  "set -euo pipefail",
205395
205694
  `bundle=${shellQuote4(remoteArtifactsBundlePath)}`,
@@ -205591,7 +205890,7 @@ codex login`
205591
205890
  entrypoints
205592
205891
  });
205593
205892
  const codexLastMessagePath = "/home/sprite/.devbox/codex-setup-output.txt";
205594
- const proxyRoot = proxyOptions ? `/home/sprite/.devbox/tmp/codex-proxy-${(0, import_node_crypto12.randomUUID)()}` : null;
205893
+ const proxyRoot = proxyOptions ? `/home/sprite/.devbox/tmp/codex-proxy-${(0, import_node_crypto13.randomUUID)()}` : null;
205595
205894
  const proxyTokenPath = proxyRoot ? `${proxyRoot}/devbox-token` : null;
205596
205895
  const proxyCodexHome = proxyRoot ? `${proxyRoot}/codex-home` : null;
205597
205896
  const proxyConfigPath = proxyCodexHome ? `${proxyCodexHome}/config.toml` : null;
@@ -206620,7 +206919,6 @@ var init_setupPlanFlow = __esm({
206620
206919
  }
206621
206920
  outsideRepoPaths.sort();
206622
206921
  directoryPaths.sort();
206623
- const hasRisk = outsideRepoPaths.length > 0 || directoryPaths.length > 0;
206624
206922
  const warningLines = [];
206625
206923
  if (outsideRepoPaths.length > 0) {
206626
206924
  warningLines.push("Outside repo:");
@@ -206637,8 +206935,7 @@ var init_setupPlanFlow = __esm({
206637
206935
  }
206638
206936
  return {
206639
206937
  summary: lines.join("\n"),
206640
- warning: warningLines.length > 0 ? warningLines.join("\n") : null,
206641
- hasRisk
206938
+ warning: warningLines.length > 0 ? warningLines.join("\n") : null
206642
206939
  };
206643
206940
  };
206644
206941
  let draftSetup = setupPlan;
@@ -206653,7 +206950,7 @@ var init_setupPlanFlow = __esm({
206653
206950
  initialSelection: draftSetup?.services ?? null
206654
206951
  });
206655
206952
  const nextPlan = { ...nextSetup, services: nextServices };
206656
- const { summary, warning, hasRisk } = await buildApprovalSummary(nextPlan);
206953
+ const { summary, warning } = await buildApprovalSummary(nextPlan);
206657
206954
  kt2(summary, "Selected setup requirements");
206658
206955
  if (warning) {
206659
206956
  kt2(warning, "Special attention");
@@ -206674,21 +206971,6 @@ var init_setupPlanFlow = __esm({
206674
206971
  draftSetup = nextPlan;
206675
206972
  continue;
206676
206973
  }
206677
- if (hasRisk) {
206678
- const confirmed = await Mt2({
206679
- message: "You selected items outside the repo and/or directories. Continue?",
206680
- active: "Continue",
206681
- inactive: "Edit selections",
206682
- initialValue: true
206683
- });
206684
- if (Ct(confirmed)) {
206685
- throwInitCanceled2();
206686
- }
206687
- if (!confirmed) {
206688
- draftSetup = nextPlan;
206689
- continue;
206690
- }
206691
- }
206692
206974
  approvedPlan = nextPlan;
206693
206975
  break;
206694
206976
  }
@@ -207220,11 +207502,11 @@ var init_provisionFlow = __esm({
207220
207502
  });
207221
207503
 
207222
207504
  // src/devbox/commands/init/ssh.ts
207223
- var import_node_crypto13, import_node_child_process10, logger9, SSH_IDENTITY_FILE, SSH_ED25519_PUBLIC_KEY_PATTERN, stripGitSuffix2, buildSshUrl, buildSettingsUrl, parseScpLike, parseGitRemote, execRemote, extractEd25519PublicKey, readRemoteOrigin, setRemoteOrigin, ensureSshKey, ensureSshConfig, verifySshAuth, openBrowser4, runClipboardCommand, copyToClipboard;
207505
+ var import_node_crypto14, import_node_child_process10, logger9, SSH_IDENTITY_FILE, SSH_ED25519_PUBLIC_KEY_PATTERN, stripGitSuffix2, buildSshUrl, buildSettingsUrl, parseScpLike, parseGitRemote, execRemote, extractEd25519PublicKey, readRemoteOrigin, setRemoteOrigin, ensureSshKey, ensureSshConfig, verifySshAuth, openBrowser4, runClipboardCommand, copyToClipboard;
207224
207506
  var init_ssh = __esm({
207225
207507
  "src/devbox/commands/init/ssh.ts"() {
207226
207508
  "use strict";
207227
- import_node_crypto13 = require("node:crypto");
207509
+ import_node_crypto14 = require("node:crypto");
207228
207510
  import_node_child_process10 = require("node:child_process");
207229
207511
  init_src();
207230
207512
  init_remote();
@@ -207306,7 +207588,7 @@ var init_ssh = __esm({
207306
207588
  return null;
207307
207589
  };
207308
207590
  execRemote = async (client2, spriteAlias, script, stage) => {
207309
- const requestId = (0, import_node_crypto13.randomUUID)();
207591
+ const requestId = (0, import_node_crypto14.randomUUID)();
207310
207592
  logger9.info("sprites_request", {
207311
207593
  requestId,
207312
207594
  method: "exec",
@@ -207844,13 +208126,15 @@ var init_finalizeFlow = __esm({
207844
208126
  promptBeforeOpenBrowser = async ({
207845
208127
  url,
207846
208128
  title,
208129
+ promptMessage,
207847
208130
  consequence,
207848
208131
  throwInitCanceled: throwInitCanceled2
207849
208132
  }) => {
207850
208133
  if (!process.stdin.isTTY) return false;
207851
208134
  showCopyableUrl(url, title);
208135
+ const message = typeof promptMessage === "string" && promptMessage.trim().length > 0 ? promptMessage : `Open ${title} in your browser?`;
207852
208136
  const choice = await qt({
207853
- message: `Open ${title} in your browser?`,
208137
+ message,
207854
208138
  options: [
207855
208139
  { value: "open", label: "Open in browser" },
207856
208140
  { value: "skip", label: "Skip" }
@@ -208176,9 +208460,11 @@ var init_finalizeFlow = __esm({
208176
208460
  } else {
208177
208461
  R2.warn("Could not copy the SSH key automatically.");
208178
208462
  }
208463
+ const openBrowserPromptMessage = copied ? `Open ${remoteInfo.host} SSH key page in your browser? (SSH key copied to clipboard; paste it into the key box, then click "Add SSH key".)` : `Open ${remoteInfo.host} SSH key page in your browser?`;
208179
208464
  const shouldOpen = await promptBeforeOpenBrowser({
208180
208465
  url: remoteInfo.settingsUrl,
208181
208466
  title: `${remoteInfo.host} SSH key page`,
208467
+ promptMessage: openBrowserPromptMessage,
208182
208468
  consequence: [
208183
208469
  "Skipping browser open.",
208184
208470
  "You must add the SSH key before git pull/push will work via SSH."
@@ -209913,7 +210199,8 @@ var init_init = __esm({
209913
210199
  title: "Ensuring daemon service",
209914
210200
  fn: async () => await ensureSpriteDaemonService({
209915
210201
  client: client2,
209916
- spriteName: alias
210202
+ spriteName: alias,
210203
+ computeProvider
209917
210204
  })
209918
210205
  });
209919
210206
  await updateInitState({ steps: { daemonServiceEnsured: true } });
@@ -211303,16 +211590,20 @@ var init_uninstall = __esm({
211303
211590
  });
211304
211591
 
211305
211592
  // src/devbox/commands/sessions.ts
211306
- var renameUsage, killUsage, listUsage, parseSessionsArgs, parseSessionTarget, parseKillTarget, runRename, runKill, runSessions;
211593
+ var import_node_os21, renameUsage, killUsage, listUsage, parseSessionsArgs, parseSessionTarget, parseKillTarget, loadBoxesSnapshot, resolveSessionsClient, runRename, runKill, runSessions;
211307
211594
  var init_sessions2 = __esm({
211308
211595
  "src/devbox/commands/sessions.ts"() {
211309
211596
  "use strict";
211597
+ import_node_os21 = __toESM(require("node:os"), 1);
211310
211598
  init_src();
211311
211599
  init_daemonClient();
211312
211600
  init_auth();
211313
211601
  init_colors();
211314
211602
  init_listFormatting();
211315
211603
  init_boxSelect();
211604
+ init_commandProvider();
211605
+ init_providerClient();
211606
+ init_modalLifecycle();
211316
211607
  init_sessionUtils();
211317
211608
  init_completions();
211318
211609
  renameUsage = "Usage: dvb sessions rename <session> -n <name> or dvb sessions rename <box>/<session> -n <name>";
@@ -211412,24 +211703,89 @@ var init_sessions2 = __esm({
211412
211703
  }
211413
211704
  return { box, session };
211414
211705
  };
211415
- runRename = async (target2, name) => {
211416
- const trimmed = name.trim();
211417
- if (!trimmed) {
211418
- throw new Error("Session name cannot be empty.");
211419
- }
211420
- const parsedTarget = parseSessionTarget(target2);
211421
- let targetBox = parsedTarget.box;
211422
- if (!targetBox) {
211423
- const selected = await selectDevbox(
211424
- "To rename a session on a specific box, use `dvb sessions rename <box>/<session> -n <name>`."
211706
+ loadBoxesSnapshot = async (socketPath) => {
211707
+ try {
211708
+ const response = await requestJson3(
211709
+ socketPath,
211710
+ "GET",
211711
+ "/boxes",
211712
+ DAEMON_TIMEOUT_MS.registry
211425
211713
  );
211426
- if (!selected) return;
211427
- targetBox = selected.box;
211714
+ if (response.status !== 200) {
211715
+ return null;
211716
+ }
211717
+ return response.body.boxes;
211718
+ } catch {
211719
+ return null;
211428
211720
  }
211721
+ };
211722
+ resolveSessionsClient = async (targetBox) => {
211429
211723
  const socketInfo = resolveSocketInfo();
211430
211724
  await ensureDaemonRunning(socketInfo.socketPath);
211431
211725
  await requireDaemonFeatures(socketInfo.socketPath, ["registry"]);
211432
- const spriteAlias = targetBox;
211726
+ const boxes = await loadBoxesSnapshot(socketInfo.socketPath);
211727
+ const providerTarget = await resolveCommandComputeProvider({
211728
+ box: targetBox,
211729
+ ...boxes ? { boxes } : {},
211730
+ homeDir: process.env.HOME ?? import_node_os21.default.homedir()
211731
+ });
211732
+ const spriteAlias = providerTarget.alias;
211733
+ if (providerTarget.computeProvider === "modal") {
211734
+ const config5 = await loadConfig(
211735
+ process.env.HOME ? { homeDir: process.env.HOME } : void 0
211736
+ );
211737
+ const store2 = await createSecretStore(
211738
+ config5?.tokenStore,
211739
+ process.env.HOME ? { homeDir: process.env.HOME } : void 0
211740
+ );
211741
+ const modalCredentialContext = createProviderCredentialContext({
211742
+ mode: "auto",
211743
+ controlPlaneToken: await store2.getControlPlaneToken()
211744
+ });
211745
+ let modalOperationOptions = await resolveModalCommandOperationOptions({
211746
+ credentials: modalCredentialContext,
211747
+ cwd: process.cwd()
211748
+ });
211749
+ if (modalOperationOptions.credentialMode === "shared" && (!modalOperationOptions.credentials.modalTokenId || !modalOperationOptions.credentials.modalTokenSecret)) {
211750
+ const controlPlaneToken = await ensureControlPlaneToken(store2);
211751
+ if (controlPlaneToken) {
211752
+ modalOperationOptions = await resolveModalCommandOperationOptions({
211753
+ credentials: createProviderCredentialContext({
211754
+ mode: "auto",
211755
+ controlPlaneToken
211756
+ }),
211757
+ cwd: process.cwd()
211758
+ });
211759
+ }
211760
+ }
211761
+ const sandbox = await findModalSandbox(
211762
+ {
211763
+ alias: spriteAlias,
211764
+ includeFinished: true
211765
+ },
211766
+ modalOperationOptions
211767
+ );
211768
+ if (!sandbox) {
211769
+ throw new Error(
211770
+ `No modal sandbox found named "${targetBox}". Run "dvb init --compute modal" to create one, or "dvb list" to see existing devboxes.`
211771
+ );
211772
+ }
211773
+ if (sandbox.status !== "running") {
211774
+ throw new Error(
211775
+ `Modal sandbox "${targetBox}" is ${sandbox.status}. Run "dvb init --resume" to reprovision it.`
211776
+ );
211777
+ }
211778
+ return {
211779
+ spriteAlias,
211780
+ computeProvider: "modal",
211781
+ client: createModalConnectSpritesClient({
211782
+ alias: spriteAlias,
211783
+ appName: sandbox.appName,
211784
+ sandboxId: sandbox.sandboxId,
211785
+ operationOptions: modalOperationOptions
211786
+ })
211787
+ };
211788
+ }
211433
211789
  const config4 = await loadConfig(
211434
211790
  process.env.HOME ? { homeDir: process.env.HOME } : void 0
211435
211791
  );
@@ -211439,7 +211795,27 @@ var init_sessions2 = __esm({
211439
211795
  );
211440
211796
  const apiBaseUrl = resolveSpritesApiUrl(config4);
211441
211797
  const { token } = await ensureSpritesToken(store, void 0, { apiBaseUrl });
211442
- const client2 = createSpritesClient({ apiBaseUrl, token });
211798
+ return {
211799
+ spriteAlias,
211800
+ computeProvider: "sprites",
211801
+ client: createSpritesClient({ apiBaseUrl, token })
211802
+ };
211803
+ };
211804
+ runRename = async (target2, name) => {
211805
+ const trimmed = name.trim();
211806
+ if (!trimmed) {
211807
+ throw new Error("Session name cannot be empty.");
211808
+ }
211809
+ const parsedTarget = parseSessionTarget(target2);
211810
+ let targetBox = parsedTarget.box;
211811
+ if (!targetBox) {
211812
+ const selected = await selectDevbox(
211813
+ "To rename a session on a specific box, use `dvb sessions rename <box>/<session> -n <name>`."
211814
+ );
211815
+ if (!selected) return;
211816
+ targetBox = selected.box;
211817
+ }
211818
+ const { spriteAlias, client: client2 } = await resolveSessionsClient(targetBox);
211443
211819
  const sessions = await readSpriteSessions(client2, spriteAlias);
211444
211820
  const sessionId = sessions[parsedTarget.session];
211445
211821
  if (!sessionId) {
@@ -211472,20 +211848,7 @@ var init_sessions2 = __esm({
211472
211848
  if (!selected) return;
211473
211849
  targetBox = selected.box;
211474
211850
  }
211475
- const socketInfo = resolveSocketInfo();
211476
- await ensureDaemonRunning(socketInfo.socketPath);
211477
- await requireDaemonFeatures(socketInfo.socketPath, ["registry"]);
211478
- const spriteAlias = targetBox;
211479
- const config4 = await loadConfig(
211480
- process.env.HOME ? { homeDir: process.env.HOME } : void 0
211481
- );
211482
- const store = await createSecretStore(
211483
- config4?.tokenStore,
211484
- process.env.HOME ? { homeDir: process.env.HOME } : void 0
211485
- );
211486
- const apiBaseUrl = resolveSpritesApiUrl(config4);
211487
- const { token } = await ensureSpritesToken(store, void 0, { apiBaseUrl });
211488
- const client2 = createSpritesClient({ apiBaseUrl, token });
211851
+ const { spriteAlias, client: client2 } = await resolveSessionsClient(targetBox);
211489
211852
  const sessionRef = parsedTarget.session;
211490
211853
  const sessions = await readSpriteSessions(client2, spriteAlias);
211491
211854
  let sessionId = sessions[sessionRef];
@@ -211560,24 +211923,31 @@ var init_sessions2 = __esm({
211560
211923
  if (!selected) return;
211561
211924
  targetArg = selected.box;
211562
211925
  }
211926
+ const { spriteAlias, client: client2 } = await resolveSessionsClient(targetArg);
211563
211927
  const socketInfo = resolveSocketInfo();
211564
211928
  await ensureDaemonRunning(socketInfo.socketPath);
211565
- await requireDaemonFeatures(socketInfo.socketPath, ["registry", "ports"]);
211566
- const spriteAlias = targetArg;
211567
- const config4 = await loadConfig(
211568
- process.env.HOME ? { homeDir: process.env.HOME } : void 0
211569
- );
211570
- const store = await createSecretStore(
211571
- config4?.tokenStore,
211572
- process.env.HOME ? { homeDir: process.env.HOME } : void 0
211573
- );
211574
- const apiBaseUrl = resolveSpritesApiUrl(config4);
211575
- const { token } = await ensureSpritesToken(store, void 0, { apiBaseUrl });
211576
- const client2 = createSpritesClient({ apiBaseUrl, token });
211577
- const [sessions, sessionMap, portsResponse] = await Promise.all([
211929
+ const readPortsSnapshot = async () => {
211930
+ try {
211931
+ await requireDaemonFeatures(socketInfo.socketPath, ["ports"]);
211932
+ const response = await requestJson3(socketInfo.socketPath, "GET", "/ports", DAEMON_TIMEOUT_MS.quick);
211933
+ if (response.status < 200 || response.status >= 300) {
211934
+ return {
211935
+ forwards: [],
211936
+ detected: []
211937
+ };
211938
+ }
211939
+ return response.body;
211940
+ } catch {
211941
+ return {
211942
+ forwards: [],
211943
+ detected: []
211944
+ };
211945
+ }
211946
+ };
211947
+ const [sessions, sessionMap, portsSnapshot] = await Promise.all([
211578
211948
  client2.listExecSessions(spriteAlias),
211579
211949
  readSpriteSessions(client2, spriteAlias),
211580
- requestJson3(socketInfo.socketPath, "GET", "/ports", DAEMON_TIMEOUT_MS.quick)
211950
+ readPortsSnapshot()
211581
211951
  ]);
211582
211952
  const idToName = /* @__PURE__ */ new Map();
211583
211953
  for (const [name, id] of Object.entries(sessionMap)) {
@@ -211598,10 +211968,10 @@ var init_sessions2 = __esm({
211598
211968
  return view;
211599
211969
  });
211600
211970
  const ports = {
211601
- forwards: portsResponse.body.forwards.filter(
211971
+ forwards: portsSnapshot.forwards.filter(
211602
211972
  (entry) => entry.box === spriteAlias
211603
211973
  ),
211604
- detected: portsResponse.body.detected.filter(
211974
+ detected: portsSnapshot.detected.filter(
211605
211975
  (entry) => entry.box === spriteAlias
211606
211976
  )
211607
211977
  };
@@ -213462,11 +213832,11 @@ var init_qr = __esm({
213462
213832
  });
213463
213833
 
213464
213834
  // src/devbox/commands/setup.ts
213465
- var import_node_crypto14, trim, normalizeOrgSlug, extractOrgFromSpriteToken, parseCodexAuthMode, parseSpriteAuthMode, resolveSpriteAuthMode, normalizeSiteUrl, resolveSiteUrl, MOBILE_DOWNLOAD_LINK, parseSetupArgs, splitQrLines, printMobileDownloadQr, printFirstSetupCompleteMessage, normalizeUrlForCompare, resolveCliName3, formatSpritesApiError, probeSpritesAccess, runSetup;
213835
+ var import_node_crypto15, trim, normalizeOrgSlug, extractOrgFromSpriteToken, parseCodexAuthMode, parseSpriteAuthMode, resolveSpriteAuthMode, normalizeSiteUrl, resolveSiteUrl, MOBILE_DOWNLOAD_LINK, parseSetupArgs, splitQrLines, printMobileDownloadQr, printFirstSetupCompleteMessage, normalizeUrlForCompare, resolveCliName3, formatSpritesApiError, probeSpritesAccess, runSetup;
213466
213836
  var init_setup = __esm({
213467
213837
  "src/devbox/commands/setup.ts"() {
213468
213838
  "use strict";
213469
- import_node_crypto14 = require("node:crypto");
213839
+ import_node_crypto15 = require("node:crypto");
213470
213840
  init_src();
213471
213841
  init_src();
213472
213842
  init_auth();
@@ -213663,7 +214033,7 @@ var init_setup = __esm({
213663
214033
  return lines.join("\n");
213664
214034
  };
213665
214035
  probeSpritesAccess = async (apiBaseUrl, token) => {
213666
- const requestId = (0, import_node_crypto14.randomUUID)();
214036
+ const requestId = (0, import_node_crypto15.randomUUID)();
213667
214037
  const url = new URL("/v1/sprites", apiBaseUrl);
213668
214038
  url.searchParams.set("max_results", "1");
213669
214039
  logger7.info("sprites_request", {
@@ -214260,14 +214630,14 @@ var init_whoami = __esm({
214260
214630
  });
214261
214631
 
214262
214632
  // src/devbox/commands/wezterm.ts
214263
- var import_node_crypto15, import_node_child_process12, import_promises32, import_node_os21, import_node_path38, import_promises33, logger10, WEZTERM_APP_PATH, WEZTERM_BIN_PATH, WEZTERM_BIN_DIR, WEZTERM_INSTALL_URL, WEZTERM_PATH_EXPORT, WEZTERM_HEALTH_POLL_INTERVAL_MS, WEZTERM_HEALTH_POLL_TIMEOUT_MS, WEZTERM_PROXY_BASE_ENV, WEZTERM_PROXY_LOG_NAME, WEZTERM_USAGE, parseWeztermArgs, resolveSpriteAlias3, initWeztermClient, waitForWeztermMuxHealthy, ensureWeztermMuxReady, runWeztermProxy, runCommand6, promptYesNo2, fileExists, hasWeztermOnPath, resolveShellProfilePath, ensureWeztermOnPath, ensureWeztermInstalled, expandPath, resolveDefaultConfigPath, escapeRegExp2, resolveCliName4, resolveDvbCommand, formatLuaArgs, resolveWeztermProxyEnv, buildProxyCommand, buildDomainBlock, canAppendToConfig, countReturns, applyReturnTableTransform, insertBlock, runWeztermSetup, startWeztermDomain, runWezterm;
214633
+ var import_node_crypto16, import_node_child_process12, import_promises32, import_node_os22, import_node_path38, import_promises33, logger10, WEZTERM_APP_PATH, WEZTERM_BIN_PATH, WEZTERM_BIN_DIR, WEZTERM_INSTALL_URL, WEZTERM_PATH_EXPORT, WEZTERM_HEALTH_POLL_INTERVAL_MS, WEZTERM_HEALTH_POLL_TIMEOUT_MS, WEZTERM_PROXY_BASE_ENV, WEZTERM_PROXY_LOG_NAME, WEZTERM_USAGE, parseWeztermArgs, resolveSpriteAlias3, initWeztermClient, waitForWeztermMuxHealthy, ensureWeztermMuxReady, runWeztermProxy, runCommand6, promptYesNo2, fileExists, hasWeztermOnPath, resolveShellProfilePath, ensureWeztermOnPath, ensureWeztermInstalled, expandPath, resolveDefaultConfigPath, escapeRegExp2, resolveCliName4, resolveDvbCommand, formatLuaArgs, resolveWeztermProxyEnv, buildProxyCommand, buildDomainBlock, canAppendToConfig, countReturns, applyReturnTableTransform, insertBlock, runWeztermSetup, startWeztermDomain, runWezterm;
214264
214634
  var init_wezterm = __esm({
214265
214635
  "src/devbox/commands/wezterm.ts"() {
214266
214636
  "use strict";
214267
- import_node_crypto15 = require("node:crypto");
214637
+ import_node_crypto16 = require("node:crypto");
214268
214638
  import_node_child_process12 = require("node:child_process");
214269
214639
  import_promises32 = __toESM(require("node:fs/promises"), 1);
214270
- import_node_os21 = __toESM(require("node:os"), 1);
214640
+ import_node_os22 = __toESM(require("node:os"), 1);
214271
214641
  import_node_path38 = __toESM(require("node:path"), 1);
214272
214642
  import_promises33 = __toESM(require("node:readline/promises"), 1);
214273
214643
  init_src();
@@ -214454,7 +214824,7 @@ var init_wezterm = __esm({
214454
214824
  runWeztermProxy = async (box, port, options) => {
214455
214825
  const writeProxyLog = async (message) => {
214456
214826
  if (process.env.DEVBOX_WEZTERM_PROXY !== "1") return;
214457
- const homeDir = import_node_os21.default.homedir();
214827
+ const homeDir = import_node_os22.default.homedir();
214458
214828
  if (!homeDir) return;
214459
214829
  try {
214460
214830
  const logDir = import_node_path38.default.join(resolveDevboxDir(homeDir), "wezterm");
@@ -214475,7 +214845,7 @@ var init_wezterm = __esm({
214475
214845
  await writeProxyLog(
214476
214846
  `proxy_ready box=${spriteAlias} setup=${skipSetup ? "skip" : "full"}`
214477
214847
  );
214478
- const requestId = (0, import_node_crypto15.randomUUID)();
214848
+ const requestId = (0, import_node_crypto16.randomUUID)();
214479
214849
  const proxyPath = `/v1/sprites/${spriteAlias}/proxy`;
214480
214850
  logger10.info("sprites_request", {
214481
214851
  requestId,
@@ -215374,7 +215744,7 @@ var init_cli = __esm({
215374
215744
 
215375
215745
  // src/bin/dvb.ts
215376
215746
  var import_node_fs14 = __toESM(require("node:fs"), 1);
215377
- var import_node_os22 = __toESM(require("node:os"), 1);
215747
+ var import_node_os23 = __toESM(require("node:os"), 1);
215378
215748
  var import_node_path40 = __toESM(require("node:path"), 1);
215379
215749
  init_src();
215380
215750
  var MIN_NODE_MAJOR = 24;
@@ -215456,7 +215826,7 @@ run().catch(async (error2) => {
215456
215826
  await flushDevboxTelemetry();
215457
215827
  const message = formatErrorMessage(error2);
215458
215828
  if (process.env.DEVBOX_WEZTERM_PROXY === "1") {
215459
- const homeDir = import_node_os22.default.homedir();
215829
+ const homeDir = import_node_os23.default.homedir();
215460
215830
  if (homeDir) {
215461
215831
  try {
215462
215832
  const logDir = import_node_path40.default.join(resolveDevboxDir(homeDir), "wezterm");
@@ -215556,4 +215926,4 @@ smol-toml/dist/index.js:
215556
215926
  */
215557
215927
  //# sourceMappingURL=dvb.cjs.map
215558
215928
 
215559
- //# debugId=5b27d1b2-cb5a-5370-b4ca-61330f7946e5
215929
+ //# debugId=b688f344-5d53-57d8-9464-1da40ea2bc02