coverme-security-scanner 3.4.0 → 3.7.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.
@@ -0,0 +1,231 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Merge multiple partial security reports into a single comprehensive report
5
+ * Usage: coverme-merge .coverme/partial-*.json -o scan.json
6
+ */
7
+
8
+ import { readFileSync, writeFileSync, readdirSync } from 'fs';
9
+ import { join, dirname } from 'path';
10
+
11
+ function mergeReports(inputDir, outputFile) {
12
+ const files = readdirSync(inputDir).filter(f => f.startsWith('partial-') && f.endsWith('.json'));
13
+
14
+ if (files.length === 0) {
15
+ console.error('No partial-*.json files found in', inputDir);
16
+ process.exit(1);
17
+ }
18
+
19
+ console.log(`Merging ${files.length} partial reports...`);
20
+
21
+ // Initialize merged report
22
+ const merged = {
23
+ project: '',
24
+ date: new Date().toISOString().split('T')[0],
25
+ branch: '',
26
+ scope: '',
27
+ methodology: '7 parallel security agents with attack chain analysis',
28
+ summary: { critical: 0, high: 0, medium: 0, low: 0, total: 0 },
29
+ overallRiskLevel: 'low',
30
+ executiveSummary: '',
31
+ topPriorities: [],
32
+ attackChains: [],
33
+ riskMatrix: [],
34
+ architecture: { overview: '', components: [], trustBoundaries: [] },
35
+ network: { diagram: '', ports: [], externalDeps: [] },
36
+ findings: [],
37
+ threatModel: [],
38
+ positiveObservations: [],
39
+ complianceMapping: [],
40
+ remediation: { p0: [], p1: [], p2: [], p3: [] },
41
+ qualityReview: { deadCode: [], dryViolations: [], deprecated: [] },
42
+ resolvedIssues: [],
43
+ privacyAnalysis: []
44
+ };
45
+
46
+ // Process each partial file
47
+ for (const file of files) {
48
+ const filePath = join(inputDir, file);
49
+ console.log(` Processing: ${file}`);
50
+
51
+ try {
52
+ const partial = JSON.parse(readFileSync(filePath, 'utf-8'));
53
+
54
+ // Merge simple fields (take first non-empty value)
55
+ if (partial.project && !merged.project) merged.project = partial.project;
56
+ if (partial.date) merged.date = partial.date;
57
+ if (partial.branch && !merged.branch) merged.branch = partial.branch;
58
+ if (partial.scope && !merged.scope) merged.scope = partial.scope;
59
+ if (partial.executiveSummary && !merged.executiveSummary) {
60
+ merged.executiveSummary = partial.executiveSummary;
61
+ }
62
+
63
+ // Merge arrays (deduplicate by id where applicable)
64
+ if (partial.findings) {
65
+ for (const f of partial.findings) {
66
+ if (!merged.findings.find(x => x.id === f.id)) {
67
+ merged.findings.push(f);
68
+ }
69
+ }
70
+ }
71
+
72
+ if (partial.attackChains) {
73
+ for (const ac of partial.attackChains) {
74
+ if (!merged.attackChains.find(x => x.id === ac.id)) {
75
+ merged.attackChains.push(ac);
76
+ }
77
+ }
78
+ }
79
+
80
+ if (partial.topPriorities) {
81
+ merged.topPriorities.push(...partial.topPriorities);
82
+ }
83
+
84
+ if (partial.riskMatrix) {
85
+ for (const rm of partial.riskMatrix) {
86
+ if (!merged.riskMatrix.find(x => x.category === rm.category)) {
87
+ merged.riskMatrix.push(rm);
88
+ }
89
+ }
90
+ }
91
+
92
+ if (partial.architecture) {
93
+ if (partial.architecture.overview && !merged.architecture.overview) {
94
+ merged.architecture.overview = partial.architecture.overview;
95
+ }
96
+ if (partial.architecture.components) {
97
+ merged.architecture.components.push(...partial.architecture.components);
98
+ }
99
+ if (partial.architecture.trustBoundaries) {
100
+ merged.architecture.trustBoundaries.push(...partial.architecture.trustBoundaries);
101
+ }
102
+ }
103
+
104
+ if (partial.network) {
105
+ if (partial.network.diagram && !merged.network.diagram) {
106
+ merged.network.diagram = partial.network.diagram;
107
+ }
108
+ if (partial.network.ports) {
109
+ for (const p of partial.network.ports) {
110
+ if (!merged.network.ports.find(x => x.port === p.port)) {
111
+ merged.network.ports.push(p);
112
+ }
113
+ }
114
+ }
115
+ if (partial.network.externalDeps) {
116
+ merged.network.externalDeps.push(...partial.network.externalDeps);
117
+ }
118
+ }
119
+
120
+ if (partial.threatModel) {
121
+ for (const tm of partial.threatModel) {
122
+ if (!merged.threatModel.find(x => x.id === tm.id)) {
123
+ merged.threatModel.push(tm);
124
+ }
125
+ }
126
+ }
127
+
128
+ if (partial.positiveObservations) {
129
+ merged.positiveObservations.push(...partial.positiveObservations);
130
+ }
131
+
132
+ if (partial.complianceMapping) {
133
+ for (const cm of partial.complianceMapping) {
134
+ const existing = merged.complianceMapping.find(x => x.framework === cm.framework);
135
+ if (existing) {
136
+ existing.controls.push(...cm.controls);
137
+ } else {
138
+ merged.complianceMapping.push(cm);
139
+ }
140
+ }
141
+ }
142
+
143
+ if (partial.remediation) {
144
+ if (partial.remediation.p0) merged.remediation.p0.push(...partial.remediation.p0);
145
+ if (partial.remediation.p1) merged.remediation.p1.push(...partial.remediation.p1);
146
+ if (partial.remediation.p2) merged.remediation.p2.push(...partial.remediation.p2);
147
+ if (partial.remediation.p3) merged.remediation.p3.push(...partial.remediation.p3);
148
+ }
149
+
150
+ if (partial.qualityReview) {
151
+ if (partial.qualityReview.deadCode) {
152
+ merged.qualityReview.deadCode.push(...partial.qualityReview.deadCode);
153
+ }
154
+ if (partial.qualityReview.dryViolations) {
155
+ merged.qualityReview.dryViolations.push(...partial.qualityReview.dryViolations);
156
+ }
157
+ if (partial.qualityReview.deprecated) {
158
+ merged.qualityReview.deprecated.push(...partial.qualityReview.deprecated);
159
+ }
160
+ }
161
+
162
+ if (partial.resolvedIssues) {
163
+ merged.resolvedIssues.push(...partial.resolvedIssues);
164
+ }
165
+
166
+ if (partial.privacyAnalysis) {
167
+ merged.privacyAnalysis.push(...partial.privacyAnalysis);
168
+ }
169
+
170
+ } catch (e) {
171
+ console.error(` Error parsing ${file}:`, e.message);
172
+ }
173
+ }
174
+
175
+ // Calculate summary counts
176
+ merged.summary.critical = merged.findings.filter(f => f.severity === 'critical').length;
177
+ merged.summary.high = merged.findings.filter(f => f.severity === 'high').length;
178
+ merged.summary.medium = merged.findings.filter(f => f.severity === 'medium').length;
179
+ merged.summary.low = merged.findings.filter(f => f.severity === 'low').length;
180
+ merged.summary.total = merged.findings.length;
181
+
182
+ // Determine overall risk level
183
+ if (merged.summary.critical > 0) {
184
+ merged.overallRiskLevel = 'critical';
185
+ } else if (merged.summary.high > 2) {
186
+ merged.overallRiskLevel = 'high';
187
+ } else if (merged.summary.high > 0 || merged.summary.medium > 3) {
188
+ merged.overallRiskLevel = 'medium';
189
+ } else {
190
+ merged.overallRiskLevel = 'low';
191
+ }
192
+
193
+ // Deduplicate top priorities (keep first 5)
194
+ const seenPriorities = new Set();
195
+ merged.topPriorities = merged.topPriorities.filter(p => {
196
+ if (seenPriorities.has(p.finding)) return false;
197
+ seenPriorities.add(p.finding);
198
+ return true;
199
+ }).slice(0, 5);
200
+
201
+ // Remove empty arrays
202
+ if (merged.qualityReview.deadCode.length === 0 &&
203
+ merged.qualityReview.dryViolations.length === 0 &&
204
+ merged.qualityReview.deprecated.length === 0) {
205
+ delete merged.qualityReview;
206
+ }
207
+ if (merged.resolvedIssues.length === 0) delete merged.resolvedIssues;
208
+ if (merged.privacyAnalysis.length === 0) delete merged.privacyAnalysis;
209
+
210
+ // Write merged report
211
+ writeFileSync(outputFile, JSON.stringify(merged, null, 2));
212
+ console.log(`\nMerged report written to: ${outputFile}`);
213
+ console.log(` Total findings: ${merged.summary.total}`);
214
+ console.log(` Critical: ${merged.summary.critical}, High: ${merged.summary.high}, Medium: ${merged.summary.medium}, Low: ${merged.summary.low}`);
215
+ console.log(` Attack chains: ${merged.attackChains.length}`);
216
+ console.log(` Overall risk: ${merged.overallRiskLevel.toUpperCase()}`);
217
+ }
218
+
219
+ // CLI
220
+ const args = process.argv.slice(2);
221
+ if (args.length < 1) {
222
+ console.log('Usage: coverme-merge <input-dir> [output-file]');
223
+ console.log(' input-dir: Directory containing partial-*.json files');
224
+ console.log(' output-file: Output file (default: scan.json)');
225
+ process.exit(1);
226
+ }
227
+
228
+ const inputDir = args[0];
229
+ const outputFile = args[1] || 'scan.json';
230
+
231
+ mergeReports(inputDir, outputFile);
@@ -1,4 +1,4 @@
1
- # Security Assessment Generator v2
1
+ # Security Assessment Generator v3
2
2
 
3
3
  Run a comprehensive security assessment on this codebase and generate a professional PDF report with deep analysis.
4
4
 
@@ -6,23 +6,31 @@ Run a comprehensive security assessment on this codebase and generate a professi
6
6
 
7
7
  You are a senior security architect and penetration tester performing a pre-production security audit. Run 7 parallel security agents to analyze this codebase comprehensively.
8
8
 
9
+ ### Step 0: Setup (Run First!)
10
+
11
+ Before starting the scan, create the output directory:
12
+
13
+ ```bash
14
+ mkdir -p .coverme
15
+ ```
16
+
9
17
  ### Step 1: Launch Parallel Agents
10
18
 
11
- Launch these 7 agents simultaneously using the Task tool:
19
+ Launch these 7 agents simultaneously using the Task tool. **IMPORTANT: Each agent must write its own partial JSON file immediately when done.**
12
20
 
13
21
  1. **Executive Summary Agent** (subagent_type: Explore)
14
22
  - Understand what the system does
15
23
  - Identify the tech stack and architecture
16
24
  - Map trust boundaries and critical assets
17
25
  - Determine overall risk level
18
- - Identify the crown jewels (most valuable assets)
26
+ - **When done: Write findings to `.coverme/partial-01-executive.json`**
19
27
 
20
28
  2. **Attack Surface Agent** (subagent_type: Explore)
21
29
  - Map all entry points (APIs, webhooks, file uploads, CLI args)
22
30
  - Identify unauthenticated endpoints
23
31
  - Find admin/debug interfaces
24
- - Check for exposed internal services
25
32
  - Document external dependencies and their trust level
33
+ - **When done: Write findings to `.coverme/partial-02-attack-surface.json`**
26
34
 
27
35
  3. **Vulnerability Hunter Agent** (subagent_type: Explore)
28
36
  - OWASP Top 10 deep dive with CODE EVIDENCE
@@ -30,121 +38,37 @@ Launch these 7 agents simultaneously using the Task tool:
30
38
  - Authentication/authorization bypass paths
31
39
  - Injection vulnerabilities (SQL, command, XSS, SSTI)
32
40
  - Secrets in code, hardcoded credentials (show exact lines)
33
- - Insecure deserialization, SSRF, XXE
34
- - Rate limiting gaps, brute force opportunities
41
+ - **When done: Write findings to `.coverme/partial-03-vulnerabilities.json`**
35
42
 
36
43
  4. **Attack Chain Analyst Agent** (subagent_type: Explore)
37
44
  - Identify how vulnerabilities COMBINE for greater impact
38
45
  - Map realistic attack scenarios (entry -> pivot -> objective)
39
46
  - Calculate blast radius for each chain
40
- - Example: "Unauthenticated API + hardcoded secret = full DB access"
41
- - Prioritize chains by likelihood and impact
47
+ - **When done: Write findings to `.coverme/partial-04-attack-chains.json`**
42
48
 
43
49
  5. **Business Logic Agent** (subagent_type: Explore)
44
50
  - Race conditions in critical flows (payments, credits, locks)
45
51
  - Workflow bypass opportunities (skip steps, replay)
46
52
  - Credit/billing manipulation vectors
47
- - Data validation gaps at business boundaries
48
- - PII handling and data residency violations
49
53
  - Privilege escalation paths
54
+ - **When done: Write findings to `.coverme/partial-05-business-logic.json`**
50
55
 
51
56
  6. **Infrastructure Agent** (subagent_type: Explore)
52
57
  - Docker/Kubernetes security (securityContext, network policies)
53
58
  - CI/CD pipeline security gates (or lack thereof)
54
59
  - Secrets management (env vars, mounted secrets, hardcoded)
55
- - Cloud configuration (IAM, S3 buckets, security groups)
56
- - Database security (encryption, access controls)
57
60
  - Dependency vulnerabilities (npm audit, CVEs)
61
+ - **When done: Write findings to `.coverme/partial-06-infrastructure.json`**
58
62
 
59
63
  7. **Compliance & Impact Agent** (subagent_type: Explore)
60
- - Map findings to compliance frameworks (SOC2, PCI-DSS, GDPR, HIPAA)
64
+ - Map findings to compliance frameworks (SOC2, PCI-DSS, GDPR)
61
65
  - Calculate business impact for each critical finding
62
66
  - Estimate financial exposure ranges
63
- - Identify SLA/availability risks
64
- - Determine data breach notification requirements
65
-
66
- ### Step 2: Deep Dive on Findings
67
-
68
- For EVERY critical and high finding, ensure you have:
69
-
70
- 1. **Code Evidence** - The EXACT vulnerable code snippet:
71
- ```
72
- "codeEvidence": [{
73
- "file": "src/auth/login.js",
74
- "startLine": 45,
75
- "endLine": 52,
76
- "code": "const user = await db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);",
77
- "annotation": "User input directly interpolated into SQL query"
78
- }]
79
- ```
80
-
81
- 2. **Exploitability Assessment**:
82
- ```
83
- "exploitability": {
84
- "skillLevel": "novice", // novice/intermediate/expert
85
- "accessRequired": "network", // network/adjacent/local/physical
86
- "authRequired": "none", // none/low/high
87
- "userInteraction": "none", // none/required
88
- "hasPublicExploit": true, // Known PoC exists?
89
- "exploitMaturity": "weaponized", // theoretical/poc/weaponized
90
- "automatable": true // Can be mass-exploited?
91
- }
92
- ```
93
-
94
- 3. **Blast Radius**:
95
- ```
96
- "blastRadius": {
97
- "affectedUsers": "all", // none/single/subset/all
98
- "affectedData": ["PII", "credentials", "financial"],
99
- "affectedServices": ["auth", "payments"],
100
- "cascadeRisk": true, // Leads to further compromise?
101
- "containment": "system" // isolated/component/system/infrastructure
102
- }
103
- ```
104
-
105
- 4. **Business Impact**:
106
- ```
107
- "businessImpact": {
108
- "confidentiality": "high",
109
- "integrity": "high",
110
- "availability": "low",
111
- "financialExposure": "$100k-$1M potential fraud",
112
- "complianceViolations": ["PCI-DSS 6.5.1", "SOC2 CC6.1"],
113
- "reputationalRisk": "high",
114
- "slaImpact": "99.9% SLA at risk"
115
- }
116
- ```
117
-
118
- 5. **Proof of Concept** (safe, non-destructive):
119
- ```
120
- "proofOfConcept": "curl -X POST /api/admin/users -H 'X-Admin: true' -d '{\"role\":\"admin\"}'"
121
- ```
122
-
123
- ### Step 3: Build Attack Chains
124
-
125
- Identify 2-5 realistic attack chains that combine multiple vulnerabilities:
126
-
127
- ```json
128
- "attackChains": [
129
- {
130
- "id": "AC-01",
131
- "name": "Credential Theft to Full Infrastructure Compromise",
132
- "description": "Attacker chains unauthenticated endpoint access with hardcoded secrets to gain full system control",
133
- "likelihood": "high",
134
- "impact": "critical",
135
- "steps": [
136
- { "order": 1, "findingId": "HIGH-02", "action": "Access unauthenticated /enclave/register endpoint", "outcome": "Register malicious enclave with attacker-controlled keys" },
137
- { "order": 2, "findingId": "HIGH-01", "action": "Use leaked tracker API key from Helm values", "outcome": "Gain access to usage analytics and user activity" },
138
- { "order": 3, "findingId": "CRIT-01", "action": "Pivot using AWS credentials from .env", "outcome": "Full AWS account access, S3 data exfiltration" }
139
- ],
140
- "mitigationStrategy": "Breaking any link stops the chain. Priority: rotate AWS credentials immediately."
141
- }
142
- ]
143
- ```
67
+ - **When done: Write findings to `.coverme/partial-07-compliance.json`**
144
68
 
145
- ### Step 4: Compile Results
69
+ ### Agent Output Format
146
70
 
147
- After all agents complete, compile their findings into a JSON file with this enhanced schema:
71
+ Each agent should write a partial JSON with this structure (include only relevant fields):
148
72
 
149
73
  ```json
150
74
  {
@@ -152,40 +76,10 @@ After all agents complete, compile their findings into a JSON file with this enh
152
76
  "date": "YYYY-MM-DD",
153
77
  "branch": "branch-name",
154
78
  "scope": "X files, ~Y lines",
155
- "methodology": "7 parallel security agents with attack chain analysis",
156
-
157
- "summary": {
158
- "critical": 0,
159
- "high": 0,
160
- "medium": 0,
161
- "low": 0,
162
- "total": 0
163
- },
164
-
165
- "overallRiskLevel": "critical|high|medium|low",
166
- "executiveSummary": "2-3 paragraphs: what the system does, key findings, recommended actions...",
79
+ "executiveSummary": "Summary paragraph...",
167
80
 
168
81
  "topPriorities": [
169
- { "finding": "Description", "severity": "critical", "action": "Immediate action required" }
170
- ],
171
-
172
- "attackChains": [
173
- {
174
- "id": "AC-01",
175
- "name": "Chain name",
176
- "description": "How vulnerabilities combine",
177
- "likelihood": "high",
178
- "impact": "critical",
179
- "steps": [
180
- { "order": 1, "findingId": "CRIT-01", "action": "What attacker does", "outcome": "What they achieve" }
181
- ],
182
- "mitigationStrategy": "How to break the chain"
183
- }
184
- ],
185
-
186
- "riskMatrix": [
187
- { "category": "Authentication", "currentRisk": "high", "residualRisk": "low", "trend": "stable" },
188
- { "category": "Data Protection", "currentRisk": "medium", "residualRisk": "low", "trend": "improving" }
82
+ { "finding": "Description", "severity": "critical", "action": "Action needed" }
189
83
  ],
190
84
 
191
85
  "architecture": {
@@ -194,7 +88,7 @@ After all agents complete, compile their findings into a JSON file with this enh
194
88
  { "name": "Component", "technology": "Tech", "description": "Purpose" }
195
89
  ],
196
90
  "trustBoundaries": [
197
- { "id": "TB-01", "boundary": "Internet/DMZ", "trustLevel": "untrusted", "description": "Public API surface" }
91
+ { "id": "TB-01", "boundary": "Name", "trustLevel": "untrusted", "description": "..." }
198
92
  ]
199
93
  },
200
94
 
@@ -202,9 +96,6 @@ After all agents complete, compile their findings into a JSON file with this enh
202
96
  "diagram": "ASCII diagram...",
203
97
  "ports": [
204
98
  { "port": 443, "protocol": "HTTPS", "component": "API", "binding": "0.0.0.0", "purpose": "Public API" }
205
- ],
206
- "externalDeps": [
207
- { "service": "Stripe", "endpoint": "api.stripe.com", "auth": "API key", "risk": "PCI scope" }
208
99
  ]
209
100
  },
210
101
 
@@ -221,58 +112,40 @@ After all agents complete, compile their findings into a JSON file with this enh
221
112
  "status": "open",
222
113
  "dreadScore": 8.5,
223
114
  "cwe": "CWE-89",
224
- "cvssScore": 9.1,
225
- "cvssVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
226
- "codeEvidence": [
227
- {
228
- "file": "src/db/query.js",
229
- "startLine": 45,
230
- "endLine": 48,
231
- "code": "db.query(`SELECT * FROM users WHERE id = ${userId}`)",
232
- "annotation": "Unsanitized user input in SQL query"
233
- }
234
- ],
235
- "exploitability": {
236
- "skillLevel": "novice",
237
- "accessRequired": "network",
238
- "authRequired": "none",
239
- "userInteraction": "none",
240
- "hasPublicExploit": true,
241
- "exploitMaturity": "weaponized",
242
- "automatable": true
243
- },
244
- "blastRadius": {
245
- "affectedUsers": "all",
246
- "affectedData": ["PII", "credentials"],
247
- "affectedServices": ["database", "auth"],
248
- "cascadeRisk": true,
249
- "containment": "system"
250
- },
251
- "businessImpact": {
252
- "confidentiality": "high",
253
- "integrity": "high",
254
- "availability": "none",
255
- "financialExposure": "$500k-$5M breach costs",
256
- "complianceViolations": ["GDPR Art 32", "SOC2 CC6.1"],
257
- "reputationalRisk": "high"
258
- },
259
- "proofOfConcept": "curl '/api/users/1 OR 1=1--'",
260
- "relatedFindings": ["HIGH-02", "HIGH-03"],
261
- "attackChainPosition": "entry",
262
- "references": ["https://owasp.org/Top10/A03_2021-Injection/"]
115
+ "codeEvidence": [{
116
+ "file": "src/file.js",
117
+ "startLine": 45,
118
+ "endLine": 50,
119
+ "code": "vulnerable code here",
120
+ "annotation": "Explanation"
121
+ }],
122
+ "proofOfConcept": "curl command or steps",
123
+ "relatedFindings": ["HIGH-02"]
263
124
  }
264
125
  ],
265
126
 
266
- "threatModel": [
127
+ "attackChains": [
267
128
  {
268
- "id": "T-01",
269
- "severity": "high",
270
- "dread": 6.5,
271
- "status": "open",
272
- "finding": "STRIDE threat description"
129
+ "id": "AC-01",
130
+ "name": "Chain name",
131
+ "description": "How vulnerabilities combine",
132
+ "likelihood": "high",
133
+ "impact": "critical",
134
+ "steps": [
135
+ { "order": 1, "findingId": "CRIT-01", "action": "What attacker does", "outcome": "Result" }
136
+ ],
137
+ "mitigationStrategy": "How to break the chain"
273
138
  }
274
139
  ],
275
140
 
141
+ "riskMatrix": [
142
+ { "category": "Authentication", "currentRisk": "high", "residualRisk": "low", "trend": "stable" }
143
+ ],
144
+
145
+ "threatModel": [
146
+ { "id": "T-01", "severity": "high", "dread": 6.5, "status": "open", "finding": "Description" }
147
+ ],
148
+
276
149
  "positiveObservations": [
277
150
  { "title": "Good Practice", "description": "What they did right..." }
278
151
  ],
@@ -288,43 +161,63 @@ After all agents complete, compile their findings into a JSON file with this enh
288
161
 
289
162
  "remediation": {
290
163
  "p0": [{ "action": "Do this NOW", "finding": "CRIT-01", "owner": "Security" }],
291
- "p1": [{ "action": "Do this week", "finding": "HIGH-01", "owner": "Backend" }],
292
- "p2": [],
293
- "p3": []
294
- }
164
+ "p1": [{ "action": "Do this week", "finding": "HIGH-01", "owner": "Backend" }]
165
+ },
166
+
167
+ "qualityReview": {
168
+ "deadCode": [{ "type": "dead-code", "action": "DELETE", "file": "path", "description": "..." }],
169
+ "dryViolations": [{ "type": "dry-violation", "action": "MERGE", "file": "path", "description": "..." }]
170
+ },
171
+
172
+ "privacyAnalysis": [
173
+ { "category": "Linkability", "risk": "medium", "description": "...", "mitigation": "..." }
174
+ ]
295
175
  }
296
176
  ```
297
177
 
298
- ### Step 5: Generate PDF
178
+ ### Step 2: Wait for All Agents and Verify
179
+
180
+ After launching all agents, wait for them to complete. Then verify all partial files exist:
181
+
182
+ ```bash
183
+ ls -la .coverme/partial-*.json
184
+ ```
185
+
186
+ You should see 7 files (partial-01 through partial-07).
187
+
188
+ ### Step 3: Merge and Generate PDF
299
189
 
300
- Save the JSON to `.coverme/scan.json` in the project root, then generate the PDF:
190
+ Once all 7 partial files are written, merge them and generate the PDF:
301
191
 
302
192
  ```bash
303
- coverme .coverme/scan.json security-assessment-$(date +%Y-%m-%d).pdf && open security-assessment-$(date +%Y-%m-%d).pdf
193
+ coverme-merge .coverme && coverme .coverme/scan.json security-assessment-$(date +%Y-%m-%d).pdf && open security-assessment-$(date +%Y-%m-%d).pdf
304
194
  ```
305
195
 
306
- **IMPORTANT:** You MUST run this command to generate and open the PDF. Do not skip this step.
196
+ This command:
197
+ 1. Merges all partial-*.json files into scan.json
198
+ 2. Generates the PDF report
199
+ 3. Opens it automatically
307
200
 
308
201
  ### Quality Checklist
309
202
 
310
203
  Before generating the PDF, verify:
204
+ - [ ] All 7 partial JSON files exist in .coverme/
311
205
  - [ ] Every CRITICAL/HIGH finding has codeEvidence with actual code
312
- - [ ] Every CRITICAL/HIGH finding has exploitability assessment
313
- - [ ] Every CRITICAL/HIGH finding has blastRadius defined
314
206
  - [ ] At least 2 attack chains are documented
315
- - [ ] Top priorities match the most impactful attack chains
316
- - [ ] Proof of concepts are safe and non-destructive
317
207
  - [ ] CWE IDs are accurate for vulnerability types
318
- - [ ] Compliance violations are specific (e.g., "PCI-DSS 6.5.1" not just "PCI-DSS")
319
208
 
320
209
  ### Output
321
210
 
322
- The final deliverable is:
323
- 1. `.coverme/scan.json` - Enhanced findings data with attack chains
324
- 2. `security-assessment-YYYY-MM-DD.pdf` - Professional PDF report (auto-opened)
211
+ The final deliverables are:
212
+ 1. `.coverme/partial-*.json` - Individual agent reports
213
+ 2. `.coverme/scan.json` - Merged comprehensive report
214
+ 3. `security-assessment-YYYY-MM-DD.pdf` - Professional PDF report
325
215
 
326
216
  ---
327
217
 
328
- Now begin the security assessment. Launch all 7 agents in parallel.
218
+ Now begin the security assessment:
329
219
 
330
- **CRITICAL REMINDER:** After completing the scan and saving scan.json, you MUST run the PDF generation command in Step 5. The assessment is NOT complete until the PDF is generated and opened.
220
+ 1. Run `mkdir -p .coverme`
221
+ 2. Launch all 7 agents in parallel
222
+ 3. Each agent writes its own partial JSON when done
223
+ 4. After all complete, run the merge and PDF generation command
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "coverme-security-scanner",
3
- "version": "3.4.0",
3
+ "version": "3.7.0",
4
4
  "description": "AI-powered security assessment reports with beautiful PDF output",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "coverme": "./bin/coverme.js",
8
+ "coverme-merge": "./bin/merge-reports.js",
8
9
  "coverme-install": "./bin/install-command.js"
9
10
  },
10
11
  "main": "./dist/index.js",