@voltro/cli 0.52.0 → 0.54.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 (244) hide show
  1. package/CHANGELOG.md +424 -0
  2. package/THIRD-PARTY-NOTICES.md +8311 -3318
  3. package/dist/{agentsMd-0l980yhL.js → agentsMd-BaLC10Na.js} +110 -82
  4. package/dist/agentsMd-DCY1RSs8.js +2 -0
  5. package/dist/apiBuild-CeUN55uk.js +2 -0
  6. package/dist/{apiBuild-CSFI8QGq.js → apiBuild-DTWp0S_q.js} +11 -5
  7. package/dist/bin.js +1 -1
  8. package/dist/build-D4ygSbnV.js +843 -0
  9. package/dist/{checkCommand-COmqc2cB.js → checkCommand-Dg1G7Gwd.js} +6 -6
  10. package/dist/{checkCommand-2SbqzukH.js → checkCommand-L7DTlpIF.js} +1 -1
  11. package/dist/{cloudCmd-QUXh-b5w.js → cloudCmd-DzKcSYuy.js} +1 -1
  12. package/dist/{codegen-VF479Cnb.js → codegen-DSLM8Su9.js} +1 -1
  13. package/dist/codegen-DjgxEOnD.js +2 -0
  14. package/dist/codegenCommand-CG_Vx4lc.js +41 -0
  15. package/dist/{codemodRunner-r7J9lIa7.js → codemodRunner-Cd4xkC6u.js} +109 -11
  16. package/dist/{commands-Cc_nV8WI.js → commands-6Kzi92Np.js} +96 -73
  17. package/dist/{dashboardCommand-C-gKvwqh.js → dashboardCommand-Cq1PWvI1.js} +5 -5
  18. package/dist/{dataCommand-BgpBHnlB.js → dataCommand-DYzW8vkv.js} +3 -3
  19. package/dist/{dbCommand-sHedr-NJ.js → dbCommand-B4NWZtGL.js} +278 -237
  20. package/dist/dbCommand-CSFWs9ev.js +2 -0
  21. package/dist/{dev-CRHoCEiy.js → dev-CmuvUKRq.js} +2903 -2306
  22. package/dist/{dev--A3nsxA3.js → dev-cKUiZZsB.js} +1 -1
  23. package/dist/{doctorCommand-DtfJ3FA6.js → doctorCommand-DCiFVMtZ.js} +101 -69
  24. package/dist/doctorCommand-J3qu4E0Y.js +2 -0
  25. package/dist/{dormancyCommand-Drn7o0No.js → dormancyCommand-w1TrmgYP.js} +1 -1
  26. package/dist/{embeddingsCommand-Z-jO1fWN.js → embeddingsCommand-CMgPyRTr.js} +1 -1
  27. package/dist/{envCommand-D4gCrrTZ.js → envCommand-Cyynmcfa.js} +8 -8
  28. package/dist/{evolveCommand-CMROeKeA.js → evolveCommand-BwvQ8dVH.js} +2 -2
  29. package/dist/fileConventions-l-RIXbx8.js +36 -0
  30. package/dist/{fileTaxonomy-DvDUV9wq.js → fileTaxonomy-CbyMQYx_.js} +42 -42
  31. package/dist/fontPipeline-LxIHa1vo.js +2 -0
  32. package/dist/fontPipeline-Tsh8kZfA.js +152 -0
  33. package/dist/{frameworkTableAssembly-w-XnLa3q.js → frameworkTableAssembly-D7LJuALW.js} +5 -5
  34. package/dist/frameworkTableAssembly-IPD1pUnZ.js +2 -0
  35. package/dist/imagePipeline-B_GVJgm6.js +2 -0
  36. package/dist/imagePipeline-CBZmjT4i.js +127 -0
  37. package/dist/index.js +2 -2
  38. package/dist/{infoCommand-DXM868o_.js → infoCommand-DlYlUPqs.js} +1 -1
  39. package/dist/{inspect-CtL_xTbu.js → inspect-Bd8-9wsi.js} +1 -1
  40. package/dist/inspect-CuoDInfZ.js +2 -0
  41. package/dist/{inspectGateHint-BjnFubmH.js → inspectGateHint-4LxkNtrz.js} +1 -1
  42. package/dist/manifestBuild-C4-J1-m_.js +2 -0
  43. package/dist/{manifestBuild-CuU1VrSm.js → manifestBuild-Cqgsx2bM.js} +1 -1
  44. package/dist/{metaCommands-C6RFmF1r.js → metaCommands-x7RCi2AF.js} +9 -3
  45. package/dist/{migrate-D0F-eTlK.js → migrate-BK_Bbx-_.js} +2 -2
  46. package/dist/mobileCommand-D9O6iq3D.js +428 -0
  47. package/dist/mobileCommand-DAum7tsG.js +2 -0
  48. package/dist/{pageConvention-CzUiSbtU.js → pageConvention-CMpfDN6r.js} +1 -1
  49. package/dist/{privacyCommand-DGdopOI6.js → privacyCommand-BCa2OoZG.js} +1 -1
  50. package/dist/{probeCommand-C9gazU0H.js → probeCommand-_C0YU207.js} +83 -24
  51. package/dist/{projectScaffold-EzlErR4E.js → projectScaffold-CJfP-xbT.js} +1 -1
  52. package/dist/{projectScaffold-B4dmTlwT.js → projectScaffold-CSN0OzBV.js} +2 -2
  53. package/dist/renderModeScan-43yQ2opo.js +147 -0
  54. package/dist/{renderProfile-Ck32Fzxr.js → renderProfile-DvrhVJHa.js} +2 -2
  55. package/dist/{runtimeTrace-BPQyCmC5.js → runtimeTrace-CGWx1Q6l.js} +1 -1
  56. package/dist/{sdkgen-Se88ifTd.js → sdkgen-CDGHQUFj.js} +1 -1
  57. package/dist/serveCommand-BiPe8BJm.js +2 -0
  58. package/dist/{serveCommand-DkP3OT0W.js → serveCommand-Bje09q1v.js} +889 -825
  59. package/dist/serveEntry.js +1 -1
  60. package/dist/start-B0bnJgxI.js +3 -0
  61. package/dist/{start-jw89Xbqy.js → start-Clz-1BHB.js} +633 -455
  62. package/dist/startEntry.js +1 -1
  63. package/dist/{staticCommand-BwNEDlSU.js → staticCommand-ey0kYmOT.js} +1 -1
  64. package/dist/{subcommandNames-DpYs3DXr.js → subcommandNames-CDzfEtKV.js} +3 -3
  65. package/dist/{templates-BR-fb4SP.js → templates-BTWZkJJT.js} +41 -9
  66. package/dist/{test-f3amja6a.js → test-D_kW4KMj.js} +1 -1
  67. package/dist/updateCommand-CIoVDKnj.js +2 -0
  68. package/dist/{updateCommand-BMk2e4ky.js → updateCommand-CRJlAOaM.js} +139 -115
  69. package/dist/{webDev-BgWL9gKV.js → webDev-DSI9SOhs.js} +1598 -1028
  70. package/dist/webDev-DlvZO30c.js +2 -0
  71. package/dist/{webhooksCommand-CoIO3jbj.js → webhooksCommand-BvzXNHji.js} +1 -1
  72. package/dist/workspaceDeps-RKEkX92S.js +45 -0
  73. package/package.json +60 -19
  74. package/templates/AGENTS.core.md +2 -0
  75. package/templates/AGENTS.md +8 -4
  76. package/templates/agent-docs/_index.md +6 -4
  77. package/templates/agent-docs/_manifest.json +21 -5
  78. package/templates/agent-docs/ai.md +6 -6
  79. package/templates/agent-docs/authentication.md +73 -1
  80. package/templates/agent-docs/cli.md +6 -3
  81. package/templates/agent-docs/configuration.md +17 -0
  82. package/templates/agent-docs/data.md +522 -29
  83. package/templates/agent-docs/database/advancedqueries.md +8 -8
  84. package/templates/agent-docs/database/columntypes.md +2 -2
  85. package/templates/agent-docs/database/migrations.md +1 -1
  86. package/templates/agent-docs/database/querying.md +1 -1
  87. package/templates/agent-docs/database/schema.md +1 -1
  88. package/templates/agent-docs/database/seedsdialects.md +65 -3
  89. package/templates/agent-docs/database/transactions.md +3 -3
  90. package/templates/agent-docs/deployment.md +8 -0
  91. package/templates/agent-docs/internationalization.md +4 -2
  92. package/templates/agent-docs/introduction.md +32 -1
  93. package/templates/agent-docs/local-first-mobile.md +226 -30
  94. package/templates/agent-docs/observability.md +5 -1
  95. package/templates/agent-docs/plugins/atlassian.md +2 -2
  96. package/templates/agent-docs/plugins/audit.md +2 -2
  97. package/templates/agent-docs/plugins/auth.md +1 -1
  98. package/templates/agent-docs/plugins/billing.md +1 -1
  99. package/templates/agent-docs/plugins/cdc-out.md +8 -3
  100. package/templates/agent-docs/plugins/comments.md +164 -0
  101. package/templates/agent-docs/plugins/notifications.md +47 -4
  102. package/templates/agent-docs/plugins/presence.md +45 -3
  103. package/templates/agent-docs/plugins/prometheus.md +3 -1
  104. package/templates/agent-docs/plugins/queue.md +172 -0
  105. package/templates/agent-docs/plugins.md +17 -13
  106. package/templates/agent-docs/reference.md +35 -4
  107. package/templates/agent-docs/routing.md +585 -7
  108. package/templates/agent-docs/scheduling.md +1 -1
  109. package/templates/agent-docs/schema-driven-ui.md +226 -4
  110. package/templates/agent-docs/security.md +3 -3
  111. package/templates/agent-docs/templates/appshells.md +36 -4
  112. package/templates/agent-docs/whats-new.md +134 -66
  113. package/templates/apps/api-ai/package.json +6 -6
  114. package/templates/apps/api-auth/package.json +8 -8
  115. package/templates/apps/api-backend/package.json +7 -7
  116. package/templates/apps/api-backend-deactivation/package.json +7 -7
  117. package/templates/apps/api-backend-mail/package.json +8 -8
  118. package/templates/apps/api-backend-mariadb/package.json +9 -9
  119. package/templates/apps/api-backend-sqlite/package.json +8 -8
  120. package/templates/apps/api-backend-storage/package.json +8 -8
  121. package/templates/apps/api-cms/package.json +9 -9
  122. package/templates/apps/api-collab/README.md +3 -3
  123. package/templates/apps/api-collab/app.config.ts +1 -1
  124. package/templates/apps/api-collab/database/schema.ts +12 -8
  125. package/templates/apps/api-collab/mutations/documents.create.mutation.server.ts +1 -1
  126. package/templates/apps/api-collab/mutations/documents.setBody.mutation.server.ts +1 -1
  127. package/templates/apps/api-collab/mutations/documents.setBody.mutation.ts +1 -1
  128. package/templates/apps/api-collab/package.json +8 -8
  129. package/templates/apps/api-collab/template.json +1 -1
  130. package/templates/apps/api-collab/tests/documents.setBody.test.ts +10 -2
  131. package/templates/apps/api-data-advanced/package.json +8 -8
  132. package/templates/apps/api-durable/package.json +8 -8
  133. package/templates/apps/api-feature-flags/package.json +9 -9
  134. package/templates/apps/api-governance/package.json +8 -8
  135. package/templates/apps/api-kv/package.json +8 -8
  136. package/templates/apps/api-moderation/package.json +8 -8
  137. package/templates/apps/api-observability/package.json +8 -8
  138. package/templates/apps/api-ratelimit/package.json +8 -8
  139. package/templates/apps/api-rbac/package.json +8 -8
  140. package/templates/apps/api-rest/package.json +7 -7
  141. package/templates/apps/api-row-history/package.json +8 -8
  142. package/templates/apps/api-saas/package.json +11 -10
  143. package/templates/apps/api-saas-starter/package.json +10 -10
  144. package/templates/apps/api-search/package.json +8 -8
  145. package/templates/apps/api-status/package.json +8 -8
  146. package/templates/apps/api-webhooks/package.json +9 -9
  147. package/templates/apps/changelog/app.config.ts +26 -2
  148. package/templates/apps/changelog/content/releases/{0.1.0.mdx → v0-1-0.mdx} +0 -1
  149. package/templates/apps/changelog/content/releases/{0.2.0.mdx → v0-2-0.mdx} +0 -1
  150. package/templates/apps/changelog/package.json +9 -8
  151. package/templates/apps/changelog/src/collections/releases.collection.ts +48 -0
  152. package/templates/apps/changelog/src/globals.d.ts +1 -1
  153. package/templates/apps/changelog/src/locales/de.ts +1 -1
  154. package/templates/apps/changelog/src/locales/en.ts +1 -1
  155. package/templates/apps/changelog/src/pages/[locale]/[slug]/page.tsx +7 -4
  156. package/templates/apps/changelog/src/pages/[locale]/mirrors.test.tsx +13 -41
  157. package/templates/apps/changelog/src/pages/[slug]/page.test.tsx +26 -51
  158. package/templates/apps/changelog/src/pages/[slug]/page.tsx +21 -19
  159. package/templates/apps/changelog/src/pages/page.test.tsx +14 -37
  160. package/templates/apps/changelog/src/pages/page.tsx +18 -12
  161. package/templates/apps/edge-functions/package.json +2 -2
  162. package/templates/apps/frontend-admin/package.json +8 -8
  163. package/templates/apps/frontend-app/package.json +9 -9
  164. package/templates/apps/frontend-auth/package.json +8 -8
  165. package/templates/apps/frontend-blank/package.json +7 -7
  166. package/templates/apps/frontend-cms/package.json +9 -9
  167. package/templates/apps/frontend-collab/README.md +43 -24
  168. package/templates/apps/frontend-collab/app.config.ts +3 -3
  169. package/templates/apps/frontend-collab/package.json +14 -10
  170. package/templates/apps/frontend-collab/src/locales/de.ts +1 -2
  171. package/templates/apps/frontend-collab/src/locales/en.ts +1 -2
  172. package/templates/apps/frontend-collab/src/pages/page.test.tsx +72 -76
  173. package/templates/apps/frontend-collab/src/pages/page.tsx +45 -22
  174. package/templates/apps/frontend-collab/template.json +2 -2
  175. package/templates/apps/frontend-contact/package.json +7 -7
  176. package/templates/apps/frontend-dashboard/package.json +7 -7
  177. package/templates/apps/frontend-docs/content/docs/de/guides/first-page.md +4 -0
  178. package/templates/apps/frontend-docs/content/docs/de/intro/getting-started.md +4 -0
  179. package/templates/apps/frontend-docs/content/docs/en/guides/first-page.md +4 -0
  180. package/templates/apps/frontend-docs/content/docs/en/intro/getting-started.md +4 -0
  181. package/templates/apps/frontend-docs/package.json +9 -6
  182. package/templates/apps/frontend-docs/src/collections/docs.collection.ts +21 -0
  183. package/templates/apps/frontend-docs/src/locales/de.ts +0 -5
  184. package/templates/apps/frontend-docs/src/locales/en.ts +0 -5
  185. package/templates/apps/frontend-docs/src/pages/[locale]/docs/[...slug]/page.tsx +17 -9
  186. package/templates/apps/frontend-docs/src/pages/[locale]/mirrors.test.tsx +10 -5
  187. package/templates/apps/frontend-docs/src/pages/[locale]/page.tsx +8 -0
  188. package/templates/apps/frontend-docs/src/pages/docs/[...slug]/page.test.tsx +53 -15
  189. package/templates/apps/frontend-docs/src/pages/docs/[...slug]/page.tsx +27 -33
  190. package/templates/apps/frontend-docs/src/pages/page.test.tsx +17 -3
  191. package/templates/apps/frontend-docs/src/pages/page.tsx +16 -12
  192. package/templates/apps/frontend-i18n/package.json +6 -6
  193. package/templates/apps/frontend-landing/README.md +48 -0
  194. package/templates/apps/frontend-landing/app.config.ts +28 -0
  195. package/templates/apps/frontend-landing/package.json +7 -6
  196. package/templates/apps/frontend-landing/src/assets/hero.jpg +0 -0
  197. package/templates/apps/frontend-landing/src/fonts/Geist-Variable.woff2 +0 -0
  198. package/templates/apps/frontend-landing/src/fonts/LICENSE-Geist.txt +92 -0
  199. package/templates/apps/frontend-landing/src/globals.css +15 -0
  200. package/templates/apps/frontend-landing/src/globals.d.ts +17 -0
  201. package/templates/apps/frontend-landing/src/locales/de.ts +3 -2
  202. package/templates/apps/frontend-landing/src/locales/en.ts +5 -2
  203. package/templates/apps/frontend-landing/src/pages/page.test.tsx +79 -0
  204. package/templates/apps/frontend-landing/src/pages/page.tsx +26 -3
  205. package/templates/apps/frontend-landing/template.json +2 -2
  206. package/templates/apps/frontend-portal/package.json +8 -8
  207. package/templates/apps/frontend-saas/package.json +8 -8
  208. package/templates/apps/frontend-spa/package.json +7 -7
  209. package/templates/apps/frontend-ssr/package.json +7 -7
  210. package/templates/apps/frontend-ssr-api/package.json +8 -8
  211. package/templates/apps/frontend-static-blog/content/posts/cms-to-ssg.md +12 -0
  212. package/templates/apps/frontend-static-blog/content/posts/hello-static.md +12 -0
  213. package/templates/apps/frontend-static-blog/content/posts/islands-not-hydration.md +14 -0
  214. package/templates/apps/frontend-static-blog/package.json +9 -6
  215. package/templates/apps/frontend-static-blog/src/collections/posts.collection.ts +27 -0
  216. package/templates/apps/frontend-static-blog/src/pages/[locale]/blog/[slug]/page.tsx +7 -4
  217. package/templates/apps/frontend-static-blog/src/pages/[locale]/mirrors.test.tsx +7 -1
  218. package/templates/apps/frontend-static-blog/src/pages/blog/[slug]/page.test.tsx +19 -9
  219. package/templates/apps/frontend-static-blog/src/pages/blog/[slug]/page.tsx +19 -21
  220. package/templates/apps/frontend-static-blog/src/pages/page.test.tsx +18 -5
  221. package/templates/apps/frontend-static-blog/src/pages/page.tsx +21 -14
  222. package/templates/apps/frontend-status/package.json +8 -8
  223. package/templates/apps/mobile-app/package.json +12 -11
  224. package/templates/apps/mobile-app/src/lib/deeplinks.ts +29 -17
  225. package/templates/apps/mobile-app/tests/deeplinks.test.ts +16 -0
  226. package/dist/agentsMd-SDDSkyl4.js +0 -2
  227. package/dist/apiBuild-BYBpL7Pz.js +0 -2
  228. package/dist/build-CPgcMQug.js +0 -793
  229. package/dist/codegen-CctkDO-1.js +0 -2
  230. package/dist/codegenCommand-DCdG2JN-.js +0 -137
  231. package/dist/dbCommand-DNb6yeOG.js +0 -2
  232. package/dist/doctorCommand-CqoWA2p5.js +0 -2
  233. package/dist/fileConventions-DOqD3lPS.js +0 -34
  234. package/dist/frameworkTableAssembly-C6ETawPR.js +0 -2
  235. package/dist/inspect-CuGDYES0.js +0 -2
  236. package/dist/manifestBuild-CPjhvM62.js +0 -2
  237. package/dist/renderModeScan-CcH2X1_D.js +0 -120
  238. package/dist/serveCommand-DLc-BznW.js +0 -2
  239. package/dist/start-DfL3fOiN.js +0 -3
  240. package/dist/updateCommand-5gFVfK5q.js +0 -2
  241. package/dist/webDev-CZbTsDcH.js +0 -2
  242. package/templates/apps/changelog/scripts/generate-rss.mjs +0 -38
  243. package/templates/apps/changelog/src/lib/releases.ts +0 -21
  244. package/templates/apps/frontend-static-blog/src/content/posts.ts +0 -64
@@ -0,0 +1,428 @@
1
+ import { a as e, r as t } from "./subcommandNames-CDzfEtKV.js";
2
+ import { t as n } from "./cliArgs-D4p8n7EE.js";
3
+ import { s as r } from "./fileConventions-l-RIXbx8.js";
4
+ import { t as i } from "./workspaceDeps-RKEkX92S.js";
5
+ import { join as a, relative as o, resolve as s, sep as c } from "node:path";
6
+ import { promises as l } from "node:fs";
7
+ import { pathToFileURL as u } from "node:url";
8
+ //#region src/mobileCodegen.ts
9
+ var d = "voltro.mobile.ts", f = a(".framework", "mobileApis.generated.ts"), p = (e) => e.replace(/[^a-zA-Z0-9]/g, "_"), m = async (e) => {
10
+ let t = a(e, d);
11
+ try {
12
+ await l.stat(t);
13
+ } catch {
14
+ return { present: !1 };
15
+ }
16
+ try {
17
+ let e = (await import(`${u(t).href}?t=${Date.now()}`)).default;
18
+ return e === void 0 || typeof e != "object" || e.apis === void 0 ? {
19
+ present: !0,
20
+ error: /* @__PURE__ */ Error(`${d} has no default export with an \`apis\` map`)
21
+ } : {
22
+ present: !0,
23
+ binding: e
24
+ };
25
+ } catch (e) {
26
+ return {
27
+ present: !0,
28
+ error: e instanceof Error ? e : Error(String(e))
29
+ };
30
+ }
31
+ }, h = (e, t) => {
32
+ let n = t.filter(([, e]) => e.package !== void 0).map(([e, t]) => {
33
+ let n = `${p(e)}Group`, r = `${p(e)}Descriptors`;
34
+ return `import { ${n === "appGroup" ? "appGroup" : `appGroup as ${n}`}, ${r === "appDescriptors" ? "appDescriptors" : `appDescriptors as ${r}`} } from '${t.package}/rpcGroup'`;
35
+ }), r = t.map(([e, t]) => t.package === void 0 ? ` // ${JSON.stringify(e)}: declared with \`url\` only — no local rpc surface to import.\n // Add \`package: '<the api package>'\` to ${d} to get typed hooks for it.` : ` { ${[
36
+ `name: ${JSON.stringify(e)}`,
37
+ `group: ${p(e)}Group`,
38
+ `descriptors: ${p(e)}Descriptors`,
39
+ `wsUrl: wsUrl(${JSON.stringify(e)})`
40
+ ].join(", ")} },`), i = t.filter(([, e]) => e.url !== void 0).map(([e, t]) => ` ${JSON.stringify(e)}: ${JSON.stringify(t.url)},`);
41
+ return [
42
+ "// GENERATED BY `voltro codegen` — do not edit; regenerate with `voltro codegen`.",
43
+ "//",
44
+ `// The api bindings declared in ${d}. Only the BINDING is`,
45
+ "// generated: the procedure types ride the imports below, so a schema change",
46
+ "// in an api needs no regeneration here.",
47
+ "",
48
+ ...n,
49
+ "import type { MobileApiBinding } from '@voltro/react-native'",
50
+ "",
51
+ "/** Every api this app talks to, bound to a runtime-resolved ws URL.",
52
+ " *",
53
+ " * The URL is a parameter because it differs per environment and `localhost`",
54
+ " * on a device is the DEVICE — see `resolveDevWsUrl` in @voltro/react-native. */",
55
+ "export const mobileApis = (",
56
+ " wsUrl: (apiName: string) => string,",
57
+ "): ReadonlyArray<MobileApiBinding> => [",
58
+ ...r,
59
+ "]",
60
+ "",
61
+ "/** Api names in declaration order — the keys the hooks bind to. */",
62
+ `export const MOBILE_API_NAMES = [${t.map(([e]) => JSON.stringify(e)).join(", ")}] as const`,
63
+ ...i.length > 0 ? [
64
+ "",
65
+ `/** URLs declared in ${d} for apis this app does not build. */`,
66
+ "export const MOBILE_API_URLS: Readonly<Record<string, string>> = {",
67
+ ...i,
68
+ "}"
69
+ ] : [],
70
+ ""
71
+ ].join("\n");
72
+ }, g = async (e) => {
73
+ let t = s(e), n = await m(t);
74
+ if (!n.present) return { kind: "not-a-mobile-app" };
75
+ if ("error" in n) return {
76
+ kind: "refused",
77
+ reason: `${d} could not be loaded — ${n.error.message}`
78
+ };
79
+ let r = Object.entries(n.binding.apis);
80
+ if (r.length === 0) return {
81
+ kind: "refused",
82
+ reason: `${d} declares no apis`
83
+ };
84
+ for (let [e, t] of r) if (t.package === void 0 && t.url === void 0) return {
85
+ kind: "refused",
86
+ reason: `api ${JSON.stringify(e)} declares neither \`package\` nor \`url\``
87
+ };
88
+ for (let [e, n] of r) if (n.package !== void 0 && await i(t, n.package) === null) return {
89
+ kind: "refused",
90
+ reason: `api ${JSON.stringify(e)}: ${n.package} is not a workspace dependency of this app. Add it to the app's package.json (\`"${n.package}": "workspace:*"\`) and install.`
91
+ };
92
+ let o = a(t, f), c = h(t, r);
93
+ await l.mkdir(a(t, ".framework"), { recursive: !0 });
94
+ let u = null;
95
+ try {
96
+ u = await l.readFile(o, "utf8");
97
+ } catch {}
98
+ return u !== c && await l.writeFile(o, c, "utf8"), {
99
+ kind: "wrote",
100
+ file: o,
101
+ apis: r.map(([e]) => e)
102
+ };
103
+ }, _ = (e, t) => t.kind === "wrote" ? `voltro codegen: wrote ${o(e, t.file)} (apis ${t.apis.join(", ")})` : t.kind === "refused" ? `voltro codegen: ${t.reason} — refusing to write.` : `voltro codegen: no ${d} here — not a mobile app.`, v = a(".framework", "deepLinks.generated.ts"), y = [a("src", "app"), "app"], b = /\.(tsx|ts|jsx|js)$/, x = (e) => {
104
+ let t = e.split(c).join("/");
105
+ if (!b.test(t)) return {
106
+ kind: "skip",
107
+ reason: "not a route file extension"
108
+ };
109
+ if (/\.(test|spec)\.[jt]sx?$/.test(t)) return {
110
+ kind: "skip",
111
+ reason: "a test file"
112
+ };
113
+ if (/\+api\.[jt]sx?$/.test(t) || /\+api\.[jt]sx?$/.test(t)) return {
114
+ kind: "skip",
115
+ reason: "an Expo Router API route, not a screen"
116
+ };
117
+ if (r.test(t)) return {
118
+ kind: "skip",
119
+ reason: "a *.deepLink.ts inside the router directory"
120
+ };
121
+ let n = t.replace(b, "").split("/"), i = [];
122
+ for (let [e, t] of n.entries()) {
123
+ let r = e === n.length - 1;
124
+ if (t.startsWith("+")) return {
125
+ kind: "skip",
126
+ reason: `\`${t}\` is an Expo Router special file, not a screen`
127
+ };
128
+ if (t.startsWith("_")) return {
129
+ kind: "skip",
130
+ reason: `\`${t}\` is not a route (Expo Router reserves the \`_\` prefix)`
131
+ };
132
+ if (t.startsWith(".")) return {
133
+ kind: "skip",
134
+ reason: "a dot-file"
135
+ };
136
+ if (!(t.startsWith("(") && t.endsWith(")"))) {
137
+ if (t.startsWith("[...") && t.endsWith("]")) return {
138
+ kind: "skip",
139
+ reason: `\`${t}\` is a catch-all — the matcher has no catch-all segment, so declare this one in a \`*.deepLink.ts\``
140
+ };
141
+ if (t.startsWith("[") && t.endsWith("]")) {
142
+ let e = t.slice(1, -1).replace(/^\[|\]$/g, "");
143
+ if (e.length === 0) return {
144
+ kind: "skip",
145
+ reason: "an empty dynamic segment"
146
+ };
147
+ i.push(`:${e}`);
148
+ continue;
149
+ }
150
+ r && t === "index" || i.push(t);
151
+ }
152
+ }
153
+ return {
154
+ kind: "route",
155
+ pattern: `/${i.join("/")}`.replace(/\/{2,}/g, "/")
156
+ };
157
+ }, S = (e, t) => {
158
+ let n = e.split("/"), r = t.split("/");
159
+ for (let e = 0; e < Math.min(n.length, r.length); e++) {
160
+ let t = n[e].startsWith(":");
161
+ if (t !== r[e].startsWith(":")) return t ? 1 : -1;
162
+ }
163
+ return n.length === r.length ? e < t ? -1 : +(e > t) : n.length - r.length;
164
+ }, C = async (e, t) => {
165
+ let n;
166
+ try {
167
+ n = await l.readdir(e, { withFileTypes: !0 });
168
+ } catch {
169
+ return;
170
+ }
171
+ for (let r of n) {
172
+ if (r.name.startsWith(".") || r.name === "node_modules") continue;
173
+ let n = a(e, r.name);
174
+ r.isDirectory() ? await C(n, t) : t(n);
175
+ }
176
+ }, w = async (e) => {
177
+ try {
178
+ return await l.stat(e), !0;
179
+ } catch {
180
+ return !1;
181
+ }
182
+ }, T = async (e) => {
183
+ for (let t of y) if (await w(a(e, t))) return t;
184
+ return null;
185
+ }, E = async (e) => {
186
+ let t = await T(e), n = [], i = [];
187
+ if (await C(e, (a) => {
188
+ let s = o(e, a);
189
+ if (s.startsWith("..") || !r.test(a)) return;
190
+ let l = s.split(c).join("/");
191
+ if (t !== null && l.startsWith(`${t.split(c).join("/")}/`)) {
192
+ i.push(l);
193
+ return;
194
+ }
195
+ n.push({
196
+ file: l,
197
+ importPath: `../${l.replace(/\.ts$/, "")}`
198
+ });
199
+ }), i.length > 0) return {
200
+ kind: "refused",
201
+ reason: `${i.join(", ")} — a *.deepLink.ts inside \`${t}\` becomes a SCREEN. Expo Router routes every .ts/.tsx under its app directory, so this file ships a route named after itself. Move it outside the router directory (e.g. src/lib/).`
202
+ };
203
+ let s = [], l = [];
204
+ if (t !== null) {
205
+ let n = a(e, t);
206
+ await C(n, (t) => {
207
+ let r = x(o(n, t)), i = o(e, t).split(c).join("/");
208
+ r.kind === "route" ? s.push({
209
+ pattern: r.pattern,
210
+ file: i
211
+ }) : l.push({
212
+ file: i,
213
+ reason: r.reason
214
+ });
215
+ });
216
+ }
217
+ let u = /* @__PURE__ */ new Set(), d = s.sort((e, t) => S(e.pattern, t.pattern)).filter((e) => !u.has(e.pattern) && (u.add(e.pattern), !0));
218
+ return {
219
+ kind: "collected",
220
+ table: {
221
+ routerDir: t,
222
+ declared: n.sort((e, t) => e.file < t.file ? -1 : +(e.file > t.file)),
223
+ derived: d,
224
+ skipped: l.sort((e, t) => e.file < t.file ? -1 : +(e.file > t.file))
225
+ }
226
+ };
227
+ }, D = (e) => `declared${e}`, O = (e) => {
228
+ let t = [
229
+ "// GENERATED BY `voltro mobile codegen` — do not edit; regenerate with",
230
+ "// `voltro mobile codegen`.",
231
+ "//",
232
+ "// The app's deep-link table, from two sources:",
233
+ "//",
234
+ `// · DERIVED — one link per Expo Router screen under \`${e.routerDir ?? "(no router directory found)"}\`.`,
235
+ "// A screen is reachable by URL, so its link needs no file.",
236
+ "// · DECLARED — every `*.deepLink.ts` in the app. These come FIRST, so a",
237
+ "// declared link for a pattern overrides the derived one for it.",
238
+ "",
239
+ "import { defineDeepLink, deepLinkHref, type DeepLinkDescriptor } from '@voltro/react-native'"
240
+ ];
241
+ for (let [n, r] of e.declared.entries()) t.push(`import ${D(n)} from '${r.importPath}'`);
242
+ return t.push("", "/** Patterns derived from the router tree, most specific first. */", "export const DERIVED_DEEP_LINK_PATTERNS = [", ...e.derived.map((e) => ` ${JSON.stringify(e.pattern)}, // ${e.file}`), "] as const", "", "/** Deep links declared by hand (`*.deepLink.ts`). */", "export const DECLARED_DEEP_LINKS: ReadonlyArray<DeepLinkDescriptor> = [", ...e.declared.map((e, t) => ` ${D(t)}, // ${e.file}`), "]", ""), e.skipped.length > 0 && t.push("// Router files that are NOT deep links. Listed rather than dropped: a", "// screen missing from the table above is otherwise indistinguishable from", "// one that has no link.", ...e.skipped.map((e) => `// ${e.file} — ${e.reason}`), ""), t.push("/**", " * The app's deep links, bound to a navigate function (expo-router's `router.push`).", " *", " * Order is the resolution order — `matchFirstDeepLink` is first-match-wins.", " * A derived pattern a declared link already covers is dropped here rather", " * than listed twice.", " */", "export const deepLinks = (", " navigate: (href: string) => void,", "): ReadonlyArray<DeepLinkDescriptor> => {", " const declaredPatterns = new Set(DECLARED_DEEP_LINKS.map((link) => link.pattern))", " const derived: ReadonlyArray<string> = DERIVED_DEEP_LINK_PATTERNS", " return [", " ...DECLARED_DEEP_LINKS,", " ...derived", " .filter((pattern) => !declaredPatterns.has(pattern))", " .map((pattern) =>", " defineDeepLink({", " pattern,", " // A derived link navigates to the screen it was derived FROM —", " // the same path, with the captured params put back.", " handler: (params) => navigate(deepLinkHref(pattern, params)),", " })),", " ]", "}", ""), t.join("\n");
243
+ }, k = async (e) => {
244
+ let t = await E(e);
245
+ if (t.kind === "refused") return t;
246
+ let n = a(e, v), r = O(t.table);
247
+ await l.mkdir(a(e, ".framework"), { recursive: !0 });
248
+ let i = null;
249
+ try {
250
+ i = await l.readFile(n, "utf8");
251
+ } catch {}
252
+ return i !== r && await l.writeFile(n, r, "utf8"), {
253
+ kind: "wrote",
254
+ file: n,
255
+ derived: t.table.derived.length,
256
+ declared: t.table.declared.length,
257
+ skipped: t.table.skipped,
258
+ routerDir: t.table.routerDir
259
+ };
260
+ }, A = (e) => {
261
+ let t = /pattern\s*:\s*(['"`])(\/[^'"`\n]*)\1/.exec(e);
262
+ return t === null ? null : t[2];
263
+ }, j = async (e, t) => {
264
+ let n = [], r = [];
265
+ for (let i of t.declared) {
266
+ let t = "";
267
+ try {
268
+ t = await l.readFile(a(e, i.file), "utf8");
269
+ } catch {}
270
+ let o = A(t);
271
+ o === null ? r.push(i.file) : n.push(o);
272
+ }
273
+ return {
274
+ patterns: n,
275
+ unreadable: r
276
+ };
277
+ }, M = /^[A-Z0-9]{10}$/, N = /^[A-Za-z][A-Za-z0-9_-]*(\.[A-Za-z0-9_-]+)+$/, P = /^[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z0-9_]+)+$/, F = (e) => {
278
+ let t = e.split("/").map((e) => e.startsWith(":") ? "*" : e).join("/");
279
+ return t.length === 0 ? "/" : t;
280
+ }, I = (e) => {
281
+ let t = e.trim().replace(/[:\s]/g, "").toUpperCase();
282
+ return /^[0-9A-F]{64}$/.test(t) ? (t.match(/.{2}/g) ?? []).join(":") : null;
283
+ }, L = (e) => {
284
+ let t = [], n = e.appleTeamId.trim().toUpperCase();
285
+ M.test(n) || t.push(`apple team id ${JSON.stringify(e.appleTeamId)} is not a 10-character Team ID. Find it in the Apple Developer portal under Membership details, and pass it as \`--team-id\` (or set VOLTRO_APPLE_TEAM_ID).`), N.test(e.bundleIdentifier) || t.push(`ios bundle identifier ${JSON.stringify(e.bundleIdentifier)} is not reverse-DNS. It comes from the Expo config's \`ios.bundleIdentifier\`.`), P.test(e.androidPackage) || t.push(`android package ${JSON.stringify(e.androidPackage)} is not a Java package name. It comes from the Expo config's \`android.package\`.`);
286
+ let r = [];
287
+ for (let n of e.sha256CertFingerprints) {
288
+ let e = I(n);
289
+ e === null ? t.push(`${JSON.stringify(n)} is not a SHA-256 fingerprint (32 hex bytes). Get it with \`keytool -list -v -keystore <your.keystore>\`, or from Play Console → Setup → App signing.`) : r.includes(e) || r.push(e);
290
+ }
291
+ if (e.sha256CertFingerprints.length === 0 && t.push("no android signing fingerprint. Pass `--fingerprint <sha256>` (repeatable — a debug keystore and Play App Signing are different certificates and BOTH must be listed, or App Links verify in one build and not the other)."), e.patterns.length === 0 && t.push("the app answers no deep links, so an association file would grant the app nothing. Add a screen under the router directory, or a `*.deepLink.ts`."), t.length > 0) return {
292
+ kind: "refused",
293
+ reasons: t
294
+ };
295
+ let i = /* @__PURE__ */ new Set(), a = e.patterns.map((e) => ({
296
+ pattern: e,
297
+ component: F(e)
298
+ })).filter(({ component: e }) => !i.has(e) && (i.add(e), !0)).map(({ pattern: e, component: t }) => ({
299
+ "/": t,
300
+ comment: `opens the app for ${e}`
301
+ }));
302
+ return {
303
+ kind: "built",
304
+ aasa: { applinks: { details: [{
305
+ appIDs: [`${n}.${e.bundleIdentifier}`],
306
+ components: a
307
+ }] } },
308
+ assetLinks: [{
309
+ relation: ["delegate_permission/common.handle_all_urls"],
310
+ target: {
311
+ namespace: "android_app",
312
+ package_name: e.androidPackage,
313
+ sha256_cert_fingerprints: r
314
+ }
315
+ }]
316
+ };
317
+ }, R = "apple-app-site-association", z = "assetlinks.json", B = ".well-known", V = [
318
+ "app.config.ts",
319
+ "app.config.js",
320
+ "app.config.json",
321
+ "app.json"
322
+ ], H = async (e) => {
323
+ try {
324
+ return await l.stat(e), !0;
325
+ } catch {
326
+ return !1;
327
+ }
328
+ }, U = async (e) => {
329
+ for (let t of V) {
330
+ let n = a(e, t);
331
+ if (await H(n)) try {
332
+ if (t.endsWith(".json")) {
333
+ let e = JSON.parse(await l.readFile(n, "utf8"));
334
+ return {
335
+ kind: "loaded",
336
+ config: e.expo ?? e,
337
+ file: n
338
+ };
339
+ }
340
+ let e = (await import(`${u(n).href}?t=${Date.now()}`)).default, r = typeof e == "function" ? e({ config: {} }) : e;
341
+ return r === void 0 || typeof r != "object" ? {
342
+ kind: "failed",
343
+ file: n,
344
+ error: /* @__PURE__ */ Error("no default export with an Expo config object")
345
+ } : {
346
+ kind: "loaded",
347
+ config: r,
348
+ file: n
349
+ };
350
+ } catch (e) {
351
+ return {
352
+ kind: "failed",
353
+ file: n,
354
+ error: e instanceof Error ? e : Error(String(e))
355
+ };
356
+ }
357
+ }
358
+ return { kind: "absent" };
359
+ }, W = async (e) => {
360
+ let t = await g(e);
361
+ return t.kind === "not-a-mobile-app" ? {
362
+ apis: t,
363
+ deepLinks: null
364
+ } : {
365
+ apis: t,
366
+ deepLinks: await k(e)
367
+ };
368
+ }, G = (e, t) => {
369
+ console.log(_(e, t.apis));
370
+ let n = t.deepLinks;
371
+ if (n === null) return 1;
372
+ if (n.kind === "refused") return console.error(`voltro mobile codegen: ${n.reason}`), 1;
373
+ let r = t.apis.kind !== "wrote";
374
+ n.routerDir === null ? console.log(`voltro mobile codegen: wrote ${o(e, n.file)} (${n.declared} declared link(s); no Expo Router directory found, so nothing was derived)`) : console.log(`voltro mobile codegen: wrote ${o(e, n.file)} (${n.derived} link(s) derived from ${n.routerDir}, ${n.declared} declared)`);
375
+ for (let e of n.skipped) e.reason.includes("catch-all") && console.log(` not derived: ${e.file} — ${e.reason}`);
376
+ return +!!r;
377
+ }, K = async (e) => G(e, await W(e)), q = (e, t) => {
378
+ let n = e.indexOf(t);
379
+ if (n !== -1 && n + 1 < e.length) return e[n + 1];
380
+ let r = e.find((e) => e.startsWith(`${t}=`));
381
+ return r === void 0 ? void 0 : r.slice(t.length + 1);
382
+ }, J = (e, t) => {
383
+ let n = [];
384
+ for (let [r, i] of e.entries()) i === t && r + 1 < e.length ? n.push(e[r + 1]) : i.startsWith(`${t}=`) && n.push(i.slice(t.length + 1));
385
+ return n;
386
+ }, Y = async (e, t) => {
387
+ let n = await U(e);
388
+ if (n.kind === "absent") return console.error(`voltro mobile links: no Expo config in ${e} (looked for ${V.join(", ")}) — this is not a mobile app.`), 1;
389
+ if (n.kind === "failed") return console.error(`voltro mobile links: ${o(e, n.file)} could not be loaded — ${n.error.message}.`), console.error(" Refusing to write: the association files would carry no bundle id and would publish anyway."), 1;
390
+ let r = await E(e);
391
+ if (r.kind === "refused") return console.error(`voltro mobile links: ${r.reason}`), 1;
392
+ let i = await j(e, r.table);
393
+ for (let e of i.unreadable) console.error(`voltro mobile links: ${e} declares a computed \`pattern\`, which cannot be read without running the module. Its path is NOT in the generated files — spell the pattern as a string literal, or add it by hand afterwards.`);
394
+ let c = [...i.patterns, ...r.table.derived.map((e) => e.pattern)], u = L({
395
+ bundleIdentifier: n.config.ios?.bundleIdentifier ?? "",
396
+ appleTeamId: q(t, "--team-id") ?? process.env.VOLTRO_APPLE_TEAM_ID ?? "",
397
+ androidPackage: n.config.android?.package ?? "",
398
+ sha256CertFingerprints: [...J(t, "--fingerprint"), ...process.env.VOLTRO_ANDROID_CERT_FINGERPRINT === void 0 ? [] : [process.env.VOLTRO_ANDROID_CERT_FINGERPRINT]],
399
+ patterns: c
400
+ });
401
+ if (u.kind === "refused") {
402
+ console.error("voltro mobile links: refusing to write —");
403
+ for (let e of u.reasons) console.error(` · ${e}`);
404
+ return 1;
405
+ }
406
+ let d = s(e, q(t, "--out") ?? ".well-known");
407
+ await l.mkdir(d, { recursive: !0 });
408
+ let f = a(d, R), p = a(d, z);
409
+ await l.writeFile(f, `${JSON.stringify(u.aasa, null, 2)}\n`, "utf8"), await l.writeFile(p, `${JSON.stringify(u.assetLinks, null, 2)}\n`, "utf8");
410
+ let m = u.aasa.applinks.details[0].components.length;
411
+ console.log(`voltro mobile links: wrote ${o(e, f)} (${m} path component(s))`), console.log(`voltro mobile links: wrote ${o(e, p)}`), console.log(` Serve both from https://<your-domain>/${B}/ as application/json, over https, with no redirect. iOS fetches the association file itself — a redirect is a silent failure.`);
412
+ let h = n.config.ios?.associatedDomains ?? [];
413
+ return h.length === 0 ? console.log(" NOTE: the Expo config declares no `ios.associatedDomains`. iOS will not fetch the association file until it does — add `ios: { associatedDomains: [\"applinks:<your-domain>\"] }`.") : console.log(` ios.associatedDomains: ${h.join(", ")}`), 0;
414
+ }, X = {
415
+ codegen: (e) => K(e),
416
+ links: (e, t) => Y(e, t)
417
+ }, Z = async (r) => {
418
+ let i = r[0];
419
+ if (i === void 0 || i === "--help" || i === "-h" || !(i in X)) return i !== void 0 && i !== "--help" && i !== "-h" && console.error(`voltro mobile: unknown subcommand ${JSON.stringify(i)}`), console.log(`voltro mobile ${e(t)}`), console.log(""), console.log(" codegen [app] regenerate the api binding + the deep-link table"), console.log(" links [app] emit apple-app-site-association + assetlinks.json"), console.log(""), console.log(" --team-id <id> Apple Team ID (or VOLTRO_APPLE_TEAM_ID)"), console.log(" --fingerprint <sha256> Android signing cert SHA-256 (repeatable,"), console.log(" or VOLTRO_ANDROID_CERT_FINGERPRINT)"), console.log(" --out <dir> where to write them (default: .well-known/)"), i === void 0 || i === "--help" || i === "-h" ? 0 : 1;
420
+ let a = r.slice(1), o = s(n(a, Q) ?? process.cwd());
421
+ return X[i](o, a);
422
+ }, Q = [
423
+ "--fingerprint",
424
+ "--out",
425
+ "--team-id"
426
+ ];
427
+ //#endregion
428
+ export { d as a, Z as i, G as n, W as r, U as t };
@@ -0,0 +1,2 @@
1
+ import { i as e } from "./mobileCommand-D9O6iq3D.js";
2
+ export { e as runMobileCommand };
@@ -1,4 +1,4 @@
1
- import { T as e } from "./fileConventions-DOqD3lPS.js";
1
+ import { D as e } from "./fileConventions-l-RIXbx8.js";
2
2
  //#region src/pageConvention.ts
3
3
  var t = (t) => e.test(t), n = (e) => e.replace(/page\.tsx$/, "page.test.tsx");
4
4
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import { t as e } from "./cliError-BmdYnghb.js";
2
2
  import { i as t, n, t as r } from "./cliArgs-D4p8n7EE.js";
3
- import { b as i, y as a } from "./fileConventions-DOqD3lPS.js";
3
+ import { S as i, x as a } from "./fileConventions-l-RIXbx8.js";
4
4
  import { n as o } from "./cliOutput-D1tSBoRM.js";
5
5
  import { join as s, resolve as c } from "node:path";
6
6
  import { promises as l } from "node:fs";
@@ -1,4 +1,4 @@
1
- import { r as e, t } from "./inspectGateHint-BjnFubmH.js";
1
+ import { r as e, t } from "./inspectGateHint-4LxkNtrz.js";
2
2
  import { n } from "./cliOutput-D1tSBoRM.js";
3
3
  import { n as r, o as i, r as a, t as o } from "./inspectFetch-EMuhTG_9.js";
4
4
  import { ansi as s } from "@voltro/logger";
@@ -57,25 +57,84 @@ server and in this shell.`);
57
57
  verdict: "refused",
58
58
  detail: `refused (${a})`
59
59
  };
60
- }, d = 0, f = (e) => ({
60
+ }, d = 0, f = (e, t) => ({
61
61
  _tag: "Request",
62
62
  id: String(++d),
63
63
  tag: e,
64
- payload: {},
64
+ payload: t,
65
65
  headers: []
66
- }), p = async (e, t) => {
67
- let { verdict: n, detail: r } = u(await o(e, "/rpc", {
66
+ }), p = (e, t = 0) => {
67
+ if (t > 6 || typeof e != "object" || !e) return;
68
+ let n = e;
69
+ switch (n._tag) {
70
+ case "StringKeyword": return "probe";
71
+ case "NumberKeyword": return 0;
72
+ case "BooleanKeyword": return !1;
73
+ case "BigIntKeyword": return "0";
74
+ case "UnknownKeyword":
75
+ case "AnyKeyword":
76
+ case "ObjectKeyword": return {};
77
+ case "VoidKeyword":
78
+ case "UndefinedKeyword": return;
79
+ case "Literal": return n.literal;
80
+ case "Enums": return n.enums?.[0]?.[1];
81
+ case "TypeLiteral": {
82
+ let e = {};
83
+ for (let r of n.propertySignatures ?? []) {
84
+ if (r.isOptional === !0) continue;
85
+ let n = p(r.type, t + 1);
86
+ if (n === void 0) return;
87
+ e[String(r.name)] = n;
88
+ }
89
+ return e;
90
+ }
91
+ case "TupleType": {
92
+ if ((n.elements ?? []).length === 0) return [];
93
+ let e = (n.elements ?? []).map((e) => p(e.type ?? e, t + 1));
94
+ return e.some((e) => e === void 0) ? void 0 : e;
95
+ }
96
+ case "Union":
97
+ for (let e of n.types ?? []) {
98
+ let n = p(e, t + 1);
99
+ if (n !== void 0) return n;
100
+ }
101
+ (n.types ?? []).some((e) => e._tag === "UndefinedKeyword");
102
+ return;
103
+ case "Refinement":
104
+ case "Transformation": return p(n.from, t + 1);
105
+ case "Suspend": return;
106
+ default: return;
107
+ }
108
+ }, m = async (e) => {
109
+ let t = /* @__PURE__ */ new Map();
110
+ try {
111
+ let { walk: n, loadDiscovered: r } = await import("./dev-cKUiZZsB.js"), i = await r(await n(e)), a = [
112
+ ...i.queries,
113
+ ...i.mutations,
114
+ ...i.actions,
115
+ ...i.streams
116
+ ];
117
+ for (let e of a) {
118
+ let n = e.descriptor.input;
119
+ if (n?.ast === void 0) continue;
120
+ let r = p(n.ast);
121
+ r !== void 0 && t.set(e.descriptor.name, r);
122
+ }
123
+ } catch {}
124
+ return t;
125
+ }, h = async (e, t, n) => {
126
+ let { verdict: r, detail: i } = u(await o(e, "/rpc", {
68
127
  method: "POST",
69
- body: f(t.tag),
128
+ body: f(t.tag, n),
70
129
  anonymous: !0
71
130
  }));
72
131
  return {
73
132
  tag: t.tag,
74
133
  kind: t.kind,
75
- verdict: n,
76
- detail: r
134
+ verdict: r,
135
+ detail: i
77
136
  };
78
- }, m = (e, t, r, i) => {
137
+ }, g = (e, t, r, i) => {
79
138
  let a = t.filter((e) => e.verdict === "admitted"), o = t.filter((e) => e.verdict === "inconclusive"), c = t.filter((e) => e.verdict === "refused");
80
139
  if (r === "json") n({
81
140
  app: e,
@@ -107,28 +166,28 @@ server and in this shell.`);
107
166
  There an anonymous request carries \`tenantId: null\`, which is the case a guard
108
167
  has to refuse — and the case a tenant-keyed role map most easily gets wrong.`), 1) : i && o.length > 0 ? (r !== "json" && console.error(`\n${s.yellow("--strict:")} ${o.length} procedure(s) could not be judged.\n Their calls failed before the guard was reached (usually payload validation).
109
168
  That is not evidence of enforcement, so under --strict it is not a pass.`), 1) : 0;
110
- }, h = async (n) => {
169
+ }, _ = async (n) => {
111
170
  let c = r(n);
112
171
  if ("error" in c) return console.error(`voltro probe access: ${c.error}`), 1;
113
- let { format: u } = c, { process: d, target: f, rest: h, error: g } = a(c.rest);
114
- if (g !== void 0) return console.error(`voltro probe access: ${g}`), 1;
115
- let _ = h.includes("--strict"), v = await i(d, f);
116
- if (v.length === 0) return console.error("voltro probe access: no live api found.\n This command asks a RUNNING app what it does — there is nothing to ask a source tree.\n Start one (`voltro dev` / `voltro serve`), or address it directly with --url."), 1;
117
- let y = 0;
118
- for (let n of v) {
172
+ let { format: u } = c, { process: d, target: f, rest: p, error: _ } = a(c.rest);
173
+ if (_ !== void 0) return console.error(`voltro probe access: ${_}`), 1;
174
+ let v = p.includes("--strict"), y = await i(d, f);
175
+ if (y.length === 0) return console.error("voltro probe access: no live api found.\n This command asks a RUNNING app what it does — there is nothing to ask a source tree.\n Start one (`voltro dev` / `voltro serve`), or address it directly with --url."), 1;
176
+ let b = 0;
177
+ for (let n of y) {
119
178
  let r = await o(n, "/_voltro/inspect/manifest");
120
179
  if (r.kind === "err" || r.status < 200 || r.status >= 300) {
121
- console.error(`${s.red("✗")} ${n.name}: could not read the manifest — ${r.kind === "err" ? r.error : `HTTP ${r.status}`}`), r.kind === "ok" && e(r.status) && console.error(` ${t(r.status)}`), y = 1;
180
+ console.error(`${s.red("✗")} ${n.name}: could not read the manifest — ${r.kind === "err" ? r.error : `HTTP ${r.status}`}`), r.kind === "ok" && e(r.status) && console.error(` ${t(r.status)}`), b = 1;
122
181
  continue;
123
182
  }
124
- let i = l(r.data?.procedures ?? []), a = [];
125
- for (let e of i) a.push(await p(n, e));
126
- y = Math.max(y, m(n.name, a, u, _));
183
+ let i = l(r.data?.procedures ?? []), a = await m(process.cwd()), c = [];
184
+ for (let e of i) c.push(await h(n, e, a.get(e.tag) ?? {}));
185
+ b = Math.max(b, g(n.name, c, u, v));
127
186
  }
128
- return y;
129
- }, g = async (e) => {
187
+ return b;
188
+ }, v = async (e) => {
130
189
  let [t, ...n] = e;
131
- return t === void 0 || t === "--help" || t === "-h" ? (c(), +(t === void 0)) : t === "access" ? h(n) : (console.error(`voltro probe: unknown subcommand "${t}" (expected: access)`), 1);
190
+ return t === void 0 || t === "--help" || t === "-h" ? (c(), +(t === void 0)) : t === "access" ? _(n) : (console.error(`voltro probe: unknown subcommand "${t}" (expected: access)`), 1);
132
191
  };
133
192
  //#endregion
134
- export { g as runProbeCommand };
193
+ export { v as runProbeCommand };
@@ -1,2 +1,2 @@
1
- import { c as e, l as t, s as n } from "./projectScaffold-B4dmTlwT.js";
1
+ import { c as e, l as t, s as n } from "./projectScaffold-CSN0OzBV.js";
2
2
  export { n as runAddApp, e as runCreateProject, t as runListTemplates };
@@ -1,7 +1,7 @@
1
- import { a as e, i as t, n, r, t as i } from "./templates-BR-fb4SP.js";
1
+ import { a as e, i as t, n, r, t as i } from "./templates-BTWZkJJT.js";
2
2
  import { i as a, n as o, t as s } from "./cloudClient-DWL-Hw_T.js";
3
3
  import { t as c } from "./cliRuntime-Dh7UDinH.js";
4
- import { n as l } from "./agentsMd-0l980yhL.js";
4
+ import { n as l } from "./agentsMd-BaLC10Na.js";
5
5
  import { n as u } from "./addCommand-C05L9tZh.js";
6
6
  import { a as d, n as f, r as p } from "./baselineCommand-Ck2Xm8M7.js";
7
7
  import { basename as m, dirname as h, join as g, resolve as _ } from "node:path";