souleyez 3.0.0__py3-none-any.whl → 3.0.9__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.

Potentially problematic release.


This version of souleyez might be problematic. Click here for more details.

Files changed (325) hide show
  1. souleyez/__init__.py +1 -1
  2. souleyez/ai/__init__.py +7 -7
  3. souleyez/ai/action_mapper.py +3 -2
  4. souleyez/ai/chain_advisor.py +2 -1
  5. souleyez/ai/claude_provider.py +2 -2
  6. souleyez/ai/context_builder.py +4 -2
  7. souleyez/ai/executor.py +9 -6
  8. souleyez/ai/feedback_handler.py +4 -2
  9. souleyez/ai/llm_provider.py +2 -2
  10. souleyez/ai/ollama_provider.py +2 -2
  11. souleyez/ai/ollama_service.py +10 -26
  12. souleyez/ai/path_scorer.py +2 -1
  13. souleyez/ai/recommender.py +6 -4
  14. souleyez/ai/report_context.py +2 -2
  15. souleyez/ai/report_service.py +5 -5
  16. souleyez/ai/result_parser.py +3 -2
  17. souleyez/ai/safety.py +5 -2
  18. souleyez/auth/__init__.py +6 -6
  19. souleyez/auth/audit.py +2 -2
  20. souleyez/auth/engagement_access.py +5 -7
  21. souleyez/auth/permissions.py +1 -1
  22. souleyez/auth/session_manager.py +5 -5
  23. souleyez/auth/user_manager.py +4 -5
  24. souleyez/commands/audit.py +6 -5
  25. souleyez/commands/auth.py +6 -5
  26. souleyez/commands/deliverables.py +2 -3
  27. souleyez/commands/engagement.py +3 -3
  28. souleyez/commands/license.py +3 -2
  29. souleyez/commands/screenshots.py +5 -4
  30. souleyez/commands/user.py +10 -8
  31. souleyez/config.py +4 -2
  32. souleyez/core/credential_tester.py +4 -2
  33. souleyez/core/cve_mappings.py +2 -1
  34. souleyez/core/cve_matcher.py +2 -1
  35. souleyez/core/msf_auto_mapper.py +2 -0
  36. souleyez/core/msf_chain_engine.py +3 -1
  37. souleyez/core/msf_database.py +7 -13
  38. souleyez/core/msf_integration.py +2 -2
  39. souleyez/core/msf_rpc_client.py +3 -2
  40. souleyez/core/msf_rpc_manager.py +4 -4
  41. souleyez/core/msf_sync_manager.py +7 -7
  42. souleyez/core/network_utils.py +1 -1
  43. souleyez/core/parser_handler.py +2 -1
  44. souleyez/core/pending_chains.py +4 -3
  45. souleyez/core/templates.py +5 -2
  46. souleyez/core/tool_chaining.py +101 -70
  47. souleyez/core/version_utils.py +1 -0
  48. souleyez/core/vuln_correlation.py +3 -2
  49. souleyez/core/web_utils.py +2 -1
  50. souleyez/detection/__init__.py +1 -1
  51. souleyez/detection/attack_signatures.py +1 -1
  52. souleyez/detection/mitre_mappings.py +1 -2
  53. souleyez/detection/validator.py +5 -4
  54. souleyez/devtools.py +4 -2
  55. souleyez/docs/README.md +2 -2
  56. souleyez/engine/background.py +168 -7
  57. souleyez/engine/base.py +2 -1
  58. souleyez/engine/loader.py +4 -2
  59. souleyez/engine/log_sanitizer.py +1 -0
  60. souleyez/engine/manager.py +3 -1
  61. souleyez/engine/result_handler.py +50 -67
  62. souleyez/engine/worker_manager.py +6 -4
  63. souleyez/export/evidence_bundle.py +1 -0
  64. souleyez/handlers/base.py +1 -0
  65. souleyez/handlers/bash_handler.py +1 -0
  66. souleyez/handlers/bloodhound_handler.py +1 -0
  67. souleyez/handlers/certipy_handler.py +1 -0
  68. souleyez/handlers/crackmapexec_handler.py +2 -20
  69. souleyez/handlers/dnsrecon_handler.py +2 -1
  70. souleyez/handlers/enum4linux_handler.py +65 -37
  71. souleyez/handlers/evil_winrm_handler.py +1 -0
  72. souleyez/handlers/ffuf_handler.py +3 -1
  73. souleyez/handlers/gobuster_handler.py +7 -6
  74. souleyez/handlers/gpp_extract_handler.py +1 -0
  75. souleyez/handlers/hashcat_handler.py +1 -0
  76. souleyez/handlers/hydra_handler.py +5 -2
  77. souleyez/handlers/impacket_getuserspns_handler.py +1 -0
  78. souleyez/handlers/impacket_psexec_handler.py +1 -0
  79. souleyez/handlers/impacket_secretsdump_handler.py +1 -0
  80. souleyez/handlers/john_handler.py +1 -0
  81. souleyez/handlers/katana_handler.py +39 -2
  82. souleyez/handlers/kerbrute_handler.py +1 -0
  83. souleyez/handlers/ldapsearch_handler.py +90 -17
  84. souleyez/handlers/lfi_extract_handler.py +1 -0
  85. souleyez/handlers/msf_auxiliary_handler.py +1 -0
  86. souleyez/handlers/msf_exploit_handler.py +1 -0
  87. souleyez/handlers/nikto_handler.py +2 -1
  88. souleyez/handlers/nmap_handler.py +2 -1
  89. souleyez/handlers/nuclei_handler.py +2 -1
  90. souleyez/handlers/nxc_handler.py +3 -18
  91. souleyez/handlers/rdp_sec_check_handler.py +1 -0
  92. souleyez/handlers/registry.py +1 -0
  93. souleyez/handlers/responder_handler.py +1 -0
  94. souleyez/handlers/service_explorer_handler.py +2 -1
  95. souleyez/handlers/smbclient_handler.py +1 -0
  96. souleyez/handlers/smbmap_handler.py +3 -2
  97. souleyez/handlers/sqlmap_handler.py +6 -4
  98. souleyez/handlers/theharvester_handler.py +2 -1
  99. souleyez/handlers/web_login_test_handler.py +1 -0
  100. souleyez/handlers/whois_handler.py +3 -2
  101. souleyez/handlers/wpscan_handler.py +2 -1
  102. souleyez/history.py +4 -3
  103. souleyez/importers/msf_importer.py +5 -3
  104. souleyez/importers/smart_importer.py +6 -4
  105. souleyez/integrations/siem/__init__.py +6 -6
  106. souleyez/integrations/siem/base.py +1 -1
  107. souleyez/integrations/siem/elastic.py +3 -3
  108. souleyez/integrations/siem/factory.py +1 -2
  109. souleyez/integrations/siem/googlesecops.py +4 -4
  110. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +1 -1
  111. souleyez/integrations/siem/sentinel.py +3 -3
  112. souleyez/integrations/siem/splunk.py +3 -3
  113. souleyez/integrations/siem/wazuh.py +4 -4
  114. souleyez/integrations/wazuh/__init__.py +1 -1
  115. souleyez/integrations/wazuh/client.py +3 -2
  116. souleyez/integrations/wazuh/config.py +3 -2
  117. souleyez/integrations/wazuh/host_mapper.py +3 -1
  118. souleyez/integrations/wazuh/sync.py +4 -1
  119. souleyez/intelligence/__init__.py +1 -1
  120. souleyez/intelligence/correlation_analyzer.py +6 -5
  121. souleyez/intelligence/exploit_knowledge.py +4 -4
  122. souleyez/intelligence/exploit_suggestions.py +4 -3
  123. souleyez/intelligence/gap_analyzer.py +5 -3
  124. souleyez/intelligence/gap_detector.py +2 -0
  125. souleyez/intelligence/sensitive_tables.py +1 -1
  126. souleyez/intelligence/service_parser.py +1 -0
  127. souleyez/intelligence/surface_analyzer.py +9 -9
  128. souleyez/intelligence/target_parser.py +1 -0
  129. souleyez/licensing/__init__.py +3 -3
  130. souleyez/main.py +25 -18
  131. souleyez/migrations/fix_job_counter.py +2 -1
  132. souleyez/parsers/bloodhound_parser.py +1 -0
  133. souleyez/parsers/crackmapexec_parser.py +2 -1
  134. souleyez/parsers/dalfox_parser.py +3 -2
  135. souleyez/parsers/dnsrecon_parser.py +2 -1
  136. souleyez/parsers/enum4linux_parser.py +2 -1
  137. souleyez/parsers/ffuf_parser.py +2 -1
  138. souleyez/parsers/gobuster_parser.py +2 -1
  139. souleyez/parsers/hashcat_parser.py +3 -2
  140. souleyez/parsers/http_fingerprint_parser.py +2 -1
  141. souleyez/parsers/hydra_parser.py +2 -1
  142. souleyez/parsers/impacket_parser.py +2 -1
  143. souleyez/parsers/john_parser.py +4 -3
  144. souleyez/parsers/katana_parser.py +134 -2
  145. souleyez/parsers/msf_parser.py +2 -1
  146. souleyez/parsers/nikto_parser.py +2 -1
  147. souleyez/parsers/nmap_parser.py +14 -3
  148. souleyez/parsers/nuclei_parser.py +3 -2
  149. souleyez/parsers/responder_parser.py +1 -0
  150. souleyez/parsers/searchsploit_parser.py +3 -2
  151. souleyez/parsers/service_explorer_parser.py +1 -0
  152. souleyez/parsers/smbmap_parser.py +2 -1
  153. souleyez/parsers/sqlmap_parser.py +36 -2
  154. souleyez/parsers/theharvester_parser.py +2 -1
  155. souleyez/parsers/whois_parser.py +2 -1
  156. souleyez/parsers/wpscan_parser.py +3 -2
  157. souleyez/plugins/afp.py +3 -1
  158. souleyez/plugins/afp_brute.py +3 -1
  159. souleyez/plugins/ard.py +3 -1
  160. souleyez/plugins/bloodhound.py +3 -2
  161. souleyez/plugins/certipy.py +1 -0
  162. souleyez/plugins/crackmapexec.py +11 -7
  163. souleyez/plugins/dalfox.py +5 -2
  164. souleyez/plugins/dns_hijack.py +3 -1
  165. souleyez/plugins/dnsrecon.py +3 -1
  166. souleyez/plugins/enum4linux.py +3 -1
  167. souleyez/plugins/evil_winrm.py +1 -0
  168. souleyez/plugins/ffuf.py +3 -1
  169. souleyez/plugins/firmware_extract.py +3 -2
  170. souleyez/plugins/gobuster.py +6 -3
  171. souleyez/plugins/gpp_extract.py +1 -0
  172. souleyez/plugins/hashcat.py +2 -1
  173. souleyez/plugins/http_fingerprint.py +57 -7
  174. souleyez/plugins/hydra.py +5 -3
  175. souleyez/plugins/impacket_common.py +40 -0
  176. souleyez/plugins/impacket_getnpusers.py +19 -2
  177. souleyez/plugins/impacket_getuserspns.py +158 -0
  178. souleyez/plugins/impacket_psexec.py +19 -2
  179. souleyez/plugins/impacket_secretsdump.py +19 -2
  180. souleyez/plugins/impacket_smbclient.py +19 -2
  181. souleyez/plugins/john.py +2 -1
  182. souleyez/plugins/katana.py +48 -6
  183. souleyez/plugins/kerbrute.py +1 -0
  184. souleyez/plugins/lfi_extract.py +1 -0
  185. souleyez/plugins/macos_ssh.py +3 -1
  186. souleyez/plugins/mdns.py +3 -1
  187. souleyez/plugins/msf_auxiliary.py +3 -2
  188. souleyez/plugins/msf_exploit.py +6 -5
  189. souleyez/plugins/nikto.py +5 -2
  190. souleyez/plugins/nmap.py +6 -4
  191. souleyez/plugins/nuclei.py +3 -1
  192. souleyez/plugins/nxc.py +1 -0
  193. souleyez/plugins/plugin_base.py +3 -2
  194. souleyez/plugins/plugin_template.py +3 -2
  195. souleyez/plugins/rdp_sec_check.py +1 -0
  196. souleyez/plugins/responder.py +2 -1
  197. souleyez/plugins/router_http_brute.py +3 -1
  198. souleyez/plugins/router_ssh_brute.py +3 -1
  199. souleyez/plugins/router_telnet_brute.py +3 -1
  200. souleyez/plugins/routersploit.py +5 -3
  201. souleyez/plugins/routersploit_exploit.py +5 -3
  202. souleyez/plugins/searchsploit.py +1 -0
  203. souleyez/plugins/service_explorer.py +2 -1
  204. souleyez/plugins/smbmap.py +3 -1
  205. souleyez/plugins/smbpasswd.py +1 -0
  206. souleyez/plugins/sqlmap.py +3 -1
  207. souleyez/plugins/theharvester.py +3 -1
  208. souleyez/plugins/tr069.py +3 -1
  209. souleyez/plugins/upnp.py +3 -1
  210. souleyez/plugins/upnp_abuse.py +4 -2
  211. souleyez/plugins/vnc_access.py +4 -2
  212. souleyez/plugins/vnc_brute.py +3 -1
  213. souleyez/plugins/web_login_test.py +1 -0
  214. souleyez/plugins/whois.py +3 -1
  215. souleyez/plugins/wpscan.py +3 -1
  216. souleyez/reporting/attack_chain.py +2 -1
  217. souleyez/reporting/charts.py +1 -0
  218. souleyez/reporting/compliance_mappings.py +1 -0
  219. souleyez/reporting/detection_report.py +10 -10
  220. souleyez/reporting/formatters.py +7 -12
  221. souleyez/reporting/generator.py +34 -46
  222. souleyez/reporting/metrics.py +2 -1
  223. souleyez/scanner.py +6 -3
  224. souleyez/security/__init__.py +7 -5
  225. souleyez/security/scope_validator.py +5 -4
  226. souleyez/security.py +5 -2
  227. souleyez/storage/credentials.py +14 -19
  228. souleyez/storage/crypto.py +7 -4
  229. souleyez/storage/database.py +6 -6
  230. souleyez/storage/db.py +8 -8
  231. souleyez/storage/deliverable_evidence.py +2 -1
  232. souleyez/storage/deliverable_exporter.py +3 -2
  233. souleyez/storage/deliverable_templates.py +2 -1
  234. souleyez/storage/deliverables.py +2 -1
  235. souleyez/storage/engagements.py +6 -4
  236. souleyez/storage/evidence.py +5 -4
  237. souleyez/storage/execution_log.py +4 -2
  238. souleyez/storage/exploit_attempts.py +3 -2
  239. souleyez/storage/exploits.py +3 -1
  240. souleyez/storage/findings.py +3 -1
  241. souleyez/storage/hosts.py +5 -2
  242. souleyez/storage/migrate_to_engagements.py +14 -24
  243. souleyez/storage/migrations/_001_add_credential_enhancements.py +12 -21
  244. souleyez/storage/migrations/_003_add_execution_log.py +8 -13
  245. souleyez/storage/migrations/_005_screenshots.py +2 -4
  246. souleyez/storage/migrations/_006_deliverables.py +2 -4
  247. souleyez/storage/migrations/_007_deliverable_templates.py +4 -8
  248. souleyez/storage/migrations/_008_add_nuclei_table.py +2 -4
  249. souleyez/storage/migrations/_010_evidence_linking.py +6 -12
  250. souleyez/storage/migrations/_012_team_collaboration.py +12 -24
  251. souleyez/storage/migrations/_013_add_host_tags.py +2 -4
  252. souleyez/storage/migrations/_014_exploit_attempts.py +10 -20
  253. souleyez/storage/migrations/_015_add_mac_os_fields.py +4 -8
  254. souleyez/storage/migrations/_016_add_domain_field.py +2 -4
  255. souleyez/storage/migrations/_017_msf_sessions.py +8 -16
  256. souleyez/storage/migrations/_018_add_osint_target.py +4 -8
  257. souleyez/storage/migrations/_019_add_engagement_type.py +4 -8
  258. souleyez/storage/migrations/_020_add_rbac.py +9 -17
  259. souleyez/storage/migrations/_021_wazuh_integration.py +4 -8
  260. souleyez/storage/migrations/_023_fix_detection_results_fk.py +2 -4
  261. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +4 -8
  262. souleyez/storage/migrations/_026_add_engagement_scope.py +4 -8
  263. souleyez/storage/migrations/_027_multi_siem_persistence.py +8 -16
  264. souleyez/storage/migrations/__init__.py +1 -4
  265. souleyez/storage/migrations/migration_manager.py +6 -9
  266. souleyez/storage/msf_sessions.py +1 -1
  267. souleyez/storage/osint.py +3 -1
  268. souleyez/storage/recommendation_engine.py +3 -2
  269. souleyez/storage/screenshots.py +2 -1
  270. souleyez/storage/smb_shares.py +3 -1
  271. souleyez/storage/sqlmap_data.py +6 -4
  272. souleyez/storage/team_collaboration.py +3 -2
  273. souleyez/storage/timeline_tracker.py +2 -1
  274. souleyez/storage/wazuh_vulns.py +3 -1
  275. souleyez/storage/web_paths.py +3 -1
  276. souleyez/testing/credential_tester.py +2 -0
  277. souleyez/ui/__init__.py +2 -1
  278. souleyez/ui/ai_quotes.py +1 -1
  279. souleyez/ui/attack_surface.py +50 -28
  280. souleyez/ui/chain_rules_view.py +6 -3
  281. souleyez/ui/correlation_view.py +3 -2
  282. souleyez/ui/dashboard.py +85 -139
  283. souleyez/ui/deliverables_view.py +1 -1
  284. souleyez/ui/design_system.py +5 -3
  285. souleyez/ui/errors.py +3 -1
  286. souleyez/ui/evidence_linking_view.py +2 -1
  287. souleyez/ui/evidence_vault.py +11 -6
  288. souleyez/ui/exploit_suggestions_view.py +11 -7
  289. souleyez/ui/export_view.py +3 -1
  290. souleyez/ui/gap_analysis_view.py +6 -3
  291. souleyez/ui/help_system.py +4 -1
  292. souleyez/ui/intelligence_view.py +7 -3
  293. souleyez/ui/interactive.py +1280 -558
  294. souleyez/ui/interactive_selector.py +3 -2
  295. souleyez/ui/log_formatter.py +1 -0
  296. souleyez/ui/menu_components.py +3 -1
  297. souleyez/ui/msf_auxiliary_menu.py +4 -1
  298. souleyez/ui/pending_chains_view.py +15 -12
  299. souleyez/ui/progress_indicators.py +5 -2
  300. souleyez/ui/recommendations_view.py +4 -2
  301. souleyez/ui/rule_builder.py +4 -1
  302. souleyez/ui/setup_wizard.py +10 -8
  303. souleyez/ui/shortcuts.py +1 -1
  304. souleyez/ui/splunk_gap_analysis_view.py +7 -4
  305. souleyez/ui/splunk_vulns_view.py +4 -1
  306. souleyez/ui/team_dashboard.py +7 -5
  307. souleyez/ui/template_selector.py +2 -1
  308. souleyez/ui/terminal.py +3 -2
  309. souleyez/ui/timeline_view.py +2 -1
  310. souleyez/ui/tool_setup.py +92 -31
  311. souleyez/ui/tutorial.py +7 -4
  312. souleyez/ui/tutorial_state.py +3 -2
  313. souleyez/ui/wazuh_vulns_view.py +5 -2
  314. souleyez/ui/wordlist_browser.py +4 -3
  315. souleyez/ui.py +13 -7
  316. souleyez/utils/tool_checker.py +95 -17
  317. souleyez/utils.py +4 -4
  318. souleyez/wordlists.py +1 -0
  319. {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/METADATA +1 -1
  320. souleyez-3.0.9.dist-info/RECORD +445 -0
  321. souleyez-3.0.0.dist-info/RECORD +0 -443
  322. {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/WHEEL +0 -0
  323. {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/entry_points.txt +0 -0
  324. {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/licenses/LICENSE +0 -0
  325. {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/top_level.txt +0 -0
souleyez/ui/dashboard.py CHANGED
@@ -2,29 +2,30 @@
2
2
  """
3
3
  souleyez.ui.dashboard - Live dashboard with real-time updates
4
4
  """
5
- import click
6
- from souleyez.config import read_config, write_config
7
- import time
8
- import os
9
- import wcwidth
5
+
10
6
  import getpass
7
+ import os
8
+ import time
11
9
  from datetime import datetime
12
- from typing import Optional
13
10
  from enum import Enum
11
+ from io import StringIO
12
+ from typing import Optional
14
13
 
15
- from souleyez.engine.background import list_jobs, get_job
16
- from souleyez.storage.engagements import EngagementManager
17
- from souleyez.storage.hosts import HostManager
18
- from souleyez.storage.findings import FindingsManager
19
- from souleyez.storage.credentials import CredentialsManager
20
- from souleyez.storage.evidence import EvidenceManager
21
- from souleyez.ui.log_formatter import format_log_stream
22
- from souleyez.ui.design_system import DesignSystem
23
- from souleyez.ui.tutorial_state import get_tutorial_state, TutorialStep
14
+ import click
15
+ import wcwidth
24
16
  from rich.console import Console
25
17
  from rich.table import Table
26
- from io import StringIO
27
18
 
19
+ from souleyez.config import read_config, write_config
20
+ from souleyez.engine.background import get_job, list_jobs
21
+ from souleyez.storage.credentials import CredentialsManager
22
+ from souleyez.storage.engagements import EngagementManager
23
+ from souleyez.storage.evidence import EvidenceManager
24
+ from souleyez.storage.findings import FindingsManager
25
+ from souleyez.storage.hosts import HostManager
26
+ from souleyez.ui.design_system import DesignSystem
27
+ from souleyez.ui.log_formatter import format_log_stream
28
+ from souleyez.ui.tutorial_state import TutorialStep, get_tutorial_state
28
29
 
29
30
  # Header cache to avoid expensive recalculations on every refresh
30
31
  # Format: {key: (timestamp, value)}
@@ -502,11 +503,11 @@ def render_engagement_summary(engagement_id: int, width: int) -> list:
502
503
  Render compact engagement summary - single section with key metrics.
503
504
  6 lines total for maximum clarity.
504
505
  """
505
- from souleyez.storage.hosts import HostManager
506
- from souleyez.storage.findings import FindingsManager
506
+ from souleyez.engine.background import list_jobs
507
507
  from souleyez.storage.credentials import CredentialsManager
508
508
  from souleyez.storage.deliverables import DeliverableManager
509
- from souleyez.engine.background import list_jobs
509
+ from souleyez.storage.findings import FindingsManager
510
+ from souleyez.storage.hosts import HostManager
510
511
 
511
512
  lines = []
512
513
  lines.extend(DesignSystem.section_header("📊", "ENGAGEMENT SUMMARY"))
@@ -1286,8 +1287,8 @@ def render_intelligence_summary(
1286
1287
  )
1287
1288
  else:
1288
1289
  try:
1289
- from souleyez.integrations.wazuh.config import WazuhConfig
1290
1290
  from souleyez.integrations.siem import SIEMFactory
1291
+ from souleyez.integrations.wazuh.config import WazuhConfig
1291
1292
 
1292
1293
  config = WazuhConfig.get_config(engagement_id)
1293
1294
 
@@ -1396,8 +1397,8 @@ def render_intelligence_summary(
1396
1397
  )
1397
1398
  else:
1398
1399
  try:
1399
- from souleyez.ai.ollama_provider import OllamaProvider
1400
1400
  from souleyez.ai.claude_provider import ClaudeProvider
1401
+ from souleyez.ai.ollama_provider import OllamaProvider
1401
1402
 
1402
1403
  config = read_config()
1403
1404
  current_provider = config.get("ai", {}).get("provider", "ollama")
@@ -1616,12 +1617,12 @@ def render_new_tool_metrics(engagement_id: int, width: int):
1616
1617
 
1617
1618
  # Get data (cached to avoid lag)
1618
1619
  def _get_tool_metrics_data():
1619
- from souleyez.storage.hosts import HostManager
1620
+ from souleyez.engine.background import list_jobs
1620
1621
  from souleyez.storage.findings import FindingsManager
1622
+ from souleyez.storage.hosts import HostManager
1621
1623
  from souleyez.storage.osint import OsintManager
1622
1624
  from souleyez.storage.smb_shares import SMBSharesManager
1623
1625
  from souleyez.storage.web_paths import WebPathsManager
1624
- from souleyez.engine.background import list_jobs
1625
1626
 
1626
1627
  hm = HostManager()
1627
1628
  fm = FindingsManager()
@@ -2053,8 +2054,8 @@ def _quick_toggle_ai_provider():
2053
2054
 
2054
2055
  def _execute_ai_recommendation(engagement_id: int):
2055
2056
  """Execute AI recommendation from dashboard."""
2056
- from souleyez.ai.recommender import AttackRecommender
2057
2057
  from souleyez.ai.executor import InteractiveExecutor
2058
+ from souleyez.ai.recommender import AttackRecommender
2058
2059
  from souleyez.ai.safety import ApprovalMode
2059
2060
  from souleyez.ui.progress_indicators import with_ai_quotes
2060
2061
 
@@ -2067,8 +2068,8 @@ def _execute_ai_recommendation(engagement_id: int):
2067
2068
 
2068
2069
  # Check available providers
2069
2070
  try:
2070
- from souleyez.ai.ollama_provider import OllamaProvider
2071
2071
  from souleyez.ai.claude_provider import ClaudeProvider
2072
+ from souleyez.ai.ollama_provider import OllamaProvider
2072
2073
 
2073
2074
  ollama = OllamaProvider()
2074
2075
  claude = ClaudeProvider()
@@ -2452,10 +2453,11 @@ def render_recent_findings(engagement_id: int, width: int):
2452
2453
 
2453
2454
  def render_endpoints_and_redirects(engagement_id: int, width: int):
2454
2455
  """Render recent endpoints and HTTP redirects with suspicious path highlighting."""
2455
- from souleyez.storage.web_paths import WebPathsManager
2456
+ from urllib.parse import urlparse
2457
+
2456
2458
  from souleyez.storage.hosts import HostManager
2457
2459
  from souleyez.storage.osint import OsintManager
2458
- from urllib.parse import urlparse
2460
+ from souleyez.storage.web_paths import WebPathsManager
2459
2461
 
2460
2462
  wpm = WebPathsManager()
2461
2463
  hm = HostManager()
@@ -3731,8 +3733,8 @@ def run_dashboard(follow_job_id: Optional[int] = None, refresh_interval: int = 1
3731
3733
 
3732
3734
  def _toggle_auto_chaining():
3733
3735
  """Toggle auto-chaining on/off with improved feedback."""
3734
- from souleyez.core.tool_chaining import ToolChaining
3735
3736
  from souleyez.auth import is_pro
3737
+ from souleyez.core.tool_chaining import ToolChaining
3736
3738
  from souleyez.ui.interactive import _show_upgrade_prompt
3737
3739
 
3738
3740
  if not is_pro():
@@ -4162,7 +4164,7 @@ def _view_security_guide():
4162
4164
 
4163
4165
  def _show_help_menu():
4164
4166
  """Show help menu with available guides."""
4165
- from souleyez.ui.help_system import show_help, HelpContext
4167
+ from souleyez.ui.help_system import HelpContext, show_help
4166
4168
 
4167
4169
  show_help(HelpContext.DASHBOARD)
4168
4170
 
@@ -4217,8 +4219,8 @@ def _show_toggle_menu(state: "DashboardState"):
4217
4219
 
4218
4220
  def _wait_for_input(timeout: int) -> Optional[str]:
4219
4221
  """Wait for keyboard input with timeout. Returns input or None."""
4220
- import sys
4221
4222
  import select
4223
+ import sys
4222
4224
 
4223
4225
  try:
4224
4226
  # Check if input is available (Unix-like systems)
@@ -4277,7 +4279,7 @@ def _show_dashboard_menu(engagement_id: int) -> str:
4277
4279
  click.echo(" " + "─" * 76)
4278
4280
 
4279
4281
  # Check user tier for Pro features
4280
- from souleyez.auth import get_current_user, Tier
4282
+ from souleyez.auth import Tier, get_current_user
4281
4283
 
4282
4284
  current_user = get_current_user()
4283
4285
  is_pro_user = current_user and current_user.tier == Tier.PRO
@@ -4293,8 +4295,6 @@ def _show_dashboard_menu(engagement_id: int) -> str:
4293
4295
  click.echo(
4294
4296
  " "
4295
4297
  + click.style("[i]", fg="bright_magenta", bold=True)
4296
- + " or "
4297
- + click.style("[1]", fg="bright_magenta")
4298
4298
  + " 🎯 Intelligence Hub "
4299
4299
  + pro_badge
4300
4300
  + " - Attack surface & correlation"
@@ -4303,9 +4303,7 @@ def _show_dashboard_menu(engagement_id: int) -> str:
4303
4303
  # Show all Pro features with appropriate badge
4304
4304
  click.echo(
4305
4305
  " "
4306
- + click.style("[x]", fg="bright_magenta", bold=True)
4307
- + " or "
4308
- + click.style("[2]", fg="bright_magenta")
4306
+ + click.style("[e]", fg="bright_magenta", bold=True)
4309
4307
  + " 🤖 AI Execute "
4310
4308
  + pro_badge
4311
4309
  + " - AI-driven autonomous execution"
@@ -4313,8 +4311,6 @@ def _show_dashboard_menu(engagement_id: int) -> str:
4313
4311
  click.echo(
4314
4312
  " "
4315
4313
  + click.style("[a]", fg="bright_magenta", bold=True)
4316
- + " or "
4317
- + click.style("[3]", fg="bright_magenta")
4318
4314
  + " 🔗 Automation "
4319
4315
  + pro_badge
4320
4316
  + " - Chain rules & settings"
@@ -4322,132 +4318,100 @@ def _show_dashboard_menu(engagement_id: int) -> str:
4322
4318
  click.echo(
4323
4319
  " "
4324
4320
  + click.style("[m]", fg="bright_magenta", bold=True)
4325
- + " or "
4326
- + click.style("[4]", fg="bright_magenta")
4327
4321
  + " 🔧 Metasploit "
4328
4322
  + pro_badge
4329
4323
  + " - Generate exploits, launch msfconsole"
4330
4324
  )
4331
4325
  click.echo()
4332
4326
 
4333
- # Documentation section
4334
- click.echo(click.style(" 📋 DOCUMENTATION", bold=True, fg="yellow"))
4335
- click.echo(" " + "─" * 76)
4336
- click.echo(
4337
- " "
4338
- + click.style("[e]", fg="yellow", bold=True)
4339
- + " or "
4340
- + click.style("[5]", fg="yellow")
4341
- + " 📦 Evidence & Artifacts - Screenshots, files, exports"
4342
- )
4343
- click.echo(
4344
- " "
4345
- + click.style("[d]", fg="yellow", bold=True)
4346
- + " or "
4347
- + click.style("[6]", fg="yellow")
4348
- + " ✅ Deliverables - Progress tracking, checklists"
4349
- )
4350
-
4351
- # Reports - Pro feature (show to all with appropriate badge)
4352
- pro_badge_yellow = (
4353
- click.style("💎", fg="yellow")
4354
- if is_pro_user
4355
- else click.style("🔒 PRO", fg="yellow")
4356
- )
4357
- click.echo(
4358
- " "
4359
- + click.style("[r]", fg="yellow", bold=True)
4360
- + " or "
4361
- + click.style("[7]", fg="yellow")
4362
- + " 📄 Reports "
4363
- + pro_badge_yellow
4364
- + " - Generate & export reports"
4365
- )
4366
- click.echo()
4367
-
4368
4327
  # Data Management section
4369
- click.echo(
4370
- click.style(" 📊 DATA MANAGEMENT (Deep Dive)", bold=True, fg="green")
4371
- )
4328
+ click.echo(click.style(" 📊 DATA MANAGEMENT", bold=True, fg="cyan"))
4372
4329
  click.echo(" " + "─" * 76)
4373
4330
  click.echo(
4374
4331
  " "
4375
4332
  + click.style("[h]", fg="cyan", bold=True)
4376
- + " or "
4377
- + click.style("[8]", fg="cyan")
4378
- + " 🎯 Hosts - Discovered hosts, tags, filtering"
4333
+ + " 🎯 Hosts - Discovered hosts, tags, filtering"
4379
4334
  )
4380
4335
  click.echo(
4381
4336
  " "
4382
4337
  + click.style("[s]", fg="cyan", bold=True)
4383
- + " or "
4384
- + click.style("[9]", fg="cyan")
4385
- + " 🔌 Services - Open ports, service enumeration"
4338
+ + " 🔌 Services - Open ports, service enumeration"
4386
4339
  )
4387
4340
  click.echo(
4388
4341
  " "
4389
4342
  + click.style("[f]", fg="cyan", bold=True)
4390
- + " or "
4391
- + click.style("[10]", fg="cyan")
4392
4343
  + " 🔍 Findings - All vulnerabilities (detailed view)"
4393
4344
  )
4394
4345
  click.echo(
4395
4346
  " "
4396
4347
  + click.style("[c]", fg="cyan", bold=True)
4397
- + " or "
4398
- + click.style("[11]", fg="cyan")
4399
4348
  + " 🔑 Credentials - Discovered users, passwords, hashes"
4400
4349
  )
4401
4350
  click.echo()
4402
4351
  click.echo(
4403
4352
  " "
4404
- + click.style("[b]", fg="cyan", bold=True)
4405
- + " or "
4406
- + click.style("[12]", fg="cyan")
4353
+ + click.style("[w]", fg="cyan", bold=True)
4407
4354
  + " 🌐 Web Paths - Directory enumeration results"
4408
4355
  )
4409
4356
  click.echo(
4410
4357
  " "
4411
- + click.style("[n]", fg="cyan", bold=True)
4412
- + " or "
4413
- + click.style("[13]", fg="cyan")
4358
+ + click.style("[b]", fg="cyan", bold=True)
4414
4359
  + " 📁 SMB Shares - SMB enumeration, accessible shares"
4415
4360
  )
4416
4361
  click.echo(
4417
4362
  " "
4418
4363
  + click.style("[l]", fg="cyan", bold=True)
4419
- + " or "
4420
- + click.style("[14]", fg="cyan")
4421
- + " 💉 SQLMap Intelligence - Deduplicated injections, high-value tables"
4364
+ + " 💉 SQLMap - SQL injection discoveries"
4422
4365
  )
4423
4366
  click.echo(
4424
4367
  " "
4425
4368
  + click.style("[p]", fg="cyan", bold=True)
4426
- + " or "
4427
- + click.style("[15]", fg="cyan")
4428
- + " 🔌 WordPress Data - WPScan vulnerabilities"
4369
+ + " 🔌 WordPress - WPScan vulnerabilities"
4370
+ )
4371
+ click.echo(
4372
+ " "
4373
+ + click.style("[x]", fg="cyan", bold=True)
4374
+ + " 💣 Exploits - SearchSploit exploit database"
4429
4375
  )
4430
4376
  click.echo(
4431
4377
  " "
4432
4378
  + click.style("[o]", fg="cyan", bold=True)
4433
- + " or "
4434
- + click.style("[16]", fg="cyan")
4435
- + " 💣 Exploits - SearchSploit exploit database"
4379
+ + " 🔍 OSINT - DNS, WHOIS, emails, infrastructure"
4380
+ )
4381
+ click.echo()
4382
+
4383
+ # Documentation section
4384
+ click.echo(click.style(" 📋 DOCUMENTATION", bold=True, fg="yellow"))
4385
+ click.echo(" " + "─" * 76)
4386
+ click.echo(
4387
+ " "
4388
+ + click.style("[v]", fg="yellow", bold=True)
4389
+ + " 📦 Evidence Vault - Screenshots, files, exports"
4436
4390
  )
4437
4391
  click.echo(
4438
4392
  " "
4439
- + click.style("[t]", fg="cyan", bold=True)
4440
- + " or "
4441
- + click.style("[17]", fg="cyan")
4442
- + " 🔍 OSINT/Discovery - DNS, WHOIS, emails, infrastructure"
4393
+ + click.style("[d]", fg="yellow", bold=True)
4394
+ + " Deliverables - Progress tracking, checklists"
4395
+ )
4396
+
4397
+ # Reports - Pro feature (show to all with appropriate badge)
4398
+ pro_badge_yellow = (
4399
+ click.style("💎", fg="yellow")
4400
+ if is_pro_user
4401
+ else click.style("🔒 PRO", fg="yellow")
4402
+ )
4403
+ click.echo(
4404
+ " "
4405
+ + click.style("[g]", fg="yellow", bold=True)
4406
+ + " 📄 Generate Reports "
4407
+ + pro_badge_yellow
4408
+ + " - Generate & export reports"
4443
4409
  )
4444
4410
  click.echo()
4445
4411
 
4446
4412
  click.echo(
4447
4413
  " "
4448
4414
  + click.style("[q]", fg="red", bold=True)
4449
- + " or "
4450
- + click.style("[18]", fg="red")
4451
4415
  + " ← Return to Command Center"
4452
4416
  )
4453
4417
  click.echo()
@@ -4459,49 +4423,30 @@ def _show_dashboard_menu(engagement_id: int) -> str:
4459
4423
  try:
4460
4424
  choice = input().strip().lower()
4461
4425
 
4462
- # Map both letters and numbers
4426
+ # Map letters to actions
4463
4427
  choice_map = {
4464
- # Intelligence & Actions (4 items: 1-4)
4428
+ # Intelligence & Actions
4465
4429
  "i": "intelligence_hub",
4466
- "1": "intelligence_hub",
4467
- "x": "ai_execute",
4468
- "2": "ai_execute",
4430
+ "e": "ai_execute",
4469
4431
  "a": "automation",
4470
- "3": "automation",
4471
4432
  "m": "msf",
4472
- "4": "msf",
4473
- # Documentation (3 items: 5-7)
4474
- "e": "evidence",
4475
- "5": "evidence",
4433
+ # Documentation
4434
+ "v": "evidence",
4476
4435
  "d": "deliverables",
4477
- "6": "deliverables",
4478
- "r": "reports",
4479
- "7": "reports",
4480
- # Data Management (10 items: 8-17)
4436
+ "g": "reports",
4437
+ # Data Management
4481
4438
  "h": "hosts",
4482
- "8": "hosts",
4483
4439
  "s": "services",
4484
- "9": "services",
4485
4440
  "f": "findings",
4486
- "10": "findings",
4487
4441
  "c": "credentials",
4488
- "11": "credentials",
4489
- "b": "web_paths",
4490
- "12": "web_paths",
4491
- "n": "smb_shares",
4492
- "13": "smb_shares",
4442
+ "w": "web_paths",
4443
+ "b": "smb_shares",
4493
4444
  "l": "sqlmap",
4494
- "14": "sqlmap",
4495
4445
  "p": "wordpress",
4496
- "15": "wordpress",
4497
- "o": "exploits_db",
4498
- "16": "exploits_db",
4499
- "t": "osint",
4500
- "17": "osint",
4446
+ "x": "exploits_db",
4447
+ "o": "osint",
4501
4448
  # Exit
4502
4449
  "q": "quit",
4503
- "18": "quit",
4504
- "0": "quit",
4505
4450
  }
4506
4451
 
4507
4452
  action = choice_map.get(choice, None)
@@ -5323,6 +5268,7 @@ def view_untested_usernames(engagement_id: int):
5323
5268
  def export_usernames_to_file(engagement_id: int, untested_creds: list):
5324
5269
  """Export untested usernames to a file."""
5325
5270
  import os
5271
+
5326
5272
  from souleyez.storage.engagements import EngagementManager
5327
5273
 
5328
5274
  em = EngagementManager()
@@ -2,8 +2,8 @@
2
2
 
3
3
  import click
4
4
  from rich.console import Console
5
+ from rich.progress import BarColumn, Progress, TextColumn
5
6
  from rich.table import Table
6
- from rich.progress import Progress, BarColumn, TextColumn
7
7
 
8
8
  try:
9
9
  from rich.progress import TaskProgressColumn
@@ -2,11 +2,13 @@
2
2
  """
3
3
  souleyez.ui.design_system - Centralized design system for consistent UI
4
4
  """
5
+
6
+ import os
5
7
  from typing import List
6
- from rich.table import Table
7
- from rich.console import Console
8
+
8
9
  from rich import box
9
- import os
10
+ from rich.console import Console
11
+ from rich.table import Table
10
12
 
11
13
  # Shared console instance
12
14
  _console = None
souleyez/ui/errors.py CHANGED
@@ -5,8 +5,10 @@ souleyez.ui.errors - User-friendly error messages with fix suggestions
5
5
  This module provides consistent, helpful error messages that guide users
6
6
  toward solutions rather than just reporting problems.
7
7
  """
8
+
9
+ from typing import List, Optional
10
+
8
11
  import click
9
- from typing import Optional, List
10
12
 
11
13
 
12
14
  class ErrorHelper:
@@ -1,6 +1,7 @@
1
1
  """Evidence linking interface for deliverables."""
2
2
 
3
3
  import click
4
+
4
5
  from souleyez.storage.deliverable_evidence import EvidenceManager
5
6
  from souleyez.storage.deliverables import DeliverableManager
6
7
  from souleyez.ui.design_system import DesignSystem
@@ -183,8 +184,8 @@ def show_evidence_linking_view(deliverable_id: int):
183
184
 
184
185
  def _add_evidence_manual(deliverable_id: int, engagement_id: int):
185
186
  """Manually select and link evidence."""
186
- from souleyez.storage.findings import FindingsManager
187
187
  from souleyez.storage.credentials import CredentialsManager
188
+ from souleyez.storage.findings import FindingsManager
188
189
 
189
190
  em = EvidenceManager()
190
191
  fm = FindingsManager()
@@ -4,11 +4,14 @@ Evidence & Artifacts - Unified evidence collection view.
4
4
  Displays all artifacts organized by pentesting methodology phases.
5
5
  Consolidates Evidence Vault and Screenshots into a single view.
6
6
  """
7
- import click
8
- from typing import Dict, List, Optional, Set
7
+
9
8
  import shutil
9
+ from typing import Dict, List, Optional, Set
10
+
11
+ import click
10
12
  from rich.console import Console
11
13
  from rich.table import Table
14
+
12
15
  from souleyez.ui.design_system import DesignSystem
13
16
  from souleyez.ui.errors import engagement_not_found
14
17
 
@@ -147,8 +150,8 @@ def view_evidence_vault(engagement_id: int):
147
150
 
148
151
  Consolidates Evidence Vault and Screenshots into a unified view.
149
152
  """
150
- from souleyez.storage.evidence import EvidenceManager
151
153
  from souleyez.storage.engagements import EngagementManager
154
+ from souleyez.storage.evidence import EvidenceManager
152
155
  from souleyez.storage.screenshots import ScreenshotManager
153
156
 
154
157
  em = EngagementManager()
@@ -508,6 +511,7 @@ def _export_selected_evidence(selected_items: List[Dict], engagement_id: int):
508
511
  import os
509
512
  import zipfile
510
513
  from datetime import datetime
514
+
511
515
  from souleyez.storage.engagement import EngagementManager
512
516
 
513
517
  click.echo(
@@ -953,11 +957,12 @@ def view_screenshots(engagement_id: int, screenshots: List[Dict], sm):
953
957
 
954
958
  Embedded screenshots view within Evidence & Artifacts.
955
959
  """
956
- from rich.console import Console
957
- from rich.table import Table
958
- from pathlib import Path
959
960
  import subprocess
960
961
  import sys
962
+ from pathlib import Path
963
+
964
+ from rich.console import Console
965
+ from rich.table import Table
961
966
 
962
967
  while True:
963
968
  DesignSystem.clear_screen()
@@ -11,17 +11,19 @@ Features:
11
11
  - Detailed info views with full context
12
12
  """
13
13
 
14
- import click
15
14
  import os
16
15
  import tempfile
16
+ from typing import Dict, List, Optional, Tuple
17
+
18
+ import click
17
19
  from rich.console import Console
18
- from rich.table import Table
19
20
  from rich.panel import Panel
20
- from typing import Dict, List, Optional, Tuple
21
- from souleyez.ui.design_system import DesignSystem
22
- from souleyez.storage.hosts import HostManager
21
+ from rich.table import Table
22
+
23
+ from souleyez.core.msf_integration import MSFConsoleManager, MSFResourceGenerator
23
24
  from souleyez.storage import exploit_attempts
24
- from souleyez.core.msf_integration import MSFResourceGenerator, MSFConsoleManager
25
+ from souleyez.storage.hosts import HostManager
26
+ from souleyez.ui.design_system import DesignSystem
25
27
 
26
28
  console = Console()
27
29
 
@@ -818,7 +820,9 @@ def _execute_msf_module(
818
820
  script += f"set PAYLOAD {payload}\n"
819
821
  script += "set LHOST 0.0.0.0 # CHANGE THIS to your IP\n"
820
822
  script += "set LPORT 4444\n"
821
- console.print(" [yellow]⚠️ Remember to set LHOST to your IP address![/yellow]")
823
+ console.print(
824
+ " [yellow]⚠️ Remember to set LHOST to your IP address![/yellow]"
825
+ )
822
826
 
823
827
  # Add check before exploit
824
828
  script += "\ncheck\n"
@@ -1,7 +1,9 @@
1
1
  """Export deliverables UI."""
2
2
 
3
- import click
4
3
  import os
4
+
5
+ import click
6
+
5
7
  from souleyez.storage.deliverable_exporter import DeliverableExporter
6
8
  from souleyez.storage.engagements import EngagementManager
7
9
  from souleyez.ui.design_system import DesignSystem
@@ -5,12 +5,15 @@ souleyez.ui.gap_analysis_view - Gap Analysis View
5
5
  Displays comparison between Wazuh (passive) and scan (active)
6
6
  vulnerability detection to identify gaps in coverage.
7
7
  """
8
+
9
+ from typing import Dict, List
10
+
8
11
  import click
9
12
  from rich.console import Console
10
13
  from rich.table import Table
11
- from typing import List, Dict
12
- from souleyez.intelligence.gap_analyzer import GapAnalyzer, GapAnalysisResult
14
+
13
15
  from souleyez.integrations.wazuh import WazuhConfig, WazuhVulnSync
16
+ from souleyez.intelligence.gap_analyzer import GapAnalysisResult, GapAnalyzer
14
17
  from souleyez.ui.design_system import DesignSystem
15
18
 
16
19
  console = Console()
@@ -200,8 +203,8 @@ def _render_summary_dashboard(
200
203
 
201
204
  def _render_severity_breakdown(breakdown: Dict, width: int) -> None:
202
205
  """Render severity breakdown."""
203
- from rich.table import Table
204
206
  from rich import box
207
+ from rich.table import Table
205
208
 
206
209
  SEVERITY_ICONS = {"Critical": "🔴", "High": "🟠", "Medium": "🟡", "Low": "⚪"}
207
210
 
@@ -4,9 +4,11 @@ souleyez.ui.help_system - In-app help and tooltips system
4
4
 
5
5
  Provides context-sensitive help throughout the application.
6
6
  """
7
- import click
7
+
8
8
  from typing import Dict, List, Optional
9
9
 
10
+ import click
11
+
10
12
 
11
13
  class HelpContext:
12
14
  """Enum-like class for help contexts."""
@@ -295,6 +297,7 @@ def show_help(
295
297
  engagement_type: Optional engagement preset type for preset-specific tips
296
298
  """
297
299
  import shutil
300
+
298
301
  from souleyez.ui.design_system import DesignSystem
299
302
 
300
303
  help_data = HELP_CONTENT.get(context, HELP_CONTENT[HelpContext.GENERAL])
@@ -3,9 +3,11 @@
3
3
  Intelligence View UI.
4
4
  Visual interface for attack surface analysis and exploitation tracking.
5
5
  """
6
- import click
7
- from typing import Dict, List
6
+
8
7
  import shutil
8
+ from typing import Dict, List
9
+
10
+ import click
9
11
 
10
12
 
11
13
  def get_terminal_width() -> int:
@@ -328,9 +330,10 @@ def display_exploit_suggestions(
328
330
  engagement_id: int, top_hosts: List[Dict], width: int, show_all: bool = False
329
331
  ):
330
332
  """Display exploit suggestions for top hosts."""
331
- from souleyez.intelligence.exploit_suggestions import ExploitSuggestionEngine
332
333
  from rich.console import Console
333
334
 
335
+ from souleyez.intelligence.exploit_suggestions import ExploitSuggestionEngine
336
+
334
337
  console = Console()
335
338
  # Disable SearchSploit in dashboard to prevent UI hangs - use manual Exploit Suggestions menu instead
336
339
  engine = ExploitSuggestionEngine(use_searchsploit=False)
@@ -725,6 +728,7 @@ def view_host_details(engagement_id: int, hosts: List[Dict]):
725
728
  # Show all services in a table
726
729
  from rich.console import Console
727
730
  from rich.table import Table
731
+
728
732
  from souleyez.ui.design_system import DesignSystem
729
733
 
730
734
  console = Console(width=width - 4)