@getvitops/generator 0.8.0 → 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 (38) hide show
  1. package/CHANGELOG.md +459 -0
  2. package/README.md +16 -4
  3. package/assets/bricks/load.php +46 -1
  4. package/assets/css/animation.css +12 -2
  5. package/assets/css/patterns/carousel.css +3 -3
  6. package/assets/css/patterns/code.css +2 -2
  7. package/assets/css/patterns/combobox.css +3 -3
  8. package/assets/css/patterns/comment.css +1 -1
  9. package/assets/css/patterns/copy.css +3 -3
  10. package/assets/css/patterns/details.css +27 -8
  11. package/assets/css/patterns/dialog.css +2 -2
  12. package/assets/css/patterns/drawer.css +17 -2
  13. package/assets/css/patterns/forms.css +11 -11
  14. package/assets/css/patterns/grouped.css +1 -1
  15. package/assets/css/patterns/icon.css +2 -2
  16. package/assets/css/patterns/list.css +5 -5
  17. package/assets/css/patterns/media.css +1 -1
  18. package/assets/css/patterns/nav.css +5 -5
  19. package/assets/css/patterns/notification.css +3 -3
  20. package/assets/css/patterns/scroll-based.css +1 -1
  21. package/assets/css/patterns/scroll-target.css +3 -3
  22. package/assets/css/patterns/sitenav.css +14 -14
  23. package/assets/css/patterns/split-link.css +4 -4
  24. package/assets/css/patterns/subgrid.css +62 -16
  25. package/assets/css/patterns/tag.css +1 -1
  26. package/assets/css/patterns/text-effects.css +1 -1
  27. package/assets/css/patterns/theme-editor.css +14 -6
  28. package/assets/css/patterns/tooltip.css +2 -2
  29. package/assets/css/patterns/tree.css +3 -3
  30. package/assets/css/utilities.css +5 -3
  31. package/assets/js/editor.js +2 -2
  32. package/dist/index.d.mts +565 -50
  33. package/dist/index.d.mts.map +1 -1
  34. package/dist/index.mjs +3337 -1301
  35. package/dist/index.mjs.map +1 -1
  36. package/package.json +3 -3
  37. package/schema.json +51 -9
  38. package/site.schema.json +149 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getvitops/generator",
3
- "version": "0.8.0",
3
+ "version": "1.0.0",
4
4
  "description": "Generate design-system outputs (Bricks, standalone CSS, Tailwind v4) from a design-system.json.",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -27,10 +27,10 @@
27
27
  "dependencies": {
28
28
  "lightningcss": "^1.32.0",
29
29
  "zod": "^4.1.13",
30
- "@getvitops/utils": "0.8.0"
30
+ "@getvitops/utils": "1.0.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "vitest": "^4.1.9",
34
- "@getvitops/core": "0.8.0"
34
+ "@getvitops/core": "1.0.0"
35
35
  }
36
36
  }
package/schema.json CHANGED
@@ -7,6 +7,21 @@
7
7
  "description": "URL of the published JSON Schema (stamped by `vitops init`) so editors provide autocomplete + validation.",
8
8
  "type": "string"
9
9
  },
10
+ "meta": {
11
+ "description": "Brand identity for agent-facing output. Consumed only by the `design` format (`DESIGN.md`); it emits no CSS and no tokens.",
12
+ "type": "object",
13
+ "properties": {
14
+ "name": {
15
+ "description": "Brand/system name. Used as the `name` field and `<h1>` of the `design` format's `DESIGN.md`. Defaults to \"Design System\".",
16
+ "type": "string"
17
+ },
18
+ "description": {
19
+ "description": "One or two sentences on the brand personality and the feeling the UI should evoke — what an agent needs when no token answers the question. Becomes the DESIGN.md `description` field and opens its Overview section; if omitted, a generic description of the system's mechanics is used instead.",
20
+ "type": "string"
21
+ }
22
+ },
23
+ "additionalProperties": false
24
+ },
10
25
  "colors": {
11
26
  "type": "object",
12
27
  "properties": {
@@ -32,7 +47,7 @@
32
47
  "additionalProperties": {
33
48
  "type": "string"
34
49
  },
35
- "description": "Step → colour overrides (hex or oklch()) that pin specific steps of the generated scale; the remaining steps interpolate around them."
50
+ "description": "Step → colour overrides (hex or oklch()) pinned VERBATIM at those steps. Every other step takes its lightness from the shared ladder, with chroma and hue interpolated between the anchors — so an anchor is reproduced exactly and is the only step allowed off the ladder. An explicit anchor overrides the seed at that step; two anchors that resolve to the same step are an error."
36
51
  }
37
52
  },
38
53
  "required": [
@@ -82,9 +97,35 @@
82
97
  "type": "string"
83
98
  },
84
99
  "additionalProperties": {
85
- "type": "string"
100
+ "anyOf": [
101
+ {
102
+ "type": "string",
103
+ "description": "A palette hue name. Shorthand for `{ hue, kind: \"chromatic\" }`."
104
+ },
105
+ {
106
+ "type": "object",
107
+ "properties": {
108
+ "hue": {
109
+ "type": "string",
110
+ "description": "The palette hue this role resolves to."
111
+ },
112
+ "kind": {
113
+ "type": "string",
114
+ "enum": [
115
+ "surface",
116
+ "chromatic"
117
+ ],
118
+ "description": "`surface` — a page/panel colour: gets a bare `bg-<role>` plus the full emphasis range and text scale. `chromatic` (default) — a signal colour: tints and solids only, no bare `bg-<role>`."
119
+ }
120
+ },
121
+ "required": [
122
+ "hue"
123
+ ],
124
+ "additionalProperties": false
125
+ }
126
+ ]
86
127
  },
87
- "description": "Maps each semantic role (neutral, surface, ui-primary/secondary/accent, brand-primary/secondary, info, success, warning, danger) to the palette hue backing it. The generator derives every role's FUNCTIONAL tokens (`--<role>-{bg,bg-muted,border,border-bold,solid,solid-bold,on-solid,text,text-muted,text-x-muted}`) plus emphasis stops from the hue's scale, and dark mode flips automatically — there is no per-appearance scheme grammar."
128
+ "description": "Maps semantic role names onto palette hues. Role names are ARBITRARY — add a key and the generator emits that role's token set (`--color-<target>-<role>[-<variant>]` for target bg/text/icon/border), its dark-mode flip and its utility classes.\n\nA value is either a hue name (`\"danger\": \"rust\"`) or `{ \"hue\": …, \"kind\": \"surface\" | \"chromatic\" }`. **The kind decides the shape of the token set.** `chromatic` (the default, and what the bare-string form means) is a signal colour: its backgrounds split into tints (`bg-<role>-x-muted`/`-muted`) and solids (`bg-<role>-solid[-bold|-x-bold]`), with deliberately **no bare `bg-<role>`** — \"how loud?\" is a question the author answers. `surface` is a page/panel colour: it has a bare `bg-<role>` plus the full emphasis range and text scale.\n\nDark mode flips automatically; there is no per-appearance scheme grammar. The solid family and its computed `text-on-<role>` foreground stay mode-stable so a filled button keeps its identity. Six roles are a required core, because the shipped framework CSS references them with no fallback: brand-primary, danger, neutral, surface, ui-primary, warning. Conventional additions are ui-secondary/accent, brand-secondary, info and success."
88
129
  },
89
130
  "utilities": {
90
131
  "type": "array",
@@ -93,13 +134,14 @@
93
134
  "enum": [
94
135
  "bg",
95
136
  "text",
137
+ "icon",
96
138
  "border",
97
139
  "outline",
98
140
  "fill",
99
141
  "stroke"
100
142
  ]
101
143
  },
102
- "description": "Which colour utility-class families to emit (`bg-*`, `text-*`, `border-*`, `outline-*`, `fill-*`, `stroke-*`). Defaults to bg, text, border."
144
+ "description": "Which colour utility-class families to emit (`bg-*`, `text-*`, `icon-*`, `border-*`, `outline-*`, `fill-*`, `stroke-*`). Defaults to bg, text, icon, border. `icon` is a separate non-text tier (a glyph may run more vivid than text); `outline`/`fill`/`stroke` have no tokens of their own and alias the border and icon tiers."
103
145
  }
104
146
  },
105
147
  "required": [
@@ -107,10 +149,10 @@
107
149
  "roles"
108
150
  ],
109
151
  "additionalProperties": false,
110
- "description": "The colour system (the only required section): `palette` hues become generated OKLCH scales; `roles` map semantic roles onto those hues, from which all functional tokens and dark mode derive."
152
+ "description": "The colour system (the only required section): `palette` hues become generated OKLCH scales; `roles` map semantic roles onto those hues, from which all role tokens and dark mode derive."
111
153
  },
112
154
  "shadows": {
113
- "description": "Named shadows → `--shadow-<name>` tokens and `.drop-shadow-<name>` utilities. Values are shadow parameter lists (offset/blur/colour), applied via `filter: drop-shadow(…)`.",
155
+ "description": "Named shadows → `--shadow-<name>` tokens and `.drop-shadow-<name>` utilities. Values are shadow parameter lists (offset/blur/colour). Each token feeds two consumers with different grammars — `box-shadow` (pattern geometry, via the `--ds-*` group aliases) and `filter: drop-shadow(…)` (the utilities and the `shadow:` state shortcut) — so values must stay in the intersection: **one layer, no spread radius, no `inset`**. `drop-shadow()` rejects all three, and rejecting them invalidates the whole filter, so the shadow vanishes rather than degrading.",
114
156
  "type": "object",
115
157
  "propertyNames": {
116
158
  "type": "string"
@@ -353,7 +395,7 @@
353
395
  "description": "Base CSS declarations. Geometry properties (padding, border-radius, border, box-shadow, font-size) are wrapped in per-pattern override hooks (`--p-<name>`, `--br-<name>`, `--b-<name>`, `--ds-<name>`, `--fs-<name>`) so consumers can restyle one pattern by setting one variable."
354
396
  },
355
397
  "states": {
356
- "description": "Interaction states (hover / active / focus-visible), each a map of shortcuts: `step` (intensify fills/text by n emphasis stops), `scale` (transform scale), `lift` (translateY + shadow), `shadow` (a shadow name → drop-shadow(var(--shadow-<name>)), or true → lift shadow), `ring` (focus ring), or raw `css` declarations. Hover rules are wrapped in `@media (hover: hover)`.",
398
+ "description": "Interaction states (hover / active / focus-visible), each a map of shortcuts: `step` (intensify the fill or text by n rungs — `bg-<role>-solid` → `-solid-bold`, `text-<role>` → `-bold`), `scale` (transform scale), `lift` (translateY + shadow), `shadow` (a shadow name → drop-shadow(var(--shadow-<name>)), or true → lift shadow), `ring` (focus ring), or raw `css` declarations. Hover rules are wrapped in `@media (hover: hover)`.",
357
399
  "type": "object",
358
400
  "propertyNames": {
359
401
  "type": "string"
@@ -420,7 +462,7 @@
420
462
  }
421
463
  },
422
464
  "headings": {
423
- "description": "Maps heading elements (h1…h6) to type roles so bare headings pick up role styling.",
465
+ "description": "Maps bare elements to type roles so unclassed markup picks up role styling — `{ \"h1\": \"display\", \"h2\": \"heading\" }`. The key is used verbatim as a selector, so it is not limited to h1…h6: **map `\"body\"` to your prose role** to bind base page typography to the role rather than hand-writing it. That binding is what makes the role editable — a stylesheet that re-states `font-family`/`line-height` as literals on `body` shadows `--<role>-ff`/`--<role>-lh`, and the live theme editor then appears to do nothing.",
424
466
  "type": "object",
425
467
  "propertyNames": {
426
468
  "type": "string"
@@ -431,7 +473,7 @@
431
473
  }
432
474
  },
433
475
  "additionalProperties": false,
434
- "description": "Typography: family aliases, semantic type roles (→ `font-<role>` classes), and the heading-element → role mapping."
476
+ "description": "Typography: family aliases, semantic type roles (→ `font-<role>` classes), and the bare-element → role mapping."
435
477
  },
436
478
  "animations": {
437
479
  "type": "object",
package/site.schema.json CHANGED
@@ -806,6 +806,21 @@
806
806
  "description": "URL of the published JSON Schema (stamped by `vitops init`) so editors provide autocomplete + validation.",
807
807
  "type": "string"
808
808
  },
809
+ "meta": {
810
+ "description": "Brand identity for agent-facing output. Consumed only by the `design` format (`DESIGN.md`); it emits no CSS and no tokens.",
811
+ "type": "object",
812
+ "properties": {
813
+ "name": {
814
+ "description": "Brand/system name. Used as the `name` field and `<h1>` of the `design` format's `DESIGN.md`. Defaults to \"Design System\".",
815
+ "type": "string"
816
+ },
817
+ "description": {
818
+ "description": "One or two sentences on the brand personality and the feeling the UI should evoke — what an agent needs when no token answers the question. Becomes the DESIGN.md `description` field and opens its Overview section; if omitted, a generic description of the system's mechanics is used instead.",
819
+ "type": "string"
820
+ }
821
+ },
822
+ "additionalProperties": false
823
+ },
809
824
  "colors": {
810
825
  "type": "object",
811
826
  "properties": {
@@ -831,7 +846,7 @@
831
846
  "additionalProperties": {
832
847
  "type": "string"
833
848
  },
834
- "description": "Step → colour overrides (hex or oklch()) that pin specific steps of the generated scale; the remaining steps interpolate around them."
849
+ "description": "Step → colour overrides (hex or oklch()) pinned VERBATIM at those steps. Every other step takes its lightness from the shared ladder, with chroma and hue interpolated between the anchors — so an anchor is reproduced exactly and is the only step allowed off the ladder. An explicit anchor overrides the seed at that step; two anchors that resolve to the same step are an error."
835
850
  }
836
851
  },
837
852
  "required": [
@@ -880,7 +895,33 @@
880
895
  "type": "string"
881
896
  },
882
897
  "additionalProperties": {
883
- "type": "string"
898
+ "anyOf": [
899
+ {
900
+ "type": "string",
901
+ "description": "A palette hue name. Shorthand for `{ hue, kind: \"chromatic\" }`."
902
+ },
903
+ {
904
+ "type": "object",
905
+ "properties": {
906
+ "hue": {
907
+ "type": "string",
908
+ "description": "The palette hue this role resolves to."
909
+ },
910
+ "kind": {
911
+ "type": "string",
912
+ "enum": [
913
+ "surface",
914
+ "chromatic"
915
+ ],
916
+ "description": "`surface` — a page/panel colour: gets a bare `bg-<role>` plus the full emphasis range and text scale. `chromatic` (default) — a signal colour: tints and solids only, no bare `bg-<role>`."
917
+ }
918
+ },
919
+ "required": [
920
+ "hue"
921
+ ],
922
+ "additionalProperties": false
923
+ }
924
+ ]
884
925
  }
885
926
  },
886
927
  "utilities": {
@@ -890,6 +931,7 @@
890
931
  "enum": [
891
932
  "bg",
892
933
  "text",
934
+ "icon",
893
935
  "border",
894
936
  "outline",
895
937
  "fill",
@@ -901,7 +943,7 @@
901
943
  "additionalProperties": false
902
944
  },
903
945
  "shadows": {
904
- "description": "Named shadows → `--shadow-<name>` tokens and `.drop-shadow-<name>` utilities. Values are shadow parameter lists (offset/blur/colour), applied via `filter: drop-shadow(…)`.",
946
+ "description": "Named shadows → `--shadow-<name>` tokens and `.drop-shadow-<name>` utilities. Values are shadow parameter lists (offset/blur/colour). Each token feeds two consumers with different grammars — `box-shadow` (pattern geometry, via the `--ds-*` group aliases) and `filter: drop-shadow(…)` (the utilities and the `shadow:` state shortcut) — so values must stay in the intersection: **one layer, no spread radius, no `inset`**. `drop-shadow()` rejects all three, and rejecting them invalidates the whole filter, so the shadow vanishes rather than degrading.",
905
947
  "type": "object",
906
948
  "propertyNames": {
907
949
  "type": "string"
@@ -1144,7 +1186,7 @@
1144
1186
  "description": "Base CSS declarations. Geometry properties (padding, border-radius, border, box-shadow, font-size) are wrapped in per-pattern override hooks (`--p-<name>`, `--br-<name>`, `--b-<name>`, `--ds-<name>`, `--fs-<name>`) so consumers can restyle one pattern by setting one variable."
1145
1187
  },
1146
1188
  "states": {
1147
- "description": "Interaction states (hover / active / focus-visible), each a map of shortcuts: `step` (intensify fills/text by n emphasis stops), `scale` (transform scale), `lift` (translateY + shadow), `shadow` (a shadow name → drop-shadow(var(--shadow-<name>)), or true → lift shadow), `ring` (focus ring), or raw `css` declarations. Hover rules are wrapped in `@media (hover: hover)`.",
1189
+ "description": "Interaction states (hover / active / focus-visible), each a map of shortcuts: `step` (intensify the fill or text by n rungs — `bg-<role>-solid` → `-solid-bold`, `text-<role>` → `-bold`), `scale` (transform scale), `lift` (translateY + shadow), `shadow` (a shadow name → drop-shadow(var(--shadow-<name>)), or true → lift shadow), `ring` (focus ring), or raw `css` declarations. Hover rules are wrapped in `@media (hover: hover)`.",
1148
1190
  "type": "object",
1149
1191
  "propertyNames": {
1150
1192
  "type": "string"
@@ -1211,7 +1253,7 @@
1211
1253
  }
1212
1254
  },
1213
1255
  "headings": {
1214
- "description": "Maps heading elements (h1…h6) to type roles so bare headings pick up role styling.",
1256
+ "description": "Maps bare elements to type roles so unclassed markup picks up role styling — `{ \"h1\": \"display\", \"h2\": \"heading\" }`. The key is used verbatim as a selector, so it is not limited to h1…h6: **map `\"body\"` to your prose role** to bind base page typography to the role rather than hand-writing it. That binding is what makes the role editable — a stylesheet that re-states `font-family`/`line-height` as literals on `body` shadows `--<role>-ff`/`--<role>-lh`, and the live theme editor then appears to do nothing.",
1215
1257
  "type": "object",
1216
1258
  "propertyNames": {
1217
1259
  "type": "string"
@@ -1222,7 +1264,7 @@
1222
1264
  }
1223
1265
  },
1224
1266
  "additionalProperties": false,
1225
- "description": "Typography: family aliases, semantic type roles (→ `font-<role>` classes), and the heading-element → role mapping."
1267
+ "description": "Typography: family aliases, semantic type roles (→ `font-<role>` classes), and the bare-element → role mapping."
1226
1268
  },
1227
1269
  "animations": {
1228
1270
  "type": "object",
@@ -2238,9 +2280,16 @@
2238
2280
  "additionalProperties": false
2239
2281
  },
2240
2282
  "legal": {
2241
- "description": "Legal pages + cookie-consent configuration.",
2283
+ "description": "Legal pages: which documents exist, where they live, and the facts the generated prose asserts.",
2242
2284
  "type": "object",
2243
2285
  "properties": {
2286
+ "jurisdiction": {
2287
+ "description": "Which legal template set the generated documents use. Default `ca`.",
2288
+ "type": "string",
2289
+ "enum": [
2290
+ "ca"
2291
+ ]
2292
+ },
2244
2293
  "privacyPolicy": {
2245
2294
  "type": "object",
2246
2295
  "properties": {
@@ -2254,6 +2303,95 @@
2254
2303
  "lastUpdated": {
2255
2304
  "type": "string",
2256
2305
  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
2306
+ },
2307
+ "privacyOfficer": {
2308
+ "description": "Who privacy requests go to. Falls back to `contact`, then `primaryLocation`.",
2309
+ "anyOf": [
2310
+ {
2311
+ "type": "string"
2312
+ },
2313
+ {
2314
+ "type": "object",
2315
+ "properties": {
2316
+ "name": {
2317
+ "type": "string"
2318
+ },
2319
+ "email": {
2320
+ "type": "string",
2321
+ "format": "email",
2322
+ "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
2323
+ },
2324
+ "phone": {
2325
+ "type": "string"
2326
+ },
2327
+ "address": {
2328
+ "type": "object",
2329
+ "properties": {
2330
+ "streetAddress": {
2331
+ "type": "string"
2332
+ },
2333
+ "addressLocality": {
2334
+ "type": "string",
2335
+ "description": "City."
2336
+ },
2337
+ "addressRegion": {
2338
+ "description": "State / province.",
2339
+ "type": "string"
2340
+ },
2341
+ "postalCode": {
2342
+ "type": "string"
2343
+ },
2344
+ "addressCountry": {
2345
+ "type": "string",
2346
+ "description": "Country (ISO 3166-1 alpha-2 preferred)."
2347
+ }
2348
+ },
2349
+ "required": [
2350
+ "streetAddress",
2351
+ "addressLocality",
2352
+ "addressCountry"
2353
+ ],
2354
+ "additionalProperties": false,
2355
+ "description": "schema.org `PostalAddress` field names, so JSON-LD generation is lossless."
2356
+ }
2357
+ },
2358
+ "additionalProperties": false
2359
+ }
2360
+ ]
2361
+ },
2362
+ "retention": {
2363
+ "description": "How long personal information is kept, in prose (e.g. \"24 months after last contact\").",
2364
+ "type": "string"
2365
+ },
2366
+ "processors": {
2367
+ "description": "Third parties that receive personal information and cannot be inferred from the rest of the config (payment processors, CRMs, mail senders). Known providers implied by `analytics`, `security` and `deployment` are added automatically — list only the rest.",
2368
+ "type": "array",
2369
+ "items": {
2370
+ "type": "object",
2371
+ "properties": {
2372
+ "name": {
2373
+ "type": "string",
2374
+ "description": "The provider, as a reader would recognise it (e.g. \"Stripe\")."
2375
+ },
2376
+ "purpose": {
2377
+ "type": "string",
2378
+ "description": "Why they receive it, as a noun phrase that reads after \"for\" (e.g. \"payment processing\")."
2379
+ },
2380
+ "country": {
2381
+ "description": "Where they process it, as it should read in a sentence (e.g. \"the United States\"). Feeds the cross-border-transfer disclosure.",
2382
+ "type": "string"
2383
+ },
2384
+ "privacyUrl": {
2385
+ "type": "string",
2386
+ "format": "uri"
2387
+ }
2388
+ },
2389
+ "required": [
2390
+ "name",
2391
+ "purpose"
2392
+ ],
2393
+ "additionalProperties": false
2394
+ }
2257
2395
  }
2258
2396
  },
2259
2397
  "required": [
@@ -2281,6 +2419,10 @@
2281
2419
  "type": "null"
2282
2420
  }
2283
2421
  ]
2422
+ },
2423
+ "governingLaw": {
2424
+ "description": "Governing-law clause, in prose (e.g. \"the Province of Ontario\"). Defaults from the contact address.",
2425
+ "type": "string"
2284
2426
  }
2285
2427
  },
2286
2428
  "required": [