Skip to content

dsh-plugin-screenshot

Verified

dsh-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。

已知限制

  1. 长截图尚未实现 —— cordis.patch.yml 里已有 longShotScrollRatio / longShotMaxFrames 配置位,但滚动驱动、帧重叠检测与拼接还没写。
  2. 仅 Windows —— os: ["win32"],依赖 PowerShell 与 Win32 API。
  3. 截图时窗口必定短暂消失 —— 想截出不含本窗口的图,窗口的像素就不能出现在屏幕上, 两者不可兼得(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