dsh-composer-screenshot:让 DSH 输入框直接接住屏幕截图

前言

DSH 的桌面端没有给页面开 getDisplayMedia() 的口子,权限处理器只放行麦克风,所以在应用窗口里截屏这条路是堵死的。日常工作里又确实会遇到「想把当前屏幕这张图直接发给模型」的场景:先切出去截屏、存盘、再回到 DSH 上传,链条长而且容易打断思路。

下面介绍的这个插件就是解这个问题:wdmb123/dsh-composer-screenshot,由 wdmb123 维护。它在输入框的 + 号右边加一个圆形按钮,截下来的图直接落进消息草稿,不需要离开 DSH。

这是什么

一句话:给 DeepSeek Harness 的 composer(输入框)加一个截图入口,截图由宿主进程完成,浏览器侧只负责按钮、菜单和附件写入。

插件源码分两部分,对应两套运行环境:

  • index.js 是宿主半,跑在 dsh runtime 里,负责调用系统的截图工具、隐藏和恢复窗口。
  • client.js 是浏览器半,负责渲染按钮和菜单,把返回的 PNG 变成草稿附件。

之所以截图放在宿主侧做,是因为 DSH 桌面端主窗口的 Electron session 没有 setDisplayMediaRequestHandler,页面里的 navigator.mediaDevices.getDisplayMedia() 必然被拒。宿主进程本身就运行在这台机器上,由它调系统截图工具是最顺的路。

核心功能

按钮点开是三行菜单,每一行对应一种截法:

  1. 截取整个屏幕:直接截全屏,不隐藏任何东西。
  2. 隐藏窗口后截取整屏:先把本应用窗口隐藏,截全屏,再把窗口恢复。
  3. 隐藏窗口后框选区域:先隐藏窗口,然后用十字光标拖出范围,窗口恢复;按 Esc 可以取消本次框选。

截图生效后作为一张图片附件进入当前会话的输入框。插件不会替你提交消息:你自己写文字、按回车发送。

三个模式的行为细节:

  • 隐藏窗口按 bundle identifier com.deepseek.dsh 定位本应用,而不是按「最前面的应用」,所以不会隐藏错窗口。无论截图成功、失败还是按 Esc 取消,窗口都会被恢复为可见并置前台。
  • 框选模式底层是 screencapture -i:十字光标拖拽选区,按空格可切换成窗口选择,Esc 取消,超时 180s。取消时返回 409 cancelled,前端静默处理:不弹错、不产生附件。
  • 普通截屏超时 30s,返回 PNG 原始分辨率,后续压缩由宿主按模型要求做。
  • 非 macOS 平台返回 501 capture-unavailable,前端显示提示。

安装与启用

环境要求:

  • DeepSeek Harness 0.2.1 及以上(作者在 0.2.1-rc.3 上验证过)
  • macOS,目前只有 screencapture 实现;其他平台走这条路会拿到 501
  • 桌面端窗口或浏览器打开的同一个 Web GUI 都可以

通过插件管理器安装时,把仓库地址作为安装目标:

github:wdmb123/dsh-composer-screenshot

管理器会完成依赖安装与 bundle 选择。命令行等价写法:

dsh plugin --profile <你的 profile> add github:wdmb123/dsh-composer-screenshot

然后在该 profile 的 package.json 里把包名 dsh-composer-screenshot 加进 dsh.profile.bundles,插件自带的 cordis.patch.yml 会插入自己的那一行。

"dsh": {
  "profile": {
    "bundles": [
      "dsh-composer-screenshot"
    ]
  }
}

装完重启 App(或刷新界面)就能看到按钮。

典型用法

第一次使用时 macOS 可能弹权限请求,需要两项:

  1. 屏幕录制权限给到 DeepSeek Harness,否则截到的可能只有壁纸。
  2. 自动化 → System Events,只有「隐藏窗口」的两个模式需要它来隐藏和恢复窗口。

配置好之后,从输入框点那个圆形按钮,菜单里选一项即可。截到的图会作为附件出现在输入区,你接着写描述文字,回车发送,和内置「文件」按钮走的是同一条草稿链路。

如果只想要某个窗口的内容,选「隐藏窗口后框选区域」,进入框选后按空格切换到窗口选择,点一下目标窗口即可。想放弃就按 Esc。

接口与实现方式

插件暴露的是单一同源路由,只接受经过信任围栏校验的请求:

POST /composer-screenshot/capture?mode=fullscreen | hidden | hidden-region

可能的响应:

  • 200 image/png:截图字节
  • 409 {"code":"cancelled"}:用户按 Esc 取消了框选
  • 400:mode 不合法
  • 401 / 403:未通过连接信任校验
  • 405:不是 POST
  • 501 {"code":"capture-unavailable"}:平台不支持或截图工具报错

截图写入系统临时目录下的独立目录,任何路径最终都会在 finally 中删除。浏览器半注册进会话作用域的 conversation.input.left 槽,附件通过 conversation.createDrafts() 和输入框的 addAttachments() 挂上草稿。

适用场景与注意事项

适合 macOS 上做日常调试、文档配图、把实现结果直接丢给模型看的人。它能省掉「切窗口、截屏、找文件、回来上传」这四步。

几点要留意:

  • 插件以当前 dsh 进程的身份和权限运行,安装前应先过一遍源码,同时确认许可证(MIT)是否符合你的使用要求。
  • 目前只有 macOS 实现,Windows / Linux 需要各自接截图工具,插件路由会返回 501。
  • 菜单向上锚定在按钮上,三行的顺序固定为:全屏、隐藏全屏、隐藏框选,目前不可配置。
  • 隐藏窗口依赖 System Events 自动化授权;如果拒绝授权,「隐藏窗口」的两个模式会报错,但窗口保持可见。

结尾

这个插件的价值不在于截图本身,而在于它把截图嵌入了输入流程:截完即得附件,不用切应用、不用找文件路径。对 macOS 上常和 DSH 打交道的人来说,这算是把一条常见路径补上了。目录页在 https://www.skillhub.cn/plugins/wdmb123/dsh-composer-screenshot,源码在 https://github.com/wdmb123/dsh-composer-screenshot,许可证 MIT,插件版本 1.0.0。

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

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

小夜