@voltro/cli 0.29.0 → 0.30.1

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 +448 -0
  2. package/THIRD-PARTY-NOTICES.md +2 -2
  3. package/dist/apiBuild-Ca6Sq5jy.js +2 -0
  4. package/dist/{apiBuild-BESZbTjA.js → apiBuild-DmkzRyv7.js} +2 -2
  5. package/dist/bin.js +3 -3
  6. package/dist/{checkCommand-BPAtyWs8.js → checkCommand-C4konUy9.js} +435 -304
  7. package/dist/checkCommand-DHD0aBeR.js +2 -0
  8. package/dist/{commands-82BDEktg.js → commands-BkJft9K2.js} +2413 -1814
  9. package/dist/{dbCommand-bCBbk6tz.js → dbCommand-qn__kLEt.js} +344 -265
  10. package/dist/dbCommand-wfGi3FgG.js +2 -0
  11. package/dist/{dev-Cg4BKLmi.js → dev-C_NPcLDp.js} +2716 -1782
  12. package/dist/{dev-DeEJj5T4.js → dev-DXhhZ7-f.js} +1 -1
  13. package/dist/frameworkTableAssembly-Bn_c4Mnl.js +2 -0
  14. package/dist/{frameworkTableAssembly-4Db40V23.js → frameworkTableAssembly-Cpgn2e88.js} +155 -141
  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-CkB2J0Zn.js} +566 -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-wsWLrq4l.js} +1 -1
  23. package/dist/serveCommand-HtI4X5kj.js +1577 -0
  24. package/dist/serveEntry.js +2 -2
  25. package/dist/{start-CsCIaW4-.js → start-egkbpugc.js} +177 -175
  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 +46 -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 +15 -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 +36 -243
  43. package/templates/agent-docs/workflows.md +367 -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
@@ -32,7 +32,7 @@ export default {
32
32
  // <I18nProvider> from these codes and loads the matching
33
33
  // `src/locales/<code>.ts` catalog — so `<T id="…" />` / `useT()` /
34
34
  // `useLocale()` work app-wide with no manual setup. The <LocaleSwitcher>
35
- // in the layout writes the `voltro:lang` cookie + reloads. Grow the app to
35
+ // in the layout writes the `voltro:locale` cookie + reloads. Grow the app to
36
36
  // more languages by adding a code here + a `src/locales/<code>.ts`.
37
37
  locales: ['en', 'de'] as const,
38
38
  defaultLocale: 'en' as const,
@@ -12,17 +12,17 @@
12
12
  "test": "voltro test"
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.1",
16
+ "@voltro/client": "0.30.1",
17
+ "@voltro/env": "0.30.1",
18
+ "@voltro/i18n": "0.30.1",
19
+ "@voltro/ui-shadcn": "0.30.1",
20
+ "@voltro/web": "0.30.1",
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.1",
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'
@@ -12,17 +12,17 @@
12
12
  "test": "voltro test"
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.1",
16
+ "@voltro/client": "0.30.1",
17
+ "@voltro/env": "0.30.1",
18
+ "@voltro/i18n": "0.30.1",
19
+ "@voltro/ui-shadcn": "0.30.1",
20
+ "@voltro/web": "0.30.1",
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.1",
26
26
  "@types/react": "^19.0.0",
27
27
  "@types/react-dom": "^19.0.0",
28
28
  "typescript": "^6.0.3",
@@ -12,16 +12,16 @@
12
12
  "test": "voltro test"
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/web": "0.29.0",
15
+ "@voltro/cli": "0.30.1",
16
+ "@voltro/client": "0.30.1",
17
+ "@voltro/env": "0.30.1",
18
+ "@voltro/i18n": "0.30.1",
19
+ "@voltro/web": "0.30.1",
20
20
  "react": "^19.0.0",
21
21
  "react-dom": "^19.0.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@voltro/devtools": "0.29.0",
24
+ "@voltro/devtools": "0.30.1",
25
25
  "@types/react": "^19.0.0",
26
26
  "@types/react-dom": "^19.0.0",
27
27
  "typescript": "^6.0.3",
@@ -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.1",
16
+ "@voltro/client": "0.30.1",
17
+ "@voltro/env": "0.30.1",
18
+ "@voltro/i18n": "0.30.1",
19
+ "@voltro/ui-shadcn": "0.30.1",
20
+ "@voltro/web": "0.30.1",
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.1",
26
26
  "@types/react": "^19.0.0",
27
27
  "@types/react-dom": "^19.0.0",
28
28
  "typescript": "^6.0.3",
@@ -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.1",
16
+ "@voltro/cli": "0.30.1",
17
+ "@voltro/client": "0.30.1",
18
+ "@voltro/env": "0.30.1",
19
+ "@voltro/i18n": "0.30.1",
20
+ "@voltro/ui-shadcn": "0.30.1",
21
+ "@voltro/web": "0.30.1",
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.1",
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'
@@ -39,7 +39,7 @@ voltro dev # api on :4000, this app on its configured port
39
39
 
40
40
  ## i18n
41
41
 
42
- Cookie-driven (no `/<locale>` URL prefix): `<LocaleSwitcher>` writes `voltro:lang`
42
+ Cookie-driven (no `/<locale>` URL prefix): `<LocaleSwitcher>` writes `voltro:locale`
43
43
  and reloads. Every string is a key in `src/locales/en.ts`, mirrored in `de.ts`
44
44
  (`defineLocale<typeof en>()` fails the build on a missing key). Add a language
45
45
  with a new code in `app.config.ts` + a `src/locales/<code>.ts`.
@@ -31,7 +31,7 @@ export default {
31
31
  // <I18nProvider> from these codes and loads the matching
32
32
  // `src/locales/<code>.ts` catalog — so `<T id="…" />` / `useT()` /
33
33
  // `useLocale()` work app-wide (SSR too). The <LocaleSwitcher> writes the
34
- // `voltro:lang` cookie + reloads. Add a code + a `src/locales/<code>.ts` to
34
+ // `voltro:locale` cookie + reloads. Add a code + a `src/locales/<code>.ts` to
35
35
  // grow the app to more languages.
36
36
  locales: ['en', 'de'] as const,
37
37
  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.1",
16
+ "@voltro/cli": "0.30.1",
17
+ "@voltro/client": "0.30.1",
18
+ "@voltro/env": "0.30.1",
19
+ "@voltro/i18n": "0.30.1",
20
+ "@voltro/ui-shadcn": "0.30.1",
21
+ "@voltro/web": "0.30.1",
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.1",
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'
@@ -20,7 +20,7 @@ export default {
20
20
  // <I18nProvider> from these codes and loads the matching
21
21
  // `src/locales/<code>.ts` catalog — so `<T id="…" />` / `useT()` /
22
22
  // `useLocale()` work app-wide with no manual setup. The <LocaleSwitcher>
23
- // in the layout writes the `voltro:lang` cookie + reloads. Grow the app to
23
+ // in the layout writes the `voltro:locale` cookie + reloads. Grow the app to
24
24
  // more languages by adding a code here + a `src/locales/<code>.ts`.
25
25
  locales: ['en', 'de'] as const,
26
26
  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.1",
16
+ "@voltro/client": "0.30.1",
17
+ "@voltro/env": "0.30.1",
18
+ "@voltro/i18n": "0.30.1",
19
+ "@voltro/ui-shadcn": "0.30.1",
20
+ "@voltro/web": "0.30.1",
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.1",
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'
@@ -2,7 +2,7 @@
2
2
  // so there is no SSR document to worry about here.
3
3
  //
4
4
  // The app is bilingual (see `locales` in app.config.ts): <LocaleSwitcher>
5
- // writes the `voltro:lang` cookie + reloads so the framework re-renders in the
5
+ // writes the `voltro:locale` cookie + reloads so the framework re-renders in the
6
6
  // chosen language.
7
7
 
8
8
  import type { ReactNode } from 'react'
@@ -15,7 +15,7 @@ import { T } from '@voltro/i18n'
15
15
  import { getCatalog } from '../locales'
16
16
 
17
17
  // Locale-aware tab title: @voltro/web resolves meta({ locale }) from the
18
- // active locale (the `voltro:lang` cookie in this cookie-i18n app).
18
+ // active locale (the `voltro:locale` cookie in this cookie-i18n app).
19
19
  export const meta = ({ locale }: { readonly locale: string }): PageMeta => ({
20
20
  title: getCatalog(locale)['meta.home.title'],
21
21
  })
@@ -24,7 +24,7 @@ export default {
24
24
  // <I18nProvider> from these codes and loads the matching
25
25
  // `src/locales/<code>.ts` catalog — so `<T id="…" />` / `useT()` /
26
26
  // `useLocale()` work app-wide (SSR + ISR too) with no manual setup. The
27
- // <LocaleSwitcher> in the layout writes the `voltro:lang` cookie + reloads.
27
+ // <LocaleSwitcher> in the layout writes the `voltro:locale` cookie + reloads.
28
28
  // Grow the app to more languages by adding a code here + a
29
29
  // `src/locales/<code>.ts`.
30
30
  locales: ['en', 'de'] as const,
@@ -12,17 +12,17 @@
12
12
  "test": "voltro test"
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.1",
16
+ "@voltro/client": "0.30.1",
17
+ "@voltro/env": "0.30.1",
18
+ "@voltro/i18n": "0.30.1",
19
+ "@voltro/ui-shadcn": "0.30.1",
20
+ "@voltro/web": "0.30.1",
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.1",
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> / <meta description>. This app is cookie-i18n (no `/<locale>` URL
3
- // prefix), so @voltro/web hands `meta` the active locale from the `voltro:lang`
3
+ // prefix), so @voltro/web hands `meta` the active locale from the `voltro:locale`
4
4
  // cookie. Inside React, use `<T>` / `useT()` via the framework's auto-wired
5
5
  // <I18nProvider> instead.
6
6
 
@@ -3,7 +3,7 @@
3
3
  // intercepts them) after the first load.
4
4
  //
5
5
  // The app is bilingual (see `locales` in app.config.ts): nav labels come from
6
- // the catalog via `<T>`, and <LocaleSwitcher> writes the `voltro:lang` cookie
6
+ // the catalog via `<T>`, and <LocaleSwitcher> writes the `voltro:locale` cookie
7
7
  // + reloads so the framework re-renders in the chosen language.
8
8
 
9
9
  import type { ReactNode } from 'react'
@@ -15,7 +15,7 @@ import { getCatalog } from '../locales'
15
15
  export const renderMode = 'ssr' as const
16
16
 
17
17
  // Locale-aware tab title + description: @voltro/web resolves meta({ locale })
18
- // from the active locale (the `voltro:lang` cookie in this cookie-i18n app).
18
+ // from the active locale (the `voltro:locale` cookie in this cookie-i18n app).
19
19
  export const meta = ({ locale }: { readonly locale: string }): PageMeta => ({
20
20
  title: getCatalog(locale)['meta.ssr.title'],
21
21
  description: getCatalog(locale)['meta.ssr.description'],
@@ -29,7 +29,7 @@ export default {
29
29
  // <I18nProvider> from these codes and loads the matching
30
30
  // `src/locales/<code>.ts` catalog — so `<T id="…" />` / `useT()` /
31
31
  // `useLocale()` work app-wide (SSR too) with no manual setup. The
32
- // <LocaleSwitcher> in the layout writes the `voltro:lang` cookie + reloads.
32
+ // <LocaleSwitcher> in the layout writes the `voltro:locale` cookie + reloads.
33
33
  // Grow the app to more languages by adding a code here + a
34
34
  // `src/locales/<code>.ts`.
35
35
  locales: ['en', 'de'] 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.1",
16
+ "@voltro/cli": "0.30.1",
17
+ "@voltro/client": "0.30.1",
18
+ "@voltro/env": "0.30.1",
19
+ "@voltro/i18n": "0.30.1",
20
+ "@voltro/ui-shadcn": "0.30.1",
21
+ "@voltro/web": "0.30.1",
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.1",
27
27
  "@types/react": "^19.0.0",
28
28
  "@types/react-dom": "^19.0.0",
29
29
  "typescript": "^6.0.3",
@@ -1,7 +1,7 @@
1
1
  // Catalog lookup OUTSIDE React — for the page's `meta({ locale, loaderData })`
2
2
  // locale-aware <title> / <meta description>. This app is cookie-i18n (no
3
3
  // `/<locale>` URL prefix), so @voltro/web hands `meta` the active locale from
4
- // the `voltro:lang` cookie. Inside React, use `<T>` / `useT()` via the
4
+ // the `voltro:locale` cookie. Inside React, use `<T>` / `useT()` via the
5
5
  // framework's auto-wired <I18nProvider> instead.
6
6
 
7
7
  import en from './en'
@@ -2,7 +2,7 @@
2
2
  // Don't render <html>/<head>/<body> here — the framework shell owns them.
3
3
  //
4
4
  // The app is bilingual (see `locales` in app.config.ts): <LocaleSwitcher>
5
- // writes the `voltro:lang` cookie + reloads so the framework re-renders in the
5
+ // writes the `voltro:locale` cookie + reloads so the framework re-renders in the
6
6
  // chosen language.
7
7
  import type { ReactNode } from 'react'
8
8
  import { useLocale, useT } from '@voltro/i18n'
@@ -12,16 +12,16 @@
12
12
  "test": "voltro test"
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/web": "0.29.0",
15
+ "@voltro/cli": "0.30.1",
16
+ "@voltro/client": "0.30.1",
17
+ "@voltro/env": "0.30.1",
18
+ "@voltro/i18n": "0.30.1",
19
+ "@voltro/web": "0.30.1",
20
20
  "react": "^19.0.0",
21
21
  "react-dom": "^19.0.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@voltro/devtools": "0.29.0",
24
+ "@voltro/devtools": "0.30.1",
25
25
  "@types/react": "^19.0.0",
26
26
  "@types/react-dom": "^19.0.0",
27
27
  "typescript": "^6.0.3",
@@ -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.1",
16
+ "@voltro/cli": "0.30.1",
17
+ "@voltro/client": "0.30.1",
18
+ "@voltro/env": "0.30.1",
19
+ "@voltro/i18n": "0.30.1",
20
+ "@voltro/ui-shadcn": "0.30.1",
21
+ "@voltro/web": "0.30.1",
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.1",
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 the page's `meta({ locale })` locale-aware
2
2
  // <title>. Cookie-i18n (no URL prefix), so @voltro/web hands `meta` the active
3
- // locale from the `voltro:lang` cookie. Inside React use `<T>` / `useT()`.
3
+ // locale from the `voltro:locale` cookie. Inside React use `<T>` / `useT()`.
4
4
  import en from './en'
5
5
  import de from './de'
6
6
 
@@ -0,0 +1,58 @@
1
+ # {{capProjectName}} — mobile (Expo + Voltro)
2
+
3
+ An [Expo](https://expo.dev) (React Native) app that is the **third consumer** of
4
+ your Voltro api — the same typed hooks you use on the web (`useSubscription` /
5
+ `useMutation`), offline-first by default, with typed deep links and device
6
+ registration for push.
7
+
8
+ > **Expo owns the dev loop, not `voltro dev`.** This app is started with
9
+ > `expo start` / `expo run:ios`, not `voltro dev`. The sibling api still runs
10
+ > under `voltro dev`; this app connects to it over the network.
11
+
12
+ ## Run it
13
+
14
+ ```sh
15
+ # 1. In one shell — the api (scaffold it with --api=api-backend):
16
+ voltro dev
17
+
18
+ # 2. Point this app at the api. On a simulator/device use your machine's LAN
19
+ # address, NOT localhost:
20
+ export EXPO_PUBLIC_API_URL="http://192.168.x.x:4000"
21
+
22
+ # 3. In another shell — the app:
23
+ pnpm ios # or: pnpm android · pnpm start (Expo Go)
24
+ ```
25
+
26
+ ## What's here
27
+
28
+ | Path | What |
29
+ |---|---|
30
+ | `src/lib/deeplinks.ts` | the typed deep-link table + pure resolver (**tested**) |
31
+ | `src/lib/sync.ts` | the background-sync decision layer (**tested**) |
32
+ | `src/lib/notifications.ts` | build a `_voltro_devices` row from a push token (**tested**) |
33
+ | `src/client.ts` | the Voltro client + the **M0 seam** (read its header) |
34
+ | `src/persistence.ts` | RN key-value with the secure/plain split |
35
+ | `src/app/*` | Expo Router screens (list, detail, settings) |
36
+ | `voltro.mobile.ts` | which api(s) this app consumes |
37
+
38
+ ## Honest status (read before you expect the loop to work on a device)
39
+
40
+ The **pure logic** in `src/lib/*` is real and unit-tested (`pnpm test`). The
41
+ **client wiring** — building the runtime + subscription cache + rpc client that
42
+ the hooks read — is **not yet implemented for React Native**: on the web it lives
43
+ in `@voltro/web`'s web-coupled boot. Wiring an RN-safe equivalent is Phase **M0**
44
+ in the framework's mobile plan (`plans/open/mobile/`). Until it lands,
45
+ `buildApiHandles()` in `src/client.ts` returns an empty map and the screens show
46
+ their loading state — deliberately, not a crash. `src/client.ts`'s header spells
47
+ out exactly what M0 must build.
48
+
49
+ The tests here run without a simulator. Booting the app on a device (`expo
50
+ run:ios`) is your Expo/EAS CI step — there is no iOS/Android toolchain in the
51
+ framework repo's sandbox.
52
+
53
+ ## Tests
54
+
55
+ ```sh
56
+ pnpm test # the pure lib — no simulator needed
57
+ pnpm typecheck # tsc over the app (needs Expo/RN types installed)
58
+ ```
@@ -0,0 +1,33 @@
1
+ // Expo app config for the {{projectName}} mobile app.
2
+ //
3
+ // NOTE: this is EXPO's config, NOT Voltro's `type: 'web'|'api'` app.config. A
4
+ // mobile app is not run by `voltro dev` — Expo owns Metro and the simulator
5
+ // (`expo start` / `expo run:ios`). The sibling api this app consumes still runs
6
+ // under `voltro dev`; the app connects to it over HTTP/WebSocket via
7
+ // `EXPO_PUBLIC_API_URL` (see src/client.ts).
8
+ //
9
+ // `scheme` is the custom URL scheme that makes deep links open THIS app
10
+ // (`{{appName}}://orders/42`). Keep it in sync with the deep-link table in
11
+ // src/lib/deeplinks.ts — `voltro mobile doctor` (planned) checks this.
12
+ import type { ExpoConfig } from 'expo/config'
13
+
14
+ const config: ExpoConfig = {
15
+ name: '{{capProjectName}}{{capAppName}}',
16
+ slug: '{{projectName}}-{{appName}}',
17
+ scheme: '{{appName}}',
18
+ version: '0.0.0',
19
+ orientation: 'portrait',
20
+ userInterfaceStyle: 'automatic',
21
+ newArchEnabled: true,
22
+ ios: { supportsTablet: true, bundleIdentifier: 'com.{{projectName}}.{{appName}}' },
23
+ android: { package: 'com.{{projectName}}.{{appName}}' },
24
+ plugins: [
25
+ 'expo-router',
26
+ 'expo-secure-store',
27
+ // Add 'expo-notifications' here once you wire the push pipeline
28
+ // (see plans/open/mobile/02-push-pipeline.md).
29
+ ],
30
+ experiments: { typedRoutes: true },
31
+ }
32
+
33
+ export default config
@@ -0,0 +1,5 @@
1
+ // Expo's Babel preset — required for expo-router + React Native transforms.
2
+ module.exports = function babel(api) {
3
+ api.cache(true)
4
+ return { presets: ['babel-preset-expo'] }
5
+ }
@@ -0,0 +1,20 @@
1
+ // Metro config — the ONLY Voltro-specific wrinkle in a monorepo: watch the
2
+ // workspace root so `@voltro/*` (and the sibling api's generated types) resolve
3
+ // from the repo, not just this app's node_modules. In a standalone (non-
4
+ // monorepo) app you can delete this file; Expo's default config is enough.
5
+ const { getDefaultConfig } = require('expo/metro-config')
6
+ const path = require('node:path')
7
+
8
+ const projectRoot = __dirname
9
+ const workspaceRoot = path.resolve(projectRoot, '../../..')
10
+
11
+ const config = getDefaultConfig(projectRoot)
12
+ config.watchFolders = [workspaceRoot]
13
+ config.resolver.nodeModulesPaths = [
14
+ path.resolve(projectRoot, 'node_modules'),
15
+ path.resolve(workspaceRoot, 'node_modules'),
16
+ ]
17
+ // Prefer a single physical React across the workspace (RN + web share one).
18
+ config.resolver.disableHierarchicalLookup = true
19
+
20
+ module.exports = config
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@{{projectName}}/{{appName}}",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "main": "expo-router/entry",
6
+ "scripts": {
7
+ "start": "expo start",
8
+ "ios": "expo run:ios",
9
+ "android": "expo run:android",
10
+ "web": "expo start --web",
11
+ "test": "vitest run",
12
+ "typecheck": "tsc --noEmit"
13
+ },
14
+ "dependencies": {
15
+ "@voltro/client": "0.30.1",
16
+ "@voltro/react-native": "0.30.1",
17
+ "expo": "^52.0.0",
18
+ "expo-constants": "~17.0.0",
19
+ "expo-linking": "~7.0.0",
20
+ "expo-router": "~4.0.0",
21
+ "expo-secure-store": "~14.0.0",
22
+ "expo-status-bar": "~2.0.0",
23
+ "@react-native-async-storage/async-storage": "1.23.1",
24
+ "@react-native-community/netinfo": "11.4.1",
25
+ "react": "^19.0.0",
26
+ "react-native": "0.76.5"
27
+ },
28
+ "devDependencies": {
29
+ "@types/react": "^19.0.0",
30
+ "typescript": "^6.0.3",
31
+ "vitest": "^4.1.10"
32
+ }
33
+ }