@clize/clize 0.32.0 → 0.34.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/README.md +20 -18
- package/dist/cli.js +487 -374
- package/dist/cli.js.map +1 -1
- package/dist/core/addresses.js +12 -11
- package/dist/core/addresses.js.map +1 -1
- package/dist/core/analytics.js +6 -5
- package/dist/core/analytics.js.map +1 -1
- package/dist/core/authz.js +6 -5
- package/dist/core/authz.js.map +1 -1
- package/dist/core/billing.js +83 -12
- package/dist/core/billing.js.map +1 -1
- package/dist/core/credentials.js +3 -1
- package/dist/core/credentials.js.map +1 -1
- package/dist/core/dns.js +3 -2
- package/dist/core/dns.js.map +1 -1
- package/dist/core/domain-health.js +74 -50
- package/dist/core/domain-health.js.map +1 -1
- package/dist/core/domains.js +74 -44
- package/dist/core/domains.js.map +1 -1
- package/dist/core/email-tx.js +8 -6
- package/dist/core/email-tx.js.map +1 -1
- package/dist/core/email.js +13 -12
- package/dist/core/email.js.map +1 -1
- package/dist/core/env-detect.js +7 -14
- package/dist/core/env-detect.js.map +1 -1
- package/dist/core/handle.js +33 -30
- package/dist/core/handle.js.map +1 -1
- package/dist/core/install.js +132 -59
- package/dist/core/install.js.map +1 -1
- package/dist/core/media.js +37 -36
- package/dist/core/media.js.map +1 -1
- package/dist/core/payments.js +5 -4
- package/dist/core/payments.js.map +1 -1
- package/dist/core/projects.js +38 -26
- package/dist/core/projects.js.map +1 -1
- package/dist/core/redirect.js +4 -3
- package/dist/core/redirect.js.map +1 -1
- package/dist/core/seo-classify.js +41 -1
- package/dist/core/seo-classify.js.map +1 -1
- package/dist/core/seo-pages.js +214 -0
- package/dist/core/seo-pages.js.map +1 -0
- package/dist/core/seo.js +147 -11
- package/dist/core/seo.js.map +1 -1
- package/dist/core/serve.js +2 -1
- package/dist/core/serve.js.map +1 -1
- package/dist/core/setup.js +11 -9
- package/dist/core/setup.js.map +1 -1
- package/dist/core/shop.js +17 -16
- package/dist/core/shop.js.map +1 -1
- package/dist/core/site.js +2 -1
- package/dist/core/site.js.map +1 -1
- package/dist/core/sites.js +41 -40
- package/dist/core/sites.js.map +1 -1
- package/dist/core/triage.js +39 -5
- package/dist/core/triage.js.map +1 -1
- package/dist/core/video.js +45 -43
- package/dist/core/video.js.map +1 -1
- package/dist/github.js +4 -3
- package/dist/github.js.map +1 -1
- package/dist/i18n/t.js +65 -0
- package/dist/i18n/t.js.map +1 -0
- package/dist/i18n/zh.js +1266 -0
- package/dist/i18n/zh.js.map +1 -0
- package/dist/index.js +61 -40
- package/dist/index.js.map +1 -1
- package/dist/lib/cloudflare.js +8 -7
- package/dist/lib/cloudflare.js.map +1 -1
- package/dist/lib/crypto.js +2 -1
- package/dist/lib/crypto.js.map +1 -1
- package/dist/lib/vercel.js +2 -1
- package/dist/lib/vercel.js.map +1 -1
- package/dist/lib/zone.js +2 -1
- package/dist/lib/zone.js.map +1 -1
- package/dist/mcp-profiles.js +5 -1
- package/dist/mcp-profiles.js.map +1 -1
- package/dist/providers/deploy/cloudflare.js +3 -2
- package/dist/providers/deploy/cloudflare.js.map +1 -1
- package/dist/providers/email/cloudflare-inbound.js +4 -3
- package/dist/providers/email/cloudflare-inbound.js.map +1 -1
- package/dist/providers/email/cloudflare-outbound.js +2 -1
- package/dist/providers/email/cloudflare-outbound.js.map +1 -1
- package/dist/providers/email/resend.js +3 -2
- package/dist/providers/email/resend.js.map +1 -1
- package/dist/providers/email/ses.js +3 -2
- package/dist/providers/email/ses.js.map +1 -1
- package/dist/providers/index.js +3 -2
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/media/google.js +10 -9
- package/dist/providers/media/google.js.map +1 -1
- package/dist/providers/media/kie.js +12 -11
- package/dist/providers/media/kie.js.map +1 -1
- package/dist/providers/media/kunavo.js +10 -9
- package/dist/providers/media/kunavo.js.map +1 -1
- package/dist/providers/media/openai.js +5 -4
- package/dist/providers/media/openai.js.map +1 -1
- package/dist/providers/media/suno.js +7 -6
- package/dist/providers/media/suno.js.map +1 -1
- package/dist/providers/registrar/routing.js +2 -1
- package/dist/providers/registrar/routing.js.map +1 -1
- package/dist/providers/registrar/vercel.js +2 -1
- package/dist/providers/registrar/vercel.js.map +1 -1
- package/dist/providers/seo/dataforseo.js +5 -4
- package/dist/providers/seo/dataforseo.js.map +1 -1
- package/dist/providers/seo/gsc.js +31 -4
- package/dist/providers/seo/gsc.js.map +1 -1
- package/dist/remote.js +25 -22
- package/dist/remote.js.map +1 -1
- package/dist/selfcheck.js +23 -22
- package/dist/selfcheck.js.map +1 -1
- package/dist/state/file-store.js +17 -16
- package/dist/state/file-store.js.map +1 -1
- package/package.json +4 -3
- package/skills/clize/SKILL.md +171 -143
- package/skills/clize-seo/SKILL.md +290 -187
- package/skills/clize-site-build/SKILL.md +97 -41
- package/skills/clize-site-debug/SKILL.md +73 -45
|
@@ -1,63 +1,119 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clize-site-build
|
|
3
3
|
description: >-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
Use when the user wants a website or landing page built from scratch (a consulting site, a SaaS
|
|
5
|
+
landing page, a portfolio, an event page): run `clize build site start` for the hosted design method
|
|
6
|
+
and a style recommendation, generate a static site with real taste and no AI-template look, then
|
|
7
|
+
ship it with clize deploy. Triggers: "build me a site", "make a landing page", "generate a website
|
|
8
|
+
for X", "从零做个站 / 落地页". You (the agent) write the content and code; clize provides the design
|
|
9
|
+
method, the images (paid, ask the user first) and the deploy.
|
|
8
10
|
---
|
|
9
11
|
|
|
10
|
-
# clize site build
|
|
12
|
+
# clize site build — design method + deploy
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
You (the brain) generate the site; clize provides the **design method** (a hosted style library) and the
|
|
15
|
+
**deploy**. To get a site with character rather than a generic template, **do not improvise** — follow the
|
|
16
|
+
method `clize build site` returns at runtime.
|
|
13
17
|
|
|
14
|
-
##
|
|
15
|
-
1.
|
|
16
|
-
2.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- `clize build site
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
## Flow
|
|
19
|
+
1. Confirm with the user: site type / brand / one-line positioning / which sections.
|
|
20
|
+
2. **Fetch the method + recommendation**: `clize build site start "<one-line brief>" --name <site name>` —
|
|
21
|
+
returns the design method, a style recommendation (style / palette / fonts) and the next steps.
|
|
22
|
+
**Follow the steps it returns exactly** (fetch the chosen style's full constitution, freeze a `DESIGN.md`
|
|
23
|
+
as the single source of truth, apply it across the whole page, self-review at the end). Useful:
|
|
24
|
+
- `clize build site list` — every style
|
|
25
|
+
- `clize build site get <slug>` — a style's full constitution (color / type / shape / signature moves)
|
|
26
|
+
plus its **imagery contract**
|
|
27
|
+
- `clize build site stack <stack> [keywords]` — implementation guide for a stack
|
|
28
|
+
- `clize build site review` — the self-review checklist (with pre-flight commands you can run)
|
|
29
|
+
3. **Generate** into `./site/`: `index.html` (self-contained) plus any `assets/`.
|
|
30
|
+
4. **Images (💰 paid → ask the user first, quote first).** Whether the site needs images is decided by the
|
|
31
|
+
**`imagery` contract** returned by `clize build site get <slug>`, not by feel: `need: "none"` (pure
|
|
32
|
+
typography / CSS aesthetics) → **do not force images**; `"optional"` → only if the brief really calls for
|
|
33
|
+
them; `"essential"` (editorial / park / archive styles that rest on photography) → **real images are
|
|
34
|
+
structural; without them the site is not finished** (the hosted process's Step 6.5 says the same). When
|
|
35
|
+
images are needed, **never generate silently and never leave placeholders**: list the image slots per the
|
|
36
|
+
contract (prompts from the contract's `promptHints` + the industry context), ask the user "generate the
|
|
37
|
+
images with clize?" and give an estimate: `clize gen image` costs about **$0.04–0.06 per image**; the
|
|
38
|
+
contract's `count` is the usual number (3–6 images ≈ **$0.2–0.4**). For an exact figure run
|
|
39
|
+
`clize gen image "<prompt>" --out ./site/img/hero.png` (**without --confirm**) → the CLI returns
|
|
40
|
+
`📋 Quote about $X`; report that number. **Add `--confirm` only after the user agrees.** For a batch,
|
|
41
|
+
have the user pre-approve one round in the conversation (e.g. "go ahead with this round at $0.05 each"),
|
|
42
|
+
then still pass `--confirm` per image — every charge stays in `clize audit`. If the user declines →
|
|
43
|
+
use their own images or ship an image-free layout; never force it. (Details in the clize skill,
|
|
44
|
+
"Media".)
|
|
45
|
+
5. **Local preview (optional, before shipping)**: `clize serve ./site` — a static server with Range support
|
|
46
|
+
that does not force no-store on media; check in a browser or with `/browse`. **Do not use
|
|
47
|
+
`python -m http.server` for pages with `<video>`** (no Range support, and home-made static servers often
|
|
48
|
+
send media as no-store → Safari will not play, `<video>` reports `MEDIA_ERR_SRC_NOT_SUPPORTED`;
|
|
49
|
+
`clize serve` handles it).
|
|
50
|
+
6. Ship: `clize deploy ./site --domain <host>` (multi-file; a free handle or a custom domain).
|
|
25
51
|
|
|
26
|
-
> `clize build site`
|
|
52
|
+
> `clize build site` needs a hosted login (`clize login`): the design method and the style library live in
|
|
53
|
+
> clize's cloud and are served at runtime; just follow what they say. Without a login it tells you to run
|
|
54
|
+
> `clize login`.
|
|
27
55
|
|
|
28
|
-
##
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
-
|
|
56
|
+
## Boundaries
|
|
57
|
+
- Content / code are yours (the brain); design method + deploy are clize's (the hands).
|
|
58
|
+
- Once you have the constitution from `clize build site`, **apply it strictly across the whole page; do
|
|
59
|
+
not drift halfway**.
|
|
60
|
+
- Do not decide the substance of the brand / copy for the user — ask when unsure.
|
|
61
|
+
- **Images cost money** (💰) — same as `domain buy`: without `--confirm` you only get a quote. Tell the user
|
|
62
|
+
"N images, about $X" and wait for their yes; never generate silently.
|
|
33
63
|
|
|
34
|
-
##
|
|
64
|
+
## Turning the site into a store that takes real money (e-commerce / payment pages)
|
|
35
65
|
|
|
36
|
-
|
|
66
|
+
When the user wants "orders and payments", add `clize shop` on top of the static site above. **Division of
|
|
67
|
+
labour: clize is the shell + the payment wiring + the order ledger; business logic (stock / tax /
|
|
68
|
+
shipping / customer accounts) stays with the merchant** (their Stripe + their own systems). clize **does
|
|
69
|
+
not store the product catalog** (it ships with the site; the price source of truth is the site's
|
|
70
|
+
`_catalog.json`); **orders are held by clize** (orders table + event stream, `shop orders / todo / fulfill /
|
|
71
|
+
refund`); stock / tax / shipping / customer accounts remain the merchant's — do not treat clize as a
|
|
72
|
+
Shopify.
|
|
37
73
|
|
|
38
|
-
|
|
39
|
-
1. `clize shop init [--
|
|
40
|
-
2.
|
|
74
|
+
**How to build it (you write the content, clize takes the payment):**
|
|
75
|
+
1. `clize shop init [--shop <host>]` — prints the integration contract (the three things below); follow it.
|
|
76
|
+
2. **The catalog = `_catalog.json` in the site** (you generate it; it is the only trusted price source; the
|
|
77
|
+
client only sends SKUs, so prices cannot be forged):
|
|
41
78
|
```json
|
|
42
79
|
{ "currency": "usd",
|
|
43
80
|
"products": [{ "sku": "tee-blk-m", "name": "Black Tee (M)", "price": 25.0, "image": "/img/tee.jpg" }] }
|
|
44
81
|
```
|
|
45
|
-
|
|
46
|
-
|
|
82
|
+
Changing a price = edit this file and `clize deploy` again. **Do not make clize manage the catalog**;
|
|
83
|
+
100k SKUs belong in the merchant's own system.
|
|
84
|
+
3. **Add-to-cart buttons and the runtime on the page** (clize ships `cart.js`; you do not write a cart):
|
|
47
85
|
```html
|
|
48
|
-
<button data-clize-add="tee-blk-m"
|
|
49
|
-
<button data-clize-checkout
|
|
86
|
+
<button data-clize-add="tee-blk-m">Add to cart</button>
|
|
87
|
+
<button data-clize-checkout>Checkout</button> <span data-clize-count></span>
|
|
50
88
|
<script src="/_clize/cart.js"></script>
|
|
51
89
|
```
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
90
|
+
**Give real feedback (important)**: `cart.js` only handles the mechanics (add / count / jump to Stripe);
|
|
91
|
+
**the visible cart UX is your job** — a clear cart badge, an "added ✓" hint, a cart drawer or page; do
|
|
92
|
+
not rely on a bare `data-clize-count` (otherwise clicks feel like "nothing happened"). You can call
|
|
93
|
+
`window.clizeCart.add(sku, qty)` / `.checkout()` / `.count()` / `.clear()` for custom interactions.
|
|
94
|
+
Note: checking out an empty cart only shows `alert("Your cart is empty")`; gate the button state
|
|
95
|
+
yourself for a better experience.
|
|
96
|
+
4. `clize deploy ./site --domain <host>` (ships `_catalog.json` with it).
|
|
97
|
+
5. **Zero-config payments** (auto-detected; nothing for you to do; the site takes money once it is live):
|
|
98
|
+
- Today: every payment lands in the merchant's **clize balance** (no fee, not withdrawable, spendable on
|
|
99
|
+
clize services only).
|
|
100
|
+
- Direct payout to the merchant's **own Stripe** (withdrawable) is **not enabled on the platform yet**;
|
|
101
|
+
once it is, the merchant connects Stripe on the web and it switches automatically, with no site change
|
|
102
|
+
and no redeploy. Until then, **do not** send the merchant to connect Stripe.
|
|
103
|
+
6. `clize shop status` shows readiness (with order counts); `clize shop orders` / `shop todo` show orders
|
|
104
|
+
and today's to-do; fulfillment primitives: `shop fulfill <id> --supplier-order|--tracking|--delivered`
|
|
105
|
+
(shipping registers with 17TRACK and drafts the shipping email) → `shop notify <id> --confirm` sends the
|
|
106
|
+
notification → `shop refund <id> [--reason] --confirm` refunds (💰 preview by default);
|
|
107
|
+
`shop webhook <url>` pushes `order.paid/sourced/shipped/delivered/refunded/disputed` events to your
|
|
108
|
+
fulfillment / dropship endpoint (`shop events --since` replays them). Buyers check their orders at the
|
|
109
|
+
site's `/orders` page (free).
|
|
58
110
|
|
|
59
|
-
|
|
111
|
+
**The payment page** is Stripe's hosted Checkout (a redirect); Stripe emails the receipt. Checkout calls the
|
|
112
|
+
same-origin `/_clize/checkout`; every secret stays in the clize control plane and no key ever appears in the
|
|
113
|
+
merchant's site.
|
|
60
114
|
|
|
61
|
-
|
|
115
|
+
**Forms / waitlists** (non-payment): the page POSTs to `/_clize/data/<collection>`; configure the receiver
|
|
116
|
+
first with `clize data webhook <collection> <url>` — clize forwards and stores nothing.
|
|
62
117
|
|
|
63
|
-
>
|
|
118
|
+
> Wanting "strict no-oversell stock / automatic supplier orders / member login on the site": that is the
|
|
119
|
+
> merchant's own backend (their system or their own Cloudflare), outside the clize storefront.
|
|
@@ -1,92 +1,120 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clize-site-debug
|
|
3
3
|
description: >-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Use when the user says a site or domain deployed with clize "does not open, is unreachable, was deployed
|
|
5
|
+
but nothing changed, still shows the placeholder page". Systematic diagnosis. clize site hosting = the
|
|
6
|
+
shared worker clize-handle-site + the KV namespace clize-sites, served by hostname; domains bind to the
|
|
7
|
+
worker as Cloudflare Workers custom domains. On v0.22.0+ run `clize domain check <domain>` first (one
|
|
8
|
+
command, four layers: registry delegation via DoH → zone → binding → content); if that does not locate
|
|
9
|
+
it, work by hand in the order proxy → content layer (KV) → binding layer (workers/domains) → DNS layer
|
|
10
|
+
(zone/NS); Vercel-registered domains need their NS moved to Cloudflare. Triggers: "my site does not
|
|
11
|
+
open", "X is unreachable", "deployed but no effect", "still the placeholder", "我的站打不开".
|
|
9
12
|
---
|
|
10
13
|
|
|
11
|
-
# clize
|
|
14
|
+
# A clize-hosted site does not open — systematic diagnosis
|
|
12
15
|
|
|
13
|
-
clize
|
|
16
|
+
clize site hosting = the shared worker **`clize-handle-site`** + the KV namespace **`clize-sites`**; the
|
|
17
|
+
worker reads `${host}${path}` from KV by hostname (no content → the placeholder page). A domain reaches the
|
|
18
|
+
worker through a **Cloudflare Workers custom domain**, which requires the zone to be on Cloudflare and
|
|
19
|
+
**active** (NS pointing at Cloudflare).
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
"Does not open" almost always means one link in that chain is broken.
|
|
16
22
|
|
|
17
|
-
##
|
|
23
|
+
## Try one command first (v0.22.0+)
|
|
18
24
|
|
|
19
25
|
```bash
|
|
20
|
-
clize domain check
|
|
21
|
-
clize domain check
|
|
26
|
+
clize domain check <domain> # four layers: registry delegation (public authoritative DoH) → CF zone → worker binding → KV content, with fix suggestions
|
|
27
|
+
clize domain check # no domain = a light check of every domain, listing the unreachable ones
|
|
22
28
|
```
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
It uses **public authoritative DNS** as the truth (immune to local proxy illusions and to CF's cached zone
|
|
31
|
+
status) and directly locates registry-delegation faults like the June 2026 outage (NXDOMAIN / NS pointing
|
|
32
|
+
elsewhere). Note that the `status` in `domain list` is the access mode (registered / external / handle /
|
|
33
|
+
pending), **not health**; do not judge by it. The platform also sweeps every 30 minutes and emails the
|
|
34
|
+
account address (set with `clize account email`) when a domain stays broken.
|
|
25
35
|
|
|
26
|
-
`domain check`
|
|
36
|
+
If `domain check` does not locate it, or you need TLS / edge / KV-key detail, go through the four manual
|
|
37
|
+
steps below. **In order; do not skip.**
|
|
27
38
|
|
|
28
|
-
## 0.
|
|
39
|
+
## 0. Rule out the local proxy first (the most common misdiagnosis; always step one)
|
|
29
40
|
|
|
30
|
-
|
|
41
|
+
If the user's machine runs Clash / Surge (TUN / fake-ip mode), `dig` resolves the domain to **`198.18.x.x`**
|
|
42
|
+
(the fake-ip range) or **cannot reach public DNS**. In that state every local `dig` / `curl` / browser
|
|
43
|
+
result is **untrustworthy** — the site may be perfectly fine and only blocked by the local proxy.
|
|
31
44
|
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
- `WebFetch https
|
|
35
|
-
- `WebFetch "https://dns.google/resolve?name
|
|
36
|
-
-
|
|
45
|
+
- Signs: `dig +short A <domain>` returns `198.18.*` / `198.19.*`, or `dig @1.1.1.1 <domain>` times out.
|
|
46
|
+
- Fix: **verify from the cloud, not the machine**:
|
|
47
|
+
- `WebFetch https://<domain>` — fetch the real content from the cloud / see whether it responds.
|
|
48
|
+
- `WebFetch "https://dns.google/resolve?name=<domain>&type=NS"` — the authoritative NS.
|
|
49
|
+
- Have the user **turn off the proxy / switch to mobile data** and try once more; many "does not open"
|
|
50
|
+
reports end right here.
|
|
37
51
|
|
|
38
|
-
## 1.
|
|
52
|
+
## 1. Content layer: did the site actually land in KV?
|
|
39
53
|
|
|
40
54
|
```bash
|
|
41
55
|
NSID=$(curl -s ".../accounts/<ACCT>/storage/kv/namespaces?per_page=100" "${A[@]}" | jq -r '.result[]|select(.title=="clize-sites").id')
|
|
42
|
-
curl -s ".../accounts/<ACCT>/storage/kv/namespaces/$NSID/keys?limit=1000" "${A[@]}" | jq -r '.result[].name' | grep -i "
|
|
56
|
+
curl -s ".../accounts/<ACCT>/storage/kv/namespaces/$NSID/keys?limit=1000" "${A[@]}" | jq -r '.result[].name' | grep -i "<domain>"
|
|
43
57
|
```
|
|
44
|
-
|
|
58
|
+
Keys like `<domain>/index.html` exist → the deploy's KV write succeeded; go to step 2. Nothing → the site
|
|
59
|
+
was never deployed; run `clize deploy ./site --domain <domain>` again.
|
|
45
60
|
|
|
46
|
-
## 2.
|
|
61
|
+
## 2. Binding layer: is the domain bound to handle-site?
|
|
47
62
|
|
|
48
63
|
```bash
|
|
49
|
-
curl -s ".../accounts/<ACCT>/workers/domains" "${A[@]}" | jq -r '.result[]|select(.service=="clize-handle-site").hostname' | grep -i "
|
|
64
|
+
curl -s ".../accounts/<ACCT>/workers/domains" "${A[@]}" | jq -r '.result[]|select(.service=="clize-handle-site").hostname' | grep -i "<domain>"
|
|
50
65
|
```
|
|
51
|
-
|
|
66
|
+
Present → the binding is fine (if it still does not open, go back to step 0 or wait for SSL). **Absent →
|
|
67
|
+
the domain is not attached to the worker (the most common cause)**; go to step 3.
|
|
52
68
|
|
|
53
|
-
## 3. DNS
|
|
69
|
+
## 3. DNS layer: is the CF zone active / does the NS point at CF?
|
|
54
70
|
|
|
55
71
|
```bash
|
|
56
|
-
curl -s ".../zones?name
|
|
72
|
+
curl -s ".../zones?name=<domain>" "${A[@]}" | jq -r '.result[0]|{id, status, name_servers}'
|
|
57
73
|
```
|
|
58
|
-
- `status=active` → NS
|
|
59
|
-
- `status=pending` → **NS
|
|
74
|
+
- `status=active` → the NS is on CF; jump to step 5 and bind.
|
|
75
|
+
- `status=pending` → **the NS is not delegated to CF**; that is the break. A CF-registered domain should
|
|
76
|
+
already have its NS on CF (abnormal; check the NS records); a **Vercel-registered domain** defaults to
|
|
77
|
+
`vercel-dns.com` and must be switched → step 4.
|
|
60
78
|
|
|
61
|
-
## 4. ⚠️
|
|
79
|
+
## 4. ⚠️ The NS trap for Vercel-registered domains
|
|
62
80
|
|
|
63
|
-
Vercel
|
|
81
|
+
Vercel-registered domains (`boughtAt` set, `serviceType:"zeit.world"`) use Vercel DNS by default. Switch to CF:
|
|
64
82
|
```bash
|
|
65
|
-
# CF
|
|
66
|
-
curl -s -X PATCH ".../v1/registrar/domains
|
|
83
|
+
# the two CF nameservers = the name_servers from step 3
|
|
84
|
+
curl -s -X PATCH ".../v1/registrar/domains/<domain>/nameservers?teamId=<TEAM>" \
|
|
67
85
|
-H "Authorization: Bearer <VERCEL_TOKEN>" -H "Content-Type: application/json" \
|
|
68
86
|
-d '{"nameservers":["xxx.ns.cloudflare.com","yyy.ns.cloudflare.com"]}'
|
|
69
87
|
```
|
|
70
|
-
|
|
88
|
+
**The trap**: after switching, Vercel's own `nameservers` / `intendedNameservers` fields **lag** (still
|
|
89
|
+
showing vercel-dns); only `customNameservers` holds what you set. **Do not trust Vercel's fields** — check
|
|
90
|
+
the **registry's authoritative NS** with `WebFetch "https://dns.google/resolve?name=<domain>&type=NS"`;
|
|
91
|
+
seeing `cloudflare.com` means the switch worked. (Lesson: Vercel-registered domains **can** be switched to
|
|
92
|
+
CF; the earlier "NS locked" belief came from that lagging field.)
|
|
71
93
|
|
|
72
|
-
## 5.
|
|
94
|
+
## 5. Fix: activate the zone + bind the custom domain
|
|
73
95
|
|
|
74
96
|
```bash
|
|
75
|
-
#
|
|
97
|
+
# ask CF to re-check the NS now (pending → active)
|
|
76
98
|
curl -s -X PUT ".../zones/<ZID>/activation_check" "${A[@]}"
|
|
77
|
-
# zone active
|
|
99
|
+
# once the zone is active, bind the custom domain to handle-site
|
|
78
100
|
curl -s -X PUT ".../accounts/<ACCT>/workers/domains" "${A[@]}" \
|
|
79
101
|
-H "Content-Type: application/json" \
|
|
80
|
-
-d '{"hostname":"
|
|
102
|
+
-d '{"hostname":"<domain>","service":"clize-handle-site","environment":"production","zone_id":"<ZID>"}'
|
|
81
103
|
```
|
|
82
|
-
|
|
104
|
+
Binding succeeded + KV has content → the site is live immediately (SSL is issued automatically; the first
|
|
105
|
+
visit may take a few dozen seconds).
|
|
83
106
|
|
|
84
|
-
##
|
|
107
|
+
## Auth cheat sheet / placeholders
|
|
85
108
|
|
|
86
|
-
- CF API base
|
|
87
|
-
- Vercel base
|
|
88
|
-
- `<ACCT>` / `<ZID>` / `<NSID
|
|
109
|
+
- CF API base: `https://api.cloudflare.com/client/v4`; auth `A=(-H "X-Auth-Email: <email>" -H "X-Auth-Key: <CF global key>")`.
|
|
110
|
+
- Vercel base: `https://api.vercel.com`; auth `-H "Authorization: Bearer <VERCEL_TOKEN>"` + `?teamId=<TEAM>`.
|
|
111
|
+
- `<ACCT>` / `<ZID>` / `<NSID>`: look them up with the list endpoints above; never hard-code.
|
|
89
112
|
|
|
90
113
|
---
|
|
91
114
|
|
|
92
|
-
>
|
|
115
|
+
> **This diagnosis is now built into deploy**: `ensureZoneActiveForHandle` in
|
|
116
|
+
> [`src/core/sites.ts`](../../src/core/sites.ts) creates the zone / switches the NS (Vercel domains) /
|
|
117
|
+
> activates / binds during `clize deploy`, and a failed binding **is an error** (no more
|
|
118
|
+
> `.catch(() => {})` false success). New deploys therefore rarely hit this; the skill is mainly for
|
|
119
|
+
> **legacy sites** (from the period when the bug reported success without binding) and for **verifying**
|
|
120
|
+
> live domains after the fact. Building a site is the `clize-site-build` skill.
|