docs/tools/diffs.md
diffs is an optional plugin tool with short built-in system guidance and a companion skill that turns change content into a read-only diff artifact for agents.
It accepts either:
before and after textpatchIt can return:
When enabled, the plugin prepends concise usage guidance into system-prompt space and also exposes a detailed skill for cases where the agent needs fuller instructions.
If you want to keep the diffs tool enabled but disable its built-in system-prompt guidance, set plugins.entries.diffs.hooks.allowPromptInjection to false:
{
plugins: {
entries: {
diffs: {
enabled: true,
hooks: {
allowPromptInjection: false,
},
},
},
},
}
This blocks the diffs plugin's before_prompt_build hook while keeping the plugin, tool, and companion skill available.
If you want to disable both the guidance and the tool, disable the plugin instead.
All fields are optional unless noted.
<ParamField path="before" type="string"> Original text. Required with `after` when `patch` is omitted. </ParamField> <ParamField path="after" type="string"> Updated text. Required with `before` when `patch` is omitted. </ParamField> <ParamField path="patch" type="string"> Unified diff text. Mutually exclusive with `before` and `after`. </ParamField> <ParamField path="path" type="string"> Display filename for before and after mode. </ParamField> <ParamField path="lang" type="string"> Language override hint for before and after mode. Unknown values fall back to plain text. </ParamField> <ParamField path="title" type="string"> Viewer title override. </ParamField> <ParamField path="mode" type='"view" | "file" | "both"'> Output mode. Defaults to plugin default `defaults.mode`. Deprecated alias: `"image"` behaves like `"file"` and is still accepted for backward compatibility. </ParamField> <ParamField path="theme" type='"light" | "dark"'> Viewer theme. Defaults to plugin default `defaults.theme`. </ParamField> <ParamField path="layout" type='"unified" | "split"'> Diff layout. Defaults to plugin default `defaults.layout`. </ParamField> <ParamField path="expandUnchanged" type="boolean"> Expand unchanged sections when full context is available. Per-call option only (not a plugin default key). </ParamField> <ParamField path="fileFormat" type='"png" | "pdf"'> Rendered file format. Defaults to plugin default `defaults.fileFormat`. </ParamField> <ParamField path="fileQuality" type='"standard" | "hq" | "print"'> Quality preset for PNG or PDF rendering. </ParamField> <ParamField path="fileScale" type="number"> Device scale override (`1`-`4`). </ParamField> <ParamField path="fileMaxWidth" type="number"> Max render width in CSS pixels (`640`-`2400`). </ParamField> <ParamField path="ttlSeconds" type="number" default="1800"> Artifact TTL in seconds for viewer and standalone file outputs. Max 21600. </ParamField> <ParamField path="baseUrl" type="string"> Viewer URL origin override. Overrides plugin `viewerBaseUrl`. Must be `http` or `https`, no query/hash. </ParamField> <AccordionGroup> <Accordion title="Legacy input aliases"> Still accepted for backward compatibility:- `format` -> `fileFormat`
- `imageFormat` -> `fileFormat`
- `imageQuality` -> `fileQuality`
- `imageScale` -> `fileScale`
- `imageMaxWidth` -> `fileMaxWidth`
The tool returns structured metadata under details.
- `artifactId`
- `viewerUrl`
- `viewerPath`
- `title`
- `expiresAt`
- `inputKind`
- `fileCount`
- `mode`
- `context` (`agentId`, `sessionId`, `messageChannel`, `agentAccountId` when available)
- `artifactId`
- `expiresAt`
- `filePath`
- `path` (same value as `filePath`, for message tool compatibility)
- `fileBytes`
- `fileFormat`
- `fileQuality`
- `fileScale`
- `fileMaxWidth`
- `format` (same value as `fileFormat`)
- `imagePath` (same value as `filePath`)
- `imageBytes` (same value as `fileBytes`)
- `imageQuality` (same value as `fileQuality`)
- `imageScale` (same value as `fileScale`)
- `imageMaxWidth` (same value as `fileMaxWidth`)
Mode behavior summary:
| Mode | What is returned |
|---|---|
"view" | Viewer fields only. |
"file" | File fields only, no viewer artifact. |
"both" | Viewer fields plus file fields. If file rendering fails, viewer still returns with fileError and imageError alias. |
N unmodified lines.expandUnchanged applies only when expandable context exists.Set plugin-wide defaults in ~/.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",
},
},
},
},
},
}
Supported defaults:
fontFamilyfontSizelineSpacinglayoutshowLineNumbersdiffIndicatorswordWrapbackgroundthemefileFormatfileQualityfileScalefileMaxWidthmodeExplicit tool parameters override these defaults.
{
plugins: {
entries: {
diffs: {
enabled: true,
config: {
viewerBaseUrl: "https://gateway.example.com/openclaw",
},
},
},
},
}
{
plugins: {
entries: {
diffs: {
enabled: true,
config: {
security: {
allowRemoteViewer: false,
},
},
},
},
},
}
$TMPDIR/openclaw-diffs.createdAt and expiresAtviewer.html pathViewer route:
/plugins/diffs/view/{artifactId}/{token}Viewer assets:
/plugins/diffs/assets/viewer.js/plugins/diffs/assets/viewer-runtime.jsThe viewer document resolves those assets relative to the viewer URL, so an optional baseUrl path prefix is preserved for both asset requests too.
URL construction behavior:
baseUrl is provided, it is used after strict validation.viewerBaseUrl is configured, it is used.127.0.0.1.custom and gateway.customBindHost is set, that host is used.baseUrl rules:
http:// or https://.mode: "file" and mode: "both" need a Chromium-compatible browser.
Resolution order:
<Steps> <Step title="Config"> `browser.executablePath` in OpenClaw config. </Step> <Step title="Environment variables"> - `OPENCLAW_BROWSER_EXECUTABLE_PATH` - `BROWSER_EXECUTABLE_PATH` - `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH` </Step> <Step title="Platform fallback"> Platform command/path discovery fallback. </Step> </Steps>Common failure text:
Diff PNG/PDF rendering requires a Chromium-compatible browser...Fix by installing Chrome, Chromium, Edge, or Brave, or setting one of the executable path options above.
mode: "view" for local interactive reviews in canvas.mode: "file" for outbound chat channels that need an attachment.allowRemoteViewer disabled unless your deployment requires remote viewer URLs.ttlSeconds for sensitive diffs.fileFormat: "pdf").