@getvitops/create 0.6.0 → 0.8.0-alpha.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 (35) hide show
  1. package/CHANGELOG.md +178 -5
  2. package/package.json +2 -2
  3. package/templates/emdash/.agents/skills/setup/SKILL.md +61 -0
  4. package/templates/emdash/.astro/types.d.ts +3 -0
  5. package/templates/emdash/.github/workflows/deploy-prod.yml +1 -1
  6. package/templates/emdash/AGENTS.md +19 -11
  7. package/templates/emdash/README.md +45 -42
  8. package/templates/emdash/SETUP.html +576 -0
  9. package/templates/emdash/_gitignore +3 -0
  10. package/templates/emdash/astro.config.mjs +33 -3
  11. package/templates/emdash/package.json +14 -9
  12. package/templates/emdash/seed/seed.json +1 -1
  13. package/templates/emdash/site.json +303 -0
  14. package/templates/emdash/src/layouts/Layout.astro +7 -1
  15. package/templates/emdash/src/pages/404.astro +5 -0
  16. package/templates/emdash/src/pages/[...slug].astro +7 -0
  17. package/templates/emdash/src/pages/index.astro +7 -0
  18. package/templates/emdash/vite.config.ts +19 -5
  19. package/templates/emdash/wrangler.jsonc +8 -3
  20. package/templates/static/.agents/skills/setup/SKILL.md +61 -0
  21. package/templates/static/.github/workflows/deploy-prod.yml +1 -1
  22. package/templates/static/AGENTS.md +14 -7
  23. package/templates/static/README.md +15 -20
  24. package/templates/static/SETUP.html +576 -0
  25. package/templates/static/_gitignore +3 -0
  26. package/templates/static/astro.config.mjs +5 -1
  27. package/templates/static/package.json +8 -6
  28. package/templates/static/site.json +228 -0
  29. package/templates/static/src/pages/index.astro +2 -2
  30. package/templates/static/wrangler.jsonc +10 -3
  31. package/templates/emdash/design-system.json +0 -148
  32. package/templates/emdash/scripts/init-github.mjs +0 -186
  33. package/templates/emdash/scripts/init-hosting.mjs +0 -150
  34. package/templates/static/scripts/init-github.mjs +0 -186
  35. package/templates/static/scripts/init-hosting.mjs +0 -62
package/CHANGELOG.md CHANGED
@@ -1,5 +1,178 @@
1
1
  # @getvitops/create
2
2
 
3
+ ## 0.8.0-alpha.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c3c1bcb: **New: the design-system editor, mounted inside the EmDash admin.** `vitopsEmdash({
8
+ designSystemEditor: { config } })` (`config` is your `site.json`, e.g. `import config from
9
+ './site.json' with { type: 'json' }`) adds a `/design-system` admin page mounting
10
+ `<wc-theme-editor>` — the same live token editor `@getvitops/vite`'s dev server has always
11
+ offered, now usable by the client directly, no dev server required. An edit is visible
12
+ site-wide immediately (a runtime `:root` override, served via a new plugin API route and
13
+ `page:fragments`) and — once `site.deployment.repo`/`branch` and a `VITOPS_GITHUB_TOKEN`
14
+ secret are set (see the scaffold's `SETUP.html`) — auto-commits to your `dev` branch, so it
15
+ reaches the git-tracked `site.json` through your repo's normal review path rather than
16
+ becoming a second, unreviewed source of truth. Until that's configured, the live half still
17
+ works; only the auto-commit half is skipped (and says so in the admin page). The save route
18
+ runs the exact same accessibility (APCA contrast) gate `generate()` enforces at build time,
19
+ synchronously, before persisting — nothing non-compliant ever goes live even momentarily.
20
+
21
+ Requires `@astrojs/react` + `react` + `react-dom` (already scaffold dependencies, for
22
+ EmDash's own admin) and `@getvitops/core` (added as a new scaffold dependency this release).
23
+ Declares two new plugin capabilities when enabled: `network:request` (for the GitHub
24
+ auto-commit) and `hooks.page-fragments:register` (for the live override) — reviewed once at
25
+ plugin-install time.
26
+
27
+ **Breaking for `@getvitops/emdash`**: `vitopsEmdash()`'s `hooks.page-fragments:register`
28
+ capability is now also granted whenever `designSystemEditor` is set, independent of the
29
+ existing `scripts: 'fragments'` option (which governs something unrelated — web-component
30
+ script delivery). No change if you don't use `designSystemEditor`.
31
+
32
+ Also new, supporting the above:
33
+ - `@getvitops/generator`: `validateColorContract()` and `buildReverseIndex()` (both
34
+ `/tokens` subpath, Worker-safe) — the monotonicity/contrast gate and the
35
+ `design-manifest.json` reverse-index, each extracted from `generate()`'s `build()` into
36
+ standalone, non-throwing functions. `patchToOverrideCss()` turns a design-system patch
37
+ into the `:root` override `<style>` block. `designSystemPath`/`getAt`/`setAt`/
38
+ `mergePatch`/`formatConfig` moved from `@getvitops/vite` into `@getvitops/generator/config`
39
+ (re-exported from `@getvitops/vite` unchanged) — one "patch a config file's design-system
40
+ subtree" implementation shared by the dev endpoint and the new plugin route. New
41
+ `site.deployment.repo`/`branch` config fields.
42
+ - `@getvitops/utils`: new `/git` subpath — `commitFile()`, a Worker-safe (fetch-only)
43
+ wrapper over GitHub's Contents API.
44
+ - `@getvitops/core`: `<wc-theme-editor>` gains a `save-endpoint` attribute (default
45
+ unchanged — `/__vitops/design-system`) so the same element can target the new plugin
46
+ route instead of the dev-only Vite endpoint.
47
+
48
+ ### Patch Changes
49
+
50
+ - 0574388: Add `vitops email setup|check` — connect `site.notifications.email.from` to whether its domain is
51
+ actually onboarded onto an outbound email provider.
52
+
53
+ Before this, nothing checked that. `EMAIL.send()` throws `E_SENDER_NOT_VERIFIED` at runtime with no
54
+ build or deploy-time warning — the failure mode is silent and production-only.
55
+
56
+ `vitops email setup [domain]` onboards a sending domain (currently Cloudflare Email Sending only)
57
+ and polls DNS until its SPF/DKIM/DMARC records resolve or a timeout is reached; `vitops email
58
+ check` is the non-blocking deploy guard both `@getvitops/create` templates' `deploy`/`deploy:dev`
59
+ scripts now run first (`--strict` makes it a real gate; opt out per-site with
60
+ `site.notifications.email.verifySender: false`, or globally with `--skip` /
61
+ `VITOPS_SKIP_EMAIL_CHECK`).
62
+
63
+ Two things worth knowing before running it:
64
+ - **The onboarded entity is an exact name, and it is usually a subdomain**
65
+ (`send.yourdomain.com`), never the apex your `from` address names. When the exact domain isn't
66
+ onboarded but a sibling in the same zone already is, the command reports that as the fix — send
67
+ from the onboarded subdomain — rather than silently trying to onboard the apex, which rewrites
68
+ `_dmarc.<domain>` and can tighten DMARC policy on every other mail your domain sends.
69
+ - Candidates come from `site.notifications.email.from` (or its derived `noreply@<domains
70
+ .canonical>` default) first; a best-effort scan of `--src` only supplements it, and never guesses
71
+ at a computed `from` value.
72
+
73
+ New `@getvitops/utils/email` subpath and `site.notifications.email.verifySender` config field.
74
+ Needs `CLOUDFLARE_API_TOKEN` with an Email Sending scope in addition to the `Zone:Read` other
75
+ commands already use.
76
+
77
+ - 0574388: Bump `emdash`/`@emdash-cms/cloudflare` peers to `>=1.0.0 <2` and `vite-plus` to `^1.0.0`, following
78
+ both projects' GA releases.
79
+
80
+ **Breaking for `@getvitops/emdash` consumers on EmDash 0.x**: the peer range no longer admits
81
+ `emdash@0.31.x`/`@emdash-cms/cloudflare@0.31.x`. Upgrade `emdash` and `@emdash-cms/cloudflare` to
82
+ `^1.0.1` first — nothing in `@getvitops/emdash`'s own plugin surface (`admin.portableTextBlocks`,
83
+ the `hooks.page-fragments:register` capability, `definePlugin()`) changed against EmDash 1.0, so no
84
+ code here needed to change, only the declared range.
85
+
86
+ The `emdash` scaffold template (`vp create @getvitops:emdash`) picks up several fixes alongside
87
+ the version bump:
88
+ - `tailwindcss`/`@tailwindcss/vite` are now real dependencies — the template selected
89
+ `css.format: 'tailwind'` without installing either, which threw on build.
90
+ - `site.json` now sets `site.icons.sprite: true` plus the full `semantic` list the
91
+ `vitops.actionLink` block's icon picker offers — previously its sprite icons pointed at a file
92
+ the build never generated.
93
+ - `astro.config.mjs` sets `migrations: { runtime: 'check', dev: 'auto' }`, and
94
+ `site-deploy-emdash.yml` runs EmDash 1.0's documented `build → status → apply → deploy → check`
95
+ migration sequence explicitly, rather than relying solely on first-request auto-migration. This
96
+ needs a new GitHub Environment variable, `EMDASH_TARGET_FINGERPRINT` (one per environment),
97
+ which only a human can set — run `emdash migrate --status` against the real deployed database,
98
+ review the printed identity, then `gh variable set EMDASH_TARGET_FINGERPRINT --env <env> --body
99
+ <value>`. Deploys fail clearly on the migration-apply step until it's set.
100
+ - `lint.options.typeAware`/`typeCheck` in the template's own `vite.config.ts` are commented out,
101
+ not deleted: vite-plus 1.0 only honours that option in a project's actual root config, and hard
102
+ errors on it in a nested one (which this file is, sitting inside the `design-system` monorepo).
103
+ Uncomment it once scaffolded into its own repo.
104
+
105
+ No config schema changes. `@getvitops/generator` also switches from the `zod/mini` subpath import
106
+ to the standalone `@zod/mini` package (zod 4.5+; same API) and fixes `validateConfig()` silently
107
+ losing the offending key name on an `unrecognized_keys` error (e.g. a typo'd `site.ads` platform
108
+ now names the bad key instead of reporting a bare "Invalid input").
109
+
110
+ Also fixed: `vp check`'s `tsconfig-error` for `packages/create/templates/emdash/tsconfig.json`
111
+ (`extends: "astro/tsconfigs/strict"`, unresolvable from inside this monorepo since the template
112
+ has no `node_modules` of its own — a pre-existing, structural gap, newly surfaced as a hard error
113
+ by oxlint 1.85's deeper config discovery, and blocking on every commit since this repo's pre-commit
114
+ hook runs `vp check --fix`). Fixed with a new `scripts/link-template-deps.mjs`, wired as the root
115
+ `postinstall` script: symlinks `astro`/`emdash`/`@emdash-cms/cloudflare` into the template's own
116
+ `node_modules/` (resolved fresh from sibling packages that already depend on them for real, not a
117
+ hardcoded `.pnpm` hash) and writes a minimal `astro:content` ambient shim at `.astro/types.d.ts`
118
+ (the same path `astro sync` would generate for real). Both are gitignored and only ever exist
119
+ inside this monorepo's copy of the template — a real scaffold installs its own real copies instead.
120
+ Considered and rejected first: inlining astro's strict preset (drift risk against astro's own
121
+ evolving default) and making the template a real pnpm workspace member (would change how its
122
+ `@getvitops/*: "latest"` deps resolve locally, which `templates.test.ts` exists to protect).
123
+
124
+ **Known gap, not fixed here**: `packages/astro/src/components/container.test.ts` (the
125
+ `AstroContainer`-based render tests) fails to even load under vite-plus 1.0's Vite 8 — direct
126
+ `.astro` imports in a Vitest file need the Astro Vite plugin registered, which nothing in this
127
+ repo's test config actually does (Astro's own docs call for `getViteConfig()`, which doesn't
128
+ compose with vite-plus's own `defineConfig`). A type-level shim
129
+ (`packages/astro/src/components/astro-modules.d.ts`) fixes `vp check`'s type-aware pass, but the
130
+ runtime `vp test` failure for this one file is still open.
131
+
132
+ - 0f8c018: **New: `resolveOrganizationName(config, locale?)`**, exported from `@getvitops/astro/routes`
133
+ alongside `toNotifyContext`/`toCrmConfig` — the same `organization.name` → `legalName` →
134
+ `undefined` fallback chain `toNotifyContext` already used for its `organizationName` field,
135
+ now usable standalone anywhere a build-time-only display name is needed (favicon generation,
136
+ a scaffold's `astro.config.mjs`, a `Layout.astro` fallback). `toNotifyContext` is unchanged —
137
+ it now delegates to this helper internally.
138
+
139
+ The emdash scaffold uses it to remove a three-way duplicated `'My EmDash Site'` string:
140
+ `astro.config.mjs`'s favicon `name` and `Layout.astro`'s title fallback both previously
141
+ hardcoded it independently of `site.json`'s `organization.name`. EmDash's own
142
+ `getSiteSettings().title` (set in the admin) still wins at render time when it's set — it's a
143
+ runtime-only fact that can't be read at build time at all — this only replaces the two
144
+ hardcoded _fallback_ strings.
145
+
146
+ ## 0.7.0
147
+
148
+ ### Minor Changes
149
+
150
+ - **Breaking (for scaffolds) — both templates now ship `site.json` instead of `design-system.json`.**
151
+
152
+ `design-system.json` is deleted from the `static` and `emdash` templates; its contents move under
153
+ `designSystem.themes.default` inside a new `site.json` (the umbrella `Config`), because a
154
+ scaffolded config can't merely reference a sibling design-system file — `ConfigSchema` requires
155
+ `designSystem` and there is no file-level `extends`. `astro.config.mjs`'s `css.input` (and
156
+ `site.input`, for emdash) now point at `site.json`; so do the `build:css`/`lint:design` scripts.
157
+
158
+ **Migration** for a project already scaffolded from an older version of this template: create
159
+ `site.json` with your existing `design-system.json`'s content under
160
+ `designSystem.themes.default`, delete `design-system.json`, and update `css.input`/`site.input` in
161
+ `astro.config.mjs`. Not reachable by `vitops lint --fix` — this is the whole migration.
162
+
163
+ Also new in both templates:
164
+ - **`SETUP.html`** — a client-onboarding checklist (styled entirely with the framework's own
165
+ classes, checkbox state in `localStorage`), generated a stylesheet for via the new
166
+ `pnpm run sop` script.
167
+ - **`.agents/skills/setup/SKILL.md`** — lets an AI agent work the same checklist autonomously,
168
+ stopping only at the steps that genuinely need a human (the Cloudflare API token, the
169
+ domain cutover, publishing generated legal documents).
170
+ - `scripts/init-github.mjs` and `scripts/init-hosting.mjs` are deleted; `pnpm run init:github` /
171
+ `init:hosting` / the new `setup` script now call `vitops setup repo` / `vitops setup hosting`
172
+ (from `@getvitops/cli`, requires the `minor` release in the same batch as this one) instead of
173
+ a template-local script, so the same capability now reaches any existing project, not just a
174
+ fresh scaffold.
175
+
3
176
  ## 0.6.0
4
177
 
5
178
  ### Minor Changes
@@ -235,15 +408,15 @@
235
408
  which `@getvitops/astro` re-exports wholesale. So from `astro.config.mjs`:
236
409
 
237
410
  ```js
238
- import { generateIconInclude } from "@getvitops/astro";
239
- import icon from "astro-icon";
411
+ import { generateIconInclude } from '@getvitops/astro';
412
+ import icon from 'astro-icon';
240
413
 
241
414
  integrations: [
242
415
  icon({
243
416
  include: generateIconInclude({
244
- ui: "fa7-solid",
245
- brand: "simple-icons",
246
- semantic: ["menu", "close", "search", "github"],
417
+ ui: 'fa7-solid',
418
+ brand: 'simple-icons',
419
+ semantic: ['menu', 'close', 'search', 'github'],
247
420
  }),
248
421
  }),
249
422
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getvitops/create",
3
- "version": "0.6.0",
3
+ "version": "0.8.0-alpha.0",
4
4
  "description": "Project templates for the Vitops design system — scaffold wired-up sites with `vp create @getvitops`.",
5
5
  "homepage": "https://docs.vitops.ca",
6
6
  "bugs": "https://github.com/getvitops/design-system/issues",
@@ -19,7 +19,7 @@
19
19
  "access": "public"
20
20
  },
21
21
  "devDependencies": {
22
- "vitest": "4.1.9"
22
+ "@getvitops/generator": "8.2.0-alpha.0"
23
23
  },
24
24
  "engines": {
25
25
  "node": ">=24"
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: setup
3
+ description: Work the client-onboarding checklist (SETUP.html) autonomously — GitHub repo + branch policy, hosting resources, Search Console/GCP/ads connections. Use when the user asks to set up, onboard, or provision this project (e.g. "run setup", "onboard this site", "get this ready to deploy"). Never run this as a side effect of unrelated work, and never on your own initiative without the user asking.
4
+ ---
5
+
6
+ # Setup (client onboarding)
7
+
8
+ `SETUP.html` is the canonical checklist — this skill adds only sequencing,
9
+ gates, and where to stop. It does not restate the steps; read `SETUP.html`
10
+ (or `npx vitops setup --help`) for what each stage actually does and why.
11
+
12
+ ## Steps
13
+
14
+ 1. **Preview the whole sequence first.**
15
+
16
+ ```bash
17
+ npx vitops setup all --dry
18
+ ```
19
+
20
+ Read the plan before doing anything. It names every step it would take and
21
+ why any step is blocked — a missing credential, a field not yet in
22
+ `site.json`, GitHub Pro/Team gating branch protection.
23
+
24
+ 2. **Run it.**
25
+
26
+ ```bash
27
+ npx vitops setup all
28
+ ```
29
+
30
+ Re-run `npx vitops setup --check` after each leg rather than retrying on
31
+ your own judgment — a step already done resolves to a no-op skip, so a
32
+ second run is safe, and `--check` tells you exactly what still needs doing
33
+ instead of you guessing from output.
34
+
35
+ 3. **Tick `SETUP.html` boxes only for what you actually completed.** Never
36
+ check a box for a step marked below as human-only, even if you did
37
+ everything up to it — the human still has to act.
38
+
39
+ ## Hard stops — ask the human, do not attempt
40
+
41
+ - **The Cloudflare API token.** No API can create one; there is no command to
42
+ run. Tell the user to create it at
43
+ <https://dash.cloudflare.com/profile/api-tokens> (Workers + D1 + R2 edit)
44
+ and run `gh secret set CLOUDFLARE_API_TOKEN`, then continue.
45
+ - **The domain cutover** (`vitops setup domain`, stage 4b in `SETUP.html`).
46
+ Uncommenting the custom-domain route and deploying overwrites the zone's DNS
47
+ record at that instant — it takes an existing live site down. `setup domain`
48
+ only ever plans and checks this; it never applies it, and neither should
49
+ you. Report the plan and hand the actual cutover to the user.
50
+ - **Publishing any generated legal document.** `vitops legal` renders a
51
+ starting point from the config, not a reviewed policy. Generate it, tell the
52
+ user it needs review, and stop — do not paste it into the admin or commit it
53
+ yourself.
54
+
55
+ ## If something is blocked
56
+
57
+ `vitops setup --check` names the field or credential and where to get it —
58
+ report that verbatim rather than guessing at a fix. A step reported as
59
+ "blocked" is not a failure to retry; it is waiting on one of the hard stops
60
+ above, or on a `site.json` field the user still needs to fill in (stage 5,
61
+ Configuration).
@@ -0,0 +1,3 @@
1
+ declare module 'astro:content' {
2
+ export function defineLiveCollection(config: unknown): unknown;
3
+ }
@@ -1,7 +1,7 @@
1
1
  # Deploys `main` to production.
2
2
  # `main` should be branch-protected — it then only advances via the Promote
3
3
  # workflow (promote.yml), so a push here always represents promoted code. The
4
- # `production` GitHub Environment (set up by `scripts/init-github.mjs`) has
4
+ # `production` GitHub Environment (set up by `vitops setup repo`) has
5
5
  # required reviewers restricted to admins, so this PAUSES for approval before
6
6
  # deploying.
7
7
  #
@@ -3,10 +3,14 @@ styled by the Vitops design system.
3
3
 
4
4
  ## Ground rules
5
5
 
6
- - `design-system.json` is the single source of truth for the design system
7
- (colors, type, spacing, patterns, animations). Never edit
8
- `src/styles/tailwind.css` — it is generated from the JSON by the
9
- `vitops()` integration on every dev/build and is gitignored.
6
+ - `site.json` is the single source of truth — organization + site facts, and
7
+ the design system (colors, type, spacing, patterns, animations) under
8
+ `designSystem.themes.default`. Never edit `src/styles/tailwind.css` — it is
9
+ generated from `site.json` by the `vitops()` integration on every dev/build
10
+ and is gitignored. (There is no separate `design-system.json`: a scaffolded
11
+ config can't merely reference a sibling file, so the token set lives inside
12
+ `site.json` — see `AGENTS.md`'s "Client onboarding" section in the toolchain
13
+ repo for why.)
10
14
  - `src/assets/placeholder/` holds neutral wireframe stand-ins (square,
11
15
  portrait, landscape; SVG + PNG) for layout work before real imagery
12
16
  exists. Delete the directory once real assets land — it's separate from
@@ -74,6 +78,10 @@ styled by the Vitops design system.
74
78
  d1/r2/sqlite there. Switch targets via `vitopsHosting({ target })` or the
75
79
  `HOSTING` env var (see README "Hosting"); the `node` target needs
76
80
  `@astrojs/node` + `better-sqlite3` installed first.
81
+ - **`SETUP.html` is the client-onboarding checklist.** When working it via the
82
+ `.agents/skills/setup/` skill, tick a box only for a step you actually
83
+ completed — never on the operator's behalf for a step marked human-only
84
+ (the Cloudflare API token, the domain cutover, publishing legal documents).
77
85
 
78
86
  ## Branch model
79
87
 
@@ -90,12 +98,12 @@ styled by the Vitops design system.
90
98
  and obviously unfinished; do not "improve" them into something that reads as
91
99
  a finished policy, because the risk here is a plausible-looking document
92
100
  getting shipped unread.
93
- To replace them properly, write a site config and run
94
- `npx vitops legal --format portable-text --out ./legal`, then paste each
95
- document's blocks into the page in the admin. That renders a real policy from
96
- what the site actually does — the analytics provider it uses, the fields its
97
- forms collect, where it deploys — rather than from guesses. It still needs
98
- review before launch.
101
+ To replace them properly, fill in `site.json`'s `organization`/`site.legal`
102
+ fields and run `npx vitops legal --format portable-text --out ./legal`, then
103
+ paste each document's blocks into the page in the admin. That renders a real
104
+ policy from what the site actually does — the analytics provider it uses,
105
+ the fields its forms collect, where it deploys — rather than from guesses.
106
+ It still needs review before launch.
99
107
 
100
108
  ## Docs MCP servers
101
109
 
@@ -112,4 +120,4 @@ searching them over pre-trained knowledge for Astro/EmDash questions.
112
120
  dev default). Only run when the user asks to set up GitHub.
113
121
  - `pnpm run init:hosting` — one-time: provision the hosting platform (dev
114
122
  D1/R2 + repo secrets on cloudflare). Only run when the user asks for it.
115
- - `npx vitops validate design-system.json` — schema-check the design config
123
+ - `npx vitops validate site.json` — schema-check the site config
@@ -10,9 +10,9 @@ Scaffolded from `vp create @getvitops:emdash`.
10
10
  - **Astro** (SSR) on **Cloudflare Workers** — D1 database, R2 media storage
11
11
  - **EmDash** — the admin lives at `/_emdash/admin`; content is queried with
12
12
  `getEmDashCollection` / `getEmDashEntry` (Astro live content collections)
13
- - **`@getvitops/astro`** — generates the design-system CSS from
14
- `design-system.json` (Tailwind v4 format), generates favicons/PWA assets
15
- from `src/assets/logo.svg`, and serves the web-component runtime
13
+ - **`@getvitops/astro`** — generates the design-system CSS from `site.json`
14
+ (Tailwind v4 format), generates favicons/PWA assets from
15
+ `src/assets/logo.svg`, and serves the web-component runtime
16
16
  - **`@getvitops/emdash`** — design-system Portable Text blocks in the editor
17
17
  slash menu: image compare, copy snippet, banner, disclosure, carousel
18
18
 
@@ -27,6 +27,11 @@ pnpm install
27
27
  pnpm dev
28
28
  ```
29
29
 
30
+ Once this is its own repo (not sitting inside the `getvitops/design-system`
31
+ monorepo), uncomment `lint.options` in `vite.config.ts` for type-aware
32
+ `vp check`/`vp lint` — it ships commented out because vite-plus 1.0 only
33
+ honours that option at a project's actual root, and errors on it otherwise.
34
+
30
35
  No Cloudflare account needed: `astro dev` runs the Worker locally with local
31
36
  D1/R2 emulation (state in `.wrangler/`). On first boot EmDash runs its
32
37
  migrations and applies the structure from `seed/seed.json` — a `pages`
@@ -42,7 +47,7 @@ Until then the home route shows a friendly empty state. Unknown paths render
42
47
  `src/pages/404.astro`.
43
48
 
44
49
  The two legal pages are placeholders. To generate real ones from what your site
45
- actually does, describe it in a site config and run:
50
+ actually does, fill in `site.json`'s `organization`/`site.legal` fields and run:
46
51
 
47
52
  ```sh
48
53
  npx vitops legal --format portable-text --out ./legal
@@ -82,22 +87,18 @@ The repo ships a two-environment flow modeled on branch = environment:
82
87
  into `main` with auto-merge enabled. With required reviews on `main`, a
83
88
  human approves the PR; merging deploys prod.
84
89
 
85
- One-time setup:
86
-
87
- 1. `pnpm run init:github` — creates a GitHub repo named after this project
88
- (via the `gh` CLI; `-- --public` for a public repo), commits if needed,
89
- pushes `main` + `dev`, and makes `dev` the default branch. Idempotent;
90
- `-- --dry-run` previews. Then branch-protect `main` (require the promotion
91
- PR + review).
92
- 2. `pnpm run init:hosting` — provisions the hosting platform (after
93
- `npx wrangler login`): creates the isolated dev D1 + R2 and sets the
94
- `DEV_D1_ID` / `CLOUDFLARE_ACCOUNT_ID` repo secrets. Idempotent;
95
- `-- --dry-run` previews.
96
- 3. Create a Cloudflare API token (Workers + D1 + R2 edit —
97
- <https://dash.cloudflare.com/profile/api-tokens>; tokens can't be created
98
- via CLI) and `gh secret set CLOUDFLARE_API_TOKEN`. Optionally
99
- `PROMOTE_TOKEN` (a PAT allowed to bypass protection) for hands-off
100
- promotion. The first workflow runs fail until the secrets exist.
90
+ One-time setup — work through the checklist:
91
+
92
+ ```bash
93
+ pnpm run sop && open SETUP.html # or: xdg-open SETUP.html
94
+ ```
95
+
96
+ It covers host choice, GitHub + branch policy, hosting resources, going live
97
+ safely on `*.workers.dev` before any custom-domain cutover, configuration,
98
+ Search Console/GCP/ads connections, legal documents, and launch gates — one
99
+ command per step. An AI agent can work the same list autonomously via
100
+ `.agents/skills/setup/`; it stops at the steps that genuinely need a human
101
+ (the Cloudflare API token, the domain cutover, publishing legal documents).
101
102
 
102
103
  `pnpm deploy:dev` reproduces the dev deploy locally: it rewrites the
103
104
  adapter-generated wrangler config (`scripts/build-dev-wrangler.mjs`) so the
@@ -146,8 +147,10 @@ and media in the storage backend (bucket/directory copy).
146
147
 
147
148
  ## The design system
148
149
 
149
- `design-system.json` is the single source of truth for colors, type, spacing,
150
- shadows, patterns, and animations. The `vitops()` integration regenerates
150
+ `site.json`'s `designSystem.themes.default` is the single source of truth for
151
+ colors, type, spacing, shadows, patterns, and animations — there is no
152
+ separate `design-system.json`, since a scaffolded config can't merely
153
+ reference a sibling file. The `vitops()` integration regenerates
151
154
  `src/styles/tailwind.css` from it on dev/build (the file is gitignored — edit
152
155
  the JSON, not the CSS). `Layout.astro` imports the stylesheet so the admin
153
156
  routes stay unstyled by it.
@@ -155,27 +158,27 @@ routes stay unstyled by it.
155
158
  Useful commands (via `@getvitops/cli`):
156
159
 
157
160
  ```bash
158
- npx vitops validate design-system.json # check the config against the schema
159
- npx vitops agents # write the design-system reference into AGENTS.md
160
- pnpm build:css # regenerate the CSS manually
161
+ npx vitops validate site.json # check the config against the schema
162
+ npx vitops agents # write the design-system reference into AGENTS.md
163
+ pnpm build:css # regenerate the CSS manually
161
164
  ```
162
165
 
163
166
  ## Project map
164
167
 
165
- | Path | Purpose |
166
- | -------------------------------- | ----------------------------------------------------------------- |
167
- | `design-system.json` | Design tokens + patterns → generated CSS |
168
- | `seed/seed.json` | First-boot content model + starter content |
169
- | `src/worker.ts` | Worker entry (fetch + EmDash scheduled handler) |
170
- | `src/live.config.ts` | Astro live content collections wiring for EmDash |
171
- | `src/layouts/Layout.astro` | Site chrome: EmDash + Vitops head tags, nav from the CMS menu |
172
- | `src/pages/index.astro` | Home — renders the `home` page entry |
173
- | `src/pages/[...slug].astro` | Catch-all — renders any `pages` entry at its slug |
174
- | `src/pages/404.astro` | Not-found page (the catch-all rewrites here) |
175
- | `wrangler.jsonc` | Cloudflare bindings (D1/R2) + cron trigger |
176
- | `scripts/build-dev-wrangler.mjs` | Rewrites the built wrangler config for the isolated dev worker |
177
- | `scripts/init-github.mjs` | One-time: create + push the GitHub repo (`pnpm run init:github`) |
178
- | `.github/workflows/` | deploy-dev (push to `dev`), deploy-prod (push to `main`), promote |
179
- | `.agents/skills/promote/` | Agent skill: dispatch the dev → main promotion |
180
- | `.mcp.json` | Astro + EmDash docs MCP servers for coding agents |
181
- | `.claude/hooks/` | Claude Code web: Node 24 + pnpm setup on session start |
168
+ | Path | Purpose |
169
+ | -------------------------------- | ------------------------------------------------------------------------------------------ |
170
+ | `site.json` | Org + site config; design tokens/patterns at `designSystem.themes.default` → generated CSS |
171
+ | `seed/seed.json` | First-boot content model + starter content |
172
+ | `src/worker.ts` | Worker entry (fetch + EmDash scheduled handler) |
173
+ | `src/live.config.ts` | Astro live content collections wiring for EmDash |
174
+ | `src/layouts/Layout.astro` | Site chrome: EmDash + Vitops head tags, nav from the CMS menu |
175
+ | `src/pages/index.astro` | Home — renders the `home` page entry |
176
+ | `src/pages/[...slug].astro` | Catch-all — renders any `pages` entry at its slug |
177
+ | `src/pages/404.astro` | Not-found page (the catch-all rewrites here) |
178
+ | `wrangler.jsonc` | Cloudflare bindings (D1/R2) + cron trigger |
179
+ | `scripts/build-dev-wrangler.mjs` | Rewrites the built wrangler config for the isolated dev worker |
180
+ | `SETUP.html` | Client-onboarding checklist — run `pnpm run sop` first (see "One-time setup") |
181
+ | `.github/workflows/` | deploy-dev (push to `dev`), deploy-prod (push to `main`), promote |
182
+ | `.agents/skills/promote/` | Agent skill: dispatch the dev → main promotion |
183
+ | `.mcp.json` | Astro + EmDash docs MCP servers for coding agents |
184
+ | `.claude/hooks/` | Claude Code web: Node 24 + pnpm setup on session start |