# Ast Grep

> Code search, analysis, and refactoring using ast-grep (sg). Use for AST-based code modifications, structural search, and linting — with validate-first pattern linting, dry-run-before-apply rewriting, per-language recipes, and a 0-matches troubleshooting ladder.

- **Type:** Skill
- **Install:** `agentstack add skill-outlinedriven-odin-claude-plugin-ast-grep`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [OutlineDriven](https://agentstack.voostack.com/s/outlinedriven)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [OutlineDriven](https://github.com/OutlineDriven)
- **Source:** https://github.com/OutlineDriven/odin-claude-plugin/tree/main/skills/ast-grep
- **Website:** https://outlinedriven.github.io

## Install

```sh
agentstack add skill-outlinedriven-odin-claude-plugin-ast-grep
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ast-grep (sg)

ast-grep is a fast and polyglot tool for code searching, linting, and rewriting based on Abstract Syntax Trees (AST). It excels at structural search and replace where regex fails.

## When to use

- **Structural Search**: Finding code based on structure (e.g., "all function calls to `foo` with 2 arguments") regardless of whitespace.
- **Refactoring**: Renaming variables, changing function signatures, or transforming code patterns safely.
- **Linting**: Creating custom rules to enforce code style or best practices.
- **Code Analysis**: Extracting information from codebases.

## Quick Start

### CLI Basics

```bash
# Search (pattern must be in single quotes)
ast-grep -p '$A + $B' --lang ts

# Rewrite (dry run)
ast-grep -p '$A != null' --rewrite '$A' --lang ts

# Interactive Rewrite
ast-grep -p 'var $A = $B' --rewrite 'const $A = $B' --interactive
```

### Pattern Syntax
- **Meta-variables**: `$VAR` matches any single node.
- **Multi-meta-variables**: `$$$ARGS` matches zero or more nodes (list of items).
- **Wildcard**: `$_` matches any node (non-capturing).
- **Anonymous**: `$$` matches any list of nodes (non-capturing).

See [Pattern Syntax](references/pattern-syntax.md) for details.

## The helper — validate first, dry-run first

`scripts/ast_grep_helper.py` wraps two safety gates:

```bash
# Lint a pattern before you search with it (exit 0 valid / exit 2 malformed; flags regex-smell)
python3 scripts/ast_grep_helper.py validate '$A + $B' --lang ts

# Preview a rewrite — diff + "N matches across M files", mutates nothing without --apply
python3 scripts/ast_grep_helper.py replace '$A != null' '$A' --lang ts src/
python3 scripts/ast_grep_helper.py replace '$A != null' '$A' --lang ts src/ --apply
```

`validate` compiles the pattern through ast-grep's own parser, so it catches malformed queries in every language (including Go/Python where `$` is not an identifier char). `replace` is two-pass: dry-run prints the blast radius, `--apply` writes.

Rule: emit a pattern → `validate` it; emit a rewrite → `replace` dry-run, inspect the diff + match count, only then re-run with `--apply`.

## What to use, when

```text
structural shape (call/func/class/import shaped like X)  → ast-grep
text / regex / filenames / comments / string contents    → rg / grep
semantic (types, references, "who calls this symbol")     → LSP / compiler
across many repos                                         → search engine, then ast-grep per-repo
```

ast-grep matches syntax, not bytes. The moment you reach for `|`, `.*`, `\w`, or `[...]`, you want rg, not a pattern.

## When a rewrite or search surprises you

Rewrite flow (never skip the dry-run):

1. `search` the pattern to confirm it matches what you think.
2. `replace` dry-run — read the diff.
3. Inspect the `N matches across M files` count; if the blast radius is wrong, stop.
4. Refine the pattern (tighten meta-vars, add `--lang`, add context).
5. Re-run with `--apply`.

0-matches ladder (in order):

1. `python3 scripts/ast_grep_helper.py validate '' --lang L` — is the pattern even well-formed?
2. Check `--lang` — `tsx` ≠ `ts`; the wrong dialect silently matches nothing.
3. `ast-grep run -p '' -l L --debug-query=pattern` — look for `ERROR` in the dumped query tree.
4. Inspect the target's actual tree (`--debug-query=ast` on a known-matching snippet) — your node kinds may differ from your guess.
5. Reproduce in the online playground.

`references/pitfalls.md` is the deep field guide — read it when 0 matches surprises you.

## Invariants (do not break)

- **Validate before you search** — lint the pattern via the helper first.
- **Dry-run before you apply** — never `--apply` (or `--update-all`) without reading the diff.
- **Writes are two-pass** — `--json` and `--update-all` conflict: combine them and `--json` silently wins, so the write is dropped with no error. Preview with `--json`, then apply with `--update-all` separately.
- **Single-quote patterns** in the shell — `$VAR` must reach ast-grep unexpanded.
- **`--lang` is required for stdin** — piped input has no filename to infer the dialect from.
- **A pattern is code, not regex** — switch to rg the moment you'd need `|`, `.*`, `\w`, or `[...]`.
- **Invoke `ast-grep`, never `sg`** — `sg` collides with the `setgroups` binary on many systems.

## Core Concepts

Understanding **Named vs Unnamed nodes** and **Matching Strictness** is crucial for precise patterns.

- **Named Nodes**: `identifier`, `function_definition` (matched by `$VAR`).
- **Unnamed Nodes**: `(`, `)`, `;` (skipped by default in `smart` mode).
- **Strictness**: Control matching precision (`smart`, `cst`, `ast`, `relaxed`, `signature`).

See [Core Concepts](references/core-concepts.md) for details.

## Rule Configuration (YAML)

For complex tasks, use YAML configuration files.

```yaml
id: no-console-log
language: TypeScript
rule:
  pattern: console.log($$$ARGS)
  inside:
    kind: function_declaration
    stopBy: end
fix: '' # Remove the log
```

See [Rule Configuration](references/rule-config.md) for details.

## Advanced Rewriting

ast-grep supports complex transformations (regex replace, case conversion) and rewriters for sub-node transformation.

See [Rewriting & Transformations](references/rewriting.md) for details.

## Project Setup & Testing

For larger projects, organize rules and tests using `sgconfig.yml`.

- **Scaffold**: `ast-grep new project`
- **Config**: `sgconfig.yml` defines rule and test directories.
- **Testing**: Define `valid` and `invalid` cases to ensure rule accuracy.

See [Project Setup & Testing](references/project-setup.md) for details.

## Utility Rules

Reuse logic with local or global utility rules. Enables recursive matching.

```yaml
utils:
  is-literal:
    any: [{kind: string}, {kind: number}]
rule:
  matches: is-literal
```

See [Utility Rules](references/utility-rules.md) for details.

## Configuration Reference

Full reference for YAML fields (`id`, `severity`, `files`, `ignores`) and supported languages.

See [Configuration Reference](references/yaml-reference.md) for details.

## CLI Reference

Common commands: `scan`, `run`, `new`, `test`, `lsp`.

See [CLI Reference](references/cli.md) for details.

## Required reading

- [Recipes](references/recipes.md) — per-language copy-paste patterns (TS/JS, Python, Rust, Go, Java, Kotlin, C, C++). Read this **first** when starting a task in a given language.
- [Pitfalls](references/pitfalls.md) — failure-mode field guide (regex-vs-AST, incomplete patterns, the two-pass write, named/unnamed nodes, meta-var naming, stdin/tsx, `sg`↔setgroups, and the 0-matches debug ladder). Read this when **0 matches surprises you**.

Use the per-topic references linked above only when that topic is relevant.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [OutlineDriven](https://github.com/OutlineDriven)
- **Source:** [OutlineDriven/odin-claude-plugin](https://github.com/OutlineDriven/odin-claude-plugin)
- **License:** Apache-2.0
- **Homepage:** https://outlinedriven.github.io

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-outlinedriven-odin-claude-plugin-ast-grep
- Seller: https://agentstack.voostack.com/s/outlinedriven
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
