find-dead-code
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFind Dead Code
查找死代码
Identify dead code in a codebase. Core rule: code only used in tests is still dead code. Only production usage counts.
识别代码库中的死代码。**核心规则:仅在测试中使用的代码仍属于死代码。**只有生产环境中的使用才算有效使用。
Step 1: Detect Languages, Scope & Test Boundaries
步骤1:检测语言、范围与测试边界
Determine the project structure:
- Check for config files: ,
package.json,tsconfig.json,pyproject.toml,setup.py,Package.swift,.xcodeproj,Cargo.toml,go.mod,pom.xmlbuild.gradle - Glob for source files: ,
**/*.ts,**/*.py,**/*.swift,**/*.go,**/*.rs**/*.java - Identify source roots — where production code lives (e.g., ,
src/,lib/)Sources/ - Partition the codebase into analysis units by top-level source directories (e.g., ,
src/auth/,src/api/,src/utils/). Each directory becomes one subagent's scope in Step 3.lib/models/
If the user specified a scope, restrict analysis to that scope.
确定项目结构:
- 检查配置文件:、
package.json、tsconfig.json、pyproject.toml、setup.py、Package.swift、.xcodeproj、Cargo.toml、go.mod、pom.xmlbuild.gradle - 匹配源文件通配符:、
**/*.ts、**/*.py、**/*.swift、**/*.go、**/*.rs**/*.java - 识别源根目录——生产代码所在位置(例如 、
src/、lib/)Sources/ - 划分代码库:按顶级源目录将代码库划分为分析单元(例如 、
src/auth/、src/api/、src/utils/)。每个目录将成为步骤3中一个子代理的分析范围。lib/models/
如果用户指定了范围,则将分析限制在该范围内。
Test File Patterns
测试文件模式
Establish which files are test files. Code referenced ONLY from these locations is dead.
| Language | Test file patterns |
|---|---|
| TS/JS | |
| Python | |
| Swift | |
| Go | |
| Rust | |
| Java/Kotlin | |
| General | |
Also exclude: test runner configs (, , ), storybook files, benchmark files.
jest.config.*vitest.config.*pytest.ini确定哪些文件是测试文件。仅从这些位置被引用的代码属于死代码。
| 语言 | 测试文件模式 |
|---|---|
| TS/JS | |
| Python | |
| Swift | |
| Go | |
| Rust | |
| Java/Kotlin | |
| 通用 | |
同时排除:测试运行器配置文件(、、)、Storybook文件、基准测试文件。
jest.config.*vitest.config.*pytest.iniStep 2: Quick Wins — CLI Tools (Optional)
步骤2:快速排查——CLI工具(可选)
If a CLI tool is installed, run it as a fast first pass for zero-reference dead code.
| Language | Tool | Check | Run |
|---|---|---|---|
| TS/JS | | | |
| Python | | | |
| Swift | | | |
| Go | | | |
| Rust | compiler warnings | — | |
Important limitation: CLI tools count test imports as real usage. They cannot detect code that is only used in tests. They only find symbols with literally zero references anywhere. Step 3 is required for test-only detection.
If no CLI tool is installed, skip to Step 3. Do not ask the user to install anything.
如果已安装CLI工具,可运行它作为快速初步排查,找出零引用的死代码。
| 语言 | 工具 | 检查命令 | 运行命令 |
|---|---|---|---|
| TS/JS | | | |
| Python | | | |
| Swift | | | |
| Go | | | |
| Rust | 编译器警告 | — | |
重要限制:CLI工具会将测试中的导入视为有效使用。它们无法检测仅在测试中使用的代码。只能找出在任何地方都完全没有引用的符号。步骤3是检测仅测试引用代码的必要环节。
如果未安装任何CLI工具,直接跳到步骤3。不要要求用户安装任何工具。
Step 3: Test-Only Analysis — Parallel Subagents (Core)
步骤3:仅测试引用分析——并行子代理(核心)
This is the primary analysis. Spawn parallel background subagents to systematically find code that is only referenced from tests.
这是主要分析环节。启动并行后台子代理,系统地查找仅在测试中被引用的代码。
Subagent Strategy
子代理策略
For each top-level source directory identified in Step 1, launch one background subagent (using the Agent tool with ). Each subagent receives:
run_in_background: true- Its assigned directory to scan for exported symbols
- The test file patterns from Step 1
- The full project root path so it can grep across the entire codebase
针对步骤1中识别的每个顶级源目录,启动一个后台子代理(使用Agent工具并设置)。每个子代理会收到:
run_in_background: true- 分配给它的目录,用于扫描导出的符号
- 步骤1中的测试文件模式
- 完整的项目根路径,以便在整个代码库中执行grep搜索
Subagent Task
子代理任务
Each subagent performs these steps on its assigned directory:
a) Find exported/public symbols:
| Language | Exported symbol patterns |
|---|---|
| TS/JS | |
| Python | Top-level |
| Swift | |
| Go | Capitalized identifiers: |
| Rust | |
| Java/Kotlin | |
b) For each symbol, grep across the entire codebase for references, excluding:
- The definition file itself
- Generated/vendored directories (,
node_modules/,dist/,build/,vendor/,__pycache__/,.tox/,.build/,DerivedData/)target/
c) Classify each reference as test or production based on the test file patterns.
CRITICAL — same-module references count as production usage. A symbol called by another production file within the same module/package is alive. Do not report symbols as "dead" when they have zero external callers but are used internally. Only report symbols with zero production references from any file. "Unnecessarily public" (could be /unexported) is a visibility issue, not dead code — do not include it.
internald) Report structured results for each symbol:
- Symbol name, type (function/class/const/etc.), definition file and line range
- Number of production references (with file paths) — including same-module references
- Number of test references (with file paths)
- Classification: (zero prod refs anywhere),
dead(only test refs),test-only(has prod refs)alive
每个子代理针对其分配的目录执行以下步骤:
a) 查找导出/公开符号:
| 语言 | 导出符号模式 |
|---|---|
| TS/JS | |
| Python | 顶级 |
| Swift | |
| Go | 大写标识符: |
| Rust | |
| Java/Kotlin | |
b) 对每个符号,在整个代码库中执行grep搜索引用,排除:
- 定义该符号的文件本身
- 生成/第三方依赖目录(、
node_modules/、dist/、build/、vendor/、__pycache__/、.tox/、.build/、DerivedData/)target/
c) 根据测试文件模式将每个引用分类为测试或生产环境引用
关键提示:同一模块内的引用算作生产环境使用。如果一个符号被同一模块内的其他生产文件调用,则该符号是活跃的。当符号没有外部调用者但在内部被使用时,不要将其报告为“死代码”。仅报告在任何文件中都没有生产环境引用的符号。“不必要的公开”(可以设为/不导出)是可见性问题,而非死代码——不要包含此类情况。
internald) 为每个符号报告结构化结果:
- 符号名称、类型(函数/类/常量等)、定义文件及行号范围
- 生产环境引用数量(含文件路径)——包括同一模块内的引用
- 测试环境引用数量(含文件路径)
- 分类:(任何地方都没有生产环境引用)、
dead(只有测试环境引用)、test-only(有生产环境引用)alive
Merging Results
合并结果
After all subagents complete, collect and merge their results. Deduplicate any symbols that appear in multiple reports (e.g., re-exports).
所有子代理完成后,收集并合并它们的结果。对出现在多个报告中的符号(例如重新导出的符号)进行去重。
Step 4: Filter, Classify & Evaluate
步骤4:过滤、分类与评估
Apply these filters to the merged results from Steps 2 and 3:
- Framework entry points: Skip symbols used by convention — React components in barrel files, Django views in URL configs, Go and
init()functions, Go interface implementations, Rustmain(), Rust trait implementations,main()generated code, CLI handlers registered in main, magic/lifecycle methods (#[derive(...)],__init__), serialization methods (__repr__,to_json), interface/protocol implementationsfrom_dict - Re-export chains: Trace barrel files (,
index.ts) before declaring a symbol dead. A symbol re-exported through a barrel may have indirect consumers.__init__.py - Dynamic usage: Flag symbols that might be used via reflection (,
getattr,importlibpackage in Go,reflectin Rust), string-based lookups, or decorator/attribute registration as "likely dead" rather than "definite"proc_macro - Cross-package references: In monorepos, verify a symbol isn't imported by a sibling package before declaring it dead
- Design docs / specs / roadmaps: If the project has spec files, roadmaps, or TODO files (e.g., ,
.turbo/spec.md,ROADMAP.md), cross-reference test-only findings against them. Test-only APIs may be planned features awaiting integration — flag as investigate rather than deleteTODO.md
Classify each finding:
- Definite dead: zero references outside its definition file
- Test-only dead: references exist, but ALL are in test files
- Likely dead: uncertain due to dynamic usage, framework conventions, or complex re-export chains
对步骤2和3的合并结果应用以下过滤规则:
- 框架入口点:跳过按约定使用的符号——桶文件中的React组件、URL配置中的Django视图、Go的和
init()函数、Go接口实现、Rust的main()、Rust trait实现、main()生成的代码、在主文件中注册的CLI处理器、魔术/生命周期方法(#[derive(...)]、__init__)、序列化方法(__repr__、to_json)、接口/协议实现from_dict - 重新导出链:在判定符号为死代码前,追溯桶文件(、
index.ts)。通过桶文件重新导出的符号可能存在间接消费者。__init__.py - 动态使用:将可能通过反射(、
getattr、Go的importlib包、Rust的reflect)、基于字符串的查找或装饰器/注解注册使用的符号标记为“可能死代码”而非“确定死代码”proc_macro - 跨包引用:在单体仓库中,先验证符号是否被兄弟包导入,再判定为死代码
- 设计文档/规格/路线图:如果项目有规格文件、路线图或TODO文件(例如、
.turbo/spec.md、ROADMAP.md),将仅测试引用的结果与这些文件交叉核对。仅测试引用的API可能是等待集成的规划功能——标记为待调查而非待删除TODO.md
对每个结果进行分类:
- 确定死代码:定义文件外无任何引用
- 仅测试引用死代码:存在引用,但全部来自测试文件
- 可能死代码:因动态使用、框架约定或复杂的重新导出链而存在不确定性
Evaluate Findings
评估结果
Run the skill on the classified results to verify each finding against the actual code and weed out false positives. Read the full definition file for each finding — not just the flagged symbol. The surrounding code may reveal that the feature is already implemented differently (e.g., a public method may be test-only while a private keepalive loop in does the real work).
/evaluate-findingsping()handleConnect()Proceed with the evaluation results in the next section.
对分类后的结果运行技能,对照实际代码验证每个结果,排除误报。阅读每个结果的完整定义文件——不只是被标记的符号。周边代码可能显示该功能已通过其他方式实现(例如,公开的方法可能仅用于测试,而中的私有保活循环才是实际生效的逻辑)。
/evaluate-findingsping()handleConnect()根据评估结果进入下一环节。
Recommend Action
推荐操作
For each surviving finding, assign a recommendation:
| Signal | Recommendation |
|---|---|
| No tests, no production usage | delete |
| Has tests but no production usage, and no spec/roadmap reference | delete (method + test assertions) |
| Has tests but no production usage, referenced in spec/roadmap/TODO | investigate (planned feature, not dead) |
| Partially wired up, unclear intent, or needs domain context | investigate |
For findings marked investigate, run the skill to determine whether the code is a planned feature, an unwired integration, or truly dead.
/investigate对每个留存的结果分配推荐操作:
| 信号 | 推荐操作 |
|---|---|
| 无测试,无生产环境使用 | 删除 |
| 有测试但无生产环境使用,且未在规格/路线图/TODO中提及 | 删除(方法+测试断言) |
| 有测试但无生产环境使用,且在规格/路线图/TODO中提及 | 调查(规划中功能,非死代码) |
| 部分已连接,意图不明确,或需要领域上下文 | 调查 |
对标记为调查的结果,运行技能以确定代码是规划中功能、未完成的集成还是真正的死代码。
/investigateCommon Dead Code Patterns
常见死代码模式
Watch for these high-yield patterns that tools and simple grep often miss:
- Test-only state accessors: Public properties/methods that expose internal state solely for test assertions (e.g., ,
isEnabled,count). The module's production consumers use behavior (events, callbacks, side effects) — only tests peek at the internal state. When removing these, the corresponding test assertions must also be removed or rewritten to use behavior-based verification.currentItems - Unused data model fields: Properties on serializable types (Codable structs, dataclasses, POJOs) that are decoded but never read by any production code. When removing a field from a serializable type, also update all data files that encode it (JSON, YAML, XML, database schemas, migration files).
- Vestigial enum cases: Enum cases defined but never constructed or matched against in production code.
- Orphaned convenience methods: Public wrappers that call through to another public method with slightly different parameters, where all callers use the underlying method directly.
留意以下高检出率的模式,这些模式常被工具和简单grep忽略:
- 仅测试状态访问器:仅为测试断言暴露内部状态的公开属性/方法(例如、
isEnabled、count)。模块的生产环境消费者使用的是行为(事件、回调、副作用)——只有测试会查看内部状态。删除这些访问器时,对应的测试断言也必须删除或重写为基于行为的验证方式。currentItems - 未使用的数据模型字段:可序列化类型(Codable结构体、数据类、POJO)上的字段,已被解码但从未被任何生产代码读取。从可序列化类型中删除字段时,还需更新所有对其进行编码的数据文件(JSON、YAML、XML、数据库模式、迁移文件)。
- 遗留枚举值:已定义但从未在生产代码中构造或匹配的枚举值。
- 孤立的便捷方法:调用另一个公开方法的公开包装器,仅参数略有不同,但所有调用者都直接使用底层方法。
Adjacent Findings
相关发现
While scanning for dead code, note (but do not act on) these related issues for the user:
- Bugs near dead code: Dead code often neighbors buggy code — a missing call, a wiring gap, or an incomplete integration
- Unwired features: Code that is "almost alive" — defined, tested, but not connected to the rest of the system. Distinguish from truly dead code.
在扫描死代码时,记录(但不处理)以下相关问题供用户参考:
- 死代码附近的Bug:死代码常与有问题的代码相邻——缺失的调用、未连接的逻辑或未完成的集成
- 未连接的功能:“几乎活跃”的代码——已定义、已测试,但未与系统其他部分连接。需与真正的死代码区分开。
Step 5: Present Findings
步骤5:呈现结果
Group results by confidence level:
按置信度分组展示结果:
Definite Dead (zero references outside definition)
确定死代码(定义文件外无引用)
| File | Symbol | Type | Line Range | Recommendation |
|---|
| 文件 | 符号 | 类型 | 行号范围 | 推荐操作 |
|---|
Test-Only Dead (referenced only in tests)
仅测试引用死代码(仅在测试中被引用)
| File | Symbol | Type | Test files referencing it | Recommendation |
|---|
| 文件 | 符号 | 类型 | 引用它的测试文件 | 推荐操作 |
|---|
Likely Dead (verify manually)
可能死代码(需手动验证)
| File | Symbol | Type | Reason for uncertainty | Recommendation |
|---|
Include:
- Total count per category
- Estimated removable lines
- Suggested removal order (leaf dependencies first)
| 文件 | 符号 | 类型 | 不确定性原因 | 推荐操作 |
|---|
需包含:
- 每个分类的总数
- 估计可移除的代码行数
- 建议的移除顺序(先移除叶子依赖)
Rules
规则
- If more than 8 top-level source directories are identified, ask the user to narrow scope or group related directories into fewer subagent batches.
- If no dead code is found, report that explicitly and note any scope limitations or analysis caveats.
- 如果识别出超过8个顶级源目录,请要求用户缩小范围或把相关目录分组为更少的子代理批次。
- 如果未找到死代码,明确报告这一点,并说明任何范围限制或分析注意事项。