From tooling
Provides ast-grep CLI syntax, metavariable patterns, and examples for structural code search and rewriting in JavaScript/TypeScript, Python, Go, Rust.
How this skill is triggered — by the user, by Claude, or both
Slash command
/tooling:howto-ast-grepThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
ast-grep (`sg`) matches code by AST structure, not text. Use it instead of grep/ripgrep when you need to match code patterns regardless of whitespace, variable names, or formatting. Patterns must be valid, parsable code in the target language.
ast-grep (sg) matches code by AST structure, not text. Use it instead of grep/ripgrep when you need to match code patterns regardless of whitespace, variable names, or formatting. Patterns must be valid, parsable code in the target language.
Prefer ast-grep over grep when:
Use grep instead when:
# Search for a pattern
sg run -p 'console.log($$$ARGS)' -l javascript src/
# Search and replace (interactive)
sg run -p '$A && $A()' -r '$A?.()' -l typescript --interactive src/
# Apply all replacements without prompting
sg run -p 'var $X = $Y' -r 'const $X = $Y' -l javascript -U src/
# JSON output for programmatic use
sg run -p '$FUNC($$$)' -l python --json src/
# Read from stdin
echo 'let x = 1' | sg run -p 'let $X = $Y' -l javascript --stdin
| Syntax | Matches | Example |
|---|---|---|
$NAME | Exactly one AST node | console.log($MSG) matches console.log("hi") but not console.log("hi", 2) |
$$$NAME | Zero or more nodes | console.log($$$ARGS) matches any number of arguments |
$_NAME | One node, non-capturing | $_OBJ.$METHOD() matches without binding $_OBJ |
Reuse enforces equality: $A == $A matches x == x but not x == y.
Always pass -l <language>. The language determines how patterns are parsed.
JavaScript/TypeScript:
# Find React hooks
sg run -p 'use$HOOK($$$)' -l typescript src/
# Optional chaining candidates
sg run -p '$A && $A.$B' -r '$A?.$B' -l typescript src/
# Async/await patterns
sg run -p 'await $PROMISE' -l javascript src/
Python:
# Find print statements
sg run -p 'print($$$)' -l python src/
# Dictionary access patterns
sg run -p '$DICT[$KEY]' -l python src/
# With statement patterns
sg run -p 'with open($$$ARGS) as $F: $$$BODY' -l python src/
Go:
# Error handling
sg run -p 'if $ERR != nil { return $$$VALS }' -l go ./
# Function calls
sg run -p '$PKG.$FUNC($$$)' -l go ./
Rust:
# Unwrap calls (potential panics)
sg run -p '$EXPR.unwrap()' -l rust src/
# Match expressions
sg run -p 'match $VAL { $$$ARMS }' -l rust src/
| Mistake | Why It Fails | Fix |
|---|---|---|
Using regex in -p | Patterns must be valid code | Write the code structure you want to find |
$VAR + Name | Parsed as $VARN + ame | Use constraints or transform in YAML rules |
| Single quotes in C/Rust patterns | 'x' is a char literal, not a string | Use "x" for strings |
Forgetting -l flag | ast-grep cannot infer language from patterns | Always specify language explicitly |
$A($B, $C) for variadic calls | Only matches exactly 2 args | Use $A($$$ARGS) for any arity |
When CLI patterns aren't expressive enough, use YAML rules:
id: no-unwrap-in-production
language: rust
rule:
pattern: $EXPR.unwrap()
not:
inside:
kind: function_item
has:
field: name
regex: '^test_'
message: "Use expect() or proper error handling instead of unwrap()"
severity: warning
Key rule combinators:
all: All sub-rules must match (AND)any: Any sub-rule can match (OR)not: Sub-rule must NOT matchinside: Target is inside another nodehas: Target contains a descendantfollows/precedes: Sibling orderingRun rules: sg scan --rule path/to/rule.yml src/
$$$ and missing variadic matches-l and getting parse failuresnpx claudepluginhub pbdeuchler/llm-plugins --plugin toolingFinds and replaces code patterns structurally using ast-grep by matching AST structure, for functions with specific signatures, API refactors across files, and regex-resistant anti-patterns.
Performs AST-based code search, structural linting, and safe refactoring using ast-grep (sg). Validates patterns before searching and dry-runs rewrites before applying.
Guides writing ast-grep rules for AST-based structural code search to find patterns like unhandled async functions or specific constructs beyond text matching.