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.
- souleyez/__init__.py +1 -1
- souleyez/ai/__init__.py +7 -7
- souleyez/ai/action_mapper.py +3 -2
- souleyez/ai/chain_advisor.py +2 -1
- souleyez/ai/claude_provider.py +2 -2
- souleyez/ai/context_builder.py +4 -2
- souleyez/ai/executor.py +9 -6
- souleyez/ai/feedback_handler.py +4 -2
- souleyez/ai/llm_provider.py +2 -2
- souleyez/ai/ollama_provider.py +2 -2
- souleyez/ai/ollama_service.py +10 -26
- souleyez/ai/path_scorer.py +2 -1
- souleyez/ai/recommender.py +6 -4
- souleyez/ai/report_context.py +2 -2
- souleyez/ai/report_service.py +5 -5
- souleyez/ai/result_parser.py +3 -2
- souleyez/ai/safety.py +5 -2
- souleyez/auth/__init__.py +6 -6
- souleyez/auth/audit.py +2 -2
- souleyez/auth/engagement_access.py +5 -7
- souleyez/auth/permissions.py +1 -1
- souleyez/auth/session_manager.py +5 -5
- souleyez/auth/user_manager.py +4 -5
- souleyez/commands/audit.py +6 -5
- souleyez/commands/auth.py +6 -5
- souleyez/commands/deliverables.py +2 -3
- souleyez/commands/engagement.py +3 -3
- souleyez/commands/license.py +3 -2
- souleyez/commands/screenshots.py +5 -4
- souleyez/commands/user.py +10 -8
- souleyez/config.py +4 -2
- souleyez/core/credential_tester.py +4 -2
- souleyez/core/cve_mappings.py +2 -1
- souleyez/core/cve_matcher.py +2 -1
- souleyez/core/msf_auto_mapper.py +2 -0
- souleyez/core/msf_chain_engine.py +3 -1
- souleyez/core/msf_database.py +7 -13
- souleyez/core/msf_integration.py +2 -2
- souleyez/core/msf_rpc_client.py +3 -2
- souleyez/core/msf_rpc_manager.py +4 -4
- souleyez/core/msf_sync_manager.py +7 -7
- souleyez/core/network_utils.py +1 -1
- souleyez/core/parser_handler.py +2 -1
- souleyez/core/pending_chains.py +4 -3
- souleyez/core/templates.py +5 -2
- souleyez/core/tool_chaining.py +101 -70
- souleyez/core/version_utils.py +1 -0
- souleyez/core/vuln_correlation.py +3 -2
- souleyez/core/web_utils.py +2 -1
- souleyez/detection/__init__.py +1 -1
- souleyez/detection/attack_signatures.py +1 -1
- souleyez/detection/mitre_mappings.py +1 -2
- souleyez/detection/validator.py +5 -4
- souleyez/devtools.py +4 -2
- souleyez/docs/README.md +2 -2
- souleyez/engine/background.py +168 -7
- souleyez/engine/base.py +2 -1
- souleyez/engine/loader.py +4 -2
- souleyez/engine/log_sanitizer.py +1 -0
- souleyez/engine/manager.py +3 -1
- souleyez/engine/result_handler.py +50 -67
- souleyez/engine/worker_manager.py +6 -4
- souleyez/export/evidence_bundle.py +1 -0
- souleyez/handlers/base.py +1 -0
- souleyez/handlers/bash_handler.py +1 -0
- souleyez/handlers/bloodhound_handler.py +1 -0
- souleyez/handlers/certipy_handler.py +1 -0
- souleyez/handlers/crackmapexec_handler.py +2 -20
- souleyez/handlers/dnsrecon_handler.py +2 -1
- souleyez/handlers/enum4linux_handler.py +65 -37
- souleyez/handlers/evil_winrm_handler.py +1 -0
- souleyez/handlers/ffuf_handler.py +3 -1
- souleyez/handlers/gobuster_handler.py +7 -6
- souleyez/handlers/gpp_extract_handler.py +1 -0
- souleyez/handlers/hashcat_handler.py +1 -0
- souleyez/handlers/hydra_handler.py +5 -2
- souleyez/handlers/impacket_getuserspns_handler.py +1 -0
- souleyez/handlers/impacket_psexec_handler.py +1 -0
- souleyez/handlers/impacket_secretsdump_handler.py +1 -0
- souleyez/handlers/john_handler.py +1 -0
- souleyez/handlers/katana_handler.py +39 -2
- souleyez/handlers/kerbrute_handler.py +1 -0
- souleyez/handlers/ldapsearch_handler.py +90 -17
- souleyez/handlers/lfi_extract_handler.py +1 -0
- souleyez/handlers/msf_auxiliary_handler.py +1 -0
- souleyez/handlers/msf_exploit_handler.py +1 -0
- souleyez/handlers/nikto_handler.py +2 -1
- souleyez/handlers/nmap_handler.py +2 -1
- souleyez/handlers/nuclei_handler.py +2 -1
- souleyez/handlers/nxc_handler.py +3 -18
- souleyez/handlers/rdp_sec_check_handler.py +1 -0
- souleyez/handlers/registry.py +1 -0
- souleyez/handlers/responder_handler.py +1 -0
- souleyez/handlers/service_explorer_handler.py +2 -1
- souleyez/handlers/smbclient_handler.py +1 -0
- souleyez/handlers/smbmap_handler.py +3 -2
- souleyez/handlers/sqlmap_handler.py +6 -4
- souleyez/handlers/theharvester_handler.py +2 -1
- souleyez/handlers/web_login_test_handler.py +1 -0
- souleyez/handlers/whois_handler.py +3 -2
- souleyez/handlers/wpscan_handler.py +2 -1
- souleyez/history.py +4 -3
- souleyez/importers/msf_importer.py +5 -3
- souleyez/importers/smart_importer.py +6 -4
- souleyez/integrations/siem/__init__.py +6 -6
- souleyez/integrations/siem/base.py +1 -1
- souleyez/integrations/siem/elastic.py +3 -3
- souleyez/integrations/siem/factory.py +1 -2
- souleyez/integrations/siem/googlesecops.py +4 -4
- souleyez/integrations/siem/rule_mappings/wazuh_rules.py +1 -1
- souleyez/integrations/siem/sentinel.py +3 -3
- souleyez/integrations/siem/splunk.py +3 -3
- souleyez/integrations/siem/wazuh.py +4 -4
- souleyez/integrations/wazuh/__init__.py +1 -1
- souleyez/integrations/wazuh/client.py +3 -2
- souleyez/integrations/wazuh/config.py +3 -2
- souleyez/integrations/wazuh/host_mapper.py +3 -1
- souleyez/integrations/wazuh/sync.py +4 -1
- souleyez/intelligence/__init__.py +1 -1
- souleyez/intelligence/correlation_analyzer.py +6 -5
- souleyez/intelligence/exploit_knowledge.py +4 -4
- souleyez/intelligence/exploit_suggestions.py +4 -3
- souleyez/intelligence/gap_analyzer.py +5 -3
- souleyez/intelligence/gap_detector.py +2 -0
- souleyez/intelligence/sensitive_tables.py +1 -1
- souleyez/intelligence/service_parser.py +1 -0
- souleyez/intelligence/surface_analyzer.py +9 -9
- souleyez/intelligence/target_parser.py +1 -0
- souleyez/licensing/__init__.py +3 -3
- souleyez/main.py +25 -18
- souleyez/migrations/fix_job_counter.py +2 -1
- souleyez/parsers/bloodhound_parser.py +1 -0
- souleyez/parsers/crackmapexec_parser.py +2 -1
- souleyez/parsers/dalfox_parser.py +3 -2
- souleyez/parsers/dnsrecon_parser.py +2 -1
- souleyez/parsers/enum4linux_parser.py +2 -1
- souleyez/parsers/ffuf_parser.py +2 -1
- souleyez/parsers/gobuster_parser.py +2 -1
- souleyez/parsers/hashcat_parser.py +3 -2
- souleyez/parsers/http_fingerprint_parser.py +2 -1
- souleyez/parsers/hydra_parser.py +2 -1
- souleyez/parsers/impacket_parser.py +2 -1
- souleyez/parsers/john_parser.py +4 -3
- souleyez/parsers/katana_parser.py +134 -2
- souleyez/parsers/msf_parser.py +2 -1
- souleyez/parsers/nikto_parser.py +2 -1
- souleyez/parsers/nmap_parser.py +14 -3
- souleyez/parsers/nuclei_parser.py +3 -2
- souleyez/parsers/responder_parser.py +1 -0
- souleyez/parsers/searchsploit_parser.py +3 -2
- souleyez/parsers/service_explorer_parser.py +1 -0
- souleyez/parsers/smbmap_parser.py +2 -1
- souleyez/parsers/sqlmap_parser.py +36 -2
- souleyez/parsers/theharvester_parser.py +2 -1
- souleyez/parsers/whois_parser.py +2 -1
- souleyez/parsers/wpscan_parser.py +3 -2
- souleyez/plugins/afp.py +3 -1
- souleyez/plugins/afp_brute.py +3 -1
- souleyez/plugins/ard.py +3 -1
- souleyez/plugins/bloodhound.py +3 -2
- souleyez/plugins/certipy.py +1 -0
- souleyez/plugins/crackmapexec.py +11 -7
- souleyez/plugins/dalfox.py +5 -2
- souleyez/plugins/dns_hijack.py +3 -1
- souleyez/plugins/dnsrecon.py +3 -1
- souleyez/plugins/enum4linux.py +3 -1
- souleyez/plugins/evil_winrm.py +1 -0
- souleyez/plugins/ffuf.py +3 -1
- souleyez/plugins/firmware_extract.py +3 -2
- souleyez/plugins/gobuster.py +6 -3
- souleyez/plugins/gpp_extract.py +1 -0
- souleyez/plugins/hashcat.py +2 -1
- souleyez/plugins/http_fingerprint.py +57 -7
- souleyez/plugins/hydra.py +5 -3
- souleyez/plugins/impacket_common.py +40 -0
- souleyez/plugins/impacket_getnpusers.py +19 -2
- souleyez/plugins/impacket_getuserspns.py +158 -0
- souleyez/plugins/impacket_psexec.py +19 -2
- souleyez/plugins/impacket_secretsdump.py +19 -2
- souleyez/plugins/impacket_smbclient.py +19 -2
- souleyez/plugins/john.py +2 -1
- souleyez/plugins/katana.py +48 -6
- souleyez/plugins/kerbrute.py +1 -0
- souleyez/plugins/lfi_extract.py +1 -0
- souleyez/plugins/macos_ssh.py +3 -1
- souleyez/plugins/mdns.py +3 -1
- souleyez/plugins/msf_auxiliary.py +3 -2
- souleyez/plugins/msf_exploit.py +6 -5
- souleyez/plugins/nikto.py +5 -2
- souleyez/plugins/nmap.py +6 -4
- souleyez/plugins/nuclei.py +3 -1
- souleyez/plugins/nxc.py +1 -0
- souleyez/plugins/plugin_base.py +3 -2
- souleyez/plugins/plugin_template.py +3 -2
- souleyez/plugins/rdp_sec_check.py +1 -0
- souleyez/plugins/responder.py +2 -1
- souleyez/plugins/router_http_brute.py +3 -1
- souleyez/plugins/router_ssh_brute.py +3 -1
- souleyez/plugins/router_telnet_brute.py +3 -1
- souleyez/plugins/routersploit.py +5 -3
- souleyez/plugins/routersploit_exploit.py +5 -3
- souleyez/plugins/searchsploit.py +1 -0
- souleyez/plugins/service_explorer.py +2 -1
- souleyez/plugins/smbmap.py +3 -1
- souleyez/plugins/smbpasswd.py +1 -0
- souleyez/plugins/sqlmap.py +3 -1
- souleyez/plugins/theharvester.py +3 -1
- souleyez/plugins/tr069.py +3 -1
- souleyez/plugins/upnp.py +3 -1
- souleyez/plugins/upnp_abuse.py +4 -2
- souleyez/plugins/vnc_access.py +4 -2
- souleyez/plugins/vnc_brute.py +3 -1
- souleyez/plugins/web_login_test.py +1 -0
- souleyez/plugins/whois.py +3 -1
- souleyez/plugins/wpscan.py +3 -1
- souleyez/reporting/attack_chain.py +2 -1
- souleyez/reporting/charts.py +1 -0
- souleyez/reporting/compliance_mappings.py +1 -0
- souleyez/reporting/detection_report.py +10 -10
- souleyez/reporting/formatters.py +7 -12
- souleyez/reporting/generator.py +34 -46
- souleyez/reporting/metrics.py +2 -1
- souleyez/scanner.py +6 -3
- souleyez/security/__init__.py +7 -5
- souleyez/security/scope_validator.py +5 -4
- souleyez/security.py +5 -2
- souleyez/storage/credentials.py +14 -19
- souleyez/storage/crypto.py +7 -4
- souleyez/storage/database.py +6 -6
- souleyez/storage/db.py +8 -8
- souleyez/storage/deliverable_evidence.py +2 -1
- souleyez/storage/deliverable_exporter.py +3 -2
- souleyez/storage/deliverable_templates.py +2 -1
- souleyez/storage/deliverables.py +2 -1
- souleyez/storage/engagements.py +6 -4
- souleyez/storage/evidence.py +5 -4
- souleyez/storage/execution_log.py +4 -2
- souleyez/storage/exploit_attempts.py +3 -2
- souleyez/storage/exploits.py +3 -1
- souleyez/storage/findings.py +3 -1
- souleyez/storage/hosts.py +5 -2
- souleyez/storage/migrate_to_engagements.py +14 -24
- souleyez/storage/migrations/_001_add_credential_enhancements.py +12 -21
- souleyez/storage/migrations/_003_add_execution_log.py +8 -13
- souleyez/storage/migrations/_005_screenshots.py +2 -4
- souleyez/storage/migrations/_006_deliverables.py +2 -4
- souleyez/storage/migrations/_007_deliverable_templates.py +4 -8
- souleyez/storage/migrations/_008_add_nuclei_table.py +2 -4
- souleyez/storage/migrations/_010_evidence_linking.py +6 -12
- souleyez/storage/migrations/_012_team_collaboration.py +12 -24
- souleyez/storage/migrations/_013_add_host_tags.py +2 -4
- souleyez/storage/migrations/_014_exploit_attempts.py +10 -20
- souleyez/storage/migrations/_015_add_mac_os_fields.py +4 -8
- souleyez/storage/migrations/_016_add_domain_field.py +2 -4
- souleyez/storage/migrations/_017_msf_sessions.py +8 -16
- souleyez/storage/migrations/_018_add_osint_target.py +4 -8
- souleyez/storage/migrations/_019_add_engagement_type.py +4 -8
- souleyez/storage/migrations/_020_add_rbac.py +9 -17
- souleyez/storage/migrations/_021_wazuh_integration.py +4 -8
- souleyez/storage/migrations/_023_fix_detection_results_fk.py +2 -4
- souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +4 -8
- souleyez/storage/migrations/_026_add_engagement_scope.py +4 -8
- souleyez/storage/migrations/_027_multi_siem_persistence.py +8 -16
- souleyez/storage/migrations/__init__.py +1 -4
- souleyez/storage/migrations/migration_manager.py +6 -9
- souleyez/storage/msf_sessions.py +1 -1
- souleyez/storage/osint.py +3 -1
- souleyez/storage/recommendation_engine.py +3 -2
- souleyez/storage/screenshots.py +2 -1
- souleyez/storage/smb_shares.py +3 -1
- souleyez/storage/sqlmap_data.py +6 -4
- souleyez/storage/team_collaboration.py +3 -2
- souleyez/storage/timeline_tracker.py +2 -1
- souleyez/storage/wazuh_vulns.py +3 -1
- souleyez/storage/web_paths.py +3 -1
- souleyez/testing/credential_tester.py +2 -0
- souleyez/ui/__init__.py +2 -1
- souleyez/ui/ai_quotes.py +1 -1
- souleyez/ui/attack_surface.py +50 -28
- souleyez/ui/chain_rules_view.py +6 -3
- souleyez/ui/correlation_view.py +3 -2
- souleyez/ui/dashboard.py +85 -139
- souleyez/ui/deliverables_view.py +1 -1
- souleyez/ui/design_system.py +5 -3
- souleyez/ui/errors.py +3 -1
- souleyez/ui/evidence_linking_view.py +2 -1
- souleyez/ui/evidence_vault.py +11 -6
- souleyez/ui/exploit_suggestions_view.py +11 -7
- souleyez/ui/export_view.py +3 -1
- souleyez/ui/gap_analysis_view.py +6 -3
- souleyez/ui/help_system.py +4 -1
- souleyez/ui/intelligence_view.py +7 -3
- souleyez/ui/interactive.py +1280 -558
- souleyez/ui/interactive_selector.py +3 -2
- souleyez/ui/log_formatter.py +1 -0
- souleyez/ui/menu_components.py +3 -1
- souleyez/ui/msf_auxiliary_menu.py +4 -1
- souleyez/ui/pending_chains_view.py +15 -12
- souleyez/ui/progress_indicators.py +5 -2
- souleyez/ui/recommendations_view.py +4 -2
- souleyez/ui/rule_builder.py +4 -1
- souleyez/ui/setup_wizard.py +10 -8
- souleyez/ui/shortcuts.py +1 -1
- souleyez/ui/splunk_gap_analysis_view.py +7 -4
- souleyez/ui/splunk_vulns_view.py +4 -1
- souleyez/ui/team_dashboard.py +7 -5
- souleyez/ui/template_selector.py +2 -1
- souleyez/ui/terminal.py +3 -2
- souleyez/ui/timeline_view.py +2 -1
- souleyez/ui/tool_setup.py +92 -31
- souleyez/ui/tutorial.py +7 -4
- souleyez/ui/tutorial_state.py +3 -2
- souleyez/ui/wazuh_vulns_view.py +5 -2
- souleyez/ui/wordlist_browser.py +4 -3
- souleyez/ui.py +13 -7
- souleyez/utils/tool_checker.py +95 -17
- souleyez/utils.py +4 -4
- souleyez/wordlists.py +1 -0
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/METADATA +1 -1
- souleyez-3.0.9.dist-info/RECORD +445 -0
- souleyez-3.0.0.dist-info/RECORD +0 -443
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/WHEEL +0 -0
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/entry_points.txt +0 -0
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/licenses/LICENSE +0 -0
- {souleyez-3.0.0.dist-info → souleyez-3.0.9.dist-info}/top_level.txt +0 -0
|
@@ -4,13 +4,14 @@ souleyez.ui.interactive_selector - Reusable interactive row selector with keyboa
|
|
|
4
4
|
|
|
5
5
|
Provides arrow-key/vim-style navigation for selecting items from tables.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import sys
|
|
8
9
|
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
|
|
9
10
|
|
|
10
11
|
import click
|
|
12
|
+
from rich import box
|
|
11
13
|
from rich.console import Console
|
|
12
14
|
from rich.table import Table
|
|
13
|
-
from rich import box
|
|
14
15
|
|
|
15
16
|
from souleyez.ui.design_system import DesignSystem
|
|
16
17
|
|
|
@@ -104,9 +105,9 @@ def _get_key() -> str:
|
|
|
104
105
|
|
|
105
106
|
# Fallback: use termios on Unix-like systems
|
|
106
107
|
try:
|
|
108
|
+
import select
|
|
107
109
|
import termios
|
|
108
110
|
import tty
|
|
109
|
-
import select
|
|
110
111
|
|
|
111
112
|
fd = sys.stdin.fileno()
|
|
112
113
|
old_settings = termios.tcgetattr(fd)
|
souleyez/ui/log_formatter.py
CHANGED
souleyez/ui/menu_components.py
CHANGED
|
@@ -9,8 +9,11 @@ Features:
|
|
|
9
9
|
- Batch execution mode
|
|
10
10
|
- Quick actions (auto-enum, search)
|
|
11
11
|
"""
|
|
12
|
+
|
|
13
|
+
from typing import Any, Dict, List, Optional, Set, Tuple
|
|
14
|
+
|
|
12
15
|
import click
|
|
13
|
-
|
|
16
|
+
|
|
14
17
|
from souleyez.ui.design_system import DesignSystem
|
|
15
18
|
|
|
16
19
|
|
|
@@ -6,25 +6,28 @@ UI for reviewing and approving/rejecting pending chain operations.
|
|
|
6
6
|
This implements the "active orchestration" workflow where users can
|
|
7
7
|
review suggested follow-up scans before execution.
|
|
8
8
|
"""
|
|
9
|
+
|
|
9
10
|
import math
|
|
10
|
-
import click
|
|
11
11
|
from typing import List, Set, Tuple
|
|
12
|
+
|
|
13
|
+
import click
|
|
14
|
+
|
|
12
15
|
from souleyez.core.pending_chains import (
|
|
13
|
-
list_pending_chains,
|
|
14
|
-
get_pending_chain,
|
|
15
|
-
approve_chain,
|
|
16
|
-
reject_chain,
|
|
17
|
-
approve_all_pending,
|
|
18
|
-
reject_all_pending,
|
|
19
|
-
get_chain_stats,
|
|
20
|
-
CHAIN_PENDING,
|
|
21
16
|
CHAIN_APPROVED,
|
|
22
|
-
CHAIN_REJECTED,
|
|
23
17
|
CHAIN_EXECUTED,
|
|
18
|
+
CHAIN_PENDING,
|
|
19
|
+
CHAIN_REJECTED,
|
|
20
|
+
approve_all_pending,
|
|
21
|
+
approve_chain,
|
|
22
|
+
get_chain_stats,
|
|
23
|
+
get_pending_chain,
|
|
24
|
+
list_pending_chains,
|
|
25
|
+
reject_all_pending,
|
|
26
|
+
reject_chain,
|
|
24
27
|
)
|
|
25
28
|
from souleyez.core.tool_chaining import ToolChaining
|
|
26
|
-
from souleyez.ui.menu_components import StandardMenu
|
|
27
29
|
from souleyez.ui.design_system import DesignSystem
|
|
30
|
+
from souleyez.ui.menu_components import StandardMenu
|
|
28
31
|
|
|
29
32
|
|
|
30
33
|
def manage_pending_chains(engagement_id: int = None):
|
|
@@ -805,9 +808,9 @@ def _view_chain_history(engagement_id: int = None):
|
|
|
805
808
|
|
|
806
809
|
def show_active_orchestration_help():
|
|
807
810
|
"""Display the Active Orchestration help guide with Rich formatting."""
|
|
811
|
+
from rich import box
|
|
808
812
|
from rich.console import Console
|
|
809
813
|
from rich.panel import Panel
|
|
810
|
-
from rich import box
|
|
811
814
|
|
|
812
815
|
console = Console()
|
|
813
816
|
DesignSystem.clear_screen()
|
|
@@ -4,11 +4,14 @@ souleyez.ui.progress_indicators - Progress indicators for long-running operation
|
|
|
4
4
|
|
|
5
5
|
Provides entertaining progress feedback during AI generation and other slow tasks.
|
|
6
6
|
"""
|
|
7
|
+
|
|
8
|
+
import sys
|
|
7
9
|
import threading
|
|
8
10
|
import time
|
|
9
|
-
import
|
|
11
|
+
from typing import Any, Callable, Optional
|
|
12
|
+
|
|
10
13
|
import click
|
|
11
|
-
|
|
14
|
+
|
|
12
15
|
from souleyez.ui.ai_quotes import get_random_quote
|
|
13
16
|
|
|
14
17
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"""Smart recommendations dashboard."""
|
|
2
2
|
|
|
3
|
-
import click
|
|
4
3
|
from typing import Dict
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
6
7
|
from souleyez.storage.engagements import EngagementManager
|
|
8
|
+
from souleyez.storage.recommendation_engine import RecommendationEngine
|
|
7
9
|
from souleyez.ui.design_system import DesignSystem
|
|
8
10
|
|
|
9
11
|
|
souleyez/ui/rule_builder.py
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
"""
|
|
3
3
|
souleyez.ui.rule_builder - Interactive chain rule builder for custom automation
|
|
4
4
|
"""
|
|
5
|
+
|
|
6
|
+
from typing import Any, Dict, List, Optional
|
|
7
|
+
|
|
5
8
|
import click
|
|
6
|
-
|
|
9
|
+
|
|
7
10
|
from souleyez.ui.design_system import DesignSystem
|
|
8
11
|
|
|
9
12
|
|
souleyez/ui/setup_wizard.py
CHANGED
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
"""
|
|
3
3
|
souleyez.ui.setup_wizard - First-run setup wizard for new users
|
|
4
4
|
"""
|
|
5
|
-
|
|
6
|
-
import time
|
|
7
|
-
import click
|
|
5
|
+
|
|
8
6
|
import getpass
|
|
7
|
+
import os
|
|
9
8
|
import shutil
|
|
10
9
|
import subprocess
|
|
10
|
+
import time
|
|
11
11
|
from pathlib import Path
|
|
12
|
-
from typing import
|
|
13
|
-
from souleyez.ui.design_system import DesignSystem
|
|
12
|
+
from typing import Dict, List, Optional
|
|
14
13
|
|
|
14
|
+
import click
|
|
15
|
+
|
|
16
|
+
from souleyez.ui.design_system import DesignSystem
|
|
15
17
|
|
|
16
18
|
# Wizard state file
|
|
17
19
|
WIZARD_STATE_FILE = Path.home() / ".souleyez" / ".wizard_completed"
|
|
@@ -471,7 +473,7 @@ def run_setup_wizard() -> bool:
|
|
|
471
473
|
"""
|
|
472
474
|
try:
|
|
473
475
|
# Check if user has Pro tier
|
|
474
|
-
from souleyez.auth import
|
|
476
|
+
from souleyez.auth import Tier, get_current_user
|
|
475
477
|
|
|
476
478
|
user = get_current_user()
|
|
477
479
|
is_pro = user and user.tier == Tier.PRO
|
|
@@ -881,10 +883,10 @@ def _wizard_create_engagement() -> dict:
|
|
|
881
883
|
def _wizard_tool_check() -> dict:
|
|
882
884
|
"""Check installed tools using the centralized tool_checker module."""
|
|
883
885
|
from souleyez.utils.tool_checker import (
|
|
884
|
-
check_tool_version,
|
|
885
886
|
EXTERNAL_TOOLS,
|
|
886
|
-
|
|
887
|
+
check_tool_version,
|
|
887
888
|
detect_distro,
|
|
889
|
+
get_install_command,
|
|
888
890
|
get_tool_version,
|
|
889
891
|
get_upgrade_command,
|
|
890
892
|
)
|
souleyez/ui/shortcuts.py
CHANGED
|
@@ -5,14 +5,17 @@ souleyez.ui.splunk_gap_analysis_view - Splunk Gap Analysis View
|
|
|
5
5
|
Displays comparison between Splunk (passive, synced from Wazuh) and
|
|
6
6
|
scan (active) vulnerability detection to identify gaps in coverage.
|
|
7
7
|
"""
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
8
12
|
import click
|
|
13
|
+
from rich import box
|
|
9
14
|
from rich.console import Console
|
|
10
15
|
from rich.table import Table
|
|
11
|
-
|
|
12
|
-
from dataclasses import dataclass, field
|
|
13
|
-
from typing import List, Dict, Any, Optional
|
|
14
|
-
from souleyez.ui.design_system import DesignSystem
|
|
16
|
+
|
|
15
17
|
from souleyez.storage.database import get_db
|
|
18
|
+
from souleyez.ui.design_system import DesignSystem
|
|
16
19
|
|
|
17
20
|
console = Console()
|
|
18
21
|
|
souleyez/ui/splunk_vulns_view.py
CHANGED
|
@@ -5,10 +5,13 @@ souleyez.ui.splunk_vulns_view - Splunk Vulnerabilities View
|
|
|
5
5
|
Displays vulnerabilities synced from Wazuh to Splunk with
|
|
6
6
|
filtering and display capabilities.
|
|
7
7
|
"""
|
|
8
|
+
|
|
9
|
+
from typing import Dict, List, Optional
|
|
10
|
+
|
|
8
11
|
import click
|
|
9
12
|
from rich.console import Console
|
|
10
13
|
from rich.table import Table
|
|
11
|
-
|
|
14
|
+
|
|
12
15
|
from souleyez.ui.design_system import DesignSystem
|
|
13
16
|
|
|
14
17
|
console = Console()
|
souleyez/ui/team_dashboard.py
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"""Team collaboration dashboard."""
|
|
2
2
|
|
|
3
|
+
from typing import Dict, List, Optional
|
|
4
|
+
|
|
3
5
|
import click
|
|
4
|
-
|
|
5
|
-
from souleyez.storage.team_collaboration import TeamCollaboration
|
|
6
|
-
from souleyez.storage.engagements import EngagementManager
|
|
6
|
+
|
|
7
7
|
from souleyez.storage.deliverables import DeliverableManager
|
|
8
|
+
from souleyez.storage.engagements import EngagementManager
|
|
9
|
+
from souleyez.storage.team_collaboration import TeamCollaboration
|
|
8
10
|
from souleyez.ui.design_system import DesignSystem
|
|
9
11
|
from souleyez.ui.interactive_selector import (
|
|
10
|
-
_get_key,
|
|
11
|
-
KEY_UP,
|
|
12
12
|
KEY_DOWN,
|
|
13
13
|
KEY_ENTER,
|
|
14
14
|
KEY_ESCAPE,
|
|
15
|
+
KEY_UP,
|
|
16
|
+
_get_key,
|
|
15
17
|
)
|
|
16
18
|
|
|
17
19
|
|
souleyez/ui/template_selector.py
CHANGED
souleyez/ui/terminal.py
CHANGED
souleyez/ui/timeline_view.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""Timeline and velocity tracking UI for deliverables."""
|
|
2
2
|
|
|
3
3
|
import click
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
from souleyez.storage.deliverables import DeliverableManager
|
|
6
6
|
from souleyez.storage.engagements import EngagementManager
|
|
7
|
+
from souleyez.storage.timeline_tracker import TimelineTracker
|
|
7
8
|
from souleyez.ui.design_system import DesignSystem
|
|
8
9
|
|
|
9
10
|
|
souleyez/ui/tool_setup.py
CHANGED
|
@@ -5,24 +5,26 @@ souleyez.ui.tool_setup - Tool installation wizard for Ubuntu/Debian systems
|
|
|
5
5
|
Helps users install pentesting tools that aren't available via apt on Ubuntu.
|
|
6
6
|
Handles PATH configuration for go and pipx installed tools.
|
|
7
7
|
"""
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
import os
|
|
9
10
|
import shutil
|
|
10
11
|
import subprocess
|
|
11
12
|
import sys
|
|
12
|
-
import os
|
|
13
13
|
from pathlib import Path
|
|
14
|
-
from typing import
|
|
14
|
+
from typing import Dict, List, Optional
|
|
15
15
|
|
|
16
|
+
import click
|
|
17
|
+
|
|
18
|
+
from souleyez.ui.design_system import DesignSystem
|
|
16
19
|
from souleyez.utils.tool_checker import (
|
|
20
|
+
EXTERNAL_TOOLS,
|
|
21
|
+
check_tool,
|
|
17
22
|
detect_distro,
|
|
18
|
-
get_missing_tools,
|
|
19
|
-
get_tools_by_category,
|
|
20
23
|
get_category_name,
|
|
21
|
-
|
|
24
|
+
get_missing_tools,
|
|
22
25
|
get_tool_stats,
|
|
23
|
-
|
|
26
|
+
get_tools_by_category,
|
|
24
27
|
)
|
|
25
|
-
from souleyez.ui.design_system import DesignSystem
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
def _reset_terminal():
|
|
@@ -46,35 +48,35 @@ def _reset_terminal():
|
|
|
46
48
|
PREREQUISITES = {
|
|
47
49
|
"build-deps": {
|
|
48
50
|
"check": None, # Always install to ensure all deps present
|
|
49
|
-
"install": "sudo apt install -y build-essential python3-dev libxml2-dev libxslt1-dev libuv1-dev libffi-dev libssl-dev rustc cargo",
|
|
51
|
+
"install": "sudo apt-get -o DPkg::Lock::Timeout=120 install -y build-essential python3-dev libxml2-dev libxslt1-dev libuv1-dev libffi-dev libssl-dev rustc cargo",
|
|
50
52
|
"description": "Build dependencies for Python packages with native extensions",
|
|
51
53
|
"always_install": True, # Flag to always run this
|
|
52
54
|
},
|
|
53
55
|
"pipx": {
|
|
54
56
|
"check": "pipx",
|
|
55
|
-
"install": "sudo apt install -y pipx && pipx ensurepath",
|
|
57
|
+
"install": "sudo apt-get -o DPkg::Lock::Timeout=120 install -y pipx && pipx ensurepath",
|
|
56
58
|
"description": "Python application installer (for theHarvester, NetExec, etc.)",
|
|
57
59
|
"path_additions": ["~/.local/bin"],
|
|
58
60
|
},
|
|
59
61
|
"golang": {
|
|
60
62
|
"check": "go",
|
|
61
|
-
"install": "sudo apt install -y golang-go",
|
|
63
|
+
"install": "sudo apt-get -o DPkg::Lock::Timeout=120 install -y golang-go",
|
|
62
64
|
"description": "Go programming language (for nuclei, ffuf)",
|
|
63
65
|
"path_additions": ["~/go/bin"],
|
|
64
66
|
},
|
|
65
67
|
"ruby": {
|
|
66
68
|
"check": "gem",
|
|
67
|
-
"install": "sudo apt install -y ruby-full ruby-dev build-essential",
|
|
69
|
+
"install": "sudo apt-get -o DPkg::Lock::Timeout=120 install -y ruby-full ruby-dev build-essential",
|
|
68
70
|
"description": "Ruby programming language (for wpscan)",
|
|
69
71
|
},
|
|
70
72
|
"snap": {
|
|
71
73
|
"check": "snap",
|
|
72
|
-
"install": "sudo apt install -y snapd",
|
|
74
|
+
"install": "sudo apt-get -o DPkg::Lock::Timeout=120 install -y snapd",
|
|
73
75
|
"description": "Snap package manager (for enum4linux)",
|
|
74
76
|
},
|
|
75
77
|
"git": {
|
|
76
78
|
"check": "git",
|
|
77
|
-
"install": "sudo apt install -y git",
|
|
79
|
+
"install": "sudo apt-get -o DPkg::Lock::Timeout=120 install -y git",
|
|
78
80
|
"description": "Git version control (for exploitdb, Responder)",
|
|
79
81
|
},
|
|
80
82
|
}
|
|
@@ -371,9 +373,17 @@ def _ensure_msfdb_initialized(console):
|
|
|
371
373
|
console.print(" [dim]Initializing MSF database (this may take a minute)...[/dim]")
|
|
372
374
|
|
|
373
375
|
try:
|
|
374
|
-
#
|
|
376
|
+
# Distro-aware msfdb init:
|
|
377
|
+
# - Kali/Parrot (apt install): requires sudo
|
|
378
|
+
# - Ubuntu/Debian (omnibus installer): must run as normal user, NOT root
|
|
379
|
+
distro = detect_distro()
|
|
380
|
+
if distro in ("kali", "parrot"):
|
|
381
|
+
msfdb_cmd = ["sudo", msfdb_path, "init"]
|
|
382
|
+
else:
|
|
383
|
+
msfdb_cmd = [msfdb_path, "init"]
|
|
384
|
+
|
|
375
385
|
result = subprocess.run(
|
|
376
|
-
|
|
386
|
+
msfdb_cmd,
|
|
377
387
|
capture_output=True,
|
|
378
388
|
timeout=300, # 5 minute timeout
|
|
379
389
|
)
|
|
@@ -749,7 +759,7 @@ def _install_apt_tools(console, tools: List[Dict]) -> bool:
|
|
|
749
759
|
return True
|
|
750
760
|
|
|
751
761
|
console.print(f" Packages: {', '.join(packages)}")
|
|
752
|
-
cmd = f"sudo apt install -y {' '.join(packages)}"
|
|
762
|
+
cmd = f"sudo apt-get -o DPkg::Lock::Timeout=120 install -y {' '.join(packages)}"
|
|
753
763
|
success, _, _ = _run_command(cmd, console)
|
|
754
764
|
|
|
755
765
|
if success:
|
|
@@ -767,20 +777,63 @@ def _install_pipx_tool(console, tool: Dict) -> bool:
|
|
|
767
777
|
|
|
768
778
|
console.print(f" {name}...", end=" ")
|
|
769
779
|
|
|
770
|
-
#
|
|
771
|
-
|
|
780
|
+
# For netexec and other complex builds, show message about output capture
|
|
781
|
+
if "NetExec" in cmd or "netexec" in cmd.lower():
|
|
782
|
+
console.print()
|
|
783
|
+
console.print(
|
|
784
|
+
" [dim]Building (output captured, this may take a while)...[/dim]"
|
|
785
|
+
)
|
|
772
786
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
787
|
+
# pipx install commands - use subprocess directly to ensure full capture
|
|
788
|
+
# Some tools (like netexec with Rust deps) can corrupt terminal with progress bars
|
|
789
|
+
try:
|
|
790
|
+
result = subprocess.run(
|
|
791
|
+
cmd,
|
|
792
|
+
shell=True,
|
|
793
|
+
capture_output=True,
|
|
794
|
+
text=True,
|
|
795
|
+
timeout=600, # 10 minute timeout
|
|
796
|
+
)
|
|
797
|
+
success = result.returncode == 0
|
|
798
|
+
stderr = result.stderr
|
|
799
|
+
|
|
800
|
+
if success:
|
|
801
|
+
console.print(
|
|
802
|
+
" [green]✓[/green]"
|
|
803
|
+
if "NetExec" not in cmd
|
|
804
|
+
else " [green]✓[/green]"
|
|
805
|
+
)
|
|
780
806
|
return True
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
807
|
+
else:
|
|
808
|
+
# Check if already installed
|
|
809
|
+
if "already exists" in stderr or "already installed" in stderr.lower():
|
|
810
|
+
console.print(
|
|
811
|
+
" [green]✓ (already installed)[/green]"
|
|
812
|
+
if "NetExec" not in cmd
|
|
813
|
+
else " [green]✓ (already installed)[/green]"
|
|
814
|
+
)
|
|
815
|
+
return True
|
|
816
|
+
console.print(
|
|
817
|
+
" [red]✗[/red]" if "NetExec" not in cmd else " [red]✗[/red]"
|
|
818
|
+
)
|
|
819
|
+
if stderr:
|
|
820
|
+
# Truncate and clean stderr for display
|
|
821
|
+
clean_stderr = stderr.replace("\n", " ")[:80]
|
|
822
|
+
console.print(f" [dim]{clean_stderr}[/dim]")
|
|
823
|
+
return False
|
|
824
|
+
except subprocess.TimeoutExpired:
|
|
825
|
+
console.print(
|
|
826
|
+
" [red]✗ timeout[/red]"
|
|
827
|
+
if "NetExec" not in cmd
|
|
828
|
+
else " [red]✗ timeout[/red]"
|
|
829
|
+
)
|
|
830
|
+
return False
|
|
831
|
+
except Exception as e:
|
|
832
|
+
console.print(
|
|
833
|
+
f" [red]✗[/red] {str(e)[:50]}"
|
|
834
|
+
if "NetExec" not in cmd
|
|
835
|
+
else f" [red]✗[/red] {str(e)[:50]}"
|
|
836
|
+
)
|
|
784
837
|
return False
|
|
785
838
|
|
|
786
839
|
|
|
@@ -980,11 +1033,19 @@ def _install_other_tool(console, tool: Dict) -> bool:
|
|
|
980
1033
|
console.print(
|
|
981
1034
|
" [dim]Installing postgresql and downloading Metasploit installer...[/dim]"
|
|
982
1035
|
)
|
|
1036
|
+
console.print(
|
|
1037
|
+
" [dim]Output is captured to prevent terminal corruption...[/dim]"
|
|
1038
|
+
)
|
|
983
1039
|
|
|
984
|
-
# Run the full install command
|
|
1040
|
+
# Run the full install command with captured output to prevent terminal corruption
|
|
1041
|
+
# Metasploit installer outputs progress bars and escape sequences that can corrupt Rich console
|
|
985
1042
|
try:
|
|
986
1043
|
result = subprocess.run(
|
|
987
|
-
cmd,
|
|
1044
|
+
cmd,
|
|
1045
|
+
shell=True,
|
|
1046
|
+
capture_output=True, # Capture to prevent terminal corruption
|
|
1047
|
+
text=True,
|
|
1048
|
+
timeout=1800, # 30 minute timeout for metasploit
|
|
988
1049
|
)
|
|
989
1050
|
if result.returncode == 0:
|
|
990
1051
|
console.print(" [green]✓ Metasploit installed[/green]")
|
souleyez/ui/tutorial.py
CHANGED
|
@@ -9,10 +9,13 @@ This tutorial guides new users through:
|
|
|
9
9
|
4. Running reconnaissance scans
|
|
10
10
|
5. Exploring the Command Center (dashboard) interactively
|
|
11
11
|
"""
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
import time
|
|
14
14
|
from pathlib import Path
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
import click
|
|
17
|
+
|
|
18
|
+
from souleyez.ui.tutorial_state import TutorialStep, get_tutorial_state
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
def clear_screen():
|
|
@@ -453,9 +456,9 @@ def _show_tutorial_complete():
|
|
|
453
456
|
def _cleanup_tutorial_data():
|
|
454
457
|
"""Clean up tutorial engagement, jobs, and related data."""
|
|
455
458
|
try:
|
|
456
|
-
from souleyez.storage.engagements import EngagementManager
|
|
457
|
-
from souleyez.engine.background import list_jobs, delete_job, kill_job
|
|
458
459
|
from souleyez.core.tool_chaining import ToolChaining
|
|
460
|
+
from souleyez.engine.background import delete_job, kill_job, list_jobs
|
|
461
|
+
from souleyez.storage.engagements import EngagementManager
|
|
459
462
|
|
|
460
463
|
# Disable auto-chaining (it's a PRO feature, tutorial enabled it for demo)
|
|
461
464
|
try:
|
souleyez/ui/tutorial_state.py
CHANGED
|
@@ -5,10 +5,11 @@ souleyez.ui.tutorial_state - Tutorial state manager for interactive guided tutor
|
|
|
5
5
|
This module tracks tutorial progress across different UI screens,
|
|
6
6
|
allowing contextual hints to be displayed in dashboard, job queue, etc.
|
|
7
7
|
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
8
10
|
from enum import Enum, auto
|
|
9
11
|
from pathlib import Path
|
|
10
|
-
from typing import
|
|
11
|
-
import json
|
|
12
|
+
from typing import Any, Dict, Optional
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class TutorialStep(Enum):
|
souleyez/ui/wazuh_vulns_view.py
CHANGED
|
@@ -5,12 +5,15 @@ souleyez.ui.wazuh_vulns_view - Wazuh Vulnerabilities View
|
|
|
5
5
|
Displays vulnerabilities discovered by Wazuh agents with sync,
|
|
6
6
|
filtering, and status management capabilities.
|
|
7
7
|
"""
|
|
8
|
+
|
|
9
|
+
from typing import Dict, List, Optional
|
|
10
|
+
|
|
8
11
|
import click
|
|
9
12
|
from rich.console import Console
|
|
10
13
|
from rich.table import Table
|
|
11
|
-
|
|
14
|
+
|
|
15
|
+
from souleyez.integrations.wazuh import WazuhConfig, WazuhHostMapper, WazuhVulnSync
|
|
12
16
|
from souleyez.storage.wazuh_vulns import WazuhVulnsManager
|
|
13
|
-
from souleyez.integrations.wazuh import WazuhVulnSync, WazuhConfig, WazuhHostMapper
|
|
14
17
|
from souleyez.ui.design_system import DesignSystem
|
|
15
18
|
from souleyez.ui.interactive_selector import interactive_select
|
|
16
19
|
|
souleyez/ui/wordlist_browser.py
CHANGED
|
@@ -5,6 +5,7 @@ souleyez.ui.wordlist_browser - Interactive wordlist browser with keyboard naviga
|
|
|
5
5
|
Discovers wordlists from common directories (SecLists, Kali, etc.) and provides
|
|
6
6
|
an interactive browser for selection.
|
|
7
7
|
"""
|
|
8
|
+
|
|
8
9
|
import os
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
from typing import Any, Dict, List, Optional, Tuple
|
|
@@ -15,11 +16,11 @@ from rich.table import Table
|
|
|
15
16
|
|
|
16
17
|
from souleyez.ui.design_system import DesignSystem
|
|
17
18
|
from souleyez.ui.interactive_selector import (
|
|
18
|
-
_get_key,
|
|
19
|
-
KEY_UP,
|
|
20
19
|
KEY_DOWN,
|
|
21
20
|
KEY_ENTER,
|
|
22
21
|
KEY_ESCAPE,
|
|
22
|
+
KEY_UP,
|
|
23
|
+
_get_key,
|
|
23
24
|
)
|
|
24
25
|
|
|
25
26
|
# Common wordlist directories to scan
|
|
@@ -322,8 +323,8 @@ class WordlistBrowser:
|
|
|
322
323
|
|
|
323
324
|
def _render(self):
|
|
324
325
|
"""Render the browser UI."""
|
|
325
|
-
from rich.table import Table
|
|
326
326
|
from rich import box
|
|
327
|
+
from rich.table import Table
|
|
327
328
|
|
|
328
329
|
DesignSystem.clear_screen()
|
|
329
330
|
width = DesignSystem.get_terminal_width()
|
souleyez/ui.py
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
# - We group by tool, and show ALL entries (no pagination)
|
|
6
6
|
# - Export pulls an entry by list index (1-based) in current view
|
|
7
7
|
|
|
8
|
-
import sys
|
|
9
8
|
import os
|
|
10
9
|
import subprocess
|
|
11
|
-
|
|
12
|
-
from
|
|
10
|
+
import sys
|
|
11
|
+
from typing import Any, Dict, List
|
|
12
|
+
|
|
13
|
+
from .utils import detect_local_subnet, nmap_installed
|
|
13
14
|
|
|
14
15
|
# Ensure enqueue_job is available for the TUI enqueue flow.
|
|
15
16
|
# If the background engine isn't available in this environment, provide a friendly stub
|
|
@@ -34,11 +35,11 @@ except Exception:
|
|
|
34
35
|
)
|
|
35
36
|
|
|
36
37
|
|
|
37
|
-
from .engine.background import
|
|
38
|
+
from .engine.background import get_job, list_jobs
|
|
38
39
|
from .engine.loader import discover_plugins
|
|
39
40
|
from .engine.manager import run_scan_sync
|
|
40
41
|
from .scanner import run_nmap
|
|
41
|
-
from .storage.db import
|
|
42
|
+
from .storage.db import get_scan, get_scans
|
|
42
43
|
|
|
43
44
|
# (history.py kept for export helpers if needed in future, not used for reads)
|
|
44
45
|
|
|
@@ -336,8 +337,9 @@ def history_export(scans: List[Dict[str, Any]]):
|
|
|
336
337
|
print("Invalid index.")
|
|
337
338
|
return
|
|
338
339
|
# Export using a simple inline writer (avoid legacy)
|
|
340
|
+
import csv
|
|
341
|
+
import json
|
|
339
342
|
from pathlib import Path
|
|
340
|
-
import json, csv
|
|
341
343
|
|
|
342
344
|
export_dir = Path.home() / ".souleyez" / "exports"
|
|
343
345
|
export_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -707,7 +709,11 @@ def view_job_live(job_id: int, refresh_interval: float = 1.0, max_lines: int = 3
|
|
|
707
709
|
- tries to locate log path via storage.get_scan(scan_id) if result_scan_id exists
|
|
708
710
|
- falls back to ~/.souleyez/artifacts/<job_id>.log when missing
|
|
709
711
|
"""
|
|
710
|
-
import
|
|
712
|
+
import json
|
|
713
|
+
import os
|
|
714
|
+
import select
|
|
715
|
+
import sys
|
|
716
|
+
import time
|
|
711
717
|
|
|
712
718
|
# lookup job record
|
|
713
719
|
j = None
|