@voltro/cli 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/CHANGELOG.md +377 -0
  2. package/THIRD-PARTY-NOTICES.md +2 -2
  3. package/dist/{apiBuild-BESZbTjA.js → apiBuild-BceikpQf.js} +2 -2
  4. package/dist/apiBuild-CxvR1Dwt.js +2 -0
  5. package/dist/bin.js +3 -3
  6. package/dist/{checkCommand-BPAtyWs8.js → checkCommand-BMr-X48w.js} +23 -16
  7. package/dist/checkCommand-BOk9y264.js +2 -0
  8. package/dist/{commands-82BDEktg.js → commands-D4Y1-Nlu.js} +1936 -1339
  9. package/dist/{dbCommand-bCBbk6tz.js → dbCommand-C7hbl5pk.js} +344 -265
  10. package/dist/dbCommand-D8nhyppR.js +2 -0
  11. package/dist/{dev-DeEJj5T4.js → dev-Cr-teYsz.js} +1 -1
  12. package/dist/{dev-Cg4BKLmi.js → dev-DmnkH-wr.js} +2660 -1742
  13. package/dist/{frameworkTableAssembly-4Db40V23.js → frameworkTableAssembly-BzAajuUv.js} +114 -98
  14. package/dist/frameworkTableAssembly-DU0aOxjL.js +2 -0
  15. package/dist/index.d.ts +7 -2
  16. package/dist/index.js +1 -1
  17. package/dist/{inspect-BMvQpwqy.js → inspect-BUUjt773.js} +150 -14
  18. package/dist/inspect-mmBuRXmy.js +2 -0
  19. package/dist/{inspectMetrics-DHYygE4s.js → inspectMetrics-BeJdP_3b.js} +564 -512
  20. package/dist/{manifestBuild-C4R1EdHn.js → manifestBuild-BLrVuSlM.js} +1 -1
  21. package/dist/manifestBuild-Dj8Jjoto.js +2 -0
  22. package/dist/{sdkgen-CW5NbYF0.js → sdkgen-CqpOq_fy.js} +1 -1
  23. package/dist/serveCommand-Ciq_wIY8.js +1577 -0
  24. package/dist/serveEntry.js +2 -2
  25. package/dist/{start-CsCIaW4-.js → start-ocqB1seX.js} +19 -19
  26. package/dist/startEntry.js +2 -2
  27. package/package.json +17 -17
  28. package/templates/AGENTS.core.md +50 -0
  29. package/templates/AGENTS.md +53 -2
  30. package/templates/agent-docs/_index.md +3 -2
  31. package/templates/agent-docs/_manifest.json +16 -4
  32. package/templates/agent-docs/ai.md +56 -0
  33. package/templates/agent-docs/cli.md +19 -0
  34. package/templates/agent-docs/internationalization.md +8 -7
  35. package/templates/agent-docs/local-first-mobile.md +18 -6
  36. package/templates/agent-docs/routing.md +1 -1
  37. package/templates/agent-docs/security.md +17 -0
  38. package/templates/agent-docs/templates/apibackends.md +209 -0
  39. package/templates/agent-docs/templates/appshells.md +144 -1
  40. package/templates/agent-docs/templates/mobile.md +60 -0
  41. package/templates/agent-docs/templates/overview.md +17 -7
  42. package/templates/agent-docs/whats-new.md +256 -157
  43. package/templates/agent-docs/workflows.md +365 -0
  44. package/templates/apps/api-ai/package.json +7 -7
  45. package/templates/apps/api-auth/package.json +8 -8
  46. package/templates/apps/api-backend/package.json +7 -7
  47. package/templates/apps/api-backend-deactivation/package.json +7 -7
  48. package/templates/apps/api-backend-mail/package.json +8 -8
  49. package/templates/apps/api-backend-mariadb/package.json +9 -9
  50. package/templates/apps/api-backend-sqlite/package.json +8 -8
  51. package/templates/apps/api-backend-storage/package.json +8 -8
  52. package/templates/apps/api-cms/package.json +10 -10
  53. package/templates/apps/api-collab/README.md +70 -0
  54. package/templates/apps/api-collab/app.config.ts +28 -0
  55. package/templates/apps/api-collab/database/schema.ts +63 -0
  56. package/templates/apps/api-collab/mutations/documents.create.mutation.server.ts +19 -0
  57. package/templates/apps/api-collab/mutations/documents.create.mutation.ts +36 -0
  58. package/templates/apps/api-collab/mutations/documents.setBody.mutation.server.ts +20 -0
  59. package/templates/apps/api-collab/mutations/documents.setBody.mutation.ts +30 -0
  60. package/templates/apps/api-collab/package.json +30 -0
  61. package/templates/apps/api-collab/queries/documents.query.server.ts +16 -0
  62. package/templates/apps/api-collab/queries/documents.query.ts +23 -0
  63. package/templates/apps/api-collab/template.json +6 -0
  64. package/templates/apps/api-collab/tests/documents.setBody.test.ts +89 -0
  65. package/templates/apps/api-collab/tsconfig.json +5 -0
  66. package/templates/apps/api-data-advanced/package.json +8 -8
  67. package/templates/apps/api-durable/package.json +8 -8
  68. package/templates/apps/api-feature-flags/package.json +9 -9
  69. package/templates/apps/api-governance/package.json +8 -8
  70. package/templates/apps/api-kv/package.json +8 -8
  71. package/templates/apps/api-moderation/package.json +8 -8
  72. package/templates/apps/api-observability/package.json +8 -8
  73. package/templates/apps/api-ratelimit/package.json +8 -8
  74. package/templates/apps/api-rbac/package.json +8 -8
  75. package/templates/apps/api-rest/package.json +7 -7
  76. package/templates/apps/api-saas/package.json +11 -11
  77. package/templates/apps/api-saas-starter/package.json +10 -10
  78. package/templates/apps/api-search/package.json +8 -8
  79. package/templates/apps/api-status/package.json +8 -8
  80. package/templates/apps/api-versioning/package.json +8 -8
  81. package/templates/apps/api-webhooks/package.json +9 -9
  82. package/templates/apps/changelog/package.json +6 -6
  83. package/templates/apps/edge-functions/package.json +2 -2
  84. package/templates/apps/frontend-admin/app.config.ts +1 -1
  85. package/templates/apps/frontend-admin/package.json +8 -8
  86. package/templates/apps/frontend-admin/src/locales/index.ts +1 -1
  87. package/templates/apps/frontend-app/app.config.ts +1 -1
  88. package/templates/apps/frontend-app/package.json +8 -8
  89. package/templates/apps/frontend-app/src/locales/index.ts +1 -1
  90. package/templates/apps/frontend-app/src/pages/layout.tsx +1 -1
  91. package/templates/apps/frontend-app/src/pages/page.tsx +1 -1
  92. package/templates/apps/frontend-auth/package.json +8 -8
  93. package/templates/apps/frontend-auth/src/locales/index.ts +1 -1
  94. package/templates/apps/frontend-blank/app.config.ts +1 -1
  95. package/templates/apps/frontend-blank/package.json +7 -7
  96. package/templates/apps/frontend-blank/src/locales/index.ts +1 -1
  97. package/templates/apps/frontend-blank/src/pages/layout.tsx +1 -1
  98. package/templates/apps/frontend-blank/src/pages/page.tsx +1 -1
  99. package/templates/apps/frontend-cms/package.json +9 -9
  100. package/templates/apps/frontend-cms/src/locales/index.ts +1 -1
  101. package/templates/apps/frontend-collab/README.md +80 -0
  102. package/templates/apps/frontend-collab/app.config.ts +38 -0
  103. package/templates/apps/frontend-collab/package.json +33 -0
  104. package/templates/apps/frontend-collab/src/locales/de.ts +29 -0
  105. package/templates/apps/frontend-collab/src/locales/en.ts +31 -0
  106. package/templates/apps/frontend-collab/src/locales/index.ts +15 -0
  107. package/templates/apps/frontend-collab/src/pages/layout.tsx +39 -0
  108. package/templates/apps/frontend-collab/src/pages/page.test.tsx +150 -0
  109. package/templates/apps/frontend-collab/src/pages/page.tsx +186 -0
  110. package/templates/apps/frontend-collab/template.json +6 -0
  111. package/templates/apps/frontend-collab/tsconfig.json +11 -0
  112. package/templates/apps/frontend-contact/package.json +7 -7
  113. package/templates/apps/frontend-dashboard/app.config.ts +1 -1
  114. package/templates/apps/frontend-dashboard/package.json +7 -7
  115. package/templates/apps/frontend-dashboard/src/locales/index.ts +1 -1
  116. package/templates/apps/frontend-docs/package.json +7 -7
  117. package/templates/apps/frontend-i18n/package.json +6 -6
  118. package/templates/apps/frontend-landing/package.json +7 -7
  119. package/templates/apps/frontend-portal/package.json +8 -8
  120. package/templates/apps/frontend-portal/src/locales/index.ts +1 -1
  121. package/templates/apps/frontend-saas/README.md +1 -1
  122. package/templates/apps/frontend-saas/app.config.ts +1 -1
  123. package/templates/apps/frontend-saas/package.json +8 -8
  124. package/templates/apps/frontend-saas/src/locales/index.ts +1 -1
  125. package/templates/apps/frontend-spa/app.config.ts +1 -1
  126. package/templates/apps/frontend-spa/package.json +7 -7
  127. package/templates/apps/frontend-spa/src/locales/index.ts +1 -1
  128. package/templates/apps/frontend-spa/src/pages/layout.tsx +1 -1
  129. package/templates/apps/frontend-spa/src/pages/page.tsx +1 -1
  130. package/templates/apps/frontend-ssr/app.config.ts +1 -1
  131. package/templates/apps/frontend-ssr/package.json +7 -7
  132. package/templates/apps/frontend-ssr/src/locales/index.ts +1 -1
  133. package/templates/apps/frontend-ssr/src/pages/layout.tsx +1 -1
  134. package/templates/apps/frontend-ssr/src/pages/page.tsx +1 -1
  135. package/templates/apps/frontend-ssr-api/app.config.ts +1 -1
  136. package/templates/apps/frontend-ssr-api/package.json +8 -8
  137. package/templates/apps/frontend-ssr-api/src/locales/index.ts +1 -1
  138. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +1 -1
  139. package/templates/apps/frontend-static-blog/package.json +6 -6
  140. package/templates/apps/frontend-status/package.json +8 -8
  141. package/templates/apps/frontend-status/src/locales/index.ts +1 -1
  142. package/templates/apps/mobile-app/README.md +58 -0
  143. package/templates/apps/mobile-app/app.config.ts +33 -0
  144. package/templates/apps/mobile-app/babel.config.js +5 -0
  145. package/templates/apps/mobile-app/metro.config.js +20 -0
  146. package/templates/apps/mobile-app/package.json +33 -0
  147. package/templates/apps/mobile-app/src/app/_layout.tsx +61 -0
  148. package/templates/apps/mobile-app/src/app/index.tsx +62 -0
  149. package/templates/apps/mobile-app/src/app/orders/[id].tsx +19 -0
  150. package/templates/apps/mobile-app/src/app/settings.tsx +51 -0
  151. package/templates/apps/mobile-app/src/client.ts +74 -0
  152. package/templates/apps/mobile-app/src/lib/deeplinks.ts +39 -0
  153. package/templates/apps/mobile-app/src/lib/notifications.ts +31 -0
  154. package/templates/apps/mobile-app/src/lib/sync.ts +29 -0
  155. package/templates/apps/mobile-app/src/persistence.ts +38 -0
  156. package/templates/apps/mobile-app/template.json +6 -0
  157. package/templates/apps/mobile-app/tests/deeplinks.test.ts +32 -0
  158. package/templates/apps/mobile-app/tests/notifications.test.ts +26 -0
  159. package/templates/apps/mobile-app/tests/sync.test.ts +34 -0
  160. package/templates/apps/mobile-app/tsconfig.json +10 -0
  161. package/templates/apps/mobile-app/voltro.mobile.ts +11 -0
  162. package/templates/patches/@effect__cluster@0.60.0.patch +6 -6
  163. package/dist/apiBuild-C8d74T6g.js +0 -2
  164. package/dist/checkCommand-DBvZvCh1.js +0 -2
  165. package/dist/dbCommand-CaIVTp-a.js +0 -2
  166. package/dist/frameworkTableAssembly-BTNirAAk.js +0 -2
  167. package/dist/inspect-DHeaMZak.js +0 -2
  168. package/dist/manifestBuild-Ck_90gZy.js +0 -2
  169. package/dist/serveCommand-BXl8mhZD.js +0 -1489
@@ -13,17 +13,17 @@
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
15
  "@effect/rpc": "^0.76.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/database": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/plugin-multitenancy": "0.29.0",
20
- "@voltro/plugin-ratelimit": "0.29.0",
21
- "@voltro/protocol": "0.29.0",
22
- "@voltro/runtime": "0.29.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/database": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/plugin-multitenancy": "0.30.0",
20
+ "@voltro/plugin-ratelimit": "0.30.0",
21
+ "@voltro/protocol": "0.30.0",
22
+ "@voltro/runtime": "0.30.0",
23
23
  "effect": "^3.22.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/testing": "0.29.0",
26
+ "@voltro/testing": "0.30.0",
27
27
  "typescript": "^6.0.3",
28
28
  "vitest": "^4.1.10"
29
29
  }
@@ -13,17 +13,17 @@
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
15
  "@effect/rpc": "^0.76.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/database": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/plugin-multitenancy": "0.29.0",
20
- "@voltro/plugin-rbac": "0.29.0",
21
- "@voltro/protocol": "0.29.0",
22
- "@voltro/runtime": "0.29.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/database": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/plugin-multitenancy": "0.30.0",
20
+ "@voltro/plugin-rbac": "0.30.0",
21
+ "@voltro/protocol": "0.30.0",
22
+ "@voltro/runtime": "0.30.0",
23
23
  "effect": "^3.22.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/testing": "0.29.0",
26
+ "@voltro/testing": "0.30.0",
27
27
  "typescript": "^6.0.3",
28
28
  "vitest": "^4.1.10"
29
29
  }
@@ -13,16 +13,16 @@
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
15
  "@effect/rpc": "^0.76.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/database": "0.29.0",
18
- "@voltro/plugin-openapi": "0.29.0",
19
- "@voltro/protocol": "0.29.0",
20
- "@voltro/runtime": "0.29.0",
21
- "@voltro/sql-postgres": "0.29.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/database": "0.30.0",
18
+ "@voltro/plugin-openapi": "0.30.0",
19
+ "@voltro/protocol": "0.30.0",
20
+ "@voltro/runtime": "0.30.0",
21
+ "@voltro/sql-postgres": "0.30.0",
22
22
  "effect": "^3.22.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@voltro/testing": "0.29.0",
25
+ "@voltro/testing": "0.30.0",
26
26
  "typescript": "^6.0.3",
27
27
  "vitest": "^4.1.10"
28
28
  }
@@ -13,20 +13,20 @@
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
15
  "@effect/rpc": "^0.76.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/database": "0.29.0",
18
- "@voltro/plugin-analytics-postgres": "0.29.0",
19
- "@voltro/plugin-billing": "0.29.0",
20
- "@voltro/plugin-multitenancy": "0.29.0",
21
- "@voltro/plugin-notifications": "0.29.0",
22
- "@voltro/plugin-presence": "0.29.0",
23
- "@voltro/protocol": "0.29.0",
24
- "@voltro/runtime": "0.29.0",
25
- "@voltro/sql-postgres": "0.29.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/database": "0.30.0",
18
+ "@voltro/plugin-analytics-postgres": "0.30.0",
19
+ "@voltro/plugin-billing": "0.30.0",
20
+ "@voltro/plugin-multitenancy": "0.30.0",
21
+ "@voltro/plugin-notifications": "0.30.0",
22
+ "@voltro/plugin-presence": "0.30.0",
23
+ "@voltro/protocol": "0.30.0",
24
+ "@voltro/runtime": "0.30.0",
25
+ "@voltro/sql-postgres": "0.30.0",
26
26
  "effect": "^3.22.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@voltro/testing": "0.29.0",
29
+ "@voltro/testing": "0.30.0",
30
30
  "typescript": "^6.0.3",
31
31
  "vitest": "^4.1.10"
32
32
  }
@@ -13,19 +13,19 @@
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
15
  "@effect/rpc": "^0.76.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/database": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/plugin-auth": "0.29.0",
20
- "@voltro/plugin-billing": "0.29.0",
21
- "@voltro/plugin-multitenancy": "0.29.0",
22
- "@voltro/protocol": "0.29.0",
23
- "@voltro/runtime": "0.29.0",
24
- "@voltro/sql-postgres": "0.29.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/database": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/plugin-auth": "0.30.0",
20
+ "@voltro/plugin-billing": "0.30.0",
21
+ "@voltro/plugin-multitenancy": "0.30.0",
22
+ "@voltro/protocol": "0.30.0",
23
+ "@voltro/runtime": "0.30.0",
24
+ "@voltro/sql-postgres": "0.30.0",
25
25
  "effect": "^3.22.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@voltro/testing": "0.29.0",
28
+ "@voltro/testing": "0.30.0",
29
29
  "typescript": "^6.0.3",
30
30
  "vitest": "^4.1.10"
31
31
  }
@@ -13,17 +13,17 @@
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
15
  "@effect/rpc": "^0.76.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/database": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/plugin-multitenancy": "0.29.0",
20
- "@voltro/plugin-search": "0.29.0",
21
- "@voltro/protocol": "0.29.0",
22
- "@voltro/runtime": "0.29.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/database": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/plugin-multitenancy": "0.30.0",
20
+ "@voltro/plugin-search": "0.30.0",
21
+ "@voltro/protocol": "0.30.0",
22
+ "@voltro/runtime": "0.30.0",
23
23
  "effect": "^3.22.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/testing": "0.29.0",
26
+ "@voltro/testing": "0.30.0",
27
27
  "typescript": "^6.0.3",
28
28
  "vitest": "^4.1.10"
29
29
  }
@@ -13,17 +13,17 @@
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
15
  "@effect/rpc": "^0.76.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/database": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/plugin-rbac": "0.29.0",
20
- "@voltro/protocol": "0.29.0",
21
- "@voltro/runtime": "0.29.0",
22
- "@voltro/sql-postgres": "0.29.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/database": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/plugin-rbac": "0.30.0",
20
+ "@voltro/protocol": "0.30.0",
21
+ "@voltro/runtime": "0.30.0",
22
+ "@voltro/sql-postgres": "0.30.0",
23
23
  "effect": "^3.22.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/testing": "0.29.0",
26
+ "@voltro/testing": "0.30.0",
27
27
  "typescript": "^6.0.3",
28
28
  "vitest": "^4.1.10"
29
29
  }
@@ -13,17 +13,17 @@
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
15
  "@effect/rpc": "^0.76.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/database": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/plugin-multitenancy": "0.29.0",
20
- "@voltro/plugin-versioning": "0.29.0",
21
- "@voltro/protocol": "0.29.0",
22
- "@voltro/runtime": "0.29.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/database": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/plugin-multitenancy": "0.30.0",
20
+ "@voltro/plugin-versioning": "0.30.0",
21
+ "@voltro/protocol": "0.30.0",
22
+ "@voltro/runtime": "0.30.0",
23
23
  "effect": "^3.22.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/testing": "0.29.0",
26
+ "@voltro/testing": "0.30.0",
27
27
  "typescript": "^6.0.3",
28
28
  "vitest": "^4.1.10"
29
29
  }
@@ -13,18 +13,18 @@
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
15
  "@effect/rpc": "^0.76.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/database": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/plugin-multitenancy": "0.29.0",
20
- "@voltro/plugin-webhooks": "0.29.0",
21
- "@voltro/protocol": "0.29.0",
22
- "@voltro/runtime": "0.29.0",
23
- "@voltro/sql-postgres": "0.29.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/database": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/plugin-multitenancy": "0.30.0",
20
+ "@voltro/plugin-webhooks": "0.30.0",
21
+ "@voltro/protocol": "0.30.0",
22
+ "@voltro/runtime": "0.30.0",
23
+ "@voltro/sql-postgres": "0.30.0",
24
24
  "effect": "^3.22.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@voltro/testing": "0.29.0",
27
+ "@voltro/testing": "0.30.0",
28
28
  "typescript": "^6.0.3",
29
29
  "vitest": "^4.1.10"
30
30
  }
@@ -12,12 +12,12 @@
12
12
  "test": "voltro test"
13
13
  },
14
14
  "dependencies": {
15
- "@voltro/changelog": "0.29.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/client": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/i18n": "0.29.0",
20
- "@voltro/web": "0.29.0",
15
+ "@voltro/changelog": "0.30.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/client": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/i18n": "0.30.0",
20
+ "@voltro/web": "0.30.0",
21
21
  "react": "^19.0.0",
22
22
  "react-dom": "^19.0.0"
23
23
  },
@@ -12,8 +12,8 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@effect/platform": "^0.97.0",
15
- "@voltro/cli": "0.29.0",
16
- "@voltro/serverless": "0.29.0",
15
+ "@voltro/cli": "0.30.0",
16
+ "@voltro/serverless": "0.30.0",
17
17
  "effect": "^3.22.0"
18
18
  },
19
19
  "devDependencies": {
@@ -22,7 +22,7 @@ export default {
22
22
  // <I18nProvider> from these codes and loads the matching
23
23
  // `src/locales/<code>.ts` catalog — so `<T id="…" />` / `useT()` /
24
24
  // `useLocale()` work app-wide with no manual setup. The <LocaleSwitcher>
25
- // in the layout writes the `voltro:lang` cookie + reloads. Grow the app to
25
+ // in the layout writes the `voltro:locale` cookie + reloads. Grow the app to
26
26
  // more languages by adding a code here + a `src/locales/<code>.ts`.
27
27
  locales: ['en', 'de'] as const,
28
28
  defaultLocale: 'en' as const,
@@ -12,18 +12,18 @@
12
12
  "test": "voltro test"
13
13
  },
14
14
  "dependencies": {
15
- "@{{projectName}}/api": "0.29.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/client": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/i18n": "0.29.0",
20
- "@voltro/ui-shadcn": "0.29.0",
21
- "@voltro/web": "0.29.0",
15
+ "@{{projectName}}/api": "0.30.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/client": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/i18n": "0.30.0",
20
+ "@voltro/ui-shadcn": "0.30.0",
21
+ "@voltro/web": "0.30.0",
22
22
  "react": "^19.0.0",
23
23
  "react-dom": "^19.0.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/devtools": "0.29.0",
26
+ "@voltro/devtools": "0.30.0",
27
27
  "@types/react": "^19.0.0",
28
28
  "@types/react-dom": "^19.0.0",
29
29
  "typescript": "^6.0.3",
@@ -1,6 +1,6 @@
1
1
  // Catalog lookup OUTSIDE React — for a page's `meta({ locale })` locale-aware
2
2
  // <title>. This app is cookie-i18n (no `/<locale>` URL prefix), so @voltro/web
3
- // hands `meta` the active locale from the `voltro:lang` cookie. Inside React,
3
+ // hands `meta` the active locale from the `voltro:locale` cookie. Inside React,
4
4
  // use `<T>` / `useT()` via the framework's auto-wired <I18nProvider> instead.
5
5
 
6
6
  import en from './en'
@@ -27,7 +27,7 @@ export default {
27
27
  // <I18nProvider> from these codes and loads the matching
28
28
  // `src/locales/<code>.ts` catalog — so `<T id="…" />` / `useT()` /
29
29
  // `useLocale()` work app-wide with no manual setup. The <LocaleSwitcher>
30
- // in the layout writes the `voltro:lang` cookie + reloads. Grow the app to
30
+ // in the layout writes the `voltro:locale` cookie + reloads. Grow the app to
31
31
  // more languages by adding a code here + a `src/locales/<code>.ts`.
32
32
  locales: ['en', 'de'] as const,
33
33
  defaultLocale: 'en' as const,
@@ -12,18 +12,18 @@
12
12
  "typecheck": "tsc --noEmit"
13
13
  },
14
14
  "dependencies": {
15
- "@{{projectName}}/api": "0.29.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/client": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/i18n": "0.29.0",
20
- "@voltro/ui-shadcn": "0.29.0",
21
- "@voltro/web": "0.29.0",
15
+ "@{{projectName}}/api": "0.30.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/client": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/i18n": "0.30.0",
20
+ "@voltro/ui-shadcn": "0.30.0",
21
+ "@voltro/web": "0.30.0",
22
22
  "react": "^19.0.0",
23
23
  "react-dom": "^19.0.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/devtools": "0.29.0",
26
+ "@voltro/devtools": "0.30.0",
27
27
  "@types/react": "^19.0.0",
28
28
  "@types/react-dom": "^19.0.0",
29
29
  "typescript": "^6.0.3",
@@ -1,6 +1,6 @@
1
1
  // Catalog lookup OUTSIDE React — for a page's `meta({ locale })` locale-aware
2
2
  // <title>. This app is cookie-i18n (no `/<locale>` URL prefix), so @voltro/web
3
- // hands `meta` the active locale from the `voltro:lang` cookie. Inside React,
3
+ // hands `meta` the active locale from the `voltro:locale` cookie. Inside React,
4
4
  // use `<T>` / `useT()` via the framework's auto-wired <I18nProvider> instead.
5
5
 
6
6
  import en from './en'
@@ -4,7 +4,7 @@
4
4
  // `theme: 'dark' | 'light' | 'system'` in app.config.ts for the dark class.
5
5
  //
6
6
  // The app is bilingual (see `locales` in app.config.ts): nav labels come from
7
- // the catalog via `<T>`, and <LocaleSwitcher> writes the `voltro:lang` cookie
7
+ // the catalog via `<T>`, and <LocaleSwitcher> writes the `voltro:locale` cookie
8
8
  // + reloads so the framework re-renders in the chosen language.
9
9
 
10
10
  import type { ReactNode } from 'react'
@@ -20,7 +20,7 @@ import { T, useTFn } from '@voltro/i18n'
20
20
  import { getCatalog } from '../locales'
21
21
 
22
22
  // Locale-aware tab title: @voltro/web resolves meta({ locale }) from the
23
- // active locale (the `voltro:lang` cookie in this cookie-i18n app).
23
+ // active locale (the `voltro:locale` cookie in this cookie-i18n app).
24
24
  export const meta = ({ locale }: { readonly locale: string }): PageMeta => ({
25
25
  title: getCatalog(locale)['meta.notes.title'],
26
26
  })
@@ -12,18 +12,18 @@
12
12
  "test": "voltro test"
13
13
  },
14
14
  "dependencies": {
15
- "@{{projectName}}/api": "0.29.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/client": "0.29.0",
18
- "@voltro/env": "0.29.0",
19
- "@voltro/i18n": "0.29.0",
20
- "@voltro/ui-shadcn": "0.29.0",
21
- "@voltro/web": "0.29.0",
15
+ "@{{projectName}}/api": "0.30.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/client": "0.30.0",
18
+ "@voltro/env": "0.30.0",
19
+ "@voltro/i18n": "0.30.0",
20
+ "@voltro/ui-shadcn": "0.30.0",
21
+ "@voltro/web": "0.30.0",
22
22
  "react": "^19.0.0",
23
23
  "react-dom": "^19.0.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/devtools": "0.29.0",
26
+ "@voltro/devtools": "0.30.0",
27
27
  "@types/react": "^19.0.0",
28
28
  "@types/react-dom": "^19.0.0",
29
29
  "typescript": "^6.0.3",
@@ -1,6 +1,6 @@
1
1
  // Catalog lookup OUTSIDE React — for a page's `meta({ locale })` locale-aware
2
2
  // <title>. This app is cookie-i18n (no `/<locale>` URL prefix), so @voltro/web
3
- // hands `meta` the active locale from the `voltro:lang` cookie. Inside React use
3
+ // hands `meta` the active locale from the `voltro:locale` cookie. Inside React use
4
4
  // `<T>` / `useT()` via the framework's auto-wired <I18nProvider> instead.
5
5
  import en from './en'
6
6
  import de from './de'
@@ -22,7 +22,7 @@ export default {
22
22
  // <I18nProvider> from these codes and loads the matching
23
23
  // `src/locales/<code>.ts` catalog — so `<T id="…" />` / `useT()` /
24
24
  // `useLocale()` work app-wide with no manual setup. The <LocaleSwitcher>
25
- // in the layout writes the `voltro:lang` cookie + reloads. Grow the app to
25
+ // in the layout writes the `voltro:locale` cookie + reloads. Grow the app to
26
26
  // more languages by adding a code here + a `src/locales/<code>.ts`.
27
27
  locales: ['en', 'de'] as const,
28
28
  defaultLocale: 'en' as const,
@@ -12,17 +12,17 @@
12
12
  "typecheck": "tsc --noEmit"
13
13
  },
14
14
  "dependencies": {
15
- "@voltro/cli": "0.29.0",
16
- "@voltro/client": "0.29.0",
17
- "@voltro/env": "0.29.0",
18
- "@voltro/i18n": "0.29.0",
19
- "@voltro/ui-shadcn": "0.29.0",
20
- "@voltro/web": "0.29.0",
15
+ "@voltro/cli": "0.30.0",
16
+ "@voltro/client": "0.30.0",
17
+ "@voltro/env": "0.30.0",
18
+ "@voltro/i18n": "0.30.0",
19
+ "@voltro/ui-shadcn": "0.30.0",
20
+ "@voltro/web": "0.30.0",
21
21
  "react": "^19.0.0",
22
22
  "react-dom": "^19.0.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@voltro/devtools": "0.29.0",
25
+ "@voltro/devtools": "0.30.0",
26
26
  "@types/react": "^19.0.0",
27
27
  "@types/react-dom": "^19.0.0",
28
28
  "typescript": "^6.0.3",
@@ -1,6 +1,6 @@
1
1
  // Catalog lookup OUTSIDE React — for a page's `meta({ locale })` locale-aware
2
2
  // <title>. This app is cookie-i18n (no `/<locale>` URL prefix), so @voltro/web
3
- // hands `meta` the active locale from the `voltro:lang` cookie. Inside React,
3
+ // hands `meta` the active locale from the `voltro:locale` cookie. Inside React,
4
4
  // use `<T>` / `useT()` via the framework's auto-wired <I18nProvider> instead.
5
5
 
6
6
  import en from './en'
@@ -7,7 +7,7 @@
7
7
  // to control the dark class.
8
8
  //
9
9
  // The app is bilingual (see `locales` in app.config.ts): <LocaleSwitcher>
10
- // writes the `voltro:lang` cookie + reloads so the framework re-renders in
10
+ // writes the `voltro:locale` cookie + reloads so the framework re-renders in
11
11
  // the chosen language.
12
12
 
13
13
  import type { ReactNode } from 'react'
@@ -10,7 +10,7 @@ import { T } from '@voltro/i18n'
10
10
  import { getCatalog } from '../locales'
11
11
 
12
12
  // Locale-aware tab title: @voltro/web resolves meta({ locale }) from the
13
- // active locale (the `voltro:lang` cookie in this cookie-i18n app).
13
+ // active locale (the `voltro:locale` cookie in this cookie-i18n app).
14
14
  export const meta = ({ locale }: { readonly locale: string }): PageMeta => ({
15
15
  title: getCatalog(locale)['meta.home.title'],
16
16
  })
@@ -12,19 +12,19 @@
12
12
  "test": "voltro test"
13
13
  },
14
14
  "dependencies": {
15
- "@{{projectName}}/api": "0.29.0",
16
- "@voltro/cli": "0.29.0",
17
- "@voltro/client": "0.29.0",
18
- "@voltro/cms": "0.29.0",
19
- "@voltro/env": "0.29.0",
20
- "@voltro/i18n": "0.29.0",
21
- "@voltro/ui-shadcn": "0.29.0",
22
- "@voltro/web": "0.29.0",
15
+ "@{{projectName}}/api": "0.30.0",
16
+ "@voltro/cli": "0.30.0",
17
+ "@voltro/client": "0.30.0",
18
+ "@voltro/cms": "0.30.0",
19
+ "@voltro/env": "0.30.0",
20
+ "@voltro/i18n": "0.30.0",
21
+ "@voltro/ui-shadcn": "0.30.0",
22
+ "@voltro/web": "0.30.0",
23
23
  "react": "^19.0.0",
24
24
  "react-dom": "^19.0.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@voltro/devtools": "0.29.0",
27
+ "@voltro/devtools": "0.30.0",
28
28
  "@types/react": "^19.0.0",
29
29
  "@types/react-dom": "^19.0.0",
30
30
  "typescript": "^6.0.3",
@@ -1,6 +1,6 @@
1
1
  // Catalog lookup OUTSIDE React — for a page's `meta({ locale })` locale-aware
2
2
  // <title>. This app is cookie-i18n (no `/<locale>` URL prefix), so @voltro/web
3
- // hands `meta` the active locale from the `voltro:lang` cookie. Inside React use
3
+ // hands `meta` the active locale from the `voltro:locale` cookie. Inside React use
4
4
  // `<T>` / `useT()` via the framework's auto-wired <I18nProvider> instead.
5
5
  import en from './en'
6
6
  import de from './de'
@@ -0,0 +1,80 @@
1
+ # {{projectName}} / {{appName}}
2
+
3
+ Voltro collaborative-editing frontend (template: **frontend-collab**).
4
+
5
+ A document editor whose textarea is bound to a `crdtText()` body over the
6
+ framework's reactive loop. Type in **two browser tabs at once** and the edits
7
+ **converge** — no last-write-wins loser — because the api merges every update
8
+ into the shared document server-side, then broadcasts the merged result back
9
+ live. Zero infra: the merge and the broadcast are in-process on a single
10
+ `voltro dev`.
11
+
12
+ ## Scaffold the pair
13
+
14
+ `frontend-collab` consumes a sibling api — scaffold it **together with
15
+ [`api-collab`](../api-collab)** (which exposes the `documents.list` subscription
16
+ + `documents.create` / `documents.setBody` mutations):
17
+
18
+ ```bash
19
+ voltro create-project collab --api=api-collab --web=frontend-collab
20
+ cd collab
21
+ pnpm install
22
+ pnpm dev # boots BOTH apps (api on :4000, web on its portRange port)
23
+ ```
24
+
25
+ Open the web app, click **Create document**, then open a **second tab** on the
26
+ same URL and type in both. Every keystroke merges — both tabs' edits survive.
27
+
28
+ ## How it works
29
+
30
+ ```
31
+ Tab A api (api-collab)
32
+ ───── ────────────────
33
+ local crdtText() handle documents.setBody (crdtText 'body' column)
34
+ │ keystroke → insert/delete └─ runtime folds the update into the
35
+ │ → handle.encode() ──rpc──► STORED state (mergeCrdtStates) → merged
36
+ ▼ └─► reactive delta ──WS──► every tab
37
+ useSubscription('app',
38
+ 'documents.list') ◄──WS── merged body ── handle.merge(body) → textarea
39
+ ```
40
+
41
+ 1. **`useSubscription('app', 'documents.list')`** streams the shared document,
42
+ including its **merged** `body` (encoded CRDT bytes), on every write.
43
+ 2. A **local `crdtText()` handle** (`@voltro/local-first`) is seeded from that
44
+ body. Each keystroke applies a contiguous insert/delete to the handle and
45
+ sends `handle.encode()` via **`useMutation('app', 'documents.setBody')`**.
46
+ 3. The api's **authoritative server-side merge** folds the update into the
47
+ stored state before broadcasting — so concurrent edits converge.
48
+ 4. Incoming server bodies are **folded back** into the local handle
49
+ (idempotent), keeping every tab in sync.
50
+
51
+ This page is exactly the app-level binding the local-first docs describe as the
52
+ `SyncClient` transport: `push` = the `setBody` mutation, `onRemoteState` = the
53
+ `documents` subscription.
54
+
55
+ ## Not wired here: presence cursors
56
+
57
+ Live "who else is editing" cursors (`usePresence` from
58
+ `@voltro/local-first/react`) need a `PresenceChannel` bound to the app's
59
+ broadcast broker — a runtime binding, not zero-infra in a single dev process
60
+ across tabs — so this template omits them. The CRDT text convergence above needs
61
+ none of that; it rides the reactive engine you already have.
62
+
63
+ ## Files
64
+
65
+ ```
66
+ app.config.ts type:web + the `apis: { app }` wiring
67
+ package.json depends on @{{projectName}}/api (the sibling) + @voltro/local-first
68
+ src/pages/
69
+ layout.tsx root shell (header + <main>)
70
+ page.tsx the collaborative editor — subscription + CRDT handle + setBody
71
+ page.test.tsx render + edit-dispatch tests (jsdom)
72
+ src/locales/{en,de}.ts bilingual UI strings
73
+ ```
74
+
75
+ ## Multi-tenancy note
76
+
77
+ The dev `AuthMiddleware` resolves the tenant from the `x-tenant` header,
78
+ defaulting to `'acme'` (the `TENANT` constant in `page.tsx`). The `documents`
79
+ table carries the `tenant()` mixin, so reads/writes are auto-scoped. Wire real
80
+ auth before production (see the authentication docs).