ast-grep

star 15

Write, debug, and validate ast-grep structural code search rules. Use this skill when the user needs syntax-aware code search, AST pattern matching, structural refactor discovery, language-construct queries, or searches that plain text tools like rg can miss, such as finding functions with particular descendants, calls inside specific contexts, missing error handling, React hook shapes, decorators, or other Tree-sitter-backed code structures.

bahayonghang By bahayonghang schedule Updated 6/8/2026

name: ast-grep description: >- Write, debug, and validate ast-grep structural code search rules. Use this skill when the user needs syntax-aware code search, AST pattern matching, structural refactor discovery, language-construct queries, or searches that plain text tools like rg can miss, such as finding functions with particular descendants, calls inside specific contexts, missing error handling, React hook shapes, decorators, or other Tree-sitter-backed code structures. version: 0.1.0 category: developer-tools-integrations tags: - ast-grep - structural-search - code-search - tree-sitter - static-analysis - refactoring argument-hint: "[code-pattern-or-search-goal] [path]" allowed-tools: Read, Glob, Grep, Bash, Write

ast-grep Structural Search

Use ast-grep when the user needs code structure, not just text. The useful outcome is a validated rule plus a clear statement of what it matches and what it may miss.

Triage

Start with the smallest tool that can answer the question.

  • Use rg for exact names, strings, comments, or simple text.
  • Use language tooling for semantic facts such as type resolution, references, imports, or rename safety.
  • Use ast-grep for syntax shape: descendants, ancestors, call forms, decorators, missing constructs, nested contexts, or multi-language structural searches.

If ast-grep is not installed, say so and offer an rg fallback only when the fallback will not pretend to be structural.

Workflow

  1. Identify the language and target files.

    • Infer from paths and extensions when possible.
    • Ask only if the language or include/exclude scope cannot be inferred.
  2. Write a tiny fixture before searching the real repository.

    • Include at least one positive example.
    • Add a negative example when false positives would be costly.
  3. Start with the simplest pattern.

    • Use ast-grep run --pattern ... --lang ... for a single-node search.
    • Move to a YAML rule when the search needs has, inside, not, any, all, regex, nthChild, or reusable metadata.
  4. Debug the parsed structure when the first rule misses.

    • Use ast-grep run --pattern '<sample code>' --lang <lang> --debug-query=ast.
    • --debug-query prints diagnostic output and may exit non-zero; treat the printed tree as useful debug output, not as a failed repository search.
  5. Validate on the fixture before running on the repository.

    • Keep the rule as simple as possible until it matches the fixture.
    • Then scan the real path and report expected false-negative boundaries.
  6. Report the final rule, command, and caveats.

    • Name node kinds or language constructs intentionally excluded.
    • Prefer JSON output when a downstream script will consume matches.

Rule File First

Rule files avoid most shell quoting problems and are the preferred form for complex searches.

On Windows, save rule files as UTF-8 without BOM. If ast-grep scan --rule reports missing field language even though the YAML has language, check for a BOM at the start of the file.

# async-await.yml
id: async-await
language: javascript
rule:
  any:
    - kind: function_declaration
    - kind: arrow_function
    - kind: method_definition
  has:
    pattern: await $EXPR
    stopBy: end
$rule = @'
id: async-await
language: javascript
rule:
  any:
    - kind: function_declaration
    - kind: arrow_function
    - kind: method_definition
  has:
    pattern: await $EXPR
    stopBy: end
'@
[System.IO.File]::WriteAllText(
  "async-await.yml",
  $rule,
  [System.Text.UTF8Encoding]::new($false)
)

ast-grep scan --rule async-await.yml .\src
ast-grep scan --rule async-await.yml .\src --json
ast-grep scan --rule async-await.yml ./src
ast-grep scan --rule async-await.yml ./src --json

Inline Smoke Tests

Use inline rules only for quick checks. In PowerShell, single-quoted here-strings preserve $META variables without escaping.

$rule = @'
id: console-call
language: javascript
rule:
  pattern: console.log($$$ARGS)
'@

"console.log('debug', value);" | ast-grep scan --inline-rules $rule --stdin

In POSIX shells, quote the YAML with single quotes or escape $.

printf '%s\n' "console.log('debug', value);" |
  ast-grep scan --inline-rules 'id: console-call
language: javascript
rule:
  pattern: console.log($$$ARGS)' --stdin

Every scan --inline-rules example must include id, language, and rule.

Debugging Checklist

When a rule produces no matches:

  1. Confirm the language: --lang javascript is different from --lang tsx.
  2. Print the query tree with --debug-query=ast or --debug-query=cst.
  3. Check that rule files are UTF-8 without BOM.
  4. Replace the complex rule with one pattern or one kind.
  5. Add relational rules back one at a time.
  6. Add stopBy: end to deep has / inside searches.
  7. Check whether metavariables occupy a whole syntax node.
  8. Broaden node kinds if the language has several forms of the same concept.

Avoid Silent False Negatives

Do not assume one node kind covers a user concept.

For JavaScript and TypeScript, "function" may include:

  • function_declaration
  • function
  • arrow_function
  • method_definition
  • class fields or object properties containing functions

For React, decide whether the user means .js, .jsx, .ts, or .tsx.

For Python, inspect the parsed shape before relying on indentation-sensitive multi-line patterns.

Output Contract

When answering an ast-grep task, include:

  1. Rule: the YAML rule or inline pattern.
  2. Validation: the fixture command you used or recommend.
  3. Repository command: the command for the user's target path.
  4. Caveats: likely false positives, false negatives, and language forms not covered.

Reference

Load references/rule_reference.md when the task needs detailed syntax for atomic rules, relational rules, composite rules, metavariables, or troubleshooting.

Install via CLI
npx skills add https://github.com/bahayonghang/my-claude-code-settings --skill ast-grep
Repository Details
star Stars 15
call_split Forks 1
navigation Branch main
article Path SKILL.md
More from Creator
bahayonghang
bahayonghang Explore all skills →