@boxes-dev/dvb 0.2.46 → 0.2.48

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
@@ -22443,7 +22443,7 @@ var init_weztermMux = __esm({
22443
22443
  });
22444
22444
 
22445
22445
  // src/devbox/commands/init/remote.ts
22446
- 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_RETRY_DELAY_MS, logger8, truncateTail, shellQuote3, expandHome2, execWithLog, isExecTimeoutError, delay2, writeRemoteFile, bootstrapDevbox, buildWeztermMuxConfig, buildWeztermMuxRunner, patchBashrc, writeRemoteCodexConfig, stageRemoteSetupArtifacts, resolveDaemonUrl, fetchDaemonBinary, buildDaemonConfig, isSameArgs, ensureSpriteDaemonService, installWeztermMux, ensureWeztermMuxService, hasWeztermMuxBinary, isWeztermMuxHealthy, installSpriteDaemon;
22446
+ 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, logger8, truncateTail, shellQuote3, expandHome2, execWithLog, writeRemoteFile, bootstrapDevbox, buildWeztermMuxConfig, buildWeztermMuxRunner, patchBashrc, writeRemoteCodexConfig, stageRemoteSetupArtifacts, resolveDaemonUrl, fetchDaemonBinary, buildDaemonConfig, isSameArgs, ensureSpriteDaemonService, installWeztermMux, ensureWeztermMuxService, hasWeztermMuxBinary, isWeztermMuxHealthy, installSpriteDaemon;
22447
22447
  var init_remote = __esm({
22448
22448
  "src/devbox/commands/init/remote.ts"() {
22449
22449
  "use strict";
@@ -22462,7 +22462,6 @@ var init_remote = __esm({
22462
22462
  DEFAULT_DAEMON_BASE_URL = process.env.SPRITE_DAEMON_BASE_URL?.trim() || "https://deploy-dev.boxes.dev";
22463
22463
  DEFAULT_HEARTBEAT_MS = 3e4;
22464
22464
  BOOTSTRAP_EXEC_TIMEOUT_MS = 9e4;
22465
- BOOTSTRAP_EXEC_RETRY_DELAY_MS = 1e4;
22466
22465
  logger8 = createLogger("devbox-init");
22467
22466
  truncateTail = (value, maxChars) => {
22468
22467
  if (value.length <= maxChars) return value;
@@ -22510,8 +22509,6 @@ var init_remote = __esm({
22510
22509
  });
22511
22510
  return result;
22512
22511
  };
22513
- isExecTimeoutError = (error) => error instanceof Error && typeof error.message === "string" && error.message.startsWith("Exec websocket timed out after ");
22514
- delay2 = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
22515
22512
  writeRemoteFile = async (client, canonical, path26, content, stage) => {
22516
22513
  const requestId = (0, import_node_crypto10.randomUUID)();
22517
22514
  logger8.info("sprites_request", {
@@ -22543,28 +22540,13 @@ var init_remote = __esm({
22543
22540
  " sudo -n chown -R sprite:sprite /home/sprite/.devbox || true",
22544
22541
  "fi"
22545
22542
  ].join("\n");
22546
- let permsResult = await execWithLog(
22543
+ const permsResult = await execWithLog(
22547
22544
  client,
22548
22545
  canonical,
22549
22546
  permissionsScript,
22550
22547
  "bootstrap-permissions",
22551
22548
  { timeoutMs: BOOTSTRAP_EXEC_TIMEOUT_MS }
22552
- ).catch(async (error) => {
22553
- if (!isExecTimeoutError(error)) throw error;
22554
- logger8.warn("sprites_exec_retry_after_timeout", {
22555
- stage: "bootstrap-permissions",
22556
- timeoutMs: BOOTSTRAP_EXEC_TIMEOUT_MS,
22557
- delayMs: BOOTSTRAP_EXEC_RETRY_DELAY_MS
22558
- });
22559
- await delay2(BOOTSTRAP_EXEC_RETRY_DELAY_MS);
22560
- return await execWithLog(
22561
- client,
22562
- canonical,
22563
- permissionsScript,
22564
- "bootstrap-permissions",
22565
- { timeoutMs: BOOTSTRAP_EXEC_TIMEOUT_MS }
22566
- );
22567
- });
22549
+ );
22568
22550
  if (permsResult.exitCode !== 0) {
22569
22551
  const details = permsResult.stderr || permsResult.stdout || "";
22570
22552
  throw new Error(
@@ -26859,7 +26841,7 @@ var init_progress = __esm({
26859
26841
  });
26860
26842
 
26861
26843
  // src/devbox/commands/init/index.ts
26862
- var import_node_path22, import_promises28, import_node_os9, resolveInitStatus, mergeLocalPaths, ensurePrivateDir, migrateLegacyRepoDevboxDir, buildServicesTomlUpdates, extractCheckpointId, writeRemoteServicesToml, enableRemoteServices, throwInitCanceled, promptBeforeOpenBrowser, toPosixPath2, toRepoRelativePath2, isOutsideRepoPath, ensureWorkdirOwnership, ensureGitSafeDirectory, runInit;
26844
+ var import_node_path22, import_promises28, import_node_os9, resolveInitStatus, mergeLocalPaths, ensurePrivateDir, DEFAULT_INIT_STEP_RETRIES, INIT_STEP_RETRYABLE_STATUSES, delay2, computeRetryDelayMs2, getErrorCode2, parseExecUnexpectedResponseStatus, isRetryableInitError, retryInitStep, migrateLegacyRepoDevboxDir, buildServicesTomlUpdates, extractCheckpointId, writeRemoteServicesToml, enableRemoteServices, throwInitCanceled, promptBeforeOpenBrowser, toPosixPath2, toRepoRelativePath2, isOutsideRepoPath, ensureWorkdirOwnership, ensureGitSafeDirectory, runInit;
26863
26845
  var init_init = __esm({
26864
26846
  "src/devbox/commands/init/index.ts"() {
26865
26847
  "use strict";
@@ -26904,6 +26886,88 @@ var init_init = __esm({
26904
26886
  } catch {
26905
26887
  }
26906
26888
  };
26889
+ DEFAULT_INIT_STEP_RETRIES = 3;
26890
+ INIT_STEP_RETRYABLE_STATUSES = /* @__PURE__ */ new Set([
26891
+ 408,
26892
+ 409,
26893
+ 425,
26894
+ 429,
26895
+ 500,
26896
+ 502,
26897
+ 503,
26898
+ 504
26899
+ ]);
26900
+ delay2 = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
26901
+ computeRetryDelayMs2 = (retryIndex) => {
26902
+ const base = 500;
26903
+ const cap = 5e3;
26904
+ const exp = Math.min(cap, base * 2 ** Math.max(0, retryIndex - 1));
26905
+ const jitter = Math.floor(Math.random() * 150);
26906
+ return exp + jitter;
26907
+ };
26908
+ getErrorCode2 = (error) => {
26909
+ if (!error || typeof error !== "object") return void 0;
26910
+ const record = error;
26911
+ const code2 = record.code;
26912
+ return typeof code2 === "string" || typeof code2 === "number" ? String(code2) : void 0;
26913
+ };
26914
+ parseExecUnexpectedResponseStatus = (error) => {
26915
+ if (!(error instanceof Error)) return null;
26916
+ const match = /Unexpected server response: (\d{3})/.exec(error.message);
26917
+ if (!match) return null;
26918
+ const status = Number(match[1]);
26919
+ return Number.isFinite(status) ? status : null;
26920
+ };
26921
+ isRetryableInitError = (error) => {
26922
+ if (error instanceof SpritesApiError) {
26923
+ return INIT_STEP_RETRYABLE_STATUSES.has(error.status);
26924
+ }
26925
+ if (error instanceof TypeError) return true;
26926
+ if (error instanceof Error && (error.name === "AbortError" || error.message.includes("aborted"))) {
26927
+ return true;
26928
+ }
26929
+ const execStatus = parseExecUnexpectedResponseStatus(error);
26930
+ if (execStatus !== null) {
26931
+ return INIT_STEP_RETRYABLE_STATUSES.has(execStatus);
26932
+ }
26933
+ const code2 = getErrorCode2(error);
26934
+ return code2 === "ECONNRESET" || code2 === "ETIMEDOUT" || code2 === "EAI_AGAIN" || code2 === "ENOTFOUND" || code2 === "ECONNREFUSED";
26935
+ };
26936
+ retryInitStep = async ({
26937
+ status,
26938
+ title,
26939
+ retries = DEFAULT_INIT_STEP_RETRIES,
26940
+ shouldRetry = isRetryableInitError,
26941
+ fn
26942
+ }) => {
26943
+ let lastError = null;
26944
+ const maxRetries = Math.max(0, Math.floor(retries));
26945
+ const attempts = maxRetries + 1;
26946
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
26947
+ try {
26948
+ return await fn();
26949
+ } catch (error) {
26950
+ lastError = error;
26951
+ const retryIndex = attempt;
26952
+ if (retryIndex > maxRetries || !shouldRetry(error)) {
26953
+ throw error;
26954
+ }
26955
+ status.stage(`${title} (retry ${retryIndex}/${maxRetries})`);
26956
+ logger7.warn("init_step_retry", {
26957
+ title,
26958
+ retry: retryIndex,
26959
+ retries: maxRetries,
26960
+ errorName: error instanceof Error ? error.name : void 0,
26961
+ errorMessage: error instanceof Error ? error.message : String(error),
26962
+ errorCode: getErrorCode2(error),
26963
+ ...error instanceof SpritesApiError ? { status: error.status } : {},
26964
+ ...parseExecUnexpectedResponseStatus(error) !== null ? { execStatus: parseExecUnexpectedResponseStatus(error) } : {}
26965
+ });
26966
+ await delay2(computeRetryDelayMs2(retryIndex));
26967
+ }
26968
+ }
26969
+ throw lastError instanceof Error ? lastError : new Error(`Init step failed: ${title}`);
26970
+ };
26907
26971
  migrateLegacyRepoDevboxDir = async ({
26908
26972
  repoRoot,
26909
26973
  projectDir
@@ -27078,15 +27142,27 @@ var init_init = __esm({
27078
27142
  client,
27079
27143
  canonical,
27080
27144
  workdir,
27081
- status,
27082
- json
27145
+ status
27083
27146
  }) => {
27084
27147
  const checkResult = await client.exec(canonical, [
27085
27148
  "/bin/bash",
27086
27149
  "-lc",
27087
- `if [ -d ${shellQuote3(workdir)} ]; then stat -c %U ${shellQuote3(workdir)}; fi`
27150
+ [
27151
+ "set -euo pipefail",
27152
+ `dir=${shellQuote3(workdir)}`,
27153
+ 'if [ ! -d "$dir" ]; then',
27154
+ ' echo "Missing workdir: $dir" >&2',
27155
+ " exit 1",
27156
+ "fi",
27157
+ 'stat -c %U "$dir"'
27158
+ ].join("\n")
27088
27159
  ]);
27089
- if (checkResult.exitCode !== 0) return;
27160
+ if (checkResult.exitCode !== 0) {
27161
+ const details = checkResult.stderr || checkResult.stdout || "";
27162
+ throw new Error(
27163
+ details ? `Failed to check workdir ownership: ${details.trim()}` : `Failed to check workdir ownership (exit ${checkResult.exitCode})`
27164
+ );
27165
+ }
27090
27166
  const owner = checkResult.stdout.trim();
27091
27167
  if (!owner || owner === "sprite") return;
27092
27168
  status.stage("Fixing workdir ownership");
@@ -27096,17 +27172,10 @@ var init_init = __esm({
27096
27172
  `sudo -n chown -R sprite:sprite ${shellQuote3(workdir)}`
27097
27173
  ]);
27098
27174
  if (chownResult.exitCode !== 0) {
27099
- logger7.warn("workdir_chown_failed", {
27100
- box: canonical,
27101
- workdir,
27102
- error: chownResult.stderr || chownResult.stdout
27103
- });
27104
- if (!json) {
27105
- status.stop();
27106
- console.warn(
27107
- "Warning: failed to update workdir ownership. Git may refuse to operate until ownership is fixed."
27108
- );
27109
- }
27175
+ const details = chownResult.stderr || chownResult.stdout || "";
27176
+ throw new Error(
27177
+ details ? `Failed to update workdir ownership: ${details.trim()}` : `Failed to update workdir ownership (exit ${chownResult.exitCode})`
27178
+ );
27110
27179
  }
27111
27180
  };
27112
27181
  ensureGitSafeDirectory = async ({
@@ -27470,7 +27539,7 @@ var init_init = __esm({
27470
27539
  fingerprint,
27471
27540
  phase: label
27472
27541
  });
27473
- return { id: null, comment, createdAt };
27542
+ throw new Error("Checkpoint ID missing.");
27474
27543
  }
27475
27544
  const record = { id, comment, createdAt };
27476
27545
  if (initState) {
@@ -27649,13 +27718,17 @@ var init_init = __esm({
27649
27718
  });
27650
27719
  await runInitStep({
27651
27720
  enabled: progressEnabled,
27652
- title: "Snapshotting filesystem (pre-setup) (optional)",
27653
- fn: async ({ fail, ok }) => {
27721
+ title: "Snapshotting filesystem (pre-setup)",
27722
+ fn: async ({ status, fail, ok }) => {
27654
27723
  try {
27655
- const checkpoint = await recordCodexCheckpoint({
27656
- client: client2,
27657
- canonical: canonical2,
27658
- phase: "preCodexSetup"
27724
+ const checkpoint = await retryInitStep({
27725
+ status,
27726
+ title: "Snapshotting filesystem (pre-setup)",
27727
+ fn: async () => await recordCodexCheckpoint({
27728
+ client: client2,
27729
+ canonical: canonical2,
27730
+ phase: "preCodexSetup"
27731
+ })
27659
27732
  });
27660
27733
  if (checkpoint.id) {
27661
27734
  ok(`Snapshot created: ${checkpoint.id}`);
@@ -27667,12 +27740,8 @@ var init_init = __esm({
27667
27740
  phase: "pre-codex-setup",
27668
27741
  error: error instanceof Error ? error.message : String(error)
27669
27742
  });
27670
- fail("Snapshotting filesystem (pre-setup) (optional) (failed)");
27671
- if (!parsed.json) {
27672
- console.warn(
27673
- "Warning: failed to create pre-setup filesystem snapshot. Continuing without it."
27674
- );
27675
- }
27743
+ fail("Snapshotting filesystem (pre-setup) (failed)");
27744
+ throw error;
27676
27745
  }
27677
27746
  }
27678
27747
  });
@@ -27708,13 +27777,17 @@ var init_init = __esm({
27708
27777
  });
27709
27778
  await runInitStep({
27710
27779
  enabled: progressEnabled,
27711
- title: "Snapshotting filesystem (post-setup) (optional)",
27712
- fn: async ({ fail, ok }) => {
27780
+ title: "Snapshotting filesystem (post-setup)",
27781
+ fn: async ({ status, fail, ok }) => {
27713
27782
  try {
27714
- const checkpoint = await recordCodexCheckpoint({
27715
- client: client2,
27716
- canonical: canonical2,
27717
- phase: "postCodexSetup"
27783
+ const checkpoint = await retryInitStep({
27784
+ status,
27785
+ title: "Snapshotting filesystem (post-setup)",
27786
+ fn: async () => await recordCodexCheckpoint({
27787
+ client: client2,
27788
+ canonical: canonical2,
27789
+ phase: "postCodexSetup"
27790
+ })
27718
27791
  });
27719
27792
  if (checkpoint.id) {
27720
27793
  ok(`Snapshot created: ${checkpoint.id}`);
@@ -27726,12 +27799,8 @@ var init_init = __esm({
27726
27799
  phase: "post-codex-setup",
27727
27800
  error: error instanceof Error ? error.message : String(error)
27728
27801
  });
27729
- fail("Snapshotting filesystem (post-setup) (optional) (failed)");
27730
- if (!parsed.json) {
27731
- console.warn(
27732
- "Warning: failed to create post-setup filesystem snapshot. Continuing without it."
27733
- );
27734
- }
27802
+ fail("Snapshotting filesystem (post-setup) (failed)");
27803
+ throw error;
27735
27804
  }
27736
27805
  }
27737
27806
  });
@@ -27897,40 +27966,33 @@ var init_init = __esm({
27897
27966
  localPaths: projectLocalPaths
27898
27967
  });
27899
27968
  const updateRegistryProjectStatus = async (initStatus) => {
27900
- try {
27901
- await requestJson3(
27902
- socketInfo.socketPath,
27903
- "POST",
27904
- "/registry/upsert",
27905
- DAEMON_TIMEOUT_MS.registry,
27906
- {
27907
- project: buildProjectEntry(initStatus)
27908
- }
27909
- );
27910
- } catch (error) {
27911
- logger7.warn("registry_project_update_failed", {
27912
- box: canonical,
27913
- status: initStatus,
27914
- error: String(error)
27915
- });
27916
- }
27969
+ await requestJson3(
27970
+ socketInfo.socketPath,
27971
+ "POST",
27972
+ "/registry/upsert",
27973
+ DAEMON_TIMEOUT_MS.registry,
27974
+ {
27975
+ project: buildProjectEntry(initStatus)
27976
+ }
27977
+ );
27917
27978
  };
27918
27979
  await runInitStep({
27919
27980
  enabled: progressEnabled,
27920
27981
  title: "Bootstrapping devbox",
27921
- fn: async ({ fail }) => {
27982
+ fn: async ({ status, fail }) => {
27922
27983
  try {
27923
- await bootstrapDevbox(client, canonical);
27984
+ await retryInitStep({
27985
+ status,
27986
+ title: "Bootstrapping devbox",
27987
+ fn: async () => await bootstrapDevbox(client, canonical)
27988
+ });
27924
27989
  } catch (error) {
27925
27990
  logger7.warn("devbox_bootstrap_failed", {
27926
27991
  box: canonical,
27927
27992
  error: String(error)
27928
27993
  });
27929
27994
  fail("Bootstrapping devbox (failed)");
27930
- if (!parsed.json) {
27931
- const message = error instanceof Error && error.message ? error.message : String(error);
27932
- console.warn(`Warning: devbox bootstrap failed. ${message}`);
27933
- }
27995
+ throw error;
27934
27996
  }
27935
27997
  }
27936
27998
  });
@@ -27971,7 +28033,7 @@ var init_init = __esm({
27971
28033
  await runInitStep({
27972
28034
  enabled: progressEnabled,
27973
28035
  title: "Installing sprite daemon",
27974
- fn: async ({ fail }) => {
28036
+ fn: async ({ status, fail }) => {
27975
28037
  try {
27976
28038
  const convexUrl = getConvexUrl();
27977
28039
  if (!controlPlaneToken) {
@@ -27993,12 +28055,16 @@ var init_init = __esm({
27993
28055
  if (!heartbeatToken) {
27994
28056
  throw new Error("Daemon token unavailable.");
27995
28057
  }
27996
- await installSpriteDaemon({
27997
- client,
27998
- spriteName: canonical,
27999
- release,
28000
- convexUrl,
28001
- heartbeatToken
28058
+ await retryInitStep({
28059
+ status,
28060
+ title: "Installing sprite daemon",
28061
+ fn: async () => await installSpriteDaemon({
28062
+ client,
28063
+ spriteName: canonical,
28064
+ release,
28065
+ convexUrl,
28066
+ heartbeatToken
28067
+ })
28002
28068
  });
28003
28069
  await updateInitState({ steps: { daemonInstalled: true } });
28004
28070
  } catch (error) {
@@ -28007,12 +28073,7 @@ var init_init = __esm({
28007
28073
  error: String(error)
28008
28074
  });
28009
28075
  fail("Installing sprite daemon (failed)");
28010
- if (!parsed.json) {
28011
- const message = error instanceof Error && error.message ? error.message : String(error);
28012
- console.warn(
28013
- `Warning: failed to install sprite daemon. ${message}`
28014
- );
28015
- }
28076
+ throw error;
28016
28077
  }
28017
28078
  }
28018
28079
  });
@@ -28020,9 +28081,13 @@ var init_init = __esm({
28020
28081
  await runInitStep({
28021
28082
  enabled: progressEnabled,
28022
28083
  title: "Ensuring sprite daemon service",
28023
- fn: async ({ fail }) => {
28084
+ fn: async ({ status, fail }) => {
28024
28085
  try {
28025
- await ensureSpriteDaemonService({ client, spriteName: canonical });
28086
+ await retryInitStep({
28087
+ status,
28088
+ title: "Ensuring sprite daemon service",
28089
+ fn: async () => await ensureSpriteDaemonService({ client, spriteName: canonical })
28090
+ });
28026
28091
  await updateInitState({ steps: { daemonServiceEnsured: true } });
28027
28092
  } catch (error) {
28028
28093
  logger7.warn("sprite_daemon_service_failed", {
@@ -28030,12 +28095,7 @@ var init_init = __esm({
28030
28095
  error: String(error)
28031
28096
  });
28032
28097
  fail("Ensuring sprite daemon service (failed)");
28033
- if (!parsed.json) {
28034
- const message = error instanceof Error && error.message ? error.message : String(error);
28035
- console.warn(
28036
- `Warning: failed to ensure sprite daemon service. ${message}`
28037
- );
28038
- }
28098
+ throw error;
28039
28099
  }
28040
28100
  }
28041
28101
  });
@@ -28905,12 +28965,15 @@ var init_init = __esm({
28905
28965
  enabled: progressEnabled,
28906
28966
  title: "Ensuring workdir ownership",
28907
28967
  fn: async ({ status }) => {
28908
- await ensureWorkdirOwnership({
28909
- client,
28910
- canonical,
28911
- workdir: expandedWorkdir,
28968
+ await retryInitStep({
28912
28969
  status,
28913
- json: parsed.json === true
28970
+ title: "Ensuring workdir ownership",
28971
+ fn: async () => await ensureWorkdirOwnership({
28972
+ client,
28973
+ canonical,
28974
+ workdir: expandedWorkdir,
28975
+ status
28976
+ })
28914
28977
  });
28915
28978
  }
28916
28979
  });
@@ -28935,13 +28998,19 @@ var init_init = __esm({
28935
28998
  await runInitStep({
28936
28999
  enabled: progressEnabled,
28937
29000
  title: "Configuring SSH mount access",
28938
- fn: async ({ fail }) => {
29001
+ fn: async ({ status, fail }) => {
28939
29002
  try {
28940
- await ensureLocalMountKey();
28941
- await ensureKnownHostsFile();
28942
- const publicKey = await readLocalMountPublicKey();
28943
- await ensureRemoteMountAccess(client, canonical, publicKey);
28944
- await ensureSshdService(client, canonical);
29003
+ await retryInitStep({
29004
+ status,
29005
+ title: "Configuring SSH mount access",
29006
+ fn: async () => {
29007
+ await ensureLocalMountKey();
29008
+ await ensureKnownHostsFile();
29009
+ const publicKey = await readLocalMountPublicKey();
29010
+ await ensureRemoteMountAccess(client, canonical, publicKey);
29011
+ await ensureSshdService(client, canonical);
29012
+ }
29013
+ });
28945
29014
  await updateInitState({ steps: { sshdConfigured: true } });
28946
29015
  } catch (error) {
28947
29016
  logger7.warn("sshd_config_failed", {
@@ -28949,13 +29018,7 @@ var init_init = __esm({
28949
29018
  error: String(error)
28950
29019
  });
28951
29020
  fail("Configuring SSH mount access (failed)");
28952
- if (!parsed.json) {
28953
- const message = error instanceof Error && error.message ? error.message : String(error);
28954
- console.warn(
28955
- `Warning: failed to configure SSH mount access. ${message}`
28956
- );
28957
- console.warn(`To retry later: dvb mount ${alias}`);
28958
- }
29021
+ throw error;
28959
29022
  }
28960
29023
  }
28961
29024
  });
@@ -29113,10 +29176,12 @@ var init_init = __esm({
29113
29176
  }
29114
29177
  const weztermMuxPresent = await runInitStep({
29115
29178
  enabled: progressEnabled,
29116
- title: "Ensuring WezTerm mux server (optional)",
29117
- fn: async ({ fail }) => {
29118
- try {
29119
- const installResult = !shouldResume || !initState?.steps.weztermMuxInstalled ? await ensureWeztermMuxInstalled({
29179
+ title: "Ensuring WezTerm mux server",
29180
+ fn: async ({ status }) => {
29181
+ const installResult = await retryInitStep({
29182
+ status,
29183
+ title: "Ensuring WezTerm mux server",
29184
+ fn: async () => !shouldResume || !initState?.steps.weztermMuxInstalled ? await ensureWeztermMuxInstalled({
29120
29185
  client,
29121
29186
  spriteName: canonical,
29122
29187
  allowResolveAsset: true
@@ -29125,49 +29190,29 @@ var init_init = __esm({
29125
29190
  spriteName: canonical,
29126
29191
  // If the mux is missing on resume, we still need to resolve a GitHub asset.
29127
29192
  allowResolveAsset: true
29128
- });
29129
- if (installResult.muxPresent) {
29130
- await updateInitState({ steps: { weztermMuxInstalled: true } });
29131
- }
29132
- return installResult.muxPresent;
29133
- } catch (error) {
29134
- logger7.warn("wezterm_mux_install_failed", {
29135
- box: canonical,
29136
- error: error instanceof Error ? error.message : String(error)
29137
- });
29138
- fail("Ensuring WezTerm mux server (optional) (failed)");
29139
- if (!parsed.json) {
29140
- const message = error instanceof Error && error.message ? error.message : String(error);
29141
- console.warn(
29142
- `Warning: failed to install WezTerm mux server (optional). ${message}
29143
- Tip: re-run with DEVBOX_LOG_LEVEL=info to see Sprite exec logs on stderr.`
29144
- );
29145
- }
29146
- return false;
29193
+ })
29194
+ });
29195
+ if (installResult.muxPresent) {
29196
+ await updateInitState({ steps: { weztermMuxInstalled: true } });
29197
+ return true;
29147
29198
  }
29199
+ throw new Error("WezTerm mux server unavailable.");
29148
29200
  }
29149
29201
  });
29150
- if (weztermMuxPresent && (!shouldResume || !initState?.steps.weztermMuxServiceEnsured)) {
29202
+ if (!shouldResume || !initState?.steps.weztermMuxServiceEnsured) {
29151
29203
  await runInitStep({
29152
29204
  enabled: progressEnabled,
29153
- title: "Ensuring WezTerm mux service (optional)",
29154
- fn: async ({ fail }) => {
29155
- try {
29156
- await ensureWeztermMuxService({ client, spriteName: canonical });
29157
- await updateInitState({ steps: { weztermMuxServiceEnsured: true } });
29158
- } catch (error) {
29159
- logger7.warn("wezterm_mux_service_failed", {
29160
- box: canonical,
29161
- error: error instanceof Error ? error.message : String(error)
29162
- });
29163
- fail("Ensuring WezTerm mux service (optional) (failed)");
29164
- if (!parsed.json) {
29165
- const message = error instanceof Error && error.message ? error.message : String(error);
29166
- console.warn(
29167
- `Warning: failed to ensure WezTerm mux service (optional). ${message}`
29168
- );
29169
- }
29205
+ title: "Ensuring WezTerm mux service",
29206
+ fn: async ({ status }) => {
29207
+ if (!weztermMuxPresent) {
29208
+ throw new Error("WezTerm mux server unavailable.");
29170
29209
  }
29210
+ await retryInitStep({
29211
+ status,
29212
+ title: "Ensuring WezTerm mux service",
29213
+ fn: async () => await ensureWeztermMuxService({ client, spriteName: canonical })
29214
+ });
29215
+ await updateInitState({ steps: { weztermMuxServiceEnsured: true } });
29171
29216
  }
29172
29217
  });
29173
29218
  }
@@ -29234,21 +29279,13 @@ Tip: re-run with DEVBOX_LOG_LEVEL=info to see Sprite exec logs on stderr.`
29234
29279
  });
29235
29280
  await runInitStep({
29236
29281
  enabled: progressEnabled,
29237
- title: "Updating Codex config on sprite (optional)",
29238
- fn: async ({ fail }) => {
29239
- try {
29240
- await writeRemoteCodexConfig(client, canonical, repoName);
29241
- } catch (error) {
29242
- logger7.warn("codex_config_update_failed", {
29243
- error: String(error)
29244
- });
29245
- fail("Updating Codex config on sprite (optional) (failed)");
29246
- if (!parsed.json) {
29247
- console.warn(
29248
- "Warning: failed to update /home/sprite/.codex/config.toml for full-access sandbox settings."
29249
- );
29250
- }
29251
- }
29282
+ title: "Updating Codex config on sprite",
29283
+ fn: async ({ status }) => {
29284
+ await retryInitStep({
29285
+ status,
29286
+ title: "Updating Codex config on sprite",
29287
+ fn: async () => await writeRemoteCodexConfig(client, canonical, repoName)
29288
+ });
29252
29289
  }
29253
29290
  });
29254
29291
  const skipSetupArtifactsStage = skipCodexApply || shouldResume && initState?.steps.setupArtifactsStaged;
@@ -29272,13 +29309,17 @@ Tip: re-run with DEVBOX_LOG_LEVEL=info to see Sprite exec logs on stderr.`
29272
29309
  if (!skipCodexApply) {
29273
29310
  await runInitStep({
29274
29311
  enabled: progressEnabled,
29275
- title: "Snapshotting filesystem (pre-setup) (optional)",
29276
- fn: async ({ fail, ok }) => {
29312
+ title: "Snapshotting filesystem (pre-setup)",
29313
+ fn: async ({ status, fail, ok }) => {
29277
29314
  try {
29278
- const checkpoint = await recordCodexCheckpoint({
29279
- client,
29280
- canonical,
29281
- phase: "preCodexSetup"
29315
+ const checkpoint = await retryInitStep({
29316
+ status,
29317
+ title: "Snapshotting filesystem (pre-setup)",
29318
+ fn: async () => await recordCodexCheckpoint({
29319
+ client,
29320
+ canonical,
29321
+ phase: "preCodexSetup"
29322
+ })
29282
29323
  });
29283
29324
  if (checkpoint.id) {
29284
29325
  ok(`Snapshot created: ${checkpoint.id}`);
@@ -29290,12 +29331,8 @@ Tip: re-run with DEVBOX_LOG_LEVEL=info to see Sprite exec logs on stderr.`
29290
29331
  phase: "pre-codex-setup",
29291
29332
  error: error instanceof Error ? error.message : String(error)
29292
29333
  });
29293
- fail("Snapshotting filesystem (pre-setup) (optional) (failed)");
29294
- if (!parsed.json) {
29295
- console.warn(
29296
- "Warning: failed to create pre-setup filesystem snapshot. Continuing without it."
29297
- );
29298
- }
29334
+ fail("Snapshotting filesystem (pre-setup) (failed)");
29335
+ throw error;
29299
29336
  }
29300
29337
  }
29301
29338
  });
@@ -29338,13 +29375,17 @@ Tip: re-run with DEVBOX_LOG_LEVEL=info to see Sprite exec logs on stderr.`
29338
29375
  );
29339
29376
  await runInitStep({
29340
29377
  enabled: progressEnabled,
29341
- title: "Snapshotting filesystem (post-setup) (optional)",
29342
- fn: async ({ fail, ok }) => {
29378
+ title: "Snapshotting filesystem (post-setup)",
29379
+ fn: async ({ status, fail, ok }) => {
29343
29380
  try {
29344
- const checkpoint = await recordCodexCheckpoint({
29345
- client,
29346
- canonical,
29347
- phase: "postCodexSetup"
29381
+ const checkpoint = await retryInitStep({
29382
+ status,
29383
+ title: "Snapshotting filesystem (post-setup)",
29384
+ fn: async () => await recordCodexCheckpoint({
29385
+ client,
29386
+ canonical,
29387
+ phase: "postCodexSetup"
29388
+ })
29348
29389
  });
29349
29390
  if (checkpoint.id) {
29350
29391
  ok(`Snapshot created: ${checkpoint.id}`);
@@ -29356,12 +29397,8 @@ Tip: re-run with DEVBOX_LOG_LEVEL=info to see Sprite exec logs on stderr.`
29356
29397
  phase: "post-codex-setup",
29357
29398
  error: error instanceof Error ? error.message : String(error)
29358
29399
  });
29359
- fail("Snapshotting filesystem (post-setup) (optional) (failed)");
29360
- if (!parsed.json) {
29361
- console.warn(
29362
- "Warning: failed to create post-setup filesystem snapshot. Continuing without it."
29363
- );
29364
- }
29400
+ fail("Snapshotting filesystem (post-setup) (failed)");
29401
+ throw error;
29365
29402
  }
29366
29403
  }
29367
29404
  });