dsh-composer-screenshot
给 DeepSeek Harness 的输入框加一个截图按钮:截取屏幕 —— 包括隐藏本窗口后截屏 —— 图片直接落进消息草稿,随手就能发给模型。
A screenshot button for the DeepSeek Harness composer: capture the screen — optionally with this window hidden — straight into the message draft.
它能做什么 / What it does
+ 号右边多一个圆形按钮,点开是三行菜单:
| 菜单项 / Menu row | 行为 / Behaviour |
|---|---|
| 截取整个屏幕 / Capture the whole screen | 直接截全屏 / Grab the whole display as it is |
| 隐藏窗口后截取整屏 / Hide this window, capture the whole screen | 隐藏本应用 → 截全屏 → 恢复窗口 / Hide the app, grab the display, restore the window |
| 隐藏窗口后框选区域 / Hide this window, select an area | 隐藏本应用 → 拖出范围(Esc 取消)→ 恢复窗口 / Hide the app, drag the region (Esc cancels), restore the window |
截图会作为一张图片附件进入当前会话的输入框;自己写文字、回车即可发送,插件不会替你提交消息。
The capture becomes an image attachment in the current composer; you add the text and press Enter yourself — the plugin never submits a message.
为什么截图在宿主侧做 / Why the Host takes the shot
DSH 桌面端主窗口的 Electron session 没有 setDisplayMediaRequestHandler,权限处理器也只放行麦克风,所以页面里的 navigator.mediaDevices.getDisplayMedia() 必然被拒。宿主进程(dsh runtime)本身就运行在这台机器上,因此由它调用系统截图工具,浏览器只负责按钮和附件。
The DSH desktop shell grants no display-media request (and its permission handler allows audio only), so getDisplayMedia() cannot work inside the application window. The Host process runs on the same machine, so it performs the capture with the operating system's own tool and the browser only handles the control and the attachment.
安装 / Install
要求 / Requirements:
- DeepSeek Harness 0.2.1 及以上(在 0.2.1-rc.3 上验证)
- macOS(目前只有
screencapture实现;其他平台路由会返回 501) - 桌面端窗口或浏览器打开的同一个 Web GUI 都可以
通过插件管理器 / Through the plugin manager: 添加插件时把本仓库地址作为安装目标(github:wdmb123/dsh-composer-screenshot),管理器会完成依赖安装与 bundle 选择。
命令行等价写法 / Equivalent CLI:
dsh plugin --profile <你的 profile> add github:wdmb123/dsh-composer-screenshot
然后把包名 dsh-composer-screenshot 加进该 profile package.json 的 dsh.profile.bundles(插件的 cordis.patch.yml 会插入自己的行)。
Then add dsh-composer-screenshot to dsh.profile.bundles in that profile's package.json; the bundle patch inserts its own row.
装完重启 App(或刷新界面)即可看到按钮。Restart the app (or refresh the UI) to see the control.
系统权限 / System permissions
第一次使用时 macOS 可能要求:
- 屏幕录制:给 DeepSeek Harness(否则截到的可能只有壁纸)
- 自动化 → System Events:仅"隐藏窗口"的两个模式需要,用来隐藏并恢复窗口
macOS may ask for Screen Recording (for DeepSeek Harness) and Automation → System Events (only the two hiding modes need it).
行为细节 / Behaviour notes
隐藏按 bundle identifier(
com.deepseek.dsh)定位本应用,而不是"最前面的应用",所以不会隐藏错窗口;无论截图成功、失败还是按 Esc 取消,窗口都会被恢复可见并置前台。框选模式用
screencapture -i:十字光标拖拽选区,按空格可切成窗口选择,Esc 取消;超时 180s。取消返回409 cancelled,前端静默不弹错、不产生附件。普通截图超时 30s,PNG 原始分辨率(宿主会按模型要求再压缩)。
除 macOS 外的平台返回
501 capture-unavailable,前端显示提示。Hiding targets this app by bundle identifier, not "the frontmost app", so the wrong window is never hidden; the window is restored (visible + frontmost) on success, failure and Esc.
Area mode runs
screencapture -i— drag with the crosshair, press Space for window mode, Esc to cancel; 180s timeout. A cancel answers409 cancelledand the UI stays silent.Whole-screen captures time out at 30s and return the native PNG (the Host compresses it for the model afterwards).
Other platforms answer
501 capture-unavailable.
接口 / API
单一同源路由,仅接受经信任围栏校验的请求:
POST /composer-screenshot/capture?mode=fullscreen | hidden | hidden-region
| 结果 / Result | 含义 / Meaning |
|---|---|
200 image/png |
截图字节 / the encoded screenshot |
409 {"code":"cancelled"} |
用户按 Esc 取消了框选 / the selector was dismissed |
400 |
mode 不合法 / unknown mode |
401 / 403 |
未通过信任校验 / failed the connection trust fence |
405 |
非 POST / not a POST |
501 {"code":"capture-unavailable"} |
平台不支持或截图工具报错 / unsupported platform or tool failure |
截图写入系统临时目录下的独立目录,任何路径都会在 finally 中删除。
Captures are written into a private temporary directory that is always removed in a finally.
结构 / Layout
index.js 宿主半:截图路由(screencapture + System Events 隐藏/恢复)
client.js 浏览器半:输入框按钮、菜单、把 PNG 变成草稿附件
cordis.patch.yml bundle patch:插入 composer-screenshot 行
locale/en.json 插件列表里的英文标题与描述
locale/zh.json 同上,中文
icon.svg 插件图标
浏览器半注册进会话作用域的 conversation.input.left 槽;附件通过 conversation.createDrafts() + 输入框的 addAttachments() 挂上草稿,和内置的"文件"按钮走同一条链路。
The browser half registers into the session-scoped conversation.input.left slot and attaches drafts through the same createDrafts() / addAttachments() path the built-in File button uses.
已知限制 / Known limits
- 只有 macOS 实现;Windows / Linux 需要各自的截图工具。
- 菜单向上锚定在按钮上;菜单行顺序固定(全屏 / 隐藏全屏 / 隐藏框选)。
- "隐藏窗口"依赖 System Events 自动化授权,拒绝授权时该模式会报错并保持窗口可见。
License
MIT
No comments yet. Be the first to write one.