Tools

차이점

diffs는 짧은 내장 시스템 지침과 변경 내용을 에이전트용 읽기 전용 diff 아티팩트로 변환하는 동반 skill이 있는 선택적 Plugin 도구입니다.

다음 중 하나를 받을 수 있습니다.

  • beforeafter 텍스트
  • 통합 patch

다음을 반환할 수 있습니다.

  • 캔버스 표시용 Gateway 뷰어 URL
  • 메시지 전달용 렌더링된 파일 경로(PNG 또는 PDF)
  • 한 번의 호출에서 두 출력 모두

활성화하면 Plugin은 간결한 사용 지침을 시스템 프롬프트 공간 앞에 추가하고, 에이전트에 더 자세한 지침이 필요한 경우를 위해 상세 skill도 노출합니다.

빠른 시작

  • Plugin 설치

    bash
    openclaw plugins install diffs
  • Plugin 활성화

    json5
    {  plugins: {    entries: {      diffs: {        enabled: true,      },    },  },}
  • 모드 선택

    view

    캔버스 우선 흐름: 에이전트는 mode: "view"diffs를 호출하고 canvas presentdetails.viewerUrl을 엽니다.

    file

    채팅 파일 전달: 에이전트는 mode: "file"diffs를 호출하고 path 또는 filePath를 사용해 messagedetails.filePath를 보냅니다.

    both

    결합: 에이전트는 mode: "both"diffs를 호출해 한 번의 호출에서 두 아티팩트를 모두 가져옵니다.

  • 내장 시스템 지침 비활성화

    diffs 도구는 활성화한 상태로 유지하되 내장 시스템 프롬프트 지침을 비활성화하려면 plugins.entries.diffs.hooks.allowPromptInjectionfalse로 설정하세요.

    json5
    {  plugins: {    entries: {      diffs: {        enabled: true,        hooks: {          allowPromptInjection: false,        },      },    },  },}

    이렇게 하면 Plugin, 도구, 동반 skill은 계속 사용할 수 있는 상태로 두면서 diffs Plugin의 before_prompt_build 훅을 차단합니다.

    지침과 도구를 모두 비활성화하려면 대신 Plugin을 비활성화하세요.

    일반적인 에이전트 워크플로

  • diffs 호출

    에이전트가 입력과 함께 diffs 도구를 호출합니다.

  • details 읽기

    에이전트가 응답에서 details 필드를 읽습니다.

  • 표시

    에이전트는 canvas presentdetails.viewerUrl을 열거나, path 또는 filePath를 사용해 messagedetails.filePath를 보내거나, 둘 다 수행합니다.

  • 입력 예시

    Before 및 after

    json
    {  "before": "# Hello\n\nOne",  "after": "# Hello\n\nTwo",  "path": "docs/example.md",  "mode": "view"}

    Patch

    json
    {  "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 텍스트입니다. beforeafter와 상호 배타적입니다.

    pathstring

    before 및 after 모드의 표시 파일 이름입니다.

    langstring

    before 및 after 모드의 언어 재정의 힌트입니다. Diff Viewer Language Pack Plugin이 설치되어 있지 않으면 알 수 없는 값과 기본 뷰어 집합 외부의 언어는 일반 텍스트로 대체됩니다.

    titlestring

    뷰어 제목 재정의입니다.

    mode"view" | "file" | "both"

    출력 모드입니다. 기본값은 Plugin 기본값 defaults.mode입니다. 더 이상 권장되지 않는 별칭: "image""file"처럼 동작하며 이전 버전과의 호환성을 위해 여전히 허용됩니다.

    theme"light" | "dark"

    뷰어 테마입니다. 기본값은 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)입니다.

    fileMaxWidthnumber

    CSS 픽셀 단위의 최대 렌더링 너비(640-2400)입니다.

    ttlSecondsnumberdefault: 1800

    뷰어 및 독립 실행형 파일 출력의 아티팩트 TTL(초)입니다. 최대 21600입니다.

    baseUrlstring

    뷰어 URL 원본 재정의입니다. Plugin viewerBaseUrl을 재정의합니다. http 또는 https여야 하며 쿼리/해시는 없어야 합니다.

    레거시 입력 별칭

    이전 버전과의 호환성을 위해 여전히 허용됩니다.

    • format -> fileFormat
    • imageFormat -> fileFormat
    • imageQuality -> fileQuality
    • imageScale -> fileScale
    • imageMaxWidth -> fileMaxWidth
    검증 및 제한
    • beforeafter는 각각 최대 512 KiB입니다.
    • patch는 최대 2 MiB입니다.
    • path는 최대 2048바이트입니다.
    • lang은 최대 128바이트입니다.
    • title은 최대 1024바이트입니다.
    • Patch 복잡도 상한: 최대 파일 128개 및 총 120000줄입니다.
    • patchbefore 또는 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을 설치하여 다른 언어를 강조 표시하세요.

    bash
    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 아래에 구조화된 메타데이터를 반환합니다.

    뷰어 필드

    뷰어를 생성하는 모드의 공유 필드:

    • artifactId
    • viewerUrl
    • viewerPath
    • title
    • expiresAt
    • inputKind
    • fileCount
    • mode
    • context (사용 가능한 경우 agentId, sessionId, messageChannel, agentAccountId)
    파일 필드

    PNG 또는 PDF가 렌더링될 때의 파일 필드:

    • artifactId
    • expiresAt
    • filePath
    • path (메시지 도구 호환성을 위해 filePath와 같은 값)
    • fileBytes
    • fileFormat
    • fileQuality
    • fileScale
    • fileMaxWidth
    호환성 별칭

    기존 호출자에게도 반환됩니다:

    • format (fileFormat과 같은 값)
    • imagePath (filePath와 같은 값)
    • imageBytes (fileBytes와 같은 값)
    • imageQuality (fileQuality와 같은 값)
    • imageScale (fileScale와 같은 값)
    • imageMaxWidth (fileMaxWidth와 같은 값)

    모드 동작 요약:

    모드 반환되는 내용
    "view" 뷰어 필드만.
    "file" 파일 필드만, 뷰어 아티팩트 없음.
    "both" 뷰어 필드와 파일 필드. 파일 렌더링이 실패하면 뷰어는 fileErrorimageError 별칭과 함께 계속 반환됩니다.

    접힌 변경 없는 섹션

    • 뷰어는 N unmodified lines 같은 행을 표시할 수 있습니다.
    • 해당 행의 펼치기 컨트롤은 조건부이며 모든 입력 종류에서 보장되지는 않습니다.
    • 펼치기 컨트롤은 렌더링된 diff에 펼칠 수 있는 컨텍스트 데이터가 있을 때 표시되며, 이는 before 및 after 입력에서 일반적입니다.
    • 많은 unified patch 입력의 경우 생략된 컨텍스트 본문은 파싱된 패치 hunk에서 사용할 수 없으므로, 행이 펼치기 컨트롤 없이 나타날 수 있습니다. 이는 예상된 동작입니다.
    • expandUnchanged는 펼칠 수 있는 컨텍스트가 있을 때만 적용됩니다.

    Plugin 기본값

    Plugin 전체 기본값을 ~/.openclaw/openclaw.json에 설정하세요.

    json5
    {  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,          },        },      },    },  },}

    지원되는 기본값:

    • fontFamily
    • fontSize
    • lineSpacing
    • layout
    • showLineNumbers
    • diffIndicators
    • wordWrap
    • background
    • theme
    • fileFormat
    • fileQuality
    • fileScale
    • fileMaxWidth
    • mode
    • ttlSeconds

    명시적인 도구 매개변수는 이러한 기본값을 재정의합니다.

    영구 뷰어 URL 구성

    viewerBaseUrlstring

    도구 호출이 baseUrl을 전달하지 않을 때 반환되는 뷰어 링크에 대한 Plugin 소유 fallback입니다. http 또는 https여야 하며, 쿼리/해시는 없어야 합니다.

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

    보안 구성

    security.allowRemoteViewerbooleandefault: false

    false: 뷰어 라우트에 대한 non-loopback 요청이 거부됩니다. true: 토큰화된 경로가 유효하면 원격 뷰어가 허용됩니다.

    json5
    {  plugins: {    entries: {      diffs: {        enabled: true,        config: {          security: {            allowRemoteViewer: false,          },        },      },    },  },}

    아티팩트 수명 주기 및 스토리지

    • 아티팩트는 임시 하위 폴더 $TMPDIR/openclaw-diffs 아래에 저장됩니다.
    • 뷰어 아티팩트 메타데이터에는 다음이 포함됩니다.
      • 무작위 아티팩트 ID(16진수 20자)
      • 무작위 토큰(16진수 48자)
      • createdAtexpiresAt
      • 저장된 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://여야 합니다.
    • 쿼리와 해시는 거부됩니다.
    • Origin과 선택적 기본 경로가 허용됩니다.

    보안 모델

    뷰어 강화
    • 기본적으로 loopback 전용입니다.
    • 엄격한 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_PATH
    • BROWSER_EXECUTABLE_PATH
    • PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
  • 플랫폼 대체

    플랫폼 명령/경로 탐색 대체.

  • 일반적인 실패 문구:

    • Diff PNG/PDF rendering requires a Chromium-compatible browser...

    Chrome, Chromium, Edge 또는 Brave를 설치하거나 위의 실행 파일 경로 옵션 중 하나를 설정하여 해결하세요.

    문제 해결

    입력 검증 오류
    • Provide patch or both before and after text.beforeafter를 모두 포함하거나 patch를 제공하세요.
    • Provide either patch or before/after input, not both. — 입력 모드를 혼합하지 마세요.
    • Invalid baseUrl: ... — 선택적 경로가 있는 http(s) Origin을 사용하고 쿼리/해시는 사용하지 마세요.
    • {field} exceeds maximum size (...) — 페이로드 크기를 줄이세요.
    • 큰 패치 거부 — 패치 파일 수 또는 전체 줄 수를 줄이세요.
    뷰어 접근성
    • 뷰어 URL은 기본적으로 127.0.0.1로 확인됩니다.
    • 원격 액세스 시나리오에서는 다음 중 하나를 사용하세요.
      • Plugin viewerBaseUrl을 설정하거나,
      • 도구 호출마다 baseUrl을 전달하거나,
      • gateway.bind=customgateway.customBindHost를 사용
    • gateway.trustedProxies가 동일 호스트 프록시(예: Tailscale Serve)를 위해 loopback을 포함하는 경우, 전달된 클라이언트 IP 헤더가 없는 원시 loopback 뷰어 요청은 설계상 실패하도록 닫힙니다.
    • 해당 프록시 토폴로지에서는 다음을 따르세요.
      • 첨부 파일만 필요할 때는 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")을 선호하세요.

    관련 항목

    Was this useful?
    On this page

    On this page