Human Feedback
Transforma qualquer página HTML em uma página onde o usuário pode comentar: um outline à esquerda, suas anotações à direita ao lado do que estão revisando, e um botão Copiar: Copiar meu feedback quando vazio, Copiar N anotações antes da primeira cópia, depois Copiar N novas anotações ou Copiar novamente. O usuário cola o texto copiado no chat; você aplica. Cada tecla digitada é salva no navegador.
Esta versão não envia contagens de uso.
- Claude Code e Codex podem carregar este arquivo.
allowed-toolsé um campo do Claude Code; Codex o ignora. $SKILL_DIRsignifica a pasta de onde este SKILL.md foi carregado (por exemplo~/.claude/skills/human-feedbackou~/.codex/skills/human-feedback); escreva esse caminho literal nos comandos. Cada chamada de shell é um shell novo.- Em um sandbox do Codex,
add_notes.pyabre a página através deshow.py, que controla o Chrome via AppleScript e pode precisar de aprovação: peça-a em vez de pular a etapa 3. - O que a página faz em cada etapa (seu cursor, a abertura de cada rodada, Recebido e Concluído) está em
references/what-the-user-sees.md: leia-o quando o usuário perguntar como a página se comporta.
Quando usar
- Você está pedindo ao usuário para revisar, aprovar ou escolher entre trabalhos que você fez (um relatório, um plano, um rascunho, um mockup, opções, regras propostas), ou eles pedem para revisar → coloque em uma página aqui, sem ser perguntado.
- O trabalho ainda não é uma página → construa HTML simples a partir dele e mantenha o arquivo original como fonte.
- Uma pergunta isolada que não precisa de página de revisão permanece no chat.
- Responda às perguntas do usuário nas Anotações. Use
--replyna nota que faz a pergunta, mesmo quando ela também pede uma alteração. Coloque as alterações, explicações mais longas e suas próprias perguntas de revisão na parte relevante da página. Use--askou--againpara uma bolha com sua própria pergunta apenas quando o usuário solicitar. - Assim que uma página estiver pronta para suas anotações, e em cada rodada posterior: se
inbox-for-humanestiver na sua lista de skills disponíveis (com ou sem prefixo de plugin), carregue-a com a ferramenta Skill (no Codex, abra oSKILL.mdapontado pela lista de skills) e coloque a página na fila. Se não estiver, diga uma vez: "Executado sem a skill inbox-for-human, que manteria esta página em uma lista de revisão."
Primeiro uso
Antes da primeira página em uma configuração, execute python3 "$SKILL_DIR/scripts/self_check.py" e repasse sua mensagem em palavras simples. Não execute novamente depois que passar; o script lembra uma verificação aprovada. --force executa novamente quando necessário.
Se você não puder executar comandos aqui, não tente. Diga exatamente: "human-feedback não pode funcionar neste modo porque não consigo trabalhar com arquivos no seu computador aqui. No aplicativo de desktop do Claude, abra a aba Código e escolha uma sessão Local. No aplicativo de desktop do ChatGPT, mude para Codex e mantenha-o em Local."
Saída 2, ou essa mensagem, significa parar: não tente construir uma página. Saída 1 fornece um arquivo que o usuário pode abrir para verificar.
1. Marque as partes
Coloque data-note em cada parte que o usuário pode comentar como uma unidade: um card, uma seção, uma opção, uma linha de tabela. Os rótulos vêm do primeiro título da parte, então um data-note simples geralmente é suficiente. Uma parte sem título, ou cujo título repete o de outra parte, recebe seu próprio rótulo: data-note="Opção B · Calmo". Os rótulos devem ser únicos na página.
Uma página que desenha suas partes a partir de seu próprio script também recebe anotações nelas, desde que o script as desenhe imediatamente, não em um evento posterior como DOMContentLoaded ou um clique. Não as copie para o HTML; a contagem da etapa 2 cobre apenas as partes escritas lá.
Marque a parte ao redor de uma página local mostrada em um <iframe>. A etapa 2 marca a página emoldurada para que suas palavras ofereçam Comentar, Editar e Destacar. A página de revisão salva o feedback e nomeia a fonte emoldurada na edição copiada.
Nunca marque texto para o usuário preencher ou reescrever, e nunca peça ao usuário para editar a página: o usuário reescreve qualquer linha quando quiser, com Editar no pop-up que um clique ou seleção abre (⌘Z desfaz uma edição). Faça perguntas em vez disso (etapa 6).
Não construa caixas de comentário, campos de entrada ou botões de copiar próprios. A camada faz tudo isso.
O outline à esquerda já é a navegação da página: lista cada parte, mostra títulos de seção fora das partes como legendas, marca a parte em vista e salta para uma parte livre da barra superior da página. Antes de fornecer à página sua própria navegação (abas de seção, lista de conteúdo, links de salto, contador de etapas com anterior e próximo), julgue o que é mais fácil para o usuário, para que ele nunca encontre duas maneiras de fazer uma coisa:
- Apenas repetiria o outline → deixe de fora. Nomeie as partes e títulos de seção como seus botões diriam.
- Faz algo que o outline não pode (um interruptor Claro/Escuro, um filtro, botões anterior e próximo que rolam a página parte por parte) → mantenha apenas essa parte.
- Mostra partes em abas ou outros painéis ocultos → torne-a uma página de rolagem única. O usuário pediu abas → marque-as e não escreva mais nada: um
role="tablist"de<button role="tab" aria-controls="…">, cada um nomeando umrole="tabpanel", então partesdata-notedentro dos painéis como de costume. A camada alterna os painéis, desenha uma barra fixa simples, lista cada aba no outline como um nível de sua hierarquia, onde ela está na página, mantém a aba aberta entre recarregamentos e versões, abre uma aba para uma linha do outline, um stepper ou um link#para ela, e segura um tópico até que sua aba abra. Uma página com seu próprio script de abas o mantém, e uma tablist com umaclassmantém o estilo próprio da página. - Cada página recebe versões a partir de sua segunda rodada (etapa 5) → não vincule as teclas ← e →; o stepper de versão as usa.
Pontos de plug-in, para qualquer página que hospede a camada (uma página feita por outra skill, ou manualmente):
data-notepartes alimentam o Outline e a coluna de anotações, como acima.data-notes-layeré definido em<html>assim que a camada é desenhada, e está ausente em uma página sem ela. Uma página hospedeira usa isso para ocultar seu próprio outline, ou uma linha que só faz sentido sem a camada, para que o usuário nunca veja duas:html[data-notes-layer] .its-outline { display: none; }. Nada desliga a camada, então o marcador permanece. Não confie em nada mais que a camada adiciona.
2. Ative as anotações
python3 "$SKILL_DIR/scripts/add_notes.py" <page.html> --agent "Claude"
Ele adiciona uma tag pouco antes de </body>, imprime a contagem de rodadas e partes, e abre a página através de show.py. Reexecuções, --next-round e a execução de acompanhamento de uma nova versão também a abrem; --new-version sozinho, --received e --converged não. Se a abertura falhar, a página permanece pronta e a execução imprime o motivo e o comando para abri-la manualmente. Na primeira rodada, também coloca um pequeno estilo no cabeçalho da página, que mantém a página oculta até que a camada a desenhe. Reexecutar substitui a tag, então execute novamente após reescrever a página. Um aviso sobre nenhuma parte ou rótulo duplicado → corrija as marcas e reexecute.
-
--hold: prepare a página sem abri-la, enquanto você a constrói ou verifica, ou quando o usuário pedir apenas um link (etapa 3). -
--pictures off: desabilite anexos de imagem para uma página compartilhada com outras pessoas ou uma construção pública; execuções posteriores mantêm a configuração. -
--agent: seu nome como as pessoas o conhecem. Claude Code passaClaude, Codex passaCodex, qualquer outro agente seu próprio nome de produto. Um cursor com esse nome e seu logotipo faz sua parte na página deles: digita suas mensagens e clica nos estados da barra de anotações deles (Recebido e Atualizando na etapa 4, Concluído na etapa 8). Execuções posteriores mantêm o nome, então passe-o na primeira vez. -
--helper "<nome>"e--owns "<nome>:[Rótulo da parte]": outro agente fez partes da página (um subagente que você enviou, Codex, qualquer um que não seja você). Nomeie cada helper uma vez, como as pessoas o conhecem, e cada parte que ele fez com--owns, o rótulo como mostrado no Outline; ambos se repetem, no máximo três helpers. Você continua sendo o líder (--agent). Na página, o cursor de cada agente faz apenas o que ele possui. Execuções posteriores os mantêm; uma execução com qualquer flag os substitui; uma nova versão começa sem nenhum, então passe-os novamente em sua execução de acompanhamento quando suas partes ainda são deles. Você fez tudo → deixe ambos de fora.python3 "$SKILL_DIR/scripts/add_notes.py" <page.html> --agent "Claude" --helper "Codex" --owns "Codex:[Opção B · Calmo]" -
--workspace <dir>: seu workspace (a pasta do projeto onde você trabalha). Cada execução cria<dir>/human-feedback/attachments/se estiver faltando, com um arquivo marcador emhuman-feedback/; a página salva as imagens que o usuário anexa lá, depois que o usuário seleciona essa pastahuman-feedbackuma vez no Chrome, e os prompts da página o nomeiam ("Na pasta do workspace de Claude, selecione a subpasta human-feedback…"). Sem ele: o repositório da página, senão o repositório do seu diretório atual, senão o diretório atual. Execuções posteriores mantêm a pasta que a tag nomeia. -
A página é servida via http (usa
fetch, módulos ou assets../) → adicione--copy, que colocahuman-feedback.jsao lado da página. Execuções posteriores, reescritas e novas versões o mantêm, e informam. -
Nunca cole ou embuta
human-feedback.jsna página, e nunca o leia: a tag é tudo que a página precisa. -
Coloque perguntas sobre a página na parte a que se referem (etapa 6).
Aparência
- Siga a aparência do sistema por padrão. Ofereça Auto, Claro e Escuro quando o material em revisão for prosa nos estilos de leitura compartilhados, ou quando o usuário pedir o controle. Deixe desligado em outras revisões.
- Ao oferecer o controle, use
--appearance pagese a coluna de leitura já tiver ambas as paletas e você puder verificar ambas. Reutilize-as na mesma página. Para uma página com tema independente, sem uma paleta testada, ou cuja aparência faz parte da revisão, use--appearance sidebarspara alternar apenas o Outline e as Anotações. Mantenha capturas de tela e embeds como estão. - No CSS da coluna de leitura,
html[data-notes-layer="light"]ehtml[data-notes-layer="dark"]são as escolhas explícitas. Mantenha a consulta de mídia do sistema para Auto e quando a página abrir sem a camada. A escolha do usuário permanece nesta revisão entre rodadas. Outras revisões começam em Auto. - Uma reexecução ou uma versão copiada por
--new-versionmantém a configuração. Passe--appearance offpara remover o controle, ou passe a configuração desejada novamente ao reconstruir o arquivo do zero.
3. Mostre-a
Para qualquer tipo de revisão, em cada rodada:
- Assim que a revisão estiver pronta, abra-a no navegador do usuário em cada rodada. O abridor reutiliza a aba existente no Chrome quando encontra uma rodada anterior lá. Use
--holdenquanto constrói ou verifica a página, ou quando o usuário pedir explicitamente apenas um link. - Para uma revisão local, termine com
add_notes.pysem--hold. Novas revisões em uma pasta dedicada cujos assets vivem nessa pasta usam um endereço web local para todas as rodadas, para que o navegador mantenha o zoom da página e as anotações. Mantenha as rodadas e seus assets nessa pasta ou suas subpastas e use caminhos de assets relativos. Forneça o link do endereço de revisão que o abridor imprime. - Para uma página já servida via HTTP, prepare com
--hold --copye executeshow.py <local page.html> --preview-url <nova URL HTTP da rodada>. Mantenha o mesmo servidor de pré-visualização entre rodadas para que o abridor possa encontrar a aba existente e o navegador mantenha as anotações do usuário. - Coloque o link da página em sua resposta a cada rodada. Use o formato de link do seu projeto, com o resultado do abridor para dizer onde a página está. Se o abridor falhar ou disser que deixou a página fechada, informe e forneça o link.
- Uma página cujas rodadas ou versões anteriores o usuário abriu de
file://→ continue mostrando-a defile://(show.pyem seu caminho) e não forneça um link localhost, mesmo onde o projeto pede um: o navegador mantém as respostas do usuário por endereço, então uma cópia localhost não mostra nenhuma delas e reabre tópicos que eles fecharam. Diga na resposta por que não há link.
Faça isso apenas quando a página estiver pronta para suas anotações.
Execute add_notes.py sem --hold assim que a página estiver pronta para suas anotações. Termine o conteúdo da página e marque cada parte primeiro. Passe quaisquer marcas concluídas e quaisquer bolhas que o usuário solicitou nessa execução (execução de acompanhamento da etapa 5 para uma nova versão).
Uma correção que você disse ao usuário que está a caminho também segura a próxima versão. Mostre-a assim que a correção estiver ativa.
Para uma verificação, prepare com --hold, então verifique você mesmo (ou peça a um subagente para capturar a tela) com a camada de anotações ativada, já que a camada estreita a página, e corrija o que encontrar. Suas mensagens (perguntas, respostas) só entram quando a aba tem foco, e um navegador headless nunca a foca a menos que a emulação de foco esteja ativada (tests/harness.mjs ativa). Sem ela, verifique as mensagens nos dados da tag, e a página em si permanece em branco atrás de sua abertura: capture-a com shoot_page.py do reading-page-formats, que captura a tela e depois exclui uma cópia simples sem a tag e seu estilo de retenção. Essa cópia simples preenche a janela inteira, mas na tela deles as colunas de anotações ocupam cerca de 375px de cada lado (medido a 2560 de largura, 2026-11-01). Então também capture-a nessa largura mais estreita e corrija qualquer quebra ou estouro antes de mostrá-la. Uma cópia simples não pode mostrar as colunas cobrindo a página, então também carregue a página retida com a camada ativada e verifique se document.querySelector('h1').getBoundingClientRect().left está à direita da borda do outline; o primeiro elemento de texto servirá em uma página sem h1. Só então abra a página usando o comando local ou HTTP acima. Diga ao usuário que está pronto para suas anotações, onde está (a linha que o abridor imprime), e para colar o que Copiar fornecer. Se você fez perguntas ou deixou respostas, diga quantas estão esperando na página.
Assim que uma página é mostrada, mantenha o chat na linha de pronto, no link e em qualquer coisa que impediu a página de abrir ou na linha exigida por outra skill. Coloque alterações, descobertas, fontes, ressalvas, verificações e perguntas nas partes a que se referem. Use o Mais informações da página para fontes e detalhes quando ela tiver um.
Uma página que você emoldurou também carrega a tag de moldura, então, aberta por conta própria, mostra as colunas de anotações e fica comprimida, e uma verificação relata falsos defeitos. Verifique-a a partir de uma cópia simples em seu scratchpad: remova o estilo de retenção (delete a tag <style id="hf"> do <head>) e ative a camada com document.querySelector('script[src*=human-feedback]')?.remove(); fetch('…/human-feedback.js').then(r => r.text()).then(eval). Faça a captura de tela nessa página com shoot_page.py's --javascript <caminho para um arquivo com esse código>; passe a tag pela URL com --copy, porque o arquivo local não a serviria via HTTP.
4. Receba as anotações
O que entra depois de "Recebido":
- O usuário cola o texto copiado no chat. Você o aplica.
- As anotações são uma lista numerada. Cada item corresponde a uma parte marcada com
data-note; a numeração segue a ordem das partes na página. Cada item contém o rótulo da parte (seudata-note), o texto da anotação, e opcionalmente uma reação com emoji, uma resposta ou uma edição. - Aplique as anotações: para cada anotação, interprete o texto como instrução (ex.: "Altere X para Y", "Adicione uma explicação sobre Z"). Se a anotação contiver uma reação com emoji, registre-a como aprovação/rejeição. Se contiver uma edição, aplique-a à parte relevante.
- Após aplicar, prepare uma nova versão da página (se necessário) e vá para a etapa 5.
5. Prepare a próxima rodada
- Incorpore as respostas e alterações das anotações na página.
- Se houver novas perguntas ou pontos a serem resolvidos, adicione-os como novas anotações (com
?para perguntas) ou como bolhas (--ask,--again). - Use
--next-roundpara marcar que é uma continuação da revisão. - Execute
add_notes.pycom as flags apropriadas para gerar a nova versão. - Volte à etapa 3 para mostrar a versão atualizada.
- Continue até que todas as anotações estejam resolvidas e o usuário indique satisfação.
6. Faça perguntas
- Use
--askpara adicionar uma bolha de pergunta ao lado de uma parte. A bolha aparece na coluna de anotações e o usuário pode respondê-la. - Use
--againpara reabrir uma discussão anterior. - Use
--replypara responder diretamente a uma anotação existente. - As perguntas devem ser específicas e direcionadas à parte relevante.
7. Finalize a revisão
- Quando o usuário confirmar que a revisão está completa, use
--convergedpara marcar a página como finalizada. - A página não será mais atualizada em novas rodadas.
- Se a skill
inbox-for-humanestiver disponível, mova a página para a lista de concluídas.
8. Histórico de versões
--new-versioncria uma nova versão independente da página, mantendo as versões anteriores.- As versões são numeradas automaticamente pela camada.
- O usuário pode navegar entre versões usando o stepper (teclas ← e →, ou controles na página).
- Cada versão preserva as anotações da versão anterior, a menos que explicitamente removidas.
Referências
references/what-the-user-sees.md: descreve o comportamento da página e o que o usuário vê em cada etapa.scripts/self_check.py: verifica o ambiente antes do primeiro uso.scripts/add_notes.py: adiciona a camada de anotações à página.scripts/show.py: abre a página no Chrome.tests/harness.mjs: utilitário de teste para emular foco e verificar a página.human-feedback.js: script da camada de anotações (não deve ser lido ou modificado).