ast-grep/agent-skill
Overview
This skill translates natural language queries into ast-grep rules for structural code search. It helps you find code by AST patterns rather than text, enabling precise queries like finding functions with specific control flow or calls with particular arguments. Use it to craft, test, and iterate ast-grep YAML or inline rules for large codebases.
How this skill works
I convert a user's description of a code pattern into an ast-grep rule or pattern, provide example code to test against, and recommend CLI commands to validate matches. I guide you through choosing pattern vs kind-based rules, adding relational rules (has/inside) with stopBy: end, and debugging using --debug-query. I also suggest stepwise simplification and escaping strategies for inline rules in shells.
When to use it
- When you need structural matching beyond regular text search (e.g., AST-level patterns).
- To locate specific language constructs like async functions, try/catch absence, or method calls with certain args.
- When queries require relational context (inside, has, precedes, follows).
- To build complex composite logic (all, any, not) across nodes.
- When you want reproducible rule files or quick inline rule iterations against a repo.
Best practices
- Start with a minimal pattern; expand to kind + relational rules only if needed.
- Always add stopBy: end for inside/has rules to traverse the full subtree.
- Use --debug-query (cst/ast/pattern) to inspect node kinds and fix mismatches.
- Escape $ metavariables for shell inline rules (use $VAR or single quotes).
- Test against a small example file before running rules across the whole codebase.
Example use cases
- Find async functions that use await but lack a try-catch block.
- Locate console.log calls that appear inside class method definitions.
- Search for function calls with a specific argument shape across JavaScript files.
- Detect classes or functions missing expected lifecycle methods or error handling.
- Create composite rules to flag patterns like deprecated API usage combined with specific surrounding context.
FAQ
Use pattern for simple single-node matches. Use kind with has/inside when matching node types or relational context that pattern cannot express.
Why add stopBy: end to relational rules?
stopBy: end ensures the relational rule searches the entire subtree, preventing early termination and missed matches.
How do I debug rules that return no matches?
Simplify the rule, inspect AST with --debug-query=cst or ast to verify node kinds, and ensure metavariables are correct and properly escaped for inline usage.