Problem
ARCHITECTURE.md's "Adding a new language extractor" walkthrough is clear, but every step lands inside the core repo: a new module under `graphify/extractors/`, a dispatch-table registration in `extract.py`, a suffix addition in `detect.py` and `watch.py`, plus a new tree-sitter dependency in `pyproject.toml`. The issue backlog already shows the cost of that: GDScript (#2152), Haxe (#1424), MATLAB (#2935), 1C/BSL (#2127) and others are all separate, unclaimed feature requests, each waiting on someone to carry a full core-repo change through review — and each new language grows the core dependency surface for everyone, whether they use it or not.
Proposal
Let a language extractor live in its own installable package and register itself via a Python entry point (e.g. `graphify.extractors`), the same pattern pytest plugins or Flake8 checks use. At startup, `extract.py`'s dispatch table would discover installed extractor packages via `importlib.metadata.entry_points`, alongside (not replacing) the built-in dispatch table for the languages graphify ships today.
Each third-party package would own: its own tree-sitter grammar dependency, its own `extract_(path) -> dict` function following the existing schema, and its own suffix registration — all outside the core repo's dependency tree.
Why this fits now
It turns "someone requests a niche language, a maintainer has to review and carry a core-repo PR" into "someone ships and maintains their own package, users `pip install` it if they need it." It doesn't compete with keeping popular languages built-in — it's specifically for the long tail already visible in the open feature requests.
Open question
Whether built-in extractors should also be migrated to this mechanism (uniform path) or stay as-is with the entry-point path only for new third-party additions — happy to follow whichever direction you'd prefer here.
Note
This is a proposal, not a commitment to implement — happy to discuss shape/scope first.
Problem
ARCHITECTURE.md's "Adding a new language extractor" walkthrough is clear, but every step lands inside the core repo: a new module under `graphify/extractors/`, a dispatch-table registration in `extract.py`, a suffix addition in `detect.py` and `watch.py`, plus a new tree-sitter dependency in `pyproject.toml`. The issue backlog already shows the cost of that: GDScript (#2152), Haxe (#1424), MATLAB (#2935), 1C/BSL (#2127) and others are all separate, unclaimed feature requests, each waiting on someone to carry a full core-repo change through review — and each new language grows the core dependency surface for everyone, whether they use it or not.
Proposal
Let a language extractor live in its own installable package and register itself via a Python entry point (e.g. `graphify.extractors`), the same pattern pytest plugins or Flake8 checks use. At startup, `extract.py`'s dispatch table would discover installed extractor packages via `importlib.metadata.entry_points`, alongside (not replacing) the built-in dispatch table for the languages graphify ships today.
Each third-party package would own: its own tree-sitter grammar dependency, its own `extract_(path) -> dict` function following the existing schema, and its own suffix registration — all outside the core repo's dependency tree.
Why this fits now
It turns "someone requests a niche language, a maintainer has to review and carry a core-repo PR" into "someone ships and maintains their own package, users `pip install` it if they need it." It doesn't compete with keeping popular languages built-in — it's specifically for the long tail already visible in the open feature requests.
Open question
Whether built-in extractors should also be migrated to this mechanism (uniform path) or stay as-is with the entry-point path only for new third-party additions — happy to follow whichever direction you'd prefer here.
Note
This is a proposal, not a commitment to implement — happy to discuss shape/scope first.