Vídeo de demonstração do README do NewsRead
Um comando produz o mp4 de demonstração canônico:
.claude/skills/demo-video/scripts/run_demo.sh [output.mp4]
# saída padrão: docs/assets/newsread-demo.mp4
O pipeline: inicia um backend isolado (:8010, banco newsread_test) → semeia
conteúdo de demonstração → inicia o frontend (:3010, modo dev) → grava um tour
scriptado com Playwright usando o Chrome do sistema (headless, cursor animado + legendas
injetadas) → converte para mp4 H.264 com ffmpeg. Os servidores são encerrados e o
banco de dados de teste é o único tocado — a stack real docker-compose do usuário em
:3000/:8000 nunca é envolvida.
Opções: DEMO_SCHEME=dark|light (padrão dark), DEMO_SPEED=1.15 (aceleração de
reprodução no mp4), CHROME_PATH (binário alternativo do navegador).
Pré-requisitos (geralmente já presentes nesta máquina)
- docker-compose Postgres em execução na porta :5433 (apenas o banco
newsread_testé usado) backend/.venvsincronizado (uv sync),frontend/node_modulesinstalado- ffmpeg no PATH, Google Chrome instalado
- Acesso à internet — o tour busca comentários ao vivo do HN, pré-visualizações de feeds do catálogo e thumbnails do picsum. Offline o vídeo ainda grava, mas essas seções ficam degradadas.
- Portas 8010/3010 livres; o worker arq não deve estar em execução contra o banco de teste (ele tentaria atualizar os feeds falsos de demonstração — inofensivo, mas ruidoso).
O que o tour canônico mostra (~80s antes da aceleração)
- Cartão de título sobre a caixa de entrada carregando
- Rolagem da caixa de entrada — leitura automática marca artigos à medida que passam; contagem de não lidos diminui
- Artigo principal ("SQLite: 35% mais rápido que o sistema de arquivos") — resumo de IA em markdown
- Cobertura relacionada — clusters de embedding semeados produzem níveis MESMA HISTÓRIA + relacionado
- Comentários ao vivo do Hacker News ("Mostrar comentários" no tópico real do HN)
- Catálogo — busca "nasa", abre modal de pré-visualização do feed, inscreve-se com configurações rápidas
- Cartão de encerramento
As partes móveis (edite estas para alterar a demonstração)
scripts/seed_demo_data.py— usuário de demonstração (demo/demo-pass-1234), 4 feeds fictícios, ~16 artigos escritos à mão com resumos em markdown, embeddings pgvector artesanais (cosseno ~0.08 → "mesma história", ~0.50 → "relacionado", aleatório ≈ ortogonal → oculto). O ID do tópico HN do artigo principal é resolvido ao vivo via API do Algolia. Idempotente; recusa qualquer URL de banco que não sejanewsread_test.scripts/record_tour.js— a lista de cenas. Primeiro faz uma passagem de aquecimento não gravada para que as compilações do Next em modo dev e as imagens sejam armazenadas em cache antes da gravação.scripts/demo_helpers.js— sobreposições injetadas de cursor/legendas/cartão de título e primitivas de entrada com ritmo humano. A rolagem usa eventos reais de roda para que o IntersectionObserver de leitura automática se comporte exatamente como para um usuário.scripts/convert_to_mp4.sh— webm → H.264/yuv420p/faststart mp4.
Verificando o resultado
Não envie um vídeo que você não visualizou. Extraia quadros de verificação:
ffmpeg -i docs/assets/newsread-demo.mp4 -vf fps=1/6 /tmp/demo-frames/f%02d.png
e leia alguns — confirme que as legendas estão legíveis, as seções de resumo/relacionado/HN
realmente apareceram, e o botão de inscrição mudou para "Inscrito".
Se uma seção estiver faltando, verifique o log do gravador e $WORK/backend.log
(o diretório de trabalho é exibido no início da execução).
Colocando no README
O GitHub só renderiza um player de vídeo para mp4s enviados através do editor web
(arrastar e soltar ao editar README.md, que gera uma
URL github.com/user-attachments/assets/...) — um .mp4 commitado
referenciado por caminho NÃO será renderizado inline. Portanto: entregue o mp4 finalizado ao
usuário e diga a ele para arrastá-lo para o README no github.com. Commitar o
arquivo em docs/assets/ como uma cópia canônica ainda é válido.
Problemas conhecidos
- A inscrição na cena do catálogo aciona uma busca síncrona real daquele feed no backend — escolha feeds confiáveis (o tour busca "nasa"); a espera permite 30s.
- Nunca semeie via
POST /api/feeds— ele busca a URL do feed de forma síncrona. O script de semente insere linhas ORM diretamente. - A interface de resumo de IA do frontend fica completamente oculta se
/api/ai/statusreportar não configurado;run_demo.shexporta um placeholderNEWSREAD_OPENAI_API_KEYpara que ele renderize. Nenhum LLM é chamado: os resumos são pré-preenchidos e o endpoint de sumarização faz curto-circuito quando eles existem. - A tag de
modeldo embedding nos vetores semeados deve ser igual aoNEWSREAD_OPENAI_EMBEDDING_MODELdo servidor —run_demo.shexporta para ambos os processos; não execute o script de semente com env diferente do servidor.