前言¶
用 DeepSeek Harness Web GUI 跑对话时,遇到一段想追问的模型输出,常规做法是复制那段文字、新开一个会话粘贴再继续问。上下文长的时候,复制会丢位置信息,新开的会话也不带原会话的上下文。dsh-plugin-selection-comments 解决这个问题:在 Web GUI 里直接选中模型输出的文字,浮出评论框写下批注,或用「更多详情」打开一个脱离主会话的独立悬浮窗口接着聊。
下面介绍这个插件。它是 AaronOhO 维护的标准 DSH bundle,托管在社区目录上,分类为客户端插件,当前星标为 0,版本 0.1.0,许可证 MIT。
定位:两个表面¶
插件做两件事,都发生在浏览器侧:
- 选中 assistant 输出的文字,浮出快捷操作栏,可以把这段文字连同你的评论「添加到对话」,或点「更多详情」打开独立会话窗口。
- 独立会话窗口是当前会话最近一个已完成轮次的 fork,上下文完整,但不改动主会话,也不出现在侧边栏。
插件不注入 iframe、不替换应用根节点,所有 UI 通过 Harness 的 Slot(shell.overlay、conversation.input.dock)注册,由 React 渲染。它不需要 Host 端配置,也不改动模型或 API 设置。
核心功能¶
1. 划词评论(Selection comments)¶
选中模型输出里的任意文字,会上浮一个快捷操作栏,提供「添加到对话」和「更多详情」两个动作。
点「添加到对话」会在选区旁浮出评论框,引用所选文字,评论内容可写可不写,Cmd/Ctrl + Enter 或发送按钮确认。确认后:
- 所选文字被持久高亮为蓝色,范围末尾出现带编号的橙色标记;
- 输入框上方出现
N 条注释胶囊按钮; - 点胶囊打开可滚动的悬浮注释列表,每条显示编号、所选文本、用户评论,支持编辑和删除;
- 胶囊上的
×一次删除本会话全部注释。
注释保存在浏览器 localStorage(dsh-selection-comments:v1:*),按会话隔离,刷新页面后高亮、编号、胶囊都会恢复。
2. 注释随消息发送¶
发送用户下一条消息时,插件会把「所选文本 + 用户评论」作为引用块放进该条消息,会话里可见。发送成功后注释自动清空,高亮、编号、胶囊一起消失,文字已经进入对话历史,属于持久的对话内容。
如果输入框为空但有注释,右侧的发送箭头会恢复为正常的蓝色可点击样式(宿主原本会把它禁用成半透明)。此时点箭头、点「发送注释」、或直接按 Enter,都能把注释作为单独一条消息发出。
发送失败时注释保持 pending,下一次尝试会再次带上它们。
3. 独立会话窗口(更多详情)¶
选中文字后点「更多详情」,打开一个悬浮窗口,标题就叫「更多详情」。
窗口里的会话是当前会话在最近一个已完成轮次上的 fork:上下文完整,但和主会话完全独立,主会话不会被改动。窗口有自己的输入框与发送/停止按钮,支持拖动标题栏移动、拖动右下角缩放、收起/展开、关闭。
这个独立会话不会出现在侧边栏——插件按会话 id 隐藏其侧边栏行([data-row-key="session:<id>"]),并记住隐藏列表。用同一段选中的文字再次点「更多详情」会复用同一个独立会话,不会重复 fork。
窗口几何只记在当前页面,不跨刷新保留。
4. 实现方式¶
插件分成 Host 半边和 Client 半边:
| 部分 | 文件 | 作用 |
|---|---|---|
| Host half | index.js |
Inert loader row,所有行为都在浏览器侧 |
| Bundle patch | cordis.patch.yml |
插入 selection-comments row |
| Client module | client.js |
构建出的浏览器 bundle,由 window.__ModuleLoader__.load 加载 |
| 源码模块 | src/*.js |
Store、持久化、锚点、CSS 高亮、评论表面、侧聊窗口、Slot 注册 |
| 共享契约 | docs/CONTRACT.md |
状态结构、data/action API、接入点、验证清单 |
高亮用的是 CSS Custom Highlight API(::highlight(...)),React 重渲染不会抹掉它。选区通过精确引用文字、行锚点 key(data-chat-anchor-key)、文本偏移和上下文捕获,流式输出稳定或历史重载后,范围会按引用文字和上下文重新定位。只有 assistant 输出行可以被选中。
独立窗口通过共享的 conversation.content Factory 和 SessionProvider 挂一个真实的 Conversation 实例,直接复用宿主的聊天和输入框。
5. 已知限制¶
- 注释标记在发送前是浏览器本地的,不跨设备或 Harness 实例同步;清除站点数据会删掉它们。发送之后,那段文字就像普通的用户消息一样留在会话里。
- 侧聊会话是本地会话 store 里的真实 fork 会话,插件只是隐藏了它们的侧边栏行。清除浏览器数据后,之前创建的侧聊会话会重新出现在侧边栏里,它们本来就是普通会话。
- 同一时间只支持一个侧聊窗口。
- 窗口收起时会折叠会话正文,因此收起前未发送的侧聊输入框草稿不保留。
安装与启用¶
插件是标准 DSH bundle(dsh.bundle.patch + dsh.client),engines.dsh 要求 ^0.2.1-alpha.2。三种安装方式:
# 从工作区 checkout 安装
dsh plugin --profile desktop add link:/absolute/path/to/dsh-plugin-selection-comments
# 或按包名安装
dsh plugin --profile desktop add dsh-plugin-selection-comments
直接从 GitHub 安装:
dsh plugin --profile desktop add AaronOhO/dsh-plugin-selection-comments
也可以在 Harness 插件管理器里,从「设置 → 插件 → 添加插件」选择本目录安装 bundle。启用「划词评论与独立会话」这一行,然后刷新一次页面,让 Client bundle 加载进来。
装进 Desktop 应用的 desktop profile(对应插件管理器的本地目录安装):
node scripts/install-desktop.mjs # 默认 ~/.dsh/profiles/desktop
# 然后重启 DeepSeek Harness,让 profile bundle layers 重新组合
这个脚本会在自身旁边备份 package.json,只追加链接的依赖和 bundle 选择。删除其中一项,或重启后在插件管理器里关掉 bundle,就能卸载插件。
卸载后两个浮层和侧边栏隐藏规则都会消失;注释本身留在浏览器存储里,除非手动清除。
典型用法:验证¶
插件自带一套独立的端到端验证报告(43/43 项检查,覆盖浅色、深色、刷新后持久化),见 docs/verification/REPORT.md 和机器可读的 docs/verification/report.json。
自动化验证用打包的隔离 Harness 运行时加 Playwright:
node build.mjs
node scripts/e2e.mjs http://127.0.0.1:12447 "<token>" .devhome-verifier/shots
scripts/e2e.mjs 对着任意正在运行的 DSH 实例跑(传入 base URL 和 ?token=)。本地需要能解析到 playwright,或者用 DSH_PLAYWRIGHT=/path/to/playwright 指定。测试覆盖 CONTRACT.md 里的清单:工具栏位置、注释的创建/编辑/删除/全部删除、高亮和标记、列表浮层、独立窗口与输入框、拖动/缩放/最小化、侧边栏隐藏、刷新持久化、浅色深色主题、控制台干净度。
适用场景与注意¶
适合经常在 Web GUI 里审阅长回答、需要对特定段落反复追问的人。划词评论解决了复制粘贴丢上下文的问题,独立窗口则在不污染主对话的情况下做分支追问。
两条使用注意:
- 插件以当前 DSH 进程的权限运行,安装前应先检查源码和许可证(MIT)。
- 未发送的注释只存在浏览器本地。要跨机器继续用同一批注,需先把注释随消息发出,让它进入对话历史。
结尾¶
这个插件的价值在于把 ChatGPT 桌面端的划词标注习惯带进 DSH Web GUI:选区即锚点,注释可回溯,追问有独立空间,而且不需要动 Host 配置。目录页:https://www.skillhub.cn/plugins/AaronOhO/dsh-plugin-selection-comments,源码:https://github.com/AaronOhO/dsh-plugin-selection-comments。