@boxes-dev/dvb 1.0.77 → 1.0.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/dvb.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="080b5259-7ff1-5cae-8b1d-315abb34a68e")}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]="b785e941-0159-5a32-9ac9-c3686e30d3af")}catch(e){}}();
4
4
 
5
5
  var __create = Object.create;
6
6
  var __defProp = Object.defineProperty;
@@ -88688,8 +88688,8 @@ var init_otel = __esm({
88688
88688
  return trimmed && trimmed.length > 0 ? trimmed : void 0;
88689
88689
  };
88690
88690
  readBuildMetadata = () => {
88691
- const rawPackageVersion = "1.0.77";
88692
- const rawGitSha = "17fefd5b7fdac0e2ca0097ce453c614262d9e6d3";
88691
+ const rawPackageVersion = "1.0.79";
88692
+ const rawGitSha = "ceaceb54444acf1719c1f5fc72074b5048324e4a";
88693
88693
  const packageVersion = typeof rawPackageVersion === "string" ? rawPackageVersion : void 0;
88694
88694
  const gitSha = typeof rawGitSha === "string" ? rawGitSha : void 0;
88695
88695
  return { packageVersion, gitSha };
@@ -120679,9 +120679,9 @@ var init_sentry = __esm({
120679
120679
  sentryEnabled = false;
120680
120680
  uncaughtExceptionMonitorInstalled = false;
120681
120681
  readBuildMetadata2 = () => {
120682
- const rawPackageVersion = "1.0.77";
120683
- const rawGitSha = "17fefd5b7fdac0e2ca0097ce453c614262d9e6d3";
120684
- const rawSentryRelease = "boxes-dev-dvb@1.0.77+17fefd5b7fdac0e2ca0097ce453c614262d9e6d3";
120682
+ const rawPackageVersion = "1.0.79";
120683
+ const rawGitSha = "ceaceb54444acf1719c1f5fc72074b5048324e4a";
120684
+ const rawSentryRelease = "boxes-dev-dvb@1.0.79+ceaceb54444acf1719c1f5fc72074b5048324e4a";
120685
120685
  const packageVersion = typeof rawPackageVersion === "string" ? rawPackageVersion : void 0;
120686
120686
  const gitSha = typeof rawGitSha === "string" ? rawGitSha : void 0;
120687
120687
  const sentryRelease = typeof rawSentryRelease === "string" ? rawSentryRelease : void 0;
@@ -141302,7 +141302,9 @@ var init_statusLine = __esm({
141302
141302
  enabled,
141303
141303
  stream = process.stderr
141304
141304
  }) => {
141305
- if (!enabled) {
141305
+ const usableColumns = typeof stream.columns !== "number" || stream.columns > 0;
141306
+ const spinnerEnabled = enabled && (!stream.isTTY || usableColumns);
141307
+ if (!spinnerEnabled) {
141306
141308
  return {
141307
141309
  stage: () => {
141308
141310
  },
@@ -198479,6 +198481,592 @@ ${result.exception}`
198479
198481
  }
198480
198482
  });
198481
198483
 
198484
+ // src/devbox/commands/provider/modalLifecycle.ts
198485
+ var import_node_crypto9, DEFAULT_APP_NAME, DEFAULT_MODAL_ENVIRONMENT, DEFAULT_MODAL_DEVBOX_IMAGE, DEFAULT_TIMEOUT_MS, IMAGE_TAG_RESOLUTION_CACHE_TTL_MS, SANDBOX_LIST_PAGE_LIMIT, MODAL_DAEMON_WRAPPER_PATH, MODAL_DAEMON_SUPERVISOR_ENTRYPOINT, FINISHED_STATUS_LABELS, REGISTRY_MANIFEST_ACCEPT_HEADER, resolvedImageTagCache, trimEnv2, EMBEDDED_BUILD_PROFILE, resolveModalEnvironmentName, resolveConvexInstanceSeed, resolveDevModalSandboxPrefix, resolveModalSandboxName, parseRegistryImageTag, parseWwwAuthenticateBearer, fetchRegistryToken, resolveLatestImageTagToDigest, resolveImageTagForBuild, decodeJwtExpMs, createSafeModalAuthTokenManager, installSafeModalAuthTokenManager, parsePositiveInt, resolveRegions, resolveAppName, resolveModalSandboxTimeoutMs, isNotFoundError, isModalAlreadyExistsError, trimToNull, resolveControlPlaneToken, hasContextModalCredentialPair, shouldUseControlPlaneFallback, withModalClient, resolveModalApp, listSandboxesRaw, formatSandboxStatus, isRunningSandbox, resolveImageFromTag, provisionModalSandbox, findModalSandbox, terminateModalSandboxesByAlias;
198486
+ var init_modalLifecycle = __esm({
198487
+ "src/devbox/commands/provider/modalLifecycle.ts"() {
198488
+ "use strict";
198489
+ init_src();
198490
+ import_node_crypto9 = require("node:crypto");
198491
+ init_dist5();
198492
+ init_controlPlane();
198493
+ DEFAULT_APP_NAME = "sandbox-modal-smoke";
198494
+ DEFAULT_MODAL_ENVIRONMENT = "main";
198495
+ DEFAULT_MODAL_DEVBOX_IMAGE = "public.ecr.aws/d8m4p4w9/modal-devbox:latest";
198496
+ DEFAULT_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
198497
+ IMAGE_TAG_RESOLUTION_CACHE_TTL_MS = 5 * 60 * 1e3;
198498
+ SANDBOX_LIST_PAGE_LIMIT = 100;
198499
+ MODAL_DAEMON_WRAPPER_PATH = "/root/.devbox/daemon/run-daemon.sh";
198500
+ MODAL_DAEMON_SUPERVISOR_ENTRYPOINT = [
198501
+ "/bin/sh",
198502
+ "-lc",
198503
+ [
198504
+ "set -u",
198505
+ `wrapper=${JSON.stringify(MODAL_DAEMON_WRAPPER_PATH)}`,
198506
+ 'until [ -x "$wrapper" ]; do sleep 0.25; done',
198507
+ "while true; do",
198508
+ ' "$wrapper"',
198509
+ " status=$?",
198510
+ ' echo "sprite-daemon exited with status $status; restarting" >&2',
198511
+ " sleep 1",
198512
+ "done"
198513
+ ].join("\n")
198514
+ ];
198515
+ FINISHED_STATUS_LABELS = {
198516
+ 1: "success",
198517
+ 2: "failure",
198518
+ 3: "terminated",
198519
+ 4: "timeout",
198520
+ 5: "init_failure",
198521
+ 6: "internal_failure",
198522
+ 7: "idle_timeout"
198523
+ };
198524
+ REGISTRY_MANIFEST_ACCEPT_HEADER = [
198525
+ "application/vnd.oci.image.index.v1+json",
198526
+ "application/vnd.oci.image.manifest.v1+json",
198527
+ "application/vnd.docker.distribution.manifest.list.v2+json",
198528
+ "application/vnd.docker.distribution.manifest.v2+json"
198529
+ ].join(", ");
198530
+ resolvedImageTagCache = /* @__PURE__ */ new Map();
198531
+ trimEnv2 = (value) => value?.trim() ?? "";
198532
+ EMBEDDED_BUILD_PROFILE = resolveDevboxProfile();
198533
+ resolveModalEnvironmentName = () => {
198534
+ if (!EMBEDDED_BUILD_PROFILE) {
198535
+ return DEFAULT_MODAL_ENVIRONMENT;
198536
+ }
198537
+ return trimEnv2(process.env.MODAL_ENVIRONMENT) || "dev";
198538
+ };
198539
+ resolveConvexInstanceSeed = () => {
198540
+ const candidates = [
198541
+ trimEnv2(process.env.DEVBOX_CONVEX_URL),
198542
+ trimEnv2(process.env.CONVEX_CLOUD_URL),
198543
+ trimEnv2(process.env.CONVEX_SITE_URL)
198544
+ ].filter((value) => value.length > 0);
198545
+ const raw = candidates[0];
198546
+ if (!raw) {
198547
+ return null;
198548
+ }
198549
+ let normalized = raw;
198550
+ if (normalized.startsWith("dev:")) {
198551
+ normalized = normalized.slice(4);
198552
+ }
198553
+ if (normalized.includes(".convex.site")) {
198554
+ normalized = normalized.replace(".convex.site", ".convex.cloud");
198555
+ }
198556
+ if (!normalized.startsWith("http://") && !normalized.startsWith("https://")) {
198557
+ normalized = `https://${normalized}`;
198558
+ }
198559
+ try {
198560
+ return new URL(normalized).host.toLowerCase();
198561
+ } catch {
198562
+ return normalized.toLowerCase();
198563
+ }
198564
+ };
198565
+ resolveDevModalSandboxPrefix = () => {
198566
+ const seed = resolveConvexInstanceSeed();
198567
+ if (!seed) {
198568
+ throw new Error(
198569
+ "Missing Convex deployment URL context for MODAL_ENVIRONMENT=dev. Set DEVBOX_CONVEX_URL or CONVEX_CLOUD_URL."
198570
+ );
198571
+ }
198572
+ return (0, import_node_crypto9.createHash)("sha256").update(seed).digest("hex").slice(0, 8);
198573
+ };
198574
+ resolveModalSandboxName = (alias, environmentName) => {
198575
+ const normalizedAlias = alias.trim();
198576
+ if (!normalizedAlias) {
198577
+ throw new Error("Modal alias is required.");
198578
+ }
198579
+ if (environmentName !== "dev") {
198580
+ return normalizedAlias;
198581
+ }
198582
+ return `${resolveDevModalSandboxPrefix()}-${normalizedAlias}`;
198583
+ };
198584
+ parseRegistryImageTag = (imageTag) => {
198585
+ const trimmed = imageTag.trim();
198586
+ if (!trimmed || trimmed.includes("@")) {
198587
+ return null;
198588
+ }
198589
+ const lastSlashIndex = trimmed.lastIndexOf("/");
198590
+ const lastColonIndex = trimmed.lastIndexOf(":");
198591
+ if (lastColonIndex <= lastSlashIndex) {
198592
+ return null;
198593
+ }
198594
+ const repositoryWithHost = trimmed.slice(0, lastColonIndex);
198595
+ const tag = trimmed.slice(lastColonIndex + 1).trim();
198596
+ if (!repositoryWithHost || !tag) {
198597
+ return null;
198598
+ }
198599
+ const firstSlashIndex = repositoryWithHost.indexOf("/");
198600
+ if (firstSlashIndex <= 0) {
198601
+ return null;
198602
+ }
198603
+ const registryHost = repositoryWithHost.slice(0, firstSlashIndex);
198604
+ const repository = repositoryWithHost.slice(firstSlashIndex + 1);
198605
+ if (!repository) {
198606
+ return null;
198607
+ }
198608
+ const hasExplicitRegistryHost = registryHost.includes(".") || registryHost.includes(":") || registryHost === "localhost";
198609
+ if (!hasExplicitRegistryHost) {
198610
+ return null;
198611
+ }
198612
+ return {
198613
+ registryHost,
198614
+ repository,
198615
+ tag,
198616
+ repositoryWithHost
198617
+ };
198618
+ };
198619
+ parseWwwAuthenticateBearer = (headerValue) => {
198620
+ const trimmed = headerValue.trim();
198621
+ if (!trimmed.toLowerCase().startsWith("bearer ")) {
198622
+ return null;
198623
+ }
198624
+ const attributes = /* @__PURE__ */ new Map();
198625
+ for (const match2 of trimmed.slice("bearer ".length).matchAll(/([A-Za-z0-9_-]+)="([^"]*)"/g)) {
198626
+ const [, key, value] = match2;
198627
+ if (!key) {
198628
+ continue;
198629
+ }
198630
+ attributes.set(key.toLowerCase(), value ?? "");
198631
+ }
198632
+ const realm = attributes.get("realm");
198633
+ const service = attributes.get("service");
198634
+ const scope = attributes.get("scope");
198635
+ if (!realm || !service) {
198636
+ return null;
198637
+ }
198638
+ return {
198639
+ realm,
198640
+ service,
198641
+ scope: scope || null
198642
+ };
198643
+ };
198644
+ fetchRegistryToken = async ({
198645
+ realm,
198646
+ service,
198647
+ scope
198648
+ }) => {
198649
+ const tokenUrl = new URL(realm);
198650
+ tokenUrl.searchParams.set("service", service);
198651
+ if (scope) {
198652
+ tokenUrl.searchParams.set("scope", scope);
198653
+ }
198654
+ const response = await fetch(tokenUrl.toString());
198655
+ if (!response.ok) {
198656
+ throw new Error(
198657
+ `Container registry auth token request failed (${response.status}).`
198658
+ );
198659
+ }
198660
+ const payload = await response.json();
198661
+ const token = typeof payload.token === "string" ? payload.token.trim() : typeof payload.access_token === "string" ? payload.access_token.trim() : "";
198662
+ if (!token) {
198663
+ throw new Error("Container registry auth token response was empty.");
198664
+ }
198665
+ return token;
198666
+ };
198667
+ resolveLatestImageTagToDigest = async (parsed) => {
198668
+ const manifestUrl = `https://${parsed.registryHost}/v2/${parsed.repository}/manifests/${encodeURIComponent(parsed.tag)}`;
198669
+ const fetchManifest = async ({
198670
+ method,
198671
+ token: token2
198672
+ }) => {
198673
+ const headers = {
198674
+ Accept: REGISTRY_MANIFEST_ACCEPT_HEADER
198675
+ };
198676
+ if (token2) {
198677
+ headers.Authorization = `Bearer ${token2}`;
198678
+ }
198679
+ return await fetch(manifestUrl, {
198680
+ headers,
198681
+ method
198682
+ });
198683
+ };
198684
+ let token = null;
198685
+ let headResponse = await fetchManifest({ method: "HEAD" });
198686
+ if (headResponse.status === 401) {
198687
+ const authHeader = headResponse.headers.get("www-authenticate") ?? "";
198688
+ const challenge = parseWwwAuthenticateBearer(authHeader);
198689
+ if (!challenge) {
198690
+ throw new Error(
198691
+ `Container registry auth challenge missing or invalid for ${parsed.repositoryWithHost}:${parsed.tag}.`
198692
+ );
198693
+ }
198694
+ token = await fetchRegistryToken(challenge);
198695
+ headResponse = await fetchManifest({
198696
+ method: "HEAD",
198697
+ token
198698
+ });
198699
+ }
198700
+ if (!headResponse.ok) {
198701
+ throw new Error(
198702
+ `Container registry manifest lookup failed for ${parsed.repositoryWithHost}:${parsed.tag} (${headResponse.status}).`
198703
+ );
198704
+ }
198705
+ const headDigest = headResponse.headers.get("docker-content-digest")?.trim();
198706
+ if (headDigest) {
198707
+ return `${parsed.repositoryWithHost}@${headDigest}`;
198708
+ }
198709
+ const getResponse = await fetchManifest(
198710
+ token ? {
198711
+ method: "GET",
198712
+ token
198713
+ } : {
198714
+ method: "GET"
198715
+ }
198716
+ );
198717
+ if (!getResponse.ok) {
198718
+ throw new Error(
198719
+ `Container registry manifest body lookup failed for ${parsed.repositoryWithHost}:${parsed.tag} (${getResponse.status}).`
198720
+ );
198721
+ }
198722
+ const headerDigest = getResponse.headers.get("docker-content-digest")?.trim();
198723
+ if (headerDigest) {
198724
+ return `${parsed.repositoryWithHost}@${headerDigest}`;
198725
+ }
198726
+ const manifestBytes = Buffer.from(await getResponse.arrayBuffer());
198727
+ const bodyDigest = `sha256:${(0, import_node_crypto9.createHash)("sha256").update(manifestBytes).digest("hex")}`;
198728
+ return `${parsed.repositoryWithHost}@${bodyDigest}`;
198729
+ };
198730
+ resolveImageTagForBuild = async (imageTag) => {
198731
+ const parsed = parseRegistryImageTag(imageTag);
198732
+ if (!parsed || parsed.tag !== "latest") {
198733
+ return imageTag;
198734
+ }
198735
+ const cacheKey = `${parsed.repositoryWithHost}:${parsed.tag}`;
198736
+ const now = Date.now();
198737
+ const cached = resolvedImageTagCache.get(cacheKey);
198738
+ if (cached && cached.expiresAt > now) {
198739
+ return cached.value;
198740
+ }
198741
+ const resolved = await resolveLatestImageTagToDigest(parsed);
198742
+ resolvedImageTagCache.set(cacheKey, {
198743
+ value: resolved,
198744
+ expiresAt: now + IMAGE_TAG_RESOLUTION_CACHE_TTL_MS
198745
+ });
198746
+ return resolved;
198747
+ };
198748
+ decodeJwtExpMs = (token) => {
198749
+ const segments = token.split(".");
198750
+ if (segments.length < 2) return null;
198751
+ const payload = segments[1];
198752
+ if (!payload) return null;
198753
+ const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
198754
+ const padLength = (4 - normalized.length % 4) % 4;
198755
+ const padded = `${normalized}${"=".repeat(padLength)}`;
198756
+ try {
198757
+ const parsed = JSON.parse(
198758
+ Buffer.from(padded, "base64").toString("utf8")
198759
+ );
198760
+ const exp = parsed.exp;
198761
+ if (typeof exp !== "number" || !Number.isFinite(exp) || exp <= 0) {
198762
+ return null;
198763
+ }
198764
+ return Math.floor(exp * 1e3);
198765
+ } catch {
198766
+ return null;
198767
+ }
198768
+ };
198769
+ createSafeModalAuthTokenManager = (modal) => {
198770
+ let token = "";
198771
+ let tokenExpMs = 0;
198772
+ let inFlight = null;
198773
+ const TOKEN_REFRESH_SKEW_MS = 3e4;
198774
+ const FALLBACK_TOKEN_TTL_MS = 15 * 60 * 1e3;
198775
+ const hasFreshToken = () => token.length > 0 && Date.now() + TOKEN_REFRESH_SKEW_MS < tokenExpMs;
198776
+ const fetchToken = async () => {
198777
+ const authTokenGet = modal.cpClient.authTokenGet;
198778
+ if (typeof authTokenGet !== "function") {
198779
+ throw new Error("Modal auth token endpoint unavailable.");
198780
+ }
198781
+ const response = await authTokenGet({});
198782
+ const nextToken = typeof response?.token === "string" ? response.token.trim() : "";
198783
+ if (!nextToken) {
198784
+ throw new Error("Modal auth token unavailable.");
198785
+ }
198786
+ token = nextToken;
198787
+ tokenExpMs = decodeJwtExpMs(nextToken) ?? Date.now() + FALLBACK_TOKEN_TTL_MS;
198788
+ return nextToken;
198789
+ };
198790
+ return {
198791
+ start: () => {
198792
+ },
198793
+ stop: () => {
198794
+ token = "";
198795
+ tokenExpMs = 0;
198796
+ inFlight = null;
198797
+ },
198798
+ getToken: async () => {
198799
+ if (hasFreshToken()) return token;
198800
+ if (!inFlight) {
198801
+ inFlight = fetchToken().finally(() => {
198802
+ inFlight = null;
198803
+ });
198804
+ }
198805
+ return await inFlight;
198806
+ }
198807
+ };
198808
+ };
198809
+ installSafeModalAuthTokenManager = (modal) => {
198810
+ const candidate = modal;
198811
+ if (candidate.authTokenManager) return;
198812
+ candidate.authTokenManager = createSafeModalAuthTokenManager(candidate);
198813
+ };
198814
+ parsePositiveInt = (value, fallback2) => {
198815
+ const parsed = Number.parseInt(value, 10);
198816
+ if (!Number.isFinite(parsed) || parsed <= 0) return fallback2;
198817
+ return parsed;
198818
+ };
198819
+ resolveRegions = () => {
198820
+ const raw = trimEnv2(process.env.MODAL_SANDBOX_REGION);
198821
+ if (!raw) return [];
198822
+ return raw.split(",").map((value) => value.trim()).filter((value) => value.length > 0);
198823
+ };
198824
+ resolveAppName = () => trimEnv2(process.env.MODAL_SANDBOX_APP) || DEFAULT_APP_NAME;
198825
+ resolveModalSandboxTimeoutMs = () => parsePositiveInt(
198826
+ trimEnv2(process.env.MODAL_SANDBOX_TIMEOUT_MS),
198827
+ DEFAULT_TIMEOUT_MS
198828
+ );
198829
+ isNotFoundError = (error2) => error2 instanceof NotFoundError;
198830
+ isModalAlreadyExistsError = (error2) => {
198831
+ if (error2 instanceof AlreadyExistsError) {
198832
+ return true;
198833
+ }
198834
+ const message = error2 instanceof Error ? `${error2.name} ${error2.message}` : String(error2 ?? "");
198835
+ if (/\bALREADY_EXISTS\b/i.test(message)) {
198836
+ return true;
198837
+ }
198838
+ return /already exists/i.test(message);
198839
+ };
198840
+ trimToNull = (value) => {
198841
+ if (typeof value !== "string") return null;
198842
+ const trimmed = value.trim();
198843
+ return trimmed.length > 0 ? trimmed : null;
198844
+ };
198845
+ resolveControlPlaneToken = (options) => trimToNull(options?.credentials?.controlPlaneToken);
198846
+ hasContextModalCredentialPair = (options) => Boolean(
198847
+ trimToNull(options?.credentials?.modalTokenId) && trimToNull(options?.credentials?.modalTokenSecret)
198848
+ );
198849
+ shouldUseControlPlaneFallback = (options) => !options?.client && Boolean(resolveControlPlaneToken(options)) && !hasContextModalCredentialPair(options);
198850
+ withModalClient = async (options, fn) => {
198851
+ if (options?.client) {
198852
+ return await fn(options.client);
198853
+ }
198854
+ const modalCredentials = resolveModalClientCredentials({
198855
+ ...options?.credentialMode ? { credentialMode: options.credentialMode } : {},
198856
+ ...options?.credentials !== void 0 ? { credentials: options.credentials } : {},
198857
+ ...options?.cwd ? { cwd: options.cwd } : {}
198858
+ });
198859
+ const modal = new ModalClient2({
198860
+ tokenId: modalCredentials.tokenId,
198861
+ tokenSecret: modalCredentials.tokenSecret,
198862
+ environment: resolveModalEnvironmentName()
198863
+ });
198864
+ installSafeModalAuthTokenManager(modal);
198865
+ try {
198866
+ return await fn(modal);
198867
+ } finally {
198868
+ modal.close();
198869
+ }
198870
+ };
198871
+ resolveModalApp = async (modal, appName, createIfMissing) => {
198872
+ try {
198873
+ const app = await modal.apps.fromName(appName, { createIfMissing });
198874
+ return { appId: app.appId, appName };
198875
+ } catch (error2) {
198876
+ if (!createIfMissing && isNotFoundError(error2)) {
198877
+ return null;
198878
+ }
198879
+ throw error2;
198880
+ }
198881
+ };
198882
+ listSandboxesRaw = async (modal, appId, includeFinished) => {
198883
+ const sandboxes = [];
198884
+ let beforeTimestamp = 0;
198885
+ let guard = 0;
198886
+ while (true) {
198887
+ guard += 1;
198888
+ if (guard > SANDBOX_LIST_PAGE_LIMIT) {
198889
+ throw new Error("Modal sandbox list pagination exceeded safety limit.");
198890
+ }
198891
+ const response = await modal.cpClient.sandboxList({
198892
+ appId,
198893
+ beforeTimestamp,
198894
+ environmentName: modal.environmentName(),
198895
+ includeFinished,
198896
+ tags: []
198897
+ });
198898
+ if (!response.sandboxes.length) break;
198899
+ sandboxes.push(...response.sandboxes);
198900
+ const nextCursor = response.sandboxes[response.sandboxes.length - 1];
198901
+ if (!nextCursor || nextCursor.createdAt === beforeTimestamp) break;
198902
+ beforeTimestamp = nextCursor.createdAt;
198903
+ }
198904
+ return sandboxes;
198905
+ };
198906
+ formatSandboxStatus = (sandbox) => {
198907
+ const result = sandbox.taskInfo?.result;
198908
+ const status = result?.status ?? 0;
198909
+ if (status === 0) return "running";
198910
+ const label = FINISHED_STATUS_LABELS[status] ?? String(status);
198911
+ const exitCode = result?.exitcode ?? "unknown";
198912
+ return `finished:${label}:exit=${String(exitCode)}`;
198913
+ };
198914
+ isRunningSandbox = (sandbox) => (sandbox.taskInfo?.result?.status ?? 0) === 0;
198915
+ resolveImageFromTag = async (modal, imageTag) => {
198916
+ const secretName = trimEnv2(process.env.MODAL_SANDBOX_IMAGE_SECRET);
198917
+ if (!secretName) {
198918
+ return modal.images.fromRegistry(imageTag);
198919
+ }
198920
+ const secret = await modal.secrets.fromName(secretName);
198921
+ if (imageTag.includes(".dkr.ecr.")) {
198922
+ return modal.images.fromAwsEcr(imageTag, secret);
198923
+ }
198924
+ return modal.images.fromRegistry(imageTag, secret);
198925
+ };
198926
+ provisionModalSandbox = async (alias, options) => {
198927
+ if (shouldUseControlPlaneFallback(options)) {
198928
+ const controlPlaneToken = resolveControlPlaneToken(options);
198929
+ if (!controlPlaneToken) {
198930
+ throw new Error(
198931
+ "Control plane token is required for modal provisioning."
198932
+ );
198933
+ }
198934
+ return await provisionModalSandboxViaControlPlane(controlPlaneToken, alias);
198935
+ }
198936
+ const appName = resolveAppName();
198937
+ const envImageTag = trimEnv2(process.env.MODAL_SANDBOX_IMAGE);
198938
+ const imageTag = envImageTag || DEFAULT_MODAL_DEVBOX_IMAGE;
198939
+ const resolvedImageTag = await resolveImageTagForBuild(imageTag);
198940
+ const timeoutMs = resolveModalSandboxTimeoutMs();
198941
+ const timeoutSecs = Math.max(1, Math.floor(timeoutMs / 1e3));
198942
+ const regions = resolveRegions();
198943
+ return await withModalClient(options, async (modal) => {
198944
+ const sandboxName = resolveModalSandboxName(alias, modal.environmentName());
198945
+ const app = await resolveModalApp(modal, appName, true);
198946
+ if (!app) {
198947
+ throw new Error(`Could not resolve Modal app "${appName}".`);
198948
+ }
198949
+ const buildImage = async (tag) => {
198950
+ const image = await resolveImageFromTag(modal, tag);
198951
+ return await image.build({ appId: app.appId });
198952
+ };
198953
+ const builtImage = await buildImage(resolvedImageTag);
198954
+ const createResponse = await modal.cpClient.sandboxCreate({
198955
+ appId: app.appId,
198956
+ definition: {
198957
+ imageId: builtImage.imageId,
198958
+ timeoutSecs,
198959
+ name: sandboxName,
198960
+ ...regions.length > 0 ? { schedulerPlacement: { regions } } : {},
198961
+ entrypointArgs: MODAL_DAEMON_SUPERVISOR_ENTRYPOINT,
198962
+ enableSnapshot: true
198963
+ }
198964
+ });
198965
+ return {
198966
+ sandboxId: createResponse.sandboxId,
198967
+ appId: app.appId,
198968
+ appName,
198969
+ imageTag: resolvedImageTag,
198970
+ timeoutMs,
198971
+ memorySnapshotEnabled: false,
198972
+ regions
198973
+ };
198974
+ });
198975
+ };
198976
+ findModalSandbox = async (options, operationOptions) => {
198977
+ if (shouldUseControlPlaneFallback(operationOptions)) {
198978
+ const controlPlaneToken = resolveControlPlaneToken(operationOptions);
198979
+ if (!controlPlaneToken) {
198980
+ throw new Error(
198981
+ "Control plane token is required for modal sandbox lookup."
198982
+ );
198983
+ }
198984
+ return await findModalSandboxViaControlPlane(controlPlaneToken, options);
198985
+ }
198986
+ const appName = resolveAppName();
198987
+ const includeFinished = options.includeFinished ?? true;
198988
+ return await withModalClient(operationOptions, async (modal) => {
198989
+ const sandboxName = resolveModalSandboxName(
198990
+ options.alias,
198991
+ modal.environmentName()
198992
+ );
198993
+ const app = await resolveModalApp(modal, appName, false);
198994
+ if (!app) return null;
198995
+ const sandboxes = await listSandboxesRaw(modal, app.appId, includeFinished);
198996
+ const matching = sandboxes.filter((sandbox) => {
198997
+ if (options.sandboxId && sandbox.id === options.sandboxId) return true;
198998
+ return sandbox.name === sandboxName;
198999
+ });
199000
+ if (matching.length === 0) return null;
199001
+ matching.sort((left, right) => {
199002
+ const runningOrder = Number(isRunningSandbox(right)) - Number(isRunningSandbox(left));
199003
+ if (runningOrder !== 0) return runningOrder;
199004
+ return right.createdAt - left.createdAt;
199005
+ });
199006
+ const selected = matching[0];
199007
+ if (!selected) {
199008
+ throw new Error("Modal sandbox selection failed.");
199009
+ }
199010
+ return {
199011
+ sandboxId: selected.id,
199012
+ appId: app.appId,
199013
+ appName: app.appName,
199014
+ name: options.alias,
199015
+ createdAt: selected.createdAt,
199016
+ status: formatSandboxStatus(selected),
199017
+ regions: selected.regions
199018
+ };
199019
+ });
199020
+ };
199021
+ terminateModalSandboxesByAlias = async (alias, options) => {
199022
+ if (shouldUseControlPlaneFallback(options)) {
199023
+ const controlPlaneToken = resolveControlPlaneToken(options);
199024
+ if (!controlPlaneToken) {
199025
+ throw new Error(
199026
+ "Control plane token is required for modal sandbox termination."
199027
+ );
199028
+ }
199029
+ return await terminateModalSandboxesByAliasViaControlPlane(
199030
+ controlPlaneToken,
199031
+ {
199032
+ alias,
199033
+ ...typeof options?.includeFinished === "boolean" ? { includeFinished: options.includeFinished } : {}
199034
+ }
199035
+ );
199036
+ }
199037
+ const appName = resolveAppName();
199038
+ const includeFinished = options?.includeFinished ?? false;
199039
+ return await withModalClient(options, async (modal) => {
199040
+ const sandboxName = resolveModalSandboxName(alias, modal.environmentName());
199041
+ const app = await resolveModalApp(modal, appName, false);
199042
+ if (!app) {
199043
+ return {
199044
+ appName,
199045
+ appId: null,
199046
+ matchedSandboxIds: [],
199047
+ terminatedSandboxIds: []
199048
+ };
199049
+ }
199050
+ const sandboxes = await listSandboxesRaw(modal, app.appId, includeFinished);
199051
+ const matching = sandboxes.filter(
199052
+ (sandbox) => sandbox.name === sandboxName
199053
+ );
199054
+ const terminatedSandboxIds = [];
199055
+ for (const sandbox of matching) {
199056
+ await modal.cpClient.sandboxTerminate({ sandboxId: sandbox.id });
199057
+ terminatedSandboxIds.push(sandbox.id);
199058
+ }
199059
+ return {
199060
+ appName: app.appName,
199061
+ appId: app.appId,
199062
+ matchedSandboxIds: matching.map((sandbox) => sandbox.id),
199063
+ terminatedSandboxIds
199064
+ };
199065
+ });
199066
+ };
199067
+ }
199068
+ });
199069
+
198482
199070
  // src/devbox/commands/provider/modalRuntime.ts
198483
199071
  var import_node_path15, import_node_net3, import_ws4, SERVICE_NAME_PATTERN, CORE_SERVICE_NAMES2, MODAL_DAEMON_REQUEST_TIMEOUT_MS, MODAL_DAEMON_TTY_HANDSHAKE_TIMEOUT_MS, MODAL_SANDBOX_RESOLVE_TIMEOUT_MS, MODAL_DAEMON_CONTROL_HTTP_TIMEOUT_MS, MODAL_DAEMON_TTY_WS_PATH, validateServiceName, isSandboxNotFoundError, resolveReadPath, decodeBase642, parseJsonRecord2, withTimeout3, parseControlError, mapControlSessionRecord, normalizeServiceScope, normalizeServiceRestartPolicy, normalizeServiceStatus2, ModalDaemonExecSocket, createModalRuntimeClient;
198484
199072
  var init_modalRuntime = __esm({
@@ -198490,6 +199078,7 @@ var init_modalRuntime = __esm({
198490
199078
  import_ws4 = __toESM(require("ws"), 1);
198491
199079
  init_src();
198492
199080
  init_daemonClient();
199081
+ init_modalLifecycle();
198493
199082
  SERVICE_NAME_PATTERN = /^[a-zA-Z0-9._-]+$/;
198494
199083
  CORE_SERVICE_NAMES2 = /* @__PURE__ */ new Set(["devbox-sprite-daemon", "devbox-sshd"]);
198495
199084
  MODAL_DAEMON_REQUEST_TIMEOUT_MS = 15e3;
@@ -198927,15 +199516,19 @@ var init_modalRuntime = __esm({
198927
199516
  serviceRole: requestedServiceRole
198928
199517
  }) => {
198929
199518
  let modal = null;
199519
+ let modalSandboxName = alias;
198930
199520
  try {
198931
199521
  const modalCredentials = resolveModalClientCredentials({
198932
199522
  ...credentialMode ? { credentialMode } : {},
198933
199523
  ...credentials !== void 0 ? { credentials } : {},
198934
199524
  ...cwd ? { cwd } : {}
198935
199525
  });
199526
+ const modalEnvironmentName = resolveModalEnvironmentName();
199527
+ modalSandboxName = resolveModalSandboxName(alias, modalEnvironmentName);
198936
199528
  modal = new ModalClient2({
198937
199529
  tokenId: modalCredentials.tokenId,
198938
- tokenSecret: modalCredentials.tokenSecret
199530
+ tokenSecret: modalCredentials.tokenSecret,
199531
+ environment: modalEnvironmentName
198939
199532
  });
198940
199533
  } catch (error2) {
198941
199534
  if (!(error2 instanceof ProviderClientError && error2.code === "authentication_required")) {
@@ -198964,7 +199557,7 @@ var init_modalRuntime = __esm({
198964
199557
  sandboxPromise = (async () => {
198965
199558
  try {
198966
199559
  const runningSandbox = await withTimeout3(
198967
- directModal.sandboxes.fromName(appName, alias),
199560
+ directModal.sandboxes.fromName(appName, modalSandboxName),
198968
199561
  MODAL_SANDBOX_RESOLVE_TIMEOUT_MS,
198969
199562
  "Timed out resolving running modal sandbox by name."
198970
199563
  );
@@ -199483,530 +200076,6 @@ var init_modalRuntime = __esm({
199483
200076
  }
199484
200077
  });
199485
200078
 
199486
- // src/devbox/commands/provider/modalLifecycle.ts
199487
- var import_node_crypto9, DEFAULT_APP_NAME, DEFAULT_MODAL_DEVBOX_IMAGE, DEFAULT_TIMEOUT_MS, IMAGE_TAG_RESOLUTION_CACHE_TTL_MS, SANDBOX_LIST_PAGE_LIMIT, MODAL_DAEMON_WRAPPER_PATH, MODAL_DAEMON_SUPERVISOR_ENTRYPOINT, FINISHED_STATUS_LABELS, REGISTRY_MANIFEST_ACCEPT_HEADER, resolvedImageTagCache, trimEnv2, parseRegistryImageTag, parseWwwAuthenticateBearer, fetchRegistryToken, resolveLatestImageTagToDigest, resolveImageTagForBuild, decodeJwtExpMs, createSafeModalAuthTokenManager, installSafeModalAuthTokenManager, parsePositiveInt, resolveRegions, resolveAppName, resolveModalSandboxTimeoutMs, isNotFoundError, isModalAlreadyExistsError, trimToNull, resolveControlPlaneToken, hasContextModalCredentialPair, shouldUseControlPlaneFallback, withModalClient, resolveModalApp, listSandboxesRaw, formatSandboxStatus, isRunningSandbox, resolveImageFromTag, provisionModalSandbox, findModalSandbox, terminateModalSandboxesByAlias;
199488
- var init_modalLifecycle = __esm({
199489
- "src/devbox/commands/provider/modalLifecycle.ts"() {
199490
- "use strict";
199491
- init_src();
199492
- import_node_crypto9 = require("node:crypto");
199493
- init_dist5();
199494
- init_controlPlane();
199495
- DEFAULT_APP_NAME = "sandbox-modal-smoke";
199496
- DEFAULT_MODAL_DEVBOX_IMAGE = "public.ecr.aws/d8m4p4w9/modal-devbox:latest";
199497
- DEFAULT_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
199498
- IMAGE_TAG_RESOLUTION_CACHE_TTL_MS = 5 * 60 * 1e3;
199499
- SANDBOX_LIST_PAGE_LIMIT = 100;
199500
- MODAL_DAEMON_WRAPPER_PATH = "/root/.devbox/daemon/run-daemon.sh";
199501
- MODAL_DAEMON_SUPERVISOR_ENTRYPOINT = [
199502
- "/bin/sh",
199503
- "-lc",
199504
- [
199505
- "set -u",
199506
- `wrapper=${JSON.stringify(MODAL_DAEMON_WRAPPER_PATH)}`,
199507
- 'until [ -x "$wrapper" ]; do sleep 0.25; done',
199508
- "while true; do",
199509
- ' "$wrapper"',
199510
- " status=$?",
199511
- ' echo "sprite-daemon exited with status $status; restarting" >&2',
199512
- " sleep 1",
199513
- "done"
199514
- ].join("\n")
199515
- ];
199516
- FINISHED_STATUS_LABELS = {
199517
- 1: "success",
199518
- 2: "failure",
199519
- 3: "terminated",
199520
- 4: "timeout",
199521
- 5: "init_failure",
199522
- 6: "internal_failure",
199523
- 7: "idle_timeout"
199524
- };
199525
- REGISTRY_MANIFEST_ACCEPT_HEADER = [
199526
- "application/vnd.oci.image.index.v1+json",
199527
- "application/vnd.oci.image.manifest.v1+json",
199528
- "application/vnd.docker.distribution.manifest.list.v2+json",
199529
- "application/vnd.docker.distribution.manifest.v2+json"
199530
- ].join(", ");
199531
- resolvedImageTagCache = /* @__PURE__ */ new Map();
199532
- trimEnv2 = (value) => value?.trim() ?? "";
199533
- parseRegistryImageTag = (imageTag) => {
199534
- const trimmed = imageTag.trim();
199535
- if (!trimmed || trimmed.includes("@")) {
199536
- return null;
199537
- }
199538
- const lastSlashIndex = trimmed.lastIndexOf("/");
199539
- const lastColonIndex = trimmed.lastIndexOf(":");
199540
- if (lastColonIndex <= lastSlashIndex) {
199541
- return null;
199542
- }
199543
- const repositoryWithHost = trimmed.slice(0, lastColonIndex);
199544
- const tag = trimmed.slice(lastColonIndex + 1).trim();
199545
- if (!repositoryWithHost || !tag) {
199546
- return null;
199547
- }
199548
- const firstSlashIndex = repositoryWithHost.indexOf("/");
199549
- if (firstSlashIndex <= 0) {
199550
- return null;
199551
- }
199552
- const registryHost = repositoryWithHost.slice(0, firstSlashIndex);
199553
- const repository = repositoryWithHost.slice(firstSlashIndex + 1);
199554
- if (!repository) {
199555
- return null;
199556
- }
199557
- const hasExplicitRegistryHost = registryHost.includes(".") || registryHost.includes(":") || registryHost === "localhost";
199558
- if (!hasExplicitRegistryHost) {
199559
- return null;
199560
- }
199561
- return {
199562
- registryHost,
199563
- repository,
199564
- tag,
199565
- repositoryWithHost
199566
- };
199567
- };
199568
- parseWwwAuthenticateBearer = (headerValue) => {
199569
- const trimmed = headerValue.trim();
199570
- if (!trimmed.toLowerCase().startsWith("bearer ")) {
199571
- return null;
199572
- }
199573
- const attributes = /* @__PURE__ */ new Map();
199574
- for (const match2 of trimmed.slice("bearer ".length).matchAll(/([A-Za-z0-9_-]+)="([^"]*)"/g)) {
199575
- const [, key, value] = match2;
199576
- if (!key) {
199577
- continue;
199578
- }
199579
- attributes.set(key.toLowerCase(), value ?? "");
199580
- }
199581
- const realm = attributes.get("realm");
199582
- const service = attributes.get("service");
199583
- const scope = attributes.get("scope");
199584
- if (!realm || !service) {
199585
- return null;
199586
- }
199587
- return {
199588
- realm,
199589
- service,
199590
- scope: scope || null
199591
- };
199592
- };
199593
- fetchRegistryToken = async ({
199594
- realm,
199595
- service,
199596
- scope
199597
- }) => {
199598
- const tokenUrl = new URL(realm);
199599
- tokenUrl.searchParams.set("service", service);
199600
- if (scope) {
199601
- tokenUrl.searchParams.set("scope", scope);
199602
- }
199603
- const response = await fetch(tokenUrl.toString());
199604
- if (!response.ok) {
199605
- throw new Error(
199606
- `Container registry auth token request failed (${response.status}).`
199607
- );
199608
- }
199609
- const payload = await response.json();
199610
- const token = typeof payload.token === "string" ? payload.token.trim() : typeof payload.access_token === "string" ? payload.access_token.trim() : "";
199611
- if (!token) {
199612
- throw new Error("Container registry auth token response was empty.");
199613
- }
199614
- return token;
199615
- };
199616
- resolveLatestImageTagToDigest = async (parsed) => {
199617
- const manifestUrl = `https://${parsed.registryHost}/v2/${parsed.repository}/manifests/${encodeURIComponent(parsed.tag)}`;
199618
- const fetchManifest = async ({
199619
- method,
199620
- token: token2
199621
- }) => {
199622
- const headers = {
199623
- Accept: REGISTRY_MANIFEST_ACCEPT_HEADER
199624
- };
199625
- if (token2) {
199626
- headers.Authorization = `Bearer ${token2}`;
199627
- }
199628
- return await fetch(manifestUrl, {
199629
- headers,
199630
- method
199631
- });
199632
- };
199633
- let token = null;
199634
- let headResponse = await fetchManifest({ method: "HEAD" });
199635
- if (headResponse.status === 401) {
199636
- const authHeader = headResponse.headers.get("www-authenticate") ?? "";
199637
- const challenge = parseWwwAuthenticateBearer(authHeader);
199638
- if (!challenge) {
199639
- throw new Error(
199640
- `Container registry auth challenge missing or invalid for ${parsed.repositoryWithHost}:${parsed.tag}.`
199641
- );
199642
- }
199643
- token = await fetchRegistryToken(challenge);
199644
- headResponse = await fetchManifest({
199645
- method: "HEAD",
199646
- token
199647
- });
199648
- }
199649
- if (!headResponse.ok) {
199650
- throw new Error(
199651
- `Container registry manifest lookup failed for ${parsed.repositoryWithHost}:${parsed.tag} (${headResponse.status}).`
199652
- );
199653
- }
199654
- const headDigest = headResponse.headers.get("docker-content-digest")?.trim();
199655
- if (headDigest) {
199656
- return `${parsed.repositoryWithHost}@${headDigest}`;
199657
- }
199658
- const getResponse = await fetchManifest(
199659
- token ? {
199660
- method: "GET",
199661
- token
199662
- } : {
199663
- method: "GET"
199664
- }
199665
- );
199666
- if (!getResponse.ok) {
199667
- throw new Error(
199668
- `Container registry manifest body lookup failed for ${parsed.repositoryWithHost}:${parsed.tag} (${getResponse.status}).`
199669
- );
199670
- }
199671
- const headerDigest = getResponse.headers.get("docker-content-digest")?.trim();
199672
- if (headerDigest) {
199673
- return `${parsed.repositoryWithHost}@${headerDigest}`;
199674
- }
199675
- const manifestBytes = Buffer.from(await getResponse.arrayBuffer());
199676
- const bodyDigest = `sha256:${(0, import_node_crypto9.createHash)("sha256").update(manifestBytes).digest("hex")}`;
199677
- return `${parsed.repositoryWithHost}@${bodyDigest}`;
199678
- };
199679
- resolveImageTagForBuild = async (imageTag) => {
199680
- const parsed = parseRegistryImageTag(imageTag);
199681
- if (!parsed || parsed.tag !== "latest") {
199682
- return imageTag;
199683
- }
199684
- const cacheKey = `${parsed.repositoryWithHost}:${parsed.tag}`;
199685
- const now = Date.now();
199686
- const cached = resolvedImageTagCache.get(cacheKey);
199687
- if (cached && cached.expiresAt > now) {
199688
- return cached.value;
199689
- }
199690
- const resolved = await resolveLatestImageTagToDigest(parsed);
199691
- resolvedImageTagCache.set(cacheKey, {
199692
- value: resolved,
199693
- expiresAt: now + IMAGE_TAG_RESOLUTION_CACHE_TTL_MS
199694
- });
199695
- return resolved;
199696
- };
199697
- decodeJwtExpMs = (token) => {
199698
- const segments = token.split(".");
199699
- if (segments.length < 2) return null;
199700
- const payload = segments[1];
199701
- if (!payload) return null;
199702
- const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
199703
- const padLength = (4 - normalized.length % 4) % 4;
199704
- const padded = `${normalized}${"=".repeat(padLength)}`;
199705
- try {
199706
- const parsed = JSON.parse(
199707
- Buffer.from(padded, "base64").toString("utf8")
199708
- );
199709
- const exp = parsed.exp;
199710
- if (typeof exp !== "number" || !Number.isFinite(exp) || exp <= 0) {
199711
- return null;
199712
- }
199713
- return Math.floor(exp * 1e3);
199714
- } catch {
199715
- return null;
199716
- }
199717
- };
199718
- createSafeModalAuthTokenManager = (modal) => {
199719
- let token = "";
199720
- let tokenExpMs = 0;
199721
- let inFlight = null;
199722
- const TOKEN_REFRESH_SKEW_MS = 3e4;
199723
- const FALLBACK_TOKEN_TTL_MS = 15 * 60 * 1e3;
199724
- const hasFreshToken = () => token.length > 0 && Date.now() + TOKEN_REFRESH_SKEW_MS < tokenExpMs;
199725
- const fetchToken = async () => {
199726
- const authTokenGet = modal.cpClient.authTokenGet;
199727
- if (typeof authTokenGet !== "function") {
199728
- throw new Error("Modal auth token endpoint unavailable.");
199729
- }
199730
- const response = await authTokenGet({});
199731
- const nextToken = typeof response?.token === "string" ? response.token.trim() : "";
199732
- if (!nextToken) {
199733
- throw new Error("Modal auth token unavailable.");
199734
- }
199735
- token = nextToken;
199736
- tokenExpMs = decodeJwtExpMs(nextToken) ?? Date.now() + FALLBACK_TOKEN_TTL_MS;
199737
- return nextToken;
199738
- };
199739
- return {
199740
- start: () => {
199741
- },
199742
- stop: () => {
199743
- token = "";
199744
- tokenExpMs = 0;
199745
- inFlight = null;
199746
- },
199747
- getToken: async () => {
199748
- if (hasFreshToken()) return token;
199749
- if (!inFlight) {
199750
- inFlight = fetchToken().finally(() => {
199751
- inFlight = null;
199752
- });
199753
- }
199754
- return await inFlight;
199755
- }
199756
- };
199757
- };
199758
- installSafeModalAuthTokenManager = (modal) => {
199759
- const candidate = modal;
199760
- if (candidate.authTokenManager) return;
199761
- candidate.authTokenManager = createSafeModalAuthTokenManager(candidate);
199762
- };
199763
- parsePositiveInt = (value, fallback2) => {
199764
- const parsed = Number.parseInt(value, 10);
199765
- if (!Number.isFinite(parsed) || parsed <= 0) return fallback2;
199766
- return parsed;
199767
- };
199768
- resolveRegions = () => {
199769
- const raw = trimEnv2(process.env.MODAL_SANDBOX_REGION);
199770
- if (!raw) return [];
199771
- return raw.split(",").map((value) => value.trim()).filter((value) => value.length > 0);
199772
- };
199773
- resolveAppName = () => trimEnv2(process.env.MODAL_SANDBOX_APP) || DEFAULT_APP_NAME;
199774
- resolveModalSandboxTimeoutMs = () => parsePositiveInt(
199775
- trimEnv2(process.env.MODAL_SANDBOX_TIMEOUT_MS),
199776
- DEFAULT_TIMEOUT_MS
199777
- );
199778
- isNotFoundError = (error2) => error2 instanceof NotFoundError;
199779
- isModalAlreadyExistsError = (error2) => {
199780
- if (error2 instanceof AlreadyExistsError) {
199781
- return true;
199782
- }
199783
- const message = error2 instanceof Error ? `${error2.name} ${error2.message}` : String(error2 ?? "");
199784
- if (/\bALREADY_EXISTS\b/i.test(message)) {
199785
- return true;
199786
- }
199787
- return /already exists/i.test(message);
199788
- };
199789
- trimToNull = (value) => {
199790
- if (typeof value !== "string") return null;
199791
- const trimmed = value.trim();
199792
- return trimmed.length > 0 ? trimmed : null;
199793
- };
199794
- resolveControlPlaneToken = (options) => trimToNull(options?.credentials?.controlPlaneToken);
199795
- hasContextModalCredentialPair = (options) => Boolean(
199796
- trimToNull(options?.credentials?.modalTokenId) && trimToNull(options?.credentials?.modalTokenSecret)
199797
- );
199798
- shouldUseControlPlaneFallback = (options) => !options?.client && Boolean(resolveControlPlaneToken(options)) && !hasContextModalCredentialPair(options);
199799
- withModalClient = async (options, fn) => {
199800
- if (options?.client) {
199801
- return await fn(options.client);
199802
- }
199803
- const modalCredentials = resolveModalClientCredentials({
199804
- ...options?.credentialMode ? { credentialMode: options.credentialMode } : {},
199805
- ...options?.credentials !== void 0 ? { credentials: options.credentials } : {},
199806
- ...options?.cwd ? { cwd: options.cwd } : {}
199807
- });
199808
- const modal = new ModalClient2({
199809
- tokenId: modalCredentials.tokenId,
199810
- tokenSecret: modalCredentials.tokenSecret
199811
- });
199812
- installSafeModalAuthTokenManager(modal);
199813
- try {
199814
- return await fn(modal);
199815
- } finally {
199816
- modal.close();
199817
- }
199818
- };
199819
- resolveModalApp = async (modal, appName, createIfMissing) => {
199820
- try {
199821
- const app = await modal.apps.fromName(appName, { createIfMissing });
199822
- return { appId: app.appId, appName };
199823
- } catch (error2) {
199824
- if (!createIfMissing && isNotFoundError(error2)) {
199825
- return null;
199826
- }
199827
- throw error2;
199828
- }
199829
- };
199830
- listSandboxesRaw = async (modal, appId, includeFinished) => {
199831
- const sandboxes = [];
199832
- let beforeTimestamp = 0;
199833
- let guard = 0;
199834
- while (true) {
199835
- guard += 1;
199836
- if (guard > SANDBOX_LIST_PAGE_LIMIT) {
199837
- throw new Error("Modal sandbox list pagination exceeded safety limit.");
199838
- }
199839
- const response = await modal.cpClient.sandboxList({
199840
- appId,
199841
- beforeTimestamp,
199842
- environmentName: modal.environmentName(),
199843
- includeFinished,
199844
- tags: []
199845
- });
199846
- if (!response.sandboxes.length) break;
199847
- sandboxes.push(...response.sandboxes);
199848
- const nextCursor = response.sandboxes[response.sandboxes.length - 1];
199849
- if (!nextCursor || nextCursor.createdAt === beforeTimestamp) break;
199850
- beforeTimestamp = nextCursor.createdAt;
199851
- }
199852
- return sandboxes;
199853
- };
199854
- formatSandboxStatus = (sandbox) => {
199855
- const result = sandbox.taskInfo?.result;
199856
- const status = result?.status ?? 0;
199857
- if (status === 0) return "running";
199858
- const label = FINISHED_STATUS_LABELS[status] ?? String(status);
199859
- const exitCode = result?.exitcode ?? "unknown";
199860
- return `finished:${label}:exit=${String(exitCode)}`;
199861
- };
199862
- isRunningSandbox = (sandbox) => (sandbox.taskInfo?.result?.status ?? 0) === 0;
199863
- resolveImageFromTag = async (modal, imageTag) => {
199864
- const secretName = trimEnv2(process.env.MODAL_SANDBOX_IMAGE_SECRET);
199865
- if (!secretName) {
199866
- return modal.images.fromRegistry(imageTag);
199867
- }
199868
- const secret = await modal.secrets.fromName(secretName);
199869
- if (imageTag.includes(".dkr.ecr.")) {
199870
- return modal.images.fromAwsEcr(imageTag, secret);
199871
- }
199872
- return modal.images.fromRegistry(imageTag, secret);
199873
- };
199874
- provisionModalSandbox = async (alias, options) => {
199875
- if (shouldUseControlPlaneFallback(options)) {
199876
- const controlPlaneToken = resolveControlPlaneToken(options);
199877
- if (!controlPlaneToken) {
199878
- throw new Error(
199879
- "Control plane token is required for modal provisioning."
199880
- );
199881
- }
199882
- return await provisionModalSandboxViaControlPlane(controlPlaneToken, alias);
199883
- }
199884
- const appName = resolveAppName();
199885
- const envImageTag = trimEnv2(process.env.MODAL_SANDBOX_IMAGE);
199886
- const imageTag = envImageTag || DEFAULT_MODAL_DEVBOX_IMAGE;
199887
- const resolvedImageTag = await resolveImageTagForBuild(imageTag);
199888
- const timeoutMs = resolveModalSandboxTimeoutMs();
199889
- const timeoutSecs = Math.max(1, Math.floor(timeoutMs / 1e3));
199890
- const regions = resolveRegions();
199891
- return await withModalClient(options, async (modal) => {
199892
- const app = await resolveModalApp(modal, appName, true);
199893
- if (!app) {
199894
- throw new Error(`Could not resolve Modal app "${appName}".`);
199895
- }
199896
- const buildImage = async (tag) => {
199897
- const image = await resolveImageFromTag(modal, tag);
199898
- return await image.build({ appId: app.appId });
199899
- };
199900
- const builtImage = await buildImage(resolvedImageTag);
199901
- const createResponse = await modal.cpClient.sandboxCreate({
199902
- appId: app.appId,
199903
- definition: {
199904
- imageId: builtImage.imageId,
199905
- timeoutSecs,
199906
- name: alias,
199907
- ...regions.length > 0 ? { schedulerPlacement: { regions } } : {},
199908
- entrypointArgs: MODAL_DAEMON_SUPERVISOR_ENTRYPOINT,
199909
- enableSnapshot: true
199910
- }
199911
- });
199912
- return {
199913
- sandboxId: createResponse.sandboxId,
199914
- appId: app.appId,
199915
- appName,
199916
- imageTag: resolvedImageTag,
199917
- timeoutMs,
199918
- memorySnapshotEnabled: false,
199919
- regions
199920
- };
199921
- });
199922
- };
199923
- findModalSandbox = async (options, operationOptions) => {
199924
- if (shouldUseControlPlaneFallback(operationOptions)) {
199925
- const controlPlaneToken = resolveControlPlaneToken(operationOptions);
199926
- if (!controlPlaneToken) {
199927
- throw new Error(
199928
- "Control plane token is required for modal sandbox lookup."
199929
- );
199930
- }
199931
- return await findModalSandboxViaControlPlane(controlPlaneToken, options);
199932
- }
199933
- const appName = resolveAppName();
199934
- const includeFinished = options.includeFinished ?? true;
199935
- return await withModalClient(operationOptions, async (modal) => {
199936
- const app = await resolveModalApp(modal, appName, false);
199937
- if (!app) return null;
199938
- const sandboxes = await listSandboxesRaw(modal, app.appId, includeFinished);
199939
- const matching = sandboxes.filter((sandbox) => {
199940
- if (options.sandboxId && sandbox.id === options.sandboxId) return true;
199941
- return sandbox.name === options.alias;
199942
- });
199943
- if (matching.length === 0) return null;
199944
- matching.sort((left, right) => {
199945
- const runningOrder = Number(isRunningSandbox(right)) - Number(isRunningSandbox(left));
199946
- if (runningOrder !== 0) return runningOrder;
199947
- return right.createdAt - left.createdAt;
199948
- });
199949
- const selected = matching[0];
199950
- if (!selected) {
199951
- throw new Error("Modal sandbox selection failed.");
199952
- }
199953
- return {
199954
- sandboxId: selected.id,
199955
- appId: app.appId,
199956
- appName: app.appName,
199957
- name: selected.name,
199958
- createdAt: selected.createdAt,
199959
- status: formatSandboxStatus(selected),
199960
- regions: selected.regions
199961
- };
199962
- });
199963
- };
199964
- terminateModalSandboxesByAlias = async (alias, options) => {
199965
- if (shouldUseControlPlaneFallback(options)) {
199966
- const controlPlaneToken = resolveControlPlaneToken(options);
199967
- if (!controlPlaneToken) {
199968
- throw new Error(
199969
- "Control plane token is required for modal sandbox termination."
199970
- );
199971
- }
199972
- return await terminateModalSandboxesByAliasViaControlPlane(
199973
- controlPlaneToken,
199974
- {
199975
- alias,
199976
- ...typeof options?.includeFinished === "boolean" ? { includeFinished: options.includeFinished } : {}
199977
- }
199978
- );
199979
- }
199980
- const appName = resolveAppName();
199981
- const includeFinished = options?.includeFinished ?? false;
199982
- return await withModalClient(options, async (modal) => {
199983
- const app = await resolveModalApp(modal, appName, false);
199984
- if (!app) {
199985
- return {
199986
- appName,
199987
- appId: null,
199988
- matchedSandboxIds: [],
199989
- terminatedSandboxIds: []
199990
- };
199991
- }
199992
- const sandboxes = await listSandboxesRaw(modal, app.appId, includeFinished);
199993
- const matching = sandboxes.filter((sandbox) => sandbox.name === alias);
199994
- const terminatedSandboxIds = [];
199995
- for (const sandbox of matching) {
199996
- await modal.cpClient.sandboxTerminate({ sandboxId: sandbox.id });
199997
- terminatedSandboxIds.push(sandbox.id);
199998
- }
199999
- return {
200000
- appName: app.appName,
200001
- appId: app.appId,
200002
- matchedSandboxIds: matching.map((sandbox) => sandbox.id),
200003
- terminatedSandboxIds
200004
- };
200005
- });
200006
- };
200007
- }
200008
- });
200009
-
200010
200079
  // src/devbox/commands/providerClient.ts
200011
200080
  var CORE_SERVICE_NAMES3, DEFAULT_MODAL_APP_NAME, normalizeServiceStatus3, mapSpriteServiceToProviderRecord2, mapProviderUpsertToSpriteInput2, trimToNull2, normalizeEpochToIso, resolveModalRuntimeSeedAppName, createProviderCredentialContext, resolveModalCommandOperationOptions, throwModalNotImplemented2, MODAL_AUTH_ERROR_CODES, normalizeModalErrorCode, extractModalErrorCode, isModalAuthError, rethrowModalOperationError, mapModalRecordToProviderInstance, createModalCommandProviderClient, createCommandProviderClient;
200012
200081
  var init_providerClient = __esm({
@@ -205365,7 +205434,7 @@ var init_session3 = __esm({
205365
205434
  nonInteractive || shouldResume && initState?.steps.codexApplied
205366
205435
  );
205367
205436
  const skipCodexCliEnsure = Boolean(
205368
- skipCodexApply || shouldResume && initState?.steps.codexCliEnsured
205437
+ shouldResume && initState?.steps.codexCliEnsured
205369
205438
  );
205370
205439
  return {
205371
205440
  initState,
@@ -206416,7 +206485,16 @@ var init_remote2 = __esm({
206416
206485
  });
206417
206486
  };
206418
206487
  ensureRemoteCodexInstalled = async (client2, spriteAlias) => {
206419
- const pathSetup = 'export PATH="$(npm bin -g 2>/dev/null):$PATH"';
206488
+ const installScript = [
206489
+ "set -euo pipefail",
206490
+ 'prefix="${HOME}/.local"',
206491
+ 'npm install -g --prefix "$prefix" @openai/codex --loglevel=error',
206492
+ 'if [ ! -x "$prefix/bin/codex" ]; then',
206493
+ ' echo "codex binary missing at $prefix/bin/codex" >&2',
206494
+ " exit 1",
206495
+ "fi",
206496
+ '"$prefix/bin/codex" --version >/dev/null'
206497
+ ].join("\n");
206420
206498
  const install = await client2.exec(spriteAlias, [
206421
206499
  "/bin/bash",
206422
206500
  "--noprofile",
@@ -206426,8 +206504,7 @@ var init_remote2 = __esm({
206426
206504
  "-o",
206427
206505
  "pipefail",
206428
206506
  "-c",
206429
- `${pathSetup}
206430
- npm install -g @openai/codex`
206507
+ installScript
206431
206508
  ]);
206432
206509
  if (install.exitCode !== 0) {
206433
206510
  throw new Error(install.stderr || "Failed to install/upgrade Codex.");
@@ -211015,7 +211092,7 @@ ${sshResult.stderr}`.trim();
211015
211092
  });
211016
211093
 
211017
211094
  // src/devbox/commands/init/claudeBootstrap.ts
211018
- var import_promises29, import_node_path32, import_node_crypto16, import_node_child_process11, import_node_os17, import_node_util5, REMOTE_CLAUDE_DIR, REMOTE_CLAUDE_JSON_PATH, REMOTE_CLAUDE_CONFIG_OVERRIDE_PATH, REMOTE_CLAUDE_SETTINGS_PATH, REMOTE_CLAUDE_CREDENTIALS_PATH, REMOTE_CLAUDE_MD_PATH, REMOTE_CLAUDE_PLUGINS_DIR, REMOTE_CLAUDE_PLUGINS_CONFIG_PATH, CLAUDE_STATE_VARIANT_PATTERN, SECURITY_TIMEOUT_MS, OAUTH_SERVICE_SUFFIX_CANDIDATES, CLAUDE_ROOT_ALLOWLIST, CLAUDE_PROJECT_ALLOWLIST, isRecord2, hasOwn, execFileAsync, stripLeadingBom, getExecErrorStatus, getExecErrorCode, parseJsonRecord3, uniquePaths, resolveLocalClaudeDirCandidates, resolveLocalClaudeStateBaseDir, resolveLocalClaudeStorageDir, getCredentialStorageHashSuffix, getOauthServiceSuffixCandidates, resolveClaudeCredentialKeychainServices, resolveClaudeCredentialKeychainAccounts, listClaudeStateVariantPaths, readFileIfExists, findFirstExistingFile, readLocalClaudeStateSource, resolveLocalClaudeFilePath, readLocalClaudeFile, readLocalClaudeSettings, extractClaudeOauthRecord, readClaudeOauthFromKeychain, readLocalClaudeOauthCredentials, normalizeLocalRepoRootCandidates, copyAllowlistedKeys, buildBootstrapClaudeState, mergeClaudeSettingsForDevbox, isNotFoundError2, readRemoteFileIfExists, ensureRemoteClaudeDirectories, applyRemoteClaudePermissions, bootstrapRemoteClaudeConfig;
211095
+ var import_promises29, import_node_path32, import_node_crypto16, import_node_child_process11, import_node_os17, import_node_util5, REMOTE_CLAUDE_DIR, REMOTE_CLAUDE_JSON_PATH, REMOTE_CLAUDE_CONFIG_OVERRIDE_PATH, REMOTE_CLAUDE_SETTINGS_PATH, REMOTE_CLAUDE_CREDENTIALS_PATH, REMOTE_CLAUDE_MD_PATH, REMOTE_CLAUDE_PLUGINS_DIR, REMOTE_CLAUDE_PLUGINS_CONFIG_PATH, CLAUDE_STATE_VARIANT_PATTERN, SECURITY_TIMEOUT_MS, OAUTH_SERVICE_SUFFIX_CANDIDATES, CLAUDE_ROOT_ALLOWLIST, CLAUDE_PROJECT_ALLOWLIST, isRecord2, hasOwn, execFileAsync, stripLeadingBom, getExecErrorStatus, getExecErrorExitCode, parseJsonRecord3, uniquePaths, resolveLocalClaudeDirCandidates, resolveLocalClaudeStateBaseDir, resolveLocalClaudeStorageDir, getCredentialStorageHashSuffix, getOauthServiceSuffixCandidates, resolveClaudeCredentialKeychainServices, resolveClaudeCredentialKeychainAccounts, listClaudeStateVariantPaths, readFileIfExists, findFirstExistingFile, readLocalClaudeStateSource, resolveLocalClaudeFilePath, readLocalClaudeFile, readLocalClaudeSettings, extractClaudeOauthRecord, readClaudeOauthFromKeychain, readLocalClaudeOauthCredentials, normalizeLocalRepoRootCandidates, copyAllowlistedKeys, buildBootstrapClaudeState, mergeClaudeSettingsForDevbox, isNotFoundError2, readRemoteFileIfExists, ensureRemoteClaudeDirectories, applyRemoteClaudePermissions, bootstrapRemoteClaudeConfig;
211019
211096
  var init_claudeBootstrap = __esm({
211020
211097
  "src/devbox/commands/init/claudeBootstrap.ts"() {
211021
211098
  "use strict";
@@ -211094,10 +211171,15 @@ var init_claudeBootstrap = __esm({
211094
211171
  const status = error2.status;
211095
211172
  return typeof status === "number" ? status : null;
211096
211173
  };
211097
- getExecErrorCode = (error2) => {
211174
+ getExecErrorExitCode = (error2) => {
211098
211175
  if (!error2 || typeof error2 !== "object") return null;
211099
211176
  const code2 = error2.code;
211100
- return typeof code2 === "string" ? code2 : null;
211177
+ if (typeof code2 === "number") return code2;
211178
+ if (typeof code2 === "string") {
211179
+ const parsed = Number.parseInt(code2, 10);
211180
+ return Number.isNaN(parsed) ? null : parsed;
211181
+ }
211182
+ return null;
211101
211183
  };
211102
211184
  parseJsonRecord3 = (value, sourcePath) => {
211103
211185
  const parsed = JSON.parse(stripLeadingBom(value.toString("utf8")));
@@ -211141,7 +211223,15 @@ var init_claudeBootstrap = __esm({
211141
211223
  };
211142
211224
  getOauthServiceSuffixCandidates = () => {
211143
211225
  const preferred = process.env.CLAUDE_CODE_CUSTOM_OAUTH_URL ? "-custom-oauth" : "";
211144
- return uniquePaths([preferred, ...OAUTH_SERVICE_SUFFIX_CANDIDATES]);
211226
+ const ordered = [preferred, ...OAUTH_SERVICE_SUFFIX_CANDIDATES];
211227
+ const seen = /* @__PURE__ */ new Set();
211228
+ const candidates = [];
211229
+ for (const suffix of ordered) {
211230
+ if (seen.has(suffix)) continue;
211231
+ seen.add(suffix);
211232
+ candidates.push(suffix);
211233
+ }
211234
+ return candidates;
211145
211235
  };
211146
211236
  resolveClaudeCredentialKeychainServices = () => {
211147
211237
  const storageHashSuffix = getCredentialStorageHashSuffix();
@@ -211323,13 +211413,13 @@ var init_claudeBootstrap = __esm({
211323
211413
  };
211324
211414
  } catch (error2) {
211325
211415
  const status = getExecErrorStatus(error2);
211326
- if (status === 44) {
211416
+ const exitCode = getExecErrorExitCode(error2);
211417
+ if (status === 44 || exitCode === 44) {
211327
211418
  continue;
211328
211419
  }
211329
211420
  if (!warning) {
211330
- const code2 = getExecErrorCode(error2);
211331
211421
  const rawMessage = error2 instanceof Error ? error2.message : String(error2);
211332
- const detail = status ? `status ${status}` : code2 ? `code ${code2}` : rawMessage;
211422
+ const detail = status ? `status ${status}` : exitCode !== null ? `code ${exitCode}` : rawMessage;
211333
211423
  warning = `Failed to copy Claude OAuth credentials from macOS Keychain (${detail}).`;
211334
211424
  }
211335
211425
  continue;
@@ -213663,7 +213753,7 @@ var init_init = __esm({
213663
213753
  ".devbox",
213664
213754
  "setup-artifacts.parts.json"
213665
213755
  );
213666
- const pathSetup = 'export PATH="$(npm bin -g 2>/dev/null):$PATH"';
213756
+ const pathSetup = 'export PATH="$HOME/.local/bin:$(npm bin -g 2>/dev/null || true):$PATH"';
213667
213757
  let canonical = alias;
213668
213758
  let projectCreatedAt = existingEntry?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
213669
213759
  let projectLocalPaths = mergeLocalPaths(
@@ -220157,4 +220247,4 @@ smol-toml/dist/index.js:
220157
220247
  */
220158
220248
  //# sourceMappingURL=dvb.cjs.map
220159
220249
 
220160
- //# debugId=080b5259-7ff1-5cae-8b1d-315abb34a68e
220250
+ //# debugId=b785e941-0159-5a32-9ac9-c3686e30d3af