diff --git a/graphify/extract.py b/graphify/extract.py
index 4b9efa732..a830d44d7 100644
--- a/graphify/extract.py
+++ b/graphify/extract.py
@@ -2405,6 +2405,42 @@ def extract_svelte(path: Path) -> dict:
return result
+_ASTRO_FRONTMATTER_RE = re.compile(r"\A\s*---[^\S\r\n]*\r?\n([\s\S]*?)\r?\n---")
+_ASTRO_SCRIPT_RE = re.compile(
+ r"",
+ re.IGNORECASE,
+)
+_ASTRO_NON_JS_TYPE_RE = re.compile(
+ r"""\btype\s*=\s*["']?(?!module\b|text/javascript\b|application/javascript\b)""",
+ re.IGNORECASE,
+)
+
+
+def _astro_mask_non_script(src: str) -> str:
+ """Blank everything in a ``.astro`` file except frontmatter and JS ``
+
+""",
+ )
+ result = extract_astro(page)
+ assert result.get("parse_errors") is None
+ labels = _labels(result)
+ assert "rank()" in labels and "toggle()" in labels
+ # Masking keeps offsets, so locations still point at the original lines.
+ assert labels["rank()"] == "L5"
+ assert labels["toggle()"] == "L15"
+
+
+def test_extract_astro_scripts_on_one_line_do_not_merge(tmp_path):
+ """Two script bodies on one line must not parse as a single statement."""
+ page = _write(
+ tmp_path / "src/pages/inline.astro",
+ "\n",
+ )
+ result = extract_astro(page)
+ assert result.get("parse_errors") is None
+ assert "b()" in _labels(result)