ClaudeMods
☰
KO
● 0 명 접속 중 · 조회 0 회
후원프로젝트 제출
GitHub 저장소 · 작성자 natsukium

figures

kitty-graphics 터미널에서 다이어그램, LaTeX 수식, 도구 결과 이미지를 인라인으로 그립니다

번역 완료

이 mod 소개

figures

kitty graphics 프로토콜을 사용해 터미널 트랜스크립트 안에 다이어그램, LaTeX 수식, 도구 결과 이미지를 인라인으로 그리는 Claude Code mod입니다.

mermaid 순서도와 LaTeX 수식을 각각 원본 아래에 그림으로 그린 답변

그리는 항목

  • 다이어그램. Claude의 답변에서 mermaid, dot(또는 graphviz), d2, svg 태그가 붙은 코드 블록을 렌더링해 답변 아래에 그립니다. 코드는 그림 위에 계속 표시됩니다.
  • 수식. LaTeX 디스플레이 수식, $$ … $$, \[ … \], 또는 math, latex, tex 코드 블록은 MathJax로 조판합니다. 인라인 $…$는 텍스트로 남깁니다. 줄 안에 그림을 넣을 수 없기 때문입니다. 전체 문서(\documentclass)를 담은 latex 블록도 코드로 남습니다.
  • 도구 결과 이미지. PNG, JPEG, GIF, WebP, SVG 파일을 Read하거나 MCP 도구가 스크린샷을 반환하면 도구 행 아래에 그립니다. Claude Code가 보통 크기 한 줄만 표시하는 자리입니다. 일부만 읽은 SVG는 그대로 둡니다. 접힌 도구 그룹에서는 썸네일로 보이고, ctrl+o로 그룹을 펼치면 전체 크기로 그립니다. Claude가 SendUserFile로 다른 기기에 보내는 PNG, JPEG, GIF, WebP, SVG도 첨부 행 아래에 그리므로 터미널로 돌아왔을 때 화면에 표시됩니다. 행을 처음 그릴 때 디스크에서 읽으며, 나중에 파일을 덮어써도 이미 표시된 그림은 바뀌지 않습니다.

크기 제한 때문에 자연 크기의 60% 아래로 줄어들 그림은 터미널 높이까지 키웁니다. 그래도 작으면 shown at 43% · /figures to enlarge처럼 그림 아래에 표시합니다.

/figures는 세션의 그림을 보여 주는 창을 엽니다. 읽기 어려울 만큼 작게 그려진 가장 최근 그림에서 시작하고, 그런 그림이 없으면 최신 그림에서 시작합니다. p와 n으로 이동하고, o는 open(macOS) 또는 xdg-open으로 현재 그림을 엽니다. Escape 또는 다음 프롬프트로 창을 닫습니다.

트랜스크립트 옆의 /figures 창에 답변의 수식이 표시된 모습

플러그인에는 diagrams skill도 포함되어 있습니다. 어떤 언어를 그릴 수 있는지, 렌더링되도록 어떻게 작성해야 하는지 Claude에 알려 줍니다.

렌더링된 각 PNG는 $TMPDIR/claude-figures/ 아래에 캐시됩니다. 원본과 테마의 해시로 이름을 정하므로, 세션을 재개해도 다시 렌더링하지 않고 그림을 그릴 수 있습니다. 세션이 시작될 때 칠 일보다 오래된 파일을 삭제합니다.

요구 사항

mods(function-hook plugins)를 활성화하고 Claude Code가 kitty-graphics를 지원한다고 인식하는 터미널에서 Claude Code 2.1.287 이상을 사용해야 합니다. Terminal support를 참고하세요. 그림 종류마다 PATH에 다음 프로그램도 있어야 합니다.

| 그림 | 필요한 항목 | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | mermaid | mmdr 또는 mmdc; resvg 권장 | | dot, graphviz | Graphviz의 dot 및 resvg | | d2 | d2 및 resvg | | svg, 수식 | resvg | | PNG가 아닌 도구 이미지 | magick(ImageMagick) 또는 sips(macOS 기본 제공) |

  • mmdc가 헤드리스 브라우저를 시작하는 동안 mmdr은 밀리초 단위로 렌더링하므로 mmdr을 먼저 시도합니다. mmdc는 mermaid.js 자체를 실행하므로 mmdr이 처리하지 못한 블록은 설치되어 있을 때 mmdc로 넘깁니다.
  • resvg가 없으면 mmdr은 PNG를 1x로 작성해 고밀도 디스플레이에서 흐릿하게 보입니다. resvg가 있으면 다이어그램을 SVG로 렌더링한 뒤 scale 옵션으로 래스터화합니다.
  • MathJax 4와 New Computer Modern 글꼴의 모든 글리프 범위가 포함되어 Claude Code 안에서 실행되므로 수식에 Node.js가 필요하지 않습니다.
  • 렌더러가 하나도 설치되지 않은 블록은 텍스트로 읽을 수 있으므로 오류 없이 코드로 남깁니다. 설치된 렌더러가 실패할 때만 오류를 표시합니다.

설치

claude plugin marketplace add natsukium/claude-code-figures-plugin
claude plugin install figures@figures

cargo install mermaid-rs-renderer로 mmdr을 설치합니다.

옵션

/config 또는 claude plugin configure figures로 설정합니다.

| 옵션 | 기본값 | 의미 | | --------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | theme | auto | auto는 Claude Code의 테마를 따릅니다. 또는 dark, default, forest, neutral, modern을 사용할 수 있습니다(mmdr 전용이며 mmdc는 default로 그립니다). dark에서는 수식을 밝게, 그 외에는 어둡게 그립니다 | | background | transparent | 다이어그램 배경. transparent이면 터미널 배경이 비칩니다 | | scale | 2 | 그림의 픽셀 밀도. 1보다 크면 resvg가 필요합니다 | | cell_width_px | 8 | 터미널 셀 하나의 너비로 가정하는 값. 다이어그램 배치에 사용하는 픽셀 단위입니다 | | cell_aspect | 2.1 | 터미널 셀 하나의 높이 대 너비 비율로 가정하는 값 | | max_columns | 120 | 그림의 최대 너비. 셀 단위이며 터미널 안에도 맞춥니다 | | max_rows | 30 | 가독성을 위해 키우기 전 허용되는 그림의 최대 높이. 셀 단위입니다 | | renderers | (비어 있음) | 우선순위 순서의 렌더러 id를 쉼표로 구분합니다. 아래를 참고하세요 | | tool_images | true | 도구 결과에서 찾은 이미지를 그립니다 | | tool_image_max_rows | 12 | 도구 결과 썸네일의 최대 높이. 셀 단위입니다 |

renderers는 각 언어를 그리는 프로그램을 선택하고 순서를 정합니다. id는 mmdr와 mmdc(mermaid), dot, d2, svg, mathjax입니다. 어떤 언어에 렌더러가 하나라도 지정되면 지정한 것만 나열된 순서로 사용하고, 나머지는 기본값을 유지합니다. 따라서 mmdc는 mmdc만으로 mermaid를 그리고, mmdc,mmdr은 mmdc를 먼저 시도합니다. 렌더러가 없는 id는 세션 시작 시 보고합니다.

터미널 지원

터미널의 XTVERSION 응답이 kitty(0.28.0 이상) 또는 Ghostty라고 이름을 지정할 때만 Claude Code가 그림을 활성화합니다. 다른 이름으로 kitty graphics 쿼리에 올바르게 답하는 터미널도 [mermaid diagram 1] 같은 alt 텍스트를 받습니다. TERM 또는 TERM_PROGRAM을 설정해도 효과가 없습니다.

그런 터미널에서 플러그인을 사용하려면 Claude Code가 읽는 재정의를 설정합니다.

CLAUDE_CODE_FORCE_TERMINAL_IMAGES=1 claude

Claude Code의 tmux 검사도 건너뜁니다. tmux 안에서는 그림에 더해 set -g allow-passthrough on이 필요합니다.

Claude Code의 판단을 보려면 --debug로 시작하고 디버그 로그에서 Terminal capabilities: 줄을 찾으세요.

제한 사항

  • mods에는 터미널 셀의 픽셀 크기가 전달되지 않으므로 셀 단위 그림 크기를 cell_width_px와 cell_aspect에서 추정합니다. 그림이 늘어나 보이면 값을 조정하세요.
  • mods는 터미널 배경색을 읽을 수 없으므로 theme=auto는 Claude Code 자체 테마(/config)를 따릅니다. light 변형은 밝은 그림을, 나머지는 어두운 그림을 그립니다. Claude Code의 테마 자체가 auto이면 해석된 값이 공개되지 않으므로 터미널이 그 값을 내보내는 위치는 COLORFGBG가 결정하고, 그 외에는 어둡게 합니다.
  • mmdr은 Mermaid를 자체 파싱하므로 모든 경우에 mermaid.js와 일치하지 않습니다. 예를 들어 레이블이 있는 연결된 간선(A --> B -->|ok| C)은 잘못 파싱됩니다. 한 줄에 간선 하나를 작성하세요. 이런 블록은 오류 없이 렌더링되므로 mmdc로 넘기지 않습니다. mmdr을 피하려면 renderers를 mmdc로 설정하세요.
  • 수식 글꼴에 없는 스크립트 문자, 예를 들어 \text{日本語}는 resvg가 시스템 글꼴로 그립니다.
  • /figures 창은 프롬프트와 화면을 공유하므로 짧은 터미널에서는 몇 줄만 사용할 수 있습니다. o를 누르면 터미널 밖에서 원래 크기로 그림을 엽니다.

개발

tsconfig.json은 .claude-plugin/types/의 엔진 타입을 확장하며 Vite, Vitest, tsc가 읽습니다. Claude Code는 이 폴더에서 플러그인을 로드할 때만 타입을 작성하고 다른 명령은 단독으로 작성하지 않으므로, pnpm types는 더미 API key로 claude -p --plugin-dir .를 시작하고 타입이 존재하면 실패한 요청을 무시합니다. build, test, typecheck는 먼저 이를 실행합니다. Claude Code는 개발 의존성이므로 스크립트와 pnpm exec claude는 PATH의 claude가 무엇이든 pnpm-lock.yaml에 고정된 버전을 사용합니다.

pnpm install
pnpm build              # regenerate hooks/vendor/
pnpm test               # unit tests (Vitest, tests/unit/*.spec.ts)
pnpm typecheck
pnpm exec claude plugin validate .
pnpm exec claude plugin test .    # hooks through the engine (tests/engine/*.test.ts)

Claude Code는 hooks/를 TypeScript 소스로 로드하므로 타사 코드만 빌드됩니다. pnpm build는 Vite로 MathJax와 @noble/hashes를 hooks/vendor/에 번들하고 커밋하여 저장소를 그대로 설치할 수 있게 합니다. Hooks 모듈은 1 MiB를 넘는 파일을 임포트할 수 없고 런타임에 모듈을 임포트할 수도 없으므로 빌드가 번들을 청크로 나누고 글꼴의 각 글리프 범위를 JSON으로 작성합니다. 플러그인은 수식에서 해당 범위가 처음 사용될 때 읽습니다.

엔진은 import 사이에 $를 전달하는 모듈을 거부하므로 hooks/register.tsx는 플러그인에 필요한 $의 내용을 Io 객체(hooks/io.ts)로 감싸고 다른 모든 모듈이 이를 받습니다.

라이선스

Apache-2.0. hooks/vendor/는 MathJax와 그 New Computer Modern font(둘 다 Apache-2.0), 그리고 noble-hashes(MIT)를 바탕으로 빌드됩니다.

설치

먼저 작성자의 README에서 marketplace와 플러그인 이름을 확인하세요. 저장소 구조에 따라 명령어가 달라질 수 있습니다.

claude plugin marketplace add natsukium/claude-code-figures-plugin
claude plugin install figures
원문 / README

figures

A Claude Code mod that draws diagrams, LaTeX math, and tool-result images inline in the terminal transcript, using the kitty graphics protocol.

A reply with a mermaid flowchart and a LaTeX formula, each drawn as a picture under its source

What it draws

  • Diagrams. A code block tagged mermaid, dot (or graphviz), d2, or svg in Claude's reply is rendered and drawn under the reply. The code stays visible above the picture.
  • Math. LaTeX display math, $$ … $$, \[ … \], or a math, latex, or tex code block, is typeset with MathJax. Inline $…$ stays text, since a picture cannot sit inside a line, and a latex block holding a whole document (\documentclass) stays code.
  • Tool-result images. Read on a PNG, JPEG, GIF, WebP, or SVG file, or a screenshot an MCP tool returns, is drawn under the tool's row, where Claude Code otherwise shows only a size line; an SVG read only in part is left alone. In a collapsed tool group they are thumbnails; ctrl+o unfolds the group and draws them full size. A PNG, JPEG, GIF, WebP, or SVG Claude sends to another device with SendUserFile is drawn under its attachment line too, so it is on screen when you come back to the terminal. It is read from disk when the row is first drawn; overwriting the file later leaves that picture as it was.

A picture the size caps would shrink below 60% of its natural size grows up to the terminal's height, and one still smaller says so under it, such as shown at 43% · /figures to enlarge.

/figures opens a pane with the session's pictures, starting on the newest one drawn too small to read, or else the newest. p and n step through them, o opens the current one with open (macOS) or xdg-open, and Escape or your next prompt closes the pane.

The /figures pane beside the transcript, showing the formula from the reply

The plugin also ships a diagrams skill, which tells Claude which languages are drawn and how to write them so they render.

Each rendered PNG is cached under $TMPDIR/claude-figures/, named by a hash of the source and the theme, so a resumed session draws its pictures again without re-rendering. Files older than seven days are removed when a session starts.

Requirements

Claude Code 2.1.287 or later, with mods (function-hook plugins) enabled, in a terminal it treats as kitty-graphics capable; see Terminal support. Each kind of picture also needs programs on PATH:

| Picture | Needs | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | mermaid | mmdr or mmdc; resvg recommended | | dot, graphviz | Graphviz's dot and resvg | | d2 | d2 and resvg | | svg, math | resvg | | Tool images other than PNG | magick (ImageMagick) or sips (built into macOS) |

  • mmdr is tried first, since it renders in milliseconds where mmdc starts a headless browser. mmdc runs mermaid.js itself, so a block mmdr fails on is handed to it when it is installed.
  • Without resvg, mmdr writes its PNG at 1x, which looks soft on a high-density display; with it, the diagram is rendered to SVG and rasterized at the scale option.
  • MathJax 4 and every glyph range of its New Computer Modern font are bundled, and run inside Claude Code, so math needs no Node.js.
  • A block none of whose renderers is installed is left as code without an error, since it still reads as text. An error is shown only when an installed renderer fails.

Install

claude plugin marketplace add natsukium/claude-code-figures-plugin
claude plugin install figures@figures

Install mmdr with cargo install mermaid-rs-renderer.

Options

Set these with /config or claude plugin configure figures.

| Option | Default | Meaning | | --------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | theme | auto | auto follows Claude Code's theme; or dark, default, forest, neutral, modern (mmdr only; mmdc draws it as default). Math is drawn light on dark and dark otherwise | | background | transparent | Diagram background; transparent lets the terminal's background show through | | scale | 2 | Pixel density of the picture; above 1 needs resvg | | cell_width_px | 8 | Assumed width of one terminal cell, in the pixels diagrams are laid out in | | cell_aspect | 2.1 | Assumed height-to-width ratio of one terminal cell | | max_columns | 120 | Widest a picture may be, in cells; it is also kept inside the terminal | | max_rows | 30 | Tallest a picture may be before it is grown for legibility, in cells | | renderers | (empty) | Renderer ids in preference order, comma-separated; see below | | tool_images | true | Draw images found in tool results | | tool_image_max_rows | 12 | Tallest a tool-result thumbnail may be, in cells |

renderers picks and orders the programs that draw each language. The ids are mmdr and mmdc (mermaid), dot, d2, svg, and mathjax. A language with any of its renderers listed uses only those, in the listed order; the others keep the default. So mmdc draws mermaid with mmdc alone, and mmdc,mmdr tries mmdc first. An id no renderer has is reported when a session starts.

Terminal support

Claude Code enables pictures only when the terminal's XTVERSION reply names kitty (0.28.0 or later) or Ghostty. A terminal that answers the kitty graphics query correctly under any other name still gets the alt text, such as [mermaid diagram 1]. Setting TERM or TERM_PROGRAM has no effect.

To use the plugin on such a terminal, set the override Claude Code reads:

CLAUDE_CODE_FORCE_TERMINAL_IMAGES=1 claude

This also skips Claude Code's tmux check. Inside tmux, the pictures additionally need set -g allow-passthrough on.

To see what Claude Code decided, start it with --debug and look for the Terminal capabilities: line in the debug log.

Limitations

  • The picture's size in cells is estimated from cell_width_px and cell_aspect, since mods are not told the terminal's cell size in pixels. Adjust them if pictures look stretched.
  • Mods cannot read the terminal's background color, so theme=auto follows Claude Code's own theme (/config): a light variant draws light pictures, the others dark. When Claude Code's theme is itself auto, its resolved value is not exposed, so COLORFGBG decides where the terminal exports it, and dark otherwise.
  • mmdr parses Mermaid on its own and does not match mermaid.js in every case. For example, a chained edge with labels (A --> B -->|ok| C) is misparsed; write one edge per line. Such a block renders without an error, so it is not handed to mmdc; set renderers to mmdc to avoid mmdr.
  • Text in a script the math font lacks, such as \text{日本語}, is drawn by resvg with a system font.
  • The /figures pane shares the screen with the prompt, so in a short terminal it has only a few rows; o opens the picture at full size outside the terminal.

Development

tsconfig.json extends the engine's typings in .claude-plugin/types/, which Vite and Vitest read as well as tsc. Claude Code writes them only when it loads the plugin from this folder, and no command writes them alone, so pnpm types starts claude -p --plugin-dir . with a dummy API key and ignores the failed request once the typings exist. build, test, and typecheck run it first. Claude Code is a dev dependency, so the scripts and pnpm exec claude use the version pinned in pnpm-lock.yaml, whatever claude is on PATH.

pnpm install
pnpm build              # regenerate hooks/vendor/
pnpm test               # unit tests (Vitest, tests/unit/*.spec.ts)
pnpm typecheck
pnpm exec claude plugin validate .
pnpm exec claude plugin test .    # hooks through the engine (tests/engine/*.test.ts)

Claude Code loads hooks/ as TypeScript source, so only third-party code is built. pnpm build bundles MathJax and @noble/hashes with Vite into hooks/vendor/, which is committed so the repository stays installable as is. A hooks module imports no file over 1 MiB and cannot import modules at run time, so the build splits the bundle into chunks and writes each of the font's glyph ranges as JSON, which the plugin reads the first time a formula uses it.

The engine refuses a module that passes $ across an import, so hooks/register.tsx wraps what the plugin needs from $ in an Io object (hooks/io.ts), and every other module takes that.

License

Apache-2.0. hooks/vendor/ is built from MathJax and its New Computer Modern font, both Apache-2.0, and @noble/hashes, MIT.

비슷한 프로젝트