ast-grep
Structural code search and refactoring using AST patterns. Use when searching for code patterns (not text), finding deprecated patterns, or systematic refactoring. Supports Nextflow, JavaScript, Python, and more.
What this skill does
# ast-grep Skill
ast-grep is a structural code search and rewriting tool. Use it when you need to find or modify code based on its AST structure rather than text patterns.
## When to Use ast-grep
**Use ast-grep when:**
- Searching for code patterns (function calls, imports, specific constructs)
- Refactoring code systematically
- Finding deprecated patterns or anti-patterns
- The pattern involves code structure, not just text
**Use grep/ripgrep when:**
- Searching for literal strings, comments, or documentation
- Simple text matching is sufficient
## Quick Reference
| Task | Command |
| ------------------ | ---------------------------------------------- |
| Find pattern | `ast-grep run --pattern 'PATTERN' --lang LANG` |
| Scan with rule | `ast-grep scan --rule file.yaml` |
| Debug AST | `--debug-query=ast` |
| Test pattern match | `--debug-query=pattern` |
| Use inline rule | `--inline-rules 'YAML'` |
| Nextflow patterns | Use `_VAR` instead of `$VAR` |
## Quick Start
### Simple Pattern Search
```bash
# Find all console.log calls
ast-grep run --pattern 'console.log($$$ARGS)' --lang js
# Find Channel.from() calls in Nextflow
ast-grep run --pattern 'Channel.from(___)' --lang nextflow
```
### Using Rules for Complex Patterns
```bash
# Scan with a rule file
ast-grep scan --rule path/to/rule.yaml
# Quick inline rule test
ast-grep scan --inline-rules '
id: test-rule
language: javascript
rule:
pattern: console.log($$$ARGS)
'
```
### Debugging Patterns
```bash
# See AST structure of code
ast-grep run --pattern '$$$' --debug-query=ast path/to/file.js
# See how pattern matches
ast-grep run --pattern 'your_pattern' --debug-query=pattern path/to/file.js
```
## Core Concepts
### Metavariables
| Syntax | Matches | Example |
| ---------- | --------------------------------- | --------------------------------------- |
| `$VAR` | Single named node | `console.$METHOD` matches `console.log` |
| `$$VAR` | Single node (including anonymous) | `$$OP` matches operators |
| `$$$VAR` | Zero or more nodes | `func($$$ARGS)` matches any args |
| `_` prefix | Non-capturing (Nextflow) | `_VAR` instead of `$VAR` |
**Note:** In Nextflow, use `_` instead of `$` for metavariables (configured via `expandoChar` in sgconfig.yml).
### Rule Structure
```yaml
id: rule-name
language: javascript # or nextflow, python, etc.
severity: warning # error, warning, hint, off
message: "Human-readable message"
note: |
Additional context and fix suggestions
rule:
pattern: code_pattern_here
```
## Workflow for Writing Rules
1. **Understand the query** - What code pattern are you looking for?
2. **Create example code** - Write a small file with the pattern
3. **Inspect the AST** - Use `--debug-query=ast` to see structure
4. **Write initial pattern** - Start simple, use metavariables
5. **Test and refine** - Use `--debug-query=pattern` to debug matches
6. **Add constraints** - Use relational rules (`inside`, `has`) as needed
## Common Patterns
### Match function with specific content
```yaml
rule:
all:
- pattern: function $NAME($$$PARAMS) { $$$ }
- has:
pattern: console.log($$$)
stopBy: end
```
### Match code inside a context
```yaml
rule:
all:
- pattern: await $PROMISE
- inside:
kind: try_statement
stopBy: end
```
### Match missing pattern (lint for absence)
```yaml
rule:
all:
- pattern: function $NAME($$$) { $$$ }
- not:
has:
pattern: return $$$
stopBy: end
```
## Key Principles
1. **Always use `stopBy: end`** for relational rules (`inside`, `has`, `precedes`, `follows`) to search the full subtree
2. **Start simple** - Get a basic pattern working before adding complexity
3. **Escape `$` in shell** - Use `\$VAR` or single quotes when running from bash
4. **Use `all` for order** - When metavariables depend on each other, `all` processes rules in order
## Integration Notes
### OpenCode Tools
This repository includes **nf-ast-grep MCP tools** for Nextflow-specific searches:
- `nf-ast-grep_find_processes` - Find all process definitions
- `nf-ast-grep_find_workflows` - Find workflow definitions
- `nf-ast-grep_find_channels` - Find channel factory operations
- `nf-ast-grep_find_deprecated` - Find deprecated patterns
- `nf-ast-grep_lint` - Run lint rules on Nextflow code
- `nf-ast-grep_search` - Search with custom patterns
Use these tools for Nextflow work instead of raw ast-grep commands when available.
### Shell Execution
When running ast-grep from bash:
- **Single quotes** preserve `$` metavariables: `ast-grep run --pattern 'console.$METHOD'`
- **Escape in double quotes**: `ast-grep run --pattern "console.\$METHOD"`
- For complex patterns, use `--inline-rules` with a heredoc or rule files
### When to Delegate
- **Large searches**: Use explore agents for searching across large codebases
- **Simple patterns**: Run ast-grep directly for quick one-off searches
- **Rule development**: Use iterative bash commands with `--debug-query`
## Error Handling
### "Pattern not matching expected code"
**Cause**: Pattern syntax doesn't match AST structure.
**Solution**:
1. Inspect actual AST: `ast-grep run --pattern '$$$' --debug-query=ast file.ext`
2. Check node kinds match what you expect
3. Simplify pattern and add constraints incrementally
### "ast-grep: command not found"
**Cause**: ast-grep not installed or not in PATH.
**Solution**:
```bash
# Install via cargo
cargo install ast-grep
# Or via npm
npm install -g @ast-grep/cli
# Or via nix
nix shell nixpkgs#ast-grep
```
### "Language not supported"
**Cause**: Trying to use an unsupported or unconfigured language.
**Solution**:
- Check supported languages: `ast-grep --help`
- For custom languages (like Nextflow), ensure `sgconfig.yml` is present with `customLanguages` configured
- See [Nextflow Reference](references/nextflow.md) for custom language setup
### "Missing stopBy in relational rule"
**Cause**: Relational rules (`inside`, `has`, `precedes`, `follows`) default to `stopBy: neighbor` which only checks immediate children.
**Solution**: Always add `stopBy: end` to search the full subtree:
```yaml
rule:
has:
pattern: target_pattern
stopBy: end # Don't forget this!
```
### "Metavariable not captured"
**Cause**: Using `_` prefix makes metavariables non-capturing, or metavariable used before it's defined.
**Solution**:
- Use `$VAR` (or `_VAR` in Nextflow) for capturing
- In `all` blocks, define metavariables before using them (rules process in order)
### Shell escaping issues
**Cause**: `$` in patterns gets interpreted as shell variable.
**Solution**:
```bash
# Use single quotes (preferred)
ast-grep run --pattern 'console.$METHOD'
# Or escape in double quotes
ast-grep run --pattern "console.\$METHOD"
# Or use rule files to avoid shell entirely
ast-grep scan --rule my-rule.yaml
```
### "Rule file not found" or YAML errors
**Cause**: Invalid YAML syntax or wrong file path.
**Solution**:
1. Validate YAML syntax (check indentation, colons, quotes)
2. Use absolute paths or run from correct directory
3. Test with `--inline-rules` first before creating rule file
## Examples
### Example 1: Finding and Fixing Deprecated Nextflow Patterns
**User request**: "Find all uses of the deprecated Channel.from() in our Nextflow pipeline"
**Workflow**:
```bash
# Step 1: Quick search to see scope of problem
ast-grep run --pattern 'Channel.from(___)' --lang nextflow
# Step 2: If many results, use the lint tool for structured output
# (uses existing deprecated-channel-from.yaml rule)
```
**Rule used** (`deprecated-channel-from.yaml`):
```yaml
id: deprecated-channel-from
language: 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.