> ## Documentation Index
> Fetch the complete documentation index at: https://docs.widerouter.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CLAUDE

# 项目配置 - WideRouter 文档中心

## 项目概述

基于 Mintlify 的文档网站，为 WideRouter（API Router 子品牌）提供技术文档。

产品形态是**统一的异步任务式调用**：图片与视频共用同一套创建/查询端点，
换模型基本只改请求体参数。因此**文档的叙事重心是「参数差异」，不是「端点差异」**。
这条决定了信息架构：模型页是一张对照矩阵，不是一堆按供应商分的接入指南。

## 多语言体系（重要）

**英文是源语言，放仓库根目录。人工只维护英文和简体中文两版，其余由 `scripts/i18n/` 管线生成。**

| 语种             | 目录         | 产出方式        | 翻译源    | 覆盖范围   |
| -------------- | ---------- | ----------- | ------ | ------ |
| English `en`   | 仓库根目录      | **人工**      | —      | 全部     |
| 简体中文 `zh`      | `zh/`      | **人工**      | en     | 全部     |
| 繁體中文 `zh-Hant` | `zh-Hant/` | OpenCC 本地转换 | **zh** | 核心 Tab |
| 日本語 `ja`       | `ja/`      | 翻译 API      | en     | 核心 Tab |
| 한국어 `ko`       | `ko/`      | 翻译 API      | en     | 核心 Tab |
| Русский `ru`   | `ru/`      | 翻译 API      | en     | 核心 Tab |

语言矩阵与「核心 Tab」的定义都在 `scripts/i18n/config.mjs`，**那是唯一的配置源**。

### 注意方向：与常见做法相反

日韩俄的源是**根目录英文**，所以它们永远不会陈旧。会陈旧的是 `zh-Hant/` ——
它的源是人工的 `zh/`。**改了英文页不改中文页，繁体版会跟着旧。**
`npm run i18n` 每次会比对两者的最后提交时间并告警，但**不阻断**，别依赖它兜底。

### 铁律

1. **`zh-Hant/` `ja/` `ko/` `ru/` 是构建产物，任何情况下都不要手工编辑 mdx。**
   下一次跑管线会整目录重建，手改必然丢失。pre-commit 会拦。
2. **译文有问题不要改 mdx**：繁体改 `scripts/i18n/overrides/zh-Hant.json`，
   日韩俄改 `scripts/i18n/glossary/<lang>.json`，导航标签改 `scripts/i18n/labels.json`，
   然后重跑管线。
3. **`docs.json` 里只手工维护 `en` 和 `zh` 两个 language 块**，其余由 `sync-nav.mjs` 整块重建。

### 写完新页面之后

```bash theme={null}
npm run i18n      # = i18n:hant + i18n:tr + i18n:nav + i18n:check
npm run links     # 全仓坏链检查
```

在本机手动执行，不走 CI（Mintlify 由 push 触发部署，CI 写回 commit 会和本机编辑打架）。

几个容易混的开关：

* `--force` 越过**成本闸门**和**篡改保护**，但**不越过增量缓存**
* `--redo` 才是越过增量缓存强制重翻，配合 `--only` 用来修个别页
* `--repair` 对已有译文重跑确定性修复，**完全不调 API**
* `--plan` 只打印计划，不写盘、不加锁

**不要并发跑 `translate.mjs`**，会互相覆盖 manifest。管线已带进程锁，会直接拒绝。

先看规模：`npm run i18n:plan`。

## 文档编写规范

### MDX 格式

* **禁止在正文使用 H1**（`# 标题`）。Mintlify 会从 frontmatter 的 `title` 自动生成 H1，
  再写一个会重复。正文从 `##` 起。
* **frontmatter 必须有 `title`**，强烈建议有 `description`。
* 不使用 HTML 注释语法，用 JSX 注释 `{/* ... */}`。

### 每一条都由 pre-commit 强制，破坏后果都是页面级故障

* **`$` 转义方向，正文和 frontmatter 相反**
  * MDX 正文（含表格）：必须写 `\$`，否则被 LaTeX 数学模式吞掉
  * Frontmatter（YAML）：直接写 `$`。`\$` 不是合法 YAML 转义序列，会导致解析失败
* **标题里不要用半角 `%`**，用全角 `％`。半角会让 Mintlify **SSR 500**。
* **JSX 属性值里禁止再出现 ASCII 双引号**。第二个 `"` 一定提前闭合属性，
  后面的中文被当 attribute name 解析报错。中文场景用「」，或外层换单引号。
  解析失败常常**级联**触发 docs.json 报「file does not exist」——
  定位时优先排查最近一次编辑的 JSX 属性。
* **JSX 标签必须配平。**
* **外部链接限制**：非第一方域名（`widerouter.com` / `apiyi.com`）不用超链接，
  改为纯文本 + 反引号，让用户主动复制。
* **小于号**：`<` 后紧跟数字会被当成标签起始，写成「少于 20」或 `&lt;20`。

### 品牌名

**统一写 `WideRouter`**，一个词、驼峰、无空格。`Wide Router` / `Widerouter` /
`widerouter`（散文中）都会被拦。域名 `widerouter.com` 和环境变量
`WIDEROUTER_API_KEY` 不受影响。

### 页面标题不要中英混排

`title` / `sidebarTitle` 只用单一语言。英文页只写英文，中文页只写中文，
不要写成 `原生工具出图（Responses image_generation）` 这种括号混排。

### 时间必须标注时区

涉及具体时间时必须附时区（`18:30 (UTC+8)`），因为有全球客户。校验器会告警。

### 新建页面必须英中双语同步

每创建一个新页面，必须同时产出英文版（根目录）和中文版（`zh/`），文件名一致，
并在 `docs.json` 的 `en` 和 `zh` 两块导航中**同时**注册（位置一致）。

* 英文页内部链接用 `/api/...`，中文页用 `/zh/api/...`
* **人工只产出这两版**，其余四个语种由管线生成

## 校验与钩子

```bash theme={null}
npm run check                         # 全仓文档规范体检
npm run check -- --files a.mdx b.mdx  # 指定文件
npm run secrets                       # 全量 Key 扫描
npm run links                         # 坏链检查
SKIP_DOC_CHECK=1 git commit           # 临时跳过文档校验
SKIP_SECRET_SCAN=1 git commit         # 临时跳过 Key 扫描
```

**每个克隆执行一次**：`npm run hooks:install`

### 一个设计要点，改规则时别退回去

`check-docs.mjs` 支持 `--staged` 下的**行级作用域**（只校验本次新增的行），
但本仓当前把**所有规则都放进了 `ALWAYS`**，即整文件判定。

这是新仓库独有的红利：有历史债务的仓库按整文件判定的话，改个错别字都会被
存量问题拦下，钩子一周内就会被 `--no-verify` 绕过。本仓第一天零存量，可以全部拦截。

**行级作用域的机械照样保留，不要因为「现在用不上」就删掉。** 存量债务必然会出现，
那时候把某条规则从 `ALWAYS` 里挪出来是一行改动，重新实现整套 `addedLines` 则不是。

## API Key 不入库（pre-commit 拦截）

任何真实 API Key 都不许写进仓库，测试脚本一律从环境变量读：

```python theme={null}
API_KEY = os.environ["WIDEROUTER_API_KEY"]   # ✅
API_KEY = "sk-your-api-key"                  # ✅ 占位符，带连字符，扫描器会放过
```

占位符统一写成带连字符的形式。放行方式：行尾加 `allow-secret`，
或写进 `.secretsallow`，或 `git commit --no-verify`。

## test/ 目录规范（测试产物不入库）

`test/` 存放各渠道/模型的实测记录。**只提交「结论与可复现的东西」，不提交「跑出来的产物」。**

| 提交 ✅                          | 不提交 ❌                                        |
| ----------------------------- | -------------------------------------------- |
| `测试计划.md`、`测试报告.md`、`分析结果.md` | `logs/` — 每次调用的响应记录                          |
| `summary.csv` 等结构化汇总          | `previews/`、`compare/` — 缩略图与对比图             |
| `scripts/` — 能重跑出全部产物的脚本      | `outputs/`、`results/` — 出图、视频等原件             |
| 少量必要的输入素材、`*.env.example`     | `*.mp4` / `*.mov` / `*.webm` / `*.body.json` |

规则在 `.gitignore` 的 `test/` 段落，按目录名匹配（末尾 `*` 覆盖 `logs-0711/`
这类变体），新建测试目录沿用这几个目录名即可自动生效。

**理由不是洁癖**：产物体积比结论大几个数量级且可由 `scripts/` 完整重新生成。
姊妹仓库没有这条规则时，单个 `logs/*.body.json` 达 35MB、`results/*.mp4` 达 48MB，
是 `.git` 膨胀到数 GB 的直接原因。

确有个别文件必须入库，用 `git add -f <file>` 单独豁免，并在报告里说明原因。

### 推荐结构

```
test/<厂商或模型>/<MMDD-主题>/
├── 测试计划.md  测试报告.md  分析结果.md  summary.csv   ✅
├── scripts/     assets/                              ✅
└── logs/  outputs/                                   ❌ 自动忽略
```

## 三层内容边界

| 层        | 内容                               | 机制                                  |
| -------- | -------------------------------- | ----------------------------------- |
| 公开发布     | 根目录英文、`zh/`、`models/`、`openapi/` | Mintlify 构建                         |
| 入库但不发布   | `test/`、`scripts/`、`data/`       | `.mintignore`                       |
| **永不入库** | 密钥、上游渠道身份、合同条款、内部毛利口径            | `.gitignore` + `check-secrets` + 人眼 |

**第三层没有自动化能完全兜住。** 写内容时自己把关。

## 尚未搭建（按蓝图的后续步骤）

* `openapi/widerouter.yaml` 单一规格 + 生成式本地化（`build-openapi-i18n.mjs`）
* `data/models.json` + 三个消费者（参数矩阵页 / 单模型页 / OpenAPI 变体注入）
* `build-changelog.mjs`
* `.claude/skills/`（写作类入库，带密钥的放 `.claude/skills/local/` 不入库）
