void 0.23.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/AGENTS_TEMPLATE.md +1 -1
  2. package/README.md +19 -106
  3. package/dist/{account-cmd-C84Ee8cO.mjs → account-cmd-DcR1ywt8.mjs} +5 -5
  4. package/dist/{auth-CSkdO2Bb.mjs → auth-7wuZ5ob8.mjs} +22 -49
  5. package/dist/auth-CdgZ9uag.mjs +2 -0
  6. package/dist/{auth-link-CioEg6uY.mjs → auth-link-Z6E5DYvM.mjs} +5 -6
  7. package/dist/{auth-router-BsR981d4.mjs → auth-router-BdM4avI8.mjs} +7 -7
  8. package/dist/{build-cmd-LzvNJORH.mjs → build-cmd-CEE7D-hM.mjs} +7 -8
  9. package/dist/{cache-C4MvnrMH.mjs → cache-TcZnBLtH.mjs} +6 -7
  10. package/dist/{cancel-deploy-abUxpP2n.mjs → cancel-deploy-CYoZmcmR.mjs} +4 -6
  11. package/dist/{cf-access-P0iZnu0q.mjs → cf-access-AHKBzmuu.mjs} +4 -48
  12. package/dist/{cf-access-DRsQRe6k.mjs → cf-access-TWNzXltp.mjs} +3 -11
  13. package/dist/cf-build-output-ChY6-XWP.mjs +2 -0
  14. package/dist/cli/cli.mjs +49 -46
  15. package/dist/cli/cloudflare-operation-process.mjs +16 -7
  16. package/dist/cli/env-schema-probe.mjs +3 -3
  17. package/dist/client-B4Me-9HE.mjs +2 -0
  18. package/dist/{client-RV8NVeB8.mjs → client-RsPo8wsP.mjs} +129 -33
  19. package/dist/{cloudflare-cmd-BcrVyTmJ.mjs → cloudflare-cmd-bhwCxAN6.mjs} +2 -2
  20. package/dist/{cloudflare-connect-B8uPZ4nx.mjs → cloudflare-connect-CuhRgk3k.mjs} +2 -2
  21. package/dist/{cloudflare-operations-AiWashgg.mjs → cloudflare-operations-BhbK6yTq.mjs} +1 -1
  22. package/dist/{cloudflare-operations-fxHb-byx.mjs → cloudflare-operations-CjaV4lZi.mjs} +2 -2
  23. package/dist/{connect-Bd4kJd9U.mjs → connect-DCvUmPXY.mjs} +13 -10
  24. package/dist/{create-project-Boczwj5r.mjs → create-project-C734I-Mu.mjs} +1 -1
  25. package/dist/{create-project-bMf6ffLZ.mjs → create-project-eAPgYq35.mjs} +13 -13
  26. package/dist/{db-8uG64XLl.mjs → db-C07GEdKF.mjs} +27 -30
  27. package/dist/{delete-NvbiyeJf.mjs → delete-pKMVsrpJ.mjs} +5 -6
  28. package/dist/deploy-BDu1vhSH.mjs +2 -0
  29. package/dist/{deploy-DzAIwqNU.mjs → deploy-DfsAe-T0.mjs} +9567 -9215
  30. package/dist/{dev-inbox-P0u4tM8Y.mjs → dev-inbox-D64ZKUod.mjs} +5 -6
  31. package/dist/{domain-y5Tvydvo.mjs → domain-D3uA9ize.mjs} +8 -8
  32. package/dist/{email-B3umsW75.mjs → email-z3o2cwjH.mjs} +8 -8
  33. package/dist/{env-BS6qYHDb.mjs → env-3Q8-_2IH.mjs} +7 -9
  34. package/dist/{env-types-C2_bIk_b.mjs → env-types-D5kds_OZ.mjs} +1 -1
  35. package/dist/{env-validation-DbTg7-ar.mjs → env-validation-cZBvGWaP.mjs} +1 -1
  36. package/dist/{env-validation-BPn7vk-V.mjs → env-validation-vBSQ8gw5.mjs} +3 -3
  37. package/dist/gen-ById9r2j.mjs +2 -0
  38. package/dist/{gen-B580--vC.mjs → gen-NjwoG9FK.mjs} +2 -4
  39. package/dist/{github-cmd-v45BdfKX.mjs → github-cmd-DquUq-b1.mjs} +15 -24
  40. package/dist/{headers-DWi2IXWx.mjs → headers-2rKda9Y6.mjs} +1 -1
  41. package/dist/help-DPGBwomV.mjs +2 -0
  42. package/dist/{help-daGKjXGk.mjs → help-DRZXC4fj.mjs} +8 -4
  43. package/dist/{inbound-aVHEUhKo.mjs → inbound-fRkqcXaC.mjs} +1 -1
  44. package/dist/index.d.mts +18 -14
  45. package/dist/index.mjs +2176 -2110
  46. package/dist/{info-B97bTX9N.mjs → info-BmA3_IFZ.mjs} +1 -3
  47. package/dist/{init-Bvy7zrBo.mjs → init-DT7yuuyl.mjs} +28 -27
  48. package/dist/{link-CDqqCjFl.mjs → link-CXOlqh2F.mjs} +6 -7
  49. package/dist/{list-CZj0dzKY.mjs → list-eEWVJEPn.mjs} +8 -9
  50. package/dist/{local-d1-2CMnpuW_.mjs → local-d1-Df4XpwhW.mjs} +1 -1
  51. package/dist/log-vqY3pqwI.mjs +29 -0
  52. package/dist/login-C98-sw79.mjs +2 -0
  53. package/dist/{login-UZKFM_u7.mjs → login-pWQHYVu2.mjs} +12 -10
  54. package/dist/{logs-CUZ6t9t3.mjs → logs-DnxVX7TR.mjs} +11 -13
  55. package/dist/migrate-CEu2X5DB.mjs +2 -0
  56. package/dist/{migrate-DHul7PRV.mjs → migrate-CV1on-yJ.mjs} +2 -4
  57. package/dist/{operator-args-CLgKGlwU.mjs → operator-args-CAVcmwUt.mjs} +12 -5
  58. package/dist/{operator-auth-8KnOVXVd.mjs → operator-auth-CkmTE3rt.mjs} +2 -2
  59. package/dist/{operator-client-DUwumHpQ.mjs → operator-client-LmwjxT6q.mjs} +3 -3
  60. package/dist/{operator-cmd-DBA6dl0m.mjs → operator-cmd-d-IEKgNk.mjs} +6 -6
  61. package/dist/{output-Dm_A4Tbv.mjs → output-BBsUwdyT.mjs} +22 -14
  62. package/dist/pages/client.d.mts +3 -0
  63. package/dist/pages/client.mjs +120 -29
  64. package/dist/pages/index.mjs +1 -1
  65. package/dist/{platform-args-BJdRtlLq.mjs → platform-args-Bzf8JPc2.mjs} +11 -3
  66. package/dist/platform-args-Cq6EjQro.mjs +2 -0
  67. package/dist/{platform-auth-config-B56E9YP1.mjs → platform-auth-config-0V0lA3pF.mjs} +7 -7
  68. package/dist/{platform-auth-protection-BDWO_aER.mjs → platform-auth-protection-DFeJ-JkK.mjs} +9 -9
  69. package/dist/{platform-auth-recovery-1gg4CSRe.mjs → platform-auth-recovery-ICy4muq6.mjs} +7 -7
  70. package/dist/{platform-cmd-Bt-1w6pY.mjs → platform-cmd-BPySFOew.mjs} +1 -1
  71. package/dist/{platform-cmd-DMcQStSc.mjs → platform-cmd-D7vSWMvV.mjs} +38 -28
  72. package/dist/platform-discovery-DDDUvnqp.mjs +27 -0
  73. package/dist/{platform-domain-BNkcz0OB.mjs → platform-domain-CUdY064e.mjs} +5 -5
  74. package/dist/{platform-lifecycle-BE6C_jxh.mjs → platform-lifecycle-BaUdTRPU.mjs} +1 -1
  75. package/dist/{platform-lifecycle-9OyBALhH.mjs → platform-lifecycle-Dm09JNkn.mjs} +4404 -3297
  76. package/dist/{platform-management-CjwLVQwN.mjs → platform-management-BSEc_ZeG.mjs} +48 -11
  77. package/dist/platform-management-Bp6aoH2C.mjs +2 -0
  78. package/dist/{platform-plans-config-BNGKGr4P.mjs → platform-plans-config-B0pOVQyW.mjs} +3 -3
  79. package/dist/{platform-recovery-D6KSpuFm.mjs → platform-recovery-WOZ95Uze.mjs} +4 -4
  80. package/dist/{platform-registry-QBa4DK32.mjs → platform-registry-KfNEF84O.mjs} +3 -3
  81. package/dist/{prepare-B5Mkic5u.mjs → prepare-39EvOhI6.mjs} +2 -4
  82. package/dist/prepare-CnjcTV2s.mjs +2 -0
  83. package/dist/{prepare-DOsL0CC9.mjs → prepare-DnaKBi--.mjs} +1 -1
  84. package/dist/{project-C0Fqu05O.mjs → project-BkbfDs0V.mjs} +15 -82
  85. package/dist/project-IOjBU8R6.mjs +2 -0
  86. package/dist/{project-cmd-CNzrqvBv.mjs → project-cmd-Bs5A392E.mjs} +21 -22
  87. package/dist/{project-team-DQOWPfQT.mjs → project-team-ohAWWaew.mjs} +8 -9
  88. package/dist/{project-token-CTDYU0Cc.mjs → project-token-CP01Jna6.mjs} +6 -9
  89. package/dist/{project-zero-trust-BNAkW-_0.mjs → project-zero-trust-BzkVgx35.mjs} +5 -6
  90. package/dist/prompts-6OSVA7DJ.mjs +2087 -0
  91. package/dist/prompts-ZAuJlyCj.mjs +2 -0
  92. package/dist/{provision-C4ORE7G7.mjs → provision-BEv0k-qz.mjs} +1 -1
  93. package/dist/{provision-CJFgTZY8.mjs → provision-Btj1jppf.mjs} +5 -7
  94. package/dist/{requests-MhxYnau8.mjs → requests-B3PBuGlX.mjs} +5 -6
  95. package/dist/{rollback-CJ6iSDoU.mjs → rollback-DDub9GsO.mjs} +9 -10
  96. package/dist/runtime/ai.mjs +3 -5
  97. package/dist/runtime/email/testing.mjs +2 -2
  98. package/dist/runtime/email.mjs +36 -18
  99. package/dist/runtime/remote/index.mjs +2 -2
  100. package/dist/runtime/routing.mjs +1 -1
  101. package/dist/{secret-Dli5fP0B.mjs → secret-3c72lY1U.mjs} +15 -16
  102. package/dist/{skills-D1II1Juz.mjs → skills-BPQUGClu.mjs} +1 -1
  103. package/dist/{subcommand-prompt-CY1C4fvl.mjs → subcommand-prompt-Dhom39bd.mjs} +40 -32
  104. package/dist/sveltekit.d.mts +1 -1
  105. package/dist/sveltekit.mjs +4 -9
  106. package/dist/{wrangler-7K-bW_DL.mjs → wrangler-DhUerFkW.mjs} +10 -15
  107. package/package.json +22 -23
  108. package/sandbox.Dockerfile +1 -1
  109. package/skills/void/SKILL.md +6 -1
  110. package/skills/void/docs/guide/ai.md +24 -86
  111. package/skills/void/docs/guide/auth.md +0 -2
  112. package/skills/void/docs/guide/database/d1.md +7 -7
  113. package/skills/void/docs/guide/deployment.md +58 -102
  114. package/skills/void/docs/guide/edge/headers.md +1 -1
  115. package/skills/void/docs/guide/email/domains.md +5 -1
  116. package/skills/void/docs/guide/email/sending.md +1 -1
  117. package/skills/void/docs/guide/env-vars.md +1 -5
  118. package/skills/void/docs/guide/index.md +19 -18
  119. package/skills/void/docs/guide/kv.md +0 -2
  120. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +49 -47
  121. package/skills/void/docs/guide/pages-routing/overview.md +2 -2
  122. package/skills/void/docs/guide/platform/administration/email.md +0 -2
  123. package/skills/void/docs/guide/platform/administration/operations.md +11 -22
  124. package/skills/void/docs/guide/platform/administration/plans.md +1 -5
  125. package/skills/void/docs/guide/platform/administration/zero-trust.md +24 -9
  126. package/skills/void/docs/guide/platform/development/schema-ci.md +7 -1
  127. package/skills/void/docs/guide/platform/installation/ci.md +1 -1
  128. package/skills/void/docs/guide/platform/installation/credentials.md +10 -3
  129. package/skills/void/docs/guide/platform/installation/domains.md +8 -3
  130. package/skills/void/docs/guide/platform/installation/first-deployment.md +2 -2
  131. package/skills/void/docs/guide/platform/installation/maintenance.md +37 -5
  132. package/skills/void/docs/guide/platform/installation/prerequisites.md +87 -14
  133. package/skills/void/docs/guide/platform/installation/setup.md +80 -10
  134. package/skills/void/docs/guide/quickstart.md +37 -80
  135. package/skills/void/docs/guide/remote-dev.md +1 -1
  136. package/skills/void/docs/guide/sandboxes.md +36 -46
  137. package/skills/void/docs/guide/self-hosted-platform.md +20 -0
  138. package/skills/void/docs/guide/websockets.md +0 -2
  139. package/skills/void/docs/integrations/frameworks/overview.md +2 -2
  140. package/skills/void/docs/integrations/frameworks/sveltekit.md +40 -25
  141. package/skills/void/docs/integrations/nodejs-bun-deno.md +7 -2
  142. package/skills/void/docs/reference/api/resources.md +27 -0
  143. package/skills/void/docs/reference/api.md +1 -1
  144. package/skills/void/docs/reference/cli/auth.md +4 -3
  145. package/skills/void/docs/reference/cli/database.md +1 -1
  146. package/skills/void/docs/reference/cli/deploy.md +21 -1
  147. package/skills/void/docs/reference/cli/platform-installation.md +42 -27
  148. package/skills/void/docs/reference/cli/platform-operations.md +4 -8
  149. package/skills/void/docs/reference/cli/platform-zero-trust.md +14 -0
  150. package/skills/void/docs/reference/cli/platform.md +5 -0
  151. package/skills/void/docs/reference/config.md +1 -1
  152. package/skills/void/docs/reference/resource-inference.md +11 -8
  153. package/dist/auth-CCjt0hcq.mjs +0 -2
  154. package/dist/cf-build-output-_0HNWysu.mjs +0 -2
  155. package/dist/client-Cu7jWiF1.mjs +0 -2
  156. package/dist/deploy-bjXdFCtn.mjs +0 -2
  157. package/dist/dist-BuDuKZJv.mjs +0 -2
  158. package/dist/dist-CTBk70IR.mjs +0 -1310
  159. package/dist/gen-BVaUUumi.mjs +0 -2
  160. package/dist/help-DofyZuY7.mjs +0 -2
  161. package/dist/log-ChfPKsVd.mjs +0 -26
  162. package/dist/login-DYt_An22.mjs +0 -2
  163. package/dist/migrate-8_2u55MD.mjs +0 -2
  164. package/dist/platform-args-D3RXyR6h.mjs +0 -2
  165. package/dist/platform-management-CnyTdcWX.mjs +0 -2
  166. package/dist/prepare-cgvDMtSb.mjs +0 -2
  167. package/dist/project-BuUwfj6f.mjs +0 -2
  168. package/skills/void/docs/guide/env-migration.md +0 -109
  169. package/dist/{cf-build-output-BPqOT964.mjs → cf-build-output-U8o1Gl6X.mjs} +1 -1
@@ -1,9 +1,9 @@
1
- import { a as listInstallationManifests, d as readInstallationRecoverySecrets, h as resolveInstallationManifest, m as removePlatformConnectionForInstallation, p as removeInstallationRecoverySecrets, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-QBa4DK32.mjs";
2
- import { E as confirm, I as select, N as note, P as outro, W as isCancel, j as log } from "./dist-CTBk70IR.mjs";
3
- import { i as createSpinner } from "./output-Dm_A4Tbv.mjs";
4
- import { A as PlatformCloudflareClient, C as revalidatePlatformInstallAction, E as resolvePlatformCloudflareCredential, M as hyperdriveOriginFromConnectionString, N as hyperdriveOriginMatches, P as verifyPlatformRuntimeTokenPermissions, S as platformProvisionIntentHash, T as assertPlatformOperatorCredentialCanApplyPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY, b as formatPlatformInstallPlan, d as loadPlatformRuntime, g as assertProjectZeroTrustAllowsUninstall, h as resolveBootstrapGitHubId, j as hyperdriveOriginConfigHash, l as createPlatformInstallationSecrets, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, p as readPlatformProjectZeroTrustState, t as assertNoninteractivePlatformMutationAcknowledged, u as installPlatform, v as trackedPlatformWorkerTraffic, w as platformDatabaseNameFromOwnerUrl, x as platformAdoptionIntentHash, y as createPlatformInstallPlan } from "./platform-lifecycle-9OyBALhH.mjs";
5
- import { createHash } from "node:crypto";
1
+ import { a as listInstallationManifests, f as readInstallationRecoverySecrets, g as resolveInstallationManifest, h as removePlatformConnectionForInstallation, m as removeInstallationRecoverySecrets, t as acquirePlatformLifecycleLock, y as writeInstallationManifest } from "./platform-registry-KfNEF84O.mjs";
2
+ import { A as confirm, B as note, H as outro, K as select, L as log, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
3
+ import { r as createSpinner } from "./output-BBsUwdyT.mjs";
4
+ import { A as PlatformCloudflareClient, C as revalidatePlatformInstallAction, E as resolvePlatformCloudflareCredential, M as hyperdriveOriginFromConnectionString, N as hyperdriveOriginMatches, P as verifyPlatformRuntimeTokenPermissions, S as platformProvisionIntentHash, T as assertPlatformOperatorCredentialCanApplyPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY, b as formatPlatformInstallPlan, d as assertProjectZeroTrustAllowsUninstall, f as loadPlatformRuntime, h as resolveBootstrapGitHubId, j as hyperdriveOriginConfigHash, m as createPlatformInstallationSecrets, n as resolvePlatformInstallDatabaseUrl, o as installPlatform, s as acquirePlatformDatabaseLifecycleLock, t as assertNoninteractivePlatformMutationAcknowledged, u as readPlatformProjectZeroTrustState, v as trackedPlatformWorkerTraffic, w as platformDatabaseNameFromOwnerUrl, x as platformAdoptionIntentHash, y as createPlatformInstallPlan } from "./platform-lifecycle-Dm09JNkn.mjs";
6
5
  import { PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE, PLATFORM_R2_OWNERSHIP_MARKER_KEY, createPlatformResourceOwnershipMarker, parsePlatformInstallationManifest, parsePlatformResourceOwnershipMarker, recordInstallationResource, recordInstallationStep, setInstallationDesiredState, transitionInstallation } from "@void/platform";
6
+ import { createHash } from "node:crypto";
7
7
  //#region src/cli/platform-management.ts
8
8
  async function verifyPlatformInstallationOwnership(client, manifest, options = {}) {
9
9
  const ready = manifest.resources.filter((resource) => resource.state === "ready" && isOwnershipVerifiableKind(resource.kind) && !options.retainedReplacementKeys?.has(resource.key));
@@ -23,6 +23,22 @@ function selectAuthoritativePlatformManifest(local, authoritative) {
23
23
  if (authoritative.id !== local.id || authoritative.ownershipNonce !== local.ownershipNonce || authoritative.account.id !== local.account.id) throw new Error("platform: The authoritative lifecycle state belongs to another installation.");
24
24
  return authoritative;
25
25
  }
26
+ function commandArgument(value) {
27
+ return /^[a-zA-Z0-9_./:@-]+$/.test(value) ? value : `'${value.replaceAll("'", "'\\''")}'`;
28
+ }
29
+ function platformLifecycleResumeCommand(args, installationId) {
30
+ const command = [
31
+ "void",
32
+ "platform",
33
+ args.subcommand,
34
+ commandArgument(installationId)
35
+ ];
36
+ if (args.runtime) command.push("--runtime", commandArgument(args.runtime));
37
+ if (args.subcommand === "rollback" && args.fromRuntime) command.push("--from-runtime", commandArgument(args.fromRuntime));
38
+ if ("dashboardUrl" in args && args.dashboardUrl) command.push("--dashboard-url", commandArgument(args.dashboardUrl));
39
+ if (args.yes) command.push("--yes");
40
+ return command.join(" ");
41
+ }
26
42
  async function runInstalledPlatformCommand(args) {
27
43
  if (args.subcommand !== "upgrade" && args.subcommand !== "rollback" && args.subcommand !== "repair" && args.subcommand !== "disable" && args.subcommand !== "enable" && args.subcommand !== "uninstall") throw new Error(`platform: Unsupported lifecycle command ${args.subcommand}.`);
28
44
  assertNoninteractivePlatformMutationAcknowledged(args, process.stdin.isTTY === true);
@@ -35,7 +51,7 @@ async function runInstalledPlatformCommand(args) {
35
51
  timingPrevious = current;
36
52
  };
37
53
  const manifest = await resolveInstalledPlatformManifest(args.selector);
38
- const operatorCredential = await resolvePlatformCloudflareCredential();
54
+ const operatorCredential = await resolvePlatformCloudflareCredential({ savedManagementToken: readInstallationRecoverySecrets(manifest)?.managementApiToken });
39
55
  const operatorClient = new PlatformCloudflareClient(operatorCredential.token);
40
56
  const runtime = args.subcommand === "uninstall" || args.subcommand === "disable" ? null : loadPlatformRuntime(args.runtime);
41
57
  const rollbackSourceRuntime = args.subcommand === "rollback" ? loadPlatformRuntime(args.fromRuntime) : null;
@@ -94,11 +110,16 @@ async function runInstalledPlatformCommand(args) {
94
110
  markPhase("plan");
95
111
  note(formatPlatformInstallPlan(plan), args.subcommand === "upgrade" ? "Upgrade plan" : args.subcommand === "rollback" ? "Rollback plan" : args.subcommand === "enable" ? "Enable plan" : "Repair plan");
96
112
  note([
97
- `Version: ${runtime.manifest.platformVersion}`,
113
+ `Version: ${manifest.platformVersion} → ${runtime.manifest.platformVersion}`,
98
114
  `Source: ${runtime.source}`,
99
115
  `Revision: ${runtime.manifest.sourceRevision ?? "not recorded"}`,
100
116
  `Manifest SHA-256: ${runtime.manifestSha256}`
101
117
  ].join("\n"), "Platform runtime");
118
+ note([
119
+ manifest.desiredState === "disabled" && args.subcommand !== "enable" ? "Application traffic will stay paused because this installation is disabled." : "Application traffic may pause during a safe cutover. Traffic resumes after verification.",
120
+ "Saved progress survives an interruption. Resume with the same runtime files.",
121
+ `Administrator status: ${plan.apiUrl}/admin/status`
122
+ ].join("\n"), "Availability and progress");
102
123
  if (args.plan) {
103
124
  outro("No Cloudflare or local installation state was changed.");
104
125
  return;
@@ -165,6 +186,7 @@ async function runInstalledPlatformCommand(args) {
165
186
  progress?.message(message);
166
187
  },
167
188
  runtime,
189
+ operation: args.subcommand,
168
190
  replanWorkers: async (recoveryManifest) => (await createPlatformInstallPlan(client, planInput, recoveryManifest, {
169
191
  authoritativeProvisionIntents: true,
170
192
  repairMissing: true,
@@ -183,14 +205,22 @@ async function runInstalledPlatformCommand(args) {
183
205
  progress?.stop(result.waitingForDns || result.waitingForSandboxDrain ? "Platform operation paused; progress is saved." : `Platform ${args.subcommand} complete.`);
184
206
  progress = void 0;
185
207
  if (result.waitingForDns) {
186
- note(`Wait for ${deployment.application.zoneName} to become active, then rerun this command.`, "Waiting for nameservers");
208
+ note(`Wait for ${deployment.application.zoneName} to become active, then resume:\n${platformLifecycleResumeCommand(args, manifest.id)}`, "Waiting for nameservers");
187
209
  return;
188
210
  }
189
211
  if (result.waitingForSandboxDrain) {
190
- note("The compatible candidate runtime is live in sandbox-drain maintenance mode and application traffic remains disabled. Preview bounded work with `void platform system sandbox-drain --plan`; follow any returned `nextCursor` with `--cursor '<value>'`. Then apply with `void platform system sandbox-drain --yes` and rerun until it reports DB-backed `complete: true`. Rerun this lifecycle command afterward to enable traffic.", "Waiting for managed Sandbox drain");
212
+ note([
213
+ "Application traffic is paused. Saved progress is ready to resume.",
214
+ "1. Review remaining Sandbox work: void platform system sandbox-drain --plan",
215
+ "2. Apply: void platform system sandbox-drain --yes (follow nextCursor with --cursor '<value>' until complete: true).",
216
+ `3. Resume: ${platformLifecycleResumeCommand(args, manifest.id)}`,
217
+ `Administrator status: ${plan.apiUrl}/admin/status`
218
+ ].join("\n"), "Waiting for managed Sandbox drain");
191
219
  return;
192
220
  }
193
- log.success(args.subcommand === "rollback" ? `${deployment.displayName} is running compatible runtime ${runtime.manifest.platformVersion}; PostgreSQL remains at schema ${rollbackSourceRuntime.manifest.database.schemaDigest}.` : `${deployment.displayName} is healthy at ${plan.apiUrl}.`);
221
+ log.success(`${deployment.displayName}: runtime ${runtime.manifest.platformVersion} ${args.subcommand === "rollback" ? "restored" : "ready"}.`);
222
+ log.info(result.manifest.desiredState === "disabled" ? "Application traffic remains paused. Enable the installation when you are ready." : `Platform verification passed. Traffic is enabled at ${plan.apiUrl}.`);
223
+ if (args.subcommand === "rollback") log.info("PostgreSQL migrations were retained; rollback changes the runtime only.");
194
224
  if (result.emailOperationId) log.info(`Shared email routing ready (operation ${result.emailOperationId}).`);
195
225
  if (result.setupPending) {
196
226
  const code = readInstallationRecoverySecrets(result.manifest)?.authBootstrapCode;
@@ -226,8 +256,15 @@ async function runInstalledPlatformCommand(args) {
226
256
  reportResult?.();
227
257
  markPhase("complete");
228
258
  } catch (error) {
259
+ const operationStarted = progress !== void 0;
229
260
  progress?.error(`Platform ${args.subcommand} failed.`);
230
261
  progress = void 0;
262
+ if (operationStarted && args.subcommand !== "uninstall" && args.subcommand !== "disable") note([
263
+ "Traffic may remain paused. Inspect the saved state before continuing:",
264
+ `void platform status ${commandArgument(manifest.id)}`,
265
+ "After resolving the error, resume with the same runtime:",
266
+ platformLifecycleResumeCommand(args, manifest.id)
267
+ ].join("\n"), "Recovery");
231
268
  throw error;
232
269
  } finally {
233
270
  try {
@@ -791,4 +828,4 @@ async function promptForConfirmation(message, initialValue) {
791
828
  return answer;
792
829
  }
793
830
  //#endregion
794
- export { resolveInstalledPlatformManifest as a, selectAuthoritativePlatformManifest as c, recoverDurablyMarkedProvisionIntents as i, uninstallPlatform as l, disablePlatform as n, resolvePlatformRuntimeTokenToPreflight as o, isPlatformManifestMonotonicExtension as r, runInstalledPlatformCommand as s, assertPlatformRollbackCompatibility as t, verifyPlatformInstallationOwnership as u };
831
+ export { recoverDurablyMarkedProvisionIntents as a, runInstalledPlatformCommand as c, verifyPlatformInstallationOwnership as d, platformLifecycleResumeCommand as i, selectAuthoritativePlatformManifest as l, disablePlatform as n, resolveInstalledPlatformManifest as o, isPlatformManifestMonotonicExtension as r, resolvePlatformRuntimeTokenToPreflight as s, assertPlatformRollbackCompatibility as t, uninstallPlatform as u };
@@ -0,0 +1,2 @@
1
+ import { c as runInstalledPlatformCommand, d as verifyPlatformInstallationOwnership, l as selectAuthoritativePlatformManifest } from "./platform-management-BSEc_ZeG.mjs";
2
+ export { runInstalledPlatformCommand, selectAuthoritativePlatformManifest, verifyPlatformInstallationOwnership };
@@ -1,6 +1,6 @@
1
- import { B as text, E as confirm, I as select, W as isCancel } from "./dist-CTBk70IR.mjs";
2
- import { n as OperatorClient, r as OperatorClientError } from "./operator-client-DUwumHpQ.mjs";
3
- import { a as resolveOperatorOrigin, r as readOperatorToken } from "./operator-auth-8KnOVXVd.mjs";
1
+ import { A as confirm, K as select, X as text, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
2
+ import { n as OperatorClient, r as OperatorClientError } from "./operator-client-LmwjxT6q.mjs";
3
+ import { a as resolveOperatorOrigin, r as readOperatorToken } from "./operator-auth-CkmTE3rt.mjs";
4
4
  import { stripVTControlCharacters } from "node:util";
5
5
  import { PLAN_EDITABLE_LIMIT_KEYS, PLAN_LIMITS, parseBuildInstanceType, parsePlanLimitsPatch, parsePlanName, parsePlatformPlanId } from "@void/platform/plans";
6
6
  import { readFile } from "node:fs/promises";
@@ -1,7 +1,7 @@
1
- import { t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
2
- import { a as listInstallationManifests, g as savePlatformConnection, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-QBa4DK32.mjs";
3
- import { a as REMOTE_INSTALLATION_MANIFEST_KEY, y as createPlatformInstallPlan } from "./platform-lifecycle-9OyBALhH.mjs";
4
- import { i as recoverDurablyMarkedProvisionIntents, r as isPlatformManifestMonotonicExtension, u as verifyPlatformInstallationOwnership } from "./platform-management-CjwLVQwN.mjs";
1
+ import { _ as savePlatformConnection, a as listInstallationManifests, t as acquirePlatformLifecycleLock, y as writeInstallationManifest } from "./platform-registry-KfNEF84O.mjs";
2
+ import { t as cfAccessHeaders } from "./cf-access-TWNzXltp.mjs";
3
+ import { a as REMOTE_INSTALLATION_MANIFEST_KEY, y as createPlatformInstallPlan } from "./platform-lifecycle-Dm09JNkn.mjs";
4
+ import { a as recoverDurablyMarkedProvisionIntents, d as verifyPlatformInstallationOwnership, r as isPlatformManifestMonotonicExtension } from "./platform-management-BSEc_ZeG.mjs";
5
5
  import { parsePlatformInstallationManifest, setInstallationEndpoints } from "@void/platform";
6
6
  //#region src/cli/platform-recovery.ts
7
7
  async function recoverPlatformInstallations(client, accountId, verifyEndpoint = verifyInstallationEndpoint, selector = "") {
@@ -1,9 +1,9 @@
1
1
  import { a as join, u as resolve } from "./dist-BVqXeR_h.mjs";
2
2
  import { closeSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
3
+ import { parsePlatformInstallationManifest } from "@void/platform";
3
4
  import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:crypto";
4
5
  import { homedir, hostname } from "node:os";
5
6
  import { Entry } from "@napi-rs/keyring";
6
- import { parsePlatformInstallationManifest } from "@void/platform";
7
7
  //#region src/cli/keyring.ts
8
8
  function readKeyringPassword(service, account) {
9
9
  try {
@@ -66,7 +66,7 @@ function parseConnection(value) {
66
66
  const lastUsedAt = String(entry.lastUsedAt ?? "");
67
67
  if (!Number.isFinite(Date.parse(lastUsedAt))) throw new Error("platform: Invalid connection timestamp in the local registry.");
68
68
  const optionalString = (input) => typeof input === "string" && input !== "" ? input : null;
69
- const proxyUrl = optionalString(entry.proxyUrl) ?? (apiUrl === "https://api.void.cloud" ? "https://proxy.void.cloud" : apiUrl === "https://api.staging.void.cloud" ? "https://proxy.staging.void.cloud" : null);
69
+ const proxyUrl = optionalString(entry.proxyUrl);
70
70
  return {
71
71
  accountId: optionalString(entry.accountId),
72
72
  apiUrl,
@@ -428,4 +428,4 @@ function removePlatformConnectionForInstallation(installationId, directory = pla
428
428
  });
429
429
  }
430
430
  //#endregion
431
- export { writeKeyringPassword as S, selectPlatformConnection as _, listInstallationManifests as a, deleteKeyringPassword as b, platformCredentialAccount as c, readInstallationRecoverySecrets as d, readPendingInstallationSecrets as f, savePlatformConnection as g, resolveInstallationManifest as h, latestPlatformWorkerCutoverGeneration as i, platformWorkerSecretUpdateIntentState as l, removePlatformConnectionForInstallation as m, assertPlatformInstallationSlugAvailable as n, listPlatformConnections as o, removeInstallationRecoverySecrets as p, getActivePlatformConnection as r, normalizePlatformApiUrl as s, acquirePlatformLifecycleLock as t, promoteInstallationSecrets as u, writeInstallationManifest as v, readKeyringPassword as x, writePendingInstallationSecrets as y };
431
+ export { writeKeyringPassword as C, readKeyringPassword as S, savePlatformConnection as _, listInstallationManifests as a, writePendingInstallationSecrets as b, platformCredentialAccount as c, promoteInstallationSecrets as d, readInstallationRecoverySecrets as f, resolveInstallationManifest as g, removePlatformConnectionForInstallation as h, latestPlatformWorkerCutoverGeneration as i, platformRegistryDirectory as l, removeInstallationRecoverySecrets as m, assertPlatformInstallationSlugAvailable as n, listPlatformConnections as o, readPendingInstallationSecrets as p, getActivePlatformConnection as r, normalizePlatformApiUrl as s, acquirePlatformLifecycleLock as t, platformWorkerSecretUpdateIntentState as u, selectPlatformConnection as v, deleteKeyringPassword as x, writeInstallationManifest as y };
@@ -1,10 +1,8 @@
1
- import { N as note, O as intro, P as outro, j as log } from "./dist-CTBk70IR.mjs";
2
- import { r as cliTitle } from "./output-Dm_A4Tbv.mjs";
3
- import { t as prepareProject } from "./prepare-DOsL0CC9.mjs";
1
+ import { B as note, H as outro, L as log } from "./prompts-6OSVA7DJ.mjs";
2
+ import { t as prepareProject } from "./prepare-DnaKBi--.mjs";
4
3
  //#region src/cli/prepare.ts
5
4
  async function runPrepareCommand(root, _args) {
6
5
  console.log();
7
- intro(cliTitle("prepare"));
8
6
  const result = await prepareProject(root);
9
7
  if (result.written.length > 0) note(result.written.join("\n"), "Wrote");
10
8
  if (result.removed.length > 0) note(result.removed.join("\n"), "Removed stale files");
@@ -0,0 +1,2 @@
1
+ import { t as prepareProject } from "./prepare-DnaKBi--.mjs";
2
+ export { prepareProject };
@@ -4,7 +4,7 @@ import { m as readConfig } from "./config-Br_JZD6u.mjs";
4
4
  import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-B8GeM0RM.mjs";
5
5
  import { i as generateDbDts, n as generateQueueTypes, t as generateRouteTypes } from "./route-types-Clm4WD0B.mjs";
6
6
  import { t as discoverSchema } from "./discover-BcPPiF1o.mjs";
7
- import { r as generateEnvTypes, t as findEnvFile } from "./env-types-C2_bIk_b.mjs";
7
+ import { r as generateEnvTypes, t as findEnvFile } from "./env-types-D5kds_OZ.mjs";
8
8
  import { a as loadLocalEnv } from "./env-_v349JBd.mjs";
9
9
  import { t as analyzeApplication } from "./application-routing-B7QEjqSR.mjs";
10
10
  import { n as generateVoidAuthDrizzleSchema, t as generateVoidAuthDatabaseModule } from "./drizzle-Beb2Am5S.mjs";
@@ -1,60 +1,7 @@
1
1
  import { a as join, n as dirname } from "./dist-BVqXeR_h.mjs";
2
- import { o as listPlatformConnections, s as normalizePlatformApiUrl } from "./platform-registry-QBa4DK32.mjs";
2
+ import { o as listPlatformConnections, s as normalizePlatformApiUrl } from "./platform-registry-KfNEF84O.mjs";
3
3
  import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
- import { homedir } from "node:os";
5
4
  import { normalizeApplicationDomain } from "@void/platform";
6
- //#region src/cli/hosted-platform.ts
7
- const VOID_CLOUD_PLATFORM = Object.freeze({
8
- apiUrl: "https://api.void.cloud",
9
- applicationDomain: "void.app",
10
- displayName: "Void Cloud",
11
- proxyUrl: "https://proxy.void.cloud"
12
- });
13
- const VOID_CLOUD_STAGING_PLATFORM = Object.freeze({
14
- apiUrl: "https://api.staging.void.cloud",
15
- applicationDomain: "staging.void.app",
16
- displayName: "Void Cloud staging",
17
- proxyUrl: "https://proxy.staging.void.cloud"
18
- });
19
- const HOSTED_PLATFORMS = [VOID_CLOUD_PLATFORM, VOID_CLOUD_STAGING_PLATFORM];
20
- function hostedPlatformForApiUrl(apiUrl) {
21
- if (typeof apiUrl !== "string") return null;
22
- let normalized;
23
- try {
24
- const parsed = new URL(apiUrl);
25
- if (parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.search || parsed.hash || parsed.pathname !== "/" && parsed.pathname !== "") return null;
26
- normalized = parsed.origin;
27
- } catch {
28
- return null;
29
- }
30
- return HOSTED_PLATFORMS.find((platform) => platform.apiUrl === normalized) ?? null;
31
- }
32
- /** Resolve an old ~/.void/config.json selection without returning credential values. */
33
- function readLegacyHostedPlatformSelection(configPath = join(homedir(), ".void", "config.json")) {
34
- let value = {};
35
- try {
36
- value = JSON.parse(readFileSync(configPath, "utf8"));
37
- } catch {
38
- return null;
39
- }
40
- if (value.api !== void 0) {
41
- const platform = hostedPlatformForApiUrl(value.api);
42
- return platform ? {
43
- ...platform,
44
- source: "configured-api"
45
- } : null;
46
- }
47
- if (typeof value.token === "string" && value.token !== "") return {
48
- ...VOID_CLOUD_PLATFORM,
49
- source: "legacy-credential"
50
- };
51
- if (typeof value.stagingToken === "string" && value.stagingToken !== "") return {
52
- ...VOID_CLOUD_STAGING_PLATFORM,
53
- source: "legacy-credential"
54
- };
55
- return null;
56
- }
57
- //#endregion
58
5
  //#region src/cli/project.ts
59
6
  const PROJECT_FILE = ".void/project.json";
60
7
  function readProjectConfigFile(root) {
@@ -83,7 +30,6 @@ function readProjectConfig(root) {
83
30
  if (typeof config.platformUrl === "string") result.platformUrl = normalizePlatformApiUrl(config.platformUrl);
84
31
  if (typeof config.applicationDomain === "string") result.applicationDomain = normalizeApplicationDomain(config.applicationDomain);
85
32
  if (typeof config.proxyUrl === "string") result.proxyUrl = normalizePlatformApiUrl(config.proxyUrl);
86
- if (config.voidInternalStaging === true) result.voidInternalStaging = true;
87
33
  return result;
88
34
  }
89
35
  /**
@@ -112,7 +58,6 @@ function writeDeploymentPlatform(root, platform) {
112
58
  if (typeof existing?.applicationDomain === "string") next.applicationDomain = existing.applicationDomain;
113
59
  if (typeof existing?.proxyUrl === "string") next.proxyUrl = existing.proxyUrl;
114
60
  if (typeof existing?.slug === "string") next.slug = existing.slug;
115
- if (existing?.voidInternalStaging === true) next.voidInternalStaging = true;
116
61
  mkdirSync(dirname(filePath), { recursive: true });
117
62
  writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
118
63
  }
@@ -120,12 +65,18 @@ function writeDeploymentPlatform(root, platform) {
120
65
  function writePlatformSelection(root, connection) {
121
66
  const existing = readProjectConfigFile(root);
122
67
  const linked = readProjectConfig(root);
123
- const pinnedUrl = isVoidInternalStaging(root) ? VOID_CLOUD_STAGING_PLATFORM.apiUrl : linked ? linked.platformUrl ?? VOID_CLOUD_PLATFORM.apiUrl : null;
68
+ const pinnedUrl = linked?.platformUrl;
124
69
  if (pinnedUrl && pinnedUrl !== connection.apiUrl) return false;
70
+ const metadata = { ...existing };
71
+ delete metadata.voidInternalStaging;
72
+ if (linked && !pinnedUrl) {
73
+ delete metadata.projectId;
74
+ delete metadata.slug;
75
+ }
125
76
  const filePath = join(root, PROJECT_FILE);
126
77
  mkdirSync(dirname(filePath), { recursive: true });
127
78
  writeFileSync(filePath, JSON.stringify({
128
- ...existing,
79
+ ...metadata,
129
80
  platform: "void",
130
81
  platformUrl: normalizePlatformApiUrl(connection.apiUrl),
131
82
  applicationDomain: normalizeApplicationDomain(connection.applicationDomain),
@@ -133,32 +84,19 @@ function writePlatformSelection(root, connection) {
133
84
  }, null, 2) + "\n");
134
85
  return true;
135
86
  }
136
- /**
137
- * Internal-only platform developers' staging switch.
138
- * This intentionally lives with the project link state, not public void.json.
139
- */
140
- function isVoidInternalStaging(root) {
141
- return readProjectConfigFile(root)?.voidInternalStaging === true;
142
- }
143
87
  function readProjectPlatformUrl(root) {
144
88
  const value = readProjectConfigFile(root)?.platformUrl;
145
89
  return typeof value === "string" && value !== "" ? normalizePlatformApiUrl(value) : null;
146
90
  }
147
- function readProjectApplicationDomain(root) {
148
- const value = readProjectConfigFile(root)?.applicationDomain;
149
- return typeof value === "string" && value !== "" ? normalizeApplicationDomain(value) : null;
91
+ /** A deploy can establish a first link, but must never replace a saved destination. */
92
+ function shouldLinkDeployProject(root, apiUrl) {
93
+ const platform = readDeploymentPlatform(root);
94
+ const selectedUrl = readProjectPlatformUrl(root);
95
+ return !readProjectConfig(root) && platform !== "cloudflare" && platform !== "none" && (!selectedUrl || selectedUrl === normalizePlatformApiUrl(apiUrl));
150
96
  }
151
97
  /** Resolve the immutable platform identity that every newly linked project records. */
152
98
  function attachSelectedPlatform(root, config, platformApiUrl) {
153
99
  const apiUrl = normalizePlatformApiUrl(platformApiUrl);
154
- const hosted = hostedPlatformForApiUrl(apiUrl);
155
- if (hosted) return {
156
- ...config,
157
- applicationDomain: hosted.applicationDomain,
158
- platformUrl: hosted.apiUrl,
159
- proxyUrl: hosted.proxyUrl,
160
- ...isVoidInternalStaging(root) && hosted.apiUrl === VOID_CLOUD_STAGING_PLATFORM.apiUrl ? { voidInternalStaging: true } : {}
161
- };
162
100
  const connection = listPlatformConnections().find((entry) => entry.apiUrl === apiUrl);
163
101
  if (connection?.applicationDomain && connection.proxyUrl) return {
164
102
  ...config,
@@ -168,10 +106,6 @@ function attachSelectedPlatform(root, config, platformApiUrl) {
168
106
  };
169
107
  throw new Error(`platform: No verified metadata is registered for ${apiUrl}. Run \`void connect ${apiUrl}\` before linking a project.`);
170
108
  }
171
- function isLegacyVoidCloudProject(root) {
172
- const config = readProjectConfigFile(root);
173
- return typeof config?.projectId === "string" && typeof config.slug === "string" && typeof config.platformUrl !== "string";
174
- }
175
109
  /**
176
110
  * Write the project config to the project root.
177
111
  */
@@ -189,7 +123,6 @@ function writeProjectConfig(root, config) {
189
123
  else if (typeof existing?.applicationDomain === "string") next.applicationDomain = existing.applicationDomain;
190
124
  if (config.proxyUrl) next.proxyUrl = normalizePlatformApiUrl(config.proxyUrl);
191
125
  else if (typeof existing?.proxyUrl === "string") next.proxyUrl = existing.proxyUrl;
192
- if (config.voidInternalStaging === true || existing?.voidInternalStaging === true) next.voidInternalStaging = true;
193
126
  mkdirSync(dirname(filePath), { recursive: true });
194
127
  writeFileSync(filePath, JSON.stringify(next, null, 2) + "\n");
195
128
  }
@@ -206,4 +139,4 @@ function removeProjectConfig(root) {
206
139
  }
207
140
  }
208
141
  //#endregion
209
- export { readProjectApplicationDomain as a, removeProjectConfig as c, writeProjectConfig as d, VOID_CLOUD_PLATFORM as f, readDeploymentPlatform as i, writeDeploymentPlatform as l, readLegacyHostedPlatformSelection as m, isLegacyVoidCloudProject as n, readProjectConfig as o, VOID_CLOUD_STAGING_PLATFORM as p, isVoidInternalStaging as r, readProjectPlatformUrl as s, attachSelectedPlatform as t, writePlatformSelection as u };
142
+ export { removeProjectConfig as a, writePlatformSelection as c, readProjectPlatformUrl as i, writeProjectConfig as l, readDeploymentPlatform as n, shouldLinkDeployProject as o, readProjectConfig as r, writeDeploymentPlatform as s, attachSelectedPlatform as t };
@@ -0,0 +1,2 @@
1
+ import { l as writeProjectConfig, t as attachSelectedPlatform } from "./project-BkbfDs0V.mjs";
2
+ export { attachSelectedPlatform, writeProjectConfig };
@@ -1,12 +1,11 @@
1
- import { c as getToken, s as getSiteDomain } from "./auth-CSkdO2Bb.mjs";
2
- import { i as readDeploymentPlatform } from "./project-C0Fqu05O.mjs";
3
- import { O as intro, P as outro, j as log } from "./dist-CTBk70IR.mjs";
4
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
5
- import { a as dim, c as import_picocolors, d as tablePrefix, r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { n as readDeploymentPlatform } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken, s as getSiteDomain } from "./auth-7wuZ5ob8.mjs";
3
+ import { H as outro, L as log } from "./prompts-6OSVA7DJ.mjs";
4
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
5
+ import { c as import_picocolors, d as tablePrefix, i as dim, o as formatCount } from "./output-BBsUwdyT.mjs";
6
6
  //#region src/cli/projects.ts
7
7
  async function runProjectsCommand(root) {
8
8
  console.log();
9
- intro(cliTitle("project list"));
10
9
  const token = getToken(root);
11
10
  if (!token) {
12
11
  log.error("Not logged in. Run `void account login` first.");
@@ -19,7 +18,7 @@ async function runProjectsCommand(root) {
19
18
  }
20
19
  const rows = projects.map((p) => ({
21
20
  slug: p.slug,
22
- role: p.role ?? "owner",
21
+ role: p.role,
23
22
  appType: p.type ?? "worker",
24
23
  url: p.custom_domain ? `https://${p.custom_domain}` : p.url ?? `https://${p.slug}.${getSiteDomain(root)}`
25
24
  }));
@@ -32,84 +31,84 @@ async function runProjectsCommand(root) {
32
31
  console.log(prefix);
33
32
  console.log(header);
34
33
  for (const line of lines) console.log(line);
35
- outro(`${projects.length} project(s)`);
34
+ outro(formatCount(projects.length, "project"));
36
35
  }
37
36
  //#endregion
38
37
  //#region src/cli/project-cmd.ts
39
38
  async function runProjectCommand(root, args) {
40
39
  const cloudflare = readDeploymentPlatform(root) === "cloudflare";
41
40
  if (args.subcommand === "status") {
42
- const { runListCommand } = await import("./list-CZj0dzKY.mjs");
41
+ const { runListCommand } = await import("./list-eEWVJEPn.mjs");
43
42
  return runListCommand(root, args.name || void 0);
44
43
  }
45
44
  if (args.subcommand === "link") {
46
45
  if (cloudflare) throw new Error("project: Direct Cloudflare apps are identified by cloudflare.name in void.config.ts and do not need linking.");
47
- const { runLink } = await import("./link-CDqqCjFl.mjs");
46
+ const { runLink } = await import("./link-CXOlqh2F.mjs");
48
47
  return runLink(root, args.name || void 0);
49
48
  }
50
49
  if (args.subcommand === "list") {
51
50
  if (cloudflare) {
52
- const { runListCommand } = await import("./list-CZj0dzKY.mjs");
51
+ const { runListCommand } = await import("./list-eEWVJEPn.mjs");
53
52
  return runListCommand(root);
54
53
  }
55
54
  return runProjectsCommand(root);
56
55
  }
57
56
  if (args.subcommand === "token") {
58
57
  if (cloudflare) throw new Error("project: CI deploy credentials are available only for Void platform projects.");
59
- const { runProjectTokenCommand } = await import("./project-token-CTDYU0Cc.mjs");
58
+ const { runProjectTokenCommand } = await import("./project-token-CP01Jna6.mjs");
60
59
  return runProjectTokenCommand(root, args);
61
60
  }
62
61
  if (args.subcommand === "team") {
63
62
  if (args.action === "") {
64
- const { printHelpPage } = await import("./help-DofyZuY7.mjs");
63
+ const { printHelpPage } = await import("./help-DPGBwomV.mjs");
65
64
  printHelpPage(["project", "team"]);
66
65
  return;
67
66
  }
68
67
  const accountInvitationAction = args.action === "pending" || args.action === "accept" || args.action === "decline";
69
68
  if (cloudflare && !accountInvitationAction) throw new Error("project: Teams are available only for projects hosted on a Void platform, not direct Cloudflare deployments.");
70
- const { runProjectTeamCommand } = await import("./project-team-DQOWPfQT.mjs");
69
+ const { runProjectTeamCommand } = await import("./project-team-ohAWWaew.mjs");
71
70
  return runProjectTeamCommand(root, args);
72
71
  }
73
72
  if (args.subcommand === "zero-trust") {
74
73
  if (cloudflare) throw new Error("project: Zero Trust overrides are available only for projects hosted on a Void platform.");
75
74
  if (args.action === "") {
76
- const { printHelpPage } = await import("./help-DofyZuY7.mjs");
75
+ const { printHelpPage } = await import("./help-DPGBwomV.mjs");
77
76
  printHelpPage(["project", "zero-trust"]);
78
77
  return;
79
78
  }
80
79
  const action = args.action;
81
- const { runProjectZeroTrustCommand } = await import("./project-zero-trust-BNAkW-_0.mjs");
80
+ const { runProjectZeroTrustCommand } = await import("./project-zero-trust-BzkVgx35.mjs");
82
81
  return runProjectZeroTrustCommand(root, {
83
82
  ...args,
84
83
  action
85
84
  });
86
85
  }
87
86
  if (args.subcommand === "logs") {
88
- const { runLogsCommand } = await import("./logs-CUZ6t9t3.mjs");
87
+ const { runLogsCommand } = await import("./logs-DnxVX7TR.mjs");
89
88
  return runLogsCommand(root, args.filter, args.range, args.deployment || void 0, args.level || void 0);
90
89
  }
91
90
  if (args.subcommand === "requests") {
92
91
  if (cloudflare) throw new Error("project: Historical request analytics require the Void platform. Use `void project logs` for a live Cloudflare tail.");
93
- const { runRequestsCommand } = await import("./requests-MhxYnau8.mjs");
92
+ const { runRequestsCommand } = await import("./requests-B3PBuGlX.mjs");
94
93
  return runRequestsCommand(root, args.range, args.status || void 0);
95
94
  }
96
95
  if (args.subcommand === "rollback") {
97
- const { runRollbackCommand } = await import("./rollback-CJ6iSDoU.mjs");
96
+ const { runRollbackCommand } = await import("./rollback-DDub9GsO.mjs");
98
97
  return runRollbackCommand(root, args.deployId || void 0);
99
98
  }
100
99
  if (args.subcommand === "cancel") {
101
100
  if (cloudflare) throw new Error("project: Direct Cloudflare deploys activate only after readiness succeeds, so there is no remote build to cancel.");
102
- const { runCancelDeployCommand } = await import("./cancel-deploy-abUxpP2n.mjs");
101
+ const { runCancelDeployCommand } = await import("./cancel-deploy-CYoZmcmR.mjs");
103
102
  return runCancelDeployCommand(root, args.deployId || void 0);
104
103
  }
105
104
  if (args.subcommand === "delete") {
106
105
  if (cloudflare) throw new Error("project: Refusing to delete Cloudflare resources through this command. Direct deployments are additive and existing resources may be shared.");
107
- const { runDeleteCommand } = await import("./delete-NvbiyeJf.mjs");
106
+ const { runDeleteCommand } = await import("./delete-pKMVsrpJ.mjs");
108
107
  return runDeleteCommand(root, args.name || void 0, { force: args.force });
109
108
  }
110
109
  if (args.subcommand === "purge-cache") {
111
110
  if (cloudflare) throw new Error("project: Direct Cloudflare ISR cache purge is not available yet; redeploy or purge the configured KV namespace explicitly.");
112
- const { runPurgeCacheCommand } = await import("./cache-C4MvnrMH.mjs");
111
+ const { runPurgeCacheCommand } = await import("./cache-TcZnBLtH.mjs");
113
112
  return runPurgeCacheCommand(root, args.projectSlug || void 0);
114
113
  }
115
114
  }
@@ -1,8 +1,8 @@
1
- import { c as getToken, i as getAccountCredential } from "./auth-CSkdO2Bb.mjs";
2
- import { o as readProjectConfig } from "./project-C0Fqu05O.mjs";
3
- import { N as note, O as intro, P as outro, j as log } from "./dist-CTBk70IR.mjs";
4
- import { n as PlatformClient, o as parsePlatformErrorBody, s as platformErrorMessage, t as PlatformApiError } from "./client-RV8NVeB8.mjs";
5
- import { r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken, i as getAccountCredential } from "./auth-7wuZ5ob8.mjs";
3
+ import { B as note, H as outro, L as log } from "./prompts-6OSVA7DJ.mjs";
4
+ import { c as platformErrorMessage, n as PlatformApiError, r as PlatformClient, s as parsePlatformErrorBody } from "./client-RsPo8wsP.mjs";
5
+ import { o as formatCount } from "./output-BBsUwdyT.mjs";
6
6
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-BG5ORGID.mjs";
7
7
  //#region src/cli/project-team.ts
8
8
  function clean(value) {
@@ -56,7 +56,6 @@ function invitationResponseError(error, apiUrl) {
56
56
  }
57
57
  async function runProjectTeamCommand(root, args) {
58
58
  console.log();
59
- intro(cliTitle(`project team ${args.action}`));
60
59
  const { apiUrl, token } = args.action === "pending" || args.action === "accept" || args.action === "decline" ? getAccountCredential() : {
61
60
  apiUrl: void 0,
62
61
  token: getToken(root)
@@ -74,7 +73,7 @@ async function runProjectTeamCommand(root, args) {
74
73
  return;
75
74
  }
76
75
  note(invitationLines(invitations, true), "Pending Project Invitations");
77
- outro(`${invitations.length} invitation(s)`);
76
+ outro(formatCount(invitations.length, "invitation"));
78
77
  return;
79
78
  }
80
79
  if (args.action === "accept" || args.action === "decline") {
@@ -91,7 +90,7 @@ async function runProjectTeamCommand(root, args) {
91
90
  if (args.action === "list") {
92
91
  const members = await client.listProjectMembers(projectId);
93
92
  note(memberLines(members), "Project Team");
94
- outro(`${members.length} member(s)`);
93
+ outro(formatCount(members.length, "member"));
95
94
  return;
96
95
  }
97
96
  if (args.action === "invitations") {
@@ -101,7 +100,7 @@ async function runProjectTeamCommand(root, args) {
101
100
  return;
102
101
  }
103
102
  note(invitationLines(invitations, false), "Project Invitations");
104
- outro(`${invitations.length} invitation(s)`);
103
+ outro(formatCount(invitations.length, "invitation"));
105
104
  return;
106
105
  }
107
106
  if (args.action === "invite") {
@@ -1,8 +1,8 @@
1
- import { c as getToken } from "./auth-CSkdO2Bb.mjs";
2
- import { o as readProjectConfig } from "./project-C0Fqu05O.mjs";
3
- import { O as intro, P as outro, j as log } from "./dist-CTBk70IR.mjs";
4
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
5
- import { a as dim, d as tablePrefix, r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { H as outro, L as log } from "./prompts-6OSVA7DJ.mjs";
4
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
5
+ import { d as tablePrefix, i as dim } from "./output-BBsUwdyT.mjs";
6
6
  import { r as resolveProjectBySlug } from "./resolve-project-BG5ORGID.mjs";
7
7
  //#region src/cli/project-token.ts
8
8
  async function resolveTarget(root, args) {
@@ -39,10 +39,7 @@ function printIssued(args, result, apiUrl) {
39
39
  console.log(`\nVOID_TOKEN=${result.token}\nVOID_API_URL=${apiUrl}\n`);
40
40
  }
41
41
  async function runProjectTokenCommand(root, args) {
42
- if (!args.json) {
43
- console.log();
44
- intro(cliTitle(`project token ${args.action}`));
45
- }
42
+ if (!args.json) console.log();
46
43
  const { client, projectId, slug } = await resolveTarget(root, args);
47
44
  if (args.action === "create") printIssued(args, await client.createProjectToken(projectId, {
48
45
  ...args.name ? { name: args.name } : {},
@@ -1,8 +1,8 @@
1
- import { c as getToken } from "./auth-CSkdO2Bb.mjs";
2
- import { o as readProjectConfig } from "./project-C0Fqu05O.mjs";
3
- import { N as note, O as intro, P as outro, j as log } from "./dist-CTBk70IR.mjs";
4
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
5
- import { l as sanitizeTerminalText, r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { B as note, H as outro, L as log } from "./prompts-6OSVA7DJ.mjs";
4
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
5
+ import { l as sanitizeTerminalText } from "./output-BBsUwdyT.mjs";
6
6
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-BG5ORGID.mjs";
7
7
  //#region src/cli/project-zero-trust.ts
8
8
  async function resolveTarget(root, args) {
@@ -44,7 +44,6 @@ function statusLines(result) {
44
44
  }
45
45
  async function runProjectZeroTrustCommand(root, args) {
46
46
  console.log();
47
- intro(cliTitle(`project zero-trust ${args.action}`));
48
47
  const { client, projectId, slug } = await resolveTarget(root, args);
49
48
  if (args.action === "status") {
50
49
  note(statusLines(await client.getProjectZeroTrust(projectId)), slug);