gitnexus 1.4.8 → 1.4.9

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 (211) hide show
  1. package/README.md +7 -0
  2. package/dist/cli/index-repo.d.ts +15 -0
  3. package/dist/cli/index-repo.js +115 -0
  4. package/dist/cli/index.js +11 -2
  5. package/dist/cli/setup.js +12 -9
  6. package/dist/cli/wiki.d.ts +4 -0
  7. package/dist/cli/wiki.js +174 -53
  8. package/dist/config/supported-languages.d.ts +7 -5
  9. package/dist/config/supported-languages.js +6 -4
  10. package/dist/core/graph/graph.js +9 -1
  11. package/dist/core/graph/types.d.ts +10 -2
  12. package/dist/core/ingestion/call-processor.d.ts +18 -1
  13. package/dist/core/ingestion/call-processor.js +297 -38
  14. package/dist/core/ingestion/call-routing.d.ts +3 -18
  15. package/dist/core/ingestion/call-routing.js +0 -19
  16. package/dist/core/ingestion/cobol/cobol-copy-expander.d.ts +57 -0
  17. package/dist/core/ingestion/cobol/cobol-copy-expander.js +385 -0
  18. package/dist/core/ingestion/cobol/cobol-preprocessor.d.ts +210 -0
  19. package/dist/core/ingestion/cobol/cobol-preprocessor.js +1509 -0
  20. package/dist/core/ingestion/cobol/jcl-parser.d.ts +68 -0
  21. package/dist/core/ingestion/cobol/jcl-parser.js +217 -0
  22. package/dist/core/ingestion/cobol/jcl-processor.d.ts +33 -0
  23. package/dist/core/ingestion/cobol/jcl-processor.js +229 -0
  24. package/dist/core/ingestion/cobol-processor.d.ts +54 -0
  25. package/dist/core/ingestion/cobol-processor.js +1186 -0
  26. package/dist/core/ingestion/entry-point-scoring.d.ts +17 -0
  27. package/dist/core/ingestion/entry-point-scoring.js +18 -4
  28. package/dist/core/ingestion/export-detection.d.ts +47 -8
  29. package/dist/core/ingestion/export-detection.js +29 -50
  30. package/dist/core/ingestion/field-extractor.d.ts +29 -0
  31. package/dist/core/ingestion/field-extractor.js +25 -0
  32. package/dist/core/ingestion/field-extractors/configs/c-cpp.d.ts +3 -0
  33. package/dist/core/ingestion/field-extractors/configs/c-cpp.js +108 -0
  34. package/dist/core/ingestion/field-extractors/configs/csharp.d.ts +8 -0
  35. package/dist/core/ingestion/field-extractors/configs/csharp.js +73 -0
  36. package/dist/core/ingestion/field-extractors/configs/dart.d.ts +8 -0
  37. package/dist/core/ingestion/field-extractors/configs/dart.js +76 -0
  38. package/dist/core/ingestion/field-extractors/configs/go.d.ts +11 -0
  39. package/dist/core/ingestion/field-extractors/configs/go.js +64 -0
  40. package/dist/core/ingestion/field-extractors/configs/helpers.d.ts +44 -0
  41. package/dist/core/ingestion/field-extractors/configs/helpers.js +134 -0
  42. package/dist/core/ingestion/field-extractors/configs/jvm.d.ts +3 -0
  43. package/dist/core/ingestion/field-extractors/configs/jvm.js +118 -0
  44. package/dist/core/ingestion/field-extractors/configs/php.d.ts +8 -0
  45. package/dist/core/ingestion/field-extractors/configs/php.js +67 -0
  46. package/dist/core/ingestion/field-extractors/configs/python.d.ts +12 -0
  47. package/dist/core/ingestion/field-extractors/configs/python.js +91 -0
  48. package/dist/core/ingestion/field-extractors/configs/ruby.d.ts +16 -0
  49. package/dist/core/ingestion/field-extractors/configs/ruby.js +75 -0
  50. package/dist/core/ingestion/field-extractors/configs/rust.d.ts +9 -0
  51. package/dist/core/ingestion/field-extractors/configs/rust.js +55 -0
  52. package/dist/core/ingestion/field-extractors/configs/swift.d.ts +8 -0
  53. package/dist/core/ingestion/field-extractors/configs/swift.js +63 -0
  54. package/dist/core/ingestion/field-extractors/configs/typescript-javascript.d.ts +3 -0
  55. package/dist/core/ingestion/field-extractors/configs/typescript-javascript.js +60 -0
  56. package/dist/core/ingestion/field-extractors/generic.d.ts +46 -0
  57. package/dist/core/ingestion/field-extractors/generic.js +111 -0
  58. package/dist/core/ingestion/field-extractors/typescript.d.ts +77 -0
  59. package/dist/core/ingestion/field-extractors/typescript.js +291 -0
  60. package/dist/core/ingestion/field-types.d.ts +59 -0
  61. package/dist/core/ingestion/field-types.js +2 -0
  62. package/dist/core/ingestion/framework-detection.d.ts +87 -0
  63. package/dist/core/ingestion/framework-detection.js +65 -2
  64. package/dist/core/ingestion/heritage-processor.js +15 -17
  65. package/dist/core/ingestion/import-processor.d.ts +9 -10
  66. package/dist/core/ingestion/import-processor.js +59 -14
  67. package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.d.ts +6 -9
  68. package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.js +20 -2
  69. package/dist/core/ingestion/import-resolvers/dart.d.ts +7 -0
  70. package/dist/core/ingestion/import-resolvers/dart.js +44 -0
  71. package/dist/core/ingestion/{resolvers → import-resolvers}/go.d.ts +4 -5
  72. package/dist/core/ingestion/{resolvers → import-resolvers}/go.js +17 -0
  73. package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.d.ts +9 -1
  74. package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.js +56 -0
  75. package/dist/core/ingestion/{resolvers → import-resolvers}/php.d.ts +6 -10
  76. package/dist/core/ingestion/{resolvers → import-resolvers}/php.js +7 -2
  77. package/dist/core/ingestion/{resolvers → import-resolvers}/python.d.ts +9 -3
  78. package/dist/core/ingestion/{resolvers → import-resolvers}/python.js +35 -3
  79. package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.d.ts +5 -2
  80. package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.js +7 -2
  81. package/dist/core/ingestion/{resolvers → import-resolvers}/rust.d.ts +5 -2
  82. package/dist/core/ingestion/{resolvers → import-resolvers}/rust.js +41 -2
  83. package/dist/core/ingestion/{resolvers → import-resolvers}/standard.d.ts +15 -7
  84. package/dist/core/ingestion/{resolvers → import-resolvers}/standard.js +22 -3
  85. package/dist/core/ingestion/import-resolvers/swift.d.ts +7 -0
  86. package/dist/core/ingestion/import-resolvers/swift.js +23 -0
  87. package/dist/core/ingestion/import-resolvers/types.d.ts +44 -0
  88. package/dist/core/ingestion/import-resolvers/types.js +6 -0
  89. package/dist/core/ingestion/{resolvers → import-resolvers}/utils.d.ts +0 -3
  90. package/dist/core/ingestion/{resolvers → import-resolvers}/utils.js +0 -9
  91. package/dist/core/ingestion/language-config.d.ts +4 -1
  92. package/dist/core/ingestion/language-provider.d.ts +121 -0
  93. package/dist/core/ingestion/language-provider.js +24 -0
  94. package/dist/core/ingestion/languages/c-cpp.d.ts +12 -0
  95. package/dist/core/ingestion/languages/c-cpp.js +71 -0
  96. package/dist/core/ingestion/languages/cobol.d.ts +1 -0
  97. package/dist/core/ingestion/languages/cobol.js +26 -0
  98. package/dist/core/ingestion/languages/csharp.d.ts +8 -0
  99. package/dist/core/ingestion/languages/csharp.js +49 -0
  100. package/dist/core/ingestion/languages/dart.d.ts +12 -0
  101. package/dist/core/ingestion/languages/dart.js +58 -0
  102. package/dist/core/ingestion/languages/go.d.ts +11 -0
  103. package/dist/core/ingestion/languages/go.js +28 -0
  104. package/dist/core/ingestion/languages/index.d.ts +38 -0
  105. package/dist/core/ingestion/languages/index.js +63 -0
  106. package/dist/core/ingestion/languages/java.d.ts +9 -0
  107. package/dist/core/ingestion/languages/java.js +29 -0
  108. package/dist/core/ingestion/languages/kotlin.d.ts +9 -0
  109. package/dist/core/ingestion/languages/kotlin.js +53 -0
  110. package/dist/core/ingestion/languages/php.d.ts +8 -0
  111. package/dist/core/ingestion/languages/php.js +145 -0
  112. package/dist/core/ingestion/languages/python.d.ts +12 -0
  113. package/dist/core/ingestion/languages/python.js +39 -0
  114. package/dist/core/ingestion/languages/ruby.d.ts +9 -0
  115. package/dist/core/ingestion/languages/ruby.js +44 -0
  116. package/dist/core/ingestion/languages/rust.d.ts +12 -0
  117. package/dist/core/ingestion/languages/rust.js +44 -0
  118. package/dist/core/ingestion/languages/swift.d.ts +12 -0
  119. package/dist/core/ingestion/languages/swift.js +133 -0
  120. package/dist/core/ingestion/languages/typescript.d.ts +10 -0
  121. package/dist/core/ingestion/languages/typescript.js +60 -0
  122. package/dist/core/ingestion/mro-processor.js +14 -15
  123. package/dist/core/ingestion/{named-binding-extraction.d.ts → named-binding-processor.d.ts} +0 -9
  124. package/dist/core/ingestion/named-binding-processor.js +42 -0
  125. package/dist/core/ingestion/named-bindings/csharp.d.ts +3 -0
  126. package/dist/core/ingestion/named-bindings/csharp.js +37 -0
  127. package/dist/core/ingestion/named-bindings/java.d.ts +3 -0
  128. package/dist/core/ingestion/named-bindings/java.js +29 -0
  129. package/dist/core/ingestion/named-bindings/kotlin.d.ts +3 -0
  130. package/dist/core/ingestion/named-bindings/kotlin.js +36 -0
  131. package/dist/core/ingestion/named-bindings/php.d.ts +3 -0
  132. package/dist/core/ingestion/named-bindings/php.js +61 -0
  133. package/dist/core/ingestion/named-bindings/python.d.ts +3 -0
  134. package/dist/core/ingestion/named-bindings/python.js +49 -0
  135. package/dist/core/ingestion/named-bindings/rust.d.ts +3 -0
  136. package/dist/core/ingestion/named-bindings/rust.js +64 -0
  137. package/dist/core/ingestion/named-bindings/types.d.ts +16 -0
  138. package/dist/core/ingestion/named-bindings/types.js +6 -0
  139. package/dist/core/ingestion/named-bindings/typescript.d.ts +3 -0
  140. package/dist/core/ingestion/named-bindings/typescript.js +58 -0
  141. package/dist/core/ingestion/parsing-processor.d.ts +5 -1
  142. package/dist/core/ingestion/parsing-processor.js +115 -16
  143. package/dist/core/ingestion/pipeline.js +925 -424
  144. package/dist/core/ingestion/resolution-context.js +1 -1
  145. package/dist/core/ingestion/route-extractors/expo.d.ts +1 -0
  146. package/dist/core/ingestion/route-extractors/expo.js +36 -0
  147. package/dist/core/ingestion/route-extractors/middleware.d.ts +47 -0
  148. package/dist/core/ingestion/route-extractors/middleware.js +143 -0
  149. package/dist/core/ingestion/route-extractors/nextjs.d.ts +3 -0
  150. package/dist/core/ingestion/route-extractors/nextjs.js +76 -0
  151. package/dist/core/ingestion/route-extractors/php.d.ts +7 -0
  152. package/dist/core/ingestion/route-extractors/php.js +21 -0
  153. package/dist/core/ingestion/route-extractors/response-shapes.d.ts +20 -0
  154. package/dist/core/ingestion/route-extractors/response-shapes.js +290 -0
  155. package/dist/core/ingestion/tree-sitter-queries.d.ts +8 -7
  156. package/dist/core/ingestion/tree-sitter-queries.js +231 -9
  157. package/dist/core/ingestion/type-env.d.ts +14 -17
  158. package/dist/core/ingestion/type-env.js +66 -14
  159. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +1 -1
  160. package/dist/core/ingestion/type-extractors/csharp.js +1 -1
  161. package/dist/core/ingestion/type-extractors/dart.d.ts +15 -0
  162. package/dist/core/ingestion/type-extractors/dart.js +371 -0
  163. package/dist/core/ingestion/type-extractors/jvm.js +1 -1
  164. package/dist/core/ingestion/type-extractors/shared.d.ts +1 -13
  165. package/dist/core/ingestion/type-extractors/shared.js +9 -102
  166. package/dist/core/ingestion/type-extractors/swift.js +334 -4
  167. package/dist/core/ingestion/type-extractors/types.d.ts +3 -1
  168. package/dist/core/ingestion/{ast-helpers.d.ts → utils/ast-helpers.d.ts} +16 -13
  169. package/dist/core/ingestion/{ast-helpers.js → utils/ast-helpers.js} +111 -32
  170. package/dist/core/ingestion/{call-analysis.js → utils/call-analysis.js} +37 -0
  171. package/dist/core/ingestion/utils/event-loop.d.ts +5 -0
  172. package/dist/core/ingestion/utils/event-loop.js +5 -0
  173. package/dist/core/ingestion/utils/language-detection.d.ts +9 -0
  174. package/dist/core/ingestion/utils/language-detection.js +70 -0
  175. package/dist/core/ingestion/utils/verbose.d.ts +1 -0
  176. package/dist/core/ingestion/utils/verbose.js +7 -0
  177. package/dist/core/ingestion/workers/parse-worker.d.ts +43 -2
  178. package/dist/core/ingestion/workers/parse-worker.js +361 -150
  179. package/dist/core/lbug/csv-generator.js +34 -1
  180. package/dist/core/lbug/lbug-adapter.js +6 -0
  181. package/dist/core/lbug/schema.d.ts +5 -3
  182. package/dist/core/lbug/schema.js +39 -2
  183. package/dist/core/tree-sitter/parser-loader.js +7 -1
  184. package/dist/core/wiki/cursor-client.d.ts +31 -0
  185. package/dist/core/wiki/cursor-client.js +127 -0
  186. package/dist/core/wiki/generator.d.ts +28 -9
  187. package/dist/core/wiki/generator.js +115 -18
  188. package/dist/core/wiki/graph-queries.d.ts +4 -0
  189. package/dist/core/wiki/graph-queries.js +7 -1
  190. package/dist/core/wiki/llm-client.d.ts +2 -0
  191. package/dist/core/wiki/llm-client.js +8 -4
  192. package/dist/core/wiki/prompts.d.ts +3 -3
  193. package/dist/core/wiki/prompts.js +6 -0
  194. package/dist/mcp/core/lbug-adapter.d.ts +5 -0
  195. package/dist/mcp/core/lbug-adapter.js +11 -1
  196. package/dist/mcp/local/local-backend.d.ts +16 -5
  197. package/dist/mcp/local/local-backend.js +711 -74
  198. package/dist/mcp/tools.js +71 -2
  199. package/dist/storage/repo-manager.d.ts +3 -0
  200. package/package.json +17 -16
  201. package/dist/core/ingestion/import-resolution.d.ts +0 -101
  202. package/dist/core/ingestion/import-resolution.js +0 -251
  203. package/dist/core/ingestion/named-binding-extraction.js +0 -373
  204. package/dist/core/ingestion/resolvers/index.d.ts +0 -18
  205. package/dist/core/ingestion/resolvers/index.js +0 -13
  206. package/dist/core/ingestion/type-extractors/index.d.ts +0 -22
  207. package/dist/core/ingestion/type-extractors/index.js +0 -31
  208. package/dist/core/ingestion/utils.d.ts +0 -20
  209. package/dist/core/ingestion/utils.js +0 -242
  210. package/scripts/patch-tree-sitter-swift.cjs +0 -74
  211. /package/dist/core/ingestion/{call-analysis.d.ts → utils/call-analysis.d.ts} +0 -0
@@ -10,6 +10,23 @@
10
10
  * This module is language-agnostic - language-specific patterns are defined per language.
11
11
  */
12
12
  import { SupportedLanguages } from '../../config/supported-languages.js';
13
+ export declare const ENTRY_POINT_PATTERNS: {
14
+ javascript: RegExp[];
15
+ typescript: RegExp[];
16
+ python: RegExp[];
17
+ java: RegExp[];
18
+ kotlin: RegExp[];
19
+ csharp: RegExp[];
20
+ go: RegExp[];
21
+ rust: RegExp[];
22
+ c: RegExp[];
23
+ cpp: RegExp[];
24
+ swift: RegExp[];
25
+ php: RegExp[];
26
+ ruby: RegExp[];
27
+ dart: RegExp[];
28
+ cobol: any[];
29
+ };
13
30
  export interface EntryPointScoreResult {
14
31
  score: number;
15
32
  reasons: string[];
@@ -36,7 +36,7 @@ const UNIVERSAL_ENTRY_POINT_PATTERNS = [
36
36
  /^fire[A-Z]/, // fireEvent
37
37
  /^emit[A-Z]/, // emitEvent
38
38
  ];
39
- const ENTRY_POINT_PATTERNS = {
39
+ export const ENTRY_POINT_PATTERNS = {
40
40
  // JavaScript/TypeScript
41
41
  [SupportedLanguages.JavaScript]: [
42
42
  /^use[A-Z]/, // React hooks (useEffect, etc.)
@@ -197,11 +197,25 @@ const ENTRY_POINT_PATTERNS = {
197
197
  /^perform$/, // Background jobs (Sidekiq, ActiveJob)
198
198
  /^execute$/, // Command pattern
199
199
  ],
200
+ // Dart / Flutter
201
+ [SupportedLanguages.Dart]: [
202
+ /^main$/, // App entry
203
+ /^build$/, // Widget.build — fundamental Flutter render entry point
204
+ /^createState$/, // StatefulWidget.createState
205
+ /^initState$/, // State lifecycle initialization
206
+ /^dispose$/, // State lifecycle teardown
207
+ /^didChangeDependencies$/, // State lifecycle — InheritedWidget changes
208
+ /^didUpdateWidget$/, // State lifecycle — widget rebuild with new config
209
+ /^runApp$/, // App entry point
210
+ /^onEvent$/, // BLoC event handler
211
+ /^mapEventToState$/, // Legacy BLoC pattern
212
+ ],
213
+ [SupportedLanguages.Cobol]: [], // Standalone regex processor — no tree-sitter entry points
200
214
  };
201
215
  /** Pre-computed merged patterns (universal + language-specific) to avoid per-call array allocation. */
202
- const MERGED_ENTRY_POINT_PATTERNS = Object.fromEntries(Object.keys(ENTRY_POINT_PATTERNS).map(lang => [
216
+ const MERGED_ENTRY_POINT_PATTERNS = Object.fromEntries(Object.values(SupportedLanguages).map(lang => [
203
217
  lang,
204
- [...UNIVERSAL_ENTRY_POINT_PATTERNS, ...ENTRY_POINT_PATTERNS[lang]],
218
+ [...UNIVERSAL_ENTRY_POINT_PATTERNS, ...(ENTRY_POINT_PATTERNS[lang] ?? [])],
205
219
  ]));
206
220
  // ============================================================================
207
221
  // UTILITY PATTERNS - Functions that should be penalized
@@ -269,7 +283,7 @@ export function calculateEntryPointScore(name, language, isExported, callerCount
269
283
  else {
270
284
  // Check positive patterns
271
285
  const allPatterns = MERGED_ENTRY_POINT_PATTERNS[language];
272
- if (allPatterns.some(p => p.test(name))) {
286
+ if (allPatterns?.some(p => p.test(name))) {
273
287
  nameMultiplier = 1.5; // Bonus for matching entry point pattern
274
288
  reasons.push('entry-pattern');
275
289
  }
@@ -6,13 +6,52 @@
6
6
  *
7
7
  * Shared between parse-worker.ts (worker pool) and parsing-processor.ts (sequential fallback).
8
8
  */
9
- import { SyntaxNode } from './utils.js';
10
- import { SupportedLanguages } from '../../config/supported-languages.js';
9
+ import { type SyntaxNode } from './utils/ast-helpers.js';
10
+ /** Handler type: given a node and symbol name, return true if the symbol is exported/public. */
11
+ export type ExportChecker = (node: SyntaxNode, name: string) => boolean;
12
+ /** JS/TS: walk ancestors looking for export_statement or export_specifier. */
13
+ export declare const tsExportChecker: ExportChecker;
14
+ /** Python: public if no leading underscore (convention). */
15
+ export declare const pythonExportChecker: ExportChecker;
16
+ /** Java: check for 'public' modifier — modifiers are siblings of the name node, not parents. */
17
+ export declare const javaExportChecker: ExportChecker;
11
18
  /**
12
- * Check if a tree-sitter node is exported/public in its language.
13
- * @param node - The tree-sitter AST node
14
- * @param name - The symbol name
15
- * @param language - The programming language
16
- * @returns true if the symbol is exported/public
19
+ * C#: modifier nodes are SIBLINGS of the name node inside the declaration.
20
+ * Walk up to the declaration node, then scan its direct children.
17
21
  */
18
- export declare const isNodeExported: (node: SyntaxNode, name: string, language: SupportedLanguages) => boolean;
22
+ export declare const csharpExportChecker: ExportChecker;
23
+ /** Go: uppercase first letter = exported. */
24
+ export declare const goExportChecker: ExportChecker;
25
+ /**
26
+ * Rust: visibility_modifier is a SIBLING of the name node within the declaration node
27
+ * (function_item, struct_item, etc.), not a parent. Walk up to the declaration node,
28
+ * then scan its direct children.
29
+ */
30
+ export declare const rustExportChecker: ExportChecker;
31
+ /**
32
+ * Kotlin: default visibility is public (unlike Java).
33
+ * visibility_modifier is inside modifiers, a sibling of the name node within the declaration.
34
+ */
35
+ export declare const kotlinExportChecker: ExportChecker;
36
+ /**
37
+ * C/C++: functions without 'static' storage class have external linkage by default,
38
+ * making them globally accessible (equivalent to exported). Only functions explicitly
39
+ * marked 'static' are file-scoped (not exported). C++ anonymous namespaces
40
+ * (namespace { ... }) also give internal linkage.
41
+ */
42
+ export declare const cCppExportChecker: ExportChecker;
43
+ /** PHP: check for visibility modifier or top-level scope. */
44
+ export declare const phpExportChecker: ExportChecker;
45
+ /**
46
+ * Swift: treat symbols as exported unless explicitly marked private/fileprivate.
47
+ *
48
+ * Swift's default access level is `internal`, which means visible to all files
49
+ * in the same module/target. Since GitNexus indexes at the target level,
50
+ * `internal` symbols should be treated as exported (cross-file visible).
51
+ * Only `private` and `fileprivate` symbols are truly file-scoped.
52
+ */
53
+ export declare const swiftExportChecker: ExportChecker;
54
+ /** Ruby: all top-level definitions are public (no export syntax). */
55
+ export declare const rubyExportChecker: ExportChecker;
56
+ /** Dart: public if no leading underscore (convention, same as Python). */
57
+ export declare const dartExportChecker: ExportChecker;
@@ -6,13 +6,12 @@
6
6
  *
7
7
  * Shared between parse-worker.ts (worker pool) and parsing-processor.ts (sequential fallback).
8
8
  */
9
- import { findSiblingChild } from './utils.js';
10
- import { SupportedLanguages } from '../../config/supported-languages.js';
9
+ import { findSiblingChild } from './utils/ast-helpers.js';
11
10
  // ============================================================================
12
11
  // Per-language export checkers
13
12
  // ============================================================================
14
13
  /** JS/TS: walk ancestors looking for export_statement or export_specifier. */
15
- const tsExportChecker = (node, _name) => {
14
+ export const tsExportChecker = (node, _name) => {
16
15
  let current = node;
17
16
  while (current) {
18
17
  const type = current.type;
@@ -30,9 +29,9 @@ const tsExportChecker = (node, _name) => {
30
29
  return false;
31
30
  };
32
31
  /** Python: public if no leading underscore (convention). */
33
- const pythonExportChecker = (_node, name) => !name.startsWith('_');
32
+ export const pythonExportChecker = (_node, name) => !name.startsWith('_');
34
33
  /** Java: check for 'public' modifier — modifiers are siblings of the name node, not parents. */
35
- const javaExportChecker = (node, _name) => {
34
+ export const javaExportChecker = (node, _name) => {
36
35
  let current = node;
37
36
  while (current) {
38
37
  if (current.parent) {
@@ -66,7 +65,7 @@ const CSHARP_DECL_TYPES = new Set([
66
65
  * C#: modifier nodes are SIBLINGS of the name node inside the declaration.
67
66
  * Walk up to the declaration node, then scan its direct children.
68
67
  */
69
- const csharpExportChecker = (node, _name) => {
68
+ export const csharpExportChecker = (node, _name) => {
70
69
  let current = node;
71
70
  while (current) {
72
71
  if (CSHARP_DECL_TYPES.has(current.type)) {
@@ -82,7 +81,7 @@ const csharpExportChecker = (node, _name) => {
82
81
  return false;
83
82
  };
84
83
  /** Go: uppercase first letter = exported. */
85
- const goExportChecker = (_node, name) => {
84
+ export const goExportChecker = (_node, name) => {
86
85
  if (name.length === 0)
87
86
  return false;
88
87
  const first = name[0];
@@ -99,7 +98,7 @@ const RUST_DECL_TYPES = new Set([
99
98
  * (function_item, struct_item, etc.), not a parent. Walk up to the declaration node,
100
99
  * then scan its direct children.
101
100
  */
102
- const rustExportChecker = (node, _name) => {
101
+ export const rustExportChecker = (node, _name) => {
103
102
  let current = node;
104
103
  while (current) {
105
104
  if (RUST_DECL_TYPES.has(current.type)) {
@@ -118,7 +117,7 @@ const rustExportChecker = (node, _name) => {
118
117
  * Kotlin: default visibility is public (unlike Java).
119
118
  * visibility_modifier is inside modifiers, a sibling of the name node within the declaration.
120
119
  */
121
- const kotlinExportChecker = (node, _name) => {
120
+ export const kotlinExportChecker = (node, _name) => {
122
121
  let current = node;
123
122
  while (current) {
124
123
  if (current.parent) {
@@ -142,7 +141,7 @@ const kotlinExportChecker = (node, _name) => {
142
141
  * marked 'static' are file-scoped (not exported). C++ anonymous namespaces
143
142
  * (namespace { ... }) also give internal linkage.
144
143
  */
145
- const cCppExportChecker = (node, _name) => {
144
+ export const cCppExportChecker = (node, _name) => {
146
145
  let cur = node;
147
146
  while (cur) {
148
147
  if (cur.type === 'function_definition' || cur.type === 'declaration') {
@@ -165,7 +164,7 @@ const cCppExportChecker = (node, _name) => {
165
164
  return true; // Top-level C/C++ functions default to external linkage
166
165
  };
167
166
  /** PHP: check for visibility modifier or top-level scope. */
168
- const phpExportChecker = (node, _name) => {
167
+ export const phpExportChecker = (node, _name) => {
169
168
  let current = node;
170
169
  while (current) {
171
170
  if (current.type === 'class_declaration' ||
@@ -182,50 +181,30 @@ const phpExportChecker = (node, _name) => {
182
181
  // Top-level functions are globally accessible
183
182
  return true;
184
183
  };
185
- /** Swift: check for 'public' or 'open' access modifiers. */
186
- const swiftExportChecker = (node, _name) => {
184
+ /**
185
+ * Swift: treat symbols as exported unless explicitly marked private/fileprivate.
186
+ *
187
+ * Swift's default access level is `internal`, which means visible to all files
188
+ * in the same module/target. Since GitNexus indexes at the target level,
189
+ * `internal` symbols should be treated as exported (cross-file visible).
190
+ * Only `private` and `fileprivate` symbols are truly file-scoped.
191
+ */
192
+ export const swiftExportChecker = (node, _name) => {
187
193
  let current = node;
188
194
  while (current) {
189
195
  if (current.type === 'modifiers' || current.type === 'visibility_modifier') {
190
196
  const text = current.text || '';
191
- if (text.includes('public') || text.includes('open'))
192
- return true;
197
+ // Exclude private(set)/fileprivate(set) only the setter is restricted,
198
+ // the symbol itself is still readable cross-file.
199
+ if (/\b(private|fileprivate)\b(?!\s*\()/.test(text))
200
+ return false;
193
201
  }
194
202
  current = current.parent;
195
203
  }
196
- return false;
197
- };
198
- // ============================================================================
199
- // Exhaustive dispatch table — satisfies enforces all SupportedLanguages are covered
200
- // ============================================================================
201
- const exportCheckers = {
202
- [SupportedLanguages.JavaScript]: tsExportChecker,
203
- [SupportedLanguages.TypeScript]: tsExportChecker,
204
- [SupportedLanguages.Python]: pythonExportChecker,
205
- [SupportedLanguages.Java]: javaExportChecker,
206
- [SupportedLanguages.CSharp]: csharpExportChecker,
207
- [SupportedLanguages.Go]: goExportChecker,
208
- [SupportedLanguages.Rust]: rustExportChecker,
209
- [SupportedLanguages.Kotlin]: kotlinExportChecker,
210
- [SupportedLanguages.C]: cCppExportChecker,
211
- [SupportedLanguages.CPlusPlus]: cCppExportChecker,
212
- [SupportedLanguages.PHP]: phpExportChecker,
213
- [SupportedLanguages.Swift]: swiftExportChecker,
214
- [SupportedLanguages.Ruby]: (_node, _name) => true,
215
- };
216
- // ============================================================================
217
- // Public API
218
- // ============================================================================
219
- /**
220
- * Check if a tree-sitter node is exported/public in its language.
221
- * @param node - The tree-sitter AST node
222
- * @param name - The symbol name
223
- * @param language - The programming language
224
- * @returns true if the symbol is exported/public
225
- */
226
- export const isNodeExported = (node, name, language) => {
227
- const checker = exportCheckers[language];
228
- if (!checker)
229
- return false;
230
- return checker(node, name);
204
+ // Default (internal), public, and open are all cross-file visible
205
+ return true;
231
206
  };
207
+ /** Ruby: all top-level definitions are public (no export syntax). */
208
+ export const rubyExportChecker = (_node, _name) => true;
209
+ /** Dart: public if no leading underscore (convention, same as Python). */
210
+ export const dartExportChecker = (_node, name) => !name.startsWith('_');
@@ -0,0 +1,29 @@
1
+ import type { SyntaxNode } from './utils/ast-helpers.js';
2
+ import { SupportedLanguages } from '../../config/supported-languages.js';
3
+ import type { FieldExtractorContext, ExtractedFields, FieldVisibility } from './field-types.js';
4
+ /**
5
+ * Language-specific field extractor
6
+ */
7
+ export interface FieldExtractor {
8
+ /** Language this extractor handles */
9
+ language: SupportedLanguages;
10
+ /**
11
+ * Extract fields from a class/struct/interface declaration
12
+ */
13
+ extract(node: SyntaxNode, context: FieldExtractorContext): ExtractedFields | null;
14
+ /**
15
+ * Check if this node represents a type declaration with fields
16
+ */
17
+ isTypeDeclaration(node: SyntaxNode): boolean;
18
+ }
19
+ /**
20
+ * Base class for field extractors with common utilities
21
+ */
22
+ export declare abstract class BaseFieldExtractor implements FieldExtractor {
23
+ abstract language: SupportedLanguages;
24
+ abstract extract(node: SyntaxNode, context: FieldExtractorContext): ExtractedFields | null;
25
+ abstract isTypeDeclaration(node: SyntaxNode): boolean;
26
+ protected normalizeType(type: string | null): string | null;
27
+ protected resolveType(typeName: string, context: FieldExtractorContext): string | null;
28
+ protected abstract extractVisibility(node: SyntaxNode): FieldVisibility;
29
+ }
@@ -0,0 +1,25 @@
1
+ // gitnexus/src/core/ingestion/field-extractor.ts
2
+ /**
3
+ * Base class for field extractors with common utilities
4
+ */
5
+ export class BaseFieldExtractor {
6
+ normalizeType(type) {
7
+ if (!type)
8
+ return null;
9
+ return type.trim().replace(/\s+/g, ' ');
10
+ }
11
+ resolveType(typeName, context) {
12
+ const { typeEnv, symbolTable, filePath } = context;
13
+ // Try to find in type environment (check file scope first)
14
+ const fileEnv = typeEnv.fileScope();
15
+ const local = fileEnv.get(typeName);
16
+ if (local)
17
+ return local;
18
+ // Try symbol table lookup in current file
19
+ const symbols = symbolTable.lookupExactAll(filePath, typeName);
20
+ if (symbols.length === 1) {
21
+ return symbols[0].nodeId;
22
+ }
23
+ return typeName;
24
+ }
25
+ }
@@ -0,0 +1,3 @@
1
+ import type { FieldExtractionConfig } from '../generic.js';
2
+ export declare const cppConfig: FieldExtractionConfig;
3
+ export declare const cConfig: FieldExtractionConfig;
@@ -0,0 +1,108 @@
1
+ // gitnexus/src/core/ingestion/field-extractors/configs/c-cpp.ts
2
+ import { SupportedLanguages } from '../../../../config/supported-languages.js';
3
+ import { hasKeyword } from './helpers.js';
4
+ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
5
+ /**
6
+ * Detect C++ access specifier (public:/private:/protected:) by walking
7
+ * backwards from the field node through siblings.
8
+ */
9
+ function cppAccessSpecifier(node) {
10
+ let sibling = node.previousNamedSibling;
11
+ while (sibling) {
12
+ if (sibling.type === 'access_specifier') {
13
+ const text = sibling.text.replace(':', '').trim();
14
+ if (text === 'public' || text === 'private' || text === 'protected')
15
+ return text;
16
+ }
17
+ sibling = sibling.previousNamedSibling;
18
+ }
19
+ return undefined;
20
+ }
21
+ function extractFieldName(node) {
22
+ // field_declaration > declarator:(field_identifier | pointer_declarator > field_identifier)
23
+ const declarator = node.childForFieldName('declarator');
24
+ if (declarator) {
25
+ if (declarator.type === 'field_identifier')
26
+ return declarator.text;
27
+ // pointer_declarator: *fieldName
28
+ for (let i = 0; i < declarator.namedChildCount; i++) {
29
+ const child = declarator.namedChild(i);
30
+ if (child?.type === 'field_identifier')
31
+ return child.text;
32
+ }
33
+ return declarator.text;
34
+ }
35
+ // fallback
36
+ for (let i = 0; i < node.namedChildCount; i++) {
37
+ const child = node.namedChild(i);
38
+ if (child?.type === 'field_identifier')
39
+ return child.text;
40
+ }
41
+ return undefined;
42
+ }
43
+ function extractFieldType(node) {
44
+ const typeNode = node.childForFieldName('type');
45
+ if (typeNode)
46
+ return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
47
+ // fallback: first child that is a type node
48
+ const first = node.firstNamedChild;
49
+ if (first && (first.type === 'type_identifier' || first.type === 'primitive_type'
50
+ || first.type === 'sized_type_specifier' || first.type === 'template_type')) {
51
+ return extractSimpleTypeName(first) ?? first.text?.trim();
52
+ }
53
+ return undefined;
54
+ }
55
+ // ---------------------------------------------------------------------------
56
+ // C++ config
57
+ // ---------------------------------------------------------------------------
58
+ export const cppConfig = {
59
+ language: SupportedLanguages.CPlusPlus,
60
+ typeDeclarationNodes: [
61
+ 'struct_specifier',
62
+ 'class_specifier',
63
+ 'union_specifier',
64
+ ],
65
+ fieldNodeTypes: ['field_declaration'],
66
+ bodyNodeTypes: ['field_declaration_list'],
67
+ defaultVisibility: 'private', // C++ class default is private
68
+ extractName: extractFieldName,
69
+ extractType: extractFieldType,
70
+ extractVisibility(node) {
71
+ const access = cppAccessSpecifier(node);
72
+ if (access)
73
+ return access;
74
+ // struct default = public, class default = private
75
+ const parent = node.parent?.parent;
76
+ return parent?.type === 'struct_specifier' ? 'public' : 'private';
77
+ },
78
+ isStatic(node) {
79
+ return hasKeyword(node, 'static');
80
+ },
81
+ isReadonly(node) {
82
+ return hasKeyword(node, 'const');
83
+ },
84
+ };
85
+ // ---------------------------------------------------------------------------
86
+ // C config (subset of C++)
87
+ // ---------------------------------------------------------------------------
88
+ export const cConfig = {
89
+ language: SupportedLanguages.C,
90
+ typeDeclarationNodes: [
91
+ 'struct_specifier',
92
+ 'union_specifier',
93
+ ],
94
+ fieldNodeTypes: ['field_declaration'],
95
+ bodyNodeTypes: ['field_declaration_list'],
96
+ defaultVisibility: 'public', // C structs are always public
97
+ extractName: extractFieldName,
98
+ extractType: extractFieldType,
99
+ extractVisibility(_node) {
100
+ return 'public'; // C has no access control
101
+ },
102
+ isStatic(node) {
103
+ return hasKeyword(node, 'static');
104
+ },
105
+ isReadonly(node) {
106
+ return hasKeyword(node, 'const');
107
+ },
108
+ };
@@ -0,0 +1,8 @@
1
+ import type { FieldExtractionConfig } from '../generic.js';
2
+ /**
3
+ * C# field extraction config.
4
+ *
5
+ * Handles field_declaration and property_declaration inside class/struct/interface bodies.
6
+ * The body node in tree-sitter-c-sharp is 'declaration_list'.
7
+ */
8
+ export declare const csharpConfig: FieldExtractionConfig;
@@ -0,0 +1,73 @@
1
+ // gitnexus/src/core/ingestion/field-extractors/configs/csharp.ts
2
+ import { SupportedLanguages } from '../../../../config/supported-languages.js';
3
+ import { findVisibility, hasKeyword, hasModifier } from './helpers.js';
4
+ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
5
+ const CSHARP_VIS = new Set(['public', 'private', 'protected', 'internal']);
6
+ /**
7
+ * C# field extraction config.
8
+ *
9
+ * Handles field_declaration and property_declaration inside class/struct/interface bodies.
10
+ * The body node in tree-sitter-c-sharp is 'declaration_list'.
11
+ */
12
+ export const csharpConfig = {
13
+ language: SupportedLanguages.CSharp,
14
+ typeDeclarationNodes: [
15
+ 'class_declaration',
16
+ 'struct_declaration',
17
+ 'interface_declaration',
18
+ 'record_declaration',
19
+ ],
20
+ fieldNodeTypes: ['field_declaration', 'property_declaration'],
21
+ bodyNodeTypes: ['declaration_list'],
22
+ defaultVisibility: 'private',
23
+ extractName(node) {
24
+ // field_declaration > variable_declaration > variable_declarator > identifier
25
+ for (let i = 0; i < node.namedChildCount; i++) {
26
+ const child = node.namedChild(i);
27
+ if (child?.type === 'variable_declaration') {
28
+ for (let j = 0; j < child.namedChildCount; j++) {
29
+ const declarator = child.namedChild(j);
30
+ if (declarator?.type === 'variable_declarator') {
31
+ const name = declarator.childForFieldName('name');
32
+ return name?.text ?? declarator.firstNamedChild?.text;
33
+ }
34
+ }
35
+ }
36
+ }
37
+ // property_declaration: name field
38
+ const nameNode = node.childForFieldName('name');
39
+ if (nameNode)
40
+ return nameNode.text;
41
+ return undefined;
42
+ },
43
+ extractType(node) {
44
+ // field_declaration > variable_declaration > type:(predefined_type | identifier | ...)
45
+ for (let i = 0; i < node.namedChildCount; i++) {
46
+ const child = node.namedChild(i);
47
+ if (child?.type === 'variable_declaration') {
48
+ const typeNode = child.childForFieldName('type');
49
+ if (typeNode)
50
+ return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
51
+ // fallback: first child that is a type
52
+ const first = child.firstNamedChild;
53
+ if (first && first.type !== 'variable_declarator') {
54
+ return extractSimpleTypeName(first) ?? first.text?.trim();
55
+ }
56
+ }
57
+ }
58
+ // property_declaration: type is first named child
59
+ const typeNode = node.childForFieldName('type');
60
+ if (typeNode)
61
+ return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
62
+ return undefined;
63
+ },
64
+ extractVisibility(node) {
65
+ return findVisibility(node, CSHARP_VIS, 'private', 'modifier');
66
+ },
67
+ isStatic(node) {
68
+ return hasKeyword(node, 'static') || hasModifier(node, 'modifier', 'static');
69
+ },
70
+ isReadonly(node) {
71
+ return hasKeyword(node, 'readonly') || hasModifier(node, 'modifier', 'readonly');
72
+ },
73
+ };
@@ -0,0 +1,8 @@
1
+ import type { FieldExtractionConfig } from '../generic.js';
2
+ /**
3
+ * Dart field extraction config.
4
+ *
5
+ * Dart class fields appear as declaration nodes inside class_body.
6
+ * Visibility is convention-based: underscore prefix = private.
7
+ */
8
+ export declare const dartConfig: FieldExtractionConfig;
@@ -0,0 +1,76 @@
1
+ // gitnexus/src/core/ingestion/field-extractors/configs/dart.ts
2
+ import { SupportedLanguages } from '../../../../config/supported-languages.js';
3
+ import { hasKeyword } from './helpers.js';
4
+ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
5
+ /**
6
+ * Dart field extraction config.
7
+ *
8
+ * Dart class fields appear as declaration nodes inside class_body.
9
+ * Visibility is convention-based: underscore prefix = private.
10
+ */
11
+ export const dartConfig = {
12
+ language: SupportedLanguages.Dart,
13
+ typeDeclarationNodes: ['class_definition'],
14
+ fieldNodeTypes: ['declaration'],
15
+ bodyNodeTypes: ['class_body'],
16
+ defaultVisibility: 'public',
17
+ extractName(node) {
18
+ // declaration > initialized_identifier_list > initialized_identifier > identifier
19
+ for (let i = 0; i < node.namedChildCount; i++) {
20
+ const child = node.namedChild(i);
21
+ if (child?.type === 'initialized_identifier_list') {
22
+ for (let j = 0; j < child.namedChildCount; j++) {
23
+ const init = child.namedChild(j);
24
+ if (init?.type === 'initialized_identifier') {
25
+ const ident = init.firstNamedChild;
26
+ if (ident?.type === 'identifier')
27
+ return ident.text;
28
+ }
29
+ }
30
+ }
31
+ if (child?.type === 'initialized_identifier') {
32
+ const ident = child.firstNamedChild;
33
+ if (ident?.type === 'identifier')
34
+ return ident.text;
35
+ }
36
+ }
37
+ // fallback: look for direct identifier
38
+ const name = node.childForFieldName('name');
39
+ return name?.text;
40
+ },
41
+ extractType(node) {
42
+ // declaration > type_identifier (first named child usually)
43
+ for (let i = 0; i < node.namedChildCount; i++) {
44
+ const child = node.namedChild(i);
45
+ if (child && (child.type === 'type_identifier' || child.type === 'generic_type'
46
+ || child.type === 'function_type')) {
47
+ return extractSimpleTypeName(child) ?? child.text?.trim();
48
+ }
49
+ }
50
+ return undefined;
51
+ },
52
+ extractVisibility(node) {
53
+ // Dart uses _ prefix for private
54
+ // Walk to find the identifier name
55
+ for (let i = 0; i < node.namedChildCount; i++) {
56
+ const child = node.namedChild(i);
57
+ if (child?.type === 'initialized_identifier_list') {
58
+ for (let j = 0; j < child.namedChildCount; j++) {
59
+ const init = child.namedChild(j);
60
+ if (init?.type === 'initialized_identifier') {
61
+ const ident = init.firstNamedChild;
62
+ if (ident?.text?.startsWith('_'))
63
+ return 'private';
64
+ }
65
+ }
66
+ }
67
+ }
68
+ return 'public';
69
+ },
70
+ isStatic(node) {
71
+ return hasKeyword(node, 'static');
72
+ },
73
+ isReadonly(node) {
74
+ return hasKeyword(node, 'final') || hasKeyword(node, 'const');
75
+ },
76
+ };
@@ -0,0 +1,11 @@
1
+ import type { FieldExtractionConfig } from '../generic.js';
2
+ /**
3
+ * Go field extraction config.
4
+ *
5
+ * Go struct fields live inside type_declaration > type_spec > struct_type >
6
+ * field_declaration_list > field_declaration.
7
+ *
8
+ * Visibility in Go is based on the first character: uppercase = exported (public),
9
+ * lowercase = unexported (package).
10
+ */
11
+ export declare const goConfig: FieldExtractionConfig;