Bundle Pluginsource linkedVerified

Diffsv2026.9.2

OpenClaw read-only diff viewer plugin and file renderer for agents.

@openclaw/diffs·runtime diffs·by @openclaw
openclaw bundles install clawhub:@openclaw/diffs
Latest release: v2026.9.2Download zip

Compatibility

Built With Open Claw Version
2026.9.2
Min Gateway Version
>=2026.4.30
Plugin Api Range
>=2026.9.2
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Credentials
The plugin registers a local gateway HTTP route, uses Chromium via Playwright for rendering, and can optionally allow remote viewer access; these are disclosed and proportionate to shareable diff viewing, with remote viewing disabled by default.
Install Mechanism
The package uses normal OpenClaw plugin metadata with a runtime extension, tool contract, config schema, and no package install script or shell-based installer in the inspected artifacts.
Instruction Scope
The skill guidance tells agents when to use the diffs tool and how to return viewer URLs or file paths; the system-prompt hook is disclosed in the README and contains stable tool-use guidance rather than unrelated role or policy manipulation.
Persistence & Privilege
Viewer HTML is stored in expiring OpenClaw blob storage with token hashes, and rendered files are temporary materializations under the OpenClaw temp directory with cleanup logic; this is purpose-aligned persistence rather than broad indexing or credential storage.
Purpose & Capability
The stated purpose is to render before/after text or unified patches as viewer URLs and optional PNG/PDF files, and the runtime implements that specific tool behavior with input size limits and no unrelated capabilities found.
Assessment
Installers should understand that diff contents may be stored temporarily in the gateway blob store or as temp PNG/PDF files, and enabling remote viewer access makes token URLs reachable by non-local clients who know the full path. Keep remote access disabled unless that sharing model is intended.
!
dist/assets/viewer-runtime.js:1
Potential obfuscated payload detected.
About static analysis
These patterns were detected by automated regex scanning. They may be normal for skills that integrate with external APIs. Check the VirusTotal and OpenClaw results above for context-aware analysis.

Verification

Tier
source linked
Scope
artifact only
Summary
Validated package structure and linked the release to source metadata.
Commit
3928bad9badf
Tag
3928bad9badfcb6c7d140530435e806fb8092190
Provenance
No
Scan status
clean

Tags

alpha
2026.5.19-alpha.1
beta
2026.7.2-beta.7
latest
2026.9.2

@openclaw/diffs

Read-only diff viewer plugin for OpenClaw agents.

Install

openclaw plugins install @openclaw/diffs

Restart the Gateway after installing or updating the plugin.

It gives agents one tool, diffs, that can:

  • render a gateway-hosted diff viewer
  • render the same diff to a file (PNG or PDF)
  • accept either arbitrary before and after text or a unified patch

What Agents Get

The tool can return:

  • details.changed: false when before/after inputs are identical and no artifact was rendered; true for rendered results
  • details.viewerUrl: a gateway URL that can be opened in the operator's browser
  • details.filePath: a local rendered artifact path when file rendering is requested
  • details.fileFormat: the rendered file format (png or pdf)
  • details.artifactId and details.expiresAt: artifact identity and TTL metadata
  • details.context: available routing metadata such as agentId, sessionId, messageChannel, and agentAccountId

When the plugin is enabled, it also ships a companion skill from skills/ and prepends stable tool-usage guidance into system-prompt space via before_prompt_build. The hook uses prependSystemContext, so the guidance stays out of user-prompt space while still being available every turn.

This means an agent can:

  • call diffs with mode=view, then return details.viewerUrl for the operator to open
  • call diffs with mode=file, then send the file through the normal message tool using path or filePath
  • call diffs with mode=both when it wants both outputs

Tool Inputs

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"
}

Useful options:

  • mode: view, file, or both Deprecated alias: image behaves like file and is still accepted for backward compatibility.
  • layout: unified or split
  • theme: light or dark (default: dark)
  • fileFormat: png or pdf (default: png)
  • fileQuality: standard, hq, or print
  • fileScale: device scale override (1-4)
  • fileMaxWidth: max width override in CSS pixels (640-2400)
  • expandUnchanged: expand unchanged sections (per-call option only, not a plugin default key)
  • path: display name for before and after input
  • lang: language hint for before/after input; unknown values fall back to plain text
  • Default syntax highlighting covers common source, config, and documentation languages. Install diffs-language-pack for the extended language catalog.
  • title: explicit viewer title
  • ttlSeconds: artifact lifetime for viewer and standalone file outputs
  • baseUrl: override the gateway base URL used in the returned viewer link (origin or origin+base path only; no query/hash)
  • viewerBaseUrl plugin config: persistent fallback used when a tool call omits baseUrl

Input safety limits:

  • before and after: max 512 KiB each
  • patch: max 2 MiB
  • patch rendering cap: max 128 files / 120,000 lines

Plugin Defaults

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",
            ttlSeconds: 21600,
          },
        },
      },
    },
  },
}

Explicit tool parameters still win over these defaults.

Docs

Package

  • Plugin id: diffs
  • Package: @openclaw/diffs
  • Minimum OpenClaw host: 2026.4.30

Security options:

  • security.allowRemoteViewer (default false): allows non-loopback access to /plugins/diffs/view/... token URLs
  • viewerBaseUrl (optional): persistent viewer-link origin/path fallback for shareable URLs
  • defaults.ttlSeconds (default 1800, max 21600): default artifact lifetime for viewer and standalone file outputs

Example:

{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
        config: {
          viewerBaseUrl: "https://gateway.example.com/openclaw",
        },
      },
    },
  },
}

Example Agent Prompts

Open in the browser:

Use the `diffs` tool in `view` mode for this before and after content, then return the viewer URL.

Path: docs/example.md

Before:
# Hello

This is version one.

After:
# Hello

This is version two.

Render a file (PNG or PDF):

Use the `diffs` tool in `file` mode for this before and after input. After it returns `details.filePath`, use the `message` tool with `path` or `filePath` to send me the rendered diff file.

Path: README.md

Before:
OpenClaw supports plugins.

After:
OpenClaw supports plugins and hosted diff views.

Do both:

Use the `diffs` tool in `both` mode for this diff. Return the viewer URL and then send the rendered file by passing `details.filePath` to the `message` tool.

Path: src/demo.ts

Before:
const status = "old";

After:
const status = "new";

Patch input:

Use the `diffs` tool with this unified patch in `view` mode. Return its viewer URL.

diff --git a/src/example.ts b/src/example.ts
--- a/src/example.ts
+++ b/src/example.ts
@@ -1,3 +1,3 @@
 export function add(a: number, b: number) {
-  return a + b;
+  return a + b + 1;
 }

Notes

  • Multi-file patches start with a changed-files summary card: totals, per-file +N/-N stats, change badges, and anchor links.
  • Rendered PNG/PDF files keep the per-file header counts but omit the interactive view toggles.
  • The viewer is hosted locally through the gateway under /plugins/diffs/....
  • Viewer HTML and metadata are ephemeral SQLite plugin blobs. The URL token is returned to the caller while SQLite stores only its SHA-256 hash.
  • Rendered PNG/PDF files remain temporary materializations in $TMPDIR/openclaw-diffs because delivery APIs require a file path. No JSON metadata sidecars are written or imported.
  • Default viewer URLs use gateway.publicOrigin when configured, then the existing bind-aware Gateway fallback. Plugin viewerBaseUrl and per-call baseUrl take precedence.
  • If gateway.trustedProxies includes loopback for a same-host proxy (for example Tailscale Serve), raw 127.0.0.1 viewer requests without forwarded client-IP headers fail closed by design.
  • In that topology, prefer mode=file / mode=both for attachments, or intentionally enable remote viewers and set plugin viewerBaseUrl (or pass a proxy/public baseUrl) when you need a shareable viewer URL.
  • Remote viewer misses are throttled to reduce token-guess abuse.
  • PNG or PDF rendering requires a Chromium-compatible browser. Set browser.executablePath if auto-detection is not enough.
  • If your delivery channel compresses images heavily (for example Telegram or WhatsApp), prefer fileFormat: "pdf" to preserve readability.
  • N unmodified lines rows may not always include expand controls for patch input, because many patch hunks do not carry full expandable context data.
  • Diff rendering is powered by Diffs.