LobeHub Acceptance 中的 macOS Computer Use(osascript)原生命令行自动化指南
导读
在 LobeHub 内置的 acceptance(Builder Self-Evidence)验收技能体系中,agent-browser 负责一切 Chromium 目标(Web、Electron),但并非所有被测对象都能通过 CDP 到达——原生 macOS 应用、系统级文件选择器、权限弹窗、Dock/菜单栏交互都游离于 DOM 之外。本文档是这套体系为「CDP 够不到的地方」预留的逃生出口:基于 osascript(AppleScript)与 screencapture 的 macOS Computer Use 工具箱。读完本文,你将掌握如何激活应用、发送按键与快捷键、用剪贴板注入长文本、按坐标点击、读取可访问性元素与屏幕文本,并把这些操作产生的截图/文本正确地上传为验收证据,同时理解其「仅限 macOS、不可云端移植、优先 CDP」的边界约束。
关联文档位于 packages/builtin-skills/src/acceptance/references/computer-use.md,它是整个 acceptance 技能资源树中的一张原生面(Native surface)操作手册。
定位:CDP 之外的原生逃生出口
agent-browser 只能驱动 Chromium 表面(Web、Electron)。凡是它够不到的地方——这正是 macOS Computer Use 的职责所在:通过 osascript(AppleScript)和 screencapture 驱动原生应用、处理操作系统层面的 chrome(系统 UI 元素),并在不存在 CDP 目标时读取屏幕。
在 acceptance 技能中,这一定位被反复强调为「原生面」(Native surface)与 Chromium 自动化(Web/Electron)的对偶补充:
原生 macOS 应用 / agent-browser 无法到达的 OS chrome —— Native(osascript + screencapture,本地 macOS)—— packages/builtin-skills/src/acceptance/surfaces/native.md
技能加载清单 packages/builtin-skills/src/acceptance/index.ts 将 computer-use.md 注册为键 references/computer-use.md 的资源(保留 .md 扩展名以便磁盘拉取 .agents/skills/acceptance/references/*.md 时与真实文件一一对应)。核心约束有三点:
- macOS-only 且不可云端移植:需要真实的带显示器的 macOS 会话;
- 当两者都能到达目标时优先 CDP 自动化:CDP 更稳健、可移植;
- 仅在 CDP 无法触达时才降级到这里。
主入口 packages/builtin-skills/src/acceptance/SKILL.md 中的「可移植性规则」同样指出:引擎级捕获优先于 OS 级捕获(agent-browser screenshot / dom / eval 可无头运行;screencapture / osascript 仅限 macOS),且轮次产物落在 .acceptances/ 目录下,由 CLI 排除在 git 之外。
何时需要 Computer Use
三种典型场景需要从 Chromium 自动化切换到 Computer Use:
- 被测对象是原生(非 Chromium)macOS 应用——CDP 驱动无法 attach 到这类应用,必须在这里驱动它;
- Web/Electron 流程中出现操作系统级步骤——原生文件选择器(file picker)、系统权限提示、Save 对话框、Dock/菜单栏交互,或页面无法脚本化的 Spotlight/应用切换。做法是:为该步骤临时降级到 Computer Use,执行完后再交还控制权给
agent-browser(surfaces/native.md 中称之为 "Mid-flow use from another surface"——无需让整轮运行都提交给原生面); - 没有 DOM/CDP 可用时读取屏幕——截图 + 视觉读取,或「全选-复制」后用
pbpaste读取屏幕文本。
这与表面选择路由表(SKILL.md 的 "Pick the surface by what you changed")完全一致:改了桌面专属行为(原生窗口、IPC、打包外壳)用 Electron(agent-browser --cdp),而原生 macOS 应用/OS chrome 才走 Native(osascript + screencapture)。
核心模式(Core patterns)
以下命令均可直接复制到 macOS 终端执行;配合 sleep 或 delay 组成完整操作序列。
激活应用
osascript -e 'tell application "AppName" to activate'
键入文本 / 发送按键
osascript -e 'tell application "System Events" to keystroke "Hello world"'
osascript -e 'tell application "System Events" to key code 36' # Enter(硬件码,与键盘布局无关)
osascript -e 'tell application "System Events" to key code 48' # Tab
osascript -e 'tell application "System Events" to key code 53' # Escape
key code 用的是硬件键码而非字符,因此不受键盘布局影响。以 key code 36 为例,它代表 Enter 键本身;某些应用「发送即回车」(send-on-Enter),此时在输入框内需要换行应改用 Shift+Enter,而不是再次敲击 Enter。
剪贴板粘贴(更快;长文本 / 非 ASCII 文本的必选项)
osascript -e 'set the clipboard to "Your long or 中文 / emoji message"'
osascript -e 'tell application "System Events" to keystroke "v" using command down'
keystroke 逐个字符投递,速度慢且会破坏非 ASCII 字符(中文、emoji、特殊符号)。凡是长文本或含非 ASCII 内容的输入,一律走「设置剪贴板 → Cmd+V」两步。
键盘快捷键(修饰键组合)
osascript -e 'tell application "System Events" to keystroke "f" using command down' # Cmd+F
osascript -e 'tell application "System Events" to keystroke "k" using {command down, shift down}' # Cmd+Shift+K
修饰键通过 using 子句传入,可组合多个:{command down, shift down}、{option down}、{control down} 等。
按屏幕坐标点击
osascript -e 'tell application "System Events" to click at {500, 300}'
读取窗口位置 / 尺寸 / ID
osascript -e '
tell application "System Events" to tell process "AppName"
get {position, size} of window 1
end tell'
操作系统级截图
screencapture /tmp/shot.png # 全屏
screencapture -i /tmp/shot.png # 交互式区域选择
screencapture -l "$WINDOW_ID" /tmp/shot.png # 指定窗口
先取窗口 ID:
osascript -e 'tell application "System Events" to tell process "AppName" to get id of window 1'
读取可访问性元素
osascript -e '
tell application "System Events" to tell process "AppName"
get value of text field 1 of window 1
end tell'
注意:
entire contents of window 1可以导出整棵 UI 树,但在复杂应用上极其缓慢——优先用「截图 + 视觉读取」或下面的剪贴板读取方式。
通过剪贴板读取屏幕文本
osascript -e '
tell application "System Events"
keystroke "a" using command down
keystroke "c" using command down
end tell'
sleep 0.5
pbpaste
此模式对「无 DOM/CDP 时确认屏幕内容」非常实用:全选 → 复制 → pbpaste 输出文本,供断言与证据使用。
完整的原生面验证流程示例
原生面文档给出了把上述命令拼成一个可执行流程的范例(packages/builtin-skills/src/acceptance/surfaces/native.md):
- 激活应用并导航到被测状态(按键/快捷键/点击——见工具箱);
- 驱动触发变更的动作;
- 采集证据:
screencapturePNG、面向时间型行为的屏幕录制,或全选复制 +pbpaste的屏幕文本。
APP="YourApp"
osascript -e "tell application \"$APP\" to activate"
sleep 1
# ... navigate + act via osascript (see computer-use.md) ...
sleep 2 # let the result settle
screencapture -l "$(osascript -e "tell application \"System Events\" to tell process \"$APP\" to get id of window 1")" ./proof/native-result.png
注意两次 sleep 的用途:激活后等待应用就绪、操作后等待结果稳定,这正是「原生应用需要时间处理 UI 事件」的实际落地。
捕获为证据(Capturing as evidence)
Computer Use 的产物需要遵循统一的证据契约(packages/builtin-skills/src/acceptance/references/evidence.md),映射规则如下:
screencapture得到的 PNG → 提交为--type screenshot --by cli(直接捕获源、未经修改,来源标注为 cli);- 时间型原生行为 → 用系统屏幕录制输出 MP4/GIF,参见 recording-native-macos.md;
pbpaste读到的文本 → 提交为--type text --content "$(pbpaste)"。
原生面证据的上传命令示例(来源为 cli,因为 osascript/screencapture 都由 shell 驱动):
lh acceptance run result submit --operation "$OPERATION_ID" --item "$CHECK_ITEM_ID" --type screenshot \
--file ./proof/native-result.png --by cli \
--desc "Native app shows the expected state after the change"
关于时间型行为的录制,recording-native-macos.md 建议优先使用固定时长以便录制器无需外部 kill 即可收尾:
screencapture -V 15 ./proof/native-flow.mp4
需要显式控制编码器时,先枚举 AVFoundation 屏幕设备,再用 ffmpeg 录制;如需内联播放可转 GIF。引用前务必检查文件中没有混入无关窗口、通知或敏感信息:直接 screencapture 输出标注 --by cli,FFmpeg 派生的媒体标注 --by program。
证据契约还强调了几条通用纪律:声明的 requiredEvidence 类型是强制的(不得用最终截图替代必需视频、或用文字替代必需的 DOM 快照);上传即走(证据在运行中途就按检查项上传,避免临近结束时崩溃丢失全部成果);不要发明证据——只捕获检查项声明的类型;引用任何图片、片段、生成文档前先人工检查,绝不提交凭据、Cookie、Token、私密用户数据或无关主机窗口/通知。
常见陷阱(Gotchas)
原文档总结的实践教训值得逐条内化,前两条决定整个工具链能否工作:
- 必须授予辅助功能(Accessibility)权限。 首次运行会弹出授权请求;需要在系统设置 → 隐私与安全性 → 辅助功能中授予宿主(Terminal / iTerm / agent runner),否则每次
System Events调用都会静默失败——不报错、也不执行,是最容易踩的坑。 keystroke慢且会破坏非 ASCII 字符——凡是长文本或中文/emoji/特殊字符,一律改用剪贴板粘贴(Cmd+V)。key code 36是 Enter 的硬件码,因此与键盘布局无关;对「发送即回车」的应用,输入框内换行用Shift+Enter。- 动作之间要加
delay/sleep——原生应用需要时间处理 UI 事件,背靠背连续命令容易丢失。 - 应用名随系统语言环境变化——例如
微信与WeChat;要按当前系统实际使用的名称处理。 - 不可云端移植——这里的一切都需要一个带显示器的真实 macOS 会话;目标若能用 CDP 到达,就让证据保持在 CDP 侧。
与 agent-browser 的坑形成对照:Chromium 侧(packages/builtin-skills/src/acceptance/references/agent-browser.md)主要头疼守护进程卡死、HMR 使引用失效、默认 25s 超时等;而原生面额外叠加上「权限缺失静默失败」「坐标/名称漂移」「慢速非 ASCII 键入」三座大山。这也再次印证了 skill 路由规则:能用 CDP 就绝不用坐标点击,原生只是本地 macOS 的兜底。
在技能体系中的位置
Computer Use 不是孤立脚本,而是 acceptance 技能「参考地图」(SKILL.md 的 Reference map)中的一个条目,与相邻资源共同构成完整手册:
| 需求 | 参考文档 |
|---|---|
| Native macOS / OS 拥有权步骤的操作工具箱 | computer-use.md |
| 原生面验证流程、与 Web/Electron 的 mid-flow 衔接、边界 | native.md |
| 时间型行为的 macOS 屏幕录制 | recording-native-macos.md |
| Web/Electron 的 Chromium CLI 命令 | agent-browser.md |
| 跨面证据契约(类型、来源、安全) | evidence.md |
| 端到端验收整体流程与硬性规则 | SKILL.md |
从技能整体看(packages/builtin-skills/src/acceptance/index.ts 的注释):整个 acceptance 技能负责「什么是合法轮次」(plan、evidence、report、不可变轮次、硬性规则),而每个具体仓库的「如何运行本仓库」则沉淀在 .agents/acceptance/ 项目层。Computer Use 工具箱正是回答「当目标跑到 Chromium 之外时,builder 如何驱动它并拿出可审计证据」的那一部分——记住核心判断顺序:先看 CDP 能否到达;不能到达时,才把 macOS 原生面作为本地逃生出口。在 README.md 所述的 LobeHub 交付验收场景中,这条路径专门覆盖「需要验证的是原生桌面应用、或流程中夹带着系统 UI 步骤」的交付检查,是保证端到端验收覆盖完整性的关键一环。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00