你拥有所有代码
布局、组件、内容、样式——站点的每一个可见部分都存放在你的仓库中。脚手架工具写入一次后便退到一旁。从那一刻起,项目就是你的:编辑任何文件、重构任何目录、修改任何默认值。无需等待上游 API,也无需 fork 固执己见的主题。
编码智能体的工作方式和你一样。当没有什么重要的东西藏在 import 边界后面时,智能体能更好地理解整个仓库。
- my-docs/
- src/
- components/
- content/docs/
- layouts/
- pages/
- styles/
- globals.css
- components.ts
- astro.config.ts
- package.json
- src/
交互式内容,完全属于你
值得阅读的文档往往需要展示机制——请求如何流转、状态如何嵌套、接口如何对接。你要么采用预设样式的组件库并继承其外观,要么从零开始构建交互部分。Nimbus 将问题一分为二。
nimbus-docs/react 提供一个无样式的 <Diagram> 包装器以及可组合的 hooks——usePhase、useMeasure、useTabIndicator、useDiagram。包装器负责那些难以做好的事情:离屏暂停、尊重减少动画偏好、键盘快捷键、错误边界、跨岛屿协调。它本身不渲染任何可见内容。
最小的有意义示例——usePhase 走两个步骤,渲染的节点依次亮起。<DiagramControls> 通过注册表安装;其余部分来自 nimbus-docs/react。
import { Diagram, usePhase } from "@cloudflare/nimbus-docs/react";
import { DiagramControls } from "@/components/react/diagram";
function PingPong() {
const { current } = usePhase({
steps: [{ id: "left", hold: 1500 }, { id: "right", hold: 1500 }],
loop: true,
});
return (
<div className="flex items-center justify-center gap-12 py-12">
<Node label="Left" active={current === "left"} />
<Node label="Right" active={current === "right"} />
</div>
);
}
export function Demo() {
return (
<Diagram label="Ping-pong">
<DiagramControls />
<PingPong />
</Diagram>
);
}操作栏、标签页和播放/暂停控件按需安装到 src/components/react/diagram/——自由编辑、重新设计样式或替换;hooks 继续正常工作。从不编写交互式卡片的站点不会产生任何开销。
以人为先,以智能体为先
文档不再只由人类阅读,因此每个 Nimbus 站点都会在 HTML 之外提供多种机器可读格式:
- 每个页面的 Markdown 版本,位于
/<slug>/index.md - 站点级别的索引,位于
/llms.txt,列出所有页面 - 每个页面头部的 JSON-LD,为搜索和智能体工具提供足够的结构化数据来识别页面内容
# Nimbus
A way to build documentation sites on top of Astro.
## Pages
- [Getting started](https://nimbus-docs.cn/get-started/index.md)
- [Installation](https://nimbus-docs.cn/installation/index.md)
- [CLI](https://nimbus-docs.cn/cli/index.md)这些格式是默认配置,而非可选插件。在智能体网络中成为一个死胡同的代价是真实存在的,而且这个代价还在增长。
智能体驱动的创作
添加 Nimbus 默认组件或功能使用 nimbus-docs add。它的工作方式取决于你要添加的内容类型。组件和工具库以文件形式复制——registry:ui 和 registry:lib 标识符会解析依赖并落入你的仓库。功能以提示词形式交接——registry:feature 标识符是一个 markdown 配方,由你环境中的编码智能体读取、适配你的项目并执行。
npx @cloudflare/nimbus-docs add 404-pageyarn dlx @cloudflare/nimbus-docs add 404-pagepnpm dlx @cloudflare/nimbus-docs add 404-pagebunx @cloudflare/nimbus-docs add 404-page两种模式之间的分界线在于一个关键问题:哪种变更实际上需要编码智能体参与,哪种更适合作为文件复制。
创作质量是一等公民
内容质量参差不齐的文档站点会损害产品本身。Nimbus 对待创作质量的方式就像代码检查工具对待源代码——一组分层的验证器,每一层捕获不同类型的错误。
预构建验证器自动运行,仅在问题确实会导致站点无法构建时才阻止构建:
- 配置验证——检查
defineConfig的形状和必填字段;错误会回显导致问题的值 - Frontmatter schema 验证——Zod 类型化的 schema 按集合捕获缺失或格式错误的字段,提供友好的编辑器错误信息
- MDX 组件验证——预构建内容检查捕获小写用法、未注册的组件和缺失的导入
- 注册表验证——在构建时解析
src/components.ts并与实际 MDX 用法进行比对
检查引擎按需添加创作质量层。规则拥有稳定的标识符,如 nimbus/single-h1 和 nimbus/bare-url,在 astro.config.ts 中与其他 Nimbus 集成配置一起设置。运行 nimbus-docs lint 获取人类可读的输出,--format json 获取智能体可读的诊断信息,--fix 应用自动修复。构建永远不会被检查结果阻止——草稿仍然会渲染,警告会保持醒目但不阻塞。
import { defineConfig } from "astro/config";
export default defineConfig({
integrations: [
nimbus(nimbusConfig, {
rules: {
"nimbus/single-h1": "error",
"nimbus/bare-url": "warn",
},
}),
],
});基于 TypeScript 签名的组件属性验证将在 v1 之后推出。
可读只是底线
每个 Nimbus 站点已经提供了智能体可读的格式——每页的 Markdown 版本、llms.txt 索引和头部的结构化数据。一年前这能让文档工具脱颖而出;如今这只是入场券。更有意思的界限在更远处。
人人都让文档对智能体可读了。Nimbus 让文档可以被智能体编写、维护和操作——端到端,基于你完全拥有的代码库。
前提条件就是本页的第一个原则。当每个文件都在你的仓库中,没有什么重要的东西藏在 import 边界后面时,智能体不仅能阅读你的文档——它还能安全地修改文档,因为它能看到所涉及内容的全貌。供应商的主题化运行时可以被智能体抓取;但它无法被智能体重写。
这就是为什么功能以配方而非手动接入的代码形式到达。nimbus-docs add 会检测是否在编码智能体内运行,并向其传送结构化配方——发现项目、确认计划、执行,然后验证构建仍然通过,并在修改文件前检查该功能是否已安装。安装不再是复制粘贴的苦差事,而是变成了一场从头到尾由你的智能体掌控的对话。
# 在编码智能体内部,配方直接传入
npx @cloudflare/nimbus-docs add new-version# 在编码智能体内部,配方直接传入
yarn dlx @cloudflare/nimbus-docs add new-version# 在编码智能体内部,配方直接传入
pnpm dlx @cloudflare/nimbus-docs add new-version# 在编码智能体内部,配方直接传入
bunx @cloudflare/nimbus-docs add new-version# 从人类终端,把它交给任意智能体
npx @cloudflare/nimbus-docs add new-version --print | claude# 从人类终端,把它交给任意智能体
yarn dlx @cloudflare/nimbus-docs add new-version --print | claude# 从人类终端,把它交给任意智能体
pnpm dlx @cloudflare/nimbus-docs add new-version --print | claude# 从人类终端,把它交给任意智能体
bunx @cloudflare/nimbus-docs add new-version --print | claude来源追踪是原语
一旦智能体开始起草页面,问题就不再是机器能否读取这个,而是谁写的这个,人类是否检查过。由于你拥有内容集合,答案就在你控制的 schema 中——来源追踪只需几个 schemaFields,而不是在顶层打的补丁。
启动器附带了这样一个字段。默认值是反向的:面向智能体的内容是默认假设,因此 audience: "human" 是明确为人类优先编写的页面设置的标志。你可以用同样的方式扩展更多字段——这个站点添加了 aiGenerated 来标记由智能体起草但人类尚未审查的页面,页面操作行会显示“待审核”标签,直到有人确认:
import { z } from "astro/zod";
docsCollection({
schemaFields: {
audience: z.literal("human").optional(),
aiGenerated: z.boolean().optional(), // 显示"待审核",直到被清除
},
})注册该字段后,每个页面的来源和审查状态都随页面本身一起传递:
---
title: New endpoint
aiGenerated: true # 由智能体起草——显示"待审核",直到人类清除
---来源追踪只有在漂移被发现时才有价值。检查引擎会输出带版本号的 JSON,其中包含 --fix 可就地应用的精确到字符的修复方案,而脚手架生成的 AGENT.md 附带一个固定诊断格式的审计配方——这样智能体可以扫描整个站点并以其他工具可解析的格式报告结果:
- [error] src/content/docs/cli.mdx:42 — 断裂的内部链接 "/instal" — 你是指 "/installation" 吗?
- [warn] src/content/docs/registry.mdx:8 — 链接文本 "here" 在上下文外没有意义。
汇总:1 个错误,1 个警告。文档变成了智能体可以长期保持正确的东西——可维护、可操作,而不仅仅是发布——基于你拥有的仓库,而不是供应商的仓库。
目录结构就是真相
除了你的内容之外,不需要维护另一份配置。src/content/ 下的目录结构就是 URL 结构。目录结构也是侧边栏。移动文件,其对应的条目随之移动;删除文件,条目消失。Frontmatter 处理细粒度的调整——排序、徽标、草稿状态——但树的形状来自文件系统本身。
- src/content/docs/
- getting-started.mdx
- guides/
- styling.mdx
- deploying.mdx
- reference/
- api.mdx
结果是页面存在的唯一事实来源。站点不会与其内容脱节,因为其内容就是站点本身。
版本只是集合
大多数文档工具将版本管理作为特殊情况附加——并行文件系统、URL 重写、自定义路由。Nimbus 用一个已有的原语来实现:多集合内容。
每个版本都是自己的内容集合,使用相同的 schema。docs-v2/ 集合就是 v2 站点;docs-v3/ 集合就是 v3。路由和侧边栏独立处理每个版本。版本选择器只是上面的一个薄层。
- src/content/
- docs/
- docs-v2/
- docs-v3/
同样的原语也能处理国际化(docs-fr/ 集合就是法语站点)和产品拆分(docs-api/ 集合与 docs-cli/ 并存)。当你需要版本管理时,你已经拥有了大部分所需的东西;你之前没有为此付出代价。