@voltro/cli 0.57.0 → 0.58.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 (109) hide show
  1. package/CHANGELOG.md +201 -0
  2. package/dist/apiBuild-CDE4NXNi.js +2 -0
  3. package/dist/{apiBuild-DDr2aNFd.js → apiBuild-CkpsCqIu.js} +2 -2
  4. package/dist/bin.js +1 -1
  5. package/dist/build-51qBWfYY.js +981 -0
  6. package/dist/{checkCommand-BISqx1OJ.js → checkCommand-C1EbNmwl.js} +1 -1
  7. package/dist/{checkCommand-DUtMWjcR.js → checkCommand-C30J2F18.js} +3 -3
  8. package/dist/{codegenCommand-DnVuDxwT.js → codegenCommand-kS3Twuc9.js} +7 -7
  9. package/dist/{codemodRunner-BlQPfjzA.js → codemodRunner-BKjCwGiN.js} +1127 -895
  10. package/dist/{commands-CRbxgxv0.js → commands-DowWkYtd.js} +21 -21
  11. package/dist/{dashboardCommand-Bf_-Ne3P.js → dashboardCommand-gG1y4PFG.js} +5 -5
  12. package/dist/{dataCommand-BoBJJ-Gb.js → dataCommand-hNOGKz4K.js} +6 -6
  13. package/dist/{dev-DOEJXicj.js → dev-Ce2gEziv.js} +2422 -2419
  14. package/dist/dev-Dff_pdik.js +3 -0
  15. package/dist/{doctorCommand-BrWu67JZ.js → doctorCommand-5ULMpL10.js} +505 -284
  16. package/dist/doctorCommand-B8H2MYCE.js +2 -0
  17. package/dist/{dormancyCommand-xn2y-pJm.js → dormancyCommand-DYgI0Kf-.js} +3 -3
  18. package/dist/{embeddingsCommand-Cn5MbRDM.js → embeddingsCommand-yJivQSrI.js} +2 -2
  19. package/dist/{envCommand-UJmJIbs9.js → envCommand-ORJUf8r_.js} +8 -8
  20. package/dist/{evolveCommand-Db30twUy.js → evolveCommand-DTawtTxf.js} +2 -2
  21. package/dist/index.js +1 -1
  22. package/dist/{infoCommand-BjVXpMlP.js → infoCommand-BFksHunl.js} +1 -1
  23. package/dist/inspect-CZvsmp8t.js +2 -0
  24. package/dist/{inspect-DZnan87F.js → inspect-PcC5J-Dl.js} +6 -7
  25. package/dist/manifestBuild-AUh31bFU.js +2 -0
  26. package/dist/{manifestBuild-DnbFKF6w.js → manifestBuild-BwiS4iYm.js} +1 -1
  27. package/dist/{probeCommand-C5fuN6Z2.js → probeCommand-BUYzc0CT.js} +1 -1
  28. package/dist/{runtimeTrace-BQL_lfz6.js → runtimeTrace-BUk5zMXY.js} +1 -1
  29. package/dist/{sdkgen-CMUPrDjH.js → sdkgen-CAhmmbjx.js} +1 -1
  30. package/dist/serveCommand-BUXUtSF5.js +2 -0
  31. package/dist/{serveCommand-B_w-Mpb_.js → serveCommand-DhtC7WBq.js} +726 -725
  32. package/dist/serveEntry.js +1 -1
  33. package/dist/{start-s25GAIgn.js → start-C75w6ftA.js} +1 -1
  34. package/dist/{start-YaUehtDV.js → start-DNtIlBcn.js} +641 -609
  35. package/dist/startEntry.js +1 -1
  36. package/dist/{updateCommand-C9n_Z_oG.js → updateCommand-CtuD5r1t.js} +1 -1
  37. package/dist/updateCommand-eVKVHj3N.js +2 -0
  38. package/dist/webDev-Bzb8ZFus.js +2 -0
  39. package/dist/{webDev-BgdkyjP6.js → webDev-CBN9KkyQ.js} +154 -146
  40. package/dist/{webhooksCommand-CYXTNvXq.js → webhooksCommand-BPJQOGTe.js} +1 -1
  41. package/package.json +61 -19
  42. package/templates/AGENTS.md +1 -1
  43. package/templates/agent-docs/_index.md +1 -1
  44. package/templates/agent-docs/_manifest.json +1 -1
  45. package/templates/agent-docs/ai.md +174 -0
  46. package/templates/agent-docs/authentication.md +34 -0
  47. package/templates/agent-docs/data.md +30 -0
  48. package/templates/agent-docs/database/transactions.md +48 -0
  49. package/templates/agent-docs/observability.md +13 -2
  50. package/templates/agent-docs/plugins/auth-supabase.md +21 -0
  51. package/templates/agent-docs/plugins/sentry.md +91 -8
  52. package/templates/agent-docs/schema-driven-ui.md +29 -0
  53. package/templates/agent-docs/whats-new.md +112 -105
  54. package/templates/apps/api-ai/package.json +6 -6
  55. package/templates/apps/api-auth/package.json +8 -8
  56. package/templates/apps/api-backend/package.json +7 -7
  57. package/templates/apps/api-backend-deactivation/package.json +7 -7
  58. package/templates/apps/api-backend-mail/package.json +8 -8
  59. package/templates/apps/api-backend-mariadb/package.json +9 -9
  60. package/templates/apps/api-backend-sqlite/package.json +8 -8
  61. package/templates/apps/api-backend-storage/package.json +8 -8
  62. package/templates/apps/api-cms/package.json +9 -9
  63. package/templates/apps/api-collab/package.json +8 -8
  64. package/templates/apps/api-data-advanced/package.json +8 -8
  65. package/templates/apps/api-durable/package.json +8 -8
  66. package/templates/apps/api-feature-flags/package.json +9 -9
  67. package/templates/apps/api-governance/package.json +8 -8
  68. package/templates/apps/api-kv/package.json +8 -8
  69. package/templates/apps/api-moderation/package.json +8 -8
  70. package/templates/apps/api-observability/package.json +8 -8
  71. package/templates/apps/api-ratelimit/package.json +8 -8
  72. package/templates/apps/api-rbac/package.json +8 -8
  73. package/templates/apps/api-rest/package.json +7 -7
  74. package/templates/apps/api-row-history/package.json +8 -8
  75. package/templates/apps/api-saas/package.json +11 -11
  76. package/templates/apps/api-saas-starter/package.json +10 -10
  77. package/templates/apps/api-search/package.json +8 -8
  78. package/templates/apps/api-status/package.json +8 -8
  79. package/templates/apps/api-webhooks/package.json +9 -9
  80. package/templates/apps/changelog/package.json +7 -7
  81. package/templates/apps/edge-functions/package.json +2 -2
  82. package/templates/apps/frontend-admin/package.json +7 -7
  83. package/templates/apps/frontend-app/package.json +8 -8
  84. package/templates/apps/frontend-auth/package.json +7 -7
  85. package/templates/apps/frontend-blank/package.json +6 -6
  86. package/templates/apps/frontend-cms/package.json +8 -8
  87. package/templates/apps/frontend-collab/package.json +9 -9
  88. package/templates/apps/frontend-contact/package.json +7 -7
  89. package/templates/apps/frontend-dashboard/package.json +6 -6
  90. package/templates/apps/frontend-docs/package.json +8 -8
  91. package/templates/apps/frontend-i18n/package.json +6 -6
  92. package/templates/apps/frontend-landing/package.json +7 -7
  93. package/templates/apps/frontend-portal/package.json +7 -7
  94. package/templates/apps/frontend-saas/package.json +7 -7
  95. package/templates/apps/frontend-spa/package.json +6 -6
  96. package/templates/apps/frontend-ssr/package.json +6 -6
  97. package/templates/apps/frontend-ssr-api/package.json +7 -7
  98. package/templates/apps/frontend-static-blog/package.json +8 -8
  99. package/templates/apps/frontend-status/package.json +7 -7
  100. package/templates/apps/mobile-app/package.json +4 -4
  101. package/dist/apiBuild-B83Cb2Rv.js +0 -2
  102. package/dist/build-QKP6Bm0J.js +0 -872
  103. package/dist/dev-Bl9HqtV7.js +0 -3
  104. package/dist/doctorCommand-DrQv9SL3.js +0 -2
  105. package/dist/inspect-B0hL41s0.js +0 -2
  106. package/dist/manifestBuild-UXrnUcXP.js +0 -2
  107. package/dist/serveCommand-Dtb48ffg.js +0 -2
  108. package/dist/updateCommand-DsXEAHbd.js +0 -2
  109. package/dist/webDev-B6ZMX42w.js +0 -2
@@ -111,21 +111,104 @@ What it does:
111
111
  > ```
112
112
  > It's a no-op on the server (SSR) and without a DSN.
113
113
 
114
- The two halves are independent: the api plugin alone gives you server traces + errors; add the web half for the browser hop. For the FULL frontend→backend waterfall in Sentry, run **both** (`sentryPlugin({ traces:true })` on the api + `sentry: { dsn }` on the web app), with matching `release`.
114
+ ### Values the bundle cannot know
115
+
116
+ Everything in that `sentry:` block is a literal frozen into the bundle. That is
117
+ right for a DSN and a release, and wrong for `environment` as soon as one image
118
+ serves more than one environment — one build job and several environment-bound
119
+ deploy jobs is an ordinary pipeline, and a baked `environment` is then true for
120
+ at most one of them. Leaving it out does not help: Sentry defaults a missing
121
+ environment to `production`, so a wrong tag is what you get either way, and a
122
+ wrong tag is worse than none because somebody acts on it.
123
+
124
+ There is no runtime channel to read instead — public values are baked at build
125
+ time by construction — so the value has to be computed where it is known. The
126
+ entry is generated anyway, so it can call something:
127
+
128
+ ```ts
129
+ // app.config.ts
130
+ sentry: { dsn: '…', optionsFrom: 'src/sentryOptions.ts' }
131
+ ```
132
+
133
+ ```ts
134
+ // src/sentryOptions.ts
135
+ export default () => ({
136
+ environment: location.hostname.startsWith('stage-') ? 'staging' : 'production',
137
+ })
138
+ ```
139
+
140
+ The module's default export is called by the generated entry before
141
+ `initSentryBrowser`, may be async, and its result is spread LAST — so it
142
+ overrides the literals above it, which is the whole reason to reach for it.
143
+
144
+ ### Or from the public env
145
+
146
+ Without an explicit option, the browser half reads
147
+ `VOLTRO_PUBLIC_SENTRY_DSN`, `VOLTRO_PUBLIC_SENTRY_ENVIRONMENT` and
148
+ `VOLTRO_PUBLIC_SENTRY_RELEASE` — the same shape the api half already has, where
149
+ `sentryPlugin()` takes no arguments and resolves `SENTRY_*` from the environment.
150
+ Declare them in your `defineEnv` contract and an app is finished without touching
151
+ `app.config.ts`.
152
+
153
+ **A public value must exist when the bundle is BUILT.** `voltro build` freezes the
154
+ declared public subset into the bundle — that is what makes it readable in a
155
+ browser — so these belong in the build (a Docker build-arg, a CI build step), not
156
+ in deployment env. Setting one as a deployment variable deploys cleanly and does
157
+ nothing; `voltro start` warns when it finds one, naming whether the bundle
158
+ carries that key at all.
159
+
160
+ The two halves are independent: the api plugin alone gives you server traces + errors; add the web half for the browser hop. For the full frontend→backend waterfall, run **both** — and both are on by default, so an app with the plugin on the api and `@voltro/plugin-sentry` as a dependency of the web app gets the whole trace from one `SENTRY_DSN` plus one `VOLTRO_PUBLIC_SENTRY_DSN`. Give both halves the same `release`.
161
+
162
+ **Traces default to on, at `tracesSampleRate: 1.0`.** That is the coherent default rather than a generous one: the browser half already sampled every page load, navigation and rpc call at 1.0, so with the api half off each of those spans was emitted, paid for, and belonged to a trace with no server side — a browser hop hanging off nothing. The rate is named on the boot line (`sentry active traces=true tracesSampleRate=1`) so a first boot shows what it is about to send; lower it with `tracesSampleRate`, or set `traces: false` to keep errors and breadcrumbs only.
115
163
 
116
164
  ## Source maps (browser stack traces)
117
165
 
118
- The web bundle is minified, so browser errors arrive in Sentry with **minified** stack traces unless you upload source maps. The plugin does **not** upload them for you — it captures + correlates errors, but wiring the build to publish maps is a per-app build step (it needs your build output plus a Sentry auth token, neither of which the runtime plugin owns). Wire it once with Sentry's official tooling, keyed to the **same `release`** the plugin uses so the maps match the uploaded events:
166
+ The web bundle is minified, so browser errors arrive in Sentry with **minified** stack traces unless the maps are uploaded. `voltro build` does it:
167
+
168
+ ```ts
169
+ // app.config.ts
170
+ web: {
171
+ sourcemaps: {
172
+ mode: 'hidden',
173
+ upload: { org: 'acme', project: 'web' },
174
+ },
175
+ }
176
+ ```
119
177
 
120
178
  ```sh
121
- # after the web build, from the web app dir — uploads maps for one release
122
- pnpm add -D @sentry/cli
123
- SENTRY_AUTH_TOKEN=… npx sentry-cli sourcemaps upload \
124
- --org <org> --project <project> \
125
- --release "$SENTRY_RELEASE" ./dist
179
+ # the build needs both; the deployment needs neither
180
+ SENTRY_AUTH_TOKEN=sntrys_… SENTRY_RELEASE=1.4.2 voltro build
126
181
  ```
127
182
 
128
- Or add `@sentry/vite-plugin` to the web app's Vite config so the upload runs automatically on every production build. Either way, set `release` to the same value (e.g. the git SHA) on BOTH the api `sentryPlugin({ release })` and the web `sentry` field the upload's `--release` must match or Sentry won't resolve the frames. Server stack traces are un-minified already (the api ships readable JS), so this is a browser-only concern.
183
+ That emits the maps, uploads them through `@sentry/cli`, and then **removes them from the output**. Three things in that sentence are the reason it lives in the build rather than in your deploy script:
184
+
185
+ - **The moment.** There is no seam in a Dockerfile between "the bundle exists" and "the image is built". There is one here.
186
+ - **The release.** Sentry matches an artifact to an event by release, and the event's comes from `SENTRY_RELEASE` via `sentryPlugin`. Upload under a different value and no frame resolves — silently, because an upload that matched nothing looks exactly like one that worked. A build with an upload configured and no release **refuses** rather than uploading under nothing.
187
+ - **The deletion.** A `.map` left in `dist` is your source, downloadable by anyone. "We delete it in the deploy step" is a promise a failing build breaks, so the removal is a `finally`: the maps go even when the upload fails, and a configured upload that did not happen fails the build.
188
+
189
+ ### Turning it on selectively
190
+
191
+ `app.config.ts` is TypeScript, so the ordinary branch is the answer:
192
+
193
+ ```ts
194
+ web: {
195
+ sourcemaps: process.env.CI
196
+ ? { mode: 'hidden', upload: { org: 'acme', project: 'web' } }
197
+ : 'hidden',
198
+ }
199
+ ```
200
+
201
+ `'hidden'` alone emits the maps and **keeps** them — right for reading a stack trace locally, and a leak in an image. Omit the field entirely and nothing is emitted, which is the default.
202
+
203
+ `keep` defaults to "keep them only if nothing consumed them": `false` when `upload` is set, `true` when it is not. Set `keep: true` beside an upload when you want both.
204
+
205
+ ### The auth token is not a config field
206
+
207
+ It is read from `SENTRY_AUTH_TOKEN` and there is deliberately no `authToken` option: `app.config.ts` is a committed file, and a token with `project:releases` scope can write to every project in the org. Give it to the **build** (a CI secret, a Docker build secret) — not to the deployment, since the upload happens while the bundle is being built.
208
+
209
+ **Install `@sentry/cli` yourself: `pnpm add -D @sentry/cli` in the web app.** The framework depends on it nowhere, and that is a licence decision rather than a packaging one — it is FSL-1.1-MIT, which restricts competing commercial use, so it must not sit in the dependency graph of a package we publish. A build with an upload configured and the package missing **refuses and names the command**, rather than skipping the upload and leaving you to find out months later that no frame resolves.
210
+
211
+ Server stack traces are un-minified already (the api ships readable JS), so this is a browser-only concern.
129
212
 
130
213
  ## Catching errors — what's automatic, what's manual
131
214
 
@@ -843,6 +843,23 @@ chat.regenerate() // re-run the last user prompt
843
843
  | `regenerate()` | Re-sends the last user prompt as a fresh turn; `undefined` if there is none. |
844
844
  | `sending` | `true` while a `send` is in flight. |
845
845
 
846
+ **You do not need `@ai-sdk/react`.** `useAgentChat` covers the three things it is
847
+ usually kept for:
848
+
849
+ - **Tool calls** — each message carries `parts`, and a `tool` part has
850
+ `toolName`, `state`, `input` and `output`. Render from `parts` rather than
851
+ `content` and a tool call looks the same live and after a reload.
852
+ - **Persistence** — the thread is a DB-backed reactive query, not client state.
853
+ Nothing is lost when the tab closes.
854
+ - **Resumption** — for the same reason. Reopen the tab mid-turn and the
855
+ in-flight assistant message re-renders from the row that is still being
856
+ written; there is no transport to reconnect and no replay to arrange.
857
+
858
+ So an app can drop `@ai-sdk/react` and `DefaultChatTransport` entirely. What
859
+ `useAgentChat` deliberately does not do is manage a transport of its own — it
860
+ composes the agent's synthesized `messages` subscription and `send` action, which
861
+ is what makes the reload behaviour free rather than implemented.
862
+
846
863
  `threadId` is required — mint one per chat (a `useRef`'d uuid) and keep it stable
847
864
  across renders, since it is the subscription key for the whole thread. Render
848
865
  from `message.parts` (text / reasoning / tool / source / file) rather than
@@ -1577,6 +1594,18 @@ changes, so define it with `useCallback` or at module scope unless you want that
1577
1594
  And the bus is per api runtime — an app talking to several apis subscribes once
1578
1595
  per api name.
1579
1596
 
1597
+ **You do not need this hook to REPORT rpc failures.** Every event this bus emits
1598
+ is also published on the client error bus, so a reporter — the Sentry browser
1599
+ integration, or anything wired with `subscribeClientErrors` — already sees it,
1600
+ under `source: 'rpc.mutation' | 'rpc.action' | 'rpc.subscription'` with the rpc
1601
+ tag and `traceId` in `context`. This hook is for cross-cutting *policy* (redirect
1602
+ on `Unauthenticated`, toast on a network failure), not for telemetry; bridging
1603
+ the two by hand now reports twice.
1604
+
1605
+ Everything is published, including a reconnect storm. If that is too loud for
1606
+ your reporter, gate it in the subscriber — which failures are worth an event is
1607
+ your policy, and the bus cannot hold one for every subscriber.
1608
+
1580
1609
  This is the read side of failures that already happened on the wire. To push a
1581
1610
  client-side error the server never saw, call `reportClientError(error, context)`
1582
1611
  instead. Note also that a subscription failure *after* data arrived reaches only