@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.
- package/CHANGELOG.md +201 -0
- package/dist/apiBuild-CDE4NXNi.js +2 -0
- package/dist/{apiBuild-DDr2aNFd.js → apiBuild-CkpsCqIu.js} +2 -2
- package/dist/bin.js +1 -1
- package/dist/build-51qBWfYY.js +981 -0
- package/dist/{checkCommand-BISqx1OJ.js → checkCommand-C1EbNmwl.js} +1 -1
- package/dist/{checkCommand-DUtMWjcR.js → checkCommand-C30J2F18.js} +3 -3
- package/dist/{codegenCommand-DnVuDxwT.js → codegenCommand-kS3Twuc9.js} +7 -7
- package/dist/{codemodRunner-BlQPfjzA.js → codemodRunner-BKjCwGiN.js} +1127 -895
- package/dist/{commands-CRbxgxv0.js → commands-DowWkYtd.js} +21 -21
- package/dist/{dashboardCommand-Bf_-Ne3P.js → dashboardCommand-gG1y4PFG.js} +5 -5
- package/dist/{dataCommand-BoBJJ-Gb.js → dataCommand-hNOGKz4K.js} +6 -6
- package/dist/{dev-DOEJXicj.js → dev-Ce2gEziv.js} +2422 -2419
- package/dist/dev-Dff_pdik.js +3 -0
- package/dist/{doctorCommand-BrWu67JZ.js → doctorCommand-5ULMpL10.js} +505 -284
- package/dist/doctorCommand-B8H2MYCE.js +2 -0
- package/dist/{dormancyCommand-xn2y-pJm.js → dormancyCommand-DYgI0Kf-.js} +3 -3
- package/dist/{embeddingsCommand-Cn5MbRDM.js → embeddingsCommand-yJivQSrI.js} +2 -2
- package/dist/{envCommand-UJmJIbs9.js → envCommand-ORJUf8r_.js} +8 -8
- package/dist/{evolveCommand-Db30twUy.js → evolveCommand-DTawtTxf.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{infoCommand-BjVXpMlP.js → infoCommand-BFksHunl.js} +1 -1
- package/dist/inspect-CZvsmp8t.js +2 -0
- package/dist/{inspect-DZnan87F.js → inspect-PcC5J-Dl.js} +6 -7
- package/dist/manifestBuild-AUh31bFU.js +2 -0
- package/dist/{manifestBuild-DnbFKF6w.js → manifestBuild-BwiS4iYm.js} +1 -1
- package/dist/{probeCommand-C5fuN6Z2.js → probeCommand-BUYzc0CT.js} +1 -1
- package/dist/{runtimeTrace-BQL_lfz6.js → runtimeTrace-BUk5zMXY.js} +1 -1
- package/dist/{sdkgen-CMUPrDjH.js → sdkgen-CAhmmbjx.js} +1 -1
- package/dist/serveCommand-BUXUtSF5.js +2 -0
- package/dist/{serveCommand-B_w-Mpb_.js → serveCommand-DhtC7WBq.js} +726 -725
- package/dist/serveEntry.js +1 -1
- package/dist/{start-s25GAIgn.js → start-C75w6ftA.js} +1 -1
- package/dist/{start-YaUehtDV.js → start-DNtIlBcn.js} +641 -609
- package/dist/startEntry.js +1 -1
- package/dist/{updateCommand-C9n_Z_oG.js → updateCommand-CtuD5r1t.js} +1 -1
- package/dist/updateCommand-eVKVHj3N.js +2 -0
- package/dist/webDev-Bzb8ZFus.js +2 -0
- package/dist/{webDev-BgdkyjP6.js → webDev-CBN9KkyQ.js} +154 -146
- package/dist/{webhooksCommand-CYXTNvXq.js → webhooksCommand-BPJQOGTe.js} +1 -1
- package/package.json +61 -19
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/_manifest.json +1 -1
- package/templates/agent-docs/ai.md +174 -0
- package/templates/agent-docs/authentication.md +34 -0
- package/templates/agent-docs/data.md +30 -0
- package/templates/agent-docs/database/transactions.md +48 -0
- package/templates/agent-docs/observability.md +13 -2
- package/templates/agent-docs/plugins/auth-supabase.md +21 -0
- package/templates/agent-docs/plugins/sentry.md +91 -8
- package/templates/agent-docs/schema-driven-ui.md +29 -0
- package/templates/agent-docs/whats-new.md +112 -105
- package/templates/apps/api-ai/package.json +6 -6
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-sqlite/package.json +8 -8
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-cms/package.json +9 -9
- package/templates/apps/api-collab/package.json +8 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/api-row-history/package.json +8 -8
- package/templates/apps/api-saas/package.json +11 -11
- package/templates/apps/api-saas-starter/package.json +10 -10
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-status/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -9
- package/templates/apps/changelog/package.json +7 -7
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +7 -7
- package/templates/apps/frontend-app/package.json +8 -8
- package/templates/apps/frontend-auth/package.json +7 -7
- package/templates/apps/frontend-blank/package.json +6 -6
- package/templates/apps/frontend-cms/package.json +8 -8
- package/templates/apps/frontend-collab/package.json +9 -9
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +6 -6
- package/templates/apps/frontend-docs/package.json +8 -8
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +7 -7
- package/templates/apps/frontend-portal/package.json +7 -7
- package/templates/apps/frontend-saas/package.json +7 -7
- package/templates/apps/frontend-spa/package.json +6 -6
- package/templates/apps/frontend-ssr/package.json +6 -6
- package/templates/apps/frontend-ssr-api/package.json +7 -7
- package/templates/apps/frontend-static-blog/package.json +8 -8
- package/templates/apps/frontend-status/package.json +7 -7
- package/templates/apps/mobile-app/package.json +4 -4
- package/dist/apiBuild-B83Cb2Rv.js +0 -2
- package/dist/build-QKP6Bm0J.js +0 -872
- package/dist/dev-Bl9HqtV7.js +0 -3
- package/dist/doctorCommand-DrQv9SL3.js +0 -2
- package/dist/inspect-B0hL41s0.js +0 -2
- package/dist/manifestBuild-UXrnUcXP.js +0 -2
- package/dist/serveCommand-Dtb48ffg.js +0 -2
- package/dist/updateCommand-DsXEAHbd.js +0 -2
- 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
|
-
|
|
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
|
|
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
|
-
#
|
|
122
|
-
|
|
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
|
-
|
|
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
|