Ir al contenido

Diffs

diffs es una herramienta de complemento opcional con una guía del sistema integrada corta y una habilidad complementaria que convierte el contenido de cambios en un artefacto de diff de solo lectura para agentes.

Acepta cualquiera:

  • texto before y after
  • un patch unificado

Puede devolver:

  • una URL de visor de puerta de enlace para la presentación en el lienzo
  • una ruta de archivo renderizada (PNG o PDF) para la entrega de mensajes
  • ambas salidas en una sola llamada

Cuando está habilitado, el complemento antepone una guía de uso concisa en el espacio del prompt del sistema y también expone una habilidad detallada para los casos en los que el agente necesita instrucciones más completas.

  1. Instalar el complemento

    Ventana de terminal
    openclaw plugins install diffs
  2. Habilitar el complemento

    {
    plugins: {
    entries: {
    diffs: {
    enabled: true,
    },
    },
    },
    }
  3. Elegir un modo

    Flujos con prioridad de Canvas: los agentes llaman a diffs con mode: "view" y abren details.viewerUrl con canvas present.

Si desea mantener la herramienta diffs habilitada pero deshabilitar su guía del sistema integrada, establezca plugins.entries.diffs.hooks.allowPromptInjection en false:

{
plugins: {
entries: {
diffs: {
enabled: true,
hooks: {
allowPromptInjection: false,
},
},
},
},
}

Esto bloquea el hook before_prompt_build del complemento diffs mientras mantiene el complemento, la herramienta y la habilidad complementaria disponibles.

Si desea deshabilitar tanto la guía como la herramienta, deshabilite el complemento en su lugar.

  1. Llamar a diffs

    El agente llama a la herramienta diffs con entrada.

  2. Leer detalles

    El agente lee los campos details de la respuesta.

  3. Presentar

    El agente abre details.viewerUrl con canvas present, envía details.filePath con message usando path o filePath, o hace ambas cosas.

{
"before": "# Hello\n\nOne",
"after": "# Hello\n\nTwo",
"path": "docs/example.md",
"mode": "view"
}

Todos los campos son opcionales a menos que se indique lo contrario.

Texto original. Requerido con `after` cuando se omite `patch`. Texto actualizado. Requerido con `before` cuando se omite `patch`. Texto de diff unificado. Mutuamente excluyente con `before` y `after`. Nombre de archivo a mostrar para el modo antes y después. Sugerencia de anulación de idioma para el modo antes y después. Los valores desconocidos y los idiomas fuera del conjunto de visores predeterminados vuelven al texto plano a menos que esté instalado el complemento Diff Viewer Language Pack. Título del visor personalizado. Modo de salida. El valor predeterminado es el del complemento `defaults.mode`. Alias obsoleto: `"image"` se comporta como `"file"` y aún se acepta por compatibilidad con versiones anteriores. Tema del visor. El valor predeterminado es el del complemento `defaults.theme`. Disposición del diff. El valor predeterminado es el del complemento `defaults.layout`. Expandir secciones sin cambios cuando el contexto completo esté disponible. Opción solo por llamada (no una clave predeterminada del complemento). Formato de archivo renderizado. El valor predeterminado es el del complemento `defaults.fileFormat`. Ajuste de calidad para el renderizado de PNG o PDF. Personalización de la escala del dispositivo (`1`-`4`). Ancho máximo de renderizado en píxeles CSS (`640`-`2400`). TTL del artefacto en segundos para las salidas del visor y de archivos independientes. Máximo 21600. Personalización del origen de la URL del visor. Anula la configuración del complemento `viewerBaseUrl`. Debe ser `http` o `https`, sin consulta/hash.
Alias de entrada heredados

Todavía se aceptan por compatibilidad con versiones anteriores:

  • format -> fileFormat
  • imageFormat -> fileFormat
  • imageQuality -> fileQuality
  • imageScale -> fileScale
  • imageMaxWidth -> fileMaxWidth
Validación y límites
  • before y after máximo 512 KiB cada uno.
  • patch máximo 2 MiB.
  • path máximo 2048 bytes.
  • lang máximo 128 bytes.
  • title máximo 1024 bytes.
  • Límite de complejidad del parche: máximo 128 archivos y 120000 líneas en total.
  • patch junto con before o after se rechazan.
  • Límites de seguridad de archivos renderizados (aplican a PNG y PDF):
    • fileQuality: "standard": máximo 8 MP (8,000,000 píxeles renderizados).
    • fileQuality: "hq": máximo 14 MP (14,000,000 píxeles renderizados).
    • fileQuality: "print": máximo 24 MP (24,000,000 píxeles renderizados).
    • PDF también tiene un máximo de 50 páginas.

OpenClaw incluye resaltado de sintaxis para lenguajes comunes de código fuente, configuración y documentación:

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, y toml.

Los alias comunes como js, ts, bash, md, yml, c++, dockerfile, rb, kt y ps1 se normalizan a esos idiomas predeterminados.

Instale el complemento Diff Viewer Language Pack para resaltar otros idiomas:

Ventana de terminal
openclaw plugins install clawhub:@openclaw/diffs-language-pack

Con el paquete de idiomas disponible, OpenClaw puede resaltar muchos más idiomas. Si el paquete no está instalado, los archivos fuera de la lista predeterminada aún se procesan como texto sin formato legible. Los ejemplos incluyen 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 y archivos diff.

Consulte el complemento Diffs Language Pack para obtener más detalles y Shiki languages para ver el catálogo de idiomas y alias upstream de Shiki.

La herramienta devuelve metadatos estructurados bajo details.

Campos del visor

Campos compartidos para los modos que crean un visor:

  • artifactId
  • viewerUrl
  • viewerPath
  • title
  • expiresAt
  • inputKind
  • fileCount
  • mode
  • context (agentId, sessionId, messageChannel, agentAccountId cuando estén disponibles)
Campos de archivo

Campos de archivo cuando se procesa PNG o PDF:

  • artifactId
  • expiresAt
  • filePath
  • path (mismo valor que filePath, para compatibilidad con la herramienta de mensajes)
  • fileBytes
  • fileFormat
  • fileQuality
  • fileScale
  • fileMaxWidth
Alias de compatibilidad

También se devuelve para los llamadores existentes:

  • format (mismo valor que fileFormat)
  • imagePath (mismo valor que filePath)
  • imageBytes (mismo valor que fileBytes)
  • imageQuality (mismo valor que fileQuality)
  • imageScale (mismo valor que fileScale)
  • imageMaxWidth (mismo valor que fileMaxWidth)

Resumen del comportamiento del modo:

ModoLo que se devuelve
"view"Solo campos del visor.
"file"Solo campos de archivo, sin artefacto de visor.
"both"Campos del visor más campos de archivo. Si la representación del archivo falla, el visor aún se devuelve con el alias fileError y imageError.
  • El visor puede mostrar filas como N unmodified lines.
  • Los controles de expansión en esas filas son condicionales y no están garantizados para cada tipo de entrada.
  • Los controles de expansión aparecen cuando el diff representado tiene datos de contexto expandibles, lo cual es típico para la entrada antes y después.
  • Para muchas entradas de parches unificados, los cuerpos de contexto omitidos no están disponibles en los fragmentos de parche analizados, por lo que la fila puede aparecer sin controles de expansión. Este es un comportamiento esperado.
  • expandUnchanged se aplica solo cuando existe contexto expandible.

Establezca los valores predeterminados de todo el complemento en ~/.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,
},
},
},
},
},
}

Valores predeterminados admitidos:

  • fontFamily
  • fontSize
  • lineSpacing
  • layout
  • showLineNumbers
  • diffIndicators
  • wordWrap
  • background
  • theme
  • fileFormat
  • fileQuality
  • fileScale
  • fileMaxWidth
  • mode
  • ttlSeconds

Los parámetros explícitos de la herramienta anulan estos valores predeterminados.

Respaldo propio del complemento para los enlaces del visor devueltos cuando una llamada a la herramienta no pasa `baseUrl`. Debe ser `http` o `https`, sin consulta/hash.
{
plugins: {
entries: {
diffs: {
enabled: true,
config: {
viewerBaseUrl: "https://gateway.example.com/openclaw",
},
},
},
},
}
`false`: se deniegan las solicitudes que no son de bucle local a las rutas del visor. `true`: se permiten visores remotos si la ruta tokenizada es válida.
{
plugins: {
entries: {
diffs: {
enabled: true,
config: {
security: {
allowRemoteViewer: false,
},
},
},
},
},
}

Ciclo de vida y almacenamiento de artefactos

Sección titulada «Ciclo de vida y almacenamiento de artefactos»
  • Los artefactos se almacenan en la subcarpeta temp: $TMPDIR/openclaw-diffs.
  • Los metadatos del artefacto del visor contienen:
    • ID de artefacto aleatorio (20 caracteres hexadecimales)
    • token aleatorio (48 caracteres hexadecimales)
    • createdAt y expiresAt
    • ruta viewer.html almacenada
  • El TTL predeterminado del artefacto es de 30 minutos cuando no se especifica.
  • El TTL máximo aceptado para el visor es de 6 horas.
  • La limpieza se ejecuta de manera oportunista después de la creación del artefacto.
  • Los artefactos caducados se eliminan.
  • La limpieza de respaldo elimina las carpetas obsoletas de más de 24 horas cuando faltan los metadatos.

Ruta del visor:

  • /plugins/diffs/view/{artifactId}/{token}

Recursos del visor:

  • /plugins/diffs/assets/viewer.js
  • /plugins/diffs/assets/viewer-runtime.js
  • /plugins/diffs-language-pack/assets/viewer.js cuando el diff utiliza un idioma del Paquete de idiomas del Visor de diffs

El documento del visor resuelve esos recursos en relación con la URL del visor, por lo que un prefijo de ruta baseUrl opcional también se conserva para ambas solicitudes de recursos.

Comportamiento de construcción de URL:

  • Si se proporciona baseUrl en la llamada a la herramienta, se usa después de una validación estricta.
  • De lo contrario, si el viewerBaseUrl del complemento está configurado, se usa.
  • Sin ninguna de las dos anulaciones, la URL del visor predeterminada es el bucle local 127.0.0.1.
  • Si el modo de enlace de la puerta de enlace es custom y gateway.customBindHost está configurado, se usa ese host.

Reglas de baseUrl:

  • Debe ser http:// o https://.
  • La consulta y el hash son rechazados.
  • Se permite el origen más una ruta base opcional.
Endurecimiento del visor
  • Solo bucle local (loopback) de forma predeterminada.
  • Rutas del visor tokenizadas con validación estricta de ID y token.
  • CSP de respuesta del visor:
    • default-src 'none'
    • scripts y activos solo de sí mismo (self)
    • sin connect-src saliente
  • Limitación de fallos remotos cuando el acceso remoto está habilitado:
    • 40 fallos por 60 segundos
    • bloqueo de 60 segundos (429 Too Many Requests)
Endurecimiento del renderizado de archivos
  • El enrutamiento de solicitudes del navegador de captura de pantalla es denegar de forma predeterminada.
  • Solo se permiten los activos del visor local de http://127.0.0.1/plugins/diffs/assets/*.
  • Las solicitudes de red externas están bloqueadas.

Requisitos del navegador para el modo de archivo

Sección titulada «Requisitos del navegador para el modo de archivo»

mode: "file" y mode: "both" necesitan un navegador compatible con Chromium.

Orden de resolución:

  1. Configuración

    browser.executablePath en la configuración de OpenClaw.

  2. Variables de entorno

    • OPENCLAW_BROWSER_EXECUTABLE_PATH
    • BROWSER_EXECUTABLE_PATH
    • PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
  3. Respaldo de plataforma

    Respaldo de descubrimiento de comando/ruta de la plataforma.

Texto de error común:

  • Diff PNG/PDF rendering requires a Chromium-compatible browser...

Solución: instale Chrome, Chromium, Edge o Brave, o configure una de las opciones de ruta ejecutable mencionadas anteriormente.

Errores de validación de entrada
  • Provide patch or both before and after text. — incluya tanto before como after, o proporcione patch.
  • Provide either patch or before/after input, not both. — no mezcle modos de entrada.
  • Invalid baseUrl: ... — use el origen http(s) con una ruta opcional, sin consulta/hash.
  • {field} exceeds maximum size (...) — reduzca el tamaño de la carga útil.
  • Rechazo de parche grande — reduzca la cantidad de archivos de parche o el total de líneas.
Accesibilidad del visor
  • La URL del visor se resuelve a 127.0.0.1 de forma predeterminada.
  • Para escenarios de acceso remoto, puede:
    • establecer el viewerBaseUrl del complemento, o
    • pasar baseUrl por cada llamada a la herramienta, o
    • usar gateway.bind=custom y gateway.customBindHost
  • Si gateway.trustedProxies incluye loopback para un proxy del mismo host (por ejemplo, Tailscale Serve), las solicitudes de visor de loopback sin encabezados de IP de cliente reenviados fallan de forma cerrada por diseño.
  • Para esa topología de proxy:
    • prefiera mode: "file" o mode: "both" cuando solo necesite un archivo adjunto, o
    • habilite intencionalmente security.allowRemoteViewer y establezca el viewerBaseUrl del complemento o pase un baseUrl proxy/público cuando necesite una URL de visor compartible
  • Habilite security.allowRemoteViewer solo cuando tenga la intención de permitir el acceso externo al visor.
La fila de líneas sin modificar no tiene botón de expandir

Esto puede ocurrir para la entrada de parche cuando el parche no lleva contexto expandible. Esto es esperado y no indica un fallo del visor.

Artefacto no encontrado
  • El artefacto expiró debido al TTL.
  • El token o la ruta cambiaron.
  • La limpieza eliminó datos obsoletos.
  • Prefiera mode: "view" para revisiones interactivas locales en el lienzo.
  • Prefiera mode: "file" para canales de chat salientes que necesiten un archivo adjunto.
  • Mantenga allowRemoteViewer deshabilitado a menos que su implementación requiera URLs de visor remoto.
  • Establezca ttlSeconds breves y explícitos para diffs confidenciales.
  • Evite enviar secretos en la entrada de diff cuando no sea necesario.
  • Si su canal comprime las imágenes de forma agresiva (por ejemplo, Telegram o WhatsApp), prefiera la salida PDF (fileFormat: "pdf").