chore: Bump version to 0.1.19 and enhance splash screen

This commit is contained in:
Ahmed Allam
2025-10-29 02:15:30 +03:00
parent 96f5c44799
commit a4712b7b78
2 changed files with 93 additions and 15 deletions

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "strix-agent" name = "strix-agent"
version = "0.1.18" version = "0.1.19"
description = "Open-source AI Hackers for your apps" description = "Open-source AI Hackers for your apps"
authors = ["Strix <hi@usestrix.com>"] authors = ["Strix <hi@usestrix.com>"]
readme = "README.md" readme = "README.md"

View File

@@ -7,9 +7,19 @@ import signal
import sys import sys
import threading import threading
from collections.abc import Callable from collections.abc import Callable
from typing import Any, ClassVar, cast from importlib.metadata import PackageNotFoundError
from importlib.metadata import version as pkg_version
from typing import TYPE_CHECKING, Any, ClassVar, cast
if TYPE_CHECKING:
from textual.timer import Timer
from rich.align import Align
from rich.console import Group
from rich.markup import escape as rich_escape from rich.markup import escape as rich_escape
from rich.panel import Panel
from rich.style import Style
from rich.text import Text from rich.text import Text
from textual import events, on from textual import events, on
from textual.app import App, ComposeResult from textual.app import App, ComposeResult
@@ -29,6 +39,13 @@ def escape_markup(text: str) -> str:
return cast("str", rich_escape(text)) return cast("str", rich_escape(text))
def get_package_version() -> str:
try:
return pkg_version("strix-agent")
except PackageNotFoundError:
return "dev"
class ChatTextArea(TextArea): # type: ignore[misc] class ChatTextArea(TextArea): # type: ignore[misc]
def __init__(self, *args: Any, **kwargs: Any) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@@ -53,24 +70,85 @@ class ChatTextArea(TextArea): # type: ignore[misc]
class SplashScreen(Static): # type: ignore[misc] class SplashScreen(Static): # type: ignore[misc]
PRIMARY_GREEN = "#22c55e"
BANNER = (
" ███████╗████████╗██████╗ ██╗██╗ ██╗\n"
" ██╔════╝╚══██╔══╝██╔══██╗██║╚██╗██╔╝\n"
" ███████╗ ██║ ██████╔╝██║ ╚███╔╝\n"
" ╚════██║ ██║ ██╔══██╗██║ ██╔██╗\n"
" ███████║ ██║ ██║ ██║██║██╔╝ ██╗\n"
" ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝"
)
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self._animation_step = 0
self._animation_timer: Timer | None = None
self._panel_static: Static | None = None
self._version = "dev"
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
ascii_art = r""" self._version = get_package_version()
[bright_green] self._animation_step = 0
start_line = self._build_start_line_text(self._animation_step)
panel = self._build_panel(start_line)
panel_static = Static(panel, id="splash_content")
self._panel_static = panel_static
yield panel_static
███████╗████████╗██████╗ ██╗██╗ ██╗ def on_mount(self) -> None:
██╔════╝╚══██╔══╝██╔══██╗██║╚██╗██╔╝ self._animation_timer = self.set_interval(0.45, self._animate_start_line)
███████╗ ██║ ██████╔╝██║ ╚███╔╝
╚════██║ ██║ ██╔══██╗██║ ██╔██╗
███████║ ██║ ██║ ██║██║██╔╝ ██╗
╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝
def on_unmount(self) -> None:
if self._animation_timer is not None:
self._animation_timer.stop()
self._animation_timer = None
[/bright_green] def _animate_start_line(self) -> None:
if not self._panel_static:
return
[bright_green]Starting Strix Cybersecurity Agent...[/bright_green] self._animation_step += 1
""" start_line = self._build_start_line_text(self._animation_step)
yield Static(ascii_art, id="splash_content") panel = self._build_panel(start_line)
self._panel_static.update(panel)
def _build_panel(self, start_line: Text) -> Panel:
content = Group(
Align.center(Text(self.BANNER.strip("\n"), style=self.PRIMARY_GREEN, justify="center")),
Align.center(Text(" ")),
Align.center(self._build_welcome_text()),
Align.center(self._build_version_text()),
Align.center(self._build_tagline_text()),
Align.center(Text(" ")),
Align.center(start_line.copy()),
)
return Panel.fit(content, border_style=self.PRIMARY_GREEN, padding=(1, 6))
def _build_welcome_text(self) -> Text:
text = Text("Welcome to ", style=Style(color="white", bold=True))
text.append("Strix", style=Style(color=self.PRIMARY_GREEN, bold=True))
text.append("!", style=Style(color="white", bold=True))
return text
def _build_version_text(self) -> Text:
return Text(f"v{self._version}", style=Style(color="white", dim=True))
def _build_tagline_text(self) -> Text:
return Text("Open-source AI hackers for your apps", style=Style(color="white", dim=True))
def _build_start_line_text(self, phase: int) -> Text:
emphasize = phase % 2 == 1
base_style = Style(color="white", dim=not emphasize, bold=emphasize)
strix_style = Style(color=self.PRIMARY_GREEN, bold=bool(emphasize))
text = Text("Starting ", style=base_style)
text.append("Strix", style=strix_style)
text.append(" Cybersecurity Agent", style=base_style)
return text
class HelpScreen(ModalScreen): # type: ignore[misc] class HelpScreen(ModalScreen): # type: ignore[misc]
@@ -362,7 +440,7 @@ class StrixCLIApp(App): # type: ignore[misc]
def on_mount(self) -> None: def on_mount(self) -> None:
self.title = "strix" self.title = "strix"
self.set_timer(3.0, self._hide_splash_screen) self.set_timer(4.5, self._hide_splash_screen)
def _hide_splash_screen(self) -> None: def _hide_splash_screen(self) -> None:
self.show_splash = False self.show_splash = False