md-preview:在侧边窗格中进行 Claude Code Markdown 预览
Claude 编辑的 Markdown 文件,以 GitHub 的样式渲染在对话旁的窗格中,并可查看修改前后的对比。
权限
- 读取文件可以读取你电脑上的文件并列出目录($.fs.read / list / stat / exists)。
- 写入文件可以在你的电脑上创建或覆盖文件($.fs.write)。
- 执行命令可以在你的电脑上运行 shell 程序($.process.run / spawn)。具体运行哪些程序请查看源码。
- 拦截工具调用能看到 Claude 发起的每一次工具调用(tool.call / tool.check),并可以阻止或修改它。
- 修改界面在 Claude Code 界面中绘制内容:横条、面板、状态文字、弹出通知(ui.render / $.ui.*)。
- 添加命令/工具注册新的斜杠命令或工具,供你或 Claude 调用($.command.register / $.tool.register)。
- 实测版本
- v2.1.291
- 最近实测
- 需要
- Claude Code ≥ 2.1.287
- 显示位置
- 面板、弹出通知
这个插件能做什么?
md-preview 是一款 Claude Code Markdown 预览社区插件,作者是 Hamza Zafar(hamzafer),属于他的 claude-code-mods 合集。它为 Claude Code 提供 Markdown 预览:当 Claude 写入或编辑 .md、.mdx 或 .markdown 文件时,会弹出提示 README.md changed · /md to preview,而 /md 会在对话旁打开一个窗格,按照 GitHub 的显示方式渲染该文件。
窗格中有 Prev、Next、Before、Render、Text、Browser 和 Close 按钮,每个按钮都有快捷键(p、n、b、r、t、o、q)。n 和 p 键可以在本次会话中改动过的 Markdown 文件之间切换。b 会把文件在本轮第一次编辑之前的样子和当前内容并排显示,最近一次编辑改动的区块会带有一条绿色竖条。/md compare <a> <b> 会把两个文件并排显示,o 或 /md open 会在你自己的浏览器中打开同一页面。
页面的绘制方式取决于你的环境。在支持图片的终端(Ghostty、iTerm2、WezTerm 或 kitty,不经过 tmux)中,并且安装了 Chrome 或某个 Chromium 浏览器时,页面会被绘制成 PNG 并显示在窗格中。否则,窗格会显示文本视图,用终端颜色呈现标题、列表、表格和代码块。清单文件中没有写明最低 Claude Code 版本。
演示
录屏中,我们在小型演示项目里启动加载了该插件的 Claude Code,并运行 /md README.md。命令会回复按键提示(n/p: next/previous · b: before | after · o: browser · r: render again · t: page/text · q: close),随后输入框上方打开一个带边框的窗格。第一行是按钮,第二行显示 README.md 1/1,下面以文本视图显示项目的 README:标题 demo-app 和一行 "A tiny demo app. Run it with npm start.",其中的代码片段带有颜色。演示所用的终端无法显示图片,因此显示的是文本视图,而不是渲染后的页面。
安装
使用安装区块中的任意一种方式;它们都直接从作者自己的插件市场安装。安装后运行 /reload-plugins 或开启新会话,然后使用 /md。
$ install md-preview
需要 Claude Code ≥ 2.1.287
从作者自己的 marketplace 安装: hamzafer/claude-code-mods
1.在 Claude Code 中一行安装
/plugin install md-preview --marketplace hamzafer/claude-code-mods粘贴到正在运行的会话中(v2.1.275+)。Claude Code 会先询问是否添加该插件市场。
2.从终端安装
claude plugin marketplace add hamzafer/claude-code-mods claude plugin install md-preview@claude-code-mods然后在所有已打开的会话中运行 /reload-plugins。
3.免安装试用
git clone https://github.com/hamzafer/claude-code-mods claude --plugin-dir ./claude-code-mods/mods/md-preview仅在当前会话中加载该插件,不会写入你的设置。
工作原理
插件由一个函数钩子模块 hooks/register.tsx,加上一个小型 Markdown 解析器(hooks/md.ts)和一个 HTML 页面生成器(hooks/page.ts)组成。tool.call 钩子会在对 Markdown 路径执行 Write、Edit 或 MultiEdit 调用之前读取该文件,然后让调用照常执行,并原样返回结果。以下是 GitHub 渲染器,来自 hooks/register.tsx:
const repo = await repoOf($, dir)
if (!repo) return null // not in a GitHub repo: the Markdown stays on this machine
const r = await $.process
.run(['gh', 'api', '-X', 'POST', '/markdown', '--input', '-'], { stdin: JSON.stringify({ text: md, mode: 'markdown', context: repo }), timeoutMs: GH_TIMEOUT_MS })
.catch(() => null)repoOf 通过 git remote -v 查找 GitHub remote。如果 gh 失败,GitHub 渲染会暂停一分钟,期间使用内置渲染器。HTML 会写入 $TMPDIR/md-preview/,并通过一个简短的 sh 脚本用无头 Chrome 绘制,每次只绘制一个,绘制结果按内容缓存。Claude 编辑过的文件会在这一轮结束后于后台绘制,所以 /md 打开时通常页面已经绘制好了。
自定义
/config 中没有任何选项。所有操作都通过命令和窗格按键完成:/md 打开最近的文件,/md <path> 打开任意 Markdown 文件,/md compare <a> <b> 对比两个文件,/md open 在浏览器中打开。如果 /md 这个名字已被其他命令占用,插件会改为注册 /mdview。若要修改 Chrome 路径列表(CHROMES)、保留的文件数(MAX_FILES)或缓存大小(CACHE_SIZE)等限制,请编辑 register.tsx 顶部的常量。
权限与安全
在运行之前,我们读过了插件可以执行的每一个文件:plugin.json、hooks/hooks.json、hooks/register.tsx、hooks/md.ts、hooks/page.ts、类型声明以及测试。没有 package.json、安装脚本、二进制文件或打包后的代码,我们也没有发现隐藏字符或零宽字符。
- **网络:**没有直接请求。存在 GitHub remote 且
gh已登录时,Markdown 文本会通过gh api发送到 GitHub 的/markdownAPI(register.tsx:592-594),无需额外选择启用。大于约 390 KB 的文件在本地渲染。渲染后的页面由无头 Chrome 加载,其 Content-Security-Policy 允许加载任意主机的图片(page.ts:97),因此 Markdown 文件中的远程图片会在绘制页面时被获取。Markdown 中的脚本无法运行。 - 进程:
git ls-files和git remote -v(register.tsx:386、607),gh api(593),带固定脚本的sh -c,用于启动无头 Chrome,并且只停止它自己启动的 Chrome(49-67、675),以及浏览器按钮使用的open或xdg-open(788)。 - **文件写入:**只写入
$TMPDIR/md-preview/(页面 HTML、PNG 分块和一次性 Chrome 配置文件)。不会写入~/.claude、设置、shell 配置文件、LaunchAgents 或 git 钩子。 - **文件读取:**Claude 编辑的 Markdown 文件、你指定的文件,以及在一轮对话的第一条 shell 命令之前,通过
git ls-files读取仓库中最多 200 个 Markdown 文件。 - 环境变量:
HOME、TMPDIR、TMUX、TERM_PROGRAM和TERM。它们不会被发送到任何地方。 - **守护进程、遥测、提示词注入:**都没有。它不会向提示词或工具结果中添加任何文本。
- 拦截:
tool.call钩子只是观察者。它等待调用完成并原样返回结果。validate把它标记为没有.catch的拦截钩子;一轮对话的第一次 shell 调用会等待 Markdown 快照完成,而快照只读取文件。 - **外部依赖:**渲染视图需要 Chrome、Chromium、Edge 或 Brave,以及支持图片的终端,
gh可选。这些都是可选的;退而求其次会使用文本视图。 - **许可证:**MIT,仓库根目录有 LICENSE 文件。
claude plugin validate 没有报告任何错误或警告,作者的 26 个测试在 Claude Code 2.1.291 上全部通过。
- 读取文件
- 可以读取你电脑上的文件并列出目录($.fs.read / list / stat / exists)。
- 写入文件
- 可以在你的电脑上创建或覆盖文件($.fs.write)。
- 执行命令
- 可以在你的电脑上运行 shell 程序($.process.run / spawn)。具体运行哪些程序请查看源码。
- 拦截工具调用
- 能看到 Claude 发起的每一次工具调用(tool.call / tool.check),并可以阻止或修改它。
- 修改界面
- 在 Claude Code 界面中绘制内容:横条、面板、状态文字、弹出通知(ui.render / $.ui.*)。
- 添加命令/工具
- 注册新的斜杠命令或工具,供你或 Claude 调用($.command.register / $.tool.register)。
兼容性与故障排除
已在 macOS 上使用 Claude Code 2.1.291 检查(validate、测试和录屏)。如果窗格的表现不符合预期:
- 提示
/md未知:检查/plugin是否显示 md-preview 已加载,或者试试/mdview。 - 看到的是文本而不是页面:你的终端无法显示图片、你在 tmux 中,或者没有找到 Chrome。解决后按
r,或按t切换视图。 - "Chrome could not draw the page":按
r重试。插件不会自动重试。 - 文件改动后没有弹出提示:只跟踪 Markdown 路径,并且只有在 git 仓库中才能察觉 shell 写入。
- 窗格显示
built-in而不是GitHub:文件不在 GitHub 仓库中、gh未登录,或者文件大于约 390 KB。
常见问题
- md-preview 会把我的 Markdown 发送到别处吗?
- 只有一种情况会。当文件所在文件夹的 git remote 位于 GitHub,并且 GitHub CLI(gh)已登录时,插件会通过你的 gh 把 Markdown 文本发送到 GitHub 的 /markdown API 进行渲染。不在 GitHub 仓库中,或者 gh 调用失败时,会使用内置渲染器,插件自身的代码不会让任何内容离开你的电脑。
- 我需要安装 Chrome 吗?
- 只有渲染后的页面视图需要。插件会在固定路径查找 Google Chrome、Chromium、Edge 或 Brave,并以无头模式、使用独立的一次性配置文件运行它,把页面绘制成 PNG。没有浏览器,或者终端无法显示图片时,它会改为显示文本视图。
- 怎样预览 Claude 没有编辑过的文件?
- 运行 /md 并加上路径,例如 /md docs/guide.md。文件必须以 .md、.mdx 或 .markdown 结尾。/md compare a.md b.md 会把两个文件并排显示,/md open 会在你的浏览器中打开页面。
- 它能察觉到由 shell 命令写入的 Markdown 吗?
- 能,前提是在 git 仓库中。在一轮对话的第一次 Bash 或 PowerShell 调用之前,它会为仓库中的 Markdown 文件(最多 200 个)做快照,并在这一轮结束时进行比较,所以像 cat > README.md 这样的修改同样会弹出提示。
- 为什么演示中显示的是文本视图?
- 演示所用的终端无法显示图片,所以插件退回到文本视图。在支持图片的终端中,例如 Ghostty、iTerm2、WezTerm 或 kitty(不经过 tmux),它会显示渲染后的页面。
# 相关插件
精选Context Bar
在 Claude Code 输入框上方用一条堆叠横条显示上下文窗口,每个类别一种颜色,并附带 token 数。
- 输入框上方
- 修改界面
- 添加命令/工具
- 存储数据
已在 v2.1.291 实测
精选工具调用计数器
统计 Claude 每轮和每个会话的工具调用次数,在加载指示器旁显示计数,并新增 /tally 查看明细。
- 加载动画
- 对话记录
- 状态栏
- 拦截工具调用
- 修改界面
- 添加命令/工具
已在 v2.1.310 实测