api-tests-coverage 1.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 (288) hide show
  1. package/README.md +703 -0
  2. package/config.yaml.example +227 -0
  3. package/dist/action/src/index.d.ts +2 -0
  4. package/dist/action/src/index.d.ts.map +1 -0
  5. package/dist/action/src/index.js +349 -0
  6. package/dist/action/src/prComment.d.ts +34 -0
  7. package/dist/action/src/prComment.d.ts.map +1 -0
  8. package/dist/action/src/prComment.js +146 -0
  9. package/dist/src/ast/astAnalysisOrchestrator.d.ts +36 -0
  10. package/dist/src/ast/astAnalysisOrchestrator.d.ts.map +1 -0
  11. package/dist/src/ast/astAnalysisOrchestrator.js +123 -0
  12. package/dist/src/ast/astTypes.d.ts +105 -0
  13. package/dist/src/ast/astTypes.d.ts.map +1 -0
  14. package/dist/src/ast/astTypes.js +9 -0
  15. package/dist/src/ast/languageAnalyzer.d.ts +46 -0
  16. package/dist/src/ast/languageAnalyzer.d.ts.map +1 -0
  17. package/dist/src/ast/languageAnalyzer.js +9 -0
  18. package/dist/src/ast/languageCapabilities.d.ts +24 -0
  19. package/dist/src/ast/languageCapabilities.d.ts.map +1 -0
  20. package/dist/src/ast/languageCapabilities.js +92 -0
  21. package/dist/src/ast/parseFile.d.ts +16 -0
  22. package/dist/src/ast/parseFile.d.ts.map +1 -0
  23. package/dist/src/ast/parseFile.js +65 -0
  24. package/dist/src/ast/parserRegistry.d.ts +39 -0
  25. package/dist/src/ast/parserRegistry.d.ts.map +1 -0
  26. package/dist/src/ast/parserRegistry.js +66 -0
  27. package/dist/src/buildSummary.d.ts +26 -0
  28. package/dist/src/buildSummary.d.ts.map +1 -0
  29. package/dist/src/buildSummary.js +193 -0
  30. package/dist/src/businessCoverage.d.ts +68 -0
  31. package/dist/src/businessCoverage.d.ts.map +1 -0
  32. package/dist/src/businessCoverage.js +290 -0
  33. package/dist/src/compatibilityCoverage.d.ts +83 -0
  34. package/dist/src/compatibilityCoverage.d.ts.map +1 -0
  35. package/dist/src/compatibilityCoverage.js +501 -0
  36. package/dist/src/config/defaultConfig.d.ts +9 -0
  37. package/dist/src/config/defaultConfig.d.ts.map +1 -0
  38. package/dist/src/config/defaultConfig.js +97 -0
  39. package/dist/src/config/index.d.ts +12 -0
  40. package/dist/src/config/index.d.ts.map +1 -0
  41. package/dist/src/config/index.js +37 -0
  42. package/dist/src/config/loadConfig.d.ts +29 -0
  43. package/dist/src/config/loadConfig.d.ts.map +1 -0
  44. package/dist/src/config/loadConfig.js +135 -0
  45. package/dist/src/config/mergeConfig.d.ts +15 -0
  46. package/dist/src/config/mergeConfig.d.ts.map +1 -0
  47. package/dist/src/config/mergeConfig.js +57 -0
  48. package/dist/src/config/schema.d.ts +15 -0
  49. package/dist/src/config/schema.d.ts.map +1 -0
  50. package/dist/src/config/schema.js +30 -0
  51. package/dist/src/config/types.d.ts +175 -0
  52. package/dist/src/config/types.d.ts.map +1 -0
  53. package/dist/src/config/types.js +9 -0
  54. package/dist/src/config/validateConfig.d.ts +22 -0
  55. package/dist/src/config/validateConfig.d.ts.map +1 -0
  56. package/dist/src/config/validateConfig.js +171 -0
  57. package/dist/src/config.d.ts +168 -0
  58. package/dist/src/config.d.ts.map +1 -0
  59. package/dist/src/config.js +204 -0
  60. package/dist/src/coverage/deep-analysis/callGraph.d.ts +67 -0
  61. package/dist/src/coverage/deep-analysis/callGraph.d.ts.map +1 -0
  62. package/dist/src/coverage/deep-analysis/callGraph.js +275 -0
  63. package/dist/src/coverage/deep-analysis/deepEndpointResolver.d.ts +23 -0
  64. package/dist/src/coverage/deep-analysis/deepEndpointResolver.d.ts.map +1 -0
  65. package/dist/src/coverage/deep-analysis/deepEndpointResolver.js +394 -0
  66. package/dist/src/coverage/deep-analysis/index.d.ts +17 -0
  67. package/dist/src/coverage/deep-analysis/index.d.ts.map +1 -0
  68. package/dist/src/coverage/deep-analysis/index.js +63 -0
  69. package/dist/src/coverage/deep-analysis/resolveAssertions.d.ts +60 -0
  70. package/dist/src/coverage/deep-analysis/resolveAssertions.d.ts.map +1 -0
  71. package/dist/src/coverage/deep-analysis/resolveAssertions.js +121 -0
  72. package/dist/src/coverage/deep-analysis/resolveConstants.d.ts +36 -0
  73. package/dist/src/coverage/deep-analysis/resolveConstants.d.ts.map +1 -0
  74. package/dist/src/coverage/deep-analysis/resolveConstants.js +92 -0
  75. package/dist/src/coverage/deep-analysis/resolveEnums.d.ts +55 -0
  76. package/dist/src/coverage/deep-analysis/resolveEnums.d.ts.map +1 -0
  77. package/dist/src/coverage/deep-analysis/resolveEnums.js +152 -0
  78. package/dist/src/coverage/deep-analysis/resolveMethodChains.d.ts +70 -0
  79. package/dist/src/coverage/deep-analysis/resolveMethodChains.d.ts.map +1 -0
  80. package/dist/src/coverage/deep-analysis/resolveMethodChains.js +152 -0
  81. package/dist/src/coverage/deep-analysis/resolvePaths.d.ts +80 -0
  82. package/dist/src/coverage/deep-analysis/resolvePaths.d.ts.map +1 -0
  83. package/dist/src/coverage/deep-analysis/resolvePaths.js +216 -0
  84. package/dist/src/coverage/deep-analysis/resolveRequestWrappers.d.ts +71 -0
  85. package/dist/src/coverage/deep-analysis/resolveRequestWrappers.d.ts.map +1 -0
  86. package/dist/src/coverage/deep-analysis/resolveRequestWrappers.js +226 -0
  87. package/dist/src/coverage/deep-analysis/symbolTable.d.ts +58 -0
  88. package/dist/src/coverage/deep-analysis/symbolTable.d.ts.map +1 -0
  89. package/dist/src/coverage/deep-analysis/symbolTable.js +230 -0
  90. package/dist/src/coverage/deep-analysis/types.d.ts +122 -0
  91. package/dist/src/coverage/deep-analysis/types.d.ts.map +1 -0
  92. package/dist/src/coverage/deep-analysis/types.js +21 -0
  93. package/dist/src/discovery/fileClassifier.d.ts +50 -0
  94. package/dist/src/discovery/fileClassifier.d.ts.map +1 -0
  95. package/dist/src/discovery/fileClassifier.js +238 -0
  96. package/dist/src/discovery/projectDiscovery.d.ts +66 -0
  97. package/dist/src/discovery/projectDiscovery.d.ts.map +1 -0
  98. package/dist/src/discovery/projectDiscovery.js +287 -0
  99. package/dist/src/endpointCoverage.d.ts +70 -0
  100. package/dist/src/endpointCoverage.d.ts.map +1 -0
  101. package/dist/src/endpointCoverage.js +381 -0
  102. package/dist/src/errorCoverage.d.ts +93 -0
  103. package/dist/src/errorCoverage.d.ts.map +1 -0
  104. package/dist/src/errorCoverage.js +698 -0
  105. package/dist/src/index.d.ts +3 -0
  106. package/dist/src/index.d.ts.map +1 -0
  107. package/dist/src/index.js +1441 -0
  108. package/dist/src/inference/businessRuleInference.d.ts +63 -0
  109. package/dist/src/inference/businessRuleInference.d.ts.map +1 -0
  110. package/dist/src/inference/businessRuleInference.js +268 -0
  111. package/dist/src/inference/integrationFlowInference.d.ts +56 -0
  112. package/dist/src/inference/integrationFlowInference.d.ts.map +1 -0
  113. package/dist/src/inference/integrationFlowInference.js +266 -0
  114. package/dist/src/integrationCoverage.d.ts +72 -0
  115. package/dist/src/integrationCoverage.d.ts.map +1 -0
  116. package/dist/src/integrationCoverage.js +317 -0
  117. package/dist/src/intelligence/index.d.ts +20 -0
  118. package/dist/src/intelligence/index.d.ts.map +1 -0
  119. package/dist/src/intelligence/index.js +105 -0
  120. package/dist/src/intelligence/linkageEngine.d.ts +20 -0
  121. package/dist/src/intelligence/linkageEngine.d.ts.map +1 -0
  122. package/dist/src/intelligence/linkageEngine.js +522 -0
  123. package/dist/src/intelligence/markdownReporter.d.ts +12 -0
  124. package/dist/src/intelligence/markdownReporter.d.ts.map +1 -0
  125. package/dist/src/intelligence/markdownReporter.js +265 -0
  126. package/dist/src/intelligence/riskScoring.d.ts +53 -0
  127. package/dist/src/intelligence/riskScoring.d.ts.map +1 -0
  128. package/dist/src/intelligence/riskScoring.js +181 -0
  129. package/dist/src/intelligence/types.d.ts +121 -0
  130. package/dist/src/intelligence/types.d.ts.map +1 -0
  131. package/dist/src/intelligence/types.js +8 -0
  132. package/dist/src/languageDetection.d.ts +100 -0
  133. package/dist/src/languageDetection.d.ts.map +1 -0
  134. package/dist/src/languageDetection.js +349 -0
  135. package/dist/src/languages/java/index.d.ts +16 -0
  136. package/dist/src/languages/java/index.d.ts.map +1 -0
  137. package/dist/src/languages/java/index.js +103 -0
  138. package/dist/src/languages/java/parser.d.ts +7 -0
  139. package/dist/src/languages/java/parser.d.ts.map +1 -0
  140. package/dist/src/languages/java/parser.js +50 -0
  141. package/dist/src/languages/java/semanticBuilder.d.ts +21 -0
  142. package/dist/src/languages/java/semanticBuilder.d.ts.map +1 -0
  143. package/dist/src/languages/java/semanticBuilder.js +358 -0
  144. package/dist/src/languages/javascript/annotationExtractor.d.ts +20 -0
  145. package/dist/src/languages/javascript/annotationExtractor.d.ts.map +1 -0
  146. package/dist/src/languages/javascript/annotationExtractor.js +94 -0
  147. package/dist/src/languages/javascript/assertionResolver.d.ts +18 -0
  148. package/dist/src/languages/javascript/assertionResolver.d.ts.map +1 -0
  149. package/dist/src/languages/javascript/assertionResolver.js +150 -0
  150. package/dist/src/languages/javascript/callResolver.d.ts +23 -0
  151. package/dist/src/languages/javascript/callResolver.d.ts.map +1 -0
  152. package/dist/src/languages/javascript/callResolver.js +236 -0
  153. package/dist/src/languages/javascript/httpInteractionExtractor.d.ts +23 -0
  154. package/dist/src/languages/javascript/httpInteractionExtractor.d.ts.map +1 -0
  155. package/dist/src/languages/javascript/httpInteractionExtractor.js +205 -0
  156. package/dist/src/languages/javascript/index.d.ts +20 -0
  157. package/dist/src/languages/javascript/index.d.ts.map +1 -0
  158. package/dist/src/languages/javascript/index.js +136 -0
  159. package/dist/src/languages/javascript/parser.d.ts +14 -0
  160. package/dist/src/languages/javascript/parser.d.ts.map +1 -0
  161. package/dist/src/languages/javascript/parser.js +38 -0
  162. package/dist/src/languages/javascript/symbolResolver.d.ts +31 -0
  163. package/dist/src/languages/javascript/symbolResolver.d.ts.map +1 -0
  164. package/dist/src/languages/javascript/symbolResolver.js +183 -0
  165. package/dist/src/languages/kotlin/index.d.ts +16 -0
  166. package/dist/src/languages/kotlin/index.d.ts.map +1 -0
  167. package/dist/src/languages/kotlin/index.js +151 -0
  168. package/dist/src/languages/kotlin/parser.d.ts +11 -0
  169. package/dist/src/languages/kotlin/parser.d.ts.map +1 -0
  170. package/dist/src/languages/kotlin/parser.js +74 -0
  171. package/dist/src/languages/python/index.d.ts +15 -0
  172. package/dist/src/languages/python/index.d.ts.map +1 -0
  173. package/dist/src/languages/python/index.js +293 -0
  174. package/dist/src/languages/ruby/index.d.ts +15 -0
  175. package/dist/src/languages/ruby/index.d.ts.map +1 -0
  176. package/dist/src/languages/ruby/index.js +274 -0
  177. package/dist/src/languages/shared/treeSitterUtils.d.ts +43 -0
  178. package/dist/src/languages/shared/treeSitterUtils.d.ts.map +1 -0
  179. package/dist/src/languages/shared/treeSitterUtils.js +100 -0
  180. package/dist/src/languages/typescript/index.d.ts +14 -0
  181. package/dist/src/languages/typescript/index.d.ts.map +1 -0
  182. package/dist/src/languages/typescript/index.js +25 -0
  183. package/dist/src/lib/index.d.ts +228 -0
  184. package/dist/src/lib/index.d.ts.map +1 -0
  185. package/dist/src/lib/index.js +486 -0
  186. package/dist/src/mcp/client/index.d.ts +37 -0
  187. package/dist/src/mcp/client/index.d.ts.map +1 -0
  188. package/dist/src/mcp/client/index.js +235 -0
  189. package/dist/src/mcp/config.d.ts +50 -0
  190. package/dist/src/mcp/config.d.ts.map +1 -0
  191. package/dist/src/mcp/config.js +125 -0
  192. package/dist/src/mcp/events.d.ts +24 -0
  193. package/dist/src/mcp/events.d.ts.map +1 -0
  194. package/dist/src/mcp/events.js +48 -0
  195. package/dist/src/mcp/fallback/index.d.ts +50 -0
  196. package/dist/src/mcp/fallback/index.d.ts.map +1 -0
  197. package/dist/src/mcp/fallback/index.js +216 -0
  198. package/dist/src/mcp/index.d.ts +67 -0
  199. package/dist/src/mcp/index.d.ts.map +1 -0
  200. package/dist/src/mcp/index.js +212 -0
  201. package/dist/src/mcp/normalizer.d.ts +21 -0
  202. package/dist/src/mcp/normalizer.d.ts.map +1 -0
  203. package/dist/src/mcp/normalizer.js +99 -0
  204. package/dist/src/mcp/prompts/index.d.ts +86 -0
  205. package/dist/src/mcp/prompts/index.d.ts.map +1 -0
  206. package/dist/src/mcp/prompts/index.js +304 -0
  207. package/dist/src/mcp/templates/index.d.ts +35 -0
  208. package/dist/src/mcp/templates/index.d.ts.map +1 -0
  209. package/dist/src/mcp/templates/index.js +143 -0
  210. package/dist/src/mcp/testing/mock-server/index.d.ts +47 -0
  211. package/dist/src/mcp/testing/mock-server/index.d.ts.map +1 -0
  212. package/dist/src/mcp/testing/mock-server/index.js +157 -0
  213. package/dist/src/mcp/types.d.ts +127 -0
  214. package/dist/src/mcp/types.d.ts.map +1 -0
  215. package/dist/src/mcp/types.js +8 -0
  216. package/dist/src/observability.d.ts +138 -0
  217. package/dist/src/observability.d.ts.map +1 -0
  218. package/dist/src/observability.js +519 -0
  219. package/dist/src/parameterCoverage.d.ts +75 -0
  220. package/dist/src/parameterCoverage.d.ts.map +1 -0
  221. package/dist/src/parameterCoverage.js +629 -0
  222. package/dist/src/perfResilienceCoverage.d.ts +155 -0
  223. package/dist/src/perfResilienceCoverage.d.ts.map +1 -0
  224. package/dist/src/perfResilienceCoverage.js +670 -0
  225. package/dist/src/pluginLoader.d.ts +51 -0
  226. package/dist/src/pluginLoader.d.ts.map +1 -0
  227. package/dist/src/pluginLoader.js +72 -0
  228. package/dist/src/publishing.d.ts +63 -0
  229. package/dist/src/publishing.d.ts.map +1 -0
  230. package/dist/src/publishing.js +379 -0
  231. package/dist/src/qualityGate.d.ts +58 -0
  232. package/dist/src/qualityGate.d.ts.map +1 -0
  233. package/dist/src/qualityGate.js +118 -0
  234. package/dist/src/reporting.d.ts +41 -0
  235. package/dist/src/reporting.d.ts.map +1 -0
  236. package/dist/src/reporting.js +278 -0
  237. package/dist/src/screenshots.d.ts +71 -0
  238. package/dist/src/screenshots.d.ts.map +1 -0
  239. package/dist/src/screenshots.js +141 -0
  240. package/dist/src/security/gate/index.d.ts +11 -0
  241. package/dist/src/security/gate/index.d.ts.map +1 -0
  242. package/dist/src/security/gate/index.js +65 -0
  243. package/dist/src/security/index.d.ts +30 -0
  244. package/dist/src/security/index.d.ts.map +1 -0
  245. package/dist/src/security/index.js +342 -0
  246. package/dist/src/security/normalizers/semgrep.d.ts +10 -0
  247. package/dist/src/security/normalizers/semgrep.d.ts.map +1 -0
  248. package/dist/src/security/normalizers/semgrep.js +104 -0
  249. package/dist/src/security/normalizers/trivy.d.ts +10 -0
  250. package/dist/src/security/normalizers/trivy.d.ts.map +1 -0
  251. package/dist/src/security/normalizers/trivy.js +78 -0
  252. package/dist/src/security/normalizers/zap.d.ts +10 -0
  253. package/dist/src/security/normalizers/zap.d.ts.map +1 -0
  254. package/dist/src/security/normalizers/zap.js +104 -0
  255. package/dist/src/security/scanners/semgrep.d.ts +6 -0
  256. package/dist/src/security/scanners/semgrep.d.ts.map +1 -0
  257. package/dist/src/security/scanners/semgrep.js +125 -0
  258. package/dist/src/security/scanners/trivy.d.ts +6 -0
  259. package/dist/src/security/scanners/trivy.d.ts.map +1 -0
  260. package/dist/src/security/scanners/trivy.js +115 -0
  261. package/dist/src/security/scanners/zap.d.ts +6 -0
  262. package/dist/src/security/scanners/zap.d.ts.map +1 -0
  263. package/dist/src/security/scanners/zap.js +135 -0
  264. package/dist/src/security/types.d.ts +146 -0
  265. package/dist/src/security/types.d.ts.map +1 -0
  266. package/dist/src/security/types.js +6 -0
  267. package/dist/src/securityCoverage.d.ts +116 -0
  268. package/dist/src/securityCoverage.d.ts.map +1 -0
  269. package/dist/src/securityCoverage.js +725 -0
  270. package/dist/src/summary/buildSummary.d.ts +28 -0
  271. package/dist/src/summary/buildSummary.d.ts.map +1 -0
  272. package/dist/src/summary/buildSummary.js +257 -0
  273. package/dist/src/summary/evaluateMetrics.d.ts +31 -0
  274. package/dist/src/summary/evaluateMetrics.d.ts.map +1 -0
  275. package/dist/src/summary/evaluateMetrics.js +118 -0
  276. package/dist/src/summary/index.d.ts +10 -0
  277. package/dist/src/summary/index.d.ts.map +1 -0
  278. package/dist/src/summary/index.js +22 -0
  279. package/dist/src/summary/markdownRenderer.d.ts +139 -0
  280. package/dist/src/summary/markdownRenderer.d.ts.map +1 -0
  281. package/dist/src/summary/markdownRenderer.js +459 -0
  282. package/dist/src/summary/prSummary.d.ts +24 -0
  283. package/dist/src/summary/prSummary.d.ts.map +1 -0
  284. package/dist/src/summary/prSummary.js +233 -0
  285. package/dist/src/summary/summaryTypes.d.ts +35 -0
  286. package/dist/src/summary/summaryTypes.d.ts.map +1 -0
  287. package/dist/src/summary/summaryTypes.js +27 -0
  288. package/package.json +84 -0
@@ -0,0 +1,227 @@
1
+ # =============================================================================
2
+ # config.yaml.example — Annotated full reference configuration
3
+ #
4
+ # Copy this file to config.yaml and customize for your project.
5
+ # All fields are optional except `version`.
6
+ # When config.yaml is absent, the analyzer runs a full default profile and
7
+ # emits a warning. See docs/guides/configuration.md for the full reference.
8
+ # =============================================================================
9
+
10
+ # Required. Config schema version. Must be 1 for this release.
11
+ version: 1
12
+
13
+ # ── Project ──────────────────────────────────────────────────────────────────
14
+
15
+ project:
16
+ # Optional. Display name used in reports and summaries.
17
+ # Default: (absent)
18
+ name: my-api-project
19
+
20
+ # ── Analysis mode ─────────────────────────────────────────────────────────────
21
+
22
+ analysis:
23
+ # Optional. 'full' runs every scan type. 'custom' runs only explicitly-enabled types.
24
+ # Default: full
25
+ defaultMode: full
26
+
27
+ # Optional. If true, the analyzer exits non-zero when config.yaml is missing.
28
+ # Default: false
29
+ failOnConfigMissing: false
30
+
31
+ # Optional. If true, a warning is printed when config.yaml is absent.
32
+ # Default: true
33
+ warnOnConfigMissing: true
34
+
35
+ # ── AST-based analysis ──────────────────────────────────────────────────────
36
+ ast:
37
+ # Optional. Master AST switch. When false, all files use the regex pipeline.
38
+ # Default: true
39
+ enabled: true
40
+
41
+ # Optional. When true, if AST parsing succeeds but finds 0 HTTP interactions,
42
+ # the regex fallback runs and tags results with resolutionType:'heuristic' and
43
+ # confidence:'low'. When false, 0 AST results are returned verbatim.
44
+ # Default: true
45
+ fallbackHeuristics: true
46
+
47
+ # Optional. Maximum call-chain depth when tracing wrapper/helper functions.
48
+ # Default: 4
49
+ maxCallDepth: 4
50
+
51
+ # Optional. Link HTTP calls to downstream response assertions.
52
+ # Default: true
53
+ assertionAware: true
54
+
55
+ # Optional. Per-language enable/disable toggles.
56
+ languages:
57
+ javascript: { enabled: true }
58
+ typescript: { enabled: true }
59
+ java: { enabled: true }
60
+ kotlin: { enabled: true }
61
+ python: { enabled: true }
62
+ ruby: { enabled: true }
63
+ cucumber: { enabled: true }
64
+
65
+ # ── Scans ─────────────────────────────────────────────────────────────────────
66
+
67
+ scans:
68
+
69
+ # Coverage scan configuration
70
+ coverage:
71
+ # Optional. Set false to skip all coverage scans.
72
+ # Default: true
73
+ enabled: true
74
+
75
+ # Optional. Which coverage types to run.
76
+ # Valid values: endpoint | parameter | business | integration | error |
77
+ # security | performance | compatibility
78
+ # Default: all types
79
+ types:
80
+ - endpoint
81
+ - parameter
82
+ - business
83
+ - integration
84
+ - error
85
+ - security
86
+ - performance
87
+ - compatibility
88
+
89
+ # Security scanner configuration
90
+ security:
91
+ # Optional. Set false to skip all security scanners.
92
+ # Default: true
93
+ enabled: true
94
+
95
+ # Optional. Which security scanners to run (only runs if scanner is installed).
96
+ # Valid values: semgrep | trivy | zap
97
+ # Default: all scanners
98
+ scanners:
99
+ - semgrep
100
+ - trivy
101
+ - zap
102
+
103
+ # AI and intelligent analysis configuration
104
+ intelligence:
105
+ # Optional. Set false to skip all AI analysis silently.
106
+ # Default: true
107
+ enabled: true
108
+
109
+ # Optional. Which intelligence analysis types to run.
110
+ # Valid values: ai-summary | risk-prioritization | recommendations |
111
+ # scanner-interpretation
112
+ # Default: all types
113
+ types:
114
+ - ai-summary
115
+ - risk-prioritization
116
+ - recommendations
117
+ - scanner-interpretation
118
+
119
+ # ── MCP integration ───────────────────────────────────────────────────────────
120
+
121
+ mcp:
122
+ # Optional. Set true to enable MCP server integrations.
123
+ # Default: false (disabled when config.yaml is absent to avoid unexpected network calls)
124
+ enabled: false
125
+
126
+ # Optional. Default transport for all servers that do not specify one.
127
+ # Valid values: stdio | http
128
+ # Default: stdio
129
+ defaultTransport: stdio
130
+
131
+ # Optional. Default request timeout in milliseconds.
132
+ # Default: 30000
133
+ timeoutMs: 30000
134
+
135
+ # Optional. Named MCP server definitions.
136
+ servers:
137
+ # Each key is a server ID of your choice.
138
+ # Example: stdio transport (spawns a local process)
139
+ # coverageSummary:
140
+ # enabled: true # Required per-server
141
+ # transport: stdio # Optional; inherits defaultTransport
142
+ # command: node # Required when transport is 'stdio'
143
+ # args: # Optional arguments for the command
144
+ # - ./mcp-servers/coverage-summary.js
145
+
146
+ # Example: HTTP transport (connects to a running HTTP MCP server)
147
+ # securityScan:
148
+ # enabled: true
149
+ # transport: http
150
+ # url: http://localhost:3100/mcp # Required when transport is 'http'
151
+ # headers: # Optional auth headers
152
+ # Authorization: Bearer my-token
153
+
154
+ # ── Thresholds ────────────────────────────────────────────────────────────────
155
+
156
+ thresholds:
157
+ # Optional. Default threshold applied when no type-specific value is set.
158
+ # Valid range: 0 – 100.
159
+ # Default: 80
160
+ global: 80
161
+
162
+ # Optional per-type thresholds (0–100). Each overrides 'global' for that type.
163
+ endpoint: 80
164
+ parameter: 80
165
+ business: 80
166
+ integration: 80
167
+ error: 80
168
+ security: 80
169
+ performance: 80
170
+ compatibility: 80
171
+
172
+ # ── Quality gate ──────────────────────────────────────────────────────────────
173
+
174
+ qualityGate:
175
+ # Optional. Enables threshold enforcement.
176
+ # Default: true
177
+ enabled: true
178
+
179
+ # Optional. When true, the analyzer exits non-zero if any threshold is missed.
180
+ # Default: false
181
+ failBuildOnThresholdMiss: false
182
+
183
+ # Optional. 'strict' fails on unknown config keys and any threshold miss.
184
+ # 'warn' logs threshold misses without failing the build.
185
+ # Valid values: strict | warn
186
+ # Default: warn
187
+ mode: warn
188
+
189
+ # ── Reports ───────────────────────────────────────────────────────────────────
190
+
191
+ reports:
192
+ # Optional. Directory where all report files are written.
193
+ # Default: reports
194
+ outputDir: reports
195
+
196
+ # Optional. Which report formats to produce.
197
+ # Valid values: json | html | csv | junit | markdown
198
+ # Default: [json]
199
+ formats:
200
+ - json
201
+ - html
202
+ - csv
203
+ - junit
204
+
205
+ # ── Publishing ────────────────────────────────────────────────────────────────
206
+
207
+ publishing:
208
+ # Optional. Set true to enable static site publishing.
209
+ # Default: false
210
+ enabled: false
211
+
212
+ githubPages:
213
+ # Optional. Set true to publish to GitHub Pages via gh-pages branch.
214
+ # Default: false
215
+ enabled: false
216
+
217
+ # ── Dashboard ─────────────────────────────────────────────────────────────────
218
+
219
+ dashboard:
220
+ aiSummary:
221
+ # Optional. When false, AI summary panels are hidden in the dashboard.
222
+ # Default: true
223
+ enabled: true
224
+
225
+ # Optional. When true, AI summary panels start collapsed in the dashboard.
226
+ # Default: true
227
+ collapsedByDefault: true
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../action/src/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,349 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const core = __importStar(require("@actions/core"));
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs"));
39
+ const index_1 = require("../../src/lib/index");
40
+ const config_1 = require("../../src/config");
41
+ const buildSummary_1 = require("../../src/buildSummary");
42
+ const prComment_1 = require("./prComment");
43
+ async function run() {
44
+ var _a, _b, _c, _d, _e, _f, _g, _h;
45
+ try {
46
+ const spec = core.getInput('spec') || 'sample/openapi.yaml';
47
+ const tests = core.getInput('tests') || 'tests/**/*.ts';
48
+ const format = core.getInput('format') || 'json,html';
49
+ const coverageTypesRaw = core.getInput('coverage-types') || 'endpoint';
50
+ const language = core.getInput('language') || 'auto';
51
+ const reportsDirInput = core.getInput('reports-dir') || 'reports';
52
+ const configInput = core.getInput('config') || '';
53
+ const publishPages = core.getInput('publish-pages') === 'true';
54
+ const siteDirInput = core.getInput('site-dir') || 'site';
55
+ const pagesBasePath = core.getInput('pages-base-path') || '/';
56
+ const qualityGateEnabled = core.getInput('quality-gate') !== 'false';
57
+ const qualityGateMode = core.getInput('quality-gate-mode') || 'strict';
58
+ const writeGitHubSummary = core.getInput('write-step-summary') !== 'false';
59
+ const githubToken = core.getInput('github-token') || '';
60
+ const postComment = core.getInput('post-pr-comment') !== 'false';
61
+ // Load config file if specified, merging with CLI inputs
62
+ const fileConfig = configInput
63
+ ? (0, config_1.resolveConfig)(configInput)
64
+ : (0, config_1.resolveConfig)();
65
+ const globalThreshold = parseFloat(core.getInput('threshold-global') || '0');
66
+ const cliThresholds = {};
67
+ if (globalThreshold > 0)
68
+ cliThresholds['global'] = globalThreshold;
69
+ const perCategoryThresholds = {
70
+ endpoint: parseFloat(core.getInput('threshold-endpoint') || '0'),
71
+ parameter: parseFloat(core.getInput('threshold-parameter') || '0'),
72
+ business: parseFloat(core.getInput('threshold-business') || '0'),
73
+ integration: parseFloat(core.getInput('threshold-integration') || '0'),
74
+ error: parseFloat(core.getInput('threshold-error') || '0'),
75
+ security: parseFloat(core.getInput('threshold-security') || '0'),
76
+ };
77
+ // Only include non-zero per-category thresholds
78
+ for (const [key, value] of Object.entries(perCategoryThresholds)) {
79
+ if (value > 0)
80
+ cliThresholds[key] = value;
81
+ }
82
+ const mergedConfig = (0, config_1.mergeConfig)(fileConfig, {
83
+ thresholds: Object.keys(cliThresholds).length > 0 ? cliThresholds : fileConfig.thresholds,
84
+ });
85
+ const workspace = (_a = process.env['GITHUB_WORKSPACE']) !== null && _a !== void 0 ? _a : process.cwd();
86
+ const reportsDir = path.isAbsolute(reportsDirInput)
87
+ ? reportsDirInput
88
+ : path.join(workspace, reportsDirInput);
89
+ const siteDir = path.isAbsolute(siteDirInput)
90
+ ? siteDirInput
91
+ : path.join(workspace, siteDirInput);
92
+ const coverageTypes = coverageTypesRaw
93
+ .split(',')
94
+ .map((t) => t.trim().toLowerCase())
95
+ .filter(Boolean);
96
+ core.info(`Running coverage types: ${coverageTypes.join(', ')}`);
97
+ core.info(`Reports will be written to: ${reportsDir}`);
98
+ if (!fs.existsSync(reportsDir)) {
99
+ fs.mkdirSync(reportsDir, { recursive: true });
100
+ }
101
+ const allResults = [];
102
+ for (const coverageType of coverageTypes) {
103
+ switch (coverageType) {
104
+ case 'endpoint': {
105
+ core.info('Running endpoint coverage analysis...');
106
+ const result = await (0, index_1.analyzeEndpoints)({
107
+ spec,
108
+ tests,
109
+ format,
110
+ language,
111
+ reportsDir,
112
+ });
113
+ allResults.push(result);
114
+ core.setOutput('endpoint-coverage', String(result.coveragePercent));
115
+ core.info(`Endpoint coverage: ${result.coveredItems}/${result.totalItems} (${result.coveragePercent}%)`);
116
+ break;
117
+ }
118
+ case 'parameter': {
119
+ core.info('Running parameter coverage analysis...');
120
+ const result = await (0, index_1.analyzeParameters)({
121
+ spec,
122
+ tests,
123
+ format,
124
+ reportsDir,
125
+ });
126
+ allResults.push(result);
127
+ core.setOutput('parameter-coverage', String(result.coveragePercent));
128
+ core.info(`Parameter coverage: ${result.coveredItems}/${result.totalItems} (${result.coveragePercent}%)`);
129
+ break;
130
+ }
131
+ case 'business': {
132
+ const rules = core.getInput('rules');
133
+ if (!rules) {
134
+ core.warning('Skipping business coverage: "rules" input is required');
135
+ break;
136
+ }
137
+ core.info('Running business rule coverage analysis...');
138
+ const result = await (0, index_1.analyzeBusinessRules)({
139
+ rules,
140
+ tests,
141
+ format,
142
+ reportsDir,
143
+ });
144
+ allResults.push(result);
145
+ core.setOutput('business-coverage', String(result.coveragePercent));
146
+ core.info(`Business coverage: ${result.coveredItems}/${result.totalItems} (${result.coveragePercent}%)`);
147
+ break;
148
+ }
149
+ case 'integration': {
150
+ const flows = core.getInput('flows');
151
+ if (!flows) {
152
+ core.warning('Skipping integration coverage: "flows" input is required');
153
+ break;
154
+ }
155
+ core.info('Running integration flow coverage analysis...');
156
+ const result = await (0, index_1.analyzeIntegrationFlows)({
157
+ flows,
158
+ tests,
159
+ format,
160
+ reportsDir,
161
+ });
162
+ allResults.push(result);
163
+ core.setOutput('integration-coverage', String(result.coveragePercent));
164
+ core.info(`Integration coverage: ${result.coveredItems}/${result.totalItems} (${result.coveragePercent}%)`);
165
+ break;
166
+ }
167
+ case 'error': {
168
+ core.info('Running error handling coverage analysis...');
169
+ const result = await (0, index_1.analyzeErrorHandling)({
170
+ spec,
171
+ tests,
172
+ format,
173
+ reportsDir,
174
+ });
175
+ allResults.push(result);
176
+ core.setOutput('error-coverage', String(result.coveragePercent));
177
+ core.info(`Error coverage: ${result.coveredItems}/${result.totalItems} (${result.coveragePercent}%)`);
178
+ break;
179
+ }
180
+ case 'security': {
181
+ core.info('Running security coverage analysis...');
182
+ const result = await (0, index_1.analyzeSecurityControls)({
183
+ spec,
184
+ tests,
185
+ format,
186
+ reportsDir,
187
+ });
188
+ allResults.push(result);
189
+ core.setOutput('security-coverage', String(result.coveragePercent));
190
+ core.info(`Security coverage: ${result.coveredItems}/${result.totalItems} (${result.coveragePercent}%)`);
191
+ break;
192
+ }
193
+ case 'security-scan': {
194
+ core.info('Running integrated security scan (Semgrep / Trivy / ZAP)...');
195
+ const semgrepReport = core.getInput('semgrep-report') || undefined;
196
+ const trivyReport = core.getInput('trivy-report') || undefined;
197
+ const zapReport = core.getInput('zap-report') || undefined;
198
+ const failOnCritical = core.getInput('fail-on-critical') === 'true';
199
+ const failOnHigh = core.getInput('fail-on-high') === 'true';
200
+ const maxSecretsRaw = core.getInput('max-secrets');
201
+ const maxMediumRaw = core.getInput('max-medium');
202
+ const maxMisconfigHighRaw = core.getInput('max-misconfig-high');
203
+ const maxCriticalVulnsRaw = core.getInput('max-critical-vulns');
204
+ const maxHighVulnsRaw = core.getInput('max-high-vulns');
205
+ const gateConfig = {};
206
+ if (failOnCritical)
207
+ gateConfig['failOnCritical'] = true;
208
+ if (failOnHigh)
209
+ gateConfig['failOnHigh'] = true;
210
+ if (maxSecretsRaw !== '')
211
+ gateConfig['maxSecrets'] = parseInt(maxSecretsRaw, 10);
212
+ if (maxMediumRaw !== '')
213
+ gateConfig['maxMedium'] = parseInt(maxMediumRaw, 10);
214
+ if (maxMisconfigHighRaw !== '')
215
+ gateConfig['maxMisconfigHigh'] = parseInt(maxMisconfigHighRaw, 10);
216
+ if (maxCriticalVulnsRaw !== '')
217
+ gateConfig['maxCriticalVulns'] = parseInt(maxCriticalVulnsRaw, 10);
218
+ if (maxHighVulnsRaw !== '')
219
+ gateConfig['maxHighVulns'] = parseInt(maxHighVulnsRaw, 10);
220
+ const scanners = {};
221
+ if (semgrepReport) {
222
+ scanners['semgrep'] = { enabled: true, mode: 'import', reportPath: semgrepReport };
223
+ }
224
+ if (trivyReport) {
225
+ scanners['trivy'] = { enabled: true, mode: 'import', reportPath: trivyReport };
226
+ }
227
+ if (zapReport) {
228
+ scanners['zap'] = { enabled: true, mode: 'import', reportPath: zapReport };
229
+ }
230
+ const summary = await (0, index_1.runSecurityAnalysis)({
231
+ config: {
232
+ enabled: true,
233
+ workspace,
234
+ scanners: scanners,
235
+ gate: Object.keys(gateConfig).length > 0
236
+ ? gateConfig
237
+ : undefined,
238
+ },
239
+ reportsDir,
240
+ });
241
+ core.setOutput('security-scan-findings', String(summary.totalFindings));
242
+ core.setOutput('security-gate-passed', String((_c = (_b = summary.gateResult) === null || _b === void 0 ? void 0 : _b.passed) !== null && _c !== void 0 ? _c : true));
243
+ core.info(`Security scan complete: ${summary.totalFindings} findings`);
244
+ core.info(` CRITICAL: ${summary.bySeverity.CRITICAL}`);
245
+ core.info(` HIGH: ${summary.bySeverity.HIGH}`);
246
+ core.info(` MEDIUM: ${summary.bySeverity.MEDIUM}`);
247
+ core.info(` LOW: ${summary.bySeverity.LOW}`);
248
+ if (summary.gateResult && !summary.gateResult.passed) {
249
+ const msg = summary.gateResult.reasons.join('\n');
250
+ core.setFailed(`Security gate failed:\n${msg}`);
251
+ return; // exit early – gate already failed the action
252
+ }
253
+ break;
254
+ }
255
+ default:
256
+ core.warning(`Unknown coverage type: ${coverageType}`);
257
+ }
258
+ }
259
+ core.setOutput('reports-dir', reportsDir);
260
+ // Build the effective config for quality gate + publishing
261
+ const effectiveConfig = {
262
+ ...mergedConfig,
263
+ publishing: {
264
+ enabled: publishPages,
265
+ outputDir: siteDir,
266
+ buildId: 'run-number',
267
+ githubPages: {
268
+ enabled: publishPages,
269
+ basePath: pagesBasePath,
270
+ },
271
+ ...((_d = mergedConfig.publishing) !== null && _d !== void 0 ? _d : {}),
272
+ },
273
+ qualityGate: {
274
+ enabled: qualityGateEnabled,
275
+ failBuildOnThresholdMiss: qualityGateEnabled,
276
+ mode: (qualityGateMode === 'warn' ? 'warn' : 'strict'),
277
+ ...((_e = mergedConfig.qualityGate) !== null && _e !== void 0 ? _e : {}),
278
+ },
279
+ };
280
+ const repoOwner = (_f = process.env['GITHUB_REPOSITORY_OWNER']) !== null && _f !== void 0 ? _f : '';
281
+ const repoName = (_h = (_g = process.env['GITHUB_REPOSITORY']) === null || _g === void 0 ? void 0 : _g.split('/')[1]) !== null && _h !== void 0 ? _h : '';
282
+ const pagesUrl = publishPages && repoOwner && repoName
283
+ ? `https://${repoOwner}.github.io/${repoName}${pagesBasePath}`
284
+ : undefined;
285
+ // Run quality gate + publishing (always generates reports, even on failure)
286
+ const { reports, qualityGate, exitCode } = await (0, index_1.runAnalysisAndEnforceQualityGate)({
287
+ results: allResults,
288
+ config: effectiveConfig,
289
+ branch: process.env['GITHUB_REF_NAME'],
290
+ reportsDir,
291
+ writeGitHubSummary,
292
+ pagesUrl,
293
+ });
294
+ if (reports) {
295
+ core.setOutput('site-dir', reports.siteDir);
296
+ core.info(`Static site written to: ${reports.siteDir}`);
297
+ }
298
+ core.setOutput('quality-gate-passed', String(qualityGate.passed));
299
+ // New top-level outputs for consumers
300
+ const overallCoverage = allResults.length > 0
301
+ ? (allResults.reduce((sum, r) => sum + r.coveragePercent, 0) / allResults.length).toFixed(2)
302
+ : '0.00';
303
+ const failedGates = qualityGate.failures.map((f) => f.category).join(',');
304
+ const summaryPath = path.join(reportsDir, 'build-summary.md');
305
+ core.setOutput('overallStatus', qualityGate.passed ? 'passed' : 'failed');
306
+ core.setOutput('overallCoverage', overallCoverage);
307
+ core.setOutput('failedGates', failedGates);
308
+ core.setOutput('summaryPath', summaryPath);
309
+ if (exitCode !== 0) {
310
+ const failureMessages = qualityGate.failures.map((f) => `${f.category}: expected ≥ ${f.expected}%, actual ${f.actual}%, gap ${f.gap}%`);
311
+ core.setFailed(`Coverage thresholds not met:\n${failureMessages.join('\n')}`);
312
+ }
313
+ else {
314
+ core.info('All coverage thresholds passed.');
315
+ }
316
+ // Post a PR comment with the coverage summary when running on a PR
317
+ if (postComment && (0, prComment_1.isPrContext)()) {
318
+ if (!githubToken) {
319
+ core.warning('post-pr-comment is enabled but github-token is empty. ' +
320
+ 'Add `github-token: ${{ secrets.GITHUB_TOKEN }}` to your workflow step to enable PR comments.');
321
+ }
322
+ else {
323
+ // Re-use the pr-summary.md that runAnalysisAndEnforceQualityGate already wrote
324
+ const prSummaryPath = path.join(reportsDir, 'pr-summary.md');
325
+ let commentBody;
326
+ if (fs.existsSync(prSummaryPath)) {
327
+ commentBody = fs.readFileSync(prSummaryPath, 'utf-8');
328
+ }
329
+ else {
330
+ // Fallback: generate an inline comment from the results we have
331
+ const { buildBuildMetadata } = await Promise.resolve().then(() => __importStar(require('../../src/publishing')));
332
+ const meta = buildBuildMetadata(allResults, qualityGate, {}, 'action', {});
333
+ commentBody = (0, buildSummary_1.generatePrComment)(allResults, qualityGate, meta, pagesUrl);
334
+ }
335
+ await (0, prComment_1.postPrComment)(githubToken, commentBody);
336
+ }
337
+ }
338
+ core.info(`Reports written to: ${reportsDir}`);
339
+ }
340
+ catch (error) {
341
+ if (error instanceof Error) {
342
+ core.setFailed(error.message);
343
+ }
344
+ else {
345
+ core.setFailed(String(error));
346
+ }
347
+ }
348
+ }
349
+ void run();
@@ -0,0 +1,34 @@
1
+ /**
2
+ * PR comment helper for the API Test Coverage Analyzer action.
3
+ *
4
+ * Detects when the action is running in a pull-request context and either
5
+ * creates or updates a single "coverage report" comment, keeping the PR
6
+ * timeline clean. The comment is identified by a hidden sentinel marker so
7
+ * subsequent runs update the same comment instead of appending new ones.
8
+ *
9
+ * Public API:
10
+ * postPrComment(token, body)
11
+ * isPrContext()
12
+ */
13
+ /**
14
+ * Return true when the current workflow run is triggered by a pull-request
15
+ * event and all required env vars are present.
16
+ */
17
+ export declare function isPrContext(): boolean;
18
+ /**
19
+ * Read the PR number from the GitHub event payload JSON file.
20
+ * Returns undefined when the file cannot be read or the number is absent.
21
+ */
22
+ export declare function readPrNumber(): number | undefined;
23
+ /**
24
+ * Post or update a single PR comment containing `body`.
25
+ *
26
+ * If a previous coverage comment (identified by COMMENT_MARKER) already
27
+ * exists it is updated in place; otherwise a new comment is created.
28
+ * Requires a token with `pull-requests: write` permission.
29
+ *
30
+ * @param token GitHub token (e.g. `${{ secrets.GITHUB_TOKEN }}`).
31
+ * @param body Markdown body to post.
32
+ */
33
+ export declare function postPrComment(token: string, body: string): Promise<void>;
34
+ //# sourceMappingURL=prComment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prComment.d.ts","sourceRoot":"","sources":["../../../action/src/prComment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH;;;GAGG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAQrC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAUjD;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD9E"}