@getvitops/create 0.8.2 → 0.9.0-alpha.1
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 +103 -0
- package/package.json +2 -2
- package/templates/emdash/.agents/skills/custom-blocks/SKILL.md +104 -0
- package/templates/emdash/.agents/skills/setup/SKILL.md +4 -4
- package/templates/emdash/.claude/hooks/session-start.sh +4 -1
- package/templates/emdash/.github/workflows/deploy-prod.yml +12 -0
- package/templates/emdash/AGENTS.md +228 -28
- package/templates/emdash/README.md +48 -37
- package/templates/emdash/SETUP.html +45 -27
- package/templates/emdash/_gitignore +3 -0
- package/templates/emdash/astro.config.mjs +14 -1
- package/templates/emdash/package.json +7 -5
- package/templates/emdash/public/_headers +19 -4
- package/templates/emdash/scripts/pull-content.mjs +83 -0
- package/templates/emdash/seed/seed.json +188 -6
- package/templates/emdash/site.json +102 -3
- package/templates/emdash/src/cloudflare-workers.d.ts +9 -0
- package/templates/emdash/src/layouts/Layout.astro +27 -45
- package/templates/emdash/src/pages/404.astro +4 -3
- package/templates/emdash/src/pages/[...slug].astro +22 -12
- package/templates/emdash/src/pages/api/track.ts +158 -0
- package/templates/emdash/src/pages/index.astro +10 -9
- package/templates/static/.agents/skills/setup/SKILL.md +4 -4
- package/templates/static/AGENTS.md +68 -14
- package/templates/static/README.md +7 -7
- package/templates/static/SETUP.html +45 -27
- package/templates/static/public/_headers +16 -4
- package/templates/static/site.json +54 -1
|
@@ -4,7 +4,7 @@ A static [Astro](https://astro.build) website on Cloudflare Workers (static
|
|
|
4
4
|
assets — no server runtime), styled by the
|
|
5
5
|
[Vitops design system](https://www.npmjs.com/org/getvitops).
|
|
6
6
|
|
|
7
|
-
Scaffolded from `vp create @getvitops:static
|
|
7
|
+
Scaffolded from `vp create @getvitops:static --directory <client-slug>` (pass a directory: `vp create` derives the package name from it and invents a random slug otherwise).
|
|
8
8
|
|
|
9
9
|
## Stack
|
|
10
10
|
|
|
@@ -20,8 +20,8 @@ before real imagery exists — delete once real assets land.
|
|
|
20
20
|
## Local development
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
vp install
|
|
24
|
+
vpr dev
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
- Site: <http://localhost:4321>
|
|
@@ -29,8 +29,8 @@ pnpm dev
|
|
|
29
29
|
## Deploy
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
vp exec wrangler login
|
|
33
|
+
vpr deploy
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
For a custom domain, uncomment the `routes` block in `wrangler.jsonc` and set
|
|
@@ -55,7 +55,7 @@ The repo ships a two-environment flow modeled on branch = environment:
|
|
|
55
55
|
One-time setup — work through the checklist:
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
|
|
58
|
+
vpr sop && open SETUP.html # or: xdg-open SETUP.html
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
It covers host choice, GitHub + branch policy, hosting resources, going live
|
|
@@ -65,7 +65,7 @@ command per step. An AI agent can work the same list autonomously via
|
|
|
65
65
|
`.agents/skills/setup/`; it stops at the steps that genuinely need a human
|
|
66
66
|
(the Cloudflare API token, the domain cutover, publishing legal documents).
|
|
67
67
|
|
|
68
|
-
`
|
|
68
|
+
`vpr deploy:dev` reproduces the dev deploy locally: it writes a
|
|
69
69
|
gitignored `.wrangler.dev.json` with the worker renamed and any custom-domain
|
|
70
70
|
route prefixed `dev.` (`scripts/dev-wrangler-config.mjs`), so it never
|
|
71
71
|
touches the prod worker.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<!--
|
|
8
8
|
Opened straight from disk (file://) before anything is deployed, which is
|
|
9
9
|
when most of these steps happen — so it links a relative, pre-generated
|
|
10
|
-
stylesheet rather than the site's own build output. Run `
|
|
10
|
+
stylesheet rather than the site's own build output. Run `vpr sop`
|
|
11
11
|
first (it's a one-line `vitops generate -f css` into .vitops/sop/); the
|
|
12
12
|
banner below explains this if the stylesheet 404s, and the markup stays
|
|
13
13
|
legible either way — every item here is a real checkbox in a real
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
-->
|
|
22
22
|
<link id="sop-stylesheet" rel="stylesheet" href=".vitops/sop/styles.css" />
|
|
23
23
|
<style>
|
|
24
|
-
/* Minimal fallback so the page is still legible before `
|
|
24
|
+
/* Minimal fallback so the page is still legible before `vpr sop`
|
|
25
25
|
has run once — intentionally not framework CSS, since it only ever
|
|
26
26
|
applies in the narrow window before the real stylesheet exists. */
|
|
27
27
|
body {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
<header class="region rhythm">
|
|
43
43
|
<h1>Client onboarding checklist</h1>
|
|
44
44
|
<p id="no-stylesheet-notice" class="banner" hidden>
|
|
45
|
-
This page isn't styled yet — run <code>
|
|
45
|
+
This page isn't styled yet — run <code>vpr sop</code> once (it generates
|
|
46
46
|
<code>.vitops/sop/styles.css</code>), then reload.
|
|
47
47
|
</p>
|
|
48
48
|
<p>
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
<span class="custom-check__box"
|
|
91
91
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
92
92
|
></span>
|
|
93
|
-
<span> Preview it: <code>
|
|
93
|
+
<span> Preview it: <code>vp exec vitops setup repo --dry</code> </span>
|
|
94
94
|
</label>
|
|
95
95
|
<label class="custom-check">
|
|
96
96
|
<input type="checkbox" data-sop="repo.run" />
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
99
99
|
></span>
|
|
100
100
|
<span>
|
|
101
|
-
Run it: <code>
|
|
101
|
+
Run it: <code>vp exec vitops setup repo</code> — creates the GitHub repo, pushes
|
|
102
102
|
<code>main</code> + <code>dev</code>, makes <code>dev</code> default, and requests
|
|
103
103
|
branch protection + the <code>production</code>/<code>dev</code>
|
|
104
104
|
environments.
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
<span class="custom-check__box"
|
|
127
127
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
128
128
|
></span>
|
|
129
|
-
<span> Preview it: <code>
|
|
129
|
+
<span> Preview it: <code>vp exec vitops setup hosting --dry</code> </span>
|
|
130
130
|
</label>
|
|
131
131
|
<label class="custom-check">
|
|
132
132
|
<input type="checkbox" data-sop="hosting.run" />
|
|
@@ -134,10 +134,10 @@
|
|
|
134
134
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
135
135
|
></span>
|
|
136
136
|
<span>
|
|
137
|
-
Run it: <code>
|
|
137
|
+
Run it: <code>vp exec vitops setup hosting</code> — provisions the isolated dev D1
|
|
138
138
|
database + R2 bucket (EmDash template) and sets the <code>DEV_D1_ID</code> /
|
|
139
139
|
<code>CLOUDFLARE_ACCOUNT_ID</code> repo secrets. Requires
|
|
140
|
-
<code>
|
|
140
|
+
<code>vp exec wrangler login</code> first.
|
|
141
141
|
</span>
|
|
142
142
|
</label>
|
|
143
143
|
<label class="custom-check">
|
|
@@ -276,7 +276,7 @@
|
|
|
276
276
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
277
277
|
></span>
|
|
278
278
|
<span>
|
|
279
|
-
Deploy once (<code>
|
|
279
|
+
Deploy once (<code>vpr deploy</code>), note the printed
|
|
280
280
|
<code>*.workers.dev</code> URL, and set
|
|
281
281
|
<code>site.environments.production.url</code> in <code>site.json</code> to it.
|
|
282
282
|
</span>
|
|
@@ -315,8 +315,8 @@
|
|
|
315
315
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
316
316
|
></span>
|
|
317
317
|
<span>
|
|
318
|
-
Preview it: <code>
|
|
319
|
-
only plans and checks; it never applies the cutover itself.
|
|
318
|
+
Preview it: <code>vp exec vitops setup domain --domain <apex> --dry</code> —
|
|
319
|
+
this only plans and checks; it never applies the cutover itself.
|
|
320
320
|
</span>
|
|
321
321
|
</label>
|
|
322
322
|
<label class="custom-check">
|
|
@@ -326,7 +326,7 @@
|
|
|
326
326
|
></span>
|
|
327
327
|
<span>
|
|
328
328
|
Uncomment the <code>routes</code> block in <code>wrangler.jsonc</code>, set your
|
|
329
|
-
apex, and deploy: <code>
|
|
329
|
+
apex, and deploy: <code>vpr deploy</code>.
|
|
330
330
|
</span>
|
|
331
331
|
</label>
|
|
332
332
|
<label class="custom-check">
|
|
@@ -347,7 +347,8 @@
|
|
|
347
347
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
348
348
|
></span>
|
|
349
349
|
<span>
|
|
350
|
-
Re-run <code>
|
|
350
|
+
Re-run <code>vp exec vitops robots</code> and
|
|
351
|
+
<code>vp exec vitops search notify</code>.
|
|
351
352
|
</span>
|
|
352
353
|
</label>
|
|
353
354
|
</div>
|
|
@@ -373,7 +374,7 @@
|
|
|
373
374
|
<span class="custom-check__box"
|
|
374
375
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
375
376
|
></span>
|
|
376
|
-
<span> Check it: <code>
|
|
377
|
+
<span> Check it: <code>vp exec vitops validate site.json</code> </span>
|
|
377
378
|
</label>
|
|
378
379
|
</div>
|
|
379
380
|
</details>
|
|
@@ -398,8 +399,8 @@
|
|
|
398
399
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
399
400
|
></span>
|
|
400
401
|
<span>
|
|
401
|
-
Preview then run: <code>
|
|
402
|
-
<code>
|
|
402
|
+
Preview then run: <code>vp exec vitops setup search --dry</code>, then
|
|
403
|
+
<code>vp exec vitops setup search</code>. This is a <strong>user OAuth</strong>
|
|
403
404
|
action, deliberately — verifying a site makes the caller an owner, and that should
|
|
404
405
|
be a person, not a deploy robot.
|
|
405
406
|
</span>
|
|
@@ -410,8 +411,25 @@
|
|
|
410
411
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
411
412
|
></span>
|
|
412
413
|
<span>
|
|
413
|
-
Preview then run: <code>
|
|
414
|
-
<code>
|
|
414
|
+
Preview then run: <code>vp exec vitops setup ads --dry</code>, then
|
|
415
|
+
<code>vp exec vitops setup ads</code>.
|
|
416
|
+
</span>
|
|
417
|
+
</label>
|
|
418
|
+
<label class="custom-check">
|
|
419
|
+
<input type="checkbox" data-sop="connections.turnstile" />
|
|
420
|
+
<span class="custom-check__box"
|
|
421
|
+
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
422
|
+
></span>
|
|
423
|
+
<span>
|
|
424
|
+
If the site has a contact form, create its spam check:
|
|
425
|
+
<code>vp exec vitops setup turnstile --dry</code>, then
|
|
426
|
+
<code>vp exec vitops setup turnstile</code>. It needs
|
|
427
|
+
<code>CLOUDFLARE_API_TOKEN</code> with
|
|
428
|
+
<strong>Account > Turnstile > Edit</strong> (plus
|
|
429
|
+
<code>CLOUDFLARE_ACCOUNT_ID</code>) and <code>wrangler login</code>. The public site
|
|
430
|
+
key goes into <code>site.security.turnstile.siteKey</code>; the secret is saved as
|
|
431
|
+
the Worker secret <code>VITOPS_TURNSTILE_SECRET</code> and never touches
|
|
432
|
+
<code>site.json</code>. It never edits or deletes an existing widget.
|
|
415
433
|
</span>
|
|
416
434
|
</label>
|
|
417
435
|
<label class="custom-check">
|
|
@@ -453,10 +471,10 @@
|
|
|
453
471
|
></span>
|
|
454
472
|
<span>
|
|
455
473
|
Generate real documents from the filled-in config —
|
|
456
|
-
<code>
|
|
457
|
-
or <code>
|
|
458
|
-
<code>/terms</code> and <code>/privacy</code> pages are deliberately
|
|
459
|
-
obviously-unfinished placeholders.
|
|
474
|
+
<code>vp exec vitops legal --format portable-text</code> (EmDash; paste into the
|
|
475
|
+
admin) or <code>vp exec vitops legal --format md</code> (static; commit the output).
|
|
476
|
+
The seeded <code>/terms</code> and <code>/privacy</code> pages are deliberately
|
|
477
|
+
short, obviously-unfinished placeholders.
|
|
460
478
|
</span>
|
|
461
479
|
</label>
|
|
462
480
|
<label class="custom-check">
|
|
@@ -484,7 +502,7 @@
|
|
|
484
502
|
></span>
|
|
485
503
|
<span>
|
|
486
504
|
Robots directive matches the live origin's intent (blocked while on workers.dev,
|
|
487
|
-
open after cutover) — <code>
|
|
505
|
+
open after cutover) — <code>vp exec vitops robots</code>.
|
|
488
506
|
</span>
|
|
489
507
|
</label>
|
|
490
508
|
<label class="custom-check">
|
|
@@ -509,7 +527,7 @@
|
|
|
509
527
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
510
528
|
></span>
|
|
511
529
|
<span>
|
|
512
|
-
<code>
|
|
530
|
+
<code>vp exec vitops lint --src</code> and <code>vpr typecheck</code> both clean.
|
|
513
531
|
</span>
|
|
514
532
|
</label>
|
|
515
533
|
<label class="custom-check">
|
|
@@ -527,7 +545,7 @@
|
|
|
527
545
|
<span class="custom-check__box"
|
|
528
546
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
529
547
|
></span>
|
|
530
|
-
<span> <code>
|
|
548
|
+
<span> <code>vp exec vitops search notify</code> run once live. </span>
|
|
531
549
|
</label>
|
|
532
550
|
<label class="custom-check">
|
|
533
551
|
<input type="checkbox" data-sop="launch.check" />
|
|
@@ -535,8 +553,8 @@
|
|
|
535
553
|
><span class="custom-check__indicator custom-check__indicator--check"></span
|
|
536
554
|
></span>
|
|
537
555
|
<span>
|
|
538
|
-
A day or two later: <code>
|
|
539
|
-
actually indexed it.
|
|
556
|
+
A day or two later: <code>vp exec vitops search notify --check</code> confirms
|
|
557
|
+
Google actually indexed it.
|
|
540
558
|
</span>
|
|
541
559
|
</label>
|
|
542
560
|
</div>
|
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
# Cloudflare
|
|
1
|
+
# Cloudflare static-assets response headers for the whole site (every page here is
|
|
2
|
+
# a static asset). See AGENTS.md "Content Security Policy".
|
|
2
3
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
4
|
+
# REPORT-ONLY on purpose: violations are logged to the browser console and
|
|
5
|
+
# nothing is blocked, so this cannot break a page. Read the console on the
|
|
6
|
+
# pages you ship, add what is legitimately needed, then rename the header to
|
|
7
|
+
# `Content-Security-Policy` to enforce it.
|
|
8
|
+
#
|
|
9
|
+
# The two sha256 values are the inline scripts <Head /> emits (the colour-scheme
|
|
10
|
+
# bootstrap and the consent-gate stub). They change only when
|
|
11
|
+
# @getvitops/astro changes those scripts; regenerate with
|
|
12
|
+
# vp exec node -e "import('@getvitops/astro').then(m => console.log(m.contentSecurityPolicy()))"
|
|
13
|
+
# `templates.test.ts` in the toolchain repo guards that they match.
|
|
14
|
+
#
|
|
15
|
+
# Third-party tags the consent gate activates need their origins in
|
|
16
|
+
# script-src/connect-src before you enforce.
|
|
6
17
|
/*
|
|
18
|
+
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'sha256-CEiVlTo192T9Rug/nAl+ihvkqOQkYdr6Rq3oc+gR9JU=' 'sha256-z/UqsITVvNGOJSaOSvhN1rdtyYdMIxpQ/lMXM1q0g90=' https://challenges.cloudflare.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-src https://challenges.cloudflare.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'
|
|
7
19
|
X-Content-Type-Options: nosniff
|
|
8
20
|
Referrer-Policy: strict-origin-when-cross-origin
|
|
9
21
|
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
|
|
@@ -93,6 +93,13 @@
|
|
|
93
93
|
"br": "0.5rem",
|
|
94
94
|
"p": "1rem",
|
|
95
95
|
"fs": "var(--fs-default)"
|
|
96
|
+
},
|
|
97
|
+
"label": {
|
|
98
|
+
"ds": "var(--ds-default)",
|
|
99
|
+
"b": "none",
|
|
100
|
+
"br": "0.25rem",
|
|
101
|
+
"p": "0.25em 0.5em",
|
|
102
|
+
"fs": "0.75rem"
|
|
96
103
|
}
|
|
97
104
|
},
|
|
98
105
|
"z": {
|
|
@@ -126,7 +133,8 @@
|
|
|
126
133
|
"ring": true
|
|
127
134
|
}
|
|
128
135
|
},
|
|
129
|
-
"roles": []
|
|
136
|
+
"roles": ["success", "danger", "warning", "info"],
|
|
137
|
+
"class": "btn"
|
|
130
138
|
},
|
|
131
139
|
"card": {
|
|
132
140
|
"group": "panel",
|
|
@@ -140,6 +148,51 @@
|
|
|
140
148
|
},
|
|
141
149
|
"states": {},
|
|
142
150
|
"roles": []
|
|
151
|
+
},
|
|
152
|
+
"badge": {
|
|
153
|
+
"group": "label",
|
|
154
|
+
"class": "badge",
|
|
155
|
+
"default_role": "brand-primary",
|
|
156
|
+
"overrides": {
|
|
157
|
+
"p": "0.2em 0.6em",
|
|
158
|
+
"br": "999px",
|
|
159
|
+
"fs": "0.85em"
|
|
160
|
+
},
|
|
161
|
+
"base": {
|
|
162
|
+
"display": "inline-block",
|
|
163
|
+
"padding": "var(--p-badge-group)",
|
|
164
|
+
"border-radius": "var(--br-badge-group)",
|
|
165
|
+
"font-size": "var(--fs-badge-group)",
|
|
166
|
+
"font-weight": "600",
|
|
167
|
+
"color": "var(--color-text-on-brand-primary)"
|
|
168
|
+
},
|
|
169
|
+
"states": {},
|
|
170
|
+
"roles": ["success", "danger", "warning", "info"]
|
|
171
|
+
},
|
|
172
|
+
"tag": {
|
|
173
|
+
"group": "label",
|
|
174
|
+
"class": "tag",
|
|
175
|
+
"default_role": "neutral",
|
|
176
|
+
"overrides": {
|
|
177
|
+
"p": "0.25em 0.6em",
|
|
178
|
+
"b": "1px solid currentColor",
|
|
179
|
+
"fs": "0.85em"
|
|
180
|
+
},
|
|
181
|
+
"base": {
|
|
182
|
+
"display": "inline-flex",
|
|
183
|
+
"align-items": "center",
|
|
184
|
+
"gap": "0.25em",
|
|
185
|
+
"padding": "var(--p-tag-group)",
|
|
186
|
+
"border": "var(--b-tag-group)",
|
|
187
|
+
"border-radius": "var(--br-tag-group)",
|
|
188
|
+
"font-size": "var(--fs-tag-group)",
|
|
189
|
+
"font-weight": "500",
|
|
190
|
+
"line-height": "1.2",
|
|
191
|
+
"white-space": "nowrap",
|
|
192
|
+
"color": "var(--color-text-neutral-bold)"
|
|
193
|
+
},
|
|
194
|
+
"states": {},
|
|
195
|
+
"roles": ["success", "danger", "warning", "info"]
|
|
143
196
|
}
|
|
144
197
|
}
|
|
145
198
|
},
|