vaspera 2.11.0 → 2.12.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 (149) hide show
  1. package/dist/__tests__/audit-trail.test.d.ts +7 -0
  2. package/dist/__tests__/audit-trail.test.d.ts.map +1 -0
  3. package/dist/__tests__/audit-trail.test.js +336 -0
  4. package/dist/__tests__/audit-trail.test.js.map +1 -0
  5. package/dist/__tests__/property-test-helpers.d.ts +1 -1
  6. package/dist/action/pr-comment.test.js +1 -0
  7. package/dist/action/pr-comment.test.js.map +1 -1
  8. package/dist/action/sarif-upload.test.js +1 -0
  9. package/dist/action/sarif-upload.test.js.map +1 -1
  10. package/dist/autofix/ast/__tests__/typescript.test.d.ts +5 -0
  11. package/dist/autofix/ast/__tests__/typescript.test.d.ts.map +1 -0
  12. package/dist/autofix/ast/__tests__/typescript.test.js +210 -0
  13. package/dist/autofix/ast/__tests__/typescript.test.js.map +1 -0
  14. package/dist/autofix/ast/index.d.ts +11 -0
  15. package/dist/autofix/ast/index.d.ts.map +1 -0
  16. package/dist/autofix/ast/index.js +11 -0
  17. package/dist/autofix/ast/index.js.map +1 -0
  18. package/dist/autofix/ast/types.d.ts +77 -0
  19. package/dist/autofix/ast/types.d.ts.map +1 -0
  20. package/dist/autofix/ast/types.js +9 -0
  21. package/dist/autofix/ast/types.js.map +1 -0
  22. package/dist/autofix/ast/typescript.d.ts +17 -0
  23. package/dist/autofix/ast/typescript.d.ts.map +1 -0
  24. package/dist/autofix/ast/typescript.js +427 -0
  25. package/dist/autofix/ast/typescript.js.map +1 -0
  26. package/dist/autofix/constitution.schema.d.ts +21 -21
  27. package/dist/autofix/index.d.ts +1 -0
  28. package/dist/autofix/index.d.ts.map +1 -1
  29. package/dist/autofix/index.js +2 -0
  30. package/dist/autofix/index.js.map +1 -1
  31. package/dist/config/flags.d.ts +6 -6
  32. package/dist/history/store.d.ts +55 -1
  33. package/dist/history/store.d.ts.map +1 -1
  34. package/dist/history/store.js +152 -4
  35. package/dist/history/store.js.map +1 -1
  36. package/dist/history/types.d.ts +9 -5
  37. package/dist/history/types.d.ts.map +1 -1
  38. package/dist/history/verify.d.ts.map +1 -1
  39. package/dist/history/verify.js +5 -3
  40. package/dist/history/verify.js.map +1 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +627 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/integrations/siem/datadog.d.ts +44 -0
  45. package/dist/integrations/siem/datadog.d.ts.map +1 -0
  46. package/dist/integrations/siem/datadog.js +211 -0
  47. package/dist/integrations/siem/datadog.js.map +1 -0
  48. package/dist/integrations/siem/format.d.ts +59 -0
  49. package/dist/integrations/siem/format.d.ts.map +1 -0
  50. package/dist/integrations/siem/format.js +360 -0
  51. package/dist/integrations/siem/format.js.map +1 -0
  52. package/dist/integrations/siem/index.d.ts +56 -0
  53. package/dist/integrations/siem/index.d.ts.map +1 -0
  54. package/dist/integrations/siem/index.js +117 -0
  55. package/dist/integrations/siem/index.js.map +1 -0
  56. package/dist/integrations/siem/sentinel.d.ts +53 -0
  57. package/dist/integrations/siem/sentinel.d.ts.map +1 -0
  58. package/dist/integrations/siem/sentinel.js +231 -0
  59. package/dist/integrations/siem/sentinel.js.map +1 -0
  60. package/dist/integrations/siem/splunk.d.ts +46 -0
  61. package/dist/integrations/siem/splunk.d.ts.map +1 -0
  62. package/dist/integrations/siem/splunk.js +210 -0
  63. package/dist/integrations/siem/splunk.js.map +1 -0
  64. package/dist/integrations/siem/types.d.ts +210 -0
  65. package/dist/integrations/siem/types.d.ts.map +1 -0
  66. package/dist/integrations/siem/types.js +9 -0
  67. package/dist/integrations/siem/types.js.map +1 -0
  68. package/dist/persistence/__tests__/persistence.test.d.ts +5 -0
  69. package/dist/persistence/__tests__/persistence.test.d.ts.map +1 -0
  70. package/dist/persistence/__tests__/persistence.test.js +369 -0
  71. package/dist/persistence/__tests__/persistence.test.js.map +1 -0
  72. package/dist/persistence/db.d.ts +15 -0
  73. package/dist/persistence/db.d.ts.map +1 -0
  74. package/dist/persistence/db.js +79 -0
  75. package/dist/persistence/db.js.map +1 -0
  76. package/dist/persistence/index.d.ts +66 -0
  77. package/dist/persistence/index.d.ts.map +1 -0
  78. package/dist/persistence/index.js +143 -0
  79. package/dist/persistence/index.js.map +1 -0
  80. package/dist/persistence/migrations/index.d.ts +10 -0
  81. package/dist/persistence/migrations/index.d.ts.map +1 -0
  82. package/dist/persistence/migrations/index.js +125 -0
  83. package/dist/persistence/migrations/index.js.map +1 -0
  84. package/dist/persistence/repositories/findings.d.ts +41 -0
  85. package/dist/persistence/repositories/findings.d.ts.map +1 -0
  86. package/dist/persistence/repositories/findings.js +238 -0
  87. package/dist/persistence/repositories/findings.js.map +1 -0
  88. package/dist/persistence/repositories/projects.d.ts +22 -0
  89. package/dist/persistence/repositories/projects.d.ts.map +1 -0
  90. package/dist/persistence/repositories/projects.js +71 -0
  91. package/dist/persistence/repositories/projects.js.map +1 -0
  92. package/dist/persistence/repositories/scans.d.ts +30 -0
  93. package/dist/persistence/repositories/scans.d.ts.map +1 -0
  94. package/dist/persistence/repositories/scans.js +107 -0
  95. package/dist/persistence/repositories/scans.js.map +1 -0
  96. package/dist/persistence/repositories/trends.d.ts +42 -0
  97. package/dist/persistence/repositories/trends.d.ts.map +1 -0
  98. package/dist/persistence/repositories/trends.js +178 -0
  99. package/dist/persistence/repositories/trends.js.map +1 -0
  100. package/dist/persistence/types.d.ts +105 -0
  101. package/dist/persistence/types.d.ts.map +1 -0
  102. package/dist/persistence/types.js +13 -0
  103. package/dist/persistence/types.js.map +1 -0
  104. package/dist/plugins/types.d.ts +2 -2
  105. package/dist/scanners/ai-code/types.d.ts +12 -12
  106. package/dist/scanners/cache.d.ts.map +1 -1
  107. package/dist/scanners/cache.js +1 -0
  108. package/dist/scanners/cache.js.map +1 -1
  109. package/dist/scanners/deploy/types.d.ts +13 -13
  110. package/dist/scanners/detection/__tests__/detection.test.d.ts +5 -0
  111. package/dist/scanners/detection/__tests__/detection.test.d.ts.map +1 -0
  112. package/dist/scanners/detection/__tests__/detection.test.js +265 -0
  113. package/dist/scanners/detection/__tests__/detection.test.js.map +1 -0
  114. package/dist/scanners/detection/engines/ast-query.d.ts +23 -0
  115. package/dist/scanners/detection/engines/ast-query.d.ts.map +1 -0
  116. package/dist/scanners/detection/engines/ast-query.js +232 -0
  117. package/dist/scanners/detection/engines/ast-query.js.map +1 -0
  118. package/dist/scanners/detection/engines/data-flow.d.ts +12 -0
  119. package/dist/scanners/detection/engines/data-flow.d.ts.map +1 -0
  120. package/dist/scanners/detection/engines/data-flow.js +269 -0
  121. package/dist/scanners/detection/engines/data-flow.js.map +1 -0
  122. package/dist/scanners/detection/index.d.ts +29 -0
  123. package/dist/scanners/detection/index.d.ts.map +1 -0
  124. package/dist/scanners/detection/index.js +140 -0
  125. package/dist/scanners/detection/index.js.map +1 -0
  126. package/dist/scanners/detection/rules/builtin.d.ts +14 -0
  127. package/dist/scanners/detection/rules/builtin.d.ts.map +1 -0
  128. package/dist/scanners/detection/rules/builtin.js +307 -0
  129. package/dist/scanners/detection/rules/builtin.js.map +1 -0
  130. package/dist/scanners/detection/rules/loader.d.ts +19 -0
  131. package/dist/scanners/detection/rules/loader.d.ts.map +1 -0
  132. package/dist/scanners/detection/rules/loader.js +111 -0
  133. package/dist/scanners/detection/rules/loader.js.map +1 -0
  134. package/dist/scanners/detection/types.d.ts +171 -0
  135. package/dist/scanners/detection/types.d.ts.map +1 -0
  136. package/dist/scanners/detection/types.js +36 -0
  137. package/dist/scanners/detection/types.js.map +1 -0
  138. package/dist/scanners/index.d.ts +9 -1
  139. package/dist/scanners/index.d.ts.map +1 -1
  140. package/dist/scanners/index.js +64 -0
  141. package/dist/scanners/index.js.map +1 -1
  142. package/dist/scanners/index.test.js +6 -6
  143. package/dist/scanners/index.test.js.map +1 -1
  144. package/dist/scanners/scale/types.d.ts +3 -3
  145. package/dist/scanners/types.d.ts +1 -1
  146. package/dist/scanners/types.d.ts.map +1 -1
  147. package/dist/scanners/types.js +1 -0
  148. package/dist/scanners/types.js.map +1 -1
  149. package/package.json +5 -1
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Projects Repository
3
+ *
4
+ * CRUD operations for projects.
5
+ *
6
+ * @module persistence/repositories/projects
7
+ */
8
+ import { randomUUID } from "crypto";
9
+ import { basename } from "path";
10
+ export class ProjectsRepository {
11
+ db;
12
+ constructor(db) {
13
+ this.db = db;
14
+ }
15
+ create(path, name) {
16
+ const id = randomUUID();
17
+ const projectName = name || basename(path);
18
+ const createdAt = new Date().toISOString();
19
+ this.db
20
+ .prepare(`INSERT INTO projects (id, path, name, created_at)
21
+ VALUES (?, ?, ?, ?)`)
22
+ .run(id, path, projectName, createdAt);
23
+ return { id, path, name: projectName, createdAt };
24
+ }
25
+ findById(id) {
26
+ const row = this.db
27
+ .prepare("SELECT * FROM projects WHERE id = ?")
28
+ .get(id);
29
+ return row ? this.mapRow(row) : undefined;
30
+ }
31
+ findByPath(path) {
32
+ const row = this.db
33
+ .prepare("SELECT * FROM projects WHERE path = ?")
34
+ .get(path);
35
+ return row ? this.mapRow(row) : undefined;
36
+ }
37
+ findOrCreate(path, name) {
38
+ const existing = this.findByPath(path);
39
+ if (existing)
40
+ return existing;
41
+ return this.create(path, name);
42
+ }
43
+ list() {
44
+ const rows = this.db
45
+ .prepare("SELECT * FROM projects ORDER BY last_scan_at DESC NULLS LAST, created_at DESC")
46
+ .all();
47
+ return rows.map((r) => this.mapRow(r));
48
+ }
49
+ updateLastScan(id) {
50
+ this.db
51
+ .prepare("UPDATE projects SET last_scan_at = datetime('now') WHERE id = ?")
52
+ .run(id);
53
+ }
54
+ delete(id) {
55
+ const result = this.db
56
+ .prepare("DELETE FROM projects WHERE id = ?")
57
+ .run(id);
58
+ return result.changes > 0;
59
+ }
60
+ mapRow(row) {
61
+ return {
62
+ id: row.id,
63
+ path: row.path,
64
+ name: row.name,
65
+ createdAt: row.created_at,
66
+ lastScanAt: row.last_scan_at || undefined,
67
+ metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
68
+ };
69
+ }
70
+ }
71
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../../src/persistence/repositories/projects.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEhC,MAAM,OAAO,kBAAkB;IACT;IAApB,YAAoB,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;IAAG,CAAC;IAE7C,MAAM,CAAC,IAAY,EAAE,IAAa;QAChC,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,WAAW,GAAG,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3C,IAAI,CAAC,EAAE;aACJ,OAAO,CACN;6BACqB,CACtB;aACA,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QAEzC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;IACpD,CAAC;IAED,QAAQ,CAAC,EAAU;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CAAC,qCAAqC,CAAC;aAC9C,GAAG,CAAC,EAAE,CAAQ,CAAC;QAElB,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CAAC,uCAAuC,CAAC;aAChD,GAAG,CAAC,IAAI,CAAQ,CAAC;QAEpB,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5C,CAAC;IAED,YAAY,CAAC,IAAY,EAAE,IAAa;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,IAAI;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE;aACjB,OAAO,CAAC,+EAA+E,CAAC;aACxF,GAAG,EAAW,CAAC;QAElB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,cAAc,CAAC,EAAU;QACvB,IAAI,CAAC,EAAE;aACJ,OAAO,CAAC,iEAAiE,CAAC;aAC1E,GAAG,CAAC,EAAE,CAAC,CAAC;IACb,CAAC;IAED,MAAM,CAAC,EAAU;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE;aACnB,OAAO,CAAC,mCAAmC,CAAC;aAC5C,GAAG,CAAC,EAAE,CAAC,CAAC;QAEX,OAAO,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEO,MAAM,CAAC,GAAQ;QACrB,OAAO;YACL,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,SAAS,EAAE,GAAG,CAAC,UAAU;YACzB,UAAU,EAAE,GAAG,CAAC,YAAY,IAAI,SAAS;YACzC,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9D,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Scans Repository
3
+ *
4
+ * CRUD operations for scan history.
5
+ *
6
+ * @module persistence/repositories/scans
7
+ */
8
+ import type Database from "better-sqlite3";
9
+ import type { Scan } from "../types.js";
10
+ import type { Severity } from "../../certification/types.js";
11
+ export declare class ScansRepository {
12
+ private db;
13
+ constructor(db: Database.Database);
14
+ create(projectId: string, certificationId?: string): Scan;
15
+ complete(id: string, results: {
16
+ totalFindings: number;
17
+ newFindings: number;
18
+ fixedFindings: number;
19
+ bySeverity: Record<Severity, number>;
20
+ byScanner: Record<string, number>;
21
+ duration: number;
22
+ }): void;
23
+ fail(id: string, error: string): void;
24
+ findById(id: string): Scan | undefined;
25
+ findByProject(projectId: string, limit?: number): Scan[];
26
+ findRecent(limit?: number): Scan[];
27
+ getCompletedCount(projectId: string, sinceDate?: string): number;
28
+ private mapRow;
29
+ }
30
+ //# sourceMappingURL=scans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scans.d.ts","sourceRoot":"","sources":["../../../src/persistence/repositories/scans.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAG7D,qBAAa,eAAe;IACd,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAEzC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI;IAyBzD,QAAQ,CACN,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,QAAQ,EAAE,MAAM,CAAC;KAClB,GACA,IAAI;IAyBP,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAYrC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAQtC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,IAAI,EAAE;IAWpD,UAAU,CAAC,KAAK,SAAM,GAAG,IAAI,EAAE;IAU/B,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAahE,OAAO,CAAC,MAAM;CAoBf"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Scans Repository
3
+ *
4
+ * CRUD operations for scan history.
5
+ *
6
+ * @module persistence/repositories/scans
7
+ */
8
+ import { randomUUID } from "crypto";
9
+ export class ScansRepository {
10
+ db;
11
+ constructor(db) {
12
+ this.db = db;
13
+ }
14
+ create(projectId, certificationId) {
15
+ const id = randomUUID();
16
+ const startedAt = new Date().toISOString();
17
+ this.db
18
+ .prepare(`INSERT INTO scans (id, project_id, certification_id, started_at, status)
19
+ VALUES (?, ?, ?, ?, 'running')`)
20
+ .run(id, projectId, certificationId || null, startedAt);
21
+ return {
22
+ id,
23
+ projectId,
24
+ certificationId,
25
+ startedAt,
26
+ status: "running",
27
+ totalFindings: 0,
28
+ newFindings: 0,
29
+ fixedFindings: 0,
30
+ bySeverity: { critical: 0, high: 0, medium: 0, low: 0, info: 0 },
31
+ byScanner: {},
32
+ };
33
+ }
34
+ complete(id, results) {
35
+ this.db
36
+ .prepare(`UPDATE scans SET
37
+ completed_at = datetime('now'),
38
+ status = 'completed',
39
+ total_findings = ?,
40
+ new_findings = ?,
41
+ fixed_findings = ?,
42
+ by_severity = ?,
43
+ by_scanner = ?,
44
+ duration = ?
45
+ WHERE id = ?`)
46
+ .run(results.totalFindings, results.newFindings, results.fixedFindings, JSON.stringify(results.bySeverity), JSON.stringify(results.byScanner), results.duration, id);
47
+ }
48
+ fail(id, error) {
49
+ this.db
50
+ .prepare(`UPDATE scans SET
51
+ completed_at = datetime('now'),
52
+ status = 'failed',
53
+ error = ?
54
+ WHERE id = ?`)
55
+ .run(error, id);
56
+ }
57
+ findById(id) {
58
+ const row = this.db
59
+ .prepare("SELECT * FROM scans WHERE id = ?")
60
+ .get(id);
61
+ return row ? this.mapRow(row) : undefined;
62
+ }
63
+ findByProject(projectId, limit = 50) {
64
+ const rows = this.db
65
+ .prepare(`SELECT * FROM scans WHERE project_id = ?
66
+ ORDER BY started_at DESC LIMIT ?`)
67
+ .all(projectId, limit);
68
+ return rows.map((r) => this.mapRow(r));
69
+ }
70
+ findRecent(limit = 100) {
71
+ const rows = this.db
72
+ .prepare(`SELECT * FROM scans ORDER BY started_at DESC LIMIT ?`)
73
+ .all(limit);
74
+ return rows.map((r) => this.mapRow(r));
75
+ }
76
+ getCompletedCount(projectId, sinceDate) {
77
+ let sql = "SELECT COUNT(*) as count FROM scans WHERE project_id = ? AND status = 'completed'";
78
+ const params = [projectId];
79
+ if (sinceDate) {
80
+ sql += " AND started_at >= ?";
81
+ params.push(sinceDate);
82
+ }
83
+ const result = this.db.prepare(sql).get(...params);
84
+ return result?.count || 0;
85
+ }
86
+ mapRow(row) {
87
+ return {
88
+ id: row.id,
89
+ projectId: row.project_id,
90
+ certificationId: row.certification_id || undefined,
91
+ startedAt: row.started_at,
92
+ completedAt: row.completed_at || undefined,
93
+ status: row.status,
94
+ totalFindings: row.total_findings || 0,
95
+ newFindings: row.new_findings || 0,
96
+ fixedFindings: row.fixed_findings || 0,
97
+ bySeverity: row.by_severity
98
+ ? JSON.parse(row.by_severity)
99
+ : { critical: 0, high: 0, medium: 0, low: 0, info: 0 },
100
+ byScanner: row.by_scanner ? JSON.parse(row.by_scanner) : {},
101
+ duration: row.duration || undefined,
102
+ error: row.error || undefined,
103
+ metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
104
+ };
105
+ }
106
+ }
107
+ //# sourceMappingURL=scans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scans.js","sourceRoot":"","sources":["../../../src/persistence/repositories/scans.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Trends Repository
3
+ *
4
+ * Historical trend calculations and aggregations.
5
+ *
6
+ * @module persistence/repositories/trends
7
+ */
8
+ import type Database from "better-sqlite3";
9
+ import type { TrendData } from "../types.js";
10
+ import type { Severity } from "../../certification/types.js";
11
+ export type TrendPeriodType = "day" | "week" | "month";
12
+ export declare class TrendsRepository {
13
+ private db;
14
+ constructor(db: Database.Database);
15
+ calculateTrends(projectId: string, period: TrendPeriodType, lookbackPeriods?: number): TrendData[];
16
+ getMTTR(projectId: string, period: TrendPeriodType, lookbackPeriods?: number): {
17
+ period: string;
18
+ mttrHours: number;
19
+ }[];
20
+ getFixVelocity(projectId: string, period: TrendPeriodType, lookbackPeriods?: number): {
21
+ period: string;
22
+ fixesCount: number;
23
+ }[];
24
+ getSeverityTrends(projectId: string, period: TrendPeriodType, lookbackPeriods?: number): {
25
+ period: string;
26
+ bySeverity: Record<Severity, number>;
27
+ }[];
28
+ getCategoryBreakdown(projectId: string): {
29
+ category: string;
30
+ count: number;
31
+ percentage: number;
32
+ }[];
33
+ getScannerEffectiveness(projectId: string): {
34
+ scanner: string;
35
+ found: number;
36
+ falsePositives: number;
37
+ accuracy: number;
38
+ }[];
39
+ private getPeriodFormat;
40
+ private getPeriodInterval;
41
+ }
42
+ //# sourceMappingURL=trends.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trends.d.ts","sourceRoot":"","sources":["../../../src/persistence/repositories/trends.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE7D,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvD,qBAAa,gBAAgB;IACf,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAEzC,eAAe,CACb,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,EACvB,eAAe,SAAK,GACnB,SAAS,EAAE;IAyCd,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,SAAK,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE;IAyBlH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,SAAK,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAAE;IAyB1H,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,EACvB,eAAe,SAAK,GACnB;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;KAAE,EAAE;IAiC7D,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAAE;IA0BlG,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE;IAsB1H,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,iBAAiB;CAU1B"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Trends Repository
3
+ *
4
+ * Historical trend calculations and aggregations.
5
+ *
6
+ * @module persistence/repositories/trends
7
+ */
8
+ export class TrendsRepository {
9
+ db;
10
+ constructor(db) {
11
+ this.db = db;
12
+ }
13
+ calculateTrends(projectId, period, lookbackPeriods = 30) {
14
+ const periodFormat = this.getPeriodFormat(period);
15
+ const periodInterval = this.getPeriodInterval(period);
16
+ const sql = `
17
+ WITH RECURSIVE dates(period_start) AS (
18
+ SELECT date('now', '-${lookbackPeriods * periodInterval} days')
19
+ UNION ALL
20
+ SELECT date(period_start, '+${periodInterval} days')
21
+ FROM dates
22
+ WHERE period_start < date('now')
23
+ ),
24
+ period_data AS (
25
+ SELECT
26
+ strftime('${periodFormat}', d.period_start) as period,
27
+ d.period_start,
28
+ COALESCE(SUM(CASE WHEN f.first_seen_at >= d.period_start
29
+ AND f.first_seen_at < date(d.period_start, '+${periodInterval} days') THEN 1 ELSE 0 END), 0) as new_findings,
30
+ COALESCE(SUM(CASE WHEN f.fixed_at >= d.period_start
31
+ AND f.fixed_at < date(d.period_start, '+${periodInterval} days') THEN 1 ELSE 0 END), 0) as fixed_findings,
32
+ COALESCE(SUM(CASE WHEN f.status = 'open'
33
+ AND f.first_seen_at <= date(d.period_start, '+${periodInterval} days') THEN 1 ELSE 0 END), 0) as open_findings
34
+ FROM dates d
35
+ LEFT JOIN findings f ON f.project_id = ?
36
+ GROUP BY d.period_start
37
+ ORDER BY d.period_start
38
+ )
39
+ SELECT * FROM period_data WHERE period IS NOT NULL
40
+ `;
41
+ const rows = this.db.prepare(sql).all(projectId);
42
+ return rows.map((r) => ({
43
+ period: r.period,
44
+ periodStart: r.period_start,
45
+ newFindings: r.new_findings,
46
+ fixedFindings: r.fixed_findings,
47
+ openFindings: r.open_findings,
48
+ }));
49
+ }
50
+ getMTTR(projectId, period, lookbackPeriods = 12) {
51
+ const periodFormat = this.getPeriodFormat(period);
52
+ const periodInterval = this.getPeriodInterval(period);
53
+ const sql = `
54
+ SELECT
55
+ strftime('${periodFormat}', fixed_at) as period,
56
+ AVG((julianday(fixed_at) - julianday(first_seen_at)) * 24) as mttr_hours
57
+ FROM findings
58
+ WHERE project_id = ?
59
+ AND status = 'fixed'
60
+ AND fixed_at IS NOT NULL
61
+ AND fixed_at >= date('now', '-${lookbackPeriods * periodInterval} days')
62
+ GROUP BY strftime('${periodFormat}', fixed_at)
63
+ ORDER BY period
64
+ `;
65
+ const rows = this.db.prepare(sql).all(projectId);
66
+ return rows.map((r) => ({
67
+ period: r.period,
68
+ mttrHours: r.mttr_hours || 0,
69
+ }));
70
+ }
71
+ getFixVelocity(projectId, period, lookbackPeriods = 12) {
72
+ const periodFormat = this.getPeriodFormat(period);
73
+ const periodInterval = this.getPeriodInterval(period);
74
+ const sql = `
75
+ SELECT
76
+ strftime('${periodFormat}', fixed_at) as period,
77
+ COUNT(*) as fixes_count
78
+ FROM findings
79
+ WHERE project_id = ?
80
+ AND status = 'fixed'
81
+ AND fixed_at IS NOT NULL
82
+ AND fixed_at >= date('now', '-${lookbackPeriods * periodInterval} days')
83
+ GROUP BY strftime('${periodFormat}', fixed_at)
84
+ ORDER BY period
85
+ `;
86
+ const rows = this.db.prepare(sql).all(projectId);
87
+ return rows.map((r) => ({
88
+ period: r.period,
89
+ fixesCount: r.fixes_count,
90
+ }));
91
+ }
92
+ getSeverityTrends(projectId, period, lookbackPeriods = 12) {
93
+ const periodFormat = this.getPeriodFormat(period);
94
+ const periodInterval = this.getPeriodInterval(period);
95
+ const sql = `
96
+ SELECT
97
+ strftime('${periodFormat}', first_seen_at) as period,
98
+ severity,
99
+ COUNT(*) as count
100
+ FROM findings
101
+ WHERE project_id = ?
102
+ AND first_seen_at >= date('now', '-${lookbackPeriods * periodInterval} days')
103
+ GROUP BY strftime('${periodFormat}', first_seen_at), severity
104
+ ORDER BY period
105
+ `;
106
+ const rows = this.db.prepare(sql).all(projectId);
107
+ const grouped = new Map();
108
+ for (const row of rows) {
109
+ if (!grouped.has(row.period)) {
110
+ grouped.set(row.period, { critical: 0, high: 0, medium: 0, low: 0, info: 0 });
111
+ }
112
+ grouped.get(row.period)[row.severity] = row.count;
113
+ }
114
+ return Array.from(grouped.entries()).map(([period, bySeverity]) => ({
115
+ period,
116
+ bySeverity,
117
+ }));
118
+ }
119
+ getCategoryBreakdown(projectId) {
120
+ const total = this.db
121
+ .prepare("SELECT COUNT(*) as count FROM findings WHERE project_id = ? AND status = 'open'")
122
+ .get(projectId);
123
+ const totalCount = total?.count || 0;
124
+ if (totalCount === 0)
125
+ return [];
126
+ const rows = this.db
127
+ .prepare(`SELECT category, COUNT(*) as count
128
+ FROM findings
129
+ WHERE project_id = ? AND status = 'open'
130
+ GROUP BY category
131
+ ORDER BY count DESC`)
132
+ .all(projectId);
133
+ return rows.map((r) => ({
134
+ category: r.category,
135
+ count: r.count,
136
+ percentage: Math.round((r.count / totalCount) * 100),
137
+ }));
138
+ }
139
+ getScannerEffectiveness(projectId) {
140
+ const rows = this.db
141
+ .prepare(`SELECT
142
+ scanner_source,
143
+ COUNT(*) as found,
144
+ SUM(CASE WHEN status = 'false_positive' THEN 1 ELSE 0 END) as false_positives
145
+ FROM findings
146
+ WHERE project_id = ?
147
+ GROUP BY scanner_source
148
+ ORDER BY found DESC`)
149
+ .all(projectId);
150
+ return rows.map((r) => ({
151
+ scanner: r.scanner_source,
152
+ found: r.found,
153
+ falsePositives: r.false_positives,
154
+ accuracy: r.found > 0 ? Math.round(((r.found - r.false_positives) / r.found) * 100) : 100,
155
+ }));
156
+ }
157
+ getPeriodFormat(period) {
158
+ switch (period) {
159
+ case "day":
160
+ return "%Y-%m-%d";
161
+ case "week":
162
+ return "%Y-W%W";
163
+ case "month":
164
+ return "%Y-%m";
165
+ }
166
+ }
167
+ getPeriodInterval(period) {
168
+ switch (period) {
169
+ case "day":
170
+ return 1;
171
+ case "week":
172
+ return 7;
173
+ case "month":
174
+ return 30;
175
+ }
176
+ }
177
+ }
178
+ //# sourceMappingURL=trends.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trends.js","sourceRoot":"","sources":["../../../src/persistence/repositories/trends.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Persistence Layer Types
3
+ *
4
+ * Types for SQLite-backed persistence of findings, scans, and trends.
5
+ *
6
+ * @module persistence/types
7
+ */
8
+ import type { Severity } from "../certification/types.js";
9
+ import type { ScannerType } from "../scanners/types.js";
10
+ export interface Project {
11
+ id: string;
12
+ path: string;
13
+ name: string;
14
+ createdAt: string;
15
+ lastScanAt?: string;
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ export interface PersistedFinding {
19
+ id: string;
20
+ projectId: string;
21
+ certificationId?: string;
22
+ severity: Severity;
23
+ category: string;
24
+ file: string;
25
+ line: number;
26
+ column?: number;
27
+ description: string;
28
+ scannerSource: ScannerType | "agent" | "detection";
29
+ ruleId?: string;
30
+ status: FindingStatus;
31
+ confidence: number;
32
+ cweIds?: string[];
33
+ firstSeenAt: string;
34
+ lastSeenAt: string;
35
+ fixedAt?: string;
36
+ fixedBy?: string;
37
+ falsePositive?: boolean;
38
+ falsePositiveReason?: string;
39
+ metadata?: Record<string, unknown>;
40
+ }
41
+ export type FindingStatus = "open" | "fixed" | "wontfix" | "false_positive" | "in_progress";
42
+ export interface Scan {
43
+ id: string;
44
+ projectId: string;
45
+ certificationId?: string;
46
+ startedAt: string;
47
+ completedAt?: string;
48
+ status: ScanStatus;
49
+ totalFindings: number;
50
+ newFindings: number;
51
+ fixedFindings: number;
52
+ bySeverity: Record<Severity, number>;
53
+ byScanner: Record<string, number>;
54
+ duration?: number;
55
+ error?: string;
56
+ metadata?: Record<string, unknown>;
57
+ }
58
+ export type ScanStatus = "running" | "completed" | "failed" | "cancelled";
59
+ export interface TrendPeriod {
60
+ projectId: string;
61
+ period: "day" | "week" | "month";
62
+ periodStart: string;
63
+ periodEnd: string;
64
+ findingsNew: number;
65
+ findingsFixed: number;
66
+ findingsOpen: number;
67
+ mttrHours?: number;
68
+ bySeverity: Record<Severity, number>;
69
+ }
70
+ export interface ProjectStats {
71
+ projectId: string;
72
+ totalFindings: number;
73
+ openFindings: number;
74
+ fixedFindings: number;
75
+ falsePositives: number;
76
+ bySeverity: Record<Severity, number>;
77
+ byCategory: Record<string, number>;
78
+ byScanner: Record<string, number>;
79
+ avgMttrHours?: number;
80
+ fixVelocityPerWeek?: number;
81
+ lastScanAt?: string;
82
+ firstScanAt?: string;
83
+ }
84
+ export interface TrendData {
85
+ period: string;
86
+ periodStart: string;
87
+ newFindings: number;
88
+ fixedFindings: number;
89
+ openFindings: number;
90
+ mttrHours?: number;
91
+ }
92
+ export interface PersistenceConfig {
93
+ dbPath: string;
94
+ enableWAL?: boolean;
95
+ maxConnections?: number;
96
+ busyTimeout?: number;
97
+ }
98
+ export declare const DEFAULT_PERSISTENCE_CONFIG: PersistenceConfig;
99
+ export interface Migration {
100
+ version: number;
101
+ name: string;
102
+ up: string;
103
+ down: string;
104
+ }
105
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/persistence/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Persistence Layer Types
3
+ *
4
+ * Types for SQLite-backed persistence of findings, scans, and trends.
5
+ *
6
+ * @module persistence/types
7
+ */
8
+ export const DEFAULT_PERSISTENCE_CONFIG = {
9
+ dbPath: ".vaspera/vaspera.db",
10
+ enableWAL: true,
11
+ busyTimeout: 5000,
12
+ };
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/persistence/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsGH,MAAM,CAAC,MAAM,0BAA0B,GAAsB;IAC3D,MAAM,EAAE,qBAAqB;IAC7B,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;CAClB,CAAC"}
@@ -134,8 +134,8 @@ export declare const PluginManifestSchema: z.ZodObject<{
134
134
  module: string;
135
135
  exportName: string;
136
136
  };
137
- license?: string | undefined;
138
137
  author?: string | undefined;
138
+ license?: string | undefined;
139
139
  rules?: {
140
140
  extensions: string[];
141
141
  directory?: string | undefined;
@@ -159,6 +159,7 @@ export declare const PluginManifestSchema: z.ZodObject<{
159
159
  module: string;
160
160
  exportName?: string | undefined;
161
161
  };
162
+ author?: string | undefined;
162
163
  capabilities?: {
163
164
  autofix?: boolean | undefined;
164
165
  incremental?: boolean | undefined;
@@ -166,7 +167,6 @@ export declare const PluginManifestSchema: z.ZodObject<{
166
167
  sandboxable?: boolean | undefined;
167
168
  } | undefined;
168
169
  license?: string | undefined;
169
- author?: string | undefined;
170
170
  rules?: {
171
171
  directory?: string | undefined;
172
172
  extensions?: string[] | undefined;
@@ -115,6 +115,12 @@ export declare const AIVerifyConfigSchema: z.ZodObject<{
115
115
  }>>;
116
116
  exclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
117
117
  }, "strip", z.ZodTypeAny, {
118
+ detection?: {
119
+ checkPatterns: boolean;
120
+ checkComments: boolean;
121
+ checkImports: boolean;
122
+ checkMetadata: boolean;
123
+ } | undefined;
118
124
  exclude?: string[] | undefined;
119
125
  hallucination?: {
120
126
  checkImports: boolean;
@@ -122,18 +128,18 @@ export declare const AIVerifyConfigSchema: z.ZodObject<{
122
128
  checkVersions: boolean;
123
129
  packageRegistry: "npm" | "pypi" | "crates";
124
130
  } | undefined;
125
- detection?: {
126
- checkPatterns: boolean;
127
- checkComments: boolean;
128
- checkImports: boolean;
129
- checkMetadata: boolean;
130
- } | undefined;
131
131
  review?: {
132
132
  requireForConfidence: "high" | "medium" | "low";
133
133
  requireForHallucinations: boolean;
134
134
  autoApproveBelow: number;
135
135
  } | undefined;
136
136
  }, {
137
+ detection?: {
138
+ checkPatterns?: boolean | undefined;
139
+ checkComments?: boolean | undefined;
140
+ checkImports?: boolean | undefined;
141
+ checkMetadata?: boolean | undefined;
142
+ } | undefined;
137
143
  exclude?: string[] | undefined;
138
144
  hallucination?: {
139
145
  checkImports?: boolean | undefined;
@@ -141,12 +147,6 @@ export declare const AIVerifyConfigSchema: z.ZodObject<{
141
147
  checkVersions?: boolean | undefined;
142
148
  packageRegistry?: "npm" | "pypi" | "crates" | undefined;
143
149
  } | undefined;
144
- detection?: {
145
- checkPatterns?: boolean | undefined;
146
- checkComments?: boolean | undefined;
147
- checkImports?: boolean | undefined;
148
- checkMetadata?: boolean | undefined;
149
- } | undefined;
150
150
  review?: {
151
151
  requireForConfidence?: "high" | "medium" | "low" | undefined;
152
152
  requireForHallucinations?: boolean | undefined;