`scan --inline-rules` never binds global utils from `utilDirs`, with or without `--config`
ast-grep 0.45.3, macOS arm64.
sgconfig.yml declares ruleDirs and utilDirs. A rule file under ruleDirs that references a global util through matches: <util-id> loads and passes ast-grep test. The same rule body passed through scan --inline-rules fails the rule parse with Rule <util-id> is not defined, in every configuration form:
- run from the project root, where
sgconfig.ymlis discovered by the upward walk - run with
-c sgconfig.yml - run from an unrelated directory with
--config /abs/path/sgconfig.yml
The config is read in these runs: with --config, an inline rule under a customLanguages grammar (language: xml) parses and matches, and without it the same rule fails on the unknown language. So --config reaches customLanguages and languageGlobs for inline rules but not utilDirs.
Reproduction:
# utils/hook.yml
# id: hook
# language: tsx
# rule: {kind: arrow_function}
# sgconfig.yml
# ruleDirs: [rules]
# utilDirs: [utils]
printf 'const f = () => 1;\n' | ast-grep scan --config sgconfig.yml --inline-rules $'id: p\nlanguage: tsx\nrule: {matches: hook}' --json --stdin
# Error: Cannot parse rule INLINE_RULES ... Rule `hook` is not defined.The documentation for utilDirs states that global utility rules are discovered from those directories and referenced with matches, and names no exception for --inline-rules. The --inline-rules documentation describes the option as running a rule "without saving it to a file first", which reads as the same rule with the same resolution. Issue #588 settled that scan --rule skips global rules by design as a no-project form; --inline-rules together with an explicit --config is the case that answer does not cover.
Expected: when a --config (or a discovered sgconfig.yml) is present, scan --inline-rules resolves matches: <global-util> from utilDirs the way a rule under ruleDirs does. If the omission is by design, the --inline-rules and utilDirs reference pages could state it.
Why it matters: MCP servers and editor integrations (ast-grep-mcp prepends --config <sgconfig> to every call and runs scan --inline-rules) cannot reuse a project's util library from an ad-hoc rule, so every ad-hoc rule re-inlines the util body.
Source: ast-grep/ast-grep