Communitygithub.com

synthetic-ui-demo

Crea videos de demostración de productos y notas de versión sin grabación de pantalla. Reconstruye las pantallas de la aplicación como React estático a partir de su código fuente, y luego las anima en Remotion con un cursor y cámara programados.

¿Qué es synthetic-ui-demo?

Esta skill permite generar videos de demostración de productos, tutoriales de funciones y notas de versión sin necesidad de grabar la pantalla real. En lugar de eso, Claude Code lee el repositorio del producto, reconstruye únicamente las pantallas que aparecen en cada escena como componentes React estáticos, y utiliza un cursor y una cámara programados dentro de Remotion para simular la interacción del usuario. Esto elimina la necesidad de cuentas de prueba, entornos en vivo o datos reales, y cada clic corresponde a un número de fotograma, lo que garantiza que la escena se renderice de manera idéntica cada vez. La skill es especialmente útil para crear videos de notas de versión que se actualizan con cada lanzamiento, demostraciones de funciones que requieren datos difíciles de obtener (como llamadas completas o vistas de administrador), o cuando las grabaciones con Playwright son poco fiables, requieren datos de prueba o se vuelven obsoletas. Funciona leyendo el código fuente de la aplicación, extrayendo el tema, los strings de idioma y los iconos, y reconstruyendo solo lo que la cámara ve en un lienzo fijo (1440x810 por defecto). La línea de tiempo se ancla al audio de la narración, por lo que los clics, el cursor y la cámara siguen automáticamente las palabras, facilitando la re-sincronización cuando se cambia el guión. Soporta múltiples escenas y aplicaciones, y se integra con herramientas de normalización de audio y video (LUFS, QC).

Compatible con✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/digitalsamba/claude-code-video-toolkit/tree/HEAD/.claude/skills/synthetic-ui-demo

Preguntar en tu IA favorita

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

Documentación

Demos de UI Sintéticas

Nada se graba de pantalla. Claude Code lee el repositorio del producto, reconstruye solo las pantallas que muestra una escena como React estático, y un cursor y cámara programados realizan el flujo en Remotion. Cada clic es un número de fotograma, por lo que una escena se re-renderiza de manera idéntica, nunca necesita una cuenta con datos o un entorno en vivo, y se actualiza editando código cuando el producto cambia.

Builds de referencia (léelos junto con esta skill; ambos se construyen sin los repositorios del producto):

  • examples/ds-free-schedule-demo: un flujo de 26s (programar una llamada) con un recuadro de narrador. El caso completo más simple. Su src/Demo.tsx es una sola línea de tiempo con cada fotograma clave del cursor, clic y movimiento de cámara.
  • examples/ds-release-649: un video de notas de versión de 80s, ocho escenas en tres aplicaciones. templates/ds-release-notes es la forma reutilizable del mismo (se envió como release 650). src/Release.tsx secuencia las escenas, src/scenes/ tiene un archivo por elemento de la versión, y src/room/ y src/ac/ son los kits de pantalla.

Cuándo usar esto en lugar de Playwright

Sintético (esta skill)Grabación con Playwright (/record-demo)
Puedes leer el código fuente de la appSolo tienes la app en ejecución
Notas de versión y tours de funciones que se rehacen cada releaseCaptura única de comportamiento real o datos reales
El flujo necesita datos que no tienes (una llamada completa, otros usuarios, una vista de administrador)Lo real es fácil de alcanzar y se ve bien tal cual
Movimientos de cámara, sincronización exacta de clics, re-renderizados después de un cambio de vozInteracciones largas y complejas que serían costosas de reconstruir

Bloques de construcción (lib/components)

import { Stage, typed, cursorAt, near } from '../../../../lib/components';

<Stage
  url="app.example.com/settings"             // barra de direcciones; host más oscuro que la ruta
  camera={CAMERA}                             // [{ f, z, x, y }] en píxeles del lienzo, suavizados, ajustados a la ventana
  path={PATH}                                 // [{ f, x, y }] fotogramas clave del cursor en píxeles del lienzo
  clicks={CLICKS}                             // fotogramas que aplastan el cursor y generan una onda
  aiNote                                      // "Las personas mostradas son generadas por IA" (o pasa tu propio texto)
  canvasWidth={1440} canvasHeight={810}       // los valores por defecto
>
  <SettingsScreen field={typed(frame, 'Q4 Product Review', 128)} />
</Stage>
  • Stage dibuja el marco del navegador alrededor de un lienzo de app de tamaño fijo, aplica la cámara y coloca el cursor encima con zIndex 100. Con zoom 1, la ventana ocupa fit (0.8625) del ancho del fotograma. Los fotogramas clave repiten un valor para mantenerlo.
  • Cursor y cursorAt funcionan por sí solos para una escena sin navegador; near(cursor, target) genera estados de hover.
  • Los kits de pantalla específicos del producto (tema, iconos, diseños) se quedan en el proyecto. No son material de la librería.

Método

1. Obtén una especificación visual del repositorio de la app, con subagentes

Envía un subagente por app o área, en paralelo, y haz que cada uno devuelva una especificación compacta en lugar de volcados de archivos:

  • Tema: paleta, familia de fuentes, radios, espaciado, sombras (del archivo de tema o variables CSS).
  • Strings: las cadenas exactas de la locale en inglés para cada etiqueta, elemento de menú, diálogo y toast que muestra la escena (public/locales/en/*.json, src/i18n/locales/en/*). Nunca parafrasees el texto de la UI.
  • Iconos: si la app usa una fuente de iconos, su selection.json de icomoon/fontello contiene las rutas SVG de cada glifo. Extrae los que necesites en un pequeño JSON y renderízalos como <svg><path d=...>. De lo contrario, copia los componentes SVG.
  • Diseño y comportamiento: árbol de componentes para las pantallas mostradas, orden de la barra de herramientas, valores predeterminados, qué hace cada control.

Lee la rama por defecto desde el remoto (git show origin/main:path, o git fetch luego lee origin/<default>). Los checkouts locales suelen estar desactualizados y te darán la UI del trimestre pasado.

Para las notas de versión, rastrea cada elemento hasta el commit y el componente que lo envía por primera vez. Eso te da las cadenas exactas y los valores predeterminados a mostrar.

2. Reconstruye solo lo que muestra una escena, en un lienzo fijo

  • Coloca cada elemento con posiciones absolutas en un lienzo fijo (1440x810 es un buen valor por defecto). Exporta los rectángulos importantes como constantes (SAVE_BTN = { x, y, w, h }), para que los objetivos de clic sean aritméticos, no adivinanzas.
  • Construye solo lo que la cámara ve. Un panel que nunca aparece puede ser un color plano.
  • Mantenlo como React estático: sin estado, sin efectos. Cada cambio visual es función de frame.
  • Pon el kit en su propia carpeta (src/ui/, src/room/) con un theme.ts para constantes.

3. Voz primero, luego pon la línea de tiempo en fotogramas

  • Escribe una línea por escena, dividiendo en oraciones (un .txt por frase), y genera el audio primero (voiceover.py --scene-dir ...). Tres tomas y tools/pick_takes.py superan a una sola toma más --max-wpm: un clon copia el ritmo y la planitud de su clip de referencia, así que si las líneas salen apresuradas o monótonas, arregla el clip con tools/voice_prosody.py expand en lugar de estirar la salida (ver "Clone Prosody" en CLAUDE.md). Lee las duraciones medidas, y tools/captions.py para las temporizaciones de palabras.
  • Ajusta cada escena a su línea más un beat, y mantén un comentario de cabecera que enumere el inicio y la duración de cada línea. Ese comentario es la fuente de verdad (ver "Audio-Anchored Timelines" en CLAUDE.md).
  • Todo es una constante de fotograma al principio del archivo de escena: fotogramas clave del cursor, CLICKS, fotogramas clave de la cámara, cambios de estado de la UI (frame >= C.save muestra el diálogo). Exporta los fotogramas de clic para que el padre pueda colocar los efectos de sonido de clic.
  • Busca los fotogramas a partir de la narración, no los establezcas manualmente. voice() (lib/components/cues.ts; la plantilla ds-release-notes tiene una copia) toma las frases de la escena con sus .captions.json y fotogramas de inicio, y cue('save') devuelve el fotograma en el que comienza la palabra. Ancla cada acción a la palabra que ilustra, con un desplazamiento, y cada fotograma clave del cursor y la cámara a esos anclajes:
    import line06a from '../../public/audio/scenes/06a_link.captions.json';
    export const LINK_VOICE = voice([{ file: '06a_link', at: 10, captions: line06a }, ...]);
    const { cue } = LINK_VOICE;
    const C = { field: cue('before', { offset: -3 }), save: cue('save') };
    const PATH = [{ f: C.field - 6, ...field }, { f: C.save - 24, ...saveBtn }];
    
    Regenera o re-temporiza una frase y los clics, escritura, cursor y cámara la siguen. Una palabra clave cuyas palabras ya no se dicen falla el bundle con las palabras que lo están. Opciones: offset, edge: 'end', after (un fotograma, para una palabra repetida), nth, in (una frase). El padre coloca el audio desde LINK_VOICE.lines, así que el fotograma de inicio de una frase se escribe una vez. templates/ds-release-notes/src/scenes/FreeCustomLink.tsx es el ejemplo trabajado.

4. Divide las líneas de lista densas en sus pausas

Una línea que enumera varias cosas ("programación, contactos, grabaciones y transcripciones") es demasiado rápida para una sola toma. Divide el audio en sus pausas en archivos de frase (07a, 07b, ...), asigna a cada frase su propia toma, y coloca cada frase en su propio beat. ds-release-649's moreVo hace esto.

5. Mide los objetivos de clic desde una hoja de contactos antes del render completo

Una coordenada adivinada suele estar 20-50px desviada una vez que la cámara hace zoom. Renderiza fotogramas fijos en cada fotograma de clic y unos pocos fotogramas antes, combínalos en mosaico, y verifica que la punta del cursor se sitúa sobre el objetivo:

i=1; for f in 46 78 122 212; do npx remotion still MyComp out/stills/s$i.png --frame=$f; i=$((i+1)); done
ffmpeg -start_number 1 -i out/stills/s%d.png -vf "scale=640:-1,tile=2x2" -frames:v 1 out/contact.png

Arregla las constantes, re-renderiza los fotogramas fijos, y solo entonces renderiza el video.

6. Etiqueta a las personas generadas por IA en pantalla

Cualquier persona que no sea real (retratos FLUX.2 en mosaicos, avatares, un narrador) recibe una etiqueta visible: aiNote en el Stage, o una insignia "IA" en un recuadro de narrador. Los nombres, contactos y datos de llamadas también son inventados, así que mantenlos claramente ficticios.

7. Renderiza, luego normaliza

tools/qc.py --project ... antes de renderizar, luego qc.py --render out/video.mp4 --fix para -14 LUFS. qc.py --project ... --layout verifica el texto propio del video (subtítulos, tarjetas, la nota de IA) en cuanto a tamaño y contraste, y lista el texto de la UI del producto por separado. Stage marca su ventana con data-qc="product"; pon el mismo atributo en cualquier maqueta de teléfono o tableta que construyas fuera de él, o su texto de UI se juzgará como parte del video.

Trucos y trampas

  • Los logotipos SVG monocromáticos se renderizan en negro. Un logo_mono.svg suele tener rellenos negros; sobre un fondo oscuro usa filter: brightness(0) invert(1).
  • Ramas locales desactualizadas. Lee origin/<default>, no la rama en la que esté el checkout local.
  • rsync --exclude src también elimina node_modules/*/src. Al copiar un proyecto o kit, ancla las exclusiones a la raíz de transferencia con una barra inicial: --exclude /src.
  • La cámara se ajusta. Un centro de cámara cerca del borde del lienzo se tira hacia adentro para que el borde de la ventana nunca se muestre más allá del fotograma. Si un zoom aterriza en algún lugar inesperado, esa es la razón; apunta a un punto más adentro.
  • Los menús y diálogos deben estar dentro del lienzo. El lienzo recorta a sus hijos. Posiciona un menú para que se abra hacia adentro, como lo hace la app real.
  • Los estados de hover provienen de la ruta del cursor. Usa near(cursorAt(frame, PATH), target) en lugar de un segundo conjunto de constantes de fotograma, para que mover un fotograma clave mueva el hover con él.
  • Una línea de voz cambiada mueve todo lo que viene después. En una escena con señales, los clics, cursor y cámara siguen solos, pero la longitud de la escena y el at de las frases posteriores aún necesitan revisión. En una escena manual, vuelve a medir cada fotograma. De cualquier manera, actualiza el comentario de cabecera y las longitudes de las escenas, luego vuelve a verificar los fotogramas fijos de clic. Si un narrador sincronizado con los labios se maneja mediante la pista de voz ensamblada, regenéralo también.
  • Un kit sobrevive a su demo. Un kit de pantalla reconstruido puede alojar otros videos: la sala ds-release-notes se convirtió en el escenario de una edición de marca de un corto paródico, con caras animadas en sus mosaicos y sin nuevo trabajo de pantalla. Copia el kit en el nuevo proyecto y escala su lienzo lógico al fotograma (.claude/skills/parody-short/formats.md).

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

digitalsamba/claude-code-video-toolkit

Python video composition with moviepy 2.x — overlaying deterministic text on AI-generated video (LTX-2, SadTalker), compositing clips, single-file build.py video projects. Use when adding labels/captions/lower-thirds to LTX-2 or SadTalker outputs, building short ad-style spots in pure Python without Remotion, or doing programmatic video composition. Triggers include text overlay on video, label LTX-2 clip, caption SadTalker output, lower third, build.py video, moviepy, Python video composition, sub-30s ad spot.

digitalsamba/claude-code-video-toolkit

Video and audio processing with FFmpeg. Use for format conversion, resizing, compression, audio extraction, and preparing assets for Remotion. Triggers include converting GIF to MP4, resizing video, extracting audio, compressing files, or any media transformation task.

digitalsamba/ideogram4

Prompting patterns for Ideogram 4 text-to-image — best-in-class in-image text rendering and exact color/layout control via structured JSON captions. Use when generating images that need legible on-image text (title cards, thumbnails, logos, signage, CTAs), precise brand colors, or controlled spatial layout. Triggers include title slide image, thumbnail with text, on-image text, legible text in image, brand color palette image, bounding-box layout, Ideogram.

digitalsamba/parody-short

Comedy shorts about a group's own life - a team's launch, quarter end, office move or leaving do; a club's season; a class's year; a family's Christmas - or about a shared topic everyone recognises (video calls, the return to the office), told in a borrowed genre (80s action intro, creature feature, Dickens Christmas ad, heist, nature documentary) and starring the group's real, animated photos or an invented cast. Covers mining the group's own context for in-jokes (chat, email, calendars,...

Skills relacionados