@voltro/cli 0.33.0 → 0.35.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 (343) hide show
  1. package/CHANGELOG.md +1968 -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-B8aoJvuw.js +2 -0
  10. package/dist/{apiBuild-h9VHtnlw.js → apiBuild-DYD_ONLD.js} +46 -46
  11. package/dist/{appGraph-gQ_6GkQQ.js → appGraph-KGDPTuTy.js} +1 -1
  12. package/dist/appGraph-zuMGKVYX.js +2 -0
  13. package/dist/appPort-B_HpJ_ck.js +48 -0
  14. package/dist/baselineCommand-C2ClWZN3.js +2 -0
  15. package/dist/baselineCommand-DIttzO8A.js +227 -0
  16. package/dist/bin.js +71 -28
  17. package/dist/build-CD8K4XOr.js +711 -0
  18. package/dist/cacheCommand-DA4OH9xt.js +42 -0
  19. package/dist/capabilitiesCommand-nq_pz5xd.js +123 -0
  20. package/dist/checkCommand-Ct9xkTrS.js +232 -0
  21. package/dist/checkCommand-DKpDLlqu.js +2 -0
  22. package/dist/{cliArgs-qdZSElM3.js → cliArgs-D4p8n7EE.js} +12 -1
  23. package/dist/cliError-BmdYnghb.js +10 -0
  24. package/dist/cliOutput-D1tSBoRM.js +15 -0
  25. package/dist/{cliRuntime-Oh517vCV.js → cliRuntime-Dh7UDinH.js} +20 -20
  26. package/dist/cloudClient-DWL-Hw_T.js +67 -0
  27. package/dist/cloudCmd-Cvv5HGaZ.js +364 -0
  28. package/dist/clusterCmd-D5wsCmA_.js +54 -0
  29. package/dist/codegen-CYM3Zqrf.js +605 -0
  30. package/dist/codegen-ChBi_hVa.js +2 -0
  31. package/dist/codegenCommand-C4YoQIc2.js +30 -0
  32. package/dist/codemodRunner-BnFq3Fgu.js +5384 -0
  33. package/dist/commandRunner-BLAEFLjp.js +47 -0
  34. package/dist/commands-BE8E7zF3.js +816 -0
  35. package/dist/connectionConfig-UFlIEiys.js +66 -0
  36. package/dist/dashboardCommand-D7SgZGaN.js +25 -0
  37. package/dist/dataCommand-BhYwDgg-.js +537 -0
  38. package/dist/dataProfile-dW-PsfLB.js +15 -0
  39. package/dist/dbCommand-DS4b97Is.js +2 -0
  40. package/dist/{dbCommand-DTLKAfbA.js → dbCommand-O8HA63s2.js} +552 -402
  41. package/dist/{dev-C_P8FLSx.js → dev-C7sFZq3m.js} +3670 -3169
  42. package/dist/dev-D2BikO7a.js +3 -0
  43. package/dist/devActivity-Dx_3nnGv.js +100 -0
  44. package/dist/devActivity.js +1 -1
  45. package/dist/dialectDriver-CgXnDfec.js +39 -0
  46. package/dist/discover-C9XKJDco.js +25 -0
  47. package/dist/doctorCommand-CM4Ch9C7.js +2 -0
  48. package/dist/{checkCommand-xGhRFFg2.js → doctorCommand-DnimF5IM.js} +523 -1278
  49. package/dist/dormancyCommand-QewYug_s.js +69 -0
  50. package/dist/e2eCmd-BRabZww-.js +147 -0
  51. package/dist/embeddingsCommand-BfiLS_QI.js +73 -0
  52. package/dist/envCommand-CCGPRQY1.js +60 -0
  53. package/dist/evalCommand-6RUfPen4.js +118 -0
  54. package/dist/evolveCommand-CHsLCtDf.js +281 -0
  55. package/dist/fileTaxonomy-CJfgOllU.js +457 -0
  56. package/dist/frameworkTableAssembly-YyVe32Cb.js +2 -0
  57. package/dist/frameworkTableAssembly-oMPBKqlE.js +511 -0
  58. package/dist/generateCommand-DbgcUpGw.js +147 -0
  59. package/dist/index.d.ts +45 -0
  60. package/dist/index.js +4 -3
  61. package/dist/infoCommand-DwOgK1t6.js +60 -0
  62. package/dist/{inspect-BUUjt773.js → inspect-CjTYzAs_.js} +113 -41
  63. package/dist/inspect-P4pxoMaV.js +2 -0
  64. package/dist/inspectCmd-EHFZ9yYu.js +224 -0
  65. package/dist/inspectFetch-EMuhTG_9.js +151 -0
  66. package/dist/inspectMetrics-CfdKLh6t.js +72 -0
  67. package/dist/loadEnv-D9nEOClM.js +44 -0
  68. package/dist/logFileSink-C_D2wRN1.js +105 -0
  69. package/dist/logsCmd-D36xK7Zu.js +260 -0
  70. package/dist/manifestBuild-COkJoyAr.js +2 -0
  71. package/dist/{manifestBuild-BLrVuSlM.js → manifestBuild-hpPLaGxV.js} +1 -1
  72. package/dist/metaCommands-7MJfZ5cf.js +196 -0
  73. package/dist/migrate-BV7I-ZHZ.js +83 -0
  74. package/dist/mssqlClusterPatch-_4cE_nun.js +44 -0
  75. package/dist/newCommand-COWOJ1_E.js +156 -0
  76. package/dist/nodeEnvironment-cGFAj1J8.js +28 -0
  77. package/dist/packageCommand-Cug_3Ogl.js +271 -0
  78. package/dist/pageConvention-cEiRxdab.js +5 -0
  79. package/dist/privacyCommand-C-Df56U_.js +146 -0
  80. package/dist/probeCommand-CZfaaUOZ.js +122 -0
  81. package/dist/projectScaffold-DmzEKHib.js +2 -0
  82. package/dist/projectScaffold-LMMtaavR.js +814 -0
  83. package/dist/renderModeScan-D7J1B7Kw.js +105 -0
  84. package/dist/renderProfile-1OWWAAtx.js +81 -0
  85. package/dist/runtimeRegistry-DMeKfTHP.js +81 -0
  86. package/dist/runtimeTrace-CH3eUiMw.js +91 -0
  87. package/dist/scheduleCmd-DQRu6BZC.js +149 -0
  88. package/dist/scheduleManifestCmd-D2x0CTTY.js +249 -0
  89. package/dist/schemaIr-UJybUUZW.js +103 -0
  90. package/dist/{sdkgen-C81QIkiL.js → sdkgen-BLkvGRfX.js} +111 -209
  91. package/dist/seedRunner-ZmLSqNe2.js +333 -0
  92. package/dist/serveCommand-CbDHU6l-.js +2 -0
  93. package/dist/serveCommand-iwlUBNS1.js +1766 -0
  94. package/dist/serveEntry.js +5 -5
  95. package/dist/serverlessCommand-CfJZy6dS.js +482 -0
  96. package/dist/start-BgN62boB.js +3 -0
  97. package/dist/start-T4VesWiM.js +1087 -0
  98. package/dist/startEntry.js +2 -2
  99. package/dist/staticCommand-Dr2M6tpU.js +304 -0
  100. package/dist/storageCommand-Co6NfLqN.js +42 -0
  101. package/dist/templates-De8IR5-c.js +102 -0
  102. package/dist/test-CI6iDsYc.js +115 -0
  103. package/dist/tracesCmd-DStmCJPi.js +232 -0
  104. package/dist/tsconfigPaths-BWXBWgcl.js +107 -0
  105. package/dist/tsxLoader-EuXmSJ1K.js +51 -0
  106. package/dist/typecheckCommand-BlsWiCNq.js +61 -0
  107. package/dist/updateCommand-BlMZhWgO.js +2 -0
  108. package/dist/updateCommand-x0pI_x-B.js +585 -0
  109. package/dist/webDev-BcykISYQ2.js +2 -0
  110. package/dist/{inspectMetrics-1xzTKAFx.js → webDev-Dybxew86.js} +988 -1560
  111. package/dist/webhookDiscovery-CrGAfhIG.js +2 -0
  112. package/dist/webhookDiscovery-D7VaeMlz.js +51 -0
  113. package/dist/webhooksCommand-DlAgS2Iw.js +267 -0
  114. package/dist/workflowsCmd-BGF-mRZ5.js +608 -0
  115. package/package.json +209 -17
  116. package/templates/AGENTS.core.md +58 -3
  117. package/templates/AGENTS.md +64 -7
  118. package/templates/agent-docs/_index.md +6 -4
  119. package/templates/agent-docs/_manifest.json +23 -6
  120. package/templates/agent-docs/ai.md +370 -0
  121. package/templates/agent-docs/authentication.md +313 -31
  122. package/templates/agent-docs/caching.md +6 -0
  123. package/templates/agent-docs/cli.md +853 -50
  124. package/templates/agent-docs/data.md +608 -12
  125. package/templates/agent-docs/database/migrations.md +223 -25
  126. package/templates/agent-docs/database/misc.md +156 -40
  127. package/templates/agent-docs/database/querying.md +19 -1
  128. package/templates/agent-docs/database/scaling.md +60 -0
  129. package/templates/agent-docs/database/schema.md +1 -0
  130. package/templates/agent-docs/database/seedsdialects.md +208 -19
  131. package/templates/agent-docs/database/transactions.md +68 -0
  132. package/templates/agent-docs/deployment.md +284 -25
  133. package/templates/agent-docs/introduction.md +88 -17
  134. package/templates/agent-docs/local-first-mobile.md +79 -4
  135. package/templates/agent-docs/multi-tenancy.md +188 -42
  136. package/templates/agent-docs/observability.md +58 -3
  137. package/templates/agent-docs/plugins/ai-flows.md +247 -2
  138. package/templates/agent-docs/plugins/analytics-postgres.md +1 -1
  139. package/templates/agent-docs/plugins/audit.md +37 -1
  140. package/templates/agent-docs/plugins/auth-social.md +143 -0
  141. package/templates/agent-docs/plugins/auth-workos.md +4 -2
  142. package/templates/agent-docs/plugins/auth.md +131 -6
  143. package/templates/agent-docs/plugins/billing.md +132 -15
  144. package/templates/agent-docs/plugins/cdc-out.md +46 -7
  145. package/templates/agent-docs/plugins/clickhouse.md +32 -1
  146. package/templates/agent-docs/plugins/duckdb.md +1 -1
  147. package/templates/agent-docs/plugins/flags.md +132 -0
  148. package/templates/agent-docs/plugins/governance.md +105 -7
  149. package/templates/agent-docs/plugins/multitenancy.md +9 -4
  150. package/templates/agent-docs/plugins/presence.md +13 -2
  151. package/templates/agent-docs/plugins/ratelimit.md +9 -0
  152. package/templates/agent-docs/plugins/search.md +162 -8
  153. package/templates/agent-docs/plugins/sso-saml.md +47 -8
  154. package/templates/agent-docs/plugins/storage.md +11 -0
  155. package/templates/agent-docs/plugins/webhooks.md +105 -0
  156. package/templates/agent-docs/plugins.md +152 -18
  157. package/templates/agent-docs/reference.md +60 -3
  158. package/templates/agent-docs/releases.md +1117 -0
  159. package/templates/agent-docs/routing.md +43 -25
  160. package/templates/agent-docs/scheduling.md +27 -0
  161. package/templates/agent-docs/schema-driven-ui.md +92 -12
  162. package/templates/agent-docs/security.md +426 -0
  163. package/templates/agent-docs/templates/apibackends.md +87 -18
  164. package/templates/agent-docs/templates/appshells.md +32 -14
  165. package/templates/agent-docs/templates/overview.md +13 -8
  166. package/templates/agent-docs/testing.md +211 -14
  167. package/templates/agent-docs/whats-new.md +98 -136
  168. package/templates/agent-docs/workflows.md +231 -14
  169. package/templates/apps/api-ai/actions/summarize.action.ts +11 -0
  170. package/templates/apps/api-ai/package.json +8 -7
  171. package/templates/apps/api-auth/actions/me.action.ts +13 -0
  172. package/templates/apps/api-auth/package.json +9 -8
  173. package/templates/apps/api-backend/mutations/notes.create.mutation.ts +9 -0
  174. package/templates/apps/api-backend/package.json +12 -8
  175. package/templates/apps/api-backend/queries/notes.query.ts +30 -8
  176. package/templates/apps/api-backend-deactivation/actions/users.get.action.ts +14 -0
  177. package/templates/apps/api-backend-deactivation/mutations/users.create.mutation.ts +8 -0
  178. package/templates/apps/api-backend-deactivation/mutations/users.deactivate.mutation.ts +10 -0
  179. package/templates/apps/api-backend-deactivation/package.json +8 -7
  180. package/templates/apps/api-backend-mail/actions/sendWelcome.action.ts +17 -0
  181. package/templates/apps/api-backend-mail/mutations/notes.create.mutation.ts +9 -0
  182. package/templates/apps/api-backend-mail/package.json +9 -8
  183. package/templates/apps/api-backend-mail/queries/notes.query.ts +30 -8
  184. package/templates/apps/api-backend-mariadb/.env.example +14 -0
  185. package/templates/apps/api-backend-mariadb/mutations/notes.create.mutation.ts +9 -0
  186. package/templates/apps/api-backend-mariadb/package.json +10 -9
  187. package/templates/apps/api-backend-mariadb/queries/notes.query.ts +30 -8
  188. package/templates/apps/api-backend-sqlite/.env.example +14 -0
  189. package/templates/apps/api-backend-sqlite/mutations/notes.create.mutation.ts +9 -0
  190. package/templates/apps/api-backend-sqlite/package.json +9 -8
  191. package/templates/apps/api-backend-sqlite/queries/notes.query.ts +30 -8
  192. package/templates/apps/api-backend-storage/actions/uploadAvatar.action.ts +13 -0
  193. package/templates/apps/api-backend-storage/actions/uploadDocument.action.ts +12 -0
  194. package/templates/apps/api-backend-storage/mutations/notes.create.mutation.ts +9 -0
  195. package/templates/apps/api-backend-storage/package.json +9 -8
  196. package/templates/apps/api-backend-storage/queries/notes.query.ts +30 -8
  197. package/templates/apps/api-cms/actions/content.get.action.ts +7 -0
  198. package/templates/apps/api-cms/actions/content.types.action.ts +6 -0
  199. package/templates/apps/api-cms/actions/me.action.ts +13 -0
  200. package/templates/apps/api-cms/app.config.ts +19 -0
  201. package/templates/apps/api-cms/authz.ts +63 -0
  202. package/templates/apps/api-cms/mutations/content.publish.mutation.ts +10 -0
  203. package/templates/apps/api-cms/mutations/content.saveDraft.mutation.ts +10 -0
  204. package/templates/apps/api-cms/mutations/content.unpublish.mutation.ts +5 -0
  205. package/templates/apps/api-cms/package.json +11 -10
  206. package/templates/apps/api-cms/queries/content.list.query.ts +23 -7
  207. package/templates/apps/api-cms/tests/accessDecisions.test.ts +121 -0
  208. package/templates/apps/api-cms/tests/content.descriptors.test.ts +8 -4
  209. package/templates/apps/api-collab/mutations/documents.create.mutation.ts +8 -0
  210. package/templates/apps/api-collab/mutations/documents.setBody.mutation.ts +13 -0
  211. package/templates/apps/api-collab/package.json +9 -8
  212. package/templates/apps/api-collab/queries/documents.query.ts +19 -7
  213. package/templates/apps/api-data-advanced/package.json +9 -8
  214. package/templates/apps/api-data-advanced/queries/authors.withBooks.query.ts +12 -0
  215. package/templates/apps/api-data-advanced/queries/books.search.query.ts +9 -0
  216. package/templates/apps/api-durable/mutations/orders.approve.mutation.ts +17 -0
  217. package/templates/apps/api-durable/mutations/orders.place.mutation.ts +9 -0
  218. package/templates/apps/api-durable/package.json +9 -8
  219. package/templates/apps/api-feature-flags/actions/notes.export.action.ts +16 -0
  220. package/templates/apps/api-feature-flags/mutations/notes.create.mutation.ts +12 -0
  221. package/templates/apps/api-feature-flags/package.json +10 -9
  222. package/templates/apps/api-governance/README.md +30 -8
  223. package/templates/apps/api-governance/actions/profiles.get.action.server.ts +17 -1
  224. package/templates/apps/api-governance/actions/profiles.get.action.ts +29 -4
  225. package/templates/apps/api-governance/database/schema.ts +16 -4
  226. package/templates/apps/api-governance/mutations/profiles.create.mutation.ts +12 -0
  227. package/templates/apps/api-governance/package.json +9 -8
  228. package/templates/apps/api-kv/actions/sync.pull.action.ts +15 -0
  229. package/templates/apps/api-kv/actions/sync.reset.action.ts +13 -0
  230. package/templates/apps/api-kv/actions/sync.status.action.ts +7 -0
  231. package/templates/apps/api-kv/package.json +9 -8
  232. package/templates/apps/api-kv/queries/events.list.query.ts +19 -8
  233. package/templates/apps/api-moderation/mutations/comments.create.mutation.ts +11 -0
  234. package/templates/apps/api-moderation/mutations/posts.create.mutation.ts +13 -0
  235. package/templates/apps/api-moderation/package.json +9 -8
  236. package/templates/apps/api-observability/mutations/notes.create.mutation.ts +8 -0
  237. package/templates/apps/api-observability/package.json +9 -8
  238. package/templates/apps/api-observability/queries/notes.list.query.ts +13 -0
  239. package/templates/apps/api-ratelimit/mutations/notes.create.mutation.ts +14 -0
  240. package/templates/apps/api-ratelimit/package.json +9 -8
  241. package/templates/apps/api-rbac/package.json +9 -8
  242. package/templates/apps/api-rest/package.json +8 -7
  243. package/templates/apps/api-saas/mutations/projects.create.mutation.ts +13 -0
  244. package/templates/apps/api-saas/package.json +12 -11
  245. package/templates/apps/api-saas/queries/projects.list.query.ts +11 -0
  246. package/templates/apps/api-saas-starter/actions/me.action.ts +13 -0
  247. package/templates/apps/api-saas-starter/app.config.ts +19 -0
  248. package/templates/apps/api-saas-starter/authz.ts +75 -0
  249. package/templates/apps/api-saas-starter/mutations/invites.create.mutation.ts +10 -0
  250. package/templates/apps/api-saas-starter/mutations/projects.create.mutation.ts +9 -0
  251. package/templates/apps/api-saas-starter/package.json +15 -11
  252. package/templates/apps/api-saas-starter/queries/invites.list.query.ts +19 -8
  253. package/templates/apps/api-saas-starter/queries/projects.list.query.ts +18 -7
  254. package/templates/apps/api-saas-starter/tests/accessDecisions.test.ts +135 -0
  255. package/templates/apps/api-search/mutations/articles.create.mutation.ts +14 -0
  256. package/templates/apps/api-search/package.json +9 -8
  257. package/templates/apps/api-search/queries/articles.list.query.ts +21 -8
  258. package/templates/apps/api-status/README.md +10 -3
  259. package/templates/apps/api-status/app.config.ts +8 -3
  260. package/templates/apps/api-status/authz.ts +5 -3
  261. package/templates/apps/api-status/package.json +9 -8
  262. package/templates/apps/api-status/queries/components.list.query.ts +14 -6
  263. package/templates/apps/api-status/queries/incidents.live.query.ts +23 -10
  264. package/templates/apps/api-status/queries/updates.list.query.ts +16 -9
  265. package/templates/apps/api-status/tests/status.test.ts +9 -1
  266. package/templates/apps/api-versioning/actions/documents.asOf.action.ts +12 -0
  267. package/templates/apps/api-versioning/actions/documents.history.action.ts +13 -0
  268. package/templates/apps/api-versioning/mutations/documents.create.mutation.ts +9 -0
  269. package/templates/apps/api-versioning/mutations/documents.update.mutation.ts +12 -0
  270. package/templates/apps/api-versioning/package.json +9 -8
  271. package/templates/apps/api-webhooks/mutations/orders.fulfill.mutation.ts +16 -0
  272. package/templates/apps/api-webhooks/package.json +10 -9
  273. package/templates/apps/api-webhooks/queries/orders.list.query.ts +10 -0
  274. package/templates/apps/changelog/package.json +8 -6
  275. package/templates/apps/edge-functions/package.json +2 -2
  276. package/templates/apps/frontend-admin/package.json +10 -8
  277. package/templates/apps/frontend-admin/src/lib/admin.ts +20 -9
  278. package/templates/apps/frontend-admin/src/locales/de.ts +11 -1
  279. package/templates/apps/frontend-admin/src/locales/en.ts +13 -1
  280. package/templates/apps/frontend-admin/src/pages/admin/[entity]/page.tsx +65 -22
  281. package/templates/apps/frontend-admin/src/pages/admin/entity.test.tsx +130 -23
  282. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +3 -2
  283. package/templates/apps/frontend-admin/src/pages/admin/page.test.tsx +19 -2
  284. package/templates/apps/frontend-admin/src/pages/admin/page.tsx +9 -4
  285. package/templates/apps/frontend-app/app.config.ts +4 -3
  286. package/templates/apps/frontend-app/package.json +11 -8
  287. package/templates/apps/frontend-app/src/lib/api.ts +25 -0
  288. package/templates/apps/frontend-app/src/pages/page.test.tsx +130 -82
  289. package/templates/apps/frontend-app/src/pages/page.tsx +14 -18
  290. package/templates/apps/frontend-auth/package.json +10 -8
  291. package/templates/apps/frontend-blank/package.json +9 -7
  292. package/templates/apps/frontend-cms/package.json +11 -9
  293. package/templates/apps/frontend-collab/package.json +12 -9
  294. package/templates/apps/frontend-collab/src/pages/page.test.tsx +122 -78
  295. package/templates/apps/frontend-contact/package.json +9 -7
  296. package/templates/apps/frontend-dashboard/package.json +9 -7
  297. package/templates/apps/frontend-docs/package.json +9 -7
  298. package/templates/apps/frontend-i18n/package.json +8 -6
  299. package/templates/apps/frontend-landing/package.json +9 -7
  300. package/templates/apps/frontend-portal/package.json +10 -8
  301. package/templates/apps/frontend-saas/app.config.ts +10 -6
  302. package/templates/apps/frontend-saas/package.json +10 -8
  303. package/templates/apps/frontend-saas/src/lib/api.ts +27 -32
  304. package/templates/apps/frontend-saas/src/pages/dashboard/billing/page.tsx +7 -8
  305. package/templates/apps/frontend-saas/src/pages/dashboard/page.test.tsx +27 -3
  306. package/templates/apps/frontend-saas/src/pages/dashboard/page.tsx +4 -4
  307. package/templates/apps/frontend-saas/src/pages/dashboard/team/page.tsx +3 -4
  308. package/templates/apps/frontend-spa/package.json +9 -7
  309. package/templates/apps/frontend-ssr/package.json +9 -7
  310. package/templates/apps/frontend-ssr-api/package.json +10 -8
  311. package/templates/apps/frontend-static-blog/package.json +8 -6
  312. package/templates/apps/frontend-status/package.json +10 -8
  313. package/templates/apps/mobile-app/README.md +1 -0
  314. package/templates/apps/mobile-app/package.json +4 -2
  315. package/templates/apps/mobile-app/src/app/index.tsx +22 -12
  316. package/templates/apps/mobile-app/src/app/orders/[id].tsx +1 -1
  317. package/templates/apps/mobile-app/src/lib/api.ts +34 -0
  318. package/templates/apps/mobile-app/voltro.mobile.ts +4 -2
  319. package/templates/baselines/bare/.env.example +14 -0
  320. package/templates/baselines/bare/baseline.json +4 -4
  321. package/templates/baselines/compose/.env.example +14 -0
  322. package/templates/baselines/compose/README.md +1 -1
  323. package/templates/baselines/compose/baseline.json +5 -5
  324. package/templates/baselines/compose-mariadb/.env.example +14 -0
  325. package/templates/baselines/compose-mariadb/README.md +1 -1
  326. package/templates/baselines/compose-mariadb/baseline.json +5 -5
  327. package/templates/baselines/helm/.env.example +14 -0
  328. package/templates/baselines/helm/baseline.json +4 -4
  329. package/dist/apiBuild-C-x9YacA.js +0 -2
  330. package/dist/appGraph-CvQCte0z.js +0 -2
  331. package/dist/checkCommand-DRovTKza.js +0 -2
  332. package/dist/commands-CJfepbm4.js +0 -11541
  333. package/dist/dbCommand-b1gum4td.js +0 -2
  334. package/dist/dev-iiMtlkfs.js +0 -3
  335. package/dist/devActivity-BhIu6ncs.js +0 -159
  336. package/dist/frameworkTableAssembly-BwIrO5nv.js +0 -638
  337. package/dist/frameworkTableAssembly-D-EebUQX.js +0 -2
  338. package/dist/inspect-mmBuRXmy.js +0 -2
  339. package/dist/manifestBuild-Dj8Jjoto.js +0 -2
  340. package/dist/seedRunner-Bqxgp7HZ.js +0 -230
  341. package/dist/serveCommand-DdaM4Hup.js +0 -1608
  342. package/dist/start-C0koT0UO.js +0 -1084
  343. /package/templates/apps/api-ai/actions/{summarize.action.server.tsx → summarize.action.server.ts} +0 -0
@@ -0,0 +1,30 @@
1
+ // Types for `nodeEnvironment.mjs`. Hand-written because the implementation is
2
+ // plain ESM on purpose — `bin/voltro.mjs` runs before the tsx loader and cannot
3
+ // import TypeScript, so the rule has to live in a file BOTH sides can load.
4
+ // `src/nodeEnvironment.ts` is the TypeScript face of it.
5
+
6
+ export type NodeEnvironmentName = string
7
+
8
+ /** Which environment an undeclared `NODE_ENV` resolves to, per command. */
9
+ export declare const COMMAND_ENVIRONMENT_DEFAULTS: Readonly<Record<string, NodeEnvironmentName | undefined>>
10
+
11
+ /** The first non-flag token of a `voltro …` argv, lowercased. */
12
+ export declare const commandOf: (argv: ReadonlyArray<string>) => string | undefined
13
+
14
+ /** Resolve this invocation's environment WITHOUT mutating `process.env`. */
15
+ export declare const resolveNodeEnvironment: (
16
+ argv: ReadonlyArray<string>,
17
+ env?: Record<string, string | undefined>,
18
+ ) => NodeEnvironmentName | undefined
19
+
20
+ /** Was `NODE_ENV` defaulted by us rather than declared by the operator? */
21
+ export declare const nodeEnvironmentWasDefaulted: () => boolean
22
+
23
+ /** Write the resolved environment into `process.env.NODE_ENV` when unset. */
24
+ export declare const declareNodeEnvironment: (
25
+ argv: ReadonlyArray<string>,
26
+ env?: Record<string, string | undefined>,
27
+ ) => NodeEnvironmentName | undefined
28
+
29
+ /** Tests only. */
30
+ export declare const resetNodeEnvironmentDeclaration: () => void
@@ -0,0 +1,158 @@
1
+ // THE decision: which environment is this process running in?
2
+ //
3
+ // ## Why this file is plain ESM and lives beside the launcher
4
+ //
5
+ // `bin/voltro.mjs` runs BEFORE the tsx loader is registered, so it cannot
6
+ // import a `.ts` module — and it was the first reader of `NODE_ENV`, three
7
+ // times, in fast paths that execute before any command's own default. Every
8
+ // other reader is TypeScript. A rule that has to hold across that boundary
9
+ // either lives in a file both sides can load, or it is two copies. It is this
10
+ // file; `src/nodeEnvironment.ts` re-exports it so the TypeScript side has one
11
+ // import and one set of types (`nodeEnvironment.d.mts`).
12
+ //
13
+ // ## The rule, and the three things it had to reconcile
14
+ //
15
+ // `voltro serve`, `voltro start` and the web preview server each carried
16
+ // `if (!process.env.NODE_ENV) process.env.NODE_ENV = 'production'`, with a
17
+ // comment saying an unset NODE_ENV in a serving container means production.
18
+ // NOTHING else agreed:
19
+ //
20
+ // - **The launcher decided first.** `bin/voltro.mjs` read `NODE_ENV` in the
21
+ // `serve` / `start` fast paths, which run before the command's default. So
22
+ // a NODE_ENV-less production deploy with a missing serve bundle skipped the
23
+ // "production requires a precompiled bundle" guard, fell through to the tsx
24
+ // path, and — in a `--prod --no-optional` image, which has no tsx — died as
25
+ // `Cannot find package 'tsx'` instead of naming the real cause.
26
+ //
27
+ // - **The migration commands ran the DEV branch of every gate.** In a
28
+ // pre-deploy job in the SAME image with NODE_ENV unset: `db apply`'s
29
+ // "auto-apply on prod is not allowed" refusal did not fire, `db
30
+ // rollback-file`'s refusal did not fire, and the plan ledger recorded
31
+ // `environment: 'dev'` for a production apply.
32
+ //
33
+ // - **And the framework TABLE SET disagreed with the process that serves
34
+ // it.** `traceTableEnabled()` and `undoCaptureEnabled()` are "on unless
35
+ // production", so a NODE_ENV-less `voltro db apply` declared
36
+ // `_voltro_traces` + `_voltro_undo_log` and `voltro serve` (which defaults
37
+ // to production) did not. The declared set is what the schema FINGERPRINT
38
+ // hashes, so the two no longer agree about it: the apply records one
39
+ // fingerprint and the serving container computes another, and serve's boot
40
+ // gate refuses with `prod-mismatch` — telling the operator to run `voltro db
41
+ // apply`, which is what they had just done. The loop has no exit.
42
+ //
43
+ // So: **an undeclared `NODE_ENV` resolves to `production` for every deploy-side
44
+ // command, and to `development` for `voltro dev`.** One rule, applied per
45
+ // command, with the polarity argued per gate at each use site:
46
+ //
47
+ // - For a REFUSAL (`db apply` auto-apply, `db rollback-file`) the cost of a
48
+ // false positive is one environment variable and the cost of a false
49
+ // negative is an un-reviewed DDL applied to a production database. Refuse.
50
+ // - For a TABLE-CREATION decision the safe direction is not "production", it
51
+ // is *the same answer the serving process will compute*. Since serve
52
+ // resolves an undeclared environment to production, so must every migration
53
+ // command, or the two declare different schemas. This is the gate the
54
+ // write-up in `frameworkTableAssembly.ts` claimed could never disagree.
55
+ // - `voltro dev` resolves to `development` so the ambiguity never reaches the
56
+ // boot auto-migrate at all: dev's table set becomes a declared fact rather
57
+ // than the absence of one.
58
+ //
59
+ // Commands NOT in the table below are left alone deliberately. Nothing in them
60
+ // branches on `NODE_ENV` in a way that crosses a process boundary, and
61
+ // declaring an environment for `voltro test` (vitest sets its own) or `voltro
62
+ // doctor` (whose serve-preflight default is documented as NODE_ENV-shaped)
63
+ // would change behaviour this decision has no opinion about.
64
+
65
+ /**
66
+ * Which environment an undeclared `NODE_ENV` resolves to, per command.
67
+ *
68
+ * A command absent from this map keeps an undeclared `NODE_ENV` undeclared.
69
+ * That is a decision, not an omission — see the header.
70
+ */
71
+ export const COMMAND_ENVIRONMENT_DEFAULTS = Object.freeze({
72
+ // The serving processes. An unset NODE_ENV in a container that is answering
73
+ // traffic is production; this is the rule the three call sites already had.
74
+ serve: 'production',
75
+ start: 'production',
76
+ // The deploy-side schema commands. They must resolve IDENTICALLY to `serve`
77
+ // or the declared framework-table set — and therefore the fingerprint — of
78
+ // the pre-deploy job differs from the serving container's.
79
+ db: 'production',
80
+ migrate: 'production',
81
+ // The development loop. Declared rather than left unset so the boot
82
+ // auto-migrate's table set is a stated fact.
83
+ dev: 'development',
84
+ })
85
+
86
+ /** Has `NODE_ENV` been given a value by the operator / the environment? */
87
+ const isDeclared = (raw) => typeof raw === 'string' && raw.length > 0
88
+
89
+ /**
90
+ * The command a `voltro …` argv invokes — the first non-flag token, lowercased.
91
+ * `undefined` when the argv carries only flags (`voltro --version`).
92
+ */
93
+ export const commandOf = (argv) => {
94
+ for (const arg of argv ?? []) {
95
+ if (typeof arg === 'string' && !arg.startsWith('-')) return arg.toLowerCase()
96
+ }
97
+ return undefined
98
+ }
99
+
100
+ /**
101
+ * Resolve this invocation's environment WITHOUT mutating anything.
102
+ *
103
+ * Returns the declared `NODE_ENV` when there is one; otherwise the command's
104
+ * default from {@link COMMAND_ENVIRONMENT_DEFAULTS}; otherwise `undefined`,
105
+ * meaning "this command has no opinion and the environment stays undeclared".
106
+ *
107
+ * The launcher uses this form: it must not write `process.env.NODE_ENV`,
108
+ * because it runs BEFORE `.env` / `.env.local` are loaded and a value it wrote
109
+ * there would silently outrank the app's own dotenv file for every later
110
+ * reader. Reading is safe; writing pre-dotenv is not.
111
+ */
112
+ export const resolveNodeEnvironment = (argv, env) => {
113
+ const source = env ?? process.env
114
+ if (isDeclared(source.NODE_ENV)) return source.NODE_ENV.toLowerCase()
115
+ const command = commandOf(argv)
116
+ if (command === undefined) return undefined
117
+ return COMMAND_ENVIRONMENT_DEFAULTS[command]
118
+ }
119
+
120
+ /**
121
+ * Whether `NODE_ENV` for THIS process was defaulted by us rather than declared
122
+ * by the operator.
123
+ *
124
+ * Module-level, not an environment variable: a refusal wants to SAY "NODE_ENV
125
+ * was not set, so this run resolved to production", and exporting that fact
126
+ * into the environment would make it inheritable by every child — a fact about
127
+ * one process, leaking as configuration.
128
+ */
129
+ let defaulted = false
130
+
131
+ /** See {@link declareNodeEnvironment}. */
132
+ export const nodeEnvironmentWasDefaulted = () => defaulted
133
+
134
+ /**
135
+ * DECLARE this process's environment: write the resolved value into
136
+ * `process.env.NODE_ENV` when it is unset, so that every later reader —
137
+ * including the ones this module cannot reach (`undoCaptureEnabled` lives in
138
+ * `@voltro/runtime`, which must not depend on the CLI) — sees a value that was
139
+ * decided once, here, rather than each guessing from an absence.
140
+ *
141
+ * Call it AFTER `.env` loading: a dotenv-provided `NODE_ENV` is a declaration
142
+ * and must win over our default.
143
+ *
144
+ * Returns the resolved name, or `undefined` when the command has no default and
145
+ * `NODE_ENV` was unset.
146
+ */
147
+ export const declareNodeEnvironment = (argv, env) => {
148
+ const source = env ?? process.env
149
+ if (isDeclared(source.NODE_ENV)) return source.NODE_ENV.toLowerCase()
150
+ const resolved = resolveNodeEnvironment(argv, source)
151
+ if (resolved === undefined) return undefined
152
+ source.NODE_ENV = resolved
153
+ defaulted = true
154
+ return resolved
155
+ }
156
+
157
+ /** Reset the "we defaulted it" flag. Tests only — a process declares once. */
158
+ export const resetNodeEnvironmentDeclaration = () => { defaulted = false }
package/bin/voltro.mjs CHANGED
@@ -17,6 +17,7 @@ import { existsSync } from 'node:fs'
17
17
  import { createRequire } from 'node:module'
18
18
  import { fileURLToPath, pathToFileURL } from 'node:url'
19
19
  import { dirname, join, resolve } from 'node:path'
20
+ import { resolveNodeEnvironment } from './nodeEnvironment.mjs'
20
21
 
21
22
  // FAST PATH — `voltro serve <app>` with a precompiled SERVE BUNDLE boots from that
22
23
  // ONE artefact IN THIS PROCESS: no child `node --import tsx`, no CLI command
@@ -32,6 +33,25 @@ const argv = process.argv.slice(2)
32
33
  const here = dirname(fileURLToPath(import.meta.url))
33
34
  const built = resolve(here, '..', 'dist', 'bin.js')
34
35
 
36
+ // WHICH ENVIRONMENT IS THIS. Resolved once, from the shared decider, and
37
+ // deliberately WITHOUT writing `process.env.NODE_ENV`: this file runs before
38
+ // `.env` / `.env.local` are loaded, so a value written here would silently
39
+ // outrank the app's own dotenv file for every later reader.
40
+ //
41
+ // The three guards below used to read `process.env.NODE_ENV === 'production'`
42
+ // directly, and they run BEFORE `runServe` / `runStartCommand` apply their own
43
+ // `if (!process.env.NODE_ENV) … = 'production'`. So a NODE_ENV-less production
44
+ // deploy whose serve bundle was missing skipped the "production requires a
45
+ // precompiled bundle" guard entirely, fell through to the tsx path, and — in a
46
+ // `--prod --no-optional` image, which has no tsx — died as `Cannot find package
47
+ // 'tsx'`: a message naming a package the user never asked for, in place of the
48
+ // one that says what is actually wrong. `serve` and `start` resolve to
49
+ // `production` when NODE_ENV is unset, which is exactly what the commands
50
+ // themselves do a few milliseconds later — this just stops the launcher from
51
+ // being the one reader that disagrees.
52
+ const launchEnvironment = resolveNodeEnvironment(argv, process.env)
53
+ const launchIsProduction = launchEnvironment === 'production'
54
+
35
55
  // FAST PATH — `voltro start <app>` (WEB) runs the built CLI IN THIS PROCESS when
36
56
  // the app is fully precompiled: no child `node --import tsx`, no loader hook.
37
57
  //
@@ -78,7 +98,7 @@ if (argv[0] === 'start') {
78
98
  // through would spawn the tsx path, and a prod image built with
79
99
  // `--no-optional` has no tsx at all — the container would die with a
80
100
  // misleading `Cannot find package 'tsx'` that hides THIS error.
81
- if (process.env.NODE_ENV === 'production') {
101
+ if (launchIsProduction) {
82
102
  console.error('[voltro] FATAL: precompiled `voltro start` failed to load:', error?.message ?? error)
83
103
  process.exit(1)
84
104
  }
@@ -87,7 +107,7 @@ if (argv[0] === 'start') {
87
107
  // in-process import legitimately can't work before a package build.
88
108
  console.warn('[voltro] start fast path failed:', error?.message ?? error)
89
109
  }
90
- } else if (process.env.NODE_ENV === 'production') {
110
+ } else if (launchIsProduction) {
91
111
  // PRODUCTION MUST start from precompiled artefacts — never transpile on
92
112
  // demand. Falling through here would spawn tsx (if it is even installed —
93
113
  // a prod image built with `--prod --no-optional` has no tsx at all) and
@@ -176,11 +196,16 @@ if (argv[0] === 'serve') {
176
196
  // build` produces the bundle and treats a build failure as fatal, so a healthy
177
197
  // deploy never hits this. Non-production (dev / an unbuilt local serve) falls
178
198
  // through to the tsx path below — on-demand transpile is a DEV-only convenience.
179
- if (process.env.NODE_ENV === 'production') {
199
+ if (launchIsProduction) {
180
200
  console.error(
181
201
  `[voltro] FATAL: production \`voltro serve\` requires a precompiled serve bundle at\n ${serveBundle}\n` +
182
202
  'but it is missing or failed to load. Run `voltro build` before serving — a bundle-build ' +
183
- 'failure is fatal by design; production never transpiles on demand.',
203
+ 'failure is fatal by design; production never transpiles on demand.' +
204
+ (process.env.NODE_ENV
205
+ ? ''
206
+ : '\n (NODE_ENV is not set in the process environment; `voltro serve` resolves that to ' +
207
+ 'production, the same way the command itself does. This launcher runs before `.env` is ' +
208
+ 'loaded, so set NODE_ENV in the environment — not in `.env` — for a non-production serve.)'),
184
209
  )
185
210
  process.exit(1)
186
211
  }
@@ -208,14 +233,53 @@ try {
208
233
  }
209
234
  }
210
235
 
236
+ // THE FIRST LINE A NEW USER SEES SHOULD BE OURS.
237
+ //
238
+ // Every invocation used to open with:
239
+ //
240
+ // (node:12345) ExperimentalWarning: localStorage is not available because
241
+ // --localstorage-file was not provided.
242
+ // (Use `node --trace-warnings ...` to show where the warning was created)
243
+ //
244
+ // — two lines of Node internals before the tool says anything, on `voltro
245
+ // version` as much as on `voltro dev`.
246
+ //
247
+ // The trigger, traced: `@voltro/runtime` → `crdtMerge.ts` → `@voltro/local-first`
248
+ // → `yjs` → `lib0/storage.js`, which touches `globalThis.localStorage` at module
249
+ // load. On Node 26 that access warns. It is a THIRD-PARTY module reading a
250
+ // global at import time, so there is nothing to fix at the point of use, and
251
+ // the framework needs `mergeCrdtStates` synchronously — deferring the import
252
+ // would make `crdtText()` async, which is a public API change to silence a log
253
+ // line.
254
+ //
255
+ // Two things address it, in this order:
256
+ // 1. Lazy command dispatch (`src/commands.ts`) keeps `@voltro/runtime` out of
257
+ // the graph entirely for commands that do not need it — `voltro version`
258
+ // is silent on its own now. That is the structural half.
259
+ // 2. This flag covers the rest, for the commands that legitimately load the
260
+ // runtime. It is NARROW: `--disable-warning` takes a warning TYPE, and
261
+ // `DeprecationWarning` — the class that matters when a dependency is about
262
+ // to break — still prints. Verified: a `DeprecationWarning` emitted under
263
+ // this flag is still shown.
264
+ //
265
+ // Node >= 20.11 has the flag and the framework's floor is 24, so it cannot
266
+ // produce a `bad option` on a supported runtime. If `@voltro/local-first` ever
267
+ // defers its yjs import, delete this — it is a workaround with a named cause,
268
+ // not a policy.
269
+ const QUIET_NODE_INTERNALS = '--disable-warning=ExperimentalWarning'
270
+
211
271
  // Export what we resolved. The child inherits `--import <abs>` in its own
212
272
  // `execArgv` and normally passes THAT on (see src/tsxLoader.ts), but a
213
273
  // grandchild spawned from a process that is not itself loader-registered has no
214
274
  // other way to learn the answer — and re-deriving it from the app's cwd is the
215
275
  // exact mistake this block exists to avoid.
276
+ //
277
+ // The quiet flag rides in `execArgv` for the same reason: `tsxLoaderArgs()`
278
+ // inherits the child's whole `execArgv`, so the dev supervisor's respawned
279
+ // grandchild is quiet too without a second place remembering to be.
216
280
  const child = spawn(
217
281
  process.execPath,
218
- ['--import', tsxImport, entry, ...process.argv.slice(2)],
282
+ [QUIET_NODE_INTERNALS, '--import', tsxImport, entry, ...process.argv.slice(2)],
219
283
  { stdio: 'inherit', env: { ...process.env, VOLTRO_TSX_IMPORT: tsxImport } },
220
284
  )
221
285
 
@@ -0,0 +1,124 @@
1
+ import { t as e } from "./mssqlClusterPatch-_4cE_nun.js";
2
+ import { dirname as t, join as n, resolve 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
+ //#region src/addCommand.ts
6
+ var s = o({ scope: "voltro:add" }), c = "redis://localhost:6379", l = (e) => {
7
+ let a = r(e);
8
+ for (let e = 0; e < 12; e++) {
9
+ if (i(n(a, "pnpm-workspace.yaml"))) return a;
10
+ let e = t(a);
11
+ if (e === a) break;
12
+ a = e;
13
+ }
14
+ return null;
15
+ }, u = async (e) => {
16
+ let t = n(e, "apps");
17
+ if (!i(t)) return [];
18
+ let r = [], o = await a.readdir(t, { withFileTypes: !0 });
19
+ for (let e of o) {
20
+ if (!e.isDirectory()) continue;
21
+ let o = n(t, e.name), s = await a.readdir(o, { withFileTypes: !0 });
22
+ for (let e of s) {
23
+ if (!e.isDirectory()) continue;
24
+ let t = n(o, e.name, "app.config.ts");
25
+ if (!i(t)) continue;
26
+ let s = await a.readFile(t, "utf8");
27
+ /type:\s*'api'/.test(s) && r.push(t);
28
+ }
29
+ }
30
+ return r;
31
+ }, d = "\n # --- added by `voltro add redis` ---\n redis:\n image: redis:7-alpine\n restart: unless-stopped\n ports:\n - \"6379:6379\"\n command: [\"redis-server\", \"--save\", \"\", \"--appendonly\", \"no\"]\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 2s\n timeout: 5s\n retries: 20\n", f = "\n# --- added by `voltro add redis` ---\nredis:\n # In-cluster Redis for the @voltro/cache backend. A cache is ephemeral,\n # so this is a Deployment (no PVC). Set enabled:false to point the app\n # at a managed Redis via CACHE_REDIS_URL instead.\n enabled: true\n image:\n repository: redis\n tag: 7-alpine\n", p = "{{- if .Values.redis.enabled }}\n# Added by `voltro add redis`. Ephemeral cache — Deployment, no PVC.\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: {{ include \"voltro-app.fullname\" . }}-redis\n labels:\n app.kubernetes.io/component: redis\nspec:\n replicas: 1\n selector:\n matchLabels:\n app.kubernetes.io/component: redis\n template:\n metadata:\n labels:\n app.kubernetes.io/component: redis\n spec:\n containers:\n - name: redis\n image: \"{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}\"\n args: [\"redis-server\", \"--save\", \"\", \"--appendonly\", \"no\"]\n ports:\n - containerPort: 6379\n readinessProbe:\n exec:\n command: [\"redis-cli\", \"ping\"]\n initialDelaySeconds: 2\n periodSeconds: 5\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: {{ include \"voltro-app.fullname\" . }}-redis\n labels:\n app.kubernetes.io/component: redis\nspec:\n selector:\n app.kubernetes.io/component: redis\n ports:\n - port: 6379\n targetPort: 6379\n{{- end }}\n", m = async (e) => {
32
+ let t = await a.readFile(e, "utf8");
33
+ if (/\bcache:\s*'/.test(t)) return !1;
34
+ let n = /(store:\s*'[^']*'\s*as const,?)/, r = /(type:\s*'api'\s*as const,?)/, i;
35
+ if (n.test(t)) i = t.replace(n, "$1\n cache: 'redis' as const,");
36
+ else if (r.test(t)) i = t.replace(r, "$1\n cache: 'redis' as const,");
37
+ else return !1;
38
+ return await a.writeFile(e, i, "utf8"), !0;
39
+ }, h = async (e) => {
40
+ let t = await a.readFile(e, "utf8");
41
+ if (/\n {2}redis:/.test(t)) return !1;
42
+ let n = /(^services:\s*\n)/m;
43
+ if (!n.test(t)) return !1;
44
+ let r = t.replace(n, `$1${d}`);
45
+ return await a.writeFile(e, r, "utf8"), !0;
46
+ }, g = async (e) => {
47
+ let t = n(e, "values.yaml"), r = n(e, "templates", "redis.yaml");
48
+ if (!i(t)) return !1;
49
+ let o = !1, s = await a.readFile(t, "utf8");
50
+ return /\nredis:/.test(s) || (await a.writeFile(t, `${s.trimEnd()}\n${f}`, "utf8"), o = !0), i(r) || (await a.writeFile(r, p, "utf8"), o = !0), o;
51
+ }, _ = async (e) => {
52
+ let t = i(e) ? await a.readFile(e, "utf8") : "";
53
+ if (/^\s*CACHE_BACKEND\s*=\s*redis\b/m.test(t)) return !1;
54
+ if (/^#\s*CACHE_BACKEND=redis\b/m.test(t)) {
55
+ let n = t.replace(/^#\s*(CACHE_BACKEND=redis)\s*$/m, "$1").replace(/^#\s*(CACHE_REDIS_URL=.*)$/m, "$1");
56
+ return await a.writeFile(e, n, "utf8"), !0;
57
+ }
58
+ let n = `${t.trimEnd()}${t ? "\n" : ""}\n# @voltro/cache — Redis backend\nCACHE_BACKEND=redis\nCACHE_REDIS_URL=${c}\n`;
59
+ return await a.writeFile(e, n, "utf8"), !0;
60
+ }, v = async (e) => {
61
+ let t = [];
62
+ for (let n of await u(e)) await m(n) && t.push(`cache: 'redis' → ${n.replace(`${e}/`, "")}`);
63
+ let r = n(e, "docker-compose.yml");
64
+ i(r) && await h(r) && t.push("redis service → docker-compose.yml");
65
+ let a = n(e, "charts", "voltro-app");
66
+ i(a) && await g(a) && t.push("redis Deployment/Service + values → charts/voltro-app/");
67
+ for (let r of [".env.example", ".env"]) {
68
+ let a = n(e, r);
69
+ (r === ".env.example" || i(a)) && await _(a) && t.push(`CACHE_BACKEND / CACHE_REDIS_URL → ${r}`);
70
+ }
71
+ return t;
72
+ }, y = async () => {
73
+ let e = l(process.cwd());
74
+ if (!e) return console.error("voltro add redis: not inside a voltro workspace (no pnpm-workspace.yaml found)"), 1;
75
+ let t = await v(e);
76
+ if (t.length === 0) return s.info("redis already enabled — nothing to do"), 0;
77
+ s.info("redis cache enabled", { changes: t.length });
78
+ for (let e of t) console.log(` ✓ ${e}`);
79
+ return console.log("\nNext: start redis (`docker compose up -d redis`) and reboot `voltro dev`."), console.log("The cache backend resolves from CACHE_BACKEND/CACHE_REDIS_URL (or app.config `cache`)."), 0;
80
+ }, b = async (e) => {
81
+ let t = await a.readFile(e, "utf8"), n = /store:\s*'([^']*)'(\s*as const)?/, r = n.exec(t);
82
+ if (r) return r[1] === "mssql" ? !1 : (await a.writeFile(e, t.replace(n, `store: 'mssql'${r[2] ?? ""}`), "utf8"), !0);
83
+ let i = /(type:\s*'api'\s*as const,?)/;
84
+ return i.test(t) ? (await a.writeFile(e, t.replace(i, "$1\n store: 'mssql' as const,"), "utf8"), !0) : !1;
85
+ }, x = async (e) => {
86
+ let t = i(e) ? await a.readFile(e, "utf8") : "";
87
+ if (/^DB_DIALECT=mssql$/m.test(t)) return !1;
88
+ let n = /^DB_DIALECT=.*$/m, r = n.test(t) ? t.replace(n, "DB_DIALECT=mssql") : `${t.trimEnd()}${t ? "\n" : ""}\n# SQL Server (mssql) — set the connection string for your server.
89
+ DB_DIALECT=mssql
90
+ # DB_URL=mssql://user:pass@host:1433/database
91
+ `;
92
+ return await a.writeFile(e, r, "utf8"), !0;
93
+ }, S = async (e, r) => {
94
+ let o = n(t(e), "package.json");
95
+ if (!i(o)) return !1;
96
+ let s = JSON.parse(await a.readFile(o, "utf8"));
97
+ return s.dependencies ??= {}, s.dependencies[r] ? !1 : (s.dependencies[r] = "workspace:*", s.dependencies = Object.fromEntries(Object.entries(s.dependencies).sort(([e], [t]) => e.localeCompare(t))), await a.writeFile(o, `${JSON.stringify(s, null, 2)}\n`, "utf8"), !0);
98
+ }, C = async (r) => {
99
+ let a = [];
100
+ for (let e of await u(r)) await b(e) && a.push(`store: 'mssql' → ${e.replace(`${r}/`, "")}`), await S(e, "@voltro/sql-mssql") && a.push(`+ @voltro/sql-mssql → ${t(e).replace(`${r}/`, "")}/package.json`);
101
+ for (let e of [".env.example", ".env"]) {
102
+ let t = n(r, e);
103
+ (e === ".env.example" || i(t)) && await x(t) && a.push(`DB_DIALECT=mssql → ${e}`);
104
+ }
105
+ for (let t of await e(r)) a.push(t);
106
+ return a;
107
+ }, w = async (e) => {
108
+ let t = await C(e);
109
+ if (t.length === 0) return s.info("mssql already wired — nothing to do"), 0;
110
+ s.info("mssql enabled", { changes: t.length });
111
+ for (let e of t) console.log(` ✓ ${e}`);
112
+ return console.log("\nNext: run `pnpm install` (applies the @effect/cluster patch), set DB_URL to your"), console.log("SQL Server, and reboot `voltro dev`. The patch fixes two mssql-only bugs in the"), console.log("durable cluster workflow engine; it is a no-op on any other dialect."), 0;
113
+ }, T = ["redis", "mssql"], E = async (e) => {
114
+ let t = e[0];
115
+ if (t === void 0) return console.error(`usage: voltro add <integration> (available: ${T.join(", ")})`), 1;
116
+ if (t === "redis") return y();
117
+ if (t === "mssql") {
118
+ let e = l(process.cwd());
119
+ return e ? w(e) : (console.error("voltro add mssql: not inside a voltro workspace (no pnpm-workspace.yaml found)"), 1);
120
+ }
121
+ return console.error(`voltro add: unknown integration '${t}'. Available: ${T.join(", ")}.`), 1;
122
+ };
123
+ //#endregion
124
+ export { v as n, E as r, C as t };
@@ -0,0 +1,2 @@
1
+ import { r as e } from "./addCommand-BNeoeSxe.js";
2
+ export { e as runAddCommand };
@@ -0,0 +1,2 @@
1
+ import { a as e } from "./agentsMd-mhQMF1bx.js";
2
+ export { e as runAgentsMd };