diff --git a/src/memory_manager/tui/app.py b/src/memory_manager/tui/app.py new file mode 100644 index 0000000..0e1f6eb --- /dev/null +++ b/src/memory_manager/tui/app.py @@ -0,0 +1,103 @@ +"""Textual TUI application.""" +import os +import asyncio +from typing import Optional + +from textual.app import App, ComposeResult +from textual.widgets import Header, Footer, DataTable, Static, Tabs, Tab +from textual.containers import Container, VerticalScroll +from textual.screen import Screen + +from memory_manager.core.services import MemoryService, CommitService +from memory_manager.db.repository import MemoryRepository + + +db_path = os.getenv("MEMORY_DB_PATH", ".memory/codebase_memory.db") +os.makedirs(os.path.dirname(db_path), exist_ok=True) + +repository = MemoryRepository(db_path) +memory_service = MemoryService(repository) +commit_service = CommitService(repository) + + +class DashboardScreen(Screen): + def compose(self) -> ComposeResult: + yield Header() + yield Static("Memory Manager Dashboard", id="title") + yield DataTable() + yield Footer() + + async def on_mount(self): + stats = await repository.get_stats() + table = self.query_one(DataTable) + table.add_columns("Metric", "Value") + table.add_row("Total Entries", str(stats["total_entries"])) + table.add_row("Total Commits", str(stats["total_commits"])) + for category, count in stats["category_counts"].items(): + table.add_row(category.title(), str(count)) + + +class MemoryListScreen(Screen): + def compose(self) -> ComposeResult: + yield Header() + yield Static("Memory Entries", id="title") + yield DataTable() + yield Footer() + + async def on_mount(self): + entries = await memory_service.list_entries(limit=100) + table = self.query_one(DataTable) + table.add_columns("ID", "Category", "Title", "Agent") + for entry in entries: + table.add_row( + str(entry.id), + entry.category.value, + entry.title[:40], + entry.agent_id, + ) + + +class CommitHistoryScreen(Screen): + def compose(self) -> ComposeResult: + yield Header() + yield Static("Commit History", id="title") + yield DataTable() + yield Footer() + + async def on_mount(self): + commits = await commit_service.get_commits(limit=50) + table = self.query_one(DataTable) + table.add_columns("Hash", "Message", "Agent", "Date") + for commit in commits: + table.add_row( + commit.hash[:8], + commit.message[:40], + commit.agent_id, + str(commit.created_at)[:10], + ) + + +class MemoryTUIApp(App): + def __init__(self): + super().__init__() + self.title = "Memory Manager TUI" + self.SCREENS = { + "dashboard": DashboardScreen(), + "list": MemoryListScreen(), + "history": CommitHistoryScreen(), + } + + def on_mount(self): + self.push_screen("dashboard") + + def compose(self) -> ComposeResult: + yield Tabs( + Tab("Dashboard", id="dashboard"), + Tab("Entries", id="list"), + Tab("History", id="history"), + ) + + +def run_tui(): + app = MemoryTUIApp() + app.run()