关于 code-tour
用于创建面向特定角色的 CodeTour 分步代码导览,并链接到仓库文件与行号。它提供从文档生成草稿和校验导览的脚本,以及模式和示例参考。
主要功能
- 01创建角色定向的 CodeTour 导览
- 02将步骤链接到文件和行号
- 03从文档生成导览草稿
- 04校验路径、行号和导览结构
- 05参考模式及注释示例
适用场景
- 01准备仓库入门导览
- 02通过代码讲解功能或架构
- 03根据 README 或文档生成导览草稿
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ github/ awesome-copilot --skill code-tour安装后在 Claude Code 中输入/code-tour确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/codetour-schema.jsonexamples.mdscripts/generate_from_docs.pyvalidate_tour.py详细介绍
代码导览技能
你正在创建一个 CodeTour —— 一个面向特定角色、逐步讲解代码库的导览,
直接链接到文件和行号。CodeTour 文件存放在 .tours/ 中,并与
VS Code CodeTour 扩展配合使用。
scripts/ 中打包了两个脚本:
scripts/validate_tour.py—— 在编写任何导览后运行。检查 JSON 有效性、文件/目录是否存在、行号是否在范围内、模式匹配、nextTour 交叉引用以及叙事结构。运行方式:python ~/.agents/skills/code-tour/scripts/validate_tour.py .tours/<name>.tour --repo-root .scripts/generate_from_docs.py—— 当用户要求从 README/文档生成时,先运行此脚本以提取骨架,然后再填充内容。运行方式:python ~/.agents/skills/code-tour/scripts/generate_from_docs.py --persona new-joiner --output .tours/skeleton.tour
还打包了两个参考文件:
references/codetour-schema.json—— 权威的 JSON schema。阅读它以验证任何字段名或类型。你使用的每个字段都必须符合它。references/examples.md—— 来自生产仓库的 8 个真实世界 CodeTour 导览,附有注释技巧。当你想了解某个特定功能(commands、selection、view、pattern、isPrimary、多导览系列)在实践中如何使用时的参考。
GitHub 上真实的 .tour 文件
这些是已确认的生产环境 .tour 文件。当你需要某个特定步骤类型、导览级字段或叙事结构的工作示例时,抓取其中一个 —— 当真实示例只需一次抓取就能获得时,不要凭记忆编写。
使用 GitHub 代码搜索查找更多:https://github.com/search?q=path%3A**%2F*.tour+&type=code
按步骤类型 / 展示的技巧
| 学习内容 | 文件 URL |
|---|---|
directory + file+line(贡献者入门) | https://github.com/coder/code-server/blob/main/.tours/contributing.tour |
selection + file+line + 介绍内容步骤(无障碍项目) | https://github.com/a11yproject/a11yproject.com/blob/main/.tours/code-tour.tour |
最小教程 —— 紧凑的 file+line 叙述,用于交互式学习 | https://github.com/lostintangent/rock-paper-scissors/blob/master/main.tour |
使用 nextTour 链接的多导览仓库(云原生 OCI 演练) | https://github.com/lucasjellema/cloudnative-on-oci-2021/blob/main/.tours/introduction.tour |
isPrimary: true(标记入门入口点) | https://github.com/nickvdyck/webbundlr/blob/main/.tours/getting-started.tour |
用 pattern 代替 line(正则锚定步骤) | https://github.com/nickvdyck/webbundlr/blob/main/.tours/architecture.tour |
原始内容提示: 在前面加上 raw.githubusercontent.com 并去掉 /blob/ 以获得原始 JSON 访问。
一个出色的导览不仅仅是注释过的文件。它是一个叙事 —— 向特定的人讲述什么重要、为什么重要以及接下来该做什么的故事。你的目标是写出正确的人在第一次打开这个仓库时希望存在的导览。
关键:只创建 .tour JSON 文件。绝不创建、修改或搭建任何其他文件。
步骤 1:探索仓库
在向用户询问任何内容之前,先探索代码库:
- 列出根目录、阅读 README,并检查关键配置文件 (package.json、pyproject.toml、go.mod、Cargo.toml、composer.json 等)
- 识别语言、框架以及项目是做什么的
- 映射 1–2 层深的文件夹结构
- 找到入口点:主文件、索引文件、应用启动引导
- 注意哪些文件实际存在 —— 你在导览中写的每个路径都必须是真实的
如果仓库内容稀少或为空,说明这一点,并基于现有内容开展工作。
如果用户说"从 README 生成"或"使用文档": 先运行骨架生成器,然后通过阅读实际文件来填写每个 [TODO: ...]:
python skills/code-tour/scripts/generate_from_docs.py \
--persona new-joiner \
--output .tours/skeleton.tour
按语言/框架划分的入口点
不要通读所有内容——从这里开始,然后沿着导入继续。
| 技术栈 | 优先阅读的入口点 |
|---|---|
| Node.js / TS | index.js/ts、server.js、app.js、src/main.ts、package.json(scripts) |
| Python | main.py、app.py、__main__.py、manage.py(Django)、app/__init__.py(Flask/FastAPI) |
| Go | main.go、cmd/<name>/main.go、internal/ |
| Rust | src/main.rs、src/lib.rs、Cargo.toml |
| Java / Kotlin | *Application.java、src/main/java/.../Main.java、build.gradle |
| Ruby | config/application.rb、config/routes.rb、app/controllers/application_controller.rb |
| PHP | index.php、public/index.php、bootstrap/app.php(Laravel) |
仓库类型变体——相应调整侧重点
同一个 persona 会根据仓库类型的不同而关注不同的内容:
| 仓库类型 | 应强调的内容 | 典型锚点文件 |
|---|---|---|
| 服务 / API | 请求生命周期、认证、错误契约 | router、middleware、handler、schema |
| 库 / SDK | 公开 API 表面、扩展点、版本管理 | index/exports、types、changelog |
| 命令行工具 | 命令解析、配置加载、输出格式化 | main、commands/、config |
| Monorepo | 包边界、共享契约、构建图 | 根 package.json/pnpm-workspace、shared/、packages/ |
| 框架 | 插件系统、生命周期钩子、逃生舱口 | core/、plugins/、lifecycle |
| 数据管道 | 源 → 转换 → 汇、schema 归属 | ingest/、transform/、schema/、dbt models |
| 前端应用 | 组件层级、状态管理、路由 | pages/、store/、router、api/ |
对于 Monorepo:找出与 persona 目标最相关的 2–3 个包。不要试图游览所有内容——以一步说明如何浏览工作区来开启导览,然后保持专注。
大型仓库策略
对于文件数超过 100 的仓库:不要试图通读所有内容。
- 先阅读入口点和 README
- 在脑海中建立前 5–7 个模块的模型
- 针对所请求的 persona,找出最关键的 2–3 个模块并深入阅读
- 对于未覆盖的模块,在导览步骤中将其标注为“本次导览范围之外”
- 对于已梳理但未阅读的区域,使用
directory步骤——它们能提供方向感,而无需完整知识
一次聚焦于正确文件的 10 步导览,胜过面面俱到的 25 步零散导览。
步骤 2:读取意图——尽可能推断一切,只问无法推断的部分
用户的一条消息就足够了。 阅读他们的请求,在提问之前先推断出 persona、 深度和侧重点。
意图映射
| 用户说 | → 角色 | → 深度 | → 操作 |
|---|---|---|---|
| "tour for this PR" / "PR review" / "#123" | pr-reviewer | standard | 为 PR 添加 uri 步骤;使用 ref 指定分支 |
| "why did X break" / "RCA" / "incident" | rca-investigator | standard | 追踪故障因果链 |
| "debug X" / "bug tour" / "find the bug" | bug-fixer | standard | 入口 → 故障点 → 测试 |
| "onboarding" / "new joiner" / "ramp up" | new-joiner | standard | 目录、环境搭建、业务背景 |
| "quick tour" / "vibe check" / "just the gist" | vibecoder | quick | 5–8 步,仅快速路径 |
| "explain how X works" / "feature tour" | feature-explainer | standard | UI → API → 后端 → 存储 |
| "architecture" / "tech lead" / "system design" | architect | deep | 边界、决策、权衡 |
| "security" / "auth review" / "trust boundaries" | security-reviewer | standard | 认证流程、校验、敏感汇聚点 |
| "refactor" / "safe to extract?" | refactorer | standard | 接缝、隐藏依赖、抽取顺序 |
| "performance" / "bottlenecks" / "slow path" | performance-optimizer | standard | 热路径、N+1、I/O、缓存 |
| "contributor" / "open source onboarding" | external-contributor | quick | 安全区域、约定、雷区 |
| "concept" / "explain pattern X" | concept-learner | standard | 概念 → 实现 → 理由 |
| "test coverage" / "where to add tests" | test-writer | standard | 契约、接缝、覆盖缺口 |
| "how do I call the API" | api-consumer | standard | 公共接口、认证、错误语义 |
静默推断: 角色、深度、关注领域、是否添加 uri/ref、isPrimary。
仅在你确实无法推断时才询问:
- "bug tour" 但未描述 bug → 询问 bug 描述
- "feature tour" 但未指明功能 → 询问是哪个功能
- 明确要求 "specific files" → 将其作为必停点予以遵循
除非用户提到了 nextTour、commands、when 或 stepMarker,否则绝不要询问这些内容。
PR tour 配方
对于 PR tour:将 "ref" 设为分支,以一个针对 PR 的 uri 步骤开场,先覆盖变更的文件,再覆盖未变更但关键的文件,最后以审查者检查清单收尾。
用户提供的自定义 — 始终遵循这些
| 用户说 | 要做什么 |
|---|---|
"cover src/auth.ts and config/db.yml" | 这些文件是必停点 |
"pin to the v2.3.0 tag" / "this commit: abc123" | 设置 "ref": "v2.3.0" |
| "link to PR #456" / 粘贴一个 URL | 在合适的叙述时机添加一个 uri 步骤 |
| "lead into the security tour when done" | 设置 "nextTour": "Security Review" |
| "make this the main onboarding tour" | 设置 "isPrimary": true |
| "open a terminal at this step" | 添加 "commands": ["workbench.action.terminal.focus"] |
| "deep" / "thorough" / "5 steps" / "quick" | 相应地覆盖深度 |
第 3 步:阅读实际文件 — 没有例外
tour 中的每个文件路径和行号都必须通过阅读文件来核实。 指向错误文件或不存在行的 tour 比没有 tour 更糟。
对于每一个计划好的步骤:
- 阅读该文件
- 找到你想高亮的那行代码的确切行号
- 充分理解它,以便向目标角色解释清楚
如果用户请求的文件不存在,就如实说明 — 不要悄悄用另一个文件替代。
第 4 步:编写 tour
保存到 .tours/<persona>-<focus>.tour。阅读 references/codetour-schema.json 获取
权威字段列表。你使用的每个字段都必须出现在该 schema 中。
导览根节点
{
"$schema": "https://aka.ms/codetour-schema",
"title": "Descriptive Title — Persona / Goal",
"description": "One sentence: who this is for and what they'll understand after.",
"ref": "main",
"isPrimary": false,
"nextTour": "Title of follow-up tour",
"steps": []
}
省略任何不适用于此导览的字段。
when — 条件显示。一个在运行时求值的 JavaScript 表达式。仅当条件为真时才显示此导览。适用于针对特定角色的自动启动,或在较简单的导览完成前隐藏高级导览。
{ "when": "workspaceFolders[0].name === 'api'" }
stepMarker — 将步骤锚点直接嵌入源代码注释中。设置后,CodeTour 会在文件中查找 // <stepMarker> 注释,并将其用作步骤位置,而不是(或同时配合)行号。适用于行号频繁变动的活跃变更代码上的导览。示例:设置 "stepMarker": "CT" 并在源文件中放入 // CT。除非用户要求,否则不要建议此做法 — 它需要编辑源文件,这并不常见。
步骤类型 — 完整参考
所有步骤类型:content(开场/收尾,最多 2 个)、directory、file+line(主力)、selection(代码块)、pattern(正则匹配)、uri(外部链接)、view(聚焦 VS Code 面板)、commands(运行 VS Code 命令)。
路径规则:
"file"和"directory"必须相对于仓库根目录。不能使用绝对路径,不能有前导./。
何时使用每种步骤类型
| 情况 | 步骤类型 |
|---|---|
| 导览开场或收尾 | content |
| "这个文件夹里有什么" | directory |
| 一行就能说明全部 | file + line |
| 函数/类主体才是重点 | selection |
| 行号会变动,文件不稳定 | pattern |
| PR / issue / 文档给出了"为什么" | uri |
| 读者应打开终端或资源管理器 | view 或 commands |
步骤数量校准
让步骤数量匹配深度和角色。这些是目标值,不是硬性限制。
| 深度 | 总步骤数 | 核心路径步骤数 | 说明 |
|---|---|---|---|
| 快速 | 5–8 | 3–5 | Vibecoder、快速探索者 — 果断删减 |
| 标准 | 9–13 | 6–9 | 大多数角色 — 广度 + 足够细节 |
| 深度 | 14–18 | 10–13 | 架构师、RCA — 每个取舍都呈现出来 |
也要随仓库大小缩放。一个 3 文件的 CLI 不该有 15 个步骤。一个 200 文件的单体项目也不该被压缩成 5 个。
| 仓库大小 | 推荐的标准深度 |
|---|---|
| 极小(< 20 个文件) | 5–8 个步骤 |
| 小(20–80 个文件) | 8–11 个步骤 |
| 中(80–300 个文件) | 10–13 个步骤 |
| 大(300+ 个文件) | 12–15 个步骤(限定在相关子系统) |
撰写出色的描述 — SMIG 公式
每条描述都应按顺序回答四个问题。你不需要写四段 — 但每条描述都需要包含全部四个要素,哪怕很简短。
S — Situation(情境):读者正在看什么?用一句话将他们置于上下文中。 M — Mechanism(机制):这段代码如何工作?涉及什么模式、规则或设计? I — Implication(影响):为什么这对该角色的具体目标很重要? G — Gotcha(陷阱):聪明人在哪里容易搞错?什么是非显而易见、脆弱或令人意外的?
描述应告诉读者一些他们自己阅读文件时无法了解到的东西。指出模式名称、解释设计决策、标明失败模式,并交叉引用相关上下文。
叙事脉络 — 每个导览、每个用户画像
-
定位引导 — 必须是
file或directory步骤,绝不能是纯内容步骤。 使用"file": "README.md", "line": 1或"directory": "src",并把欢迎文本放在 description 中。 纯内容的第一个步骤(没有file、directory或uri)在 VS Code CodeTour 中会渲染为空白页面 — 这是 VS Code 扩展的已知行为,无法配置。 -
高层地图(1–3 个 directory 或 uri 步骤)— 主要模块及其相互关系。 不是每个文件夹 — 只包含此用户画像需要了解的内容。
-
核心路径(file/line、selection、pattern、uri 步骤)— 真正重要的具体代码。 这是导览的核心。阅读并讲解。不要略读。
-
收尾(content)— 读者现在理解了什么、接下来可以做什么, 2–3 个建议的后续导览。如果设置了
nextTour,在此处按名称引用它。
收尾步骤
不要总结 — 读者刚刚读过了。相反,告诉他们现在可以做什么、要避免什么,并建议 2-3 个后续导览。
20 个用户画像
| 用户画像 | 目标 | 必须涵盖 | 避免 |
|---|---|---|---|
| Vibecoder | 快速感受整体氛围 | 入口点、请求流、主要模块。最多 8 个步骤。 | 深入细节、边界情况 |
| 新加入者 | 结构化上手 | 目录、环境搭建、业务上下文、服务边界。 | 高级内部机制 |
| Bug 修复者 | 快速定位根因 | 用户操作 → 触发 → 故障点。复现提示 + 测试位置。 | 架构导览 |
| RCA 调查者 | 为什么会失败 | 因果链、副作用、竞态条件、可观测性。 | 正常路径 |
| 功能讲解者 | 一个功能端到端 | UI → API → 后端 → 存储。功能开关、边界情况。 | 无关功能 |
| PR 审查者 | 正确审查变更 | 变更故事、不变量、风险区域、审查者检查清单。为 PR 设置 uri 步骤。 | 无关上下文 |
| 安全审查者 | 信任边界 | 认证流程、输入验证、密钥处理、敏感汇聚点。 | 无关业务逻辑 |
| 重构者 | 安全重构 | 接缝、隐藏依赖、耦合热点、安全提取顺序。 | 功能讲解 |
| 外部贡献者 | 贡献而不破坏 | 安全区域、代码风格、架构雷区。 | 深层内部机制 |
| 技术负责人 / 架构师 | 形态与理由 | 模块边界、设计权衡、风险热点。 | 逐行走查 |
设计导览系列
当代码库复杂到单个导览无法很好地覆盖时,设计一个系列。
nextTour 字段将它们串联起来:当读者完成一个导览后,VS Code 会自动提议
启动下一个。
在编写任何导览之前先规划系列。 好的系列具备:
- 清晰的递进路径(宽泛 → 狭窄,定位 → 深入)
- 导览之间没有重复步骤
- 每个导览足够独立,单独使用也有价值
在每个导览中将 nextTour 设置为下一个导览的 title(必须完全匹配)。每个导览都应足够独立,单独使用也有价值。
CodeTour 无法做到的事
如果被要求实现以下任何一项,请明确说明不支持 — 不要建议不存在的变通方法:
| 请求 | 实际情况 |
|---|---|
| X 秒后自动前进到下一步 | 不支持。导航始终是手动的 — 读者点击 Next。CodeTour 中没有定时器、延迟或自动播放步骤机制。 |
| 在步骤中嵌入视频或 GIF | 不支持。描述仅为 Markdown 文本。 |
| 运行任意 shell 命令 | 不支持。commands 仅执行 VS Code 命令(例如 workbench.action.terminal.focus),而非 shell 命令。 |
| 分支 / 条件式下一步 | 不支持。导览是线性的。when 控制是否显示某个导览,而非哪一步跟随哪一步。 |
| 不打开文件就显示某一步骤 | 部分支持 — 纯内容步骤可以工作,但第 1 步必须有 file 或 directory 锚点,否则 VS Code 会显示空白页面。 |
反模式
| 反模式 | 修复方法 |
|---|---|
| 文件罗列 — 用“此文件包含……”的方式逐个介绍文件 | 讲一个故事;每一步都应依赖上一步 |
| 泛泛而谈的描述 | 点明这个代码库特有的具体模式/坑点 |
| 猜测行号 | 绝不写下未经阅读文件验证的行号 |
| 忽略人物画像 | 删掉所有不服务于其特定目标的步骤 |
| 虚构的文件 | 如果文件不存在,就跳过该步骤 |
质量检查清单 — 写文件前逐项核对
- 每个
file路径都相对于仓库根目录(没有开头的/或./) - 每个
file路径都已读取并确认存在 - 每个
line行号都通过读取文件验证过(不是猜的) - 每个
directory都相对于仓库根目录并确认存在 - 每个
pattern正则都能匹配文件中的真实行 - 每个
uri都是完整、真实的 URL(https://...) - 如果设置了
ref,它是一个真实的分支/标签/提交 - 如果设置了
nextTour,它与另一个.tour文件的title完全一致 - 只创建了
.tourJSON 文件 — 没有改动任何源代码 - 第一步有
file或directory锚点(纯内容的第一步在 VS Code 中会渲染为空白页) - 导览以一个收尾的内容步骤结束,告诉读者接下来可以做什么
- 每段描述都回答了 SMIG — 情境(Situation)、机制(Mechanism)、影响(Implication)、坑点(Gotcha)
- 由人物画像的优先级驱动步骤选择(删掉所有不服务于其目标的内容)
- 步骤数量与要求的深度和仓库规模相匹配(参见校准表)
- 纯内容步骤最多 2 个(开场 + 收尾)
- 所有字段都符合
references/codetour-schema.json
第 5 步:验证导览
写完导览文件后务必立即运行验证器。不要跳过这一步。
python ~/.agents/skills/code-tour/scripts/validate_tour.py .tours/<name>.tour --repo-root .
验证器会检查:
- JSON 有效性
- 每个
file路径都存在,且每个line都在文件范围内 - 每个
directory都存在 - 每个
pattern正则都能编译,并至少匹配文件中的一行 - 每个
uri都以https://开头 nextTour与.tours/中已存在的导览标题匹配- 纯内容步骤数量(超过 2 个时警告)
- 叙事弧线(没有开场或收尾步骤时警告)
继续之前修复每一个错误。 反复重新运行,直到验证器报告 ✓ 或仅剩警告。警告仅供参考 — 请自行判断。在验证通过之前,不要向用户展示该导览。
VS Code 常见问题: 纯内容的第一步会渲染为空白(改为锚定到 file/directory)。绝对路径或带 ./ 前缀的路径会静默失败。越界的行号会滚动不到任何位置。
如果你无法运行脚本,请手动验证:第 1 步有 file/directory,所有路径都存在,所有行号都在范围内,nextTour 完全匹配。
自动播放: isPrimary: true + 带有 { "codetour.promptForPrimaryTour": true } 的 .vscode/settings.json 会在仓库打开时弹出提示。对于应在任何分支上都出现的导览,省略 ref。
分享: 对于公开仓库,用户可以在 https://vscode.dev/github.com/<owner>/<repo> 打开导览,无需安装。
第 6 步:总结
写完导览后,告诉用户:
- 文件路径(
.tours/<name>.tour) - 一段话总结该导览涵盖的内容以及面向谁
- 如果仓库是公开的,提供
vscode.devURL(这样他们可以立即分享) - 2–3 个建议的后续导览(如果已规划了系列,则是系列中的下一个导览)
- 任何用户要求但实际不存在的文件(要明确说明 — 不要悄悄替换)
文件命名
<persona>-<focus>.tour — kebab-case,同时传达两者:
onboarding-new-joiner.tour
bug-fixer-payment-flow.tour
architect-overview.tour
vibecoder-quickstart.tour
pr-review-auth-refactor.tour
security-auth-boundaries.tour
concept-dependency-injection.tour
rca-login-outage.tour