Skip to content

fix(vue,explore): index Vue template bindings; rank exact identifiers above plain words - #2073

Open
L0garithmic wants to merge 2 commits into
colbymchenry:mainfrom
L0garithmic:fix/vue-template-bindings-precise-rank
Open

L0garithmic wants to merge 2 commits into
colbymchenry:mainfrom
L0garithmic:fix/vue-template-bindings-precise-rank

Conversation

@L0garithmic

Copy link
Copy Markdown

Two fixes found while using codegraph on a large Vue + TypeScript monorepo.

1. Vue templates now produce edges for the identifiers they bind

Vue SFC templates were indexed for component tags only. An identifier a template binds (:prop="x", @event="save", v-if / v-show / v-model values, v-for sources, {{ mustache }} expressions) produced no edge, so "where is myLinkBrandingLocked used" had no answer and explore never rendered the template line that binds a named symbol.

src/extraction/vue-extractor.ts now emits calls for template calls and handler names and references for bare identifiers that the <script> blocks declare or import. It skips v-for and slot locals, object keys, member tails, globals and $-helpers. Explore also renders the same-file use sites of a named symbol, whose source is the whole-file component node that the range builder drops as an envelope.

2. Exact identifiers rank above plain English words

Once a precise query token (camelCase, PascalCase, snake_case, qualified) resolves to a named seed, a file whose only claim is a plain query word (no seed, no precise term, no symbol one edge from a seed) now loses entry-file gate protection and centrality and sorts last, so it only gets leftover budget. Example: WorkspaceMyLinkView appearance section myLinkBrandingLocked spent its budget after the view on an unrelated PHP layout class that matched only "section".

A second commit keeps the files one edge from the named seed (its callers and callees) in the relevance gate, and exempts them from the allocation cliff only while such a word-only file is in the running. Without it, a caller of the exact symbol (the answer to "where is X used") scored under the cliff because it matches no query word, while the word-only file kept its bytes. Its weight and share are unchanged, and when no word-only file exists the cliff behaves exactly as before.

Tests

  • __tests__/extraction.test.ts: template bindings produce the expected calls and references edges, and locals, keys, globals and $-helpers produce none.
  • __tests__/explore-nl-stopword-collision.test.ts: precise-before-plain ordering.

Rebased onto current main (through #2064). tsc --noEmit is clean, and every __tests__/*explore*.test.ts file plus extraction.test.ts passes (the 692 extraction tests included). One note from running them locally on Windows: with many files per worker a thread died with a V8 "Fatal process out of memory: Zone" before reporting. Each file passes on its own, so this looks like worker memory rather than these changes.

L0garithmic and others added 2 commits September 28, 2026 02:48
…ve plain words

Vue SFC templates were indexed only for component tags. Identifiers a
template binds (`:prop="x"`, `@event="save"`, `v-if`, `v-for` sources,
`{{ mustache }}`) produced no edge, so "where is myLinkBrandingLocked
used" had no answer and explore never rendered the template lines that
bind a named symbol. The Vue extractor now emits `calls` for template
calls and handler names and `references` for bare identifiers the
<script> blocks declare or import, skipping v-for/slot locals, object
keys, member tails, globals and $-helpers. Explore renders same-file
use sites of a named symbol (the component envelope was dropped).

Explore: once a precise query token resolves to a named seed, a file
whose only claim is a plain query word (no seed, no precise term, no
symbol one edge from a seed) loses entry-file gate protection and
centrality and sorts last, so it only takes leftover budget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…llocation cliff

The precise-before-plain tier sorted src/profile/panel.ts (calls the named
seed) above the word-only file, but allocateExploreBudget cliffed it to a
pointer: it matches no query word, so its score (3.5) sat under the cliff
(7.5) while the word-only file kept its bytes. Seed-neighbour files now
carry an `anchored` flag that exempts them from the cliff only (weight and
share unchanged), set only while a word-only file exists. The neighbour set
is hoisted so the relevance gate also keeps them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant