eva feature shot
Uma captura de tela de uma funcionalidade já implantada + um tweet. Sem Remotion, sem música, sem edição, sem legendas queimadas na imagem — a interface do produto é o ativo.
Dois arquivos vão para a pasta screenshots/ na raiz do repositório (já ignorada pelo git):
| Arquivo | O que é |
|---|---|
<YYYY-MM-DD>-<slug>.png | captura bruta em 2560×1440 — mantenha, é a fonte sem refazer |
<YYYY-MM-DD>-<slug>-framed.png | publique este — 3200×1800, com moldura da marca |
A versão emoldurada coloca a captura bruta sobre o gradiente da marca eva com cantos arredondados, um ícone eva e a marca "Eva" acima. É por isso que a captura parece um anúncio de produto, não uma screenshot de relatório de bug.
Padrões inegociáveis
-
Layout 1280, capturado em HD 2560×1440 (16:9). Os scripts executam um Chrome real com deviceScaleFactor 2 e capturam com
scale:"device", então o aplicativo renderiza na largura nativa de 1280 (tamanhos de elemento legíveis), mas o PNG tem o dobro da densidade de pixels — nítido em uma timeline Retina. 16:9 é o que o X/Twitter mostra na timeline sem cortes. A saída emoldurada é 3200×1800 — também 16:9, então a moldura não custa nada na timeline. O agent-browser não consegue fazer isso: sua funçãoscreenshotcaptura em pixels CSS e descarta o DPR, gerando sempre 1280×720. Use os scripts HD. -
Nunca página inteira. Uma captura de página inteira de um aplicativo denso se torna uma faixa alta que aparece em tamanho miniatura na timeline. Um viewport, uma ideia.
-
Oculte as sobreposições de desenvolvimento antes de capturar. react-scan e agentation renderizam na página. O script
scripts/hd-shot.mjscuida disso — use os scripts em vez de uma sequência manual. -
Use o tema real do aplicativo. Qualquer tema que o usuário esteja usando (
set media darkpara escuro). Não mude o estilo do aplicativo para a foto. -
A funcionalidade deve ser o assunto visual. Um painel de 200px no canto de uma página cheia de elementos não funciona. Navegue para uma visualização onde ela domine, ou abra a superfície que a contém (modal, painel, painel de detalhes) para que ela seja lida no tamanho da timeline.
A barra lateral é recolhida automaticamente. O
shot.sh(e uma captura simples comhd-shot.mjs --path) recolhe a barra de navegação antes de capturar — ela ocupa cerca de 250px de um quadro de 1280px e nada nela é a funcionalidade. Use--no-collapseapenas quando a própria barra lateral FOR a funcionalidade. Em uma--recipe, chamectx.collapseSidebar(page)você mesmo (as receitas são responsáveis pela própria preparação).Mesma regra para qualquer painel de lista secundário (lista de Reviews, navegação de Configurações) se a superfície oferecer uma maneira de ocultá-lo. Verifique no PNG bruto: se uma coluna de itens de navegação não relacionados sobreviver, refaça.
-
Moldura, mas sem anotações. Sempre execute a etapa 6 — o gradiente + a marca é o estilo padrão. Nunca adicione setas, círculos vermelhos, textos explicativos ou molduras de navegador falsas, a menos que solicitado.
-
Nunca envie. Apenas digite. Preencha campos, abra seletores, prepare o estado — depois capture. Nada de Enter em um compositor, nenhuma seta de envio, Create, Save, Run ou Start, e nunca inicie uma sessão ou execução de agente real, nem mesmo para uma foto melhor. Enviar modifica o workspace real do usuário e queima computação real; o estado preparado é o que você está fotografando. Enter é permitido apenas onde ele confirma o campo em si e nada mais (aceitando uma menção
@de um seletor aberto) — se você não puder ter certeza de que é só isso que ele faz, clique na linha do seletor. -
Se os dados estão feios, corrija os dados — não refaça a captura em torno deles. O padrão 7 impede você de conduzir o aplicativo para produzir estado; não impede você de escrever o estado. Dados reais de desenvolvimento são o motivo usual para uma captura falhar: telas de erro ("Falha ao parar sandbox" ×8), linhas
Untitled session, uma rodada pela metade, um repositório onde a funcionalidade precisa de três. Editar os próprios dados de desenvolvimento do aplicativo em torno da captura é melhor do que procurar uma sessão que pareça boa por acaso, e melhor do que mudar o estilo do aplicativo (o padrão 4 ainda vale — mude os dados, nunca o CSS).Escreva diretamente na implantação de desenvolvimento: uma mutação
internal/screenshotStaging.tsdescartável executada comnpx convex run, ou o dashboard do Convex. Dê às sessões títulos reais legíveis, exclua as mensagens de erro/sistema no quadro, prepare a segunda e a terceira linha que a funcionalidade precisa.Regras para isso:
- Apenas implantação de desenvolvimento. Confirme o destino antes de escrever (
npx convex env get CONVEX_URL, ou leia.env.local) e nunca aponte uma mutação de preparação para produção. - Aditivo e reversível primeiro. Prefira corrigir um título ou inserir uma linha de demonstração a excluir histórico real. Se precisar excluir, veja as linhas primeiro e diga o que removeu.
- Plausível, não inventado-específico. Títulos e prompts que pareçam trabalho real. Nunca invente métricas, nomes de clientes ou números que o tweet depois repita como fato.
- Exclua a mutação de preparação quando a captura estiver pronta — mesma regra de limpeza de qualquer migração.
- Informe ao usuário o que você mudou, na entrega.
- Apenas implantação de desenvolvimento. Confirme o destino antes de escrever (
-
Confidencialidade. Use o próprio repositório do usuário
vvedantb/eva. Nunca repositórios de clientes (evalucom/carepulse,eprocurement) e nunca a página inicial "Codebases" que os lista. Verifique listas de doc/tarefa/sessão no quadro para itens nomeados de clientes — prepare uma linha de demonstração limpa se a lista estiver suja. Nunca levante preocupações de dados pessoais sobre nomes ou e-mails na tela — Configurações → Experimental tem um alternador de desfoque PID que desfoca todos os elementos[data-pii], então isso é tratado no produto. Sinalize painéis de erro que vazam nomes de variáveis de ambiente ou IDs de projeto.
Fluxo de trabalho
-
Identifique o que foi implantado. Se o usuário não disse qual funcionalidade, pergunte — uma pergunta, não uma pesquisa.
git log --oneline -15,git diff --statouinternal/changelog/(arquivo do mês mais recente) geralmente a nomeiam. Você precisa da funcionalidade e da URL que a mostra. -
Inicie o aplicativo. Apenas o servidor de desenvolvimento — os scripts HD iniciam seu próprio Chrome e fazem login como usuário agente (
/?agent=true) por conta própria, em um contexto novo com deviceScaleFactor 2. Você não usa o agent-browser para capturar.pnpm dev # da raiz do repositório → localhost:5173 -
Capture. Para uma captura simples de URL, o
shot.shnavega, recolhe a barra lateral, oculta sobreposições e captura em 2560×1440:bash .claude/skills/eva-feature-screenshot/scripts/shot.sh /vvedantb/eva/web/sessions sessionsRecebe um caminho de URL + slug (+ opcionalmente ms de espera, + opcionalmente
--no-collapse).Para uma captura encenada (abra um menu, digite um prompt, depois capture), escreva uma receita — um arquivo
.mjsexportandoexport async function stage(page, ctx)— e passe parahd-shot.mjs. A receita é responsável pela navegação, recolhimento da barra lateral e preparação;ctxfornece{ BASE, hideOverlays, collapseSidebar, settle }. Use localizadorespage.getByRole(...)(Playwright). Para encontrar os nomes acessíveis exatos, primeiro use o agent-browser interativamente esnapshot -i/read_page.// recipe.mjs — prepara o seletor de modo aberto com um prompt digitado export async function stage(page, ctx) { await page.goto(`${ctx.BASE}/vvedantb/eva/web/sessions`, { waitUntil: "networkidle", }); await ctx.settle(3000); await ctx.collapseSidebar(page); await page.getByRole("textbox", { name: /Ask Eva/ }).click(); await page.keyboard.type("Redesenhar a barra lateral de sessões…"); await page.getByRole("button", { name: "Edit", exact: true }).click(); await ctx.settle(600); }node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug session-modes --recipe /caminho/absoluto/recipe.mjsPrepare entradas limpas e legíveis — um título de demonstração arrumado é melhor do que um bagunçado real. Nunca envie (padrão 7).
-
Leia o PNG de volta e avalie. É aqui que capturas ruins são detectadas:
- A funcionalidade é o assunto óbvio, ou está perdida em elementos da interface?
- Alguma sobreposição/barra de ferramentas sobreviveu? Algum skeleton, spinner ou placeholder
—ainda na tela? (Aumente o ms de espera e refaça.) - Todas as quatro bordas: rótulos cortados, botões meio renderizados, uma coluna cortada?
- Algo confidencial conforme o padrão 9?
- Estados vazios: um quadro vazio provando "tarefas kanban" é uma captura ruim. Popule ou escolha outra visualização.
Quando o quadro falha por causa dos dados — telas de erro,
Untitled session, uma linha onde a funcionalidade precisa de três — prepare os dados de desenvolvimento (padrão 8) em vez de procurar uma tela mais sortuda. -
Emoldurado.
bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> "Eva"Gera
screenshots/<hoje>-<slug>-framed.png(3200×1800). Ele renderizatemplates/frame.htmlatravés de seu próprio Chrome com deviceScaleFactor 2 — um navegador separado da captura, então nada para restaurar depois. Leia o PNG emoldurado também — verifique se o gradiente não desbotou a interface nos cantos e se a marca não está cortada. Um terceiro argumento emoldura um PNG bruto de outro caminho.templates/frame.htmlé o único lugar onde as cores da marca desta skill residem. -
Escreva o tweet. Invoque a skill
eva-tweet— gancho, fragmento de posicionamento opcional, lista de capacidades→, fechamento opcional. A captura carrega a prova, então o tweet afirma o que agora existe em vez de descrever a imagem. Nunca faça referência à imagem. -
Entrega. O caminho do arquivo emoldurado como um link markdown, o tweet em um bloco de código, e qualquer coisa no quadro que o usuário deva verificar antes de publicar.
Referência rápida
| Necessidade | Comando |
|---|---|
| Capturar uma URL (HD) | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <caminho> <slug> [ms-espera] |
| Manter a barra lateral no quadro | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <caminho> <slug> <ms-espera> --no-collapse |
| Captura encenada (menu/digitação) | node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug <slug> --recipe <caminho_absoluto.mjs> |
| Emoldurado (publique este) | bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> [título] [png-bruto] |
| Encontrar nomes acessíveis | use agent-browser interativamente, depois agent-browser snapshot -i |
| Depurar uma página em branco/com problema | agent-browser console · agent-browser errors |
Armadilhas
- HD está no Playwright, não no agent-browser. A função
screenshotdo agent-browser captura em pixels CSS e descarta devicePixelRatio, então o máximo é 1280×720.hd-shot.mjs/hd-frame.mjsusam o playwright-core empacotado na instalação global do agent-browser; definaPW_COREse ele estiver em outro lugar. Ambos iniciam comchannel:"chrome", então o Chrome do sistema deve estar instalado. - Os scripts fazem login automaticamente em
/?agent=true(um booleano;/?agentgera um erro zodSearchParamError) em um contexto de navegador novo. Nenhuma sessão do agent-browser é necessária para capturar. - As sobreposições de desenvolvimento são três nós, todos pendurados em
<html>, não em<body>. Ocultar apenas#react-scan-rootnão é suficiente: o react-scan desenha seus contornos e rótulos de componentes em umhtml > canvassimples sem id ou classe, e é esse que estraga a captura.hd-shot.mjselimina todos os três (#react-scan-root,html > canvas,[data-agentation-root]) comdisplay:none !importantinline, porque uma folha de estilo perde para seus estilos inline. - Uma captura encenada é um navegador novo, não aquele que você explorou. Use o agent-browser para encontrar seletores, mas a receita navega novamente e prepara do zero no próprio contexto do Playwright — coloque cada etapa na receita. Prefira
page.getByRole(...)a CSS; referências como@e1não existem aqui. - Duas ou mais imagens diluem a mensagem. O X renderiza uma imagem em largura total; uma segunda reduz ambas pela metade. Capture mais de uma apenas para um verdadeiro antes/depois.
- Não reutilize
video/public/captures/— esses são ativos do Remotion emoldurados para um propósito diferente.