Per-language extractors. Each reads source and emits the normalized JSON in
docs/schema.md §2. The core never sees source (ADR 0005).
typescript/— ts-morph. Functions, imports, calls, and HTTPconsumes.native/— generic tree-sitter extractor driven by a language registry (Swift, Kotlin; Kotlin also emits Retrofitconsumes).go/— tree-sitter-go. Functions/methods, calls, and chiexposes(ADR 0010).
Most languages drop into native/ with one registry entry:
-
Install the grammar:
npm install tree-sitter-<lang>(pick a version whosetree-sitterpeer matches our pinned core — see.npmrc/ ADR 0008). -
Add it to
LANGUAGESinnative/index.ts:rust: { grammar: Rust, exts: [".rs"], funcType: "function_item", callType: "call_expression", classScopeTypes: ["impl_item"], nameTypes: ["identifier"], classNameTypes: ["type_identifier"], memberType: "field_expression", memberSuffixType: "field_identifier", }
Languages that share the common shape (
function_declaration/call_expression, like Swift/Kotlin) can spread...COMMON. -
That's it —
scan/refreshpick it up automatically (nativeLanguages()), and detection (cli/detect.ts) can mark the extension extractable.
A language whose HTTP framework needs route extraction (like Go + chi) gets its
own extractor instead — see go/ and ADR 0010. Keep it earn-it: add a
language only when a real service needs it (Phase 4 rule).