"""Rich terminal display helpers for SneakyCode.""" from rich.panel import Panel from rich.table import Table from rich.theme import Theme from app.models.message import Message from app.utils.logging import console # Custom theme for consistent styling across the application SNEAKYCODE_THEME = Theme( { "info": "cyan", "warning": "yellow", "error": "bold red", "success": "bold green", "tool": "magenta", "dim": "dim white", } ) # Apply the theme to the shared console console.push_theme(SNEAKYCODE_THEME) def print_banner() -> None: """Print the SneakyCode startup banner.""" console.print( "\n[bold cyan] SneakyCode[/bold cyan] [dim]— Local AI Coding Agent[/dim]\n", ) def print_info(message: str) -> None: """Print an informational message.""" console.print(f"[info]{message}[/info]") def print_warning(message: str) -> None: """Print a warning message.""" console.print(f"[warning]⚠ {message}[/warning]") def print_error(message: str) -> None: """Print an error message.""" console.print(f"[error]✗ {message}[/error]") def print_success(message: str) -> None: """Print a success message.""" console.print(f"[success]✓ {message}[/success]") def print_user_message(content: str) -> None: """Print a user message in a styled panel.""" console.print(Panel(content, title="You", border_style="cyan", expand=False)) def print_assistant_message(content: str) -> None: """Print an assistant message in a styled panel.""" console.print(Panel(content, title="Assistant", border_style="green", expand=False)) def print_tool_call(name: str, args: str) -> None: """Print a tool call summary (stub for Phase 4).""" console.print(f"[tool]Tool: {name}[/tool] [dim]{args}[/dim]") def print_token_usage(usage_tokens: int, budget: int) -> None: """Print current token usage against budget.""" console.print(f"[dim]Tokens: ~{usage_tokens:,} / {budget:,}[/dim]") def print_history(messages: list[Message]) -> None: """Print conversation history as a Rich table. Args: messages: List of conversation messages to display. """ if not messages: console.print("[dim]No messages in history.[/dim]") return table = Table(title="Conversation History") table.add_column("#", style="dim", width=4) table.add_column("Role", width=10) table.add_column("Content") role_styles = { "user": "cyan", "assistant": "green", "system": "yellow", "tool": "magenta", } for i, msg in enumerate(messages, 1): style = role_styles.get(msg.role, "white") content = msg.content or "[dim](no content)[/dim]" # Truncate long content for display if len(content) > 120: content = content[:117] + "..." table.add_row(str(i), f"[{style}]{msg.role}[/{style}]", content) console.print(table)