关于 mdnote
mdnote 是通过命令行处理 Markdown 文件批注的审阅流程技能,可应用未处理的批注、清除已处理项,并将失效批注交由人工复核。
主要功能
- 01从旁路文件读取批注
- 02等待审阅者提交
- 03按锚定文本应用意见
- 04清除已处理批注
- 05标记失效批注供复核
适用场景
- 01依据审阅意见修改 Markdown 文件
- 02收集确认后再继续处理
- 03找出编辑后失效的批注
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jlui17/ mdnote --skill mdnote安装后在 Claude Code 中输入/mdnote确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreCLAUDE.mdbun.lockpackage.jsonREADME.md.claude/settings.jsondocs/agents/issue-tracker.mddomain.mdsrc/actions.tsanchor.tscli.tsserver.tsregistry.tslock.tsconfig.tsrender.tstypes.tsstore.tsthemes.tstests/anchor-dom.test.tsactions.test.tshelp.test.tsconfig.test.tscolor-math.tsanchor.test.tsdepth.test.tshover.test.tslock.test.tsregistry.test.tsrender.test.ts详细介绍
mdnote 审阅流程
批注保存在文件旁的 sidecar 文件中(<file>.mdnote.json),通过浏览器 UI 创建。你无需打开浏览器,只使用 CLI。
即使服务器已关闭,comments 和 clear 也能正常工作:它们会回退到 sidecar 文件。mdnote 是安装在 ~/.bun/bin 中的 bun 脚本;如果非交互式 shell 找不到 mdnote 或 bun,请将 ~/.bun/bin 和 mise shims 目录(~/.local/share/mise/shims)添加到 PATH 前面。
1. 开始审阅(如果已在运行,则跳过)
如果用户还没有启动服务器(不确定时请询问),则启动服务器:
mdnote <file.md>
在后台或另一个终端中运行它——它会提供页面并打开浏览器,还会持续运行以支持实时重新加载。如果用户希望绑定到其他地址,可选用 --host/--port;本地使用默认值即可。
要将文件交给用户并阻塞等待其审阅,请用以下命令替代步骤 1–2:
mdnote wait <file.md>
它会为用户打开页面(页面中的提示栏会显示你正在等待),并阻塞直到用户点击 Submit,然后向 stdout 打印一个 JSON 信封:{path, submittedAt, annotations}。annotations 为空表示用户原样批准——继续后续操作。否则,带着信封中的批注继续步骤 3。请在前台运行,并做好等待几分钟的准备;没有超时设置。每条批注在首次送达时都会标记一个 round 编号,因此重复等待时,较早轮次的批注是你已经看过的(仍处于打开状态表示你从未清除它们)。
2. 获取批注
mdnote comments <file.md> --json
返回 {file, annotations}。每条批注包含:
lineRange:[start, end],源文件中从 1 开始、两端均包含的行号(文档级批注为null)anchorText:精确选中的文本(文档级批注为null)columnRange:[start, end],选中文本跨度中从 1 开始、两端均包含的列号:start位于lineRange[0]所在行,end位于lineRange[1]所在行textBefore、textAfter:跨度前后紧邻的最多 24 个源文件字符,取自跨度首行和末行(位于行首或行尾时为空)note:修改指示status:open|stale
只处理 status: "open" 的批注。
3. 应用每条批注
note 是针对锚定跨度的自由形式指示:“make this punchier”表示修改得更有力,“remove”表示删除,以此类推。anchorText 为 null 时,该批注适用于整篇文档——请在整个文件中应用。
使用 lineRange 跳转到对应位置;通过匹配 anchorText 确认找到正确的跨度(本轮此前的修改可能已导致行号偏移——请重新检查,不要依赖过时的行号)。
columnRange、textBefore 和 textAfter 会一并提供,且仅适用于文本选区;当某行中的 anchorText 出现多次时,它们会标明用户选择的是哪一处。源文本为 textBefore + <span> + textAfter,从 lineRange[0] 所在行开始。anchorText 是渲染后的文本,因此源文件中的跨度可能与之不同(例如其中包含 ** 或换行符);如果 anchorText 确实按原样出现在源文件中,请搜索 textBefore + anchorText + textAfter。如果未找到该字符串或匹配结果不唯一,请通过 columnRange 切分:单行跨度是 lineRange[0] 所在行中从 columnRange[0] - 1 开始、到 columnRange[1] 之前的字符,按 JS 字符串索引(UTF-16 代码单元)计数;较长的跨度从起始列一直延伸到 lineRange[1] 所在行的 columnRange[1] 列。如果这三个字段缺失,mdnote 无法区分多处匹配:请仅依据 lineRange 和 anchorText 判断;如果该行存在歧义,请询问用户。
4. 清除已处理的批注
mdnote clear <file.md> --ids <id>,<id>,...
用一次逗号分隔的调用传入你已处理的所有 id,或者完成后一次性全部清除:
mdnote clear <file.md>
页面会自动实时重新加载——无需操作。
5. 循环
重新运行 mdnote comments <file.md> --json。继续编辑和清除,直到不再返回任何 open 批注。
过时的批注(status: "stale",编辑后已找不到锚点文本)不应由你猜测如何处理——应将其告知用户,以便用户手动复查,而不是清除或重新解读。