design-constraint-validator 1.0.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 (195) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +659 -0
  3. package/adapters/README.md +46 -0
  4. package/adapters/css.d.ts +44 -0
  5. package/adapters/css.d.ts.map +1 -0
  6. package/adapters/css.js +97 -0
  7. package/adapters/css.ts +116 -0
  8. package/adapters/js.d.ts +3 -0
  9. package/adapters/js.d.ts.map +1 -0
  10. package/adapters/js.js +15 -0
  11. package/adapters/js.ts +14 -0
  12. package/adapters/json.d.ts +18 -0
  13. package/adapters/json.d.ts.map +1 -0
  14. package/adapters/json.js +35 -0
  15. package/adapters/json.ts +45 -0
  16. package/cli/build-css.d.ts +2 -0
  17. package/cli/build-css.d.ts.map +1 -0
  18. package/cli/build-css.js +23 -0
  19. package/cli/build-css.ts +32 -0
  20. package/cli/commands/build.d.ts +5 -0
  21. package/cli/commands/build.d.ts.map +1 -0
  22. package/cli/commands/build.js +89 -0
  23. package/cli/commands/build.ts +65 -0
  24. package/cli/commands/graph.d.ts +3 -0
  25. package/cli/commands/graph.d.ts.map +1 -0
  26. package/cli/commands/graph.js +219 -0
  27. package/cli/commands/graph.ts +137 -0
  28. package/cli/commands/index.d.ts +8 -0
  29. package/cli/commands/index.d.ts.map +1 -0
  30. package/cli/commands/index.js +7 -0
  31. package/cli/commands/index.ts +7 -0
  32. package/cli/commands/patch-apply.d.ts +3 -0
  33. package/cli/commands/patch-apply.d.ts.map +1 -0
  34. package/cli/commands/patch-apply.js +75 -0
  35. package/cli/commands/patch-apply.ts +80 -0
  36. package/cli/commands/patch.d.ts +3 -0
  37. package/cli/commands/patch.d.ts.map +1 -0
  38. package/cli/commands/patch.js +21 -0
  39. package/cli/commands/patch.ts +22 -0
  40. package/cli/commands/set.d.ts +3 -0
  41. package/cli/commands/set.d.ts.map +1 -0
  42. package/cli/commands/set.js +286 -0
  43. package/cli/commands/set.ts +225 -0
  44. package/cli/commands/utils.d.ts +4 -0
  45. package/cli/commands/utils.d.ts.map +1 -0
  46. package/cli/commands/utils.js +51 -0
  47. package/cli/commands/utils.ts +50 -0
  48. package/cli/commands/validate.d.ts +3 -0
  49. package/cli/commands/validate.d.ts.map +1 -0
  50. package/cli/commands/validate.js +131 -0
  51. package/cli/commands/validate.ts +115 -0
  52. package/cli/commands/why.d.ts +3 -0
  53. package/cli/commands/why.d.ts.map +1 -0
  54. package/cli/commands/why.js +64 -0
  55. package/cli/commands/why.ts +46 -0
  56. package/cli/config-schema.d.ts +238 -0
  57. package/cli/config-schema.d.ts.map +1 -0
  58. package/cli/config-schema.js +21 -0
  59. package/cli/config-schema.ts +27 -0
  60. package/cli/config.d.ts +4 -0
  61. package/cli/config.d.ts.map +1 -0
  62. package/cli/config.js +37 -0
  63. package/cli/config.ts +35 -0
  64. package/cli/dcv.d.ts +3 -0
  65. package/cli/dcv.d.ts.map +1 -0
  66. package/cli/dcv.js +86 -0
  67. package/cli/dcv.ts +107 -0
  68. package/cli/engine-helpers.d.ts +8 -0
  69. package/cli/engine-helpers.d.ts.map +1 -0
  70. package/cli/engine-helpers.js +70 -0
  71. package/cli/engine-helpers.ts +61 -0
  72. package/cli/graph-poset.d.ts +9 -0
  73. package/cli/graph-poset.d.ts.map +1 -0
  74. package/cli/graph-poset.js +58 -0
  75. package/cli/graph-poset.ts +74 -0
  76. package/cli/index.d.ts +3 -0
  77. package/cli/index.d.ts.map +1 -0
  78. package/cli/index.js +2 -0
  79. package/cli/index.ts +2 -0
  80. package/cli/result.d.ts +17 -0
  81. package/cli/result.d.ts.map +1 -0
  82. package/cli/result.js +29 -0
  83. package/cli/result.ts +27 -0
  84. package/cli/run.d.ts +3 -0
  85. package/cli/run.d.ts.map +1 -0
  86. package/cli/run.js +47 -0
  87. package/cli/run.ts +54 -0
  88. package/cli/smoke-test.d.ts +2 -0
  89. package/cli/smoke-test.d.ts.map +1 -0
  90. package/cli/smoke-test.js +33 -0
  91. package/cli/smoke-test.ts +40 -0
  92. package/cli/types.d.ts +86 -0
  93. package/cli/types.d.ts.map +1 -0
  94. package/cli/types.js +1 -0
  95. package/cli/types.ts +78 -0
  96. package/core/breakpoints.d.ts +12 -0
  97. package/core/breakpoints.d.ts.map +1 -0
  98. package/core/breakpoints.js +48 -0
  99. package/core/breakpoints.ts +50 -0
  100. package/core/cli-format.d.ts +8 -0
  101. package/core/cli-format.d.ts.map +1 -0
  102. package/core/cli-format.js +29 -0
  103. package/core/cli-format.ts +31 -0
  104. package/core/color.d.ts +14 -0
  105. package/core/color.d.ts.map +1 -0
  106. package/core/color.js +136 -0
  107. package/core/color.ts +148 -0
  108. package/core/constraints/cross-axis.d.ts +33 -0
  109. package/core/constraints/cross-axis.d.ts.map +1 -0
  110. package/core/constraints/cross-axis.js +93 -0
  111. package/core/constraints/cross-axis.ts +114 -0
  112. package/core/constraints/monotonic-lightness.d.ts +5 -0
  113. package/core/constraints/monotonic-lightness.d.ts.map +1 -0
  114. package/core/constraints/monotonic-lightness.js +37 -0
  115. package/core/constraints/monotonic-lightness.ts +38 -0
  116. package/core/constraints/monotonic.d.ts +7 -0
  117. package/core/constraints/monotonic.d.ts.map +1 -0
  118. package/core/constraints/monotonic.js +65 -0
  119. package/core/constraints/monotonic.ts +74 -0
  120. package/core/constraints/threshold.d.ts +10 -0
  121. package/core/constraints/threshold.d.ts.map +1 -0
  122. package/core/constraints/threshold.js +36 -0
  123. package/core/constraints/threshold.ts +43 -0
  124. package/core/constraints/wcag.d.ts +11 -0
  125. package/core/constraints/wcag.d.ts.map +1 -0
  126. package/core/constraints/wcag.js +53 -0
  127. package/core/constraints/wcag.ts +70 -0
  128. package/core/cross-axis-config.d.ts +5 -0
  129. package/core/cross-axis-config.d.ts.map +1 -0
  130. package/core/cross-axis-config.js +144 -0
  131. package/core/cross-axis-config.ts +152 -0
  132. package/core/engine.d.ts +32 -0
  133. package/core/engine.d.ts.map +1 -0
  134. package/core/engine.js +46 -0
  135. package/core/engine.ts +65 -0
  136. package/core/flatten.d.ts +20 -0
  137. package/core/flatten.d.ts.map +1 -0
  138. package/core/flatten.js +80 -0
  139. package/core/flatten.ts +116 -0
  140. package/core/image-export.d.ts +10 -0
  141. package/core/image-export.d.ts.map +1 -0
  142. package/core/image-export.js +43 -0
  143. package/core/image-export.ts +48 -0
  144. package/core/index.d.ts +31 -0
  145. package/core/index.d.ts.map +1 -0
  146. package/core/index.js +54 -0
  147. package/core/index.ts +72 -0
  148. package/core/patch.d.ts +28 -0
  149. package/core/patch.d.ts.map +1 -0
  150. package/core/patch.js +110 -0
  151. package/core/patch.ts +134 -0
  152. package/core/poset.d.ts +41 -0
  153. package/core/poset.d.ts.map +1 -0
  154. package/core/poset.js +275 -0
  155. package/core/poset.ts +311 -0
  156. package/core/why.d.ts +17 -0
  157. package/core/why.d.ts.map +1 -0
  158. package/core/why.js +45 -0
  159. package/core/why.ts +63 -0
  160. package/dist/test-overrides-removal.json +4 -0
  161. package/dist/tmp.patch.json +35 -0
  162. package/package.json +90 -0
  163. package/themes/color.lg.order.json +15 -0
  164. package/themes/color.md.order.json +15 -0
  165. package/themes/color.order.json +15 -0
  166. package/themes/color.sm.order.json +15 -0
  167. package/themes/cross-axis.rules.json +36 -0
  168. package/themes/cross-axis.sm.rules.json +12 -0
  169. package/themes/layout.lg.order.json +18 -0
  170. package/themes/layout.md.order.json +18 -0
  171. package/themes/layout.order.json +18 -0
  172. package/themes/layout.sm.order.json +18 -0
  173. package/themes/spacing.order.json +14 -0
  174. package/themes/typography.lg.order.json +15 -0
  175. package/themes/typography.md.order.json +15 -0
  176. package/themes/typography.order.json +15 -0
  177. package/themes/typography.sm.order.json +15 -0
  178. package/tokens/overrides/base.json +22 -0
  179. package/tokens/overrides/lg.json +20 -0
  180. package/tokens/overrides/md.json +16 -0
  181. package/tokens/overrides/sm.json +16 -0
  182. package/tokens/overrides/viol.color.json +6 -0
  183. package/tokens/overrides/viol.typography.json +6 -0
  184. package/tokens/tokens.demo-violations.json +116 -0
  185. package/tokens/tokens.example.json +128 -0
  186. package/tokens/tokens.json +67 -0
  187. package/tokens/tokens.multi-violations.json +21 -0
  188. package/tokens/tokens.schema.d.ts +2298 -0
  189. package/tokens/tokens.schema.d.ts.map +1 -0
  190. package/tokens/tokens.schema.js +148 -0
  191. package/tokens/tokens.schema.ts +196 -0
  192. package/tokens/tokens.test.json +38 -0
  193. package/tokens/tokens.touch-violation.json +8 -0
  194. package/tokens/typography.classes.css +11 -0
  195. package/tokens/typography.css +20 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Cseperke Papp
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,659 @@
1
+ # Design Constraint Validator (DCV)
2
+ > Mathematical constraint validator for design systems — ensuring consistency, accessibility, and logical coherence.
3
+
4
+ [![CI](https://github.com/CseperkePapp/design-constraint-validator/actions/workflows/ci.yml/badge.svg)](https://github.com/CseperkePapp/design-constraint-validator/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![Node](https://img.shields.io/badge/node-%3E%3D18.x-339933.svg)](#)
7
+
8
+ > **Note:** DCV's CI intentionally includes validation errors in example tokens to demonstrate the tool works. See our [CI workflow](.github/workflows/ci.yml) for how we use `--fail-on off` to report violations without blocking builds.
9
+
10
+ **Design Constraint Validator (DCV)** validates design constraints across token sets and styles:
11
+ - ✅ **Accessibility:** WCAG text contrast, perceptual lightness floor/ceilings
12
+ - ✅ **Order & Monotonicity:** increasing typography scales, spacing hierarchies
13
+ - ✅ **Thresholds & Policies:** min/max ranges, cross-axis guards (size × weight × contrast)
14
+ - ✅ **Graph Intelligence:** Hasse/poset graph export; "why" explanations with implicated edges
15
+
16
+ This is **not** a schema linter; it's a **reasoning validator** for values and relationships.
17
+
18
+ ---
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ # Local (recommended)
24
+ npm i -D design-constraint-validator
25
+
26
+ # One-off run
27
+ npx dcv --help
28
+ ```
29
+
30
+ **Node:** ≥ 18.x (ESM)
31
+
32
+ ---
33
+
34
+ ## Quick Start
35
+
36
+ ```bash
37
+ # Validate a token set (JSON) with default constraints
38
+ npx dcv validate ./tokens/example.tokens.json
39
+
40
+ # Validate with a policy profile (e.g., AA)
41
+ npx dcv validate ./tokens/example.tokens.json --policy ./themes/policies/aa.json
42
+
43
+ # Explain failures (tabular)
44
+ npx dcv why --format table
45
+
46
+ # Export graph (Mermaid or DOT)
47
+ npx dcv graph --format mermaid > graph.mmd
48
+ ```
49
+
50
+ > Try the failing samples to see diagnostics:
51
+
52
+ Note: When installed from npm, the `examples/` folder is not included to keep the package lean. You can browse and run examples directly from the repo:
53
+
54
+ - Failing examples: https://github.com/CseperkePapp/design-constraint-validator/tree/main/examples/failing
55
+ - Minimal example: https://github.com/CseperkePapp/design-constraint-validator/tree/main/examples/minimal
56
+
57
+ ```bash
58
+ npx dcv validate ./examples/failing/contrast-fail.tokens.json
59
+ npx dcv validate ./examples/failing/monotonicity-fail.tokens.json
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Input formats
65
+
66
+ DCV accepts a **token JSON** (flat or nested) and optional **policy JSON**.
67
+ Adapters normalize common ecosystems (Style Dictionary, Tokens Studio JSON, DTCG).
68
+
69
+ * See: [`adapters/README.md`](adapters/README.md)
70
+ * Example policies: `themes/policies/*.json` (AA/AAA presets, org policies)
71
+
72
+ ---
73
+
74
+ ## Example Output (Why / Explanations)
75
+
76
+ ```
77
+ Constraint Status Details
78
+ ──────────────────────────── ────── ─────────────────────────────────────────────
79
+ WCAG Contrast ≥ 4.5:1 FAIL text.primary(#5A5A5A) on bg.body(#F5F5F5) ⇒ 3.8
80
+ Typography monotonic scale FAIL h3(22) < body(18) < h2(21) < h1(34) ✖ out-of-order: h2<h3
81
+ Cross-axis (weight vs size) PASS all headings satisfy min weight for size bucket
82
+ Perceptual L (OKLCH L) PASS text on dark surfaces ≥ 0.85 L
83
+ Exit code: 1 (violations found)
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Programmatic API (Node)
89
+
90
+ ```ts
91
+ // ESM / TypeScript
92
+ import { validate } from 'design-constraint-validator';
93
+
94
+ const result = await validate({
95
+ tokensPath: './tokens/example.tokens.json',
96
+ policyPath: './themes/policies/aa.json'
97
+ });
98
+
99
+ if (result.ok) {
100
+ console.log('All constraints satisfied.');
101
+ } else {
102
+ for (const v of result.violations) {
103
+ console.log(`[${v.kind}] ${v.message}`, v.context);
104
+ }
105
+ process.exitCode = 1;
106
+ }
107
+ ```
108
+
109
+ ### Quick try (REPL)
110
+
111
+ ```bash
112
+ node
113
+ ```
114
+
115
+ ```js
116
+ // In Node REPL (ESM)
117
+ const dcv = await import('design-constraint-validator');
118
+ const tokens = { typography: { size: { h1: { $value: '32px' }, h2: { $value: '24px' } } } };
119
+ const themes = { order: [["typography.size.h1", ">=", "typography.size.h2"]] };
120
+ const res = await dcv.validate({ tokensObject: tokens, policyObject: themes });
121
+ console.log(res.ok ? 'OK' : res.violations);
122
+ ```
123
+
124
+ ### Subpath imports (typed)
125
+
126
+ If you prefer lower-level primitives:
127
+
128
+ ```ts
129
+ import { flattenTokens } from 'design-constraint-validator/core/flatten.js';
130
+ import { Engine } from 'design-constraint-validator/core/index.js';
131
+ ```
132
+
133
+ **Return shape (simplified):**
134
+
135
+ ```ts
136
+ type ValidationResult = {
137
+ ok: boolean;
138
+ violations: Array<{
139
+ kind: 'wcag' | 'monotonic' | 'threshold' | 'crossAxis' | string;
140
+ message: string;
141
+ context?: Record<string, unknown>;
142
+ nodes?: string[]; // implicated token ids
143
+ edges?: [string,string][]; // graph edges
144
+ }>;
145
+ stats: { checked: number; durationMs: number };
146
+ };
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Why constraints, not conventions?
152
+
153
+ Conventional linters catch **schema** issues ("has a value, has a type").
154
+ **DCV** enforces **relationships** that matter to users and brand integrity:
155
+
156
+ * Legible contrast under all themes and states
157
+ * Proper hierarchical spacing/typography (monotonic scales)
158
+ * Coherent cross-axis behavior (e.g., weight increases with size where needed)
159
+ * Policy conformance (AA/AAA, internal thresholds)
160
+
161
+ This transforms tokens from "bags of numbers" into a **formal design system**.
162
+
163
+ ---
164
+
165
+ ## Comparison (schema linters vs DCV)
166
+
167
+ * **Schema linters** (e.g., DTCG schema validators) ensure JSON shape.
168
+ * **DCV** validates **mathematical & policy constraints** over *values and relations*.
169
+
170
+ > DCV is not affiliated with Anima's `design-tokens-validator` (schema-focused).
171
+
172
+ ---
173
+
174
+ ## Graphs
175
+
176
+ Export the constraint graph for audits and docs:
177
+
178
+ ```bash
179
+ npx dcv graph --format mermaid > graph.mmd
180
+ ```
181
+
182
+ **Mermaid (illustrative):**
183
+
184
+ ```mermaid
185
+ graph TD
186
+ BodySize --> H2Size
187
+ H2Size --> H1Size
188
+ BodyColor --> WCAG
189
+ H1Color --> WCAG
190
+ ```
191
+
192
+ ---
193
+
194
+ ## Adapters
195
+
196
+ * **Style Dictionary** input
197
+ * **Tokens Studio JSON** input
198
+ * **DTCG** (Design Tokens Community Group) mapping
199
+
200
+ See [`adapters/README.md`](adapters/README.md) for format notes.
201
+
202
+ ---
203
+
204
+ ## Getting Started
205
+
206
+ ### Your First Validation (5 minutes)
207
+
208
+ **1. Install**
209
+ ```bash
210
+ npm install -D design-constraint-validator
211
+ ```
212
+
213
+ **2. Create `tokens.json`** in your project root:
214
+ ```json
215
+ {
216
+ "color": {
217
+ "text": { "$value": "#1a1a1a" },
218
+ "background": { "$value": "#ffffff" }
219
+ },
220
+ "typography": {
221
+ "size": {
222
+ "h1": { "$value": "32px" },
223
+ "h2": { "$value": "24px" },
224
+ "body": { "$value": "16px" }
225
+ }
226
+ }
227
+ }
228
+ ```
229
+
230
+ **3. Create `themes/wcag.json`** (WCAG contrast constraint):
231
+ ```json
232
+ {
233
+ "constraints": {
234
+ "wcag": [{
235
+ "foreground": "color.text",
236
+ "background": "color.background",
237
+ "ratio": 4.5
238
+ }]
239
+ }
240
+ }
241
+ ```
242
+
243
+ **4. Create `themes/typography.order.json`** (size hierarchy):
244
+ ```json
245
+ {
246
+ "order": [
247
+ ["typography.size.h1", ">=", "typography.size.h2"],
248
+ ["typography.size.h2", ">=", "typography.size.body"]
249
+ ]
250
+ }
251
+ ```
252
+
253
+ **5. Validate**
254
+ ```bash
255
+ npx dcv validate
256
+ ```
257
+
258
+ **Output:**
259
+ ```
260
+ ✅ validate: 0 error(s), 0 warning(s)
261
+ ```
262
+
263
+ Success! Your tokens pass all constraints.
264
+
265
+ ### What if validation fails?
266
+
267
+ Try changing `h2` to `"40px"` (larger than h1) and run validation again:
268
+
269
+ ```bash
270
+ npx dcv validate
271
+ ```
272
+
273
+ **Output:**
274
+ ```
275
+ validate: 1 error(s), 0 warning(s)
276
+ ERROR monotonic typography.size.h2 @ typography.order.json — typography.size.h1 >= typography.size.h2 violated: 32px < 40px
277
+ ```
278
+
279
+ The validator explains exactly what failed and why.
280
+
281
+ ### Minimal Working Example
282
+
283
+ See [examples/minimal/](examples/minimal/) for a complete minimal setup you can copy.
284
+
285
+ ## Example Output
286
+
287
+ ### ✅ Successful Validation
288
+ ```bash
289
+ $ npx dcv validate
290
+ ✅ validate: 0 error(s), 0 warning(s)
291
+ ```
292
+
293
+ ### ❌ Failed Validation
294
+ ```bash
295
+ $ npx dcv validate
296
+ validate: 2 error(s), 1 warning(s)
297
+
298
+ ERROR monotonic typography.size.h2
299
+ typography.size.h1 >= typography.size.h2 violated: 32px < 40px
300
+ Defined in: themes/typography.order.json
301
+
302
+ ERROR wcag color.text vs color.background
303
+ Contrast ratio 4.5:1 required, got 2.1:1
304
+ Defined in: themes/wcag.json
305
+
306
+ WARN threshold control.size.min
307
+ Touch target should be >= 44px, got 30px
308
+ Defined in: themes/touch.json
309
+ ```
310
+
311
+ ## Constraint Types
312
+
313
+ ### 1. Monotonic Constraints
314
+ Enforce ordering relationships (e.g., h1 ≥ h2 ≥ h3)
315
+
316
+ ```json
317
+ {
318
+ "order": [
319
+ ["typography.size.h1", ">=", "typography.size.h2"],
320
+ ["typography.size.h2", ">=", "typography.size.h3"]
321
+ ]
322
+ }
323
+ ```
324
+
325
+ ### 2. WCAG Contrast
326
+ Validate color accessibility
327
+
328
+ ```json
329
+ {
330
+ "constraints": {
331
+ "wcag": [
332
+ {
333
+ "foreground": "color.role.text.default",
334
+ "background": "color.role.bg.surface",
335
+ "ratio": 4.5
336
+ }
337
+ ]
338
+ }
339
+ }
340
+ ```
341
+
342
+ ### 3. Threshold Rules
343
+ Size guardrails (e.g., ≥44px touch targets)
344
+
345
+ ```typescript
346
+ {
347
+ id: 'control.size.min',
348
+ op: '>=',
349
+ valuePx: 44,
350
+ where: 'Touch target (WCAG / Apple HIG)'
351
+ }
352
+ ```
353
+
354
+ ### 4. Lightness Ordering
355
+ Color palette progression
356
+
357
+ ```json
358
+ {
359
+ "order": [
360
+ ["color.palette.brand.100", ">=", "color.palette.brand.200"],
361
+ ["color.palette.brand.200", ">=", "color.palette.brand.300"]
362
+ ]
363
+ }
364
+ ```
365
+
366
+ ### 5. Cross-Axis Constraints
367
+ Multi-domain relationships
368
+
369
+ ```json
370
+ {
371
+ "when": { "id": "typography.weight.body", "op": "<=", "value": 400 },
372
+ "require": { "id": "typography.size.body", "op": ">=", "fallback": "16px" }
373
+ }
374
+ ```
375
+
376
+ ## CLI Commands
377
+
378
+ ### Validate
379
+
380
+ ```bash
381
+ # Validate all tokens
382
+ dcv validate
383
+
384
+ # Validate specific breakpoint
385
+ dcv validate --breakpoint md
386
+
387
+ # All breakpoints with summary
388
+ dcv validate --all-breakpoints --summary table
389
+
390
+ # Fail on warnings
391
+ dcv validate --fail-on warn
392
+ ```
393
+
394
+ ### Graph Visualization
395
+
396
+ Export token dependency graphs in text formats (Mermaid, Graphviz DOT):
397
+
398
+ ```bash
399
+ # Export Mermaid format (renders on GitHub)
400
+ dcv graph --hasse typography --format mermaid > typography.mmd
401
+
402
+ # Export Graphviz DOT format
403
+ dcv graph --hasse color --format dot > color.dot
404
+
405
+ # JSON format for programmatic use
406
+ dcv graph --hasse layout --format json > layout.json
407
+
408
+ # Show only violations
409
+ dcv graph --hasse color --only-violations --format mermaid
410
+
411
+ # Highlight violations
412
+ dcv graph --hasse layout --highlight-violations --format mermaid
413
+ ```
414
+
415
+ **Rendering Options:**
416
+ 1. **GitHub** - Paste Mermaid code into `.md` files (native support)
417
+ 2. **mermaid.live** - Online Mermaid editor and renderer
418
+ 3. **VS Code** - Use Mermaid Preview extension
419
+ 4. **Graphviz** - Render DOT files: `dot -Tpng color.dot -o color.png`
420
+
421
+ **For PNG/SVG generation** (optional):
422
+ ```bash
423
+ # Install Mermaid CLI globally
424
+ npm install -g @mermaid-js/mermaid-cli
425
+
426
+ # Generate image
427
+ mmdc -i typography.mmd -o typography.png
428
+ ```
429
+
430
+ ### Provenance Analysis
431
+
432
+ ```bash
433
+ # Why does this token have this value?
434
+ dcv why typography.size.h1
435
+
436
+ # JSON output
437
+ dcv why color.role.text.default --format json
438
+ ```
439
+
440
+ ### Build Tokens
441
+
442
+ ```bash
443
+ # Build tokens
444
+ dcv build
445
+
446
+ # Build all formats
447
+ dcv build --all-formats
448
+
449
+ # Watch mode
450
+ dcv build --watch
451
+ ```
452
+
453
+ ### Set Token Values
454
+
455
+ ```bash
456
+ # Set a single token
457
+ dcv set typography.size.h1=32px
458
+
459
+ # Set color with OKLCH
460
+ dcv set color.palette.brand.500=oklch(0.65 0.15 280)
461
+ ```
462
+
463
+ ## Use Cases
464
+
465
+ ✅ **Design System Validation** - Catch inconsistencies in CI/CD
466
+ ✅ **Accessibility Compliance** - Ensure WCAG 2.1 AA/AAA
467
+ ✅ **Multi-Breakpoint** - Validate responsive token overrides
468
+ ✅ **Dependency Analysis** - Visualize token relationships
469
+ ✅ **Token Debugging** - Understand where values come from
470
+
471
+ ## Example
472
+
473
+ **tokens.json:**
474
+ ```json
475
+ {
476
+ "typography": {
477
+ "size": {
478
+ "h1": "32px",
479
+ "h2": "24px",
480
+ "body": "16px"
481
+ }
482
+ },
483
+ "color": {
484
+ "role": {
485
+ "text": { "default": "#1a1a1a" },
486
+ "bg": { "surface": "#ffffff" }
487
+ }
488
+ }
489
+ }
490
+ ```
491
+
492
+ **themes/typography.order.json:**
493
+ ```json
494
+ {
495
+ "order": [
496
+ ["typography.size.h1", ">=", "typography.size.h2"],
497
+ ["typography.size.h2", ">=", "typography.size.body"]
498
+ ]
499
+ }
500
+ ```
501
+
502
+ **Validate:**
503
+ ```bash
504
+ $ npx dcv validate
505
+
506
+ ✅ validate [bp=base]: 0 error(s), 0 warning(s)
507
+ ```
508
+
509
+ ## Architecture
510
+
511
+ ```
512
+ ┌─────────────────────────────────────┐
513
+ │ Token Dependency Graph (DAG) │
514
+ │ Tracks references & dependencies │
515
+ └─────────────────────────────────────┘
516
+
517
+ ┌─────────────────────────────────────┐
518
+ │ Constraint Validation Engine │
519
+ │ ┌──────────────────────────────┐ │
520
+ │ │ Plugin-based architecture │ │
521
+ │ │ - Monotonic │ │
522
+ │ │ - WCAG Contrast │ │
523
+ │ │ - Threshold │ │
524
+ │ │ - Lightness │ │
525
+ │ │ - Cross-Axis │ │
526
+ │ └──────────────────────────────┘ │
527
+ └─────────────────────────────────────┘
528
+
529
+ ┌─────────────────────────────────────┐
530
+ │ Violation Reporting │
531
+ │ - Descriptive error messages │
532
+ │ - Provenance tracing │
533
+ │ - Graph visualization │
534
+ └─────────────────────────────────────┘
535
+ ```
536
+
537
+ ## Documentation
538
+
539
+ - **[Getting Started](docs/Getting-Started.md)** - 5-minute quick start
540
+ - **[Constraint Types](docs/Constraints.md)** - All constraint types
541
+ - **[CLI Reference](docs/CLI.md)** - Complete command documentation
542
+ - **[Configuration](docs/Configuration.md)** - Config file options
543
+ - **[Architecture](docs/Architecture.md)** - How DCV works
544
+ - **[API Reference](docs/API.md)** - Programmatic usage
545
+
546
+ ---
547
+
548
+ ## Roadmap
549
+
550
+ * Plugin API for **custom constraints**
551
+ * **VS Code** diagnostics (inline explain)
552
+ * **Cross-axis packs** (typography × weight × contrast)
553
+ * **Receipts & provenance** (hashes, signable reports)
554
+ * UI graph explorer (node inspector, violations focus)
555
+
556
+ ---
557
+
558
+ ## Philosophy
559
+
560
+ > **Constraints, not conventions.**
561
+
562
+ Design systems need more than naming conventions - they need mathematical guarantees. This validator:
563
+
564
+ 1. **Enforces relationships** - Typography hierarchies, color progressions
565
+ 2. **Validates accessibility** - WCAG contrast with alpha compositing
566
+ 3. **Explains violations** - Provenance tracing shows why rules fail
567
+ 4. **Scales with complexity** - Incremental validation of 1000s of tokens
568
+
569
+ ## Related Projects
570
+
571
+ This is the **core validation engine**. For a complete decision-driven design system with a 5-axis framework (Tone, Emphasis, Size, Density, Shape) and theme configurator UI, see **DecisionThemes** (coming soon).
572
+
573
+ ## FAQ
574
+
575
+ ### How does the tool find my tokens and constraints?
576
+
577
+ By default, it looks for:
578
+ - **Tokens**: `tokens.json` or `tokens/*.json`
579
+ - **Constraints**: `themes/*.json` or `themes/**/*.json`
580
+
581
+ You can customize paths in a `dcv.config.json` file. See [CONFIGURATION.md](CONFIGURATION.md) for details.
582
+
583
+ ### What's the relationship with DecisionThemes?
584
+
585
+ `design-constraint-validator` is the **core validation engine** - it validates any design tokens against constraints.
586
+
587
+ **DecisionThemes** (coming soon) is a complete design system framework that uses this validator under the hood, plus adds:
588
+ - 5-axis decision framework (Tone, Emphasis, Size, Density, Shape)
589
+ - Theme configurator UI
590
+ - Decision → Token mapping
591
+
592
+ Think of it as: **design-token-validator** = engine, **DecisionThemes** = full product built on the engine.
593
+
594
+ ### Can I use this with my existing tokens?
595
+
596
+ Yes! As long as your tokens follow a structured JSON format. The tool supports:
597
+ - [W3C Design Tokens Community Group](https://design-tokens.github.io/community-group/) format
598
+ - Custom nested JSON structures
599
+ - Token references with `{token.path}` syntax
600
+
601
+ ### How do I use incremental validation?
602
+
603
+ Incremental validation automatically detects changed tokens and only validates those tokens plus their dependents. This feature is built-in - no configuration needed. When you run `dcv validate`, it will use cached results for unchanged tokens.
604
+
605
+ ### What breakpoints are supported?
606
+
607
+ The tool supports responsive tokens with breakpoint-specific overrides. Place override files in `tokens/overrides/`:
608
+ - `tokens/overrides/sm.json` - Small screens
609
+ - `tokens/overrides/md.json` - Medium screens
610
+ - `tokens/overrides/lg.json` - Large screens
611
+
612
+ Validate specific breakpoints with `--breakpoint md` or all breakpoints with `--all-breakpoints`.
613
+
614
+ ### Can I use this in CI/CD?
615
+
616
+ Absolutely! That's a primary use case:
617
+
618
+ ```yaml
619
+ # .github/workflows/validate-tokens.yml
620
+ name: Validate Design Tokens
621
+ on: [push, pull_request]
622
+ jobs:
623
+ validate:
624
+ runs-on: ubuntu-latest
625
+ steps:
626
+ - uses: actions/checkout@v4
627
+ - uses: actions/setup-node@v4
628
+ - run: npm ci
629
+ - run: npx dcv validate --fail-on warn
630
+ ```
631
+
632
+ The tool exits with non-zero code on validation failures, making it perfect for CI/CD gates.
633
+
634
+ ### How do I visualize my token dependencies?
635
+
636
+ Use the `graph` command:
637
+
638
+ ```bash
639
+ # Generate Mermaid diagram (renders on GitHub)
640
+ dcv graph --hasse typography --format mermaid > typography.mmd
641
+
642
+ # Generate Graphviz DOT
643
+ dcv graph --hasse color --format dot > color.dot
644
+
645
+ # Then render with Graphviz
646
+ dot -Tpng color.dot -o color.png
647
+ ```
648
+
649
+ ### What Node.js version do I need?
650
+
651
+ Node.js 18 or higher is required.
652
+
653
+ ## Contributing
654
+
655
+ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md)
656
+
657
+ ## License
658
+
659
+ MIT © Cseperke Papp