Construa um vídeo de demonstração do fluxo descrito pelo usuário. O resultado é salvo em uma pasta nova demo/vN/.
A única regra que importa: cada tela é uma transcrição da interface real, não uma impressão dela. Uma demonstração que inventa layout, texto ou componentes é pior do que nenhuma demonstração — ela ensina os espectadores sobre um produto que não existe. Leia o código-fonte de cada tela antes de escrever qualquer marcação para ela.
Entradas
/create-product-demo-video <o que deve acontecer> — uma descrição do fluxo. Se for vaga ("mostrar o
produto"), escolha o fluxo completo mais restrito que termina em valor visível, diga qual você
selecionou em uma linha, e construa-o. Não pare para fazer perguntas.
Passos
-
Mapeie o fluxo para rotas. Transforme o prompt em uma lista ordenada de rotas reais pelas quais o usuário passaria. Encontre o roteador primeiro — um diretório
routes/, uma árvoreapp/, um bloco<Routes>, um manifesto de rotas — e liste apenas os caminhos que existem. Se o fluxo precisar de uma entidade que deve ser criada antes que uma tela posterior possa existir (um projeto antes de um relatório com escopo de projeto), inclua essa tela ou escolha um escopo que não precise dela — não pule uma etapa necessária silenciosamente. -
Leia o código-fonte de cada tela. Para cada rota: o arquivo de rota, os componentes que ela renderiza, os componentes de layout compartilhados do aplicativo (shell, cabeçalho de página, estado vazio) e seus primitivos do sistema de design (
components/ui/ou onde estiverem). Leia também qualquer coisa que gere strings que a demonstração exibe — helpers de pré-visualização, nomes derivados, serviços de renderização/modelo do backend. Copie strings literalmente; não parafraseie o texto do produto. -
Estrutura inicial.
mkdir -p demo/vN(próximo N não utilizado — nunca sobrescreva um vN existente), depois copieassets/skeleton.html→demo/vN/index.htmleassets/record.mjs→demo/vN/record.mjs.assets/fica ao lado desteSKILL.md, onde quer que a skill esteja instalada — um diretório de cache de plugins,~/.claude/skills/, ou.claude/skills/de um projeto. Resolva-o a partir do próprio diretório da skill, nunca do repositório que está sendo demonstrado. O esqueleto carrega um shell placeholder, uma escala de token e o mecanismo de reprodução. Para uma demonstração com trilha sonora, copie também a faixa escolhida deassets/music/→demo/vN/music.mp3— veja Música. Copiá-la (em vez de referenciar a pasta da skill) é o que permite regravarvN/depois, pela mesma razão querecord.mjsé copiado por versão. -
Adapte o esqueleto a este produto. Tudo marcado como
REPLACE:é um placeholder que deve ser substituído antes que qualquer cena seja escrita, porque cada tela o herda:Em index.htmlSubstitua por PRODUCTO nome do aplicativo, o host que sua barra de endereço mostra e seu logotipo svg real NAVA barra lateral transcrita da navegação real — mesmas seções, mesma ordem, mesmos rótulos TOPBARA barra superior real; remova controles que o aplicativo não possui Tokens :rootO bloco :rootda folha de estilo do aplicativo, para que cor/raio/tipo correspondamICONSDados de caminho do conjunto de ícones que o aplicativo realmente usa Remova os blocos CSS opcionais (tela de terceiros, painéis de entrega) que o fluxo não usa. -
Escreva as cenas. Uma
<section class="scene" data-scene="N">por tela, em ordem. Reutilize as classes CSS do esqueleto (.pagehead,.card,.btn,.seg,.opt,.chip,.scopeid,.statusbadge,.empty,.input,.pillbar,.toast) — elas são moldadas como a saída de um sistema estilo Tailwind/shadcn, então verifique cada uma em relação às classes reais do componente e ajuste em vez de presumir. Adicione novo CSS apenas para um componente que o esqueleto não possui, e derive-o das classes reais desse componente. -
Escreva
play(). Cartão de título → telas → encerramento. Use legendas para nomear cada etapa e definaCAPTIONSno topo do script — o estilo esteps= quantas chamadassay()a execução faz. As interações passam pelos helpers do ponteiro para que o espectador possa acompanhar o que está sendo clicado. -
Grave.
node demo/vN/record.mjs→demo/vN/out/product-demo.mp4. Adicione--gifpara um gif de 900px. Um arquivodemo/vN/music.*é detectado automaticamente;--music <caminho>aponta para um em outro lugar,--music-db <n>desloca o nível,--no-musicforça silêncio. -
Verifique olhando. Extraia quadros e leia as imagens — isso não é opcional, é como bugs de layout são detectados:
for t in 5 12 20 28 36 44; do ffmpeg -y -loglevel error -ss $t \ -i demo/vN/out/product-demo.mp4 -frames:v 1 /tmp/f$t.png; doneVerifique: sem ícones superdimensionados, nada cortado na dobra, o ponteiro pousa no elemento que afirma clicar, o texto não está colapsado em uma linha. Corrija e regrave até ficar limpo.
Os quadros não mostram o áudio. Em uma demonstração com trilha sonora, verifique também o fluxo e as rampas —
volumedetectregistra em nível de informação, então-v errorengoliria sua saída:ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,duration \ -of default=nw=1 demo/vN/out/product-demo.mp4 for w in "-ss 0 -t 0.25" "-ss 12 -t 0.5" "-sseof -0.25"; do \ ffmpeg -hide_banner -nostats $w -i demo/vN/out/product-demo.mp4 \ -af volumedetect -f null - 2>&1 | grep mean_volume; doneEspere um fluxo
aacdentro de ~0,05s da duração do vídeo,max_volumeabaixo de 0 dB, e as médias do início e fim bem abaixo da média do meio — isso é o fade provando que funcionou. -
Escreva
demo/vN/README.md— tabela de cenas com rotas, o mapeamento de arquivos-fonte, duração, o estiloCAPTIONSe a faixa de música com a qual a versão foi gravada, e o que o fluxo deliberadamente pula. Atualizedemo/README.mdpara listar a nova versão.
Relate o caminho, duração e tamanho, depois abra o mp4 para que o usuário possa assisti-lo — open no
macOS, xdg-open no Linux, start no Windows.
API do Mecanismo
Disponível dentro de play():
| Chamada | Efeito |
|---|---|
scene(n) | Transição para cena n, atualiza a barra de endereço de URLS |
tap(sel, ms) | Move o ponteiro até o elemento e clica (ondulação + pressão) |
moveTo(sel, ms) / click(sel) | As duas metades, quando você precisa de mudanças de estado entre elas |
hideCursor() / place(x, y, 0) | Redefine o ponteiro ao entrar em uma cena |
say(texto, opts?) / hush() | Legenda entra/sai. { at: sel } ancora uma legenda coach; { step: n } força o índice |
type(el, texto, ms) | Digitação caractere por caractere em um <span> |
wait(ms) | Pausa |
reveal(el) | Chamado automaticamente por moveTo — rolagem suave de .main para que alvos fora da dobra fiquem visíveis |
Defina window.__demoDone = true no final (o esqueleto já faz isso) — o gravador espera por ele.
Design de legendas
const CAPTIONS = { style: 'pill', steps: 6 } fica com URLS no topo do mecanismo. Todos os quatro
estilos estão incluídos no esqueleto; say() é a mesma chamada independentemente de qual esteja ativo.
Escolha por vídeo:
style | O que é | Escolha quando |
|---|---|---|
pill (padrão) | Cápsula de tinta, centro inferior | Qualquer coisa curta e voltada ao marketing. Menos oclusão, ~10 palavras por legenda |
lower-third | Bloco ancorado à esquerda com índice de etapa + barra de progresso | Fluxos mais longos onde o espectador deve sentir a sequência; mais legível em um gif |
rail | Faixa de 68px sob a janela, pontos de capítulo | Documentação e clipes de suporte onde nada pode ser coberto. Custa altura do app — veja abaixo |
coach | Chamada ancorada ao elemento em ação, resto escurecido | Walkthroughs de acompanhamento. Cada legenda precisa de { at: sel }; as sem ele recaem em pill |
steps controla o índice, a barra de progresso e os pontos da faixa — conte as chamadas say() e defina-o,
ou a execução termina mostrando 05 / 06. Não sabe qual estilo? Abra index.html em um navegador e alterne
CAPTIONS.style — a página repete com R, então todos os quatro podem ser comparados sem gravação.
Música
Opcional, e desligada a menos que uma faixa esteja presente. A base é multiplexada no momento da codificação — o Playwright não captura áudio algum, então nada disso toca na página de demonstração ou no mecanismo.
node demo/vN/record.mjs # usa demo/vN/music.* se presente, silencioso se não
node demo/vN/record.mjs --music ~/beds/x.mp3 # caminho explícito vence o irmão
node demo/vN/record.mjs --music-db -4 # base mais silenciosa
node demo/vN/record.mjs --no-music # silencioso mesmo com uma faixa irmã
- Faixas incluídas ficam em
assets/music/, uma linha por arquivo em seuLICENSES.md. Nenhuma faixa é distribuída sem uma linha CC0/CC-BY verificável — um mp3 sem licença é um problema para todos que instalam isso, não só seu. Em dúvida? Mantenha fora do repositório e passe--music <caminho>. - Nível é normalizado, não definido. Cada faixa é ajustada para −18 LUFS com um teto de pico
verdadeiro de −1,5 dB, para que bases trocadas entre versões correspondam sem ajuste manual.
--music-dbdesloca esse alvo; não adiciona ganho adicional. - Fades são automáticos — 1,5s de entrada, 2,5s de saída, a saída cronometrada pela duração real do vídeo.
- Escolha uma faixa mais longa que o vídeo. Qualquer coisa mais curta é repetida e a emenda é audível; o gravador avisa quando precisa fazer isso. 60s+ cobre uma demonstração normal de 40–60s.
- Sem vocais, sem quedas bruscas. O espectador está lendo legendas e texto da interface ao mesmo tempo.
- Áudio vai apenas no mp4. O webm é a captura silenciosa bruta, e um gif não tem faixa de áudio
alguma — uma mudança apenas na música é invisível na saída
--gif.
Convenções
- O palco é um navegador simulado fixo de 1280×800; 44px disso são o chrome do navegador, deixando 1280×756 para o aplicativo. O esqueleto fornece um