dsh-rightclick-paste:在 DeepSeek Harness 输入框右键粘贴

前言

DeepSeek Harness(DSH)的插件化架构让开发者可以按需扩展行为。在智能体开发场景中,经常需要在多处复制内容,再一次性粘贴到当前对话草稿里。传统的右键粘贴会弹出菜单,打断思路;手动选中再粘贴又多一步操作。下面这个插件直接接管输入框区域的右键事件,把剪贴板文本追加到草稿末尾,像 cmd / PowerShell 的粘贴那样。

插件定位

dsh-rightclick-paste 是 DeepSeek Harness 的一个客户端插件,由 Eureka-KK 维护。它解决的是「在输入框区域内快速追加剪贴板文本」的重复操作问题,不提供 UI,仅扩展右键行为。

核心功能

  • 在输入框区域内右键:不弹出任何菜单,剪贴板文本直接追加到当前会话草稿末尾。
  • 在输入框以外右键:完全不接管,DSH 原生菜单照常显示(复制、检查元素等)。
  • Shift + 右键(输入框内):放行原生菜单,作为逃生口。
  • 命中范围:点在内层节点 / 卡片空白处同样算「输入框区域内」;点在输入卡片里的按钮上不接管,走原生菜单。
  • 剪贴板来源不限:DSH 内复制的、其他软件复制的、纯文本都能粘。
  • 追加规则:草稿为空或以换行结尾时直接拼;否则先补一个换行再拼。剪贴板内容一字不改。
  • 超长保护:单次最多粘贴 200 KB,超出部分截断并在控制台提示。
  • 与 dsh-quote-to-input 正交:前者负责「选中 → 引用」,后者负责「右键 → 粘贴」,两者互不干预。

安装与启用

使用 link 方式安装,修改代码即时生效:

# 安装:<插件目录> = 本仓库在你机器上的绝对路径(link 方式,改代码即时生效)
dsh plugin --profile desktop add link:<插件目录>

# 卸载
dsh plugin --profile desktop remove dsh-rightclick-paste

DSH 开启 HMR 时,修改 profile 清单会触发热重组,无需重启 App;但需要刷新一次 GUI 才能加载新增的客户端模块。

验证方式

  1. 无头验证(自动):
node verify-client.mjs

用假 DOM / 假 window / 假 navigator / 假 ctx 跑完整行为矩阵:bundle 协议、框内接管并写入正确文本、框外不接管、Shift 放行、剪贴板缺失或抛错不崩、超长截断、HMR 反复加载不叠监听器,以及一批内存纪律静态断言。退出码 0 = 全绿。

  1. 真机验证(手动):

  2. 安装后刷新 GUI(Ctrl+R)。

  3. 在别处复制一段文字,在输入框里右键——应立即出现在草稿末尾,且不弹菜单。
  4. 在消息列表区域右键——原生菜单照常弹出。
  5. Shift + 右键输入框——原生菜单照常弹出。

内存与实现设计

本插件按「零常驻」设计:

  • 零 UI:不注册槽位、不 require(‘react’)、不建任何 DOM,反馈只走 console。
  • 零定时器 / 零观察器:没有 setInterval、setTimeout、requestAnimationFrame、MutationObserver。
  • 单监听器 + 可卸载:唯一的全局监听器经 ctx.effect(…) 注册并返回 disposer。DSH 开启 HMR 时,缺 disposer 会导致每次热重载叠加一份监听器,这是真正会涨内存的地方,泄漏测试覆盖了它。
  • 零常驻状态:剪贴板文本与草稿快照只活在单次事件调用栈里,模块级没有任何可变变量。
  • 日志不含正文:只打长度({ chars: 1234 }),避免 DevTools 控制台历史强引用正文。
  • 200 KB 截断:草稿会经 setDraft → 状态机 → contenteditable → React state 复制多份,故设上限。

实现要点:

  • 命中判定靠 DSH 自己的 DOM 锚点:[data-composer-input](Lexical 的 contenteditable 宿主)与 [data-composer-card](输入卡片)。命中不了就退让,绝不误接管。
  • 读剪贴板用 navigator.clipboard.readText()。桌面端 main.js 中的 setPermissionCheckHandler / setPermissionRequestHandler 对非 media 权限一律放行,因此不会被权限拦;右键前必有 mousedown,transient activation 也在。
  • 写输入框复用官方唯一写路径 ctx.conversation.input.for(binding.ctx).setDraft(text)(全文替换语义,所以先读草稿再拼接)。
  • 压掉原生菜单靠渲染进程 preventDefault():Blink 只在 DOM contextmenu 未被取消时才向浏览器进程请求菜单,而 DSH 的菜单是主进程硬编码的(app.asar 内 lib/main.js 的 webContents.on(‘context-menu’)),插件无法扩展它。
  • 监听器挂在冒泡阶段并先查 event.defaultPrevented,页面上别的组件仍有机会先消费事件。

适用场景与注意

  • 适合频繁需要在对话草稿中追加大量文本的用户。
  • 插件以当前 DSH 进程权限运行,安装前应检查源码与许可证。
  • 若 DSH 将来改掉 [data-composer-input] / [data-composer-card] 锚点,插件会静默失效(既不接管也不报错),不会干扰原生菜单,可用 verify-client.mjs 与新 GUI 一起回归。
  • 只处理文本(readText),不处理图片或富文本。

结尾

dsh-rightclick-paste 通过极简的右键拦截与追加逻辑,减少重复操作,让对话草稿的文本录入更顺畅。其「零常驻」设计也避免了内存泄漏风险。目录页与源码仓库见下:

https://www.skillhub.cn/plugins/Eureka-KK/dsh-rightclick-paste
https://github.com/Eureka-KK/dsh-rightclick-paste

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜