code-auditor-mcp 2.6.2 → 3.0.1

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 (344) hide show
  1. package/README.md +23 -196
  2. package/dist/analyzers/analyzerUtils.d.ts +13 -11
  3. package/dist/analyzers/analyzerUtils.d.ts.map +1 -1
  4. package/dist/analyzers/analyzerUtils.js +22 -56
  5. package/dist/analyzers/analyzerUtils.js.map +1 -1
  6. package/dist/analyzers/cross-language/APIContractAnalyzer.d.ts.map +1 -1
  7. package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.d.ts.map +1 -1
  8. package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.js.map +1 -1
  9. package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -1
  10. package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -1
  11. package/dist/analyzers/cross-language/SchemaValidator.d.ts.map +1 -1
  12. package/dist/analyzers/cross-language/SchemaValidator.js.map +1 -1
  13. package/dist/analyzers/dataAccessAnalyzer.d.ts.map +1 -1
  14. package/dist/analyzers/dataAccessAnalyzer.js +50 -24
  15. package/dist/analyzers/dataAccessAnalyzer.js.map +1 -1
  16. package/dist/analyzers/documentationAnalyzer.d.ts +4 -1
  17. package/dist/analyzers/documentationAnalyzer.d.ts.map +1 -1
  18. package/dist/analyzers/documentationAnalyzer.js +210 -111
  19. package/dist/analyzers/documentationAnalyzer.js.map +1 -1
  20. package/dist/analyzers/dryAnalyzer.d.ts.map +1 -1
  21. package/dist/analyzers/dryAnalyzer.js +190 -58
  22. package/dist/analyzers/dryAnalyzer.js.map +1 -1
  23. package/dist/analyzers/invariantsAnalyzer.d.ts +20 -0
  24. package/dist/analyzers/invariantsAnalyzer.d.ts.map +1 -0
  25. package/dist/analyzers/invariantsAnalyzer.js +148 -0
  26. package/dist/analyzers/invariantsAnalyzer.js.map +1 -0
  27. package/dist/analyzers/reactAnalyzer.d.ts.map +1 -1
  28. package/dist/analyzers/reactAnalyzer.js +2 -2
  29. package/dist/analyzers/reactAnalyzer.js.map +1 -1
  30. package/dist/analyzers/schemaAnalyzer.d.ts +2 -0
  31. package/dist/analyzers/schemaAnalyzer.d.ts.map +1 -1
  32. package/dist/analyzers/schemaAnalyzer.js +306 -147
  33. package/dist/analyzers/schemaAnalyzer.js.map +1 -1
  34. package/dist/analyzers/solidAnalyzer.d.ts.map +1 -1
  35. package/dist/analyzers/solidAnalyzer.js +145 -119
  36. package/dist/analyzers/solidAnalyzer.js.map +1 -1
  37. package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts +3 -1
  38. package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -1
  39. package/dist/analyzers/universal/UniversalDRYAnalyzer.js +41 -1
  40. package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -1
  41. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
  42. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +8 -8
  43. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
  44. package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -1
  45. package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +6 -6
  46. package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -1
  47. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -1
  48. package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -1
  49. package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +1 -1
  50. package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -1
  51. package/dist/api/index.js +1 -0
  52. package/dist/api/index.js.map +1 -1
  53. package/dist/auditRunner.d.ts.map +1 -1
  54. package/dist/auditRunner.js +367 -24
  55. package/dist/auditRunner.js.map +1 -1
  56. package/dist/cli.d.ts +1 -1
  57. package/dist/cli.d.ts.map +1 -1
  58. package/dist/cli.js +740 -18
  59. package/dist/cli.js.map +1 -1
  60. package/dist/codeIndexDB-enhanced.d.ts +35 -13
  61. package/dist/codeIndexDB-enhanced.d.ts.map +1 -1
  62. package/dist/codeIndexDB-enhanced.js +311 -214
  63. package/dist/codeIndexDB-enhanced.js.map +1 -1
  64. package/dist/{codeIndexDb.d.ts → codeIndexDB.d.ts} +51 -224
  65. package/dist/codeIndexDB.d.ts.map +1 -0
  66. package/dist/codeIndexDB.js +2042 -0
  67. package/dist/codeIndexDB.js.map +1 -0
  68. package/dist/codeIndexService.d.ts.map +1 -1
  69. package/dist/codeIndexService.js.map +1 -1
  70. package/dist/componentScanner.d.ts +14 -8
  71. package/dist/componentScanner.d.ts.map +1 -1
  72. package/dist/componentScanner.js +136 -113
  73. package/dist/componentScanner.js.map +1 -1
  74. package/dist/config/configLoader.d.ts.map +1 -1
  75. package/dist/config/configLoader.js +10 -7
  76. package/dist/config/configLoader.js.map +1 -1
  77. package/dist/config/defaults.d.ts.map +1 -1
  78. package/dist/constants.js.map +1 -1
  79. package/dist/fingerprint.d.ts +15 -0
  80. package/dist/fingerprint.d.ts.map +1 -0
  81. package/dist/fingerprint.js +32 -0
  82. package/dist/fingerprint.js.map +1 -0
  83. package/dist/functionScanner.d.ts +5 -0
  84. package/dist/functionScanner.d.ts.map +1 -1
  85. package/dist/functionScanner.js +417 -341
  86. package/dist/functionScanner.js.map +1 -1
  87. package/dist/generators/AWSQConfigGenerator.d.ts.map +1 -1
  88. package/dist/generators/AiderConfigGenerator.d.ts.map +1 -1
  89. package/dist/generators/BaseConfigGenerator.d.ts.map +1 -1
  90. package/dist/generators/BaseConfigGenerator.js.map +1 -1
  91. package/dist/generators/ClaudeConfigGenerator.d.ts.map +1 -1
  92. package/dist/generators/ClineConfigGenerator.d.ts.map +1 -1
  93. package/dist/generators/CodeiumConfigGenerator.d.ts.map +1 -1
  94. package/dist/generators/ConfigGeneratorFactory.d.ts.map +1 -1
  95. package/dist/generators/ConfigGeneratorFactory.js.map +1 -1
  96. package/dist/generators/ContinueConfigGenerator.d.ts.map +1 -1
  97. package/dist/generators/CopilotConfigGenerator.d.ts.map +1 -1
  98. package/dist/generators/CursorConfigGenerator.d.ts.map +1 -1
  99. package/dist/generators/JetBrainsConfigGenerator.d.ts.map +1 -1
  100. package/dist/generators/VSCodeConfigGenerator.d.ts.map +1 -1
  101. package/dist/grammars/tree-sitter-go.wasm +0 -0
  102. package/dist/grammars/tree-sitter-javascript.wasm +0 -0
  103. package/dist/grammars/tree-sitter-tsx.wasm +0 -0
  104. package/dist/grammars/tree-sitter-typescript.wasm +0 -0
  105. package/dist/index.d.ts +1 -0
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +2 -1
  108. package/dist/index.js.map +1 -1
  109. package/dist/invariants/index.d.ts +9 -0
  110. package/dist/invariants/index.d.ts.map +1 -0
  111. package/dist/invariants/index.js +4 -0
  112. package/dist/invariants/index.js.map +1 -0
  113. package/dist/invariants/invariant-rules.schema.json +137 -0
  114. package/dist/invariants/ruleEngine.d.ts +32 -0
  115. package/dist/invariants/ruleEngine.d.ts.map +1 -0
  116. package/dist/invariants/ruleEngine.js +536 -0
  117. package/dist/invariants/ruleEngine.js.map +1 -0
  118. package/dist/invariants/ruleValidator.d.ts +17 -0
  119. package/dist/invariants/ruleValidator.d.ts.map +1 -0
  120. package/dist/invariants/ruleValidator.js +264 -0
  121. package/dist/invariants/ruleValidator.js.map +1 -0
  122. package/dist/invariants/types.d.ts +78 -0
  123. package/dist/invariants/types.d.ts.map +1 -0
  124. package/dist/invariants/types.js +5 -0
  125. package/dist/invariants/types.js.map +1 -0
  126. package/dist/languages/LanguageOrchestrator.d.ts.map +1 -1
  127. package/dist/languages/LanguageOrchestrator.js.map +1 -1
  128. package/dist/languages/LanguageRegistry.d.ts.map +1 -1
  129. package/dist/languages/RuntimeManager.d.ts.map +1 -1
  130. package/dist/languages/RuntimeManager.js +1 -1
  131. package/dist/languages/RuntimeManager.js.map +1 -1
  132. package/dist/languages/UniversalAnalyzer.d.ts.map +1 -1
  133. package/dist/languages/UniversalAnalyzer.js.map +1 -1
  134. package/dist/languages/adapterBridge.d.ts +102 -0
  135. package/dist/languages/adapterBridge.d.ts.map +1 -0
  136. package/dist/languages/adapterBridge.js +382 -0
  137. package/dist/languages/adapterBridge.js.map +1 -0
  138. package/dist/languages/go/GoAdapter.d.ts +37 -26
  139. package/dist/languages/go/GoAdapter.d.ts.map +1 -1
  140. package/dist/languages/go/GoAdapter.js +560 -281
  141. package/dist/languages/go/GoAdapter.js.map +1 -1
  142. package/dist/languages/index.d.ts +5 -2
  143. package/dist/languages/index.d.ts.map +1 -1
  144. package/dist/languages/index.js +11 -9
  145. package/dist/languages/index.js.map +1 -1
  146. package/dist/languages/tree-sitter/converter.d.ts +43 -0
  147. package/dist/languages/tree-sitter/converter.d.ts.map +1 -0
  148. package/dist/languages/tree-sitter/converter.js +150 -0
  149. package/dist/languages/tree-sitter/converter.js.map +1 -0
  150. package/dist/languages/tree-sitter/parser.d.ts +36 -0
  151. package/dist/languages/tree-sitter/parser.d.ts.map +1 -0
  152. package/dist/languages/tree-sitter/parser.js +114 -0
  153. package/dist/languages/tree-sitter/parser.js.map +1 -0
  154. package/dist/languages/types.d.ts +11 -0
  155. package/dist/languages/types.d.ts.map +1 -1
  156. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts +92 -0
  157. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -0
  158. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +951 -0
  159. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -0
  160. package/dist/mcp-tools/projectTasks.d.ts +58 -22
  161. package/dist/mcp-tools/projectTasks.d.ts.map +1 -1
  162. package/dist/mcp-tools/projectTasks.js +172 -10
  163. package/dist/mcp-tools/projectTasks.js.map +1 -1
  164. package/dist/mcp-tools/whitelistTools.d.ts +21 -21
  165. package/dist/mcp-tools/whitelistTools.d.ts.map +1 -1
  166. package/dist/mcp-tools/workflowGuide.d.ts.map +1 -1
  167. package/dist/mcp-tools/workflowGuide.js +130 -126
  168. package/dist/mcp-tools/workflowGuide.js.map +1 -1
  169. package/dist/mcp-tools-shared.d.ts.map +1 -1
  170. package/dist/mcp-tools-shared.js.map +1 -1
  171. package/dist/mcp-ui-simple.js +1 -1
  172. package/dist/mcp-ui-simple.js.map +1 -1
  173. package/dist/mcp.d.ts +1 -1
  174. package/dist/mcp.d.ts.map +1 -1
  175. package/dist/mcp.js +1376 -1181
  176. package/dist/mcp.js.map +1 -1
  177. package/dist/mcpAuditJobs.d.ts +4 -0
  178. package/dist/mcpAuditJobs.d.ts.map +1 -1
  179. package/dist/mcpAuditJobs.js +49 -2
  180. package/dist/mcpAuditJobs.js.map +1 -1
  181. package/dist/mcpToolErrors.d.ts.map +1 -1
  182. package/dist/mcpToolErrors.js.map +1 -1
  183. package/dist/native/ast-grep-napi.darwin-arm64.node +0 -0
  184. package/dist/native/ast-grep-napi.darwin-x64.node +0 -0
  185. package/dist/native/ast-grep-napi.linux-arm64-gnu.node +0 -0
  186. package/dist/native/ast-grep-napi.linux-arm64-musl.node +0 -0
  187. package/dist/native/ast-grep-napi.linux-x64-gnu.node +0 -0
  188. package/dist/native/ast-grep-napi.linux-x64-musl.node +0 -0
  189. package/dist/native/ast-grep-napi.win32-x64-msvc.node +0 -0
  190. package/dist/native-bootstrap.d.ts +15 -0
  191. package/dist/native-bootstrap.d.ts.map +1 -0
  192. package/dist/native-bootstrap.js +75 -0
  193. package/dist/native-bootstrap.js.map +1 -0
  194. package/dist/reporting/csvReportGenerator.d.ts.map +1 -1
  195. package/dist/reporting/htmlReportGenerator.d.ts.map +1 -1
  196. package/dist/reporting/jsonReportGenerator.d.ts.map +1 -1
  197. package/dist/reporting/reportGenerator.d.ts.map +1 -1
  198. package/dist/reporting/reportGenerator.js +4 -0
  199. package/dist/reporting/reportGenerator.js.map +1 -1
  200. package/dist/reporting/sarifReportGenerator.d.ts +39 -0
  201. package/dist/reporting/sarifReportGenerator.d.ts.map +1 -0
  202. package/dist/reporting/sarifReportGenerator.js +229 -0
  203. package/dist/reporting/sarifReportGenerator.js.map +1 -0
  204. package/dist/search/QueryParser.d.ts +41 -0
  205. package/dist/search/QueryParser.d.ts.map +1 -1
  206. package/dist/search/QueryParser.js +200 -19
  207. package/dist/search/QueryParser.js.map +1 -1
  208. package/dist/services/CodeMapGenerator.d.ts.map +1 -1
  209. package/dist/services/CodeMapGenerator.js +4 -4
  210. package/dist/services/CodeMapGenerator.js.map +1 -1
  211. package/dist/services/ProjectTaskRepository.d.ts +15 -2
  212. package/dist/services/ProjectTaskRepository.d.ts.map +1 -1
  213. package/dist/services/ProjectTaskRepository.js +16 -1
  214. package/dist/services/ProjectTaskRepository.js.map +1 -1
  215. package/dist/services/SchemaParser.d.ts.map +1 -1
  216. package/dist/services/SchemaParser.js +5 -8
  217. package/dist/services/SchemaParser.js.map +1 -1
  218. package/dist/services/auditJobService.d.ts +1 -1
  219. package/dist/services/projectTaskHelpers.js.map +1 -1
  220. package/dist/services/whitelistService.d.ts.map +1 -1
  221. package/dist/services/whitelistService.js +1 -1
  222. package/dist/services/whitelistService.js.map +1 -1
  223. package/dist/tool-registry.d.ts +79 -0
  224. package/dist/tool-registry.d.ts.map +1 -0
  225. package/dist/tool-registry.js +139 -0
  226. package/dist/tool-registry.js.map +1 -0
  227. package/dist/types/projectTask.d.ts +4 -0
  228. package/dist/types/projectTask.d.ts.map +1 -1
  229. package/dist/types.d.ts +26 -2
  230. package/dist/types.d.ts.map +1 -1
  231. package/dist/types.js.map +1 -1
  232. package/dist/ui/InteractivePrompts.d.ts.map +1 -1
  233. package/dist/ui/InteractivePrompts.js.map +1 -1
  234. package/dist/utils/astParser.d.ts +31 -38
  235. package/dist/utils/astParser.d.ts.map +1 -1
  236. package/dist/utils/astParser.js +138 -196
  237. package/dist/utils/astParser.js.map +1 -1
  238. package/dist/utils/astUtils.d.ts +87 -58
  239. package/dist/utils/astUtils.d.ts.map +1 -1
  240. package/dist/utils/astUtils.js +852 -581
  241. package/dist/utils/astUtils.js.map +1 -1
  242. package/dist/utils/componentPatterns.js.map +1 -1
  243. package/dist/utils/componentResponsibility.d.ts +13 -9
  244. package/dist/utils/componentResponsibility.d.ts.map +1 -1
  245. package/dist/utils/componentResponsibility.js +236 -206
  246. package/dist/utils/componentResponsibility.js.map +1 -1
  247. package/dist/utils/dependencyExtractor.d.ts +11 -6
  248. package/dist/utils/dependencyExtractor.d.ts.map +1 -1
  249. package/dist/utils/dependencyExtractor.js +200 -119
  250. package/dist/utils/dependencyExtractor.js.map +1 -1
  251. package/dist/utils/fileDiscovery.d.ts +1 -1
  252. package/dist/utils/fileDiscovery.d.ts.map +1 -1
  253. package/dist/utils/fileDiscovery.js +15 -6
  254. package/dist/utils/fileDiscovery.js.map +1 -1
  255. package/dist/utils/jsDocParser.d.ts +27 -30
  256. package/dist/utils/jsDocParser.d.ts.map +1 -1
  257. package/dist/utils/jsDocParser.js +271 -207
  258. package/dist/utils/jsDocParser.js.map +1 -1
  259. package/dist/utils/reactDetection.d.ts +27 -12
  260. package/dist/utils/reactDetection.d.ts.map +1 -1
  261. package/dist/utils/reactDetection.js +331 -219
  262. package/dist/utils/reactDetection.js.map +1 -1
  263. package/dist/workers/auditWorker.js +17 -3
  264. package/dist/workers/auditWorker.js.map +1 -1
  265. package/package.json +54 -51
  266. package/dist/adapters/GoAdapter.d.ts +0 -53
  267. package/dist/adapters/GoAdapter.d.ts.map +0 -1
  268. package/dist/adapters/GoAdapter.js +0 -611
  269. package/dist/adapters/GoAdapter.js.map +0 -1
  270. package/dist/adapters/GoConfig.d.ts +0 -35
  271. package/dist/adapters/GoConfig.d.ts.map +0 -1
  272. package/dist/adapters/GoConfig.js +0 -155
  273. package/dist/adapters/GoConfig.js.map +0 -1
  274. package/dist/adapters/LanguageAdapter.d.ts +0 -135
  275. package/dist/adapters/LanguageAdapter.d.ts.map +0 -1
  276. package/dist/adapters/LanguageAdapter.js +0 -47
  277. package/dist/adapters/LanguageAdapter.js.map +0 -1
  278. package/dist/adapters/TypeScriptAdapter.d.ts +0 -43
  279. package/dist/adapters/TypeScriptAdapter.d.ts.map +0 -1
  280. package/dist/adapters/TypeScriptAdapter.js +0 -386
  281. package/dist/adapters/TypeScriptAdapter.js.map +0 -1
  282. package/dist/adapters/UniversalAnalyzer.d.ts +0 -42
  283. package/dist/adapters/UniversalAnalyzer.d.ts.map +0 -1
  284. package/dist/adapters/UniversalAnalyzer.js +0 -103
  285. package/dist/adapters/UniversalAnalyzer.js.map +0 -1
  286. package/dist/adapters/UniversalSOLIDAnalyzer.d.ts +0 -48
  287. package/dist/adapters/UniversalSOLIDAnalyzer.d.ts.map +0 -1
  288. package/dist/adapters/UniversalSOLIDAnalyzer.js +0 -178
  289. package/dist/adapters/UniversalSOLIDAnalyzer.js.map +0 -1
  290. package/dist/adapters/solidAnalyzerCompat.d.ts +0 -21
  291. package/dist/adapters/solidAnalyzerCompat.d.ts.map +0 -1
  292. package/dist/adapters/solidAnalyzerCompat.js +0 -78
  293. package/dist/adapters/solidAnalyzerCompat.js.map +0 -1
  294. package/dist/analyzers/dataAccessAnalyzerCompat.d.ts +0 -20
  295. package/dist/analyzers/dataAccessAnalyzerCompat.d.ts.map +0 -1
  296. package/dist/analyzers/dataAccessAnalyzerCompat.js +0 -59
  297. package/dist/analyzers/dataAccessAnalyzerCompat.js.map +0 -1
  298. package/dist/analyzers/documentationAnalyzerCompat.d.ts +0 -20
  299. package/dist/analyzers/documentationAnalyzerCompat.d.ts.map +0 -1
  300. package/dist/analyzers/documentationAnalyzerCompat.js +0 -52
  301. package/dist/analyzers/documentationAnalyzerCompat.js.map +0 -1
  302. package/dist/analyzers/dryAnalyzerCompat.d.ts +0 -20
  303. package/dist/analyzers/dryAnalyzerCompat.d.ts.map +0 -1
  304. package/dist/analyzers/dryAnalyzerCompat.js +0 -44
  305. package/dist/analyzers/dryAnalyzerCompat.js.map +0 -1
  306. package/dist/analyzers/schemaAnalyzerCompat.d.ts +0 -20
  307. package/dist/analyzers/schemaAnalyzerCompat.d.ts.map +0 -1
  308. package/dist/analyzers/schemaAnalyzerCompat.js +0 -69
  309. package/dist/analyzers/schemaAnalyzerCompat.js.map +0 -1
  310. package/dist/analyzers/solidAnalyzerCompat.d.ts +0 -20
  311. package/dist/analyzers/solidAnalyzerCompat.d.ts.map +0 -1
  312. package/dist/analyzers/solidAnalyzerCompat.js +0 -78
  313. package/dist/analyzers/solidAnalyzerCompat.js.map +0 -1
  314. package/dist/codeIndexDb.d.ts.map +0 -1
  315. package/dist/codeIndexDb.js +0 -2102
  316. package/dist/codeIndexDb.js.map +0 -1
  317. package/dist/languages/typescript/TypeScriptAdapter.d.ts +0 -108
  318. package/dist/languages/typescript/TypeScriptAdapter.d.ts.map +0 -1
  319. package/dist/languages/typescript/TypeScriptAdapter.js +0 -567
  320. package/dist/languages/typescript/TypeScriptAdapter.js.map +0 -1
  321. package/dist/languages/typescript/test-extraction.d.ts +0 -2
  322. package/dist/languages/typescript/test-extraction.d.ts.map +0 -1
  323. package/dist/languages/typescript/test-extraction.js +0 -36
  324. package/dist/languages/typescript/test-extraction.js.map +0 -1
  325. package/dist/mcp-hybrid.d.ts +0 -10
  326. package/dist/mcp-hybrid.d.ts.map +0 -1
  327. package/dist/mcp-hybrid.js +0 -41
  328. package/dist/mcp-hybrid.js.map +0 -1
  329. package/dist/mcp-index.d.ts +0 -13
  330. package/dist/mcp-index.d.ts.map +0 -1
  331. package/dist/mcp-index.js +0 -136
  332. package/dist/mcp-index.js.map +0 -1
  333. package/dist/mcp-standalone.d.ts +0 -3
  334. package/dist/mcp-standalone.d.ts.map +0 -1
  335. package/dist/mcp-standalone.js +0 -1324
  336. package/dist/mcp-standalone.js.map +0 -1
  337. package/dist/mcp-ui-server.d.ts +0 -27
  338. package/dist/mcp-ui-server.d.ts.map +0 -1
  339. package/dist/mcp-ui-server.js +0 -484
  340. package/dist/mcp-ui-server.js.map +0 -1
  341. package/dist/test-multi-strategy-search.d.ts +0 -3
  342. package/dist/test-multi-strategy-search.d.ts.map +0 -1
  343. package/dist/test-multi-strategy-search.js +0 -170
  344. package/dist/test-multi-strategy-search.js.map +0 -1
@@ -0,0 +1,951 @@
1
+ /**
2
+ * Tree-sitter TypeScript/JavaScript adapter implementing the LanguageAdapter interface.
3
+ *
4
+ * Uses web-tree-sitter WASM parsers behind the adapter seam — no TypeScript compiler API.
5
+ * Supports .ts, .tsx, .js, and .jsx files.
6
+ */
7
+ import { getParser } from '../tree-sitter/parser.js';
8
+ import { toASTNode, toSourceLocation } from '../tree-sitter/converter.js';
9
+ // ---------------------------------------------------------------------------
10
+ // Source code storage
11
+ // ---------------------------------------------------------------------------
12
+ /**
13
+ * Source code indexed by AST, so methods that only receive an AST
14
+ * can recover the original source text.
15
+ */
16
+ const sourceCodeMap = new WeakMap();
17
+ // ---------------------------------------------------------------------------
18
+ // Adapter implementation
19
+ // ---------------------------------------------------------------------------
20
+ export class TreeSitterTypeScriptAdapter {
21
+ name = 'typescript';
22
+ fileExtensions = ['.ts', '.tsx', '.js', '.jsx'];
23
+ // -- File detection -------------------------------------------------------
24
+ supportsFile(filePath) {
25
+ return this.fileExtensions.some((ext) => filePath.endsWith(ext));
26
+ }
27
+ // -- Parsing --------------------------------------------------------------
28
+ async parse(filePath, content) {
29
+ const isTsx = filePath.endsWith('.tsx') || filePath.endsWith('.jsx');
30
+ const lang = isTsx ? 'tsx' : filePath.endsWith('.go') ? 'go' : 'typescript';
31
+ const parser = getParser(lang, isTsx);
32
+ const tree = parser.parse(content);
33
+ if (!tree)
34
+ throw new Error(`Failed to parse file: ${filePath}`);
35
+ const errors = [];
36
+ // Collect ERROR nodes as parse errors
37
+ this.collectErrors(tree.rootNode, errors);
38
+ const root = toASTNode(tree.rootNode, undefined, lang);
39
+ const ast = {
40
+ root,
41
+ language: lang,
42
+ filePath,
43
+ errors,
44
+ };
45
+ sourceCodeMap.set(ast, content);
46
+ return ast;
47
+ }
48
+ // -- AST Navigation -------------------------------------------------------
49
+ findNodes(ast, pattern) {
50
+ const results = [];
51
+ this.walk(ast.root, (node) => {
52
+ if (this.matchesPattern(node, pattern)) {
53
+ results.push(node);
54
+ }
55
+ });
56
+ return results;
57
+ }
58
+ getParent(node) {
59
+ return node.parent ?? null;
60
+ }
61
+ getChildren(node) {
62
+ return node.children ?? [];
63
+ }
64
+ getSiblings(node) {
65
+ if (!node.parent?.children)
66
+ return [];
67
+ return node.parent.children.filter((c) => c !== node);
68
+ }
69
+ // -- Node Information -----------------------------------------------------
70
+ getNodeType(node) {
71
+ return node.type;
72
+ }
73
+ getNodeText(node, sourceCode) {
74
+ return sourceCode.slice(node.range[0], node.range[1]);
75
+ }
76
+ getNodeName(node) {
77
+ const syntaxNode = node.raw;
78
+ return this.extractName(syntaxNode);
79
+ }
80
+ getNodeLocation(node) {
81
+ return node.location;
82
+ }
83
+ // -- Language-Specific Extraction -----------------------------------------
84
+ extractFunctions(ast) {
85
+ const sourceCode = sourceCodeMap.get(ast) ?? '';
86
+ const functions = [];
87
+ this.walk(ast.root, (node) => {
88
+ const syntaxNode = node.raw;
89
+ const type = syntaxNode.type;
90
+ if (type === 'function_declaration' ||
91
+ type === 'generator_function_declaration' ||
92
+ type === 'function_expression' ||
93
+ type === 'arrow_function' ||
94
+ type === 'method_definition') {
95
+ const fn = this.buildFunctionInfo(syntaxNode, sourceCode);
96
+ if (fn)
97
+ functions.push(fn);
98
+ }
99
+ });
100
+ return functions;
101
+ }
102
+ extractClasses(ast) {
103
+ const sourceCode = sourceCodeMap.get(ast) ?? '';
104
+ const classes = [];
105
+ this.walk(ast.root, (node) => {
106
+ const syntaxNode = node.raw;
107
+ if (syntaxNode.type === 'class_declaration') {
108
+ const cls = this.buildClassInfo(syntaxNode, sourceCode);
109
+ if (cls)
110
+ classes.push(cls);
111
+ }
112
+ });
113
+ return classes;
114
+ }
115
+ extractImports(ast) {
116
+ const sourceCode = sourceCodeMap.get(ast) ?? '';
117
+ const imports = [];
118
+ this.walk(ast.root, (node) => {
119
+ const syntaxNode = node.raw;
120
+ if (syntaxNode.type === 'import_statement') {
121
+ const imp = this.buildImportInfo(syntaxNode, sourceCode);
122
+ if (imp)
123
+ imports.push(imp);
124
+ }
125
+ });
126
+ return imports;
127
+ }
128
+ extractExports(ast) {
129
+ const sourceCode = sourceCodeMap.get(ast) ?? '';
130
+ const exports = [];
131
+ this.walk(ast.root, (node) => {
132
+ const syntaxNode = node.raw;
133
+ if (syntaxNode.type === 'export_statement') {
134
+ const ex = this.buildExportInfo(syntaxNode, sourceCode);
135
+ if (ex)
136
+ exports.push(ex);
137
+ }
138
+ });
139
+ return exports;
140
+ }
141
+ // -- Pattern Matching Helpers ---------------------------------------------
142
+ isClass(node) {
143
+ const type = node.raw.type;
144
+ return type === 'class_declaration' || type === 'class_expression';
145
+ }
146
+ isFunction(node) {
147
+ const type = node.raw.type;
148
+ return (type === 'function_declaration' ||
149
+ type === 'function_expression' ||
150
+ type === 'arrow_function' ||
151
+ type === 'generator_function_declaration' ||
152
+ type === 'generator_function_expression');
153
+ }
154
+ isMethod(node) {
155
+ return node.raw.type === 'method_definition';
156
+ }
157
+ isInterface(node) {
158
+ return node.raw.type === 'interface_declaration';
159
+ }
160
+ isImport(node) {
161
+ return node.raw.type === 'import_statement';
162
+ }
163
+ isExport(node) {
164
+ return node.raw.type === 'export_statement';
165
+ }
166
+ isLoop(node) {
167
+ const type = node.raw.type;
168
+ return (type === 'for_statement' ||
169
+ type === 'for_in_statement' ||
170
+ type === 'while_statement' ||
171
+ type === 'do_statement');
172
+ }
173
+ isConditional(node) {
174
+ const type = node.raw.type;
175
+ return (type === 'if_statement' ||
176
+ type === 'switch_statement' ||
177
+ type === 'ternary_expression' ||
178
+ type === 'switch_case');
179
+ }
180
+ isVariableDeclaration(node) {
181
+ const type = node.raw.type;
182
+ return (type === 'variable_declaration' ||
183
+ type === 'lexical_declaration' ||
184
+ type === 'variable_declarator');
185
+ }
186
+ // -- Advanced Features ----------------------------------------------------
187
+ getTypeInfo(node) {
188
+ const syntaxNode = node.raw;
189
+ return this.extractTypeAnnotation(syntaxNode);
190
+ }
191
+ getDocumentation(node) {
192
+ const syntaxNode = node.raw;
193
+ return this.extractDocumentation(syntaxNode);
194
+ }
195
+ getComplexity(node) {
196
+ const syntaxNode = node.raw;
197
+ return this.calculateCyclomaticComplexity(syntaxNode);
198
+ }
199
+ // -- Optional: Interfaces -------------------------------------------------
200
+ extractInterfaces(ast) {
201
+ const sourceCode = sourceCodeMap.get(ast) ?? '';
202
+ const interfaces = [];
203
+ this.walk(ast.root, (node) => {
204
+ const syntaxNode = node.raw;
205
+ if (syntaxNode.type === 'interface_declaration') {
206
+ const iface = this.buildInterfaceInfo(syntaxNode, sourceCode);
207
+ if (iface)
208
+ interfaces.push(iface);
209
+ }
210
+ });
211
+ return interfaces;
212
+ }
213
+ // -- Optional: Raw imports (static, dynamic, require) ----------------------
214
+ extractRawImports(_filePath, content) {
215
+ const results = [];
216
+ const parser = getParser('typescript');
217
+ const tree = parser.parse(content);
218
+ if (!tree)
219
+ return results;
220
+ // Static imports
221
+ this.walkRaw(tree.rootNode, (node) => {
222
+ if (node.type === 'import_statement') {
223
+ const source = this.getChildByType(node, 'string');
224
+ if (source) {
225
+ const specifier = source.text.slice(1, -1); // strip quotes
226
+ results.push({
227
+ moduleSpecifier: specifier,
228
+ isStatic: true,
229
+ isDynamic: false,
230
+ isRequire: false,
231
+ line: source.startPosition.row,
232
+ });
233
+ }
234
+ }
235
+ // Dynamic import(): import('...')
236
+ if (node.type === 'call_expression') {
237
+ const fn = node.firstChild;
238
+ if (fn?.type === 'import') {
239
+ const args = this.getChildByType(node, 'arguments');
240
+ if (args) {
241
+ const strNode = this.findFirstNamedChild(args, 'string');
242
+ if (strNode) {
243
+ const specifier = strNode.text.slice(1, -1);
244
+ results.push({
245
+ moduleSpecifier: specifier,
246
+ isStatic: false,
247
+ isDynamic: true,
248
+ isRequire: false,
249
+ line: strNode.startPosition.row,
250
+ });
251
+ }
252
+ }
253
+ }
254
+ // require('...')
255
+ if (fn?.type === 'identifier' && fn.text === 'require') {
256
+ const args = this.getChildByType(node, 'arguments');
257
+ if (args) {
258
+ const strNode = this.findFirstNamedChild(args, 'string');
259
+ if (strNode) {
260
+ const specifier = strNode.text.slice(1, -1);
261
+ results.push({
262
+ moduleSpecifier: specifier,
263
+ isStatic: false,
264
+ isDynamic: false,
265
+ isRequire: true,
266
+ line: strNode.startPosition.row,
267
+ });
268
+ }
269
+ }
270
+ }
271
+ }
272
+ });
273
+ return results;
274
+ }
275
+ // -- Optional: Exported symbol names --------------------------------------
276
+ extractExportedSymbols(ast) {
277
+ const symbols = [];
278
+ this.walk(ast.root, (astNode) => {
279
+ const node = astNode.raw;
280
+ if (node.type === 'export_statement') {
281
+ // export function foo / export class Foo / export const x
282
+ const declaration = this.findFirstNamedChild(node, [
283
+ 'function_declaration',
284
+ 'class_declaration',
285
+ 'lexical_declaration',
286
+ 'variable_declaration',
287
+ 'interface_declaration',
288
+ 'type_alias_declaration',
289
+ 'enum_declaration',
290
+ ]);
291
+ if (declaration) {
292
+ const name = this.extractName(declaration);
293
+ if (name) {
294
+ symbols.push({ name, line: declaration.startPosition.row });
295
+ return;
296
+ }
297
+ }
298
+ // export { foo, bar } or export { default }
299
+ const clause = this.getChildByType(node, 'export_clause');
300
+ if (clause) {
301
+ for (const child of clause.namedChildren) {
302
+ if (child.type === 'export_specifier') {
303
+ const nameNode = this.getChildByType(child, 'identifier');
304
+ if (nameNode) {
305
+ symbols.push({
306
+ name: nameNode.text,
307
+ line: nameNode.startPosition.row,
308
+ });
309
+ }
310
+ }
311
+ }
312
+ }
313
+ // export default <expression>
314
+ if (node.childForFieldName?.('value')) {
315
+ symbols.push({
316
+ name: 'default',
317
+ line: node.startPosition.row,
318
+ });
319
+ }
320
+ }
321
+ });
322
+ return symbols;
323
+ }
324
+ // ---------------------------------------------------------------------------
325
+ // Internal helpers
326
+ // ---------------------------------------------------------------------------
327
+ /** Walk all ASTNodes in a tree (depth-first). */
328
+ walk(node, visitor) {
329
+ visitor(node);
330
+ if (node.children) {
331
+ for (const child of node.children) {
332
+ this.walk(child, visitor);
333
+ }
334
+ }
335
+ }
336
+ /** Walk all TreeSitterNodes in a tree (depth-first). */
337
+ walkRaw(node, visitor) {
338
+ visitor(node);
339
+ for (const child of node.children) {
340
+ this.walkRaw(child, visitor);
341
+ }
342
+ }
343
+ /** Collect ERROR nodes from tree-sitter's error recovery. */
344
+ collectErrors(node, errors) {
345
+ if (node.type === 'ERROR' || node.isError) {
346
+ errors.push({
347
+ message: `Parse error near "${node.text.slice(0, 50)}"`,
348
+ location: toSourceLocation(node),
349
+ severity: 'error',
350
+ });
351
+ }
352
+ for (const child of node.children) {
353
+ this.collectErrors(child, errors);
354
+ }
355
+ }
356
+ /** Match an ASTNode against a NodePattern. */
357
+ matchesPattern(node, pattern) {
358
+ const syntaxNode = node.raw;
359
+ // type matching
360
+ if (pattern.type !== undefined) {
361
+ const types = Array.isArray(pattern.type) ? pattern.type : [pattern.type];
362
+ if (!types.includes(syntaxNode.type))
363
+ return false;
364
+ }
365
+ // name matching
366
+ if (pattern.name !== undefined) {
367
+ const nodeName = this.extractName(syntaxNode);
368
+ if (nodeName === null)
369
+ return false;
370
+ if (typeof pattern.name === 'string') {
371
+ if (nodeName !== pattern.name)
372
+ return false;
373
+ }
374
+ else if (pattern.name instanceof RegExp) {
375
+ if (!pattern.name.test(nodeName))
376
+ return false;
377
+ }
378
+ }
379
+ // hasChild matching
380
+ if (pattern.hasChild !== undefined) {
381
+ const childNodes = node.children ?? [];
382
+ const hasMatch = childNodes.some((c) => this.matchesPattern(c, pattern.hasChild));
383
+ if (!hasMatch)
384
+ return false;
385
+ }
386
+ // hasParent matching
387
+ if (pattern.hasParent !== undefined) {
388
+ if (!node.parent)
389
+ return false;
390
+ if (!this.matchesPattern(node.parent, pattern.hasParent))
391
+ return false;
392
+ }
393
+ // custom predicate
394
+ if (pattern.custom !== undefined) {
395
+ if (!pattern.custom(node))
396
+ return false;
397
+ }
398
+ return true;
399
+ }
400
+ /** Extract the name/identifier from a tree-sitter TreeSitterNode. */
401
+ extractName(node) {
402
+ switch (node.type) {
403
+ case 'function_declaration':
404
+ case 'generator_function_declaration':
405
+ case 'class_declaration':
406
+ case 'interface_declaration':
407
+ case 'enum_declaration':
408
+ case 'type_alias_declaration': {
409
+ const nameNode = node.childForFieldName?.('name');
410
+ if (nameNode)
411
+ return nameNode.text;
412
+ // Fallback: find first identifier child
413
+ for (const child of node.namedChildren) {
414
+ if (child.type === 'identifier' || child.type === 'type_identifier') {
415
+ return child.text;
416
+ }
417
+ }
418
+ return null;
419
+ }
420
+ case 'method_definition':
421
+ case 'public_field_definition': {
422
+ const nameNode = node.childForFieldName?.('name');
423
+ if (nameNode)
424
+ return nameNode.text;
425
+ // property_identifier or string
426
+ for (const child of node.namedChildren) {
427
+ if (child.type === 'property_identifier' ||
428
+ child.type === 'string') {
429
+ return child.text.replace(/^["']|["']$/g, '');
430
+ }
431
+ }
432
+ return null;
433
+ }
434
+ case 'variable_declarator': {
435
+ const nameNode = node.childForFieldName?.('name');
436
+ if (nameNode)
437
+ return nameNode.text;
438
+ return null;
439
+ }
440
+ case 'lexical_declaration':
441
+ case 'variable_declaration': {
442
+ // Find the declarator child and extract its name
443
+ for (const child of node.namedChildren) {
444
+ if (child.type === 'variable_declarator') {
445
+ return this.extractName(child);
446
+ }
447
+ }
448
+ return null;
449
+ }
450
+ case 'arrow_function': {
451
+ // Check if assigned to a variable: const foo = () => {}
452
+ const parent = node.parent;
453
+ if (parent?.type === 'variable_declarator') {
454
+ return this.extractName(parent);
455
+ }
456
+ return null;
457
+ }
458
+ case 'function_expression': {
459
+ // Might have a name: const foo = function bar() {}
460
+ const nameNode = node.childForFieldName?.('name');
461
+ if (nameNode)
462
+ return nameNode.text;
463
+ // Check if assigned to a variable
464
+ const parent = node.parent;
465
+ if (parent?.type === 'variable_declarator') {
466
+ return this.extractName(parent);
467
+ }
468
+ return null;
469
+ }
470
+ case 'property_identifier':
471
+ return node.text;
472
+ case 'identifier':
473
+ return node.text;
474
+ default:
475
+ return null;
476
+ }
477
+ }
478
+ /** Extract a type annotation string from a node. */
479
+ extractTypeAnnotation(node) {
480
+ // Function return type
481
+ if (node.type === 'function_declaration' ||
482
+ node.type === 'method_definition' ||
483
+ node.type === 'arrow_function') {
484
+ const returnType = node.childForFieldName?.('return_type');
485
+ if (returnType) {
486
+ return returnType.text.replace(/^:\s*/, '').trim();
487
+ }
488
+ }
489
+ // Variable / parameter type annotation
490
+ const typeAnnotation = node.childForFieldName?.('type');
491
+ if (typeAnnotation) {
492
+ return typeAnnotation.text.replace(/^:\s*/, '').trim();
493
+ }
494
+ // Named children that are type_annotation
495
+ for (const child of node.namedChildren) {
496
+ if (child.type === 'type_annotation') {
497
+ return child.text.replace(/^:\s*/, '').trim();
498
+ }
499
+ }
500
+ return null;
501
+ }
502
+ /** Extract JSDoc or leading comment from a node. */
503
+ extractDocumentation(node) {
504
+ const parent = node.parent;
505
+ if (!parent)
506
+ return null;
507
+ // Find the node's position among its parent's children and look for
508
+ // a preceding comment node.
509
+ const siblings = parent.children;
510
+ let myIndex = -1;
511
+ for (let i = 0; i < siblings.length; i++) {
512
+ if (siblings[i] === node) {
513
+ myIndex = i;
514
+ break;
515
+ }
516
+ }
517
+ if (myIndex === -1)
518
+ return null;
519
+ // Look backwards through siblings for comment nodes
520
+ const comments = [];
521
+ for (let i = myIndex - 1; i >= 0; i--) {
522
+ const sibling = siblings[i];
523
+ if (sibling.type === 'comment') {
524
+ comments.unshift(sibling.text);
525
+ }
526
+ else if (sibling.isNamed) {
527
+ // Stop at the first non-comment, named sibling
528
+ break;
529
+ }
530
+ // Continue past non-named tokens (whitespace, semicolons, etc.)
531
+ }
532
+ if (comments.length === 0)
533
+ return null;
534
+ const text = comments.join('\n').trim();
535
+ return this.cleanCommentText(text);
536
+ }
537
+ /** Strip comment syntax markers. */
538
+ cleanCommentText(comment) {
539
+ // Block comments: /* ... */ or /** ... */
540
+ if (comment.startsWith('/*')) {
541
+ let inner = comment.slice(2, -2);
542
+ // Strip leading asterisks
543
+ inner = inner
544
+ .split('\n')
545
+ .map((line) => line.replace(/^\s*\*\s?/, ''))
546
+ .join('\n');
547
+ return inner.trim();
548
+ }
549
+ // Line comments: //
550
+ if (comment.startsWith('//')) {
551
+ return comment.replace(/^\/\/\s*/, '').trim();
552
+ }
553
+ return comment.trim();
554
+ }
555
+ /**
556
+ * Cyclomatic complexity: count decision points + 1.
557
+ * Decision points: if, for, while, do, switch_case, ternary, &&, ||.
558
+ */
559
+ calculateCyclomaticComplexity(node) {
560
+ let complexity = 1;
561
+ this.walkRaw(node, (child) => {
562
+ if (child === node)
563
+ return; // don't count the root node itself
564
+ switch (child.type) {
565
+ case 'if_statement':
566
+ case 'for_statement':
567
+ case 'for_in_statement':
568
+ case 'while_statement':
569
+ case 'do_statement':
570
+ case 'switch_case':
571
+ case 'ternary_expression':
572
+ case 'catch_clause':
573
+ complexity++;
574
+ break;
575
+ case 'binary_expression': {
576
+ // && and || create branching paths
577
+ const op = this.getOperator(child);
578
+ if (op === '&&' || op === '||') {
579
+ complexity++;
580
+ }
581
+ break;
582
+ }
583
+ }
584
+ });
585
+ return complexity;
586
+ }
587
+ /** Get the operator text from a binary expression node. */
588
+ getOperator(node) {
589
+ for (const child of node.children) {
590
+ if (!child.isNamed &&
591
+ ['&&', '||', '+', '-', '*', '/', '%', '===', '!==', '==', '!='].includes(child.type)) {
592
+ return child.type;
593
+ }
594
+ }
595
+ return null;
596
+ }
597
+ // -- Extraction helpers ----------------------------------------------------
598
+ buildFunctionInfo(node, sourceCode) {
599
+ const name = this.extractName(node);
600
+ if (name === null && node.type !== 'arrow_function')
601
+ return null;
602
+ const isAsync = this.hasModifier(node, 'async');
603
+ const isMethod = node.type === 'method_definition';
604
+ const isExported = this.isNodeExported(node);
605
+ const returnType = this.extractTypeAnnotation(node);
606
+ const jsDoc = this.extractDocumentation(node);
607
+ const className = isMethod ? this.getEnclosingClassName(node) : undefined;
608
+ const parameters = this.extractParameters(node, sourceCode);
609
+ return {
610
+ name: name ?? '<anonymous>',
611
+ location: toSourceLocation(node),
612
+ parameters,
613
+ returnType: returnType ?? undefined,
614
+ isAsync,
615
+ isExported,
616
+ isMethod,
617
+ className,
618
+ jsDoc: jsDoc ?? undefined,
619
+ };
620
+ }
621
+ buildClassInfo(node, sourceCode) {
622
+ const name = this.extractName(node);
623
+ if (!name)
624
+ return null;
625
+ const isAbstract = this.hasModifier(node, 'abstract');
626
+ const isExported = this.isNodeExported(node);
627
+ const jsDoc = this.extractDocumentation(node);
628
+ // Extract extends
629
+ let extendsName;
630
+ const extendsClause = node.childForFieldName?.('extends');
631
+ if (extendsClause) {
632
+ const firstTypeChild = extendsClause.namedChildren[0];
633
+ if (firstTypeChild) {
634
+ extendsName = firstTypeChild.text;
635
+ }
636
+ }
637
+ // Extract implements
638
+ let implementsList;
639
+ const implementsClause = node.childForFieldName?.('implements');
640
+ if (implementsClause) {
641
+ implementsList = implementsClause.namedChildren.map((c) => c.text);
642
+ }
643
+ // Extract methods
644
+ const classBody = node.childForFieldName?.('body');
645
+ const methods = [];
646
+ const properties = [];
647
+ if (classBody) {
648
+ for (const member of classBody.namedChildren) {
649
+ if (member.type === 'method_definition') {
650
+ const fnInfo = this.buildFunctionInfo(member, sourceCode);
651
+ if (fnInfo) {
652
+ fnInfo.className = name;
653
+ fnInfo.isMethod = true;
654
+ methods.push(fnInfo);
655
+ }
656
+ }
657
+ else if (member.type === 'public_field_definition' ||
658
+ member.type === 'field_definition') {
659
+ const propInfo = this.buildPropertyInfo(member);
660
+ if (propInfo)
661
+ properties.push(propInfo);
662
+ }
663
+ }
664
+ }
665
+ return {
666
+ name,
667
+ location: toSourceLocation(node),
668
+ methods,
669
+ properties,
670
+ extends: extendsName,
671
+ implements: implementsList,
672
+ isAbstract,
673
+ isExported,
674
+ jsDoc: jsDoc ?? undefined,
675
+ };
676
+ }
677
+ buildPropertyInfo(node) {
678
+ const name = this.extractName(node);
679
+ if (!name)
680
+ return null;
681
+ let visibility;
682
+ if (this.hasModifier(node, 'private'))
683
+ visibility = 'private';
684
+ else if (this.hasModifier(node, 'protected'))
685
+ visibility = 'protected';
686
+ else if (this.hasModifier(node, 'public'))
687
+ visibility = 'public';
688
+ const isStatic = this.hasModifier(node, 'static');
689
+ const isReadonly = this.hasModifier(node, 'readonly');
690
+ const type = this.extractTypeAnnotation(node);
691
+ return {
692
+ name,
693
+ type: type ?? undefined,
694
+ visibility,
695
+ isStatic,
696
+ isReadonly,
697
+ };
698
+ }
699
+ buildImportInfo(node, _sourceCode) {
700
+ // import source
701
+ const sourceNode = node.childForFieldName?.('source');
702
+ if (!sourceNode)
703
+ return null;
704
+ const source = sourceNode.text.slice(1, -1); // strip quotes
705
+ const specifiers = [];
706
+ // import defaultExport from 'module'
707
+ // import * as namespace from 'module'
708
+ // import { named } from 'module'
709
+ for (const child of node.namedChildren) {
710
+ if (child.type === 'import_specifier') {
711
+ const nameNode = child.childForFieldName?.('name');
712
+ const aliasNode = child.childForFieldName?.('alias');
713
+ if (nameNode) {
714
+ specifiers.push({
715
+ name: nameNode.text,
716
+ alias: aliasNode?.text,
717
+ isDefault: false,
718
+ isNamespace: false,
719
+ });
720
+ }
721
+ }
722
+ else if (child.type === 'namespace_import') {
723
+ const nameNode = child.childForFieldName?.('name');
724
+ if (nameNode) {
725
+ specifiers.push({
726
+ name: nameNode.text,
727
+ isDefault: false,
728
+ isNamespace: true,
729
+ });
730
+ }
731
+ }
732
+ else if (child.type === 'import') {
733
+ // default import: `import foo from '...'`
734
+ const nameNode = node.childForFieldName?.('name');
735
+ if (nameNode) {
736
+ specifiers.push({
737
+ name: nameNode.text,
738
+ isDefault: true,
739
+ isNamespace: false,
740
+ });
741
+ }
742
+ }
743
+ }
744
+ return {
745
+ source,
746
+ specifiers,
747
+ location: toSourceLocation(node),
748
+ };
749
+ }
750
+ buildExportInfo(node, _sourceCode) {
751
+ // export default <expression>
752
+ const isDefault = this.hasChild(node, 'default');
753
+ // export { foo, bar } [from '...']
754
+ const clause = node.childForFieldName?.('clause');
755
+ if (clause?.type === 'export_clause') {
756
+ const sourceNode = node.childForFieldName?.('source');
757
+ const exports = [];
758
+ for (const spec of clause.namedChildren) {
759
+ if (spec.type === 'export_specifier') {
760
+ const nameNode = spec.childForFieldName?.('name');
761
+ if (nameNode) {
762
+ exports.push({
763
+ name: nameNode.text,
764
+ location: toSourceLocation(nameNode),
765
+ isDefault: false,
766
+ source: sourceNode?.text.slice(1, -1),
767
+ });
768
+ }
769
+ }
770
+ }
771
+ // Return first (handled by caller iterating export_statement nodes)
772
+ return exports[0] ?? null;
773
+ }
774
+ // export function/class/const/let/var name
775
+ const declaration = this.findFirstNamedChild(node, [
776
+ 'function_declaration',
777
+ 'class_declaration',
778
+ 'lexical_declaration',
779
+ 'variable_declaration',
780
+ ]);
781
+ if (declaration) {
782
+ const name = this.extractName(declaration);
783
+ if (name) {
784
+ return {
785
+ name,
786
+ location: toSourceLocation(node),
787
+ isDefault,
788
+ source: node.childForFieldName?.('source')?.text.slice(1, -1),
789
+ };
790
+ }
791
+ }
792
+ // export default <name> (no declaration)
793
+ if (isDefault) {
794
+ const value = node.childForFieldName?.('value');
795
+ if (value) {
796
+ return {
797
+ name: value.text,
798
+ location: toSourceLocation(node),
799
+ isDefault: true,
800
+ };
801
+ }
802
+ }
803
+ return null;
804
+ }
805
+ buildInterfaceInfo(node, _sourceCode) {
806
+ const name = this.extractName(node);
807
+ if (!name)
808
+ return null;
809
+ const isExported = this.isNodeExported(node);
810
+ // Extends
811
+ let extendsList;
812
+ const extendsClause = node.childForFieldName?.('extends');
813
+ if (extendsClause) {
814
+ extendsList = extendsClause.namedChildren.map((c) => c.text);
815
+ }
816
+ // Members
817
+ const body = node.childForFieldName?.('body');
818
+ const members = [];
819
+ if (body) {
820
+ for (const member of body.namedChildren) {
821
+ if (member.type === 'method_signature') {
822
+ const memberName = member.childForFieldName?.('name')?.text;
823
+ if (memberName) {
824
+ members.push({
825
+ name: memberName,
826
+ type: 'method',
827
+ location: toSourceLocation(member),
828
+ });
829
+ }
830
+ }
831
+ else if (member.type === 'property_signature') {
832
+ const memberName = member.childForFieldName?.('name')?.text;
833
+ if (memberName) {
834
+ members.push({
835
+ name: memberName,
836
+ type: 'property',
837
+ location: toSourceLocation(member),
838
+ });
839
+ }
840
+ }
841
+ }
842
+ }
843
+ return {
844
+ name,
845
+ location: toSourceLocation(node),
846
+ members,
847
+ extends: extendsList,
848
+ isExported,
849
+ };
850
+ }
851
+ // -- Parameter extraction --------------------------------------------------
852
+ extractParameters(node, sourceCode) {
853
+ const params = [];
854
+ const formalParams = node.childForFieldName?.('parameters');
855
+ if (!formalParams)
856
+ return params;
857
+ for (const child of formalParams.namedChildren) {
858
+ if (child.type === 'required_parameter' || child.type === 'optional_parameter') {
859
+ const paramNode = child.childForFieldName?.('pattern');
860
+ const name = paramNode?.text ?? child.firstNamedChild?.text;
861
+ const isOptional = child.type === 'optional_parameter';
862
+ const typeNode = child.childForFieldName?.('type');
863
+ let defaultValue;
864
+ // Check for a default value
865
+ const valueNode = child.childForFieldName?.('value');
866
+ if (valueNode) {
867
+ defaultValue = valueNode.text;
868
+ }
869
+ if (name) {
870
+ params.push({
871
+ name,
872
+ type: typeNode?.text.replace(/^:\s*/, ''),
873
+ optional: isOptional,
874
+ defaultValue,
875
+ });
876
+ }
877
+ }
878
+ }
879
+ return params;
880
+ }
881
+ // -- Context helpers -------------------------------------------------------
882
+ /** Check if a node has an `async` modifier keyword. */
883
+ hasModifier(node, modifier) {
884
+ for (const child of node.children) {
885
+ if (!child.isNamed && child.type === modifier)
886
+ return true;
887
+ // tree-sitter may represent modifiers as named decorator/modifier nodes
888
+ if (child.isNamed &&
889
+ (child.type === modifier ||
890
+ child.type === 'accessibility_modifier' ||
891
+ child.type === 'override_modifier' ||
892
+ child.type === 'readonly' ||
893
+ child.type === 'static' ||
894
+ child.type === 'abstract')) {
895
+ if (child.text === modifier)
896
+ return true;
897
+ }
898
+ }
899
+ return false;
900
+ }
901
+ /** Check if a node is under an export_statement. */
902
+ isNodeExported(node) {
903
+ const parent = node.parent;
904
+ if (parent?.type === 'export_statement')
905
+ return true;
906
+ // Also check for `export` keyword on the node itself (TS module syntax)
907
+ for (const child of node.children) {
908
+ if (!child.isNamed && child.type === 'export')
909
+ return true;
910
+ }
911
+ return false;
912
+ }
913
+ /** Get the enclosing class name for a method. */
914
+ getEnclosingClassName(node) {
915
+ let current = node.parent;
916
+ while (current) {
917
+ if (current.type === 'class_declaration') {
918
+ return this.extractName(current) ?? undefined;
919
+ }
920
+ current = current.parent ?? null;
921
+ }
922
+ return undefined;
923
+ }
924
+ // -- Tree traversal helpers ------------------------------------------------
925
+ /** Find first child of node matching one of the given types. */
926
+ getChildByType(node, type) {
927
+ for (const child of node.children) {
928
+ if (child.type === type)
929
+ return child;
930
+ }
931
+ return null;
932
+ }
933
+ /** Find the first named child matching one of the given types. */
934
+ findFirstNamedChild(node, types) {
935
+ const typeSet = Array.isArray(types) ? new Set(types) : new Set([types]);
936
+ for (const child of node.namedChildren) {
937
+ if (typeSet.has(child.type))
938
+ return child;
939
+ }
940
+ return null;
941
+ }
942
+ /** Check if node has a direct child (named or anonymous) with the given text. */
943
+ hasChild(node, text) {
944
+ for (const child of node.children) {
945
+ if (child.text === text || child.type === text)
946
+ return true;
947
+ }
948
+ return false;
949
+ }
950
+ }
951
+ //# sourceMappingURL=TreeSitterTypeScriptAdapter.js.map