terlar/nix-config/ast-grep
Claude Code and agent skill by terlar/nix-config
- community
Checking that the SKILL.md file is still in the repository.
Use when searching for CODE STRUCTURE or PATTERNS (functions, classes, method calls, imports, hooks, error handling, async patterns, parameter counts) in JavaScript, TypeScript, Python, Rust, Go, Java, C, Ruby, PHP, Nix. Understands code syntax and structure. NOT for plain text search (TODO comments, string literals, simple text patterns) — use grep for those.
Install
npx vskill@latest install terlar/nix-config/ast-grepSKILL.md
ast-grep Structural Code Search
Overview
This skill enables structural code search using Abstract Syntax Tree (AST) patterns via the ast-grep MCP server. Unlike text-based search (grep), ast-grep understands code structure, allowing precise queries like "find async functions without error handling" or "locate functions with >3 parameters".
When to Use This Skill
Use ast-grep for structural/semantic queries:
- Code constructs: "find all functions/classes/imports/exports"
- Structural relationships: "functions that call X", "methods inside class Y"
- Semantic patterns: "async without await", "missing error handling", ">N parameters"
- Language-specific: "React hooks in useEffect", "SQL injection patterns"
- Context-aware: "console.log inside class methods"
Use grep for text search:
- Plain text: "TODO comments", "FIXME", "deprecated"
- String literals: "find error messages containing X"
- Simple regex: "email addresses", "URLs"
- Non-code files: markdown, JSON, config files
Workflow
1. Understand the Query
Clarify the search requirements:
- What code structure? (function, class, call, import, assignment)
- Which language? (javascript, typescript, python, rust, go, etc.)
- Structural constraints? (inside X, has Y, without Z)
- Edge cases to consider?
2. Create Example Code
Write a minimal code snippet that represents what should match. This will be used for testing the rule.
Example: For "async functions that use await":
3. Write the ast-grep Rule
Translate the pattern into an ast-grep rule. Start with simple patterns first, only use kind for complex nested structures.
Decision tree:
- Can you write the code literally? → Use
pattern - Need to match variations? → Add metavariables (
$VAR,$$$ARGS) - Need structural constraints? → Add
has/inside/not - Still not working? → Use
dump_syntax_tree, then trykind
Start here (simple pattern):
Only escalate to `kind` if pattern fails:
Key principles:
- Pattern first — matches exactly what you see in code
- Multiple conditions? Use
all: [...], not duplicatehas: - Relational rules (
has,inside) requirestopBy: end - Test with
dump_syntax_treeonly when pattern doesn't match
See references/rule_reference.md for comprehensive rule syntax documentation.
4. Test the Rule
Use the `ast-grep_test_match_code_rule` MCP tool to validate before searching the full codebase:
If no matches:
- Start simpler — remove conditions one by one
- Use `pattern` instead of `kind` — write code literally with metavariables
- Check for duplicate fields — use
all: [...]for multiplehas/inside - Verify `stopBy: end` on relational rules (
has,inside) - Inspect AST — use
dump_syntax_treeto see actual structure - Last resort: `kind` — use when pattern fundamentally can't express it
5. Search the Codebase
Once the rule matches the example correctly:
For simple patterns: Use ast-grep_find_code tool:
For complex rules: Use ast-grep_find_code_by_rule tool:
Output format:
"text"(default) — compact, ~75% fewer tokens, grep-like output"json"— full metadata, use only when you need metavariable extraction or precise ranges
MCP Tools
ast-grep_find_code
Simple pattern search for straightforward structural matches.
Parameters:
pattern(required): ast-grep pattern with metavariables (e.g.,console.log($ARG))language(required): target language (javascript, typescript, python, rust, go, etc.)output_format(optional):"text"(default) or"json"max_results(optional): limit number of matches returned
Example:
ast-grep_find_code_by_rule
Advanced rule-based search with complex matching logic.
Parameters:
rule(required): YAML rule content as a stringoutput_format(optional):"text"(default) or"json"max_results(optional): limit number of matches returned
Example:
ast-grep_test_match_code_rule
Test a rule against example code before searching the entire codebase.
Parameters:
rule(required): YAML rule string to testcode(required): code snippet to match against
Returns: Matches found in the test code (empty if no matches)
Use this to:
- Validate rules work as expected
- Iterate on rule development
- Debug complex matching logic
Example:
ast-grep_dump_syntax_tree
Inspect the AST structure of code to understand node types and structure.
Parameters:
code(required): code snippet to inspectlanguage(required): target language
Use this to:
- Find correct
kindvalues for AST nodes - Understand code structure for complex patterns
- Debug why patterns aren't matching
Example:
Rule Writing Reference
Metavariables
$VAR— matches a single node (expression, statement, identifier)$$$VARS— matches zero or more nodes (variadic)
Example:
Relational Rules
Match code based on structural relationships:
has: { pattern: X, stopBy: end }— contains X anywhere insideinside: { pattern: Y, stopBy: end }— is inside Yprecedes: X— comes before X in source orderfollows: X— comes after X in source order
Always include `stopBy: end` to search to the end of the scope.
Example:
Composite Logic
Combine rules using boolean operators:
all: [rule1, rule2, ...]— AND (all must match) — use for multiple `has`/`inside`any: [rule1, rule2, ...]— OR (at least one matches)not: { rule }— negation (must not match)
Critical: Use `all` for multiple conditions, never duplicate `has`/`inside` fields.
Example:
Examples
Find Async Functions Without Error Handling
Pattern-first approach (recommended):
Find Nix Bindings with Specific Value
Matches: { programs.opencode.enable = true; } $A captures: programs.opencode.enable (full attrpath)
Find Nix Function Definitions
Matches: x: x + 1, name: version: src: ...
Find Functions with More Than 3 Parameters
Find React Hooks Inside useEffect
Find Console Logs in Class Methods
Tips
- Pattern first, `kind` last — write code literally with
$VAR, only usekindwhen pattern can't express it - Test first — always use
test_match_code_rulebefore searching the full codebase - Use `all` for multiple conditions — never duplicate
has/insidefields - Add `stopBy: end` to relational rules (
has,inside) - Prefer text format — use
output_format: "text"for efficiency (default) - Limit results — set
max_resultsfor exploratory searches to avoid token bloat
Debugging
Pattern not matching:
- Try simpler pattern — remove metavariables, match exact code first
- Check for YAML errors — duplicate
hasfields? Missingall:? - Inspect AST — use
dump_syntax_treeto see structure - Verify `stopBy: end` on
has/insiderules - Last resort: `kind` — check AST node names match language
Duplicate field errors (`has`, `inside`, etc.):
Too many false positives:
- Add
notconstraints to exclude unwanted matches - Add structural constraints with
insideorhas - Use more specific patterns (fewer metavariables)
No results but code exists:
- Test rule with
test_match_code_rulefirst - Check language specification matches file type
- Verify pattern syntax is valid code for that language
Supported Languages
ast-grep supports many languages including:
- JavaScript, TypeScript
- Python
- Rust
- Go
- Java, Kotlin
- C, C++, C#
- Ruby
- PHP
- Nix
- And many more
See full list: https://ast-grep.github.io/reference/languages.html
Language-Specific Notes
Nix:
- Attrpaths are single metavariables:
$Amatches full path likeprograms.opencode.enable - Bindings:
{ $A = $B; }matches{ programs.opencode.enable = true; } - Can't use dot notation in patterns:
$A.enable = $Bdoesn't work - Functions:
$A: $Bmatches lambda,{ $A, $B }: $Cmatches attribute set pattern - Lists:
[ $$$ITEMS ]matches any list elements - Let expressions:
let $A = $B; in $C - With expressions:
with $A; $B - Working examples from ast-grep tests:
```yaml # Match any binding with specific value pattern: "{ $A = true; }" # Matches { enable = true; }
# Match function definitions pattern: "$A: $B" # Matches x: x + 1
# Match attribute set functions pattern: "{ $A, $B }: $C" # Matches { foo, bar }: foo + bar ```
JavaScript/TypeScript:
asyncis a sibling offunction_declaration, not inside it- Use
pattern: async function $NAME() {}notkind: function_declaration+has: async - Arrow functions:
($$$) => $EXPRor$VAR => $EXPR - Imports:
import { $$$NAMES } from '$MODULE'
Python:
- Indentation matters in patterns — match exact indentation or use
kindfor flexibility - Decorators:
@$DECORATOR\ndef $NAME($$$): $$$ - Type hints:
def $NAME($$$) -> $TYPE: $$$ - Comprehensions:
[$EXPR for $VAR in $ITER]
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingmodules/home/profiles/user/terje/programs/opencode/skills/ast-grep/SKILL.md
Popularity
- Repository stars
- 104
- Repository forks
- 4
- 7-day trend score
- 23
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/terlar/nix-config/ast-grep)