vinhnx/vtcode/ast-grep

Claude Code and agent skill by vinhnx/vtcode

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Use for ast-grep project setup, rule authoring, rule debugging, and structural search workflows.

Install

npx vskill@latest install vinhnx/vtcode/ast-grep

SKILL.md

Ast-Grep

Use this skill for ast-grep project setup, rule authoring, rule debugging, and CLI workflows that go beyond a single structural query.

Routing

  • Use exec_command for ast-grep queries, project scans, rule tests, debug output, and rewrite previews.
  • Use ast-grep scan for project rules and ast-grep test for rule tests.
  • Use ast-grep run --pattern=... --rewrite=... --json=compact --color=never for dry-run rewrite previews. Review every

replacement before applying changes.

  • Use ast-grep run --debug-query when a query matches an unexpected syntax node.
  • Use --kind to match node kinds. Ast-grep supports ESQuery-style compound selectors and pseudo-selectors in supported

releases.

  • Keep this skill read-only unless the user explicitly authorises applying a rewrite.

Quick Start

  • In VT Code, prefer vtcode dependencies install ast-grep before suggesting system package managers.
  • External install routes such as Homebrew, Cargo, npm, pip, MacPorts, or Nix are fallback options when the user

explicitly wants a system-managed install.

  • After installation, validate availability with ast-grep --help.
  • On Linux, prefer the full ast-grep binary name over sg because sg may already refer to setgroups.
  • When running CLI patterns with shell metavariables like $PROP, use single quotes so the shell does not expand them

before ast-grep sees the pattern.

  • A good first rewrite example is optional chaining, for example rewriting $PROP && $PROP() to $PROP?.().

Command Overview

  • ast-grep run: ad-hoc query execution and one-off rewrites.
  • ast-grep scan: project rule scanning.
  • ast-grep new: scaffold and rule generation.
  • ast-grep test: rule-test execution.
  • ast-grep lsp: editor integration via language server.

Built-In Languages

  • ast-grep ships many built-in languages. Common aliases include bash, c, cc / cpp, cs, css, ex, go /

golang, html, java, js / javascript / jsx, json, kt, lua, md / markdown, php, py / python, rb, rs / rust, swift, ts / typescript, tsx, and yml.

  • --lang <alias> and YAML language: <alias> use those built-in aliases. File-system scans infer language from

built-in extensions unless the project overrides them.

  • Pass --lang <alias> to the CLI when extension inference is insufficient.
  • Use languageGlobs when the repository needs a different extension mapping than ast-grep’s built-in defaults.

How Ast-Grep Works

  • ast-grep accepts several query formats: pattern queries, YAML rules, and programmatic API usage.
  • The core pipeline is parse first, match second. Tree-Sitter builds the syntax tree, then ast-grep’s Rust matcher finds

the target nodes.

  • The main usage scenarios are search, rewrite, lint, and analyze.
  • ast-grep processes many files in parallel and is built to use multiple CPU cores on larger codebases.
  • In VT Code, run ast-grep through exec_command and use this skill for YAML authoring, rule tests, rewrites, and

API-level work.

Project Scaffolding

  • A scan-ready ast-grep project needs workspace sgconfig.yml plus at least one rule directory, usually rules/.
  • rule-tests/ and utils/ are optional scaffolding that ast-grep new can create for rule tests and reusable utility

rules.

  • If the repository already has sgconfig.yml and rules/, prefer working with the existing layout instead of

recreating scaffolding.

  • Use ast-grep new when the repository does not have ast-grep scaffolding yet.
  • Use ast-grep new rule when the scaffold exists and the task is creating a new rule plus optional test case.

sgconfig.yml

  • sgconfig.yml is the project-level ast-grep config file, not a rule file. Treat it like the repository root for rule

discovery, tests, parser overrides, and embedded-language behavior.

  • ruleDirs is required and is resolved relative to the directory containing sgconfig.yml.
  • testConfigs is optional and configures ast-grep test discovery. Each entry needs testDir; snapshotDir is

optional and otherwise defaults to __snapshots__ under that testDir.

  • utilDirs declares directories for global utility rules shared across multiple rule files.
  • languageGlobs remaps files to parsers and takes precedence over ast-grep’s default extension mapping, which is

useful for similar-language reuse like TS -> TSX or C -> Cpp.

  • customLanguages registers project-local parsers. libraryPath can be one relative library path or a target-triple

map, extensions is required, expandoChar is optional, and languageSymbol defaults to tree_sitter_{name}.

  • languageInjections is experimental. Each entry needs hostLanguage, rule, and injected.
  • Use dynamic injected candidates when the rule captures $LANG and the embedded language must be chosen from a list

such as css, scss, or less.

  • Raw ast-grep project discovery walks upward from the current working directory until it finds sgconfig.yml, and

--config <file> overrides that discovery with an explicit root config path.

  • ast-grep scan requires project config and will error if no sgconfig.yml is found. ast-grep run can still search

without project config, though it also benefits from discovered config for things like customLanguages and languageGlobs.

  • ast-grep scan --inspect summary is the quickest way to confirm which project directory and config file ast-grep

actually selected during discovery.

  • ast-grep also recognizes a home-directory sgconfig.yml as a global fallback config. XDG config directories are not

part of this behavior.

  • Keep sgconfig.yml authoring on the skill path and pass the project config to ast-grep commands where needed.

Rule Catalog

  • Use the ast-grep catalog as inspiration when the user wants existing example rules, not as something to copy blindly.
  • Start from examples in the same language family when possible.
  • Read catalog markers as hints about rule complexity:
  • simple pattern examples are good starting points
  • Fix means the example includes a rewrite path
  • constraints, labels, utils, transform, and rewriters mean the example depends on more advanced rule

features

  • When adapting a catalog example, translate it to the current repository’s language, style, and safety constraints

instead of preserving the example verbatim.

  • Prefer the bundled skill workflow when the user asks to explain, adapt, or combine catalog examples.

VT Code Bundled Rules

VT Code ships a set of curated ast-grep rules under rules/ with matching tests under rule-tests/. Run them with vtcode check ast-grep. The bundled rules are organised by language:

Python (rules/python/)
  • no-print: flags print() calls in production code
  • no-walrus-source: flags walrus operators that harm readability
  • no-unnecessary-list: flags list(...) wrapping an already-list expression
  • no-identity-check-with-type: flags type(x) is T in favor of isinstance(x, T)
  • optional-to-union: flags Optional[X] in favor of X | None
  • prefer-dict-get: flags if k in d: d[k] in favor of d.get(k)
  • prefer-generator-expression: flags list comprehensions passed to sum/any/all/min/max
  • prefer-isinstance-tuple: flags isinstance(x, A) or isinstance(x, B) in favor of isinstance(x, (A, B))
Rust (rules/rust/)
  • no-unsafe-fn-without-unsafe: flags unsafe fn bodies that contain no unsafe block
  • avoid-duplicate-export: flags pub use when pub mod already exposes the module
  • no-iterator-for-each: flags .iter().for_each() in favor of for loops
  • no-redundant-closure: flags |x| foo(x) in favor of foo directly
  • let-chain-candidate: flags nested if that could be collapsed with let-chains
  • no-chars-enumerate: flags .chars().enumerate() when .char_indices() is more idiomatic
  • no-alloc-digit-count: flags digit-count loops that allocate instead of using repeated division
  • prefer-iterator-sum: flags manual accumulator loops in favor of .sum()
  • prefer-retain-over-filter-collect: flags .filter().collect() on a Vec in favor of .retain()
  • prefer-unwrap-or-default: flags .unwrap_or(Default::default()) in favor of .unwrap_or_default()
Kotlin (rules/kotlin/)
  • no-var: flags mutable var declarations
  • no-println: flags println/print calls
  • no-lateinit: flags lateinit var usage
  • no-unsafe-cast: flags as casts without null-safe as?
  • no-unnecessary-let: flags let blocks that add no value
  • prefer-is-empty: flags .count() == 0 in favor of .isEmpty()
  • prefer-data-class: flags classes that should be data class
  • clean-architecture-imports: flags imports that violate clean architecture layer boundaries
Ruby (rules/ruby/)
  • no-path-traversal: flags string concatenation in File.join / Pathname that may cause traversal
  • prefer-action-over-filter: flags before_filter / after_filter in favor of before_action / after_action
  • prefer-symbol-over-proc: flags Proc.new with a symbol when (&:method) is cleaner
TypeScript (rules/typescript/)
  • no-await-in-promise-all: flags await inside Promise.all() arrays (defeats parallelism)
  • no-console-except-error: flags console.log/debug/warn/info/trace (allows console.error in catch blocks)
  • no-debugger: flags debugger statements
  • no-unnecessary-boolean-literal-compare: flags x === true or x === false
  • no-useless-promise-resolve: flags return Promise.resolve(...) in async functions
  • prefer-array-flat-map: flags .map(fn).flat() in favor of .flatMap(fn)
  • prefer-nullish-coalescing: flags || in assignments/returns where ?? is more precise
  • use-logical-assignment: flags $A = $A || $B in favor of $A ||= $B
  • prefer-optional-chaining: flags a && a.b in favor of a?.b
  • no-return-in-forEach: flags return inside .forEach() callbacks (does not return from caller)
  • no-array-delete: flags delete arr[i] in favor of .splice()
TSX (rules/tsx/)
  • avoid-jsx-short-circuit: flags {cond && <Elem />} in favor of {cond ? <Elem /> : null} (prevents rendering 0)
  • no-nested-links: flags <a> elements nested inside other <a> elements (invalid HTML)
  • no-unnecessary-usestate-type: flags useState<string>('hello') when TypeScript can infer the type
  • rename-svg-attribute: flags hyphenated SVG attributes like stroke-linecap in favor of camelCase strokeLinecap
Examples (rules/examples/)
  • no-console-log: starter rule scoped to __ast_grep_examples__/ for scaffold validation

Rust Catalog Highlights

  • Avoid duplicated exports: a Rust lint-style rule can detect pub use foo::Bar; in the same source file that already

exposes pub mod foo;. Treat this as API-surface cleanup, not a mechanical rewrite. The rule uses all to combine a pub use $A::$B; pattern with inside: { kind: source_file } and a has check for pub mod $A; with stopBy: end:

yaml
id: avoid-duplicate-export
language: Rust
severity: warning
message: Item re-exported via `pub use` when `pub mod` already exposes the module.
rule:
all:
- pattern: "pub use $A::$B;"
- inside:
kind: source_file
- has:
pattern: "pub mod $A;"
stopBy: end
  • Beware chars().enumerate(): the Rust catalog rewrite from $A.chars().enumerate() to $A.char_indices() is valid

when the code needs byte offsets instead of character indexes. Do not apply blindly if the caller intentionally wants character positions:

yaml
id: no-chars-enumerate
language: Rust
severity: warning
message: Use `.char_indices()` instead of `.chars().enumerate()` when byte offsets are needed.
rule:
pattern: "$A.chars().enumerate()"
fix: "$A.char_indices()"

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
5

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
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/vinhnx/vtcode/ast-grep/badge)](https://verified-skill.com/skills/vinhnx/vtcode/ast-grep)

Something wrong with this skill or its page? Tell us.