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
@@ -1,1324 +0,0 @@
1
- #!/usr/bin/env node
2
- import './applyDataDirEnv.js';
3
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
- import { CallToolRequestSchema, ListToolsRequestSchema, InitializeRequestSchema } from '@modelcontextprotocol/sdk/types.js';
6
- import { createAuditRunner } from './auditRunner.js';
7
- import { syncFileIndex, searchFunctions, findDefinition, clearIndex } from './codeIndexService.js';
8
- import { CodeIndexDB } from './codeIndexDB.js';
9
- import { ConfigGeneratorFactory } from './generators/ConfigGeneratorFactory.js';
10
- import { IS_DEV_MODE, PACKAGE_VERSION } from './constants.js';
11
- import { scanFunctionsInDirectory } from './functionScanner.js';
12
- import path from 'node:path';
13
- import chalk from 'chalk';
14
- import { assertAuditPathExists, formatMcpToolErrorPayload } from './mcpToolErrors.js';
15
- import { logMcpInfo, mcpDebugStderr, mcpTraceStderr } from './mcpDiagnostics.js';
16
- import { createWriteStream } from 'node:fs';
17
- import { getAuditJobStatus, getAuditResultsPage, startAuditJob } from './mcpAuditJobs.js';
18
- // Set up file logging (only in development mode)
19
- let logStream = null;
20
- if (IS_DEV_MODE) {
21
- const logFilePath = path.join(process.cwd(), 'mcp-server.log');
22
- logStream = createWriteStream(logFilePath, { flags: 'a' });
23
- console.error(chalk.blue('[INFO]'), `Development mode: Logging to file: ${logFilePath}`);
24
- }
25
- // Save original console.error (log is redirected to stderr; see below)
26
- const originalConsoleError = console.error;
27
- // Override console.log — MCP uses stdout only for JSON-RPC; log() must never touch stdout.
28
- console.log = (...args) => {
29
- if (logStream) {
30
- const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
31
- const timestamp = new Date().toISOString();
32
- logStream.write(`[${timestamp}] [LOG] ${message}\n`);
33
- }
34
- originalConsoleError.apply(console, args);
35
- };
36
- // Override console.error (with conditional file logging)
37
- console.error = (...args) => {
38
- if (logStream) {
39
- const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
40
- const timestamp = new Date().toISOString();
41
- logStream.write(`[${timestamp}] [ERROR] ${message}\n`);
42
- }
43
- originalConsoleError.apply(console, args);
44
- };
45
- const tools = [
46
- {
47
- name: 'audit',
48
- description: 'Fetch paginated results for a completed audit by resultId (or auditId alias). This tool never starts a new audit.',
49
- parameters: [
50
- {
51
- name: 'limit',
52
- type: 'number',
53
- required: false,
54
- description: 'Maximum number of violations to return per page (default: 50, max: 100)',
55
- default: 50,
56
- },
57
- {
58
- name: 'offset',
59
- type: 'number',
60
- required: false,
61
- description: 'Violation offset for pagination (default: 0)',
62
- default: 0,
63
- },
64
- {
65
- name: 'resultId',
66
- type: 'string',
67
- required: false,
68
- description: 'Result ID returned by audit_status when the background audit job completes.',
69
- },
70
- {
71
- name: 'auditId',
72
- type: 'string',
73
- required: false,
74
- description: 'Backward-compatible alias for resultId.',
75
- },
76
- ],
77
- },
78
- {
79
- name: 'start_audit',
80
- description: 'Start a background audit job. Returns immediately with a jobId. Poll audit_status until completed, then fetch pages with audit or audit_results.',
81
- parameters: [
82
- {
83
- name: 'path',
84
- type: 'string',
85
- required: false,
86
- description: 'File or directory path to audit (defaults to current directory).',
87
- default: process.cwd(),
88
- },
89
- {
90
- name: 'analyzers',
91
- type: 'array',
92
- required: false,
93
- description: 'Analyzers to run (default: solid, dry).',
94
- default: ['solid', 'dry'],
95
- },
96
- {
97
- name: 'minSeverity',
98
- type: 'string',
99
- required: false,
100
- description: 'Minimum severity level to report.',
101
- default: 'info',
102
- enum: ['info', 'warning', 'critical'],
103
- },
104
- {
105
- name: 'indexFunctions',
106
- type: 'boolean',
107
- required: false,
108
- description: 'Index functions during audit (default: true).',
109
- default: true,
110
- },
111
- {
112
- name: 'analyzerConfigs',
113
- type: 'object',
114
- required: false,
115
- description: 'Analyzer-specific configuration overrides.',
116
- },
117
- {
118
- name: 'analyzerConcurrency',
119
- type: 'number',
120
- required: false,
121
- description: 'Max analyzers to run in parallel (default: 1).',
122
- default: 1,
123
- },
124
- {
125
- name: 'partitionStrategy',
126
- type: 'string',
127
- required: false,
128
- description: 'Partition mode: none | auto | top-level. auto shards when large source trees are detected.',
129
- default: 'auto',
130
- enum: ['none', 'auto', 'top-level'],
131
- },
132
- {
133
- name: 'maxPartitions',
134
- type: 'number',
135
- required: false,
136
- description: 'Maximum number of folder partitions for sharded audits (default: 4).',
137
- default: 4,
138
- },
139
- {
140
- name: 'partitionThresholdFiles',
141
- type: 'number',
142
- required: false,
143
- description: 'Minimum discovered files before auto partitioning is enabled (default: 250).',
144
- default: 250,
145
- },
146
- {
147
- name: 'workerCount',
148
- type: 'number',
149
- required: false,
150
- description: 'Number of worker processes for shard execution (default: min(4, CPU-1)).',
151
- },
152
- {
153
- name: 'maxRetries',
154
- type: 'number',
155
- required: false,
156
- description: 'Retry attempts per shard for retryable failures (default: 1).',
157
- default: 1,
158
- },
159
- {
160
- name: 'shardTimeoutMs',
161
- type: 'number',
162
- required: false,
163
- description: 'Per-shard timeout in milliseconds (default: 180000).',
164
- default: 180000,
165
- },
166
- {
167
- name: 'retryBackoffMs',
168
- type: 'number',
169
- required: false,
170
- description: 'Base retry backoff in milliseconds (default: 500).',
171
- default: 500,
172
- },
173
- {
174
- name: 'jobTimeoutMs',
175
- type: 'number',
176
- required: false,
177
- description: 'Maximum wall time for the entire audit job (default 30m, env CODE_AUDITOR_JOB_TIMEOUT_MS, cap 4h). Aborts workers cooperatively then tears down.',
178
- },
179
- {
180
- name: 'maxFilesPerRun',
181
- type: 'number',
182
- required: false,
183
- description: 'Per worker chunk: if more files match than this, the worker finishes one chunk and the parent queues the rest on another worker (optional).',
184
- },
185
- {
186
- name: 'shardSoftBudgetMs',
187
- type: 'number',
188
- required: false,
189
- description: 'Per worker soft wall-clock budget; aborts in-process analysis cooperatively via AbortSignal so the parent can assign the next chunk to a fresh worker.',
190
- },
191
- {
192
- name: 'generateCodeMap',
193
- type: 'boolean',
194
- required: false,
195
- description: 'Generate code map artifacts during audit (default: false).',
196
- default: false,
197
- },
198
- ],
199
- },
200
- {
201
- name: 'audit_status',
202
- description: 'Get current status for a previously started background audit job. Returns resultId when completed.',
203
- parameters: [
204
- {
205
- name: 'jobId',
206
- type: 'string',
207
- required: true,
208
- description: 'Job ID returned by start_audit.',
209
- },
210
- ],
211
- },
212
- {
213
- name: 'audit_results',
214
- description: 'Fetch paginated violations for a completed audit result by resultId.',
215
- parameters: [
216
- {
217
- name: 'resultId',
218
- type: 'string',
219
- required: true,
220
- description: 'Result ID returned by audit_status when status is completed.',
221
- },
222
- {
223
- name: 'limit',
224
- type: 'number',
225
- required: false,
226
- description: 'Maximum number of violations to return per page (default: 50, max: 100).',
227
- default: 50,
228
- },
229
- {
230
- name: 'offset',
231
- type: 'number',
232
- required: false,
233
- description: 'Violation offset for pagination (default: 0).',
234
- default: 0,
235
- },
236
- ],
237
- },
238
- {
239
- name: 'audit_health',
240
- description: 'Quick health check of a codebase with key metrics',
241
- parameters: [
242
- {
243
- name: 'path',
244
- type: 'string',
245
- required: false,
246
- description: 'The directory path to check',
247
- default: process.cwd(),
248
- },
249
- {
250
- name: 'threshold',
251
- type: 'number',
252
- required: false,
253
- description: 'Health score threshold (0-100) for pass/fail',
254
- default: 70,
255
- },
256
- {
257
- name: 'indexFunctions',
258
- type: 'boolean',
259
- required: false,
260
- description: 'Automatically index functions during health check',
261
- default: true,
262
- },
263
- ],
264
- },
265
- {
266
- name: 'search_code',
267
- description: 'Search indexed functions and React components with natural language queries. Supports operators: entity:component, component:functional|class|memo|forwardRef, hook:useState|useEffect|etc, prop:propName, dep:packageName, dependency:lodash, uses:express, calls:functionName, calledby:functionName, dependents-of:functionName, used-by:functionName, depends-on:module, imports-from:file, unused-imports, dead-imports, type:fileType, file:path, lang:language, complexity:1-10, jsdoc:true|false',
268
- parameters: [
269
- {
270
- name: 'query',
271
- type: 'string',
272
- required: true,
273
- description: 'Search query with natural language and/or operators. Examples: "Button component:functional", "entity:component hook:useState", "render prop:onClick", "dep:lodash", "calls:validateUser", "unused-imports", "dependents-of:authenticate"',
274
- },
275
- {
276
- name: 'filters',
277
- type: 'object',
278
- required: false,
279
- description: 'Optional filters (language, filePath, dependencies, componentType, entityType, searchMode). Set searchMode to "content" to search within function bodies, "metadata" for names/signatures only, or "both" for combined search',
280
- },
281
- {
282
- name: 'limit',
283
- type: 'number',
284
- required: false,
285
- description: 'Maximum results to return',
286
- default: 50,
287
- },
288
- {
289
- name: 'offset',
290
- type: 'number',
291
- required: false,
292
- description: 'Offset for pagination',
293
- default: 0,
294
- },
295
- ],
296
- },
297
- {
298
- name: 'find_definition',
299
- description: 'Find the exact definition of a specific function',
300
- parameters: [
301
- {
302
- name: 'name',
303
- type: 'string',
304
- required: true,
305
- description: 'Function name to find',
306
- },
307
- {
308
- name: 'filePath',
309
- type: 'string',
310
- required: false,
311
- description: 'Optional file path to narrow search',
312
- },
313
- ],
314
- },
315
- {
316
- name: 'sync_index',
317
- description: 'Synchronize, cleanup, or reset analysis-derived data (indexed functions, cached audits, code maps, schema overlays). Project tasks, analyzer configs, and whitelist entries are preserved on reset.',
318
- parameters: [
319
- {
320
- name: 'mode',
321
- type: 'string',
322
- required: false,
323
- description: 'sync: update index from files; cleanup: remove index rows for deleted files; reset: clear all analysis-derived data (not tasks/config/whitelist)',
324
- default: 'sync',
325
- enum: ['sync', 'cleanup', 'reset'],
326
- },
327
- {
328
- name: 'path',
329
- type: 'string',
330
- required: false,
331
- description: 'Optional specific path to sync',
332
- },
333
- ],
334
- },
335
- {
336
- name: 'generate_ai_config',
337
- description: 'Generate configuration files for AI coding assistants',
338
- parameters: [
339
- {
340
- name: 'tools',
341
- type: 'array',
342
- required: true,
343
- description: 'AI tools to configure (cursor, continue, copilot, claude, zed, windsurf, cody, aider, cline, pearai)',
344
- },
345
- {
346
- name: 'outputDir',
347
- type: 'string',
348
- required: false,
349
- description: 'Output directory for configuration files',
350
- default: '.',
351
- },
352
- ],
353
- },
354
- {
355
- name: 'get_workflow_guide',
356
- description: 'Get recommended workflows and best practices for using code auditor tools effectively',
357
- parameters: [
358
- {
359
- name: 'scenario',
360
- type: 'string',
361
- required: false,
362
- description: 'Specific scenario: initial-setup, react-development, code-review, find-patterns, maintenance. Leave empty to see all.',
363
- },
364
- ],
365
- },
366
- // Analyzer Configuration Tools
367
- {
368
- name: 'set_analyzer_config',
369
- description: 'Set or update analyzer configuration that persists across audit runs',
370
- parameters: [
371
- {
372
- name: 'analyzerName',
373
- type: 'string',
374
- required: true,
375
- description: 'The analyzer to configure (solid, dry, security, etc.)',
376
- },
377
- {
378
- name: 'config',
379
- type: 'object',
380
- required: true,
381
- description: 'Configuration object for the analyzer (e.g., thresholds, rules)',
382
- },
383
- {
384
- name: 'projectPath',
385
- type: 'string',
386
- required: false,
387
- description: 'Optional project path for project-specific config (defaults to global)',
388
- },
389
- ],
390
- },
391
- {
392
- name: 'get_analyzer_config',
393
- description: 'Get current configuration for an analyzer',
394
- parameters: [
395
- {
396
- name: 'analyzerName',
397
- type: 'string',
398
- required: false,
399
- description: 'Specific analyzer name, or omit to get all configs',
400
- },
401
- {
402
- name: 'projectPath',
403
- type: 'string',
404
- required: false,
405
- description: 'Optional project path to get project-specific config',
406
- },
407
- ],
408
- },
409
- {
410
- name: 'reset_analyzer_config',
411
- description: 'Reset analyzer configuration to defaults',
412
- parameters: [
413
- {
414
- name: 'analyzerName',
415
- type: 'string',
416
- required: false,
417
- description: 'Specific analyzer to reset, or omit to reset all',
418
- },
419
- {
420
- name: 'projectPath',
421
- type: 'string',
422
- required: false,
423
- description: 'Optional project path to reset only project-specific config',
424
- },
425
- ],
426
- },
427
- {
428
- name: 'whitelist_get',
429
- description: 'Get current whitelist entries for dependency and class instantiation checks',
430
- parameters: [
431
- {
432
- name: 'type',
433
- type: 'string',
434
- required: false,
435
- description: 'Filter by type: platform-api, framework-class, project-dep, shared-library, node-builtin',
436
- enum: ['platform-api', 'framework-class', 'project-dep', 'shared-library', 'node-builtin'],
437
- },
438
- {
439
- name: 'status',
440
- type: 'string',
441
- required: false,
442
- description: 'Filter by status: active, pending, rejected, disabled',
443
- enum: ['active', 'pending', 'rejected', 'disabled'],
444
- },
445
- ],
446
- },
447
- {
448
- name: 'whitelist_add',
449
- description: 'Add a new entry to the whitelist',
450
- parameters: [
451
- {
452
- name: 'name',
453
- type: 'string',
454
- required: true,
455
- description: 'Class name or import path to whitelist',
456
- },
457
- {
458
- name: 'type',
459
- type: 'string',
460
- required: true,
461
- description: 'Type of whitelist entry',
462
- enum: ['platform-api', 'framework-class', 'project-dep', 'shared-library', 'node-builtin'],
463
- },
464
- {
465
- name: 'description',
466
- type: 'string',
467
- required: false,
468
- description: 'Explanation of why this is whitelisted',
469
- },
470
- {
471
- name: 'patterns',
472
- type: 'array',
473
- required: false,
474
- description: 'Additional patterns to match (e.g., ["fs/*", "node:fs"])',
475
- },
476
- ],
477
- },
478
- {
479
- name: 'whitelist_update_status',
480
- description: 'Update the status of a whitelist entry',
481
- parameters: [
482
- {
483
- name: 'name',
484
- type: 'string',
485
- required: true,
486
- description: 'Name of the whitelist entry to update',
487
- },
488
- {
489
- name: 'status',
490
- type: 'string',
491
- required: true,
492
- description: 'New status for the entry',
493
- enum: ['active', 'pending', 'rejected', 'disabled'],
494
- },
495
- ],
496
- },
497
- {
498
- name: 'whitelist_detect',
499
- description: 'Detect potential whitelist candidates from package.json and usage patterns',
500
- parameters: [
501
- {
502
- name: 'path',
503
- type: 'string',
504
- required: false,
505
- description: 'Project path to analyze (defaults to current directory)',
506
- default: process.cwd(),
507
- },
508
- {
509
- name: 'includePackageJson',
510
- type: 'boolean',
511
- required: false,
512
- description: 'Include dependencies from package.json',
513
- default: true,
514
- },
515
- {
516
- name: 'autoPopulate',
517
- type: 'boolean',
518
- required: false,
519
- description: 'Automatically add high-confidence entries (>95% confidence)',
520
- default: false,
521
- },
522
- ],
523
- },
524
- {
525
- name: 'project_tasks',
526
- description: 'Manage a persistent per-project task queue. Tasks and analyzer configs survive sync_index reset; reset clears function index, cached audits, code maps, and schema overlays. Use delete to remove a task.',
527
- parameters: [
528
- {
529
- name: 'action',
530
- type: 'string',
531
- required: true,
532
- description: 'list | list_tree | create | get | update | complete_task | delete. list/list_tree/create use projectPath or default to process.cwd(); create needs title; get/update/complete_task/delete need taskId; update needs patch object.',
533
- enum: [
534
- 'list',
535
- 'list_tree',
536
- 'create',
537
- 'get',
538
- 'update',
539
- 'complete_task',
540
- 'delete'
541
- ],
542
- },
543
- {
544
- name: 'projectPath',
545
- type: 'string',
546
- required: false,
547
- description: 'Project root (resolved). Omit to use the MCP server working directory; response includes projectPathDefaulted when omitted.',
548
- },
549
- {
550
- name: 'taskId',
551
- type: 'string',
552
- required: false,
553
- description: 'Stable task id (UUID). Required for get, update, complete_task, delete.',
554
- },
555
- {
556
- name: 'title',
557
- type: 'string',
558
- required: false,
559
- description: 'Task title. Required for create.',
560
- },
561
- {
562
- name: 'description',
563
- type: 'string',
564
- required: false,
565
- description: 'Longer description / notes.',
566
- },
567
- {
568
- name: 'status',
569
- type: 'string',
570
- required: false,
571
- description: 'pending | in_progress | blocked | done | cancelled. Filter for list; initial status for create; can be set via update patch.',
572
- enum: ['pending', 'in_progress', 'blocked', 'done', 'cancelled'],
573
- },
574
- {
575
- name: 'priority',
576
- type: 'string',
577
- required: false,
578
- description: 'Optional priority for create/update patch.',
579
- enum: ['low', 'medium', 'high'],
580
- },
581
- {
582
- name: 'labels',
583
- type: 'array',
584
- required: false,
585
- description: 'String tags (e.g. ["audit","refactor"]).',
586
- },
587
- {
588
- name: 'metadata',
589
- type: 'object',
590
- required: false,
591
- description: 'Arbitrary JSON object: related file paths, links, audit IDs, etc.',
592
- },
593
- {
594
- name: 'parentTaskId',
595
- type: 'string',
596
- required: false,
597
- description: 'Optional parent task for subtasks.',
598
- },
599
- {
600
- name: 'source',
601
- type: 'string',
602
- required: false,
603
- description: 'manual | audit | mcp. Filter for list; provenance for create; can be set via update patch.',
604
- enum: ['manual', 'audit', 'mcp'],
605
- },
606
- {
607
- name: 'blockedBy',
608
- type: 'array',
609
- required: false,
610
- description: 'Task IDs this item is blocked by (waiting-on).',
611
- },
612
- {
613
- name: 'label',
614
- type: 'string',
615
- required: false,
616
- description: 'Filter/search by label value.',
617
- },
618
- {
619
- name: 'blockedByTaskId',
620
- type: 'string',
621
- required: false,
622
- description: 'Filter tasks blocked by this task ID.',
623
- },
624
- {
625
- name: 'query',
626
- type: 'string',
627
- required: false,
628
- description: 'Case-insensitive text search across title/description/labels/files/symbols.',
629
- },
630
- {
631
- name: 'hasChildren',
632
- type: 'boolean',
633
- required: false,
634
- description: 'Filter tasks that do/do not have direct subtasks.',
635
- },
636
- {
637
- name: 'overdueOnly',
638
- type: 'boolean',
639
- required: false,
640
- description: 'Filter tasks with dueAt in the past and not closed.',
641
- },
642
- {
643
- name: 'actionableOnly',
644
- type: 'boolean',
645
- required: false,
646
- description: 'Filter tasks that are open and unblocked by open dependencies.',
647
- },
648
- {
649
- name: 'dueAt',
650
- type: 'string',
651
- required: false,
652
- description: 'ISO 8601 due datetime for create; omit or null in patch to clear.',
653
- },
654
- {
655
- name: 'sortOrder',
656
- type: 'number',
657
- required: false,
658
- description: 'Lower numbers sort first within a project (default 0).',
659
- },
660
- {
661
- name: 'relatedFiles',
662
- type: 'array',
663
- required: false,
664
- description: 'Repo-relative or absolute file paths tied to the task.',
665
- },
666
- {
667
- name: 'relatedSymbols',
668
- type: 'array',
669
- required: false,
670
- description: 'Function, class, or component names for cross-linking.',
671
- },
672
- {
673
- name: 'patch',
674
- type: 'object',
675
- required: false,
676
- description: 'For update: partial fields (title, description, status, priority, labels, metadata, parentTaskId, source, blockedBy, dueAt, sortOrder, relatedFiles, relatedSymbols).',
677
- },
678
- {
679
- name: 'limit',
680
- type: 'number',
681
- required: false,
682
- description: 'Max tasks to return for list (default 500, max 1000).',
683
- },
684
- {
685
- name: 'mode',
686
- type: 'string',
687
- required: false,
688
- description: 'Delete mode: reject (default), detach subtasks, or cascade descendants.',
689
- enum: ['reject', 'detach', 'cascade'],
690
- },
691
- ],
692
- },
693
- ];
694
- function getAllViolations(result) {
695
- const violations = [];
696
- for (const [analyzerName, analyzerResult] of Object.entries(result.analyzerResults)) {
697
- for (const violation of analyzerResult.violations) {
698
- violations.push({
699
- ...violation,
700
- analyzer: analyzerName,
701
- });
702
- }
703
- }
704
- return violations;
705
- }
706
- function calculateHealthScore(result) {
707
- const filesAnalyzed = result.metadata?.filesAnalyzed || 1;
708
- const critical = result.summary.criticalIssues || 0;
709
- const warnings = result.summary.warnings || 0;
710
- const suggestions = result.summary.suggestions || 0;
711
- // Weight factors for different severity levels
712
- const weights = {
713
- critical: 10,
714
- warning: 3,
715
- suggestion: 0.5
716
- };
717
- // Calculate weighted violations per file
718
- const weightedViolations = (critical * weights.critical) +
719
- (warnings * weights.warning) +
720
- (suggestions * weights.suggestion);
721
- const violationsPerFile = weightedViolations / filesAnalyzed;
722
- // Score calculation: 100 points minus deductions
723
- // Each weighted violation per file reduces score
724
- // Critical-heavy codebases drop faster than suggestion-heavy ones
725
- let score = 100 - (violationsPerFile * 2);
726
- return Math.max(0, Math.round(Math.min(100, score)));
727
- }
728
- class RequestAbortedError extends Error {
729
- constructor(message = 'MCP request aborted') {
730
- super(message);
731
- this.name = 'RequestAbortedError';
732
- }
733
- }
734
- function throwIfRequestAborted(signal, phase) {
735
- if (!signal?.aborted) {
736
- return;
737
- }
738
- throw new RequestAbortedError(`Request aborted${phase ? ` during ${phase}` : ''}`);
739
- }
740
- async function withAbortSignal(signal, phase, op) {
741
- throwIfRequestAborted(signal, phase);
742
- if (!signal) {
743
- return op();
744
- }
745
- return await new Promise((resolve, reject) => {
746
- const onAbort = () => reject(new RequestAbortedError(`Request aborted during ${phase}`));
747
- signal.addEventListener('abort', onAbort, { once: true });
748
- void op()
749
- .then(resolve)
750
- .catch(reject)
751
- .finally(() => {
752
- signal.removeEventListener('abort', onAbort);
753
- });
754
- });
755
- }
756
- function serializeForMcp(value) {
757
- try {
758
- return JSON.stringify(value);
759
- }
760
- catch (error) {
761
- return JSON.stringify({
762
- success: false,
763
- error: `Failed to serialize MCP response: ${error instanceof Error ? error.message : String(error)}`
764
- });
765
- }
766
- }
767
- function safeJson(value) {
768
- try {
769
- return JSON.stringify(value, null, 2);
770
- }
771
- catch (error) {
772
- return `[unserializable: ${error instanceof Error ? error.message : String(error)}]`;
773
- }
774
- }
775
- function registerProcessReliabilityHandlers() {
776
- const g = globalThis;
777
- const exitOnFatal = process.env.CODE_AUDITOR_EXIT_ON_FATAL === '1' ||
778
- process.env.CODE_AUDITOR_EXIT_ON_FATAL === 'true';
779
- if (!g.__codeAuditorUncaughtExceptionHandlerInstalled) {
780
- process.on('uncaughtException', (error) => {
781
- console.error(chalk.red('[ERROR]'), 'Uncaught exception:', error);
782
- console.error(chalk.red('[ERROR]'), 'Stack:', error.stack);
783
- console.error(chalk.red('[ERROR]'), 'Error details:', safeJson(error));
784
- if (exitOnFatal) {
785
- process.exit(1);
786
- }
787
- });
788
- g.__codeAuditorUncaughtExceptionHandlerInstalled = true;
789
- }
790
- if (!g.__codeAuditorUnhandledRejectionHandlerInstalled) {
791
- process.on('unhandledRejection', (reason, promise) => {
792
- console.error(chalk.red('[ERROR]'), 'Unhandled rejection at:', promise);
793
- console.error(chalk.red('[ERROR]'), 'Reason:', reason);
794
- console.error(chalk.red('[ERROR]'), 'Rejection details:', safeJson(reason));
795
- if (exitOnFatal) {
796
- process.exit(1);
797
- }
798
- });
799
- g.__codeAuditorUnhandledRejectionHandlerInstalled = true;
800
- }
801
- }
802
- async function startMcpServer() {
803
- logMcpInfo('startup', `code-auditor-mcp ${PACKAGE_VERSION} (standalone stdio)`, {
804
- pid: process.pid,
805
- cwd: process.cwd(),
806
- dataDir: process.env.CODE_AUDITOR_DATA_DIR ?? '(default)'
807
- });
808
- mcpDebugStderr(chalk.blue('[DEBUG]'), `Node ${process.version} · cwd ${process.cwd()}`);
809
- const server = new Server({
810
- name: 'code-auditor',
811
- version: PACKAGE_VERSION,
812
- }, {
813
- capabilities: {
814
- tools: {},
815
- },
816
- });
817
- // Add error handler
818
- server.onerror = (error) => {
819
- console.error(chalk.red('[ERROR]'), 'Server error occurred:', error);
820
- console.error(chalk.red('[ERROR]'), 'Error stack:', error.stack);
821
- };
822
- server.setRequestHandler(ListToolsRequestSchema, async (request) => {
823
- mcpTraceStderr(chalk.blue('[DEBUG]'), 'ListTools', JSON.stringify(request, null, 2));
824
- const response = {
825
- tools: tools.map(tool => ({
826
- name: tool.name,
827
- description: tool.description,
828
- inputSchema: {
829
- type: 'object',
830
- properties: tool.parameters.reduce((acc, param) => {
831
- acc[param.name] = {
832
- type: param.type,
833
- description: param.description,
834
- ...(param.default !== undefined && { default: param.default }),
835
- ...(param.enum && { enum: param.enum }),
836
- };
837
- return acc;
838
- }, {}),
839
- required: tool.parameters.filter(p => p.required).map(p => p.name),
840
- },
841
- })),
842
- };
843
- mcpTraceStderr(chalk.blue('[DEBUG]'), `ListTools → ${response.tools.length} tools`);
844
- return response;
845
- });
846
- server.setRequestHandler(InitializeRequestSchema, async (request) => {
847
- mcpTraceStderr(chalk.blue('[DEBUG]'), 'initialize', JSON.stringify(request, null, 2));
848
- const response = {
849
- protocolVersion: '2024-11-05',
850
- capabilities: {
851
- tools: {},
852
- },
853
- serverInfo: {
854
- name: 'code-auditor',
855
- version: PACKAGE_VERSION,
856
- },
857
- };
858
- mcpTraceStderr(chalk.blue('[DEBUG]'), 'initialize response', JSON.stringify(response, null, 2));
859
- return response;
860
- });
861
- server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
862
- const { name, arguments: args } = request.params;
863
- mcpTraceStderr(chalk.blue('[DEBUG]'), `CallTool ${name}`, JSON.stringify({
864
- argKeys: args && typeof args === 'object' ? Object.keys(args) : [],
865
- hasArgs: !!args
866
- }));
867
- const requestSignal = extra?.signal;
868
- try {
869
- let result;
870
- throwIfRequestAborted(requestSignal, `start ${name}`);
871
- switch (name) {
872
- case 'start_audit': {
873
- result = await withAbortSignal(requestSignal, 'start_audit', () => startAuditJob(args, {
874
- defaultAnalyzers: ['solid', 'dry'],
875
- defaultMinSeverity: 'warning',
876
- defaultGenerateCodeMap: false,
877
- }));
878
- break;
879
- }
880
- case 'audit_status': {
881
- const jobId = args.jobId;
882
- if (!jobId) {
883
- throw new Error('audit_status requires jobId');
884
- }
885
- result = getAuditJobStatus(jobId);
886
- break;
887
- }
888
- case 'audit_results': {
889
- result = await withAbortSignal(requestSignal, 'audit_results', () => getAuditResultsPage(args));
890
- break;
891
- }
892
- case 'audit': {
893
- result = await withAbortSignal(requestSignal, 'audit', () => getAuditResultsPage(args));
894
- break;
895
- }
896
- case 'audit_health': {
897
- const auditPath = path.resolve(args.path || process.cwd());
898
- await assertAuditPathExists(auditPath);
899
- const indexFunctions = args.indexFunctions !== false; // Default true
900
- // Get stored analyzer configs from database
901
- const db = CodeIndexDB.getInstance();
902
- await db.initialize();
903
- const storedConfigs = await db.getAllAnalyzerConfigs(auditPath);
904
- // Merge stored configs with any provided configs
905
- const analyzerConfigs = {
906
- ...storedConfigs,
907
- ...(args.analyzerConfigs || {})
908
- };
909
- const runner = createAuditRunner({
910
- projectRoot: auditPath,
911
- enabledAnalyzers: ['solid', 'dry'],
912
- minSeverity: 'warning',
913
- verbose: false,
914
- indexFunctions, // Pass the flag to the runner
915
- ...(Object.keys(analyzerConfigs).length > 0 && { analyzerConfigs }),
916
- });
917
- const auditResult = await runner.run();
918
- const healthScore = calculateHealthScore(auditResult);
919
- // Handle function indexing if enabled and functions were collected
920
- let indexingResult = null;
921
- if (indexFunctions && auditResult.metadata.fileToFunctionsMap) {
922
- try {
923
- const syncStats = { added: 0, updated: 0, removed: 0 };
924
- // Sync each file's functions to handle additions, updates, and removals
925
- for (const [filePath, functions] of Object.entries(auditResult.metadata.fileToFunctionsMap)) {
926
- const fileStats = await syncFileIndex(filePath, functions);
927
- syncStats.added += fileStats.added;
928
- syncStats.updated += fileStats.updated;
929
- syncStats.removed += fileStats.removed;
930
- }
931
- indexingResult = {
932
- success: true,
933
- registered: syncStats.added + syncStats.updated,
934
- failed: 0,
935
- syncStats
936
- };
937
- mcpDebugStderr(chalk.blue('[INFO]'), `Synced functions: ${syncStats.added} added, ${syncStats.updated} updated, ${syncStats.removed} removed`);
938
- }
939
- catch (error) {
940
- console.error(chalk.yellow('[WARN]'), 'Failed to index functions:', error);
941
- }
942
- }
943
- const threshold = args.threshold || 70;
944
- result = {
945
- healthScore,
946
- threshold,
947
- passed: healthScore >= threshold,
948
- status: healthScore >= threshold ? 'healthy' : 'needs-attention',
949
- metrics: {
950
- filesAnalyzed: auditResult.metadata.filesAnalyzed,
951
- totalViolations: auditResult.summary.totalViolations,
952
- criticalViolations: auditResult.summary.criticalIssues,
953
- warningViolations: auditResult.summary.warnings,
954
- },
955
- recommendation: healthScore >= 90 ? 'Excellent code health!' :
956
- healthScore >= 70 ? 'Good code health with room for improvement' :
957
- 'Code health needs attention - run detailed audit',
958
- ...(indexingResult && { functionIndexing: indexingResult }),
959
- };
960
- break;
961
- }
962
- case 'search_code': {
963
- const query = args.query;
964
- const filters = args.filters;
965
- const limit = args.limit || 50;
966
- const offset = args.offset || 0;
967
- // Extract searchMode from filters if present
968
- let searchMode;
969
- if (filters && filters.searchMode) {
970
- searchMode = filters.searchMode;
971
- // Remove searchMode from filters as it's a top-level option
972
- const { searchMode: _, ...cleanFilters } = filters;
973
- result = await searchFunctions({ query, filters: cleanFilters, limit, offset, searchMode });
974
- }
975
- else {
976
- result = await searchFunctions({ query, filters, limit, offset });
977
- }
978
- break;
979
- }
980
- case 'find_definition': {
981
- const name = args.name;
982
- const filePath = args.filePath;
983
- const definition = await findDefinition(name, filePath);
984
- result = definition || { error: 'Function not found' };
985
- break;
986
- }
987
- case 'sync_index': {
988
- const mode = args.mode || 'sync';
989
- const targetPath = args.path;
990
- const db = CodeIndexDB.getInstance();
991
- await db.initialize();
992
- switch (mode) {
993
- case 'cleanup': {
994
- const cleanupResult = await db.bulkCleanup();
995
- result = {
996
- success: true,
997
- mode: 'cleanup',
998
- filesProcessed: cleanupResult.scannedCount,
999
- functionsRemoved: cleanupResult.removedCount,
1000
- message: `Removed ${cleanupResult.removedCount} functions from ${cleanupResult.removedFiles.length} deleted files`
1001
- };
1002
- break;
1003
- }
1004
- case 'sync': {
1005
- let syncResult;
1006
- if (targetPath) {
1007
- const functions = await scanFunctionsInDirectory(targetPath);
1008
- syncResult = await syncFileIndex(targetPath, functions);
1009
- result = {
1010
- success: true,
1011
- mode: 'sync',
1012
- path: targetPath,
1013
- ...syncResult
1014
- };
1015
- }
1016
- else {
1017
- syncResult = await db.deepSync();
1018
- result = {
1019
- success: true,
1020
- mode: 'sync',
1021
- filesProcessed: syncResult.syncedFiles,
1022
- functionsAdded: syncResult.addedFunctions,
1023
- functionsUpdated: syncResult.updatedFunctions,
1024
- functionsRemoved: syncResult.removedFunctions
1025
- };
1026
- }
1027
- // Auto-detect and populate whitelist entries
1028
- try {
1029
- const { WhitelistService } = await import('./services/whitelistService.js');
1030
- const whitelistService = WhitelistService.getInstance();
1031
- const whitelistResult = await whitelistService.whitelistAllDependencies(targetPath || process.cwd());
1032
- if (whitelistResult.added > 0) {
1033
- result.whitelistAdded = whitelistResult.added;
1034
- result.whitelistMessage = `Auto-added ${whitelistResult.added} whitelist entries`;
1035
- }
1036
- }
1037
- catch (error) {
1038
- // Don't fail sync if whitelist detection fails
1039
- console.warn('Whitelist auto-detection failed:', error);
1040
- }
1041
- break;
1042
- }
1043
- case 'reset': {
1044
- await clearIndex();
1045
- result = {
1046
- success: true,
1047
- mode: 'reset',
1048
- message: 'Analysis-derived data cleared (functions, search index, cached audits, code maps, schemas). Project tasks, whitelist, and analyzer configs were preserved.'
1049
- };
1050
- break;
1051
- }
1052
- default:
1053
- throw new Error(`Unknown sync mode: ${mode}`);
1054
- }
1055
- break;
1056
- }
1057
- case 'generate_ai_config': {
1058
- const tools = args.tools;
1059
- const outputDir = args.outputDir || '.';
1060
- if (!Array.isArray(tools) || tools.length === 0) {
1061
- throw new Error('tools parameter is required and must be a non-empty array');
1062
- }
1063
- const factory = new ConfigGeneratorFactory();
1064
- const generatedFiles = [];
1065
- const errors = [];
1066
- for (const toolName of tools) {
1067
- try {
1068
- const generator = factory.createGenerator(toolName);
1069
- if (!generator) {
1070
- errors.push(`Unknown tool: ${toolName}`);
1071
- continue;
1072
- }
1073
- const config = generator.generateConfig();
1074
- const outputPath = path.join(outputDir, config.filename);
1075
- // Check if file exists
1076
- const fs = await import('fs/promises');
1077
- try {
1078
- await fs.access(outputPath);
1079
- errors.push(`File already exists: ${config.filename} (use overwrite: true to replace)`);
1080
- continue;
1081
- }
1082
- catch {
1083
- // File doesn't exist, proceed
1084
- }
1085
- await fs.writeFile(outputPath, config.content, 'utf8');
1086
- generatedFiles.push(config.filename);
1087
- }
1088
- catch (error) {
1089
- errors.push(`Failed to generate config for ${toolName}: ${error instanceof Error ? error.message : 'Unknown error'}`);
1090
- }
1091
- }
1092
- result = {
1093
- success: errors.length === 0,
1094
- generatedFiles,
1095
- ...(errors.length > 0 && { errors }),
1096
- totalRequested: tools.length,
1097
- totalGenerated: generatedFiles.length
1098
- };
1099
- break;
1100
- }
1101
- case 'get_workflow_guide': {
1102
- const scenario = args.scenario;
1103
- const { getWorkflowGuide, getWorkflowTips } = await import('./mcp-tools/workflowGuide.js');
1104
- try {
1105
- const workflows = getWorkflowGuide(scenario);
1106
- const tips = getWorkflowTips();
1107
- result = {
1108
- success: true,
1109
- ...(scenario ? { workflow: workflows } : { workflows }),
1110
- tips
1111
- };
1112
- }
1113
- catch (error) {
1114
- result = {
1115
- success: false,
1116
- error: error instanceof Error ? error.message : 'Unknown error',
1117
- availableScenarios: ['initial-setup', 'react-development', 'code-review', 'find-patterns', 'maintenance', 'analyzer-configuration']
1118
- };
1119
- }
1120
- break;
1121
- }
1122
- case 'set_analyzer_config': {
1123
- const analyzerName = args.analyzerName;
1124
- const config = args.config;
1125
- const projectPath = args.projectPath;
1126
- const db = CodeIndexDB.getInstance();
1127
- await db.initialize();
1128
- try {
1129
- await db.storeAnalyzerConfig(analyzerName, config, {
1130
- projectPath,
1131
- isGlobal: !projectPath
1132
- });
1133
- result = {
1134
- success: true,
1135
- message: `Configuration for ${analyzerName} analyzer has been saved${projectPath ? ` for project ${projectPath}` : ' globally'}`,
1136
- analyzer: analyzerName,
1137
- scope: projectPath ? 'project' : 'global',
1138
- config
1139
- };
1140
- }
1141
- catch (error) {
1142
- result = {
1143
- success: false,
1144
- error: error instanceof Error ? error.message : 'Failed to save configuration'
1145
- };
1146
- }
1147
- break;
1148
- }
1149
- case 'get_analyzer_config': {
1150
- const analyzerName = args.analyzerName;
1151
- const projectPath = args.projectPath;
1152
- const db = CodeIndexDB.getInstance();
1153
- await db.initialize();
1154
- try {
1155
- if (analyzerName) {
1156
- const config = await db.getAnalyzerConfig(analyzerName, projectPath);
1157
- result = {
1158
- success: true,
1159
- analyzer: analyzerName,
1160
- config: config || null,
1161
- scope: projectPath ? 'project' : 'global',
1162
- message: config ? 'Configuration found' : 'No custom configuration found, using defaults'
1163
- };
1164
- }
1165
- else {
1166
- const configs = await db.getAllAnalyzerConfigs(projectPath);
1167
- result = {
1168
- success: true,
1169
- configs,
1170
- scope: projectPath ? 'project' : 'global',
1171
- message: `Found ${Object.keys(configs).length} analyzer configurations`
1172
- };
1173
- }
1174
- }
1175
- catch (error) {
1176
- result = {
1177
- success: false,
1178
- error: error instanceof Error ? error.message : 'Failed to get configuration'
1179
- };
1180
- }
1181
- break;
1182
- }
1183
- case 'reset_analyzer_config': {
1184
- const analyzerName = args.analyzerName;
1185
- const projectPath = args.projectPath;
1186
- const db = CodeIndexDB.getInstance();
1187
- await db.initialize();
1188
- try {
1189
- if (analyzerName) {
1190
- const deleted = await db.deleteAnalyzerConfig(analyzerName, {
1191
- projectPath,
1192
- isGlobal: !projectPath
1193
- });
1194
- result = {
1195
- success: deleted,
1196
- message: deleted
1197
- ? `Configuration for ${analyzerName} analyzer has been reset${projectPath ? ` for project ${projectPath}` : ' globally'}`
1198
- : `No configuration found for ${analyzerName} analyzer`,
1199
- analyzer: analyzerName,
1200
- scope: projectPath ? 'project' : 'global'
1201
- };
1202
- }
1203
- else {
1204
- await db.resetAnalyzerConfigs(projectPath);
1205
- result = {
1206
- success: true,
1207
- message: projectPath
1208
- ? `All project-specific configurations for ${projectPath} have been reset`
1209
- : 'All analyzer configurations have been reset to defaults',
1210
- scope: projectPath ? 'project' : 'global'
1211
- };
1212
- }
1213
- }
1214
- catch (error) {
1215
- result = {
1216
- success: false,
1217
- error: error instanceof Error ? error.message : 'Failed to reset configuration'
1218
- };
1219
- }
1220
- break;
1221
- }
1222
- case 'whitelist_get': {
1223
- const { handleWhitelistGet } = await import('./mcp-tools/whitelistTools.js');
1224
- result = await handleWhitelistGet(args);
1225
- break;
1226
- }
1227
- case 'whitelist_add': {
1228
- const { handleWhitelistAdd } = await import('./mcp-tools/whitelistTools.js');
1229
- result = await handleWhitelistAdd(args);
1230
- break;
1231
- }
1232
- case 'whitelist_update_status': {
1233
- const { handleWhitelistUpdateStatus } = await import('./mcp-tools/whitelistTools.js');
1234
- result = await handleWhitelistUpdateStatus(args);
1235
- break;
1236
- }
1237
- case 'whitelist_detect': {
1238
- const { handleWhitelistDetect } = await import('./mcp-tools/whitelistTools.js');
1239
- result = await handleWhitelistDetect(args);
1240
- break;
1241
- }
1242
- case 'project_tasks': {
1243
- const { handleProjectTasks } = await import('./mcp-tools/projectTasks.js');
1244
- result = await withAbortSignal(requestSignal, 'project_tasks', () => handleProjectTasks((args || {}), {
1245
- signal: requestSignal
1246
- }));
1247
- break;
1248
- }
1249
- default:
1250
- throw new Error(`Unknown tool: ${name}`);
1251
- }
1252
- const response = {
1253
- content: [
1254
- {
1255
- type: 'text',
1256
- text: serializeForMcp(result),
1257
- },
1258
- ],
1259
- };
1260
- mcpTraceStderr(chalk.blue('[DEBUG]'), `Tool ${name} ok`, `responseBytes=${response.content[0].text.length}`);
1261
- throwIfRequestAborted(requestSignal, `before response ${name}`);
1262
- return response;
1263
- }
1264
- catch (error) {
1265
- if (error instanceof RequestAbortedError) {
1266
- throw error;
1267
- }
1268
- console.error(chalk.red('[ERROR]'), `Tool ${name} execution failed:`, error);
1269
- console.error(chalk.red('[ERROR]'), 'Error stack:', error instanceof Error ? error.stack : 'No stack trace');
1270
- return {
1271
- content: [
1272
- {
1273
- type: 'text',
1274
- text: serializeForMcp(formatMcpToolErrorPayload(name, error)),
1275
- },
1276
- ],
1277
- isError: true,
1278
- };
1279
- }
1280
- });
1281
- const transport = new StdioServerTransport();
1282
- // Add transport event handlers if available
1283
- if (transport.onclose) {
1284
- transport.onclose = () => {
1285
- console.error(chalk.yellow('[WARN]'), 'Transport closed');
1286
- };
1287
- }
1288
- if (transport.onerror) {
1289
- transport.onerror = (error) => {
1290
- console.error(chalk.red('[ERROR]'), 'Transport error:', error);
1291
- };
1292
- }
1293
- await server.connect(transport);
1294
- console.error(chalk.green('✓ Code Auditor MCP Server started (standalone mode)'));
1295
- console.error(chalk.gray(`Listening on stdio · ${tools.length} tools · ${PACKAGE_VERSION}`));
1296
- mcpDebugStderr(chalk.blue('[DEBUG]'), 'Server ready', {
1297
- name: 'code-auditor',
1298
- transport: 'stdio',
1299
- toolCount: tools.length
1300
- });
1301
- }
1302
- registerProcessReliabilityHandlers();
1303
- // Add SIGTERM and SIGINT handlers
1304
- process.on('SIGTERM', () => {
1305
- console.error(chalk.yellow('[WARN]'), 'Received SIGTERM, shutting down gracefully...');
1306
- process.exitCode = 0;
1307
- });
1308
- process.on('SIGINT', () => {
1309
- console.error(chalk.yellow('[WARN]'), 'Received SIGINT, shutting down gracefully...');
1310
- process.exitCode = 0;
1311
- });
1312
- // Log when stdin/stdout events occur
1313
- process.stdin.on('error', (error) => {
1314
- console.error(chalk.red('[ERROR]'), 'stdin error:', error);
1315
- });
1316
- process.stdout.on('error', (error) => {
1317
- console.error(chalk.red('[ERROR]'), 'stdout error:', error);
1318
- });
1319
- startMcpServer().catch(error => {
1320
- console.error(chalk.red('[ERROR]'), 'Failed to start MCP server:', error);
1321
- console.error(chalk.red('[ERROR]'), 'Stack:', error.stack);
1322
- process.exitCode = 1;
1323
- });
1324
- //# sourceMappingURL=mcp-standalone.js.map