arcvision 0.2.1 → 0.2.3

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/dist/index.js CHANGED
@@ -56569,6 +56569,692 @@ var require_parser = __commonJS({
56569
56569
  }
56570
56570
  });
56571
56571
 
56572
+ // src/core/di-detector.js
56573
+ var require_di_detector = __commonJS({
56574
+ "src/core/di-detector.js"(exports2, module2) {
56575
+ var traverse = require_lib8().default;
56576
+ function detectConstructorInjection(ast) {
56577
+ const injections = [];
56578
+ traverse(ast, {
56579
+ ClassDeclaration(path2) {
56580
+ const className = path2.node.id ? path2.node.id.name : "Anonymous";
56581
+ const constructor = path2.node.body.body.find(
56582
+ (member) => member.kind === "constructor"
56583
+ );
56584
+ if (constructor && constructor.params) {
56585
+ constructor.params.forEach((param) => {
56586
+ let paramName = null;
56587
+ let paramType = null;
56588
+ if (param.type === "TSParameterProperty") {
56589
+ if (param.parameter.type === "Identifier") {
56590
+ paramName = param.parameter.name;
56591
+ if (param.parameter.typeAnnotation) {
56592
+ paramType = extractTypeName(param.parameter.typeAnnotation);
56593
+ }
56594
+ }
56595
+ } else if (param.type === "Identifier") {
56596
+ paramName = param.name;
56597
+ if (param.typeAnnotation) {
56598
+ paramType = extractTypeName(param.typeAnnotation);
56599
+ }
56600
+ }
56601
+ if (paramName) {
56602
+ injections.push({
56603
+ className,
56604
+ paramName,
56605
+ paramType,
56606
+ pattern: "constructor_injection",
56607
+ loc: constructor.loc
56608
+ });
56609
+ }
56610
+ });
56611
+ }
56612
+ }
56613
+ });
56614
+ return injections;
56615
+ }
56616
+ function detectReactContextUsage(ast) {
56617
+ const contextUsages = [];
56618
+ traverse(ast, {
56619
+ // Detect useContext hook calls
56620
+ CallExpression(path2) {
56621
+ if (path2.node.callee.name === "useContext" && path2.node.arguments.length > 0) {
56622
+ const contextArg = path2.node.arguments[0];
56623
+ let contextName = null;
56624
+ if (contextArg.type === "Identifier") {
56625
+ contextName = contextArg.name;
56626
+ } else if (contextArg.type === "MemberExpression") {
56627
+ contextName = extractMemberExpressionName(contextArg);
56628
+ }
56629
+ if (contextName) {
56630
+ contextUsages.push({
56631
+ type: "useContext",
56632
+ contextName,
56633
+ pattern: "context_consumer",
56634
+ loc: path2.node.loc
56635
+ });
56636
+ }
56637
+ }
56638
+ },
56639
+ // Detect Context.Provider usage in JSX
56640
+ JSXElement(path2) {
56641
+ const openingElement = path2.node.openingElement;
56642
+ if (openingElement.name.type === "JSXMemberExpression") {
56643
+ const objectName = openingElement.name.object.name;
56644
+ const propertyName = openingElement.name.property.name;
56645
+ if (propertyName === "Provider" || propertyName === "Consumer") {
56646
+ contextUsages.push({
56647
+ type: "JSXProvider",
56648
+ contextName: objectName,
56649
+ pattern: propertyName === "Provider" ? "context_provider" : "context_consumer",
56650
+ loc: path2.node.loc
56651
+ });
56652
+ }
56653
+ }
56654
+ }
56655
+ });
56656
+ return contextUsages;
56657
+ }
56658
+ function detectHookDependencies(ast) {
56659
+ const hookDeps = [];
56660
+ traverse(ast, {
56661
+ CallExpression(path2) {
56662
+ const calleeName = path2.node.callee.name;
56663
+ if (calleeName && calleeName.startsWith("use") && calleeName !== "useContext") {
56664
+ hookDeps.push({
56665
+ hookName: calleeName,
56666
+ pattern: "custom_hook",
56667
+ loc: path2.node.loc
56668
+ });
56669
+ }
56670
+ }
56671
+ });
56672
+ return hookDeps;
56673
+ }
56674
+ function detectDependencyInjection(ast) {
56675
+ if (!ast) {
56676
+ return {
56677
+ constructorInjections: [],
56678
+ contextUsages: [],
56679
+ hookDependencies: []
56680
+ };
56681
+ }
56682
+ return {
56683
+ constructorInjections: detectConstructorInjection(ast),
56684
+ contextUsages: detectReactContextUsage(ast),
56685
+ hookDependencies: detectHookDependencies(ast)
56686
+ };
56687
+ }
56688
+ function extractTypeName(typeAnnotation) {
56689
+ if (!typeAnnotation)
56690
+ return null;
56691
+ const annotation = typeAnnotation.typeAnnotation || typeAnnotation;
56692
+ if (annotation.type === "TSTypeReference" && annotation.typeName) {
56693
+ if (annotation.typeName.type === "Identifier") {
56694
+ return annotation.typeName.name;
56695
+ }
56696
+ }
56697
+ return null;
56698
+ }
56699
+ function extractMemberExpressionName(node) {
56700
+ if (node.type === "MemberExpression") {
56701
+ const object = node.object.name || "";
56702
+ const property = node.property.name || "";
56703
+ return object + "." + property;
56704
+ }
56705
+ return null;
56706
+ }
56707
+ module2.exports = {
56708
+ detectConstructorInjection,
56709
+ detectReactContextUsage,
56710
+ detectHookDependencies,
56711
+ detectDependencyInjection
56712
+ };
56713
+ }
56714
+ });
56715
+
56716
+ // src/core/method-tracker.js
56717
+ var require_method_tracker = __commonJS({
56718
+ "src/core/method-tracker.js"(exports2, module2) {
56719
+ var traverse = require_lib8().default;
56720
+ function trackMethodCalls(ast, imports = []) {
56721
+ const functionCalls = [];
56722
+ const methodCalls = [];
56723
+ const constructorCalls = [];
56724
+ if (!ast) {
56725
+ return { functionCalls, methodCalls, constructorCalls };
56726
+ }
56727
+ const importedSymbols = /* @__PURE__ */ new Set();
56728
+ imports.forEach((imp) => {
56729
+ if (imp.specifiers && Array.isArray(imp.specifiers)) {
56730
+ imp.specifiers.forEach((spec) => {
56731
+ const localName = spec.local || spec.imported || spec;
56732
+ if (typeof localName === "string") {
56733
+ importedSymbols.add(localName);
56734
+ }
56735
+ });
56736
+ }
56737
+ });
56738
+ traverse(ast, {
56739
+ CallExpression(path2) {
56740
+ const callee = path2.node.callee;
56741
+ if (callee.type === "Identifier") {
56742
+ const functionName = callee.name;
56743
+ if (importedSymbols.has(functionName) || /^[A-Z]/.test(functionName)) {
56744
+ functionCalls.push({
56745
+ name: functionName,
56746
+ type: "function_call",
56747
+ loc: path2.node.loc
56748
+ });
56749
+ }
56750
+ } else if (callee.type === "MemberExpression") {
56751
+ const objectName = extractObjectName(callee.object);
56752
+ const methodName = callee.property.name || callee.property.value;
56753
+ if (objectName && methodName) {
56754
+ methodCalls.push({
56755
+ object: objectName,
56756
+ method: methodName,
56757
+ type: "method_call",
56758
+ loc: path2.node.loc
56759
+ });
56760
+ }
56761
+ }
56762
+ },
56763
+ // Track constructor calls: new ClassName()
56764
+ NewExpression(path2) {
56765
+ const callee = path2.node.callee;
56766
+ if (callee.type === "Identifier") {
56767
+ const className = callee.name;
56768
+ if (importedSymbols.has(className)) {
56769
+ constructorCalls.push({
56770
+ className,
56771
+ type: "constructor_call",
56772
+ loc: path2.node.loc
56773
+ });
56774
+ }
56775
+ }
56776
+ }
56777
+ });
56778
+ return {
56779
+ functionCalls,
56780
+ methodCalls,
56781
+ constructorCalls
56782
+ };
56783
+ }
56784
+ function buildCallGraph(nodes) {
56785
+ const callEdges = [];
56786
+ nodes.forEach((node) => {
56787
+ const filePath = node.id;
56788
+ const metadata = node.metadata;
56789
+ if (!metadata)
56790
+ return;
56791
+ if (metadata.functionCalls && Array.isArray(metadata.functionCalls)) {
56792
+ metadata.functionCalls.forEach((call) => {
56793
+ callEdges.push({
56794
+ source: filePath,
56795
+ callType: "function",
56796
+ calledSymbol: call.name,
56797
+ loc: call.loc
56798
+ });
56799
+ });
56800
+ }
56801
+ if (metadata.constructorCalls && Array.isArray(metadata.constructorCalls)) {
56802
+ metadata.constructorCalls.forEach((call) => {
56803
+ callEdges.push({
56804
+ source: filePath,
56805
+ callType: "constructor",
56806
+ calledSymbol: call.className,
56807
+ loc: call.loc
56808
+ });
56809
+ });
56810
+ }
56811
+ if (metadata.methodCalls && Array.isArray(metadata.methodCalls)) {
56812
+ metadata.methodCalls.forEach((call) => {
56813
+ callEdges.push({
56814
+ source: filePath,
56815
+ callType: "method",
56816
+ calledSymbol: `${call.object}.${call.method}`,
56817
+ loc: call.loc
56818
+ });
56819
+ });
56820
+ }
56821
+ });
56822
+ return callEdges;
56823
+ }
56824
+ function extractObjectName(node) {
56825
+ if (node.type === "Identifier") {
56826
+ return node.name;
56827
+ } else if (node.type === "ThisExpression") {
56828
+ return "this";
56829
+ } else if (node.type === "MemberExpression") {
56830
+ const object = extractObjectName(node.object);
56831
+ const property = node.property.name || node.property.value;
56832
+ return object && property ? `${object}.${property}` : object;
56833
+ }
56834
+ return null;
56835
+ }
56836
+ module2.exports = {
56837
+ trackMethodCalls,
56838
+ buildCallGraph
56839
+ };
56840
+ }
56841
+ });
56842
+
56843
+ // src/core/type-analyzer.js
56844
+ var require_type_analyzer = __commonJS({
56845
+ "src/core/type-analyzer.js"(exports2, module2) {
56846
+ var traverse = require_lib8().default;
56847
+ function extractTypeImports(ast) {
56848
+ const typeImports = [];
56849
+ if (!ast)
56850
+ return typeImports;
56851
+ traverse(ast, {
56852
+ ImportDeclaration(path2) {
56853
+ const node = path2.node;
56854
+ if (node.importKind === "type") {
56855
+ const specifiers = [];
56856
+ node.specifiers.forEach((spec) => {
56857
+ if (spec.imported) {
56858
+ specifiers.push({
56859
+ imported: spec.imported.name || spec.imported.value,
56860
+ local: spec.local.name
56861
+ });
56862
+ }
56863
+ });
56864
+ typeImports.push({
56865
+ source: node.source.value,
56866
+ specifiers,
56867
+ importKind: "type",
56868
+ loc: node.loc
56869
+ });
56870
+ } else {
56871
+ const typeSpecifiers = [];
56872
+ node.specifiers.forEach((spec) => {
56873
+ if (spec.importKind === "type" && spec.imported) {
56874
+ typeSpecifiers.push({
56875
+ imported: spec.imported.name || spec.imported.value,
56876
+ local: spec.local.name
56877
+ });
56878
+ }
56879
+ });
56880
+ if (typeSpecifiers.length > 0) {
56881
+ typeImports.push({
56882
+ source: node.source.value,
56883
+ specifiers: typeSpecifiers,
56884
+ importKind: "mixed",
56885
+ loc: node.loc
56886
+ });
56887
+ }
56888
+ }
56889
+ }
56890
+ });
56891
+ return typeImports;
56892
+ }
56893
+ function extractInterfaceDependencies(ast) {
56894
+ const interfaceDeps = [];
56895
+ if (!ast)
56896
+ return interfaceDeps;
56897
+ traverse(ast, {
56898
+ // Interface extends
56899
+ TSInterfaceDeclaration(path2) {
56900
+ const node = path2.node;
56901
+ const interfaceName = node.id.name;
56902
+ if (node.extends && node.extends.length > 0) {
56903
+ node.extends.forEach((ext) => {
56904
+ const extendedInterface = extractTypeName(ext.expression);
56905
+ if (extendedInterface) {
56906
+ interfaceDeps.push({
56907
+ interface: interfaceName,
56908
+ extends: extendedInterface,
56909
+ type: "interface_extends",
56910
+ loc: node.loc
56911
+ });
56912
+ }
56913
+ });
56914
+ }
56915
+ },
56916
+ // Class implements
56917
+ ClassDeclaration(path2) {
56918
+ const node = path2.node;
56919
+ const className = node.id ? node.id.name : "Anonymous";
56920
+ if (node.implements && node.implements.length > 0) {
56921
+ node.implements.forEach((impl) => {
56922
+ const implementedInterface = extractTypeName(impl.expression);
56923
+ if (implementedInterface) {
56924
+ interfaceDeps.push({
56925
+ class: className,
56926
+ implements: implementedInterface,
56927
+ type: "class_implements",
56928
+ loc: node.loc
56929
+ });
56930
+ }
56931
+ });
56932
+ }
56933
+ }
56934
+ });
56935
+ return interfaceDeps;
56936
+ }
56937
+ function extractGenericDependencies(ast) {
56938
+ const genericDeps = [];
56939
+ if (!ast)
56940
+ return genericDeps;
56941
+ traverse(ast, {
56942
+ // Function return types
56943
+ FunctionDeclaration(path2) {
56944
+ const node = path2.node;
56945
+ const functionName = node.id ? node.id.name : "anonymous";
56946
+ if (node.returnType) {
56947
+ const returnTypeName = extractComplexTypeName(node.returnType.typeAnnotation);
56948
+ if (returnTypeName) {
56949
+ genericDeps.push({
56950
+ function: functionName,
56951
+ returnType: returnTypeName,
56952
+ type: "return_type",
56953
+ loc: node.loc
56954
+ });
56955
+ }
56956
+ }
56957
+ },
56958
+ // Arrow function return types
56959
+ ArrowFunctionExpression(path2) {
56960
+ const node = path2.node;
56961
+ if (node.returnType) {
56962
+ const returnTypeName = extractComplexTypeName(node.returnType.typeAnnotation);
56963
+ if (returnTypeName) {
56964
+ genericDeps.push({
56965
+ function: "arrow_function",
56966
+ returnType: returnTypeName,
56967
+ type: "return_type",
56968
+ loc: node.loc
56969
+ });
56970
+ }
56971
+ }
56972
+ },
56973
+ // Variable type annotations
56974
+ VariableDeclarator(path2) {
56975
+ const node = path2.node;
56976
+ const varName = node.id.name;
56977
+ if (node.id.typeAnnotation) {
56978
+ const typeName = extractComplexTypeName(node.id.typeAnnotation.typeAnnotation);
56979
+ if (typeName) {
56980
+ genericDeps.push({
56981
+ variable: varName,
56982
+ type: typeName,
56983
+ kind: "variable_type",
56984
+ loc: node.loc
56985
+ });
56986
+ }
56987
+ }
56988
+ }
56989
+ });
56990
+ return genericDeps;
56991
+ }
56992
+ function analyzeTypeDependencies(ast) {
56993
+ if (!ast) {
56994
+ return {
56995
+ typeImports: [],
56996
+ interfaceDependencies: [],
56997
+ genericDependencies: []
56998
+ };
56999
+ }
57000
+ return {
57001
+ typeImports: extractTypeImports(ast),
57002
+ interfaceDependencies: extractInterfaceDependencies(ast),
57003
+ genericDependencies: extractGenericDependencies(ast)
57004
+ };
57005
+ }
57006
+ function extractTypeName(node) {
57007
+ if (!node)
57008
+ return null;
57009
+ if (node.type === "Identifier") {
57010
+ return node.name;
57011
+ } else if (node.type === "TSTypeReference" && node.typeName) {
57012
+ if (node.typeName.type === "Identifier") {
57013
+ return node.typeName.name;
57014
+ }
57015
+ }
57016
+ return null;
57017
+ }
57018
+ function extractComplexTypeName(node) {
57019
+ if (!node)
57020
+ return null;
57021
+ if (node.type === "TSTypeReference" && node.typeName) {
57022
+ let baseName = extractTypeName(node);
57023
+ if (node.typeParameters && node.typeParameters.params) {
57024
+ const params = node.typeParameters.params.map((p) => extractComplexTypeName(p)).filter(Boolean).join(", ");
57025
+ if (params) {
57026
+ baseName += `<${params}>`;
57027
+ }
57028
+ }
57029
+ return baseName;
57030
+ } else if (node.type === "Identifier") {
57031
+ return node.name;
57032
+ } else if (node.type === "TSArrayType") {
57033
+ const elementType = extractComplexTypeName(node.elementType);
57034
+ return elementType ? `${elementType}[]` : null;
57035
+ }
57036
+ return null;
57037
+ }
57038
+ module2.exports = {
57039
+ extractTypeImports,
57040
+ extractInterfaceDependencies,
57041
+ extractGenericDependencies,
57042
+ analyzeTypeDependencies
57043
+ };
57044
+ }
57045
+ });
57046
+
57047
+ // src/core/react-nextjs-detector.js
57048
+ var require_react_nextjs_detector = __commonJS({
57049
+ "src/core/react-nextjs-detector.js"(exports2, module2) {
57050
+ var traverse = require_lib8().default;
57051
+ function detectComponentUsage(ast) {
57052
+ const componentUsages = [];
57053
+ if (!ast)
57054
+ return componentUsages;
57055
+ traverse(ast, {
57056
+ JSXElement(path2) {
57057
+ const openingElement = path2.node.openingElement;
57058
+ let componentName = null;
57059
+ if (openingElement.name.type === "JSXIdentifier") {
57060
+ componentName = openingElement.name.name;
57061
+ if (/^[A-Z]/.test(componentName)) {
57062
+ componentUsages.push({
57063
+ component: componentName,
57064
+ type: "jsx_component",
57065
+ loc: path2.node.loc
57066
+ });
57067
+ }
57068
+ } else if (openingElement.name.type === "JSXMemberExpression") {
57069
+ const object = openingElement.name.object.name;
57070
+ const property = openingElement.name.property.name;
57071
+ componentName = `${object}.${property}`;
57072
+ componentUsages.push({
57073
+ component: componentName,
57074
+ type: "jsx_member_component",
57075
+ loc: path2.node.loc
57076
+ });
57077
+ }
57078
+ }
57079
+ });
57080
+ return componentUsages;
57081
+ }
57082
+ function detectServerClientBoundaries(content) {
57083
+ const boundaries = {
57084
+ isClientComponent: false,
57085
+ isServerComponent: false,
57086
+ isServerAction: false
57087
+ };
57088
+ if (!content)
57089
+ return boundaries;
57090
+ if (/['"]use client['"]/.test(content)) {
57091
+ boundaries.isClientComponent = true;
57092
+ }
57093
+ if (/['"]use server['"]/.test(content)) {
57094
+ boundaries.isServerAction = true;
57095
+ }
57096
+ if (!boundaries.isClientComponent && !boundaries.isServerAction) {
57097
+ boundaries.isServerComponent = true;
57098
+ }
57099
+ return boundaries;
57100
+ }
57101
+ function detectAPIRouteDependencies(ast) {
57102
+ const apiDeps = [];
57103
+ if (!ast)
57104
+ return apiDeps;
57105
+ traverse(ast, {
57106
+ // Detect Next.js API route handlers: export async function GET/POST/etc
57107
+ ExportNamedDeclaration(path2) {
57108
+ const node = path2.node;
57109
+ if (node.declaration && node.declaration.type === "FunctionDeclaration") {
57110
+ const funcName = node.declaration.id ? node.declaration.id.name : null;
57111
+ if (["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"].includes(funcName)) {
57112
+ apiDeps.push({
57113
+ handler: funcName,
57114
+ type: "api_route_handler",
57115
+ loc: node.loc
57116
+ });
57117
+ }
57118
+ }
57119
+ },
57120
+ // Detect fetch calls and database queries within API routes
57121
+ CallExpression(path2) {
57122
+ const callee = path2.node.callee;
57123
+ if (callee.type === "MemberExpression") {
57124
+ const objectName = callee.object.name;
57125
+ const methodName = callee.property.name || callee.property.value;
57126
+ if (objectName === "supabase" || /supabase/i.test(objectName)) {
57127
+ apiDeps.push({
57128
+ service: "supabase",
57129
+ method: methodName,
57130
+ type: "database_query",
57131
+ loc: path2.node.loc
57132
+ });
57133
+ }
57134
+ if (objectName === "prisma" || /prisma/i.test(objectName)) {
57135
+ apiDeps.push({
57136
+ service: "prisma",
57137
+ method: methodName,
57138
+ type: "database_query",
57139
+ loc: path2.node.loc
57140
+ });
57141
+ }
57142
+ }
57143
+ }
57144
+ });
57145
+ return apiDeps;
57146
+ }
57147
+ function detectMiddlewareDependencies(ast, filePath = "") {
57148
+ const middlewareDeps = [];
57149
+ const isMiddleware = /middleware\.(ts|js)$/.test(filePath);
57150
+ if (!isMiddleware || !ast)
57151
+ return middlewareDeps;
57152
+ traverse(ast, {
57153
+ // Detect middleware function export
57154
+ ExportNamedDeclaration(path2) {
57155
+ const node = path2.node;
57156
+ if (node.declaration && node.declaration.type === "FunctionDeclaration") {
57157
+ const funcName = node.declaration.id ? node.declaration.id.name : null;
57158
+ if (funcName === "middleware") {
57159
+ middlewareDeps.push({
57160
+ function: funcName,
57161
+ type: "middleware_function",
57162
+ loc: node.loc
57163
+ });
57164
+ }
57165
+ }
57166
+ },
57167
+ // Detect auth checks and redirects
57168
+ CallExpression(path2) {
57169
+ const callee = path2.node.callee;
57170
+ if (callee.type === "MemberExpression") {
57171
+ const methodName = callee.property.name || callee.property.value;
57172
+ if (methodName === "getUser" || methodName === "getSession") {
57173
+ middlewareDeps.push({
57174
+ service: "auth",
57175
+ method: methodName,
57176
+ type: "auth_check",
57177
+ loc: path2.node.loc
57178
+ });
57179
+ }
57180
+ if (methodName === "redirect" || methodName === "rewrite") {
57181
+ middlewareDeps.push({
57182
+ service: "next",
57183
+ method: methodName,
57184
+ type: "middleware_action",
57185
+ loc: path2.node.loc
57186
+ });
57187
+ }
57188
+ }
57189
+ }
57190
+ });
57191
+ return middlewareDeps;
57192
+ }
57193
+ function detectReactNextJSPatterns(ast, content = "", filePath = "") {
57194
+ return {
57195
+ componentUsages: detectComponentUsage(ast),
57196
+ boundaries: detectServerClientBoundaries(content),
57197
+ apiDependencies: detectAPIRouteDependencies(ast),
57198
+ middlewareDependencies: detectMiddlewareDependencies(ast, filePath)
57199
+ };
57200
+ }
57201
+ module2.exports = {
57202
+ detectComponentUsage,
57203
+ detectServerClientBoundaries,
57204
+ detectAPIRouteDependencies,
57205
+ detectMiddlewareDependencies,
57206
+ detectReactNextJSPatterns
57207
+ };
57208
+ }
57209
+ });
57210
+
57211
+ // src/core/parser-enhanced.js
57212
+ var require_parser_enhanced = __commonJS({
57213
+ "src/core/parser-enhanced.js"(exports2, module2) {
57214
+ var { parseFile: originalParseFile } = require_parser();
57215
+ var { detectDependencyInjection } = require_di_detector();
57216
+ var { trackMethodCalls } = require_method_tracker();
57217
+ var { analyzeTypeDependencies } = require_type_analyzer();
57218
+ var { detectReactNextJSPatterns } = require_react_nextjs_detector();
57219
+ var fs2 = require("fs");
57220
+ function parseFileEnhanced(filePath) {
57221
+ const metadata = originalParseFile(filePath);
57222
+ if (!metadata.ast) {
57223
+ return metadata;
57224
+ }
57225
+ const ast = metadata.ast;
57226
+ const fileContent = fs2.readFileSync(filePath, "utf-8");
57227
+ try {
57228
+ const diPatterns = detectDependencyInjection(ast);
57229
+ metadata.constructorInjections = diPatterns.constructorInjections || [];
57230
+ metadata.contextUsages = diPatterns.contextUsages || [];
57231
+ metadata.hookDependencies = diPatterns.hookDependencies || [];
57232
+ const callTracking = trackMethodCalls(ast, metadata.imports);
57233
+ metadata.functionCalls = callTracking.functionCalls || [];
57234
+ metadata.constructorCalls = callTracking.constructorCalls || [];
57235
+ metadata.methodCalls = callTracking.methodCalls || [];
57236
+ const typeDeps = analyzeTypeDependencies(ast);
57237
+ metadata.typeImports = typeDeps.typeImports || [];
57238
+ metadata.interfaceDependencies = typeDeps.interfaceDependencies || [];
57239
+ metadata.genericDependencies = typeDeps.genericDependencies || [];
57240
+ const reactPatterns = detectReactNextJSPatterns(ast, fileContent, filePath);
57241
+ metadata.componentUsage = reactPatterns.componentUsages || [];
57242
+ metadata.serverClientBoundaries = reactPatterns.boundaries || {};
57243
+ metadata.apiDependencies = reactPatterns.apiDependencies || [];
57244
+ metadata.middlewareDependencies = reactPatterns.middlewareDependencies || [];
57245
+ } catch (error) {
57246
+ console.warn(`\u26A0\uFE0F Enhanced analysis failed for ${filePath}: ${error.message}`);
57247
+ }
57248
+ delete metadata.ast;
57249
+ return metadata;
57250
+ }
57251
+ module2.exports = {
57252
+ parseFile: parseFileEnhanced,
57253
+ parseFileBasic: originalParseFile
57254
+ };
57255
+ }
57256
+ });
57257
+
56572
57258
  // src/plugins/plugin-manager.js
56573
57259
  var require_plugin_manager = __commonJS({
56574
57260
  "src/plugins/plugin-manager.js"(exports2, module2) {
@@ -56597,7 +57283,7 @@ var require_plugin_manager = __commonJS({
56597
57283
  enhancedMetadata = { ...enhancedMetadata, ...result };
56598
57284
  }
56599
57285
  } catch (error) {
56600
- console.warn(`Plugin ${plugin.name} failed: ${error.message}`);
57286
+ console.warn(`Plugin ${plugin.name} failed: ${error.message || error}`);
56601
57287
  }
56602
57288
  }
56603
57289
  return enhancedMetadata;
@@ -56695,7 +57381,7 @@ var require_path_resolver = __commonJS({
56695
57381
  const suffix = importPath.substring(patternBase.length);
56696
57382
  for (const target of aliasTargets) {
56697
57383
  const targetBase = target.replace(/\*.*$/, "");
56698
- const targetPath = path2.resolve(projectRoot, targetBase) + suffix;
57384
+ const targetPath = path2.resolve(projectRoot, path2.join(targetBase, suffix));
56699
57385
  const extensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".json"];
56700
57386
  for (const ext of extensions) {
56701
57387
  if (fs2.existsSync(targetPath + ext)) {
@@ -56982,29 +57668,43 @@ var require_context_builder = __commonJS({
56982
57668
  for (const edge of edges) {
56983
57669
  const sourceNode = nodes.find((n) => n.path === edge.source);
56984
57670
  const targetNode = nodes.find((n) => n.path === edge.target);
56985
- if (sourceNode && targetNode) {
57671
+ if (sourceNode) {
56986
57672
  let relationType = "imports";
56987
57673
  if (edge.type === "imports" || edge.type === "require" || edge.type === "export-from" || edge.type === "export-all" || edge.type === "dynamic-import" || edge.type === "require-assignment") {
56988
57674
  relationType = "imports";
57675
+ } else if (edge.type === "function_call" || edge.type === "method_call") {
57676
+ relationType = "calls";
57677
+ } else if (edge.type === "constructor_call") {
57678
+ relationType = "calls";
57679
+ } else if (edge.type === "component_usage" || edge.type === "jsx_component" || edge.type === "jsx_member_component") {
57680
+ relationType = "imports";
56989
57681
  } else if (edge.type === "calls") {
56990
57682
  relationType = "calls";
56991
57683
  } else if (edge.type === "owns") {
56992
57684
  relationType = "owns";
56993
57685
  } else if (edge.type === "depends_on") {
56994
57686
  relationType = "depends_on";
57687
+ } else {
57688
+ relationType = "imports";
57689
+ }
57690
+ if (targetNode) {
57691
+ schemaEdges.push({
57692
+ from: sourceNode.id,
57693
+ to: targetNode.id,
57694
+ relation: relationType
57695
+ });
57696
+ } else {
56995
57697
  }
56996
- schemaEdges.push({
56997
- from: sourceNode.id,
56998
- to: targetNode.id,
56999
- relation: relationType
57000
- });
57001
57698
  }
57002
57699
  }
57003
57700
  const metrics = {
57004
57701
  total_files: nodes.length,
57005
57702
  total_nodes: nodes.length,
57006
57703
  total_edges: schemaEdges.length,
57007
- total_imports: schemaEdges.length,
57704
+ total_imports: schemaEdges.filter((edge) => edge.relation === "imports").length,
57705
+ total_calls: schemaEdges.filter((edge) => edge.relation === "calls").length,
57706
+ total_owns: schemaEdges.filter((edge) => edge.relation === "owns").length,
57707
+ total_depends_on: schemaEdges.filter((edge) => edge.relation === "depends_on").length,
57008
57708
  files_with_functions: nodes.filter((n) => n.role === "Implementation").length
57009
57709
  };
57010
57710
  const context = {
@@ -63577,13 +64277,167 @@ var require_context_sorter = __commonJS({
63577
64277
  }
63578
64278
  });
63579
64279
 
64280
+ // src/core/semantic-analyzer.js
64281
+ var require_semantic_analyzer = __commonJS({
64282
+ "src/core/semantic-analyzer.js"(exports2, module2) {
64283
+ function buildSymbolTable(nodes) {
64284
+ const symbolTable = /* @__PURE__ */ new Map();
64285
+ nodes.forEach((node) => {
64286
+ const filePath = node.id;
64287
+ const metadata = node.metadata;
64288
+ if (!metadata)
64289
+ return;
64290
+ if (metadata.exports && Array.isArray(metadata.exports)) {
64291
+ metadata.exports.forEach((exp) => {
64292
+ const symbolName = exp.name;
64293
+ if (!symbolTable.has(symbolName)) {
64294
+ symbolTable.set(symbolName, []);
64295
+ }
64296
+ symbolTable.get(symbolName).push({
64297
+ file: filePath,
64298
+ type: exp.type,
64299
+ loc: exp.loc
64300
+ });
64301
+ });
64302
+ }
64303
+ if (metadata.functions && Array.isArray(metadata.functions)) {
64304
+ metadata.functions.forEach((func) => {
64305
+ const symbolName = func.name;
64306
+ if (!symbolTable.has(symbolName)) {
64307
+ symbolTable.set(symbolName, []);
64308
+ }
64309
+ symbolTable.get(symbolName).push({
64310
+ file: filePath,
64311
+ type: "function",
64312
+ loc: func.loc
64313
+ });
64314
+ });
64315
+ }
64316
+ if (metadata.classes && Array.isArray(metadata.classes)) {
64317
+ metadata.classes.forEach((cls) => {
64318
+ const symbolName = cls.name;
64319
+ if (!symbolTable.has(symbolName)) {
64320
+ symbolTable.set(symbolName, []);
64321
+ }
64322
+ symbolTable.get(symbolName).push({
64323
+ file: filePath,
64324
+ type: "class",
64325
+ loc: cls.loc
64326
+ });
64327
+ });
64328
+ }
64329
+ });
64330
+ return symbolTable;
64331
+ }
64332
+ function resolveSymbolUsage(node, symbolTable) {
64333
+ const resolvedUsages = [];
64334
+ const metadata = node.metadata;
64335
+ if (!metadata)
64336
+ return resolvedUsages;
64337
+ const importedSymbols = /* @__PURE__ */ new Map();
64338
+ if (metadata.imports && Array.isArray(metadata.imports)) {
64339
+ metadata.imports.forEach((imp) => {
64340
+ if (imp.specifiers && Array.isArray(imp.specifiers)) {
64341
+ imp.specifiers.forEach((spec) => {
64342
+ const localName = spec.local || spec.imported || spec;
64343
+ const importedName = spec.imported || spec.local || spec;
64344
+ importedSymbols.set(localName, {
64345
+ source: imp.source,
64346
+ originalName: importedName
64347
+ });
64348
+ });
64349
+ }
64350
+ });
64351
+ }
64352
+ if (metadata.functionCalls && Array.isArray(metadata.functionCalls)) {
64353
+ metadata.functionCalls.forEach((call) => {
64354
+ const callName = call.name;
64355
+ if (importedSymbols.has(callName)) {
64356
+ const importInfo = importedSymbols.get(callName);
64357
+ resolvedUsages.push({
64358
+ type: "function_call",
64359
+ symbol: callName,
64360
+ source: importInfo.source,
64361
+ loc: call.loc
64362
+ });
64363
+ }
64364
+ });
64365
+ }
64366
+ if (metadata.constructorCalls && Array.isArray(metadata.constructorCalls)) {
64367
+ metadata.constructorCalls.forEach((call) => {
64368
+ const className = call.className;
64369
+ if (importedSymbols.has(className)) {
64370
+ const importInfo = importedSymbols.get(className);
64371
+ resolvedUsages.push({
64372
+ type: "constructor_call",
64373
+ symbol: className,
64374
+ source: importInfo.source,
64375
+ loc: call.loc
64376
+ });
64377
+ }
64378
+ });
64379
+ }
64380
+ if (metadata.componentUsage && Array.isArray(metadata.componentUsage)) {
64381
+ metadata.componentUsage.forEach((comp) => {
64382
+ const componentName = comp.component;
64383
+ if (importedSymbols.has(componentName)) {
64384
+ const importInfo = importedSymbols.get(componentName);
64385
+ resolvedUsages.push({
64386
+ type: "component_usage",
64387
+ symbol: componentName,
64388
+ source: importInfo.source,
64389
+ loc: comp.loc
64390
+ });
64391
+ }
64392
+ });
64393
+ }
64394
+ return resolvedUsages;
64395
+ }
64396
+ function trackCrossFileReferences(nodes, symbolTable) {
64397
+ const usageEdges = [];
64398
+ nodes.forEach((node) => {
64399
+ const filePath = node.id;
64400
+ const resolvedUsages = resolveSymbolUsage(node, symbolTable);
64401
+ resolvedUsages.forEach((usage) => {
64402
+ usageEdges.push({
64403
+ source: filePath,
64404
+ target: usage.source,
64405
+ type: usage.type,
64406
+ symbol: usage.symbol,
64407
+ loc: usage.loc
64408
+ });
64409
+ });
64410
+ });
64411
+ return usageEdges;
64412
+ }
64413
+ function analyzeSemantics(nodes) {
64414
+ const symbolTable = buildSymbolTable(nodes);
64415
+ const usageEdges = trackCrossFileReferences(nodes, symbolTable);
64416
+ return {
64417
+ symbolTable,
64418
+ usageEdges,
64419
+ stats: {
64420
+ totalSymbols: symbolTable.size,
64421
+ totalUsages: usageEdges.length
64422
+ }
64423
+ };
64424
+ }
64425
+ module2.exports = {
64426
+ buildSymbolTable,
64427
+ resolveSymbolUsage,
64428
+ trackCrossFileReferences,
64429
+ analyzeSemantics
64430
+ };
64431
+ }
64432
+ });
64433
+
63580
64434
  // src/core/scanner.js
63581
64435
  var require_scanner = __commonJS({
63582
64436
  "src/core/scanner.js"(exports2, module2) {
63583
64437
  var { glob } = require_commonjs5();
63584
64438
  var path2 = require("path");
63585
64439
  var fs2 = require("fs");
63586
- var parser = require_parser();
64440
+ var parser = require_parser_enhanced();
63587
64441
  var pluginManager = require_plugin_manager();
63588
64442
  var { loadTSConfig } = require_tsconfig_utils();
63589
64443
  var { resolveImport } = require_path_resolver();
@@ -63591,6 +64445,7 @@ var require_scanner = __commonJS({
63591
64445
  var { buildContext } = require_context_builder();
63592
64446
  var { validateContext } = require_context_validator();
63593
64447
  var { sortContext } = require_context_sorter();
64448
+ var { analyzeSemantics } = require_semantic_analyzer();
63594
64449
  async function scan(directory) {
63595
64450
  const normalize = (p) => p.replace(/\\/g, "/");
63596
64451
  const options = {
@@ -63607,6 +64462,7 @@ var require_scanner = __commonJS({
63607
64462
  edges: []
63608
64463
  };
63609
64464
  const fileMap = /* @__PURE__ */ new Map();
64465
+ let totalImportsFound = 0;
63610
64466
  for (const file of files) {
63611
64467
  try {
63612
64468
  const relativePath = path2.relative(directory, file);
@@ -63632,6 +64488,9 @@ var require_scanner = __commonJS({
63632
64488
  metadata = parser.parseFile(file);
63633
64489
  }
63634
64490
  metadata = await pluginManager.processFile(file, metadata);
64491
+ if (metadata.imports && Array.isArray(metadata.imports)) {
64492
+ totalImportsFound += metadata.imports.length;
64493
+ }
63635
64494
  const node = {
63636
64495
  id: normalizedRelativePath,
63637
64496
  type: "file",
@@ -63643,42 +64502,266 @@ var require_scanner = __commonJS({
63643
64502
  console.warn(`\u26A0\uFE0F Failed to process ${file} \u2014 file skipped, you should check manually (${e.message})`);
63644
64503
  }
63645
64504
  }
64505
+ console.log("Performing semantic analysis...");
64506
+ const semanticResults = analyzeSemantics(architectureMap.nodes);
64507
+ console.log(`Semantic analysis complete: ${semanticResults.stats.totalSymbols} symbols, ${semanticResults.stats.totalUsages} usage edges`);
63646
64508
  const tsconfig = loadTSConfig(directory);
64509
+ const allPossiblePaths = /* @__PURE__ */ new Set();
63647
64510
  const pathToNodeIdMap = /* @__PURE__ */ new Map();
63648
64511
  architectureMap.nodes.forEach((node) => {
63649
64512
  const normalizedPath = normalize(node.id);
64513
+ allPossiblePaths.add(normalizedPath);
63650
64514
  pathToNodeIdMap.set(normalizedPath, node.id);
63651
64515
  });
64516
+ let unresolvedImports = 0;
64517
+ let resolvedImports = 0;
63652
64518
  architectureMap.nodes.forEach((node) => {
63653
64519
  if (node.metadata.imports && Array.isArray(node.metadata.imports)) {
63654
64520
  node.metadata.imports.forEach((imp) => {
63655
64521
  if (imp.source && typeof imp.source === "string") {
63656
- const resolvedPath = resolveImport(
63657
- imp.source,
63658
- path2.join(directory, node.id),
63659
- directory,
63660
- tsconfig
63661
- );
63662
- if (resolvedPath) {
63663
- const relativeResolvedPath = path2.relative(directory, resolvedPath);
63664
- const normalizedResolvedPath = normalize(relativeResolvedPath);
63665
- if (pathToNodeIdMap.has(normalizedResolvedPath)) {
64522
+ let targetFound = false;
64523
+ try {
64524
+ if (allPossiblePaths.has(imp.source)) {
63666
64525
  architectureMap.edges.push({
63667
64526
  source: normalize(node.id),
63668
- target: normalizedResolvedPath,
64527
+ target: imp.source,
63669
64528
  type: imp.type || "import"
63670
64529
  });
64530
+ resolvedImports++;
64531
+ targetFound = true;
63671
64532
  }
64533
+ if (!targetFound) {
64534
+ const resolvedPath = resolveImport(
64535
+ imp.source,
64536
+ path2.join(directory, node.id),
64537
+ directory,
64538
+ tsconfig
64539
+ );
64540
+ if (resolvedPath) {
64541
+ const relativeResolvedPath = path2.relative(directory, resolvedPath);
64542
+ const normalizedResolvedPath = normalize(relativeResolvedPath);
64543
+ if (allPossiblePaths.has(normalizedResolvedPath)) {
64544
+ architectureMap.edges.push({
64545
+ source: normalize(node.id),
64546
+ target: normalizedResolvedPath,
64547
+ type: imp.type || "import"
64548
+ });
64549
+ resolvedImports++;
64550
+ targetFound = true;
64551
+ }
64552
+ }
64553
+ }
64554
+ if (!targetFound) {
64555
+ try {
64556
+ const baseDir = path2.dirname(path2.join(directory, node.id));
64557
+ const calculatedAbsolutePath = path2.resolve(baseDir, imp.source);
64558
+ const calculatedRelativePath = path2.relative(directory, calculatedAbsolutePath);
64559
+ const calculatedNormalizedPath = normalize(calculatedRelativePath);
64560
+ if (allPossiblePaths.has(calculatedNormalizedPath)) {
64561
+ architectureMap.edges.push({
64562
+ source: normalize(node.id),
64563
+ target: calculatedNormalizedPath,
64564
+ type: imp.type || "import"
64565
+ });
64566
+ resolvedImports++;
64567
+ targetFound = true;
64568
+ }
64569
+ } catch (e) {
64570
+ console.warn(`\u26A0\uFE0F Path calculation failed for import '${imp.source}' in file '${node.id}': ${e.message}`);
64571
+ }
64572
+ }
64573
+ if (!targetFound) {
64574
+ if (imp.source.startsWith("./") || imp.source.startsWith("../")) {
64575
+ const extensions = ["", ".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"];
64576
+ for (const ext of extensions) {
64577
+ let testPath = imp.source;
64578
+ if (!imp.source.endsWith(ext)) {
64579
+ testPath = imp.source + ext;
64580
+ }
64581
+ try {
64582
+ const baseDir = path2.dirname(path2.join(directory, node.id));
64583
+ const calculatedAbsolutePath = path2.resolve(baseDir, testPath);
64584
+ const calculatedRelativePath = path2.relative(directory, calculatedAbsolutePath);
64585
+ const calculatedNormalizedPath = normalize(calculatedRelativePath);
64586
+ if (allPossiblePaths.has(calculatedNormalizedPath)) {
64587
+ architectureMap.edges.push({
64588
+ source: normalize(node.id),
64589
+ target: calculatedNormalizedPath,
64590
+ type: imp.type || "import"
64591
+ });
64592
+ resolvedImports++;
64593
+ targetFound = true;
64594
+ break;
64595
+ }
64596
+ } catch (e) {
64597
+ console.warn(`\u26A0\uFE0F Extension path calculation failed for import '${imp.source}' with extension '${ext}' in file '${node.id}': ${e.message}`);
64598
+ }
64599
+ }
64600
+ }
64601
+ }
64602
+ if (!targetFound) {
64603
+ if (imp.source.startsWith("./") || imp.source.startsWith("../")) {
64604
+ try {
64605
+ const baseDir = path2.dirname(path2.join(directory, node.id));
64606
+ const calculatedAbsolutePath = path2.resolve(baseDir, imp.source);
64607
+ const directoryPath = calculatedAbsolutePath;
64608
+ const indexFiles = ["index.js", "index.ts", "index.jsx", "index.tsx", "index.mjs", "index.cjs"];
64609
+ for (const indexFile of indexFiles) {
64610
+ const indexPath = path2.join(directoryPath, indexFile);
64611
+ const indexRelativePath = path2.relative(directory, indexPath);
64612
+ const indexNormalizedPath = normalize(indexRelativePath);
64613
+ if (allPossiblePaths.has(indexNormalizedPath)) {
64614
+ architectureMap.edges.push({
64615
+ source: normalize(node.id),
64616
+ target: indexNormalizedPath,
64617
+ type: imp.type || "import"
64618
+ });
64619
+ resolvedImports++;
64620
+ targetFound = true;
64621
+ break;
64622
+ }
64623
+ }
64624
+ } catch (e) {
64625
+ console.warn(`\u26A0\uFE0F Index file check failed for import '${imp.source}' in file '${node.id}': ${e.message}`);
64626
+ }
64627
+ }
64628
+ }
64629
+ if (!targetFound) {
64630
+ if (imp.source.startsWith("@") || imp.source.startsWith("/") || !imp.source.startsWith(".")) {
64631
+ const commonSourceDirs = ["src", "app", "lib", "components", "utils", "services", "assets"];
64632
+ for (const srcDir of commonSourceDirs) {
64633
+ const potentialPath = path2.join(srcDir, imp.source);
64634
+ const potentialRelativePath = path2.relative(directory, path2.resolve(directory, potentialPath));
64635
+ const potentialNormalizedPath = normalize(potentialRelativePath);
64636
+ if (allPossiblePaths.has(potentialNormalizedPath)) {
64637
+ architectureMap.edges.push({
64638
+ source: normalize(node.id),
64639
+ target: potentialNormalizedPath,
64640
+ type: imp.type || "import"
64641
+ });
64642
+ resolvedImports++;
64643
+ targetFound = true;
64644
+ break;
64645
+ }
64646
+ const extensions = [
64647
+ ".js",
64648
+ ".ts",
64649
+ ".jsx",
64650
+ ".tsx",
64651
+ ".mjs",
64652
+ ".cjs",
64653
+ "index.js",
64654
+ "index.ts",
64655
+ "index.jsx",
64656
+ "index.tsx",
64657
+ "index.mjs",
64658
+ "index.cjs"
64659
+ ];
64660
+ for (const ext of extensions) {
64661
+ let testPath;
64662
+ if (ext.startsWith("index")) {
64663
+ testPath = path2.join(srcDir, imp.source, ext);
64664
+ } else {
64665
+ testPath = path2.join(srcDir, imp.source + ext);
64666
+ }
64667
+ const testRelativePath = path2.relative(directory, path2.resolve(directory, testPath));
64668
+ const testNormalizedPath = normalize(testRelativePath);
64669
+ if (allPossiblePaths.has(testNormalizedPath)) {
64670
+ architectureMap.edges.push({
64671
+ source: normalize(node.id),
64672
+ target: testNormalizedPath,
64673
+ type: imp.type || "import"
64674
+ });
64675
+ resolvedImports++;
64676
+ targetFound = true;
64677
+ break;
64678
+ }
64679
+ }
64680
+ if (targetFound)
64681
+ break;
64682
+ }
64683
+ }
64684
+ }
64685
+ if (!targetFound) {
64686
+ if (imp.source.startsWith("@") || imp.source.startsWith("/")) {
64687
+ try {
64688
+ const parts = imp.source.split("/");
64689
+ if (parts.length > 1) {
64690
+ const dirParts = parts.slice(0, -1);
64691
+ const fileName = parts[parts.length - 1];
64692
+ const dirPath = dirParts.join("/") + "/index";
64693
+ const indexFiles = ["index.js", "index.ts", "index.jsx", "index.tsx", "index.mjs", "index.cjs"];
64694
+ for (const indexFile of indexFiles) {
64695
+ const indexPath = path2.join(dirParts.join("/"), indexFile);
64696
+ const indexRelativePath = path2.relative(directory, path2.resolve(directory, indexPath));
64697
+ const indexNormalizedPath = normalize(indexRelativePath);
64698
+ if (allPossiblePaths.has(indexNormalizedPath)) {
64699
+ architectureMap.edges.push({
64700
+ source: normalize(node.id),
64701
+ target: indexNormalizedPath,
64702
+ type: imp.type || "import"
64703
+ });
64704
+ resolvedImports++;
64705
+ targetFound = true;
64706
+ break;
64707
+ }
64708
+ }
64709
+ }
64710
+ } catch (e) {
64711
+ console.warn(`\u26A0\uFE0F Barrel file check failed for import '${imp.source}' in file '${node.id}': ${e.message}`);
64712
+ }
64713
+ }
64714
+ }
64715
+ if (!targetFound) {
64716
+ for (const possiblePath of allPossiblePaths) {
64717
+ if (possiblePath.toLowerCase() === imp.source.toLowerCase()) {
64718
+ architectureMap.edges.push({
64719
+ source: normalize(node.id),
64720
+ target: possiblePath,
64721
+ type: imp.type || "import"
64722
+ });
64723
+ resolvedImports++;
64724
+ targetFound = true;
64725
+ break;
64726
+ }
64727
+ }
64728
+ }
64729
+ } catch (e) {
64730
+ console.error(`\u274C Critical error processing import '${imp.source}' in file '${node.id}': ${e.message}`);
64731
+ console.error(e.stack);
64732
+ unresolvedImports++;
64733
+ }
64734
+ if (!targetFound) {
64735
+ unresolvedImports++;
63672
64736
  }
63673
64737
  }
63674
64738
  });
63675
64739
  }
63676
64740
  });
64741
+ console.log("RESOLVED IMPORTS:", resolvedImports);
64742
+ console.log("UNRESOLVED IMPORTS:", unresolvedImports);
64743
+ console.log("IMPORT EDGES CREATED:", architectureMap.edges.length);
64744
+ if (semanticResults && semanticResults.usageEdges) {
64745
+ semanticResults.usageEdges.forEach((usageEdge) => {
64746
+ const sourceExists = architectureMap.nodes.some((n) => n.id === usageEdge.source);
64747
+ const targetExists = architectureMap.nodes.some((n) => n.id === usageEdge.target);
64748
+ if (sourceExists && targetExists) {
64749
+ architectureMap.edges.push({
64750
+ source: normalize(usageEdge.source),
64751
+ target: normalize(usageEdge.target),
64752
+ type: usageEdge.type
64753
+ // 'function_call', 'constructor_call', 'component_usage'
64754
+ });
64755
+ }
64756
+ });
64757
+ }
64758
+ console.log("TOTAL EDGES (with usage):", architectureMap.edges.length);
63677
64759
  const reverseGraph = buildReverseDependencyGraph(architectureMap);
63678
64760
  const blastRadiusMap = computeBlastRadius(reverseGraph);
63679
64761
  architectureMap.nodes.forEach((node) => {
63680
64762
  node.metadata.blast_radius = blastRadiusMap[node.id] || 0;
63681
64763
  });
64764
+ console.log("BEFORE DEDUPLICATION EDGES:", architectureMap.edges.length);
63682
64765
  const validEdges = [];
63683
64766
  const edgeSet = /* @__PURE__ */ new Set();
63684
64767
  architectureMap.edges.forEach((edge) => {
@@ -63696,6 +64779,7 @@ var require_scanner = __commonJS({
63696
64779
  });
63697
64780
  }
63698
64781
  });
64782
+ console.log("AFTER DEDUPLICATION EDGES:", validEdges.length);
63699
64783
  architectureMap.edges = validEdges;
63700
64784
  const totalFiles = architectureMap.nodes.length;
63701
64785
  const { computeBlastRadiusWithPercentage: computeBlastRadiusWithPercentage2, analyzeCriticality } = require_blastRadius();