code-tour

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Code Tour Skill

Code Tour Skill

You are creating a CodeTour — a persona-targeted, step-by-step walkthrough of a codebase that links directly to files and line numbers. CodeTour files live in
.tours/
and work with the VS Code CodeTour extension.
Two scripts are bundled in
scripts/
:
  • scripts/validate_tour.py
    — run after writing any tour. Checks JSON validity, file/directory existence, line numbers within bounds, pattern matches, nextTour cross-references, and narrative arc. Run it:
    python ~/.agents/skills/code-tour/scripts/validate_tour.py .tours/<name>.tour --repo-root .
  • scripts/generate_from_docs.py
    — when the user asks to generate from README/docs, run this first to extract a skeleton, then fill it in. Run it:
    python ~/.agents/skills/code-tour/scripts/generate_from_docs.py --persona new-joiner --output .tours/skeleton.tour
Two reference files are bundled:
  • references/codetour-schema.json
    — the authoritative JSON schema. Read it to verify any field name or type. Every field you use must conform to it.
  • references/examples.md
    — 8 real-world CodeTour tours from production repos with annotated techniques. Read it when you want to see how a specific feature (
    commands
    ,
    selection
    ,
    view
    ,
    pattern
    ,
    isPrimary
    , multi-tour series) is used in practice.
你将创建一个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。可通过它验证任何字段名称或类型,你使用的每个字段都必须符合该schema。
  • references/examples.md
    —— 来自生产仓库的8个真实CodeTour导览示例,并附带技术注释。当你想了解特定功能(
    commands
    selection
    view
    pattern
    isPrimary
    、多导览系列)的实际用法时,可以参考该文件。

Real-world
.tour
files on GitHub

GitHub上的真实
.tour
文件

These are confirmed production
.tour
files. Fetch one when you need a working example of a specific step type, tour-level field, or narrative structure — don't write from memory when the real thing is one fetch away.
Find more with the GitHub code search: https://github.com/search?q=path%3A**%2F*.tour+&type=code
这些是经过验证的生产环境
.tour
文件。当你需要特定步骤类型、导览级字段或叙事结构的可用示例时,可以获取这些文件——不要仅凭记忆编写,真实示例触手可及。
可通过GitHub代码搜索找到更多:https://github.com/search?q=path%3A**%2F*.tour+&type=code

By step type / technique demonstrated

按演示的步骤类型/技术分类

What to studyFile URL
directory
+
file+line
(contributor onboarding)
https://github.com/coder/code-server/blob/main/.tours/contributing.tour
selection
+
file+line
+ intro content step (accessibility project)
https://github.com/a11yproject/a11yproject.com/blob/main/.tours/code-tour.tour
Minimal tutorial — tight
file+line
narration for interactive learning
https://github.com/lostintangent/rock-paper-scissors/blob/master/main.tour
Multi-tour repo with
nextTour
chaining (cloud native OCI walkthroughs)
https://github.com/lucasjellema/cloudnative-on-oci-2021/blob/main/.tours/introduction.tour
isPrimary: true
(marks the onboarding entry point)
https://github.com/nickvdyck/webbundlr/blob/main/.tours/getting-started.tour
pattern
instead of
line
(regex-anchored steps)
https://github.com/nickvdyck/webbundlr/blob/main/.tours/architecture.tour
学习内容文件链接
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

Notes on each

各示例说明

coder/code-server
— Contributing
Opens with a
directory
step on
src/
that orients with a single sentence, then drives straight into
src/node/entry.ts
line 157. Clean external-contributor structure: orientation → entry point → key subsystems → links to FAQ docs via URI steps. Good model for any contributor tour.
a11yproject/a11yproject.com
— Code Tour
Uses
selection
to highlight a block within
package.json
(start line 1, end varies) alongside a
line
for the same file. Shows how to vary step type on the same file. Note: the intro step in this tour is content-only — in some VS Code versions this renders blank. Prefer anchoring the first step to a file or directory and putting the welcome text in its description.
lostintangent/rock-paper-scissors
— main.tour
Only 4–5 steps. Shows how a minimal tour can be complete: every step tells the reader something actionable, links to a specific line, and ends with a clear call to action ("try changing this and watch it take effect"). Good reference when writing a vibecoder or quick-explainer tour.
lucasjellema/cloudnative-on-oci-2021
— multi-tour series
Multiple
.tour
files in the same repo, each scoped to a different cloud service. Browse the
.tours/
directory to see how a series is organized — separate files, clear scoped titles, and
nextTour
linking between them. Good model for a complex domain with a tour-series strategy.
Raw content tip: If GitHub rate-limits the HTML view, prefix
raw.githubusercontent.com
and drop
/blob/
:
https://raw.githubusercontent.com/coder/code-server/main/.tours/contributing.tour
https://raw.githubusercontent.com/a11yproject/a11yproject.com/main/.tours/code-tour.tour
https://raw.githubusercontent.com/lostintangent/rock-paper-scissors/master/main.tour
A great tour is not just annotated files. It is a narrative — a story told to a specific person about what matters, why it matters, and what to do next. Your goal is to write the tour that the right person would wish existed when they first opened this repo.
CRITICAL: Only create
.tour
JSON files. Never create, modify, or scaffold any other files.

coder/code-server
—— 贡献者导览
src/
目录的
directory
步骤开篇,用一句话介绍整体情况,然后直接跳转至
src/node/entry.ts
的157行。结构清晰,适合外部贡献者:定位介绍 → 入口文件 → 核心子系统 → 通过URI步骤链接至FAQ文档。是任何贡献者导览的优秀模板。
a11yproject/a11yproject.com
—— 代码导览
使用
selection
高亮
package.json
中的代码块(起始行1,结束行不定),同时搭配同一文件的
line
步骤。展示了如何对同一文件使用不同的步骤类型。注意:该导览的介绍步骤仅包含内容——在部分VS Code版本中会显示空白页。建议将第一步锚定至文件或目录,并在描述中加入欢迎文本。
lostintangent/rock-paper-scissors
—— main.tour
仅包含4-5个步骤。展示了极简导览也可以完整覆盖核心内容:每个步骤都向读者传达可操作的信息,关联至特定行,并以明确的行动号召结尾(“尝试修改此处,观察效果”)。是编写快速浏览者或快速解释类导览的优质参考。
lucasjellema/cloudnative-on-oci-2021
—— 多导览系列
同一仓库中包含多个
.tour
文件,每个文件对应不同的云服务。浏览
.tours/
目录可了解系列导览的组织方式——独立文件、清晰的标题范围、以及通过
nextTour
实现的导览间关联。是复杂领域采用系列导览策略的优秀模板。
原始内容提示: 如果GitHub的HTML视图触发了速率限制,可在链接前添加
raw.githubusercontent.com
并移除
/blob/
https://raw.githubusercontent.com/coder/code-server/main/.tours/contributing.tour
https://raw.githubusercontent.com/a11yproject/a11yproject.com/main/.tours/code-tour.tour
https://raw.githubusercontent.com/lostintangent/rock-paper-scissors/master/main.tour
优秀的导览不只是带注释的文件,它是一个叙事——向特定人群讲述什么内容重要、为什么重要,以及下一步该做什么。你的目标是编写一份导览,让目标人群在首次打开仓库时,会希望这份导览早就存在。
重要提示:仅创建
.tour
JSON文件。禁止创建、修改或搭建任何其他文件。

Step 1: Discover the repo

步骤1:探索仓库

Before asking the user anything, explore the codebase:
  • List the root directory, read the README, and check key config files (package.json, pyproject.toml, go.mod, Cargo.toml, composer.json, etc.)
  • Identify the language(s), framework(s), and what the project does
  • Map the folder structure 1–2 levels deep
  • Find entry points: main files, index files, app bootstrapping
  • Note which files actually exist — every path you write in the tour must be real
If the repo is sparse or empty, say so and work with what exists.
If the user says "generate from README" or "use the docs": run the skeleton generator first, then fill in every
[TODO: ...]
by reading the actual files:
bash
python skills/code-tour/scripts/generate_from_docs.py \
  --persona new-joiner \
  --output .tours/skeleton.tour
在向用户提问前,先探索代码库:
  • 列出根目录内容,阅读README,查看关键配置文件(package.json、pyproject.toml、go.mod、Cargo.toml、composer.json等)
  • 确定项目使用的语言、框架,以及项目功能
  • 梳理1-2层深度的文件夹结构
  • 找到入口点:主文件、索引文件、应用启动文件
  • 记录实际存在的文件——导览中写入的每个路径都必须真实存在
如果仓库内容稀疏或为空,请告知用户,并基于现有内容进行操作。
如果用户要求“基于README生成”或“使用文档”: 先运行框架生成脚本,然后通过读取实际文件填充所有
[TODO: ...]
内容:
bash
python skills/code-tour/scripts/generate_from_docs.py \\
  --persona new-joiner \\
  --output .tours/skeleton.tour

Entry points by language/framework

按语言/框架划分的入口点

Don't read everything — start here, then follow imports.
StackEntry points to read first
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)
无需阅读所有内容——从以下入口点开始,再根据依赖关系延伸阅读。
技术栈优先阅读的入口点
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)

Repo type variants — adjust focus accordingly

仓库类型变体——调整关注重点

The same persona asks for different things depending on what kind of repo this is:
Repo typeWhat to emphasizeTypical anchor files
Service / APIRequest lifecycle, auth, error contractsrouter, middleware, handler, schema
Library / SDKPublic API surface, extension points, versioningindex/exports, types, changelog
CLI toolCommand parsing, config loading, output formattingmain, commands/, config
MonorepoPackage boundaries, shared contracts, build graphroot package.json/pnpm-workspace, shared/, packages/
FrameworkPlugin system, lifecycle hooks, escape hatchescore/, plugins/, lifecycle
Data pipelineSource → transform → sink, schema ownershipingest/, transform/, schema/, dbt models
Frontend appComponent hierarchy, state management, routingpages/, store/, router, api/
For monorepos: identify the 2–3 packages most relevant to the persona's goal. Don't try to tour everything — open the tour with a step that explains how to navigate the workspace, then stay focused.
同一角色的需求会因仓库类型不同而有所差异:
仓库类型重点关注内容典型锚定文件
服务/API请求生命周期、认证、错误契约路由、中间件、处理器、schema
库/SDK公共API表面、扩展点、版本控制索引/导出文件、类型定义、变更日志
CLI工具命令解析、配置加载、输出格式化主文件、commands/目录、配置文件
单体仓库包边界、共享契约、构建图根目录package.json/pnpm-workspace、shared/、packages/
框架插件系统、生命周期钩子、逃生舱口core/、plugins/、生命周期文件
数据管道源→转换→输出、schema归属ingest/、transform/、schema/、dbt模型
前端应用组件层级、状态管理、路由pages/、store/、路由文件、api/
对于单体仓库:确定与角色目标最相关的2-3个包。不要尝试导览所有内容——在导览开篇添加一个步骤,说明如何导航工作区,然后聚焦重点内容。

Large repo strategy

大型仓库策略

For repos with 100+ files: don't try to read everything.
  1. Read entry points and the README first
  2. Build a mental model of the top 5–7 modules
  3. For the requested persona, identify the 2–3 modules that matter most and read those deeply
  4. For modules you're not covering, mention them in the intro step as "out of scope for this tour"
  5. Use
    directory
    steps for areas you mapped but didn't read — they orient without requiring full knowledge
A focused 10-step tour of the right files beats a scattered 25-step tour of everything.

对于包含100+文件的仓库:无需尝试阅读所有内容。
  1. 先阅读入口点和README
  2. 建立对前5-7个模块的心智模型
  3. 针对目标角色,确定最相关的2-3个模块并深入阅读
  4. 对于未覆盖的模块,在介绍步骤中说明“本导览不包含这些内容”
  5. 对已梳理但未深入阅读的区域,使用
    directory
    步骤——无需完全了解内容即可帮助用户定位
聚焦于正确文件的10步导览,远胜于零散覆盖所有内容的25步导览。

Step 2: Read the intent — infer everything you can, ask only what you can't

步骤2:理解用户意图——尽可能推断信息,仅在必要时提问

One message from the user should be enough. Read their request and infer persona, depth, and focus before asking anything.
用户的一条消息应足够支撑你完成大部分工作。先阅读用户请求,推断角色、深度和关注重点,再考虑是否需要提问。

Intent map

意图映射

User says→ Persona→ Depth→ Action
"tour for this PR" / "PR review" / "#123"pr-reviewerstandardAdd
uri
step for the PR; use
ref
for the branch
"why did X break" / "RCA" / "incident"rca-investigatorstandardTrace the failure causality chain
"debug X" / "bug tour" / "find the bug"bug-fixerstandardEntry → fault points → tests
"onboarding" / "new joiner" / "ramp up"new-joinerstandardDirectories, setup, business context
"quick tour" / "vibe check" / "just the gist"vibecoderquick5–8 steps, fast path only
"explain how X works" / "feature tour"feature-explainerstandardUI → API → backend → storage
"architecture" / "tech lead" / "system design"architectdeepBoundaries, decisions, tradeoffs
"security" / "auth review" / "trust boundaries"security-reviewerstandardAuth flow, validation, sensitive sinks
"refactor" / "safe to extract?"refactorerstandardSeams, hidden deps, extraction order
"performance" / "bottlenecks" / "slow path"performance-optimizerstandardHot path, N+1, I/O, caches
"contributor" / "open source onboarding"external-contributorquickSafe areas, conventions, landmines
"concept" / "explain pattern X"concept-learnerstandardConcept → implementation → rationale
"test coverage" / "where to add tests"test-writerstandardContracts, seams, coverage gaps
"how do I call the API"api-consumerstandardPublic surface, auth, error semantics
Infer silently: persona, depth, focus area, whether to add
uri
/
ref
,
isPrimary
.
Ask only if you genuinely can't infer:
  • "bug tour" but no bug described → ask for the bug description
  • "feature tour" but no feature named → ask which feature
  • "specific files" explicitly requested → honor them as required stops
Never ask about
nextTour
,
commands
,
when
, or
stepMarker
unless the user mentioned them.
用户表述→ 对应角色→ 深度→ 操作
“针对此PR的导览”/“PR评审”/“#123”pr-reviewer(PR评审者)标准添加指向PR的
uri
步骤;为分支设置
ref
“为什么X会崩溃”/“RCA”/“事件复盘”rca-investigator(根因分析者)标准追踪故障因果链
“调试X”/“Bug导览”/“查找Bug”bug-fixer(Bug修复者)标准入口点→故障点→测试用例
“入职”/“新员工”/“快速上手”new-joiner(新员工)标准目录、设置、业务背景
“快速导览”/“快速概览”/“核心要点”vibecoder(快速浏览者)快速5-8个步骤,仅覆盖核心路径
“解释X的工作原理”/“功能导览”feature-explainer(功能解释者)标准UI→API→后端→存储
“架构”/“技术负责人”/“系统设计”architect(架构师)深入边界、决策、权衡
“安全”/“认证评审”/“信任边界”security-reviewer(安全评审者)标准认证流程、验证、敏感输出
“重构”/“是否可安全提取?”refactorer(重构者)标准衔接点、隐藏依赖、提取顺序
“性能”/“瓶颈”/“慢路径”performance-optimizer(性能优化者)标准热点路径、N+1问题、I/O、缓存
“贡献者”/“开源入职”external-contributor(外部贡献者)快速安全贡献区域、约定、常见陷阱
“概念”/“解释模式X”concept-learner(概念学习者)标准概念→实现→原理
“测试覆盖率”/“在哪里添加测试”test-writer(测试编写者)标准契约、衔接点、覆盖缺口
“如何调用API”api-consumer(API使用者)标准公共表面、认证、错误语义
默默推断: 角色、深度、关注领域、是否添加
uri
/
ref
isPrimary
仅在确实无法推断时提问:
  • “Bug导览”但未描述Bug → 询问Bug详情
  • “功能导览”但未指定功能 → 询问具体功能
  • 明确要求覆盖特定文件 → 必须包含这些文件
除非用户提及,否则不要询问
nextTour
commands
when
stepMarker
相关问题。

PR tour recipe

PR导览模板

When the user says "tour for this PR" or pastes a GitHub PR URL:
  1. Set
    "ref"
    to the PR's branch name
  2. Open with a
    uri
    step pointing to the PR itself — this gives the reviewer the full diff context
  3. Add a
    uri
    step for any related issue or RFC if linked in the PR description
  4. Cover changed files first — what changed and why
  5. Then add steps for files not in the diff that reviewers must understand to evaluate the change correctly (call sites, dependency files, tests)
  6. Flag invariants the change must preserve
  7. Close with a reviewer checklist: what to verify, what tests to run, what to watch out for
json
[
  { "uri": "https://github.com/org/repo/pull/456",
    "title": "The PR", "description": "This PR refactors auth to use refresh tokens. Key concern: session invalidation during migration." },
  { "file": "src/auth/tokenService.ts", "line": 12, "title": "What Changed: Token Issuing", "description": "..." },
  { "file": "src/auth/middleware.ts", "line": 38, "title": "Unchanged But Critical", "description": "This file wasn't touched but depends on the token shape. Verify line 38 still matches." },
  { "title": "Reviewer Checklist", "description": "- [ ] Session invalidation tested?\n- [ ] Old tokens still rejected after migration?\n- [ ] Refresh token rotation tested?" }
]
当用户要求“针对此PR的导览”或粘贴GitHub PR链接时:
  1. "ref"
    设置为PR的分支名称
  2. 以指向PR的
    uri
    步骤开篇——这能为评审者提供完整的差异上下文
  3. 如果PR描述中链接了相关问题或RFC,添加对应的
    uri
    步骤
  4. 优先覆盖已变更的文件——说明变更内容和原因
  5. 然后添加PR差异中未包含但评审者必须了解的文件步骤(调用点、依赖文件、测试用例)
  6. 标记变更必须保留的不变量
  7. 以评审者检查清单结尾:需要验证的内容、需要运行的测试、需要注意的事项
json
[
  { "uri": "https://github.com/org/repo/pull/456",
    "title": "PR详情", "description": "此PR重构了认证逻辑,改用刷新令牌。核心关注点:迁移期间的会话失效问题。" },
  { "file": "src/auth/tokenService.ts", "line": 12, "title": "变更点:令牌颁发", "description": "..." },
  { "file": "src/auth/middleware.ts", "line": 38, "title": "未变更但关键的文件", "description": "此文件未被修改,但依赖令牌格式。请验证第38行是否仍匹配。" },
  { "title": "评审者检查清单", "description": "- [ ] 会话失效是否经过测试?\
- [ ] 迁移后旧令牌是否会被拒绝?\
- [ ] 刷新令牌轮换是否经过测试?" }
]

User-provided customization — always honor these

用户指定的自定义要求——必须遵守

User saysWhat to do
"cover
src/auth.ts
and
config/db.yml
"
Those files are required stops
"pin to the
v2.3.0
tag" / "this commit: abc123"
Set
"ref": "v2.3.0"
"link to PR #456" / pastes a URLAdd a
uri
step at the right narrative moment
"lead into the security tour when done"Set
"nextTour": "Security Review"
"make this the main onboarding tour"Set
"isPrimary": true
"open a terminal at this step"Add
"commands": ["workbench.action.terminal.focus"]
"deep" / "thorough" / "5 steps" / "quick"Override depth accordingly

用户表述操作方式
“覆盖
src/auth.ts
config/db.yml
这些文件是导览的必选节点
“固定到
v2.3.0
标签”/“此提交:abc123”
设置
"ref": "v2.3.0"
“链接到PR #456”/粘贴URL在合适的叙事节点添加
uri
步骤
“完成后跳转至安全导览”设置
"nextTour": "Security Review"
“将此设置为主要入职导览”设置
"isPrimary": true
“在此步骤打开终端”添加
"commands": ["workbench.action.terminal.focus"]
“深入”/“全面”/“5个步骤”/“快速”相应调整导览深度

Step 3: Read the actual files — no exceptions

步骤3:阅读实际文件——无例外

Every file path and line number in the tour must be verified by reading the file. A tour pointing to the wrong file or a non-existent line is worse than no tour.
For every planned step:
  1. Read the file
  2. Find the exact line of the code you want to highlight
  3. Understand it well enough to explain it to the target persona
If a user-requested file doesn't exist, say so — don't silently substitute another.

导览中的每个文件路径和行号都必须通过阅读文件进行验证。指向错误文件或不存在行号的导览,还不如不创建导览。
对于每个计划中的步骤:
  1. 阅读文件
  2. 找到要高亮的代码的确切行号
  3. 充分理解代码,以便向目标角色进行解释
如果用户要求的文件不存在,请告知用户——不要悄悄替换为其他文件。

Step 4: Write the tour

步骤4:编写导览

Save to
.tours/<persona>-<focus>.tour
. Read
references/codetour-schema.json
for the authoritative field list. Every field you use must appear in that schema.
将文件保存至
.tours/<persona>-<focus>.tour
。可通过
references/codetour-schema.json
查看权威字段列表,你使用的每个字段都必须出现在该schema中。

Tour root

导览根结构

json
{
  "$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": []
}
Omit any field that doesn't apply to this tour.
when
— conditional display. A JavaScript expression evaluated at runtime. Only show this tour if the condition is true. Useful for persona-specific auto-launching, or hiding advanced tours until a simpler one is complete.
json
{ "when": "workspaceFolders[0].name === 'api'" }
stepMarker
— embed step anchors directly in source code comments. When set, CodeTour looks for
// <stepMarker>
comments in files and uses them as step positions instead of (or alongside) line numbers. Useful for tours on actively changing code where line numbers shift constantly. Example: set
"stepMarker": "CT"
and put
// CT
in the source file. Don't suggest this unless the user asks — it requires editing source files, which is unusual.

json
{
  "$schema": "https://aka.ms/codetour-schema",
  "title": "描述性标题——角色/目标",
  "description": "一句话说明:此导览面向谁,以及读完后能了解什么。",
  "ref": "main",
  "isPrimary": false,
  "nextTour": "后续导览的标题",
  "steps": []
}
可省略与当前导览不相关的字段。
when
—— 条件显示。这是一个在运行时执行的JavaScript表达式。只有当条件为真时,才会显示此导览。适用于特定角色的自动启动,或在完成简单导览前隐藏高级导览。
json
{ "when": "workspaceFolders[0].name === 'api'" }
stepMarker
—— 将步骤锚点直接嵌入源代码注释中。设置后,CodeTour会在文件中查找
// <stepMarker>
注释,并将其作为步骤位置(替代或配合行号使用)。适用于代码行号经常变化的活跃开发文件,或生成的代码。示例:设置
"stepMarker": "CT"
,然后在源代码中添加
// CT
注释。除非用户要求,否则不建议使用此功能——因为它需要修改源代码,这并不常见。

Step types — the full toolkit

步骤类型——完整工具集

Content step — narrative only, no file. Use for intro and closing. Max 2 per tour.
json
{ "title": "Welcome", "description": "markdown..." }
Directory step — orient to a module. "What lives here."
json
{ "directory": "src/services", "title": "Service Layer", "description": "..." }
File + line step — the workhorse. One specific meaningful line.
json
{ "file": "src/auth/middleware.ts", "line": 42, "title": "Auth Gate", "description": "..." }
Path rule — always relative to repo root.
"file"
and
"directory"
values must be relative to the repository root (the directory that contains
.tours/
). Never use an absolute path (
/Users/...
) and never use a leading
./
. If the repo root is
/projects/myapp
and the file is at
/projects/myapp/src/auth.ts
, write
"src/auth.ts"
— not
./src/auth.ts
, not
/projects/myapp/src/auth.ts
, not
auth.ts
(unless it's actually at the root).
Selection step — a block of logic. Use when one line isn't enough (a function body, a config block, a type definition).
json
{
  "file": "src/core/pipeline.py",
  "selection": { "start": { "line": 15, "character": 0 }, "end": { "line": 34, "character": 0 } },
  "title": "The Request Pipeline",
  "description": "..."
}
Pattern step — match by regex instead of line number. Use when line numbers shift frequently (actively changing files, generated code).
json
{ "file": "src/app.ts", "pattern": "export default class Application", "title": "...", "description": "..." }
URI step — link to an external resource: a PR, issue, RFC, ADR, architecture diagram, Notion doc. Use to bring in context that lives outside the codebase.
json
{
  "uri": "https://github.com/org/repo/pull/456",
  "title": "The PR That Introduced This Pattern",
  "description": "This design was debated in PR #456. The key tradeoff was..."
}
View step — auto-focus a VS Code panel at this step (terminal, problems, scm, explorer).
json
{ "file": "src/server.ts", "line": 1, "view": "terminal", "title": "...", "description": "..." }
Commands step — execute VS Code commands when the reader arrives. Add to any file step.
json
{
  "file": "src/server.ts", "line": 1,
  "title": "Run It",
  "description": "Hit the play button — you'll see the server boot sequence here.",
  "commands": ["workbench.action.terminal.focus"]
}
Useful commands:
CommandWhat it does
editor.action.goToDeclaration
Jump to definition
editor.action.showHover
Show type hover
references-view.findReferences
Show all references
workbench.action.terminal.focus
Open terminal
workbench.action.tasks.runTask
Run a task
workbench.view.scm
Open source control panel
workbench.view.explorer
Open file explorer

内容步骤 —— 仅包含叙事内容,不关联文件。适用于导览开篇和结尾,每个导览最多使用2个。
json
{ "title": "欢迎", "description": "markdown格式内容..." }
目录步骤 —— 帮助用户定位模块。说明“此目录包含什么内容”。
json
{ "directory": "src/services", "title": "服务层", "description": "..." }
文件+行步骤 —— 最常用的步骤类型。指向特定的有意义行。
json
{ "file": "src/auth/middleware.ts", "line": 42, "title": "认证网关", "description": "..." }
路径规则——始终相对于仓库根目录
"file"
"directory"
的值必须相对于仓库根目录(即包含
.tours/
的目录)。禁止使用绝对路径(
/Users/...
)或开头为
./
的路径。如果仓库根目录是
/projects/myapp
,文件路径为
/projects/myapp/src/auth.ts
,则应写为
"src/auth.ts"
——不要写
./src/auth.ts
/projects/myapp/src/auth.ts
auth.ts
(除非文件确实在根目录)。
选区步骤 —— 指向一段逻辑代码块。当单行代码不足以说明问题时使用(比如函数体、配置块、类型定义)。
json
{
  "file": "src/core/pipeline.py",
  "selection": { "start": { "line": 15, "character": 0 }, "end": { "line": 34, "character": 0 } },
  "title": "请求处理管道",
  "description": "..."
}
模式步骤 —— 通过正则表达式匹配,而非行号。适用于行号经常变化的文件(活跃开发的文件、生成的代码)。
json
{ "file": "src/app.ts", "pattern": "export default class Application", "title": "...", "description": "..." }
URI步骤 —— 链接至外部资源:PR、问题、RFC、ADR、架构图、Notion文档。用于引入代码库之外的上下文。
json
{
  "uri": "https://github.com/org/repo/pull/456",
  "title": "引入此模式的PR",
  "description": "此设计在PR #456中经过讨论,核心权衡是..."
}
视图步骤 —— 在此步骤自动聚焦VS Code面板(终端、问题、源代码管理、资源管理器)。
json
{ "file": "src/server.ts", "line": 1, "view": "terminal", "title": "...", "description": "..." }
命令步骤 —— 当读者进入此步骤时,执行VS Code命令。可添加到任何文件步骤中。
json
{
  "file": "src/server.ts", "line": 1,
  "title": "运行服务",
  "description": "点击播放按钮——你将在此处看到服务启动序列。",
  "commands": ["workbench.action.terminal.focus"]
}
常用命令:
命令功能
editor.action.goToDeclaration
跳转到定义
editor.action.showHover
显示类型悬浮提示
references-view.findReferences
显示所有引用
workbench.action.terminal.focus
打开终端
workbench.action.tasks.runTask
运行任务
workbench.view.scm
打开源代码控制面板
workbench.view.explorer
打开文件资源管理器

When to use each step type

各步骤类型的适用场景

SituationStep type
Tour intro or closingcontent
"Here's what lives in this folder"directory
One line tells the whole storyfile + line
A function/class body is the pointselection
Line numbers shift, file is volatilepattern
PR / issue / doc gives the "why"uri
Reader should open terminal or explorerview or commands

场景步骤类型
导览开篇或结尾content(内容步骤)
“此文件夹包含什么内容”directory(目录步骤)
单行代码即可说明核心内容file + line(文件+行步骤)
函数/类体是核心关注点selection(选区步骤)
行号经常变化,文件不稳定pattern(模式步骤)
PR/问题/文档能解释“为什么”uri(URI步骤)
读者需要打开终端或资源管理器view(视图步骤)或commands(命令步骤)

Step count calibration

步骤数量校准

Match steps to depth and persona. These are targets, not hard limits.
DepthTotal stepsCore path stepsNotes
Quick5–83–5Vibecoder, fast explorer — cut ruthlessly
Standard9–136–9Most personas — breadth + enough detail
Deep14–1810–13Architect, RCA — every tradeoff surfaced
Scale with repo size too. A 3-file CLI doesn't get 15 steps. A 200-file monolith shouldn't be squeezed into 5.
Repo sizeRecommended standard depth
Tiny (< 20 files)5–8 steps
Small (20–80 files)8–11 steps
Medium (80–300 files)10–13 steps
Large (300+ files)12–15 steps (scoped to relevant subsystem)

根据深度和角色调整步骤数量。以下是目标值,而非硬性限制。
深度总步骤数核心路径步骤数说明
快速5–83–5适用于快速浏览者、快速探索——果断删减非核心内容
标准9–136–9适用于大多数角色——兼顾广度和足够的细节
深入14–1810–13适用于架构师、根因分析者——揭示所有权衡
还需根据仓库大小调整。一个仅包含3个文件的CLI工具不需要15个步骤,一个包含200个文件的单体应用也不应压缩到5个步骤。
仓库大小推荐的标准深度步骤数
极小(<20个文件)5–8个步骤
小型(20–80个文件)8–11个步骤
中型(80–300个文件)10–13个步骤
大型(300+个文件)12–15个步骤(聚焦于相关子系统)

Writing excellent descriptions — the SMIG formula

编写优质描述——SMIG公式

Every description should answer four questions in order. You don't need four paragraphs — but every description needs all four elements, even briefly.
S — Situation: What is the reader looking at? One sentence grounding them in context. M — Mechanism: How does this code work? What pattern, rule, or design is in play? I — Implication: Why does this matter for this persona's goal specifically? G — Gotcha: What would a smart person get wrong here? What's non-obvious, fragile, or surprising?
Bad description (generic — could apply to any codebase):
"This is the authentication middleware. It checks if the user is authenticated before allowing access to protected routes."
Good description (SMIG applied):
S: Every HTTP request passes through this file before reaching any controller — it's the sole auth checkpoint.
M: Notice the dual-check pattern on line 42: it validates the JWT signature and does a Redis lookup for the session. Both must pass. A valid JWT alone isn't enough if the session was revoked (logout, password reset, force-expire).
I: For a bug fixer: if a user reports being logged out unexpectedly, this is your first stop. Redis miss → 401 → silent logout is the most common failure path.
G: If Redis is down, line 53 propagates the error as a 401 — meaning a Redis outage silently logs everyone out. There's no circuit breaker here. This is tracked in ISSUE-4421, and the workaround is in
config/redis.ts
line 18.
The good description tells the reader something they couldn't learn by reading the file themselves. It names the pattern, explains the design decision, flags the failure mode, and cross-references related context.
Persona vocabulary cheat sheet — speak their language, not generic developer-speak:
PersonaTheir vocabularyAvoid
New joiner"this means", "you'll need to", "the team calls this"acronyms, assumed context
Bug fixer"failure path", "where this breaks", "repro steps"architecture history
Security reviewer"trust boundary", "untrusted input", "privilege escalation"vague "be careful"
PR reviewer"invariant", "this must stay true", "the change story"unrelated context
Architect"seam", "coupling", "extension point", "decision"step-by-step walkthroughs
Vibecoder"the main loop", "ignore for now", "start here"deep explanations

每个描述都应按顺序回答以下四个问题。不需要分成四段,但每个描述都必须包含这四个要素,即使是简要说明。
S — Situation(场景): 读者当前看到的是什么?用一句话说明上下文。 M — Mechanism(机制): 这段代码如何工作?使用了什么模式、规则或设计? I — Implication(影响): 这对该角色的目标有什么重要意义? G — Gotcha(陷阱): 聪明的开发者可能会在这里犯什么错误?有什么不明显、脆弱或令人惊讶的地方?
糟糕的描述(通用表述——适用于任何代码库):
“这是认证中间件,它会在允许访问受保护路由前检查用户是否已认证。”
优秀的描述(应用SMIG公式):
S: 每个HTTP请求在到达任何控制器前都会经过此文件——这是唯一的认证检查点。
M: 注意第42行的双重检查模式:它会验证JWT签名,同时在Redis中查找会话。两者都必须通过。即使JWT有效,如果会话已被撤销(登出、密码重置、强制过期),也无法通过认证。
I: 对于Bug修复者:如果用户报告意外登出,这里是你的第一排查点。Redis查询失败→返回401→静默登出是最常见的故障路径。
G: 如果Redis宕机,第53行会将错误传播为401——这意味着Redis故障会导致所有用户被静默登出。此处没有断路器,该问题在ISSUE-4421中被追踪,解决方法位于
config/redis.ts
的第18行。
优秀的描述能告诉读者仅通过阅读文件无法了解的信息:它命名了模式,解释了设计决策,标记了故障模式,并关联了相关上下文。
角色词汇表——使用他们的语言,而非通用开发术语:
角色他们常用的词汇避免使用
新员工“这意味着”、“你需要”、“团队称之为”缩写、默认读者已知的上下文
Bug修复者“故障路径”、“此处可能崩溃的原因”、“复现步骤”架构历史
安全评审者“信任边界”、“不可信输入”、“权限提升”模糊的“请注意”
PR评审者“不变量”、“此规则必须保持”、“变更背景”无关上下文
架构师“衔接点”、“耦合”、“扩展点”、“决策”逐行导览
快速浏览者“主循环”、“暂时忽略”、“从此处开始”深入解释

Narrative arc — every tour, every persona

叙事逻辑——适用于所有导览和角色

  1. Orientationmust be a
    file
    or
    directory
    step, never content-only.
    Use
    "file": "README.md", "line": 1
    or
    "directory": "src"
    and put your welcome text in the description. A content-only first step (no
    file
    ,
    directory
    , or
    uri
    ) renders as a blank page in VS Code CodeTour — this is a known VS Code extension behaviour, not configurable.
  2. High-level map (1–3 directory or uri steps) — major modules and how they relate. Not every folder — just what this persona needs to know.
  3. Core path (file/line, selection, pattern, uri steps) — the specific code that matters. This is the heart of the tour. Read and narrate. Don't skim.
  4. Closing (content) — what the reader now understands, what they can do next, 2–3 suggested follow-up tours. If
    nextTour
    is set, reference it by name here.
  1. 定位介绍 —— 必须是
    file
    directory
    步骤,不能仅为内容步骤
    。使用
    "file": "README.md", "line": 1
    "directory": "src"
    ,并在描述中加入欢迎文本。
  2. 全局概览(1-3个directory或uri步骤)—— 介绍主要模块及其关系。不需要覆盖所有文件夹,只需要包含与角色目标相关的内容。
  3. 核心路径(file/line、selection、pattern、uri步骤)—— 与角色目标相关的具体代码。这是导览的核心内容,需要深入阅读并详细说明。
  4. 结尾总结(content步骤)—— 说明读者现在能理解什么、下一步可以做什么,以及2-3个建议的后续导览。如果设置了
    nextTour
    ,在此处提及它的名称。

What makes a closing step excellent

如何编写优秀的结尾步骤

The closing is frequently the weakest step. Don't summarize — the reader just read it. Instead:
❌ Bad closing (recap):
"In this tour we covered the entry point, the middleware stack, and the database layer."
✅ Good closing (action + next):
"You now know enough to safely add a new route without breaking auth or session handling. The danger zones to stay away from are
src/auth/tokenService.ts
(don't change the token shape without a migration plan) and
src/db/pool.ts
(connection limits are load-tested at current values).
What's next:
  • If you're fixing a bug → jump to the Bug Fixer: Payment Flow tour for the specific path
  • If you're adding a feature → the Feature Explainer: Notifications tour shows the full pattern
  • If something's on fire → the RCA: Incident Guide tour maps the observability anchors"
The good closing tells the reader what they're now capable of, what to avoid, and gives them a map of where to go next.

结尾步骤往往是最薄弱的部分。不要只是总结——读者刚刚阅读完导览内容。
❌ 糟糕的结尾(总结):
“在本导览中,我们介绍了入口点、中间件栈和数据库层。”
✅ 优秀的结尾(行动指引+后续方向):
“你现在已经掌握了足够的知识,可以安全地添加新路由,而不会破坏认证或会话处理。需要避开的危险区域是
src/auth/tokenService.ts
(修改令牌格式前必须制定迁移计划)和
src/db/pool.ts
(连接限制是经过负载测试的当前值)。
下一步建议:
  • 如果要修复Bug → 跳转至Bug修复者:支付流程导览,查看具体路径
  • 如果要添加功能 → 功能解释者:通知系统导览展示了完整的实现模式
  • 如果发生故障 → RCA:事件指南导览标记了可观测性锚点”
优秀的结尾会告诉读者他们现在能做什么、需要避免什么,以及下一步的方向。

The 20 personas

20种角色

PersonaGoalMust coverAvoid
VibecoderGet the vibe fastEntry point, request flow, main modules. "Start here / Core loop / Ignore for now." Max 8 steps.Deep dives, history, edge cases
New joinerStructured ramp-upDirectories, setup/run instructions, business context, service boundaries, team terms defined.Advanced internals before basics
Reboarding engineerCatch up on what changedWhat's new vs. what they remember. "This used to be X, now it's Y."Re-explaining things they knew
Bug fixerRoot cause fastUser action → trigger → fault points. Validation, branching, error handling. Repro hints + test locations.Architecture tours, business context
RCA / incident investigatorWhy did it failCausality chain. State transitions, side effects, race conditions. Observability anchors.Happy path
Feature explainerOne feature end-to-endUI → API → backend → storage. Feature flags, auth, edge cases, scope.Unrelated features
Concept learnerUnderstand a patternConcept intro → implementation → why this design → tradeoffs → common misunderstanding.Code without conceptual framing
PR reviewerReview the change correctlyThe change story, not just changed files. Invariants. Risky areas. Reviewer checklist. URI step for the PR.Unrelated context
MaintainerLong-term healthArchitectural intent. Extension points. "Do not bypass this layer." Long-lived invariants.One-time setup concerns
RefactorerSafe restructuringSeams, hidden deps, implicit contracts, coupling hotspots, safe extraction order.Feature explanations
Performance optimizerFind bottlenecksHot paths, N+1, I/O, serialization. Caches, batching. Existing benchmarks.Cold paths, setup code
Security reviewerTrust boundaries + abuse pathsAuth flow. Input validation. Secret handling. Sensitive sinks. Safe failure modes.Unrelated business logic
Test writerAdd good testsBehavior contracts. Existing patterns. Mocking seams. Coverage gaps. High-value scenarios.Implementation detail
API consumerCall the system correctlyPublic surface, request/response shapes, auth, error semantics, stable vs. internal.Internal implementation
Platform / infra engineerOperational understandingBoot sequence, config loading, infra deps, background jobs, graceful shutdown.Business logic
Data engineerData lineage + schemasEvent emission, schema definitions, source-to-sink path, data quality, backfill.UI / request flow
AI agent operatorDeterministic navigationStable anchors, allowed edit zones, required validation steps. "Do not infer — read this file first."Ambiguous or implied structure
Product-minded engineerBusiness rules in codeDomain language, business rules, feature toggles, "why does this weird code exist?"Pure infrastructure
External contributorContribute without breakingContribution-safe areas, code style, architecture landmines, typical first-timer mistakes.Deep internals
Tech lead / architectShape and rationaleModule boundaries, design tradeoffs, risk hotspots, future evolution.Line-by-line walkthroughs

角色目标必须覆盖的内容避免内容
Vibecoder(快速浏览者)快速了解仓库核心入口点、请求流程、主要模块。使用“从此处开始/主循环/暂时忽略”等表述。最多8个步骤。深入分析、历史背景、边缘情况
New joiner(新员工)结构化快速上手目录、设置/运行说明、业务背景、服务边界、团队术语解释。在掌握基础前介绍高级内部实现
Reboarding engineer(重返岗位工程师)了解仓库变更内容新内容与他们记忆中内容的差异。说明“以前是X,现在是Y”。重新解释他们已经知道的内容
Bug fixer(Bug修复者)快速定位根因用户操作→触发点→故障点。验证、分支、错误处理。复现提示+测试位置。架构导览、业务背景
RCA / incident investigator(根因分析/事件复盘者)了解故障原因因果链。状态转换、副作用、竞态条件。可观测性锚点。正常流程
Feature explainer(功能解释者)端到端介绍单个功能UI→API→后端→存储。功能开关、认证、边缘情况、范围。无关功能
Concept learner(概念学习者)理解某种模式概念介绍→实现→设计原因→权衡→常见误解。缺乏概念框架的代码讲解
PR reviewer(PR评审者)正确评审变更变更背景,而非仅变更文件。不变量。风险区域。评审者检查清单。添加指向PR的URI步骤。无关上下文
Maintainer(维护者)保障仓库长期健康架构意图。扩展点。强调“不要绕过此层”。长期不变量。一次性设置相关内容
Refactorer(重构者)安全重构代码衔接点、隐藏依赖、隐式契约、耦合热点、安全提取顺序。功能解释
Performance optimizer(性能优化者)找到性能瓶颈热点路径、N+1问题、I/O、序列化。缓存、批量处理。现有基准测试。冷路径、设置代码
Security reviewer(安全评审者)检查信任边界和滥用路径认证流程。输入验证。密钥处理。敏感输出。安全故障模式。无关业务逻辑
Test writer(测试编写者)添加优质测试用例行为契约。现有模式。模拟衔接点。覆盖缺口。高价值场景。实现细节
API consumer(API使用者)正确调用系统公共表面、请求/响应格式、认证、错误语义、稳定与内部接口。内部实现
Platform / infra engineer(平台/基础设施工程师)了解可运维性启动序列、配置加载、基础设施依赖、后台任务、优雅关闭。业务逻辑
Data engineer(数据工程师)了解数据血缘和schema事件发射、schema定义、源到输出路径、数据质量、回填。UI/请求流程
AI agent operator(AI代理操作者)确定性导航稳定锚点、允许编辑的区域、必要的验证步骤。强调“不要推断——先阅读此文件”。模糊或隐含的结构
Product-minded engineer(产品导向工程师)理解代码中的业务规则领域语言、业务规则、功能开关、“为什么这段代码看起来很奇怪?”纯基础设施内容
External contributor(外部贡献者)安全贡献代码可安全贡献的区域、代码风格、架构陷阱、首次贡献者常见错误。深入内部实现
Tech lead / architect(技术负责人/架构师)了解设计和原理模块边界、设计权衡、风险热点、未来演进方向。逐行导览

Designing a tour series

设计导览系列

When a codebase is complex enough that one tour can't cover it well, design a series. The
nextTour
field chains them: when the reader finishes one tour, VS Code offers to launch the next automatically.
Plan the series before writing any tour. A good series has:
  • A clear escalation path (broad → narrow, orientation → deep-dive)
  • No duplicate steps between tours
  • Each tour standalone enough to be useful on its own
Common series patterns:
Onboarding series (new joiner):
  1. "Orientation" → repo structure, how to run it (isPrimary: true)
  2. "Core Request Flow" → entry to response, middleware chain
  3. "Data Layer" → models, migrations, query patterns
  4. "Testing Patterns" → how to write and run tests
Incident / debug series (bug fixer + RCA):
  1. "Happy Path" → normal flow from trigger to response
  2. "Failure Modes" → where it can break and why
  3. "Observability Map" → logs, metrics, traces to look at
Architecture series (tech lead):
  1. "Module Boundaries" → what lives where and why
  2. "Extension Points" → where to add new features
  3. "Danger Zones" → what must never be changed carelessly
When writing a series: set
nextTour
in each tour to the
title
of the next one. The value must match exactly. Tell the reader in the closing step which tour comes next and why they should read it.
当代码库足够复杂,单个导览无法全面覆盖时,可以设计导览系列。通过
nextTour
字段实现导览间的链式关联:当读者完成一个导览后,VS Code会自动提示启动下一个导览。
在编写任何导览前先规划系列。优秀的导览系列应具备:
  • 清晰的升级路径(从宽泛到具体,从定位到深入)
  • 导览间无重复步骤
  • 每个导览都足够独立,可单独使用
常见系列模式:
入职系列(面向新员工):
  1. “定位介绍” → 仓库结构、运行方法(设置
    isPrimary: true
  2. “核心请求流程” → 从入口到响应的中间件链
  3. “数据层” → 模型、迁移、查询模式
  4. “测试模式” → 如何编写和运行测试
事件/调试系列(面向Bug修复者+根因分析者):
  1. “正常流程” → 从触发到响应的正常流程
  2. “故障模式” → 可能崩溃的位置和原因
  3. “可观测性地图” → 需要查看的日志、指标、追踪数据
架构系列(面向技术负责人):
  1. “模块边界” → 各模块的内容和划分原因
  2. “扩展点” → 可添加新功能的位置
  3. “危险区域” → 不能随意修改的内容
编写系列导览时: 在每个导览中设置
nextTour
,使其值等于下一个导览的
title
。值必须完全匹配。在结尾步骤中告诉读者下一个导览是什么,以及为什么应该阅读它。

Hot files — anchor the series

核心文件——作为系列导览的锚点

Some files deserve a step in almost every tour because they're where the system's core rules live. Identify 2–3 of these early and treat them as anchors:
  • The main entry point — every persona needs to see this
  • The central router or dispatcher — where requests branch
  • The primary config loader — where behavior is controlled
  • The auth boundary — the single place permissions are checked
When the same file appears in multiple tours, give it a different framing each time — new joiners get "this is where the server starts", security reviewers get "this is the only place secrets are loaded".

有些文件几乎在每个导览中都值得设置一个步骤,因为它们是系统核心规则的所在之处。尽早确定2-3个这样的文件,并将它们作为锚点:
  • 主入口点 —— 每个角色都需要了解
  • 中央路由或调度器 —— 请求分支的位置
  • 主配置加载器 —— 控制系统行为的位置
  • 认证边界 —— 唯一检查权限的位置
当同一文件出现在多个导览中时,每次都要采用不同的框架——新员工会看到“这是服务启动的位置”,安全评审者会看到“这是唯一加载密钥的位置”。

What CodeTour cannot do

CodeTour无法实现的功能

If asked for any of these, say clearly that it's not supported — do not suggest a workaround that doesn't exist:
RequestReality
Auto-advance to next step after X secondsNot supported. Navigation is always manual — the reader clicks Next. There is no timer, delay, or autoplay step mechanic in CodeTour.
Embed a video or GIF in a stepNot supported. Descriptions are Markdown text only.
Run arbitrary shell commandsNot supported.
commands
only executes VS Code commands (e.g.
workbench.action.terminal.focus
), not shell commands.
Branch / conditional next stepNot supported. Tours are linear.
when
controls whether a tour is shown, not which step follows which.
Show a step without opening a filePartially — content-only steps work, but step 1 must have a
file
or
directory
anchor or VS Code shows a blank page.

如果用户要求以下功能,请明确告知不支持——不要建议不存在的解决方法:
请求实际情况
X秒后自动跳转到下一步不支持。导航始终是手动的——读者需要点击“下一步”。CodeTour中没有计时器、延迟或自动播放步骤的机制。
在步骤中嵌入视频或GIF不支持。描述仅支持Markdown文本。
运行任意Shell命令不支持。
commands
仅能执行VS Code命令(如
workbench.action.terminal.focus
),不能执行Shell命令。
分支/条件下一步不支持。导览是线性的。
when
控制是否显示导览,而不是控制步骤的跳转逻辑。
不打开文件显示步骤部分支持——内容步骤可以,但第一步必须有
file
directory
锚点,否则VS Code会显示空白页。

Anti-patterns — what ruins a tour

反模式——会破坏导览的常见错误

Avoid these. They are the most common failures.
Anti-patternWhat it looks likeThe fix
File listingVisiting
models.py
,
routes.py
,
utils.py
in sequence with descriptions like "this file contains the models"
Tell a story — each step should depend on having seen the previous one. Ask: "why does this step come after the last one?"
Generic descriptions"This is the main entry point of the application."If your description would make sense for any repo, rewrite it. Name the specific pattern, decision, or gotcha that's unique to this codebase.
Line number guessingWriting
"line": 42
without reading the file
Never write a line number you didn't verify. Off-by-one lands the cursor on the wrong code and breaks trust instantly.
Ignoring the personaSecurity reviewer getting a folder structure tourStep selection must reflect what this specific person is trying to accomplish. Cut every step that doesn't serve their goal.
Too many stepsA 20-step "vibecoder" tourRespecting depth means actually cutting steps — not just labeling it "quick."
Hallucinated filesSteps pointing to files that don't existIf a file doesn't exist in the repo, skip the step. Never use a placeholder.
Recap closing"In this tour we covered X, Y, and Z."The closing should tell the reader what they can now do, what to watch out for, and where to go next.
Persona vocabulary mismatchExplaining JWTs to a security reviewerMeet each persona where they are. Security reviewers know what a JWT is — tell them what's wrong with this implementation.
Broken
nextTour
"nextTour"
value doesn't exactly match any tour title
Always copy the title string verbatim. A typo silently breaks the chain.

请避免这些错误,它们是最常见的失败原因。
反模式表现形式修复方法
文件清单式导览按顺序访问
models.py
routes.py
utils.py
,描述为“此文件包含模型”
讲述一个连贯的故事——每个步骤都应依赖于前一个步骤。自问:“为什么这个步骤要放在上一个步骤之后?”
通用描述“这是应用的主入口点。”如果你的描述适用于任何仓库,请重写。指出此代码库特有的模式、决策或陷阱。
猜测行号未阅读文件就写入
"line": 42
永远不要编写未验证的行号。差一行就会导致光标定位到错误的代码,瞬间失去读者的信任。
忽略角色需求为安全评审者提供文件夹结构导览步骤选择必须反映该角色的目标。删除所有与角色目标无关的步骤。
步骤过多面向快速浏览者的20步导览遵守深度要求意味着真正删减步骤——而不只是标记为“快速”。
虚构文件步骤指向不存在的文件如果仓库中没有该文件,跳过此步骤。永远不要使用占位符。
总结式结尾“在本导览中,我们介绍了X、Y和Z。”结尾应告诉读者他们现在能做什么、需要注意什么,以及下一步的方向。
角色词汇不匹配向安全评审者解释JWT是什么从角色的现有知识出发。安全评审者知道JWT是什么——告诉他们此实现中的问题
nextTour
设置错误
"nextTour"
的值与任何导览的
title
不完全匹配
始终直接复制标题字符串。拼写错误会导致链式关联静默失效。

Quality checklist — verify before writing the file

质量检查清单——编写文件前验证

  • Every
    file
    path is relative to the repo root (no leading
    /
    or
    ./
    )
  • Every
    file
    path read and confirmed to exist
  • Every
    line
    number verified by reading the file (not guessed)
  • Every
    directory
    is relative to the repo root and confirmed to exist
  • Every
    pattern
    regex would match a real line in the file
  • Every
    uri
    is a complete, real URL (https://...)
  • ref
    is a real branch/tag/commit if set
  • nextTour
    exactly matches the
    title
    of another
    .tour
    file if set
  • Only
    .tour
    JSON files created — no source code touched
  • First step has a
    file
    or
    directory
    anchor (content-only first step = blank page in VS Code)
  • Tour ends with a closing content step that tells the reader what they can do next
  • Every description answers SMIG — Situation, Mechanism, Implication, Gotcha
  • Persona's priorities drive step selection (cut everything that doesn't serve their goal)
  • Step count matches requested depth and repo size (see calibration table)
  • At most 2 content-only steps (intro + closing)
  • All fields conform to
    references/codetour-schema.json

  • 每个
    file
    路径相对于仓库根目录(不以
    /
    ./
    开头)
  • 每个
    file
    路径都已阅读并确认存在
  • 每个
    line
    号都已通过阅读文件验证(未猜测)
  • 每个
    directory
    路径相对于仓库根目录并确认存在
  • 每个
    pattern
    正则表达式都能匹配文件中的真实行
  • 每个
    uri
    都是完整的真实URL(以https://开头)
  • 如果设置了
    ref
    ,它是真实的分支/标签/提交
  • 如果设置了
    nextTour
    ,它与另一个
    .tour
    文件的
    title
    完全匹配
  • 仅创建
    .tour
    JSON文件——未修改源代码
  • 第一步有
    file
    directory
    锚点(仅内容的第一步会导致VS Code显示空白页)
  • 导览以内容步骤结尾,告诉读者下一步能做什么
  • 每个描述都符合SMIG公式——场景、机制、影响、陷阱
  • 角色的优先级决定了步骤选择(删除所有与角色目标无关的步骤)
  • 步骤数量符合请求的深度和仓库大小(参考校准表)
  • 最多使用2个仅内容的步骤(开篇+结尾)
  • 所有字段都符合
    references/codetour-schema.json

Step 5: Validate the tour

步骤5:验证导览

Always run the validator immediately after writing the tour file. Do not skip this step.
bash
python ~/.agents/skills/code-tour/scripts/validate_tour.py .tours/<name>.tour --repo-root .
The validator checks:
  • JSON validity
  • Every
    file
    path exists and every
    line
    is within file bounds
  • Every
    directory
    exists
  • Every
    pattern
    regex compiles and matches at least one line in the file
  • Every
    uri
    starts with
    https://
  • nextTour
    matches an existing tour title in
    .tours/
  • Content-only step count (warns if > 2)
  • Narrative arc (warns if no orientation or closing step)
Fix every error before proceeding. Re-run until the validator reports ✓ or only warnings. Warnings are advisory — use your judgment. Do not show the user the tour until validation passes.
What actually breaks VS Code CodeTour (the real causes of blank/broken steps):
  • Content-only first step — step 1 has no
    file
    ,
    directory
    , or
    uri
    . VS Code opens to a blank page. Fix: anchor step 1 to a file or directory and put the intro text in its description.
  • File path not relative to repo root — absolute paths or
    ./
    -prefixed paths silently fail to open. Fix: always use paths relative to where
    .tours/
    lives (e.g.
    src/auth.ts
    , not
    ./src/auth.ts
    ).
  • Line number out of bounds — VS Code opens the file but scrolls nowhere. The validator catches this.
These are the only structural issues that cause VS Code rendering failures. Description length, markdown formatting, and use of
\n
in JSON strings do NOT affect rendering.
If you can't run scripts, do the equivalent check manually:
  1. Confirm step 1 has a
    file
    or
    directory
    field
  2. Confirm every
    file
    path exists by reading it (relative to repo root, no leading
    ./
    )
  3. Confirm every
    line
    is within the file's line count
  4. Confirm every
    directory
    exists
  5. Read the step titles in sequence — do they tell a coherent story?
  6. Confirm
    nextTour
    matches another tour's
    title
    exactly
Autoplay on repo open
isPrimary: true
makes CodeTour show a "Start Tour?" prompt when the repo opens in VS Code. To make this reliable for everyone who clones the repo, also write
.vscode/settings.json
:
json
{ "codetour.promptForPrimaryTour": true }
Without this file, the prompt depends on each user's global VS Code config. Committed to the repo, it fires for everyone automatically. Create this file whenever you set
isPrimary: true
.
ref
and autoplay:
if the tour has
"ref": "main"
, CodeTour only prompts when the user is on that exact branch or tag. For tours that should appear on any branch, omit
ref
.
Share via vscode.dev — the fastest way for someone to use the tour without cloning the repo. For any public GitHub repo with tours committed to
.tours/
, they can open it directly in the browser:
https://vscode.dev/github.com/<owner>/<repo>
VS Code Web will detect the
.tours/
directory and offer to start the tour. No install needed. Tell the user this URL in your summary when the repo is public.

编写完导览文件后立即运行验证脚本。不要跳过此步骤。
bash
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 CodeTour失效的真实原因(导致空白/损坏步骤的结构问题):
  • 仅内容的第一步 —— 第一步没有
    file
    directory
    uri
    。VS Code会打开空白页。修复方法:将第一步锚定至文件或目录,并在描述中加入介绍文本。
  • 文件路径未相对于仓库根目录 —— 绝对路径或以
    ./
    开头的路径会静默无法打开。修复方法:始终使用相对于
    .tours/
    所在位置的路径(如
    src/auth.ts
    ,而非
    ./src/auth.ts
    )。
  • 行号超出范围 —— VS Code会打开文件,但不会滚动到对应位置。验证器会捕获此问题。
如果无法运行脚本,可手动执行等效检查:
  1. 确认第一步有
    file
    directory
    字段
  2. 确认每个
    file
    路径都存在(相对于仓库根目录,不以
    ./
    开头)
  3. 确认每个
    line
    号都在文件的行号范围内
  4. 确认每个
    directory
    都存在
  5. 按顺序阅读步骤标题——它们是否讲述了连贯的故事?
  6. 确认
    nextTour
    与另一个导览的
    title
    完全匹配
仓库打开时自动播放 —— 设置
isPrimary: true
后,当仓库在VS Code中打开时,CodeTour会显示“开始导览?”的提示。为了让所有克隆仓库的用户都能可靠地看到此提示,还需要编写
.vscode/settings.json
json
{ "codetour.promptForPrimaryTour": true }
如果没有此文件,提示的显示取决于用户的全局VS Code配置。将此文件提交到仓库后,所有用户打开仓库时都会自动看到提示。当你设置
isPrimary: true
时,请创建此文件。
ref
与自动播放:
如果导览设置了
"ref": "main"
,CodeTour仅会在用户处于该分支或标签时显示提示。如果希望导览在任何分支都能显示,请省略
ref
通过vscode.dev分享 —— 无需克隆仓库即可快速使用导览的方法。对于任何包含
.tours/
目录的公开GitHub仓库,用户可直接在浏览器中打开:
https://vscode.dev/github.com/<owner>/<repo>
VS Code Web会检测到
.tours/
目录,并提示启动导览。无需安装任何软件。如果仓库是公开的,可在总结中告知用户此URL。

Step 6: Summarize

步骤6:总结

After writing the tour, tell the user:
  • File path (
    .tours/<name>.tour
    )
  • One-paragraph summary of what the tour covers and who it's for
  • The
    vscode.dev
    URL if the repo is public (so they can share it immediately)
  • 2–3 suggested follow-up tours (or the next tour in the series if one was planned)
  • Any user-requested files that didn't exist (be explicit — don't quietly substitute)

编写完导览后,告知用户:
  • 文件路径(
    .tours/<name>.tour
  • 一段总结,说明导览覆盖的内容和面向的人群
  • 如果仓库是公开的,提供
    vscode.dev
    链接(方便用户立即分享)
  • 2-3个建议的后续导览(如果是系列导览,说明下一个导览)
  • 明确告知用户哪些他们要求的文件不存在(不要悄悄替换)

File naming

文件命名规则

<persona>-<focus>.tour
— kebab-case, communicates both:
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
<persona>-<focus>.tour
—— 使用短横线分隔的小写字母,同时传达角色和关注重点:
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
```",