@voltro/cli 0.50.0 → 0.51.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 (111) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/dist/{apiBuild-CFYXo06U.js → apiBuild-CPDHXF72.js} +2 -2
  3. package/dist/apiBuild-GDKuGOMV.js +2 -0
  4. package/dist/appGraph-CFmFKHb2.js +2 -0
  5. package/dist/appGraph-yRuKjOba.js +111 -0
  6. package/dist/bin.js +1 -1
  7. package/dist/{build-CnSH-zru.js → build-DETLZAFt.js} +271 -240
  8. package/dist/{checkCommand-OL41BMIb.js → checkCommand-CWcnDArJ.js} +1 -1
  9. package/dist/{checkCommand-Do3SQbLx.js → checkCommand-DNuPiWMc.js} +56 -46
  10. package/dist/{codegenCommand-BJzaRz6q.js → codegenCommand-BNBHcNNj.js} +2 -2
  11. package/dist/{codemodRunner-De3k0pRd.js → codemodRunner-BDVixlSw.js} +278 -136
  12. package/dist/{commands-By23Ljny.js → commands-B1OiS9bX.js} +24 -23
  13. package/dist/{dashboardCommand-DN1rAABE.js → dashboardCommand-C-vvPY1B.js} +5 -5
  14. package/dist/{dataCommand-B93TUBIx.js → dataCommand-C1GxXW5q.js} +458 -384
  15. package/dist/dbCommand-C27HIsGE.js +2 -0
  16. package/dist/{dbCommand-Bf7Cy0mn.js → dbCommand-If4Y1xQ-.js} +1 -1
  17. package/dist/{dev-BWwE0QjK.js → dev-CK522MV5.js} +1 -1
  18. package/dist/{dev-1yu42ubu.js → dev-kdAg9Q7l.js} +1246 -1246
  19. package/dist/doctorCommand-BK4l18eG.js +2 -0
  20. package/dist/{doctorCommand-y-EbP8st.js → doctorCommand-nKmeW78u.js} +42 -26
  21. package/dist/{doctorSourceRelations-Dd48LPvO.js → doctorSourceRelations-c5mlN5HI.js} +66 -34
  22. package/dist/{dormancyCommand-Dc7KRNCG.js → dormancyCommand-CY3wa_SW.js} +1 -1
  23. package/dist/{embeddingsCommand-kPs132bB.js → embeddingsCommand-BDLIgje_.js} +1 -1
  24. package/dist/{envCommand-E12zSt51.js → envCommand-C6V_xVlT.js} +13 -13
  25. package/dist/{evolveCommand-B3nagPVc.js → evolveCommand-D3c4DSfN.js} +2 -2
  26. package/dist/{generateCommand-CcyvH2ve.js → generateCommand-DTNPGjxo.js} +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/{infoCommand-Cq0Yz98u.js → infoCommand-BnRFEF1o.js} +1 -1
  29. package/dist/{inspect-B7U7Cl_Z.js → inspect-CtL_xTbu.js} +1 -0
  30. package/dist/inspect-CuGDYES0.js +2 -0
  31. package/dist/manifestBuild-CPjhvM62.js +2 -0
  32. package/dist/{manifestBuild-BK42hu0k.js → manifestBuild-CuU1VrSm.js} +2 -2
  33. package/dist/{migrate-D3MK9BpK.js → migrate-DehuBakM.js} +1 -1
  34. package/dist/{runtimeTrace-BpLUcrfy.js → runtimeTrace-ZsBU7Tkx.js} +1 -1
  35. package/dist/{sdkgen-dl4-WKF6.js → sdkgen-O4XqWOjM.js} +1 -1
  36. package/dist/serveCommand-BRnPCxVd.js +2 -0
  37. package/dist/{serveCommand-8CTzQCY0.js → serveCommand-DdiYNBBu.js} +4 -4
  38. package/dist/serveEntry.js +1 -1
  39. package/dist/{start-7HcSIKEp.js → start-BLNmWkLa.js} +331 -327
  40. package/dist/{start-DvlYDyAr.js → start-Dzicuyw8.js} +1 -1
  41. package/dist/startEntry.js +1 -1
  42. package/dist/{updateCommand-i8JbrLAA.js → updateCommand-Bs322Q78.js} +1 -1
  43. package/dist/updateCommand-eXB35SEv.js +2 -0
  44. package/dist/{webDev-B4IEMB0n.js → webDev-B-ubQEMX.js} +283 -224
  45. package/dist/webDev-DposiF3j.js +2 -0
  46. package/dist/{webhooksCommand-B0bdyuQ4.js → webhooksCommand-FLYY9IXh.js} +1 -1
  47. package/package.json +41 -17
  48. package/templates/AGENTS.core.md +15 -5
  49. package/templates/AGENTS.md +16 -6
  50. package/templates/agent-docs/_index.md +1 -1
  51. package/templates/agent-docs/cli.md +92 -3
  52. package/templates/agent-docs/data.md +36 -0
  53. package/templates/agent-docs/internationalization.md +131 -13
  54. package/templates/agent-docs/whats-new.md +73 -27
  55. package/templates/apps/api-ai/package.json +7 -7
  56. package/templates/apps/api-auth/package.json +8 -8
  57. package/templates/apps/api-backend/package.json +7 -7
  58. package/templates/apps/api-backend-deactivation/package.json +7 -7
  59. package/templates/apps/api-backend-mail/package.json +8 -8
  60. package/templates/apps/api-backend-mariadb/package.json +9 -9
  61. package/templates/apps/api-backend-sqlite/package.json +8 -8
  62. package/templates/apps/api-backend-storage/package.json +8 -8
  63. package/templates/apps/api-cms/package.json +10 -10
  64. package/templates/apps/api-collab/package.json +8 -8
  65. package/templates/apps/api-data-advanced/package.json +8 -8
  66. package/templates/apps/api-durable/package.json +8 -8
  67. package/templates/apps/api-feature-flags/package.json +9 -9
  68. package/templates/apps/api-governance/package.json +8 -8
  69. package/templates/apps/api-kv/package.json +8 -8
  70. package/templates/apps/api-moderation/package.json +8 -8
  71. package/templates/apps/api-observability/package.json +8 -8
  72. package/templates/apps/api-ratelimit/package.json +8 -8
  73. package/templates/apps/api-rbac/package.json +8 -8
  74. package/templates/apps/api-rest/package.json +7 -7
  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-versioning/package.json +8 -8
  80. package/templates/apps/api-webhooks/package.json +9 -9
  81. package/templates/apps/changelog/package.json +6 -6
  82. package/templates/apps/edge-functions/package.json +2 -2
  83. package/templates/apps/frontend-admin/package.json +8 -8
  84. package/templates/apps/frontend-app/package.json +9 -9
  85. package/templates/apps/frontend-auth/package.json +8 -8
  86. package/templates/apps/frontend-blank/package.json +7 -7
  87. package/templates/apps/frontend-cms/package.json +9 -9
  88. package/templates/apps/frontend-collab/package.json +10 -10
  89. package/templates/apps/frontend-contact/package.json +7 -7
  90. package/templates/apps/frontend-dashboard/package.json +7 -7
  91. package/templates/apps/frontend-docs/package.json +7 -7
  92. package/templates/apps/frontend-i18n/package.json +6 -6
  93. package/templates/apps/frontend-landing/package.json +7 -7
  94. package/templates/apps/frontend-portal/package.json +8 -8
  95. package/templates/apps/frontend-saas/package.json +8 -8
  96. package/templates/apps/frontend-spa/package.json +7 -7
  97. package/templates/apps/frontend-ssr/package.json +7 -7
  98. package/templates/apps/frontend-ssr-api/package.json +8 -8
  99. package/templates/apps/frontend-static-blog/package.json +6 -6
  100. package/templates/apps/frontend-status/package.json +8 -8
  101. package/templates/apps/mobile-app/package.json +4 -4
  102. package/dist/apiBuild-BWo8KI6n.js +0 -2
  103. package/dist/appGraph-KGDPTuTy.js +0 -110
  104. package/dist/appGraph-zuMGKVYX.js +0 -2
  105. package/dist/dbCommand-Bnl7MSGC.js +0 -2
  106. package/dist/doctorCommand-BmovAwb7.js +0 -2
  107. package/dist/inspect-DUze25t0.js +0 -2
  108. package/dist/manifestBuild-j0n109tt.js +0 -2
  109. package/dist/serveCommand-C_WI4TTG.js +0 -2
  110. package/dist/updateCommand-D91-TZ7E.js +0 -2
  111. package/dist/webDev-B79ji8M5.js +0 -2
@@ -1,4 +1,4 @@
1
- # What's new in 0.50.0
1
+ # What's new in 0.51.0
2
2
 
3
3
  Read this FIRST when a task touches an area you have not worked in recently.
4
4
  It is the cheapest way to notice that the framework grew the thing you were
@@ -9,54 +9,100 @@ BREAKING entries name a codemod; run `voltro update` to apply it.
9
9
 
10
10
  ### ⚠ BREAKING
11
11
 
12
- - **@voltro/cli** — The read-only run-history endpoint moved:
12
+ - **@voltro/data-transfer, @voltro/cli** — The asset counts reported references as if they were blobs. `_voltro_storage_refs` holds one row per reference and several rows legitimately name one key, so a capture of 57 rows over 16 keys wrote `count: 57` into the stamp beside an `assets/` directory holding 16 files, and the restore reported "57 blob(s) restored" while 16 objects appeared. Nothing was lost; what was lost is the ability to check. Anyone answering "are all the blobs there?" after a restore compared the stamp's number against one they counted and found a 3.5x gap that was not one.
13
13
 
14
- GET /_voltro/admin/imports GET /_voltro/admin/transfers
14
+ A key named by several references is now fetched once rather than downloaded, hashed and discarded once per row, and the three numbers are stated separately: `references` (rows enumerated), `count` (distinct keys), `objects` (distinct sha256 bodies), with `totalBytes` and `objectBytes` beside them. The stamp's existing fields keep their names and now mean what a reader always took them for; the new ones are optional, so a stamp written before them still parses.
15
15
 
16
- Same secret, same query parameters, same response shape. Only the path changed.
16
+ **Breaking on one export.** `restoreAssetsFromCas` returns `{ count, objects }` instead of a bare `number` — one number could not answer both questions, which is the defect. `count` is what the old value was, so the migration that changes nothing is `.count`.
17
17
 
18
- It answers for four directions nowimport, export, native backup, native restore — and it named one of them. The subcommand and the table were renamed for exactly that reason in 0.49.0 and this path was left behind, which is worse than renaming none of them: a reader who follows a rename tries the matching path, gets a 404, and concludes the instance is too old.
18
+ **`voltro update` carries you across this**codemod `0.51.0/03_restore-assets-returns-counts`. If you pin versions by hand and never run it, print the notes without changing anything: `voltro update --codemods-only --from <your current version> --dry-run` (this one ships in 0.51.0).
19
+ - **@voltro/i18n** — `<I18nProvider>` takes `timeZone` as its own prop, and `intlConfig` no longer accepts one.
19
20
 
20
- `voltro data transfers --target api` uses the new path for you. What needs a hand is anything calling it directlya monitoring check, an uptime probe, a curl in a runbook, a dashboard datasource. The codemod is `manual` and declares `reach: 'beyond-source'`, so it prints whether or not the path is found in your repository.
21
- - **@voltro/database, @voltro/voltro** — `InterruptedReplace.tables` is `number | null`, and the interface gains `kind?: 'replace' | 'restore'`.
21
+ `intlConfig` exists to forward props to react-intl UNMODIFIED, and for every other member of `IntlConfig` that is the right shape. `timeZone` is the one member this package's own formatters read and they did not read it: `useFormatDate` built `Intl.DateTimeFormat` itself and took only the locale from the provider. So a zone passed through `intlConfig` configured `<T>`'s ICU dates and NOT the `useFormatDate()` beside them. Measured under one provider, one instant (`2026-08-24T23:30:00Z`), `locale: 'de'`, `intlConfig: { timeZone: 'Europe/Berlin' }`, process zone UTC: react-intl rendered `25.08.26, 01:30` and the hook rendered `24.08.26, 23:30`. A different hour, and a different day.
22
22
 
23
- `_voltro_replace_in_progress` records two destructive operations now an import's `--mode replace` and a native `voltro data restore`. A restore replaces the whole database from an artefact, so "how many tables was this going to empty and refill" has no answer: not known up front, not meaningful after.
23
+ The zone has to be a prop this package can see. It is validated once at the provider (an unusable zone a stale cookie, a typo, a runtime with a trimmed ICU is dropped, because `Intl` THROWS on an unknown zone and `useFormatDate` catches, which would degrade every timestamp in the app to a raw `Date` string). It is what the new `useTimeZone()` reports. And it is what the framework fills per request.
24
24
 
25
- Writing `0` would have preserved the type and been worse. That number is rendered into the boot refusal, which is read under pressure, and it would have said `began emptying 0 table(s)` a measurement that was never taken. The framework's own text says "this database" instead; `Number(null)` is `0`, so coercing it reintroduces exactly the sentence being avoided.
25
+ **Migration:** `intlConfig={{ timeZone: 'Europe/Berlin' }}` `timeZone="Europe/Berlin"`. The codemod does it, including the case where the zone was the bag's only member. An `intlConfig` naming a variable is reported by file and line rather than guessed at the property would otherwise stop being read with nothing red anywhere.
26
+ - **@voltro/cli** — A native restore whose bookkeeping store would not open ran anyway, with no in-progress marker and no word about it. `nativeBookkeeping` was `try { … } catch { return undefined }`, and that `undefined` guarded every branch below — including the refusal for a marker that could not be written. So the failure removed the precaution AND the sentence that would have reported it missing, and `markerState` was never computed, defaulting to "held".
26
27
 
27
- `DataTransferRun.direction` also widens to name `'backup'` and `'restore'` explicitly. That one is documentary — the union already ended in `| string`, so no assignability changes.
28
+ What it produced was worse than silence: a failed restore printed "This database is now in an unknown state and the next boot will REFUSE, by design" over a database with zero marker rows. The next boot did not refuse, and `voltro data clear-replace-marker` had nothing to clear. The trigger is not exotic wrong credentials, an unreachable database, a missing env var, no `app.config.ts` from here — and a restore is the operation you run against a target that is already unwell, so the guard fell away exactly when it was needed.
28
29
 
29
- **`voltro update` carries you across this**codemod `0.50.0/03_interrupted-replace-tables-nullable`.
30
+ The reason now travels instead of being caught and dropped. A restore that cannot write the marker REFUSES and names which of the two reasons it was (the store would not open, or the table is not there); those were two separate refusals and are now one, because they are one decision for the operator. `--no-marker` is the deliberate way past it and warns every time. And the `recorded:` line no longer reports a local failure as a property of the target it says where the failure was.
31
+
32
+ **This changes an exit code.** A restore that could not write the marker used to exit 0; it now exits 1. Two invocations are affected — the bookkeeping store will not open, or there is no `app.config.ts` from the working directory — and the second surprises people, because `restore` reads its target from the environment and so looks like it needs no project. It does not, for the dump; it needs one for the marker. `--no-marker` is the deliberate way through and warns every time. The note ships under `reach: 'beyond-source'` because the affected invocations live in cron entries, CI jobs and runbooks rather than in TypeScript.
33
+
34
+ **`voltro update` carries you across this** — codemod `0.51.0/02_restore-refuses-without-marker`. If you pin versions by hand and never run it, print the notes without changing anything: `voltro update --codemods-only --from <your current version> --dry-run` (this one ships in 0.51.0).
30
35
 
31
36
  ### Added
32
37
 
33
- - **@voltro/cli, @voltro/data-transfer, @voltro/database** — `voltro data backup --assets` and `voltro data restore --assets` now move the stored blobs alongside the vendor dump, through the same content-addressed phase the logical `export` / `import` path uses — streamed, deduped by sha256, verified on the way back, resumable per key.
38
+ - **@voltro/i18n, @voltro/cli, @voltro/voltro** — `timeZone` in the web `app.config.ts` the zone every date/time formatter renders in, resolved per request and published so the client agrees.
39
+
40
+ A formatter is deterministic given the value, the locale, the zone and the clock. The locale already came from the provider and was already agreed across the hydration boundary — the server publishes it as `<html lang>` and the client reads that attribute rather than `navigator.languages`, precisely because the browser's own answer can differ from what the server saw. The zone had no such source. `Intl` fell back to the zone of whichever runtime was formatting: the pod on the server (UTC on a container with no `TZ`), the viewer's machine in the browser. Every server-rendered timestamp was therefore a hydration mismatch waiting for a wide enough offset, and across midnight it was a different calendar day.
41
+
42
+ timeZone: 'Europe/Berlin' // one zone for every viewer timeZone: 'viewer' // per request, from the `voltro:tz` cookie defaultTimeZone: 'UTC' // before the viewer's zone is known
43
+
44
+ Whatever it resolves to is stamped on the document as `<html data-voltro-tz>`, and the generated client entry reads that attribute. Both sides then format against one value — which is the property that removes the mismatch, whether or not the value is the viewer's true zone: being wrong together is repairable after mount, being different is not.
45
+
46
+ Under `'viewer'` the framework injects a script that seeds `voltro:tz` from the browser when the cookie is absent, so the server renders in the viewer's zone from the second request with no login. It never overwrites an existing value — the APP is the authoritative writer, at login, from the zone it holds for the signed-in user (`TIMEZONE_COOKIE` and `isSupportedTimeZone` are exported for that). Unset, nothing changes: each runtime keeps using its own zone, and `useTimeZone()` returns `undefined` to say so.
34
47
 
35
- `--assets` was accepted by `backup` and silently ignored, with the only signal a field in the closing JSON reading `NOT included`; `restore` did not accept it at all. A rows-only backup restores a database whose rows reference objects nothing puts back, and the reference and the object are checked at different times, so that state is discovered by a user rather than by the restore.
48
+ This is the RENDER zone. The server-side compute zone what `startOfDay` resolves against inside a handler is still `@voltro/datetime/context`'s seam, unwired.
36
49
 
37
- Three refusals, each for a belief that is otherwise acted on silently: `backup --assets` with no storage provider is refused rather than swallowed; `restore --assets` on a rows-only artefact is refused; a restore WITHOUT `--assets` over an artefact that has them warns and proceeds, because restoring rows without blobs is legitimate and refusing it would push people at `--force`.
50
+ **`apiSurface: compatible`** covers the two golden lines that moved, and they are the same change twice: `makeSsgWrap`'s returned wrapper, and the `wraps` record on the SSG shell input, each gained an OPTIONAL second parameter (the per-request zone + render instant; the wrapper is built once per locale, so they cannot live in the factory). A function with an optional extra parameter is assignable wherever the one-parameter type was expected, so no call site that compiled stops compiling and both are the framework's SSG bridge, documented as never imported by app code. Everything else this release adds to these packages is a pure addition; the one genuine break in `@voltro/i18n` is the `timeZone` prop, which has its own entry and its own codemod.
38
51
 
39
- The dump itself still has no resume — a vendor artefact is one opaque file with no offset to restart from, and the logical path is what exists for that.
40
- - **@voltro/cli, @voltro/database, @voltro/data-transfer** — A native `backup` / `restore` now writes to the same `_voltro_data_transfers` record `import` and `export` use, so `voltro data transfers` answers "did last night's backup finish" from the instance that ran it. A native run reports blobs rather than rows — a vendor tool reports no row count we can trust, and printing `0 row(s)` over a dump that worked would be a wrong measurement.
52
+ ### Changed
41
53
 
42
- `restore` also writes the `_voltro_replace_in_progress` marker before its first destructive statement and clears it after the last write, blobs included, so a killed restore refuses the next boot instead of serving a half-loaded database. `--allow-live` guards from the wrong side — it asks you not to and this guards from the right one. The marker carries a `kind` so the refusal can say something different for a `replace` (re-import the capture) and a `restore` (finish the restore), and `tables` is nullable because a native restore has no table count to claim.
54
+ - **@voltro/cli** A `BREAKING` entry's changelog footer now tells a reader who pins versions by hand how to print the codemod's note without upgrading anything:
43
55
 
44
- The sqlite / turso restore is atomic now (temp file + rename): its marker lives in the very file being replaced, so a plain in-place copy would leave a truncated database with nothing left to catch it.
56
+ voltro update --codemods-only --from <your current version> --dry-run
45
57
 
46
- A target with no `_voltro_data_transfers` table still gets its backup; the closing line says it was not recorded rather than implying it was.
47
- - **@voltro/cli** — A re-issued migration note for the `voltro data imports` → `voltro data transfers` rename that shipped in 0.49.0.
58
+ The footer used to stop at the codemod's id, which is enough for anyone who runs `voltro update` and nothing at all for anyone who does not. A deployment said so plainly: they pin every `@voltro/*` version from their own container scripts, have never run the command, and `CHANGELOG.md` out of the tarball is the only channel anything reaches them through. So a note deliberately filed under an unreached version — our one mechanism for correcting guidance that can no longer be corrected in place — reached that population not at all, and the id told them a fix existed without telling them what it was.
48
59
 
49
- Codemods are selected by `from < version <= to`, so the 0.49.0 note fires once, on the jump that crosses 0.49.0, and cannot be corrected for anyone already past it. Its gate searched `.ts` / `.tsx` while the command it is about lives in shell scripts, CI job definitions and runbooks — so a project whose only occurrence sat in `.gitlab-ci.yml` crossed 0.49.0 and was told there was nothing to apply.
60
+ No new surface: every flag in that invocation is already parsed, which is what lets `check-message-apis.mjs` verify the line rather than trust it.
61
+ - **@voltro/cli** — Two fingerprint labels now say what they compare.
50
62
 
51
- The re-issue is filed under 0.50.0, prints unconditionally, and says what to grep for. Redundant for anyone already fixed; the alternative is firing for nobody.
63
+ The restore's skew warning said the backup's schema "differs from what this code declares". It does not: the value it compares against is the TARGET database's live schema, read by introspection at restore time. Bringing a target to the backup's shape makes the warning disappear while the declared fingerprint is a third value entirely, which is how the mislabel was caught. The comparison is the useful one and is unchanged; the sentence sent readers looking for a code change where a database differed.
64
+
65
+ `voltro db plan` prints `fingerprint: live … · declared …` instead of `from … → to …`, plus a line saying the two are not meant to match. A hash of a live database never equals the hash of the declaration it came from — introspection cannot recover generated expressions, `maxLength` or sensitivity markers — which is why `db drift` keeps a separate live baseline. Printed as `from → to`, `0 operations` under two differing hashes read as a contradiction.
52
66
 
53
67
  ### Fixed
54
68
 
55
- - **@voltro/cli** — A `manual` codemod's `appliesTo` can now search every text file the project owns — `.sh`, `.yml`, `.json`, `.md`, `Makefile`, the `.js` scriptsthrough a new `ctx.text` on the predicate context, and a codemod may declare `reach: 'beyond-source'` to print its note even when nothing matched.
69
+ - **@voltro/cli** — `voltro check` reported a reactivity CHANNEL as a missing table, at `error` severityso it set the exit code:
70
+
71
+ ✗ error reference/dangling-source query(presence.list) reads table 'channel:presence' which does not exist fix: declare a 'channel:presence.entity.ts' table or fix the query's source
72
+
73
+ A `source:` entry is a table name OR a channel's routing key (`channel:<name>`), and every rule resolved entries against the table set. The advice cannot be followed — a channel exists precisely because no table is meant — and because it is an error rather than a warning, `voltro check` could not be a CI gate for any app that uses a channel. That includes an app whose only channel comes from `@voltro/plugin-presence`, whose own `presence.list` declares one: a first-party feature meeting a rule that did not know about it, inside a first-party plugin.
74
+
75
+ Channels are filtered in the ONE helper every table rule reads, rather than at each rule, because a per-rule filter is how the next rule joins without one. The same cause was live one rule over: `observed/declared-but-unobserved` reported "declares source 'channel:presence' but never read it while running" for every exercised procedure that declares a channel. Both are covered, each with a negative control — a filter that dropped the whole source list would have silenced the rules instead of narrowing them.
76
+ - **@voltro/data-transfer** — A native dump no longer carries `_voltro_data_transfers`, for the same reason it stopped carrying the in-progress marker one release ago. The restore opens its own run row there BEFORE the tool runs; the dump then dropped the table mid-flight, and the update recording the outcome wrote into a table that no longer held the row. Measured downstream: after a deliberately failed native restore, `voltro data transfers` showed no restore at all — only the `backup` row the dump had carried over from the SOURCE database. The command that answers "did the restore finish" could not see the run asking the question.
77
+
78
+ Exactly two tables are excluded and the line is deliberate: a native restore into the same deployment should bring the migration ledger, the stored plans, the CDC offsets and the schedule claims, because they describe the data being restored. These two describe the RESTORE, and a record of an operation must not be overwritten by the operation it records. Covered per dialect against real servers and real vendor tools, including a non-vacuity check that a table which SHOULD travel still does.
79
+ - **@voltro/i18n, @voltro/cli** — `useRelativeTime` used `Date.now()` as its base, which under SSR is two different numbers. The server rendered at T and wrote "3 minutes ago" into the HTML; the browser hydrated at T+Δ and rendered "4 minutes ago" whenever a unit boundary fell in the gap. The gap is network latency, so it reproduced on a slow connection and never on the developer's machine, and it had nothing to do with timezones — a correctly zoned app hit it just the same.
80
+
81
+ The server states its render instant (`<html data-voltro-now>`, `renderedAt` on the provider), the first client render uses that same number, and the clock goes live once hydration commits. Server markup and hydration markup are therefore identical BY CONSTRUCTION — the property `await.tsx` and `deferred.ts` already hold, rather than `suppressHydrationWarning`, which would hide a real mismatch along with this one. An explicit `{ now }` still wins.
82
+
83
+ The mount state lives in the provider, not in the hook: a table of ten thousand rows would otherwise pay a state hook and a passive effect each to learn one fact that is true for the whole document. An app that never renders on the server publishes no stamp and takes no second render pass.
84
+ - **@voltro/cli** — `closeNativeRun` writes the transfer row BACK when the restore's own artefact dropped the table it lives in, instead of issuing an `UPDATE` that matches nothing and returning happily. Excluding `_voltro_data_transfers` from our own dumps shortens that window; it does nothing for a dump taken before that change, for a hand-made one, or for mssql and sqlite, whose restores have no per-table exclusion at all. The write-back covers every dialect and every artefact, which is why it is the rule and the exclusion is the optimisation.
85
+
86
+ The row is read back rather than trusted — an update that matched nothing is indistinguishable from one that matched — and a read that itself fails writes nothing, because a duplicate row invented on a guess is its own defect in a history somebody reads under pressure.
87
+ - **@voltro/cli** — A prerendered page shipped the shell's baked `lang="en"` whatever locale it was rendered in.
88
+
89
+ `voltro dev` and `voltro start` both set `<html lang>` per request; the prerender never did. So a `/de/...` artefact — rendered with the German catalog, handed `locale: 'de'` in its `meta` — served `<html lang="en">`. That attribute is what a screen reader pronounces in, what Chrome offers to translate FROM, and what hyphenation uses, so the failure was silent to whoever shipped it and loud only to the people it excluded. The same shape as the 0.30.0 cookie-name drift, one document path over.
90
+
91
+ It surfaced while giving the zone somewhere to travel: `<html lang>` was set by four hand-written copies of one `.replace(/<html…/)` and by nothing in the prerender, and adding a second attribute to that arrangement is how the next one reaches three paths out of five. There is one `applyDocumentAttrs` now, and the prerender is one of its callers — which fixes the locale as a side effect of having somewhere to put the zone.
92
+
93
+ ### Internal (no consumer-facing effect)
94
+
95
+ - **@voltro/cli** — `voltro data backup --assets` / `restore --assets` are now driven against a REAL S3 API (MinIO in the test stack), over the network, with a real backup and a real restore into a second bucket and the bytes compared.
96
+
97
+ The asset half rests on one field: a provider must map "there is no object at that key" to `status === 404`, and nothing looser — a 403 from a rotated credential is also non-transient, and calling that "the object is gone" turns a recoverable outage into a backup that quietly contains nothing. That mapping was measured against memory, filesystem and database live, and against the s3/azure SDK error SHAPES constructed. A constructed shape is a claim about an SDK, not about a round trip: nothing in it exercises signing, path-style addressing, or what the SDK actually raises when a server answers `NoSuchKey`. Two deployments listed exactly this as the gap they could not close either.
98
+
99
+ Both directions are covered against the real server: a dangling reference is stepped over and reported, and a bad credential fails the capture rather than being read as a missing object.
100
+
101
+ The native dialect lane also stops being silent about mssql. It was absent from the array entirely — an absent lane and a covered one look identical from the outside — and it is now listed with a written reason for why it does not register here (`sqlpackage` is a separate Microsoft download on a .NET runtime, absent from `mcr.microsoft.com/mssql-tools`). It is registered rather than skipped-forever, because a skip present on every healthy run teaches readers to ignore skip lines; and an assertion fails if any lane drops out WITHOUT a written reason, or if a reason names a lane that is in fact running.
102
+ - **@voltro/cli, @voltro/plugin-storage** — Coverage for the data commands, at the level the defects actually live.
56
103
 
57
- Both halves close the same gap, and it was in the codemod most in need of a gate. A manual codemod exists BECAUSE its subject could not be transformed, which usually means it is not source at all and `appliesTo` was reading the ts-morph project, which holds `.ts` / `.tsx` and nothing else. Measured with one identical CLI invocation in four files: the `.ts` one printed the note, the `.sh`, `.yml` and `.md` ones printed nothing, and the run reported `codemods: nothing to apply for this jump`. That is an acquittal from a check that never looked at the file, and an acquittal gets acted on.
104
+ `dataDirectFlags.e2e.test.ts` drives every DIRECT-target flag of `voltro data export` / `import` through the real binary against a real sqlite database, and carries the same `DATA_FLAGS`-driven self-check the native suite has: a new direct flag has to be driven there or the file goes red. The api-only flags are listed explicitly with the reason they are not here, and that list is asserted against `DATA_FLAGS` so it cannot become a place to hide an untested flag.
58
105
 
59
- `reach: 'beyond-source'` covers what no scan of one repository can reach an inline script in a CI runner's own UI, a CronJob spec in another repo, a wiki runbook. The note prints either way; only its framing changes, and an uncertain one says plainly that we could not look there.
60
- - **@voltro/data-transfer** — When `mariadb-dump` is absent and the mysql-family fallback runs Oracle's `mysqldump` against a MariaDB server, the failure now names the way out.
106
+ `missingObjectIs404.test.ts` pins the contract the dangling-reference skip rests on: every provider maps "no object at that key" to `status === 404`, and nothing looser. Five providers, three of them live, s3 and azure through their SDK's real error shapes which read DIFFERENT fields (`$metadata.httpStatusCode` vs a bare `statusCode`), so a mapping copied from one to the other would turn dangling references back into hard capture failures on that backend alone.
61
107
 
62
- The stderr it prints is the child's own words and is the right first thing to show — and on its own it is a dead end: `Unknown table 'COLUMN_STATISTICS' in information_schema (1109)` names a table nobody asked for, in a schema nobody wrote, about a feature nobody enabled. Everything needed to act on it was known where the fallback was DECIDED: which binary we wanted, which one we took, and why the difference matters. That travels with the step now and prints under the stderr, including the counter-move a reader reaches for on their own (`--column-statistics=0` does not exist on `mariadb-dump`, so it fixes the wrong client and breaks the right one).
108
+ `codegenFeatureTables.integration.test.ts` measures the count a report was about: `voltro codegen` must carry the tables a `*.cron.tsx` contributes, which the entity walk cannot see. The structural guards beside it were TRUE while that count was wrong. `frameworkSourceTypo.integration.test.ts` measures what catches a misspelled `_voltro_*` source given that the type deliberately does not `voltro check` reports it as a dangling source and exits 1, with a negative control so the check is not merely flagging every framework name.
@@ -12,16 +12,16 @@
12
12
  "dependencies": {
13
13
  "@effect/platform": "^0.97.0",
14
14
  "@effect/rpc": "^0.76.0",
15
- "@voltro/ai": "0.50.0",
16
- "@voltro/cli": "0.50.0",
17
- "@voltro/database": "0.50.0",
18
- "@voltro/env": "0.50.0",
19
- "@voltro/protocol": "0.50.0",
20
- "@voltro/runtime": "0.50.0",
15
+ "@voltro/ai": "0.51.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/database": "0.51.0",
18
+ "@voltro/env": "0.51.0",
19
+ "@voltro/protocol": "0.51.0",
20
+ "@voltro/runtime": "0.51.0",
21
21
  "effect": "^3.22.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@voltro/testing": "0.50.0",
24
+ "@voltro/testing": "0.51.0",
25
25
  "typescript": "^6.0.3",
26
26
  "@vitest/coverage-v8": "^4.1.10",
27
27
  "vitest": "^4.1.10"
@@ -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.50.0",
17
- "@voltro/database": "0.50.0",
18
- "@voltro/env": "0.50.0",
19
- "@voltro/plugin-auth": "0.50.0",
20
- "@voltro/protocol": "0.50.0",
21
- "@voltro/runtime": "0.50.0",
22
- "@voltro/sql-postgres": "0.50.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/database": "0.51.0",
18
+ "@voltro/env": "0.51.0",
19
+ "@voltro/plugin-auth": "0.51.0",
20
+ "@voltro/protocol": "0.51.0",
21
+ "@voltro/runtime": "0.51.0",
22
+ "@voltro/sql-postgres": "0.51.0",
23
23
  "effect": "^3.22.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/testing": "0.50.0",
26
+ "@voltro/testing": "0.51.0",
27
27
  "typescript": "^6.0.3",
28
28
  "@vitest/coverage-v8": "^4.1.10",
29
29
  "vitest": "^4.1.10"
@@ -16,16 +16,16 @@
16
16
  "dependencies": {
17
17
  "@effect/platform": "^0.97.0",
18
18
  "@effect/rpc": "^0.76.0",
19
- "@voltro/cli": "0.50.0",
20
- "@voltro/database": "0.50.0",
21
- "@voltro/env": "0.50.0",
22
- "@voltro/plugin-multitenancy": "0.50.0",
23
- "@voltro/protocol": "0.50.0",
24
- "@voltro/runtime": "0.50.0",
19
+ "@voltro/cli": "0.51.0",
20
+ "@voltro/database": "0.51.0",
21
+ "@voltro/env": "0.51.0",
22
+ "@voltro/plugin-multitenancy": "0.51.0",
23
+ "@voltro/protocol": "0.51.0",
24
+ "@voltro/runtime": "0.51.0",
25
25
  "effect": "^3.22.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@voltro/testing": "0.50.0",
28
+ "@voltro/testing": "0.51.0",
29
29
  "typescript": "^6.0.3",
30
30
  "@vitest/coverage-v8": "^4.1.10",
31
31
  "vitest": "^4.1.10"
@@ -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.50.0",
17
- "@voltro/database": "0.50.0",
18
- "@voltro/env": "0.50.0",
19
- "@voltro/plugin-deactivation": "0.50.0",
20
- "@voltro/protocol": "0.50.0",
21
- "@voltro/runtime": "0.50.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/database": "0.51.0",
18
+ "@voltro/env": "0.51.0",
19
+ "@voltro/plugin-deactivation": "0.51.0",
20
+ "@voltro/protocol": "0.51.0",
21
+ "@voltro/runtime": "0.51.0",
22
22
  "effect": "^3.22.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@voltro/testing": "0.50.0",
25
+ "@voltro/testing": "0.51.0",
26
26
  "typescript": "^6.0.3",
27
27
  "@vitest/coverage-v8": "^4.1.10",
28
28
  "vitest": "^4.1.10"
@@ -13,18 +13,18 @@
13
13
  "dependencies": {
14
14
  "@react-email/components": "^1.0.12",
15
15
  "@react-email/render": "^1.4.0",
16
- "@voltro/cli": "0.50.0",
17
- "@voltro/database": "0.50.0",
18
- "@voltro/env": "0.50.0",
19
- "@voltro/plugin-mail": "0.50.0",
20
- "@voltro/plugin-multitenancy": "0.50.0",
21
- "@voltro/protocol": "0.50.0",
22
- "@voltro/runtime": "0.50.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/database": "0.51.0",
18
+ "@voltro/env": "0.51.0",
19
+ "@voltro/plugin-mail": "0.51.0",
20
+ "@voltro/plugin-multitenancy": "0.51.0",
21
+ "@voltro/protocol": "0.51.0",
22
+ "@voltro/runtime": "0.51.0",
23
23
  "effect": "^3.22.0",
24
24
  "react": "^19.0.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@voltro/testing": "0.50.0",
27
+ "@voltro/testing": "0.51.0",
28
28
  "typescript": "^6.0.3",
29
29
  "@vitest/coverage-v8": "^4.1.10",
30
30
  "vitest": "^4.1.10"
@@ -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.50.0",
17
- "@voltro/database": "0.50.0",
18
- "@voltro/env": "0.50.0",
19
- "@voltro/plugin-multitenancy": "0.50.0",
20
- "@voltro/plugin-storage": "0.50.0",
21
- "@voltro/protocol": "0.50.0",
22
- "@voltro/runtime": "0.50.0",
23
- "@voltro/sql-mysql": "0.50.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/database": "0.51.0",
18
+ "@voltro/env": "0.51.0",
19
+ "@voltro/plugin-multitenancy": "0.51.0",
20
+ "@voltro/plugin-storage": "0.51.0",
21
+ "@voltro/protocol": "0.51.0",
22
+ "@voltro/runtime": "0.51.0",
23
+ "@voltro/sql-mysql": "0.51.0",
24
24
  "effect": "^3.22.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@voltro/testing": "0.50.0",
27
+ "@voltro/testing": "0.51.0",
28
28
  "typescript": "^6.0.3",
29
29
  "@vitest/coverage-v8": "^4.1.10",
30
30
  "vitest": "^4.1.10"
@@ -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.50.0",
17
- "@voltro/database": "0.50.0",
18
- "@voltro/env": "0.50.0",
19
- "@voltro/plugin-multitenancy": "0.50.0",
20
- "@voltro/protocol": "0.50.0",
21
- "@voltro/runtime": "0.50.0",
22
- "@voltro/sql-sqlite": "0.50.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/database": "0.51.0",
18
+ "@voltro/env": "0.51.0",
19
+ "@voltro/plugin-multitenancy": "0.51.0",
20
+ "@voltro/protocol": "0.51.0",
21
+ "@voltro/runtime": "0.51.0",
22
+ "@voltro/sql-sqlite": "0.51.0",
23
23
  "effect": "^3.22.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/testing": "0.50.0",
26
+ "@voltro/testing": "0.51.0",
27
27
  "typescript": "^6.0.3",
28
28
  "@vitest/coverage-v8": "^4.1.10",
29
29
  "vitest": "^4.1.10"
@@ -11,17 +11,17 @@
11
11
  "test": "voltro test"
12
12
  },
13
13
  "dependencies": {
14
- "@voltro/cli": "0.50.0",
15
- "@voltro/database": "0.50.0",
16
- "@voltro/env": "0.50.0",
17
- "@voltro/plugin-multitenancy": "0.50.0",
18
- "@voltro/plugin-storage": "0.50.0",
19
- "@voltro/protocol": "0.50.0",
20
- "@voltro/runtime": "0.50.0",
14
+ "@voltro/cli": "0.51.0",
15
+ "@voltro/database": "0.51.0",
16
+ "@voltro/env": "0.51.0",
17
+ "@voltro/plugin-multitenancy": "0.51.0",
18
+ "@voltro/plugin-storage": "0.51.0",
19
+ "@voltro/protocol": "0.51.0",
20
+ "@voltro/runtime": "0.51.0",
21
21
  "effect": "^3.22.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@voltro/testing": "0.50.0",
24
+ "@voltro/testing": "0.51.0",
25
25
  "typescript": "^6.0.3",
26
26
  "@vitest/coverage-v8": "^4.1.10",
27
27
  "vitest": "^4.1.10"
@@ -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.50.0",
17
- "@voltro/cms": "0.50.0",
18
- "@voltro/database": "0.50.0",
19
- "@voltro/env": "0.50.0",
20
- "@voltro/plugin-auth": "0.50.0",
21
- "@voltro/plugin-multitenancy": "0.50.0",
22
- "@voltro/protocol": "0.50.0",
23
- "@voltro/runtime": "0.50.0",
24
- "@voltro/sql-postgres": "0.50.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/cms": "0.51.0",
18
+ "@voltro/database": "0.51.0",
19
+ "@voltro/env": "0.51.0",
20
+ "@voltro/plugin-auth": "0.51.0",
21
+ "@voltro/plugin-multitenancy": "0.51.0",
22
+ "@voltro/protocol": "0.51.0",
23
+ "@voltro/runtime": "0.51.0",
24
+ "@voltro/sql-postgres": "0.51.0",
25
25
  "effect": "^3.22.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@voltro/testing": "0.50.0",
28
+ "@voltro/testing": "0.51.0",
29
29
  "typescript": "^6.0.3",
30
30
  "@vitest/coverage-v8": "^4.1.10",
31
31
  "vitest": "^4.1.10"
@@ -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.50.0",
17
- "@voltro/database": "0.50.0",
18
- "@voltro/env": "0.50.0",
19
- "@voltro/local-first": "0.50.0",
20
- "@voltro/plugin-multitenancy": "0.50.0",
21
- "@voltro/protocol": "0.50.0",
22
- "@voltro/runtime": "0.50.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/database": "0.51.0",
18
+ "@voltro/env": "0.51.0",
19
+ "@voltro/local-first": "0.51.0",
20
+ "@voltro/plugin-multitenancy": "0.51.0",
21
+ "@voltro/protocol": "0.51.0",
22
+ "@voltro/runtime": "0.51.0",
23
23
  "effect": "^3.22.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/testing": "0.50.0",
26
+ "@voltro/testing": "0.51.0",
27
27
  "typescript": "^6.0.3",
28
28
  "@vitest/coverage-v8": "^4.1.10",
29
29
  "vitest": "^4.1.10"
@@ -12,17 +12,17 @@
12
12
  "dependencies": {
13
13
  "@effect/platform": "^0.97.0",
14
14
  "@effect/rpc": "^0.76.0",
15
- "@voltro/cli": "0.50.0",
16
- "@voltro/database": "0.50.0",
17
- "@voltro/env": "0.50.0",
18
- "@voltro/plugin-governance": "0.50.0",
19
- "@voltro/plugin-multitenancy": "0.50.0",
20
- "@voltro/protocol": "0.50.0",
21
- "@voltro/runtime": "0.50.0",
15
+ "@voltro/cli": "0.51.0",
16
+ "@voltro/database": "0.51.0",
17
+ "@voltro/env": "0.51.0",
18
+ "@voltro/plugin-governance": "0.51.0",
19
+ "@voltro/plugin-multitenancy": "0.51.0",
20
+ "@voltro/protocol": "0.51.0",
21
+ "@voltro/runtime": "0.51.0",
22
22
  "effect": "^3.22.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@voltro/testing": "0.50.0",
25
+ "@voltro/testing": "0.51.0",
26
26
  "typescript": "^6.0.3",
27
27
  "@vitest/coverage-v8": "^4.1.10",
28
28
  "vitest": "^4.1.10"
@@ -12,17 +12,17 @@
12
12
  "dependencies": {
13
13
  "@effect/platform": "^0.97.0",
14
14
  "@effect/rpc": "^0.76.0",
15
- "@voltro/cli": "0.50.0",
16
- "@voltro/database": "0.50.0",
17
- "@voltro/env": "0.50.0",
18
- "@voltro/plugin-multitenancy": "0.50.0",
19
- "@voltro/protocol": "0.50.0",
20
- "@voltro/runtime": "0.50.0",
21
- "@voltro/workflow": "0.50.0",
15
+ "@voltro/cli": "0.51.0",
16
+ "@voltro/database": "0.51.0",
17
+ "@voltro/env": "0.51.0",
18
+ "@voltro/plugin-multitenancy": "0.51.0",
19
+ "@voltro/protocol": "0.51.0",
20
+ "@voltro/runtime": "0.51.0",
21
+ "@voltro/workflow": "0.51.0",
22
22
  "effect": "^3.22.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@voltro/testing": "0.50.0",
25
+ "@voltro/testing": "0.51.0",
26
26
  "typescript": "^6.0.3",
27
27
  "@vitest/coverage-v8": "^4.1.10",
28
28
  "vitest": "^4.1.10"
@@ -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.50.0",
17
- "@voltro/database": "0.50.0",
18
- "@voltro/env": "0.50.0",
19
- "@voltro/plugin-flags": "0.50.0",
20
- "@voltro/plugin-multitenancy": "0.50.0",
21
- "@voltro/protocol": "0.50.0",
22
- "@voltro/runtime": "0.50.0",
23
- "@voltro/sql-postgres": "0.50.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/database": "0.51.0",
18
+ "@voltro/env": "0.51.0",
19
+ "@voltro/plugin-flags": "0.51.0",
20
+ "@voltro/plugin-multitenancy": "0.51.0",
21
+ "@voltro/protocol": "0.51.0",
22
+ "@voltro/runtime": "0.51.0",
23
+ "@voltro/sql-postgres": "0.51.0",
24
24
  "effect": "^3.22.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@voltro/testing": "0.50.0",
27
+ "@voltro/testing": "0.51.0",
28
28
  "typescript": "^6.0.3",
29
29
  "@vitest/coverage-v8": "^4.1.10",
30
30
  "vitest": "^4.1.10"
@@ -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.50.0",
17
- "@voltro/database": "0.50.0",
18
- "@voltro/env": "0.50.0",
19
- "@voltro/plugin-audit": "0.50.0",
20
- "@voltro/plugin-governance": "0.50.0",
21
- "@voltro/protocol": "0.50.0",
22
- "@voltro/runtime": "0.50.0",
16
+ "@voltro/cli": "0.51.0",
17
+ "@voltro/database": "0.51.0",
18
+ "@voltro/env": "0.51.0",
19
+ "@voltro/plugin-audit": "0.51.0",
20
+ "@voltro/plugin-governance": "0.51.0",
21
+ "@voltro/protocol": "0.51.0",
22
+ "@voltro/runtime": "0.51.0",
23
23
  "effect": "^3.22.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@voltro/testing": "0.50.0",
26
+ "@voltro/testing": "0.51.0",
27
27
  "typescript": "^6.0.3",
28
28
  "@vitest/coverage-v8": "^4.1.10",
29
29
  "vitest": "^4.1.10"
@@ -12,17 +12,17 @@
12
12
  "dependencies": {
13
13
  "@effect/platform": "^0.97.0",
14
14
  "@effect/rpc": "^0.76.0",
15
- "@voltro/cli": "0.50.0",
16
- "@voltro/database": "0.50.0",
17
- "@voltro/env": "0.50.0",
18
- "@voltro/kv": "0.50.0",
19
- "@voltro/plugin-multitenancy": "0.50.0",
20
- "@voltro/protocol": "0.50.0",
21
- "@voltro/runtime": "0.50.0",
15
+ "@voltro/cli": "0.51.0",
16
+ "@voltro/database": "0.51.0",
17
+ "@voltro/env": "0.51.0",
18
+ "@voltro/kv": "0.51.0",
19
+ "@voltro/plugin-multitenancy": "0.51.0",
20
+ "@voltro/protocol": "0.51.0",
21
+ "@voltro/runtime": "0.51.0",
22
22
  "effect": "^3.22.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@voltro/testing": "0.50.0",
25
+ "@voltro/testing": "0.51.0",
26
26
  "typescript": "^6.0.3",
27
27
  "@vitest/coverage-v8": "^4.1.10",
28
28
  "vitest": "^4.1.10"