howto-ast-grep
Use when searching for or transforming code patterns structurally - provides ast-grep CLI syntax, metavariable patterns, and language-specific examples for precise AST-based code search and rewriting
What this skill does
# Using ast-grep for Structural Code Search
## Overview
ast-grep (`sg`) matches code by AST structure, not text. Use it instead of grep/ripgrep when you need to match code patterns regardless of whitespace, variable names, or formatting. Patterns must be valid, parsable code in the target language.
## When to Use
**Prefer ast-grep over grep when:**
- Finding function calls with specific argument shapes
- Matching patterns where variable names differ but structure is the same
- Rewriting code patterns across a codebase (migrations, deprecations)
- Finding anti-patterns that regex can't express (e.g. "await inside a loop")
**Use grep instead when:**
- Searching for string literals, comments, or non-code text
- Simple keyword search (import names, error messages)
- ast-grep is not installed
## CLI Quick Reference
```bash
# Search for a pattern
sg run -p 'console.log($$$ARGS)' -l javascript src/
# Search and replace (interactive)
sg run -p '$A && $A()' -r '$A?.()' -l typescript --interactive src/
# Apply all replacements without prompting
sg run -p 'var $X = $Y' -r 'const $X = $Y' -l javascript -U src/
# JSON output for programmatic use
sg run -p '$FUNC($$$)' -l python --json src/
# Read from stdin
echo 'let x = 1' | sg run -p 'let $X = $Y' -l javascript --stdin
```
## Metavariable Syntax
| Syntax | Matches | Example |
|--------|---------|---------|
| `$NAME` | Exactly one AST node | `console.log($MSG)` matches `console.log("hi")` but not `console.log("hi", 2)` |
| `$$$NAME` | Zero or more nodes | `console.log($$$ARGS)` matches any number of arguments |
| `$_NAME` | One node, non-capturing | `$_OBJ.$METHOD()` matches without binding `$_OBJ` |
**Reuse enforces equality:** `$A == $A` matches `x == x` but not `x == y`.
## Language-Specific Patterns
Always pass `-l <language>`. The language determines how patterns are parsed.
**JavaScript/TypeScript:**
```bash
# Find React hooks
sg run -p 'use$HOOK($$$)' -l typescript src/
# Optional chaining candidates
sg run -p '$A && $A.$B' -r '$A?.$B' -l typescript src/
# Async/await patterns
sg run -p 'await $PROMISE' -l javascript src/
```
**Python:**
```bash
# Find print statements
sg run -p 'print($$$)' -l python src/
# Dictionary access patterns
sg run -p '$DICT[$KEY]' -l python src/
# With statement patterns
sg run -p 'with open($$$ARGS) as $F: $$$BODY' -l python src/
```
**Go:**
```bash
# Error handling
sg run -p 'if $ERR != nil { return $$$VALS }' -l go ./
# Function calls
sg run -p '$PKG.$FUNC($$$)' -l go ./
```
**Rust:**
```bash
# Unwrap calls (potential panics)
sg run -p '$EXPR.unwrap()' -l rust src/
# Match expressions
sg run -p 'match $VAL { $$$ARMS }' -l rust src/
```
## Pattern Pitfalls
| Mistake | Why It Fails | Fix |
|---------|-------------|-----|
| Using regex in `-p` | Patterns must be valid code | Write the code structure you want to find |
| `$VAR + Name` | Parsed as `$VARN + ame` | Use constraints or transform in YAML rules |
| Single quotes in C/Rust patterns | `'x'` is a char literal, not a string | Use `"x"` for strings |
| Forgetting `-l` flag | ast-grep cannot infer language from patterns | Always specify language explicitly |
| `$A($B, $C)` for variadic calls | Only matches exactly 2 args | Use `$A($$$ARGS)` for any arity |
## YAML Rules for Complex Matching
When CLI patterns aren't expressive enough, use YAML rules:
```yaml
id: no-unwrap-in-production
language: rust
rule:
pattern: $EXPR.unwrap()
not:
inside:
kind: function_item
has:
field: name
regex: '^test_'
message: "Use expect() or proper error handling instead of unwrap()"
severity: warning
```
**Key rule combinators:**
- `all`: All sub-rules must match (AND)
- `any`: Any sub-rule can match (OR)
- `not`: Sub-rule must NOT match
- `inside`: Target is inside another node
- `has`: Target contains a descendant
- `follows`/`precedes`: Sibling ordering
**Run rules:** `sg scan --rule path/to/rule.yml src/`
## Red Flags
- Using grep with complex regex when ast-grep would match the structure directly
- Forgetting `$$$` and missing variadic matches
- Writing patterns that aren't valid code in the target language
- Not specifying `-l` and getting parse failures
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.