@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.
Files changed (116) hide show
  1. package/README.md +20 -18
  2. package/dist/cli.js +487 -374
  3. package/dist/cli.js.map +1 -1
  4. package/dist/core/addresses.js +12 -11
  5. package/dist/core/addresses.js.map +1 -1
  6. package/dist/core/analytics.js +6 -5
  7. package/dist/core/analytics.js.map +1 -1
  8. package/dist/core/authz.js +6 -5
  9. package/dist/core/authz.js.map +1 -1
  10. package/dist/core/billing.js +83 -12
  11. package/dist/core/billing.js.map +1 -1
  12. package/dist/core/credentials.js +3 -1
  13. package/dist/core/credentials.js.map +1 -1
  14. package/dist/core/dns.js +3 -2
  15. package/dist/core/dns.js.map +1 -1
  16. package/dist/core/domain-health.js +74 -50
  17. package/dist/core/domain-health.js.map +1 -1
  18. package/dist/core/domains.js +74 -44
  19. package/dist/core/domains.js.map +1 -1
  20. package/dist/core/email-tx.js +8 -6
  21. package/dist/core/email-tx.js.map +1 -1
  22. package/dist/core/email.js +13 -12
  23. package/dist/core/email.js.map +1 -1
  24. package/dist/core/env-detect.js +7 -14
  25. package/dist/core/env-detect.js.map +1 -1
  26. package/dist/core/handle.js +33 -30
  27. package/dist/core/handle.js.map +1 -1
  28. package/dist/core/install.js +132 -59
  29. package/dist/core/install.js.map +1 -1
  30. package/dist/core/media.js +37 -36
  31. package/dist/core/media.js.map +1 -1
  32. package/dist/core/payments.js +5 -4
  33. package/dist/core/payments.js.map +1 -1
  34. package/dist/core/projects.js +38 -26
  35. package/dist/core/projects.js.map +1 -1
  36. package/dist/core/redirect.js +4 -3
  37. package/dist/core/redirect.js.map +1 -1
  38. package/dist/core/seo-classify.js +41 -1
  39. package/dist/core/seo-classify.js.map +1 -1
  40. package/dist/core/seo-pages.js +214 -0
  41. package/dist/core/seo-pages.js.map +1 -0
  42. package/dist/core/seo.js +147 -11
  43. package/dist/core/seo.js.map +1 -1
  44. package/dist/core/serve.js +2 -1
  45. package/dist/core/serve.js.map +1 -1
  46. package/dist/core/setup.js +11 -9
  47. package/dist/core/setup.js.map +1 -1
  48. package/dist/core/shop.js +17 -16
  49. package/dist/core/shop.js.map +1 -1
  50. package/dist/core/site.js +2 -1
  51. package/dist/core/site.js.map +1 -1
  52. package/dist/core/sites.js +41 -40
  53. package/dist/core/sites.js.map +1 -1
  54. package/dist/core/triage.js +39 -5
  55. package/dist/core/triage.js.map +1 -1
  56. package/dist/core/video.js +45 -43
  57. package/dist/core/video.js.map +1 -1
  58. package/dist/github.js +4 -3
  59. package/dist/github.js.map +1 -1
  60. package/dist/i18n/t.js +65 -0
  61. package/dist/i18n/t.js.map +1 -0
  62. package/dist/i18n/zh.js +1266 -0
  63. package/dist/i18n/zh.js.map +1 -0
  64. package/dist/index.js +61 -40
  65. package/dist/index.js.map +1 -1
  66. package/dist/lib/cloudflare.js +8 -7
  67. package/dist/lib/cloudflare.js.map +1 -1
  68. package/dist/lib/crypto.js +2 -1
  69. package/dist/lib/crypto.js.map +1 -1
  70. package/dist/lib/vercel.js +2 -1
  71. package/dist/lib/vercel.js.map +1 -1
  72. package/dist/lib/zone.js +2 -1
  73. package/dist/lib/zone.js.map +1 -1
  74. package/dist/mcp-profiles.js +5 -1
  75. package/dist/mcp-profiles.js.map +1 -1
  76. package/dist/providers/deploy/cloudflare.js +3 -2
  77. package/dist/providers/deploy/cloudflare.js.map +1 -1
  78. package/dist/providers/email/cloudflare-inbound.js +4 -3
  79. package/dist/providers/email/cloudflare-inbound.js.map +1 -1
  80. package/dist/providers/email/cloudflare-outbound.js +2 -1
  81. package/dist/providers/email/cloudflare-outbound.js.map +1 -1
  82. package/dist/providers/email/resend.js +3 -2
  83. package/dist/providers/email/resend.js.map +1 -1
  84. package/dist/providers/email/ses.js +3 -2
  85. package/dist/providers/email/ses.js.map +1 -1
  86. package/dist/providers/index.js +3 -2
  87. package/dist/providers/index.js.map +1 -1
  88. package/dist/providers/media/google.js +10 -9
  89. package/dist/providers/media/google.js.map +1 -1
  90. package/dist/providers/media/kie.js +12 -11
  91. package/dist/providers/media/kie.js.map +1 -1
  92. package/dist/providers/media/kunavo.js +10 -9
  93. package/dist/providers/media/kunavo.js.map +1 -1
  94. package/dist/providers/media/openai.js +5 -4
  95. package/dist/providers/media/openai.js.map +1 -1
  96. package/dist/providers/media/suno.js +7 -6
  97. package/dist/providers/media/suno.js.map +1 -1
  98. package/dist/providers/registrar/routing.js +2 -1
  99. package/dist/providers/registrar/routing.js.map +1 -1
  100. package/dist/providers/registrar/vercel.js +2 -1
  101. package/dist/providers/registrar/vercel.js.map +1 -1
  102. package/dist/providers/seo/dataforseo.js +5 -4
  103. package/dist/providers/seo/dataforseo.js.map +1 -1
  104. package/dist/providers/seo/gsc.js +31 -4
  105. package/dist/providers/seo/gsc.js.map +1 -1
  106. package/dist/remote.js +25 -22
  107. package/dist/remote.js.map +1 -1
  108. package/dist/selfcheck.js +23 -22
  109. package/dist/selfcheck.js.map +1 -1
  110. package/dist/state/file-store.js +17 -16
  111. package/dist/state/file-store.js.map +1 -1
  112. package/package.json +4 -3
  113. package/skills/clize/SKILL.md +171 -143
  114. package/skills/clize-seo/SKILL.md +290 -187
  115. package/skills/clize-site-build/SKILL.md +97 -41
  116. 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
- 当用户想"从零做个网站 / 落地页"(咨询站、SaaS 落地页、作品集、活动页等),用这个 skill:
5
- `clize build site start` 取设计方法 + 风格推荐(托管),据此生成有气质、不带 AI 味的静态站,
6
- clize deploy 上线。触发:"做个站"、"帮我做个落地页"、"生成一个 X 网站"、"从零做个咨询站"。
7
- 内容 / 代码你(agent)生成;clize 出设计方法、配图(文生图 · 花钱前先问用户)、部署。
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
- ()生成站点;clize **设计方法**(托管的风格库)+ **部署**。要做出有调性、非通用模板的站,**别凭空发挥** —— `clize build site` 运行时返回的方法走。
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. **取方法 + 推荐**:`clize build site start "<一句话 brief>" --project <名>` —— 返回设计方法 + 风格推荐(风格 / 调色板 / 字体)+ 后续步骤。**严格照它返回的步骤做**(包括取选定风格的完整宪法、冻一份 `DESIGN.md` 作唯一真源、整页贯彻、最后自审)。常用:
17
- - `clize build site list` —— 看全部风格
18
- - `clize build site get <slug>` —— 取某风格的完整宪法( / / / 签名手法)+ **imagery 配图契约**
19
- - `clize build site stack <stack> [关键词]` —— 取技术栈实现指南
20
- - `clize build site review` —— 取自审清单(含可直接跑的预检命令)
21
- 3. **生成**到 `./site/`:`index.html`(自包含)+ 需要的 `assets/`。
22
- 4. **配图(💰 花钱 → 先问用户、先报价)**:要不要图不靠临场感觉 —— `clize build site get <slug>` 返回的 **`imagery` 契约**说了算:`need: "none"`(纯排版 / CSS 美学)**别硬配图**;`"optional"` 看 brief 是否真需要;`"essential"`(editorial / park / archive 这类摄影承重的风格)**真图是结构件,没图等于没建完**(托管 process 的 Step 6.5 同此)。要配图时**别默默生成、也别留占位图** —— 先按契约列图位清单(prompt 用契约的 `promptHints` + 行业语境),问用户「要不要用 clize 生成配图?」并给预估:`clize gen image` 约 **$0.04–0.06/张**,契约的 `count` 即常用张数(如 3–6 张 ≈ **$0.2–0.4**)。要精确数就先跑 `clize gen image "<prompt>" --out ./site/img/hero.png`(**不带 --confirm**)→ CLI 回 `📋 报价约 $X`,把这个数报给用户。**用户同意了才加 `--confirm` 生成**;多图迭代先 `clize gen budget set <usd>` 预批额度。用户不要生成 → 用他自备的图 / 出无图版式,别硬生成。(细节见 clize skill 的"生成媒体")
23
- 5. **本地预览(可选,上线前看一眼)**:`clize serve ./site` —— 起支持 Range·媒体不灌 no-store 的本地 server,浏览器 / `/browse` 看效果。**含 `<video>` 的页面别用 `python -m http.server`**(不支持 Range,且自定义静态 server 常给媒体灌 no-store → Safari 不播、`<video>` 报 `MEDIA_ERR_SRC_NOT_SUPPORTED`;`clize serve` 已内置正确处理)。
24
- 6. 上线:`clize deploy ./site --domain <host>`(多文件;免费 handle 或自定义域)
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` 需登录托管模式(`clize login`):设计方法 + 风格库都在 clize 云端、运行时按需下发,你照它做即可。没登录时它会提示去 `clize login`。
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
- - 内容 / 代码由你生成();设计方法 + 部署由 clize (手脚)
30
- - 拿到 `clize build site` 返回的宪法后,**整页严格贯彻、别中途漂移**。
31
- - 不替用户决定品牌 / 文案的实质 —— 拿不准就问。
32
- - **配图要花钱**(💰)—— `domain buy`:缺 `--confirm` 只报价、不生成。生成前把"几张 + 预估 $X"告诉用户、等他点头;绝不默默生成花钱。
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
- 用户要"能下单收钱"时,在上面静态站之上接 `clize shop`。**分工铁律:clize 只做壳 + 收款 + 接线;商业逻辑(库存 / 退款 / / 运费 / 客户账户)全归商家**(走他的 Stripe + 他自己的系统)。clize **不存商品、不存订单** —— 别想着让 clize 当 Shopify。
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
- **怎么搭(你生成内容,clize 收款):**
39
- 1. `clize shop init [--domain <host>]` —— 打印接入契约(下面三样),照着做。
40
- 2. **商品目录 = 站点里的 `_catalog.json`**(你生成,价格的唯一可信源;客户端只传 sku,价它伪造不了):
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
- 改价 = 改这个文件重新 `clize deploy`。**别让 clize 管目录**;10 SKU 这种用商家自己的系统。
46
- 3. **页面里放加购按钮 + 引运行时**(clize 提供 `cart.js`,你不用写购物车):
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">加入购物车</button>
49
- <button data-clize-checkout>结账</button> <span data-clize-count></span>
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
- **给真实反馈(重要)**:`cart.js` 只管机制(加购 / 计数 / 跳转 Stripe),**可见的购物车 UX 是你的活** —— 做明显的购物车角标、"已加入 ✓" 提示、购物车抽屉或页,别只靠裸 `data-clize-count`(否则用户点了会觉得「没反应」)。可调 `window.clizeCart.add(sku,qty)` / `.checkout()` / `.count()` / `.clear()` 自定义交互。注意:空车点 `data-clize-checkout` 只弹一个 `alert("购物车为空")`,要更好体验就自己 gate 按钮状态。
53
- 4. `clize deploy ./site --domain <host>`(连 `_catalog.json` 一起上线)。
54
- 5. **收款零配置**(auto-detect,不用你做任何事,站上线就能收):
55
- - 缺省 **Mode A**:进商家的 **clize 余额**(不抽成、不可提现、只能花在 clize 服务)。适合自用 / 收入反哺 clize,不适合一般零售。
56
- - 商家**本人**去 https://clize.ai/app#/billing 连接自己的 Stripe(要登录 Stripe KYC,agent 跑不了 onboarding)→ 自动切 **Mode B**:钱进商家**自己的 Stripe**、可提现,clize 抽成。**真零售让商家去连这个**;连上即生效,不用改站、不用重 deploy。
57
- 6. `clize shop status` 查就绪(含订单计数);`clize shop orders` / `shop todo` 看单与今日操作清单;履约走原语 `shop fulfill <id> --supplier-order|--tracking|--delivered`(发货自动注册 17TRACK + 出发货邮件草稿)→ `shop notify <id> --confirm` 发通知 → `shop refund <id> [--reason] --confirm` 退款(💰 默认预览);`shop webhook <url>` 把 `order.paid/sourced/shipped/delivered/refunded/disputed` 事件推给你的履约 / dropship 端点(`shop events --since` 可回放补拉)。买家在站点 `/orders` 自助查单(白得)。
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
- **支付页**走 Stripe 托管 Checkout(跳转);客户收据 Stripe 自动发。结账同源打 `/_clize/checkout`,密钥都在 clize 控制面,商家站里不出现任何 key。
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
- **表单 / 候补**(非支付):页面 POST `/_clize/data/<collection>`,先 `clize data webhook <collection> <url>` 配好接收端 —— clize 只转发、不存。
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
- > 想要"自营库存严格不超卖 / 供应商自动下单 / 站内会员登录"这类:那是商家自己后端的活(他的系统或他自己的 CF),不在 clize 店面范围内。
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
- 当用户说某个用 clize 部署的站点 / 域名「打不开、访问不了、部署了但没生效、还是占位页」时,用这个 skill 系统排查。
5
- clize 站点托管 = 共享 worker clize-handle-site + KV clize-sites,按 hostname serve;域名经 CF Workers custom domain 绑到 worker。
6
- v0.22.0+ 先跑 `clize domain check <域名>`(一条命令四层体检:注册局委派 DoH zone 绑定 内容);
7
- 没定位到再按「先排代理 内容层(KV) 绑定层(workers/domains) DNS 层(zone/NS)」手工四步,Vercel 注册域名要切 NS→CF。
8
- 触发:"我的站打不开"、"X 域名访问不了"、"deploy 了没生效"、"还是占位页"、"freevideocompressor 这种站不能用"。
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 站点托管 = 共享 worker **`clize-handle-site`** + KV **`clize-sites`**,worker 按 hostname 从 KV 取 `${host}${path}`(无内容→占位页)。域名通过 **CF Workers custom domain** 绑到这个 worker,要求域名 zone 在 CF 且 **active**(NS 指向 CF)。
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
- ## 先试一条命令(v0.22.0+)
23
+ ## Try one command first (v0.22.0+)
18
24
 
19
25
  ```bash
20
- clize domain check <域名> # 四层体检:注册局委派(DoH 公网权威)→ CF zone → worker 绑定 → KV 内容,带修复建议
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
- 它以**公网权威 DNS 为准**(不吃本机代理假象、不信 CF zone 缓存),能直接定位 2026-06 断链事故那类注册局委派故障(NXDOMAIN / NS 指向别处)。注意 `domain list` `status` 是接入方式(registered/external/pending),**不代表健康**,别拿它判断。平台每 30 分钟还会自动巡检,持续异常向账户邮箱(`clize account email` 配置)发告警。
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` 没定位到、或要查 TLS/边缘/KV key 细节时,再走下面手工四步。**按顺序查,别跳步。**
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
- 用户本机若跑 Clash/Surge(TUN / fake-ip 模式),`dig` 会把域名解析到 **`198.18.x.x`**(fake-ip 段)或**连不上公共 DNS**。这种情况本机 `dig` / `curl` / 浏览器结果**全部不可信** —— 站点可能完全正常,只是被本机代理拦了。
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
- - 判据:`dig +short A <域名>` 返回 `198.18.*` / `198.19.*`,或 `dig @1.1.1.1 <域名>` 超时。
33
- - 对策:**从云端验证,别信本机**:
34
- - `WebFetch https://<域名>` —— 从云端抓真实内容 / 看能否访问。
35
- - `WebFetch "https://dns.google/resolve?name=<域名>&type=NS"` —— 查权威 NS
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. 内容层:站点真写进 KV 了吗
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
- `<域名>/index.html` key → deploy 的「写 KV」成功了,进第 2 步。没有 站点根本没部署,重新 `clize deploy ./site --domain <域名>`。
58
+ Keys like `<domain>/index.html` existthe 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. 绑定层:域名绑到 handle-site 了吗
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
- 绑定 OK(若仍打不开,回第 0 步查代理 / SSL)。**没有 域名没接到 worker(最常见的打不开原因)**,进第 3 步。
66
+ Presentthe 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 层:CF zone active / NS CF
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=<域名>" "${A[@]}" | jq -r '.result[0]|{id, status, name_servers}'
72
+ curl -s ".../zones?name=<domain>" "${A[@]}" | jq -r '.result[0]|{id, status, name_servers}'
57
73
  ```
58
- - `status=active` → NS 已指 CF,直接跳第 5 步绑定。
59
- - `status=pending` → **NS 没委派给 CF**,这是断点。CF 注册的域名 NS 本应在 CF(异常,查 NS 记录);**Vercel 注册的域名**默认 `vercel-dns.com`,要切 4 步。
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. ⚠️ Vercel 注册域名的 NS
79
+ ## 4. ⚠️ The NS trap for Vercel-registered domains
62
80
 
63
- Vercel 注册(`boughtAt` 有值、`serviceType:"zeit.world"`)的域名默认用 Vercel DNS。切到 CF:
81
+ Vercel-registered domains (`boughtAt` set, `serviceType:"zeit.world"`) use Vercel DNS by default. Switch to CF:
64
82
  ```bash
65
- # CF 的两个 NS = 3 步查到的 name_servers
66
- curl -s -X PATCH ".../v1/registrar/domains/<域名>/nameservers?teamId=<TEAM>" \
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
- **关键坑**:切完后 Vercel 自己的 `nameservers` / `intendedNameservers` 字段**会显示滞后**(还写着 vercel-dns),只有 `customNameservers` 是你设的值。**别信 Vercel 的字段** —— 用 `WebFetch "https://dns.google/resolve?name=<域名>&type=NS"` 查**注册局权威 NS**,看到 `cloudflare.com` 就是切成功了。(经验:Vercel 注册域名的 NS **是能切到 CF 的**,之前「NS 锁死」是被这个滞后字段误导。)
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. 修复:激活 zone + custom domain
94
+ ## 5. Fix: activate the zone + bind the custom domain
73
95
 
74
96
  ```bash
75
- # CF 立即重查 NS(pending→active)
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 后,绑 custom domain handle-site
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":"<域名>","service":"clize-handle-site","environment":"production","zone_id":"<ZID>"}'
102
+ -d '{"hostname":"<domain>","service":"clize-handle-site","environment":"production","zone_id":"<ZID>"}'
81
103
  ```
82
- 绑成功 + KV 有内容站点立刻上线(SSL 自动签,首访可能等几十秒)。
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:`https://api.cloudflare.com/client/v4`;认证 `A=(-H "X-Auth-Email: <email>" -H "X-Auth-Key: <CF global key>")`。
87
- - Vercel base:`https://api.vercel.com`;认证 `-H "Authorization: Bearer <VERCEL_TOKEN>"` + `?teamId=<TEAM>`。
88
- - `<ACCT>` / `<ZID>` / `<NSID>` 都用上面的 list 接口现查,别硬编码。
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
- > **此排查流程已固化进部署**:[`src/core/sites.ts`](../../src/core/sites.ts) `ensureZoneActiveForHandle` 会在 `clize deploy` 时自动建 zone / 切 NS(Vercel 域名)/ 激活 / 绑定,且绑定失败会**报错**(不再 `.catch(()=>{})` 假成功)。所以新部署一般不会再出这问题;这个 skill 主要用于**排查历史遗留**(那次 bug 期间「假成功」但没真接上的站)和**事后核验**已上线域名。建站流程见 `clize-site-build` skill。
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.