Communitygithub.com

digitalsamba/synthetic-ui-demo

Crie vídeos de demonstração de produtos e notas de versão sem gravação de tela. Reconstrói as telas do aplicativo como React estático a partir do código-fonte e as apresenta no Remotion com um cursor e câmera roteirizados.

O que é synthetic-ui-demo?

Esta skill permite gerar vídeos de demonstração de produto, tours de funcionalidades e notas de versão sem precisar gravar a tela real ou depender de ambientes vivos. Ela funciona lendo o repositório do produto, reconstruindo apenas as telas necessárias como componentes React estáticos (sem estado ou efeitos colaterais) e usando o Remotion para orquestrar uma câmera e um cursor animados quadro a quadro. Isso garante que cada clique seja um número de frame — o vídeo renderiza sempre de forma idêntica, não precisa de contas com dados de teste nem de ambientes em execução, e é atualizado simplesmente editando o código quando o produto muda. É ideal para cenários onde uma gravação com Playwright seria frágil (por exemplo, por depender de dados reais ou estado de sessão) ou para notas de versão que precisam ser refeitas a cada release. A skill suporta múltiplos aplicativos em um mesmo vídeo, sincronização de áudio com âncoras de palavras, e inclui ferramentas de controle de qualidade para verificar layout, contraste e loudness.

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

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Demonstrações de UI Sintéticas

Nada é gravado da tela. Claude Code lê o repositório do produto, reconstrói apenas as telas que uma cena mostra como React estático, e um cursor e câmera roteirizados executam o fluxo no Remotion. Cada clique é um número de frame, então uma cena é renderizada de forma idêntica, nunca precisa de uma conta com dados pré-cadastrados ou de um ambiente ativo, e é atualizada editando o código quando o produto muda.

Builds de referência (leia-os junto com esta skill; ambos compilam sem os repositórios do produto):

  • examples/ds-free-schedule-demo: um fluxo de 26s (agendar uma chamada) com um tile de narrador. O caso completo mais simples. Seu src/Demo.tsx é uma única linha do tempo com todos os keyframes do cursor, cliques e movimentos de câmera.
  • examples/ds-release-649: um vídeo de notas de versão de 80s, oito cenas em três aplicativos. templates/ds-release-notes é a forma reutilizável dele (lançado como release 650). src/Release.tsx sequencia as cenas, src/scenes/ tem um arquivo por item de release, e src/room/ e src/ac/ são os kits de tela.

Quando usar isto vs. Playwright

Sintético (esta skill)Gravação Playwright (/record-demo)
Você pode ler o código-fonte do aplicativoVocê só tem o aplicativo em execução
Notas de versão e tours de funcionalidades que são refeitos a cada releaseCaptura única de comportamento real ou dados reais
O fluxo precisa de dados que você não tem (uma chamada completa, outros usuários, uma visão de admin)A coisa real é fácil de acessar e parece boa como está
Movimentos de câmera, tempo exato de clique, re-renderização após uma mudança de vozInterações longas e complexas que seriam caras para reconstruir

Blocos de construção (lib/components)

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

<Stage
  url="app.example.com/settings"             // barra de endereço; host mais escuro que o caminho
  camera={CAMERA}                             // [{ f, z, x, y }] em px do canvas, suavizados, limitados à janela
  path={PATH}                                 // [{ f, x, y }] keyframes do cursor em px do canvas
  clicks={CLICKS}                             // frames que achatam o cursor e lançam uma ondulação
  aiNote                                      // "As pessoas mostradas são geradas por IA" (ou passe seu próprio texto)
  canvasWidth={1440} canvasHeight={810}       // os padrões
>
  <SettingsScreen field={typed(frame, 'Revisão Q4', 128)} />
</Stage>
  • Stage desenha a borda do navegador ao redor de um canvas de tamanho fixo, aplica a câmera e coloca o cursor no topo com zIndex 100. No zoom 1 a janela é fit (0.8625) da largura do frame. Keyframes repetem um valor para mantê-lo.
  • Cursor e cursorAt funcionam sozinhos para uma cena sem navegador; near(cursor, target) aciona estados de hover.
  • Kits de tela específicos do produto (tema, ícones, layouts) ficam no projeto. Eles não são material da biblioteca.

Método

1. Extraia uma especificação visual do repositório do aplicativo, com subagentes

Envie um subagente por aplicativo ou área, em paralelo, e faça cada um retornar uma especificação compacta em vez de despejos de arquivos:

  • Tema: paleta, família de fontes, raios, espaçamento, sombras (do arquivo de tema ou variáveis CSS).
  • Strings: as strings exatas de localização em inglês para cada rótulo, item de menu, diálogo e toast que a cena mostra (public/locales/en/*.json, src/i18n/locales/en/*). Nunca parafraseie texto da interface.
  • Ícones: se o aplicativo usa uma fonte de ícones, seu arquivo selection.json (icomoon/fontello) contém os paths SVG de cada glifo. Extraia os que você precisa em um pequeno JSON e renderize-os como <svg><path d=...>. Caso contrário, copie os componentes SVG.
  • Layout e comportamento: árvore de componentes para as telas mostradas, ordem da barra de ferramentas, padrões, o que cada controle faz.

Leia o branch padrão do remoto (git show origin/main:path, ou git fetch e depois leia origin/<default>). Checkouts locais estão frequentemente desatualizados e lhe darão a interface do trimestre passado.

Para notas de versão, rastreie cada item até o commit e o componente que o entrega primeiro. Isso lhe dá as strings exatas e os valores padrão a serem mostrados.

2. Reconstrua apenas o que uma cena mostra, em um canvas fixo

  • Disponha cada elemento com posições absolutas em um canvas fixo (1440x810 é um bom padrão). Exporte os retângulos importantes como constantes (SAVE_BTN = { x, y, w, h }), para que os alvos de clique sejam aritméticos, não suposições.
  • Construa apenas o que a câmera vê. Um painel que nunca está no quadro pode ser uma cor sólida.
  • Mantenha-o React estático: sem estado, sem efeitos. Toda mudança visual é uma função de frame.
  • Coloque o kit em sua própria pasta (src/ui/, src/room/) com um theme.ts para constantes.

3. Voz primeiro, depois coloque a linha do tempo em frames

  • Escreva uma linha por cena, dividida em sentenças (um .txt por frase), e gere o áudio primeiro (voiceover.py --scene-dir ...). Três takes e tools/pick_takes.py vencem um take único mais --max-wpm: um clone copia o ritmo e a monotonia do clipe de referência, então se as linhas saírem apressadas ou monótonas, corrija o clipe com tools/voice_prosody.py expand em vez de esticar a saída (veja "Clone Prosody" no CLAUDE.md). Leia as durações medidas e tools/captions.py para temporizações de palavras.
  • Dimensione cada cena para sua linha mais uma pausa, e mantenha um comentário de cabeçalho listando o início e a duração de cada linha. Esse comentário é a fonte da verdade (veja "Audio-Anchored Timelines" no CLAUDE.md).
  • Tudo é uma constante de frame no topo do arquivo da cena: keyframes do cursor, CLICKS, keyframes da câmera, mudanças de estado da UI (frame >= C.save mostra o diálogo). Exporte os frames de clique para que o pai possa colocar efeitos sonoros de clique.
  • Consulte os frames a partir da narração, não os defina manualmente. voice() (lib/components/cues.ts; o modelo ds-release-notes tem uma cópia) pega as frases da cena com seus .captions.json e frames de início, e cue('save') retorna o frame em que a palavra começa. Ancore cada ação à palavra que ela ilustra, com um deslocamento, e cada keyframe de cursor e câmera a essas âncoras:
    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('antes', { offset: -3 }), save: cue('salvar') };
    const PATH = [{ f: C.field - 6, ...field }, { f: C.save - 24, ...saveBtn }];
    
    Regere ou re-temporize uma frase e os cliques, digitação, cursor e câmera a seguem. Uma deixa cujas palavras não são mais ditas falha no bundle com as palavras que são. Opções: offset, edge: 'end', after (um frame, para uma palavra repetida), nth, in (uma frase). O pai posiciona o áudio de LINK_VOICE.lines, então o frame de início de uma frase é escrito uma vez. templates/ds-release-notes/src/scenes/FreeCustomLink.tsx é o exemplo prático.

4. Divida linhas de lista densas em suas pausas

Uma linha que lista várias coisas ("agendamento, contatos, gravações e transcrições") é rápida demais para um único take. Divida o áudio em suas pausas em arquivos de frase (07a, 07b, ...), dê a cada frase seu próprio take, e coloque cada frase em seu próprio tempo. ds-release-649's campo moreVo faz isso.

5. Meça os alvos de clique a partir de uma folha de contato antes da renderização completa

Uma coordenada adivinhada geralmente está 20-50px fora depois que a câmera dá zoom. Renderize stills em cada frame de clique e alguns frames antes, disponha-os em grade e verifique se a ponta do cursor está sobre o alvo:

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

Corrija as constantes, re-renderize os stills e só então renderize o vídeo.

6. Rotule pessoas geradas por IA na tela

Qualquer pessoa que não seja real (retratos FLUX.2 em tiles, avatares, um narrador) recebe um rótulo visível: aiNote no Stage, ou um selo "IA" em um tile de narrador. Nomes, contatos e dados de chamada também são inventados, então mantenha-os claramente ficcionais.

7. Renderize, depois normalize

tools/qc.py --project ... antes de renderizar, depois qc.py --render out/video.mp4 --fix para -14 LUFS. qc.py --project ... --layout verifica o texto do próprio vídeo (legendas, cards, a nota de IA) quanto a tamanho e contraste, e lista o texto da UI do produto separadamente. Stage marca sua janela data-qc="product"; coloque o mesmo atributo em qualquer mockup de telefone ou tablet que você construir fora dele, ou seu texto de UI será julgado como o do vídeo.

Armadilhas

  • Logos SVG monocromáticos renderizam pretos. Um logo_mono.svg geralmente tem preenchimentos pretos; em um fundo escuro use filter: brightness(0) invert(1).
  • Branches locais desatualizados. Leia origin/<default>, não o branch em que o checkout local está.
  • rsync --exclude src também remove node_modules/*/src. Ao copiar um projeto ou kit, ancore exclusões à raiz de transferência com uma barra no início: --exclude /src.
  • A câmera limita. Um centro de câmera próximo à borda do canvas é puxado para dentro para que a borda da janela nunca apareça além do frame. Se um zoom pousar em algum lugar inesperado, é por isso; aponte para um ponto mais para dentro.
  • Menus e diálogos devem ficar dentro do canvas. O canvas recorta seus filhos. Posicione um menu para que ele abra para dentro, como o aplicativo real faz.
  • Estados de hover vêm do caminho do cursor. Use near(cursorAt(frame, PATH), target) em vez de um segundo conjunto de constantes de frame, para que mover um keyframe mova o hover junto.
  • Uma linha de voz alterada move tudo depois dela. Em uma cenário com deixas, os cliques, cursor e câmera seguem por conta própria, mas a duração da cena e os at das frases posteriores ainda precisam ser verificados. Em uma cena com frames manuais, re-meça cada frame. De qualquer forma, atualize o comentário de cabeçalho e as durações das cenas, depois verifique novamente os stills de clique. Se um narrador com sincronia labial for orientado pela trilha de áudio montada, regere-a também.
  • Um kit sobrevive à sua demonstração. Um kit de tela reconstruído pode hospedar outros vídeos: a sala ds-release-notes se tornou o palco de uma edição de marca de um curta de paródia, com rostos animados em seus tiles e nenhum novo trabalho de tela. Copie o kit para o novo projeto e dimensione seu canvas lógico para o frame (.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,...

Habilidades Relacionadas