@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,86 @@
1
+ /**
2
+ * EnumNode - contract for ENUM node
3
+ *
4
+ * Represents TypeScript enum declarations.
5
+ *
6
+ * ID format: {file}:ENUM:{name}:{line}
7
+ * Example: /src/types.ts:ENUM:Status:20
8
+ */
9
+
10
+ import type { BaseNodeRecord } from '@grafema/types';
11
+
12
+ interface EnumMemberRecord {
13
+ name: string;
14
+ value?: string | number;
15
+ }
16
+
17
+ interface EnumNodeRecord extends BaseNodeRecord {
18
+ type: 'ENUM';
19
+ column: number;
20
+ isConst: boolean;
21
+ members: EnumMemberRecord[];
22
+ }
23
+
24
+ interface EnumNodeOptions {
25
+ isConst?: boolean;
26
+ members?: EnumMemberRecord[];
27
+ }
28
+
29
+ export class EnumNode {
30
+ static readonly TYPE = 'ENUM' as const;
31
+
32
+ static readonly REQUIRED = ['name', 'file', 'line'] as const;
33
+ static readonly OPTIONAL = ['column', 'isConst', 'members'] as const;
34
+
35
+ /**
36
+ * Create ENUM node
37
+ *
38
+ * @param name - Enum name
39
+ * @param file - File path
40
+ * @param line - Line number
41
+ * @param column - Column position
42
+ * @param options - Optional enum properties
43
+ * @returns EnumNodeRecord
44
+ */
45
+ static create(
46
+ name: string,
47
+ file: string,
48
+ line: number,
49
+ column: number,
50
+ options: EnumNodeOptions = {}
51
+ ): EnumNodeRecord {
52
+ if (!name) throw new Error('EnumNode.create: name is required');
53
+ if (!file) throw new Error('EnumNode.create: file is required');
54
+ if (!line) throw new Error('EnumNode.create: line is required');
55
+
56
+ return {
57
+ id: `${file}:ENUM:${name}:${line}`,
58
+ type: this.TYPE,
59
+ name,
60
+ file,
61
+ line,
62
+ column: column || 0,
63
+ isConst: options.isConst || false,
64
+ members: options.members || []
65
+ };
66
+ }
67
+
68
+ static validate(node: EnumNodeRecord): string[] {
69
+ const errors: string[] = [];
70
+
71
+ if (node.type !== this.TYPE) {
72
+ errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
73
+ }
74
+
75
+ const nodeRecord = node as unknown as Record<string, unknown>;
76
+ for (const field of this.REQUIRED) {
77
+ if (!nodeRecord[field]) {
78
+ errors.push(`Missing required field: ${field}`);
79
+ }
80
+ }
81
+
82
+ return errors;
83
+ }
84
+ }
85
+
86
+ export type { EnumNodeRecord, EnumMemberRecord };
@@ -1,30 +1,55 @@
1
1
  /**
2
2
  * ExportNode - contract for EXPORT 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}->global->EXPORT->{exportedName}
9
+ * Example: src/utils.js->global->EXPORT->formatDate
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
  type ExportKind = 'value' | 'type';
8
16
 
17
+ type ExportType = 'default' | 'named' | 'all';
18
+
9
19
  interface ExportNodeRecord extends BaseNodeRecord {
10
20
  type: 'EXPORT';
11
21
  column: number;
12
22
  exportKind: ExportKind;
13
23
  local: string;
14
24
  default: boolean;
25
+ source?: string;
26
+ exportType?: ExportType;
15
27
  }
16
28
 
17
29
  interface ExportNodeOptions {
18
30
  exportKind?: ExportKind;
19
31
  local?: string;
20
32
  default?: boolean;
33
+ source?: string;
34
+ exportType?: ExportType;
35
+ }
36
+
37
+ /**
38
+ * Options for createWithContext
39
+ */
40
+ interface ExportContextOptions {
41
+ exportKind?: ExportKind;
42
+ local?: string;
43
+ default?: boolean;
44
+ source?: string;
45
+ exportType?: ExportType;
21
46
  }
22
47
 
23
48
  export class ExportNode {
24
49
  static readonly TYPE = 'EXPORT' as const;
25
50
 
26
51
  static readonly REQUIRED = ['name', 'file', 'line'] as const;
27
- static readonly OPTIONAL = ['column', 'exportKind', 'local', 'default'] as const;
52
+ static readonly OPTIONAL = ['column', 'exportKind', 'local', 'default', 'source', 'exportType'] as const;
28
53
 
29
54
  static create(
30
55
  name: string,
@@ -46,7 +71,50 @@ export class ExportNode {
46
71
  column: column || 0,
47
72
  exportKind: options.exportKind || 'value',
48
73
  local: options.local || name,
49
- default: options.default || false
74
+ default: options.default || false,
75
+ ...(options.source !== undefined && { source: options.source }),
76
+ ...(options.exportType !== undefined && { exportType: options.exportType })
77
+ };
78
+ }
79
+
80
+ /**
81
+ * Create EXPORT node with semantic ID (NEW API)
82
+ *
83
+ * Uses ScopeContext from ScopeTracker for stable identifiers.
84
+ * Export names are unique within module, so no discriminator needed.
85
+ *
86
+ * @param name - Exported name (as visible to importers)
87
+ * @param context - Scope context from ScopeTracker.getContext()
88
+ * @param location - Source location { line, column }
89
+ * @param options - Optional export properties
90
+ * @returns ExportNodeRecord with semantic ID
91
+ */
92
+ static createWithContext(
93
+ name: string,
94
+ context: ScopeContext,
95
+ location: Partial<Location>,
96
+ options: ExportContextOptions = {}
97
+ ): ExportNodeRecord {
98
+ // Validate required fields
99
+ if (!name) throw new Error('ExportNode.createWithContext: name is required');
100
+ if (!context.file) throw new Error('ExportNode.createWithContext: file is required');
101
+ if (location.line === undefined) throw new Error('ExportNode.createWithContext: line is required');
102
+
103
+ // Compute semantic ID
104
+ const id = computeSemanticId(this.TYPE, name, context);
105
+
106
+ return {
107
+ id,
108
+ type: this.TYPE,
109
+ name,
110
+ file: context.file,
111
+ line: location.line,
112
+ column: location.column ?? 0,
113
+ exportKind: options.exportKind || 'value',
114
+ local: options.local || name,
115
+ default: options.default || false,
116
+ ...(options.source !== undefined && { source: options.source }),
117
+ ...(options.exportType !== undefined && { exportType: options.exportType })
50
118
  };
51
119
  }
52
120
 
@@ -0,0 +1,231 @@
1
+ /**
2
+ * ExpressionNode - contract for EXPRESSION node
3
+ *
4
+ * Represents complex expressions for data flow tracking
5
+ * (MemberExpression, BinaryExpression, LogicalExpression, etc.)
6
+ *
7
+ * ID format: {file}:EXPRESSION:{expressionType}:{line}:{column}
8
+ * Example: /src/app.ts:EXPRESSION:MemberExpression:25:10
9
+ */
10
+
11
+ import type { BaseNodeRecord } from '@grafema/types';
12
+
13
+ interface ExpressionNodeRecord extends BaseNodeRecord {
14
+ type: 'EXPRESSION';
15
+ column: number;
16
+ expressionType: string;
17
+ // MemberExpression fields
18
+ object?: string;
19
+ property?: string;
20
+ computed?: boolean;
21
+ computedPropertyVar?: string;
22
+ // Binary/Logical expression fields
23
+ operator?: string;
24
+ // Tracking fields
25
+ path?: string;
26
+ baseName?: string;
27
+ propertyPath?: string[];
28
+ arrayIndex?: number;
29
+ }
30
+
31
+ interface ExpressionNodeOptions {
32
+ // MemberExpression
33
+ object?: string;
34
+ property?: string;
35
+ computed?: boolean;
36
+ computedPropertyVar?: string;
37
+ // Binary/Logical
38
+ operator?: string;
39
+ // Tracking
40
+ path?: string;
41
+ baseName?: string;
42
+ propertyPath?: string[];
43
+ arrayIndex?: number;
44
+ }
45
+
46
+ export class ExpressionNode {
47
+ static readonly TYPE = 'EXPRESSION' as const;
48
+
49
+ static readonly REQUIRED = ['expressionType', 'file', 'line'] as const;
50
+ static readonly OPTIONAL = [
51
+ 'column', 'object', 'property', 'computed', 'computedPropertyVar',
52
+ 'operator', 'path', 'baseName', 'propertyPath', 'arrayIndex'
53
+ ] as const;
54
+
55
+ /**
56
+ * Create EXPRESSION node
57
+ *
58
+ * @param expressionType - Type of expression (MemberExpression, BinaryExpression, etc.)
59
+ * @param file - File path
60
+ * @param line - Line number
61
+ * @param column - Column position
62
+ * @param options - Optional expression properties
63
+ * @returns ExpressionNodeRecord
64
+ */
65
+ static create(
66
+ expressionType: string,
67
+ file: string,
68
+ line: number,
69
+ column: number,
70
+ options: ExpressionNodeOptions = {}
71
+ ): ExpressionNodeRecord {
72
+ if (!expressionType) throw new Error('ExpressionNode.create: expressionType is required');
73
+ if (!file) throw new Error('ExpressionNode.create: file is required');
74
+ if (!line) throw new Error('ExpressionNode.create: line is required');
75
+
76
+ const node: ExpressionNodeRecord = {
77
+ id: `${file}:EXPRESSION:${expressionType}:${line}:${column}`,
78
+ type: this.TYPE,
79
+ name: this._computeName(expressionType, options),
80
+ file,
81
+ line,
82
+ column: column || 0,
83
+ expressionType
84
+ };
85
+
86
+ // Add optional fields if present
87
+ if (options.object !== undefined) node.object = options.object;
88
+ if (options.property !== undefined) node.property = options.property;
89
+ if (options.computed !== undefined) node.computed = options.computed;
90
+ if (options.computedPropertyVar !== undefined) node.computedPropertyVar = options.computedPropertyVar;
91
+ if (options.operator !== undefined) node.operator = options.operator;
92
+ if (options.path !== undefined) node.path = options.path;
93
+ if (options.baseName !== undefined) node.baseName = options.baseName;
94
+ if (options.propertyPath !== undefined) node.propertyPath = options.propertyPath;
95
+ if (options.arrayIndex !== undefined) node.arrayIndex = options.arrayIndex;
96
+
97
+ return node;
98
+ }
99
+
100
+ /**
101
+ * Compute name from expression properties
102
+ *
103
+ * Naming conventions:
104
+ * - MemberExpression: "object.property"
105
+ * - BinaryExpression: "<BinaryExpression>"
106
+ * - LogicalExpression: "<LogicalExpression>"
107
+ * - ConditionalExpression: "<ternary>"
108
+ * - TemplateLiteral: "<template>"
109
+ * - Other: expressionType
110
+ */
111
+ private static _computeName(expressionType: string, options: ExpressionNodeOptions): string {
112
+ if (options.path) {
113
+ return options.path;
114
+ }
115
+ if (options.object && options.property) {
116
+ return `${options.object}.${options.property}`;
117
+ }
118
+ // Special naming for non-MemberExpression types
119
+ switch (expressionType) {
120
+ case 'BinaryExpression':
121
+ case 'LogicalExpression':
122
+ return `<${expressionType}>`;
123
+ case 'ConditionalExpression':
124
+ return '<ternary>';
125
+ case 'TemplateLiteral':
126
+ return '<template>';
127
+ default:
128
+ return expressionType;
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Generate EXPRESSION node ID without creating the full node
134
+ *
135
+ * Used by JSASTAnalyzer when creating assignment metadata.
136
+ * The full node is created later by GraphBuilder.
137
+ *
138
+ * ID format: {file}:EXPRESSION:{expressionType}:{line}:{column}
139
+ *
140
+ * @param expressionType - Type of expression (MemberExpression, BinaryExpression, etc.)
141
+ * @param file - File path
142
+ * @param line - Line number
143
+ * @param column - Column position
144
+ * @returns Generated ID string in colon format
145
+ */
146
+ static generateId(
147
+ expressionType: string,
148
+ file: string,
149
+ line: number,
150
+ column: number
151
+ ): string {
152
+ return `${file}:EXPRESSION:${expressionType}:${line}:${column}`;
153
+ }
154
+
155
+ /**
156
+ * Create EXPRESSION node from assignment metadata
157
+ *
158
+ * Used by GraphBuilder when processing variableAssignments.
159
+ * The ID is provided from upstream (generated by JSASTAnalyzer).
160
+ *
161
+ * @param expressionType - Type of expression
162
+ * @param file - File path
163
+ * @param line - Line number
164
+ * @param column - Column position
165
+ * @param options - Must include id; optional: expression properties
166
+ * @returns ExpressionNodeRecord
167
+ */
168
+ static createFromMetadata(
169
+ expressionType: string,
170
+ file: string,
171
+ line: number,
172
+ column: number,
173
+ options: ExpressionNodeOptions & { id: string }
174
+ ): ExpressionNodeRecord {
175
+ if (!options.id) {
176
+ throw new Error('ExpressionNode.createFromMetadata: id is required');
177
+ }
178
+
179
+ // Validate ID format - must use colon format
180
+ if (!options.id.includes(':EXPRESSION:')) {
181
+ throw new Error(
182
+ `ExpressionNode.createFromMetadata: Invalid ID format "${options.id}". ` +
183
+ `Expected format: {file}:EXPRESSION:{type}:{line}:{column}`
184
+ );
185
+ }
186
+
187
+ // Create base node structure
188
+ const node: ExpressionNodeRecord = {
189
+ id: options.id, // Use provided ID (from upstream)
190
+ type: this.TYPE,
191
+ name: this._computeName(expressionType, options),
192
+ file,
193
+ line,
194
+ column: column || 0,
195
+ expressionType
196
+ };
197
+
198
+ // Add optional fields if present (same logic as create())
199
+ if (options.object !== undefined) node.object = options.object;
200
+ if (options.property !== undefined) node.property = options.property;
201
+ if (options.computed !== undefined) node.computed = options.computed;
202
+ if (options.computedPropertyVar !== undefined) node.computedPropertyVar = options.computedPropertyVar;
203
+ if (options.operator !== undefined) node.operator = options.operator;
204
+ if (options.path !== undefined) node.path = options.path;
205
+ if (options.baseName !== undefined) node.baseName = options.baseName;
206
+ if (options.propertyPath !== undefined) node.propertyPath = options.propertyPath;
207
+ if (options.arrayIndex !== undefined) node.arrayIndex = options.arrayIndex;
208
+
209
+ return node;
210
+ }
211
+
212
+ static validate(node: ExpressionNodeRecord): string[] {
213
+ const errors: string[] = [];
214
+
215
+ if (node.type !== this.TYPE) {
216
+ errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
217
+ }
218
+
219
+ if (!node.expressionType) {
220
+ errors.push('Missing required field: expressionType');
221
+ }
222
+
223
+ if (!node.file) {
224
+ errors.push('Missing required field: file');
225
+ }
226
+
227
+ return errors;
228
+ }
229
+ }
230
+
231
+ export type { ExpressionNodeRecord, ExpressionNodeOptions };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * ExternalModuleNode - contract for EXTERNAL_MODULE node
3
+ *
4
+ * Represents external npm packages or Node.js built-in modules
5
+ * that are imported but not analyzed.
6
+ *
7
+ * ID format: EXTERNAL_MODULE:{source}
8
+ * Example: EXTERNAL_MODULE:lodash, EXTERNAL_MODULE:@tanstack/react-query
9
+ */
10
+
11
+ import type { BaseNodeRecord } from '@grafema/types';
12
+
13
+ interface ExternalModuleNodeRecord extends BaseNodeRecord {
14
+ type: 'EXTERNAL_MODULE';
15
+ }
16
+
17
+ export class ExternalModuleNode {
18
+ static readonly TYPE = 'EXTERNAL_MODULE' as const;
19
+
20
+ static readonly REQUIRED = ['name'] as const;
21
+ static readonly OPTIONAL = [] as const;
22
+
23
+ /**
24
+ * Create EXTERNAL_MODULE node
25
+ *
26
+ * @param source - Module name (e.g., 'lodash', '@tanstack/react-query', 'node:fs')
27
+ * @returns ExternalModuleNodeRecord
28
+ */
29
+ static create(source: string): ExternalModuleNodeRecord {
30
+ if (!source) throw new Error('ExternalModuleNode.create: source is required');
31
+
32
+ return {
33
+ id: `EXTERNAL_MODULE:${source}`,
34
+ type: this.TYPE,
35
+ name: source,
36
+ file: '',
37
+ line: 0
38
+ };
39
+ }
40
+
41
+ static validate(node: ExternalModuleNodeRecord): string[] {
42
+ const errors: string[] = [];
43
+
44
+ if (node.type !== this.TYPE) {
45
+ errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
46
+ }
47
+
48
+ if (!node.name) {
49
+ errors.push('Missing required field: name');
50
+ }
51
+
52
+ return errors;
53
+ }
54
+ }
55
+
56
+ export type { ExternalModuleNodeRecord };
@@ -1,19 +1,26 @@
1
1
  /**
2
- * ExternalStdioNode - contract for EXTERNAL_STDIO node (singleton)
2
+ * ExternalStdioNode - contract for net:stdio node (singleton)
3
+ *
4
+ * Represents standard I/O streams (console.log, console.error, etc.)
5
+ * Singleton node - only one instance per graph.
6
+ *
7
+ * Uses namespaced type 'net:stdio' for semantic grouping - AI agents
8
+ * can query all I/O-related nodes via 'net:*' pattern.
3
9
  */
4
10
 
5
11
  import type { BaseNodeRecord } from '@grafema/types';
6
12
 
7
13
  interface ExternalStdioNodeRecord extends BaseNodeRecord {
8
- type: 'EXTERNAL_STDIO';
14
+ type: 'net:stdio';
15
+ description?: string;
9
16
  }
10
17
 
11
18
  export class ExternalStdioNode {
12
- static readonly TYPE = 'EXTERNAL_STDIO' as const;
13
- static readonly SINGLETON_ID = 'EXTERNAL_STDIO:__stdio__';
19
+ static readonly TYPE = 'net:stdio' as const;
20
+ static readonly SINGLETON_ID = 'net:stdio#__stdio__';
14
21
 
15
- static readonly REQUIRED = ['name', 'file'] as const;
16
- static readonly OPTIONAL = [] as const;
22
+ static readonly REQUIRED = ['name'] as const;
23
+ static readonly OPTIONAL = ['description'] as const;
17
24
 
18
25
  static create(): ExternalStdioNodeRecord {
19
26
  return {
@@ -21,14 +28,15 @@ export class ExternalStdioNode {
21
28
  type: this.TYPE,
22
29
  name: '__stdio__',
23
30
  file: '__builtin__',
24
- line: 0
31
+ line: 0,
32
+ description: 'Standard input/output stream'
25
33
  };
26
34
  }
27
35
 
28
36
  static validate(node: ExternalStdioNodeRecord): string[] {
29
37
  const errors: string[] = [];
30
- if (node.type !== this.TYPE) errors.push(`Expected type ${this.TYPE}`);
31
- if (node.id !== this.SINGLETON_ID) errors.push(`Invalid singleton ID`);
38
+ if (node.type !== this.TYPE) errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
39
+ if (node.id !== this.SINGLETON_ID) errors.push(`Invalid singleton ID: ${node.id}, expected ${this.SINGLETON_ID}`);
32
40
  return errors;
33
41
  }
34
42
  }
@@ -1,9 +1,20 @@
1
1
  /**
2
2
  * FunctionNode - contract for FUNCTION 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}->FUNCTION->{name}
9
+ * Example: src/app.js->global->FUNCTION->processData
3
10
  */
4
11
 
5
12
  import type { FunctionNodeRecord } from '@grafema/types';
13
+ import { computeSemanticId, type ScopeContext, type Location } from '../SemanticId.js';
6
14
 
15
+ /**
16
+ * Options for function node creation
17
+ */
7
18
  interface FunctionNodeOptions {
8
19
  async?: boolean;
9
20
  generator?: boolean;
@@ -16,6 +27,19 @@ interface FunctionNodeOptions {
16
27
  counter?: number;
17
28
  }
18
29
 
30
+ /**
31
+ * Options specific to createWithContext
32
+ */
33
+ interface FunctionNodeContextOptions {
34
+ async?: boolean;
35
+ generator?: boolean;
36
+ exported?: boolean;
37
+ arrowFunction?: boolean;
38
+ isClassMethod?: boolean;
39
+ className?: string;
40
+ params?: string[];
41
+ }
42
+
19
43
  export class FunctionNode {
20
44
  static readonly TYPE = 'FUNCTION' as const;
21
45
 
@@ -42,7 +66,6 @@ export class FunctionNode {
42
66
 
43
67
  return {
44
68
  id,
45
- stableId: id,
46
69
  type: this.TYPE,
47
70
  name,
48
71
  file,
@@ -59,6 +82,83 @@ export class FunctionNode {
59
82
  };
60
83
  }
61
84
 
85
+ /**
86
+ * Create FUNCTION node with semantic ID (NEW API)
87
+ *
88
+ * Uses ScopeContext from ScopeTracker for stable identifiers that
89
+ * don't change when unrelated code is added/removed.
90
+ *
91
+ * @param name - Function name (or 'anonymous[N]' for anonymous functions)
92
+ * @param context - Scope context from ScopeTracker.getContext()
93
+ * @param location - Source location { line, column }
94
+ * @param options - Optional function properties
95
+ * @returns FunctionNodeRecord with semantic ID
96
+ */
97
+ static createWithContext(
98
+ name: string,
99
+ context: ScopeContext,
100
+ location: Partial<Location>,
101
+ options: FunctionNodeContextOptions = {}
102
+ ): FunctionNodeRecord {
103
+ // Validate required fields
104
+ if (!name) throw new Error('FunctionNode.createWithContext: name is required');
105
+ if (!context.file) throw new Error('FunctionNode.createWithContext: file is required');
106
+ if (location.line === undefined) throw new Error('FunctionNode.createWithContext: line is required');
107
+ if (location.column === undefined) throw new Error('FunctionNode.createWithContext: column is required');
108
+
109
+ // Compute semantic ID
110
+ const id = computeSemanticId(this.TYPE, name, context);
111
+
112
+ // Compute parentScopeId from context
113
+ // If we have a scope path, the parent is the last scope in the path
114
+ let parentScopeId: string | undefined;
115
+ if (context.scopePath.length > 0) {
116
+ // Find the most recent function/method scope to use as parent
117
+ // For now, we construct the parent's semantic ID from the scope path
118
+ const parentContext = {
119
+ file: context.file,
120
+ scopePath: context.scopePath.slice(0, -1) // Remove last scope
121
+ };
122
+ const parentScopeName = context.scopePath[context.scopePath.length - 1];
123
+
124
+ // Check if parent is a function/method scope (not a control flow scope)
125
+ if (!parentScopeName.includes('#')) {
126
+ // Named scope - likely a function or class
127
+ parentScopeId = computeSemanticId('FUNCTION', parentScopeName, parentContext);
128
+ } else {
129
+ // Control flow scope - find the nearest function ancestor
130
+ // For simplicity, take the first non-control-flow scope from the path
131
+ const nonControlFlowScopes = context.scopePath.filter(s => !s.includes('#'));
132
+ if (nonControlFlowScopes.length > 0) {
133
+ const parentName = nonControlFlowScopes[nonControlFlowScopes.length - 1];
134
+ const idx = context.scopePath.indexOf(parentName);
135
+ const ancestorContext = {
136
+ file: context.file,
137
+ scopePath: context.scopePath.slice(0, idx)
138
+ };
139
+ parentScopeId = computeSemanticId('FUNCTION', parentName, ancestorContext);
140
+ }
141
+ }
142
+ }
143
+
144
+ return {
145
+ id,
146
+ type: this.TYPE,
147
+ name,
148
+ file: context.file,
149
+ line: location.line,
150
+ column: location.column,
151
+ async: options.async || false,
152
+ generator: options.generator || false,
153
+ exported: options.exported || false,
154
+ arrowFunction: options.arrowFunction || false,
155
+ parentScopeId,
156
+ isClassMethod: options.isClassMethod || false,
157
+ className: options.className,
158
+ params: options.params || []
159
+ };
160
+ }
161
+
62
162
  static validate(node: FunctionNodeRecord): string[] {
63
163
  const errors: string[] = [];
64
164