返回资讯中心
外部精选
软件工程
#开发者实时流

Loose Ends 推出代码存活检查工具,检测 AI 编写或遗留的未使用代码

来源标题:Loose Ends: A check for unused code AI wrote or forgot to remove

Loose Ends 以图结构为基础做存活分析,在合并前检查 AI 编码代理新增或改动过的代码是否仍能从真实入口访问。它会报告未被引用的新文件、被替换但未删除的旧服务(如 UserService 与 UserServiceV2 结构相似度达 100%)以及已注销路由遗留的处理函数,并给出证据链。可通过 npx loose-ends check 运行。

Hacker News 最新sid7322026/11/13 · 今天25 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

有人以为留着这些代码“以后可能用得上”,结果它们一直躺在仓库里吃灰。这个工具就是用来清理这类残留代码的。以下为译文:

基于图的活性检查,专治 AI 写代码时留下的残留。

编程 Agent 写代码很快,但也会留下不少东西:一个从未被调用的 helper、一个和它替换掉的 UserService 并排放着的 UserServiceV2、一个路由被注销了但 handler 还留着。Loose Ends 在合并前检查每一处改动,并给出证据,报告它新增或触及的代码是否仍能从真实入口点到达。

$ npx loose-ends check Loose Ends · check main (dc9af08) → working tree 4 files changed ✖ error orphaned-addition src/lib/pagination.ts:1 File added in this change is not reachable from any entry point. Import it from live code, add it to entries, or mark it with // loose-ends-file: dormant <reason>. ✖ error superseded src/services/users.ts:1 src/services/users.ts appears to have been replaced by src/services/users-v2.ts#listUsersV2 but was not removed: its callers now use the new code (src/routes/users.ts); the names match; 100% structural similarity. Delete it, or mark it dormant with a reason. edge removed: src/routes/users.ts → src/services/users.ts was reached via: src/server.ts → src/routes/index.ts → src/routes/users.ts → src/services/users.ts root: entry point "src/server.ts" of express-api-example related: src/services/users-v2.ts#listUsersV2 Summary: 2 errors, 0 warnings, 0 info Files: 6 live, 0 test-only, 2 orphaned, 0 uncertain, 0 dormant Result: fail (2 findings in failOn: orphaned-addition, superseded)

这就是 express-api 示例在一次 Agent 风格改动之后的样子:新增了一个 v2 服务并接入,原服务被丢在一旁,同时还加了一个没人用的分页 helper。

新增的代码必须能从公认的产品入口点到达。

改动不得通过移除保持原有代码存活的边,让既有代码变成孤儿。

被替换的实现必须删除,或者给出明确理由。

Loose Ends 会为 TypeScript、JavaScript、Python 和 Java 代码构建一张 Liveness Graph:imports、exports、re-exports、顶层声明之间的引用、动态 import,以及包依赖。它从包清单、脚本、框架约定(Next.js 路由、Vite 入口、浏览器扩展 manifest、serverless functions、工具配置、Django apps、pyproject entry points、Dockerfile 和 Procfile 中的服务命令、Spring 与 Jakarta 注解、Android manifest 和 layout)、配置以及测试中寻找根节点。它分析 base 和 head 两个版本,只报告这次改动造成的影响。既有的死代码永远不会阻塞 pull request。

它不是让 LLM 去猜代码看起来是否没人用,也不是通用代码审查器、格式化工具或安全扫描器。它不会声称未被观测到的代码就可以安全删除,也绝不在缺少确定性证据和通过的验证运行的情况下删除任何东西。

bench/RESULTS.md 里有在公开仓库上的结果,包括约 700 个 Python 和 Java commit 通过 check 重放,以及对 30 个热门仓库的扫描。

npm install --save-dev loose-ends

需要 Node.js 20 或更高版本,以及 git。

Python 和 Java 项目不需要 package.json。装好 Node 后,在仓库根目录运行 npx loose-ends check 即可。

npm 包通过 GitHub Actions 带 provenance 发布,因此每个版本都能链接回它构建时所用的 commit。

npx loose-ends check # working tree vs. 与默认分支的 merge base npx loose-ends check --base origin/main --head HEAD npx loose-ends check --format markdown # 还支持:json、sarif npx loose-ends scan # 全项目报告既有债务 npx loose-ends explain src/lib/format.ts#formatUser npx loose-ends roots # 什么算作入口点,以及为什么 npx loose-ends fix --verify --patch cleanup.diff npx loose-ends init # 生成 loose-ends.config.json 初始模板

check 通过时退出码为 0,有阻塞性发现时为 1,无法运行时为 2。

Kind Severity 含义

orphaned-addition error 新增的代码没有任何生产根节点能到达。

newly-orphaned error 改动前是活的,改动后不再是活的。

superseded error 被替换的实现没有删除。

invalid-suppression error 某个 suppression 或 dormant 标记没有理由、已过期,或没有匹配到任何东西。

test-only-addition warning 新增的代码只有测试能到达。

newly-test-only warning 生产代码不再使用这段代码,只有测试还在用。

duplicate warning 新增的代码与某个既有的活跃实现几乎完全相同。

unused-dependency warning 没有任何活跃代码 import 的依赖。

uncertain info 可达性取决于图无法解析的动态 import。

scan 报告的是既有代码而非某次改动,因此它使用 orphaned(没有任何东西能到达)和 test-only(只有测试能到达),外加 unused-dependency 和 uncertain。除非传入 --fail,否则它以 0 退出。

每种 kind 的含义以及该怎么处理,见 docs/findings.md。

所有选项都是可选的。npx loose-ends init 会写出一个 loose-ends.config.json 初始模板:

"$schema": "https://raw.githubusercontent.com/sid732/loose-ends/main/schema/config.schema.json

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →