gitnexus 1.4.1 → 1.4.6
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 +215 -194
- package/dist/cli/ai-context.d.ts +2 -1
- package/dist/cli/ai-context.js +117 -90
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +57 -30
- package/dist/cli/augment.js +1 -1
- package/dist/cli/eval-server.d.ts +1 -1
- package/dist/cli/eval-server.js +14 -6
- package/dist/cli/index.js +18 -25
- package/dist/cli/lazy-action.d.ts +6 -0
- package/dist/cli/lazy-action.js +18 -0
- package/dist/cli/mcp.js +1 -1
- package/dist/cli/setup.js +42 -32
- 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 +48 -13
- package/dist/cli/wiki.js +2 -2
- package/dist/config/ignore-service.d.ts +25 -0
- package/dist/config/ignore-service.js +76 -0
- package/dist/config/supported-languages.d.ts +1 -0
- package/dist/config/supported-languages.js +1 -1
- package/dist/core/augmentation/engine.js +99 -72
- 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 +74 -47
- package/dist/core/embeddings/types.d.ts +1 -1
- package/dist/core/graph/types.d.ts +5 -2
- package/dist/core/ingestion/ast-cache.js +3 -2
- package/dist/core/ingestion/call-processor.d.ts +5 -7
- package/dist/core/ingestion/call-processor.js +430 -283
- package/dist/core/ingestion/call-routing.d.ts +53 -0
- package/dist/core/ingestion/call-routing.js +108 -0
- package/dist/core/ingestion/cluster-enricher.js +16 -16
- 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 +94 -24
- 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 +5 -1
- package/dist/core/ingestion/framework-detection.js +48 -8
- 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 +202 -696
- 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 +3 -11
- package/dist/core/ingestion/parsing-processor.js +85 -181
- package/dist/core/ingestion/pipeline.d.ts +5 -1
- package/dist/core/ingestion/pipeline.js +192 -116
- package/dist/core/ingestion/process-processor.js +2 -1
- 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 +12 -11
- package/dist/core/ingestion/tree-sitter-queries.js +642 -485
- 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/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 +98 -0
- package/dist/core/ingestion/utils.js +1064 -9
- package/dist/core/ingestion/workers/parse-worker.d.ts +38 -4
- package/dist/core/ingestion/workers/parse-worker.js +251 -359
- package/dist/core/ingestion/workers/worker-pool.js +8 -0
- package/dist/core/{kuzu → lbug}/csv-generator.d.ts +1 -1
- package/dist/core/{kuzu → lbug}/csv-generator.js +20 -4
- package/dist/core/{kuzu/kuzu-adapter.d.ts → lbug/lbug-adapter.d.ts} +19 -19
- package/dist/core/{kuzu/kuzu-adapter.js → lbug/lbug-adapter.js} +82 -82
- package/dist/core/{kuzu → lbug}/schema.d.ts +4 -4
- package/dist/core/{kuzu → lbug}/schema.js +304 -289
- package/dist/core/search/bm25-index.d.ts +4 -4
- package/dist/core/search/bm25-index.js +17 -16
- package/dist/core/search/hybrid-search.d.ts +2 -2
- package/dist/core/search/hybrid-search.js +9 -9
- package/dist/core/tree-sitter/parser-loader.js +9 -2
- package/dist/core/wiki/generator.d.ts +4 -52
- package/dist/core/wiki/generator.js +53 -552
- package/dist/core/wiki/graph-queries.d.ts +4 -46
- package/dist/core/wiki/graph-queries.js +103 -282
- package/dist/core/wiki/html-viewer.js +192 -192
- package/dist/core/wiki/llm-client.js +11 -73
- package/dist/core/wiki/prompts.d.ts +8 -52
- package/dist/core/wiki/prompts.js +86 -200
- 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} +7 -9
- package/dist/mcp/core/{kuzu-adapter.js → lbug-adapter.js} +77 -79
- package/dist/mcp/local/local-backend.d.ts +7 -6
- package/dist/mcp/local/local-backend.js +176 -147
- package/dist/mcp/resources.js +42 -42
- package/dist/mcp/server.js +18 -19
- package/dist/mcp/tools.js +103 -104
- 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/repo-manager.d.ts +20 -2
- package/dist/storage/repo-manager.js +55 -1
- package/dist/types/pipeline.d.ts +1 -1
- package/hooks/claude/gitnexus-hook.cjs +238 -155
- package/hooks/claude/pre-tool-use.sh +79 -79
- package/hooks/claude/session-start.sh +42 -42
- package/package.json +99 -96
- package/scripts/patch-tree-sitter-swift.cjs +74 -74
- package/skills/gitnexus-cli.md +82 -82
- package/skills/gitnexus-debugging.md +89 -89
- package/skills/gitnexus-exploring.md +78 -78
- package/skills/gitnexus-guide.md +64 -64
- package/skills/gitnexus-impact-analysis.md +97 -97
- package/skills/gitnexus-pr-review.md +163 -163
- package/skills/gitnexus-refactoring.md +121 -121
- package/vendor/leiden/index.cjs +355 -355
- package/vendor/leiden/utils.cjs +392 -392
- package/dist/core/wiki/diagrams.d.ts +0 -27
- package/dist/core/wiki/diagrams.js +0 -163
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export Detection
|
|
3
|
+
*
|
|
4
|
+
* Determines whether a symbol (function, class, etc.) is exported/public
|
|
5
|
+
* in its language. This is a pure function — safe for use in worker threads.
|
|
6
|
+
*
|
|
7
|
+
* Shared between parse-worker.ts (worker pool) and parsing-processor.ts (sequential fallback).
|
|
8
|
+
*/
|
|
9
|
+
import { findSiblingChild } from './utils.js';
|
|
10
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Per-language export checkers
|
|
13
|
+
// ============================================================================
|
|
14
|
+
/** JS/TS: walk ancestors looking for export_statement or export_specifier. */
|
|
15
|
+
const tsExportChecker = (node, _name) => {
|
|
16
|
+
let current = node;
|
|
17
|
+
while (current) {
|
|
18
|
+
const type = current.type;
|
|
19
|
+
if (type === 'export_statement' ||
|
|
20
|
+
type === 'export_specifier' ||
|
|
21
|
+
(type === 'lexical_declaration' && current.parent?.type === 'export_statement')) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
// Fallback: check if node text starts with 'export ' for edge cases
|
|
25
|
+
if (current.text?.startsWith('export ')) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
current = current.parent;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
32
|
+
/** Python: public if no leading underscore (convention). */
|
|
33
|
+
const pythonExportChecker = (_node, name) => !name.startsWith('_');
|
|
34
|
+
/** Java: check for 'public' modifier — modifiers are siblings of the name node, not parents. */
|
|
35
|
+
const javaExportChecker = (node, _name) => {
|
|
36
|
+
let current = node;
|
|
37
|
+
while (current) {
|
|
38
|
+
if (current.parent) {
|
|
39
|
+
const parent = current.parent;
|
|
40
|
+
for (let i = 0; i < parent.childCount; i++) {
|
|
41
|
+
const child = parent.child(i);
|
|
42
|
+
if (child?.type === 'modifiers' && child.text?.includes('public')) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (parent.type === 'method_declaration' || parent.type === 'constructor_declaration') {
|
|
47
|
+
if (parent.text?.trimStart().startsWith('public')) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
current = current.parent;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
};
|
|
56
|
+
/** C# declaration node types for sibling modifier scanning. */
|
|
57
|
+
const CSHARP_DECL_TYPES = new Set([
|
|
58
|
+
'method_declaration', 'local_function_statement', 'constructor_declaration',
|
|
59
|
+
'class_declaration', 'interface_declaration', 'struct_declaration',
|
|
60
|
+
'enum_declaration', 'record_declaration', 'record_struct_declaration',
|
|
61
|
+
'record_class_declaration', 'delegate_declaration',
|
|
62
|
+
'property_declaration', 'field_declaration', 'event_declaration',
|
|
63
|
+
'namespace_declaration', 'file_scoped_namespace_declaration',
|
|
64
|
+
]);
|
|
65
|
+
/**
|
|
66
|
+
* C#: modifier nodes are SIBLINGS of the name node inside the declaration.
|
|
67
|
+
* Walk up to the declaration node, then scan its direct children.
|
|
68
|
+
*/
|
|
69
|
+
const csharpExportChecker = (node, _name) => {
|
|
70
|
+
let current = node;
|
|
71
|
+
while (current) {
|
|
72
|
+
if (CSHARP_DECL_TYPES.has(current.type)) {
|
|
73
|
+
for (let i = 0; i < current.childCount; i++) {
|
|
74
|
+
const child = current.child(i);
|
|
75
|
+
if (child?.type === 'modifier' && child.text === 'public')
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
current = current.parent;
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
};
|
|
84
|
+
/** Go: uppercase first letter = exported. */
|
|
85
|
+
const goExportChecker = (_node, name) => {
|
|
86
|
+
if (name.length === 0)
|
|
87
|
+
return false;
|
|
88
|
+
const first = name[0];
|
|
89
|
+
return first === first.toUpperCase() && first !== first.toLowerCase();
|
|
90
|
+
};
|
|
91
|
+
/** Rust declaration node types for sibling visibility_modifier scanning. */
|
|
92
|
+
const RUST_DECL_TYPES = new Set([
|
|
93
|
+
'function_item', 'struct_item', 'enum_item', 'trait_item', 'impl_item',
|
|
94
|
+
'union_item', 'type_item', 'const_item', 'static_item', 'mod_item',
|
|
95
|
+
'use_declaration', 'associated_type', 'function_signature_item',
|
|
96
|
+
]);
|
|
97
|
+
/**
|
|
98
|
+
* Rust: visibility_modifier is a SIBLING of the name node within the declaration node
|
|
99
|
+
* (function_item, struct_item, etc.), not a parent. Walk up to the declaration node,
|
|
100
|
+
* then scan its direct children.
|
|
101
|
+
*/
|
|
102
|
+
const rustExportChecker = (node, _name) => {
|
|
103
|
+
let current = node;
|
|
104
|
+
while (current) {
|
|
105
|
+
if (RUST_DECL_TYPES.has(current.type)) {
|
|
106
|
+
for (let i = 0; i < current.childCount; i++) {
|
|
107
|
+
const child = current.child(i);
|
|
108
|
+
if (child?.type === 'visibility_modifier' && child.text?.startsWith('pub'))
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
current = current.parent;
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Kotlin: default visibility is public (unlike Java).
|
|
119
|
+
* visibility_modifier is inside modifiers, a sibling of the name node within the declaration.
|
|
120
|
+
*/
|
|
121
|
+
const kotlinExportChecker = (node, _name) => {
|
|
122
|
+
let current = node;
|
|
123
|
+
while (current) {
|
|
124
|
+
if (current.parent) {
|
|
125
|
+
const visMod = findSiblingChild(current.parent, 'modifiers', 'visibility_modifier');
|
|
126
|
+
if (visMod) {
|
|
127
|
+
const text = visMod.text;
|
|
128
|
+
if (text === 'private' || text === 'internal' || text === 'protected')
|
|
129
|
+
return false;
|
|
130
|
+
if (text === 'public')
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
current = current.parent;
|
|
135
|
+
}
|
|
136
|
+
// No visibility modifier = public (Kotlin default)
|
|
137
|
+
return true;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* C/C++: functions without 'static' storage class have external linkage by default,
|
|
141
|
+
* making them globally accessible (equivalent to exported). Only functions explicitly
|
|
142
|
+
* marked 'static' are file-scoped (not exported). C++ anonymous namespaces
|
|
143
|
+
* (namespace { ... }) also give internal linkage.
|
|
144
|
+
*/
|
|
145
|
+
const cCppExportChecker = (node, _name) => {
|
|
146
|
+
let cur = node;
|
|
147
|
+
while (cur) {
|
|
148
|
+
if (cur.type === 'function_definition' || cur.type === 'declaration') {
|
|
149
|
+
// Check for 'static' storage class specifier as a direct child node.
|
|
150
|
+
// This avoids reading the full function text (which can be very large).
|
|
151
|
+
for (let i = 0; i < cur.childCount; i++) {
|
|
152
|
+
const child = cur.child(i);
|
|
153
|
+
if (child?.type === 'storage_class_specifier' && child.text === 'static')
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// C++ anonymous namespace: namespace_definition with no name child = internal linkage
|
|
158
|
+
if (cur.type === 'namespace_definition') {
|
|
159
|
+
const hasName = cur.childForFieldName?.('name');
|
|
160
|
+
if (!hasName)
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
cur = cur.parent;
|
|
164
|
+
}
|
|
165
|
+
return true; // Top-level C/C++ functions default to external linkage
|
|
166
|
+
};
|
|
167
|
+
/** PHP: check for visibility modifier or top-level scope. */
|
|
168
|
+
const phpExportChecker = (node, _name) => {
|
|
169
|
+
let current = node;
|
|
170
|
+
while (current) {
|
|
171
|
+
if (current.type === 'class_declaration' ||
|
|
172
|
+
current.type === 'interface_declaration' ||
|
|
173
|
+
current.type === 'trait_declaration' ||
|
|
174
|
+
current.type === 'enum_declaration') {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
if (current.type === 'visibility_modifier') {
|
|
178
|
+
return current.text === 'public';
|
|
179
|
+
}
|
|
180
|
+
current = current.parent;
|
|
181
|
+
}
|
|
182
|
+
// Top-level functions are globally accessible
|
|
183
|
+
return true;
|
|
184
|
+
};
|
|
185
|
+
/** Swift: check for 'public' or 'open' access modifiers. */
|
|
186
|
+
const swiftExportChecker = (node, _name) => {
|
|
187
|
+
let current = node;
|
|
188
|
+
while (current) {
|
|
189
|
+
if (current.type === 'modifiers' || current.type === 'visibility_modifier') {
|
|
190
|
+
const text = current.text || '';
|
|
191
|
+
if (text.includes('public') || text.includes('open'))
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
current = current.parent;
|
|
195
|
+
}
|
|
196
|
+
return false;
|
|
197
|
+
};
|
|
198
|
+
// ============================================================================
|
|
199
|
+
// Exhaustive dispatch table — satisfies enforces all SupportedLanguages are covered
|
|
200
|
+
// ============================================================================
|
|
201
|
+
const exportCheckers = {
|
|
202
|
+
[SupportedLanguages.JavaScript]: tsExportChecker,
|
|
203
|
+
[SupportedLanguages.TypeScript]: tsExportChecker,
|
|
204
|
+
[SupportedLanguages.Python]: pythonExportChecker,
|
|
205
|
+
[SupportedLanguages.Java]: javaExportChecker,
|
|
206
|
+
[SupportedLanguages.CSharp]: csharpExportChecker,
|
|
207
|
+
[SupportedLanguages.Go]: goExportChecker,
|
|
208
|
+
[SupportedLanguages.Rust]: rustExportChecker,
|
|
209
|
+
[SupportedLanguages.Kotlin]: kotlinExportChecker,
|
|
210
|
+
[SupportedLanguages.C]: cCppExportChecker,
|
|
211
|
+
[SupportedLanguages.CPlusPlus]: cCppExportChecker,
|
|
212
|
+
[SupportedLanguages.PHP]: phpExportChecker,
|
|
213
|
+
[SupportedLanguages.Swift]: swiftExportChecker,
|
|
214
|
+
[SupportedLanguages.Ruby]: (_node, _name) => true,
|
|
215
|
+
};
|
|
216
|
+
// ============================================================================
|
|
217
|
+
// Public API
|
|
218
|
+
// ============================================================================
|
|
219
|
+
/**
|
|
220
|
+
* Check if a tree-sitter node is exported/public in its language.
|
|
221
|
+
* @param node - The tree-sitter AST node
|
|
222
|
+
* @param name - The symbol name
|
|
223
|
+
* @param language - The programming language
|
|
224
|
+
* @returns true if the symbol is exported/public
|
|
225
|
+
*/
|
|
226
|
+
export const isNodeExported = (node, name, language) => {
|
|
227
|
+
const checker = exportCheckers[language];
|
|
228
|
+
if (!checker)
|
|
229
|
+
return false;
|
|
230
|
+
return checker(node, name);
|
|
231
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { glob } from 'glob';
|
|
4
|
-
import {
|
|
4
|
+
import { createIgnoreFilter } from '../../config/ignore-service.js';
|
|
5
5
|
const READ_CONCURRENCY = 32;
|
|
6
6
|
/** Skip files larger than 512KB — they're usually generated/vendored and crash tree-sitter */
|
|
7
7
|
const MAX_FILE_SIZE = 512 * 1024;
|
|
@@ -10,12 +10,13 @@ const MAX_FILE_SIZE = 512 * 1024;
|
|
|
10
10
|
* Memory: ~10MB for 100K files vs ~1GB+ with content.
|
|
11
11
|
*/
|
|
12
12
|
export const walkRepositoryPaths = async (repoPath, onProgress) => {
|
|
13
|
-
const
|
|
13
|
+
const ignoreFilter = await createIgnoreFilter(repoPath);
|
|
14
|
+
const filtered = await glob('**/*', {
|
|
14
15
|
cwd: repoPath,
|
|
15
16
|
nodir: true,
|
|
16
17
|
dot: false,
|
|
18
|
+
ignore: ignoreFilter,
|
|
17
19
|
});
|
|
18
|
-
const filtered = files.filter(file => !shouldIgnorePath(file));
|
|
19
20
|
const entries = [];
|
|
20
21
|
let processed = 0;
|
|
21
22
|
let skippedLarge = 0;
|
|
@@ -33,6 +33,9 @@ export declare const FRAMEWORK_AST_PATTERNS: {
|
|
|
33
33
|
spring: string[];
|
|
34
34
|
jaxrs: string[];
|
|
35
35
|
aspnet: string[];
|
|
36
|
+
signalr: string[];
|
|
37
|
+
blazor: string[];
|
|
38
|
+
efcore: string[];
|
|
36
39
|
'go-http': string[];
|
|
37
40
|
laravel: string[];
|
|
38
41
|
actix: string[];
|
|
@@ -42,9 +45,10 @@ export declare const FRAMEWORK_AST_PATTERNS: {
|
|
|
42
45
|
swiftui: string[];
|
|
43
46
|
combine: string[];
|
|
44
47
|
};
|
|
48
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
45
49
|
/**
|
|
46
50
|
* Detect framework entry points from AST definition text (decorators/annotations/attributes).
|
|
47
51
|
* Returns null if no known pattern is found.
|
|
48
52
|
* Note: callers should slice definitionText to ~300 chars since annotations appear at the start.
|
|
49
53
|
*/
|
|
50
|
-
export declare function detectFrameworkFromAST(language:
|
|
54
|
+
export declare function detectFrameworkFromAST(language: SupportedLanguages, definitionText: string): FrameworkHint | null;
|
|
@@ -140,6 +140,29 @@ export function detectFrameworkFromPath(filePath) {
|
|
|
140
140
|
if (p.endsWith('controller.cs')) {
|
|
141
141
|
return { framework: 'aspnet', entryPointMultiplier: 3.0, reason: 'aspnet-controller-file' };
|
|
142
142
|
}
|
|
143
|
+
// ASP.NET Services
|
|
144
|
+
if ((p.includes('/services/') || p.includes('/service/')) && p.endsWith('.cs')) {
|
|
145
|
+
return { framework: 'aspnet', entryPointMultiplier: 1.8, reason: 'aspnet-service' };
|
|
146
|
+
}
|
|
147
|
+
// ASP.NET Middleware
|
|
148
|
+
if (p.includes('/middleware/') && p.endsWith('.cs')) {
|
|
149
|
+
return { framework: 'aspnet', entryPointMultiplier: 2.5, reason: 'aspnet-middleware' };
|
|
150
|
+
}
|
|
151
|
+
// SignalR Hubs
|
|
152
|
+
if (p.includes('/hubs/') && p.endsWith('.cs')) {
|
|
153
|
+
return { framework: 'signalr', entryPointMultiplier: 2.5, reason: 'signalr-hub' };
|
|
154
|
+
}
|
|
155
|
+
if (p.endsWith('hub.cs')) {
|
|
156
|
+
return { framework: 'signalr', entryPointMultiplier: 2.5, reason: 'signalr-hub-file' };
|
|
157
|
+
}
|
|
158
|
+
// Minimal API / Program.cs / Startup.cs
|
|
159
|
+
if (p.endsWith('/program.cs') || p.endsWith('/startup.cs')) {
|
|
160
|
+
return { framework: 'aspnet', entryPointMultiplier: 3.0, reason: 'aspnet-entry' };
|
|
161
|
+
}
|
|
162
|
+
// Background services / Hosted services
|
|
163
|
+
if ((p.includes('/backgroundservices/') || p.includes('/hostedservices/')) && p.endsWith('.cs')) {
|
|
164
|
+
return { framework: 'aspnet', entryPointMultiplier: 2.0, reason: 'aspnet-background-service' };
|
|
165
|
+
}
|
|
143
166
|
// Blazor pages
|
|
144
167
|
if (p.includes('/pages/') && p.endsWith('.razor')) {
|
|
145
168
|
return { framework: 'blazor', entryPointMultiplier: 2.5, reason: 'blazor-page' };
|
|
@@ -232,6 +255,15 @@ export function detectFrameworkFromPath(filePath) {
|
|
|
232
255
|
if (p.includes('/repositories/') && p.endsWith('.php')) {
|
|
233
256
|
return { framework: 'laravel', entryPointMultiplier: 1.5, reason: 'laravel-repository' };
|
|
234
257
|
}
|
|
258
|
+
// ========== RUBY ==========
|
|
259
|
+
// Ruby: bin/ or exe/ (CLI entry points)
|
|
260
|
+
if ((p.includes('/bin/') || p.includes('/exe/')) && p.endsWith('.rb')) {
|
|
261
|
+
return { framework: 'ruby', entryPointMultiplier: 2.5, reason: 'ruby-executable' };
|
|
262
|
+
}
|
|
263
|
+
// Ruby: Rakefile or *.rake (task definitions)
|
|
264
|
+
if (p.endsWith('/rakefile') || p.endsWith('.rake')) {
|
|
265
|
+
return { framework: 'ruby', entryPointMultiplier: 1.5, reason: 'ruby-rake' };
|
|
266
|
+
}
|
|
235
267
|
// ========== SWIFT / iOS ==========
|
|
236
268
|
// iOS App entry points (highest priority)
|
|
237
269
|
if (p.endsWith('/appdelegate.swift') || p.endsWith('/scenedelegate.swift') || p.endsWith('/app.swift')) {
|
|
@@ -296,7 +328,11 @@ export const FRAMEWORK_AST_PATTERNS = {
|
|
|
296
328
|
'spring': ['@RestController', '@Controller', '@GetMapping', '@PostMapping', '@RequestMapping'],
|
|
297
329
|
'jaxrs': ['@Path', '@GET', '@POST', '@PUT', '@DELETE'],
|
|
298
330
|
// C# attributes
|
|
299
|
-
'aspnet': ['[ApiController]', '[HttpGet]', '[HttpPost]', '[
|
|
331
|
+
'aspnet': ['[ApiController]', '[HttpGet]', '[HttpPost]', '[HttpPut]', '[HttpDelete]',
|
|
332
|
+
'[Route]', '[Authorize]', '[AllowAnonymous]'],
|
|
333
|
+
'signalr': ['[HubMethodName]', ': Hub', ': Hub<'],
|
|
334
|
+
'blazor': ['@page', '[Parameter]', '@inject'],
|
|
335
|
+
'efcore': ['DbContext', 'DbSet<', 'OnModelCreating'],
|
|
300
336
|
// Go patterns (function signatures)
|
|
301
337
|
'go-http': ['http.Handler', 'http.HandlerFunc', 'ServeHTTP'],
|
|
302
338
|
// PHP/Laravel
|
|
@@ -311,31 +347,35 @@ export const FRAMEWORK_AST_PATTERNS = {
|
|
|
311
347
|
'swiftui': ['@main', 'WindowGroup', 'ContentView', '@StateObject', '@ObservedObject'],
|
|
312
348
|
'combine': ['sink', 'assign', 'Publisher', 'Subscriber'],
|
|
313
349
|
};
|
|
350
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
314
351
|
const AST_FRAMEWORK_PATTERNS_BY_LANGUAGE = {
|
|
315
|
-
|
|
352
|
+
[SupportedLanguages.JavaScript]: [
|
|
316
353
|
{ framework: 'nestjs', entryPointMultiplier: 3.2, reason: 'nestjs-decorator', patterns: FRAMEWORK_AST_PATTERNS.nestjs },
|
|
317
354
|
],
|
|
318
|
-
|
|
355
|
+
[SupportedLanguages.TypeScript]: [
|
|
319
356
|
{ framework: 'nestjs', entryPointMultiplier: 3.2, reason: 'nestjs-decorator', patterns: FRAMEWORK_AST_PATTERNS.nestjs },
|
|
320
357
|
],
|
|
321
|
-
|
|
358
|
+
[SupportedLanguages.Python]: [
|
|
322
359
|
{ framework: 'fastapi', entryPointMultiplier: 3.0, reason: 'fastapi-decorator', patterns: FRAMEWORK_AST_PATTERNS.fastapi },
|
|
323
360
|
{ framework: 'flask', entryPointMultiplier: 2.8, reason: 'flask-decorator', patterns: FRAMEWORK_AST_PATTERNS.flask },
|
|
324
361
|
],
|
|
325
|
-
|
|
362
|
+
[SupportedLanguages.Java]: [
|
|
326
363
|
{ framework: 'spring', entryPointMultiplier: 3.2, reason: 'spring-annotation', patterns: FRAMEWORK_AST_PATTERNS.spring },
|
|
327
364
|
{ framework: 'jaxrs', entryPointMultiplier: 3.0, reason: 'jaxrs-annotation', patterns: FRAMEWORK_AST_PATTERNS.jaxrs },
|
|
328
365
|
],
|
|
329
|
-
|
|
366
|
+
[SupportedLanguages.Kotlin]: [
|
|
330
367
|
{ framework: 'spring-kotlin', entryPointMultiplier: 3.2, reason: 'spring-kotlin-annotation', patterns: FRAMEWORK_AST_PATTERNS.spring },
|
|
331
368
|
{ framework: 'jaxrs', entryPointMultiplier: 3.0, reason: 'jaxrs-annotation', patterns: FRAMEWORK_AST_PATTERNS.jaxrs },
|
|
332
369
|
{ framework: 'ktor', entryPointMultiplier: 2.8, reason: 'ktor-routing', patterns: ['routing', 'embeddedServer', 'Application.module'] },
|
|
333
370
|
{ framework: 'android-kotlin', entryPointMultiplier: 2.5, reason: 'android-annotation', patterns: ['@AndroidEntryPoint', 'AppCompatActivity', 'Fragment('] },
|
|
334
371
|
],
|
|
335
|
-
|
|
372
|
+
[SupportedLanguages.CSharp]: [
|
|
336
373
|
{ framework: 'aspnet', entryPointMultiplier: 3.2, reason: 'aspnet-attribute', patterns: FRAMEWORK_AST_PATTERNS.aspnet },
|
|
374
|
+
{ framework: 'signalr', entryPointMultiplier: 2.8, reason: 'signalr-attribute', patterns: FRAMEWORK_AST_PATTERNS.signalr },
|
|
375
|
+
{ framework: 'blazor', entryPointMultiplier: 2.5, reason: 'blazor-attribute', patterns: FRAMEWORK_AST_PATTERNS.blazor },
|
|
376
|
+
{ framework: 'efcore', entryPointMultiplier: 2.0, reason: 'efcore-pattern', patterns: FRAMEWORK_AST_PATTERNS.efcore },
|
|
337
377
|
],
|
|
338
|
-
|
|
378
|
+
[SupportedLanguages.PHP]: [
|
|
339
379
|
{ framework: 'laravel', entryPointMultiplier: 3.0, reason: 'php-route-attribute', patterns: FRAMEWORK_AST_PATTERNS.laravel },
|
|
340
380
|
],
|
|
341
381
|
};
|
|
@@ -2,19 +2,27 @@
|
|
|
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 { KnowledgeGraph } from '../graph/types.js';
|
|
9
17
|
import { ASTCache } from './ast-cache.js';
|
|
10
|
-
import { SymbolTable } from './symbol-table.js';
|
|
11
18
|
import type { ExtractedHeritage } from './workers/parse-worker.js';
|
|
19
|
+
import type { ResolutionContext } from './resolution-context.js';
|
|
12
20
|
export declare const processHeritage: (graph: KnowledgeGraph, files: {
|
|
13
21
|
path: string;
|
|
14
22
|
content: string;
|
|
15
|
-
}[], astCache: ASTCache,
|
|
23
|
+
}[], astCache: ASTCache, ctx: ResolutionContext, onProgress?: (current: number, total: number) => void) => Promise<void>;
|
|
16
24
|
/**
|
|
17
25
|
* Fast path: resolve pre-extracted heritage from workers.
|
|
18
26
|
* No AST parsing — workers already extracted className + parentName + kind.
|
|
19
27
|
*/
|
|
20
|
-
export declare const processHeritageFromExtracted: (graph: KnowledgeGraph, extractedHeritage: ExtractedHeritage[],
|
|
28
|
+
export declare const processHeritageFromExtracted: (graph: KnowledgeGraph, extractedHeritage: ExtractedHeritage[], ctx: ResolutionContext, onProgress?: (current: number, total: number) => void) => Promise<void>;
|