dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DSH 截图提问插件:原生框选截图直接进输入框,全程不落盘(DeepSeek Harness plugin, Windows)
DeepSeek Harness(DSH)插件:原生框选截图,直接进输入框提问。 仓库:https://github.com/sky1ine139/dsh-plugin-screenshot-ask · 仅 Windows
在 DSH 输入框左侧加一个 📷 按钮(或按 Ctrl+Shift+A):DSH 窗口自动最小化 →
屏幕变暗 → 拖动框选 → 选区旁出现「确认 / 取消」按钮 → 确认后窗口回来,
选区直接作为图片附件落进输入框,接着打字提问、回车发送。
和系统快捷键截图最大的区别:全程不落盘。图片以字节流从宿主进程走到浏览器,
成为一个普通的图片草稿附件,不再往 图片 文件夹里堆文件。
点按钮 / Ctrl+Shift+A
→ 宿主进程把浏览器窗口最小化(这样才看得到、也截得到被它挡住的内容)
→ 整个虚拟屏幕盖上变暗的冻结帧(多显示器全覆盖,按物理像素抓取)
→ 拖框选范围(8 个手柄微调,方向键 1px / Shift+方向键 10px 挪动)
→ 点选区旁的「确认」(或双击 / Enter / 右键)→ 窗口恢复并回到输入框
→ PNG 经官方 composer 图片通道进入输入框 → 输入问题 → 回车发送
saveFolder。createDrafts +
inputActions.addAttachments(与内置文件选择器同一条路径),所以它就是一张图片附件:
有缩略图、可删除、可配文字 —— 不会被别的插件截走,也不会被存成文件。Ctrl+Shift+A。maxEdge 时等比缩小;同时守住 DSH 附件通道的两条硬线
(单边 ≤ 2000px、单图 ≤ 5MB),超了会继续缩,不会因为图太大被拒。方式一:直接从 GitHub 装(需要 pnpm;本插件无构建步骤,装完即可用)
$bin = "$env:LOCALAPPDATA\DeepSeekHarness\dsh-pkg\node_modules\@deepseek-ai\dsh\lib\bin.js"
node $bin plugin --profile web add github:sky1ine139/dsh-plugin-screenshot-ask
方式二:本地打包再装(自己改代码时用这种)
# 注意:pnpm 的 file: 规范会在空格处断开,所以仓库路径和输出目录都别带空格
cd <这个仓库的本地路径>
npm pack --pack-destination "$env:USERPROFILE\.dsh\plugin-packs"
$bin = "$env:LOCALAPPDATA\DeepSeekHarness\dsh-pkg\node_modules\@deepseek-ai\dsh\lib\bin.js"
node $bin plugin --profile web add "$env:USERPROFILE\.dsh\plugin-packs\dsh-plugin-screenshot-ask-0.2.4.tgz"
必须重启 dsh web 进程(宿主半段与浏览器 bundle 都在进程启动时装载,刷新页面不够):
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.dsh\restart-dsh-web.ps1"
重启后打开日志里新打印的带 token 地址(形如 http://127.0.0.1:3080/?token=...,
restart-dsh-web.ps1 会顺便弹一个浏览器标签页),输入框左下方出现相机按钮。
卸载:
node $bin plugin --profile web remove dsh-plugin-screenshot-ask
| 操作 | 效果 |
|---|---|
| 左键点按钮 | 最小化窗口并进入框选 |
| 右键点按钮 | 直接截取整个屏幕(多屏为整个虚拟桌面) |
Ctrl+Shift+A | 等同左键点按钮(页面有焦点时生效) |
| 拖动 | 拉出选区;松手后选区保留 |
| 拖选区内部 | 移动选区 |
| 拖 8 个白点 | 缩放选区 |
方向键 / Shift+方向键 | 选区挪 1px / 10px |
| 点工具条「确认」 | 截取选区并回到输入框 |
双击 / Enter / 右键选区 | 同上(键盘或纯鼠标都能确认) |
点工具条「取消」/ Esc / 右键空白处 | 放弃本次截图,窗口照常恢复 |
浮层内 Ctrl+A | 全选整个屏幕 |
截取成功后输入框里会出现一张图片缩略图,直接打字提问即可;也可以点缩略图上的 删除按钮反悔,或再截一张(会依次排队进同一条附件栏)。
在 ~/.dsh/profiles/web/cordis.patch.yml 里按 id 覆盖(该文件当前是 [],改成下面这样即可):
- id: screenshot-ask
config:
maxEdge: 2000 # 只用于「调小」:长边上限,填更小值图片更小;DSH 附件上限是 2000,填更大也按 2000
saveFolder: '' # 非空且目录存在时,额外往这里存一份 PNG(默认不落盘)
timeoutMs: 180000 # 浮层忘关时的兜底超时(超时会强杀脚本并自动恢复被最小化的窗口)
hideWindow: true # false = 截图时不最小化 DSH 窗口(想连 DSH 界面一起截时用)
allowRemote: false # true = 允许非 loopback 来源触发截图(不建议)
改完同样需要重启 dsh web。
宿主半段 lib/index.js:在 ctx.webServer 上注册两条精确路由
POST /api/screenshot-ask/capture({mode:'rect'|'full', keepWindow?:true})与
GET /api/screenshot-ask/status;capture 拉起 lib/capture.ps1,把它的
JSON(含 base64 PNG)原样回给浏览器。带并发闸、超时、loopback 校验;
若脚本被超时强杀,宿主会读脚本留下的窗口句柄把浏览器窗口恢复回来。
截屏脚本 lib/capture.ps1:
ShowWindow(SW_MINIMIZE),并把句柄写进状态文件;Paint 里画,
不是 BackgroundImage —— 超大窗体上后者不渲染,会退化成一块灰);CopyFromScreen
天然对齐;选区旁画工具条(尺寸 +「确认」+「取消」),鼠标命中测试与绘制共用同一套布局函数;
重绘走统一失效区域:上一次与当前的选区框 + 工具条四块矩形一起失效。
工具条在选区下方 14~50px 处,只按选区外扩失效会漏掉它 —— 那正是"直接框选后出现带状、
手动调整一下就正常"的成因(手动调整触发了工具条自己的失效);
顶部提示条按显示器逐屏居中绘制:只在整块虚拟屏上居中会让它骑在多屏接缝上,
每块屏各露半截(看起来像凭空多出一个被截断的黑框);finally 恢复并聚焦原窗口。
输出 {ok, dataUrl, width, height, sourceWidth, sourceHeight, bytes, dpiAware, hidden, restored}。
纯 ASCII 源码(Windows PowerShell 5.1 会把无 BOM 的 UTF-8 当 ANSI 读,因此中文串由
Text-Of 按码点拼);几何逻辑带 -SelfTest,多屏覆盖带 -Probe 亮度自检,
-DemoDrag 能合成真实拖拽并用像素读数验证工具条确实被画出来。DPI:进程按 per-monitor-v2 → per-monitor → system 依次降级申请 DPI 感知。
只用 SetProcessDPIAware(system)时,副屏若缩放不同,Windows 会把鼠标坐标虚拟化
(实测 120% 屏上坐标 ×1.2),选区与抓帧就会错位 —— 这是本插件踩过的坑。
浏览器半段 lib/client.js:window.__ModuleLoader__.load 经典脚本 bundle,
注册到 conversation.input.left 槽位;拿到 dataURL 后取当前会话 id(ctx.get('sessions')),
用 ctx.get('conversation').createDrafts(sessionId, [file]) 建一张浏览器侧图片草稿,
再交给该会话的 inputActions.addAttachments(ids) 追加进输入框 —— 与内置文件选择器
(ui-conversation 的 addFiles)完全同一条路径:不派发任何 DOM 事件,其他插件的
drop 监听器无从插手,字节也不落盘。追加被拒(提交中的相位)时会
releaseDraftAttachments 回收并提示,不会泄漏草稿。最后把焦点交回输入框。
曾经的实现是「合成一个 document 级
drop、塞进DataTransfer」,那是错的:dsh-files也监听 document 的drop,会把文件上传到.dsh-filess/<session>/落盘, 再往输入框塞路径 —— 输入框里已有图片草稿时这一步会失败,于是截图变成一张 文件卡外加一条红色报错。现在只在会话服务不可达(老版本 DSH)时才回退到 drop。
Ctrl+Shift+A 只在 DSH 页面有焦点时生效。hideWindow 设为 false(或调接口时带 keepWindow: true)。dsh-capture(见下)或后续版本。DSH 插件市场里已经有两个同类插件,本插件是它们的组合与取舍:
deepseekbluefish/dsh-screenshot-plugin:
同样的原生框选浮层,但截图存进 ~/Pictures/DSH-Screenshots 并只在输入框写入
[Shot N HH:mm] 标记,需要再配视觉插件让 agent 去读文件 —— 正好是「占空间」的痛点。Max-Null/dsh-capture(@max-null/dsh-capture):
框选 + 标注(矩形/箭头/文字)+ 图片直入输入框,功能更全;但纯浏览器模式下走
getDisplayMedia,每次截图都要在系统选择器里先选一次屏幕,且无法截取被 DSH 窗口
遮住的内容之外的整屏自由度。想要「标注 + 全局热键」的完整体验,可考虑装 DSH Desktop 桌面壳(dsh-capture、dsh-appshots 在壳内提供全局快捷键)。
| 现象 | 处理 |
|---|---|
| 输入框旁边没有相机按钮 | 插件没被装载:确认 dsh plugin --profile web add 成功、profile 的 dsh.profile.bundles 里有 dsh-plugin-screenshot-ask,然后重启 dsh web |
| 点按钮提示「截图失败:… HTTP 404」 | 宿主半段没加载(如无 webServer 的 TUI 部署),Web 版才有这条路由 |
| 提示「没有可用的输入框」 | 没有打开的会话;先进入一个会话再截图 |
| 浮层只有一块屏幕变暗 / 只有一个显示器能框选 | 运行 -Probe 看两台显示器的 meanLuma 是否都被压暗;仍不行就贴 -DemoRect ... -DemoMs 3000 的输出(里面 realWindowRect 是操作系统认定的真实窗口矩形) |
| 选区位置和实际截到的区域错位 | 典型的混合 DPI 问题:看 -CaptureRect 输出里的 dpiAware 是否为 true;另外检查环境变量 LIB(绿色版 VC6 会污染 C# 编译,脚本已临时置空处理) |
| 窗口最小化后没回来 | 正常路径由脚本 finally 恢复;被超时强杀时宿主会用状态文件恢复。若仍卡住:powershell -File lib/capture.ps1 -Mode restore -StateFile "$env:TEMP\dsh-screenshot-ask-hwnd.txt" |
| 图太大、发送慢 | 调小 maxEdge(如 1600) |
| 截图变成一张「文件卡」,还弹红字「文件已上传但未能加入输入框」 | 这是别的插件(dsh-files)抢到了 document 级 drop:它把文件落盘到 .dsh-filess/<session>/ 再往输入框塞路径。本插件 v0.2.1 起不再合成 drop,走会话草稿 API;若仍出现,说明 ctx.get('conversation') 不可达(老版本 DSH),控制台会打印 using the drop fallback,可临时停用 dsh-files 或升级 DSH |
| 连拍两张只进了一张 | 第二张时输入框处于提交相位会被拒(提示「输入框正忙」),等这一条提交完再截;草稿不会被泄漏 |
| 输入框已经有图片草稿,能否继续加 | 可以,同一条附件栏按顺序排队,最多 20 张 |
| 工具条位置/尺寸数字和选框对不上(例如徽标写 1146、选框只有 800 宽) | v0.2.1 及更早的残留像素:改小选区后选框重画了、工具条那块没重画,于是看到的是旧的工具条(位置和数字都还是旧选区的)。v0.2.2 起重绘范围包含"旧/新 选区框 + 工具条"四块矩形。判据:同一个 Paint 里画的框和文字不可能不一致 —— 不一致就一定是有一块没被重画。回归自检:-DemoDrag "2600,400,3746,800" -DemoDrag2 "3746,600,3400,600" -DemoMs 5000 -KeepWindow(先建 1146 宽选区,再从右中手柄收窄到 800;读 toolbarProbe.confirm 应为 37,132,246 且 at.x 对新选区居中) |
| 某块屏幕顶部凭空多出一个半截黑框(文字被截断,比如只看到「Enter 确认 | Esc 取」) | v0.2.2 及更早:顶部提示条按整块虚拟屏居中,正好骑在两屏接缝上,于是每块屏各露半截。v0.2.3 起改为每块显示器各画一条完整提示。自检:-DemoDrag ... -KeepWindow 输出里的 hintProbe,每块屏的 delta 应接近 0(提示文字中心与该屏中心之差) |
不想最小化窗口就加 -KeepWindow:
powershell -NoProfile -ExecutionPolicy Bypass -File lib/capture.ps1 -DemoRect 200,150,400,250 -DemoMs 3000 -KeepWindow
自测(不需要重启,直接跑脚本):
# 几何自检
powershell -NoProfile -ExecutionPolicy Bypass -File lib/capture.ps1 -SelfTest
# 无头截取一块区域,验证 base64 PNG 通路
powershell -NoProfile -ExecutionPolicy Bypass -File lib/capture.ps1 -CaptureRect 40,60,320,200
# 每台显示器的实时平均亮度(用来判断遮罩是否覆盖全屏)
powershell -NoProfile -ExecutionPolicy Bypass -File lib/capture.ps1 -Probe
# 渲染自检:弹出自检浮层 3 秒后自动关闭,并报告真实窗口矩形 / 覆盖情况 / Paint 错误
powershell -NoProfile -ExecutionPolicy Bypass -File lib/capture.ps1 -DemoRect 200,150,400,250 -DemoMs 3000
# 合成鼠标点击工具条按钮(真跑一遍命中测试)
powershell -NoProfile -ExecutionPolicy Bypass -File lib/capture.ps1 -DemoRect 200,150,400,250 -DemoMs 6000 -DemoClick confirm
# 合成一次真实的框选拖拽,并读屏幕上工具条三处的实际像素
# 期望:confirm=37,132,246(确认键蓝底)cancel=66,66,70(取消键灰底)
powershell -NoProfile -ExecutionPolicy Bypass -File lib/capture.ps1 -DemoDrag 2600,400,3400,800 -DemoMs 4200 -KeepWindow
# 拖拽 + 点确认,走完整条链路(应返回 width=800 height=400 的 PNG)
powershell -NoProfile -ExecutionPolicy Bypass -File lib/capture.ps1 -DemoDrag 2600,400,3400,800 -DemoClick confirm -DemoMs 6000 -KeepWindow
# 回归:先建 1146 宽选区,再从右中手柄收窄到 800(旧版本会留下旧的工具条)
powershell -NoProfile -ExecutionPolicy Bypass -File lib/capture.ps1 -DemoDrag 2600,400,3746,800 -DemoDrag2 3746,600,3400,600 -DemoMs 5000 -KeepWindow
node scripts/selftest.mjs # capture.ps1 端到端(自检 + 区域 + 整屏 + 降采样)
node scripts/client-smoke.mjs # 浏览器半段:假 DOM / 假 React / 假会话服务,覆盖
# 草稿 API 投递、忙时回收、连拍两张、drop 回退、快捷键
node scripts/overlay-probe.mjs # 全链路:窗口隐藏/恢复 + 遮罩是否覆盖每一台显示器(会短暂最小化窗口)
# 排查用:量一张已有截图里选框/工具条的实际像素位置,或把某块区域放大出来看
powershell -File scripts/scan-shot.ps1 -Path <截图.png>
powershell -File scripts/crop-shot.ps1 -Path <截图.png> -Out out.png -X 1600 -Y 860 -W 524 -H 100 -Scale 2
改完重新 npm pack + dsh plugin add + 重启即可(或 npm run selftest / npm run smoke)。
MIT。浮层实现与 file: 交付思路分别改编自
dsh-screenshot-plugin 与
dsh-capture(均为 MIT),详见 LICENSE。