---
id: sm-ast-grep
name: "ast-grep"
url: https://skills.yangsir.net/skill/sm-ast-grep
author: ast-grep
domain: ai-code-generation-quality
tags: ["ast-grep", "abstract-syntax-tree-(ast)", "code-analysis", "refactoring", "static-analysis"]
install_count: 11700
rating: 4.50 (93 reviews)
github: https://github.com/ast-grep/agent-skill
---

# ast-grep

> 将自然语言查询转换为ast-grep规则，利用抽象语法树（AST）模式进行结构化代码搜索。

**Stats**: 11,700 installs · 4.5/5 (93 reviews)

## Before / After 对比

### 自然语言转AST规则，高效代码搜索

## Readme

# ast-grep

# ast-grep Code Search

## Overview

This skill helps translate natural language queries into ast-grep rules for structural code search. ast-grep uses Abstract Syntax Tree (AST) patterns to match code based on its structure rather than just text, enabling powerful and precise code search across large codebases.

## When to Use This Skill

Use this skill when users:

- Need to search for code patterns using structural matching (e.g., "find all async functions that don't have error handling")

- Want to locate specific language constructs (e.g., "find all function calls with specific parameters")

- Request searches that require understanding code structure rather than just text

- Ask to search for code with particular AST characteristics

- Need to perform complex code queries that traditional text search cannot handle

## General Workflow

Follow this process to help users write effective ast-grep rules:

### Step 1: Understand the Query

Clearly understand what the user wants to find. Ask clarifying questions if needed:

- What specific code pattern or structure are they looking for?

- Which programming language?

- Are there specific edge cases or variations to consider?

- What should be included or excluded from matches?

### Step 2: Create Example Code

Write a simple code snippet that represents what the user wants to match. Save this to a temporary file for testing.

**Example:**
If searching for "async functions that use await", create a test file:

```
// test_example.js
async function example() {
  const result = await fetchData();
  return result;
}

```

### Step 3: Write the ast-grep Rule

Translate the pattern into an ast-grep rule. Start simple and add complexity as needed.

**Key principles:**

- Always use `stopBy: end` for relational rules (`inside`, `has`) to ensure search goes to the end of the direction

- Use `pattern` for simple structures

- Use `kind` with `has`/`inside` for complex structures

- Break complex queries into smaller sub-rules using `all`, `any`, or `not`

**Example rule file (test_rule.yml):**

```
id: async-with-await
language: javascript
rule:
  kind: function_declaration
  has:
    pattern: await $EXPR
    stopBy: end

```

See `references/rule_reference.md` for comprehensive rule documentation.

### Step 4: Test the Rule

Use ast-grep CLI to verify the rule matches the example code. There are two main approaches:

**Option A: Test with inline rules (for quick iterations)**

```
echo "async function test() { await fetch(); }" | ast-grep scan --inline-rules "id: test
language: javascript
rule:
  kind: function_declaration
  has:
    pattern: await \$EXPR
    stopBy: end" --stdin

```

**Option B: Test with rule files (recommended for complex rules)**

```
ast-grep scan --rule test_rule.yml test_example.js

```

**Debugging if no matches:**

- Simplify the rule (remove sub-rules)

- Add `stopBy: end` to relational rules if not present

- Use `--debug-query` to understand the AST structure (see below)

- Check if `kind` values are correct for the language

### Step 5: Search the Codebase

Once the rule matches the example code correctly, search the actual codebase:

**For simple pattern searches:**

```
ast-grep run --pattern 'console.log($ARG)' --lang javascript /path/to/project

```

**For complex rule-based searches:**

```
ast-grep scan --rule my_rule.yml /path/to/project

```

**For inline rules (without creating files):**

```
ast-grep scan --inline-rules "id: my-rule
language: javascript
rule:
  pattern: \$PATTERN" /path/to/project

```

## ast-grep CLI Commands

### Inspect Code Structure (--debug-query)

Dump the AST structure to understand how code is parsed:

```
ast-grep run --pattern 'async function example() { await fetch(); }' \
  --lang javascript \
  --debug-query=cst

```

**Available formats:**

- `cst`: Concrete Syntax Tree (shows all nodes including punctuation)

- `ast`: Abstract Syntax Tree (shows only named nodes)

- `pattern`: Shows how ast-grep interprets your pattern

**Use this to:**

- Find the correct `kind` values for nodes

- Understand the structure of code you want to match

- Debug why patterns aren't matching

**Example:**

```
# See the structure of your target code
ast-grep run --pattern 'class User { constructor() {} }' \
  --lang javascript \
  --debug-query=cst

# See how ast-grep interprets your pattern
ast-grep run --pattern 'class $NAME { $$$BODY }' \
  --lang javascript \
  --debug-query=pattern

```

### Test Rules (scan with --stdin)

Test a rule against code snippet without creating files:

```
echo "const x = await fetch();" | ast-grep scan --inline-rules "id: test
language: javascript
rule:
  pattern: await \$EXPR" --stdin

```

**Add --json for structured output:**

```
echo "const x = await fetch();" | ast-grep scan --inline-rules "..." --stdin --json

```

### Search with Patterns (run)

Simple pattern-based search for single AST node matches:

```
# Basic pattern search
ast-grep run --pattern 'console.log($ARG)' --lang javascript .

# Search specific files
ast-grep run --pattern 'class $NAME' --lang python /path/to/project

# JSON output for programmatic use
ast-grep run --pattern 'function $NAME($$$)' --lang javascript --json .

```

**When to use:**

- Simple, single-node matches

- Quick searches without complex logic

- When you don't need relational rules (inside/has)

### Search with Rules (scan)

YAML rule-based search for complex structural queries:

```
# With rule file
ast-grep scan --rule my_rule.yml /path/to/project

# With inline rules
ast-grep scan --inline-rules "id: find-async
language: javascript
rule:
  kind: function_declaration
  has:
    pattern: await \$EXPR
    stopBy: end" /path/to/project

# JSON output
ast-grep scan --rule my_rule.yml --json /path/to/project

```

**When to use:**

- Complex structural searches

- Relational rules (inside, has, precedes, follows)

- Composite logic (all, any, not)

- When you need the power of full YAML rules

**Tip:** For relational rules (inside/has), always add `stopBy: end` to ensure complete traversal.

## Tips for Writing Effective Rules

### Always Use stopBy: end

For relational rules, always use `stopBy: end` unless there's a specific reason not to:

```
has:
  pattern: await $EXPR
  stopBy: end

```

This ensures the search traverses the entire subtree rather than stopping at the first non-matching node.

### Start Simple, Then Add Complexity

Begin with the simplest rule that could work:

- Try a `pattern` first

- If that doesn't work, try `kind` to match the node type

- Add relational rules (`has`, `inside`) as needed

- Combine with composite rules (`all`, `any`, `not`) for complex logic

### Use the Right Rule Type

- **Pattern**: For simple, direct code matching (e.g., `console.log($ARG)`)

- **Kind + Relational**: For complex structures (e.g., "function containing await")

- **Composite**: For logical combinations (e.g., "function with await but not in try-catch")

### Debug with AST Inspection

When rules don't match:

- Use `--debug-query=cst` to see the actual AST structure

- Check if metavariables are being detected correctly

- Verify the node `kind` matches what you expect

- Ensure relational rules are searching in the right direction

### Escaping in Inline Rules

When using `--inline-rules`, escape metavariables in shell commands:

- Use `\$VAR` instead of `$VAR` (shell interprets `$` as variable)

- Or use single quotes: `'$VAR'` works in most shells

**Example:**

```
# Correct: escaped $
ast-grep scan --inline-rules "rule: {pattern: 'console.log(\$ARG)'}" .

# Or use single quotes
ast-grep scan --inline-rules 'rule: {pattern: "console.log($ARG)"}' .

```

## Common Use Cases

### Find Functions with Specific Content

Find async functions that use await:

```
ast-grep scan --inline-rules "id: async-await
language: javascript
rule:
  all:
    - kind: function_declaration
    - has:
        pattern: await \$EXPR
        stopBy: end" /path/to/project

```

### Find Code Inside Specific Contexts

Find console.log inside class methods:

```
ast-grep scan --inline-rules "id: console-in-class
language: javascript
rule:
  pattern: console.log(\$\$\$)
  inside:
    kind: method_definition
    stopBy: end" /path/to/project

```

### Find Code Missing Expected Patterns

Find async functions without try-catch:

```
ast-grep scan --inline-rules "id: async-no-trycatch
language: javascript
rule:
  all:
    - kind: function_declaration
    - has:
        pattern: await \$EXPR
        stopBy: end
    - not:
        has:
          pattern: try { \$\$\$ } catch (\$E) { \$\$\$ }
          stopBy: end" /path/to/project

```

## Resources

### references/

Contains detailed documentation for ast-grep rule syntax:

- `rule_reference.md`: Comprehensive ast-grep rule documentation covering atomic rules, relational rules, composite rules, and metavariables

Load these references when detailed rule syntax information is needed.
Weekly Installs1.7KRepository[ast-grep/agent-skill](https://github.com/ast-grep/agent-skill)GitHub Stars567First SeenJan 22, 2026Security Audits[Gen Agent Trust HubPass](/ast-grep/agent-skill/ast-grep/security/agent-trust-hub)[SocketPass](/ast-grep/agent-skill/ast-grep/security/socket)[SnykPass](/ast-grep/agent-skill/ast-grep/security/snyk)Installed onclaude-code1.3Kopencode944codex877github-copilot843gemini-cli836amp729

---
*Source: https://skills.yangsir.net/skill/sm-ast-grep*
*Markdown mirror: https://skills.yangsir.net/api/skill/sm-ast-grep/markdown*