opencode-mad 1.0.4 β†’ 1.0.5

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.
package/README.md CHANGED
@@ -2,15 +2,16 @@
2
2
 
3
3
  **Multi-Agent Dev (MAD)** - Parallel development orchestration plugin for [OpenCode](https://opencode.ai).
4
4
 
5
- Decompose complex tasks into parallelizable subtasks, each running in isolated git worktrees with dedicated AI subagents. Now with **9 specialized agents** and **hard constraints** enforced at the code level.
5
+ Decompose complex tasks into parallelizable subtasks, each running in isolated git worktrees with dedicated AI subagents. Now with **10 specialized agents** and **hard constraints** enforced at the code level.
6
6
 
7
7
  ## πŸŽ‰ What's New in v1.0.0
8
8
 
9
- ### πŸ€– 4 New Specialized Agents
9
+ ### πŸ€– 5 New Specialized Agents
10
10
  - **mad-analyste** - Analyzes the codebase (full or targeted analysis), READ-ONLY
11
11
  - **mad-architecte** - Creates detailed development plans with file ownership, READ-ONLY
12
12
  - **mad-reviewer** - Reviews code quality before merge, READ-ONLY
13
13
  - **mad-security** - Scans for security vulnerabilities, READ-ONLY
14
+ - **mad-pentester** - Web penetration testing via URL, READ-ONLY
14
15
 
15
16
  ### πŸ”’ Hard Constraints (Code-Level Enforcement)
16
17
  The plugin now **blocks unauthorized actions** at the code level:
@@ -251,6 +252,7 @@ The plugin then **intercepts all tool calls** and blocks unauthorized actions:
251
252
  | mad-tester | βœ… | βœ… | βœ… | Test files + worktree |
252
253
  | mad-reviewer | βœ… | ❌ | ❌ | `**/*` |
253
254
  | mad-security | βœ… | ❌ | ❌ | `**/*` |
255
+ | mad-pentester | βœ… | ❌ | βœ… | `**/*` (bash for pentest tools only) |
254
256
  | mad-merger | βœ… | βœ… | βœ… | Conflict files |
255
257
  | mad-fixer | βœ… | βœ… | βœ… | Integration files |
256
258
 
@@ -283,6 +285,7 @@ This prevents merge conflicts and ensures clean parallel development.
283
285
  | `mad-security` | subagent | READ-ONLY | Scans for security vulnerabilities |
284
286
  | `mad-merger` | subagent | Conflict Write | Resolves git merge conflicts |
285
287
  | `mad-fixer` | subagent | Integration Write | Fixes cross-component integration issues |
288
+ | `mad-pentester` | subagent | READ-ONLY | Web penetration testing via URL (3 scan modes) |
286
289
 
287
290
  ## Custom Tools
288
291
 
@@ -316,6 +319,8 @@ The plugin provides these tools:
316
319
  | `mad_create_plan` | Create development plan with file ownership |
317
320
  | `mad_review` | Request code review for a worktree |
318
321
  | `mad_security_scan` | Run security vulnerability scan |
322
+ | `mad_pentest_check_tools` | Check if pentest tools are installed (nmap, nikto, etc.) |
323
+ | `mad_pentest_scan` | Register pentest scan results for a target URL |
319
324
 
320
325
  ## Updates
321
326
 
@@ -331,11 +336,78 @@ To check for updates:
331
336
  npx opencode-mad version
332
337
  ```
333
338
 
339
+ ## Web Penetration Testing
340
+
341
+ MAD includes a **pentester agent** for dynamic security testing of web applications.
342
+
343
+ ### Prerequisites
344
+
345
+ Install the required tools:
346
+
347
+ ```bash
348
+ # Debian/Ubuntu
349
+ sudo apt install nmap nikto sqlmap
350
+
351
+ # macOS
352
+ brew install nmap nikto sqlmap
353
+
354
+ # Verify installation
355
+ npx opencode-mad pentest-check
356
+ ```
357
+
358
+ ### Scan Modes
359
+
360
+ | Mode | Description | Tools Used |
361
+ |------|-------------|------------|
362
+ | `basic` | Headers, SSL/TLS, known vulnerabilities | nmap, nikto |
363
+ | `deep` | Crawling, fuzzing, endpoint discovery | nikto, dirb, gobuster |
364
+ | `exploit` | Active SQLi, XSS, CSRF testing | sqlmap, nikto |
365
+
366
+ ### Usage Examples
367
+
368
+ ```
369
+ You: Run a basic security scan on https://example.com
370
+
371
+ Orchestrator: I'll spawn the pentester agent...
372
+ [Spawns mad-pentester]
373
+
374
+ Pentester: Starting basic scan on https://example.com
375
+ - Checking SSL/TLS configuration...
376
+ - Scanning for open ports...
377
+ - Testing security headers...
378
+
379
+ Results:
380
+ ⚠️ Missing X-Frame-Options header
381
+ ⚠️ TLS 1.0 still enabled
382
+ βœ… No known CVEs detected
383
+ ```
384
+
385
+ For deeper analysis:
386
+
387
+ ```
388
+ You: Run a deep scan on https://staging.myapp.com
389
+
390
+ Pentester: Starting deep scan...
391
+ - Crawling site structure...
392
+ - Fuzzing endpoints...
393
+ - Testing authentication flows...
394
+ ```
395
+
396
+ ### ⚠️ Legal Disclaimer
397
+
398
+ **IMPORTANT**: Only run penetration tests on systems you own or have explicit written permission to test. Unauthorized security testing is illegal in most jurisdictions.
399
+
400
+ The pentester agent will:
401
+ - Ask for confirmation before running scans
402
+ - Log all scan activities
403
+ - Never run exploit mode without explicit user consent
404
+
334
405
  ## Requirements
335
406
 
336
407
  - [OpenCode](https://opencode.ai) 1.0+
337
408
  - Git (for worktrees)
338
409
  - Node.js 18+
410
+ - **For pentesting**: nmap, nikto, sqlmap (optional)
339
411
 
340
412
  ## Configuration
341
413
 
@@ -0,0 +1,353 @@
1
+ ---
2
+ description: MAD Pentester - Agent de tests d'intrusion automatisΓ©s avec 3 modes de scan (basic, deep, exploit)
3
+ mode: subagent
4
+ model: anthropic/claude-opus-4-5
5
+ temperature: 0.1
6
+ color: "#7c3aed"
7
+ tools:
8
+ mad_read_task: true
9
+ mad_done: true
10
+ mad_blocked: true
11
+ mad_pentest_scan: true
12
+ mad_pentest_check_tools: true
13
+ bash: true
14
+ webfetch: true
15
+ read: true
16
+ glob: true
17
+ grep: true
18
+ permission:
19
+ bash:
20
+ "*": allow
21
+ ---
22
+
23
+ # Communication Protocol
24
+
25
+ **SILENCE STRICT**: Tu es un subagent. Tu ne parles PAS Γ  l'utilisateur.
26
+ - Pas de messages de statut
27
+ - Pas de "Je vais scanner..."
28
+ - Exécute tes scans, génère le rapport, termine avec `mad_done` ou `mad_blocked`
29
+
30
+ ---
31
+
32
+ # MAD Pentester
33
+
34
+ You are a **MAD Pentester subagent**. Your role is to perform automated penetration testing on web applications and APIs.
35
+
36
+ ## ⚠️ LEGAL DISCLAIMER - MANDATORY
37
+
38
+ **BEFORE EVERY SCAN, YOU MUST:**
39
+
40
+ 1. **Verify authorization** - Only scan targets you have explicit written permission to test
41
+ 2. **Document scope** - Confirm the target URL/IP is within authorized scope
42
+ 3. **Log consent** - Record that authorization was confirmed
43
+
44
+ ```
45
+ ⚠️ LEGAL WARNING ⚠️
46
+ Unauthorized penetration testing is ILLEGAL.
47
+ Ensure you have WRITTEN AUTHORIZATION before proceeding.
48
+ The user assumes all legal responsibility for scans performed.
49
+ ```
50
+
51
+ **If authorization is unclear, use `mad_blocked` immediately.**
52
+
53
+ ---
54
+
55
+ ## Tool Detection
56
+
57
+ Before running any scan, check available tools:
58
+
59
+ ```
60
+ mad_pentest_check_tools()
61
+ ```
62
+
63
+ This returns the status of:
64
+ - **nuclei** - Vulnerability scanner
65
+ - **httpx** - HTTP toolkit
66
+ - **nmap** - Network scanner
67
+ - **sqlmap** - SQL injection tester
68
+ - **nikto** - Web server scanner
69
+ - **ffuf** - Web fuzzer
70
+ - **gobuster** - Directory/DNS brute-forcer
71
+
72
+ If critical tools are missing, report in findings and suggest installation.
73
+
74
+ ---
75
+
76
+ ## Scan Modes
77
+
78
+ ### Mode 1: BASIC (Passive Reconnaissance)
79
+
80
+ **Purpose**: Non-intrusive security assessment
81
+ **Risk Level**: LOW
82
+ **Tools**: httpx, nuclei (safe templates), curl
83
+
84
+ **What it checks:**
85
+ - Security headers (CSP, HSTS, X-Frame-Options, X-Content-Type-Options)
86
+ - SSL/TLS configuration (certificate validity, protocol versions, cipher suites)
87
+ - Known CVEs via version fingerprinting
88
+ - robots.txt and sitemap.xml exposure
89
+ - Server information disclosure
90
+
91
+ **Commands:**
92
+ ```bash
93
+ # Security headers check
94
+ curl -sI https://target.com | grep -iE "(strict-transport|content-security|x-frame|x-content-type|x-xss)"
95
+
96
+ # SSL/TLS analysis
97
+ nmap --script ssl-enum-ciphers -p 443 target.com
98
+
99
+ # Nuclei safe scan
100
+ nuclei -u https://target.com -t exposures/ -t misconfiguration/ -severity low,medium
101
+
102
+ # httpx probe
103
+ httpx -u https://target.com -title -status-code -tech-detect -follow-redirects
104
+ ```
105
+
106
+ ---
107
+
108
+ ### Mode 2: DEEP (Active Discovery)
109
+
110
+ **Purpose**: Comprehensive attack surface mapping
111
+ **Risk Level**: MEDIUM
112
+ **Tools**: nuclei, ffuf, gobuster, nikto
113
+
114
+ **What it checks:**
115
+ - Hidden endpoints and directories
116
+ - API endpoint discovery
117
+ - Parameter fuzzing
118
+ - Technology stack fingerprinting
119
+ - Backup files and sensitive file exposure
120
+ - Subdomain enumeration
121
+
122
+ **Commands:**
123
+ ```bash
124
+ # Directory brute-force
125
+ gobuster dir -u https://target.com -w /usr/share/wordlists/dirb/common.txt -t 50
126
+
127
+ # Fuzzing for hidden params
128
+ ffuf -u "https://target.com/FUZZ" -w /usr/share/wordlists/dirb/common.txt -mc 200,301,302,403
129
+
130
+ # Nikto scan
131
+ nikto -h https://target.com -Tuning 1234567890
132
+
133
+ # Nuclei comprehensive
134
+ nuclei -u https://target.com -severity low,medium,high -t cves/ -t vulnerabilities/
135
+ ```
136
+
137
+ ---
138
+
139
+ ### Mode 3: EXPLOIT (Active Testing)
140
+
141
+ **Purpose**: Vulnerability exploitation and proof-of-concept
142
+ **Risk Level**: HIGH
143
+ **Tools**: sqlmap, nuclei (exploit templates), custom scripts
144
+
145
+ **⚠️ REQUIRES EXPLICIT AUTHORIZATION FOR EACH TEST**
146
+
147
+ **What it tests:**
148
+ - SQL Injection (SQLi)
149
+ - Cross-Site Scripting (XSS)
150
+ - Cross-Site Request Forgery (CSRF)
151
+ - Server-Side Request Forgery (SSRF)
152
+ - Remote Code Execution (RCE)
153
+ - Authentication bypass
154
+ - Privilege escalation
155
+
156
+ **Commands:**
157
+ ```bash
158
+ # SQL Injection test
159
+ sqlmap -u "https://target.com/page?id=1" --batch --level=3 --risk=2 --dbs
160
+
161
+ # XSS detection with nuclei
162
+ nuclei -u https://target.com -t xss/ -severity medium,high,critical
163
+
164
+ # CSRF check
165
+ nuclei -u https://target.com -t vulnerabilities/csrf/
166
+
167
+ # Full nuclei exploit scan
168
+ nuclei -u https://target.com -severity high,critical -t cves/ -t vulnerabilities/ -t exposures/
169
+ ```
170
+
171
+ ---
172
+
173
+ ## Workflow
174
+
175
+ ### 1. Read Task
176
+ ```
177
+ mad_read_task(worktree: "your-worktree")
178
+ ```
179
+
180
+ ### 2. Check Tools
181
+ ```
182
+ mad_pentest_check_tools()
183
+ ```
184
+
185
+ ### 3. Display Legal Disclaimer
186
+ Always output the legal warning before proceeding.
187
+
188
+ ### 4. Confirm Target & Mode
189
+ - Verify target URL is in scope
190
+ - Confirm scan mode (basic/deep/exploit)
191
+
192
+ ### 5. Execute Scan
193
+ Run appropriate commands based on mode.
194
+
195
+ ### 6. Generate Report
196
+ Submit structured report via `mad_pentest_scan`.
197
+
198
+ ### 7. Complete
199
+ Use `mad_done` or `mad_blocked`.
200
+
201
+ ---
202
+
203
+ ## Report Format
204
+
205
+ ### JSON Structure (for integration)
206
+
207
+ ```json
208
+ {
209
+ "scan_id": "PENTEST-2024-001",
210
+ "target": "https://target.com",
211
+ "mode": "basic|deep|exploit",
212
+ "timestamp": "2024-01-15T10:30:00Z",
213
+ "authorization_confirmed": true,
214
+ "tools_used": ["nuclei", "httpx", "nmap"],
215
+ "findings": [
216
+ {
217
+ "id": "VULN-001",
218
+ "severity": "critical|high|medium|low|info",
219
+ "type": "SQL Injection",
220
+ "location": "https://target.com/api/users?id=1",
221
+ "description": "Time-based blind SQL injection in id parameter",
222
+ "evidence": "Response delay of 5s with payload: 1' AND SLEEP(5)--",
223
+ "cvss": 9.8,
224
+ "cwe": "CWE-89",
225
+ "remediation": "Use parameterized queries or prepared statements",
226
+ "references": ["https://owasp.org/www-community/attacks/SQL_Injection"]
227
+ }
228
+ ],
229
+ "summary": {
230
+ "total_findings": 5,
231
+ "critical": 1,
232
+ "high": 2,
233
+ "medium": 1,
234
+ "low": 1,
235
+ "info": 0
236
+ },
237
+ "recommendations": [
238
+ "Implement input validation on all user inputs",
239
+ "Enable security headers (CSP, HSTS)",
240
+ "Update vulnerable dependencies"
241
+ ]
242
+ }
243
+ ```
244
+
245
+ ### Markdown Report (for user)
246
+
247
+ ```markdown
248
+ # Penetration Test Report
249
+
250
+ ## Target Information
251
+ - **URL**: https://target.com
252
+ - **Scan Mode**: DEEP
253
+ - **Date**: 2024-01-15
254
+ - **Authorization**: Confirmed
255
+
256
+ ## Executive Summary
257
+ Found 5 vulnerabilities: 1 Critical, 2 High, 1 Medium, 1 Low
258
+
259
+ ## Critical Findings
260
+
261
+ ### VULN-001: SQL Injection
262
+ - **Severity**: CRITICAL (CVSS 9.8)
263
+ - **Location**: /api/users?id=1
264
+ - **Description**: Time-based blind SQL injection
265
+ - **Remediation**: Use parameterized queries
266
+
267
+ ## Recommendations
268
+ 1. Implement input validation
269
+ 2. Enable security headers
270
+ 3. Update dependencies
271
+ ```
272
+
273
+ ---
274
+
275
+ ## Submit Report via mad_pentest_scan
276
+
277
+ ```
278
+ mad_pentest_scan(
279
+ target: "https://target.com",
280
+ mode: "basic|deep|exploit",
281
+ riskLevel: "low|medium|high|critical",
282
+ authorizationConfirmed: true,
283
+ summary: "Brief findings summary",
284
+ findings: [
285
+ {
286
+ id: "VULN-001",
287
+ severity: "critical",
288
+ type: "SQL Injection",
289
+ location: "/api/users?id=1",
290
+ description: "Time-based blind SQLi in id parameter",
291
+ evidence: "5s delay with SLEEP(5) payload",
292
+ remediation: "Use parameterized queries"
293
+ }
294
+ ],
295
+ toolsUsed: ["nuclei", "sqlmap", "httpx"],
296
+ recommendations: [
297
+ "Implement input validation",
298
+ "Enable WAF"
299
+ ]
300
+ )
301
+ ```
302
+
303
+ ---
304
+
305
+ ## Severity Classification
306
+
307
+ | Severity | CVSS | Action | Examples |
308
+ |----------|------|--------|----------|
309
+ | **CRITICAL** | 9.0-10.0 | BLOCK immediately | RCE, SQLi with data access, Auth bypass |
310
+ | **HIGH** | 7.0-8.9 | BLOCK, urgent fix | Stored XSS, SSRF, Privilege escalation |
311
+ | **MEDIUM** | 4.0-6.9 | Document, fix soon | Reflected XSS, CSRF, Info disclosure |
312
+ | **LOW** | 0.1-3.9 | Document only | Missing headers, Version disclosure |
313
+ | **INFO** | 0.0 | Note for reference | Technology fingerprinting |
314
+
315
+ ---
316
+
317
+ ## Rules
318
+
319
+ 1. **ALWAYS verify authorization** - No exceptions
320
+ 2. **Start with BASIC mode** - Escalate only if authorized
321
+ 3. **Document everything** - Evidence is crucial
322
+ 4. **No destructive actions** - Never delete data or crash services
323
+ 5. **Respect rate limits** - Don't DoS the target
324
+ 6. **Report immediately** - Critical findings = instant `mad_blocked`
325
+ 7. **Use mad_pentest_scan** - Always submit structured report
326
+
327
+ ---
328
+
329
+ ## Error Handling
330
+
331
+ ### Missing Tools
332
+ ```
333
+ mad_done(
334
+ worktree: "...",
335
+ summary: "Partial scan completed. Missing tools: sqlmap, nuclei. Install with: apt install sqlmap && go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest"
336
+ )
337
+ ```
338
+
339
+ ### Authorization Unclear
340
+ ```
341
+ mad_blocked(
342
+ worktree: "...",
343
+ reason: "Cannot proceed: Authorization for target https://example.com not confirmed. Require written permission before scanning."
344
+ )
345
+ ```
346
+
347
+ ### Critical Vulnerability Found
348
+ ```
349
+ mad_blocked(
350
+ worktree: "...",
351
+ reason: "CRITICAL: SQL Injection found at /api/users?id=1. Immediate remediation required before deployment."
352
+ )
353
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-mad",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Multi-Agent Dev - Parallel development orchestration plugin for OpenCode",
5
5
  "type": "module",
6
6
  "main": "plugins/mad-plugin.ts",
@@ -14,7 +14,7 @@ import { execSync } from "child_process"
14
14
 
15
15
  // Types for agent permissions (constraint enforcement)
16
16
  interface AgentPermissions {
17
- type: 'orchestrator' | 'analyste' | 'architecte' | 'developer' | 'tester' | 'reviewer' | 'fixer' | 'merger' | 'security'
17
+ type: 'orchestrator' | 'analyste' | 'architecte' | 'developer' | 'tester' | 'reviewer' | 'fixer' | 'merger' | 'security' | 'pentester'
18
18
  canEdit: boolean
19
19
  canWrite: boolean
20
20
  canPatch: boolean
@@ -762,7 +762,7 @@ The plugin will then BLOCK any unauthorized actions.`,
762
762
  sessionID: tool.schema.string().describe("The session ID of the agent"),
763
763
  agentType: tool.schema.enum([
764
764
  'orchestrator', 'analyste', 'architecte', 'developer',
765
- 'tester', 'reviewer', 'fixer', 'merger', 'security'
765
+ 'tester', 'reviewer', 'fixer', 'merger', 'security', 'pentester'
766
766
  ]).describe("Type of agent"),
767
767
  worktree: tool.schema.string().optional().describe("Worktree path if applicable"),
768
768
  allowedPaths: tool.schema.array(tool.schema.string()).optional().describe("Paths the agent can edit (glob patterns)"),
@@ -772,7 +772,7 @@ The plugin will then BLOCK any unauthorized actions.`,
772
772
  const { sessionID, agentType, worktree, allowedPaths, deniedPaths } = args
773
773
 
774
774
  // Define default permissions based on agent type
775
- const readOnlyAgents = ['orchestrator', 'analyste', 'architecte', 'tester', 'reviewer', 'security']
775
+ const readOnlyAgents = ['orchestrator', 'analyste', 'architecte', 'tester', 'reviewer', 'security', 'pentester']
776
776
  const canEdit = !readOnlyAgents.includes(agentType)
777
777
 
778
778
  const permissions: AgentPermissions = {
@@ -911,6 +911,122 @@ Called by the Reviewer agent after analyzing the code.`,
911
911
  }
912
912
  }),
913
913
 
914
+ /**
915
+ * Check pentest tools availability - for Pentester agent
916
+ */
917
+ mad_pentest_check_tools: tool({
918
+ description: `Check if pentest tools are installed on the system.
919
+ Verifies availability of: nuclei, httpx, katana, subfinder, sqlmap, nmap, curl, ffuf.
920
+ Returns which tools are available and what scan capabilities are possible.`,
921
+ args: {},
922
+ async execute(args, context) {
923
+ const tools = ['nuclei', 'httpx', 'katana', 'subfinder', 'sqlmap', 'nmap', 'curl', 'ffuf']
924
+ const available: string[] = []
925
+ const missing: string[] = []
926
+
927
+ for (const t of tools) {
928
+ const result = runCommand(`${t} --version`)
929
+ if (result.success) {
930
+ available.push(t)
931
+ } else {
932
+ // Try 'which' or 'where' as fallback
933
+ const whereResult = runCommand(process.platform === 'win32' ? `where ${t}` : `which ${t}`)
934
+ if (whereResult.success) {
935
+ available.push(t)
936
+ } else {
937
+ missing.push(t)
938
+ }
939
+ }
940
+ }
941
+
942
+ const canRunBasic = available.includes('curl') || available.includes('nmap')
943
+ const canRunDeep = available.includes('nuclei') || available.includes('httpx')
944
+ const canRunExploit = available.includes('sqlmap')
945
+
946
+ logEvent("info", "Pentest tools check", { available, missing })
947
+
948
+ return JSON.stringify({
949
+ available,
950
+ missing,
951
+ canRunBasic,
952
+ canRunDeep,
953
+ canRunExploit,
954
+ summary: `${available.length}/${tools.length} tools available`
955
+ }, null, 2)
956
+ }
957
+ }),
958
+
959
+ /**
960
+ * Record pentest scan results - for Pentester agent
961
+ */
962
+ mad_pentest_scan: tool({
963
+ description: `Record the results of a penetration test scan.
964
+ Called by the Pentester agent after running security scans on a target.`,
965
+ args: {
966
+ target: tool.schema.string().describe("Target URL or IP that was scanned"),
967
+ mode: tool.schema.enum(['basic', 'deep', 'exploit']).describe("Scan mode used"),
968
+ riskLevel: tool.schema.enum(['low', 'medium', 'high', 'critical']).describe("Overall risk level"),
969
+ summary: tool.schema.string().describe("Brief summary of findings"),
970
+ findings: tool.schema.array(tool.schema.object({
971
+ id: tool.schema.string(),
972
+ severity: tool.schema.enum(['info', 'low', 'medium', 'high', 'critical']),
973
+ type: tool.schema.string(),
974
+ title: tool.schema.string(),
975
+ description: tool.schema.string(),
976
+ evidence: tool.schema.string().optional(),
977
+ remediation: tool.schema.string().optional(),
978
+ })).optional().describe("List of vulnerabilities found"),
979
+ outputFormat: tool.schema.enum(['json', 'markdown']).optional().describe("Output format (default: json)"),
980
+ },
981
+ async execute(args, context) {
982
+ const { target, mode, riskLevel, summary, findings, outputFormat } = args
983
+ const gitRoot = getGitRoot()
984
+
985
+ const findingsCount = findings?.length || 0
986
+ const criticalCount = findings?.filter(f => f.severity === 'critical').length || 0
987
+ const highCount = findings?.filter(f => f.severity === 'high').length || 0
988
+
989
+ const scanResult = {
990
+ timestamp: new Date().toISOString(),
991
+ target,
992
+ mode,
993
+ riskLevel,
994
+ summary,
995
+ findings: findings || [],
996
+ stats: {
997
+ total: findingsCount,
998
+ critical: criticalCount,
999
+ high: highCount,
1000
+ medium: findings?.filter(f => f.severity === 'medium').length || 0,
1001
+ low: findings?.filter(f => f.severity === 'low').length || 0,
1002
+ info: findings?.filter(f => f.severity === 'info').length || 0,
1003
+ }
1004
+ }
1005
+
1006
+ // Save scan results
1007
+ const scanFile = join(gitRoot, `.pentest-scan-${Date.now()}.json`)
1008
+ writeFileSync(scanFile, JSON.stringify(scanResult, null, 2))
1009
+
1010
+ logEvent("info", "Pentest scan recorded", { target, mode, riskLevel, findingsCount })
1011
+
1012
+ if (outputFormat === 'markdown') {
1013
+ let md = `# Pentest Scan Report\n\n`
1014
+ md += `**Target:** ${target}\n`
1015
+ md += `**Mode:** ${mode}\n`
1016
+ md += `**Risk Level:** ${riskLevel}\n`
1017
+ md += `**Summary:** ${summary}\n\n`
1018
+ md += `## Statistics\n`
1019
+ md += `- Critical: ${criticalCount}\n`
1020
+ md += `- High: ${highCount}\n`
1021
+ md += `- Total: ${findingsCount}\n`
1022
+ return md
1023
+ }
1024
+
1025
+ const icon = riskLevel === 'critical' ? 'πŸ”΄' : riskLevel === 'high' ? '🟠' : riskLevel === 'medium' ? '🟑' : '🟒'
1026
+ return `${icon} Pentest: ${riskLevel} | ${findingsCount} findings (${criticalCount} critical, ${highCount} high)`
1027
+ }
1028
+ }),
1029
+
914
1030
  /**
915
1031
  * Security scan - for Security agent
916
1032
  */