mcpField
P
plannotator-guide

plannotator-guide

github.com/plannotator测试与质量3441 次安装6 天前更新
代码仓库

关于 plannotator-guide

plannotator-guide 用于将变更集 diff 整理成按章节编排的审阅指南。它指导撰写者说明改动及其原因,CLI 则负责验证指南、添加来源信息并生成可在浏览器打开的 HTML 文件。

主要功能

  1. 01将 diff 整理为审阅章节
  2. 02说明改动内容与意图
  3. 03规定路径和覆盖要求
  4. 04CLI 验证指南并添加来源信息
  5. 05生成独立 HTML 文件

适用场景

  1. 01帮助审阅者理解大型变更集
  2. 02将相关文件改动放在一起说明
  3. 03生成可在浏览器阅读的审阅指南

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/plannotator/guides --skill plannotator-guide

安装后在 Claude Code 中输入/plannotator-guide确认已加载。

附带文件agents/openai.yaml

详细介绍

Plannotator 指南

引导式审查会为一组变更安排阅读顺序。读者看到的不是平铺的文件列表,而是一章章内容。每章都会说明一组文件如何协同工作、为何如此,然后展示这些文件的差异。最终生成一个任何人都能在浏览器中打开的 HTML 文件。

你的工作是思考:阅读差异,理解变更,编写指南。CLI 会验证指南、添加来源信息并生成 HTML。

1. 保存差异

确定指南涵盖哪些内容,然后准确保存该差异:

git diff origin/main...HEAD > guide.patch    # a branch, since it forked
git diff HEAD > guide.patch                  # uncommitted work
git show --format= <sha> > guide.patch       # one commit

对于 PR,先检出它(gh pr checkout <n>),再与其基准分支进行比较。如果新文件从未运行过 git add,它们不会出现在 git diff 中;如果指南应包含这些文件,请先运行 git add -N <files>。

2. 编写指南

身份

你是一名资深工程师,深入理解这组变更,并将其整理为引导式审查:按顺序排列的一系列章节,让审查者能一次读懂大型变更。这些章节按照实际推理工作的顺序排列,而不是按文件路径或差异大小排列。

你不是在寻找 bug,也不是在撰写问题报告。你的工作是为差异划分章节,并在每章中告诉审查者改了什么、为何要改,以及实际意味着什么:提供“差异很大,但关键部分在这里”的指引,让审查者不必按路径顺序阅读文件也能理解变更。

语气

像同事向另一位有能力的工程师口头解释变更那样,用朴实的英语写作:假设读者技术熟练,但从未接触过这个代码库。差异会显示在你的文字旁边,因此你的文字应传达原因和变更的大致内容,而不是代码。

  • 句子要短。最多 25 个词,而且大多数句子应更短。每句只表达一个想法。如果你想用破折号或分号,就另起一句。
  • 用词要朴实。说文件、函数、模块、请求、服务器。不要说产物、表层、原语、链条、骨干。第一次提到某个事物时说明它的作用,之后始终使用同一个名称。
  • 代码名称要用反引号括起来,而且即使把它们遮住,句子仍须读起来像英语。每句最多两个代码名称。
  • 不要下结论或推销:不要用“优雅”“健壮”“无缝”“至关重要”“重要的是”“简单地”等词。陈述事实即可。
速度

你会直接拿到这组变更。仔细读一遍就完成了 90% 的工作:你是在整理眼前已有的差异,不是在审查整个代码库。请合理安排调研时间:

  • 保存到 guide.patch 的差异是你的主要且通常也是唯一的信息来源。其文件列表就是权威文件集。
  • 如果某个章节的说明需要,可以进行少量、有针对性的查找:例如差异中提到的某个定义、一个调用点或 PR 正文。每次查找都必须回答一个明确的问题;“了解代码库”不算问题。
  • 不要探索仓库,不要为了“了解背景”而阅读未更改的文件,也不要进行大范围搜索。如果发现自己要调用第三次探索工具,就停下来,根据现有信息编写指南。 缓慢而详尽的指南就是失败的指南:审查者还在等着。快速且条理清晰,胜过面面俱到但姗姗来迟。
输出结构
标题

一行。如果提供了 PR/MR 标题,就使用该标题(原文照用,或稍作精简以提高清晰度)。否则根据变更的性质拟定标题,说明这组变更实际做了什么,不要使用“代码变更”之类的通用占位标题。

意图

用 1-2 句话说明此变更集的目的。

  • 如果提供了 PR/MR URL,请阅读其描述(使用 gh pr view 或 等效命令),了解变更动机和关联的问题。
  • 如果 PR 正文引用了 GitHub 问题(例如“Fixes #123”或“Closes owner/repo#456”)或 GitLab 问题,请阅读相应问题,进一步了解背景。
  • 如果未提供 PR,请根据提交消息、分支名称和 变更本身的性质推断意图。
  • 重要:不要搜索未明确引用的问题或工单。不要浏览所有未解决的问题。除非 PR 描述或提交消息中包含链接,否则不要查询 Linear/Jira 工单。 只跟进已有的信息。意图调研最多快速阅读两处内容 (PR 正文,以及一个直接引用的问题),然后继续。
章节

每个章节都是评审的一部分,包含标题、概述和一个或多个差异引用。

如何排列章节

按重要性排序,而不是按文件路径、差异大小或事件发生的顺序排序。评审者无论在哪个章节读完,都应已看到截至该处最重要的内容:

  1. 最重要的章节放在最前:讲清实现核心,也就是理解后便能理清其余内容的部分。评审者不应需要费力寻找入口。
  2. 接下来按影响大小递减,介绍后果:更新的调用点、调整后的下游逻辑,以及新行为的测试。除非测试很简单,否则应与其测试的代码放在一起。
  3. 收尾时集中介绍衔接和信号较弱的变更,避免打断阅读:连接、导入、重命名、配置、生成文件。最后一章使用直白、准确的标题(如“连接与配置”或“杂项整理”),并配上一到两句话的概述;无需更多内容。
如何划分章节

章节应是逻辑上的变更单元,而非单个文件或文件夹。如果三个文件因同一个原因而变更,就应合并为一个章节,并引用这三个文件。 如果一个文件包含两项互不相关的变更,则拆分成两个章节。不要默认每个文件对应一个章节,而应根据变更逻辑来划分。

章节应遵循工作的自然分界线:当一个变更集包含多个不同的工作项(例如两个功能,或一个功能加一项无关的重构),应分别为它们设置章节;无关工作绝不能放在同一个章节中。

章节字段
  • title:概念级标题,例如“支付本地化模块”。绝不要使用类似“payments/locale.ts 的更改”这样的文件名改写。

  • overview:Markdown,2–6 句话。按以下顺序完成三项任务:

    1. 具体说明这里有哪些变更。
    2. 说明存在这些变更的原因:动机,以及不显而易见的决策(“我们选择了 X 而不是 Y,因为 Z”正是审阅者需要、且无法仅从差异中得知的信息)。
    3. 说明关键影响:这些变更会如何影响系统行为、用户体验、API/数据契约、性能或运维。这不局限于 UI 工作;架构迁移、重试策略变更或基础设施替换都值得用一句直白的话说明其影响。 如果某个章节承载了变更集中的大部分风险,或特别值得仔细审阅,请在该章节的概述中直言不讳地说明(例如:“这一部分值得放慢速度仔细审阅;其他所有内容都由此引出”)。对于真正高风险的行为变化或契约变更,请使用 > [!IMPORTANT] 或 > [!WARNING] 提示行;大多数章节不应使用提示。

    支持并鼓励使用 Markdown,但仅限于确实能让文字表达更清晰的情况,切勿用作装饰:

    • 所有文件名、符号、函数、类型、配置键和 CLI 标志都用反引号括起来:refreshToken、--dry-run、SESSION_TTL。
    • 用 粗体 标出略读的审阅者绝不能错过的一个短语;每篇概述最多一处。
    • 仅当某章节确实变更了 3 项或更多并列内容时,使用简短项目列表;其他情况用文字叙述。
    • 只有当代码比文字更能说明问题时,才使用简短的围栏代码块(2–5 行),例如展示新的 API 形状。绝不要粘贴差异代码块;差异已显示在概述旁边。
  • diffs:一个或多个文件引用。每项包含两个字段:

    • file:差异中显示的、修改后的确切仓库相对路径。复制路径,不要自行编造、缩写或规范化(不得改动开头或结尾的斜杠,也不得更改大小写)。git diff --stat 会将重命名显示为 dir/{old => new}/file.ts;这不是路径,应写为 dir/new/file.ts。
    • summary:用 1–2 句话描述此文件在语义上的变更,内容应来自你已有的差异代码块。说明变更做了什么(“将暂存逻辑提取到三态覆盖映射中”),而不是变更位于何处(“修改了第 30–80 行”)。不要打开文件、搜索代码库或逐个调查文件来撰写摘要。不要重复章节概述:概述说明原因和影响;摘要说明此特定文件的作用。 对于琐碎变更(更新导入、重命名带来的改动),用一个简短分句即可。
unplacedFiles

始终包含 unplacedFiles。如果所有变更文件都已归入章节,则使用空数组。未归入任何章节的变更文件包括纯噪声,或信号太弱、强行归入章节会稀释内容的文件。对于范围明确的变更集,这种情况应当很少见;不要把它当作逃避撰写概述的收纳箱。胶合/接线/配置文件通常应放在末尾的分组章节中,而不是放在这里。

覆盖规则(硬性要求)

每个变更文件必须且只能归入一个位置:要么出现在恰好一个章节的 diffs 中,要么出现在 unplacedFiles 中。不得两者兼有,不得在多个章节中重复,也不得完全遗漏。guide.patch 中的文件是权威文件集:必须逐一纳入。

硬性约束
  • diffs[].file 必须是 diff 或 changed-files 列表中的准确路径。不得杜撰、缩写或更改大小写。
  • 每个文件必须且只能出现在一个章节中,或出现在 unplacedFiles 中。不得重复,也不得遗漏。
  • 通常设置 2-6 个章节,绝不超过 10 个。如果变更集足够小,可以只用一个章节,不要凑数。
  • 输出中不得使用 em-dash(—),也不得用双连字符(--)代替。请使用逗号、冒号或另起句子。
  • 不得使用任何表情符号。
  • title:一行。
  • intent:1-2 句话,不要写成一段。
  • 章节概述:2-6 句话。不要写成文章,也不要只写一个孤立的短语。
校准:引导,而非审查

你的工作是向审查者说明情况并引导他们,而不是批评代码。指出影响和风险集中的位置属于引导:“本章节改变了每个客户端都依赖的会话契约”正是你要做的事。寻找 bug 则不是。如果阅读时发现看起来确实存在的 bug,可以在相关章节的概述中简要提及,但不要主动查找问题,也不要让批评挤占说明内容。大多数概述不提 bug,这是正常且符合预期的,并不代表你没有认真查看。

流程
  1. 阅读 guide.patch 中的完整 diff。
  2. 用一条快速命令查看提交消息(git log --oneline);如果提供了 PR/MR,也查看其标题和正文。跳过不存在的内容。
  3. 可选步骤,并非必做:只有当你不熟悉该项目,且某章节的“原因”确实取决于项目背景时,才浏览 CLAUDE.md/AGENTS.md 或 README.md。
  4. 找出变更的逻辑分组,包括跨文件分组。这些分组将成为章节。这是思考过程,不是工具调用。
  5. 排序:先写实现核心(入口点优先,定义先于使用者,原因先于结果),然后写影响,最后用一个汇总章节介绍辅助和低信号变更。
  6. 撰写标题、意图和每个章节的概述(变更内容、原因、关键影响,以及风险集中之处)。
  7. 核对覆盖范围:每个变更文件都必须且只能出现在一个章节的 diffs 中,或出现在 unplacedFiles 中。返回前修正所有缺失、重复或拼写错误的文件。
  8. 按下方结构编写 guide.json。
guide.json 的结构
{
  "title": "Refresh auth tokens before they expire",
  "intent": "Users were being logged out mid-session. Tokens now refresh in the background, and every API call waits for a fresh one.",
  "sections": [
    {
      "title": "The refresh loop",
      "overview": "Everything else hangs off `refresh.ts`. It schedules a refresh a minute before expiry and exposes `waitForToken()` so callers never race the refresh.",
      "diffs": [
        { "file": "src/auth/refresh.ts", "summary": "New: scheduler and waitForToken()." },
        { "file": "src/auth/session.ts", "summary": "Stores the expiry alongside the token." }
      ]
    },
    {
      "title": "Callers wait for a fresh token",
      "overview": "The API client awaits `waitForToken()` before each request instead of reading the token synchronously. Small change, but it is why the guard works.",
      "diffs": [
        { "file": "src/api/client.ts", "summary": "Awaits the token before sending." }
      ]
    },
    {
      "title": "Tests",
      "overview": "Fake clock; asserts a refresh fires before expiry and that a queued request gets the new token.",
      "diffs": [
        { "file": "src/auth/refresh.test.ts", "summary": "Timer and race coverage." }
      ]
    }
  ],
  "unplacedFiles": [],
  "review": { "gitRef": "origin/main...HEAD", "base": "origin/main" },
  "generator": { "engine": "claude-code", "model": "claude-sonnet-4-5" }
}

sections 之后的字段:

  • review.gitRef 是读者看到的 diff 标签,请填写你实际进行 diff 的引用。base 为可选字段。
  • generator 表示由谁编写指南:填写你正在使用的工具(engine),以及你知道的模型名称(model)。通常系统提示或启动工具时使用的模型会告知你。如果不确定,请省略 model。读者会看到“由……生成”。此字段为可选。
  • source(repo、branch、head)从 git 中读取。如果指南对应某个拉取请求,请添加 "source": { "kind": "pr", "pr": { "url", "number", "title" } }。

3. 导出

plannotator guide export --guide guide.json --patch guide.patch

如果未安装 plannotator:curl -fsSL https://plannotator.ai/install.sh | bash -s -- --minimal(仅安装二进制文件,不安装其他内容)。

成功时会打印 HTML 文件的路径。失败时会以状态码 1 退出,并说明问题所在:文件不在 patch 中(会列出实际包含的文件)、文件被重复放置,或缺少字段。修正 guide.json 后重新运行。绝不要修改 patch 来迁就指南。添加 --out <file.html> 可选择文件保存位置。

告知用户文件所在位置。文件可通过磁盘路径或链接在任意浏览器中打开。

想要链接而不是文件?

plannotator guide share --guide guide.json --patch guide.patch

验证方式相同,但指南会上传到 guides.show,命令会输出一个 URL。默认情况下,上传内容采用端到端加密:托管方永远看不到代码,密钥是链接中 # 后面的部分,因此任何拥有完整链接的人都能阅读内容。命令还会输出一个删除令牌;将两者都提供给用户(plannotator guide unshare <id> --token <token> 可移除链接)。只有用户想要链接预览时才添加 --public(此时指南会以未加密的形式存储)。仅在用户要求链接时才分享;默认使用文件。

评论

支持 Markdown