@grafema/core 0.1.0-alpha.5 → 0.1.1-alpha

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.
Files changed (391) hide show
  1. package/README.md +0 -1
  2. package/dist/Orchestrator.d.ts +24 -2
  3. package/dist/Orchestrator.d.ts.map +1 -1
  4. package/dist/Orchestrator.js +197 -24
  5. package/dist/config/ConfigLoader.d.ts +72 -0
  6. package/dist/config/ConfigLoader.d.ts.map +1 -0
  7. package/dist/config/ConfigLoader.js +187 -0
  8. package/dist/config/index.d.ts +6 -0
  9. package/dist/config/index.d.ts.map +1 -0
  10. package/dist/config/index.js +4 -0
  11. package/dist/core/ASTWorker.d.ts +11 -36
  12. package/dist/core/ASTWorker.d.ts.map +1 -1
  13. package/dist/core/ASTWorker.js +93 -99
  14. package/dist/core/CoverageAnalyzer.d.ts +65 -0
  15. package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
  16. package/dist/core/CoverageAnalyzer.js +198 -0
  17. package/dist/core/FileNodeManager.d.ts +40 -0
  18. package/dist/core/FileNodeManager.d.ts.map +1 -0
  19. package/dist/core/FileNodeManager.js +84 -0
  20. package/dist/core/GraphFreshnessChecker.d.ts +33 -0
  21. package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
  22. package/dist/core/GraphFreshnessChecker.js +101 -0
  23. package/dist/core/HashUtils.d.ts +24 -0
  24. package/dist/core/HashUtils.d.ts.map +1 -0
  25. package/dist/core/HashUtils.js +45 -0
  26. package/dist/core/IncrementalReanalyzer.d.ts +36 -0
  27. package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
  28. package/dist/core/IncrementalReanalyzer.js +132 -0
  29. package/dist/core/NodeFactory.d.ts +225 -17
  30. package/dist/core/NodeFactory.d.ts.map +1 -1
  31. package/dist/core/NodeFactory.js +208 -18
  32. package/dist/core/ScopeTracker.d.ts +84 -0
  33. package/dist/core/ScopeTracker.d.ts.map +1 -0
  34. package/dist/core/ScopeTracker.js +116 -0
  35. package/dist/core/SemanticId.d.ts +90 -0
  36. package/dist/core/SemanticId.d.ts.map +1 -0
  37. package/dist/core/SemanticId.js +115 -0
  38. package/dist/core/VersionManager.d.ts.map +1 -1
  39. package/dist/core/VersionManager.js +3 -2
  40. package/dist/core/nodes/ArgumentExpressionNode.d.ts +43 -0
  41. package/dist/core/nodes/ArgumentExpressionNode.d.ts.map +1 -0
  42. package/dist/core/nodes/ArgumentExpressionNode.js +60 -0
  43. package/dist/core/nodes/ArrayLiteralNode.d.ts +27 -0
  44. package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -0
  45. package/dist/core/nodes/ArrayLiteralNode.js +41 -0
  46. package/dist/core/nodes/CallSiteNode.d.ts +28 -0
  47. package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
  48. package/dist/core/nodes/CallSiteNode.js +46 -0
  49. package/dist/core/nodes/ClassNode.d.ts +33 -1
  50. package/dist/core/nodes/ClassNode.d.ts.map +1 -1
  51. package/dist/core/nodes/ClassNode.js +46 -2
  52. package/dist/core/nodes/DecoratorNode.d.ts +42 -0
  53. package/dist/core/nodes/DecoratorNode.d.ts.map +1 -0
  54. package/dist/core/nodes/DecoratorNode.js +62 -0
  55. package/dist/core/nodes/EnumNode.d.ts +42 -0
  56. package/dist/core/nodes/EnumNode.d.ts.map +1 -0
  57. package/dist/core/nodes/EnumNode.js +54 -0
  58. package/dist/core/nodes/ExportNode.d.ts +37 -1
  59. package/dist/core/nodes/ExportNode.d.ts.map +1 -1
  60. package/dist/core/nodes/ExportNode.js +48 -2
  61. package/dist/core/nodes/ExpressionNode.d.ts +97 -0
  62. package/dist/core/nodes/ExpressionNode.d.ts.map +1 -0
  63. package/dist/core/nodes/ExpressionNode.js +178 -0
  64. package/dist/core/nodes/ExternalModuleNode.d.ts +28 -0
  65. package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -0
  66. package/dist/core/nodes/ExternalModuleNode.js +41 -0
  67. package/dist/core/nodes/ExternalStdioNode.d.ts +13 -6
  68. package/dist/core/nodes/ExternalStdioNode.d.ts.map +1 -1
  69. package/dist/core/nodes/ExternalStdioNode.js +15 -8
  70. package/dist/core/nodes/FunctionNode.d.ts +36 -0
  71. package/dist/core/nodes/FunctionNode.d.ts.map +1 -1
  72. package/dist/core/nodes/FunctionNode.js +80 -1
  73. package/dist/core/nodes/ImportNode.d.ts +19 -5
  74. package/dist/core/nodes/ImportNode.d.ts.map +1 -1
  75. package/dist/core/nodes/ImportNode.js +23 -5
  76. package/dist/core/nodes/InterfaceNode.d.ts +46 -0
  77. package/dist/core/nodes/InterfaceNode.d.ts.map +1 -0
  78. package/dist/core/nodes/InterfaceNode.js +55 -0
  79. package/dist/core/nodes/IssueNode.d.ts +73 -0
  80. package/dist/core/nodes/IssueNode.d.ts.map +1 -0
  81. package/dist/core/nodes/IssueNode.js +129 -0
  82. package/dist/core/nodes/MethodCallNode.d.ts +30 -0
  83. package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
  84. package/dist/core/nodes/MethodCallNode.js +49 -0
  85. package/dist/core/nodes/MethodNode.d.ts +32 -0
  86. package/dist/core/nodes/MethodNode.d.ts.map +1 -1
  87. package/dist/core/nodes/MethodNode.js +48 -0
  88. package/dist/core/nodes/ModuleNode.d.ts +31 -0
  89. package/dist/core/nodes/ModuleNode.d.ts.map +1 -1
  90. package/dist/core/nodes/ModuleNode.js +37 -0
  91. package/dist/core/nodes/NetworkRequestNode.d.ts +54 -0
  92. package/dist/core/nodes/NetworkRequestNode.d.ts.map +1 -0
  93. package/dist/core/nodes/NetworkRequestNode.js +65 -0
  94. package/dist/core/nodes/ObjectLiteralNode.d.ts +27 -0
  95. package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -0
  96. package/dist/core/nodes/ObjectLiteralNode.js +41 -0
  97. package/dist/core/nodes/ScopeNode.d.ts +31 -0
  98. package/dist/core/nodes/ScopeNode.d.ts.map +1 -1
  99. package/dist/core/nodes/ScopeNode.js +49 -0
  100. package/dist/core/nodes/TypeNode.d.ts +36 -0
  101. package/dist/core/nodes/TypeNode.d.ts.map +1 -0
  102. package/dist/core/nodes/TypeNode.js +53 -0
  103. package/dist/core/nodes/VariableDeclarationNode.d.ts +27 -0
  104. package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
  105. package/dist/core/nodes/VariableDeclarationNode.js +40 -0
  106. package/dist/core/nodes/index.d.ts +12 -1
  107. package/dist/core/nodes/index.d.ts.map +1 -1
  108. package/dist/core/nodes/index.js +14 -0
  109. package/dist/diagnostics/DiagnosticCollector.d.ts +98 -0
  110. package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
  111. package/dist/diagnostics/DiagnosticCollector.js +129 -0
  112. package/dist/diagnostics/DiagnosticReporter.d.ts +77 -0
  113. package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
  114. package/dist/diagnostics/DiagnosticReporter.js +159 -0
  115. package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
  116. package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
  117. package/dist/diagnostics/DiagnosticWriter.js +43 -0
  118. package/dist/diagnostics/index.d.ts +14 -0
  119. package/dist/diagnostics/index.d.ts.map +1 -0
  120. package/dist/diagnostics/index.js +11 -0
  121. package/dist/errors/GrafemaError.d.ts +118 -0
  122. package/dist/errors/GrafemaError.d.ts.map +1 -0
  123. package/dist/errors/GrafemaError.js +131 -0
  124. package/dist/index.d.ts +57 -1
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +54 -1
  127. package/dist/logging/Logger.d.ts +48 -0
  128. package/dist/logging/Logger.d.ts.map +1 -0
  129. package/dist/logging/Logger.js +134 -0
  130. package/dist/plugins/Plugin.d.ts +5 -1
  131. package/dist/plugins/Plugin.d.ts.map +1 -1
  132. package/dist/plugins/Plugin.js +33 -0
  133. package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
  134. package/dist/plugins/analysis/DatabaseAnalyzer.js +13 -6
  135. package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
  136. package/dist/plugins/analysis/ExpressAnalyzer.js +27 -19
  137. package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
  138. package/dist/plugins/analysis/ExpressRouteAnalyzer.js +21 -14
  139. package/dist/plugins/analysis/FetchAnalyzer.d.ts +1 -0
  140. package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
  141. package/dist/plugins/analysis/FetchAnalyzer.js +34 -14
  142. package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts +6 -3
  143. package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -1
  144. package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +76 -80
  145. package/dist/plugins/analysis/JSASTAnalyzer.d.ts +180 -17
  146. package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
  147. package/dist/plugins/analysis/JSASTAnalyzer.js +1171 -471
  148. package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -1
  149. package/dist/plugins/analysis/ReactAnalyzer.js +56 -57
  150. package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -1
  151. package/dist/plugins/analysis/RustAnalyzer.js +15 -10
  152. package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
  153. package/dist/plugins/analysis/SQLiteAnalyzer.js +9 -7
  154. package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -1
  155. package/dist/plugins/analysis/ServiceLayerAnalyzer.js +21 -9
  156. package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
  157. package/dist/plugins/analysis/SocketIOAnalyzer.js +27 -15
  158. package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -1
  159. package/dist/plugins/analysis/SystemDbAnalyzer.js +15 -5
  160. package/dist/plugins/analysis/ast/GraphBuilder.d.ts +34 -4
  161. package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
  162. package/dist/plugins/analysis/ast/GraphBuilder.js +318 -298
  163. package/dist/plugins/analysis/ast/IdGenerator.d.ts +105 -0
  164. package/dist/plugins/analysis/ast/IdGenerator.d.ts.map +1 -0
  165. package/dist/plugins/analysis/ast/IdGenerator.js +116 -0
  166. package/dist/plugins/analysis/ast/types.d.ts +176 -5
  167. package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
  168. package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts +33 -0
  169. package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts.map +1 -0
  170. package/dist/plugins/analysis/ast/utils/createParameterNodes.js +89 -0
  171. package/dist/plugins/analysis/ast/utils/index.d.ts +6 -0
  172. package/dist/plugins/analysis/ast/utils/index.d.ts.map +1 -0
  173. package/dist/plugins/analysis/ast/utils/index.js +5 -0
  174. package/dist/plugins/analysis/ast/utils/location.d.ts +87 -0
  175. package/dist/plugins/analysis/ast/utils/location.d.ts.map +1 -0
  176. package/dist/plugins/analysis/ast/utils/location.js +78 -0
  177. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +9 -4
  178. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
  179. package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +6 -5
  180. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +99 -9
  181. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
  182. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +663 -125
  183. package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +4 -1
  184. package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -1
  185. package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +72 -32
  186. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +4 -1
  187. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
  188. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +128 -63
  189. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
  190. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +11 -8
  191. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +12 -1
  192. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -1
  193. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +36 -14
  194. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +4 -1
  195. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
  196. package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +17 -13
  197. package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -1
  198. package/dist/plugins/discovery/MonorepoServiceDiscovery.js +3 -2
  199. package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -1
  200. package/dist/plugins/discovery/SimpleProjectDiscovery.js +5 -1
  201. package/dist/plugins/discovery/WorkspaceDiscovery.d.ts +22 -0
  202. package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -0
  203. package/dist/plugins/discovery/WorkspaceDiscovery.js +136 -0
  204. package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts +46 -0
  205. package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts.map +1 -0
  206. package/dist/plugins/discovery/resolveSourceEntrypoint.js +86 -0
  207. package/dist/plugins/discovery/workspaces/detector.d.ts +21 -0
  208. package/dist/plugins/discovery/workspaces/detector.d.ts.map +1 -0
  209. package/dist/plugins/discovery/workspaces/detector.js +49 -0
  210. package/dist/plugins/discovery/workspaces/globResolver.d.ts +35 -0
  211. package/dist/plugins/discovery/workspaces/globResolver.d.ts.map +1 -0
  212. package/dist/plugins/discovery/workspaces/globResolver.js +184 -0
  213. package/dist/plugins/discovery/workspaces/index.d.ts +9 -0
  214. package/dist/plugins/discovery/workspaces/index.d.ts.map +1 -0
  215. package/dist/plugins/discovery/workspaces/index.js +8 -0
  216. package/dist/plugins/discovery/workspaces/parsers.d.ts +38 -0
  217. package/dist/plugins/discovery/workspaces/parsers.d.ts.map +1 -0
  218. package/dist/plugins/discovery/workspaces/parsers.js +80 -0
  219. package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
  220. package/dist/plugins/enrichment/AliasTracker.js +14 -8
  221. package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
  222. package/dist/plugins/enrichment/HTTPConnectionEnricher.js +14 -7
  223. package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
  224. package/dist/plugins/enrichment/ImportExportLinker.js +23 -6
  225. package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
  226. package/dist/plugins/enrichment/MethodCallResolver.js +18 -12
  227. package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
  228. package/dist/plugins/enrichment/MountPointResolver.js +8 -3
  229. package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -1
  230. package/dist/plugins/enrichment/PrefixEvaluator.js +16 -7
  231. package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -1
  232. package/dist/plugins/enrichment/RustFFIEnricher.js +6 -5
  233. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +17 -0
  234. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
  235. package/dist/plugins/enrichment/ValueDomainAnalyzer.js +129 -10
  236. package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -1
  237. package/dist/plugins/indexing/IncrementalModuleIndexer.js +23 -14
  238. package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
  239. package/dist/plugins/indexing/JSModuleIndexer.js +63 -31
  240. package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
  241. package/dist/plugins/indexing/RustModuleIndexer.js +5 -4
  242. package/dist/plugins/indexing/ServiceDetector.d.ts +10 -0
  243. package/dist/plugins/indexing/ServiceDetector.d.ts.map +1 -1
  244. package/dist/plugins/indexing/ServiceDetector.js +28 -15
  245. package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
  246. package/dist/plugins/validation/CallResolverValidator.js +8 -7
  247. package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
  248. package/dist/plugins/validation/DataFlowValidator.js +17 -12
  249. package/dist/plugins/validation/EvalBanValidator.d.ts.map +1 -1
  250. package/dist/plugins/validation/EvalBanValidator.js +17 -16
  251. package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
  252. package/dist/plugins/validation/GraphConnectivityValidator.js +19 -23
  253. package/dist/plugins/validation/NodeCreationValidator.d.ts +85 -0
  254. package/dist/plugins/validation/NodeCreationValidator.d.ts.map +1 -0
  255. package/dist/plugins/validation/NodeCreationValidator.js +415 -0
  256. package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
  257. package/dist/plugins/validation/SQLInjectionValidator.js +59 -16
  258. package/dist/plugins/validation/ShadowingDetector.d.ts.map +1 -1
  259. package/dist/plugins/validation/ShadowingDetector.js +6 -5
  260. package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -1
  261. package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +12 -11
  262. package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -1
  263. package/dist/plugins/vcs/GitPlugin.js +10 -12
  264. package/dist/plugins/vcs/VCSPlugin.d.ts +3 -2
  265. package/dist/plugins/vcs/VCSPlugin.d.ts.map +1 -1
  266. package/dist/plugins/vcs/VCSPlugin.js +5 -5
  267. package/dist/storage/backends/RFDBServerBackend.d.ts +10 -17
  268. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
  269. package/dist/storage/backends/RFDBServerBackend.js +31 -10
  270. package/dist/validation/PathValidator.d.ts +1 -2
  271. package/dist/validation/PathValidator.d.ts.map +1 -1
  272. package/package.json +3 -3
  273. package/src/Orchestrator.ts +237 -24
  274. package/src/config/ConfigLoader.ts +263 -0
  275. package/src/config/index.ts +5 -0
  276. package/src/core/ASTWorker.ts +143 -139
  277. package/src/core/CoverageAnalyzer.ts +243 -0
  278. package/src/core/FileNodeManager.ts +100 -0
  279. package/src/core/GraphFreshnessChecker.ts +143 -0
  280. package/src/core/HashUtils.ts +48 -0
  281. package/src/core/IncrementalReanalyzer.ts +192 -0
  282. package/src/core/NodeFactory.ts +401 -18
  283. package/src/core/ScopeTracker.ts +154 -0
  284. package/src/core/SemanticId.ts +192 -0
  285. package/src/core/VersionManager.ts +3 -2
  286. package/src/core/nodes/ArgumentExpressionNode.ts +89 -0
  287. package/src/core/nodes/ArrayLiteralNode.ts +65 -0
  288. package/src/core/nodes/CallSiteNode.ts +58 -0
  289. package/src/core/nodes/ClassNode.ts +63 -2
  290. package/src/core/nodes/DecoratorNode.ts +91 -0
  291. package/src/core/nodes/EnumNode.ts +86 -0
  292. package/src/core/nodes/ExportNode.ts +70 -2
  293. package/src/core/nodes/ExpressionNode.ts +231 -0
  294. package/src/core/nodes/ExternalModuleNode.ts +56 -0
  295. package/src/core/nodes/ExternalStdioNode.ts +17 -9
  296. package/src/core/nodes/FunctionNode.ts +101 -1
  297. package/src/core/nodes/ImportNode.ts +32 -10
  298. package/src/core/nodes/InterfaceNode.ts +91 -0
  299. package/src/core/nodes/IssueNode.ts +177 -0
  300. package/src/core/nodes/MethodCallNode.ts +64 -0
  301. package/src/core/nodes/MethodNode.ts +63 -0
  302. package/src/core/nodes/ModuleNode.ts +50 -0
  303. package/src/core/nodes/NetworkRequestNode.ts +77 -0
  304. package/src/core/nodes/ObjectLiteralNode.ts +65 -0
  305. package/src/core/nodes/ScopeNode.ts +65 -0
  306. package/src/core/nodes/TypeNode.ts +78 -0
  307. package/src/core/nodes/VariableDeclarationNode.ts +52 -0
  308. package/src/core/nodes/index.ts +18 -1
  309. package/src/diagnostics/DiagnosticCollector.ts +163 -0
  310. package/src/diagnostics/DiagnosticReporter.ts +204 -0
  311. package/src/diagnostics/DiagnosticWriter.ts +50 -0
  312. package/src/diagnostics/index.ts +16 -0
  313. package/src/errors/GrafemaError.ts +174 -0
  314. package/src/index.ts +148 -1
  315. package/src/logging/Logger.ts +152 -0
  316. package/src/plugins/Plugin.ts +42 -0
  317. package/src/plugins/analysis/DatabaseAnalyzer.ts +14 -8
  318. package/src/plugins/analysis/ExpressAnalyzer.ts +29 -19
  319. package/src/plugins/analysis/ExpressRouteAnalyzer.ts +22 -21
  320. package/src/plugins/analysis/FetchAnalyzer.ts +39 -16
  321. package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +84 -101
  322. package/src/plugins/analysis/JSASTAnalyzer.ts +1483 -503
  323. package/src/plugins/analysis/ReactAnalyzer.ts +57 -57
  324. package/src/plugins/analysis/RustAnalyzer.ts +15 -10
  325. package/src/plugins/analysis/SQLiteAnalyzer.ts +10 -7
  326. package/src/plugins/analysis/ServiceLayerAnalyzer.ts +22 -16
  327. package/src/plugins/analysis/SocketIOAnalyzer.ts +31 -22
  328. package/src/plugins/analysis/SystemDbAnalyzer.ts +16 -11
  329. package/src/plugins/analysis/ast/GraphBuilder.ts +439 -327
  330. package/src/plugins/analysis/ast/IdGenerator.ts +177 -0
  331. package/src/plugins/analysis/ast/types.ts +209 -6
  332. package/src/plugins/analysis/ast/utils/createParameterNodes.ts +104 -0
  333. package/src/plugins/analysis/ast/utils/index.ts +12 -0
  334. package/src/plugins/analysis/ast/utils/location.ts +103 -0
  335. package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +11 -8
  336. package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +909 -83
  337. package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +97 -44
  338. package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +159 -93
  339. package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +12 -8
  340. package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +41 -14
  341. package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +37 -17
  342. package/src/plugins/discovery/MonorepoServiceDiscovery.ts +3 -2
  343. package/src/plugins/discovery/SimpleProjectDiscovery.ts +6 -1
  344. package/src/plugins/discovery/WorkspaceDiscovery.ts +177 -0
  345. package/src/plugins/discovery/resolveSourceEntrypoint.ts +103 -0
  346. package/src/plugins/discovery/workspaces/detector.ts +63 -0
  347. package/src/plugins/discovery/workspaces/globResolver.ts +229 -0
  348. package/src/plugins/discovery/workspaces/index.ts +23 -0
  349. package/src/plugins/discovery/workspaces/parsers.ts +99 -0
  350. package/src/plugins/enrichment/AliasTracker.ts +14 -8
  351. package/src/plugins/enrichment/HTTPConnectionEnricher.ts +14 -7
  352. package/src/plugins/enrichment/ImportExportLinker.ts +24 -6
  353. package/src/plugins/enrichment/MethodCallResolver.ts +18 -12
  354. package/src/plugins/enrichment/MountPointResolver.ts +8 -3
  355. package/src/plugins/enrichment/PrefixEvaluator.ts +16 -7
  356. package/src/plugins/enrichment/RustFFIEnricher.ts +6 -5
  357. package/src/plugins/enrichment/ValueDomainAnalyzer.ts +149 -12
  358. package/src/plugins/indexing/IncrementalModuleIndexer.ts +23 -14
  359. package/src/plugins/indexing/JSModuleIndexer.ts +74 -34
  360. package/src/plugins/indexing/RustModuleIndexer.ts +5 -4
  361. package/src/plugins/validation/CallResolverValidator.ts +8 -7
  362. package/src/plugins/validation/DataFlowValidator.ts +16 -12
  363. package/src/plugins/validation/EvalBanValidator.ts +17 -16
  364. package/src/plugins/validation/GraphConnectivityValidator.ts +19 -23
  365. package/src/plugins/validation/NodeCreationValidator.ts +554 -0
  366. package/src/plugins/validation/SQLInjectionValidator.ts +61 -15
  367. package/src/plugins/validation/ShadowingDetector.ts +6 -5
  368. package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +12 -11
  369. package/src/plugins/vcs/GitPlugin.ts +40 -12
  370. package/src/plugins/vcs/VCSPlugin.ts +7 -5
  371. package/src/storage/backends/RFDBServerBackend.ts +43 -29
  372. package/src/validation/PathValidator.ts +1 -1
  373. package/dist/core/AnalysisWorker.d.ts +0 -14
  374. package/dist/core/AnalysisWorker.d.ts.map +0 -1
  375. package/dist/core/AnalysisWorker.js +0 -307
  376. package/dist/core/ParallelAnalyzer.d.ts +0 -120
  377. package/dist/core/ParallelAnalyzer.d.ts.map +0 -1
  378. package/dist/core/ParallelAnalyzer.js +0 -331
  379. package/dist/core/QueueWorker.d.ts +0 -12
  380. package/dist/core/QueueWorker.d.ts.map +0 -1
  381. package/dist/core/QueueWorker.js +0 -567
  382. package/dist/core/RFDBClient.d.ts +0 -179
  383. package/dist/core/RFDBClient.d.ts.map +0 -1
  384. package/dist/core/RFDBClient.js +0 -429
  385. package/dist/plugins/discovery/ZonServiceDiscovery.d.ts +0 -19
  386. package/dist/plugins/discovery/ZonServiceDiscovery.d.ts.map +0 -1
  387. package/dist/plugins/discovery/ZonServiceDiscovery.js +0 -204
  388. package/src/core/AnalysisWorker.ts +0 -410
  389. package/src/core/ParallelAnalyzer.ts +0 -476
  390. package/src/core/QueueWorker.ts +0 -780
  391. package/src/plugins/indexing/ServiceDetector.ts +0 -230
@@ -9,10 +9,15 @@ import { fileURLToPath } from 'url';
9
9
  import { spawn, execSync, ChildProcess } from 'child_process';
10
10
  import { setTimeout as sleep } from 'timers/promises';
11
11
  import { SimpleProjectDiscovery } from './plugins/discovery/SimpleProjectDiscovery.js';
12
+ import { resolveSourceEntrypoint } from './plugins/discovery/resolveSourceEntrypoint.js';
12
13
  import { Profiler } from './core/Profiler.js';
13
14
  import { AnalysisQueue } from './core/AnalysisQueue.js';
15
+ import { DiagnosticCollector } from './diagnostics/DiagnosticCollector.js';
14
16
  import type { Plugin, PluginContext } from './plugins/Plugin.js';
15
- import type { GraphBackend } from '@grafema/types';
17
+ import type { GraphBackend, PluginPhase, Logger, LogLevel, IssueSpec, ServiceDefinition } from '@grafema/types';
18
+ import { createLogger } from './logging/Logger.js';
19
+ import { NodeFactory } from './core/NodeFactory.js';
20
+ import type { IssueSeverity } from './core/nodes/IssueNode.js';
16
21
 
17
22
  /**
18
23
  * Progress callback info
@@ -50,8 +55,19 @@ export interface OrchestratorOptions {
50
55
  onProgress?: ProgressCallback;
51
56
  forceAnalysis?: boolean;
52
57
  serviceFilter?: string | null;
58
+ /** Override entrypoint, bypasses auto-detection. Path relative to project root. */
59
+ entrypoint?: string;
53
60
  indexOnly?: boolean;
54
61
  parallel?: ParallelConfig | null;
62
+ /** Logger instance for structured logging. */
63
+ logger?: Logger;
64
+ /** Log level for the default logger. Ignored if logger is provided. */
65
+ logLevel?: LogLevel;
66
+ /**
67
+ * Config-provided services (REG-174).
68
+ * If provided and non-empty, discovery plugins are skipped.
69
+ */
70
+ services?: ServiceDefinition[];
55
71
  }
56
72
 
57
73
  /**
@@ -125,12 +141,17 @@ export class Orchestrator {
125
141
  private onProgress: ProgressCallback;
126
142
  private forceAnalysis: boolean;
127
143
  private serviceFilter: string | null;
144
+ private entrypoint: string | undefined;
128
145
  private indexOnly: boolean;
129
146
  private profiler: Profiler;
130
147
  private parallelConfig: ParallelConfig | null;
131
148
  private analysisQueue: AnalysisQueue | null;
132
149
  private rfdbServerProcess: ChildProcess | null;
133
150
  private _serverWasExternal: boolean;
151
+ private diagnosticCollector: DiagnosticCollector;
152
+ private logger: Logger;
153
+ /** Config-provided services (REG-174) */
154
+ private configServices: ServiceDefinition[] | undefined;
134
155
 
135
156
  constructor(options: OrchestratorOptions = {}) {
136
157
  this.graph = options.graph!;
@@ -140,6 +161,7 @@ export class Orchestrator {
140
161
  this.onProgress = options.onProgress || (() => {}); // Callback для прогресса
141
162
  this.forceAnalysis = options.forceAnalysis || false; // Флаг для игнорирования кэша
142
163
  this.serviceFilter = options.serviceFilter || null; // Фильтр для одного сервиса
164
+ this.entrypoint = options.entrypoint; // Override entrypoint, bypasses discovery
143
165
  this.indexOnly = options.indexOnly || false; // Только DISCOVERY + INDEXING (для coverage)
144
166
  this.profiler = new Profiler('Orchestrator');
145
167
 
@@ -149,9 +171,21 @@ export class Orchestrator {
149
171
  this.rfdbServerProcess = null;
150
172
  this._serverWasExternal = false;
151
173
 
152
- // Auto-add default discovery if no discovery plugins provided
174
+ // Initialize diagnostic collector
175
+ this.diagnosticCollector = new DiagnosticCollector();
176
+
177
+ // Initialize logger (use provided or create default)
178
+ this.logger = options.logger ?? createLogger(options.logLevel ?? 'info');
179
+
180
+ // Store config-provided services (REG-174)
181
+ this.configServices = options.services;
182
+
183
+ // Modified auto-add logic: SKIP auto-add if config services provided (REG-174)
153
184
  const hasDiscovery = this.plugins.some(p => p.metadata?.phase === 'DISCOVERY');
154
- if (!hasDiscovery) {
185
+ const hasConfigServices = this.configServices && this.configServices.length > 0;
186
+
187
+ if (!hasDiscovery && !hasConfigServices) {
188
+ // Only auto-add if NO discovery plugins AND NO config services
155
189
  this.plugins.unshift(new SimpleProjectDiscovery());
156
190
  }
157
191
  }
@@ -165,11 +199,38 @@ export class Orchestrator {
165
199
  // Resolve to absolute path
166
200
  const absoluteProjectPath = projectPath.startsWith('/') ? projectPath : resolve(projectPath);
167
201
 
202
+ // RADICAL SIMPLIFICATION: Clear entire graph once at the start if forceAnalysis
203
+ if (this.forceAnalysis && this.graph.clear) {
204
+ this.logger.info('Clearing entire graph (forceAnalysis=true)');
205
+ await this.graph.clear();
206
+ this.logger.info('Graph cleared successfully');
207
+ }
208
+
168
209
  this.onProgress({ phase: 'discovery', currentPlugin: 'Starting discovery...', message: 'Discovering services...', totalFiles: 0, processedFiles: 0 });
169
210
 
170
- // PHASE 0: DISCOVERY - запуск плагинов фазы DISCOVERY
211
+ // PHASE 0: DISCOVERY - запуск плагинов фазы DISCOVERY (or use entrypoint override)
171
212
  this.profiler.start('DISCOVERY');
172
- const manifest = await this.discover(absoluteProjectPath);
213
+ let manifest: DiscoveryManifest;
214
+ if (this.entrypoint) {
215
+ // Skip discovery, create synthetic manifest with single service
216
+ const entrypointPath = this.entrypoint.startsWith('/')
217
+ ? this.entrypoint
218
+ : join(absoluteProjectPath, this.entrypoint);
219
+ const serviceName = this.entrypoint.split('/').pop()?.replace(/\.[^.]+$/, '') || 'main';
220
+ manifest = {
221
+ services: [{
222
+ id: `service:${serviceName}`,
223
+ name: serviceName,
224
+ path: entrypointPath,
225
+ metadata: { entrypoint: entrypointPath }
226
+ }],
227
+ entrypoints: [],
228
+ projectPath: absoluteProjectPath
229
+ };
230
+ this.logger.info('Using entrypoint override', { entrypoint: this.entrypoint, resolved: entrypointPath });
231
+ } else {
232
+ manifest = await this.discover(absoluteProjectPath);
233
+ }
173
234
  this.profiler.end('DISCOVERY');
174
235
 
175
236
  const epCount = manifest.entrypoints?.length || 0;
@@ -181,7 +242,7 @@ export class Orchestrator {
181
242
  totalFiles: 0,
182
243
  processedFiles: 0
183
244
  });
184
- console.log(`[Orchestrator] Discovery: ${svcCount} services, ${epCount} entrypoints`);
245
+ this.logger.info('Discovery complete', { services: svcCount, entrypoints: epCount });
185
246
 
186
247
  // Build unified list of indexing units from services AND entrypoints
187
248
  const indexingUnits = this.buildIndexingUnits(manifest);
@@ -195,13 +256,12 @@ export class Orchestrator {
195
256
  u.name.includes(this.serviceFilter!) ||
196
257
  u.path.includes(this.serviceFilter!)
197
258
  );
198
- console.log(`[Orchestrator] Filtering: ${this.serviceFilter} (found ${unitsToProcess.length} of ${indexingUnits.length})`);
259
+ this.logger.info('Filtering services', { filter: this.serviceFilter, found: unitsToProcess.length, total: indexingUnits.length });
199
260
  } else {
200
261
  unitsToProcess = indexingUnits;
201
262
  }
202
263
 
203
- console.log(`[Orchestrator] Processing ${unitsToProcess.length} indexing units (services + entrypoints)`);
204
- console.log(`[Orchestrator] Strategy: Phase-by-phase with DFS dependency tree per entrypoint`);
264
+ this.logger.info('Processing indexing units', { count: unitsToProcess.length, strategy: 'Phase-by-phase with DFS' });
205
265
 
206
266
  // PHASE 1: INDEXING - каждый сервис строит своё дерево зависимостей от entrypoint
207
267
  const indexingStart = Date.now();
@@ -232,6 +292,7 @@ export class Orchestrator {
232
292
  // Параллельно обрабатываем батч units
233
293
  await Promise.all(batch.map(async (unit, idx) => {
234
294
  const unitStart = Date.now();
295
+
235
296
  const unitManifest: UnitManifest = {
236
297
  projectPath: manifest.projectPath,
237
298
  service: {
@@ -243,9 +304,13 @@ export class Orchestrator {
243
304
  modules: []
244
305
  };
245
306
 
246
- await this.runPhase('INDEXING', { manifest: unitManifest, graph: this.graph, workerCount: 1 });
307
+ await this.runPhase('INDEXING', {
308
+ manifest: unitManifest,
309
+ graph: this.graph,
310
+ workerCount: 1,
311
+ });
247
312
  const unitTime = ((Date.now() - unitStart) / 1000).toFixed(2);
248
- console.log(`[Orchestrator] ⏱️ INDEXING ${unit.name}: ${unitTime}s`);
313
+ this.logger.debug('INDEXING complete', { unit: unit.name, duration: unitTime });
249
314
 
250
315
  this.onProgress({
251
316
  phase: 'indexing',
@@ -260,13 +325,12 @@ export class Orchestrator {
260
325
  processedUnits += batch.length;
261
326
  }
262
327
  this.profiler.end('INDEXING');
263
- console.log(`[Orchestrator] ⏱️ INDEXING phase total: ${((Date.now() - indexingStart) / 1000).toFixed(2)}s`);
328
+ this.logger.info('INDEXING phase complete', { duration: ((Date.now() - indexingStart) / 1000).toFixed(2) });
264
329
 
265
330
  // Skip remaining phases if indexOnly mode (for coverage)
266
331
  if (this.indexOnly) {
267
332
  const totalTime = ((Date.now() - totalStartTime) / 1000).toFixed(2);
268
- console.log(`[Orchestrator] ⏱️ indexOnly mode - skipping ANALYSIS/ENRICHMENT/VALIDATION`);
269
- console.log(`[Orchestrator] ⏱️ Total time: ${totalTime}s for ${unitsToProcess.length} units`);
333
+ this.logger.info('indexOnly mode - skipping remaining phases', { duration: totalTime, units: unitsToProcess.length });
270
334
  return manifest;
271
335
  }
272
336
 
@@ -313,9 +377,13 @@ export class Orchestrator {
313
377
  modules: []
314
378
  };
315
379
 
316
- await this.runPhase('ANALYSIS', { manifest: unitManifest, graph: this.graph, workerCount: 1 });
380
+ await this.runPhase('ANALYSIS', {
381
+ manifest: unitManifest,
382
+ graph: this.graph,
383
+ workerCount: 1,
384
+ });
317
385
  const unitTime = ((Date.now() - unitStart) / 1000).toFixed(2);
318
- console.log(`[Orchestrator] ⏱️ ANALYSIS ${unit.name}: ${unitTime}s`);
386
+ this.logger.debug('ANALYSIS complete', { unit: unit.name, duration: unitTime });
319
387
 
320
388
  this.onProgress({
321
389
  phase: 'analysis',
@@ -332,7 +400,7 @@ export class Orchestrator {
332
400
  }
333
401
 
334
402
  this.profiler.end('ANALYSIS');
335
- console.log(`[Orchestrator] ⏱️ ANALYSIS phase total: ${((Date.now() - analysisStart) / 1000).toFixed(2)}s`);
403
+ this.logger.info('ANALYSIS phase complete', { duration: ((Date.now() - analysisStart) / 1000).toFixed(2) });
336
404
 
337
405
  // PHASE 3: ENRICHMENT - post-processing, граф traversal, вычисления (глобально)
338
406
  const enrichmentStart = Date.now();
@@ -340,7 +408,7 @@ export class Orchestrator {
340
408
  this.onProgress({ phase: 'enrichment', currentPlugin: 'Starting enrichment...', message: 'Enriching graph data...', totalFiles: 0, processedFiles: 0 });
341
409
  await this.runPhase('ENRICHMENT', { manifest, graph: this.graph, workerCount: this.workerCount });
342
410
  this.profiler.end('ENRICHMENT');
343
- console.log(`[Orchestrator] ⏱️ ENRICHMENT phase: ${((Date.now() - enrichmentStart) / 1000).toFixed(2)}s`);
411
+ this.logger.info('ENRICHMENT phase complete', { duration: ((Date.now() - enrichmentStart) / 1000).toFixed(2) });
344
412
 
345
413
  // PHASE 4: VALIDATION - проверка корректности графа (глобально)
346
414
  const validationStart = Date.now();
@@ -348,7 +416,7 @@ export class Orchestrator {
348
416
  this.onProgress({ phase: 'validation', currentPlugin: 'Starting validation...', message: 'Validating graph structure...', totalFiles: 0, processedFiles: 0 });
349
417
  await this.runPhase('VALIDATION', { manifest, graph: this.graph, workerCount: this.workerCount });
350
418
  this.profiler.end('VALIDATION');
351
- console.log(`[Orchestrator] ⏱️ VALIDATION phase: ${((Date.now() - validationStart) / 1000).toFixed(2)}s`);
419
+ this.logger.info('VALIDATION phase complete', { duration: ((Date.now() - validationStart) / 1000).toFixed(2) });
352
420
 
353
421
  // Flush graph to ensure all edges are persisted and queryable
354
422
  if (this.graph.flush) {
@@ -356,7 +424,7 @@ export class Orchestrator {
356
424
  }
357
425
 
358
426
  const totalTime = ((Date.now() - totalStartTime) / 1000).toFixed(2);
359
- console.log(`[Orchestrator] ⏱️ Total time: ${totalTime}s for ${unitsToProcess.length} units`);
427
+ this.logger.info('Analysis complete', { duration: totalTime, units: unitsToProcess.length });
360
428
 
361
429
  // Print profiling summary
362
430
  this.profiler.printSummary();
@@ -409,14 +477,86 @@ export class Orchestrator {
409
477
  }
410
478
 
411
479
  /**
412
- * PHASE 0: Discovery - запуск плагинов DISCOVERY фазы
480
+ * PHASE 0: Discovery - запуск плагинов DISCOVERY фазы.
481
+ * If config services are provided, they take precedence and plugins are skipped.
413
482
  */
414
483
  async discover(projectPath: string): Promise<DiscoveryManifest> {
484
+ // REG-174: If config provided services, use them directly instead of running discovery plugins
485
+ if (this.configServices && this.configServices.length > 0) {
486
+ this.logger.info('Using config-provided services (skipping discovery plugins)', {
487
+ serviceCount: this.configServices.length
488
+ });
489
+
490
+ const services: ServiceInfo[] = [];
491
+ // For each config service:
492
+ // 1. Resolve path relative to project root (validation ensures paths are relative)
493
+ // 2. Auto-detect entrypoint from package.json if not specified
494
+ // 3. Fall back to 'index.js' if detection fails
495
+ for (const configSvc of this.configServices) {
496
+ // All paths are relative (absolute paths rejected by ConfigLoader validation)
497
+ const servicePath = join(projectPath, configSvc.path);
498
+
499
+ // Resolve entrypoint
500
+ let entrypoint: string;
501
+ if (configSvc.entryPoint) {
502
+ entrypoint = configSvc.entryPoint;
503
+ } else {
504
+ // Auto-detect if not provided
505
+ const packageJsonPath = join(servicePath, 'package.json');
506
+ if (existsSync(packageJsonPath)) {
507
+ try {
508
+ const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
509
+ entrypoint = resolveSourceEntrypoint(servicePath, pkg) ?? pkg.main ?? 'index.js';
510
+ } catch (e) {
511
+ this.logger.warn('Failed to read package.json for auto-detection', {
512
+ service: configSvc.name,
513
+ path: packageJsonPath,
514
+ error: (e as Error).message
515
+ });
516
+ entrypoint = 'index.js';
517
+ }
518
+ } else {
519
+ entrypoint = 'index.js';
520
+ }
521
+ }
522
+
523
+ // Create SERVICE node
524
+ const serviceNode = NodeFactory.createService(configSvc.name, servicePath, {
525
+ discoveryMethod: 'config',
526
+ entrypoint: entrypoint,
527
+ });
528
+ await this.graph.addNode(serviceNode);
529
+
530
+ services.push({
531
+ id: serviceNode.id,
532
+ name: configSvc.name,
533
+ path: servicePath,
534
+ metadata: {
535
+ entrypoint: join(servicePath, entrypoint),
536
+ },
537
+ });
538
+
539
+ this.logger.info('Registered config service', {
540
+ name: configSvc.name,
541
+ path: servicePath,
542
+ entrypoint: entrypoint
543
+ });
544
+ }
545
+
546
+ return {
547
+ services,
548
+ entrypoints: [], // Config services don't provide entrypoints
549
+ projectPath: projectPath
550
+ };
551
+ }
552
+
553
+ // ORIGINAL CODE: Run discovery plugins if no config services
415
554
  const context = {
416
555
  projectPath,
417
556
  graph: this.graph,
418
557
  config: this.config,
419
- phase: 'DISCOVERY'
558
+ phase: 'DISCOVERY',
559
+ logger: this.logger,
420
560
  };
421
561
 
422
562
  // Фильтруем плагины для фазы DISCOVERY
@@ -491,9 +631,75 @@ export class Orchestrator {
491
631
  const pluginContext: PluginContext = {
492
632
  ...context,
493
633
  onProgress: this.onProgress as unknown as PluginContext['onProgress'],
494
- forceAnalysis: this.forceAnalysis
634
+ forceAnalysis: this.forceAnalysis,
635
+ logger: this.logger,
495
636
  };
496
- await plugin.execute(pluginContext);
637
+
638
+ // Add reportIssue for VALIDATION phase
639
+ if (phaseName === 'VALIDATION') {
640
+ pluginContext.reportIssue = async (issue: IssueSpec): Promise<string> => {
641
+ const node = NodeFactory.createIssue(
642
+ issue.category,
643
+ issue.severity as IssueSeverity,
644
+ issue.message,
645
+ plugin.metadata.name,
646
+ issue.file,
647
+ issue.line,
648
+ issue.column || 0,
649
+ { context: issue.context }
650
+ );
651
+ await context.graph.addNode(node);
652
+ if (issue.targetNodeId) {
653
+ await context.graph.addEdge({
654
+ src: node.id,
655
+ dst: issue.targetNodeId,
656
+ type: 'AFFECTS',
657
+ });
658
+ }
659
+ return node.id;
660
+ };
661
+ }
662
+
663
+ try {
664
+ const result = await plugin.execute(pluginContext);
665
+
666
+ // Collect errors into diagnostics
667
+ this.diagnosticCollector.addFromPluginResult(
668
+ phaseName as PluginPhase,
669
+ plugin.metadata.name,
670
+ result
671
+ );
672
+
673
+ // Log plugin completion with warning if errors occurred
674
+ if (!result.success) {
675
+ console.warn(`[Orchestrator] Plugin ${plugin.metadata.name} reported failure`, {
676
+ errors: result.errors.length,
677
+ warnings: result.warnings.length,
678
+ });
679
+ }
680
+
681
+ // Check for fatal errors - STOP immediately
682
+ if (this.diagnosticCollector.hasFatal()) {
683
+ const allDiagnostics = this.diagnosticCollector.getAll();
684
+ const fatal = allDiagnostics.find(d => d.severity === 'fatal');
685
+ throw new Error(`Fatal error in ${plugin.metadata.name}: ${fatal?.message || 'Unknown fatal error'}`);
686
+ }
687
+ } catch (e) {
688
+ // Plugin threw an exception (not just returned errors)
689
+ const error = e instanceof Error ? e : new Error(String(e));
690
+
691
+ // Don't re-add if this was already a fatal error we threw
692
+ if (!this.diagnosticCollector.hasFatal()) {
693
+ this.diagnosticCollector.add({
694
+ code: 'ERR_PLUGIN_THREW',
695
+ severity: 'fatal',
696
+ message: error.message,
697
+ phase: phaseName as PluginPhase,
698
+ plugin: plugin.metadata.name,
699
+ });
700
+ }
701
+ throw error; // Re-throw to stop analysis
702
+ }
497
703
 
498
704
  // Send completion for this plugin
499
705
  this.onProgress({
@@ -504,6 +710,13 @@ export class Orchestrator {
504
710
  }
505
711
  }
506
712
 
713
+ /**
714
+ * Get the diagnostic collector for retrieving all collected diagnostics
715
+ */
716
+ getDiagnostics(): DiagnosticCollector {
717
+ return this.diagnosticCollector;
718
+ }
719
+
507
720
  /**
508
721
  * Run queue-based parallel analysis using worker_threads and RFDB server
509
722
  *
@@ -0,0 +1,263 @@
1
+ import { readFileSync, existsSync, statSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { parse as parseYAML } from 'yaml';
4
+ import type { ServiceDefinition } from '@grafema/types';
5
+
6
+ /**
7
+ * Grafema configuration schema.
8
+ *
9
+ * YAML Location: .grafema/config.yaml (preferred) or .grafema/config.json (deprecated)
10
+ *
11
+ * Example config.yaml:
12
+ *
13
+ * ```yaml
14
+ * # Plugins for each analysis phase
15
+ * plugins:
16
+ * indexing:
17
+ * - JSModuleIndexer
18
+ * analysis:
19
+ * - JSASTAnalyzer
20
+ * - ExpressRouteAnalyzer
21
+ * enrichment:
22
+ * - MethodCallResolver
23
+ * validation:
24
+ * - EvalBanValidator
25
+ *
26
+ * # Optional: Explicit service definitions (bypass auto-discovery)
27
+ * services:
28
+ * - name: "backend"
29
+ * path: "apps/backend" # Relative to project root
30
+ * entryPoint: "src/index.ts" # Optional, auto-detected if omitted
31
+ * - name: "frontend"
32
+ * path: "apps/frontend"
33
+ * ```
34
+ *
35
+ * If 'services' is not specified or empty, auto-discovery is used (SimpleProjectDiscovery).
36
+ * If 'services' is specified and non-empty, auto-discovery plugins are skipped entirely.
37
+ */
38
+ export interface GrafemaConfig {
39
+ plugins: {
40
+ discovery?: string[];
41
+ indexing: string[];
42
+ analysis: string[];
43
+ enrichment: string[];
44
+ validation: string[];
45
+ };
46
+ /**
47
+ * Optional explicit services for manual configuration.
48
+ * If provided and non-empty, auto-discovery is skipped.
49
+ */
50
+ services: ServiceDefinition[];
51
+ }
52
+
53
+ /**
54
+ * Default plugin configuration.
55
+ * Matches current DEFAULT_PLUGINS in analyze.ts and config.ts (MCP).
56
+ */
57
+ export const DEFAULT_CONFIG: GrafemaConfig = {
58
+ plugins: {
59
+ discovery: [],
60
+ indexing: ['JSModuleIndexer'],
61
+ analysis: [
62
+ 'JSASTAnalyzer',
63
+ 'ExpressRouteAnalyzer',
64
+ 'SocketIOAnalyzer',
65
+ 'DatabaseAnalyzer',
66
+ 'FetchAnalyzer',
67
+ 'ServiceLayerAnalyzer',
68
+ ],
69
+ enrichment: [
70
+ 'MethodCallResolver',
71
+ 'AliasTracker',
72
+ 'ValueDomainAnalyzer',
73
+ 'MountPointResolver',
74
+ 'PrefixEvaluator',
75
+ 'ImportExportLinker',
76
+ 'HTTPConnectionEnricher',
77
+ ],
78
+ validation: [
79
+ 'CallResolverValidator',
80
+ 'EvalBanValidator',
81
+ 'SQLInjectionValidator',
82
+ 'ShadowingDetector',
83
+ 'GraphConnectivityValidator',
84
+ 'DataFlowValidator',
85
+ 'TypeScriptDeadCodeValidator',
86
+ ],
87
+ },
88
+ services: [], // Empty by default (uses auto-discovery)
89
+ };
90
+
91
+ /**
92
+ * Load Grafema config from project directory.
93
+ *
94
+ * Priority:
95
+ * 1. config.yaml (preferred)
96
+ * 2. config.json (deprecated, fallback)
97
+ * 3. DEFAULT_CONFIG (if neither exists)
98
+ *
99
+ * Warnings:
100
+ * - Logs deprecation warning if config.json is used
101
+ * - Logs parse errors but doesn't throw (returns defaults)
102
+ *
103
+ * @param projectPath - Absolute path to project root
104
+ * @param logger - Optional logger for warnings (defaults to console.warn)
105
+ * @returns Parsed config or defaults
106
+ */
107
+ export function loadConfig(
108
+ projectPath: string,
109
+ logger: { warn: (msg: string) => void } = console
110
+ ): GrafemaConfig {
111
+ const grafemaDir = join(projectPath, '.grafema');
112
+ const yamlPath = join(grafemaDir, 'config.yaml');
113
+ const jsonPath = join(grafemaDir, 'config.json');
114
+
115
+ // 1. Try YAML first (preferred)
116
+ if (existsSync(yamlPath)) {
117
+ let parsed: Partial<GrafemaConfig>;
118
+
119
+ try {
120
+ const content = readFileSync(yamlPath, 'utf-8');
121
+ parsed = parseYAML(content) as Partial<GrafemaConfig>;
122
+
123
+ // Validate structure - ensure plugins sections are arrays if they exist
124
+ if (parsed.plugins) {
125
+ for (const phase of ['discovery', 'indexing', 'analysis', 'enrichment', 'validation'] as const) {
126
+ const value = parsed.plugins[phase];
127
+ if (value !== undefined && value !== null && !Array.isArray(value)) {
128
+ throw new Error(`plugins.${phase} must be an array, got ${typeof value}`);
129
+ }
130
+ }
131
+ }
132
+ } catch (err) {
133
+ const error = err instanceof Error ? err : new Error(String(err));
134
+ logger.warn(`Failed to parse config.yaml: ${error.message}`);
135
+ logger.warn('Using default configuration');
136
+ return DEFAULT_CONFIG;
137
+ }
138
+
139
+ // Validate services array if present (THROWS on error per Linus review)
140
+ // This is OUTSIDE try-catch - config errors MUST throw
141
+ validateServices(parsed.services, projectPath);
142
+
143
+ // Merge with defaults (user config may be partial)
144
+ return mergeConfig(DEFAULT_CONFIG, parsed);
145
+ }
146
+
147
+ // 2. Fallback to JSON (migration path)
148
+ if (existsSync(jsonPath)) {
149
+ logger.warn('⚠ config.json is deprecated. Run "grafema init --force" to migrate to config.yaml');
150
+
151
+ let parsed: Partial<GrafemaConfig>;
152
+
153
+ try {
154
+ const content = readFileSync(jsonPath, 'utf-8');
155
+ parsed = JSON.parse(content) as Partial<GrafemaConfig>;
156
+ } catch (err) {
157
+ const error = err instanceof Error ? err : new Error(String(err));
158
+ logger.warn(`Failed to parse config.json: ${error.message}`);
159
+ logger.warn('Using default configuration');
160
+ return DEFAULT_CONFIG;
161
+ }
162
+
163
+ // Validate services array if present (THROWS on error)
164
+ // This is OUTSIDE try-catch - config errors MUST throw
165
+ validateServices(parsed.services, projectPath);
166
+
167
+ return mergeConfig(DEFAULT_CONFIG, parsed);
168
+ }
169
+
170
+ // 3. No config file - return defaults
171
+ return DEFAULT_CONFIG;
172
+ }
173
+
174
+ /**
175
+ * Validate services array structure.
176
+ * THROWS on error (fail loudly per Linus review).
177
+ *
178
+ * @param services - Parsed services array (may be undefined)
179
+ * @param projectPath - Project root for path validation
180
+ */
181
+ function validateServices(services: unknown, projectPath: string): void {
182
+ // undefined/null is valid (means use defaults)
183
+ if (services === undefined || services === null) {
184
+ return;
185
+ }
186
+
187
+ // Must be an array
188
+ if (!Array.isArray(services)) {
189
+ throw new Error(`Config error: services must be an array, got ${typeof services}`);
190
+ }
191
+
192
+ // Validate each service
193
+ for (let i = 0; i < services.length; i++) {
194
+ const svc = services[i];
195
+
196
+ // Must be an object
197
+ if (typeof svc !== 'object' || svc === null) {
198
+ throw new Error(`Config error: services[${i}] must be an object`);
199
+ }
200
+
201
+ // Name validation - required, non-empty string
202
+ if (typeof svc.name !== 'string') {
203
+ throw new Error(`Config error: services[${i}].name must be a string, got ${typeof svc.name}`);
204
+ }
205
+ if (!svc.name.trim()) {
206
+ throw new Error(`Config error: services[${i}].name cannot be empty or whitespace-only`);
207
+ }
208
+
209
+ // Path validation - required, non-empty string
210
+ if (typeof svc.path !== 'string') {
211
+ throw new Error(`Config error: services[${i}].path must be a string, got ${typeof svc.path}`);
212
+ }
213
+ if (!svc.path.trim()) {
214
+ throw new Error(`Config error: services[${i}].path cannot be empty or whitespace-only`);
215
+ }
216
+
217
+ // Path validation - must be relative (reject absolute paths per Linus review)
218
+ if (svc.path.startsWith('/') || svc.path.startsWith('~')) {
219
+ throw new Error(`Config error: services[${i}].path must be relative to project root, got "${svc.path}"`);
220
+ }
221
+
222
+ // Path validation - must exist
223
+ const absolutePath = join(projectPath, svc.path);
224
+ if (!existsSync(absolutePath)) {
225
+ throw new Error(`Config error: services[${i}].path "${svc.path}" does not exist`);
226
+ }
227
+
228
+ // Path validation - must be directory
229
+ if (!statSync(absolutePath).isDirectory()) {
230
+ throw new Error(`Config error: services[${i}].path "${svc.path}" must be a directory`);
231
+ }
232
+
233
+ // entryPoint validation (optional field) - must be non-empty string if provided
234
+ if (svc.entryPoint !== undefined) {
235
+ if (typeof svc.entryPoint !== 'string') {
236
+ throw new Error(`Config error: services[${i}].entryPoint must be a string, got ${typeof svc.entryPoint}`);
237
+ }
238
+ if (!svc.entryPoint.trim()) {
239
+ throw new Error(`Config error: services[${i}].entryPoint cannot be empty or whitespace-only`);
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ /**
246
+ * Merge user config with defaults.
247
+ * User config takes precedence, but missing sections use defaults.
248
+ */
249
+ function mergeConfig(
250
+ defaults: GrafemaConfig,
251
+ user: Partial<GrafemaConfig>
252
+ ): GrafemaConfig {
253
+ return {
254
+ plugins: {
255
+ discovery: user.plugins?.discovery ?? defaults.plugins.discovery,
256
+ indexing: user.plugins?.indexing ?? defaults.plugins.indexing,
257
+ analysis: user.plugins?.analysis ?? defaults.plugins.analysis,
258
+ enrichment: user.plugins?.enrichment ?? defaults.plugins.enrichment,
259
+ validation: user.plugins?.validation ?? defaults.plugins.validation,
260
+ },
261
+ services: user.services ?? defaults.services,
262
+ };
263
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Configuration loading utilities
3
+ */
4
+ export { loadConfig, DEFAULT_CONFIG } from './ConfigLoader.js';
5
+ export type { GrafemaConfig } from './ConfigLoader.js';