void 0.26.0 → 0.27.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 (365) hide show
  1. package/AGENTS_TEMPLATE.md +1 -3
  2. package/README.md +19 -9
  3. package/dist/{account-cmd-CDry3B5V.mjs → account-cmd-l-FM7Ioq.mjs} +8 -7
  4. package/dist/{application-analysis-DC2yPvzY.mjs → application-analysis-DKy02UY0.mjs} +21 -32
  5. package/dist/{application-routing-C9khgLiS.mjs → application-routing-DQyUh_5S.mjs} +1 -1
  6. package/dist/{auth-D52yG7hl.mjs → auth-Dn2vw-SG.mjs} +9 -9
  7. package/dist/{auth-B60QDbjg.mjs → auth-LMJcNESe.mjs} +1 -1
  8. package/dist/{auth-link-DjeOptYi.mjs → auth-link-vz9Z2kmG.mjs} +5 -5
  9. package/dist/{auth-migrations-9vif1uj8.mjs → auth-migrations-BwHgeEsD.mjs} +8 -18
  10. package/dist/{auth-router-BRxIuqDi.mjs → auth-router-DvsCUVw4.mjs} +6 -19
  11. package/dist/{better-auth-shared-BVkjZ3vM.d.mts → better-auth-shared-CPvWD3nG.d.mts} +0 -4
  12. package/dist/{better-auth-shared-hy6RPh9W.mjs → better-auth-shared-DPpj8zxc.mjs} +94 -16
  13. package/dist/{build-cmd-Ce3C8huo.mjs → build-cmd-D6we0VjO.mjs} +8 -7
  14. package/dist/{cache-CS8Yxr5a.mjs → cache-CZRdzKx1.mjs} +8 -8
  15. package/dist/{cancel-deploy-mZsD88Xa.mjs → cancel-deploy-CQ3NnMvf.mjs} +6 -5
  16. package/dist/{cf-access-YTlqvAsk.mjs → cf-access-BcIBSKqG.mjs} +11 -12
  17. package/dist/{cf-build-output-U8o1Gl6X.mjs → cf-build-output-DjvB_872.mjs} +62 -85
  18. package/dist/cf-build-output-H9a97vME.mjs +2 -0
  19. package/dist/cf-user-agent-lKblH3zU.mjs +17 -0
  20. package/dist/cli/cli.mjs +48 -83
  21. package/dist/cli/cloudflare-operation-process.mjs +78 -78
  22. package/dist/cli/env-schema-probe.mjs +5 -6
  23. package/dist/{client-mC-dFGDD.mjs → client-DlDJuY0s.mjs} +30 -8
  24. package/dist/client-tso2OfcG.mjs +2 -0
  25. package/dist/{cloudflare-auth-Qdc7tw8F.mjs → cloudflare-auth-CuxfF6OA.mjs} +9 -17
  26. package/dist/{cloudflare-cmd-bhwCxAN6.mjs → cloudflare-cmd-lHqNlJGW.mjs} +6 -5
  27. package/dist/{cloudflare-config-Bktvwtpf.mjs → cloudflare-config-BmhBv3HV.mjs} +1 -1
  28. package/dist/{cloudflare-connect-CuhRgk3k.mjs → cloudflare-connect-2G3rL2rP.mjs} +4 -4
  29. package/dist/{cloudflare-operations-DoQrVHAt.mjs → cloudflare-operations-BlYLlowZ.mjs} +1 -1
  30. package/dist/{cloudflare-operations-DYa3coIk.mjs → cloudflare-operations-CwI1bChl.mjs} +41 -70
  31. package/dist/{cloudflare-process-B-wekeR6.mjs → cloudflare-process-2-TfIEzB.mjs} +20 -22
  32. package/dist/{config-CyQ-wVd7.mjs → config-5r-YpMC-.mjs} +1 -1
  33. package/dist/{config-C_XRIPx2.mjs → config-B_ggY-IO.mjs} +3 -3
  34. package/dist/config-BtSFvXZx.mjs +2 -0
  35. package/dist/config-CLYAosnQ.mjs +78 -0
  36. package/dist/{config-BMHb8RCj.d.mts → config-CSa15FvD.d.mts} +1 -1
  37. package/dist/{config-Br_JZD6u.mjs → config-DiowPT80.mjs} +24 -30
  38. package/dist/config-entry.d.mts +1 -1
  39. package/dist/{config-write-B1f88wJA.mjs → config-write-AHGesphx.mjs} +8 -7
  40. package/dist/{connect-H6EvP62X.mjs → connect-BfPBHHm-.mjs} +12 -11
  41. package/dist/{create-project-B2kk9Q0o.mjs → create-project-BdXEFKal.mjs} +7 -7
  42. package/dist/{create-project-Dbb4uiN-.mjs → create-project-qFDC45zg.mjs} +1 -1
  43. package/dist/{db-DpCKZto0.mjs → db-Xs80hcaA.mjs} +101 -133
  44. package/dist/{delete-CxlSvsvW.mjs → delete-d2vuou3j.mjs} +7 -7
  45. package/dist/{deploy-CeEbnv4b.mjs → deploy-Bqe1PYBw.mjs} +2351 -2497
  46. package/dist/deploy-VsWsVQkw.mjs +2 -0
  47. package/dist/{dev-inbox-D64ZKUod.mjs → dev-inbox-CK-UuPob.mjs} +7 -16
  48. package/dist/{discover-BcPPiF1o.mjs → discover-CkCYv9T_.mjs} +1 -2
  49. package/dist/discover-EDUf6JJw.mjs +2 -0
  50. package/dist/{prompts-ZAuJlyCj.mjs → dist-Bx1z6Eva.mjs} +1 -1
  51. package/dist/{dist-AoCzRTJE.mjs → dist-Cegxq8gs.mjs} +8 -8
  52. package/dist/{prompts-6OSVA7DJ.mjs → dist-D3m88sjf.mjs} +10 -53
  53. package/dist/{domain-B_9VgOm6.mjs → domain-BsDUBAvt.mjs} +29 -30
  54. package/dist/{dotenv-VQxupEUv.mjs → dotenv-BfU6eqFt.mjs} +20 -32
  55. package/dist/{drizzle-Beb2Am5S.mjs → drizzle-CF84FOVM.mjs} +16 -13
  56. package/dist/{email-BokHgjKj.mjs → email-_lGAHOhp.mjs} +24 -19
  57. package/dist/{email--tEtMoj_.mjs → email-d_Aux1vM.mjs} +1 -1
  58. package/dist/{entry-CF5wvH4w.mjs → entry-CMAkqBmU.mjs} +6 -6
  59. package/dist/{env-_v349JBd.mjs → env-BxocywBB.mjs} +25 -6
  60. package/dist/{env-BdTc-K2L.mjs → env-C74QepDE.mjs} +10 -10
  61. package/dist/{env-D5liuQYR.mjs → env-DMA3cXZt.mjs} +1 -1
  62. package/dist/{env-raw-Cx8ElDdj.mjs → env-raw-jZpP5n47.mjs} +1 -2
  63. package/dist/{env-types-D5kds_OZ.mjs → env-types-CwXgeMgL.mjs} +1 -1
  64. package/dist/{env-validation-cZBvGWaP.mjs → env-validation-CrVNjsPm.mjs} +1 -1
  65. package/dist/{env-validation-vBSQ8gw5.mjs → env-validation-Dxdx_5wo.mjs} +17 -21
  66. package/dist/{fetch-_SeGZao9.d.mts → fetch-BPCYVi3H.d.mts} +20 -1
  67. package/dist/{fetch-BIZJh7vR.mjs → fetch-sAcwjzLO.mjs} +1 -1
  68. package/dist/{fetch-stream-Nm3hkZbT.mjs → fetch-stream-PGgz4uGz.mjs} +18 -23
  69. package/dist/{fetch-stream-Bjf0hoZb.d.mts → fetch-stream-obvZ7fvO.d.mts} +1 -16
  70. package/dist/{gen-BhDlTpwW.mjs → gen-DtkQhvQg.mjs} +40 -57
  71. package/dist/gen-dA9hW7AV.mjs +2 -0
  72. package/dist/{github-cmd-hhkTzlGS.mjs → github-cmd-DaDdBbSS.mjs} +65 -164
  73. package/dist/{handler-DghKr6dU.mjs → handler-BHAn2fZJ.mjs} +1 -0
  74. package/dist/{handler-BeK3weD4.d.mts → handler-CNAwjRcW.d.mts} +4 -11
  75. package/dist/{head-Do8P4puT.d.mts → head-C8K_iGe6.d.mts} +1 -1
  76. package/dist/{head-D_QRR5Yd.mjs → head-D2VF4ApL.mjs} +29 -51
  77. package/dist/{headers-2rKda9Y6.mjs → headers-DlfR78Nu.mjs} +3 -3
  78. package/dist/{help-Bv44e2tm.mjs → help-0bTe_lID.mjs} +13 -32
  79. package/dist/help-DfQYVfGY.mjs +2 -0
  80. package/dist/{inbound-fRkqcXaC.mjs → inbound-PfQDLXc5.mjs} +23 -24
  81. package/dist/index.d.mts +19 -2
  82. package/dist/index.mjs +619 -532
  83. package/dist/{info-DhtTKh65.mjs → info-PYWwkWyt.mjs} +4 -4
  84. package/dist/{init-BMf4T03q.mjs → init-DaBGmaXC.mjs} +161 -198
  85. package/dist/{link-BqYsSS_I.mjs → link-C6fjafep.mjs} +10 -10
  86. package/dist/{list-_kBToO-l.mjs → list-BTFBlqKl.mjs} +9 -8
  87. package/dist/{live-CB1y5IuC.mjs → live-CgQuTpqD.mjs} +15 -16
  88. package/dist/{live-iAuEH1hd.d.mts → live-Du8jXwOW.d.mts} +4 -2
  89. package/dist/{local-d1-fGxYrVD6.mjs → local-d1-ga5O_idV.mjs} +2 -2
  90. package/dist/{login-DFuo-RWO.mjs → login-GKcNUmtI.mjs} +7 -7
  91. package/dist/login-mx_ydhmp.mjs +2 -0
  92. package/dist/{logs-DYgnh6dH.mjs → logs-BiMSULmc.mjs} +28 -11
  93. package/dist/migrate-BHp07yJE.mjs +2 -0
  94. package/dist/{migrate-CV1on-yJ.mjs → migrate-NLsjBbuM.mjs} +34 -20
  95. package/dist/{mime-D5Nmdzf7.mjs → mime-DxCznlJq.mjs} +45 -95
  96. package/dist/{node-C6Q6e1Es.mjs → node-DJicPvPj.mjs} +5 -5
  97. package/dist/{operator-args-DdY54Bgb.mjs → operator-args-DOBhIaIg.mjs} +10 -1
  98. package/dist/{operator-auth-2dsGlTT5.mjs → operator-auth-BEZ_u0Cz.mjs} +2 -2
  99. package/dist/{operator-client-BFqpp6z0.mjs → operator-client-DbDv4vtE.mjs} +2 -2
  100. package/dist/{operator-cmd-CUGHXrQf.mjs → operator-cmd-BT4hgavL.mjs} +24 -11
  101. package/dist/operator-cmd-CwBB-1yb.mjs +2 -0
  102. package/dist/{output-BvdaehtE.mjs → output-C50ag2r3.mjs} +20 -2
  103. package/dist/pages/client.d.mts +19 -51
  104. package/dist/pages/client.mjs +204 -225
  105. package/dist/pages/head-client.d.mts +1 -1
  106. package/dist/pages/head.d.mts +1 -1
  107. package/dist/pages/head.mjs +1 -1
  108. package/dist/pages/index.d.mts +2 -2
  109. package/dist/pages/index.mjs +6 -12
  110. package/dist/pages/islands-plugin.d.mts +1 -1
  111. package/dist/pages/islands-plugin.mjs +21 -25
  112. package/dist/pages/protocol.d.mts +2 -2
  113. package/dist/pages/protocol.mjs +2 -2
  114. package/dist/{plan-CJGEeTEI.mjs → plan-BhLO2p4w.mjs} +2 -1
  115. package/dist/plan-CH2G51je.mjs +2 -0
  116. package/dist/platform-args-D4E1PjVw.mjs +2 -0
  117. package/dist/{platform-args-DSV2p4nY.mjs → platform-args-DUeXY9Om.mjs} +1 -1
  118. package/dist/{platform-auth-config-Bosx7U1h.mjs → platform-auth-config-CkSx3usH.mjs} +40 -36
  119. package/dist/{platform-auth-protection-DcbL_LW_.mjs → platform-auth-protection-BJimB_p9.mjs} +9 -8
  120. package/dist/{platform-auth-recovery-WfTZ8K6o.mjs → platform-auth-recovery-BU6izFAU.mjs} +8 -7
  121. package/dist/{platform-cmd-DbKtQb_4.mjs → platform-cmd-BbY1dWiM.mjs} +14 -13
  122. package/dist/{platform-cmd-dyFUof0t.mjs → platform-cmd-BbmJiq5O.mjs} +1 -1
  123. package/dist/{platform-discovery-BC0HCKYt.mjs → platform-discovery-DIYz8V63.mjs} +1 -1
  124. package/dist/{platform-domain-Bsq43AJp.mjs → platform-domain-CHVS6cV0.mjs} +6 -6
  125. package/dist/{platform-lifecycle--5gWmDoI.mjs → platform-lifecycle-ByAlpkhV.mjs} +1 -1
  126. package/dist/{platform-lifecycle-Cfi0o6xM.mjs → platform-lifecycle-DzCwqhFq.mjs} +76 -387
  127. package/dist/{platform-management-Bbwf6-Dq.mjs → platform-management-CBOT4BSM.mjs} +1 -1
  128. package/dist/{platform-management-BrF9STZp.mjs → platform-management-CuuVDhyt.mjs} +7 -7
  129. package/dist/{platform-plans-config-DU-8nC2Y.mjs → platform-plans-config-CN-heS4q.mjs} +5 -4
  130. package/dist/{platform-recovery-DQAqAQYu.mjs → platform-recovery-CskSJgLh.mjs} +3 -3
  131. package/dist/{platform-registry-P387v42A.mjs → platform-registry-Cjv2Qf0r.mjs} +5 -1
  132. package/dist/platform-setup-BBxRxmFC.mjs +299 -0
  133. package/dist/{plugin-inference-CXWnn79A.mjs → plugin-inference-BlQbOL0P.mjs} +43 -42
  134. package/dist/prepare-DRUV-g3X.mjs +2 -0
  135. package/dist/{prepare-WoUubFKL.mjs → prepare-Do96654b.mjs} +8 -8
  136. package/dist/{prepare-BMrRWLwP.mjs → prepare-Dq9hTIbo.mjs} +4 -4
  137. package/dist/{prerender-render-D9qbLs2f.mjs → prerender-render-Ct20jftc.mjs} +17 -3
  138. package/dist/prerender-render.mjs +1 -1
  139. package/dist/{project-DQstYTxO.mjs → project-BAm2aB6Q.mjs} +1 -1
  140. package/dist/{project-BiaPQ7ur.mjs → project-DedqCp59.mjs} +1 -1
  141. package/dist/{project-cmd-BbH2LptN.mjs → project-cmd-DaoRrn-8.mjs} +19 -19
  142. package/dist/{project-team-Yiww3-go.mjs → project-team-Q_lCA7Io.mjs} +15 -18
  143. package/dist/{project-token-BrtT2NkY.mjs → project-token-BArgK9o1.mjs} +14 -17
  144. package/dist/{project-tsconfig-B8GeM0RM.mjs → project-tsconfig-CVJhNMxs.mjs} +2 -1
  145. package/dist/{project-zero-trust-nYJ2V2nc.mjs → project-zero-trust-KO9Hu2Pq.mjs} +12 -9
  146. package/dist/{protocol-BX8t2jiw.d.mts → protocol-BPZaNqBo.d.mts} +4 -2
  147. package/dist/{protocol-U7bfjHmA.mjs → protocol-CfaUwNs8.mjs} +46 -49
  148. package/dist/{providers-CJlNS3kT.mjs → providers-BXuhmuub.mjs} +1 -12
  149. package/dist/{provision-VeqAC77A.mjs → provision-BfaLiWbj.mjs} +38 -41
  150. package/dist/{provision-DMTPG8Rh.mjs → provision-Wu9ZBk9L.mjs} +2 -3
  151. package/dist/{requests-TIz_jtSu.mjs → requests-C7Oeoh5u.mjs} +5 -5
  152. package/dist/resolve-project-BIeYs9Cw.mjs +2 -0
  153. package/dist/{resolve-project-BG5ORGID.mjs → resolve-project-CP8rZs_p.mjs} +6 -1
  154. package/dist/{rollback-dBqICPzj.mjs → rollback-DVAtrLAl.mjs} +30 -37
  155. package/dist/{route-types-Clm4WD0B.mjs → route-types-CbtsIeFn.mjs} +1 -1
  156. package/dist/route-url-BgPja1GS.d.mts +5 -0
  157. package/dist/route-url-BjGv_KKY.mjs +28 -0
  158. package/dist/runner-9wjsSZx-.mjs +2 -0
  159. package/dist/{runner--2KF6Kua.mjs → runner-DMBKSrRk.mjs} +2 -2
  160. package/dist/{runner-mysql-DmWchSWJ.mjs → runner-mysql-CEzKtmFb.mjs} +8 -8
  161. package/dist/{runner-mysql-CEG5JozK.mjs → runner-mysql-CkFqZ6CE.mjs} +1 -1
  162. package/dist/{runner-pg-Bh4AgZdj.mjs → runner-pg-BGYRFdRp.mjs} +1 -1
  163. package/dist/runtime/ai.d.mts +1 -1
  164. package/dist/runtime/ai.mjs +34 -95
  165. package/dist/runtime/better-auth-mysql.d.mts +1 -1
  166. package/dist/runtime/better-auth-mysql.mjs +4 -9
  167. package/dist/runtime/better-auth-pg.d.mts +1 -1
  168. package/dist/runtime/better-auth-pg.mjs +5 -10
  169. package/dist/runtime/better-auth.d.mts +1 -1
  170. package/dist/runtime/better-auth.mjs +3 -3
  171. package/dist/runtime/client-react.d.mts +2 -3
  172. package/dist/runtime/client-react.mjs +2 -2
  173. package/dist/runtime/client-solid.d.mts +2 -3
  174. package/dist/runtime/client-solid.mjs +2 -2
  175. package/dist/runtime/client-svelte.d.mts +2 -3
  176. package/dist/runtime/client-svelte.mjs +2 -2
  177. package/dist/runtime/client-vue.d.mts +2 -3
  178. package/dist/runtime/client-vue.mjs +2 -2
  179. package/dist/runtime/client.d.mts +2 -3
  180. package/dist/runtime/client.mjs +2 -2
  181. package/dist/runtime/db.mjs +1 -1
  182. package/dist/runtime/durable.mjs +3 -10
  183. package/dist/runtime/email/testing.mjs +5 -5
  184. package/dist/runtime/email.d.mts +2 -1
  185. package/dist/runtime/email.mjs +11 -27
  186. package/dist/runtime/env-public.mjs +15 -20
  187. package/dist/runtime/env.mjs +1 -1
  188. package/dist/runtime/fetch-stream.d.mts +2 -2
  189. package/dist/runtime/fetch-stream.mjs +1 -1
  190. package/dist/runtime/fetch.d.mts +2 -3
  191. package/dist/runtime/fetch.mjs +1 -1
  192. package/dist/runtime/handler.d.mts +1 -1
  193. package/dist/runtime/handler.mjs +2 -2
  194. package/dist/runtime/isr.mjs +1 -1
  195. package/dist/runtime/kv.mjs +10 -11
  196. package/dist/runtime/live-client.d.mts +1 -1
  197. package/dist/runtime/live-client.mjs +12 -22
  198. package/dist/runtime/live-server.mjs +27 -35
  199. package/dist/runtime/live.d.mts +2 -2
  200. package/dist/runtime/live.mjs +2 -2
  201. package/dist/runtime/migration-handler.mjs +4 -81
  202. package/dist/runtime/queues.mjs +1 -1
  203. package/dist/runtime/remote/binding-handler.d.mts +2 -2
  204. package/dist/runtime/remote/binding-handler.mjs +8 -9
  205. package/dist/runtime/remote/index.mjs +27 -77
  206. package/dist/runtime/route-url.d.mts +2 -4
  207. package/dist/runtime/route-url.mjs +1 -1
  208. package/dist/runtime/routing.d.mts +1 -1
  209. package/dist/runtime/routing.mjs +15 -26
  210. package/dist/runtime/sandbox.mjs +2 -2
  211. package/dist/runtime/sse.mjs +1 -1
  212. package/dist/runtime/storage.mjs +1 -1
  213. package/dist/runtime/validator.d.mts +1 -1
  214. package/dist/runtime/ws-server.d.mts +2 -2
  215. package/dist/runtime/ws-server.mjs +30 -61
  216. package/dist/runtime/ws.d.mts +1 -1
  217. package/dist/runtime/ws.mjs +1 -1
  218. package/dist/{scan-C8dA7iM4.mjs → scan-C3uDzz6J.mjs} +12 -13
  219. package/dist/{secret-AKnNXNP5.mjs → secret-BvtB7IjY.mjs} +15 -15
  220. package/dist/{skills-BPQUGClu.mjs → skills-BgVMvQdy.mjs} +2 -2
  221. package/dist/{sse-CQNaDFFV.mjs → sse-CMvCgjNk.mjs} +1 -1
  222. package/dist/{subcommand-prompt-B6WS9Aoz.mjs → subcommand-prompt-BSlnD1fI.mjs} +2 -2
  223. package/dist/sveltekit.d.mts +0 -2
  224. package/dist/terminal-log-text-D9ACPOuG.mjs +32 -0
  225. package/dist/validate-BJr9LfXy.mjs +2 -0
  226. package/dist/{validate-ymhap6M_.mjs → validate-C9qJArv7.mjs} +9 -28
  227. package/dist/{defer-YsYDUoii.mjs → validation-error-Dg9Recn1.mjs} +11 -11
  228. package/dist/{wrangler-DhUerFkW.mjs → wrangler-D9KTuqnv.mjs} +89 -194
  229. package/dist/{ws-C79j4aED.d.mts → ws-CChrrAU-.d.mts} +1 -1
  230. package/dist/{yarn-pnp-BV4AzNul.mjs → yarn-pnp-CUX_iTPA.mjs} +19 -27
  231. package/{skills/void/docs → docs}/guide/ai.md +5 -3
  232. package/{skills/void/docs → docs}/guide/auth.md +37 -1
  233. package/{skills/void/docs → docs}/guide/database/postgresql.md +2 -2
  234. package/{skills/void/docs → docs}/guide/deployment.md +2 -2
  235. package/{skills/void/docs → docs}/guide/edge/revalidation.md +1 -1
  236. package/{skills/void/docs → docs}/guide/edge/rewrites.md +2 -4
  237. package/{skills/void/docs → docs}/guide/email/receiving.md +2 -2
  238. package/{skills/void/docs → docs}/guide/email/sending.md +0 -2
  239. package/{skills/void/docs → docs}/guide/env-vars.md +4 -0
  240. package/{skills/void/docs → docs}/guide/jobs.md +2 -2
  241. package/{skills/void/docs → docs}/guide/live.md +10 -5
  242. package/{skills/void/docs → docs}/guide/pages-routing/actions-and-forms.md +20 -8
  243. package/{skills/void/docs → docs}/guide/pages-routing/loaders.md +7 -3
  244. package/{skills/void/docs → docs}/guide/pages-routing/markdown.md +15 -23
  245. package/{skills/void/docs → docs}/guide/pages-routing/overview.md +6 -4
  246. package/{skills/void/docs → docs}/guide/platform/administration/access.md +3 -11
  247. package/{skills/void/docs → docs}/guide/platform/administration/operations.md +3 -12
  248. package/{skills/void/docs → docs}/guide/platform/administration/projects.md +1 -1
  249. package/{skills/void/docs → docs}/guide/platform/development/local.md +4 -2
  250. package/{skills/void/docs → docs}/guide/platform/development/runtime.md +1 -1
  251. package/{skills/void/docs → docs}/guide/platform/development/schema-ci.md +1 -1
  252. package/{skills/void/docs → docs}/guide/platform/installation/domains.md +3 -1
  253. package/{skills/void/docs → docs}/guide/platform/installation/first-deployment.md +4 -2
  254. package/{skills/void/docs → docs}/guide/platform/installation/maintenance.md +4 -0
  255. package/{skills/void/docs → docs}/guide/project-collaboration.md +7 -3
  256. package/{skills/void/docs → docs}/guide/queues.md +0 -2
  257. package/{skills/void/docs → docs}/guide/remote-dev.md +5 -5
  258. package/{skills/void/docs → docs}/guide/sandboxes.md +2 -2
  259. package/{skills/void/docs → docs}/guide/sse.md +0 -2
  260. package/{skills/void/docs → docs}/guide/storage.md +7 -2
  261. package/{skills/void/docs → docs}/guide/websockets.md +4 -0
  262. package/docs/integrations/agents.md +37 -0
  263. package/{skills/void/docs → docs}/integrations/frameworks/astro.md +3 -3
  264. package/{skills/void/docs → docs}/integrations/frameworks/nuxt.md +6 -2
  265. package/{skills/void/docs → docs}/integrations/hono.md +15 -7
  266. package/{skills/void/docs → docs}/integrations/nodejs-bun-deno.md +1 -0
  267. package/{skills/void/docs → docs}/reference/api/auth.md +1 -1
  268. package/{skills/void/docs → docs}/reference/api/handlers.md +4 -2
  269. package/{skills/void/docs → docs}/reference/api/pages.md +4 -0
  270. package/{skills/void/docs → docs}/reference/cli/auth.md +1 -6
  271. package/{skills/void/docs → docs}/reference/cli/database.md +3 -4
  272. package/{skills/void/docs → docs}/reference/cli/deploy.md +1 -1
  273. package/{skills/void/docs → docs}/reference/cli/generate.md +1 -1
  274. package/{skills/void/docs → docs}/reference/cli/github.md +3 -12
  275. package/{skills/void/docs → docs}/reference/cli/platform-config.md +1 -1
  276. package/{skills/void/docs → docs}/reference/cli/platform-email.md +2 -3
  277. package/{skills/void/docs → docs}/reference/cli/platform-installation.md +1 -1
  278. package/{skills/void/docs → docs}/reference/cli/platform-operations.md +3 -0
  279. package/{skills/void/docs → docs}/reference/cli/platform-users.md +2 -2
  280. package/{skills/void/docs → docs}/reference/cli/project.md +5 -4
  281. package/{skills/void/docs → docs}/reference/cli/secrets.md +3 -3
  282. package/{skills/void/docs → docs}/reference/cli/setup.md +9 -11
  283. package/{skills/void/docs → docs}/reference/cli.md +1 -1
  284. package/{skills/void/docs → docs}/reference/config.md +13 -13
  285. package/{skills/void/docs → docs}/reference/resource-inference.md +1 -16
  286. package/package.json +34 -30
  287. package/schema.json +1 -1
  288. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +4 -1
  289. package/skills/void/SKILL.md +9 -5
  290. package/dist/cf-build-output-ChY6-XWP.mjs +0 -2
  291. package/dist/client-BxVixJBI.mjs +0 -2
  292. package/dist/config-0acf1oys.mjs +0 -2
  293. package/dist/config-D8MOgiQV.mjs +0 -32
  294. package/dist/deploy-qmiLE1G1.mjs +0 -2
  295. package/dist/discover-AMCBXivQ.mjs +0 -2
  296. package/dist/fetch-error-Sp1R4mZv.d.mts +0 -20
  297. package/dist/gen-qCBwH3fZ.mjs +0 -2
  298. package/dist/help-Dw5f9Xrg.mjs +0 -2
  299. package/dist/login-D7meQg_3.mjs +0 -2
  300. package/dist/migrate-CEu2X5DB.mjs +0 -2
  301. package/dist/operator-cmd-DRPvhpjM.mjs +0 -2
  302. package/dist/plan-COtUvdMA.mjs +0 -2
  303. package/dist/platform-args-Dcy_5b_Y.mjs +0 -2
  304. package/dist/prepare-BBknoZI1.mjs +0 -2
  305. package/dist/resolve-project-DtbidV4y.mjs +0 -2
  306. package/dist/route-url-CG7U-cRN.mjs +0 -15
  307. package/dist/runner-voIltZrY.mjs +0 -2
  308. package/dist/validate-pna7R3Pv.mjs +0 -2
  309. package/skills/void/docs/integrations/agents.md +0 -26
  310. package/dist/{runner-pg-D4OPlil-.mjs → runner-pg-DV8p_zjA.mjs} +4 -4
  311. package/{skills/void/docs → docs}/guide/app-types.md +0 -0
  312. package/{skills/void/docs → docs}/guide/database/d1.md +2 -2
  313. package/{skills/void/docs → docs}/guide/database/mysql.md +0 -0
  314. package/{skills/void/docs → docs}/guide/database.md +8 -8
  315. package/{skills/void/docs → docs}/guide/durable-state.md +0 -0
  316. package/{skills/void/docs → docs}/guide/edge/headers.md +0 -0
  317. package/{skills/void/docs → docs}/guide/edge/prerendering.md +0 -0
  318. package/{skills/void/docs → docs}/guide/edge/redirects.md +0 -0
  319. package/{skills/void/docs → docs}/guide/edge/static-assets.md +0 -0
  320. package/{skills/void/docs → docs}/guide/email/domains.md +0 -0
  321. package/{skills/void/docs → docs}/guide/email.md +0 -0
  322. package/{skills/void/docs → docs}/guide/index.md +0 -0
  323. package/{skills/void/docs → docs}/guide/kv.md +0 -0
  324. package/{skills/void/docs → docs}/guide/pages-routing/head.md +0 -0
  325. package/{skills/void/docs → docs}/guide/pages-routing/islands.md +2 -2
  326. package/{skills/void/docs → docs}/guide/pages-routing/layouts.md +0 -0
  327. package/{skills/void/docs → docs}/guide/pages-routing/view-transitions.md +0 -0
  328. package/{skills/void/docs → docs}/guide/platform/administration/email.md +0 -0
  329. package/{skills/void/docs → docs}/guide/platform/administration/plans.md +0 -0
  330. package/{skills/void/docs → docs}/guide/platform/administration/zero-trust.md +0 -0
  331. package/{skills/void/docs → docs}/guide/platform/installation/ci.md +0 -0
  332. package/{skills/void/docs → docs}/guide/platform/installation/credentials.md +0 -0
  333. package/{skills/void/docs → docs}/guide/platform/installation/prerequisites.md +0 -0
  334. package/{skills/void/docs → docs}/guide/platform/installation/setup.md +0 -0
  335. package/{skills/void/docs → docs}/guide/platform/installation/uninstall.md +0 -0
  336. package/{skills/void/docs → docs}/guide/platform-administration.md +0 -0
  337. package/{skills/void/docs → docs}/guide/platform-development.md +0 -0
  338. package/{skills/void/docs → docs}/guide/quickstart.md +0 -0
  339. package/{skills/void/docs → docs}/guide/self-hosted-platform.md +0 -0
  340. package/{skills/void/docs → docs}/guide/server-routing.md +3 -3
  341. package/{skills/void/docs → docs}/guide/ssg.md +0 -0
  342. package/{skills/void/docs → docs}/guide/ssr.md +0 -0
  343. package/{skills/void/docs → docs}/guide/type-safety.md +0 -0
  344. package/{skills/void/docs → docs}/guide/typed-fetch.md +0 -0
  345. package/{skills/void/docs → docs}/index.md +0 -0
  346. package/{skills/void/docs → docs}/integrations/cloudflare.md +0 -0
  347. package/{skills/void/docs → docs}/integrations/frameworks/analog.md +3 -3
  348. package/{skills/void/docs → docs}/integrations/frameworks/overview.md +0 -0
  349. package/{skills/void/docs → docs}/integrations/frameworks/react-router.md +3 -3
  350. package/{skills/void/docs → docs}/integrations/frameworks/sveltekit.md +1 -1
  351. package/{skills/void/docs → docs}/integrations/frameworks/tanstack-start.md +2 -2
  352. package/{skills/void/docs → docs}/reference/api/client.md +0 -0
  353. package/{skills/void/docs → docs}/reference/api/database.md +2 -2
  354. /package/{skills/void/docs → docs}/reference/api/durable.md +0 -0
  355. /package/{skills/void/docs → docs}/reference/api/env.md +0 -0
  356. /package/{skills/void/docs → docs}/reference/api/plugin.md +0 -0
  357. /package/{skills/void/docs → docs}/reference/api/resources.md +0 -0
  358. /package/{skills/void/docs → docs}/reference/api/rewrites.md +0 -0
  359. /package/{skills/void/docs → docs}/reference/api/types.md +0 -0
  360. /package/{skills/void/docs → docs}/reference/api.md +0 -0
  361. /package/{skills/void/docs → docs}/reference/cli/domains.md +0 -0
  362. /package/{skills/void/docs → docs}/reference/cli/email.md +0 -0
  363. /package/{skills/void/docs → docs}/reference/cli/platform-zero-trust.md +0 -0
  364. /package/{skills/void/docs → docs}/reference/cli/platform.md +0 -0
  365. /package/{skills/void/docs → docs}/reference/structure.md +0 -0
@@ -1,14 +1,14 @@
1
1
  import { a as join, n as dirname, u as resolve } from "./dist-BVqXeR_h.mjs";
2
- import { S as writePendingInstallationSecrets, a as latestPlatformWorkerCutoverGeneration, c as normalizePlatformApiUrl, d as platformRegistryDirectory, f as platformWorkerSecretUpdateIntentState, h as readPendingInstallationSecrets, m as readInstallationRecoverySecrets, n as assertPlatformInstallationSlugAvailable, o as listInstallationManifests, p as promoteInstallationSecrets, t as acquirePlatformLifecycleLock, v as resolveInstallationManifest, x as writeInstallationManifest, y as savePlatformConnection } from "./platform-registry-P387v42A.mjs";
2
+ import { S as writePendingInstallationSecrets, a as latestPlatformWorkerCutoverGeneration, c as normalizePlatformApiUrl, d as platformRegistryDirectory, f as platformWorkerSecretUpdateIntentState, h as readPendingInstallationSecrets, m as readInstallationRecoverySecrets, n as assertPlatformInstallationSlugAvailable, o as listInstallationManifests, p as promoteInstallationSecrets, t as acquirePlatformLifecycleLock, v as resolveInstallationManifest, x as writeInstallationManifest, y as savePlatformConnection } from "./platform-registry-Cjv2Qf0r.mjs";
3
3
  import { t as cfAccessHeaders } from "./cf-access-TWNzXltp.mjs";
4
- import { n as ensurePlatformAccessToken } from "./cf-access-YTlqvAsk.mjs";
5
- import { u as openBrowser } from "./auth-D52yG7hl.mjs";
6
- import { A as confirm, H as outro, K as select, L as log, U as password, X as text$1, tt as isCancel, z as multiselect } from "./prompts-6OSVA7DJ.mjs";
7
- import { c as resolveCloudflareOperationArgv } from "./cloudflare-process-B-wekeR6.mjs";
8
- import { c as import_picocolors, l as note, n as cliCommandName, r as createSpinner } from "./output-BvdaehtE.mjs";
9
- import { o as runCloudflareAuthCommand } from "./cloudflare-auth-Qdc7tw8F.mjs";
10
- import { _ as resolvePinnedApiBaseUrl, o as createDefaultRunWrangler } from "./provision-VeqAC77A.mjs";
11
- import { t as parsePlatformArgs } from "./platform-args-DSV2p4nY.mjs";
4
+ import { n as ensurePlatformAccessToken } from "./cf-access-BcIBSKqG.mjs";
5
+ import { A as confirm, H as outro, K as select, L as log, U as password, X as text$1, tt as isCancel, z as multiselect } from "./dist-D3m88sjf.mjs";
6
+ import { d as printSuccess, l as import_picocolors, n as cliCommandName, r as createSpinner, u as note } from "./output-C50ag2r3.mjs";
7
+ import { l as resolveCloudflareOperationArgv } from "./cloudflare-process-2-TfIEzB.mjs";
8
+ import { o as runCloudflareAuthCommand } from "./cloudflare-auth-CuxfF6OA.mjs";
9
+ import { _ as resolvePinnedApiBaseUrl, o as createDefaultRunWrangler } from "./provision-BfaLiWbj.mjs";
10
+ import { t as parsePlatformArgs } from "./platform-args-DUeXY9Om.mjs";
11
+ import { a as platformManagementSetupPage, c as platformSetupLink, i as platformInstallCommandArguments, l as platformSetupPages, n as formatPlatformSetupPlan, o as platformPromptAnswer, r as openPlatformSetupPage, s as platformSetupFieldHelp, t as formatPlatformInstallCommand } from "./platform-setup-BBxRxmFC.mjs";
12
12
  import { copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
13
13
  import { fileURLToPath } from "node:url";
14
14
  import { isRecord } from "@void/deploy-core";
@@ -16,11 +16,10 @@ import { PLATFORM_APP_ACCESS_SETUP_PROOF_PREFIX, PLATFORM_AUTH_SETUP_PROOF_PREFI
16
16
  import { createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
17
17
  import { tmpdir } from "node:os";
18
18
  import { stripVTControlCharacters } from "node:util";
19
- import { execFile } from "node:child_process";
20
19
  import { encodeCloudflareVersionMessage, parseCloudflareVersionMessage, readCloudflareTriggerConfig, readCloudflareVersionMigrationTag, stabilizeCloudflareVersionTriggers } from "@void/deploy-cloudflare";
20
+ import { createServer, request } from "node:http";
21
21
  import { readFile } from "node:fs/promises";
22
22
  import { PLATFORM_ADMIN_ASSETS_DIRECTORY, platformDatabaseSchemaDigest, resolvePlatformRuntime } from "@void/platform/installer";
23
- import { createServer, request } from "node:http";
24
23
  import { request as request$1 } from "node:https";
25
24
  //#region src/cli/platform-cloudflare.ts
26
25
  var PlatformCloudflareApiError = class extends Error {
@@ -722,21 +721,6 @@ var PlatformCloudflareClient = class PlatformCloudflareClient {
722
721
  async removeRoutes(_accountId, _zoneId, tracked) {
723
722
  if (tracked.routes.length > 0 || tracked.customDomains.length > 0) throw new Error("platform: Cloudflare does not support conditional Worker traffic deletion. Retaining routes and custom domains for explicit dashboard cleanup.");
724
723
  }
725
- async setWorkerSubdomain(accountId, workerName, enabled) {
726
- try {
727
- await this.request(`/accounts/${encodeURIComponent(accountId)}/workers/scripts/${encodeURIComponent(workerName)}/subdomain`, {
728
- body: JSON.stringify({
729
- enabled,
730
- previews_enabled: enabled
731
- }),
732
- headers: { "Cloudflare-Workers-Script-Api-Date": "2025-08-01" },
733
- method: "POST"
734
- });
735
- } catch (error) {
736
- if (!enabled && error instanceof PlatformCloudflareApiError && error.status === 404) return;
737
- throw error;
738
- }
739
- }
740
724
  };
741
725
  function accessResourcePath(accountId, kind, id) {
742
726
  return `/accounts/${encodeURIComponent(accountId)}/access/${kind === "application" ? "apps" : "service_tokens"}/${encodeURIComponent(id)}`;
@@ -997,6 +981,18 @@ function platformAccessOverlapsOrigin(destination, origin) {
997
981
  const pattern = "^" + destination.split("/")[0].split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join(".*") + "$";
998
982
  return new RegExp(pattern, "i").test(new URL(origin).hostname);
999
983
  }
984
+ /** Whether an application path-covers, or exactly covers, any protected platform origin. */
985
+ function platformAccessOverlapsOrigins(application, origins) {
986
+ return platformAccessPublicDestinations(application).some((destination) => origins.some((origin) => platformAccessOverlapsOrigin(destination, origin)) && (destination.includes("/") || origins.some((origin) => destination === new URL(origin).hostname)));
987
+ }
988
+ /** A definitive 4xx means the create did not happen, so a retry may not find a hidden duplicate. */
989
+ function platformAccessCreateRejected(error) {
990
+ return error instanceof PlatformCloudflareApiError && error.status >= 400 && error.status < 500 && ![
991
+ 408,
992
+ 409,
993
+ 429
994
+ ].includes(error.status);
995
+ }
1000
996
  async function inspectPlatformAccess(client, input) {
1001
997
  const authDomain = text(object(await client.get("organizations"), "Access organization").auth_domain, "Access team domain");
1002
998
  const teamDomain = authDomain.startsWith("https://") ? authDomain : `https://${authDomain}`;
@@ -1031,7 +1027,6 @@ async function provisionPlatformAccess(client, input, previous, save) {
1031
1027
  if (url.origin !== value || url.protocol !== "https:") throw new Error("platform: Access requires exact HTTPS origins without credentials, paths, or query strings.");
1032
1028
  return url.origin;
1033
1029
  }))];
1034
- for (const origin of origins) if (!origin.startsWith("https://")) throw new Error("platform: Access protection requires HTTPS platform origins.");
1035
1030
  const state = previous ? structuredClone(previous) : {
1036
1031
  version: 1,
1037
1032
  accountId: input.accountId,
@@ -1063,7 +1058,7 @@ async function provisionPlatformAccess(client, input, previous, save) {
1063
1058
  }
1064
1059
  if (input.protection) for (const app of inventory) {
1065
1060
  if (app.id === input.protection.applicationId || app.id === state.resources.protection?.id || app.name === state.resources.protection?.name) continue;
1066
- if (platformAccessPublicDestinations(app).some((destination) => origins.some((origin) => platformAccessOverlapsOrigin(destination, origin)) && (destination.includes("/") || origins.some((origin) => destination === new URL(origin).hostname)))) throw new Error("platform: An existing Access application overlaps a platform endpoint. Connect or reconcile it explicitly before provisioning protection.");
1061
+ if (platformAccessOverlapsOrigins(app, origins)) throw new Error("platform: An existing Access application overlaps a platform endpoint. Connect or reconcile it explicitly before provisioning protection.");
1067
1062
  }
1068
1063
  const output = { resources: [] };
1069
1064
  const application = async (key, expected, existingId) => {
@@ -1118,11 +1113,7 @@ async function provisionPlatformAccess(client, input, previous, save) {
1118
1113
  save(state);
1119
1114
  return object(await client.get(`apps/${encodeURIComponent(checkpoint.id)}`), "Access application");
1120
1115
  } catch (error) {
1121
- if (error instanceof PlatformCloudflareApiError && error.status >= 400 && error.status < 500 && ![
1122
- 408,
1123
- 409,
1124
- 429
1125
- ].includes(error.status)) {
1116
+ if (platformAccessCreateRejected(error)) {
1126
1117
  checkpoint.pending = false;
1127
1118
  save(state);
1128
1119
  }
@@ -1277,295 +1268,6 @@ async function verifyPlatformAccessApplication(client, input, app, type, machine
1277
1268
  if (machineId && !currentPolicies.some((policy) => policy.decision === "non_identity")) throw new Error("platform: The platform service token is not admitted by Access.");
1278
1269
  }
1279
1270
  //#endregion
1280
- //#region src/cli/platform-setup.ts
1281
- function platformSetupLink(page, hyperlinks = supportsSetupLinks()) {
1282
- return hyperlinks ? "\x1B]8;;" + page.url + "\x1B\\" + import_picocolors.default.underline(page.title) + "\x1B]8;;\x1B\\" : page.title + ": " + import_picocolors.default.underline(page.url);
1283
- }
1284
- function platformSetupFieldHelp(key) {
1285
- const docs = (page, section, title) => platformSetupLink({
1286
- title,
1287
- url: `https://void.cloud/guide/platform/installation/${page}#${section}`
1288
- });
1289
- switch (key) {
1290
- case "databaseUrl": return {
1291
- placeholder: "postgresql://user:pw@…/database",
1292
- description: "Provide a PostgreSQL database URL for platform users, projects, and deployments. Use an empty hosted database, e.g. " + platformSetupLink({
1293
- title: "Neon",
1294
- url: "https://neon.com/"
1295
- }) + ". " + docs("prerequisites", "platform-database", "Database setup")
1296
- };
1297
- case "jwtSecret": return { description: `Create a JWT signing key for platform login tokens. Run ${import_picocolors.default.blue("openssl rand -base64 32")}. Save the key in your password manager. ` + docs("credentials", "signing-and-encryption-keys", "Key setup") };
1298
- case "projectSecretKey": return { description: `Generate a project encryption key for app secrets. Run ${import_picocolors.default.blue("openssl rand -base64 32")} separately. Save this key for recovery. ` + docs("credentials", "signing-and-encryption-keys", "Key setup") };
1299
- default: return;
1300
- }
1301
- }
1302
- function supportsSetupLinks() {
1303
- return !!process.stdout.isTTY && ([
1304
- "ghostty",
1305
- "iTerm.app",
1306
- "WezTerm",
1307
- "vscode",
1308
- "WarpTerminal"
1309
- ].includes(process.env.TERM_PROGRAM ?? "") || !!process.env.WT_SESSION || !!process.env.VTE_VERSION || !!process.env.KONSOLE_VERSION || process.env.TERM === "xterm-kitty");
1310
- }
1311
- /** Dashboard keys use permission-catalog labels, which can differ from product names. */
1312
- function platformAccountTokenPermissions(includeAiGateway) {
1313
- return [
1314
- {
1315
- key: "account_settings",
1316
- type: "read"
1317
- },
1318
- {
1319
- key: "workers_scripts",
1320
- type: "edit"
1321
- },
1322
- {
1323
- key: "workers_kv_storage",
1324
- type: "edit"
1325
- },
1326
- {
1327
- key: "workers_r2",
1328
- type: "edit"
1329
- },
1330
- {
1331
- key: "d1",
1332
- type: "edit"
1333
- },
1334
- {
1335
- key: "queues",
1336
- type: "edit"
1337
- },
1338
- {
1339
- key: "account_analytics",
1340
- type: "read"
1341
- },
1342
- {
1343
- key: "workers_tail",
1344
- type: "read"
1345
- },
1346
- {
1347
- key: "query_cache",
1348
- type: "edit"
1349
- },
1350
- ...includeAiGateway ? [{
1351
- key: "aig",
1352
- type: "edit"
1353
- }] : []
1354
- ];
1355
- }
1356
- /**
1357
- * Account token links cannot preselect a zone: Cloudflare documents only
1358
- * `permissionGroupKeys` and `name`, and the form puts zone permissions in an
1359
- * "All Domains" policy. Tell the user which dashboard choice to change.
1360
- */
1361
- function specifiedDomainsInstruction(zones) {
1362
- return `Change the zone policy from All Domains to Specified Domains → ${zones.join(" and ")}.`;
1363
- }
1364
- function plansZoneCreation(plan) {
1365
- return plan.actions.some((action) => action.kind === "zone" && action.action === "create");
1366
- }
1367
- function platformManagementSetupPage(plan, options = {}) {
1368
- const createsZone = plansZoneCreation(plan);
1369
- const zoneName = plan.deployment.application.zoneName;
1370
- const apiHostname = plan.deployment.controlPlane.apiHostname;
1371
- const access = options.access ?? (plan.deployment.authentication.accessProtection || plan.deployment.authentication.providers.includes("cloudflare-access") ? {
1372
- protection: !!plan.deployment.authentication.accessProtection,
1373
- readOnly: false
1374
- } : void 0);
1375
- const zones = [...zoneName ? [zoneName] : [], ...apiHostname && apiHostname !== zoneName && !apiHostname.endsWith(`.${zoneName}`) ? [`the zone for ${apiHostname}`] : []];
1376
- const accessLevel = access && access.readOnly ? "read" : "edit";
1377
- const appAccess = !!plan.deployment.appAccess;
1378
- const appAccessLevel = appAccess ? "edit" : accessLevel;
1379
- const permissions = [
1380
- ...platformAccountTokenPermissions(true),
1381
- ...zoneName || apiHostname || createsZone ? [
1382
- {
1383
- key: "zone",
1384
- type: createsZone ? "edit" : "read"
1385
- },
1386
- {
1387
- key: "dns",
1388
- type: "edit"
1389
- },
1390
- {
1391
- key: "workers_routes",
1392
- type: "edit"
1393
- }
1394
- ] : [],
1395
- ...access || appAccess ? [
1396
- {
1397
- key: "access",
1398
- type: appAccessLevel
1399
- },
1400
- {
1401
- key: "access_acct",
1402
- type: "read"
1403
- },
1404
- ...access && access.protection ? [{
1405
- key: "access_service_token",
1406
- type: accessLevel
1407
- }] : []
1408
- ] : [],
1409
- ...zoneName && plan.deployment.application.baseDomain !== zoneName ? [{
1410
- key: "ssl_and_certificates",
1411
- type: "read"
1412
- }] : []
1413
- ];
1414
- return {
1415
- title: "Cloudflare management API token",
1416
- linkInTitle: true,
1417
- url: "https://dash.cloudflare.com/?" + new URLSearchParams({
1418
- to: "/" + plan.account.id + "/api-tokens",
1419
- name: plan.deployment.displayName + " Management",
1420
- permissionGroupKeys: JSON.stringify(permissions)
1421
- }),
1422
- instructions: [
1423
- "This token lets the Void CLI install your platform. Void will now open a pre-configured token creation site. Please review the permissions and then paste the token here.",
1424
- `Scope it to ${plan.account.name}.`,
1425
- ...createsZone ? [`Keep the zone policy on All Domains so Void can create ${zoneName}.`] : zones.length ? [specifiedDomainsInstruction(zones)] : []
1426
- ].join("\n")
1427
- };
1428
- }
1429
- function platformSetupPages(plan) {
1430
- const permissions = [
1431
- ...platformAccountTokenPermissions(plan.actions.some((action) => action.kind === "ai-gateway" && action.action === "inspect")),
1432
- ...plan.deployment.application.zoneName ? [{
1433
- key: "cache",
1434
- type: "purge"
1435
- }] : [],
1436
- ...plan.deployment.capabilities.customDomains ? [{
1437
- key: "ssl_and_certificates",
1438
- type: "edit"
1439
- }] : [],
1440
- ...plan.deployment.capabilities.email ? [
1441
- {
1442
- key: "zone",
1443
- type: "read"
1444
- },
1445
- {
1446
- key: "zone_settings",
1447
- type: "edit"
1448
- },
1449
- {
1450
- key: "email_routing_address",
1451
- type: "edit"
1452
- },
1453
- {
1454
- key: "email_routing_rule",
1455
- type: "edit"
1456
- },
1457
- {
1458
- key: "email_sending",
1459
- type: "edit"
1460
- }
1461
- ] : []
1462
- ];
1463
- const zoneName = plan.deployment.application.zoneName;
1464
- return {
1465
- runtime: {
1466
- title: "Cloudflare runtime token",
1467
- linkInTitle: true,
1468
- url: "https://dash.cloudflare.com/?" + new URLSearchParams({
1469
- to: "/" + plan.account.id + "/api-tokens",
1470
- name: plan.deployment.displayName + " Runtime",
1471
- permissionGroupKeys: JSON.stringify(permissions)
1472
- }),
1473
- instructions: ["Create a Cloudflare runtime token that Void can use to manage the platform. Please review the permissions and then paste the token here.", ...zoneName && plansZoneCreation(plan) ? [`Keep the zone policy on All Domains so the token can purge cache on ${zoneName} after Void creates it.`] : zoneName ? [specifiedDomainsInstruction([zoneName, ...plan.deployment.capabilities.email ? ["every zone that will carry mail"] : []])] : []].join("\n")
1474
- },
1475
- github: {
1476
- title: "GitHub OAuth App",
1477
- url: "https://github.com/settings/applications/new",
1478
- instructions: "GitHub Auth will be used by the users of your Void Platform instance. Register a GitHub app and generate a client secret.\nHomepage: " + plan.apiUrl + "\nRedirect URI: " + plan.apiUrl + "/auth/callback"
1479
- },
1480
- r2: {
1481
- title: "R2 upload token",
1482
- url: "https://dash.cloudflare.com/?" + new URLSearchParams({
1483
- to: "/" + plan.account.id + "/r2/api-tokens/create",
1484
- type: "account"
1485
- }),
1486
- instructions: [
1487
- "Select Object Read & Write.",
1488
- "Keep Apply to all buckets in this account selected.",
1489
- "Create the token, then copy the Access Key ID and Secret Access Key into the CLI."
1490
- ].join("\n")
1491
- }
1492
- };
1493
- }
1494
- function formatPlatformSetupPlan(plan, options = {}) {
1495
- const writesDns = plan.actions.some((action) => action.kind === "zone" && action.action === "create" || action.kind === "dns-record" && action.action !== "reuse");
1496
- return [
1497
- "The installation will guide you through setting up the following credentials:",
1498
- "",
1499
- ...[
1500
- ...options.managementToken ? [options.managementAccess ? `Cloudflare management API token for ${writesDns ? "DNS changes and " : ""}Access setup` : "Cloudflare management API token for DNS changes"] : [],
1501
- "PostgreSQL database URL",
1502
- "Cloudflare runtime token",
1503
- "R2 upload token",
1504
- ...plan.deployment.authentication.providers.includes("github") ? ["GitHub OAuth App client ID and secret"] : [],
1505
- ...plan.deployment.authentication.providers.filter((provider) => provider !== "github").map((provider) => (provider === "google" ? "Google OAuth" : provider === "oidc" ? "OIDC" : "Cloudflare Access OIDC") + " client ID and secret"),
1506
- ...plan.deployment.authentication.accessProtection ? ["Cloudflare Access application and installer credentials"] : [],
1507
- ...plan.deployment.appAccess ? ["Cloudflare Access check and app-management token when needed (stored encrypted)"] : [],
1508
- "JWT signing key and project encryption key"
1509
- ].map((credential) => `• ${credential}`)
1510
- ].join("\n");
1511
- }
1512
- function platformInstallCommandArguments(options) {
1513
- const parts = [
1514
- options.commandName,
1515
- "platform",
1516
- "install"
1517
- ];
1518
- const flag = (name, value) => {
1519
- if (value) parts.push(name, value);
1520
- };
1521
- if (options.resumeId) {
1522
- parts.push("--resume");
1523
- flag("--name", options.resumeId);
1524
- } else {
1525
- flag("--name", options.installationSlug);
1526
- flag("--account", options.accountId);
1527
- flag("--display-name", options.displayName);
1528
- if (options.workersDev) parts.push("--workers-dev");
1529
- else {
1530
- flag("--application-domain", options.applicationDomain);
1531
- flag("--zone", options.zoneName);
1532
- if (options.dedicatedZone) parts.push("--dedicated-zone");
1533
- else parts.push("--no-dedicated-zone");
1534
- }
1535
- flag("--control-plane-domain", options.controlPlaneDomain);
1536
- if (!options.controlPlaneDomain) parts.push("--no-control-plane-domain");
1537
- }
1538
- flag("--hyperdrive", options.hyperdrive ?? "");
1539
- flag("--auth-config", options.authConfig ?? "");
1540
- if (!options.resumeId && options.appAccess) flag("--app-access", options.appAccess);
1541
- if (!options.authConfig && !options.resumeId && options.authentication) {
1542
- flag("--login-methods", options.authentication.providers.join(","));
1543
- parts.push(options.authentication.accessProtection ? "--access-protection" : "--no-access-protection");
1544
- }
1545
- flag("--dashboard-url", options.dashboardUrl ?? "");
1546
- flag("--runtime", options.runtime);
1547
- if (options.yes) parts.push("--yes");
1548
- return parts;
1549
- }
1550
- function formatPlatformInstallCommand(options) {
1551
- return platformInstallCommandArguments(options).map((value) => {
1552
- if (/^[A-Za-z0-9_@%+=:,./-]+$/.test(value)) return value;
1553
- return process.platform === "win32" ? `'${value.replaceAll("'", "''")}'` : `'${value.replaceAll("'", "'\\''")}'`;
1554
- }).join(" ");
1555
- }
1556
- function openPlatformSetupPage(page, dependencies = {}) {
1557
- log.info((page.linkInTitle ? platformSetupLink(page) : page.title) + "\n" + page.instructions);
1558
- if (!page.linkInTitle) console.log(platformSetupLink({
1559
- ...page,
1560
- title: "Open " + page.title
1561
- }));
1562
- if (dependencies.interactive ?? process.stdin.isTTY === true) try {
1563
- (dependencies.open ?? ((url) => openBrowser(url, execFile)))(page.url);
1564
- } catch {
1565
- log.info("Could not open the browser. Use the link above.");
1566
- }
1567
- }
1568
- //#endregion
1569
1271
  //#region src/cli/platform-access-setup.ts
1570
1272
  function accessSetupGuide() {
1571
1273
  return platformSetupLink({
@@ -1596,11 +1298,11 @@ async function selectCompanyAccessPolicies(client, initialPolicies, accountId, m
1596
1298
  let choices;
1597
1299
  if (options.length === 0) {
1598
1300
  log.info("No reusable Allow or Deny policies were found in this account. Create an Allow policy for your company, or refresh after saving one.");
1599
- choices = [answer$2(await select({
1301
+ choices = [platformPromptAnswer(await select({
1600
1302
  message: "Company Access policies:",
1601
1303
  options: actions
1602
1304
  }))];
1603
- } else choices = answer$2(await multiselect({
1305
+ } else choices = platformPromptAnswer(await multiselect({
1604
1306
  message: "Company Access policies (select all that apply):",
1605
1307
  options: [...options, ...actions],
1606
1308
  initialValues: selectedIds,
@@ -1619,7 +1321,7 @@ async function selectCompanyAccessPolicies(client, initialPolicies, accountId, m
1619
1321
  title: "Open Cloudflare account",
1620
1322
  url: `https://dash.cloudflare.com/${encodeURIComponent(accountId)}`
1621
1323
  }));
1622
- if (!answer$2(await confirm({
1324
+ if (!platformPromptAnswer(await confirm({
1623
1325
  message: "Have you saved the new policy?",
1624
1326
  initialValue: true
1625
1327
  }))) continue;
@@ -1700,10 +1402,6 @@ function parsePlatformAccessSetupSpec(input) {
1700
1402
  }
1701
1403
  return value;
1702
1404
  }
1703
- function answer$2(value) {
1704
- if (isCancel(value) || typeof value === "symbol") throw new Error("platform: Cancelled.");
1705
- return value;
1706
- }
1707
1405
  function secretReference(name) {
1708
1406
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name) || !process.env[name]) throw new Error("platform: Supply the referenced Access credential in the environment.");
1709
1407
  return process.env[name];
@@ -1742,7 +1440,7 @@ async function preparePlatformAccessSetup(input) {
1742
1440
  if (input.protection) throw new Error("platform: Protection requires cloudflareAccess create or existing application verification in --auth-config.");
1743
1441
  return;
1744
1442
  }
1745
- const mode = answer$2(await select({
1443
+ const mode = platformPromptAnswer(await select({
1746
1444
  message: "Cloudflare Access setup:",
1747
1445
  options: [
1748
1446
  {
@@ -1765,17 +1463,17 @@ async function preparePlatformAccessSetup(input) {
1765
1463
  spec = { mode };
1766
1464
  if (mode === "existing") {
1767
1465
  log.info("Enter the account that owns your company’s Access configuration. This may differ from the account hosting Void.");
1768
- spec.accountId = answer$2(await text$1({
1466
+ spec.accountId = platformPromptAnswer(await text$1({
1769
1467
  message: "Cloudflare identity account ID:",
1770
1468
  initialValue: input.plan.account.id
1771
1469
  }));
1772
1470
  if (input.login) {
1773
1471
  log.info("Enter the ID of the Access application that provides company sign-in to Void.");
1774
- spec.loginApplicationId = answer$2(await text$1({ message: "Existing Access OIDC application ID:" }));
1472
+ spec.loginApplicationId = platformPromptAnswer(await text$1({ message: "Existing Access OIDC application ID:" }));
1775
1473
  }
1776
1474
  if (input.protection) {
1777
1475
  log.info("Enter the ID of the Access application that protects the platform’s UI and APIs.");
1778
- spec.protectionApplicationId = answer$2(await text$1({ message: "Existing Access protection application ID:" }));
1476
+ spec.protectionApplicationId = platformPromptAnswer(await text$1({ message: "Existing Access protection application ID:" }));
1779
1477
  }
1780
1478
  }
1781
1479
  }
@@ -1795,7 +1493,7 @@ async function preparePlatformAccessSetup(input) {
1795
1493
  if (!(error instanceof PlatformCloudflareApiError) || ![401, 403].includes(error.status) || !process.stdin.isTTY || credential) throw error;
1796
1494
  log.info(`Your current token lacks the required Access permissions for account ${accountId}. Create a token for that account using the permissions in the setup guide.`);
1797
1495
  console.log(accessSetupGuide());
1798
- const token = answer$2(await password({ message: "Access setup API token:" }));
1496
+ const token = platformPromptAnswer(await password({ message: "Access setup API token:" }));
1799
1497
  input.save({ accessManagementToken: token });
1800
1498
  management = new PlatformCloudflareClient(token, { apiBase: input.client.apiBaseUrl });
1801
1499
  client = new PlatformAccessClient(management, accountId);
@@ -1804,7 +1502,7 @@ async function preparePlatformAccessSetup(input) {
1804
1502
  policies = await client.list("policies");
1805
1503
  }
1806
1504
  if (!spec.identityProviderIds && process.stdin.isTTY) log.info("Choose how employees sign in—for example, your company’s Okta or Google Workspace connection.");
1807
- const identityProviderIds = spec.identityProviderIds ?? (process.stdin.isTTY ? answer$2(await multiselect({
1505
+ const identityProviderIds = spec.identityProviderIds ?? (process.stdin.isTTY ? platformPromptAnswer(await multiselect({
1808
1506
  message: "Company identity providers:",
1809
1507
  required: true,
1810
1508
  options: providers.filter((provider) => typeof provider.id === "string").map(platformAccessIdentityProvider).map((provider) => ({
@@ -1839,9 +1537,9 @@ async function preparePlatformAccessSetup(input) {
1839
1537
  else if (process.stdin.isTTY) {
1840
1538
  log.info("This lets the installer reach the protected platform during setup. Use a service token allowed by the existing Access application.");
1841
1539
  serviceToken = {
1842
- id: answer$2(await text$1({ message: "Existing admitted Access service token ID:" })),
1843
- clientId: answer$2(await password({ message: "Access service token client ID:" })),
1844
- clientSecret: answer$2(await password({ message: "Access service token client secret:" }))
1540
+ id: platformPromptAnswer(await text$1({ message: "Existing admitted Access service token ID:" })),
1541
+ clientId: platformPromptAnswer(await password({ message: "Access service token client ID:" })),
1542
+ clientSecret: platformPromptAnswer(await password({ message: "Access service token client secret:" }))
1845
1543
  };
1846
1544
  input.save({ accessExistingServiceTokenJson: JSON.stringify(serviceToken) });
1847
1545
  }
@@ -1862,7 +1560,7 @@ async function preparePlatformAccessSetup(input) {
1862
1560
  };
1863
1561
  console.log(JSON.stringify({ accessPlan: reviewed }, null, 2));
1864
1562
  if (!input.yes) {
1865
- if (!process.stdin.isTTY || !answer$2(await confirm({
1563
+ if (!process.stdin.isTTY || !platformPromptAnswer(await confirm({
1866
1564
  message: "Apply this Access configuration?",
1867
1565
  initialValue: false
1868
1566
  }))) throw new Error("platform: Access setup changes require confirmation or --yes.");
@@ -1877,7 +1575,7 @@ async function preparePlatformAccessSetup(input) {
1877
1575
  let loginClientSecret = spec.loginClientSecretEnv ? secretReference(spec.loginClientSecretEnv) : input.checkpoint.accessExistingLoginSecret;
1878
1576
  if (input.login && spec.mode === "existing" && !loginClientSecret && process.stdin.isTTY) {
1879
1577
  log.info("Enter the client secret from the existing Access login application’s OIDC settings.");
1880
- loginClientSecret = answer$2(await password({ message: "Existing Access OIDC client secret:" }));
1578
+ loginClientSecret = platformPromptAnswer(await password({ message: "Existing Access OIDC client secret:" }));
1881
1579
  input.save({ accessExistingLoginSecret: loginClientSecret });
1882
1580
  }
1883
1581
  const result = await provisionPlatformAccess(client, {
@@ -1944,8 +1642,8 @@ async function verifyPlatformManagementAccess(client, accountId, access) {
1944
1642
  }
1945
1643
  function assertPlatformOperatorCredentialCanApplyPlan(credential, plan, access) {
1946
1644
  if (!platformOperatorNeedsManagementToken(credential, plan, access)) return;
1947
- const createsZone = plan.actions.some((action) => action.kind === "zone" && action.action === "create");
1948
- const writesDns = plan.actions.some((action) => action.kind === "dns-record" && action.action !== "reuse");
1645
+ const createsZone = planCreatesZone(plan);
1646
+ const writesDns = planWritesDns(plan);
1949
1647
  const permissions = [
1950
1648
  ...createsZone ? ["Account → Zone → Edit"] : [],
1951
1649
  ...writesDns ? ["Zone → DNS → Edit"] : [],
@@ -1958,7 +1656,13 @@ function assertPlatformOperatorCredentialCanApplyPlan(credential, plan, access)
1958
1656
  throw new Error(`platform: Cloudflare browser login cannot authorize the planned ${access ? "Access setup" : "zone or DNS changes"}. Set CLOUDFLARE_API_TOKEN with ${permissions.join(" and ")}, scoped to the selected account${createsZone || writesDns ? " and application zone" : ""}, then rerun the command.`);
1959
1657
  }
1960
1658
  function platformOperatorNeedsManagementToken(credential, plan, access) {
1961
- return credential.source === "oauth" && (!!access || plan.actions.some((action) => action.kind === "zone" && action.action === "create" || action.kind === "dns-record" && action.action !== "reuse"));
1659
+ return credential.source === "oauth" && (!!access || planCreatesZone(plan) || planWritesDns(plan));
1660
+ }
1661
+ function planCreatesZone(plan) {
1662
+ return plan.actions.some((action) => action.kind === "zone" && action.action === "create");
1663
+ }
1664
+ function planWritesDns(plan) {
1665
+ return plan.actions.some((action) => action.kind === "dns-record" && action.action !== "reuse");
1962
1666
  }
1963
1667
  async function resolvePlatformCloudflareCredential(dependencies = {}) {
1964
1668
  const { credential } = await resolvePlatformCloudflareCredentialWithInput(async () => void 0, dependencies);
@@ -2022,26 +1726,18 @@ async function readExistingCredential(dependencies, runWrangler) {
2022
1726
  if (!(dependencies.interactive ?? process.stdin.isTTY === true)) throw new Error("platform: Cloudflare authentication is required. Run `void cloudflare login` interactively, or set CLOUDFLARE_API_TOKEN in CI.");
2023
1727
  return await readWranglerOAuthCredential(runWrangler);
2024
1728
  }
2025
- async function readWranglerOAuthCredential(runWrangler = (args) => runCloudflareAuthCommand(process.cwd(), args)) {
1729
+ async function readWranglerOAuthCredential(runWrangler) {
2026
1730
  const result = await runWrangler({ type: "auth.token" }, true);
2027
1731
  if (result.status !== 0 || result.signal || result.error) return null;
2028
- try {
2029
- const parsed = result.data;
2030
- if (!parsed || parsed.type !== "oauth" || typeof parsed.token !== "string" || !parsed.token.trim()) return null;
2031
- return {
2032
- source: "oauth",
2033
- token: parsed.token.trim()
2034
- };
2035
- } catch {
2036
- return null;
2037
- }
1732
+ const parsed = result.data;
1733
+ if (!parsed || parsed.type !== "oauth" || typeof parsed.token !== "string" || !parsed.token.trim()) return null;
1734
+ return {
1735
+ source: "oauth",
1736
+ token: parsed.token.trim()
1737
+ };
2038
1738
  }
2039
1739
  //#endregion
2040
1740
  //#region src/cli/platform-app-access.ts
2041
- function answer$1(value) {
2042
- if (isCancel(value) || typeof value === "symbol") throw new Error("platform: Cancelled.");
2043
- return value;
2044
- }
2045
1741
  async function selectInstallationAppAccess(authentication, recorded, choice) {
2046
1742
  const config = authentication.file?.appAccess;
2047
1743
  if (config && (typeof config !== "object" || Array.isArray(config) || "apiToken" in config || config.tokenEnv !== void 0 && (typeof config.tokenEnv !== "string" || !/^[A-Z_][A-Z0-9_]*$/.test(config.tokenEnv)))) throw new Error("platform: App access configuration must use tokenEnv; plaintext tokens are not accepted.");
@@ -2057,7 +1753,7 @@ async function selectInstallationAppAccess(authentication, recorded, choice) {
2057
1753
  return recorded.appAccess;
2058
1754
  }
2059
1755
  const protectedPlatform = !!authentication.authentication.accessProtection;
2060
- const selected = supplied ?? (!process.stdin.isTTY ? protectedPlatform ? "platform" : "public" : answer$1(await select({
1756
+ const selected = supplied ?? (!process.stdin.isTTY ? protectedPlatform ? "platform" : "public" : platformPromptAnswer(await select({
2061
1757
  message: "Who should be able to access deployed apps?",
2062
1758
  initialValue: protectedPlatform ? "platform" : "public",
2063
1759
  options: [
@@ -2128,7 +1824,7 @@ async function prepareInstallationAppAccess(input) {
2128
1824
  const collectToken = async () => {
2129
1825
  if (!process.stdin.isTTY) throw new Error("platform: App access requires VOID_PLATFORM_APP_ACCESS_TOKEN or appAccess.tokenEnv in --auth-config, scoped to the hosting account.");
2130
1826
  tokenPage();
2131
- const value = String(answer$1(await password({ message: "App access API token (stored encrypted when app rules are needed):" }))).trim();
1827
+ const value = String(platformPromptAnswer(await password({ message: "App access API token (stored encrypted when app rules are needed):" }))).trim();
2132
1828
  if (!value || /\s/.test(value)) throw new Error("platform: An app access token without whitespace is required.");
2133
1829
  input.save({
2134
1830
  appAccessToken: value,
@@ -2172,7 +1868,7 @@ async function prepareInstallationAppAccess(input) {
2172
1868
  if (!organization) throw new Error(`platform: Enable Zero Trust in account ${input.plan.account.name}, then resume to configure app access.`);
2173
1869
  if (!token) {
2174
1870
  log.info("Void needs an Access-management token stored encrypted to manage access for future apps and custom domains.");
2175
- if (reusable && process.stdin.isTTY && answer$1(await confirm({
1871
+ if (reusable && process.stdin.isTTY && platformPromptAnswer(await confirm({
2176
1872
  message: "Reuse the setup token for ongoing app access management?",
2177
1873
  initialValue: true
2178
1874
  }))) {
@@ -2192,7 +1888,7 @@ async function prepareInstallationAppAccess(input) {
2192
1888
  if (!process.stdin.isTTY) throw new Error("platform: Set appAccess.identityProviderIds in --auth-config for the hosting account.");
2193
1889
  const providers = (await access.list("identity_providers")).map(platformAccessIdentityProvider);
2194
1890
  if (!providers.length) throw new Error(`platform: Add an identity provider in Zero Trust for ${input.plan.account.name}, then resume.`);
2195
- identityProviderIds = answer$1(await multiselect({
1891
+ identityProviderIds = platformPromptAnswer(await multiselect({
2196
1892
  message: "App identity providers:",
2197
1893
  required: true,
2198
1894
  options: providers.map((p) => ({
@@ -5227,11 +4923,7 @@ async function ensurePlatformAccessHealthChecks(input) {
5227
4923
  recorded.id = created.id;
5228
4924
  save();
5229
4925
  } catch (error) {
5230
- if (error instanceof PlatformCloudflareApiError && error.status >= 400 && error.status < 500 && ![
5231
- 408,
5232
- 409,
5233
- 429
5234
- ].includes(error.status)) {
4926
+ if (platformAccessCreateRejected(error)) {
5235
4927
  recorded.pending = false;
5236
4928
  save();
5237
4929
  }
@@ -5281,7 +4973,7 @@ async function verifyInstalledPlatformAccessProtection(input) {
5281
4973
  ].map((value) => new URL(value).origin).some((origin) => !origins.includes(origin)) || protection.applications.some((entry) => entry.audience !== app.aud || !platformAccessPublicDestinations(app).includes(new URL(entry.origin).hostname))) throw new Error("platform: Access audiences and complete origin coverage must match the active platform protection. Restore the current Access checkpoint or repair its applications.");
5282
4974
  for (const other of await access.list("apps")) {
5283
4975
  if (other.id === app.id) continue;
5284
- if (platformAccessPublicDestinations(other).some((destination) => origins.some((origin) => platformAccessOverlapsOrigin(destination, origin)) && (destination.includes("/") || origins.some((origin) => destination === new URL(origin).hostname)))) throw new Error("platform: Another Access application overlaps a protected platform origin. Reconcile it before maintenance.");
4976
+ if (platformAccessOverlapsOrigins(other, origins)) throw new Error("platform: Another Access application overlaps a protected platform origin. Reconcile it before maintenance.");
5285
4977
  }
5286
4978
  const liveToken = (await access.list("service_tokens")).find((entry) => entry.id === service.id);
5287
4979
  const expiry = liveToken?.expires_at;
@@ -5292,7 +4984,7 @@ async function verifyInstalledPlatformAccessProtection(input) {
5292
4984
  }
5293
4985
  const existingWorkers = input.plan.actions.filter((action) => action.kind === "worker" && action.action === "update").map((action) => action.name);
5294
4986
  if (existingWorkers.length) {
5295
- const { verifyProtectionWorkerOrigins } = await import("./platform-auth-protection-DcbL_LW_.mjs");
4987
+ const { verifyProtectionWorkerOrigins } = await import("./platform-auth-protection-BJimB_p9.mjs");
5296
4988
  await verifyProtectionWorkerOrigins({
5297
4989
  request: input.client.request.bind(input.client),
5298
4990
  listWorkerDomains: input.client.listWorkerDomains.bind(input.client),
@@ -7813,10 +7505,6 @@ function platformManagementAccessForAuthentication(selection, accountId, checkpo
7813
7505
  readOnly: spec?.mode === "existing"
7814
7506
  };
7815
7507
  }
7816
- function answer(value) {
7817
- if (isCancel(value) || typeof value === "symbol") throw new Error("platform: Cancelled.");
7818
- return value;
7819
- }
7820
7508
  async function selectInstallationAuthentication(file, recorded, choices = {}) {
7821
7509
  if (file) {
7822
7510
  const input = JSON.parse(await readFile(file, "utf8"));
@@ -7841,7 +7529,7 @@ async function selectInstallationAuthentication(file, recorded, choices = {}) {
7841
7529
  return { authentication: recorded };
7842
7530
  }
7843
7531
  if (!process.stdin.isTTY && !choices.loginMethods && choices.accessProtection === void 0) return { authentication: { providers: ["github"] } };
7844
- const providers = choices.loginMethods ?? (!process.stdin.isTTY ? ["github"] : answer(await multiselect({
7532
+ const providers = choices.loginMethods ?? (!process.stdin.isTTY ? ["github"] : platformPromptAnswer(await multiselect({
7845
7533
  message: "Platform login methods (select all that apply):",
7846
7534
  initialValues: [],
7847
7535
  required: true,
@@ -7864,7 +7552,7 @@ async function selectInstallationAuthentication(file, recorded, choices = {}) {
7864
7552
  }
7865
7553
  ]
7866
7554
  })));
7867
- const protection = choices.accessProtection ?? (!process.stdin.isTTY ? false : answer(await confirm({
7555
+ const protection = choices.accessProtection ?? (!process.stdin.isTTY ? false : platformPromptAnswer(await confirm({
7868
7556
  message: "Also protect the platform UI and APIs with Cloudflare Access?",
7869
7557
  initialValue: false
7870
7558
  })));
@@ -7887,7 +7575,7 @@ async function collectInstallationAuthentication(selection, plan, checkpoint, sa
7887
7575
  }
7888
7576
  const prompt = async (message, initialValue = "", masked = false) => {
7889
7577
  if (!process.stdin.isTTY) throw new Error(`platform: ${message} Supply it through --auth-config and environment references.`);
7890
- return masked ? answer(await password({ message })) : answer(await text$1({
7578
+ return masked ? platformPromptAnswer(await password({ message })) : platformPromptAnswer(await text$1({
7891
7579
  message,
7892
7580
  initialValue
7893
7581
  }));
@@ -7954,7 +7642,7 @@ async function collectInstallationAuthentication(selection, plan, checkpoint, sa
7954
7642
  save({ [partialKey]: JSON.stringify(connection) });
7955
7643
  connections.push(connection);
7956
7644
  }
7957
- const administratorConnectionId = selection.file?.administratorConnectionId ?? (connections.length === 1 ? connections[0].configuration.id : process.stdin.isTTY ? answer(await select({
7645
+ const administratorConnectionId = selection.file?.administratorConnectionId ?? (connections.length === 1 ? connections[0].configuration.id : process.stdin.isTTY ? platformPromptAnswer(await select({
7958
7646
  message: "Login method for the first administrator:",
7959
7647
  options: connections.map((entry) => ({
7960
7648
  value: entry.configuration.id,
@@ -7985,7 +7673,7 @@ async function collectInstallationAuthentication(selection, plan, checkpoint, sa
7985
7673
  } : { mode: "restricted" });
7986
7674
  if (!selection.file && !protection && process.stdin.isTTY) {
7987
7675
  const eligible = connections.filter((entry) => entry.configuration.kind !== "github" && (entry.configuration.kind !== "google" || entry.configuration.allowedDomains.length > 0));
7988
- const mode = answer(await select({
7676
+ const mode = platformPromptAnswer(await select({
7989
7677
  message: "Who can create an account?",
7990
7678
  initialValue: eligible.length ? "company" : "restricted",
7991
7679
  options: [
@@ -8003,7 +7691,7 @@ async function collectInstallationAuthentication(selection, plan, checkpoint, sa
8003
7691
  }
8004
7692
  ]
8005
7693
  }));
8006
- const ids = mode === "company" ? answer(await multiselect({
7694
+ const ids = mode === "company" ? platformPromptAnswer(await multiselect({
8007
7695
  message: "Company login methods that qualify new users:",
8008
7696
  required: true,
8009
7697
  initialValues: eligible.map((entry) => entry.configuration.id),
@@ -8188,24 +7876,25 @@ function resolvePlatformInstallDatabaseUrl(checkpoint, manifest = null) {
8188
7876
  }
8189
7877
  async function runPlatformLifecycleCommand(commandArgs) {
8190
7878
  if (commandArgs.subcommand === "domain") {
8191
- const { runPlatformDomainCommand } = await import("./platform-domain-Bsq43AJp.mjs");
7879
+ const { runPlatformDomainCommand } = await import("./platform-domain-CHVS6cV0.mjs");
8192
7880
  await runPlatformDomainCommand(commandArgs);
8193
7881
  return;
8194
7882
  }
8195
7883
  if (commandArgs.subcommand === "discover") {
8196
7884
  const client = new PlatformCloudflareClient((await resolvePlatformCloudflareCredential()).token);
8197
7885
  const accountId = await selectAccount(await readAccounts(client), commandArgs.account);
8198
- const { recoverPlatformInstallations } = await import("./platform-recovery-DQAqAQYu.mjs");
7886
+ const { recoverPlatformInstallations } = await import("./platform-recovery-CskSJgLh.mjs");
8199
7887
  const recovered = await recoverPlatformInstallations(client, accountId, void 0, commandArgs.selector);
8200
7888
  if (recovered.length === 0) {
8201
7889
  log.info(`No recoverable Void platform installations were found in ${accountId}.`);
8202
7890
  return;
8203
7891
  }
8204
- for (const manifest of recovered) log.success(`Recovered ${manifest.deployment.displayName} (${manifest.id}) at ${manifest.endpoints.apiUrl}.`);
7892
+ for (const manifest of recovered) log.step(`Recovered ${manifest.deployment.displayName} (${manifest.id}) at ${manifest.endpoints.apiUrl}.`);
7893
+ printSuccess(`Recovered ${recovered.length} platform installation${recovered.length === 1 ? "" : "s"}.`);
8205
7894
  return;
8206
7895
  }
8207
7896
  if (commandArgs.subcommand !== "install") {
8208
- const { runInstalledPlatformCommand } = await import("./platform-management-Bbwf6-Dq.mjs");
7897
+ const { runInstalledPlatformCommand } = await import("./platform-management-CBOT4BSM.mjs");
8209
7898
  await runInstalledPlatformCommand(commandArgs);
8210
7899
  return;
8211
7900
  }
@@ -8378,7 +8067,7 @@ async function runPlatformLifecycleCommand(commandArgs) {
8378
8067
  progress?.stop("Read the saved installation.");
8379
8068
  progress = void 0;
8380
8069
  if (authoritative) {
8381
- const { selectAuthoritativePlatformManifest } = await import("./platform-management-Bbwf6-Dq.mjs");
8070
+ const { selectAuthoritativePlatformManifest } = await import("./platform-management-CBOT4BSM.mjs");
8382
8071
  const selected = selectAuthoritativePlatformManifest(existing, authoritative);
8383
8072
  authoritativeProvisionIntents = true;
8384
8073
  if (!args.plan && JSON.stringify(selected) !== JSON.stringify(existing)) writeInstallationManifest(selected);
@@ -8783,7 +8472,7 @@ async function runPlatformLifecycleCommand(commandArgs) {
8783
8472
  })).actions.filter((action) => action.kind === "worker"),
8784
8473
  revalidateBeforeWorkerDeploy: (manifest, action) => revalidatePlatformInstallAction(client, plan, manifest, action),
8785
8474
  verifyExistingOwnership: async (manifest, databaseCheckpointExists) => {
8786
- const { verifyPlatformInstallationOwnership } = await import("./platform-management-Bbwf6-Dq.mjs");
8475
+ const { verifyPlatformInstallationOwnership } = await import("./platform-management-CBOT4BSM.mjs");
8787
8476
  const retainedReplacementKeys = new Set(plan.actions.filter((action) => {
8788
8477
  const previous = manifest.resources.find((resource) => resource.key === action.key);
8789
8478
  return action.action === "create" && previous && previous.name !== action.name;
@@ -8807,7 +8496,6 @@ async function runPlatformLifecycleCommand(commandArgs) {
8807
8496
  outro(`Installation ${result.manifest.id} is safely checkpointed.`);
8808
8497
  return;
8809
8498
  }
8810
- log.success(`${result.manifest.deployment.displayName} is installed at ${new URL("/admin", plan.apiUrl).href}.`);
8811
8499
  log.info(`API URL: ${plan.apiUrl}`);
8812
8500
  if (result.emailOperationId) log.info(`Shared email routing ready. Operation: ${result.emailOperationId}.`);
8813
8501
  const completedAuthCode = readInstallationRecoverySecrets(result.manifest)?.authBootstrapCode;
@@ -8817,7 +8505,8 @@ async function runPlatformLifecycleCommand(commandArgs) {
8817
8505
  log.info("Confirm your identity in the browser, then test and enable any additional login methods in Settings.");
8818
8506
  }
8819
8507
  if (!plan.deployment.application.zoneName) log.info("Apps will use workers.dev addresses. When your domain is ready: void platform domain set <domain>");
8820
- outro("Run `void account login`, then deploy an app with `void deploy --platform void`.");
8508
+ log.info("Run `void account login`, then deploy an app with `void deploy --platform void`.");
8509
+ printSuccess(`${result.manifest.deployment.displayName} is installed at ${new URL("/admin", plan.apiUrl).href}.`);
8821
8510
  } catch (error) {
8822
8511
  progress?.error("Platform installation failed.");
8823
8512
  progress = void 0;