Claude模拟器自动化iOS:cmux+baguette实战评测

2026-06-12阅读 0热度 0
Claude

写在前面:让我愣了三秒的一幕

上周让Claude帮我测一段地图App的行为,本来想自己截图喂给它。结果它反问了一句:"能不能让我自己操作模拟器?"

愣了三秒。然后它真的把模拟器启动、截图、找坐标、点搜索框、粘贴中文、定位"新庄地铁站"全跑完了,从头到尾没碰过模拟器。

这篇就是给当时一样懵的同学准备的:cmux是什么,baguette是什么,怎么把它俩凑一起让Agent自己动手。

一、先认识两个工具

baguette:模拟器的命令行遥控器

baguette是iOS模拟器的命令行控制工具。

平时玩模拟器,流程是打开Xcode → Open Developer Tool → Simulator,弹出一个iPhone窗口,再用鼠标戳。baguette把这一整套塞进了CLI:

baguette list                # 列出所有模拟器
baguette boot --udid   # 启动模拟器,不弹GUI
baguette screenshot --udid   # 拍一张屏幕
baguette tap --x 72 --y 455 ...    # 在指定坐标戳一下
baguette describe-ui         # 把当前页面变成JSON树
baguette type "hello"       # 往焦点输入框打字(仅ASCII)

最有意思的是这条:

baguette serve
# → http://localhost:8421/farm

打开浏览器你能看到所有运行中的模拟器实时推流,也能在网页上戳屏幕。在farm里点对应设备就能进入单机视图,地址格式:

http://localhost:8421/simulators/3AC22B97-2407-4282-BC03-9F0335FA4387

cmux:给AI Agent用的终端

iTerm2、Warp、Ghostty是给人用的终端。cmux是给AI Agent用的。

它基于libghostty(Ghostty内核),多了几样东西:

  • 垂直标签页加分屏:左边Claude Code写代码,中间跑测试,右边盯模拟器,互不打扰
  • 监听OSC 9/99/777转义序列做通知,Agent跑完任务能ping你
  • 内置可脚本化浏览器,Agent能自己开网页、点按钮、填表单,不用再装Playwright
  • 自带cmux notify命令,可以接到Claude Code的Hook里

简单说,cmux是为Agent准备的工位。

二、为什么这俩配?

把它们拆开看:

痛点 单独使用 cmux + baguette
AI看不到屏幕 你截图喂给它 screenshot直出JPEG
AI不知道点哪 你描述坐标 describe-ui给完整a11y树
AI操作完没反馈 你再截一张 自动通知 + 再截图
多任务切换累 一堆Terminal窗口 垂直标签 + 分屏
中文不能用type 卡死 pbcopy + simctl pbsync走系统粘贴

baguette解决"看见和动手",cmux解决"工位"。凑一起就能干活。

三、3步装好

Step 1:装cmux

cmux.com下dmg双击装,也能用brew:

brew install --cask cmux

cmux只支持macOS(基于libghostty私有API),Windows用不了。

Step 2:装baguette

baguette用Swift Package Manager编译,需要Xcode 26 + Apple Silicon(arm64e-apple-macos26.0):

git clone https://github.com/tddworks/baguette
cd baguette
swift build -c release
sudo cp .build/release/baguette /usr/local/bin
baguette --version  # 验证

仓库README如果提供了Homebrew tap,也可以直接:

brew install tddworks/tap/baguette

Step 3:启一个模拟器

# 列设备
baguette list
# 选一个UDID启起来(不会弹GUI)
baguette boot --udid 3AC22B97-2407-4282-BC03-9F0335FA4387
# 看一眼
baguette screenshot --udid  -o /tmp/now.jpg && open /tmp/now.jpg

或者直接baguette serve,浏览器开http://localhost:8421/farm。在farm里点对应设备就能进入单机视图,地址格式:

http://localhost:8421/simulators/3AC22B97-2407-4282-BC03-9F0335FA4387

四、实战:让Claude自己打开地图App搜"新庄地铁站"

下面是我真实跑过的命令序列,照样输到cmux里你也能复现。

1. 找地图App图标坐标

baguette describe-ui --udid  | jq '.. | objects | select(.label == "地图")'

返回(节选):

{
  "role": "AXButton",
  "identifier": "地图",
  "frame": { "x": 38, "y": 410, "width": 68, "height": 90.67 }
}

中心点(72, 455)

2. 戳开它

baguette tap --udid  --x 72 --y 455 --width 440 --height 956

第一坑:tap必须传--width --height。这俩不是手势宽高,是整个屏幕的逻辑宽高。iPhone 16 Pro Max是440 × 956,从describe-ui顶层AXApplication.frame拿。

3. 点搜索框

baguette describe-ui --udid  | jq '.. | objects | select(.identifier == "MapsSearchTextField")'
# → frame: { x: 16, y: 869, width: 362, height: 36 }
baguette tap --udid  --x 197 --y 887 --width 440 --height 956

4. 输入中文(关键技巧)

baguette type文档明写only US-ASCII,中文打不进去。绕法是走系统粘贴板:

# 1) 把中文塞到Mac剪贴板
printf '新庄地铁站' | pbcopy
# 2) 同步到模拟器剪贴板
xcrun simctl pbsync host 
# 3) 长按搜索框唤出"粘贴"菜单(duration至少1秒)
baguette tap --udid  --x 197 --y 107 --width 440 --height 956 --duration 1.2
# 4) 点"粘贴"按钮(坐标从describe-ui拿)
baguette tap --udid  --x 51 --y 148 --width 440 --height 956

跑完,搜索框里就是"新庄地铁站",地图自动定位过去。

苹果地图(iOS 18数据源高德)按关键词模糊匹配,南京"新庄"实际官方站名是"南京林业大学·新庄",1号线和3号线交汇站,所以首条命中的就是它。整个过程Agent自己跑完,没动过任何东西。

5. cmux里怎么"看戏"

打开cmux,竖着分两屏:

  • 左边:Claude Code执行命令
  • 右边:浏览器开http://localhost:8421/simulators/3AC22B97-2407-4282-BC03-9F0335FA4387,实时看模拟器

那个长串是iPhone 16 Pro Max的UDID,换成你自己设备的就行。Agent每点一下,你眼看着iPhone自己动。

五、几个进阶玩法

自动化UI测试

把上面的步骤包成一个prompt,让Claude跑回归:

帮我测试地图App的搜索功能:
1. 启动地图App
2. 在搜索框输入"新庄地铁站"
3. 截图保存到 /tmp/test_新庄地铁站.jpg
4. 如果搜索结果首条命中"新庄",标记PASS,否则FAIL

要批量回归,第2步换成关键字数组循环跑就是了,同一套脚手架。跑完Claude会把每次的截图和PASS/FAIL列给你,比你自己手点稳得多。

多设备farm并行

baguette boot --udid 
baguette boot --udid 
baguette boot --udid 

/farm看板一次显示三台,Agent可以并发对每台跑同一套用例。适配测试一次过。

cmux notify闭环

在Claude Code的Stop Hook里加:

cmux notify "模拟器测试跑完啦,赶紧来看"

晚上让它自己跑一晚,第二天起来直接看通知。

六、新手会踩的坑

这些坑都踩过:

  1. baguette tap报"Missing argument --x"。参数顺序无所谓,但--width --height必传,看--help一眼漏掉是常事。
  2. 中文输入卡死。baguette type不支持中文,老老实实走pbcopy + pbsync + 长按粘贴。
  3. 长按变成普通点击。--duration至少给1.0,0.5不够触发iOS的long-press阈值。
  4. describe-ui抓不到列表项。iOS的UICollectionView有时懒加载a11y节点,看不到具体行。这种情况只能根据图像估算坐标(屏幕逻辑大小 / 显示像素 = 比例尺)。
  5. Xcode版本不匹配。baguette当前要求Xcode 26 + macOS 26 + Apple Silicon,老Intel Mac用不了。

写在最后

cmux给Agent一张工位,baguette给Agent一双手,剩下"该让它干嘛"是我们自己的活。

跑完那次"新庄地铁站",第一反应不是"AI真厉害",而是"我下班是不是更难了"。话又说回来,重复点屏幕的活本来就不该人来干,能让Agent自己跑,何必自己加班。

跑通了的同学欢迎评论区贴你的截图,看看你的Claude在iPhone里点了啥。

参考资料:

  • tddworks/baguette · GitHub
  • cmux官网
免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策