coverme-security-scanner 3.6.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
 
@@ -14,25 +14,23 @@ Before starting the scan, create the output directory:
14
14
  mkdir -p .coverme
15
15
  ```
16
16
 
17
- This prevents errors when saving the scan results.
18
-
19
17
  ### Step 1: Launch Parallel Agents
20
18
 
21
- 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.**
22
20
 
23
21
  1. **Executive Summary Agent** (subagent_type: Explore)
24
22
  - Understand what the system does
25
23
  - Identify the tech stack and architecture
26
24
  - Map trust boundaries and critical assets
27
25
  - Determine overall risk level
28
- - Identify the crown jewels (most valuable assets)
26
+ - **When done: Write findings to `.coverme/partial-01-executive.json`**
29
27
 
30
28
  2. **Attack Surface Agent** (subagent_type: Explore)
31
29
  - Map all entry points (APIs, webhooks, file uploads, CLI args)
32
30
  - Identify unauthenticated endpoints
33
31
  - Find admin/debug interfaces
34
- - Check for exposed internal services
35
32
  - Document external dependencies and their trust level
33
+ - **When done: Write findings to `.coverme/partial-02-attack-surface.json`**
36
34
 
37
35
  3. **Vulnerability Hunter Agent** (subagent_type: Explore)
38
36
  - OWASP Top 10 deep dive with CODE EVIDENCE
@@ -40,121 +38,37 @@ Launch these 7 agents simultaneously using the Task tool:
40
38
  - Authentication/authorization bypass paths
41
39
  - Injection vulnerabilities (SQL, command, XSS, SSTI)
42
40
  - Secrets in code, hardcoded credentials (show exact lines)
43
- - Insecure deserialization, SSRF, XXE
44
- - Rate limiting gaps, brute force opportunities
41
+ - **When done: Write findings to `.coverme/partial-03-vulnerabilities.json`**
45
42
 
46
43
  4. **Attack Chain Analyst Agent** (subagent_type: Explore)
47
44
  - Identify how vulnerabilities COMBINE for greater impact
48
45
  - Map realistic attack scenarios (entry -> pivot -> objective)
49
46
  - Calculate blast radius for each chain
50
- - Example: "Unauthenticated API + hardcoded secret = full DB access"
51
- - Prioritize chains by likelihood and impact
47
+ - **When done: Write findings to `.coverme/partial-04-attack-chains.json`**
52
48
 
53
49
  5. **Business Logic Agent** (subagent_type: Explore)
54
50
  - Race conditions in critical flows (payments, credits, locks)
55
51
  - Workflow bypass opportunities (skip steps, replay)
56
52
  - Credit/billing manipulation vectors
57
- - Data validation gaps at business boundaries
58
- - PII handling and data residency violations
59
53
  - Privilege escalation paths
54
+ - **When done: Write findings to `.coverme/partial-05-business-logic.json`**
60
55
 
61
56
  6. **Infrastructure Agent** (subagent_type: Explore)
62
57
  - Docker/Kubernetes security (securityContext, network policies)
63
58
  - CI/CD pipeline security gates (or lack thereof)
64
59
  - Secrets management (env vars, mounted secrets, hardcoded)
65
- - Cloud configuration (IAM, S3 buckets, security groups)
66
- - Database security (encryption, access controls)
67
60
  - Dependency vulnerabilities (npm audit, CVEs)
61
+ - **When done: Write findings to `.coverme/partial-06-infrastructure.json`**
68
62
 
69
63
  7. **Compliance & Impact Agent** (subagent_type: Explore)
70
- - Map findings to compliance frameworks (SOC2, PCI-DSS, GDPR, HIPAA)
64
+ - Map findings to compliance frameworks (SOC2, PCI-DSS, GDPR)
71
65
  - Calculate business impact for each critical finding
72
66
  - Estimate financial exposure ranges
73
- - Identify SLA/availability risks
74
- - Determine data breach notification requirements
75
-
76
- ### Step 2: Deep Dive on Findings
77
-
78
- For EVERY critical and high finding, ensure you have:
79
-
80
- 1. **Code Evidence** - The EXACT vulnerable code snippet:
81
- ```
82
- "codeEvidence": [{
83
- "file": "src/auth/login.js",
84
- "startLine": 45,
85
- "endLine": 52,
86
- "code": "const user = await db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);",
87
- "annotation": "User input directly interpolated into SQL query"
88
- }]
89
- ```
90
-
91
- 2. **Exploitability Assessment**:
92
- ```
93
- "exploitability": {
94
- "skillLevel": "novice", // novice/intermediate/expert
95
- "accessRequired": "network", // network/adjacent/local/physical
96
- "authRequired": "none", // none/low/high
97
- "userInteraction": "none", // none/required
98
- "hasPublicExploit": true, // Known PoC exists?
99
- "exploitMaturity": "weaponized", // theoretical/poc/weaponized
100
- "automatable": true // Can be mass-exploited?
101
- }
102
- ```
103
-
104
- 3. **Blast Radius**:
105
- ```
106
- "blastRadius": {
107
- "affectedUsers": "all", // none/single/subset/all
108
- "affectedData": ["PII", "credentials", "financial"],
109
- "affectedServices": ["auth", "payments"],
110
- "cascadeRisk": true, // Leads to further compromise?
111
- "containment": "system" // isolated/component/system/infrastructure
112
- }
113
- ```
114
-
115
- 4. **Business Impact**:
116
- ```
117
- "businessImpact": {
118
- "confidentiality": "high",
119
- "integrity": "high",
120
- "availability": "low",
121
- "financialExposure": "$100k-$1M potential fraud",
122
- "complianceViolations": ["PCI-DSS 6.5.1", "SOC2 CC6.1"],
123
- "reputationalRisk": "high",
124
- "slaImpact": "99.9% SLA at risk"
125
- }
126
- ```
127
-
128
- 5. **Proof of Concept** (safe, non-destructive):
129
- ```
130
- "proofOfConcept": "curl -X POST /api/admin/users -H 'X-Admin: true' -d '{\"role\":\"admin\"}'"
131
- ```
132
-
133
- ### Step 3: Build Attack Chains
134
-
135
- Identify 2-5 realistic attack chains that combine multiple vulnerabilities:
67
+ - **When done: Write findings to `.coverme/partial-07-compliance.json`**
136
68
 
137
- ```json
138
- "attackChains": [
139
- {
140
- "id": "AC-01",
141
- "name": "Credential Theft to Full Infrastructure Compromise",
142
- "description": "Attacker chains unauthenticated endpoint access with hardcoded secrets to gain full system control",
143
- "likelihood": "high",
144
- "impact": "critical",
145
- "steps": [
146
- { "order": 1, "findingId": "HIGH-02", "action": "Access unauthenticated /enclave/register endpoint", "outcome": "Register malicious enclave with attacker-controlled keys" },
147
- { "order": 2, "findingId": "HIGH-01", "action": "Use leaked tracker API key from Helm values", "outcome": "Gain access to usage analytics and user activity" },
148
- { "order": 3, "findingId": "CRIT-01", "action": "Pivot using AWS credentials from .env", "outcome": "Full AWS account access, S3 data exfiltration" }
149
- ],
150
- "mitigationStrategy": "Breaking any link stops the chain. Priority: rotate AWS credentials immediately."
151
- }
152
- ]
153
- ```
69
+ ### Agent Output Format
154
70
 
155
- ### Step 4: Compile Results
156
-
157
- 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):
158
72
 
159
73
  ```json
160
74
  {
@@ -162,40 +76,10 @@ After all agents complete, compile their findings into a JSON file with this enh
162
76
  "date": "YYYY-MM-DD",
163
77
  "branch": "branch-name",
164
78
  "scope": "X files, ~Y lines",
165
- "methodology": "7 parallel security agents with attack chain analysis",
166
-
167
- "summary": {
168
- "critical": 0,
169
- "high": 0,
170
- "medium": 0,
171
- "low": 0,
172
- "total": 0
173
- },
174
-
175
- "overallRiskLevel": "critical|high|medium|low",
176
- "executiveSummary": "2-3 paragraphs: what the system does, key findings, recommended actions...",
79
+ "executiveSummary": "Summary paragraph...",
177
80
 
178
81
  "topPriorities": [
179
- { "finding": "Description", "severity": "critical", "action": "Immediate action required" }
180
- ],
181
-
182
- "attackChains": [
183
- {
184
- "id": "AC-01",
185
- "name": "Chain name",
186
- "description": "How vulnerabilities combine",
187
- "likelihood": "high",
188
- "impact": "critical",
189
- "steps": [
190
- { "order": 1, "findingId": "CRIT-01", "action": "What attacker does", "outcome": "What they achieve" }
191
- ],
192
- "mitigationStrategy": "How to break the chain"
193
- }
194
- ],
195
-
196
- "riskMatrix": [
197
- { "category": "Authentication", "currentRisk": "high", "residualRisk": "low", "trend": "stable" },
198
- { "category": "Data Protection", "currentRisk": "medium", "residualRisk": "low", "trend": "improving" }
82
+ { "finding": "Description", "severity": "critical", "action": "Action needed" }
199
83
  ],
200
84
 
201
85
  "architecture": {
@@ -204,7 +88,7 @@ After all agents complete, compile their findings into a JSON file with this enh
204
88
  { "name": "Component", "technology": "Tech", "description": "Purpose" }
205
89
  ],
206
90
  "trustBoundaries": [
207
- { "id": "TB-01", "boundary": "Internet/DMZ", "trustLevel": "untrusted", "description": "Public API surface" }
91
+ { "id": "TB-01", "boundary": "Name", "trustLevel": "untrusted", "description": "..." }
208
92
  ]
209
93
  },
210
94
 
@@ -212,9 +96,6 @@ After all agents complete, compile their findings into a JSON file with this enh
212
96
  "diagram": "ASCII diagram...",
213
97
  "ports": [
214
98
  { "port": 443, "protocol": "HTTPS", "component": "API", "binding": "0.0.0.0", "purpose": "Public API" }
215
- ],
216
- "externalDeps": [
217
- { "service": "Stripe", "endpoint": "api.stripe.com", "auth": "API key", "risk": "PCI scope" }
218
99
  ]
219
100
  },
220
101
 
@@ -231,58 +112,40 @@ After all agents complete, compile their findings into a JSON file with this enh
231
112
  "status": "open",
232
113
  "dreadScore": 8.5,
233
114
  "cwe": "CWE-89",
234
- "cvssScore": 9.1,
235
- "cvssVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
236
- "codeEvidence": [
237
- {
238
- "file": "src/db/query.js",
239
- "startLine": 45,
240
- "endLine": 48,
241
- "code": "db.query(`SELECT * FROM users WHERE id = ${userId}`)",
242
- "annotation": "Unsanitized user input in SQL query"
243
- }
244
- ],
245
- "exploitability": {
246
- "skillLevel": "novice",
247
- "accessRequired": "network",
248
- "authRequired": "none",
249
- "userInteraction": "none",
250
- "hasPublicExploit": true,
251
- "exploitMaturity": "weaponized",
252
- "automatable": true
253
- },
254
- "blastRadius": {
255
- "affectedUsers": "all",
256
- "affectedData": ["PII", "credentials"],
257
- "affectedServices": ["database", "auth"],
258
- "cascadeRisk": true,
259
- "containment": "system"
260
- },
261
- "businessImpact": {
262
- "confidentiality": "high",
263
- "integrity": "high",
264
- "availability": "none",
265
- "financialExposure": "$500k-$5M breach costs",
266
- "complianceViolations": ["GDPR Art 32", "SOC2 CC6.1"],
267
- "reputationalRisk": "high"
268
- },
269
- "proofOfConcept": "curl '/api/users/1 OR 1=1--'",
270
- "relatedFindings": ["HIGH-02", "HIGH-03"],
271
- "attackChainPosition": "entry",
272
- "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"]
273
124
  }
274
125
  ],
275
126
 
276
- "threatModel": [
127
+ "attackChains": [
277
128
  {
278
- "id": "T-01",
279
- "severity": "high",
280
- "dread": 6.5,
281
- "status": "open",
282
- "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"
283
138
  }
284
139
  ],
285
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
+
286
149
  "positiveObservations": [
287
150
  { "title": "Good Practice", "description": "What they did right..." }
288
151
  ],
@@ -298,53 +161,63 @@ After all agents complete, compile their findings into a JSON file with this enh
298
161
 
299
162
  "remediation": {
300
163
  "p0": [{ "action": "Do this NOW", "finding": "CRIT-01", "owner": "Security" }],
301
- "p1": [{ "action": "Do this week", "finding": "HIGH-01", "owner": "Backend" }],
302
- "p2": [],
303
- "p3": []
304
- }
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
+ ]
305
175
  }
306
176
  ```
307
177
 
308
- ### Step 5: Save and Generate PDF
178
+ ### Step 2: Wait for All Agents and Verify
309
179
 
310
- **IMPORTANT: Write the JSON using the Write tool, NOT bash heredoc.**
180
+ After launching all agents, wait for them to complete. Then verify all partial files exist:
311
181
 
312
- 1. **Create the output directory first:**
313
182
  ```bash
314
- mkdir -p .coverme
183
+ ls -la .coverme/partial-*.json
315
184
  ```
316
185
 
317
- 2. **Use the Write tool to save `.coverme/scan.json`** with ALL findings from the agents.
318
- Include everything: all codeEvidence, exploitability, blastRadius, businessImpact.
319
- The more detail, the better the report.
186
+ You should see 7 files (partial-01 through partial-07).
187
+
188
+ ### Step 3: Merge and Generate PDF
189
+
190
+ Once all 7 partial files are written, merge them and generate the PDF:
320
191
 
321
- 3. **Generate the PDF:**
322
192
  ```bash
323
- 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
324
194
  ```
325
195
 
326
- **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
327
200
 
328
201
  ### Quality Checklist
329
202
 
330
203
  Before generating the PDF, verify:
204
+ - [ ] All 7 partial JSON files exist in .coverme/
331
205
  - [ ] Every CRITICAL/HIGH finding has codeEvidence with actual code
332
- - [ ] Every CRITICAL/HIGH finding has exploitability assessment
333
- - [ ] Every CRITICAL/HIGH finding has blastRadius defined
334
206
  - [ ] At least 2 attack chains are documented
335
- - [ ] Top priorities match the most impactful attack chains
336
- - [ ] Proof of concepts are safe and non-destructive
337
207
  - [ ] CWE IDs are accurate for vulnerability types
338
- - [ ] Compliance violations are specific (e.g., "PCI-DSS 6.5.1" not just "PCI-DSS")
339
208
 
340
209
  ### Output
341
210
 
342
- The final deliverable is:
343
- 1. `.coverme/scan.json` - Enhanced findings data with attack chains
344
- 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
345
215
 
346
216
  ---
347
217
 
348
- Now begin the security assessment. Launch all 7 agents in parallel.
218
+ Now begin the security assessment:
349
219
 
350
- **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.6.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",