关于 ast-grep
ast-grep 是一项使用 AST 感知型搜索与改写工具的技能,支持 25 种语言。它面向需要按代码结构查找和转换代码的编码 Agent,并提供 Python 辅助脚本来验证模式、预览改动和执行编辑。
主要功能
- 01基于 AST 搜索与改写
- 02通过 Python 脚本搜索和替换
- 03离线验证匹配模式
- 04应用编辑前预览改动
- 05扫描 YAML 规则并自动修复
- 06列出语言并诊断二进制文件
适用场景
- 01按代码结构查找调用、函数或导入
- 02在仓库文件中执行代码迁移
- 03依据 YAML lint 规则检查代码
- 04搜索前验证匹配模式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ code-yeongyu/ ast-grep-skill --skill ast-grep安装后在 Claude Code 中输入/ast-grep确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreLICENSEinstall.ps1README.mdinstall.sh.github/workflows/ci.ymlreferences/patterns.mdinstall.mdcli.mdpitfalls.mdrecipes.mdsgconfig.mdyaml-rules.mdscripts/ast_grep_helper.pytests/smoke.shsmoke.ps1详细介绍
ast-grep
sg(也以 ast-grep 的名称安装)是一款支持 25 种语言的 AST 感知型搜索和重写工具。它会将你的模式视为代码,以解析项目的相同方式解析该模式,并进行结构化匹配。当你的问题取决于 代码结构 而非文本字节时,它就是合适的工具。
此技能提供了一个 Python 包装脚本 scripts/ast_grep_helper.py,以及平台安装脚本 install.sh(POSIX)和 install.ps1(Windows)。该助手增加了离线模式验证、两遍写入技巧和二进制文件自动解析功能。请将其作为默认入口。
何时使用此技能
当用户的问题涉及 代码结构 而非字节时,请使用它:
- “找出所有接受
Request参数的函数。” - “将所有
console.log(x)重写为logger.info(x)。” - “删除所有
as any类型断言。” - “在整个代码库中将
require(...)替换为import。” - “找出空的 catch 块。”
- “将
Optional[X]迁移为X | None。” - “在这 200 个文件中应用此代码转换。”
- “运行我们的 YAML lint 规则并列出违规项。”
如果问题以文本为中心(字符串字面量内容、注释、许可证头、文件名、跨语言正则表达式),请改用普通的 grep / rg。拿不准时,问问自己:“答案取决于该语言的语法树,还是只取决于文件的字节?”前者用 ast-grep,后者用 grep。
Agent 必须牢记的三件事
1. ast-grep 不是正则表达式
通配符是 $VAR(一个 AST 节点)和 $$$(零个或多个节点)。正则表达式语法会静默失效:
| 你写的内容 | ast-grep 的解析结果 | 你的预期 |
|---|---|---|
foo|bar | foo 和 bar 的按位或 | 分别运行两次搜索 |
.*foo | 无法解析 | $$$ foo(如果 $$$ 是节点列表)或使用 rg |
\w+ | 无法解析 | 使用 $VAR 捕获任意标识符 |
[a-z] | 字符类,无法解析 | 改用 rg |
完整的反模式表见 references/pitfalls.md §1。助手的 validate 子命令可以机械地检测这些问题——在手动排查“无匹配项”之前先运行它。
2. 模式必须是有效代码
模式本身必须能够解析。def $FN($$$): 会失败,因为末尾的 : 使其不完整;请使用 def $FN($$$)。不带参数或函数体的 function $NAME 会失败;请使用 function $NAME($$$) { $$$ }。各语言的完整对照表见 references/pitfalls.md §2。
3. --update-all 和 --json 不能同时使用(但不会报错)
这是编写脚本时最大的陷阱。sg run -p P -r R --json --update-all 会返回 JSON,但 不会修改文件。若要同时预览和应用更改,请分两遍运行:
sg run -p P -r R --json=compact . # pass 1: see what would change
sg run -p P -r R --update-all . # pass 2: actually apply
调用 replace --apply 时,助手会自动完成此操作。请阅读 references/pitfalls.md §9。
助手脚本——scripts/ast_grep_helper.py
一个单文件 Python 3 标准库包装脚本。在所有操作系统上用法相同。它是 Agent 的默认入口。
search——查找模式的所有匹配项
python3 scripts/ast_grep_helper.py search 'console.log($MSG)' --lang ts src/
首先离线验证模式。如果模式看起来像正则表达式(\w、.*、| 等),助手会退出并给出提示,不会调用 sg——省去一次往返。传入 --force 可跳过验证。
选项:
--lang ts(或 25 种语言中的任意一种;接受js、py、rs、kt等别名)--globs '!**/*.test.ts'(可重复使用;添加前缀!以排除)-C 3(上下文行数)--json-out(输出原始 JSON,而非人类可读格式)
replace——按模式重写,默认试运行
# Dry-run preview (default — no files mutated)
python3 scripts/ast_grep_helper.py replace 'console.log($MSG)' 'logger.info($MSG)' --lang ts src/
# Actually apply
python3 scripts/ast_grep_helper.py replace 'console.log($MSG)' 'logger.info($MSG)' --lang ts src/ --apply
助手会:
- 验证
pattern和rewrite中是否存在可通过提示检测到的错误。 - 使用
--json=compact运行第一遍,收集匹配项并显示预览。 - 如果设置了
--apply,则使用--update-all运行第二遍,修改文件。
scan——运行 YAML 规则
# Discover sgconfig.yml from cwd and run all rules
python3 scripts/ast_grep_helper.py scan src/
# Run a single rule file
python3 scripts/ast_grep_helper.py scan -r rules/no-console.yml src/
# Apply auto-fixes
python3 scripts/ast_grep_helper.py scan -U src/
# CI-friendly GitHub annotations
python3 scripts/ast_grep_helper.py scan --report-style short src/
validate——离线检查模式(不调用 sg)
适用于 CI lint、提交前钩子和快速检查:
python3 scripts/ast_grep_helper.py validate '\w+' --lang ts
# → exit 2: regex \w not supported. Use $VAR for identifiers.
python3 scripts/ast_grep_helper.py validate 'console.log($MSG)' --lang ts
# → exit 0: pattern looks plausible for ast-grep.
langs / doctor / install
python3 scripts/ast_grep_helper.py langs # list 25 supported languages and aliases
python3 scripts/ast_grep_helper.py doctor # check ast-grep binary availability
python3 scripts/ast_grep_helper.py install # delegate to install.sh / install.ps1
new 和 test 子命令会直接转发给 sg new 和 sg test。
直接使用 sg(当辅助工具不够用时)
这个辅助工具有自己的使用倾向。若要完全掌控,请改用 sg。该技能随附了一份 CLI 速查表,位于 references/cli.md。基本用法:
# Search
sg run -p 'console.log($MSG)' --lang ts src/
# Search with JSON for scripting
sg run -p 'console.log($MSG)' --lang ts --json=compact src/ | jq '.[] | .file'
# Rewrite, dry-run
sg run -p 'console.log($MSG)' -r 'logger.info($MSG)' --lang ts --json=compact src/
# Rewrite, apply
sg run -p 'console.log($MSG)' -r 'logger.info($MSG)' --lang ts --update-all src/
# Pattern from stdin (great for ad-hoc experiments)
echo 'console.log("hi")' | sg run -p 'console.log($MSG)' --lang js --stdin
# Debug a pattern that returns 0 matches
sg run -p '<your pattern>' --lang <lang> --debug-query=ast --stdin <<< '<sample-code>'
# Run YAML rules
sg scan src/
# Inline YAML rule (one-off)
sg scan --inline-rules '
id: no-todo
language: TypeScript
severity: warning
rule: { pattern: TODO }' src/
在 shell 中直接使用 sg 时,务必用单引号括住模式,以免 shell 展开 $VAR。
决策树——何时使用什么
USER asks for "find/rewrite/codemod"
│
├─ structural pattern (function shape, call, class, import, control flow)
│ └→ ast-grep (this skill)
│
├─ text pattern (regex, alternation, character classes, file names)
│ └→ rg / grep
│
├─ semantic question (what variable does this refer to? does this throw?)
│ └→ LSP tools, TypeScript compiler, Pyright, Semgrep with type inference
│
└─ multiple repos / federated search
└→ a search engine + then ast-grep / rg / LSP per-repo
如果用户说“查找所有”或“每个”,当目标具有结构特征(函数、类、调用、导入、语句)时,默认使用 ast-grep。当目标是文本(字符串内容、注释、许可证标头、文件名、标识符子串)时,默认使用 rg。
重写时务必先运行 dry-run
错误的模式可能会悄无声息地重写错误内容。因此,辅助工具的 replace 默认采用 dry-run。流程如下:
- 搜索以确认匹配项:
helper search '<pattern>' --lang X . - 以 dry-run 方式重写:
helper replace '<pattern>' '<rewrite>' --lang X .(不加--apply) - 检查 dry-run 摘要:匹配项数量、受影响的文件,以及各位置的预览。
- 如果不正确:优化模式,返回第 1 步。
- 如果正确:
helper replace '<pattern>' '<rewrite>' --lang X . --apply。
绝不要应用未经 dry-run 的重写。
当 sg 返回 0 个匹配项,但你确定代码确实存在时
按优先顺序:
- 运行
helper validate '<pattern>' --lang <lang>——检查正则用法错误、缺少函数体以及 Python 末尾冒号问题。 - 检查
--lang——sg会根据扩展名推断语言;如果传入.tsx文件却使用--lang ts(而不是tsx),JSX 将无法解析。 - 检查解析后的模式:
sg run -p '<pattern>' --lang <lang> --debug-query=ast --stdin <<< '<sample>'。如果显示ERROR节点,说明模式格式有误。 - 检查目标文件的 AST:
sg run -p '$_' --lang <lang> --debug-query=cst path/to/file | head -40——找到你试图匹配的kind。 - 试试交互式演练场:https://ast-grep.github.io/playground.html——粘贴代码和模式,查看具体情况。
不要盲目尝试各种变体。每次失败都有原因;应将其找出来。
何时使用 YAML 规则,何时使用内联 -p 模式
以下情况使用内联 -p:
- 一次性临时查询。
- 模式简单(没有约束条件或修复模板)。
- 正在探索。
以下情况使用 YAML 规则(放在 rules/ 下的文件,通过 sg scan 运行):
- 模式会重复使用(lint 规则、在 CI 中运行的 codemod)。
- 需要使用
constraints、transform、复杂的inside/has或组合逻辑。 - 需要自动修复(
fix:字段)。 - 需要测试规则(通过
sg test进行快照测试)。
完整的 YAML 规则架构见 references/yaml-rules.md。项目配置(sgconfig.yml、ruleDirs、utilDirs)见 references/sgconfig.md。
输出规范
sg run --json=compact会生成匹配对象数组:{ file, range: {start, end}, text, replacement?, lines, language, ... }。可通过管道传给jq进行后续处理。- 不使用
--json时,sg会输出适合在终端查看、带颜色且易于阅读的内容。 - 辅助工具默认输出易于阅读的内容(文件:行:列 + 匹配预览)。传入
--json-out可获取原始 JSON。 - 辅助工具的
replace始终会生成摘要:匹配项数量、文件数量以及各位置的预览。
向用户总结时,务必注明受影响的文件数量,不能只说匹配项数量。用户关心影响范围。
必读内容(按优先级排序)
references/patterns.md— 元变量、命名规则、严格程度级别。不确定模式为何无法匹配时阅读。references/pitfalls.md— 失败模式指南。对 0 个匹配结果感到意外时阅读。references/recipes.md— 按语言分类的可复制粘贴模式。开始新任务时先阅读。references/cli.md—sg run、sg scan、sg test、sg new、sg lsp。辅助工具不够用时阅读。references/yaml-rules.md— YAML 规则架构。内联模式无法满足需求时阅读。references/sgconfig.md— 项目级配置。为真实项目设置sg scan时阅读。references/install.md— 各操作系统的安装方法。仅在install.sh/install.ps1失败时阅读。
不变量(不得违反)
- 搜索前先验证。 通过程序生成模式时,先调用
helper validate。它能捕获正则误用这一类错误,而这类错误约占“0 个匹配结果”调试会话的 70%。 - 应用前先试运行。 未先检查匹配结果时,绝不要运行
sg run -r ... --update-all。辅助工具的replace默认会强制执行此操作。 - 分两次写入。 直接使用
sg预览并应用时,分两次调用——--json会忽略--update-all。 - 在 Shell 中对模式使用单引号。 使用
'$VAR',而不是"$VAR"。Shell 会将双引号中的$VAR展开为空字符串,从而破坏模式。 - 模式是代码,不是正则表达式。 如果模式需要
|、.*、\w或[a-z],请改用rg。不要试图强行让 ast-grep 采用正则表达式的形式。 - 从标准输入读取时必须指定
--lang。 使用--stdin进行管道传输时,请明确设置--lang;sg无法根据扩展名推断语言。 - Linux:优先使用
ast-grep而非sg,因为sg与setgroups冲突。辅助工具会处理此问题;如果直接调用sg,请为其设置别名:alias sg=ast-grep。