From e8bde35ed53e347fc514785ecff12872b5b15c22 Mon Sep 17 00:00:00 2001 From: L0garithmic Date: Sun, 27 Sep 2026 18:21:14 -0500 Subject: [PATCH 1/2] fix(vue,explore): index template bindings; rank exact identifiers above 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 +`; + const result = extractFromSource('WorkspaceMyLinkView.vue', code); + const templateRefs = result.unresolvedReferences.filter((r) => r.line <= 11); + const named = (kind: string) => templateRefs.filter((r) => r.referenceKind === kind).map((r) => r.referenceName); + + // Bound script state is a reference, on the template line that binds it. + const locked = templateRefs.filter((r) => r.referenceName === 'myLinkBrandingLocked'); + expect(locked.map((r) => r.line).sort()).toEqual([2, 4]); + expect(named('references')).toContain('isActive'); + expect(named('references')).toContain('domains'); + // A bare event handler and a template call are calls. + expect(named('calls')).toContain('saveDomain'); + expect(named('calls')).toContain('formatDomain'); + // Locals, object keys, member tails, globals, $-helpers and string contents bind nothing. + const all = templateRefs.map((r) => r.referenceName); + for (const absent of ['item', 'index', 'row', 'active', 'id', 'label', 'Math', 'max', '$t']) { + expect(all).not.toContain(absent); + } + expect(templateRefs.filter((r) => r.referenceName === 'isActive')).toHaveLength(1); + }); + it('should extract from both