使用 OpenClaw Diffs 外掛:快速產出差異比對與檔案交付
每次看 AI 改完程式碼,都要對著終端機裡一堆 + 和 - 看到眼花嗎?要把這些變更清楚地呈現給使用者,或是讓 Agent 自己確認修改是否正確,其實可以更簡單。
diffs 是一個選用的 Plugin 工具,它內建了簡短的系統引導和配套技能,能將變更內容轉換為唯讀的 diff artifact,方便 Agent 處理。
它接受以下任一輸入:
before與after文本- Unified
patch
它可以回傳:
- 用於 Canvas 呈現的 Gateway Viewer URL
- 用於訊息傳送的渲染檔案路徑(PNG 或 PDF)
- 在一次呼叫中同時回傳上述兩者
啟用後,此 Plugin 會在系統提示詞空間(system-prompt space)開頭加入簡潔的使用指南,並在 Agent 需要更完整指令時提供詳細的技能說明。
- 啟用 Plugin。
- 呼叫
diffs並設定mode: "view"用於 Canvas 優先的流程。 - 呼叫
diffs並設定mode: "file"用於聊天檔案傳送流程。 - 當你需要兩種成品時,呼叫
diffs並設定mode: "both"。
啟用 Plugin
Section titled “啟用 Plugin”{ plugins: { entries: { diffs: { enabled: true, }, }, },}停用內建系統引導
Section titled “停用內建系統引導”如果你想保持 diffs 工具啟用,但想停用其內建的系統提示詞引導,請將 plugins.entries.diffs.hooks.allowPromptInjection 設定為 false:
{ plugins: { entries: { diffs: { enabled: true, hooks: { allowPromptInjection: false, }, }, }, },}這會阻擋 Diffs Plugin 的 before_prompt_build hook,同時保留 Plugin、工具和配套技能供你使用。
如果你想同時停用引導和工具,請直接停用該 Plugin。
典型的 Agent 工作流程
Section titled “典型的 Agent 工作流程”- Agent 呼叫
diffs。 - Agent 讀取
details欄位。 - Agent 執行以下操作之一:
- 使用
canvas present開啟details.viewerUrl - 使用
path或filePath透過message傳送details.filePath - 兩者皆執行
- 使用
Before 與 After:
{ "before": "# Hello\n\nOne", "after": "# Hello\n\nTwo", "path": "docs/example.md", "mode": "view"}Patch:
{ "patch": "diff --git a/src/example.ts b/src/example.ts\n--- a/src/example.ts\n+++ b/src/example.ts\n@@ -1 +1 @@\n-const x = 1;\n+const x = 2;\n", "mode": "both"}工具輸入參數參考
Section titled “工具輸入參數參考”除非另有說明,否則所有欄位均為選填:
before(string): 原始文本。若省略patch,則必須與after一起提供。after(string): 更新後的文本。若省略patch,則必須與before一起提供。patch(string): Unified diff 文本。與before和after互斥。path(string): 在 before/after 模式下顯示的檔名。lang(string): 在 before/after 模式下的語言覆寫提示。未知值將回退為純文字。title(string): 覆寫 Viewer 標題。mode("view" | "file" | "both"): 輸出模式。預設為 Plugin 的defaults.mode。 已棄用的別名:"image"的行為與"file"相同,為了向後相容仍可接受。theme("light" | "dark"): Viewer 主題。預設為 Plugin 的defaults.theme。layout("unified" | "split"): Diff 佈局。預設為 Plugin 的defaults.layout。expandUnchanged(boolean): 當有完整上下文時,展開未修改的區塊。僅限單次呼叫選項(非 Plugin 預設鍵值)。fileFormat("png" | "pdf"): 渲染的檔案格式。預設為 Plugin 的defaults.fileFormat。fileQuality("standard" | "hq" | "print"): PNG 或 PDF 渲染的品質預設值。fileScale(number): 裝置縮放比例覆寫 (1-4)。fileMaxWidth(number): 以 CSS 像素計的最大渲染寬度 (640-2400)。ttlSeconds(number): Viewer artifact 的存活時間(秒)。預設 1800,最大 21600。baseUrl(string): Viewer URL 的 Origin 覆寫。必須是http或https,不可包含 query 或 hash。
驗證與限制:
before與after每個最大 512 KiB。patch最大 2 MiB。path最大 2048 bytes。lang最大 128 bytes。title最大 1024 bytes。- Patch 複雜度上限:最多 128 個檔案和總計 120,000 行。
- 同時提供
patch與before或after會被拒絕。 - 渲染檔案安全限制(適用於 PNG 和 PDF):
fileQuality: "standard": 最大 8 MP (8,000,000 渲染像素)。fileQuality: "hq": 最大 14 MP (14,000,000 渲染像素)。fileQuality: "print": 最大 24 MP (24,000,000 渲染像素)。- PDF 另有最大 50 頁的限制。
輸出詳情規範
Section titled “輸出詳情規範”該工具會在 details 下回傳結構化的元數據。
建立 Viewer 模式的共用欄位:
artifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(包含agentId,sessionId,messageChannel,agentAccountId等可用資訊)
渲染 PNG 或 PDF 時的檔案欄位:
artifactIdexpiresAtfilePathpath(與filePath相同,用於訊息工具相容性)fileBytesfileFormatfileQualityfileScalefileMaxWidth
模式行為摘要:
mode: "view": 僅包含 Viewer 欄位。mode: "file": 僅包含檔案欄位,不產生 Viewer artifact。mode: "both": 包含 Viewer 欄位與檔案欄位。若檔案渲染失敗,Viewer 仍會回傳並附帶fileError。
摺疊未修改區塊
Section titled “摺疊未修改區塊”- Viewer 可以顯示如
N unmodified lines的行數。 - 這些行上的展開控制項是根據條件顯示的,並不保證適用於每種輸入類型。
- 當渲染的 diff 具有可展開的上下文數據時(通常是 before 和 after 輸入),會出現展開控制項。
- 對於許多 Unified patch 輸入,省略的上下文主體在解析的 patch hunk 中不可用,因此該行可能會在沒有展開控制項的情況下出現。這是預期行為。
expandUnchanged僅在存在可展開上下文時生效。
Plugin 預設值
Section titled “Plugin 預設值”在 ~/.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", }, }, }, }, },}支援的預設值:
fontFamilyfontSizelineSpacinglayoutshowLineNumbersdiffIndicatorswordWrapbackgroundthemefileFormatfileQualityfileScalefileMaxWidthmode
明確的工具參數會覆寫這些預設值。
security.allowRemoteViewer(boolean, 預設為false)false: 拒絕所有對 Viewer 路由的非 loopback 請求。true: 如果 tokenized 路徑有效,則允許遠端 Viewer。
範例:
{ plugins: { entries: { diffs: { enabled: true, config: { security: { allowRemoteViewer: false, }, }, }, }, },}成品生命週期與儲存
Section titled “成品生命週期與儲存”- Artifact 儲存在暫存子資料夾下:
$TMPDIR/openclaw-diffs。 - Viewer artifact 元數據包含:
- 隨機 artifact ID (20 個十六進位字元)
- 隨機 token (48 個十六進位字元)
createdAt與expiresAt- 儲存的
viewer.html路徑
- 未指定時,預設 Viewer TTL 為 30 分鐘。
- 最大可接受的 Viewer TTL 為 6 小時。
- 清理工作會在 artifact 建立後伺機執行。
- 過期的 artifact 會被刪除。
- 當元數據缺失時,後備清理機制會移除超過 24 小時的過期資料夾。
Viewer URL 與網路行為
Section titled “Viewer URL 與網路行為”Viewer 路由:
/plugins/diffs/view/{artifactId}/{token}
Viewer 資產:
/plugins/diffs/assets/viewer.js/plugins/diffs/assets/viewer-runtime.js
Viewer 文件會根據 Viewer URL 相對解析這些資產,因此選填的 baseUrl 路徑前綴也會保留給資產請求。
URL 建構行為:
- 如果提供了
baseUrl,則在嚴格驗證後使用。 - 若無
baseUrl,Viewer URL 預設為 loopback127.0.0.1。 - 如果 Gateway 綁定模式為
custom且設定了gateway.customBindHost,則使用該主機。
baseUrl 規則:
- 必須是
http://或https://。 - 拒絕 Query 和 hash。
- 允許 Origin 加上選填的基礎路徑。
Viewer 防護:
- 預設僅限 Loopback。
- 具有嚴格 ID 和 Token 驗證的 Tokenized Viewer 路徑。
- Viewer 回應的 CSP:
default-src 'none'- 僅允許來自自身的 script 和資產
- 無對外
connect-src
- 啟用遠端存取時的遠端錯誤限流:
- 每 60 秒 40 次失敗
- 60 秒鎖定 (
429 Too Many Requests)
檔案渲染防護:
- 截圖瀏覽器的請求路由預設為拒絕。
- 僅允許來自
http://127.0.0.1/plugins/diffs/assets/*的本地 Viewer 資產。 - 阻擋外部網路請求。
File 模式的瀏覽器需求
Section titled “File 模式的瀏覽器需求”mode: "file" 和 mode: "both" 需要 Chromium 相容的瀏覽器。
解析順序:
- OpenClaw 配置中的
browser.executablePath。 - 環境變數:
OPENCLAW_BROWSER_EXECUTABLE_PATHBROWSER_EXECUTABLE_PATHPLAYWRIGHT_CHROMIUM_EXECUTABLE_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)的 origin 與選填路徑,不要包含 query/hash。
- 使用包含
{field} exceeds maximum size (...)- 減少 payload 大小。
- Large patch rejection
- 減少 patch 檔案數量或總行數。
Viewer 存取問題:
- Viewer URL 預設解析為
127.0.0.1。 - 對於遠端存取情境,你可以:
- 在每次工具呼叫時傳遞
baseUrl,或 - 使用
gateway.bind=custom並設定gateway.customBindHost
- 在每次工具呼叫時傳遞
- 僅在你打算開放外部 Viewer 存取時才啟用
security.allowRemoteViewer。
未修改行(Unmodified-lines)沒有展開按鈕:
- 這可能發生在 patch 輸入時,且該 patch 未攜帶可展開的上下文。
- 這是正常現象,不代表 Viewer 故障。
找不到 Artifact:
- Artifact 因 TTL 到期。
- Token 或路徑已變更。
- 清理機制移除了過期數據。
- 在 Canvas 中進行本地互動式審查時,優先使用
mode: "view"。 - 對於需要附件的外部聊天頻道,優先使用
mode: "file"。 - 除非你的部署環境需要遠端 Viewer URL,否則請保持
allowRemoteViewer停用。 - 對於敏感的 diff,請明確設定較短的
ttlSeconds。 - 除非必要,避免在 diff 輸入中傳送秘密資訊(Secrets)。
- 如果你的頻道會對圖片進行強力壓縮(例如 Telegram 或 WhatsApp),建議優先選用 PDF 輸出 (
fileFormat: "pdf")。
Diff 渲染引擎:
- 由 Diffs 提供技術支援。
下一步: 想了解如何將這些工具整合到你的工作流中嗎? 你可以參考 Tools 概覽 了解更多可用工具,或是查看 Plugins 學習如何擴充功能。
有任何設定上的問題?歡迎詢問 AI Setup Assistant!
OpenClaw Expert
還是卡住了?
如果這篇文件沒有解決你的情境,直接問 OpenClaw Expert,拿到可執行步驟。