void 0.25.0 → 0.26.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 (373) hide show
  1. package/AGENTS_TEMPLATE.md +1 -3
  2. package/README.md +19 -9
  3. package/dist/{account-cmd-DcR1ywt8.mjs → account-cmd-CfUXh_nU.mjs} +8 -7
  4. package/dist/{application-analysis-BVsVqc11.mjs → application-analysis-DKy02UY0.mjs} +21 -32
  5. package/dist/{application-routing-B7QEjqSR.mjs → application-routing-DQyUh_5S.mjs} +1 -1
  6. package/dist/{auth-7wuZ5ob8.mjs → auth-B5_tZLxT.mjs} +9 -9
  7. package/dist/{auth-CdgZ9uag.mjs → auth-BgX2qYSY.mjs} +1 -1
  8. package/dist/{auth-link-Z6E5DYvM.mjs → auth-link-D5RmKnzh.mjs} +5 -5
  9. package/dist/{auth-migrations-9vif1uj8.mjs → auth-migrations-BwHgeEsD.mjs} +8 -18
  10. package/dist/{auth-router-BdM4avI8.mjs → auth-router-Bap-pvbn.mjs} +6 -19
  11. package/dist/{better-auth-shared-BVkjZ3vM.d.mts → better-auth-shared-CPvWD3nG.d.mts} +0 -4
  12. package/dist/{better-auth-shared-hy6RPh9W.mjs → better-auth-shared-DPpj8zxc.mjs} +94 -16
  13. package/dist/{build-cmd-CEE7D-hM.mjs → build-cmd-B58c8iS8.mjs} +8 -7
  14. package/dist/{cache-TcZnBLtH.mjs → cache-Bo52trKF.mjs} +8 -8
  15. package/dist/{cancel-deploy-CYoZmcmR.mjs → cancel-deploy-BZNz3Q26.mjs} +6 -5
  16. package/dist/{cf-access-AHKBzmuu.mjs → cf-access-ngGqZpHZ.mjs} +11 -12
  17. package/dist/{cf-build-output-U8o1Gl6X.mjs → cf-build-output-DjvB_872.mjs} +62 -85
  18. package/dist/cf-build-output-H9a97vME.mjs +2 -0
  19. package/dist/cli/cli.mjs +48 -83
  20. package/dist/cli/cloudflare-operation-process.mjs +71 -77
  21. package/dist/cli/env-schema-probe.d.mts +1 -1
  22. package/dist/cli/env-schema-probe.mjs +5 -6
  23. package/dist/client-By4JjMw_.mjs +2 -0
  24. package/dist/{client-RsPo8wsP.mjs → client-C2Prx_Bi.mjs} +30 -8
  25. package/dist/{cloudflare-auth-Qdc7tw8F.mjs → cloudflare-auth-CuxfF6OA.mjs} +9 -17
  26. package/dist/{cloudflare-cmd-bhwCxAN6.mjs → cloudflare-cmd-lHqNlJGW.mjs} +6 -5
  27. package/dist/{cloudflare-config-Bktvwtpf.mjs → cloudflare-config-BmhBv3HV.mjs} +1 -1
  28. package/dist/{cloudflare-connect-CuhRgk3k.mjs → cloudflare-connect-2G3rL2rP.mjs} +4 -4
  29. package/dist/{cloudflare-operations-BhbK6yTq.mjs → cloudflare-operations-BlYLlowZ.mjs} +1 -1
  30. package/dist/{cloudflare-operations-CjaV4lZi.mjs → cloudflare-operations-CwI1bChl.mjs} +41 -70
  31. package/dist/{cloudflare-process-B-wekeR6.mjs → cloudflare-process-2-TfIEzB.mjs} +20 -22
  32. package/dist/{config-CyQ-wVd7.mjs → config-5r-YpMC-.mjs} +1 -1
  33. package/dist/{config-C_XRIPx2.mjs → config-B_ggY-IO.mjs} +3 -3
  34. package/dist/config-BtSFvXZx.mjs +2 -0
  35. package/dist/config-CLYAosnQ.mjs +78 -0
  36. package/dist/{config-BMHb8RCj.d.mts → config-CSa15FvD.d.mts} +1 -1
  37. package/dist/{config-Br_JZD6u.mjs → config-DiowPT80.mjs} +24 -30
  38. package/dist/config-entry.d.mts +1 -1
  39. package/dist/{config-write-B1f88wJA.mjs → config-write-AHGesphx.mjs} +8 -7
  40. package/dist/{connect-DCvUmPXY.mjs → connect-X0MUA1gk.mjs} +12 -11
  41. package/dist/{create-project-eAPgYq35.mjs → create-project-DxiyW6iX.mjs} +7 -7
  42. package/dist/{create-project-C734I-Mu.mjs → create-project-iwkbqiBU.mjs} +1 -1
  43. package/dist/{db-C07GEdKF.mjs → db-XnVMHzoV.mjs} +101 -133
  44. package/dist/{delete-pKMVsrpJ.mjs → delete-esYlMiSJ.mjs} +8 -8
  45. package/dist/{deploy-DfsAe-T0.mjs → deploy-BsEvnlJl.mjs} +2377 -2512
  46. package/dist/deploy-C1d-YTfp.mjs +2 -0
  47. package/dist/{dev-inbox-D64ZKUod.mjs → dev-inbox-CK-UuPob.mjs} +7 -16
  48. package/dist/{discover-BcPPiF1o.mjs → discover-CkCYv9T_.mjs} +1 -2
  49. package/dist/discover-EDUf6JJw.mjs +2 -0
  50. package/dist/{prompts-ZAuJlyCj.mjs → dist-Bx1z6Eva.mjs} +1 -1
  51. package/dist/{dist-AoCzRTJE.mjs → dist-Cegxq8gs.mjs} +8 -8
  52. package/dist/{prompts-6OSVA7DJ.mjs → dist-D3m88sjf.mjs} +10 -53
  53. package/dist/{domain-D3uA9ize.mjs → domain-CbbBWhWE.mjs} +29 -30
  54. package/dist/{dotenv-VQxupEUv.mjs → dotenv-BfU6eqFt.mjs} +20 -32
  55. package/dist/{drizzle-Beb2Am5S.mjs → drizzle-CF84FOVM.mjs} +16 -13
  56. package/dist/{email-z3o2cwjH.mjs → email-CpuT42g7.mjs} +24 -19
  57. package/dist/{email--tEtMoj_.mjs → email-d_Aux1vM.mjs} +1 -1
  58. package/dist/{entry-CF5wvH4w.mjs → entry-CMAkqBmU.mjs} +6 -6
  59. package/dist/{env-_v349JBd.mjs → env-BxocywBB.mjs} +25 -6
  60. package/dist/{env-D5liuQYR.mjs → env-DMA3cXZt.mjs} +1 -1
  61. package/dist/{env-public-BX_r8HR6.d.mts → env-public-DR7ZM6d-.d.mts} +1 -1
  62. package/dist/{env-raw-Cx8ElDdj.mjs → env-raw-jZpP5n47.mjs} +1 -2
  63. package/dist/{env-types-D5kds_OZ.mjs → env-types-CwXgeMgL.mjs} +1 -1
  64. package/dist/{env-validation-cZBvGWaP.mjs → env-validation-CrVNjsPm.mjs} +1 -1
  65. package/dist/{env-validation-vBSQ8gw5.mjs → env-validation-Dxdx_5wo.mjs} +17 -21
  66. package/dist/{env-3Q8-_2IH.mjs → env-w9jOyGZn.mjs} +10 -9
  67. package/dist/{fetch-_SeGZao9.d.mts → fetch-BPCYVi3H.d.mts} +20 -1
  68. package/dist/{fetch-BIZJh7vR.mjs → fetch-sAcwjzLO.mjs} +1 -1
  69. package/dist/{fetch-stream-IvCYKyQL.mjs → fetch-stream-PGgz4uGz.mjs} +26 -24
  70. package/dist/{fetch-stream-Bjf0hoZb.d.mts → fetch-stream-obvZ7fvO.d.mts} +1 -16
  71. package/dist/{gen-NjwoG9FK.mjs → gen-DtkQhvQg.mjs} +40 -57
  72. package/dist/gen-dA9hW7AV.mjs +2 -0
  73. package/dist/{github-cmd-DquUq-b1.mjs → github-cmd-D_FsOFxq.mjs} +65 -164
  74. package/dist/{handler-DghKr6dU.mjs → handler-BHAn2fZJ.mjs} +1 -0
  75. package/dist/{handler-CZ4nAylQ.d.mts → handler-CNAwjRcW.d.mts} +5 -12
  76. package/dist/{head-Do8P4puT.d.mts → head-C8K_iGe6.d.mts} +1 -1
  77. package/dist/{head-D_QRR5Yd.mjs → head-D2VF4ApL.mjs} +29 -51
  78. package/dist/{headers-2rKda9Y6.mjs → headers-DlfR78Nu.mjs} +3 -3
  79. package/dist/{help-DRZXC4fj.mjs → help-CVFBTmBx.mjs} +23 -38
  80. package/dist/help-DzKUrQvk.mjs +2 -0
  81. package/dist/{inbound-fRkqcXaC.mjs → inbound-PfQDLXc5.mjs} +23 -24
  82. package/dist/index.d.mts +19 -2
  83. package/dist/index.mjs +632 -532
  84. package/dist/{info-BmA3_IFZ.mjs → info-PYWwkWyt.mjs} +4 -4
  85. package/dist/{init-DT7yuuyl.mjs → init-Bw-fRKGp.mjs} +161 -197
  86. package/dist/{limits-Bq5LG8Id.d.mts → limits-CFsDKQvU.d.mts} +1 -10
  87. package/dist/{limits-Cjuk2VPm.mjs → limits-D0vD1M9A.mjs} +1 -22
  88. package/dist/{link-CXOlqh2F.mjs → link-DlPG8iX3.mjs} +10 -10
  89. package/dist/{list-eEWVJEPn.mjs → list-2GN7_ueV.mjs} +11 -9
  90. package/dist/{live-CB1y5IuC.mjs → live-CgQuTpqD.mjs} +15 -16
  91. package/dist/{live-Chw1eIMv.d.mts → live-Du8jXwOW.d.mts} +4 -2
  92. package/dist/{local-d1-Df4XpwhW.mjs → local-d1-ga5O_idV.mjs} +2 -2
  93. package/dist/{login-pWQHYVu2.mjs → login-D-Q4xw3Q.mjs} +7 -7
  94. package/dist/login-Dc-wuTDq.mjs +2 -0
  95. package/dist/{logs-DnxVX7TR.mjs → logs-rd8J-OFh.mjs} +28 -11
  96. package/dist/migrate-BHp07yJE.mjs +2 -0
  97. package/dist/{migrate-CV1on-yJ.mjs → migrate-NLsjBbuM.mjs} +34 -20
  98. package/dist/{mime-D5Nmdzf7.mjs → mime-DxCznlJq.mjs} +45 -95
  99. package/dist/{node-BkyRWRx8.mjs → node-DJicPvPj.mjs} +5 -5
  100. package/dist/{operator-args-CAVcmwUt.mjs → operator-args-BNsW5gfp.mjs} +10 -1
  101. package/dist/{operator-auth-CkmTE3rt.mjs → operator-auth-AzVLbrr3.mjs} +4 -8
  102. package/dist/{operator-client-LmwjxT6q.mjs → operator-client-BQtzyG-g.mjs} +3 -3
  103. package/dist/{operator-cmd-d-IEKgNk.mjs → operator-cmd-B6f6Cg9Z.mjs} +45 -14
  104. package/dist/operator-cmd-Cwn50lOV.mjs +2 -0
  105. package/dist/{output-BBsUwdyT.mjs → output-C50ag2r3.mjs} +44 -2
  106. package/dist/pages/client.d.mts +19 -51
  107. package/dist/pages/client.mjs +204 -225
  108. package/dist/pages/head-client.d.mts +1 -1
  109. package/dist/pages/head.d.mts +1 -1
  110. package/dist/pages/head.mjs +1 -1
  111. package/dist/pages/index.d.mts +2 -2
  112. package/dist/pages/index.mjs +6 -12
  113. package/dist/pages/islands-plugin.d.mts +1 -1
  114. package/dist/pages/islands-plugin.mjs +21 -25
  115. package/dist/pages/protocol.d.mts +2 -2
  116. package/dist/pages/protocol.mjs +2 -2
  117. package/dist/{plan-NPpwZ_kc.mjs → plan-BhLO2p4w.mjs} +4 -3
  118. package/dist/plan-CH2G51je.mjs +2 -0
  119. package/dist/{platform-args-Bzf8JPc2.mjs → platform-args-BoZkWQnJ.mjs} +4 -2
  120. package/dist/platform-args-DYgITk0D.mjs +2 -0
  121. package/dist/{platform-auth-config-0V0lA3pF.mjs → platform-auth-config-n603OANg.mjs} +45 -40
  122. package/dist/{platform-auth-protection-DFeJ-JkK.mjs → platform-auth-protection-zxDr0hWW.mjs} +9 -8
  123. package/dist/{platform-auth-recovery-ICy4muq6.mjs → platform-auth-recovery-tw9lgtgE.mjs} +8 -7
  124. package/dist/{platform-cmd-D7vSWMvV.mjs → platform-cmd-B8-bCb7t.mjs} +48 -23
  125. package/dist/{platform-cmd-BPySFOew.mjs → platform-cmd-C00YM14r.mjs} +1 -1
  126. package/dist/{platform-discovery-DDDUvnqp.mjs → platform-discovery-BC0HCKYt.mjs} +18 -4
  127. package/dist/{platform-domain-CUdY064e.mjs → platform-domain-p0kobLV8.mjs} +6 -5
  128. package/dist/{platform-lifecycle-Dm09JNkn.mjs → platform-lifecycle-D_QEY32D.mjs} +906 -389
  129. package/dist/{platform-lifecycle-BaUdTRPU.mjs → platform-lifecycle-vFqtNPPa.mjs} +1 -1
  130. package/dist/{platform-management-BSEc_ZeG.mjs → platform-management-BdYblvvE.mjs} +175 -32
  131. package/dist/{platform-management-Bp6aoH2C.mjs → platform-management-oi-SvI3f.mjs} +1 -1
  132. package/dist/{platform-plans-config-B0pOVQyW.mjs → platform-plans-config-CjiFv5J4.mjs} +5 -4
  133. package/dist/{platform-recovery-WOZ95Uze.mjs → platform-recovery-PvNS9Nl2.mjs} +3 -3
  134. package/dist/{platform-registry-KfNEF84O.mjs → platform-registry-P387v42A.mjs} +17 -10
  135. package/dist/platform-setup-DVe42Ws7.mjs +299 -0
  136. package/dist/{plugin-inference-CXWnn79A.mjs → plugin-inference-BlQbOL0P.mjs} +43 -42
  137. package/dist/prepare-DRUV-g3X.mjs +2 -0
  138. package/dist/{prepare-DnaKBi--.mjs → prepare-Do96654b.mjs} +8 -8
  139. package/dist/{prepare-39EvOhI6.mjs → prepare-Dq9hTIbo.mjs} +4 -3
  140. package/dist/{prerender-render-D9qbLs2f.mjs → prerender-render-Ct20jftc.mjs} +17 -3
  141. package/dist/prerender-render.mjs +1 -1
  142. package/dist/{project-IOjBU8R6.mjs → project-BiaPQ7ur.mjs} +1 -1
  143. package/dist/{project-BkbfDs0V.mjs → project-DQstYTxO.mjs} +1 -1
  144. package/dist/{project-cmd-Bs5A392E.mjs → project-cmd-ti8_yTcA.mjs} +19 -19
  145. package/dist/{project-team-ohAWWaew.mjs → project-team-CDPE1Tsg.mjs} +15 -18
  146. package/dist/{project-token-CP01Jna6.mjs → project-token-CkZ1cN0Z.mjs} +14 -17
  147. package/dist/{project-tsconfig-B8GeM0RM.mjs → project-tsconfig-CVJhNMxs.mjs} +2 -1
  148. package/dist/{project-zero-trust-BzkVgx35.mjs → project-zero-trust-DdjLR61k.mjs} +12 -9
  149. package/dist/{protocol-CjF_iI9X.d.mts → protocol-BPZaNqBo.d.mts} +4 -2
  150. package/dist/{protocol-U7bfjHmA.mjs → protocol-CfaUwNs8.mjs} +46 -49
  151. package/dist/{providers-CJlNS3kT.mjs → providers-BXuhmuub.mjs} +1 -12
  152. package/dist/{provision-Btj1jppf.mjs → provision-BfaLiWbj.mjs} +51 -42
  153. package/dist/{provision-BEv0k-qz.mjs → provision-Wu9ZBk9L.mjs} +2 -3
  154. package/dist/{requests-B3PBuGlX.mjs → requests-DFAqyYy8.mjs} +5 -5
  155. package/dist/resolve-project-BIeYs9Cw.mjs +2 -0
  156. package/dist/{resolve-project-BG5ORGID.mjs → resolve-project-CP8rZs_p.mjs} +6 -1
  157. package/dist/{rollback-DDub9GsO.mjs → rollback-BKYXBduI.mjs} +30 -37
  158. package/dist/{route-types-Clm4WD0B.mjs → route-types-CbtsIeFn.mjs} +1 -1
  159. package/dist/route-url-BgPja1GS.d.mts +5 -0
  160. package/dist/route-url-BjGv_KKY.mjs +28 -0
  161. package/dist/runner-9wjsSZx-.mjs +2 -0
  162. package/dist/{runner-Ol0TNjk6.mjs → runner-DMBKSrRk.mjs} +2 -2
  163. package/dist/{runner-mysql-DmWchSWJ.mjs → runner-mysql-CEzKtmFb.mjs} +8 -8
  164. package/dist/{runner-mysql-CEG5JozK.mjs → runner-mysql-CkFqZ6CE.mjs} +1 -1
  165. package/dist/{runner-pg-Bh4AgZdj.mjs → runner-pg-BGYRFdRp.mjs} +1 -1
  166. package/dist/runtime/ai.d.mts +11 -12
  167. package/dist/runtime/ai.mjs +47 -113
  168. package/dist/runtime/better-auth-mysql.d.mts +1 -1
  169. package/dist/runtime/better-auth-mysql.mjs +4 -9
  170. package/dist/runtime/better-auth-pg.d.mts +1 -1
  171. package/dist/runtime/better-auth-pg.mjs +5 -10
  172. package/dist/runtime/better-auth.d.mts +1 -1
  173. package/dist/runtime/better-auth.mjs +3 -3
  174. package/dist/runtime/client-react.d.mts +2 -3
  175. package/dist/runtime/client-react.mjs +2 -2
  176. package/dist/runtime/client-solid.d.mts +2 -3
  177. package/dist/runtime/client-solid.mjs +2 -2
  178. package/dist/runtime/client-svelte.d.mts +2 -3
  179. package/dist/runtime/client-svelte.mjs +2 -2
  180. package/dist/runtime/client-vue.d.mts +2 -3
  181. package/dist/runtime/client-vue.mjs +2 -2
  182. package/dist/runtime/client.d.mts +2 -3
  183. package/dist/runtime/client.mjs +2 -2
  184. package/dist/runtime/db.mjs +1 -1
  185. package/dist/runtime/durable.mjs +3 -10
  186. package/dist/runtime/email/testing.mjs +5 -5
  187. package/dist/runtime/email.d.mts +2 -1
  188. package/dist/runtime/email.mjs +11 -27
  189. package/dist/runtime/env-public.d.mts +1 -1
  190. package/dist/runtime/env-public.mjs +15 -20
  191. package/dist/runtime/env.mjs +1 -1
  192. package/dist/runtime/fetch-stream.d.mts +2 -2
  193. package/dist/runtime/fetch-stream.mjs +1 -1
  194. package/dist/runtime/fetch.d.mts +2 -3
  195. package/dist/runtime/fetch.mjs +1 -1
  196. package/dist/runtime/handler.d.mts +1 -1
  197. package/dist/runtime/handler.mjs +2 -2
  198. package/dist/runtime/isr.mjs +1 -1
  199. package/dist/runtime/kv.mjs +10 -11
  200. package/dist/runtime/limits.d.mts +2 -2
  201. package/dist/runtime/limits.mjs +2 -2
  202. package/dist/runtime/live-client.d.mts +1 -1
  203. package/dist/runtime/live-client.mjs +12 -22
  204. package/dist/runtime/live-server.mjs +27 -35
  205. package/dist/runtime/live.d.mts +2 -2
  206. package/dist/runtime/live.mjs +2 -2
  207. package/dist/runtime/migration-handler.mjs +35 -86
  208. package/dist/runtime/queues.mjs +1 -1
  209. package/dist/runtime/remote/binding-handler.d.mts +2 -2
  210. package/dist/runtime/remote/binding-handler.mjs +8 -9
  211. package/dist/runtime/remote/index.mjs +27 -77
  212. package/dist/runtime/route-url.d.mts +2 -4
  213. package/dist/runtime/route-url.mjs +1 -1
  214. package/dist/runtime/routing.d.mts +1 -1
  215. package/dist/runtime/routing.mjs +15 -26
  216. package/dist/runtime/sandbox.d.mts +1 -1
  217. package/dist/runtime/sandbox.mjs +14 -24
  218. package/dist/runtime/sse.mjs +1 -1
  219. package/dist/runtime/storage.mjs +1 -1
  220. package/dist/runtime/validator.d.mts +1 -1
  221. package/dist/runtime/ws-server.d.mts +2 -2
  222. package/dist/runtime/ws-server.mjs +30 -61
  223. package/dist/runtime/ws.d.mts +1 -1
  224. package/dist/runtime/ws.mjs +1 -1
  225. package/dist/{sandbox-XZAqzFlG.d.mts → sandbox-C5LFoJMf.d.mts} +7 -7
  226. package/dist/{scan-C7okrLyM.mjs → scan-C3uDzz6J.mjs} +21 -18
  227. package/dist/{secret-3c72lY1U.mjs → secret-BAt2KMmO.mjs} +15 -15
  228. package/dist/{skills-BPQUGClu.mjs → skills-BgVMvQdy.mjs} +2 -2
  229. package/dist/{sse-CQNaDFFV.mjs → sse-CMvCgjNk.mjs} +1 -1
  230. package/dist/{subcommand-prompt-Dhom39bd.mjs → subcommand-prompt-BSlnD1fI.mjs} +2 -2
  231. package/dist/sveltekit.d.mts +0 -2
  232. package/dist/terminal-log-text-D9ACPOuG.mjs +32 -0
  233. package/dist/validate-BJr9LfXy.mjs +2 -0
  234. package/dist/{validate-ctOrgiS3.mjs → validate-C9qJArv7.mjs} +9 -28
  235. package/dist/{defer-YsYDUoii.mjs → validation-error-Dg9Recn1.mjs} +11 -11
  236. package/dist/{wrangler-DhUerFkW.mjs → wrangler-D9KTuqnv.mjs} +89 -194
  237. package/dist/{ws-CL1w7GXU.d.mts → ws-CChrrAU-.d.mts} +1 -1
  238. package/dist/{yarn-pnp-BV4AzNul.mjs → yarn-pnp-CUX_iTPA.mjs} +19 -27
  239. package/{skills/void/docs → docs}/guide/ai.md +69 -64
  240. package/{skills/void/docs → docs}/guide/app-types.md +1 -1
  241. package/{skills/void/docs → docs}/guide/auth.md +37 -1
  242. package/{skills/void/docs → docs}/guide/database/postgresql.md +2 -2
  243. package/{skills/void/docs → docs}/guide/database.md +23 -8
  244. package/{skills/void/docs → docs}/guide/edge/revalidation.md +1 -1
  245. package/{skills/void/docs → docs}/guide/edge/rewrites.md +2 -4
  246. package/{skills/void/docs → docs}/guide/email/receiving.md +2 -2
  247. package/{skills/void/docs → docs}/guide/email/sending.md +0 -2
  248. package/{skills/void/docs → docs}/guide/env-vars.md +4 -0
  249. package/{skills/void/docs → docs}/guide/jobs.md +2 -2
  250. package/{skills/void/docs → docs}/guide/live.md +12 -5
  251. package/{skills/void/docs → docs}/guide/pages-routing/actions-and-forms.md +21 -9
  252. package/{skills/void/docs → docs}/guide/pages-routing/loaders.md +7 -3
  253. package/{skills/void/docs → docs}/guide/pages-routing/markdown.md +15 -23
  254. package/{skills/void/docs → docs}/guide/pages-routing/overview.md +6 -4
  255. package/{skills/void/docs → docs}/guide/platform/administration/access.md +2 -10
  256. package/{skills/void/docs → docs}/guide/platform/administration/operations.md +3 -12
  257. package/{skills/void/docs → docs}/guide/platform/administration/projects.md +1 -1
  258. package/{skills/void/docs → docs}/guide/platform/development/local.md +4 -2
  259. package/{skills/void/docs → docs}/guide/platform/development/runtime.md +1 -1
  260. package/{skills/void/docs → docs}/guide/platform/development/schema-ci.md +1 -1
  261. package/{skills/void/docs → docs}/guide/platform/installation/credentials.md +2 -2
  262. package/{skills/void/docs → docs}/guide/platform/installation/domains.md +3 -1
  263. package/{skills/void/docs → docs}/guide/platform/installation/first-deployment.md +8 -2
  264. package/{skills/void/docs → docs}/guide/platform/installation/maintenance.md +7 -1
  265. package/{skills/void/docs → docs}/guide/platform/installation/setup.md +1 -1
  266. package/docs/guide/platform/installation/uninstall.md +102 -0
  267. package/{skills/void/docs → docs}/guide/project-collaboration.md +6 -2
  268. package/{skills/void/docs → docs}/guide/queues.md +0 -2
  269. package/{skills/void/docs → docs}/guide/remote-dev.md +5 -5
  270. package/{skills/void/docs → docs}/guide/sandboxes.md +41 -22
  271. package/{skills/void/docs → docs}/guide/sse.md +0 -2
  272. package/{skills/void/docs → docs}/guide/storage.md +7 -2
  273. package/{skills/void/docs → docs}/guide/websockets.md +4 -0
  274. package/docs/integrations/agents.md +37 -0
  275. package/{skills/void/docs → docs}/integrations/frameworks/astro.md +3 -3
  276. package/{skills/void/docs → docs}/integrations/frameworks/nuxt.md +6 -2
  277. package/{skills/void/docs → docs}/integrations/hono.md +15 -7
  278. package/{skills/void/docs → docs}/integrations/nodejs-bun-deno.md +1 -0
  279. package/{skills/void/docs → docs}/reference/api/auth.md +1 -1
  280. package/{skills/void/docs → docs}/reference/api/handlers.md +4 -2
  281. package/{skills/void/docs → docs}/reference/api/pages.md +4 -0
  282. package/{skills/void/docs → docs}/reference/api/resources.md +11 -14
  283. package/{skills/void/docs → docs}/reference/api.md +35 -34
  284. package/{skills/void/docs → docs}/reference/cli/auth.md +3 -6
  285. package/{skills/void/docs → docs}/reference/cli/database.md +3 -4
  286. package/{skills/void/docs → docs}/reference/cli/generate.md +1 -1
  287. package/{skills/void/docs → docs}/reference/cli/github.md +3 -12
  288. package/{skills/void/docs → docs}/reference/cli/platform-config.md +3 -3
  289. package/{skills/void/docs → docs}/reference/cli/platform-email.md +2 -3
  290. package/{skills/void/docs → docs}/reference/cli/platform-installation.md +15 -13
  291. package/{skills/void/docs → docs}/reference/cli/platform-operations.md +3 -0
  292. package/{skills/void/docs → docs}/reference/cli/platform-users.md +2 -2
  293. package/{skills/void/docs → docs}/reference/cli/platform.md +4 -2
  294. package/{skills/void/docs → docs}/reference/cli/project.md +5 -4
  295. package/{skills/void/docs → docs}/reference/cli/secrets.md +3 -3
  296. package/{skills/void/docs → docs}/reference/cli/setup.md +9 -11
  297. package/{skills/void/docs → docs}/reference/cli.md +2 -2
  298. package/{skills/void/docs → docs}/reference/config.md +13 -13
  299. package/{skills/void/docs → docs}/reference/resource-inference.md +2 -16
  300. package/package.json +34 -30
  301. package/schema.json +1 -1
  302. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +4 -1
  303. package/skills/void/SKILL.md +11 -5
  304. package/dist/cf-build-output-ChY6-XWP.mjs +0 -2
  305. package/dist/client-B4Me-9HE.mjs +0 -2
  306. package/dist/config-0acf1oys.mjs +0 -2
  307. package/dist/config-D8MOgiQV.mjs +0 -32
  308. package/dist/deploy-BDu1vhSH.mjs +0 -2
  309. package/dist/discover-AMCBXivQ.mjs +0 -2
  310. package/dist/fetch-error-Sp1R4mZv.d.mts +0 -20
  311. package/dist/gen-ById9r2j.mjs +0 -2
  312. package/dist/help-DPGBwomV.mjs +0 -2
  313. package/dist/login-C98-sw79.mjs +0 -2
  314. package/dist/migrate-CEu2X5DB.mjs +0 -2
  315. package/dist/plan-D1Q5rf-r.mjs +0 -2
  316. package/dist/platform-args-Cq6EjQro.mjs +0 -2
  317. package/dist/prepare-CnjcTV2s.mjs +0 -2
  318. package/dist/resolve-project-DtbidV4y.mjs +0 -2
  319. package/dist/route-url-CG7U-cRN.mjs +0 -15
  320. package/dist/runner-CXA9Fh8h.mjs +0 -2
  321. package/dist/validate-Dq_L3s0S.mjs +0 -2
  322. package/skills/void/docs/guide/platform/installation/uninstall.md +0 -69
  323. package/skills/void/docs/integrations/agents.md +0 -26
  324. package/dist/{runner-pg-D4OPlil-.mjs → runner-pg-DV8p_zjA.mjs} +4 -4
  325. package/{skills/void/docs → docs}/guide/database/d1.md +2 -2
  326. package/{skills/void/docs → docs}/guide/database/mysql.md +0 -0
  327. package/{skills/void/docs → docs}/guide/deployment.md +0 -0
  328. package/{skills/void/docs → docs}/guide/durable-state.md +0 -0
  329. package/{skills/void/docs → docs}/guide/edge/headers.md +0 -0
  330. package/{skills/void/docs → docs}/guide/edge/prerendering.md +0 -0
  331. package/{skills/void/docs → docs}/guide/edge/redirects.md +0 -0
  332. package/{skills/void/docs → docs}/guide/edge/static-assets.md +0 -0
  333. package/{skills/void/docs → docs}/guide/email/domains.md +0 -0
  334. package/{skills/void/docs → docs}/guide/email.md +0 -0
  335. package/{skills/void/docs → docs}/guide/index.md +0 -0
  336. package/{skills/void/docs → docs}/guide/kv.md +0 -0
  337. package/{skills/void/docs → docs}/guide/pages-routing/head.md +0 -0
  338. package/{skills/void/docs → docs}/guide/pages-routing/islands.md +2 -2
  339. package/{skills/void/docs → docs}/guide/pages-routing/layouts.md +0 -0
  340. package/{skills/void/docs → docs}/guide/pages-routing/view-transitions.md +0 -0
  341. package/{skills/void/docs → docs}/guide/platform/administration/email.md +0 -0
  342. package/{skills/void/docs → docs}/guide/platform/administration/plans.md +0 -0
  343. package/{skills/void/docs → docs}/guide/platform/administration/zero-trust.md +0 -0
  344. package/{skills/void/docs → docs}/guide/platform/installation/ci.md +0 -0
  345. package/{skills/void/docs → docs}/guide/platform/installation/prerequisites.md +0 -0
  346. package/{skills/void/docs → docs}/guide/platform-administration.md +0 -0
  347. package/{skills/void/docs → docs}/guide/platform-development.md +0 -0
  348. package/{skills/void/docs → docs}/guide/quickstart.md +0 -0
  349. package/{skills/void/docs → docs}/guide/self-hosted-platform.md +0 -0
  350. package/{skills/void/docs → docs}/guide/server-routing.md +3 -3
  351. package/{skills/void/docs → docs}/guide/ssg.md +0 -0
  352. package/{skills/void/docs → docs}/guide/ssr.md +0 -0
  353. package/{skills/void/docs → docs}/guide/type-safety.md +0 -0
  354. package/{skills/void/docs → docs}/guide/typed-fetch.md +0 -0
  355. package/{skills/void/docs → docs}/index.md +0 -0
  356. package/{skills/void/docs → docs}/integrations/cloudflare.md +0 -0
  357. package/{skills/void/docs → docs}/integrations/frameworks/analog.md +3 -3
  358. package/{skills/void/docs → docs}/integrations/frameworks/overview.md +0 -0
  359. package/{skills/void/docs → docs}/integrations/frameworks/react-router.md +3 -3
  360. package/{skills/void/docs → docs}/integrations/frameworks/sveltekit.md +1 -1
  361. package/{skills/void/docs → docs}/integrations/frameworks/tanstack-start.md +2 -2
  362. package/{skills/void/docs → docs}/reference/api/client.md +0 -0
  363. package/{skills/void/docs → docs}/reference/api/database.md +2 -2
  364. /package/{skills/void/docs → docs}/reference/api/durable.md +0 -0
  365. /package/{skills/void/docs → docs}/reference/api/env.md +0 -0
  366. /package/{skills/void/docs → docs}/reference/api/plugin.md +0 -0
  367. /package/{skills/void/docs → docs}/reference/api/rewrites.md +0 -0
  368. /package/{skills/void/docs → docs}/reference/api/types.md +0 -0
  369. /package/{skills/void/docs → docs}/reference/cli/deploy.md +0 -0
  370. /package/{skills/void/docs → docs}/reference/cli/domains.md +0 -0
  371. /package/{skills/void/docs → docs}/reference/cli/email.md +0 -0
  372. /package/{skills/void/docs → docs}/reference/cli/platform-zero-trust.md +0 -0
  373. /package/{skills/void/docs → docs}/reference/structure.md +0 -0
@@ -1,2 +1,2 @@
1
- import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-Dm09JNkn.mjs";
1
+ import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-D_QEY32D.mjs";
2
2
  export { runPlatformLifecycleCommand };
@@ -1,7 +1,7 @@
1
- import { a as listInstallationManifests, f as readInstallationRecoverySecrets, g as resolveInstallationManifest, h as removePlatformConnectionForInstallation, m as removeInstallationRecoverySecrets, t as acquirePlatformLifecycleLock, y as writeInstallationManifest } from "./platform-registry-KfNEF84O.mjs";
2
- import { A as confirm, B as note, H as outro, K as select, L as log, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
3
- import { r as createSpinner } from "./output-BBsUwdyT.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 assertProjectZeroTrustAllowsUninstall, f as loadPlatformRuntime, h as resolveBootstrapGitHubId, j as hyperdriveOriginConfigHash, m as createPlatformInstallationSecrets, n as resolvePlatformInstallDatabaseUrl, o as installPlatform, s as acquirePlatformDatabaseLifecycleLock, t as assertNoninteractivePlatformMutationAcknowledged, u as readPlatformProjectZeroTrustState, v as trackedPlatformWorkerTraffic, w as platformDatabaseNameFromOwnerUrl, x as platformAdoptionIntentHash, y as createPlatformInstallPlan } from "./platform-lifecycle-Dm09JNkn.mjs";
1
+ import { _ as removePlatformConnectionForInstallation, g as removeInstallationRecoverySecrets, m as readInstallationRecoverySecrets, o as listInstallationManifests, t as acquirePlatformLifecycleLock, v as resolveInstallationManifest, x as writeInstallationManifest } from "./platform-registry-P387v42A.mjs";
2
+ import { A as confirm, H as outro, K as select, L as log, tt as isCancel } from "./dist-D3m88sjf.mjs";
3
+ import { d as printSuccess, l as import_picocolors, r as createSpinner, u as note } from "./output-C50ag2r3.mjs";
4
+ import { A as resolveBootstrapGitHubId, B as assertPlatformOperatorCredentialCanApplyPlan, C as purgeResourcesKeptReason, D as loadPlatformRuntime, E as runPurgeResourcesTeardown, F as formatPlatformInstallPlan, H as verifyPlatformCloudflareCredential, I as platformAdoptionIntentHash, J as hyperdriveOriginFromConnectionString, K as PlatformCloudflareClient, L as platformProvisionIntentHash, N as trackedPlatformWorkerTraffic, P as createPlatformInstallPlan, R as revalidatePlatformInstallAction, S as purgeResourcesHandlesEmailRouting, T as purgeResourcesPermissions, V as resolvePlatformCloudflareCredential, X as verifyPlatformRuntimeTokenPermissions, Y as hyperdriveOriginMatches, _ as describePurgeResourcesPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY, b as isPurgedAccessResource, d as readPlatformProjectZeroTrustState, f as assertProjectZeroTrustAllowsUninstall, g as checkPurgeResourcesCredentials, h as assertNoPlatformProjects, k as createPlatformInstallationSecrets, m as PlatformResourceChangedError, n as resolvePlatformInstallDatabaseUrl, o as installPlatform, q as hyperdriveOriginConfigHash, s as acquirePlatformDatabaseLifecycleLock, t as assertNoninteractivePlatformMutationAcknowledged, u as readPlatformProjectSlugs, v as isPlatformTailWorker, w as purgeResourcesKeptResources, x as purgeResourcesAlwaysKept, y as isPurgeResourcesCandidate, z as platformDatabaseNameFromOwnerUrl } from "./platform-lifecycle-D_QEY32D.mjs";
5
5
  import { PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE, PLATFORM_R2_OWNERSHIP_MARKER_KEY, createPlatformResourceOwnershipMarker, parsePlatformInstallationManifest, parsePlatformResourceOwnershipMarker, recordInstallationResource, recordInstallationStep, setInstallationDesiredState, transitionInstallation } from "@void/platform";
6
6
  import { createHash } from "node:crypto";
7
7
  //#region src/cli/platform-management.ts
@@ -53,6 +53,13 @@ async function runInstalledPlatformCommand(args) {
53
53
  const manifest = await resolveInstalledPlatformManifest(args.selector);
54
54
  const operatorCredential = await resolvePlatformCloudflareCredential({ savedManagementToken: readInstallationRecoverySecrets(manifest)?.managementApiToken });
55
55
  const operatorClient = new PlatformCloudflareClient(operatorCredential.token);
56
+ await verifyPlatformCloudflareCredential(operatorClient, {
57
+ account: manifest.account,
58
+ source: operatorCredential.source,
59
+ r2Buckets: args.subcommand === "disable" || args.subcommand === "uninstall" ? [] : manifest.resources.filter((resource) => resource.kind === "r2-bucket").map((resource) => resource.name),
60
+ allowMissingR2Buckets: args.subcommand === "repair"
61
+ });
62
+ markPhase("operator credential");
56
63
  const runtime = args.subcommand === "uninstall" || args.subcommand === "disable" ? null : loadPlatformRuntime(args.runtime);
57
64
  const rollbackSourceRuntime = args.subcommand === "rollback" ? loadPlatformRuntime(args.fromRuntime) : null;
58
65
  let progress;
@@ -78,7 +85,12 @@ async function runInstalledPlatformCommand(args) {
78
85
  readProjectZeroTrust: databaseLock ? databaseLock.readProjectZeroTrust : () => readPlatformProjectZeroTrustState(databaseUrl, manifest.id, manifest.ownershipNonce),
79
86
  lockProjectZeroTrust: databaseLock?.lockProjectZeroTrust,
80
87
  fenceProjectZeroTrust: databaseLock?.fenceProjectZeroTrust,
81
- liftProjectZeroTrustFence: databaseLock?.liftProjectZeroTrustFence
88
+ liftProjectZeroTrustFence: databaseLock?.liftProjectZeroTrustFence,
89
+ readProjects: databaseLock ? databaseLock.readProjects : () => readPlatformProjectSlugs(databaseUrl, manifest.id, manifest.ownershipNonce),
90
+ credential: {
91
+ source: operatorCredential.source,
92
+ aiGatewayToken: !!gatewayToken
93
+ }
82
94
  });
83
95
  return;
84
96
  }
@@ -115,20 +127,12 @@ async function runInstalledPlatformCommand(args) {
115
127
  `Revision: ${runtime.manifest.sourceRevision ?? "not recorded"}`,
116
128
  `Manifest SHA-256: ${runtime.manifestSha256}`
117
129
  ].join("\n"), "Platform runtime");
118
- note([
119
- manifest.desiredState === "disabled" && args.subcommand !== "enable" ? "Application traffic will stay paused because this installation is disabled." : "Application traffic may pause during a safe cutover. Traffic resumes after verification.",
120
- "Saved progress survives an interruption. Resume with the same runtime files.",
121
- `Administrator status: ${plan.apiUrl}/admin/status`
122
- ].join("\n"), "Availability and progress");
130
+ log.info(manifest.desiredState === "disabled" && args.subcommand !== "enable" ? "Application traffic will stay paused because this installation is disabled." : "Application traffic may pause briefly during a safe cutover.");
123
131
  if (args.plan) {
124
132
  outro("No Cloudflare or local installation state was changed.");
125
133
  return;
126
134
  }
127
135
  assertPlatformOperatorCredentialCanApplyPlan(operatorCredential, plan);
128
- progress = createSpinner({ onCancel: () => {
129
- if (!process.emit("SIGINT")) process.exit(130);
130
- } });
131
- progress.start(args.subcommand === "upgrade" ? "Upgrading the platform" : args.subcommand === "rollback" ? "Rolling back the platform" : args.subcommand === "enable" ? "Enabling the platform" : "Repairing the platform");
132
136
  const repairingMissingRoutingCheckpoint = args.subcommand === "repair" && plan.actions.some((action) => action.key === "routing-kv" && action.action === "create" && action.id === null);
133
137
  await verifyPlatformMutationOwnership(client, manifest, new Set(manifest.resources.filter((resource) => isOwnershipVerifiableKind(resource.kind) && !plan.actions.some((action) => action.key === resource.key && action.action === "create" && action.name !== resource.name)).map((resource) => resource.key)), {
134
138
  allowMissingRoutingCheckpoint: repairingMissingRoutingCheckpoint,
@@ -137,7 +141,6 @@ async function runInstalledPlatformCommand(args) {
137
141
  });
138
142
  markPhase("ownership");
139
143
  const installation = args.subcommand === "enable" ? setInstallationDesiredState(manifest, "enabled", (/* @__PURE__ */ new Date()).toISOString()) : manifest;
140
- if (installation !== manifest) writeInstallationManifest(installation);
141
144
  const bootstrapGitHubLogin = process.env.VOID_PLATFORM_ADMIN_GITHUB_LOGIN || recovery?.bootstrapGitHubLogin || "";
142
145
  const bootstrapGitHubId = process.env.VOID_PLATFORM_ADMIN_GITHUB_ID || recovery?.bootstrapGitHubId || (bootstrapGitHubLogin ? await resolveBootstrapGitHubId(bootstrapGitHubLogin) : "");
143
146
  const secrets = createPlatformInstallationSecrets({
@@ -169,6 +172,11 @@ async function runInstalledPlatformCommand(args) {
169
172
  });
170
173
  markPhase("runtime token");
171
174
  if (!databaseLock?.readAuthenticationState) throw new Error("platform: The database lifecycle lock cannot read authoritative authentication settings.");
175
+ progress = createSpinner({ onCancel: () => {
176
+ if (!process.emit("SIGINT")) process.exit(130);
177
+ } });
178
+ progress.start(args.subcommand === "upgrade" ? "Upgrading the platform" : args.subcommand === "rollback" ? "Rolling back the platform" : args.subcommand === "enable" ? "Enabling the platform" : "Repairing the platform");
179
+ if (installation !== manifest) writeInstallationManifest(installation);
172
180
  const result = await installPlatform(plan, secrets, installation, {
173
181
  acquireDatabaseLifecycleLock: async () => Object.assign(async () => {}, {
174
182
  checkpoint: databaseLock?.checkpoint,
@@ -180,6 +188,7 @@ async function runInstalledPlatformCommand(args) {
180
188
  verifyDatabase: databaseLock?.verifyDatabase
181
189
  }),
182
190
  client,
191
+ operatorApiToken: operatorCredential.token,
183
192
  databaseRollbackSource: rollbackSourceRuntime ?? void 0,
184
193
  onProgress: (message) => {
185
194
  markPhase(message);
@@ -218,7 +227,6 @@ async function runInstalledPlatformCommand(args) {
218
227
  ].join("\n"), "Waiting for managed Sandbox drain");
219
228
  return;
220
229
  }
221
- log.success(`${deployment.displayName}: runtime ${runtime.manifest.platformVersion} ${args.subcommand === "rollback" ? "restored" : "ready"}.`);
222
230
  log.info(result.manifest.desiredState === "disabled" ? "Application traffic remains paused. Enable the installation when you are ready." : `Platform verification passed. Traffic is enabled at ${plan.apiUrl}.`);
223
231
  if (args.subcommand === "rollback") log.info("PostgreSQL migrations were retained; rollback changes the runtime only.");
224
232
  if (result.emailOperationId) log.info(`Shared email routing ready (operation ${result.emailOperationId}).`);
@@ -229,6 +237,7 @@ async function runInstalledPlatformCommand(args) {
229
237
  console.log(`One-time administrator setup code: ${code}`);
230
238
  }
231
239
  }
240
+ printSuccess(`${deployment.displayName}: runtime ${runtime.manifest.platformVersion} ${args.subcommand === "rollback" ? "restored" : "ready"}.`);
232
241
  };
233
242
  };
234
243
  if (args.plan) {
@@ -313,7 +322,7 @@ async function disablePlatform(client, initialManifest, planOnly, dependencies =
313
322
  const reconciled = await recoverDurablyMarkedProvisionIntents(client, initialManifest);
314
323
  const writeLifecycleCheckpoint = (checkpointClient, checkpointManifest) => writeLifecycleCheckpointWithoutDatabase(checkpointClient, checkpointManifest, dependencies.checkpoint);
315
324
  const writeRemoteManifestIfPresent = (checkpointClient, checkpointManifest) => writeRemoteManifestIfPresentWithoutDatabase(checkpointClient, checkpointManifest, dependencies.checkpoint);
316
- note("Block platform traffic through installation-owned routing storage. Retain routes and custom domains for explicit dashboard cleanup because Cloudflare cannot condition their deletion on an immutable generation. Workers and all data remain installed.", "Disable plan");
325
+ note("Block all platform traffic and the platform API. Routes, custom domains, Workers, and data stay installed.", "Disable plan");
317
326
  if (planOnly) {
318
327
  outro("No Cloudflare or local installation state was changed.");
319
328
  return;
@@ -345,7 +354,7 @@ async function disablePlatform(client, initialManifest, planOnly, dependencies =
345
354
  await writeLifecycleCheckpoint(client, next);
346
355
  next = transitionInstallation(next, "disabled", (/* @__PURE__ */ new Date()).toISOString());
347
356
  await writeLifecycleCheckpoint(client, next);
348
- log.success(`${next.deployment.displayName} is disabled. Its data was not changed.`);
357
+ printSuccess(`${next.deployment.displayName} is disabled. Its data was not changed.`);
349
358
  } catch (error) {
350
359
  next = transitionInstallation(next, "failed", (/* @__PURE__ */ new Date()).toISOString());
351
360
  writeInstallationManifest(next);
@@ -358,14 +367,33 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
358
367
  const writeLifecycleCheckpoint = (checkpointClient, checkpointManifest) => writeLifecycleCheckpointWithoutDatabase(checkpointClient, checkpointManifest, dependencies.checkpoint);
359
368
  const writeRemoteManifestIfPresent = (checkpointClient, checkpointManifest) => writeRemoteManifestIfPresentWithoutDatabase(checkpointClient, checkpointManifest, dependencies.checkpoint);
360
369
  const retainData = !args.purgeData;
361
- const hasRoutingCheckpoint = manifest.resources.some((resource) => resource.key === "routing-kv" && resource.state === "ready");
370
+ const purgeResources = args.purgeResources;
371
+ const routingKv = manifest.resources.find((resource) => resource.key === "routing-kv");
372
+ const reopenedRouting = purgeResources && routingKv?.state === "retained" && isPurgeResourcesCandidate(manifest, routingKv);
373
+ const hasRoutingCheckpoint = routingKv?.state === "ready" || reopenedRouting;
362
374
  const createdZone = manifest.resources.find((resource) => resource.key === "zone" && resource.ownership === "created");
363
375
  const interactive = dependencies.interactive ?? process.stdin.isTTY;
364
376
  const confirmAction = dependencies.confirm ?? promptForConfirmation;
365
377
  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.`);
366
378
  await assertProjectZeroTrustAllowsUninstall(dependencies.readProjectZeroTrust);
367
- 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.";
368
- 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");
379
+ if (purgeResources) await assertNoPlatformProjects(dependencies.readProjects);
380
+ const purgeResourcesClient = purgeResources ? requirePurgeResourcesClient(client) : null;
381
+ if (args.plan || interactive && !args.yes) note(purgeResources ? purgeResourcesPlanText(manifest) : [
382
+ "Disable platform traffic.",
383
+ retainData ? "Keep Workers and data." : "Delete eligible data; keep Workers, R2, and AI Gateway.",
384
+ "Delete unused Queues.",
385
+ ...describeKeptResources(manifest, plannedKeptResources(manifest, retainData, hasRoutingCheckpoint), "Keep for manual cleanup:", "Keep Access resources:")
386
+ ].join("\n"), import_picocolors.default.bold("Uninstall plan"));
387
+ if (purgeResourcesClient) {
388
+ const credentialCheck = checkPurgeResourcesCredentials(purgeResourcesClient, manifest, dependencies.credential ?? {
389
+ source: "environment",
390
+ aiGatewayToken: false
391
+ });
392
+ if (args.plan) await credentialCheck.catch((error) => {
393
+ log.warn(error instanceof Error ? error.message : String(error));
394
+ });
395
+ else await credentialCheck;
396
+ }
369
397
  if (args.plan) {
370
398
  outro("No Cloudflare or local installation state was changed.");
371
399
  return;
@@ -373,20 +401,29 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
373
401
  if (manifest !== initialManifest) writeInstallationManifest(manifest);
374
402
  if (!interactive && !args.yes) throw new Error("platform: Non-interactive `void platform uninstall` requires --yes to acknowledge Cloudflare changes. Run with --plan first to inspect them.");
375
403
  if (interactive && !args.yes) {
376
- if (!await confirmAction(args.purgeData ? "Permanently purge installer-owned platform data?" : "Uninstall this platform?", false)) {
404
+ if (!await confirmAction(purgeResources ? "Permanently delete every Cloudflare resource this installation created?" : args.purgeData ? "Permanently purge installer-owned platform data?" : "Uninstall this platform?", false)) {
377
405
  outro("No changes made.");
378
406
  return;
379
407
  }
380
408
  }
381
- const resourcesToDelete = new Set(manifest.resources.filter((resource) => shouldDeleteResource(resource, retainData) && (hasRoutingCheckpoint || resource.kind === "zone") && !(resource.kind === "dns-record" && !manifest.resources.some((entry) => entry.key === "zone"))).map((resource) => resource.key));
409
+ log.step(`Uninstalling ${manifest.deployment.displayName}...`);
410
+ const purgeResourcesKept = new Set(purgeResources ? purgeResourcesKeptResources(manifest).map((resource) => resource.key) : []);
411
+ const resourcesToDelete = new Set(manifest.resources.filter((resource) => (shouldDeleteResource(resource, retainData) || purgeResources && (resource.state === "ready" || isPurgeResourcesCandidate(manifest, resource)) && !purgeResourcesKept.has(resource.key) && isOwnershipVerifiableKind(resource.kind) && resource.kind !== "dns-record" && !hasLifecycleStep(manifest, `uninstall:purge-resources:r2-marker:${resource.key}`)) && (hasRoutingCheckpoint || resource.kind === "zone") && !(resource.kind === "dns-record" && !manifest.resources.some((entry) => entry.key === "zone"))).map((resource) => resource.key));
382
412
  const ownershipTargets = /* @__PURE__ */ new Set([
383
413
  ...hasRoutingCheckpoint ? ["routing-kv"] : [],
384
414
  "zone",
385
415
  ...manifest.resources.filter((resource) => resource.kind === "worker").map((resource) => resource.key),
386
416
  ...resourcesToDelete
387
417
  ]);
418
+ const proofManifest = {
419
+ ...manifest,
420
+ resources: manifest.resources.map((resource) => resource.state === "retained" && resourcesToDelete.has(resource.key) ? {
421
+ ...resource,
422
+ state: "ready"
423
+ } : resource)
424
+ };
388
425
  let missingResources;
389
- if (hasRoutingCheckpoint) missingResources = await verifyPlatformMutationOwnership(client, manifest, ownershipTargets, {
426
+ if (hasRoutingCheckpoint) missingResources = await verifyPlatformMutationOwnership(client, proofManifest, ownershipTargets, {
390
427
  allowDeletedRoutingCheckpoint: args.purgeData,
391
428
  databaseUrl: dependencies.databaseUrl
392
429
  });
@@ -408,6 +445,7 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
408
445
  let next = manifest;
409
446
  try {
410
447
  await assertProjectZeroTrustAllowsUninstall(dependencies.readProjectZeroTrust);
448
+ if (purgeResources) await assertNoPlatformProjects(dependencies.readProjects);
411
449
  fenced = true;
412
450
  await fenceProjectZeroTrust();
413
451
  next = transitionInstallation(manifest, "uninstalling", (/* @__PURE__ */ new Date()).toISOString());
@@ -418,7 +456,7 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
418
456
  }
419
457
  try {
420
458
  await writeRemoteManifestIfPresent(client, next);
421
- const routing = next.resources.find((resource) => resource.key === "routing-kv" && resource.state === "ready");
459
+ const routing = hasRoutingCheckpoint ? requireResource(next, "routing-kv") : void 0;
422
460
  disablingTraffic = true;
423
461
  if (routing) await client.putKvValue(next.account.id, routing.id, PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE);
424
462
  await releaseProjectZeroTrust();
@@ -442,6 +480,23 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
442
480
  await writeLifecycleCheckpoint(client, next);
443
481
  }
444
482
  }
483
+ if (purgeResourcesClient && hasRoutingCheckpoint) next = await runPurgeResourcesTeardown({
484
+ client: purgeResourcesClient,
485
+ checkpoint: async (checkpointManifest) => {
486
+ next = checkpointManifest;
487
+ await writeLifecycleCheckpoint(client, checkpointManifest);
488
+ },
489
+ verify: (checkpointManifest, keys) => verifyPlatformMutationOwnership(client, checkpointManifest, keys, {
490
+ allowDeletedRoutingCheckpoint: true,
491
+ databaseUrl: dependencies.databaseUrl
492
+ }),
493
+ bucketGeneration: async (checkpointManifest, bucket) => {
494
+ const live = (await client.listR2Buckets(checkpointManifest.account.id)).find((entry) => entry.id === bucket.id && entry.name === bucket.name);
495
+ if (!live) return null;
496
+ return live.fingerprint === void 0 ? "unknown" : r2BucketConfigHash(bucket.name, live.fingerprint);
497
+ },
498
+ readProjects: () => dependencies.readProjects()
499
+ }, next);
445
500
  const deletionPriority = {
446
501
  worker: 0,
447
502
  queue: 1,
@@ -455,7 +510,11 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
455
510
  };
456
511
  const resources = [...next.resources].sort((left, right) => resourceDeletionPriority(left, deletionPriority) - resourceDeletionPriority(right, deletionPriority));
457
512
  const queuesInUse = hasRoutingCheckpoint && resources.some((resource) => resource.kind === "queue" && shouldDeleteResource(resource, retainData)) && await hasLiveInstallationWorker(client, next);
458
- for (const resource of resources) {
513
+ for (const listed of resources) {
514
+ const resource = reopenedRouting && listed.key === "routing-kv" ? {
515
+ ...listed,
516
+ state: "ready"
517
+ } : listed;
459
518
  if (resource.state !== "ready") continue;
460
519
  if (!hasRoutingCheckpoint && resource.kind !== "zone") {
461
520
  next = updateResourceState(next, resource.key, "retained");
@@ -463,7 +522,8 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
463
522
  continue;
464
523
  }
465
524
  if (!shouldDeleteResource(resource, retainData)) {
466
- next = updateResourceState(next, resource.key, "retained");
525
+ const removed = resource.kind === "ai-gateway" && resource.ownership === "created" && !hasNamedResource(await client.listAiGateways(next.account.id), resource);
526
+ next = updateResourceState(next, resource.key, removed ? "deleted" : "retained");
467
527
  await writeLifecycleCheckpoint(client, next);
468
528
  continue;
469
529
  }
@@ -480,7 +540,7 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
480
540
  await writeLifecycleCheckpoint(client, next);
481
541
  continue;
482
542
  }
483
- await client.deleteResource(next.account.id, resource.kind, resource.id, zone?.id);
543
+ await client.deleteResource(next.account.id, resource, zone?.id);
484
544
  next = updateResourceState(next, resource.key, "deleted");
485
545
  await writeLifecycleCheckpoint(client, next);
486
546
  }
@@ -490,7 +550,9 @@ async function uninstallPlatform(client, initialManifest, args, dependencies = {
490
550
  writeInstallationManifest(completed);
491
551
  if (!retainData) removeInstallationRecoverySecrets(next);
492
552
  removePlatformConnectionForInstallation(next.id);
493
- log.success(retainData ? `${next.deployment.displayName} was uninstalled; data resources were retained and recorded in ${next.id}.` : `${next.deployment.displayName} was uninstalled.`);
553
+ const kept = describeKeptResources(next, next.resources.filter((resource) => resource.state === "retained"), "Cloudflare resources:", "Access resources:", purgeResources && purgeResourcesHandlesEmailRouting(next));
554
+ if (kept.length) note(kept.join("\n"), import_picocolors.default.bold("Kept resources"));
555
+ printSuccess(`Uninstalled ${next.deployment.displayName}.`);
494
556
  } catch (error) {
495
557
  await stopProjectZeroTrustHold().catch(() => {});
496
558
  next = transitionInstallation(next, "failed", (/* @__PURE__ */ new Date()).toISOString());
@@ -568,6 +630,87 @@ const DATA_RESOURCE_KINDS = /* @__PURE__ */ new Set([
568
630
  function isOwnershipVerifiableKind(kind) {
569
631
  return kind === "ai-gateway" || kind === "dispatch-namespace" || kind === "dns-record" || kind === "hyperdrive" || kind === "kv-namespace" || kind === "queue" || kind === "r2-bucket" || kind === "worker" || kind === "zone";
570
632
  }
633
+ const KEPT_RESOURCE_ORDER = [
634
+ "dns-record",
635
+ "worker-route",
636
+ "worker-custom-domain",
637
+ "queue",
638
+ "worker",
639
+ "dispatch-namespace",
640
+ "kv-namespace",
641
+ "hyperdrive",
642
+ "r2-bucket",
643
+ "ai-gateway",
644
+ "analytics-dataset",
645
+ "zone"
646
+ ];
647
+ /** Resources an uninstall with these options leaves in the account. */
648
+ function plannedKeptResources(manifest, retainData, hasRoutingCheckpoint) {
649
+ const workersRemain = manifest.resources.some((resource) => resource.kind === "worker" && resource.state === "ready");
650
+ return manifest.resources.filter((resource) => resource.state === "retained" || resource.state === "ready" && (!hasRoutingCheckpoint && resource.kind !== "zone" || !shouldDeleteResource(resource, retainData) || resource.kind === "queue" && workersRemain));
651
+ }
652
+ function keptResourceRank(manifest, resource) {
653
+ return isPlatformTailWorker(manifest, resource) ? KEPT_RESOURCE_ORDER.indexOf("dispatch-namespace") + .5 : KEPT_RESOURCE_ORDER.indexOf(resource.kind);
654
+ }
655
+ function purgeResourcesPlanText(manifest) {
656
+ const permissions = purgeResourcesPermissions(manifest);
657
+ const keepManifest = {
658
+ ...manifest,
659
+ authenticationResources: (manifest.authenticationResources ?? []).filter((resource) => resource.ownership !== "created" || purgeResourcesKeptReason(manifest, `access:${resource.key}`) !== null)
660
+ };
661
+ return [
662
+ "Disable platform traffic.",
663
+ ...describePurgeResourcesPlan(manifest),
664
+ ...describeKeptResources(keepManifest, purgeResourcesKeptResources(manifest), "Keep for manual cleanup:", "Keep Access resources you connected:", purgeResourcesHandlesEmailRouting(manifest)),
665
+ "Always kept:",
666
+ ...purgeResourcesAlwaysKept(),
667
+ ...permissions.length ? [`API token needs: ${permissions.join(", ")}. Browser login cannot delete DNS records or Access resources.`] : []
668
+ ].join("\n");
669
+ }
670
+ function requirePurgeResourcesClient(client) {
671
+ if ([
672
+ "deleteAccessResource",
673
+ "deleteDispatchNamespaceScript",
674
+ "deleteEmailRoutingRule",
675
+ "deleteQueueConsumer",
676
+ "deleteR2Object",
677
+ "deleteWorkerDomain",
678
+ "deleteWorkerRoute",
679
+ "emptyR2Bucket",
680
+ "forceDeleteWorker",
681
+ "getAccessResource",
682
+ "getEmailRoutingCatchAll",
683
+ "listDispatchNamespaceScripts",
684
+ "listEmailRoutingRules",
685
+ "listQueueConsumers",
686
+ "listWorkerDependents",
687
+ "listWorkerRoutes",
688
+ "resetEmailRoutingCatchAll"
689
+ ].some((method) => typeof client[method] !== "function")) throw new Error("platform: This Cloudflare client cannot run --purge-resources.");
690
+ return client;
691
+ }
692
+ function describeKeptResources(manifest, resources, heading, accessHeading, emailRulesRemoved = false) {
693
+ const sorted = [...resources].sort((left, right) => keptResourceRank(manifest, left) - keptResourceRank(manifest, right));
694
+ const isTraffic = (resource) => KEPT_RESOURCE_ORDER.indexOf(resource.kind) < KEPT_RESOURCE_ORDER.indexOf("queue");
695
+ const why = (key) => {
696
+ const reason = purgeResourcesKeptReason(manifest, key);
697
+ return reason === null ? "" : `, kept because ${reason}`;
698
+ };
699
+ const line = (resource) => ` ${resource.kind}: ${resource.name}${resource.name === resource.id ? "" : ` (${resource.id})`}${why(resource.key)}`;
700
+ const { capabilities, emailSenderDomain, emailSharedZoneId, resources: names } = manifest.deployment;
701
+ const email = capabilities.email ? [emailRulesRemoved && emailSenderDomain ? ` Email Routing for ${emailSenderDomain} (zone ${emailSharedZoneId}): its settings and the sender domain's MX, SPF, and DKIM records.` : emailSenderDomain ? ` Email Routing for ${emailSenderDomain} (zone ${emailSharedZoneId}): its routing DNS records and any catch-all rule that sends mail to ${names.emailGatewayWorker}.` : ` Email Routing: any catch-all rule that sends mail to ${names.emailGatewayWorker}.`] : [];
702
+ const remainingAccess = (manifest.authenticationResources ?? []).filter((resource) => !isPurgedAccessResource(manifest, resource));
703
+ const accessLine = (resource) => ` ${resource.ownership} ${resource.kind}: ${resource.name} (${resource.id}, account ${resource.accountId})${why(`access:${resource.key}`)}`;
704
+ const keptAccess = (resource) => purgeResourcesKeptReason(manifest, `access:${resource.key}`) !== null;
705
+ const kept = [
706
+ ...sorted.filter(isTraffic).map(line),
707
+ ...remainingAccess.filter(keptAccess).map(accessLine),
708
+ ...email,
709
+ ...sorted.filter((resource) => !isTraffic(resource)).map(line)
710
+ ];
711
+ const access = remainingAccess.filter((resource) => !keptAccess(resource)).map(accessLine);
712
+ return [...kept.length ? [heading, ...kept] : [], ...access.length ? [accessHeading, ...access] : []];
713
+ }
571
714
  function shouldDeleteResource(resource, retainData) {
572
715
  if (resource.state !== "ready" || resource.ownership !== "created") return false;
573
716
  if (resource.kind === "zone") return false;
@@ -641,7 +784,7 @@ async function verifyPlatformMutationOwnership(client, manifest, targetKeys, opt
641
784
  const zone = manifest.resources.find((resource) => resource.key === "zone");
642
785
  const [aiGateways, dispatchNamespaces, hyperdrives, kvNamespaces, r2Buckets, workerNames] = await Promise.all([
643
786
  client.listAiGateways(accountId),
644
- client.listDispatchNamespaces(accountId),
787
+ targetResources.some((resource) => resource.kind === "dispatch-namespace") ? client.listDispatchNamespaces(accountId) : Promise.resolve([]),
645
788
  client.listHyperdriveConfigs(accountId),
646
789
  client.listKvNamespaces(accountId),
647
790
  client.listR2Buckets(accountId),
@@ -686,7 +829,7 @@ async function verifyPlatformMutationOwnership(client, manifest, targetKeys, opt
686
829
  name: resource.name
687
830
  })).digest("hex");
688
831
  const expectedHash = dnsRecordConfigHash(resource.name, "AAAA", "100::", true);
689
- if (liveHash !== resource.configHash && !(resource.configHash === legacyHash && liveHash === expectedHash)) throw ownershipError(`dns-record ${resource.name} changed configuration after installation`);
832
+ if (liveHash !== resource.configHash && !(resource.configHash === legacyHash && liveHash === expectedHash)) throw new PlatformResourceChangedError(resource.key, "its configuration changed after installation", ownershipError(`dns-record ${resource.name} changed configuration after installation`).message);
690
833
  }
691
834
  }
692
835
  } else if (resource.kind === "worker") {
@@ -725,7 +868,7 @@ function isPlatformManifestMonotonicExtension(earlier, later) {
725
868
  if (earlier.id !== later.id || earlier.ownershipNonce !== later.ownershipNonce || earlier.account.id !== later.account.id || earlier.createdAt !== later.createdAt || JSON.stringify(earlier.deployment) !== JSON.stringify(later.deployment) || Date.parse(later.updatedAt) < Date.parse(earlier.updatedAt)) return false;
726
869
  const resourcesAdvance = earlier.resources.every((resource) => {
727
870
  const next = later.resources.find((entry) => entry.key === resource.key);
728
- return next?.id === resource.id && next.kind === resource.kind && next.name === resource.name && next.ownership === resource.ownership && (next.state === resource.state || resource.state === "ready" && (next.state === "deleted" || next.state === "retained"));
871
+ return next?.id === resource.id && next.kind === resource.kind && next.name === resource.name && next.ownership === resource.ownership && (next.state === resource.state || resource.state === "ready" && (next.state === "deleted" || next.state === "retained") || resource.state === "retained" && next.state === "deleted");
729
872
  });
730
873
  const stepsAdvance = earlier.steps.every((step) => later.steps.some((entry) => entry.key === step.key && entry.completedAt === step.completedAt && entry.resultHash === step.resultHash));
731
874
  const authenticationResourcesAdvance = (earlier.authenticationResources ?? []).every((resource) => (later.authenticationResources ?? []).some((next) => JSON.stringify(next) === JSON.stringify(resource)));
@@ -1,2 +1,2 @@
1
- import { c as runInstalledPlatformCommand, d as verifyPlatformInstallationOwnership, l as selectAuthoritativePlatformManifest } from "./platform-management-BSEc_ZeG.mjs";
1
+ import { c as runInstalledPlatformCommand, d as verifyPlatformInstallationOwnership, l as selectAuthoritativePlatformManifest } from "./platform-management-BdYblvvE.mjs";
2
2
  export { runInstalledPlatformCommand, selectAuthoritativePlatformManifest, verifyPlatformInstallationOwnership };
@@ -1,6 +1,7 @@
1
- import { A as confirm, K as select, X as text, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
2
- import { n as OperatorClient, r as OperatorClientError } from "./operator-client-LmwjxT6q.mjs";
3
- import { a as resolveOperatorOrigin, r as readOperatorToken } from "./operator-auth-CkmTE3rt.mjs";
1
+ import { A as confirm, K as select, X as text, tt as isCancel } from "./dist-D3m88sjf.mjs";
2
+ import { d as printSuccess } from "./output-C50ag2r3.mjs";
3
+ import { n as OperatorClient, r as OperatorClientError } from "./operator-client-BQtzyG-g.mjs";
4
+ import { a as resolveOperatorOrigin, r as readOperatorToken } from "./operator-auth-AzVLbrr3.mjs";
4
5
  import { stripVTControlCharacters } from "node:util";
5
6
  import { PLAN_EDITABLE_LIMIT_KEYS, PLAN_LIMITS, parseBuildInstanceType, parsePlanLimitsPatch, parsePlanName, parsePlatformPlanId } from "@void/platform/plans";
6
7
  import { readFile } from "node:fs/promises";
@@ -215,7 +216,7 @@ async function apply(client, path, body, args, catalog) {
215
216
  ...result
216
217
  };
217
218
  if (args.json) print(completed);
218
- else console.log(`Saved ${applied.action ?? "plans.sync"} ${applied.target ?? ""}. Account updates complete.`);
219
+ else printSuccess(`Saved ${applied.action ?? "plans.sync"} ${applied.target ?? ""}. Account updates complete.`);
219
220
  }
220
221
  async function runPlatformPlansConfig(args) {
221
222
  const origin = resolveOperatorOrigin(args.connection);
@@ -1,7 +1,7 @@
1
- import { _ as savePlatformConnection, a as listInstallationManifests, t as acquirePlatformLifecycleLock, y as writeInstallationManifest } from "./platform-registry-KfNEF84O.mjs";
1
+ import { o as listInstallationManifests, t as acquirePlatformLifecycleLock, x as writeInstallationManifest, y as savePlatformConnection } from "./platform-registry-P387v42A.mjs";
2
2
  import { t as cfAccessHeaders } from "./cf-access-TWNzXltp.mjs";
3
- import { a as REMOTE_INSTALLATION_MANIFEST_KEY, y as createPlatformInstallPlan } from "./platform-lifecycle-Dm09JNkn.mjs";
4
- import { a as recoverDurablyMarkedProvisionIntents, d as verifyPlatformInstallationOwnership, r as isPlatformManifestMonotonicExtension } from "./platform-management-BSEc_ZeG.mjs";
3
+ import { P as createPlatformInstallPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY } from "./platform-lifecycle-D_QEY32D.mjs";
4
+ import { a as recoverDurablyMarkedProvisionIntents, d as verifyPlatformInstallationOwnership, r as isPlatformManifestMonotonicExtension } from "./platform-management-BdYblvvE.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 = "") {
@@ -189,6 +189,19 @@ function getActivePlatformConnection(directory = platformRegistryDirectory()) {
189
189
  const registry = readRegistry(directory);
190
190
  return registry.connections.find((connection) => connection.id === registry.activeConnectionId) ?? (registry.connections.length === 1 ? registry.connections[0] : null);
191
191
  }
192
+ function platformConnectionSlug(connection, installations) {
193
+ const matches = installations.filter((manifest) => manifest.status !== "uninstalled" && manifest.id === connection.installationId && (connection.accountId === null || connection.accountId === manifest.account.id));
194
+ return matches.length === 1 ? matches[0].deployment.installationSlug : null;
195
+ }
196
+ /** Resolve saved platforms without selecting one or changing its credentials. */
197
+ function findPlatformConnections(selector, directory = platformRegistryDirectory(), connections = listPlatformConnections(directory)) {
198
+ let normalizedUrl = null;
199
+ try {
200
+ normalizedUrl = normalizePlatformApiUrl(selector);
201
+ } catch {}
202
+ const installations = connections.some((connection) => connection.installationId) ? listInstallationManifests(directory) : [];
203
+ return connections.filter((entry) => entry.id === selector || entry.installationId === selector || entry.displayName.toLowerCase() === selector.toLowerCase() || entry.apiUrl === normalizedUrl || platformConnectionSlug(entry, installations) === selector.toLowerCase());
204
+ }
192
205
  function savePlatformConnection(input, directory = platformRegistryDirectory()) {
193
206
  const apiUrl = normalizePlatformApiUrl(input.apiUrl);
194
207
  const id = platformConnectionId(apiUrl);
@@ -214,14 +227,7 @@ function savePlatformConnection(input, directory = platformRegistryDirectory())
214
227
  function selectPlatformConnection(selector, directory = platformRegistryDirectory()) {
215
228
  return withRegistryLock(directory, () => {
216
229
  const current = readRegistry(directory);
217
- const normalizedUrl = (() => {
218
- try {
219
- return normalizePlatformApiUrl(selector);
220
- } catch {
221
- return null;
222
- }
223
- })();
224
- const matches = current.connections.filter((entry) => entry.id === selector || entry.installationId === selector || entry.displayName.toLowerCase() === selector.toLowerCase() || normalizedUrl !== null && entry.apiUrl === normalizedUrl);
230
+ const matches = findPlatformConnections(selector, directory, current.connections);
225
231
  if (matches.length !== 1) throw new Error(matches.length === 0 ? `platform: No installed or connected platform matches ${JSON.stringify(selector)}.` : `platform: More than one platform matches ${JSON.stringify(selector)}. Use its id or URL.`);
226
232
  const selected = {
227
233
  ...matches[0],
@@ -273,7 +279,8 @@ function listInstallationManifests(directory = platformRegistryDirectory()) {
273
279
  return manifests.sort((left, right) => left.deployment.displayName.localeCompare(right.deployment.displayName));
274
280
  }
275
281
  function resolveInstallationManifest(selector, directory = platformRegistryDirectory()) {
276
- const manifests = listInstallationManifests(directory).filter((manifest) => manifest.status !== "uninstalled" && (!selector || manifest.id === selector || manifest.deployment.installationSlug === selector || manifest.deployment.displayName.toLowerCase() === selector.toLowerCase()));
282
+ const connection = selector ? listPlatformConnections(directory).find((entry) => entry.id === selector) : void 0;
283
+ const manifests = listInstallationManifests(directory).filter((manifest) => manifest.status !== "uninstalled" && (!selector || manifest.id === selector || manifest.id === connection?.installationId && (connection.accountId === null || connection.accountId === manifest.account.id) || manifest.deployment.installationSlug === selector || manifest.deployment.displayName.toLowerCase() === selector.toLowerCase()));
277
284
  if (manifests.length !== 1) throw new Error(manifests.length === 0 ? `platform: No local installation matches ${JSON.stringify(selector)}.` : "platform: Multiple local installations match; specify an installation id.");
278
285
  return manifests[0];
279
286
  }
@@ -428,4 +435,4 @@ function removePlatformConnectionForInstallation(installationId, directory = pla
428
435
  });
429
436
  }
430
437
  //#endregion
431
- export { writeKeyringPassword as C, readKeyringPassword as S, savePlatformConnection as _, listInstallationManifests as a, writePendingInstallationSecrets as b, platformCredentialAccount as c, promoteInstallationSecrets as d, readInstallationRecoverySecrets as f, resolveInstallationManifest as g, removePlatformConnectionForInstallation as h, latestPlatformWorkerCutoverGeneration as i, platformRegistryDirectory as l, removeInstallationRecoverySecrets as m, assertPlatformInstallationSlugAvailable as n, listPlatformConnections as o, readPendingInstallationSecrets as p, getActivePlatformConnection as r, normalizePlatformApiUrl as s, acquirePlatformLifecycleLock as t, platformWorkerSecretUpdateIntentState as u, selectPlatformConnection as v, deleteKeyringPassword as x, writeInstallationManifest as y };
438
+ export { deleteKeyringPassword as C, writePendingInstallationSecrets as S, writeKeyringPassword as T, removePlatformConnectionForInstallation as _, latestPlatformWorkerCutoverGeneration as a, selectPlatformConnection as b, normalizePlatformApiUrl as c, platformRegistryDirectory as d, platformWorkerSecretUpdateIntentState as f, removeInstallationRecoverySecrets as g, readPendingInstallationSecrets as h, getActivePlatformConnection as i, platformConnectionSlug as l, readInstallationRecoverySecrets as m, assertPlatformInstallationSlugAvailable as n, listInstallationManifests as o, promoteInstallationSecrets as p, findPlatformConnections as r, listPlatformConnections as s, acquirePlatformLifecycleLock as t, platformCredentialAccount as u, resolveInstallationManifest as v, readKeyringPassword as w, writeInstallationManifest as x, savePlatformConnection as y };