@duytransipher/gitnexus 1.4.6-sipher.0
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/LICENSE +73 -0
- package/README.md +261 -0
- package/dist/cli/ai-context.d.ts +23 -0
- package/dist/cli/ai-context.js +265 -0
- package/dist/cli/analyze.d.ts +12 -0
- package/dist/cli/analyze.js +345 -0
- package/dist/cli/augment.d.ts +13 -0
- package/dist/cli/augment.js +33 -0
- package/dist/cli/clean.d.ts +10 -0
- package/dist/cli/clean.js +60 -0
- package/dist/cli/eval-server.d.ts +37 -0
- package/dist/cli/eval-server.js +389 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +137 -0
- package/dist/cli/lazy-action.d.ts +6 -0
- package/dist/cli/lazy-action.js +18 -0
- package/dist/cli/list.d.ts +6 -0
- package/dist/cli/list.js +30 -0
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +36 -0
- package/dist/cli/serve.d.ts +4 -0
- package/dist/cli/serve.js +6 -0
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +367 -0
- package/dist/cli/sipher-patched.d.ts +2 -0
- package/dist/cli/sipher-patched.js +77 -0
- package/dist/cli/skill-gen.d.ts +26 -0
- package/dist/cli/skill-gen.js +549 -0
- package/dist/cli/status.d.ts +6 -0
- package/dist/cli/status.js +36 -0
- package/dist/cli/tool.d.ts +60 -0
- package/dist/cli/tool.js +180 -0
- package/dist/cli/wiki.d.ts +15 -0
- package/dist/cli/wiki.js +365 -0
- package/dist/config/ignore-service.d.ts +26 -0
- package/dist/config/ignore-service.js +284 -0
- package/dist/config/supported-languages.d.ts +15 -0
- package/dist/config/supported-languages.js +16 -0
- package/dist/core/augmentation/engine.d.ts +26 -0
- package/dist/core/augmentation/engine.js +240 -0
- package/dist/core/embeddings/embedder.d.ts +60 -0
- package/dist/core/embeddings/embedder.js +251 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +51 -0
- package/dist/core/embeddings/embedding-pipeline.js +356 -0
- package/dist/core/embeddings/index.d.ts +9 -0
- package/dist/core/embeddings/index.js +9 -0
- package/dist/core/embeddings/text-generator.d.ts +24 -0
- package/dist/core/embeddings/text-generator.js +182 -0
- package/dist/core/embeddings/types.d.ts +87 -0
- package/dist/core/embeddings/types.js +32 -0
- package/dist/core/graph/graph.d.ts +2 -0
- package/dist/core/graph/graph.js +66 -0
- package/dist/core/graph/types.d.ts +66 -0
- package/dist/core/graph/types.js +1 -0
- package/dist/core/ingestion/ast-cache.d.ts +11 -0
- package/dist/core/ingestion/ast-cache.js +35 -0
- package/dist/core/ingestion/call-processor.d.ts +23 -0
- package/dist/core/ingestion/call-processor.js +793 -0
- package/dist/core/ingestion/call-routing.d.ts +68 -0
- package/dist/core/ingestion/call-routing.js +129 -0
- package/dist/core/ingestion/cluster-enricher.d.ts +38 -0
- package/dist/core/ingestion/cluster-enricher.js +170 -0
- package/dist/core/ingestion/community-processor.d.ts +39 -0
- package/dist/core/ingestion/community-processor.js +312 -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 +40 -0
- package/dist/core/ingestion/entry-point-scoring.js +353 -0
- 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.d.ts +28 -0
- package/dist/core/ingestion/filesystem-walker.js +81 -0
- package/dist/core/ingestion/framework-detection.d.ts +54 -0
- package/dist/core/ingestion/framework-detection.js +411 -0
- package/dist/core/ingestion/heritage-processor.d.ts +28 -0
- package/dist/core/ingestion/heritage-processor.js +251 -0
- package/dist/core/ingestion/import-processor.d.ts +34 -0
- package/dist/core/ingestion/import-processor.js +398 -0
- 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 +19 -0
- package/dist/core/ingestion/parsing-processor.js +315 -0
- package/dist/core/ingestion/pipeline.d.ts +6 -0
- package/dist/core/ingestion/pipeline.js +401 -0
- package/dist/core/ingestion/process-processor.d.ts +51 -0
- package/dist/core/ingestion/process-processor.js +315 -0
- 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/structure-processor.d.ts +2 -0
- package/dist/core/ingestion/structure-processor.js +36 -0
- package/dist/core/ingestion/symbol-table.d.ts +63 -0
- package/dist/core/ingestion/symbol-table.js +85 -0
- package/dist/core/ingestion/tree-sitter-queries.d.ts +15 -0
- package/dist/core/ingestion/tree-sitter-queries.js +888 -0
- package/dist/core/ingestion/type-env.d.ts +49 -0
- package/dist/core/ingestion/type-env.js +613 -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 +455 -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 +456 -0
- package/dist/core/ingestion/type-extractors/shared.d.ts +145 -0
- package/dist/core/ingestion/type-extractors/shared.js +810 -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/types.js +1 -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 +138 -0
- package/dist/core/ingestion/utils.js +1290 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +122 -0
- package/dist/core/ingestion/workers/parse-worker.js +1126 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +16 -0
- package/dist/core/ingestion/workers/worker-pool.js +128 -0
- package/dist/core/lbug/csv-generator.d.ts +33 -0
- package/dist/core/lbug/csv-generator.js +366 -0
- package/dist/core/lbug/lbug-adapter.d.ts +103 -0
- package/dist/core/lbug/lbug-adapter.js +769 -0
- package/dist/core/lbug/schema.d.ts +53 -0
- package/dist/core/lbug/schema.js +430 -0
- package/dist/core/search/bm25-index.d.ts +23 -0
- package/dist/core/search/bm25-index.js +96 -0
- package/dist/core/search/hybrid-search.d.ts +49 -0
- package/dist/core/search/hybrid-search.js +118 -0
- package/dist/core/tree-sitter/parser-loader.d.ts +5 -0
- package/dist/core/tree-sitter/parser-loader.js +63 -0
- package/dist/core/wiki/generator.d.ts +120 -0
- package/dist/core/wiki/generator.js +939 -0
- package/dist/core/wiki/graph-queries.d.ts +80 -0
- package/dist/core/wiki/graph-queries.js +238 -0
- package/dist/core/wiki/html-viewer.d.ts +10 -0
- package/dist/core/wiki/html-viewer.js +297 -0
- package/dist/core/wiki/llm-client.d.ts +43 -0
- package/dist/core/wiki/llm-client.js +186 -0
- package/dist/core/wiki/prompts.d.ts +53 -0
- package/dist/core/wiki/prompts.js +174 -0
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.js +3 -0
- package/dist/mcp/compatible-stdio-transport.d.ts +25 -0
- package/dist/mcp/compatible-stdio-transport.js +200 -0
- package/dist/mcp/core/embedder.d.ts +27 -0
- package/dist/mcp/core/embedder.js +108 -0
- package/dist/mcp/core/lbug-adapter.d.ts +57 -0
- package/dist/mcp/core/lbug-adapter.js +455 -0
- package/dist/mcp/local/local-backend.d.ts +181 -0
- package/dist/mcp/local/local-backend.js +1722 -0
- package/dist/mcp/resources.d.ts +31 -0
- package/dist/mcp/resources.js +411 -0
- package/dist/mcp/server.d.ts +23 -0
- package/dist/mcp/server.js +296 -0
- package/dist/mcp/staleness.d.ts +15 -0
- package/dist/mcp/staleness.js +29 -0
- package/dist/mcp/tools.d.ts +24 -0
- package/dist/mcp/tools.js +292 -0
- package/dist/server/api.d.ts +10 -0
- package/dist/server/api.js +344 -0
- package/dist/server/mcp-http.d.ts +13 -0
- package/dist/server/mcp-http.js +100 -0
- package/dist/storage/git.d.ts +6 -0
- package/dist/storage/git.js +35 -0
- package/dist/storage/repo-manager.d.ts +138 -0
- package/dist/storage/repo-manager.js +299 -0
- package/dist/types/pipeline.d.ts +32 -0
- package/dist/types/pipeline.js +18 -0
- package/dist/unreal/bridge.d.ts +4 -0
- package/dist/unreal/bridge.js +113 -0
- package/dist/unreal/config.d.ts +6 -0
- package/dist/unreal/config.js +55 -0
- package/dist/unreal/types.d.ts +105 -0
- package/dist/unreal/types.js +1 -0
- package/hooks/claude/gitnexus-hook.cjs +238 -0
- package/hooks/claude/pre-tool-use.sh +79 -0
- package/hooks/claude/session-start.sh +42 -0
- package/package.json +100 -0
- package/scripts/ensure-cli-executable.cjs +21 -0
- package/scripts/patch-tree-sitter-swift.cjs +74 -0
- package/scripts/setup-unreal-gitnexus.ps1 +191 -0
- package/skills/gitnexus-cli.md +82 -0
- package/skills/gitnexus-debugging.md +89 -0
- package/skills/gitnexus-exploring.md +78 -0
- package/skills/gitnexus-guide.md +64 -0
- package/skills/gitnexus-impact-analysis.md +97 -0
- package/skills/gitnexus-pr-review.md +163 -0
- package/skills/gitnexus-refactoring.md +121 -0
- package/vendor/leiden/index.cjs +355 -0
- package/vendor/leiden/utils.cjs +392 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import Parser from 'tree-sitter';
|
|
2
|
+
import { loadParser, loadLanguage, isLanguageAvailable } from '../tree-sitter/parser-loader.js';
|
|
3
|
+
import { LANGUAGE_QUERIES } from './tree-sitter-queries.js';
|
|
4
|
+
import { generateId } from '../../lib/utils.js';
|
|
5
|
+
import { getLanguageFromFilename, yieldToEventLoop, getDefinitionNodeFromCaptures, findEnclosingClassId, extractMethodSignature } from './utils.js';
|
|
6
|
+
import { extractPropertyDeclaredType } from './type-extractors/shared.js';
|
|
7
|
+
import { isNodeExported } from './export-detection.js';
|
|
8
|
+
import { detectFrameworkFromAST } from './framework-detection.js';
|
|
9
|
+
import { typeConfigs } from './type-extractors/index.js';
|
|
10
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
11
|
+
import { getTreeSitterBufferSize, TREE_SITTER_MAX_BUFFER } from './constants.js';
|
|
12
|
+
// isNodeExported imported from ./export-detection.js (shared module)
|
|
13
|
+
// Re-export for backward compatibility with any external consumers
|
|
14
|
+
export { isNodeExported } from './export-detection.js';
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Worker-based parallel parsing
|
|
17
|
+
// ============================================================================
|
|
18
|
+
const processParsingWithWorkers = async (graph, files, symbolTable, astCache, workerPool, onFileProgress) => {
|
|
19
|
+
// Filter to parseable files only
|
|
20
|
+
const parseableFiles = [];
|
|
21
|
+
for (const file of files) {
|
|
22
|
+
const lang = getLanguageFromFilename(file.path);
|
|
23
|
+
if (lang)
|
|
24
|
+
parseableFiles.push({ path: file.path, content: file.content });
|
|
25
|
+
}
|
|
26
|
+
if (parseableFiles.length === 0)
|
|
27
|
+
return { imports: [], calls: [], assignments: [], heritage: [], routes: [], constructorBindings: [] };
|
|
28
|
+
const total = files.length;
|
|
29
|
+
// Dispatch to worker pool — pool handles splitting into chunks and sub-batching
|
|
30
|
+
const chunkResults = await workerPool.dispatch(parseableFiles, (filesProcessed) => {
|
|
31
|
+
onFileProgress?.(Math.min(filesProcessed, total), total, 'Parsing...');
|
|
32
|
+
});
|
|
33
|
+
// Merge results from all workers into graph and symbol table
|
|
34
|
+
const allImports = [];
|
|
35
|
+
const allCalls = [];
|
|
36
|
+
const allAssignments = [];
|
|
37
|
+
const allHeritage = [];
|
|
38
|
+
const allRoutes = [];
|
|
39
|
+
const allConstructorBindings = [];
|
|
40
|
+
for (const result of chunkResults) {
|
|
41
|
+
for (const node of result.nodes) {
|
|
42
|
+
graph.addNode({
|
|
43
|
+
id: node.id,
|
|
44
|
+
label: node.label,
|
|
45
|
+
properties: node.properties,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
for (const rel of result.relationships) {
|
|
49
|
+
graph.addRelationship(rel);
|
|
50
|
+
}
|
|
51
|
+
for (const sym of result.symbols) {
|
|
52
|
+
symbolTable.add(sym.filePath, sym.name, sym.nodeId, sym.type, {
|
|
53
|
+
parameterCount: sym.parameterCount,
|
|
54
|
+
returnType: sym.returnType,
|
|
55
|
+
declaredType: sym.declaredType,
|
|
56
|
+
ownerId: sym.ownerId,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
allImports.push(...result.imports);
|
|
60
|
+
allCalls.push(...result.calls);
|
|
61
|
+
allAssignments.push(...result.assignments);
|
|
62
|
+
allHeritage.push(...result.heritage);
|
|
63
|
+
allRoutes.push(...result.routes);
|
|
64
|
+
allConstructorBindings.push(...result.constructorBindings);
|
|
65
|
+
}
|
|
66
|
+
// Merge and log skipped languages from workers
|
|
67
|
+
const skippedLanguages = new Map();
|
|
68
|
+
for (const result of chunkResults) {
|
|
69
|
+
for (const [lang, count] of Object.entries(result.skippedLanguages)) {
|
|
70
|
+
skippedLanguages.set(lang, (skippedLanguages.get(lang) || 0) + count);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (skippedLanguages.size > 0) {
|
|
74
|
+
const summary = Array.from(skippedLanguages.entries())
|
|
75
|
+
.map(([lang, count]) => `${lang}: ${count}`)
|
|
76
|
+
.join(', ');
|
|
77
|
+
console.warn(` Skipped unsupported languages: ${summary}`);
|
|
78
|
+
}
|
|
79
|
+
// Final progress
|
|
80
|
+
onFileProgress?.(total, total, 'done');
|
|
81
|
+
return { imports: allImports, calls: allCalls, assignments: allAssignments, heritage: allHeritage, routes: allRoutes, constructorBindings: allConstructorBindings };
|
|
82
|
+
};
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// Sequential fallback (original implementation)
|
|
85
|
+
// ============================================================================
|
|
86
|
+
const processParsingSequential = async (graph, files, symbolTable, astCache, onFileProgress) => {
|
|
87
|
+
const parser = await loadParser();
|
|
88
|
+
const total = files.length;
|
|
89
|
+
const skippedLanguages = new Map();
|
|
90
|
+
for (let i = 0; i < files.length; i++) {
|
|
91
|
+
const file = files[i];
|
|
92
|
+
onFileProgress?.(i + 1, total, file.path);
|
|
93
|
+
if (i % 20 === 0)
|
|
94
|
+
await yieldToEventLoop();
|
|
95
|
+
const language = getLanguageFromFilename(file.path);
|
|
96
|
+
if (!language)
|
|
97
|
+
continue;
|
|
98
|
+
// Skip unsupported languages (e.g. Swift when tree-sitter-swift not installed)
|
|
99
|
+
if (!isLanguageAvailable(language)) {
|
|
100
|
+
skippedLanguages.set(language, (skippedLanguages.get(language) || 0) + 1);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
// Skip files larger than the max tree-sitter buffer (32 MB)
|
|
104
|
+
if (file.content.length > TREE_SITTER_MAX_BUFFER)
|
|
105
|
+
continue;
|
|
106
|
+
try {
|
|
107
|
+
await loadLanguage(language, file.path);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
continue; // parser unavailable — safety net
|
|
111
|
+
}
|
|
112
|
+
let tree;
|
|
113
|
+
try {
|
|
114
|
+
tree = parser.parse(file.content, undefined, { bufferSize: getTreeSitterBufferSize(file.content.length) });
|
|
115
|
+
}
|
|
116
|
+
catch (parseError) {
|
|
117
|
+
console.warn(`Skipping unparseable file: ${file.path}`);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
astCache.set(file.path, tree);
|
|
121
|
+
const queryString = LANGUAGE_QUERIES[language];
|
|
122
|
+
if (!queryString) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
let query;
|
|
126
|
+
let matches;
|
|
127
|
+
try {
|
|
128
|
+
const language = parser.getLanguage();
|
|
129
|
+
query = new Parser.Query(language, queryString);
|
|
130
|
+
matches = query.matches(tree.rootNode);
|
|
131
|
+
}
|
|
132
|
+
catch (queryError) {
|
|
133
|
+
console.warn(`Query error for ${file.path}:`, queryError);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
matches.forEach(match => {
|
|
137
|
+
const captureMap = {};
|
|
138
|
+
match.captures.forEach(c => {
|
|
139
|
+
captureMap[c.name] = c.node;
|
|
140
|
+
});
|
|
141
|
+
if (captureMap['import']) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (captureMap['call']) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const nameNode = captureMap['name'];
|
|
148
|
+
// Synthesize name for constructors without explicit @name capture (e.g. Swift init)
|
|
149
|
+
if (!nameNode && !captureMap['definition.constructor'])
|
|
150
|
+
return;
|
|
151
|
+
const nodeName = nameNode ? nameNode.text : 'init';
|
|
152
|
+
let nodeLabel = 'CodeElement';
|
|
153
|
+
if (captureMap['definition.function']) {
|
|
154
|
+
// C/C++: @definition.function is broad and also matches inline class methods (inside
|
|
155
|
+
// a class/struct body). Those are already captured by @definition.method, so skip
|
|
156
|
+
// the duplicate Function entry to prevent double-indexing in globalIndex.
|
|
157
|
+
if (language === SupportedLanguages.CPlusPlus || language === SupportedLanguages.C) {
|
|
158
|
+
let ancestor = captureMap['definition.function']?.parent;
|
|
159
|
+
while (ancestor) {
|
|
160
|
+
if (ancestor.type === 'class_specifier' || ancestor.type === 'struct_specifier') {
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
ancestor = ancestor.parent;
|
|
164
|
+
}
|
|
165
|
+
if (ancestor)
|
|
166
|
+
return; // inside a class body — handled by @definition.method
|
|
167
|
+
}
|
|
168
|
+
nodeLabel = 'Function';
|
|
169
|
+
}
|
|
170
|
+
else if (captureMap['definition.class'])
|
|
171
|
+
nodeLabel = 'Class';
|
|
172
|
+
else if (captureMap['definition.interface'])
|
|
173
|
+
nodeLabel = 'Interface';
|
|
174
|
+
else if (captureMap['definition.method'])
|
|
175
|
+
nodeLabel = 'Method';
|
|
176
|
+
else if (captureMap['definition.struct'])
|
|
177
|
+
nodeLabel = 'Struct';
|
|
178
|
+
else if (captureMap['definition.enum'])
|
|
179
|
+
nodeLabel = 'Enum';
|
|
180
|
+
else if (captureMap['definition.namespace'])
|
|
181
|
+
nodeLabel = 'Namespace';
|
|
182
|
+
else if (captureMap['definition.module'])
|
|
183
|
+
nodeLabel = 'Module';
|
|
184
|
+
else if (captureMap['definition.trait'])
|
|
185
|
+
nodeLabel = 'Trait';
|
|
186
|
+
else if (captureMap['definition.impl'])
|
|
187
|
+
nodeLabel = 'Impl';
|
|
188
|
+
else if (captureMap['definition.type'])
|
|
189
|
+
nodeLabel = 'TypeAlias';
|
|
190
|
+
else if (captureMap['definition.const'])
|
|
191
|
+
nodeLabel = 'Const';
|
|
192
|
+
else if (captureMap['definition.static'])
|
|
193
|
+
nodeLabel = 'Static';
|
|
194
|
+
else if (captureMap['definition.typedef'])
|
|
195
|
+
nodeLabel = 'Typedef';
|
|
196
|
+
else if (captureMap['definition.macro'])
|
|
197
|
+
nodeLabel = 'Macro';
|
|
198
|
+
else if (captureMap['definition.union'])
|
|
199
|
+
nodeLabel = 'Union';
|
|
200
|
+
else if (captureMap['definition.property'])
|
|
201
|
+
nodeLabel = 'Property';
|
|
202
|
+
else if (captureMap['definition.record'])
|
|
203
|
+
nodeLabel = 'Record';
|
|
204
|
+
else if (captureMap['definition.delegate'])
|
|
205
|
+
nodeLabel = 'Delegate';
|
|
206
|
+
else if (captureMap['definition.annotation'])
|
|
207
|
+
nodeLabel = 'Annotation';
|
|
208
|
+
else if (captureMap['definition.constructor'])
|
|
209
|
+
nodeLabel = 'Constructor';
|
|
210
|
+
else if (captureMap['definition.template'])
|
|
211
|
+
nodeLabel = 'Template';
|
|
212
|
+
const definitionNodeForRange = getDefinitionNodeFromCaptures(captureMap);
|
|
213
|
+
const startLine = definitionNodeForRange ? definitionNodeForRange.startPosition.row : (nameNode ? nameNode.startPosition.row : 0);
|
|
214
|
+
const nodeId = generateId(nodeLabel, `${file.path}:${nodeName}`);
|
|
215
|
+
const definitionNode = getDefinitionNodeFromCaptures(captureMap);
|
|
216
|
+
const frameworkHint = definitionNode
|
|
217
|
+
? detectFrameworkFromAST(language, (definitionNode.text || '').slice(0, 300))
|
|
218
|
+
: null;
|
|
219
|
+
// Extract method signature for Method/Constructor nodes
|
|
220
|
+
const methodSig = (nodeLabel === 'Function' || nodeLabel === 'Method' || nodeLabel === 'Constructor')
|
|
221
|
+
? extractMethodSignature(definitionNode)
|
|
222
|
+
: undefined;
|
|
223
|
+
// Language-specific return type fallback (e.g. Ruby YARD @return [Type])
|
|
224
|
+
// Also upgrades uninformative AST types like PHP `array` with PHPDoc `@return User[]`
|
|
225
|
+
if (methodSig && (!methodSig.returnType || methodSig.returnType === 'array' || methodSig.returnType === 'iterable') && definitionNode) {
|
|
226
|
+
const tc = typeConfigs[language];
|
|
227
|
+
if (tc?.extractReturnType) {
|
|
228
|
+
const docReturn = tc.extractReturnType(definitionNode);
|
|
229
|
+
if (docReturn)
|
|
230
|
+
methodSig.returnType = docReturn;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const node = {
|
|
234
|
+
id: nodeId,
|
|
235
|
+
label: nodeLabel,
|
|
236
|
+
properties: {
|
|
237
|
+
name: nodeName,
|
|
238
|
+
filePath: file.path,
|
|
239
|
+
startLine: definitionNodeForRange ? definitionNodeForRange.startPosition.row : startLine,
|
|
240
|
+
endLine: definitionNodeForRange ? definitionNodeForRange.endPosition.row : startLine,
|
|
241
|
+
language: language,
|
|
242
|
+
isExported: isNodeExported(nameNode || definitionNodeForRange, nodeName, language),
|
|
243
|
+
...(frameworkHint ? {
|
|
244
|
+
astFrameworkMultiplier: frameworkHint.entryPointMultiplier,
|
|
245
|
+
astFrameworkReason: frameworkHint.reason,
|
|
246
|
+
} : {}),
|
|
247
|
+
...(methodSig ? {
|
|
248
|
+
parameterCount: methodSig.parameterCount,
|
|
249
|
+
returnType: methodSig.returnType,
|
|
250
|
+
} : {}),
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
graph.addNode(node);
|
|
254
|
+
// Compute enclosing class for Method/Constructor/Property/Function — used for both ownerId and HAS_METHOD
|
|
255
|
+
// Function is included because Kotlin/Rust/Python capture class methods as Function nodes
|
|
256
|
+
const needsOwner = nodeLabel === 'Method' || nodeLabel === 'Constructor' || nodeLabel === 'Property' || nodeLabel === 'Function';
|
|
257
|
+
const enclosingClassId = needsOwner ? findEnclosingClassId(nameNode || definitionNodeForRange, file.path) : null;
|
|
258
|
+
// Extract declared type for Property nodes (field/property type annotations)
|
|
259
|
+
const declaredType = (nodeLabel === 'Property' && definitionNode)
|
|
260
|
+
? extractPropertyDeclaredType(definitionNode)
|
|
261
|
+
: undefined;
|
|
262
|
+
symbolTable.add(file.path, nodeName, nodeId, nodeLabel, {
|
|
263
|
+
parameterCount: methodSig?.parameterCount,
|
|
264
|
+
returnType: methodSig?.returnType,
|
|
265
|
+
declaredType,
|
|
266
|
+
ownerId: enclosingClassId ?? undefined,
|
|
267
|
+
});
|
|
268
|
+
const fileId = generateId('File', file.path);
|
|
269
|
+
const relId = generateId('DEFINES', `${fileId}->${nodeId}`);
|
|
270
|
+
const relationship = {
|
|
271
|
+
id: relId,
|
|
272
|
+
sourceId: fileId,
|
|
273
|
+
targetId: nodeId,
|
|
274
|
+
type: 'DEFINES',
|
|
275
|
+
confidence: 1.0,
|
|
276
|
+
reason: '',
|
|
277
|
+
};
|
|
278
|
+
graph.addRelationship(relationship);
|
|
279
|
+
// ── HAS_METHOD / HAS_PROPERTY: link member to enclosing class ──
|
|
280
|
+
if (enclosingClassId) {
|
|
281
|
+
const memberEdgeType = nodeLabel === 'Property' ? 'HAS_PROPERTY' : 'HAS_METHOD';
|
|
282
|
+
graph.addRelationship({
|
|
283
|
+
id: generateId(memberEdgeType, `${enclosingClassId}->${nodeId}`),
|
|
284
|
+
sourceId: enclosingClassId,
|
|
285
|
+
targetId: nodeId,
|
|
286
|
+
type: memberEdgeType,
|
|
287
|
+
confidence: 1.0,
|
|
288
|
+
reason: '',
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
if (skippedLanguages.size > 0) {
|
|
294
|
+
const summary = Array.from(skippedLanguages.entries())
|
|
295
|
+
.map(([lang, count]) => `${lang}: ${count}`)
|
|
296
|
+
.join(', ');
|
|
297
|
+
console.warn(` Skipped unsupported languages: ${summary}`);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
// ============================================================================
|
|
301
|
+
// Public API
|
|
302
|
+
// ============================================================================
|
|
303
|
+
export const processParsing = async (graph, files, symbolTable, astCache, onFileProgress, workerPool) => {
|
|
304
|
+
if (workerPool) {
|
|
305
|
+
try {
|
|
306
|
+
return await processParsingWithWorkers(graph, files, symbolTable, astCache, workerPool, onFileProgress);
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
console.warn('Worker pool parsing failed, falling back to sequential:', err instanceof Error ? err.message : err);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// Fallback: sequential parsing (no pre-extracted data)
|
|
313
|
+
await processParsingSequential(graph, files, symbolTable, astCache, onFileProgress);
|
|
314
|
+
return null;
|
|
315
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PipelineProgress, PipelineResult } from '../../types/pipeline.js';
|
|
2
|
+
export interface PipelineOptions {
|
|
3
|
+
/** Skip MRO, community detection, and process extraction for faster test runs. */
|
|
4
|
+
skipGraphPhases?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare const runPipelineFromRepo: (repoPath: string, onProgress: (progress: PipelineProgress) => void, options?: PipelineOptions) => Promise<PipelineResult>;
|