mcpField
A
agent-desktop-linux

agent-desktop-linux

github.com/vercel-labsAgent 工作流22.0k424 次安装1 天前更新
代码仓库

关于 agent-desktop-linux

agent-desktop-linux 是面向 Linux 图形桌面的 UI 自动化技能,供 Agent 通过无障碍接口观察并操作应用。文档列出 X11、Wayland 与 GNOME 环境中的能力差异及运行条件。

主要功能

  1. 01通过 AT-SPI 观察界面
  2. 02按引用操作界面控件
  3. 03启动应用并管理窗口
  4. 04捕获屏幕及管理剪贴板
  5. 05等待界面变化并处理通知

适用场景

  1. 01检查应用窗口和界面内容
  2. 02操作控件或输入文本
  3. 03等待应用窗口出现或关闭
  4. 04查看 GNOME 通知

MCP 相关

README 未说明其与 MCP 的关系。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/vercel-labs/agent-desktop --skill agent-desktop-linux

安装后在 Claude Code 中输入/agent-desktop-linux确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
bus-and-permissions.md
capture-and-clipboard.md
display-servers-and-input.md
shell-tray-and-notifications.md
troubleshooting.md
windows-and-lifecycle.md

详细介绍

agent-desktop-linux

此文件仅介绍 Linux 上的差异。观察-操作循环、引用、JSON 封装、会话和追踪在所有平台上都相同。

需要 Ubuntu 24.04+(x86_64 或 aarch64)、已登录用户的图形会话以及正在运行的 AT-SPI 总线。其他发行版需要应用 at-spi2-core 桥接修复 dc0dc33;Ubuntu 22.04 的桥接会在 Action.GetActions 处中止。归档加载器要求 glibc 2.35 或更高版本。请在目标应用的桌面会话中运行 CLI:会话总线、显示环境和运行时目录均来自该会话的环境。在 TTY 登录环境、缺少会话变量的 SSH shell、没有总线的容器或其他用户的会话中,都无法看到应用。经测试的桌面环境为 GNOME;X11 和 Wayland 会话均可运行,但在输入、捕获和窗口控制方面有所不同。观察和语义操作无需辅助工具。

能力表

组命令Linux 上的状态
观察snapshot、find、get、is通过 AT-SPI 在 X11 和 Wayland 上运行。支持 window、sheet、alert 和 menu;GNOME 还支持 shell 表面。虚拟托盘 getter 有限制;请参阅 shell 参考并检查 status
表面list-surfaces列出应用的窗口、工作表和已打开菜单;shell 读取使用 snapshot --surface
按引用交互click、right-click、type、set-value、clear、select、toggle、check、uncheck、expand、collapse、scroll-to需要可读取的实时标识和所需的 AT-SPI 能力。菜单引用解析限制请参阅 shell 参考;X11 有头回退也需要可用的几何信息,且不会绕过标识检查
滚轮滚动scroll、mouse-wheel物理滚轮输入;仅支持 X11 和 --headed
指针手势double-click、triple-click、hover、drag仅支持 X11 上的 --headed。在 Wayland 上无法对准指针,因此这些操作会以 ACTION_NOT_SUPPORTED 拒绝
焦点focus焦点权限需要 --headed。对尚未处于 focused 状态的可聚焦节点调用 AT-SPI Component.GrabFocus,不操作指针,并验证状态;GTK4 应用会拒绝此调用,因此在那里 focus 会以 ACTION_FAILED grab_focus_rejected 结束,聚焦其窗口应使用 focus-window
键盘和鼠标press、mouse-click、mouse-move、mouse-wheelpress 和文本按键可在 X11 及经能力检测的 Mutter Wayland 会话上运行;指针命令仅支持 X11 和 --headed。请参阅 references/display-servers-and-input.md
按住输入key-down、key-up、mouse-down、mouse-up在所有平台上均安全拒绝:在 Linux 上,key-down 和 key-up 返回 ACTION_NOT_SUPPORTED;无头模式下 mouse-down 和 mouse-up 返回 POLICY_DENIED,使用 --headed 时返回 ACTION_NOT_SUPPORTED
应用和窗口launch、close-app、list-windows、list-apps、focus-window、move-window、resize-window、minimize、maximize、restore启动和列表查询可在 X11 和 Wayland 上运行;focus-window 需要 X11。其他窗口控制和正常关闭需要 X11 客户端。请参阅 references/windows-and-lifecycle.md
显示器list-displays可用
捕获screenshotX11:无需权限即可捕获窗口;仅在非合成管理器下才能捕获显示器。Wayland:需要门户授权,可裁剪显示器画面。不指定选择器时返回主显示器。请参阅 references/capture-and-clipboard.md
剪贴板clipboard-get、clipboard-set、clipboard-clear可用;支持文本、图像和文件列表。Wayland 需要 wl-clipboard
等待wait支持毫秒、--element、--window、--text、--menu、--menu-closed、--event。菜单等待共用菜单表面检测器;--notification 会等待 GNOME 上的新通知
通知list-notifications、dismiss-notification、dismiss-all-notifications、notification-action仅支持 GNOME Shell;列表查询可在无头模式下进行,修改操作需要在 X11 上使用 --headed,且 dismiss-notification 和 notification-action 还需要 --expected-app 或 --expected-title。字段从 shell 的 widget 布局读取,仅在 GNOME Shell 46.0 上验证过,并且每次修改都会通过其效果进行验证。Wayland 会在输入前拒绝 shell 指针操作。通知所有者不是 shell 或其自身辅助程序时,会返回 PLATFORM_NOT_SUPPORTED。请参阅 shell 参考
Shell 表面open-system-surface仅 system-tray 和 action-center 可能可用。system-tray 需要 StatusNotifierWatcher(否则会以 watcher: absent 拒绝);action-center 需要已验证的角色祖先关系。quick-settings 会以 shell_container_unproven 拒绝,taskbar 始终拒绝,且不支持 start-menu 和 system-tray-overflow,尽管 --help 会列出它们。请参阅 shell 参考
光标叠加层cursor-overlay需要活动会话;请参阅下方的光标叠加层。X11 启用后返回 data.rendered: true;Wayland 会保存设置并返回 data.rendered: false
系统status、permissions、version、batch、skills、session、trace可用

First Contact

  • 先运行 agent-desktop status。 supported_surfaces 为空表示辅助功能总线没有响应,而不是桌面为空。请阅读 references/bus-and-permissions.md;不要重启你没有启动的总线。
  • --app 接受 list-apps 打印的名称(gnome-calculator、 nautilus),或由已验证的可执行文件和参数身份支持的桌面条目名称或 ID,绝不能是窗口标题或任意注册表标签。桌面条目存在后,即可接受诸如 Files 这样的桌面条目名称。 list-windows --app 会精确匹配(包括别名);list-apps --app 会将所列名称中的子字符串与精确的适配器别名合并匹配,且不区分大小写。
  • 窗口 ID 是不透明地址,长度为 34 到 70 个字符,在窗口进程存续期间有效;重启后请再次运行 list-windows。 list-apps 的各行包含 bundle_id(已知时为桌面 ID)和 process_instance。
  • GTK4 应用的嵌套层级很深。 --max-depth 和 --skeleton 计算的是语义层级,因此空布局包装器也会增加输出层级。-i --compact 仍会显示嵌套的无名 group 节点:请继续查看其后内容。
  • 文件视图为空并不能证明文件夹为空。 如果图标视图没有显示任何文件项,请尝试可用的列表视图或详细视图,然后获取新的快照并确认应用实际显示了哪些项。
  • 窗口会先于其内容出现。 请先运行 wait --window "Text Editor" --app gnome-text-editor,然后再运行 wait --text;该命令会匹配节点自身的名称、值或描述。对于 Web 引擎应用(根据其 AT-SPI 工具包元数据检测),窗口观察会等待三次完整读取结果相同且出现 Web 文档角色,或达到请求的深度截断。若 Shell 尚无文档,预算耗尽时仍会保持未完成状态。若 --timeout 短于首次读取所需时间,则会返回 TIMEOUT,而不会返回部分树。
  • 引用必须是唯一的。 Linux 不存储元素地址,因此只有当快照捕获的窗口中仅有一个元素符合其角色、原生 ID、名称和描述,且当前仍恰有一个活动元素符合条件时,引用才会解析成功。唯一性按整个窗口计算,而不是按 --skeleton 或 --max-depth 快照展示的浅层树计算,因此即使浅层树从未显示过的同类元素,也会导致引用被拒绝。 位置、尺寸和值都不计入身份,因此布局变化本身不会使引用失效,但同类元素会:相同的按钮,或共用同一角色且没有其他字段的视图,会在任何操作到达应用之前以 AMBIGUOUS_TARGET、details.kind: identity_not_unique 拒绝;已经消失的元素则会返回 STALE_REF、saved_ref_absent。列表变化后,请获取新的快照。要在 X11 上从两个相同控件中选中一个,请使用 --headed mouse-click --xy;Wayland 会话会拒绝有头指针输入,因此在那里,同类元素既没有引用,也无法通过指针操作。引用属于其所在窗口,因此标题相同的两个窗口各自解析自己的引用。
  • Chromium 和 Qt 应用需要启动标志或变量才能显示在总线上; Electron 应用不需要这些,仅当 chrome-sandbox 未设置 setuid 时才需要 --no-sandbox。请参阅 references/troubleshooting.md。
  • 有头引用操作需要窗口能够获得焦点。 如果窗口管理器从未激活某个窗口,操作会以 activation_not_granted 结束。请参阅 references/windows-and-lifecycle.md。
  • GTK4 密码字段可能会显示其文本。 只有密码角色的内容会被隐藏。 请将带隐藏字符的 GTK4 输入框视为可被所有观察命令读取。
  • 被阻止的组合键会在未指定 --force 时被拒绝。 请参阅 references/display-servers-and-input.md。
  • 打开菜单角色的弹出窗口后,请检查 data.surfaces。 若存在 menu 条目,请使用 snapshot --surface menu --app <name> -i。若没有,请先使用 wait --menu 和 list-surfaces,再判断打开操作是否失败。由列表支持的下拉菜单属于窗口,而不是菜单表面;请参阅 Shell 参考。
  • Shell 指针输入需要接收方证明。 在 X11 上,有头 Shell 单击的接收方须由 Shell 自身的树证明:接收方必须是目标且保持不动,否则单击会在触发任何指针事件前被拒绝。Wayland 上的 Shell 单击会被拒绝。通知需要 GNOME 通知服务;托盘快照也需要 StatusNotifierWatcher。
  • 状态根目录必须是私有的。 如果 AGENT_DESKTOP_HOME 或 ~/.agent-desktop 允许组写入或所有用户访问,snapshot 会以 INTERNAL 失败;请对其运行 chmod 700,或让工具创建该目录。

等待窗口

等待应用窗口出现(--window 需要指定标题或标题子字符串):

agent-desktop wait --window "Text Editor" --app gnome-text-editor --timeout 10000

若要等待由你触发的关闭,请将操作批处理,以便在关闭前获取基线(Calculator 没有未保存文档提示,不会打断操作):

agent-desktop batch '[{"command":"close-app","args":{"app":"gnome-calculator"}},{"command":"wait","args":{"event":"window-closed","app":"gnome-calculator","timeout":10000}}]' --stop-on-error

若要监视其他人关闭窗口,请在对方关闭窗口前启动 agent-desktop wait --event window-closed --app gnome-text-editor --timeout 10000。没有 --window-closed 标志。

光标叠加层

启动会话,并将返回的 ID 传递给每个叠加层命令:

session_id=$(agent-desktop session start --name docs-example | jq -r '.data.session_id')
agent-desktop cursor-overlay enable --session "$session_id"
agent-desktop cursor-overlay disable --session "$session_id"
agent-desktop session end "$session_id"

如果没有会话,cursor-overlay enable 和 disable 会返回 INVALID_ARGS。 在 X11 上,启用会返回 data.rendered: true;在 Wayland 上,它会保存设置并返回 data.rendered: false,但不会绘制叠加层。

session start --cursor --multi-agent 会返回 data.rendered: false,因为在 Agent 执行操作前不会绘制任何内容。在 X11 上,随后每个 Agent ID 都会获得自己的光标;在 Wayland 上则不会绘制光标。

Linux 上的差异

  • Firefox/Gecko 的 select 可以在不触发 change 或 input 事件的情况下更改所选值,因此依赖这些事件的页面处理程序不会运行。即使读回的值匹配,结果仍为 delivered_unverified。继续操作前,请检查应用程序中的相应效果:仅凭读回值不能证明操作已提交。
  • 在同一个 GTK4 按钮上,两次 click 调用间隔不到约 250 ms 时,只会生效一次。两次调用都会返回 ok: true 和 delivered_unverified。若要多次点击同一个按钮,请在两次点击之间等待效果出现:在显示结果的元素上使用 wait --element <ref> --predicate value --value <expected>,或使用 wait 300。
  • Ref 操作是语义化的 AT-SPI 调用,不会移动指针,也不会更改活动窗口。在 --headed 模式下,ref click、right-click 和 type 会先尝试物理输入,只有在因 not_delivered 而拒绝后才会回退到语义操作(Windows 则相反)。在 Wayland 上,headed 指针命令和 headed select 会立即以 ACTION_NOT_SUPPORTED 拒绝,原因是 wayland_session;headed type 则需要 Mutter RemoteDesktop 功能。完整规则见 references/display-servers-and-input.md。
  • select 会先尝试语义方式,再尝试指针方式;在 X11 上,指针方式需要显式请求 --headed。Qt 组合框的语义选择只会高亮其弹出窗口中的行,因此无头模式下的选择会在更改高亮前以 POLICY_DENIED、类型 pointer_required 拒绝。在 headed 模式下,对于无法将工具包索引映射到行的列表(GTK4 列表),它会点击该行并检查其 selected 状态;对于没有语义打开操作的组合框(libadwaita 组合框行),它会点击组合框将其打开,通过弹出窗口自己的列表选择选项,并检查组合框显示的值。在无头模式下,除非组合框已显示该选项,否则列表会以 selection_index_unproven 拒绝,而没有语义打开操作的组合框会以 POLICY_DENIED、类型 pointer_required 拒绝。通过自身切换控件打开的 GTK4 下拉框,无需 --headed 即可使用 select,并会检查其显示的值。
  • Ref 可能不提供安全的语义修改方式。在这种情况下,无头请求会返回不支持的操作错误,不会臆造 hidden 或 disabled 状态,也不会切换到物理输入。GTK4 条目和密码框的 Activate 操作就是此类情况:使用 type 编辑字段,或者在确实要点击指针时显式请求 --headed。
  • 打开原生 Wayland Qt 组合框时,会在调用其操作前返回 ACTION_NOT_SUPPORTED,类型为 native_popup_requires_input。Qt 需要用户输入序列号才能显示该弹出窗口。已打开的组合框仍可收起;已确认使用 Xwayland 的 Qt 窗口仍保留其语义打开操作。
  • 无头 type 通过 EditableText 写入内容。终端的文本节点是名为 Terminal 的 textfield,其唯一操作是 RightClick;对它使用无头 type 会因检查项 supported_action 返回 POLICY_DENIED,且其值为 null。它只有在 --headed 模式下才能接收按键。
  • 在按键组合中,cmd 和 meta 均表示 Super 键。按键名称采用 macOS 和 Windows 的名称,以及 X keysym 名称。press 只接受映射后的按键;type 则可处理键盘布局无法生成的字符。
  • 窗口操作面向 X11 客户端;focus-window 和 headed 范围内的 press 需要 X11 会话。无头范围内的 press 在任一显示服务器上都需要目标当前获得焦点。聚焦另一个工作区上的窗口可能会切换用户当前的桌面。
  • 精确的 FFI ref 调用(ad_resolve_element_exact 和 ad_execute_ref_action_exact_with_policy)在所有平台上都会以 ACTION_NOT_SUPPORTED 失败;其边界规则优先适用:边界必须相对于窗口。
  • Ref 会重新识别唯一元素,而非控件实例。对于会销毁并重新创建行的工具包(GTK4、Qt6),若名称唯一,ref 会解析到替代元素,因此操作会作用于新元素。相同控件会改为以 AMBIGUOUS_TARGET 拒绝。
  • 对于仍将已移除控件列在列表中的工具包(GTK4 未设父级的控件、Qt6 setParent(None)),ref 可能会解析到用户已无法看到的控件。此时 GTK4 会返回 ok 和 delivered_unverified,但不会产生效果。任何身份规则都无法解决这一问题;请检查应用程序自身的效果。

参考资料

  • references/bus-and-permissions.md:总线初始化、三种总线状态、status 和 permissions 输出、状态根目录规则。
  • references/display-servers-and-input.md:X11 与 Wayland 对照表、press、type、指针、滚轮、拖动、被阻止的组合键、按键名称。
  • references/windows-and-lifecycle.md:launch、close-app、窗口操作、焦点、工作区、已停止的应用、后台 press。
  • references/capture-and-clipboard.md:X11 和 Wayland 上的 screenshot、Wayland 授权对话框、剪贴板所有者和辅助程序。
  • references/shell-tray-and-notifications.md:菜单和 GTK4 弹出窗口、GNOME 概览/顶栏、Shell 读取与输入、通知身份校验、SNI 和 AppIndicator 要求及拒绝情形、沙盒指南。
  • references/troubleshooting.md:症状与原因对照表、Chromium、Electron 和 Qt 标志、工具包限制、包含 platform_detail 的错误代码。

从二进制文件中读取任意文件: agent-desktop skills get agent-desktop-linux references/troubleshooting.md。

评论

支持 Markdown