by momasiku
DeepSeek Harness 的桌面自动化:给整台 Windows 机器装上眼睛和手。可以做人能做的任何事,包括且不仅限于CAD,WPS,浏览器操作,发微信。安全,快速,可靠,聪明,人性化。
# Add to your Claude Code skills
git clone https://github.com/momasiku/dsh-pilotSee how dsh-pilot compares with popular alternatives.
dsh-pilot is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by momasiku. DeepSeek Harness 的桌面自动化:给整台 Windows 机器装上眼睛和手。可以做人能做的任何事,包括且不仅限于CAD,WPS,浏览器操作,发微信。安全,快速,可靠,聪明,人性化。. It has 53 GitHub stars.
dsh-pilot's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/momasiku/dsh-pilot" and add it to your Claude Code skills directory (see the Installation section above).
dsh-pilot is primarily written in JavaScript. It is open-source under momasiku on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh dsh-pilot against similar tools.
No comments yet. Be the first to share your thoughts!
Available after the catalog security scan passes.
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
Give DeepSeek Harness hands and eyes on your desktop.
给 DeepSeek Harness 装上眼睛和手——装在整个桌面上。
范围:Windows 桌面操控——模型看到的是真实屏幕,驱动的是真实鼠标与键盘。
DSH 原本只会"说":它能推理、能写代码、能规划,但看不见你的屏幕,也动不了你的鼠标。于是看屏幕的是你、截图的是你、点按钮的是你、出错了汇报的也是你——你成了它的手、它的眼,还兼任它的报错信息。
dsh-pilot 把这个环闭上:模型直接看真实像素,然后自己动手。

模型自己画出来的 CAD 图。 用的就是 AutoCAD 自己的命令行——REC → 0,0 → 240,150、内轮廓、五个圆孔、中心线、两道尺寸,AutoCAD 里什么都没装。

一次调用改完一张表。 desktop_sequence 聚焦工作簿、把鼠标移到 C1、点击、粘贴「Q3 收入」、回车、保存——整串动作只花一次往返。

从零建一个 3D 模型。 清空视口 → 加一个立方体 → Ctrl+1、Ctrl+3 两级细分,方盒子被磨成一个球。真机上的 Blender 4.2,跑在一台没有显卡的机器上——靠 Mesa 的软件 OpenGL,而那套环境也是模型自己配好的。
| 工具 | 作用 |
|---|---|
screen_view |
抓取当前屏幕,把 PNG 作为真正的图像块交给模型(不是 OCR、不是文字描述),连光标位置、前台窗口、各显示器范围一起给出 |
desktop_control |
移动鼠标、单击/双击/右键、拖拽、滚轮、打字、按键、聚焦与列出窗口;可以在同一次调用里顺手截一张,让效果立刻可见 |
desktop_sequence |
一次调用跑完一整串动作,最后只看一眼结果 |
桌面自动化的瓶颈从来不是鼠标点得快不快,而是 "模型和电脑要来回说多少次话":
| 一个五步任务(聚焦窗口 → 点输入框 → 打字 → 回车 → 看结果) | 只用 DSH | DSH + dsh-pilot |
|---|---|---|
| 谁在看屏幕 | 你 | 模型,看真实像素 |
| 谁在点击打字 | 你 | 模型 |
| 模型 ↔ 电脑往返次数 | 5 次(每步一次,外加你的) | 1 次 |
| 送给模型的截图 | 4–5 张 | 1 张 |
| 出错时 | 你发现、你描述 | 同一次结果里就写明哪一步、为什么 |
视觉驱动点击最经典的翻车方式是"坐标差一点点",这里堵掉了三个来源:
PER_MONITOR_AWARE_V2,所以一个图像像素就是一个物理屏幕像素。origin x,y step n 说明。模型直接读刻度,不用数像素;刻度是屏幕坐标,所以即使图片被压缩也依然有效。<delivered_scale>delivered 1974x873 = 0.873x capture; multiply image readings by 1.1454 to get screen pixels</delivered_scale>
批处理是大头(省的是往返,不是点击);第二个大头是不再每次重启 PowerShell——一个常驻 worker 同时服务动作与截图:
| 请求 | 一次性脚本 | 常驻 worker |
|---|---|---|
| 动作(移动/点击/打字…) | ~0.9–2.0 秒 | 6–12 毫秒 |
| 截图(主屏) | ~1.2–2.3 秒 | ~0.5 秒 |
(2560×1600、150% 缩放、DSH 界面还在动的情况下实测)。worker 在第一次调用时后台预热,它需要的约 1 秒与第一张截图重叠,不会拖慢第一个动作。
没变化的帧不重复发送:每次截图都带 frameHash,与同会话上一帧逐字节相同时就不重复附图(也不重复存储),结果里写 unchanged: true,模型手上那张图的坐标继续有效;想看就传 forceImage: true。
截图是要靠猜的:模型在像素里找到按钮、估个中心、点一下,再截一张图看猜没猜对。 而 Windows 通过 UI Automation 直接把同一个控件交出来——角色、名字、矩形——于是点击 就变成「那个矩形的中心」,什么也不用看。
desktop_control({ action: 'controls', title: '记事本' })
// 4 [Button] '最小化' @ 887,1 45x39
// 14 [Button] '新建会话' @ 12,54 256x24
// 23 [Edit] '搜索会话名称' @ 204,238 4x20 offscreen
desktop_control({ action: 'click', target: 14, title: '记事本' })
控件树不是更快的截图,是另一种取舍。
| 截图 | 控件树 | |
|---|---|---|
| 读一次 | ~150 ms,~1k token | ~130-300 ms,~850 token(过滤后) |
| 点击位置 | 从像素里估 | 控件的精确矩形 |
| 状态 | 「看着像禁用」 | enabled、offscreen、HasKeyboardFocus、IsSelected、值 |
| 可用性 | 永远有 | 不一定有,见下 |
按单次调用看,树更慢或打平;按单个任务看,树快得多——一次读取能定位好几个目标, 既不用多截一张图,也不用多跑一轮推理。
它不是总存在。 canvas、绘图面、自绘列表、以及什么都不上报的 Electron 窗口, 给出的树要么是空的要么没意义。所以截图这条路还在,而且仍然是兜底:先读树, 树为空、或者你需要看「画出来什么」而不是「声明了什么」时,再截一张图。
三个要知道的点。
the control at index 4 is not the one that was listed: expected [Button] 'OK', found [Button] 'Cancel'。meaningfulOnly(默认 true)只返回人能操作的控件。在一个真实的 673 元素窗口上,
这是 77 个元素、约 850 token,而不是 9k——其余全是没名字、没状态、点了也没反应的
布局面板。要整棵树就传 false。includeValues 默认关闭:结构不是内容。即使打开,密码框也会被打码。当你要找的东西本身没有树——聊天记录、画布、自绘面板——不要去找它。去找围着它的
东西再做减法:输入框是个带矩形的 Edit,窗口有矩形,那么聊天区就是它们之间剩下的那块。
或者干脆不用几何:在树里选中那一条,用 HasKeyboardFocus 确认键盘落点就是你要的地方,
打字,回车。最后这一步是截图做不到的——截图能给你一根光标,给不了保证。
给模型装上手,最该讲究的就是这一块:
low 可自由批量;声明 medium/high 的批次、或含 risk: "high" 步骤的批次,在碰桌面之前就被拒绝,除非调用方带 confirm: true(而它只会在你同意之后带)。dryRun: true 只校验并列出计划,不执行。focus 失败绝不会有"接着往面前那个窗口里打字"的后续。hwnd)时,注入前会再次把该窗口置前,点击不会落进旁边的窗口。finally 里松开按键——中断的回合不会留下按住的鼠标,也不会把剩下的点击跑完。maxSequenceSteps(默认 24)。# 从 npm 装(推荐)
dsh plugin --profile <你的profile> add @momasiku/dsh-pilot
# 或从仓库装
dsh plugin --profile <你的profile> add github:momasiku/dsh-pilot
# 或用本仓库 Release 里的预构建包,免构建授权
dsh plugin --profile <你的profile> add https://github.com/momasiku/dsh-pilot/releases/latest/download/dsh-pilot.tgz
# 或你本地已有的检出
dsh plugin --profile <你的profile> add "file:E:\path\to\dsh-pilot"
下载: npm 包 · 预构建 tarball · 源码
✅ 推荐用 npm 上的 scoped 包名 @momasiku/dsh-pilot。 裸名 dsh-pilot 在 npm 上属于另一款无关的浏览器操控插件,而 dsh plugin add 总是先查 npm,所以别用裸名;用仓库地址或 tarball 也照样可以。
包自带 loader 行:plugin add 会把 @momasiku/dsh-pilot 放进 dsh.profile.bundles,行本身来自包内的 cordis.patch.yml(由 dsh.bundle.patch 声明),所以不会像手写补丁行那样被插件管理器重写时弄丢。装完重启一次 DSH Desktop,然后新开一个会话,三个工具就会出现在工具列表里。
要求 DSH 0.1.5-rc.2 至 0.2.x(即 package.json 里的 peer 范围,也是 dsh plugin add 在安装前的门禁)。环境要求:Windows、PowerShell 5.1 或 7、以及声明了图像输入的模型线路(deepseek-flash 可以)。
0.6.3 —— controls 的两处真问题(issue #1 / #2)。
controlText() 只拼了 action / cursor / foreground,把 controls 和 windows 整个丢了 —— 对纯文本模型来说,README 里说的「便宜路径」事实上不可用,只能退回截图。现在渲染成 <controls> / <windows> 块,并带上窗口名与计数。meaningfulOnly 的 $name 从未赋值:$null.Length -eq 0 恒为真,于是 ListItem / TreeItem / MenuItem / DataItem 四类无论有没有名字都被丢弃。改成读元素自己的名字,与注释里写的意图一致。Pane 不在白名单:原生 Win32 对话框(#32770)的所有子控件经 MSAA 桥接后都报 Pane,于是一个满是按钮的对话框过滤后是空的。命名 Pane 现在算控件,无名 Pane 仍视作布局。controlTotal / filteredOut 并渲染进文本。实测「运行」对话框:10 个元素,保留 6 个(确定 / 取消 / 浏览 / 提示文字),丢掉 4 个无名 Pane。script-smoke 现在会真按一次 Win+R,断言该对话框在 meaningfulOnly:true 下非空且含「确定/取消」,随后 Esc 关闭。0.6.2 —— 兼容性声明落到能验证的地方。
screen_view 抓屏、windows 枚举、controls 控件树、desktop_sequence 三步批次都正常,peer 声明 >=0.2.1-0 <0.3.0-0 本身就覆盖 rc.3。check-peers 新增 --asar:以前它只校验开发副本 node_modules(可能落在旧代),现在可以直接读已安装桌面端的 app.asar,按里面真实携带的 dsh-* 版本判定 —— 也就是用户真正在跑的那一代。--asar 的两个细节:Electron 的 fs 会把 .asar 当压缩包拦截,读取失败时回退到临时副本;asar 头部按 4 字节对齐填充 NUL,要剥掉尾部才能 JSON.parse。0.6.1 —— 简介和 README 都用中文先说。
# English 标题,顶部语言链接同步调换。0.5.14 —— 坐标契约不再猜「你看到的那张图有多大」。
2560x1600 抓取 → 1609x1006 预览,把每个读数乘 1.5911。面积落在预算内的帧会原样送达,所以抓窗口或抓区域能得到真正的 1:1 —— 1365×960 可以,1024×768 可以;4K 和 5K 则分别写 2.2642 倍和 3.0189 倍。0.5.12 —— 冷树,以及一个什么都没说的空列表。
controls 在「worker 还没见过完整树、且结果异常少」时会等 300 ms 重试一次。(no operable controls here; the window has 2 elements - pass meaningfulOnly:false to see them)。0.5.11 —— 控件树,外加两个让批量操作「不说谎」的修复。
controls 读窗口的 UI Automation 树,target 点列表里那个控件的精确矩形,于是有名字的控件不必再去像素里找。它不截图,所以也不付 settle。在 673 个元素的窗口上实测:过滤后 0.65 秒、约 850 token(77 个可操作元素),不过滤约 9k。暖 worker 记着它发出去的那份列表,所以某一行换了身份会报错,而不是点到搬进来的那个。desktop_control 每次调用都付。实测不截图的动作用时 814 ms → 12 ms。focus 被拒绝却报成功(0.5.9)。那一步只记一条备注、仍然说 ok,于是批量剩下的步骤全打进了真正在前台的那个窗口。现在改成在尝试之后检查真实前台——看状态,不看 SetForegroundWindow 的返回值——不符就报错并说出两个窗口。tolerant: true 可以恢复旧行为,给「坐标反正都对」的调用方留口子。0.2.1 这个元组需要它自己的预发布比较符:预发布版本只有在某个比较符与它同属一个 major.minor.patch、且自身带预发布标签时才放行。0.5.8 —— 两个修复,同时包已发布到 npm:@momasiku/dsh-pilot。
System.Windows.Forms.Screen.AllScreens,这是静态缓存,只有进程处理 WM_DISPLAYCHANGE 时才刷新;而暖 worker 是没有消息泵的 -NonInteractive 读取循环,缓存永远不会失效。实测:存活 13 小时的 worker 报 <screens>primary WinDisc 0,0,1600,900</screens>,而同一份结果里的 <image_size> 是 1024x768 —— 同一份结果两个答案,而坐标契约正是从这份帧里读的。现在每次截图都用 `EnumDisplayMonit