void 0.23.0 → 0.25.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 (169) hide show
  1. package/AGENTS_TEMPLATE.md +1 -1
  2. package/README.md +19 -106
  3. package/dist/{account-cmd-C84Ee8cO.mjs → account-cmd-DcR1ywt8.mjs} +5 -5
  4. package/dist/{auth-CSkdO2Bb.mjs → auth-7wuZ5ob8.mjs} +22 -49
  5. package/dist/auth-CdgZ9uag.mjs +2 -0
  6. package/dist/{auth-link-CioEg6uY.mjs → auth-link-Z6E5DYvM.mjs} +5 -6
  7. package/dist/{auth-router-BsR981d4.mjs → auth-router-BdM4avI8.mjs} +7 -7
  8. package/dist/{build-cmd-LzvNJORH.mjs → build-cmd-CEE7D-hM.mjs} +7 -8
  9. package/dist/{cache-C4MvnrMH.mjs → cache-TcZnBLtH.mjs} +6 -7
  10. package/dist/{cancel-deploy-abUxpP2n.mjs → cancel-deploy-CYoZmcmR.mjs} +4 -6
  11. package/dist/{cf-access-P0iZnu0q.mjs → cf-access-AHKBzmuu.mjs} +4 -48
  12. package/dist/{cf-access-DRsQRe6k.mjs → cf-access-TWNzXltp.mjs} +3 -11
  13. package/dist/cf-build-output-ChY6-XWP.mjs +2 -0
  14. package/dist/cli/cli.mjs +49 -46
  15. package/dist/cli/cloudflare-operation-process.mjs +16 -7
  16. package/dist/cli/env-schema-probe.mjs +3 -3
  17. package/dist/client-B4Me-9HE.mjs +2 -0
  18. package/dist/{client-RV8NVeB8.mjs → client-RsPo8wsP.mjs} +129 -33
  19. package/dist/{cloudflare-cmd-BcrVyTmJ.mjs → cloudflare-cmd-bhwCxAN6.mjs} +2 -2
  20. package/dist/{cloudflare-connect-B8uPZ4nx.mjs → cloudflare-connect-CuhRgk3k.mjs} +2 -2
  21. package/dist/{cloudflare-operations-AiWashgg.mjs → cloudflare-operations-BhbK6yTq.mjs} +1 -1
  22. package/dist/{cloudflare-operations-fxHb-byx.mjs → cloudflare-operations-CjaV4lZi.mjs} +2 -2
  23. package/dist/{connect-Bd4kJd9U.mjs → connect-DCvUmPXY.mjs} +13 -10
  24. package/dist/{create-project-Boczwj5r.mjs → create-project-C734I-Mu.mjs} +1 -1
  25. package/dist/{create-project-bMf6ffLZ.mjs → create-project-eAPgYq35.mjs} +13 -13
  26. package/dist/{db-8uG64XLl.mjs → db-C07GEdKF.mjs} +27 -30
  27. package/dist/{delete-NvbiyeJf.mjs → delete-pKMVsrpJ.mjs} +5 -6
  28. package/dist/deploy-BDu1vhSH.mjs +2 -0
  29. package/dist/{deploy-DzAIwqNU.mjs → deploy-DfsAe-T0.mjs} +9567 -9215
  30. package/dist/{dev-inbox-P0u4tM8Y.mjs → dev-inbox-D64ZKUod.mjs} +5 -6
  31. package/dist/{domain-y5Tvydvo.mjs → domain-D3uA9ize.mjs} +8 -8
  32. package/dist/{email-B3umsW75.mjs → email-z3o2cwjH.mjs} +8 -8
  33. package/dist/{env-BS6qYHDb.mjs → env-3Q8-_2IH.mjs} +7 -9
  34. package/dist/{env-types-C2_bIk_b.mjs → env-types-D5kds_OZ.mjs} +1 -1
  35. package/dist/{env-validation-DbTg7-ar.mjs → env-validation-cZBvGWaP.mjs} +1 -1
  36. package/dist/{env-validation-BPn7vk-V.mjs → env-validation-vBSQ8gw5.mjs} +3 -3
  37. package/dist/gen-ById9r2j.mjs +2 -0
  38. package/dist/{gen-B580--vC.mjs → gen-NjwoG9FK.mjs} +2 -4
  39. package/dist/{github-cmd-v45BdfKX.mjs → github-cmd-DquUq-b1.mjs} +15 -24
  40. package/dist/{headers-DWi2IXWx.mjs → headers-2rKda9Y6.mjs} +1 -1
  41. package/dist/help-DPGBwomV.mjs +2 -0
  42. package/dist/{help-daGKjXGk.mjs → help-DRZXC4fj.mjs} +8 -4
  43. package/dist/{inbound-aVHEUhKo.mjs → inbound-fRkqcXaC.mjs} +1 -1
  44. package/dist/index.d.mts +18 -14
  45. package/dist/index.mjs +2176 -2110
  46. package/dist/{info-B97bTX9N.mjs → info-BmA3_IFZ.mjs} +1 -3
  47. package/dist/{init-Bvy7zrBo.mjs → init-DT7yuuyl.mjs} +28 -27
  48. package/dist/{link-CDqqCjFl.mjs → link-CXOlqh2F.mjs} +6 -7
  49. package/dist/{list-CZj0dzKY.mjs → list-eEWVJEPn.mjs} +8 -9
  50. package/dist/{local-d1-2CMnpuW_.mjs → local-d1-Df4XpwhW.mjs} +1 -1
  51. package/dist/log-vqY3pqwI.mjs +29 -0
  52. package/dist/login-C98-sw79.mjs +2 -0
  53. package/dist/{login-UZKFM_u7.mjs → login-pWQHYVu2.mjs} +12 -10
  54. package/dist/{logs-CUZ6t9t3.mjs → logs-DnxVX7TR.mjs} +11 -13
  55. package/dist/migrate-CEu2X5DB.mjs +2 -0
  56. package/dist/{migrate-DHul7PRV.mjs → migrate-CV1on-yJ.mjs} +2 -4
  57. package/dist/{operator-args-CLgKGlwU.mjs → operator-args-CAVcmwUt.mjs} +12 -5
  58. package/dist/{operator-auth-8KnOVXVd.mjs → operator-auth-CkmTE3rt.mjs} +2 -2
  59. package/dist/{operator-client-DUwumHpQ.mjs → operator-client-LmwjxT6q.mjs} +3 -3
  60. package/dist/{operator-cmd-DBA6dl0m.mjs → operator-cmd-d-IEKgNk.mjs} +6 -6
  61. package/dist/{output-Dm_A4Tbv.mjs → output-BBsUwdyT.mjs} +22 -14
  62. package/dist/pages/client.d.mts +3 -0
  63. package/dist/pages/client.mjs +120 -29
  64. package/dist/pages/index.mjs +1 -1
  65. package/dist/{platform-args-BJdRtlLq.mjs → platform-args-Bzf8JPc2.mjs} +11 -3
  66. package/dist/platform-args-Cq6EjQro.mjs +2 -0
  67. package/dist/{platform-auth-config-B56E9YP1.mjs → platform-auth-config-0V0lA3pF.mjs} +7 -7
  68. package/dist/{platform-auth-protection-BDWO_aER.mjs → platform-auth-protection-DFeJ-JkK.mjs} +9 -9
  69. package/dist/{platform-auth-recovery-1gg4CSRe.mjs → platform-auth-recovery-ICy4muq6.mjs} +7 -7
  70. package/dist/{platform-cmd-Bt-1w6pY.mjs → platform-cmd-BPySFOew.mjs} +1 -1
  71. package/dist/{platform-cmd-DMcQStSc.mjs → platform-cmd-D7vSWMvV.mjs} +38 -28
  72. package/dist/platform-discovery-DDDUvnqp.mjs +27 -0
  73. package/dist/{platform-domain-BNkcz0OB.mjs → platform-domain-CUdY064e.mjs} +5 -5
  74. package/dist/{platform-lifecycle-BE6C_jxh.mjs → platform-lifecycle-BaUdTRPU.mjs} +1 -1
  75. package/dist/{platform-lifecycle-9OyBALhH.mjs → platform-lifecycle-Dm09JNkn.mjs} +4404 -3297
  76. package/dist/{platform-management-CjwLVQwN.mjs → platform-management-BSEc_ZeG.mjs} +48 -11
  77. package/dist/platform-management-Bp6aoH2C.mjs +2 -0
  78. package/dist/{platform-plans-config-BNGKGr4P.mjs → platform-plans-config-B0pOVQyW.mjs} +3 -3
  79. package/dist/{platform-recovery-D6KSpuFm.mjs → platform-recovery-WOZ95Uze.mjs} +4 -4
  80. package/dist/{platform-registry-QBa4DK32.mjs → platform-registry-KfNEF84O.mjs} +3 -3
  81. package/dist/{prepare-B5Mkic5u.mjs → prepare-39EvOhI6.mjs} +2 -4
  82. package/dist/prepare-CnjcTV2s.mjs +2 -0
  83. package/dist/{prepare-DOsL0CC9.mjs → prepare-DnaKBi--.mjs} +1 -1
  84. package/dist/{project-C0Fqu05O.mjs → project-BkbfDs0V.mjs} +15 -82
  85. package/dist/project-IOjBU8R6.mjs +2 -0
  86. package/dist/{project-cmd-CNzrqvBv.mjs → project-cmd-Bs5A392E.mjs} +21 -22
  87. package/dist/{project-team-DQOWPfQT.mjs → project-team-ohAWWaew.mjs} +8 -9
  88. package/dist/{project-token-CTDYU0Cc.mjs → project-token-CP01Jna6.mjs} +6 -9
  89. package/dist/{project-zero-trust-BNAkW-_0.mjs → project-zero-trust-BzkVgx35.mjs} +5 -6
  90. package/dist/prompts-6OSVA7DJ.mjs +2087 -0
  91. package/dist/prompts-ZAuJlyCj.mjs +2 -0
  92. package/dist/{provision-C4ORE7G7.mjs → provision-BEv0k-qz.mjs} +1 -1
  93. package/dist/{provision-CJFgTZY8.mjs → provision-Btj1jppf.mjs} +5 -7
  94. package/dist/{requests-MhxYnau8.mjs → requests-B3PBuGlX.mjs} +5 -6
  95. package/dist/{rollback-CJ6iSDoU.mjs → rollback-DDub9GsO.mjs} +9 -10
  96. package/dist/runtime/ai.mjs +3 -5
  97. package/dist/runtime/email/testing.mjs +2 -2
  98. package/dist/runtime/email.mjs +36 -18
  99. package/dist/runtime/remote/index.mjs +2 -2
  100. package/dist/runtime/routing.mjs +1 -1
  101. package/dist/{secret-Dli5fP0B.mjs → secret-3c72lY1U.mjs} +15 -16
  102. package/dist/{skills-D1II1Juz.mjs → skills-BPQUGClu.mjs} +1 -1
  103. package/dist/{subcommand-prompt-CY1C4fvl.mjs → subcommand-prompt-Dhom39bd.mjs} +40 -32
  104. package/dist/sveltekit.d.mts +1 -1
  105. package/dist/sveltekit.mjs +4 -9
  106. package/dist/{wrangler-7K-bW_DL.mjs → wrangler-DhUerFkW.mjs} +10 -15
  107. package/package.json +22 -23
  108. package/sandbox.Dockerfile +1 -1
  109. package/skills/void/SKILL.md +6 -1
  110. package/skills/void/docs/guide/ai.md +24 -86
  111. package/skills/void/docs/guide/auth.md +0 -2
  112. package/skills/void/docs/guide/database/d1.md +7 -7
  113. package/skills/void/docs/guide/deployment.md +58 -102
  114. package/skills/void/docs/guide/edge/headers.md +1 -1
  115. package/skills/void/docs/guide/email/domains.md +5 -1
  116. package/skills/void/docs/guide/email/sending.md +1 -1
  117. package/skills/void/docs/guide/env-vars.md +1 -5
  118. package/skills/void/docs/guide/index.md +19 -18
  119. package/skills/void/docs/guide/kv.md +0 -2
  120. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +49 -47
  121. package/skills/void/docs/guide/pages-routing/overview.md +2 -2
  122. package/skills/void/docs/guide/platform/administration/email.md +0 -2
  123. package/skills/void/docs/guide/platform/administration/operations.md +11 -22
  124. package/skills/void/docs/guide/platform/administration/plans.md +1 -5
  125. package/skills/void/docs/guide/platform/administration/zero-trust.md +24 -9
  126. package/skills/void/docs/guide/platform/development/schema-ci.md +7 -1
  127. package/skills/void/docs/guide/platform/installation/ci.md +1 -1
  128. package/skills/void/docs/guide/platform/installation/credentials.md +10 -3
  129. package/skills/void/docs/guide/platform/installation/domains.md +8 -3
  130. package/skills/void/docs/guide/platform/installation/first-deployment.md +2 -2
  131. package/skills/void/docs/guide/platform/installation/maintenance.md +37 -5
  132. package/skills/void/docs/guide/platform/installation/prerequisites.md +87 -14
  133. package/skills/void/docs/guide/platform/installation/setup.md +80 -10
  134. package/skills/void/docs/guide/quickstart.md +37 -80
  135. package/skills/void/docs/guide/remote-dev.md +1 -1
  136. package/skills/void/docs/guide/sandboxes.md +36 -46
  137. package/skills/void/docs/guide/self-hosted-platform.md +20 -0
  138. package/skills/void/docs/guide/websockets.md +0 -2
  139. package/skills/void/docs/integrations/frameworks/overview.md +2 -2
  140. package/skills/void/docs/integrations/frameworks/sveltekit.md +40 -25
  141. package/skills/void/docs/integrations/nodejs-bun-deno.md +7 -2
  142. package/skills/void/docs/reference/api/resources.md +27 -0
  143. package/skills/void/docs/reference/api.md +1 -1
  144. package/skills/void/docs/reference/cli/auth.md +4 -3
  145. package/skills/void/docs/reference/cli/database.md +1 -1
  146. package/skills/void/docs/reference/cli/deploy.md +21 -1
  147. package/skills/void/docs/reference/cli/platform-installation.md +42 -27
  148. package/skills/void/docs/reference/cli/platform-operations.md +4 -8
  149. package/skills/void/docs/reference/cli/platform-zero-trust.md +14 -0
  150. package/skills/void/docs/reference/cli/platform.md +5 -0
  151. package/skills/void/docs/reference/config.md +1 -1
  152. package/skills/void/docs/reference/resource-inference.md +11 -8
  153. package/dist/auth-CCjt0hcq.mjs +0 -2
  154. package/dist/cf-build-output-_0HNWysu.mjs +0 -2
  155. package/dist/client-Cu7jWiF1.mjs +0 -2
  156. package/dist/deploy-bjXdFCtn.mjs +0 -2
  157. package/dist/dist-BuDuKZJv.mjs +0 -2
  158. package/dist/dist-CTBk70IR.mjs +0 -1310
  159. package/dist/gen-BVaUUumi.mjs +0 -2
  160. package/dist/help-DofyZuY7.mjs +0 -2
  161. package/dist/log-ChfPKsVd.mjs +0 -26
  162. package/dist/login-DYt_An22.mjs +0 -2
  163. package/dist/migrate-8_2u55MD.mjs +0 -2
  164. package/dist/platform-args-D3RXyR6h.mjs +0 -2
  165. package/dist/platform-management-CnyTdcWX.mjs +0 -2
  166. package/dist/prepare-cgvDMtSb.mjs +0 -2
  167. package/dist/project-BuUwfj6f.mjs +0 -2
  168. package/skills/void/docs/guide/env-migration.md +0 -109
  169. package/dist/{cf-build-output-BPqOT964.mjs → cf-build-output-U8o1Gl6X.mjs} +1 -1
@@ -0,0 +1,2 @@
1
+ import { K as select, L as log, X as text, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
2
+ export { isCancel, log, select, text };
@@ -1,3 +1,3 @@
1
1
  import { r as scanWranglerDotenvKeys } from "./dotenv-VQxupEUv.mjs";
2
- import { _ as resolvePinnedApiBaseUrl, a as checkCloudflareProvisionDrift, c as enableD1ReadReplicationViaApi, d as isQueueConfirmedAbsent, f as isRealD1Id, g as provisionEnv, h as provisionCloudflareResources, i as assertValidResourceName, l as isAlreadyGoneKillError, m as normalizeRunWranglerResult, n as acquireProvisionLock, o as createDefaultRunWrangler, p as isRealKvId, r as assertNoTransportRedirectInProjectDotenv, s as deleteEnvVarCaseAware, t as WranglerQuarantineError, u as isQuarantineError, v as resolveProperLockfileKey } from "./provision-CJFgTZY8.mjs";
2
+ import { _ as resolvePinnedApiBaseUrl, a as checkCloudflareProvisionDrift, c as enableD1ReadReplicationViaApi, d as isQueueConfirmedAbsent, f as isRealD1Id, g as provisionEnv, h as provisionCloudflareResources, i as assertValidResourceName, l as isAlreadyGoneKillError, m as normalizeRunWranglerResult, n as acquireProvisionLock, o as createDefaultRunWrangler, p as isRealKvId, r as assertNoTransportRedirectInProjectDotenv, s as deleteEnvVarCaseAware, t as WranglerQuarantineError, u as isQuarantineError, v as resolveProperLockfileKey } from "./provision-Btj1jppf.mjs";
3
3
  export { WranglerQuarantineError, acquireProvisionLock, assertNoTransportRedirectInProjectDotenv, assertValidResourceName, checkCloudflareProvisionDrift, createDefaultRunWrangler, deleteEnvVarCaseAware, enableD1ReadReplicationViaApi, isAlreadyGoneKillError, isQuarantineError, isQueueConfirmedAbsent, isRealD1Id, isRealKvId, normalizeRunWranglerResult, provisionCloudflareResources, provisionEnv, resolvePinnedApiBaseUrl, resolveProperLockfileKey, scanWranglerDotenvKeys };
@@ -1,15 +1,16 @@
1
1
  import { a as join, n as dirname, o as normalize, t as basename, u as resolve$2 } from "./dist-BVqXeR_h.mjs";
2
+ import { i as voidWarn, r as voidLog } from "./log-vqY3pqwI.mjs";
2
3
  import { i as persistCloudflareConfig } from "./cloudflare-config-Bktvwtpf.mjs";
3
- import { A as writeProvisionedWranglerConfig, s as assertNoDuplicateMembers, v as readProvisionedBindingEntry } from "./wrangler-7K-bW_DL.mjs";
4
- import { i as voidWarn, r as voidLog } from "./log-ChfPKsVd.mjs";
4
+ import { A as writeProvisionedWranglerConfig, s as assertNoDuplicateMembers, v as readProvisionedBindingEntry } from "./wrangler-DhUerFkW.mjs";
5
5
  import { r as scanWranglerDotenvKeys } from "./dotenv-VQxupEUv.mjs";
6
6
  import { c as resolveCloudflareOperationArgv, n as decodeCloudflareOperationResult, r as encodeCloudflareOperation } from "./cloudflare-process-B-wekeR6.mjs";
7
7
  import { createRequire } from "node:module";
8
8
  import { closeSync, existsSync, fsyncSync, lstatSync, openSync, readFileSync, readlinkSync, realpathSync, renameSync, unlinkSync, writeSync } from "node:fs";
9
+ import { isRecord } from "@void/deploy-core";
9
10
  import { randomUUID } from "node:crypto";
10
- import { spawn } from "node:child_process";
11
11
  import { parse } from "jsonc-parser";
12
12
  import { types } from "node:util";
13
+ import { spawn } from "node:child_process";
13
14
  import { resolve } from "node:path/posix";
14
15
  import { resolve as resolve$1 } from "node:path/win32";
15
16
  import lockfile from "proper-lockfile";
@@ -1430,9 +1431,6 @@ function parseJsonArrayStrict(value) {
1430
1431
  function parseJsonObject(value) {
1431
1432
  return isRecord(value) ? value : void 0;
1432
1433
  }
1433
- function isRecord(value) {
1434
- return typeof value === "object" && value !== null && !Array.isArray(value);
1435
- }
1436
1434
  /**
1437
1435
  * Read the single provisioned binding entry for `field`/`binding` from the resolved
1438
1436
  * config, delegating to the STRICT canonical reader in `wrangler.ts`
@@ -1533,7 +1531,7 @@ function reconcileD1IdAliases(entry) {
1533
1531
  * exact-match rule so no sibling gap remains.
1534
1532
  */
1535
1533
  function normalizeD1(entry, requestedName) {
1536
- if (!isRecord(entry)) return { kind: "other" };
1534
+ if (entry === void 0) return { kind: "other" };
1537
1535
  const names = [entry.name, entry.database_name].filter((value) => typeof value === "string" && value.length > 0);
1538
1536
  if (!names.includes(requestedName)) return { kind: "other" };
1539
1537
  if (new Set(names).size > 1) return { kind: "claimed-but-invalid" };
@@ -1,12 +1,11 @@
1
- import { c as getToken } from "./auth-CSkdO2Bb.mjs";
2
- import { o as readProjectConfig } from "./project-C0Fqu05O.mjs";
3
- import { O as intro, P as outro, j as log } from "./dist-CTBk70IR.mjs";
4
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
5
- import { a as dim, c as import_picocolors, r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { H as outro, L as log } from "./prompts-6OSVA7DJ.mjs";
4
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
5
+ import { c as import_picocolors, i as dim } from "./output-BBsUwdyT.mjs";
6
6
  //#region src/cli/requests.ts
7
7
  async function runRequestsCommand(root, range, status) {
8
8
  console.log();
9
- intro(cliTitle("project requests"));
10
9
  const token = getToken(root);
11
10
  if (!token) {
12
11
  log.error("Not logged in. Run `void account login` first.");
@@ -1,12 +1,11 @@
1
- import { c as getToken } from "./auth-CSkdO2Bb.mjs";
2
- import { i as readDeploymentPlatform, o as readProjectConfig } from "./project-C0Fqu05O.mjs";
3
- import { E as confirm, I as select, O as intro, P as outro, T as cancel, W as isCancel, j as log } from "./dist-CTBk70IR.mjs";
4
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
5
- import { a as dim, c as import_picocolors, i as createSpinner, o as ensureUtc, r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { A as confirm, H as outro, K as select, L as log, O as cancel, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
4
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
5
+ import { a as ensureUtc, c as import_picocolors, i as dim, o as formatCount, r as createSpinner } from "./output-BBsUwdyT.mjs";
6
6
  //#region src/cli/rollback.ts
7
7
  async function runRollbackCommand(root, deployId) {
8
8
  console.log();
9
- intro(cliTitle("project rollback"));
10
9
  const platform = readDeploymentPlatform(root);
11
10
  if (platform === "cloudflare") return runCloudflareRollback(root, deployId);
12
11
  if (platform === "none") throw new Error("rollback: Deployment is disabled. Run `void init` to choose a platform.");
@@ -56,7 +55,7 @@ async function runRollbackCommand(root, deployId) {
56
55
  const targetMigrations = target.applied_migrations ? JSON.parse(target.applied_migrations) : [];
57
56
  const migrationDiff = currentMigrations.filter((m) => !targetMigrations.includes(m));
58
57
  if (migrationDiff.length > 0) {
59
- log.warn(`The current database has ${migrationDiff.length} migration(s) applied after this deployment:`);
58
+ log.warn(`The current database has ${formatCount(migrationDiff.length, "migration")} applied after this deployment:`);
60
59
  for (const m of migrationDiff) log.message(` ${dim("•")} ${m}`);
61
60
  log.message(dim("Rolling back will NOT revert these migrations. The older code will run against the current schema."));
62
61
  const proceed = await confirm({ message: "Proceed with rollback?" });
@@ -83,7 +82,7 @@ async function runRollbackCommand(root, deployId) {
83
82
  outro(dim("Traffic is now serving the rolled-back deployment."));
84
83
  }
85
84
  async function runCloudflareRollback(root, deployId) {
86
- const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-AiWashgg.mjs");
85
+ const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-BhbK6yTq.mjs");
87
86
  const context = resolveCloudflareOperationContext(root);
88
87
  const status = await readCloudflareWorkerStatus(context);
89
88
  const deployedVersionIds = new Set(status.deployedVersionIds);
@@ -109,7 +108,7 @@ async function runCloudflareRollback(root, deployId) {
109
108
  options: candidates.map((version) => ({
110
109
  value: version.id,
111
110
  label: `${version.id} ${dim(formatAge(version.createdAt))}`,
112
- hint: version.metadata ? `${version.metadata.migrations.length} migration(s)` : "migration state unknown"
111
+ hint: version.metadata ? formatCount(version.metadata.migrations.length, "migration") : "migration state unknown"
113
112
  }))
114
113
  });
115
114
  if (isCancel(result)) {
@@ -131,7 +130,7 @@ async function runCloudflareRollback(root, deployId) {
131
130
  const targetSet = new Set(target.metadata.migrations);
132
131
  const migrationDiff = current.metadata.migrations.filter((migration) => !targetSet.has(migration));
133
132
  if (migrationDiff.length > 0) {
134
- log.warn(`The current database has ${migrationDiff.length} migration(s) applied after this version:`);
133
+ log.warn(`The current database has ${formatCount(migrationDiff.length, "migration")} applied after this version:`);
135
134
  for (const migration of migrationDiff) log.message(` ${dim("•")} ${migration}`);
136
135
  log.message(dim("Rolling back will NOT revert these migrations. The older code will run against the current schema."));
137
136
  const proceed = await confirm({ message: "Proceed with rollback?" });
@@ -1,4 +1,4 @@
1
- import { t as cfAccessHeaders } from "../cf-access-DRsQRe6k.mjs";
1
+ import { t as cfAccessHeaders } from "../cf-access-TWNzXltp.mjs";
2
2
  import { a as getRawRuntimeEnv } from "../env-raw-Cx8ElDdj.mjs";
3
3
  import { a as readUsageLimit, i as limitOperation, r as limitFromResponse, t as UsageLimit } from "../limits-Cjuk2VPm.mjs";
4
4
  //#region src/runtime/ai-types.ts
@@ -27,8 +27,6 @@ const PROVIDER_KEY_MAP = {
27
27
  };
28
28
  //#endregion
29
29
  //#region src/runtime/ai.ts
30
- const PROXY_URL = "https://proxy.void.cloud/ai";
31
- const STAGING_PROXY_URL = "https://proxy.staging.void.cloud/ai";
32
30
  const VOID_FILE_MARKER = "__voidFile";
33
31
  const PROVIDER_AUTH_DEFAULTS = {
34
32
  "google-ai-studio": {
@@ -239,8 +237,8 @@ function resolveProviderKey(provider, runtimeEnv, options) {
239
237
  }
240
238
  function getProxyUrl(runtimeEnv) {
241
239
  const custom = runtimeEnv.__VOID_PROXY_URL;
242
- if (typeof custom === "string" && custom.length > 0) return custom + "/ai";
243
- return runtimeEnv.__VOID_STAGING ? STAGING_PROXY_URL : PROXY_URL;
240
+ if (typeof custom === "string" && custom.length > 0) return custom.replace(/\/+$/, "") + "/ai";
241
+ throw new Error("ai: No connected platform proxy is available. Run `void connect <url>` first.");
244
242
  }
245
243
  function providerAuthDefaults(provider) {
246
244
  return PROVIDER_AUTH_DEFAULTS[provider] ?? {
@@ -1,7 +1,7 @@
1
1
  import { i as normalizeEmail, r as buildMime } from "../../mime-D5Nmdzf7.mjs";
2
2
  import { n as compileEmailPattern, t as compareEmailRoutes } from "../../email--tEtMoj_.mjs";
3
- import { y as registerEmailSink } from "../../dev-inbox-P0u4tM8Y.mjs";
4
- import { i as createMessageProxy, n as MAX_INBOUND_HEADERS, t as MAX_INBOUND_BYTES } from "../../inbound-aVHEUhKo.mjs";
3
+ import { y as registerEmailSink } from "../../dev-inbox-D64ZKUod.mjs";
4
+ import { i as createMessageProxy, n as MAX_INBOUND_HEADERS, t as MAX_INBOUND_BYTES } from "../../inbound-fRkqcXaC.mjs";
5
5
  //#region src/runtime/email/testing.ts
6
6
  /**
7
7
  * Test harnesses for void/email.
@@ -1,7 +1,8 @@
1
1
  import { i as normalizeEmail, n as MimeError, r as buildMime } from "../mime-D5Nmdzf7.mjs";
2
- import { a as DEV_INBOX_ENV_VAR, b as serializeCapturedMessage, c as DEV_INBOX_TOKEN_ENV_VAR, d as captureMessage, h as hasActiveSink, i as DEV_INBOX_CAPTURE_URL, p as dispatchToSinks } from "../dev-inbox-P0u4tM8Y.mjs";
2
+ import { a as DEV_INBOX_ENV_VAR, b as serializeCapturedMessage, c as DEV_INBOX_TOKEN_ENV_VAR, d as captureMessage, h as hasActiveSink, i as DEV_INBOX_CAPTURE_URL, p as dispatchToSinks } from "../dev-inbox-D64ZKUod.mjs";
3
3
  import { a as getRawRuntimeEnv } from "../env-raw-Cx8ElDdj.mjs";
4
- import { a as defineEmail, c as parseEmail, i as createMessageProxy, l as replyEmail, o as enactEmailActions, r as ParseEmailError, s as isForwardableEmailMessage } from "../inbound-aVHEUhKo.mjs";
4
+ import { a as defineEmail, c as parseEmail, i as createMessageProxy, l as replyEmail, o as enactEmailActions, r as ParseEmailError, s as isForwardableEmailMessage } from "../inbound-fRkqcXaC.mjs";
5
+ import { isRecord } from "@void/deploy-core";
5
6
  //#region src/runtime/email.ts
6
7
  const VALID_SLUG = /^[a-z0-9](?:[a-z0-9-]{0,54}[a-z0-9])?$/;
7
8
  function makeError(code, message, cause) {
@@ -232,7 +233,7 @@ function coerceErrorCode(code) {
232
233
  "IDEMPOTENCY_CONFLICT",
233
234
  "OUTCOME_UNKNOWN",
234
235
  "UPSTREAM_ERROR"
235
- ].includes(code) ? code : "UPSTREAM_ERROR";
236
+ ].find((knownCode) => knownCode === code) ?? "UPSTREAM_ERROR";
236
237
  }
237
238
  /**
238
239
  * The text of a refusal the proxy's middleware sent instead of a send
@@ -247,13 +248,30 @@ function readProxyRefusal(body) {
247
248
  if (typeof error !== "string" || error === "") return null;
248
249
  return typeof message === "string" && message !== "" ? message : error;
249
250
  }
250
- function isValidProxyResponse(b) {
251
- if (typeof b !== "object" || b === null) return false;
252
- const r = b;
253
- if (r.ok === true && Array.isArray(r.ids)) return true;
254
- if (r.ok === false && typeof r.error === "object" && r.error !== null) return true;
255
- if (r.ok === false && Array.isArray(r.deliveries)) return true;
256
- return false;
251
+ function readProxyResponse(value) {
252
+ if (!isRecord(value)) return null;
253
+ const operationId = value.operationId;
254
+ if (value.ok === true && Array.isArray(value.ids)) return {
255
+ ok: true,
256
+ ids: value.ids,
257
+ operationId
258
+ };
259
+ if (value.ok !== false) return null;
260
+ if (Array.isArray(value.deliveries)) return {
261
+ ok: false,
262
+ deliveries: value.deliveries,
263
+ operationId
264
+ };
265
+ const error = value.error;
266
+ if (typeof error === "object" && error !== null) return {
267
+ ok: false,
268
+ error: {
269
+ code: "code" in error ? error.code : void 0,
270
+ message: "message" in error ? error.message : void 0
271
+ },
272
+ operationId
273
+ };
274
+ return null;
257
275
  }
258
276
  /**
259
277
  * Require exactly one valid outcome per requested recipient in either list
@@ -410,31 +428,31 @@ async function readResponseAsResult(res, recipients, fallbackId, beforeDeadline)
410
428
  } catch {
411
429
  return err("OUTCOME_UNKNOWN", `email: could not establish the send outcome (status ${res.status}); check email logs or repeat the same idempotency key`);
412
430
  }
413
- if (!isValidProxyResponse(body)) {
431
+ const response = readProxyResponse(body);
432
+ if (response === null) {
414
433
  const refusal = readProxyRefusal(body);
415
434
  if (!res.ok && refusal !== null) return err("UPSTREAM_ERROR", `email: proxy returned ${res.status}: ${refusal}`, body);
416
435
  return err("OUTCOME_UNKNOWN", `email: proxy returned malformed response (status ${res.status})`, body);
417
436
  }
418
437
  const malformedList = (reason) => err("OUTCOME_UNKNOWN", `email: proxy returned a malformed delivery list (${reason}); do not retry with a new idempotency key`, body);
419
- const operation = typeof body.operationId === "string" && body.operationId.length <= 128 ? { operationId: body.operationId } : {};
420
- if (body.ok === true) {
421
- const list = readDeliveryList(body.ids, recipients, fallbackId);
438
+ const operation = typeof response.operationId === "string" && response.operationId.length <= 128 ? { operationId: response.operationId } : {};
439
+ if (response.ok === true) {
440
+ const list = readDeliveryList(response.ids, recipients, fallbackId);
422
441
  return list.ok ? {
423
442
  ok: true,
424
443
  ids: list.entries,
425
444
  ...operation
426
445
  } : malformedList(list.reason);
427
446
  }
428
- const failure = body;
429
- if (Array.isArray(failure.deliveries)) {
430
- const list = readFailureDeliveries(failure.deliveries, recipients, fallbackId);
447
+ if ("deliveries" in response) {
448
+ const list = readFailureDeliveries(response.deliveries, recipients, fallbackId);
431
449
  return list.ok ? {
432
450
  ok: false,
433
451
  deliveries: list.entries,
434
452
  ...operation
435
453
  } : malformedList(list.reason);
436
454
  }
437
- const e = failure.error;
455
+ const e = response.error;
438
456
  return {
439
457
  ...err(coerceErrorCode(e.code), typeof e.message === "string" ? e.message : "email: upstream send failed"),
440
458
  ...operation
@@ -1,4 +1,4 @@
1
- import { t as cfAccessHeaders } from "../../cf-access-DRsQRe6k.mjs";
1
+ import { t as cfAccessHeaders } from "../../cf-access-TWNzXltp.mjs";
2
2
  import { n as serializeR2Conditional } from "../../r2-conditions-D1Wk8i7b.mjs";
3
3
  //#region src/runtime/remote/client.ts
4
4
  function readableMessage(value) {
@@ -49,7 +49,7 @@ async function proxyError(response) {
49
49
  return /* @__PURE__ */ new Error(`remote: Proxy request failed with ${response.status}: ${message}`);
50
50
  }
51
51
  /**
52
- * HTTP client for the remote bindings proxy (proxy.void.cloud).
52
+ * HTTP client for the connected platform's remote bindings proxy.
53
53
  *
54
54
  * Used by ProxyD1Database, ProxyKVNamespace, and ProxyR2Bucket to forward
55
55
  * binding operations to the platform proxy during local development.
@@ -1,8 +1,8 @@
1
1
  import { t as convertReturnValue } from "../response-Tn7rU0MV.mjs";
2
2
  import { t as VoidAssetRewriteError } from "../handler-DghKr6dU.mjs";
3
3
  import { n as handlePageGet, r as handlePageMutation } from "../protocol-U7bfjHmA.mjs";
4
- import { compilePattern, mergeQueryIntoLocation, substituteParams } from "@void/edge";
5
4
  import { AsyncLocalStorage } from "node:async_hooks";
5
+ import { compilePattern, mergeQueryIntoLocation, substituteParams } from "@void/edge";
6
6
  //#region src/runtime/routing-errors.ts
7
7
  const __VOID_ERROR_PAGE_FONT_STACK = "system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif";
8
8
  const errorStack = Error;
@@ -1,15 +1,14 @@
1
- import { c as getToken } from "./auth-CSkdO2Bb.mjs";
2
- import { i as readDeploymentPlatform, o as readProjectConfig } from "./project-C0Fqu05O.mjs";
3
- import { _ as validateSecretValues } from "./env-validation-BPn7vk-V.mjs";
4
- import { E as confirm, F as password, N as note, O as intro, P as outro, T as cancel, W as isCancel, j as log } from "./dist-CTBk70IR.mjs";
5
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
6
- import { r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { _ as validateSecretValues } from "./env-validation-vBSQ8gw5.mjs";
4
+ import { A as confirm, B as note, H as outro, L as log, O as cancel, U as password, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
5
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
6
+ import { o as formatCount } from "./output-BBsUwdyT.mjs";
7
7
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-BG5ORGID.mjs";
8
8
  import { readFileSync } from "node:fs";
9
9
  //#region src/cli/secret.ts
10
10
  async function runSecretCommand(root, args) {
11
11
  console.log();
12
- intro(cliTitle("secret"));
13
12
  const platform = readDeploymentPlatform(root);
14
13
  if (platform === "cloudflare") return runCloudflareSecretCommand(root, args);
15
14
  if (platform === "none") throw new Error("secret: Deployment is disabled. Run `void init` to choose a platform.");
@@ -38,7 +37,7 @@ async function runSecretCommand(root, args) {
38
37
  return;
39
38
  }
40
39
  note(secrets.map((s) => ` ${s.name}`).join("\n"), "Secrets");
41
- outro(`${secrets.length} secret(s)`);
40
+ outro(formatCount(secrets.length, "secret"));
42
41
  return;
43
42
  }
44
43
  if (args.action === "put") {
@@ -59,9 +58,9 @@ async function runSecretCommand(root, args) {
59
58
  return;
60
59
  }
61
60
  await validateSecretValues(root, secrets);
62
- log.info(`Found ${secrets.length} secret(s):`);
61
+ log.info(`Found ${formatCount(secrets.length, "secret")}:`);
63
62
  for (const s of secrets) log.message(` ${s.name}`);
64
- const proceed = await confirm({ message: `This will overwrite ${secrets.length} secret(s) in the remote environment. Continue?` });
63
+ const proceed = await confirm({ message: `This will overwrite ${formatCount(secrets.length, "secret")} in the remote environment. Continue?` });
65
64
  if (isCancel(proceed) || !proceed) {
66
65
  cancel("Secret sync cancelled.");
67
66
  process.exit(0);
@@ -70,7 +69,7 @@ async function runSecretCommand(root, args) {
70
69
  await client.setSecret(projectId, s.name, s.value);
71
70
  log.success(`Set ${s.name}`);
72
71
  }
73
- outro(`Synced ${secrets.length} secret(s).`);
72
+ outro(`Synced ${formatCount(secrets.length, "secret")}.`);
74
73
  return;
75
74
  }
76
75
  await client.deleteSecret(projectId, args.name);
@@ -78,7 +77,7 @@ async function runSecretCommand(root, args) {
78
77
  }
79
78
  async function runCloudflareSecretCommand(root, args) {
80
79
  if (args.projectName) throw new Error("secret: --project selects a Void platform project and is not used for direct Cloudflare apps.");
81
- const { deleteCloudflareSecret, listCloudflareSecrets, putCloudflareSecret, resolveCloudflareOperationContext, syncCloudflareSecrets } = await import("./cloudflare-operations-AiWashgg.mjs");
80
+ const { deleteCloudflareSecret, listCloudflareSecrets, putCloudflareSecret, resolveCloudflareOperationContext, syncCloudflareSecrets } = await import("./cloudflare-operations-BhbK6yTq.mjs");
82
81
  const context = resolveCloudflareOperationContext(root);
83
82
  if (args.action === "list") {
84
83
  const secrets = await listCloudflareSecrets(context);
@@ -87,7 +86,7 @@ async function runCloudflareSecretCommand(root, args) {
87
86
  return;
88
87
  }
89
88
  note(secrets.map((name) => ` ${name}`).join("\n"), "Secrets");
90
- outro(`${secrets.length} secret(s)`);
89
+ outro(formatCount(secrets.length, "secret"));
91
90
  return;
92
91
  }
93
92
  if (args.action === "put") {
@@ -108,15 +107,15 @@ async function runCloudflareSecretCommand(root, args) {
108
107
  return;
109
108
  }
110
109
  await validateSecretValues(root, secrets);
111
- log.info(`Found ${secrets.length} secret(s):`);
110
+ log.info(`Found ${formatCount(secrets.length, "secret")}:`);
112
111
  for (const secret of secrets) log.message(` ${secret.name}`);
113
- const proceed = await confirm({ message: `This will overwrite ${secrets.length} secret(s) in the Cloudflare Worker. Continue?` });
112
+ const proceed = await confirm({ message: `This will overwrite ${formatCount(secrets.length, "secret")} in the Cloudflare Worker. Continue?` });
114
113
  if (isCancel(proceed) || !proceed) {
115
114
  cancel("Secret sync cancelled.");
116
115
  process.exit(0);
117
116
  }
118
117
  await syncCloudflareSecrets(context, secrets);
119
- outro(`Synced ${secrets.length} secret(s).`);
118
+ outro(`Synced ${formatCount(secrets.length, "secret")}.`);
120
119
  return;
121
120
  }
122
121
  await deleteCloudflareSecret(context, args.name);
@@ -1,5 +1,5 @@
1
1
  import { a as join, l as relative } from "./dist-BVqXeR_h.mjs";
2
- import { j as log } from "./dist-CTBk70IR.mjs";
2
+ import { L as log } from "./prompts-6OSVA7DJ.mjs";
3
3
  import { n as getPackageDir } from "./agents-B_pX_HmQ.mjs";
4
4
  import { existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, symlinkSync } from "node:fs";
5
5
  //#region src/cli/skills.ts
@@ -1,5 +1,5 @@
1
- import { S as S_STEP_SUBMIT, _ as S_RADIO_ACTIVE, c as S_CHECKBOX_INACTIVE, i as S_BAR_END, q as wrapAnsi, r as S_BAR, s as S_CHECKBOX_ACTIVE, v as S_RADIO_INACTIVE, y as S_STEP_ACTIVE } from "./dist-CTBk70IR.mjs";
2
- import { c as import_picocolors } from "./output-Dm_A4Tbv.mjs";
1
+ import { $ as wrapTextWithPrefix, G as promptTitle, M as getGuide, V as optionText, b as S_RADIO_ACTIVE, d as S_CHECKBOX_SELECTED, i as S_BAR_END, it as wrapAnsi, j as formatInstructionFooter, n as SELECT_INSTRUCTIONS, r as S_BAR, t as MULTISELECT_INSTRUCTIONS, u as S_CHECKBOX_INACTIVE, w as S_STEP_SUBMIT } from "./prompts-6OSVA7DJ.mjs";
2
+ import { c as import_picocolors } from "./output-BBsUwdyT.mjs";
3
3
  //#region src/cli/subcommand-prompt.ts
4
4
  function promptSubcommand(command, subcommands) {
5
5
  return new Promise((resolve) => {
@@ -45,16 +45,25 @@ function promptSubcommand(command, subcommands) {
45
45
  }
46
46
  return `${lines[0]}…`;
47
47
  }
48
+ function guidePrefix() {
49
+ return getGuide() ? import_picocolors.default.gray(S_BAR) + " " : " ";
50
+ }
51
+ function renderOption(marker, label, focused, suffix = "") {
52
+ return guidePrefix() + optionText(stdout, marker + " ", label, focused ? (value) => import_picocolors.default.blue(import_picocolors.default.bold(value)) : import_picocolors.default.dim, suffix);
53
+ }
54
+ function instructions(items) {
55
+ return formatInstructionFooter(items, getGuide(), stdout);
56
+ }
48
57
  function writeFrame(header, options, footer) {
49
- const count = Math.max(1, Math.min(7, (stdout.rows || 24) - footer.length - 5));
58
+ const heading = header.trimEnd().split("\n");
59
+ const end = getGuide() ? [import_picocolors.default.gray(S_BAR_END)] : [];
60
+ const count = Math.max(1, Math.min(7, (stdout.rows || 24) - heading.length - footer.length - end.length - 1));
50
61
  const start = Math.max(0, Math.min(cursor - Math.floor(count / 2), options.length - count));
51
62
  previousFrame = [
52
- truncate(header),
53
- import_picocolors.default.gray(S_BAR),
63
+ ...heading.map((line) => truncate(line)),
54
64
  ...options.slice(start, start + count).map((option) => truncate(option)),
55
- import_picocolors.default.gray(S_BAR),
56
65
  ...footer.map((line) => truncate(line)),
57
- import_picocolors.default.gray(S_BAR_END)
66
+ ...end
58
67
  ].join("\n");
59
68
  stdout.write(previousFrame + "\n");
60
69
  }
@@ -69,7 +78,7 @@ function promptSubcommand(command, subcommands) {
69
78
  const title = command ? `void ${command}` : "void";
70
79
  function headerLine() {
71
80
  const argPart = selectedArg ? ` ${selectedArg}` : "";
72
- return `${import_picocolors.default.cyan(S_STEP_ACTIVE)} ${import_picocolors.default.cyan(title)} ${import_picocolors.default.dim("·")} ${import_picocolors.default.cyan(`${selectedSub.name}${argPart}`)}`;
81
+ return promptTitle(`${import_picocolors.default.blue(title)} ${import_picocolors.default.dim("·")} ${selectedSub.name}${argPart}`, "active", { output: stdout });
73
82
  }
74
83
  function renderSelect() {
75
84
  const lines = [];
@@ -78,22 +87,21 @@ function promptSubcommand(command, subcommands) {
78
87
  for (let i = 0; i < subcommands.length; i++) {
79
88
  const sub = subcommands[i];
80
89
  const isFocused = i === cursor;
81
- const radio = isFocused ? import_picocolors.default.green(S_RADIO_ACTIVE) : import_picocolors.default.dim(S_RADIO_INACTIVE);
90
+ const radio = isFocused ? import_picocolors.default.blue(S_RADIO_ACTIVE) : import_picocolors.default.dim(" ");
82
91
  const name = sub.name.padEnd(maxName);
83
92
  let suffix = "";
84
- if (sub.arg) {
85
- if (isFocused && input.length > 0) suffix = ` ${import_picocolors.default.cyan(truncate(input, (stdout.columns || 80) - maxName - 9, true))}`;
93
+ if (isFocused && sub.arg) {
94
+ if (isFocused && input.length > 0) suffix = ` ${import_picocolors.default.blue(truncate(input, (stdout.columns || 80) - maxName - 9, true))}`;
86
95
  else suffix = ` ${import_picocolors.default.dim(sub.arg)}`;
87
- } else if (sub.hint) suffix = ` ${import_picocolors.default.dim(sub.hint)}`;
88
- if (isFocused) lines.push(`${import_picocolors.default.gray(S_BAR)} ${radio} ${import_picocolors.default.reset(name)}${suffix}`);
89
- else lines.push(`${import_picocolors.default.gray(S_BAR)} ${radio} ${import_picocolors.default.dim(name)}${suffix}`);
96
+ } else if (isFocused && sub.hint) suffix = ` ${import_picocolors.default.dim(sub.hint)}`;
97
+ lines.push(renderOption(radio, name, isFocused, suffix));
90
98
  }
91
- const footer = [`${import_picocolors.default.gray(S_BAR)} ${import_picocolors.default.dim(focused.description)}`];
99
+ const footer = [guidePrefix() + import_picocolors.default.dim(focused.description), ...instructions(SELECT_INSTRUCTIONS)];
92
100
  if (focused.arg) {
93
- if (focused.arg.startsWith("<")) footer.push(`${import_picocolors.default.gray(S_BAR)} ${import_picocolors.default.dim(`Type ${focused.arg}, then press Enter`)}`);
94
- else footer.push(`${import_picocolors.default.gray(S_BAR)} ${import_picocolors.default.dim(`Type ${focused.arg}, then press Enter, or press Enter to skip`)}`);
101
+ if (focused.arg.startsWith("<")) footer.push(`${guidePrefix()}${import_picocolors.default.dim(`Type ${focused.arg}, then press Enter`)}`);
102
+ else footer.push(`${guidePrefix()}${import_picocolors.default.dim(`Type ${focused.arg}, then press Enter, or press Enter to skip`)}`);
95
103
  }
96
- writeFrame(`${import_picocolors.default.cyan(S_STEP_ACTIVE)} ${import_picocolors.default.cyan(title)}`, lines, footer);
104
+ writeFrame(promptTitle(import_picocolors.default.blue(title), "active", { output: stdout }), lines, footer);
97
105
  }
98
106
  function renderFlags() {
99
107
  const flags = selectedSub.flags;
@@ -104,19 +112,19 @@ function promptSubcommand(command, subcommands) {
104
112
  const flag = flags[i];
105
113
  const state = flagStates[i];
106
114
  const isFocused = i === cursor;
107
- const checkbox = state.enabled ? import_picocolors.default.green(S_CHECKBOX_ACTIVE) : isFocused ? S_CHECKBOX_INACTIVE : import_picocolors.default.dim(S_CHECKBOX_INACTIVE);
115
+ const checkbox = state.enabled ? import_picocolors.default.blue(S_CHECKBOX_SELECTED) : isFocused ? import_picocolors.default.blue(S_CHECKBOX_INACTIVE) : import_picocolors.default.dim(S_CHECKBOX_INACTIVE);
108
116
  const name = flag.name.padEnd(maxFlag);
109
117
  let valueText = "";
110
118
  if (flag.arg) {
111
119
  if (state.enabled && state.value.length > 0) {
112
120
  const value = truncate(state.value, (stdout.columns || 80) - maxFlag - 9, true);
113
- valueText = ` ${isFocused ? import_picocolors.default.cyan(value) : import_picocolors.default.dim(value)}`;
121
+ valueText = ` ${isFocused ? import_picocolors.default.blue(value) : import_picocolors.default.dim(value)}`;
114
122
  } else valueText = ` ${import_picocolors.default.dim(flag.arg)}`;
115
123
  }
116
- if (isFocused) lines.push(`${import_picocolors.default.gray(S_BAR)} ${checkbox} ${import_picocolors.default.reset(name)}${valueText}`);
117
- else lines.push(`${import_picocolors.default.gray(S_BAR)} ${checkbox} ${import_picocolors.default.dim(name)}${valueText}`);
124
+ const pointer = isFocused ? import_picocolors.default.blue(S_RADIO_ACTIVE) : " ";
125
+ lines.push(renderOption(pointer + " " + checkbox, name, isFocused, valueText));
118
126
  }
119
- writeFrame(headerLine(), lines, [`${import_picocolors.default.gray(S_BAR)} ${import_picocolors.default.dim(focused.description)}`]);
127
+ writeFrame(headerLine(), lines, [guidePrefix() + import_picocolors.default.dim(focused.description), ...instructions(MULTISELECT_INSTRUCTIONS)]);
120
128
  }
121
129
  function renderMultiSelect() {
122
130
  const options = selectedSub.followUp.options;
@@ -126,21 +134,21 @@ function promptSubcommand(command, subcommands) {
126
134
  const opt = options[i];
127
135
  const selected = multiSelectStates[i];
128
136
  const isFocused = i === cursor;
129
- const checkbox = selected ? import_picocolors.default.green(S_CHECKBOX_ACTIVE) : isFocused ? S_CHECKBOX_INACTIVE : import_picocolors.default.dim(S_CHECKBOX_INACTIVE);
137
+ const checkbox = selected ? import_picocolors.default.blue(S_CHECKBOX_SELECTED) : isFocused ? import_picocolors.default.blue(S_CHECKBOX_INACTIVE) : import_picocolors.default.dim(S_CHECKBOX_INACTIVE);
130
138
  const label = opt.label.padEnd(maxLabel);
131
- if (isFocused) lines.push(`${import_picocolors.default.gray(S_BAR)} ${checkbox} ${import_picocolors.default.reset(label)}`);
132
- else lines.push(`${import_picocolors.default.gray(S_BAR)} ${checkbox} ${import_picocolors.default.dim(label)}`);
139
+ const pointer = isFocused ? import_picocolors.default.blue(S_RADIO_ACTIVE) : " ";
140
+ lines.push(renderOption(pointer + " " + checkbox, label, isFocused));
133
141
  }
134
- writeFrame(headerLine(), lines, [`${import_picocolors.default.gray(S_BAR)} ${import_picocolors.default.dim("space to toggle, enter to confirm")}`]);
142
+ writeFrame(headerLine(), lines, instructions(MULTISELECT_INSTRUCTIONS));
135
143
  }
136
144
  function renderRepeatInput() {
137
145
  const followUp = selectedSub.followUp;
138
146
  const lines = [];
139
- for (const entry of repeatEntries) lines.push(`${import_picocolors.default.gray(S_BAR)} ${import_picocolors.default.dim(entry)}`);
140
- if (repeatInput.length > 0) lines.push(`${import_picocolors.default.gray(S_BAR)} ${import_picocolors.default.cyan(truncate(repeatInput, (stdout.columns || 80) - 4, true))}`);
141
- else lines.push(`${import_picocolors.default.gray(S_BAR)} ${import_picocolors.default.dim(followUp.placeholder)}`);
147
+ for (const entry of repeatEntries) lines.push(`${guidePrefix()}${import_picocolors.default.dim(entry)}`);
148
+ if (repeatInput.length > 0) lines.push(`${guidePrefix()}${import_picocolors.default.blue(truncate(repeatInput, (stdout.columns || 80) - 4, true))}`);
149
+ else lines.push(`${guidePrefix()}${import_picocolors.default.dim(followUp.placeholder)}`);
142
150
  cursor = lines.length - 1;
143
- writeFrame(headerLine(), lines, [`${import_picocolors.default.gray(S_BAR)} ${import_picocolors.default.dim("enter to add, empty to finish")}`]);
151
+ writeFrame(headerLine(), lines, instructions(["Enter add", "Empty input finish"]));
144
152
  }
145
153
  function cleanup() {
146
154
  if (resolved) return;
@@ -163,7 +171,7 @@ function promptSubcommand(command, subcommands) {
163
171
  if (typeof value === "string") summary += ` ${value}`;
164
172
  }
165
173
  if (result.extraArgs && result.extraArgs.length > 0) summary += ` ${result.extraArgs.join(" ")}`;
166
- stdout.write(`${import_picocolors.default.gray(S_STEP_SUBMIT)} ${import_picocolors.default.dim(title)} ${import_picocolors.default.dim("·")} ${import_picocolors.default.dim(summary)}\n`);
174
+ stdout.write(wrapTextWithPrefix(stdout, `${import_picocolors.default.dim(title)} ${import_picocolors.default.dim("·")} ${import_picocolors.default.dim(summary)}`, " ", `${import_picocolors.default.gray(S_STEP_SUBMIT)} `) + "\n");
167
175
  }
168
176
  resolve(result);
169
177
  }
@@ -4,7 +4,7 @@ type TsconfigHook = (config: Tsconfig) => Tsconfig | void;
4
4
  export type VoidSvelteKitTsconfigOptions = {
5
5
  /** Project root. Defaults to process.cwd(). */
6
6
  root?: string;
7
- /** SvelteKit output directory. Defaults to ".svelte-kit". */
7
+ /** @deprecated Generated paths no longer depend on SvelteKit's output directory. */
8
8
  outDir?: string;
9
9
  };
10
10
  /**
@@ -1,4 +1,4 @@
1
- import { a as join, i as isAbsolute, l as relative, u as resolve } from "./dist-BVqXeR_h.mjs";
1
+ import { a as join, i as isAbsolute, u as resolve } from "./dist-BVqXeR_h.mjs";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  //#region src/sveltekit.ts
4
4
  /**
@@ -7,18 +7,17 @@ import { existsSync, readFileSync } from "node:fs";
7
7
  * `kit.typescript.config` in `svelte.config.js`.
8
8
  */
9
9
  function mergeVoidSvelteKitTsconfig(config, options = {}) {
10
- const root = options.root ?? process.cwd();
10
+ const root = resolve(options.root ?? process.cwd());
11
11
  const voidDir = join(root, ".void");
12
12
  const voidTsconfigPath = join(voidDir, "tsconfig.json");
13
13
  if (!existsSync(voidTsconfigPath)) return config;
14
14
  const voidConfig = JSON.parse(readFileSync(voidTsconfigPath, "utf-8"));
15
- const outputDir = resolve(root, options.outDir ?? ".svelte-kit");
16
15
  const voidFiles = Array.isArray(voidConfig.files) ? voidConfig.files.filter((entry) => typeof entry === "string") : [];
17
- if (voidFiles.length > 0) config.files = uniqueStrings([...Array.isArray(config.files) ? config.files.filter((entry) => typeof entry === "string") : [], ...voidFiles.map((entry) => relativeFrom(outputDir, resolveTsconfigEntry(voidDir, entry)))]);
16
+ if (voidFiles.length > 0) config.files = uniqueStrings([...Array.isArray(config.files) ? config.files.filter((entry) => typeof entry === "string") : [], ...voidFiles.map((entry) => resolveTsconfigEntry(voidDir, entry))]);
18
17
  const voidPaths = readPathMap(readObject(readObject(voidConfig.compilerOptions)?.paths));
19
18
  if (Object.keys(voidPaths).length > 0) {
20
19
  const paths = ensureObject(ensureObject(config, "compilerOptions"), "paths");
21
- for (const [key, values] of Object.entries(voidPaths)) paths[key] = values.map((entry) => relativeFrom(outputDir, resolveTsconfigEntry(voidDir, entry)));
20
+ for (const [key, values] of Object.entries(voidPaths)) paths[key] = values.map((entry) => resolveTsconfigEntry(voidDir, entry));
22
21
  }
23
22
  return config;
24
23
  }
@@ -51,10 +50,6 @@ function readPathMap(value) {
51
50
  function resolveTsconfigEntry(baseDir, entry) {
52
51
  return isAbsolute(entry) ? entry : resolve(baseDir, entry);
53
52
  }
54
- function relativeFrom(fromDir, target) {
55
- const value = relative(fromDir, target);
56
- return value.startsWith(".") ? value : `./${value}`;
57
- }
58
53
  function uniqueStrings(values) {
59
54
  return Array.from(new Set(values));
60
55
  }