gitnexus 1.5.3 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/README.md +10 -0
  2. package/dist/_shared/graph/types.d.ts +1 -1
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/index.d.ts +1 -0
  5. package/dist/_shared/index.d.ts.map +1 -1
  6. package/dist/_shared/language-detection.d.ts.map +1 -1
  7. package/dist/_shared/language-detection.js +2 -0
  8. package/dist/_shared/language-detection.js.map +1 -1
  9. package/dist/_shared/languages.d.ts +1 -0
  10. package/dist/_shared/languages.d.ts.map +1 -1
  11. package/dist/_shared/languages.js +1 -0
  12. package/dist/_shared/languages.js.map +1 -1
  13. package/dist/_shared/lbug/schema-constants.d.ts +1 -1
  14. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  15. package/dist/_shared/lbug/schema-constants.js +3 -1
  16. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  17. package/dist/_shared/mro-strategy.d.ts +19 -0
  18. package/dist/_shared/mro-strategy.d.ts.map +1 -0
  19. package/dist/_shared/mro-strategy.js +2 -0
  20. package/dist/_shared/mro-strategy.js.map +1 -0
  21. package/dist/cli/ai-context.d.ts +1 -0
  22. package/dist/cli/ai-context.js +28 -4
  23. package/dist/cli/analyze.d.ts +2 -0
  24. package/dist/cli/analyze.js +30 -4
  25. package/dist/cli/group.d.ts +2 -0
  26. package/dist/cli/group.js +233 -0
  27. package/dist/cli/index.js +3 -0
  28. package/dist/cli/serve.js +4 -1
  29. package/dist/cli/setup.js +34 -3
  30. package/dist/config/ignore-service.js +8 -3
  31. package/dist/core/augmentation/engine.js +1 -1
  32. package/dist/core/git-staleness.d.ts +13 -0
  33. package/dist/core/git-staleness.js +29 -0
  34. package/dist/core/group/bridge-db.d.ts +82 -0
  35. package/dist/core/group/bridge-db.js +460 -0
  36. package/dist/core/group/bridge-schema.d.ts +27 -0
  37. package/dist/core/group/bridge-schema.js +55 -0
  38. package/dist/core/group/config-parser.d.ts +3 -0
  39. package/dist/core/group/config-parser.js +83 -0
  40. package/dist/core/group/contract-extractor.d.ts +7 -0
  41. package/dist/core/group/contract-extractor.js +1 -0
  42. package/dist/core/group/extractors/fs-utils.d.ts +10 -0
  43. package/dist/core/group/extractors/fs-utils.js +24 -0
  44. package/dist/core/group/extractors/grpc-extractor.d.ts +25 -0
  45. package/dist/core/group/extractors/grpc-extractor.js +386 -0
  46. package/dist/core/group/extractors/grpc-patterns/go.d.ts +2 -0
  47. package/dist/core/group/extractors/grpc-patterns/go.js +97 -0
  48. package/dist/core/group/extractors/grpc-patterns/index.d.ts +19 -0
  49. package/dist/core/group/extractors/grpc-patterns/index.js +46 -0
  50. package/dist/core/group/extractors/grpc-patterns/java.d.ts +2 -0
  51. package/dist/core/group/extractors/grpc-patterns/java.js +173 -0
  52. package/dist/core/group/extractors/grpc-patterns/node.d.ts +4 -0
  53. package/dist/core/group/extractors/grpc-patterns/node.js +290 -0
  54. package/dist/core/group/extractors/grpc-patterns/proto.d.ts +9 -0
  55. package/dist/core/group/extractors/grpc-patterns/proto.js +134 -0
  56. package/dist/core/group/extractors/grpc-patterns/python.d.ts +2 -0
  57. package/dist/core/group/extractors/grpc-patterns/python.js +67 -0
  58. package/dist/core/group/extractors/grpc-patterns/types.d.ts +50 -0
  59. package/dist/core/group/extractors/grpc-patterns/types.js +1 -0
  60. package/dist/core/group/extractors/http-patterns/go.d.ts +2 -0
  61. package/dist/core/group/extractors/http-patterns/go.js +215 -0
  62. package/dist/core/group/extractors/http-patterns/index.d.ts +17 -0
  63. package/dist/core/group/extractors/http-patterns/index.js +44 -0
  64. package/dist/core/group/extractors/http-patterns/java.d.ts +2 -0
  65. package/dist/core/group/extractors/http-patterns/java.js +253 -0
  66. package/dist/core/group/extractors/http-patterns/node.d.ts +4 -0
  67. package/dist/core/group/extractors/http-patterns/node.js +354 -0
  68. package/dist/core/group/extractors/http-patterns/php.d.ts +2 -0
  69. package/dist/core/group/extractors/http-patterns/php.js +70 -0
  70. package/dist/core/group/extractors/http-patterns/python.d.ts +2 -0
  71. package/dist/core/group/extractors/http-patterns/python.js +133 -0
  72. package/dist/core/group/extractors/http-patterns/types.d.ts +61 -0
  73. package/dist/core/group/extractors/http-patterns/types.js +1 -0
  74. package/dist/core/group/extractors/http-route-extractor.d.ts +21 -0
  75. package/dist/core/group/extractors/http-route-extractor.js +391 -0
  76. package/dist/core/group/extractors/manifest-extractor.d.ts +54 -0
  77. package/dist/core/group/extractors/manifest-extractor.js +235 -0
  78. package/dist/core/group/extractors/topic-extractor.d.ts +8 -0
  79. package/dist/core/group/extractors/topic-extractor.js +97 -0
  80. package/dist/core/group/extractors/topic-patterns/go.d.ts +2 -0
  81. package/dist/core/group/extractors/topic-patterns/go.js +120 -0
  82. package/dist/core/group/extractors/topic-patterns/index.d.ts +14 -0
  83. package/dist/core/group/extractors/topic-patterns/index.js +38 -0
  84. package/dist/core/group/extractors/topic-patterns/java.d.ts +2 -0
  85. package/dist/core/group/extractors/topic-patterns/java.js +80 -0
  86. package/dist/core/group/extractors/topic-patterns/node.d.ts +4 -0
  87. package/dist/core/group/extractors/topic-patterns/node.js +155 -0
  88. package/dist/core/group/extractors/topic-patterns/python.d.ts +2 -0
  89. package/dist/core/group/extractors/topic-patterns/python.js +116 -0
  90. package/dist/core/group/extractors/topic-patterns/types.d.ts +25 -0
  91. package/dist/core/group/extractors/topic-patterns/types.js +10 -0
  92. package/dist/core/group/extractors/tree-sitter-scanner.d.ts +113 -0
  93. package/dist/core/group/extractors/tree-sitter-scanner.js +94 -0
  94. package/dist/core/group/matching.d.ts +13 -0
  95. package/dist/core/group/matching.js +198 -0
  96. package/dist/core/group/normalization.d.ts +3 -0
  97. package/dist/core/group/normalization.js +115 -0
  98. package/dist/core/group/service-boundary-detector.d.ts +8 -0
  99. package/dist/core/group/service-boundary-detector.js +155 -0
  100. package/dist/core/group/service.d.ts +46 -0
  101. package/dist/core/group/service.js +160 -0
  102. package/dist/core/group/storage.d.ts +9 -0
  103. package/dist/core/group/storage.js +91 -0
  104. package/dist/core/group/sync.d.ts +21 -0
  105. package/dist/core/group/sync.js +148 -0
  106. package/dist/core/group/types.d.ts +130 -0
  107. package/dist/core/group/types.js +1 -0
  108. package/dist/core/ingestion/binding-accumulator.d.ts +212 -0
  109. package/dist/core/ingestion/binding-accumulator.js +336 -0
  110. package/dist/core/ingestion/call-processor.d.ts +155 -24
  111. package/dist/core/ingestion/call-processor.js +1129 -247
  112. package/dist/core/ingestion/class-extractors/generic.d.ts +2 -0
  113. package/dist/core/ingestion/class-extractors/generic.js +135 -0
  114. package/dist/core/ingestion/class-types.d.ts +34 -0
  115. package/dist/core/ingestion/class-types.js +1 -0
  116. package/dist/core/ingestion/cobol-processor.d.ts +1 -1
  117. package/dist/core/ingestion/entry-point-scoring.d.ts +1 -0
  118. package/dist/core/ingestion/entry-point-scoring.js +1 -0
  119. package/dist/core/ingestion/field-types.d.ts +2 -2
  120. package/dist/core/ingestion/filesystem-walker.js +8 -0
  121. package/dist/core/ingestion/framework-detection.d.ts +1 -0
  122. package/dist/core/ingestion/framework-detection.js +1 -0
  123. package/dist/core/ingestion/heritage-processor.d.ts +8 -15
  124. package/dist/core/ingestion/heritage-processor.js +15 -28
  125. package/dist/core/ingestion/import-processor.d.ts +1 -11
  126. package/dist/core/ingestion/import-processor.js +1 -13
  127. package/dist/core/ingestion/import-resolvers/utils.js +1 -0
  128. package/dist/core/ingestion/import-resolvers/vue.d.ts +8 -0
  129. package/dist/core/ingestion/import-resolvers/vue.js +9 -0
  130. package/dist/core/ingestion/language-config.js +1 -1
  131. package/dist/core/ingestion/language-provider.d.ts +14 -3
  132. package/dist/core/ingestion/languages/c-cpp.js +168 -1
  133. package/dist/core/ingestion/languages/csharp.js +20 -0
  134. package/dist/core/ingestion/languages/dart.js +26 -4
  135. package/dist/core/ingestion/languages/go.js +22 -0
  136. package/dist/core/ingestion/languages/index.d.ts +1 -0
  137. package/dist/core/ingestion/languages/index.js +2 -0
  138. package/dist/core/ingestion/languages/java.js +17 -0
  139. package/dist/core/ingestion/languages/kotlin.js +24 -1
  140. package/dist/core/ingestion/languages/php.js +23 -11
  141. package/dist/core/ingestion/languages/python.js +9 -0
  142. package/dist/core/ingestion/languages/ruby.js +43 -0
  143. package/dist/core/ingestion/languages/rust.js +38 -0
  144. package/dist/core/ingestion/languages/swift.js +31 -0
  145. package/dist/core/ingestion/languages/typescript.d.ts +1 -0
  146. package/dist/core/ingestion/languages/typescript.js +52 -3
  147. package/dist/core/ingestion/languages/vue.d.ts +13 -0
  148. package/dist/core/ingestion/languages/vue.js +81 -0
  149. package/dist/core/ingestion/markdown-processor.d.ts +1 -1
  150. package/dist/core/ingestion/method-extractors/configs/c-cpp.d.ts +3 -0
  151. package/dist/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
  152. package/dist/core/ingestion/method-extractors/configs/csharp.js +5 -1
  153. package/dist/core/ingestion/method-extractors/configs/dart.d.ts +2 -0
  154. package/dist/core/ingestion/method-extractors/configs/dart.js +376 -0
  155. package/dist/core/ingestion/method-extractors/configs/go.d.ts +2 -0
  156. package/dist/core/ingestion/method-extractors/configs/go.js +176 -0
  157. package/dist/core/ingestion/method-extractors/configs/jvm.js +14 -4
  158. package/dist/core/ingestion/method-extractors/configs/php.d.ts +2 -0
  159. package/dist/core/ingestion/method-extractors/configs/php.js +304 -0
  160. package/dist/core/ingestion/method-extractors/configs/python.d.ts +2 -0
  161. package/dist/core/ingestion/method-extractors/configs/python.js +309 -0
  162. package/dist/core/ingestion/method-extractors/configs/ruby.d.ts +2 -0
  163. package/dist/core/ingestion/method-extractors/configs/ruby.js +286 -0
  164. package/dist/core/ingestion/method-extractors/configs/rust.d.ts +2 -0
  165. package/dist/core/ingestion/method-extractors/configs/rust.js +195 -0
  166. package/dist/core/ingestion/method-extractors/configs/swift.d.ts +2 -0
  167. package/dist/core/ingestion/method-extractors/configs/swift.js +277 -0
  168. package/dist/core/ingestion/method-extractors/configs/typescript-javascript.js +85 -8
  169. package/dist/core/ingestion/method-extractors/generic.d.ts +6 -0
  170. package/dist/core/ingestion/method-extractors/generic.js +84 -17
  171. package/dist/core/ingestion/method-types.d.ts +29 -0
  172. package/dist/core/ingestion/model/field-registry.d.ts +18 -0
  173. package/dist/core/ingestion/model/field-registry.js +22 -0
  174. package/dist/core/ingestion/model/heritage-map.d.ts +70 -0
  175. package/dist/core/ingestion/model/heritage-map.js +159 -0
  176. package/dist/core/ingestion/model/index.d.ts +20 -0
  177. package/dist/core/ingestion/model/index.js +41 -0
  178. package/dist/core/ingestion/model/method-registry.d.ts +62 -0
  179. package/dist/core/ingestion/model/method-registry.js +130 -0
  180. package/dist/core/ingestion/model/registration-table.d.ts +139 -0
  181. package/dist/core/ingestion/model/registration-table.js +224 -0
  182. package/dist/core/ingestion/model/resolution-context.d.ts +93 -0
  183. package/dist/core/ingestion/model/resolution-context.js +337 -0
  184. package/dist/core/ingestion/model/resolve.d.ts +56 -0
  185. package/dist/core/ingestion/model/resolve.js +297 -0
  186. package/dist/core/ingestion/model/semantic-model.d.ts +86 -0
  187. package/dist/core/ingestion/model/semantic-model.js +120 -0
  188. package/dist/core/ingestion/model/symbol-table.d.ts +222 -0
  189. package/dist/core/ingestion/model/symbol-table.js +206 -0
  190. package/dist/core/ingestion/model/type-registry.d.ts +39 -0
  191. package/dist/core/ingestion/model/type-registry.js +62 -0
  192. package/dist/core/ingestion/mro-processor.d.ts +5 -4
  193. package/dist/core/ingestion/mro-processor.js +311 -107
  194. package/dist/core/ingestion/parsing-processor.d.ts +5 -4
  195. package/dist/core/ingestion/parsing-processor.js +224 -87
  196. package/dist/core/ingestion/pipeline-phases/cobol.d.ts +16 -0
  197. package/dist/core/ingestion/pipeline-phases/cobol.js +45 -0
  198. package/dist/core/ingestion/pipeline-phases/communities.d.ts +16 -0
  199. package/dist/core/ingestion/pipeline-phases/communities.js +62 -0
  200. package/dist/core/ingestion/pipeline-phases/cross-file-impl.d.ts +17 -0
  201. package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +156 -0
  202. package/dist/core/ingestion/pipeline-phases/cross-file.d.ts +37 -0
  203. package/dist/core/ingestion/pipeline-phases/cross-file.js +63 -0
  204. package/dist/core/ingestion/pipeline-phases/index.d.ts +21 -0
  205. package/dist/core/ingestion/pipeline-phases/index.js +22 -0
  206. package/dist/core/ingestion/pipeline-phases/markdown.d.ts +17 -0
  207. package/dist/core/ingestion/pipeline-phases/markdown.js +33 -0
  208. package/dist/core/ingestion/pipeline-phases/mro.d.ts +18 -0
  209. package/dist/core/ingestion/pipeline-phases/mro.js +36 -0
  210. package/dist/core/ingestion/pipeline-phases/orm-extraction.d.ts +22 -0
  211. package/dist/core/ingestion/pipeline-phases/orm-extraction.js +92 -0
  212. package/dist/core/ingestion/pipeline-phases/orm.d.ts +15 -0
  213. package/dist/core/ingestion/pipeline-phases/orm.js +74 -0
  214. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +47 -0
  215. package/dist/core/ingestion/pipeline-phases/parse-impl.js +437 -0
  216. package/dist/core/ingestion/pipeline-phases/parse.d.ts +49 -0
  217. package/dist/core/ingestion/pipeline-phases/parse.js +33 -0
  218. package/dist/core/ingestion/pipeline-phases/processes.d.ts +16 -0
  219. package/dist/core/ingestion/pipeline-phases/processes.js +143 -0
  220. package/dist/core/ingestion/pipeline-phases/routes.d.ts +21 -0
  221. package/dist/core/ingestion/pipeline-phases/routes.js +243 -0
  222. package/dist/core/ingestion/pipeline-phases/runner.d.ts +22 -0
  223. package/dist/core/ingestion/pipeline-phases/runner.js +203 -0
  224. package/dist/core/ingestion/pipeline-phases/scan.d.ts +21 -0
  225. package/dist/core/ingestion/pipeline-phases/scan.js +46 -0
  226. package/dist/core/ingestion/pipeline-phases/structure.d.ts +27 -0
  227. package/dist/core/ingestion/pipeline-phases/structure.js +35 -0
  228. package/dist/core/ingestion/pipeline-phases/tools.d.ts +20 -0
  229. package/dist/core/ingestion/pipeline-phases/tools.js +79 -0
  230. package/dist/core/ingestion/pipeline-phases/types.d.ts +79 -0
  231. package/dist/core/ingestion/pipeline-phases/types.js +37 -0
  232. package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.d.ts +35 -0
  233. package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.js +174 -0
  234. package/dist/core/ingestion/pipeline.d.ts +18 -10
  235. package/dist/core/ingestion/pipeline.js +66 -1410
  236. package/dist/core/ingestion/process-processor.js +1 -1
  237. package/dist/core/ingestion/tree-sitter-queries.d.ts +5 -5
  238. package/dist/core/ingestion/tree-sitter-queries.js +90 -0
  239. package/dist/core/ingestion/type-env.d.ts +15 -2
  240. package/dist/core/ingestion/type-env.js +163 -102
  241. package/dist/core/ingestion/type-extractors/csharp.js +17 -0
  242. package/dist/core/ingestion/type-extractors/jvm.js +11 -0
  243. package/dist/core/ingestion/type-extractors/php.js +0 -55
  244. package/dist/core/ingestion/type-extractors/ruby.js +0 -32
  245. package/dist/core/ingestion/type-extractors/swift.js +13 -0
  246. package/dist/core/ingestion/type-extractors/types.d.ts +8 -8
  247. package/dist/core/ingestion/type-extractors/typescript.js +66 -69
  248. package/dist/core/ingestion/utils/ast-helpers.d.ts +32 -44
  249. package/dist/core/ingestion/utils/ast-helpers.js +157 -573
  250. package/dist/core/ingestion/utils/env.d.ts +10 -0
  251. package/dist/core/ingestion/utils/env.js +10 -0
  252. package/dist/core/ingestion/utils/graph-sort.d.ts +58 -0
  253. package/dist/core/ingestion/utils/graph-sort.js +100 -0
  254. package/dist/core/ingestion/utils/method-props.d.ts +32 -0
  255. package/dist/core/ingestion/utils/method-props.js +147 -0
  256. package/dist/core/ingestion/vue-sfc-extractor.d.ts +44 -0
  257. package/dist/core/ingestion/vue-sfc-extractor.js +94 -0
  258. package/dist/core/ingestion/workers/parse-worker.d.ts +31 -19
  259. package/dist/core/ingestion/workers/parse-worker.js +469 -200
  260. package/dist/core/lbug/lbug-adapter.d.ts +6 -0
  261. package/dist/core/lbug/lbug-adapter.js +134 -27
  262. package/dist/core/lbug/pool-adapter.d.ts +76 -0
  263. package/dist/core/lbug/pool-adapter.js +522 -0
  264. package/dist/core/run-analyze.d.ts +2 -0
  265. package/dist/core/run-analyze.js +1 -1
  266. package/dist/core/search/bm25-index.js +1 -1
  267. package/dist/core/tree-sitter/parser-loader.js +1 -0
  268. package/dist/core/wiki/graph-queries.js +1 -1
  269. package/dist/mcp/core/embedder.js +6 -5
  270. package/dist/mcp/core/lbug-adapter.d.ts +3 -63
  271. package/dist/mcp/core/lbug-adapter.js +3 -484
  272. package/dist/mcp/local/local-backend.d.ts +31 -2
  273. package/dist/mcp/local/local-backend.js +255 -46
  274. package/dist/mcp/resources.js +5 -4
  275. package/dist/mcp/staleness.d.ts +3 -13
  276. package/dist/mcp/staleness.js +2 -31
  277. package/dist/mcp/tools.js +80 -4
  278. package/dist/server/analyze-job.d.ts +2 -0
  279. package/dist/server/analyze-job.js +4 -0
  280. package/dist/server/api.d.ts +20 -1
  281. package/dist/server/api.js +306 -71
  282. package/dist/server/git-clone.d.ts +2 -1
  283. package/dist/server/git-clone.js +98 -5
  284. package/dist/storage/git.d.ts +13 -0
  285. package/dist/storage/git.js +25 -0
  286. package/dist/storage/repo-manager.js +1 -1
  287. package/package.json +9 -3
  288. package/scripts/patch-tree-sitter-swift.cjs +78 -0
  289. package/vendor/tree-sitter-proto/binding.gyp +30 -0
  290. package/vendor/tree-sitter-proto/bindings/node/binding.cc +20 -0
  291. package/vendor/tree-sitter-proto/bindings/node/index.d.ts +28 -0
  292. package/vendor/tree-sitter-proto/bindings/node/index.js +7 -0
  293. package/vendor/tree-sitter-proto/package.json +18 -0
  294. package/vendor/tree-sitter-proto/src/node-types.json +1145 -0
  295. package/vendor/tree-sitter-proto/src/parser.c +10149 -0
  296. package/vendor/tree-sitter-proto/src/tree_sitter/alloc.h +54 -0
  297. package/vendor/tree-sitter-proto/src/tree_sitter/array.h +291 -0
  298. package/vendor/tree-sitter-proto/src/tree_sitter/parser.h +266 -0
  299. package/dist/core/ingestion/named-binding-processor.d.ts +0 -18
  300. package/dist/core/ingestion/named-binding-processor.js +0 -42
  301. package/dist/core/ingestion/resolution-context.d.ts +0 -58
  302. package/dist/core/ingestion/resolution-context.js +0 -135
  303. package/dist/core/ingestion/symbol-table.d.ts +0 -79
  304. package/dist/core/ingestion/symbol-table.js +0 -115
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Field Registry
3
+ *
4
+ * Owner-scoped field/property index extracted from SymbolTable.
5
+ * Stores Property symbols keyed by `ownerNodeId\0fieldName` for O(1) lookup.
6
+ */
7
+ import type { SymbolDefinition } from './symbol-table.js';
8
+ export interface FieldRegistry {
9
+ /** Look up a field/property by its owning class nodeId and field name. */
10
+ lookupFieldByOwner(ownerNodeId: string, fieldName: string): SymbolDefinition | undefined;
11
+ }
12
+ export interface MutableFieldRegistry extends FieldRegistry {
13
+ /** Register a field/property under its owner. */
14
+ register(ownerNodeId: string, fieldName: string, def: SymbolDefinition): void;
15
+ /** Clear all entries. */
16
+ clear(): void;
17
+ }
18
+ export declare const createFieldRegistry: () => MutableFieldRegistry;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Field Registry
3
+ *
4
+ * Owner-scoped field/property index extracted from SymbolTable.
5
+ * Stores Property symbols keyed by `ownerNodeId\0fieldName` for O(1) lookup.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Factory
9
+ // ---------------------------------------------------------------------------
10
+ export const createFieldRegistry = () => {
11
+ const fieldByOwner = new Map();
12
+ const lookupFieldByOwner = (ownerNodeId, fieldName) => {
13
+ return fieldByOwner.get(`${ownerNodeId}\0${fieldName}`);
14
+ };
15
+ const register = (ownerNodeId, fieldName, def) => {
16
+ fieldByOwner.set(`${ownerNodeId}\0${fieldName}`, def);
17
+ };
18
+ const clear = () => {
19
+ fieldByOwner.clear();
20
+ };
21
+ return { lookupFieldByOwner, register, clear };
22
+ };
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Heritage Map
3
+ *
4
+ * Unified inheritance data structure built from accumulated
5
+ * {@link ExtractedHeritage} records **after all chunks complete** (between
6
+ * chunk processing and call resolution). Consumes `ExtractedHeritage[]` and
7
+ * resolves type names to nodeIds via `lookupClassByName`, NOT graph-edge
8
+ * queries.
9
+ *
10
+ * Combines two concerns:
11
+ * 1. **Parent/ancestor lookup** (MRO-aware method resolution)
12
+ * 2. **Implementor lookup** (interface dispatch — which files contain
13
+ * classes implementing a given interface)
14
+ */
15
+ import type { ResolutionContext } from './resolution-context.js';
16
+ import { type SupportedLanguages } from '../../../_shared/index.js';
17
+ export interface ExtractedHeritage {
18
+ filePath: string;
19
+ className: string;
20
+ parentName: string;
21
+ /** 'extends' | 'implements' | 'trait-impl' | 'include' | 'extend' | 'prepend' */
22
+ kind: string;
23
+ }
24
+ export interface HeritageResolutionStrategy {
25
+ /** If set and the parent name matches, force IMPLEMENTS even when the
26
+ * symbol is unresolved (e.g. `/^I[A-Z]/` for C# / Java). */
27
+ readonly interfaceNamePattern?: RegExp;
28
+ /** Fallback edge for unresolved parents when the name pattern doesn't
29
+ * match (Swift uses 'IMPLEMENTS' for protocol conformance). */
30
+ readonly defaultEdge: 'EXTENDS' | 'IMPLEMENTS';
31
+ }
32
+ /** Callback used by `buildHeritageMap` to look up the resolution strategy
33
+ * for a given language. Injected by callers so the model module doesn't
34
+ * depend on `../languages/index.js`. */
35
+ export type HeritageStrategyLookup = (lang: SupportedLanguages) => HeritageResolutionStrategy;
36
+ /**
37
+ * Determine whether a heritage.extends capture is actually an IMPLEMENTS
38
+ * relationship. Consults the symbol table first (authoritative — Tier 1 /
39
+ * Tier 2 resolution); falls back to the injected {@link HeritageResolutionStrategy}
40
+ * heuristics for external symbols not present in the graph.
41
+ */
42
+ export declare const resolveExtendsType: (parentName: string, currentFilePath: string, ctx: ResolutionContext, strategy: HeritageResolutionStrategy) => {
43
+ type: "EXTENDS" | "IMPLEMENTS";
44
+ idPrefix: string;
45
+ };
46
+ export interface HeritageMap {
47
+ /** Direct parents of `childNodeId` (extends + implements + trait-impl). */
48
+ getParents(childNodeId: string): string[];
49
+ /** Full ancestor chain (BFS, bounded depth, cycle-safe). */
50
+ getAncestors(childNodeId: string): string[];
51
+ /**
52
+ * File paths of classes that directly implement or extend-as-interface the
53
+ * given interface/abstract-class **name**. Replaces the standalone
54
+ * `ImplementorMap` — used by interface-dispatch in call resolution.
55
+ */
56
+ getImplementorFiles(interfaceName: string): ReadonlySet<string>;
57
+ }
58
+ /**
59
+ * Build a HeritageMap from accumulated ExtractedHeritage records.
60
+ *
61
+ * Resolves class/interface/struct/trait names to nodeIds via
62
+ * `ctx.model.types.lookupClassByName`. When a name resolves to multiple
63
+ * candidates, all are recorded (partial-class / cross-file scenario).
64
+ * Unresolvable names are silently skipped — a missing parent is better
65
+ * than a wrong edge.
66
+ *
67
+ * Also builds the implementor index (interface name → implementing file
68
+ * paths) used by interface-dispatch in call resolution.
69
+ */
70
+ export declare const buildHeritageMap: (heritage: readonly ExtractedHeritage[], ctx: ResolutionContext, getHeritageStrategy?: HeritageStrategyLookup) => HeritageMap;
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Heritage Map
3
+ *
4
+ * Unified inheritance data structure built from accumulated
5
+ * {@link ExtractedHeritage} records **after all chunks complete** (between
6
+ * chunk processing and call resolution). Consumes `ExtractedHeritage[]` and
7
+ * resolves type names to nodeIds via `lookupClassByName`, NOT graph-edge
8
+ * queries.
9
+ *
10
+ * Combines two concerns:
11
+ * 1. **Parent/ancestor lookup** (MRO-aware method resolution)
12
+ * 2. **Implementor lookup** (interface dispatch — which files contain
13
+ * classes implementing a given interface)
14
+ */
15
+ import { getLanguageFromFilename } from '../../../_shared/index.js';
16
+ /**
17
+ * Determine whether a heritage.extends capture is actually an IMPLEMENTS
18
+ * relationship. Consults the symbol table first (authoritative — Tier 1 /
19
+ * Tier 2 resolution); falls back to the injected {@link HeritageResolutionStrategy}
20
+ * heuristics for external symbols not present in the graph.
21
+ */
22
+ export const resolveExtendsType = (parentName, currentFilePath, ctx, strategy) => {
23
+ const resolved = ctx.resolve(parentName, currentFilePath);
24
+ if (resolved && resolved.candidates.length > 0) {
25
+ const isInterface = resolved.candidates[0].type === 'Interface';
26
+ return isInterface
27
+ ? { type: 'IMPLEMENTS', idPrefix: 'Interface' }
28
+ : { type: 'EXTENDS', idPrefix: 'Class' };
29
+ }
30
+ // Unresolved symbol — fall back to strategy heuristics.
31
+ if (strategy.interfaceNamePattern?.test(parentName)) {
32
+ return { type: 'IMPLEMENTS', idPrefix: 'Interface' };
33
+ }
34
+ if (strategy.defaultEdge === 'IMPLEMENTS') {
35
+ return { type: 'IMPLEMENTS', idPrefix: 'Interface' };
36
+ }
37
+ return { type: 'EXTENDS', idPrefix: 'Class' };
38
+ };
39
+ // ---------------------------------------------------------------------------
40
+ // Public types
41
+ // ---------------------------------------------------------------------------
42
+ /** Maximum ancestor chain depth to prevent runaway traversal. */
43
+ const MAX_ANCESTOR_DEPTH = 32;
44
+ /** Shared empty set returned when no implementors are found. */
45
+ const EMPTY_SET = new Set();
46
+ /** Default strategy used when `buildHeritageMap` is called without an
47
+ * explicit `getHeritageStrategy` callback — the fallback for a language
48
+ * whose provider sets no interface-name pattern and no non-default
49
+ * `heritageDefaultEdge`. */
50
+ const DEFAULT_HERITAGE_STRATEGY = { defaultEdge: 'EXTENDS' };
51
+ // ---------------------------------------------------------------------------
52
+ // Builder
53
+ // ---------------------------------------------------------------------------
54
+ /**
55
+ * Build a HeritageMap from accumulated ExtractedHeritage records.
56
+ *
57
+ * Resolves class/interface/struct/trait names to nodeIds via
58
+ * `ctx.model.types.lookupClassByName`. When a name resolves to multiple
59
+ * candidates, all are recorded (partial-class / cross-file scenario).
60
+ * Unresolvable names are silently skipped — a missing parent is better
61
+ * than a wrong edge.
62
+ *
63
+ * Also builds the implementor index (interface name → implementing file
64
+ * paths) used by interface-dispatch in call resolution.
65
+ */
66
+ export const buildHeritageMap = (heritage, ctx, getHeritageStrategy) => {
67
+ // childNodeId → Set<parentNodeId> (Set to deduplicate cross-chunk duplicates)
68
+ const directParents = new Map();
69
+ // interfaceName → Set<filePath> (implementor lookup for interface dispatch)
70
+ const implementorFiles = new Map();
71
+ for (const h of heritage) {
72
+ // ── Parent lookup (nodeId-based) ────────────────────────────────
73
+ const childDefs = ctx.model.types.lookupClassByName(h.className);
74
+ const parentDefs = ctx.model.types.lookupClassByName(h.parentName);
75
+ if (childDefs.length > 0 && parentDefs.length > 0) {
76
+ for (const child of childDefs) {
77
+ for (const parent of parentDefs) {
78
+ // Skip self-references
79
+ if (child.nodeId === parent.nodeId)
80
+ continue;
81
+ let parents = directParents.get(child.nodeId);
82
+ if (!parents) {
83
+ parents = new Set();
84
+ directParents.set(child.nodeId, parents);
85
+ }
86
+ parents.add(parent.nodeId);
87
+ }
88
+ }
89
+ }
90
+ // ── Implementor index (name-based) ──────────────────────────────
91
+ //
92
+ // Known limitation: Rust `kind: 'trait-impl'` entries are intentionally NOT
93
+ // added to the implementor index. Interface dispatch resolution currently
94
+ // does not traverse Rust trait objects, so recording them here would
95
+ // inflate the index without a consumer. Revisit if/when trait-object
96
+ // dispatch is added.
97
+ //
98
+ // Known limitation: `getImplementorFiles` is keyed by interface **name**
99
+ // (string), so two interfaces with the same unqualified name in different
100
+ // packages (e.g. `pkgA.IRepository` vs `pkgB.IRepository`) collide.
101
+ let isImpl = false;
102
+ if (h.kind === 'implements') {
103
+ isImpl = true;
104
+ }
105
+ else if (h.kind === 'extends') {
106
+ const lang = getLanguageFromFilename(h.filePath);
107
+ if (lang) {
108
+ const strategy = getHeritageStrategy?.(lang) ?? DEFAULT_HERITAGE_STRATEGY;
109
+ const { type } = resolveExtendsType(h.parentName, h.filePath, ctx, strategy);
110
+ isImpl = type === 'IMPLEMENTS';
111
+ }
112
+ }
113
+ if (isImpl) {
114
+ let files = implementorFiles.get(h.parentName);
115
+ if (!files) {
116
+ files = new Set();
117
+ implementorFiles.set(h.parentName, files);
118
+ }
119
+ files.add(h.filePath);
120
+ }
121
+ }
122
+ // --- Public API ---------------------------------------------------
123
+ const getParents = (childNodeId) => {
124
+ const parents = directParents.get(childNodeId);
125
+ return parents ? [...parents] : [];
126
+ };
127
+ const getAncestors = (childNodeId) => {
128
+ const result = [];
129
+ const visited = new Set();
130
+ visited.add(childNodeId); // prevent cycles through the start node
131
+ // BFS with bounded depth
132
+ let frontier = getParents(childNodeId);
133
+ let depth = 0;
134
+ while (frontier.length > 0 && depth < MAX_ANCESTOR_DEPTH) {
135
+ const nextFrontier = [];
136
+ for (const parentId of frontier) {
137
+ if (visited.has(parentId))
138
+ continue;
139
+ visited.add(parentId);
140
+ result.push(parentId);
141
+ // Expand parent's own parents for next level
142
+ const grandparents = directParents.get(parentId);
143
+ if (grandparents) {
144
+ for (const gp of grandparents) {
145
+ if (!visited.has(gp))
146
+ nextFrontier.push(gp);
147
+ }
148
+ }
149
+ }
150
+ frontier = nextFrontier;
151
+ depth++;
152
+ }
153
+ return result;
154
+ };
155
+ const getImplementorFiles = (interfaceName) => {
156
+ return implementorFiles.get(interfaceName) ?? EMPTY_SET;
157
+ };
158
+ return { getParents, getAncestors, getImplementorFiles };
159
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Semantic Model — public module surface.
3
+ *
4
+ * Barrel re-export for the `model/` module. Consumers outside `model/`
5
+ * should import from this file rather than reaching into individual
6
+ * registry files.
7
+ *
8
+ * The model is owner-scoped type/method/field knowledge layered above
9
+ * `SymbolTable`. File-indexed and name-keyed callable lookups stay in
10
+ * `SymbolTable` by design.
11
+ */
12
+ export { type SemanticModel, type MutableSemanticModel, createSemanticModel, } from './semantic-model.js';
13
+ export { type SymbolTableReader, type SymbolTableWriter, createSymbolTable, } from './symbol-table.js';
14
+ export { type TypeRegistry, type MutableTypeRegistry, createTypeRegistry, } from './type-registry.js';
15
+ export { type MethodRegistry, type MutableMethodRegistry, createMethodRegistry, } from './method-registry.js';
16
+ export { type FieldRegistry, type MutableFieldRegistry, createFieldRegistry, } from './field-registry.js';
17
+ export { lookupMethodByOwnerWithMRO } from './resolve.js';
18
+ export { type NamedImportBinding, type NamedImportMap, isFileInPackageDir, } from './resolution-context.js';
19
+ export { type ExtractedHeritage, type HeritageResolutionStrategy, type HeritageStrategyLookup, } from './heritage-map.js';
20
+ export { CALLABLE_ONLY_LABELS, INERT_LABELS, DISPATCH_LABELS, ALL_NODE_LABELS, type LabelBehavior, } from './registration-table.js';
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Semantic Model — public module surface.
3
+ *
4
+ * Barrel re-export for the `model/` module. Consumers outside `model/`
5
+ * should import from this file rather than reaching into individual
6
+ * registry files.
7
+ *
8
+ * The model is owner-scoped type/method/field knowledge layered above
9
+ * `SymbolTable`. File-indexed and name-keyed callable lookups stay in
10
+ * `SymbolTable` by design.
11
+ */
12
+ // Unified semantic model (factory + interfaces). SemanticModel is the
13
+ // top-level container and owns the file/callable SymbolTable as a
14
+ // nested `symbols` field.
15
+ export { createSemanticModel, } from './semantic-model.js';
16
+ // SymbolTable is exclusively owned by SemanticModel. Re-exported here
17
+ // for the rare caller that needs the file/callable interface in
18
+ // isolation (e.g. tests).
19
+ export { createSymbolTable, } from './symbol-table.js';
20
+ // Type registry (classes, structs, interfaces, enums, records, impls)
21
+ export { createTypeRegistry, } from './type-registry.js';
22
+ // Method registry (owner-scoped methods with arity-aware overload lookup)
23
+ export { createMethodRegistry, } from './method-registry.js';
24
+ // Field registry (owner-scoped fields/properties)
25
+ export { createFieldRegistry, } from './field-registry.js';
26
+ // MRO-aware method resolution (C3, first-wins, leftmost-base, implements-split,
27
+ // qualified-syntax). Pure function that depends only on the model + HeritageMap.
28
+ // `MroStrategy` itself lives in `gitnexus-shared`; re-exported here for
29
+ // consumers that reach model behavior through the barrel.
30
+ export { lookupMethodByOwnerWithMRO } from './resolve.js';
31
+ // Named-import types and package-dir helper. Re-exported so barrel
32
+ // consumers don't need to reach into a specific model file.
33
+ export { isFileInPackageDir, } from './resolution-context.js';
34
+ // Behavior-grouped dispatch table for SymbolTable.add() routing.
35
+ // See registration-table.ts module JSDoc for the behavior group taxonomy
36
+ // and "how to add a new NodeLabel" checklist.
37
+ // NOTE: createRegistrationTable, RegistrationHook, and RegistrationTableDeps
38
+ // are deliberately NOT re-exported here — they are factory internals of
39
+ // SemanticModel and should only be imported directly from registration-table.js
40
+ // by semantic-model.ts and the registration-table.test.ts file.
41
+ export { CALLABLE_ONLY_LABELS, INERT_LABELS, DISPATCH_LABELS, ALL_NODE_LABELS, } from './registration-table.js';
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Method Registry
3
+ *
4
+ * Owner-scoped method index extracted from SymbolTable.
5
+ * Stores Method/Constructor/Function-with-ownerId symbols keyed by
6
+ * `ownerNodeId\0methodName` for O(1) lookup. Supports overloads
7
+ * (array values) and arity-based filtering.
8
+ */
9
+ import type { SymbolDefinition } from './symbol-table.js';
10
+ export interface MethodRegistry {
11
+ /**
12
+ * Look up a method by owner class + name, optionally filtered by arity.
13
+ *
14
+ * When `argCount` is provided, overloads whose parameter count doesn't
15
+ * accommodate the call's argument count are filtered out before the
16
+ * returnType dedup runs. This lets D0 (`resolveMemberCall`) disambiguate
17
+ * arity-differing overloads (e.g. C++ `greet()` vs `greet(string)`) that
18
+ * would otherwise collide on the shared `ownerId + methodName` key.
19
+ *
20
+ * Same-arity, same-returnType overloads (e.g. `save(int)` vs `save(String)`,
21
+ * both returning `void`) still collapse to the first match — callers must
22
+ * gate D0 on overload concern before invoking this function for that case.
23
+ */
24
+ lookupMethodByOwner(ownerNodeId: string, methodName: string, argCount?: number): SymbolDefinition | undefined;
25
+ /**
26
+ * Flat-by-name lookup across all owners. Returns every method registered
27
+ * with the given unqualified name, in registration order, accumulated
28
+ * across owners and overloads.
29
+ *
30
+ * Required by Tier 3 global resolution: Method and Constructor do not
31
+ * land in `SymbolTable.callableByName`, so Tier 3 reaches them through
32
+ * this flat index instead. Returns `[]` on miss — never `undefined` —
33
+ * so callers can concatenate without null checks.
34
+ *
35
+ * Reference identity: each returned def is the same object reference
36
+ * stored under `lookupMethodByOwner`, so a method symbol occupies one
37
+ * allocation reachable from two indexes.
38
+ */
39
+ lookupMethodByName(name: string): readonly SymbolDefinition[];
40
+ /**
41
+ * True iff at least one registered def has `type === 'Function'` — i.e.,
42
+ * a Python/Rust/Kotlin class method emitted by the worker as
43
+ * `Function + ownerId` rather than as a strict `Method` label. Such defs
44
+ * are double-indexed: they land in `SymbolTable.callableByName` (via the
45
+ * Function callable-index gate) AND in this registry (via the
46
+ * dispatch-key normalization in `wrappedAdd`). Tier 3 resolution must
47
+ * then dedup the two indexes by nodeId.
48
+ *
49
+ * When this flag is false, the callable and method indexes are
50
+ * guaranteed disjoint and Tier 3 can skip the dedup pass entirely.
51
+ * The flag is monotonic (false→true once, never back) for the lifetime
52
+ * of the MethodRegistry.
53
+ */
54
+ readonly hasFunctionMethods: boolean;
55
+ }
56
+ export interface MutableMethodRegistry extends MethodRegistry {
57
+ /** Register a method under its owner. Supports multiple overloads. */
58
+ register(ownerNodeId: string, methodName: string, def: SymbolDefinition): void;
59
+ /** Clear all entries. */
60
+ clear(): void;
61
+ }
62
+ export declare const createMethodRegistry: () => MutableMethodRegistry;
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Method Registry
3
+ *
4
+ * Owner-scoped method index extracted from SymbolTable.
5
+ * Stores Method/Constructor/Function-with-ownerId symbols keyed by
6
+ * `ownerNodeId\0methodName` for O(1) lookup. Supports overloads
7
+ * (array values) and arity-based filtering.
8
+ */
9
+ // ---------------------------------------------------------------------------
10
+ // Factory
11
+ // ---------------------------------------------------------------------------
12
+ export const createMethodRegistry = () => {
13
+ const methodByOwner = new Map();
14
+ // Secondary flat-by-name index. Values are the SAME SymbolDefinition
15
+ // references stored under `methodByOwner` — no copy, just a second key.
16
+ // Populated in lockstep by `register()` and emptied by `clear()`.
17
+ const methodsByName = new Map();
18
+ const EMPTY = Object.freeze([]);
19
+ // Set once when a Function+ownerId def lands here, powers the Tier 3
20
+ // dedup fast-path. Monotonic: never unset except on `clear()`.
21
+ let hasFunctionMethodsFlag = false;
22
+ const lookupMethodByOwner = (ownerNodeId, methodName, argCount) => {
23
+ const defs = methodByOwner.get(`${ownerNodeId}\0${methodName}`);
24
+ if (!defs || defs.length === 0)
25
+ return undefined;
26
+ // Arity narrowing: when an argCount is provided and there are multiple
27
+ // overloads, keep only those whose parameterCount can accommodate the
28
+ // call. This resolves arity-differing overloads (e.g. C++ `greet()` vs
29
+ // `greet(string)`) that share the same `ownerId + methodName` key.
30
+ //
31
+ // Candidates with `parameterCount === undefined` (extractor didn't
32
+ // populate the count — typically variadic or unknown) are retained
33
+ // conservatively so that legitimate variadic matches still resolve.
34
+ //
35
+ // Streaming loop avoids allocating a filtered array on the common
36
+ // "arity selects 0 or 1 match" path. We scan once, count arity
37
+ // matches, and only materialize a narrowed array if at least one
38
+ // match was found and at least one non-match exists. If arity rules
39
+ // out every candidate, fall back to the unfiltered set so the
40
+ // caller's fuzzy path still has something to work with.
41
+ let pool = defs;
42
+ if (argCount !== undefined && defs.length > 1) {
43
+ let matchedCount = 0;
44
+ let rejectedCount = 0;
45
+ for (const d of defs) {
46
+ if (d.parameterCount === undefined) {
47
+ matchedCount++;
48
+ continue;
49
+ }
50
+ const min = d.requiredParameterCount ?? d.parameterCount;
51
+ if (argCount >= min && argCount <= d.parameterCount)
52
+ matchedCount++;
53
+ else
54
+ rejectedCount++;
55
+ }
56
+ // Only narrow when the filter actually discriminates: at least one
57
+ // match AND at least one rejection. Pure-match and pure-reject
58
+ // paths both keep the unfiltered pool (the latter because fallback
59
+ // semantics demand it).
60
+ if (matchedCount > 0 && rejectedCount > 0) {
61
+ const arityMatched = [];
62
+ for (const d of defs) {
63
+ if (d.parameterCount === undefined) {
64
+ arityMatched.push(d);
65
+ continue;
66
+ }
67
+ const min = d.requiredParameterCount ?? d.parameterCount;
68
+ if (argCount >= min && argCount <= d.parameterCount)
69
+ arityMatched.push(d);
70
+ }
71
+ pool = arityMatched;
72
+ }
73
+ }
74
+ if (pool.length === 1)
75
+ return pool[0];
76
+ // Multiple overloads after arity narrowing: return first if all share
77
+ // the same defined returnType (safe for chain resolution), undefined if
78
+ // return types differ (truly ambiguous — can't determine which overload).
79
+ const firstReturnType = pool[0].returnType;
80
+ if (firstReturnType === undefined)
81
+ return undefined;
82
+ for (let i = 1; i < pool.length; i++) {
83
+ if (pool[i].returnType !== firstReturnType)
84
+ return undefined;
85
+ }
86
+ return pool[0];
87
+ };
88
+ const lookupMethodByName = (name) => {
89
+ return methodsByName.get(name) ?? EMPTY;
90
+ };
91
+ const register = (ownerNodeId, methodName, def) => {
92
+ const key = `${ownerNodeId}\0${methodName}`;
93
+ const existing = methodByOwner.get(key);
94
+ if (existing) {
95
+ existing.push(def);
96
+ }
97
+ else {
98
+ methodByOwner.set(key, [def]);
99
+ }
100
+ const byName = methodsByName.get(methodName);
101
+ if (byName) {
102
+ byName.push(def);
103
+ }
104
+ else {
105
+ methodsByName.set(methodName, [def]);
106
+ }
107
+ // A `Function`-typed def reaching MethodRegistry means the worker
108
+ // emitted a Python/Rust/Kotlin class method as `Function + ownerId`.
109
+ // It was already written into `SymbolTable.callableByName` by the
110
+ // upstream Function callable-index gate, so the two indexes are no
111
+ // longer disjoint for this registry's lifetime — Tier 3 must dedup.
112
+ if (!hasFunctionMethodsFlag && def.type === 'Function') {
113
+ hasFunctionMethodsFlag = true;
114
+ }
115
+ };
116
+ const clear = () => {
117
+ methodByOwner.clear();
118
+ methodsByName.clear();
119
+ hasFunctionMethodsFlag = false;
120
+ };
121
+ return {
122
+ lookupMethodByOwner,
123
+ lookupMethodByName,
124
+ register,
125
+ clear,
126
+ get hasFunctionMethods() {
127
+ return hasFunctionMethodsFlag;
128
+ },
129
+ };
130
+ };
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Registration Dispatch Table
3
+ *
4
+ * Behavior-grouped O(1) dispatch table for routing `SymbolTable.add()`
5
+ * registrations into the semantic registries. Replaces the cascading
6
+ * `if/else` ladder in `symbol-table.ts` with a `Map<NodeLabel, RoutingDecision>`
7
+ * whose entries point to closure-captured hooks.
8
+ *
9
+ * ## Ownership diagram
10
+ *
11
+ * SemanticModel
12
+ * ├── types (TypeRegistry) ← classLikeHook / implHook write here
13
+ * ├── methods (MethodRegistry) ← methodHook writes here
14
+ * ├── fields (FieldRegistry) ← propertyHook writes here
15
+ * └── symbols (SymbolTable) ← owns fileIndex + callableByName,
16
+ * calls dispatch() in add()
17
+ *
18
+ * ## Behavior groups (5 hooks, 13 table entries)
19
+ *
20
+ * | Group | NodeLabel values | Hook | Skip callable? |
21
+ * |---------------|---------------------------------------------------|--------------|----------------|
22
+ * | class-like | Class, Struct, Interface, Enum, Record, Trait | classLikeHook | no |
23
+ * | method-like | Method, Constructor | methodHook | no |
24
+ * | property | Property | propertyHook | YES |
25
+ * | impl-block | Impl | implHook | no |
26
+ * | callable-only | Function, Macro, Delegate | (no entry) | no |
27
+ *
28
+ * Every other `NodeLabel` is "inert" — reached by `fileIndex` only. No
29
+ * specialized registry, no callable index append.
30
+ *
31
+ * ## How to add a new NodeLabel
32
+ *
33
+ * 1. Add the variant to the `NodeLabel` union in `gitnexus-shared/src/graph/types.ts`.
34
+ * 2. Decide which behavior group it belongs to by asking "which lookups must
35
+ * return this symbol?" (not "what language feature is it?"). A new Swift
36
+ * `Extension` is class-like if you want owner-scoped method lookup on it;
37
+ * a new Kotlin `Object` is class-like for the same reason.
38
+ * 3. Either:
39
+ * - Add a table entry here pointing at one of the existing hooks, OR
40
+ * - Add it to `CALLABLE_ONLY_LABELS` if it is a free callable, OR
41
+ * - Add it to `INERT_LABELS` if it's metadata-only (File, Folder, Decorator,
42
+ * etc.) — never queried via owner/class lookups.
43
+ * 4. If none of the above fit — the new kind needs a brand-new registry —
44
+ * design the registry first in `model/`, then add a new hook closure
45
+ * and table entries. Update `DISPATCH_LABELS` / the exhaustiveness guard
46
+ * accordingly.
47
+ *
48
+ * The runtime exhaustiveness guard in `symbol-table.ts` will warn if a
49
+ * `NodeLabel` is missing from all three sets.
50
+ */
51
+ import type { NodeLabel } from '../../../_shared/index.js';
52
+ import type { SymbolDefinition } from './symbol-table.js';
53
+ import type { MutableTypeRegistry } from './type-registry.js';
54
+ import type { MutableMethodRegistry } from './method-registry.js';
55
+ import type { MutableFieldRegistry } from './field-registry.js';
56
+ /**
57
+ * Registration hook — a pure side-effectful function closed over a
58
+ * specific registry. Performs the specialized registry write into the
59
+ * appropriate owner-scoped registry for one NodeLabel.
60
+ *
61
+ * Closure capture is the isolation mechanism: `propertyHook` literally
62
+ * cannot call `types.registerClass` because its closure does not hold
63
+ * a reference to `types`. This is the runtime half of the principle of
64
+ * least authority — the compile-time half is enforced by TypeScript.
65
+ *
66
+ * The callable-index gate lives inside `SymbolTable.add()` via the
67
+ * `FREE_CALLABLE_TYPES` allowlist — the dispatch table does not
68
+ * participate in that decision.
69
+ */
70
+ export type RegistrationHook = (name: string, def: SymbolDefinition) => void;
71
+ /**
72
+ * Dependencies required to build the dispatch table. Matches the shape
73
+ * that `createSemanticModel()` passes into `createRegistrationTable()`.
74
+ */
75
+ export interface RegistrationTableDeps {
76
+ readonly types: MutableTypeRegistry;
77
+ readonly methods: MutableMethodRegistry;
78
+ readonly fields: MutableFieldRegistry;
79
+ }
80
+ /**
81
+ * Behavior category for a NodeLabel during ingestion. Determines which
82
+ * registry (if any) receives the symbol write during `SymbolTable.add()`:
83
+ *
84
+ * - `dispatch` — owner-scoped registry write via the dispatch table
85
+ * (Class/Struct/Interface/Enum/Record/Trait → types.registerClass,
86
+ * Method/Constructor → methods.register,
87
+ * Property → fields.register,
88
+ * Impl → types.registerImpl)
89
+ * - `callable-only` — no specialized registry; symbol appears in
90
+ * `callableByName` via `SymbolTable.add()`'s
91
+ * FREE_CALLABLE_TYPES gate (Function/Macro/Delegate)
92
+ * - `inert` — no registry, no callable index; file-index only
93
+ * (metadata / structural nodes like Project, Module,
94
+ * Import, Decorator, etc.)
95
+ *
96
+ * `Function` has a twist: `Function`-with-`ownerId` (Python `def` in a
97
+ * class body, Rust trait method, Kotlin companion method) is pre-normalized
98
+ * to `Method` in `createSemanticModel`'s `wrappedAdd` before dispatch lookup,
99
+ * so only free functions actually flow through the callable-only path.
100
+ */
101
+ export type LabelBehavior = 'dispatch' | 'callable-only' | 'inert';
102
+ /**
103
+ * All known NodeLabels, derived from the keys of `LABEL_BEHAVIOR`. The
104
+ * `satisfies Record<NodeLabel, LabelBehavior>` bijection above proves
105
+ * that `Object.keys(LABEL_BEHAVIOR)` is exactly the NodeLabel set —
106
+ * the cast to `NodeLabel[]` is sound, not a type-system bypass.
107
+ *
108
+ * Consumers (e.g., the semantic-model barrel re-export for tests) can
109
+ * rely on this list being complete by construction. No runtime drift
110
+ * check is needed or possible — the type system is the proof.
111
+ */
112
+ export declare const ALL_NODE_LABELS: readonly NodeLabel[];
113
+ /**
114
+ * NodeLabel values that are free callables — appear in `callableByName`
115
+ * but have no owner-scoped specialized registry. Alias of
116
+ * {@link FREE_CALLABLE_TYPES} exported here for taxonomy-test use. The
117
+ * compile-time cross-invariant on `LABEL_BEHAVIOR` above guarantees the
118
+ * alias and the LABEL_BEHAVIOR `callable-only` classification cannot
119
+ * drift.
120
+ */
121
+ export declare const CALLABLE_ONLY_LABELS: ReadonlySet<NodeLabel>;
122
+ /**
123
+ * NodeLabel values that touch only the file index — no specialized
124
+ * registry, no callable index.
125
+ */
126
+ export declare const INERT_LABELS: ReadonlySet<NodeLabel>;
127
+ /**
128
+ * NodeLabel values that have a dispatch table entry. `createRegistrationTable`
129
+ * below must provide a hook for exactly this set — the test file's behavior-
130
+ * group tests and the integration tests pin the hook↔label correspondence.
131
+ */
132
+ export declare const DISPATCH_LABELS: ReadonlySet<NodeLabel>;
133
+ /**
134
+ * Build the dispatch table. Must be called once per `createSymbolTable`
135
+ * invocation so each hook closes over that SymbolTable's injected
136
+ * registries. Reusing a single module-level instance would cause hooks
137
+ * to write into the wrong SemanticModel.
138
+ */
139
+ export declare const createRegistrationTable: (deps: RegistrationTableDeps) => Map<NodeLabel, RegistrationHook>;