Video demo del README de NewsRead
Un solo comando produce el mp4 demo canónico:
.claude/skills/demo-video/scripts/run_demo.sh [output.mp4]
# salida predeterminada: docs/assets/newsread-demo.mp4
El pipeline: inicia un backend aislado (:8010, base de datos newsread_test) → siembra contenido demo → inicia el frontend (:3010, modo dev) → graba un recorrido guionizado con Playwright usando Chrome del sistema (headless, con cursor animado + subtítulos inyectados) → convierte a H.264 mp4 con ffmpeg. Los servidores se detienen y solo se toca la base de datos de prueba: el stack real de docker-compose del usuario en :3000/:8000 nunca se ve involucrado.
Opciones: DEMO_SCHEME=dark|light (oscuro por defecto), DEMO_SPEED=1.15 (aceleración de reproducción en el mp4), CHROME_PATH (binario de navegador alternativo).
Requisitos previos (generalmente ya se cumplen en esta máquina)
- docker-compose con Postgres funcionando en :5433 (solo se usa la base de datos
newsread_test) backend/.venvsincronizado (uv sync),frontend/node_modulesinstalados- ffmpeg en el PATH, Google Chrome instalado
- Conexión a internet: el recorrido obtiene comentarios en vivo de HN, vistas previas de catálogo y miniaturas de picsum. Sin conexión el video aún se graba pero esas secciones se degradan.
- Puertos 8010/3010 libres; el worker de arq no debe estar ejecutándose contra la base de datos de prueba (intentaría refrescar los feeds demo falsos — inofensivo pero ruidoso).
Lo que muestra el recorrido canónico (~80s antes de la aceleración)
- Tarjeta de título sobre la bandeja de entrada cargando
- Desplazamiento de la bandeja de entrada — la lectura automática marca los artículos al pasar; el contador de no leídos disminuye
- Artículo principal ("SQLite: 35% más rápido que el sistema de archivos") — resumen AI en markdown
- Cobertura relacionada — los clusters de embeddings sembrados producen niveles MISMA HISTORIA + relacionado
- Comentarios en vivo de Hacker News ("Mostrar comentarios" en el hilo real de HN)
- Catálogo — buscar "nasa", abrir un modal de vista previa del feed, suscribirse con ajustes rápidos
- Tarjeta de cierre
Las piezas móviles (edítalas para cambiar el demo)
scripts/seed_demo_data.py— usuario demo (demo/demo-pass-1234), 4 feeds ficticios, ~16 artículos escritos a mano con resúmenes teaser en markdown, embeddings pgvector hechos a mano (coseno ~0.08 → "misma historia", ~0.50 → "relacionado", aleatorio ≈ ortogonal → oculto). El ID del hilo HN del artículo principal se resuelve en vivo mediante la API de Algolia. Idempotente; rechaza cualquier URL de base de datos que no seanewsread_test.scripts/record_tour.js— la lista de escenas. Primero hace una pasada de calentamiento no grabada para que Next.js compile en modo dev y las imágenes se almacenen en caché antes de grabar.scripts/demo_helpers.js— superposiciones de cursor/subtítulos/tarjetas de título inyectadas y primitivas de entrada con ritmo humano. El desplazamiento usa eventos reales de rueda para que el auto-lectura del IntersectionObserver se comporte exactamente como lo haría con un usuario.scripts/convert_to_mp4.sh— webm → H.264/yuv420p/faststart mp4.
Verificación del resultado
No entregues un video que no hayas revisado. Extrae fotogramas de muestra:
ffmpeg -i docs/assets/newsread-demo.mp4 -vf fps=1/6 /tmp/demo-frames/f%02d.png
y revísalos: confirma que los subtítulos sean legibles, que las secciones de resumen/relacionados/HN realmente aparecieron, y que el botón de suscripción cambió a "Suscrito". Si falta alguna sección, revisa el registro del grabador y $WORK/backend.log (el directorio de trabajo se imprime al inicio de la ejecución).
Cómo insertarlo en el README
GitHub solo renderiza un reproductor de video para mp4 subidos a través de su editor web (arrastrar y soltar mientras se edita README.md, lo que genera una URL github.com/user-attachments/assets/...) — un .mp4 commiteado y referenciado por ruta NO se renderizará en línea. Por lo tanto: entrega el mp4 terminado al usuario y dile que lo arrastre al README en github.com. Commitar el archivo en docs/assets/ como copia canónica sigue siendo válido.
Problemas conocidos
- La suscripción en la escena del catálogo dispara una búsqueda síncrona real de ese feed en el backend — elige feeds confiables (el recorrido busca "nasa"); la espera permite hasta 30s.
- Nunca siembres mediante
POST /api/feeds— obtiene la URL del feed de forma síncrona. El script de siembra inserta filas ORM directamente. - La interfaz de resumen AI del frontend se oculta completamente si
/api/ai/statusreporta "no configurado";run_demo.shexporta unNEWSREAD_OPENAI_API_KEYde relleno para que se renderice. Nunca se llama a ningún LLM: los resúmenes están previamente rellenados, y el endpoint de resumen se cortocircuita cuando existen. - La etiqueta
modelde los embeddings en los vectores sembrados debe coincidir conNEWSREAD_OPENAI_EMBEDDING_MODELdel servidor —run_demo.shlo exporta para ambos procesos; no ejecutes el script de siembra con un entorno diferente al del servidor.