galElmalah/claude-mods/tree/main/claude-mermaid
mermaid-draw
Claude Code 中的 Mermaid 图表:Claude 编写的每个 ```mermaid 块都会转录中围栏所在的位置以彩色方框艺术形式绘制。需要函数钩子(早期访问)和交互式终端。
关于这个 mod
mermaid-draw
Claude Code 中的 Mermaid 图表。Claude 编写的每个 ```mermaid 块
都会在转录中围栏所在的位置以彩色方框艺术形式绘制。
不多花一个 token:插件在本地绘制,屏幕上不出现其他内容——没有窗格,没有按钮。
❯ how does a prompt become a reply?
⏺ A prompt flows through understanding and a decision point before a reply.
┌────────┐ ┌────────────┐ ◇────────────◇ ┌───────┐
│ │ │ │ │ │ │ │
│ Prompt ├────►│ Understand ├────►│ Use Tools? ├─Yes►│ Reply │
│ │ │ │ │ │ │ │
└────────┘ └────────────┘ ◇────────────◇ └───────┘
流程图、状态图、序列图、类图和 ER 图以及 xy 图表都会被绘制;
其他类型(甘特图、饼图、思维导图……)保留其围栏。当适合且不损失任何内容时,
自上而下的流程图或状态图会从左到右布局
(终端中的行很宝贵:5 行而不是 30 行),并且状态图的
[*] 开始和结束(渲染器将其绘制为空框)会被省略。
一个 mod:一个基于 Claude Code 函数钩子 构建的插件,TypeScript 在 Claude Code 自己的进程中运行。早期访问,因此需要下面的环境变量, 并且 API 可能会在版本之间变化。
要求
- Claude Code 2.1.270 或更高版本,并带有
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1。 - 一个交互式终端会话,字体具有制表符绘制字符
(如果没有,使用
/mermaid ascii on)。在claude -p中不会绘制任何内容。
快速开始
-
在
~/.claude/settings.json中打开函数钩子:{ "env": { "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1" } }或者对于单个会话:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude。 -
从克隆加载插件(仓库自己的
.claude/settings.json为在其中启动的会话设置变量):git clone https://github.com/galElmalah/claude-mods cd claude-mods claude --plugin-dir claude-mermaid或者从仓库的市场
gal-mods安装:claude plugin marketplace add galElmalah/claude-mods claude plugin install mermaid-draw@gal-mods -
向 Claude 请求一个图表。它会在回复中绘制。
从 claude-mermaid@claude-mods 升级?请遵循
迁移说明。
使用
| 命令 | 作用 |
| --- | --- |
| /mermaid | 显示当前设置 |
| /mermaid ascii on\|off | 使用纯 +--| 艺术而不是制表符绘制字形(默认关闭) |
| /mermaid color on\|off | 边框青色,箭头黄色,线条暗淡(默认开启) |
| /mermaid lr on\|off | 在不损失任何内容时,将自上而下的流程图和状态图从左到右布局(默认开启) |
| /mermaid reset | 恢复默认值 |
设置会重绘屏幕上已有的图表。设置会跨会话保存在 插件的存储中。
工作原理
hooks/register.ts是钩子模块。它钩住AssistantMessage的ui.render:在终端上开启颜色时,它返回自己的树(散文用Markdown,每条图表线用一个Text,颜色作为其 span 上的 props),因为从 Claude Code 2.1.287 起,重写后的props.text可能不携带任何转义序列;否则,它将每个闭合的 mermaid 围栏替换为纯文本艺术的文本围栏。它还钩住/mermaid的command.run。hooks/diagrams.ts是纯逻辑部分:查找围栏、渲染、选择横向布局(仅当自上而下渲染的每个词都保留时才保留,因为渲染器可能会覆盖反向运行的边的标签)、适配宽度、序列化。bun test覆盖它。hooks/vendor/mermaid-ascii.js是 beautiful-mermaid 的 ASCII 渲染器,由scripts/build-vendor.mjs打包(钩子模块在没有 Node 的情况下运行,无法导入包)。该渲染器只输出 ANSI,因此它在 truecolor 下针对哨兵颜色主题运行,转义被解码回角色(边框、线、箭头、文本),然后为终端自己的 16 色调色板上色,使浅色和深色主题都可读。- 该捆绑包修补了一件事:上游的 A* 边路由器搜索无界网格,因此一个将边的目标围住的图运行了约 25 秒,并因
Map maximum size exceeded而死,这会耗尽钩子的全部预算。供应商副本限制了搜索并回退到直线段,因此同一张图在约 60 毫秒内绘制完成。渲染的艺术按源和字形集缓存;钩子在首次绘制后几毫秒内稳定。
开发
npm install # esbuild, beautiful-mermaid, aimock, bun types
npm run build:vendor # rebuilds hooks/vendor/mermaid-ascii.js
npm test # unit tests of hooks/diagrams.ts
npm run test:plugin # render-hook tests in Claude Code's plugin test kit
npm run test:e2e # the plugin inside a real Claude Code (below)
npm run typecheck # against ../.claude/types (run /plugin-types first)
npm run validate # what the engine sees the module hook and call
类型检查需要你的 Claude Code 构建的声明:在仓库根目录打开一个会话,开启函数钩子并运行 /plugin-types,它会写入被 git 忽略的 .claude/types/。
插件测试套件和 Bun 使用不同的运行时。test:plugin 将钩子和套件测试复制到临时插件文件夹中,这样 Claude 的运行器就不会尝试加载 Bun 测试。npm run test:all 用各自的运行器运行两个套件和端到端测试。
端到端测试
tests/e2e 在 tmux 窗格中驱动一个真实的交互式 Claude Code,其
回复由 aimock 脚本化(一个
在本机端口上的 Anthropic-API mock,ANTHROPIC_BASE_URL 指向它),
插件从检出目录通过 --plugin-dir 加载。每个测试发送一个
提示,等待屏幕显示某个东西,并对捕获的文本进行断言,
在颜色重要时使用 -e。它覆盖每种已绘制的类型、颜色、
一条回复中的两个图表、一个未绘制的类型、过去会
挂起的密集图、列表项内的围栏、侧向布局、每种 /mermaid 形式,以及一个
对图形来说太窄的终端。需要 PATH 上有 tmux 和 claude,并且检出目录
是 Claude Code 信任的文件夹;否则跳过。约 10 秒。
对 hooks/ 的编辑会热重载到正在运行的 --plugin-dir 会话中。使用
--debug-file /tmp/mermaid.log 启动 Claude,以查看引擎拒绝了什么。
限制
- beautiful-mermaid 不绘制的类型(gantt、pie、mindmap、gitGraph、 journey、timeline、quadrant、C4、……)保留其围栏。
- 比记录更宽的图形在右侧用
…截断,并有一行 说明超出了多少;把终端调宽即可。 - 颜色仅在终端上绘制;桌面、VS Code 和移动端显示
普通图形。如果一条回复中图表之间的正文超过 10000 个字符
(一个
Markdown元素的上限),也会以普通形式绘制。
许可证
MIT。
安装
请先查看作者 README 确认 marketplace 和插件名称;命令可能随仓库结构改变。
claude plugin marketplace add galElmalah/claude-mods claude plugin install mermaid-draw@gal-mods
原文 / README
mermaid-draw
Mermaid diagrams in Claude Code. Every ```mermaid block Claude writes
is drawn as box art, in colour, right where the fence was in the transcript.
Nothing costs a token: the plugin draws locally, and nothing else appears on
screen — no pane, no buttons.
❯ how does a prompt become a reply?
⏺ A prompt flows through understanding and a decision point before a reply.
┌────────┐ ┌────────────┐ ◇────────────◇ ┌───────┐
│ │ │ │ │ │ │ │
│ Prompt ├────►│ Understand ├────►│ Use Tools? ├─Yes►│ Reply │
│ │ │ │ │ │ │ │
└────────┘ └────────────┘ ◇────────────◇ └───────┘
Flowcharts, state, sequence, class and ER diagrams and xy charts are drawn;
other kinds (gantt, pie, mindmap, …) keep their fence. A top-down flowchart
or state diagram is laid out left to right when that fits and loses nothing
(rows are dear in a terminal: 5 rows instead of 30), and a state diagram's
[*] start and end, which the renderer draws as empty boxes, are left out.
A mod: a plugin built on Claude Code function hooks, TypeScript that runs inside Claude Code's own process. Early access, so it needs the environment variable below and the API can change between releases.
Requirements
- Claude Code 2.1.270 or later with
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1. - An interactive terminal session with a font that has box-drawing
characters (
/mermaid ascii onfor one that does not). Nothing draws inclaude -p.
Quick start
-
Turn function hooks on, in
~/.claude/settings.json:{ "env": { "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1" } }Or for one session:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude. -
Load the plugin from a clone (the repo's own
.claude/settings.jsonsets the variable for sessions started inside it):git clone https://github.com/galElmalah/claude-mods cd claude-mods claude --plugin-dir claude-mermaidOr install it from the repo's marketplace,
gal-mods:claude plugin marketplace add galElmalah/claude-mods claude plugin install mermaid-draw@gal-mods -
Ask Claude for a diagram. It is drawn in the reply.
Upgrading from claude-mermaid@claude-mods? Follow the
migration instructions.
Use
| command | what it does |
| --- | --- |
| /mermaid | shows the current settings |
| /mermaid ascii on\|off | plain +--| art instead of box-drawing glyphs (default off) |
| /mermaid color on\|off | borders cyan, arrows yellow, lines dim (default on) |
| /mermaid lr on\|off | lay top-down flowcharts and state diagrams out left to right when nothing is lost (default on) |
| /mermaid reset | the defaults again |
A setting redraws the diagrams already on screen. Settings are kept in the plugin's store across sessions.
How it works
hooks/register.tsis the hooks module. It hooksui.renderofAssistantMessage: with colour on, on the terminal, it returns a tree of its own (Markdownfor the prose, oneTextper diagram line, the colours as props on its spans), since a rewrittenprops.textmay carry no escape sequence from Claude Code 2.1.287 on; otherwise it swaps each closed mermaid fence for a text fence of plain art. It also hookscommand.runfor/mermaid.hooks/diagrams.tsis the pure part: finding fences, rendering, choosing the sideways layout (kept only when every word of the top-down render survives, since the renderer can overwrite the label of an edge that runs back the other way), fitting to a width, serializing.bun testcovers it.hooks/vendor/mermaid-ascii.jsis beautiful-mermaid's ASCII renderer bundled byscripts/build-vendor.mjs(hooks modules run with no Node and cannot import packages). The renderer only emits ANSI, so it is run in truecolor against a theme of sentinel colours and the escapes are decoded back into roles (border, line, arrow, text), then coloured for the terminal's own 16-colour palette so light and dark themes both read.- The bundle patches one thing: upstream's A* edge router searches an
unbounded grid, so a graph that fences an edge's target in ran for ~25 s
and died on
Map maximum size exceeded, which would burn the hook's whole budget. The vendored copy caps the search and falls back to a straight segment, so the same graph draws in ~60 ms. Rendered art is cached per source and glyph set; a hook settles in a few ms after the first draw.
Develop
npm install # esbuild, beautiful-mermaid, aimock, bun types
npm run build:vendor # rebuilds hooks/vendor/mermaid-ascii.js
npm test # unit tests of hooks/diagrams.ts
npm run test:plugin # render-hook tests in Claude Code's plugin test kit
npm run test:e2e # the plugin inside a real Claude Code (below)
npm run typecheck # against ../.claude/types (run /plugin-types first)
npm run validate # what the engine sees the module hook and call
Typechecking needs the declarations of your Claude Code build: open a
session in the repository root with function hooks on and run /plugin-types,
which writes the git-ignored .claude/types/.
The plugin test kit and Bun use different runtimes. test:plugin copies the
hooks and kit tests into a temporary plugin folder so Claude's runner does
not try to load the Bun tests. npm run test:all runs both suites and the
end-to-end tests with their respective runners.
End-to-end tests
tests/e2e drives a real interactive Claude Code in a tmux pane, its
replies scripted by aimock (an
Anthropic-API mock on a local port, ANTHROPIC_BASE_URL pointed at it), the
plugin loaded from the checkout with --plugin-dir. Each test sends a
prompt, waits for the screen to show a thing, and asserts on the captured
text, with -e where colour matters. It covers every drawn kind, colours,
two diagrams in one reply, an undrawn kind, the dense graph that used to
hang, a fence inside a list item, the sideways layout, every /mermaid form, and a terminal too
narrow for the art. Needs tmux and claude on PATH, and the checkout to
be a folder Claude Code trusts; skipped otherwise. About 10 s.
Edits to hooks/ hot-reload into a running --plugin-dir session. Start
Claude with --debug-file /tmp/mermaid.log to see what the engine refused.
Limits
- Kinds beautiful-mermaid does not draw (gantt, pie, mindmap, gitGraph, journey, timeline, quadrant, C4, …) keep their fence.
- Art wider than the transcript is cut at the right with
…and a line saying by how much; make the terminal wider. - Colours are drawn on the terminal alone; desktop, VS Code and mobile show
plain art. A reply whose prose between diagrams runs past 10000 characters
(one
Markdownelement's cap) is drawn plain too.
License
MIT.
