# LAIDA Mission Control TUI - Roadmap de Implementación

## Resumen Ejecutivo

Este documento detalla el plan de implementación para la interfaz "Mission Control" TUI (Text User Interface) de LAIDA CLI v3. El objetivo es transformar la terminal en un cuadro de mandos inmersivo con telemetría en tiempo real.

**Principio Fundamental**: La TUI es una capa de presentación alternativa. NO modifica la arquitectura existente. Se integra mediante los mismos puertos y servicios que los comandos CLI actuales.

---

## 1. Arquitectura Actual (Baseline)

### 1.1 Estructura de Capas Existente

```
src/laida_cli/
├── domain/              # Capa de Dominio (Value Objects, Aggregates)
│   ├── phase_number.py
│   ├── step_number.py
│   ├── execution_status.py
│   ├── execution_result.py
│   ├── phase_execution.py
│   ├── project_path.py
│   └── validation_result.py
│
├── ports/               # Puertos (Contratos/Protocolos)
│   ├── claude_code_port.py    # ClaudeCodePort, ClaudeCodeAuthError
│   ├── file_system_port.py
│   └── yaml_port.py
│
├── adapters/            # Adaptadores (Implementaciones de Puertos)
│   ├── claude_code_adapter.py # ClaudeCodeSubprocessAdapter
│   ├── file_system_adapter.py
│   ├── yaml_adapter.py
│   └── schema_adapter.py
│
├── services/            # Servicios de Aplicación (Orquestación)
│   ├── execute_phase.py       # ExecutePhaseService
│   ├── invoke_claude_code.py  # InvokeClaudeCodeService
│   ├── detect_state.py        # DetectStateService
│   ├── detect_completion.py
│   ├── manage_context.py
│   ├── context_validator.py
│   └── traceability_checker.py
│
├── commands/            # Comandos CLI (Click) - CAPA DE PRESENTACIÓN
│   ├── init.py
│   ├── login.py
│   ├── run.py
│   ├── status.py
│   └── validate.py
│
├── ui/                  # Componentes UI (Rich)
│   ├── theme.py         # LAIDA_THEME, Styles
│   ├── console.py       # LaidaConsole
│   └── streaming.py     # StreamingPanel
│
├── banner.py
└── main.py              # Entry point CLI
```

### 1.2 Diagrama de Dependencias Actual

```
┌─────────────────────────────────────────────────────────────────────────┐
│                         CAPA DE PRESENTACIÓN                            │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  commands/          │  ui/              │  banner.py  │  main.py │   │
│  │  (Click handlers)   │  (Rich components)│             │          │   │
│  └─────────────────────────────────────────────────────────────────┘    │
└───────────────────────────────┬─────────────────────────────────────────┘
                                │ usa
                                ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         CAPA DE APLICACIÓN                              │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  services/                                                       │   │
│  │  ExecutePhaseService, DetectStateService, InvokeClaudeCodeService│   │
│  └─────────────────────────────────────────────────────────────────┘    │
└───────────────────────────────┬─────────────────────────────────────────┘
                                │ usa
                                ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         CAPA DE INFRAESTRUCTURA                         │
│  ┌───────────────────────┐         ┌───────────────────────────────┐    │
│  │  ports/ (Contratos)   │◄────────│  adapters/ (Implementaciones) │    │
│  │  ClaudeCodePort       │         │  ClaudeCodeSubprocessAdapter  │    │
│  │  FileSystemPort       │         │  FileSystemAdapter            │    │
│  └───────────────────────┘         └───────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         CAPA DE DOMINIO                                 │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │  domain/                                                         │   │
│  │  PhaseNumber, StepNumber, ExecutionResult, PhaseExecution        │   │
│  └─────────────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────────────┘
```

### 1.3 Principio de No Contaminación

La TUI se implementará como **otra capa de presentación paralela**:

```
┌─────────────────────────────────────────────────────────────────────────┐
│                         CAPA DE PRESENTACIÓN                            │
│  ┌────────────────────────┐    ┌────────────────────────────────────┐   │
│  │  CLI MODE (actual)     │    │  TUI MODE (nuevo)                  │   │
│  │  commands/ + ui/       │    │  tui/                              │   │
│  │  main.py               │    │  tui_main.py                       │   │
│  └────────────────────────┘    └────────────────────────────────────┘   │
│              │                              │                           │
│              └──────────────┬───────────────┘                           │
│                             ▼                                           │
│                    MISMOS SERVICIOS                                     │
└─────────────────────────────────────────────────────────────────────────┘
```

**Regla de Oro**: Ningún archivo existente en `services/`, `ports/`, `adapters/`, o `domain/` será modificado para la TUI. Toda la lógica TUI vive en `tui/`.

---

## 2. Diseño de la TUI

### 2.1 Layout Visual Final

```
┌─── LAIDA Mission Control ──────────────────────────────────────────────────┐
│                                                                            │
│  ┌─── Context Panel (30%) ─────┬─── Main Viewer (70%) ─────────────────┐  │
│  │                             │                                        │  │
│  │  📂 PROJECT FILES           │  ┌─── Claude Live Feed ─────────────┐ │  │
│  │  ┌ outputs/phase0/          │  │                                   │ │  │
│  │  │ ├─ step0_profiling/      │  │  > Reading project_context.yaml  │ │  │
│  │  │ │   ├─ _index.yaml       │  │  > [THOUGHT] Analyzing scale...  │ │  │
│  │  │ │   └─ project_scale.yaml│  │  > Writing methodology_config... │ │  │
│  │  │ └─ step1_foundation/     │  │  > Validating output... OK       │ │  │
│  │  │     └─ (pending)         │  │  _                                │ │  │
│  │  │                          │  │                                   │ │  │
│  │  ─────────────────────────  │  └───────────────────────────────────┘ │  │
│  │                             │                                        │  │
│  │  🔀 GIT STATUS              │  ┌─── Quick Actions ─────────────────┐ │  │
│  │  Branch: main               │  │  [R] Run Next  [S] Status         │ │  │
│  │  Status: Clean ✔            │  │  [V] Validate  [L] Login          │ │  │
│  │                             │  │  [Q] Quit      [?] Help           │ │  │
│  │  ─────────────────────────  │  └───────────────────────────────────┘ │  │
│  │                             │                                        │  │
│  │  📊 PROJECT PROGRESS        │                                        │  │
│  │  Phase 0 Step 1             │                                        │  │
│  │  [████████░░░░░░░░] 40%     │                                        │  │
│  │  8/20 steps completed       │                                        │  │
│  │                             │                                        │  │
│  └─────────────────────────────┴────────────────────────────────────────┘  │
│                                                                            │
├─── Telemetry Bar ──────────────────────────────────────────────────────────┤
│  ✔ Last: P0-S0 OK │ 🕒 Session: 00:14:32 │ ⚡ Task: 00:00:45 │ 📦 RAM: 24MB │
└────────────────────────────────────────────────────────────────────────────┘
```

### 2.2 Estructura de Archivos TUI (Nueva)

```
src/laida_cli/
├── tui/                          # NUEVO - Todo el código TUI aquí
│   ├── __init__.py
│   ├── app.py                    # TUIApp - Aplicación principal Textual
│   ├── screens/
│   │   ├── __init__.py
│   │   ├── main_screen.py        # Pantalla principal Mission Control
│   │   └── execution_screen.py   # Pantalla durante ejecución
│   ├── widgets/
│   │   ├── __init__.py
│   │   ├── file_tree.py          # Widget árbol de archivos
│   │   ├── git_status.py         # Widget estado Git
│   │   ├── progress_bar.py       # Widget progreso proyecto
│   │   ├── live_feed.py          # Widget streaming Claude
│   │   ├── quick_actions.py      # Widget acciones rápidas
│   │   └── telemetry_bar.py      # Widget barra telemetría
│   ├── services/
│   │   ├── __init__.py
│   │   ├── file_watcher.py       # Servicio vigilante archivos
│   │   ├── git_service.py        # Servicio consulta Git
│   │   └── telemetry_service.py  # Servicio métricas sistema
│   └── theme.py                  # Tema Textual (extiende ui/theme.py)
│
├── tui_main.py                   # Entry point TUI: `laida tui`
│
└── ... (estructura existente sin modificar)
```

### 2.3 Nuevos Puertos (Opcional - Solo si necesario)

Si la TUI requiere contratos adicionales, se añaden a `ports/` sin modificar los existentes:

```python
# ports/file_watcher_port.py (NUEVO)
class FileWatcherPort(Protocol):
    def watch(self, path: Path, callback: Callable[[FileEvent], None]) -> None: ...
    def stop(self) -> None: ...

# ports/system_metrics_port.py (NUEVO)
class SystemMetricsPort(Protocol):
    def get_memory_usage(self) -> int: ...
    def get_process_info(self) -> ProcessInfo: ...
```

**Nota**: Estos puertos son OPCIONALES. Solo se crean si la TUI necesita abstracciones que no existen.

---

## 3. Dependencias Nuevas

### 3.1 Paquetes Requeridos

```toml
# pyproject.toml - Añadir a [project.dependencies]
dependencies = [
    # ... existentes ...
    "textual>=0.50.0",      # Framework TUI reactivo (basado en Rich)
    "watchdog>=4.0.0",      # File system events (cross-platform)
    "psutil>=5.9.0",        # System/process metrics
]

# Opcional: grupo separado para TUI
[project.optional-dependencies]
tui = [
    "textual>=0.50.0",
    "watchdog>=4.0.0",
    "psutil>=5.9.0",
]
```

### 3.2 Justificación de Dependencias

| Paquete | Propósito | Alternativas | Decisión |
|---------|-----------|--------------|----------|
| `textual` | Framework TUI | `urwid`, `blessed` | Textual es de los creadores de Rich, integración nativa |
| `watchdog` | File events | `inotify` (Linux only) | Cross-platform, bien mantenido |
| `psutil` | System metrics | `/proc` parsing | Cross-platform, API limpia |

---

## 4. Fases de Implementación

### Fase 0: Preparación (Pre-requisitos)

**Objetivo**: Establecer la infraestructura base sin romper nada.

#### Tareas

| ID | Tarea | Descripción | Archivos |
|----|-------|-------------|----------|
| P0-01 | Crear estructura directorios | Crear `tui/`, `tui/widgets/`, `tui/screens/`, `tui/services/` | Directorios |
| P0-02 | Añadir dependencias | Actualizar `pyproject.toml` con grupo `[tui]` | `pyproject.toml` |
| P0-03 | Crear `__init__.py` | Inicializar paquetes TUI | `tui/__init__.py`, etc. |
| P0-04 | Verificar imports | Asegurar que TUI puede importar servicios existentes | Tests |

#### Criterio de Aceptación
- [ ] `pip install -e ".[tui]"` funciona sin errores
- [ ] `from laida_cli.services import DetectStateService` funciona desde TUI
- [ ] Tests existentes siguen pasando (74 tests)

---

### Fase 1: Telemetry Bar (Foundation)

**Objetivo**: Crear el componente más simple para validar el stack Textual.

#### Diseño del Componente

```python
# tui/widgets/telemetry_bar.py
class TelemetryBar(Static):
    """Barra inferior con métricas en tiempo real."""

    # Reactive attributes (se actualizan automáticamente)
    last_result: reactive[str] = reactive("--")
    session_time: reactive[str] = reactive("00:00:00")
    task_time: reactive[str] = reactive("--:--")
    memory_mb: reactive[int] = reactive(0)
```

#### Tareas

| ID | Tarea | Descripción | Archivos |
|----|-------|-------------|----------|
| P1-01 | Crear TelemetryService | Servicio que recolecta métricas del sistema | `tui/services/telemetry_service.py` |
| P1-02 | Crear TelemetryBar widget | Widget Textual con reactive attributes | `tui/widgets/telemetry_bar.py` |
| P1-03 | Crear TUIApp básica | App Textual minimal con solo TelemetryBar | `tui/app.py` |
| P1-04 | Crear entry point | Comando `laida tui` que lanza la app | `tui_main.py`, `main.py` |
| P1-05 | Tests unitarios | Tests para TelemetryService | `tests/unit/tui/` |

#### Código Ejemplo

```python
# tui/services/telemetry_service.py
import psutil
import time
from dataclasses import dataclass

@dataclass
class TelemetryData:
    session_start: float
    task_start: float | None
    last_result: str
    memory_mb: int

class TelemetryService:
    def __init__(self) -> None:
        self._session_start = time.time()
        self._task_start: float | None = None
        self._last_result = "--"

    def start_task(self) -> None:
        self._task_start = time.time()

    def end_task(self, success: bool, phase: int, step: int) -> None:
        status = "✔" if success else "✘"
        self._last_result = f"{status} P{phase}-S{step}"
        self._task_start = None

    def get_data(self) -> TelemetryData:
        process = psutil.Process()
        return TelemetryData(
            session_start=self._session_start,
            task_start=self._task_start,
            last_result=self._last_result,
            memory_mb=process.memory_info().rss // (1024 * 1024),
        )
```

#### Criterio de Aceptación
- [ ] `laida tui` abre una ventana con la barra de telemetría
- [ ] El reloj de sesión avanza en tiempo real
- [ ] La memoria se actualiza cada segundo
- [ ] `q` cierra la aplicación

---

### Fase 2: Layout Base + Progress Panel

**Objetivo**: Establecer el grid de 2 columnas y añadir el panel de progreso.

#### Diseño del Layout

```python
# tui/screens/main_screen.py
class MainScreen(Screen):
    def compose(self) -> ComposeResult:
        yield Header()
        with Horizontal():
            with Vertical(id="sidebar"):
                yield ProgressPanel()
                # ... más widgets después
            with Vertical(id="main"):
                yield Placeholder("Main Viewer")
        yield TelemetryBar()
```

#### Tareas

| ID | Tarea | Descripción | Archivos |
|----|-------|-------------|----------|
| P2-01 | Crear MainScreen | Screen con layout grid 30/70 | `tui/screens/main_screen.py` |
| P2-02 | Crear ProgressPanel | Widget con barra de progreso | `tui/widgets/progress_panel.py` |
| P2-03 | Integrar DetectStateService | Usar servicio existente para obtener progreso | `tui/widgets/progress_panel.py` |
| P2-04 | Crear CSS tema | Estilos Textual que usan colores de `ui/theme.py` | `tui/theme.tcss` |
| P2-05 | Tests de integración | Verificar que ProgressPanel usa DetectStateService | Tests |

#### Integración con Servicios Existentes

```python
# tui/widgets/progress_panel.py
from laida_cli.services.detect_state import DetectStateService

class ProgressPanel(Static):
    def __init__(self, project_path: Path) -> None:
        super().__init__()
        self._state_service = DetectStateService()  # REUTILIZA servicio existente
        self._project_path = project_path

    def update_progress(self) -> None:
        state = self._state_service.detect(self._project_path)
        # Actualizar UI con state.next_phase, state.next_step, etc.
```

#### Criterio de Aceptación
- [ ] Layout 30/70 visible
- [ ] Barra de progreso muestra datos reales del proyecto
- [ ] Integración con DetectStateService funciona
- [ ] Estilos consistentes con tema LAIDA

---

### Fase 3: Git Status Widget

**Objetivo**: Añadir información de Git al panel lateral.

#### Tareas

| ID | Tarea | Descripción | Archivos |
|----|-------|-------------|----------|
| P3-01 | Crear GitService | Servicio que consulta estado Git | `tui/services/git_service.py` |
| P3-02 | Crear GitStatusWidget | Widget que muestra branch y status | `tui/widgets/git_status.py` |
| P3-03 | Añadir al sidebar | Integrar en MainScreen | `tui/screens/main_screen.py` |
| P3-04 | Auto-refresh | Actualizar cada 5 segundos | Timer |

#### Código Ejemplo

```python
# tui/services/git_service.py
import subprocess
from dataclasses import dataclass

@dataclass
class GitStatus:
    branch: str
    is_clean: bool
    changed_files: int

class GitService:
    def get_status(self, path: Path) -> GitStatus | None:
        try:
            branch = subprocess.run(
                ["git", "rev-parse", "--abbrev-ref", "HEAD"],
                cwd=path, capture_output=True, text=True
            ).stdout.strip()

            status = subprocess.run(
                ["git", "status", "--porcelain"],
                cwd=path, capture_output=True, text=True
            ).stdout

            changed = len([l for l in status.splitlines() if l.strip()])

            return GitStatus(
                branch=branch,
                is_clean=changed == 0,
                changed_files=changed,
            )
        except FileNotFoundError:
            return None  # Git no instalado
```

#### Criterio de Aceptación
- [ ] Muestra rama actual
- [ ] Indica si hay cambios pendientes
- [ ] Funciona sin Git instalado (muestra "N/A")

---

### Fase 4: File Tree Widget

**Objetivo**: Implementar el árbol de archivos con watch en tiempo real.

#### Tareas

| ID | Tarea | Descripción | Archivos |
|----|-------|-------------|----------|
| P4-01 | Crear FileWatcherService | Servicio con watchdog para eventos FS | `tui/services/file_watcher.py` |
| P4-02 | Crear FileTreeWidget | Widget árbol con Rich Tree | `tui/widgets/file_tree.py` |
| P4-03 | Implementar debounce | Evitar actualizaciones excesivas | `tui/services/file_watcher.py` |
| P4-04 | Filtrar outputs/ | Solo mostrar carpeta outputs relevante | Config |
| P4-05 | Highlight nuevos | Resaltar archivos recién creados | Styling |

#### Diseño del FileWatcher

```python
# tui/services/file_watcher.py
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class FileWatcherService:
    def __init__(self, path: Path, on_change: Callable[[], None]) -> None:
        self._path = path
        self._on_change = on_change
        self._observer = Observer()
        self._debounce_timer: float = 0

    def start(self) -> None:
        handler = _ChangeHandler(self._handle_event)
        self._observer.schedule(handler, str(self._path), recursive=True)
        self._observer.start()

    def stop(self) -> None:
        self._observer.stop()
        self._observer.join()

    def _handle_event(self) -> None:
        # Debounce: solo notificar si pasaron 500ms desde último evento
        now = time.time()
        if now - self._debounce_timer > 0.5:
            self._debounce_timer = now
            self._on_change()
```

#### Criterio de Aceptación
- [ ] Árbol muestra estructura outputs/
- [ ] Archivos nuevos aparecen automáticamente
- [ ] No hay parpadeo excesivo (debounce funciona)
- [ ] Performance aceptable (< 50ms por refresh)

---

### Fase 5: Live Feed Widget

**Objetivo**: Integrar el streaming de Claude en la TUI.

#### Tareas

| ID | Tarea | Descripción | Archivos |
|----|-------|-------------|----------|
| P5-01 | Crear LiveFeedWidget | Widget que muestra streaming | `tui/widgets/live_feed.py` |
| P5-02 | Adaptar ExecutePhaseService | Usar callback para TUI | (ya existe on_output) |
| P5-03 | Auto-scroll | Mantener última línea visible | Widget config |
| P5-04 | Syntax highlighting | Colorear pensamiento vs acción | Styling |
| P5-05 | Buffer limitado | Mantener últimas N líneas | Performance |

#### Integración con Streaming Existente

```python
# tui/widgets/live_feed.py
from textual.widgets import RichLog

class LiveFeedWidget(RichLog):
    """Widget que muestra output de Claude en tiempo real."""

    def __init__(self) -> None:
        super().__init__(highlight=True, markup=True, max_lines=500)

    def append_line(self, line: str) -> None:
        """Callback para execute_streaming."""
        # Detectar tipo de línea y aplicar estilo
        if "[THOUGHT]" in line or "thinking" in line.lower():
            self.write(f"[italic magenta]{line}[/]")
        elif line.startswith(">"):
            self.write(f"[cyan]{line}[/]")
        else:
            self.write(line)
```

#### Uso desde TUI

```python
# tui/screens/execution_screen.py
async def run_phase(self, phase: int, step: int) -> None:
    adapter = ClaudeCodeSubprocessAdapter()
    service = ExecutePhaseService(adapter)

    live_feed = self.query_one(LiveFeedWidget)

    # Ejecutar con callback que actualiza el widget
    result = service.execute_streaming(
        phase=phase,
        step=step,
        project_path=str(self._project_path),
        on_output=live_feed.append_line,  # REUTILIZA infraestructura existente
    )
```

#### Criterio de Aceptación
- [ ] Output de Claude aparece línea por línea
- [ ] Pensamiento en color diferente a acciones
- [ ] Auto-scroll funciona
- [ ] No hay memory leak (buffer limitado)

---

### Fase 6: Quick Actions + Keyboard Bindings

**Objetivo**: Implementar el menú de acciones rápidas y atajos de teclado.

#### Tareas

| ID | Tarea | Descripción | Archivos |
|----|-------|-------------|----------|
| P6-01 | Crear QuickActionsWidget | Panel con botones de acción | `tui/widgets/quick_actions.py` |
| P6-02 | Implementar bindings | Atajos: R, S, V, L, Q, ? | `tui/app.py` |
| P6-03 | Crear ActionService | Servicio que ejecuta acciones | `tui/services/action_service.py` |
| P6-04 | Modal confirmación | Confirmar antes de acciones destructivas | Modal |
| P6-05 | Help screen | Pantalla de ayuda con `?` | `tui/screens/help_screen.py` |

#### Bindings

```python
# tui/app.py
class TUIApp(App):
    BINDINGS = [
        Binding("r", "run_next", "Run Next Step"),
        Binding("s", "show_status", "Status"),
        Binding("v", "validate", "Validate"),
        Binding("l", "login", "Login"),
        Binding("q", "quit", "Quit"),
        Binding("?", "help", "Help"),
    ]

    async def action_run_next(self) -> None:
        state = self._state_service.detect(self._project_path)
        await self.push_screen(
            ExecutionScreen(state.next_phase, state.next_step)
        )
```

#### Criterio de Aceptación
- [ ] Todos los atajos funcionan
- [ ] Acciones ejecutan comandos reales
- [ ] Modal de confirmación para run
- [ ] Help muestra todos los atajos

---

### Fase 7: Modo Idle vs Active

**Objetivo**: Implementar transiciones entre estados de la TUI.

#### Estados

```
┌─────────────┐     run_next()      ┌─────────────┐
│    IDLE     │ ──────────────────► │   ACTIVE    │
│  MainScreen │                     │  ExecScreen │
└─────────────┘ ◄────────────────── └─────────────┘
                   execution_done()
```

#### Tareas

| ID | Tarea | Descripción | Archivos |
|----|-------|-------------|----------|
| P7-01 | Crear ExecutionScreen | Screen para modo activo | `tui/screens/execution_screen.py` |
| P7-02 | Transición Idle→Active | Push screen al iniciar ejecución | Navigation |
| P7-03 | Transición Active→Idle | Pop screen al terminar | Navigation |
| P7-04 | Border color dinámico | Verde éxito, rojo error | Styling |
| P7-05 | Bloquear input | Deshabilitar atajos durante ejecución | Bindings |

#### Criterio de Aceptación
- [ ] Al presionar `R`, cambia a ExecutionScreen
- [ ] Durante ejecución, otros atajos deshabilitados
- [ ] Al terminar, borde cambia de color
- [ ] `Enter` vuelve a MainScreen

---

### Fase 8: Pulido Visual + Fallback

**Objetivo**: Refinamiento final y modo fallback para terminales limitados.

#### Tareas

| ID | Tarea | Descripción | Archivos |
|----|-------|-------------|----------|
| P8-01 | Terminal detection | Detectar capacidades del terminal | Utils |
| P8-02 | Fallback mode | Modo simplificado sin Textual | Fallback |
| P8-03 | Responsive layout | Adaptar a diferentes tamaños | CSS |
| P8-04 | Animaciones | Transiciones suaves | CSS |
| P8-05 | Documentación | README TUI, capturas | Docs |

#### Fallback para Terminales Limitados

```python
# tui_main.py
def launch_tui(project_path: Path) -> None:
    # Detectar si el terminal soporta TUI completa
    if not _supports_advanced_tui():
        console.warning("Terminal limitado. Usando modo simplificado.")
        _launch_simple_mode(project_path)
        return

    # TUI completa
    app = TUIApp(project_path)
    app.run()

def _supports_advanced_tui() -> bool:
    """Verificar capacidades del terminal."""
    import os
    term = os.environ.get("TERM", "")
    # Verificar si soporta 256 colores y es interactivo
    return (
        "256color" in term or "truecolor" in term
    ) and sys.stdin.isatty()
```

#### Criterio de Aceptación
- [ ] TUI funciona en terminals modernos (iTerm2, Windows Terminal, etc.)
- [ ] Fallback funciona en terminals básicos
- [ ] Layout se adapta a ventanas pequeñas
- [ ] Documentación completa

---

## 5. Matriz de Riesgos

| Riesgo | Probabilidad | Impacto | Mitigación |
|--------|--------------|---------|------------|
| Incompatibilidad terminal | Media | Alto | Fallback mode + detection |
| Performance file watcher | Baja | Medio | Debounce + ignore patterns |
| Memory leak en LiveFeed | Media | Medio | Buffer limitado |
| Textual breaking changes | Baja | Alto | Pin versión, tests CI |
| Conflicto con tests existentes | Baja | Alto | TUI en paquete separado |

---

## 6. Testing Strategy

### 6.1 Estructura de Tests

```
tests/
├── unit/
│   └── tui/
│       ├── test_telemetry_service.py
│       ├── test_git_service.py
│       ├── test_file_watcher.py
│       └── test_widgets.py
└── integration/
    └── tui/
        ├── test_tui_app.py
        └── test_screens.py
```

### 6.2 Snapshot Testing para Widgets

```python
# tests/unit/tui/test_widgets.py
async def test_progress_panel_renders_correctly():
    async with TUIApp().run_test() as pilot:
        # Verificar que el widget renderiza correctamente
        assert pilot.app.query_one(ProgressPanel)
        # Snapshot del render
        assert pilot.app.query_one(ProgressPanel).render() == expected_snapshot
```

---

## 7. Cronograma Sugerido

| Fase | Descripción | Complejidad | Dependencias |
|------|-------------|-------------|--------------|
| 0 | Preparación | Baja | Ninguna |
| 1 | Telemetry Bar | Baja | Fase 0 |
| 2 | Layout + Progress | Media | Fase 1 |
| 3 | Git Status | Baja | Fase 2 |
| 4 | File Tree | Media | Fase 2 |
| 5 | Live Feed | Media | Fase 2 |
| 6 | Quick Actions | Media | Fases 3-5 |
| 7 | Idle/Active | Media | Fase 6 |
| 8 | Pulido | Baja | Fase 7 |

---

## 8. Definición de Hecho (DoD)

Cada fase se considera **DONE** cuando:

- [ ] Código implementado y funcional
- [ ] Tests unitarios escritos y pasando
- [ ] mypy --strict sin errores
- [ ] ruff check sin errores
- [ ] Tests existentes (74) siguen pasando
- [ ] Documentación inline (docstrings)
- [ ] Revisión de código completada

---

## 9. Comandos de Verificación

```bash
# Verificar que nada se rompió
pytest tests/

# Type checking
mypy src/laida_cli --strict

# Linting
ruff check src/laida_cli

# Probar TUI (después de Fase 1)
laida tui
```

---

## 10. Apéndice: Referencia Visual Textual

### CSS Básico (Textual)

```css
/* tui/theme.tcss */
Screen {
    background: $surface;
}

#sidebar {
    width: 30%;
    border-right: solid $primary;
}

#main {
    width: 70%;
}

TelemetryBar {
    dock: bottom;
    height: 1;
    background: $primary-darken-2;
}

ProgressPanel {
    height: auto;
    padding: 1;
    border: round $primary;
}
```

### Colores (Mapeo desde ui/theme.py)

```python
# tui/theme.py
from laida_cli.ui.theme import LAIDA_STYLES

# Convertir estilos Rich a variables CSS Textual
TEXTUAL_THEME = {
    "primary": "#a78bfa",      # laida.brand
    "secondary": "#5eead4",    # laida.agent
    "success": "#10b981",      # laida.success
    "error": "#f87171",        # laida.error
    "warning": "#fbbf24",      # laida.warning
}
```

---

**Documento creado**: 2024-12-23
**Autor**: Claude (asistido por usuario)
**Estado**: DRAFT - Pendiente aprobación
