Imported from chomusuke-mk/vidra (
AGENTS.md). Install upstream withnpx skills add chomusuke-mk/vidra. Copyright stays with the author.
🤖 Guía para Agentes de IA en Vidra
¡Bienvenido! Eres un agente de inteligencia artificial (IA) o asistente de código encargado de colaborar en el proyecto Vidra. Esta guía contiene las instrucciones, estándares y arquitectura del proyecto para que puedas empezar a trabajar de manera rápida y eficiente.
🎯 Objetivo General del Proyecto
Vidra es un gestor de descargas de video avanzado, multiplataforma (Android, Windows, Linux, macOS), construido con:
- Frontend (Cliente): Flutter (Dart) con enfoque en un diseño moderno, responsivo y usando principios de Clean Architecture.
- Backend (Motor de descarga): Python empaquetado como un proceso aislado (Isolate) usando
serious_python. Utiliza internamenteyt-dlpyFFmpeg/QuickJS. - Comunicación: A través de una API REST HTTP local en un puerto dinámico y seguro.
📂 Estructura del Proyecto
El código está fuertemente separado entre el frontend (UI) y el backend (lógica de descarga). A continuación, se detallan los directorios clave:
/lib: Contiene el código fuente en Dart/Flutter. Mantiene la separación de preocupaciones (UI, lógica de negocio/estado conProvider, servicios HTTP, manejo de archivos y modelos)./app: Contiene el código fuente del backend en Python y sus dependencias (requirements/)./docs: Documentación técnica detallada. DEBES consultar estos archivos cuando trabajes en características complejas.docs/system-architecture.md: Detalles de cómo se comunica Flutter con el backend de Python.docs/client-flows.md: Flujos principales de la UI y ciclo de vida de la app.docs/development-guide.md: Guía de desarrollo, testing y troubleshooting.
/android,/windows,/linux,/macos: Configuraciones nativas de las plataformas soportadas./.github/workflows: Definición de los pipelines de CI/CD (GitHub Actions) para el empaquetado de dependencias nativas (como FFmpeg/QuickJS) y la automatización de releases./teste/integration_test: Pruebas unitarias, de widgets y de integración en Dart.
📖 Orden de Lectura Sugerido
Antes de implementar modificaciones significativas, asegúrate de comprender la base de conocimiento del proyecto. Como agente, debes priorizar leer estos archivos utilizando tus herramientas de lectura:
README.md: Para entender cómo funciona el proyecto a alto nivel, cómo se compila y el rol de dependencias críticas comoserious_python.pubspec.yaml: Para conocer las dependencias de Dart disponibles en el proyecto (ej.provider,dio/http,flutter_localizations). ¡Usa lo que ya está instalado!docs/system-architecture.md(Si vas a tocar la interacción entre Dart y Python): Para entender los puertos de la API local, encriptado de datos y cómo se sincroniza el progreso.docs/development-guide.md(Si necesitas probar o compilar algo complejo): Para entender cómo manejar binarios nativos (FFmpeg, QuickJS) durante el entorno de desarrollo.
🛠️ Estándares y Convenciones de Código
Frontend: Flutter / Dart (/lib)
- Gestión de Estado: Se usa el paquete
provider. Respeta el flujo unidireccional. La UI consume Providers y no almacena estado complejo de negocio internamente. - Internacionalización (i18n): Cualquier texto visible en la interfaz debe estar localizado usando los archivos
i18n/*.jsoncy el modeloAppStringKeyenlib/features/locales/domain/locale.dart. Cero strings hardcodeados en las vistas.- Convención de prefijos i18n:
s_ys_*_desc: Pantalla de configuración y sus descripciones informativas.d_: Pantalla principal de descargas.dd_: Detalles de descarga.sw_: Modal y flujo de selección de elementos (Selection Wrapper).shw_: Envoltura de enlace compartido (Share Wrapper).ov_: Pantalla y modal flotante de Overlay.p_: Pantalla de permisos.sd_: Estado y detalles del sistema.tu_: Textos de tutoriales (TutorialUtils).dc_: Tarjeta de descarga (DownloadCard).fe_: Diálogo de error fatal.
- Al agregar un string nuevo, añádelo en
i18n/en.jsonc, genera su getter enAppStringKeyy regístralo en_allAppStrings.
- Convención de prefijos i18n:
- Pantalla de Configuración (
SettingsScreen):- Todas las opciones se definen dentro de
_getAllSettingsmediante_SettingDef. - Emplea exclusivamente los componentes optimizados de
lib/shared/widgets/:LazyDropdown,LazyTextField,LazyList,LazyMapySettingRow. - Modificaciones en las opciones de descarga deben reflejarse en
DownloadOptions(toJson/fromJson) y en_applyDynamicDefaultsdeSettingsController.
- Todas las opciones se definen dentro de
- Overlay de Compartir (
QuickShareOverlay):- Se ejecuta en un Isolate secundario e independiente (
overlayMaincon@pragma("vm:entry-point")). - La comunicación para encolar descargas desde el overlay hacia el motor se realiza mediante IPC con
IsolateNameServer.lookupPortByName('vidra_backend_port'). - Las preferencias temporales del overlay se almacenan en
SharedPreferencesusando el prefijoov_*.
- Se ejecuta en un Isolate secundario e independiente (
- Diseño Adaptativo: Vidra se ejecuta en móviles y escritorio. La UI debe adaptarse a múltiples resoluciones usando
LayoutBuilder,MediaQueryo dependencias relacionadas. Sigue los lineamientos de diseño premium (esquemas oscuros, animaciones sutiles, fuentes modernas). - Manejo de Errores Asíncronos: El backend es un ente separado; asume que las peticiones HTTP pueden fallar. Usa bloques
try/catchde forma defensiva y maneja los estados visuales (carga, éxito, error).
Backend: Python (/app)
- Independencia Total: El backend de Python ignora por completo la existencia de la UI. Su única interfaz es exponer un servicio API REST que la app consume localmente.
- Respuestas Estandarizadas: Retorna códigos de estado HTTP correctos (200, 400, 404, 500) y payloads JSON estructurados.
- Rendimiento: Evita bloquear el hilo principal. El proceso de descargas o conversión (
ffmpeg) es intensivo, por lo que todo progreso debe reportarse asíncronamente o en intervalos para no colapsar la comunicación.
Infraestructura y CI / CD
- Sin Binarios Nativos Extra: No subas binarios nativos precompilados de FFmpeg o QuickJS al repositorio. Estos son gestionados y descargados por GitHub Actions.
- Modificación del Backend: Si cambias la lógica en
/app, asegúrate de que el empaquetado mediante el comando deserious_pythonno se rompa (se empaquetan en un archivo comprimido especial consumible por Flutter).
🗺️ Guía de Archivos por Funcionalidad (Adición y Modificación)
Cuando se te solicite implementar o alterar una funcionalidad en Vidra, consulta y actualiza rigurosamente este mapa de archivos:
1. Nueva Opción o Parámetro de Descarga (yt-dlp)
Se debe cubrir el ciclo completo entre Python y Flutter (7 archivos):
app/src/vidra_yt_dlp_parser_types.py: Agregar alVidraOptions(TypedDict) y su regla enis_valid_options.app/src/vidra_yt_dlp_parser.py: Agregar valor default enDEFAULT_OPTIONS, assert enoptions_parsery mapear a flag CLI deyt-dlp.lib/features/settings/domain/download_options.dart: Agregar campo aDownloadOptions(con su enum si aplica), constructor,copyWith,toJsonyfromJson.lib/features/settings/presentation/settings_controller.dart: Incluir en_applyDynamicDefaultssi requiere rutas/ejecutables dinámicos.lib/features/settings/presentation/settings_screen.dart: Registrar el control en_getAllSettings(LazyDropdown,LazyTextField,LazyList,LazyMap,Switch).i18n/en.jsonc: Agregar clavess_<clave>ys_<clave>_desc.lib/features/locales/domain/locale.dart: Agregar getters enAppStringKeyy registrar en_allAppStrings.
2. Nuevo Endpoint o Acción en la API REST Local
app/src/main.py: Declarar ruta@server.route(...)protegida con@token_required.app/src/app.py: Implementar la lógica del endpoint en la claseApp.app/src/descarga.py(si aplica): Si la acción afecta una descarga individual en progreso.lib/core/network/vidra_http_client.dart: Declarar el método cliente HTTP con_headersy timeout.lib/features/downloads/data/download_repository.dart: Exponer el método al controlador de la UI.lib/features/downloads/presentation/downloads_controller.dart: Agregar la acción y notificar cambios.
3. Nueva Pantalla o Flujo en la UI
lib/features/<feature>/domain/<model>.dart: Modelo inmutable confromJson/toJson.lib/features/<feature>/data/<feature>_repository.dart: Acceso a datos/HTTP.lib/features/<feature>/presentation/<feature>_controller.dart:ChangeNotifierde la feature.lib/features/<feature>/presentation/<feature>_screen.dart: UI adaptativa usando widgets compartidos.lib/main.dart: Inyectar enMultiProvider.i18n/en.jsonc&lib/features/locales/domain/locale.dart: Textos localizados con prefijo único.
4. Ajustes en Quick Share Overlay
lib/features/downloads/presentation/overlay_main.dart: UI flotante (overlayMain), lectura de SharedPreferences con prefijoov_*.lib/core/isolate/backend_isolate.dart: Escucha de comandos IPC envidra_backend_port.
🚀 Flujo y Comandos Clave (CLI)
Como agente, puedes ejecutar scripts en bash si es necesario validar código (una vez el usuario haya aprobado tus cambios o si estás debugueando de forma segura).
- Obtener dependencias (Dart):
flutter pub get - Empaquetar el Backend en Python (Ejemplo Windows):
dart run serious_python:main package app/src -r -r -r app/requirements/base.txt -r -r -r app/requirements/Windows.txt -p Windows --verbose --compile-packages(Nota: Ajusta el archivo.txty el target-psegún el OS) - Lanzar la app:
flutter run -d <windows|linux|android> - Ejecutar Pruebas Estáticas y Tests:
dart analyzeflutter test - Pruebas con Aislamiento de Logs:
VIDRA_SERVER_DATA=/tmp/vidra_tests flutter test --tags integration
🤖 Reglas Generales de Comportamiento (Agente)
- Reutilización: Antes de crear un nuevo componente, servicio o clase utilitaria, revisa
/libpara ver si ya existe algo que resuelva la misma necesidad. - Consistencia de APIs: Si un usuario solicita un cambio en los parámetros que envía Python (API JSON), obligatoriamente debes ajustar el modelo y el servicio consumido en el lado de Dart (y viceversa).
- Planes de Ejecución (Planning Mode): Si el cambio solicitado es muy grande (ej. un nuevo flujo completo, refactorización masiva o nueva página), debes SIEMPRE crear un plan de implementación detallado en un artefacto y esperar aprobación del usuario antes de empezar a programar.
- Dudas y Ambigüedades: No adivines ni asumas. Si algo no queda claro, detente y pide aclaraciones al usuario mediante las herramientas correspondientes.