Tools
Diferenças
diffs é uma ferramenta opcional de Plugin incluído que transforma um texto anterior/posterior ou um patch unificado em um artefato de diff somente leitura. Ela também adiciona breves orientações para o agente ao início do prompt do sistema e inclui uma skill complementar com instruções mais completas.
Entrada: texto before + after ou um patch unificado (mutuamente exclusivos).
Saída: uma URL do visualizador do Gateway para apresentação no canvas, um caminho de arquivo PNG/PDF renderizado para envio por mensagem ou ambos.
Início rápido
Instale o Plugin
openclaw plugins install diffsAtive o Plugin
{ plugins: { entries: { diffs: { enabled: true, }, }, },}Escolha um modo
view
Fluxos com prioridade para o canvas: os agentes chamam diffs com mode: "view" e abrem details.viewerUrl com canvas present.
file
Envio de arquivo pelo chat: os agentes chamam diffs com mode: "file" e enviam details.filePath com message usando path ou filePath.
both
Combinado (padrão): os agentes chamam diffs com mode: "both" para obter ambos os artefatos em uma única chamada.
Desativar a orientação integrada do sistema
Para manter a ferramenta, mas remover a orientação adicionada ao início do prompt do sistema, defina plugins.entries.diffs.hooks.allowPromptInjection como false:
{ plugins: { entries: { diffs: { enabled: true, hooks: { allowPromptInjection: false, }, }, }, },}Isso bloqueia o hook before_prompt_build do Plugin, mantendo a ferramenta e a skill disponíveis. Para desativar tanto a orientação quanto a ferramenta, desative o Plugin.
Referência de entrada da ferramenta
Todos os campos são opcionais, salvo indicação em contrário.
beforestringTexto original. Obrigatório com after quando patch for omitido.
afterstringTexto atualizado. Obrigatório com before quando patch for omitido.
patchstringTexto de diff unificado. Mutuamente exclusivo com before e after.
pathstringNome de arquivo exibido no modo anterior/posterior.
langstringDica para substituir o idioma no modo anterior/posterior. Valores desconhecidos e idiomas fora do conjunto padrão do visualizador usam texto simples como alternativa, a menos que o Plugin Diff Viewer Language Pack esteja instalado.
titlestringSubstituição do título do visualizador.
mode"view" | "file" | "both"Modo de saída. O padrão é o valor padrão do Plugin defaults.mode (both). Alias obsoleto: "image" se comporta de forma idêntica a "file".
theme"light" | "dark"Tema do visualizador. O padrão é o valor padrão do Plugin defaults.theme.
layout"unified" | "split"Layout do diff. O padrão é o valor padrão do Plugin defaults.layout.
expandUnchangedbooleanExpande as seções inalteradas quando o contexto completo está disponível. Opção apenas por chamada (não é uma chave padrão do Plugin).
fileFormat"png" | "pdf"Formato do arquivo renderizado. O padrão é o valor padrão do Plugin defaults.fileFormat.
fileQuality"standard" | "hq" | "print"Predefinição de qualidade para renderização em PNG/PDF.
fileScalenumberSubstituição da escala do dispositivo (1-4).
fileMaxWidthnumberLargura máxima da renderização em pixels CSS (640-2400).
ttlSecondsnumberdefault: 1800TTL do artefato em segundos para as saídas do visualizador e de arquivos independentes. Máximo de 21600.
baseUrlstringSubstituição da origem da URL do visualizador. Substitui viewerBaseUrl do Plugin. Deve ser http ou https, sem consulta/hash.
Validação e limites
before/after: máximo de 512 KiB cada.patch: máximo de 2 MiB.path: máximo de 2048 bytes.lang: máximo de 128 bytes.title: máximo de 1024 bytes.- Limite de complexidade do patch: máximo de 128 arquivos e 120000 linhas no total.
patchjunto combefore/afteré rejeitado.- Limites de segurança do arquivo renderizado (PNG e PDF):
fileQuality: "standard": máximo de 8 MP (8,000,000 pixels renderizados).fileQuality: "hq": máximo de 14 MP.fileQuality: "print": máximo de 24 MP.- PDF também é limitado a 50 páginas.
Realce de sintaxe
Linguagens integradas:
javascript, typescript, tsx, jsx, json, markdown, yaml, css, html, sh, python, go, rust, java, c, cpp, csharp, php, sql, docker, ruby, swift, kotlin, r, dart, lua, powershell, xml e toml.
Aliases comuns (js, ts, bash, md, yml, c++, dockerfile, rb, kt, ps1 etc.) são normalizados para essas linguagens.
Instale o Plugin Diff Viewer Language Pack para obter mais linguagens (Astro, Vue, Svelte, MDX, GraphQL, Terraform/HCL, Nix, Clojure, Elixir, Haskell, OCaml, Scala, Zig, Solidity, Verilog/VHDL, Fortran, MATLAB, LaTeX, Mermaid, Sass/Less/SCSS, Nginx, Apache, CSV, dotenv, INI, diff e outras):
openclaw plugins install clawhub:@openclaw/diffs-language-packSem o pacote, linguagens não compatíveis ainda são renderizadas como texto simples legível. Consulte o Plugin Diffs Language Pack e as linguagens do Shiki para ver o catálogo upstream.
Contrato dos detalhes da saída
Todos os resultados bem-sucedidos incluem changed: uma entrada anterior/posterior idêntica retorna false sem criar um artefato; resultados renderizados retornam true.
Campos do visualizador (modos view e both)
changedartifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(agentId,sessionId,messageChannel,agentAccountIdquando disponíveis)
Campos do arquivo (modos file e both)
changedartifactIdexpiresAtfilePathpath(mesmo valor quefilePath, para compatibilidade com a ferramenta de mensagens)fileBytesfileFormatfileQualityfileScalefileMaxWidth
| Modo | Retorna |
|---|---|
"view" |
Somente os campos do visualizador. |
"file" |
Somente os campos do arquivo, sem artefato do visualizador. |
"both" |
Campos do visualizador e do arquivo. Se a renderização do arquivo falhar, o visualizador ainda será retornado com fileError. |
Seções inalteradas recolhidas
O visualizador mostra linhas como N unmodified lines. Os controles de expansão só aparecem quando o diff renderizado tem dados de contexto expansíveis (típico para entradas de antes/depois). Muitos patches unificados omitem os blocos de contexto em seus trechos, portanto a linha pode aparecer sem um controle de expansão — isso é esperado, não é um bug. expandUnchanged só se aplica quando existe contexto expansível.
Navegação entre vários arquivos
Os patches que alteram mais de um arquivo começam com um cartão de resumo dos arquivos alterados: contagens totais de +N / -N, contagens por arquivo, indicadores de adicionado/excluído/renomeado e links de âncora que levam a cada arquivo. Os arquivos PNG/PDF renderizados mantêm as contagens no cabeçalho de cada arquivo, mas omitem os controles interativos de alternância de visualização, pois eles não funcionam em um arquivo estático.
Padrões do Plugin
Defina os padrões gerais do Plugin em ~/.openclaw/openclaw.json:
{ plugins: { entries: { diffs: { enabled: true, config: { defaults: { fontFamily: "Fira Code", fontSize: 15, lineSpacing: 1.6, layout: "unified", showLineNumbers: true, diffIndicators: "bars", wordWrap: true, background: true, theme: "dark", fileFormat: "png", fileQuality: "standard", fileScale: 2, fileMaxWidth: 960, mode: "both", ttlSeconds: 21600, }, }, }, }, },}Chaves de defaults compatíveis: fontFamily, fontSize, lineSpacing, layout, showLineNumbers, diffIndicators, wordWrap, background, theme, fileFormat, fileQuality, fileScale, fileMaxWidth, mode, ttlSeconds. Parâmetros explícitos de chamada de ferramenta substituem esses valores.
Configuração persistente da URL do visualizador
viewerBaseUrlstringFallback pertencente ao Plugin para links do visualizador retornados quando uma chamada de ferramenta não fornece baseUrl. Deve usar http ou https, sem consulta/hash.
{ plugins: { entries: { diffs: { enabled: true, config: { viewerBaseUrl: "https://gateway.example.com/openclaw", }, }, }, },}Configuração de segurança
security.allowRemoteViewerbooleandefault: falsefalse: solicitações que não sejam de loopback para as rotas do visualizador são negadas. true: visualizadores remotos são permitidos se o caminho com token for válido.
{ plugins: { entries: { diffs: { enabled: true, config: { security: { allowRemoteViewer: false, }, }, }, }, },}Ciclo de vida e armazenamento de artefatos
- Os artefatos ficam em
$TMPDIR/openclaw-diffs. - Os metadados do visualizador armazenam um ID de artefato aleatório de 20 caracteres hexadecimais, um token aleatório de 48 caracteres hexadecimais,
createdAt/expiresAte o caminho armazenado deviewer.html. - TTL padrão do artefato: 30 minutos. TTL máximo aceito: 6 horas.
- A limpeza é executada de forma oportunista após cada chamada de criação de artefato; os artefatos expirados são excluídos.
- A varredura de contingência remove pastas obsoletas com mais de 24 horas quando os metadados estão ausentes.
URL do visualizador e comportamento da rede
Rota do visualizador: /plugins/diffs/view/{artifactId}/{token}
Recursos do visualizador:
/plugins/diffs/assets/viewer.js/plugins/diffs/assets/viewer-runtime.js/plugins/diffs-language-pack/assets/viewer.js(somente quando o diff usa um idioma do pacote de idiomas)
O documento do visualizador resolve esses recursos em relação à URL do visualizador, portanto, um prefixo de caminho opcional em baseUrl também é aplicado às solicitações de recursos.
Ordem de resolução da URL: baseUrl da chamada da ferramenta (após validação rigorosa) -> viewerBaseUrl do plugin -> padrão de loopback 127.0.0.1. Se o modo de vinculação do Gateway for custom e gateway.customBindHost estiver definido, esse host será usado em vez do loopback.
Regras de baseUrl: deve ser http:// ou https://; query e hash são rejeitados; é permitida uma origem com um caminho-base opcional.
Modelo de segurança
Proteção do visualizador
- Somente loopback por padrão.
- Caminhos tokenizados do visualizador com validação rigorosa dos padrões de ID e token.
- CSP da resposta do visualizador:
default-src 'none'; scripts/recursos somente da própria origem; nenhumconnect-srcde saída. - Limitação de tentativas malsucedidas remotas quando o acesso remoto está habilitado: 40 falhas em 60 segundos acionam um bloqueio de 60 segundos (
429 Too Many Requests).
Proteção da renderização de arquivos
- O roteamento de solicitações do navegador para capturas de tela é bloqueado por padrão.
- Somente recursos locais do visualizador em
http://127.0.0.1/plugins/diffs/assets/*são permitidos. - Solicitações de rede externas são bloqueadas.
Requisitos de navegador para o modo de arquivo
mode: "file" e mode: "both" precisam de um navegador compatível com Chromium.
Ordem de resolução:
Configuração
browser.executablePath na configuração do OpenClaw.
Variáveis de ambiente
OPENCLAW_BROWSER_EXECUTABLE_PATHBROWSER_EXECUTABLE_PATHPLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
Fallback da plataforma
Caminhos de instalação comuns e buscas no PATH para Chrome, Chromium, Edge e Brave.
Texto comum de falha: Diff PNG/PDF rendering requires a Chromium-compatible browser.... Corrija instalando o Chrome, Chromium, Edge ou Brave, ou definindo uma das opções de caminho do executável acima.
Solução de problemas
Erros de validação de entrada
Provide patch or both before and after text.-- incluabeforeeafter, ou forneçapatch.Provide either patch or before/after input, not both.-- não misture os modos de entrada.Invalid baseUrl: ...-- use uma origemhttp(s)com caminho opcional, sem consulta/hash.{field} exceeds maximum size (...)-- reduza o tamanho da carga útil.- Rejeição de patch grande -- reduza a quantidade de arquivos do patch ou o total de linhas.
Acessibilidade do visualizador
- A URL do visualizador é resolvida como
127.0.0.1por padrão. - Para acesso remoto, defina
viewerBaseUrlno plugin, passebaseUrlpor chamada ou usegateway.bind=customcomgateway.customBindHost. - Se
gateway.trustedProxiesincluir o endereço de loopback para um proxy no mesmo host (por exemplo, Tailscale Serve), as solicitações brutas do visualizador via loopback sem cabeçalhos encaminhados de IP do cliente falharão de forma segura por design. - Para essa topologia de proxy, prefira
mode: "file"/"both"para um anexo ou habilite intencionalmentesecurity.allowRemoteViewerjunto comviewerBaseUrlno plugin/umbaseUrlde proxy para obter um link compartilhável do visualizador. - Habilite
security.allowRemoteViewersomente quando o acesso externo ao visualizador for desejado.
A linha de linhas não modificadas não tem botão de expansão
Comportamento esperado para uma entrada de patch sem contexto expansível; não é uma falha do visualizador.
Artefato não encontrado
- O artefato expirou devido ao TTL.
- O token ou o caminho foi alterado.
- A limpeza removeu dados obsoletos.
Orientações operacionais
- Prefira
mode: "view"para revisões interativas locais no canvas. - Prefira
mode: "file"para canais de chat externos que precisam de um anexo. - Mantenha
allowRemoteViewerdesativado, a menos que sua implantação exija URLs de visualização remota. - Defina um
ttlSecondscurto e explícito para diffs confidenciais. - Evite enviar segredos na entrada do diff quando não for necessário.
- Se o seu canal compactar imagens de forma agressiva (por exemplo, Telegram ou WhatsApp), prefira a saída em PDF (
fileFormat: "pdf").