@motion-proto/live-tokens 0.78.0 → 0.79.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 (166) hide show
  1. package/.claude/skills/live-tokens-check-compliance/SKILL.md +60 -31
  2. package/.claude/skills/live-tokens-create-component/SKILL.md +23 -28
  3. package/.claude/skills/live-tokens-create-component/references/contract-tests.md +61 -0
  4. package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +2 -2
  5. package/.claude/skills/live-tokens-create-component/references/token-naming.md +6 -15
  6. package/.claude/skills/live-tokens-create-page/SKILL.md +6 -4
  7. package/.claude/skills/live-tokens-create-theme/references/design-directions.md +1 -1
  8. package/.claude/skills/live-tokens-pick-component/SKILL.md +3 -3
  9. package/.claude/skills/live-tokens-set-colors/references/color-anchors.md +1 -1
  10. package/.claude/skills/live-tokens-set-geometry/SKILL.md +1 -1
  11. package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +1 -1
  12. package/CHANGELOG.md +231 -0
  13. package/README.md +9 -15
  14. package/bin/check-component.mjs +152 -551
  15. package/bin/check-page.mjs +55 -541
  16. package/bin/cli.mjs +59 -13
  17. package/bin/contractRunner.mjs +37 -91
  18. package/bin/lib/catalogue.mjs +161 -34
  19. package/bin/lib/componentSource.mjs +152 -0
  20. package/bin/lib/cssValues.mjs +9 -0
  21. package/bin/lib/dataDir.mjs +126 -0
  22. package/bin/lib/findings.mjs +103 -12
  23. package/bin/lib/fixers.mjs +64 -0
  24. package/bin/lib/geometry.mjs +92 -0
  25. package/bin/lib/pageSource.mjs +230 -0
  26. package/bin/lib/report.mjs +57 -59
  27. package/bin/lib/tokenVocabulary.mjs +104 -34
  28. package/bin/rules/componentStructure.mjs +344 -0
  29. package/bin/rules/componentUse.mjs +313 -0
  30. package/bin/rules/importsAndRoutes.mjs +136 -0
  31. package/bin/rules/testRuns.mjs +122 -0
  32. package/bin/rules/tokens.mjs +363 -0
  33. package/bin/setup-claude.mjs +1 -2
  34. package/dist-plugin/{chunk-PDNL4NC5.js → chunk-D4WRIKEZ.js} +7 -2
  35. package/dist-plugin/{chunk-SWXRVZKT.js → chunk-REBHE3ZM.js} +414 -1
  36. package/dist-plugin/index.cjs +432 -15
  37. package/dist-plugin/index.js +8 -9
  38. package/dist-plugin/migrateData/index.cjs +422 -4
  39. package/dist-plugin/migrateData/index.js +2 -2
  40. package/dist-plugin/setColors/index.cjs +414 -1
  41. package/dist-plugin/setColors/index.d.cts +1 -1
  42. package/dist-plugin/setColors/index.d.ts +1 -1
  43. package/dist-plugin/setColors/index.js +1 -1
  44. package/dist-plugin/setGeometry/index.cjs +423 -13
  45. package/dist-plugin/setGeometry/index.d.cts +3 -3
  46. package/dist-plugin/setGeometry/index.d.ts +3 -3
  47. package/dist-plugin/setGeometry/index.js +10 -13
  48. package/dist-plugin/setType/index.d.cts +1 -1
  49. package/dist-plugin/setType/index.d.ts +1 -1
  50. package/dist-plugin/{themeTypes-BxRtuN5V.d.cts → themeTypes-B8_Idrp4.d.cts} +2 -2
  51. package/dist-plugin/{themeTypes-BxRtuN5V.d.ts → themeTypes-B8_Idrp4.d.ts} +2 -2
  52. package/package.json +2 -2
  53. package/src/editor/component-editor/CalloutEditor.svelte +2 -2
  54. package/src/editor/component-editor/CollapsibleSectionEditor.svelte +14 -15
  55. package/src/editor/component-editor/CornerBadgeEditor.svelte +14 -14
  56. package/src/editor/component-editor/DialogEditor.svelte +5 -5
  57. package/src/editor/component-editor/InlineEditActionsEditor.svelte +2 -2
  58. package/src/editor/component-editor/RadioButtonEditor.svelte +21 -21
  59. package/src/editor/component-editor/SectionDividerEditor.svelte +7 -7
  60. package/src/editor/component-editor/SegmentedControlEditor.svelte +5 -5
  61. package/src/editor/component-editor/SideNavigationEditor.svelte +25 -25
  62. package/src/editor/component-editor/TabBarEditor.svelte +6 -6
  63. package/src/editor/component-editor/TableEditor.svelte +6 -6
  64. package/src/editor/component-editor/ToggleEditor.svelte +2 -2
  65. package/src/editor/component-editor/index.ts +3 -0
  66. package/src/editor/component-editor/registry.ts +57 -1
  67. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +14 -14
  68. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +3 -0
  69. package/src/editor/component-editor/scaffolding/types.ts +15 -0
  70. package/src/editor/core/components/adjustAliases.ts +4 -4
  71. package/src/editor/core/components/aliasKinds.ts +20 -19
  72. package/src/editor/core/sketch/sketchLayer.ts +3 -3
  73. package/src/editor/core/themes/migrateComponentConfig.ts +14 -6
  74. package/src/editor/core/themes/migrations/2026-09-13-badge-brand.ts +42 -0
  75. package/src/editor/core/themes/migrations/2026-09-13-collapsiblesection-open.ts +33 -0
  76. package/src/editor/core/themes/migrations/2026-09-13-cornerbadge-prefix.ts +70 -0
  77. package/src/editor/core/themes/migrations/2026-09-13-hairline.ts +92 -0
  78. package/src/editor/core/themes/migrations/2026-09-13-indicator.ts +54 -0
  79. package/src/editor/core/themes/migrations/2026-09-13-sectiondivider-surface.ts +36 -0
  80. package/src/editor/core/themes/migrations/2026-09-13-selected-state.ts +124 -0
  81. package/src/editor/core/themes/migrations/2026-09-13-toggle-label.ts +31 -0
  82. package/src/editor/core/themes/migrations/index.ts +16 -0
  83. package/src/editor/core/themes/themeService.ts +3 -3
  84. package/src/editor/core/themes/themeTypes.ts +13 -15
  85. package/src/editor/docs/Docs.svelte +1 -1
  86. package/src/editor/docs/content/light-and-dark.md +3 -3
  87. package/src/editor/docs/content.generated.ts +1 -1
  88. package/src/editor/index.ts +1 -0
  89. package/src/editor/overlay/LiveEditorOverlay.svelte +15 -0
  90. package/src/editor/skill-atlas/SkillAtlas.svelte +4 -4
  91. package/src/editor/skill-atlas/TreeNodeCard.svelte +4 -4
  92. package/src/editor/skill-atlas/skillSources.generated.ts +11 -14
  93. package/src/editor/skill-atlas/skillTrees.ts +1 -3
  94. package/src/editor/skill-atlas/trees/check-compliance.ts +258 -93
  95. package/src/editor/skill-atlas/trees/create-component.ts +73 -62
  96. package/src/editor/skill-atlas/trees/create-page.ts +38 -17
  97. package/src/editor/skill-atlas/trees/pick-component.ts +3 -3
  98. package/src/editor/skill-atlas/trees/set-geometry.ts +1 -1
  99. package/src/editor/ui/UIPaletteSelector.svelte +11 -15
  100. package/src/editor/ui/variantScales.ts +8 -8
  101. package/src/live-tokens/data/themes/autumn.json +188 -188
  102. package/src/live-tokens/data/themes/halloween.json +188 -188
  103. package/src/live-tokens/data/themes/midnight-study.json +245 -245
  104. package/src/live-tokens/data/themes/ocean.json +188 -188
  105. package/src/live-tokens/data/themes/royal-velvet.json +188 -188
  106. package/src/live-tokens/data/themes/sketchy.json +188 -188
  107. package/src/live-tokens/data/themes/spring-meadow.json +188 -188
  108. package/src/live-tokens/data/themes/sunset.json +188 -188
  109. package/src/system/components/Badge.svelte +27 -23
  110. package/src/system/components/Button.svelte +13 -7
  111. package/src/system/components/Callout.svelte +16 -11
  112. package/src/system/components/Card.svelte +22 -15
  113. package/src/system/components/CodeSnippet.svelte +10 -6
  114. package/src/system/components/CollapsibleSection.svelte +68 -63
  115. package/src/system/components/CornerBadge.svelte +78 -72
  116. package/src/system/components/Dialog.svelte +21 -18
  117. package/src/system/components/IconButton.svelte +13 -9
  118. package/src/system/components/Image.svelte +14 -8
  119. package/src/system/components/ImageLightbox.svelte +10 -6
  120. package/src/system/components/InlineEditActions.svelte +17 -14
  121. package/src/system/components/Input.svelte +13 -7
  122. package/src/system/components/MenuSelect.svelte +13 -7
  123. package/src/system/components/Notification.svelte +17 -11
  124. package/src/system/components/Panel.svelte +13 -6
  125. package/src/system/components/ProgressBar.svelte +10 -5
  126. package/src/system/components/RadioButton.svelte +33 -30
  127. package/src/system/components/SectionDivider.svelte +28 -21
  128. package/src/system/components/SegmentedControl.svelte +27 -23
  129. package/src/system/components/SideNavigation.svelte +175 -171
  130. package/src/system/components/Slider.svelte +11 -7
  131. package/src/system/components/TabBar.svelte +53 -49
  132. package/src/system/components/Table.svelte +20 -15
  133. package/src/system/components/Toggle.svelte +14 -10
  134. package/src/system/components/Tooltip.svelte +10 -6
  135. package/src/system/styles/CONVENTIONS.md +3 -4
  136. package/src/testing-js/chunk-3UKGXCDL.js +48 -0
  137. package/src/testing-js/chunk-3UKGXCDL.js.map +1 -0
  138. package/src/testing-js/{chunk-FAFOAWYL.js → chunk-Q3YIAAG3.js} +17 -3
  139. package/src/testing-js/chunk-Q3YIAAG3.js.map +1 -0
  140. package/src/testing-js/{chunk-GNIUPIU2.js → chunk-U7OJE5DU.js} +18 -18
  141. package/src/testing-js/chunk-U7OJE5DU.js.map +1 -0
  142. package/src/testing-js/{chunk-4JQX6WWL.js → chunk-ZMZQZ33J.js} +474 -166
  143. package/src/testing-js/chunk-ZMZQZ33J.js.map +1 -0
  144. package/src/testing-js/component-behavior.contract.js +155 -0
  145. package/src/testing-js/component-behavior.contract.js.map +1 -0
  146. package/src/testing-js/component-editor.contract.js +6 -4
  147. package/src/testing-js/component-editor.contract.js.map +1 -1
  148. package/src/testing-js/component-render.contract.js +14 -10
  149. package/src/testing-js/component-render.contract.js.map +1 -1
  150. package/src/testing-js/index.d.ts +44 -4
  151. package/src/testing-js/index.js +13 -7
  152. package/src/testing-js/index.js.map +1 -1
  153. package/src/testing-js/page-compliance.contract.js +48 -10
  154. package/src/testing-js/page-compliance.contract.js.map +1 -1
  155. package/src/testing-js/registry.contract.js +5 -3
  156. package/src/testing-js/registry.contract.js.map +1 -1
  157. package/src/testing-js/{vitest-C-wNWcoA.d.ts → vitest-BMLIbDs2.d.ts} +8 -2
  158. package/src/testing-js/vitest.d.ts +1 -1
  159. package/src/testing-js/vitest.js +2 -1
  160. package/template/package.json +1 -1
  161. package/.claude/skills/live-tokens-create-component/SKILL copy.md +0 -196
  162. package/.claude/skills/live-tokens-fix-findings/SKILL.md +0 -105
  163. package/src/editor/skill-atlas/trees/fix-findings.ts +0 -504
  164. package/src/testing-js/chunk-4JQX6WWL.js.map +0 -1
  165. package/src/testing-js/chunk-FAFOAWYL.js.map +0 -1
  166. package/src/testing-js/chunk-GNIUPIU2.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,236 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.79.0 — Checks fix what they find
4
+
5
+ ### Added
6
+
7
+ - **Every finding carries its own repair.** `report --json` and both
8
+ checkers' `--json` now put `guidance`, `repair`, and `exception` on every
9
+ finding, alongside `rule`, `severity`, `file`, `line`, and `message`.
10
+ `guidance` is the rule's repair instruction in plain sentences, such as the
11
+ design token each color role takes for a `color-literal`.
12
+ `repair` is `auto` (code can apply the patch), `choice` (a role or a tie
13
+ needs the user, and `details` lists the candidates), or `authored` (the
14
+ user's own words are the fix). `exception` is the narrower
15
+ `live-tokens.config.json` entry that steps the rule down one level to
16
+ record a deliberate decision to leave the finding as it is.
17
+ - **`check-page` and `check-component` fix what they can.** Both apply every
18
+ `auto` finding's patch before they report: a deep import rewritten to its
19
+ public path, a spacing, radius, or stroke-width literal replaced by its one
20
+ nearest design token, a page's `size` prop deleted, a semantic property
21
+ override deleted. They then recheck and list each fix beside the findings
22
+ that remain, in `--json` as `fix.applied`. With `--tests`, the fixes land
23
+ before the tests run. A second run applies nothing. `--no-fix` reports
24
+ without editing, for a build or CI; the template's `check:design` passes it.
25
+ - **Three findings that used to be report-only facts.** `unread-token`
26
+ (warn): a runtime declares a property in `:global(:root)` and reads it
27
+ nowhere in its own CSS. `missing-description` (warn): a runtime file has no
28
+ `catalogue` export, or a required field in it is not a string literal. `config-token`: an alias in
29
+ `component-configs/<id>/default.json` names something the vocabulary
30
+ lacks, or a bare literal stands on a property the editor declares no
31
+ intrinsic for.
32
+ - **`ComponentContract` gains `behavior`.** A Vitest suite mounts the
33
+ runtime under happy-dom by its registration and drives each declared case
34
+ with a real DOM event: a callback fires with its documented argument,
35
+ stays silent under `disabled`, or a controlled prop drives its attribute
36
+ while an action leaves it alone. A failure reports `contract-behavior`,
37
+ naming the case. `behavior` is a required field; a component with no
38
+ callback prop declares it `{ applicable: false, reason: '...' }`.
39
+ - **A stroke's width has its own token scale**, `border-width`, so a
40
+ `dimension-literal` on a border, divider, or accent resolves to a stroke
41
+ step instead of a colour scale with nothing to offer it. 26 scales in
42
+ total; `tokens --scale border-width` resolves the name.
43
+ - **One component inventory.** `componentDirs` in `live-tokens.config.json`
44
+ is honoured everywhere a component is discovered, checked, or run under
45
+ `--tests`, not only by `report`. A registered id with no runtime, or a
46
+ runtime with no editor, now surfaces as a `missing-file` finding rather
47
+ than silently dropping out of the batch.
48
+ - **`CatalogueEntry` and the `catalogue` export.** A runtime file's
49
+ `<script module>` block exports `catalogue`, typed `CatalogueEntry`, with
50
+ `description`, `useFor`, `notFor`, and an optional `props` map keyed by
51
+ prop name. `CatalogueEntry` is exported from `@motion-proto/live-tokens`
52
+ and from `@motion-proto/live-tokens/component-editor`. `catalogueOf` reads
53
+ the export statically, the way the CLI already reads `component` and
54
+ `allTokens` from editor files, and `components <id>` prints its fields.
55
+
56
+ ### Changed (breaking)
57
+
58
+ - **`check-page` and `check-component` edit files by default.** `--fix` is
59
+ gone; every run applies the `auto` patches. A build or CI script that runs
60
+ either checker must pass `--no-fix` to stay report-only, as the template's
61
+ `check:design` does.
62
+ - **`behavior` is a required `ComponentContract` field.** A consumer's
63
+ `tests/contracts.ts` stops compiling until each contract declares a
64
+ behavior or marks it inapplicable with a reason. `references/contract-tests.md`
65
+ in the create-component skill carries the Toggle-shaped example and the
66
+ one-line inapplicable form.
67
+ - **`RegistryEntry.catalogue` is required, with no default.** A
68
+ `registerComponent` call now passes `catalogue`, imported from the
69
+ runtime file beside its editor import. The runtime file's leading comment
70
+ is deleted; the CLI never falls back to it. A consumer's registration
71
+ stops compiling until it imports and passes `catalogue`.
72
+ - **Selection says `selected`.** RadioButton's `active` prop is `selected`
73
+ and SideNavigation's `forceActivePart` is `forceSelectedPart`. The
74
+ `-active-` segment reads `-selected-` across RadioButton's nine, TabBar's
75
+ fourteen, and SideNavigation's forty semantic properties, and the `.active`
76
+ class on a radio row, a tab, and a rail part is `.selected`. A saved theme
77
+ or component config is renamed on load. `active` stays the pressed state,
78
+ so Button's and IconButton's `--*-outline-active-*` are untouched.
79
+ - **One hairline.** The line a component draws between its parts is
80
+ `-hairline-color` and its width is `-hairline-width` everywhere. Dialog's,
81
+ Table's, and TabBar's `-divider` and `-divider-width`, SegmentedControl's
82
+ `-divider-color`, `-divider-thickness`, and `-divider-inset`,
83
+ CollapsibleSection's twenty-three `--collapsiblesection-divider-*`, and
84
+ SectionDivider's three `-hairline-thickness` are renamed on load.
85
+ CollapsibleSection's `variant="divider"` is `variant="hairline"`, and its
86
+ class is `.variant-hairline`. `check-component` no longer accepts the
87
+ suffixes `-thickness`, `-divider`, `-divider-width`, `-divider-thickness`,
88
+ `-hairline-thickness`, `-divider-height`, `-divider-inset`, or `-inset`; a
89
+ property carrying one is a naming finding. The `set-geometry` op kind
90
+ `divider-width` is `hairline-width`, and an ops file naming the old kind is
91
+ rejected.
92
+ - **One indicator.** The bar beside SideNavigation's current item and the
93
+ stripe on Callout's leading edge are indicators, the word MenuSelect and
94
+ TabBar already use. SideNavigation's twelve `-accent` and twelve
95
+ `-accent-width` properties and Callout's four `-accent-width` are
96
+ `-indicator` and `-indicator-width`, renamed on load. `check-component` no
97
+ longer accepts the suffixes `-accent` or `-accent-width`; a property
98
+ carrying one is a naming finding. The `set-geometry` op kind `accent-width`
99
+ is `indicator-width`, and an ops file naming the old kind is rejected.
100
+ `accent` now names the color family only, so Badge's and CornerBadge's
101
+ `--*-accent-*` are untouched.
102
+ - **SectionDivider's fill reads `-surface`.** Its three `-background`
103
+ properties are `-surface`, matching every other component's fill name,
104
+ renamed on load. `check-component` no longer accepts the suffix
105
+ `-background`; a property carrying one is a naming finding.
106
+ - **A property's prefix is the component's id, with no exception.**
107
+ CornerBadge's forty `--corner-badge-*` properties are `--cornerbadge-*`,
108
+ renamed on load. `check-component` no longer accepts a hyphenated prefix
109
+ for any component; a property that carries one is a naming finding.
110
+ - **A text part's color is its bare name.** Toggle's `--toggle-label-text`
111
+ and `--toggle-disabled-label-text` are `--toggle-label` and
112
+ `--toggle-disabled-label`, renamed on load, matching every other
113
+ component's bare-part color.
114
+ - **A callback prop is `on` followed by the event name, all lowercase.**
115
+ TabBar's `ontabChange` is `onchange`. InlineEditActions' `onSave` and
116
+ `onCancel` are `onsave` and `oncancel`. A consumer passing the old prop
117
+ name stops compiling; there is no runtime migration for a prop.
118
+ - **`open` everywhere.** Dialog's `show` prop is `open`, still `$bindable`.
119
+ CollapsibleSection's `expanded` prop is `open`, and its four
120
+ `-expanded-` properties are `-open-`, renamed on load. A consumer passing
121
+ the old prop name stops compiling; there is no runtime migration for a
122
+ prop.
123
+ - **Size values are `default` and `small`.** Card's `size="compact"` is
124
+ `size="small"`. Notification's `size="normal"` is `size="default"` and
125
+ `size="compact"` is `size="small"`. A consumer passing the old value
126
+ stops compiling; there is no runtime migration for a prop.
127
+ - **TabBar's `selectedTab` is `value`; SideNavigation's `titleLabel` is
128
+ `title`.** Both now hold the same kind of value SegmentedControl's and
129
+ MenuSelect's `value` props do. `titleHref` is unchanged. A consumer
130
+ passing the old prop name stops compiling; there is no runtime migration
131
+ for a prop.
132
+ - **Badge's and CornerBadge's `primary` variant is `brand`.** The variant
133
+ paints the brand color family, which its tokens already name
134
+ (`--surface-brand`), so `variant="primary"` on either component is
135
+ `variant="brand"` and the rendered class is `badge-brand`. Badge's
136
+ thirteen `--badge-primary-*` and CornerBadge's three
137
+ `--cornerbadge-primary-*` properties are `--badge-brand-*` and
138
+ `--cornerbadge-brand-*`, renamed on load. Button's and IconButton's
139
+ `primary`, the one primary action a page carries, is unchanged. A consumer
140
+ passing the old value stops compiling; there is no runtime migration for a
141
+ prop.
142
+
143
+ ### Changed
144
+
145
+ - **Every shipped catalogue entry explains the props that carry a choice.**
146
+ `props.variant` on Badge, CornerBadge, Callout, Notification, Card, and
147
+ Slider, `props.anchor` on CornerBadge, `props.type` on Input,
148
+ `props.role` on MenuSelect, and `props.minHeight` on Panel, which used to
149
+ sit inside `useFor`. SectionDivider's entry keys its size guidance under
150
+ `variant`, the prop's real name, instead of `level`, and adds `eyebrow`
151
+ and `description`. The registry contract test now fails on a `props` key
152
+ that names no declared prop.
153
+ - **`components` prints only the catalogue fields a file has.** A file whose
154
+ export lacks a field no longer prints `Use for: undefined`; the
155
+ `missing-description` finding already names the field.
156
+ - **"section" replaces "band" and "range" replaces "band"** in the catalogue,
157
+ the skills, the docs, and the README, following the design vocabulary in
158
+ `docs/terminology.md`.
159
+ - **`contract-preview` is retired.** The harness throws `contract-states`
160
+ from its state assertions and `contract-interaction` from its interaction
161
+ assertions directly, so a failure the CLI used to report under
162
+ `contract-preview` now reports under the rule that actually failed.
163
+ - **`report --json`'s `components[]` facts are narrower.** No `name`,
164
+ `unread`, or `described`; a component's unread tokens and missing
165
+ description are now the `unread-token` and `missing-description` findings
166
+ under `findings.components`. `usage` drops `customUnregistered`; an
167
+ unregistered project component is now `missing-registration`.
168
+ - **The catalogue reads "views" for what TabBar switches, "a note" for
169
+ Tooltip, "section" for what Panel frames, and "a modal window" for
170
+ Dialog.**
171
+ - **`docs/terminology.md` and the create-component skill record the
172
+ component naming rules**: which word names a prop or a semantic property,
173
+ and the retired spellings each replaces.
174
+
175
+ ### Removed
176
+
177
+ - **`live-tokens-fix-findings` is gone.** `live-tokens-check-compliance`
178
+ now checks and fixes the whole project: it reads the report, runs the
179
+ token migrations, runs both checkers, repairs each remaining finding from
180
+ its `guidance`, and adds `check:design` to the build. "Make check:design
181
+ pass" and "fix the project" now reach it. `npx live-tokens setup-claude
182
+ --force` deletes a project's old copy, because it prunes every
183
+ `live-tokens-` skill a release no longer ships.
184
+
185
+ ### Fixed
186
+
187
+ - **The overlay's collapsed pill no longer covers the pinned variant strip on
188
+ the components page.** While the pill rests in the top band the overlay
189
+ publishes its right inset as `--lt-pill-inset`, and the pinned preview header
190
+ wraps its tabs clear of it. The contract harness's tab clicks are forced
191
+ clicks again, so chrome over a tab fails the run.
192
+ - **The component inventory discovers a runtime nested below a
193
+ `componentDirs` entry**, not only one directly inside it. `componentInventory`
194
+ now walks each directory recursively, the way the discovery it replaced did.
195
+ - **`config-token` reads `component-configs/<id>/default.json` from the
196
+ project's actual data directory** — `dataDir` in `live-tokens.testing.ts` or
197
+ `live-tokens.config.json`, same resolution `check-component --tests`
198
+ already isolates — instead of the literal `src/live-tokens/data`.
199
+ - **`config-token` checks an alias against its own component's properties**,
200
+ not the union across every component's. An alias that names a sibling
201
+ component's property now fires, where it used to pass silently.
202
+ - **A component with neither a runtime nor an editor reports both
203
+ `missing-file` findings**, not only the runtime's. The editor check runs
204
+ before the runtime check returns.
205
+ - **`check-page`'s attribute parser reads an attribute a newline separates
206
+ from the tag name**, and reads `size = "small"` — spaces around `=` — as
207
+ Svelte does, as one attribute rather than a stray `=` that stopped the scan.
208
+ - **One broken alias is one finding.** `check-component <id> --tests` used to
209
+ report a `default.json` alias naming an unknown token twice: once as
210
+ `config-token` from the static read, once as `contract-alias` from the
211
+ browser watching the same property resolve to nothing. The merge now drops
212
+ the browser's copy when every property it names already carries a
213
+ `config-token` finding for that component. A `contract-alias` naming a token
214
+ the vocabulary knows, declared and still unresolved, is a different defect
215
+ and stays.
216
+ - **A missing runtime is the registry rule's finding.** The behavior suite
217
+ skips a component's cases, with the reason, when the file its registration
218
+ names does not exist, instead of failing every declared case on the same
219
+ unresolved import. `contract-behavior` then reads `incomplete` in coverage,
220
+ explained by the `contract-registry` failure beside it.
221
+ - **Every registry assertion names its component.** "Every authored component
222
+ is registered" is now one assertion per authored id, so an unregistered
223
+ component reports `contract-registry` naming itself. It used to reach the
224
+ CLI as `tests-setup`, which means the tooling never ran.
225
+ - **A page obligation measures a page that has stopped moving.** `PageHarness`
226
+ waited on `--body-md-font-size`, which `tokens.css` sets on its own, then on
227
+ two animation frames. A page whose theme values, route stylesheet, or fonts
228
+ were still arriving could be measured mid-flight, and a rule reading its
229
+ geometry would report a finding on one run and none on the next. The harness
230
+ now waits for a quiet window over the page's geometry, its projected root
231
+ style, and its font set, bounded so a page that never settles is still
232
+ measured.
233
+
3
234
  ## 0.78.0 — A page proves compliance as rendered
4
235
 
5
236
  ### Added
package/README.md CHANGED
@@ -338,7 +338,7 @@ Once installed in a project, the same commands are available as `npx live-tokens
338
338
 
339
339
  ## Claude Code skills
340
340
 
341
- The package bundles nine Claude Code skills. They encode the conventions this README cannot carry in full: which component fits a need, how a page is wired, how one request becomes a whole look, what a valid theme looks like in OKLCH, how two typefaces sit together, how geometry moves along the token scales, how a project is checked against all of that, and how an existing page or component is brought back into line. Each triggers from an ordinary request, so there are no slash commands to learn.
341
+ The package bundles eight Claude Code skills. They encode the conventions this README cannot carry in full: which component fits a need, how a page is wired, how one request becomes a whole look, what a valid theme looks like in OKLCH, how two typefaces sit together, how geometry moves along the token scales, how a project is checked against all of that, and how an existing page or component is brought back into line. Each triggers from an ordinary request, so there are no slash commands to learn.
342
342
 
343
343
  ### Install
344
344
 
@@ -390,7 +390,7 @@ Ask for color: "a cooler palette", "warmer", "more contrast", "calmer", "make th
390
390
 
391
391
  The skill translates the color intent into ten OKLCH base colors (Brand, Accent, Special, Canvas, Neutral, Alternate, Info, Success, Warning, Danger) plus a light or dark scheme, then runs `npx live-tokens set-colors <base-colors.json>`. The CLI assembles the curves, enforces AA contrast on derived text tokens and auto-corrects where it can, writes the result to the unsaved colors-and-type buffer, and prints a contrast report. Exit 1 means the base colors themselves are unworkable, and each failure line names the base color to change.
392
392
 
393
- Most of the skill is the judgment the generator cannot supply: a chroma budget scaled to how much screen area each palette covers, per-role lightness and hue bands for each scheme, three levels of canvas commitment, gamut guardrails against impossible base colors, harmony modes, and the optional canvas gradient. OKLCH anchors for every named feeling, idiom, and occasion live in a reference file the skill reads on demand.
393
+ Most of the skill is the judgment the generator cannot supply: a chroma budget scaled to how much screen area each palette covers, per-role lightness and hue ranges for each scheme, three levels of canvas commitment, gamut guardrails against impossible base colors, harmony modes, and the optional canvas gradient. OKLCH anchors for every named feeling, idiom, and occasion live in a reference file the skill reads on demand.
394
394
 
395
395
  Color is the one dimension every look fixes, so it runs first and never skips. `--dry-run` prints the report without writing. Saving the open theme in the editor, or running `save-theme`, keeps the result; Adopt ships it. A re-run replaces the buffer's whole color state, including palette edits made in the editor since the last run, and carries the type and geometry buffers forward.
396
396
 
@@ -420,25 +420,19 @@ Ask for something the catalogue lacks: "author a Rating component", "make my Chi
420
420
 
421
421
  The skill covers the recipe: the runtime `.svelte` file with its `:global(:root)` token block, the editor `.svelte` file exporting `allTokens` and its variant groups, the `registerComponent()` call, and the catalogue entry that keeps `live-tokens-pick-component` current. It carries the naming scheme, the token suffix vocabulary, the state model (component states such as selected and disabled are separate from interaction states such as hover), and the public-imports rule, and points at the shipped `Toggle` in `node_modules` as the worked example. Linked siblings, intrinsics, and the fixed-overlay portal rule sit in reference files the skill reads only when a component needs them.
422
422
 
423
- ### `live-tokens-check-compliance`
424
-
425
- Ask how things stand: "check this project against the design system", "audit the pricing page", "what would it take to make the build pass?", "review this before I upgrade".
426
-
427
- The skill runs `npx live-tokens report --json`, which is the project as facts: pending `tokens.css` migrations, the tokens each component declares and reads, which page renders which component, and both checkers' findings by rule under the project's severities and under `--strict`. It presents the report, says what each rule holds, marks each recommended fix as mechanical or a judgement call, names any visible shift, and flags a finding that looks deliberate together with the config entry that would record the decision. It edits nothing and ends by handing the list to `live-tokens-fix-findings`.
428
-
429
- ### `live-tokens-fix-findings`
430
-
431
- Ask for the existing code to catch up: "make check:design pass", "fix the design-system warnings", "replace the hex and pixel values with tokens", "why is check-page failing on the pricing page?".
432
-
433
- The two checkers report a stable rule id per finding. The skill runs them with `--json`, groups the findings by rule, and carries one fix recipe per rule: a colour literal becomes the token for its role rather than the nearest hue, a spacing literal moves to the nearest `--space-*` step with the shift named, a raw `font-size` becomes a whole text style, a prop the component does not declare is mapped or dropped, and `site.css` moves out of `main.ts` into each page. It re-runs after every rule and stops at exit 0, then reports what changed, what it left and why, and what `--strict` would add. It never silences a rule to pass and never adds a token to `tokens.css` to match a value a page happened to use.
434
-
435
423
  Verify the result:
436
424
 
437
425
  ```bash
438
426
  npx @motion-proto/live-tokens check-component <id>
439
427
  ```
440
428
 
441
- The validator checks the file layout, the `:global(:root)` block, the token-suffix vocabulary, the state-before-property rule, the public-imports rule, the `registerComponent({ id })` call, and that every default resolves to a theme token rather than a literal. Exit code 0 means the static contract is met. A project scaffolded by `create` runs it, with `check-page`, as `npm run check:design` before every `vite build`, so a component or page that opts out of the theme cannot ship by accident.
429
+ The validator checks the file layout, the `:global(:root)` block, the token-suffix vocabulary, the state-before-property rule, the public-imports rule, the `registerComponent({ id })` call, and that every default resolves to a design token rather than a literal. Exit code 0 means the static contract is met. A project scaffolded by `create` runs it, with `check-page`, as `npm run check:design` before every `vite build`, so a component or page that opts out of the theme cannot ship by accident.
430
+
431
+ ### `live-tokens-check-compliance`
432
+
433
+ Ask how things stand, or ask for the code to catch up: "check this project against the design system and fix it", "audit the pricing page", "make check:design pass", "fix the design-system warnings", "replace the hex and pixel values with tokens", "review this before I upgrade".
434
+
435
+ The skill runs `npx live-tokens report --json`, which is the project as facts: pending `tokens.css` migrations, the tokens each component declares and reads, which page renders which component, and both checkers' findings by rule under the project's severities and under `--strict`. It then runs `npx live-tokens migrate` and both checkers, which apply every `auto` repair themselves and return each remaining finding with its own `guidance`. The skill groups what remains by rule, largest error group first, makes each repair from its guidance, and re-runs until both checkers exit 0. It reports what `--strict` adds, clears the warnings when the request covers them, and adds `check:design` to the build with `--no-fix`. The reply names the fixes the checkers applied, the changes by rule with any visible shift, and each finding left with its reason. It never silences a rule to pass and never adds a token to `tokens.css` to match a value a page happened to use. A finding the user chooses to keep goes into the config entry its `exception` field names.
442
436
 
443
437
  ## From edit to production
444
438