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
@@ -4,158 +4,114 @@ outline: deep
4
4
 
5
5
  # Deployment
6
6
 
7
- `void deploy` builds your app, provisions its resources, applies migrations, and deploys it to your own Cloudflare account or a Void platform run by your team.
7
+ `void deploy` builds your app, provisions resources, applies migrations, and deploys it. Choose your own Cloudflare account or a Void platform run by your team.
8
8
 
9
- You can [install a Void platform](./self-hosted-platform.md) for shared team deployments.
9
+ After a successful deployment, Void prints your deployment URL in a summary box with the details reported by your deployment target.
10
10
 
11
- ## Deployment Targets
11
+ ## Deploy to Cloudflare
12
12
 
13
- Both targets use the same application APIs. Their deployment features differ:
13
+ Choose Cloudflare during `void init`, or connect later:
14
14
 
15
- | Feature | Direct Cloudflare | Core self-hosted platform |
16
- | ------------------------------------------------ | -------------------------------- | --------------------------------------------- |
17
- | Static sites, SPAs, and native Pages SSR | Supported | Supported |
18
- | Routing rules, WebSockets, queues, cron, and ISR | Supported | Supported |
19
- | D1, KV, R2, and external SQL through Hyperdrive | Supported | Supported |
20
- | Workers AI and provider requests | Your account and gateway | Installation gateway and proxy |
21
- | Runtime logs | Live Cloudflare tail | Retained platform logs |
22
- | Application rollback | Worker versions | Retained platform deployments |
23
- | Typed Durable State | Supported | Unavailable |
24
- | Sandboxes | Requires Workers Paid and Docker | Requires Workers Paid on the platform account |
25
- | Custom application domains | Supported | Unavailable in the core installation |
26
- | Generated GitHub deployment workflow | Supported | Use your CI with a scoped developer token |
27
- | User dashboard and managed GitHub builds | Not required | Not included in a standard installation |
28
-
29
- Native apps can run on Workers Free within its quotas. A team platform requires Workers for Platforms and the [documented infrastructure](./platform/installation/domains.md#cloudflare-footprint). Rollback does not reverse database migrations.
30
-
31
- Native Void apps and static sites use Void routing rules. Framework deployments use their framework's routing and asset policies; direct deploy rejects unsupported Void rules.
32
-
33
- Use matching CLI and framework adapter versions. For a team platform, the available features depend on its installed version and configuration. Ask your administrator if a feature is unavailable or an upgrade is required.
34
-
35
- ## CLI
36
-
37
- ### First deploy
38
-
39
- ```bash
40
- void init # choose Cloudflare (default), Void, or Skip deployment setup
41
- void deploy # builds and deploys to the saved platform
15
+ ```sh
16
+ void connect --platform cloudflare
17
+ void deploy --platform cloudflare
42
18
  ```
43
19
 
44
- During setup, Void asks where you want to deploy:
45
-
46
- - **Cloudflare:** sign in through your browser and choose an account. Void saves the account in `void.config.ts` or `void.lock.json`.
47
- - **Void:** connect to a platform, sign in, and link or create a project.
48
- - **Skip:** set up deployment later with `void connect`.
49
-
50
- Your choice is saved in `.void/project.json`, so the next deploy is just `void deploy`.
20
+ Void opens your browser to sign in and asks which account to use. Later deploys use the saved target, so you can run `void deploy`.
51
21
 
52
- Already have a Cloudflare Worker and a root `wrangler.jsonc` or `wrangler.json`? Run `void deploy`. If no destination is selected, Void offers to link and deploy using the existing Worker and resources. Accept once to keep deploying to that site. See [Deploy an existing Worker](../integrations/cloudflare.md#deploy-an-existing-worker) for the first-deployment checks.
22
+ Native apps work on Workers Free within its quotas. [Sandboxes](./sandboxes.md#requirements) require Workers Paid and Containers access. See the [Cloudflare guide](../integrations/cloudflare.md) for configuration, token permissions, and features with additional requirements.
53
23
 
54
- To set up deployment later, use `void connect --platform cloudflare` or `void connect <platform-url>`.
24
+ If you already have a Worker and a root `wrangler.jsonc` or `wrangler.json`, `void deploy` can link it and preserve its resources. See [Deploy an existing Worker](../integrations/cloudflare.md#deploy-an-existing-worker).
55
25
 
56
- Owners can [share a platform project](./project-collaboration.md) with readers, collaborators, and project administrators. This does not apply to direct Cloudflare deployments.
26
+ ## Prepare your app
57
27
 
58
28
  ### Migrations
59
29
 
60
- Deploy applies pending SQL migrations from `db/migrations/`. If your schema has changes without a migration, deploy stops. Run `void db generate`, review and commit the SQL, then deploy again. See the [Database guide](./database.md).
30
+ Deploy applies pending SQL migrations from `db/migrations/`. If your schema has changes without a migration, deploy stops:
61
31
 
62
- ### Flags
63
-
64
- ```bash
65
- void deploy [--platform <cloudflare|void>] [--project <name>] [--dir <path>] [--spa]
32
+ ```sh
33
+ void db generate
66
34
  ```
67
35
 
68
- | Flag | Purpose |
69
- | ------------------------------- | ------------------------------------------------- |
70
- | `--platform <cloudflare\|void>` | Override the saved deployment platform |
71
- | `--project <name>` | Target a specific Void project by slug |
72
- | `--dir <path>` | Deploy a pre-built static directory (skips build) |
73
- | `--spa` | Use SPA mode instead of SSG for static deploys |
74
-
75
- ### Project resolution
36
+ Review and commit the SQL, then deploy again. Rollback does not reverse database migrations. See [Database](./database.md) for the local workflow.
76
37
 
77
- For a Void platform deploy, the CLI chooses the project in this order:
38
+ ### Environment variables
78
39
 
79
- 1. `--project <name>` flag
80
- 2. `VOID_PROJECT` environment variable
81
- 3. Linked project in `.void/project.json`
40
+ Declare values in `env.ts` and set production server secrets with `void secret put`. Deploy never uploads your local `.env`. Supply public `VITE_*` values through the build environment. See [Environment Variables](./env-vars.md).
82
41
 
83
- If none is set, Void asks you to choose a project. Direct Cloudflare deploys use the Worker and account saved in your Cloudflare config.
42
+ Keep the CLI and framework adapters on matching versions, and commit `void.config.ts` and `void.lock.json` when generated.
84
43
 
85
- ### CI preparation
44
+ ## Deploy from GitHub {#github}
86
45
 
87
- If your CI pipeline runs typechecking or other static analysis before deploy, run `void prepare` after install to generate the `.void/` artifacts without booting Vite.
46
+ Generate a workflow for your saved target and package manager:
88
47
 
89
- ### Environment variables
48
+ ```sh
49
+ void init --github
50
+ ```
90
51
 
91
- | Variable | Purpose |
92
- | -------------- | -------------------------------- |
93
- | `VOID_TOKEN` | Auth token (for CI, skips OAuth) |
94
- | `VOID_PROJECT` | Project slug override |
52
+ For Cloudflare, add `CLOUDFLARE_API_TOKEN` to your repository secrets. The token needs access to the account and products your app uses. PostgreSQL and MySQL apps also need `DATABASE_URL`.
95
53
 
96
- ## GitHub
54
+ Follow the [Cloudflare CI setup](../integrations/cloudflare.md#deploying-from-ci) for Worker preview URLs and Cloudflare Access credentials.
97
55
 
98
- You can deploy from a GitHub repo on every push to `main`. Running `void init --github` generates `.github/workflows/void-deploy.yml` for the platform saved in `.void/project.json`.
56
+ ### Team platform CI
99
57
 
100
- For Cloudflare, add `CLOUDFLARE_API_TOKEN` to your repository secrets. The token needs access to the account and products your app uses. PostgreSQL and MySQL apps also need a `DATABASE_URL` secret.
58
+ For a core self-hosted platform, use your own workflow with a [project deploy token](./platform/installation/first-deployment.md). Set `VOID_TOKEN`, `VOID_API_URL`, and the project slug, then connect in each fresh CI environment:
101
59
 
102
- If your Worker has no version preview URL, set the `CLOUDFLARE_WORKERS_SUBDOMAIN` repository variable. If Cloudflare Access protects the Worker, also add `CF_ACCESS_CLIENT_ID` and `CF_ACCESS_CLIENT_SECRET` secrets so Void can check that a deployment is ready. See [Cloudflare deployment](../integrations/cloudflare.md#deploy-to-your-own-cloudflare-account) for the setup details.
60
+ ```sh
61
+ void connect "$VOID_API_URL" --no-login
62
+ void deploy --platform void --project "$VOID_PROJECT"
63
+ ```
103
64
 
104
- Void platforms with GitHub Actions support use short-lived GitHub OIDC credentials. You don't need to store a `VOID_TOKEN` for that workflow.
65
+ Platforms with the optional GitHub Actions integration use short-lived OIDC credentials. Authorize the repository with `void github connect <project> --repo <owner/repo> --executor github_actions`, set the repository's `VOID_API_URL`, and keep `permissions: id-token: write` in the generated workflow.
105
66
 
106
- ### Void GitHub App
67
+ If your platform supports managed GitHub builds, the GitHub App can deploy on push without a workflow file. See [GitHub commands](../reference/cli/github.md#github) to install the App and connect your repository.
107
68
 
108
- If your platform supports managed GitHub builds, the Void GitHub App can build and deploy your app when you push. This feature requires a platform with a configured GitHub App and build Containers; it isn't included in a core self-hosted installation.
69
+ If CI runs typechecking before deploy, run `void prepare` after installing dependencies to generate the `.void/` types.
109
70
 
110
- You don't need a deployment workflow file or a repository `VOID_TOKEN` for this path.
71
+ ## Deploy to a team platform
111
72
 
112
- With a linked project, connect the repository:
73
+ Use the API URL from your administrator. In a new or unlinked app:
113
74
 
114
75
  ```sh
115
- void github install
116
- void github connect --executor container
117
- void github status
76
+ void connect https://platform.example.com
77
+ void deploy --platform void --project my-app
118
78
  ```
119
79
 
120
- If your organization already installed the App, Void can join that installation during setup. Organization repositories require browser authorization.
80
+ Sign in and confirm project creation when asked. To use an existing project, run `void project link`. Later deploys use the saved destination.
121
81
 
122
- Push to the configured branch to deploy, then follow progress with `void build logs --follow`. See [GitHub commands](../reference/cli/github.md#github) for installation sharing and connection options.
82
+ Project owners can [share access](./project-collaboration.md). To install a platform for your team, start with [Install a Void Platform](./self-hosted-platform.md), which also compares the deployment features of both targets.
123
83
 
124
- ### GitHub Actions
84
+ ### Deploy to another Void platform
125
85
 
126
- Run `void init --github` to generate the workflow for your saved platform and package manager. On Void platforms with GitHub Actions support, authorize the repository once:
86
+ For a single deployment to a different platform, connect and name its project:
127
87
 
128
88
  ```sh
129
- void github connect <project> --repo <owner/repo> --executor github_actions
89
+ void connect https://second.example.com
90
+ VOID_API_URL=https://second.example.com void deploy --platform void --project my-app
130
91
  ```
131
92
 
132
- Set the repository's `VOID_API_URL` variable to your platform's API URL. Keep `permissions: id-token: write` in the workflow for [GitHub OIDC](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). The workflow uses your linked project, or the `VOID_PROJECT` repository variable.
93
+ This keeps your saved destination. Each platform has its own projects, secrets, and data. See the [CLI reference](../reference/cli/deploy.md) for target selection and other flags.
133
94
 
134
- Core self-hosted installations do not support this integration. Use your own CI workflow with a [project deploy token](./platform/installation/first-deployment.md).
95
+ ## Logs and rollback
135
96
 
136
- ## Other Targets
97
+ Inspect your deployment, read runtime logs, or select a previous deployment:
137
98
 
138
- ### Your own Cloudflare account
139
-
140
- Select Cloudflare during setup, or run `void deploy --platform cloudflare`. See the [Cloudflare guide](../integrations/cloudflare.md) for configuration, CI credentials, and deployment limits.
141
-
142
- ### Node.js, Bun, and Deno
99
+ ```sh
100
+ void project status
101
+ void project logs
102
+ void project rollback
103
+ ```
143
104
 
144
- Set [`target`](../reference/config.md#target) in `void.config.ts` to build a standalone server for Node.js, Bun, or Deno. You can run the result on your own server or in a container.
105
+ Cloudflare logs use a live tail; team platforms retain log history. Before rolling back, check that the earlier code works with your current database schema. See [Project commands](../reference/cli/project.md).
145
106
 
146
- Deploy `dist/ssr` and `dist/client` together. See the target guide for startup commands.
107
+ ## Other runtimes
147
108
 
148
- These targets don't provide Cloudflare bindings such as D1, KV, R2, and Workers AI. See the [Node.js, Bun, and Deno guide](../integrations/nodejs-bun-deno.md) for the features available on each target.
109
+ Build a standalone server for [Node.js, Bun, or Deno](../integrations/nodejs-bun-deno.md) using the `target` setting. Deploy `dist/ssr` and `dist/client` together using your own hosting. Cloudflare bindings such as D1, KV, R2, and Workers AI are unavailable on these targets.
149
110
 
150
111
  ## Usage and execution limit pages
151
112
 
152
- Void platforms show a built-in page when an app exhausts its request allowance or an invocation exceeds its CPU limit. API requests and Pages action requests receive a structured HTTP 429 with `code: 'usage_limit'`, `resource`, `reason`, and `message`.
153
-
154
- To customize browser error pages, add either optional file to your app's public assets:
155
-
156
- - `public/usage-limit.html` for exhausted request allowances.
157
- - `public/execution-limit.html` for execution limits.
113
+ Team platforms return a structured HTTP 429 to API and Pages action requests when an app exceeds its request or CPU allowance. Browser requests get an error page.
158
114
 
159
- Use standalone HTML with inline CSS and data-URL images. These pages run with scripts, external assets and form submissions disabled, so they remain usable while application requests are blocked. Void serves them directly from the deployed assets; your Worker, loaders and database are not involved. A missing or unreadable custom page uses the built-in page.
115
+ To customize it, add `public/usage-limit.html` for request limits or `public/execution-limit.html` for execution limits. Use standalone HTML with inline CSS and data-URL images. Scripts, external assets, and form submissions are disabled. Missing custom pages use the built-in page.
160
116
 
161
- Responses are not cached. Once a streaming response has started, it cannot be replaced with an error page; clients should display stream failures and end their pending state. These platform pages apply to Void platform deployments. Direct Cloudflare runtime limits use Cloudflare's own response behavior.
117
+ Responses are not cached. A streaming response that has already started cannot be replaced with an error page; handle stream failures in your UI.
@@ -35,7 +35,7 @@ Header rules do not apply to ISR cache responses.
35
35
 
36
36
  ### Blocked headers
37
37
 
38
- `Set-Cookie` and `Clear-Site-Data` are ignored in header rules. On a shared domain such as `*.void.app`, a rule could otherwise affect cookies or data belonging to another project's subdomain.
38
+ `Set-Cookie` and `Clear-Site-Data` are ignored in header rules. On a shared domain such as `*.apps.example.com`, a rule could otherwise affect cookies or data belonging to another project's subdomain.
39
39
 
40
40
  ## Framework `_headers` files
41
41
 
@@ -50,7 +50,9 @@ Use a mail subdomain to keep existing mail on `acme.com` with its current provid
50
50
 
51
51
  Sign in with `void cloudflare login`, or use a `CLOUDFLARE_API_TOKEN` with **Email Routing Edit** and **Email Sending Edit** in addition to deploy permissions. If your browser session lacks email permissions, log out and sign in again. Global API Keys aren't supported.
52
52
 
53
- Run `void deploy --platform cloudflare`. Void shows the domain, routing, sending, DNS, and handler addresses it would configure. Accept to set up email and deploy. Later deploys reuse the setup. Without `email.from`, or if you decline the initial setup, the app deploys without email.
53
+ Run `void deploy --platform cloudflare`. Void shows the domain, routing, sending, DNS, and handler addresses it would configure. Accept to set up email and deploy. Later deploys reuse the setup. If you decline the initial setup, the app deploys without email.
54
+
55
+ Without `email.from`, Void skips automatic setup and preserves authored `cloudflare.send_email` bindings and `cloudflare.addresses`; check their readiness yourself. `--require-email` still refuses deployment when automatic setup cannot be verified.
54
56
 
55
57
  If subdomain setup needs a dashboard step, follow the checklist under **Email → Settings → Subdomains**, then retry. After DNS changes, check readiness with:
56
58
 
@@ -78,6 +80,8 @@ Setup enables the zone's plus addressing so `support+T-42@mail.acme.com` reaches
78
80
 
79
81
  On Workers Free, `sendEmail()` can send to verified destinations listed under **Email Routing → Destination addresses** in Cloudflare.
80
82
 
83
+ Configure your sender domain's SPF, DKIM, and DMARC records using [Cloudflare's email authentication guidance](https://developers.cloudflare.com/email-service/concepts/email-authentication/), then check the authentication results in a received message's original headers. A successful `sendEmail()` result confirms provider acceptance; it does not confirm delivery or authentication readiness.
84
+
81
85
  Sending to arbitrary recipients requires [Workers Paid](https://dash.cloudflare.com/?to=/:account/workers/plans) and Email Sending onboarding. After upgrading, run `void email setup --platform cloudflare`. Void doesn't retry onboarding during ordinary deploys.
82
86
 
83
87
  Existing DMARC or bounce-domain records can block onboarding; the checklist identifies conflicts to resolve. Inbound mail remains available.
@@ -34,7 +34,7 @@ Check both failure shapes: `result.error` reports a request failure, while `resu
34
34
 
35
35
  ## Setup {#setup}
36
36
 
37
- On a platform with email enabled, deploy without additional email configuration. Ask your administrator for its shared mail domain. Administrators [enable email during installation or upgrade](/guide/platform/installation/credentials#runtime-token-permissions); Void Cloud uses `mail.void.cloud`.
37
+ On a platform with email enabled, deploy without additional email configuration. Ask your administrator for its shared mail domain. Administrators [enable email during installation or upgrade](/guide/platform/installation/credentials#runtime-token-permissions).
38
38
 
39
39
  Each project on an email-enabled platform has:
40
40
 
@@ -39,7 +39,7 @@ STRIPE_KEY=sk_test_example
39
39
  VITE_API_ORIGIN=http://localhost:5173
40
40
  ```
41
41
 
42
- Keep `.env` out of Git. Other dotenv files, including `.env.local`, `.env.production`, `.env.example`, and Wrangler’s `.dev.vars*`, are not supported. See [Environment migration](./env-migration.md) if your app uses them.
42
+ Keep `.env` out of Git. Other dotenv files, including `.env.local`, `.env.production`, `.env.example`, and Wrangler’s `.dev.vars*`, are not supported.
43
43
 
44
44
  Run the local check at any time:
45
45
 
@@ -105,7 +105,3 @@ Invalid-value diagnostics redact the supplied value by default. Set `VOID_ENV_UN
105
105
  ## Imports inside `env.ts`
106
106
 
107
107
  Use relative imports or package names inside `env.ts`. TypeScript path aliases and imports that need Vite transforms are not supported.
108
-
109
- ## Migrating from the multi-file model
110
-
111
- See [Environment migration](/guide/env-migration) for the breaking-change checklist.
@@ -4,34 +4,35 @@ outline: deep
4
4
 
5
5
  # What is Void?
6
6
 
7
- Void adds server routes, typed data access, and deployment to Vite apps. Native Void apps run on Cloudflare Workers. You can also use Void with a [supported framework](../integrations/frameworks/overview).
7
+ Void is a full-stack framework for Cloudflare Workers, powered by Vite. Build your UI with React, Vue, Svelte, or Solid, and write server code in the same project. Void connects routing, data access, and deployment while keeping types shared across your app.
8
8
 
9
- Start with the [Quickstart](./quickstart) to create an app, run it locally, and deploy it.
9
+ Start with the [Quickstart](./quickstart.md) to create and deploy an app. If you already use a meta framework, follow its [integration guide](../integrations/frameworks/overview.md).
10
10
 
11
- The CLI and build tools require Node.js 24.21.0 or later.
11
+ ## Server routes and pages
12
12
 
13
- ## Resources from your code
13
+ Files define routes. A handler in `routes/api/users.ts` serves `/api/users`; a component in `pages/users/index.tsx` renders `/users`.
14
+
15
+ Each page can have a companion `.server.ts` file. Its **loader** reads data and returns typed props to the component. Its **actions** handle forms and other mutations, then update the page. Server code stays on the server; components render there initially and run in the browser for navigation and interaction.
14
16
 
15
- Import `db` from `void/db`, and Void provides a local database and provisions one for deployment. The same pattern applies to KV, object storage, queues, and AI. Configure resources explicitly when you need to use existing infrastructure.
17
+ Use [Pages routing](./pages-routing/overview.md) for a full-stack UI, or keep your own client-side router and call [server routes](./server-routing.md) with [typed fetch](./typed-fetch.md). You can also build an API without a frontend.
18
+
19
+ ## Resources from your code
16
20
 
17
- Your Drizzle schema defines database types. Route handlers infer return types, and the [typed fetch client](./typed-fetch.md) checks calls from the frontend. Changing a field shows you which callers need to change.
21
+ Import `db` from `void/db` to query your database. Void provides a local database during development and provisions one when you deploy. Imports also enable resources such as [KV](./kv.md), [object storage](./storage.md), and [queues](./queues.md). Use configuration when you need to connect existing resources.
18
22
 
19
- Void connects these parts of your app:
23
+ Your Drizzle schema defines database types. Handlers infer response types, and typed fetch checks their callers. Page loaders and actions carry the same types into components and forms. Changing a field shows you which parts of the app need to change.
20
24
 
21
- - [Server routes](./server-routing.md) and [pages](./pages-routing/overview.md) for your app's backend and UI
22
- - [Database](./database.md), [KV](./kv.md), and [storage](./storage.md) that work locally and in production
23
- - [Standard Schema](https://standardschema.dev/) validation for runtime values and TypeScript types
24
- - `void deploy` to build, apply migrations, provision resources, and deploy
25
+ ## From local development to production
25
26
 
26
- ## Deployment targets
27
+ Vite runs your app locally with Cloudflare's runtime. `void deploy` builds it, provisions resources, applies database migrations, and publishes it. [Environment variables](./env-vars.md) use a schema, local values, and production secrets.
27
28
 
28
- Deploy to [your own Cloudflare account](../integrations/cloudflare.md#deploy-to-your-own-cloudflare-account) or to a [Void platform](./self-hosted-platform.md) run by your team. Both use the same SDK and CLI.
29
+ Deploy to [your own Cloudflare account](./deployment.md#deploy-to-cloudflare), or connect to a [Void platform](./self-hosted-platform.md) run by your team. Both use the same application APIs. A platform adds shared access, deployment history, and administration.
29
30
 
30
- [Static assets](./edge/static-assets) are cached at the edge. [Prerendering](./edge/prerendering) builds pages ahead of time, while [incremental revalidation](./edge/revalidation) caches pages rendered on demand. Database, storage, secrets, and deployment commands are available through Void.
31
+ Void also deploys [existing frameworks and static sites](./app-types.md). Your framework keeps its routing and rendering; Void handles resources and deployment.
31
32
 
32
33
  ## Next steps
33
34
 
34
- - [Quickstart](./quickstart): get a running app in minutes
35
- - [Server Routing](./server-routing): dynamic params, middleware, and validation
36
- - [Pages Routing](./pages-routing/overview): full-stack pages with server loaders and actions
37
- - [Supported App Types](./app-types): full-stack, meta-framework, and static site modes
35
+ - [Quickstart](./quickstart.md): create your first app
36
+ - [Pages Routing](./pages-routing/overview.md): loaders, layouts, and forms
37
+ - [Database](./database.md): schemas, queries, and migrations
38
+ - [Deployment](./deployment.md): Cloudflare, team platforms, and CI
@@ -27,8 +27,6 @@ await kv.put('user:123', { name: 'Alice', role: 'admin' });
27
27
 
28
28
  Values, including strings, are JSON-serialized. Reads preserve their types, so a string such as `"123"` or `"null"` comes back as a string.
29
29
 
30
- If an older Void version stored a JSON-looking string as raw text, rewrite that key with `kv.put(key, originalString)`. Existing stored values keep their previous read behavior; Void cannot distinguish an old raw string such as `"123"` from a stored number. Use the original string or read its raw text through `c.env.KV.get(key)` when rewriting it.
31
-
32
30
  Add a TTL (in seconds) or absolute expiration (Unix timestamp):
33
31
 
34
32
  ```ts
@@ -29,57 +29,12 @@ export const action = defineHandler.withValidator({
29
29
  | Nothing (void) | Re-runs the loader, page re-renders with fresh props. |
30
30
  | `c.redirect('/path')` | Navigates to another page. |
31
31
 
32
- ## Named Actions
33
-
34
- When a page needs multiple mutations, such as updating and deleting a user on the same page, export `actions` (plural) instead of `action`:
35
-
36
- ```ts
37
- // pages/users/[id].server.ts
38
- import { defineHandler } from 'void';
39
- import { db, eq } from 'void/db';
40
- import { users, updateUserSchema } from '@schema';
41
-
42
- export const actions = {
43
- update: defineHandler.withValidator({
44
- body: updateUserSchema,
45
- })(async (c, { body }) => {
46
- await db
47
- .update(users)
48
- .set(body)
49
- .where(eq(users.id, Number(c.req.param('id'))));
50
- }),
51
-
52
- delete: defineHandler(async (c) => {
53
- await db.delete(users).where(eq(users.id, Number(c.req.param('id'))));
54
- }),
55
- };
56
- ```
57
-
58
- Named actions are dispatched via a `?actionName` suffix on the URL (e.g. `/users/42?update`). The client primitives `useForm` and `action()` handle this automatically.
59
-
60
- Use `action` or `actions` in a file, not both.
61
-
62
- You can also define an `actions.default` key for the action that runs when no name is specified (i.e. a bare POST to the page URL):
63
-
64
- ```ts
65
- export const actions = {
66
- default: defineHandler(async (c) => {
67
- // runs on POST /users/edit (no ?suffix)
68
- }),
69
- delete: defineHandler(async (c) => {
70
- // runs on POST /users/edit?delete
71
- }),
72
- };
73
- ```
74
-
75
32
  ## Form
76
33
 
77
- Pair `Form` with `useForm` for automatic error presentation. It preserves controlled input on failure, announces validation and action errors, and displays the message from structured quota responses. Known retry deadlines prevent premature resubmission without locking the fields. It never retries a submission automatically.
34
+ Pair `Form` with `useForm` to submit values and display validation and action errors. Inputs stay editable when a submission fails.
78
35
 
79
36
  Import `Form` from your adapter. Pass `form` and, optionally, `method="put"`, `"patch"`, or `"delete"`; the default is `"post"`. Use `renderError` for a custom action-error renderer (a snippet in Svelte).
80
37
 
81
- On the server, use `limit.response({ message: 'AI is temporarily unavailable. Your draft is still editable.' })` in an AI or Sandbox operation's required `limited` handler. It supplies the status and structured metadata consumed by `Form`.
82
-
83
38
  ## `useForm`
84
39
 
85
40
  `useForm` handles submissions, loading state, and validation errors. URLs, form values, and error fields are typed from your action.
@@ -216,6 +171,49 @@ const form = useForm('/users/:id', { name: '' }, { params: { id: '42' } });
216
171
  <Form form={form} method="put">{/* submits to /users/42 */}</Form>
217
172
  ```
218
173
 
174
+ ## Named Actions
175
+
176
+ When a page needs multiple mutations, such as updating and deleting a user on the same page, export `actions` (plural) instead of `action`:
177
+
178
+ ```ts
179
+ // pages/users/[id].server.ts
180
+ import { defineHandler } from 'void';
181
+ import { db, eq } from 'void/db';
182
+ import { users, updateUserSchema } from '@schema';
183
+
184
+ export const actions = {
185
+ update: defineHandler.withValidator({
186
+ body: updateUserSchema,
187
+ })(async (c, { body }) => {
188
+ await db
189
+ .update(users)
190
+ .set(body)
191
+ .where(eq(users.id, Number(c.req.param('id'))));
192
+ }),
193
+
194
+ delete: defineHandler(async (c) => {
195
+ await db.delete(users).where(eq(users.id, Number(c.req.param('id'))));
196
+ }),
197
+ };
198
+ ```
199
+
200
+ Named actions are dispatched via a `?actionName` suffix on the URL (e.g. `/users/42?update`). The client primitives `useForm` and `action()` handle this automatically.
201
+
202
+ Use `action` or `actions` in a file, not both.
203
+
204
+ You can also define an `actions.default` key for the action that runs when no name is specified (i.e. a bare POST to the page URL):
205
+
206
+ ```ts
207
+ export const actions = {
208
+ default: defineHandler(async (c) => {
209
+ // runs on POST /users/edit (no ?suffix)
210
+ }),
211
+ delete: defineHandler(async (c) => {
212
+ // runs on POST /users/edit?delete
213
+ }),
214
+ };
215
+ ```
216
+
219
217
  ### Named Actions with `useForm`
220
218
 
221
219
  When a page exports named actions, append `?actionName` to the URL:
@@ -258,7 +256,7 @@ Authentication errors (`401`, `403`), server errors (`500`, `502`), and unexpect
258
256
  Actions can throw `ValidationError` for custom validation logic:
259
257
 
260
258
  ```ts
261
- import { defineHandler, ValidationError } from 'void';
259
+ import { defineHandler, ValidationError } from 'void/handler';
262
260
 
263
261
  export const action = defineHandler(async (c) => {
264
262
  const body = await c.req.json();
@@ -269,6 +267,10 @@ export const action = defineHandler(async (c) => {
269
267
  });
270
268
  ```
271
269
 
270
+ ### Usage limits
271
+
272
+ For [AI](../ai.md) and [Sandbox](../sandboxes.md) actions, return `limit.response({ message: 'Try again shortly. Your draft is still editable.' })` from the operation's `limited` handler. `Form` displays the message and waits until a known retry deadline before allowing resubmission. It keeps the fields editable and never retries automatically.
273
+
272
274
  ## Authentication and origin checks
273
275
 
274
276
  Browser submissions must come from the same origin as the page, including its scheme, hostname, and port. Void rejects cross-origin page actions with `403 Forbidden`. Server clients can call actions without browser origin headers; actions still need authentication and authorization for protected data.
@@ -225,9 +225,9 @@ export default function PostPage() {
225
225
 
226
226
  ## Scroll Restoration
227
227
 
228
- Client-side navigation manages scroll position automatically:
228
+ Void manages scroll position for Pages automatically:
229
229
 
230
- - **Back/forward navigation** restores the exact scroll position you were at before navigating away.
230
+ - **Back/forward navigation and reloads** restore the saved scroll position.
231
231
  - **New navigation** scrolls to the top of the page.
232
232
  - **Hash links** (`/docs#api`) scroll to the target element. Same-page hash links (`#section`) skip the server fetch entirely.
233
233
 
@@ -144,5 +144,3 @@ Run recovery with the same platform version that created the persisted intent.
144
144
  `applied` continues without replaying the write; `not-applied` permits that exact
145
145
  step to retry. Secret rotation keeps its staged generation, and removal resumes
146
146
  from the unresolved cleanup step. Age alone never authorizes a retry.
147
-
148
- Register administrator domains only after a platform upgrade has completed, and remove them before rolling the platform back to a version that predates this feature: an earlier runtime cannot use the platform credential for them and does not distinguish administrator-registered domains from owner-registered ones.
@@ -51,28 +51,6 @@ Following waits for the final logs before stopping, including diagnostics writte
51
51
 
52
52
  ## Checking the Platform
53
53
 
54
- ### Migrating older deployment assets
55
-
56
- After upgrading the platform, inspect every page of its asset inventory:
57
-
58
- ```sh
59
- void platform system asset-migrations --page 1 --limit 100
60
- void platform deployment migrate-assets <deployment-id> --plan
61
- void platform deployment migrate-assets <deployment-id> --yes
62
- ```
63
-
64
- Migrate every deployment with a nonzero `needsMigration` count, including retained
65
- rollback targets and stored Worker bundles. Investigate entries marked `invalid`
66
- before continuing. The command verifies each copied asset, preserves originals,
67
- and applies successive batches. If interrupted, inspect the result and resume
68
- with the last successful `nextCursor` using `--cursor`; restarting without a
69
- cursor also verifies and reuses completed copies.
70
-
71
- Run the inventory again across all pages when finished. Existing applications
72
- continue serving during this migration, and the provider asset mirror remains.
73
- Legacy reads remain available while older platform runtimes and cached manifests
74
- can still reference original assets.
75
-
76
54
  ### Health checks
77
55
 
78
56
  Use the overview to see recent activity, or run a health check to test the platform's services and database:
@@ -88,6 +66,17 @@ The dashboard’s **System Status** page refreshes health checks every 30 second
88
66
 
89
67
  Use `void platform upgrade`, `repair`, `disable`, and `enable` to maintain your platform. See [platform maintenance](/guide/platform/installation/maintenance#resume-repair-recover-and-upgrade).
90
68
 
69
+ Upgrades and rollbacks run through the CLI; watching their progress is optional.
70
+ During maintenance, navigating the admin UI automatically redirects to
71
+ `/admin/status`. You can also open that page directly on the API origin. It
72
+ refreshes automatically and shows saved progress and the API's traffic state
73
+ while the API and authentication database remain reachable. If a status refresh
74
+ fails, the last confirmed snapshot is marked as stale. Normal administrator
75
+ changes stay paused during maintenance.
76
+ If the CLI reports an error or a waiting state, follow its recovery instructions
77
+ to resume the operation. See
78
+ [Follow upgrade and rollback progress](/guide/platform/installation/maintenance#follow-upgrade-and-rollback-progress).
79
+
91
80
  For disaster recovery, keep a matching PostgreSQL backup, provider data backups, installation identity and complete project-encryption keyring, and immutable runtime artifacts. Keep traffic disabled while restoring data, run `discover` to reconstruct verified local metadata, and review `repair --plan` before recreating missing installer-owned infrastructure. Neither command restores backed-up data. See [Prepare for disaster recovery](/guide/platform/installation/maintenance#prepare-for-disaster-recovery) for the full sequence.
92
81
 
93
82
  ## Using Scripts
@@ -11,9 +11,7 @@ void platform auth login
11
11
  void platform config plans
12
12
  ```
13
13
 
14
- Choose a plan to inspect or edit it, copy one into a new plan, or choose the default for new accounts. Existing installations keep their plans, limits, and default until you change them. After upgrading the platform to support plan configuration, these changes require no app or platform redeploy.
15
-
16
- Inspection and previews are available immediately after a platform upgrade. Allow 15 minutes before applying changes.
14
+ Choose a plan to inspect or edit it, copy one into a new plan, or choose the default for new accounts. Changes require no app or platform redeploy.
17
15
 
18
16
  ## Use the Dashboard
19
17
 
@@ -90,8 +88,6 @@ Storage figures shown for D1, R2, and KV are informational and cannot be edited
90
88
 
91
89
  The preview shows the affected account count and checks a sample for accounts already above a proposed quota. Lowering a quota can restrict existing apps, including accounts outside that sample. Usage history and billing periods are preserved, so a plan change does not reset usage. Manual administrator suspensions remain in effect.
92
90
 
93
- After the initial platform upgrade, request quota accounting includes unlimited plans too. For an account that was unlimited before that upgrade, its quota counter may not include earlier requests in the current billing period. Historical analytics remain available. When introducing its first cap, allow for the remaining period or wait until its next billing period.
94
-
95
91
  ## Archive or Remove a Plan
96
92
 
97
93
  Archive a plan to stop assigning it to new accounts while preserving its current accounts: