Pular para o conteúdo principal
T

dsh-composer-shot

thetao-xt/dsh-composer-shot

WeChat-style screenshot button in the DSH composer on Windows: freeze the screen, drag a region, and the crop lands in the current draft as an attachment; an eye switch hides the DSH window during the capture and restores it right after.

Instalar

dsh plugin --profile web add github:thetao-xt/dsh-composer-shot

README

dsh-composer-shot

A WeChat-style screenshot button inside the DeepSeek Harness composer (Windows 10/11 x64): click the camera, drag a region on the frozen screen, and the PNG lands in the current draft as an attachment — it never sends by itself. The eye switch next to it hides the whole DSH window before the capture and brings it straight back afterwards.

下面为中文说明 · English summary

一个 DSH(DeepSeek Harness)桌面端客户端插件:在聊天输入框底部工具区加一枚截屏按钮和一枚隐藏窗口开关,截出来的 PNG 直接进入当前会话草稿(不会自动发送)。

截图交互是微信截图风格:点相机后整个屏幕冻结,灰黑色遮罩 + 绿色边框 + 8 个手柄 + 尺寸标签,拖选区域后按 Enter 或点 ✓ 确认,按 Esc 或点 ✕ 取消。

  • 仅支持 Windows 10/11 x64
  • 全部逻辑在本机完成:截图走本机回环 HTTP,图片以 temp 文件中转,不上传、不埋点、不写外部日志
  • 无 npm 运行时依赖;原生截图组件随包提供 C# 源码,首次使用时用系统自带的 .NET Framework 4 csc.exe 编译(约 1 秒),之后复用

功能

功能说明
📷 截屏冻结全屏 → 拖选 → Enter / ✓ 确认 → PNG 作为图片附件进入草稿
👁 隐藏窗口紧挨相机左侧的开关。开启后点相机时先隐藏整个 DSH 窗口(等待 120 ms)再截屏,选完/取消/出错后自动恢复窗口;关闭时正常截屏(包含 DSH 窗口)
状态持久化隐藏开关的状态保存在 localStorage(键 dsh-composer-shot.hide-dsh)
单会话同一时间只允许一个截图会话;重复请求返回 409「上一次截屏还没结束」
忙碌态截图进行中相机变成 spinner;再点一次 = 取消(快速双击则展示宿主返回的 409 文案)
失败提示所有失败通过底部 toast 提示,不弹 alert
主题只用 --dsw-alias-* 设计变量配色,亮色/暗色主题都跟随;样式带 data-plugin 标记且只注入一次

按钮位置:conversation.input.right 座位,用 CSS order: 1 排在模型选择器之后、语音按钮/发送按钮之前。

安装

需要 DSH 桌面端已安装(dsh CLI 通过桌面运行时提供,通常不在 PATH 里)。

从市场安装(推荐):DSH 里打开 插件 → Discover,搜 dsh-composer-shot,点安装;或在设置 → 插件页直接启用。

从 npm 安装:

& "$env:LOCALAPPDATA\Programs\DeepSeek Harness\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add dsh-composer-shot

从源码 / 压缩包安装见下面的脚本与手动两节。

方式一:脚本(推荐)

# 在包目录(含 install.ps1 和 *.tgz)内
powershell -ExecutionPolicy Bypass -File .\install.ps1

脚本会:解析 dsh CLI → dsh plugin --profile desktop add <tgz> → 确认 dsh.profile.bundles 已记录 → 预编译原生截图组件到 %LOCALAPPDATA%\dsh-composer-shot\dsh-shot-helper.exe。

可选参数:

-ProfileName web                  # 装到别的 profile(默认 desktop)
-DshCli D:\DeepSeek\resources\runtime\cli\bin\dsh.cmd
-PackagePath .\dsh-composer-shot-1.0.4.tgz

方式二:手动

# 把 tgz 放进 profile 目录再安装
Copy-Item .\dsh-composer-shot-1.0.4.tgz "$HOME\.dsh\profiles\desktop\"
& "D:\DeepSeek\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add .\dsh-composer-shot-1.0.4.tgz

安装后刷新 DSH 窗口(Ctrl+R)或重启桌面端,输入框右下角就会出现 👁 和 📷 两个小按钮。

注意:plugin add 会把插件写进 profile 的 package.json(dependencies 与 dsh.profile.bundles)。本插件不改 cordis.yml,也不往用户层 cordis.patch.yml 里塞条目。

卸载

powershell -ExecutionPolicy Bypass -File .\uninstall.ps1            # 只卸插件
powershell -ExecutionPolicy Bypass -File .\uninstall.ps1 -Purge     # 连编译缓存一起删

手动等价写法:

& "D:\DeepSeek\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop remove dsh-composer-shot
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\dsh-composer-shot"

快捷键

截图覆盖层是原生窗口,按键在窗口内生效:

按键 / 操作效果
在空白处按住左键拖动新建选区
选区内部按住拖动移动选区
拖动 8 个手柄之一缩放选区(最小 4×4 物理像素)
Enter确认,写入 PNG 并插入草稿
Esc取消,不产生图片
鼠标右键(任意位置)取消,不产生图片;拖动中途右键也能中止
点 ✓ / ✕同 Enter / Esc
点击 spinner取消当前截屏(宿主会终止 helper 进程树)

工作原理(便于排障)

┌─ 客户端 (lib/client.js) ─────────────────────────────────────────┐
│ conversation.input.right 座位渲染两个按钮                          │
│ POST /dsh-shot/capture { hideDsh }  ──► 等待最终 PNG               │
│ PNG ─► File ─► 对 [data-composer-card] 派发 drop(700 ms 内生效)   │
│            └► 未生效则回退 paste 到编辑器根节点(只允许成功一条)    │
└──────────────────────────────────────────────────────────────────┘
┌─ 宿主 (lib/index.js) ────────────────────────────────────────────┐
│ GET  /dsh-shot/ping      探测平台/编译器/helper 是否就绪            │
│ POST /dsh-shot/capture   编译并按需启动 dsh-shot-helper.exe         │
│ POST /dsh-shot/cancel    taskkill /t 终止 helper 进程树             │
│ 每个 handler 先过 ctx.connection.requestRejection(req)(仅回环)   │
└──────────────────────────────────────────────────────────────────┘
┌─ 原生 (lib/ShotHelper.cs → dsh-shot-helper.exe) ─────────────────┐
│ 全屏冻结位图 → 可选隐藏 DSH 顶层窗口 → 抓屏 → 恢复窗口             │
│ → 无边框 TopMost 覆盖层选图 → 裁剪 → 写 PNG(物理像素,无损)       │
│ 退出码:0 成功 / 2 取消 / 3 失败                                    │
└──────────────────────────────────────────────────────────────────┘
  • 为什么选区在原生层:开启「隐藏窗口」时渲染层会随窗口一起消失,无法显示选区;原生覆盖层还能跨显示器、跨应用、按物理像素工作。
  • 隐藏与恢复顺序是安全的:helper 先隐藏 DSH → 等 120 ms → 抓屏 → 立即恢复窗口 → 再弹覆盖层;即使 helper 被强杀,宿主退出后还会再跑一次 --show-exe 兜底,不会把窗口永久留在隐藏状态。

已知限制

  1. 仅 Windows 10/11 x64:依赖 .NET Framework 4 的 csc.exe 与 user32.ShowWindow。非 Windows 或缺少 .NET Framework 4 时按钮会置灰/报错。
  2. 选区界面是英文:提示语为 Drag to select a region | Enter to confirm | Esc to cancel,覆盖层不随 DSH 语言变化。
  3. 不支持滚动长截图、窗口自动识别、贴图/涂鸦:只做区域截图。
  4. 隐藏模式下 DSH 在整个选区期间不可见:点相机后先隐藏 DSH、等合成器稳定再抓屏,选区确认(Enter/✓ 或右键)后才恢复窗口,所以从点击截图到选完,DSH 大约会有 1–3 秒不在屏幕上——这是刻意的,避免任何一帧把 DSH 拍进图里。 窗口恢复做了三步兜底:抓屏后立即 ShowWindow(按隐藏前是否最大化精确还原)→ 恢复前台(绕过前台锁)→ 强制重绘;宿主在助手退出后还会再跑一次 --show-exe 恢复。 若助手在隐藏期间被杀(超时/取消/崩溃),恢复依据 %TEMP%\dsh-shot-hidden.txt 里记录的窗口句柄,只还原它自己藏起来的窗口。 每次截屏的隐藏/恢复结果写入 %LOCALAPPDATA%\dsh-composer-shot\capture.log,排查「窗口没回来」时先看这个文件。
  5. 多虚拟桌面:CopyFromScreen 只能抓当前桌面与当前会话的可见像素;被最小化/被其它虚拟桌面遮挡的窗口内容不在图中。
  6. HDR / 宽色域屏幕:截图为 32bpp ARGB 的 sRGB PNG,颜色可能与 HDR 显示观感略有差异。
  7. 首次截图需编译(约 1 秒):装完或 ShotHelper.cs 变更后的第一次调用会编译,之后走缓存;安装脚本已预编译。
  8. 草稿插入依赖 DOM 通道:通过 [data-composer-card] 的 drop / paste 事件进入草稿。若 DSH 未来改动输入框结构,插件会自动改试另一条通道;两条都失败时提示「截图已生成,但没有插入草稿」,此时图片只存在于内存中、不会落盘,需要重截一次。
  9. 光标不参与截图:抓屏时不含鼠标指针。
  10. 不修改任何已有插件,也不新增 npm 运行时依赖。

文件

package.json         # 包清单:dsh.bundle.patch / dsh.client / exports
cordis.patch.yml     # 包内挂载行(不属于用户配置层)
lib/index.js         # 宿主:三条回环 HTTP 路由 + helper 编译/生命周期
lib/client.js        # 客户端:手写 ModuleLoader bundle,两个按钮 + toast + 入草稿
lib/ShotHelper.cs    # 原生截图组件源码(首次使用时编译)
install.ps1          # 安装 + 预编译
uninstall.ps1        # 卸载(-Purge 连缓存)
README.md
LICENSE              # MIT

隐私

插件只与本机 127.0.0.1 上的 DSH Web 服务通信(/dsh-shot/*),由 ctx.connection.requestRejection 拒绝一切非回环请求。图片经操作系统临时目录中转后立即删除,不写外部日志、不上传、不埋点。

许可

MIT,见 LICENSE。


English summary

What it does. Adds two controls to the DSH composer toolbar: a camera that freezes the screen, lets you drag a region (8 handles, move, resize, Enter/✓ to confirm, Esc/✕ to cancel) and drops the cropped PNG into the current draft as an image attachment; and an eye switch that hides the DSH window for the duration of the capture and restores it immediately afterwards (about 0.1–0.2 s of flicker).

Requirements. Windows 10/11 x64, DSH desktop (or any dsh host) with the plugin installed into the desktop profile. The native helper is shipped as C# source and compiled on first use with the .NET Framework 4 csc.exe that ships with Windows — no SDK, no npm runtime dependencies, no network calls: the PNG travels from the helper to the host over a temp file and from there to the renderer over loopback HTTP.

Install.

dsh plugin --profile desktop add dsh-composer-shot     # from npm
powershell -ExecutionPolicy Bypass -File .\install.ps1  # from this repo (installs + precompiles the helper)

Then fully quit and reopen DSH — the plugin composition is decided at process start, so a renderer reload alone is not enough.

Privacy. Nothing leaves the machine. No telemetry, no uploads, no external log file; a per-capture diagnostic line is written to %LOCALAPPDATA%\dsh-composer-shot\capture.log only for the hide/restore path.

License. MIT.


开发

lib/index.js       宿主侧(ESM):/dsh-shot/ping、/dsh-shot/capture、/dsh-shot/cancel 三条回环路由
lib/ShotHelper.cs  原生截图助手(WinForms,C# 5,ASCII-only):冻结屏幕、覆盖层选区、隐藏/恢复窗口
lib/client.js      客户端 ModuleLoader bundle:两颗按钮、忙碌态、toast、把 PNG 塞进草稿
cordis.patch.yml   插件组合补丁(只 insert 自己这一行)

打包与本地验证:

npm pack --ignore-scripts
powershell -ExecutionPolicy Bypass -File .\install.ps1 -PackagePath .\dsh-composer-shot-1.0.4.tgz

改完 lib/*.js 后,同一版本号 dsh plugin add 不会覆盖已装文件——先在 profile 里 remove 再 add,或直接把文件拷进 node_modules/dsh-composer-shot/lib/ 做联调。

Plugins relacionados