@voltro/ui-shadcn 0.76.0 → 0.77.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 (2) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -39,6 +39,71 @@ _Changes staged for the next release accumulate here (rolled up from
39
39
 
40
40
  ---
41
41
 
42
+ ## [0.77.1] — 2026-09-22
43
+
44
+ ### Fixed
45
+
46
+ - **A built page no longer claims it was generated by `voltro dev`** — `@voltro/cli`
47
+
48
+ `voltro dev`, `voltro build` and `voltro start` share one shell generator, and it headed every generated file with ``GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.`` whoever called it. `voltro build` runs Vite with the generated shell as its template, so that line travelled into `dist/` and was readable in the page source of every deployed site — wrong about the command, and wrong about the promise, because nothing overwrites a deployed tree on a boot. The writing command is now passed in and the banner names it: a built page says `voltro build` and `will be overwritten on next build`. The parameter is required, so a future caller has to decide rather than silently inheriting the development wording.
49
+
50
+ ---
51
+
52
+ ## [0.77.0] — 2026-09-22
53
+
54
+ ### ⚠ BREAKING
55
+
56
+ - **Flow run rows record a cancellation request as `cancelling` until confirmed** — `@voltro/plugin-ai-flows`, `@voltro/devtools-ui`, `@voltro/cli`
57
+
58
+ `cancelFlow` used to write the flow row to `cancelled` before asking the engine, so a receipt reporting `engine: 'unreachable'` or `'unknown'` sat next to a row that read as a stopped run, and a reader of the row alone could not tell the difference. `RunStatus` gains `cancelling`: a live row now records the request as `cancelling` with `cancelledAt` as the request time and reads `cancelled` only once the engine confirmed — through the receipt's `engine: 'cancelled'`, the engine honouring the request at its next step boundary, its own run row turning cancelled, or a repeated confirmed request. Terminal rows are never resubmitted. The plugin documentation now states what a UI renders per `engine` outcome. Migration: extend exhaustive `RunStatus` switches and any filter that treated `cancelled` as the request marker; render `cancelling` as an open request and offer a retry when `engine` was `unreachable` or `unknown`. Only `succeeded`, `failed` and `cancelled` are terminal; `useFlowRun` reports `done` for those alone.
59
+
60
+ **`voltro update` carries you across this** — codemod `0.77.0/01_flow-cancelling-row-status`. 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.77.0).
61
+
62
+ ### Added
63
+
64
+ - **An `@source` glob that matches no file is now reported** — `@voltro/cli`
65
+
66
+ Tailwind generates a utility only when it finds the class in a scanned file, and a `@source` pointing at a directory that does not exist is not an error — it is a set with no members. The build stays green and the page renders with classes that name rules which were never generated. `voltro build` now warns for every `@source` glob that matches nothing, and `voltro doctor` reports the same. The usual cause is scanning a dependency at a path it does not publish: a package that ships only its bundle has no `src/` once installed, so `@source "../node_modules/<pkg>/src/**"` matches everything in a workspace (where the dependency is a symlink to its source tree) and nothing in CI. Scan the one path the package publishes — `@source "../node_modules/<pkg>/dist/*.js"` — and rebuild that dependency after editing it, since its bundle is what you scan.
67
+
68
+ ### Fixed
69
+
70
+ - **A failing admission placement no longer holds the drain at one tick per second** — `@voltro/cli`
71
+
72
+ Physical workflow admission drains every placement on a coordinated tick and backs off to a five-second reconciliation bound when a tick finds nothing to admit. A placement whose recovery failed on every tick — a release census page that threw, a placement that could not be opened — kept the tick at its base interval instead: the failure counted as "not idle", the interval never left one second, and the process wrote one schedule claim per second for as long as the condition lasted, with `scanned: 0` on every drain and every run terminal. Such a tick now reports `idle: true` beside its `placementFailures`, `discoveryProblems` and `releaseFailures`, backs off like a healthy idle tick, and retries the failing placement at the reconciliation bound; it is never disarmed, and the `physical recovery incomplete` warning still names the placement, the phase and the database's own reason. Incomplete discovery is unchanged: a further page is known work.
73
+
74
+ Two causes of a permanently failing release census are closed with it. The census pager compared row identities in code-unit order to detect a stalled cursor, while the store had ordered and cursor-filtered the page under its own collation; a correctly ordered page could be refused wholesale, and with it every global pool permit release behind it. The pager now walks a page as the store returns it and refuses only a page that repeats its cursor row or an identity within itself, naming both identities. And a census page that throws no longer pins its cursor: the next tick restarts that placement's census from the beginning, so an owner released behind the cursor since is visited again rather than waiting behind a page that fails on every read.
75
+ - **A file migration body runs under test without a database** — `@voltro/database`
76
+
77
+ `makeFileMigrationContext` accepts an in-memory store without a `sql` client, so a migration's `each`, `rewrite` (temporal guards included), `expect`, `skipUnless`, `store`, `log` and a Promise body under `transactional` run in a unit test against the framework's own in-memory store. The surfaces that genuinely need a connection — `raw()`, every `ctx.schema` operation, an Effect body under `transactional` — fail with the new typed `MigrationNeedsSqlClient`, whose message names the operation and what is missing. A placeholder handed in as `sql`, or a SQL-backed store arriving without its client, is refused at construction with the same error. Previously `rewrite` introspected the live schema unconditionally and a database-free test died with `TypeError: onDialectOrElse is not a function` from inside the bundle. `FileMigrationContextInput` is now the union of `FileMigrationContextLiveInput` (client + store) and `FileMigrationContextInMemoryInput` (a store without `run`); the runner's call shape is unchanged.
78
+ - **`voltro data restore` accepts an empty target and names a takeable remedy** — `@voltro/cli`, `@voltro/data-transfer`, `@voltro/database`
79
+
80
+ A native restore into a freshly created database was refused because the in-progress marker's table did not exist there, and the refusal said to run `voltro db apply` first — which on that target installs the current declared schema, the very state the artefact is about to replace. The restore now creates that one table itself, index- and trigger-free like the migration ledgers, and writes the marker into it before the first destructive statement; a refusal that remains carries the driver's own reason. `--no-marker` now means no marker on every target, warns every time, and no longer reports afterwards that "the restore artefact removed the in-progress marker and it could NOT be written back" over a run that never wrote one. On sqlite and turso the restore closes its bookkeeping connection before the file copy, removes the replaced file's `-wal` / `-shm` sidecars with it, and reopens bookkeeping afterwards: writes through the old connection landed the old database's WAL frames beside the new file, which SQLite replayed over it on the next open.
81
+ - **Rolling-deploy advisory skips tables the same plan creates** — `@voltro/database`, `@voltro/cli`
82
+
83
+ `voltro db plan` and `db apply` no longer flag an operation as unsafe under a rolling deploy when the table it targets is created by the same plan. A fresh deployment against an empty database used to print one "old instances may write values … the new CHECK rejects" line per enum-membership CHECK, because the classifier judged each operation alone and never asked whether the plan's own `create-table` list held the table. No instance on a previous release can touch a table that did not exist a moment earlier, so the rule covers every kind — CHECK, foreign key, unique constraint, `NOT NULL`, type change, JSON validation — not only the one reported. A mixed plan still flags the same operations on pre-existing tables. Every remaining verdict now names its premise (`instances on the previous release …`), and the JSON warning carries a `premise` field, so a deployment with no previous release can tell from the message alone that the advisory does not apply. `classifyRollingDeploySafety` accepts an optional plan context (`{ createdTables }`); `createdTablesOf` builds it from a plan.
84
+ - **The precompiled serve bundle boots with a trace exporter on** — `@voltro/cli`
85
+
86
+ `voltro serve` from the bundle `voltro build` writes died at boot whenever a trace exporter was active — `FRAMEWORK_TRACING=console` with `ConsoleSpanExporter is not a constructor`, an `OTEL_EXPORTER_OTLP_ENDPOINT` with `OTLPTraceExporter is not a constructor` — while the ring-only serve, dev and every test path booted fine. The OpenTelemetry SDK packages are CommonJS and are reached through a dynamic `import()`; the bundler splits such an import into a chunk that exposes only `default`, so every named member read off that namespace was `undefined`. The production bundler now routes a dynamic import of an inlined CommonJS package through an ESM facade that carries the same named exports Node gives it, so the console and OTLP exporters, the metrics readers and any other lazily imported CommonJS package construct as they do under development. Both exporters are now booted from a relocated production bundle in the bundle test matrix, and each has to deliver a span.
87
+
88
+ The facade has a measured cost, split without remainder against the previous release: the web start bundle grows 14 901 B (0.87 %) and the api serve bundle 28 552 B (0.34 %), both from the re-exported CommonJS surfaces; no file count moves. The remaining growth of the same release (22 B and 35 893 B) is ordinary source change. The artefact budgets are re-pinned to the measured sizes with the same 15 % headroom.
89
+ - **A store failure carries the sentence that explains it** — `@voltro/protocol`, `@voltro/database`, `@voltro/runtime`
90
+
91
+ `StoreOperationFailed.cause` reduced every error to its class name, so an eager load on a table with no relations registered arrived as `cause: "Error"` while the refusal's own sentence — naming the table, the missing `relations(...)` declaration and the likely fix — was only recoverable by unwrapping the value by hand. A sentence the framework authored now travels whole in `cause`; anything a driver raised is still reduced to its class and code, because the driver's text carries row data and socket addresses. The error's `message` is now one readable sentence (`query on 'x' failed: …`) instead of a JSON rendering of its fields, so a test reporter, `Cause.pretty` and the undeclared-error envelope all show the diagnosis. And when a statement fails and takes the connection with it, `EffectStore.transactional` now reports the statement's failure (with its code) instead of the rollback's uncoded error that used to replace it. `@voltro/database` exports `authoredError` / `authoredMessageOf` for a hand-written store that wants the same treatment.
92
+ - **A boot missing `@effect/opentelemetry` refuses once and names its cause** — `@voltro/runtime`, `@voltro/cli`
93
+
94
+ `@effect/opentelemetry` has been an optional peer of `@voltro/runtime` since 0.33.0, and the note that made it one said to skip the install unless traces or metrics are exported. That scope was too narrow: the tracer layer loads the OpenTelemetry SDK whenever a trace sink is installed, and `voltro dev` arms its in-process trace ring by default — so every `voltro dev` needs the package with no tracing variable set, and `voltro serve` needs it when its inspect trace ring or an exporter is on. Measured against the published 0.75.0 and 0.76.0 with the package absent: identical refusals, unrelated to `VOLTRO_TRACING_PERSIST`. Three things change. The refusal is now a marked boot refusal: printed once without a stack on every boot path, listing each cause that kept the layer active with the switch that removes it (the previous message named `FRAMEWORK_TRACING=off` for a ring that variable does not touch). `voltro doctor` reports `@effect/opentelemetry is not installed` when the installed runtime cannot see it, using the runtime's own lookup path, and fails the run unless `VOLTRO_TRACING_BUFFER=off` is set. And the corrected scope is re-issued as `0.77.0/03_tracing-peer`, printed for every project because tracing is configured outside the repository; the codemod text scan now also reads tracked `.env*` files, where those switches live. The golden churn is `otelImportFailure` gaining an optional second parameter, which no existing call can fail to compile against.
95
+ - **TypeScript 7 upgrade note: typed ESLint alias pair and removed tsconfig options** — `@voltro/cli`
96
+
97
+ The 0.76.0 dependency note recommended TypeScript `^7.0.2` and read as though a plain bump were sufficient. It is not for a workspace that lints with typescript-eslint: the current release line declares the peer `"typescript": ">=4.8.4 <6.1.0"` and exits 2 on load under TypeScript 7, before linting anything. TypeScript 7 also removed `"moduleResolution": "node"` (TS5108) and `baseUrl` (TS5102), which the note did not mention. A note under an already-published version reaches nobody who acted on it, so the corrected guidance is re-issued under `0.77.0/02_typescript7-side-by-side`: the side-by-side alias pair (`"@typescript/native": "npm:typescript@^7.0.2"`, `"typescript": "npm:@typescript/typescript6@^6.0.2"`) that keeps `tsc` on 7.0 while typed ESLint resolves the 6.0 API, the two removals with their replacements, and when a plain bump is fine. Gated on any `typescript` declaration or removed option, so it reaches workspaces that bumped, reverted, or have not bumped yet.
98
+
99
+ ### Internal (no consumer-facing effect)
100
+
101
+ - **A release moves `latest` only once every tarball is downloadable** — `@voltro/cli`
102
+
103
+ npm writes a new version into a package's metadata before the tarball behind it is downloadable from the CDN, and a consumer installing on `latest` inside that window sees a resolvable version whose download answers 404. The release now holds the promotion of `latest` until every published tarball answers 200 from the URL its own metadata publishes, and refuses to promote — leaving the previous release in place — if one does not within a bounded wait.
104
+
105
+ ---
106
+
42
107
  ## [0.76.0] — 2026-09-21
43
108
 
44
109
  ### ⚠ BREAKING
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/ui-shadcn",
3
- "version": "0.76.0",
3
+ "version": "0.77.1",
4
4
  "description": "Voltro's first-party shadcn/ui kit: Tailwind v4 design tokens (light + dark), 30+ primitives, layout compositions, styled widgets for the @voltro/ui seam, and the canonical theme/language preference-cookie helpers.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -52,7 +52,7 @@
52
52
  "@radix-ui/react-toggle-group": "^1.1.19",
53
53
  "@shikijs/langs": "^4.4.3",
54
54
  "@shikijs/themes": "^4.4.3",
55
- "@voltro/ui": "0.76.0",
55
+ "@voltro/ui": "0.77.1",
56
56
  "class-variance-authority": "^0.7.1",
57
57
  "clsx": "^2.1.1",
58
58
  "shiki": "^4.4.3",