gitnexus 1.4.7 → 1.4.9
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 +29 -1
- package/dist/cli/ai-context.d.ts +1 -1
- package/dist/cli/ai-context.js +1 -1
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +54 -21
- package/dist/cli/index-repo.d.ts +15 -0
- package/dist/cli/index-repo.js +115 -0
- package/dist/cli/index.js +13 -3
- package/dist/cli/setup.js +90 -10
- package/dist/cli/wiki.d.ts +4 -0
- package/dist/cli/wiki.js +174 -53
- package/dist/config/supported-languages.d.ts +33 -1
- package/dist/config/supported-languages.js +32 -0
- package/dist/core/embeddings/embedder.d.ts +6 -1
- package/dist/core/embeddings/embedder.js +65 -5
- package/dist/core/embeddings/embedding-pipeline.js +11 -9
- package/dist/core/embeddings/http-client.d.ts +31 -0
- package/dist/core/embeddings/http-client.js +179 -0
- package/dist/core/embeddings/index.d.ts +1 -0
- package/dist/core/embeddings/index.js +1 -0
- package/dist/core/embeddings/types.d.ts +1 -1
- package/dist/core/graph/graph.js +9 -1
- package/dist/core/graph/types.d.ts +11 -2
- package/dist/core/ingestion/call-processor.d.ts +66 -2
- package/dist/core/ingestion/call-processor.js +650 -30
- package/dist/core/ingestion/call-routing.d.ts +9 -18
- package/dist/core/ingestion/call-routing.js +0 -19
- package/dist/core/ingestion/cobol/cobol-copy-expander.d.ts +57 -0
- package/dist/core/ingestion/cobol/cobol-copy-expander.js +385 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.d.ts +210 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.js +1509 -0
- package/dist/core/ingestion/cobol/jcl-parser.d.ts +68 -0
- package/dist/core/ingestion/cobol/jcl-parser.js +217 -0
- package/dist/core/ingestion/cobol/jcl-processor.d.ts +33 -0
- package/dist/core/ingestion/cobol/jcl-processor.js +229 -0
- package/dist/core/ingestion/cobol-processor.d.ts +54 -0
- package/dist/core/ingestion/cobol-processor.js +1186 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +17 -0
- package/dist/core/ingestion/entry-point-scoring.js +52 -28
- package/dist/core/ingestion/export-detection.d.ts +47 -8
- package/dist/core/ingestion/export-detection.js +29 -50
- package/dist/core/ingestion/field-extractor.d.ts +29 -0
- package/dist/core/ingestion/field-extractor.js +25 -0
- package/dist/core/ingestion/field-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/c-cpp.js +108 -0
- package/dist/core/ingestion/field-extractors/configs/csharp.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/csharp.js +73 -0
- package/dist/core/ingestion/field-extractors/configs/dart.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/dart.js +76 -0
- package/dist/core/ingestion/field-extractors/configs/go.d.ts +11 -0
- package/dist/core/ingestion/field-extractors/configs/go.js +64 -0
- package/dist/core/ingestion/field-extractors/configs/helpers.d.ts +44 -0
- package/dist/core/ingestion/field-extractors/configs/helpers.js +134 -0
- package/dist/core/ingestion/field-extractors/configs/jvm.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/jvm.js +118 -0
- package/dist/core/ingestion/field-extractors/configs/php.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/php.js +67 -0
- package/dist/core/ingestion/field-extractors/configs/python.d.ts +12 -0
- package/dist/core/ingestion/field-extractors/configs/python.js +91 -0
- package/dist/core/ingestion/field-extractors/configs/ruby.d.ts +16 -0
- package/dist/core/ingestion/field-extractors/configs/ruby.js +75 -0
- package/dist/core/ingestion/field-extractors/configs/rust.d.ts +9 -0
- package/dist/core/ingestion/field-extractors/configs/rust.js +55 -0
- package/dist/core/ingestion/field-extractors/configs/swift.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/swift.js +63 -0
- package/dist/core/ingestion/field-extractors/configs/typescript-javascript.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/typescript-javascript.js +60 -0
- package/dist/core/ingestion/field-extractors/generic.d.ts +46 -0
- package/dist/core/ingestion/field-extractors/generic.js +111 -0
- package/dist/core/ingestion/field-extractors/typescript.d.ts +77 -0
- package/dist/core/ingestion/field-extractors/typescript.js +291 -0
- package/dist/core/ingestion/field-types.d.ts +59 -0
- package/dist/core/ingestion/field-types.js +2 -0
- package/dist/core/ingestion/framework-detection.d.ts +97 -2
- package/dist/core/ingestion/framework-detection.js +114 -14
- package/dist/core/ingestion/heritage-processor.js +62 -66
- package/dist/core/ingestion/import-processor.d.ts +9 -10
- package/dist/core/ingestion/import-processor.js +150 -196
- package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.d.ts +6 -9
- package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.js +20 -2
- package/dist/core/ingestion/import-resolvers/dart.d.ts +7 -0
- package/dist/core/ingestion/import-resolvers/dart.js +44 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/go.d.ts +4 -5
- package/dist/core/ingestion/{resolvers → import-resolvers}/go.js +17 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.d.ts +10 -1
- package/dist/core/ingestion/import-resolvers/jvm.js +159 -0
- package/dist/core/ingestion/import-resolvers/php.d.ts +25 -0
- package/dist/core/ingestion/import-resolvers/php.js +80 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/python.d.ts +9 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/python.js +35 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.d.ts +5 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.js +7 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/rust.d.ts +5 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/rust.js +41 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/standard.d.ts +15 -7
- package/dist/core/ingestion/{resolvers → import-resolvers}/standard.js +22 -3
- package/dist/core/ingestion/import-resolvers/swift.d.ts +7 -0
- package/dist/core/ingestion/import-resolvers/swift.js +23 -0
- package/dist/core/ingestion/import-resolvers/types.d.ts +44 -0
- package/dist/core/ingestion/import-resolvers/types.js +6 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/utils.d.ts +2 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/utils.js +7 -0
- package/dist/core/ingestion/language-config.d.ts +6 -0
- package/dist/core/ingestion/language-config.js +13 -0
- package/dist/core/ingestion/language-provider.d.ts +121 -0
- package/dist/core/ingestion/language-provider.js +24 -0
- package/dist/core/ingestion/languages/c-cpp.d.ts +12 -0
- package/dist/core/ingestion/languages/c-cpp.js +71 -0
- package/dist/core/ingestion/languages/cobol.d.ts +1 -0
- package/dist/core/ingestion/languages/cobol.js +26 -0
- package/dist/core/ingestion/languages/csharp.d.ts +8 -0
- package/dist/core/ingestion/languages/csharp.js +49 -0
- package/dist/core/ingestion/languages/dart.d.ts +12 -0
- package/dist/core/ingestion/languages/dart.js +58 -0
- package/dist/core/ingestion/languages/go.d.ts +11 -0
- package/dist/core/ingestion/languages/go.js +28 -0
- package/dist/core/ingestion/languages/index.d.ts +38 -0
- package/dist/core/ingestion/languages/index.js +63 -0
- package/dist/core/ingestion/languages/java.d.ts +9 -0
- package/dist/core/ingestion/languages/java.js +29 -0
- package/dist/core/ingestion/languages/kotlin.d.ts +9 -0
- package/dist/core/ingestion/languages/kotlin.js +53 -0
- package/dist/core/ingestion/languages/php.d.ts +8 -0
- package/dist/core/ingestion/languages/php.js +145 -0
- package/dist/core/ingestion/languages/python.d.ts +12 -0
- package/dist/core/ingestion/languages/python.js +39 -0
- package/dist/core/ingestion/languages/ruby.d.ts +9 -0
- package/dist/core/ingestion/languages/ruby.js +44 -0
- package/dist/core/ingestion/languages/rust.d.ts +12 -0
- package/dist/core/ingestion/languages/rust.js +44 -0
- package/dist/core/ingestion/languages/swift.d.ts +12 -0
- package/dist/core/ingestion/languages/swift.js +133 -0
- package/dist/core/ingestion/languages/typescript.d.ts +10 -0
- package/dist/core/ingestion/languages/typescript.js +60 -0
- package/dist/core/ingestion/markdown-processor.d.ts +17 -0
- package/dist/core/ingestion/markdown-processor.js +124 -0
- package/dist/core/ingestion/mro-processor.js +22 -18
- package/dist/core/ingestion/named-binding-processor.d.ts +18 -0
- package/dist/core/ingestion/named-binding-processor.js +42 -0
- package/dist/core/ingestion/named-bindings/csharp.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/csharp.js +37 -0
- package/dist/core/ingestion/named-bindings/java.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/java.js +29 -0
- package/dist/core/ingestion/named-bindings/kotlin.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/kotlin.js +36 -0
- package/dist/core/ingestion/named-bindings/php.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/php.js +61 -0
- package/dist/core/ingestion/named-bindings/python.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/python.js +49 -0
- package/dist/core/ingestion/named-bindings/rust.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/rust.js +64 -0
- package/dist/core/ingestion/named-bindings/types.d.ts +16 -0
- package/dist/core/ingestion/named-bindings/types.js +6 -0
- package/dist/core/ingestion/named-bindings/typescript.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/typescript.js +58 -0
- package/dist/core/ingestion/parsing-processor.d.ts +6 -2
- package/dist/core/ingestion/parsing-processor.js +125 -85
- package/dist/core/ingestion/pipeline.d.ts +10 -0
- package/dist/core/ingestion/pipeline.js +1235 -317
- package/dist/core/ingestion/resolution-context.d.ts +5 -0
- package/dist/core/ingestion/resolution-context.js +8 -5
- package/dist/core/ingestion/route-extractors/expo.d.ts +1 -0
- package/dist/core/ingestion/route-extractors/expo.js +36 -0
- package/dist/core/ingestion/route-extractors/middleware.d.ts +47 -0
- package/dist/core/ingestion/route-extractors/middleware.js +143 -0
- package/dist/core/ingestion/route-extractors/nextjs.d.ts +3 -0
- package/dist/core/ingestion/route-extractors/nextjs.js +76 -0
- package/dist/core/ingestion/route-extractors/php.d.ts +7 -0
- package/dist/core/ingestion/route-extractors/php.js +21 -0
- package/dist/core/ingestion/route-extractors/response-shapes.d.ts +20 -0
- package/dist/core/ingestion/route-extractors/response-shapes.js +290 -0
- package/dist/core/ingestion/symbol-table.d.ts +16 -0
- package/dist/core/ingestion/symbol-table.js +20 -6
- package/dist/core/ingestion/tree-sitter-queries.d.ts +10 -9
- package/dist/core/ingestion/tree-sitter-queries.js +274 -11
- package/dist/core/ingestion/type-env.d.ts +42 -18
- package/dist/core/ingestion/type-env.js +481 -106
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +5 -0
- package/dist/core/ingestion/type-extractors/c-cpp.js +119 -0
- package/dist/core/ingestion/type-extractors/csharp.js +149 -16
- package/dist/core/ingestion/type-extractors/dart.d.ts +15 -0
- package/dist/core/ingestion/type-extractors/dart.js +371 -0
- package/dist/core/ingestion/type-extractors/jvm.js +169 -66
- package/dist/core/ingestion/type-extractors/rust.js +35 -1
- package/dist/core/ingestion/type-extractors/shared.d.ts +1 -15
- package/dist/core/ingestion/type-extractors/shared.js +14 -112
- package/dist/core/ingestion/type-extractors/swift.js +338 -7
- package/dist/core/ingestion/type-extractors/types.d.ts +40 -8
- package/dist/core/ingestion/type-extractors/typescript.js +141 -9
- package/dist/core/ingestion/utils/ast-helpers.d.ts +83 -0
- package/dist/core/ingestion/utils/ast-helpers.js +817 -0
- package/dist/core/ingestion/utils/call-analysis.d.ts +73 -0
- package/dist/core/ingestion/utils/call-analysis.js +527 -0
- package/dist/core/ingestion/utils/event-loop.d.ts +5 -0
- package/dist/core/ingestion/utils/event-loop.js +5 -0
- package/dist/core/ingestion/utils/language-detection.d.ts +9 -0
- package/dist/core/ingestion/utils/language-detection.js +70 -0
- package/dist/core/ingestion/utils/verbose.d.ts +1 -0
- package/dist/core/ingestion/utils/verbose.js +7 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +55 -5
- package/dist/core/ingestion/workers/parse-worker.js +415 -225
- package/dist/core/lbug/csv-generator.js +51 -1
- package/dist/core/lbug/lbug-adapter.d.ts +10 -0
- package/dist/core/lbug/lbug-adapter.js +75 -4
- package/dist/core/lbug/schema.d.ts +8 -4
- package/dist/core/lbug/schema.js +65 -4
- package/dist/core/tree-sitter/parser-loader.js +7 -1
- package/dist/core/wiki/cursor-client.d.ts +31 -0
- package/dist/core/wiki/cursor-client.js +127 -0
- package/dist/core/wiki/generator.d.ts +28 -9
- package/dist/core/wiki/generator.js +115 -18
- package/dist/core/wiki/graph-queries.d.ts +4 -0
- package/dist/core/wiki/graph-queries.js +7 -1
- package/dist/core/wiki/llm-client.d.ts +2 -0
- package/dist/core/wiki/llm-client.js +8 -4
- package/dist/core/wiki/prompts.d.ts +3 -3
- package/dist/core/wiki/prompts.js +6 -0
- package/dist/mcp/core/embedder.js +11 -3
- package/dist/mcp/core/lbug-adapter.d.ts +5 -0
- package/dist/mcp/core/lbug-adapter.js +23 -2
- package/dist/mcp/local/local-backend.d.ts +38 -5
- package/dist/mcp/local/local-backend.js +804 -63
- package/dist/mcp/resources.js +2 -0
- package/dist/mcp/tools.js +73 -4
- package/dist/server/api.d.ts +19 -1
- package/dist/server/api.js +66 -6
- package/dist/storage/git.d.ts +12 -0
- package/dist/storage/git.js +21 -0
- package/dist/storage/repo-manager.d.ts +3 -0
- package/package.json +25 -16
- package/dist/core/ingestion/named-binding-extraction.d.ts +0 -61
- package/dist/core/ingestion/named-binding-extraction.js +0 -363
- package/dist/core/ingestion/resolvers/index.d.ts +0 -18
- package/dist/core/ingestion/resolvers/index.js +0 -13
- package/dist/core/ingestion/resolvers/jvm.js +0 -87
- package/dist/core/ingestion/resolvers/php.d.ts +0 -15
- package/dist/core/ingestion/resolvers/php.js +0 -35
- package/dist/core/ingestion/type-extractors/index.d.ts +0 -22
- package/dist/core/ingestion/type-extractors/index.js +0 -31
- package/dist/core/ingestion/utils.d.ts +0 -138
- package/dist/core/ingestion/utils.js +0 -1290
- package/scripts/patch-tree-sitter-swift.cjs +0 -74
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export function extractRustNamedBindings(importNode) {
|
|
2
|
+
// use_declaration may contain use_as_clause at any depth
|
|
3
|
+
if (importNode.type !== 'use_declaration')
|
|
4
|
+
return undefined;
|
|
5
|
+
const bindings = [];
|
|
6
|
+
collectRustBindings(importNode, bindings);
|
|
7
|
+
return bindings.length > 0 ? bindings : undefined;
|
|
8
|
+
}
|
|
9
|
+
function collectRustBindings(node, bindings) {
|
|
10
|
+
if (node.type === 'use_as_clause') {
|
|
11
|
+
// First identifier = exported name, second identifier = local alias
|
|
12
|
+
const idents = [];
|
|
13
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
14
|
+
const child = node.namedChild(i);
|
|
15
|
+
if (child?.type === 'identifier')
|
|
16
|
+
idents.push(child.text);
|
|
17
|
+
// For scoped_identifier, extract the last segment
|
|
18
|
+
if (child?.type === 'scoped_identifier') {
|
|
19
|
+
const nameNode = child.childForFieldName?.('name');
|
|
20
|
+
if (nameNode)
|
|
21
|
+
idents.push(nameNode.text);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (idents.length === 2) {
|
|
25
|
+
bindings.push({ local: idents[1], exported: idents[0] });
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// Terminal identifier in a use_list: use crate::models::{User, Repo}
|
|
30
|
+
if (node.type === 'identifier' && node.parent?.type === 'use_list') {
|
|
31
|
+
bindings.push({ local: node.text, exported: node.text });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Skip scoped_identifier that serves as path prefix in scoped_use_list
|
|
35
|
+
// e.g. use crate::models::{User, Repo} — the path node "crate::models" is not an importable symbol
|
|
36
|
+
if (node.type === 'scoped_identifier' && node.parent?.type === 'scoped_use_list') {
|
|
37
|
+
return; // path prefix — the use_list sibling handles the actual symbols
|
|
38
|
+
}
|
|
39
|
+
// Terminal scoped_identifier: use crate::models::User;
|
|
40
|
+
// Only extract if this is a leaf (no deeper use_list/use_as_clause/scoped_use_list)
|
|
41
|
+
if (node.type === 'scoped_identifier') {
|
|
42
|
+
let hasDeeper = false;
|
|
43
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
44
|
+
const child = node.namedChild(i);
|
|
45
|
+
if (child?.type === 'use_list' || child?.type === 'use_as_clause' || child?.type === 'scoped_use_list') {
|
|
46
|
+
hasDeeper = true;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (!hasDeeper) {
|
|
51
|
+
const nameNode = node.childForFieldName?.('name');
|
|
52
|
+
if (nameNode) {
|
|
53
|
+
bindings.push({ local: nameNode.text, exported: nameNode.text });
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Recurse into children
|
|
59
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
60
|
+
const child = node.namedChild(i);
|
|
61
|
+
if (child)
|
|
62
|
+
collectRustBindings(child, bindings);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Named binding types — shared across all per-language binding extractors.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from import-resolution.ts to co-locate types with their consumers.
|
|
5
|
+
*/
|
|
6
|
+
import type { SyntaxNode } from '../utils/ast-helpers.js';
|
|
7
|
+
/** A single named import binding: local name in the importing file and exported name from the source.
|
|
8
|
+
* When `isModuleAlias` is true, the binding represents a Python `import X as Y` module alias
|
|
9
|
+
* and is routed to moduleAliasMap instead of namedImportMap during import processing. */
|
|
10
|
+
export interface NamedBinding {
|
|
11
|
+
local: string;
|
|
12
|
+
exported: string;
|
|
13
|
+
isModuleAlias?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** Per-language named binding extractor -- optional (returns undefined if language has no named imports). */
|
|
16
|
+
export type NamedBindingExtractorFn = (importNode: SyntaxNode) => NamedBinding[] | undefined;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { findChild } from '../utils/ast-helpers.js';
|
|
2
|
+
export function extractTsNamedBindings(importNode) {
|
|
3
|
+
// import_statement > import_clause > named_imports > import_specifier*
|
|
4
|
+
const importClause = findChild(importNode, 'import_clause');
|
|
5
|
+
if (importClause) {
|
|
6
|
+
const namedImports = findChild(importClause, 'named_imports');
|
|
7
|
+
if (!namedImports)
|
|
8
|
+
return undefined; // default import, namespace import, or side-effect
|
|
9
|
+
const bindings = [];
|
|
10
|
+
for (let i = 0; i < namedImports.namedChildCount; i++) {
|
|
11
|
+
const specifier = namedImports.namedChild(i);
|
|
12
|
+
if (specifier?.type !== 'import_specifier')
|
|
13
|
+
continue;
|
|
14
|
+
const identifiers = [];
|
|
15
|
+
for (let j = 0; j < specifier.namedChildCount; j++) {
|
|
16
|
+
const child = specifier.namedChild(j);
|
|
17
|
+
if (child?.type === 'identifier')
|
|
18
|
+
identifiers.push(child.text);
|
|
19
|
+
}
|
|
20
|
+
if (identifiers.length === 1) {
|
|
21
|
+
bindings.push({ local: identifiers[0], exported: identifiers[0] });
|
|
22
|
+
}
|
|
23
|
+
else if (identifiers.length === 2) {
|
|
24
|
+
// import { Foo as Bar } → exported='Foo', local='Bar'
|
|
25
|
+
bindings.push({ local: identifiers[1], exported: identifiers[0] });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return bindings.length > 0 ? bindings : undefined;
|
|
29
|
+
}
|
|
30
|
+
// Re-export: export { X } from './y' → export_statement > export_clause > export_specifier
|
|
31
|
+
const exportClause = findChild(importNode, 'export_clause');
|
|
32
|
+
if (exportClause) {
|
|
33
|
+
const bindings = [];
|
|
34
|
+
for (let i = 0; i < exportClause.namedChildCount; i++) {
|
|
35
|
+
const specifier = exportClause.namedChild(i);
|
|
36
|
+
if (specifier?.type !== 'export_specifier')
|
|
37
|
+
continue;
|
|
38
|
+
const identifiers = [];
|
|
39
|
+
for (let j = 0; j < specifier.namedChildCount; j++) {
|
|
40
|
+
const child = specifier.namedChild(j);
|
|
41
|
+
if (child?.type === 'identifier')
|
|
42
|
+
identifiers.push(child.text);
|
|
43
|
+
}
|
|
44
|
+
if (identifiers.length === 1) {
|
|
45
|
+
// export { User } from './base' → re-exports User as User
|
|
46
|
+
bindings.push({ local: identifiers[0], exported: identifiers[0] });
|
|
47
|
+
}
|
|
48
|
+
else if (identifiers.length === 2) {
|
|
49
|
+
// export { Repo as Repository } from './models' → name=Repo, alias=Repository
|
|
50
|
+
// For re-exports, the first id is the source name, second is what's exported
|
|
51
|
+
// When another file imports { Repository }, they get Repo from the source
|
|
52
|
+
bindings.push({ local: identifiers[1], exported: identifiers[0] });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return bindings.length > 0 ? bindings : undefined;
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
@@ -2,7 +2,7 @@ import { KnowledgeGraph } from '../graph/types.js';
|
|
|
2
2
|
import { SymbolTable } from './symbol-table.js';
|
|
3
3
|
import { ASTCache } from './ast-cache.js';
|
|
4
4
|
import { WorkerPool } from './workers/worker-pool.js';
|
|
5
|
-
import type { ExtractedImport, ExtractedCall, ExtractedAssignment, ExtractedHeritage, ExtractedRoute, FileConstructorBindings } from './workers/parse-worker.js';
|
|
5
|
+
import type { ExtractedImport, ExtractedCall, ExtractedAssignment, ExtractedHeritage, ExtractedRoute, ExtractedFetchCall, ExtractedDecoratorRoute, ExtractedToolDef, FileConstructorBindings, FileTypeEnvBindings, ExtractedORMQuery } from './workers/parse-worker.js';
|
|
6
6
|
export type FileProgressCallback = (current: number, total: number, filePath: string) => void;
|
|
7
7
|
export interface WorkerExtractedData {
|
|
8
8
|
imports: ExtractedImport[];
|
|
@@ -10,9 +10,13 @@ export interface WorkerExtractedData {
|
|
|
10
10
|
assignments: ExtractedAssignment[];
|
|
11
11
|
heritage: ExtractedHeritage[];
|
|
12
12
|
routes: ExtractedRoute[];
|
|
13
|
+
fetchCalls: ExtractedFetchCall[];
|
|
14
|
+
decoratorRoutes: ExtractedDecoratorRoute[];
|
|
15
|
+
toolDefs: ExtractedToolDef[];
|
|
16
|
+
ormQueries: ExtractedORMQuery[];
|
|
13
17
|
constructorBindings: FileConstructorBindings[];
|
|
18
|
+
typeEnvBindings: FileTypeEnvBindings[];
|
|
14
19
|
}
|
|
15
|
-
export { isNodeExported } from './export-detection.js';
|
|
16
20
|
export declare const processParsing: (graph: KnowledgeGraph, files: {
|
|
17
21
|
path: string;
|
|
18
22
|
content: string;
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import Parser from 'tree-sitter';
|
|
2
2
|
import { loadParser, loadLanguage, isLanguageAvailable } from '../tree-sitter/parser-loader.js';
|
|
3
|
-
import {
|
|
3
|
+
import { getProvider } from './languages/index.js';
|
|
4
4
|
import { generateId } from '../../lib/utils.js';
|
|
5
|
-
import { getLanguageFromFilename
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { getLanguageFromFilename } from './utils/language-detection.js';
|
|
6
|
+
import { yieldToEventLoop } from './utils/event-loop.js';
|
|
7
|
+
import { getDefinitionNodeFromCaptures, findEnclosingClassId, extractMethodSignature, getLabelFromCaptures, CLASS_CONTAINER_TYPES } from './utils/ast-helpers.js';
|
|
8
8
|
import { detectFrameworkFromAST } from './framework-detection.js';
|
|
9
|
-
import {
|
|
10
|
-
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
9
|
+
import { buildTypeEnv } from './type-env.js';
|
|
11
10
|
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
11
|
// ============================================================================
|
|
16
12
|
// Worker-based parallel parsing
|
|
17
13
|
// ============================================================================
|
|
@@ -24,7 +20,7 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
24
20
|
parseableFiles.push({ path: file.path, content: file.content });
|
|
25
21
|
}
|
|
26
22
|
if (parseableFiles.length === 0)
|
|
27
|
-
return { imports: [], calls: [], assignments: [], heritage: [], routes: [], constructorBindings: [] };
|
|
23
|
+
return { imports: [], calls: [], assignments: [], heritage: [], routes: [], fetchCalls: [], decoratorRoutes: [], toolDefs: [], ormQueries: [], constructorBindings: [], typeEnvBindings: [] };
|
|
28
24
|
const total = files.length;
|
|
29
25
|
// Dispatch to worker pool — pool handles splitting into chunks and sub-batching
|
|
30
26
|
const chunkResults = await workerPool.dispatch(parseableFiles, (filesProcessed) => {
|
|
@@ -36,7 +32,12 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
36
32
|
const allAssignments = [];
|
|
37
33
|
const allHeritage = [];
|
|
38
34
|
const allRoutes = [];
|
|
35
|
+
const allFetchCalls = [];
|
|
36
|
+
const allDecoratorRoutes = [];
|
|
37
|
+
const allToolDefs = [];
|
|
38
|
+
const allORMQueries = [];
|
|
39
39
|
const allConstructorBindings = [];
|
|
40
|
+
const allTypeEnvBindings = [];
|
|
40
41
|
for (const result of chunkResults) {
|
|
41
42
|
for (const node of result.nodes) {
|
|
42
43
|
graph.addNode({
|
|
@@ -51,6 +52,8 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
51
52
|
for (const sym of result.symbols) {
|
|
52
53
|
symbolTable.add(sym.filePath, sym.name, sym.nodeId, sym.type, {
|
|
53
54
|
parameterCount: sym.parameterCount,
|
|
55
|
+
requiredParameterCount: sym.requiredParameterCount,
|
|
56
|
+
parameterTypes: sym.parameterTypes,
|
|
54
57
|
returnType: sym.returnType,
|
|
55
58
|
declaredType: sym.declaredType,
|
|
56
59
|
ownerId: sym.ownerId,
|
|
@@ -61,7 +64,13 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
61
64
|
allAssignments.push(...result.assignments);
|
|
62
65
|
allHeritage.push(...result.heritage);
|
|
63
66
|
allRoutes.push(...result.routes);
|
|
67
|
+
allFetchCalls.push(...result.fetchCalls);
|
|
68
|
+
allDecoratorRoutes.push(...result.decoratorRoutes);
|
|
69
|
+
allToolDefs.push(...result.toolDefs);
|
|
70
|
+
if (result.ormQueries)
|
|
71
|
+
allORMQueries.push(...result.ormQueries);
|
|
64
72
|
allConstructorBindings.push(...result.constructorBindings);
|
|
73
|
+
allTypeEnvBindings.push(...result.typeEnvBindings);
|
|
65
74
|
}
|
|
66
75
|
// Merge and log skipped languages from workers
|
|
67
76
|
const skippedLanguages = new Map();
|
|
@@ -78,17 +87,75 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
78
87
|
}
|
|
79
88
|
// Final progress
|
|
80
89
|
onFileProgress?.(total, total, 'done');
|
|
81
|
-
return { imports: allImports, calls: allCalls, assignments: allAssignments, heritage: allHeritage, routes: allRoutes, constructorBindings: allConstructorBindings };
|
|
90
|
+
return { imports: allImports, calls: allCalls, assignments: allAssignments, heritage: allHeritage, routes: allRoutes, fetchCalls: allFetchCalls, decoratorRoutes: allDecoratorRoutes, toolDefs: allToolDefs, ormQueries: allORMQueries, constructorBindings: allConstructorBindings, typeEnvBindings: allTypeEnvBindings };
|
|
82
91
|
};
|
|
83
92
|
// ============================================================================
|
|
84
93
|
// Sequential fallback (original implementation)
|
|
85
94
|
// ============================================================================
|
|
95
|
+
// Inline caches to avoid repeated parent-walks per node (same pattern as parse-worker.ts).
|
|
96
|
+
// Keyed by tree-sitter node reference — cleared at the start of each file.
|
|
97
|
+
const classIdCache = new Map();
|
|
98
|
+
const exportCache = new Map();
|
|
99
|
+
const cachedFindEnclosingClassId = (node, filePath) => {
|
|
100
|
+
const cached = classIdCache.get(node);
|
|
101
|
+
if (cached !== undefined)
|
|
102
|
+
return cached;
|
|
103
|
+
const result = findEnclosingClassId(node, filePath);
|
|
104
|
+
classIdCache.set(node, result);
|
|
105
|
+
return result;
|
|
106
|
+
};
|
|
107
|
+
const cachedExportCheck = (checker, node, name) => {
|
|
108
|
+
const cached = exportCache.get(node);
|
|
109
|
+
if (cached !== undefined)
|
|
110
|
+
return cached;
|
|
111
|
+
const result = checker(node, name);
|
|
112
|
+
exportCache.set(node, result);
|
|
113
|
+
return result;
|
|
114
|
+
};
|
|
115
|
+
// FieldExtractor cache for sequential path — same pattern as parse-worker.ts
|
|
116
|
+
const seqFieldInfoCache = new Map();
|
|
117
|
+
function seqFindEnclosingClassNode(node) {
|
|
118
|
+
let current = node.parent;
|
|
119
|
+
while (current) {
|
|
120
|
+
if (CLASS_CONTAINER_TYPES.has(current.type))
|
|
121
|
+
return current;
|
|
122
|
+
current = current.parent;
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
/** Minimal no-op SymbolTable stub for FieldExtractorContext (sequential path has a real
|
|
127
|
+
* SymbolTable, but it's incomplete at this stage — use the stub for safety). */
|
|
128
|
+
const NOOP_SYMBOL_TABLE_SEQ = {
|
|
129
|
+
lookupExactAll: () => [],
|
|
130
|
+
lookupExact: () => undefined,
|
|
131
|
+
lookupExactFull: () => undefined,
|
|
132
|
+
};
|
|
133
|
+
function seqGetFieldInfo(classNode, provider, context) {
|
|
134
|
+
if (!provider.fieldExtractor)
|
|
135
|
+
return undefined;
|
|
136
|
+
const cacheKey = classNode.startIndex;
|
|
137
|
+
let cached = seqFieldInfoCache.get(cacheKey);
|
|
138
|
+
if (cached)
|
|
139
|
+
return cached;
|
|
140
|
+
const extracted = provider.fieldExtractor.extract(classNode, context);
|
|
141
|
+
if (!extracted?.fields?.length)
|
|
142
|
+
return undefined;
|
|
143
|
+
cached = new Map();
|
|
144
|
+
for (const field of extracted.fields)
|
|
145
|
+
cached.set(field.name, field);
|
|
146
|
+
seqFieldInfoCache.set(cacheKey, cached);
|
|
147
|
+
return cached;
|
|
148
|
+
}
|
|
86
149
|
const processParsingSequential = async (graph, files, symbolTable, astCache, onFileProgress) => {
|
|
87
150
|
const parser = await loadParser();
|
|
88
151
|
const total = files.length;
|
|
89
152
|
const skippedLanguages = new Map();
|
|
90
153
|
for (let i = 0; i < files.length; i++) {
|
|
91
154
|
const file = files[i];
|
|
155
|
+
// Reset memoization before each new file (node refs are per-tree)
|
|
156
|
+
classIdCache.clear();
|
|
157
|
+
exportCache.clear();
|
|
158
|
+
seqFieldInfoCache.clear();
|
|
92
159
|
onFileProgress?.(i + 1, total, file.path);
|
|
93
160
|
if (i % 20 === 0)
|
|
94
161
|
await yieldToEventLoop();
|
|
@@ -118,7 +185,8 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
|
|
|
118
185
|
continue;
|
|
119
186
|
}
|
|
120
187
|
astCache.set(file.path, tree);
|
|
121
|
-
const
|
|
188
|
+
const provider = getProvider(language);
|
|
189
|
+
const queryString = provider.treeSitterQueries;
|
|
122
190
|
if (!queryString) {
|
|
123
191
|
continue;
|
|
124
192
|
}
|
|
@@ -133,82 +201,21 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
|
|
|
133
201
|
console.warn(`Query error for ${file.path}:`, queryError);
|
|
134
202
|
continue;
|
|
135
203
|
}
|
|
204
|
+
// Build per-file type environment for FieldExtractor context (lightweight — skipped if no fieldExtractor)
|
|
205
|
+
const typeEnv = provider.fieldExtractor ? buildTypeEnv(tree, language, { enclosingFunctionFinder: provider.enclosingFunctionFinder }) : null;
|
|
136
206
|
matches.forEach(match => {
|
|
137
207
|
const captureMap = {};
|
|
138
208
|
match.captures.forEach(c => {
|
|
139
209
|
captureMap[c.name] = c.node;
|
|
140
210
|
});
|
|
141
|
-
|
|
211
|
+
const nodeLabel = getLabelFromCaptures(captureMap, provider);
|
|
212
|
+
if (!nodeLabel)
|
|
142
213
|
return;
|
|
143
|
-
}
|
|
144
|
-
if (captureMap['call']) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
214
|
const nameNode = captureMap['name'];
|
|
148
215
|
// Synthesize name for constructors without explicit @name capture (e.g. Swift init)
|
|
149
|
-
if (!nameNode &&
|
|
216
|
+
if (!nameNode && nodeLabel !== 'Constructor')
|
|
150
217
|
return;
|
|
151
218
|
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
219
|
const definitionNodeForRange = getDefinitionNodeFromCaptures(captureMap);
|
|
213
220
|
const startLine = definitionNodeForRange ? definitionNodeForRange.startPosition.row : (nameNode ? nameNode.startPosition.row : 0);
|
|
214
221
|
const nodeId = generateId(nodeLabel, `${file.path}:${nodeName}`);
|
|
@@ -223,7 +230,7 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
|
|
|
223
230
|
// Language-specific return type fallback (e.g. Ruby YARD @return [Type])
|
|
224
231
|
// Also upgrades uninformative AST types like PHP `array` with PHPDoc `@return User[]`
|
|
225
232
|
if (methodSig && (!methodSig.returnType || methodSig.returnType === 'array' || methodSig.returnType === 'iterable') && definitionNode) {
|
|
226
|
-
const tc =
|
|
233
|
+
const tc = provider.typeConfig;
|
|
227
234
|
if (tc?.extractReturnType) {
|
|
228
235
|
const docReturn = tc.extractReturnType(definitionNode);
|
|
229
236
|
if (docReturn)
|
|
@@ -239,13 +246,15 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
|
|
|
239
246
|
startLine: definitionNodeForRange ? definitionNodeForRange.startPosition.row : startLine,
|
|
240
247
|
endLine: definitionNodeForRange ? definitionNodeForRange.endPosition.row : startLine,
|
|
241
248
|
language: language,
|
|
242
|
-
isExported:
|
|
249
|
+
isExported: cachedExportCheck(provider.exportChecker, nameNode || definitionNodeForRange, nodeName),
|
|
243
250
|
...(frameworkHint ? {
|
|
244
251
|
astFrameworkMultiplier: frameworkHint.entryPointMultiplier,
|
|
245
252
|
astFrameworkReason: frameworkHint.reason,
|
|
246
253
|
} : {}),
|
|
247
254
|
...(methodSig ? {
|
|
248
255
|
parameterCount: methodSig.parameterCount,
|
|
256
|
+
...(methodSig.requiredParameterCount !== undefined ? { requiredParameterCount: methodSig.requiredParameterCount } : {}),
|
|
257
|
+
...(methodSig.parameterTypes ? { parameterTypes: methodSig.parameterTypes } : {}),
|
|
249
258
|
returnType: methodSig.returnType,
|
|
250
259
|
} : {}),
|
|
251
260
|
},
|
|
@@ -254,13 +263,44 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
|
|
|
254
263
|
// Compute enclosing class for Method/Constructor/Property/Function — used for both ownerId and HAS_METHOD
|
|
255
264
|
// Function is included because Kotlin/Rust/Python capture class methods as Function nodes
|
|
256
265
|
const needsOwner = nodeLabel === 'Method' || nodeLabel === 'Constructor' || nodeLabel === 'Property' || nodeLabel === 'Function';
|
|
257
|
-
const enclosingClassId = needsOwner ?
|
|
258
|
-
// Extract declared type for Property nodes
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
266
|
+
const enclosingClassId = needsOwner ? cachedFindEnclosingClassId(nameNode || definitionNodeForRange, file.path) : null;
|
|
267
|
+
// Extract declared type and field metadata for Property nodes
|
|
268
|
+
let declaredType;
|
|
269
|
+
let seqVisibility;
|
|
270
|
+
let seqIsStatic;
|
|
271
|
+
let seqIsReadonly;
|
|
272
|
+
if (nodeLabel === 'Property' && definitionNode) {
|
|
273
|
+
// FieldExtractor is the single source of truth when available
|
|
274
|
+
if (provider.fieldExtractor && typeEnv) {
|
|
275
|
+
const classNode = seqFindEnclosingClassNode(definitionNode);
|
|
276
|
+
if (classNode) {
|
|
277
|
+
const fieldMap = seqGetFieldInfo(classNode, provider, {
|
|
278
|
+
typeEnv, symbolTable: NOOP_SYMBOL_TABLE_SEQ, filePath: file.path, language,
|
|
279
|
+
});
|
|
280
|
+
const info = fieldMap?.get(nodeName);
|
|
281
|
+
if (info) {
|
|
282
|
+
declaredType = info.type ?? undefined;
|
|
283
|
+
seqVisibility = info.visibility;
|
|
284
|
+
seqIsStatic = info.isStatic;
|
|
285
|
+
seqIsReadonly = info.isReadonly;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// All 14 languages register a FieldExtractor — no fallback needed.
|
|
290
|
+
}
|
|
291
|
+
// Apply field metadata to the graph node retroactively
|
|
292
|
+
if (seqVisibility !== undefined)
|
|
293
|
+
node.properties.visibility = seqVisibility;
|
|
294
|
+
if (seqIsStatic !== undefined)
|
|
295
|
+
node.properties.isStatic = seqIsStatic;
|
|
296
|
+
if (seqIsReadonly !== undefined)
|
|
297
|
+
node.properties.isReadonly = seqIsReadonly;
|
|
298
|
+
if (declaredType !== undefined)
|
|
299
|
+
node.properties.declaredType = declaredType;
|
|
262
300
|
symbolTable.add(file.path, nodeName, nodeId, nodeLabel, {
|
|
263
301
|
parameterCount: methodSig?.parameterCount,
|
|
302
|
+
requiredParameterCount: methodSig?.requiredParameterCount,
|
|
303
|
+
parameterTypes: methodSig?.parameterTypes,
|
|
264
304
|
returnType: methodSig?.returnType,
|
|
265
305
|
declaredType,
|
|
266
306
|
ownerId: enclosingClassId ?? undefined,
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { PipelineProgress, PipelineResult } from '../../types/pipeline.js';
|
|
2
|
+
/** A group of files with no mutual dependencies, safe to process in parallel. */
|
|
3
|
+
type IndependentFileGroup = readonly string[];
|
|
4
|
+
/** Kahn's algorithm: returns files grouped by topological level.
|
|
5
|
+
* Files in the same level have no mutual dependencies — safe to process in parallel.
|
|
6
|
+
* Files in cycles are returned as a final group (no cross-cycle propagation). */
|
|
7
|
+
export declare function topologicalLevelSort(importMap: ReadonlyMap<string, ReadonlySet<string>>): {
|
|
8
|
+
levels: readonly IndependentFileGroup[];
|
|
9
|
+
cycleCount: number;
|
|
10
|
+
};
|
|
2
11
|
export interface PipelineOptions {
|
|
3
12
|
/** Skip MRO, community detection, and process extraction for faster test runs. */
|
|
4
13
|
skipGraphPhases?: boolean;
|
|
5
14
|
}
|
|
6
15
|
export declare const runPipelineFromRepo: (repoPath: string, onProgress: (progress: PipelineProgress) => void, options?: PipelineOptions) => Promise<PipelineResult>;
|
|
16
|
+
export {};
|