@tryvitris/website-harness 0.1.0-beta.7 → 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 (75) hide show
  1. package/README.md +49 -117
  2. package/agent/graph.yaml +12 -6
  3. package/agent/refs/admin.md +11 -0
  4. package/agent/refs/analytics.md +17 -0
  5. package/agent/refs/launch.md +15 -11
  6. package/agent/refs/performance.md +1 -1
  7. package/bin/api/agent/evaluate.js +5 -5
  8. package/bin/api/agent/grade.js +5 -5
  9. package/bin/api/cli/api.js +15 -13
  10. package/bin/api/cli.js +15 -15
  11. package/bin/api/engine.js +6 -6
  12. package/bin/api/hosting.js +9 -7
  13. package/bin/api/index.js +2 -2
  14. package/bin/api/render.js +1 -1
  15. package/bin/chunks/{chunk-ZIROO2U4.js → chunk-37F7XIMH.js} +4 -3
  16. package/bin/chunks/{chunk-TTAUU3AZ.js → chunk-3OKR5AZJ.js} +1 -1
  17. package/bin/chunks/{chunk-PGFFKPK6.js → chunk-A2XMAPVW.js} +2 -2
  18. package/bin/chunks/{chunk-O55LAQ2C.js → chunk-FGSQE3DU.js} +2 -2
  19. package/bin/chunks/{chunk-VTI32UGJ.js → chunk-H3BS2EBR.js} +2 -2
  20. package/bin/chunks/{chunk-DSS2U2OM.js → chunk-KVMZSQ3D.js} +8 -2
  21. package/bin/chunks/{chunk-4MFPATAB.js → chunk-L44ZTNDM.js} +12 -5
  22. package/bin/chunks/{chunk-7V3OKLKH.js → chunk-LZC37OJZ.js} +4 -4
  23. package/bin/chunks/{chunk-5YSPWKFF.js → chunk-PYCRUMCT.js} +1 -1
  24. package/bin/chunks/{chunk-QRWGFLUU.js → chunk-R2WRQDVE.js} +2 -2
  25. package/bin/chunks/{chunk-YZWEXHT4.js → chunk-SEMH6MCV.js} +129 -21
  26. package/bin/chunks/{chunk-H7Y72HXC.js → chunk-UFTVWTEZ.js} +26 -7
  27. package/bin/chunks/{chunk-P56ZDMX7.js → chunk-WMJVLMU2.js} +16 -4
  28. package/bin/chunks/{chunk-FRABKM65.js → chunk-XY73ZLHB.js} +12 -9
  29. package/bin/chunks/{chunk-ZWFG4GPG.js → chunk-YXJAQYDE.js} +69 -53
  30. package/bin/chunks/{design-context-store-DCZOAK56.js → design-context-store-W3VTZ4HA.js} +5 -5
  31. package/bin/chunks/{packets-QOLWPRNV.js → packets-LBMDIFPO.js} +5 -5
  32. package/bin/chunks/{preparation-T2IOD5SJ.js → preparation-AV4PDQY6.js} +5 -5
  33. package/bin/chunks/{template-gallery-ET76ERZQ.js → template-gallery-H2SVYNRD.js} +1 -1
  34. package/bin/cloudflare/backend.js +144 -62
  35. package/bin/types/src/admin/connection.d.ts +3 -0
  36. package/bin/types/src/cli/admin.d.ts +21 -0
  37. package/bin/types/src/cli/api.d.ts +1 -1
  38. package/bin/types/src/cli/deploy.d.ts +2 -0
  39. package/bin/types/src/cli/doctor.d.ts +1 -0
  40. package/bin/types/src/cli/site-create.d.ts +2 -0
  41. package/bin/types/src/compile/site.d.ts +1 -1
  42. package/bin/types/src/integrations/hosting.d.ts +2 -0
  43. package/bin/vitris-art.js +5 -5
  44. package/bin/vitris-build.js +3 -3
  45. package/bin/vitris-create-site.js +9 -7
  46. package/bin/vitris-cursor-hook.js +5 -5
  47. package/bin/vitris-eval.js +7 -7
  48. package/bin/vitris-go.js +7 -7
  49. package/bin/vitris-harvest.js +6 -6
  50. package/bin/vitris-knowledge.js +6 -6
  51. package/bin/vitris-launch-preflight.js +5 -5
  52. package/bin/vitris-motion-view.js +5 -5
  53. package/bin/vitris-references.js +3 -3
  54. package/bin/vitris-refresh.js +6 -6
  55. package/bin/vitris-stock.js +1 -1
  56. package/bin/vitris-templates.js +1 -1
  57. package/bin/vitris-themes.js +5 -5
  58. package/bin/vitris-upgrade.js +6 -6
  59. package/bin/vitris-verify-browser.js +5 -5
  60. package/bin/vitris-verify-performance.js +3 -3
  61. package/bin/vitris.js +15 -15
  62. package/docs/ADMIN.md +85 -0
  63. package/docs/CLI.md +14 -6
  64. package/docs/CLOUDFLARE.md +27 -2
  65. package/docs/DISTRIBUTION.md +5 -3
  66. package/docs/ENGINE.md +6 -0
  67. package/docs/PRESERVE.md +1 -1
  68. package/docs/SECURITY.md +2 -2
  69. package/package.json +28 -23
  70. package/templates/site/AGENTS.md +4 -2
  71. package/templates/site/README.md +8 -3
  72. package/templates/site/deployment/README.md +24 -0
  73. package/templates/site/{.github/workflows/deploy.yml → deployment/github-actions.yml.example} +5 -6
  74. package/templates/site/gitignore +3 -0
  75. package/templates/site/package.json +3 -1
package/README.md CHANGED
@@ -1,142 +1,74 @@
1
- # Vitris
1
+ # Vitrus Website Harness
2
2
 
3
- Vitris gives your coding agent the business context, design judgment, and verification process to build distinctive websites on a consistent technical foundation.
3
+ Vitrus Website Harness gives a coding agent the context, design guidance, and checks to build distinctive websites. It includes a static site compiler, a template library, media tools, and an optional Cloudflare backend for leads, analytics, and owner administration. Each website lives in its own repository.
4
4
 
5
- This repository produces **`@tryvitris/website-harness`**, an agent harness for building and verifying customer websites. It includes a static site compiler, design tokens, an optional Cloudflare backend for owner admin, leads, and analytics, harvest tools, and an agent kit. Each customer website is a separate git repo started from `templates/site`. Normal generation stops at a verified local preview. Cloudflare launch is a separate explicit operation. Built-in design lessons live in `design-system/knowledge/v1` and do not require a user reference.
5
+ The package is [`@tryvitris/website-harness`](https://www.npmjs.com/package/@tryvitris/website-harness). Bring your own coding agent and Node.js 24 or newer. Generation normally ends with a verified local preview; Cloudflare launch is a separate, explicit step.
6
6
 
7
- Sites own their visual components and adapt the selected template direction to their content.
7
+ ## Create a website
8
8
 
9
- The default template gallery is `artifacts/templates/gallery.html`. Run `npm run templates:gallery` and open `http://127.0.0.1:4390/`. It displays the live Cloudflare library and automatically includes future publications. Publish complete new demonstrations with `npm run templates -- publish --bundle ABSOLUTE_TRANSIENT_DIRECTORY`; see `agent/refs/template-library.md`. Source fixtures contain original Vitris instructional material; external demonstrations remain hosted with their own provenance records.
10
-
11
- MIT licensed. The public npm package is `@tryvitris/website-harness`; prerelease `0.1.0-beta.7` is available through the `beta` and `latest` dist-tags. Bring your own coding agent. Optional hosting uses your own Cloudflare account; see [Cloudflare setup](docs/CLOUDFLARE.md) and [credential safety](docs/SECURITY.md).
12
-
13
- Requires Node 24 or newer. Hosted demonstrations and third-party media have their own license records; see NOTICE.
14
-
15
- The npm package contains the bundled JavaScript CLI and APIs, TypeScript declarations, starter templates, agent kit, and required runtime assets. The complete TypeScript development source and tests are in the [GitHub repository](https://github.com/jackperrotta/vitris-harness).
16
-
17
- ## Start a client website
18
-
19
- Each client gets an independent site directory and Git repository. **That client directory is where you open your coding agent and build the website.** This source repository maintains the reusable harness, compiler, knowledge, media catalog, and optional backend.
20
-
21
- To use a local checkout, build and pack it, then generate a site:
9
+ An optional separate business admin is available through `vitris admin setup|status|verify`; new-site `--admin` prepares follow-up instructions. See the [admin integration guide](docs/ADMIN.md) for pinned packages, local plan/apply, backend grants and the separate customer-account Cloudflare rollout.
22
10
 
23
11
  ```bash
24
- npm ci
25
- npm pack
26
- node bin/vitris.js site create --dir ../acme --slug acme --name "Acme Shop" --from https://old-site.example --harness ../vitris-harness/tryvitris-website-harness-0.1.0-beta.7.tgz
27
- cd ../acme
12
+ npx --package @tryvitris/website-harness@1.0.0 vitris site create \
13
+ --dir acme --slug acme --name "Acme Shop" \
14
+ --from https://old-site.example --template "Still & Field" \
15
+ --content-file ./acme-notes.md
16
+ cd acme
28
17
  npm install
29
18
  npx playwright install chromium
30
- npm run go
31
- ```
32
-
33
- The tarball path is relative to the generated site directory. Adjust it for your directory layout. Open the **acme directory** in your coding agent and follow `AGENTS.md` and `agent/CURRENT.md`. Commit its generated lockfile with the client source. Before using the client repo on another computer, switch the dependency to a published version or distribute the tarball with it.
34
-
35
- The public beta starter command is:
36
-
37
- ```bash
38
- npx --package @tryvitris/website-harness@0.1.0-beta.7 vitris site create --dir acme --slug acme --from https://old-site.example
39
19
  ```
40
20
 
41
- Use `--blank` when there is no existing website. New sites pin the creating harness version. `--harness file:../vitris-harness` explicitly opts into local development; run `npm run build:cli` in that checkout first. Jev is optional and off by default. Backend and Cloudflare credentials are not required to author and preview a static site locally.
21
+ Replace the example values with your own. Use `--blank` instead of `--from` for a new site. `--template` accepts a catalog ID, name, or hosted preview URL; `--content` accepts supplied text directly. Both are optional. See the [CLI guide](docs/CLI.md) for input and media policies.
42
22
 
43
- See [distribution and migration](docs/DISTRIBUTION.md) for existing clients and release preparation. Cloudflare hosting is configured and deployed separately from installing the npm package.
23
+ Open the **site directory** in your coding agent and ask it to build the site. It follows the site's `AGENTS.md` and the prepare → `agent/CURRENT.md` → work → complete loop until the local preview is ready. To start or resume manually, use `npm run go`; for a later change, use `npm run go -- --change "Describe the change"`.
44
24
 
45
- ## Local demo
25
+ To browse templates from a harness checkout, run `npm ci`, then `npm run templates:gallery` and open <http://127.0.0.1:4390/>. The gallery loads the hosted catalog. See the [template library guide](agent/refs/template-library.md) for creating and publishing templates.
46
26
 
47
- ```bash
48
- cp .dev.vars.example .dev.vars
49
- npm install
50
- npm run catalog
51
- npm run build:demo
52
- npm run dev
53
- ```
27
+ ## Built-in skills
54
28
 
55
- Then:
29
+ The harness loads stage-specific instructions from [`agent/refs/`](agent/refs/) automatically. These are not installed agent slash commands: describe the work to your agent, and the workflow selects the relevant guidance. The creative workflow also has the following named skills; their prerequisites are included when needed.
56
30
 
57
- - Backend home: http://127.0.0.1:8787/
58
- - Fixture build: `dist/demo/` (from `src/test/fixtures/site`)
59
- - Owner admin: http://127.0.0.1:8787/app/login — `owner@demo.test`
60
- - Operator: http://127.0.0.1:8787/ops — `ops@demo.test`
31
+ | Skill | What it does |
32
+ | --- | --- |
33
+ | `business-positioning` | Ground the offer and distinguishing value in business evidence. |
34
+ | `narrative` | Organize the visitor journey, questions, and supporting proof. |
35
+ | `visual-research` | Adapt useful principles from visual references. |
36
+ | `art-direction` | Turn the central idea into a coherent visual direction. |
37
+ | `typography` | Establish readable, expressive type hierarchy. |
38
+ | `composition` | Shape page layout, rhythm, and visual priority. |
39
+ | `media-direction` | Select authentic imagery and identify media gaps. |
40
+ | `copy-layout` | Develop page copy and layout together. |
41
+ | `purposeful-interaction` | Choose interactions that help visitors act or decide. |
42
+ | `responsive-design` | Preserve hierarchy and usable controls across screen sizes. |
43
+ | `visual-critique` | Identify consequential visual weaknesses in rendered pages. |
44
+ | `visitor-journey` | Test whether visitors can complete intended tasks. |
45
+ | `motion-direction` | Plan useful movement and quiet intervals. |
46
+ | `motion-page` | Compose motion across each page's journey. |
47
+ | `motion-statistics` | Present supplied numbers accessibly, with motion where useful. |
48
+ | `motion-phrases` | Pace text without hiding essential copy. |
49
+ | `motion-choreography` | Coordinate imagery, captions, and process accents. |
61
50
 
62
- `/preview/{slug}/` requires an owner/operator session and opens the tenant’s **GitHub** `pages/` + `components/` on its own preview hostname. Hosted previews require `PREVIEW_HOST_SUFFIX`, `github_owner` / `github_repo` and `GITHUB_TOKEN`; see [Cloudflare setup](docs/CLOUDFLARE.md). Local CLI previews need none of these.
51
+ For example, ask your agent to “improve the mobile layout,” “review the visitor journey,” or “adapt this template to the business.” The workflow includes additional guidance for template adaptation, copy, accessibility, SEO, browser checks, and launch. See the [workflow guide](agent/WORKFLOW.md) and [creative skill registry](src/agent/creative-skills.ts).
63
52
 
64
- `DEV_LOGIN=1` skips email and seeds demo users only on local loopback or `.localhost` requests. The deployable Wrangler config does not set it. Production sign-in requires email delivery and the authentication D1 migration; production never displays sign-in links or creates demo accounts.
53
+ ## Develop the harness
65
54
 
66
- ## Site source layout
67
-
68
- ```
69
- pages/index.html → /
70
- pages/about.html → /about
71
- components/hero/… reusable layout + slots
72
- site.json name, slug, motion
73
- theme/defaults.json brand tokens
74
- agent/ workflow graph, stage prompt, evals, refs
75
- launch.json backend + Cloudflare contract (no secrets)
76
- ```
77
-
78
- Authoring tags like `<hero>…</hero>` flatten at build time. Copy for a page lives in that page’s HTML; shared chrome lives inside `components/header` and `components/footer`.
79
-
80
- ## New customer site
55
+ Customer sites build and verify locally, then upload the exact finished bundle directly to Cloudflare Pages. Use `npm run deploy:preview` for a hosted preview and `npm run deploy` for explicitly requested production publication. GitHub stores source; hosted deployment automation is opt-in. See [Cloudflare setup](docs/CLOUDFLARE.md) for new sites and migration of existing sites.
81
56
 
82
57
  ```bash
83
- node --experimental-strip-types scripts/create-site.ts \
84
- --dir ../acme --slug acme --name "Acme Shop" \
85
- --from https://old-site.example \
86
- --owner owner@acme.example --harness file:../vitris-harness
58
+ npm ci
59
+ npx playwright install chromium
60
+ npm run typecheck
61
+ npm test
62
+ npm run verify:package
87
63
  ```
88
64
 
89
- That scaffolds the site folder with the agent kit and records the old URL. **Open the site repo** and say **go** (or `npm run go`). The active-agent workflow walks:
90
-
91
- `harvest → business + review → media → narrative + review → reference analysis → direction + review → storyboard → copy + review → representative + browser + reviews → copy expansion → pages → browser → visual + content reviews → preview`
92
-
93
- Default stop is local `dist/` preview (`preview_ready`). Cloudflare / GitHub launch is an optional later node.
94
-
95
- See [AGENTS.md](AGENTS.md) and `agent/PROMPT.md`.
96
-
97
- ## How site updates work
98
-
99
- Owners file tickets at `/app/requests` (or email). You:
100
-
101
- 1. Open `/ops/inbox`
102
- 2. Copy the ticket into Cursor **in that client’s site repo**
103
- 3. Follow `AGENTS.md` (reuse preview eval after edits)
104
- 4. Push an `update/…` branch so Pages builds a preview
105
- 5. Paste the preview URL on the ticket and email the client
106
- 6. Merge to `main` when they approve
107
-
108
- Git is the source of truth. Register `github_owner` / `github_repo` / `pages_project` on the tenant in `/ops`.
109
-
110
- ## Stack rules
111
-
112
- No React/Vue/Svelte, no Hono, no Tailwind, no ORM. Components compile to flat HTML/CSS plus optional tiny islands (no Shadow DOM). Lead forms POST to the backend `/api/leads`.
113
-
114
- ## Analytics
115
-
116
- Public sites ship first-party `beacon.js`. Cookie preference page is backend-owned at `/cookie-compliance`.
117
-
118
- ## Workflow graph
119
-
120
- See [operator guide](agent/WORKFLOW.md) for theme requests, adapters, retry budgets and safe kit refresh, and [evaluation protocol](agent/EVALUATION.md) for frozen baselines and operator preference labels.
121
-
122
- Run `npx playwright install chromium` once before `npm test`; the workflow regressions include actual browser rendering and crawl resumption. `npm run typecheck` checks the TypeScript surface. `npm run preview -- --site CLIENT_DIRECTORY` serves a built client site locally.
123
-
124
- ## Verified publication
125
-
126
- The local production preflight builds the site, runs Chromium checks, and binds the report to every publishable byte in `dist/`. For a Worker-managed Pages tenant, protected CI signs that exact bundle with `vitris-sign-publish-bundle`; the Worker route `/api/publish-attested` authenticates the signature, checks tenant/project identity, freshness, and the current policy, then uploads the verified files through the Cloudflare Pages assets and deployments API. Set the same long random `VITRIS_PUBLISH_ATTESTATION_SECRET` in protected CI and `PUBLISH_ATTESTATION_SECRET` on the Worker. Keep the Cloudflare token in the Worker; do not pass it to the site bundle. The generated site workflow shows the signing and POST commands. A rejected request returns before deployment or preview storage mutation.
127
-
128
- The local preflight and mocked Cloudflare publication tests are engineering checks; the live Pages API path still needs an authorized deployment to validate Cloudflare credentials and project settings.
129
-
130
- ## Jev semantic assistance
131
-
132
- Jev defaults to off. `--jev-mode off` on `vitris-go`, `vitris resume`, or `vitris refine` makes no model transport requests. Shadow records bounded task results without placing them in the active agent prompt. Assist adds advisory observations to selected stages; it cannot waive factual, browser, or review requirements. The semantic tasks run only where their inputs are relevant, through the configured Jev client, budgets, and usage receipts. Lesson ranking judges each selected candidate separately. Direction continuity runs during visual review, after page authoring, using affected pages and shared components; oversized evidence is reported unavailable. Use a mock endpoint for local checks unless paid usage is explicitly authorized.
133
-
134
- ## Official-test baseline
135
-
136
- `npm run test:freeze` verifies source, tests and a packed installation, then creates a hashed source/package baseline under `artifacts/official-test/`. The active-agent trial driver supports `--prepare-only`, `--resume` and `--status`; unfinished stages stay pending. See [the official test protocol](docs/OFFICIAL-TEST.md). Historical `scratch/` experiments remain local archives and are excluded from source tracking and packages.
65
+ For a local checkout, run `npm run build:cli` and create a sibling site with `--harness file:../vitris-harness`. See [distribution](docs/DISTRIBUTION.md) for package and upgrade details, and [official testing](docs/OFFICIAL-TEST.md) for frozen baselines.
137
66
 
138
- ## Media library
67
+ ## More information
139
68
 
140
- See [Stock and customer media](docs/STOCK-MEDIA.md) for inspected stock retrieval, customer identity preservation, local imports, and Jev classification/selection. `npm run stock -- --help` lists the staged acquisition and explicit publication commands.
69
+ - [Active-agent quickstart](docs/QUICKSTART.md) and [workflow guide](agent/WORKFLOW.md)
70
+ - [Cloudflare setup](docs/CLOUDFLARE.md), [contact forms](docs/CONTACT-FORMS.md), and [credential safety](docs/SECURITY.md)
71
+ - [Stock and customer media](docs/STOCK-MEDIA.md) and [icon guide](agent/refs/icons.md)
72
+ - [Evaluation protocol](agent/EVALUATION.md) and [CLI reference](docs/CLI.md)
141
73
 
142
- Original SVG icons are included at build time. Use paired `<vitris-icon name="phone"></vitris-icon>` tags in pages or components; each route receives only the icons it uses, without an icon font or browser runtime. Explore with `npm run icons:gallery`, discover with `vitris-icons search QUERY`, and inspect supported styles and sizing with `vitris-icons inspect NAME --json`. The collection contains 381 symbols, four core styles, and five studio families for a curated 24-symbol selection. See [the icon guide](agent/refs/icons.md).
74
+ MIT licensed. Hosted demonstrations and third-party media have their own license records; see [NOTICE](NOTICE).
package/agent/graph.yaml CHANGED
@@ -267,7 +267,8 @@
267
267
  "seo",
268
268
  "media",
269
269
  "motion",
270
- "icons"
270
+ "icons",
271
+ "analytics"
271
272
  ],
272
273
  "optionalRefs": [
273
274
  "design-synthesis",
@@ -365,7 +366,8 @@
365
366
  "usability",
366
367
  "media",
367
368
  "motion",
368
- "icons"
369
+ "icons",
370
+ "analytics"
369
371
  ],
370
372
  "tools": [],
371
373
  "eval": "representative",
@@ -411,7 +413,8 @@
411
413
  "refs": [
412
414
  "browser",
413
415
  "motion",
414
- "icons"
416
+ "icons",
417
+ "analytics"
415
418
  ],
416
419
  "tools": [],
417
420
  "eval": "representative-browser",
@@ -562,7 +565,8 @@
562
565
  "accessibility",
563
566
  "performance",
564
567
  "motion",
565
- "icons"
568
+ "icons",
569
+ "analytics"
566
570
  ],
567
571
  "optionalRefs": [
568
572
  "design-synthesis",
@@ -605,7 +609,8 @@
605
609
  "refs": [
606
610
  "browser",
607
611
  "motion",
608
- "icons"
612
+ "icons",
613
+ "analytics"
609
614
  ],
610
615
  "tools": [],
611
616
  "eval": "browser",
@@ -738,7 +743,8 @@
738
743
  "launch.json"
739
744
  ],
740
745
  "refs": [
741
- "launch"
746
+ "launch",
747
+ "analytics"
742
748
  ],
743
749
  "tools": [],
744
750
  "eval": "launch",
@@ -0,0 +1,11 @@
1
+ # Optional business admin
2
+
3
+ Only prepare an admin when requested or when the operator opts in with site creation `--admin`. Continue the website's prepare → CURRENT → work → complete workflow and verified local-preview stop. Admin rollout does not bypass website consent or release gates.
4
+
5
+ Read the installed harness's `docs/ADMIN.md` and the published admin's packaged `agent/WORKFLOW.md`, `agent/refs/harness.md`, and `agent/refs/cloudflare.md`. Use the pinned **0.1.0-alpha.1** release. Run `vitris admin setup --site WEBSITE --dir SIBLING_ADMIN --domain admin.customer-domain.com --website HTTPS_SITE_ORIGIN --tenant EXISTING_TENANT_ID --backend-origin HTTPS_BACKEND --plan`. Review `artifacts/admin/setup-plan.json`, then repeat with `--apply` and a dedicated environment `VITRIS_ADMIN_API_TOKEN`. Reuse the published installer; never reproduce it or silently overwrite an installation.
6
+
7
+ Setup is local scaffolding and public connection metadata only. Preserve forms, origins, tenants, existing accounts/records, authored source and workflow progress. Never infer compatibility from scaffolding: an older deployed backend needs its own reviewed API upgrade. `vitris admin status` is local metadata; `vitris admin verify --site WEBSITE --dir ADMIN` checks deployed identity and authoritative reads with the dedicated credential, without printing records. Failures must remain visible, with no demo fallback.
8
+
9
+ Default scopes: leads:read and analytics:read. Add --lead-write to both setup commands only for explicit status-write authorization. Prepare a complete hashed grant map with `vitris admin grant`; preserve unrelated grants. Store only SHA-256 in backend ADMIN_CONNECTIONS, and upload the raw token to the admin as HARNESS_API_TOKEN through secret stdin. Never commit configuration or credentials.
10
+
11
+ Prepare explicit, separate customer-account provisioning, D1 migrations, owner bootstrap, Cloudflare Email Service onboarding, authentication, DNS/TLS and deployment steps. Never deploy/migrate a shared backend as a side effect. Sites without collection need an explicitly provisioned backend and separately reviewed form/analytics activation; they have no historical data to import. Production demo login is forbidden. Test submissions and notification captures remain isolated and read-only; preview traffic is excluded from analytics. Clearly label synthetic fixtures and stub services. Pages, Media, page builders and arbitrary HTML editing remain outside scope.
@@ -0,0 +1,17 @@
1
+ # Built-in analytics and delivery
2
+
3
+ Read this when planning calls to action, implementing pages, checking browser behavior, or launching a site. The harness already owns tracking; do not add a second analytics SDK to components or islands.
4
+
5
+ ## Configure and use
6
+
7
+ - `launch.json.backendOrigin` connects the optional Vitris backend. Compilation adds one deferred first-party beacon and the generated `/cookie-compliance` preference page. Without a backend, neither is emitted. A backend must be provisioned and the site's hostname registered before real collection works; compiling a URL alone does not provision it.
8
+ - The beacon records pageviews, referrer/UTM source and medium, session/device/channel summaries, elapsed time and maximum scroll depth, navigation/button/image/carousel engagement, and telephone, email and map clicks. Use actual `tel:`/`mailto:` links, readable labels, semantic navigation, and the built-in components. Engagement is bounded to 25 events per page; live presence uses a 15-second timer while visible and permitted by the current preference.
9
+ - Successful lead conversions are recorded by the server after acceptance. Use registered `launch.json.forms` bindings and the shared `data-lead-form` runtime; see the installed `docs/CONTACT-FORMS.md`. Never count a submit click or a mocked browser response as a real accepted lead. Never send field values, message contents or other customer details to analytics.
10
+ - Optional `launch.json.webAnalyticsToken` is the public 32-character hexadecimal Cloudflare Web Analytics token. It adds a separate deferred field-performance beacon on production pages; preview builds omit it. Use either Cloudflare dashboard injection or this manual hook, avoiding duplicate collection. This hook does not create an account resource or establish field results without visitor data.
11
+ - The preference page and banner are owned by the first-party beacon. Preserve Accept/Reject controls and GPC/DNT handling. Reject clears the visitor cookie and stops presence pings; cookieless measurement can remain. Do not describe the existing implementation as sending no requests after Reject. Hosted `/preview/SLUG` traffic is tagged separately; do not claim a production analytics result from local mocks or previews.
12
+
13
+ ## Compile only what the route uses
14
+
15
+ Read `motion.md` and its selected recipes for the motion library, `icons.md` for the complete searchable icon catalog, and `performance.md` for delivery and measurement. Motion is a minified, self-hosted runtime requested only by active motion routes. Explicit off and quiet routes need no motion script. Icons compile to the selected inline SVG geometry, with no client catalog, icon font or JavaScript. Static builds emit content-addressed CSS and islands per route; shared bytes deduplicate. A route without interactions needs no islands module. The generated preference page needs the beacon and base styles, not another route's widgets or motion.
16
+
17
+ Inspect actual desktop/mobile routes and network requests. Verify calls to action, synthetic form states, preference persistence and optional tracking requests using interception; do not create real leads or contaminate production analytics during tests. Check that unused motion, widgets and icon geometry are absent, that immutable asset references resolve, and that measured performance meets the configured gate. Do not infer a field performance pass from a successful build.
@@ -1,11 +1,15 @@
1
- # Launch (optional)
2
-
3
- Only when the operator asks after `preview_ready`.
4
-
5
- 1. `gh repo create ORG/SLUG --source . --private --push` (or push to existing remote).
6
- 2. Set the real `launch.json.publicOrigin` and Cloudflare Pages build command to `npm ci && npx playwright install chromium && npm run build && npm run preflight`, output `dist`, production `main`. Set `VITRIS_SITE_ENVIRONMENT=production` on the production branch. Preview branches use `preview` and remain diagnostic. A direct `wrangler pages deploy` must follow a successful current preflight on the exact `dist` bytes.
7
- 3. Register tenant in harness `/ops`: owner email (`launch.json` → `ownerEmail`), `pages_project`, `github_owner`, `github_repo`.
8
- 4. Fill `launch.json` → `github`, `publicOrigin` when known.
9
- 5. Owner admin: `{backendOrigin}/app/login` with `ownerEmail`.
10
-
11
- Do not merge secrets into git. Use `.env` for Cloudflare tokens.
1
+ # Launch (optional)
2
+
3
+ For a separately requested business admin at `admin.customer-domain.com`, read `admin.md` and the installed harness's `docs/ADMIN.md`. Use `vitris admin setup --plan` and reviewed `--apply`; verify the actual deployed backend with `vitris admin verify`. Local scaffolding does not enable collection/authentication or deploy infrastructure. Keep the sibling admin's Cloudflare provisioning and release separate from website publication.
4
+
5
+ Only when the operator asks after `preview_ready`. Build and verify locally, then upload the exact staged bundle directly to Cloudflare Pages. GitHub stores source and history; hosted deployment automation is opt-in.
6
+
7
+ 1. Commit authored source and the lockfile to the customer's private repository when requested. Keep `dist/`, `agent/release-bundles/`, `agent/release-candidate.json`, `agent/releases/`, captures and credentials out of Git.
8
+ 2. Authenticate with the operator's own `npx wrangler login` and confirm the account. For a new site create a Pages Direct Upload project with `npx wrangler pages project create PROJECT`. Set `launch.json.pagesProject` and the real production `launch.json.publicOrigin`. Install Chromium locally for preflight. Run `npm run deploy:preview` and accept the hosted preview; run `npm run deploy` only for explicit production publication. Ordinary deployment builds and verifies locally, stages the exact checked files, uploads them, records their identity and checks the hosted URL. Preservation sites support temporary previews only.
9
+ 3. For existing Git-connected Pages projects, disable automatic production and preview branch deployments before local uploads. Review and disable existing automatic GitHub deployment workflows as well. Preserve project names, domains, launch configuration, authored files and workflow progress. Installing or upgrading the harness does not migrate package scripts or remote settings. See the installed harness's `docs/CLOUDFLARE.md`.
10
+ 4. Backend tenant registration, contact forms, administration sign-in, custom domains and DNS are separate configured features. If publishing through the authenticated backend Worker, retain the exact verified bundle signing and attestation contract and review that path before migration. Direct Pages uploads do not provision tenants or forms.
11
+ 5. Hosted automation is opt-in. `deployment/github-actions.yml.example` is inactive until an operator chooses and installs it under `.github/workflows/` with protected secrets. Cloudflare Git builds are another optional alternative. Enable one publication path per site; preserve preflight and bundle integrity checks in every ordinary path.
12
+
13
+ Do not merge secrets into git. Use `.env` for Cloudflare tokens.
14
+
15
+ For an explicitly requested quick publish, use `vitris deploy --quick --environment production` (`npm run deploy:quick` in newly scaffolded sites). This rebuilds and deploys without browser, graph or launch review gates. Compilation, Cloudflare credentials, staged-file integrity and an HTTP smoke check still run. Receipts record build-only verification. Preservation sites use `--environment preview` and also skip screenshot comparisons. Ordinary deployment retains full preflight.
@@ -1,4 +1,4 @@
1
- # Performance
1
+ # Performance
2
2
 
3
3
  Ship static HTML, the CSS of components that are used, and islands only when a page needs them. The Vitris starting budgets are project policy: 100 KiB gzip of first-party JavaScript, 100 KiB gzip of CSS, 200 KiB of fonts, and 1.5 MiB initial transfer. They are not Core Web Vitals.
4
4
 
@@ -11,8 +11,8 @@ import {
11
11
  parentDiversitySourceSubject,
12
12
  reviewSubject,
13
13
  validateParentDiversityReview
14
- } from "../../chunks/chunk-FRABKM65.js";
15
- import "../../chunks/chunk-DSS2U2OM.js";
14
+ } from "../../chunks/chunk-XY73ZLHB.js";
15
+ import "../../chunks/chunk-KVMZSQ3D.js";
16
16
  import "../../chunks/chunk-WOORR67N.js";
17
17
  import "../../chunks/chunk-PRLL7B63.js";
18
18
  import "../../chunks/chunk-5JTBC6UK.js";
@@ -25,9 +25,9 @@ import "../../chunks/chunk-AUO5I56E.js";
25
25
  import "../../chunks/chunk-BIEDSEL2.js";
26
26
  import "../../chunks/chunk-IKNMBGGD.js";
27
27
  import "../../chunks/chunk-WEFDVXFX.js";
28
- import "../../chunks/chunk-VTI32UGJ.js";
29
- import "../../chunks/chunk-4MFPATAB.js";
30
- import "../../chunks/chunk-ZIROO2U4.js";
28
+ import "../../chunks/chunk-H3BS2EBR.js";
29
+ import "../../chunks/chunk-L44ZTNDM.js";
30
+ import "../../chunks/chunk-37F7XIMH.js";
31
31
  import "../../chunks/chunk-LKN75JGA.js";
32
32
  import "../../chunks/chunk-YYPYYOEV.js";
33
33
  import "../../chunks/chunk-GZDLXYZV.js";
@@ -9,8 +9,8 @@ import {
9
9
  gradePages,
10
10
  gradePreview,
11
11
  gradeResearch
12
- } from "../../chunks/chunk-FRABKM65.js";
13
- import "../../chunks/chunk-DSS2U2OM.js";
12
+ } from "../../chunks/chunk-XY73ZLHB.js";
13
+ import "../../chunks/chunk-KVMZSQ3D.js";
14
14
  import "../../chunks/chunk-WOORR67N.js";
15
15
  import "../../chunks/chunk-PRLL7B63.js";
16
16
  import "../../chunks/chunk-5JTBC6UK.js";
@@ -23,9 +23,9 @@ import "../../chunks/chunk-AUO5I56E.js";
23
23
  import "../../chunks/chunk-BIEDSEL2.js";
24
24
  import "../../chunks/chunk-IKNMBGGD.js";
25
25
  import "../../chunks/chunk-WEFDVXFX.js";
26
- import "../../chunks/chunk-VTI32UGJ.js";
27
- import "../../chunks/chunk-4MFPATAB.js";
28
- import "../../chunks/chunk-ZIROO2U4.js";
26
+ import "../../chunks/chunk-H3BS2EBR.js";
27
+ import "../../chunks/chunk-L44ZTNDM.js";
28
+ import "../../chunks/chunk-37F7XIMH.js";
29
29
  import "../../chunks/chunk-LKN75JGA.js";
30
30
  import "../../chunks/chunk-YYPYYOEV.js";
31
31
  import "../../chunks/chunk-GZDLXYZV.js";
@@ -11,7 +11,7 @@ import {
11
11
  runDoctor,
12
12
  shareSite,
13
13
  synthesizeSite
14
- } from "../../chunks/chunk-ZWFG4GPG.js";
14
+ } from "../../chunks/chunk-YXJAQYDE.js";
15
15
  import {
16
16
  applyOperations,
17
17
  buildSiteDraft,
@@ -19,35 +19,36 @@ import {
19
19
  inspectSite,
20
20
  prepareChange,
21
21
  verifyChange
22
- } from "../../chunks/chunk-O55LAQ2C.js";
22
+ } from "../../chunks/chunk-FGSQE3DU.js";
23
23
  import {
24
24
  deployVerifiedArtifact,
25
+ prepareQuickRelease,
25
26
  prepareVerifiedRelease,
26
27
  verifySite
27
- } from "../../chunks/chunk-P56ZDMX7.js";
28
+ } from "../../chunks/chunk-WMJVLMU2.js";
28
29
  import {
29
30
  upgradeSite
30
- } from "../../chunks/chunk-PGFFKPK6.js";
31
+ } from "../../chunks/chunk-A2XMAPVW.js";
31
32
  import {
32
33
  createSite
33
- } from "../../chunks/chunk-H7Y72HXC.js";
34
+ } from "../../chunks/chunk-UFTVWTEZ.js";
34
35
  import "../../chunks/chunk-2NW7KSPA.js";
35
36
  import {
36
37
  buildAdapterConfig,
37
38
  runPreserve,
38
39
  runSite,
39
40
  statusSite
40
- } from "../../chunks/chunk-7V3OKLKH.js";
41
- import "../../chunks/chunk-QRWGFLUU.js";
41
+ } from "../../chunks/chunk-LZC37OJZ.js";
42
+ import "../../chunks/chunk-R2WRQDVE.js";
42
43
  import "../../chunks/chunk-34H54KEY.js";
43
44
  import {
44
45
  EXIT_CODES
45
46
  } from "../../chunks/chunk-JCRGE6AL.js";
46
47
  import "../../chunks/chunk-XL2DRAYI.js";
47
- import "../../chunks/chunk-5YSPWKFF.js";
48
+ import "../../chunks/chunk-PYCRUMCT.js";
48
49
  import "../../chunks/chunk-XGTHGWPW.js";
49
- import "../../chunks/chunk-FRABKM65.js";
50
- import "../../chunks/chunk-DSS2U2OM.js";
50
+ import "../../chunks/chunk-XY73ZLHB.js";
51
+ import "../../chunks/chunk-KVMZSQ3D.js";
51
52
  import "../../chunks/chunk-WOORR67N.js";
52
53
  import "../../chunks/chunk-PRLL7B63.js";
53
54
  import "../../chunks/chunk-5JTBC6UK.js";
@@ -60,9 +61,9 @@ import "../../chunks/chunk-AUO5I56E.js";
60
61
  import "../../chunks/chunk-BIEDSEL2.js";
61
62
  import "../../chunks/chunk-IKNMBGGD.js";
62
63
  import "../../chunks/chunk-WEFDVXFX.js";
63
- import "../../chunks/chunk-VTI32UGJ.js";
64
- import "../../chunks/chunk-4MFPATAB.js";
65
- import "../../chunks/chunk-ZIROO2U4.js";
64
+ import "../../chunks/chunk-H3BS2EBR.js";
65
+ import "../../chunks/chunk-L44ZTNDM.js";
66
+ import "../../chunks/chunk-37F7XIMH.js";
66
67
  import "../../chunks/chunk-LKN75JGA.js";
67
68
  import "../../chunks/chunk-YYPYYOEV.js";
68
69
  import "../../chunks/chunk-GZDLXYZV.js";
@@ -83,6 +84,7 @@ export {
83
84
  inspectSite,
84
85
  migrateSite,
85
86
  prepareChange,
87
+ prepareQuickRelease,
86
88
  prepareVerifiedRelease,
87
89
  previewSite,
88
90
  refineSite,
package/bin/api/cli.js CHANGED
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  runCli
3
- } from "../chunks/chunk-YZWEXHT4.js";
4
- import "../chunks/chunk-ZWFG4GPG.js";
5
- import "../chunks/chunk-O55LAQ2C.js";
6
- import "../chunks/chunk-P56ZDMX7.js";
7
- import "../chunks/chunk-PGFFKPK6.js";
8
- import "../chunks/chunk-H7Y72HXC.js";
3
+ } from "../chunks/chunk-SEMH6MCV.js";
4
+ import "../chunks/chunk-YXJAQYDE.js";
5
+ import "../chunks/chunk-FGSQE3DU.js";
6
+ import "../chunks/chunk-WMJVLMU2.js";
7
+ import "../chunks/chunk-A2XMAPVW.js";
8
+ import "../chunks/chunk-UFTVWTEZ.js";
9
9
  import "../chunks/chunk-2NW7KSPA.js";
10
- import "../chunks/chunk-TTAUU3AZ.js";
11
- import "../chunks/chunk-7V3OKLKH.js";
12
- import "../chunks/chunk-QRWGFLUU.js";
10
+ import "../chunks/chunk-3OKR5AZJ.js";
11
+ import "../chunks/chunk-LZC37OJZ.js";
12
+ import "../chunks/chunk-R2WRQDVE.js";
13
13
  import "../chunks/chunk-34H54KEY.js";
14
14
  import "../chunks/chunk-JCRGE6AL.js";
15
15
  import "../chunks/chunk-XL2DRAYI.js";
16
- import "../chunks/chunk-5YSPWKFF.js";
16
+ import "../chunks/chunk-PYCRUMCT.js";
17
17
  import "../chunks/chunk-XGTHGWPW.js";
18
- import "../chunks/chunk-FRABKM65.js";
19
- import "../chunks/chunk-DSS2U2OM.js";
18
+ import "../chunks/chunk-XY73ZLHB.js";
19
+ import "../chunks/chunk-KVMZSQ3D.js";
20
20
  import "../chunks/chunk-WOORR67N.js";
21
21
  import "../chunks/chunk-PRLL7B63.js";
22
22
  import "../chunks/chunk-5JTBC6UK.js";
@@ -29,9 +29,9 @@ import "../chunks/chunk-AUO5I56E.js";
29
29
  import "../chunks/chunk-BIEDSEL2.js";
30
30
  import "../chunks/chunk-IKNMBGGD.js";
31
31
  import "../chunks/chunk-WEFDVXFX.js";
32
- import "../chunks/chunk-VTI32UGJ.js";
33
- import "../chunks/chunk-4MFPATAB.js";
34
- import "../chunks/chunk-ZIROO2U4.js";
32
+ import "../chunks/chunk-H3BS2EBR.js";
33
+ import "../chunks/chunk-L44ZTNDM.js";
34
+ import "../chunks/chunk-37F7XIMH.js";
35
35
  import "../chunks/chunk-LKN75JGA.js";
36
36
  import "../chunks/chunk-YYPYYOEV.js";
37
37
  import "../chunks/chunk-GZDLXYZV.js";
package/bin/api/engine.js CHANGED
@@ -7,12 +7,12 @@ import {
7
7
  prepareChange,
8
8
  publicEditManifest,
9
9
  verifyChange
10
- } from "../chunks/chunk-O55LAQ2C.js";
10
+ } from "../chunks/chunk-FGSQE3DU.js";
11
11
  import {
12
12
  changedSourceFiles,
13
13
  sourceRevision
14
- } from "../chunks/chunk-FRABKM65.js";
15
- import "../chunks/chunk-DSS2U2OM.js";
14
+ } from "../chunks/chunk-XY73ZLHB.js";
15
+ import "../chunks/chunk-KVMZSQ3D.js";
16
16
  import "../chunks/chunk-WOORR67N.js";
17
17
  import "../chunks/chunk-PRLL7B63.js";
18
18
  import "../chunks/chunk-5JTBC6UK.js";
@@ -25,9 +25,9 @@ import "../chunks/chunk-AUO5I56E.js";
25
25
  import "../chunks/chunk-BIEDSEL2.js";
26
26
  import "../chunks/chunk-IKNMBGGD.js";
27
27
  import "../chunks/chunk-WEFDVXFX.js";
28
- import "../chunks/chunk-VTI32UGJ.js";
29
- import "../chunks/chunk-4MFPATAB.js";
30
- import "../chunks/chunk-ZIROO2U4.js";
28
+ import "../chunks/chunk-H3BS2EBR.js";
29
+ import "../chunks/chunk-L44ZTNDM.js";
30
+ import "../chunks/chunk-37F7XIMH.js";
31
31
  import "../chunks/chunk-LKN75JGA.js";
32
32
  import "../chunks/chunk-YYPYYOEV.js";
33
33
  import "../chunks/chunk-GZDLXYZV.js";
@@ -1,13 +1,14 @@
1
1
  import {
2
2
  deployVerifiedArtifact,
3
+ prepareQuickRelease,
3
4
  prepareVerifiedRelease
4
- } from "../chunks/chunk-P56ZDMX7.js";
5
+ } from "../chunks/chunk-WMJVLMU2.js";
5
6
  import "../chunks/chunk-2NW7KSPA.js";
6
- import "../chunks/chunk-QRWGFLUU.js";
7
+ import "../chunks/chunk-R2WRQDVE.js";
7
8
  import "../chunks/chunk-JCRGE6AL.js";
8
9
  import "../chunks/chunk-XL2DRAYI.js";
9
- import "../chunks/chunk-FRABKM65.js";
10
- import "../chunks/chunk-DSS2U2OM.js";
10
+ import "../chunks/chunk-XY73ZLHB.js";
11
+ import "../chunks/chunk-KVMZSQ3D.js";
11
12
  import "../chunks/chunk-WOORR67N.js";
12
13
  import "../chunks/chunk-PRLL7B63.js";
13
14
  import "../chunks/chunk-5JTBC6UK.js";
@@ -20,9 +21,9 @@ import "../chunks/chunk-AUO5I56E.js";
20
21
  import "../chunks/chunk-BIEDSEL2.js";
21
22
  import "../chunks/chunk-IKNMBGGD.js";
22
23
  import "../chunks/chunk-WEFDVXFX.js";
23
- import "../chunks/chunk-VTI32UGJ.js";
24
- import "../chunks/chunk-4MFPATAB.js";
25
- import "../chunks/chunk-ZIROO2U4.js";
24
+ import "../chunks/chunk-H3BS2EBR.js";
25
+ import "../chunks/chunk-L44ZTNDM.js";
26
+ import "../chunks/chunk-37F7XIMH.js";
26
27
  import "../chunks/chunk-LKN75JGA.js";
27
28
  import "../chunks/chunk-YYPYYOEV.js";
28
29
  import "../chunks/chunk-GZDLXYZV.js";
@@ -31,5 +32,6 @@ import "../chunks/chunk-T6PE4KN4.js";
31
32
  import "../chunks/chunk-7FS67SRF.js";
32
33
  export {
33
34
  deployVerifiedArtifact,
35
+ prepareQuickRelease,
34
36
  prepareVerifiedRelease
35
37
  };
package/bin/api/index.js CHANGED
@@ -4,8 +4,8 @@ import {
4
4
  loadSiteCatalog,
5
5
  loadSiteDir,
6
6
  loadSitePages
7
- } from "../chunks/chunk-4MFPATAB.js";
8
- import "../chunks/chunk-ZIROO2U4.js";
7
+ } from "../chunks/chunk-L44ZTNDM.js";
8
+ import "../chunks/chunk-37F7XIMH.js";
9
9
  import "../chunks/chunk-LKN75JGA.js";
10
10
  import "../chunks/chunk-YYPYYOEV.js";
11
11
  import "../chunks/chunk-GZDLXYZV.js";
package/bin/api/render.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  sitemapXml,
19
19
  usedComponents,
20
20
  wrapMain
21
- } from "../chunks/chunk-ZIROO2U4.js";
21
+ } from "../chunks/chunk-37F7XIMH.js";
22
22
  import "../chunks/chunk-GZDLXYZV.js";
23
23
  import "../chunks/chunk-7FS67SRF.js";
24
24
 
@@ -2703,8 +2703,8 @@ ${urls}
2703
2703
  </urlset>
2704
2704
  `;
2705
2705
  }
2706
- function compileSite(opts) {
2707
- const compiled = opts.pages.map(
2706
+ function compileSite(opts, preparedPages) {
2707
+ const compiled = preparedPages ?? opts.pages.map(
2708
2708
  (page) => compilePage(page, opts.catalog, opts.site, opts.kernelOrigin)
2709
2709
  );
2710
2710
  const islands = siteIslands(compiled, opts.catalog);
@@ -2742,7 +2742,8 @@ function compileSite(opts) {
2742
2742
  themeHref: opts.themeHref,
2743
2743
  assetsPrefix: opts.assetsPrefix,
2744
2744
  publicOrigin: opts.publicOrigin,
2745
- islandsHref
2745
+ islandsHref: null,
2746
+ styleHref: opts.pageAssets?.[COOKIE_COMPLIANCE_PATH]?.css
2746
2747
  })
2747
2748
  });
2748
2749
  return files;