Tools
差分
diffs は、短い組み込みシステムガイダンスとコンパニオン Skill を備えた任意の Plugin ツールで、変更内容をエージェント向けの読み取り専用 diff アーティファクトに変換します。
次のいずれかを受け付けます。
beforeとafterのテキスト- 統一形式の
patch
次を返せます。
- canvas 表示用の Gateway viewer URL
- メッセージ配信用のレンダリング済みファイルパス(PNG または PDF)
- 1 回の呼び出しで両方の出力
有効にすると、この Plugin はシステムプロンプト領域に簡潔な使用ガイダンスを追加し、エージェントがより詳しい手順を必要とする場合のために詳細な Skill も公開します。
クイックスタート
Install the plugin
openclaw plugins install diffsEnable the plugin
{ plugins: { entries: { diffs: { enabled: true, }, }, },}Pick a mode
view
canvas 優先のフロー: エージェントは mode: "view" で diffs を呼び出し、canvas present で details.viewerUrl を開きます。
file
チャットでのファイル配信: エージェントは mode: "file" で diffs を呼び出し、path または filePath を使って message で details.filePath を送信します。
both
組み合わせ: エージェントは mode: "both" で diffs を呼び出し、1 回の呼び出しで両方のアーティファクトを取得します。
組み込みシステムガイダンスを無効にする
diffs ツールを有効にしたまま、その組み込みシステムプロンプトガイダンスを無効にしたい場合は、plugins.entries.diffs.hooks.allowPromptInjection を false に設定します。
{ plugins: { entries: { diffs: { enabled: true, hooks: { allowPromptInjection: false, }, }, }, },}これにより、Plugin、ツール、コンパニオン Skill は利用可能なまま、diffs Plugin の before_prompt_build フックがブロックされます。
ガイダンスとツールの両方を無効にしたい場合は、代わりに Plugin を無効にします。
一般的なエージェントワークフロー
Call diffs
エージェントが入力を指定して diffs ツールを呼び出します。
Read details
エージェントがレスポンスから details フィールドを読み取ります。
Present
エージェントは canvas present で details.viewerUrl を開くか、path または filePath を使って message で details.filePath を送信するか、その両方を行います。
入力例
Before and 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"}ツール入力リファレンス
特記がない限り、すべてのフィールドは任意です。
beforestring元のテキスト。patch を省略する場合は after と一緒に必須です。
afterstring更新後のテキスト。patch を省略する場合は before と一緒に必須です。
patchstring統一 diff テキスト。before および after とは同時に指定できません。
pathstringbefore and after モードで表示するファイル名。
langstringbefore and after モードの言語上書きヒント。不明な値やデフォルト viewer セット外の言語は、 Diff Viewer Language Pack Plugin がインストールされていない限り、プレーンテキストにフォールバックします。
titlestringviewer タイトルの上書き。
mode"view" | "file" | "both"出力モード。Plugin のデフォルト defaults.mode が既定です。非推奨のエイリアス: "image" は "file" と同様に動作し、後方互換性のため引き続き受け付けられます。
theme"light" | "dark"viewer テーマ。Plugin のデフォルト defaults.theme が既定です。
layout"unified" | "split"diff レイアウト。Plugin のデフォルト defaults.layout が既定です。
expandUnchangedboolean完全なコンテキストが利用可能な場合に、変更のないセクションを展開します。呼び出しごとのオプションのみです(Plugin のデフォルトキーではありません)。
fileFormat"png" | "pdf"レンダリング済みファイル形式。Plugin のデフォルト defaults.fileFormat が既定です。
fileQuality"standard" | "hq" | "print"PNG または PDF レンダリングの品質プリセット。
fileScalenumberデバイススケールの上書き(1-4)。
fileMaxWidthnumberCSS ピクセル単位の最大レンダリング幅(640-2400)。
ttlSecondsnumberdefault: 1800viewer およびスタンドアロンファイル出力のアーティファクト TTL(秒)。最大 21600。
baseUrlstringviewer URL オリジンの上書き。Plugin の viewerBaseUrl を上書きします。http または https である必要があり、query/hash は指定できません。
Legacy input aliases
後方互換性のため引き続き受け付けられます。
format->fileFormatimageFormat->fileFormatimageQuality->fileQualityimageScale->fileScaleimageMaxWidth->fileMaxWidth
Validation and limits
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(14,000,000 レンダリングピクセル)。fileQuality: "print": 最大 24 MP(24,000,000 レンダリングピクセル)。- PDF には最大 50 ページの上限もあります。
構文ハイライト
OpenClaw には、一般的なソース、設定、ドキュメント言語の構文ハイライトが含まれています。
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 などの一般的なエイリアスは、これらのデフォルト言語に正規化されます。
Diff Viewer Language Pack Plugin をインストールして、他の言語をハイライトします。
openclaw plugins install clawhub:@openclaw/diffs-language-pack言語パックが利用可能になると、OpenClaw はさらに多くの言語をハイライトできます。パックがインストールされていない場合でも、デフォルトリスト外のファイルは読みやすいプレーンテキストとしてレンダリングされます。例には 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 Plugin を、Shiki の上流言語とエイリアスカタログは Shiki languages を参照してください。
出力詳細の契約
このツールは details の下に構造化メタデータを返します。
Viewer fields
ビューアーを作成するモードの共有フィールド:
artifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(利用可能な場合はagentId、sessionId、messageChannel、agentAccountId)
File fields
PNG または PDF がレンダリングされた場合のファイルフィールド:
artifactIdexpiresAtfilePathpath(メッセージツール互換性のため、filePathと同じ値)fileBytesfileFormatfileQualityfileScalefileMaxWidth
Compatibility aliases
既存の呼び出し元向けにも返されます:
format(fileFormatと同じ値)imagePath(filePathと同じ値)imageBytes(fileBytesと同じ値)imageQuality(fileQualityと同じ値)imageScale(fileScaleと同じ値)imageMaxWidth(fileMaxWidthと同じ値)
モード動作の概要:
| モード | 返される内容 |
|---|---|
"view" |
ビューアーフィールドのみ。 |
"file" |
ファイルフィールドのみ。ビューアーアーティファクトはありません。 |
"both" |
ビューアーフィールドとファイルフィールド。ファイルのレンダリングに失敗した場合でも、ビューアーは fileError と imageError エイリアス付きで返されます。 |
折りたたまれた未変更セクション
- ビューアーは
N unmodified linesのような行を表示できます。 - それらの行の展開コントロールは条件付きであり、すべての入力種別で保証されるわけではありません。
- 展開コントロールは、レンダリングされた diff に展開可能なコンテキストデータがある場合に表示されます。これは before と after の入力で一般的です。
- 多くの unified patch 入力では、省略されたコンテキスト本文は解析済みパッチハンクで利用できないため、行が展開コントロールなしで表示されることがあります。これは想定される動作です。
expandUnchangedは、展開可能なコンテキストが存在する場合にのみ適用されます。
Plugin のデフォルト
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", ttlSeconds: 21600, }, }, }, }, },}サポートされるデフォルト:
fontFamilyfontSizelineSpacinglayoutshowLineNumbersdiffIndicatorswordWrapbackgroundthemefileFormatfileQualityfileScalefileMaxWidthmodettlSeconds
明示的なツールパラメーターはこれらのデフォルトを上書きします。
永続的なビューアー URL 設定
viewerBaseUrlstringツール呼び出しが baseUrl を渡さない場合に返されるビューアーリンク向けの、Plugin 所有のフォールバック。http または https である必要があり、クエリ/ハッシュは指定できません。
{ plugins: { entries: { diffs: { enabled: true, config: { viewerBaseUrl: "https://gateway.example.com/openclaw", }, }, }, },}セキュリティ設定
security.allowRemoteViewerbooleandefault: falsefalse: ビューアールートへの非 local loopback リクエストは拒否されます。true: トークン化されたパスが有効な場合、リモートビューアーが許可されます。
{ plugins: { entries: { diffs: { enabled: true, config: { security: { allowRemoteViewer: false, }, }, }, }, },}アーティファクトのライフサイクルとストレージ
- アーティファクトは temp サブフォルダー
$TMPDIR/openclaw-diffsの下に保存されます。 - ビューアアーティファクトのメタデータには次が含まれます:
- ランダムなアーティファクト ID (20 桁の 16 進文字)
- ランダムなトークン (48 桁の 16 進文字)
createdAtとexpiresAt- 保存された
viewer.htmlパス
- 指定されていない場合、デフォルトのアーティファクト TTL は 30 分です。
- 受け入れられるビューア TTL の最大値は 6 時間です。
- クリーンアップはアーティファクト作成後に適宜実行されます。
- 期限切れのアーティファクトは削除されます。
- フォールバッククリーンアップは、メタデータがない場合に 24 時間を超えて古いフォルダーを削除します。
ビューア URL とネットワーク動作
ビューアルート:
/plugins/diffs/view/{artifactId}/{token}
ビューアアセット:
/plugins/diffs/assets/viewer.js/plugins/diffs/assets/viewer-runtime.js- diff が Diff Viewer Language Pack の言語を使用する場合は
/plugins/diffs-language-pack/assets/viewer.js
ビューアドキュメントはそれらのアセットをビューア URL からの相対パスとして解決するため、任意の baseUrl パスプレフィックスも両方のアセットリクエストで保持されます。
URL 構築の動作:
- ツール呼び出しの
baseUrlが指定されている場合、厳密な検証後に使用されます。 - それ以外で Plugin の
viewerBaseUrlが設定されている場合、それが使用されます。 - どちらの上書きもない場合、ビューア URL はデフォルトで loopback
127.0.0.1になります。 - Gateway バインドモードが
customで、gateway.customBindHostが設定されている場合、そのホストが使用されます。
baseUrl のルール:
http://またはhttps://である必要があります。- クエリとハッシュは拒否されます。
- オリジンと任意のベースパスが許可されます。
セキュリティモデル
ビューアの堅牢化
- デフォルトでは 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 互換ブラウザーが必要です。
解決順序:
設定
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)オリジンを使用し、クエリ/ハッシュは使用しません。{field} exceeds maximum size (...)— ペイロードサイズを減らします。- 大きなパッチの拒否 — パッチファイル数または合計行数を減らします。
ビューアのアクセシビリティ
- ビューア URL はデフォルトで
127.0.0.1に解決されます。 - リモートアクセスシナリオでは、次のいずれかを行います:
- Plugin の
viewerBaseUrlを設定する、または - ツール呼び出しごとに
baseUrlを渡す、または gateway.bind=customとgateway.customBindHostを使用する
- Plugin の
gateway.trustedProxiesに同一ホストのプロキシ (たとえば Tailscale Serve) 用の loopback が含まれる場合、転送されたクライアント IP ヘッダーのない生の loopback ビューアリクエストは設計上 fail closed になります。- そのプロキシトポロジでは:
- 添付ファイルだけが必要な場合は
mode: "file"またはmode: "both"を優先する、または - 共有可能なビューア URL が必要な場合は、意図的に
security.allowRemoteViewerを有効にし、Plugin のviewerBaseUrlを設定するか、プロキシ/公開baseUrlを渡します
- 添付ファイルだけが必要な場合は
- 外部ビューアアクセスを意図する場合にのみ
security.allowRemoteViewerを有効にします。
未変更行の行に展開ボタンがない
これは、パッチに展開可能なコンテキストが含まれない場合にパッチ入力で発生することがあります。これは想定どおりであり、ビューアの失敗を示すものではありません。
アーティファクトが見つからない
- TTL によりアーティファクトが期限切れになりました。
- トークンまたはパスが変更されました。
- クリーンアップにより古いデータが削除されました。
運用ガイダンス
- キャンバスでのローカル対話型レビューには
mode: "view"を優先します。 - 添付ファイルが必要なアウトバウンドチャットチャネルには
mode: "file"を優先します。 - デプロイでリモートビューア URL が必要な場合を除き、
allowRemoteViewerは無効のままにします。 - 機密性の高い diff には明示的に短い
ttlSecondsを設定します。 - 必要でない場合は、diff 入力にシークレットを送信しないでください。
- チャネルが画像を強く圧縮する場合 (たとえば Telegram や WhatsApp)、PDF 出力 (
fileFormat: "pdf") を優先します。