feat(extract): give .svelte and .astro a real AST pass via script masking - #2731
feat(extract): give .svelte and .astro a real AST pass via script masking#2731RepairYourTech wants to merge 1 commit into
Conversation
…king extract_svelte and extract_astro fed the raw file to the JS grammar. HTML markup is not valid JS, so tree-sitter produced a top-level ERROR node, the AST pass was abandoned, and both extractors fell back to regex-scraping imports. Every function, const, interface and type in those files was invisible to the graph. graphify already solves this for .vue: _vue_mask_non_script blanks the markup (preserving newlines so line numbers stay accurate) and hands the result to _extract_generic via source_override — a parameter whose docstring states it exists so "container formats (e.g. Vue SFCs) mask the wrapper and parse just the embedded <script>". Svelte and Astro were never wired to it. - .svelte reuses _vue_mask_non_script verbatim; the <script> shape matches Vue's, including the lang= grammar selection (tsx/js/ts). - .astro gains _astro_mask, covering the `---` fenced frontmatter plus client <script> bodies. _astro_best_mask falls back to frontmatter-only for the few files whose client script does not concatenate onto frontmatter as valid TS, so those parse clean instead of degrading. - _parse_js_tree masks both formats too, so import resolution sees the script. Measured on a Svelte 5 + Astro monorepo (1,367 files): .svelte 260 files 931 -> 4,307 nodes 1,047 -> 6,225 edges .astro 1,107 files 2,946 -> 6,607 nodes 9,963 -> 15,337 edges Non-Svelte/Astro extraction is byte-identical: node/edge digests over ts, tsx, rust, python, sql and json samples are unchanged. The existing test_vue_extraction, test_astro_extraction and test_astro_import_ids suites pass, and the broader extraction sweep goes 723 -> 731 passing with the same 231 pre-existing environment failures.
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
This pull request modifies the Svelte and Astro extractors so that both mask out the non-code regions of the file (markup/template/style) and parse the remaining script with the TypeScript grammar, rather than feeding the raw file to the JS grammar. It adds new _astro_mask and _astro_best_mask helpers in resolution.py, wires the masking into extract_svelte, extract_astro, and _parse_js_tree, and keeps the existing regex-based import fallback. A new test file exercises the masking helpers and end-to-end extraction for both file types, and a changelog entry describes the change.
No blocking issues surfaced. 2 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 1839 functions depend on the 529 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
_extract_generic()— 20 callers, 23 callees - worse:
extract_astro()— 8 callers, 6 callees - worse:
extract_svelte()— 5 callers, 6 callees
Verification — 1839 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 1699 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract\_astro.
The verifier did not have enough to check extract\_astro, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set
Could not verify: Could not verify extract\_svelte.
The verifier did not have enough to check extract\_svelte, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_parse\_js\_tree.
The verifier did not have enough to check \_parse\_js\_tree, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set
· 3 more finding(s) on lines outside this diff (see the check run).
feat(extract): give
.svelteand.astroa real AST pass via script maskingThe problem
extract_svelteandextract_astrofeed the raw file to the JS grammar:HTML markup is not valid JS, so tree-sitter produces a top-level ERROR node, the
AST pass is abandoned, and both extractors fall back to regex-scraping imports.
Their own docstrings acknowledge this:
Imports are rescued by regex, so the gap is invisible in import-shaped tests —
but every function, const, interface and type in those files is missing from
the graph. On a Svelte/Astro codebase that is most of the application.
The fix
graphify already solves exactly this for
.vue._vue_mask_non_scriptblanksthe markup (preserving
\r/\nso line numbers stay accurate) and hands theresult to
_extract_genericviasource_override— a parameter that exists forthis purpose:
Svelte and Astro were simply never wired to it.
.sveltereuses_vue_mask_non_scriptverbatim — the<script>shapematches Vue's, including
lang=grammar selection (tsx / js / ts)..astrogains_astro_mask, covering the---fenced frontmatter plusclient
<script>bodies._astro_best_maskfalls back to frontmatter-only forthe few files whose client script does not concatenate onto the frontmatter as
valid TS, so those parse clean rather than degrading.
_parse_js_treemasks both formats too, so import resolution sees thescript rather than the markup.
The existing regex rescues are left in place — they still cover template-layer
dynamic imports such as
{#await import('./X.svelte')}, which the AST cannotsee, and they dedupe against the AST nodes via
existing_ids.Results
Measured on a Svelte 5 + Astro monorepo (RepairYour.Tech, 1,367 files):
.svelte.astroParse cleanliness after masking: 258/258 Svelte, 1,104/1,107 Astro (from zero
clean before — every file errored at line 1).
Regression safety
ts,tsx,rust,python,sqlandjsonsamplesare byte-identical before and after. Only the
.svelte/.astrodispatchpaths and two new
_parse_js_treebranches are touched; the.vuepath isuntouched.
test_vue_extraction.py,test_astro_extraction.pyandtest_astro_import_ids.pyall pass.failures in my environment (missing optional tree-sitter grammars — identical
set on a clean checkout).
Tests added
tests/test_svelte_astro_masking.py(8 tests), mirroringtest_vue_extraction.py:<script>variants.astrofile with no frontmatter masks safely to blankextract_svelte/extract_astrorecover declarations and keep importsNote for maintainers
This has no issue number yet — happy to open one first if you'd prefer, and to
add the
(#NNNN, thanks @…)reference to the CHANGELOG entry to match theexisting convention.