@feugene/granularity-test-kit
v0.8.12026-08-27
Fixed
gr-check-dist-dev-guardnow recognises the guard in either comparison direction. A minifier is free to normalise!(NODE_ENV !== 'production')intoNODE_ENV === 'production', and the gate — which only knew!==— failed the build of a package whose guard was expanded correctly.
v0.8.02026-08-27
Changed
-
Peer floors on
@feugene/*raised to the current minor. Every peer this package declares on the ecosystem now starts at the version the monorepo actually ships:@feugene/unocss-preset-granular→>=0.13.0 <1.0.0
The floors had drifted far behind — some still admitted releases from a year of development ago — and a range that claims support it was never tested against is worse than a narrow one: the install succeeds and the breakage surfaces later, in the consumer’s app.
This is breaking for anyone below a floor. Installing against an older
@feugene/granularitynow produces a peer conflict instead of silence. The fix is to move the core up; nothing in this package’s own API changed.
v0.7.42026-08-25
Fixed
-
The package tarball now ships
LICENSE. The manifest has always declared"license": "SEE LICENSE IN LICENSE", and the file it points at was not there:npmaddsLICENSEto a tarball on its own, but only when the file exists in the package directory. A consumer’s compliance scanner reads a licence reference that resolves to nothing and flags the dependency as unlicensed — a refusal on formal grounds, before anyone reads the terms.The copy is byte-identical to the one at the repository root and is kept that way by
yarn check:licenses, a gate in CI: eleven copies of a 598-line file drift silently, and they drift exactly when the licence text is being edited.
v0.7.32026-08-23
Fixed
- Two liveness guards no longer fail a package for being young. Both watch the parser, not
the package, and both were tied to the shape of a mature one. The locale gate demanded more than
five keys under a message reading “no key found at all” — a package with one component was red
while its parsing worked perfectly; the threshold is now zero, which is what the message says.
The style gate required
--gr-leading-*specifically, so a package built out of controls — which legitimately uses only--gr-control-leading-*— could never satisfy it, even though the paired check right above it accepts both scales. Both scales now count.
v0.7.22026-08-23
Fixed
- The axe scan now measures the page at rest.
a11yRegressionsread whatever frame the page happened to be on, and a frame in the middle of a transition carries a blended colour: the activeGrSidebaritem halfway throughtransition-colorsis#7d818bon#afabf3— 1.84:1 where the settled state is 8.59:1.color-contrastreported a defect the page does not have, and the failure looked random because it depended on whether the scan landed inside the 150 ms window. The showcase starts that motion by itself: its dev server generates UnoCSS rules on demand, so a class first seen when a demo mounts arrives one frame after the node. Transitions and animations are now frozen for the duration of the scan and released immediately after, since the scan is also called mid-scenario where the next step waits on an animation.
v0.7.12026-08-23
Fixed
-
The preset is loaded lazily, so
optional: trueis no longer a lie.gates/registry.tsimported@feugene/unocss-preset-granular/codegenstatically, which made the preset mandatory for every gate in the kit: importing@feugene/granularity-test-kit/gatesfailed at resolution before the consumer even chose a factory — whilepeerDependenciesMetapromised the opposite and the other eight factories need nothing from it. The import now happens insidebeforeAll, with a message naming the package and the version instead of a bare module-not-found. -
The registry gate narrows the subcomponent scan by the component list. Without
componentsthe map picked up.vuefiles from directories that are not components at all.
v0.7.02026-08-23
Added
-
prefixon five gates.componentDirsfilteredGras a literal, sodefineComponentDefaultsGate,defineComponentTokensGate,defineEmitNamingGate,defineComponentDocsGateanddefineRegistryGatefound zero components in a companion package with its own prefix — and four of them went green on that, because there was nothing left to check. The kit is meant for exactly those packages, and/codegenof the preset had taken the prefix as an option long ago.Default stays
'Gr', so nothing changes for the core. Reported by a consumer of@efureev/ft-extra-granularity, who had to rewrite five ready-made factories by hand.
Changed
componentDirswalks grouped layouts and returns paths relative to the components directory (transaction-details/FtExpenseModal), one level deep — the same rule the preset’s registry generator follows. Without it the gates would call «extra» exactly the components the generator had just written.
v0.6.02026-08-22
Added
-
defineStyleTokensGate— the tone is not a foreground colour. The rule («a saturated tone must not paint text — that is what-textis for») lived in a comment inside one component, so nothing reported a breach: a consumer counted fifteen of them in their own package, against three correct ones.text-[var(--gr-<tone>)]is now an error naming the paired role;bg-,border-,fill-andstroke-are untouched — that is what a tone is for.A tone mixed into a text colour (
color-mixinsidetext-*) only warns: there the ratio decides, and statics cannot weigh it. Icons are caught alongside text on purpose — next to a label an icon owes the same legibility.toneRolesoverrides the list,toneAsTextExceptionsallows a file explicitly — as a list, so the exception is visible in review rather than inferred. -
forbidImportantUtilities— an opt-in check against!-important utilities (!text-…,!bg-…). Almost always it means the built-in knob — a token or a prop — was not found, and the override then depends on the order of generated rules, so it drops silently.
Earlier versions
The bodies of these releases are not shown: the full feed weighs more than a page is allowed to. The file in the repository is always complete.
v0.5.02026-08-22v0.4.02026-08-20v0.3.02026-08-19v0.2.02026-08-19v0.1.02026-08-15