关于 diffity-tour
diffity-tour 是创建带讲解和代码链接的导览技能,用于解释代码库、功能或 GitHub 拉取请求。它会研究相关执行流程,并在浏览器中以分步说明和高亮代码呈现内容。
主要功能
- 01创建聚焦、功能、系统、概念或审查导览
- 02研究代码路径及相关源文件
- 03按顺序展示说明并高亮代码
- 04将 GitHub PR 导览限定于 PR 差异
- 05添加注释并完成导览
适用场景
- 01解释功能或请求流程的运作方式
- 02介绍代码库架构
- 03合并前讲解分支或 PR
- 04用代码示例说明编程概念
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nilbuild/ diffity --skill diffity-tour安装后在 Claude Code 中输入/diffity-tour确认已加载。
详细介绍
Diffity 导览技能
你正在创建一次引导式代码导览——通过讲解逐步浏览代码库,回答用户的问题或说明某项功能的工作原理。导览会在浏览器中打开,侧边栏显示讲解内容和高亮的代码片段。
参数
question(必填):用户的问题、主题、概念或 GitHub PR URL。示例:/diffity-tour how does authentication work?/diffity-tour explain the request lifecycle/diffity-tour how are comments stored and retrieved?/diffity-tour closures/diffity-tour React hooks/diffity-tour walk me through this branch before I merge/diffity-tour https://github.com/owner/repo/pull/123
当参数为 GitHub PR URL(匹配 github.com/owner/repo/pull/N)时,导览会自动锁定为 Review 模式——导览范围由 PR 的差异决定,结论中必须包含 PR 标记列表。请参阅下文的 Review 导览 部分。
CLI 参考
diffity agent tour-start --topic "<text>" [--body "<text>"] --json
diffity agent tour-step --tour <id> --file <path> --line <n> [--end-line <n>] --body "<text>" [--annotation "<text>"] --json
diffity agent tour-done --tour <id> --json
diffity list --json
前置条件
- 检查
diffity是否可用:运行which diffity。如果未找到,请运行npm install -g diffity安装。 - 如果参数为 GitHub PR URL:
- 检查是否已安装并完成身份验证的
gh:运行gh auth status。如果尚未完成身份验证,请停止并让用户运行gh auth login。 - 验证当前仓库与 PR 所属仓库一致:运行
gh repo view --json nameWithOwner -q .nameWithOwner,并确认其与 URL 中的owner/repo一致。如果不一致,请停止并告知用户需要进入该 PR 仓库的本地克隆目录——diffity 无法导览尚未检出的仓库中的 PR。 - 针对该 PR 启动 diffity:使用 Bash 工具运行
diffity --no-open <pr-url>,并设置run_in_background: true。--no-open标记必须放在 URL 前面——commander 的passThroughOptions()会将位置参数 URL 后出现的任何标记都读入 refs 数组,从而跳过 PR 处理并报出“unknown ref”错误。此命令会在本地检出 PR 分支,并启动一个限定差异范围的会话。等待 2 秒,然后运行diffity list --json获取端口。无需另外启动 tree 实例——差异会话支持agent tour-*命令。
- 检查是否已安装并完成身份验证的
- 否则,确保有一个 tree 实例正在运行:运行
diffity list --json。- 如果没有运行中的实例,请启动一个:使用 Bash 工具运行
diffity tree --no-open,并设置run_in_background: true;等待 2 秒,然后运行diffity list --json获取端口。
- 如果没有运行中的实例,请启动一个:使用 Bash 工具运行
说明
先选择一种模式
在进行任何操作之前,先确定本次导览属于哪种模式。本技能的其余部分会根据这一选择分支展开——范围、研究方法和输出形式都会有所不同。请在调用任何工具之前完成此操作。
**快捷方式:**如果参数是 GitHub PR URL(匹配 github.com/owner/repo/pull/N),则跳过选择,直接锁定为 Review 模式。
| 模式 | 适用于用户询问…… | 范围依据 | 目标步骤数 |
|---|---|---|---|
| Focused | 范围较窄的“X 是如何工作的?”问题 | 一条代码路径 | 3-6 |
| Feature | “这个功能是如何工作的?” | 功能边界 | 6-10 |
| System | “整个系统是如何工作的?” | 架构 | 8-15 |
| Concept | 编程概念相关问题 | 代码中的示例 | 3-8 |
| Review | 合并前审查分支/PR/功能 | git diff <base>..HEAD | 可变——涵盖每项有意义的变更 |
引导选择各模式的触发词:
- Focused:“X 如何验证”“带我了解 Y 端点”
- Feature:“身份验证如何工作”“解释评论系统”
- System:“应用如何工作”“介绍一下整体架构”
- Concept:单独出现的概念名称(
closures、React hooks、async/await、generics) - Review:“合并之前”“审查这个分支”“带我了解整个功能”“审计这个 PR”“我准备合并”
如果多种模式都适用,优先选择更具体的模式(Review > Concept > Focused > Feature > System)。如果确实无法判断用户想要哪种模式,请在开始研究前先询问——不要猜测并生成错误形式的导览。
模式决定本技能的哪些部分适用:
- Concept 模式 → 阅读下方的 Concept 导览部分;研究方法有所不同(搜索示例,而非跟踪流程),步骤安排也不同。
- Review 模式 → 阅读下方的 Review 导览部分;范围由差异决定,逐个检查讨论串,结论必须包含 PR 标记列表。
- Focused / Feature / System 模式 → 直接遵循默认的 Phase 1-3 指引。
Phase 1:确定范围并开展研究
创建任何导览步骤之前,必须彻底理解用户问题的答案。
-
**确认范围。**所选模式决定大致的步骤数(参见上方的 选择一种模式)。如果用户的问题过于宽泛,无法在该步骤数范围内解答(例如“解释所有内容”却选择了 System 模式),请在思路中缩小范围,聚焦最重要的方面,并在引言中说明涵盖和未涵盖的内容。
-
**确定受众。**根据问题的措辞进行判断:
- “X 如何工作?” → 假设用户刚接触此代码库——解释架构决策,而不只是代码机制
- “为什么 X 会执行 Y?” → 假设用户正在调试或审查——聚焦原因和边缘情况
- “带我了解 X” → 假设用户想了解完整情况——充分讲解并提供背景
-
**研究代码库。**彻底阅读相关源文件。从入口点开始,沿代码路径追踪到执行完成。
对 Review 导览而言,还要阅读
git log --reverse <base>..HEAD,并打开提交说明中描述了不明显的修复、重构或防御性变更的提交。作者自己的说明通常最能解释 原因,远胜于仅从代码推断意图。在步骤正文中引用或转述提交说明,以阐明设计决策(例如:“提交abc1234在一次生产事故后加入了这项检查,当时……”)。 查看 GitHub PR 时,使用gh获取元数据和差异:gh pr view <url> --json title,body,baseRefName,headRefName,commits,files— 获取 PR 标题、正文、基准分支和头部分支、提交列表以及更改文件列表。PR 的正文通常包含最丰富的“原因”信息(设计背景、截图、作者考虑过的权衡)——在引言中引用或概述这些内容。gh pr diff <url>— 获取定义本次导览范围的统一差异。用它确认完整的影响范围,而不仅仅是git diff中显示的内容。- 使用 PR 的
baseRefName(来自上述 JSON)作为差异基准,而不要默认使用master/main。git log --reverse <baseRefName>..<headRefName>之类的命令会按作者顺序遍历 PR 的提交。 - 工作树中的源文件可直接读取,因为
diffity <pr-url>已在本地检出 PR 分支。
-
确定关键位置,指出能讲清楚整个过程的文件和行范围——读者需要查看这些内容才能理解答案。
-
注意配置依赖项。 如果行为会因环境变量、功能标志、配置文件或运行时条件而变化,请注明。必须在导览中说明这些依赖,让读者理解“配置为 X 时会发生什么;但如果设置为 Y,流程会在哪些地方有所不同”。
-
规划合理的步骤顺序,循序渐进地建立理解。每一步都应自然引出下一步。
选择步骤的指南:
- 从真正的入口点开始——外部输入到达的位置(HTTP 路由、CLI 命令、定时任务、Webhook)。配置、模式和常量以及辅助函数都不是入口点;它们是流程的依赖项。
- 在恰当时机介绍基础内容。流程首次读取模式时,再讲解该模式;首次调用辅助函数时,再讲解该函数;首次引用配置值时,再讲解该配置。不要在流程开始前,先把一系列基础内容作为铺垫介绍。
- 入口点之前最多只能有一个“概览”步骤(例如展示所有端点的路由表)。其他内容都应由读者刚看到的内容自然引出。
- 按照实际执行顺序跟进流程。
- 只包含理解过程所必需的位置——跳过样板代码。
- 以最终结果收尾(发送响应、持久化数据、渲染 UI)。
- 每一步只讲解一个概念或代码片段。
- 尽可能提供具体示例(例如:“用户运行
diffity main时,这会变成……”)。
自顶向下,而非自底向上。 导览应反映代码在运行时的执行方式,而不是代码的构建方式。不要按配置 → 模式 → 辅助函数 → 路由 → 操作的顺序讲解。应按路由 → 操作 →(查询读取模式时介绍模式)→(处理程序引用配置时介绍配置)→(代码调用辅助函数时介绍辅助函数)的顺序讲解。每当新内容与当前流程相关时再引入,读者会更容易保持上下文。读者应感觉自己正与你并肩追踪一个真实请求,而不是在演示开始前先听一堂架构课。
处理跨模块流程: 当代码路径进入库、工具模块或深层嵌套的抽象时,请决定是否继续跟进:
- 继续跟进:其中的逻辑对于理解答案至关重要时(例如,会转换请求的自定义中间件)
- 概述:模块执行的是标准或常见操作时(例如,“这里会调用 Express 路由器,由它匹配路径并调用我们的处理程序”)——在步骤正文中说明其作用,无需单独设置一个步骤
- 跳过:纯样板代码或管线代码时(例如,重新导出、仅包含类型的文件) 应用于多个文件的模式。 当单个更改被复制到 N 个相似的调用点(例如,为 8 个处理程序添加相同的保护条件,或在每个路由上注册相同的中间件)时,不要创建 N 个步骤。请在最具代表性的文件中创建一个包含完整上下文的步骤,然后在正文中将其他调用点列为 goto 链接(“X、Y、Z 也添加了相同的保护条件”)。一个概念,一个步骤——导览应只教读者一次这种模式,而不是 N 次。例外情况:如果其中一个应用与其他应用略有不同(例如,在传输流程中调用了两次,或使用了不同的参数),则为它单独创建一个步骤。
第 2 阶段:创建导览
导览 UI 设有专用的说明面板。简介(来自 tour-start --body)会显示为第 0 步——这是读者看到的第一项内容,并占满整个面板。之后的每个步骤都会在同一面板中显示说明,并同时高亮代码。面板空间充足,请撰写内容丰富、详细的说明。
-
开始导览,提供简短的主题标题和简介正文:
diffity agent tour-start --topic "<short title>" --body "<intro>" --json--topic会显示在导览面板标题栏中——请控制在 3–6 个词(例如,“身份验证流程”“路由工作原理”“评论系统架构”)。不要将用户的完整问题用作主题。撰写简介正文(第 0 步): 这是读者看到的第一项内容,会占满整个说明面板。请利用这部分内容提供全面的架构概览,让读者在深入阅读代码前了解所需的一切。请包括:
- 涉及的关键组件、软件包或模块及其职责
- 它们之间的连接方式——数据流、调用链或依赖关系
- 读者应了解的关键抽象或模式
- 使用粗体文本绘制流程概览图(例如,CLI 参数 → git diff → 解析器 → JSON API → React 渲染)
- 配置背景——如果功能行为取决于配置、环境变量或功能标志,请在此处提及,让读者了解本次导览假定的模式或状态
如果你缩小了宽泛问题的范围,请说明涵盖的内容:“本导览聚焦于 OAuth 登录流程。令牌刷新和会话管理与此相关,但会单独介绍。”
使用丰富的 Markdown 格式——段落、粗体、
code、表格、代码块。这不是对导览内容的目录,而是一份能帮助读者了解情况的独立概览。从 JSON 输出中提取导览 ID。
-
按顺序添加步骤。对每个步骤:
diffity agent tour-step --tour <id> --file <path> --line <start> --end-line <end> --body "<narrative>" --annotation "<short label>" --json撰写步骤内容:
--file:相对于仓库根目录的路径(例如,src/server.ts)--line/--end-line:要高亮的确切行范围。请聚焦于相关部分。--annotation:简短标签(3–6 个词),用作步骤标题。可将其视为章节标题。--body:显示在说明面板中的正文。面板空间充足,请使用 Markdown 撰写详尽说明:
提交步骤前验证目标。 调用
tour-step前,请确认--file路径可从仓库根目录读取,并且你描述的函数或代码块确实位于指定的--line/--end-line范围内——请读取该范围,不要依赖本次会话早些时候的记忆。正文中的每个goto:链接也同样如此:错误的 goto 链接比没有链接更糟,因为读者会相信它,却在毫无提示的情况下跳转到错误位置。如果不确定确切行号,请使用普通的反引号代码,而不要使用 goto 链接。步骤正文结构。 每个步骤的正文都应按顺序遵循以下脉络:
- 过渡(1 句话):衔接上一步——请参阅下方示例。
- 说明(主体):说明这段代码的作用,以及为什么要这样组织——设计决策、权衡和具体示例。如果代码范围包含不同部分,可使用子高亮(
focus:X-Y)。 - 要点(1-2 句话):指出易踩的坑、边缘情况,或“如果要修改……,需要关注这里”的提示。
没有过渡的步骤正文会显得突兀;没有要点的正文则会让人觉得未完成。每个步骤正文尽量控制在 150-300 个词左右——只有逻辑确实需要时才写得更长。如果草稿超过 400 个词,这一步很可能涵盖了两件事;可以考虑拆分。
步骤过渡——串联叙述: 每个步骤都应自然承接上一步。每段步骤正文都以一句过渡句开头,衔接前文:
- “现在我们已经了解请求是如何解析的,接下来看看它在哪里进行验证……”
- “刚才看到的处理器会将工作委托给这个服务,实际业务逻辑就在这里……”
- “到这里,数据已经完成转换,可以持久化了——下面看看这是如何实现的……”
不要让步骤一开头就像读者失去了上下文。这次代码导览是一个故事——每一步都是其中的一章,而不是孤立的段落。
建议:
-
使用散文段落撰写,并在有帮助时辅以结构化内容
-
函数名、变量、引用和命令使用
code。引用位于已知文件和行号中的函数、类或代码符号时,应将其设为跳转链接,方便读者点击跳转。语法:[`symbolName`](goto:path/to/file.ts:startLine-endLine),单行则使用[`symbolName`](goto:path/to/file.ts:line)。这些链接会渲染为可点击的行内代码,可跳转至文件并高亮目标行。示例:[`handleDragEnd`](goto:src/KanbanContent.jsx:42-58)。通用术语、CLI 命令,或尚未在代码库中定位的符号,使用普通反引号代码。 -
使用粗体标出引入的关键概念
-
说明代码存在的原因和背后的设计决策,而不只是它的作用
-
使用具体示例:“运行
diffity main时,这一行会调用normalizeRef('main'),计算出git merge-base main HEAD” -
使用表格展示映射关系(输入 → 输出、引用 → git 命令)
-
使用代码块展示数据结构或命令输出
-
将每一步与引言中的整体内容联系起来
-
指出边缘情况和易踩的坑——如果存在不明显的行为、已知限制,或“看起来不对,但这是有意设计”的情况,请明确指出。这些问题往往会让之后修改代码的人踩坑。
-
对较大的高亮范围,使用子高亮链接,聚焦步骤中的具体部分。语法:
[label](focus:startLine-endLine)。这些链接会渲染为可点击的标签,将高亮范围切换到指定行。例如:首先,函数会验证参数: [参数验证](focus:15-22) 接着,核心转换会处理每个条目: [核心转换](focus:25-40) 最后,返回结果前会先将其缓存: [结果缓存](focus:42-48)如果一步涵盖 30 行以上,且叙述自然分为不同部分,请使用子高亮。行号范围必须位于该步骤的
--line/--end-line范围内。 Mermaid 图表: 当某个概念用视觉方式更容易理解时——例如架构关系、数据流、状态机或时序图——请加入 Mermaid 代码块。不要在每一步都强行加入图表;只在确实能让说明更清晰时使用。适合加入图表的内容包括: -
开头(步骤 0)的概览:展示各组件如何连接的流程图
-
涉及多个组件交互或请求流程的步骤
-
状态机或生命周期转换
选择最合适的图表类型:
graph TD/LR用于架构、模块依赖关系和数据流sequenceDiagram用于调用链、请求/响应流程stateDiagram-v2用于状态机和生命周期转换classDiagram用于类型层次结构和结构体关系flowchart用于算法、决策树和控制流
图表应简洁(节点数少于约 12 个)。它们会以内嵌形式显示在导览面板中。
不要:
- 罗列一大堆项目符号——请使用带格式的段落
- 只描述语法——请解释设计决策
- 重复高亮代码中已显示的信息
- 在步骤正文中使用标题(注释本身就是标题)
- 在每一步都强行加入图表——只在确实有帮助时添加
- 在步骤开头不与上一步建立联系
-
添加结尾步骤。 导览的最后一步应总结全文。沿用最后一个有实质内容的步骤中的文件/行范围,并撰写正文,其中:
- 总结完整流程:用 2-3 句话概括——读者看过所有部分后,为他们提炼出可供后续参考的整体思路
- 突出关键设计决策:指出这段代码中最重要的 2-3 个架构选择,以及选择它们的原因
- 指出扩展入口:如果要修改或扩展此功能,应从哪里着手?需要改动哪些文件?
- 提及相关领域:提及 1-2 个与此功能相关的特性或流程,为读者指明后续探索方向
此步骤使用注释
"Putting It Together"。 -
完成导览:
diffity agent tour-done --tour <id> --json
阶段 3:在浏览器中打开
-
使用
diffity list --json获取运行中实例的端口。 -
打开导览:
open "http://localhost:<port>/tour/<tour-id>"(或使用适用于用户操作系统的命令)。 -
告知用户导览已就绪:
导览已就绪——请在浏览器中查看。
概念导览
当用户询问的是编程概念,而非功能或流程(例如“闭包”“泛型”“错误处理模式”)时,导览就会成为教学工具。
概念导览与功能导览的区别:
- 研究阶段:不要沿着执行路径梳理,而要在代码库中搜索该概念的实际用例。使用 grep、glob 和文件读取来查找模式。广泛搜索——闭包可能会以回调、工厂函数或事件处理器的形式出现。
- 示例选择:选取 3-8 个示例,涵盖概念的不同方面,并从简单到复杂逐步深入。不要展示 5 个用法相同的示例。
- 介绍正文:面向可能从未接触过该概念的读者。包括:不含术语的定义、概念存在的原因(解决什么问题)、心智模型或类比,以及需要留意的语法线索。
- 步骤正文:每个步骤通过一个实际示例讲解一个方面。结构为:引导读者定位代码 → 指出概念的实际用法 → 说明此处为何使用它 → 总结关键要点。术语首次出现时,需在行文中解释。
- 递进安排:第一个示例应让读者觉得“哦,原来就是这样?”最后一个示例应展示最复杂的用法。
- 总结步骤:回顾 3-5 条关键规则,列出 2-3 个常见错误,并建议接下来学习的相关概念。
- 代码库中的示例较少:如果实际示例少于 3 个,就创建临时教学代码片段文件,将其作为导览步骤(明确标注为独立示例),并在导览创建完成后删除。
其他所有导览指南(过渡、goto 链接、子高亮、mermaid 图表、结尾)仍然适用。
代码评审导览
当用户要求在合并前对分支、PR 或功能进行评审时,应将导览组织为贯穿面向用户流程的请求追踪,而不是架构漫游。这种模式最有可能产出可供读者采取行动的审查结果。
代码评审导览与功能导览的区别:
- 根据差异确定范围:读者想审查发生了哪些变化。首先阅读
git diff <base>...HEAD(以及相关提交),以了解完整的变更范围。每项有意义的变更都应覆盖;只有纯样板代码可以跳过。 - 介绍结构:先用一段话说明功能,然后加入一张运行部分表(区域 → 位置 → 用途)、一个高层流程图,以及一个简短的配置上下文区块(环境变量、新常量、行为默认值)。介绍部分要帮助读者建立接下来要沿着导航的地图。
- 允许一个方向指引步骤:如果有路由表、webhook 分发器或其他端点目录,可以将其作为第 1 步,列出导览将追踪的各条路径。之后的所有步骤都必须以流程为主线。
- 一次追踪一条路径:先选最常见的用户旅程(通常是“创建 → 激活 → 持续管理”),端到端地追踪,并在需要时介绍基础内容,然后再依次追踪其他路径。不要交错讲解不同路径。
- 最后讲解横向门控:应用于多个操作的访问检查、速率限制、功能标志或共享防护,应放在主要流程之后,以便读者先了解“哪些内容受到门控”,再了解“如何进行门控”。
- 面向评审者的结尾:除了通常的心智模型和扩展点外,还应加入**“PR 讨论中需要提出的问题”**列表,涵盖不明显的权衡、防御性代码、竞态窗口、过时的默认值以及非事务性写入。这通常是代码评审导览中最有价值的部分。
其他所有导览指南(过渡、goto 链接、子高亮、mermaid 图表、结尾)仍然适用。
质量检查清单
完成前,请确认:
- 引言(步骤 0)提供全面的架构概览,而不是目录
- 如果问题的范围已缩小,引言会说明涵盖和未涵盖的内容
- 在相关位置注明配置依赖项(环境变量、功能标志、配置)
- 第一个代码步骤是真正的入口点(路由、CLI 处理程序、事件处理程序),而不是配置文件、架构或辅助工具
- 基础部分(架构、配置、常量、辅助工具)应在流程首次引用它们的步骤中介绍,而不是放在前言里
- 入口点之前最多只有一个概览步骤
- 步骤遵循实际的执行/数据流,而不是按文件名的字母顺序排列
- 每个步骤都以衔接前一步的过渡内容开头
- 解释设计决策和“为什么”,而不只是“代码做了什么”
- 指出存在的边缘情况和注意事项
- 不要连续两个步骤都突出显示同一文件中的相同行
- 跨模块跳转要么继续跟进,要么进行概述,要么跳过,不能不作解释
- 结论步骤将所有内容串联起来,说明整体思路、设计决策和扩展点
- 每个已知文件位置的函数、类或符号引用都使用跳转链接
- 所有
goto:链接以及每个--file/--line值都已对照实际文件核实,不得猜测行号 - 重复模式(在 N 个文件中相同的保护条件/中间件)应集中在一个步骤中介绍,而不是拆成 N 个步骤
- 步骤正文遵循“过渡 → 解释 → 总结”的结构,长度为 150–300 个单词
- 对于评审导览,结论中应包含“在 PR 讨论中需要指出的事项”列表