把 9 个文件里的 11 处 claudecode-haha.relakkesyang.org 换成 cchaha.ai。 apex 走 Cloudflare CNAME flattening,www 由 GitHub 自动 301 到裸域名。 - docs/public/CNAME 与 prepare-static-output.mjs 的 expectedCustomDomain 必须同步:后者是硬校验,不一致会让 postbuild 直接 throw、Pages 发不出去。 它同时驱动 canonical / hreflang / og:url / sitemap.xml / robots.txt。 - meta.js 的 SITE_ORIGIN 管前端运行时那一份同名标签。 - AGENTS.md 里的契约描述一并更新,否则后续改动会照旧域名回退。 - 桌面端 IM 文档跳转链接及其测试断言。 验证:site build 通过(78 路由 + 74 重定向)、check:docs 通过(78 页 323 链接)、 sitemap 80 条 loc 全为新域名、AdapterSettings 6 tests passed。
3.5 KiB
React Site Instructions
These rules apply to the public landing page and documentation experience under site/.
Contracts that must not break
- Keep the site independently installable with
npm ciand buildable withnpm run build. - Keep
npm run checkdeterministic, offline, and responsible for site-specific validation beyond compilation. - Preserve the GitHub Pages custom-domain contract; production assets and routes must work from the root of
cchaha.ai.scripts/prepare-static-output.mjshard-fails when the CNAME drifts. - Treat files under
docs/as the source of truth for long-form Chinese and English documentation. Keep paired public routes aligned when both languages exist. - Do not copy private user state, credentials, local filesystem paths, or unredacted product screenshots into the site.
- Run
bun run check:docsafter site or docs changes and include desktop plus narrow-mobile browser evidence for user-visible layout changes.
How content reaches the site
scripts/generate-docs-manifest.mjs scans docs/, then emits three things into src/generated/ (gitignored):
docs-index.js— the eager index: route, section, title,nav_title, description,order. Keep it small; it ships on every page.content/<id>.js— one module per document holding the markdown body (frontmatter already stripped).docsContentmaps a route to a dynamic import, so opening one page never downloads the rest.search-index.js— lazily imported by the search dialog only.
Routes come from file paths (docs/start/install.md → /start/install). Renaming a file renames its URL, so add the old path to both LEGACY_ROUTES in src/content/docs.js and legacyRoutes in scripts/prepare-static-output.mjs.
Sidebar grouping comes from the sections array in the generator — register any new top-level docs/ directory there or it sorts last with a bare directory name. Order inside a group comes from each document's order frontmatter.
Design system
src/styles/base.css holds every token. The palette is lifted from the desktop app's 「纸·墨·印」 themes — light mirrors 纯白, dark mirrors 墨夜 — so the site and the app read as one product. Rules:
- Use tokens (
--surface-*,--text-*,--border*,--brand*,--sp-*,--fs-*,--r-*) rather than literal values. A raw hex in a component is a bug. - The primary button is ink (
--ink), turning terracotta (--brand) on hover. It is not brand-coloured at rest. - Depth comes from 1px borders and surface layering, not heavy shadows.
- Both themes must work.
data-themeon<html>is set by the bootstrap script inindex.htmlbefore first paint. - Breakpoints are 1180 / 900 / 620 across both stylesheets. Do not introduce a fourth.
Mermaid
````mermaid fences render as diagrams. Nothing under docs/ currently uses one — the two pages that did were deleted in the July 2026 restructure — so the dependency and its .doc-mermaid styles sit unused, lazily loaded and costing readers nothing. Keep them: internals/ is exactly where a diagram would earn its place, and the mermaid theme is already wired to the site tokens.
Fonts
Self-hosted in public/fonts/, copied from desktop/public/fonts/. Never add a Google Fonts @import or <link> — it is unreachable from mainland China and would leave every heading in a fallback serif. Only the latin subsets are hosted; Chinese glyphs fall through to the platform font on purpose, exactly as the desktop app does.