@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
@@ -0,0 +1,65 @@
1
+ /**
2
+ * ObjectLiteralNode - contract for OBJECT_LITERAL node
3
+ *
4
+ * Represents an object literal expression: { key: value, ... }
5
+ * Used for tracking data flow through object construction.
6
+ */
7
+
8
+ import type { BaseNodeRecord } from '@grafema/types';
9
+
10
+ interface ObjectLiteralNodeRecord extends BaseNodeRecord {
11
+ type: 'OBJECT_LITERAL';
12
+ column: number;
13
+ parentCallId?: string;
14
+ argIndex?: number;
15
+ }
16
+
17
+ interface ObjectLiteralNodeOptions {
18
+ parentCallId?: string;
19
+ argIndex?: number;
20
+ counter?: number;
21
+ }
22
+
23
+ export class ObjectLiteralNode {
24
+ static readonly TYPE = 'OBJECT_LITERAL' as const;
25
+
26
+ static readonly REQUIRED = ['file', 'line', 'column'] as const;
27
+ static readonly OPTIONAL = ['parentCallId', 'argIndex'] as const;
28
+
29
+ static create(
30
+ file: string,
31
+ line: number,
32
+ column: number,
33
+ options: ObjectLiteralNodeOptions = {}
34
+ ): ObjectLiteralNodeRecord {
35
+ if (!file) throw new Error('ObjectLiteralNode.create: file is required');
36
+ if (line === undefined) throw new Error('ObjectLiteralNode.create: line is required');
37
+
38
+ const counter = options.counter !== undefined ? `:${options.counter}` : '';
39
+ const argSuffix = options.argIndex !== undefined ? `arg${options.argIndex}` : 'obj';
40
+ const id = `OBJECT_LITERAL#${argSuffix}#${file}#${line}:${column || 0}${counter}`;
41
+
42
+ return {
43
+ id,
44
+ type: this.TYPE,
45
+ name: `<object>`,
46
+ file,
47
+ line,
48
+ column: column || 0,
49
+ parentCallId: options.parentCallId,
50
+ argIndex: options.argIndex
51
+ };
52
+ }
53
+
54
+ static validate(node: ObjectLiteralNodeRecord): string[] {
55
+ const errors: string[] = [];
56
+ if (node.type !== this.TYPE) errors.push(`Expected type ${this.TYPE}`);
57
+ const nodeRecord = node as unknown as Record<string, unknown>;
58
+ for (const field of this.REQUIRED) {
59
+ if (nodeRecord[field] === undefined) errors.push(`Missing: ${field}`);
60
+ }
61
+ return errors;
62
+ }
63
+ }
64
+
65
+ export type { ObjectLiteralNodeRecord, ObjectLiteralNodeOptions };
@@ -1,8 +1,16 @@
1
1
  /**
2
2
  * ScopeNode - contract for SCOPE node
3
+ *
4
+ * Supports two creation modes:
5
+ * 1. createWithContext() - NEW: Uses ScopeContext + Location for semantic IDs
6
+ * 2. create() - LEGACY: Uses line-based IDs for backward compatibility
7
+ *
8
+ * Semantic ID format: {file}->{scope_path}->SCOPE->{scopeType}#N
9
+ * Example: src/app.js->handler->SCOPE->if#0
3
10
  */
4
11
 
5
12
  import type { BaseNodeRecord } from '@grafema/types';
13
+ import { computeSemanticId, type ScopeContext, type Location } from '../SemanticId.js';
6
14
 
7
15
  interface ScopeNodeRecord extends BaseNodeRecord {
8
16
  type: 'SCOPE';
@@ -22,6 +30,17 @@ interface ScopeNodeOptions {
22
30
  counter?: number;
23
31
  }
24
32
 
33
+ /**
34
+ * Options for createWithContext
35
+ */
36
+ interface ScopeContextOptions {
37
+ discriminator: number;
38
+ conditional?: boolean;
39
+ parentScopeId?: string;
40
+ parentFunctionId?: string;
41
+ capturesFrom?: string[];
42
+ }
43
+
25
44
  export class ScopeNode {
26
45
  static readonly TYPE = 'SCOPE' as const;
27
46
 
@@ -59,6 +78,52 @@ export class ScopeNode {
59
78
  };
60
79
  }
61
80
 
81
+ /**
82
+ * Create SCOPE node with semantic ID (NEW API)
83
+ *
84
+ * Uses ScopeContext from ScopeTracker for stable identifiers.
85
+ * Requires discriminator for multiple scopes of same type within parent scope.
86
+ *
87
+ * @param scopeType - Type of scope (if, else, try, catch, finally, for, while, switch)
88
+ * @param context - Scope context from ScopeTracker.getContext()
89
+ * @param location - Source location { line }
90
+ * @param options - Options including required discriminator
91
+ * @returns ScopeNodeRecord with semantic ID
92
+ */
93
+ static createWithContext(
94
+ scopeType: string,
95
+ context: ScopeContext,
96
+ location: Partial<Location>,
97
+ options: ScopeContextOptions
98
+ ): ScopeNodeRecord {
99
+ // Validate required fields
100
+ if (!scopeType) throw new Error('ScopeNode.createWithContext: scopeType is required');
101
+ if (!context.file) throw new Error('ScopeNode.createWithContext: file is required');
102
+ if (location.line === undefined) throw new Error('ScopeNode.createWithContext: line is required');
103
+ if (options.discriminator === undefined) throw new Error('ScopeNode.createWithContext: discriminator is required');
104
+
105
+ // Compute semantic ID with discriminator
106
+ const id = computeSemanticId('SCOPE', scopeType, context, {
107
+ discriminator: options.discriminator
108
+ });
109
+
110
+ // Name includes the discriminator for display purposes
111
+ const name = `${scopeType}#${options.discriminator}`;
112
+
113
+ return {
114
+ id,
115
+ type: this.TYPE,
116
+ scopeType,
117
+ name,
118
+ file: context.file,
119
+ line: location.line,
120
+ conditional: options.conditional || false,
121
+ parentScopeId: options.parentScopeId,
122
+ parentFunctionId: options.parentFunctionId,
123
+ capturesFrom: options.capturesFrom
124
+ };
125
+ }
126
+
62
127
  static validate(node: ScopeNodeRecord): string[] {
63
128
  const errors: string[] = [];
64
129
 
@@ -0,0 +1,78 @@
1
+ /**
2
+ * TypeNode - contract for TYPE node
3
+ *
4
+ * Represents TypeScript type alias declarations.
5
+ *
6
+ * ID format: {file}:TYPE:{name}:{line}
7
+ * Example: /src/types.ts:TYPE:UserId:10
8
+ */
9
+
10
+ import type { BaseNodeRecord } from '@grafema/types';
11
+
12
+ interface TypeNodeRecord extends BaseNodeRecord {
13
+ type: 'TYPE';
14
+ column: number;
15
+ aliasOf?: string;
16
+ }
17
+
18
+ interface TypeNodeOptions {
19
+ aliasOf?: string;
20
+ }
21
+
22
+ export class TypeNode {
23
+ static readonly TYPE = 'TYPE' as const;
24
+
25
+ static readonly REQUIRED = ['name', 'file', 'line'] as const;
26
+ static readonly OPTIONAL = ['column', 'aliasOf'] as const;
27
+
28
+ /**
29
+ * Create TYPE node
30
+ *
31
+ * @param name - Type alias name
32
+ * @param file - File path
33
+ * @param line - Line number
34
+ * @param column - Column position
35
+ * @param options - Optional type properties
36
+ * @returns TypeNodeRecord
37
+ */
38
+ static create(
39
+ name: string,
40
+ file: string,
41
+ line: number,
42
+ column: number,
43
+ options: TypeNodeOptions = {}
44
+ ): TypeNodeRecord {
45
+ if (!name) throw new Error('TypeNode.create: name is required');
46
+ if (!file) throw new Error('TypeNode.create: file is required');
47
+ if (!line) throw new Error('TypeNode.create: line is required');
48
+
49
+ return {
50
+ id: `${file}:TYPE:${name}:${line}`,
51
+ type: this.TYPE,
52
+ name,
53
+ file,
54
+ line,
55
+ column: column || 0,
56
+ aliasOf: options.aliasOf
57
+ };
58
+ }
59
+
60
+ static validate(node: TypeNodeRecord): string[] {
61
+ const errors: string[] = [];
62
+
63
+ if (node.type !== this.TYPE) {
64
+ errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
65
+ }
66
+
67
+ const nodeRecord = node as unknown as Record<string, unknown>;
68
+ for (const field of this.REQUIRED) {
69
+ if (!nodeRecord[field]) {
70
+ errors.push(`Missing required field: ${field}`);
71
+ }
72
+ }
73
+
74
+ return errors;
75
+ }
76
+ }
77
+
78
+ export type { TypeNodeRecord };
@@ -1,8 +1,16 @@
1
1
  /**
2
2
  * VariableDeclarationNode - contract for VARIABLE_DECLARATION node
3
+ *
4
+ * Supports two creation modes:
5
+ * 1. createWithContext() - NEW: Uses ScopeContext + Location for semantic IDs
6
+ * 2. create() - LEGACY: Uses line-based IDs for backward compatibility
7
+ *
8
+ * Semantic ID format: {file}->{scope_path}->VARIABLE->{name}
9
+ * Example: src/app.js->handler->VARIABLE->result
3
10
  */
4
11
 
5
12
  import type { BaseNodeRecord } from '@grafema/types';
13
+ import { computeSemanticId, type ScopeContext, type Location } from '../SemanticId.js';
6
14
 
7
15
  interface VariableDeclarationNodeRecord extends BaseNodeRecord {
8
16
  type: 'VARIABLE_DECLARATION';
@@ -15,6 +23,13 @@ interface VariableDeclarationNodeOptions {
15
23
  counter?: number;
16
24
  }
17
25
 
26
+ /**
27
+ * Options for createWithContext
28
+ */
29
+ interface VariableContextOptions {
30
+ parentScopeId?: string;
31
+ }
32
+
18
33
  export class VariableDeclarationNode {
19
34
  static readonly TYPE = 'VARIABLE_DECLARATION' as const;
20
35
 
@@ -46,6 +61,43 @@ export class VariableDeclarationNode {
46
61
  };
47
62
  }
48
63
 
64
+ /**
65
+ * Create VARIABLE_DECLARATION node with semantic ID (NEW API)
66
+ *
67
+ * Uses ScopeContext from ScopeTracker for stable identifiers.
68
+ * Variable names are unique within scope (handles shadowing naturally).
69
+ *
70
+ * @param name - Variable name
71
+ * @param context - Scope context from ScopeTracker.getContext()
72
+ * @param location - Source location { line, column }
73
+ * @param options - Optional variable properties
74
+ * @returns VariableDeclarationNodeRecord with semantic ID
75
+ */
76
+ static createWithContext(
77
+ name: string,
78
+ context: ScopeContext,
79
+ location: Partial<Location>,
80
+ options: VariableContextOptions = {}
81
+ ): VariableDeclarationNodeRecord {
82
+ // Validate required fields
83
+ if (!name) throw new Error('VariableDeclarationNode.createWithContext: name is required');
84
+ if (!context.file) throw new Error('VariableDeclarationNode.createWithContext: file is required');
85
+ if (location.line === undefined) throw new Error('VariableDeclarationNode.createWithContext: line is required');
86
+
87
+ // Compute semantic ID using 'VARIABLE' type for cleaner IDs
88
+ const id = computeSemanticId('VARIABLE', name, context);
89
+
90
+ return {
91
+ id,
92
+ type: this.TYPE,
93
+ name,
94
+ file: context.file,
95
+ line: location.line,
96
+ column: location.column ?? 0,
97
+ parentScopeId: options.parentScopeId
98
+ };
99
+ }
100
+
49
101
  static validate(node: VariableDeclarationNodeRecord): string[] {
50
102
  const errors: string[] = [];
51
103
  if (node.type !== this.TYPE) errors.push(`Expected type ${this.TYPE}`);
@@ -18,13 +18,27 @@ export { MethodCallNode, type MethodCallNodeRecord } from './MethodCallNode.js';
18
18
  export { VariableDeclarationNode, type VariableDeclarationNodeRecord } from './VariableDeclarationNode.js';
19
19
  export { ConstantNode, type ConstantNodeRecord } from './ConstantNode.js';
20
20
  export { LiteralNode, type LiteralNodeRecord } from './LiteralNode.js';
21
+ export { ObjectLiteralNode, type ObjectLiteralNodeRecord, type ObjectLiteralNodeOptions } from './ObjectLiteralNode.js';
22
+ export { ArrayLiteralNode, type ArrayLiteralNodeRecord, type ArrayLiteralNodeOptions } from './ArrayLiteralNode.js';
21
23
 
22
24
  // Import/Export nodes
23
- export { ImportNode, type ImportNodeRecord, type ImportKind } from './ImportNode.js';
25
+ export { ImportNode, type ImportNodeRecord, type ImportBinding, type ImportType } from './ImportNode.js';
24
26
  export { ExportNode, type ExportNodeRecord, type ExportKind } from './ExportNode.js';
27
+ export { ExternalModuleNode, type ExternalModuleNodeRecord } from './ExternalModuleNode.js';
28
+
29
+ // TypeScript declaration nodes
30
+ export { InterfaceNode, type InterfaceNodeRecord, type InterfacePropertyRecord } from './InterfaceNode.js';
31
+ export { TypeNode, type TypeNodeRecord } from './TypeNode.js';
32
+ export { EnumNode, type EnumNodeRecord, type EnumMemberRecord } from './EnumNode.js';
33
+ export { DecoratorNode, type DecoratorNodeRecord, type DecoratorTargetType } from './DecoratorNode.js';
34
+
35
+ // Expression nodes
36
+ export { ExpressionNode, type ExpressionNodeRecord, type ExpressionNodeOptions } from './ExpressionNode.js';
37
+ export { ArgumentExpressionNode, type ArgumentExpressionNodeRecord, type ArgumentExpressionNodeOptions } from './ArgumentExpressionNode.js';
25
38
 
26
39
  // External/IO nodes
27
40
  export { ExternalStdioNode, type ExternalStdioNodeRecord } from './ExternalStdioNode.js';
41
+ export { NetworkRequestNode, type NetworkRequestNodeRecord } from './NetworkRequestNode.js';
28
42
  export { EventListenerNode, type EventListenerNodeRecord } from './EventListenerNode.js';
29
43
  export { HttpRequestNode, type HttpRequestNodeRecord } from './HttpRequestNode.js';
30
44
  export { DatabaseQueryNode, type DatabaseQueryNodeRecord } from './DatabaseQueryNode.js';
@@ -32,6 +46,9 @@ export { DatabaseQueryNode, type DatabaseQueryNodeRecord } from './DatabaseQuery
32
46
  // Guarantee nodes (contract-based)
33
47
  export { GuaranteeNode, type GuaranteeNodeRecord, type GuaranteePriority, type GuaranteeStatus, type GuaranteeType } from './GuaranteeNode.js';
34
48
 
49
+ // Issue nodes (detected problems)
50
+ export { IssueNode, type IssueNodeRecord, type IssueSeverity, type IssueType } from './IssueNode.js';
51
+
35
52
  // Node type constants and helpers
36
53
  export {
37
54
  NODE_TYPE,
@@ -0,0 +1,163 @@
1
+ /**
2
+ * DiagnosticCollector - Collects and filters diagnostics from plugin execution
3
+ *
4
+ * The DiagnosticCollector aggregates errors from PluginResult.errors[],
5
+ * converting both GrafemaError instances (with rich info) and plain Error
6
+ * instances (treated as generic errors) into unified Diagnostic entries.
7
+ *
8
+ * Usage:
9
+ * const collector = new DiagnosticCollector();
10
+ * collector.addFromPluginResult('INDEXING', 'JSModuleIndexer', result);
11
+ *
12
+ * if (collector.hasFatal()) {
13
+ * throw new Error('Fatal error detected');
14
+ * }
15
+ *
16
+ * console.log(collector.toDiagnosticsLog());
17
+ */
18
+
19
+ import type { PluginPhase, PluginResult } from '@grafema/types';
20
+ import { GrafemaError } from '../errors/GrafemaError.js';
21
+
22
+ /**
23
+ * Diagnostic entry - unified format for all errors/warnings
24
+ */
25
+ export interface Diagnostic {
26
+ code: string;
27
+ severity: 'fatal' | 'error' | 'warning' | 'info';
28
+ message: string;
29
+ file?: string;
30
+ line?: number;
31
+ phase: PluginPhase;
32
+ plugin: string;
33
+ timestamp: number;
34
+ suggestion?: string;
35
+ }
36
+
37
+ /**
38
+ * Diagnostic input (without timestamp, which is auto-generated)
39
+ */
40
+ export type DiagnosticInput = Omit<Diagnostic, 'timestamp'>;
41
+
42
+ /**
43
+ * DiagnosticCollector - collects, filters, and formats diagnostics
44
+ */
45
+ export class DiagnosticCollector {
46
+ private diagnostics: Diagnostic[] = [];
47
+
48
+ /**
49
+ * Extract errors from PluginResult and add as diagnostics.
50
+ *
51
+ * GrafemaError instances provide rich info (code, severity, context, suggestion).
52
+ * Plain Error instances are treated as generic errors with code 'ERR_UNKNOWN'.
53
+ */
54
+ addFromPluginResult(phase: PluginPhase, plugin: string, result: PluginResult): void {
55
+ for (const error of result.errors) {
56
+ if (error instanceof GrafemaError) {
57
+ this.add({
58
+ code: error.code,
59
+ severity: error.severity,
60
+ message: error.message,
61
+ file: error.context.filePath,
62
+ line: error.context.lineNumber,
63
+ phase,
64
+ plugin,
65
+ suggestion: error.suggestion,
66
+ });
67
+ } else {
68
+ // Plain Error - treat as generic error
69
+ this.add({
70
+ code: 'ERR_UNKNOWN',
71
+ severity: 'error',
72
+ message: error.message,
73
+ phase,
74
+ plugin,
75
+ });
76
+ }
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Add a diagnostic directly.
82
+ * Timestamp is set automatically.
83
+ */
84
+ add(diagnostic: DiagnosticInput): void {
85
+ this.diagnostics.push({
86
+ ...diagnostic,
87
+ timestamp: Date.now(),
88
+ });
89
+ }
90
+
91
+ /**
92
+ * Get all diagnostics.
93
+ * Returns a copy to prevent external modification.
94
+ */
95
+ getAll(): Diagnostic[] {
96
+ return [...this.diagnostics];
97
+ }
98
+
99
+ /**
100
+ * Get diagnostics filtered by phase.
101
+ */
102
+ getByPhase(phase: PluginPhase): Diagnostic[] {
103
+ return this.diagnostics.filter(d => d.phase === phase);
104
+ }
105
+
106
+ /**
107
+ * Get diagnostics filtered by plugin name (case-sensitive).
108
+ */
109
+ getByPlugin(plugin: string): Diagnostic[] {
110
+ return this.diagnostics.filter(d => d.plugin === plugin);
111
+ }
112
+
113
+ /**
114
+ * Get diagnostics filtered by error code.
115
+ */
116
+ getByCode(code: string): Diagnostic[] {
117
+ return this.diagnostics.filter(d => d.code === code);
118
+ }
119
+
120
+ /**
121
+ * Check if any fatal diagnostic exists.
122
+ * Fatal errors require immediate stop of analysis.
123
+ */
124
+ hasFatal(): boolean {
125
+ return this.diagnostics.some(d => d.severity === 'fatal');
126
+ }
127
+
128
+ /**
129
+ * Check if any error (including fatal) exists.
130
+ */
131
+ hasErrors(): boolean {
132
+ return this.diagnostics.some(d => d.severity === 'error' || d.severity === 'fatal');
133
+ }
134
+
135
+ /**
136
+ * Check if any warning exists.
137
+ */
138
+ hasWarnings(): boolean {
139
+ return this.diagnostics.some(d => d.severity === 'warning');
140
+ }
141
+
142
+ /**
143
+ * Get total count of diagnostics.
144
+ */
145
+ count(): number {
146
+ return this.diagnostics.length;
147
+ }
148
+
149
+ /**
150
+ * Format diagnostics as JSON lines (one JSON object per line).
151
+ * Suitable for .grafema/diagnostics.log file.
152
+ */
153
+ toDiagnosticsLog(): string {
154
+ return this.diagnostics.map(d => JSON.stringify(d)).join('\n');
155
+ }
156
+
157
+ /**
158
+ * Clear all diagnostics.
159
+ */
160
+ clear(): void {
161
+ this.diagnostics = [];
162
+ }
163
+ }
@@ -0,0 +1,204 @@
1
+ /**
2
+ * DiagnosticReporter - Formats diagnostics for output
3
+ *
4
+ * Supports multiple output formats:
5
+ * - text: Human-readable format with severity indicators
6
+ * - json: Machine-readable JSON format for CI integration
7
+ * - csv: Spreadsheet-compatible format
8
+ *
9
+ * Usage:
10
+ * const reporter = new DiagnosticReporter(collector);
11
+ * console.log(reporter.report({ format: 'text', includeSummary: true }));
12
+ * console.log(reporter.summary());
13
+ */
14
+
15
+ import type { Diagnostic, DiagnosticCollector } from './DiagnosticCollector.js';
16
+
17
+ /**
18
+ * Report output options
19
+ */
20
+ export interface ReportOptions {
21
+ format: 'text' | 'json' | 'csv';
22
+ includeSummary?: boolean;
23
+ includeTrace?: boolean;
24
+ }
25
+
26
+ /**
27
+ * Summary statistics
28
+ */
29
+ export interface SummaryStats {
30
+ total: number;
31
+ fatal: number;
32
+ errors: number;
33
+ warnings: number;
34
+ info: number;
35
+ }
36
+
37
+ /**
38
+ * DiagnosticReporter - formats diagnostics for different output formats
39
+ */
40
+ export class DiagnosticReporter {
41
+ constructor(private collector: DiagnosticCollector) {}
42
+
43
+ /**
44
+ * Generate a formatted report of all diagnostics.
45
+ */
46
+ report(options: ReportOptions): string {
47
+ const diagnostics = this.collector.getAll();
48
+
49
+ if (options.format === 'json') {
50
+ return this.jsonReport(diagnostics, options);
51
+ } else if (options.format === 'csv') {
52
+ return this.csvReport(diagnostics);
53
+ } else {
54
+ return this.textReport(diagnostics, options);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Generate a human-readable summary of diagnostic counts.
60
+ */
61
+ summary(): string {
62
+ const stats = this.getStats();
63
+
64
+ if (stats.total === 0) {
65
+ return 'No issues found.';
66
+ }
67
+
68
+ const parts: string[] = [];
69
+
70
+ if (stats.fatal > 0) {
71
+ parts.push(`Fatal: ${stats.fatal}`);
72
+ }
73
+ if (stats.errors > 0) {
74
+ parts.push(`Errors: ${stats.errors}`);
75
+ }
76
+ if (stats.warnings > 0) {
77
+ parts.push(`Warnings: ${stats.warnings}`);
78
+ }
79
+
80
+ return parts.join(', ');
81
+ }
82
+
83
+ /**
84
+ * Get diagnostic statistics by severity.
85
+ */
86
+ getStats(): SummaryStats {
87
+ const diagnostics = this.collector.getAll();
88
+ return {
89
+ total: diagnostics.length,
90
+ fatal: diagnostics.filter(d => d.severity === 'fatal').length,
91
+ errors: diagnostics.filter(d => d.severity === 'error').length,
92
+ warnings: diagnostics.filter(d => d.severity === 'warning').length,
93
+ info: diagnostics.filter(d => d.severity === 'info').length,
94
+ };
95
+ }
96
+
97
+ /**
98
+ * Generate human-readable text report.
99
+ */
100
+ private textReport(diagnostics: Diagnostic[], options: ReportOptions): string {
101
+ if (diagnostics.length === 0) {
102
+ return 'No issues found.';
103
+ }
104
+
105
+ const lines: string[] = [];
106
+
107
+ for (const diag of diagnostics) {
108
+ const icon = this.getSeverityIcon(diag.severity);
109
+ const location = this.formatLocation(diag);
110
+
111
+ lines.push(`${icon} ${diag.code} ${location} ${diag.message}`);
112
+
113
+ if (diag.suggestion) {
114
+ lines.push(` Suggestion: ${diag.suggestion}`);
115
+ }
116
+ }
117
+
118
+ if (options.includeSummary) {
119
+ lines.push('');
120
+ lines.push(this.summary());
121
+ }
122
+
123
+ return lines.join('\n');
124
+ }
125
+
126
+ /**
127
+ * Generate JSON report.
128
+ */
129
+ private jsonReport(diagnostics: Diagnostic[], options: ReportOptions): string {
130
+ const result: {
131
+ diagnostics: Diagnostic[];
132
+ summary?: SummaryStats;
133
+ } = {
134
+ diagnostics,
135
+ };
136
+
137
+ if (options.includeSummary) {
138
+ result.summary = this.getStats();
139
+ }
140
+
141
+ return JSON.stringify(result, null, 2);
142
+ }
143
+
144
+ /**
145
+ * Generate CSV report.
146
+ */
147
+ private csvReport(diagnostics: Diagnostic[]): string {
148
+ const header = 'severity,code,file,line,message,plugin,phase,suggestion';
149
+ const rows = diagnostics.map(d =>
150
+ [
151
+ d.severity,
152
+ d.code,
153
+ d.file || '',
154
+ d.line || '',
155
+ this.csvEscape(d.message),
156
+ d.plugin,
157
+ d.phase,
158
+ d.suggestion ? this.csvEscape(d.suggestion) : '',
159
+ ].join(',')
160
+ );
161
+ return [header, ...rows].join('\n');
162
+ }
163
+
164
+ /**
165
+ * Get severity indicator for text output.
166
+ */
167
+ private getSeverityIcon(severity: Diagnostic['severity']): string {
168
+ switch (severity) {
169
+ case 'fatal':
170
+ return '[FATAL]';
171
+ case 'error':
172
+ return '[ERROR]';
173
+ case 'warning':
174
+ return '[WARN]';
175
+ case 'info':
176
+ return '[INFO]';
177
+ default:
178
+ return '[?]';
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Format file location for display.
184
+ */
185
+ private formatLocation(diag: Diagnostic): string {
186
+ if (!diag.file) {
187
+ return '';
188
+ }
189
+ if (diag.line) {
190
+ return `(${diag.file}:${diag.line})`;
191
+ }
192
+ return `(${diag.file})`;
193
+ }
194
+
195
+ /**
196
+ * Escape a value for CSV output.
197
+ * Wraps in quotes and escapes internal quotes.
198
+ */
199
+ private csvEscape(value: string): string {
200
+ // Always quote to handle commas and special characters
201
+ const escaped = value.replace(/"/g, '""');
202
+ return `"${escaped}"`;
203
+ }
204
+ }