# Extension points — Graphify-Labs/graphify

> Canonical page: https://codevetter.com/unpack/graphify/extension-points

# Extension points — Graphify-Labs/graphify

Scanned commit 20a20d30d8e7eef77675651f0199d87f913bd3e7 (2026-09-20). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The codebase has clear, documented seams for extension: a suffix/filename/shebang dispatch table for new language extractors, a LanguageResolver registry for cross-file resolution passes, a BACKENDS dict + custom-provider JSON for LLM backends, a _PLATFORM_CONFIG table + skillgen fragments for new assistant platforms, and one-function-per-format exporters. ARCHITECTURE.md carries an explicit 5-step checklist for adding a language.
- New languages plug into extract.py's _DISPATCH suffix table (plus _SHEBANG_DISPATCH for extensionless, filename routers for MCP configs/package manifests, and content sniffs for ambiguous .h/.m); ARCHITECTURE.md lists the full checklist: extractor fn, _DISPATCH + collect_files registration, CODE_EXTENSIONS + watch _WATCHED_EXTENSIONS, pyproject grammar dep, fixture + tests. — [graphify/extract.py#L6270-6373](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/extract.py#L6270-L6373) [graphify/extract.py#L6411-6545](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/extract.py#L6411-L6545) [ARCHITECTURE.md#L75-81](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/ARCHITECTURE.md#L75-L81)
- Cross-file/language-specific resolution passes register via resolver_registry.register(LanguageResolver(name, suffixes, resolve)) — e.g. terraform_modules, swift/python/ruby/typescript/csharp/java/rust member calls, kotlin import targets, csharp interface dispatch — and run_language_resolvers activates only resolvers whose suffixes appear in the corpus, logging-and-continuing on failure. — [graphify/resolver_registry.py#L28-85](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/resolver_registry.py#L28-L85) [graphify/extract.py#L5143-5256](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/extract.py#L5143-L5256)
- extractors/ is the destination for new/migrated language extractors: MIGRATION.md prescribes verbatim moves, a mandatory facade re-export in extract.py, registry entry in extractors/__init__.py (LANGUAGE_EXTRACTORS seed), and a registry test — with strict 'never import graphify.extract from this package' directionality. — [graphify/extractors/MIGRATION.md#L36-107](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/extractors/MIGRATION.md#L36-L107) [graphify/extractors/__init__.py#L1-30](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/extractors/__init__.py#L1-L30)
- LLM backends extend via the BACKENDS dict (base_url, default_model, env_key, pricing, temperature, vision) plus a call path (_call_openai_compat covers most); custom providers are added at runtime with `graphify provider add --base-url --default-model --env-key` persisted to a user-global JSON via _custom_providers_path. — [graphify/llm.py#L101-200](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/llm.py#L101-L200) [graphify/llm.py#L225-308](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/llm.py#L225-L308) [graphify/cli.py#L1101-1158](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/cli.py#L1101-L1158)
- New assistant platforms extend _PLATFORM_CONFIG (skill_file, skill_dst, claude_md, skill_refs) and get generated artifacts by adding fragments under tools/skillgen/fragments/ + an entry in platforms.toml; install destinations and always-on blocks are resolved from packaged assets under graphify/skills/ and graphify/always_on/. — [graphify/install.py#L120-260](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/install.py#L120-L260) [tools/skillgen/gen.py#L1-56](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/tools/skillgen/gen.py#L1-L56) [pyproject.toml#L144-150](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/pyproject.toml#L144-L150)
- Exporters are one-function-per-format in export.py (to_json, to_obsidian, to_canvas, to_graphml, to_svg, to_cypher) with html/callflow-html and neo4j/falkordb push in the exporters/ subpackage; a new format adds a function plus a `graphify export` subcommand arm. — [graphify/export.py#L271-535](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/export.py#L271-L535) [graphify/exporters/graphdb.py#L9-40](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/exporters/graphdb.py#L9-L40) [graphify/cli.py#L2782-2790](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/cli.py#L2782-L2790)
- Optional-dependency gating is itself an extension seam: _EXTRA_FOR_EXTENSION maps suffixes to extras (.sql->sql, .tf->terraform, .ml->ocaml, .robot->robot...) so a grammar-backed language can ship as an extra without breaking the base install, and the #1745 warning names the missing extra to the user. — [graphify/extract.py#L6376-6399](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/extract.py#L6376-L6399) [pyproject.toml#L52-108](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/pyproject.toml#L52-L108)
- The MCP tool list is extended by appending a types.Tool to the _tools list in _build_server and a handler in the dispatch dict — project_path is injected into every schema automatically, so new tools inherit multi-project support for free. — [graphify/serve.py#L1866-2019](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/serve.py#L1866-L2019) [graphify/serve.py#L2250](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/serve.py#L2250)
- New edge relations/relations-of-interest surface in affected traversal via DEFAULT_AFFECTED_RELATIONS and in build-time stub minting via _EXTERNAL_STUB_RELATIONS — both are small frozensets designed to be extended. — [graphify/affected.py#L11-29](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/affected.py#L11-L29) [graphify/build.py#L64-77](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/build.py#L64-L77)
- Caching tiers are separately pluggable: the AST cache is versioned per package release + _AST_CACHE_SCHEMA bump, while the semantic cache is keyed by a fingerprint of the extraction prompt file — so changing the extraction-spec.md prompt invalidates semantic entries without touching AST entries. — [graphify/cache.py#L22-98](https://github.com/Graphify-Labs/graphify/blob/20a20d30d8e7eef77675651f0199d87f913bd3e7/graphify/cache.py#L22-L98)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
