zen-ai-pentest 2.1.0__tar.gz → 2.2.0__tar.gz

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 (134) hide show
  1. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/PKG-INFO +1 -1
  2. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/api/main.py +2 -2
  3. zen_ai_pentest-2.2.0/api/websocket_v2.py +181 -0
  4. zen_ai_pentest-2.2.0/modules/report_export.py +207 -0
  5. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/pyproject.toml +1 -1
  6. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/zen_ai_pentest.egg-info/PKG-INFO +1 -1
  7. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/zen_ai_pentest.egg-info/SOURCES.txt +2 -0
  8. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/CONTRIBUTING.md +0 -0
  9. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/CONTRIBUTORS.md +0 -0
  10. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/LICENSE +0 -0
  11. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/MANIFEST.in +0 -0
  12. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/README.md +0 -0
  13. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/__init__.py +0 -0
  14. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/agent_base.py +0 -0
  15. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/agent_orchestrator.py +0 -0
  16. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/analysis_agent.py +0 -0
  17. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/cli.py +0 -0
  18. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/exploit_agent.py +0 -0
  19. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/integration.py +0 -0
  20. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/post_scan_agent.py +0 -0
  21. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/react_agent.py +0 -0
  22. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/react_agent_enhanced.py +0 -0
  23. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/react_agent_vm.py +0 -0
  24. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/agents/research_agent.py +0 -0
  25. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/api/__init__.py +0 -0
  26. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/api/auth.py +0 -0
  27. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/api/schemas.py +0 -0
  28. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/api/websocket.py +0 -0
  29. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/autonomous/__init__.py +0 -0
  30. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/autonomous/agent.py +0 -0
  31. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/autonomous/agent_loop.py +0 -0
  32. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/autonomous/exploit_validator.py +0 -0
  33. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/autonomous/memory.py +0 -0
  34. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/autonomous/react.py +0 -0
  35. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/autonomous/tool_executor.py +0 -0
  36. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/backends/__init__.py +0 -0
  37. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/backends/chatgpt_direct.py +0 -0
  38. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/backends/claude_direct.py +0 -0
  39. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/backends/duckduckgo.py +0 -0
  40. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/backends/openrouter.py +0 -0
  41. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/benchmarks/__init__.py +0 -0
  42. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/benchmarks/benchmark_engine.py +0 -0
  43. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/benchmarks/ci_benchmark.py +0 -0
  44. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/benchmarks/comparison.py +0 -0
  45. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/benchmarks/metrics.py +0 -0
  46. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/benchmarks/run_benchmarks.py +0 -0
  47. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/ci_cd/__init__.py +0 -0
  48. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/__init__.py +0 -0
  49. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/async_pool.py +0 -0
  50. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/asyncio_fix.py +0 -0
  51. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/cache.py +0 -0
  52. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/container.py +0 -0
  53. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/database.py +0 -0
  54. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/input_validator.py +0 -0
  55. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/models.py +0 -0
  56. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/orchestrator.py +0 -0
  57. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/plugin_manager.py +0 -0
  58. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/rate_limiter.py +0 -0
  59. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/secure_config.py +0 -0
  60. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/core/shield_integration.py +0 -0
  61. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/.gitkeep +0 -0
  62. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/API.md +0 -0
  63. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/API_DOCUMENTATION.md +0 -0
  64. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/ATTACKERS_MINDSET_TTPs.md +0 -0
  65. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/BRANCH_PROTECTION.md +0 -0
  66. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/CI_CD_MONITORING.md +0 -0
  67. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/CONTAINER_INTEGRATION.md +0 -0
  68. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/DEPENDABOT.md +0 -0
  69. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/DOCKER_SETUP.md +0 -0
  70. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/GITHUB_SETUP.md +0 -0
  71. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/NOTIFICATIONS.md +0 -0
  72. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/OSINT_MODULE.md +0 -0
  73. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/PENTESTER_VS_ATTACKER_MINDSET.md +0 -0
  74. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/PLUGIN_SYSTEM.md +0 -0
  75. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/POSTMAN.md +0 -0
  76. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/POST_SCAN_AGENT.md +0 -0
  77. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/PROTONVPN_INTEGRATION.md +0 -0
  78. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/REACT_AGENT.md +0 -0
  79. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/README.md +0 -0
  80. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/REAL_LIFE_SCENARIOS.md +0 -0
  81. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/ROADMAP-2026.md +0 -0
  82. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/TOOLS_SUMMARY.md +0 -0
  83. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/VIRTUALIZATION_SUMMARY.md +0 -0
  84. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/WEBHOOK_SETUP.md +0 -0
  85. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/ZEN_SHIELD.md +0 -0
  86. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/_config.yml +0 -0
  87. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/adr/0001-record-architecture-decisions.md +0 -0
  88. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/adr/0002-multi-agent-architecture.md +0 -0
  89. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/adr/0003-llm-backend-routing.md +0 -0
  90. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/adr/0004-autonomous-agent-architecture.md +0 -0
  91. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/adr/0005-tool-execution-framework.md +0 -0
  92. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/adr/0006-risk-scoring-methodology.md +0 -0
  93. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/adr/README.md +0 -0
  94. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/api/autonomous.md +0 -0
  95. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/api/risk_engine.md +0 -0
  96. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/architecture.md +0 -0
  97. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/architecture.svg +0 -0
  98. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/index.html +0 -0
  99. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/index.md +0 -0
  100. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/research/FUNDAMENTAL_PENTEST_TOOLS.md +0 -0
  101. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/roadmap/2026/Q1_Q2_Q3_Q4_SUMMARY.md +0 -0
  102. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/setup/VIRTUALBOX_SETUP.md +0 -0
  103. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/docs/tutorials/getting-started.md +0 -0
  104. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/__init__.py +0 -0
  105. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/cve_database.py +0 -0
  106. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/exploit_assist.py +0 -0
  107. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/nuclei_integration.py +0 -0
  108. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/osint.py +0 -0
  109. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/protonvpn.py +0 -0
  110. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/recon.py +0 -0
  111. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/siem_integration.py +0 -0
  112. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/sql_injection_db.py +0 -0
  113. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/tool_orchestrator.py +0 -0
  114. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/vuln_scanner.py +0 -0
  115. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/modules/wordlist_generator.py +0 -0
  116. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/requirements.txt +0 -0
  117. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/risk_engine/__init__.py +0 -0
  118. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/risk_engine/business_impact.py +0 -0
  119. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/risk_engine/business_impact_calculator.py +0 -0
  120. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/risk_engine/cvss.py +0 -0
  121. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/risk_engine/epss.py +0 -0
  122. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/risk_engine/example_usage.py +0 -0
  123. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/risk_engine/false_positive_engine.py +0 -0
  124. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/risk_engine/scorer.py +0 -0
  125. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/setup.cfg +0 -0
  126. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/setup.py +0 -0
  127. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/templates/reports/executive_summary.md +0 -0
  128. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/templates/reports/technical_report.md +0 -0
  129. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/web_ui/backend/main.py +0 -0
  130. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/zen_ai_pentest.egg-info/dependency_links.txt +0 -0
  131. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/zen_ai_pentest.egg-info/entry_points.txt +0 -0
  132. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/zen_ai_pentest.egg-info/not-zip-safe +0 -0
  133. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/zen_ai_pentest.egg-info/requires.txt +0 -0
  134. {zen_ai_pentest-2.1.0 → zen_ai_pentest-2.2.0}/zen_ai_pentest.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zen-ai-pentest
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: Advanced AI-Powered Penetration Testing Framework with Multi-Agent Orchestration
5
5
  Home-page: https://github.com/SHAdd0WTAka/zen-ai-pentest
6
6
  Author: SHAdd0WTAka
@@ -60,7 +60,7 @@ async def lifespan(app: FastAPI):
60
60
  app = FastAPI(
61
61
  title="Zen-AI-Pentest API",
62
62
  description="Professional Pentesting Framework API",
63
- version="2.1.0",
63
+ version="2.2.0",
64
64
  lifespan=lifespan
65
65
  )
66
66
 
@@ -500,7 +500,7 @@ async def health_check():
500
500
  """Health check endpoint"""
501
501
  return {
502
502
  "status": "healthy",
503
- "version": "2.1.0",
503
+ "version": "2.2.0",
504
504
  "timestamp": datetime.utcnow().isoformat()
505
505
  }
506
506
 
@@ -0,0 +1,181 @@
1
+ """
2
+ WebSocket v2.0 - Real-time Updates
3
+ Q2 2026 Feature
4
+ """
5
+
6
+ import json
7
+ import logging
8
+ from typing import Dict, Set
9
+ from fastapi import WebSocket, WebSocketDisconnect
10
+ from datetime import datetime
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class ConnectionManagerV2:
16
+ """Advanced WebSocket connection manager with rooms"""
17
+
18
+ def __init__(self):
19
+ # Active connections by room
20
+ self.rooms: Dict[str, Set[WebSocket]] = {
21
+ "dashboard": set(),
22
+ "scans": set(),
23
+ "findings": set(),
24
+ "notifications": set()
25
+ }
26
+ # User connections
27
+ self.user_connections: Dict[str, WebSocket] = {}
28
+
29
+ async def connect(self, websocket: WebSocket, room: str = "dashboard", user_id: str = None):
30
+ """Connect client to room"""
31
+ await websocket.accept()
32
+
33
+ if room in self.rooms:
34
+ self.rooms[room].add(websocket)
35
+
36
+ if user_id:
37
+ self.user_connections[user_id] = websocket
38
+
39
+ logger.info(f"Client connected to room: {room}")
40
+
41
+ # Send welcome message
42
+ await websocket.send_json({
43
+ "type": "connection",
44
+ "status": "connected",
45
+ "room": room,
46
+ "timestamp": datetime.utcnow().isoformat()
47
+ })
48
+
49
+ def disconnect(self, websocket: WebSocket, room: str = None):
50
+ """Disconnect client"""
51
+ if room and room in self.rooms:
52
+ self.rooms[room].discard(websocket)
53
+ else:
54
+ # Remove from all rooms
55
+ for room_set in self.rooms.values():
56
+ room_set.discard(websocket)
57
+
58
+ # Remove from user connections
59
+ for user_id, conn in list(self.user_connections.items()):
60
+ if conn == websocket:
61
+ del self.user_connections[user_id]
62
+
63
+ logger.info("Client disconnected")
64
+
65
+ async def broadcast_to_room(self, room: str, message: dict):
66
+ """Broadcast message to all clients in room"""
67
+ if room not in self.rooms:
68
+ return
69
+
70
+ disconnected = set()
71
+ for connection in self.rooms[room]:
72
+ try:
73
+ await connection.send_json(message)
74
+ except Exception:
75
+ disconnected.add(connection)
76
+
77
+ # Clean up disconnected clients
78
+ for conn in disconnected:
79
+ self.rooms[room].discard(conn)
80
+
81
+ async def send_to_user(self, user_id: str, message: dict):
82
+ """Send message to specific user"""
83
+ if user_id in self.user_connections:
84
+ try:
85
+ await self.user_connections[user_id].send_json(message)
86
+ except Exception:
87
+ del self.user_connections[user_id]
88
+
89
+ async def broadcast_scan_update(self, scan_id: str, status: str, progress: int = None):
90
+ """Broadcast scan progress update"""
91
+ await self.broadcast_to_room("scans", {
92
+ "type": "scan_update",
93
+ "scan_id": scan_id,
94
+ "status": status,
95
+ "progress": progress,
96
+ "timestamp": datetime.utcnow().isoformat()
97
+ })
98
+
99
+ async def broadcast_finding(self, finding: dict):
100
+ """Broadcast new finding discovery"""
101
+ await self.broadcast_to_room("findings", {
102
+ "type": "new_finding",
103
+ "finding": finding,
104
+ "timestamp": datetime.utcnow().isoformat()
105
+ })
106
+
107
+ async def broadcast_notification(self, title: str, message: str, severity: str = "info"):
108
+ """Broadcast system notification"""
109
+ await self.broadcast_to_room("notifications", {
110
+ "type": "notification",
111
+ "title": title,
112
+ "message": message,
113
+ "severity": severity,
114
+ "timestamp": datetime.utcnow().isoformat()
115
+ })
116
+
117
+ def get_room_stats(self) -> dict:
118
+ """Get connection statistics"""
119
+ return {
120
+ room: len(connections)
121
+ for room, connections in self.rooms.items()
122
+ }
123
+
124
+
125
+ # Global manager instance
126
+ manager_v2 = ConnectionManagerV2()
127
+
128
+
129
+ async def websocket_dashboard_endpoint(websocket: WebSocket):
130
+ """Dashboard real-time updates"""
131
+ await manager_v2.connect(websocket, room="dashboard")
132
+ try:
133
+ while True:
134
+ # Receive ping from client
135
+ data = await websocket.receive_text()
136
+ message = json.loads(data)
137
+
138
+ if message.get("action") == "ping":
139
+ await websocket.send_json({
140
+ "type": "pong",
141
+ "timestamp": datetime.utcnow().isoformat()
142
+ })
143
+
144
+ except WebSocketDisconnect:
145
+ manager_v2.disconnect(websocket, room="dashboard")
146
+
147
+
148
+ async def websocket_scans_endpoint(websocket: WebSocket):
149
+ """Scan progress real-time updates"""
150
+ await manager_v2.connect(websocket, room="scans")
151
+ try:
152
+ while True:
153
+ data = await websocket.receive_text()
154
+ # Handle scan subscription requests
155
+ message = json.loads(data)
156
+
157
+ if message.get("action") == "subscribe_scan":
158
+ scan_id = message.get("scan_id")
159
+ await websocket.send_json({
160
+ "type": "subscribed",
161
+ "scan_id": scan_id,
162
+ "message": f"Subscribed to scan {scan_id} updates"
163
+ })
164
+
165
+ except WebSocketDisconnect:
166
+ manager_v2.disconnect(websocket, room="scans")
167
+
168
+
169
+ async def websocket_notifications_endpoint(websocket: WebSocket, user_id: str = None):
170
+ """User-specific notifications"""
171
+ await manager_v2.connect(websocket, room="notifications", user_id=user_id)
172
+ try:
173
+ while True:
174
+ data = await websocket.receive_text()
175
+ # Acknowledge receipt
176
+ await websocket.send_json({
177
+ "type": "ack",
178
+ "received": True
179
+ })
180
+ except WebSocketDisconnect:
181
+ manager_v2.disconnect(websocket, room="notifications")
@@ -0,0 +1,207 @@
1
+ """
2
+ Report Export Module
3
+ Q2 2026 - PDF & CSV Export
4
+ """
5
+
6
+ import csv
7
+ import io
8
+ import logging
9
+ from datetime import datetime
10
+ from typing import List, Dict, Any
11
+ from dataclasses import dataclass
12
+
13
+ try:
14
+ from weasyprint import HTML, CSS
15
+ WEASYPRINT_AVAILABLE = True
16
+ except ImportError:
17
+ WEASYPRINT_AVAILABLE = False
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ @dataclass
23
+ class ReportData:
24
+ """Report data structure"""
25
+ title: str
26
+ scan_date: datetime
27
+ target: str
28
+ findings: List[Dict[str, Any]]
29
+ summary: Dict[str, int]
30
+ recommendations: List[str]
31
+
32
+
33
+ class ReportExporter:
34
+ """Export reports to various formats"""
35
+
36
+ def __init__(self):
37
+ self.templates = {
38
+ "executive": self._executive_template,
39
+ "technical": self._technical_template,
40
+ "compliance": self._compliance_template
41
+ }
42
+
43
+ def export_csv(self, findings: List[Dict], filename: str = None) -> bytes:
44
+ """Export findings to CSV"""
45
+ if not filename:
46
+ filename = f"findings_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
47
+
48
+ output = io.StringIO()
49
+ writer = csv.writer(output)
50
+
51
+ # Header
52
+ writer.writerow([
53
+ "ID", "Severity", "Title", "Description", "Target",
54
+ "CVE", "CVSS", "Status", "Discovered"
55
+ ])
56
+
57
+ # Data
58
+ for finding in findings:
59
+ writer.writerow([
60
+ finding.get("id", ""),
61
+ finding.get("severity", ""),
62
+ finding.get("title", ""),
63
+ finding.get("description", ""),
64
+ finding.get("target", ""),
65
+ finding.get("cve_id", ""),
66
+ finding.get("cvss_score", ""),
67
+ finding.get("status", "open"),
68
+ finding.get("discovered_at", "")
69
+ ])
70
+
71
+ return output.getvalue().encode('utf-8')
72
+
73
+ def export_pdf(self, report: ReportData, template: str = "executive") -> bytes:
74
+ """Export report to PDF"""
75
+ if not WEASYPRINT_AVAILABLE:
76
+ logger.error("WeasyPrint not available. Install: pip install weasyprint")
77
+ raise RuntimeError("PDF generation requires WeasyPrint")
78
+
79
+ html_content = self.templates.get(template, self._executive_template)(report)
80
+
81
+ pdf = HTML(string=html_content).write_pdf()
82
+ return pdf
83
+
84
+ def _executive_template(self, report: ReportData) -> str:
85
+ """Executive summary template"""
86
+ findings_html = ""
87
+ for f in report.findings[:10]: # Top 10
88
+ severity_color = {
89
+ "critical": "#dc2626",
90
+ "high": "#ea580c",
91
+ "medium": "#ca8a04",
92
+ "low": "#16a34a"
93
+ }.get(f.get("severity", "low"), "#6b7280")
94
+
95
+ findings_html += f"""
96
+ <div style="margin: 10px 0; padding: 10px; border-left: 4px solid {severity_color}; background: #f9fafb;">
97
+ <strong>{f.get('title', 'Unknown')}</strong>
98
+ <span style="color: {severity_color}; text-transform: uppercase; font-size: 0.8em;">
99
+ {f.get('severity', 'unknown')}
100
+ </span>
101
+ <p style="margin: 5px 0; color: #4b5563;">{f.get('description', '')[:200]}...</p>
102
+ </div>
103
+ """
104
+
105
+ return f"""
106
+ <!DOCTYPE html>
107
+ <html>
108
+ <head>
109
+ <meta charset="UTF-8">
110
+ <title>{report.title}</title>
111
+ <style>
112
+ body {{ font-family: Arial, sans-serif; margin: 40px; }}
113
+ h1 {{ color: #111827; border-bottom: 2px solid #059669; padding-bottom: 10px; }}
114
+ .summary {{ background: #f3f4f6; padding: 20px; border-radius: 8px; margin: 20px 0; }}
115
+ .metric {{ display: inline-block; margin: 10px 20px; }}
116
+ .metric-value {{ font-size: 2em; font-weight: bold; color: #059669; }}
117
+ .metric-label {{ color: #6b7280; font-size: 0.9em; }}
118
+ .findings {{ margin-top: 30px; }}
119
+ </style>
120
+ </head>
121
+ <body>
122
+ <h1>{report.title}</h1>
123
+ <p><strong>Target:</strong> {report.target}</p>
124
+ <p><strong>Scan Date:</strong> {report.scan_date.strftime('%Y-%m-%d %H:%M')}</p>
125
+
126
+ <div class="summary">
127
+ <h2>Summary</h2>
128
+ <div class="metric">
129
+ <div class="metric-value">{report.summary.get('critical', 0)}</div>
130
+ <div class="metric-label">Critical</div>
131
+ </div>
132
+ <div class="metric">
133
+ <div class="metric-value">{report.summary.get('high', 0)}</div>
134
+ <div class="metric-label">High</div>
135
+ </div>
136
+ <div class="metric">
137
+ <div class="metric-value">{report.summary.get('medium', 0)}</div>
138
+ <div class="metric-label">Medium</div>
139
+ </div>
140
+ <div class="metric">
141
+ <div class="metric-value">{report.summary.get('low', 0)}</div>
142
+ <div class="metric-label">Low</div>
143
+ </div>
144
+ </div>
145
+
146
+ <div class="findings">
147
+ <h2>Top Findings</h2>
148
+ {findings_html}
149
+ </div>
150
+
151
+ <div style="margin-top: 40px; padding-top: 20px; border-top: 1px solid #e5e7eb; color: #6b7280; font-size: 0.9em;">
152
+ <p>Generated by Zen AI Pentest v2.1.0</p>
153
+ <p>Confidential - For authorized eyes only</p>
154
+ </div>
155
+ </body>
156
+ </html>
157
+ """
158
+
159
+ def _technical_template(self, report: ReportData) -> str:
160
+ """Technical detailed template"""
161
+ # Similar to executive but with more technical details
162
+ return self._executive_template(report) # Simplified for now
163
+
164
+ def _compliance_template(self, report: ReportData) -> str:
165
+ """Compliance-focused template"""
166
+ # For compliance reporting (PCI-DSS, GDPR, etc.)
167
+ return self._executive_template(report) # Simplified for now
168
+
169
+ def export_json(self, findings: List[Dict]) -> str:
170
+ """Export findings to JSON"""
171
+ import json
172
+ return json.dumps(findings, indent=2)
173
+
174
+ def get_export_formats(self) -> List[str]:
175
+ """List available export formats"""
176
+ formats = ["csv", "json"]
177
+ if WEASYPRINT_AVAILABLE:
178
+ formats.append("pdf")
179
+ return formats
180
+
181
+
182
+ # Convenience function
183
+ def export_findings(findings: List[Dict], format: str = "csv") -> bytes:
184
+ """Quick export function"""
185
+ exporter = ReportExporter()
186
+
187
+ if format == "csv":
188
+ return exporter.export_csv(findings)
189
+ elif format == "json":
190
+ return exporter.export_json(findings).encode('utf-8')
191
+ elif format == "pdf":
192
+ report = ReportData(
193
+ title="Security Assessment Report",
194
+ scan_date=datetime.now(),
195
+ target="Multiple Targets",
196
+ findings=findings,
197
+ summary={
198
+ "critical": len([f for f in findings if f.get("severity") == "critical"]),
199
+ "high": len([f for f in findings if f.get("severity") == "high"]),
200
+ "medium": len([f for f in findings if f.get("severity") == "medium"]),
201
+ "low": len([f for f in findings if f.get("severity") == "low"])
202
+ },
203
+ recommendations=[]
204
+ )
205
+ return exporter.export_pdf(report)
206
+ else:
207
+ raise ValueError(f"Unsupported format: {format}")
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "zen-ai-pentest"
7
- version = "2.1.0"
7
+ version = "2.2.0"
8
8
  description = "Advanced AI-Powered Penetration Testing Framework with Multi-Agent Orchestration"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zen-ai-pentest
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: Advanced AI-Powered Penetration Testing Framework with Multi-Agent Orchestration
5
5
  Home-page: https://github.com/SHAdd0WTAka/zen-ai-pentest
6
6
  Author: SHAdd0WTAka
@@ -23,6 +23,7 @@ api/auth.py
23
23
  api/main.py
24
24
  api/schemas.py
25
25
  api/websocket.py
26
+ api/websocket_v2.py
26
27
  autonomous/__init__.py
27
28
  autonomous/agent.py
28
29
  autonomous/agent_loop.py
@@ -105,6 +106,7 @@ modules/nuclei_integration.py
105
106
  modules/osint.py
106
107
  modules/protonvpn.py
107
108
  modules/recon.py
109
+ modules/report_export.py
108
110
  modules/siem_integration.py
109
111
  modules/sql_injection_db.py
110
112
  modules/tool_orchestrator.py
File without changes
File without changes
File without changes
File without changes