Diffs
diffs 是一个可选的插件工具,可将 before/after 文本或统一补丁转换为只读的 diff 工件。它还会在系统提示词前插入简短的代理指导,并附带一个配套 skill,以便提供更完整的说明。
输入:before + after 文本,或统一 patch(互斥)。
输出:用于浏览器展示的 Gateway 查看器 URL、用于消息投递的渲染 PNG/PDF 文件路径,或两者兼有。
Control UI 在未安装此插件的情况下已能高亮显示内联工具 diff 和会话 diff。当代理需要独立的查看器链接或用于其他渠道的渲染附件时,请安装 diffs。
快速开始¶
1. 安装插件
安装会自动应用到正在运行的 Gateway;否则将在下次启动时生效。参见 应用更改并检查。
diffs 及其语言包作为独立软件包发布,而非随 OpenClaw 一起提供,因此安装需要使用作用域定位符(scoped locator)。clawhub: 前缀会选择 ClawHub 上的 @openclaw/diffs 副本。如需改从 npm 安装,请使用 npm:@openclaw/diffs。
2. 启用插件
3. 选择模式
浏览器流程:代理以 mode: "view" 调用 diffs,并在浏览器中打开 details.viewerUrl。
聊天文件投递:代理以 mode: "file" 调用 diffs,并通过 path 或 filePath 将 details.filePath 随 message 一起发送。
组合(默认):代理以 mode: "both" 调用 diffs,一次调用即可获得两种工件。
禁用内置系统指导¶
若要保留工具但移除前置的系统提示词指导,请将 plugins.entries.diffs.hooks.allowPromptInjection 设置为 false:
这会阻止插件的 before_prompt_build 钩子,同时保持工具和 skill 可用。若要同时禁用指导与工具,请改为禁用该插件。
工具输入参考¶
除非另有说明,所有字段均为可选。
beforestring (path)- 原始文本。当省略
patch时,需与after一起提供。 afterstring (path)- 更新后的文本。当省略
patch时,需与before一起提供。 patchstring (path)- 统一 diff 文本。与
before和after互斥。 pathstring (path)- before/after 模式的显示文件名。
langstring (path)- before/after 模式的语言覆盖提示。未知值以及默认查看器集合之外的语言会回退为纯文本,除非已安装 Diffs Language Pack 插件。
titlestring (path)- 查看器标题覆盖。
mode"view" | "file" | "both" (path)- 输出模式。默认为插件默认值
defaults.mode(both)。已弃用的别名:"image"的行为与"file"相同。 theme"light" | "dark" (path)- 查看器主题。默认为插件默认值
defaults.theme。 layout"unified" | "split" (path)- diff 布局。默认为插件默认值
defaults.layout。 expandUnchangedboolean (path)- 当完整上下文可用时展开未更改的部分。仅为每次调用时的选项(不是插件默认键)。
fileFormat"png" | "pdf" (path)- 渲染文件格式。默认为插件默认值
defaults.fileFormat。 fileQuality"standard" | "hq" | "print" (path)- PNG/PDF 渲染的质量预设。
fileScalenumber (path)- 设备缩放比例覆盖(
1-4)。 fileMaxWidthnumber (path)- 最大渲染宽度(CSS 像素)(
640-2400)。 ttlSecondsnumber (path) 默认值:1800- 查看器和独立文件输出的工件 TTL(秒)。最大
21600。 baseUrlstring (path)- 查看器 URL 来源(origin)覆盖。覆盖插件的
viewerBaseUrl。必须为http或https,且不含查询参数/哈希。
验证与限制
before/after:各自最大 512 KiB。patch:最大 2 MiB。path:最大 2048 字节。lang:最大 128 字节。title:最大 1024 字节。- 补丁复杂度上限:最多 128 个文件和 120000 总行数。
- 同时提供
patch与before/after会被拒绝。 - 渲染文件安全限制(PNG 和 PDF):
fileQuality: "standard":最大 8 MP(8,000,000 渲染像素)。fileQuality: "hq":最大 14 MP。fileQuality: "print":最大 24 MP。- PDF 还限制为最多 50 页。
语法高亮¶
内置语言:
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 和 toml。
常用别名(js、ts、bash、md、yml、c++、dockerfile、rb、kt、ps1 等)会规范化为上述语言。
安装 Diffs Language Pack 插件以支持更多语言(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 等):
未安装该语言包时,不支持的语言仍会以可读的纯文本形式渲染。上游目录请参见 Diffs Language Pack 插件 和 Shiki 语言。
输出详情约定¶
所有成功结果均包含 changed:当 before/after 输入完全相同时返回 false,且不会创建工件;渲染结果返回 true。
查看器字段(view 和 both 模式)
changedartifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(可用时的agentId、sessionId、messageChannel、agentAccountId)
文件字段(file 和 both 模式)
changedartifactIdexpiresAtfilePathpath(与filePath相同,用于消息工具兼容性)fileBytesfileFormatfileQualityfileScalefileMaxWidth
| 模式 | 返回内容 |
|---|---|
"view" |
仅查看器字段。 |
"file" |
仅文件字段,无查看器工件。 |
"both" |
查看器字段以及文件字段。如果文件渲染失败,查看器仍会返回结果,并带有 fileError。 |
折叠的未更改部分¶
查看器显示类似 N unmodified lines 的行。展开控件只有在渲染的差异包含可展开的上下文数据时才会出现(通常出现在 before/after 输入中)。许多 unified 补丁在其 hunk 中省略了上下文主体。此时该行可能没有展开控件。这是预期行为,不是 bug。expandUnchanged 仅在存在可展开的上下文时生效。
多文件导航¶
涉及多个文件的补丁会以已更改文件摘要卡片开头。该卡片显示:
- 总计
+N/-N计数 - 每个文件的计数
- 新增、删除和重命名的徽标
- 跳转到每个文件的锚点链接
渲染后的 PNG/PDF 文件会保留每个文件的头部计数。它们会去掉交互式视图切换开关,因为在静态文件中这些控件是失效的。
插件默认值¶
在 ~/.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,
},
},
},
},
},
}
支持的 defaults 键:fontFamily、fontSize、lineSpacing、layout、showLineNumbers、diffIndicators、wordWrap、background、theme、fileFormat、fileQuality、fileScale、fileMaxWidth、mode、ttlSeconds。显式的工具调用参数会覆盖这些默认值。
持久化查看器 URL 配置¶
viewerBaseUrlstring (path)- 当工具调用未传入
baseUrl时,用于返回查看器链接的插件自有回退地址。必须是http或https,且不含查询字符串或哈希。
{
plugins: {
entries: {
diffs: {
enabled: true,
config: {
viewerBaseUrl: "https://gateway.example.com/openclaw",
},
},
},
},
}
安全配置¶
security.allowRemoteViewerboolean (path) default:falsefalse:拒绝指向查看器路由的非回环请求。true:如果令牌化路径有效,则允许远程查看器。
{
plugins: {
entries: {
diffs: {
enabled: true,
config: {
security: {
allowRemoteViewer: false,
},
},
},
},
},
}
工件生命周期与存储¶
- 查看器 HTML 和元数据存储在共享的
state/openclaw.sqlite数据库中,位于 Diffs 插件的 blob 命名空间下。HTML 经过 gzip 压缩。SQLite 仅存储随机 URL 令牌的 SHA-256 哈希,而非令牌本身。 - 由于频道投递需要文件路径,渲染后的 PNG/PDF 文件会以临时物化文件的形式保留在
$TMPDIR/openclaw-diffs下。SQLite 持有其过期元数据。OpenClaw 不写入 JSON sidecar 文件。 - 默认工件 TTL:30 分钟。最大可接受 TTL:6 小时。
- 每次工件创建调用后,清理会择机运行。首先删除过期的 SQLite 行,然后删除任何相应的 PNG/PDF 目录。
- 后备扫描会移除超过 24 小时且无对应 SQLite 行的临时文件夹。遗留的
meta.json、file-meta.json和viewer.html缓存不会被导入或读取。
查看器 URL 与网络行为¶
查看器路由:/plugins/diffs/view/{artifactId}/{token}
查看器资源:
/plugins/diffs/assets/viewer.js/plugins/diffs/assets/viewer-runtime.js/plugins/diffs-language-pack/assets/viewer.js(仅当差异使用语言包语言时)
查看器文档会相对于查看器 URL 解析这些资源。因此,可选的 baseUrl 路径前缀也会同样应用到资源请求中。
URL 解析顺序:工具调用的 baseUrl(经过严格验证后)-> 插件 viewerBaseUrl -> gateway.publicOrigin -> 现有的绑定感知 Gateway 回退。
baseUrl 规则:
- 协议必须是
http://或https://。 - 带有查询字符串或哈希的
baseUrl会被拒绝。 - 允许源(origin)加可选的基础路径。
安全模型¶
查看器加固
- 默认仅限回环(loopback)。
- 令牌化查看器路径,具有严格的 ID 和令牌模式验证。
- 查看器响应 CSP:
default-src 'none'。脚本和资源仅从自身(self)加载。查看器不发出任何出站connect-src请求。 - 启用远程访问时的远程未命中限流:每 60 秒 40 次失败会触发 60 秒锁定(
429 Too Many Requests)。
文件渲染加固
- 截图浏览器请求路由默认拒绝。
- 仅允许来自
http://127.0.0.1/plugins/diffs/assets/*的本地查看器资源。 - 外部网络请求会被阻止。
文件模式的浏览器要求¶
mode: "file" 和 mode: "both" 需要兼容 Chromium 的浏览器。
解析顺序:
1. 配置
OpenClaw 配置中的 browser.executablePath。
2. 环境变量
OPENCLAW_BROWSER_EXECUTABLE_PATHBROWSER_EXECUTABLE_PATHPLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
3. 平台回退
Chrome、Chromium、Edge 和 Brave 的常见安装路径和 PATH 查找。
常见失败文本:Diff PNG/PDF rendering requires a Chromium-compatible browser...。通过安装 Chrome、Chromium、Edge 或 Brave,或设置上述任一可执行文件路径选项来修复。
故障排查¶
输入验证错误
Provide patch or both before and after text.-- 同时包含before和after,或提供patch。Provide either patch or before/after input, not both.-- 不要混用输入模式。Invalid baseUrl: ...-- 使用带可选路径的http(s)源,不包含查询参数/哈希。{field} exceeds maximum size (...)-- 减小负载大小。- 大型 patch 被拒绝 -- 减少 patch 文件数量或总行数。
查看器可访问性
- 查看器 URL 默认解析为
127.0.0.1。 - 对于远程访问,设置
gateway.publicOrigin,设置插件viewerBaseUrl,或按调用传递baseUrl。 gateway.trustedProxies可以包含回环地址,用于同一主机代理,例如 Tailscale Serve。此时,未携带转发客户端 IP 头的原始回环查看器请求会按设计失败关闭。- 对于该代理拓扑,附件优先使用
mode: "file"/"both"。对于可共享的查看器链接,请有意启用security.allowRemoteViewer以及插件viewerBaseUrl/代理baseUrl。 - 仅在打算允许外部查看器访问时启用
security.allowRemoteViewer。
未修改行没有展开按钮
对于缺少可展开上下文的 patch 输入,这是预期行为。这不是查看器故障。
未找到工件
- 工件因 TTL 过期。
- Token 或路径已更改。
- 清理移除了过期数据。
操作指南¶
- 对于浏览器中的本地交互式审查,优先使用
mode: "view"。 - 对于需要附件的外发聊天渠道,优先使用
mode: "file"。 - 除非部署需要远程查看器 URL,否则保持
allowRemoteViewer禁用。 - 为敏感 diff 设置明确的短
ttlSeconds。 - 除非必要,避免在 diff 输入中发送机密信息。
- 如果渠道会强力压缩图像(例如 Telegram 或 WhatsApp),优先使用 PDF 输出(
fileFormat: "pdf")。
Note
Diff 渲染引擎由 Diffs 提供支持。
相关¶
- 浏览器
- 插件
- 工具概览
apply_patch— 生成这些编辑的工具
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw