@getvitops/cli 4.0.0 → 5.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.
- package/CHANGELOG.md +389 -0
- package/dist/cli.mjs +1372 -292
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -3
- package/skill/SKILL.md +127 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getvitops/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "CLI for the Vitops design-system generator: generate, init, and validate a design-system.json.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@getvitops/
|
|
26
|
-
"@getvitops/
|
|
25
|
+
"@getvitops/generator": "5.0.0",
|
|
26
|
+
"@getvitops/utils": "5.0.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"vitest": "^4.1.9"
|
package/skill/SKILL.md
CHANGED
|
@@ -22,6 +22,83 @@ colour roles, fluid type/space scales, component patterns, animation effects).
|
|
|
22
22
|
**Core rule:** prefer the framework's utility + component classes over hand-written CSS or
|
|
23
23
|
ad-hoc values — they encode the tokens, respond to dark mode, and update with the system.
|
|
24
24
|
|
|
25
|
+
## Layout foundations — apply these before fetching anything
|
|
26
|
+
|
|
27
|
+
Six classes carry the structure of nearly every page. They are stated here rather than
|
|
28
|
+
left to `vitops docs classes` because the failure mode is not disagreement, it is **not
|
|
29
|
+
knowing there was a decision to make** — writing a container by hand looks like ordinary
|
|
30
|
+
CSS competence, so nothing prompts you to go look. Every row below has been found in real
|
|
31
|
+
downstream sites.
|
|
32
|
+
|
|
33
|
+
| About to write… | Write this instead |
|
|
34
|
+
| ------------------------------------------------------- | ----------------------------------------------- |
|
|
35
|
+
| a `wrap` / `wrapper` / `container` / `inner` class | **`centered`** — never invent a container class |
|
|
36
|
+
| `max-width` + `margin-inline: auto` | **`centered`** |
|
|
37
|
+
| `padding-block` on a section to separate it | **`region`** |
|
|
38
|
+
| margins between headings, paragraphs, lists | **`rhythm`** on the container |
|
|
39
|
+
| `display: grid` + `grid-template-columns: repeat(n, …)` | **`subgrid`** |
|
|
40
|
+
| `repeat(auto-fit, minmax(…))` | **`grid-auto`** (or `subgrid`, below) |
|
|
41
|
+
| `display: flex` + `gap` for a row of buttons/badges | **`cluster`** |
|
|
42
|
+
|
|
43
|
+
**`centered` is not a max-width box, which is why hand-rolling it never quite works.** It is
|
|
44
|
+
a grid of _named tracks_, so a child widens itself (`breakout`, `spotlight`, `fullbleed`)
|
|
45
|
+
without the parent knowing. A bespoke `.wrap` renders identically until the first full-bleed
|
|
46
|
+
image, and then the only way out is more hand-written CSS. There is no case where inventing a
|
|
47
|
+
container class is correct.
|
|
48
|
+
|
|
49
|
+
**More than one card means `subgrid`.** This is the most under-used class in the framework,
|
|
50
|
+
and the reason it gets skipped is that a plain `grid` _looks_ right — it aligns the outer
|
|
51
|
+
boxes. It cannot align the tranches **inside** them, so across three cards the headings sit
|
|
52
|
+
at three heights, the bodies start at three points, and the CTAs float wherever the copy
|
|
53
|
+
ended. `subgrid` re-declares the parent's row tracks on each item so head / body / footer
|
|
54
|
+
share row lines regardless of content length. Write
|
|
55
|
+
`<ul class="subgrid subgrid-cols-3" role="list">` with `<li class="card subgrid-card">` items —
|
|
56
|
+
a set of cards is a list — and set `--subgrid-row-span` (or `subgrid-rows-<n>`) to the number of
|
|
57
|
+
row bands each card holds. In Astro use `<Subgrid />`, which renders the slot verbatim: **author
|
|
58
|
+
the `<li>` items yourself.**
|
|
59
|
+
|
|
60
|
+
**`role="list"` is not optional on a hand-written one.** `subgrid` is markerless on `ul`/`ol`,
|
|
61
|
+
and Safari + VoiceOver stop announcing a marker-less `<ul>` as a list — so the marker reset
|
|
62
|
+
silently costs the semantics the `<ul>` was chosen for. `<Subgrid />` adds it for you.
|
|
63
|
+
|
|
64
|
+
**When the whole card is a link, the card is still the grid item** — and there are two ways to
|
|
65
|
+
do it, both keeping the accessible name on real text rather than on a whole card of it:
|
|
66
|
+
|
|
67
|
+
| Want | Use |
|
|
68
|
+
| ------------------------------------ | ------------------------------------------ |
|
|
69
|
+
| no JS at all | `stretched-link` — **text not selectable** |
|
|
70
|
+
| selectable text and a clickable card | `<Cards>` / `<wc-cards>` — needs JS |
|
|
71
|
+
|
|
72
|
+
- `stretched-link` goes on a link **inside** the card (usually the heading); its `::after`
|
|
73
|
+
covers it. `subgrid-card` already carries the required `position: relative`; on a bare `card`
|
|
74
|
+
add `relative`. Anything else interactive in the card needs **`raised`** — `relative` alone
|
|
75
|
+
does not work, because a positioned element at `z-index: auto` cannot rise above an explicit
|
|
76
|
+
one. The cost is inherent to the technique: the overlay takes the pointer-drag, so the card's
|
|
77
|
+
text can no longer be selected.
|
|
78
|
+
- `<Cards>` wraps the list in `<wc-cards>`, which adds no overlay and instead distinguishes a
|
|
79
|
+
click from the end of a drag. Text stays selectable; with no JS the card's own link still
|
|
80
|
+
works, and the pointer cursor appears only once the element upgrades. It emits its own
|
|
81
|
+
`<wc-cards>` — do not add your own wrapper.
|
|
82
|
+
- **Never layer the two.** The overlay wins, so you lose selection _and_ the JS never runs.
|
|
83
|
+
`vitops lint` reports the combination.
|
|
84
|
+
|
|
85
|
+
`<li><a class="card">` is the wrong shape and **it renders fine**, which is why it keeps being
|
|
86
|
+
written: the `<li>` is the grid item, so the anchor is an ordinary block inside it and the
|
|
87
|
+
tranches within the anchor never reach the parent's shared row lines — the alignment is
|
|
88
|
+
silently absent, and the anchor does not fill the cell either. Putting the anchor in the
|
|
89
|
+
grid's place (`<ul><a></ul>`) is invalid HTML. `vitops lint` reports this shape.
|
|
90
|
+
|
|
91
|
+
The one honest alternative is **`grid-auto`** — an auto-fit track (`--grid-min`, `--grid-gap`)
|
|
92
|
+
for items with **no internal tranches to align**: a gallery, a logo wall, a row of icons. Never
|
|
93
|
+
hand-write `repeat(auto-fit, minmax(…))`; that is `grid-auto`. The moment an item has an
|
|
94
|
+
eyebrow and a heading and a footer, `subgrid` is the one that lines them up.
|
|
95
|
+
|
|
96
|
+
**`vitops lint` reports all six of these**, in CSS, in `<style>` blocks and in markup — a
|
|
97
|
+
hand-rolled container, a repeated-item grid, and a loop that renders cards outside a
|
|
98
|
+
`subgrid`. They report as `suggestion`, so they do not fail the build unless `--strict`.
|
|
99
|
+
Run it before considering a page done; if it names one of these, the fix is the class, not a
|
|
100
|
+
justification for the CSS.
|
|
101
|
+
|
|
25
102
|
## Getting the current reference docs
|
|
26
103
|
|
|
27
104
|
Run **`vitops docs <topic>`** — it prints the reference as markdown to stdout, generated
|
|
@@ -56,7 +133,17 @@ never stale and always names the project's actual tokens. (If `vitops` isn't on
|
|
|
56
133
|
emits no CSS, so it composes: `--format css,design`. The live reference above is
|
|
57
134
|
richer; DESIGN.md is for handing the identity to a tool that doesn't have this skill.
|
|
58
135
|
- `vitops init` / `vitops validate` — scaffold / check a config. `validate` routes on the
|
|
59
|
-
file's shape, so it checks a site config as a site config.
|
|
136
|
+
file's shape, so it checks a site config as a site config. It also resolves every
|
|
137
|
+
`var(--…)` the config authors against the tokens it emits, so a reference to a token
|
|
138
|
+
that does not exist is a build failure rather than a declaration that silently does
|
|
139
|
+
nothing.
|
|
140
|
+
- `vitops lint [--src <dir>] [--fix]` — **run this after a major bump.** It finds
|
|
141
|
+
framework classes and design-system tokens in your source that resolve to nothing, and
|
|
142
|
+
it is the migration tool for anything the changelog says was renamed. `--fix` rewrites
|
|
143
|
+
pre-1.0 colour-grammar token references in one pass (several of those renames rotate, so
|
|
144
|
+
applying them one at a time compounds them); everything else it reports needs a decision
|
|
145
|
+
and is left alone.
|
|
146
|
+
- Every subcommand takes `-h` / `--help`.
|
|
60
147
|
|
|
61
148
|
**The config may be a `design-system.json` or the site config that embeds one.** Every
|
|
62
149
|
`--input` (and the Vite plugin / Astro integration equivalent) accepts either; a site
|
|
@@ -66,10 +153,15 @@ there — do not create a second file for the tooling's sake.
|
|
|
66
153
|
|
|
67
154
|
## Which tier provides a pattern
|
|
68
155
|
|
|
69
|
-
A pattern (tree, carousel, dialog, card, …) may be provided by up to
|
|
70
|
-
**compose** rather than compete: CSS framework classes, a `<wc-*>` web component,
|
|
71
|
-
|
|
72
|
-
tiers each pattern has, and the
|
|
156
|
+
A pattern (tree, carousel, dialog, card, …) may be provided by up to **three tiers**, and they
|
|
157
|
+
**compose** rather than compete: (1) CSS framework classes, (2) a `<wc-*>` web component,
|
|
158
|
+
(3) a platform wrapper that generates the markup — an Astro component or a Bricks element.
|
|
159
|
+
**Run `vitops docs components`** for the full table — which tiers each pattern has, and the
|
|
160
|
+
exact call to write.
|
|
161
|
+
|
|
162
|
+
**Astro and Bricks are the same tier, not tiers 3 and 4.** Both are HTML generators built on
|
|
163
|
+
the classes and elements of tiers 1 and 2 — siblings chosen by which platform you are on. No
|
|
164
|
+
project uses both, and neither outranks the other.
|
|
73
165
|
|
|
74
166
|
Three things to know before you write markup:
|
|
75
167
|
|
|
@@ -83,6 +175,30 @@ Three things to know before you write markup:
|
|
|
83
175
|
HTML is the no-JS fallback and must be semantic and usable on its own. If you find yourself
|
|
84
176
|
wanting a component that renders from nothing, that pattern is in the wrong tier.
|
|
85
177
|
|
|
178
|
+
## Astro rendering mode
|
|
179
|
+
|
|
180
|
+
Nothing vitops emits needs a server — the CSS, favicons and web-component bundles are
|
|
181
|
+
build-time artifacts, and the components progressively enhance markup that is already
|
|
182
|
+
complete in the HTML. So the default is static, and the rule differs by project kind:
|
|
183
|
+
|
|
184
|
+
- **A plain Astro site:** keep `output: 'static'` and add `export const prerender = false`
|
|
185
|
+
only on the individual routes that genuinely need per-request work (a form `POST` handler,
|
|
186
|
+
an auth-gated page, per-visitor content). Don't switch the whole site to `output: 'server'`
|
|
187
|
+
for a couple of dynamic routes.
|
|
188
|
+
- **An EmDash site:** `output: 'server'` is required (the admin, media/API routes, preview
|
|
189
|
+
and scheduled publishing all need a server), so prerendering is opt-in per route. Put
|
|
190
|
+
`export const prerender = true` on every page that doesn't need per-request data, and give
|
|
191
|
+
dynamic routes (`[slug].astro`, `[...slug].astro`) a `getStaticPaths()` that queries the
|
|
192
|
+
collection at build time. A route with no `prerender` export is re-rendered on every
|
|
193
|
+
request.
|
|
194
|
+
|
|
195
|
+
A prerendered page reflects the database as of the last build, so publishing from the admin
|
|
196
|
+
needs a redeploy to appear. Leave a route server-rendered only where that is unacceptable —
|
|
197
|
+
the preview route, anything personalised, anything that must go live within seconds.
|
|
198
|
+
|
|
199
|
+
Note `@astrojs/sitemap` lists prerendered routes only, so an unmarked route on a server site
|
|
200
|
+
is also missing from the sitemap. (EmDash serves its own sitemap from the database.)
|
|
201
|
+
|
|
86
202
|
## Fonts: vitops names them, it does not load them
|
|
87
203
|
|
|
88
204
|
`design-system.json`'s `fonts` block holds **stacks only** — each entry emits a
|
|
@@ -123,7 +239,12 @@ where no provider covers the family.
|
|
|
123
239
|
collect, the countries it names come from the providers in use. So the fix for a wrong
|
|
124
240
|
policy is a corrected config, never hand-editing the output — the next build overwrites
|
|
125
241
|
it. Declare processors the config cannot imply (payment, CRM, mail) under
|
|
126
|
-
`legal.privacyPolicy.processors`.
|
|
242
|
+
`legal.privacyPolicy.processors`. On each one, **where it stores data and whose law reaches
|
|
243
|
+
it are separate facts**: `storage: [{ country, scope? }]` is residency, `operatorCountry` is
|
|
244
|
+
the jurisdiction that can compel access, and `country` is shorthand for both — so a Canadian
|
|
245
|
+
region run by a US company is `storage: [{ country: "Canada" }]` with
|
|
246
|
+
`operatorCountry: "the United States"`, not one string. Combining `country` with either is
|
|
247
|
+
rejected.
|
|
127
248
|
Generated from config, not legal advice — always tell the user to have it reviewed
|
|
128
249
|
before publishing.
|
|
129
250
|
- `vitops search notify` — tell search engines a deploy happened, from a **site config**'s
|