skailabinfo/claude-video-harness

Configuração inicial do projeto para um novo usuário — verificação do ambiente e entrevista detalhada (quem é você; ~10 reels de referência e análise de gosto; transcrição; conexão de serviços com verificação de acesso; paleta; fontes; legendas, gráficos, movimento, som), com exibição de opções por meio de quadros prontos; geração de harness.config.json, brand-kit.md, editing-taste.md, exemplars.md. Execute quando "configured" em harness.config.json for false, ou quando o usuário solicitar reconfiguração do projeto / mudança de estilo / reanálise de referências.

O que é claude-video-harness?

Esta skill (para Claude Code) conduz a configuração inicial completa de um pipeline de edição de vídeos verticais (tipo "talking head") no estilo do usuário, utilizando Remotion. Ela realiza uma entrevista interativa e estruturada em blocos: primeiro, identifica o usuário, sua marca e tom; em seguida, coleta cerca de 10 links de Reels/TikTok/Shorts como referências de estilo. As referências são baixadas e analisadas automaticamente por um script Python (refs.py) para extrair métricas como ritmo, cortes, paleta de cores e padrões visuais. A skill então guia a escolha de serviços de terceiros (ElevenLabs para transcrição e áudio, Higgsfield para b-roll gerado por IA, 21st.dev para componentes React, Buffer para agendamento), verificando o acesso a cada um. Finalmente, apresenta opções visuais (paletas, fontes, estilo de legendas, cards, movimento) através de quadros gerados por scripts Python (variants.py), permitindo que o usuário escolha suas preferências. Toda a configuração é salva em arquivos de perfil (harness.config.json, brand-kit.md, editing-taste.md, exemplars.md), documentando o "gosto editorial" do usuário para uso futuro. A skill é projetada para ser executada uma vez no início do projeto ou quando o usuário desejar redefinir o estilo.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/skailabinfo/claude-video-harness/tree/HEAD/.claude/skills/setup

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

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

Documentação

Configuração do Projeto

Objetivo: transformar um clone limpo em um pipeline que monta no estilo dessa pessoa — entender o que ela gosta, conectar seus serviços e mostrar quadros do seu futuro vídeo. Fale no idioma do usuário, de forma curta e humana.

O projeto não tem estilo próprio. Tudo que diz respeito à aparência do vídeo — paleta, fontes, legendas, cards, stickers, pôster, ritmo, punch-ins, gradação, som — é escolhido pelo usuário ou extraído de suas referências. Você não oferece uma opção "padrão" ou "popular", não insere suas preferências e nada do que já está no projeto (placeholders em harness.config.json e demo não são estilo, são espaço vazio).

Regras da Entrevista

  • Um bloco — uma mensagem, blocos nunca são combinados. Não coloque dois blocos em um único AskUserQuestion: as pessoas clicam na primeira opção de uma lista de perguntas. Blocos 4 (serviços), 6 (paleta), 7 (fontes), 8 (aparência da edição) — conversa de várias mensagens.
  • Sem "(recomendo)" sobre gosto. A marcação é permitida apenas para escolhas puramente técnicas — método de transcrição (bloco 3). Para cores, fontes, estilo, serviços e perguntas sobre a pessoa, não há essa marca; descreva as opções de forma neutra, explicando o que cada uma oferece.
  • Opções — a partir das respostas e referências da pessoa. Se não houver respostas nem referências, monte 2–3 opções visivelmente diferentes adequadas ao tema e tom dela e mostre com quadros; a escolha é dela.
  • Mostre, não descreva: paleta, fontes e aparência da edição — com quadros prontos via video/scripts/variants.py.
  • Pular bloco ("pule") — apenas por palavra do usuário. Nesse caso, o perfil mantém um placeholder neutro, e isso é dito claramente: "pode configurar depois — diga 'configure legendas'".
  • Não suponha nada sobre a pessoa. Marca, nome, tema, público e tom — apenas a partir das respostas dela, não do e-mail da conta, nome no sistema, nome da pasta ou link do repositório. O nome da conta no link do repositório é o autor do template, não o usuário.
  • Técnica não é levada para a entrevista: zonas seguras, cortes sem caudas aparadas, loudnorm de duas passadas, mecânica de punch-ins nas emendas — isso não é gosto, é como o pipeline funciona (CLAUDE.md, "Mecânica").
  • Chaves nunca passam pelo chat. O usuário as insere em video/.env; você verifica o acesso através do doctor.sh, sem imprimir nada. Se ele enviou a chave no chat — não use, recomende revogá-la e criar uma nova.
  • Tudo que é instalado via brew / pip ou pesa muito — primeiro "o que é e quanto", depois "sim".

Passo 0. Boas-vindas (uma mensagem)

Duas ou três linhas: isto é montagem de vídeos verticais "talking head" via Claude Code + Remotion; o projeto não tem estilo próprio — agora vamos configurar tudo para você: conte sobre você, envie ~10 Reels de que gosta, escolheremos cores, fontes e aparência da edição (mostrarei opções com quadros), conectaremos os serviços necessários. Vá direto para o Passo 1.

Passo 1. Ambiente

cd video && ( [ -d node_modules ] || npm install ) && bash scripts/doctor.sh

Mostre o resultado em uma tabela resumida. Para cada MISSING, sugira o comando da saída e, após concordância, execute:

  • Skills do Remotion (obrigatório): npx -y skills add remotion-dev/skills --skill '*' --agent claude-code -y a partir da raiz do projeto.
  • ffmpeg, node, python3, yt-dlp (para referências) — brew install … (macOS); Linux — gerenciador de pacotes; Windows — WSL.
  • whisper / rembg — quando forem necessários com base nas respostas (passo 3).

Não tem brew — forneça o link https://brew.sh e aguarde (a instalação pede senha, é feita pelo próprio usuário).

Passo 2. Entrevista

Bloco 1 — quem é você

Marca / nome do canal; quem aparece no quadro; sobre o que são os vídeos; plataformas e handles (Reels, TikTok, Shorts, Telegram…); público; tom; idioma dos vídeos; call to action final.

Pergunte de forma aberta — deixe-o responder com suas próprias palavras, mesmo em uma mensagem. Se oferecer opções (para tom ou CTA), que sejam neutras e iguais para qualquer pessoa, sem tema ou nicho inserido.

Bloco 2 — referências (~10 Reels)

Peça: "Envie cerca de 10 links de Reels de que você gosta visualmente — Instagram, TikTok ou Shorts. De preferência aqueles em que você gostaria de se inspirar. Através deles, entenderei seu gosto: ritmo, legendas, gráficos, cores, fontes." Menos de 5 — peça mais: com 3 vídeos não é possível extrair um gosto geral. Explique que, sem referências, será necessário perguntar com mais detalhes nos blocos 6–8.

Ao receber os links — inicie a análise em segundo plano imediatamente e vá para o bloco 3:

cd video && python3 scripts/refs.py "URL1" "URL2" … > ../takes/refs.log 2>&1     # run_in_background

O script baixa para takes/refs/ (não vai para o git) e mede: duração, frequência de troca de cena, mudanças no hook, volume, ritmo da fala, primeira frase, cores vibrantes (palette.png); gera NN-sheet.jpg (24 quadros por vídeo) e NN-hook.jpg (primeiros 3 segundos). Se parte dos links falhar com exigência de login — opções de SERVICES.md → "Instagram": reiniciar com COOKIES_FROM=chrome (apenas com "sim" explícito) ou o usuário baixa manualmente e coloca mp4 em takes/refs/ (então passe os caminhos em vez dos links).

Bloco 3 — Transcrição da fala

  • whisper.cpp local (recomendo no Mac): gratuito, offline; brew install whisper-cpp + modelo large-v3-turbo 1.6 GB.
  • ElevenLabs Scribe: pago (créditos), não instala nada, funciona em qualquer sistema; precisa de chave (bloco 4).

Bloco 4 — Serviços (uma mensagem por serviço)

Não pergunte com uma única questão "o que conectar?". Passe pelos serviços um por um — uma mensagem por serviço: o que ele oferece na edição (1–2 linhas com exemplo), quanto custa, o que é necessário do usuário e quanto tempo leva. Pergunta: "conectamos agora / depois / não precisa".

serviçoo que oferece na ediçãoacessotempo
ElevenLabstranscrição Scribe; acentos sonoros de acordo com seu gosto; narraçãoChave de API~3 min
Higgsfieldpequenas inserções de vídeo (b-roll) quando se fala sobre algo que pode ser mostradologin via navegador~2 min + após reinicialização
21st.devcomponentes React prontos como base para novos gráficosChave de API~3 min
Bufferrascunhos de posts no Reels / TikTok / Shortslogin via navegador + canais no Buffer~5 min

Ordem: ElevenLabs → Higgsfield → 21st.dev → Buffer. Se no bloco 3 foi escolhido Scribe — ElevenLabs é obrigatório, diga isso. "Depois" e "não precisa" são respostas normais.

Para cada um que responder "agora" — execute a seção de SERVICES.md: links e etapas com suas palavras, aguarde "pronto", configure sua parte e verifique:

  • Chaves (ElevenLabs, 21st.dev): se video/.env não existir — cp video/.env.example video/.env; o usuário insere a chave manualmente (open -e video/.env). Verificação — bash video/scripts/doctor.sh, seção access. Se rejeitada — provavelmente copiada incompleta ou sem as permissões necessárias; peça para criar uma nova.
  • 21st.dev: após verificar a chave, adicione o servidor localmente (a chave é lida do .env diretamente no shell):
    cd video && set -a && . ./.env && set +a && cd .. && claude mcp add --transport http 21st https://21st.dev/api/mcp --header "x-api-key: $TWENTYFIRST_API_KEY" --scope local
    
    Se claude não estiver no PATH — forneça este comando para o usuário executar no terminal.
  • OAuth (Higgsfield, Buffer, opcionalmente ElevenLabs MCP): adicione os servidores escolhidos no .mcp.json raiz:
    {
      "mcpServers": {
        "higgsfield": { "type": "http", "url": "https://mcp.higgsfield.ai/mcp" },
        "buffer": { "type": "http", "url": "https://mcp.buffer.com/mcp" },
        "elevenlabs": { "type": "http", "url": "https://api.elevenlabs.io/v1/mcp" }
      }
    }
    
    Login via navegador — após reiniciar o Claude Code (/mcp → servidor → Authenticate): avise agora e lembre no passo 5. Para Buffer, peça para conectar os canais antecipadamente no próprio Buffer (Instagram — conta profissional).

Marque os conectados em integrations. Se travar em um serviço por 15+ minutos — sugira adiar: "conectamos depois — diga 'conecte Buffer'".

Bloco 5 — o que você gosta (com base nas referências)

Aguarde o fim da análise (ps -axo command | grep "[r]efs.py"), leia takes/refs/refs.json, veja cada NN-hook.jpg, NN-sheet.jpg e palette.png. Para cada vídeo, anote o que os números não mostram: legendas (posição, tamanho, caixa, peso, cor, destaque de palavras, fundo), gráficos (cards e sua aparência, stickers, screenshots, b-roll, emojis), enquadramento e punch-ins, proporção de rosto, paleta de gráficos, fontes, o que está no hook (texto-pôster, pergunta, ação), final.

Resuma em um "perfil de gosto": 5–7 padrões que aparecem em pelo menos metade dos vídeos, com números (medianas de refs.py). Mostre em uma única mensagem e pergunte: "isso se aplica a você? o que disso você quer e o que não quer?" O que for aceito se tornará sugestões nos blocos 6–8 — lá você mostra os quadros dele ao lado de outras opções, não aplica silenciosamente. O que não se encaixa nas configurações (emoji stickers, tela verde…) — registre como desejo no perfil.

Bloco 6 — Paleta (2–3 mensagens)

6.1 Perguntas — em uma mensagem, texto aberto:

  • Existem cores da marca — logotipo, site, identidade visual do canal, capas? Envie hex, link do site ou coloque o logotipo / screenshot em takes/brand/.
  • O que nos vídeos deve se destacar com cor: números, palavras-chave, CTAs?
  • Qual sensação é necessária: sóbria, acolhedora, vibrante, calma?
  • Quais cores definitivamente não?

Se ele enviar uma imagem — extraia as cores principais:

python3 -c "
from PIL import Image; import sys
im = Image.open(sys.argv[1]).convert('RGB').resize((200, 200)).quantize(6)
pal = im.getpalette(); cnt = sorted(im.getcolors(), reverse=True)
print([('#%02X%02X%02X' % tuple(pal[i*3:i*3+3]), round(100*n/40000)) for n, i in cnt])
" takes/brand/logo.png

Link do site — abra e encontre as cores principais (logotipo, botões, variáveis CSS).

6.2 Candidatos — 2–3 paletas com quatro papéis: dark (placas, telas), light (texto), accent (destaque), pain (card de "não fazer assim", se necessário):

  • das referências — recurring_colours em refs.json e palette.png; confira com os storyboards se a cor é de gráfico ou texto, e não parede, objeto no quadro ou pele;
  • das cores da marca, se houver;
  • com base nas respostas 6.1 — sensação e o que destacar.

Legibilidade (técnica, não gosto): o texto sobre placa e sobre o footage deve ser legível — verifique o contraste de cada candidato (light sobre dark ≥ 7:1, accent sobre dark ≥ 3:1); se o candidato não passar — avise e ofereça o mais próximo que passe:

python3 -c "
import sys
def L(h):
    c=[int(h[i:i+2],16)/255 for i in (1,3,5)]
    c=[x/12.92 if x<=0.03928 else ((x+0.055)/1.055)**2.4 for x in c]
    return 0.2126*c[0]+0.7152*c[1]+0.0722*c[2]
a,b=sorted([L(sys.argv[1]),L(sys.argv[2])]); print(round((b+0.05)/(a+0.05),1))
" '#FFFFFF' '#141414'

6.3 Mostre com quadros:

cd video && python3 scripts/variants.py out/palette-options.png 70,368 \
  '{"label":"A","colors":{"dark":"#…","light":"#…","accent":"#…","pain":"#…"}}' \
  '{"label":"B","colors":{…}}' '{"label":"C","colors":{…}}'

Mostre a imagem (SendUserFile), legendando: "A — das suas referências, B — do logotipo, C — pela sensação". Ajustes ("A, mas o accent mais escuro") — nova execução. O escolhido vai para colors.

Bloco 7 — Fontes (2–3 mensagens)

Duas fontes: texto (legendas e cards, pesos 500 / 600 / 700) e pôster (título no início do vídeo, se houver). Ambas devem suportar o alfabeto do idioma dos vídeos.

7.1 Perguntas — em uma mensagem: existem fontes da marca (nomes ou arquivos em takes/brand/); qual o caráter — sóbrio, amigável, tecnológico, editorial; legendas leves ou densas.

Se houve bloco 2 — veja as legendas e títulos nos storyboards e diga o que vê: tipo (grotesco geométrico, neo-grotesco, estreito, arredondado, serifado), peso, caixa. Não adivinhe o nome exato através da imagem — escolha uma fonte livre semelhante.

7.2 Candidatos — 2–3 pares "texto + pôster" do @fontsource com o alfabeto necessário, diferentes em caráter, de acordo com suas respostas e referências. Para russo, verifique cirílico; Bebas Neue — apenas latim. Fonte da marca comprada — coloque em video/src/fonts/ + @font-face com font-display: block manualmente; lembre sobre a licença se o repositório for público.

7.3 Mostre com quadros:

cd video && npm i @fontsource/<a> @fontsource/<b>                  # candidatos
ls node_modules/@fontsource/<a>/ | grep -c cyrillic                # para ru > 0
ls node_modules/@fontsource/<a>/ | grep -E '^[0-9]+\.css$'         # pesos disponíveis
grep -m1 font-family node_modules/@fontsource/<a>/400.css          # nome exato da família

Adicione em video/src/index.css as importações dos pesos dos candidatos (@import "@fontsource//600.css"; …), depois:

python3 scripts/variants.py out/font-options.png 70,368 \
  '{"label":"A","fonts":{"text":"…","poster":"…","posterWeight":700}}' '{"label":"B","fonts":{…}}'

Mostre, legendando. Após a escolha, mantenha em index.css apenas as importações selecionadas e remova os pacotes extras (npm un …).

Bloco 8 — Aparência da edição (uma mensagem por tópico)

Quatro tópicos, cada um em mensagem separada: pergunta, o que é visto nas referências ("em 7 de 10 legendas centralizadas, grandes"), depois 2–3 opções com quadros via variants.py (chaves style.*, quadros 70,270,368). Sem "recomendo".

8.1 Legendas (style.captions):

  • posição: cycle — frases vagam pelo quadro (canto superior esquerdo → canto superior direito → inferior); rail — sempre embaixo; center — centralizado;
  • tamanho size: [palavra normal, palavra destacada] em px (~48 pequeno, 60 médio, 76 grande);
  • peso weight (500–800); caixa case: lower / asis / upper;
  • destaque highlight: color (palavras-chave na cor de destaque) / size (maior) / both / none;
  • fundo box: true — placa sob a linha, false — sombra.

8.2 Gráficos:

  • cards style.cards: glass (vidro semitransparente) / solid (placa sólida) / none; frequência — em palavras em editing-taste.md §3;
  • stickers/pictogramas em pausas style.stickers: true / false;
  • pôster-título atrás da cabeça no início style.poster: enabled, caixa case (upper / asis), subtítulo pequeno kicker. Se ativado — precisa de rembg (~30 min em segundo plano por vídeo, modelo ~1 GB uma vez);
  • b-roll (se Higgsfield conectado): necessário? quantidade — em palavras em brand-kit.md §5.

8.3 Movimento e imagem:

  • ritmo style.pacing: slow (cortes mais longos, transições suaves) / medium / fast (cortes rápidos, punch-ins frequentes);
  • punch-ins style.punchins: frequent (a cada 3–5 segundos) / moderate / rare;
  • safe zones (zonas seguras) — não é uma opção, é ação do pipeline: central 90% do quadro, texto dentro de 80% central; nunca em bordas;
  • gradação style.grading: natural (cores próximas da câmera) / warm (tendência ao laranja/âmbar) / cool (tendência ao azul) / high-contrast (contraste elevado, pretos profundos).

8.4 Som:

  • música de fundo style.music: energetic / calm / none; volume ~25% da fala;
  • efeitos sonoros (transições, destaques): true / false; se true — em edting-taste.md §6 descreva o tipo (micro, digitais, ambientes);
  • voz: nível alvo do pipeline -16 LUFS (integrado), duas passadas loudnorm; não é opção.

Passo 3. Finalização

Gere ou atualize:

cd video && python3 scripts/generate_config.py     # harness.config.json

A skill salva em:

  • video/harness.config.json — configuração técnica (cores, fontes, serviços, preferências de estilo);
  • video/brand-kit.md — diretrizes da marca para uso futuro (nome, tom, público, logotipo, paleta, fontes);
  • video/editing-taste.md — perfil editorial detalhado (padrões de refs, preferências de legendas, cards, movimento, som);
  • video/exemplars.md — links e descrições dos vídeos de referência com anotações.

Após gerar, mostre uma mensagem resumo: "Tudo pronto! Agora você tem seu perfil de estilo salvo. Para gerar um vídeo, execute: cd video && bash scripts/render.sh — ele usará suas configurações e mostrará opções onde você escolher. Se quiser ajustar algo depois, diga 'configure legendas' / 'configure paleta' / 'configure estilo' — a skill vai direto ao bloco."

Notas Importantes

  • Se o usuário interromper a entrevista ou pedir para pausar, salve o progresso atual em harness.config.json (configured: false) e lembre que pode retomar com "continuar".
  • Sempre que possível, mostre exemplos visuais (quadros) em vez de apenas descrever.
  • Mantenha um tom amigável e paciente, especialmente com usuários menos técnicos.
  • Nunca compartilhe chaves de API ou tokens no chat.
  • Ao final, ofusque quaisquer chaves/tokens que possam ter sido exibidos acidentalmente.

Individual skills in this repo

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

Habilidades Relacionadas