vaspera 2.7.0 → 2.9.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 (321) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +111 -7
  3. package/dist/__tests__/agents/adversary/tactics/api.test.d.ts +5 -0
  4. package/dist/__tests__/agents/adversary/tactics/api.test.d.ts.map +1 -0
  5. package/dist/__tests__/agents/adversary/tactics/api.test.js +369 -0
  6. package/dist/__tests__/agents/adversary/tactics/api.test.js.map +1 -0
  7. package/dist/__tests__/agents/adversary/tactics/llm.test.d.ts +5 -0
  8. package/dist/__tests__/agents/adversary/tactics/llm.test.d.ts.map +1 -0
  9. package/dist/__tests__/agents/adversary/tactics/llm.test.js +409 -0
  10. package/dist/__tests__/agents/adversary/tactics/llm.test.js.map +1 -0
  11. package/dist/__tests__/agents/adversary/tactics/registry.test.d.ts +7 -0
  12. package/dist/__tests__/agents/adversary/tactics/registry.test.d.ts.map +1 -0
  13. package/dist/__tests__/agents/adversary/tactics/registry.test.js +74 -0
  14. package/dist/__tests__/agents/adversary/tactics/registry.test.js.map +1 -0
  15. package/dist/__tests__/agents/adversary/tactics/web-app.test.d.ts +7 -0
  16. package/dist/__tests__/agents/adversary/tactics/web-app.test.d.ts.map +1 -0
  17. package/dist/__tests__/agents/adversary/tactics/web-app.test.js +374 -0
  18. package/dist/__tests__/agents/adversary/tactics/web-app.test.js.map +1 -0
  19. package/dist/__tests__/compliance-bundle.test.d.ts +9 -0
  20. package/dist/__tests__/compliance-bundle.test.d.ts.map +1 -0
  21. package/dist/__tests__/compliance-bundle.test.js +344 -0
  22. package/dist/__tests__/compliance-bundle.test.js.map +1 -0
  23. package/dist/__tests__/healthcare-compliance.test.d.ts +9 -0
  24. package/dist/__tests__/healthcare-compliance.test.d.ts.map +1 -0
  25. package/dist/__tests__/healthcare-compliance.test.js +233 -0
  26. package/dist/__tests__/healthcare-compliance.test.js.map +1 -0
  27. package/dist/action/diff-mode.d.ts +124 -8
  28. package/dist/action/diff-mode.d.ts.map +1 -1
  29. package/dist/action/diff-mode.js +384 -65
  30. package/dist/action/diff-mode.js.map +1 -1
  31. package/dist/action/diff-mode.test.js +3 -3
  32. package/dist/action/diff-mode.test.js.map +1 -1
  33. package/dist/action/pr-comment.test.js +1 -0
  34. package/dist/action/pr-comment.test.js.map +1 -1
  35. package/dist/action/sarif-upload.test.js +1 -0
  36. package/dist/action/sarif-upload.test.js.map +1 -1
  37. package/dist/agents/adversary/config.d.ts +113 -0
  38. package/dist/agents/adversary/config.d.ts.map +1 -0
  39. package/dist/agents/adversary/config.js +391 -0
  40. package/dist/agents/adversary/config.js.map +1 -0
  41. package/dist/agents/adversary/index.d.ts +41 -0
  42. package/dist/agents/adversary/index.d.ts.map +1 -0
  43. package/dist/agents/adversary/index.js +838 -0
  44. package/dist/agents/adversary/index.js.map +1 -0
  45. package/dist/agents/adversary/reporting/compliance-mapper.d.ts +108 -0
  46. package/dist/agents/adversary/reporting/compliance-mapper.d.ts.map +1 -0
  47. package/dist/agents/adversary/reporting/compliance-mapper.js +391 -0
  48. package/dist/agents/adversary/reporting/compliance-mapper.js.map +1 -0
  49. package/dist/agents/adversary/reporting/index.d.ts +10 -0
  50. package/dist/agents/adversary/reporting/index.d.ts.map +1 -0
  51. package/dist/agents/adversary/reporting/index.js +10 -0
  52. package/dist/agents/adversary/reporting/index.js.map +1 -0
  53. package/dist/agents/adversary/reporting/poc-generator.d.ts +44 -0
  54. package/dist/agents/adversary/reporting/poc-generator.d.ts.map +1 -0
  55. package/dist/agents/adversary/reporting/poc-generator.js +308 -0
  56. package/dist/agents/adversary/reporting/poc-generator.js.map +1 -0
  57. package/dist/agents/adversary/tactics/api.d.ts +13 -0
  58. package/dist/agents/adversary/tactics/api.d.ts.map +1 -0
  59. package/dist/agents/adversary/tactics/api.js +815 -0
  60. package/dist/agents/adversary/tactics/api.js.map +1 -0
  61. package/dist/agents/adversary/tactics/auth.d.ts +13 -0
  62. package/dist/agents/adversary/tactics/auth.d.ts.map +1 -0
  63. package/dist/agents/adversary/tactics/auth.js +676 -0
  64. package/dist/agents/adversary/tactics/auth.js.map +1 -0
  65. package/dist/agents/adversary/tactics/index.d.ts +129 -0
  66. package/dist/agents/adversary/tactics/index.d.ts.map +1 -0
  67. package/dist/agents/adversary/tactics/index.js +199 -0
  68. package/dist/agents/adversary/tactics/index.js.map +1 -0
  69. package/dist/agents/adversary/tactics/infra.d.ts +13 -0
  70. package/dist/agents/adversary/tactics/infra.d.ts.map +1 -0
  71. package/dist/agents/adversary/tactics/infra.js +827 -0
  72. package/dist/agents/adversary/tactics/infra.js.map +1 -0
  73. package/dist/agents/adversary/tactics/injection.d.ts +12 -0
  74. package/dist/agents/adversary/tactics/injection.d.ts.map +1 -0
  75. package/dist/agents/adversary/tactics/injection.js +549 -0
  76. package/dist/agents/adversary/tactics/injection.js.map +1 -0
  77. package/dist/agents/adversary/tactics/llm.d.ts +13 -0
  78. package/dist/agents/adversary/tactics/llm.d.ts.map +1 -0
  79. package/dist/agents/adversary/tactics/llm.js +767 -0
  80. package/dist/agents/adversary/tactics/llm.js.map +1 -0
  81. package/dist/agents/adversary/tactics/web-app.d.ts +13 -0
  82. package/dist/agents/adversary/tactics/web-app.d.ts.map +1 -0
  83. package/dist/agents/adversary/tactics/web-app.js +717 -0
  84. package/dist/agents/adversary/tactics/web-app.js.map +1 -0
  85. package/dist/agents/adversary/types.d.ts +407 -0
  86. package/dist/agents/adversary/types.d.ts.map +1 -0
  87. package/dist/agents/adversary/types.js +12 -0
  88. package/dist/agents/adversary/types.js.map +1 -0
  89. package/dist/agents/index.d.ts +1 -0
  90. package/dist/agents/index.d.ts.map +1 -1
  91. package/dist/agents/index.js +2 -0
  92. package/dist/agents/index.js.map +1 -1
  93. package/dist/agents/zero-day-hunter.d.ts +1 -1
  94. package/dist/agents/zero-day-hunter.d.ts.map +1 -1
  95. package/dist/analysis/data-flow.d.ts +154 -0
  96. package/dist/analysis/data-flow.d.ts.map +1 -0
  97. package/dist/analysis/data-flow.js +393 -0
  98. package/dist/analysis/data-flow.js.map +1 -0
  99. package/dist/analysis/index.d.ts +9 -0
  100. package/dist/analysis/index.d.ts.map +1 -0
  101. package/dist/analysis/index.js +9 -0
  102. package/dist/analysis/index.js.map +1 -0
  103. package/dist/badge-service/index.d.ts +144 -0
  104. package/dist/badge-service/index.d.ts.map +1 -0
  105. package/dist/badge-service/index.js +206 -0
  106. package/dist/badge-service/index.js.map +1 -0
  107. package/dist/certification/consensus.test.js +2 -0
  108. package/dist/certification/consensus.test.js.map +1 -1
  109. package/dist/certification/store.d.ts.map +1 -1
  110. package/dist/certification/store.js +4 -0
  111. package/dist/certification/store.js.map +1 -1
  112. package/dist/certification/types.d.ts +3 -3
  113. package/dist/certification/types.d.ts.map +1 -1
  114. package/dist/certification/types.js +2 -0
  115. package/dist/certification/types.js.map +1 -1
  116. package/dist/commands/certification/certify.d.ts.map +1 -1
  117. package/dist/commands/certification/certify.js +18 -4
  118. package/dist/commands/certification/certify.js.map +1 -1
  119. package/dist/compliance/attestation.d.ts +39 -0
  120. package/dist/compliance/attestation.d.ts.map +1 -0
  121. package/dist/compliance/attestation.js +364 -0
  122. package/dist/compliance/attestation.js.map +1 -0
  123. package/dist/compliance/cfr42-part2.d.ts +42 -0
  124. package/dist/compliance/cfr42-part2.d.ts.map +1 -0
  125. package/dist/compliance/cfr42-part2.js +408 -0
  126. package/dist/compliance/cfr42-part2.js.map +1 -0
  127. package/dist/compliance/compliance-bundle.d.ts +100 -0
  128. package/dist/compliance/compliance-bundle.d.ts.map +1 -0
  129. package/dist/compliance/compliance-bundle.js +210 -0
  130. package/dist/compliance/compliance-bundle.js.map +1 -0
  131. package/dist/compliance/healthcare-bundle.d.ts +68 -0
  132. package/dist/compliance/healthcare-bundle.d.ts.map +1 -0
  133. package/dist/compliance/healthcare-bundle.js +104 -0
  134. package/dist/compliance/healthcare-bundle.js.map +1 -0
  135. package/dist/compliance/hipaa.d.ts.map +1 -1
  136. package/dist/compliance/hipaa.js +14 -11
  137. package/dist/compliance/hipaa.js.map +1 -1
  138. package/dist/compliance/index.d.ts +10 -2
  139. package/dist/compliance/index.d.ts.map +1 -1
  140. package/dist/compliance/index.js +9 -3
  141. package/dist/compliance/index.js.map +1 -1
  142. package/dist/compliance/mapper.d.ts.map +1 -1
  143. package/dist/compliance/mapper.js +3 -17
  144. package/dist/compliance/mapper.js.map +1 -1
  145. package/dist/compliance/nist-800-53.d.ts +22 -6
  146. package/dist/compliance/nist-800-53.d.ts.map +1 -1
  147. package/dist/compliance/nist-800-53.js +264 -272
  148. package/dist/compliance/nist-800-53.js.map +1 -1
  149. package/dist/compliance/report.d.ts +31 -2
  150. package/dist/compliance/report.d.ts.map +1 -1
  151. package/dist/compliance/report.js +255 -4
  152. package/dist/compliance/report.js.map +1 -1
  153. package/dist/compliance/types.d.ts +1 -1
  154. package/dist/compliance/types.d.ts.map +1 -1
  155. package/dist/config/flags.d.ts +12 -12
  156. package/dist/cost/index.d.ts +1 -1
  157. package/dist/cost/index.d.ts.map +1 -1
  158. package/dist/cost/index.js +1 -1
  159. package/dist/cost/index.js.map +1 -1
  160. package/dist/cost/tracker.d.ts +64 -0
  161. package/dist/cost/tracker.d.ts.map +1 -1
  162. package/dist/cost/tracker.js +165 -0
  163. package/dist/cost/tracker.js.map +1 -1
  164. package/dist/eval/fixtures/healthcare/audit-gaps.d.ts +28 -0
  165. package/dist/eval/fixtures/healthcare/audit-gaps.d.ts.map +1 -0
  166. package/dist/eval/fixtures/healthcare/audit-gaps.js +90 -0
  167. package/dist/eval/fixtures/healthcare/audit-gaps.js.map +1 -0
  168. package/dist/eval/fixtures/healthcare/consent-bypass.d.ts +31 -0
  169. package/dist/eval/fixtures/healthcare/consent-bypass.d.ts.map +1 -0
  170. package/dist/eval/fixtures/healthcare/consent-bypass.js +61 -0
  171. package/dist/eval/fixtures/healthcare/consent-bypass.js.map +1 -0
  172. package/dist/eval/fixtures/healthcare/phi-in-logs.d.ts +24 -0
  173. package/dist/eval/fixtures/healthcare/phi-in-logs.d.ts.map +1 -0
  174. package/dist/eval/fixtures/healthcare/phi-in-logs.js +41 -0
  175. package/dist/eval/fixtures/healthcare/phi-in-logs.js.map +1 -0
  176. package/dist/evidence/collector.d.ts +21 -0
  177. package/dist/evidence/collector.d.ts.map +1 -0
  178. package/dist/evidence/collector.js +340 -0
  179. package/dist/evidence/collector.js.map +1 -0
  180. package/dist/evidence/index.d.ts +11 -0
  181. package/dist/evidence/index.d.ts.map +1 -0
  182. package/dist/evidence/index.js +12 -0
  183. package/dist/evidence/index.js.map +1 -0
  184. package/dist/evidence/store.d.ts +39 -0
  185. package/dist/evidence/store.d.ts.map +1 -0
  186. package/dist/evidence/store.js +173 -0
  187. package/dist/evidence/store.js.map +1 -0
  188. package/dist/evidence/types.d.ts +175 -0
  189. package/dist/evidence/types.d.ts.map +1 -0
  190. package/dist/evidence/types.js +9 -0
  191. package/dist/evidence/types.js.map +1 -0
  192. package/dist/exporters/checkmarx.d.ts +18 -0
  193. package/dist/exporters/checkmarx.d.ts.map +1 -0
  194. package/dist/exporters/checkmarx.js +203 -0
  195. package/dist/exporters/checkmarx.js.map +1 -0
  196. package/dist/exporters/index.d.ts +22 -0
  197. package/dist/exporters/index.d.ts.map +1 -0
  198. package/dist/exporters/index.js +41 -0
  199. package/dist/exporters/index.js.map +1 -0
  200. package/dist/exporters/snyk.d.ts +18 -0
  201. package/dist/exporters/snyk.d.ts.map +1 -0
  202. package/dist/exporters/snyk.js +119 -0
  203. package/dist/exporters/snyk.js.map +1 -0
  204. package/dist/exporters/sonarqube.d.ts +18 -0
  205. package/dist/exporters/sonarqube.d.ts.map +1 -0
  206. package/dist/exporters/sonarqube.js +125 -0
  207. package/dist/exporters/sonarqube.js.map +1 -0
  208. package/dist/exporters/types.d.ts +190 -0
  209. package/dist/exporters/types.d.ts.map +1 -0
  210. package/dist/exporters/types.js +9 -0
  211. package/dist/exporters/types.js.map +1 -0
  212. package/dist/frontier/index.d.ts +12 -0
  213. package/dist/frontier/index.d.ts.map +1 -0
  214. package/dist/frontier/index.js +12 -0
  215. package/dist/frontier/index.js.map +1 -0
  216. package/dist/frontier/orchestrator.d.ts +73 -0
  217. package/dist/frontier/orchestrator.d.ts.map +1 -0
  218. package/dist/frontier/orchestrator.js +312 -0
  219. package/dist/frontier/orchestrator.js.map +1 -0
  220. package/dist/frontier/providers/stub.d.ts +32 -0
  221. package/dist/frontier/providers/stub.d.ts.map +1 -0
  222. package/dist/frontier/providers/stub.js +66 -0
  223. package/dist/frontier/providers/stub.js.map +1 -0
  224. package/dist/frontier/types.d.ts +318 -0
  225. package/dist/frontier/types.d.ts.map +1 -0
  226. package/dist/frontier/types.js +27 -0
  227. package/dist/frontier/types.js.map +1 -0
  228. package/dist/history/index.d.ts +13 -0
  229. package/dist/history/index.d.ts.map +1 -0
  230. package/dist/history/index.js +15 -0
  231. package/dist/history/index.js.map +1 -0
  232. package/dist/history/store.d.ts +74 -0
  233. package/dist/history/store.d.ts.map +1 -0
  234. package/dist/history/store.js +399 -0
  235. package/dist/history/store.js.map +1 -0
  236. package/dist/history/types.d.ts +282 -0
  237. package/dist/history/types.d.ts.map +1 -0
  238. package/dist/history/types.js +41 -0
  239. package/dist/history/types.js.map +1 -0
  240. package/dist/history/verify.d.ts +44 -0
  241. package/dist/history/verify.d.ts.map +1 -0
  242. package/dist/history/verify.js +230 -0
  243. package/dist/history/verify.js.map +1 -0
  244. package/dist/index.d.ts.map +1 -1
  245. package/dist/index.js +431 -18
  246. package/dist/index.js.map +1 -1
  247. package/dist/multimodel/index.d.ts +1 -0
  248. package/dist/multimodel/index.d.ts.map +1 -1
  249. package/dist/multimodel/index.js +2 -0
  250. package/dist/multimodel/index.js.map +1 -1
  251. package/dist/multimodel/leaderboard.d.ts +116 -0
  252. package/dist/multimodel/leaderboard.d.ts.map +1 -0
  253. package/dist/multimodel/leaderboard.js +262 -0
  254. package/dist/multimodel/leaderboard.js.map +1 -0
  255. package/dist/observability/otel.d.ts.map +1 -1
  256. package/dist/observability/otel.js +1 -3
  257. package/dist/observability/otel.js.map +1 -1
  258. package/dist/plugins/loader.js +1 -1
  259. package/dist/plugins/loader.js.map +1 -1
  260. package/dist/sbom/provenance.test.js +2 -2
  261. package/dist/sbom/provenance.test.js.map +1 -1
  262. package/dist/scanners/agent/agent-chain-analysis.d.ts +152 -0
  263. package/dist/scanners/agent/agent-chain-analysis.d.ts.map +1 -0
  264. package/dist/scanners/agent/agent-chain-analysis.js +438 -0
  265. package/dist/scanners/agent/agent-chain-analysis.js.map +1 -0
  266. package/dist/scanners/agent/manifest-audit.d.ts.map +1 -1
  267. package/dist/scanners/agent/manifest-audit.js +30 -18
  268. package/dist/scanners/agent/manifest-audit.js.map +1 -1
  269. package/dist/scanners/agent/payloads/index.d.ts +2 -1
  270. package/dist/scanners/agent/payloads/index.d.ts.map +1 -1
  271. package/dist/scanners/agent/payloads/index.js +25 -6
  272. package/dist/scanners/agent/payloads/index.js.map +1 -1
  273. package/dist/scanners/agent/prompt-injection-fuzzer.d.ts.map +1 -1
  274. package/dist/scanners/agent/prompt-injection-fuzzer.js +14 -0
  275. package/dist/scanners/agent/prompt-injection-fuzzer.js.map +1 -1
  276. package/dist/scanners/agent/types.d.ts +5 -5
  277. package/dist/scanners/agent/types.d.ts.map +1 -1
  278. package/dist/scanners/agent/types.js.map +1 -1
  279. package/dist/scanners/cache.d.ts +156 -0
  280. package/dist/scanners/cache.d.ts.map +1 -0
  281. package/dist/scanners/cache.js +462 -0
  282. package/dist/scanners/cache.js.map +1 -0
  283. package/dist/scanners/dependencies.d.ts.map +1 -1
  284. package/dist/scanners/dependencies.js +5 -6
  285. package/dist/scanners/dependencies.js.map +1 -1
  286. package/dist/scanners/gosec.d.ts.map +1 -1
  287. package/dist/scanners/gosec.js +47 -9
  288. package/dist/scanners/gosec.js.map +1 -1
  289. package/dist/scanners/healthcare.d.ts +29 -0
  290. package/dist/scanners/healthcare.d.ts.map +1 -0
  291. package/dist/scanners/healthcare.js +526 -0
  292. package/dist/scanners/healthcare.js.map +1 -0
  293. package/dist/scanners/index.d.ts +1 -0
  294. package/dist/scanners/index.d.ts.map +1 -1
  295. package/dist/scanners/index.js +33 -0
  296. package/dist/scanners/index.js.map +1 -1
  297. package/dist/scanners/index.test.js +6 -6
  298. package/dist/scanners/index.test.js.map +1 -1
  299. package/dist/scanners/secrets.js +4 -4
  300. package/dist/scanners/secrets.js.map +1 -1
  301. package/dist/scanners/semgrep.js +5 -5
  302. package/dist/scanners/semgrep.js.map +1 -1
  303. package/dist/scanners/types.d.ts +1 -1
  304. package/dist/scanners/types.d.ts.map +1 -1
  305. package/dist/scanners/types.js +1 -0
  306. package/dist/scanners/types.js.map +1 -1
  307. package/dist/scanners/typescript.test.js +1 -1
  308. package/dist/scanners/typescript.test.js.map +1 -1
  309. package/dist/telemetry/index.d.ts +10 -0
  310. package/dist/telemetry/index.d.ts.map +1 -0
  311. package/dist/telemetry/index.js +10 -0
  312. package/dist/telemetry/index.js.map +1 -0
  313. package/dist/telemetry/registry.d.ts +178 -0
  314. package/dist/telemetry/registry.d.ts.map +1 -0
  315. package/dist/telemetry/registry.js +297 -0
  316. package/dist/telemetry/registry.js.map +1 -0
  317. package/dist/telemetry/usage.d.ts +197 -0
  318. package/dist/telemetry/usage.d.ts.map +1 -0
  319. package/dist/telemetry/usage.js +244 -0
  320. package/dist/telemetry/usage.js.map +1 -0
  321. package/package.json +11 -2
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Scan Registry Module
3
+ *
4
+ * Maintains a persistent registry of all scans for analytics,
5
+ * case study identification, and compliance auditing.
6
+ *
7
+ * @module telemetry/registry
8
+ */
9
+ import type { Severity, CertificationLevel } from "../certification/types.js";
10
+ /**
11
+ * A record of a completed scan
12
+ */
13
+ export interface ScanRecord {
14
+ /** Unique scan ID */
15
+ id: string;
16
+ /** Certification ID if certified */
17
+ certificationId?: string;
18
+ /** Project path (can be redacted) */
19
+ projectPath: string;
20
+ /** SHA256 hash of project path for matching */
21
+ projectHash: string;
22
+ /** Repository URL (if opted in) */
23
+ repoUrl?: string;
24
+ /** Organization name (if opted in) */
25
+ orgName?: string;
26
+ /** User email (if opted in) */
27
+ userEmail?: string;
28
+ /** When the scan was performed */
29
+ scanDate: string;
30
+ /** Certification level achieved */
31
+ level?: CertificationLevel;
32
+ /** Overall score (0-100) */
33
+ score?: number;
34
+ /** Scan duration in milliseconds */
35
+ duration: number;
36
+ /** Findings by severity */
37
+ findingsSummary: Record<Severity, number>;
38
+ /** Total findings */
39
+ totalFindings: number;
40
+ /** Scanners that were run */
41
+ scannersRun: string[];
42
+ /** Frameworks assessed */
43
+ frameworksAssessed: string[];
44
+ /** Whether the scan succeeded */
45
+ success: boolean;
46
+ /** Error message if failed */
47
+ errorMessage?: string;
48
+ /** Whether user consented to case study */
49
+ caseStudyConsent?: boolean;
50
+ /** Tags for categorization */
51
+ tags?: string[];
52
+ }
53
+ /**
54
+ * Summary of findings for analytics
55
+ */
56
+ export interface FindingSummary {
57
+ /** Rule/check ID */
58
+ ruleId: string;
59
+ /** Scanner that found it */
60
+ scanner: string;
61
+ /** Category */
62
+ category: string;
63
+ /** Severity */
64
+ severity: Severity;
65
+ /** Number of occurrences across all scans */
66
+ occurrences: number;
67
+ /** Number of unique projects affected */
68
+ projectsAffected: number;
69
+ }
70
+ /**
71
+ * Analytics summary
72
+ */
73
+ export interface RegistryAnalytics {
74
+ /** Total scans recorded */
75
+ totalScans: number;
76
+ /** Successful scans */
77
+ successfulScans: number;
78
+ /** Failed scans */
79
+ failedScans: number;
80
+ /** Scans by certification level */
81
+ byLevel: Record<CertificationLevel, number>;
82
+ /** Scans by framework */
83
+ byFramework: Record<string, number>;
84
+ /** Scans by scanner */
85
+ byScanner: Record<string, number>;
86
+ /** Scans by month (YYYY-MM format) */
87
+ byMonth: Record<string, number>;
88
+ /** Average score */
89
+ averageScore: number;
90
+ /** Average scan duration in ms */
91
+ averageDuration: number;
92
+ /** Top findings */
93
+ topFindings: FindingSummary[];
94
+ /** Case study candidates count */
95
+ caseStudyCandidates: number;
96
+ }
97
+ /**
98
+ * Scan Registry for persistent tracking of all scans
99
+ */
100
+ export declare class ScanRegistry {
101
+ private records;
102
+ private storagePath;
103
+ private loaded;
104
+ constructor(storagePath?: string);
105
+ /**
106
+ * Load registry from storage
107
+ */
108
+ load(): Promise<void>;
109
+ /**
110
+ * Save registry to storage
111
+ */
112
+ save(): Promise<void>;
113
+ /**
114
+ * Generate a unique scan ID
115
+ */
116
+ private generateScanId;
117
+ /**
118
+ * Hash a project path for matching
119
+ */
120
+ private hashProjectPath;
121
+ /**
122
+ * Record a new scan
123
+ */
124
+ recordScan(record: Omit<ScanRecord, "id" | "projectHash">): Promise<ScanRecord>;
125
+ /**
126
+ * Get a scan by ID
127
+ */
128
+ getScan(scanId: string): Promise<ScanRecord | undefined>;
129
+ /**
130
+ * Get scans for a project (by path or hash)
131
+ */
132
+ getScansForProject(projectPathOrHash: string): Promise<ScanRecord[]>;
133
+ /**
134
+ * Get scans for an organization
135
+ */
136
+ getScansForOrg(orgName: string): Promise<ScanRecord[]>;
137
+ /**
138
+ * Get recent scans
139
+ */
140
+ getRecentScans(limit?: number): Promise<ScanRecord[]>;
141
+ /**
142
+ * Get successful scans with high scores (case study candidates)
143
+ */
144
+ getCaseStudyCandidates(minScore?: number): Promise<ScanRecord[]>;
145
+ /**
146
+ * Get all unique organizations
147
+ */
148
+ getOrganizations(): Promise<string[]>;
149
+ /**
150
+ * Get analytics summary
151
+ */
152
+ getAnalytics(): Promise<RegistryAnalytics>;
153
+ /**
154
+ * Export registry to JSON
155
+ */
156
+ exportToJson(): Promise<string>;
157
+ /**
158
+ * Export analytics to JSON
159
+ */
160
+ exportAnalyticsToJson(): Promise<string>;
161
+ /**
162
+ * Get total scan count
163
+ */
164
+ getCount(): Promise<number>;
165
+ /**
166
+ * Clear all records (use with caution)
167
+ */
168
+ clear(): Promise<void>;
169
+ }
170
+ /**
171
+ * Get the singleton registry instance
172
+ */
173
+ export declare function getRegistry(storagePath?: string): ScanRegistry;
174
+ /**
175
+ * Reset the singleton (for testing)
176
+ */
177
+ export declare function resetRegistry(): void;
178
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/telemetry/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,297 @@
1
+ /**
2
+ * Scan Registry Module
3
+ *
4
+ * Maintains a persistent registry of all scans for analytics,
5
+ * case study identification, and compliance auditing.
6
+ *
7
+ * @module telemetry/registry
8
+ */
9
+ import { readFile, writeFile, mkdir } from "fs/promises";
10
+ import { join, dirname } from "path";
11
+ import { createHash } from "crypto";
12
+ import { logger } from "../logger.js";
13
+ // ============================================================================
14
+ // Scan Registry
15
+ // ============================================================================
16
+ /**
17
+ * Scan Registry for persistent tracking of all scans
18
+ */
19
+ export class ScanRegistry {
20
+ records = [];
21
+ storagePath;
22
+ loaded = false;
23
+ constructor(storagePath) {
24
+ this.storagePath =
25
+ storagePath ||
26
+ join(process.env.HOME || "/tmp", ".vaspera", "scan-registry.json");
27
+ }
28
+ /**
29
+ * Load registry from storage
30
+ */
31
+ async load() {
32
+ if (this.loaded)
33
+ return;
34
+ try {
35
+ const content = await readFile(this.storagePath, "utf-8");
36
+ const data = JSON.parse(content);
37
+ if (data.version !== 1) {
38
+ logger.warn("registry.version_mismatch", {
39
+ expected: 1,
40
+ actual: data.version,
41
+ });
42
+ }
43
+ this.records = data.records || [];
44
+ this.loaded = true;
45
+ logger.debug("registry.loaded", { recordCount: this.records.length });
46
+ }
47
+ catch (error) {
48
+ if (error.code === "ENOENT") {
49
+ this.records = [];
50
+ this.loaded = true;
51
+ logger.debug("registry.created_new");
52
+ }
53
+ else {
54
+ logger.error("registry.load_failed", {
55
+ error: error instanceof Error ? error.message : String(error),
56
+ });
57
+ throw error;
58
+ }
59
+ }
60
+ }
61
+ /**
62
+ * Save registry to storage
63
+ */
64
+ async save() {
65
+ const data = {
66
+ version: 1,
67
+ lastUpdated: new Date().toISOString(),
68
+ records: this.records,
69
+ };
70
+ await mkdir(dirname(this.storagePath), { recursive: true });
71
+ await writeFile(this.storagePath, JSON.stringify(data, null, 2));
72
+ logger.debug("registry.saved", { recordCount: this.records.length });
73
+ }
74
+ /**
75
+ * Generate a unique scan ID
76
+ */
77
+ generateScanId() {
78
+ const timestamp = Date.now().toString(36);
79
+ const random = Math.random().toString(36).slice(2, 8);
80
+ return `scan-${timestamp}-${random}`;
81
+ }
82
+ /**
83
+ * Hash a project path for matching
84
+ */
85
+ hashProjectPath(path) {
86
+ return createHash("sha256").update(path).digest("hex").slice(0, 16);
87
+ }
88
+ /**
89
+ * Record a new scan
90
+ */
91
+ async recordScan(record) {
92
+ await this.load();
93
+ const fullRecord = {
94
+ ...record,
95
+ id: this.generateScanId(),
96
+ projectHash: this.hashProjectPath(record.projectPath),
97
+ };
98
+ this.records.push(fullRecord);
99
+ await this.save();
100
+ logger.info("registry.scan_recorded", {
101
+ scanId: fullRecord.id,
102
+ level: fullRecord.level,
103
+ score: fullRecord.score,
104
+ });
105
+ return fullRecord;
106
+ }
107
+ /**
108
+ * Get a scan by ID
109
+ */
110
+ async getScan(scanId) {
111
+ await this.load();
112
+ return this.records.find((r) => r.id === scanId);
113
+ }
114
+ /**
115
+ * Get scans for a project (by path or hash)
116
+ */
117
+ async getScansForProject(projectPathOrHash) {
118
+ await this.load();
119
+ const hash = projectPathOrHash.length === 16
120
+ ? projectPathOrHash
121
+ : this.hashProjectPath(projectPathOrHash);
122
+ return this.records.filter((r) => r.projectHash === hash);
123
+ }
124
+ /**
125
+ * Get scans for an organization
126
+ */
127
+ async getScansForOrg(orgName) {
128
+ await this.load();
129
+ return this.records.filter((r) => r.orgName === orgName);
130
+ }
131
+ /**
132
+ * Get recent scans
133
+ */
134
+ async getRecentScans(limit = 50) {
135
+ await this.load();
136
+ return [...this.records]
137
+ .sort((a, b) => new Date(b.scanDate).getTime() - new Date(a.scanDate).getTime())
138
+ .slice(0, limit);
139
+ }
140
+ /**
141
+ * Get successful scans with high scores (case study candidates)
142
+ */
143
+ async getCaseStudyCandidates(minScore = 80) {
144
+ await this.load();
145
+ return this.records
146
+ .filter((r) => r.success &&
147
+ r.score !== undefined &&
148
+ r.score >= minScore &&
149
+ (r.caseStudyConsent === true || r.repoUrl !== undefined))
150
+ .sort((a, b) => (b.score || 0) - (a.score || 0));
151
+ }
152
+ /**
153
+ * Get all unique organizations
154
+ */
155
+ async getOrganizations() {
156
+ await this.load();
157
+ const orgs = new Set();
158
+ for (const record of this.records) {
159
+ if (record.orgName) {
160
+ orgs.add(record.orgName);
161
+ }
162
+ }
163
+ return Array.from(orgs).sort();
164
+ }
165
+ /**
166
+ * Get analytics summary
167
+ */
168
+ async getAnalytics() {
169
+ await this.load();
170
+ const byLevel = {
171
+ CERTIFIED: 0,
172
+ APPROVED: 0,
173
+ REVIEW_REQUIRED: 0,
174
+ BLOCKED: 0,
175
+ };
176
+ const byFramework = {};
177
+ const byScanner = {};
178
+ const byMonth = {};
179
+ const findingCounts = new Map();
180
+ let totalScore = 0;
181
+ let scoreCount = 0;
182
+ let totalDuration = 0;
183
+ let successfulScans = 0;
184
+ let failedScans = 0;
185
+ let caseStudyCandidates = 0;
186
+ for (const record of this.records) {
187
+ // Count success/failure
188
+ if (record.success) {
189
+ successfulScans++;
190
+ }
191
+ else {
192
+ failedScans++;
193
+ }
194
+ // Count by level
195
+ if (record.level) {
196
+ byLevel[record.level]++;
197
+ }
198
+ // Count by framework
199
+ for (const framework of record.frameworksAssessed) {
200
+ byFramework[framework] = (byFramework[framework] || 0) + 1;
201
+ }
202
+ // Count by scanner
203
+ for (const scanner of record.scannersRun) {
204
+ byScanner[scanner] = (byScanner[scanner] || 0) + 1;
205
+ }
206
+ // Count by month
207
+ const month = record.scanDate.slice(0, 7); // YYYY-MM
208
+ byMonth[month] = (byMonth[month] || 0) + 1;
209
+ // Accumulate score
210
+ if (record.score !== undefined) {
211
+ totalScore += record.score;
212
+ scoreCount++;
213
+ }
214
+ // Accumulate duration
215
+ totalDuration += record.duration;
216
+ // Count case study candidates
217
+ if (record.success && record.score !== undefined && record.score >= 80) {
218
+ if (record.caseStudyConsent || record.repoUrl) {
219
+ caseStudyCandidates++;
220
+ }
221
+ }
222
+ }
223
+ // Calculate top findings (placeholder - would need finding-level data)
224
+ const topFindings = [];
225
+ return {
226
+ totalScans: this.records.length,
227
+ successfulScans,
228
+ failedScans,
229
+ byLevel,
230
+ byFramework,
231
+ byScanner,
232
+ byMonth,
233
+ averageScore: scoreCount > 0 ? Math.round(totalScore / scoreCount) : 0,
234
+ averageDuration: this.records.length > 0
235
+ ? Math.round(totalDuration / this.records.length)
236
+ : 0,
237
+ topFindings,
238
+ caseStudyCandidates,
239
+ };
240
+ }
241
+ /**
242
+ * Export registry to JSON
243
+ */
244
+ async exportToJson() {
245
+ await this.load();
246
+ return JSON.stringify({
247
+ exportedAt: new Date().toISOString(),
248
+ recordCount: this.records.length,
249
+ records: this.records,
250
+ }, null, 2);
251
+ }
252
+ /**
253
+ * Export analytics to JSON
254
+ */
255
+ async exportAnalyticsToJson() {
256
+ const analytics = await this.getAnalytics();
257
+ return JSON.stringify({
258
+ exportedAt: new Date().toISOString(),
259
+ analytics,
260
+ }, null, 2);
261
+ }
262
+ /**
263
+ * Get total scan count
264
+ */
265
+ async getCount() {
266
+ await this.load();
267
+ return this.records.length;
268
+ }
269
+ /**
270
+ * Clear all records (use with caution)
271
+ */
272
+ async clear() {
273
+ this.records = [];
274
+ await this.save();
275
+ logger.warn("registry.cleared");
276
+ }
277
+ }
278
+ // ============================================================================
279
+ // Singleton Instance
280
+ // ============================================================================
281
+ let _registry = null;
282
+ /**
283
+ * Get the singleton registry instance
284
+ */
285
+ export function getRegistry(storagePath) {
286
+ if (!_registry) {
287
+ _registry = new ScanRegistry(storagePath);
288
+ }
289
+ return _registry;
290
+ }
291
+ /**
292
+ * Reset the singleton (for testing)
293
+ */
294
+ export function resetRegistry() {
295
+ _registry = null;
296
+ }
297
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/telemetry/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Usage Telemetry Module
3
+ *
4
+ * Tracks scan events and usage patterns for analytics and case studies.
5
+ * All telemetry is opt-in and respects user privacy preferences.
6
+ *
7
+ * @module telemetry/usage
8
+ */
9
+ import type { Severity, CertificationLevel } from "../certification/types.js";
10
+ /**
11
+ * Telemetry configuration
12
+ */
13
+ export interface TelemetryConfig {
14
+ /** Whether telemetry is enabled */
15
+ enabled: boolean;
16
+ /** API endpoint for telemetry events */
17
+ endpoint?: string;
18
+ /** Optional API key for authentication */
19
+ apiKey?: string;
20
+ /** Include repository URL (requires explicit opt-in) */
21
+ includeRepoUrl?: boolean;
22
+ /** Include organization name (requires explicit opt-in) */
23
+ includeOrgName?: boolean;
24
+ /** Include user email (requires explicit opt-in) */
25
+ includeUserEmail?: boolean;
26
+ }
27
+ /**
28
+ * Default telemetry configuration
29
+ */
30
+ export declare const DEFAULT_TELEMETRY_CONFIG: TelemetryConfig;
31
+ /**
32
+ * Types of telemetry events
33
+ */
34
+ export type TelemetryEventType = "certification_started" | "certification_completed" | "certification_failed" | "finding_discovered" | "finding_resolved" | "scanner_run" | "badge_generated" | "sbom_generated" | "compliance_report_generated";
35
+ /**
36
+ * Base telemetry event
37
+ */
38
+ export interface BaseTelemetryEvent {
39
+ /** Event type */
40
+ eventType: TelemetryEventType;
41
+ /** ISO timestamp */
42
+ timestamp: string;
43
+ /** SHA256 hash of project path (anonymized) */
44
+ projectHash: string;
45
+ /** Vaspera version */
46
+ vasperaVersion: string;
47
+ /** Platform (darwin, linux, win32) */
48
+ platform: string;
49
+ /** Node.js version */
50
+ nodeVersion: string;
51
+ }
52
+ /**
53
+ * Event when a certification scan starts
54
+ */
55
+ export interface CertificationStartedEvent extends BaseTelemetryEvent {
56
+ eventType: "certification_started";
57
+ /** Scanners being run */
58
+ scanners: string[];
59
+ /** Frameworks being assessed */
60
+ frameworks: string[];
61
+ /** Corpus size setting */
62
+ corpusSize?: string;
63
+ }
64
+ /**
65
+ * Event when a certification scan completes
66
+ */
67
+ export interface CertificationCompletedEvent extends BaseTelemetryEvent {
68
+ eventType: "certification_completed";
69
+ /** Certification ID */
70
+ certificationId: string;
71
+ /** Achieved level */
72
+ level: CertificationLevel;
73
+ /** Overall score (0-100) */
74
+ score: number;
75
+ /** Duration in milliseconds */
76
+ duration: number;
77
+ /** Findings count by severity */
78
+ severityCounts: Record<Severity, number>;
79
+ /** Total findings */
80
+ totalFindings: number;
81
+ /** Frameworks assessed */
82
+ frameworks: string[];
83
+ /** Optional: repository URL if user opted in */
84
+ repoUrl?: string;
85
+ /** Optional: organization name if user opted in */
86
+ orgName?: string;
87
+ /** Optional: user email if user opted in */
88
+ userEmail?: string;
89
+ }
90
+ /**
91
+ * Event when a certification scan fails
92
+ */
93
+ export interface CertificationFailedEvent extends BaseTelemetryEvent {
94
+ eventType: "certification_failed";
95
+ /** Error message (sanitized) */
96
+ errorMessage: string;
97
+ /** Error category */
98
+ errorCategory: "scanner_error" | "config_error" | "timeout" | "unknown";
99
+ /** Duration before failure */
100
+ duration: number;
101
+ }
102
+ /**
103
+ * Event when a finding is discovered
104
+ */
105
+ export interface FindingDiscoveredEvent extends BaseTelemetryEvent {
106
+ eventType: "finding_discovered";
107
+ /** Finding category */
108
+ category: string;
109
+ /** Severity level */
110
+ severity: Severity;
111
+ /** Scanner that found it */
112
+ scanner: string;
113
+ /** Rule/check ID */
114
+ ruleId?: string;
115
+ }
116
+ /**
117
+ * Event when a scanner completes
118
+ */
119
+ export interface ScannerRunEvent extends BaseTelemetryEvent {
120
+ eventType: "scanner_run";
121
+ /** Scanner name */
122
+ scanner: string;
123
+ /** Duration in milliseconds */
124
+ duration: number;
125
+ /** Number of findings */
126
+ findingsCount: number;
127
+ /** Whether it succeeded */
128
+ success: boolean;
129
+ }
130
+ /**
131
+ * Union of all telemetry events
132
+ */
133
+ export type TelemetryEvent = CertificationStartedEvent | CertificationCompletedEvent | CertificationFailedEvent | FindingDiscoveredEvent | ScannerRunEvent;
134
+ /**
135
+ * Initialize telemetry with configuration
136
+ */
137
+ export declare function initTelemetry(config: Partial<TelemetryConfig>): void;
138
+ /**
139
+ * Check if telemetry is enabled
140
+ */
141
+ export declare function isTelemetryEnabled(): boolean;
142
+ /**
143
+ * Hash a value for anonymization
144
+ */
145
+ export declare function hashValue(value: string): string;
146
+ /**
147
+ * Track a telemetry event
148
+ */
149
+ export declare function trackEvent(event: Omit<TelemetryEvent, keyof BaseTelemetryEvent> & {
150
+ eventType: TelemetryEventType;
151
+ projectPath: string;
152
+ }): Promise<void>;
153
+ /**
154
+ * Flush buffered events to the telemetry endpoint
155
+ */
156
+ export declare function flushEvents(): Promise<void>;
157
+ /**
158
+ * Shutdown telemetry (flush remaining events)
159
+ */
160
+ export declare function shutdownTelemetry(): Promise<void>;
161
+ /**
162
+ * Track certification start
163
+ */
164
+ export declare function trackCertificationStarted(projectPath: string, scanners: string[], frameworks: string[], corpusSize?: string): Promise<void>;
165
+ /**
166
+ * Track certification completion
167
+ */
168
+ export declare function trackCertificationCompleted(projectPath: string, certificationId: string, level: CertificationLevel, score: number, duration: number, severityCounts: Record<Severity, number>, totalFindings: number, frameworks: string[], optionalInfo?: {
169
+ repoUrl?: string;
170
+ orgName?: string;
171
+ userEmail?: string;
172
+ }): Promise<void>;
173
+ /**
174
+ * Track certification failure
175
+ */
176
+ export declare function trackCertificationFailed(projectPath: string, errorMessage: string, errorCategory: CertificationFailedEvent["errorCategory"], duration: number): Promise<void>;
177
+ /**
178
+ * Track a finding discovery
179
+ */
180
+ export declare function trackFindingDiscovered(projectPath: string, category: string, severity: Severity, scanner: string, ruleId?: string): Promise<void>;
181
+ /**
182
+ * Track a scanner run
183
+ */
184
+ export declare function trackScannerRun(projectPath: string, scanner: string, duration: number, findingsCount: number, success: boolean): Promise<void>;
185
+ export declare const telemetry: {
186
+ init: typeof initTelemetry;
187
+ isEnabled: typeof isTelemetryEnabled;
188
+ track: typeof trackEvent;
189
+ flush: typeof flushEvents;
190
+ shutdown: typeof shutdownTelemetry;
191
+ trackCertificationStarted: typeof trackCertificationStarted;
192
+ trackCertificationCompleted: typeof trackCertificationCompleted;
193
+ trackCertificationFailed: typeof trackCertificationFailed;
194
+ trackFindingDiscovered: typeof trackFindingDiscovered;
195
+ trackScannerRun: typeof trackScannerRun;
196
+ };
197
+ //# sourceMappingURL=usage.d.ts.map