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
@@ -1,6 +1,5 @@
1
- import { SupportedLanguages } from '../../config/supported-languages.js';
2
- import { generateId } from '../../lib/utils.js';
3
- import { extractSimpleTypeName } from './type-extractors/shared.js';
1
+ import { generateId } from '../../../lib/utils.js';
2
+ import { extractSimpleTypeName } from '../type-extractors/shared.js';
4
3
  /**
5
4
  * Ordered list of definition capture keys for tree-sitter query matches.
6
5
  * Used to extract the definition node from a capture map.
@@ -75,6 +74,9 @@ export const FUNCTION_NODE_TYPES = new Set([
75
74
  // Ruby
76
75
  'method', // def foo
77
76
  'singleton_method', // def self.foo
77
+ // Dart
78
+ 'function_signature',
79
+ 'method_signature',
78
80
  ]);
79
81
  /**
80
82
  * Node types for standard function declarations that need C/C++ declarator handling.
@@ -135,39 +137,23 @@ export function isKotlinClassMethod(captureNode) {
135
137
  }
136
138
  return false;
137
139
  }
138
- /**
139
- * C/C++: check if a Function capture is inside a class/struct body.
140
- * If true, the function is already captured by @definition.method and should be skipped
141
- * to prevent double-indexing in globalIndex.
142
- */
143
- export function isCppDuplicateClassFunction(functionNode, nodeLabel, language) {
144
- if (nodeLabel !== 'Function')
145
- return false;
146
- if (language !== SupportedLanguages.CPlusPlus && language !== SupportedLanguages.C)
147
- return false;
148
- let ancestor = functionNode?.parent;
149
- while (ancestor) {
150
- if (ancestor.type === 'class_specifier' || ancestor.type === 'struct_specifier')
151
- return true;
152
- ancestor = ancestor.parent;
153
- }
154
- return false;
155
- }
156
140
  /**
157
141
  * Determine the graph node label from a tree-sitter capture map.
158
- * Handles language-specific reclassification (C/C++ duplicate skipping, Kotlin Method promotion).
142
+ * Handles language-specific reclassification via the provider's labelOverride hook
143
+ * (e.g. C/C++ duplicate skipping, Kotlin Method promotion).
159
144
  * Returns null if the capture should be skipped (import, call, C/C++ duplicate, missing name).
160
145
  */
161
- export function getLabelFromCaptures(captureMap, language) {
146
+ export function getLabelFromCaptures(captureMap, provider) {
162
147
  if (captureMap['import'] || captureMap['call'])
163
148
  return null;
164
149
  if (!captureMap['name'] && !captureMap['definition.constructor'])
165
150
  return null;
166
151
  if (captureMap['definition.function']) {
167
- if (isCppDuplicateClassFunction(captureMap['definition.function'], 'Function', language))
168
- return null;
169
- if (language === SupportedLanguages.Kotlin && isKotlinClassMethod(captureMap['definition.function']))
170
- return 'Method';
152
+ if (provider.labelOverride) {
153
+ const override = provider.labelOverride(captureMap['definition.function'], 'Function');
154
+ if (override !== 'Function')
155
+ return override;
156
+ }
171
157
  return 'Function';
172
158
  }
173
159
  if (captureMap['definition.class'])
@@ -410,11 +396,6 @@ export const extractFunctionName = (node) => {
410
396
  }
411
397
  }
412
398
  funcName = nameNode?.text;
413
- // Kotlin: function_declaration inside a class_body is a method, not a top-level function.
414
- // Must match the label assigned in parse-worker.ts for consistent generateId() output.
415
- if (funcName && node.type === 'function_declaration' && isKotlinClassMethod(node)) {
416
- label = 'Method';
417
- }
418
399
  }
419
400
  }
420
401
  else if (node.type === 'impl_item') {
@@ -499,6 +480,45 @@ export const extractFunctionName = (node) => {
499
480
  funcName = nameNode?.text;
500
481
  label = 'Method';
501
482
  }
483
+ else if (node.type === 'function_signature') {
484
+ // Dart: top-level function signatures
485
+ let nameNode = node.childForFieldName?.('name');
486
+ if (!nameNode) {
487
+ for (let i = 0; i < node.childCount; i++) {
488
+ const c = node.child(i);
489
+ if (c?.type === 'identifier') {
490
+ nameNode = c;
491
+ break;
492
+ }
493
+ }
494
+ }
495
+ funcName = nameNode?.text ?? null;
496
+ }
497
+ else if (node.type === 'method_signature') {
498
+ // Dart: method_signature wraps function_signature
499
+ let funcSig = null;
500
+ for (let i = 0; i < node.childCount; i++) {
501
+ const c = node.child(i);
502
+ if (c?.type === 'function_signature') {
503
+ funcSig = c;
504
+ break;
505
+ }
506
+ }
507
+ if (funcSig) {
508
+ let nameNode = funcSig.childForFieldName?.('name');
509
+ if (!nameNode) {
510
+ for (let i = 0; i < funcSig.childCount; i++) {
511
+ const c = funcSig.child(i);
512
+ if (c?.type === 'identifier') {
513
+ nameNode = c;
514
+ break;
515
+ }
516
+ }
517
+ }
518
+ funcName = nameNode?.text ?? null;
519
+ }
520
+ label = 'Method';
521
+ }
502
522
  return { funcName, label };
503
523
  };
504
524
  /** Argument list node types shared between extractMethodSignature and countCallArguments. */
@@ -522,6 +542,7 @@ export const extractMethodSignature = (node) => {
522
542
  const paramListTypes = new Set([
523
543
  'formal_parameters', 'parameters', 'parameter_list',
524
544
  'function_parameters', 'method_parameters', 'function_value_parameters',
545
+ 'formal_parameter_list', // Dart
525
546
  ]);
526
547
  // Node types that indicate variadic/rest parameters
527
548
  const VARIADIC_PARAM_TYPES = new Set([
@@ -654,6 +675,18 @@ export const extractMethodSignature = (node) => {
654
675
  }
655
676
  }
656
677
  }
678
+ // Swift fallback: tree-sitter-swift places `parameter` nodes as direct children of
679
+ // function_declaration without a wrapping parameters/function_parameters list node.
680
+ // When no parameter list was found, count direct `parameter` children on the node.
681
+ if (!parameterList && parameterCount === 0) {
682
+ for (const child of node.namedChildren) {
683
+ if (child.type === 'parameter') {
684
+ if (!hasDefaultValue(child))
685
+ requiredCount++;
686
+ parameterCount++;
687
+ }
688
+ }
689
+ }
657
690
  // Return type extraction — language-specific field names
658
691
  // Go: 'result' field is either a type_identifier or parameter_list (multi-return)
659
692
  const goResult = node.childForFieldName?.('result');
@@ -736,3 +769,49 @@ export const extractMethodSignature = (node) => {
736
769
  ? requiredCount : undefined;
737
770
  return { parameterCount, requiredParameterCount, parameterTypes: hasTypes ? paramTypes : undefined, returnType };
738
771
  };
772
+ // ============================================================================
773
+ // Generic AST traversal helpers (shared by parse-worker + php-helpers)
774
+ // ============================================================================
775
+ /** Walk an AST node depth-first, returning the first descendant with the given type. */
776
+ export function findDescendant(node, type) {
777
+ if (node.type === type)
778
+ return node;
779
+ for (const child of (node.children ?? [])) {
780
+ const found = findDescendant(child, type);
781
+ if (found)
782
+ return found;
783
+ }
784
+ return null;
785
+ }
786
+ /** Extract the text content from a string or encapsed_string AST node. */
787
+ export function extractStringContent(node) {
788
+ if (!node)
789
+ return null;
790
+ const content = node.children?.find((c) => c.type === 'string_content');
791
+ if (content)
792
+ return content.text;
793
+ if (node.type === 'string_content')
794
+ return node.text;
795
+ return null;
796
+ }
797
+ /** Check if a C/C++ function_definition is inside a class or struct body.
798
+ * Used by the C/C++ labelOverride to skip duplicate function captures
799
+ * that are already covered by definition.method queries. */
800
+ export function isCppInsideClassOrStruct(functionNode) {
801
+ let ancestor = functionNode?.parent ?? null;
802
+ while (ancestor) {
803
+ if (ancestor.type === 'class_specifier' || ancestor.type === 'struct_specifier')
804
+ return true;
805
+ ancestor = ancestor.parent;
806
+ }
807
+ return false;
808
+ }
809
+ /** Find the first direct named child of a tree-sitter node matching the given type. */
810
+ export function findChild(node, type) {
811
+ for (let i = 0; i < node.namedChildCount; i++) {
812
+ const child = node.namedChild(i);
813
+ if (child?.type === type)
814
+ return child;
815
+ }
816
+ return null;
817
+ }
@@ -61,6 +61,7 @@ const MEMBER_ACCESS_NODE_TYPES = new Set([
61
61
  'selector_expression', // Go: obj.Method()
62
62
  'navigation_suffix', // Kotlin/Swift: obj.method() — nameNode sits inside navigation_suffix
63
63
  'member_binding_expression', // C#: user?.Method() — null-conditional access
64
+ 'unconditional_assignable_selector', // Dart: obj.method() — nameNode inside selector > unconditional_assignable_selector
64
65
  ]);
65
66
  /**
66
67
  * Call node types that are inherently constructor invocations.
@@ -179,6 +180,15 @@ export const extractReceiverName = (nameNode) => {
179
180
  receiver = receiver.firstChild;
180
181
  }
181
182
  }
183
+ // Dart: unconditional_assignable_selector is inside a `selector`, which is a sibling
184
+ // of the receiver in the expression_statement. For `user.save()`, the previous named
185
+ // sibling of the `selector` is `identifier [user]`.
186
+ if (!receiver && parent.type === 'unconditional_assignable_selector') {
187
+ const selectorNode = parent.parent; // selector [.save]
188
+ if (selectorNode) {
189
+ receiver = selectorNode.previousNamedSibling;
190
+ }
191
+ }
182
192
  // C# null-conditional: user?.Save() → conditional_access_expression wraps member_binding_expression
183
193
  if (!receiver && parent.type === 'member_binding_expression') {
184
194
  const condAccess = parent.parent;
@@ -249,6 +259,13 @@ export const extractReceiverNode = (nameNode) => {
249
259
  receiver = receiver.firstChild;
250
260
  }
251
261
  }
262
+ // Dart: unconditional_assignable_selector — receiver is previous sibling of the selector
263
+ if (!receiver && parent.type === 'unconditional_assignable_selector') {
264
+ const selectorNode = parent.parent;
265
+ if (selectorNode) {
266
+ receiver = selectorNode.previousNamedSibling;
267
+ }
268
+ }
252
269
  if (!receiver && parent.type === 'member_binding_expression') {
253
270
  const condAccess = parent.parent;
254
271
  if (condAccess?.type === 'conditional_access_expression') {
@@ -479,6 +496,26 @@ export function extractMixedChain(receiverNode) {
479
496
  return { chain, baseReceiverName: innerObject.text || undefined };
480
497
  }
481
498
  }
499
+ else if (current.type === 'selector') {
500
+ // ── Dart: flat selector siblings (user.address.save() uses selector nodes) ──
501
+ // Extract field name from unconditional_assignable_selector child
502
+ const uas = current.namedChildren?.find((c) => c.type === 'unconditional_assignable_selector');
503
+ const propertyName = uas?.namedChildren?.find((c) => c.type === 'identifier')?.text;
504
+ if (!propertyName)
505
+ break;
506
+ chain.unshift({ kind: 'field', name: propertyName });
507
+ // Walk to previous sibling for the next step in the chain
508
+ const prev = current.previousNamedSibling;
509
+ if (!prev)
510
+ break;
511
+ if (prev.type === 'selector') {
512
+ current = prev;
513
+ }
514
+ else {
515
+ // Base receiver (identifier or other terminal)
516
+ return { chain, baseReceiverName: prev.text || undefined };
517
+ }
518
+ }
482
519
  else {
483
520
  // Simple identifier — this is the base receiver
484
521
  return chain.length > 0
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Yield control to the event loop so spinners/progress can render.
3
+ * Call periodically in hot loops to prevent UI freezes.
4
+ */
5
+ export declare const yieldToEventLoop: () => Promise<void>;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Yield control to the event loop so spinners/progress can render.
3
+ * Call periodically in hot loops to prevent UI freezes.
4
+ */
5
+ export const yieldToEventLoop = () => new Promise(resolve => setImmediate(resolve));
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Language Detection — maps file paths to SupportedLanguages enum values.
3
+ */
4
+ import { SupportedLanguages } from '../../../config/supported-languages.js';
5
+ /**
6
+ * Map file extension to SupportedLanguage enum.
7
+ * Returns null if the file extension is not recognized.
8
+ */
9
+ export declare const getLanguageFromFilename: (filename: string) => SupportedLanguages | null;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Language Detection — maps file paths to SupportedLanguages enum values.
3
+ */
4
+ import { SupportedLanguages } from '../../../config/supported-languages.js';
5
+ /** Ruby extensionless filenames recognised as Ruby source */
6
+ const RUBY_EXTENSIONLESS_FILES = new Set(['Rakefile', 'Gemfile', 'Guardfile', 'Vagrantfile', 'Brewfile']);
7
+ /**
8
+ * Map file extension to SupportedLanguage enum.
9
+ * Returns null if the file extension is not recognized.
10
+ */
11
+ export const getLanguageFromFilename = (filename) => {
12
+ // TypeScript (including TSX)
13
+ if (filename.endsWith('.tsx'))
14
+ return SupportedLanguages.TypeScript;
15
+ if (filename.endsWith('.ts'))
16
+ return SupportedLanguages.TypeScript;
17
+ // JavaScript (including JSX)
18
+ if (filename.endsWith('.jsx'))
19
+ return SupportedLanguages.JavaScript;
20
+ if (filename.endsWith('.js'))
21
+ return SupportedLanguages.JavaScript;
22
+ // Python
23
+ if (filename.endsWith('.py'))
24
+ return SupportedLanguages.Python;
25
+ // Java
26
+ if (filename.endsWith('.java'))
27
+ return SupportedLanguages.Java;
28
+ // C source files
29
+ if (filename.endsWith('.c'))
30
+ return SupportedLanguages.C;
31
+ // C++ (all common extensions, including .h)
32
+ // .h is parsed as C++ because tree-sitter-cpp is a strict superset of C, so pure-C
33
+ // headers parse correctly, and C++ headers (classes, templates) are handled properly.
34
+ if (filename.endsWith('.cpp') || filename.endsWith('.cc') || filename.endsWith('.cxx') ||
35
+ filename.endsWith('.h') || filename.endsWith('.hpp') || filename.endsWith('.hxx') || filename.endsWith('.hh'))
36
+ return SupportedLanguages.CPlusPlus;
37
+ // C#
38
+ if (filename.endsWith('.cs'))
39
+ return SupportedLanguages.CSharp;
40
+ // Go
41
+ if (filename.endsWith('.go'))
42
+ return SupportedLanguages.Go;
43
+ // Rust
44
+ if (filename.endsWith('.rs'))
45
+ return SupportedLanguages.Rust;
46
+ // Kotlin
47
+ if (filename.endsWith('.kt') || filename.endsWith('.kts'))
48
+ return SupportedLanguages.Kotlin;
49
+ // PHP (all common extensions)
50
+ if (filename.endsWith('.php') || filename.endsWith('.phtml') ||
51
+ filename.endsWith('.php3') || filename.endsWith('.php4') ||
52
+ filename.endsWith('.php5') || filename.endsWith('.php8')) {
53
+ return SupportedLanguages.PHP;
54
+ }
55
+ // Ruby (extensions)
56
+ if (filename.endsWith('.rb') || filename.endsWith('.rake') || filename.endsWith('.gemspec')) {
57
+ return SupportedLanguages.Ruby;
58
+ }
59
+ // Ruby (extensionless files)
60
+ const basename = filename.split('/').pop() || filename;
61
+ if (RUBY_EXTENSIONLESS_FILES.has(basename)) {
62
+ return SupportedLanguages.Ruby;
63
+ }
64
+ // Swift (extensions)
65
+ if (filename.endsWith('.swift'))
66
+ return SupportedLanguages.Swift;
67
+ if (filename.endsWith('.dart'))
68
+ return SupportedLanguages.Dart;
69
+ return null;
70
+ };
@@ -0,0 +1 @@
1
+ export declare const isVerboseIngestionEnabled: () => boolean;
@@ -0,0 +1,7 @@
1
+ export const isVerboseIngestionEnabled = () => {
2
+ const raw = process.env.GITNEXUS_VERBOSE;
3
+ if (!raw)
4
+ return false;
5
+ const value = raw.toLowerCase();
6
+ return value === '1' || value === 'true' || value === 'yes';
7
+ };
@@ -1,7 +1,7 @@
1
1
  import { SupportedLanguages } from '../../../config/supported-languages.js';
2
- import { type MixedChainStep } from '../utils.js';
2
+ import { type MixedChainStep } from '../utils/call-analysis.js';
3
3
  import type { ConstructorBinding } from '../type-env.js';
4
- import type { NamedBinding } from '../import-resolution.js';
4
+ import type { NamedBinding } from '../named-bindings/types.js';
5
5
  import type { NodeLabel } from '../../graph/types.js';
6
6
  interface ParsedNode {
7
7
  id: string;
@@ -19,6 +19,10 @@ interface ParsedNode {
19
19
  parameterCount?: number;
20
20
  requiredParameterCount?: number;
21
21
  returnType?: string;
22
+ declaredType?: string;
23
+ visibility?: string;
24
+ isStatic?: boolean;
25
+ isReadonly?: boolean;
22
26
  };
23
27
  }
24
28
  interface ParsedRelationship {
@@ -40,6 +44,9 @@ interface ParsedSymbol {
40
44
  returnType?: string;
41
45
  declaredType?: string;
42
46
  ownerId?: string;
47
+ visibility?: string;
48
+ isStatic?: boolean;
49
+ isReadonly?: boolean;
43
50
  }
44
51
  export interface ExtractedImport {
45
52
  filePath: string;
@@ -98,6 +105,31 @@ export interface ExtractedRoute {
98
105
  prefix: string | null;
99
106
  lineNumber: number;
100
107
  }
108
+ export interface ExtractedFetchCall {
109
+ filePath: string;
110
+ fetchURL: string;
111
+ lineNumber: number;
112
+ }
113
+ export interface ExtractedDecoratorRoute {
114
+ filePath: string;
115
+ routePath: string;
116
+ httpMethod: string;
117
+ decoratorName: string;
118
+ lineNumber: number;
119
+ }
120
+ export interface ExtractedToolDef {
121
+ filePath: string;
122
+ toolName: string;
123
+ description: string;
124
+ lineNumber: number;
125
+ }
126
+ export interface ExtractedORMQuery {
127
+ filePath: string;
128
+ orm: 'prisma' | 'supabase';
129
+ model: string;
130
+ method: string;
131
+ lineNumber: number;
132
+ }
101
133
  /** Constructor bindings keyed by filePath for cross-file type resolution */
102
134
  export interface FileConstructorBindings {
103
135
  filePath: string;
@@ -118,6 +150,10 @@ export interface ParseWorkerResult {
118
150
  assignments: ExtractedAssignment[];
119
151
  heritage: ExtractedHeritage[];
120
152
  routes: ExtractedRoute[];
153
+ fetchCalls: ExtractedFetchCall[];
154
+ decoratorRoutes: ExtractedDecoratorRoute[];
155
+ toolDefs: ExtractedToolDef[];
156
+ ormQueries: ExtractedORMQuery[];
121
157
  constructorBindings: FileConstructorBindings[];
122
158
  /** File-scope type bindings from TypeEnv fixpoint for exported symbol collection. */
123
159
  typeEnvBindings: FileTypeEnvBindings[];
@@ -128,4 +164,9 @@ export interface ParseWorkerInput {
128
164
  path: string;
129
165
  content: string;
130
166
  }
167
+ /**
168
+ * Extract ORM query calls from file content via regex.
169
+ * Appends results to the provided array (avoids allocation when no matches).
170
+ */
171
+ export declare function extractORMQueries(filePath: string, content: string, out: ExtractedORMQuery[]): void;
131
172
  export {};