@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
|
@@ -2,16 +2,73 @@
|
|
|
2
2
|
* Heritage Processor
|
|
3
3
|
*
|
|
4
4
|
* Extracts class inheritance relationships:
|
|
5
|
-
* - EXTENDS: Class extends another Class (TS, JS, Python)
|
|
6
|
-
* - IMPLEMENTS: Class implements an Interface (TS
|
|
5
|
+
* - EXTENDS: Class extends another Class (TS, JS, Python, C#, C++)
|
|
6
|
+
* - IMPLEMENTS: Class implements an Interface (TS, C#, Java, Kotlin, PHP)
|
|
7
|
+
*
|
|
8
|
+
* Languages like C# use a single `base_list` for both class and interface parents.
|
|
9
|
+
* We resolve the correct edge type by checking the symbol table: if the parent is
|
|
10
|
+
* registered as an Interface, we emit IMPLEMENTS; otherwise EXTENDS. For unresolved
|
|
11
|
+
* external symbols, the fallback heuristic is language-gated:
|
|
12
|
+
* - C# / Java: apply the `I[A-Z]` naming convention (e.g. IDisposable → IMPLEMENTS)
|
|
13
|
+
* - Swift: default to IMPLEMENTS (protocol conformance is more common than class inheritance)
|
|
14
|
+
* - All other languages: default to EXTENDS
|
|
7
15
|
*/
|
|
8
16
|
import Parser from 'tree-sitter';
|
|
9
|
-
import { loadParser, loadLanguage } from '../tree-sitter/parser-loader.js';
|
|
17
|
+
import { isLanguageAvailable, loadParser, loadLanguage } from '../tree-sitter/parser-loader.js';
|
|
10
18
|
import { LANGUAGE_QUERIES } from './tree-sitter-queries.js';
|
|
11
19
|
import { generateId } from '../../lib/utils.js';
|
|
12
|
-
import { getLanguageFromFilename, yieldToEventLoop } from './utils.js';
|
|
13
|
-
|
|
20
|
+
import { getLanguageFromFilename, isVerboseIngestionEnabled, yieldToEventLoop } from './utils.js';
|
|
21
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
22
|
+
import { getTreeSitterBufferSize } from './constants.js';
|
|
23
|
+
/** C#/Java convention: interfaces start with I followed by an uppercase letter */
|
|
24
|
+
const INTERFACE_NAME_RE = /^I[A-Z]/;
|
|
25
|
+
/**
|
|
26
|
+
* Determine whether a heritage.extends capture is actually an IMPLEMENTS relationship.
|
|
27
|
+
* Uses the symbol table first (authoritative — Tier 1); falls back to a language-gated
|
|
28
|
+
* heuristic for external symbols not present in the graph:
|
|
29
|
+
* - C# / Java: `I[A-Z]` naming convention
|
|
30
|
+
* - Swift: default IMPLEMENTS (protocol conformance is the norm)
|
|
31
|
+
* - All others: default EXTENDS
|
|
32
|
+
*/
|
|
33
|
+
const resolveExtendsType = (parentName, currentFilePath, ctx, language) => {
|
|
34
|
+
const resolved = ctx.resolve(parentName, currentFilePath);
|
|
35
|
+
if (resolved && resolved.candidates.length > 0) {
|
|
36
|
+
const isInterface = resolved.candidates[0].type === 'Interface';
|
|
37
|
+
return isInterface
|
|
38
|
+
? { type: 'IMPLEMENTS', idPrefix: 'Interface' }
|
|
39
|
+
: { type: 'EXTENDS', idPrefix: 'Class' };
|
|
40
|
+
}
|
|
41
|
+
// Unresolved symbol — fall back to language-specific heuristic
|
|
42
|
+
if (language === SupportedLanguages.CSharp || language === SupportedLanguages.Java) {
|
|
43
|
+
if (INTERFACE_NAME_RE.test(parentName)) {
|
|
44
|
+
return { type: 'IMPLEMENTS', idPrefix: 'Interface' };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else if (language === SupportedLanguages.Swift) {
|
|
48
|
+
// Protocol conformance is far more common than class inheritance in Swift
|
|
49
|
+
return { type: 'IMPLEMENTS', idPrefix: 'Interface' };
|
|
50
|
+
}
|
|
51
|
+
return { type: 'EXTENDS', idPrefix: 'Class' };
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Resolve a symbol ID for heritage, with fallback to generated ID.
|
|
55
|
+
* Uses ctx.resolve() → pick first candidate's nodeId → generate synthetic ID.
|
|
56
|
+
*/
|
|
57
|
+
const resolveHeritageId = (name, filePath, ctx, fallbackLabel, fallbackKey) => {
|
|
58
|
+
const resolved = ctx.resolve(name, filePath);
|
|
59
|
+
if (resolved && resolved.candidates.length > 0) {
|
|
60
|
+
// For global with multiple candidates, refuse (a wrong edge is worse than no edge)
|
|
61
|
+
if (resolved.tier === 'global' && resolved.candidates.length > 1) {
|
|
62
|
+
return generateId(fallbackLabel, fallbackKey ?? name);
|
|
63
|
+
}
|
|
64
|
+
return resolved.candidates[0].nodeId;
|
|
65
|
+
}
|
|
66
|
+
return generateId(fallbackLabel, fallbackKey ?? name);
|
|
67
|
+
};
|
|
68
|
+
export const processHeritage = async (graph, files, astCache, ctx, onProgress) => {
|
|
14
69
|
const parser = await loadParser();
|
|
70
|
+
const logSkipped = isVerboseIngestionEnabled();
|
|
71
|
+
const skippedByLang = logSkipped ? new Map() : null;
|
|
15
72
|
for (let i = 0; i < files.length; i++) {
|
|
16
73
|
const file = files[i];
|
|
17
74
|
onProgress?.(i + 1, files.length);
|
|
@@ -21,6 +78,12 @@ export const processHeritage = async (graph, files, astCache, symbolTable, onPro
|
|
|
21
78
|
const language = getLanguageFromFilename(file.path);
|
|
22
79
|
if (!language)
|
|
23
80
|
continue;
|
|
81
|
+
if (!isLanguageAvailable(language)) {
|
|
82
|
+
if (skippedByLang) {
|
|
83
|
+
skippedByLang.set(language, (skippedByLang.get(language) ?? 0) + 1);
|
|
84
|
+
}
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
24
87
|
const queryStr = LANGUAGE_QUERIES[language];
|
|
25
88
|
if (!queryStr)
|
|
26
89
|
continue;
|
|
@@ -28,17 +91,15 @@ export const processHeritage = async (graph, files, astCache, symbolTable, onPro
|
|
|
28
91
|
await loadLanguage(language, file.path);
|
|
29
92
|
// 3. Get AST
|
|
30
93
|
let tree = astCache.get(file.path);
|
|
31
|
-
let wasReparsed = false;
|
|
32
94
|
if (!tree) {
|
|
33
95
|
// Use larger bufferSize for files > 32KB
|
|
34
96
|
try {
|
|
35
|
-
tree = parser.parse(file.content, undefined, { bufferSize:
|
|
97
|
+
tree = parser.parse(file.content, undefined, { bufferSize: getTreeSitterBufferSize(file.content.length) });
|
|
36
98
|
}
|
|
37
99
|
catch (parseError) {
|
|
38
100
|
// Skip files that can't be parsed
|
|
39
101
|
continue;
|
|
40
102
|
}
|
|
41
|
-
wasReparsed = true;
|
|
42
103
|
// Cache re-parsed tree for potential future use
|
|
43
104
|
astCache.set(file.path, tree);
|
|
44
105
|
}
|
|
@@ -59,23 +120,26 @@ export const processHeritage = async (graph, files, astCache, symbolTable, onPro
|
|
|
59
120
|
match.captures.forEach(c => {
|
|
60
121
|
captureMap[c.name] = c.node;
|
|
61
122
|
});
|
|
62
|
-
// EXTENDS:
|
|
123
|
+
// EXTENDS or IMPLEMENTS: resolve via symbol table for languages where
|
|
124
|
+
// the tree-sitter query can't distinguish classes from interfaces (C#, Java)
|
|
63
125
|
if (captureMap['heritage.class'] && captureMap['heritage.extends']) {
|
|
126
|
+
// Go struct embedding: skip named fields (only anonymous fields are embedded)
|
|
127
|
+
const extendsNode = captureMap['heritage.extends'];
|
|
128
|
+
const fieldDecl = extendsNode.parent;
|
|
129
|
+
if (fieldDecl?.type === 'field_declaration' && fieldDecl.childForFieldName('name')) {
|
|
130
|
+
return; // Named field, not struct embedding
|
|
131
|
+
}
|
|
64
132
|
const className = captureMap['heritage.class'].text;
|
|
65
133
|
const parentClassName = captureMap['heritage.extends'].text;
|
|
66
|
-
|
|
67
|
-
const childId =
|
|
68
|
-
|
|
69
|
-
generateId('Class', `${file.path}:${className}`);
|
|
70
|
-
const parentId = symbolTable.lookupFuzzy(parentClassName)[0]?.nodeId ||
|
|
71
|
-
generateId('Class', `${parentClassName}`);
|
|
134
|
+
const { type: relType, idPrefix } = resolveExtendsType(parentClassName, file.path, ctx, language);
|
|
135
|
+
const childId = resolveHeritageId(className, file.path, ctx, 'Class', `${file.path}:${className}`);
|
|
136
|
+
const parentId = resolveHeritageId(parentClassName, file.path, ctx, idPrefix);
|
|
72
137
|
if (childId && parentId && childId !== parentId) {
|
|
73
|
-
const relId = generateId('EXTENDS', `${childId}->${parentId}`);
|
|
74
138
|
graph.addRelationship({
|
|
75
|
-
id:
|
|
139
|
+
id: generateId(relType, `${childId}->${parentId}`),
|
|
76
140
|
sourceId: childId,
|
|
77
141
|
targetId: parentId,
|
|
78
|
-
type:
|
|
142
|
+
type: relType,
|
|
79
143
|
confidence: 1.0,
|
|
80
144
|
reason: '',
|
|
81
145
|
});
|
|
@@ -85,16 +149,11 @@ export const processHeritage = async (graph, files, astCache, symbolTable, onPro
|
|
|
85
149
|
if (captureMap['heritage.class'] && captureMap['heritage.implements']) {
|
|
86
150
|
const className = captureMap['heritage.class'].text;
|
|
87
151
|
const interfaceName = captureMap['heritage.implements'].text;
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
symbolTable.lookupFuzzy(className)[0]?.nodeId ||
|
|
91
|
-
generateId('Class', `${file.path}:${className}`);
|
|
92
|
-
const interfaceId = symbolTable.lookupFuzzy(interfaceName)[0]?.nodeId ||
|
|
93
|
-
generateId('Interface', `${interfaceName}`);
|
|
152
|
+
const classId = resolveHeritageId(className, file.path, ctx, 'Class', `${file.path}:${className}`);
|
|
153
|
+
const interfaceId = resolveHeritageId(interfaceName, file.path, ctx, 'Interface');
|
|
94
154
|
if (classId && interfaceId) {
|
|
95
|
-
const relId = generateId('IMPLEMENTS', `${classId}->${interfaceId}`);
|
|
96
155
|
graph.addRelationship({
|
|
97
|
-
id:
|
|
156
|
+
id: generateId('IMPLEMENTS', `${classId}->${interfaceId}`),
|
|
98
157
|
sourceId: classId,
|
|
99
158
|
targetId: interfaceId,
|
|
100
159
|
type: 'IMPLEMENTS',
|
|
@@ -107,16 +166,11 @@ export const processHeritage = async (graph, files, astCache, symbolTable, onPro
|
|
|
107
166
|
if (captureMap['heritage.trait'] && captureMap['heritage.class']) {
|
|
108
167
|
const structName = captureMap['heritage.class'].text;
|
|
109
168
|
const traitName = captureMap['heritage.trait'].text;
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
symbolTable.lookupFuzzy(structName)[0]?.nodeId ||
|
|
113
|
-
generateId('Struct', `${file.path}:${structName}`);
|
|
114
|
-
const traitId = symbolTable.lookupFuzzy(traitName)[0]?.nodeId ||
|
|
115
|
-
generateId('Trait', `${traitName}`);
|
|
169
|
+
const structId = resolveHeritageId(structName, file.path, ctx, 'Struct', `${file.path}:${structName}`);
|
|
170
|
+
const traitId = resolveHeritageId(traitName, file.path, ctx, 'Trait');
|
|
116
171
|
if (structId && traitId) {
|
|
117
|
-
const relId = generateId('IMPLEMENTS', `${structId}->${traitId}`);
|
|
118
172
|
graph.addRelationship({
|
|
119
|
-
id:
|
|
173
|
+
id: generateId('IMPLEMENTS', `${structId}->${traitId}`),
|
|
120
174
|
sourceId: structId,
|
|
121
175
|
targetId: traitId,
|
|
122
176
|
type: 'IMPLEMENTS',
|
|
@@ -128,12 +182,17 @@ export const processHeritage = async (graph, files, astCache, symbolTable, onPro
|
|
|
128
182
|
});
|
|
129
183
|
// Tree is now owned by the LRU cache — no manual delete needed
|
|
130
184
|
}
|
|
185
|
+
if (skippedByLang && skippedByLang.size > 0) {
|
|
186
|
+
for (const [lang, count] of skippedByLang.entries()) {
|
|
187
|
+
console.warn(`[ingestion] Skipped ${count} ${lang} file(s) in heritage processing — ${lang} parser not available.`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
131
190
|
};
|
|
132
191
|
/**
|
|
133
192
|
* Fast path: resolve pre-extracted heritage from workers.
|
|
134
193
|
* No AST parsing — workers already extracted className + parentName + kind.
|
|
135
194
|
*/
|
|
136
|
-
export const processHeritageFromExtracted = async (graph, extractedHeritage,
|
|
195
|
+
export const processHeritageFromExtracted = async (graph, extractedHeritage, ctx, onProgress) => {
|
|
137
196
|
const total = extractedHeritage.length;
|
|
138
197
|
for (let i = 0; i < extractedHeritage.length; i++) {
|
|
139
198
|
if (i % 500 === 0) {
|
|
@@ -142,28 +201,26 @@ export const processHeritageFromExtracted = async (graph, extractedHeritage, sym
|
|
|
142
201
|
}
|
|
143
202
|
const h = extractedHeritage[i];
|
|
144
203
|
if (h.kind === 'extends') {
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
|
|
204
|
+
const fileLanguage = getLanguageFromFilename(h.filePath);
|
|
205
|
+
if (!fileLanguage)
|
|
206
|
+
continue;
|
|
207
|
+
const { type: relType, idPrefix } = resolveExtendsType(h.parentName, h.filePath, ctx, fileLanguage);
|
|
208
|
+
const childId = resolveHeritageId(h.className, h.filePath, ctx, 'Class', `${h.filePath}:${h.className}`);
|
|
209
|
+
const parentId = resolveHeritageId(h.parentName, h.filePath, ctx, idPrefix);
|
|
150
210
|
if (childId && parentId && childId !== parentId) {
|
|
151
211
|
graph.addRelationship({
|
|
152
|
-
id: generateId(
|
|
212
|
+
id: generateId(relType, `${childId}->${parentId}`),
|
|
153
213
|
sourceId: childId,
|
|
154
214
|
targetId: parentId,
|
|
155
|
-
type:
|
|
215
|
+
type: relType,
|
|
156
216
|
confidence: 1.0,
|
|
157
217
|
reason: '',
|
|
158
218
|
});
|
|
159
219
|
}
|
|
160
220
|
}
|
|
161
221
|
else if (h.kind === 'implements') {
|
|
162
|
-
const classId =
|
|
163
|
-
|
|
164
|
-
generateId('Class', `${h.filePath}:${h.className}`);
|
|
165
|
-
const interfaceId = symbolTable.lookupFuzzy(h.parentName)[0]?.nodeId ||
|
|
166
|
-
generateId('Interface', `${h.parentName}`);
|
|
222
|
+
const classId = resolveHeritageId(h.className, h.filePath, ctx, 'Class', `${h.filePath}:${h.className}`);
|
|
223
|
+
const interfaceId = resolveHeritageId(h.parentName, h.filePath, ctx, 'Interface');
|
|
167
224
|
if (classId && interfaceId) {
|
|
168
225
|
graph.addRelationship({
|
|
169
226
|
id: generateId('IMPLEMENTS', `${classId}->${interfaceId}`),
|
|
@@ -175,20 +232,17 @@ export const processHeritageFromExtracted = async (graph, extractedHeritage, sym
|
|
|
175
232
|
});
|
|
176
233
|
}
|
|
177
234
|
}
|
|
178
|
-
else if (h.kind === 'trait-impl') {
|
|
179
|
-
const structId =
|
|
180
|
-
|
|
181
|
-
generateId('Struct', `${h.filePath}:${h.className}`);
|
|
182
|
-
const traitId = symbolTable.lookupFuzzy(h.parentName)[0]?.nodeId ||
|
|
183
|
-
generateId('Trait', `${h.parentName}`);
|
|
235
|
+
else if (h.kind === 'trait-impl' || h.kind === 'include' || h.kind === 'extend' || h.kind === 'prepend') {
|
|
236
|
+
const structId = resolveHeritageId(h.className, h.filePath, ctx, 'Struct', `${h.filePath}:${h.className}`);
|
|
237
|
+
const traitId = resolveHeritageId(h.parentName, h.filePath, ctx, 'Trait');
|
|
184
238
|
if (structId && traitId) {
|
|
185
239
|
graph.addRelationship({
|
|
186
|
-
id: generateId('IMPLEMENTS', `${structId}->${traitId}`),
|
|
240
|
+
id: generateId('IMPLEMENTS', `${structId}->${traitId}:${h.kind}`),
|
|
187
241
|
sourceId: structId,
|
|
188
242
|
targetId: traitId,
|
|
189
243
|
type: 'IMPLEMENTS',
|
|
190
244
|
confidence: 1.0,
|
|
191
|
-
reason:
|
|
245
|
+
reason: h.kind,
|
|
192
246
|
});
|
|
193
247
|
}
|
|
194
248
|
}
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import { KnowledgeGraph } from '../graph/types.js';
|
|
2
2
|
import { ASTCache } from './ast-cache.js';
|
|
3
3
|
import type { ExtractedImport } from './workers/parse-worker.js';
|
|
4
|
+
import type { ResolutionContext } from './resolution-context.js';
|
|
5
|
+
import type { SuffixIndex } from './resolvers/index.js';
|
|
6
|
+
export type { SuffixIndex, TsconfigPaths, GoModuleConfig, CSharpProjectConfig, ComposerConfig } from './resolvers/index.js';
|
|
4
7
|
export type ImportMap = Map<string, Set<string>>;
|
|
5
|
-
export
|
|
8
|
+
export type PackageMap = Map<string, Set<string>>;
|
|
9
|
+
export interface NamedImportBinding {
|
|
10
|
+
sourcePath: string;
|
|
11
|
+
exportedName: string;
|
|
12
|
+
}
|
|
13
|
+
export type NamedImportMap = Map<string, Map<string, NamedImportBinding>>;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a file path is directly inside a package directory identified by its suffix.
|
|
16
|
+
* Used by the symbol resolver for Go and C# directory-level import matching.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isFileInPackageDir(filePath: string, dirSuffix: string): boolean;
|
|
6
19
|
/** Pre-built lookup structures for import resolution. Build once, reuse across chunks. */
|
|
7
20
|
export interface ImportResolutionContext {
|
|
8
21
|
allFilePaths: Set<string>;
|
|
@@ -12,27 +25,10 @@ export interface ImportResolutionContext {
|
|
|
12
25
|
resolveCache: Map<string, string | null>;
|
|
13
26
|
}
|
|
14
27
|
export declare function buildImportResolutionContext(allPaths: string[]): ImportResolutionContext;
|
|
15
|
-
/**
|
|
16
|
-
* Build a suffix index for O(1) endsWith lookups.
|
|
17
|
-
* Maps every possible path suffix to its original file path.
|
|
18
|
-
* e.g. for "src/com/example/Foo.java":
|
|
19
|
-
* "Foo.java" -> "src/com/example/Foo.java"
|
|
20
|
-
* "example/Foo.java" -> "src/com/example/Foo.java"
|
|
21
|
-
* "com/example/Foo.java" -> "src/com/example/Foo.java"
|
|
22
|
-
* etc.
|
|
23
|
-
*/
|
|
24
|
-
export interface SuffixIndex {
|
|
25
|
-
/** Exact suffix lookup (case-sensitive) */
|
|
26
|
-
get(suffix: string): string | undefined;
|
|
27
|
-
/** Case-insensitive suffix lookup */
|
|
28
|
-
getInsensitive(suffix: string): string | undefined;
|
|
29
|
-
/** Get all files in a directory suffix */
|
|
30
|
-
getFilesInDir(dirSuffix: string, extension: string): string[];
|
|
31
|
-
}
|
|
32
28
|
export declare const processImports: (graph: KnowledgeGraph, files: {
|
|
33
29
|
path: string;
|
|
34
30
|
content: string;
|
|
35
|
-
}[], astCache: ASTCache,
|
|
31
|
+
}[], astCache: ASTCache, ctx: ResolutionContext, onProgress?: (current: number, total: number) => void, repoRoot?: string, allPaths?: string[]) => Promise<void>;
|
|
36
32
|
export declare const processImportsFromExtracted: (graph: KnowledgeGraph, files: {
|
|
37
33
|
path: string;
|
|
38
|
-
}[], extractedImports: ExtractedImport[],
|
|
34
|
+
}[], extractedImports: ExtractedImport[], ctx: ResolutionContext, onProgress?: (current: number, total: number) => void, repoRoot?: string, prebuiltCtx?: ImportResolutionContext) => Promise<void>;
|