From tooling
Provides ast-grep CLI syntax, metavariable patterns, and examples for structural code search and rewriting in JavaScript/TypeScript, Python, Go, Rust.
npx claudepluginhub pbdeuchler/llm-plugins --plugin toolingThis skill uses the workspace's default tool permissions.
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.
Finds 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, analysis, refactoring, and linting using ast-grep for structural patterns, safe rewrites, and custom rules across languages.
Searches codebases by AST structure using ast-grep to find semantic patterns like function calls, imports, React hooks, async code, and anti-patterns. Supports previewing and applying refactors in JS/TS, Python, Go.
Share bugs, ideas, or general feedback.
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 failures