.config/pi/agent/skills/ast-grep/SKILL.md
Search code by AST patterns and perform structural refactoring across files. Use when finding function calls, replacing code patterns, or refactoring syntax that regex cannot reliably match.
npx skillsauth add adragomir/dotfiles ast-grepInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Structural code search and rewriting using AST matching instead of regex.
ast-grep uses pattern placeholders to match and capture AST nodes:
| Pattern | Description |
|---------|-------------|
| $VAR | Match a single AST node and capture it as VAR |
| $$$VAR | Match zero or more AST nodes (spread) and capture as VAR |
| $_ | Anonymous placeholder (matches any single node, no capture) |
| $$$_ | Anonymous spread placeholder (matches any number of nodes) |
Shell quoting tip: Escape $ as \$VAR or wrap the pattern in single quotes to avoid shell expansion.
javascript, typescript, tsx, html, css, python, go, rust, java, c, cpp, csharp, ruby, php, yaml
| Command | Description |
|---------|-------------|
| ast-grep run | One-time search or rewrite (default) |
| ast-grep scan | Scan and rewrite by configuration |
| ast-grep test | Test ast-grep rules |
| ast-grep new | Create new project or rules |
| ast-grep lsp | Start language server |
Find patterns in code:
# Find console.log calls
ast-grep run --pattern 'console.log($$$ARGS)' --lang javascript .
# Find React useState hooks
ast-grep run --pattern 'const [$STATE, $SETTER] = useState($INIT)' --lang tsx .
# Find async functions
ast-grep run --pattern 'async function $NAME($$$ARGS) { $$$BODY }' --lang typescript .
# Find Express route handlers
ast-grep run --pattern 'app.$METHOD($PATH, ($$$ARGS) => { $$$BODY })' --lang javascript .
# Find Python function definitions
ast-grep run --pattern 'def $NAME($$$ARGS): $$$BODY' --lang python .
# Find Go error handling
ast-grep run --pattern 'if $ERR != nil { $$$BODY }' --lang go .
Preview refactoring changes without modifying files:
# Replace == with === (preview)
ast-grep run --pattern '$A == $B' --rewrite '$A === $B' --lang javascript .
# Convert function to arrow function (preview)
ast-grep run --pattern 'function $NAME($$$ARGS) { $$$BODY }' \
--rewrite 'const $NAME = ($$$ARGS) => { $$$BODY }' --lang javascript .
# Replace var with let (preview)
ast-grep run --pattern 'var $NAME = $VALUE' --rewrite 'let $NAME = $VALUE' --lang javascript .
# Add optional chaining (preview)
ast-grep run --pattern '$OBJ && $OBJ.$PROP' --rewrite '$OBJ?.$PROP' --lang javascript .
Apply refactoring to files:
# Apply changes (use --update-all)
ast-grep run --pattern '$A == $B' --rewrite '$A === $B' --lang javascript --update-all .
Use inline rules for complex pattern matching with logical operators:
# Find functions containing await
ast-grep scan --inline-rules '{"id": "async-fn", "language": "javascript", "rule": {"kind": "function_declaration", "has": {"pattern": "await $EXPR"}}}' .
# Find nested if statements
ast-grep scan --inline-rules '{"id": "nested-if", "language": "javascript", "rule": {"kind": "if_statement", "inside": {"kind": "if_statement"}}}' .
# Find console.log inside catch blocks
ast-grep scan --inline-rules '{"id": "catch-log", "language": "javascript", "rule": {"pattern": "console.log($$$ARGS)", "inside": {"kind": "catch_clause"}}}' .
Rules support these operators for complex matching:
all: All conditions must matchany: Any condition must matchnot: Negate a conditioninside: Node must be inside another patternhas: Node must contain another patternkind: Match AST node typepattern: Match a code pattern# Convert require to import
ast-grep run --pattern 'const $NAME = require($PATH)' \
--rewrite 'import $NAME from $PATH' --lang javascript .
# Simplify boolean return
ast-grep run --pattern 'if ($COND) { return true } else { return false }' \
--rewrite 'return !!$COND' --lang javascript .
# Convert Promise.then to async/await
ast-grep run --pattern '$PROMISE.then($CALLBACK)' \
--rewrite 'await $PROMISE' --lang javascript .
# Convert string formatting
ast-grep run --pattern '"%s" % ($ARGS)' \
--rewrite 'f"{$ARGS}"' --lang python .
# Find deprecated function calls
ast-grep run --pattern 'old_function($$$ARGS)' --lang python .
# Find class components
ast-grep run --pattern 'class $NAME extends React.Component { $$$BODY }' --lang tsx .
# Find useEffect with empty deps
ast-grep run --pattern 'useEffect($CALLBACK, [])' --lang tsx .
ast-grep run --pattern to find matches--rewrite to see what would change--update-all to modify filesCreate a new ast-grep project with rules:
# Initialize project with sgconfig.yml
ast-grep new
# Create a new rule
ast-grep new rule
# Create a new test for rules
ast-grep new test
# Test all rules in project
ast-grep test
# Test with specific config
ast-grep test -c ./sgconfig.yml
# Start LSP for editor integration (use tmux for background)
tmux new -d -s ast-grep-lsp 'ast-grep lsp'
$_ for parts you don't care about capturing$$$ for variable-length matches (arguments, statements)ast-grep run --pattern '...' --lang js path/to/file.jsast-grep run --pattern '...' --jsonast-grep new to scaffold rules and teststools
Allows to interact with web pages by performing actions such as clicking buttons, filling out forms, and navigating links. It works by remote controlling Google Chrome or Chromium browsers using the Chrome DevTools Protocol (CDP). When Claude needs to browse the web, it can use this skill to do so.
tools
Remote control tmux sessions for interactive CLIs (python, gdb, etc.) by sending keystrokes and scraping pane output.
development
Load and parse session transcripts from shittycodingagent.ai/buildwithpi.ai/buildwithpi.com (pi-share) URLs. Fetches gists, decodes embedded session data, and extracts conversation history.
testing
Create and render OpenSCAD 3D models. Generate preview images from multiple angles, extract customizable parameters, validate syntax, and export STL files for 3D printing platforms like MakerWorld.