code-auditor-mcp 5.0.2 → 5.3.3

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 (419) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +326 -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 +35 -14
  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/UniversalDRYAnalyzer.d.ts +0 -2
  27. package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -1
  28. package/dist/analyzers/universal/UniversalDRYAnalyzer.js +4 -5
  29. package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -1
  30. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +32 -15
  31. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
  32. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +189 -115
  33. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
  34. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts +0 -2
  35. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -1
  36. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +0 -5
  37. package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -1
  38. package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts +2 -10
  39. package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts.map +1 -1
  40. package/dist/analyzers/universal/UniversalStylesAnalyzer.js +7 -49
  41. package/dist/analyzers/universal/UniversalStylesAnalyzer.js.map +1 -1
  42. package/dist/analyzers/universal/schema/codeAnalysis.d.ts.map +1 -1
  43. package/dist/analyzers/universal/schema/codeAnalysis.js +51 -3
  44. package/dist/analyzers/universal/schema/codeAnalysis.js.map +1 -1
  45. package/dist/analyzers/universal/schema/config.d.ts.map +1 -1
  46. package/dist/analyzers/universal/schema/config.js +0 -2
  47. package/dist/analyzers/universal/schema/config.js.map +1 -1
  48. package/dist/analyzers/universal/schema/types.d.ts +0 -2
  49. package/dist/analyzers/universal/schema/types.d.ts.map +1 -1
  50. package/dist/analyzers/vendorSurfaces.d.ts +126 -0
  51. package/dist/analyzers/vendorSurfaces.d.ts.map +1 -0
  52. package/dist/analyzers/vendorSurfaces.js +580 -0
  53. package/dist/analyzers/vendorSurfaces.js.map +1 -0
  54. package/dist/auditRunner.d.ts +9 -1
  55. package/dist/auditRunner.d.ts.map +1 -1
  56. package/dist/auditRunner.js +198 -146
  57. package/dist/auditRunner.js.map +1 -1
  58. package/dist/cacheGc.d.ts +88 -0
  59. package/dist/cacheGc.d.ts.map +1 -0
  60. package/dist/cacheGc.js +196 -0
  61. package/dist/cacheGc.js.map +1 -0
  62. package/dist/churn/churnExtractor.d.ts +0 -1
  63. package/dist/churn/churnExtractor.d.ts.map +1 -1
  64. package/dist/churn/churnExtractor.js +2 -4
  65. package/dist/churn/churnExtractor.js.map +1 -1
  66. package/dist/cli.d.ts +1 -1
  67. package/dist/cli.d.ts.map +1 -1
  68. package/dist/cli.js +260 -47
  69. package/dist/cli.js.map +1 -1
  70. package/dist/codeIndex/migrations.d.ts.map +1 -1
  71. package/dist/codeIndex/migrations.js +4 -3
  72. package/dist/codeIndex/migrations.js.map +1 -1
  73. package/dist/codeIndexDB.d.ts +11 -2
  74. package/dist/codeIndexDB.d.ts.map +1 -1
  75. package/dist/codeIndexDB.js +27 -2
  76. package/dist/codeIndexDB.js.map +1 -1
  77. package/dist/config/configLoader.d.ts +60 -7
  78. package/dist/config/configLoader.d.ts.map +1 -1
  79. package/dist/config/configLoader.js +252 -60
  80. package/dist/config/configLoader.js.map +1 -1
  81. package/dist/config/defaults.d.ts +137 -43
  82. package/dist/config/defaults.d.ts.map +1 -1
  83. package/dist/config/defaults.js +174 -101
  84. package/dist/config/defaults.js.map +1 -1
  85. package/dist/config/effectiveConfig.d.ts +1 -1
  86. package/dist/config/effectiveConfig.d.ts.map +1 -1
  87. package/dist/config/effectiveConfig.js +4 -6
  88. package/dist/config/effectiveConfig.js.map +1 -1
  89. package/dist/config/pathProfiles.d.ts +4 -3
  90. package/dist/config/pathProfiles.d.ts.map +1 -1
  91. package/dist/config/pathProfiles.js +3 -2
  92. package/dist/config/pathProfiles.js.map +1 -1
  93. package/dist/constants.d.ts +2 -1
  94. package/dist/constants.d.ts.map +1 -1
  95. package/dist/constants.js +4 -0
  96. package/dist/constants.js.map +1 -1
  97. package/dist/daemon/main.d.ts +0 -1
  98. package/dist/daemon/main.d.ts.map +1 -1
  99. package/dist/daemon/main.js +11 -4
  100. package/dist/daemon/main.js.map +1 -1
  101. package/dist/dataPaths.d.ts +32 -9
  102. package/dist/dataPaths.d.ts.map +1 -1
  103. package/dist/dataPaths.js +69 -16
  104. package/dist/dataPaths.js.map +1 -1
  105. package/dist/hookLog.d.ts +54 -0
  106. package/dist/hookLog.d.ts.map +1 -0
  107. package/dist/hookLog.js +105 -0
  108. package/dist/hookLog.js.map +1 -0
  109. package/dist/hookLogPath.generated.d.ts +3 -0
  110. package/dist/hookLogPath.generated.d.ts.map +1 -0
  111. package/dist/hookLogPath.generated.js +8 -0
  112. package/dist/hookLogPath.generated.js.map +1 -0
  113. package/dist/index.d.ts +0 -5
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js +0 -7
  116. package/dist/index.js.map +1 -1
  117. package/dist/installConfig.d.ts +15 -2
  118. package/dist/installConfig.d.ts.map +1 -1
  119. package/dist/installConfig.js +17 -2
  120. package/dist/installConfig.js.map +1 -1
  121. package/dist/installer.d.ts.map +1 -1
  122. package/dist/installer.js +2 -1
  123. package/dist/installer.js.map +1 -1
  124. package/dist/languages/adapterBridge.d.ts +11 -0
  125. package/dist/languages/adapterBridge.d.ts.map +1 -1
  126. package/dist/languages/adapterBridge.js +11 -0
  127. package/dist/languages/adapterBridge.js.map +1 -1
  128. package/dist/languages/types.d.ts +8 -0
  129. package/dist/languages/types.d.ts.map +1 -1
  130. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts +13 -0
  131. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -1
  132. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +135 -18
  133. package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -1
  134. package/dist/ledger.d.ts +7 -0
  135. package/dist/ledger.d.ts.map +1 -1
  136. package/dist/ledger.js +7 -0
  137. package/dist/ledger.js.map +1 -1
  138. package/dist/mcp-tools/workflowGuide.js +8 -8
  139. package/dist/mcp-tools/workflowGuide.js.map +1 -1
  140. package/dist/mcp-tools-shared.d.ts.map +1 -1
  141. package/dist/mcp-tools-shared.js +5 -2
  142. package/dist/mcp-tools-shared.js.map +1 -1
  143. package/dist/mcp-ui-simple.d.ts +5 -0
  144. package/dist/mcp-ui-simple.d.ts.map +1 -1
  145. package/dist/mcp-ui-simple.js +9 -2
  146. package/dist/mcp-ui-simple.js.map +1 -1
  147. package/dist/mcp.d.ts +0 -1
  148. package/dist/mcp.d.ts.map +1 -1
  149. package/dist/mcp.js +36 -33
  150. package/dist/mcp.js.map +1 -1
  151. package/dist/mcpAuditJobs.d.ts +10 -0
  152. package/dist/mcpAuditJobs.d.ts.map +1 -1
  153. package/dist/mcpAuditJobs.js +10 -1
  154. package/dist/mcpAuditJobs.js.map +1 -1
  155. package/dist/mcpAutoIndex.d.ts.map +1 -1
  156. package/dist/mcpAutoIndex.js +2 -1
  157. package/dist/mcpAutoIndex.js.map +1 -1
  158. package/dist/mcpDiagnostics.d.ts +2 -0
  159. package/dist/mcpDiagnostics.d.ts.map +1 -1
  160. package/dist/mcpDiagnostics.js +2 -0
  161. package/dist/mcpDiagnostics.js.map +1 -1
  162. package/dist/phase/candidates.d.ts +53 -0
  163. package/dist/phase/candidates.d.ts.map +1 -0
  164. package/dist/phase/candidates.js +67 -0
  165. package/dist/phase/candidates.js.map +1 -0
  166. package/dist/phase/colorMath.d.ts +18 -5
  167. package/dist/phase/colorMath.d.ts.map +1 -1
  168. package/dist/phase/colorMath.js +88 -5
  169. package/dist/phase/colorMath.js.map +1 -1
  170. package/dist/phase/dataAccessCallsCandidates.js +1 -1
  171. package/dist/phase/dataAccessCallsCandidates.js.map +1 -1
  172. package/dist/phase/goFunctionAnalysis.d.ts +2 -2
  173. package/dist/phase/goFunctionAnalysis.js +2 -2
  174. package/dist/phase/goFunctions.d.ts +2 -2
  175. package/dist/phase/goFunctions.js +2 -2
  176. package/dist/phase/goImports.d.ts +2 -2
  177. package/dist/phase/goImports.js +2 -2
  178. package/dist/phase/goSwitches.d.ts +2 -2
  179. package/dist/phase/goSwitches.js +2 -2
  180. package/dist/phase/imports.d.ts.map +1 -1
  181. package/dist/phase/imports.js +1 -0
  182. package/dist/phase/imports.js.map +1 -1
  183. package/dist/phase/loopQueryCandidates.js +1 -1
  184. package/dist/phase/loopQueryCandidates.js.map +1 -1
  185. package/dist/phase/oracles.d.ts +28 -0
  186. package/dist/phase/oracles.d.ts.map +1 -1
  187. package/dist/phase/oracles.js +28 -0
  188. package/dist/phase/oracles.js.map +1 -1
  189. package/dist/phase/phaseModel.d.ts +47 -8
  190. package/dist/phase/phaseModel.d.ts.map +1 -1
  191. package/dist/phase/phaseModel.js +44 -8
  192. package/dist/phase/phaseModel.js.map +1 -1
  193. package/dist/phase/producers.d.ts.map +1 -1
  194. package/dist/phase/producers.js +24 -17
  195. package/dist/phase/producers.js.map +1 -1
  196. package/dist/phase/reachability.d.ts +44 -1
  197. package/dist/phase/reachability.d.ts.map +1 -1
  198. package/dist/phase/reachability.js +79 -0
  199. package/dist/phase/reachability.js.map +1 -1
  200. package/dist/phase/rules/conventions.d.ts.map +1 -1
  201. package/dist/phase/rules/conventions.js +6 -2
  202. package/dist/phase/rules/conventions.js.map +1 -1
  203. package/dist/phase/rules/crossDomain.d.ts.map +1 -1
  204. package/dist/phase/rules/crossDomain.js +16 -6
  205. package/dist/phase/rules/crossDomain.js.map +1 -1
  206. package/dist/phase/rules/dataAccess.d.ts.map +1 -1
  207. package/dist/phase/rules/dataAccess.js +13 -0
  208. package/dist/phase/rules/dataAccess.js.map +1 -1
  209. package/dist/phase/rules/documentation.d.ts.map +1 -1
  210. package/dist/phase/rules/documentation.js +11 -1
  211. package/dist/phase/rules/documentation.js.map +1 -1
  212. package/dist/phase/rules/dry.d.ts +16 -7
  213. package/dist/phase/rules/dry.d.ts.map +1 -1
  214. package/dist/phase/rules/dry.js +51 -32
  215. package/dist/phase/rules/dry.js.map +1 -1
  216. package/dist/phase/rules/goRules.d.ts +2 -2
  217. package/dist/phase/rules/goRules.js +2 -2
  218. package/dist/phase/rules/secrets.d.ts +22 -8
  219. package/dist/phase/rules/secrets.d.ts.map +1 -1
  220. package/dist/phase/rules/secrets.js +75 -69
  221. package/dist/phase/rules/secrets.js.map +1 -1
  222. package/dist/phase/rules/styles.d.ts +23 -9
  223. package/dist/phase/rules/styles.d.ts.map +1 -1
  224. package/dist/phase/rules/styles.js +61 -15
  225. package/dist/phase/rules/styles.js.map +1 -1
  226. package/dist/phase/rules/unreferencedModule.d.ts.map +1 -1
  227. package/dist/phase/rules/unreferencedModule.js +32 -10
  228. package/dist/phase/rules/unreferencedModule.js.map +1 -1
  229. package/dist/phase/runner.d.ts +16 -7
  230. package/dist/phase/runner.d.ts.map +1 -1
  231. package/dist/phase/runner.js +32 -20
  232. package/dist/phase/runner.js.map +1 -1
  233. package/dist/phase/stringLiterals.d.ts.map +1 -1
  234. package/dist/phase/stringLiterals.js +16 -7
  235. package/dist/phase/stringLiterals.js.map +1 -1
  236. package/dist/phase/stylesCss.d.ts.map +1 -1
  237. package/dist/phase/stylesCss.js +4 -0
  238. package/dist/phase/stylesCss.js.map +1 -1
  239. package/dist/phase/stylesMarkup.d.ts.map +1 -1
  240. package/dist/phase/stylesMarkup.js +4 -0
  241. package/dist/phase/stylesMarkup.js.map +1 -1
  242. package/dist/phase/stylesSource.d.ts.map +1 -1
  243. package/dist/phase/stylesSource.js +6 -0
  244. package/dist/phase/stylesSource.js.map +1 -1
  245. package/dist/phase/testProgram.d.ts +57 -0
  246. package/dist/phase/testProgram.d.ts.map +1 -0
  247. package/dist/phase/testProgram.js +244 -0
  248. package/dist/phase/testProgram.js.map +1 -0
  249. package/dist/phase/typeDeclarations.d.ts +2 -2
  250. package/dist/phase/typeDeclarations.js +2 -2
  251. package/dist/phase/types.d.ts +104 -0
  252. package/dist/phase/types.d.ts.map +1 -1
  253. package/dist/pipeline.d.ts +4 -0
  254. package/dist/pipeline.d.ts.map +1 -1
  255. package/dist/pipeline.js +4 -0
  256. package/dist/pipeline.js.map +1 -1
  257. package/dist/pipelineAdapters.d.ts +1 -171
  258. package/dist/pipelineAdapters.d.ts.map +1 -1
  259. package/dist/pipelineAdapters.js +47 -1281
  260. package/dist/pipelineAdapters.js.map +1 -1
  261. package/dist/reporting/csvReportGenerator.d.ts.map +1 -1
  262. package/dist/reporting/csvReportGenerator.js +0 -6
  263. package/dist/reporting/csvReportGenerator.js.map +1 -1
  264. package/dist/reporting/htmlReportGenerator.d.ts.map +1 -1
  265. package/dist/reporting/htmlReportGenerator.js +0 -4
  266. package/dist/reporting/htmlReportGenerator.js.map +1 -1
  267. package/dist/reporting/jsonReportGenerator.d.ts.map +1 -1
  268. package/dist/reporting/jsonReportGenerator.js +0 -1
  269. package/dist/reporting/jsonReportGenerator.js.map +1 -1
  270. package/dist/reporting/sarifReportGenerator.d.ts.map +1 -1
  271. package/dist/reporting/sarifReportGenerator.js +0 -7
  272. package/dist/reporting/sarifReportGenerator.js.map +1 -1
  273. package/dist/services/auditJobService.d.ts +15 -0
  274. package/dist/services/auditJobService.d.ts.map +1 -1
  275. package/dist/services/auditJobService.js +15 -0
  276. package/dist/services/auditJobService.js.map +1 -1
  277. package/dist/services/projectTaskHelpers.d.ts +7 -0
  278. package/dist/services/projectTaskHelpers.d.ts.map +1 -1
  279. package/dist/services/projectTaskHelpers.js +7 -0
  280. package/dist/services/projectTaskHelpers.js.map +1 -1
  281. package/dist/services/whitelistService.d.ts +28 -0
  282. package/dist/services/whitelistService.d.ts.map +1 -1
  283. package/dist/services/whitelistService.js +28 -0
  284. package/dist/services/whitelistService.js.map +1 -1
  285. package/dist/sqlite/driver.d.ts +17 -1
  286. package/dist/sqlite/driver.d.ts.map +1 -1
  287. package/dist/sqlite/driver.js +28 -5
  288. package/dist/sqlite/driver.js.map +1 -1
  289. package/dist/styles/cssInJsHarvest.d.ts +36 -0
  290. package/dist/styles/cssInJsHarvest.d.ts.map +1 -0
  291. package/dist/styles/cssInJsHarvest.js +78 -0
  292. package/dist/styles/cssInJsHarvest.js.map +1 -0
  293. package/dist/styles/definedClasses.d.ts +95 -0
  294. package/dist/styles/definedClasses.d.ts.map +1 -0
  295. package/dist/styles/definedClasses.js +129 -0
  296. package/dist/styles/definedClasses.js.map +1 -0
  297. package/dist/styles/markupStyleHarvest.d.ts +33 -0
  298. package/dist/styles/markupStyleHarvest.d.ts.map +1 -0
  299. package/dist/styles/markupStyleHarvest.js +73 -0
  300. package/dist/styles/markupStyleHarvest.js.map +1 -0
  301. package/dist/styles/styleExtractor.d.ts +37 -0
  302. package/dist/styles/styleExtractor.d.ts.map +1 -1
  303. package/dist/styles/styleExtractor.js +89 -33
  304. package/dist/styles/styleExtractor.js.map +1 -1
  305. package/dist/styles/styleIndexer.d.ts.map +1 -1
  306. package/dist/styles/styleIndexer.js +11 -10
  307. package/dist/styles/styleIndexer.js.map +1 -1
  308. package/dist/styles/tailwindExpander.d.ts.map +1 -1
  309. package/dist/styles/tailwindExpander.js +31 -10
  310. package/dist/styles/tailwindExpander.js.map +1 -1
  311. package/dist/styles/tailwindUtilityExpander.d.ts +4 -0
  312. package/dist/styles/tailwindUtilityExpander.d.ts.map +1 -1
  313. package/dist/styles/tailwindUtilityExpander.js +4 -0
  314. package/dist/styles/tailwindUtilityExpander.js.map +1 -1
  315. package/dist/telemetry.d.ts +67 -1
  316. package/dist/telemetry.d.ts.map +1 -1
  317. package/dist/telemetry.js +100 -20
  318. package/dist/telemetry.js.map +1 -1
  319. package/dist/types/crossLanguage.d.ts +1 -0
  320. package/dist/types/crossLanguage.d.ts.map +1 -1
  321. package/dist/types.d.ts +73 -56
  322. package/dist/types.d.ts.map +1 -1
  323. package/dist/types.js +4 -4
  324. package/dist/types.js.map +1 -1
  325. package/dist/version.generated.d.ts +1 -1
  326. package/dist/version.generated.js +1 -1
  327. package/examples/.auditrc.example.json +7 -22
  328. package/examples/.auditrc.json +12 -155
  329. package/examples/.code-auditor.json +8 -51
  330. package/examples/nextjs.auditrc.json +7 -34
  331. package/examples/node-api.auditrc.json +6 -46
  332. package/examples/react.auditrc.json +8 -25
  333. package/examples/tolerant-solid.auditrc.json +12 -44
  334. package/package.json +8 -5
  335. package/plugin/.claude-plugin/manifest.json +10 -9
  336. package/plugin/.claude-plugin/plugin.json +1 -1
  337. package/plugin/hooks/hooks.json +4 -4
  338. package/plugin/scripts/hook-audit.sh +25 -10
  339. package/plugin/scripts/hook-common.sh +12 -7
  340. package/plugin/scripts/hook-drift-check.sh +10 -1
  341. package/plugin/scripts/hook-log-path.sh +7 -0
  342. package/plugin/scripts/hook-self-audit.sh +21 -6
  343. package/plugin/scripts/hook-warm.sh +17 -11
  344. package/plugin/skills/code-auditor/SKILL.md +26 -3
  345. package/server.json +2 -2
  346. package/dist/__tests__/fixtures/spec-20/scripts/tool.d.ts +0 -6
  347. package/dist/__tests__/fixtures/spec-20/scripts/tool.d.ts.map +0 -1
  348. package/dist/__tests__/fixtures/spec-20/scripts/tool.js +0 -12
  349. package/dist/__tests__/fixtures/spec-20/scripts/tool.js.map +0 -1
  350. package/dist/__tests__/fixtures/spec-20/src/demo-module.d.ts +0 -7
  351. package/dist/__tests__/fixtures/spec-20/src/demo-module.d.ts.map +0 -1
  352. package/dist/__tests__/fixtures/spec-20/src/demo-module.js +0 -13
  353. package/dist/__tests__/fixtures/spec-20/src/demo-module.js.map +0 -1
  354. package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.d.ts +0 -14
  355. package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.d.ts.map +0 -1
  356. package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.js +0 -16
  357. package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.js.map +0 -1
  358. package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.d.ts +0 -15
  359. package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.d.ts.map +0 -1
  360. package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.js +0 -17
  361. package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.js.map +0 -1
  362. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts +0 -14
  363. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts.map +0 -1
  364. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js +0 -19
  365. package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js.map +0 -1
  366. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts +0 -18
  367. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts.map +0 -1
  368. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js +0 -19
  369. package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js.map +0 -1
  370. package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.d.ts +0 -19
  371. package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.d.ts.map +0 -1
  372. package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.js +0 -19
  373. package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.js.map +0 -1
  374. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts +0 -17
  375. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts.map +0 -1
  376. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.js +0 -19
  377. package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.js.map +0 -1
  378. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts +0 -25
  379. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts.map +0 -1
  380. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.js +0 -21
  381. package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.js.map +0 -1
  382. package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.d.ts +0 -15
  383. package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.d.ts.map +0 -1
  384. package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.js +0 -19
  385. package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.js.map +0 -1
  386. package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.d.ts +0 -14
  387. package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.d.ts.map +0 -1
  388. package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.js +0 -14
  389. package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.js.map +0 -1
  390. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts +0 -15
  391. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts.map +0 -1
  392. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.js +0 -16
  393. package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.js.map +0 -1
  394. package/dist/languages/go/analyzer-darwin-amd64 +0 -0
  395. package/dist/languages/go/analyzer-darwin-arm64 +0 -0
  396. package/dist/languages/go/analyzer-linux-amd64 +0 -0
  397. package/dist/languages/go/analyzer-linux-arm64 +0 -0
  398. package/dist/languages/go/analyzer-src/analyzer.go +0 -643
  399. package/dist/languages/go/analyzer-src/dataaccess.go +0 -388
  400. package/dist/languages/go/analyzer-src/go.mod +0 -3
  401. package/dist/languages/go/analyzer-src/indexer.go +0 -268
  402. package/dist/languages/go/analyzer-src/parser.go +0 -461
  403. package/dist/languages/go/analyzer-src/solid.go +0 -311
  404. package/dist/languages/go/analyzer-src/testconventions.go +0 -25
  405. package/dist/languages/go/analyzer-src/types.go +0 -156
  406. package/dist/languages/go/analyzer-windows-amd64.exe +0 -0
  407. package/dist/languages/go/go.mod +0 -7
  408. package/dist/languages/go/main.go +0 -203
  409. package/dist/native/ast-grep-napi.darwin-arm64.node +0 -0
  410. package/dist/native/ast-grep-napi.darwin-x64.node +0 -0
  411. package/dist/native/ast-grep-napi.linux-arm64-gnu.node +0 -0
  412. package/dist/native/ast-grep-napi.linux-arm64-musl.node +0 -0
  413. package/dist/native/ast-grep-napi.linux-x64-gnu.node +0 -0
  414. package/dist/native/ast-grep-napi.linux-x64-musl.node +0 -0
  415. package/dist/native/ast-grep-napi.win32-x64-msvc.node +0 -0
  416. package/dist/native-bootstrap.d.ts +0 -15
  417. package/dist/native-bootstrap.d.ts.map +0 -1
  418. package/dist/native-bootstrap.js +0 -75
  419. package/dist/native-bootstrap.js.map +0 -1
@@ -1,388 +0,0 @@
1
- package analyzer
2
-
3
- import (
4
- "go/ast"
5
- "go/token"
6
- "regexp"
7
- "strconv"
8
- "strings"
9
- )
10
-
11
- // runDataAccessAnalysis analyzes database-access patterns on `database/sql`,
12
- // `sqlx`, and GORM (`Raw`) method calls. It is the Go-subprocess counterpart of the TypeScript
13
- // `UniversalDataAccessAnalyzer` + schema Stage-4 reducer, emitting the same
14
- // bare rule IDs at the same ledger severities.
15
- //
16
- // Tenancy is declared, not guessed. The TypeScript pipeline resolves "which
17
- // tables require an org/tenant filter" from three tiers — explicit
18
- // `orgFilterTables` (config), configured `schemas` tables carrying a
19
- // tenant-scoping column, and DDL migrations (`CREATE TABLE` columns) — via
20
- // `buildOrgFilterTierSet`. This subprocess is syntax-only and does not read the
21
- // project config or DDL itself, so the resolved tiers are handed to it in
22
- // `AnalysisOptions`:
23
- //
24
- // - `orgFilterTables` — the tenant-scoped tables (all three tiers, lowercased)
25
- // that drive `missing-org-filter`.
26
- // - `knownTables` — the known-table catalog (DDL tables + configured schemas +
27
- // explicit tables) that drives `unknown-table`.
28
- // - `orgFilterColumns` — the tenant-scoping column names that count as a
29
- // tenant predicate, defaulting to org_id/tenant_id/organization_id/
30
- // workspace_id (the same default as the TS pipeline).
31
- //
32
- // An earlier revision hardcoded `tenantTables`/`knownTables` word lists as a
33
- // substitute for declared tenancy — the Spec 44 English-name fallback the TS
34
- // side had already deleted on purpose. That made `missing-org-filter` fire on
35
- // `users`/`projects`/`orders` whether or not the project declared them
36
- // multi-tenant, and stay silent on a genuinely tenant-scoped table whose name
37
- // was absent from the list. Declared tenancy removes both errors.
38
-
39
- // tableExtractRe matches `FROM <table>` / `INTO <table>` / `UPDATE <table>`
40
- // (optionally backtick/double/single-quoted, optionally schema-prefixed).
41
- var tableExtractRe = regexp.MustCompile(`(?i)\b(?:from|into|update)\s+[` + "`\"']?([A-Za-z_][A-Za-z0-9_.]*)")
42
-
43
- // whereRe matches a row-limiting clause (WHERE/HAVING/LIMIT).
44
- var whereRe = regexp.MustCompile(`(?i)\b(where|having|limit)\b`)
45
-
46
- // defaultOrgFilterColumns are the tenant-scoping column names assumed when the
47
- // caller supplies none. Mirrors DEFAULT_ORG_FILTER_COLUMNS on the TS side.
48
- var defaultOrgFilterColumns = []string{"org_id", "tenant_id", "organization_id", "workspace_id"}
49
-
50
- func (a *Analyzer) runDataAccessAnalysis() []Violation {
51
- var violations []Violation
52
-
53
- tenantTables := a.declaredTenantTables()
54
- knownTables := a.declaredKnownTables()
55
- tenantPredRe := a.tenantPredicateRegex()
56
-
57
- for filePath, file := range a.parser.files {
58
- ast.Inspect(file, func(n ast.Node) bool {
59
- call, ok := n.(*ast.CallExpr)
60
- if !ok {
61
- return true
62
- }
63
- method, sqlArgIndex, isDB := dbMethodName(call)
64
- if !isDB || sqlArgIndex < 0 || sqlArgIndex >= len(call.Args) {
65
- return true
66
- }
67
- sqlExpr := call.Args[sqlArgIndex]
68
-
69
- // sql-injection-risk: a dynamically-constructed SQL string is an
70
- // injection surface; a raw string literal with `$1` placeholders is
71
- // not. The dynamic case returns early — its table name is not
72
- // resolvable, so the table-based rules below cannot apply.
73
- if isDynamicSQL(sqlExpr) {
74
- if !containsSQLVerb(sqlFormatString(sqlExpr)) {
75
- return true
76
- }
77
- pos := a.parser.fileSet.Position(call.Pos())
78
- violations = append(violations, Violation{
79
- File: filePath,
80
- Line: pos.Line,
81
- Severity: "critical",
82
- Message: "SQL query is built with string formatting instead of parameterized placeholders",
83
- Details: map[string]interface{}{
84
- "method": method,
85
- },
86
- Suggestion: "Use $1/$2 placeholders and pass the values as separate arguments",
87
- Analyzer: "go",
88
- Rule: "sql-injection-risk",
89
- })
90
- return true
91
- }
92
-
93
- sqlText := literalString(sqlExpr)
94
- if sqlText == "" {
95
- // A variable-held SQL string: neither provably static nor
96
- // provably dynamic. Leave it alone rather than guess.
97
- return true
98
- }
99
-
100
- verb := sqlVerb(sqlText)
101
- table := extractTable(sqlText)
102
- if table == "" {
103
- return true
104
- }
105
-
106
- // unknown-table: a recognized-name near-miss (`user` → `users`).
107
- if near, known := nearMissTable(knownTables, table); !known && near != "" {
108
- pos := a.parser.fileSet.Position(call.Pos())
109
- violations = append(violations, Violation{
110
- File: filePath,
111
- Line: pos.Line,
112
- Severity: "critical",
113
- Message: "Reference to unknown table \"" + table + "\" (did you mean \"" + near + "\"?)",
114
- Details: map[string]interface{}{
115
- "table": table,
116
- "suggestion": near,
117
- },
118
- Suggestion: "Rename the table reference \"" + table + "\" to \"" + near + "\"",
119
- Analyzer: "go",
120
- Rule: "unknown-table",
121
- })
122
- }
123
-
124
- hasWhere := whereRe.MatchString(sqlText)
125
- hasTenantPred := tenantPredRe.MatchString(sqlText)
126
-
127
- // missing-org-filter: a row-affecting query (SELECT/UPDATE/DELETE) on
128
- // a tenant table with no tenant predicate. INSERT is excluded — an
129
- // insert does not filter existing rows; it should carry the tenant
130
- // column as a value, not a predicate.
131
- if tenantTables[table] && verb != "INSERT" && !hasTenantPred {
132
- pos := a.parser.fileSet.Position(call.Pos())
133
- violations = append(violations, Violation{
134
- File: filePath,
135
- Line: pos.Line,
136
- Severity: "critical",
137
- Message: "Query on \"" + table + "\" has no organization/tenant predicate",
138
- Details: map[string]interface{}{
139
- "table": table,
140
- "method": method,
141
- },
142
- Suggestion: "Add the tenant column (organization_id / org_id) to the WHERE predicate",
143
- Analyzer: "go",
144
- Rule: "missing-org-filter",
145
- })
146
- }
147
-
148
- // unfiltered-query: a write (INSERT/UPDATE/DELETE) with no
149
- // WHERE/HAVING/LIMIT. INSERT counts as a write here — the corpus pins
150
- // it — whereas the TS rule scopes writes to DELETE/UPDATE; an
151
- // unparameterized mass INSERT is the same "no filter" shape.
152
- if isWriteVerb(verb) && !hasWhere {
153
- pos := a.parser.fileSet.Position(call.Pos())
154
- violations = append(violations, Violation{
155
- File: filePath,
156
- Line: pos.Line,
157
- Severity: "high",
158
- Message: "Write query on \"" + table + "\" has no WHERE/HAVING/LIMIT",
159
- Details: map[string]interface{}{
160
- "table": table,
161
- "method": method,
162
- },
163
- Suggestion: "Add a WHERE/HAVING/LIMIT to scope the write",
164
- Analyzer: "go",
165
- Rule: "unfiltered-query",
166
- })
167
- }
168
-
169
- return true
170
- })
171
- }
172
-
173
- return violations
174
- }
175
-
176
- // dbMethodName reports whether the call is a `database/sql`, `sqlx`, or GORM
177
- // method invocation and returns the selector name plus the index of the
178
- // SQL-string argument within the call. The method set is the `database/sql`
179
- // query/exec/prepare surface, the `sqlx` wrapper surface, and GORM's `Raw`
180
- // (its one full-SQL literal method); it deliberately excludes `Close`,
181
- // `Commit`, `Rollback`, `Err`, and `Next`, which are not SQL-bearing.
182
- //
183
- // The SQL argument is not always arg[0], and getting the index wrong is a
184
- // silent no-op (the analyzer extracts the wrong expression, sees it is not a
185
- // string literal, and returns early). Two families carry the SQL later:
186
- //
187
- // - **Context variants** (`QueryContext`, `ExecContext`, `QueryxContext`,
188
- // `MustExecContext`, …) put `ctx context.Context` first, so the SQL is
189
- // arg[1]. This is the canonical parameterized form since Go 1.8 — the
190
- // overwhelmingly common shape in production code — so the index matters
191
- // more here than for the bare forms.
192
- // - **sqlx `Get`/`Select`** put the destination pointer before the SQL
193
- // (`Get(dest, query, args…)`), so the SQL is arg[1]; with `ctx` it is
194
- // arg[2] (`GetContext(ctx, dest, query, args…)`).
195
- func dbMethodName(call *ast.CallExpr) (string, int, bool) {
196
- sel, ok := call.Fun.(*ast.SelectorExpr)
197
- if !ok {
198
- return "", -1, false
199
- }
200
- switch sel.Sel.Name {
201
- // database/sql — SQL string is arg[0].
202
- case "Query", "QueryRow", "Exec", "Prepare":
203
- return sel.Sel.Name, 0, true
204
- // database/sql Context — ctx first, SQL string is arg[1].
205
- case "QueryContext", "QueryRowContext", "ExecContext", "PrepareContext":
206
- return sel.Sel.Name, 1, true
207
- // sqlx — SQL string is arg[0].
208
- case "Queryx", "QueryRowx", "NamedExec", "NamedQuery", "MustExec":
209
- return sel.Sel.Name, 0, true
210
- // sqlx Context — ctx first, SQL string is arg[1].
211
- case "QueryxContext", "QueryRowxContext", "NamedExecContext", "NamedQueryContext", "MustExecContext":
212
- return sel.Sel.Name, 1, true
213
- // sqlx — SQL string is arg[1] (after the destination pointer).
214
- case "Get", "Select":
215
- return sel.Sel.Name, 1, true
216
- // sqlx — SQL string is arg[2] (after ctx + destination pointer).
217
- case "GetContext", "SelectContext":
218
- return sel.Sel.Name, 2, true
219
- // GORM — `Raw(sql, values…)` is GORM's full-SQL literal method; SQL is
220
- // arg[0]. GORM's `Exec`/`Select` are intentionally NOT listed here: `Exec`
221
- // is already the database/sql case above, and GORM's `Select` takes a
222
- // column list (`Select("name, age")`), not a full statement.
223
- case "Raw":
224
- return sel.Sel.Name, 0, true
225
- }
226
- return "", -1, false
227
- }
228
-
229
- // isDynamicSQL reports whether the SQL argument is constructed at runtime
230
- // (string formatting or concatenation) rather than a single string literal.
231
- func isDynamicSQL(expr ast.Expr) bool {
232
- switch e := expr.(type) {
233
- case *ast.BasicLit:
234
- return false
235
- case *ast.CallExpr:
236
- // Any call producing the SQL (fmt.Sprintf, a query builder, …) is
237
- // dynamic — its text is not a constant the analyzer can inspect.
238
- return true
239
- case *ast.BinaryExpr:
240
- return e.Op == token.ADD
241
- default:
242
- // A bare identifier is a variable-held string: treated as static (not
243
- // flagged), since there is no construction site to name as the risk.
244
- return false
245
- }
246
- }
247
-
248
- // literalString returns the unquoted value of a string literal, or "".
249
- func literalString(expr ast.Expr) string {
250
- lit, ok := expr.(*ast.BasicLit)
251
- if !ok || lit.Kind != token.STRING {
252
- return ""
253
- }
254
- s, err := strconv.Unquote(lit.Value)
255
- if err != nil {
256
- return lit.Value
257
- }
258
- return s
259
- }
260
-
261
- // sqlFormatString returns the format string of a Sprintf-style call (its first
262
- // argument when that argument is a literal), else "".
263
- func sqlFormatString(expr ast.Expr) string {
264
- call, ok := expr.(*ast.CallExpr)
265
- if !ok || len(call.Args) == 0 {
266
- return ""
267
- }
268
- return literalString(call.Args[0])
269
- }
270
-
271
- // containsSQLVerb reports whether a (possibly dynamic) SQL fragment contains a
272
- // DML keyword — the signal that a formatted string is actually SQL, not e.g.
273
- // a `fmt.Sprintf` of a display label passed as a query argument by accident.
274
- func containsSQLVerb(s string) bool {
275
- up := strings.ToUpper(s)
276
- return strings.Contains(up, "SELECT") ||
277
- strings.Contains(up, "INSERT") ||
278
- strings.Contains(up, "UPDATE") ||
279
- strings.Contains(up, "DELETE") ||
280
- strings.Contains(up, "FROM")
281
- }
282
-
283
- // sqlVerb returns the leading DML keyword of a SQL statement, or "".
284
- func sqlVerb(sql string) string {
285
- up := strings.ToUpper(strings.TrimSpace(sql))
286
- switch {
287
- case strings.HasPrefix(up, "SELECT"):
288
- return "SELECT"
289
- case strings.HasPrefix(up, "INSERT"):
290
- return "INSERT"
291
- case strings.HasPrefix(up, "UPDATE"):
292
- return "UPDATE"
293
- case strings.HasPrefix(up, "DELETE"):
294
- return "DELETE"
295
- }
296
- return ""
297
- }
298
-
299
- // extractTable returns the lowercased table name referenced by FROM/INTO/UPDATE,
300
- // or "". A schema prefix (`public.users`) is stripped to the bare name.
301
- func extractTable(sql string) string {
302
- m := tableExtractRe.FindStringSubmatch(sql)
303
- if m == nil {
304
- return ""
305
- }
306
- table := m[1]
307
- if idx := strings.LastIndexByte(table, '.'); idx >= 0 {
308
- table = table[idx+1:]
309
- }
310
- return strings.ToLower(table)
311
- }
312
-
313
- // nearMissTable reports whether a table name is in the declared known-table
314
- // catalog; when it is not, and it is a singular/plural near-miss of a known
315
- // name, it returns the corrected name. The `user` vs `users` singular→plural
316
- // direction is what fires `unknown-table`. The catalog is empty when the caller
317
- // declared no known tables — then the rule cannot accuse (fail-open, matching
318
- // the TS schema reducer).
319
- func nearMissTable(knownTables map[string]bool, table string) (near string, known bool) {
320
- if knownTables[table] {
321
- return "", true
322
- }
323
- if knownTables[table+"s"] {
324
- return table + "s", false
325
- }
326
- if knownTables[table+"es"] {
327
- return table + "es", false
328
- }
329
- if strings.HasSuffix(table, "s") {
330
- if base := strings.TrimSuffix(table, "s"); knownTables[base] {
331
- return base, false
332
- }
333
- }
334
- if strings.HasSuffix(table, "es") {
335
- if base := strings.TrimSuffix(table, "es"); knownTables[base] {
336
- return base, false
337
- }
338
- }
339
- return "", false
340
- }
341
-
342
- // declaredTenantTables builds the tenant-scoped table set from the resolved
343
- // tiers the caller passed in `orgFilterTables`. Empty when the caller declared
344
- // no tenancy — the honest result is "no tenant tables", not a guessed list.
345
- func (a *Analyzer) declaredTenantTables() map[string]bool {
346
- set := make(map[string]bool, len(a.options.OrgFilterTables))
347
- for _, t := range a.options.OrgFilterTables {
348
- set[strings.ToLower(t)] = true
349
- }
350
- return set
351
- }
352
-
353
- // declaredKnownTables builds the known-table catalog from the caller's
354
- // `knownTables`. An empty catalog means `unknown-table` cannot accuse.
355
- func (a *Analyzer) declaredKnownTables() map[string]bool {
356
- set := make(map[string]bool, len(a.options.KnownTables))
357
- for _, t := range a.options.KnownTables {
358
- set[strings.ToLower(t)] = true
359
- }
360
- return set
361
- }
362
-
363
- // tenantPredicateRegex builds the tenant-predicate matcher from the configured
364
- // tenant columns (or the default set when none were supplied). Each column name
365
- // is regex-escaped and word-boundary-matched so a tenant column referenced
366
- // anywhere in the SQL counts as a tenant predicate.
367
- func (a *Analyzer) tenantPredicateRegex() *regexp.Regexp {
368
- cols := a.options.OrgFilterColumns
369
- if len(cols) == 0 {
370
- cols = defaultOrgFilterColumns
371
- }
372
- alts := make([]string, 0, len(cols))
373
- for _, c := range cols {
374
- if c == "" {
375
- continue
376
- }
377
- alts = append(alts, regexp.QuoteMeta(strings.ToLower(c)))
378
- }
379
- if len(alts) == 0 {
380
- alts = append(alts, regexp.QuoteMeta(defaultOrgFilterColumns[0]))
381
- }
382
- return regexp.MustCompile(`(?i)\b(?:` + strings.Join(alts, "|") + `)\b`)
383
- }
384
-
385
- // isWriteVerb reports whether the verb mutates rows (INSERT/UPDATE/DELETE).
386
- func isWriteVerb(verb string) bool {
387
- return verb == "INSERT" || verb == "UPDATE" || verb == "DELETE"
388
- }
@@ -1,3 +0,0 @@
1
- module code-auditor-go/analyzer
2
-
3
- go 1.19
@@ -1,268 +0,0 @@
1
- package analyzer
2
-
3
- import (
4
- "fmt"
5
- "path/filepath"
6
- )
7
-
8
- // Indexer creates index entries for Go entities
9
- type Indexer struct {
10
- parser *Parser
11
- }
12
-
13
- // NewIndexer creates a new indexer
14
- func NewIndexer(parser *Parser) *Indexer {
15
- return &Indexer{
16
- parser: parser,
17
- }
18
- }
19
-
20
- // GenerateIndexEntries creates index entries for all parsed entities
21
- func (i *Indexer) GenerateIndexEntries() []IndexEntry {
22
- // Non-nil empty slice so zero entries serialize to [] not null.
23
- entries := make([]IndexEntry, 0)
24
-
25
- // Index functions
26
- functions := i.parser.ExtractFunctions()
27
- for _, function := range functions {
28
- entry := i.createFunctionIndexEntry(function)
29
- entries = append(entries, entry)
30
- }
31
-
32
- // Index structs
33
- structs := i.parser.ExtractStructs()
34
- for _, structInfo := range structs {
35
- entry := i.createStructIndexEntry(structInfo)
36
- entries = append(entries, entry)
37
- }
38
-
39
- // Index interfaces
40
- interfaces := i.parser.ExtractInterfaces()
41
- for _, interfaceInfo := range interfaces {
42
- entry := i.createInterfaceIndexEntry(interfaceInfo)
43
- entries = append(entries, entry)
44
- }
45
-
46
- return entries
47
- }
48
-
49
- // createFunctionIndexEntry creates an index entry for a function
50
- func (i *Indexer) createFunctionIndexEntry(function Function) IndexEntry {
51
- return IndexEntry{
52
- ID: i.generateID("function", function.File, function.Name, function.StartLine),
53
- Name: function.Name,
54
- Type: "function",
55
- Language: "go",
56
- File: function.File,
57
- Signature: function.Signature,
58
- Parameters: function.Parameters,
59
- Purpose: function.Purpose,
60
- Context: i.generateContext(function.EntityInfo),
61
- StartLine: function.StartLine,
62
- EndLine: function.EndLine,
63
- Metadata: map[string]interface{}{
64
- "isMethod": function.IsMethod,
65
- "isExported": function.IsExported,
66
- "receiver": function.Receiver,
67
- "returnType": function.ReturnType,
68
- "complexity": function.Complexity,
69
- "package": function.Package,
70
- "dependencies": function.Dependencies,
71
- },
72
- }
73
- }
74
-
75
- // createStructIndexEntry creates an index entry for a struct
76
- func (i *Indexer) createStructIndexEntry(structInfo Struct) IndexEntry {
77
- return IndexEntry{
78
- ID: i.generateID("struct", structInfo.File, structInfo.Name, structInfo.StartLine),
79
- Name: structInfo.Name,
80
- Type: "struct",
81
- Language: "go",
82
- File: structInfo.File,
83
- Signature: structInfo.Signature,
84
- Purpose: i.generateStructPurpose(structInfo),
85
- Context: i.generateContext(structInfo.EntityInfo),
86
- StartLine: structInfo.StartLine,
87
- EndLine: structInfo.EndLine,
88
- Metadata: map[string]interface{}{
89
- "isExported": structInfo.IsExported,
90
- "fieldCount": len(structInfo.Fields),
91
- "fields": i.serializeFields(structInfo.Fields),
92
- "methods": structInfo.Methods,
93
- "package": structInfo.Package,
94
- },
95
- }
96
- }
97
-
98
- // createInterfaceIndexEntry creates an index entry for an interface
99
- func (i *Indexer) createInterfaceIndexEntry(interfaceInfo Interface) IndexEntry {
100
- return IndexEntry{
101
- ID: i.generateID("interface", interfaceInfo.File, interfaceInfo.Name, interfaceInfo.StartLine),
102
- Name: interfaceInfo.Name,
103
- Type: "interface",
104
- Language: "go",
105
- File: interfaceInfo.File,
106
- Signature: interfaceInfo.Signature,
107
- Purpose: i.generateInterfacePurpose(interfaceInfo),
108
- Context: i.generateContext(interfaceInfo.EntityInfo),
109
- StartLine: interfaceInfo.StartLine,
110
- EndLine: interfaceInfo.EndLine,
111
- Metadata: map[string]interface{}{
112
- "isExported": interfaceInfo.IsExported,
113
- "methodCount": len(interfaceInfo.Methods),
114
- "methods": i.serializeMethods(interfaceInfo.Methods),
115
- "package": interfaceInfo.Package,
116
- },
117
- }
118
- }
119
-
120
- // generateID creates a unique ID for an entity
121
- func (i *Indexer) generateID(entityType, file, name string, line int) string {
122
- return fmt.Sprintf("go:%s:%s:%s:%d", entityType, filepath.Base(file), name, line)
123
- }
124
-
125
- // generateContext creates context information for an entity
126
- func (i *Indexer) generateContext(entity EntityInfo) string {
127
- return fmt.Sprintf("Go %s in package %s at %s:%d",
128
- entity.Type, entity.Package, filepath.Base(entity.File), entity.StartLine)
129
- }
130
-
131
- // generateStructPurpose creates a purpose description for a struct
132
- func (i *Indexer) generateStructPurpose(structInfo Struct) string {
133
- if structInfo.Purpose != "" {
134
- return structInfo.Purpose
135
- }
136
-
137
- fieldCount := len(structInfo.Fields)
138
- if fieldCount == 0 {
139
- return fmt.Sprintf("Empty struct %s", structInfo.Name)
140
- }
141
-
142
- return fmt.Sprintf("Data structure with %d fields representing %s",
143
- fieldCount, i.inferStructPurpose(structInfo))
144
- }
145
-
146
- // generateInterfacePurpose creates a purpose description for an interface
147
- func (i *Indexer) generateInterfacePurpose(interfaceInfo Interface) string {
148
- if interfaceInfo.Purpose != "" {
149
- return interfaceInfo.Purpose
150
- }
151
-
152
- methodCount := len(interfaceInfo.Methods)
153
- if methodCount == 0 {
154
- return fmt.Sprintf("Empty interface %s", interfaceInfo.Name)
155
- }
156
-
157
- return fmt.Sprintf("Interface defining %d methods for %s behavior",
158
- methodCount, i.inferInterfacePurpose(interfaceInfo))
159
- }
160
-
161
- // inferStructPurpose tries to infer the purpose of a struct from its name and fields
162
- func (i *Indexer) inferStructPurpose(structInfo Struct) string {
163
- name := structInfo.Name
164
-
165
- // Common patterns in Go struct names
166
- if containsAny(name, []string{"Config", "Configuration"}) {
167
- return "configuration data"
168
- }
169
- if containsAny(name, []string{"Request", "Req"}) {
170
- return "request data"
171
- }
172
- if containsAny(name, []string{"Response", "Resp"}) {
173
- return "response data"
174
- }
175
- if containsAny(name, []string{"Handler", "Controller"}) {
176
- return "request handling"
177
- }
178
- if containsAny(name, []string{"Service", "Manager"}) {
179
- return "business logic"
180
- }
181
- if containsAny(name, []string{"Repository", "Repo", "Store"}) {
182
- return "data access"
183
- }
184
- if containsAny(name, []string{"Model", "Entity"}) {
185
- return "data model"
186
- }
187
- if containsAny(name, []string{"Client", "Adapter"}) {
188
- return "external integration"
189
- }
190
-
191
- return "entity data"
192
- }
193
-
194
- // inferInterfacePurpose tries to infer the purpose of an interface from its name and methods
195
- func (i *Indexer) inferInterfacePurpose(interfaceInfo Interface) string {
196
- name := interfaceInfo.Name
197
-
198
- // Common patterns in Go interface names
199
- if containsAny(name, []string{"Reader", "Writer", "ReadWriter"}) {
200
- return "I/O operations"
201
- }
202
- if containsAny(name, []string{"Handler", "Processor"}) {
203
- return "request processing"
204
- }
205
- if containsAny(name, []string{"Repository", "Store"}) {
206
- return "data storage"
207
- }
208
- if containsAny(name, []string{"Service", "Provider"}) {
209
- return "service operations"
210
- }
211
- if containsAny(name, []string{"Client", "Adapter"}) {
212
- return "external communication"
213
- }
214
- if containsAny(name, []string{"Validator", "Checker"}) {
215
- return "validation logic"
216
- }
217
- if containsAny(name, []string{"Builder", "Factory"}) {
218
- return "object creation"
219
- }
220
-
221
- return "behavioral contract"
222
- }
223
-
224
- // serializeFields converts struct fields to a serializable format
225
- func (i *Indexer) serializeFields(fields []Field) []map[string]interface{} {
226
- var serialized []map[string]interface{}
227
-
228
- for _, field := range fields {
229
- serialized = append(serialized, map[string]interface{}{
230
- "name": field.Name,
231
- "type": field.Type,
232
- "tag": field.Tag,
233
- "isExported": field.IsExported,
234
- })
235
- }
236
-
237
- return serialized
238
- }
239
-
240
- // serializeMethods converts interface methods to a serializable format
241
- func (i *Indexer) serializeMethods(methods []Method) []map[string]interface{} {
242
- var serialized []map[string]interface{}
243
-
244
- for _, method := range methods {
245
- serialized = append(serialized, map[string]interface{}{
246
- "name": method.Name,
247
- "signature": method.Signature,
248
- "parameters": method.Parameters,
249
- "returnType": method.ReturnType,
250
- })
251
- }
252
-
253
- return serialized
254
- }
255
-
256
- // containsAny checks if a string contains any of the given substrings
257
- func containsAny(str string, substrings []string) bool {
258
- for _, substring := range substrings {
259
- if len(str) >= len(substring) {
260
- for i := 0; i <= len(str)-len(substring); i++ {
261
- if str[i:i+len(substring)] == substring {
262
- return true
263
- }
264
- }
265
- }
266
- }
267
- return false
268
- }