Skip to content

feat: index the Salesforce stack (Apex, LWC, Aura, Visualforce)#714

Open
dormonbear wants to merge 3 commits into
colbymchenry:mainfrom
dormonbear:feat/salesforce-stack
Open

feat: index the Salesforce stack (Apex, LWC, Aura, Visualforce)#714
dormonbear wants to merge 3 commits into
colbymchenry:mainfrom
dormonbear:feat/salesforce-stack

Conversation

@dormonbear

Copy link
Copy Markdown

Add end-to-end indexing for Salesforce projects as one connected graph:

  • Apex (.cls/.trigger): vendored tree-sitter-apex.wasm (ABI 15) + declarative extractor — classes, interfaces, enums, methods, constructors, properties, triggers, inner classes; call/extends/implements edges; annotations.
  • Visualforce (.page/.component), Aura (.cmp/.app/.evt/.intf), and LWC HTML templates (lwc/*.html): custom markup extractors (one component node per file).
  • Cross-layer salesforce.ts resolver: LWC/Aura JS @salesforce/apex imports ->
    Apex method; VF controller=/extensions=/<c:comp> -> Apex class/component; Aura cmp.get("c.x") -> Apex method. Apex stays its own language family so the framework gate keeps these cross-language edges.

Validated: check-grammar PASS (ABI 15); verify-extraction PASS on ebikes-lwc, dreamhouse-lwc, apex-recipes; agent A/B (claude -p, Opus 4.8) shows the LWC->Apex flow answered by one codegraph_explore with 0 Read/0 Grep vs 4-9 Read without. 17 extraction tests; full suite 1257 passed / 0 failed.

Docs: README supported-languages + coverage tables, CHANGELOG, coverage playbook entry, docs/design/salesforce-stack.md, agent-eval corpus.

Add end-to-end indexing for Salesforce projects as one connected graph:

- Apex (.cls/.trigger): vendored tree-sitter-apex.wasm (ABI 15) + declarative
  extractor — classes, interfaces, enums, methods, constructors, properties,
  triggers, inner classes; call/extends/implements edges; annotations.
- Visualforce (.page/.component), Aura (.cmp/.app/.evt/.intf), and LWC HTML
  templates (lwc/*.html): custom markup extractors (one component node per file).
- Cross-layer salesforce.ts resolver: LWC/Aura JS @salesforce/apex imports ->
  Apex method; VF controller=/extensions=/<c:comp> -> Apex class/component;
  Aura cmp.get("c.x") -> Apex method. Apex stays its own language family so the
  framework gate keeps these cross-language edges.

Validated: check-grammar PASS (ABI 15); verify-extraction PASS on ebikes-lwc,
dreamhouse-lwc, apex-recipes; agent A/B (claude -p, Opus 4.8) shows the LWC->Apex
flow answered by one codegraph_explore with 0 Read/0 Grep vs 4-9 Read without.
17 extraction tests; full suite 1257 passed / 0 failed.

Docs: README supported-languages + coverage tables, CHANGELOG, coverage
playbook entry, docs/design/salesforce-stack.md, agent-eval corpus.
A JS/TS bare method call (`.replace()`, `.resolve()`) was exact-matched to a
single same-named method in another language at confidence 0.5, since `calls`
edges are intentionally left ungated for cross-layer bridges. This inflated an
Apex method's dependents with false JS callers (e.g. CurrencyTokenReplacer::
replace picking up every String.replace in a React app).

Gate `calls` only when the CALLER is in a known multi-language family (web,
jvm, apple, c, dotnet): such a language is self-sufficient, so a genuine
cross-family call goes through a framework/import resolver, never a bare name.
Singleton/unknown-family callers (aura/visualforce → apex, config↔code) stay
ungated. The deliberate Aura cmp.get("c.method") → Apex dispatch, whose JS file
is a known-family caller, is re-routed through the salesforce framework resolver
(Strategy 1, ungated) so it still connects.
The first pass gated only known multi-language families (web/jvm/apple/c/
dotnet). Singleton-family languages that are nonetheless self-sufficient
programming languages (python/go/rust/php/ruby/dart/lua/pascal) were left
ungated, so a Python `str.replace()` still bound to an Apex `…::replace` by
name collision. Gate the calls of any self-sufficient programming-language
caller; markup/template/config callers (visualforce/lwc/aura/svelte/vue/liquid/
twig/xml/yaml) stay ungated to preserve config->code bridges.
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