@aceshooting/lyra-ui 10.0.1 → 11.1.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 (83) hide show
  1. package/CHANGELOG.md +271 -0
  2. package/custom-elements.json +1 -1
  3. package/design-tokens.json +13 -0
  4. package/dist/cli/migrate-wa.mjs +164 -1
  5. package/dist/cli/migration-contract.json +1 -1
  6. package/dist/components/charts/chart/box-plot.class.d.ts +27 -0
  7. package/dist/components/charts/chart/box-plot.class.js +14 -4
  8. package/dist/components/charts/chart/box-plot.styles.js +28 -0
  9. package/dist/components/charts/chart/chart.class.d.ts +27 -0
  10. package/dist/components/charts/chart/chart.class.js +15 -5
  11. package/dist/components/charts/chart/chart.styles.js +28 -0
  12. package/dist/components/charts/chart/lite-chart.class.d.ts +32 -0
  13. package/dist/components/charts/chart/lite-chart.class.js +17 -4
  14. package/dist/components/charts/chart/lite-chart.styles.js +29 -0
  15. package/dist/components/data/heatmap/heatmap.class.d.ts +35 -2
  16. package/dist/components/data/heatmap/heatmap.class.js +2 -2
  17. package/dist/components/data/table/table.class.d.ts +19 -0
  18. package/dist/components/data/table/table.class.js +3 -3
  19. package/dist/components/forms/combobox/combobox.class.d.ts +71 -3
  20. package/dist/components/forms/combobox/combobox.class.js +4 -2
  21. package/dist/components/forms/combobox/combobox.styles.js +9 -0
  22. package/dist/components/forms/date-picker/date-input.class.d.ts +12 -1
  23. package/dist/components/forms/date-picker/date-input.class.js +4 -2
  24. package/dist/components/forms/date-picker/date-picker.class.d.ts +72 -0
  25. package/dist/components/forms/date-picker/date-picker.class.js +15 -3
  26. package/dist/components/forms/date-picker/date-picker.styles.js +46 -0
  27. package/dist/components/media/flag/flag.class.d.ts +3 -1
  28. package/dist/components/media/flag/flag.class.js +1 -1
  29. package/dist/components/media/map/map.class.d.ts +39 -2
  30. package/dist/components/media/map/map.class.js +1 -1
  31. package/dist/components/overlays/dialog/dialog.class.d.ts +20 -0
  32. package/dist/components/overlays/overlay/popover.class.d.ts +19 -3
  33. package/dist/components/overlays/overlay/popover.class.js +1 -1
  34. package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +1 -1
  35. package/dist/custom-elements-jsx.d.ts +31 -16
  36. package/dist/internal/canvas.js +1 -1
  37. package/dist/internal/package-metadata.d.ts +1 -1
  38. package/dist/internal/package-metadata.js +1 -1
  39. package/dist/internal/tokens.styles.js +1 -0
  40. package/dist/lyra.d.ts +1 -1
  41. package/dist/svelte.d.ts +31 -16
  42. package/dist/theme.css +32 -0
  43. package/dist/vue.d.ts +31 -16
  44. package/llms/components/lr-agent-eval-dashboard.md +1 -1
  45. package/llms/components/lr-agent-workspace.md +1 -1
  46. package/llms/components/lr-bar-chart.md +4 -3
  47. package/llms/components/lr-box-plot.md +15 -4
  48. package/llms/components/lr-bubble-chart.md +4 -3
  49. package/llms/components/lr-chart.md +13 -3
  50. package/llms/components/lr-chunk-inspector.md +1 -1
  51. package/llms/components/lr-combobox.md +42 -6
  52. package/llms/components/lr-date-input.md +40 -4
  53. package/llms/components/lr-date-picker.md +40 -4
  54. package/llms/components/lr-dialog.md +2 -1
  55. package/llms/components/lr-doughnut-chart.md +4 -3
  56. package/llms/components/lr-entity-dossier.md +1 -1
  57. package/llms/components/lr-eval-run.md +1 -1
  58. package/llms/components/lr-flag.md +10 -3
  59. package/llms/components/lr-grounding-summary.md +1 -1
  60. package/llms/components/lr-heatmap.md +20 -2
  61. package/llms/components/lr-histogram.md +4 -3
  62. package/llms/components/lr-line-chart.md +4 -3
  63. package/llms/components/lr-lite-chart.md +19 -3
  64. package/llms/components/lr-map.md +21 -4
  65. package/llms/components/lr-memory-panel.md +1 -1
  66. package/llms/components/lr-option.md +41 -5
  67. package/llms/components/lr-pie-chart.md +4 -3
  68. package/llms/components/lr-polar-area-chart.md +4 -3
  69. package/llms/components/lr-popover.md +20 -1
  70. package/llms/components/lr-provenance-panel.md +1 -1
  71. package/llms/components/lr-radar-chart.md +4 -3
  72. package/llms/components/lr-rag-answer.md +1 -1
  73. package/llms/components/lr-rag-eval-dashboard.md +1 -1
  74. package/llms/components/lr-retrieval-results.md +1 -1
  75. package/llms/components/lr-retrieval-trace.md +1 -1
  76. package/llms/components/lr-scatter-chart.md +4 -3
  77. package/llms/peers.md +8 -8
  78. package/llms/tokens.md +27 -1
  79. package/llms-full.txt +231 -28
  80. package/package.json +1 -1
  81. package/vscode-css-data.json +70 -0
  82. package/vscode-html-data.json +131 -20
  83. package/web-types.json +190 -23
package/CHANGELOG.md CHANGED
@@ -1,5 +1,276 @@
1
1
  # Changelog
2
2
 
3
+ ## 11.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 555154e: Four follow-ups to 11.0.0, all reported against the shipped release:
8
+
9
+ - **`<lr-date-input>` forwards `presets`** to its nested picker, and exports the `presets` /
10
+ `preset-button` parts. 11.0.0 landed the feature on the inline calendar only, while the compact
11
+ text-field-plus-popover shape is the one a dashboard time filter actually uses — and there was no
12
+ consumer-side escape hatch, since a CSS part cannot set a JS property.
13
+ - **`<lr-date-picker>` gains a read-only `appliedPreset`**, reporting which preset produced the
14
+ current value (`undefined` for a hand-picked range). 11.0.0 presented commit-path
15
+ indistinguishability as a feature; it is, for serialization and clamping, but it destroyed the one
16
+ fact a dashboard filter needs, because "Last 7 days" must stay *relative* across a reload.
17
+ Re-deriving it by matching `value` is both the mapping table `presets` exists to delete and
18
+ ambiguous — Today and This month coincide on the 1st.
19
+ - **`LyraDateRangePreset.start`/`.end` are now optional**, meaning an open bound that resolves to
20
+ `min`/`max`. The changelog and doc comment advertised an "All time" preset that the type could not
21
+ express and `applyPreset` silently ignored, so that button rendered and did nothing. Where the
22
+ matching `min`/`max` is unset the button now renders **disabled** rather than looking live.
23
+ - **`<lr-lite-chart>` gains `showDataTable` and `dataTableToggle`** with the same semantics and the
24
+ same `data-table-toggle` part as `<lr-chart>`. It extends `LyraElement` directly and inherited
25
+ nothing from the 11.0.0 addition, which left the component that exists to avoid the Chart.js peers
26
+ as the only one still needing a hand-rolled `<details>` — or Chart.js, for a button.
27
+
28
+ ### Patch Changes
29
+
30
+ - 555154e: Corrected 14 documentation annotations that named **10.1.0**, a version that was never published.
31
+ Those members shipped in 11.0.0: the docs were written while the release was expected to be a
32
+ minor, the public-API semver gate then required a major, and nothing restamped the annotations.
33
+
34
+ This was worse than a typo. A consumer on 10.0.1 reading "new in 10.1.0" either installs a version
35
+ that does not exist, or assumes their 10.0.1 install already has the feature and debugs an
36
+ attribute that silently does nothing — Lit accepts an unknown attribute without error, so there is
37
+ no failure signal at all.
38
+
39
+ Also corrects the generated per-component "Optional peers" header, which attributed peers reached
40
+ only through an erased `import type`. `lr-lite-chart` was listed under all four Chart.js peers
41
+ despite existing precisely to avoid them, inverting the choice the component offers; the same fix
42
+ drops several other over-attributions (the d3 peers were credited to 12 tags and genuinely belong
43
+ to 2). Side-effect registration edges still count, so transitive peers are unaffected.
44
+ - 555154e: **Fixes a silent focus-ring regression introduced in 11.0.0.** `--lr-focus-ring` was added as a
45
+ composite outline shorthand explicitly to replace the Web Awesome `outline: var(--wa-focus-ring)`
46
+ idiom — but it was declared only inside each component's `:host`, and that idiom is written by a
47
+ consumer against their *own* element. At document scope the token resolved to the empty string,
48
+ which makes the whole `outline` declaration invalid at computed-value time; because `outline` does
49
+ not inherit, the ring did not fall back, it **disappeared**. No console warning, no test signal —
50
+ a WCAG 2.4.7 failure that looked correct in review. The library evidenced the gap itself:
51
+ `styles/native.css` hand-expanded the ring rather than using the composite.
52
+
53
+ `theme.css` now declares `--lr-focus-ring` and its three parts at document scope, on `:root` and on
54
+ both mode selectors — not `:root` alone, because `.lr-dark` / `[data-lr-theme='dark']` may sit on
55
+ any ancestor, and resolving the colour once at `:root` would freeze the light value for a subtree
56
+ that later switches. Components are unaffected: their own `:host` declarations still win, which is
57
+ now asserted.
58
+
59
+ `styles/native.css` deliberately keeps its fallback-chained expansion so it continues to work for
60
+ consumers who load it without `theme.css`.
61
+
62
+ Reported twice independently, with a live `getComputedStyle` repro showing `outlineStyle: "none"`.
63
+ - 2821af9: Three defects reported against 11.0.0:
64
+
65
+ - **`<lr-pdf-viewer>` text layer, reopened.** 10.0.0 fixed only half of it. The chunk bounding
66
+ guarded against copying an `undefined` style over a good one, but it also *rebuilt* the style map
67
+ from the fonts of the items retained in that chunk — so a style PDF.js announces ahead of the
68
+ items that use it was dropped and never re-sent. Both failures end the same way: a later lookup
69
+ reads `undefined.vertical` and aborts the rest of the page. Measured by the reporter on a 9-page
70
+ document as 4 affected pages and 101 of 271 spans orphaned. Now every own entry the chunk carries
71
+ is copied and only `undefined` is skipped, so falsy-but-defined styles (`null`, `0`, `''`) still
72
+ survive and an inherited `constructor`/`toString` stays unreachable.
73
+
74
+ - **`<lr-table>` no longer dies on a column missing its `cell` renderer.** `cell` is typed and
75
+ documented required, but columns arrive through a lit `.columns=${...}` binding, which `tsc` does
76
+ not type-check — so required-ness was unenforced where it is written *and* unguarded at runtime.
77
+ A single malformed column threw out of lit's `repeat`, taking the whole table down with a stack
78
+ naming neither the column nor the table. It now degrades to an empty cell and reports once per
79
+ column, naming the key, the tag and the missing member.
80
+
81
+ - **The shared scratch canvas is created with `willReadFrequently`.** `<lr-heatmap>`'s colour
82
+ resolution does a 1×1 `getImageData()` readback for any colour the canvas normalizes into a form
83
+ its string parsers reject (`color-mix()`, `oklch()`, `lab()`), which Chrome warns about on every
84
+ page carrying a heatmap. A `color-mix()` ramp takes that readback per cell.
85
+
86
+ ## 11.0.0
87
+
88
+ ### Major Changes
89
+
90
+ - 5066d4b: **Version note: this major carries no known breaking change for consumers.**
91
+
92
+ Everything in this release is additive or a bug fix — no public member was removed, renamed, or
93
+ had its behaviour or default altered. The major bump is taken because the public-API semver gate
94
+ (`check:public-api`) classifies 328 changes as breaking, and every one of them is fingerprint or
95
+ generated-type churn rather than a real break:
96
+
97
+ - 248 `:dependencies` and 39 `:contract` hash changes — a symbol's transitive-dependency
98
+ fingerprint moves whenever a widely-composed base class gains a member, so adding one property to
99
+ `LyraChart` rewrites the hash of every chart subclass and every subpath that re-exports it.
100
+ - 39 generated React/Vue/Svelte props **type strings**, widened by the newly added props. The
101
+ differ compares the printed type text, which cannot distinguish an additive union widening from a
102
+ removal.
103
+ - 2 `lr-popover` `popup-role` default entries moving `null → 'dialog'`. The default did not change;
104
+ this release simply documents it with `@default` for the first time, so the manifest records a
105
+ value where it previously recorded none.
106
+
107
+ Consumers upgrading from 10.x should not need code changes. If you use the generated framework
108
+ prop types, the unions gained members but lost none.
109
+
110
+ ### Minor Changes
111
+
112
+ - 2fb4af7: `<lr-chart>` (and every chart subclassing it — bar, line, pie, doughnut, radar, polar-area,
113
+ scatter, bubble, histogram) and `<lr-box-plot>` gain `dataTableToggle` (`data-table-toggle`), which
114
+ renders a localized disclosure button above the accessible data table.
115
+
116
+ `showDataTable` was all-or-nothing: the table was either permanently screen-reader-only or
117
+ permanently visible, so a sighted reader who wanted the numbers behind a chart could only get them
118
+ if the consumer hand-rolled a `<details>` around a duplicated copy of the table. With the toggle
119
+ on, `showDataTable` becomes the disclosure's initial state rather than its whole behavior. The
120
+ table stays in the DOM in both states, so assistive technology never loses it, and the button
121
+ carries `aria-expanded` plus `aria-controls`. A new `data-table-toggle` CSS part styles the
122
+ control. Unset, nothing renders and behavior is unchanged.
123
+ - e084afb: `<lr-combobox>` now renders `<lr-option>`'s adornment slots, and gains `visibleOptions` for bounding
124
+ the suggestion popup's height.
125
+
126
+ **Adornments (a fixed contract, not just a new feature).** `<lr-option>` documented `start`/`end`
127
+ slots, their `prefix`/`suffix` aliases, and four matching CSS parts — but `<lr-combobox>` builds its
128
+ popup from normalized row *data* rather than from the light-DOM nodes, so inside the one component
129
+ `<lr-option>` exists to feed, none of them rendered. A row could show a colour dot, a badge and a
130
+ sub-line but not a 16px image, which is the one adornment a country, currency, language or user
131
+ picker most often wants, and neither documented workaround was available (`::part(option)` cannot be
132
+ compounded past the part, and `dot-color` rejects `url()`).
133
+
134
+ Adornments now render as new `option-start` / `option-end` parts, inert and `aria-hidden` so they
135
+ never join the option's accessible name. The nodes are **cloned** into the row, so the author's own
136
+ `<lr-option>` subtree is left exactly where they put it rather than being moved into a shadow root
137
+ as a side effect of opening a dropdown. Async `source` rows can supply the same `start`/`end`
138
+ fields alongside the existing `icon`.
139
+
140
+ **`visibleOptions`** (`visible-options`) bounds the popup to about that many rows, leaving the rest
141
+ reachable by scrolling. It is measured from where row N actually starts, since a row's height varies
142
+ with sub-lines, adornments and group labels. Unset, the listbox keeps exactly its previous
143
+ max-height behavior.
144
+
145
+ The doc comments on all three caps — `visibleOptions`, `maxRender`, and `maxOptionsVisible` — now
146
+ each state how they differ from the other two, which was the confusion that prompted this.
147
+ - 3b3af14: `<lr-date-picker>` gains `presets`, a quick-range button row for the dashboard time-filter shape
148
+ (Today / Last 7 days / Last 30 days / This month / All time).
149
+
150
+ The pieces for this existed but were split across two components that each held half the contract:
151
+ the date components had the calendar, locale and range logic but no preset affordance, while
152
+ `<lr-time-range>` had exactly the wanted preset API but is a two-handle numeric brush with no date
153
+ logic, so a caller had to map a time axis onto `[min, max]` themselves and got no calendar. Building
154
+ it by hand meant a ~260-line control plus its own preset/custom state machine.
155
+
156
+ `LyraDateRangePreset` is deliberately the same `label`/`start`/`end` shape as `TimeRangePreset`, so
157
+ the library has one preset vocabulary rather than two — only the unit differs (ISO `YYYY-MM-DD`
158
+ instead of numbers). Range mode only; unset renders nothing. Applying a preset commits through the
159
+ same path a two-click selection uses, so ISO serialization, `min`/`max` clamping and the
160
+ `input`-then-`change` pair are identical. A reversed preset normalizes, and a malformed one is
161
+ ignored rather than clearing the value, so a bad entry in a config-driven list never reads as "the
162
+ user picked nothing". New `presets` and `preset-button` CSS parts.
163
+ - c915980: Added `--lr-focus-ring`, a composite outline shorthand (`var(--lr-focus-ring-width) solid
164
+ var(--lr-focus-ring-color)`) alongside the three existing parts, which stay exactly as they are.
165
+
166
+ Web Awesome exposes `--wa-focus-ring` as a ready-made outline value, so the common consumer idiom
167
+ is `outline: var(--wa-focus-ring)`. Migrating it meant hand-expanding every site, which is easy to
168
+ get subtly wrong — omitting the `solid` keyword yields an outline that renders in some engines and
169
+ not others — and each hand-expanded copy stops tracking any future change to how the ring is
170
+ composed. `--lr-focus-ring-offset` stays separate because `outline-offset` is its own property, not
171
+ part of the `outline` shorthand.
172
+
173
+ `llms/tokens.md` also now documents why an ancestor `--lr-*` override does not survive a nested
174
+ component boundary: every component re-derives that layer from `--lr-theme-*` on its own `:host`,
175
+ so the override is reset at the first `lr-*` inside another `lr-*`'s shadow root and degrades
176
+ silently. The `--lr-theme-*` input layer is the one that inherits.
177
+ - 3d7a6a5: `<lr-heatmap>` matrix mode gains `colLabelRotation` (`col-label-rotation`) and an `'auto'` value for
178
+ `colLabelHeight` (`col-label-height`), giving column labels the escape hatch the row gutter got in
179
+ 10.0.0.
180
+
181
+ Column labels were horizontal-only in a fixed 20px band, so in a dense matrix — where every column
182
+ is far narrower than a typical label — adjacent labels collided and the axis became unreadable,
183
+ with no rotation or angle property anywhere in the surface. Each label now rotates about an anchor
184
+ at its own column's centre with the label's end at that anchor, so it leans back over the columns
185
+ to its left and the last column's label cannot overflow the canvas. `col-label-height="auto"`
186
+ measures the labels and projects their width through the rotation, so the band sizes itself.
187
+
188
+ Unset, both are inert and painting is unchanged. Values outside `[0, 90]` clamp and non-finite
189
+ values normalize to `0`. Rotation is deliberately not mirrored under `dir="rtl"`, matching the
190
+ documented rule that both grid modes retain physical LTR geometry.
191
+ - 20728fb: `<lr-map>` gains a `'step'` choropleth interpolation and independent fill/stroke colours on
192
+ `dataLayers` — the two declarative gaps that stopped an application migrating off a first-party
193
+ MapLibre wrapper after every other property already matched.
194
+
195
+ **`interpolation: 'step'`** emits maplibre's `['step', …]` instead of `['interpolate', …]`, giving
196
+ discrete bands rather than a continuous ramp. A ramp is wrong whenever the legend advertises a fixed
197
+ set of ranges with one swatch each: it puts colours on the map that appear nowhere in the legend and
198
+ renders two regions in the same advertised band as visibly different colours. `stepBaseColor` sets
199
+ the colour below the first threshold (which `['step', …]` requires) and defaults to the first stop's
200
+ own colour.
201
+
202
+ **`dataLayers[].color` / `.strokeColor`** override `tone` for the fill and for the line/circle
203
+ layers respectively, falling back to `color` and then `tone`. They are separable because a fill and
204
+ its outline want opposite things on a choropleth-plus-overlay map: the fill competes for area and
205
+ must sit quiet, while the 1px outline competes with nothing and is the only thing keeping a no-data
206
+ region's shape readable once the fill is that faint. Deriving one from the other measured 1.41:1
207
+ against a light basemap, under WCAG 1.4.11's 3:1 floor for graphical objects. A `var(--lr-…)`
208
+ reference is resolved against the host first, since MapLibre paints to a WebGL canvas and never sees
209
+ the CSS cascade.
210
+
211
+ Both are additive: an unset `interpolation` still interpolates linearly, and a `tone`-only data
212
+ layer paints exactly as before.
213
+ - 4a701e7: `<lr-popover>` gains a third `popupRole` value, `none`, so the library can express the WAI-ARIA
214
+ disclosure-navigation pattern. Previously `popupRole` was `dialog | menu` only, which left a header
215
+ nav flyout with no correct option: `menu` announces "menu, menu item" and expects `menuitem`
216
+ children, while a navigation flyout is a list of links, and `dialog` implies an interruptive
217
+ surface. Consumers had to abandon the library's overlays and hand-roll a
218
+ `button[aria-expanded][aria-controls]` plus a plain list.
219
+
220
+ Under `popup-role="none"` the popup surface renders no `role` and no generated `aria-label`, and
221
+ the trigger carries no `aria-haspopup`, so the slotted `<nav>` owns the semantics and the
222
+ accessible name. Everything else — `aria-expanded`/`aria-controls`, light dismiss, Escape, focus
223
+ return, positioning — is unchanged. Purely additive: `dialog` remains the default, and
224
+ `lr-dropdown` still pins its own role to `menu`.
225
+
226
+ ### Patch Changes
227
+
228
+ - e6ed0ca: The migration codemod now warns about four classes of `wa-*`/`sl-*` reference it does not rewrite,
229
+ instead of leaving them silent: tag selectors inside a `` css`` `` tagged template, `::slotted()`,
230
+ DOM selector strings reached through `this`/`this.shadowRoot`, and `--wa-*`/`--sl-*` custom
231
+ properties.
232
+
233
+ Each of these fails silently at runtime after a migration — a CSS rule keyed on a tag that no
234
+ longer exists matches nothing, `::slotted()` likewise, `querySelector` returns null, and a `var()`
235
+ naming a removed token falls back to its second argument or to nothing. Nothing throws, nothing
236
+ fails a build, and a typechecker cannot see inside a template literal. Because `--check` is
237
+ documented as a CI gate, the silence meant CI certified a migration that had visibly broken the
238
+ component's styling.
239
+
240
+ Tokens are deliberately reported rather than rewritten: the two spacing scales are offset by one
241
+ step (Web Awesome `m` is 1rem, Lyra `m` is 0.75rem), so renaming by name alone silently tightens
242
+ every gap, while mapping by value has no target for 1.5rem or 2.5rem. Warnings are filtered against
243
+ the rewrites the same pass produced, so a reference the inventory does map is never both rewritten
244
+ and warned about, and a self-declared `--wa-*` property (the consumer's own, merely sharing the
245
+ prefix) is exempt.
246
+
247
+ `<lr-dialog>`'s docs also now warn that `lr-close` is not a dialog-scoped name — nine components
248
+ emit it, several of which are routinely nested inside a dialog, and library events bubble and are
249
+ composed, so a listener bound on the dialog also receives a descendant's close.
250
+ - c5baec5: `<lr-flag>` now warns once in the console when `country`/`language` is set but no flag resolver has
251
+ been registered, naming the offending code and the `flag-peer.js` import that fixes it. Previously
252
+ this failed to the visible `[part="error"]` state in complete silence, which is indistinguishable
253
+ from missing flag data — the resolver is deliberately absent from the core component's module
254
+ graph, so an unimported peer entry is the single likeliest cause and was the hardest to diagnose.
255
+ The warning is emitted once per resolver-registration generation, so a page of many flags does not
256
+ repeat it. An already-resolved `src`, a registered resolver, and a well-formed-but-unmapped code
257
+ (which is data, not a defect) all stay silent.
258
+ - b573859: The `lr-locale-picker` Storybook page now registers the optional flag peer, so its rows render real
259
+ flags instead of silently empty frames. Found by the new `<lr-flag>` missing-resolver warning on its
260
+ first run — `flag.stories.ts` had always imported `flag-peer.js` for exactly this reason, and the
261
+ locale-picker page never did.
262
+ - c915980: The `lyra-ui-migrate` CLI no longer silently does nothing when launched through a package manager's
263
+ bin shim. Its entry guard compared `process.argv[1]` to `import.meta.url` as raw paths; under pnpm
264
+ the package directory is a symlink into the virtual store, so the two never matched and `run()`
265
+ never executed. The process printed nothing — not even `--help` — rewrote nothing, wrote no report,
266
+ and exited 0.
267
+
268
+ The serious half is that `--check` is documented as a CI gate that "exits nonzero while rewrites or
269
+ warnings remain". A silent exit 0 is indistinguishable from success, so on every pnpm project the
270
+ gate passed unconditionally — worse than having no gate, because it is trusted. npm and yarn were
271
+ unaffected, which is why it survived. The guard now compares realpaths, and a regression test
272
+ invokes the CLI through a symlink that mimics the pnpm layout.
273
+
3
274
  ## 10.0.1
4
275
 
5
276
  ### Patch Changes