void 0.21.1 → 0.21.3

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 (189) hide show
  1. package/README.md +3 -2
  2. package/dist/{auth-cmd-g_ymMkUe.mjs → account-cmd-DGt9cpRe.mjs} +10 -10
  3. package/dist/{agents-gni4eqBu.mjs → agents-B_pX_HmQ.mjs} +1 -1
  4. package/dist/ast-CPGPjb0V.mjs +18 -0
  5. package/dist/{auth-CAw7zHqj.mjs → auth-CZuiVsFh.mjs} +1 -1
  6. package/dist/{auth-B9_D6ygs.mjs → auth-DLNN0D3Z.mjs} +4 -4
  7. package/dist/{auth-link-DFvxIyZi.mjs → auth-link-Cl9vOuf7.mjs} +5 -5
  8. package/dist/auth-router-D4ZcMUSf.mjs +74 -0
  9. package/dist/{better-auth-shared-BoVwA5Vm.d.mts → better-auth-shared-BVkjZ3vM.d.mts} +1 -0
  10. package/dist/{better-auth-shared-syGYYmnY.mjs → better-auth-shared-rsBGBvWJ.mjs} +3 -6
  11. package/dist/{build-cmd-wJAv808h.mjs → build-cmd-Dpt0jd-x.mjs} +5 -5
  12. package/dist/{cache-Be0Fu5Ka.mjs → cache-7_UeZdTk.mjs} +5 -5
  13. package/dist/{cancel-deploy-BgmyOwhe.mjs → cancel-deploy-D23R1RXT.mjs} +4 -4
  14. package/dist/{cf-access-rAZxzMkL.mjs → cf-access-P0iZnu0q.mjs} +1 -1
  15. package/dist/{cf-build-output-CTdlo6Rt.mjs → cf-build-output-CGT03qCD.mjs} +2 -2
  16. package/dist/cli/cf-compat.mjs +2 -2
  17. package/dist/cli/cli.mjs +122 -66
  18. package/dist/cli/env-schema-probe.mjs +3 -3
  19. package/dist/client-4cDVv7BO.mjs +2 -0
  20. package/dist/{client-PdAJ-F0t.mjs → client-QTl6ko_D.mjs} +28 -5
  21. package/dist/{cloudflare-auth-BCmTc1X_.mjs → cloudflare-auth-B9jPCkV2.mjs} +1 -1
  22. package/dist/{cloudflare-cmd-D6PrKn7o.mjs → cloudflare-cmd-BjNxR1XF.mjs} +3 -3
  23. package/dist/{cloudflare-connect-DloREDlc.mjs → cloudflare-connect-CCUozPOe.mjs} +3 -3
  24. package/dist/{cloudflare-operations-BHNJVDbN.mjs → cloudflare-operations-BipGMJ5O.mjs} +1 -1
  25. package/dist/{cloudflare-operations-CPEdHYhM.mjs → cloudflare-operations-sMZXpk_S.mjs} +4 -4
  26. package/dist/collect-DLyFDiKW.mjs +2 -0
  27. package/dist/{collect-DXHNWHcT.mjs → collect-DiTn9yr6.mjs} +1 -1
  28. package/dist/config-0acf1oys.mjs +2 -0
  29. package/dist/{config-DywxBLQC.d.mts → config-CF69HgXc.d.mts} +7 -0
  30. package/dist/{config-Dxr6cTXn.mjs → config-CafTW6Cz.mjs} +12 -1
  31. package/dist/{config-BSe70f4T.mjs → config-D8MOgiQV.mjs} +3 -3
  32. package/dist/config-DPByhVck.mjs +32 -0
  33. package/dist/config-entry.d.mts +1 -1
  34. package/dist/{config--T87TD8T.mjs → config-s7Xj7tPb.mjs} +1 -1
  35. package/dist/{config-write-y3CBI_ux.mjs → config-write-BSduPMY8.mjs} +3 -3
  36. package/dist/{connect-LnvW4HKx.mjs → connect-4Ph5Y0QE.mjs} +8 -8
  37. package/dist/{create-project-JV9-6ICF.mjs → create-project-BniEV0OW.mjs} +1 -1
  38. package/dist/{create-project-BZBl_gQ0.mjs → create-project-DBfFSZKY.mjs} +4 -4
  39. package/dist/{db-Mzv88E1C.mjs → db-DzJRn-qz.mjs} +128 -60
  40. package/dist/{delete-Ri6JemSU.mjs → delete-D6dZ9B6B.mjs} +5 -5
  41. package/dist/deploy-BH0grP4y.mjs +2 -0
  42. package/dist/{deploy-DEsMVrCY.mjs → deploy-CsMJrPfM.mjs} +522 -262
  43. package/dist/discover-AMCBXivQ.mjs +2 -0
  44. package/dist/{discover-C4O6YxVS.mjs → discover-BcPPiF1o.mjs} +2 -2
  45. package/dist/{dist-4WkAWhWx.mjs → dist-BVqXeR_h.mjs} +9 -1
  46. package/dist/dist-_UUlL6bg.mjs +2 -0
  47. package/dist/{domain-BA37Ye7T.mjs → domain-Dmhvb2oU.mjs} +5 -5
  48. package/dist/{email-C5kaZXzJ.mjs → email--tEtMoj_.mjs} +1 -1
  49. package/dist/{email-C5NsxrQG.mjs → email-BRKOG2RG.mjs} +10 -10
  50. package/dist/{entry-DdRFGK0y.mjs → entry-CF5wvH4w.mjs} +4 -21
  51. package/dist/{env-U_ohASB0.mjs → env-Csi-tMbT.mjs} +8 -8
  52. package/dist/{env-Yz4HcvHs.mjs → env-D5liuQYR.mjs} +5 -2
  53. package/dist/{env-DX_v-Q-v.mjs → env-_v349JBd.mjs} +1 -1
  54. package/dist/{env-types-CWDtqHgw.mjs → env-types-C2_bIk_b.mjs} +2 -2
  55. package/dist/{env-validation-BsFEXps5.mjs → env-validation-BB4GkLxn.mjs} +4 -4
  56. package/dist/{env-validation-DIDGM7h4.mjs → env-validation-BXge7uyK.mjs} +1 -1
  57. package/dist/{gen-pg-Ojg8Y.mjs → gen-Dz3X1Qab.mjs} +8 -8
  58. package/dist/gen-Vnv2f65C.mjs +2 -0
  59. package/dist/{generate-C0VY6RVf.mjs → generate-GDbL7sUr.mjs} +2 -2
  60. package/dist/{github-cmd-DsrkweIl.mjs → github-cmd-BED3_9JD.mjs} +7 -7
  61. package/dist/{headers-B_HBMgi0.mjs → headers-BOg_velo.mjs} +2 -2
  62. package/dist/{help-sBhFH6pi.mjs → help-DC7gdz7L.mjs} +46 -11
  63. package/dist/help-DQMfeKMz.mjs +2 -0
  64. package/dist/index.mjs +134 -160
  65. package/dist/{init-C--Yyj1b.mjs → init-CRGDXzVC.mjs} +105 -289
  66. package/dist/{link-BC-mNG9-.mjs → link-CsHOinF7.mjs} +6 -6
  67. package/dist/{list-DHU1Wj6c.mjs → list-CDb-4bZ1.mjs} +6 -6
  68. package/dist/{local-d1-DzykTWY8.mjs → local-d1-CC8sKFGu.mjs} +3 -3
  69. package/dist/{login-jKe_0QZL.mjs → login-BQyISZuW.mjs} +4 -4
  70. package/dist/login-r2gL8l7B.mjs +2 -0
  71. package/dist/{logs-BG11f5PR.mjs → logs-BdfiOezj.mjs} +5 -5
  72. package/dist/{migrate-BV8qHiCb.mjs → migrate-B8KuoYsO.mjs} +69 -44
  73. package/dist/migrate-TsHGBnDA.mjs +2 -0
  74. package/dist/{node-Cupyf7-s.mjs → node-BM43oz4G.mjs} +5 -5
  75. package/dist/{operator-auth-BkVgJqv-.mjs → operator-auth-8KnOVXVd.mjs} +2 -2
  76. package/dist/{operator-client-A0iex2yi.mjs → operator-client-DUwumHpQ.mjs} +2 -2
  77. package/dist/{operator-cmd-BwAS2XZt.mjs → operator-cmd-Co-PeaeD.mjs} +6 -6
  78. package/dist/{package-json-iCbMg5XF.mjs → package-json-DXfiT1jV.mjs} +1 -1
  79. package/dist/pages/index.d.mts +1 -1
  80. package/dist/pages/index.mjs +11 -6
  81. package/dist/pages/islands-plugin.d.mts +271 -1
  82. package/dist/pages/islands-plugin.mjs +95 -18
  83. package/dist/parse-filename-DioPHiR9.mjs +77 -0
  84. package/dist/{platform-auth-config-C-hv-_Ok.mjs → platform-auth-config-TSw8edHw.mjs} +5 -5
  85. package/dist/{platform-auth-protection-DjTE5Hj-.mjs → platform-auth-protection-Ba1XqGhn.mjs} +6 -6
  86. package/dist/{platform-auth-recovery-Cr0r8TEb.mjs → platform-auth-recovery-BkT3EsF2.mjs} +5 -5
  87. package/dist/{platform-cmd-DE6dw45v.mjs → platform-cmd-C8OqhqPt.mjs} +1 -1
  88. package/dist/{platform-cmd-0tEh2ZtA.mjs → platform-cmd-CRSKfu8k.mjs} +5 -5
  89. package/dist/{platform-domain-B_7x6Iqx.mjs → platform-domain-j9YCXRm6.mjs} +3 -3
  90. package/dist/{platform-lifecycle-Di0LbhPM.mjs → platform-lifecycle-78H0XQUA.mjs} +278 -230
  91. package/dist/{platform-lifecycle-Dhx9Pnub.mjs → platform-lifecycle-DDc9zCeJ.mjs} +1 -1
  92. package/dist/{platform-management-eaiaU3uM.mjs → platform-management-6w8-DUjC.mjs} +2 -2
  93. package/dist/{platform-management-B9LUtMt9.mjs → platform-management-DzKNsMlt.mjs} +1 -1
  94. package/dist/{platform-recovery-BxfA8E5C.mjs → platform-recovery-Do8VOyDE.mjs} +3 -3
  95. package/dist/{platform-registry-BJbgZLS1.mjs → platform-registry-QBa4DK32.mjs} +1 -1
  96. package/dist/{plugin-inference-DsvtJLll.mjs → plugin-inference-BMfKRSqE.mjs} +188 -85
  97. package/dist/prepare-BZXkjdNe.mjs +2 -0
  98. package/dist/{prepare-pcWcxSCh.mjs → prepare-C3kt3Rst.mjs} +11 -11
  99. package/dist/{prepare-_T-Haxrr.mjs → prepare-DyZ-Yok5.mjs} +1 -1
  100. package/dist/{prerender-render-Cf_WDE9W.mjs → prerender-render-D9qbLs2f.mjs} +1 -1
  101. package/dist/prerender-render.mjs +1 -1
  102. package/dist/{preset-Dowh9tTt.mjs → preset-UHj9ARyP.mjs} +4 -4
  103. package/dist/{project-BEBFDFLz.mjs → project-BuUwfj6f.mjs} +1 -1
  104. package/dist/{project-CWNIPoXc.mjs → project-C0Fqu05O.mjs} +2 -2
  105. package/dist/{project-cmd-DrnRJdep.mjs → project-cmd-B44I8J_W.mjs} +16 -16
  106. package/dist/{project-paths-CKQ-Q5JS.mjs → project-paths-GgcMozYz.mjs} +1 -1
  107. package/dist/{project-team-CzRbO_kA.mjs → project-team-BkbYIsXN.mjs} +6 -6
  108. package/dist/{project-token-Bwxjf4y6.mjs → project-token-C8xEEQnB.mjs} +4 -4
  109. package/dist/{project-tsconfig-CwfqUnVp.mjs → project-tsconfig-B8GeM0RM.mjs} +2 -2
  110. package/dist/{provision-Cck2m3jJ.mjs → provision-BhreDAOS.mjs} +141 -78
  111. package/dist/provision-DNtrtaVD.mjs +3 -0
  112. package/dist/{requests-DwrqUQZ8.mjs → requests-DFyhBMaf.mjs} +4 -4
  113. package/dist/{resolve-project-Xvis70DG.mjs → resolve-project-BG5ORGID.mjs} +1 -1
  114. package/dist/resolve-project-DtbidV4y.mjs +2 -0
  115. package/dist/{rollback-B4tFWmkN.mjs → rollback-DHHxXZiS.mjs} +5 -5
  116. package/dist/{route-types-Id82-veQ.mjs → route-types-Clm4WD0B.mjs} +39 -16
  117. package/dist/{runner-CQs_cDSG.mjs → runner-B8wXwWlo.mjs} +1 -1
  118. package/dist/{runner-mysql-1o47achK.mjs → runner-mysql-CEG5JozK.mjs} +1 -1
  119. package/dist/{runner-mysql-BhwMk2Bm.mjs → runner-mysql-DmWchSWJ.mjs} +1 -1
  120. package/dist/{runner-BGVsGgkb.mjs → runner-p-dMs2UN.mjs} +3 -3
  121. package/dist/{runner-pg-D7z01mQS.mjs → runner-pg-Bh4AgZdj.mjs} +1 -1
  122. package/dist/{runner-pg-CJ_JeGF6.mjs → runner-pg-D4OPlil-.mjs} +1 -1
  123. package/dist/runtime/better-auth-mysql.d.mts +1 -1
  124. package/dist/runtime/better-auth-mysql.mjs +1 -1
  125. package/dist/runtime/better-auth-pg.d.mts +1 -1
  126. package/dist/runtime/better-auth-pg.mjs +1 -1
  127. package/dist/runtime/better-auth.d.mts +1 -1
  128. package/dist/runtime/better-auth.mjs +2 -2
  129. package/dist/runtime/db.mjs +8 -5
  130. package/dist/runtime/durable.mjs +1 -1
  131. package/dist/runtime/email/testing.mjs +1 -1
  132. package/dist/runtime/env-public.mjs +1 -1
  133. package/dist/runtime/env.d.mts +1 -1
  134. package/dist/runtime/env.mjs +1 -1
  135. package/dist/runtime/kv.mjs +1 -1
  136. package/dist/runtime/live-server.mjs +38 -23
  137. package/dist/runtime/queues.mjs +1 -1
  138. package/dist/runtime/sandbox.mjs +1 -1
  139. package/dist/runtime/storage.mjs +1 -1
  140. package/dist/runtime/ws-server.d.mts +1 -1
  141. package/dist/runtime/ws-server.mjs +1 -1
  142. package/dist/{scan-DJbooZm2.mjs → scan-4tfN-PSn.mjs} +113 -99
  143. package/dist/{scan-DdDvRCU1.mjs → scan-ClYmX3sa.mjs} +35 -137
  144. package/dist/{secret-UtrRjhEO.mjs → secret-DN9sSNiV.mjs} +7 -7
  145. package/dist/{skills-B-690E7h.mjs → skills-O6FUaizK.mjs} +2 -2
  146. package/dist/sveltekit.mjs +1 -1
  147. package/dist/{validate-qNhV00PD.mjs → validate-CIUwFpjB.mjs} +2 -2
  148. package/dist/validate-EKmJWxmy.mjs +2 -0
  149. package/dist/{wrangler-D01qs6VB.mjs → wrangler-BymcxrRa.mjs} +3 -3
  150. package/dist/{yarn-pnp-CVEc3gE7.mjs → yarn-pnp-BV4AzNul.mjs} +1 -1
  151. package/package.json +7 -7
  152. package/schema.json +18 -0
  153. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +1 -1
  154. package/skills/void/SKILL.md +4 -2
  155. package/skills/void/docs/guide/app-types.md +1 -1
  156. package/skills/void/docs/guide/auth.md +2 -2
  157. package/skills/void/docs/guide/database/d1.md +6 -0
  158. package/skills/void/docs/guide/durable-state.md +1 -1
  159. package/skills/void/docs/guide/edge/rewrites.md +2 -3
  160. package/skills/void/docs/guide/env-migration.md +1 -1
  161. package/skills/void/docs/guide/pages-routing/markdown.md +1 -1
  162. package/skills/void/docs/guide/platform/administration/access.md +1 -1
  163. package/skills/void/docs/guide/platform/development/local.md +1 -1
  164. package/skills/void/docs/guide/platform/installation/prerequisites.md +2 -2
  165. package/skills/void/docs/guide/platform/installation/setup.md +1 -1
  166. package/skills/void/docs/guide/project-collaboration.md +1 -1
  167. package/skills/void/docs/guide/server-routing.md +2 -3
  168. package/skills/void/docs/guide/ssr.md +4 -10
  169. package/skills/void/docs/guide/websockets.md +1 -1
  170. package/skills/void/docs/integrations/cloudflare.md +2 -0
  171. package/skills/void/docs/reference/api.md +1 -1
  172. package/skills/void/docs/reference/cli.md +34 -13
  173. package/skills/void/docs/reference/config.md +12 -1
  174. package/skills/void/docs/reference/resource-inference.md +1 -1
  175. package/dist/client-DAAivdid.mjs +0 -2
  176. package/dist/collect-DAUItMDS.mjs +0 -2
  177. package/dist/config-DDIFxQYx.mjs +0 -2
  178. package/dist/config-uP7ZDtVZ.mjs +0 -21
  179. package/dist/deploy-DAH2-m_-.mjs +0 -2
  180. package/dist/discover-BBzDZe_o.mjs +0 -2
  181. package/dist/dist-D7-nEOXi.mjs +0 -2
  182. package/dist/gen-B87rlalt.mjs +0 -2
  183. package/dist/help-B403BLBB.mjs +0 -2
  184. package/dist/login-BwiopVdg.mjs +0 -2
  185. package/dist/migrate-BXY3B3m7.mjs +0 -2
  186. package/dist/prepare-D4CkM3_v.mjs +0 -2
  187. package/dist/provision-CNgEBkVA.mjs +0 -3
  188. package/dist/resolve-project-BTotl8Nn.mjs +0 -2
  189. package/dist/validate-DqJ33oHj.mjs +0 -2
@@ -1,6 +1,6 @@
1
- import { a as join, l as relative } from "./dist-4WkAWhWx.mjs";
1
+ import { a as join, l as relative } from "./dist-BVqXeR_h.mjs";
2
2
  import { j as log } from "./dist-Dn6nn2IU.mjs";
3
- import { n as getPackageDir } from "./agents-gni4eqBu.mjs";
3
+ import { n as getPackageDir } from "./agents-B_pX_HmQ.mjs";
4
4
  import { existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, symlinkSync } from "node:fs";
5
5
  //#region src/cli/skills.ts
6
6
  function parseSkills(skillsDir) {
@@ -1,4 +1,4 @@
1
- import { a as join, i as isAbsolute, l as relative, u as resolve } from "./dist-4WkAWhWx.mjs";
1
+ import { a as join, i as isAbsolute, l as relative, u as resolve } from "./dist-BVqXeR_h.mjs";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  //#region src/sveltekit.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
- import { a as join } from "./dist-4WkAWhWx.mjs";
2
- import { n as readJournal, r as stripSqlExt } from "./collect-DXHNWHcT.mjs";
1
+ import { a as join } from "./dist-BVqXeR_h.mjs";
2
+ import { n as readJournal, r as stripSqlExt } from "./collect-DiTn9yr6.mjs";
3
3
  import { t as DESTRUCTIVE_PRAGMA, u as tokenizeSql } from "./plan-BEZ8VJW0.mjs";
4
4
  import { existsSync, readdirSync } from "node:fs";
5
5
  //#region src/migrations/validate.ts
@@ -0,0 +1,2 @@
1
+ import { i as validateMigrations } from "./validate-CIUwFpjB.mjs";
2
+ export { validateMigrations };
@@ -1,6 +1,6 @@
1
- import { a as join, i as isAbsolute, n as dirname, o as normalize, t as basename } from "./dist-4WkAWhWx.mjs";
2
- import "./project-paths-CKQ-Q5JS.mjs";
3
- import { m as readConfig } from "./config-Dxr6cTXn.mjs";
1
+ import { a as join, i as isAbsolute, n as dirname, o as normalize, t as basename } from "./dist-BVqXeR_h.mjs";
2
+ import "./project-paths-GgcMozYz.mjs";
3
+ import { m as readConfig } from "./config-CafTW6Cz.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
6
6
  import { appendSqliteClassMigration } from "@void/deploy-core";
@@ -1,4 +1,4 @@
1
- import { a as join, n as dirname } from "./dist-4WkAWhWx.mjs";
1
+ import { a as join, n as dirname } from "./dist-BVqXeR_h.mjs";
2
2
  import { existsSync, readdirSync } from "node:fs";
3
3
  import { pathToFileURL } from "node:url";
4
4
  //#region src/cli/yarn-pnp.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "void",
3
- "version": "0.21.1",
3
+ "version": "0.21.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/voidzero-dev/void.git",
@@ -325,11 +325,11 @@
325
325
  "@cloudflare/vite-plugin": "1.54.7",
326
326
  "@cloudflare/workers-types": "^4.20260702.1",
327
327
  "@napi-rs/keyring": "2.0.0",
328
- "@void/deploy-cloudflare": "0.21.1",
329
- "@void/deploy-core": "0.21.1",
330
- "@void/edge": "0.21.1",
331
- "@void/isr": "0.21.1",
332
- "@void/platform": "0.21.1",
328
+ "@void/deploy-cloudflare": "0.21.3",
329
+ "@void/deploy-core": "0.21.3",
330
+ "@void/edge": "0.21.3",
331
+ "@void/isr": "0.21.3",
332
+ "@void/platform": "0.21.3",
333
333
  "acorn": "^8.15.0",
334
334
  "better-auth": "^1.7.3",
335
335
  "better-sqlite3": "^13.0.3",
@@ -379,7 +379,7 @@
379
379
  "zod": "^4.6.1"
380
380
  },
381
381
  "peerDependencies": {
382
- "@void/md": "0.21.1",
382
+ "@void/md": "0.21.3",
383
383
  "arktype": ">=2.0.0",
384
384
  "valibot": ">=1.0.0-beta.7",
385
385
  "vite": "^8.0.0",
package/schema.json CHANGED
@@ -385,6 +385,24 @@
385
385
  },
386
386
  "additionalProperties": false
387
387
  },
388
+ "deploy": {
389
+ "type": "object",
390
+ "description": "Void deployment choices. Cloudflare Worker settings belong in cloudflare instead.",
391
+ "properties": {
392
+ "cloudflare": {
393
+ "type": "object",
394
+ "properties": {
395
+ "mode": {
396
+ "type": "string",
397
+ "enum": ["staged", "atomic"],
398
+ "description": "Staged is the default and verifies readiness before traffic. Atomic publishes a Durable Object Worker directly and verifies readiness afterward."
399
+ }
400
+ },
401
+ "additionalProperties": false
402
+ }
403
+ },
404
+ "additionalProperties": false
405
+ },
388
406
  "database": {
389
407
  "type": "string",
390
408
  "enum": ["pg", "mysql"],
@@ -83,7 +83,7 @@ export default defineConfig({
83
83
  7. Deploy workflow migration
84
84
 
85
85
  - Replace old deploy instructions with:
86
- - `void auth login`
86
+ - `void account login`
87
87
  - `void deploy`
88
88
  - If CI must target a specific project, use:
89
89
  - `void deploy --project <slug>`
@@ -59,7 +59,7 @@ dedicated Access applications or connect existing ones, including a separate
59
59
  identity account. Protection setup verifies API/proxy coverage and uses scoped
60
60
  service credentials for installation and CI. Use `platform config auth protection`
61
61
  to show, enable, or disable protection; retain the company gate when probes fail.
62
- Users link another enabled method with `void auth link [connection-id]` after
62
+ Users link another enabled method with `void account link [connection-id]` after
63
63
  recent sign-in and explicit browser identity confirmation. For expired first-admin
64
64
  codes, resume installation or repair completed provisioning. Lost-provider recovery
65
65
  uses `platform config auth recover` with installation ownership, original recovery
@@ -79,6 +79,8 @@ For Void platform project access, use `void project team`: invite only an email
79
79
 
80
80
  Use Void commands for every user-facing workflow. Never ask the user to install, authenticate, or run Wrangler directly. Say Cloudflare or Void instead, except when naming literal `wrangler.jsonc` / `wrangler.json` files or `WRANGLER_*` environment variables the user must inspect.
81
81
 
82
+ `void auth login|status|logout` follows the saved deploy destination or asks the user to choose; `void account` explicitly manages a Void platform account.
83
+
82
84
  Use `void` in examples and commands in this skill. For first-time setup, prefer `void init` followed by `void deploy`; in an empty directory, install `void` first and let `void init` add the matching Pages adapter and starter dependencies with Vite+ as the default scaffold toolchain. In an existing app, `void init` configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`. For Cloudflare deployment, Void uses bundled tooling and secure browser OAuth; init or the first deploy saves the selected `account_id`, and `void cloudflare login|status|logout` manages the session; Void-managed deployment requires an explicitly connected platform. Use `void connect <url>` for an existing platform or `void platform install --plan` to preview a company control plane in the user's Cloudflare account. The core self-hosted platform excludes the dashboard, GitHub App, and build Containers; lifecycle commands are resumable and verify remote, Worker, and R2 ownership before mutations. `void platform disable` gates traffic through installation-owned routing storage and remains disabled through repair or upgrade; `void platform enable` explicitly restores traffic. Safe uninstall retains name-addressed Workers, R2, AI Gateway, external PostgreSQL, and zones for explicit manual cleanup. Direct Cloudflare deploys support native Void apps, static/SPA/SSG output, and Cloudflare builds from TanStack Start, React Router, vinext, SvelteKit, Nuxt, Analog, and Astro. They provision inferred resources, validate and apply migrations, require schema-declared server values in encrypted remote secret storage, upload and probe an immutable Worker Version, then activate and synchronize triggers. Native Void features are Workers Free-compatible by default; `void/sandbox` is an explicit exception because it uses Cloudflare Containers and therefore requires Workers Paid. A Sandbox deploy checks Containers access before provisioning/building, while apps without Sandbox perform no entitlement probe. Versions without preview URLs are staged at 0% and probed through workers.dev using a version override; the same safe fallback applies when Access blocks a generated preview alias but admits the stable Worker hostname. Set `CLOUDFLARE_WORKERS_SUBDOMAIN` in a fresh CI checkout, while local deploys cache it automatically. When Cloudflare Access protects `workers.dev`, use an admitted `CF_ACCESS_CLIENT_ID` / `CF_ACCESS_CLIENT_SECRET` service-token pair for CI, or a short-lived `CF_ACCESS_TOKEN` from `cloudflared` for an interactive local readiness probe. With Cloudflare saved in `.void/project.json`, secret, domain, project status/log/rollback, and remote database commands operate directly on the pinned Worker/account. Logs are a live tail. Rollback restores the selected version's saved schedules, queues, workflows, routes, and domains but never reverses database migrations; versions without complete trigger snapshots use code-only rollback and keep the current routes and schedules. On either deployment platform, auth-enabled `void deploy` preserves an existing `BETTER_AUTH_SECRET` or creates a persistent encrypted secret when missing; always use Void's deployment flow so it can manage that secret safely.
83
85
 
84
86
  Use `void` and `@void/*` in code examples and package manifests.
@@ -110,7 +112,7 @@ If invoked without a concrete task, do a brief app status check and report:
110
112
  3. Runtime signals (`void/db`, `void/kv`, `void/storage`, queue usage).
111
113
  4. Auth signals (`void/auth`, `auth` client imports, OAuth env vars).
112
114
  5. Deployment platform and optional Void project linkage (`.void/project.json`), plus config readiness (`void.config.ts`, Cloudflare `account_id`, tsconfig extends).
113
- 6. Optional health checks (`void auth whoami`, `void db status` when relevant).
115
+ 6. Optional health checks (`void account whoami`, `void db status` when relevant).
114
116
 
115
117
  Then ask what to do next.
116
118
 
@@ -104,7 +104,7 @@ export default defineConfig({
104
104
 
105
105
  `vitepress build` emits the site, then `vite build` copies `publicDir` into `dist/client` and emits the worker into `dist/ssr`. Keep `voidPlugin()` in the **root** `vite.config.ts` only — not in the generator's own config (e.g. `.vitepress/config.ts`).
106
106
 
107
- Because the worker now owns unmatched requests, add [`routing.notFound`](../reference/config.md#routing-notfound) if you want the generator's `404.html` instead of the SPA-style `index.html` fallback:
107
+ The Worker handles unmatched requests. Set [`routing.notFound`](../reference/config.md#routing-notfound) to serve the generator's `404.html` for those requests:
108
108
 
109
109
  ```json
110
110
  { "routing": { "notFound": "404-page" } }
@@ -218,11 +218,11 @@ When auth is active, Void configures Better Auth with these conventions:
218
218
  - D1/SQLite uses the app `DB` binding
219
219
  - PostgreSQL apps (`"database": "pg"`) use the app `HYPERDRIVE` binding
220
220
 
221
- Auth sessions live in the same database system as the rest of the app. `AUTH_KV` is no longer used.
221
+ Auth sessions live in the same database system as the rest of the app.
222
222
 
223
223
  On both deployment targets, Void keeps an existing `BETTER_AUTH_SECRET` or generates one when it's missing. The value is stored as an encrypted Worker secret and reused by later versions.
224
224
 
225
- Localhost development uses a built-in fallback secret automatically. Production deployment through Void manages the secret lifecycle for you.
225
+ The Vite development server uses a built-in fallback secret automatically. A local preview of a production build needs `BETTER_AUTH_SECRET`; production deployment through Void manages the secret lifecycle for you.
226
226
 
227
227
  ## Customization
228
228
 
@@ -21,6 +21,12 @@ For write-heavy workloads, complex queries, or connecting to existing infrastruc
21
21
 
22
22
  None. D1 is the default dialect, so you can start by defining your schema and querying.
23
23
 
24
+ ## Read replication
25
+
26
+ Void enables [D1 read replication](https://developers.cloudflare.com/d1/best-practices/read-replication/) when it provisions a database. For a database that was already configured before this feature, run `void deploy --platform cloudflare --provision` once to enable it. Queries through `db` from `void/db` use a D1 session for each Void request, so reads can run near the request and later queries in that request see at least the same data. Framework handlers without Void's request scope start each database operation on the primary. `createDb` starts a replica-capable session for the binding you pass it.
27
+
28
+ Replicas can lag between requests. Authentication session checks start on the primary so a revoked session is not accepted because of replica lag. If another read must start with the latest primary data, use `env.DB.withSession('first-primary')` from `cloudflare:workers`. Other query libraries and raw D1 calls need their own `withSession()` to use replicas; a bare D1 binding reads from the primary.
29
+
24
30
  ## Local Database
25
31
 
26
32
  `void dev` and local `void db` commands share the same database. If `cloudflare.d1_databases` in `void.config.ts` declares the D1 binding, Void uses its ID. A `preview_database_id` takes precedence during local development.
@@ -129,7 +129,7 @@ export default Counter;
129
129
 
130
130
  These state migrations are separate from Cloudflare's Durable Object class migration. Void generates the latter with `new_sqlite_classes` when it discovers the file.
131
131
 
132
- Do not delete or reorder generated Durable Object migrations in `void.lock.json` after deployment. Native Cloudflare beta deploys can create these classes with the Worker's first deployment, but do not yet apply a later class migration to an existing Worker. Additions, renames, and removals require an explicit supported Cloudflare deployment workflow; after its migration tag is active, `void deploy --platform cloudflare` can resume ordinary version uploads.
132
+ Do not delete or reorder generated Durable Object migrations in `void.lock.json` after deployment. For a class addition, rename, or removal on an existing Worker, review the migration and run `void deploy --platform cloudflare --atomic`. If this Worker needs atomic publication on every deploy, set `deploy: { cloudflare: { mode: 'atomic' } }` in `void.config.ts`. Cloudflare applies class lifecycle changes in one deployment. The Worker receives traffic before Void checks readiness, and you cannot roll back across that migration boundary. Staged deploys keep pre-traffic readiness verification.
133
133
 
134
134
  ## Deployment support
135
135
 
@@ -22,7 +22,7 @@ Define source patterns and destination paths in `routing.rewrites` in [`void.con
22
22
 
23
23
  ## When to use rewrites
24
24
 
25
- Use rewrites instead of [redirects](./redirects) when you want to decouple the **public URL** from the **internal route** without the user seeing a URL change. Common scenarios:
25
+ Use rewrites to decouple the **public URL** from the **internal route**. Common scenarios:
26
26
 
27
27
  - **i18n routing** — serve the default locale at unprefixed paths (`/docs` serves `/en/docs`)
28
28
  - **URL restructuring** — reorganize internal route files without changing public URLs or SEO
@@ -40,7 +40,6 @@ If you **do** want the user to see the new URL (e.g., for SEO canonical signals
40
40
  - `:splat` in the destination is replaced with the portion of the path matched by `*` in the source pattern.
41
41
  - When multiple rules match, the **first match wins**. Put more-specific rules above more-general ones (matches Netlify `_redirects` and Vercel `vercel.json` semantics).
42
42
  - On the default target, rewrites are evaluated at the edge **before** the request reaches the worker. On `node` / `bun` / `deno` targets they run in-process as Hono middleware, still before route dispatch. Either way, the rewritten path is then used for static asset serving, ISR, and SSR.
43
- - Unlike redirects, rewrites do **not** change the URL in the browser or send a `Location` header.
44
43
 
45
44
  ## Example: i18n routing
46
45
 
@@ -107,7 +106,7 @@ After reorganizing from `/blog/:slug` to `/posts/:slug`, keep the old URLs worki
107
106
  }
108
107
  ```
109
108
 
110
- Unlike a redirect, users on `/blog/hello-world` won't see the URL change — they'll just see the content from `/posts/hello-world`.
109
+ Users on `/blog/hello-world` see the content from `/posts/hello-world` at the original URL.
111
110
 
112
111
  ## Programmatic rewrites in middleware
113
112
 
@@ -1,6 +1,6 @@
1
1
  # Environment migration
2
2
 
3
- The environment model now uses `.env` for local development only and remote secrets for every server-side production value. There are no compatibility shims for the previous four-file behavior.
3
+ Use `.env` for local development and remote secrets for server-side production values.
4
4
 
5
5
  ## 1. Preserve production values and consolidate local development values
6
6
 
@@ -265,7 +265,7 @@ The array is sorted by path and updates on HMR in dev when `.md` files are added
265
265
 
266
266
  ## Default CSS Theme
267
267
 
268
- The markdown plugin provides a minimal default theme. Unlike Vitepress, this theme is CSS only - it is designed to be built on top of. The theme ships two entry points depending on your needs:
268
+ The markdown plugin provides a minimal CSS theme with two entry points:
269
269
 
270
270
  ### Full theme (reset + baseline + content)
271
271
 
@@ -107,7 +107,7 @@ Cloudflare applications for deliberate cleanup. Disabling an Access login method
107
107
  does not remove the gate.
108
108
 
109
109
  Users can add another enabled login to their existing account with
110
- `void auth link <connection-id>` or **Account** in the optional
110
+ `void account link <connection-id>` or **Account** in the optional
111
111
  dashboard. Sign in again first if prompted, then authenticate with the additional
112
112
  provider and confirm the identity shown. Matching email addresses alone do not
113
113
  link accounts.
@@ -16,7 +16,7 @@ vpr install:void-dev
16
16
  void-dev --help
17
17
  ```
18
18
 
19
- Use the Node.js version recorded in `.node-version`. The workspace uses public npm packages; a GitHub Packages token is not required.
19
+ Use the Node.js version recorded in `.node-version`.
20
20
 
21
21
  `install:void-dev` builds the CLI, shared packages, and platform runtime, then makes this checkout's built CLI globally available as `void-dev`. Public packages export their built files, so run `vp run build:core` after later source changes to refresh the alias. The installer refuses to replace an unrelated global command. Remove only this checkout's alias with `vpr uninstall:void-dev`. The commands on these development pages run from the repository root.
22
22
 
@@ -8,7 +8,7 @@ Start with a Cloudflare account you can administer, an account with your chosen
8
8
 
9
9
  Void creates the Workers, storage, queues, routing, and database tables through the CLI.
10
10
 
11
- This setup has costs: Workers for Platforms requires a paid plan, and your database and Cloudflare usage have their own pricing. External PostgreSQL is required in either mode. Native single-app deployments remain Workers Free-compatible unless the app uses a paid-only product.
11
+ This setup has costs: Workers for Platforms requires a paid plan, and your database and Cloudflare usage have their own pricing. External PostgreSQL is required in either mode.
12
12
 
13
13
  ## Prepare Your Cloudflare Account and Domain
14
14
 
@@ -85,4 +85,4 @@ For a dedicated Supabase project, [disable the Data API](https://supabase.com/do
85
85
 
86
86
  Once installation claims the database, continue using that same database for resume and maintenance commands. Uninstall never deletes external PostgreSQL.
87
87
 
88
- During interactive installation, choose whether Void creates Hyperdrive or uses one you manage separately. If you choose a separately managed Hyperdrive and none exists, Void gives you the required name and setup instructions, then stops so you can create it. Name it `void-<installation-name>-database`, point it at the same dedicated PostgreSQL database using a runtime user, and disable SQL result caching. See [Cloudflare's Hyperdrive setup guide](https://developers.cloudflare.com/hyperdrive/get-started/), or ask your organization's Hyperdrive administrator to create it. Rerun the installer; Void shows the matching Hyperdrive's database, host, port, and runtime user for confirmation. Paste a database owner connection into the PostgreSQL URL prompt for installation and migrations. Void verifies that Hyperdrive points to the same database and records its identity for later maintenance without taking ownership of it. For unattended installation, supply the existing Hyperdrive ID, origin host, and runtime user through the environment variables in [Install from CI](/guide/platform/installation/ci).
88
+ During interactive installation, choose whether Void creates Hyperdrive or uses an existing configuration in your Cloudflare account. Select an existing configuration by name and confirm its database, host, port, runtime user, and disabled SQL result caching. If you need a new separately managed configuration, choose **Set up a separately managed Hyperdrive**; Void pauses and gives you setup instructions. Create it with any unused name, point it at the dedicated PostgreSQL database using a runtime user, and disable SQL result caching. See [Cloudflare's Hyperdrive setup guide](https://developers.cloudflare.com/hyperdrive/get-started/), or ask your organization's Hyperdrive administrator to create it. Rerun the installer and select it. Paste a database owner connection into the PostgreSQL URL prompt for installation and migrations. Void verifies the selected Hyperdrive against that database, records its identity for later maintenance, and leaves its configuration under your external manager's control. For unattended installation, supply the existing Hyperdrive ID, origin host, and runtime user through the environment variables in [Install from CI](/guide/platform/installation/ci).
@@ -138,7 +138,7 @@ For the default GitHub-only setup:
138
138
  3. Set the **Redirect URI** (also called **Authorization callback URL**) to the exact printed URL ending in `/auth/callback`, then register the application. This URL is now pinned in your saved draft and remains the same if credential setup is interrupted.
139
139
  4. Save the **Client ID**, generate a **Client Secret**, and save that too. GitHub's [registration guide](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) describes the form.
140
140
 
141
- This OAuth App handles sign-in. A GitHub App with repository access and build webhooks is not required for the core platform.
141
+ This OAuth App handles sign-in.
142
142
 
143
143
  For the default GitHub-only setup, the prompts collect the runtime token, administrator GitHub username, PostgreSQL URL, GitHub client ID and secret, R2 credentials, and signing/encryption keys. Other login methods collect their configured provider credentials and use the one-time administrator setup code described above. Secret values are masked and setup progress is encrypted locally using the system keychain. Keep a password-manager copy for recovery on another machine.
144
144
 
@@ -77,7 +77,7 @@ and run `void project link`.
77
77
 
78
78
  If the invitation is missing, check the platform and signed-in account. To
79
79
  switch accounts, set `VOID_API_URL` to the invitation's platform URL, unset
80
- `VOID_TOKEN` if present, then run `void auth logout` and `void auth login` using
80
+ `VOID_TOKEN` if present, then run `void account logout` and `void account login` using
81
81
  the invited email address. For an expired or revoked invitation, ask a project
82
82
  administrator to invite you again.
83
83
 
@@ -29,10 +29,9 @@ routes/
29
29
 
30
30
  Excluded routes aren't included in the Worker bundle, generated types, or route and WebSocket configuration.
31
31
 
32
- Two things do not follow the suffix:
32
+ `void prepare` is the exception: it boots no Vite, so it has no environment to read. It generates types for routes in both environments.
33
33
 
34
- - `void prepare` boots no Vite, so it has no environment to read. It generates types for every route in both environments.
35
- - [Binding inference](../reference/resource-inference.md) scans your source for imports and does not read the suffix. A `void/storage` import inside `api/debug.dev.ts` still adds an R2 binding to your production config, and `void deploy` still provisions the bucket. Set the binding explicitly with [`inference.bindings`](../reference/config.md#inference-bindings) if you do not want it.
34
+ [Binding inference](../reference/resource-inference.md) follows the suffix for files in `routes/`. For example, a `void/storage` import used only in `api/debug.dev.ts` adds a development R2 binding, but does not provision a production bucket. Imports in other source directories remain available in both environments.
36
35
 
37
36
  The suffix applies to files in `routes/` only. It has no effect in `pages/`, `middleware/`, `crons/`, or `queues/`.
38
37
 
@@ -15,9 +15,7 @@ For most apps, [Pages Routing](./pages-routing/overview) handles SSR automatical
15
15
  Custom SSR is separate from Pages Routing. Use Custom SSR when you want to bring
16
16
  your own root component, router, data loading, HTML shell, and hydration logic.
17
17
 
18
- The `App` component in the examples below is not a Void convention and it is not
19
- the same thing as `pages/layout.tsx`. It is just the root component for your
20
- custom-rendered application:
18
+ The `App` component below is the root of this custom-rendered application:
21
19
 
22
20
  ```tsx
23
21
  // src/App.tsx
@@ -26,11 +24,8 @@ export default function App({ url }: { url: string }) {
26
24
  }
27
25
  ```
28
26
 
29
- If you are using `pages/` with `@void/react`, `@void/vue`, `@void/svelte`, or
30
- `@void/solid`, do not create `src/main.ssr.*`, `src/main.client.*`, or
31
- `src/App.*` for Pages mode. The adapter generates the SSR and hydration entries
32
- and automatically composes your `pages/layout.*`, route components, loaders, and
33
- actions.
27
+ Pages Routing adapters generate their own SSR and hydration entries and compose
28
+ `pages/layout.*`, route components, loaders, and actions.
34
29
 
35
30
  ## Required entries
36
31
 
@@ -105,8 +100,7 @@ hydrateRoot(document.getElementById('root')!, <App url={window.location.pathname
105
100
 
106
101
  ## Client Asset Injection
107
102
 
108
- Void no longer mutates your rendered HTML automatically.
109
- You decide whether and where to inject client asset tags.
103
+ Place the client asset tags in the HTML returned by your `render()` function.
110
104
 
111
105
  The `assetTags` values are computed by Void:
112
106
 
@@ -10,7 +10,7 @@ Typed WebSocket routes currently work in native Void apps. They aren't available
10
10
 
11
11
  Create a `.ws.ts` route to add a typed WebSocket endpoint. Void runs each route instance in a Cloudflare Durable Object, which coordinates the clients connected to it. These routes require the Cloudflare target; Node.js, Bun, and Deno builds reject them.
12
12
 
13
- New route classes use SQLite-backed Durable Objects on both deployment platforms. Void preserves legacy key-value-backed migration history for existing hosted projects and never reclassifies an already-created class.
13
+ New WebSocket route classes use SQLite-backed Durable Objects on both deployment platforms.
14
14
 
15
15
  For example, a chat route at `/rooms/[id]` gives each room its own instance. Use it for chat, presence, collaborative documents, or notifications.
16
16
 
@@ -313,6 +313,8 @@ For apps using auth, Void creates a random 32-byte `BETTER_AUTH_SECRET` only whe
313
313
 
314
314
  Void usually checks an uploaded version before sending it traffic. When Cloudflare provides a version preview URL, Void probes that URL. Otherwise, it stages the version at 0% traffic and checks it through `workers.dev` using Cloudflare's version-override header.
315
315
 
316
+ For an existing Durable Object Worker that Cloudflare cannot stage, review the Worker and database changes, then run `void deploy --platform cloudflare --atomic`. To use that mode on every deploy, set `deploy: { cloudflare: { mode: 'atomic' } }` in `void.config.ts`. Void will then publish directly, without first attempting staging, and check `/__void/ready` afterward. Production traffic can reach the new version before that check finishes, and a Durable Object class migration cannot be rolled back across its migration boundary. The default `staged` mode continues to check readiness before traffic. A failed staged upload is recorded locally in `.void/cloudflare-candidate.json`; keep that file for a safe retry from the same checkout.
317
+
316
318
  If readiness or trigger synchronization fails, Void restores the previous deployment. If you already have a gradual rollout splitting traffic across versions, finish or cancel it in Cloudflare before deploying through Void.
317
319
 
318
320
  A new Worker may need one ordinary deployment before version uploads work. This can happen when creating the Worker, establishing its first Durable Object migration history, or enabling preview URLs. Void checks that the Worker did not exist before first-deploy secret setup, deploys it once, then checks the active Worker through `/__void/ready`. It keeps that earlier check even if attaching a secret creates a placeholder version. This bootstrap is never used for an existing application.
@@ -1193,7 +1193,7 @@ See [Markdown Pages](../guide/pages-routing/markdown.md) for setup and framework
1193
1193
 
1194
1194
  ## User-Facing Imports
1195
1195
 
1196
- This table lists app-facing imports. Exported implementation subpaths such as `void/pages*`, `void/runtime/*`, and `void/remote*` are used by adapters, generated entries, or internal runtime wiring and are not documented as application APIs.
1196
+ Import Void's app-facing APIs from these paths:
1197
1197
 
1198
1198
  | Import path | Contents |
1199
1199
  | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
@@ -28,7 +28,8 @@ Use this page as a command reference. If you are setting up a project for the fi
28
28
  | `void secret sync .env` | Bulk upload secrets from dotenv file |
29
29
  | `void env check [--remote]` | Validate env.ts schema |
30
30
  | `void env types` | Regenerate .void/env.d.ts from env.ts |
31
- | `void auth login` | Authenticate with Void |
31
+ | `void auth login` | Authenticate with the project’s saved destination, or choose one |
32
+ | `void account login` | Authenticate with a Void platform |
32
33
  | `void cloudflare login` | Authenticate with Cloudflare through Void |
33
34
  | `void platform install` | Install a company Void platform in Cloudflare |
34
35
  | `void connect <url>` | Connect the CLI to a Void platform |
@@ -169,9 +170,23 @@ The deployment preference is saved in `.void/project.json`. Connecting to anothe
169
170
 
170
171
  In a non-interactive shell, supply a URL or explicit target. Cloudflare requires usable credentials and an unambiguous account (`CLOUDFLARE_ACCOUNT_ID` when needed). For a Void platform, provide `VOID_TOKEN` with a matching `VOID_API_URL`, or reuse a valid origin-scoped keychain session. Use `void connect <url> --no-login` to save the verified connection without authenticating; this option is only available for Void platforms.
171
172
 
172
- ## Auth
173
+ ## Authentication
173
174
 
174
- ### `void auth login`
175
+ `void auth login`, `void auth status`, and `void auth logout` use the destination
176
+ saved for the current project by `void init` or `void connect`. If no destination
177
+ is saved, interactive commands let you choose Cloudflare or a connected Void
178
+ platform. In a non-interactive shell, pass `--platform cloudflare|void` or use
179
+ the explicit `void cloudflare` and `void account` commands. Choosing a destination
180
+ for authentication does not change the project's deploy target.
181
+
182
+ `void auth whoami`, `void auth link`, and `void auth token` remain supported for
183
+ existing scripts. `whoami` follows the selected destination; `link` and `token`
184
+ are Void account operations. Prefer `void auth status`, `void account link`, and
185
+ `void account token` in new scripts.
186
+
187
+ ## Void platform account
188
+
189
+ ### `void account login`
175
190
 
176
191
  Browser login through one of the platform's currently enabled methods. The token is saved in the operating-system keychain, scoped to the platform origin. Login fails closed when no keychain is available instead of writing the token to a plaintext file; headless environments use `VOID_TOKEN` from their secret manager.
177
192
 
@@ -182,22 +197,22 @@ saved login instead, unset `VOID_TOKEN`.
182
197
 
183
198
  This is optional if you already completed auth during `void connect` or the interactive `void init` flow.
184
199
 
185
- ### `void auth link [connection-id]`
200
+ ### `void account link [connection-id]`
186
201
 
187
202
  Link another enabled login method to your current account. Sign in again if your
188
203
  session is no longer recent, complete the additional provider's browser login,
189
204
  and confirm the displayed identity. With no connection ID, choose an enabled
190
205
  method interactively. The optional dashboard exposes the same flow in **Account**.
191
206
 
192
- ### `void auth logout`
207
+ ### `void account logout`
193
208
 
194
209
  Removes saved credentials.
195
210
 
196
- ### `void auth whoami`
211
+ ### `void account whoami`
197
212
 
198
213
  Prints your current login.
199
214
 
200
- ### `void auth token`
215
+ ### `void account token`
201
216
 
202
217
  Copies your human auth token to the system clipboard. It is intended for
203
218
  interactive troubleshooting and remains subject to login-method revocation. Do
@@ -785,7 +800,7 @@ Setup drafts save Worker names, the login callback, and partial credentials encr
785
800
 
786
801
  Use an empty PostgreSQL database dedicated to the installation. You can correct a failed initial connection, but after the database is claimed or Hyperdrive is provisioned, commands reject a different URL.
787
802
 
788
- During interactive installation, choose whether Void creates Hyperdrive or uses one you manage separately. If the separately managed configuration is missing, Void shows the required name and setup instructions, then stops before provisioning. Once it exists, Void shows its database, host, port, runtime user, and cache setting for confirmation. Supply an owner PostgreSQL URL at the normal prompt for database claims and migrations. Void adopts the Hyperdrive after verifying its origin and disabled SQL result caching; its configuration stays under the external manager's control. Unattended installs can set `VOID_PLATFORM_HYPERDRIVE_ID`, `VOID_PLATFORM_HYPERDRIVE_ORIGIN_HOST`, and `VOID_PLATFORM_HYPERDRIVE_ORIGIN_USER` together.
803
+ During interactive installation, choose whether Void creates Hyperdrive or uses an existing one. The installer lists the account's Hyperdrive configurations, suggests a matching generated name when present, and lets you select any configuration. Review its database, host, port, runtime user, and cache setting before confirming; its name need not match the installation name. If you need to create a separately managed configuration, Void shows setup instructions and stops before provisioning. Supply an owner PostgreSQL URL at the normal prompt for database claims and migrations. Void adopts the selected Hyperdrive after verifying its database origin and disabled SQL result caching; its configuration stays under the external manager's control. Unattended installs can set `VOID_PLATFORM_HYPERDRIVE_ID`, `VOID_PLATFORM_HYPERDRIVE_ORIGIN_HOST`, and `VOID_PLATFORM_HYPERDRIVE_ORIGIN_USER` together.
789
804
 
790
805
  Recovery secrets are encrypted with AES-256-GCM using a key in your system keychain. The encrypted data is tied to the installation identity. Without a keychain, supply a canonical base64-encoded 32-byte `VOID_PLATFORM_RECOVERY_KEY`; otherwise Void stops before saving secrets. CI can generate a temporary key when its original credentials remain in protected secrets.
791
806
 
@@ -864,6 +879,7 @@ See [Disable and Uninstall](../guide/platform/installation/uninstall.md) for the
864
879
  ```
865
880
  void deploy [--project <name>] [--dir <path>] [--spa] [--skip-build] [--debug]
866
881
  void deploy [--platform <cloudflare|void>] [--require-email]
882
+ void deploy --platform cloudflare --atomic
867
883
  ```
868
884
 
869
885
  Auto-detects your project type and chooses the right pipeline. See [Supported App Types](../guide/app-types.md) and [Deployment](../guide/deployment.md) for details.
@@ -884,8 +900,11 @@ For Drizzle projects, deploy performs a read-only schema drift check. If a new m
884
900
  | `--spa` | Use SPA mode instead of SSG for static deploys |
885
901
  | `--skip-build` | Skip the build step; on Cloudflare this is supported for static/SPA/SSG deploys only |
886
902
  | `--require-email` | Fail when email cannot be set up instead of deploying without it; requires `--platform cloudflare` |
903
+ | `--atomic` | Publish an existing Durable Object Worker directly; readiness is checked after traffic changes |
887
904
  | `--debug` | Mirror the structured deploy log to stderr (also written to `~/.void/logs/`) |
888
905
 
906
+ `--atomic` applies to one deployment. For an existing Durable Object Worker that consistently cannot stage, set `deploy: { cloudflare: { mode: 'atomic' } }` in `void.config.ts` so plain `void deploy` uses atomic publication. The default is `staged`.
907
+
889
908
  The older `--backend cloudflare` spelling remains available as a compatibility alias for `--platform cloudflare`.
890
909
 
891
910
  Every deploy writes a structured JSONL trace to `~/.void/logs/deploy-<timestamp>.jsonl` regardless of `--debug`. On failure the path is printed at the end of the error message so you can attach it when reporting platform issues. `VOID_DEPLOY_DEBUG=1` is accepted as an alternate trigger for stderr mirroring.
@@ -971,7 +990,7 @@ If Cloudflare Access protects readiness URLs, supply an allowed `CF_ACCESS_CLIEN
971
990
 
972
991
  Secrets and migrations are validated after the build, so a failed check may leave provisioned resources. It doesn't apply remote D1 migrations or upload the application Worker. PostgreSQL migrations are transactional; MySQL schema changes may partially apply on error.
973
992
 
974
- Void records provisioned resource IDs in `void.lock.json`. Commit it for other machines and CI. Run the first deploy from one machine at a time; provisioning locks are local. The `--provision` flag is accepted but no longer needed.
993
+ Void records provisioned resource IDs in `void.lock.json`. Commit it for other machines and CI. Run the first deploy from one machine at a time; provisioning locks are local.
975
994
 
976
995
  `.env` stays local. Store server keys declared in `env.ts` with `void secret put <NAME>`; Void rejects them as plaintext Worker vars. If the first deploy reports missing remote secrets, set them and retry. Custom D1 migration layouts must match the exact files, contents, and order Void validated. Direct deploy and Cloudflare commands use the top-level settings, not named environments or alternate config paths.
977
996
 
@@ -1095,7 +1114,9 @@ void db export [--output <path>] [--no-data] [--no-schema] [--table <name>]
1095
1114
 
1096
1115
  Dump the local database as SQL. Outputs to stdout by default (pipeable), or to a file with `--output`.
1097
1116
 
1098
- Data exports preserve SQLite AUTOINCREMENT and PostgreSQL SERIAL counters, including IDs consumed by deleted rows. PostgreSQL schema exports create serial sequences before their tables and restore ownership, constraints, and indexes afterward. `--no-schema` restores counter values into an existing schema; `--no-data` starts counters at their schema-defined starting values.
1117
+ Data exports preserve SQLite AUTOINCREMENT and PostgreSQL SERIAL and identity counters, including IDs consumed by deleted rows. SQLite schema exports include indexes, views, and triggers. PostgreSQL schema exports preserve column types, generated columns, identity definitions, serial sequences, constraints, and indexes. `--no-schema` restores counter values into an existing schema; `--no-data` starts counters at their schema-defined starting values.
1118
+
1119
+ For PostgreSQL schemas with views, triggers, custom types, functions, or standalone sequences, use `pg_dump` for a complete backup. `void db export` reports these objects before writing a schema dump.
1099
1120
 
1100
1121
  | Flag | Purpose |
1101
1122
  | ----------------- | ---------------------------------- |
@@ -1300,12 +1321,12 @@ Deploy-on-GitHub works from **any** Void login — Google, GitHub, or other SSO.
1300
1321
  void github link
1301
1322
  ```
1302
1323
 
1303
- Link your current Void account to a GitHub identity. Opens your browser to authorize Void on GitHub (a localhost + PKCE handshake, the same mechanics as `void auth login`), then binds that GitHub identity to the logged-in account. Requires an authenticated CLI (`void auth login` first).
1324
+ Link your current Void account to a GitHub identity. Opens your browser to authorize Void on GitHub (a localhost + PKCE handshake, the same mechanics as `void account login`), then binds that GitHub identity to the logged-in account. Requires an authenticated CLI (`void account login` first).
1304
1325
 
1305
1326
  You normally don't need to run this directly — `void github install` runs the link automatically when your account has no GitHub identity yet. Run it on its own to link ahead of time, or to link a GitHub identity without installing the App.
1306
1327
 
1307
1328
  ::: warning Existing GitHub sign-in
1308
- Void accounts cannot be merged. If the GitHub account you authorize is already linked to a different Void account, including one created through GitHub sign-in, `void github link` is refused with `This GitHub account is already linked to another Void account.` Run `void auth logout` and sign in to that existing account, or authorize a different GitHub account. The command is also refused if your current Void account is already linked to a different GitHub identity. Re-authorizing the GitHub account attached to your current Void account is allowed and reports `GitHub account already linked.`
1329
+ Void accounts cannot be merged. If the GitHub account you authorize is already linked to a different Void account, including one created through GitHub sign-in, `void github link` is refused with `This GitHub account is already linked to another Void account.` Run `void account logout` and sign in to that existing account, or authorize a different GitHub account. The command is also refused if your current Void account is already linked to a different GitHub identity. Re-authorizing the GitHub account attached to your current Void account is allowed and reports `GitHub account already linked.`
1309
1330
  :::
1310
1331
 
1311
1332
  ### `void github install`
@@ -1334,7 +1355,7 @@ Join the GitHub App installations your organization already has. If a teammate i
1334
1355
 
1335
1356
  In an interactive terminal you rarely need to run this yourself — `void github connect` runs the same join automatically when no active installations are linked to your account. Running `void github join` yourself matters mainly for non-interactive use (without a TTY, `void github connect` never opens a browser), or to link installations ahead of time.
1336
1357
 
1337
- Requires an authenticated CLI (`void auth login` first) and organization-installation sharing enabled on your Void instance; when it is not enabled the command fails closed with a clear message. You can only join installations your GitHub authorization actually returns — you cannot name or join one you cannot access on GitHub.
1358
+ Requires an authenticated CLI (`void account login` first) and organization-installation sharing enabled on your Void instance; when it is not enabled the command fails closed with a clear message. You can only join installations your GitHub authorization actually returns — you cannot name or join one you cannot access on GitHub.
1338
1359
 
1339
1360
  ### `void github connect`
1340
1361
 
@@ -217,7 +217,7 @@ Use remote D1/KV/R2 bindings during local development instead of local miniflare
217
217
 
218
218
  **Requirements:**
219
219
 
220
- - Must be logged in (`void auth login`)
220
+ - Must be logged in (`void account login`)
221
221
  - Must have a linked project (`void project link`)
222
222
  - Only affects D1 (`DB`), KV (`KV`), and R2 (`STORAGE`) bindings
223
223
 
@@ -316,6 +316,17 @@ Void writes a generated Cloudflare config for its tooling and records provisione
316
316
 
317
317
  If you need to remove a value that Void previously generated, remove it from the `resolved` object in `void.lock.json`. Void refreshes the generated Cloudflare file on the next command. Put ongoing custom settings in `cloudflare` in `void.config.ts`.
318
318
 
319
+ ### `deploy.cloudflare.mode`
320
+
321
+ Direct Cloudflare deploys use `staged` by default: Void checks the new Worker before sending it production traffic. If Cloudflare cannot stage an existing Durable Object Worker, choose `atomic` after reviewing the pending Worker and database changes:
322
+
323
+ ```ts
324
+ // Inside defineConfig({ ... })
325
+ deploy: { cloudflare: { mode: 'atomic' } },
326
+ ```
327
+
328
+ This choice applies to subsequent `void deploy` runs. Atomic deployment sends traffic to the new Worker before Void checks readiness; a Durable Object class migration cannot be rolled back across its migration boundary. Use `--atomic` for a single deployment instead. `deploy` is a Void setting and is not passed to Cloudflare's Worker config.
329
+
319
330
  `worker.limits.cpu_ms` sets the CPU time limit per request, from 1 to 300000 ms. On a Void platform, deploy fails if the limit exceeds the account plan; lower it in `void.config.ts` before retrying. Rollback instead caps the old limit at the current plan ceiling. On direct deploys, [Cloudflare enforces the value](https://developers.cloudflare.com/workers/platform/limits/#cpu-time): Workers Free allows up to 10 ms and Workers Paid up to 300000 ms per request.
320
331
 
321
332
  ```json
@@ -31,7 +31,7 @@ This runs once before plugins initialize, so the results are available to config
31
31
 
32
32
  Auth detection also triggers when importing the `auth` specifier from `void/client` or a framework-specific client subpath such as `void/client/react` (but not when importing only `fetch`).
33
33
 
34
- Durable state uses a filesystem convention rather than the import scanner. For example, `durable-objects/shopping-cart.ts` creates the `SHOPPING_CART` binding, exports `ShoppingCartDurableObject`, and adds a `new_sqlite_classes` migration. See [Durable State](../guide/durable-state.md).
34
+ Durable state is inferred from files in `durable-objects/`. For example, `durable-objects/shopping-cart.ts` creates the `SHOPPING_CART` binding, exports `ShoppingCartDurableObject`, and adds a `new_sqlite_classes` migration. See [Durable State](../guide/durable-state.md).
35
35
 
36
36
  ## Scanned Directories
37
37
 
@@ -1,2 +0,0 @@
1
- import { n as PlatformClient } from "./client-PdAJ-F0t.mjs";
2
- export { PlatformClient };
@@ -1,2 +0,0 @@
1
- import { t as collectMigrations } from "./collect-DXHNWHcT.mjs";
2
- export { collectMigrations };
@@ -1,2 +0,0 @@
1
- import { t as writeDrizzleConfig } from "./config-BSe70f4T.mjs";
2
- export { writeDrizzleConfig };