#!/usr/bin/env node /** * check-sfc-script-parses.mjs — every .vue script block must actually PARSE. * * ⚠ IT IMPORTS `@vue/compiler-sfc`, so it needs an INSTALLED node_modules. Unlike its ~20 sibling * check:* gates, which use only Node built-ins and therefore run in a bare worktree, this one * dies with ERR_MODULE_NOT_FOUND if deps are missing — and it is the FIRST pre-gate to do so, so * its failure is what a dependency-less worktree looks like from the build log. Measured * 2026-09-24 in wt-packet: `node_modules/` was entirely absent, `bun run build` reported * "6/7 pre gates passed — check:sfc-parse FAILED" on a tree with ZERO parse errors, and the real * error (`Cannot find package '@vue/compiler-sfc'`) was hidden by the parallel runner. * If you see this gate fail with ERR_MODULE_NOT_FOUND, run `bun install --frozen-lockfile` — * do NOT chase a parse bug, and do NOT switch the shebang to bun. Switching runtimes only * APPEARS to fix it: bun falls back to a global module cache and resolves the import on a tree * that has no node_modules at all, so this gate goes green while all 23 bundle builds still fail * on `Cannot find package 'vite'`. That is a masked environment fault, not a fix. * * THE GAP THIS CLOSES. `check:template-literal` catches a stray backtick inside a CSS *comment* * within a template literal, but NOT one in LIVE CSS — and a live-CSS backtick breaks the build the * same way. Proven both directions on 2026-09-21 (see * BUG-TEMPLATE-LITERAL-GATE-MISSES-BACKTICKS-IN-LIVE-CSS): planting `content: \`x\`;` into * doxa-simple-map's shadow CSS left check:template-literal at PASS/EXIT=0, while * `BUNDLE=doxa-simple-map bun x vite build` died EXIT=1 with a Babel parseSubscripts stack trace * pointing far from the edit — the exact misleading error that gate exists to replace. * * ★ WHY "NOT ACHIEVABLE" WAS ONE STEP TOO STRONG. That card concluded live-CSS detection was not * achievable, on solid evidence: THREE lookahead heuristics were tried and reverted, scoring 98 and * then 136 false positives on a HEALTHY tree (the real terminator of a template literal is also a * backtick, so no window of surrounding characters can separate the two). The evidence was right * and the inference over-generalised — "no heuristic works" is not "nothing works." The card itself * named the answer in its last line: *needs a tokenizer*. A parser does not guess; it knows where * the literal ends, because ending it is what parsing means. * * ★ MEASURED BEFORE BEING BUILT, against the same tree the heuristics failed on: * lookahead heuristic (pre-fix) -> 98 false positives * lookahead heuristic (post-fix) -> 136 false positives * THIS (parse the script block) -> 0 false positives across 83 .vue files * * WHY @babel/parser SPECIFICALLY: it is the parser Vite's own pipeline reports errors from, so its * verdict matches what actually breaks the build rather than approximating it. @vue/compiler-sfc * splits the SFC first, so the check sees exactly the `