Files
captain-claude/PLAN_CAPTAIN_MOBILE_V2.md
ARCHITECT f199daf4ba Change PIN to 1451
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 23:31:52 +00:00

10 KiB

PLAN: Captain Claude Mobile v2

Objetivo

App móvil nativa de chat con Claude que ejecuta comandos en el servidor y muestra resultados formateados.


1. ARQUITECTURA

┌──────────────────┐     HTTPS/WSS      ┌──────────────────┐
│                  │ ◄────────────────► │                  │
│   Flutter App    │                    │   FastAPI        │
│   (Android/iOS)  │                    │   Backend        │
│                  │                    │                  │
└──────────────────┘                    └────────┬─────────┘
                                                 │
                                                 │ subprocess
                                                 ▼
                                        ┌──────────────────┐
                                        │                  │
                                        │   Claude CLI     │
                                        │   (claude -p)    │
                                        │                  │
                                        └──────────────────┘

Backend (FastAPI)

  • Recibe mensajes del usuario via WebSocket
  • Ejecuta claude -p "mensaje" --output-format stream-json
  • Parsea el output JSON de Claude
  • Envía respuesta formateada al frontend
  • Guarda historial en PostgreSQL

Frontend (Flutter)

  • UI de chat nativa (burbujas, input, etc.)
  • Renderiza Markdown en respuestas
  • Syntax highlighting en code blocks
  • Muestra progreso de ejecución
  • Historial de conversaciones

2. DISEÑO UI/UX

Pantalla Principal (Chat)

┌─────────────────────────────────┐
│ ☰  Captain Claude    [●] Online│  ← AppBar con estado conexión
├─────────────────────────────────┤
│                                 │
│ ┌─ User ────────────────────┐  │
│ │ Muéstrame el uso de disco │  │  ← Burbuja usuario (derecha)
│ └───────────────────────────┘  │
│                                 │
│ ┌─ Claude ──────────────────┐  │  ← Burbuja Claude (izquierda)
│ │ Ejecutando `df -h`...     │  │
│ │                           │  │
│ │ ```                       │  │  ← Code block con resultado
│ │ Filesystem  Size  Used    │  │
│ │ /dev/sda1   100G  45G     │  │
│ │ ```                       │  │
│ │                           │  │
│ │ El disco principal tiene  │  │  ← Explicación en texto
│ │ 55% libre (55GB).         │  │
│ └───────────────────────────┘  │
│                                 │
├─────────────────────────────────┤
│ ┌─────────────────────────┐ 📎│  ← Input con attach
│ │ Escribe un mensaje...   │ ➤ │  ← Botón enviar
│ └─────────────────────────────┘│
└─────────────────────────────────┘

Pantalla Historial

┌─────────────────────────────────┐
│ ← Conversaciones                │
├─────────────────────────────────┤
│ ┌─────────────────────────────┐│
│ │ 📁 Backup de base de datos  ││  ← Título auto-generado
│ │ Hace 2 horas • 5 mensajes   ││
│ └─────────────────────────────┘│
│ ┌─────────────────────────────┐│
│ │ 🔧 Fix error en nginx       ││
│ │ Ayer • 12 mensajes          ││
│ └─────────────────────────────┘│
│ ┌─────────────────────────────┐│
│ │ 📊 Análisis de logs         ││
│ │ 15 Ene • 8 mensajes         ││
│ └─────────────────────────────┘│
└─────────────────────────────────┘

Estados de Mensaje Claude

  1. Pensando: Spinner + "Claude está pensando..."
  2. Ejecutando: Muestra comando siendo ejecutado
  3. Streaming: Texto aparece progresivamente
  4. Completado: Mensaje completo con formato
  5. Error: Mensaje rojo con opción de reintentar

3. API BACKEND

Endpoints REST

Método Endpoint Descripción
POST /auth/login Login, retorna JWT
GET /conversations Lista conversaciones
GET /conversations/{id} Mensajes de una conversación
DELETE /conversations/{id} Eliminar conversación
POST /upload Subir archivo para contexto

WebSocket /ws/chat

Cliente → Servidor:

{
  "type": "message",
  "content": "Muéstrame el uso de disco",
  "conversation_id": "uuid-opcional",
  "files": ["/path/to/file"]
}

Servidor → Cliente (streaming):

{"type": "thinking"}
{"type": "tool_use", "tool": "Bash", "input": "df -h"}
{"type": "tool_result", "output": "Filesystem  Size..."}
{"type": "text", "content": "El disco principal..."}
{"type": "done", "conversation_id": "uuid"}

4. MODELO DE DATOS

PostgreSQL

-- Conversaciones
CREATE TABLE conversations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id VARCHAR(255) NOT NULL,
    title VARCHAR(500),
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

-- Mensajes
CREATE TABLE messages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    conversation_id UUID REFERENCES conversations(id),
    role VARCHAR(50) NOT NULL,  -- 'user' | 'assistant'
    content TEXT NOT NULL,
    tool_uses JSONB,  -- [{tool, input, output}]
    created_at TIMESTAMP DEFAULT NOW()
);

5. FLUTTER - ESTRUCTURA

lib/
├── main.dart
├── config/
│   └── api_config.dart
├── models/
│   ├── conversation.dart
│   ├── message.dart
│   └── tool_use.dart
├── services/
│   ├── api_service.dart
│   ├── chat_service.dart      # WebSocket
│   └── auth_service.dart
├── providers/
│   ├── auth_provider.dart
│   └── chat_provider.dart
├── screens/
│   ├── login_screen.dart
│   ├── chat_screen.dart
│   └── history_screen.dart
└── widgets/
    ├── message_bubble.dart    # Burbuja de mensaje
    ├── code_block.dart        # Syntax highlighting
    ├── tool_use_card.dart     # Muestra ejecución de tool
    ├── thinking_indicator.dart
    └── chat_input.dart        # Input con attach

6. COMPONENTES CLAVE

MessageBubble (Flutter)

class MessageBubble extends StatelessWidget {
  final Message message;

  // Renderiza según tipo:
  // - Texto normal → Markdown
  // - Code blocks → Syntax highlighting
  // - Tool uses → Cards expandibles
  // - Errores → Estilo rojo
}

ToolUseCard (Flutter)

// Muestra:
// ┌─ Bash ──────────────────────┐
// │ ▶ df -h                     │  ← Comando ejecutado
// ├─────────────────────────────┤
// │ Filesystem  Size  Used  ... │  ← Output (colapsable)
// └─────────────────────────────┘

ChatInput (Flutter)

// - TextField multilínea
// - Botón adjuntar archivo
// - Botón enviar (disabled si vacío o desconectado)
// - Indicador de conexión

7. PROCESO DE DESARROLLO

Fase 1: Backend básico

  1. FastAPI con WebSocket
  2. Integración con Claude CLI
  3. Parsing de output JSON
  4. Base de datos PostgreSQL

Fase 2: Frontend básico

  1. Chat UI con burbujas
  2. Conexión WebSocket
  3. Streaming de mensajes
  4. Markdown rendering

Fase 3: Features completas

  1. Historial de conversaciones
  2. Syntax highlighting
  3. Tool use cards
  4. Upload de archivos
  5. Estados de conexión

Fase 4: Pulido

  1. Animaciones
  2. Error handling robusto
  3. Offline mode básico
  4. Notificaciones

8. PROCESO DE AUDITORÍA (post-código)

Ronda 1: Agentes paralelos

  • Arquitecto: Revisa estructura del código
  • QA: Busca bugs y edge cases
  • UX: Evalúa usabilidad

Ronda 2: Tests reales

  • Probar cada endpoint con curl
  • Instalar APK y probar flujos
  • Documentar problemas

Ronda 3: Fixes + re-test

  • Aplicar correcciones
  • Verificar que funcionan
  • Compilar versión final

9. DIFERENCIAS CON v1

Aspecto v1 (Terminal) v2 (Chat)
UI Emulador xterm Chat nativo
Input Teclado terminal Texto natural
Output Raw ANSI Markdown formateado
Comandos Ctrl+C manual Claude decide
UX Técnico Amigable

10. CRITERIOS DE ÉXITO

  1. Usuario puede chatear con Claude en lenguaje natural
  2. Claude ejecuta comandos y muestra resultados formateados
  3. Code blocks tienen syntax highlighting
  4. Conversaciones se guardan y se pueden retomar
  5. UI es responsiva y agradable en móvil
  6. Errores se muestran claramente con opción de reintentar
  7. Conexión se reconecta automáticamente

PRÓXIMO PASO

¿Apruebas este plan para empezar a implementar?