void 0.10.13 → 0.20.1

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 (432) hide show
  1. package/AGENTS_TEMPLATE.md +6 -0
  2. package/{skills/void/docs/node_modules/void/node_modules/pglite-server/LICENSE.md → LICENSE} +1 -1
  3. package/README.md +34 -8
  4. package/dist/{auth-qgMlYp7Z.d.mts → auth-DkcFflXV.d.mts} +10 -11
  5. package/dist/auth-W9WII-mN.mjs +630 -0
  6. package/dist/{auth-cmd-BqsdZJp5.mjs → auth-cmd-CAH62yDU.mjs} +4 -3
  7. package/dist/{auth-migrations-BTZ-ATvQ.mjs → auth-migrations-9vif1uj8.mjs} +53 -12
  8. package/dist/{better-auth-shared-BQooDxbw.mjs → better-auth-shared-CYw1T3k4.mjs} +7 -10
  9. package/dist/{better-auth-shared-DealXecJ.d.mts → better-auth-shared-DSCeohOK.d.mts} +10 -5
  10. package/dist/{build-cmd-Bujrv5q-.mjs → build-cmd-CJvZvPQO.mjs} +6 -4
  11. package/dist/{cache-C11V8Fxq.mjs → cache-BlNeQjuP.mjs} +9 -5
  12. package/dist/{cancel-deploy-fwFYF04b.mjs → cancel-deploy-CmlAZ9P6.mjs} +3 -2
  13. package/dist/cf-access-AJ1ehiFR.mjs +42 -0
  14. package/dist/cf-access-DsSsZUPr.mjs +67 -0
  15. package/dist/cli/cli.d.mts +1 -1
  16. package/dist/cli/cli.mjs +1735 -165
  17. package/dist/cli/env-schema-probe.d.mts +48 -61
  18. package/dist/cli/env-schema-probe.mjs +10 -58
  19. package/dist/{client-Gb71-XkG.mjs → client-Clirrol3.mjs} +120 -463
  20. package/dist/cloudflare-auth-B1QtTO1b.mjs +217 -0
  21. package/dist/cloudflare-cmd-B6_OZx2V.mjs +62 -0
  22. package/dist/cloudflare-connect-j5D4hhrG.mjs +56 -0
  23. package/dist/cloudflare-operations-CPTpRW6d.mjs +566 -0
  24. package/dist/{config-qHGgPuWT.mjs → config-BQFq7QvD.mjs} +75 -41
  25. package/dist/{config-CutEMNGJ.mjs → config-NOG_U1aK.mjs} +10 -15
  26. package/dist/connect-C04Wdy_h.mjs +79 -0
  27. package/dist/{create-project-DsYvl3TB.mjs → create-project-ChGZ1DFd.mjs} +26 -16
  28. package/dist/database-provider.d.mts +21 -0
  29. package/dist/database-provider.mjs +6 -0
  30. package/dist/{db-C0i0sYMS.mjs → db-D2d_mUsB.mjs} +612 -117
  31. package/dist/{delete-mh6p-zkQ.mjs → delete-D8GigDk8.mjs} +9 -6
  32. package/dist/{deploy-jBJT1fUT.mjs → deploy-iXZ3F0N6.mjs} +3252 -1995
  33. package/dist/dev-inbox-DkgRWLkW.mjs +307 -0
  34. package/dist/{discover-CJHyvYfR.mjs → discover-xvfrgJeo.mjs} +3 -3
  35. package/dist/{magic-string.es-ZQjdJFFn.mjs → dist-BR1quN_w.mjs} +570 -216
  36. package/dist/{dist-DaKKDf8D.mjs → dist-BrsS7cai.mjs} +17 -2
  37. package/dist/{dist-BuiRJkTd.mjs → dist-m40_XgNh.mjs} +48 -33
  38. package/dist/{domain-DiaNQbrl.mjs → domain-B1VmoSr0.mjs} +41 -4
  39. package/dist/dotenv-VQxupEUv.mjs +181 -0
  40. package/dist/edge.d.mts +2 -0
  41. package/dist/edge.mjs +2 -0
  42. package/dist/email-Ce6SQq-i.mjs +182 -0
  43. package/dist/email-uKyQYUVY.mjs +1016 -0
  44. package/dist/{entry-D7yy4xVH.mjs → entry-DU3oDoQ3.mjs} +2 -2
  45. package/dist/env-BcQzYgoG.mjs +73 -0
  46. package/dist/env-D4Emu-M_.mjs +95 -0
  47. package/dist/env-helpers-CyKtOBpj.d.mts +22 -0
  48. package/dist/env-public-D_6u46fX.d.mts +135 -0
  49. package/dist/{env-types-QBj-ndax.mjs → env-types-BNPhro-M.mjs} +2 -2
  50. package/dist/{env-validation-Dea3v3ej.mjs → env-validation-ENpMy6Ez.mjs} +68 -122
  51. package/dist/{gen-BzXf3Jh2.mjs → gen-DI2YwdBM.mjs} +70 -15
  52. package/dist/generate-RTK8_kK1.mjs +47 -0
  53. package/dist/{github-cmd-DKcGUNsj.mjs → github-cmd-xItS5Zwf.mjs} +39 -31
  54. package/dist/{handler-Cjh8uM3Y.d.mts → handler-D1hLsObx.d.mts} +124 -122
  55. package/dist/{head-nmvOgFjd.d.mts → head-Do8P4puT.d.mts} +9 -8
  56. package/dist/{headers-ChAADPQu.mjs → headers-D8QfRX9Y.mjs} +12 -10
  57. package/dist/inbound-2d0zi2yS.mjs +706 -0
  58. package/dist/inbound-afAcWeQ9.d.mts +363 -0
  59. package/dist/index.d.mts +61 -34
  60. package/dist/index.mjs +1012 -293
  61. package/dist/{init-7JCAcKNQ.mjs → init-BD-9THgn.mjs} +329 -271
  62. package/dist/link-RMdgjF1v.mjs +52 -0
  63. package/dist/{list-CPwFDZ_c.mjs → list-3F52R_yO.mjs} +37 -5
  64. package/dist/{runner-kapo9aPs.mjs → local-d1-D2I6Ox5F.mjs} +116 -6
  65. package/dist/{login-BT3H8PN3.mjs → login-pV69H-ZO.mjs} +17 -15
  66. package/dist/{logs-Bt313ax7.mjs → logs-DFHHD6wE.mjs} +16 -2
  67. package/dist/mime-BJD7d_qL.mjs +1216 -0
  68. package/dist/neon-DHwd2zvC.mjs +54 -0
  69. package/dist/{node-pRg81HqV.mjs → node-Dk3H2jmU.mjs} +29 -8
  70. package/dist/operator-cmd-DYWRbWUA.mjs +348 -0
  71. package/dist/{agents-CtgBYqld.mjs → output-tFQLLj26.mjs} +676 -211
  72. package/dist/{package-json-Cx1osYo6.mjs → package-json-CPoWX79C.mjs} +1 -1
  73. package/dist/pages/client.d.mts +43 -41
  74. package/dist/pages/client.mjs +40 -33
  75. package/dist/pages/head-client.d.mts +10 -12
  76. package/dist/pages/head.d.mts +1 -1
  77. package/dist/pages/index.d.mts +37 -14
  78. package/dist/pages/index.mjs +5 -5
  79. package/dist/pages/islands-plugin.d.mts +25 -27
  80. package/dist/pages/islands-plugin.mjs +6 -4
  81. package/dist/pages/prefetch.d.mts +6 -7
  82. package/dist/pages/protocol.d.mts +2 -2
  83. package/dist/pages/protocol.mjs +2 -1
  84. package/dist/pages/serialize.d.mts +7 -8
  85. package/dist/platform-cmd-DxJ2FRwR.mjs +123 -0
  86. package/dist/platform-domain-ChvbJkdy.mjs +228 -0
  87. package/dist/platform-lifecycle-DN4MzJF_.mjs +4450 -0
  88. package/dist/platform-management-Db2PXw0B.mjs +698 -0
  89. package/dist/platform-recovery-C_YO-tIs.mjs +99 -0
  90. package/dist/{plugin-inference-DMeavIJ6.mjs → plugin-inference-BDRfZngg.mjs} +35 -19
  91. package/dist/prepare-BfJvFUtJ.mjs +14 -0
  92. package/dist/{prepare-BvvgAz-3.mjs → prepare-CBetXvsN.mjs} +15 -24
  93. package/dist/{preset-BjyR3lzz.mjs → preset-lAy0B0BQ.mjs} +25 -212
  94. package/dist/{project-cmd-D_w-4w5B.mjs → project-cmd-Mo0V9yKS.mjs} +25 -12
  95. package/dist/{project-paths-BQd7OmIo.mjs → project-paths-SK8nMHPp.mjs} +3 -1
  96. package/dist/{project-tsconfig-B-QtXjLQ.mjs → project-tsconfig-Ql2XsSQp.mjs} +2 -2
  97. package/dist/{protocol-Bnb0LFp3.d.mts → protocol-C-pqYJjE.d.mts} +3 -4
  98. package/dist/{provision-CPx2ZxsH.mjs → provision-Blnstcm2.mjs} +78 -45
  99. package/dist/r2-conditions-D1Wk8i7b.mjs +30 -0
  100. package/dist/{requests-B8sZxaFM.mjs → requests-BcKOVpRg.mjs} +5 -3
  101. package/dist/{resolve-project-BBMtLLV9.mjs → resolve-project--Vxawf7z.mjs} +2 -2
  102. package/dist/rollback-Bx85-0xh.mjs +166 -0
  103. package/dist/{rolldown-runtime-DJK8HYOj.mjs → rolldown-runtime-rQ84J-ij.mjs} +1 -1
  104. package/dist/{route-types-z1jtHEi_.mjs → route-types-Da-DpyUp.mjs} +77 -25
  105. package/dist/routes-stub.d.mts +22 -23
  106. package/dist/runner-mysql-7BPUNGmL.mjs +61 -0
  107. package/dist/{runner-pg-CHM76xuC.mjs → runner-pg-BkEza-dX.mjs} +18 -6
  108. package/dist/runtime/ai.d.mts +21 -14
  109. package/dist/runtime/ai.mjs +5 -4
  110. package/dist/runtime/auth-client-react.d.mts +3 -5
  111. package/dist/runtime/auth-client-solid.d.mts +3 -5
  112. package/dist/runtime/auth-client-svelte.d.mts +3 -5
  113. package/dist/runtime/auth-client-vue.d.mts +3 -5
  114. package/dist/runtime/auth-client.d.mts +3 -5
  115. package/dist/runtime/auth.d.mts +1 -1
  116. package/dist/runtime/better-auth-mysql.d.mts +10 -0
  117. package/dist/runtime/better-auth-mysql.mjs +49 -0
  118. package/dist/runtime/better-auth-pg.d.mts +8 -9
  119. package/dist/runtime/better-auth-pg.mjs +2 -2
  120. package/dist/runtime/better-auth.d.mts +8 -9
  121. package/dist/runtime/better-auth.mjs +2 -2
  122. package/dist/runtime/client-react.d.mts +1 -1
  123. package/dist/runtime/client-solid.d.mts +1 -1
  124. package/dist/runtime/client-svelte.d.mts +1 -1
  125. package/dist/runtime/client-vue.d.mts +1 -1
  126. package/dist/runtime/client.d.mts +1 -1
  127. package/dist/runtime/db-mysql.d.mts +2 -0
  128. package/dist/runtime/db-mysql.mjs +1 -0
  129. package/dist/runtime/db.d.mts +10 -11
  130. package/dist/runtime/durable.d.mts +47 -0
  131. package/dist/runtime/durable.mjs +146 -0
  132. package/dist/runtime/email/testing.d.mts +112 -0
  133. package/dist/runtime/email/testing.mjs +283 -0
  134. package/dist/runtime/email.d.mts +30 -0
  135. package/dist/runtime/email.mjs +573 -0
  136. package/dist/runtime/env-helpers.d.mts +2 -2
  137. package/dist/runtime/env-helpers.mjs +5 -42
  138. package/dist/runtime/env-public-client.d.mts +10 -11
  139. package/dist/runtime/env-public-client.mjs +1 -1
  140. package/dist/runtime/env-public.d.mts +2 -2
  141. package/dist/runtime/env-public.mjs +104 -49
  142. package/dist/runtime/env.d.mts +19 -18
  143. package/dist/runtime/env.mjs +15 -2
  144. package/dist/runtime/fetch-stream.d.mts +20 -21
  145. package/dist/runtime/fetch.d.mts +15 -16
  146. package/dist/runtime/handler.d.mts +1 -1
  147. package/dist/runtime/isr.d.mts +21 -22
  148. package/dist/runtime/isr.mjs +26 -8
  149. package/dist/runtime/kv.d.mts +9 -10
  150. package/dist/runtime/live-client.d.mts +5 -7
  151. package/dist/runtime/live-client.mjs +9 -7
  152. package/dist/runtime/live-server.d.mts +4 -5
  153. package/dist/runtime/live.d.mts +22 -24
  154. package/dist/runtime/live.mjs +1 -1
  155. package/dist/runtime/log.d.mts +16 -17
  156. package/dist/runtime/migration-handler-mysql.d.mts +4 -0
  157. package/dist/runtime/migration-handler-mysql.mjs +81 -0
  158. package/dist/runtime/migration-handler-pg.d.mts +2 -4
  159. package/dist/runtime/migration-handler.d.mts +5 -6
  160. package/dist/runtime/migration-handler.mjs +4 -3
  161. package/dist/runtime/queues.d.mts +3 -4
  162. package/dist/runtime/queues.mjs +2 -1
  163. package/dist/runtime/remote/binding-handler.d.mts +10 -12
  164. package/dist/runtime/remote/binding-handler.mjs +24 -3
  165. package/dist/runtime/remote/index.d.mts +5 -6
  166. package/dist/runtime/remote/index.mjs +21 -18
  167. package/dist/runtime/response.d.mts +10 -11
  168. package/dist/runtime/sandbox.d.mts +56 -55
  169. package/dist/runtime/sandbox.mjs +57 -49
  170. package/dist/runtime/schema-mysql.d.mts +1 -0
  171. package/dist/runtime/schema-mysql.mjs +2 -0
  172. package/dist/runtime/seed.d.mts +14 -9
  173. package/dist/runtime/sse-client.d.mts +6 -7
  174. package/dist/runtime/sse.d.mts +11 -12
  175. package/dist/runtime/storage.d.mts +3 -4
  176. package/dist/runtime/validator.d.mts +1 -1
  177. package/dist/runtime/ws-server.d.mts +12 -12
  178. package/dist/runtime/ws-server.mjs +32 -4
  179. package/dist/runtime/ws.d.mts +19 -21
  180. package/dist/{scan-ChWt4pX1.mjs → scan-BMH4rzlv.mjs} +42 -19
  181. package/dist/{scan-NU4xKGci.mjs → scan-CpK-57ug.mjs} +5 -4
  182. package/dist/{secret-Dt32J6RI.mjs → secret-ByhJ9AMl.mjs} +62 -5
  183. package/dist/{skills-CLjN0uUO.mjs → skills-Q46GZMO-.mjs} +6 -4
  184. package/dist/sqlite-validation-BzKMWnO4.mjs +25 -0
  185. package/dist/{standard-schema-DJ0HW7QP.d.mts → standard-schema-Fo_vCAZh.d.mts} +6 -6
  186. package/dist/{subcommand-prompt-BzV8iQZo.mjs → subcommand-prompt-WfySCQ7S.mjs} +67 -48
  187. package/dist/sveltekit.d.mts +12 -11
  188. package/dist/sveltekit.mjs +1 -1
  189. package/dist/types-BAp5AEBU.d.mts +79 -0
  190. package/dist/types-CKWnYgfy.d.mts +1 -0
  191. package/dist/{validate-Cw_RLeTj.mjs → validate-tBBN_dXH.mjs} +4 -3
  192. package/dist/wrangler--imS8n0d.mjs +1796 -0
  193. package/dist/{yarn-pnp-DJn3SAHF.mjs → yarn-pnp-DxSInkzL.mjs} +1 -1
  194. package/package.json +79 -65
  195. package/schema.json +22 -3
  196. package/skills/void/SKILL.md +59 -2
  197. package/skills/void/docs/guide/ai.md +32 -14
  198. package/skills/void/docs/guide/app-types.md +6 -6
  199. package/skills/void/docs/guide/auth.md +14 -16
  200. package/skills/void/docs/guide/database/d1.md +6 -0
  201. package/skills/void/docs/guide/database/mysql.md +60 -0
  202. package/skills/void/docs/guide/database/postgresql.md +14 -9
  203. package/skills/void/docs/guide/database.md +39 -26
  204. package/skills/void/docs/guide/deployment.md +99 -25
  205. package/skills/void/docs/guide/durable-state.md +140 -0
  206. package/skills/void/docs/guide/edge/headers.md +5 -5
  207. package/skills/void/docs/guide/edge/prerendering.md +2 -0
  208. package/skills/void/docs/guide/edge/revalidation.md +21 -6
  209. package/skills/void/docs/guide/edge/rewrites.md +18 -14
  210. package/skills/void/docs/guide/edge/static-assets.md +12 -10
  211. package/skills/void/docs/guide/email.md +640 -0
  212. package/skills/void/docs/guide/env-migration.md +109 -0
  213. package/skills/void/docs/guide/env-vars.md +70 -248
  214. package/skills/void/docs/guide/index.md +15 -17
  215. package/skills/void/docs/guide/jobs.md +8 -5
  216. package/skills/void/docs/guide/live.md +7 -15
  217. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +8 -4
  218. package/skills/void/docs/guide/pages-routing/islands.md +3 -3
  219. package/skills/void/docs/guide/pages-routing/loaders.md +6 -4
  220. package/skills/void/docs/guide/pages-routing/overview.md +7 -7
  221. package/skills/void/docs/guide/platform-administration.md +212 -0
  222. package/skills/void/docs/guide/platform-development.md +264 -0
  223. package/skills/void/docs/guide/queues.md +10 -10
  224. package/skills/void/docs/guide/quickstart.md +46 -67
  225. package/skills/void/docs/guide/remote-dev.md +8 -6
  226. package/skills/void/docs/guide/sandboxes.md +33 -16
  227. package/skills/void/docs/guide/self-hosted-platform.md +553 -0
  228. package/skills/void/docs/guide/server-routing.md +5 -5
  229. package/skills/void/docs/guide/sse.md +4 -4
  230. package/skills/void/docs/guide/ssg.md +5 -3
  231. package/skills/void/docs/guide/storage.md +2 -2
  232. package/skills/void/docs/guide/websockets.md +15 -7
  233. package/skills/void/docs/index.md +3 -3
  234. package/skills/void/docs/integrations/agents.md +6 -64
  235. package/skills/void/docs/integrations/cloudflare.md +165 -146
  236. package/skills/void/docs/integrations/frameworks/analog.md +4 -4
  237. package/skills/void/docs/integrations/frameworks/astro.md +5 -5
  238. package/skills/void/docs/integrations/frameworks/nuxt.md +5 -5
  239. package/skills/void/docs/integrations/frameworks/overview.md +3 -3
  240. package/skills/void/docs/integrations/frameworks/react-router.md +3 -3
  241. package/skills/void/docs/integrations/frameworks/sveltekit.md +3 -3
  242. package/skills/void/docs/integrations/frameworks/tanstack-start.md +2 -2
  243. package/skills/void/docs/integrations/nodejs-bun-deno.md +11 -4
  244. package/skills/void/docs/reference/api.md +42 -6
  245. package/skills/void/docs/reference/cli.md +665 -160
  246. package/skills/void/docs/reference/config.md +67 -27
  247. package/skills/void/docs/reference/resource-inference.md +13 -9
  248. package/skills/void/docs/reference/structure.md +9 -11
  249. package/AGENT_PROMPT.md +0 -19
  250. package/dist/cf-access-Bqw81xAf.mjs +0 -22
  251. package/dist/env-CZy5MorI.mjs +0 -299
  252. package/dist/env-helpers-z4stu8uc.d.mts +0 -52
  253. package/dist/env-mask-Dd47NbR6.mjs +0 -90
  254. package/dist/env-public-BfiLcMBk.d.mts +0 -140
  255. package/dist/link-CdGHSIy-.mjs +0 -45
  256. package/dist/mcp-DoM3_nhd.mjs +0 -377
  257. package/dist/project-paths-GpziKeQQ.d.mts +0 -25
  258. package/dist/providers-BNKRacMr.d.mts +0 -7
  259. package/dist/proxy-D-3_D-Gl.mjs +0 -5
  260. package/dist/rollback-CkvTFXx5.mjs +0 -90
  261. package/dist/runtime/isr-cache.d.mts +0 -207
  262. package/dist/runtime/isr-cache.mjs +0 -523
  263. package/dist/types-lLjNE9Qp.d.mts +0 -51
  264. package/getting-started-prompt.txt +0 -28
  265. package/skills/void/command/void.md +0 -7
  266. package/skills/void/docs/integrations/auth-providers.md +0 -0
  267. package/skills/void/docs/integrations/payment-processors.md +0 -0
  268. package/skills/void/docs/node_modules/@iconify/vue/README.md +0 -408
  269. package/skills/void/docs/node_modules/@iconify/vue/offline/readme.md +0 -5
  270. package/skills/void/docs/node_modules/@voidzero-dev/vitepress-theme/README.md +0 -103
  271. package/skills/void/docs/node_modules/oxc-minify/README.md +0 -78
  272. package/skills/void/docs/node_modules/reka-ui/README.md +0 -80
  273. package/skills/void/docs/node_modules/vitepress/README.md +0 -28
  274. package/skills/void/docs/node_modules/vitepress/template/api-examples.md +0 -49
  275. package/skills/void/docs/node_modules/vitepress/template/index.md +0 -28
  276. package/skills/void/docs/node_modules/vitepress/template/markdown-examples.md +0 -85
  277. package/skills/void/docs/node_modules/vitepress-plugin-group-icons/README.md +0 -101
  278. package/skills/void/docs/node_modules/void/AGENT_PROMPT.md +0 -19
  279. package/skills/void/docs/node_modules/void/CLAUDE.md +0 -221
  280. package/skills/void/docs/node_modules/void/README.md +0 -90
  281. package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/CHANGELOG.md +0 -685
  282. package/skills/void/docs/node_modules/void/node_modules/@clack/prompts/README.md +0 -396
  283. package/skills/void/docs/node_modules/void/node_modules/@cloudflare/sandbox/README.md +0 -219
  284. package/skills/void/docs/node_modules/void/node_modules/@cloudflare/vite-plugin/README.md +0 -37
  285. package/skills/void/docs/node_modules/void/node_modules/@cloudflare/workers-types/README.md +0 -135
  286. package/skills/void/docs/node_modules/void/node_modules/@electric-sql/pglite/README.md +0 -189
  287. package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/CHANGELOG.md +0 -143
  288. package/skills/void/docs/node_modules/void/node_modules/@hono/oauth-providers/README.md +0 -1272
  289. package/skills/void/docs/node_modules/void/node_modules/@napi-rs/keyring/README.md +0 -19
  290. package/skills/void/docs/node_modules/void/node_modules/@types/better-sqlite3/README.md +0 -15
  291. package/skills/void/docs/node_modules/void/node_modules/@types/node/README.md +0 -15
  292. package/skills/void/docs/node_modules/void/node_modules/@types/pg/README.md +0 -15
  293. package/skills/void/docs/node_modules/void/node_modules/@types/proper-lockfile/README.md +0 -51
  294. package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/README.md +0 -22
  295. package/skills/void/docs/node_modules/void/node_modules/@typescript/native-preview/vendor/vscode-jsonrpc/README.md +0 -69
  296. package/skills/void/docs/node_modules/void/node_modules/@void/md/README.md +0 -153
  297. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/engine-javascript/README.md +0 -9
  298. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@shikijs/transformers/README.md +0 -9
  299. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/@types/node/README.md +0 -15
  300. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/CHANGELOG.md +0 -24
  301. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/gray-matter/README.md +0 -565
  302. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-exit/README.md +0 -127
  303. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-anchor/README.md +0 -600
  304. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-attrs/README.md +0 -386
  305. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-container/README.md +0 -95
  306. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-emoji/README.md +0 -101
  307. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-footnote/README.md +0 -135
  308. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/pathslash/README.md +0 -64
  309. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/shiki/README.md +0 -15
  310. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/tinyglobby/README.md +0 -25
  311. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/AGENTS.md +0 -16
  312. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/README.md +0 -220
  313. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/build.md +0 -21
  314. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/check.md +0 -35
  315. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/create.md +0 -70
  316. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/fmt.md +0 -20
  317. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/index.md +0 -35
  318. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/lint.md +0 -26
  319. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/pack.md +0 -17
  320. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/run.md +0 -364
  321. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/staged.md +0 -15
  322. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/config/test.md +0 -18
  323. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/automatic-data-tracking.md +0 -145
  324. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/build.md +0 -40
  325. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/cache.md +0 -107
  326. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/check.md +0 -60
  327. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/ci.md +0 -62
  328. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/commit-hooks.md +0 -60
  329. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/create.md +0 -341
  330. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/dev.md +0 -24
  331. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/docker.md +0 -175
  332. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/env.md +0 -167
  333. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/fmt.md +0 -41
  334. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/github-actions-cache.md +0 -165
  335. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/ide-integration.md +0 -101
  336. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/implode.md +0 -23
  337. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/index.md +0 -134
  338. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/install.md +0 -199
  339. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/lint.md +0 -50
  340. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/migrate-rules.md +0 -347
  341. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/migrate.md +0 -197
  342. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/monorepo.md +0 -176
  343. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/pack.md +0 -69
  344. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/run.md +0 -356
  345. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/test.md +0 -35
  346. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/troubleshooting.md +0 -108
  347. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/upgrade.md +0 -101
  348. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/vpx.md +0 -66
  349. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/guide/why.md +0 -39
  350. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/index.md +0 -12
  351. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/docs/team.md +0 -35
  352. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/templates/generator/README.md +0 -35
  353. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vite-plus/templates/monorepo/README.md +0 -29
  354. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/vue/README.md +0 -58
  355. package/skills/void/docs/node_modules/void/node_modules/arktype/README.md +0 -165
  356. package/skills/void/docs/node_modules/void/node_modules/better-auth/LICENSE.md +0 -20
  357. package/skills/void/docs/node_modules/void/node_modules/better-auth/README.md +0 -32
  358. package/skills/void/docs/node_modules/void/node_modules/better-sqlite3/README.md +0 -99
  359. package/skills/void/docs/node_modules/void/node_modules/blake3-jit/README.md +0 -108
  360. package/skills/void/docs/node_modules/void/node_modules/drizzle-arktype/README.md +0 -51
  361. package/skills/void/docs/node_modules/void/node_modules/drizzle-kit/README.md +0 -79
  362. package/skills/void/docs/node_modules/void/node_modules/drizzle-orm/README.md +0 -44
  363. package/skills/void/docs/node_modules/void/node_modules/drizzle-valibot/README.md +0 -51
  364. package/skills/void/docs/node_modules/void/node_modules/drizzle-zod/README.md +0 -65
  365. package/skills/void/docs/node_modules/void/node_modules/es-module-lexer/README.md +0 -403
  366. package/skills/void/docs/node_modules/void/node_modules/estree-walker/README.md +0 -48
  367. package/skills/void/docs/node_modules/void/node_modules/hono/README.md +0 -85
  368. package/skills/void/docs/node_modules/void/node_modules/ignore/README.md +0 -452
  369. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/CHANGELOG.md +0 -76
  370. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/LICENSE.md +0 -21
  371. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/README.md +0 -364
  372. package/skills/void/docs/node_modules/void/node_modules/jsonc-parser/SECURITY.md +0 -41
  373. package/skills/void/docs/node_modules/void/node_modules/magic-string/README.md +0 -325
  374. package/skills/void/docs/node_modules/void/node_modules/ofetch/README.md +0 -398
  375. package/skills/void/docs/node_modules/void/node_modules/pathslash/README.md +0 -64
  376. package/skills/void/docs/node_modules/void/node_modules/pg/README.md +0 -96
  377. package/skills/void/docs/node_modules/void/node_modules/pglite-server/README.md +0 -135
  378. package/skills/void/docs/node_modules/void/node_modules/picocolors/README.md +0 -21
  379. package/skills/void/docs/node_modules/void/node_modules/proper-lockfile/CHANGELOG.md +0 -108
  380. package/skills/void/docs/node_modules/void/node_modules/proper-lockfile/README.md +0 -183
  381. package/skills/void/docs/node_modules/void/node_modules/tinyglobby/README.md +0 -25
  382. package/skills/void/docs/node_modules/void/node_modules/valibot/LICENSE.md +0 -9
  383. package/skills/void/docs/node_modules/void/node_modules/valibot/README.md +0 -94
  384. package/skills/void/docs/node_modules/void/node_modules/vite-plus/AGENTS.md +0 -16
  385. package/skills/void/docs/node_modules/void/node_modules/vite-plus/README.md +0 -220
  386. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/build.md +0 -21
  387. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/check.md +0 -35
  388. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/create.md +0 -70
  389. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/fmt.md +0 -20
  390. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/index.md +0 -35
  391. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/lint.md +0 -26
  392. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/pack.md +0 -17
  393. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/run.md +0 -364
  394. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/staged.md +0 -15
  395. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/config/test.md +0 -18
  396. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/automatic-data-tracking.md +0 -145
  397. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/build.md +0 -40
  398. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/cache.md +0 -107
  399. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/check.md +0 -60
  400. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/ci.md +0 -62
  401. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/commit-hooks.md +0 -60
  402. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/create.md +0 -341
  403. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/dev.md +0 -24
  404. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/docker.md +0 -175
  405. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/env.md +0 -167
  406. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/fmt.md +0 -41
  407. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/github-actions-cache.md +0 -165
  408. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/ide-integration.md +0 -101
  409. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/implode.md +0 -23
  410. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/index.md +0 -134
  411. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/install.md +0 -199
  412. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/lint.md +0 -50
  413. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/migrate-rules.md +0 -347
  414. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/migrate.md +0 -197
  415. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/monorepo.md +0 -176
  416. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/pack.md +0 -69
  417. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/run.md +0 -356
  418. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/test.md +0 -35
  419. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/troubleshooting.md +0 -108
  420. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/upgrade.md +0 -101
  421. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/vpx.md +0 -66
  422. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/guide/why.md +0 -39
  423. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/index.md +0 -12
  424. package/skills/void/docs/node_modules/void/node_modules/vite-plus/docs/team.md +0 -35
  425. package/skills/void/docs/node_modules/void/node_modules/vite-plus/templates/generator/README.md +0 -35
  426. package/skills/void/docs/node_modules/void/node_modules/vite-plus/templates/monorepo/README.md +0 -29
  427. package/skills/void/docs/node_modules/void/node_modules/wrangler/README.md +0 -63
  428. package/skills/void/docs/node_modules/void/node_modules/zod/README.md +0 -191
  429. package/skills/void/docs/node_modules/void/skills/migrate-vite-cloudflare-to-void/SKILL.md +0 -175
  430. package/skills/void/docs/node_modules/void/skills/void/SKILL.md +0 -76
  431. package/skills/void/docs/node_modules/void/skills/void/command/void.md +0 -7
  432. package/skills/void/docs/node_modules/void/test/e2e/README.md +0 -85
package/dist/cli/cli.mjs CHANGED
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { a as join } from "../dist-DaKKDf8D.mjs";
3
- import { D as outro, E as note, T as log, d as sectionTitle, i as categoryTitle, l as helpLine, r as getPackageDir, u as import_picocolors } from "../agents-CtgBYqld.mjs";
2
+ import { n as __exportAll } from "../rolldown-runtime-rQ84J-ij.mjs";
3
+ import { o as join } from "../dist-BrsS7cai.mjs";
4
+ import { D as log, G as normalizePlatformApiUrl, O as note, c as import_picocolors, d as formatCloudflareUserMessage, k as outro, l as sectionTitle, p as getPackageDir, s as helpLine, t as categoryTitle } from "../output-tFQLLj26.mjs";
5
+ import { t as cfAccessHeaders } from "../cf-access-AJ1ehiFR.mjs";
4
6
  import { readFileSync } from "node:fs";
5
7
  import { parseArgs } from "node:util";
6
8
  //#region src/cli/args.ts
@@ -15,8 +17,10 @@ function parseDeployArgs(args) {
15
17
  spa: { type: "boolean" },
16
18
  "skip-build": { type: "boolean" },
17
19
  debug: { type: "boolean" },
20
+ platform: { type: "string" },
18
21
  backend: { type: "string" },
19
- provision: { type: "boolean" }
22
+ provision: { type: "boolean" },
23
+ "require-email": { type: "boolean" }
20
24
  },
21
25
  allowPositionals: true,
22
26
  strict: true,
@@ -25,7 +29,9 @@ function parseDeployArgs(args) {
25
29
  } catch (error) {
26
30
  const message = error instanceof Error ? error.message : String(error);
27
31
  if (message.includes("argument missing") || message.includes("argument is ambiguous")) {
28
- if (message.match(/Option '(--[a-z-]+)/)?.[1] === "--backend") throw new Error("deploy: --backend requires a value ('cloudflare').");
32
+ const optionMatch = message.match(/Option '(--[a-z-]+)/);
33
+ if (optionMatch?.[1] === "--platform") throw new Error("deploy: --platform requires a value ('cloudflare' or 'void').");
34
+ if (optionMatch?.[1] === "--backend") throw new Error("deploy: --backend requires a value ('cloudflare').");
29
35
  throw new Error("deploy: --project requires a slug.");
30
36
  }
31
37
  const unknownOptionMatch = message.match(/Unknown option '([^']+)'/);
@@ -34,7 +40,11 @@ function parseDeployArgs(args) {
34
40
  }
35
41
  const tokens = parsed.tokens ?? [];
36
42
  if (tokens.filter((token) => token.kind === "option" && token.name === "project").length > 1) throw new Error("deploy: --project can only be specified once.");
37
- if (tokens.filter((token) => token.kind === "option" && token.name === "backend").length > 1) throw new Error("deploy: --backend can only be specified once.");
43
+ const backendTokens = tokens.filter((token) => token.kind === "option" && token.name === "backend");
44
+ if (backendTokens.length > 1) throw new Error("deploy: --backend can only be specified once.");
45
+ const platformTokens = tokens.filter((token) => token.kind === "option" && token.name === "platform");
46
+ if (platformTokens.length > 1) throw new Error("deploy: --platform can only be specified once.");
47
+ if (platformTokens.length > 0 && backendTokens.length > 0) throw new Error("deploy: --platform and --backend cannot be used together.");
38
48
  if (parsed.positionals.length > 0) throw new Error(`deploy: Unexpected argument '${parsed.positionals[0]}'.`);
39
49
  const projectValue = parsed.values.project;
40
50
  const projectSlug = typeof projectValue === "string" ? projectValue : void 0;
@@ -43,15 +53,18 @@ function parseDeployArgs(args) {
43
53
  const spa = parsed.values.spa === true ? true : void 0;
44
54
  const skipBuild = parsed.values["skip-build"] === true ? true : void 0;
45
55
  const debug = parsed.values.debug === true ? true : void 0;
56
+ const platformValue = typeof parsed.values.platform === "string" ? parsed.values.platform : void 0;
57
+ if (platformValue !== void 0 && platformValue !== "cloudflare" && platformValue !== "void") throw new Error("deploy: --platform must be 'cloudflare' or 'void'.");
58
+ const platform = platformValue;
46
59
  const backendValue = typeof parsed.values.backend === "string" ? parsed.values.backend : void 0;
47
60
  if (backendValue !== void 0 && backendValue !== "cloudflare") throw new Error("deploy: --backend must be 'cloudflare'.");
48
61
  const backend = backendValue;
49
62
  const provision = parsed.values.provision === true ? true : void 0;
50
- if (provision && backend !== "cloudflare") throw new Error("deploy: --provision requires --backend cloudflare.");
51
- if (backend === "cloudflare") {
52
- if (projectSlug !== void 0) throw new Error("deploy: --project is not supported with --backend cloudflare — this backend deploys to your own Cloudflare account and no Void project is involved.");
53
- if (dir !== void 0) throw new Error("deploy: --dir is not supported with --backend cloudflare — this backend uploads the worker your build emits, not a static directory.");
54
- if (spa) throw new Error("deploy: --spa is not supported with --backend cloudflare — this backend uploads the worker your build emits, not a static SPA.");
63
+ if (provision && backend !== "cloudflare" && platform !== "cloudflare") throw new Error("deploy: --provision requires --platform cloudflare.");
64
+ const requireEmail = parsed.values["require-email"] === true ? true : void 0;
65
+ if (requireEmail && backend !== "cloudflare" && platform !== "cloudflare") throw new Error("deploy: --require-email requires --platform cloudflare.");
66
+ if (backend === "cloudflare" || platform === "cloudflare") {
67
+ if (projectSlug !== void 0) throw new Error("deploy: --project is not supported with --platform cloudflare — this platform deploys to your own Cloudflare account and no Void project is involved.");
55
68
  }
56
69
  return {
57
70
  projectSlug,
@@ -59,8 +72,10 @@ function parseDeployArgs(args) {
59
72
  spa,
60
73
  skipBuild,
61
74
  debug,
75
+ platform,
62
76
  backend,
63
- provision
77
+ provision,
78
+ requireEmail
64
79
  };
65
80
  }
66
81
  //#endregion
@@ -135,6 +150,54 @@ function parseBuildArgs(args) {
135
150
  };
136
151
  }
137
152
  //#endregion
153
+ //#region src/cli/cloudflare-args.ts
154
+ const cloudflareSubcommands = [
155
+ {
156
+ name: "login",
157
+ description: "Sign in or switch Cloudflare users securely"
158
+ },
159
+ {
160
+ name: "status",
161
+ description: "Show Cloudflare identity and the pinned deployment account"
162
+ },
163
+ {
164
+ name: "logout",
165
+ description: "Remove the local Cloudflare browser session"
166
+ }
167
+ ];
168
+ function parseCloudflareArgs(args) {
169
+ const [subcommand, extra] = args;
170
+ if (!subcommand || ![
171
+ "login",
172
+ "status",
173
+ "logout"
174
+ ].includes(subcommand)) throw new Error("cloudflare: Usage: void cloudflare <login|status|logout>.");
175
+ if (extra) throw new Error(`cloudflare: Unexpected argument '${extra}'.`);
176
+ return { subcommand };
177
+ }
178
+ //#endregion
179
+ //#region src/cli/connect-args.ts
180
+ function parseConnectArgs(args) {
181
+ const { values, positionals } = parseArgs({
182
+ args,
183
+ allowPositionals: true,
184
+ strict: true,
185
+ options: {
186
+ platform: { type: "string" },
187
+ "no-login": { type: "boolean" }
188
+ }
189
+ });
190
+ if (positionals.length > 1) throw new Error("connect: Expected at most one platform URL.");
191
+ const platform = values.platform ?? null;
192
+ if (platform !== null && platform !== "cloudflare" && platform !== "void") throw new Error("connect: --platform must be cloudflare or void.");
193
+ if (platform === "cloudflare" && (positionals.length > 0 || values["no-login"])) throw new Error("connect: A URL and --no-login are only supported for Void platforms.");
194
+ return {
195
+ url: positionals[0] ?? "",
196
+ platform,
197
+ noLogin: values["no-login"] ?? false
198
+ };
199
+ }
200
+ //#endregion
138
201
  //#region src/cli/db-args.ts
139
202
  const dbSubcommands = [
140
203
  {
@@ -189,7 +252,33 @@ const dbSubcommands = [
189
252
  },
190
253
  {
191
254
  name: "set-url",
192
- description: "Update the PostgreSQL connection string for deployment"
255
+ description: "Update the external database URL for deployment"
256
+ },
257
+ {
258
+ name: "connect",
259
+ arg: "[connection-string]",
260
+ description: "Connect or provision an external database",
261
+ flags: [
262
+ {
263
+ name: "--provider",
264
+ arg: "<name-or-module>",
265
+ description: "Provision with an adapter"
266
+ },
267
+ {
268
+ name: "--name",
269
+ arg: "<name>",
270
+ description: "Provider project/database name"
271
+ },
272
+ {
273
+ name: "--region",
274
+ arg: "<region>",
275
+ description: "Provider region identifier"
276
+ },
277
+ {
278
+ name: "--local-only",
279
+ description: "Do not sync a linked Void project"
280
+ }
281
+ ]
193
282
  },
194
283
  {
195
284
  name: "rename-migrations",
@@ -229,7 +318,11 @@ function parseDbArgs(args) {
229
318
  "no-data": { type: "boolean" },
230
319
  "no-schema": { type: "boolean" },
231
320
  table: { type: "string" },
232
- remote: { type: "boolean" }
321
+ remote: { type: "boolean" },
322
+ provider: { type: "string" },
323
+ name: { type: "string" },
324
+ region: { type: "string" },
325
+ "local-only": { type: "boolean" }
233
326
  },
234
327
  allowPositionals: true,
235
328
  strict: true
@@ -289,6 +382,20 @@ function parseDbArgs(args) {
289
382
  if (rest.length > 0) throw new Error(`db: Unexpected argument '${rest[0]}'.`);
290
383
  return { action };
291
384
  }
385
+ if (action === "connect") {
386
+ if (rest.length > 1) throw new Error(`db: Unexpected argument '${rest[1]}'.`);
387
+ const url = rest[0];
388
+ const provider = typeof parsed.values.provider === "string" ? parsed.values.provider : void 0;
389
+ if (url && provider) throw new Error("db: Provide either a connection string or --provider, not both.");
390
+ return {
391
+ action,
392
+ url,
393
+ provider,
394
+ name: typeof parsed.values.name === "string" ? parsed.values.name : void 0,
395
+ region: typeof parsed.values.region === "string" ? parsed.values.region : void 0,
396
+ localOnly: parsed.values["local-only"] === true ? true : void 0
397
+ };
398
+ }
292
399
  if (action === "rename-migrations") {
293
400
  if (rest.length > 0) throw new Error(`db: Unexpected argument '${rest[0]}'.`);
294
401
  return { action };
@@ -304,7 +411,7 @@ function parseDbArgs(args) {
304
411
  table: typeof parsed.values.table === "string" ? parsed.values.table : void 0
305
412
  };
306
413
  }
307
- throw new Error("db: Usage: void db <push|generate|status|reset|seed|execute|migrate|studio|export|set-url|rename-migrations>.");
414
+ throw new Error("db: Usage: void db <push|generate|status|reset|seed|execute|migrate|studio|export|connect|set-url|rename-migrations>.");
308
415
  }
309
416
  //#endregion
310
417
  //#region src/cli/domain-args.ts
@@ -354,29 +461,221 @@ function parseDomainArgs(args) {
354
461
  };
355
462
  }
356
463
  //#endregion
357
- //#region src/cli/env-args.ts
358
- const envSubcommands = [
464
+ //#region src/cli/email-args.ts
465
+ const PLATFORM_FLAG = {
466
+ name: "--platform",
467
+ arg: "<cloudflare|void>",
468
+ description: "Your own Cloudflare account (`cloudflare`) instead of the Void platform"
469
+ };
470
+ const emailSubcommands = [
359
471
  {
360
- name: "check",
361
- description: "Validate env.ts schema against .env files (and optionally remote secrets)",
362
- flags: [{
363
- name: "--remote",
364
- description: "Also check that required keys exist as remote secrets"
365
- }]
472
+ name: "usage",
473
+ description: "Show monthly email send/receive counts and quota"
366
474
  },
367
475
  {
368
- name: "types",
369
- description: "Regenerate .void/env.d.ts from env.ts"
476
+ name: "logs",
477
+ description: "Show recent email delivery activity"
370
478
  },
371
479
  {
372
- name: "example",
373
- description: "Refresh the void-managed block in .env.example",
374
- flags: [{
375
- name: "--force",
376
- description: "Suppress the \"appended block\" notice (for scripted runs)"
377
- }]
480
+ name: "destinations",
481
+ description: "List verified recipient addresses for outbound mail"
482
+ },
483
+ {
484
+ name: "allow",
485
+ arg: "<address>",
486
+ description: "Add a recipient and trigger CF verification"
487
+ },
488
+ {
489
+ name: "disallow",
490
+ arg: "<address>",
491
+ description: "Remove a verified recipient"
492
+ },
493
+ {
494
+ name: "domain",
495
+ arg: "<add|status|list|sync|remove>",
496
+ description: "Send and receive at your own domain on a Cloudflare zone"
497
+ },
498
+ {
499
+ name: "status",
500
+ description: "Show the email setup state and address map",
501
+ flags: [PLATFORM_FLAG]
502
+ },
503
+ {
504
+ name: "setup",
505
+ description: "Set email up on your own Cloudflare account (--platform cloudflare)",
506
+ flags: [PLATFORM_FLAG]
378
507
  }
379
508
  ];
509
+ const EMAIL_SUBCOMMANDS = [
510
+ "usage",
511
+ "logs",
512
+ "destinations",
513
+ "allow",
514
+ "disallow",
515
+ "domain",
516
+ "status",
517
+ "setup"
518
+ ];
519
+ const EMAIL_DOMAIN_VERBS = [
520
+ "add",
521
+ "status",
522
+ "list",
523
+ "sync",
524
+ "remove"
525
+ ];
526
+ /**
527
+ * Read a value-taking flag in its `--flag value` or `--flag=value` form. Returns the
528
+ * raw value, or `undefined` when the flag is the last token or is followed by another
529
+ * option — the same rule `parseArgs` applies for `void deploy`, so `--platform --limit 3`
530
+ * is a missing value, not a value of `--limit`.
531
+ */
532
+ function readFlagValue(rest, i, flag) {
533
+ const token = rest[i];
534
+ if (token.startsWith(`${flag}=`)) return {
535
+ value: token.slice(flag.length + 1),
536
+ next: i
537
+ };
538
+ const value = rest[i + 1];
539
+ if (value === void 0 || value.startsWith("-")) return {
540
+ value: void 0,
541
+ next: i
542
+ };
543
+ return {
544
+ value,
545
+ next: i + 1
546
+ };
547
+ }
548
+ function parseEmailArgs(args) {
549
+ const subcommand = args[0];
550
+ if (!subcommand || !EMAIL_SUBCOMMANDS.includes(subcommand)) throw new Error("email: Usage: void email <usage|logs|destinations|allow|disallow|domain|status|setup> [args] [--project <name>] [--limit <n>] [--platform cloudflare].");
551
+ let limit;
552
+ const projectValues = [];
553
+ const platformValues = [];
554
+ const backendValues = [];
555
+ const subdomainValues = [];
556
+ let forceCount = 0;
557
+ const positional = [];
558
+ const rest = args.slice(1);
559
+ for (let i = 0; i < rest.length; i++) if (rest[i] === "--project" || rest[i]?.startsWith("--project=")) {
560
+ const { value, next } = readFlagValue(rest, i, "--project");
561
+ if (value === void 0 || value.trim() === "") throw new Error("email: --project requires a value (a project name).");
562
+ projectValues.push(value);
563
+ i = next;
564
+ } else if (rest[i] === "--limit" || rest[i]?.startsWith("--limit=")) {
565
+ const { value: raw, next } = readFlagValue(rest, i, "--limit");
566
+ if (raw === void 0) throw new Error("email: --limit requires a value (a positive integer).");
567
+ const n = parseInt(raw, 10);
568
+ if (!Number.isFinite(n) || n <= 0) throw new Error(`email: --limit must be a positive integer (got '${raw}').`);
569
+ limit = n;
570
+ i = next;
571
+ } else if (rest[i] === "--platform" || rest[i]?.startsWith("--platform=")) {
572
+ const { value, next } = readFlagValue(rest, i, "--platform");
573
+ if (value === void 0) throw new Error("email: --platform requires a value ('cloudflare' or 'void').");
574
+ platformValues.push(value);
575
+ i = next;
576
+ } else if (rest[i] === "--backend" || rest[i]?.startsWith("--backend=")) {
577
+ const { value, next } = readFlagValue(rest, i, "--backend");
578
+ if (value === void 0) throw new Error("email: --backend requires a value ('cloudflare').");
579
+ backendValues.push(value);
580
+ i = next;
581
+ } else if (rest[i] === "--subdomain" || rest[i]?.startsWith("--subdomain=")) {
582
+ const { value, next } = readFlagValue(rest, i, "--subdomain");
583
+ if (value === void 0 || value.trim() === "") throw new Error("email: --subdomain requires a value (a subdomain label or host).");
584
+ subdomainValues.push(value);
585
+ i = next;
586
+ } else if (rest[i] === "--force" || rest[i]?.startsWith("--force=")) {
587
+ if (rest[i] !== "--force") throw new Error("email: --force takes no value.");
588
+ forceCount++;
589
+ } else positional.push(rest[i]);
590
+ if (forceCount > 1) throw new Error("email: --force can only be specified once.");
591
+ const force = forceCount > 0 ? true : void 0;
592
+ if (projectValues.length > 1) throw new Error("email: --project can only be specified once.");
593
+ const projectSlug = projectValues[0];
594
+ if (backendValues.length > 1) throw new Error("email: --backend can only be specified once.");
595
+ if (platformValues.length > 1) throw new Error("email: --platform can only be specified once.");
596
+ if (platformValues.length > 0 && backendValues.length > 0) throw new Error("email: --platform and --backend cannot be used together.");
597
+ let platform;
598
+ const platformValue = platformValues[0];
599
+ if (platformValue !== void 0) {
600
+ if (platformValue !== "cloudflare" && platformValue !== "void") throw new Error("email: --platform must be 'cloudflare' or 'void'.");
601
+ platform = platformValue;
602
+ }
603
+ const backendValue = backendValues[0];
604
+ if (backendValue !== void 0) {
605
+ if (backendValue !== "cloudflare") throw new Error("email: --backend must be 'cloudflare'.");
606
+ platform = "cloudflare";
607
+ }
608
+ if (subdomainValues.length > 1) throw new Error("email: --subdomain can only be specified once.");
609
+ const subdomain = subdomainValues[0];
610
+ if (subcommand === "domain") {
611
+ if (platform === "cloudflare") throw new Error("email: --platform cloudflare applies to `void email status` and `void email setup` only (`domain` is a Void platform command).");
612
+ return parseEmailDomainArgs(positional, {
613
+ projectSlug,
614
+ limit,
615
+ platform,
616
+ subdomain,
617
+ force
618
+ });
619
+ }
620
+ if (subdomain !== void 0) throw new Error("email: --subdomain applies to `void email domain add` only.");
621
+ if (force !== void 0) throw new Error("email: --force applies to `void email domain remove` only.");
622
+ if (positional.length > 1) throw new Error(`email: \`void email ${subcommand}\` takes exactly one positional argument (got ${positional.length}: ${positional.map((p) => JSON.stringify(p)).join(", ")}).`);
623
+ const address = positional[0];
624
+ if ((subcommand === "allow" || subcommand === "disallow") && !address) throw new Error(`email: Usage: void email ${subcommand} <address> [--project <name>].`);
625
+ if (platform === "cloudflare") {
626
+ if (subcommand !== "status" && subcommand !== "setup") throw new Error(`email: --platform cloudflare applies to \`void email status\` and \`void email setup\` only (\`${subcommand}\` is a Void platform command).`);
627
+ if (projectSlug !== void 0) throw new Error("email: --project cannot be combined with --platform cloudflare (it reads the local project, not a Void project).");
628
+ if (address !== void 0) throw new Error(`email: \`void email ${subcommand} --platform cloudflare\` takes no argument.`);
629
+ }
630
+ return {
631
+ subcommand,
632
+ projectSlug,
633
+ limit,
634
+ address,
635
+ platform
636
+ };
637
+ }
638
+ /**
639
+ * The nested `void email domain <verb> [<domain>]` group. positional[0] is the
640
+ * verb, positional[1] the domain — `list` takes no domain, every other verb
641
+ * requires exactly one. Shape validation of the domain itself is the command's
642
+ * job (and ultimately the api's — its regex is authoritative); the parser only
643
+ * counts positionals, exactly as it does for `allow <address>`.
644
+ */
645
+ function parseEmailDomainArgs(positional, flags) {
646
+ const verb = positional[0];
647
+ if (!verb || !EMAIL_DOMAIN_VERBS.includes(verb)) throw new Error("email: Usage: void email domain <add|status|list|sync|remove> [<domain>] [--project <name>].");
648
+ if (flags.subdomain !== void 0 && verb !== "add") throw new Error("email: --subdomain applies to `void email domain add` only.");
649
+ if (flags.force !== void 0 && verb !== "remove") throw new Error("email: --force applies to `void email domain remove` only.");
650
+ const domain = positional[1];
651
+ if (verb === "list") {
652
+ if (domain !== void 0) throw new Error("email: `void email domain list` takes no domain argument.");
653
+ } else if (domain === void 0) throw new Error(`email: Usage: void email domain ${verb} <domain> [--project <name>].`);
654
+ if (positional.length > 2) throw new Error(`email: \`void email domain ${verb}\` takes exactly one domain argument (got ${positional.length - 1}: ${positional.slice(1).map((p) => JSON.stringify(p)).join(", ")}).`);
655
+ return {
656
+ subcommand: "domain",
657
+ domainVerb: verb,
658
+ domain,
659
+ subdomain: flags.subdomain,
660
+ force: flags.force,
661
+ projectSlug: flags.projectSlug,
662
+ limit: flags.limit,
663
+ platform: flags.platform
664
+ };
665
+ }
666
+ //#endregion
667
+ //#region src/cli/env-args.ts
668
+ const envSubcommands = [{
669
+ name: "check",
670
+ description: "Validate local .env or required remote secret names",
671
+ flags: [{
672
+ name: "--remote",
673
+ description: "Also check that required keys exist as remote secrets"
674
+ }]
675
+ }, {
676
+ name: "types",
677
+ description: "Regenerate .void/env.d.ts from env.ts"
678
+ }];
380
679
  function parseEnvArgs(args) {
381
680
  const [subcommand, ...rest] = args;
382
681
  if (subcommand === "check") {
@@ -396,20 +695,7 @@ function parseEnvArgs(args) {
396
695
  if (rest.length > 0) throw new Error(`env: Unexpected argument '${rest[0]}'.`);
397
696
  return { subcommand: "types" };
398
697
  }
399
- if (subcommand === "example") {
400
- const parsed = parseArgs({
401
- args: rest,
402
- options: { force: { type: "boolean" } },
403
- allowPositionals: true,
404
- strict: true
405
- });
406
- if (parsed.positionals.length > 0) throw new Error(`env: Unexpected argument '${parsed.positionals[0]}'.`);
407
- return {
408
- subcommand: "example",
409
- force: !!parsed.values.force
410
- };
411
- }
412
- throw new Error("env: Usage: void env <check|types|example>.");
698
+ throw new Error("env: Usage: void env <check|types>.");
413
699
  }
414
700
  //#endregion
415
701
  //#region src/cli/gen-args.ts
@@ -854,21 +1140,588 @@ dP .dP .d8888b. dP .d888b88
854
1140
  | |/ / /_/ / / /_/ /
855
1141
  |___/\\____/_/\\__,_/`
856
1142
  ];
1143
+ const OPERATOR_MAX_TIMEOUT_MS = 36e5;
1144
+ var OperatorClientError = class extends Error {
1145
+ code;
1146
+ status;
1147
+ details;
1148
+ constructor(message, code = "operator_error", status, details) {
1149
+ super(message);
1150
+ this.code = code;
1151
+ this.status = status;
1152
+ this.details = details;
1153
+ this.name = "OperatorClientError";
1154
+ }
1155
+ toJSON() {
1156
+ return {
1157
+ error: this.code,
1158
+ message: this.message,
1159
+ ...this.status === void 0 ? {} : { status: this.status },
1160
+ ...this.details === void 0 ? {} : { details: this.details }
1161
+ };
1162
+ }
1163
+ };
1164
+ var OperatorClient = class {
1165
+ token;
1166
+ fetcher;
1167
+ origin;
1168
+ constructor(origin, token, fetcher = fetch) {
1169
+ this.token = token;
1170
+ this.fetcher = fetcher;
1171
+ this.origin = normalizePlatformApiUrl(origin);
1172
+ }
1173
+ async request(path, options = {}) {
1174
+ if (!path.startsWith("/") || path.startsWith("//") || path.includes("?") || path.includes("#")) throw new OperatorClientError("Invalid operator API path.");
1175
+ const timeoutMs = options.timeoutMs ?? (options.method === "POST" ? 3e5 : 3e4);
1176
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1e3 || timeoutMs > 36e5) throw new OperatorClientError(`Operator request timeout must be an integer from 1 to ${OPERATOR_MAX_TIMEOUT_MS / 1e3} seconds.`, "invalid_timeout");
1177
+ const url = new URL(`${this.origin}/operator/v1${path}`);
1178
+ for (const [name, value] of Object.entries(options.query ?? {})) url.searchParams.set(name, value);
1179
+ const timeoutController = new AbortController();
1180
+ const timer = setTimeout(() => timeoutController.abort(), timeoutMs);
1181
+ timer.unref();
1182
+ const signal = options.signal ? AbortSignal.any([options.signal, timeoutController.signal]) : timeoutController.signal;
1183
+ try {
1184
+ let response;
1185
+ try {
1186
+ response = await this.fetcher(url, {
1187
+ method: options.method ?? "GET",
1188
+ headers: {
1189
+ ...cfAccessHeaders(process.env, this.origin),
1190
+ Authorization: `Bearer ${this.token}`,
1191
+ Accept: "application/json",
1192
+ ...options.body ? { "Content-Type": "application/json" } : {}
1193
+ },
1194
+ ...options.body ? { body: JSON.stringify(options.body) } : {},
1195
+ redirect: "manual",
1196
+ signal
1197
+ });
1198
+ } catch (error) {
1199
+ if (options.signal?.aborted) throw error;
1200
+ if (timeoutController.signal.aborted) throw new OperatorClientError(`Operator request exceeded the ${timeoutMs / 1e3}-second timeout. ${options.method === "POST" ? "Its outcome may be unknown; inspect platform state before retrying." : "Check connectivity and try again."}`, "request_timeout");
1201
+ throw new OperatorClientError(`Operator request to ${this.origin} failed. ${options.method === "POST" ? "Its outcome may be unknown; inspect platform state before retrying." : "Check connectivity and try again."}`, "connection_failed");
1202
+ }
1203
+ if (response.status >= 300 && response.status < 400) throw new OperatorClientError("The operator API redirected the request. Credentials were not forwarded; use the exact platform API origin.", "redirect_rejected", response.status);
1204
+ let data;
1205
+ try {
1206
+ data = await response.json();
1207
+ } catch {
1208
+ throw new OperatorClientError(`Operator API returned invalid JSON (HTTP ${response.status}).${options.method === "POST" ? " Inspect platform state before retrying." : ""}`, "invalid_response", response.status);
1209
+ }
1210
+ if (!data || typeof data !== "object" || Array.isArray(data)) throw new OperatorClientError("Operator API returned an invalid response object.", "invalid_response", response.status);
1211
+ const result = data;
1212
+ if (!response.ok) throw new OperatorClientError(typeof result.message === "string" ? result.message : `Operator request failed (HTTP ${response.status}).`, typeof result.error === "string" ? result.error : "request_failed", response.status, result.details);
1213
+ if (result.partial === true || result.ok === false) throw new OperatorClientError("The operation did not fully complete. Inspect the partial result before retrying.", "partial_failure", response.status, result);
1214
+ return result;
1215
+ } finally {
1216
+ clearTimeout(timer);
1217
+ }
1218
+ }
1219
+ };
1220
+ //#endregion
1221
+ //#region src/cli/operator-args.ts
1222
+ const operatorCommands = [
1223
+ {
1224
+ group: "auth",
1225
+ action: "login",
1226
+ description: "Sign in as a platform administrator",
1227
+ path: "/session",
1228
+ values: { provider: "OAuth provider" },
1229
+ booleans: ["token-stdin"]
1230
+ },
1231
+ {
1232
+ group: "auth",
1233
+ action: "logout",
1234
+ description: "Revoke the current operator session and remove its local credential",
1235
+ path: "/session/logout"
1236
+ },
1237
+ {
1238
+ group: "auth",
1239
+ action: "status",
1240
+ description: "Inspect operator identity, expiry, and capabilities",
1241
+ path: "/session"
1242
+ },
1243
+ {
1244
+ group: "auth",
1245
+ action: "token",
1246
+ description: "Print an operator token; exchange an API session with --token-stdin",
1247
+ path: "/session",
1248
+ booleans: ["token-stdin"]
1249
+ },
1250
+ {
1251
+ group: "user",
1252
+ action: "list",
1253
+ description: "List users",
1254
+ path: "/users",
1255
+ values: { search: "Search login or email" }
1256
+ },
1257
+ {
1258
+ group: "user",
1259
+ action: "show",
1260
+ description: "Inspect a user, usage, and projects",
1261
+ path: "/users/:id",
1262
+ positional: ["id"]
1263
+ },
1264
+ {
1265
+ group: "user",
1266
+ action: "plan",
1267
+ description: "Change a user plan",
1268
+ path: "/users/:id/plan",
1269
+ positional: ["id", "plan"],
1270
+ method: "POST"
1271
+ },
1272
+ {
1273
+ group: "user",
1274
+ action: "suspend",
1275
+ description: "Suspend a user and their projects",
1276
+ path: "/users/:id/suspend",
1277
+ positional: ["id"],
1278
+ values: { reason: "Reason for suspension" },
1279
+ method: "POST"
1280
+ },
1281
+ {
1282
+ group: "user",
1283
+ action: "restore",
1284
+ description: "Restore a suspended user",
1285
+ path: "/users/:id/restore",
1286
+ positional: ["id"],
1287
+ method: "POST"
1288
+ },
1289
+ {
1290
+ group: "user",
1291
+ action: "delete",
1292
+ description: "Delete a user and all owned resources",
1293
+ path: "/users/:id/delete",
1294
+ positional: ["id"],
1295
+ method: "POST"
1296
+ },
1297
+ {
1298
+ group: "project",
1299
+ action: "list",
1300
+ description: "List tenant projects",
1301
+ path: "/projects",
1302
+ values: {
1303
+ user: "Owner user ID",
1304
+ search: "Search projects"
1305
+ }
1306
+ },
1307
+ {
1308
+ group: "project",
1309
+ action: "show",
1310
+ description: "Inspect a project and its resources",
1311
+ path: "/projects/:id",
1312
+ positional: ["id"]
1313
+ },
1314
+ {
1315
+ group: "project",
1316
+ action: "delete",
1317
+ description: "Delete a project and its resources",
1318
+ path: "/projects/:id/delete",
1319
+ positional: ["id"],
1320
+ method: "POST"
1321
+ },
1322
+ {
1323
+ group: "deployment",
1324
+ action: "list",
1325
+ description: "List tenant deployments",
1326
+ path: "/deployments",
1327
+ values: {
1328
+ project: "Project ID",
1329
+ search: "Search deployments",
1330
+ status: "Deployment status"
1331
+ }
1332
+ },
1333
+ {
1334
+ group: "deployment",
1335
+ action: "show",
1336
+ description: "Inspect a deployment",
1337
+ path: "/deployments/:id",
1338
+ positional: ["id"]
1339
+ },
1340
+ {
1341
+ group: "deployment",
1342
+ action: "cancel",
1343
+ description: "Cancel a deployment",
1344
+ path: "/deployments/:id/cancel",
1345
+ positional: ["id"],
1346
+ method: "POST"
1347
+ },
1348
+ {
1349
+ group: "deployment",
1350
+ action: "logs",
1351
+ description: "Read runtime logs (JSON follow emits one object per line)",
1352
+ path: "/deployments/:id/logs",
1353
+ positional: ["id"],
1354
+ values: {
1355
+ since: "Duration or ISO timestamp",
1356
+ cursor: "Opaque continuation cursor"
1357
+ },
1358
+ booleans: ["follow"]
1359
+ },
1360
+ {
1361
+ group: "build",
1362
+ action: "show",
1363
+ description: "Inspect a managed build",
1364
+ path: "/builds/:id",
1365
+ positional: ["id"]
1366
+ },
1367
+ {
1368
+ group: "build",
1369
+ action: "logs",
1370
+ description: "Read build logs (JSON follow emits one object per line)",
1371
+ path: "/builds/:id/logs",
1372
+ positional: ["id"],
1373
+ values: { since: "Last received sequence number" },
1374
+ booleans: ["follow"]
1375
+ },
1376
+ {
1377
+ group: "signup",
1378
+ action: "show",
1379
+ description: "Inspect signup restrictions and allowlist",
1380
+ path: "/signup"
1381
+ },
1382
+ {
1383
+ group: "signup",
1384
+ action: "restrict",
1385
+ description: "Restrict signup to the allowlist",
1386
+ path: "/signup/restrict",
1387
+ method: "POST"
1388
+ },
1389
+ {
1390
+ group: "signup",
1391
+ action: "open",
1392
+ description: "Open public signup",
1393
+ path: "/signup/open",
1394
+ method: "POST"
1395
+ },
1396
+ {
1397
+ group: "signup",
1398
+ action: "allow",
1399
+ description: "Add a github or email allowlist pattern",
1400
+ path: "/signup/allow",
1401
+ positional: ["type", "pattern"],
1402
+ values: { note: "Allowlist note" },
1403
+ method: "POST"
1404
+ },
1405
+ {
1406
+ group: "signup",
1407
+ action: "remove",
1408
+ description: "Remove a github or email allowlist pattern",
1409
+ path: "/signup/remove",
1410
+ positional: ["type", "pattern"],
1411
+ method: "POST"
1412
+ },
1413
+ {
1414
+ group: "invitation",
1415
+ action: "list",
1416
+ description: "List invitations",
1417
+ path: "/invitations"
1418
+ },
1419
+ {
1420
+ group: "invitation",
1421
+ action: "send",
1422
+ description: "Send invitations to comma-separated email addresses",
1423
+ path: "/invitations/send",
1424
+ positional: ["emails"],
1425
+ method: "POST"
1426
+ },
1427
+ {
1428
+ group: "invitation",
1429
+ action: "revoke",
1430
+ description: "Revoke an invitation",
1431
+ path: "/invitations/:id/revoke",
1432
+ positional: ["id"],
1433
+ method: "POST"
1434
+ },
1435
+ {
1436
+ group: "system",
1437
+ action: "overview",
1438
+ description: "Inspect platform usage and capacity",
1439
+ path: "/system/overview"
1440
+ },
1441
+ {
1442
+ group: "system",
1443
+ action: "health",
1444
+ description: "Check platform health",
1445
+ path: "/system/health"
1446
+ },
1447
+ {
1448
+ group: "system",
1449
+ action: "cli-versions",
1450
+ description: "Inspect CLI version adoption and deployment statistics",
1451
+ path: "/system/cli-versions"
1452
+ },
1453
+ {
1454
+ group: "system",
1455
+ action: "events",
1456
+ description: "List operator audit events",
1457
+ path: "/system/events"
1458
+ },
1459
+ {
1460
+ group: "system",
1461
+ action: "backfill-queue-tokens",
1462
+ description: "Repair missing queue authentication tokens",
1463
+ path: "/system/backfill-queue-tokens",
1464
+ method: "POST"
1465
+ },
1466
+ {
1467
+ group: "system",
1468
+ action: "sandbox-drain",
1469
+ description: "Drain and verify managed Sandbox container applications",
1470
+ path: "/system/sandbox-drain",
1471
+ values: { cursor: "Opaque cursor returned by --plan" },
1472
+ method: "POST"
1473
+ },
1474
+ {
1475
+ group: "worker",
1476
+ action: "list",
1477
+ description: "List hosted platform workers",
1478
+ path: "/workers",
1479
+ values: { environment: "production or staging" }
1480
+ },
1481
+ {
1482
+ group: "worker",
1483
+ action: "show",
1484
+ description: "Inspect hosted worker versions",
1485
+ path: "/workers/:id",
1486
+ positional: ["id"],
1487
+ values: { environment: "production or staging" }
1488
+ },
1489
+ {
1490
+ group: "worker",
1491
+ action: "rollback",
1492
+ description: "Roll back a hosted worker to a version",
1493
+ path: "/workers/:id/rollback",
1494
+ positional: ["id", "versionId"],
1495
+ values: { environment: "production or staging" },
1496
+ method: "POST"
1497
+ },
1498
+ {
1499
+ group: "worker",
1500
+ action: "rollback-all",
1501
+ description: "Roll back all hosted workers to their previous versions",
1502
+ path: "/workers/rollback-all",
1503
+ values: { environment: "production or staging" },
1504
+ method: "POST"
1505
+ },
1506
+ {
1507
+ group: "worker",
1508
+ action: "events",
1509
+ description: "List hosted worker events or inspect a batch",
1510
+ path: "/workers/events",
1511
+ positional: ["batchId"],
1512
+ optionalPositional: true,
1513
+ values: { environment: "production or staging" }
1514
+ }
1515
+ ];
1516
+ const operatorGroups = [...new Set(operatorCommands.map(({ group }) => group))];
1517
+ function parseOperatorArgs(args) {
1518
+ const positional = [];
1519
+ const values = {};
1520
+ const flags = /* @__PURE__ */ new Set();
1521
+ const booleanFlags = /* @__PURE__ */ new Set([
1522
+ "json",
1523
+ "plan",
1524
+ "yes",
1525
+ "follow",
1526
+ "token-stdin"
1527
+ ]);
1528
+ for (let index = 0; index < args.length; index++) {
1529
+ const arg = args[index];
1530
+ if (!arg.startsWith("-")) {
1531
+ positional.push(arg);
1532
+ continue;
1533
+ }
1534
+ if (!arg.startsWith("--")) throw new Error(`platform: Unknown flag '${arg}'.`);
1535
+ const flag = arg.slice(2);
1536
+ if (flags.has(flag) || Object.hasOwn(values, flag)) throw new Error(`platform: Duplicate flag '${arg}'.`);
1537
+ if (booleanFlags.has(flag)) flags.add(flag);
1538
+ else {
1539
+ const value = args[++index];
1540
+ if (!value || value.startsWith("-")) throw new Error(`platform: ${arg} requires a value.`);
1541
+ values[flag] = value;
1542
+ }
1543
+ }
1544
+ const [group = "", action = "", ...parameters] = positional;
1545
+ if (!operatorGroups.includes(group)) throw new Error("platform: Unknown operator command group.");
1546
+ const parsed = {
1547
+ subcommand: "operator",
1548
+ group,
1549
+ action,
1550
+ connection: values.connection ?? "",
1551
+ json: flags.has("json"),
1552
+ plan: flags.has("plan"),
1553
+ yes: flags.has("yes"),
1554
+ follow: flags.has("follow"),
1555
+ tokenStdin: flags.has("token-stdin"),
1556
+ provider: values.provider ?? "github",
1557
+ method: "GET",
1558
+ path: "",
1559
+ query: {},
1560
+ body: {}
1561
+ };
1562
+ if (!action && args.length === 1) return parsed;
1563
+ const command = operatorCommands.find((entry) => entry.group === group && entry.action === action);
1564
+ if (!command) throw new Error(`platform: Usage: void platform ${group} <${operatorCommands.filter((entry) => entry.group === group).map(({ action }) => action).join("|")}>.`);
1565
+ const count = command.positional?.length ?? 0;
1566
+ if (parameters.length > count || !command.optionalPositional && parameters.length !== count) throw new Error(`platform: Usage: void platform ${group} ${action}${command.positional?.map((name) => ` <${name}>`).join("") ?? ""}.`);
1567
+ const paged = action === "list" || action === "events" || action === "logs";
1568
+ const allowed = /* @__PURE__ */ new Set([
1569
+ "connection",
1570
+ ...command.method ? ["timeout"] : [],
1571
+ ...Object.keys(command.values ?? {}),
1572
+ ...paged ? ["limit", ...action !== "logs" ? ["page"] : []] : []
1573
+ ]);
1574
+ for (const name of Object.keys(values)) if (!allowed.has(name)) throw new Error(`platform: Unknown flag '--${name}' for ${group} ${action}.`);
1575
+ for (const name of flags) if (![
1576
+ "json",
1577
+ ...command.method ? ["yes", "plan"] : [],
1578
+ ...command.booleans ?? []
1579
+ ].includes(name)) throw new Error(`platform: Unknown flag '--${name}' for ${group} ${action}.`);
1580
+ if (parsed.plan && parsed.yes) throw new Error("platform: --plan and --yes cannot be combined.");
1581
+ parsed.path = command.path;
1582
+ parsed.method = command.method ?? "GET";
1583
+ for (const [index, name] of (command.positional ?? []).entries()) {
1584
+ const value = parameters[index];
1585
+ if (value === void 0) continue;
1586
+ if (value === "." || value === "..") throw new Error("platform: An object ID cannot be a dot path segment.");
1587
+ if (parsed.path.includes(`:${name}`)) parsed.path = parsed.path.replace(`:${name}`, encodeURIComponent(value));
1588
+ else if (group === "worker" && action === "events") parsed.path += `/${encodeURIComponent(value)}`;
1589
+ else parsed.body[name] = name === "emails" ? value.split(",").map((email) => email.trim()) : value;
1590
+ }
1591
+ for (const [name, value] of Object.entries(values)) {
1592
+ if (name === "connection" || name === "provider") continue;
1593
+ if (name === "timeout") {
1594
+ const maximum = OPERATOR_MAX_TIMEOUT_MS / 1e3;
1595
+ if (!/^[1-9]\d*$/.test(value) || Number(value) > maximum) throw new Error(`platform: --timeout must be an integer from 1 to ${maximum} seconds.`);
1596
+ parsed.timeoutMs = Number(value) * 1e3;
1597
+ continue;
1598
+ }
1599
+ if (name === "page" || name === "limit") {
1600
+ const maximum = name === "limit" ? action === "logs" ? 500 : 100 : 1e6;
1601
+ if (!/^[1-9]\d*$/.test(value) || Number(value) > maximum) throw new Error(`platform: --${name} must be an integer from 1 to ${maximum}.`);
1602
+ }
1603
+ if (name === "since" && group === "build" && (!/^\d+$/.test(value) || !Number.isSafeInteger(Number(value)))) throw new Error("platform: --since must be a nonnegative safe integer for build logs.");
1604
+ if (name === "environment" && !["production", "staging"].includes(value)) throw new Error("platform: --environment must be production or staging.");
1605
+ if (parsed.method === "POST") parsed.body[name] = value;
1606
+ else parsed.query[name] = value;
1607
+ }
1608
+ if (parsed.body.type && !["github", "email"].includes(String(parsed.body.type))) throw new Error("platform: Signup pattern type must be github or email.");
1609
+ return parsed;
1610
+ }
857
1611
  //#endregion
858
1612
  //#region src/cli/help.ts
1613
+ var help_exports = /* @__PURE__ */ __exportAll({
1614
+ getHelpPath: () => getHelpPath,
1615
+ printGlobalHelp: () => printGlobalHelp,
1616
+ printHelpPage: () => printHelpPage,
1617
+ printVoidHeader: () => printVoidHeader
1618
+ });
1619
+ function operatorHelpTree() {
1620
+ return Object.fromEntries(operatorGroups.map((group) => {
1621
+ const commands = operatorCommands.filter((entry) => entry.group === group);
1622
+ return [group, {
1623
+ summary: `Administer platform ${group}. Operator credentials are separate from deployment credentials.`,
1624
+ usage: [`void platform ${group} <command> [options]`],
1625
+ commands: commands.map((entry) => ({
1626
+ command: entry.action,
1627
+ description: entry.description
1628
+ })),
1629
+ children: Object.fromEntries(commands.map((entry) => [entry.action, {
1630
+ summary: `${entry.description}.`,
1631
+ usage: [`void platform ${group} ${entry.action}${entry.positional?.map((name) => entry.optionalPositional ? ` [${name}]` : ` <${name}>`).join("") ?? ""} [options]`],
1632
+ options: [
1633
+ {
1634
+ command: "--connection <id-or-url>",
1635
+ description: "Choose a registered connection; otherwise use VOID_API_URL or the active connection"
1636
+ },
1637
+ {
1638
+ command: "--json",
1639
+ description: "Write structured JSON to stdout (JSON Lines while following logs)"
1640
+ },
1641
+ ...entry.method ? [
1642
+ {
1643
+ command: "--plan",
1644
+ description: "Validate and preview without changing anything"
1645
+ },
1646
+ {
1647
+ command: "--yes",
1648
+ description: "Apply after preview without prompting; required in unattended scripts"
1649
+ },
1650
+ {
1651
+ command: "--timeout <seconds>",
1652
+ description: "Mutation deadline (default 300 seconds; maximum 3600 seconds)"
1653
+ }
1654
+ ] : [],
1655
+ ...[
1656
+ "list",
1657
+ "events",
1658
+ "logs"
1659
+ ].includes(entry.action) ? [{
1660
+ command: "--limit <number>",
1661
+ description: entry.action === "logs" ? "Maximum 500 log records" : "Maximum 100 records per page"
1662
+ }, ...entry.action !== "logs" ? [{
1663
+ command: "--page <number>",
1664
+ description: "One-based page number"
1665
+ }] : []] : [],
1666
+ ...Object.entries(entry.values ?? {}).map(([flag, description]) => ({
1667
+ command: `--${flag} <value>`,
1668
+ description
1669
+ })),
1670
+ ...(entry.booleans ?? []).map((flag) => ({
1671
+ command: `--${flag}`,
1672
+ description: flag === "follow" ? "Poll new logs until interrupted or the build ends" : "Read a full API session from stdin for explicit operator session exchange"
1673
+ }))
1674
+ ]
1675
+ }]))
1676
+ }];
1677
+ }));
1678
+ }
859
1679
  const HELP_TREE = {
1680
+ connect: {
1681
+ summary: "Connect this project to Cloudflare or an existing Void platform.",
1682
+ usage: ["void connect [url] [--platform <cloudflare|void>] [--no-login]"],
1683
+ options: [{
1684
+ command: "--platform <cloudflare|void>",
1685
+ description: "Choose the deployment destination"
1686
+ }, {
1687
+ command: "--no-login",
1688
+ description: "Save a Void connection without authenticating"
1689
+ }],
1690
+ examples: [
1691
+ {
1692
+ command: "void connect",
1693
+ description: "Choose a destination and sign in"
1694
+ },
1695
+ {
1696
+ command: "void connect https://platform.example.com",
1697
+ description: "Join a Void platform"
1698
+ },
1699
+ {
1700
+ command: "void connect --platform cloudflare",
1701
+ description: "Sign in and select a Cloudflare account"
1702
+ }
1703
+ ]
1704
+ },
860
1705
  init: {
861
1706
  summary: "Set up Void in a new or existing project.",
862
1707
  usage: ["void init [options]"],
863
1708
  options: [
864
1709
  {
865
1710
  command: "--agents",
866
- description: "Set up agent instructions, skills, and MCP config"
1711
+ description: "Set up agent instructions and skills"
867
1712
  },
868
1713
  {
869
1714
  command: "--tsconfig",
870
1715
  description: "Only update tsconfig.json"
871
1716
  },
1717
+ {
1718
+ command: "--git",
1719
+ description: "Initialize a Git repository without prompting"
1720
+ },
1721
+ {
1722
+ command: "--no-git",
1723
+ description: "Skip Git repository initialization"
1724
+ },
872
1725
  {
873
1726
  command: "--github",
874
1727
  description: "Only create the GitHub Actions deploy workflow (OIDC, no stored token)"
@@ -881,7 +1734,7 @@ const HELP_TREE = {
881
1734
  },
882
1735
  {
883
1736
  command: "void init --agents",
884
- description: "Install agent instructions and MCP config"
1737
+ description: "Install agent instructions and skills"
885
1738
  },
886
1739
  {
887
1740
  command: "void init --github",
@@ -890,7 +1743,7 @@ const HELP_TREE = {
890
1743
  ]
891
1744
  },
892
1745
  deploy: {
893
- summary: "Build and deploy the current project to Void.",
1746
+ summary: "Build and deploy. Offers to link an existing Cloudflare Worker when no destination is configured.",
894
1747
  usage: ["void deploy [options]"],
895
1748
  options: [
896
1749
  {
@@ -907,15 +1760,15 @@ const HELP_TREE = {
907
1760
  },
908
1761
  {
909
1762
  command: "--skip-build",
910
- description: "Skip the build step and use existing output (not with --backend cloudflare)"
1763
+ description: "Skip the build step and use existing output (static deploys on Cloudflare)"
911
1764
  },
912
1765
  {
913
- command: "--backend cloudflare",
914
- description: "Deploy to your own Cloudflare account instead of the Void platform"
1766
+ command: "--platform <cloudflare|void>",
1767
+ description: "Override the platform saved by void init"
915
1768
  },
916
1769
  {
917
- command: "--provision",
918
- description: "Create missing D1/KV/R2/Queue/Hyperdrive resources (with --backend cloudflare)"
1770
+ command: "--require-email",
1771
+ description: "Fail instead of deploying without email when the mail domain is not set up (with --platform cloudflare)"
919
1772
  },
920
1773
  {
921
1774
  command: "--debug",
@@ -936,12 +1789,8 @@ const HELP_TREE = {
936
1789
  description: "Deploy a static SPA directory"
937
1790
  },
938
1791
  {
939
- command: "void deploy --backend cloudflare",
1792
+ command: "void deploy --platform cloudflare",
940
1793
  description: "Deploy to your own Cloudflare account"
941
- },
942
- {
943
- command: "void deploy --backend cloudflare --provision",
944
- description: "Provision missing resources, then deploy to Cloudflare"
945
1794
  }
946
1795
  ]
947
1796
  },
@@ -957,20 +1806,250 @@ const HELP_TREE = {
957
1806
  command: "logout",
958
1807
  description: "Log out and remove credentials"
959
1808
  },
960
- {
961
- command: "whoami",
962
- description: "Show the logged-in username"
1809
+ {
1810
+ command: "whoami",
1811
+ description: "Show the logged-in username"
1812
+ },
1813
+ {
1814
+ command: "token",
1815
+ description: "Copy auth token to clipboard"
1816
+ }
1817
+ ],
1818
+ children: {
1819
+ login: basicSubcommand("Log in with GitHub or Google.", "void auth login"),
1820
+ logout: basicSubcommand("Log out and remove credentials.", "void auth logout"),
1821
+ whoami: basicSubcommand("Show the logged-in username.", "void auth whoami"),
1822
+ token: basicSubcommand("Copy auth token to clipboard.", "void auth token")
1823
+ }
1824
+ },
1825
+ cloudflare: {
1826
+ summary: "Manage Cloudflare authentication used by Void.",
1827
+ usage: ["void cloudflare <command>"],
1828
+ commands: [
1829
+ {
1830
+ command: "login",
1831
+ description: "Sign in or switch users with browser OAuth"
1832
+ },
1833
+ {
1834
+ command: "status",
1835
+ description: "Show identity, authentication, and the deployment account"
1836
+ },
1837
+ {
1838
+ command: "logout",
1839
+ description: "Remove the local browser session"
1840
+ }
1841
+ ],
1842
+ children: {
1843
+ login: basicSubcommand("Sign in again or switch Cloudflare users with browser OAuth.", "void cloudflare login"),
1844
+ status: basicSubcommand("Show Cloudflare identity, authentication, accessible accounts, and the pinned deployment account.", "void cloudflare status"),
1845
+ logout: basicSubcommand("Remove the local browser session.", "void cloudflare logout")
1846
+ }
1847
+ },
1848
+ platform: {
1849
+ summary: "Install Void platforms and administer users, projects, access, and operations. Use `void connect` to join one.",
1850
+ usage: ["void platform <command>"],
1851
+ commands: [
1852
+ ...operatorGroups.map((group) => ({
1853
+ command: `${group} <command>`,
1854
+ description: `Administer platform ${group}`
1855
+ })),
1856
+ {
1857
+ command: "list",
1858
+ description: "List installed and connected platforms"
1859
+ },
1860
+ {
1861
+ command: "use [id]",
1862
+ description: "Select the default Void platform"
1863
+ },
1864
+ {
1865
+ command: "status [id]",
1866
+ description: "Inspect a platform and its health"
1867
+ },
1868
+ {
1869
+ command: "discover",
1870
+ description: "Recover installations from a Cloudflare account"
1871
+ },
1872
+ {
1873
+ command: "domain set <domain>",
1874
+ description: "Add an application domain to a test platform"
1875
+ },
1876
+ {
1877
+ command: "install",
1878
+ description: "Install a Void platform in Cloudflare"
1879
+ },
1880
+ {
1881
+ command: "upgrade [id]",
1882
+ description: "Upgrade an installed Void platform"
1883
+ },
1884
+ {
1885
+ command: "rollback [id]",
1886
+ description: "Restore a compatible earlier platform runtime"
1887
+ },
1888
+ {
1889
+ command: "repair [id]",
1890
+ description: "Reconcile an installed Void platform"
1891
+ },
1892
+ {
1893
+ command: "disable [id]",
1894
+ description: "Disable traffic without deleting data"
1895
+ },
1896
+ {
1897
+ command: "enable [id]",
1898
+ description: "Restore traffic for a disabled platform"
1899
+ },
1900
+ {
1901
+ command: "uninstall [id]",
1902
+ description: "Safely remove an installed Void platform"
1903
+ }
1904
+ ],
1905
+ children: {
1906
+ ...operatorHelpTree(),
1907
+ domain: {
1908
+ summary: "Add an application domain while keeping existing workers.dev URLs.",
1909
+ usage: ["void platform domain set <domain> [options]"],
1910
+ children: { set: {
1911
+ summary: "Set up DNS and verify HTTPS before making an application domain canonical. Rerun to resume.",
1912
+ usage: ["void platform domain set <domain> [options]"],
1913
+ options: [
1914
+ {
1915
+ command: "--installation <id>",
1916
+ description: "Choose an installed platform; otherwise select interactively"
1917
+ },
1918
+ {
1919
+ command: "--zone <domain>",
1920
+ description: "Containing Cloudflare zone; detected when it already exists"
1921
+ },
1922
+ {
1923
+ command: "--dedicated-zone",
1924
+ description: "Add catch-all routes for a zone dedicated to this platform"
1925
+ },
1926
+ {
1927
+ command: "--plan",
1928
+ description: "Preview without making changes"
1929
+ },
1930
+ {
1931
+ command: "--yes",
1932
+ description: "Apply without an interactive confirmation"
1933
+ }
1934
+ ]
1935
+ } }
1936
+ },
1937
+ list: basicSubcommand("List installed and connected platforms.", "void platform list"),
1938
+ use: basicSubcommand("Select the default Void platform.", "void platform use [id]"),
1939
+ status: basicSubcommand("Inspect a platform and its health.", "void platform status [id]"),
1940
+ discover: {
1941
+ summary: "Recover owned platform installations from Cloudflare.",
1942
+ usage: ["void platform discover [--account <id>] [--installation <id-or-name>]"],
1943
+ options: [{
1944
+ command: "--account <id>",
1945
+ description: "Cloudflare account id"
1946
+ }, {
1947
+ command: "--installation <id-or-name>",
1948
+ description: "Recover only one installation from a shared account"
1949
+ }]
1950
+ },
1951
+ install: {
1952
+ summary: "Install or resume a Void platform with a domain, or workers.dev for testing.",
1953
+ usage: ["void platform install [options]"],
1954
+ options: [
1955
+ {
1956
+ command: "--name <slug>",
1957
+ description: "Installation name"
1958
+ },
1959
+ {
1960
+ command: "--workers-dev",
1961
+ description: "Use workers.dev for testing; add a domain later"
1962
+ },
1963
+ {
1964
+ command: "--display-name <name>",
1965
+ description: "Human-readable platform name"
1966
+ },
1967
+ {
1968
+ command: "--account <id>",
1969
+ description: "Cloudflare account id"
1970
+ },
1971
+ {
1972
+ command: "--application-domain <domain>",
1973
+ description: "Base domain for applications (zone apex is simplest)"
1974
+ },
1975
+ {
1976
+ command: "--zone <domain>",
1977
+ description: "Cloudflare zone containing the app domain"
1978
+ },
1979
+ {
1980
+ command: "--dedicated-zone",
1981
+ description: "Allow zone-wide application catch-all routes"
1982
+ },
1983
+ {
1984
+ command: "--control-plane-domain <domain>",
1985
+ description: "Optional API hostname"
1986
+ },
1987
+ {
1988
+ command: "--plan",
1989
+ description: "Print the exact plan without changing Cloudflare"
1990
+ },
1991
+ {
1992
+ command: "--resume",
1993
+ description: "Resume the matching local installation"
1994
+ },
1995
+ {
1996
+ command: "--runtime <path>",
1997
+ description: "Deploy an integrity-checked runtime directory instead of the package"
1998
+ },
1999
+ {
2000
+ command: "--yes",
2001
+ description: "Acknowledge changes without an interactive prompt"
2002
+ }
2003
+ ]
2004
+ },
2005
+ upgrade: lifecycleHelp("upgrade", "Upgrade an installed platform without deleting resources."),
2006
+ rollback: {
2007
+ summary: "Restore a compatible earlier runtime without reversing database migrations.",
2008
+ usage: ["void platform rollback [id] --runtime <earlier-path> [--from-runtime <current-path>] [--plan] [--yes]"],
2009
+ options: [
2010
+ {
2011
+ command: "--runtime <path>",
2012
+ description: "Earlier compatible runtime to restore"
2013
+ },
2014
+ {
2015
+ command: "--from-runtime <path>",
2016
+ description: "Current installed runtime when it differs from the packaged runtime"
2017
+ },
2018
+ {
2019
+ command: "--plan",
2020
+ description: "Print the exact plan without making changes"
2021
+ },
2022
+ {
2023
+ command: "--yes",
2024
+ description: "Acknowledge non-interactive Cloudflare changes"
2025
+ }
2026
+ ]
963
2027
  },
964
- {
965
- command: "token",
966
- description: "Copy auth token to clipboard"
2028
+ repair: lifecycleHelp("repair", "Reconcile drift using the installation ownership manifest."),
2029
+ disable: lifecycleHelp("disable", "Disable platform traffic without deleting data."),
2030
+ enable: lifecycleHelp("enable", "Restore configured traffic for a disabled platform."),
2031
+ uninstall: {
2032
+ summary: "Safely remove installer-owned platform resources.",
2033
+ usage: ["void platform uninstall [id] [options]"],
2034
+ options: [
2035
+ {
2036
+ command: "--plan",
2037
+ description: "Print the exact deletion and retention plan"
2038
+ },
2039
+ {
2040
+ command: "--yes",
2041
+ description: "Acknowledge changes without an interactive prompt"
2042
+ },
2043
+ {
2044
+ command: "--purge-data",
2045
+ description: "Delete installer-owned data even when it contains apps"
2046
+ },
2047
+ {
2048
+ command: "--keep-zone",
2049
+ description: "Explicitly retain an installer-created zone"
2050
+ }
2051
+ ]
967
2052
  }
968
- ],
969
- children: {
970
- login: basicSubcommand("Log in with GitHub or Google.", "void auth login"),
971
- logout: basicSubcommand("Log out and remove credentials.", "void auth logout"),
972
- whoami: basicSubcommand("Show the logged-in username.", "void auth whoami"),
973
- token: basicSubcommand("Copy auth token to clipboard.", "void auth token")
974
2053
  }
975
2054
  },
976
2055
  project: {
@@ -1162,6 +2241,137 @@ const HELP_TREE = {
1162
2241
  }
1163
2242
  }
1164
2243
  },
2244
+ email: {
2245
+ summary: "Inspect email activity, manage verified recipients, and send and receive at your own domain.",
2246
+ usage: ["void email <command>"],
2247
+ commands: [
2248
+ {
2249
+ command: "usage",
2250
+ description: "Show monthly outbound/inbound counts and quota"
2251
+ },
2252
+ {
2253
+ command: "logs",
2254
+ description: "Show recent email delivery activity"
2255
+ },
2256
+ {
2257
+ command: "destinations",
2258
+ description: "List verified recipient addresses"
2259
+ },
2260
+ {
2261
+ command: "allow <address>",
2262
+ description: "Add a recipient and trigger CF verification"
2263
+ },
2264
+ {
2265
+ command: "disallow <address>",
2266
+ description: "Remove a recipient from the allowlist"
2267
+ },
2268
+ {
2269
+ command: "domain <add|status|list|sync|remove>",
2270
+ description: "Send and receive at your own domain on a Cloudflare zone"
2271
+ },
2272
+ {
2273
+ command: "status --platform cloudflare",
2274
+ description: "Show the email setup state and address map on your own account"
2275
+ },
2276
+ {
2277
+ command: "setup --platform cloudflare",
2278
+ description: "Set email up on your own Cloudflare account (one confirmation)"
2279
+ }
2280
+ ],
2281
+ children: {
2282
+ usage: withProjectOption("Show monthly outbound/inbound counts and quota.", "void email usage [options]"),
2283
+ logs: {
2284
+ summary: "Show recent email delivery activity.",
2285
+ usage: ["void email logs [options]"],
2286
+ options: [{
2287
+ command: "--project <name>",
2288
+ description: "Project name override"
2289
+ }, {
2290
+ command: "--limit <n>",
2291
+ description: "How many entries to show (positive integer)"
2292
+ }]
2293
+ },
2294
+ destinations: withProjectOption("List verified recipient addresses.", "void email destinations [options]"),
2295
+ allow: withProjectOption("Add a recipient and trigger a Cloudflare verification email.", "void email allow <address> [options]"),
2296
+ disallow: withProjectOption("Remove a recipient from the verified allowlist.", "void email disallow <address> [options]"),
2297
+ domain: {
2298
+ summary: "Send and receive at your own domain on a Cloudflare zone.",
2299
+ usage: ["void email domain <verb> [<domain>] [options]"],
2300
+ commands: [
2301
+ {
2302
+ command: "add <domain>",
2303
+ description: "Register the domain (OAuth grant, or a scoped API token)"
2304
+ },
2305
+ {
2306
+ command: "status <domain>",
2307
+ description: "Show state; re-probes the credential and relay, polls a pending row"
2308
+ },
2309
+ {
2310
+ command: "list",
2311
+ description: "List registered email domains"
2312
+ },
2313
+ {
2314
+ command: "sync <domain>",
2315
+ description: "Redeploy the relay at the current version and rotate its secret"
2316
+ },
2317
+ {
2318
+ command: "remove <domain>",
2319
+ description: "Delete the registration, stored credential, and relay secret"
2320
+ }
2321
+ ],
2322
+ options: [{
2323
+ command: "--subdomain <label|host>",
2324
+ description: "On add: register this subdomain instead of the proposed mail.<domain>"
2325
+ }, {
2326
+ command: "--project <name>",
2327
+ description: "Project name override"
2328
+ }],
2329
+ children: {
2330
+ add: {
2331
+ summary: "Register a domain on a Cloudflare zone you own for sending and receiving. Proposes mail.<domain> when the apex already carries MX.",
2332
+ usage: ["void email domain add <domain> [options]"],
2333
+ options: [{
2334
+ command: "--subdomain <label|host>",
2335
+ description: "Register this subdomain instead of the proposed mail.<domain>"
2336
+ }, {
2337
+ command: "--project <name>",
2338
+ description: "Project name override"
2339
+ }]
2340
+ },
2341
+ status: withProjectOption("Show a registered domain, re-probing its credential and relay.", "void email domain status <domain> [options]"),
2342
+ list: withProjectOption("List registered email domains.", "void email domain list [options]"),
2343
+ sync: withProjectOption("Redeploy the relay at the current version and rotate its secret.", "void email domain sync <domain> [options]"),
2344
+ remove: {
2345
+ summary: "Delete the registration, stored credential, and relay secret.",
2346
+ usage: ["void email domain remove <domain> [options]"],
2347
+ options: [{
2348
+ command: "--force",
2349
+ description: "Drop the row even when Cloudflare-side cleanup fails"
2350
+ }, {
2351
+ command: "--project <name>",
2352
+ description: "Project name override"
2353
+ }]
2354
+ }
2355
+ }
2356
+ },
2357
+ status: {
2358
+ summary: "Show the email setup state and address map. Exit 1 when not ready.",
2359
+ usage: ["void email status --platform cloudflare"],
2360
+ options: [{
2361
+ command: "--platform cloudflare",
2362
+ description: "Your own Cloudflare account (the only platform with a status today)"
2363
+ }]
2364
+ },
2365
+ setup: {
2366
+ summary: "Set email up on your own Cloudflare account: enable Email Routing, onboard Email Sending, write send_email + addresses into wrangler.jsonc. Asks once before changing the account.",
2367
+ usage: ["void email setup --platform cloudflare"],
2368
+ options: [{
2369
+ command: "--platform cloudflare",
2370
+ description: "Your own Cloudflare account (required; the Void platform needs no setup)"
2371
+ }]
2372
+ }
2373
+ }
2374
+ },
1165
2375
  github: {
1166
2376
  summary: "Connect a GitHub repository for automatic deploys.",
1167
2377
  usage: ["void github <command>"],
@@ -1392,9 +2602,13 @@ const HELP_TREE = {
1392
2602
  command: "export",
1393
2603
  description: "Export local database as SQL"
1394
2604
  },
2605
+ {
2606
+ command: "connect",
2607
+ description: "Connect or provision an external database"
2608
+ },
1395
2609
  {
1396
2610
  command: "set-url",
1397
- description: "Update the PostgreSQL connection string"
2611
+ description: "Update the external database URL"
1398
2612
  },
1399
2613
  {
1400
2614
  command: "rename-migrations",
@@ -1484,45 +2698,59 @@ const HELP_TREE = {
1484
2698
  }
1485
2699
  ]
1486
2700
  },
1487
- "set-url": basicSubcommand("Update the PostgreSQL connection string for deployment.", "void db set-url"),
2701
+ connect: {
2702
+ summary: "Connect or provision an external PostgreSQL/MySQL database.",
2703
+ usage: ["void db connect [connection-string]", "void db connect --provider <name-or-module> [options]"],
2704
+ options: [
2705
+ {
2706
+ command: "--provider <name-or-module>",
2707
+ description: "Provision with an adapter"
2708
+ },
2709
+ {
2710
+ command: "--name <name>",
2711
+ description: "Provider project/database name"
2712
+ },
2713
+ {
2714
+ command: "--region <region>",
2715
+ description: "Provider region identifier"
2716
+ },
2717
+ {
2718
+ command: "--local-only",
2719
+ description: "Do not sync a linked Void project"
2720
+ }
2721
+ ],
2722
+ examples: [{
2723
+ command: "void db connect \"postgresql://user:pass@host/db\"",
2724
+ description: "Connect an existing database"
2725
+ }, {
2726
+ command: "void db connect --provider neon --name my-app",
2727
+ description: "Provision a Neon database using NEON_API_KEY"
2728
+ }]
2729
+ },
2730
+ "set-url": basicSubcommand("Update the external database connection string for deployment.", "void db set-url"),
1488
2731
  "rename-migrations": basicSubcommand("Rename migrations to timestamp-based format.", "void db rename-migrations")
1489
2732
  }
1490
2733
  },
1491
2734
  env: {
1492
- summary: "Validate env.ts and generate environment artifacts.",
2735
+ summary: "Validate env.ts and generate environment types.",
1493
2736
  usage: ["void env <command>"],
1494
- commands: [
1495
- {
1496
- command: "check",
1497
- description: "Validate env.ts against .env files"
1498
- },
1499
- {
1500
- command: "types",
1501
- description: "Regenerate .void/env.d.ts from env.ts"
1502
- },
1503
- {
1504
- command: "example",
1505
- description: "Generate .env.example from env.ts schema"
1506
- }
1507
- ],
2737
+ commands: [{
2738
+ command: "check",
2739
+ description: "Validate local .env or remote secret names"
2740
+ }, {
2741
+ command: "types",
2742
+ description: "Regenerate .void/env.d.ts from env.ts"
2743
+ }],
1508
2744
  children: {
1509
2745
  check: {
1510
- summary: "Validate env.ts against .env files and optionally remote secrets.",
2746
+ summary: "Validate local .env or required remote secret names.",
1511
2747
  usage: ["void env check [options]"],
1512
2748
  options: [{
1513
2749
  command: "--remote",
1514
- description: "Also check required keys as remote secrets"
2750
+ description: "Check required server keys as remote secrets"
1515
2751
  }]
1516
2752
  },
1517
- types: basicSubcommand("Regenerate .void/env.d.ts from env.ts.", "void env types"),
1518
- example: {
1519
- summary: "Refresh the Void-managed block in .env.example.",
1520
- usage: ["void env example [options]"],
1521
- options: [{
1522
- command: "--force",
1523
- description: "Suppress the appended block notice"
1524
- }]
1525
- }
2753
+ types: basicSubcommand("Regenerate .void/env.d.ts from env.ts.", "void env types")
1526
2754
  }
1527
2755
  },
1528
2756
  gen: {
@@ -1614,10 +2842,6 @@ const HELP_TREE = {
1614
2842
  command: "void prepare",
1615
2843
  description: "Refresh generated project types"
1616
2844
  }]
1617
- },
1618
- mcp: {
1619
- summary: "Start the Void MCP server over stdio for AI agents.",
1620
- usage: ["void mcp"]
1621
2845
  }
1622
2846
  };
1623
2847
  function basicSubcommand(summary, usage, example) {
@@ -1640,17 +2864,42 @@ function withProjectOption(summary, usage) {
1640
2864
  }]
1641
2865
  };
1642
2866
  }
2867
+ function lifecycleHelp(command, summary) {
2868
+ return {
2869
+ summary,
2870
+ usage: [`void platform ${command} [id] [--plan]${command === "disable" ? "" : " [--runtime <path>]"} [--yes]`],
2871
+ options: [
2872
+ {
2873
+ command: "--plan",
2874
+ description: "Print the exact plan without making changes"
2875
+ },
2876
+ ...command === "disable" ? [] : [{
2877
+ command: "--runtime <path>",
2878
+ description: "Deploy an integrity-checked runtime directory instead of the package"
2879
+ }],
2880
+ {
2881
+ command: "--yes",
2882
+ description: "Acknowledge non-interactive Cloudflare changes"
2883
+ }
2884
+ ]
2885
+ };
2886
+ }
1643
2887
  function printGlobalHelp() {
1644
2888
  printVoidHeader();
1645
2889
  note([
1646
2890
  globalCommandLine(["init"], "void init"),
1647
2891
  ...globalOptionLines(["init"]),
1648
2892
  "",
2893
+ globalCommandLine(["connect"], "void connect [url]"),
2894
+ ...globalOptionLines(["connect"]),
2895
+ "",
1649
2896
  globalCommandLine(["deploy"], "void deploy"),
1650
2897
  ...globalOptionLines(["deploy"]),
1651
2898
  "",
1652
2899
  ...globalCommandGroup("auth"),
1653
2900
  "",
2901
+ ...globalCommandGroup("platform"),
2902
+ "",
1654
2903
  ...globalCommandGroup("project"),
1655
2904
  "",
1656
2905
  categoryTitle("secrets"),
@@ -1658,6 +2907,8 @@ function printGlobalHelp() {
1658
2907
  "",
1659
2908
  ...globalCommandGroup("domain"),
1660
2909
  "",
2910
+ ...globalCommandGroup("email"),
2911
+ "",
1661
2912
  ...globalCommandGroup("github"),
1662
2913
  "",
1663
2914
  ...globalCommandGroup("build"),
@@ -1673,7 +2924,6 @@ function printGlobalHelp() {
1673
2924
  "",
1674
2925
  ...globalCommandGroup("env"),
1675
2926
  ...globalOptionLines(["env", "check"]),
1676
- ...globalOptionLines(["env", "example"]),
1677
2927
  "",
1678
2928
  categoryTitle("codegen"),
1679
2929
  globalCommandLine(["prepare"], "void prepare"),
@@ -1681,7 +2931,6 @@ function printGlobalHelp() {
1681
2931
  "",
1682
2932
  categoryTitle("agent"),
1683
2933
  helpLine("void init --agents", requiredOption(["init"], "--agents").description),
1684
- globalCommandLine(["mcp"], "void mcp"),
1685
2934
  "",
1686
2935
  categoryTitle("help"),
1687
2936
  helpLine("void help <command>", "Show command-specific help"),
@@ -1781,6 +3030,287 @@ function formatHelpPath(path) {
1781
3030
  return path.length === 0 ? "help" : path.join(" ");
1782
3031
  }
1783
3032
  //#endregion
3033
+ //#region src/cli/platform-args.ts
3034
+ const platformSubcommands = [
3035
+ ...operatorGroups.map((name) => ({
3036
+ name,
3037
+ hint: "Operator commands",
3038
+ description: `Administer platform ${name}`
3039
+ })),
3040
+ {
3041
+ name: "list",
3042
+ description: "List installed and connected platforms"
3043
+ },
3044
+ {
3045
+ name: "use",
3046
+ arg: "[id]",
3047
+ description: "Select the default Void platform"
3048
+ },
3049
+ {
3050
+ name: "status",
3051
+ arg: "[id]",
3052
+ description: "Inspect a platform and its health"
3053
+ },
3054
+ {
3055
+ name: "discover",
3056
+ description: "Recover installations from a Cloudflare account"
3057
+ },
3058
+ {
3059
+ name: "domain",
3060
+ hint: "Set an application domain",
3061
+ description: "Add a domain to a workers.dev test platform"
3062
+ },
3063
+ {
3064
+ name: "install",
3065
+ description: "Install a Void platform with a domain or workers.dev for testing"
3066
+ },
3067
+ {
3068
+ name: "upgrade",
3069
+ arg: "[id]",
3070
+ description: "Upgrade an installed Void platform"
3071
+ },
3072
+ {
3073
+ name: "rollback",
3074
+ arg: "[id]",
3075
+ description: "Restore a compatible earlier platform runtime"
3076
+ },
3077
+ {
3078
+ name: "repair",
3079
+ arg: "[id]",
3080
+ description: "Reconcile an installed Void platform"
3081
+ },
3082
+ {
3083
+ name: "disable",
3084
+ arg: "[id]",
3085
+ description: "Disable traffic without deleting data"
3086
+ },
3087
+ {
3088
+ name: "enable",
3089
+ arg: "[id]",
3090
+ description: "Restore traffic for a disabled platform"
3091
+ },
3092
+ {
3093
+ name: "uninstall",
3094
+ arg: "[id]",
3095
+ description: "Safely remove an installed Void platform"
3096
+ }
3097
+ ];
3098
+ function readValue(rest, index, flag) {
3099
+ const value = rest[index + 1];
3100
+ if (!value || value.startsWith("-")) throw new Error(`platform: ${flag} requires a value.`);
3101
+ return [value, index + 1];
3102
+ }
3103
+ function parseSelector(rest, subcommand, options = {}) {
3104
+ let selector = "";
3105
+ let plan = false;
3106
+ let yes = false;
3107
+ for (const arg of rest) if (arg === "--plan") plan = true;
3108
+ else if (arg === "--yes" && options.allowYes) yes = true;
3109
+ else if (arg.startsWith("-")) throw new Error(`platform: Unknown flag '${arg}'.`);
3110
+ else if (selector) throw new Error(`platform: Unexpected argument '${arg}'.`);
3111
+ else selector = arg;
3112
+ if ((subcommand === "use" || subcommand === "status") && plan) throw new Error("platform: Unknown flag '--plan'.");
3113
+ return {
3114
+ selector,
3115
+ plan,
3116
+ yes
3117
+ };
3118
+ }
3119
+ function parseLifecycleSelector(rest, subcommand) {
3120
+ const positional = [];
3121
+ let runtime = "";
3122
+ let fromRuntime = "";
3123
+ for (let index = 0; index < rest.length; index++) {
3124
+ const arg = rest[index];
3125
+ if (arg === "--runtime") {
3126
+ if (subcommand === "disable") throw new Error("platform: Unknown flag '--runtime'.");
3127
+ const [value, next] = readValue(rest, index, arg);
3128
+ runtime = value;
3129
+ index = next;
3130
+ } else if (arg === "--from-runtime" && subcommand === "rollback") {
3131
+ const [value, next] = readValue(rest, index, arg);
3132
+ fromRuntime = value;
3133
+ index = next;
3134
+ } else positional.push(arg);
3135
+ }
3136
+ const parsed = parseSelector(positional, subcommand, { allowYes: true });
3137
+ if (subcommand === "rollback" && !runtime) throw new Error("platform: rollback requires --runtime <earlier-runtime-directory>.");
3138
+ return {
3139
+ ...parsed,
3140
+ runtime,
3141
+ fromRuntime
3142
+ };
3143
+ }
3144
+ function parsePlatformArgs(args) {
3145
+ if (operatorGroups.includes(args[0] ?? "") || [
3146
+ "--connection",
3147
+ "--json",
3148
+ "--plan",
3149
+ "--yes",
3150
+ "--timeout"
3151
+ ].includes(args[0] ?? "")) return parseOperatorArgs(args);
3152
+ const [subcommand, ...rest] = args;
3153
+ if (subcommand === "domain") {
3154
+ if (rest.length === 0) return {
3155
+ subcommand,
3156
+ domain: "",
3157
+ selector: "",
3158
+ zone: "",
3159
+ dedicatedZone: false,
3160
+ plan: false,
3161
+ yes: false
3162
+ };
3163
+ if (rest[0] !== "set") throw new Error("platform: Usage: void platform domain set <domain> [--installation <id>] [--zone <domain>] [--dedicated-zone] [--plan] [--yes].");
3164
+ let domain = "";
3165
+ let selector = "";
3166
+ let zone = "";
3167
+ let plan = false;
3168
+ let yes = false;
3169
+ let dedicatedZone = false;
3170
+ for (let index = 1; index < rest.length; index++) {
3171
+ const arg = rest[index];
3172
+ if (arg === "--installation" || arg === "--zone") {
3173
+ const [value, next] = readValue(rest, index, arg);
3174
+ index = next;
3175
+ if (arg === "--zone") zone = value;
3176
+ else selector = value;
3177
+ } else if (arg === "--plan") plan = true;
3178
+ else if (arg === "--yes") yes = true;
3179
+ else if (arg === "--dedicated-zone") dedicatedZone = true;
3180
+ else if (!arg.startsWith("-") && !domain) domain = arg;
3181
+ else throw new Error(`platform: Unexpected argument '${arg}'.`);
3182
+ }
3183
+ if (!domain) throw new Error("platform: domain set requires an application domain.");
3184
+ if (plan && yes) throw new Error("platform: Use either --plan or --yes.");
3185
+ return {
3186
+ subcommand,
3187
+ domain,
3188
+ selector,
3189
+ zone,
3190
+ dedicatedZone,
3191
+ plan,
3192
+ yes
3193
+ };
3194
+ }
3195
+ if (subcommand === "list") {
3196
+ if (rest.length > 0) throw new Error(`platform: Unexpected argument '${rest[0]}'.`);
3197
+ return { subcommand };
3198
+ }
3199
+ if (subcommand === "use") {
3200
+ const { selector } = parseSelector(rest, subcommand);
3201
+ return {
3202
+ subcommand,
3203
+ selector
3204
+ };
3205
+ }
3206
+ if (subcommand === "status") {
3207
+ const { selector, plan } = parseSelector(rest, subcommand);
3208
+ if (plan) throw new Error("platform: Unknown flag '--plan'.");
3209
+ return {
3210
+ subcommand,
3211
+ selector
3212
+ };
3213
+ }
3214
+ if (subcommand === "discover") {
3215
+ let account = "";
3216
+ let selector = "";
3217
+ for (let index = 0; index < rest.length; index++) {
3218
+ const arg = rest[index];
3219
+ if (arg === "--account" || arg === "--installation") {
3220
+ const [value, next] = readValue(rest, index, arg);
3221
+ if (arg === "--account") account = value;
3222
+ else selector = value;
3223
+ index = next;
3224
+ } else throw new Error("platform: Usage: void platform discover [--account <id>] [--installation <id-or-name>].");
3225
+ }
3226
+ return {
3227
+ subcommand,
3228
+ account,
3229
+ selector
3230
+ };
3231
+ }
3232
+ if (subcommand === "upgrade" || subcommand === "rollback" || subcommand === "repair" || subcommand === "disable" || subcommand === "enable") {
3233
+ const { selector, plan, runtime, fromRuntime, yes } = parseLifecycleSelector(rest, subcommand);
3234
+ return subcommand === "rollback" ? {
3235
+ subcommand,
3236
+ selector,
3237
+ plan,
3238
+ runtime,
3239
+ fromRuntime,
3240
+ yes
3241
+ } : {
3242
+ subcommand,
3243
+ selector,
3244
+ plan,
3245
+ runtime,
3246
+ yes
3247
+ };
3248
+ }
3249
+ if (subcommand === "uninstall") {
3250
+ const parsed = parseSelector(rest.filter((arg) => ![
3251
+ "--purge-data",
3252
+ "--delete-zone",
3253
+ "--keep-zone"
3254
+ ].includes(arg)), subcommand, { allowYes: true });
3255
+ if (rest.includes("--delete-zone") && rest.includes("--keep-zone")) throw new Error("platform: --delete-zone and --keep-zone cannot be used together.");
3256
+ return {
3257
+ subcommand,
3258
+ selector: parsed.selector,
3259
+ plan: parsed.plan,
3260
+ purgeData: rest.includes("--purge-data"),
3261
+ yes: parsed.yes,
3262
+ deleteZone: rest.includes("--delete-zone") ? true : rest.includes("--keep-zone") ? false : null
3263
+ };
3264
+ }
3265
+ if (subcommand === "install") {
3266
+ const values = /* @__PURE__ */ new Map();
3267
+ let plan = false;
3268
+ let resume = false;
3269
+ let dedicatedZone = false;
3270
+ let yes = false;
3271
+ const valueFlags = /* @__PURE__ */ new Set([
3272
+ "--account",
3273
+ "--application-domain",
3274
+ "--control-plane-domain",
3275
+ "--display-name",
3276
+ "--name",
3277
+ "--runtime",
3278
+ "--zone"
3279
+ ]);
3280
+ let workersDev = false;
3281
+ for (let i = 0; i < rest.length; i++) {
3282
+ const arg = rest[i];
3283
+ if (valueFlags.has(arg)) {
3284
+ const [value, next] = readValue(rest, i, arg);
3285
+ values.set(arg, value);
3286
+ i = next;
3287
+ } else if (arg === "--plan") plan = true;
3288
+ else if (arg === "--resume") resume = true;
3289
+ else if (arg === "--dedicated-zone") dedicatedZone = true;
3290
+ else if (arg === "--yes") yes = true;
3291
+ else if (arg === "--workers-dev") workersDev = true;
3292
+ else throw new Error(`platform: Unexpected argument '${arg}'.`);
3293
+ }
3294
+ if (workersDev && (values.has("--application-domain") || values.has("--zone") || dedicatedZone)) throw new Error("platform: --workers-dev cannot be combined with a domain, zone, or --dedicated-zone.");
3295
+ return {
3296
+ subcommand,
3297
+ ...workersDev ? { workersDev: true } : {},
3298
+ account: values.get("--account") ?? "",
3299
+ applicationDomain: values.get("--application-domain") ?? "",
3300
+ controlPlaneDomain: values.get("--control-plane-domain") ?? "",
3301
+ dedicatedZone,
3302
+ displayName: values.get("--display-name") ?? "",
3303
+ name: values.get("--name") ?? "",
3304
+ plan,
3305
+ resume,
3306
+ runtime: values.get("--runtime") ?? "",
3307
+ yes,
3308
+ zone: values.get("--zone") ?? ""
3309
+ };
3310
+ }
3311
+ throw new Error("platform: Usage: void platform <auth|user|project|deployment|build|signup|invitation|system|worker|list|use|status|discover|install|domain|upgrade|rollback|repair|disable|enable|uninstall>.");
3312
+ }
3313
+ //#endregion
1784
3314
  //#region src/cli/prepare-args.ts
1785
3315
  function parsePrepareArgs(args) {
1786
3316
  const parsed = parseArgs({
@@ -2047,94 +3577,115 @@ function buildArgs(result, trailingArgs) {
2047
3577
  async function runSubcommandGroup(command, subcommands, parse, run) {
2048
3578
  const root = process.cwd();
2049
3579
  const sub = args[1];
3580
+ const hasNamedSubcommand = args.slice(1).some((arg) => subcommands.some(({ name }) => name === arg));
2050
3581
  try {
2051
- if ((!sub || sub.startsWith("-")) && process.stdin.isTTY) {
2052
- const { promptSubcommand } = await import("../subcommand-prompt-BzV8iQZo.mjs");
3582
+ if ((!sub || sub.startsWith("-") && !hasNamedSubcommand) && process.stdin.isTTY) {
3583
+ const { promptSubcommand } = await import("../subcommand-prompt-WfySCQ7S.mjs");
2053
3584
  const result = await promptSubcommand(command, subcommands);
2054
3585
  if (!result) process.exit(0);
2055
3586
  await run(root, parse(buildArgs(result, args.slice(1))));
2056
3587
  } else await run(root, parse(args.slice(1)));
2057
3588
  } catch (err) {
2058
- log.error(err instanceof Error ? err.message : String(err));
3589
+ if (command === "platform" && args.includes("--json")) {
3590
+ console.error(JSON.stringify(err instanceof OperatorClientError ? err.toJSON() : {
3591
+ error: "invalid_command",
3592
+ message: err instanceof Error ? err.message : String(err)
3593
+ }));
3594
+ process.exit(1);
3595
+ }
3596
+ const message = formatCloudflareUserMessage(err instanceof Error ? err.message : String(err));
3597
+ if (command === "platform") console.error(err instanceof OperatorClientError && err.details !== void 0 ? `${message}\nPartial result:\n${JSON.stringify(err.details, null, 2)}` : message);
3598
+ else log.error(message);
2059
3599
  process.exit(1);
2060
3600
  }
2061
3601
  }
2062
3602
  const args = process.argv.slice(2);
2063
3603
  const command = args[0];
2064
3604
  const helpPath = getHelpPath(args);
2065
- if (helpPath) if (helpPath.length === 0) printGlobalHelp();
2066
- else try {
2067
- printHelpPage(helpPath);
2068
- } catch (err) {
2069
- log.error(err instanceof Error ? err.message : String(err));
2070
- process.exit(1);
2071
- }
2072
- else if (command === "deploy") {
3605
+ if (helpPath) {
3606
+ if (helpPath.length === 0) printGlobalHelp();
3607
+ else try {
3608
+ printHelpPage(helpPath);
3609
+ } catch (err) {
3610
+ log.error(formatCloudflareUserMessage(err instanceof Error ? err.message : String(err)));
3611
+ process.exit(1);
3612
+ }
3613
+ } else if (command === "deploy") {
2073
3614
  const root = process.cwd();
2074
3615
  let deployArgs;
2075
3616
  try {
2076
3617
  deployArgs = parseDeployArgs(args.slice(1));
2077
3618
  } catch (err) {
2078
- log.error(err instanceof Error ? err.message : String(err));
3619
+ log.error(formatCloudflareUserMessage(err instanceof Error ? err.message : String(err)));
2079
3620
  process.exit(1);
2080
3621
  }
2081
- import("../deploy-jBJT1fUT.mjs").then((n) => n.t).then(({ runDeploy }) => {
3622
+ import("../deploy-iXZ3F0N6.mjs").then((n) => n.n).then(({ runDeploy }) => {
2082
3623
  runDeploy(root, {
2083
3624
  projectSlug: deployArgs.projectSlug,
2084
3625
  dir: deployArgs.dir,
2085
3626
  spa: deployArgs.spa,
2086
3627
  skipBuild: deployArgs.skipBuild,
2087
3628
  debug: deployArgs.debug,
3629
+ platform: deployArgs.platform,
2088
3630
  backend: deployArgs.backend,
2089
- provision: deployArgs.provision
3631
+ provision: deployArgs.provision,
3632
+ requireEmail: deployArgs.requireEmail
2090
3633
  }).catch((err) => {
2091
- log.error(err.message ?? err);
3634
+ log.error(formatCloudflareUserMessage(err.message ?? String(err)));
2092
3635
  process.exit(1);
2093
3636
  });
2094
3637
  });
2095
- } else if (command === "auth") runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (root, parsed) => import("../auth-cmd-BqsdZJp5.mjs").then(({ runAuthCommand }) => runAuthCommand(root, parsed)));
2096
- else if (command === "project") runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (root, parsed) => import("../project-cmd-D_w-4w5B.mjs").then(({ runProjectCommand }) => runProjectCommand(root, parsed)));
2097
- else if (command === "secret") runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (root, parsed) => import("../secret-Dt32J6RI.mjs").then(({ runSecretCommand }) => runSecretCommand(root, parsed)));
2098
- else if (command === "domain") runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (root, parsed) => import("../domain-DiaNQbrl.mjs").then(({ runDomainCommand }) => runDomainCommand(root, parsed)));
2099
- else if (command === "db") runSubcommandGroup("db", dbSubcommands, parseDbArgs, (root, parsed) => import("../db-C0i0sYMS.mjs").then(({ runDbCommand }) => runDbCommand(root, parsed)));
2100
- else if (command === "env") runSubcommandGroup("env", envSubcommands, parseEnvArgs, (root, parsed) => import("../env-CZy5MorI.mjs").then(({ runEnvCommand }) => runEnvCommand(root, parsed)));
2101
- else if (command === "gen") runSubcommandGroup("gen", genSubcommands, parseGenArgs, (root, parsed) => import("../gen-BzXf3Jh2.mjs").then(({ runGenCommand }) => runGenCommand(root, parsed)));
2102
- else if (command === "github") runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (root, parsed) => import("../github-cmd-DKcGUNsj.mjs").then(({ runGithubCommand }) => runGithubCommand(root, parsed)));
2103
- else if (command === "build") runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (root, parsed) => import("../build-cmd-Bujrv5q-.mjs").then(({ runBuildCommand }) => runBuildCommand(root, parsed)));
3638
+ } else if (command === "connect") (async () => {
3639
+ const parsed = parseConnectArgs(args.slice(1));
3640
+ const { runConnectCommand } = await import("../connect-C04Wdy_h.mjs");
3641
+ await runConnectCommand(process.cwd(), parsed);
3642
+ })().catch((err) => {
3643
+ log.error(formatCloudflareUserMessage(err instanceof Error ? err.message : String(err)));
3644
+ process.exit(1);
3645
+ });
3646
+ else if (command === "auth") runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (root, parsed) => import("../auth-cmd-CAH62yDU.mjs").then(({ runAuthCommand }) => runAuthCommand(root, parsed)));
3647
+ else if (command === "platform") runSubcommandGroup("platform", platformSubcommands, parsePlatformArgs, (root, parsed) => import("../platform-cmd-DxJ2FRwR.mjs").then(({ runPlatformCommand }) => runPlatformCommand(root, parsed)));
3648
+ else if (command === "cloudflare") runSubcommandGroup("cloudflare", cloudflareSubcommands, parseCloudflareArgs, (root, parsed) => import("../cloudflare-cmd-B6_OZx2V.mjs").then(({ runCloudflareCommand }) => runCloudflareCommand(root, parsed)));
3649
+ else if (command === "project") runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (root, parsed) => import("../project-cmd-Mo0V9yKS.mjs").then(({ runProjectCommand }) => runProjectCommand(root, parsed)));
3650
+ else if (command === "secret") runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (root, parsed) => import("../secret-ByhJ9AMl.mjs").then(({ runSecretCommand }) => runSecretCommand(root, parsed)));
3651
+ else if (command === "domain") runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (root, parsed) => import("../domain-B1VmoSr0.mjs").then(({ runDomainCommand }) => runDomainCommand(root, parsed)));
3652
+ else if (command === "email") runSubcommandGroup("email", emailSubcommands, parseEmailArgs, (root, parsed) => import("../email-uKyQYUVY.mjs").then(({ runEmailCommand }) => runEmailCommand(root, parsed)));
3653
+ else if (command === "db") runSubcommandGroup("db", dbSubcommands, parseDbArgs, (root, parsed) => import("../db-D2d_mUsB.mjs").then(({ runDbCommand }) => runDbCommand(root, parsed)));
3654
+ else if (command === "env") runSubcommandGroup("env", envSubcommands, parseEnvArgs, (root, parsed) => import("../env-BcQzYgoG.mjs").then(({ runEnvCommand }) => runEnvCommand(root, parsed)));
3655
+ else if (command === "gen") runSubcommandGroup("gen", genSubcommands, parseGenArgs, (root, parsed) => import("../gen-DI2YwdBM.mjs").then(({ runGenCommand }) => runGenCommand(root, parsed)));
3656
+ else if (command === "github") runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (root, parsed) => import("../github-cmd-xItS5Zwf.mjs").then(({ runGithubCommand }) => runGithubCommand(root, parsed)));
3657
+ else if (command === "build") runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (root, parsed) => import("../build-cmd-CJvZvPQO.mjs").then(({ runBuildCommand }) => runBuildCommand(root, parsed)));
2104
3658
  else if (command === "prepare") {
2105
3659
  const root = process.cwd();
2106
3660
  let prepareArgs;
2107
3661
  try {
2108
3662
  prepareArgs = parsePrepareArgs(args.slice(1));
2109
3663
  } catch (err) {
2110
- log.error(err instanceof Error ? err.message : String(err));
3664
+ log.error(formatCloudflareUserMessage(err instanceof Error ? err.message : String(err)));
2111
3665
  process.exit(1);
2112
3666
  }
2113
- import("../prepare-BvvgAz-3.mjs").then(({ runPrepareCommand }) => {
3667
+ import("../prepare-BfJvFUtJ.mjs").then(({ runPrepareCommand }) => {
2114
3668
  runPrepareCommand(root, prepareArgs).catch((err) => {
2115
- log.error(err.message ?? err);
3669
+ log.error(formatCloudflareUserMessage(err.message ?? String(err)));
2116
3670
  process.exit(1);
2117
3671
  });
2118
3672
  });
2119
3673
  } else if (command === "init") {
2120
3674
  const root = process.cwd();
2121
- import("../init-7JCAcKNQ.mjs").then(({ runInitCommand, parseInitArgs }) => {
3675
+ import("../init-BD-9THgn.mjs").then(({ runInitCommand, parseInitArgs }) => {
2122
3676
  let initArgs;
2123
3677
  try {
2124
3678
  initArgs = parseInitArgs(args.slice(1));
2125
3679
  } catch (err) {
2126
- log.error(err instanceof Error ? err.message : String(err));
3680
+ log.error(formatCloudflareUserMessage(err instanceof Error ? err.message : String(err)));
2127
3681
  process.exit(1);
2128
3682
  }
2129
3683
  runInitCommand(root, initArgs).catch((err) => {
2130
- log.error(err.message ?? err);
3684
+ log.error(formatCloudflareUserMessage(err.message ?? String(err)));
2131
3685
  process.exit(1);
2132
3686
  });
2133
3687
  });
2134
- } else if (command === "mcp") import("../mcp-DoM3_nhd.mjs").then(({ runMcp }) => {
2135
- runMcp();
2136
- });
2137
- else if (command === "-v" || command === "--version") {
3688
+ } else if (command === "-v" || command === "--version") {
2138
3689
  const version = JSON.parse(readFileSync(join(getPackageDir(), "package.json"), "utf-8")).version;
2139
3690
  console.log(version);
2140
3691
  } else if (command && command !== "help" && command !== "--help" && command !== "-h") {
@@ -2144,17 +3695,32 @@ else if (command === "-v" || command === "--version") {
2144
3695
  const topLevelCommands = [
2145
3696
  {
2146
3697
  name: "init",
3698
+ hint: "--agents | --tsconfig | --github | --git | --no-git",
2147
3699
  description: "Set up void in a new or existing project"
2148
3700
  },
3701
+ {
3702
+ name: "connect",
3703
+ description: "Connect to Cloudflare or a Void platform"
3704
+ },
2149
3705
  {
2150
3706
  name: "deploy",
2151
- description: "Build and deploy to Void"
3707
+ description: "Build and deploy, or link an existing Cloudflare Worker"
2152
3708
  },
2153
3709
  {
2154
3710
  name: "auth",
2155
3711
  hint: "login | logout | whoami | token",
2156
3712
  description: "Login, logout, and token management"
2157
3713
  },
3714
+ {
3715
+ name: "platform",
3716
+ hint: "auth | user | project | deployment | signup | system | install",
3717
+ description: "Install platforms and administer users, projects, access, and operations"
3718
+ },
3719
+ {
3720
+ name: "cloudflare",
3721
+ hint: "login | status | logout",
3722
+ description: "Manage Cloudflare sign-in and inspect the deployment account"
3723
+ },
2158
3724
  {
2159
3725
  name: "project",
2160
3726
  hint: "status | link | list | logs | requests | rollback | cancel | delete | purge-cache",
@@ -2170,6 +3736,11 @@ else if (command === "-v" || command === "--version") {
2170
3736
  hint: "add | delete | list | status",
2171
3737
  description: "Configure custom domains"
2172
3738
  },
3739
+ {
3740
+ name: "email",
3741
+ hint: "usage | logs | destinations | allow | disallow | domain | status | setup",
3742
+ description: "Inspect email activity and manage verified recipients"
3743
+ },
2173
3744
  {
2174
3745
  name: "github",
2175
3746
  hint: "install | installations | connect | update | status | disconnect | link | join",
@@ -2182,13 +3753,13 @@ else if (command === "-v" || command === "--version") {
2182
3753
  },
2183
3754
  {
2184
3755
  name: "db",
2185
- hint: "status | reset | seed | execute | migrate | studio | export | rename-migrations",
3756
+ hint: "connect | status | reset | seed | execute | migrate | studio | export",
2186
3757
  description: "Database migrations and management"
2187
3758
  },
2188
3759
  {
2189
3760
  name: "env",
2190
- hint: "check | types | example",
2191
- description: "Validate env.ts, generate types, or scaffold .env.example"
3761
+ hint: "check | types",
3762
+ description: "Validate env.ts or generate types"
2192
3763
  },
2193
3764
  {
2194
3765
  name: "gen",
@@ -2199,10 +3770,6 @@ else if (command === "-v" || command === "--version") {
2199
3770
  name: "prepare",
2200
3771
  description: "Generate .void artifacts without starting Vite"
2201
3772
  },
2202
- {
2203
- name: "mcp",
2204
- description: "Start MCP server (for AI agents)"
2205
- },
2206
3773
  {
2207
3774
  name: "help",
2208
3775
  description: "Show help message"
@@ -2210,38 +3777,41 @@ else if (command === "-v" || command === "--version") {
2210
3777
  ];
2211
3778
  (async () => {
2212
3779
  printVoidHeader();
2213
- const { promptSubcommand } = await import("../subcommand-prompt-BzV8iQZo.mjs");
3780
+ const { promptSubcommand } = await import("../subcommand-prompt-WfySCQ7S.mjs");
2214
3781
  const result = await promptSubcommand("", topLevelCommands);
2215
3782
  if (!result) process.exit(0);
2216
3783
  const cmd = result.subcommand;
2217
3784
  const root = process.cwd();
2218
3785
  switch (cmd) {
3786
+ case "connect": {
3787
+ const { runConnectCommand } = await import("../connect-C04Wdy_h.mjs");
3788
+ await runConnectCommand(root, parseConnectArgs([]));
3789
+ return;
3790
+ }
2219
3791
  case "init": {
2220
- const { runInitCommand, parseInitArgs } = await import("../init-7JCAcKNQ.mjs");
3792
+ const { runInitCommand, parseInitArgs } = await import("../init-BD-9THgn.mjs");
2221
3793
  await runInitCommand(root, parseInitArgs([]));
2222
3794
  return;
2223
3795
  }
2224
3796
  case "deploy": {
2225
- const { runDeploy } = await import("../deploy-jBJT1fUT.mjs").then((n) => n.t);
3797
+ const { runDeploy } = await import("../deploy-iXZ3F0N6.mjs").then((n) => n.n);
2226
3798
  await runDeploy(root);
2227
3799
  return;
2228
3800
  }
2229
- case "mcp": {
2230
- const { runMcp } = await import("../mcp-DoM3_nhd.mjs");
2231
- runMcp();
2232
- return;
2233
- }
2234
- case "auth": return runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (r, p) => import("../auth-cmd-BqsdZJp5.mjs").then(({ runAuthCommand }) => runAuthCommand(r, p)));
2235
- case "project": return runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (r, p) => import("../project-cmd-D_w-4w5B.mjs").then(({ runProjectCommand }) => runProjectCommand(r, p)));
2236
- case "secret": return runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (r, p) => import("../secret-Dt32J6RI.mjs").then(({ runSecretCommand }) => runSecretCommand(r, p)));
2237
- case "domain": return runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (r, p) => import("../domain-DiaNQbrl.mjs").then(({ runDomainCommand }) => runDomainCommand(r, p)));
2238
- case "github": return runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (r, p) => import("../github-cmd-DKcGUNsj.mjs").then(({ runGithubCommand }) => runGithubCommand(r, p)));
2239
- case "build": return runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (r, p) => import("../build-cmd-Bujrv5q-.mjs").then(({ runBuildCommand }) => runBuildCommand(r, p)));
2240
- case "db": return runSubcommandGroup("db", dbSubcommands, parseDbArgs, (r, p) => import("../db-C0i0sYMS.mjs").then(({ runDbCommand }) => runDbCommand(r, p)));
2241
- case "env": return runSubcommandGroup("env", envSubcommands, parseEnvArgs, (r, p) => import("../env-CZy5MorI.mjs").then(({ runEnvCommand }) => runEnvCommand(r, p)));
2242
- case "gen": return runSubcommandGroup("gen", genSubcommands, parseGenArgs, (r, p) => import("../gen-BzXf3Jh2.mjs").then(({ runGenCommand }) => runGenCommand(r, p)));
3801
+ case "auth": return runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (r, p) => import("../auth-cmd-CAH62yDU.mjs").then(({ runAuthCommand }) => runAuthCommand(r, p)));
3802
+ case "platform": return runSubcommandGroup("platform", platformSubcommands, parsePlatformArgs, (r, p) => import("../platform-cmd-DxJ2FRwR.mjs").then(({ runPlatformCommand }) => runPlatformCommand(r, p)));
3803
+ case "cloudflare": return runSubcommandGroup("cloudflare", cloudflareSubcommands, parseCloudflareArgs, (r, p) => import("../cloudflare-cmd-B6_OZx2V.mjs").then(({ runCloudflareCommand }) => runCloudflareCommand(r, p)));
3804
+ case "project": return runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (r, p) => import("../project-cmd-Mo0V9yKS.mjs").then(({ runProjectCommand }) => runProjectCommand(r, p)));
3805
+ case "secret": return runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (r, p) => import("../secret-ByhJ9AMl.mjs").then(({ runSecretCommand }) => runSecretCommand(r, p)));
3806
+ case "domain": return runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (r, p) => import("../domain-B1VmoSr0.mjs").then(({ runDomainCommand }) => runDomainCommand(r, p)));
3807
+ case "github": return runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (r, p) => import("../github-cmd-xItS5Zwf.mjs").then(({ runGithubCommand }) => runGithubCommand(r, p)));
3808
+ case "build": return runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (r, p) => import("../build-cmd-CJvZvPQO.mjs").then(({ runBuildCommand }) => runBuildCommand(r, p)));
3809
+ case "email": return runSubcommandGroup("email", emailSubcommands, parseEmailArgs, (r, p) => import("../email-uKyQYUVY.mjs").then(({ runEmailCommand }) => runEmailCommand(r, p)));
3810
+ case "db": return runSubcommandGroup("db", dbSubcommands, parseDbArgs, (r, p) => import("../db-D2d_mUsB.mjs").then(({ runDbCommand }) => runDbCommand(r, p)));
3811
+ case "env": return runSubcommandGroup("env", envSubcommands, parseEnvArgs, (r, p) => import("../env-BcQzYgoG.mjs").then(({ runEnvCommand }) => runEnvCommand(r, p)));
3812
+ case "gen": return runSubcommandGroup("gen", genSubcommands, parseGenArgs, (r, p) => import("../gen-DI2YwdBM.mjs").then(({ runGenCommand }) => runGenCommand(r, p)));
2243
3813
  case "prepare": {
2244
- const { runPrepareCommand } = await import("../prepare-BvvgAz-3.mjs");
3814
+ const { runPrepareCommand } = await import("../prepare-BfJvFUtJ.mjs");
2245
3815
  await runPrepareCommand(root, parsePrepareArgs([]));
2246
3816
  return;
2247
3817
  }
@@ -2250,9 +3820,9 @@ else if (command === "-v" || command === "--version") {
2250
3820
  return;
2251
3821
  }
2252
3822
  })().catch((err) => {
2253
- log.error(err instanceof Error ? err.message : String(err));
3823
+ log.error(formatCloudflareUserMessage(err instanceof Error ? err.message : String(err)));
2254
3824
  process.exit(1);
2255
3825
  });
2256
3826
  } else printGlobalHelp();
2257
3827
  //#endregion
2258
- export {};
3828
+ export { OperatorClient as n, OperatorClientError as r, help_exports as t };