void 0.21.9 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/README.md +5 -1
  2. package/dist/{account-cmd-DZZGK80W.mjs → account-cmd-C84Ee8cO.mjs} +5 -5
  3. package/dist/{scan-ClYmX3sa.mjs → application-analysis-BVsVqc11.mjs} +135 -18
  4. package/dist/application-routing-B7QEjqSR.mjs +27 -0
  5. package/dist/{auth-CZuiVsFh.mjs → auth-CCjt0hcq.mjs} +1 -1
  6. package/dist/{auth-DLNN0D3Z.mjs → auth-CSkdO2Bb.mjs} +4 -47
  7. package/dist/{auth-link-B_CeugBw.mjs → auth-link-CioEg6uY.mjs} +5 -5
  8. package/dist/{auth-router-BgEFRuvZ.mjs → auth-router-BsR981d4.mjs} +5 -5
  9. package/dist/{better-auth-shared-rsBGBvWJ.mjs → better-auth-shared-hy6RPh9W.mjs} +13 -2
  10. package/dist/{build-cmd-Dpt0jd-x.mjs → build-cmd-LzvNJORH.mjs} +19 -7
  11. package/dist/{cache-7_UeZdTk.mjs → cache-C4MvnrMH.mjs} +4 -4
  12. package/dist/{cancel-deploy-D23R1RXT.mjs → cancel-deploy-abUxpP2n.mjs} +4 -4
  13. package/dist/{cf-build-output-CGT03qCD.mjs → cf-build-output-BPqOT964.mjs} +141 -63
  14. package/dist/cf-build-output-_0HNWysu.mjs +2 -0
  15. package/dist/cli/cli.mjs +114 -460
  16. package/dist/cli/cloudflare-operation-process.mjs +1103 -0
  17. package/dist/cli/env-schema-probe.d.mts +2 -1
  18. package/dist/cli/env-schema-probe.mjs +3 -3
  19. package/dist/client-Cu7jWiF1.mjs +2 -0
  20. package/dist/{client-QTl6ko_D.mjs → client-RV8NVeB8.mjs} +165 -21
  21. package/dist/{cloudflare-auth-C4_GPZr0.mjs → cloudflare-auth-Qdc7tw8F.mjs} +41 -43
  22. package/dist/{cloudflare-cmd-bSmZ1d5L.mjs → cloudflare-cmd-BcrVyTmJ.mjs} +9 -10
  23. package/dist/cloudflare-config-Bktvwtpf.mjs +182 -0
  24. package/dist/{cloudflare-connect-jAwacxxP.mjs → cloudflare-connect-B8uPZ4nx.mjs} +4 -4
  25. package/dist/{cloudflare-operations-BipGMJ5O.mjs → cloudflare-operations-AiWashgg.mjs} +1 -1
  26. package/dist/{cloudflare-operations-sMZXpk_S.mjs → cloudflare-operations-fxHb-byx.mjs} +118 -203
  27. package/dist/{preset-UHj9ARyP.mjs → cloudflare-process-B-wekeR6.mjs} +93 -6
  28. package/dist/{config-CF69HgXc.d.mts → config-BMHb8RCj.d.mts} +2 -2
  29. package/dist/{config-CafTW6Cz.mjs → config-Br_JZD6u.mjs} +2 -7
  30. package/dist/config-C_XRIPx2.mjs +89 -0
  31. package/dist/{config-s7Xj7tPb.mjs → config-CyQ-wVd7.mjs} +1 -1
  32. package/dist/config-entry.d.mts +1 -1
  33. package/dist/{config-write-BSduPMY8.mjs → config-write-B1f88wJA.mjs} +1 -1
  34. package/dist/{connect-BsUSRzln.mjs → connect-Bd4kJd9U.mjs} +6 -6
  35. package/dist/{create-project-BniEV0OW.mjs → create-project-Boczwj5r.mjs} +1 -1
  36. package/dist/{create-project-DBfFSZKY.mjs → create-project-bMf6ffLZ.mjs} +9 -5
  37. package/dist/{db-hRrvZaq_.mjs → db-8uG64XLl.mjs} +26 -26
  38. package/dist/{delete-D6dZ9B6B.mjs → delete-NvbiyeJf.mjs} +4 -4
  39. package/dist/{deploy-WaAQez1O.mjs → deploy-DzAIwqNU.mjs} +944 -607
  40. package/dist/{deploy-DDz7c8LK.mjs → deploy-bjXdFCtn.mjs} +1 -1
  41. package/dist/{dist-BR1quN_w.mjs → dist-AoCzRTJE.mjs} +226 -60
  42. package/dist/{dist-C5fND3R0.mjs → dist-BuDuKZJv.mjs} +1 -1
  43. package/dist/{dist-Dn6nn2IU.mjs → dist-CTBk70IR.mjs} +42 -42
  44. package/dist/{domain-Dmhvb2oU.mjs → domain-y5Tvydvo.mjs} +5 -5
  45. package/dist/{email-DFi-s2t4.mjs → email-B3umsW75.mjs} +15 -30
  46. package/dist/{env-Csi-tMbT.mjs → env-BS6qYHDb.mjs} +6 -6
  47. package/dist/{env-public-D_6u46fX.d.mts → env-public-BX_r8HR6.d.mts} +2 -1
  48. package/dist/{env-validation-BB4GkLxn.mjs → env-validation-BPn7vk-V.mjs} +18 -71
  49. package/dist/{env-validation-BXge7uyK.mjs → env-validation-DbTg7-ar.mjs} +1 -1
  50. package/dist/{fetch-CXDChK7B.mjs → fetch-BIZJh7vR.mjs} +2 -2
  51. package/dist/{fetch-stream-AOByI7Ki.mjs → fetch-stream-IvCYKyQL.mjs} +24 -4
  52. package/dist/{gen-Dz3X1Qab.mjs → gen-B580--vC.mjs} +5 -5
  53. package/dist/gen-BVaUUumi.mjs +2 -0
  54. package/dist/{github-cmd-BED3_9JD.mjs → github-cmd-v45BdfKX.mjs} +6 -8
  55. package/dist/{handler-BXJTXd02.d.mts → handler-CZ4nAylQ.d.mts} +2 -1
  56. package/dist/{headers-BOg_velo.mjs → headers-DWi2IXWx.mjs} +1 -1
  57. package/dist/help-DofyZuY7.mjs +2 -0
  58. package/dist/{help-DC7gdz7L.mjs → help-daGKjXGk.mjs} +268 -666
  59. package/dist/index.d.mts +1 -1
  60. package/dist/index.mjs +305 -1490
  61. package/dist/info-B97bTX9N.mjs +113 -0
  62. package/dist/{init-WO0JlPx8.mjs → init-Bvy7zrBo.mjs} +51 -20
  63. package/dist/limits-Bq5LG8Id.d.mts +27 -0
  64. package/dist/limits-Cjuk2VPm.mjs +68 -0
  65. package/dist/{link-CsHOinF7.mjs → link-CDqqCjFl.mjs} +5 -5
  66. package/dist/{list-CDb-4bZ1.mjs → list-CZj0dzKY.mjs} +5 -5
  67. package/dist/{live-CKiJilLr.d.mts → live-Chw1eIMv.d.mts} +1 -1
  68. package/dist/{local-d1-CC8sKFGu.mjs → local-d1-2CMnpuW_.mjs} +2 -2
  69. package/dist/login-DYt_An22.mjs +2 -0
  70. package/dist/{login-DvqXsfGs.mjs → login-UZKFM_u7.mjs} +5 -5
  71. package/dist/{logs-BdfiOezj.mjs → logs-CUZ6t9t3.mjs} +5 -5
  72. package/dist/migrate-8_2u55MD.mjs +2 -0
  73. package/dist/{migrate-B8KuoYsO.mjs → migrate-DHul7PRV.mjs} +5 -4
  74. package/dist/{node-BM43oz4G.mjs → node-BkyRWRx8.mjs} +2 -2
  75. package/dist/operator-args-CLgKGlwU.mjs +690 -0
  76. package/dist/{operator-cmd-03819ATr.mjs → operator-cmd-DBA6dl0m.mjs} +69 -23
  77. package/dist/output-Dm_A4Tbv.mjs +81 -0
  78. package/dist/pages/client.d.mts +34 -2
  79. package/dist/pages/client.mjs +59 -3
  80. package/dist/pages/index.d.mts +1 -1
  81. package/dist/pages/index.mjs +3 -3
  82. package/dist/pages/islands-plugin.d.mts +16 -6
  83. package/dist/pages/islands-plugin.mjs +2 -2
  84. package/dist/pages/protocol.d.mts +2 -2
  85. package/dist/pages/protocol.mjs +2 -308
  86. package/dist/{parse-filename-DioPHiR9.mjs → parse-filename-CUbj-1MP.mjs} +35 -1
  87. package/dist/{output-CCH48AMM.mjs → picocolors-BTps1_gs.mjs} +2 -76
  88. package/dist/plan-D1Q5rf-r.mjs +2 -0
  89. package/dist/plan-NPpwZ_kc.mjs +58 -0
  90. package/dist/platform-args-BJdRtlLq.mjs +506 -0
  91. package/dist/platform-args-D3RXyR6h.mjs +2 -0
  92. package/dist/{platform-auth-config-z92h63q5.mjs → platform-auth-config-B56E9YP1.mjs} +4 -4
  93. package/dist/{platform-auth-protection-DeE3yr2R.mjs → platform-auth-protection-BDWO_aER.mjs} +3 -3
  94. package/dist/{platform-auth-recovery-o_340Ixx.mjs → platform-auth-recovery-1gg4CSRe.mjs} +4 -4
  95. package/dist/{platform-cmd-C4ZV3Vpy.mjs → platform-cmd-Bt-1w6pY.mjs} +1 -1
  96. package/dist/{platform-cmd-DNl8WosH.mjs → platform-cmd-DMcQStSc.mjs} +26 -5
  97. package/dist/{platform-domain-CU1JtJkW.mjs → platform-domain-BNkcz0OB.mjs} +36 -9
  98. package/dist/{platform-lifecycle-Bc047IeT.mjs → platform-lifecycle-9OyBALhH.mjs} +850 -276
  99. package/dist/{platform-lifecycle-Bs2qx1E3.mjs → platform-lifecycle-BE6C_jxh.mjs} +1 -1
  100. package/dist/{platform-management-CVpGI9Y5.mjs → platform-management-CjwLVQwN.mjs} +59 -11
  101. package/dist/{platform-management-C8tt6D8h.mjs → platform-management-CnyTdcWX.mjs} +1 -1
  102. package/dist/platform-plans-config-BNGKGr4P.mjs +359 -0
  103. package/dist/{platform-recovery-dvUaptLr.mjs → platform-recovery-D6KSpuFm.mjs} +2 -2
  104. package/dist/{plugin-inference-BMfKRSqE.mjs → plugin-inference-CXWnn79A.mjs} +174 -64
  105. package/dist/{prepare-DyZ-Yok5.mjs → prepare-B5Mkic5u.mjs} +3 -3
  106. package/dist/{prepare-C3kt3Rst.mjs → prepare-DOsL0CC9.mjs} +4 -20
  107. package/dist/prepare-cgvDMtSb.mjs +2 -0
  108. package/dist/{project-cmd-B44I8J_W.mjs → project-cmd-CNzrqvBv.mjs} +30 -16
  109. package/dist/{project-team-BkbYIsXN.mjs → project-team-DQOWPfQT.mjs} +4 -4
  110. package/dist/{project-token-C8xEEQnB.mjs → project-token-CTDYU0Cc.mjs} +4 -4
  111. package/dist/project-zero-trust-BNAkW-_0.mjs +63 -0
  112. package/dist/{protocol-ZH3jP4a7.d.mts → protocol-CjF_iI9X.d.mts} +2 -2
  113. package/dist/protocol-U7bfjHmA.mjs +331 -0
  114. package/dist/{provision-DNtrtaVD.mjs → provision-C4ORE7G7.mjs} +1 -1
  115. package/dist/{provision-BhreDAOS.mjs → provision-CJFgTZY8.mjs} +111 -215
  116. package/dist/{requests-DFyhBMaf.mjs → requests-MhxYnau8.mjs} +4 -4
  117. package/dist/resource-name-C7LVpcRm.mjs +11 -0
  118. package/dist/{rollback-DHHxXZiS.mjs → rollback-CJ6iSDoU.mjs} +5 -5
  119. package/dist/route-url-CG7U-cRN.mjs +15 -0
  120. package/dist/{runner-B8wXwWlo.mjs → runner-CXA9Fh8h.mjs} +1 -1
  121. package/dist/{runner-p-dMs2UN.mjs → runner-Ol0TNjk6.mjs} +2 -2
  122. package/dist/runtime/ai.d.mts +12 -8
  123. package/dist/runtime/ai.mjs +84 -17
  124. package/dist/runtime/better-auth-mysql.mjs +1 -1
  125. package/dist/runtime/better-auth-pg.mjs +1 -1
  126. package/dist/runtime/better-auth.mjs +1 -1
  127. package/dist/runtime/client-react.mjs +2 -2
  128. package/dist/runtime/client-solid.mjs +2 -2
  129. package/dist/runtime/client-svelte.mjs +2 -2
  130. package/dist/runtime/client-vue.mjs +2 -2
  131. package/dist/runtime/client.mjs +2 -2
  132. package/dist/runtime/durable.d.mts +3 -1
  133. package/dist/runtime/durable.mjs +4 -1
  134. package/dist/runtime/email/testing.mjs +1 -1
  135. package/dist/runtime/env-public.d.mts +1 -1
  136. package/dist/runtime/fetch-stream.mjs +1 -1
  137. package/dist/runtime/fetch.mjs +1 -1
  138. package/dist/runtime/handler.d.mts +1 -1
  139. package/dist/runtime/kv.mjs +0 -1
  140. package/dist/runtime/limits.d.mts +2 -0
  141. package/dist/runtime/limits.mjs +2 -0
  142. package/dist/runtime/live-client.d.mts +1 -1
  143. package/dist/runtime/live-server.mjs +25 -16
  144. package/dist/runtime/live.d.mts +1 -1
  145. package/dist/runtime/migration-handler.mjs +62 -42
  146. package/dist/runtime/route-url.d.mts +4 -0
  147. package/dist/runtime/route-url.mjs +2 -0
  148. package/dist/runtime/routing.d.mts +180 -0
  149. package/dist/runtime/routing.mjs +1082 -0
  150. package/dist/runtime/sandbox-container.d.mts +3 -0
  151. package/dist/runtime/sandbox-container.mjs +2 -0
  152. package/dist/runtime/sandbox.d.mts +4 -32
  153. package/dist/runtime/sandbox.mjs +151 -75
  154. package/dist/runtime/sse.mjs +1 -1
  155. package/dist/runtime/validator.d.mts +1 -1
  156. package/dist/runtime/ws-server.d.mts +4 -2
  157. package/dist/runtime/ws-server.mjs +27 -2
  158. package/dist/runtime/ws.d.mts +2 -2
  159. package/dist/runtime/ws.mjs +8 -6
  160. package/dist/sandbox-XZAqzFlG.d.mts +52 -0
  161. package/dist/sandbox-container-Bo0eiFKz.d.mts +73 -0
  162. package/dist/sandbox-container-C6ItmVuN.mjs +281 -0
  163. package/dist/{scan-4tfN-PSn.mjs → scan-C7okrLyM.mjs} +4 -35
  164. package/dist/{secret-DN9sSNiV.mjs → secret-Dli5fP0B.mjs} +6 -6
  165. package/dist/{skills-O6FUaizK.mjs → skills-D1II1Juz.mjs} +1 -1
  166. package/dist/{sse-BaC1jXko.mjs → sse-CQNaDFFV.mjs} +6 -3
  167. package/dist/{subcommand-prompt-BuGYkAkC.mjs → subcommand-prompt-CY1C4fvl.mjs} +2 -2
  168. package/dist/validate-Dq_L3s0S.mjs +2 -0
  169. package/dist/{validate-CIUwFpjB.mjs → validate-ctOrgiS3.mjs} +2 -1
  170. package/dist/{wrangler-BymcxrRa.mjs → wrangler-7K-bW_DL.mjs} +14 -235
  171. package/dist/{ws-BwcqizuH.d.mts → ws-CL1w7GXU.d.mts} +13 -2
  172. package/package.json +48 -33
  173. package/sandbox.Dockerfile +4 -0
  174. package/schema.json +10 -22
  175. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +34 -157
  176. package/skills/void/SKILL.md +50 -133
  177. package/skills/void/docs/guide/ai.md +94 -84
  178. package/skills/void/docs/guide/app-types.md +3 -32
  179. package/skills/void/docs/guide/auth.md +12 -116
  180. package/skills/void/docs/guide/database/d1.md +9 -54
  181. package/skills/void/docs/guide/database/mysql.md +1 -1
  182. package/skills/void/docs/guide/database/postgresql.md +5 -26
  183. package/skills/void/docs/guide/database.md +23 -75
  184. package/skills/void/docs/guide/deployment.md +27 -113
  185. package/skills/void/docs/guide/durable-state.md +43 -18
  186. package/skills/void/docs/guide/edge/headers.md +3 -47
  187. package/skills/void/docs/guide/edge/prerendering.md +5 -20
  188. package/skills/void/docs/guide/edge/redirects.md +11 -64
  189. package/skills/void/docs/guide/edge/revalidation.md +6 -19
  190. package/skills/void/docs/guide/edge/rewrites.md +56 -284
  191. package/skills/void/docs/guide/edge/static-assets.md +23 -72
  192. package/skills/void/docs/guide/email/domains.md +112 -0
  193. package/skills/void/docs/guide/email/receiving.md +139 -0
  194. package/skills/void/docs/guide/email/sending.md +231 -0
  195. package/skills/void/docs/guide/email.md +13 -619
  196. package/skills/void/docs/guide/env-migration.md +11 -11
  197. package/skills/void/docs/guide/env-vars.md +9 -29
  198. package/skills/void/docs/guide/index.md +0 -15
  199. package/skills/void/docs/guide/jobs.md +3 -18
  200. package/skills/void/docs/guide/kv.md +5 -11
  201. package/skills/void/docs/guide/live.md +5 -56
  202. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +78 -125
  203. package/skills/void/docs/guide/pages-routing/head.md +10 -10
  204. package/skills/void/docs/guide/pages-routing/islands.md +6 -36
  205. package/skills/void/docs/guide/pages-routing/layouts.md +6 -128
  206. package/skills/void/docs/guide/pages-routing/loaders.md +3 -19
  207. package/skills/void/docs/guide/pages-routing/markdown.md +13 -171
  208. package/skills/void/docs/guide/pages-routing/overview.md +7 -17
  209. package/skills/void/docs/guide/pages-routing/view-transitions.md +1 -1
  210. package/skills/void/docs/guide/platform/administration/access.md +1 -4
  211. package/skills/void/docs/guide/platform/administration/email.md +35 -8
  212. package/skills/void/docs/guide/platform/administration/operations.md +26 -4
  213. package/skills/void/docs/guide/platform/administration/plans.md +126 -0
  214. package/skills/void/docs/guide/platform/administration/projects.md +5 -2
  215. package/skills/void/docs/guide/platform/administration/zero-trust.md +189 -0
  216. package/skills/void/docs/guide/platform/development/local.md +2 -2
  217. package/skills/void/docs/guide/platform/development/runtime.md +3 -13
  218. package/skills/void/docs/guide/platform/development/schema-ci.md +0 -58
  219. package/skills/void/docs/guide/platform/installation/credentials.md +6 -4
  220. package/skills/void/docs/guide/platform/installation/domains.md +31 -3
  221. package/skills/void/docs/guide/platform/installation/first-deployment.md +6 -0
  222. package/skills/void/docs/guide/platform/installation/maintenance.md +3 -1
  223. package/skills/void/docs/guide/platform/installation/prerequisites.md +21 -16
  224. package/skills/void/docs/guide/platform/installation/setup.md +9 -5
  225. package/skills/void/docs/guide/platform/installation/uninstall.md +17 -2
  226. package/skills/void/docs/guide/platform-administration.md +2 -0
  227. package/skills/void/docs/guide/queues.md +7 -9
  228. package/skills/void/docs/guide/quickstart.md +38 -37
  229. package/skills/void/docs/guide/remote-dev.md +4 -9
  230. package/skills/void/docs/guide/sandboxes.md +78 -41
  231. package/skills/void/docs/guide/server-routing.md +9 -72
  232. package/skills/void/docs/guide/sse.md +4 -18
  233. package/skills/void/docs/guide/ssg.md +3 -15
  234. package/skills/void/docs/guide/ssr.md +14 -62
  235. package/skills/void/docs/guide/storage.md +9 -4
  236. package/skills/void/docs/guide/type-safety.md +3 -14
  237. package/skills/void/docs/guide/typed-fetch.md +3 -7
  238. package/skills/void/docs/guide/websockets.md +68 -40
  239. package/skills/void/docs/integrations/agents.md +3 -3
  240. package/skills/void/docs/integrations/cloudflare.md +85 -316
  241. package/skills/void/docs/integrations/frameworks/analog.md +5 -64
  242. package/skills/void/docs/integrations/frameworks/astro.md +4 -73
  243. package/skills/void/docs/integrations/frameworks/nuxt.md +5 -62
  244. package/skills/void/docs/integrations/frameworks/overview.md +11 -54
  245. package/skills/void/docs/integrations/frameworks/react-router.md +5 -60
  246. package/skills/void/docs/integrations/frameworks/sveltekit.md +6 -65
  247. package/skills/void/docs/integrations/frameworks/tanstack-start.md +4 -62
  248. package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -69
  249. package/skills/void/docs/reference/api/auth.md +156 -0
  250. package/skills/void/docs/reference/api/client.md +87 -0
  251. package/skills/void/docs/reference/api/database.md +95 -0
  252. package/skills/void/docs/reference/api/durable.md +46 -0
  253. package/skills/void/docs/reference/api/env.md +50 -0
  254. package/skills/void/docs/reference/api/handlers.md +254 -0
  255. package/skills/void/docs/reference/api/pages.md +241 -0
  256. package/skills/void/docs/reference/api/plugin.md +39 -0
  257. package/skills/void/docs/reference/api/resources.md +109 -0
  258. package/skills/void/docs/reference/api/rewrites.md +76 -0
  259. package/skills/void/docs/reference/api/types.md +92 -0
  260. package/skills/void/docs/reference/api.md +56 -1218
  261. package/skills/void/docs/reference/cli/auth.md +88 -0
  262. package/skills/void/docs/reference/cli/database.md +128 -0
  263. package/skills/void/docs/reference/cli/deploy.md +85 -0
  264. package/skills/void/docs/reference/cli/domains.md +41 -0
  265. package/skills/void/docs/reference/cli/email.md +129 -0
  266. package/skills/void/docs/reference/cli/generate.md +116 -0
  267. package/skills/void/docs/reference/cli/github.md +189 -0
  268. package/skills/void/docs/reference/cli/platform-config.md +92 -0
  269. package/skills/void/docs/reference/cli/platform-email.md +81 -0
  270. package/skills/void/docs/reference/cli/platform-installation.md +127 -0
  271. package/skills/void/docs/reference/cli/platform-operations.md +90 -0
  272. package/skills/void/docs/reference/cli/platform-users.md +89 -0
  273. package/skills/void/docs/reference/cli/platform-zero-trust.md +45 -0
  274. package/skills/void/docs/reference/cli/platform.md +70 -0
  275. package/skills/void/docs/reference/cli/project.md +214 -0
  276. package/skills/void/docs/reference/cli/secrets.md +76 -0
  277. package/skills/void/docs/reference/cli/setup.md +70 -0
  278. package/skills/void/docs/reference/cli.md +33 -1621
  279. package/skills/void/docs/reference/config.md +26 -32
  280. package/skills/void/docs/reference/resource-inference.md +3 -58
  281. package/skills/void/docs/reference/structure.md +14 -41
  282. package/dist/canonical-json-DuDiiUsQ.mjs +0 -13
  283. package/dist/cli/cf-compat.mjs +0 -968
  284. package/dist/client-4cDVv7BO.mjs +0 -2
  285. package/dist/gen-Vnv2f65C.mjs +0 -2
  286. package/dist/help-DQMfeKMz.mjs +0 -2
  287. package/dist/login-DFQk7rbW.mjs +0 -2
  288. package/dist/migrate-TsHGBnDA.mjs +0 -2
  289. package/dist/plan-BEZ8VJW0.mjs +0 -256
  290. package/dist/plan-DpuOr14e.mjs +0 -2
  291. package/dist/prepare-BZXkjdNe.mjs +0 -2
  292. package/dist/validate-EKmJWxmy.mjs +0 -2
  293. /package/dist/cli/{cf-compat.d.mts → cloudflare-operation-process.d.mts} +0 -0
@@ -1,2 +1,2 @@
1
- import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-Bc047IeT.mjs";
1
+ import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-9OyBALhH.mjs";
2
2
  export { runPlatformLifecycleCommand };
@@ -1,7 +1,7 @@
1
- import { i as createSpinner } from "./output-CCH48AMM.mjs";
2
1
  import { a as listInstallationManifests, d as readInstallationRecoverySecrets, h as resolveInstallationManifest, m as removePlatformConnectionForInstallation, p as removeInstallationRecoverySecrets, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-QBa4DK32.mjs";
3
- import { E as confirm, I as select, N as note, P as outro, W as isCancel, j as log } from "./dist-Dn6nn2IU.mjs";
4
- import { A as hyperdriveOriginFromConnectionString, C as assertPlatformOperatorCredentialCanApplyPlan, M as verifyPlatformRuntimeTokenPermissions, O as PlatformCloudflareClient, S as platformDatabaseNameFromOwnerUrl, _ as createPlatformInstallPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY, b as platformProvisionIntentHash, d as loadPlatformRuntime, g as trackedPlatformWorkerTraffic, j as hyperdriveOriginMatches, k as hyperdriveOriginConfigHash, l as createPlatformInstallationSecrets, m as resolveBootstrapGitHubId, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, t as assertNoninteractivePlatformMutationAcknowledged, u as installPlatform, v as formatPlatformInstallPlan, w as resolvePlatformCloudflareCredential, x as revalidatePlatformInstallAction, y as platformAdoptionIntentHash } from "./platform-lifecycle-Bc047IeT.mjs";
2
+ import { E as confirm, I as select, N as note, P as outro, W as isCancel, j as log } from "./dist-CTBk70IR.mjs";
3
+ import { i as createSpinner } from "./output-Dm_A4Tbv.mjs";
4
+ import { A as PlatformCloudflareClient, C as revalidatePlatformInstallAction, E as resolvePlatformCloudflareCredential, M as hyperdriveOriginFromConnectionString, N as hyperdriveOriginMatches, P as verifyPlatformRuntimeTokenPermissions, S as platformProvisionIntentHash, T as assertPlatformOperatorCredentialCanApplyPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY, b as formatPlatformInstallPlan, d as loadPlatformRuntime, g as assertProjectZeroTrustAllowsUninstall, h as resolveBootstrapGitHubId, j as hyperdriveOriginConfigHash, l as createPlatformInstallationSecrets, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, p as readPlatformProjectZeroTrustState, t as assertNoninteractivePlatformMutationAcknowledged, u as installPlatform, v as trackedPlatformWorkerTraffic, w as platformDatabaseNameFromOwnerUrl, x as platformAdoptionIntentHash, y as createPlatformInstallPlan } from "./platform-lifecycle-9OyBALhH.mjs";
5
5
  import { createHash } from "node:crypto";
6
6
  import { PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE, PLATFORM_R2_OWNERSHIP_MARKER_KEY, createPlatformResourceOwnershipMarker, parsePlatformInstallationManifest, parsePlatformResourceOwnershipMarker, recordInstallationResource, recordInstallationStep, setInstallationDesiredState, transitionInstallation } from "@void/platform";
7
7
  //#region src/cli/platform-management.ts
@@ -58,7 +58,11 @@ async function runInstalledPlatformCommand(args) {
58
58
  if (args.subcommand === "uninstall") {
59
59
  await uninstallPlatform(client, manifest, args, {
60
60
  checkpoint: databaseLock?.checkpoint,
61
- databaseUrl
61
+ databaseUrl,
62
+ readProjectZeroTrust: databaseLock ? databaseLock.readProjectZeroTrust : () => readPlatformProjectZeroTrustState(databaseUrl, manifest.id, manifest.ownershipNonce),
63
+ lockProjectZeroTrust: databaseLock?.lockProjectZeroTrust,
64
+ fenceProjectZeroTrust: databaseLock?.fenceProjectZeroTrust,
65
+ liftProjectZeroTrustFence: databaseLock?.liftProjectZeroTrustFence
62
66
  });
63
67
  return;
64
68
  }
@@ -73,6 +77,7 @@ async function runInstalledPlatformCommand(args) {
73
77
  ...args.subcommand === "upgrade" && process.env.VOID_EMAIL_SENDER_DOMAIN ? { emailSenderDomain: process.env.VOID_EMAIL_SENDER_DOMAIN } : {},
74
78
  applicationDomain: deployment.application.baseDomain,
75
79
  controlPlaneDomain: deployment.controlPlane.apiHostname ?? "",
80
+ ...args.subcommand !== "rollback" && args.dashboardUrl !== void 0 ? { dashboardUrl: args.dashboardUrl } : {},
76
81
  dedicatedZone: deployment.application.dedicatedZone,
77
82
  displayName: deployment.displayName,
78
83
  installationSlug: deployment.installationSlug,
@@ -83,7 +88,8 @@ async function runInstalledPlatformCommand(args) {
83
88
  repairMissing: args.subcommand === "repair",
84
89
  allowUnverifiedAiGateway: args.plan,
85
90
  includeEmailGateway: runtime.manifest.artifacts.emailGateway !== void 0,
86
- enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3
91
+ enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3,
92
+ deploymentExecution: runtime.manifest.deploymentExecution === 1
87
93
  });
88
94
  markPhase("plan");
89
95
  note(formatPlatformInstallPlan(plan), args.subcommand === "upgrade" ? "Upgrade plan" : args.subcommand === "rollback" ? "Rollback plan" : args.subcommand === "enable" ? "Enable plan" : "Repair plan");
@@ -145,6 +151,7 @@ async function runInstalledPlatformCommand(args) {
145
151
  const result = await installPlatform(plan, secrets, installation, {
146
152
  acquireDatabaseLifecycleLock: async () => Object.assign(async () => {}, {
147
153
  checkpoint: databaseLock?.checkpoint,
154
+ liftProjectZeroTrustFence: databaseLock?.liftProjectZeroTrustFence,
148
155
  prepareDatabase: databaseLock?.prepareDatabase,
149
156
  prepareSandboxDrain: databaseLock?.prepareSandboxDrain,
150
157
  readAuthenticationState: databaseLock?.readAuthenticationState,
@@ -162,9 +169,13 @@ async function runInstalledPlatformCommand(args) {
162
169
  authoritativeProvisionIntents: true,
163
170
  repairMissing: true,
164
171
  includeEmailGateway: runtime.manifest.artifacts.emailGateway !== void 0,
165
- enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3
172
+ enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3,
173
+ deploymentExecution: runtime.manifest.deploymentExecution === 1
166
174
  })).actions.filter((action) => action.kind === "worker"),
167
- revalidateBeforeWorkerDeploy: (manifest, action) => revalidatePlatformInstallAction(client, plan, manifest, action, { repairMissing: args.subcommand === "repair" })
175
+ revalidateBeforeWorkerDeploy: (manifest, action) => revalidatePlatformInstallAction(client, plan, manifest, action, {
176
+ repairMissing: args.subcommand === "repair",
177
+ stableWorkerUpdate: args.subcommand === "upgrade"
178
+ })
168
179
  });
169
180
  progress.message("Finalizing platform changes");
170
181
  markPhase("installer complete");
@@ -315,8 +326,9 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
315
326
  const interactive = dependencies.interactive ?? process.stdin.isTTY;
316
327
  const confirmAction = dependencies.confirm ?? promptForConfirmation;
317
328
  if (createdZone && args.deleteZone === true) throw new Error(`platform: Refusing to delete Cloudflare zone ${JSON.stringify(createdZone.name)} automatically. A zone can contain unrelated DNS, settings, and products that the installer cannot exhaustively prove ownership of. Uninstall with --keep-zone, inspect the retained zone in Cloudflare, and delete it manually if appropriate.`);
329
+ await assertProjectZeroTrustAllowsUninstall(dependencies.readProjectZeroTrust);
318
330
  const dataMessage = retainData ? "Retain installer-owned Workers, storage, dispatch, AI logs, and Hyperdrive by default." : args.purgeData ? "Delete safely identifiable installer-owned data (--purge-data); retain Workers, R2, AI Gateway, and external PostgreSQL for manual cleanup." : "Retain installer-owned data; external PostgreSQL is never deleted.";
319
- note(`Disable all platform traffic through installation-owned routing storage.\nRetain DNS records, routes, and custom domains for explicit dashboard cleanup.\nDelete installer-owned Queues.\n${dataMessage}\n${createdZone ? `Keep zone ${createdZone.name} for explicit manual cleanup.` : "Never delete the adopted application zone."}${(manifest.authenticationResources ?? []).length ? "\nRetain Access resources for deliberate cleanup:\n" + manifest.authenticationResources.map((resource) => ` ${resource.ownership} ${resource.kind}: ${resource.name} (${resource.id}, account ${resource.accountId})`).join("\n") : ""}`, "Uninstall plan");
331
+ note(`Disable all platform traffic through installation-owned routing storage.\nRetain DNS records, routes, and custom domains for explicit dashboard cleanup.\nDelete installer-owned Queues unless a retained Worker still uses them.\n${dataMessage}\n${createdZone ? `Keep zone ${createdZone.name} for explicit manual cleanup.` : "Never delete the adopted application zone."}${(manifest.authenticationResources ?? []).length ? "\nRetain Access resources for deliberate cleanup:\n" + manifest.authenticationResources.map((resource) => ` ${resource.ownership} ${resource.kind}: ${resource.name} (${resource.id}, account ${resource.accountId})`).join("\n") : ""}`, "Uninstall plan");
320
332
  if (args.plan) {
321
333
  outro("No Cloudflare or local installation state was changed.");
322
334
  return;
@@ -345,12 +357,34 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
345
357
  await verifyPlatformInstallationOwnership(client, manifest, { databaseUrl: dependencies.databaseUrl });
346
358
  missingResources = /* @__PURE__ */ new Set();
347
359
  }
348
- let next = transitionInstallation(manifest, "uninstalling", (/* @__PURE__ */ new Date()).toISOString());
349
- writeInstallationManifest(next);
360
+ const { fenceProjectZeroTrust, liftProjectZeroTrustFence, lockProjectZeroTrust } = dependencies;
361
+ if (!lockProjectZeroTrust || !fenceProjectZeroTrust || !liftProjectZeroTrustFence) throw new Error("platform: Refusing to uninstall because no platform database connection is available to hold off project Zero Trust changes.");
362
+ const releaseProjectZeroTrust = await lockProjectZeroTrust();
363
+ let fenced = false;
364
+ let disablingTraffic = false;
365
+ const stopProjectZeroTrustHold = async () => {
366
+ if (fenced && !disablingTraffic) await liftProjectZeroTrustFence().catch((error) => {
367
+ log.warn(`Could not reopen project Zero Trust changes after the uninstall stopped: ${error instanceof Error ? error.message : String(error)}\nRun \`void platform uninstall\` again, or \`void platform repair\` to keep the platform.`);
368
+ });
369
+ await releaseProjectZeroTrust();
370
+ };
371
+ let next = manifest;
372
+ try {
373
+ await assertProjectZeroTrustAllowsUninstall(dependencies.readProjectZeroTrust);
374
+ fenced = true;
375
+ await fenceProjectZeroTrust();
376
+ next = transitionInstallation(manifest, "uninstalling", (/* @__PURE__ */ new Date()).toISOString());
377
+ writeInstallationManifest(next);
378
+ } catch (error) {
379
+ await stopProjectZeroTrustHold();
380
+ throw error;
381
+ }
350
382
  try {
351
383
  await writeRemoteManifestIfPresent(client, next);
352
384
  const routing = next.resources.find((resource) => resource.key === "routing-kv" && resource.state === "ready");
385
+ disablingTraffic = true;
353
386
  if (routing) await client.putKvValue(next.account.id, routing.id, PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE);
387
+ await releaseProjectZeroTrust();
354
388
  for (const key of missingResources) {
355
389
  const resource = requireResource(next, key);
356
390
  next = updateResourceState(next, key, resource.ownership === "created" ? "deleted" : "retained");
@@ -383,6 +417,7 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
383
417
  zone: 8
384
418
  };
385
419
  const resources = [...next.resources].sort((left, right) => resourceDeletionPriority(left, deletionPriority) - resourceDeletionPriority(right, deletionPriority));
420
+ const queuesInUse = hasRoutingCheckpoint && resources.some((resource) => resource.kind === "queue" && shouldDeleteResource(resource, retainData)) && await hasLiveInstallationWorker(client, next);
386
421
  for (const resource of resources) {
387
422
  if (resource.state !== "ready") continue;
388
423
  if (!hasRoutingCheckpoint && resource.kind !== "zone") {
@@ -395,7 +430,7 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
395
430
  await writeLifecycleCheckpoint(client, next);
396
431
  continue;
397
432
  }
398
- if (resource.kind === "dns-record" && !zone) {
433
+ if (resource.kind === "dns-record" && !zone || resource.kind === "queue" && queuesInUse) {
399
434
  next = updateResourceState(next, resource.key, "retained");
400
435
  await writeLifecycleCheckpoint(client, next);
401
436
  continue;
@@ -420,6 +455,7 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
420
455
  removePlatformConnectionForInstallation(next.id);
421
456
  log.success(retainData ? `${next.deployment.displayName} was uninstalled; data resources were retained and recorded in ${next.id}.` : `${next.deployment.displayName} was uninstalled.`);
422
457
  } catch (error) {
458
+ await stopProjectZeroTrustHold().catch(() => {});
423
459
  next = transitionInstallation(next, "failed", (/* @__PURE__ */ new Date()).toISOString());
424
460
  writeInstallationManifest(next);
425
461
  await writeRemoteManifestIfPresent(client, next).catch(() => {});
@@ -505,6 +541,18 @@ function shouldDeleteResource(resource, retainData) {
505
541
  if (resource.kind === "worker-route" || resource.kind === "worker-custom-domain") return false;
506
542
  return !(retainData && DATA_RESOURCE_KINDS.has(resource.kind));
507
543
  }
544
+ async function hasLiveInstallationWorker(client, manifest) {
545
+ const names = manifest.deployment.resources;
546
+ const installationWorkers = /* @__PURE__ */ new Set([
547
+ names.apiWorker,
548
+ names.proxyWorker,
549
+ names.emailGatewayWorker,
550
+ names.tailWorker,
551
+ names.dispatchWorker,
552
+ ...manifest.resources.filter((resource) => resource.kind === "worker").map((resource) => resource.name)
553
+ ]);
554
+ return (await client.listWorkerNames(manifest.account.id)).some((name) => installationWorkers.has(name));
555
+ }
508
556
  function resourceDeletionPriority(resource, priorities) {
509
557
  return resource.key === "routing-kv" ? 100 : priorities[resource.kind] ?? 99;
510
558
  }
@@ -1,2 +1,2 @@
1
- import { c as selectAuthoritativePlatformManifest, s as runInstalledPlatformCommand, u as verifyPlatformInstallationOwnership } from "./platform-management-CVpGI9Y5.mjs";
1
+ import { c as selectAuthoritativePlatformManifest, s as runInstalledPlatformCommand, u as verifyPlatformInstallationOwnership } from "./platform-management-CjwLVQwN.mjs";
2
2
  export { runInstalledPlatformCommand, selectAuthoritativePlatformManifest, verifyPlatformInstallationOwnership };
@@ -0,0 +1,359 @@
1
+ import { B as text, E as confirm, I as select, W as isCancel } from "./dist-CTBk70IR.mjs";
2
+ import { n as OperatorClient, r as OperatorClientError } from "./operator-client-DUwumHpQ.mjs";
3
+ import { a as resolveOperatorOrigin, r as readOperatorToken } from "./operator-auth-8KnOVXVd.mjs";
4
+ import { stripVTControlCharacters } from "node:util";
5
+ import { PLAN_EDITABLE_LIMIT_KEYS, PLAN_LIMITS, parseBuildInstanceType, parsePlanLimitsPatch, parsePlanName, parsePlatformPlanId } from "@void/platform/plans";
6
+ import { readFile } from "node:fs/promises";
7
+ //#region src/cli/platform-plans-config.ts
8
+ const limitLabels = {
9
+ requestsPerMonth: "Requests per billing month",
10
+ cpuMsPerRequest: "Default CPU per request (ms)",
11
+ maxCpuMsPerRequest: "Maximum app CPU per request (ms)",
12
+ subRequestsPerInvocation: "Subrequests per invocation",
13
+ deploysPerDay: "Deployments per day",
14
+ aiNeuronsPerMonth: "AI neurons per billing month",
15
+ retainedDeployments: "Retained Worker deployments",
16
+ sandboxRuntimeSecondsPerMonth: "Sandbox runtime per billing month (seconds)",
17
+ sandboxMaxConcurrentInstances: "Concurrent Sandbox instances",
18
+ concurrentBuilds: "Concurrent builds",
19
+ buildTimeoutMinutes: "Build timeout (minutes)"
20
+ };
21
+ function limitValue(value, key) {
22
+ if (value === 0 && key === "buildTimeoutMinutes") return "platform maximum (60 minutes)";
23
+ return value === 0 ? "unlimited" : value.toLocaleString("en-US");
24
+ }
25
+ function showListing(listing, json) {
26
+ if (json) {
27
+ print(listing);
28
+ return;
29
+ }
30
+ console.log(`Default for new accounts: ${listing.catalog.defaultPlanId}`);
31
+ for (const plan of listing.catalog.plans) {
32
+ const count = listing.accounts.find((entry) => entry.planId === plan.id)?.count ?? 0;
33
+ console.log(`${label(plan)} — ${count} accounts`);
34
+ }
35
+ if (listing.catalog.reconciliation && !listing.catalog.reconciliation.complete) console.log("Account updates are pending. Run void platform config plans sync --yes.");
36
+ }
37
+ function showPreview(preview, before, write = console.error) {
38
+ const after = preview.catalog;
39
+ write(`Change: ${preview.action} ${preview.target}`);
40
+ write(`Accounts affected: ${preview.affectedAccounts}`);
41
+ for (const warning of preview.warnings ?? []) write(stripVTControlCharacters(warning));
42
+ if (typeof preview.usageSampleSize === "number" && preview.usageSampleSize > 0) write(`Usage preview samples ${preview.usageSampleSize} accounts.`);
43
+ if (before.defaultPlanId !== after.defaultPlanId) write(`Default for new accounts: ${before.defaultPlanId} → ${after.defaultPlanId}`);
44
+ for (const plan of after.plans) {
45
+ const previous = before.plans.find((entry) => entry.id === plan.id);
46
+ if (!previous) {
47
+ write(`Add ${label(plan)}; build size ${plan.buildInstanceType}`);
48
+ for (const key of PLAN_EDITABLE_LIMIT_KEYS) write(` ${limitLabels[key]}: ${limitValue(plan.limits[key], key)}`);
49
+ write(` Short project slugs: ${plan.allowShortSlugs ? "allowed" : "not allowed"}`);
50
+ continue;
51
+ }
52
+ if (previous.name !== plan.name) write(`Name: ${previous.name} → ${plan.name}`);
53
+ if (previous.archived !== plan.archived) write(`${plan.id}: ${plan.archived ? "archive for new assignments" : "restore assignments"}`);
54
+ if (previous.buildInstanceType !== plan.buildInstanceType) write(`Build size: ${previous.buildInstanceType} → ${plan.buildInstanceType}`);
55
+ if (previous.allowShortSlugs !== plan.allowShortSlugs) write(`Short project slugs: ${previous.allowShortSlugs ? "allowed" : "not allowed"} → ${plan.allowShortSlugs ? "allowed" : "not allowed"}`);
56
+ for (const key of PLAN_EDITABLE_LIMIT_KEYS) if (previous.limits[key] !== plan.limits[key]) write(`${limitLabels[key]}: ${limitValue(previous.limits[key], key)} → ${limitValue(plan.limits[key], key)}`);
57
+ }
58
+ for (const plan of before.plans) if (!after.plans.some((entry) => entry.id === plan.id)) {
59
+ write(`Remove ${label(plan)}`);
60
+ const replacement = after.plans.find((entry) => entry.id === preview.replacementPlanId);
61
+ if (replacement) {
62
+ write(`Move accounts to ${label(replacement)}`);
63
+ if (plan.buildInstanceType !== replacement.buildInstanceType) write(`Build size: ${plan.buildInstanceType} → ${replacement.buildInstanceType}`);
64
+ if (plan.allowShortSlugs !== replacement.allowShortSlugs) write(`Short project slugs: ${plan.allowShortSlugs ? "allowed" : "not allowed"} → ${replacement.allowShortSlugs ? "allowed" : "not allowed"}`);
65
+ for (const key of PLAN_EDITABLE_LIMIT_KEYS) if (plan.limits[key] !== replacement.limits[key]) write(`${limitLabels[key]}: ${limitValue(plan.limits[key], key)} → ${limitValue(replacement.limits[key], key)}`);
66
+ }
67
+ }
68
+ for (const account of preview.overLimitAccounts ?? []) write(`Already above proposed limits: ${stripVTControlCharacters(account.login)} (${account.id}): ${account.reasons.join(", ")}`);
69
+ }
70
+ function value(input) {
71
+ if (isCancel(input) || typeof input === "symbol") throw new Error("platform: Cancelled.");
72
+ return input;
73
+ }
74
+ function print(result) {
75
+ console.log(JSON.stringify(result, null, 2));
76
+ }
77
+ function label(plan) {
78
+ return `${stripVTControlCharacters(plan.name)} (${plan.id}${plan.archived ? ", archived" : ""})`;
79
+ }
80
+ async function choosePlan(catalog, message, options = {}) {
81
+ const plans = catalog.plans.filter((plan) => plan.id !== options.exclude && (!options.activeOnly || !plan.archived));
82
+ if (!plans.length) throw new Error("platform: No eligible plans are available.");
83
+ return value(await select({
84
+ message,
85
+ options: plans.map((plan) => ({
86
+ value: plan.id,
87
+ label: label(plan)
88
+ }))
89
+ }));
90
+ }
91
+ async function changesInput(args, plan) {
92
+ if (args.file) {
93
+ const input = JSON.parse(await readFile(args.file, "utf8"));
94
+ if (!input || typeof input !== "object" || Array.isArray(input)) throw new Error("platform: A plan file must contain a JSON object.");
95
+ const object = input;
96
+ for (const key of Object.keys(object)) if (![
97
+ "name",
98
+ "limits",
99
+ "buildInstanceType",
100
+ "allowShortSlugs"
101
+ ].includes(key)) throw new Error(`platform: Unknown plan field ${key}. Use name, limits, buildInstanceType, or allowShortSlugs.`);
102
+ if (object.allowShortSlugs !== void 0 && typeof object.allowShortSlugs !== "boolean") throw new Error("platform: allowShortSlugs must be a boolean.");
103
+ return {
104
+ ...object,
105
+ ...object.name !== void 0 ? { name: parsePlanName(object.name) } : {},
106
+ ...object.buildInstanceType !== void 0 ? { buildInstanceType: parseBuildInstanceType(object.buildInstanceType) } : {},
107
+ ...object.limits !== void 0 ? { limits: parsePlanLimitsPatch(object.limits) } : {},
108
+ ...args.name ? { name: parsePlanName(args.name) } : {}
109
+ };
110
+ }
111
+ if (args.name) return { name: parsePlanName(args.name) };
112
+ if (!process.stdin.isTTY || args.json) {
113
+ if (args.action === "add") throw new Error("platform: Supply --name or --file when adding a plan in non-interactive mode.");
114
+ throw new Error("platform: Supply --name or --file with the changes in non-interactive mode.");
115
+ }
116
+ if (args.action === "add") return { name: parsePlanName(value(await text({
117
+ message: "Plan name:",
118
+ initialValue: args.target
119
+ }))) };
120
+ const field = value(await select({
121
+ message: "What would you like to change?",
122
+ options: [
123
+ {
124
+ value: "name",
125
+ label: "Plan name"
126
+ },
127
+ ...PLAN_EDITABLE_LIMIT_KEYS.map((key) => ({
128
+ value: key,
129
+ label: `${limitLabels[key]}: ${limitValue(plan.limits[key], key)}`
130
+ })),
131
+ {
132
+ value: "buildInstanceType",
133
+ label: "Build instance size"
134
+ }
135
+ ]
136
+ }));
137
+ if (field === "name") return { name: parsePlanName(value(await text({
138
+ message: "Plan name:",
139
+ initialValue: plan.name
140
+ }))) };
141
+ if (field === "buildInstanceType") return { buildInstanceType: value(await select({
142
+ message: "Build instance size:",
143
+ initialValue: plan.buildInstanceType,
144
+ options: [{
145
+ value: "standard-3",
146
+ label: "Standard: 2 vCPU, 8 GiB"
147
+ }, {
148
+ value: "standard-4",
149
+ label: "Large: 4 vCPU, 12 GiB"
150
+ }]
151
+ })) };
152
+ const current = plan.limits[field];
153
+ const input = value(await text({
154
+ message: `${limitLabels[field]} (${field === "buildTimeoutMinutes" ? "0 uses the platform maximum of 60 minutes" : "0 means unlimited"}):`,
155
+ initialValue: String(current),
156
+ validate: (value) => /^\d+$/.test(value ?? "") && Number.isSafeInteger(Number(value)) ? void 0 : "Enter a nonnegative whole number."
157
+ }));
158
+ return { limits: parsePlanLimitsPatch({ [field]: Number(input) }) };
159
+ }
160
+ async function apply(client, path, body, args, catalog) {
161
+ if (!args.plan && !args.yes && (!process.stdin.isTTY || args.json)) throw new Error("platform: Configuration changes require --yes or --plan in non-interactive mode.");
162
+ const preview = await client.request(path, {
163
+ method: "POST",
164
+ body: {
165
+ ...body,
166
+ dryRun: true
167
+ }
168
+ });
169
+ if (args.plan) {
170
+ if (args.json) print(preview);
171
+ else showPreview(preview, catalog, console.log);
172
+ return;
173
+ }
174
+ if (!Number.isSafeInteger(preview.expectedRevision)) throw new Error("platform: The platform returned an invalid plan revision.");
175
+ if (!args.yes) {
176
+ showPreview(preview, catalog);
177
+ if (!value(await confirm({
178
+ message: `Apply this change to ${client.origin}?`,
179
+ initialValue: false
180
+ }))) throw new Error("platform: Cancelled.");
181
+ }
182
+ let result = await client.request(path, {
183
+ method: "POST",
184
+ body: {
185
+ ...body,
186
+ expectedRevision: preview.expectedRevision
187
+ }
188
+ });
189
+ const committedCatalog = result.catalog;
190
+ if (!Number.isSafeInteger(committedCatalog?.revision)) throw new Error("platform: The platform returned an invalid saved plan revision. Inspect the catalog before retrying.");
191
+ const committedRevision = committedCatalog.revision;
192
+ const applied = result;
193
+ let previousCursor = catalog.reconciliation?.cursor ?? null;
194
+ while (true) {
195
+ const reconciliation = result.reconciliation;
196
+ if (!reconciliation || reconciliation.complete !== false) break;
197
+ const currentCatalog = result.catalog;
198
+ const cursor = currentCatalog.reconciliation?.cursor ?? null;
199
+ if (reconciliation.error || !Number.isSafeInteger(reconciliation.processed) || reconciliation.processed <= 0 || cursor === previousCursor || currentCatalog.revision !== committedRevision) {
200
+ const pending = {
201
+ ...applied,
202
+ ...result
203
+ };
204
+ print(pending);
205
+ throw new OperatorClientError("Plan configuration was saved, but account updates are pending. Run void platform config plans sync --yes.", "plan_sync_pending", void 0, pending);
206
+ }
207
+ previousCursor = cursor;
208
+ result = await client.request("/config/plans/sync", {
209
+ method: "POST",
210
+ body: { expectedRevision: committedRevision }
211
+ });
212
+ }
213
+ const completed = {
214
+ ...applied,
215
+ ...result
216
+ };
217
+ if (args.json) print(completed);
218
+ else console.log(`Saved ${applied.action ?? "plans.sync"} ${applied.target ?? ""}. Account updates complete.`);
219
+ }
220
+ async function runPlatformPlansConfig(args) {
221
+ const origin = resolveOperatorOrigin(args.connection);
222
+ const client = new OperatorClient(origin, readOperatorToken(origin));
223
+ const listing = await client.request("/config/plans");
224
+ const { catalog } = listing;
225
+ if (!args.action) {
226
+ if (!process.stdin.isTTY || args.json) {
227
+ showListing(listing, args.json);
228
+ return;
229
+ }
230
+ const selected = value(await select({
231
+ message: "Platform plans:",
232
+ options: [
233
+ ...catalog.plans.map((plan) => ({
234
+ value: plan.id,
235
+ label: `${label(plan)}${plan.id === catalog.defaultPlanId ? " — default" : ""}`,
236
+ hint: `${listing.accounts.find((entry) => entry.planId === plan.id)?.count ?? 0} accounts`
237
+ })),
238
+ {
239
+ value: ":add",
240
+ label: "Add a plan by copying an existing plan"
241
+ },
242
+ {
243
+ value: ":default",
244
+ label: "Choose the default for new accounts"
245
+ },
246
+ ...catalog.reconciliation && !catalog.reconciliation.complete ? [{
247
+ value: ":sync",
248
+ label: "Continue pending account updates"
249
+ }] : []
250
+ ]
251
+ }));
252
+ if (selected === ":sync") return runPlatformPlansConfig({
253
+ ...args,
254
+ action: "sync"
255
+ });
256
+ if (selected === ":default") {
257
+ const target = await choosePlan(catalog, "Default plan for new accounts:", { activeOnly: true });
258
+ return runPlatformPlansConfig({
259
+ ...args,
260
+ action: "default",
261
+ target
262
+ });
263
+ }
264
+ if (selected === ":add") {
265
+ const target = parsePlatformPlanId(value(await text({ message: "New plan ID (stable; lowercase letters, digits, and hyphens):" })));
266
+ const copy = await choosePlan(catalog, "Copy limits and build size from:");
267
+ return runPlatformPlansConfig({
268
+ ...args,
269
+ action: "add",
270
+ target,
271
+ copy
272
+ });
273
+ }
274
+ const plan = catalog.plans.find((entry) => entry.id === selected);
275
+ const action = value(await select({
276
+ message: label(plan),
277
+ options: [
278
+ {
279
+ value: "show",
280
+ label: "Show limits and account count"
281
+ },
282
+ {
283
+ value: "set",
284
+ label: "Edit name or limits"
285
+ },
286
+ {
287
+ value: plan.archived ? "restore" : "archive",
288
+ label: plan.archived ? "Restore assignments to this plan" : "Archive for new assignments"
289
+ },
290
+ ...Object.hasOwn(PLAN_LIMITS, plan.id) ? [{
291
+ value: "reset",
292
+ label: "Reset to original limits and build size"
293
+ }] : [],
294
+ {
295
+ value: "remove",
296
+ label: "Remove this plan"
297
+ }
298
+ ]
299
+ }));
300
+ return runPlatformPlansConfig({
301
+ ...args,
302
+ action,
303
+ target: selected
304
+ });
305
+ }
306
+ if (args.action === "show") {
307
+ if (!args.target) showListing(listing, args.json);
308
+ else {
309
+ const result = await client.request(`/config/plans/${encodeURIComponent(args.target)}`);
310
+ if (args.json) print(result);
311
+ else {
312
+ const plan = result.plan;
313
+ console.log(`${label(plan)}${result.default ? " — default for new accounts" : ""}`);
314
+ console.log(`Accounts: ${result.accounts}; build size: ${plan.buildInstanceType}`);
315
+ console.log(`Short project slugs: ${plan.allowShortSlugs ? "allowed" : "not allowed"}`);
316
+ for (const key of PLAN_EDITABLE_LIMIT_KEYS) console.log(`${limitLabels[key]}: ${limitValue(plan.limits[key], key)}`);
317
+ }
318
+ }
319
+ return;
320
+ }
321
+ let body = {};
322
+ let path = `/config/plans/${encodeURIComponent(args.target)}/${args.action}`;
323
+ const plan = catalog.plans.find((entry) => entry.id === args.target);
324
+ if (args.action === "add") {
325
+ let copy = args.copy;
326
+ if (!copy) {
327
+ if (!process.stdin.isTTY || args.json) throw new Error("platform: Adding a plan requires --copy <plan-id> in non-interactive mode.");
328
+ copy = await choosePlan(catalog, "Copy limits and build size from:");
329
+ }
330
+ body = {
331
+ id: args.target,
332
+ copyFrom: copy,
333
+ ...await changesInput(args)
334
+ };
335
+ path = "/config/plans/add";
336
+ } else if (args.action === "default") {
337
+ body = { planId: args.target };
338
+ path = "/config/plans/default";
339
+ } else if (args.action === "sync") path = "/config/plans/sync";
340
+ else {
341
+ if (!plan) throw new Error("platform: Plan not found. Run void platform config plans show.");
342
+ if (args.action === "set") body = await changesInput(args, plan);
343
+ else if (args.action === "archive" || args.action === "restore") {
344
+ path = `/config/plans/${encodeURIComponent(args.target)}/archive`;
345
+ body = { archived: args.action === "archive" };
346
+ } else if (args.action === "remove") {
347
+ let replacement = args.replacement;
348
+ const needsReplacement = args.target === catalog.defaultPlanId || (listing.accounts.find((entry) => entry.planId === args.target)?.count ?? 0) > 0;
349
+ if (!replacement && needsReplacement && process.stdin.isTTY && !args.json) replacement = await choosePlan(catalog, "Move accounts and any default to:", {
350
+ activeOnly: true,
351
+ exclude: args.target
352
+ });
353
+ body = replacement ? { replacementPlanId: replacement } : {};
354
+ }
355
+ }
356
+ await apply(client, path, body, args, catalog);
357
+ }
358
+ //#endregion
359
+ export { runPlatformPlansConfig };
@@ -1,7 +1,7 @@
1
1
  import { t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
2
2
  import { a as listInstallationManifests, g as savePlatformConnection, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-QBa4DK32.mjs";
3
- import { _ as createPlatformInstallPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY } from "./platform-lifecycle-Bc047IeT.mjs";
4
- import { i as recoverDurablyMarkedProvisionIntents, r as isPlatformManifestMonotonicExtension, u as verifyPlatformInstallationOwnership } from "./platform-management-CVpGI9Y5.mjs";
3
+ import { a as REMOTE_INSTALLATION_MANIFEST_KEY, y as createPlatformInstallPlan } from "./platform-lifecycle-9OyBALhH.mjs";
4
+ import { i as recoverDurablyMarkedProvisionIntents, r as isPlatformManifestMonotonicExtension, u as verifyPlatformInstallationOwnership } from "./platform-management-CjwLVQwN.mjs";
5
5
  import { parsePlatformInstallationManifest, setInstallationEndpoints } from "@void/platform";
6
6
  //#region src/cli/platform-recovery.ts
7
7
  async function recoverPlatformInstallations(client, accountId, verifyEndpoint = verifyInstallationEndpoint, selector = "") {