dsh-mindmap
DeepSeek Harness 的思维导图插件。在会话右侧抽屉里打开,用树形大纲记想法,存到 Host 上,一键转成 Markdown。
它能做什么
- 右侧抽屉里打开:右侧栏首页点「思维导图」卡片,导图和对话并排,不占主区域
- 键盘化编辑:
Tab加子节点、Enter加同级、Alt+←→调层级、方向键在树上游走——手不离主键位区 - 自由拖动:节点可拖到任意位置并持久化,也能一键「重新排版」回自动布局
- 节点配图:粘贴或把文件拖进画布就给节点加图;文字留空就是纯图片节点
- 右侧 Markdown 栏:可收起,两边都能改——画布上改实时同步过去,改 Markdown 点「应用修改」合并回画布(节点图片与位置保留)
- 两种 Markdown 图片输出:默认相对路径 + 单独导出图片包,也可一键内嵌成单文件
- 自动保存:防抖 0.6 秒 + 离开页面前强制落盘 + 失败自动重试,状态常驻可见
- 选中即输入:选中节点后直接打字就改内容,不用双击
- 节点标识:⭐ 重点 / ⚠️ 易错 / ❓ 疑问 等,标记重难点
- 多主题:一张画布上并列多个中心主题
- 连线:点线即选中;双击写说明;线型 / 粗细 / 颜色可单独设;拖线两端可把节点改挂到别的节点下
- 复制节点:
Cmd/Ctrl+D连子树一起复制 - 框选批量操作:空白处拖出选框圈住多个节点,可整体拖动、批量改样式
- 画布缩放:25%–300%,
−/+/ 点百分比复位,支持Cmd/Ctrl+滚轮 - 撤销 / 重做:改错了
Cmd/Ctrl+Z就回去,深 100 步 - 节点属性:配色、字号、加粗/斜体、圆角、边框,可一键应用到整支
- 属性面板是显式开关:工具栏点「属性」才展开,选中节点/连线不会自动弹面板(面板开着时内容跟着选中走,连线属性与节点属性共用同一个抽屉)
- 保存到磁盘:存在
~/.dsh/storages/dsh-mindmap.json,刷新换浏览器重启都不会丢 - 两种 Markdown 形态:
- 标题形态(每层一个
#,超过 6 层自动降级成列表)→ 当文章骨架 - 列表形态(整棵树是嵌套无序列表)→ 贴进大纲工具、喂给模型
- 标题形态(每层一个
- 复制 / 下载
.md/ 实时预览 - 命令行:不开网页也能导出
装
前提:Node ≥ 20,dsh 在 PATH 里。下面命令里的 web 是 profile 名——装到自己平时
用的那个 profile(内置的是 web,自定义的通常在 ~/.dsh/profiles/ 下)。
从 GitHub 装
dsh plugin --profile web add git+https://github.com/stzyk/dsh-mindmap.git
lib/ 不进仓库(构建产物),所以这个包带了一个 prepare 脚本,安装时现场编译。
pnpm 默认拦截来自 git 的构建脚本,第一次装会失败并打印类似这样的一行:
allowBuilds:
dsh-mindmap@git+https://github.com/stzyk/dsh-mindmap.git#<commit>: true
把那一行原样加到 $DSH_HOME/profiles/web/pnpm-workspace.yaml(没有这个文件就新建,
只写 allowBuilds 这一段也可以),然后重跑上面的 add。
从本地目录装(改代码时用这个)
git clone https://github.com/stzyk/dsh-mindmap.git
cd dsh-mindmap
npm install && npm run bundle # link: 不会替你构建,先产出 lib/
dsh plugin --profile web add link:$PWD # 用绝对路径
link: 装的是指向源码目录的软链,之后改源码只要 npm run bundle 再刷新页面即可。
装完要重启
dsh web # profile 就叫 web
dsh --profile desktop-web web # 其它 profile(换成你的名字)
lib/index.js(Node 半区)的改动只有重启才生效;只改客户端 lib/client.js
刷新页面就够了。
确认装上了
dsh --profile web --dump-config | grep -A1 mindmap
能看到 - id: dsh-mindmap 就说明 bundle 已经进装配树(dsh plugin add 会自动把它
追加到 profile 的 dsh.profile.bundles 里,不需要手改)。界面上则去会话右侧栏
首页,能看到「思维导图」卡片。
卸载
dsh plugin --profile web remove dsh-mindmap
依赖和 dsh.profile.bundles 里的登记会一起清掉(数据文件保留在
~/.dsh/storages/ 下,要彻底清干净就自己删)。
用
右侧栏首页点「思维导图」卡片 → 填标题 → 新建 → 开始画。要改外观时先选中节点或连线,再点工具栏的「属性」。
| 按键 | 动作 |
|---|---|
Tab |
加子节点(进入编辑,打完字回车继续) |
Enter |
在选中节点后加一个同级节点,并进入编辑 |
Shift+Tab |
减少一级缩进 |
Alt+→ / ← |
增加 / 减少缩进 |
Alt+↑ / ↓ |
在兄弟之间上移 / 下移 |
↑ ↓ ← → |
在树上移动光标(← 到父节点,→ 进第一个子节点) |
空格 或 F2 |
编辑选中节点的文字(保留原内容,光标在末尾) |
Backspace / Delete |
删除选中节点(中心主题不可删) |
Esc |
退出编辑 / 取消选中 |
Cmd/Ctrl+Z |
撤销 |
Cmd/Ctrl+Shift+Z |
重做(Ctrl+Y 也行) |
| 双击节点 | 直接编辑 |
画布上方是一条常驻操作条:搜索 / ↶ 撤销 / ↷ 重做 / 重新排版 / 缩放(− 100% +)/ 居中。
自动保存
改动后 0.6 秒自动写入;关闭标签页、刷新、切走之前会强制落盘,不等防抖。 保存失败会按 2/5/10/30 秒自动重试,工具栏右上角常驻显示状态:
| 状态 | 含义 |
|---|---|
| 未保存 | 有改动,等待写入 |
| 保存中… | 正在写磁盘 |
| 已保存 | 已落盘(悬停看时间) |
| 保存失败 | 点击手动重试,后台也会自动重试 |
编辑节点文字
双击(或选中后直接打字)进入编辑,编辑框会自动加宽加高,长文本可以通读:
| 按键 | 作用 |
|---|---|
Enter |
只确认内容(不会顺手加节点) |
Tab |
确认并保持当前节点 |
Esc |
放弃这次修改 |
Shift+Enter |
换行(节点文字仍是单行,换行会折成空格) |
长文本在画布上显示不全时,鼠标停上去会浮出完整内容(只在真的被截断时才弹)。
改文字:三种进入方式
| 想干的事 | 怎么做 | 结果 |
|---|---|---|
| 改几个字 | 按 空格 或 F2 |
打开编辑框,原内容保留,光标在末尾 |
| 整段重写 | 选中后直接打字 | 首字符顶替原内容 |
| 光标放到末尾再改 | 双击节点 | 同空格 |
Tab / Enter / 方向键 / Delete / 撤销等快捷键不受影响。
搜索定位
Cmd/Ctrl+F 打开搜索框,输入关键词即可:
- 所有匹配的节点套一圈浅色高亮,当前那一个套深色环
- 计数显示「第几个 / 共几个」
Enter下一个,Shift+Enter上一个,循环跳转Esc关闭并清掉高亮
只搜节点正文(备注不进画布,搜到了也看不见,所以不搜)。
视口记忆
关掉再打开同一份导图,会回到上次看的位置和缩放,不用每次重新挪画布。
记录存在浏览器本地(localStorage),不写进文档——所以滚动不会触发自动保存,
也不会出现在别人的机器上。
主题 / 子节点
属性面板里有「种类」一行,可以在主题和子节点之间切换:
- 主题:顶层的中心主题(一张画布可以有多个)
- 子节点:挂在某个节点下面的普通节点
断开连线(选中连线后点中间的 ×)时,节点会升到第 1 级——它不再属于任何上级,
于是变成多主题里的一个主题,样式和整棵子树都保留。
节点标识
给节点打图标记号,复习时一眼扫出重难点。属性面板最上面一排,点一下加上、再点取消。
| 标识 | 含义 |
|---|---|
| ⭐ | 重点 |
| 🔥 | 高频考点 |
| ⚠️ | 容易出错 |
| ❓ | 还没搞懂 |
| 💡 | 想法 / 延伸 |
| ⏰ | 待补充 |
| ✅ | 已掌握 |
| 🚩 | 关键结论 |
一个节点最多 4 个。标识会存进数据,刷新、导出都在。
节点属性面板
选中节点后,右侧面板显示的是这个节点当前实际生效的外观,而不只是你手动改过的项:
- 对应档位会高亮(没设置过的也会按默认值高亮)
- 没手动设置过的项旁标「默认」
- 生效值不在预设档位里时标出实际数值,例如「当前 13.5」(根节点默认字号)
所以打开面板就能看出"这个节点现在到底长什么样",不用猜。
多主题
在画布空白处双击就能加一个并列的中心主题,新主题出现在双击的位置。 第一次这么做会把当前导图升级成多主题——原来的中心主题变成第一个主题。
- 多个主题纵向排开,各自独立成树
- 每个主题照常加子节点、改样式、连线
- 导出 Markdown 时每个主题各成一个
#一级标题 - 已有导图不需要迁移,没加过主题的仍是单主题
注意:多主题导图暂不支持从 Markdown 反向修改(会明确拒绝并提示), 单主题不受影响。
关系线(自由连线)
除了层级连线,还可以在任意两个节点之间画关系线:
- 选中一个节点,它右侧边缘中间会出现一个连接点
- 把连接点拖到另一个节点上松手(连接点统一在方框的左右两端,不在上下)
- 一个节点可以连出任意多条关系线
- 默认实线;线型(实线 / 虚线)、粗细、颜色都能在「连线属性」里单独改
- 关系线不改变树结构,不影响 Markdown 大纲
- 点关系线可以选中、双击写文字、点
×删除
如果连线的一端还是 1 级节点,连线会自动把它挂到另一端下面(变成普通的上下级), 不再保留这条关系线——层级已经用树结构表达了。
连线
层级连线在结构上不是独立数据:它由父子关系推导出来。但线型、粗细、颜色、文字 是这条线自己的属性,选中线就能单独调。改端点等于改父子关系。
点一下线即可选中它(不用先选节点)。选中后:
| 操作 | 效果 |
|---|---|
| 拖线的左端(父端) | 把这个节点改挂到别的节点下(子树一起走) |
| 拖线的右端(子端) | 改这条线连到谁(1→2 拖到 3 就变成 1→3) |
| 直接拖线身 | 等于拖右端(改它连到谁) |
| 点线上方的 × | 断开这条连线(节点升到 1 级,见上) |
| 双击连线 | 给这条线加文字说明(回车确认,Esc 取消,上限 120 字) |
| 点工具栏「属性」 | 打开「连线属性」:线型(实线 / 虚线)、粗细(1/2/3)、颜色 |
端点不画圆圈(只为画面干净),但线两端仍然可以拖——把鼠标放在线头附近会出现抓取光标。
限制:不能挂到自己的子孙上(会成环);根节点没有上级连线,不能改。
连线文字跟着节点走——节点改挂到别处,说明也跟着过去。
注意:连线文字目前不导出到 Markdown(避免和节点正文混淆)。
加节点 / 加图片怎么操作
工具条上没有「加子节点 / 加同级 / 加图片」这些按钮——它们都有更顺手的入口:
| 要做的 | 怎么做 |
|---|---|
| 加子节点 | 选中后按 Tab |
| 加同级 | 选中后按 Enter |
| 加主题 | 双击画布空白处(在双击位置新建) |
| 加图片 | 直接粘贴图片,或把文件拖进画布 |
| 删图片 | 鼠标移到图片上,点右上角 × |
| 复制节点 | Cmd/Ctrl+D |
工具条只保留撤销 / 重做 / 重新排版 / 缩放。
复制节点
选中节点按 Cmd/Ctrl+D,连同所有子节点一起复制,
副本插入在原节点之后并自动选中。
- 子树里每个节点都会获得新 id(不会出现两个节点共享身份)
- 图片与配色等属性一并保留,图片共用同一份资源文件
- 手动摆放过的节点,副本会偏移一点,避免完全重叠
- 根节点没有同级,不能复制
- 可以撤销
多选与批量
| 操作 | 效果 |
|---|---|
| 空白处拖动 | 拉出虚线框,框住的节点全部选中 |
Shift / Cmd / Ctrl + 点击 |
加选或减选 |
| 拖动任一选中节点 | 整组一起移动(相对位置不变) |
| 右侧属性抽屉 | 点工具栏「属性」打开后自动切成批量模式,改什么作用于全部选中 |
框选时按 Shift 可以追加到已有选中。点空白处取消选中。
缩放
操作条右侧:− / 125% / +,点百分比回到 100%。
| 操作 | 效果 |
|---|---|
点 + / − |
按档位缩放(25 / 33 / 50 / 67 / 75 / 100 / 125 / 150 / 200 / 250 / 300 %) |
| 点百分比 | 复位 100% |
Cmd/Ctrl + = / − |
放大 / 缩小 |
Cmd/Ctrl + 0 |
复位 |
Cmd/Ctrl + 滚轮 |
以鼠标位置为锚缩放 |
| 按住右键 / 中键拖动 | 整体平移画布(也可以直接拖滚动条) |
| 点「居中」 | 把内容挪回视野中央(对准根节点;拖远了找不回来时用) |
| Cmd/Ctrl + F | 搜索节点内容,Enter / Shift+Enter 在匹配间跳 |
缩放状态下拖动节点仍然跟手(位移按比例换算)。
画布四周留了很大一片虚拟空白,所以:
- 滚动条一直可用,能滚到内容之外很远(不会"卡死在内容边缘");
- 右键 / 中键拖动可以整体平移;
- 拖远了看不见内容时,点工具栏的**「居中」**一键回到内容。
平移时画布上的浏览器右键菜单会被屏蔽,中键也不会触发浏览器的自动滚动。
节点外观
属性面板是显式开关:先选中节点或连线,再点工具栏「属性」,画布右侧浮出抽屉 (浮在画布之上,不压缩画布宽度;点 × 收起,收起后选中状态保留)。开着的时候 选中谁就显示谁,什么都没选时显示一句提示。选中远处的节点会自动滚进视野,不会躲在抽屉后面:
| 属性 | 可选值 |
|---|---|
| 配色 | 11 组预设色板(海蓝 / 青碧 / 草绿 / 琥珀 / 落日 / 砖红 / 藕粉 / 雾紫 / 石板 / 石灰 / 墨黑) |
| 字号 | 11 / 13 / 16 / 20 px |
| 字形 | 加粗、斜体 |
| 圆角 | 0 / 4 / 8 / 14 px |
| 边框 | 无 / 1 / 2 / 3 px |
- 勾「含子节点」把设置应用到该节点及其所有子孙
- 「恢复默认」清空整支的自定义外观
- 配色是背景 + 文字成对的,保证文字永远看得清(不用自己配前景色)
撤销
改错了按 Cmd/Ctrl+Z,工具栏也有 ↶ 撤销 / ↷ 重做 按钮(不可用时是灰的)。
- 覆盖:节点增删改、缩进、折叠、拖动位置、加删图片
- 不覆盖:改文档标题、删除整份导图
- 深度 100 步,只作用于当前文档;切换文档或刷新页面后历史清空
给节点加图片
三种方式,任选:
| 方式 | 操作 |
|---|---|
| 粘贴 | 复制一张图,在面板里 Ctrl/Cmd+V |
| 拖入 | 把图片文件拖到画布上,松手即加 |
- 图片按原始比例等比缩放到节点内,不裁剪
- 文字留空 + 有图片 = 纯图片节点,画布上只显示图
- 一个节点可放多张(上限 24 张)
- 图片可管理:悬停每张图有「改说明 / 替换 / 删除」
- 双击图片看大图(遮罩 + 缩放,Esc 或点背景关闭)
- 支持 PNG / JPEG / GIF / WebP,单张上限 8MB(不支持 SVG——它可含脚本)
用 Markdown 改导图
点工具栏「Markdown」在右侧展开一栏(可随时收起,画布一直都在)。
- 画布改 → 侧栏跟着变:加节点、改文字、拖动都会立刻反映
- 侧栏改 → 画布跟着变:改完点底部的「应用修改」
- 只支持标题(
#)、嵌套列表(-)、引用块(备注)、图片行 - 合并时会保留节点上的图片、拖动位置与折叠状态——改几个字不会丢图
直接编辑 Markdown 时若画布那边也改了,未应用的修改会被丢弃并提示。
图片导出
导出的 Markdown 里,图片有两种写法:
| 模式 | 输出 | 适合 |
|---|---|---|
| 默认(相对路径) |  |
放进仓库;配合「导出图片」按钮下图片包 |
| 勾选「内嵌图片」 | data:image/png;base64,... |
单文件分享,图多时文件会变大 |
图片文件存在 ~/.dsh/storages/dsh-mindmap-assets/。删文档时会清理它独占的图片,
启动时也会对账一次孤儿文件,不会只涨不跌。
鼠标拖动
节点可以直接拖到画布任意位置,位置会保存,刷新后还在。
- 拖动只改「画在哪」,不改「挂在哪」——导出的 Markdown 层级结构不受影响
- 拖过的节点左侧有一道短竖线标记
- 想回到整齐的自动布局,点「重新排版」
- 拖动距离小于 3px 算点击,不会误把节点锁成手动位置
点工具栏「Markdown」展开右侧栏 → 选形态(标题 / 列表)→ 复制或下载 .md。
命令行
/mindmap list 列出全部导图
/mindmap show <id> 用大纲看结构
/mindmap markdown <id> [headings|list] 导出 Markdown
/mindmap new <标题> 新建一份
/mindmap rm <id> 删除一份
命令和按钮调用的是同一个转换实现,导出结果逐字节一致。
数据在哪
~/.dsh/storages/dsh-mindmap.json(跟随 DSH_HOME)。
- 原子写:先写临时文件再 rename,不会读到半截 JSON
- 串行队列:并发保存不互相覆盖
- 坏文件自愈:解析失败时备份成
*.corrupt-<时间戳>,从空列表继续——插件不会因为一份坏数据让宿主起不来
上限:单文档 5000 节点、总共 200 份文档。超限会明确报错。
开发
npm install
npm run bundle # src/ → lib/(esbuild)
npm test # 271 项单测(核心逻辑 / 存储 / 撤销 / Markdown / 样式 / 模型工具)
npm run gates # 41 项合同一致性门禁
# 浏览器冒烟(隔离实例跑在 3099,独立 DSH_HOME,不碰 3080 的真实数据)
bash verify/start-isolated.sh --bg
python3 verify/smoke.py "$(grep -oE 'http://[^ ]*token=[A-Za-z0-9_-]+' verify/dsh-web-3099.log | head -1)"
bash verify/stop-web.sh
结构:
src/core/ 两半共用纯函数(树操作 / Markdown / 布局),有单测
src/index.ts Host:RPC + /mindmap 命令 + 存储
src/store.ts Host:文档 JSON 原子写
src/assets.ts Host:图片字节存储(魔数校验、尺寸探测、孤儿清理)
src/client/ 浏览器:画布 / 图片 / 灯箱 / 撤销栈 / 属性面板 / 列表 / Markdown 栏
src/core/ 是刻意做成不碰 DOM 也不碰 Node 的——它同时被打进两个产物,保证 Host 导出的和浏览器看到的永远是同一套转换规则。
让对话直接读写导图(模型工具)
插件会向会话注册 4 个工具,模型可以自己看结构、建图、改图:
| 工具 | 作用 |
|---|---|
mindmap_list |
列出所有导图(doc- 开头的 id / 标题 / 节点数) |
mindmap_read |
读结构,每行末尾带节点 id(模型靠它精确定位) |
mindmap_create |
用 Markdown 大纲建新图;# 标题 那行就是中心主题,不会再套一层 |
mindmap_update |
增量改:add / update / remove / move / reparent |
mindmap_update 的几个约定:
id是导图 id(doc-开头),不是节点 id(n开头)——传错了会直接告诉你;- 一次调用可以放多个 op,按顺序执行;任一 op 失败则整批不生效(不会留下半成品);
add可以用as起一个本批次内的临时名字,后面的 op 直接引用它 (新节点 id 是随机的,调用前不可能知道,否则"加完再挂到别处"只能拆成两次调用);- 返回里会列出新建节点的 id,接着改它们不用再
mindmap_read一次。
想在对话里关掉这些工具,在插件配置里写 tools: false。
边界
拖节点本身只改位置、不改层级(调层级用 Shift+Tab / Alt+←→ / Alt+↑↓,
或拖连线的端点)、
节点外观只支持预设档位(不提供自由取色器,以保证文字可读性)、
不做协作与版本历史、节点文字是纯文本单行。
撤销只覆盖文档内编辑,不含改名与删文档;历史不跨文档、不跨刷新。
鼠标移到任意一张图片上,右上角会出现三个小按钮:
| 按钮 | 作用 |
|---|---|
T |
改这张图的说明(会写进 Markdown 的图片 alt) |
↻ |
换一张图(原地替换,顺序和其它图不受影响) |
× |
删除这一张 |
图片不做裁剪/旋转编辑,只按比例缩放显示(找不到原图时显示"图片丢失"占位);不收 SVG。
License
MIT
No comments yet. Be the first to write one.