code-auditor-mcp 2.6.2 → 3.0.0

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 (343) hide show
  1. package/README.md +319 -147
  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.map +1 -1
  254. package/dist/utils/jsDocParser.d.ts +27 -30
  255. package/dist/utils/jsDocParser.d.ts.map +1 -1
  256. package/dist/utils/jsDocParser.js +271 -207
  257. package/dist/utils/jsDocParser.js.map +1 -1
  258. package/dist/utils/reactDetection.d.ts +27 -12
  259. package/dist/utils/reactDetection.d.ts.map +1 -1
  260. package/dist/utils/reactDetection.js +331 -219
  261. package/dist/utils/reactDetection.js.map +1 -1
  262. package/dist/workers/auditWorker.js +17 -3
  263. package/dist/workers/auditWorker.js.map +1 -1
  264. package/package.json +54 -51
  265. package/dist/adapters/GoAdapter.d.ts +0 -53
  266. package/dist/adapters/GoAdapter.d.ts.map +0 -1
  267. package/dist/adapters/GoAdapter.js +0 -611
  268. package/dist/adapters/GoAdapter.js.map +0 -1
  269. package/dist/adapters/GoConfig.d.ts +0 -35
  270. package/dist/adapters/GoConfig.d.ts.map +0 -1
  271. package/dist/adapters/GoConfig.js +0 -155
  272. package/dist/adapters/GoConfig.js.map +0 -1
  273. package/dist/adapters/LanguageAdapter.d.ts +0 -135
  274. package/dist/adapters/LanguageAdapter.d.ts.map +0 -1
  275. package/dist/adapters/LanguageAdapter.js +0 -47
  276. package/dist/adapters/LanguageAdapter.js.map +0 -1
  277. package/dist/adapters/TypeScriptAdapter.d.ts +0 -43
  278. package/dist/adapters/TypeScriptAdapter.d.ts.map +0 -1
  279. package/dist/adapters/TypeScriptAdapter.js +0 -386
  280. package/dist/adapters/TypeScriptAdapter.js.map +0 -1
  281. package/dist/adapters/UniversalAnalyzer.d.ts +0 -42
  282. package/dist/adapters/UniversalAnalyzer.d.ts.map +0 -1
  283. package/dist/adapters/UniversalAnalyzer.js +0 -103
  284. package/dist/adapters/UniversalAnalyzer.js.map +0 -1
  285. package/dist/adapters/UniversalSOLIDAnalyzer.d.ts +0 -48
  286. package/dist/adapters/UniversalSOLIDAnalyzer.d.ts.map +0 -1
  287. package/dist/adapters/UniversalSOLIDAnalyzer.js +0 -178
  288. package/dist/adapters/UniversalSOLIDAnalyzer.js.map +0 -1
  289. package/dist/adapters/solidAnalyzerCompat.d.ts +0 -21
  290. package/dist/adapters/solidAnalyzerCompat.d.ts.map +0 -1
  291. package/dist/adapters/solidAnalyzerCompat.js +0 -78
  292. package/dist/adapters/solidAnalyzerCompat.js.map +0 -1
  293. package/dist/analyzers/dataAccessAnalyzerCompat.d.ts +0 -20
  294. package/dist/analyzers/dataAccessAnalyzerCompat.d.ts.map +0 -1
  295. package/dist/analyzers/dataAccessAnalyzerCompat.js +0 -59
  296. package/dist/analyzers/dataAccessAnalyzerCompat.js.map +0 -1
  297. package/dist/analyzers/documentationAnalyzerCompat.d.ts +0 -20
  298. package/dist/analyzers/documentationAnalyzerCompat.d.ts.map +0 -1
  299. package/dist/analyzers/documentationAnalyzerCompat.js +0 -52
  300. package/dist/analyzers/documentationAnalyzerCompat.js.map +0 -1
  301. package/dist/analyzers/dryAnalyzerCompat.d.ts +0 -20
  302. package/dist/analyzers/dryAnalyzerCompat.d.ts.map +0 -1
  303. package/dist/analyzers/dryAnalyzerCompat.js +0 -44
  304. package/dist/analyzers/dryAnalyzerCompat.js.map +0 -1
  305. package/dist/analyzers/schemaAnalyzerCompat.d.ts +0 -20
  306. package/dist/analyzers/schemaAnalyzerCompat.d.ts.map +0 -1
  307. package/dist/analyzers/schemaAnalyzerCompat.js +0 -69
  308. package/dist/analyzers/schemaAnalyzerCompat.js.map +0 -1
  309. package/dist/analyzers/solidAnalyzerCompat.d.ts +0 -20
  310. package/dist/analyzers/solidAnalyzerCompat.d.ts.map +0 -1
  311. package/dist/analyzers/solidAnalyzerCompat.js +0 -78
  312. package/dist/analyzers/solidAnalyzerCompat.js.map +0 -1
  313. package/dist/codeIndexDb.d.ts.map +0 -1
  314. package/dist/codeIndexDb.js +0 -2102
  315. package/dist/codeIndexDb.js.map +0 -1
  316. package/dist/languages/typescript/TypeScriptAdapter.d.ts +0 -108
  317. package/dist/languages/typescript/TypeScriptAdapter.d.ts.map +0 -1
  318. package/dist/languages/typescript/TypeScriptAdapter.js +0 -567
  319. package/dist/languages/typescript/TypeScriptAdapter.js.map +0 -1
  320. package/dist/languages/typescript/test-extraction.d.ts +0 -2
  321. package/dist/languages/typescript/test-extraction.d.ts.map +0 -1
  322. package/dist/languages/typescript/test-extraction.js +0 -36
  323. package/dist/languages/typescript/test-extraction.js.map +0 -1
  324. package/dist/mcp-hybrid.d.ts +0 -10
  325. package/dist/mcp-hybrid.d.ts.map +0 -1
  326. package/dist/mcp-hybrid.js +0 -41
  327. package/dist/mcp-hybrid.js.map +0 -1
  328. package/dist/mcp-index.d.ts +0 -13
  329. package/dist/mcp-index.d.ts.map +0 -1
  330. package/dist/mcp-index.js +0 -136
  331. package/dist/mcp-index.js.map +0 -1
  332. package/dist/mcp-standalone.d.ts +0 -3
  333. package/dist/mcp-standalone.d.ts.map +0 -1
  334. package/dist/mcp-standalone.js +0 -1324
  335. package/dist/mcp-standalone.js.map +0 -1
  336. package/dist/mcp-ui-server.d.ts +0 -27
  337. package/dist/mcp-ui-server.d.ts.map +0 -1
  338. package/dist/mcp-ui-server.js +0 -484
  339. package/dist/mcp-ui-server.js.map +0 -1
  340. package/dist/test-multi-strategy-search.d.ts +0 -3
  341. package/dist/test-multi-strategy-search.d.ts.map +0 -1
  342. package/dist/test-multi-strategy-search.js +0 -170
  343. package/dist/test-multi-strategy-search.js.map +0 -1
package/dist/cli.js CHANGED
@@ -2,17 +2,23 @@
2
2
  /**
3
3
  * Code Auditor CLI - Enhanced with AI Tool Integration
4
4
  */
5
+ // MUST be first import: sets NAPI_RS_NATIVE_LIBRARY_PATH before @ast-grep/napi loads
6
+ import './native-bootstrap.js';
5
7
  import { Command } from 'commander';
6
8
  import chalk from 'chalk';
7
9
  import { createAuditRunner } from './auditRunner.js';
8
10
  import { readFileSync } from 'fs';
9
11
  import { promises as fs } from 'fs';
12
+ import { createInterface } from 'readline';
10
13
  import { fileURLToPath } from 'url';
11
- import { dirname, join, resolve } from 'path';
14
+ import { dirname, isAbsolute, join, relative, resolve } from 'path';
12
15
  import { ConfigGeneratorFactory } from './generators/ConfigGeneratorFactory.js';
13
16
  import { InteractivePrompts } from './ui/InteractivePrompts.js';
14
17
  import { DEFAULT_SERVER_URL, DEFAULT_PORT } from './constants.js';
15
18
  import { CodeMapGenerator } from './services/CodeMapGenerator.js';
19
+ import { initParsers } from './languages/index.js';
20
+ import { queryParser } from './search/QueryParser.js';
21
+ import { CodeIndexDB } from './codeIndexDB.js';
16
22
  // Get package.json for version info
17
23
  const __filename = fileURLToPath(import.meta.url);
18
24
  const __dirname = dirname(__filename);
@@ -30,10 +36,12 @@ program
30
36
  .option('-p, --path <path>', 'Path to audit', process.cwd())
31
37
  .option('-c, --config <config>', 'Configuration name')
32
38
  .option('-o, --output <dir>', 'Output directory for reports')
39
+ .option('-f, --format <format>', 'Report format: html, json, csv, or sarif')
33
40
  .action(async (options) => {
34
41
  console.log(chalk.blue('🔍 Code Quality Audit Tool'));
35
42
  console.log(chalk.gray('══════════════════════════════════════════════════'));
36
43
  try {
44
+ await initParsers();
37
45
  const runner = createAuditRunner({
38
46
  projectRoot: options.path,
39
47
  configName: options.config,
@@ -44,6 +52,148 @@ program
44
52
  console.log(`Critical: ${result.summary.criticalIssues}`);
45
53
  console.log(`Warnings: ${result.summary.warnings}`);
46
54
  console.log(`Suggestions: ${result.summary.suggestions}`);
55
+ // Generate formatted report if --format is specified
56
+ if (options.format) {
57
+ const validFormats = ['html', 'json', 'csv', 'sarif'];
58
+ if (!validFormats.includes(options.format)) {
59
+ console.error(chalk.red(`Unknown format: "${options.format}". Must be one of: ${validFormats.join(', ')}`));
60
+ process.exit(1);
61
+ }
62
+ const { generateReport } = await import('./reporting/reportGenerator.js');
63
+ const report = generateReport(result, options.format);
64
+ const outputDir = options.output || process.cwd();
65
+ const ext = options.format === 'sarif' ? 'sarif' : options.format;
66
+ const reportPath = join(outputDir, `audit-report.${ext}`);
67
+ await fs.writeFile(reportPath, report, 'utf-8');
68
+ console.log(chalk.green(`\nReport written to ${reportPath}`));
69
+ }
70
+ }
71
+ catch (error) {
72
+ console.error(chalk.red('Error:'), error);
73
+ process.exit(1);
74
+ }
75
+ });
76
+ // Diff-scoped audit command (Spec 04 R4)
77
+ program
78
+ .command('changed [paths...]')
79
+ .description('Audit changed files only — reads stdin when --stdin is set')
80
+ .option('--json', 'Output violations as machine-readable JSON to stdout')
81
+ .option('-f, --format <format>', 'Report format: json, or sarif (overrides --json)')
82
+ .option('--quiet', 'Suppress output when zero violations')
83
+ .option('--fail-on <severity>', 'Exit code 2 when violations at or above this severity exist', 'critical')
84
+ .option('--stdin', 'Read file paths from stdin (one per line)')
85
+ .option('-p, --path <projectPath>', 'Project root path', process.cwd())
86
+ .action(async (paths, options) => {
87
+ try {
88
+ await initParsers();
89
+ const fileSet = new Set();
90
+ // Collect paths from stdin if requested
91
+ if (options.stdin) {
92
+ const rl = createInterface({
93
+ input: process.stdin,
94
+ output: undefined,
95
+ terminal: false
96
+ });
97
+ for await (const line of rl) {
98
+ const trimmed = line.trim();
99
+ if (trimmed)
100
+ fileSet.add(trimmed);
101
+ }
102
+ }
103
+ // Add paths from command line
104
+ for (const p of paths) {
105
+ fileSet.add(p);
106
+ }
107
+ // Resolve scope
108
+ let scope = 'changed';
109
+ if (fileSet.size > 0) {
110
+ // Convert to absolute paths
111
+ const resolved = [...fileSet].map((f) => isAbsolute(f) ? f : resolve(process.cwd(), f));
112
+ scope = resolved;
113
+ }
114
+ // Validate --fail-on severity
115
+ const validSeverities = ['critical', 'warning', 'suggestion'];
116
+ const failOnSeverity = options.failOn;
117
+ if (!validSeverities.includes(failOnSeverity)) {
118
+ console.error(chalk.red(`Invalid --fail-on severity: "${failOnSeverity}". Must be one of: ${validSeverities.join(', ')}`));
119
+ process.exit(1);
120
+ }
121
+ // Create runner
122
+ const runner = createAuditRunner({
123
+ projectRoot: options.path,
124
+ scope,
125
+ analyzerConcurrency: 4
126
+ });
127
+ const result = await runner.run();
128
+ // Collect all violations
129
+ const violations = Object.values(result.analyzerResults).flatMap((r) => r.violations || []);
130
+ // JSON output
131
+ if (options.format === 'sarif') {
132
+ const { generateSARIFReport } = await import('./reporting/sarifReportGenerator.js');
133
+ const sarifOutput = generateSARIFReport(result);
134
+ process.stdout.write(sarifOutput + '\n');
135
+ }
136
+ else if (options.json) {
137
+ const projectDir = resolve(options.path || process.cwd());
138
+ const jsonOutput = violations.map((v) => {
139
+ // Compute relative path if file resolves inside the project
140
+ let filePath = v.file || '';
141
+ if (filePath.startsWith('/') || filePath.startsWith('\\\\')) {
142
+ const rel = relative(projectDir, filePath);
143
+ // Only use relative path if it doesn't escape the project
144
+ if (!rel.startsWith('..') && !isAbsolute(rel)) {
145
+ filePath = rel;
146
+ }
147
+ }
148
+ // Find column: prefer explicit column, then start.column, then default to 1
149
+ const col = v.column ?? v.start?.column ?? 1;
150
+ return {
151
+ analyzer: v.analyzer || '',
152
+ rule: v.rule || v.type || '',
153
+ severity: v.severity,
154
+ message: v.message,
155
+ file: filePath,
156
+ line: v.line ?? v.start?.line,
157
+ column: col,
158
+ endLine: v.end?.line,
159
+ endColumn: v.end?.column,
160
+ enclosingSymbol: v.symbol || v.enclosingFunction || '',
161
+ suggestion: v.suggestion || '',
162
+ details: v.details || ''
163
+ };
164
+ });
165
+ process.stdout.write(JSON.stringify(jsonOutput, null, 2) + '\n');
166
+ }
167
+ else if (!options.quiet || violations.length > 0) {
168
+ // Console output
169
+ console.log(chalk.blue('🔍 Diff-Scoped Code Audit'));
170
+ console.log(chalk.gray('══════════════════════════════════════════════════'));
171
+ console.log(chalk.gray(`Files analyzed: ${result.metadata.filesAnalyzed}`));
172
+ console.log(`\nFound ${violations.length} violations`);
173
+ console.log(`Critical: ${result.summary.criticalIssues}`);
174
+ console.log(`Warnings: ${result.summary.warnings}`);
175
+ console.log(`Suggestions: ${result.summary.suggestions}`);
176
+ if (violations.length > 0) {
177
+ console.log(chalk.gray('\n── Violations ────────────────────────────────────'));
178
+ for (const v of violations) {
179
+ const icon = v.severity === 'critical' ? '🔴' :
180
+ v.severity === 'warning' ? '🟡' : '🔵';
181
+ console.log(`${icon} ${chalk.bold(v.file)}${v.line ? `:${v.line}` : ''} [${v.severity}] ${v.message}`);
182
+ }
183
+ }
184
+ }
185
+ // Exit code based on --fail-on
186
+ if (failOnSeverity) {
187
+ const severityOrder = ['critical', 'warning', 'suggestion'];
188
+ const failIndex = severityOrder.indexOf(failOnSeverity);
189
+ const hasAtOrAbove = violations.some((v) => {
190
+ const vIndex = severityOrder.indexOf(v.severity);
191
+ return vIndex >= 0 && vIndex <= failIndex;
192
+ });
193
+ if (hasAtOrAbove) {
194
+ process.exit(2);
195
+ }
196
+ }
47
197
  }
48
198
  catch (error) {
49
199
  console.error(chalk.red('Error:'), error);
@@ -85,27 +235,226 @@ program
85
235
  console.log('Options:', options);
86
236
  // TODO: Implement server start
87
237
  });
88
- // Index command (placeholder - will be implemented later)
89
- program
90
- .command('index <path>')
91
- .description('Index a directory')
92
- .option('-p, --pattern <pattern>', 'File pattern', '**/*.{js,ts,jsx,tsx}')
93
- .action(async (path, options) => {
94
- console.log(chalk.yellow('Index command will be implemented in a future task'));
95
- console.log('Path:', path, 'Options:', options);
96
- // TODO: Implement indexing
238
+ // Index command
239
+ const indexCmd = program
240
+ .command('index')
241
+ .description('Manage the code index')
242
+ .action(() => {
243
+ console.log(chalk.yellow('Use an index subcommand:'));
244
+ console.log(chalk.gray(' code-audit index sync --path . Sync the index from source files'));
245
+ console.log(chalk.gray(' code-audit index cleanup Remove stale entries for deleted files'));
246
+ console.log(chalk.gray(' code-audit index reset Clear all analysis data'));
97
247
  });
98
- // Search command (placeholder - will be implemented later)
248
+ indexCmd
249
+ .command('sync')
250
+ .description('Synchronize index from source files')
251
+ .option('--path <path>', 'Path to a specific file or directory', process.cwd())
252
+ .option('--json', 'Output as JSON')
253
+ .action(async (options) => {
254
+ try {
255
+ await initParsers();
256
+ const db = CodeIndexDB.getInstance();
257
+ await db.initialize();
258
+ const targetPath = resolve(options.path || process.cwd());
259
+ const isSingleFile = (await fs.stat(targetPath).catch(() => null))?.isFile();
260
+ let result;
261
+ if (isSingleFile) {
262
+ result = await db.synchronizeFile(targetPath);
263
+ result = { mode: 'sync', success: true, path: targetPath, ...(result || { message: 'File not found' }) };
264
+ }
265
+ else {
266
+ const syncResult = await db.deepSync();
267
+ result = {
268
+ mode: 'sync',
269
+ success: true,
270
+ syncedFiles: syncResult.syncedFiles,
271
+ addedFunctions: syncResult.addedFunctions,
272
+ updatedFunctions: syncResult.updatedFunctions,
273
+ removedFunctions: syncResult.removedFunctions,
274
+ errors: syncResult.errors,
275
+ message: `Synced ${syncResult.syncedFiles} files: ${syncResult.addedFunctions} added, ${syncResult.updatedFunctions} updated, ${syncResult.removedFunctions} removed`,
276
+ };
277
+ }
278
+ if (options.json) {
279
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
280
+ }
281
+ else {
282
+ console.log(chalk.green(result.success ? '✓ Index sync complete' : '✗ Index sync failed'));
283
+ if (result.message)
284
+ console.log(chalk.gray(result.message));
285
+ }
286
+ }
287
+ catch (error) {
288
+ console.error(chalk.red('Error:'), error);
289
+ process.exit(1);
290
+ }
291
+ });
292
+ indexCmd
293
+ .command('cleanup')
294
+ .description('Remove index entries for deleted files')
295
+ .option('--json', 'Output as JSON')
296
+ .action(async (options) => {
297
+ try {
298
+ const db = CodeIndexDB.getInstance();
299
+ await db.initialize();
300
+ const result = await db.bulkCleanup();
301
+ if (options.json) {
302
+ process.stdout.write(JSON.stringify({ mode: 'cleanup', success: true, ...result }) + '\n');
303
+ }
304
+ else {
305
+ console.log(chalk.green('✓ Cleanup complete'));
306
+ console.log(chalk.gray(`Removed ${result.removedCount} entries from ${result.removedFiles.length} deleted files`));
307
+ }
308
+ }
309
+ catch (error) {
310
+ console.error(chalk.red('Error:'), error);
311
+ process.exit(1);
312
+ }
313
+ });
314
+ indexCmd
315
+ .command('reset')
316
+ .description('Clear all analysis data (preserves tasks, config, whitelist)')
317
+ .option('--json', 'Output as JSON')
318
+ .action(async (options) => {
319
+ try {
320
+ const db = CodeIndexDB.getInstance();
321
+ await db.initialize();
322
+ await db.clearIndex();
323
+ if (options.json) {
324
+ process.stdout.write(JSON.stringify({ mode: 'reset', success: true, message: 'All analysis data cleared' }) + '\n');
325
+ }
326
+ else {
327
+ console.log(chalk.green('✓ Index reset complete'));
328
+ console.log(chalk.gray('All analysis-derived data cleared (tasks, config, and whitelist preserved)'));
329
+ }
330
+ }
331
+ catch (error) {
332
+ console.error(chalk.red('Error:'), error);
333
+ process.exit(1);
334
+ }
335
+ });
336
+ // Config command
337
+ const configCmd = program
338
+ .command('config')
339
+ .description('Manage analyzer configuration and invariant rules')
340
+ .action(() => {
341
+ console.log(chalk.yellow('Use a config subcommand:'));
342
+ console.log(chalk.gray(' code-audit config rules-list List invariant rules from .codeauditor.json'));
343
+ console.log(chalk.gray(' code-audit config rules-check Validate .codeauditor.json rules'));
344
+ });
345
+ configCmd
346
+ .command('rules-list')
347
+ .description('List all configured invariant rules from .codeauditor.json')
348
+ .option('--config-path <path>', 'Path to .codeauditor.json')
349
+ .option('--json', 'Output as JSON')
350
+ .action(async (options) => {
351
+ try {
352
+ const pathModule = await import('path');
353
+ const { readFileSync } = await import('fs');
354
+ const configPath = options.configPath ||
355
+ pathModule.join(process.cwd(), '.codeauditor.json');
356
+ try {
357
+ const raw = readFileSync(configPath, 'utf-8');
358
+ const config = JSON.parse(raw);
359
+ const rules = config?.rules ?? [];
360
+ if (options.json) {
361
+ process.stdout.write(JSON.stringify({
362
+ rules: rules.map((r) => ({ id: r.id, kind: r.kind, severity: r.severity, message: r.message || null })),
363
+ count: rules.length,
364
+ configPath,
365
+ }, null, 2) + '\n');
366
+ }
367
+ else {
368
+ if (rules.length === 0) {
369
+ console.log(chalk.yellow(`No rules found in ${configPath}`));
370
+ }
371
+ else {
372
+ console.log(chalk.blue(`\n${rules.length} rule(s) in ${configPath}`));
373
+ console.log(chalk.gray('──────────────────────────────────────────'));
374
+ for (const r of rules) {
375
+ const sevIcon = r.severity === 'critical' ? '🔴' : r.severity === 'warning' ? '🟡' : '🔵';
376
+ console.log(`${sevIcon} ${chalk.bold(r.id)} [${r.kind}] ${chalk.dim(r.severity)}`);
377
+ if (r.message)
378
+ console.log(` ${r.message}`);
379
+ }
380
+ }
381
+ }
382
+ }
383
+ catch (err) {
384
+ console.error(chalk.red(`Failed to read rules: ${err.message}`));
385
+ process.exit(1);
386
+ }
387
+ }
388
+ catch (error) {
389
+ console.error(chalk.red('Error:'), error);
390
+ process.exit(1);
391
+ }
392
+ });
393
+ configCmd
394
+ .command('rules-check')
395
+ .description('Validate the current .codeauditor.json rules')
396
+ .option('--config-path <path>', 'Path to .codeauditor.json')
397
+ .option('--json', 'Output as JSON')
398
+ .action(async (options) => {
399
+ try {
400
+ const pathModule = await import('path');
401
+ const { readFileSync } = await import('fs');
402
+ const { validateRulesConfig } = await import('./invariants/ruleValidator.js');
403
+ const configPath = options.configPath ||
404
+ pathModule.join(process.cwd(), '.codeauditor.json');
405
+ try {
406
+ const raw = readFileSync(configPath, 'utf-8');
407
+ const config = JSON.parse(raw);
408
+ const rulesArray = config?.rules;
409
+ const errors = validateRulesConfig({ rules: rulesArray ?? [] });
410
+ if (options.json) {
411
+ process.stdout.write(JSON.stringify({
412
+ valid: errors.length === 0,
413
+ errors: errors.map(e => ({ ruleId: e.ruleId || null, message: e.message })),
414
+ configPath,
415
+ }, null, 2) + '\n');
416
+ }
417
+ else {
418
+ if (errors.length === 0) {
419
+ console.log(chalk.green(`✓ All rules valid (${configPath})`));
420
+ }
421
+ else {
422
+ console.log(chalk.red(`✗ ${errors.length} validation error(s) in ${configPath}`));
423
+ console.log(chalk.gray('──────────────────────────────────────────'));
424
+ for (const e of errors) {
425
+ const id = e.ruleId ? chalk.bold(e.ruleId) + ': ' : '';
426
+ console.log(` ${id}${chalk.red(e.message)}`);
427
+ }
428
+ }
429
+ }
430
+ }
431
+ catch (err) {
432
+ console.error(chalk.red(`Failed to read/parse config: ${err.message}`));
433
+ process.exit(1);
434
+ }
435
+ }
436
+ catch (error) {
437
+ console.error(chalk.red('Error:'), error);
438
+ process.exit(1);
439
+ }
440
+ });
441
+ // Search command
99
442
  program
100
443
  .command('search <query>')
101
- .description('Search the code index')
102
- .option('-f, --fuzzy', 'Use fuzzy search', true)
103
- .option('-t, --type <type>', 'Symbol type filter')
444
+ .description('Search the code index with operator syntax: calls:<fn>, dep:<module>, lang:<lang>, complexity:>N, etc.')
104
445
  .option('-l, --limit <limit>', 'Result limit', '20')
446
+ .option('--language <lang>', 'Filter by language (typescript, javascript, go)')
447
+ .option('--json', 'Output results as JSON')
448
+ .option('--definition', 'Look up a specific symbol definition by name')
105
449
  .action(async (query, options) => {
106
- console.log(chalk.yellow('Search command will be implemented in a future task'));
107
- console.log('Query:', query, 'Options:', options);
108
- // TODO: Implement search
450
+ try {
451
+ await initParsers();
452
+ await runSearch(query, options);
453
+ }
454
+ catch (error) {
455
+ console.error(chalk.red('Error:'), error);
456
+ process.exit(1);
457
+ }
109
458
  });
110
459
  // Test command (placeholder - will be implemented later)
111
460
  program
@@ -142,6 +491,285 @@ program
142
491
  process.exit(1);
143
492
  }
144
493
  });
494
+ // Tasks command — thin adapter over MCP service layer
495
+ const tasksCmd = program
496
+ .command('tasks')
497
+ .description('Manage the per-project task queue')
498
+ .action(() => {
499
+ console.log(chalk.yellow('Use a tasks subcommand: list, create, get, update, complete, delete, from-audit'));
500
+ console.log(chalk.gray(' code-audit tasks list List all tasks'));
501
+ console.log(chalk.gray(' code-audit tasks create --title "Fix SQL injection"'));
502
+ console.log(chalk.gray(' code-audit tasks get <taskId> Get task details'));
503
+ console.log(chalk.gray(' code-audit tasks update <taskId> --status in_progress'));
504
+ console.log(chalk.gray(' code-audit tasks complete <taskId> Mark task done'));
505
+ console.log(chalk.gray(' code-audit tasks delete <taskId> Delete a task'));
506
+ console.log(chalk.gray(' code-audit tasks from-audit Create tasks from audit violations'));
507
+ });
508
+ tasksCmd
509
+ .command('list')
510
+ .description('List project tasks')
511
+ .option('--status <status>', 'Filter by status (open, in_progress, completed)')
512
+ .option('--source <source>', 'Filter by source (manual, audit)')
513
+ .option('--priority <priority>', 'Filter by priority (low, medium, high)')
514
+ .option('--label <label>', 'Filter by label')
515
+ .option('--limit <limit>', 'Result limit', '50')
516
+ .option('--json', 'Output as JSON')
517
+ .action(async (options) => {
518
+ try {
519
+ const args = { action: 'list' };
520
+ if (options.status)
521
+ args.status = options.status;
522
+ if (options.source)
523
+ args.source = options.source;
524
+ if (options.priority)
525
+ args.priority = options.priority;
526
+ if (options.label)
527
+ args.label = options.label;
528
+ if (options.limit)
529
+ args.limit = parseInt(options.limit, 10);
530
+ const { handleProjectTasks } = await import('./mcp-tools/projectTasks.js');
531
+ const result = await handleProjectTasks(args);
532
+ if (options.json) {
533
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
534
+ }
535
+ else if (result.success) {
536
+ const tasks = result.tasks || [];
537
+ if (tasks.length === 0) {
538
+ console.log(chalk.yellow('No tasks found.'));
539
+ }
540
+ else {
541
+ for (const t of tasks) {
542
+ const icon = t.status === 'completed' ? '✅' : t.status === 'in_progress' ? '🔄' : '📋';
543
+ const priority = t.priority ? chalk.dim(` [${t.priority}]`) : '';
544
+ console.log(`${icon} ${chalk.bold(t.title ?? t.id)}${priority}`);
545
+ if (t.description)
546
+ console.log(chalk.dim(` ${t.description}`));
547
+ }
548
+ }
549
+ }
550
+ else {
551
+ console.error(chalk.red(result.error || 'Unknown error'));
552
+ process.exit(1);
553
+ }
554
+ }
555
+ catch (error) {
556
+ console.error(chalk.red('Error:'), error);
557
+ process.exit(1);
558
+ }
559
+ });
560
+ tasksCmd
561
+ .command('create')
562
+ .description('Create a project task')
563
+ .requiredOption('--title <title>', 'Task title')
564
+ .option('--description <description>', 'Task description')
565
+ .option('--priority <priority>', 'Priority (low, medium, high)')
566
+ .option('--status <status>', 'Status (open, in_progress)')
567
+ .option('--labels <labels>', 'Comma-separated labels')
568
+ .option('--json', 'Output as JSON')
569
+ .action(async (options) => {
570
+ try {
571
+ const args = {
572
+ action: 'create',
573
+ title: options.title,
574
+ };
575
+ if (options.description)
576
+ args.description = options.description;
577
+ if (options.priority)
578
+ args.priority = options.priority;
579
+ if (options.status)
580
+ args.status = options.status;
581
+ if (options.labels)
582
+ args.labels = options.labels.split(',').map((s) => s.trim());
583
+ const { handleProjectTasks } = await import('./mcp-tools/projectTasks.js');
584
+ const result = await handleProjectTasks(args);
585
+ if (options.json) {
586
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
587
+ }
588
+ else if (result.success) {
589
+ const task = result.task || {};
590
+ console.log(chalk.green(`✓ Task created: ${task.title || task.taskId || 'unknown'}`));
591
+ }
592
+ else {
593
+ console.error(chalk.red(result.error || 'Unknown error'));
594
+ process.exit(1);
595
+ }
596
+ }
597
+ catch (error) {
598
+ console.error(chalk.red('Error:'), error);
599
+ process.exit(1);
600
+ }
601
+ });
602
+ tasksCmd
603
+ .command('get <taskId>')
604
+ .description('Get a task by ID')
605
+ .option('--json', 'Output as JSON')
606
+ .action(async (taskId, options) => {
607
+ try {
608
+ const { handleProjectTasks } = await import('./mcp-tools/projectTasks.js');
609
+ const result = await handleProjectTasks({ action: 'get', taskId });
610
+ if (options.json) {
611
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
612
+ }
613
+ else if (result.success) {
614
+ const t = result.task;
615
+ console.log(chalk.blue(`\nTask: ${t.title}`));
616
+ console.log(chalk.gray('──────────────────────────────────────────'));
617
+ console.log(`${chalk.bold('ID:')} ${t.id}`);
618
+ console.log(`${chalk.bold('Status:')} ${t.status}`);
619
+ if (t.priority)
620
+ console.log(`${chalk.bold('Priority:')} ${t.priority}`);
621
+ if (t.description)
622
+ console.log(`${chalk.bold('Description:')}\n${t.description}`);
623
+ if (t.labels?.length)
624
+ console.log(`${chalk.bold('Labels:')} ${t.labels.join(', ')}`);
625
+ if (t.relatedFiles?.length)
626
+ console.log(`${chalk.bold('Files:')} ${t.relatedFiles.join(', ')}`);
627
+ if (t.fingerprint)
628
+ console.log(chalk.dim(`\nfingerprint: ${t.fingerprint}`));
629
+ }
630
+ else {
631
+ console.error(chalk.red(result.error || 'Unknown error'));
632
+ process.exit(1);
633
+ }
634
+ }
635
+ catch (error) {
636
+ console.error(chalk.red('Error:'), error);
637
+ process.exit(1);
638
+ }
639
+ });
640
+ tasksCmd
641
+ .command('update <taskId>')
642
+ .description('Update a task')
643
+ .option('--title <title>', 'New title')
644
+ .option('--description <description>', 'New description')
645
+ .option('--status <status>', 'New status (open, in_progress, completed)')
646
+ .option('--priority <priority>', 'New priority (low, medium, high)')
647
+ .option('--labels <labels>', 'Comma-separated labels')
648
+ .option('--json', 'Output as JSON')
649
+ .action(async (taskId, options) => {
650
+ try {
651
+ const patch = {};
652
+ if (options.title)
653
+ patch.title = options.title;
654
+ if (options.description)
655
+ patch.description = options.description;
656
+ if (options.status)
657
+ patch.status = options.status;
658
+ if (options.priority)
659
+ patch.priority = options.priority;
660
+ if (options.labels)
661
+ patch.labels = options.labels.split(',').map((s) => s.trim());
662
+ if (Object.keys(patch).length === 0) {
663
+ console.error(chalk.yellow('No update fields provided. Use --title, --description, --status, --priority, or --labels.'));
664
+ process.exit(1);
665
+ }
666
+ const { handleProjectTasks } = await import('./mcp-tools/projectTasks.js');
667
+ const result = await handleProjectTasks({ action: 'update', taskId, patch });
668
+ if (options.json) {
669
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
670
+ }
671
+ else if (result.success) {
672
+ console.log(chalk.green(`✓ Task updated`));
673
+ }
674
+ else {
675
+ console.error(chalk.red(result.error || 'Unknown error'));
676
+ process.exit(1);
677
+ }
678
+ }
679
+ catch (error) {
680
+ console.error(chalk.red('Error:'), error);
681
+ process.exit(1);
682
+ }
683
+ });
684
+ tasksCmd
685
+ .command('complete <taskId>')
686
+ .description('Mark a task as completed')
687
+ .option('--json', 'Output as JSON')
688
+ .action(async (taskId, options) => {
689
+ try {
690
+ const { handleProjectTasks } = await import('./mcp-tools/projectTasks.js');
691
+ const result = await handleProjectTasks({ action: 'complete_task', taskId });
692
+ if (options.json) {
693
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
694
+ }
695
+ else if (result.success) {
696
+ console.log(chalk.green(`✓ Task completed`));
697
+ }
698
+ else {
699
+ console.error(chalk.red(result.error || 'Unknown error'));
700
+ process.exit(1);
701
+ }
702
+ }
703
+ catch (error) {
704
+ console.error(chalk.red('Error:'), error);
705
+ process.exit(1);
706
+ }
707
+ });
708
+ tasksCmd
709
+ .command('delete <taskId>')
710
+ .description('Delete a task')
711
+ .option('--json', 'Output as JSON')
712
+ .action(async (taskId, options) => {
713
+ try {
714
+ const { handleProjectTasks } = await import('./mcp-tools/projectTasks.js');
715
+ const result = await handleProjectTasks({ action: 'delete', taskId });
716
+ if (options.json) {
717
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
718
+ }
719
+ else if (result.success) {
720
+ console.log(chalk.green(`✓ Task deleted`));
721
+ }
722
+ else {
723
+ console.error(chalk.red(result.error || 'Unknown error'));
724
+ process.exit(1);
725
+ }
726
+ }
727
+ catch (error) {
728
+ console.error(chalk.red('Error:'), error);
729
+ process.exit(1);
730
+ }
731
+ });
732
+ tasksCmd
733
+ .command('from-audit')
734
+ .description('Populate tasks from audit violations')
735
+ .option('--auditJobId <id>', 'Specific audit result ID')
736
+ .option('--severities <severities>', 'Comma-separated severities (critical,warning,suggestion)', 'critical,warning')
737
+ .option('--json', 'Output as JSON')
738
+ .action(async (options) => {
739
+ try {
740
+ const args = { action: 'from_audit' };
741
+ if (options.auditJobId)
742
+ args.auditJobId = options.auditJobId;
743
+ if (options.severities)
744
+ args.severities = options.severities.split(',').map((s) => s.trim());
745
+ const { handleProjectTasks } = await import('./mcp-tools/projectTasks.js');
746
+ const result = await handleProjectTasks(args);
747
+ if (options.json) {
748
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
749
+ }
750
+ else if (result.success) {
751
+ const r = result;
752
+ console.log(chalk.green(`✓ Created ${r.created || 0} task(s), skipped ${r.skipped || 0} (duplicates)`));
753
+ if (r.tasks?.length) {
754
+ for (const t of r.tasks) {
755
+ console.log(` 📋 ${chalk.bold(t.title)}`);
756
+ }
757
+ }
758
+ }
759
+ else if (result.error === 'No audit results found. Run an audit first, or provide an auditJobId.') {
760
+ // Not a real error — just nothing to convert. Exit 0 so scripts don't break.
761
+ console.log(chalk.yellow(result.error));
762
+ }
763
+ else {
764
+ console.error(chalk.red(result.error || 'Unknown error'));
765
+ process.exit(1);
766
+ }
767
+ }
768
+ catch (error) {
769
+ console.error(chalk.red('Error:'), error);
770
+ process.exit(1);
771
+ }
772
+ });
145
773
  // Parse command line arguments
146
774
  program.parse(process.argv);
147
775
  // If no command was provided, show help
@@ -335,7 +963,8 @@ async function generateCodeMap(options) {
335
963
  console.log(chalk.gray(` • Functions found: ${codeMap.stats.totalFunctions}`));
336
964
  console.log(chalk.gray(` • Components found: ${codeMap.stats.totalComponents}`));
337
965
  if (documentation) {
338
- console.log(chalk.gray(` • Documentation coverage: ${documentation.coverageScore}%`));
966
+ const docMetrics = documentation;
967
+ console.log(chalk.gray(` • Documentation coverage: ${docMetrics.coverageScore}%`));
339
968
  }
340
969
  }
341
970
  else {
@@ -357,4 +986,97 @@ async function generateCodeMap(options) {
357
986
  }
358
987
  }
359
988
  }
989
+ /**
990
+ * Run a search query against the code index.
991
+ */
992
+ async function runSearch(query, options) {
993
+ const limit = parseInt(options.limit || '20', 10);
994
+ const db = CodeIndexDB.getInstance();
995
+ await db.initialize();
996
+ // --definition: look up a specific symbol
997
+ if (options.definition) {
998
+ const func = await db.findDefinition(query);
999
+ if (!func) {
1000
+ console.log(chalk.yellow(`No definition found for "${query}"`));
1001
+ return;
1002
+ }
1003
+ if (options.json) {
1004
+ process.stdout.write(JSON.stringify(func, null, 2) + '\n');
1005
+ }
1006
+ else {
1007
+ console.log(chalk.blue(`\nDefinition: ${func.name}`));
1008
+ console.log(chalk.gray('──────────────────────────────────────────'));
1009
+ console.log(`${chalk.bold('File:')} ${func.filePath}${func.lineNumber ? `:${func.lineNumber}` : ''}`);
1010
+ if (func.signature) {
1011
+ console.log(`${chalk.bold('Signature:')} ${func.signature}`);
1012
+ }
1013
+ if (func.purpose) {
1014
+ console.log(`${chalk.bold('Purpose:')} ${func.purpose}`);
1015
+ }
1016
+ if (func.language) {
1017
+ console.log(`${chalk.bold('Language:')} ${func.language}`);
1018
+ }
1019
+ if (func.dependencies?.length) {
1020
+ console.log(`${chalk.bold('Dependencies:')} ${func.dependencies.join(', ')}`);
1021
+ }
1022
+ if (func.jsDoc) {
1023
+ console.log(`${chalk.bold('JSDoc:')} ${func.jsDoc}`);
1024
+ }
1025
+ }
1026
+ return;
1027
+ }
1028
+ // Full search: parse the query, build SearchOptions, run search
1029
+ const parsed = queryParser.parse(query);
1030
+ const searchOptions = {
1031
+ query,
1032
+ parsedQuery: parsed,
1033
+ limit,
1034
+ offset: 0,
1035
+ searchStrategy: parsed.fuzzy ? 'fuzzy' : 'exact',
1036
+ };
1037
+ // Apply --language filter
1038
+ if (options.language) {
1039
+ if (!searchOptions.filters) {
1040
+ searchOptions.filters = {};
1041
+ }
1042
+ searchOptions.filters.language = options.language;
1043
+ }
1044
+ const result = await db.searchFunctions(searchOptions);
1045
+ if (options.json) {
1046
+ process.stdout.write(JSON.stringify({
1047
+ query,
1048
+ totalCount: result.totalCount,
1049
+ executionTime: result.executionTime,
1050
+ functions: result.functions,
1051
+ }, null, 2) + '\n');
1052
+ }
1053
+ else {
1054
+ console.log(chalk.blue(`\nSearch: "${query}"`));
1055
+ console.log(chalk.gray('──────────────────────────────────────────'));
1056
+ console.log(chalk.gray(`Found ${result.totalCount} result${result.totalCount !== 1 ? 's' : ''} in ${result.executionTime}ms`));
1057
+ console.log('');
1058
+ if (result.functions.length === 0) {
1059
+ console.log(chalk.yellow('No results found.'));
1060
+ console.log(chalk.gray('Tip: Run an audit first if the index is empty: code-audit audit'));
1061
+ }
1062
+ else {
1063
+ for (const func of result.functions) {
1064
+ const lang = func.language ? chalk.dim(` [${func.language}]`) : '';
1065
+ const lineInfo = func.lineNumber ? chalk.dim(`:${func.lineNumber}`) : '';
1066
+ console.log(`${chalk.bold(func.name)}${lang} — ${chalk.green(func.filePath)}${lineInfo}`);
1067
+ if (func.signature) {
1068
+ console.log(chalk.dim(` ${func.signature}`));
1069
+ }
1070
+ if (func.purpose) {
1071
+ console.log(chalk.dim(` ${func.purpose}`));
1072
+ }
1073
+ // Show score for relevance-sorted results
1074
+ if (func.score) {
1075
+ console.log(chalk.dim(` score: ${func.score.toFixed(2)}`));
1076
+ }
1077
+ console.log('');
1078
+ }
1079
+ }
1080
+ }
1081
+ }
360
1082
  //# sourceMappingURL=cli.js.map