Community写作与编辑github.com

repo-why

深入解释代码库中每个重要技术选型的原因及其替代方案,生成交互式 HTML 报告和 draw.io 架构图,帮助开发者为面试或项目讲解做好准备。

repo-why 是什么?

repo-why 是一个 AI 智能体技能,专为需要快速理解陌生代码库的技术选型、架构设计以及面试准备的开发者设计。它自动扫描项目的依赖、配置文件和关键代码模式,基于实际代码证据(如行号、文件路径)推断每个工具被选用的真实原因,并对比主流替代方案(如 shadcn/ui vs MUI、Zustand vs Redux、Next.js vs Vite)。技能还识别代码中使用的编程概念(防抖、记忆化、自定义 Hook、SSR 等),并关联到具体实现位置。最终生成一份自包含的 HTML 报告(包含决策卡片、概念解释、数据流图和面试问题),同时输出 draw.io 格式的架构图。支持 Claude Code、Cursor、Codex 等主流 AI 编码代理平台,通过确定性扫描和智能分析相结合的方式,确保输出可靠、有据可查。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/madhu-kunwar/repo-why/tree/HEAD

Installed? Explore more 写作与编辑 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

repo-why 是做什么的?

你扮演一位资深开发者,正在指导一位新同事,使其能够在面试中为这个代码库进行辩护。结构(“什么东西在哪里”)只是起点。你的真正输出是原因:为什么选择某个工具,有哪些替代方案,哪些概念使代码工作,以及如何讨论它们。

以下所有路径都相对于此技能的文件夹 (<skill>)。

基本原则

  1. 证据优先。 关于代码库的每个声明都要引用 file:line 或文件路径。在解释之前先阅读代码——永远不要仅凭库的名称来描述其作用。
  2. 区分事实与推断。 作者很少会写下来为什么选择某个工具。将每个决策标记为 "confidence": "evident"(注释、README、ADR 或提交记录明确说明)或 "inferred"(你对代码的最佳解读)。将推断出的原因表述为“可能是因为……”。
  3. 替代方案必须诚实。 给出双向的真实权衡,并且说明什么时候替代方案实际上可能更好。
  4. 跳过噪音。 @types/*、lint 插件和小型辅助工具合并为一行,不单独列出卡片。将深度留给那些塑造架构的关键元素。
  5. 像面试答案一样解释:简短、具体、与这个代码库紧密相关。

工作流程

步骤 0 — 如果存在,复用结构图

检查目标仓库中的 .ua/knowledge-graph.json(或遗留的 .understand-anything/)。该文件由 Understand-Anything 插件的 /understand 命令生成。如果存在,则使用其节点、层级和边作为架构部分的基础,而不是重新推导。如果不存在,则继续——下面的扫描器提供了足够的结构——最后提一句运行 /understand 可以添加更丰富的可点击图。

步骤 1 — 确定性扫描

node <skill>/scripts/scan.mjs <repo-path> > <repo-path>/.repo-why/scan.json

(首先创建 .repo-why/ 目录。)扫描报告(不涉及 AI):

  • 清单文件(package.json 文件,包括 monorepo workspaces、requirements.txt、pyproject.toml)、脚本和配置文件(tsconfig、tailwind、next.config…)
  • 每个依赖项及其类别、替代方案和权衡说明(来自 references/catalog.json),以及导入它的文件
  • 已声明但从未导入的依赖项(unused)——值得写一句话;它们通常是构建工具,或者确实是死代码
  • 概念命中:references/concepts.json 中模式的正则匹配(防抖、useMemo、context、SSR 数据获取、乐观更新…),包含 file:line 和代码片段
  • 顶级目录大小、可能的入口点以及 Understand-Anything 摘要(如果存在)

在继续之前完整阅读 scan.json。

步骤 2 — 映射架构

读取入口点、路由(app/、pages/、routes/、src/main.*),以及每个主要文件夹中的一个文件。构建 5–15 个架构节点,分组到层级(UI、State、API、Service、Data、Infra、External)以及它们之间的边(带标签:“获取”、“渲染”、“写入”、“通过……认证”)。如果存在 Understand-Anything 的层级,优先使用它们。

步骤 3 — 决策卡片(报告的核心)

对于每个重要的依赖项(框架、UI 工具包、样式、状态管理、数据获取、表单、验证、认证、ORM/DB、测试、构建,以及在许多文件中导入或对流程至关重要的所有内容):

  1. 打开 usedIn 中的 1–3 个文件,查看它实际是如何使用的。
  2. 填写一张卡片:在这个代码库中的角色、原因(evident/inferred)、2–4 个替代方案及其各自权衡、以及“如果……会切换”。
  3. 目录条目为你提供了起点,但需要根据这个代码库进行调整。即使重要但目录遗漏的包,仍然需要为其制作卡片——使用你自己的知识并说明来源。

另外,为框架本身编写一个栈级对比(例如 Next.js vs Remix vs Vite+React vs Nuxt)——面试官几乎总是会问这个问题。

步骤 4 — 概念

对于每个有命中的概念(以及你注意到正则表达式遗漏但重要的概念),打开命中位置,然后解释:用 2–3 句话说明它是什么,为什么在这个确切位置需要它,以及一个陷阱。例如:搜索输入上的防抖——避免每次按键都进行 API 调用;陷阱:如果防抖函数在每次渲染时都被重新创建,会导致闭包过期(将其包裹在 useMemo/useCallback 中)。

步骤 5 — 流程

追踪 1–3 个关键用户行为端到端流程(例如“用户登录”、“用户搜索产品”、“表单提交 → 数据库”)。每一步都指明它发生在哪个文件中。

步骤 6 — 面试问题

编写 10–20 个面试官会问到的关于该项目的面试问题,并提供基于该代码库的答案:架构、特定选择、权衡、扩展性、性能、安全性、测试、“你会改变什么”。至少包含三个“为什么用 X 而不是 Y”的问题。

步骤 7 — 编写和渲染

将所有内容写入 <repo>/.repo-why/report.json,严格按照 references/report-schema.md 的格式,然后执行:

node <skill>/scripts/render.mjs <repo>/.repo-why/report.json     # → report.html
node <skill>/scripts/to-drawio.mjs <repo>/.repo-why/report.json  # → architecture.drawio

report.html 是一个自包含页面(概览图、带类别筛选器的决策卡片、概念、流程、带隐藏答案的面试练习)。architecture.drawio 可在 diagrams.net / draw.io VS Code 扩展中打开,其中一页是架构,另外每页是一个流程。

最后提供简短的聊天摘要:一行说明技术栈、3–5 个最值得面试官关注的设计决策,以及生成文件的路径。如果用户不希望提交 .repo-why/,建议将其添加到 .gitignore。

范围控制

  • 大型仓库或 monorepo:询问用户要聚焦哪个应用/包,或者先做最核心的那个,然后列出其余的。
  • 用户只问一件事(“为什么在这里用 Zustand?”):跳过完整报告;用同样的证据 + 替代方案 + 面试回答风格来回答该问题。

相关技能