DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

yffo /

yffo/dsh-operator

Verified

给每个 DSH 会话一双手:全局 Computer Use 插件(13 个桌面 GUI 工具 + 后台 code_agent,观察截图自动降 token,动作失败有校验提示)

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@f1ca934b

dsh-operator icon

dsh-operator

给每个 DSH 会话一双手。

dsh-operator 产品图

license: MIT dsh node tests

dsh-operator 是一个装一次、所有会话可用的 Computer Use 插件:安装进 DSH 的 desktop profile 后,无论你开「标准 / PTC / 极简 / 创造」哪种模式,会话里都会直接出现一套桌面 GUI 工具,支持看屏幕、点鼠标、敲键盘、开应用,也带一个后台 code_agent。不用建特殊会话,也不用切模式。

它不依赖任何外部账号、远程服务或运行时二进制:核心能力是纯 JavaScript + macOS 自带命令 + 一个编译好的小型 AX 助手。接入 cua-driver 只是可选增强,用来做「AI 在后台操作、你同时用电脑」的人机并行。

为什么值得装

  • 装一次,全局可用:挂在 host 层工具栈里,所有当前和将来的会话自动继承,不需要每个会话单独配。
  • 观察自带省 token 机制:Retina 截图先按长边 1280 + JPEG q80 编码再交给模型(约原图 1/4 的图片 token);原生 App 额外附 AX 文本快照(通常约 1KB),比只给截图少猜很多。
  • 动作有校验:每次动作后自动重采并比较,给出 actionEffect(confirmed / unverifiable / suspected_noop);失败会附上可读提示,而不是让模型瞎猜。
  • 后台人机并行(可选):接入 cua-driver 后,cua_launch 后台启动 App、cua_observe 读窗口、cua_act 在后台点击/输入,不移动你的真实光标、不抢占焦点;你也可以选择不装,全部基础工具照常可用。
  • 安全边界清楚:危险快捷键/「删除」类按压默认拦截(guard);审计日志只记元数据、不存屏幕内容;失败样本自动脱敏;剪贴板用完还原。
  • 代码可自持:MIT,全部能力代码在本仓库维护、无外部补丁链,562 项测试 + CI 全绿;欢迎自己改、自己发布。

3 分钟上手

# 1. 装进 desktop profile
dsh plugin --profile desktop add dsh-operator

# 2. 完全退出 DSH(⌘Q),再重新打开

首次使用 GUI 工具时 macOS 会弹「屏幕录制 / 辅助功能」授权,允许给 DeepSeek Harness(或你的 DSH 宿主 App)即可。打开任意会话,问它「截一张图看看我的屏幕」,能返回截图就说明通了。

升级:dsh plugin --profile desktop update dsh-operator(或再 add 一次),然后重启 App。 卸载:dsh plugin --profile desktop remove dsh-operator。

改动前想留后路:备份 ~/.dsh/profiles/desktop/ 下的 package.json、pnpm-lock.yaml、cordis.patch.yml 三件套即可回滚。 想跑仓库最新代码而不是发布版:git clone https://github.com/yffo/dsh-operator && dsh plugin --profile desktop add file:$PWD。

怎么跟它说话

装好之后不用记命令,**用平时的说法讲清「目标 + 验收标准」**就行:

你会说 它就去做
「打开系统设置,确认在「外观」页,截个图给我」 先看再开、最后给截图
「先看看现在前台是什么,别乱点」 只读观察
「这个流程存成技能,叫 archive-screenshots」 存成可回放的技能
「这是跨应用任务,先做计划再动手,每步校验」 生成计划并逐步执行
「写个交接」/ 新窗口只说 「接手」 交接与无缝续做

完整口语用法、出错时怎么问、它不会做什么,见 对话式使用指南。

只想让它看、不让它动:跟它说「只读模式」,或把 profile 的 guiTools 设为 false。

工具一览

会话里实际能用的工具(旧版名字默认保留,可用配置 legacyToolNames 关闭):

类别 工具
观察 screenshot(截图+前台信息)、wait / long_wait、cu_observe(按窗口读 AX/截图)、screenshot_window、list_windows、zoom_region(局部原生分辨率放大)、ocr(Vision 文本兜底:AX 拿不到时读截图,返回带坐标的文本行)
鼠标 / 键盘 click(snap:false 关吸附、verify_text 点前校验落点文案)、drag、scroll、input_text、hotkey、long_press、cu_act(后台动作)
AX 读写 ax_snapshot(列控件树:ref / complete / evidence 三态,可用 root 只截一块)、ax_press(支持 ref)、ax_set_value、ax_scroll、ax_menu、ax_batch(1–12 个动作一批,AX 步骤可直接用 ref,可混跑桌面与浏览器动作)
窗口 / 应用 list_apps、open_app(前台激活)、cua_launch(后台启动,不置顶)、open_in_browser、open_in_finder、window_move(含 left/right-half 等预设)
浏览器 DOM browser_dom_snapshot、browser_dom_click、browser_dom_fill、browser_dom_probe(Chrome/Safari,AppleScript 优先,CDP 回退)
自带浏览器实例 browser_launch(独立 profile + 独立窗口,用完 browser_close;可指定 window_size;profile:"user" 复制本机登录态到临时 profile)、browser_close
浏览器自动化 browser_state、browser_prepare(可按 app 名找窗口)、browser_open、browser_click(ref 或文案)、browser_type、browser_pointer、browser_select、browser_key、browser_dialog、browser_download、browser_set_input_files(经 cua-driver:真实 profile、语义 ref、受信任输入;快照会去噪压缩,用上一代快照的 ref 会被直接拦下并提示重新读)
浏览器 CDP browser_wait、browser_read、browser_console、browser_network、browser_eval(单表达式求值)、browser_selector(元素盒子/样式/属性)、browser_screenshot(整页或指定元素,存到 ~/.dsh/dsh-operator/shots/)、crawl_diff(两份 browser_crawl JSON 离线对比:新增/消失/字段变化)、crawl_recipe(把列表选择器/列定义存成命名配方,下次 browser_crawl recipe=名字 直接复用)、browser_crawl(从列表页逐页跟进,汇总成一篇文档,失败项单独列出;传 columns 可把每页字段抽成并排对比表,字段在 detail_selector 内取值、默认 body;max_pages+next_selector 可连着翻列表页;format 选 md/csv/json);browser_extract(把页面整理成带标题/来源/时间的文档,可 path 落盘;selector 只抓正文区,all 一次抓整列卡片,columns 按列导出 CSV 或 JSON)(需 browserCdpPort + Chrome --remote-debugging-port)
剪贴板 clipboard_read、clipboard_write(文本/图片/文件;只读文本默认 4000 字符,硬顶 20000)
任务 / 技能 task_profile、plan_create/list/update/run/delete、skill_save/list/show/run/delete
后台会话 code_agent(另起标准会话执行代码/长任务)
查询 / 诊断 verify_state(窗口标题/AX/前台等谓词轮询)、operator_status、operator_guide(打印当前版本的使用指南)、failure_list(失败样本摘要)

可选:cua-driver 人机并行

基础工具用的是「真实键盘鼠标」语义;如果你希望 AI 操作的同时自己继续用电脑,接入 cua-driver:

# 1. 安装 cua-driver(见官方文档),确认:
cua-driver --version

# 2. 首次授权(Accessibility + Screen Recording 一次)
cua-driver permissions grant

# 3. 试试后台流程
#    cua_windows -> cua_observe -> cua_act / cua_launch
  • cua_windows:列出窗口和 window_id(不需要前台)。
  • cua_observe window_id=…:读该窗口的 AX 树([N] 行 + element_token),可选截图附件。
  • cua_act window_id=… action=click role=… name=…:后台点击/输入,默认 delivery_mode=background。
  • cua_launch bundle_id=com.apple.Safari:后台启动 App 或打开文件/URL,不抢焦点。

环境变量:DSH_OPERATOR_CUA=0 关闭 cua 工具;DSH_OPERATOR_CUA_BIN 指定 cua-driver 路径;DSH_OPERATOR_CUA_SOCKET 指定 daemon socket。已知限制见本文「已知限制」一节。

浏览器自动化(真实 profile)

browser_* 走 cua-driver 的浏览器通道,直接操作你正在用的 Chrome/Edge/Brave(真实登录态、真实扩展、无自动化启动参数):

# 1. 找到浏览器窗口
cua_windows app_contains="Chrome"
# 2. 绑定并拿语义快照(首次会要求授权;macOS Chrome 会弹一次它自己的调试确认)
browser_prepare pid=… window_id=… delivery_mode="foreground"
browser_state pid=… window_id=…        # 返回 target_id / tab_id / tabs / refs
# 3. 操作(ref 形如 p1:12,导航后失效)
browser_open url="https://example.com/"
browser_state target_id=… tab_id=…
browser_click ref="p1:2"
browser_type  ref="p1:5" text="hello" replace=true
browser_pointer action="scroll" delta_y=-600
  • 输入默认走 Input.dispatchMouseEvent(受信任事件,不是 element.click());需要合成点击时才传 input_route:"dom_event"。
  • 绑定用户浏览器需要显式授权;background_unavailable 时用 delivery_mode:"foreground"。
  • 不读 Cookie/密码、不伪造指纹、不绕验证码;遇到挑战会停下并在提示里让你接管。
  • DSH_OPERATOR_BROWSER=0 关闭这组工具;cua-driver < 0.38 时自动跳过。细节见本文「浏览器自动化」与「坐标与尺寸」两节。

自带实例:独立窗口、用完即关

需要干净的登录环境(换个账号)或后台跑任务、不想动自己的浏览器时,让插件自己开一个实例—— 独立 profile(独立 cookie)+ 独立调试端口,不碰你正在用的浏览器:

browser_launch headless=false            # 返回 pid / port / profileDir
browser_state  port=…                    # 后续 browser_* 都带这个 port
browser_close  port=…                    # 用完即关,临时 profile 自动删除
  • 独立实例是按需的:不启动、不常驻,关掉就干净了,不会多一个窗口一直挂着。
  • 传 user_data_dir 可以保留登录态,下次接着用;不传则用临时目录、关闭时删除。
  • 与上面「真实 profile」的区别:那条复用的是你已有的登录态,这条是隔离出来的干净环境。

页面开发与调试

除了点击输入,还有四个页面开发用的工具(都走 CDP,读优先):

browser_eval expression="document.querySelectorAll('.item').length"   # 跑一个表达式,返回 JSON 值
browser_selector selector="#submit"                                    # 元素存在性 / 盒子 / 计算样式 / 属性
browser_screenshot selector=".chart"                                   # 截图存盘,返回路径(read_image 查看)
browser_launch headless=false window_size={width:1280,height:800}      # 启动时定视口
  • browser_eval 只接受单个表达式,不是脚本块;表达式碰到 cookie / 存储 / 网络时会自动带一句敏感提示。
  • 视口尺寸在启动时用 window_size 定(实测运行时 Emulation 覆盖在 Chrome 156 上不改变 layout viewport); 宽度精确,高度按窗口算(含浏览器 UI,实际视口会小约 87px)。
  • 页面调试常用组合:browser_console(报错)+ browser_network(失败请求)+ browser_selector(元素为什么看不见)。

为什么省 token

Computer Use 的成本主要不在截图数量,而在每张图多大:

  • 2x Retina 全屏截图直接进模型,单张图片就是几千 token;本插件先缩到长边 1280 再按 q80 编码,量级约为原图的 1/4。
  • 观察只带「当前这一张」截图,不为每一步上传历史图。
  • 原生 App 额外给 AX 文本(<ax_snapshot>,通常 1KB 左右),模型能按「名字/角色」定位而不是从像素里猜坐标;Web/Electron 的 AX 树很浅时会自动退回纯视觉,不为没用信息付 token。
  • 工具策略提示词做过瘦身(8.4KB → 3.9KB),全局会话每轮都在省。
  • suspected_noop、clipped、imageError 等降级提示都能减少「模型反复重试同一动作」造成的浪费。

坐标与尺寸(重要)

GUI 工具(click / drag / scroll / zoom_region)用的是 0–1000 归一化坐标, 相对于这一次附给你的那张窗口截图,不是屏幕像素:

  • [500, 500] = 截图中心,[0, 0] = 左上角;x、y 各自按宽度/高度缩放。
  • 窗口大小变了、被遮挡了一部分,[500, 500] 永远是「当前可见区域的中心」——所以不要拿上一轮的 坐标点下一轮的图,动作前先看最新截图。

回包里跟换算有关的字段(都在 screens[] 里,按显示器给出):

字段 含义
image.width / image.height 模型实际收到的那张预览图的像素尺寸
logicalWidth / logicalHeight 该显示器的逻辑尺寸(points)
scale 像素倍率(Retina 通常是 2)
sourceBounds / visibleBounds 该显示器在全屏坐标里的位置,以及当前被裁掉多少

换算:同一显示器内,真实 x = sourceBounds.x + round(x / 1000 × visibleBounds.width),y 同理。

像素模式(coordinateMode: "pixel")直接吃截图像素坐标,但要求先有附上的截图栅格 (attachedWidth / attachedHeight 必须与当前截图一致),换一轮就失效。

尚未验证:多显示器、混合 DPI(不同屏 scale 不同)下的换算。单屏已验证;多屏请先用 list_windows 看 displays,动作后用 verify_state 确认结果。

点不中怎么办

20px 级的按钮(「重新生成」「停止生成」这类)在缩略图上只占几个像素,坐标猜不准很正常。 顺序试这三条:

  1. 先走 AX:ax_snapshot 列出控件 → ax_press 点它。Tauri / Electron / 原生 App 通常都把按钮暴露在 AX 树里,这条路径不受缩放和遮挡影响,也不需要先看坐标。 更稳的做法是传 ax_snapshot 回包里的 ref(形如 @s1a2b3c:12)而不是裸 index: 界面变过之后旧 ref 会报 STALE_REF 并让你重新快照,不会顺手按到旁边的按钮。 工具条、弹窗这类深处的小按钮,用 ax_snapshot 的 root: "<ref>" 做局部快照, 只看那个控件范围内的节点,不用把整棵树拉下来。
  2. 要坐标就先看像素:ocr 传 pixel_coordinates: true,一次给出窗口坐标、截图像素、 全局屏幕坐标三套;或照 screens[].image.width 自己换算。
  3. 键盘兜底:Tab / Shift-Tab 在控件间移动焦点,Enter 触发;只读文本通知里也能确认焦点。

ax_press 回包里的 actionEffect 会告诉你界面到底变没变(confirmed / suspected_noop / unverifiable)——看到 suspected_noop 就该重新快照,不要用同一个 index 反复按。

抓取 → 文档

browser_extract 把当前绑定页面整理成一份可以存档的文档:

browser_extract path="/Users/you/notes/某篇文章.md"
# 只抓正文区(网页导航/侧栏多时用这个,走 CDP)
browser_extract selector="article" path="/Users/you/notes/某篇文章.md"
  • 内容:标题、来源 URL、抓取时间、正文,以及带 ref 的可交互元素清单 (拿到清单还能接着用 browser_click ref="..." 继续操作)。
  • 格式:按 path 后缀或 format 选 md / txt;父目录会自动创建。
  • 不传 path 就把文本回给你(前 8000 字符),适合先看一眼再决定存哪儿。
  • 正文优先取页面的 result.text(干净);需要元素清单时加 include_refs: true,默认只留可操作、有名字的元素(max_refs 默认 50)——存文章时不把几十行 ref 塞进正文。
  • 先用 browser_state(或 browser_prepare)把目标页绑上。

反爬与合规边界

浏览器自动化会被站点识别成「非人操作」,这是事实;能做的只有像人、可解释、被拦就停。

  • 做:用真实 Chrome profile(browser_launch profile: "user",复制登录态到临时目录、原 profile 不动); 操作走受信任输入;ref 绑定快照,页面变了就重读;一次任务里的操作尽量连续、有目的。
  • 不做:破解验证码、伪造浏览器指纹、轮换 UA/IP、批量抓取——既违反多数站点的使用条款, 也会让「这条记录是谁做的」变得不可信。
  • 被拦就停:browser_state / browser_extract 会识别验证码、人机验证、unusual traffic、 「操作过于频繁」这类页面,命中了就直接告诉你「把控制权交给用户」,不要重试。 用户手动过完验证后,你再 browser_state 读一次确认即可;拿不到就改用站点的官方 API 或导出功能。

安全与边界

  • 安装即授权:插件能控制桌面和读取屏幕;装之前请确认这是你愿意用的工具。
  • guard:危险快捷键(如强制退出)和「删除/移除/支付/发送」类静默按压会被拦截;确认要做时可显式 confirm: true。
  • 审计:~/.dsh/dsh-operator/audit.jsonl 记录动作事件(窗口 id、动作类型、结果计数等元数据),不记录屏幕内容、不记录输入文本。
  • 失败样本:仅保留工具名/错误类别/消息摘要与参数长度,不含文字内容;npm run failures 可导出摘要,failure_list 工具可直接看。
  • 剪贴板:输入长文本时临时使用「快照 → 写入 → 粘贴 → 还原」,不会把你的剪贴板内容发给模型。
  • 网络:插件本身不上传任何数据;截图会随会话请求发给模型服务商,这是 Computer Use 本身的代价。

已知限制

  • 平台面(0.33.0):macOS 已验证;Windows/Linux「代码兼容、未验证」——Windows 基础 GUI 后端(GDI BitBlt + SendInput)能加载但没有真机验收,Linux 能加载但桌面后端未实现(调用报 unsupported_platform);扩展工具(AX/浏览器/剪贴板)只在 macOS 注册。operator_status / doctor 会明确打印 UNVERIFIED,不冒充支持。
  • 多屏混合 DPI 跨屏截图可能有裁切误差(clipped/visibleBounds 会提示)。
  • 纯视觉定位仍然是兜底;无 AX 的 canvas/WebGL 界面只能点像素。
  • ax_menu 需要前台进程有菜单栏;open_app 是前台激活(想要后台启动就用 cua_launch)。
  • window_move 对 Finder 部分窗口会被系统拒绝尺寸(高度纵向被夹紧时以返回 frame 为准);多窗口拖拽先把「目标窗口」置顶,否则落点会交给最上层窗口。
  • cua 相关:需要另装 cua-driver 并授权;element_token 只在相邻 cua_observe → cua_act 之间有效,跨调用会过期——插件发现过期后会重新观察并按 role+name 重试一次(控件没有名字时才退回新 token);Electron/Chromium 后台输入可能回退前台一次。
  • guard 仍是 v1:按标题/关键词判断,没有 hit-test;误拦时用 confirm: true 放行。

配置

~/.dsh/profiles/desktop/cordis.patch.yml 里给 computer-use 插件加配置(都有合理默认,通常不用改):

键 默认 说明
captureMaxEdge 1280 观察截图长边上限(0 = 不缩放)
jpegQuality 80 重编码质量(100 = 不重编码)
axObservation true 原生 App 观察是否附 AX 文本
firstFrame "auto" 首帧观察策略:auto / eager / off
guard true 危险动作拦截
auditLog true 无内容审计日志
legacyToolNames true 保留旧工具名别名
failureSamples true 写脱敏失败样本

cua-driver 相关:DSH_OPERATOR_CUA、DSH_OPERATOR_CUA_BIN、DSH_OPERATOR_CUA_SOCKET。

排障

npm run doctor      # 安装/数据目录/权限/日志等 9 项体检
npm run preflight   # 隔离环境里做一次 DSH 引导,抓插件加载错误
npm run failures    # 失败样本摘要(工具 / 分类 / App / 错误四组)
npm run failures -- --report   # 带处理建议的 markdown 报告
npm test            # 562 项测试

会话里也可以直接问 operator_status(版本/工具面/审计行数),或列出失败样本(failure_list)。

失败样本里最常见几类,按「它到底在说什么」处理:

回包里的字样 意思 怎么做
element not found (index out of range) 快照过期,序号对不上了 重新 ax_snapshot 用新 ref;ax_press 也会自动重试一次
前台是「A」,不是「B」 菜单栏属于前台 App,这是故意的守卫 先 open_app 把 B 切到前台,或传 pid
guarded 危险快捷键/删除类控件被拦 确认要做时显式 confirm: true
window_identity_mismatch window id 被系统复用,归属的进程不对 重新 list_windows,必要时传 expect_pid
AX tree is empty or unreadable 树读不出来(不等于控件不存在) 看进程还在不在、辅助功能是否授权
AXPress failed (AXError -25205) 这个控件不支持 AXPress 换坐标 click,或用 cua_act 的 role/name
element_token is stale cua 驱动的 token 只活一次调用 插件会自动按 role+name 重试;仍失败就重新 cua_observe

文档

使用指南就是本 README;问题、建议、用法讨论请开 issue。

更新记录

每个版本的变更见 Releases——tag 即版本,release notes 是当时写下的说明。 README 里不再维护版本流水账。

路线图

进行中

  • 视觉解析(低 AX 场景):先接 cua-driver 的 parse_visual_regions → 等上游 cua-perception 扩展的签名 catalog 发布 后,做持久 MCP 连接(现在的 cua-driver call 是一次性进程,解析不了跨进程的 capture_id)并做真机验证。 当前可用兜底:ocr 读文字 + 坐标点击(零依赖),见上文「AX 树为空时怎么办」。

排队中

  • 真实画布/游戏应用的真机验证(Blender / Sketch 这类纯自绘界面)。
  • 多屏混合 DPI 的跨屏截图校准。
  • Windows 真机验证。
  • 更完整的官方 seam provider 运行态(受 desktop 组合层顺序限制,暂缓)。
  • 用 5 类真实任务做公开可复现的基线数据(成功率 / 步数 / token / 耗时)。

许可

MIT。第三方组件的版权与许可声明集中在 NOTICE;其余为本项目自有代码。

—/ 5

No ratings yet

Verified DSH bundle

Commit f1ca934ba46b

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout