souleyez 2.43.29__py3-none-any.whl → 2.43.32__py3-none-any.whl

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 (356) hide show
  1. souleyez/__init__.py +1 -2
  2. souleyez/ai/__init__.py +21 -15
  3. souleyez/ai/action_mapper.py +249 -150
  4. souleyez/ai/chain_advisor.py +116 -100
  5. souleyez/ai/claude_provider.py +29 -28
  6. souleyez/ai/context_builder.py +80 -62
  7. souleyez/ai/executor.py +158 -117
  8. souleyez/ai/feedback_handler.py +136 -121
  9. souleyez/ai/llm_factory.py +27 -20
  10. souleyez/ai/llm_provider.py +4 -2
  11. souleyez/ai/ollama_provider.py +6 -9
  12. souleyez/ai/ollama_service.py +44 -37
  13. souleyez/ai/path_scorer.py +91 -76
  14. souleyez/ai/recommender.py +176 -144
  15. souleyez/ai/report_context.py +74 -73
  16. souleyez/ai/report_service.py +84 -66
  17. souleyez/ai/result_parser.py +222 -229
  18. souleyez/ai/safety.py +67 -44
  19. souleyez/auth/__init__.py +23 -22
  20. souleyez/auth/audit.py +36 -26
  21. souleyez/auth/engagement_access.py +65 -48
  22. souleyez/auth/permissions.py +14 -3
  23. souleyez/auth/session_manager.py +54 -37
  24. souleyez/auth/user_manager.py +109 -64
  25. souleyez/commands/audit.py +40 -43
  26. souleyez/commands/auth.py +35 -15
  27. souleyez/commands/deliverables.py +55 -50
  28. souleyez/commands/engagement.py +47 -28
  29. souleyez/commands/license.py +32 -23
  30. souleyez/commands/screenshots.py +36 -32
  31. souleyez/commands/user.py +82 -36
  32. souleyez/config.py +52 -44
  33. souleyez/core/credential_tester.py +87 -81
  34. souleyez/core/cve_mappings.py +179 -192
  35. souleyez/core/cve_matcher.py +162 -148
  36. souleyez/core/msf_auto_mapper.py +100 -83
  37. souleyez/core/msf_chain_engine.py +294 -256
  38. souleyez/core/msf_database.py +153 -70
  39. souleyez/core/msf_integration.py +679 -673
  40. souleyez/core/msf_rpc_client.py +40 -42
  41. souleyez/core/msf_rpc_manager.py +77 -79
  42. souleyez/core/msf_sync_manager.py +241 -181
  43. souleyez/core/network_utils.py +22 -15
  44. souleyez/core/parser_handler.py +34 -25
  45. souleyez/core/pending_chains.py +114 -63
  46. souleyez/core/templates.py +158 -107
  47. souleyez/core/tool_chaining.py +9592 -2879
  48. souleyez/core/version_utils.py +79 -94
  49. souleyez/core/vuln_correlation.py +136 -89
  50. souleyez/core/web_utils.py +33 -32
  51. souleyez/data/wordlists/ad_users.txt +378 -0
  52. souleyez/data/wordlists/api_endpoints_large.txt +769 -0
  53. souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
  54. souleyez/data/wordlists/lfi_payloads.txt +82 -0
  55. souleyez/data/wordlists/passwords_brute.txt +1548 -0
  56. souleyez/data/wordlists/passwords_crack.txt +2479 -0
  57. souleyez/data/wordlists/passwords_spray.txt +386 -0
  58. souleyez/data/wordlists/subdomains_large.txt +5057 -0
  59. souleyez/data/wordlists/usernames_common.txt +694 -0
  60. souleyez/data/wordlists/web_dirs_large.txt +4769 -0
  61. souleyez/detection/__init__.py +1 -1
  62. souleyez/detection/attack_signatures.py +12 -17
  63. souleyez/detection/mitre_mappings.py +61 -55
  64. souleyez/detection/validator.py +97 -86
  65. souleyez/devtools.py +23 -10
  66. souleyez/docs/README.md +4 -4
  67. souleyez/docs/api-reference/cli-commands.md +2 -2
  68. souleyez/docs/developer-guide/adding-new-tools.md +562 -0
  69. souleyez/docs/user-guide/auto-chaining.md +30 -8
  70. souleyez/docs/user-guide/getting-started.md +1 -1
  71. souleyez/docs/user-guide/installation.md +26 -3
  72. souleyez/docs/user-guide/metasploit-integration.md +2 -2
  73. souleyez/docs/user-guide/rbac.md +1 -1
  74. souleyez/docs/user-guide/scope-management.md +1 -1
  75. souleyez/docs/user-guide/siem-integration.md +1 -1
  76. souleyez/docs/user-guide/tools-reference.md +1 -8
  77. souleyez/docs/user-guide/worker-management.md +1 -1
  78. souleyez/engine/background.py +1238 -535
  79. souleyez/engine/base.py +4 -1
  80. souleyez/engine/job_status.py +17 -49
  81. souleyez/engine/log_sanitizer.py +103 -77
  82. souleyez/engine/manager.py +38 -7
  83. souleyez/engine/result_handler.py +2198 -1550
  84. souleyez/engine/worker_manager.py +50 -41
  85. souleyez/export/evidence_bundle.py +72 -62
  86. souleyez/feature_flags/features.py +16 -20
  87. souleyez/feature_flags.py +5 -9
  88. souleyez/handlers/__init__.py +11 -0
  89. souleyez/handlers/base.py +188 -0
  90. souleyez/handlers/bash_handler.py +277 -0
  91. souleyez/handlers/bloodhound_handler.py +243 -0
  92. souleyez/handlers/certipy_handler.py +311 -0
  93. souleyez/handlers/crackmapexec_handler.py +486 -0
  94. souleyez/handlers/dnsrecon_handler.py +344 -0
  95. souleyez/handlers/enum4linux_handler.py +400 -0
  96. souleyez/handlers/evil_winrm_handler.py +493 -0
  97. souleyez/handlers/ffuf_handler.py +815 -0
  98. souleyez/handlers/gobuster_handler.py +1114 -0
  99. souleyez/handlers/gpp_extract_handler.py +334 -0
  100. souleyez/handlers/hashcat_handler.py +444 -0
  101. souleyez/handlers/hydra_handler.py +563 -0
  102. souleyez/handlers/impacket_getuserspns_handler.py +343 -0
  103. souleyez/handlers/impacket_psexec_handler.py +222 -0
  104. souleyez/handlers/impacket_secretsdump_handler.py +426 -0
  105. souleyez/handlers/john_handler.py +286 -0
  106. souleyez/handlers/katana_handler.py +425 -0
  107. souleyez/handlers/kerbrute_handler.py +298 -0
  108. souleyez/handlers/ldapsearch_handler.py +636 -0
  109. souleyez/handlers/lfi_extract_handler.py +464 -0
  110. souleyez/handlers/msf_auxiliary_handler.py +408 -0
  111. souleyez/handlers/msf_exploit_handler.py +380 -0
  112. souleyez/handlers/nikto_handler.py +413 -0
  113. souleyez/handlers/nmap_handler.py +821 -0
  114. souleyez/handlers/nuclei_handler.py +359 -0
  115. souleyez/handlers/nxc_handler.py +371 -0
  116. souleyez/handlers/rdp_sec_check_handler.py +353 -0
  117. souleyez/handlers/registry.py +288 -0
  118. souleyez/handlers/responder_handler.py +232 -0
  119. souleyez/handlers/service_explorer_handler.py +434 -0
  120. souleyez/handlers/smbclient_handler.py +344 -0
  121. souleyez/handlers/smbmap_handler.py +510 -0
  122. souleyez/handlers/smbpasswd_handler.py +296 -0
  123. souleyez/handlers/sqlmap_handler.py +1116 -0
  124. souleyez/handlers/theharvester_handler.py +601 -0
  125. souleyez/handlers/whois_handler.py +277 -0
  126. souleyez/handlers/wpscan_handler.py +554 -0
  127. souleyez/history.py +32 -16
  128. souleyez/importers/msf_importer.py +106 -75
  129. souleyez/importers/smart_importer.py +208 -147
  130. souleyez/integrations/siem/__init__.py +10 -10
  131. souleyez/integrations/siem/base.py +17 -18
  132. souleyez/integrations/siem/elastic.py +108 -122
  133. souleyez/integrations/siem/factory.py +207 -80
  134. souleyez/integrations/siem/googlesecops.py +146 -154
  135. souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
  136. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
  137. souleyez/integrations/siem/sentinel.py +107 -109
  138. souleyez/integrations/siem/splunk.py +246 -212
  139. souleyez/integrations/siem/wazuh.py +65 -71
  140. souleyez/integrations/wazuh/__init__.py +5 -5
  141. souleyez/integrations/wazuh/client.py +70 -93
  142. souleyez/integrations/wazuh/config.py +85 -57
  143. souleyez/integrations/wazuh/host_mapper.py +28 -36
  144. souleyez/integrations/wazuh/sync.py +78 -68
  145. souleyez/intelligence/__init__.py +4 -5
  146. souleyez/intelligence/correlation_analyzer.py +309 -295
  147. souleyez/intelligence/exploit_knowledge.py +661 -623
  148. souleyez/intelligence/exploit_suggestions.py +159 -139
  149. souleyez/intelligence/gap_analyzer.py +132 -97
  150. souleyez/intelligence/gap_detector.py +251 -214
  151. souleyez/intelligence/sensitive_tables.py +266 -129
  152. souleyez/intelligence/service_parser.py +137 -123
  153. souleyez/intelligence/surface_analyzer.py +407 -268
  154. souleyez/intelligence/target_parser.py +159 -162
  155. souleyez/licensing/__init__.py +6 -6
  156. souleyez/licensing/validator.py +17 -19
  157. souleyez/log_config.py +79 -54
  158. souleyez/main.py +1505 -687
  159. souleyez/migrations/fix_job_counter.py +16 -14
  160. souleyez/parsers/bloodhound_parser.py +41 -39
  161. souleyez/parsers/crackmapexec_parser.py +178 -111
  162. souleyez/parsers/dalfox_parser.py +72 -77
  163. souleyez/parsers/dnsrecon_parser.py +103 -91
  164. souleyez/parsers/enum4linux_parser.py +183 -153
  165. souleyez/parsers/ffuf_parser.py +29 -25
  166. souleyez/parsers/gobuster_parser.py +301 -41
  167. souleyez/parsers/hashcat_parser.py +324 -79
  168. souleyez/parsers/http_fingerprint_parser.py +350 -103
  169. souleyez/parsers/hydra_parser.py +131 -111
  170. souleyez/parsers/impacket_parser.py +231 -178
  171. souleyez/parsers/john_parser.py +98 -86
  172. souleyez/parsers/katana_parser.py +316 -0
  173. souleyez/parsers/msf_parser.py +943 -498
  174. souleyez/parsers/nikto_parser.py +346 -65
  175. souleyez/parsers/nmap_parser.py +262 -174
  176. souleyez/parsers/nuclei_parser.py +40 -44
  177. souleyez/parsers/responder_parser.py +26 -26
  178. souleyez/parsers/searchsploit_parser.py +74 -74
  179. souleyez/parsers/service_explorer_parser.py +279 -0
  180. souleyez/parsers/smbmap_parser.py +180 -124
  181. souleyez/parsers/sqlmap_parser.py +434 -308
  182. souleyez/parsers/theharvester_parser.py +75 -57
  183. souleyez/parsers/whois_parser.py +135 -94
  184. souleyez/parsers/wpscan_parser.py +278 -190
  185. souleyez/plugins/afp.py +44 -36
  186. souleyez/plugins/afp_brute.py +114 -46
  187. souleyez/plugins/ard.py +48 -37
  188. souleyez/plugins/bloodhound.py +95 -61
  189. souleyez/plugins/certipy.py +303 -0
  190. souleyez/plugins/crackmapexec.py +186 -85
  191. souleyez/plugins/dalfox.py +120 -59
  192. souleyez/plugins/dns_hijack.py +146 -41
  193. souleyez/plugins/dnsrecon.py +97 -61
  194. souleyez/plugins/enum4linux.py +91 -66
  195. souleyez/plugins/evil_winrm.py +291 -0
  196. souleyez/plugins/ffuf.py +166 -90
  197. souleyez/plugins/firmware_extract.py +133 -29
  198. souleyez/plugins/gobuster.py +387 -190
  199. souleyez/plugins/gpp_extract.py +393 -0
  200. souleyez/plugins/hashcat.py +100 -73
  201. souleyez/plugins/http_fingerprint.py +854 -267
  202. souleyez/plugins/hydra.py +566 -200
  203. souleyez/plugins/impacket_getnpusers.py +117 -69
  204. souleyez/plugins/impacket_psexec.py +84 -64
  205. souleyez/plugins/impacket_secretsdump.py +103 -69
  206. souleyez/plugins/impacket_smbclient.py +89 -75
  207. souleyez/plugins/john.py +86 -69
  208. souleyez/plugins/katana.py +313 -0
  209. souleyez/plugins/kerbrute.py +237 -0
  210. souleyez/plugins/lfi_extract.py +541 -0
  211. souleyez/plugins/macos_ssh.py +117 -48
  212. souleyez/plugins/mdns.py +35 -30
  213. souleyez/plugins/msf_auxiliary.py +253 -130
  214. souleyez/plugins/msf_exploit.py +239 -161
  215. souleyez/plugins/nikto.py +134 -78
  216. souleyez/plugins/nmap.py +275 -91
  217. souleyez/plugins/nuclei.py +180 -89
  218. souleyez/plugins/nxc.py +285 -0
  219. souleyez/plugins/plugin_base.py +35 -36
  220. souleyez/plugins/plugin_template.py +13 -5
  221. souleyez/plugins/rdp_sec_check.py +130 -0
  222. souleyez/plugins/responder.py +112 -71
  223. souleyez/plugins/router_http_brute.py +76 -65
  224. souleyez/plugins/router_ssh_brute.py +118 -41
  225. souleyez/plugins/router_telnet_brute.py +124 -42
  226. souleyez/plugins/routersploit.py +91 -59
  227. souleyez/plugins/routersploit_exploit.py +77 -55
  228. souleyez/plugins/searchsploit.py +91 -77
  229. souleyez/plugins/service_explorer.py +1160 -0
  230. souleyez/plugins/smbmap.py +122 -72
  231. souleyez/plugins/smbpasswd.py +215 -0
  232. souleyez/plugins/sqlmap.py +301 -113
  233. souleyez/plugins/theharvester.py +127 -75
  234. souleyez/plugins/tr069.py +79 -57
  235. souleyez/plugins/upnp.py +65 -47
  236. souleyez/plugins/upnp_abuse.py +73 -55
  237. souleyez/plugins/vnc_access.py +129 -42
  238. souleyez/plugins/vnc_brute.py +109 -38
  239. souleyez/plugins/whois.py +77 -58
  240. souleyez/plugins/wpscan.py +173 -69
  241. souleyez/reporting/__init__.py +2 -1
  242. souleyez/reporting/attack_chain.py +411 -346
  243. souleyez/reporting/charts.py +436 -501
  244. souleyez/reporting/compliance_mappings.py +334 -201
  245. souleyez/reporting/detection_report.py +126 -125
  246. souleyez/reporting/formatters.py +828 -591
  247. souleyez/reporting/generator.py +386 -302
  248. souleyez/reporting/metrics.py +72 -75
  249. souleyez/scanner.py +35 -29
  250. souleyez/security/__init__.py +37 -11
  251. souleyez/security/scope_validator.py +175 -106
  252. souleyez/security/validation.py +223 -149
  253. souleyez/security.py +22 -6
  254. souleyez/storage/credentials.py +247 -186
  255. souleyez/storage/crypto.py +296 -129
  256. souleyez/storage/database.py +73 -50
  257. souleyez/storage/db.py +58 -36
  258. souleyez/storage/deliverable_evidence.py +177 -128
  259. souleyez/storage/deliverable_exporter.py +282 -246
  260. souleyez/storage/deliverable_templates.py +134 -116
  261. souleyez/storage/deliverables.py +135 -130
  262. souleyez/storage/engagements.py +109 -56
  263. souleyez/storage/evidence.py +181 -152
  264. souleyez/storage/execution_log.py +31 -17
  265. souleyez/storage/exploit_attempts.py +93 -57
  266. souleyez/storage/exploits.py +67 -36
  267. souleyez/storage/findings.py +48 -61
  268. souleyez/storage/hosts.py +176 -144
  269. souleyez/storage/migrate_to_engagements.py +43 -19
  270. souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
  271. souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
  272. souleyez/storage/migrations/_003_add_execution_log.py +14 -8
  273. souleyez/storage/migrations/_005_screenshots.py +13 -5
  274. souleyez/storage/migrations/_006_deliverables.py +13 -5
  275. souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
  276. souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
  277. souleyez/storage/migrations/_010_evidence_linking.py +17 -10
  278. souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
  279. souleyez/storage/migrations/_012_team_collaboration.py +34 -21
  280. souleyez/storage/migrations/_013_add_host_tags.py +12 -6
  281. souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
  282. souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
  283. souleyez/storage/migrations/_016_add_domain_field.py +10 -4
  284. souleyez/storage/migrations/_017_msf_sessions.py +16 -8
  285. souleyez/storage/migrations/_018_add_osint_target.py +10 -6
  286. souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
  287. souleyez/storage/migrations/_020_add_rbac.py +36 -15
  288. souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
  289. souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
  290. souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
  291. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
  292. souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
  293. souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
  294. souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
  295. souleyez/storage/migrations/__init__.py +26 -26
  296. souleyez/storage/migrations/migration_manager.py +19 -19
  297. souleyez/storage/msf_sessions.py +100 -65
  298. souleyez/storage/osint.py +17 -24
  299. souleyez/storage/recommendation_engine.py +269 -235
  300. souleyez/storage/screenshots.py +33 -32
  301. souleyez/storage/smb_shares.py +136 -92
  302. souleyez/storage/sqlmap_data.py +183 -128
  303. souleyez/storage/team_collaboration.py +135 -141
  304. souleyez/storage/timeline_tracker.py +122 -94
  305. souleyez/storage/wazuh_vulns.py +64 -66
  306. souleyez/storage/web_paths.py +33 -37
  307. souleyez/testing/credential_tester.py +221 -205
  308. souleyez/ui/__init__.py +1 -1
  309. souleyez/ui/ai_quotes.py +12 -12
  310. souleyez/ui/attack_surface.py +2439 -1516
  311. souleyez/ui/chain_rules_view.py +914 -382
  312. souleyez/ui/correlation_view.py +312 -230
  313. souleyez/ui/dashboard.py +2382 -1130
  314. souleyez/ui/deliverables_view.py +148 -62
  315. souleyez/ui/design_system.py +13 -13
  316. souleyez/ui/errors.py +49 -49
  317. souleyez/ui/evidence_linking_view.py +284 -179
  318. souleyez/ui/evidence_vault.py +393 -285
  319. souleyez/ui/exploit_suggestions_view.py +555 -349
  320. souleyez/ui/export_view.py +100 -66
  321. souleyez/ui/gap_analysis_view.py +315 -171
  322. souleyez/ui/help_system.py +105 -97
  323. souleyez/ui/intelligence_view.py +436 -293
  324. souleyez/ui/interactive.py +22783 -10678
  325. souleyez/ui/interactive_selector.py +75 -68
  326. souleyez/ui/log_formatter.py +47 -39
  327. souleyez/ui/menu_components.py +22 -13
  328. souleyez/ui/msf_auxiliary_menu.py +184 -133
  329. souleyez/ui/pending_chains_view.py +336 -172
  330. souleyez/ui/progress_indicators.py +5 -3
  331. souleyez/ui/recommendations_view.py +195 -137
  332. souleyez/ui/rule_builder.py +343 -225
  333. souleyez/ui/setup_wizard.py +678 -284
  334. souleyez/ui/shortcuts.py +217 -165
  335. souleyez/ui/splunk_gap_analysis_view.py +452 -270
  336. souleyez/ui/splunk_vulns_view.py +139 -86
  337. souleyez/ui/team_dashboard.py +498 -335
  338. souleyez/ui/template_selector.py +196 -105
  339. souleyez/ui/terminal.py +6 -6
  340. souleyez/ui/timeline_view.py +198 -127
  341. souleyez/ui/tool_setup.py +264 -164
  342. souleyez/ui/tutorial.py +202 -72
  343. souleyez/ui/tutorial_state.py +40 -40
  344. souleyez/ui/wazuh_vulns_view.py +235 -141
  345. souleyez/ui/wordlist_browser.py +260 -107
  346. souleyez/ui.py +464 -312
  347. souleyez/utils/tool_checker.py +427 -367
  348. souleyez/utils.py +33 -29
  349. souleyez/wordlists.py +134 -167
  350. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/METADATA +1 -1
  351. souleyez-2.43.32.dist-info/RECORD +441 -0
  352. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/WHEEL +1 -1
  353. souleyez-2.43.29.dist-info/RECORD +0 -379
  354. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/entry_points.txt +0 -0
  355. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/licenses/LICENSE +0 -0
  356. {souleyez-2.43.29.dist-info → souleyez-2.43.32.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,10 @@
1
1
  """Deliverables dashboard view for interactive UI."""
2
+
2
3
  import click
3
4
  from rich.console import Console
4
5
  from rich.table import Table
5
6
  from rich.progress import Progress, BarColumn, TextColumn
7
+
6
8
  try:
7
9
  from rich.progress import TaskProgressColumn
8
10
  except ImportError:
@@ -32,98 +34,155 @@ def show_deliverables_dashboard(engagement_id):
32
34
  # Header
33
35
  width = DesignSystem.get_terminal_width()
34
36
  click.echo("\n┌" + "─" * (width - 2) + "┐")
35
- click.echo("│" + click.style(" DELIVERABLES & ACCEPTANCE CRITERIA ".center(width - 2), bold=True, fg='cyan') + "│")
37
+ click.echo(
38
+ "│"
39
+ + click.style(
40
+ " DELIVERABLES & ACCEPTANCE CRITERIA ".center(width - 2),
41
+ bold=True,
42
+ fg="cyan",
43
+ )
44
+ + "│"
45
+ )
36
46
  click.echo("└" + "─" * (width - 2) + "┘")
37
47
  click.echo()
38
48
 
39
49
  # Summary
40
50
  summary = dm.get_summary(engagement_id)
41
51
 
42
- if summary['total'] == 0:
52
+ if summary["total"] == 0:
43
53
  # Go directly to template selector when no deliverables exist
44
54
  from souleyez.ui.template_selector import show_template_selector
55
+
45
56
  loaded = show_template_selector(engagement_id)
46
57
  if loaded:
47
58
  continue # Reload deliverables view
48
59
  break # Back if cancelled
49
60
 
50
61
  click.echo(f" Engagement: {current['name']}")
51
- click.echo(f" Overall Progress: {summary['completed']}/{summary['total']} deliverables ({summary['completion_rate']*100:.0f}%)")
62
+ click.echo(
63
+ f" Overall Progress: {summary['completed']}/{summary['total']} deliverables ({summary['completion_rate']*100:.0f}%)"
64
+ )
52
65
  click.echo()
53
66
 
54
67
  # Progress bar
55
68
  bar_width = min(50, width - 30)
56
- completed = summary['completed']
57
- total = summary['total'] if summary['total'] > 0 else 1
69
+ completed = summary["completed"]
70
+ total = summary["total"] if summary["total"] > 0 else 1
58
71
  filled = int((completed / total) * bar_width)
59
72
  bar = "█" * filled + "░" * (bar_width - filled)
60
-
73
+
61
74
  click.echo(f" Progress: [{bar}] {completed}/{total}")
62
75
  click.echo()
63
76
 
64
77
  # Deliverables by category
65
78
  deliverables = dm.list_deliverables(engagement_id)
66
79
 
67
- categories = ['reconnaissance', 'enumeration', 'exploitation', 'post_exploitation', 'techniques']
80
+ categories = [
81
+ "reconnaissance",
82
+ "enumeration",
83
+ "exploitation",
84
+ "post_exploitation",
85
+ "techniques",
86
+ ]
68
87
 
69
88
  for category in categories:
70
- cat_deliverables = [d for d in deliverables if d['category'] == category]
89
+ cat_deliverables = [d for d in deliverables if d["category"] == category]
71
90
 
72
91
  if not cat_deliverables:
73
92
  continue
74
93
 
75
- click.echo(click.style(f"\n {category.upper().replace('_', ' ')}", bold=True, fg='cyan'))
94
+ click.echo(
95
+ click.style(
96
+ f"\n {category.upper().replace('_', ' ')}", bold=True, fg="cyan"
97
+ )
98
+ )
76
99
  click.echo(" " + "─" * (width - 4))
77
100
 
78
101
  for d in cat_deliverables:
79
102
  # Status icon
80
103
  status_icon = {
81
- 'completed': '',
82
- 'in_progress': '🔄',
83
- 'pending': '⚠️',
84
- 'failed': ''
85
- }.get(d['status'], '?')
104
+ "completed": "",
105
+ "in_progress": "🔄",
106
+ "pending": "⚠️",
107
+ "failed": "",
108
+ }.get(d["status"], "?")
86
109
 
87
110
  # Progress
88
- if d['target_type'] == 'count':
89
- current_val = d['current_value'] or 0
90
- target_val = d['target_value']
111
+ if d["target_type"] == "count":
112
+ current_val = d["current_value"] or 0
113
+ target_val = d["target_value"]
91
114
  progress_str = f"[{current_val}/{target_val}]"
92
- elif d['target_type'] == 'boolean':
93
- progress_str = "[✓]" if d['status'] == 'completed' else "[✗]"
115
+ elif d["target_type"] == "boolean":
116
+ progress_str = "[✓]" if d["status"] == "completed" else "[✗]"
94
117
  else:
95
118
  progress_str = "[Manual]"
96
119
 
97
120
  # Priority color
98
121
  priority_styles = {
99
- 'critical': 'red',
100
- 'high': 'yellow',
101
- 'medium': 'white',
102
- 'low': 'bright_black'
122
+ "critical": "red",
123
+ "high": "yellow",
124
+ "medium": "white",
125
+ "low": "bright_black",
103
126
  }
104
- priority_color = priority_styles.get(d['priority'], 'white')
127
+ priority_color = priority_styles.get(d["priority"], "white")
105
128
 
106
- title_line = f" {status_icon} [{d['id']}] {d['title']} {progress_str}"
107
- if d['priority'] in ['critical', 'high']:
129
+ title_line = (
130
+ f" {status_icon} [{d['id']}] {d['title']} {progress_str}"
131
+ )
132
+ if d["priority"] in ["critical", "high"]:
108
133
  title_line = click.style(title_line, fg=priority_color)
109
-
134
+
110
135
  click.echo(title_line)
111
136
 
112
- if d['description'] and d['status'] != 'completed':
113
- click.echo(click.style(f" {d['description']}", fg='bright_black'))
137
+ if d["description"] and d["status"] != "completed":
138
+ click.echo(
139
+ click.style(f" {d['description']}", fg="bright_black")
140
+ )
114
141
 
115
142
  # Menu with standardized numbered options
116
143
  from souleyez.ui.menu_components import StandardMenu
117
144
 
118
145
  options = [
119
- {'number': 1, 'label': 'Validate All Deliverables', 'description': 'Auto-validate all deliverables based on evidence'},
120
- {'number': 2, 'label': 'Mark as Complete', 'description': 'Mark specific deliverable as complete'},
121
- {'number': 3, 'label': 'Link Evidence', 'description': 'Associate evidence with deliverable'},
122
- {'number': 4, 'label': 'View Timeline', 'description': 'Display timeline and velocity metrics'},
123
- {'number': 5, 'label': 'Export Deliverables', 'description': 'Generate deliverables report'},
124
- {'number': 6, 'label': 'Smart Recommendations', 'description': 'View AI-powered recommendations'},
125
- {'number': 7, 'label': 'Team Collaboration', 'description': 'Manage team assignments and status'},
126
- {'number': 8, 'label': 'Refresh View', 'description': 'Reload deliverables data'},
146
+ {
147
+ "number": 1,
148
+ "label": "Validate All Deliverables",
149
+ "description": "Auto-validate all deliverables based on evidence",
150
+ },
151
+ {
152
+ "number": 2,
153
+ "label": "Mark as Complete",
154
+ "description": "Mark specific deliverable as complete",
155
+ },
156
+ {
157
+ "number": 3,
158
+ "label": "Link Evidence",
159
+ "description": "Associate evidence with deliverable",
160
+ },
161
+ {
162
+ "number": 4,
163
+ "label": "View Timeline",
164
+ "description": "Display timeline and velocity metrics",
165
+ },
166
+ {
167
+ "number": 5,
168
+ "label": "Export Deliverables",
169
+ "description": "Generate deliverables report",
170
+ },
171
+ {
172
+ "number": 6,
173
+ "label": "Smart Recommendations",
174
+ "description": "View AI-powered recommendations",
175
+ },
176
+ {
177
+ "number": 7,
178
+ "label": "Team Collaboration",
179
+ "description": "Manage team assignments and status",
180
+ },
181
+ {
182
+ "number": 8,
183
+ "label": "Refresh View",
184
+ "description": "Reload deliverables data",
185
+ },
127
186
  ]
128
187
 
129
188
  choice = StandardMenu.render(options)
@@ -133,9 +192,11 @@ def show_deliverables_dashboard(engagement_id):
133
192
  elif choice == 1:
134
193
  # Validate
135
194
  click.echo()
136
- click.echo(click.style(" Validating all deliverables...", fg='cyan'))
195
+ click.echo(click.style(" Validating all deliverables...", fg="cyan"))
137
196
  stats = dm.validate_all(engagement_id)
138
- click.echo(click.style(f" ✓ Updated {stats['updated']} deliverables", fg='green'))
197
+ click.echo(
198
+ click.style(f" ✓ Updated {stats['updated']} deliverables", fg="green")
199
+ )
139
200
  click.echo(f" Completed: {stats['completed']}")
140
201
  click.echo(f" In Progress: {stats['in_progress']}")
141
202
  click.pause()
@@ -144,49 +205,67 @@ def show_deliverables_dashboard(engagement_id):
144
205
  from souleyez.ui.interactive_selector import interactive_select
145
206
 
146
207
  # Get incomplete deliverables
147
- incomplete = [d for d in deliverables if d['status'] != 'completed']
208
+ incomplete = [d for d in deliverables if d["status"] != "completed"]
148
209
 
149
210
  if not incomplete:
150
- click.echo(click.style("\n All deliverables are already completed!", fg='green'))
211
+ click.echo(
212
+ click.style(
213
+ "\n All deliverables are already completed!", fg="green"
214
+ )
215
+ )
151
216
  click.pause()
152
217
  continue
153
218
 
154
219
  selected_ids = set()
155
220
  columns = [
156
- {'name': 'ID', 'width': 6, 'key': 'id', 'justify': 'right'},
157
- {'name': 'Category', 'width': 15, 'key': 'category'},
158
- {'name': 'Status', 'width': 12, 'key': 'status'},
159
- {'name': 'Priority', 'width': 10, 'key': 'priority'},
160
- {'name': 'Title', 'key': 'title'},
221
+ {"name": "ID", "width": 6, "key": "id", "justify": "right"},
222
+ {"name": "Category", "width": 15, "key": "category"},
223
+ {"name": "Status", "width": 12, "key": "status"},
224
+ {"name": "Priority", "width": 10, "key": "priority"},
225
+ {"name": "Title", "key": "title"},
161
226
  ]
162
227
 
163
228
  def format_deliverable_cell(item: dict, key: str) -> str:
164
229
  value = item.get(key)
165
230
  if value is None:
166
- return '-'
167
- if key == 'status':
168
- colors = {'pending': 'yellow', 'in_progress': 'cyan', 'failed': 'red'}
169
- color = colors.get(value, 'white')
170
- return f'[{color}]{value}[/{color}]'
171
- if key == 'priority':
172
- colors = {'critical': 'red', 'high': 'yellow', 'medium': 'white', 'low': 'dim'}
173
- color = colors.get(value, 'white')
174
- return f'[{color}]{value}[/{color}]'
175
- return str(value) if value else '-'
231
+ return "-"
232
+ if key == "status":
233
+ colors = {
234
+ "pending": "yellow",
235
+ "in_progress": "cyan",
236
+ "failed": "red",
237
+ }
238
+ color = colors.get(value, "white")
239
+ return f"[{color}]{value}[/{color}]"
240
+ if key == "priority":
241
+ colors = {
242
+ "critical": "red",
243
+ "high": "yellow",
244
+ "medium": "white",
245
+ "low": "dim",
246
+ }
247
+ color = colors.get(value, "white")
248
+ return f"[{color}]{value}[/{color}]"
249
+ return str(value) if value else "-"
176
250
 
177
251
  interactive_select(
178
252
  items=incomplete,
179
253
  columns=columns,
180
254
  selected_ids=selected_ids,
181
- get_id=lambda d: d.get('id'),
182
- title='SELECT DELIVERABLES TO MARK COMPLETE',
183
- format_cell=format_deliverable_cell
255
+ get_id=lambda d: d.get("id"),
256
+ title="SELECT DELIVERABLES TO MARK COMPLETE",
257
+ format_cell=format_deliverable_cell,
184
258
  )
185
259
 
186
260
  if selected_ids:
187
261
  for did in selected_ids:
188
262
  dm.mark_complete(did)
189
- click.echo(click.style(f"\n ✓ Marked {len(selected_ids)} deliverable(s) as completed", fg='green'))
263
+ click.echo(
264
+ click.style(
265
+ f"\n ✓ Marked {len(selected_ids)} deliverable(s) as completed",
266
+ fg="green",
267
+ )
268
+ )
190
269
  else:
191
270
  click.echo("\n No deliverables selected.")
192
271
  click.pause()
@@ -196,29 +275,36 @@ def show_deliverables_dashboard(engagement_id):
196
275
  deliverable = dm.get_deliverable(deliverable_id)
197
276
  if deliverable:
198
277
  from souleyez.ui.evidence_linking_view import show_evidence_linking_view
278
+
199
279
  show_evidence_linking_view(deliverable_id)
200
280
  else:
201
- click.echo(click.style(f" Deliverable {deliverable_id} not found", fg='red'))
281
+ click.echo(
282
+ click.style(f" Deliverable {deliverable_id} not found", fg="red")
283
+ )
202
284
  click.pause()
203
285
  elif choice == 4:
204
286
  # View timeline and velocity
205
287
  from souleyez.ui.timeline_view import show_timeline_view
288
+
206
289
  show_timeline_view(engagement_id)
207
290
  elif choice == 5:
208
291
  # Export deliverables
209
292
  from souleyez.ui.export_view import show_export_view
293
+
210
294
  show_export_view(engagement_id)
211
295
  elif choice == 6:
212
296
  # Smart recommendations
213
297
  from souleyez.ui.recommendations_view import show_recommendations_dashboard
298
+
214
299
  show_recommendations_dashboard(engagement_id)
215
300
  elif choice == 7:
216
301
  # Team collaboration
217
302
  from souleyez.ui.team_dashboard import show_team_dashboard
303
+
218
304
  show_team_dashboard(engagement_id)
219
305
  elif choice == 8:
220
306
  # Refresh
221
307
  continue
222
308
  else:
223
- click.echo(click.style(" Invalid choice", fg='yellow'))
309
+ click.echo(click.style(" Invalid choice", fg="yellow"))
224
310
  click.pause()
@@ -16,19 +16,19 @@ class DesignSystem:
16
16
  """Centralized design system for SoulEyez UI."""
17
17
 
18
18
  # Box Styles
19
- HEADER_BOX = box.DOUBLE # ╔═╗ - App header only
20
- TABLE_BOX = box.SIMPLE # ─── - All tables
19
+ HEADER_BOX = box.DOUBLE # ╔═╗ - App header only
20
+ TABLE_BOX = box.SIMPLE # ─── - All tables
21
21
 
22
22
  # Widths
23
- DEFAULT_WIDTH = 100 # Default terminal width
24
- MIN_WIDTH = 80 # Minimum supported width
23
+ DEFAULT_WIDTH = 100 # Default terminal width
24
+ MIN_WIDTH = 80 # Minimum supported width
25
25
 
26
26
  # Separators
27
- SECTION_SEP = "─" # Section separator character
27
+ SECTION_SEP = "─" # Section separator character
28
28
 
29
29
  # Spacing
30
- SECTION_SPACING = 2 # Blank lines between sections
31
- CONTENT_SPACING = 1 # Blank lines after separator
30
+ SECTION_SPACING = 2 # Blank lines between sections
31
+ CONTENT_SPACING = 1 # Blank lines after separator
32
32
 
33
33
  @staticmethod
34
34
  def get_terminal_width() -> int:
@@ -44,7 +44,7 @@ class DesignSystem:
44
44
  """Generate section separator line."""
45
45
  w = width or DesignSystem.get_terminal_width()
46
46
  return DesignSystem.SECTION_SEP * w
47
-
47
+
48
48
  @staticmethod
49
49
  def clear_screen():
50
50
  """
@@ -57,10 +57,10 @@ class DesignSystem:
57
57
  import sys
58
58
 
59
59
  # Use system clear command - most reliable across all terminals
60
- if os.name == 'posix':
61
- os.system('clear')
60
+ if os.name == "posix":
61
+ os.system("clear")
62
62
  else:
63
- os.system('cls')
63
+ os.system("cls")
64
64
 
65
65
  @staticmethod
66
66
  def create_table(expand: bool = True, **kwargs) -> Table:
@@ -80,7 +80,7 @@ class DesignSystem:
80
80
  padding=(0, 1),
81
81
  show_header=True,
82
82
  header_style="bold",
83
- **kwargs
83
+ **kwargs,
84
84
  )
85
85
 
86
86
  @staticmethod
@@ -100,7 +100,7 @@ class DesignSystem:
100
100
  lines = [
101
101
  f"{emoji} {title}",
102
102
  DesignSystem.SECTION_SEP * w,
103
- "" # Blank line after separator
103
+ "", # Blank line after separator
104
104
  ]
105
105
  return lines
106
106