From a67fe4c45c563b6fd16944b4e195601eb23ee42a Mon Sep 17 00:00:00 2001 From: 0xallam Date: Mon, 19 Jan 2026 16:42:38 -0800 Subject: [PATCH] refactor: redesign finished dialogs and UI elements --- strix/interface/assets/tui_styles.tcss | 4 +- strix/interface/cli.py | 46 ++++----- strix/interface/main.py | 68 ++++++------- .../tool_components/agents_graph_renderer.py | 7 +- .../tool_components/file_edit_renderer.py | 33 +++---- .../tool_components/finish_renderer.py | 4 +- .../tool_components/notes_renderer.py | 16 +-- .../tool_components/scan_info_renderer.py | 3 +- strix/interface/tui.py | 50 +++++----- strix/interface/utils.py | 97 +++++++++---------- 10 files changed, 154 insertions(+), 174 deletions(-) diff --git a/strix/interface/assets/tui_styles.tcss b/strix/interface/assets/tui_styles.tcss index e29cce3..0edeb42 100644 --- a/strix/interface/assets/tui_styles.tcss +++ b/strix/interface/assets/tui_styles.tcss @@ -36,7 +36,7 @@ Screen { } #sidebar { - width: 25%; + width: 20%; background: transparent; margin-left: 1; } @@ -174,7 +174,7 @@ VulnerabilityDetailScreen { } #chat_area_container { - width: 75%; + width: 80%; background: transparent; } diff --git a/strix/interface/cli.py b/strix/interface/cli.py index 414a24f..ef99f5e 100644 --- a/strix/interface/cli.py +++ b/strix/interface/cli.py @@ -24,30 +24,26 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 console = Console() start_text = Text() - start_text.append("πŸ¦‰ ", style="bold white") - start_text.append("STRIX CYBERSECURITY AGENT", style="bold green") + start_text.append("Penetration test initiated", style="bold #22c55e") target_text = Text() + target_text.append("Target", style="dim") + target_text.append(" ") if len(args.targets_info) == 1: - target_text.append("🎯 Target: ", style="bold cyan") target_text.append(args.targets_info[0]["original"], style="bold white") else: - target_text.append("🎯 Targets: ", style="bold cyan") - target_text.append(f"{len(args.targets_info)} targets\n", style="bold white") - for i, target_info in enumerate(args.targets_info): - target_text.append(" β€’ ", style="dim white") + target_text.append(f"{len(args.targets_info)} targets", style="bold white") + for target_info in args.targets_info: + target_text.append("\n ") target_text.append(target_info["original"], style="white") - if i < len(args.targets_info) - 1: - target_text.append("\n") results_text = Text() - results_text.append("πŸ“Š Results will be saved to: ", style="bold cyan") - results_text.append(f"strix_runs/{args.run_name}", style="bold white") + results_text.append("Output", style="dim") + results_text.append(" ") + results_text.append(f"strix_runs/{args.run_name}", style="#60a5fa") note_text = Text() note_text.append("\n\n", style="dim") - note_text.append("⏱️ ", style="dim") - note_text.append("This may take a while depending on target complexity. ", style="dim") note_text.append("Vulnerabilities will be displayed in real-time.", style="dim") startup_panel = Panel( @@ -59,9 +55,9 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 results_text, note_text, ), - title="[bold green]πŸ›‘οΈ STRIX PENETRATION TEST INITIATED", - title_align="center", - border_style="green", + title="[bold white]STRIX", + title_align="left", + border_style="#22c55e", padding=(1, 2), ) @@ -126,8 +122,7 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 def create_live_status() -> Panel: status_text = Text() - status_text.append("πŸ¦‰ ", style="bold white") - status_text.append("Running penetration test...", style="bold #22c55e") + status_text.append("Penetration test in progress", style="bold #22c55e") status_text.append("\n\n") stats_text = build_live_stats_text(tracer, agent_config) @@ -136,8 +131,8 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 return Panel( status_text, - title="[bold #22c55e]πŸ” Live Penetration Test Status", - title_align="center", + title="[bold white]STRIX", + title_align="left", border_style="#22c55e", padding=(1, 2), ) @@ -169,7 +164,7 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 error_msg = result.get("error", "Unknown error") error_details = result.get("details") console.print() - console.print(f"[bold red]❌ Penetration test failed:[/] {error_msg}") + console.print(f"[bold red]Penetration test failed:[/] {error_msg}") if error_details: console.print(f"[dim]{error_details}[/]") console.print() @@ -186,8 +181,7 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 console.print() final_report_text = Text() - final_report_text.append("πŸ“„ ", style="bold cyan") - final_report_text.append("FINAL PENETRATION TEST REPORT", style="bold cyan") + final_report_text.append("Penetration test summary", style="bold #60a5fa") final_report_panel = Panel( Text.assemble( @@ -195,9 +189,9 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 "\n\n", tracer.final_scan_result, ), - title="[bold cyan]πŸ“Š PENETRATION TEST SUMMARY", - title_align="center", - border_style="cyan", + title="[bold white]STRIX", + title_align="left", + border_style="#60a5fa", padding=(1, 2), ) diff --git a/strix/interface/main.py b/strix/interface/main.py index bef1999..c7ced70 100644 --- a/strix/interface/main.py +++ b/strix/interface/main.py @@ -76,7 +76,6 @@ def validate_environment() -> None: # noqa: PLR0912, PLR0915 if missing_required_vars: error_text = Text() - error_text.append("❌ ", style="bold red") error_text.append("MISSING REQUIRED ENVIRONMENT VARIABLES", style="bold red") error_text.append("\n\n", style="white") @@ -163,8 +162,8 @@ def validate_environment() -> None: # noqa: PLR0912, PLR0915 panel = Panel( error_text, - title="[bold red]πŸ›‘οΈ STRIX CONFIGURATION ERROR", - title_align="center", + title="[bold white]STRIX", + title_align="left", border_style="red", padding=(1, 2), ) @@ -179,7 +178,6 @@ def check_docker_installed() -> None: if shutil.which("docker") is None: console = Console() error_text = Text() - error_text.append("❌ ", style="bold red") error_text.append("DOCKER NOT INSTALLED", style="bold red") error_text.append("\n\n", style="white") error_text.append("The 'docker' CLI was not found in your PATH.\n", style="white") @@ -189,8 +187,8 @@ def check_docker_installed() -> None: panel = Panel( error_text, - title="[bold red]πŸ›‘οΈ STRIX STARTUP ERROR", - title_align="center", + title="[bold white]STRIX", + title_align="left", border_style="red", padding=(1, 2), ) @@ -234,7 +232,6 @@ async def warm_up_llm() -> None: except Exception as e: # noqa: BLE001 error_text = Text() - error_text.append("❌ ", style="bold red") error_text.append("LLM CONNECTION FAILED", style="bold red") error_text.append("\n\n", style="white") error_text.append("Could not establish connection to the language model.\n", style="white") @@ -243,8 +240,8 @@ async def warm_up_llm() -> None: panel = Panel( error_text, - title="[bold red]πŸ›‘οΈ STRIX STARTUP ERROR", - title_align="center", + title="[bold white]STRIX", + title_align="left", border_style="red", padding=(1, 2), ) @@ -410,30 +407,22 @@ def display_completion_message(args: argparse.Namespace, results_path: Path) -> completion_text = Text() if scan_completed: - completion_text.append("πŸ¦‰ ", style="bold white") - completion_text.append("AGENT FINISHED", style="bold green") - completion_text.append(" β€’ ", style="dim white") - completion_text.append("Penetration test completed", style="white") + completion_text.append("Penetration test completed", style="bold #22c55e") else: - completion_text.append("πŸ¦‰ ", style="bold white") - completion_text.append("SESSION ENDED", style="bold yellow") - completion_text.append(" β€’ ", style="dim white") - completion_text.append("Penetration test interrupted by user", style="white") - - stats_text = build_final_stats_text(tracer) + completion_text.append("SESSION ENDED", style="bold #eab308") target_text = Text() + target_text.append("Target", style="dim") + target_text.append(" ") if len(args.targets_info) == 1: - target_text.append("🎯 Target: ", style="bold cyan") target_text.append(args.targets_info[0]["original"], style="bold white") else: - target_text.append("🎯 Targets: ", style="bold cyan") - target_text.append(f"{len(args.targets_info)} targets\n", style="bold white") - for i, target_info in enumerate(args.targets_info): - target_text.append(" β€’ ", style="dim white") + target_text.append(f"{len(args.targets_info)} targets", style="bold white") + for target_info in args.targets_info: + target_text.append("\n ") target_text.append(target_info["original"], style="white") - if i < len(args.targets_info) - 1: - target_text.append("\n") + + stats_text = build_final_stats_text(tracer) panel_parts = [completion_text, "\n\n", target_text] @@ -442,18 +431,20 @@ def display_completion_message(args: argparse.Namespace, results_path: Path) -> if scan_completed or has_vulnerabilities: results_text = Text() - results_text.append("πŸ“Š Results Saved To: ", style="bold cyan") - results_text.append(str(results_path), style="bold yellow") - panel_parts.extend(["\n\n", results_text]) + results_text.append("\n") + results_text.append("Output", style="dim") + results_text.append(" ") + results_text.append(str(results_path), style="#60a5fa") + panel_parts.extend(["\n", results_text]) panel_content = Text.assemble(*panel_parts) - border_style = "green" if scan_completed else "yellow" + border_style = "#22c55e" if scan_completed else "#eab308" panel = Panel( panel_content, - title="[bold green]πŸ›‘οΈ STRIX CYBERSECURITY AGENT", - title_align="center", + title="[bold white]STRIX", + title_align="left", border_style=border_style, padding=(1, 2), ) @@ -461,8 +452,7 @@ def display_completion_message(args: argparse.Namespace, results_path: Path) -> console.print("\n") console.print(panel) console.print() - console.print("[dim]🌐 Website:[/] [cyan]https://strix.ai[/]") - console.print("[dim]πŸ’¬ Discord:[/] [cyan]https://discord.gg/YjKFvEZSdZ[/]") + console.print("[#60a5fa]strix.ai[/] [dim]Β·[/] [#60a5fa]discord.gg/YjKFvEZSdZ[/]") console.print() @@ -474,7 +464,7 @@ def pull_docker_image() -> None: return console.print() - console.print(f"[bold cyan]🐳 Pulling Docker image:[/] {Config.get('strix_image')}") + console.print(f"[dim]Pulling image[/] {Config.get('strix_image')}") console.print("[dim yellow]This only happens on first run and may take a few minutes...[/]") console.print() @@ -489,7 +479,6 @@ def pull_docker_image() -> None: except DockerException as e: console.print() error_text = Text() - error_text.append("❌ ", style="bold red") error_text.append("FAILED TO PULL IMAGE", style="bold red") error_text.append("\n\n", style="white") error_text.append(f"Could not download: {Config.get('strix_image')}\n", style="white") @@ -497,8 +486,8 @@ def pull_docker_image() -> None: panel = Panel( error_text, - title="[bold red]πŸ›‘οΈ DOCKER PULL ERROR", - title_align="center", + title="[bold white]STRIX", + title_align="left", border_style="red", padding=(1, 2), ) @@ -506,8 +495,7 @@ def pull_docker_image() -> None: sys.exit(1) success_text = Text() - success_text.append("βœ… ", style="bold green") - success_text.append("Successfully pulled Docker image", style="green") + success_text.append("Docker image ready", style="#22c55e") console.print(success_text) console.print() diff --git a/strix/interface/tool_components/agents_graph_renderer.py b/strix/interface/tool_components/agents_graph_renderer.py index b69a6ea..8292373 100644 --- a/strix/interface/tool_components/agents_graph_renderer.py +++ b/strix/interface/tool_components/agents_graph_renderer.py @@ -92,12 +92,13 @@ class AgentFinishRenderer(BaseToolRenderer): success = args.get("success", True) text = Text() - text.append("🏁 ") if success: - text.append("Agent completed", style="bold #fbbf24") + text.append("β—† ", style="#22c55e") + text.append("Agent completed", style="bold #22c55e") else: - text.append("Agent failed", style="bold #fbbf24") + text.append("β—† ", style="#ef4444") + text.append("Agent failed", style="bold #ef4444") if result_summary: text.append("\n ") diff --git a/strix/interface/tool_components/file_edit_renderer.py b/strix/interface/tool_components/file_edit_renderer.py index 2290863..7043c1d 100644 --- a/strix/interface/tool_components/file_edit_renderer.py +++ b/strix/interface/tool_components/file_edit_renderer.py @@ -65,16 +65,16 @@ class StrReplaceEditorRenderer(BaseToolRenderer): text = Text() icons_and_labels = { - "view": ("πŸ“– ", "Reading file", "#10b981"), - "str_replace": ("✏️ ", "Editing file", "#10b981"), - "create": ("πŸ“ ", "Creating file", "#10b981"), - "insert": ("✏️ ", "Inserting text", "#10b981"), - "undo_edit": ("↩️ ", "Undoing edit", "#10b981"), + "view": ("β—‡ ", "read", "#10b981"), + "str_replace": ("β—‡ ", "edit", "#10b981"), + "create": ("β—‡ ", "create", "#10b981"), + "insert": ("β—‡ ", "insert", "#10b981"), + "undo_edit": ("β—‡ ", "undo", "#10b981"), } - icon, label, color = icons_and_labels.get(command, ("πŸ“„ ", "File operation", "#10b981")) - text.append(icon) - text.append(label, style=f"bold {color}") + icon, label, color = icons_and_labels.get(command, ("β—‡ ", "file", "#10b981")) + text.append(icon, style=color) + text.append(label, style="dim") if path: path_display = path[-60:] if len(path) > 60 else path @@ -158,23 +158,20 @@ class SearchFilesRenderer(BaseToolRenderer): regex = args.get("regex", "") text = Text() - text.append("πŸ” ") - text.append("Searching files", style="bold purple") - text.append(" ") + text.append("β—‡ ", style="#a855f7") + text.append("search", style="dim") + text.append(" ") if path and regex: text.append(path, style="dim") - text.append(" for '", style="dim") - text.append(regex, style="dim") - text.append("'", style="dim") + text.append(" ", style="dim") + text.append(regex, style="#a855f7") elif path: text.append(path, style="dim") elif regex: - text.append("'", style="dim") - text.append(regex, style="dim") - text.append("'", style="dim") + text.append(regex, style="#a855f7") else: - text.append("Searching...", style="dim") + text.append("...", style="dim") css_classes = cls.get_css_classes("completed") return Static(text, classes=css_classes) diff --git a/strix/interface/tool_components/finish_renderer.py b/strix/interface/tool_components/finish_renderer.py index 22beadd..17c8051 100644 --- a/strix/interface/tool_components/finish_renderer.py +++ b/strix/interface/tool_components/finish_renderer.py @@ -27,8 +27,8 @@ class FinishScanRenderer(BaseToolRenderer): recommendations = args.get("recommendations", "") text = Text() - text.append("🏁 ") - text.append("Finishing Scan", style="bold #dc2626") + text.append("β—† ", style="#22c55e") + text.append("Penetration test completed", style="bold #22c55e") if executive_summary: text.append("\n\n") diff --git a/strix/interface/tool_components/notes_renderer.py b/strix/interface/tool_components/notes_renderer.py index f7ac24d..f4fc1a3 100644 --- a/strix/interface/tool_components/notes_renderer.py +++ b/strix/interface/tool_components/notes_renderer.py @@ -21,8 +21,8 @@ class CreateNoteRenderer(BaseToolRenderer): category = args.get("category", "general") text = Text() - text.append("πŸ“ ") - text.append("Note", style="bold #fbbf24") + text.append("β—‡ ", style="#fbbf24") + text.append("note", style="dim") text.append(" ") text.append(f"({category})", style="dim") @@ -50,8 +50,8 @@ class DeleteNoteRenderer(BaseToolRenderer): @classmethod def render(cls, tool_data: dict[str, Any]) -> Static: # noqa: ARG003 text = Text() - text.append("πŸ“ ") - text.append("Note Removed", style="bold #94a3b8") + text.append("β—‡ ", style="#fbbf24") + text.append("note removed", style="dim") css_classes = cls.get_css_classes("completed") return Static(text, classes=css_classes) @@ -70,8 +70,8 @@ class UpdateNoteRenderer(BaseToolRenderer): content = args.get("content") text = Text() - text.append("πŸ“ ") - text.append("Note Updated", style="bold #fbbf24") + text.append("β—‡ ", style="#fbbf24") + text.append("note updated", style="dim") if title: text.append("\n ") @@ -99,8 +99,8 @@ class ListNotesRenderer(BaseToolRenderer): result = tool_data.get("result") text = Text() - text.append("πŸ“ ") - text.append("Notes", style="bold #fbbf24") + text.append("β—‡ ", style="#fbbf24") + text.append("notes", style="dim") if isinstance(result, str) and result.strip(): text.append("\n ") diff --git a/strix/interface/tool_components/scan_info_renderer.py b/strix/interface/tool_components/scan_info_renderer.py index 04477a6..fa5e4ce 100644 --- a/strix/interface/tool_components/scan_info_renderer.py +++ b/strix/interface/tool_components/scan_info_renderer.py @@ -19,7 +19,8 @@ class ScanStartInfoRenderer(BaseToolRenderer): targets = args.get("targets", []) text = Text() - text.append("πŸš€ Starting penetration test") + text.append("β—ˆ ", style="#22c55e") + text.append("Starting penetration test") if len(targets) == 1: text.append(" on ") diff --git a/strix/interface/tui.py b/strix/interface/tui.py index 6181b32..38aaad8 100644 --- a/strix/interface/tui.py +++ b/strix/interface/tui.py @@ -192,7 +192,7 @@ class SplashScreen(Static): # type: ignore[misc] class HelpScreen(ModalScreen): # type: ignore[misc] def compose(self) -> ComposeResult: yield Grid( - Label("πŸ¦‰ Strix Help", id="help_title"), + Label("Strix Help", id="help_title"), Label( "F1 Help\nCtrl+Q/C Quit\nESC Stop Agent\n" "Enter Send message to agent\nTab Switch panels\n↑/↓ Navigate tree", @@ -668,7 +668,7 @@ class QuitScreen(ModalScreen): # type: ignore[misc] class StrixTUIApp(App): # type: ignore[misc] CSS_PATH = "assets/tui_styles.tcss" - SIDEBAR_MIN_WIDTH = 100 + SIDEBAR_MIN_WIDTH = 140 selected_agent_id: reactive[str | None] = reactive(default=None) show_splash: reactive[bool] = reactive(default=True) @@ -795,7 +795,7 @@ class StrixTUIApp(App): # type: ignore[misc] chat_input.set_app_reference(self) chat_input_container = Horizontal(chat_prompt, chat_input, id="chat_input_container") - agents_tree = Tree("πŸ€– Active Agents", id="agents_tree") + agents_tree = Tree("Agents", id="agents_tree") agents_tree.root.expand() agents_tree.show_root = False @@ -911,16 +911,16 @@ class StrixTUIApp(App): # type: ignore[misc] status = agent_data.get("status", "running") status_indicators = { - "running": "🟒", - "waiting": "⏸️", - "completed": "βœ…", - "failed": "❌", - "stopped": "⏹️", - "stopping": "⏸️", - "llm_failed": "πŸ”΄", + "running": "●", + "waiting": "β—‹", + "completed": "β—†", + "failed": "β—‡", + "stopped": "β– ", + "stopping": "β—‹", + "llm_failed": "β—‡", } - status_icon = status_indicators.get(status, "πŸ”΅") + status_icon = status_indicators.get(status, "β—‹") vuln_count = self._agent_vulnerability_count(agent_id) vuln_indicator = f" ({vuln_count})" if vuln_count > 0 else "" agent_name = f"{status_icon} {agent_name_raw}{vuln_indicator}" @@ -1466,15 +1466,15 @@ class StrixTUIApp(App): # type: ignore[misc] agent_name_raw = agent_data.get("name", "Agent") status_indicators = { - "running": "🟒", - "waiting": "🟑", - "completed": "βœ…", - "failed": "❌", - "stopped": "⏹️", - "stopping": "⏸️", + "running": "●", + "waiting": "β—‹", + "completed": "β—†", + "failed": "β—‡", + "stopped": "β– ", + "stopping": "β—‹", } - status_icon = status_indicators.get(status, "πŸ”΅") + status_icon = status_indicators.get(status, "β—‹") vuln_count = self._agent_vulnerability_count(agent_id) vuln_indicator = f" ({vuln_count})" if vuln_count > 0 else "" agent_name = f"{status_icon} {agent_name_raw}{vuln_indicator}" @@ -1540,15 +1540,15 @@ class StrixTUIApp(App): # type: ignore[misc] status = agent_data.get("status", "running") status_indicators = { - "running": "🟒", - "waiting": "🟑", - "completed": "βœ…", - "failed": "❌", - "stopped": "⏹️", - "stopping": "⏸️", + "running": "●", + "waiting": "β—‹", + "completed": "β—†", + "failed": "β—‡", + "stopped": "β– ", + "stopping": "β—‹", } - status_icon = status_indicators.get(status, "πŸ”΅") + status_icon = status_indicators.get(status, "β—‹") vuln_count = self._agent_vulnerability_count(agent_id) vuln_indicator = f" ({vuln_count})" if vuln_count > 0 else "" agent_name = f"{status_icon} {agent_name_raw}{vuln_indicator}" diff --git a/strix/interface/utils.py b/strix/interface/utils.py index e678d15..fa5726c 100644 --- a/strix/interface/utils.py +++ b/strix/interface/utils.py @@ -208,7 +208,7 @@ def _build_vulnerability_stats(stats_text: Text, tracer: Any) -> None: if severity in severity_counts: severity_counts[severity] += 1 - stats_text.append("πŸ” Vulnerabilities Found: ", style="bold red") + stats_text.append("Vulnerabilities ", style="bold red") severity_parts = [] for severity in ["critical", "high", "medium", "low", "info"]: @@ -230,7 +230,7 @@ def _build_vulnerability_stats(stats_text: Text, tracer: Any) -> None: stats_text.append(")", style="dim white") stats_text.append("\n") else: - stats_text.append("πŸ” Vulnerabilities Found: ", style="bold green") + stats_text.append("Vulnerabilities ", style="bold #22c55e") stats_text.append("0", style="bold white") stats_text.append(" (No exploitable vulnerabilities detected)", style="dim green") stats_text.append("\n") @@ -240,29 +240,29 @@ def _build_llm_stats(stats_text: Text, total_stats: dict[str, Any]) -> None: """Build LLM usage section of stats text.""" if total_stats["requests"] > 0: stats_text.append("\n") - stats_text.append("πŸ“₯ Input Tokens: ", style="bold cyan") - stats_text.append(format_token_count(total_stats["input_tokens"]), style="bold white") + stats_text.append("Input Tokens ", style="dim") + stats_text.append(format_token_count(total_stats["input_tokens"]), style="white") if total_stats["cached_tokens"] > 0: - stats_text.append(" β€’ ", style="dim white") - stats_text.append("⚑ Cached Tokens: ", style="bold green") - stats_text.append(format_token_count(total_stats["cached_tokens"]), style="bold white") + stats_text.append(" Β· ", style="dim white") + stats_text.append("Cached Tokens ", style="dim") + stats_text.append(format_token_count(total_stats["cached_tokens"]), style="#22c55e") - stats_text.append(" β€’ ", style="dim white") - stats_text.append("πŸ“€ Output Tokens: ", style="bold cyan") - stats_text.append(format_token_count(total_stats["output_tokens"]), style="bold white") + stats_text.append(" Β· ", style="dim white") + stats_text.append("Output Tokens ", style="dim") + stats_text.append(format_token_count(total_stats["output_tokens"]), style="white") if total_stats["cost"] > 0: - stats_text.append(" β€’ ", style="dim white") - stats_text.append("πŸ’° Total Cost: ", style="bold cyan") - stats_text.append(f"${total_stats['cost']:.4f}", style="bold yellow") + stats_text.append(" Β· ", style="dim white") + stats_text.append("Cost ", style="dim") + stats_text.append(f"${total_stats['cost']:.4f}", style="bold #fbbf24") else: stats_text.append("\n") - stats_text.append("πŸ’° Total Cost: ", style="bold cyan") - stats_text.append("$0.0000 ", style="bold yellow") - stats_text.append("β€’ ", style="bold white") - stats_text.append("πŸ“Š Tokens: ", style="bold cyan") - stats_text.append("0", style="bold white") + stats_text.append("Cost ", style="dim") + stats_text.append("$0.0000 ", style="#fbbf24") + stats_text.append("Β· ", style="dim white") + stats_text.append("Tokens ", style="dim") + stats_text.append("0", style="white") def build_final_stats_text(tracer: Any) -> Text: @@ -276,10 +276,12 @@ def build_final_stats_text(tracer: Any) -> Text: tool_count = tracer.get_real_tool_count() agent_count = len(tracer.agents) - stats_text.append("πŸ€– Agents Used: ", style="bold cyan") + stats_text.append("Agents", style="dim") + stats_text.append(" ") stats_text.append(str(agent_count), style="bold white") - stats_text.append(" β€’ ", style="dim white") - stats_text.append("πŸ› οΈ Tools Called: ", style="bold cyan") + stats_text.append(" Β· ", style="dim white") + stats_text.append("Tools", style="dim") + stats_text.append(" ") stats_text.append(str(tool_count), style="bold white") llm_stats = tracer.get_total_llm_stats() @@ -296,15 +298,16 @@ def build_live_stats_text(tracer: Any, agent_config: dict[str, Any] | None = Non if agent_config: llm_config = agent_config["llm_config"] model = getattr(llm_config, "model_name", "Unknown") - stats_text.append(f"🧠 Model: {model}") + stats_text.append("Model ", style="dim") + stats_text.append(model, style="white") stats_text.append("\n") vuln_count = len(tracer.vulnerability_reports) tool_count = tracer.get_real_tool_count() agent_count = len(tracer.agents) - stats_text.append("πŸ” Vulnerabilities: ", style="bold white") - stats_text.append(f"{vuln_count}", style="dim white") + stats_text.append("Vulnerabilities ", style="dim") + stats_text.append(f"{vuln_count}", style="white") stats_text.append("\n") if vuln_count > 0: severity_counts = {"critical": 0, "high": 0, "medium": 0, "low": 0, "info": 0} @@ -330,33 +333,32 @@ def build_live_stats_text(tracer: Any, agent_config: dict[str, Any] | None = Non stats_text.append("\n") - stats_text.append("πŸ€– Agents: ", style="bold white") - stats_text.append(str(agent_count), style="dim white") - stats_text.append(" β€’ ", style="dim white") - stats_text.append("πŸ› οΈ Tools: ", style="bold white") - stats_text.append(str(tool_count), style="dim white") + stats_text.append("Agents ", style="dim") + stats_text.append(str(agent_count), style="white") + stats_text.append(" Β· ", style="dim white") + stats_text.append("Tools ", style="dim") + stats_text.append(str(tool_count), style="white") llm_stats = tracer.get_total_llm_stats() total_stats = llm_stats["total"] stats_text.append("\n") - stats_text.append("πŸ“₯ Input: ", style="bold white") - stats_text.append(format_token_count(total_stats["input_tokens"]), style="dim white") + stats_text.append("Input Tokens ", style="dim") + stats_text.append(format_token_count(total_stats["input_tokens"]), style="white") - stats_text.append(" β€’ ", style="dim white") - stats_text.append("⚑ ", style="bold white") - stats_text.append("Cached: ", style="bold white") - stats_text.append(format_token_count(total_stats["cached_tokens"]), style="dim white") + stats_text.append(" Β· ", style="dim white") + stats_text.append("Cached Tokens ", style="dim") + stats_text.append(format_token_count(total_stats["cached_tokens"]), style="#22c55e") stats_text.append("\n") - stats_text.append("πŸ“€ Output: ", style="bold white") - stats_text.append(format_token_count(total_stats["output_tokens"]), style="dim white") + stats_text.append("Output Tokens ", style="dim") + stats_text.append(format_token_count(total_stats["output_tokens"]), style="white") - stats_text.append(" β€’ ", style="dim white") - stats_text.append("πŸ’° Cost: ", style="bold white") - stats_text.append(f"${total_stats['cost']:.4f}", style="dim white") + stats_text.append(" Β· ", style="dim white") + stats_text.append("Cost ", style="dim") + stats_text.append(f"${total_stats['cost']:.4f}", style="#fbbf24") return stats_text @@ -668,7 +670,6 @@ def clone_repository(repo_url: str, run_name: str, dest_name: str | None = None) except subprocess.CalledProcessError as e: error_text = Text() - error_text.append("❌ ", style="bold red") error_text.append("REPOSITORY CLONE FAILED", style="bold red") error_text.append("\n\n", style="white") error_text.append(f"Could not clone repository: {repo_url}\n", style="white") @@ -678,8 +679,8 @@ def clone_repository(repo_url: str, run_name: str, dest_name: str | None = None) panel = Panel( error_text, - title="[bold red]πŸ›‘οΈ STRIX CLONE ERROR", - title_align="center", + title="[bold white]STRIX", + title_align="left", border_style="red", padding=(1, 2), ) @@ -689,7 +690,6 @@ def clone_repository(repo_url: str, run_name: str, dest_name: str | None = None) sys.exit(1) except FileNotFoundError: error_text = Text() - error_text.append("❌ ", style="bold red") error_text.append("GIT NOT FOUND", style="bold red") error_text.append("\n\n", style="white") error_text.append("Git is not installed or not available in PATH.\n", style="white") @@ -697,8 +697,8 @@ def clone_repository(repo_url: str, run_name: str, dest_name: str | None = None) panel = Panel( error_text, - title="[bold red]πŸ›‘οΈ STRIX CLONE ERROR", - title_align="center", + title="[bold white]STRIX", + title_align="left", border_style="red", padding=(1, 2), ) @@ -715,7 +715,6 @@ def check_docker_connection() -> Any: except DockerException: console = Console() error_text = Text() - error_text.append("❌ ", style="bold red") error_text.append("DOCKER NOT AVAILABLE", style="bold red") error_text.append("\n\n", style="white") error_text.append("Cannot connect to Docker daemon.\n", style="white") @@ -726,8 +725,8 @@ def check_docker_connection() -> Any: panel = Panel( error_text, - title="[bold red]πŸ›‘οΈ STRIX STARTUP ERROR", - title_align="center", + title="[bold white]STRIX", + title_align="left", border_style="red", padding=(1, 2), )