code-auditor-mcp 5.0.2 → 5.2.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 (336) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +184 -3
  3. package/README.md +24 -2
  4. package/configs/hhra-compat.json +12 -118
  5. package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -1
  6. package/dist/analyzers/cross-language/DependencyGraphBuilder.js +11 -1
  7. package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -1
  8. package/dist/analyzers/crossDomain/CrossDomainAnalyzer.d.ts.map +1 -1
  9. package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js +57 -52
  10. package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js.map +1 -1
  11. package/dist/analyzers/provenance.d.ts +9 -4
  12. package/dist/analyzers/provenance.d.ts.map +1 -1
  13. package/dist/analyzers/provenance.js +8 -25
  14. package/dist/analyzers/provenance.js.map +1 -1
  15. package/dist/analyzers/reactAnalyzer.d.ts.map +1 -1
  16. package/dist/analyzers/reactAnalyzer.js +0 -5
  17. package/dist/analyzers/reactAnalyzer.js.map +1 -1
  18. package/dist/analyzers/ruleRegistry.js +4 -4
  19. package/dist/analyzers/ruleRegistry.js.map +1 -1
  20. package/dist/analyzers/ruleTiming.d.ts +1 -1
  21. package/dist/analyzers/ruleTiming.js +2 -2
  22. package/dist/analyzers/ruleTiming.js.map +1 -1
  23. package/dist/analyzers/universal/UniversalConventionsAnalyzer.d.ts.map +1 -1
  24. package/dist/analyzers/universal/UniversalConventionsAnalyzer.js +22 -26
  25. package/dist/analyzers/universal/UniversalConventionsAnalyzer.js.map +1 -1
  26. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +32 -15
  27. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
  28. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +189 -115
  29. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
  30. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts +0 -2
  31. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -1
  32. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +0 -5
  33. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -1
  34. package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts +2 -10
  35. package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts.map +1 -1
  36. package/dist/analyzers/universal/UniversalStylesAnalyzer.js +7 -49
  37. package/dist/analyzers/universal/UniversalStylesAnalyzer.js.map +1 -1
  38. package/dist/analyzers/universal/schema/config.d.ts.map +1 -1
  39. package/dist/analyzers/universal/schema/config.js +0 -2
  40. package/dist/analyzers/universal/schema/config.js.map +1 -1
  41. package/dist/analyzers/universal/schema/types.d.ts +0 -2
  42. package/dist/analyzers/universal/schema/types.d.ts.map +1 -1
  43. package/dist/analyzers/vendorSurfaces.d.ts +126 -0
  44. package/dist/analyzers/vendorSurfaces.d.ts.map +1 -0
  45. package/dist/analyzers/vendorSurfaces.js +580 -0
  46. package/dist/analyzers/vendorSurfaces.js.map +1 -0
  47. package/dist/auditRunner.d.ts.map +1 -1
  48. package/dist/auditRunner.js +136 -142
  49. package/dist/auditRunner.js.map +1 -1
  50. package/dist/churn/churnExtractor.d.ts +0 -1
  51. package/dist/churn/churnExtractor.d.ts.map +1 -1
  52. package/dist/churn/churnExtractor.js +2 -4
  53. package/dist/churn/churnExtractor.js.map +1 -1
  54. package/dist/cli.d.ts +1 -1
  55. package/dist/cli.d.ts.map +1 -1
  56. package/dist/cli.js +195 -26
  57. package/dist/cli.js.map +1 -1
  58. package/dist/codeIndex/migrations.d.ts.map +1 -1
  59. package/dist/codeIndex/migrations.js +4 -3
  60. package/dist/codeIndex/migrations.js.map +1 -1
  61. package/dist/codeIndexDB.d.ts +11 -2
  62. package/dist/codeIndexDB.d.ts.map +1 -1
  63. package/dist/codeIndexDB.js +27 -2
  64. package/dist/codeIndexDB.js.map +1 -1
  65. package/dist/config/configLoader.d.ts +60 -7
  66. package/dist/config/configLoader.d.ts.map +1 -1
  67. package/dist/config/configLoader.js +252 -60
  68. package/dist/config/configLoader.js.map +1 -1
  69. package/dist/config/defaults.d.ts +77 -18
  70. package/dist/config/defaults.d.ts.map +1 -1
  71. package/dist/config/defaults.js +105 -43
  72. package/dist/config/defaults.js.map +1 -1
  73. package/dist/constants.d.ts +2 -1
  74. package/dist/constants.d.ts.map +1 -1
  75. package/dist/constants.js +4 -0
  76. package/dist/constants.js.map +1 -1
  77. package/dist/daemon/main.d.ts +0 -1
  78. package/dist/daemon/main.d.ts.map +1 -1
  79. package/dist/daemon/main.js +11 -4
  80. package/dist/daemon/main.js.map +1 -1
  81. package/dist/dataPaths.d.ts +17 -11
  82. package/dist/dataPaths.d.ts.map +1 -1
  83. package/dist/dataPaths.js +51 -16
  84. package/dist/dataPaths.js.map +1 -1
  85. package/dist/hookLog.d.ts +54 -0
  86. package/dist/hookLog.d.ts.map +1 -0
  87. package/dist/hookLog.js +105 -0
  88. package/dist/hookLog.js.map +1 -0
  89. package/dist/hookLogPath.generated.d.ts +3 -0
  90. package/dist/hookLogPath.generated.d.ts.map +1 -0
  91. package/dist/hookLogPath.generated.js +8 -0
  92. package/dist/hookLogPath.generated.js.map +1 -0
  93. package/dist/index.d.ts +0 -5
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +0 -7
  96. package/dist/index.js.map +1 -1
  97. package/dist/installConfig.d.ts +15 -2
  98. package/dist/installConfig.d.ts.map +1 -1
  99. package/dist/installConfig.js +17 -2
  100. package/dist/installConfig.js.map +1 -1
  101. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -1
  102. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +18 -3
  103. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -1
  104. package/dist/mcp-tools/workflowGuide.js +8 -8
  105. package/dist/mcp-tools/workflowGuide.js.map +1 -1
  106. package/dist/mcp-tools-shared.d.ts.map +1 -1
  107. package/dist/mcp-tools-shared.js +5 -2
  108. package/dist/mcp-tools-shared.js.map +1 -1
  109. package/dist/mcp-ui-simple.d.ts +5 -0
  110. package/dist/mcp-ui-simple.d.ts.map +1 -1
  111. package/dist/mcp-ui-simple.js +9 -2
  112. package/dist/mcp-ui-simple.js.map +1 -1
  113. package/dist/mcp.d.ts +0 -1
  114. package/dist/mcp.d.ts.map +1 -1
  115. package/dist/mcp.js +36 -33
  116. package/dist/mcp.js.map +1 -1
  117. package/dist/mcpAuditJobs.d.ts +10 -0
  118. package/dist/mcpAuditJobs.d.ts.map +1 -1
  119. package/dist/mcpAuditJobs.js +10 -1
  120. package/dist/mcpAuditJobs.js.map +1 -1
  121. package/dist/mcpAutoIndex.d.ts.map +1 -1
  122. package/dist/mcpAutoIndex.js +2 -1
  123. package/dist/mcpAutoIndex.js.map +1 -1
  124. package/dist/phase/colorMath.d.ts +18 -5
  125. package/dist/phase/colorMath.d.ts.map +1 -1
  126. package/dist/phase/colorMath.js +88 -5
  127. package/dist/phase/colorMath.js.map +1 -1
  128. package/dist/phase/dataAccessCallsCandidates.js +1 -1
  129. package/dist/phase/dataAccessCallsCandidates.js.map +1 -1
  130. package/dist/phase/goFunctionAnalysis.d.ts +2 -2
  131. package/dist/phase/goFunctionAnalysis.js +2 -2
  132. package/dist/phase/goFunctions.d.ts +2 -2
  133. package/dist/phase/goFunctions.js +2 -2
  134. package/dist/phase/goImports.d.ts +2 -2
  135. package/dist/phase/goImports.js +2 -2
  136. package/dist/phase/goSwitches.d.ts +2 -2
  137. package/dist/phase/goSwitches.js +2 -2
  138. package/dist/phase/loopQueryCandidates.js +1 -1
  139. package/dist/phase/loopQueryCandidates.js.map +1 -1
  140. package/dist/phase/phaseModel.d.ts +37 -8
  141. package/dist/phase/phaseModel.d.ts.map +1 -1
  142. package/dist/phase/phaseModel.js +33 -8
  143. package/dist/phase/phaseModel.js.map +1 -1
  144. package/dist/phase/producers.d.ts.map +1 -1
  145. package/dist/phase/producers.js +24 -17
  146. package/dist/phase/producers.js.map +1 -1
  147. package/dist/phase/reachability.d.ts +44 -1
  148. package/dist/phase/reachability.d.ts.map +1 -1
  149. package/dist/phase/reachability.js +79 -0
  150. package/dist/phase/reachability.js.map +1 -1
  151. package/dist/phase/rules/crossDomain.d.ts.map +1 -1
  152. package/dist/phase/rules/crossDomain.js +16 -6
  153. package/dist/phase/rules/crossDomain.js.map +1 -1
  154. package/dist/phase/rules/dry.d.ts.map +1 -1
  155. package/dist/phase/rules/dry.js +0 -1
  156. package/dist/phase/rules/dry.js.map +1 -1
  157. package/dist/phase/rules/goRules.d.ts +2 -2
  158. package/dist/phase/rules/goRules.js +2 -2
  159. package/dist/phase/rules/secrets.d.ts +22 -8
  160. package/dist/phase/rules/secrets.d.ts.map +1 -1
  161. package/dist/phase/rules/secrets.js +48 -67
  162. package/dist/phase/rules/secrets.js.map +1 -1
  163. package/dist/phase/rules/styles.d.ts +23 -9
  164. package/dist/phase/rules/styles.d.ts.map +1 -1
  165. package/dist/phase/rules/styles.js +47 -15
  166. package/dist/phase/rules/styles.js.map +1 -1
  167. package/dist/phase/rules/unreferencedModule.d.ts.map +1 -1
  168. package/dist/phase/rules/unreferencedModule.js +16 -5
  169. package/dist/phase/rules/unreferencedModule.js.map +1 -1
  170. package/dist/phase/runner.d.ts +16 -7
  171. package/dist/phase/runner.d.ts.map +1 -1
  172. package/dist/phase/runner.js +32 -20
  173. package/dist/phase/runner.js.map +1 -1
  174. package/dist/phase/stylesCss.d.ts.map +1 -1
  175. package/dist/phase/stylesCss.js +4 -0
  176. package/dist/phase/stylesCss.js.map +1 -1
  177. package/dist/phase/stylesMarkup.d.ts.map +1 -1
  178. package/dist/phase/stylesMarkup.js +4 -0
  179. package/dist/phase/stylesMarkup.js.map +1 -1
  180. package/dist/phase/stylesSource.d.ts.map +1 -1
  181. package/dist/phase/stylesSource.js +6 -0
  182. package/dist/phase/stylesSource.js.map +1 -1
  183. package/dist/phase/testProgram.d.ts +57 -0
  184. package/dist/phase/testProgram.d.ts.map +1 -0
  185. package/dist/phase/testProgram.js +244 -0
  186. package/dist/phase/testProgram.js.map +1 -0
  187. package/dist/phase/typeDeclarations.d.ts +2 -2
  188. package/dist/phase/typeDeclarations.js +2 -2
  189. package/dist/phase/types.d.ts +46 -0
  190. package/dist/phase/types.d.ts.map +1 -1
  191. package/dist/pipelineAdapters.d.ts +1 -171
  192. package/dist/pipelineAdapters.d.ts.map +1 -1
  193. package/dist/pipelineAdapters.js +47 -1281
  194. package/dist/pipelineAdapters.js.map +1 -1
  195. package/dist/reporting/csvReportGenerator.d.ts.map +1 -1
  196. package/dist/reporting/csvReportGenerator.js +0 -6
  197. package/dist/reporting/csvReportGenerator.js.map +1 -1
  198. package/dist/reporting/htmlReportGenerator.d.ts.map +1 -1
  199. package/dist/reporting/htmlReportGenerator.js +0 -4
  200. package/dist/reporting/htmlReportGenerator.js.map +1 -1
  201. package/dist/reporting/jsonReportGenerator.d.ts.map +1 -1
  202. package/dist/reporting/jsonReportGenerator.js +0 -1
  203. package/dist/reporting/jsonReportGenerator.js.map +1 -1
  204. package/dist/reporting/sarifReportGenerator.d.ts.map +1 -1
  205. package/dist/reporting/sarifReportGenerator.js +0 -7
  206. package/dist/reporting/sarifReportGenerator.js.map +1 -1
  207. package/dist/sqlite/driver.d.ts +17 -1
  208. package/dist/sqlite/driver.d.ts.map +1 -1
  209. package/dist/sqlite/driver.js +28 -5
  210. package/dist/sqlite/driver.js.map +1 -1
  211. package/dist/styles/cssInJsHarvest.d.ts +36 -0
  212. package/dist/styles/cssInJsHarvest.d.ts.map +1 -0
  213. package/dist/styles/cssInJsHarvest.js +78 -0
  214. package/dist/styles/cssInJsHarvest.js.map +1 -0
  215. package/dist/styles/definedClasses.d.ts +95 -0
  216. package/dist/styles/definedClasses.d.ts.map +1 -0
  217. package/dist/styles/definedClasses.js +129 -0
  218. package/dist/styles/definedClasses.js.map +1 -0
  219. package/dist/styles/markupStyleHarvest.d.ts +33 -0
  220. package/dist/styles/markupStyleHarvest.d.ts.map +1 -0
  221. package/dist/styles/markupStyleHarvest.js +73 -0
  222. package/dist/styles/markupStyleHarvest.js.map +1 -0
  223. package/dist/styles/styleExtractor.d.ts +37 -0
  224. package/dist/styles/styleExtractor.d.ts.map +1 -1
  225. package/dist/styles/styleExtractor.js +89 -33
  226. package/dist/styles/styleExtractor.js.map +1 -1
  227. package/dist/styles/styleIndexer.d.ts.map +1 -1
  228. package/dist/styles/styleIndexer.js +11 -10
  229. package/dist/styles/styleIndexer.js.map +1 -1
  230. package/dist/styles/tailwindExpander.d.ts.map +1 -1
  231. package/dist/styles/tailwindExpander.js +31 -10
  232. package/dist/styles/tailwindExpander.js.map +1 -1
  233. package/dist/telemetry.d.ts +67 -1
  234. package/dist/telemetry.d.ts.map +1 -1
  235. package/dist/telemetry.js +100 -20
  236. package/dist/telemetry.js.map +1 -1
  237. package/dist/types/crossLanguage.d.ts +1 -0
  238. package/dist/types/crossLanguage.d.ts.map +1 -1
  239. package/dist/types.d.ts +23 -56
  240. package/dist/types.d.ts.map +1 -1
  241. package/dist/types.js +4 -4
  242. package/dist/types.js.map +1 -1
  243. package/dist/version.generated.d.ts +1 -1
  244. package/dist/version.generated.js +1 -1
  245. package/examples/.auditrc.example.json +7 -22
  246. package/examples/.auditrc.json +12 -155
  247. package/examples/.code-auditor.json +8 -51
  248. package/examples/nextjs.auditrc.json +7 -34
  249. package/examples/node-api.auditrc.json +6 -46
  250. package/examples/react.auditrc.json +8 -25
  251. package/examples/tolerant-solid.auditrc.json +12 -44
  252. package/package.json +6 -5
  253. package/plugin/.claude-plugin/manifest.json +10 -9
  254. package/plugin/.claude-plugin/plugin.json +1 -1
  255. package/plugin/hooks/hooks.json +4 -4
  256. package/plugin/scripts/hook-audit.sh +9 -0
  257. package/plugin/scripts/hook-common.sh +8 -2
  258. package/plugin/scripts/hook-drift-check.sh +10 -1
  259. package/plugin/scripts/hook-log-path.sh +7 -0
  260. package/plugin/scripts/hook-self-audit.sh +9 -0
  261. package/plugin/scripts/hook-warm.sh +17 -11
  262. package/plugin/skills/code-auditor/SKILL.md +26 -3
  263. package/dist/__tests__/fixtures/spec-20/scripts/tool.d.ts +0 -6
  264. package/dist/__tests__/fixtures/spec-20/scripts/tool.d.ts.map +0 -1
  265. package/dist/__tests__/fixtures/spec-20/scripts/tool.js +0 -12
  266. package/dist/__tests__/fixtures/spec-20/scripts/tool.js.map +0 -1
  267. package/dist/__tests__/fixtures/spec-20/src/demo-module.d.ts +0 -7
  268. package/dist/__tests__/fixtures/spec-20/src/demo-module.d.ts.map +0 -1
  269. package/dist/__tests__/fixtures/spec-20/src/demo-module.js +0 -13
  270. package/dist/__tests__/fixtures/spec-20/src/demo-module.js.map +0 -1
  271. package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.d.ts +0 -14
  272. package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.d.ts.map +0 -1
  273. package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.js +0 -16
  274. package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.js.map +0 -1
  275. package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.d.ts +0 -15
  276. package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.d.ts.map +0 -1
  277. package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.js +0 -17
  278. package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.js.map +0 -1
  279. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts +0 -14
  280. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts.map +0 -1
  281. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js +0 -19
  282. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js.map +0 -1
  283. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts +0 -18
  284. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts.map +0 -1
  285. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js +0 -19
  286. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js.map +0 -1
  287. package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.d.ts +0 -19
  288. package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.d.ts.map +0 -1
  289. package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.js +0 -19
  290. package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.js.map +0 -1
  291. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts +0 -17
  292. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts.map +0 -1
  293. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.js +0 -19
  294. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.js.map +0 -1
  295. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts +0 -25
  296. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts.map +0 -1
  297. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.js +0 -21
  298. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.js.map +0 -1
  299. package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.d.ts +0 -15
  300. package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.d.ts.map +0 -1
  301. package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.js +0 -19
  302. package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.js.map +0 -1
  303. package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.d.ts +0 -14
  304. package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.d.ts.map +0 -1
  305. package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.js +0 -14
  306. package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.js.map +0 -1
  307. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts +0 -15
  308. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts.map +0 -1
  309. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.js +0 -16
  310. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.js.map +0 -1
  311. package/dist/languages/go/analyzer-darwin-amd64 +0 -0
  312. package/dist/languages/go/analyzer-darwin-arm64 +0 -0
  313. package/dist/languages/go/analyzer-linux-amd64 +0 -0
  314. package/dist/languages/go/analyzer-linux-arm64 +0 -0
  315. package/dist/languages/go/analyzer-src/analyzer.go +0 -643
  316. package/dist/languages/go/analyzer-src/dataaccess.go +0 -388
  317. package/dist/languages/go/analyzer-src/go.mod +0 -3
  318. package/dist/languages/go/analyzer-src/indexer.go +0 -268
  319. package/dist/languages/go/analyzer-src/parser.go +0 -461
  320. package/dist/languages/go/analyzer-src/solid.go +0 -311
  321. package/dist/languages/go/analyzer-src/testconventions.go +0 -25
  322. package/dist/languages/go/analyzer-src/types.go +0 -156
  323. package/dist/languages/go/analyzer-windows-amd64.exe +0 -0
  324. package/dist/languages/go/go.mod +0 -7
  325. package/dist/languages/go/main.go +0 -203
  326. package/dist/native/ast-grep-napi.darwin-arm64.node +0 -0
  327. package/dist/native/ast-grep-napi.darwin-x64.node +0 -0
  328. package/dist/native/ast-grep-napi.linux-arm64-gnu.node +0 -0
  329. package/dist/native/ast-grep-napi.linux-arm64-musl.node +0 -0
  330. package/dist/native/ast-grep-napi.linux-x64-gnu.node +0 -0
  331. package/dist/native/ast-grep-napi.linux-x64-musl.node +0 -0
  332. package/dist/native/ast-grep-napi.win32-x64-msvc.node +0 -0
  333. package/dist/native-bootstrap.d.ts +0 -15
  334. package/dist/native-bootstrap.d.ts.map +0 -1
  335. package/dist/native-bootstrap.js +0 -75
  336. package/dist/native-bootstrap.js.map +0 -1
package/dist/cli.js CHANGED
@@ -2,15 +2,14 @@
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';
7
5
  import { Command } from 'commander';
8
6
  import chalk from 'chalk';
9
7
  import { createAuditRunner } from './auditRunner.js';
8
+ import { readHookNotice } from './hookLog.js';
10
9
  import { promises as fs } from 'fs';
11
10
  import { createInterface } from 'readline';
12
11
  import { dirname, isAbsolute, join, relative, resolve } from 'path';
13
- import { PACKAGE_VERSION } from './constants.js';
12
+ import { PACKAGE_VERSION, DEFAULT_RULE_REQUEST_BASE_URL } from './constants.js';
14
13
  import inquirer from 'inquirer';
15
14
  import { CodeMapGenerator } from './services/CodeMapGenerator.js';
16
15
  import { initParsers } from './languages/index.js';
@@ -20,13 +19,14 @@ import { getFilesProcessed, getFactsConsumed, isVisitorStatus, isReducerStatus }
20
19
  import { createBaselineFromFindings, saveBaseline, loadBaseline, diffBaselines } from './baseline.js';
21
20
  import { fingerprint, buildFingerprintInput } from './fingerprint.js';
22
21
  import { buildDismissalEntry, upsertDismissal } from './dismissals.js';
23
- import { resolveTelemetryConfig, signatureForFinding, buildTelemetryPayload, formatTelemetryPreview, sendTelemetry, languageHint } from './telemetry.js';
22
+ import { resolveTelemetryConfig, signatureForFinding, buildTelemetryPayload, formatTelemetryPreview, sendTelemetry, languageHint, telemetryStatus, telemetryEnable, telemetryDisable, postJson } from './telemetry.js';
24
23
  import { getInstallId } from './installConfig.js';
25
24
  import { computeGatingDecision } from './enforcement/gate.js';
26
25
  import { BLOCKING_SEVERITIES, SEVERITIES } from './types.js';
27
26
  import { rankFilesByPriority, orderFindingsWithinFile } from './nextFile.js';
28
27
  import { runNextFile } from './nextFileIncremental.js';
29
28
  import { describeSqliteBackend } from './sqlite/driver.js';
29
+ import { isRuleTimingEnabled } from './analyzers/ruleTiming.js';
30
30
  const program = new Command();
31
31
  // Legacy severity names that were renamed off Spec-54's "advisory" back to "high"
32
32
  // (Spec-54's third tier rendered as "advisory", which read as optional — the very
@@ -142,17 +142,6 @@ function printAuditDiagnostics(result) {
142
142
  `${covCannotFire} cannot-fire · ${unprovenSiteCount} unproven sites · ` +
143
143
  `${heldOutByProfile} held out by profile`));
144
144
  }
145
- // ── Skipped analyzers (Spec 61) ──────────────────────────────
146
- const skippedAnalyzers = (result.metadata?.diagnostics ?? []).filter((d) => d.kind === 'go-toolchain-missing' ||
147
- d.kind === 'go-analyzer-wrong-arch' ||
148
- d.kind === 'go-analyzer-build-failed');
149
- if (skippedAnalyzers.length > 0) {
150
- console.log(chalk.yellow(`── Skipped analyzers ── ${skippedAnalyzers.length}`));
151
- for (const d of skippedAnalyzers) {
152
- const name = d.analyzerName || 'go';
153
- console.log(chalk.yellow(` ${name} [${d.kind}] — ${d.message}`));
154
- }
155
- }
156
145
  // ── Ignored config keys (Spec 61 R1.4) ─────────────────────────
157
146
  const ignoredConfigKeys = (result.metadata?.diagnostics ?? []).filter((d) => d.kind === 'config-key-rejected');
158
147
  if (ignoredConfigKeys.length > 0) {
@@ -600,6 +589,13 @@ program
600
589
  outputDirectory: options.output,
601
590
  presets: presetIds
602
591
  }).run();
592
+ // Hook-liveness notice — a top-level notice, not a per-file finding. A live
593
+ // "hook not running" condition means the PostToolUse hook is not enqueueing
594
+ // changes, so cached findings may be stale.
595
+ const hookNotice = readHookNotice();
596
+ if (hookNotice) {
597
+ console.log(chalk.yellow(`\n⚠️ ${hookNotice.message}`));
598
+ }
603
599
  const violations = Object.values(result.analyzerResults).flatMap((r) => r.violations || []);
604
600
  const baseline = result.metadata?.baseline;
605
601
  printAuditDiagnostics(result);
@@ -732,7 +728,7 @@ program
732
728
  // Emitted to stderr so it never corrupts --json stdout. Slowest rule first.
733
729
  // The gate metric is CPU time (auditCpuMs), not wall clock: the budget is
734
730
  // about a slow *rule*, and CPU time isolates that from a slow machine.
735
- if (process.env.CODE_AUDIT_RULE_TIMING === '1') {
731
+ if (isRuleTimingEnabled()) {
736
732
  const ruleTiming = result.metadata?.ruleTiming;
737
733
  const gateMs = result.metadata?.auditCpuMs;
738
734
  const gateWallMs = result.metadata?.auditDuration;
@@ -889,7 +885,18 @@ async function emitChangedOutput(result, violations, blocking, dismissedCount, o
889
885
  }
890
886
  }
891
887
  else {
892
- console.log(chalk.green('\n✓ No readings.'));
888
+ // A bare `changed` scope that found no baseline to diff against must not
889
+ // report a false clean. The diagnostic names both causes (never indexed,
890
+ // or the index was discarded) so the agent sees "cannot determine what
891
+ // changed", never "nothing changed".
892
+ const noBaseline = (result.metadata?.diagnostics ?? []).find((d) => d.kind === 'no-baseline');
893
+ if (noBaseline) {
894
+ console.log(chalk.yellow('\n⚠ Cannot determine what changed.'));
895
+ console.log(chalk.yellow(noBaseline.message));
896
+ }
897
+ else {
898
+ console.log(chalk.green('\n✓ No readings.'));
899
+ }
893
900
  }
894
901
  }
895
902
  }
@@ -1306,7 +1313,7 @@ program
1306
1313
  .description('Dismiss one finding by fingerprint — a written reason is required')
1307
1314
  .requiredOption('--reason <reason>', 'Why this finding is dismissed (required — a dismissal without a reason is a config error)')
1308
1315
  .option('-p, --path <path>', OPTION_PROJECT_PATH, process.cwd())
1309
- .option('--telemetry-endpoint <url>', 'Feedback service endpoint override (defaults to the opt-in endpoint recorded by the telemetry tool)')
1316
+ .option('--telemetry-endpoint <url>', 'Feedback service endpoint override (defaults to the opt-in endpoint recorded by the `code-audit telemetry` command)')
1310
1317
  .option('--json', OPTION_OUTPUT_AS_JSON)
1311
1318
  .action(async (fingerprintArg, options) => {
1312
1319
  try {
@@ -1334,9 +1341,9 @@ program
1334
1341
  const entry = buildDismissalEntry(match, reason, PACKAGE_VERSION);
1335
1342
  const dismissals = upsertDismissal(projectRoot, entry);
1336
1343
  // Spec 57 — opt-in telemetry. Nothing is sent unless the user opted in via
1337
- // the `telemetry` MCP tool (default OFF) AND an endpoint is configured. The
1338
- // payload is printed for review before sending; any send failure is silent
1339
- // and never affects the dismissal or the exit code.
1344
+ // the `code-audit telemetry enable` command (default OFF) AND an endpoint is
1345
+ // configured. The payload is printed for review before sending; any send
1346
+ // failure is silent and never affects the dismissal or the exit code.
1340
1347
  const telemetry = resolveTelemetryConfig({ endpoint: options.telemetryEndpoint });
1341
1348
  if (telemetry.enabled && telemetry.endpoint) {
1342
1349
  const signature = signatureForFinding(match.file, match.line ?? match.start?.line ?? 1, match.column ?? match.start?.column ?? 1) ?? 'unknown';
@@ -1384,6 +1391,153 @@ program
1384
1391
  process.exit(1);
1385
1392
  }
1386
1393
  });
1394
+ // Telemetry opt-in (Spec 57) — status/enable/disable call the same three
1395
+ // functions as the telemetry MCP tool (telemetry.ts), so the CLI and the MCP
1396
+ // tool can never disagree about what is enabled or what a submission contains.
1397
+ const telemetry = program
1398
+ .command('telemetry')
1399
+ .description('Manage anonymous dismissal feedback opt-in (default OFF). Actions: status, enable, disable.');
1400
+ telemetry
1401
+ .command('status')
1402
+ .description('Show whether anonymous dismissal feedback is enabled, its endpoint, and the anonymous install ID.')
1403
+ .option('--json', OPTION_OUTPUT_AS_JSON)
1404
+ .action(async (options) => {
1405
+ const s = telemetryStatus();
1406
+ if (options.json) {
1407
+ process.stdout.write(JSON.stringify(s, null, 2) + '\n');
1408
+ }
1409
+ else {
1410
+ console.log(chalk.bold(s.enabled ? 'Telemetry: enabled' : 'Telemetry: disabled'));
1411
+ if (s.enabled) {
1412
+ console.log(chalk.gray(` endpoint: ${s.endpoint}`));
1413
+ console.log(chalk.gray(` install ID: ${s.installId}`));
1414
+ }
1415
+ else {
1416
+ console.log(chalk.gray(' endpoint: (none — enable with `code-audit telemetry enable`)'));
1417
+ }
1418
+ console.log(chalk.gray(`\n${s.message}`));
1419
+ }
1420
+ });
1421
+ telemetry
1422
+ .command('enable')
1423
+ .description('Opt in to anonymous dismissal feedback. Defaults to the built-in service endpoint. Generates the anonymous install ID on first use.')
1424
+ .option('--endpoint <url>', 'Optional ingest URL. Defaults to the built-in service endpoint.')
1425
+ .option('--json', OPTION_OUTPUT_AS_JSON)
1426
+ .action(async (options) => {
1427
+ try {
1428
+ const s = telemetryEnable(options.endpoint);
1429
+ if (options.json) {
1430
+ process.stdout.write(JSON.stringify(s, null, 2) + '\n');
1431
+ }
1432
+ else {
1433
+ console.log(chalk.green('✓ Telemetry enabled.'));
1434
+ console.log(chalk.gray(` endpoint: ${s.endpoint}`));
1435
+ console.log(chalk.gray(` install ID: ${s.installId}`));
1436
+ console.log(chalk.gray(`\n${s.message}`));
1437
+ }
1438
+ }
1439
+ catch (error) {
1440
+ console.error(chalk.red('Error:'), error);
1441
+ process.exit(1);
1442
+ }
1443
+ });
1444
+ telemetry
1445
+ .command('disable')
1446
+ .description('Turn off anonymous dismissal feedback. The endpoint is remembered; nothing further is sent.')
1447
+ .option('--json', OPTION_OUTPUT_AS_JSON)
1448
+ .action(async (options) => {
1449
+ const s = telemetryDisable();
1450
+ if (options.json) {
1451
+ process.stdout.write(JSON.stringify(s, null, 2) + '\n');
1452
+ }
1453
+ else {
1454
+ console.log(chalk.green('✓ Telemetry disabled.'));
1455
+ console.log(chalk.gray(s.message));
1456
+ }
1457
+ });
1458
+ // Accumulate a repeatable option (commander's default keeps only the last value).
1459
+ function collectOption(value, previous) {
1460
+ return [...(previous ?? []), value];
1461
+ }
1462
+ // Request a new rule (rule-request intake). POSTs to the docs site's HTTP tool
1463
+ // API, which validates and forwards to the shared feedback service. The CLI does
1464
+ // no own validation: it reads the example files, sends them with the client
1465
+ // surface, and prints whatever the server decides (receipt id, or field errors).
1466
+ program
1467
+ .command('request-rule')
1468
+ .description('Submit a request for a new Code Auditor rule (an unflagged defect class)')
1469
+ .requiredOption('--title <title>', 'Short rule title (10-120 chars)')
1470
+ .requiredOption('--symptom <text>', 'Symptom this rule should catch (40-2000 chars)')
1471
+ .requiredOption('--signal <text>', 'Signal/pattern the rule should look for (40-2000 chars)')
1472
+ .option('--language <lang>', 'Language the rule applies to (repeatable)', collectOption, [])
1473
+ .option('--fires <path>', 'Example file that SHOULD be flagged (repeatable)', collectOption, [])
1474
+ .option('--clean <path>', 'Example file that should NOT be flagged (repeatable)', collectOption, [])
1475
+ .option('--endpoint <url>', `Docs API base URL (default ${DEFAULT_RULE_REQUEST_BASE_URL})`)
1476
+ .option('--json', OPTION_OUTPUT_AS_JSON)
1477
+ .action(async (options) => {
1478
+ try {
1479
+ const readFiles = async (paths) => {
1480
+ const out = [];
1481
+ for (const p of paths) {
1482
+ out.push({ path: p, content: await fs.readFile(resolve(p), 'utf-8') });
1483
+ }
1484
+ return out;
1485
+ };
1486
+ const [firingExample, cleanExample] = await Promise.all([
1487
+ readFiles(options.fires ?? []),
1488
+ readFiles(options.clean ?? []),
1489
+ ]);
1490
+ const body = {
1491
+ title: options.title,
1492
+ symptom: options.symptom,
1493
+ signal: options.signal,
1494
+ languages: options.language ?? [],
1495
+ firingExample,
1496
+ cleanExample,
1497
+ toolVersion: PACKAGE_VERSION,
1498
+ };
1499
+ const base = (options.endpoint ?? DEFAULT_RULE_REQUEST_BASE_URL).replace(/\/+$/, '');
1500
+ const url = `${base}/api/tools/request_rule`;
1501
+ const result = await postJson(url, body, {
1502
+ timeoutMs: 5000,
1503
+ headers: { 'x-code-auditor-client': 'cli' },
1504
+ });
1505
+ if (result.error) {
1506
+ console.error(chalk.red('Error:'), result.error);
1507
+ process.exit(1);
1508
+ }
1509
+ if (!result.ok) {
1510
+ const res = result.body;
1511
+ if (res?.fields) {
1512
+ console.error(chalk.red(`Error: request rejected (${res.error ?? 'validation failed'})`));
1513
+ for (const [field, msgs] of Object.entries(res.fields)) {
1514
+ console.error(chalk.gray(` ${field}: ${msgs.join('; ')}`));
1515
+ }
1516
+ }
1517
+ else if (res?.retryAfterSeconds !== undefined) {
1518
+ console.error(chalk.red(`Error: rate limited — retry in ${res.retryAfterSeconds}s`));
1519
+ }
1520
+ else {
1521
+ console.error(chalk.red(`Error: ${res?.message ?? res?.error ?? `HTTP ${result.status}`}`));
1522
+ }
1523
+ process.exit(1);
1524
+ }
1525
+ const out = result.body;
1526
+ if (options.json) {
1527
+ process.stdout.write(JSON.stringify(out, null, 2) + '\n');
1528
+ }
1529
+ else {
1530
+ console.log(chalk.green(`✓ Rule request submitted${out.duplicateSubmission ? ' (duplicate — already received)' : ''}`));
1531
+ console.log(chalk.gray(` receipt id: ${out.id}`));
1532
+ const matches = out.existingRuleMatches ?? [];
1533
+ console.log(chalk.gray(` existingRuleMatches: ${matches.length ? matches.join(', ') : '(none)'}`));
1534
+ }
1535
+ }
1536
+ catch (error) {
1537
+ console.error(chalk.red('Error:'), error);
1538
+ process.exit(1);
1539
+ }
1540
+ });
1387
1541
  // Generate configuration command
1388
1542
  program
1389
1543
  .command('generate-config')
@@ -2298,8 +2452,18 @@ program
2298
2452
  if (existing.cnt === 0 && options.path) {
2299
2453
  const { extractChurn } = await import('./churn/churnExtractor.js');
2300
2454
  const { computeHotspots } = await import('./hotspots/hotspotScorer.js');
2455
+ const { findConfigFileUp, loadConfig } = await import('./config/configLoader.js');
2456
+ const { DEFAULT_CHURN_CONFIG } = await import('./config/defaults.js');
2301
2457
  try {
2302
- extractChurn(rawDb, options.path, { churnWindowMonths: 12 });
2458
+ // Read the `churn` config key (Spec 13 R1) — the literal
2459
+ // `{ churnWindowMonths: 12 }` was the orphan; the window now resolves
2460
+ // from `.codeauditor.json` with DEFAULT_CHURN_CONFIG as the default.
2461
+ const configPath = await findConfigFileUp(options.path);
2462
+ const { config } = await loadConfig({
2463
+ configPath: configPath ?? undefined,
2464
+ projectRoot: options.path,
2465
+ });
2466
+ extractChurn(rawDb, options.path, config.churn ?? DEFAULT_CHURN_CONFIG);
2303
2467
  computeHotspots(rawDb);
2304
2468
  }
2305
2469
  catch (err) {
@@ -2586,8 +2750,6 @@ ledgerCmd
2586
2750
  // `audit --detach` forks workers/auditJobRunner; `status`/`result`/`jobs` read
2587
2751
  // the persisted ledger. One job model (the ledger run), one write path — these
2588
2752
  // are thin wrappers over ledger.ts + mcpAuditJobs.ts, not a second store.
2589
- /** Lease TTL used by read-path reclaim, mirroring mcpAuditJobs.jobLeaseTtlMs. */
2590
- const CLI_JOB_LEASE_TTL_MS = Number(process.env.CODE_AUDITOR_JOB_LEASE_TTL_MS) || 30_000;
2591
2753
  function spec41StatusBadge(status) {
2592
2754
  switch (status) {
2593
2755
  case 'completed':
@@ -2692,10 +2854,11 @@ program
2692
2854
  .action(async (jobId, options) => {
2693
2855
  try {
2694
2856
  const { getLedgerRun, reclaimStaleRunning, computeStaleness } = await import('./ledger.js');
2857
+ const { jobLeaseTtlMs } = await import('./mcpAuditJobs.js');
2695
2858
  const projectRoot = resolve(options.path);
2696
2859
  const db = CodeIndexDB.getInstance(undefined, projectRoot);
2697
2860
  await db.initialize();
2698
- reclaimStaleRunning(db.rawDb, projectRoot, CLI_JOB_LEASE_TTL_MS);
2861
+ reclaimStaleRunning(db.rawDb, projectRoot, jobLeaseTtlMs());
2699
2862
  const run = getLedgerRun(db.rawDb, jobId);
2700
2863
  if (!run) {
2701
2864
  console.error(chalk.red(`Job not found: ${jobId}`));
@@ -2853,10 +3016,11 @@ program
2853
3016
  .action(async (options) => {
2854
3017
  try {
2855
3018
  const { listLedgerRuns, reclaimStaleRunning, pruneLedgerRuns, computeStaleness } = await import('./ledger.js');
3019
+ const { jobLeaseTtlMs } = await import('./mcpAuditJobs.js');
2856
3020
  const projectRoot = resolve(options.path);
2857
3021
  const db = CodeIndexDB.getInstance(undefined, projectRoot);
2858
3022
  await db.initialize();
2859
- reclaimStaleRunning(db.rawDb, projectRoot, CLI_JOB_LEASE_TTL_MS);
3023
+ reclaimStaleRunning(db.rawDb, projectRoot, jobLeaseTtlMs());
2860
3024
  if (options.prune) {
2861
3025
  const keep = parseInt(options.keep, 10) || 10;
2862
3026
  const n = pruneLedgerRuns(db.rawDb, projectRoot, keep);
@@ -3069,6 +3233,11 @@ program
3069
3233
  hooks: options.hooks,
3070
3234
  list: options.list,
3071
3235
  });
3236
+ // Nudge an undecided user toward the one-time telemetry choice. Only after
3237
+ // a real install (not `--list`), and never once they've already decided.
3238
+ if (!options.list && !telemetryStatus().decided) {
3239
+ console.log('Anonymous dismissal feedback is off. Run `code-audit telemetry enable` to opt in, or `code-audit telemetry disable` to decline.');
3240
+ }
3072
3241
  }
3073
3242
  catch (error) {
3074
3243
  console.error(chalk.red('Error:'), error);