@getvitops/cli 3.0.0 → 4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getvitops/cli",
3
- "version": "3.0.0",
3
+ "version": "4.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/generator": "3.0.0",
26
- "@getvitops/utils": "3.0.0"
25
+ "@getvitops/utils": "4.0.0",
26
+ "@getvitops/generator": "4.0.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "vitest": "^4.1.9"
package/skill/SKILL.md CHANGED
@@ -1,12 +1,16 @@
1
1
  ---
2
2
  name: vitops-design-system
3
3
  description: >-
4
- Work with this project's Vitops design system. Use when styling or authoring
5
- pages or components (choosing utility/pattern classes, colours, spacing,
6
- typography), when editing design-system.json (tokens, palette, patterns,
7
- scales, animations), when generating output (vitops generate --format
8
- tailwind|css|bricks), or when asking what the design system provides on a
9
- given platform (Tailwind vs Bricks vs standalone CSS).
4
+ Work with this project's Vitops design system and site toolchain. Use when
5
+ styling or authoring pages or components (choosing utility/pattern classes,
6
+ colours, spacing, typography), when editing design-system.json (tokens,
7
+ palette, patterns, scales, animations), when generating output (vitops
8
+ generate --format tailwind|css|bricks), when asking what the design system
9
+ provides on a given platform (Tailwind vs Bricks vs standalone CSS), and when
10
+ touching the site subsystems it generates or gates: the cookie-consent banner
11
+ and gating third-party tags, ad-click attribution and conversion
12
+ notifications, the generated privacy policy / terms / cookie notice, and
13
+ Google Search Console onboarding or post-deploy indexing.
10
14
  ---
11
15
 
12
16
  # Vitops design system
@@ -25,17 +29,22 @@ live from this project's `design-system.json` and the installed package version,
25
29
  never stale and always names the project's actual tokens. (If `vitops` isn't on PATH, use
26
30
  `pnpm exec vitops docs <topic>` or `npx vitops docs <topic>`.)
27
31
 
28
- | Run | When you need |
29
- | ----------------------- | ---------------------------------------------------------------------- |
30
- | `vitops docs classes` | which class to apply — the full class vocabulary as naming rules |
31
- | `vitops docs authoring` | what a `design-system.json` field means / what's valid |
32
- | `vitops docs config` | the three-section config: `designSystem` / `organization` / `site` |
33
- | `vitops docs formats` | tailwind vs css vs bricks output — incl. which utilities Tailwind owns |
34
- | `vitops docs color` | how the colour system works (seeded OKLCH scales, roles, dark mode) |
35
- | `vitops docs scales` | how the fluid type/space scales work |
36
- | `vitops docs patterns` | how pattern CSS is assembled (token cascade, override hooks, states) |
37
- | `vitops docs icons` | semantic icon names across sets, bundle derivation, sprite delivery |
38
- | `vitops docs elements` | the custom Bricks Builder elements and their controls |
32
+ | Run | When you need |
33
+ | ------------------------ | ---------------------------------------------------------------------- |
34
+ | `vitops docs classes` | which class to apply — the full class vocabulary as naming rules |
35
+ | `vitops docs authoring` | what a `design-system.json` field means / what's valid |
36
+ | `vitops docs config` | the three-section config: `designSystem` / `organization` / `site` |
37
+ | `vitops docs formats` | tailwind vs css vs bricks output — incl. which utilities Tailwind owns |
38
+ | `vitops docs color` | how the colour system works (seeded OKLCH scales, roles, dark mode) |
39
+ | `vitops docs scales` | how the fluid type/space scales work |
40
+ | `vitops docs patterns` | how pattern CSS is assembled (token cascade, override hooks, states) |
41
+ | `vitops docs components` | which tier provides a pattern (classes / `wc-*` / Astro / Bricks) |
42
+ | `vitops docs icons` | semantic icon names across sets, bundle derivation, sprite delivery |
43
+ | `vitops docs consent` | the consent gate — gating a tag, demand-driven prompting, the API |
44
+ | `vitops docs tracking` | ad-click attribution, the `_ac` cookie, conversion notifications |
45
+ | `vitops docs search` | what search engines accept, Search Console onboarding + notification |
46
+ | `vitops docs legal` | how the policy / terms / cookie notice derive from config facts |
47
+ | `vitops docs elements` | the custom Bricks Builder elements and their controls |
39
48
 
40
49
  `vitops docs` (no topic) lists the topics; `vitops docs --all` prints everything.
41
50
 
@@ -55,6 +64,25 @@ config holds the design system at `designSystem.themes.<name>`, selected with `-
55
64
  If this project keeps its tokens inside a `company.json` / `site.json`, point `--input`
56
65
  there — do not create a second file for the tooling's sake.
57
66
 
67
+ ## Which tier provides a pattern
68
+
69
+ A pattern (tree, carousel, dialog, card, …) may be provided by up to four tiers, and they
70
+ **compose** rather than compete: CSS framework classes, a `<wc-*>` web component, an Astro
71
+ component, a Bricks element. **Run `vitops docs components`** for the full table — which
72
+ tiers each pattern has, and the exact call to write.
73
+
74
+ Three things to know before you write markup:
75
+
76
+ - **Prefer the highest tier your stack has, and write only its call.** In Astro that is the
77
+ Astro component; in Bricks the element; anywhere else the classes plus the `<wc-*>` tag if
78
+ one exists. Hand-writing markup a component already emits is the common miss.
79
+ - **Do not compose two tiers yourself.** Where an Astro component wraps a web component it
80
+ emits that tag _with the accessible fallback inside_, so `<wc-tree><Tree /></wc-tree>`
81
+ nests two elements on one tree. The doc records which components wrap a tag.
82
+ - **A `<wc-*>` element enhances markup you supply; it never renders from empty.** The slotted
83
+ HTML is the no-JS fallback and must be semantic and usable on its own. If you find yourself
84
+ wanting a component that renders from nothing, that pattern is in the wrong tier.
85
+
58
86
  ## Fonts: vitops names them, it does not load them
59
87
 
60
88
  `design-system.json`'s `fonts` block holds **stacks only** — each entry emits a
@@ -98,7 +126,7 @@ where no provider covers the family.
98
126
  `legal.privacyPolicy.processors`.
99
127
  Generated from config, not legal advice — always tell the user to have it reviewed
100
128
  before publishing.
101
- - `vitops indexing` — tell search engines a deploy happened, from a **site config**'s
129
+ - `vitops search notify` — tell search engines a deploy happened, from a **site config**'s
102
130
  `seo.indexing` block. Run `--dry` first: it prints the full plan and makes no requests.
103
131
  **Be accurate about what this does, because the obvious assumption is wrong.** Google
104
132
  has no API that requests indexing — the Search Console button is not exposed anywhere,
@@ -114,6 +142,65 @@ where no provider covers the family.
114
142
  between runs or every run submits everything. Google's **Indexing API is deliberately
115
143
  not wired**: it is scoped to `JobPosting`/`BroadcastEvent`, and using it for ordinary
116
144
  pages violates its terms — don't suggest it as a workaround.
145
+ - `vitops search setup` — onboard the domains in a **site config**'s `site.searchConsole`
146
+ block into Google Search Console as domain properties. For each domain it ensures the
147
+ apex verification TXT in Cloudflare, verifies ownership (DNS_TXT, retried with backoff
148
+ while DNS propagates — a still-unverified domain is reported PENDING, not failed), adds
149
+ the `sc-domain:` property, and adds any `delegatedOwners` to the web resource. Idempotent:
150
+ a re-run of an onboarded domain is a no-op, and `--check` reports drift without mutating.
151
+ DNS is only ever created, never edited or deleted. Credentials come from the environment
152
+ (`CLOUDFLARE_API_TOKEN`, and `VITOPS_GOOGLE_CLIENT_ID`/`_CLIENT_SECRET`/`_REFRESH_TOKEN`),
153
+ never the config. Granting a Google Group **Full-User** access has no API — it is surfaced
154
+ as a reminder, not automated; don't tell a user the tool did it.
117
155
  - `vitops agents` — (re-)link this skill into `.agents/skills/` + `.claude/skills/` and
118
156
  refresh the AGENTS.md pointer block. The links point into the installed package and
119
157
  survive version bumps; re-run only if they were deleted.
158
+
159
+ ## Consent and third-party tags
160
+
161
+ If the site has a consent gate, **every** non-essential third party goes through it. Run
162
+ `vitops docs consent` before wiring one up — the failure modes here are silent and legal.
163
+ The four that bite:
164
+
165
+ - **A gated tag must render inert.** `type="text/plain"` + `data-consent="<category>"` +
166
+ the URL on `data-src` (never `src`), plus `data-consent-cookies` naming what it sets so
167
+ a revoke can clear them. Given a live `src` the browser fetches the library immediately
168
+ and the gate is decorative — an undecided visitor's page must issue **no** third-party
169
+ request.
170
+ - **Use `require()`, not `granted()`, when you want permission.** `granted()` is passive:
171
+ it never raises the banner, so on a site where nothing else demands that category it is a
172
+ **permanent silent no-op** and your write never happens. `require()` registers the demand,
173
+ which is what makes the banner appear. `request()` is the promise form.
174
+ - **No `window.vitopsConsent` means the site has no gate — store freely.** It does not mean
175
+ denied. (A synchronous stub in `<head>` covers the window before the runtime loads, so
176
+ absence is reliable. Listen for the `vitops:consent` event rather than calling
177
+ `subscribe()`, which the stub lacks.)
178
+ - **Patch exactly the categories you put on screen.** `acceptAll()` / `rejectAll()` mean
179
+ literally every optional category — using one to answer a single-category prompt records
180
+ consent nobody gave. "Not asked" is a third value (`null`), distinct from declined, and
181
+ only it can be re-prompted.
182
+
183
+ The banner is **demand-driven**: it appears when something actually asks, not on first visit.
184
+ A site whose only analytics provider is cookieless never interrupts anyone. Don't "fix" a
185
+ missing banner by forcing it to show — find out what should have demanded a category.
186
+
187
+ Whatever loads must match what the **generated cookie notice** discloses; the Astro
188
+ integration warns when they disagree, and that is a compliance defect, not a doc nit.
189
+
190
+ ## Conversion tracking
191
+
192
+ `vitops docs tracking`. `site.tracking.enabled` captures ad click IDs and UTMs from the
193
+ landing URL into the first-party `_ac` cookie; a conversion route reads it back and notifies
194
+ via `site.notifications`. Points worth holding:
195
+
196
+ - `_ac` is a 90-day identifier, so it waits on `marketing` (or `site.tracking.category`) and
197
+ the capture **`require()`s** it — see above.
198
+ - Only an arrival actually carrying a click ID or UTM asks; organic visitors are never
199
+ interrupted.
200
+ - The read is synchronous and the _write_ is what waits — the click ID exists only in the
201
+ landing URL, so it cannot be deferred.
202
+ - Only the `email` channel (Cloudflare Email Sending) is implemented. Its sending domain must
203
+ be onboarded with `wrangler email sending enable <domain>` or every send fails; the tool
204
+ surfaces that error verbatim rather than as "send failed".
205
+ - `--dry`-style planning is pure and reports **why** anything was skipped. A silently unsent
206
+ notification is indistinguishable from no conversion, so never leave one unexplained.