ast-grep
Skill0 starsChanged 3 months agoMITView on GitHub
AST-aware structural code search and rewrite via ast-grep.
21 other projects use a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- zxyycom/skillstheir own version, first seen Nov 8, 2026
- coleam00/skillstheir own version, first seen Nov 2, 2026
- hugefiver/dsmmedited, first seen Nov 1, 2026
- AprilNEA/OpenLogitheir own version, first seen Oct 17, 2026
- phalbohr/skillstheir own version, first seen Oct 13, 2026
- moeru-ai/auvtheir own version, first seen Oct 10, 2026
Used with
Projects with it also use rust, create-pr and 2 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
MicrosoftSkillrust
Use this guide when working on Rust changes in the FAST monorepo.
Also in 3 projects that use this
SentrySkillcreate-pr
Create pull requests following Sentry conventions. Use when opening PRs, writing PR descriptions, or preparing changes for review. Follows Sentry's code review guidelines.
Also in 4 projects that use this
GoogleSkilltdd
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
Also in 4 projects that use this
SentrySkillcommit
Create commit messages following Sentry conventions. Use when committing code changes, writing commit messages, or formatting git history. Follows conventional commits with Sentry-specific issue references.
Also in 3 projects that use this
Other versions21 projects use a version of this.
Word for word · 0
None found.
Edited · 1
- hugefiver/dsmm★ 156% same
Wrote their own version · 20
- AprilNEA/OpenLogi★ 25ksame name
- ccusage/ccusage★ 19ksame name
- ryoppippi/ccusage★ 19ksame name
- warp-drive-data/warp-drive★ 3.2ksame name
- coleam00/skills★ 730same name
- nodetool-ai/nodetool★ 615same name
- moeru-ai/auv★ 207same name
- damusix/skills★ 61same name
- ulpi-io/browse★ 15same name
- tstapler/dotfiles★ 8same name
10 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository87 other files it gives its agents.
- hermes/AGENTS.mdAGENTS.md
- prime/AGENTS.mdAGENTS.md
- apple-notesSkill
- apple-remindersSkill
- findmySkill
- imessageSkill
- vulnerability-triageSkill
- claude-codeSkill
- codexSkill
- computer-useSkill
- hermes-agentSkill
- merge-reconcilerSkill
- opencodeSkill
- architecture-diagramSkill
- ascii-artSkill
- ascii-videoSkill
- baoyu-infographicSkill
- claude-designSkill
- comfyuiSkill
- design-mdSkill
- excalidrawSkill
- humanizerSkill
- manim-videoSkill
- p5jsSkill
- popular-web-designsSkill
- pretextSkill
- sketchSkill
- songwriting-and-ai-musicSkill
- touchdesigner-mcpSkill
- sdlc-reviewSkill
- email-inbox-triageSkill
- himalayaSkill
- codebase-inspectionSkill
- github-authSkill
- github-code-reviewSkill
- github-issuesSkill
- github-issue-to-prSkill
- github-pr-workflowSkill
- github-repo-managementSkill
- gif-searchSkill
- songseeSkill
- youtube-contentSkill
- huggingface-hubSkill
- obsidianSkill
- airtableSkill
- boxSkill
- document-to-action-itemsSkill
- docxSkill
- google-workspaceSkill
- mapsSkill
- meeting-action-itemsSkill
- nano-pdfSkill
- notionSkill
- ocr-and-documentsSkill
- pdfSkill
- powerpointSkill
- product-price-monitorSkill
- session-librarianSkill
- teams-meeting-pipelineSkill
- weekly-review-planningSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. 0 are common, 5 are distinctive, and 11 are very specific to this project.
0
Common
Most of the 20 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 27
Use it whenever the question is about code structure, not bytes:
- Very specific: line 41
Run the helper and sg through the terminal tool.
- Very specific: line 110
If --apply is set, runs pass 2 with --update-all to mutate files.
- Very specific: line 186
When using sg directly in a shell, always single-quote patterns so $VAR is not expanded by the shell.
- Distinctive: line 208
If the user says "find all" or "every", default to ast-grep when the target is shaped (function, class, call, import, statement).
- Very specific: line 216
Search to confirm matches: helper search '<pattern>' --lang X .
- Distinctive: line 219
If wrong: refine pattern, go back to step 1.
- Very specific: line 222
Never apply a rewrite that you have not first dry-run.
- Distinctive: line 236
Do not blindly retry with variations.
- Very specific: line 242
Use inline
-p: when: - Distinctive: line 264
When summarizing for the user, always include the count of files affected, not just the count of matches.
- Very specific: line 282
Validate before searching: When emitting a pattern programmatically, call helper validate first.
- Very specific: line 283
Dry-run before applying: Never run sg run -r ... --update-all without first inspecting the matches.
- Very specific: line 284
Two-pass writes: When using sg directly to both preview and apply, run two invocations — --json ignores --update-all.
- Very specific: line 286
Pattern is code, not regex: When the pattern would need |, .*, \w, or [a-z], switch to search_files instead.
- Very specific: line 287
--langis required for stdin: When piping with --stdin, set --lang explicitly.
“Common” is measured: kept by at least 6 in 10 of the 20 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
ast-grep
ast-grep (binary also named sg) is an AST-aware search and rewrite tool across 25 languages. It treats your pattern as code, parses it the same way it parses your project, and matches structurally. It is the right tool whenever your question depends on code shape rather than text bytes.
This skill ships a Python wrapper at scripts/ast_grep_helper.py and platform install scripts at install.sh (POSIX) and install.ps1 (Windows). The helper adds offline pattern validation, the two-pass write trick, and binary auto-resolution. Use it as your default entry point.
Upstream source: vendored from code-yeongyu/ast-grep-skill (MIT), as shipped in oh-my-openagent's shared-skills bundle.
When to use this skill
Use it whenever the question is about code structure, not bytes:
- "Find every function that takes a
Requestparameter." - "Rewrite every
console.log(x)tologger.info(x)." - "Strip every
as anycast." - "Replace
require(...)withimportacross the repo." - "Find empty catch blocks."
- "Migrate
Optional[X]toX | None." - "Apply this codemod across these 200 files."
- "Run our YAML lint rules and surface violations."
Switch to search_files (or plain rg) when the question is text-shaped (string literal contents, comments, license headers, file names, cross-language regex). When in doubt, ask: "does the answer depend on the language's syntax tree, or just on the file's bytes?" If the former, ast-grep. If the latter, search_files.
Hermes integration notes:
- Run the helper and
sgthrough theterminaltool. Single-quote every pattern so the shell never expands$VAR. - For find→read chains around matches, use
--json-outand process withexecute_coderather than piping through interpreters. - This complements (does not replace) Hermes's
patchtool:patchis for targeted edits you author; ast-grep is for pattern-driven bulk rewrites across many sites.
Three things the agent must internalize
1. ast-grep is NOT regex
The wildcards are $VAR (one AST node) and $$$ (zero or more nodes). Regex syntax fails silently:
| You wrote | What ast-grep saw | What you wanted |
foo|bar | bitwise-or of foo and bar | run two separate searches |
.*foo | not parseable | $$$ foo (if $$$ is a list of nodes) or use rg |
\w+ | not parseable | $VAR to capture any identifier |
[a-z] | character class, not parseable | switch to rg |
The full anti-pattern table is in references/pitfalls.md §1. The helper's validate subcommand catches these mechanically — call it before debugging "no matches" by hand.
2. Patterns must be valid code
The pattern itself must parse. def $FN($$$): fails because the trailing : makes it incomplete; use def $FN($$$). function $NAME without params/body fails; use function $NAME($$$) { $$$ }. Full table per language in references/pitfalls.md §2.
3. --update-all and --json are mutually exclusive (silently)
This is the single biggest gotcha when scripting. sg run -p P -r R --json --update-all returns the JSON but does not mutate files. To both preview AND apply, run two passes:
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 applyThe helper does this automatically when you call replace --apply. Read references/pitfalls.md §9.
The helper script — scripts/ast_grep_helper.py
A single-file Python 3 stdlib wrapper. Same on every OS. The agent's default entry point.
search — find all matches of a pattern
python scripts/ast_grep_helper.py search 'console.log($MSG)' --lang ts src/Validates the pattern offline first. If the pattern looks like regex (\w, .*, |, etc.) the helper exits with a hint and never calls sg — saves a round-trip. Pass --force to skip validation.
Flags:
--lang ts(or any of the 25 languages; aliases likejs,py,rs,ktaccepted)--globs '!**/*.test.ts'(repeatable; prefix!to exclude)-C 3(context lines)--json-out(raw JSON instead of human format)
replace — rewrite by pattern, dry-run by default
# Dry-run preview (default — no files mutated)
python scripts/ast_grep_helper.py replace 'console.log($MSG)' 'logger.info($MSG)' --lang ts src/
# Actually apply
python scripts/ast_grep_helper.py replace 'console.log($MSG)' 'logger.info($MSG)' --lang ts src/ --applyThe helper:
- Validates both
patternandrewritefor hint-detectable mistakes. - Runs pass 1 with
--json=compactto collect matches and show a preview. - If
--applyis set, runs pass 2 with--update-allto mutate files.
scan — run YAML rules
# Discover sgconfig.yml from cwd and run all rules
python scripts/ast_grep_helper.py scan src/
# Run a single rule file
python scripts/ast_grep_helper.py scan -r rules/no-console.yml src/
# Apply auto-fixes
python scripts/ast_grep_helper.py scan -U src/
# CI-friendly GitHub annotations
python scripts/ast_grep_helper.py scan --report-style short src/validate — offline pattern check (no sg call)
Useful for CI lints, pre-commit hooks, and quick sanity checks:
python scripts/ast_grep_helper.py validate '\w+' --lang ts
# → exit 2: regex \w not supported. Use $VAR for identifiers.
python scripts/ast_grep_helper.py validate 'console.log($MSG)' --lang ts
# → exit 0: pattern looks plausible for ast-grep.langs / doctor / install
python scripts/ast_grep_helper.py langs # list 25 supported languages and aliases
python scripts/ast_grep_helper.py doctor # check ast-grep binary availability
python scripts/ast_grep_helper.py install # delegate to install.sh / install.ps1new and test subcommands proxy directly to sg new and sg test.
Direct sg use (when the helper isn't enough)
The helper is opinionated. For full control, drop to sg. The skill ships a CLI cheat sheet in references/cli.md. The minimal idioms:
# 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/
# 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/When using sg directly in a shell, always single-quote patterns so $VAR is not expanded by the shell.
Decision tree — what to use, when
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)
│ └→ search_files / rg
│
├─ 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-repoIf the user says "find all" or "every", default to ast-grep when the target is shaped (function, class, call, import, statement). Default to search_files when the target is text (string content, comment, license header, file name, identifier substring).
Always run dry-run first when rewriting
A bad pattern silently rewrites the wrong thing. The helper's replace defaults to dry-run for this reason. The flow is:
- Search to confirm matches:
helper search '<pattern>' --lang X . - Dry-run rewrite:
helper replace '<pattern>' '<rewrite>' --lang X .(no--apply) - Inspect the dry-run summary: number of matches, files affected, the per-location preview.
- If wrong: refine pattern, go back to step 1.
- If right:
helper replace '<pattern>' '<rewrite>' --lang X . --apply.
Never apply a rewrite that you have not first dry-run. After an --apply in a git repo, review with git diff --stat before committing.
When sg returns 0 matches but you know the code is there
In priority order:
- Run
helper validate '<pattern>' --lang <lang>— catches regex misuse, missing function bodies, Python trailing colons. - Check
--lang—sginfers from extension; if you pass a.tsxfile with--lang ts(nottsx), JSX won't parse. - Inspect the parsed pattern:
sg run -p '<pattern>' --lang <lang> --debug-query=ast --stdin <<< '<sample>'. If it showsERRORnodes, the pattern is malformed. - Check the AST of the target file:
sg run -p '$_' --lang <lang> --debug-query=cst path/to/file | head -40— find thekindyou're trying to match. - Try the playground: https://ast-grep.github.io/playground.html — paste code + pattern, see what's happening.
Do not blindly retry with variations. Each failure has a reason; surface it.
When to use YAML rules vs inline -p patterns
Use inline -p when:
- One-off ad-hoc query.
- The pattern is simple (no constraints, no fix template).
- You're exploring.
Use YAML rules (file under rules/, run via sg scan) when:
- The pattern is reused (lint rule, codemod that runs in CI).
- You need
constraints,transform, complexinside/has, or composite logic. - You want auto-fix (
fix:field). - You want to test the rule (snapshot tests via
sg test).
The full YAML rule schema is in references/yaml-rules.md. Project setup (sgconfig.yml, ruleDirs, utilDirs) is in references/sgconfig.md.
Output discipline
sg run --json=compactproduces an array of match objects:{ file, range: {start, end}, text, replacement?, lines, language, ... }.- Without
--json,sgproduces human-readable colored output suitable for terminals. - The helper's default output is human-readable (file:line:column + match preview). Pass
--json-outfor raw JSON. - The helper's
replacealways summarizes: number of matches, number of files, per-location preview.
When summarizing for the user, always include the count of files affected, not just the count of matches. Users care about blast radius.
Required reading (in order of priority)
references/patterns.md— meta-variables, naming rules, strictness levels. Read when you're unsure why a pattern doesn't match.references/pitfalls.md— the failure-mode field guide. Read when 0 matches surprises you.references/recipes.md— copy-paste patterns by language. Read first when you start a new task.references/cli.md—sg run,sg scan,sg test,sg new,sg lsp. Read when the helper isn't enough.references/yaml-rules.md— YAML rule schema. Read when you outgrow inline patterns.references/sgconfig.md— project-level configuration. Read when you set upsg scanfor a real project.references/install.md— per-OS install methods. Read only ifinstall.sh/install.ps1fail.
Invariants (do not break)
- Validate before searching. When emitting a pattern programmatically, call
helper validatefirst. It catches the regex-misuse class of mistakes that account for ~70% of "0 matches" debug sessions. - Dry-run before applying. Never run
sg run -r ... --update-allwithout first inspecting the matches. The helper'sreplaceenforces this by default. - Two-pass writes. When using
sgdirectly to both preview and apply, run two invocations —--jsonignores--update-all. - Single-quote patterns in shell.
'$VAR'not"$VAR". The shell expands$VARto the empty string in double quotes, breaking the pattern. - Pattern is code, not regex. When the pattern would need
|,.*,\w, or[a-z], switch to search_files instead. Don't try to force ast-grep into a regex shape. --langis required for stdin. When piping with--stdin, set--langexplicitly;sgcannot infer from extension.- Linux: prefer
ast-grepoversgbecausesgcollides withsetgroupsfromutil-linux. The helper handles this; if you callsgdirectly, alias it:alias sg=ast-grep.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

