deepspace 0.23.1 → 0.23.2

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/cli.js CHANGED
@@ -3322,7 +3322,7 @@ var test_default = defineDeepspaceCommand({
3322
3322
  name: "test",
3323
3323
  description: "Run tests for your DeepSpace app"
3324
3324
  },
3325
- jsonDescription: "Stream test output; emit the final JSON result on the last line",
3325
+ jsonDescription: "Stream test output on stderr; stdout is the single-line JSON result",
3326
3326
  args: {
3327
3327
  suite: {
3328
3328
  type: "positional",
@@ -3357,6 +3357,7 @@ var test_default = defineDeepspaceCommand({
3357
3357
  }
3358
3358
  },
3359
3359
  async run({ args }) {
3360
+ suiteOutputToStderr = args.json === true;
3360
3361
  const say = (line) => {
3361
3362
  if (!args.json) console.log(line);
3362
3363
  };
@@ -3471,6 +3472,7 @@ Available: smoke, api, e2e, unit, all`,
3471
3472
  return { data: { suite, port, appDir, wranglerEnv: wranglerEnv ?? null, skippedSpecs } };
3472
3473
  }
3473
3474
  });
3475
+ var suiteOutputToStderr = false;
3474
3476
  function runSuite(appDir, argv, wranglerEnv, extraEnv = {}) {
3475
3477
  let wranglerConfig;
3476
3478
  try {
@@ -3482,7 +3484,9 @@ function runSuite(appDir, argv, wranglerEnv, extraEnv = {}) {
3482
3484
  try {
3483
3485
  const result = spawnSync4("npx", argv, {
3484
3486
  cwd: appDir,
3485
- stdio: "inherit",
3487
+ // Under --json the child's stdout is routed to our stderr: the live
3488
+ // suite output stays visible and stdout stays a single JSON line.
3489
+ stdio: suiteOutputToStderr ? ["inherit", 2, 2] : "inherit",
3486
3490
  env: wranglerViteEnv(process.env, wranglerConfig, extraEnv)
3487
3491
  });
3488
3492
  return result.status ?? 1;
@@ -6000,6 +6004,12 @@ function detachedHeadRefusal() {
6000
6004
  }
6001
6005
 
6002
6006
  // src/cli/commands/deploy/request.ts
6007
+ function renameRefusalMessage(rename2) {
6008
+ return `This deploy renames the app: ${rename2.fromHost} \u2192 ${rename2.toHost}. Confirmation needs an interactive terminal \u2014 re-run with --rename to approve the rename, or \`deepspace app init --new-id\` if you meant a separate app.`;
6009
+ }
6010
+ function renamePromptMessage(rename2) {
6011
+ return `This deploy renames the app: ${rename2.fromHost} \u2192 ${rename2.toHost}. The URL changes and the old one stops serving right away; data, secrets, and collaborators travel with it \u2014 the display name in \`src/constants.ts\` (\`APP_NAME\`) does not, update it yourself. (Meant a separate app? Run \`deepspace app init --new-id\` instead.) Rename?`;
6012
+ }
6003
6013
  var CLOUDFLARE_DEPLOY_ERROR_HINT = "Deployment reached the DeepSpace deploy worker, but Cloudflare's deployment control-plane API failed. This is often caused by a Cloudflare Dashboard/API incident or Workers for Platforms entitlement outage. Already deployed apps should keep serving; wait for Cloudflare to recover and retry.";
6004
6014
  var DEPLOY_SERVICE_LIMIT_HINT = "The DeepSpace deploy service hit a resource limit processing this deploy (the deploy worker was terminated before it could answer). This is a DeepSpace-side failure, not a Cloudflare incident \u2014 your app was not changed. Retry; if it keeps happening, report the app id and asset count.";
6005
6015
  var REQUIRED_ASSET_TRANSPORT = "content-addressed-v1";
@@ -6119,16 +6129,11 @@ async function deployBuiltBundle(options) {
6119
6129
  let body = await response.json().catch(() => ({}));
6120
6130
  if (response.status === 409 && body.code === "rename_required" && !confirmRename) {
6121
6131
  spinner2.stop("Rename confirmation needed");
6132
+ const rename2 = { fromHost: body.fromHost ?? "", toHost: body.toHost ?? "" };
6122
6133
  if (output.nonInteractive) {
6123
- await bail(
6124
- `This deploy renames the app: ${body.fromHost} \u2192 ${body.toHost}. Confirmation needs an interactive terminal \u2014 re-run with --rename to approve the rename, or \`deepspace app init --new-id\` if you meant a separate app.`,
6125
- null,
6126
- "rename_required"
6127
- );
6134
+ await bail(renameRefusalMessage(rename2), null, "rename_required");
6128
6135
  }
6129
- const confirmed = await p10.confirm({
6130
- message: `This deploy renames the app: ${body.fromHost} \u2192 ${body.toHost}. The URL changes and the old one stops serving right away; data, secrets, and collaborators travel with it. (Meant a separate app? Run \`deepspace app init --new-id\` instead.) Rename?`
6131
- });
6136
+ const confirmed = await p10.confirm({ message: renamePromptMessage(rename2) });
6132
6137
  if (p10.isCancel(confirmed) || !confirmed) await bail("Deploy cancelled.", null);
6133
6138
  confirmRename = true;
6134
6139
  spinner2.start(`Deploying ${appName}...`);
@@ -6471,188 +6476,196 @@ var deploy_default = defineCommand3({
6471
6476
  },
6472
6477
  async run({ args }) {
6473
6478
  const output = createDeployOutput(args.json === true);
6474
- preflightNodeVersion("deploy");
6475
- const appDir = resolve14(args.dir ?? ".");
6476
- const selectorRefusal = blankSelectorRefusal(args);
6477
- if (selectorRefusal) output.die(selectorRefusal.error, selectorRefusal.code);
6478
- const envName = typeof args.env === "string" && args.env.trim() ? args.env.trim() : void 0;
6479
- if (!hasWranglerConfig(appDir)) {
6480
- output.die(noWranglerConfigMessage(join19(appDir, "wrangler.toml")), "not_in_app_repo");
6481
- }
6482
6479
  try {
6483
- ensureInstallReady(appDir);
6480
+ await runDeploy(args, output);
6484
6481
  } catch (error) {
6485
- const refusal = error;
6486
- output.die(refusal.message ?? String(error), refusal.code ?? "deps_missing", {
6487
- action: refusal.action
6488
- });
6482
+ if (error instanceof CliExit) throw error;
6483
+ output.die(formatCliError(error), errorCode(error) ?? "deploy_failed");
6489
6484
  }
6490
- p12.intro("Deploying DeepSpace app");
6491
- output.showIntro();
6492
- const wranglerConfig = readWranglerConfig(appDir);
6493
- const nameResult = resolveAppNameForEnv(wranglerConfig, envName);
6494
- if (!nameResult.ok) return output.die(nameResult.reason, nameResult.code ?? "invalid_app_name");
6495
- const declaredName = envName ? wranglerConfig.env?.[envName]?.name : wranglerConfig.name;
6496
- if (declaredName !== nameResult.name) {
6497
- const location = envName ? `[env.${envName}].name` : "`name`";
6498
- output.die(
6499
- `wrangler.toml: ${location} "${declaredName}" is not in canonical form. Update it to "${nameResult.name}" and re-run.`,
6500
- "invalid_app_name"
6501
- );
6485
+ }
6486
+ });
6487
+ async function runDeploy(args, output) {
6488
+ preflightNodeVersion("deploy");
6489
+ const appDir = resolve14(args.dir ?? ".");
6490
+ const selectorRefusal = blankSelectorRefusal(args);
6491
+ if (selectorRefusal) output.die(selectorRefusal.error, selectorRefusal.code);
6492
+ const envName = typeof args.env === "string" && args.env.trim() ? args.env.trim() : void 0;
6493
+ if (!hasWranglerConfig(appDir)) {
6494
+ output.die(noWranglerConfigMessage(join19(appDir, "wrangler.toml")), "not_in_app_repo");
6495
+ }
6496
+ try {
6497
+ ensureInstallReady(appDir);
6498
+ } catch (error) {
6499
+ const refusal = error;
6500
+ output.die(refusal.message ?? String(error), refusal.code ?? "deps_missing", {
6501
+ action: refusal.action
6502
+ });
6503
+ }
6504
+ p12.intro("Deploying DeepSpace app");
6505
+ output.showIntro();
6506
+ const wranglerConfig = readWranglerConfig(appDir);
6507
+ const nameResult = resolveAppNameForEnv(wranglerConfig, envName);
6508
+ if (!nameResult.ok) return output.die(nameResult.reason, nameResult.code ?? "invalid_app_name");
6509
+ const declaredName = envName ? wranglerConfig.env?.[envName]?.name : wranglerConfig.name;
6510
+ if (declaredName !== nameResult.name) {
6511
+ const location = envName ? `[env.${envName}].name` : "`name`";
6512
+ output.die(
6513
+ `wrangler.toml: ${location} "${declaredName}" is not in canonical form. Update it to "${nameResult.name}" and re-run.`,
6514
+ "invalid_app_name"
6515
+ );
6516
+ }
6517
+ const appName = nameResult.name;
6518
+ const appId = readAppId(appDir, envName);
6519
+ p12.log.info(envName ? `App: ${appName} (env: ${envName})` : `App: ${appName}`);
6520
+ const { token, ownerId } = await authenticate(appDir, output);
6521
+ if (!appId) {
6522
+ return output.die(
6523
+ `No app id in wrangler.toml${envName ? ` for [env.${envName}]` : ""}. Run \`deepspace app init${envName ? ` --env ${envName}` : ""}\` to register this app, then re-deploy.`,
6524
+ "app_not_initialized",
6525
+ {
6526
+ action: {
6527
+ cwd: appDir,
6528
+ argv: ["deepspace", "app", "init", ...envName ? ["--env", envName] : []]
6529
+ },
6530
+ actionRequired: true
6531
+ }
6532
+ );
6533
+ }
6534
+ p12.log.info(`Id: ${appId}`);
6535
+ const sourceState = await getAppSource(DEPLOY_URL3, token, appId);
6536
+ if (!sourceState.registered) {
6537
+ output.die(
6538
+ `${appId} is not registered. If this repo's id came from an older SDK's scaffold, run \`deepspace app init --new-id\` to register it as a fresh app; a brand-new app dir registers with \`deepspace app init\`.`,
6539
+ "app_not_registered"
6540
+ );
6541
+ }
6542
+ const secretsCache = await loadDeploySecrets({
6543
+ deployUrl: DEPLOY_URL3,
6544
+ appDir,
6545
+ appId,
6546
+ envName,
6547
+ ownerId,
6548
+ token,
6549
+ output
6550
+ });
6551
+ const ownerJwtRefusal = ownerJwtMissingRefusal(sourceState);
6552
+ if (ownerJwtRefusal) output.die(ownerJwtRefusal.error, ownerJwtRefusal.code);
6553
+ let confirmRename = args.rename === true;
6554
+ const rename2 = pendingRename(sourceState.registeredHost, appName);
6555
+ if (rename2 && !confirmRename) {
6556
+ if (output.nonInteractive) {
6557
+ output.die(renameRefusalMessage(rename2), "rename_required");
6502
6558
  }
6503
- const appName = nameResult.name;
6504
- const appId = readAppId(appDir, envName);
6505
- p12.log.info(envName ? `App: ${appName} (env: ${envName})` : `App: ${appName}`);
6506
- const { token, ownerId } = await authenticate(appDir, output);
6507
- if (!appId) {
6508
- return output.die(
6509
- `No app id in wrangler.toml${envName ? ` for [env.${envName}]` : ""}. Run \`deepspace app init${envName ? ` --env ${envName}` : ""}\` to register this app, then re-deploy.`,
6510
- "app_not_initialized",
6511
- {
6512
- action: {
6513
- cwd: appDir,
6514
- argv: ["deepspace", "app", "init", ...envName ? ["--env", envName] : []]
6515
- },
6516
- actionRequired: true
6517
- }
6559
+ const confirmed = await p12.confirm({ message: renamePromptMessage(rename2) });
6560
+ if (p12.isCancel(confirmed) || !confirmed) output.die("Deploy cancelled.", "rename_declined");
6561
+ confirmRename = true;
6562
+ }
6563
+ const repositoryPreflight = preflightDeployRepository({
6564
+ appDir,
6565
+ push: args.push !== false,
6566
+ source: sourceState.source
6567
+ });
6568
+ if (repositoryPreflight) {
6569
+ output.die(repositoryPreflight.error, repositoryPreflight.code);
6570
+ }
6571
+ const spinner2 = createSpinner();
6572
+ const bundle = await buildDeployBundle({
6573
+ appDir,
6574
+ appName,
6575
+ appId,
6576
+ envName,
6577
+ output,
6578
+ spinner: spinner2
6579
+ });
6580
+ const oversized = oversizedAssetRefusal(bundle.assets);
6581
+ if (oversized) {
6582
+ spinner2.stop("Deploy failed");
6583
+ output.die(oversized, "assets_too_large");
6584
+ }
6585
+ const repository = await syncDeployRepository({
6586
+ deployUrl: DEPLOY_URL3,
6587
+ appDir,
6588
+ appId,
6589
+ token,
6590
+ push: args.push !== false,
6591
+ ignoreStale: Boolean(args["ignore-stale"]),
6592
+ output,
6593
+ sourceState
6594
+ });
6595
+ const secrets = prepareDeploySecrets({
6596
+ cache: secretsCache,
6597
+ customBindings: bundle.customBindings,
6598
+ doManifest: bundle.doManifest,
6599
+ output
6600
+ });
6601
+ const body = await deployBuiltBundle({
6602
+ deployUrl: DEPLOY_URL3,
6603
+ appDir,
6604
+ appId,
6605
+ appName,
6606
+ token,
6607
+ rename: confirmRename,
6608
+ claimReleased: args["claim-released"] === true,
6609
+ ignoreStale: Boolean(args["ignore-stale"]),
6610
+ bundle,
6611
+ secrets,
6612
+ repository,
6613
+ output,
6614
+ spinner: spinner2
6615
+ });
6616
+ let serving = "unverifiable";
6617
+ const edgeWaitStarted = Date.now();
6618
+ if (body.url) {
6619
+ spinner2.message("Waiting for the edge to serve this release...");
6620
+ serving = await waitForLiveRelease(body.url, body.releaseStamp, 9e4);
6621
+ if (serving !== "confirmed") {
6622
+ spinner2.stop(
6623
+ serving === "unconfirmed" ? "Deployed \u2014 the edge is still rolling this release out" : "Deployed \u2014 serving could not be verified from here"
6518
6624
  );
6519
- }
6520
- p12.log.info(`Id: ${appId}`);
6521
- const sourceState = await getAppSource(DEPLOY_URL3, token, appId);
6522
- if (!sourceState.registered) {
6523
- output.die(
6524
- `${appId} is not registered. If this repo's id came from an older SDK's scaffold, run \`deepspace app init --new-id\` to register it as a fresh app; a brand-new app dir registers with \`deepspace app init\`.`,
6525
- "app_not_registered"
6625
+ p12.log.warn(
6626
+ serving === "unconfirmed" ? "Some requests still get the previous release. Cloudflare rolls a version out per edge machine; it usually settles within a couple of minutes. Wait before asserting against it." : "This release carries no serving stamp (older platform, or a resumed deploy), so the CLI cannot tell which release the edge answers with."
6526
6627
  );
6628
+ p12.log.info(`URL: ${body.url}`);
6629
+ await syncCommerce(appDir, appId, token, output.nonInteractive);
6630
+ if (output.json) {
6631
+ return output.emitJson({
6632
+ ok: true,
6633
+ appId,
6634
+ appName,
6635
+ url: body.url,
6636
+ releaseId: body.releaseId ?? null,
6637
+ bundleRetained: body.bundleRetained ?? null,
6638
+ serving,
6639
+ recoverable: repository.recoverable,
6640
+ ...staleBaseGuardFields(body)
6641
+ });
6642
+ }
6643
+ p12.outro("Done");
6644
+ return;
6527
6645
  }
6528
- const secretsCache = await loadDeploySecrets({
6529
- deployUrl: DEPLOY_URL3,
6530
- appDir,
6531
- appId,
6532
- envName,
6533
- ownerId,
6534
- token,
6535
- output
6536
- });
6537
- const ownerJwtRefusal = ownerJwtMissingRefusal(sourceState);
6538
- if (ownerJwtRefusal) output.die(ownerJwtRefusal.error, ownerJwtRefusal.code);
6539
- let confirmRename = args.rename === true;
6540
- const rename2 = pendingRename(sourceState.registeredHost, appName);
6541
- if (rename2 && !confirmRename) {
6542
- if (output.nonInteractive) {
6543
- output.die(renameRefusalMessage(rename2), "rename_required");
6544
- }
6545
- const confirmed = await p12.confirm({ message: renamePromptMessage(rename2) });
6546
- if (p12.isCancel(confirmed) || !confirmed) output.die("Deploy cancelled.", "rename_declined");
6547
- confirmRename = true;
6548
- }
6549
- const repositoryPreflight = preflightDeployRepository({
6550
- appDir,
6551
- push: args.push !== false,
6552
- source: sourceState.source
6553
- });
6554
- if (repositoryPreflight) {
6555
- output.die(repositoryPreflight.error, repositoryPreflight.code);
6556
- }
6557
- const spinner2 = createSpinner();
6558
- const bundle = await buildDeployBundle({
6559
- appDir,
6560
- appName,
6561
- appId,
6562
- envName,
6563
- output,
6564
- spinner: spinner2
6565
- });
6566
- const oversized = oversizedAssetRefusal(bundle.assets);
6567
- if (oversized) {
6568
- spinner2.stop("Deploy failed");
6569
- output.die(oversized, "assets_too_large");
6570
- }
6571
- const repository = await syncDeployRepository({
6572
- deployUrl: DEPLOY_URL3,
6573
- appDir,
6574
- appId,
6575
- token,
6576
- push: args.push !== false,
6577
- ignoreStale: Boolean(args["ignore-stale"]),
6578
- output,
6579
- sourceState
6580
- });
6581
- const secrets = prepareDeploySecrets({
6582
- cache: secretsCache,
6583
- customBindings: bundle.customBindings,
6584
- doManifest: bundle.doManifest,
6585
- output
6586
- });
6587
- const body = await deployBuiltBundle({
6588
- deployUrl: DEPLOY_URL3,
6589
- appDir,
6646
+ }
6647
+ spinner2.stop(
6648
+ `Deployed! (edge confirmed in ${Math.round((Date.now() - edgeWaitStarted) / 1e3)}s)`
6649
+ );
6650
+ p12.log.success(`Live at: ${body.url}`);
6651
+ await syncCommerce(appDir, appId, token, output.nonInteractive);
6652
+ if (output.json) {
6653
+ return output.emitJson({
6654
+ ok: true,
6590
6655
  appId,
6591
6656
  appName,
6592
- token,
6593
- rename: confirmRename,
6594
- claimReleased: args["claim-released"] === true,
6595
- ignoreStale: Boolean(args["ignore-stale"]),
6596
- bundle,
6597
- secrets,
6598
- repository,
6599
- output,
6600
- spinner: spinner2
6657
+ url: body.url ?? null,
6658
+ // Always present, so a caller branches on one field instead of
6659
+ // inferring success from an absent one.
6660
+ serving,
6661
+ releaseId: body.releaseId ?? null,
6662
+ bundleRetained: body.bundleRetained ?? null,
6663
+ recoverable: repository.recoverable,
6664
+ ...staleBaseGuardFields(body)
6601
6665
  });
6602
- let serving = "unverifiable";
6603
- const edgeWaitStarted = Date.now();
6604
- if (body.url) {
6605
- spinner2.message("Waiting for the edge to serve this release...");
6606
- serving = await waitForLiveRelease(body.url, body.releaseStamp, 9e4);
6607
- if (serving !== "confirmed") {
6608
- spinner2.stop(
6609
- serving === "unconfirmed" ? "Deployed \u2014 the edge is still rolling this release out" : "Deployed \u2014 serving could not be verified from here"
6610
- );
6611
- p12.log.warn(
6612
- serving === "unconfirmed" ? "Some requests still get the previous release. Cloudflare rolls a version out per edge machine; it usually settles within a couple of minutes. Wait before asserting against it." : "This release carries no serving stamp (older platform, or a resumed deploy), so the CLI cannot tell which release the edge answers with."
6613
- );
6614
- p12.log.info(`URL: ${body.url}`);
6615
- await syncCommerce(appDir, appId, token, output.nonInteractive);
6616
- if (output.json) {
6617
- return output.emitJson({
6618
- ok: true,
6619
- appId,
6620
- appName,
6621
- url: body.url,
6622
- releaseId: body.releaseId ?? null,
6623
- bundleRetained: body.bundleRetained ?? null,
6624
- serving,
6625
- recoverable: repository.recoverable,
6626
- ...staleBaseGuardFields(body)
6627
- });
6628
- }
6629
- p12.outro("Done");
6630
- return;
6631
- }
6632
- }
6633
- spinner2.stop(
6634
- `Deployed! (edge confirmed in ${Math.round((Date.now() - edgeWaitStarted) / 1e3)}s)`
6635
- );
6636
- p12.log.success(`Live at: ${body.url}`);
6637
- await syncCommerce(appDir, appId, token, output.nonInteractive);
6638
- if (output.json) {
6639
- return output.emitJson({
6640
- ok: true,
6641
- appId,
6642
- appName,
6643
- url: body.url ?? null,
6644
- // Always present, so a caller branches on one field instead of
6645
- // inferring success from an absent one.
6646
- serving,
6647
- releaseId: body.releaseId ?? null,
6648
- bundleRetained: body.bundleRetained ?? null,
6649
- recoverable: repository.recoverable,
6650
- ...staleBaseGuardFields(body)
6651
- });
6652
- }
6653
- p12.outro("Done");
6654
6666
  }
6655
- });
6667
+ p12.outro("Done");
6668
+ }
6656
6669
  async function syncCommerce(appDir, appId, token, nonInteractive) {
6657
6670
  await syncSubscriptionPlans(appDir, appId, token, nonInteractive);
6658
6671
  await syncOneTimeProducts(appDir, appId, token);
@@ -6670,12 +6683,6 @@ function pendingRename(registeredHost, appName) {
6670
6683
  if (label === appName) return null;
6671
6684
  return { fromHost: registeredHost, toHost: [appName, ...domain].join(".") };
6672
6685
  }
6673
- function renameRefusalMessage(rename2) {
6674
- return `This deploy renames the app: ${rename2.fromHost} \u2192 ${rename2.toHost}. Confirmation needs an interactive terminal \u2014 re-run with --rename to approve the rename, or \`deepspace app init --new-id\` if you meant a separate app.`;
6675
- }
6676
- function renamePromptMessage(rename2) {
6677
- return `This deploy renames the app: ${rename2.fromHost} \u2192 ${rename2.toHost}. The URL changes and the old one stops serving right away; data, secrets, and collaborators travel with it. (Meant a separate app? Run \`deepspace app init --new-id\` instead.) Rename?`;
6678
- }
6679
6686
  function blankSelectorRefusal(args) {
6680
6687
  if (args.env !== void 0 && !String(args.env).trim()) {
6681
6688
  return {
@@ -6869,6 +6876,11 @@ var undeploy_default = defineDeepspaceCommand({
6869
6876
  type: "string",
6870
6877
  description: "wrangler.toml [env.<name>] block whose deployed app to remove (e.g. --env staging). Ignored if a positional name is given.",
6871
6878
  required: false
6879
+ },
6880
+ yes: {
6881
+ type: "boolean",
6882
+ description: "Skip the interactive confirmation. (Scripts and --json callers are never prompted; the command itself is their consent.)",
6883
+ default: false
6872
6884
  }
6873
6885
  },
6874
6886
  async run({ args }) {
@@ -6894,7 +6906,18 @@ var undeploy_default = defineDeepspaceCommand({
6894
6906
  "not_in_app_repo"
6895
6907
  );
6896
6908
  }
6897
- if (!args.json) p13.intro(`Undeploying ${appId}`);
6909
+ if (!args.json && !args.yes && process.stdin.isTTY) {
6910
+ p13.intro(`Undeploying ${appId}`);
6911
+ const confirmed = await p13.confirm({
6912
+ message: `Take ${appId} offline now? Its URL stops serving immediately; data, secrets, and the registration stay (the name is reserved for you for 30 days).`,
6913
+ initialValue: false
6914
+ });
6915
+ if (p13.isCancel(confirmed) || !confirmed) {
6916
+ throw new Refusal("Undeploy cancelled.", "undeploy_declined");
6917
+ }
6918
+ } else if (!args.json) {
6919
+ p13.intro(`Undeploying ${appId}`);
6920
+ }
6898
6921
  const s = args.json ? null : createSpinner();
6899
6922
  s?.start("Removing...");
6900
6923
  const res = await fetch(`${DEPLOY_URL4}/api/deploy/${appId}`, {
@@ -8495,7 +8518,7 @@ function fmtDate(iso) {
8495
8518
  if (!iso) return "\u2014";
8496
8519
  return iso.slice(0, 10);
8497
8520
  }
8498
- async function confirm5(message) {
8521
+ async function confirm6(message) {
8499
8522
  process.stdout.write(`${message} [y/N] `);
8500
8523
  const answer = await new Promise((resolve22) => {
8501
8524
  process.stdin.setEncoding("utf-8");
@@ -8574,7 +8597,7 @@ var buy = defineDeepspaceCommand({
8574
8597
  "confirmation_required"
8575
8598
  );
8576
8599
  }
8577
- const ok2 = await confirm5(
8600
+ const ok2 = await confirm6(
8578
8601
  `Buy ${domain} for ${price}/yr (auto-renews; non-refundable), attach to ${appId}? Provisioning takes ${expectedTime}.`
8579
8602
  );
8580
8603
  if (!ok2) {
@@ -8744,7 +8767,7 @@ var detach = defineDeepspaceCommand({
8744
8767
  "confirmation_required"
8745
8768
  );
8746
8769
  }
8747
- const ok2 = await confirm5(
8770
+ const ok2 = await confirm6(
8748
8771
  `Detach ${domain}? Routing will stop; the domain stays registered (auto-renew is unchanged).`
8749
8772
  );
8750
8773
  if (!ok2) {
@@ -10777,19 +10800,18 @@ var status_default = defineCommand11({
10777
10800
  "DEEPSPACE_API_URL",
10778
10801
  "DEEPSPACE_PLATFORM_URL"
10779
10802
  ].filter((k) => process.env[k]);
10803
+ const urls = effectivePlatformUrls();
10804
+ lines.push([
10805
+ "Env",
10806
+ [DEEPSPACE_ENV, ...urlOverrides.map((k) => `${k} set`)].join(" \xB7 ")
10807
+ ]);
10808
+ json.env = DEEPSPACE_ENV;
10809
+ json.services = urls;
10780
10810
  if (DEEPSPACE_ENV !== "production" || urlOverrides.length > 0) {
10781
- const urls = effectivePlatformUrls();
10782
- const detail = [
10783
- DEEPSPACE_ENV !== "production" ? DEEPSPACE_ENV : null,
10784
- ...urlOverrides.map((k) => `${k} set`)
10785
- ].filter(Boolean).join(" \xB7 ");
10786
- lines.push(["Env", detail]);
10787
10811
  lines.push([
10788
10812
  "Services",
10789
10813
  `auth ${urls.auth} \xB7 api ${urls.api} \xB7 platform ${urls.platform} \xB7 deploy ${urls.deploy}`
10790
10814
  ]);
10791
- json.env = DEEPSPACE_ENV;
10792
- json.services = urls;
10793
10815
  if (urlOverrides.length > 0) json.urlOverrides = urlOverrides;
10794
10816
  }
10795
10817
  facts.loggedIn = existsSync23(SESSION_PATH);
@@ -11310,9 +11332,9 @@ var pull_default = defineDeepspaceCommand({
11310
11332
  const token = await ensureToken();
11311
11333
  const deployUrl = deployBaseUrl();
11312
11334
  const appId = await resolveAppTarget(deployUrl, token, appArg);
11313
- ensureSpaceRemote(appDir, appId);
11314
11335
  spinner2?.message(`Checking the cloud ${branch} ref\u2026`);
11315
11336
  const remote = await repoApi(deployUrl, token, appId).getRefs();
11337
+ ensureSpaceRemote(appDir, appId);
11316
11338
  if (!remote) {
11317
11339
  spinner2?.stop("No cloud repo yet.");
11318
11340
  const pushCommand2 = targetedVcCommand("push", appId, branch);
@@ -14178,7 +14200,7 @@ import { join as join27, resolve as resolve21 } from "path";
14178
14200
  // package.json
14179
14201
  var package_default = {
14180
14202
  name: "deepspace",
14181
- version: "0.23.1",
14203
+ version: "0.23.2",
14182
14204
  engines: {
14183
14205
  node: ">=22.15.0 <23 || >=24 <25 || >=26 <27"
14184
14206
  },