dsh-plugin-screenshot
Verifieddsh-plugin-screenshot · v0.3.2 · MIT · Web UI
DeepSeek Harness 截图插件:输入框入口、隐藏/保留本窗口截图、窗口边缘自动吸附框选、截图直接插入对话框
Install
dsh plugin add dsh-plugin-screenshot Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Creators
Readme
dsh-plugin-screenshot
DeepSeek Harness 截图插件 — 输入框一键截图,隐藏 / 保留本窗口、窗口边缘自动吸附框选、截图直接插入对话框。
Windows 专用(依赖 PowerShell + Win32);实测于 DSH 0.2.0-rc.2。
功能
| 功能 | 说明 |
|---|---|
| 输入框入口 | 在 + 号那一行加入截图按钮,旁边有 ▾ 选择默认行为 |
| 隐藏本窗口截图 | 截图时先把 DSH 窗口隐藏,成品里不含自己 |
| 保留本窗口截图 | 需要连 DSH 界面一起截时使用 |
| 窗口边缘自动吸附 | 拖拽选框靠近窗口边界即贴合;也可直接点一下窗口选中整个窗口 |
| 截图直接插入对话框 | 框选完成后图片自动进入输入框,不必手动 Ctrl+V |
| 顶部避让 | 截图界面顶部留出 48px,露出 DSH 的菜单栏(可正常点击) |
| 多显示器 | 使用 SystemInformation.VirtualScreen,整个虚拟桌面都在一张图里 |
安装
# 在你的 DSH profile 目录下
cd $env:USERPROFILE\.dsh\profiles\desktop
npm install dsh-plugin-screenshot
然后把 dsh-plugin-screenshot 加进该 profile package.json 的 dsh.profile.bundles 数组,重启 DeepSeek Harness。
依赖提示:本插件的
peerDependencies钉在^0.2.0-rc.1。npm 上@deepseek-ai/dsh-tools的latest标签指向陈旧的0.0.1-rc.1,请勿用@latest安装 DSH 核心包,否则 API 不匹配。需要 DSH>= 0.2.0-rc.1。
操作
| 操作 | 效果 |
|---|---|
| 左键点截图按钮 | 按当前默认行为截图 |
点 ▾ 箭头 |
打开菜单选择默认行为(会记住) |
| 拖拽 | 框选;靠近窗口边缘自动吸附 |
| 单击窗口 | 直接选中整个窗口 |
| 拖 8 个手柄 | 改变选区大小(四角 / 四边中点,光标会变成缩放箭头) |
| 在选区内拖动 | 整体移动选区 |
| 方向键 | 微调位置 1px;Ctrl+方向键 改大小;Alt 每次 10px |
Shift + 拖拽 |
本次临时关闭吸附 |
S |
开关吸附 |
Enter / Ctrl+C |
完成(图片进对话框) |
Esc / 右键 |
取消 |
Alt + 点截图按钮 |
临时用另一种隐藏模式 |
实现要点
lib/index.js 宿主半身:PowerShell 调用、7 条 HTTP 路由、2 个模型工具
lib/client.js 浏览器半身:composer 按钮 + 全屏框选覆盖层
scripts/snip.ps1 隐藏 → 截图 → 恢复,单进程完成
scripts/win.ps1 枚举窗口、显示 / 隐藏窗口、读窗口矩形
scripts/shot.ps1 全屏 / 单窗口(PrintWindow) / 区域截图
scripts/crop.ps1 按矩形裁切
scripts/clip.ps1 写入剪贴板(需 -STA)
- 通信:持久化插件包的浏览器半身跑在完整模块系统里,因此走 HTTP 路由(
ctx.webServer.register),而不是动态包才有的host.call。 - 坐标系:所有脚本第一步都调
SetProcessDPIAware(),所以窗口矩形、截图范围、框选坐标都在同一套真实屏幕像素里。 - 隐藏原理:隐藏、截图、恢复三步都在
snip.ps1一个进程内完成。分成三次pwsh调用时每次启动约 1.1s,窗口要消失一秒多,而且恢复若单独失败窗口会一直隐藏; 合并后窗口不可见时间降到 ~380ms,恢复写在finally里,异常也不会漏掉。 恢复用SW_RESTORE+ 顶层重排 +SetForegroundWindow,否则隐藏过的窗口会被其它窗口压到后面。 - 插入原理:composer 是 Lexical 编辑器,其自身 paste 处理器读取
event.clipboardData.items。本插件构造标准ClipboardEvent派发给编辑器,走的是和手动Ctrl+V完全相同的代码路径,未触碰任何 DSH 内部 API。
已知限制
- 长截图尚未实现 ——
cordis.patch.yml里已有longShotScrollRatio/longShotMaxFrames配置位,但滚动驱动、帧重叠检测与拼接还没写。 - 仅 Windows ——
os: ["win32"],依赖 PowerShell 与 Win32 API。 - 截图时窗口必定短暂消失 —— 想截出不含本窗口的图,窗口的像素就不能出现在屏幕上,
两者不可兼得(
SetWindowDisplayAffinity对非属主进程返回"拒绝访问",是系统安全设计)。 本插件把这段时间压到约 380ms。
配置
在 profile 的 cordis.patch.yml 中覆盖:
- id: dsh-plugin-screenshot
name: 'dsh-plugin-screenshot'
config:
snapThreshold: 12 # 吸附阈值(屏幕像素)
ignoreWindowPatterns: # 不参与吸附的窗口
- 'NVIDIA'
- 'TextInputHost'
longShotScrollRatio: 0.8 # 长截图(预留)
longShotMaxFrames: 40 # 长截图(预留)
变更记录
0.3.2
性能报告指出:点截图后框选界面已出现,但要等约 6 秒才能吸附 —— 因为吸附目标列表是 overlay 挂载后才异步拉取的,请求返回前数组是空的,鼠标移动不会产生任何高亮。
- 优化:
win.ps1枚举窗口时逐个调用Get-Process -Id取进程名(44 个窗口约 1.4s), 改为一次性建立进程名表再查表(约 50ms)。实测单次枚举: PowerShell 5.1 4826ms → 1708ms,pwsh 7 2085ms → 1678ms。 - 优化:
/windows路由先枚举一次,紧接着findOwnWindow()内部又枚举一次 —— 纯重复。 现在把已有结果传进去复用(findOwnWindow(windows)),参数可选,其余调用点不受影响。 - 优化:客户端在发起截图的同时并行预取窗口列表。截图本身要数秒, 足够覆盖窗口枚举,因此吸附目标在 overlay 出现时通常已经就绪,感知延迟接近 0。
- 附带收益:
/capture内部同样调用findOwnWindow(),点一次截图也少等一次枚举。
0.3.1
四个缺陷的报告来自一台只有 Windows PowerShell 5.1、没有 PowerShell 7 的机器, 以及不同的 DWM 合成时序。感谢那份逐行定位的报告。
- 修复(致命):
snip.ps1没有加载System.Drawing程序集,却使用了它的类型。 PowerShell 7 会自动加载,5.1 不会,于是该脚本在无 pwsh 的机器上直接失败:snip.ps1 failed: [System.Drawing.Imaging.PixelFormat]。已补上显式Add-Type。 - 修复:shell 候选表里的裸名
pwsh.exe/powershell.exe不做存在性检查, 在没有 PowerShell 7 的机器上会选中不存在的pwsh.exe并抛出spawn pwsh.exe ENOENT, 反而永远走不到确实存在的powershell.exe。现在只探测绝对路径,找不到时给出说明性错误; 另新增config.shellPath供部署方显式指定解释器。 - 修复:隐藏本窗口的截图里窗口仍有残影或撕裂。
ShowWindow(SW_HIDE)只清掉WS_VISIBLE,真正把像素从屏幕上抹掉是 DWM 异步完成的;原先 50ms 的等待在另一台机器上 会抓到合成中间帧。现在先DwmFlush()阻塞到 DWM 完成一次合成,再留 250ms 余量。 - 修复:隐藏模式下出现"虚空吸附框"。UWP 应用被 shell 挂起后,其窗口对象仍在且
IsWindowVisible仍返回 true,但它被 DWM cloak(DWMWA_CLOAKED != 0)、屏幕上并不存在。 这类窗口会成为看不见的吸附目标。现在枚举时按DWMWA_CLOAKED过滤。 客户端的"覆盖全屏"判定也从逐轴 90% 改为面积占比 85% —— 逐轴判定太脆: 2560x1400 的窗口在 2560x1600 屏幕上高度只占 87.5%,能躲过检查却仍覆盖近九成桌面。
0.3.0
- 新增:框选完成后可以调整,不必重画。
- 拖动 8 个手柄(四角 / 四边中点)改变大小,鼠标移到手柄上会变成对应的缩放箭头。
- 在选区内部拖动可整体移动。
- 方向键微调位置,
Ctrl+方向键改大小,按住Alt每次 10px。
- 修复:手柄拖到屏幕边缘后继续拖,选区会从另一头反向变化。现在被拖动的边在 图像边界处停住,不再翻折;单边压到对面时最小保留 1px。
- 选区位置与大小受图像范围约束 —— 越界的框被宿主裁剪时会产生与屏幕所见不一致的结果。
0.2.0
- 性能:隐藏本窗口截图时,隐藏 / 截图 / 恢复三步合并进
scripts/snip.ps1单进程完成。 窗口不可见时间由 ~1100ms 降到 ~380ms,总耗时由 ~2600ms 降到 ~1680ms。 - 修复:恢复步骤原本是独立的第三次调用,若其失败窗口会一直隐藏。现在恢复位于
finally块中,与隐藏同进程,不可能被跳过。 - 窗口 / 区域截图改为从整屏截图裁剪,隐藏与恢复时序因此只有一处实现。
0.1.2
- 文档:移除上一版 README 中引用的"自检脚本"章节 —— 那些脚本属于开发工具,不在 发布包内,照文档执行会报找不到文件。
0.1.1
- 修复:客户端 bundle 的模块 id 与包名不一致 ——
__ModuleLoader__.load({ id })仍是改名前的dsh-screenshot,触发client-modules: duplicate factory registration,整个 entry 加载失败。 0.1.0 不可用,请使用 0.1.1 或更高版本。
0.1.0
- 首次发布(含上述缺陷,请勿使用)。
License
MIT