@voltro/cli 0.33.0 → 0.34.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 (337) hide show
  1. package/CHANGELOG.md +1801 -0
  2. package/bin/nodeEnvironment.d.mts +30 -0
  3. package/bin/nodeEnvironment.mjs +158 -0
  4. package/bin/voltro.mjs +69 -5
  5. package/dist/addCommand-BNeoeSxe.js +124 -0
  6. package/dist/addCommand-aXSQveak.js +2 -0
  7. package/dist/agentsMd-BTchIZku.js +2 -0
  8. package/dist/agentsMd-mhQMF1bx.js +254 -0
  9. package/dist/apiBuild-BICVGnEC.js +2 -0
  10. package/dist/{apiBuild-h9VHtnlw.js → apiBuild-DZF_f0_I.js} +46 -46
  11. package/dist/appPort-B_HpJ_ck.js +48 -0
  12. package/dist/baselineCommand-C2ClWZN3.js +2 -0
  13. package/dist/baselineCommand-DIttzO8A.js +227 -0
  14. package/dist/bin.js +71 -28
  15. package/dist/build-CE7Ca9gm.js +711 -0
  16. package/dist/cacheCommand-DA4OH9xt.js +42 -0
  17. package/dist/capabilitiesCommand-nq_pz5xd.js +123 -0
  18. package/dist/checkCommand-Dv8r9tGO.js +231 -0
  19. package/dist/checkCommand-YZDmkAGd.js +2 -0
  20. package/dist/{cliArgs-qdZSElM3.js → cliArgs-D4p8n7EE.js} +12 -1
  21. package/dist/cliError-BmdYnghb.js +10 -0
  22. package/dist/cliOutput-D1tSBoRM.js +15 -0
  23. package/dist/{cliRuntime-Oh517vCV.js → cliRuntime-Dh7UDinH.js} +20 -20
  24. package/dist/cloudClient-DWL-Hw_T.js +67 -0
  25. package/dist/cloudCmd-Cvv5HGaZ.js +364 -0
  26. package/dist/clusterCmd-CNXKlcvD.js +54 -0
  27. package/dist/codegen-CYM3Zqrf.js +605 -0
  28. package/dist/codegen-ChBi_hVa.js +2 -0
  29. package/dist/codegenCommand-DC6w2tNZ.js +30 -0
  30. package/dist/codemodRunner-DRRqXR74.js +5243 -0
  31. package/dist/commandRunner-BLAEFLjp.js +47 -0
  32. package/dist/commands-gutsz-Ac.js +808 -0
  33. package/dist/connectionConfig-UFlIEiys.js +66 -0
  34. package/dist/dashboardCommand-3YG8p-UA.js +25 -0
  35. package/dist/dataCommand-qL0r7fPO.js +535 -0
  36. package/dist/dataProfile-dW-PsfLB.js +15 -0
  37. package/dist/{dbCommand-DTLKAfbA.js → dbCommand-B6X0FZbq.js} +551 -401
  38. package/dist/dbCommand-CpdKLeQq.js +2 -0
  39. package/dist/{dev-C_P8FLSx.js → dev-CerMd0mW.js} +3122 -3129
  40. package/dist/dev-CoG-ZPx8.js +3 -0
  41. package/dist/devActivity-Dx_3nnGv.js +100 -0
  42. package/dist/devActivity.js +1 -1
  43. package/dist/dialectDriver-CgXnDfec.js +39 -0
  44. package/dist/discover-C9XKJDco.js +25 -0
  45. package/dist/doctorCommand-BvqGBwNG.js +2 -0
  46. package/dist/{checkCommand-xGhRFFg2.js → doctorCommand-CnDXQxfa.js} +520 -1278
  47. package/dist/dormancyCommand-Dszo57d6.js +69 -0
  48. package/dist/e2eCmd-BRabZww-.js +147 -0
  49. package/dist/embeddingsCommand-C0sKVRo1.js +73 -0
  50. package/dist/envCommand-DPgdV1Bq.js +60 -0
  51. package/dist/evalCommand-6RUfPen4.js +118 -0
  52. package/dist/evolveCommand-DHpkgjgH.js +281 -0
  53. package/dist/fileTaxonomy-CJfgOllU.js +457 -0
  54. package/dist/frameworkTableAssembly-BGHmck-x.js +2 -0
  55. package/dist/{frameworkTableAssembly-BwIrO5nv.js → frameworkTableAssembly-DkkP6BgC.js} +184 -148
  56. package/dist/generateCommand-oibemh97.js +147 -0
  57. package/dist/index.d.ts +45 -0
  58. package/dist/index.js +4 -3
  59. package/dist/infoCommand-BJw9nLUR.js +60 -0
  60. package/dist/{inspect-BUUjt773.js → inspect-CBqFtAKA.js} +82 -40
  61. package/dist/inspect-C_T_WGvl.js +2 -0
  62. package/dist/inspectCmd-Bppy-GGw.js +224 -0
  63. package/dist/inspectFetch-Cm8_wVvp.js +151 -0
  64. package/dist/inspectMetrics-CfdKLh6t.js +72 -0
  65. package/dist/loadEnv-D9nEOClM.js +44 -0
  66. package/dist/logFileSink-C_D2wRN1.js +105 -0
  67. package/dist/logsCmd-CCca3KRZ.js +260 -0
  68. package/dist/manifestBuild-ChsKAhmn.js +2 -0
  69. package/dist/{manifestBuild-BLrVuSlM.js → manifestBuild-sxpwdKY1.js} +1 -1
  70. package/dist/metaCommands-7MJfZ5cf.js +196 -0
  71. package/dist/migrate-CBwOt_iV.js +83 -0
  72. package/dist/mssqlClusterPatch-_4cE_nun.js +44 -0
  73. package/dist/newCommand-COWOJ1_E.js +156 -0
  74. package/dist/nodeEnvironment-cGFAj1J8.js +28 -0
  75. package/dist/packageCommand-Cug_3Ogl.js +271 -0
  76. package/dist/pageConvention-cEiRxdab.js +5 -0
  77. package/dist/privacyCommand-C-Df56U_.js +146 -0
  78. package/dist/projectScaffold-DmzEKHib.js +2 -0
  79. package/dist/projectScaffold-LMMtaavR.js +814 -0
  80. package/dist/renderModeScan-D7J1B7Kw.js +105 -0
  81. package/dist/renderProfile-1OWWAAtx.js +81 -0
  82. package/dist/runtimeRegistry-DMeKfTHP.js +81 -0
  83. package/dist/runtimeTrace-CRxalXTs.js +91 -0
  84. package/dist/scheduleCmd--jksTrf6.js +69 -0
  85. package/dist/scheduleManifestCmd-D2x0CTTY.js +249 -0
  86. package/dist/schemaIr-UJybUUZW.js +103 -0
  87. package/dist/{sdkgen-C81QIkiL.js → sdkgen-CYJscZC7.js} +111 -209
  88. package/dist/seedRunner-TFHHiToI.js +329 -0
  89. package/dist/serveCommand-B_isw7q4.js +1647 -0
  90. package/dist/serveCommand-DOvbgRnQ.js +2 -0
  91. package/dist/serveEntry.js +5 -5
  92. package/dist/serverlessCommand-CfJZy6dS.js +482 -0
  93. package/dist/start-9LiUOfES.js +1087 -0
  94. package/dist/start-B-9Nsp-S.js +3 -0
  95. package/dist/startEntry.js +2 -2
  96. package/dist/staticCommand-Dr2M6tpU.js +304 -0
  97. package/dist/storageCommand-Co6NfLqN.js +42 -0
  98. package/dist/templates-De8IR5-c.js +102 -0
  99. package/dist/test-CI6iDsYc.js +115 -0
  100. package/dist/tracesCmd-CkEZQrtt.js +232 -0
  101. package/dist/tsconfigPaths-BWXBWgcl.js +107 -0
  102. package/dist/tsxLoader-EuXmSJ1K.js +51 -0
  103. package/dist/typecheckCommand-BlsWiCNq.js +61 -0
  104. package/dist/updateCommand-Bkptutss.js +585 -0
  105. package/dist/updateCommand-us1_hdIC.js +2 -0
  106. package/dist/{inspectMetrics-1xzTKAFx.js → webDev-CBYvPqQr.js} +975 -1559
  107. package/dist/webDev-Cg-fFiyd2.js +2 -0
  108. package/dist/webhookDiscovery-CrGAfhIG.js +2 -0
  109. package/dist/webhookDiscovery-D7VaeMlz.js +51 -0
  110. package/dist/webhooksCommand-CID96Rga.js +267 -0
  111. package/dist/workflowsCmd-D1VTmLMY.js +608 -0
  112. package/package.json +179 -17
  113. package/templates/AGENTS.core.md +58 -3
  114. package/templates/AGENTS.md +64 -7
  115. package/templates/agent-docs/_index.md +6 -4
  116. package/templates/agent-docs/_manifest.json +22 -5
  117. package/templates/agent-docs/ai.md +370 -0
  118. package/templates/agent-docs/authentication.md +265 -31
  119. package/templates/agent-docs/caching.md +6 -0
  120. package/templates/agent-docs/cli.md +794 -50
  121. package/templates/agent-docs/data.md +550 -11
  122. package/templates/agent-docs/database/migrations.md +174 -25
  123. package/templates/agent-docs/database/misc.md +156 -40
  124. package/templates/agent-docs/database/querying.md +19 -1
  125. package/templates/agent-docs/database/scaling.md +60 -0
  126. package/templates/agent-docs/database/schema.md +1 -0
  127. package/templates/agent-docs/database/seedsdialects.md +208 -19
  128. package/templates/agent-docs/database/transactions.md +68 -0
  129. package/templates/agent-docs/deployment.md +69 -3
  130. package/templates/agent-docs/introduction.md +87 -16
  131. package/templates/agent-docs/local-first-mobile.md +79 -4
  132. package/templates/agent-docs/multi-tenancy.md +95 -20
  133. package/templates/agent-docs/observability.md +58 -3
  134. package/templates/agent-docs/plugins/ai-flows.md +161 -2
  135. package/templates/agent-docs/plugins/analytics-postgres.md +1 -1
  136. package/templates/agent-docs/plugins/audit.md +37 -1
  137. package/templates/agent-docs/plugins/auth-social.md +143 -0
  138. package/templates/agent-docs/plugins/auth-workos.md +4 -2
  139. package/templates/agent-docs/plugins/auth.md +131 -6
  140. package/templates/agent-docs/plugins/billing.md +132 -15
  141. package/templates/agent-docs/plugins/cdc-out.md +46 -7
  142. package/templates/agent-docs/plugins/clickhouse.md +1 -1
  143. package/templates/agent-docs/plugins/duckdb.md +1 -1
  144. package/templates/agent-docs/plugins/flags.md +132 -0
  145. package/templates/agent-docs/plugins/governance.md +105 -7
  146. package/templates/agent-docs/plugins/multitenancy.md +9 -4
  147. package/templates/agent-docs/plugins/presence.md +13 -2
  148. package/templates/agent-docs/plugins/ratelimit.md +9 -0
  149. package/templates/agent-docs/plugins/search.md +157 -6
  150. package/templates/agent-docs/plugins/sso-saml.md +47 -8
  151. package/templates/agent-docs/plugins/webhooks.md +105 -0
  152. package/templates/agent-docs/plugins.md +150 -18
  153. package/templates/agent-docs/reference.md +60 -3
  154. package/templates/agent-docs/releases.md +1117 -0
  155. package/templates/agent-docs/routing.md +43 -25
  156. package/templates/agent-docs/scheduling.md +10 -0
  157. package/templates/agent-docs/schema-driven-ui.md +92 -12
  158. package/templates/agent-docs/security.md +426 -0
  159. package/templates/agent-docs/templates/apibackends.md +87 -18
  160. package/templates/agent-docs/templates/appshells.md +32 -14
  161. package/templates/agent-docs/templates/overview.md +13 -8
  162. package/templates/agent-docs/testing.md +211 -14
  163. package/templates/agent-docs/whats-new.md +1700 -104
  164. package/templates/agent-docs/workflows.md +130 -14
  165. package/templates/apps/api-ai/actions/summarize.action.ts +11 -0
  166. package/templates/apps/api-ai/package.json +8 -7
  167. package/templates/apps/api-auth/actions/me.action.ts +13 -0
  168. package/templates/apps/api-auth/package.json +9 -8
  169. package/templates/apps/api-backend/mutations/notes.create.mutation.ts +9 -0
  170. package/templates/apps/api-backend/package.json +12 -8
  171. package/templates/apps/api-backend/queries/notes.query.ts +30 -8
  172. package/templates/apps/api-backend-deactivation/actions/users.get.action.ts +14 -0
  173. package/templates/apps/api-backend-deactivation/mutations/users.create.mutation.ts +8 -0
  174. package/templates/apps/api-backend-deactivation/mutations/users.deactivate.mutation.ts +10 -0
  175. package/templates/apps/api-backend-deactivation/package.json +8 -7
  176. package/templates/apps/api-backend-mail/actions/sendWelcome.action.ts +17 -0
  177. package/templates/apps/api-backend-mail/mutations/notes.create.mutation.ts +9 -0
  178. package/templates/apps/api-backend-mail/package.json +9 -8
  179. package/templates/apps/api-backend-mail/queries/notes.query.ts +30 -8
  180. package/templates/apps/api-backend-mariadb/.env.example +14 -0
  181. package/templates/apps/api-backend-mariadb/mutations/notes.create.mutation.ts +9 -0
  182. package/templates/apps/api-backend-mariadb/package.json +10 -9
  183. package/templates/apps/api-backend-mariadb/queries/notes.query.ts +30 -8
  184. package/templates/apps/api-backend-sqlite/.env.example +14 -0
  185. package/templates/apps/api-backend-sqlite/mutations/notes.create.mutation.ts +9 -0
  186. package/templates/apps/api-backend-sqlite/package.json +9 -8
  187. package/templates/apps/api-backend-sqlite/queries/notes.query.ts +30 -8
  188. package/templates/apps/api-backend-storage/actions/uploadAvatar.action.ts +13 -0
  189. package/templates/apps/api-backend-storage/actions/uploadDocument.action.ts +12 -0
  190. package/templates/apps/api-backend-storage/mutations/notes.create.mutation.ts +9 -0
  191. package/templates/apps/api-backend-storage/package.json +9 -8
  192. package/templates/apps/api-backend-storage/queries/notes.query.ts +30 -8
  193. package/templates/apps/api-cms/actions/content.get.action.ts +7 -0
  194. package/templates/apps/api-cms/actions/content.types.action.ts +6 -0
  195. package/templates/apps/api-cms/actions/me.action.ts +13 -0
  196. package/templates/apps/api-cms/app.config.ts +19 -0
  197. package/templates/apps/api-cms/authz.ts +63 -0
  198. package/templates/apps/api-cms/mutations/content.publish.mutation.ts +10 -0
  199. package/templates/apps/api-cms/mutations/content.saveDraft.mutation.ts +10 -0
  200. package/templates/apps/api-cms/mutations/content.unpublish.mutation.ts +5 -0
  201. package/templates/apps/api-cms/package.json +11 -10
  202. package/templates/apps/api-cms/queries/content.list.query.ts +23 -7
  203. package/templates/apps/api-cms/tests/accessDecisions.test.ts +121 -0
  204. package/templates/apps/api-cms/tests/content.descriptors.test.ts +8 -4
  205. package/templates/apps/api-collab/mutations/documents.create.mutation.ts +8 -0
  206. package/templates/apps/api-collab/mutations/documents.setBody.mutation.ts +13 -0
  207. package/templates/apps/api-collab/package.json +9 -8
  208. package/templates/apps/api-collab/queries/documents.query.ts +19 -7
  209. package/templates/apps/api-data-advanced/package.json +9 -8
  210. package/templates/apps/api-data-advanced/queries/authors.withBooks.query.ts +12 -0
  211. package/templates/apps/api-data-advanced/queries/books.search.query.ts +9 -0
  212. package/templates/apps/api-durable/mutations/orders.approve.mutation.ts +17 -0
  213. package/templates/apps/api-durable/mutations/orders.place.mutation.ts +9 -0
  214. package/templates/apps/api-durable/package.json +9 -8
  215. package/templates/apps/api-feature-flags/actions/notes.export.action.ts +16 -0
  216. package/templates/apps/api-feature-flags/mutations/notes.create.mutation.ts +12 -0
  217. package/templates/apps/api-feature-flags/package.json +10 -9
  218. package/templates/apps/api-governance/README.md +30 -8
  219. package/templates/apps/api-governance/actions/profiles.get.action.server.ts +17 -1
  220. package/templates/apps/api-governance/actions/profiles.get.action.ts +29 -4
  221. package/templates/apps/api-governance/database/schema.ts +16 -4
  222. package/templates/apps/api-governance/mutations/profiles.create.mutation.ts +12 -0
  223. package/templates/apps/api-governance/package.json +9 -8
  224. package/templates/apps/api-kv/actions/sync.pull.action.ts +15 -0
  225. package/templates/apps/api-kv/actions/sync.reset.action.ts +13 -0
  226. package/templates/apps/api-kv/actions/sync.status.action.ts +7 -0
  227. package/templates/apps/api-kv/package.json +9 -8
  228. package/templates/apps/api-kv/queries/events.list.query.ts +19 -8
  229. package/templates/apps/api-moderation/mutations/comments.create.mutation.ts +11 -0
  230. package/templates/apps/api-moderation/mutations/posts.create.mutation.ts +13 -0
  231. package/templates/apps/api-moderation/package.json +9 -8
  232. package/templates/apps/api-observability/mutations/notes.create.mutation.ts +8 -0
  233. package/templates/apps/api-observability/package.json +9 -8
  234. package/templates/apps/api-observability/queries/notes.list.query.ts +13 -0
  235. package/templates/apps/api-ratelimit/mutations/notes.create.mutation.ts +14 -0
  236. package/templates/apps/api-ratelimit/package.json +9 -8
  237. package/templates/apps/api-rbac/package.json +9 -8
  238. package/templates/apps/api-rest/package.json +8 -7
  239. package/templates/apps/api-saas/mutations/projects.create.mutation.ts +13 -0
  240. package/templates/apps/api-saas/package.json +12 -11
  241. package/templates/apps/api-saas/queries/projects.list.query.ts +11 -0
  242. package/templates/apps/api-saas-starter/actions/me.action.ts +13 -0
  243. package/templates/apps/api-saas-starter/app.config.ts +19 -0
  244. package/templates/apps/api-saas-starter/authz.ts +75 -0
  245. package/templates/apps/api-saas-starter/mutations/invites.create.mutation.ts +10 -0
  246. package/templates/apps/api-saas-starter/mutations/projects.create.mutation.ts +9 -0
  247. package/templates/apps/api-saas-starter/package.json +15 -11
  248. package/templates/apps/api-saas-starter/queries/invites.list.query.ts +19 -8
  249. package/templates/apps/api-saas-starter/queries/projects.list.query.ts +18 -7
  250. package/templates/apps/api-saas-starter/tests/accessDecisions.test.ts +135 -0
  251. package/templates/apps/api-search/mutations/articles.create.mutation.ts +14 -0
  252. package/templates/apps/api-search/package.json +9 -8
  253. package/templates/apps/api-search/queries/articles.list.query.ts +21 -8
  254. package/templates/apps/api-status/README.md +10 -3
  255. package/templates/apps/api-status/app.config.ts +8 -3
  256. package/templates/apps/api-status/authz.ts +5 -3
  257. package/templates/apps/api-status/package.json +9 -8
  258. package/templates/apps/api-status/queries/components.list.query.ts +14 -6
  259. package/templates/apps/api-status/queries/incidents.live.query.ts +23 -10
  260. package/templates/apps/api-status/queries/updates.list.query.ts +16 -9
  261. package/templates/apps/api-status/tests/status.test.ts +9 -1
  262. package/templates/apps/api-versioning/actions/documents.asOf.action.ts +12 -0
  263. package/templates/apps/api-versioning/actions/documents.history.action.ts +13 -0
  264. package/templates/apps/api-versioning/mutations/documents.create.mutation.ts +9 -0
  265. package/templates/apps/api-versioning/mutations/documents.update.mutation.ts +12 -0
  266. package/templates/apps/api-versioning/package.json +9 -8
  267. package/templates/apps/api-webhooks/mutations/orders.fulfill.mutation.ts +16 -0
  268. package/templates/apps/api-webhooks/package.json +10 -9
  269. package/templates/apps/api-webhooks/queries/orders.list.query.ts +10 -0
  270. package/templates/apps/changelog/package.json +8 -6
  271. package/templates/apps/edge-functions/package.json +2 -2
  272. package/templates/apps/frontend-admin/package.json +10 -8
  273. package/templates/apps/frontend-admin/src/lib/admin.ts +20 -9
  274. package/templates/apps/frontend-admin/src/locales/de.ts +11 -1
  275. package/templates/apps/frontend-admin/src/locales/en.ts +13 -1
  276. package/templates/apps/frontend-admin/src/pages/admin/[entity]/page.tsx +65 -22
  277. package/templates/apps/frontend-admin/src/pages/admin/entity.test.tsx +130 -23
  278. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +3 -2
  279. package/templates/apps/frontend-admin/src/pages/admin/page.test.tsx +19 -2
  280. package/templates/apps/frontend-admin/src/pages/admin/page.tsx +9 -4
  281. package/templates/apps/frontend-app/app.config.ts +4 -3
  282. package/templates/apps/frontend-app/package.json +11 -8
  283. package/templates/apps/frontend-app/src/lib/api.ts +25 -0
  284. package/templates/apps/frontend-app/src/pages/page.test.tsx +130 -82
  285. package/templates/apps/frontend-app/src/pages/page.tsx +14 -18
  286. package/templates/apps/frontend-auth/package.json +10 -8
  287. package/templates/apps/frontend-blank/package.json +9 -7
  288. package/templates/apps/frontend-cms/package.json +11 -9
  289. package/templates/apps/frontend-collab/package.json +12 -9
  290. package/templates/apps/frontend-collab/src/pages/page.test.tsx +122 -78
  291. package/templates/apps/frontend-contact/package.json +9 -7
  292. package/templates/apps/frontend-dashboard/package.json +9 -7
  293. package/templates/apps/frontend-docs/package.json +9 -7
  294. package/templates/apps/frontend-i18n/package.json +8 -6
  295. package/templates/apps/frontend-landing/package.json +9 -7
  296. package/templates/apps/frontend-portal/package.json +10 -8
  297. package/templates/apps/frontend-saas/app.config.ts +10 -6
  298. package/templates/apps/frontend-saas/package.json +10 -8
  299. package/templates/apps/frontend-saas/src/lib/api.ts +27 -32
  300. package/templates/apps/frontend-saas/src/pages/dashboard/billing/page.tsx +7 -8
  301. package/templates/apps/frontend-saas/src/pages/dashboard/page.test.tsx +27 -3
  302. package/templates/apps/frontend-saas/src/pages/dashboard/page.tsx +4 -4
  303. package/templates/apps/frontend-saas/src/pages/dashboard/team/page.tsx +3 -4
  304. package/templates/apps/frontend-spa/package.json +9 -7
  305. package/templates/apps/frontend-ssr/package.json +9 -7
  306. package/templates/apps/frontend-ssr-api/package.json +10 -8
  307. package/templates/apps/frontend-static-blog/package.json +8 -6
  308. package/templates/apps/frontend-status/package.json +10 -8
  309. package/templates/apps/mobile-app/README.md +1 -0
  310. package/templates/apps/mobile-app/package.json +4 -2
  311. package/templates/apps/mobile-app/src/app/index.tsx +22 -12
  312. package/templates/apps/mobile-app/src/app/orders/[id].tsx +1 -1
  313. package/templates/apps/mobile-app/src/lib/api.ts +34 -0
  314. package/templates/apps/mobile-app/voltro.mobile.ts +4 -2
  315. package/templates/baselines/bare/.env.example +14 -0
  316. package/templates/baselines/bare/baseline.json +4 -4
  317. package/templates/baselines/compose/.env.example +14 -0
  318. package/templates/baselines/compose/README.md +1 -1
  319. package/templates/baselines/compose/baseline.json +5 -5
  320. package/templates/baselines/compose-mariadb/.env.example +14 -0
  321. package/templates/baselines/compose-mariadb/README.md +1 -1
  322. package/templates/baselines/compose-mariadb/baseline.json +5 -5
  323. package/templates/baselines/helm/.env.example +14 -0
  324. package/templates/baselines/helm/baseline.json +4 -4
  325. package/dist/apiBuild-C-x9YacA.js +0 -2
  326. package/dist/checkCommand-DRovTKza.js +0 -2
  327. package/dist/commands-CJfepbm4.js +0 -11541
  328. package/dist/dbCommand-b1gum4td.js +0 -2
  329. package/dist/dev-iiMtlkfs.js +0 -3
  330. package/dist/devActivity-BhIu6ncs.js +0 -159
  331. package/dist/frameworkTableAssembly-D-EebUQX.js +0 -2
  332. package/dist/inspect-mmBuRXmy.js +0 -2
  333. package/dist/manifestBuild-Dj8Jjoto.js +0 -2
  334. package/dist/seedRunner-Bqxgp7HZ.js +0 -230
  335. package/dist/serveCommand-DdaM4Hup.js +0 -1608
  336. package/dist/start-C0koT0UO.js +0 -1084
  337. /package/templates/apps/api-ai/actions/{summarize.action.server.tsx → summarize.action.server.ts} +0 -0
@@ -0,0 +1,105 @@
1
+ import { join as e } from "node:path";
2
+ import { readFile as t } from "node:fs/promises";
3
+ //#region src/isrCache.ts
4
+ var n = () => {
5
+ let e = /* @__PURE__ */ new Map();
6
+ return {
7
+ get(t) {
8
+ return e.get(t);
9
+ },
10
+ set(t, n) {
11
+ e.set(t, n);
12
+ },
13
+ invalidate(t) {
14
+ e.delete(t);
15
+ },
16
+ invalidateBy(t) {
17
+ let n = 0;
18
+ for (let r of e.keys()) t(r) && (e.delete(r), n++);
19
+ return n;
20
+ },
21
+ clear() {
22
+ e.clear();
23
+ },
24
+ size() {
25
+ return e.size;
26
+ },
27
+ snapshot() {
28
+ return Array.from(e.entries());
29
+ }
30
+ };
31
+ }, r = (e) => {
32
+ if (typeof e == "number" && Number.isFinite(e) && e > 0) return e * 1e3;
33
+ if (typeof e != "string") return null;
34
+ let t = /^\s*(\d+)\s*(s|seconds?|m|minutes?|h|hours?|d|days?)\s*$/i.exec(e);
35
+ if (!t) return null;
36
+ let n = parseInt(t[1], 10);
37
+ if (!Number.isFinite(n) || n <= 0) return null;
38
+ let r = t[2].toLowerCase();
39
+ return r === "s" || r.startsWith("second") ? n * 1e3 : r === "m" || r.startsWith("minute") ? n * 6e4 : r === "h" || r.startsWith("hour") ? n * 36e5 : r === "d" || r.startsWith("day") ? n * 864e5 : null;
40
+ }, i = (e, t = {}) => {
41
+ let n = [e];
42
+ return t.tenant !== void 0 && t.tenant !== "" && n.push(`tenant=${t.tenant}`), t.locale !== void 0 && t.locale !== "" && n.push(`lang=${t.locale}`), n.join("|");
43
+ }, a = (e, t) => e.expiresAt > t, o = (e, t) => e.expiresAt <= t && e.servableUntil > t, s = [
44
+ "static",
45
+ "spa",
46
+ "ssr",
47
+ "isr"
48
+ ], c = (e) => typeof e == "string" && s.includes(e), l = s.map((e) => `'${e}'`).join(" | "), u = (e, t) => `[voltro] ${e}: unknown renderMode '${t}'.\n Valid values: ${l}.${t === "client" || t === "csr" || t === "browser" ? "\n A page that renders only in the browser is 'spa': it is skipped by the prerender and mounts on the client. If its route has a layout, that layout still renders server-side as an SSR shell." : t === "server" || t === "dynamic" ? "\n A page rendered per request is 'ssr'." : t === "ssg" || t === "prerender" ? "\n A page rendered once at build time is 'static' (the default)." : ""}`, d = class extends Error {
49
+ page;
50
+ value;
51
+ name = "InvalidRenderModeError";
52
+ constructor(e, t) {
53
+ super(u(e, t)), this.page = e, this.value = t;
54
+ }
55
+ }, f = (e, t = "<page>") => {
56
+ if (e.renderMode !== void 0 && e.renderMode !== null) {
57
+ if (!c(e.renderMode)) throw new d(t, String(e.renderMode));
58
+ return e.renderMode;
59
+ }
60
+ return e.dynamic === "force-dynamic" ? "ssr" : (e.dynamic, "static");
61
+ }, p = (e, t = "<page>") => ({
62
+ renderMode: f(e, t),
63
+ tenantAware: e.tenantAware === !0,
64
+ revalidateMs: r(e.revalidate),
65
+ staleWhileRevalidateMs: r(e.staleWhileRevalidate) ?? 0,
66
+ cacheInvalidatesOn: Array.isArray(e.cacheInvalidatesOn) ? e.cacheInvalidatesOn : [],
67
+ interactive: e.interactive ?? "full",
68
+ hasLoader: typeof e.loader == "function",
69
+ hasMeta: e.meta != null,
70
+ hasGetStaticPaths: typeof e.getStaticPaths == "function"
71
+ }), m = /export\s+const\s+renderMode\s*(?::[^=]+)?=\s*['"]([^'"]*)['"]/, h = (e) => m.exec(e)?.[1] ?? null, g = /export\s*\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g, _ = (e) => {
72
+ g.lastIndex = 0;
73
+ let t;
74
+ for (; (t = g.exec(e)) !== null;) {
75
+ let e = t[2];
76
+ if (e.startsWith(".")) for (let n of t[1].split(",")) {
77
+ let t = n.lastIndexOf(" as ");
78
+ if ((t === -1 ? n : n.slice(t + 4)).trim() === "renderMode") return e;
79
+ }
80
+ }
81
+ return null;
82
+ }, v = /export\s*\{([^}]*)\}/g, y = (e) => {
83
+ if (/export\s+default\b/.test(e)) return !0;
84
+ v.lastIndex = 0;
85
+ let t;
86
+ for (; (t = v.exec(e)) !== null;) for (let e of t[1].split(",")) {
87
+ let t = e.lastIndexOf(" as ");
88
+ if ((t === -1 ? e : e.slice(t + 4)).trim() === "default") return !0;
89
+ }
90
+ return !1;
91
+ }, b = async (n, r) => {
92
+ let i = (await Promise.all(r.map(async (r) => {
93
+ let i;
94
+ try {
95
+ i = await t(e(n, r.file), "utf8");
96
+ } catch {
97
+ return null;
98
+ }
99
+ let a = h(i);
100
+ return a !== null && !c(a) ? u(e("src", "pages", r.file), a) : y(i) ? null : `${e("src", "pages", r.file)} is a route (a \`page.tsx\` under src/pages/) but exports no default.\n\n A page's default export IS its component — the router has nothing to render without it,\n and the failure would otherwise surface only in \`voltro build\`'s prerender as\n "SSR received a descriptor with no Component", long after the file was written.\n\n Fix: \`export default function Page() { … }\`, or re-export another page's component\n (\`export { default } from '../page'\`). If this file is NOT a route, rename it —\n only the reserved names route, and anything else under src/pages/ is ordinary code\n that may live beside the page that uses it.`;
101
+ }))).filter((e) => e !== null);
102
+ if (i.length !== 0) throw Error(i.join("\n\n"));
103
+ };
104
+ //#endregion
105
+ export { p as a, f as c, o as d, n as f, s as i, i as l, h as n, c as o, r as p, _ as r, u as s, b as t, a as u };
@@ -0,0 +1,81 @@
1
+ import { m as e } from "./fileConventions-Cof68_BL.js";
2
+ import { i as t, n, o as r, r as i, s as a } from "./renderModeScan-D7J1B7Kw.js";
3
+ import { dirname as o, join as s, relative as c, resolve as l } from "node:path";
4
+ import { Effect as u } from "effect";
5
+ import { readFile as d, readdir as f } from "node:fs/promises";
6
+ //#region src/static/renderProfile.ts
7
+ var p = /* @__PURE__ */ new Set([
8
+ "node_modules",
9
+ "dist",
10
+ "build",
11
+ ".turbo",
12
+ ".vite",
13
+ ".framework",
14
+ ".git"
15
+ ]), m = /export\s+const\s+dynamic\s*=\s*['"]force-(dynamic|static)['"]/, h = /export\s+(?:const|async\s+function|function)\s+getStaticPaths\b/, g = 5, _ = async (e) => {
16
+ for (let t of [
17
+ e,
18
+ `${e}.tsx`,
19
+ `${e}.ts`,
20
+ s(e, "index.tsx"),
21
+ s(e, "index.ts")
22
+ ]) if (/\.[jt]sx?$/.test(t)) try {
23
+ return {
24
+ src: await d(t, "utf8"),
25
+ path: t
26
+ };
27
+ } catch {}
28
+ return null;
29
+ }, v = async (e, t, s) => {
30
+ let c = e, u = t, d = s;
31
+ for (let e = 0; e <= g; e++) {
32
+ let e = n(c);
33
+ if (e !== null) {
34
+ if (!r(e)) throw Error(a(u, e));
35
+ return e;
36
+ }
37
+ let t = m.exec(c);
38
+ if (t) return t[1] === "dynamic" ? "ssr" : "static";
39
+ let s = i(c);
40
+ if (s === null) return "static";
41
+ let f = await _(l(o(d), s));
42
+ if (f === null) return "static";
43
+ c = f.src, u = f.path, d = f.path;
44
+ }
45
+ return "static";
46
+ }, y = async (n) => {
47
+ let r = s(n, "src", "pages"), i = [], a = async (t) => {
48
+ let n;
49
+ try {
50
+ n = await f(t, { withFileTypes: !0 });
51
+ } catch {
52
+ return;
53
+ }
54
+ for (let o of n) {
55
+ if (p.has(o.name)) continue;
56
+ let n = s(t, o.name);
57
+ if (o.isDirectory()) await a(n);
58
+ else if (o.isFile() && e.test(o.name)) {
59
+ let e = c(r, n), t = await d(n, "utf8");
60
+ i.push({
61
+ file: e,
62
+ mode: await v(t, s("src", "pages", e), n),
63
+ dynamic: e.includes("["),
64
+ hasStaticPaths: h.test(t)
65
+ });
66
+ }
67
+ }
68
+ };
69
+ await a(r);
70
+ let o = Object.fromEntries(t.map((e) => [e, 0]));
71
+ for (let e of i) o[e.mode]++;
72
+ let l = i.filter((e) => e.mode === "static" && e.dynamic && !e.hasStaticPaths).map((e) => e.file);
73
+ return {
74
+ pages: i,
75
+ counts: o,
76
+ dynamicMissing: l,
77
+ staticSafe: o.ssr === 0 && o.isr === 0 && l.length === 0
78
+ };
79
+ }, b = (e) => u.promise(() => y(e));
80
+ //#endregion
81
+ export { y as n, b as t };
@@ -0,0 +1,81 @@
1
+ import { join as e } from "node:path";
2
+ import { promises as t } from "node:fs";
3
+ import { homedir as n } from "node:os";
4
+ //#region src/runtimeRegistry.ts
5
+ var r = e(n(), ".voltro"), i = e(r, "runtime-registry.json"), a = 3e4, o = () => {
6
+ let e = Math.random().toString(36).slice(2, 10);
7
+ return `${i}.${process.pid}.${Date.now()}.${e}.tmp`;
8
+ }, s = async () => {
9
+ await t.mkdir(r, { recursive: !0 });
10
+ }, c = async () => {
11
+ try {
12
+ let e = await t.readFile(i, "utf8"), n = JSON.parse(e);
13
+ return n.version !== 1 || !Array.isArray(n.apps) ? {
14
+ version: 1,
15
+ apps: []
16
+ } : n;
17
+ } catch {
18
+ return {
19
+ version: 1,
20
+ apps: []
21
+ };
22
+ }
23
+ }, l = async (e) => {
24
+ await s();
25
+ let n = o();
26
+ try {
27
+ await t.writeFile(n, JSON.stringify(e, null, 2), {
28
+ encoding: "utf8",
29
+ mode: 384
30
+ }), await t.rename(n, i), await t.chmod(i, 384).catch(() => {});
31
+ } catch (e) {
32
+ try {
33
+ await t.unlink(n);
34
+ } catch {}
35
+ throw e;
36
+ }
37
+ }, u = (e) => {
38
+ try {
39
+ return process.kill(e, 0), !0;
40
+ } catch {
41
+ return !1;
42
+ }
43
+ }, d = (e) => {
44
+ let t = Date.now();
45
+ return e.filter((e) => u(e.pid) ? t - new Date(e.heartbeatAt).getTime() < a : !1);
46
+ }, f = async () => {
47
+ let e = await c(), t = d(e.apps);
48
+ if (t.length === e.apps.length) return e;
49
+ try {
50
+ await l({
51
+ version: 1,
52
+ apps: t
53
+ });
54
+ } catch {}
55
+ return {
56
+ version: 1,
57
+ apps: t
58
+ };
59
+ }, p = async (e) => {
60
+ let t = await c(), n = (/* @__PURE__ */ new Date()).toISOString(), r = t.apps.findIndex((t) => t.id === e.id), i = e.inspectToken ?? process.env.VOLTRO_INSPECT_TOKEN, a = {
61
+ ...e,
62
+ ...i !== void 0 && i !== "" ? { inspectToken: i } : {},
63
+ registeredAt: r >= 0 ? t.apps[r].registeredAt : n,
64
+ heartbeatAt: n
65
+ };
66
+ await l({
67
+ version: 1,
68
+ apps: r >= 0 ? t.apps.map((e, t) => t === r ? a : e) : [...t.apps, a]
69
+ });
70
+ }, m = async (e) => {
71
+ try {
72
+ let t = await c(), n = t.apps.filter((t) => t.id !== e);
73
+ if (n.length === t.apps.length) return;
74
+ await l({
75
+ version: 1,
76
+ apps: n
77
+ });
78
+ } catch {}
79
+ }, h = (e, t, n) => `${e}:${t}:${n}`;
80
+ //#endregion
81
+ export { p as i, f as n, m as r, h as t };
@@ -0,0 +1,91 @@
1
+ import { n as e } from "./apiBuild-DZF_f0_I.js";
2
+ import { join as t, resolve as n, sep as r } from "node:path";
3
+ import { existsSync as i, promises as a } from "node:fs";
4
+ import { createLogger as o } from "@voltro/logger";
5
+ import { createRequire as s } from "node:module";
6
+ //#region src/runtimeTrace.ts
7
+ var c = o({ scope: "voltro:build" }), l = [
8
+ [
9
+ ".framework",
10
+ "dist-web",
11
+ "startBundle",
12
+ "startEntry.js"
13
+ ],
14
+ [
15
+ ".framework",
16
+ "dist",
17
+ "server",
18
+ "ssrEntry.js"
19
+ ],
20
+ [
21
+ ".framework",
22
+ "dist",
23
+ "server",
24
+ "appConfig.js"
25
+ ],
26
+ [
27
+ ".framework",
28
+ "dist-api",
29
+ "serveBundle",
30
+ "serveEntry.js"
31
+ ]
32
+ ], u = ["pg", ...e.filter((e) => !e.includes("*"))], d = async (e) => {
33
+ let o = t(e, "node_modules");
34
+ if (!i(o)) return null;
35
+ let d;
36
+ try {
37
+ ({nodeFileTrace: d} = await import("@vercel/nft"));
38
+ } catch {
39
+ return c.warn("runtime trace skipped — @vercel/nft not installed (image keeps the full node_modules)"), null;
40
+ }
41
+ let f = l.map((n) => t(e, ...n)).filter((e) => i(e));
42
+ if (f.length === 0) return null;
43
+ let p = s(t(e, "_.js")), m = 0;
44
+ for (let e of u) try {
45
+ f.push(p.resolve(e)), m++;
46
+ } catch {}
47
+ let { fileList: h } = await d(f, { base: e }), g = /* @__PURE__ */ new Set();
48
+ for (let t of h) {
49
+ let i = n(e, t);
50
+ i.startsWith(o + r) && g.add(i);
51
+ }
52
+ let _ = 0, v = async (e) => {
53
+ let n = !1;
54
+ for (let r of await a.readdir(e, { withFileTypes: !0 })) {
55
+ let i = t(e, r.name);
56
+ if (r.isSymbolicLink()) {
57
+ n = !0;
58
+ continue;
59
+ }
60
+ r.isDirectory() ? await v(i) ? n = !0 : await a.rmdir(i).catch(() => {
61
+ n = !0;
62
+ }) : g.has(i) ? n = !0 : (await a.rm(i).catch(() => {}), _++);
63
+ }
64
+ return n;
65
+ }, y = await v(o);
66
+ return y || await a.rm(o, {
67
+ recursive: !0,
68
+ force: !0
69
+ }).catch(() => {}), c.info("runtime trace: pruned node_modules to the reachable set", {
70
+ nativeLeaves: m > 0 ? u.filter((e) => {
71
+ try {
72
+ return !!p.resolve(e);
73
+ } catch {
74
+ return !1;
75
+ }
76
+ }).join(", ") : "none",
77
+ filesRemoved: _,
78
+ nodeModules: y ? "pruned" : "removed (fully self-contained)"
79
+ }), m;
80
+ }, f = async (e) => {
81
+ let t = e.find((e) => !e.startsWith("-"));
82
+ if (!t) return c.error("usage: voltro prune-runtime <deploy-dir>"), 1;
83
+ try {
84
+ await d(n(t));
85
+ } catch (e) {
86
+ c.warn("runtime trace failed — image keeps the full node_modules (not fatal)", {}, e);
87
+ }
88
+ return 0;
89
+ };
90
+ //#endregion
91
+ export { f as runPruneRuntimeCommand };
@@ -0,0 +1,69 @@
1
+ import { n as e } from "./cliOutput-D1tSBoRM.js";
2
+ import { n as t, o as n, r, t as i } from "./inspectFetch-Cm8_wVvp.js";
3
+ import { ansi as a } from "@voltro/logger";
4
+ //#region src/scheduleCmd.ts
5
+ var o = () => {
6
+ console.log(`${a.bold("voltro schedule")} — operate on registered schedules
7
+
8
+ ${a.bold("run <name>")} fire the named schedule once, now
9
+
10
+ Options
11
+ --process NAME target one app by name (default: every live api)
12
+ --trigger manual|external
13
+ how the run is recorded (default: manual)
14
+ --format pretty|json
15
+ --url URL address a process directly instead of via the local registry
16
+
17
+ Examples
18
+ voltro schedule run nightly-reconcile
19
+ voltro schedule run nightly-reconcile --process billing --format json
20
+
21
+ The target must expose the inspect surface: set ${a.bold("VOLTRO_INSPECT_TOKEN")} on the
22
+ server and in this shell. \`voltro dev\` mints one per project; \`serve\` / \`start\`
23
+ never mint — inspect stays closed until an operator opens it.`);
24
+ }, s = (t, n, r, i) => {
25
+ if (i === "json") {
26
+ e({
27
+ app: t,
28
+ schedule: n,
29
+ runId: r
30
+ });
31
+ return;
32
+ }
33
+ if (r === null) {
34
+ console.log(`${a.yellow("○")} ${t}: ${a.bold(n)} not started — no run id.\n Another replica holds the coordination lock, or the previous run is still going and this schedule's onOverlap is 'skip'.`);
35
+ return;
36
+ }
37
+ console.log(`${a.green("✓")} ${t}: ${a.bold(n)} fired — run ${a.bold(r)}`), console.log(` watch it: voltro inspect schedules --process ${t}`);
38
+ }, c = async (e) => {
39
+ let [c, ...l] = e;
40
+ if (c === void 0 || c === "--help" || c === "-h") return o(), +(c === void 0);
41
+ if (c !== "run") return console.error(`voltro schedule: unknown subcommand "${c}" (expected: run)`), 1;
42
+ let u = l.find((e) => !e.startsWith("-"));
43
+ if (u === void 0) return console.error("voltro schedule run: a schedule name is required — `voltro schedule run <name>`"), 1;
44
+ let d = t(l);
45
+ if ("error" in d) return console.error(`voltro schedule run: ${d.error}`), 1;
46
+ let { format: f } = d, { process: p, target: m, rest: h, error: g } = r(d.rest);
47
+ if (g !== void 0) return console.error(`voltro schedule run: ${g}`), 1;
48
+ let _ = h[h.indexOf("--trigger") + 1], v = h.includes("--trigger") && _ === "external" ? "external" : "manual", y = await n(p, m);
49
+ if (y.length === 0) return console.error("voltro schedule run: no live api found.\n Start one (`voltro dev` / `voltro serve`), or address it directly with --url."), 1;
50
+ let b = 0;
51
+ for (let e of y) {
52
+ let t = await i(e, `/_voltro/inspect/schedules/${encodeURIComponent(u)}/fire?trigger=${v}`, { method: "POST" });
53
+ if (t.kind === "err") {
54
+ b += 1, console.error(`${a.red("✗")} ${e.name}: ${t.error}`);
55
+ continue;
56
+ }
57
+ if (t.status < 200 || t.status >= 300) {
58
+ b += 1;
59
+ let n = t.data, r = n?.message === void 0 ? n?.error === void 0 ? `HTTP ${t.status}` : String(n.error) : String(n.message);
60
+ console.error(`${a.red("✗")} ${e.name}: ${r}`), t.status === 401 && console.error(" Set VOLTRO_INSPECT_TOKEN on the server and in this shell."), t.status === 404 && console.error(" A 404 here means the app is older than this endpoint, or it is a web app (schedules are api-only).");
61
+ continue;
62
+ }
63
+ let n = t.data?.runId ?? null;
64
+ s(e.name, u, n, f);
65
+ }
66
+ return +(b > 0);
67
+ };
68
+ //#endregion
69
+ export { c as runScheduleCommand };
@@ -0,0 +1,249 @@
1
+ import { n as e, t } from "./cliArgs-D4p8n7EE.js";
2
+ import { dirname as n, join as r, resolve as i } from "node:path";
3
+ import { promises as a } from "node:fs";
4
+ import { pathToFileURL as o } from "node:url";
5
+ import { createLogger as s } from "@voltro/logger";
6
+ import { isScheduleDefinition as c } from "@voltro/runtime";
7
+ //#region src/scheduleManifest.ts
8
+ var l = (e) => `/_voltro/schedule/${encodeURIComponent(e)}/fire?trigger=external`, u = (e) => {
9
+ let t = e.trim().split(/\s+/);
10
+ return t.length === 6 ? `6-field (seconds) cron "${e}" can't drive an external scheduler — k8s/gcp/aws are minute-resolution. Use a 5-field expression or trigger:'self'.` : t.length === 5 ? null : `expected a 5-field cron expression, got ${t.length} fields: "${e}"`;
11
+ }, d = (e, t) => {
12
+ let n = t.tokenEnv ?? "VOLTRO_SCHEDULE_TOKEN", r = e.name.toLowerCase().replace(/[^a-z0-9-]/g, "-");
13
+ return `---
14
+ # ${e.description ?? `schedule "${e.name}"`}
15
+ # Generated from defineSchedule("${e.name}") — do not edit by hand;
16
+ # re-run \`voltro schedule-manifest\` after changing the cron.
17
+ apiVersion: batch/v1
18
+ kind: CronJob
19
+ metadata:
20
+ name: ${t.appName}-${r}
21
+ spec:
22
+ schedule: "${e.cron}"
23
+ timeZone: "${e.timezone}"
24
+ concurrencyPolicy: Forbid
25
+ jobTemplate:
26
+ spec:
27
+ backoffLimit: 2
28
+ template:
29
+ spec:
30
+ restartPolicy: Never
31
+ containers:
32
+ - name: trigger
33
+ image: curlimages/curl:8.11.0
34
+ env:
35
+ - name: ${n}
36
+ valueFrom:
37
+ secretKeyRef:
38
+ name: ${t.appName}-schedule
39
+ key: token
40
+ command: ["sh", "-c"]
41
+ args:
42
+ - >
43
+ curl -fsS -X POST
44
+ -H "Authorization: Bearer $(${n})"
45
+ "${t.baseUrl}${l(e.name)}"
46
+ `;
47
+ }, f = (e, t) => {
48
+ let n = t.tokenEnv ?? "VOLTRO_SCHEDULE_TOKEN", r = e.name.toLowerCase().replace(/[^a-z0-9-]/g, "-");
49
+ return `# ${e.description ?? `schedule "${e.name}"`}
50
+ gcloud scheduler jobs create http ${t.appName}-${r} \\
51
+ --schedule="${e.cron}" \\
52
+ --time-zone="${e.timezone}" \\
53
+ --uri="${t.baseUrl}${l(e.name)}" \\
54
+ --http-method=POST \\
55
+ --headers="Authorization=Bearer $${n}"
56
+ `;
57
+ }, p = (e) => {
58
+ let [t, n, r, i, a] = e.trim().split(/\s+/), o = r, s = a, c = null;
59
+ return r === "*" && a === "*" ? s = "?" : r !== "*" && a !== "*" ? c = `AWS cron can't constrain BOTH day-of-month AND day-of-week — review "${e}" manually.` : a === "*" ? s = "?" : o = "?", {
60
+ expr: `cron(${t} ${n} ${o} ${i} ${s} *)`,
61
+ note: c
62
+ };
63
+ }, m = (e, t) => {
64
+ let n = e.name.replace(/[^a-zA-Z0-9-_]/g, "-"), { expr: r, note: i } = p(e.cron);
65
+ return `# ${e.description ?? `schedule "${e.name}"`}${i ? `\n# ⚠ ${i}` : ""}
66
+ # EventBridge Scheduler → HTTP needs an API destination + connection
67
+ # (holds the bearer secret). Create those once, then:
68
+ aws scheduler create-schedule \\
69
+ --name "${t.appName}-${n}" \\
70
+ --schedule-expression "${r}" \\
71
+ --schedule-expression-timezone "${e.timezone}" \\
72
+ --flexible-time-window '{"Mode":"OFF"}' \\
73
+ --target '{
74
+ "Arn": "<API_DESTINATION_ARN>",
75
+ "RoleArn": "<SCHEDULER_ROLE_ARN>",
76
+ "HttpParameters": { "HeaderParameters": {} },
77
+ "Input": ""
78
+ }'
79
+ # Target endpoint: ${t.baseUrl}${l(e.name)}
80
+ `;
81
+ }, h = (e, t) => `// ${e.description ?? `schedule "${e.name}"`}
82
+ // Azure has no direct cron→HTTP primitive. Two options:
83
+ // 1. Logic App with a Recurrence trigger (skeleton below) → HTTP action.
84
+ // 2. An Azure Function with a timer trigger ("${e.cron}") that does the POST.
85
+ // Logic App recurrence skeleton (paste into the App's definition):
86
+ {
87
+ "triggers": {
88
+ "${e.name}": {
89
+ "type": "Recurrence",
90
+ "recurrence": { "frequency": "Minute", "interval": 1, "timeZone": "${e.timezone}" },
91
+ "note": "Translate cron '${e.cron}' into the recurrence schedule; the Recurrence trigger is interval-based, not cron — a timer-trigger Function matches cron exactly."
92
+ }
93
+ },
94
+ "actions": {
95
+ "fire": {
96
+ "type": "Http",
97
+ "inputs": {
98
+ "method": "POST",
99
+ "uri": "${t.baseUrl}${l(e.name)}",
100
+ "headers": { "Authorization": "Bearer @{parameters('scheduleToken')}" }
101
+ }
102
+ }
103
+ }
104
+ }
105
+ `, g = (e, t) => {
106
+ let n = t.tokenEnv ?? "VOLTRO_SCHEDULE_TOKEN", r = e.map((e) => `| \`${e.name}\` | \`${e.cron}\` | ${e.timezone} | \`POST ${l(e.name)}\` |`).join("\n");
107
+ return `# External-trigger schedules — ${t.appName}
108
+
109
+ These schedules use \`trigger: 'external'\`. The app does NOT run an
110
+ in-process timer for them; an outside scheduler must POST the fire
111
+ endpoint on the cadence below. Each call is authenticated with a
112
+ bearer token (env \`${n}\`).
113
+
114
+ | Schedule | Cron | Timezone | Endpoint |
115
+ |---|---|---|---|
116
+ ${r}
117
+
118
+ ## curl shape
119
+
120
+ \`\`\`sh
121
+ curl -fsS -X POST \\
122
+ -H "Authorization: Bearer $${n}" \\
123
+ "${t.baseUrl}/_voltro/schedule/<name>/fire?trigger=external"
124
+ \`\`\`
125
+
126
+ The endpoint returns \`{ "runId": "sr_..." }\` on success (or \`null\`
127
+ when the schedule lost a coordination race — harmless). It is
128
+ idempotent-safe to call at-most-once per intended firing; the
129
+ external scheduler owns the once-only guarantee.
130
+ `;
131
+ }, _ = (e, t, n) => {
132
+ let r = [], i = [];
133
+ for (let t of e) {
134
+ let e = u(t.cron);
135
+ if (e) {
136
+ r.push(`schedule "${t.name}": ${e}`);
137
+ continue;
138
+ }
139
+ i.push(t);
140
+ }
141
+ if (i.length === 0) return {
142
+ files: [],
143
+ warnings: r
144
+ };
145
+ let a = [];
146
+ switch (t) {
147
+ case "kubernetes":
148
+ a.push({
149
+ path: ".voltro/scheduling/kubernetes-cronjobs.yaml",
150
+ content: i.map((e) => d(e, n)).join("\n")
151
+ });
152
+ break;
153
+ case "gcp":
154
+ a.push({
155
+ path: ".voltro/scheduling/gcp-cloud-scheduler.sh",
156
+ content: `#!/bin/sh\n# GCP Cloud Scheduler jobs — generated from defineSchedule(...).\nset -e\n\n${i.map((e) => f(e, n)).join("\n")}`
157
+ });
158
+ break;
159
+ case "aws":
160
+ a.push({
161
+ path: ".voltro/scheduling/aws-eventbridge.sh",
162
+ content: `#!/bin/sh\n# AWS EventBridge Scheduler — generated from defineSchedule(...).\n# Review the cron translations flagged with ⚠ before applying.\nset -e\n\n${i.map((e) => m(e, n)).join("\n")}`
163
+ });
164
+ break;
165
+ case "azure":
166
+ a.push({
167
+ path: ".voltro/scheduling/azure-recurrence.jsonc",
168
+ content: i.map((e) => h(e, n)).join("\n")
169
+ });
170
+ break;
171
+ case "generic": break;
172
+ }
173
+ return a.push({
174
+ path: ".voltro/scheduling/README.md",
175
+ content: g(i, n)
176
+ }), {
177
+ files: a,
178
+ warnings: r
179
+ };
180
+ }, v = s({ scope: "voltro:schedule-manifest" }), y = /* @__PURE__ */ new Set([
181
+ "kubernetes",
182
+ "aws",
183
+ "gcp",
184
+ "azure",
185
+ "generic"
186
+ ]), b = /* @__PURE__ */ new Set([
187
+ "node_modules",
188
+ "dist",
189
+ "build",
190
+ ".turbo",
191
+ ".vite",
192
+ ".git",
193
+ ".framework",
194
+ ".voltro"
195
+ ]), x = async (e) => {
196
+ let t = [], n = async (e) => {
197
+ let i = await a.readdir(e, { withFileTypes: !0 });
198
+ for (let a of i) {
199
+ if (b.has(a.name)) continue;
200
+ let i = r(e, a.name);
201
+ a.isDirectory() ? await n(i) : a.isFile() && /\.cron\.tsx?$/.test(a.name) && t.push(i);
202
+ }
203
+ };
204
+ return await n(e), t;
205
+ }, S = [
206
+ "--provider",
207
+ "--base-url",
208
+ "--token-env"
209
+ ], C = async (s) => {
210
+ let l = i(t(s, S) ?? process.cwd()), u, d = "app";
211
+ try {
212
+ let e = (await import(o(r(l, "app.config.ts")).href)).default ?? {};
213
+ d = typeof e.name == "string" ? e.name : d, u = e.scheduling?.externalProvider;
214
+ } catch {}
215
+ let f = e(s, "--provider") ?? u ?? "generic";
216
+ if (!y.has(f)) return v.error(`unknown --provider "${f}" (expected: ${[...y].join(", ")})`), 1;
217
+ let p = f, m = e(s, "--base-url") ?? process.env.VOLTRO_PUBLIC_URL ?? "https://CHANGE-ME.example.com", h = e(s, "--token-env") ?? "VOLTRO_SCHEDULE_TOKEN", g = "self";
218
+ try {
219
+ g = (await import(o(r(l, "app.config.ts")).href)).default?.scheduling?.trigger ?? "self";
220
+ } catch {}
221
+ let b = await x(l), C = [];
222
+ for (let e of b) {
223
+ let t = (await import(o(e).href)).default;
224
+ c(t) && (t.trigger ?? g) === "external" && C.push({
225
+ name: t.name,
226
+ cron: t.cron,
227
+ timezone: t.timezone,
228
+ ...t.description === void 0 ? {} : { description: t.description }
229
+ });
230
+ }
231
+ if (C.length === 0) return v.info("no external-trigger schedules found — nothing to emit", { scanned: b.length }), 0;
232
+ let { files: w, warnings: T } = _(C, p, {
233
+ baseUrl: m,
234
+ tokenEnv: h,
235
+ appName: d
236
+ });
237
+ for (let e of T) v.warn(e);
238
+ for (let e of w) {
239
+ let t = r(l, e.path);
240
+ await a.mkdir(n(t), { recursive: !0 }), await a.writeFile(t, e.content, "utf8"), v.info("wrote", { path: e.path });
241
+ }
242
+ return v.info("schedule manifests emitted", {
243
+ provider: p,
244
+ schedules: C.length,
245
+ files: w.length
246
+ }), m.includes("CHANGE-ME") && v.warn("base URL not set — pass --base-url https://your-app or set VOLTRO_PUBLIC_URL"), 0;
247
+ };
248
+ //#endregion
249
+ export { C as runScheduleManifest };