chore: Bump version to 0.1.19 and enhance splash screen
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
106
strix/cli/app.py
106
strix/cli/app.py
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user