gitnexus 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/cli/analyze.js +28 -3
  2. package/dist/core/group/extractors/fs-utils.d.ts +10 -0
  3. package/dist/core/group/extractors/fs-utils.js +24 -0
  4. package/dist/core/group/extractors/grpc-extractor.d.ts +17 -8
  5. package/dist/core/group/extractors/grpc-extractor.js +313 -191
  6. package/dist/core/group/extractors/grpc-patterns/go.d.ts +2 -0
  7. package/dist/core/group/extractors/grpc-patterns/go.js +97 -0
  8. package/dist/core/group/extractors/grpc-patterns/index.d.ts +19 -0
  9. package/dist/core/group/extractors/grpc-patterns/index.js +46 -0
  10. package/dist/core/group/extractors/grpc-patterns/java.d.ts +2 -0
  11. package/dist/core/group/extractors/grpc-patterns/java.js +173 -0
  12. package/dist/core/group/extractors/grpc-patterns/node.d.ts +4 -0
  13. package/dist/core/group/extractors/grpc-patterns/node.js +290 -0
  14. package/dist/core/group/extractors/grpc-patterns/proto.d.ts +9 -0
  15. package/dist/core/group/extractors/grpc-patterns/proto.js +134 -0
  16. package/dist/core/group/extractors/grpc-patterns/python.d.ts +2 -0
  17. package/dist/core/group/extractors/grpc-patterns/python.js +67 -0
  18. package/dist/core/group/extractors/grpc-patterns/types.d.ts +50 -0
  19. package/dist/core/group/extractors/grpc-patterns/types.js +1 -0
  20. package/dist/core/group/extractors/http-patterns/go.d.ts +2 -0
  21. package/dist/core/group/extractors/http-patterns/go.js +215 -0
  22. package/dist/core/group/extractors/http-patterns/index.d.ts +17 -0
  23. package/dist/core/group/extractors/http-patterns/index.js +44 -0
  24. package/dist/core/group/extractors/http-patterns/java.d.ts +2 -0
  25. package/dist/core/group/extractors/http-patterns/java.js +253 -0
  26. package/dist/core/group/extractors/http-patterns/node.d.ts +4 -0
  27. package/dist/core/group/extractors/http-patterns/node.js +354 -0
  28. package/dist/core/group/extractors/http-patterns/php.d.ts +2 -0
  29. package/dist/core/group/extractors/http-patterns/php.js +70 -0
  30. package/dist/core/group/extractors/http-patterns/python.d.ts +2 -0
  31. package/dist/core/group/extractors/http-patterns/python.js +133 -0
  32. package/dist/core/group/extractors/http-patterns/types.d.ts +61 -0
  33. package/dist/core/group/extractors/http-patterns/types.js +1 -0
  34. package/dist/core/group/extractors/http-route-extractor.d.ts +10 -13
  35. package/dist/core/group/extractors/http-route-extractor.js +201 -238
  36. package/dist/core/group/extractors/manifest-extractor.d.ts +54 -0
  37. package/dist/core/group/extractors/manifest-extractor.js +235 -0
  38. package/dist/core/group/extractors/topic-extractor.d.ts +0 -1
  39. package/dist/core/group/extractors/topic-extractor.js +55 -192
  40. package/dist/core/group/extractors/topic-patterns/go.d.ts +2 -0
  41. package/dist/core/group/extractors/topic-patterns/go.js +120 -0
  42. package/dist/core/group/extractors/topic-patterns/index.d.ts +14 -0
  43. package/dist/core/group/extractors/topic-patterns/index.js +38 -0
  44. package/dist/core/group/extractors/topic-patterns/java.d.ts +2 -0
  45. package/dist/core/group/extractors/topic-patterns/java.js +80 -0
  46. package/dist/core/group/extractors/topic-patterns/node.d.ts +4 -0
  47. package/dist/core/group/extractors/topic-patterns/node.js +155 -0
  48. package/dist/core/group/extractors/topic-patterns/python.d.ts +2 -0
  49. package/dist/core/group/extractors/topic-patterns/python.js +116 -0
  50. package/dist/core/group/extractors/topic-patterns/types.d.ts +25 -0
  51. package/dist/core/group/extractors/topic-patterns/types.js +10 -0
  52. package/dist/core/group/extractors/tree-sitter-scanner.d.ts +113 -0
  53. package/dist/core/group/extractors/tree-sitter-scanner.js +94 -0
  54. package/dist/core/ingestion/binding-accumulator.d.ts +22 -17
  55. package/dist/core/ingestion/binding-accumulator.js +29 -25
  56. package/dist/core/ingestion/cobol-processor.d.ts +1 -1
  57. package/dist/core/ingestion/import-processor.js +1 -1
  58. package/dist/core/ingestion/language-config.js +1 -1
  59. package/dist/core/ingestion/language-provider.d.ts +8 -0
  60. package/dist/core/ingestion/languages/ruby.js +15 -0
  61. package/dist/core/ingestion/markdown-processor.d.ts +1 -1
  62. package/dist/core/ingestion/method-extractors/configs/jvm.js +1 -0
  63. package/dist/core/ingestion/method-extractors/configs/ruby.js +1 -0
  64. package/dist/core/ingestion/method-extractors/generic.d.ts +6 -0
  65. package/dist/core/ingestion/method-extractors/generic.js +48 -4
  66. package/dist/core/ingestion/method-types.d.ts +4 -0
  67. package/dist/core/ingestion/model/resolve.js +103 -48
  68. package/dist/core/ingestion/model/semantic-model.d.ts +1 -1
  69. package/dist/core/ingestion/model/semantic-model.js +1 -1
  70. package/dist/core/ingestion/model/symbol-table.d.ts +7 -7
  71. package/dist/core/ingestion/model/symbol-table.js +7 -7
  72. package/dist/core/ingestion/mro-processor.d.ts +1 -1
  73. package/dist/core/ingestion/mro-processor.js +1 -1
  74. package/dist/core/ingestion/parsing-processor.js +54 -42
  75. package/dist/core/ingestion/pipeline-phases/cobol.d.ts +16 -0
  76. package/dist/core/ingestion/pipeline-phases/cobol.js +45 -0
  77. package/dist/core/ingestion/pipeline-phases/communities.d.ts +16 -0
  78. package/dist/core/ingestion/pipeline-phases/communities.js +62 -0
  79. package/dist/core/ingestion/pipeline-phases/cross-file-impl.d.ts +17 -0
  80. package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +156 -0
  81. package/dist/core/ingestion/pipeline-phases/cross-file.d.ts +37 -0
  82. package/dist/core/ingestion/pipeline-phases/cross-file.js +63 -0
  83. package/dist/core/ingestion/pipeline-phases/index.d.ts +21 -0
  84. package/dist/core/ingestion/pipeline-phases/index.js +22 -0
  85. package/dist/core/ingestion/pipeline-phases/markdown.d.ts +17 -0
  86. package/dist/core/ingestion/pipeline-phases/markdown.js +33 -0
  87. package/dist/core/ingestion/pipeline-phases/mro.d.ts +18 -0
  88. package/dist/core/ingestion/pipeline-phases/mro.js +36 -0
  89. package/dist/core/ingestion/pipeline-phases/orm-extraction.d.ts +22 -0
  90. package/dist/core/ingestion/pipeline-phases/orm-extraction.js +92 -0
  91. package/dist/core/ingestion/pipeline-phases/orm.d.ts +15 -0
  92. package/dist/core/ingestion/pipeline-phases/orm.js +74 -0
  93. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +47 -0
  94. package/dist/core/ingestion/pipeline-phases/parse-impl.js +437 -0
  95. package/dist/core/ingestion/pipeline-phases/parse.d.ts +49 -0
  96. package/dist/core/ingestion/pipeline-phases/parse.js +33 -0
  97. package/dist/core/ingestion/pipeline-phases/processes.d.ts +16 -0
  98. package/dist/core/ingestion/pipeline-phases/processes.js +143 -0
  99. package/dist/core/ingestion/pipeline-phases/routes.d.ts +21 -0
  100. package/dist/core/ingestion/pipeline-phases/routes.js +243 -0
  101. package/dist/core/ingestion/pipeline-phases/runner.d.ts +22 -0
  102. package/dist/core/ingestion/pipeline-phases/runner.js +203 -0
  103. package/dist/core/ingestion/pipeline-phases/scan.d.ts +21 -0
  104. package/dist/core/ingestion/pipeline-phases/scan.js +46 -0
  105. package/dist/core/ingestion/pipeline-phases/structure.d.ts +27 -0
  106. package/dist/core/ingestion/pipeline-phases/structure.js +35 -0
  107. package/dist/core/ingestion/pipeline-phases/tools.d.ts +20 -0
  108. package/dist/core/ingestion/pipeline-phases/tools.js +79 -0
  109. package/dist/core/ingestion/pipeline-phases/types.d.ts +79 -0
  110. package/dist/core/ingestion/pipeline-phases/types.js +37 -0
  111. package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.d.ts +35 -0
  112. package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.js +174 -0
  113. package/dist/core/ingestion/pipeline.d.ts +16 -10
  114. package/dist/core/ingestion/pipeline.js +66 -1534
  115. package/dist/core/ingestion/process-processor.js +1 -1
  116. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  117. package/dist/core/ingestion/tree-sitter-queries.js +69 -0
  118. package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -3
  119. package/dist/core/ingestion/utils/ast-helpers.js +48 -21
  120. package/dist/core/ingestion/utils/env.d.ts +10 -0
  121. package/dist/core/ingestion/utils/env.js +10 -0
  122. package/dist/core/ingestion/utils/graph-sort.d.ts +58 -0
  123. package/dist/core/ingestion/utils/graph-sort.js +100 -0
  124. package/dist/core/ingestion/workers/parse-worker.js +12 -8
  125. package/dist/core/lbug/lbug-adapter.js +66 -24
  126. package/package.json +3 -3
  127. package/vendor/tree-sitter-proto/binding.gyp +30 -0
  128. package/vendor/tree-sitter-proto/bindings/node/binding.cc +20 -0
  129. package/vendor/tree-sitter-proto/bindings/node/index.d.ts +28 -0
  130. package/vendor/tree-sitter-proto/bindings/node/index.js +7 -0
  131. package/vendor/tree-sitter-proto/package.json +18 -0
  132. package/vendor/tree-sitter-proto/src/node-types.json +1145 -0
  133. package/vendor/tree-sitter-proto/src/parser.c +10149 -0
  134. package/vendor/tree-sitter-proto/src/tree_sitter/alloc.h +54 -0
  135. package/vendor/tree-sitter-proto/src/tree_sitter/array.h +291 -0
  136. package/vendor/tree-sitter-proto/src/tree_sitter/parser.h +266 -0
@@ -1,5 +1,5 @@
1
1
  import fs from 'fs/promises';
2
- import { createReadStream } from 'fs';
2
+ import { createReadStream, createWriteStream } from 'fs';
3
3
  import { createInterface } from 'readline';
4
4
  import path from 'path';
5
5
  import lbug from '@ladybugdb/core';
@@ -215,9 +215,12 @@ export const loadGraphToLbug = async (graph, repoPath, storagePath, onProgress)
215
215
  }
216
216
  }
217
217
  // Bulk COPY relationships — split by FROM→TO label pair (LadybugDB requires it)
218
- // Stream-read the relation CSV line by line to avoid exceeding V8 max string length
218
+ // Stream-read the relation CSV line by line and write directly to per-pair
219
+ // temp files on disk. This avoids accumulating potentially millions of CSV
220
+ // lines in memory which could exceed V8 Map or array limits on large repos.
219
221
  let relHeader = '';
220
- const relsByPair = new Map();
222
+ const relsByPairMeta = new Map();
223
+ const pairWriteStreams = new Map();
221
224
  let skippedRels = 0;
222
225
  let totalValidRels = 0;
223
226
  await new Promise((resolve, reject) => {
@@ -246,33 +249,49 @@ export const loadGraphToLbug = async (graph, repoPath, storagePath, onProgress)
246
249
  return;
247
250
  }
248
251
  const pairKey = `${fromLabel}|${toLabel}`;
249
- let list = relsByPair.get(pairKey);
250
- if (!list) {
251
- list = [];
252
- relsByPair.set(pairKey, list);
252
+ let ws = pairWriteStreams.get(pairKey);
253
+ if (!ws) {
254
+ const pairCsvPath = path.join(csvDir, `rel_${fromLabel}_${toLabel}.csv`);
255
+ ws = createWriteStream(pairCsvPath, 'utf-8');
256
+ ws.write(relHeader + '\n');
257
+ pairWriteStreams.set(pairKey, ws);
258
+ relsByPairMeta.set(pairKey, { csvPath: pairCsvPath, rows: 0 });
253
259
  }
254
- list.push(line);
260
+ const ok = ws.write(line + '\n');
261
+ relsByPairMeta.get(pairKey).rows++;
255
262
  totalValidRels++;
263
+ // Handle backpressure: pause reading when the write buffer is full,
264
+ // resume when the stream drains. Prevents unbounded memory growth
265
+ // on repos with millions of relationships.
266
+ if (!ok) {
267
+ rl.pause();
268
+ ws.once('drain', () => rl.resume());
269
+ }
256
270
  });
257
271
  rl.on('close', resolve);
258
- rl.on('error', reject);
272
+ rl.on('error', (err) => {
273
+ // Destroy all open write streams to avoid resource leaks
274
+ for (const ws of pairWriteStreams.values())
275
+ ws.destroy();
276
+ reject(err);
277
+ });
259
278
  });
279
+ // Close all per-pair write streams before COPY
280
+ await Promise.all(Array.from(pairWriteStreams.values()).map((ws) => new Promise((resolve, reject) => ws.end((err) => (err ? reject(err) : resolve())))));
260
281
  const insertedRels = totalValidRels;
261
282
  const warnings = [];
262
283
  if (insertedRels > 0) {
263
- log(`Loading edges: ${insertedRels.toLocaleString()} across ${relsByPair.size} types`);
284
+ log(`Loading edges: ${insertedRels.toLocaleString()} across ${relsByPairMeta.size} types`);
264
285
  let pairIdx = 0;
265
286
  let failedPairEdges = 0;
266
- const failedPairLines = [];
267
- for (const [pairKey, lines] of relsByPair) {
287
+ const failedPairCsvPaths = new Set();
288
+ for (const [pairKey, { csvPath: pairCsvPath, rows }] of relsByPairMeta) {
268
289
  pairIdx++;
269
290
  const [fromLabel, toLabel] = pairKey.split('|');
270
- const pairCsvPath = path.join(csvDir, `rel_${fromLabel}_${toLabel}.csv`);
271
- await fs.writeFile(pairCsvPath, relHeader + '\n' + lines.join('\n'), 'utf-8');
272
291
  const normalizedPath = normalizeCopyPath(pairCsvPath);
273
292
  const copyQuery = `COPY ${REL_TABLE_NAME} FROM "${normalizedPath}" (from="${fromLabel}", to="${toLabel}", HEADER=true, ESCAPE='"', DELIM=',', QUOTE='"', PARALLEL=false, auto_detect=false)`;
274
- if (pairIdx % 5 === 0 || lines.length > 1000) {
275
- log(`Loading edges: ${pairIdx}/${relsByPair.size} types (${fromLabel} -> ${toLabel})`);
293
+ if (pairIdx % 5 === 0 || rows > 1000) {
294
+ log(`Loading edges: ${pairIdx}/${relsByPairMeta.size} types (${fromLabel} -> ${toLabel})`);
276
295
  }
277
296
  try {
278
297
  await conn.query(copyQuery);
@@ -284,19 +303,42 @@ export const loadGraphToLbug = async (graph, repoPath, storagePath, onProgress)
284
303
  }
285
304
  catch (retryErr) {
286
305
  const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
287
- warnings.push(`${fromLabel}->${toLabel} (${lines.length} edges): ${retryMsg.slice(0, 80)}`);
288
- failedPairEdges += lines.length;
289
- failedPairLines.push(...lines);
306
+ warnings.push(`${fromLabel}->${toLabel} (${rows} edges): ${retryMsg.slice(0, 80)}`);
307
+ failedPairEdges += rows;
308
+ failedPairCsvPaths.add(pairCsvPath);
290
309
  }
291
310
  }
292
- try {
293
- await fs.unlink(pairCsvPath);
311
+ // Only delete if not in failedPairCsvPaths (needed for fallback)
312
+ if (!failedPairCsvPaths.has(pairCsvPath)) {
313
+ try {
314
+ await fs.unlink(pairCsvPath);
315
+ }
316
+ catch { }
294
317
  }
295
- catch { }
296
318
  }
297
- if (failedPairLines.length > 0) {
319
+ if (failedPairCsvPaths.size > 0) {
298
320
  log(`Inserting ${failedPairEdges} edges individually (missing schema pairs)`);
299
- await fallbackRelationshipInserts([relHeader, ...failedPairLines], validTables, getNodeLabel);
321
+ // Read failed pair files and merge for fallback inserts
322
+ const allLines = [relHeader];
323
+ for (const failedPath of failedPairCsvPaths) {
324
+ try {
325
+ const content = await fs.readFile(failedPath, 'utf-8');
326
+ const lines = content.split('\n');
327
+ // Skip header line (first) and empty lines
328
+ for (let i = 1; i < lines.length; i++) {
329
+ if (lines[i].trim())
330
+ allLines.push(lines[i]);
331
+ }
332
+ }
333
+ catch { }
334
+ try {
335
+ await fs.unlink(failedPath);
336
+ }
337
+ catch { }
338
+ }
339
+ if (allLines.length > 1) {
340
+ await fallbackRelationshipInserts(allLines, validTables, getNodeLabel);
341
+ }
300
342
  }
301
343
  }
302
344
  // Cleanup all CSVs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",
@@ -59,7 +59,6 @@
59
59
  "commander": "^12.0.0",
60
60
  "cors": "^2.8.5",
61
61
  "express": "^4.19.2",
62
- "gitnexus-shared": "file:../gitnexus-shared",
63
62
  "glob": "^11.0.0",
64
63
  "graphology": "^0.25.4",
65
64
  "graphology-indices": "^0.17.0",
@@ -85,8 +84,9 @@
85
84
  "uuid": "^13.0.0"
86
85
  },
87
86
  "optionalDependencies": {
88
- "tree-sitter-dart": "github:UserNobody14/tree-sitter-dart#80e23c07b64494f7e21090bb3450223ef0b192f4",
87
+ "tree-sitter-dart": "https://github.com/UserNobody14/tree-sitter-dart/archive/80e23c07b64494f7e21090bb3450223ef0b192f4.tar.gz",
89
88
  "tree-sitter-kotlin": "^0.3.8",
89
+ "tree-sitter-proto": "file:./vendor/tree-sitter-proto",
90
90
  "tree-sitter-swift": "^0.6.0"
91
91
  },
92
92
  "devDependencies": {
@@ -0,0 +1,30 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "tree_sitter_proto_binding",
5
+ "dependencies": [
6
+ "<!(node -p \"require('node-addon-api').targets\"):node_addon_api_except",
7
+ ],
8
+ "include_dirs": [
9
+ "src",
10
+ ],
11
+ "sources": [
12
+ "bindings/node/binding.cc",
13
+ "src/parser.c",
14
+ # NOTE: if your language has an external scanner, add it here.
15
+ ],
16
+ "conditions": [
17
+ ["OS!='win'", {
18
+ "cflags_c": [
19
+ "-std=c11",
20
+ ],
21
+ }, { # OS == "win"
22
+ "cflags_c": [
23
+ "/std:c11",
24
+ "/utf-8",
25
+ ],
26
+ }],
27
+ ],
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,20 @@
1
+ #include <napi.h>
2
+
3
+ typedef struct TSLanguage TSLanguage;
4
+
5
+ extern "C" TSLanguage *tree_sitter_proto();
6
+
7
+ // "tree-sitter", "language" hashed with BLAKE2
8
+ const napi_type_tag LANGUAGE_TYPE_TAG = {
9
+ 0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16
10
+ };
11
+
12
+ Napi::Object Init(Napi::Env env, Napi::Object exports) {
13
+ exports["name"] = Napi::String::New(env, "proto");
14
+ auto language = Napi::External<TSLanguage>::New(env, tree_sitter_proto());
15
+ language.TypeTag(&LANGUAGE_TYPE_TAG);
16
+ exports["language"] = language;
17
+ return exports;
18
+ }
19
+
20
+ NODE_API_MODULE(tree_sitter_proto_binding, Init)
@@ -0,0 +1,28 @@
1
+ type BaseNode = {
2
+ type: string;
3
+ named: boolean;
4
+ };
5
+
6
+ type ChildNode = {
7
+ multiple: boolean;
8
+ required: boolean;
9
+ types: BaseNode[];
10
+ };
11
+
12
+ type NodeInfo =
13
+ | (BaseNode & {
14
+ subtypes: BaseNode[];
15
+ })
16
+ | (BaseNode & {
17
+ fields: { [name: string]: ChildNode };
18
+ children: ChildNode[];
19
+ });
20
+
21
+ type Language = {
22
+ name: string;
23
+ language: unknown;
24
+ nodeTypeInfo: NodeInfo[];
25
+ };
26
+
27
+ declare const language: Language;
28
+ export = language;
@@ -0,0 +1,7 @@
1
+ const root = require("path").join(__dirname, "..", "..");
2
+
3
+ module.exports = require("node-gyp-build")(root);
4
+
5
+ try {
6
+ module.exports.nodeTypeInfo = require("../../src/node-types.json");
7
+ } catch (_) {}
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "tree-sitter-proto",
3
+ "version": "0.4.1",
4
+ "description": "tree-sitter grammar for protobuf — ABI 14 build from coder3101/tree-sitter-proto latest grammar.js, compatible with tree-sitter 0.25",
5
+ "repository": "https://github.com/coder3101/tree-sitter-proto",
6
+ "license": "MIT",
7
+ "main": "bindings/node",
8
+ "scripts": {
9
+ "install": "node-gyp-build"
10
+ },
11
+ "peerDependencies": {
12
+ "tree-sitter": ">=0.21.0"
13
+ },
14
+ "dependencies": {
15
+ "node-addon-api": "^8.0.0",
16
+ "node-gyp-build": "^4.8.0"
17
+ }
18
+ }