Communitygithub.com

bueno-demo

Graba un video demo breve y pulido de una aplicación web (navegador real, zoom suave hacia cada clic, cursor con movimiento elástico) y exporta MP4, un póster y opcionalmente un GIF. Úsalo cuando un demo en movimiento explique una función mejor que una captura de pantalla, para notas de versión, documentación, presentaciones, PRs o Slack. Se activa con frases como "grabar un demo", "video demo", "grabación de pantalla de", "hacer un GIF de", "mostrar esta función en un video".

¿Qué es bueno-demo?

bueno-demo es una herramienta de línea de comandos diseñada para grabar y renderizar videos demo pulidos de aplicaciones web, ideal para desarrolladores que necesitan mostrar funciones de forma visual en documentación, notas de versión o presentaciones. Funciona en dos fases: captura y renderizado. En la fase de captura, utiliza Playwright para controlar un navegador Chromium real, ejecutando un script JSON que define pasos como clics, escritura de texto, desplazamiento y esperas. La fase de renderizado añade efectos de cámara (zoom suave hacia cada clic), un cursor con movimiento elástico, títulos y marcas visuales, generando un video MP4 estilo Screen Studio, un póster PNG y opcionalmente un GIF. Soporta plataformas como macOS (con ffmpeg) y cualquier entorno donde pueda ejecutarse Node.js y Playwright. Es útil para crear demostraciones breves y enfocadas sin exponer datos reales de clientes, gracias a hooks de privacidad que reemplazan información sensible durante la grabación.

Compatible con~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/johnchourajr/bueno-demo/tree/main/skills/bueno-demo

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Videos demo con bueno-demo

bueno-demo graba un recorrido guionizado por una página web y lo renderiza en un clip estilo Screen Studio. Hay dos pasos: captura que maneja una ventana Chromium real y la graba, y renderizado que añade la cámara, el cursor y los títulos.

Configuración, una vez por máquina

npm i -D bueno-demo            # o ejecuta todo con npx bueno-demo
npx playwright install chromium
brew install ffmpeg            # requerido; añade imagemagick para pósteres WebP

El ciclo

  1. Escribe un script, un archivo JSON (ver más abajo). Mantén una idea por clip, de 10 a 15 segundos.
  2. Captura: npx bueno-demo capture demos/<nombre>.json out/<nombre>
  3. Corte opcional de una carga lenta: npx bueno-demo cut out/<nombre> <desde-s> <hasta-s>
  4. Renderiza: npx bueno-demo render out/<nombre> out/<nombre>/<nombre> --gif
  5. Revísalo antes de usarlo. Crea una hoja de contactos y verifica cada fotograma: ffmpeg -i out/<nombre>/<nombre>.mp4 -vf "fps=1,scale=640:-1,tile=3x4" -frames:v 1 sheet.png Si aparece un error o datos privados en cámara, corrige el script o córtalo, luego vuelve a renderizar.

Scripts

{
  "url": "http://localhost:3000/ajustes",
  "viewport": [1440, 900],
  "storage": "auth.json",
  "keep": "document.querySelectorAll('[data-user-email]').forEach(e => e.textContent = '[email protected]')",
  "steps": [
    { "scroll": "[data-testid=facturacion]" },
    { "click": "[data-testid=plan-toggle]", "after": 1200 },
    { "type": "[data-testid=nombre-equipo]", "text": "Northwind", "clear": true },
    { "hover": "[data-testid=guardar]", "zoom": true },
    { "click": "[data-testid=guardar]", "zoom": false },
    { "wait": 800 }
  ]
}

Pasos, cada uno opcionalmente con after (ms para pausar después):

  • click: desliza hacia el elemento y haz clic. zoom: false omite el zoom de cámara; úsalo en un clic que navegue.
  • type: haz clic, luego escribe text (delay ms por tecla, por defecto 55; clear: true reemplaza el valor).
  • fill: haz clic, luego establece text de una vez, para inputs que la escritura no puede manejar (selectores de fecha).
  • hover: desliza hacia allí. zoom: true también apunta la cámara.
  • upload: desliza hacia una zona de destino y adjunta file (relativo al script) al input.
  • press: una tecla, como "Escape".
  • scroll: desplaza suavemente el elemento hasta que sea visible.
  • wait: pausa, en ms. eval: ejecuta JS en la página, en cámara.

Opciones:

  • Iniciar sesión: storage apunta a un archivo de estado de almacenamiento de Playwright (guarda uno con npx playwright codegen --save-storage=auth.json <url>). O "cookiesFrom": "agent-browser" toma prestada una sesión de agent-browser con sesión iniciada. Las cookies nunca se imprimen.
  • Privacidad: keep es JS que se ejecuta antes de la grabación y cada 250 ms durante ella, para reemplazar nombres reales y correos electrónicos por sustitutos, de modo que una re-renderización nunca los recupere. hide añade selectores CSS para ocultar (los overlays de desarrollo de Next.js y Vercel ya están ocultos; "hide": false los muestra).
  • Fuera de cámara: setup es JS que se ejecuta una vez antes de la grabación (para cerrar un banner, por ejemplo).
  • Sensación: travelMs (tiempo de recorrido del cursor, por defecto 700), settle (espera después de cargar, por defecto 1500), tail (pausa al final, por defecto 1200), cursorStart ([x, y]), reducedMotion: true.
  • Carga: waitUntil (por defecto networkidle). Una página que transmite video o hace polling nunca estará inactiva, por lo que la captura se agota; establece "load" y deja que settle cubra el resto.
  • Otro servidor: --base http://localhost:3001 en la captura graba la misma ruta en otro lugar.

Selectores: prefiere data-testid o estructura (#title, input[name=amount]) sobre texto visible, para que los cambios de copia no rompan el script.

Banderas de renderizado

  • --zoom 1.6 qué tan lejos acerca un clic (1.3 cuando importan dos cosas a la vez).
  • --speed 0.9 reproduce un 10% más lento; --speed 2.5 para un montaje rápido.
  • --end 9.8 corta en ese segundo; --hold 1.2 congela el último fotograma.
  • --matte '#fdfaf1' enmarca la página como una ventana redondeada sobre ese color (por defecto es de borde a borde).
  • --title 'Moviendo un evento' --kicker 'Eventos' añade un título de apertura; --end-cap añade una tarjeta de cierre.
  • --brand brand.json establece el aspecto del título y la tarjeta: ink, paper, accent, displayFont / monoFont ({ "family", "file", "weight" }), logo, footer, kicker. Las rutas son relativas al archivo de marca.
  • --fit renderiza con la forma propia de la página (vertical para un viewport de teléfono).
  • --gif también escribe un GIF de 960px y 15fps.

Reglas

  • Nunca grabes datos reales de clientes. Usa cuentas de prueba y un hook keep para cualquier cosa personal; revisa la hoja de contactos antes de compartir.
  • Cortos y de un solo propósito. Una función por clip; recorta las esperas con cut.
  • Aloja el video fuera del repositorio. Sube el script (y un póster si tu documentación lo necesita); coloca los MP4 y GIFs en tu almacenamiento o CDN.

Skills relacionados