agentleFS
Locker-Room-ToolsLocker-Room-Tools/synapse/.agents/skills/add-language/SKILL.md

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

  • Other versions4 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 4

    1. ZoneMinder/zmNinjaNg★ 101same name
    2. DailybotHQ/deepworkplan-website★ 15same name
    3. madeinoz67/madeinoz-knowledge-system★ 3same name
    4. 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.

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
  1. Very specific:

    After registering, uv run python -m synapse grammars install must succeed.

    line 23
  2. Very specific:

    Create src/synapse/queries/<lang>/symbols.scm and references.scm.

    line 27
  3. Very specific:

    Add one LanguageSpec(...) to LANGUAGES in src/synapse/core/languages/registry.py.

    line 52
  4. Very specific:

    Add one tuple (language, file_name, source, expected_symbol, expected_reference) to the appropriate TIER*_SAMPLES table in …

    line 76
  5. Very specific:

    Add the language to the matching TIERn_LANGUAGES list in tests/core/languages/test_queries.py.

    line 81
  6. Very specific:

    Add one detect_language(Path("x.<ext>")) == "<id>" line to test_detect_language_by_extension in tests/core/languages/test_registry.py.

    line 83
  7. Very specific:

    Add a CHANGELOG.md entry under ## [Unreleased] (recent entries show the tier-announcement wording).

    line 90

“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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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_map raises 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 (see angular_template).
  • Call semantics are evidence-based. call_usage_kinds must be a strict subset of reference_usage_kinds, and every advertised usage kind must appear as @reference.<kind_with_underscores> in the packaged query (pinned by tests such as test_ts_js_advertised_usage_kinds_are_backed_by_query_captures). Default both to empty — an empty call_usage_kinds means 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's invocation).
  • 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.

  1. Add one tuple (language, file_name, source, expected_symbol, expected_reference) to the appropriate TIER*_SAMPLES table in tests/core/indexing/test_parser_tier2.py … tier5.py. For Tier-1-grade support (rich symbol coverage), write a dedicated test_parse_file_extracts_<lang>_symbols in tests/core/indexing/test_parser.py following the existing per-language tests.
  2. Add the language to the matching TIERn_LANGUAGES list in tests/core/languages/test_queries.py.
  3. Add one detect_language(Path("x.<ext>")) == "<id>" line to test_detect_language_by_extension in tests/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.md entry under ## [Unreleased] (recent entries show the tier-announcement wording). There is no per-language table in docs/ or README.md to 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/indexing

Download now (ZIP)

Does 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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.