@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.
- package/README.md +37 -80
- package/dist/benchmark/agent-context/tool-runner.js +2 -2
- package/dist/benchmark/neonspark-candidates.js +3 -3
- package/dist/benchmark/tool-runner.js +2 -2
- package/dist/cli/ai-context.d.ts +2 -1
- package/dist/cli/ai-context.js +16 -12
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +68 -48
- package/dist/cli/augment.js +1 -1
- package/dist/cli/eval-server.d.ts +8 -1
- package/dist/cli/eval-server.js +30 -13
- package/dist/cli/index.js +28 -82
- package/dist/cli/lazy-action.d.ts +6 -0
- package/dist/cli/lazy-action.js +18 -0
- package/dist/cli/mcp.js +3 -1
- package/dist/cli/setup.js +87 -48
- package/dist/cli/setup.test.js +18 -13
- package/dist/cli/skill-gen.d.ts +26 -0
- package/dist/cli/skill-gen.js +549 -0
- package/dist/cli/status.js +13 -4
- package/dist/cli/tool.d.ts +3 -2
- package/dist/cli/tool.js +50 -16
- package/dist/cli/wiki.js +8 -4
- package/dist/config/ignore-service.d.ts +25 -0
- package/dist/config/ignore-service.js +76 -0
- package/dist/config/supported-languages.d.ts +4 -1
- package/dist/config/supported-languages.js +3 -2
- package/dist/core/augmentation/engine.js +94 -67
- package/dist/core/embeddings/embedder.d.ts +1 -1
- package/dist/core/embeddings/embedder.js +1 -1
- package/dist/core/embeddings/embedding-pipeline.d.ts +3 -3
- package/dist/core/embeddings/embedding-pipeline.js +52 -25
- package/dist/core/embeddings/types.d.ts +1 -1
- package/dist/core/graph/types.d.ts +7 -2
- package/dist/core/ingestion/ast-cache.js +3 -2
- package/dist/core/ingestion/call-processor.d.ts +8 -6
- package/dist/core/ingestion/call-processor.js +468 -206
- package/dist/core/ingestion/call-routing.d.ts +53 -0
- package/dist/core/ingestion/call-routing.js +108 -0
- package/dist/core/ingestion/constants.d.ts +16 -0
- package/dist/core/ingestion/constants.js +16 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +2 -1
- package/dist/core/ingestion/entry-point-scoring.js +116 -23
- package/dist/core/ingestion/export-detection.d.ts +18 -0
- package/dist/core/ingestion/export-detection.js +231 -0
- package/dist/core/ingestion/filesystem-walker.js +4 -3
- package/dist/core/ingestion/framework-detection.d.ts +19 -4
- package/dist/core/ingestion/framework-detection.js +182 -6
- package/dist/core/ingestion/heritage-processor.d.ts +13 -5
- package/dist/core/ingestion/heritage-processor.js +109 -55
- package/dist/core/ingestion/import-processor.d.ts +16 -20
- package/dist/core/ingestion/import-processor.js +199 -579
- package/dist/core/ingestion/language-config.d.ts +46 -0
- package/dist/core/ingestion/language-config.js +167 -0
- package/dist/core/ingestion/mro-processor.d.ts +45 -0
- package/dist/core/ingestion/mro-processor.js +369 -0
- package/dist/core/ingestion/named-binding-extraction.d.ts +61 -0
- package/dist/core/ingestion/named-binding-extraction.js +363 -0
- package/dist/core/ingestion/parsing-processor.d.ts +4 -1
- package/dist/core/ingestion/parsing-processor.js +107 -109
- package/dist/core/ingestion/pipeline.d.ts +6 -3
- package/dist/core/ingestion/pipeline.js +208 -114
- package/dist/core/ingestion/process-processor.js +8 -2
- package/dist/core/ingestion/resolution-context.d.ts +53 -0
- package/dist/core/ingestion/resolution-context.js +132 -0
- package/dist/core/ingestion/resolvers/csharp.d.ts +22 -0
- package/dist/core/ingestion/resolvers/csharp.js +109 -0
- package/dist/core/ingestion/resolvers/go.d.ts +19 -0
- package/dist/core/ingestion/resolvers/go.js +42 -0
- package/dist/core/ingestion/resolvers/index.d.ts +18 -0
- package/dist/core/ingestion/resolvers/index.js +13 -0
- package/dist/core/ingestion/resolvers/jvm.d.ts +23 -0
- package/dist/core/ingestion/resolvers/jvm.js +87 -0
- package/dist/core/ingestion/resolvers/php.d.ts +15 -0
- package/dist/core/ingestion/resolvers/php.js +35 -0
- package/dist/core/ingestion/resolvers/python.d.ts +19 -0
- package/dist/core/ingestion/resolvers/python.js +52 -0
- package/dist/core/ingestion/resolvers/ruby.d.ts +12 -0
- package/dist/core/ingestion/resolvers/ruby.js +15 -0
- package/dist/core/ingestion/resolvers/rust.d.ts +15 -0
- package/dist/core/ingestion/resolvers/rust.js +73 -0
- package/dist/core/ingestion/resolvers/standard.d.ts +28 -0
- package/dist/core/ingestion/resolvers/standard.js +123 -0
- package/dist/core/ingestion/resolvers/utils.d.ts +33 -0
- package/dist/core/ingestion/resolvers/utils.js +122 -0
- package/dist/core/ingestion/symbol-table.d.ts +21 -1
- package/dist/core/ingestion/symbol-table.js +40 -12
- package/dist/core/ingestion/tree-sitter-queries.d.ts +13 -10
- package/dist/core/ingestion/tree-sitter-queries.js +297 -7
- package/dist/core/ingestion/type-env.d.ts +49 -0
- package/dist/core/ingestion/type-env.js +611 -0
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +385 -0
- package/dist/core/ingestion/type-extractors/csharp.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/csharp.js +383 -0
- package/dist/core/ingestion/type-extractors/go.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/go.js +467 -0
- package/dist/core/ingestion/type-extractors/index.d.ts +22 -0
- package/dist/core/ingestion/type-extractors/index.js +31 -0
- package/dist/core/ingestion/type-extractors/jvm.d.ts +3 -0
- package/dist/core/ingestion/type-extractors/jvm.js +681 -0
- package/dist/core/ingestion/type-extractors/php.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/php.js +549 -0
- package/dist/core/ingestion/type-extractors/python.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/python.js +406 -0
- package/dist/core/ingestion/type-extractors/ruby.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/ruby.js +389 -0
- package/dist/core/ingestion/type-extractors/rust.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/rust.js +449 -0
- package/dist/core/ingestion/type-extractors/shared.d.ts +133 -0
- package/dist/core/ingestion/type-extractors/shared.js +703 -0
- package/dist/core/ingestion/type-extractors/swift.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/swift.js +137 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +127 -0
- package/dist/core/ingestion/type-extractors/typescript.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/typescript.js +494 -0
- package/dist/core/ingestion/utils.d.ts +103 -0
- package/dist/core/ingestion/utils.js +1085 -4
- package/dist/core/ingestion/workers/parse-worker.d.ts +51 -4
- package/dist/core/ingestion/workers/parse-worker.js +634 -222
- package/dist/core/ingestion/workers/worker-pool.js +8 -0
- package/dist/core/{kuzu → lbug}/csv-generator.d.ts +12 -10
- package/dist/core/{kuzu → lbug}/csv-generator.js +82 -101
- package/dist/core/{kuzu/kuzu-adapter.d.ts → lbug/lbug-adapter.d.ts} +20 -25
- package/dist/core/{kuzu/kuzu-adapter.js → lbug/lbug-adapter.js} +150 -122
- package/dist/core/{kuzu → lbug}/schema.d.ts +4 -4
- package/dist/core/{kuzu → lbug}/schema.js +23 -22
- package/dist/core/lbug/schema.test.d.ts +1 -0
- package/dist/core/search/bm25-index.d.ts +4 -4
- package/dist/core/search/bm25-index.js +12 -11
- package/dist/core/search/hybrid-search.d.ts +2 -2
- package/dist/core/search/hybrid-search.js +6 -6
- package/dist/core/tree-sitter/parser-loader.d.ts +1 -0
- package/dist/core/tree-sitter/parser-loader.js +19 -0
- package/dist/core/wiki/generator.d.ts +2 -2
- package/dist/core/wiki/generator.js +6 -6
- package/dist/core/wiki/graph-queries.d.ts +4 -4
- package/dist/core/wiki/graph-queries.js +7 -7
- package/dist/mcp/compatible-stdio-transport.d.ts +25 -0
- package/dist/mcp/compatible-stdio-transport.js +200 -0
- package/dist/mcp/core/{kuzu-adapter.d.ts → lbug-adapter.d.ts} +11 -10
- package/dist/mcp/core/lbug-adapter.js +327 -0
- package/dist/mcp/local/local-backend.d.ts +21 -16
- package/dist/mcp/local/local-backend.js +306 -706
- package/dist/mcp/local/unity-parity-seed-loader.d.ts +6 -1
- package/dist/mcp/local/unity-parity-seed-loader.js +119 -9
- package/dist/mcp/local/unity-parity-seed-loader.test.js +95 -7
- package/dist/mcp/resources.js +2 -2
- package/dist/mcp/server.js +28 -13
- package/dist/mcp/staleness.js +2 -2
- package/dist/mcp/tools.js +12 -3
- package/dist/server/api.js +12 -12
- package/dist/server/mcp-http.d.ts +1 -1
- package/dist/server/mcp-http.js +1 -1
- package/dist/storage/git.js +4 -1
- package/dist/storage/repo-manager.d.ts +20 -2
- package/dist/storage/repo-manager.js +74 -4
- package/dist/types/pipeline.d.ts +1 -1
- package/hooks/claude/gitnexus-hook.cjs +149 -46
- package/hooks/claude/pre-tool-use.sh +2 -1
- package/hooks/claude/session-start.sh +0 -0
- package/package.json +20 -4
- package/scripts/patch-tree-sitter-swift.cjs +74 -0
- package/skills/gitnexus-cli.md +8 -8
- package/skills/gitnexus-debugging.md +1 -1
- package/skills/gitnexus-exploring.md +1 -1
- package/skills/gitnexus-guide.md +1 -1
- package/skills/gitnexus-impact-analysis.md +1 -1
- package/skills/gitnexus-pr-review.md +163 -0
- package/skills/gitnexus-refactoring.md +1 -1
- package/dist/cli/claude-hooks.d.ts +0 -22
- package/dist/cli/claude-hooks.js +0 -97
- package/dist/mcp/core/kuzu-adapter.js +0 -231
- /package/dist/core/{kuzu/csv-generator.test.d.ts → ingestion/type-extractors/types.js} +0 -0
- /package/dist/core/{kuzu/relationship-pair-buckets.test.d.ts → lbug/csv-generator.test.d.ts} +0 -0
- /package/dist/core/{kuzu → lbug}/csv-generator.test.js +0 -0
- /package/dist/core/{kuzu → lbug}/relationship-pair-buckets.d.ts +0 -0
- /package/dist/core/{kuzu → lbug}/relationship-pair-buckets.js +0 -0
- /package/dist/core/{kuzu/schema.test.d.ts → lbug/relationship-pair-buckets.test.d.ts} +0 -0
- /package/dist/core/{kuzu → lbug}/relationship-pair-buckets.test.js +0 -0
- /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
|
|
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
|
|
26
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
68
|
-
|
|
64
|
+
accessOrder = [];
|
|
65
|
+
maxSize;
|
|
66
|
+
repoPath;
|
|
67
|
+
constructor(repoPath, maxSize = 3000) {
|
|
69
68
|
this.repoPath = repoPath;
|
|
70
|
-
this.
|
|
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
|
-
|
|
78
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
234
|
-
|
|
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
|
|
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,
|
|
314
|
+
// Code element nodes (Function, Class, Interface, CodeElement)
|
|
344
315
|
const writer = codeWriterMap[node.label];
|
|
345
316
|
if (writer) {
|
|
346
|
-
|
|
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
|
|
1
|
+
import lbug from '@ladybugdb/core';
|
|
2
2
|
import { KnowledgeGraph } from '../graph/types.js';
|
|
3
|
-
export declare const
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
12
|
-
export type
|
|
13
|
-
export
|
|
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
|
|
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
|
|
24
|
+
* @param dbPath - Path to LadybugDB database (optional if already initialized)
|
|
30
25
|
*/
|
|
31
|
-
export declare const
|
|
26
|
+
export declare const insertNodeToLbug: (label: string, properties: Record<string, any>, dbPath?: string) => Promise<boolean>;
|
|
32
27
|
/**
|
|
33
|
-
* Batch insert multiple nodes to
|
|
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
|
|
30
|
+
* @param dbPath - Path to LadybugDB database
|
|
36
31
|
* @returns Object with success count and error count
|
|
37
32
|
*/
|
|
38
|
-
export declare const
|
|
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
|
|
42
|
+
export declare const getLbugStats: () => Promise<{
|
|
48
43
|
nodes: number;
|
|
49
44
|
edges: number;
|
|
50
45
|
}>;
|
|
51
46
|
/**
|
|
52
|
-
* Load cached embeddings from
|
|
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
|
|
64
|
-
export declare const
|
|
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
|
|
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
|
|
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<{
|