@cparkerwebm/webmonterey 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.
- package/CHANGELOG.md +56 -0
- package/LICENSE +21 -0
- package/README.md +104 -0
- package/agents/.gitkeep +0 -0
- package/dist/webm.mjs +2381 -0
- package/hooks/.gitkeep +0 -0
- package/package.json +101 -0
- package/schema/design.json +118 -0
- package/skills/launch/SKILL.md +183 -0
- package/skills/new-component/SKILL.md +85 -0
- package/skills/start/SKILL.md +117 -0
- package/skills/traps/SKILL.md +333 -0
- package/skills/upgrade/SKILL.md +42 -0
- package/src/actions/index.ts +348 -0
- package/src/cli/checks.test.ts +711 -0
- package/src/cli/checks.ts +822 -0
- package/src/cli/codemods.test.ts +42 -0
- package/src/cli/codemods.ts +51 -0
- package/src/cli/compare.test.ts +144 -0
- package/src/cli/compare.ts +222 -0
- package/src/cli/design-extract.test.ts +96 -0
- package/src/cli/design-extract.ts +229 -0
- package/src/cli/doctor.ts +187 -0
- package/src/cli/mcp.test.ts +57 -0
- package/src/cli/mcp.ts +110 -0
- package/src/cli/new.ts +148 -0
- package/src/cli/package-root.ts +58 -0
- package/src/cli/scaffold.test.ts +230 -0
- package/src/cli/scaffold.ts +424 -0
- package/src/cli/seed.ts +133 -0
- package/src/cli/slug.test.ts +70 -0
- package/src/cli/slug.ts +109 -0
- package/src/cli/sync.test.ts +137 -0
- package/src/cli/sync.ts +266 -0
- package/src/cli/upgrade.ts +93 -0
- package/src/design/__fixtures__/tokens-v1.4.1.css +227 -0
- package/src/design/brand.ts +49 -0
- package/src/design/compile.test.ts +98 -0
- package/src/design/compile.ts +155 -0
- package/src/design/defaults.ts +315 -0
- package/src/design/index.ts +18 -0
- package/src/design/resolve.test.ts +80 -0
- package/src/design/resolve.ts +108 -0
- package/src/design/types.ts +96 -0
- package/src/emails/autoresponse.test.ts +82 -0
- package/src/emails/autoresponse.ts +83 -0
- package/src/emails/footer.test.ts +102 -0
- package/src/emails/footer.ts +91 -0
- package/src/emails/index.ts +24 -0
- package/src/emails/subject.test.ts +66 -0
- package/src/emails/subject.ts +80 -0
- package/src/emails/submission-notification.ts +76 -0
- package/src/env.d.ts +12 -0
- package/src/includes/cloudflare/d1/client.ts +86 -0
- package/src/includes/cloudflare/r2/README.md +68 -0
- package/src/includes/cloudflare/r2/media.ts +41 -0
- package/src/includes/cloudflare/r2/url.test.ts +44 -0
- package/src/includes/cloudflare/r2/url.ts +34 -0
- package/src/includes/cloudflare/turnstile/Turnstile.astro +161 -0
- package/src/includes/cloudflare/turnstile/verify.ts +157 -0
- package/src/includes/cloudflare/workers/env.ts +56 -0
- package/src/includes/google/tag-manager/TagManager.astro +73 -0
- package/src/includes/sinch/mailgun/redirect.test.ts +96 -0
- package/src/includes/sinch/mailgun/redirect.ts +96 -0
- package/src/includes/sinch/mailgun/send.ts +186 -0
- package/src/includes/webmonterey/animations/animations.css +347 -0
- package/src/includes/webmonterey/animations/observe.test.ts +88 -0
- package/src/includes/webmonterey/animations/observe.ts +209 -0
- package/src/includes/webmonterey/compliance/ConsentInit.astro +74 -0
- package/src/includes/webmonterey/compliance/CookieConsent.astro +558 -0
- package/src/includes/webmonterey/compliance/consent-styles.test.ts +83 -0
- package/src/includes/webmonterey/compliance/consent.ts +142 -0
- package/src/includes/webmonterey/config.test.ts +94 -0
- package/src/includes/webmonterey/config.ts +346 -0
- package/src/includes/webmonterey/copy-defaults.ts +148 -0
- package/src/includes/webmonterey/copy.ts +13 -0
- package/src/includes/webmonterey/credits/Credit.astro +80 -0
- package/src/includes/webmonterey/credits/credit.test.ts +111 -0
- package/src/includes/webmonterey/credits/credit.ts +59 -0
- package/src/includes/webmonterey/forms/honeypot.test.ts +40 -0
- package/src/includes/webmonterey/forms/honeypot.ts +66 -0
- package/src/includes/webmonterey/prose/inline.test.ts +94 -0
- package/src/includes/webmonterey/prose/inline.ts +71 -0
- package/src/includes/webmonterey/scroll-top/ScrollTop.astro +209 -0
- package/src/includes/webmonterey/site.ts +136 -0
- package/src/includes/webmonterey/structured-data/nodes.ts +315 -0
- package/src/includes/webmonterey/zoned-hour.test.ts +49 -0
- package/src/integration/adapter.ts +53 -0
- package/src/integration/app-middleware.ts +43 -0
- package/src/integration/config.ts +96 -0
- package/src/integration/content.ts +66 -0
- package/src/integration/image-size.test.ts +83 -0
- package/src/integration/image-size.ts +100 -0
- package/src/integration/index.ts +386 -0
- package/src/integration/virtual.d.ts +101 -0
- package/src/layouts/base.astro +402 -0
- package/src/package.test.ts +121 -0
- package/src/pages/404.astro +33 -0
- package/src/pages/[...slug].astro +126 -0
- package/src/pages/robots.txt.ts +41 -0
- package/src/pages/webm.astro +23 -0
- package/src/scripts/.gitkeep +0 -0
- package/src/styles/base.css +185 -0
- package/src/styles/global.css +47 -0
- package/src/styles/layers.test.ts +32 -0
- package/src/styles/layers.ts +21 -0
- package/src/styles/layout.css +235 -0
- package/src/styles/reset.css +135 -0
- package/src/styles/utilities.css +90 -0
- package/src/worker.ts +76 -0
- package/template/assets/logo.svg +14 -0
- package/template/assets/open-graph.png +0 -0
- package/template/migrations/0001_create_submissions.sql +40 -0
- package/template/migrations/README.md +41 -0
- package/template/public/android-chrome-192x192.png +0 -0
- package/template/public/android-chrome-512x512.png +0 -0
- package/template/public/apple-touch-icon.png +0 -0
- package/template/public/favicon-16x16.png +0 -0
- package/template/public/favicon-32x32.png +0 -0
- package/template/public/favicon.ico +0 -0
- package/template/public/favicon.svg +4 -0
- package/template/public/open-graph.png +0 -0
- package/template/scripts/check-node.mjs +72 -0
- package/template/scripts/test-hooks.mjs +96 -0
- package/template/site/.editorconfig +22 -0
- package/template/site/.prettierignore +15 -0
- package/template/site/.prettierrc.json +17 -0
- package/template/site/CLAUDE.md +245 -0
- package/template/site/CONTENT.md +135 -0
- package/template/site/PRIVACY-POLICY-DRAFT.md +81 -0
- package/template/site/public/_headers +70 -0
- package/template/site/src/forms/contact.json +45 -0
- package/template/workflows/ci.yml +52 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# @cparkerwebm/webmonterey
|
|
2
|
+
|
|
3
|
+
Every published version, what changed, and whether it asks anything of you.
|
|
4
|
+
|
|
5
|
+
Entries answer one question: **should I move a site onto this, and does anything need doing
|
|
6
|
+
afterwards?** Versions are tagged in git — `git checkout v1.0.0` is the code inside that release —
|
|
7
|
+
and each has a [GitHub release](https://github.com/cparkerwebm/webmonterey/releases).
|
|
8
|
+
|
|
9
|
+
Upgrade a site with `npx webm upgrade`, then build and `npx webm compare` against the previous
|
|
10
|
+
build. See `/webm:upgrade`.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1.0.0 — 2026-09-02
|
|
15
|
+
|
|
16
|
+
The first public release, on npmjs. This is the framework as it stands after two private
|
|
17
|
+
generations and an ownership audit — not a rewrite, and not the same package renamed.
|
|
18
|
+
|
|
19
|
+
### What a site gets
|
|
20
|
+
|
|
21
|
+
- **The integration.** One call in `astro.config.mjs` derives `site` from `webmonterey.json`,
|
|
22
|
+
sets static output, wires the sitemap with noindex filtering, and provides the virtual modules
|
|
23
|
+
a package needs to read files in the repo it is installed into.
|
|
24
|
+
- **The design system as data.** `design.json` carries ~15 brand values over a 124-token
|
|
25
|
+
system; the compiler emits CSS custom properties, email-safe literals and brand context from
|
|
26
|
+
one file.
|
|
27
|
+
- **The cascade.** Eight layers in a fixed order, emitted inline ahead of every stylesheet
|
|
28
|
+
because a bare `@layer` statement does not survive bundling. Reset, base, layout and
|
|
29
|
+
utilities, with `src/styles/custom/` as the client's override seam.
|
|
30
|
+
- **The form pipeline.** Validate → honeypot → Turnstile (per-form opt-out) → D1 → notify →
|
|
31
|
+
autoresponse. Store before send. A form with nowhere to deliver refuses rather than saying
|
|
32
|
+
thank you.
|
|
33
|
+
- **Consent.** Consent Mode v2 defaults before GTM loads, GPC honored, a native `<dialog>`
|
|
34
|
+
whose decline buttons never leave the fold, and `whenConsented()` for every third party.
|
|
35
|
+
- **Staging never mails a real person.** `environment: "staging"` and any `workers.dev`
|
|
36
|
+
hostname redirect every recipient to `stagingEmail`. There is no default inbox in the package;
|
|
37
|
+
a staging site without one refuses to send and fails `webm doctor`.
|
|
38
|
+
- **The web app namespace, reserved.** `src/pages/webapp/` on every site; `app.path` in
|
|
39
|
+
`webmonterey.json` is the public URL, rewritten onto the folder by injected middleware when
|
|
40
|
+
it differs. Off by default; nothing runs until it is switched on.
|
|
41
|
+
- **Structured data as parts, not a verdict.** The package emits no JSON-LD of its own. A site
|
|
42
|
+
composes its graph from the builders in `@cparkerwebm/webmonterey/structured-data` and exports
|
|
43
|
+
it as `structuredData` from its registry; `/webm:launch` is where that gets written.
|
|
44
|
+
- **`webm` CLI:** `new`, `sync`, `doctor` (21 checks, each for a failure that stays silent),
|
|
45
|
+
`upgrade` (branch, install, codemods, resync), `compare` (text, head, JSON-LD and CSS of two
|
|
46
|
+
builds), `design:extract`.
|
|
47
|
+
- **Five skills**, materialized into `.claude/skills/webm/` on every install: `/webm:start`,
|
|
48
|
+
`/webm:launch`, `/webm:upgrade`, `/webm:new-component`, `/webm:traps`. A client's own skills
|
|
49
|
+
and agents sit beside the plugin folder and are never touched.
|
|
50
|
+
|
|
51
|
+
### What is deliberately absent
|
|
52
|
+
|
|
53
|
+
- **No registry credential anywhere.** Not in the scaffold, not in CI, not in Workers Builds.
|
|
54
|
+
- **No visible components.** Every block a visitor sees is built per client.
|
|
55
|
+
- **No `/webm` scratch page in a production build.** It exists in `astro dev` and nowhere else.
|
|
56
|
+
- **No default JSON-LD, no default inbox, no plan or tier anywhere in config.**
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Carl Parker
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# webmonterey
|
|
2
|
+
|
|
3
|
+
The Astro framework behind WebMonterey client sites, for Cloudflare Workers with D1, R2 and
|
|
4
|
+
Turnstile. Plumbing, the design system, and the Claude Code skills — everything that is the same
|
|
5
|
+
on every site, in one upgradable package.
|
|
6
|
+
|
|
7
|
+
Published as [`@cparkerwebm/webmonterey`](https://www.npmjs.com/package/@cparkerwebm/webmonterey)
|
|
8
|
+
on npmjs, MIT. It is an agency framework, published so the sites built on it are cleanly their
|
|
9
|
+
owners' and so a fix propagates on `npm update`. It is not a community project and is not
|
|
10
|
+
supported as one.
|
|
11
|
+
|
|
12
|
+
**[ARCHITECTURE.md](ARCHITECTURE.md) is the design and the reasoning.** Read it before changing
|
|
13
|
+
anything structural; most of what looks like an odd choice is a documented one.
|
|
14
|
+
|
|
15
|
+
## What the package owns, and what it does not
|
|
16
|
+
|
|
17
|
+
The package owns anything where a bug is the _same_ bug on every site: the cascade layer order,
|
|
18
|
+
the reset, the Cloudflare includes, the consent system, the form pipeline, the router.
|
|
19
|
+
|
|
20
|
+
It ships **zero visible components**. Every block a visitor sees is built per client, in that
|
|
21
|
+
client's repo. Every default has a documented way to opt out of it.
|
|
22
|
+
|
|
23
|
+
## Creating a client site
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npx @cparkerwebm/webmonterey new example.com --client="Example Co"
|
|
27
|
+
cd example_com
|
|
28
|
+
claude # then /webm:start
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`webm new` writes the identity and design files, a working contact form, a home page and the
|
|
32
|
+
fleet skills, then runs `git init` and `npm install`. It touches nothing outside the directory.
|
|
33
|
+
`/webm:start` takes it from there: the GitHub repo, Cloudflare resources, Workers Builds, the
|
|
34
|
+
first deploy. Start Claude from the repo root — project skills load from the directory you start
|
|
35
|
+
in.
|
|
36
|
+
|
|
37
|
+
Then `/webm:new-component` per block, and `/webm:launch` when the site is approved on a preview.
|
|
38
|
+
|
|
39
|
+
## Layout
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
src/
|
|
43
|
+
design/ design.json -> CSS, email literals, brand context. No Astro imports.
|
|
44
|
+
integration/ the Astro integration, the virtual modules, the app-path middleware
|
|
45
|
+
styles/ reset, base, layout, utilities - and layers.ts, the one layer-order list
|
|
46
|
+
includes/ plumbing, grouped by vendor first
|
|
47
|
+
layouts/ base.astro
|
|
48
|
+
pages/ the block router, robots.txt, the 404, the dev-only /webm scratch page
|
|
49
|
+
actions/ the form pipeline
|
|
50
|
+
emails/ transactional templates
|
|
51
|
+
cli/ the webm command
|
|
52
|
+
skills/ the fleet skills, materialized into client repos by `webm sync`
|
|
53
|
+
agents/ hooks/ ride along with the skills when the package ships any
|
|
54
|
+
template/ what `webm new` seeds and what `webm sync` refreshes
|
|
55
|
+
schema/ JSON Schema for design.json
|
|
56
|
+
examples/minimal a real site CI builds on every PR
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Commands
|
|
60
|
+
|
|
61
|
+
| Command | Runs |
|
|
62
|
+
| ------------------ | ---------------------------------------------------------------- |
|
|
63
|
+
| `npm test` | `node --test` over `src/**/*.test.ts` and `scripts/**/*.test.mjs` |
|
|
64
|
+
| `npm run check` | `tsc --noEmit` |
|
|
65
|
+
| `npm run format` | prettier |
|
|
66
|
+
| `npm run test:e2e` | pack a tarball, scaffold a site with it, build, assert on the HTML |
|
|
67
|
+
|
|
68
|
+
**No test framework and no test dependency.** Node's runner needs nothing installed and strips
|
|
69
|
+
TypeScript on its own.
|
|
70
|
+
|
|
71
|
+
## The pattern to follow when adding code
|
|
72
|
+
|
|
73
|
+
**Pure logic goes in a file with no virtual-module imports; the config binding goes beside it.**
|
|
74
|
+
`r2/url.ts` and `r2/media.ts` are the example. Anything importing `virtual:webm/site`
|
|
75
|
+
transitively only resolves inside an Astro build, so a test touching it cannot run.
|
|
76
|
+
|
|
77
|
+
## Node
|
|
78
|
+
|
|
79
|
+
`.nvmrc` pins 24, which is what Workers Builds runs. `engines` is `>=22.18.0`, the first release
|
|
80
|
+
with unflagged type stripping, which the CLI needs.
|
|
81
|
+
|
|
82
|
+
## Releasing
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
# 1. write the entry first - it is the release notes, not a chore afterwards
|
|
86
|
+
# add "## 1.1.0 — YYYY-MM-DD" to CHANGELOG.md, then commit and push
|
|
87
|
+
npm login # once per machine
|
|
88
|
+
npm run release minor # or patch, major, or an explicit 1.1.0
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
One command, in the order that makes each step safe: clean tree on `main` in sync with origin →
|
|
92
|
+
the changelog entry must exist → format, types and tests → `npm version` (which commits **and**
|
|
93
|
+
tags) → `npm publish --provenance` → push commit and tag and read both back off origin → GitHub
|
|
94
|
+
release from the changelog section → install the published tarball the way a client would.
|
|
95
|
+
|
|
96
|
+
`--dry-run` runs every check and prints the plan without changing anything. `prepublishOnly`
|
|
97
|
+
runs the same guard, so a bare `npm publish` still refuses to ship a version that is
|
|
98
|
+
undocumented, untagged, or built from a dirty tree.
|
|
99
|
+
|
|
100
|
+
| | |
|
|
101
|
+
| ------- | ------------------------------------------------ |
|
|
102
|
+
| `patch` | a fix that asks nothing of any site |
|
|
103
|
+
| `minor` | new capability, or a fix a site may want to know about |
|
|
104
|
+
| `major` | something a site must change to take — and it ships a codemod |
|
package/agents/.gitkeep
ADDED
|
File without changes
|