@veewo/gitnexus 1.3.11 → 1.4.6-rc

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 (181) hide show
  1. package/README.md +37 -80
  2. package/dist/benchmark/agent-context/tool-runner.js +2 -2
  3. package/dist/benchmark/neonspark-candidates.js +3 -3
  4. package/dist/benchmark/tool-runner.js +2 -2
  5. package/dist/cli/ai-context.d.ts +2 -1
  6. package/dist/cli/ai-context.js +16 -12
  7. package/dist/cli/analyze.d.ts +2 -0
  8. package/dist/cli/analyze.js +68 -48
  9. package/dist/cli/augment.js +1 -1
  10. package/dist/cli/eval-server.d.ts +8 -1
  11. package/dist/cli/eval-server.js +30 -13
  12. package/dist/cli/index.js +28 -82
  13. package/dist/cli/lazy-action.d.ts +6 -0
  14. package/dist/cli/lazy-action.js +18 -0
  15. package/dist/cli/mcp.js +3 -1
  16. package/dist/cli/setup.js +87 -48
  17. package/dist/cli/setup.test.js +18 -13
  18. package/dist/cli/skill-gen.d.ts +26 -0
  19. package/dist/cli/skill-gen.js +549 -0
  20. package/dist/cli/status.js +13 -4
  21. package/dist/cli/tool.d.ts +3 -2
  22. package/dist/cli/tool.js +50 -16
  23. package/dist/cli/wiki.js +8 -4
  24. package/dist/config/ignore-service.d.ts +25 -0
  25. package/dist/config/ignore-service.js +76 -0
  26. package/dist/config/supported-languages.d.ts +4 -1
  27. package/dist/config/supported-languages.js +3 -2
  28. package/dist/core/augmentation/engine.js +94 -67
  29. package/dist/core/embeddings/embedder.d.ts +1 -1
  30. package/dist/core/embeddings/embedder.js +1 -1
  31. package/dist/core/embeddings/embedding-pipeline.d.ts +3 -3
  32. package/dist/core/embeddings/embedding-pipeline.js +52 -25
  33. package/dist/core/embeddings/types.d.ts +1 -1
  34. package/dist/core/graph/types.d.ts +7 -2
  35. package/dist/core/ingestion/ast-cache.js +3 -2
  36. package/dist/core/ingestion/call-processor.d.ts +8 -6
  37. package/dist/core/ingestion/call-processor.js +468 -206
  38. package/dist/core/ingestion/call-routing.d.ts +53 -0
  39. package/dist/core/ingestion/call-routing.js +108 -0
  40. package/dist/core/ingestion/constants.d.ts +16 -0
  41. package/dist/core/ingestion/constants.js +16 -0
  42. package/dist/core/ingestion/entry-point-scoring.d.ts +2 -1
  43. package/dist/core/ingestion/entry-point-scoring.js +116 -23
  44. package/dist/core/ingestion/export-detection.d.ts +18 -0
  45. package/dist/core/ingestion/export-detection.js +231 -0
  46. package/dist/core/ingestion/filesystem-walker.js +4 -3
  47. package/dist/core/ingestion/framework-detection.d.ts +19 -4
  48. package/dist/core/ingestion/framework-detection.js +182 -6
  49. package/dist/core/ingestion/heritage-processor.d.ts +13 -5
  50. package/dist/core/ingestion/heritage-processor.js +109 -55
  51. package/dist/core/ingestion/import-processor.d.ts +16 -20
  52. package/dist/core/ingestion/import-processor.js +199 -579
  53. package/dist/core/ingestion/language-config.d.ts +46 -0
  54. package/dist/core/ingestion/language-config.js +167 -0
  55. package/dist/core/ingestion/mro-processor.d.ts +45 -0
  56. package/dist/core/ingestion/mro-processor.js +369 -0
  57. package/dist/core/ingestion/named-binding-extraction.d.ts +61 -0
  58. package/dist/core/ingestion/named-binding-extraction.js +363 -0
  59. package/dist/core/ingestion/parsing-processor.d.ts +4 -1
  60. package/dist/core/ingestion/parsing-processor.js +107 -109
  61. package/dist/core/ingestion/pipeline.d.ts +6 -3
  62. package/dist/core/ingestion/pipeline.js +208 -114
  63. package/dist/core/ingestion/process-processor.js +8 -2
  64. package/dist/core/ingestion/resolution-context.d.ts +53 -0
  65. package/dist/core/ingestion/resolution-context.js +132 -0
  66. package/dist/core/ingestion/resolvers/csharp.d.ts +22 -0
  67. package/dist/core/ingestion/resolvers/csharp.js +109 -0
  68. package/dist/core/ingestion/resolvers/go.d.ts +19 -0
  69. package/dist/core/ingestion/resolvers/go.js +42 -0
  70. package/dist/core/ingestion/resolvers/index.d.ts +18 -0
  71. package/dist/core/ingestion/resolvers/index.js +13 -0
  72. package/dist/core/ingestion/resolvers/jvm.d.ts +23 -0
  73. package/dist/core/ingestion/resolvers/jvm.js +87 -0
  74. package/dist/core/ingestion/resolvers/php.d.ts +15 -0
  75. package/dist/core/ingestion/resolvers/php.js +35 -0
  76. package/dist/core/ingestion/resolvers/python.d.ts +19 -0
  77. package/dist/core/ingestion/resolvers/python.js +52 -0
  78. package/dist/core/ingestion/resolvers/ruby.d.ts +12 -0
  79. package/dist/core/ingestion/resolvers/ruby.js +15 -0
  80. package/dist/core/ingestion/resolvers/rust.d.ts +15 -0
  81. package/dist/core/ingestion/resolvers/rust.js +73 -0
  82. package/dist/core/ingestion/resolvers/standard.d.ts +28 -0
  83. package/dist/core/ingestion/resolvers/standard.js +123 -0
  84. package/dist/core/ingestion/resolvers/utils.d.ts +33 -0
  85. package/dist/core/ingestion/resolvers/utils.js +122 -0
  86. package/dist/core/ingestion/symbol-table.d.ts +21 -1
  87. package/dist/core/ingestion/symbol-table.js +40 -12
  88. package/dist/core/ingestion/tree-sitter-queries.d.ts +13 -10
  89. package/dist/core/ingestion/tree-sitter-queries.js +297 -7
  90. package/dist/core/ingestion/type-env.d.ts +49 -0
  91. package/dist/core/ingestion/type-env.js +611 -0
  92. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +2 -0
  93. package/dist/core/ingestion/type-extractors/c-cpp.js +385 -0
  94. package/dist/core/ingestion/type-extractors/csharp.d.ts +2 -0
  95. package/dist/core/ingestion/type-extractors/csharp.js +383 -0
  96. package/dist/core/ingestion/type-extractors/go.d.ts +2 -0
  97. package/dist/core/ingestion/type-extractors/go.js +467 -0
  98. package/dist/core/ingestion/type-extractors/index.d.ts +22 -0
  99. package/dist/core/ingestion/type-extractors/index.js +31 -0
  100. package/dist/core/ingestion/type-extractors/jvm.d.ts +3 -0
  101. package/dist/core/ingestion/type-extractors/jvm.js +681 -0
  102. package/dist/core/ingestion/type-extractors/php.d.ts +2 -0
  103. package/dist/core/ingestion/type-extractors/php.js +549 -0
  104. package/dist/core/ingestion/type-extractors/python.d.ts +2 -0
  105. package/dist/core/ingestion/type-extractors/python.js +406 -0
  106. package/dist/core/ingestion/type-extractors/ruby.d.ts +2 -0
  107. package/dist/core/ingestion/type-extractors/ruby.js +389 -0
  108. package/dist/core/ingestion/type-extractors/rust.d.ts +2 -0
  109. package/dist/core/ingestion/type-extractors/rust.js +449 -0
  110. package/dist/core/ingestion/type-extractors/shared.d.ts +133 -0
  111. package/dist/core/ingestion/type-extractors/shared.js +703 -0
  112. package/dist/core/ingestion/type-extractors/swift.d.ts +2 -0
  113. package/dist/core/ingestion/type-extractors/swift.js +137 -0
  114. package/dist/core/ingestion/type-extractors/types.d.ts +127 -0
  115. package/dist/core/ingestion/type-extractors/typescript.d.ts +2 -0
  116. package/dist/core/ingestion/type-extractors/typescript.js +494 -0
  117. package/dist/core/ingestion/utils.d.ts +103 -0
  118. package/dist/core/ingestion/utils.js +1085 -4
  119. package/dist/core/ingestion/workers/parse-worker.d.ts +51 -4
  120. package/dist/core/ingestion/workers/parse-worker.js +634 -222
  121. package/dist/core/ingestion/workers/worker-pool.js +8 -0
  122. package/dist/core/{kuzu → lbug}/csv-generator.d.ts +12 -10
  123. package/dist/core/{kuzu → lbug}/csv-generator.js +82 -101
  124. package/dist/core/{kuzu/kuzu-adapter.d.ts → lbug/lbug-adapter.d.ts} +20 -25
  125. package/dist/core/{kuzu/kuzu-adapter.js → lbug/lbug-adapter.js} +150 -122
  126. package/dist/core/{kuzu → lbug}/schema.d.ts +4 -4
  127. package/dist/core/{kuzu → lbug}/schema.js +23 -22
  128. package/dist/core/lbug/schema.test.d.ts +1 -0
  129. package/dist/core/search/bm25-index.d.ts +4 -4
  130. package/dist/core/search/bm25-index.js +12 -11
  131. package/dist/core/search/hybrid-search.d.ts +2 -2
  132. package/dist/core/search/hybrid-search.js +6 -6
  133. package/dist/core/tree-sitter/parser-loader.d.ts +1 -0
  134. package/dist/core/tree-sitter/parser-loader.js +19 -0
  135. package/dist/core/wiki/generator.d.ts +2 -2
  136. package/dist/core/wiki/generator.js +6 -6
  137. package/dist/core/wiki/graph-queries.d.ts +4 -4
  138. package/dist/core/wiki/graph-queries.js +7 -7
  139. package/dist/mcp/compatible-stdio-transport.d.ts +25 -0
  140. package/dist/mcp/compatible-stdio-transport.js +200 -0
  141. package/dist/mcp/core/{kuzu-adapter.d.ts → lbug-adapter.d.ts} +11 -10
  142. package/dist/mcp/core/lbug-adapter.js +327 -0
  143. package/dist/mcp/local/local-backend.d.ts +21 -16
  144. package/dist/mcp/local/local-backend.js +306 -706
  145. package/dist/mcp/local/unity-parity-seed-loader.d.ts +6 -1
  146. package/dist/mcp/local/unity-parity-seed-loader.js +119 -9
  147. package/dist/mcp/local/unity-parity-seed-loader.test.js +95 -7
  148. package/dist/mcp/resources.js +2 -2
  149. package/dist/mcp/server.js +28 -13
  150. package/dist/mcp/staleness.js +2 -2
  151. package/dist/mcp/tools.js +12 -3
  152. package/dist/server/api.js +12 -12
  153. package/dist/server/mcp-http.d.ts +1 -1
  154. package/dist/server/mcp-http.js +1 -1
  155. package/dist/storage/git.js +4 -1
  156. package/dist/storage/repo-manager.d.ts +20 -2
  157. package/dist/storage/repo-manager.js +74 -4
  158. package/dist/types/pipeline.d.ts +1 -1
  159. package/hooks/claude/gitnexus-hook.cjs +149 -46
  160. package/hooks/claude/pre-tool-use.sh +2 -1
  161. package/hooks/claude/session-start.sh +0 -0
  162. package/package.json +20 -4
  163. package/scripts/patch-tree-sitter-swift.cjs +74 -0
  164. package/skills/gitnexus-cli.md +8 -8
  165. package/skills/gitnexus-debugging.md +1 -1
  166. package/skills/gitnexus-exploring.md +1 -1
  167. package/skills/gitnexus-guide.md +1 -1
  168. package/skills/gitnexus-impact-analysis.md +1 -1
  169. package/skills/gitnexus-pr-review.md +163 -0
  170. package/skills/gitnexus-refactoring.md +1 -1
  171. package/dist/cli/claude-hooks.d.ts +0 -22
  172. package/dist/cli/claude-hooks.js +0 -97
  173. package/dist/mcp/core/kuzu-adapter.js +0 -231
  174. /package/dist/core/{kuzu/csv-generator.test.d.ts → ingestion/type-extractors/types.js} +0 -0
  175. /package/dist/core/{kuzu/relationship-pair-buckets.test.d.ts → lbug/csv-generator.test.d.ts} +0 -0
  176. /package/dist/core/{kuzu → lbug}/csv-generator.test.js +0 -0
  177. /package/dist/core/{kuzu → lbug}/relationship-pair-buckets.d.ts +0 -0
  178. /package/dist/core/{kuzu → lbug}/relationship-pair-buckets.js +0 -0
  179. /package/dist/core/{kuzu/schema.test.d.ts → lbug/relationship-pair-buckets.test.d.ts} +0 -0
  180. /package/dist/core/{kuzu → lbug}/relationship-pair-buckets.test.js +0 -0
  181. /package/dist/core/{kuzu → lbug}/schema.test.js +0 -0
@@ -1,5 +1,7 @@
1
1
  import { Worker } from 'node:worker_threads';
2
2
  import os from 'node:os';
3
+ import fs from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
3
5
  /**
4
6
  * Max files to send to a worker in a single postMessage.
5
7
  * Keeps structured-clone memory bounded per sub-batch.
@@ -12,6 +14,12 @@ const SUB_BATCH_TIMEOUT_MS = 30_000;
12
14
  * Create a pool of worker threads.
13
15
  */
14
16
  export const createWorkerPool = (workerUrl, poolSize) => {
17
+ // Validate worker script exists before spawning to prevent uncaught
18
+ // MODULE_NOT_FOUND crashes in worker threads (e.g. when running from src/ via vitest)
19
+ const workerPath = fileURLToPath(workerUrl);
20
+ if (!fs.existsSync(workerPath)) {
21
+ throw new Error(`Worker script not found: ${workerPath}`);
22
+ }
15
23
  const size = poolSize ?? Math.min(8, Math.max(1, os.cpus().length - 1));
16
24
  const workers = [];
17
25
  for (let i = 0; i < size; i++) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * CSV Generator for KuzuDB Hybrid Schema
2
+ * CSV Generator for LadybugDB Hybrid Schema
3
3
  *
4
4
  * Streams CSV rows directly to disk files in a single pass over graph nodes.
5
5
  * File contents are lazy-read from disk per-node to avoid holding the entire
@@ -13,25 +13,27 @@
13
13
  */
14
14
  import { KnowledgeGraph, GraphNode } from '../graph/types.js';
15
15
  import { NodeTableName } from './schema.js';
16
+ export declare const sanitizeUTF8: (str: string) => string;
17
+ export declare const escapeCSVField: (value: string | number | undefined | null) => string;
18
+ export declare const escapeCSVNumber: (value: number | undefined | null, defaultValue?: number) => string;
19
+ export declare const isBinaryContent: (content: string) => boolean;
16
20
  /**
17
21
  * LRU content cache — avoids re-reading the same source file for every
18
22
  * symbol defined in it. Sized generously so most files stay cached during
19
23
  * the single-pass node iteration.
20
24
  */
21
25
  export declare class FileContentCache {
22
- private repoPath;
23
- private maxBytes;
24
26
  private cache;
25
- private currentBytes;
26
- constructor(repoPath: string, maxBytes?: number);
27
+ private accessOrder;
28
+ private maxSize;
29
+ private repoPath;
30
+ constructor(repoPath: string, maxSize?: number);
31
+ setForTest(relativePath: string, content: string): void;
32
+ hasForTest(relativePath: string): boolean;
27
33
  get(relativePath: string): Promise<string>;
28
- setForTest(key: string, value: string): void;
29
- hasForTest(key: string): boolean;
30
- private touch;
31
34
  private set;
32
- private evictIfNeeded;
33
35
  }
34
- export declare function toCodeElementCsvRow(node: GraphNode, contentCache?: FileContentCache): Promise<string>;
36
+ export declare const toCodeElementCsvRow: (node: GraphNode) => Promise<string>;
35
37
  export interface StreamedCSVResult {
36
38
  nodeFiles: Map<NodeTableName, {
37
39
  csvPath: string;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * CSV Generator for KuzuDB Hybrid Schema
2
+ * CSV Generator for LadybugDB Hybrid Schema
3
3
  *
4
4
  * Streams CSV rows directly to disk files in a single pass over graph nodes.
5
5
  * File contents are lazy-read from disk per-node to avoid holding the entire
@@ -19,7 +19,7 @@ const FLUSH_EVERY = 500;
19
19
  // ============================================================================
20
20
  // CSV ESCAPE UTILITIES
21
21
  // ============================================================================
22
- const sanitizeUTF8 = (str) => {
22
+ export const sanitizeUTF8 = (str) => {
23
23
  return str
24
24
  .replace(/\r\n/g, '\n')
25
25
  .replace(/\r/g, '\n')
@@ -27,23 +27,22 @@ const sanitizeUTF8 = (str) => {
27
27
  .replace(/[\uD800-\uDFFF]/g, '')
28
28
  .replace(/[\uFFFE\uFFFF]/g, '');
29
29
  };
30
- const escapeCSVField = (value) => {
30
+ export const escapeCSVField = (value) => {
31
31
  if (value === undefined || value === null)
32
32
  return '""';
33
33
  let str = String(value);
34
34
  str = sanitizeUTF8(str);
35
35
  return `"${str.replace(/"/g, '""')}"`;
36
36
  };
37
- const escapeCSVNumber = (value, defaultValue = -1) => {
37
+ export const escapeCSVNumber = (value, defaultValue = -1) => {
38
38
  if (value === undefined || value === null)
39
39
  return String(defaultValue);
40
40
  return String(value);
41
41
  };
42
- const UNITY_RESOURCE_PATH_PATTERN = /\.(prefab|unity|asset)$/i;
43
42
  // ============================================================================
44
43
  // CONTENT EXTRACTION (lazy — reads from disk on demand)
45
44
  // ============================================================================
46
- const isBinaryContent = (content) => {
45
+ export const isBinaryContent = (content) => {
47
46
  if (!content || content.length === 0)
48
47
  return false;
49
48
  const sample = content.slice(0, 1000);
@@ -61,21 +60,32 @@ const isBinaryContent = (content) => {
61
60
  * the single-pass node iteration.
62
61
  */
63
62
  export class FileContentCache {
64
- repoPath;
65
- maxBytes;
66
63
  cache = new Map();
67
- currentBytes = 0;
68
- constructor(repoPath, maxBytes = 128 * 1024 * 1024) {
64
+ accessOrder = [];
65
+ maxSize;
66
+ repoPath;
67
+ constructor(repoPath, maxSize = 3000) {
69
68
  this.repoPath = repoPath;
70
- this.maxBytes = maxBytes;
69
+ this.maxSize = maxSize;
70
+ }
71
+ setForTest(relativePath, content) {
72
+ this.set(relativePath, content);
73
+ }
74
+ hasForTest(relativePath) {
75
+ return this.cache.has(relativePath);
71
76
  }
72
77
  async get(relativePath) {
73
78
  if (!relativePath)
74
79
  return '';
75
80
  const cached = this.cache.get(relativePath);
76
81
  if (cached !== undefined) {
77
- this.touch(relativePath, cached);
78
- return cached.content;
82
+ // Move to end of accessOrder (LRU promotion)
83
+ const idx = this.accessOrder.indexOf(relativePath);
84
+ if (idx !== -1) {
85
+ this.accessOrder.splice(idx, 1);
86
+ this.accessOrder.push(relativePath);
87
+ }
88
+ return cached;
79
89
  }
80
90
  try {
81
91
  const fullPath = path.join(this.repoPath, relativePath);
@@ -88,40 +98,28 @@ export class FileContentCache {
88
98
  return '';
89
99
  }
90
100
  }
91
- setForTest(key, value) {
92
- this.set(key, value);
93
- }
94
- hasForTest(key) {
95
- return this.cache.has(key);
96
- }
97
- touch(key, value) {
98
- this.cache.delete(key);
99
- this.cache.set(key, value);
100
- }
101
101
  set(key, value) {
102
- const prev = this.cache.get(key);
103
- if (prev) {
104
- this.currentBytes -= prev.sizeBytes;
105
- this.cache.delete(key);
106
- }
107
- const sizeBytes = Buffer.byteLength(value, 'utf-8');
108
- this.cache.set(key, { content: value, sizeBytes });
109
- this.currentBytes += sizeBytes;
110
- this.evictIfNeeded();
111
- }
112
- evictIfNeeded() {
113
- while (this.currentBytes > this.maxBytes && this.cache.size > 0) {
114
- const oldestKey = this.cache.keys().next().value;
115
- if (!oldestKey)
116
- break;
117
- const oldest = this.cache.get(oldestKey);
118
- this.cache.delete(oldestKey);
119
- if (oldest) {
120
- this.currentBytes -= oldest.sizeBytes;
121
- }
102
+ if (this.cache.size >= this.maxSize) {
103
+ const oldest = this.accessOrder.shift();
104
+ if (oldest)
105
+ this.cache.delete(oldest);
122
106
  }
107
+ this.cache.set(key, value);
108
+ this.accessOrder.push(key);
123
109
  }
124
110
  }
111
+ export const toCodeElementCsvRow = async (node) => {
112
+ return [
113
+ escapeCSVField(node.id),
114
+ escapeCSVField(node.properties.name || ''),
115
+ escapeCSVField(node.properties.filePath || ''),
116
+ escapeCSVNumber(node.properties.startLine, -1),
117
+ escapeCSVNumber(node.properties.endLine, -1),
118
+ node.properties.isExported ? 'true' : 'false',
119
+ escapeCSVField(''),
120
+ escapeCSVField(node.properties.description || ''),
121
+ ].join(',');
122
+ };
125
123
  const extractContent = async (node, contentCache) => {
126
124
  const filePath = node.properties.filePath;
127
125
  const content = await contentCache.get(filePath);
@@ -150,56 +148,6 @@ const extractContent = async (node, contentCache) => {
150
148
  ? snippet.slice(0, MAX_SNIPPET) + '\n... [truncated]'
151
149
  : snippet;
152
150
  };
153
- function compactUnityComponentDescription(description) {
154
- const raw = typeof description === 'string' ? description : '';
155
- if (!raw)
156
- return '';
157
- try {
158
- const parsed = JSON.parse(raw);
159
- const compact = {};
160
- if (parsed.bindingKind)
161
- compact.bindingKind = parsed.bindingKind;
162
- if (parsed.componentObjectId)
163
- compact.componentObjectId = parsed.componentObjectId;
164
- if (parsed.lightweight)
165
- compact.lightweight = true;
166
- const scalarFields = parsed.serializedFields?.scalarFields || [];
167
- const referenceFields = parsed.serializedFields?.referenceFields || [];
168
- if (scalarFields.length > 0 || referenceFields.length > 0) {
169
- compact.serializedFields = { scalarFields, referenceFields };
170
- }
171
- if (Array.isArray(parsed.resolvedReferences) && parsed.resolvedReferences.length > 0) {
172
- compact.resolvedReferences = parsed.resolvedReferences;
173
- }
174
- if (Array.isArray(parsed.assetRefPaths) && parsed.assetRefPaths.length > 0) {
175
- compact.assetRefPaths = parsed.assetRefPaths;
176
- }
177
- return JSON.stringify(Object.keys(compact).length > 0 ? compact : parsed);
178
- }
179
- catch {
180
- return raw;
181
- }
182
- }
183
- export async function toCodeElementCsvRow(node, contentCache) {
184
- const filePath = String(node.properties.filePath || '');
185
- const isUnityComponentRow = node.label === 'CodeElement' && UNITY_RESOURCE_PATH_PATTERN.test(filePath);
186
- const content = isUnityComponentRow
187
- ? ''
188
- : (contentCache ? await extractContent(node, contentCache) : '');
189
- const description = isUnityComponentRow
190
- ? compactUnityComponentDescription(node.properties.description || '')
191
- : String(node.properties.description || '');
192
- return [
193
- escapeCSVField(node.id),
194
- escapeCSVField(node.properties.name || ''),
195
- escapeCSVField(filePath),
196
- escapeCSVNumber(node.properties.startLine, -1),
197
- escapeCSVNumber(node.properties.endLine, -1),
198
- node.properties.isExported ? 'true' : 'false',
199
- escapeCSVField(content),
200
- escapeCSVField(description),
201
- ].join(',');
202
- }
203
151
  // ============================================================================
204
152
  // BUFFERED CSV WRITER
205
153
  // ============================================================================
@@ -227,11 +175,18 @@ class BufferedCSVWriter {
227
175
  const chunk = this.buffer.join('\n') + '\n';
228
176
  this.buffer.length = 0;
229
177
  return new Promise((resolve, reject) => {
178
+ this.ws.once('error', reject);
230
179
  const ok = this.ws.write(chunk);
231
- if (ok)
180
+ if (ok) {
181
+ this.ws.removeListener('error', reject);
232
182
  resolve();
233
- else
234
- this.ws.once('drain', resolve);
183
+ }
184
+ else {
185
+ this.ws.once('drain', () => {
186
+ this.ws.removeListener('error', reject);
187
+ resolve();
188
+ });
189
+ }
235
190
  });
236
191
  }
237
192
  async finish() {
@@ -266,7 +221,8 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
266
221
  const functionWriter = new BufferedCSVWriter(path.join(csvDir, 'function.csv'), codeElementHeader);
267
222
  const classWriter = new BufferedCSVWriter(path.join(csvDir, 'class.csv'), codeElementHeader);
268
223
  const interfaceWriter = new BufferedCSVWriter(path.join(csvDir, 'interface.csv'), codeElementHeader);
269
- const methodWriter = new BufferedCSVWriter(path.join(csvDir, 'method.csv'), codeElementHeader);
224
+ const methodHeader = 'id,name,filePath,startLine,endLine,isExported,content,description,parameterCount,returnType';
225
+ const methodWriter = new BufferedCSVWriter(path.join(csvDir, 'method.csv'), methodHeader);
270
226
  const codeElemWriter = new BufferedCSVWriter(path.join(csvDir, 'codeelement.csv'), codeElementHeader);
271
227
  const communityWriter = new BufferedCSVWriter(path.join(csvDir, 'community.csv'), 'id,label,heuristicLabel,keywords,description,enrichedBy,cohesion,symbolCount');
272
228
  const processWriter = new BufferedCSVWriter(path.join(csvDir, 'process.csv'), 'id,label,heuristicLabel,processType,stepCount,communities,entryPointId,terminalId');
@@ -282,7 +238,6 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
282
238
  'Function': functionWriter,
283
239
  'Class': classWriter,
284
240
  'Interface': interfaceWriter,
285
- 'Method': methodWriter,
286
241
  'CodeElement': codeElemWriter,
287
242
  };
288
243
  const seenFileIds = new Set();
@@ -311,7 +266,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
311
266
  break;
312
267
  case 'Community': {
313
268
  const keywords = node.properties.keywords || [];
314
- const keywordsStr = `[${keywords.map((k) => `'${k.replace(/'/g, "''")}'`).join(',')}]`;
269
+ const keywordsStr = `[${keywords.map((k) => `'${k.replace(/\\/g, '\\\\').replace(/'/g, "''").replace(/,/g, '\\,')}'`).join(',')}]`;
315
270
  await communityWriter.addRow([
316
271
  escapeCSVField(node.id),
317
272
  escapeCSVField(node.properties.name || ''),
@@ -339,11 +294,37 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
339
294
  ].join(','));
340
295
  break;
341
296
  }
297
+ case 'Method': {
298
+ const content = await extractContent(node, contentCache);
299
+ await methodWriter.addRow([
300
+ escapeCSVField(node.id),
301
+ escapeCSVField(node.properties.name || ''),
302
+ escapeCSVField(node.properties.filePath || ''),
303
+ escapeCSVNumber(node.properties.startLine, -1),
304
+ escapeCSVNumber(node.properties.endLine, -1),
305
+ node.properties.isExported ? 'true' : 'false',
306
+ escapeCSVField(content),
307
+ escapeCSVField(node.properties.description || ''),
308
+ escapeCSVNumber(node.properties.parameterCount, 0),
309
+ escapeCSVField(node.properties.returnType || ''),
310
+ ].join(','));
311
+ break;
312
+ }
342
313
  default: {
343
- // Code element nodes (Function, Class, Interface, Method, CodeElement)
314
+ // Code element nodes (Function, Class, Interface, CodeElement)
344
315
  const writer = codeWriterMap[node.label];
345
316
  if (writer) {
346
- await writer.addRow(await toCodeElementCsvRow(node, contentCache));
317
+ const content = await extractContent(node, contentCache);
318
+ await writer.addRow([
319
+ escapeCSVField(node.id),
320
+ escapeCSVField(node.properties.name || ''),
321
+ escapeCSVField(node.properties.filePath || ''),
322
+ escapeCSVNumber(node.properties.startLine, -1),
323
+ escapeCSVNumber(node.properties.endLine, -1),
324
+ node.properties.isExported ? 'true' : 'false',
325
+ escapeCSVField(content),
326
+ escapeCSVField(node.properties.description || ''),
327
+ ].join(','));
347
328
  }
348
329
  else {
349
330
  // Multi-language node types (Struct, Impl, Trait, Macro, etc.)
@@ -1,41 +1,36 @@
1
- import kuzu from 'kuzu';
1
+ import lbug from '@ladybugdb/core';
2
2
  import { KnowledgeGraph } from '../graph/types.js';
3
- export declare const initKuzu: (dbPath: string) => Promise<{
4
- db: kuzu.Database;
5
- conn: kuzu.Connection;
3
+ export declare const getOpenLbugDatabase: (dbPath: string) => lbug.Database | null;
4
+ export declare const initLbug: (dbPath: string) => Promise<{
5
+ db: lbug.Database;
6
+ conn: lbug.Connection;
6
7
  }>;
7
8
  /**
8
9
  * Execute multiple queries against one repo DB atomically.
9
10
  * While the callback runs, no other request can switch the active DB.
10
11
  */
11
- export declare const withKuzuDb: <T>(dbPath: string, operation: () => Promise<T>) => Promise<T>;
12
- export type KuzuProgressCallback = (message: string) => void;
13
- export interface FallbackInsertStats {
14
- attempted: number;
15
- succeeded: number;
16
- failed: number;
17
- }
18
- export declare const loadGraphToKuzu: (graph: KnowledgeGraph, repoPath: string, storagePath: string, onProgress?: KuzuProgressCallback) => Promise<{
12
+ export declare const withLbugDb: <T>(dbPath: string, operation: () => Promise<T>) => Promise<T>;
13
+ export type LbugProgressCallback = (message: string) => void;
14
+ export declare const loadGraphToLbug: (graph: KnowledgeGraph, repoPath: string, storagePath: string, onProgress?: LbugProgressCallback) => Promise<{
19
15
  success: boolean;
20
16
  insertedRels: number;
21
17
  skippedRels: number;
22
18
  warnings: string[];
23
- fallbackStats: FallbackInsertStats;
24
19
  }>;
25
20
  /**
26
- * Insert a single node to KuzuDB
21
+ * Insert a single node to LadybugDB
27
22
  * @param label - Node type (File, Function, Class, etc.)
28
23
  * @param properties - Node properties
29
- * @param dbPath - Path to KuzuDB database (optional if already initialized)
24
+ * @param dbPath - Path to LadybugDB database (optional if already initialized)
30
25
  */
31
- export declare const insertNodeToKuzu: (label: string, properties: Record<string, any>, dbPath?: string) => Promise<boolean>;
26
+ export declare const insertNodeToLbug: (label: string, properties: Record<string, any>, dbPath?: string) => Promise<boolean>;
32
27
  /**
33
- * Batch insert multiple nodes to KuzuDB using a single connection
28
+ * Batch insert multiple nodes to LadybugDB using a single connection
34
29
  * @param nodes - Array of {label, properties} to insert
35
- * @param dbPath - Path to KuzuDB database
30
+ * @param dbPath - Path to LadybugDB database
36
31
  * @returns Object with success count and error count
37
32
  */
38
- export declare const batchInsertNodesToKuzu: (nodes: Array<{
33
+ export declare const batchInsertNodesToLbug: (nodes: Array<{
39
34
  label: string;
40
35
  properties: Record<string, any>;
41
36
  }>, dbPath: string) => Promise<{
@@ -44,12 +39,12 @@ export declare const batchInsertNodesToKuzu: (nodes: Array<{
44
39
  }>;
45
40
  export declare const executeQuery: (cypher: string) => Promise<any[]>;
46
41
  export declare const executeWithReusedStatement: (cypher: string, paramsList: Array<Record<string, any>>) => Promise<void>;
47
- export declare const getKuzuStats: () => Promise<{
42
+ export declare const getLbugStats: () => Promise<{
48
43
  nodes: number;
49
44
  edges: number;
50
45
  }>;
51
46
  /**
52
- * Load cached embeddings from KuzuDB before a rebuild.
47
+ * Load cached embeddings from LadybugDB before a rebuild.
53
48
  * Returns all embedding vectors so they can be re-inserted after the graph is reloaded,
54
49
  * avoiding expensive re-embedding of unchanged nodes.
55
50
  */
@@ -60,12 +55,12 @@ export declare const loadCachedEmbeddings: () => Promise<{
60
55
  embedding: number[];
61
56
  }>;
62
57
  }>;
63
- export declare const closeKuzu: () => Promise<void>;
64
- export declare const isKuzuReady: () => boolean;
58
+ export declare const closeLbug: () => Promise<void>;
59
+ export declare const isLbugReady: () => boolean;
65
60
  /**
66
- * Delete all nodes (and their relationships) for a specific file from KuzuDB
61
+ * Delete all nodes (and their relationships) for a specific file from LadybugDB
67
62
  * @param filePath - The file path to delete nodes for
68
- * @param dbPath - Optional path to KuzuDB for per-query connection
63
+ * @param dbPath - Optional path to LadybugDB for per-query connection
69
64
  * @returns Object with counts of deleted nodes
70
65
  */
71
66
  export declare const deleteNodesForFile: (filePath: string, dbPath?: string) => Promise<{