Tools
差分
diffs は、短い組み込みシステムガイダンスと付属スキルを備えた任意の Plugin ツールで、変更内容をエージェント向けの読み取り専用差分アーティファクトに変換します。
次のいずれかを受け取ります。
beforeとafterのテキスト- 統一形式の
patch
次を返せます。
- キャンバス表示用の Gateway ビューアー URL
- メッセージ配信用のレンダリング済みファイルパス (PNG または PDF)
- 1 回の呼び出しで両方の出力
有効にすると、この Plugin は簡潔な使用ガイダンスをシステムプロンプト領域に付加し、エージェントがより詳しい手順を必要とする場合のために詳細なスキルも公開します。
クイックスタート
Plugin をインストールする
openclaw plugins install diffs
Plugin を有効にする
{
plugins: {
entries: {
diffs: {
enabled: true,
},
},
},
}
モードを選ぶ
view
キャンバス優先のフロー: エージェントは 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、ツール、付属スキルは利用可能なまま、diffs Plugin の before_prompt_build フックがブロックされます。
ガイダンスとツールの両方を無効にしたい場合は、代わりに Plugin を無効にしてください。
一般的なエージェントワークフロー
diffs を呼び出す
エージェントが入力を指定して diffs ツールを呼び出します。
details を読む
エージェントがレスポンスから details フィールドを読み取ります。
提示する
エージェントは canvas present で details.viewerUrl を開くか、path または filePath を使って message で details.filePath を送信するか、またはその両方を行います。
入力例
変更前と変更後
{
"before": "# Hello\n\nOne",
"after": "# Hello\n\nTwo",
"path": "docs/example.md",
"mode": "view"
}
パッチ
{
"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統一差分テキスト。before および after とは相互に排他的です。
pathstring変更前後モードで表示するファイル名。
langstring変更前後モードの言語上書きヒント。不明な値はプレーンテキストにフォールバックします。
titlestringビューアータイトルの上書き。
mode"view" | "file" | "both"出力モード。Plugin のデフォルト defaults.mode が既定値です。非推奨のエイリアス: "image" は "file" と同様に動作し、後方互換性のために引き続き受け付けられます。
theme"light" | "dark"ビューアーテーマ。Plugin のデフォルト defaults.theme が既定値です。
layout"unified" | "split"差分レイアウト。Plugin のデフォルト defaults.layout が既定値です。
expandUnchangedboolean完全なコンテキストが利用可能な場合に、未変更セクションを展開します。呼び出しごとのオプションのみです (Plugin のデフォルトキーではありません)。
fileFormat"png" | "pdf"レンダリング済みファイル形式。Plugin のデフォルト defaults.fileFormat が既定値です。
fileQuality"standard" | "hq" | "print"PNG または PDF レンダリングの品質プリセット。
fileScalenumberデバイススケールの上書き (1-4)。
fileMaxWidthnumberCSS ピクセルでの最大レンダリング幅 (640-2400)。
ttlSecondsnumberビューアーとスタンドアロンファイル出力のアーティファクト TTL (秒)。最大 21600。
baseUrlstringビューアー URL オリジンの上書き。Plugin の viewerBaseUrl を上書きします。http または https である必要があり、クエリ/ハッシュは使えません。
レガシー入力エイリアス
後方互換性のために引き続き受け付けられます。
format->fileFormatimageFormat->fileFormatimageQuality->fileQualityimageScale->fileScaleimageMaxWidth->fileMaxWidth
検証と制限
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 ページの制限もあります。
出力 details の契約
このツールは details 配下に構造化メタデータを返します。
ビューアーフィールド
ビューアーを作成するモードの共有フィールド:
artifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(利用可能な場合はagentId,sessionId,messageChannel,agentAccountId)
ファイルフィールド
PNG または PDF がレンダリングされる場合のファイルフィールド:
artifactIdexpiresAtfilePathpath(メッセージツール互換性のため、filePathと同じ値)fileBytesfileFormatfileQualityfileScalefileMaxWidth
互換性エイリアス
既存の呼び出し元向けに次も返されます。
format(fileFormatと同じ値)imagePath(filePathと同じ値)imageBytes(fileBytesと同じ値)imageQuality(fileQualityと同じ値)imageScale(fileScaleと同じ値)imageMaxWidth(fileMaxWidthと同じ値)
モード動作の概要:
| モード | 返される内容 |
|---|---|
"view" |
ビューアーフィールドのみ。 |
"file" |
ファイルフィールドのみ。ビューアーアーティファクトはありません。 |
"both" |
ビューアーフィールドとファイルフィールド。ファイルレンダリングに失敗した場合も、ビューアーは fileError と imageError エイリアス付きで返されます。 |
折りたたまれた未変更セクション
- ビューアーは
N unmodified linesのような行を表示できます。 - それらの行の展開コントロールは条件付きであり、すべての入力種別で保証されるわけではありません。
- 展開コントロールは、レンダリング済み差分に展開可能なコンテキストデータがある場合に表示されます。これは変更前後入力では一般的です。
- 多くの統一パッチ入力では、省略されたコンテキスト本文は解析済みパッチハンクで利用できないため、展開コントロールなしで行が表示されることがあります。これは想定される動作です。
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",
},
},
},
},
},
}
サポートされるデフォルト:
fontFamilyfontSizelineSpacinglayoutshowLineNumbersdiffIndicatorswordWrapbackgroundthemefileFormatfileQualityfileScalefileMaxWidthmode
明示的なツールパラメーターはこれらのデフォルトを上書きします。
永続ビューアー URL 設定
viewerBaseUrlstringツール呼び出しで baseUrl が渡されない場合に返されるビューアーリンクの、Plugin 所有のフォールバック。http または https である必要があり、クエリ/ハッシュは使えません。
{
plugins: {
entries: {
diffs: {
enabled: true,
config: {
viewerBaseUrl: "https://gateway.example.com/openclaw",
},
},
},
},
}
セキュリティ設定
security.allowRemoteViewerbooleanfalse: ビューアールートへの非ループバックリクエストは拒否されます。true: トークン付きパスが有効な場合、リモートビューアーが許可されます。
{
plugins: {
entries: {
diffs: {
enabled: true,
config: {
security: {
allowRemoteViewer: false,
},
},
},
},
},
}
アーティファクトのライフサイクルと保存
- アーティファクトは一時サブフォルダー
$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
ビューアードキュメントはそれらのアセットをビューアー URL からの相対位置で解決するため、任意の baseUrl パスプレフィックスは両方のアセットリクエストでも維持されます。
URL 構築動作:
- ツール呼び出しの
baseUrlが指定されている場合は、厳格な検証後に使用されます。 - それ以外で Plugin の
viewerBaseUrlが設定されている場合は、それが使用されます。 - どちらの上書きもない場合、ビューアー URL はループバック
127.0.0.1が既定値になります。 - Gateway のバインドモードが
customで、gateway.customBindHostが設定されている場合は、そのホストが使用されます。
baseUrl ルール:
http://またはhttps://である必要があります。- クエリとハッシュは拒否されます。
- オリジンに任意のベースパスを加えたものが許可されます。
セキュリティモデル
ビューアーの強化
- デフォルトではループバックのみ。
- 厳密な ID とトークン検証を備えた、トークン化されたビューアーパス。
- ビューアーレスポンスの CSP:
default-src 'none'- スクリプトとアセットは自分自身からのみ
- 外向きの
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) のループバックが含まれる場合、転送されたクライアント IP ヘッダーのない生のループバックビューアーリクエストは、設計上フェイルクローズします。- そのプロキシトポロジーでは:
- 添付ファイルだけが必要な場合は
mode: "file"またはmode: "both"を優先する、または - 共有可能なビューアー URL が必要な場合は、意図的に
security.allowRemoteViewerを有効にし、Plugin のviewerBaseUrlを設定するか、プロキシ/パブリックbaseUrlを渡す
- 添付ファイルだけが必要な場合は
- 外部ビューアーアクセスを意図している場合にのみ、
security.allowRemoteViewerを有効にします。
未変更行の行に展開ボタンがない
これは、パッチ入力でパッチが展開可能なコンテキストを持たない場合に発生することがあります。これは想定どおりであり、ビューアーの失敗を示すものではありません。
アーティファクトが見つからない
- TTL によりアーティファクトの有効期限が切れました。
- トークンまたはパスが変更されました。
- クリーンアップにより古いデータが削除されました。
運用ガイダンス
- canvas でのローカル対話型レビューには
mode: "view"を優先します。 - 添付ファイルが必要な外向きチャットチャネルには
mode: "file"を優先します。 - デプロイでリモートビューアー URL が必要でない限り、
allowRemoteViewerは無効のままにします。 - 機密性の高い diff には、明示的で短い
ttlSecondsを設定します。 - 必要でない場合は、diff 入力にシークレットを送信しないでください。
- チャネルが画像を強く圧縮する場合 (たとえば Telegram や WhatsApp)、PDF 出力 (
fileFormat: "pdf") を優先します。