"""
Core TUI interface coordination and lifecycle management.
"""
import os
import signal
import time
try:
from rich.console import Console
from rich.live import Live
from rich.panel import Panel
RICH_AVAILABLE = True
except ImportError:
RICH_AVAILABLE = False
try:
from textual.app import App
TEXTUAL_AVAILABLE = True
except ImportError:
TEXTUAL_AVAILABLE = False
from .components import ComponentBuilder
from .data_manager import DataManager
from .fallback import FallbackInterface
from .layouts import LayoutManager
[docs]
class ModernTUIInterface:
"""Modern TUI interface for OrKa memory monitoring."""
def __init__(self):
self.console = Console() if RICH_AVAILABLE else None
self.running = False
self.refresh_interval = 2.0
self.current_view = "dashboard" # dashboard, memories, performance, config
self.selected_row = 0
self.filter_text = ""
# Initialize components
self.data_manager = DataManager()
self.components = ComponentBuilder(self.data_manager)
self.layouts = LayoutManager(self.components)
self.fallback = FallbackInterface()
# Share running state with data manager
self.data_manager.running = True
[docs]
def run(self, args):
"""Main entry point for the TUI interface."""
if not RICH_AVAILABLE:
print("â Modern TUI requires 'rich' library. Install with: pip install rich")
print("Falling back to basic interface...")
return self.fallback.run_basic_fallback(args)
try:
# Initialize memory logger
self.data_manager.init_memory_logger(args)
# Setup signal handlers
signal.signal(signal.SIGINT, self._signal_handler)
# Start monitoring
self.running = True
self.data_manager.running = True
self.refresh_interval = getattr(args, "interval", 2.0)
# Default to Textual interface (new primary interface)
use_rich_fallback = (
getattr(args, "use_rich", False)
or getattr(args, "fallback", False)
or os.getenv("ORKA_TUI_MODE", "").lower() == "rich"
)
if not TEXTUAL_AVAILABLE:
if self.console:
self.console.print(
"[yellow]â ī¸ Textual not available. Using Rich fallback interface.[/yellow]",
)
self.console.print("[blue]đĄ Install with: pip install textual[/blue]")
return self._run_rich_interface(args)
elif use_rich_fallback:
if self.console:
self.console.print("[blue]âšī¸ Using Rich fallback interface.[/blue]")
return self._run_rich_interface(args)
else:
# Default to new Textual interface
return self._run_textual_interface(args)
except Exception as e:
if self.console:
self.console.print(f"[red]â Error in TUI interface: {e}[/red]")
else:
print(f"â Error in TUI interface: {e}")
import traceback
traceback.print_exc()
return 1
def _signal_handler(self, signum, frame):
"""Handle interrupt signals gracefully."""
self.running = False
self.data_manager.running = False
def _run_rich_interface(self, args):
"""Run the rich-based interface with live updates."""
try:
with Live(
self.layouts.get_view(self.current_view),
console=self.console,
refresh_per_second=0.5, # Slower refresh to prevent jumping
screen=True,
vertical_overflow="crop", # Prevent overflow
) as live:
while self.running:
try:
# Update data
self.data_manager.update_data()
# Update display based on current view
live.update(self.layouts.get_view(self.current_view))
time.sleep(max(self.refresh_interval, 2.0)) # Minimum 2 second intervals
except KeyboardInterrupt:
break
except Exception as e:
live.update(Panel(f"[red]Error: {e}[/red]", title="Error"))
time.sleep(self.refresh_interval)
except KeyboardInterrupt:
pass
self.console.print("\n[green]đ OrKa TUI monitoring stopped[/green]")
return 0
def _run_textual_interface(self, args):
"""Run the textual-based interface (more interactive)."""
try:
# Import the new Textual app
from .textual_app import OrKaTextualApp
app = OrKaTextualApp(self.data_manager)
app.run()
return 0
except ImportError as e:
if self.console:
self.console.print(f"[red]Failed to load Textual interface: {e}[/red]")
self.console.print("[yellow]Falling back to Rich interface...[/yellow]")
# Fallback to rich interface
return self._run_rich_interface(args)