ast-grep
Use for searching code, finding code patterns, refactoring, and analyzing code structure. NEVER use Grep for Python code.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use for searching code, finding code patterns, refactoring, and analyzing code structure. NEVER use Grep for Python code.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Bootstrap an implementation plan and coordinate a parallel team of named agents using native Agent Teams.
Semantic documentation architect. Analyzes PROSE CONTENT to organize by concept affinity, eliminate contradictions in explanations, and consolidate scattered ideas.
Recover accidentally deleted files from the recycle bin.
| name | ast-grep |
| description | Use for searching code, finding code patterns, refactoring, and analyzing code structure. NEVER use Grep for Python code. |
Uses ast-grep (installed locally via uv) for structural code search and pattern matching.
MANDATORY for:
NEVER use Grep for these tasks - ast-grep understands syntax and avoids false positives.
Determine the code pattern you need to find:
function_name($$$)class ClassName or class ClassName($$$)def method_name($$$)$VAR: TypeNamefrom $_ import target$VAR = $$$@decorator_nameraise ExceptionType($$$) or except ExceptionTypeUse ast-grep pattern syntax:
$$$ - matches any number of arguments/parameters/statements$_ - matches any single identifier$VAR - captures and names a matched variable for referenceGood patterns:
# Find all calls to a specific function
uv run ast-grep run --pattern "compute_value($$$)" --lang python --json
# Find class definitions with any base classes
uv run ast-grep run --pattern "class ClassName($$$)" --lang python --json
# Find all type annotations for a specific type
uv run ast-grep run --pattern "$_: Decimal" --lang python --json
# Find imports of a specific module
uv run ast-grep run --pattern "from ceridwen_types import $$$" --lang python --json
ALWAYS use JSON output format for programmatic processing:
uv run ast-grep run --pattern "<your-pattern>" --lang python --json
JSON format provides structured data:
{
"file": "path/to/file.py",
"start": {"line": 45, "column": 0},
"end": {"line": 52, "column": 0},
"text": "def compute_value...",
"metaVariables": {"$$$": ["x: int, y: int"]}
}
Return structured summary:
{
"pattern": "<pattern-used>",
"total_matches": 51,
"files_affected": ["file1.py", "file2.py"],
"matches": [
{"file": "...", "line": 77, "context": "..."},
...
]
}
If results aren't what you expected:
$$$ or $_ for wildcardsMANDATORY: When using this skill, return results as JSON:
{
"search": {
"pattern": "FixedDecimalType($$$)",
"language": "python",
"scope": "entire project"
},
"results": {
"total_matches": 51,
"files_affected": 8,
"summary": {
"imports": 5,
"instantiations": 51,
"definitions": 1
}
},
"key_findings": [
"Most instantiations in tests (20 matches)",
"Inference engine uses computed precision",
"DBRM tests use various precision/scale combinations"
],
"matches": [
{
"file": "packages/ceridwen-types/src/ceridwen_types/pli/arithmetic.py",
"line": 77,
"type": "definition",
"context": "class FixedDecimalType(PLIType)"
},
{
"file": "tests/test_expression_emit_signature.py",
"lines": [64, 73, 101, 113],
"type": "instantiation",
"pattern": "FixedDecimalType(precision=15, scale=2)"
}
]
}
This structured format enables:
# All calls to a function
uv run ast-grep run --pattern "function_name($$$)" --lang python --json
# Calls with specific first argument
uv run ast-grep run --pattern "function_name('specific_arg', $$$)" --lang python --json
# Method calls on objects
uv run ast-grep run --pattern "$_.method_name($$$)" --lang python --json
# Function definitions
uv run ast-grep run --pattern "def function_name($$$)" --lang python --json
# Class definitions
uv run ast-grep run --pattern "class ClassName($$$)" --lang python --json
# Method definitions in classes
uv run ast-grep run --pattern "def __init__($$$)" --lang python --json
# Type annotations
uv run ast-grep run --pattern "$_: TypeName" --lang python --json
# Type hints in function signatures
uv run ast-grep run --pattern "def $_($$): -> ReturnType" --lang python --json
# Generic type usage
uv run ast-grep run --pattern "List[$_]" --lang python --json
# Import from module
uv run ast-grep run --pattern "from module_name import $$$" --lang python --json
# Specific import
uv run ast-grep run --pattern "from $_ import ClassName" --lang python --json
# Import alias
uv run ast-grep run --pattern "import $_ as $_" --lang python --json
# Any assignment to variable
uv run ast-grep run --pattern "variable_name = $$$" --lang python --json
# Class attribute assignment
uv run ast-grep run --pattern "self.$_ = $$$" --lang python --json
# Multiple assignment
uv run ast-grep run --pattern "$_, $_ = $$$" --lang python --json
# Raising exceptions
uv run ast-grep run --pattern "raise ExceptionType($$$)" --lang python --json
# Exception handlers
uv run ast-grep run --pattern "except ExceptionType" --lang python --json
# Try-except blocks
uv run ast-grep run --pattern "try: $$$ except $_: $$$" --lang python --json
ast-grep can match patterns across multiple lines:
uv run ast-grep run --pattern "if $CONDITION: $$$" --lang python --json
For complex searches:
Use shell commands to search specific directories:
# Search only in specific package
cd packages/ceridwen-compiler && uv run ast-grep run --pattern "..." --lang python --json
# Search in tests only
cd tests && uv run ast-grep run --pattern "..." --lang python --json
ast-grep can automatically rewrite code using YAML rule files with fix transformations. This is powerful for
mechanical refactoring tasks like renaming imports, updating function calls, or changing API usage patterns.
Reference: https://ast-grep.github.io/guide/rewrite-code.html
Good candidates for automated rewriting:
NOT suitable for automated rewriting:
Step 1: Create a YAML rule file with both rule and fix:
# rule.yml
id: rename-import
language: python
rule:
pattern: from ceridwen_runtime import LocalMemoryView
fix: from ceridwen_memory.views import LocalMemoryView
Step 2: Test the rule (dry-run to see what would change):
# See proposed changes without applying them
uv run ast-grep scan --inline-rules 'rule.yml' --json
Step 3: Apply the transformation:
# Actually rewrite files
uv run ast-grep scan --inline-rules 'rule.yml' --update-all
Use metavariables ($VAR) to preserve parts of the matched code:
# Update function calls with reordered parameters
id: reorder-params
language: python
rule:
pattern: compute_value($X, $Y, precision=$P)
fix: compute_value(precision=$P, x=$X, y=$Y)
This finds compute_value(a, b, precision=15) and rewrites to compute_value(precision=15, x=a, y=b).
Scenario: Move DispatchFunction from ceridwen_compiler to ceridwen_codegen_types.
# rename-dispatch-import.yml
id: update-dispatch-import
language: python
rule:
any:
- pattern: from ceridwen_compiler.core.codegen.dispatches import $$$NAMES
- pattern: from ceridwen_compiler.core.codegen import $$$NAMES
has:
any:
- kind: identifier
pattern: DispatchFunction
- kind: identifier
pattern: DispatchRegistry
fix: from ceridwen_codegen_types.dispatch import $$$NAMES
Usage:
# Preview changes
uv run ast-grep scan --inline-rules 'rename-dispatch-import.yml'
# Apply changes
uv run ast-grep scan --inline-rules 'rename-dispatch-import.yml' --update-all
# Verify with tests
uv run pyright
uv run pytest
Scenario: Add new required parameter to all function calls.
# add-context-param.yml
id: add-context-parameter
language: python
rule:
pattern: emit_statement($STMT)
fix: emit_statement($STMT, ctx)
Apply:
uv run ast-grep scan --inline-rules 'add-context-param.yml' --update-all
uv run pyright # Check types
uv run ruff check . # Check style
uv run pytest # Run tests
ast-grep rewrites are syntactic, not semantic:
When automated rewriting fails, fall back to manual refactoring with:
Recommended workflow for type movements (like in plans/layering.md):
Search phase: Use ast-grep to find all usages
uv run ast-grep run --pattern "from old_package import TargetType" --lang python --json
Decide approach:
Automated rewriting:
# Create rule file
cat > update-import.yml << 'EOF'
id: update-import
language: python
rule:
pattern: from old_package import TargetType
fix: from new_package import TargetType
EOF
# Apply
uv run ast-grep scan --inline-rules 'update-import.yml' --update-all
Verify:
uv run pyright
uv run pytest
Clean up: Remove old type definition, update documentation
This approach combines ast-grep's search capabilities (find all usages) with its rewriting capabilities (mechanical transformations), falling back to manual edits only when needed.
Found 3 matches:
path/to/file.py:45-52
def compute_value(x: int, y: int) -> int:
result = x + y
return result
{
"file": "path/to/file.py",
"start": {"line": 45, "column": 0},
"end": {"line": 52, "column": 0},
"text": "def compute_value...",
"metaVariables": {"$$$": ["x: int, y: int"]}
}
| Aspect | ast-grep | Grep |
|---|---|---|
| Syntax awareness | ✅ Understands Python | ❌ Text matching only |
| False positives | ✅ None from comments/strings | ❌ Many false positives |
| Multi-line patterns | ✅ Handles naturally | ❌ Complex/impossible |
| Structural context | ✅ Captures scope/hierarchy | ❌ No context |
| Refactoring safety | ✅ Finds all real usages | ❌ Misses or over-matches |
def $FUNC($$$) to match any function and see structure$$$, $_, $VAR)Before using ast-grep:
After using ast-grep:
# Before refactoring DecimalValue type
cd packages && uv run ast-grep run --pattern "$_: DecimalValue" --lang python --json
# Before changing emit_expression signature
cd packages/ceridwen-compiler && uv run ast-grep run --pattern "emit_expression($$$)" --lang python --json
# Finding all WAT module creations
uv run ast-grep run --pattern "WATModule($$$)" --lang python --json
# Finding all host functions
cd packages/ceridwen-runtime && uv run ast-grep run --pattern "@host_function" --lang python --json
Always cite which code locations you found using ast-grep when documenting refactoring or analysis work.