add-language
Skill2 starsChanged 3 months agoMITView on GitHub
Add tree-sitter language support to Synapse — .scm query pair, LanguageSpec registry entry, tier tests. Use when asked to add, extend, or fix support for a programming language, its file extensions, or its symbol/reference extraction.
4 other projects use a version of this.
Adopted by
Most recently taken up by
- GeoffMillerAZ/fathomtheir own version, first seen Nov 8, 2026
- DailybotHQ/deepworkplan-websitetheir own version, first seen Oct 9, 2026
- madeinoz67/madeinoz-knowledge-systemtheir own version, first seen Jan 18, 2026
- ZoneMinder/zmNinjaNgtheir own version, first seen Jan 10, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- ZoneMinder/zmNinjaNg★ 101same name
- DailybotHQ/deepworkplan-website★ 15same name
- madeinoz67/madeinoz-knowledge-system★ 3same name
- GeoffMillerAZ/fathom★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository7 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- ab-evalSkill
- add-adapterSkill
- add-mcp-toolSkill
- releaseSkill
- schema-changeSkill
The file
We split this skill into the rules it gives an agent
7 rules. 0 are common, 0 are distinctive, and 7 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 23
After registering, uv run python -m synapse grammars install must succeed.
- Very specific: line 27
Create src/synapse/queries/<lang>/symbols.scm and references.scm.
- Very specific: line 52
Add one LanguageSpec(...) to LANGUAGES in src/synapse/core/languages/registry.py.
- Very specific: line 76
Add one tuple (language, file_name, source, expected_symbol, expected_reference) to the appropriate TIER*_SAMPLES table in …
- Very specific: line 81
Add the language to the matching TIERn_LANGUAGES list in tests/core/languages/test_queries.py.
- Very specific: line 83
Add one detect_language(Path("x.<ext>")) == "<id>" line to test_detect_language_by_extension in tests/core/languages/test_registry.py.
- Very specific: line 90
Add a CHANGELOG.md entry under ## [Unreleased] (recent entries show the tier-announcement wording).
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Add a language
New languages are added via declarative .scm queries plus one registry entry — never via
per-language branching in src/synapse/core/indexing/parser.py. If the task seems to need a
parser branch, the design is wrong; stop and reconsider the query or the LanguageSpec metadata.
1. Grammar precondition
LanguageSpec.tree_sitter_name must be a grammar that tree-sitter-language-pack ships — the
install path is fully registry-derived (tree_sitter_language_names() collects
spec.tree_sitter_name values; install_grammars() prefetches exactly that set). There is no
separate grammar list to edit. Verify early:
uv run python -c "from tree_sitter_language_pack import get_language; get_language('<name>')"After registering, uv run python -m synapse grammars install must succeed.
2. Query pair
Create src/synapse/queries/<lang>/symbols.scm and references.scm. Both are required and must
be non-empty (core/languages/queries.py raises on missing/empty;
tests/core/languages/test_queries.py loops over all of LANGUAGES asserting @reference
appears). Start by copying the nearest-relative language's pair. query_dir may point at another
language's directory when the grammar is shared (tsx reuses query_dir="typescript").
symbols.scm — each match must contain exactly one @definition.<kind> capture and one
@name capture, or the match is skipped. Valid kinds are the _CAPTURE_KIND_MAP set in
src/synapse/core/indexing/parser.py:
class constant constructor enum field function import interface method module namespace package
property record struct type variable — any other suffix raises. Map onto the
Container/Entity/Worker model: containers = namespace/package/module/class/interface/struct/
record/enum/type; workers = function/method/constructor/property; entities =
field/variable/constant/import. Containment (nesting) is computed from byte ranges, not from the
query — do not try to encode parent/child in the query. ALL-CAPS field/variable captures are
auto-promoted to constant when uppercase_constants=True (the default).
references.scm — capture suffix becomes the stored usage kind via
suffix.replace("_", "-") (@reference.base_type → base-type); a bare @reference stores no
usage kind (the go style — correct when you cannot distinguish reference positions). Copy the
leading comment convention from src/synapse/queries/python/references.scm, which documents
which suffixes are advertised and why only some are call-proven.
3. Registry entry
Add one LanguageSpec(...) to LANGUAGES in src/synapse/core/languages/registry.py.
Minimal shape (most languages): id, tree_sitter_name, extensions, query_dir, plus
name_separator if not "." (rust uses "::").
Rules that bite:
- Extensions are exclusive.
_build_extension_mapraises on duplicate claims; the collision policy comment near the bottom of the file documents the precedents (.m→matlab,.h→c,.v→verilog). The losing language must simply not list the extension. Extension-less matching goes through_FILENAME_SUFFIX_TO_LANGUAGE(seeangular_template). - Call semantics are evidence-based.
call_usage_kindsmust be a strict subset ofreference_usage_kinds, and every advertised usage kind must appear as@reference.<kind_with_underscores>in the packaged query (pinned by tests such astest_ts_js_advertised_usage_kinds_are_backed_by_query_captures). Default both to empty — an emptycall_usage_kindsmeans the language yields no caller/callee evidence, which is honest; a wrong one silently corrupts call-proven navigation. Only advertise a kind as a call when the query capture provably matches only call sites (e.g. Python'sinvocation). reference_syntax(the structural resolver config) exists only for csharp and python; do not attempt one for a new language unless that is explicitly the task.
4. Tests
There are no on-disk fixtures — samples are inline string literals.
- Add one tuple
(language, file_name, source, expected_symbol, expected_reference)to the appropriateTIER*_SAMPLEStable intests/core/indexing/test_parser_tier2.py…tier5.py. For Tier-1-grade support (rich symbol coverage), write a dedicatedtest_parse_file_extracts_<lang>_symbolsintests/core/indexing/test_parser.pyfollowing the existing per-language tests. - Add the language to the matching
TIERn_LANGUAGESlist intests/core/languages/test_queries.py. - Add one
detect_language(Path("x.<ext>")) == "<id>"line totest_detect_language_by_extensionintests/core/languages/test_registry.py.
5. Docs and changelog
CONTRIBUTING.md§ "Adding a language" is the canonical human checklist — keep it consistent if this skill's procedure and the doc ever diverge.- Add a
CHANGELOG.mdentry under## [Unreleased](recent entries show the tier-announcement wording). There is no per-language table indocs/orREADME.mdto update.
6. Packaging and gate
Query files must live under src/synapse/ to ship in the wheel — the release workflow gates on
≥100 packaged .scm files. Finish with:
uv run ruff check && uv run mypy && uv run pytest -q tests/core/languages tests/core/indexingDoes it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

