gitnexus 1.4.8 → 1.4.10

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 +14 -14
  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
@@ -0,0 +1,64 @@
1
+ // gitnexus/src/core/ingestion/field-extractors/configs/go.ts
2
+ import { SupportedLanguages } from '../../../../config/supported-languages.js';
3
+ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
4
+ /**
5
+ * Go field extraction config.
6
+ *
7
+ * Go struct fields live inside type_declaration > type_spec > struct_type >
8
+ * field_declaration_list > field_declaration.
9
+ *
10
+ * Visibility in Go is based on the first character: uppercase = exported (public),
11
+ * lowercase = unexported (package).
12
+ */
13
+ export const goConfig = {
14
+ language: SupportedLanguages.Go,
15
+ typeDeclarationNodes: [
16
+ 'type_declaration',
17
+ ],
18
+ fieldNodeTypes: ['field_declaration'],
19
+ bodyNodeTypes: ['field_declaration_list'],
20
+ defaultVisibility: 'package',
21
+ extractName(node) {
22
+ // field_declaration > name:(field_identifier)
23
+ const name = node.childForFieldName('name');
24
+ if (name)
25
+ return name.text;
26
+ // fallback: first field_identifier child
27
+ for (let i = 0; i < node.namedChildCount; i++) {
28
+ const child = node.namedChild(i);
29
+ if (child?.type === 'field_identifier')
30
+ return child.text;
31
+ }
32
+ return undefined;
33
+ },
34
+ extractType(node) {
35
+ // field_declaration > type:(type_identifier | pointer_type | ...)
36
+ const typeNode = node.childForFieldName('type');
37
+ if (typeNode)
38
+ return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
39
+ // fallback: second named child is usually the type
40
+ if (node.namedChildCount >= 2) {
41
+ const t = node.namedChild(1);
42
+ if (t)
43
+ return extractSimpleTypeName(t) ?? t.text?.trim();
44
+ }
45
+ return undefined;
46
+ },
47
+ extractVisibility(node) {
48
+ const name = node.childForFieldName('name');
49
+ const text = name?.text;
50
+ if (text && text.length > 0) {
51
+ const first = text.charAt(0);
52
+ return first === first.toUpperCase() && first !== first.toLowerCase()
53
+ ? 'public'
54
+ : 'package';
55
+ }
56
+ return 'package';
57
+ },
58
+ isStatic(_node) {
59
+ return false; // Go has no static fields
60
+ },
61
+ isReadonly(_node) {
62
+ return false; // Go fields are not readonly
63
+ },
64
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Shared AST-walking helpers used by multiple language configs.
3
+ * Keeps individual config files small.
4
+ */
5
+ import type { SyntaxNode } from '../../utils/ast-helpers.js';
6
+ import type { FieldVisibility } from '../../field-types.js';
7
+ /**
8
+ * Check whether any child of `node` (named or unnamed) has .text matching
9
+ * one of the given `keywords`.
10
+ */
11
+ export declare function hasKeyword(node: SyntaxNode, keyword: string): boolean;
12
+ /**
13
+ * Check whether a named child of type `modifierType` contains `keyword`.
14
+ * Useful for languages that group modifiers under a wrapper node
15
+ * (e.g. Java 'modifiers', Kotlin 'modifiers').
16
+ */
17
+ export declare function hasModifier(node: SyntaxNode, modifierType: string, keyword: string): boolean;
18
+ /**
19
+ * Return the first matching visibility keyword found either as a direct keyword
20
+ * child or inside a modifier wrapper node.
21
+ */
22
+ export declare function findVisibility(node: SyntaxNode, keywords: ReadonlySet<FieldVisibility>, defaultVis: FieldVisibility, modifierNodeType?: string): FieldVisibility;
23
+ /**
24
+ * Extract the text of the first named child whose type is in `types`.
25
+ */
26
+ export declare function firstChildText(node: SyntaxNode, types: ReadonlySet<string>): string | undefined;
27
+ /**
28
+ * Extract the first named child node whose type is in `types`.
29
+ */
30
+ export declare function firstChildOfType(node: SyntaxNode, types: ReadonlySet<string>): SyntaxNode | null;
31
+ /**
32
+ * Get type text from a named field on the node, using extractSimpleTypeName.
33
+ * Falls back to raw .text of the field child if extractSimpleTypeName returns undefined.
34
+ */
35
+ export declare function typeFromField(node: SyntaxNode, fieldName: string): string | undefined;
36
+ /**
37
+ * Walk named children looking for a type_annotation node and extract its type.
38
+ */
39
+ export declare function typeFromAnnotation(node: SyntaxNode): string | undefined;
40
+ /**
41
+ * Find the first descendant (depth-first, one level) matching one of the given types
42
+ * and return its text via extractSimpleTypeName.
43
+ */
44
+ export declare function typeFromDescendant(node: SyntaxNode, types: ReadonlySet<string>): string | undefined;
@@ -0,0 +1,134 @@
1
+ // gitnexus/src/core/ingestion/field-extractors/configs/helpers.ts
2
+ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Modifier scanning
5
+ // ---------------------------------------------------------------------------
6
+ /**
7
+ * Check whether any child of `node` (named or unnamed) has .text matching
8
+ * one of the given `keywords`.
9
+ */
10
+ export function hasKeyword(node, keyword) {
11
+ for (let i = 0; i < node.childCount; i++) {
12
+ const child = node.child(i);
13
+ if (child && child.text.trim() === keyword)
14
+ return true;
15
+ }
16
+ return false;
17
+ }
18
+ /**
19
+ * Check whether a named child of type `modifierType` contains `keyword`.
20
+ * Useful for languages that group modifiers under a wrapper node
21
+ * (e.g. Java 'modifiers', Kotlin 'modifiers').
22
+ */
23
+ export function hasModifier(node, modifierType, keyword) {
24
+ for (let i = 0; i < node.namedChildCount; i++) {
25
+ const child = node.namedChild(i);
26
+ if (child && child.type === modifierType) {
27
+ for (let j = 0; j < child.childCount; j++) {
28
+ const mod = child.child(j);
29
+ if (mod && mod.text.trim() === keyword)
30
+ return true;
31
+ }
32
+ }
33
+ }
34
+ return false;
35
+ }
36
+ /**
37
+ * Return the first matching visibility keyword found either as a direct keyword
38
+ * child or inside a modifier wrapper node.
39
+ */
40
+ export function findVisibility(node, keywords, defaultVis, modifierNodeType) {
41
+ // Direct keyword children
42
+ for (let i = 0; i < node.childCount; i++) {
43
+ const child = node.child(i);
44
+ const text = child?.text.trim();
45
+ if (text && keywords.has(text))
46
+ return text;
47
+ }
48
+ // Modifier wrapper
49
+ if (modifierNodeType) {
50
+ for (let i = 0; i < node.namedChildCount; i++) {
51
+ const child = node.namedChild(i);
52
+ if (child && child.type === modifierNodeType) {
53
+ for (let j = 0; j < child.childCount; j++) {
54
+ const mod = child.child(j);
55
+ const modText = mod?.text.trim();
56
+ if (modText && keywords.has(modText))
57
+ return modText;
58
+ }
59
+ }
60
+ }
61
+ }
62
+ return defaultVis;
63
+ }
64
+ // ---------------------------------------------------------------------------
65
+ // Name and type extraction
66
+ // ---------------------------------------------------------------------------
67
+ /**
68
+ * Extract the text of the first named child whose type is in `types`.
69
+ */
70
+ export function firstChildText(node, types) {
71
+ for (let i = 0; i < node.namedChildCount; i++) {
72
+ const child = node.namedChild(i);
73
+ if (child && types.has(child.type))
74
+ return child.text;
75
+ }
76
+ return undefined;
77
+ }
78
+ /**
79
+ * Extract the first named child node whose type is in `types`.
80
+ */
81
+ export function firstChildOfType(node, types) {
82
+ for (let i = 0; i < node.namedChildCount; i++) {
83
+ const child = node.namedChild(i);
84
+ if (child && types.has(child.type))
85
+ return child;
86
+ }
87
+ return null;
88
+ }
89
+ /**
90
+ * Get type text from a named field on the node, using extractSimpleTypeName.
91
+ * Falls back to raw .text of the field child if extractSimpleTypeName returns undefined.
92
+ */
93
+ export function typeFromField(node, fieldName) {
94
+ const typeNode = node.childForFieldName(fieldName);
95
+ if (!typeNode)
96
+ return undefined;
97
+ return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
98
+ }
99
+ /**
100
+ * Walk named children looking for a type_annotation node and extract its type.
101
+ */
102
+ export function typeFromAnnotation(node) {
103
+ for (let i = 0; i < node.namedChildCount; i++) {
104
+ const child = node.namedChild(i);
105
+ if (child && child.type === 'type_annotation') {
106
+ const inner = child.firstNamedChild;
107
+ if (inner)
108
+ return extractSimpleTypeName(inner) ?? inner.text?.trim();
109
+ }
110
+ }
111
+ return undefined;
112
+ }
113
+ /**
114
+ * Find the first descendant (depth-first, one level) matching one of the given types
115
+ * and return its text via extractSimpleTypeName.
116
+ */
117
+ export function typeFromDescendant(node, types) {
118
+ for (let i = 0; i < node.namedChildCount; i++) {
119
+ const child = node.namedChild(i);
120
+ if (!child)
121
+ continue;
122
+ if (types.has(child.type)) {
123
+ return extractSimpleTypeName(child) ?? child.text?.trim();
124
+ }
125
+ // one more level
126
+ for (let j = 0; j < child.namedChildCount; j++) {
127
+ const grandchild = child.namedChild(j);
128
+ if (grandchild && types.has(grandchild.type)) {
129
+ return extractSimpleTypeName(grandchild) ?? grandchild.text?.trim();
130
+ }
131
+ }
132
+ }
133
+ return undefined;
134
+ }
@@ -0,0 +1,3 @@
1
+ import type { FieldExtractionConfig } from '../generic.js';
2
+ export declare const javaConfig: FieldExtractionConfig;
3
+ export declare const kotlinConfig: FieldExtractionConfig;
@@ -0,0 +1,118 @@
1
+ // gitnexus/src/core/ingestion/field-extractors/configs/jvm.ts
2
+ import { SupportedLanguages } from '../../../../config/supported-languages.js';
3
+ import { findVisibility, hasKeyword, hasModifier, typeFromField } from './helpers.js';
4
+ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
5
+ // ---------------------------------------------------------------------------
6
+ // Java
7
+ // ---------------------------------------------------------------------------
8
+ const JAVA_VIS = new Set(['public', 'private', 'protected']);
9
+ export const javaConfig = {
10
+ language: SupportedLanguages.Java,
11
+ typeDeclarationNodes: [
12
+ 'class_declaration',
13
+ 'interface_declaration',
14
+ 'enum_declaration',
15
+ 'record_declaration',
16
+ ],
17
+ fieldNodeTypes: ['field_declaration'],
18
+ bodyNodeTypes: ['class_body', 'interface_body', 'enum_body'],
19
+ defaultVisibility: 'package',
20
+ extractName(node) {
21
+ // field_declaration > declarator:(variable_declarator name:(identifier))
22
+ const declarator = node.childForFieldName('declarator');
23
+ if (declarator) {
24
+ const name = declarator.childForFieldName('name');
25
+ return name?.text;
26
+ }
27
+ // fallback: walk children for variable_declarator
28
+ for (let i = 0; i < node.namedChildCount; i++) {
29
+ const child = node.namedChild(i);
30
+ if (child?.type === 'variable_declarator') {
31
+ const name = child.childForFieldName('name');
32
+ return name?.text;
33
+ }
34
+ }
35
+ return undefined;
36
+ },
37
+ extractType(node) {
38
+ // field_declaration > type:(type_identifier|generic_type|...)
39
+ const t = typeFromField(node, 'type');
40
+ if (t)
41
+ return t;
42
+ // fallback: first named child that looks like a type
43
+ const first = node.firstNamedChild;
44
+ if (first && first.type !== 'modifiers') {
45
+ return extractSimpleTypeName(first) ?? first.text?.trim();
46
+ }
47
+ return undefined;
48
+ },
49
+ extractVisibility(node) {
50
+ return findVisibility(node, JAVA_VIS, 'package', 'modifiers');
51
+ },
52
+ isStatic(node) {
53
+ return hasKeyword(node, 'static') || hasModifier(node, 'modifiers', 'static');
54
+ },
55
+ isReadonly(node) {
56
+ return hasKeyword(node, 'final') || hasModifier(node, 'modifiers', 'final');
57
+ },
58
+ };
59
+ // ---------------------------------------------------------------------------
60
+ // Kotlin
61
+ // ---------------------------------------------------------------------------
62
+ const KOTLIN_VIS = new Set(['public', 'private', 'protected', 'internal']);
63
+ export const kotlinConfig = {
64
+ language: SupportedLanguages.Kotlin,
65
+ typeDeclarationNodes: [
66
+ 'class_declaration',
67
+ 'object_declaration',
68
+ ],
69
+ fieldNodeTypes: ['property_declaration'],
70
+ bodyNodeTypes: ['class_body'],
71
+ defaultVisibility: 'public',
72
+ extractName(node) {
73
+ // property_declaration > variable_declaration > simple_identifier
74
+ for (let i = 0; i < node.namedChildCount; i++) {
75
+ const child = node.namedChild(i);
76
+ if (child?.type === 'variable_declaration') {
77
+ for (let j = 0; j < child.namedChildCount; j++) {
78
+ const ident = child.namedChild(j);
79
+ if (ident?.type === 'simple_identifier')
80
+ return ident.text;
81
+ }
82
+ }
83
+ if (child?.type === 'simple_identifier')
84
+ return child.text;
85
+ }
86
+ return undefined;
87
+ },
88
+ extractType(node) {
89
+ // property_declaration may have a user_type or type_identifier under variable_declaration
90
+ for (let i = 0; i < node.namedChildCount; i++) {
91
+ const child = node.namedChild(i);
92
+ if (child?.type === 'variable_declaration') {
93
+ for (let j = 0; j < child.namedChildCount; j++) {
94
+ const t = child.namedChild(j);
95
+ if (t && (t.type === 'user_type' || t.type === 'type_identifier'
96
+ || t.type === 'nullable_type' || t.type === 'generic_type')) {
97
+ return extractSimpleTypeName(t) ?? t.text?.trim();
98
+ }
99
+ }
100
+ }
101
+ if (child?.type === 'user_type' || child?.type === 'nullable_type') {
102
+ return extractSimpleTypeName(child) ?? child.text?.trim();
103
+ }
104
+ }
105
+ return undefined;
106
+ },
107
+ extractVisibility(node) {
108
+ return findVisibility(node, KOTLIN_VIS, 'public', 'modifiers');
109
+ },
110
+ isStatic(_node) {
111
+ // Kotlin doesn't have static; companion object members are handled separately
112
+ return false;
113
+ },
114
+ isReadonly(node) {
115
+ // 'val' = readonly, 'var' = mutable
116
+ return hasKeyword(node, 'val');
117
+ },
118
+ };
@@ -0,0 +1,8 @@
1
+ import type { FieldExtractionConfig } from '../generic.js';
2
+ /**
3
+ * PHP field extraction config.
4
+ *
5
+ * Handles property_declaration inside class/interface/trait bodies.
6
+ * tree-sitter-php uses 'declaration_list' for the class body.
7
+ */
8
+ export declare const phpConfig: FieldExtractionConfig;
@@ -0,0 +1,67 @@
1
+ // gitnexus/src/core/ingestion/field-extractors/configs/php.ts
2
+ import { SupportedLanguages } from '../../../../config/supported-languages.js';
3
+ import { findVisibility, hasKeyword } from './helpers.js';
4
+ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
5
+ const PHP_VIS = new Set(['public', 'private', 'protected']);
6
+ /**
7
+ * PHP field extraction config.
8
+ *
9
+ * Handles property_declaration inside class/interface/trait bodies.
10
+ * tree-sitter-php uses 'declaration_list' for the class body.
11
+ */
12
+ export const phpConfig = {
13
+ language: SupportedLanguages.PHP,
14
+ typeDeclarationNodes: [
15
+ 'class_declaration',
16
+ 'interface_declaration',
17
+ 'trait_declaration',
18
+ ],
19
+ fieldNodeTypes: ['property_declaration'],
20
+ bodyNodeTypes: ['declaration_list'],
21
+ defaultVisibility: 'public',
22
+ extractName(node) {
23
+ // property_declaration > property_element > variable_name ($varName)
24
+ for (let i = 0; i < node.namedChildCount; i++) {
25
+ const child = node.namedChild(i);
26
+ if (child?.type === 'property_element') {
27
+ const varName = child.childForFieldName('name')
28
+ ?? child.firstNamedChild;
29
+ if (varName) {
30
+ // strip leading $ from PHP variable names
31
+ const text = varName.text;
32
+ return text.startsWith('$') ? text.slice(1) : text;
33
+ }
34
+ }
35
+ // fallback: variable_name direct child
36
+ if (child?.type === 'variable_name') {
37
+ const text = child.text;
38
+ return text.startsWith('$') ? text.slice(1) : text;
39
+ }
40
+ }
41
+ return undefined;
42
+ },
43
+ extractType(node) {
44
+ // property_declaration may have a type before the property_element
45
+ // tree-sitter-php: type can be union_type, named_type, optional_type, primitive_type
46
+ for (let i = 0; i < node.namedChildCount; i++) {
47
+ const child = node.namedChild(i);
48
+ if (!child)
49
+ continue;
50
+ if (child.type === 'union_type' || child.type === 'named_type'
51
+ || child.type === 'optional_type' || child.type === 'primitive_type'
52
+ || child.type === 'intersection_type' || child.type === 'nullable_type') {
53
+ return extractSimpleTypeName(child) ?? child.text?.trim();
54
+ }
55
+ }
56
+ return undefined;
57
+ },
58
+ extractVisibility(node) {
59
+ return findVisibility(node, PHP_VIS, 'public');
60
+ },
61
+ isStatic(node) {
62
+ return hasKeyword(node, 'static');
63
+ },
64
+ isReadonly(node) {
65
+ return hasKeyword(node, 'readonly');
66
+ },
67
+ };
@@ -0,0 +1,12 @@
1
+ import type { FieldExtractionConfig } from '../generic.js';
2
+ /**
3
+ * Python field extraction config.
4
+ *
5
+ * Python class fields appear as:
6
+ * - Annotated assignments: `name: str = ""`
7
+ * - Plain assignments in __init__: `self.name = value`
8
+ *
9
+ * For AST-level extraction we handle expression_statement containing
10
+ * assignment or type nodes inside a class body block.
11
+ */
12
+ export declare const pythonConfig: FieldExtractionConfig;
@@ -0,0 +1,91 @@
1
+ // gitnexus/src/core/ingestion/field-extractors/configs/python.ts
2
+ import { SupportedLanguages } from '../../../../config/supported-languages.js';
3
+ import { extractSimpleTypeName } from '../../type-extractors/shared.js';
4
+ /**
5
+ * Python field extraction config.
6
+ *
7
+ * Python class fields appear as:
8
+ * - Annotated assignments: `name: str = ""`
9
+ * - Plain assignments in __init__: `self.name = value`
10
+ *
11
+ * For AST-level extraction we handle expression_statement containing
12
+ * assignment or type nodes inside a class body block.
13
+ */
14
+ export const pythonConfig = {
15
+ language: SupportedLanguages.Python,
16
+ typeDeclarationNodes: ['class_definition'],
17
+ fieldNodeTypes: ['expression_statement'],
18
+ bodyNodeTypes: ['block'],
19
+ defaultVisibility: 'public',
20
+ extractName(node) {
21
+ // expression_statement wrapping an assignment or type
22
+ const inner = node.firstNamedChild;
23
+ if (!inner)
24
+ return undefined;
25
+ // Annotated assignment: name: str = "default"
26
+ // tree-sitter node: type (expression_statement (type (identifier) (type) ...))
27
+ if (inner.type === 'type') {
28
+ const ident = inner.childForFieldName('name') ?? inner.firstNamedChild;
29
+ return ident?.type === 'identifier' ? ident.text : undefined;
30
+ }
31
+ // assignment: x = 5 (class variable)
32
+ if (inner.type === 'assignment') {
33
+ const left = inner.childForFieldName('left');
34
+ if (left?.type === 'identifier')
35
+ return left.text;
36
+ }
37
+ return undefined;
38
+ },
39
+ extractType(node) {
40
+ const inner = node.firstNamedChild;
41
+ if (!inner)
42
+ return undefined;
43
+ // Annotated assignment with value: `name: str = "default"`
44
+ // AST: expression_statement > type > [identifier, type, ...]
45
+ if (inner.type === 'type') {
46
+ const typeNode = inner.childForFieldName('type') ?? inner.namedChild(1);
47
+ if (typeNode)
48
+ return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
49
+ }
50
+ // Annotation without value: `address: Address`
51
+ // AST: expression_statement > assignment > [identifier, type]
52
+ if (inner.type === 'assignment') {
53
+ for (let i = 0; i < inner.childCount; i++) {
54
+ const child = inner.child(i);
55
+ if (child?.type === 'type') {
56
+ const typeId = child.firstNamedChild;
57
+ if (typeId)
58
+ return extractSimpleTypeName(typeId) ?? typeId.text?.trim();
59
+ }
60
+ }
61
+ }
62
+ return undefined;
63
+ },
64
+ extractVisibility(node) {
65
+ const inner = node.firstNamedChild;
66
+ let name;
67
+ if (inner?.type === 'type') {
68
+ const ident = inner.childForFieldName('name') ?? inner.firstNamedChild;
69
+ name = ident?.text;
70
+ }
71
+ else if (inner?.type === 'assignment') {
72
+ const left = inner.childForFieldName('left');
73
+ name = left?.text;
74
+ }
75
+ if (!name)
76
+ return 'public';
77
+ if (name.startsWith('__') && !name.endsWith('__'))
78
+ return 'private';
79
+ if (name.startsWith('_'))
80
+ return 'protected';
81
+ return 'public';
82
+ },
83
+ isStatic(_node) {
84
+ // Reports syntactic static keyword — Python class variables don't use explicit static keyword.
85
+ // Instance variables (self.x) live in __init__ and are not extracted here.
86
+ return false;
87
+ },
88
+ isReadonly(_node) {
89
+ return false;
90
+ },
91
+ };
@@ -0,0 +1,16 @@
1
+ import type { FieldExtractionConfig } from '../generic.js';
2
+ /**
3
+ * Ruby field extraction config.
4
+ *
5
+ * Ruby is unusual: there are no field declarations in the traditional sense.
6
+ * Fields are instance variables (@var) created by assignment, or declared
7
+ * via attr_accessor / attr_reader / attr_writer calls.
8
+ *
9
+ * We detect:
10
+ * - `call` nodes for attr_accessor / attr_reader / attr_writer
11
+ * (their arguments are symbol names → field names)
12
+ *
13
+ * For simplicity we focus on attr_* calls in the class body.
14
+ * Instance variable assignments (self.x = ...) would require deeper analysis.
15
+ */
16
+ export declare const rubyConfig: FieldExtractionConfig;
@@ -0,0 +1,75 @@
1
+ // gitnexus/src/core/ingestion/field-extractors/configs/ruby.ts
2
+ import { SupportedLanguages } from '../../../../config/supported-languages.js';
3
+ /**
4
+ * Collect all field names declared by an `attr_accessor`, `attr_reader`, or
5
+ * `attr_writer` call node. A single call may list multiple symbols:
6
+ * attr_accessor :foo, :bar, :baz
7
+ */
8
+ function extractAttrNames(node) {
9
+ const method = node.childForFieldName('method');
10
+ if (!method)
11
+ return [];
12
+ const methodName = method.text;
13
+ if (methodName !== 'attr_accessor' && methodName !== 'attr_reader'
14
+ && methodName !== 'attr_writer') {
15
+ return [];
16
+ }
17
+ const args = node.childForFieldName('arguments');
18
+ if (!args)
19
+ return [];
20
+ const names = [];
21
+ for (let i = 0; i < args.namedChildCount; i++) {
22
+ const arg = args.namedChild(i);
23
+ if (!arg)
24
+ continue;
25
+ // simple_symbol text is :name — strip the leading colon
26
+ const text = arg.text;
27
+ names.push(text.startsWith(':') ? text.slice(1) : text);
28
+ }
29
+ return names;
30
+ }
31
+ /**
32
+ * Ruby field extraction config.
33
+ *
34
+ * Ruby is unusual: there are no field declarations in the traditional sense.
35
+ * Fields are instance variables (@var) created by assignment, or declared
36
+ * via attr_accessor / attr_reader / attr_writer calls.
37
+ *
38
+ * We detect:
39
+ * - `call` nodes for attr_accessor / attr_reader / attr_writer
40
+ * (their arguments are symbol names → field names)
41
+ *
42
+ * For simplicity we focus on attr_* calls in the class body.
43
+ * Instance variable assignments (self.x = ...) would require deeper analysis.
44
+ */
45
+ export const rubyConfig = {
46
+ language: SupportedLanguages.Ruby,
47
+ typeDeclarationNodes: ['class'],
48
+ fieldNodeTypes: ['call'],
49
+ bodyNodeTypes: ['body_statement'],
50
+ defaultVisibility: 'public',
51
+ extractName(node) {
52
+ // Returns the first symbol name for interface compatibility.
53
+ // Use extractNames to obtain all names from a single attr_* call.
54
+ return extractAttrNames(node)[0];
55
+ },
56
+ extractNames(node) {
57
+ return extractAttrNames(node);
58
+ },
59
+ extractType(_node) {
60
+ // Ruby is dynamically typed; no type annotations in standard Ruby
61
+ return undefined;
62
+ },
63
+ extractVisibility(_node) {
64
+ // attr_accessor/attr_writer fields are effectively public
65
+ // attr_reader fields are read-only from outside but still public
66
+ return 'public';
67
+ },
68
+ isStatic(_node) {
69
+ return false;
70
+ },
71
+ isReadonly(node) {
72
+ const method = node.childForFieldName('method');
73
+ return method?.text === 'attr_reader';
74
+ },
75
+ };
@@ -0,0 +1,9 @@
1
+ import type { FieldExtractionConfig } from '../generic.js';
2
+ /**
3
+ * Rust field extraction config.
4
+ *
5
+ * Handles struct fields (named and tuple variants are out of scope).
6
+ * Visibility: `pub` keyword = public, otherwise private (crate-private).
7
+ * All fields are immutable by default in Rust (mutability is on the binding).
8
+ */
9
+ export declare const rustConfig: FieldExtractionConfig;