Prhub

#2489 docs: label-only sidebar groups, explicit Overview pages, scoped link color

原始 PR 作者 nblintao 合并时间 2026-08-14 05:20 文件变更 22 提交数 1 评论 0 代码增减 +181 / -161

执行摘要

文档导航统一为纯标签分组、Overview 落地页、链接色收窄

PR body 给出的核心动机是让侧边栏行为遵循一条可读的规则:"Makes the docs sidebar behave by one legible rule: section headers are labels, rows are pages, and the only collapsible items are the Models family catalogs." 具体要解决三个问题:未加作用域的 a 链接颜色规则压过 Mintlify 的 layered Tailwind 颜色,把侧边栏/标签栏/页内 TOC 全刷成橙色并掩盖当前页高亮;带 root 的分组标题会跳转、无 root 的只折叠,点击前无法区分;导航结构层级不统一(单分组 tab 也套了一层 groups)。无关联 Issue,设计说明全部由 PR body 承担。

值得快速浏览:本 PR 是文档工程化的不错样板 —— 把导航语义写成『生成器 + 钩子 + 约定文档 + 单测』四件套,并用页面数与 broken links 守恒作为自证回归证据。不需要精读源码;值得关注的决策点包括:用 sidebarTitle 分离 h1/SEO 标题与侧边栏短标签、以纯标签分组消灭『可点击与不可点击标题』的不一致、以及 pygrep 钩子一行代码锁死配置契约。后续维护者需留意 SECTION_DIRS 硬编码与生成器/手写双轨配置的扩展点。

讨论亮点

该 PR 全程零讨论:无 issue 评论、无 PR 评论、无行内 review 评论,reviewer Zhichenzzz 直接给予空 body 的 APPROVED。设计决策由作者在 PR body 中完整自述,并以四重机制(同步脚本 + pre-commit 钩子 + docs/README.md 约定 + 单元测试)固化,弥补了缺乏评审交锋的审查盲区。回归证据同样由 PR body 自我声明:页面总数 96 不变,mint broken-links 与 main 持平(25 个存量)。

实现拆解

  1. 链接颜色作用域收窄(docs/style.css):三条规则 aa:hovera[href^="http"]::after 分别改为 .mdx-content a.mdx-content a:hover.mdx-content a[href^="http"]。原因是未作用域的 a 规则属于 unlayered 层,会压过 Mintlify 的 layered Tailwind 颜色,把侧边栏、tabs、页内 TOC 全部刷成品牌橙 #d55816;收窄后自定义颜色与站外链接 ↗ 标记只作用于正文容器。
  2. 导航配置重构(docs/docs.json,+97/-143):移除所有导航分组 root 键,模型家族各组(DeepSeek、Thinking Machines、Qwen、GLM、Kimi、Nemotron、Gemma)的 index 页降为各组 pages 首项,gpt-oss 等单页直接挂到 Models 根组之下;Welcome、Resources、FAQ 三个单分组 tab 从 groups 包装扁平化为顶层 pages;User Guide 的 Launch Script 两页分组被扁平化(页面标题从 "Structure and Usage" 改回 "Launch Script");Advanced Features 与 Developer Guide 内的 Performance、Scale & Reliability、MoE & Routing、CI 等子组全部静态展开,仅 Models 家族保留 expanded: false 折叠。附带变更:navbar 新增 "Contact" 主按钮(mailto:miles@radixark.ai)。
  3. 同步脚本语义升级(scripts/tools/sync_example_docs.py):新增 SECTION_DIRS = ("infra_features",) 常量标记纯标签分组目录;render_page 通过 landing = rel_dir == "" or rel_dir in SECTION_DIRS 判定 landing 页,命中则注入 sidebarTitle: "Overview"title 保留完整值供 h1/SEO;build_navigation 从返回带 root/expanded 的 group 字典改为返回 entries 列表(examples/index 恒为首项,随后是不带 root 的 "Recipes"、"Infra Features" 分组,且 infra landing 页作为分组第一行);main() 相应改为 tab.pop("groups", None) 后写 tab["pages"]
  4. Landing 页批量打标(各 index.md)docs/index.md(title 从 "Miles Documentation" 改为 "Welcome" 并新增 sidebarTitle)、docs/models/{deepseek,gemma,glm,kimi,nemotron,qwen,thinkingmachines}/index.mddocs/advanced/index.mddocs/developer/index.mddocs/examples/index.md 等 frontmatter 统一追加 sidebarTitle: Overview
  5. 回归防护三件套docs/README.md 新增两段约定(landing 页 title 面向 h1/浏览器/搜索、sidebarTitle 是恒定字段名;禁止分组 root,正确做法是 landing 页作为 pages 首项);.pre-commit-config.yaml 新增 pygrep 钩子 ban-docs-nav-group-root(entry "root":,files 限定 ^docs/docs\.json$);tests/fast/doc/test_sync_example_docs.py 更新 test_navigation_follows_bullet_order 断言并新增 test_section_directory_becomes_rootless_group_with_landing_first,既有漂移门禁 test_docs_examples_matches_the_readmes(--check)保持不变,保证生成结果与提交内容一致。
文件 模块 状态 重要度
scripts/tools/sync_example_docs.py 同步脚本 modified 6.25
docs/docs.json 导航配置 modified 5.4
tests/fast/doc/test_sync_example_docs.py 同步测试 modified 4.98
.pre-commit-config.yaml 提交钩子 modified 3.37
docs/style.css 站点样式 modified 2.99
docs/README.md 文档约定 modified 2.43
docs/index.md 站点首页 modified 1.99

关键符号

build_navigation render_page main parse_index test_section_directory_becomes_rootless_group_with_landing_first test_navigation_follows_bullet_order

关键源码片段

scripts/tools/sync_example_docs.py core-logic

Examples tab 导航生成器,随本次约定同步升级:build_navigation 改为输出无 root 的 pages 列表(index 首项 + 纯标签分组),render_page 对 landing 页注入 sidebarTitle: Overview,main() 从写 groups 改为写 pages。

# 需要渲染为纯标签侧边栏分组的目录:目录自己的 README 作为分组第一行
# (侧边栏显示 Overview),而不是作为 group `root` —— root 会使分组标题
# 变成可点击链接,与纯折叠分组外观无法区分(已被 pre-commit 禁止)。
SECTION_DIRS = ("infra_features",)
​
​
def render_page(title, description, rel_dir, body):
    source = f"{repo_dir_of(rel_dir)}/README.md"
    # 只有 tab 首页(rel_dir == "")与 section 目录首页写入 sidebarTitle:
    # 页面保留完整 title(供 h1 / SEO),侧边栏统一显示短标签 Overview。
    landing = rel_dir == "" or rel_dir in SECTION_DIRS
    sidebar = 'sidebarTitle: "Overview"\n' if landing else ""
    return (
        "---\n"
        f"title: {json.dumps(title, ensure_ascii=False)}\n"
        f"{sidebar}"
        f"description: {json.dumps(description, ensure_ascii=False)}\n"
        f"# Generated from {source} by scripts/tools/sync_example_docs.py. Edit that README, not this file.\n"
        "---\n"
        f"{body}\n"
    )
​
​
def build_navigation(pages, bullet_order):
    """生成 Examples tab 的 pages 列表:index 最前,随后是纯标签分组。    侧边栏顺序遵循 examples/README.md 的 bullet 顺序(README 拥有排序、
    标题与描述);没有 bullet 的目录排最后、按字母序。返回的 entries
    不含任何 group `root` —— Examples tab 在 main() 里直接写入
    tab["pages"],而不再包一层 groups。
    """
    rank = {rel_dir: i for i, rel_dir in enumerate(bullet_order)}
    recipes, infra = [], []
    for rel_dir in sorted(pages, key=lambda d: (rank.get(d, len(rank)), d)):
        if not rel_dir:
            continue
        page = f"examples/{slug_for(rel_dir)}"
        # infra_features 目录归入 Infra Features 分组,其余全部归入 Recipes
        (infra if rel_dir.startswith("infra_features") else recipes).append(page)
    entries = ["examples/index"]
    entries.append({"group": "Recipes", "pages": recipes})
    if infra:
        infra_root = "examples/infra-features"
        children = [p for p in infra if p != infra_root]
        # landing 页作为分组第一行出现,分组自身不设 root、不设 expanded
        entries.append({"group": "Infra Features", "pages": [infra_root] + children})
    return entries
docs/style.css core-logic

修复全局 a 规则把侧边栏、tabs、页内 TOC 刷成橙色并掩盖活动页高亮的问题:链接颜色与站外链接 ↗ 标记限定在 .mdx-content 正文容器内。

/*
 * 链接颜色只作用于正文容器 .mdx-content:未加作用域的 a 规则属于
 * unlayered 层,会压过 Mintlify 的 layered Tailwind 颜色,把侧边栏、
 * tab 栏、页内 TOC 全部刷成橙色,并掩盖当前页高亮。收窄后自定义
 * 颜色只出现在正文内容区。
 */
.mdx-content a {
  color: #d55816;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}.mdx-content a:hover {
  text-decoration-thickness: 2px;
}/* 站外链接自动追加 ↗ 符号,同样限定在正文容器内 */
.mdx-content a[href^="http"]:not([href*="radixark.com"])::after {
  content: "↗";
  margin-left: 0.15em;
  font-size: 0.7em;
}

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  • pre-commit 规则一刀切(.pre-commit-config.yaml)ban-docs-nav-group-root 以 pygrep 精确匹配 "root": 键,当前不会误伤其他键;但若未来 Mintlify 导航 schema 或文档站自身需要合法 root 用途,该钩子会直接拦截,需要调整匹配范围。
  • 生成器与手写配置双轨(scripts/tools/sync_example_docs.py vs docs/docs.json):Examples tab 完全由生成器接管,main() 现在显式 tab.pop("groups", None) 并写入 pages,手改 Examples 段会被 --check 漂移门禁拦截;而 User Guide/Advanced 等 tab 仍为手写,两套来源并存,语义必须保持一致。
  • SECTION_DIRS 硬编码("infra_features",) 写死,未来新增 section 类目录(如把某组升级为纯标签分组)必须同步改代码,否则该目录会被静默归入 Recipes 分组,产生与期望不符的导航。
  • CSS 依赖 Mintlify DOM(docs/style.css).mdx-content 是 Mintlify 生成的容器类名,若平台改版导致类名变化,正文链接颜色与 ↗ 标记会静默失效(不破坏布局但丢失定制样式)。
  • 导航语义变化对读者的影响:所有分组标题不再可点击、落地页变成显式 "Overview" 行,习惯点击分组标题跳转的读者需要适应;URL 全部不变,无书签/外链破坏。

影响范围限定在 docs 站点与文档维护工具链,不涉及训练、rollout、session 等任何运行时模块。对读者:侧边栏语义统一(标签不跳转、行才是页面)、活动页高亮恢复、站外链接 ↗ 与橙色仅出现在正文,导航可预期性明显提升。对团队:docs 贡献者必须遵守新约定(禁止 root、landing 页 sidebarTitle: Overview、Examples tab 由生成器独占),否则提交被 pre-commit 拦截或漂移测试失败;导航结构的增删改成本被工具化。页面数与 broken links 均无变化,说明这是一次无页面增删的纯结构重构。

零 review 讨论 pre-commit 规则一刀切 SECTION_DIRS 硬编码 生成器与手写配置双轨

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论