- 区块链
- DeFi
- 前端
- 移动开发
【免费下载链接】interface
🦄 Open source interfaces for the Uniswap protocol
本篇技术指南面向在 Uniswap interface 单仓库中开发与调试移动端(apps/mobile)的 AI Agent 与开发者,系统讲解.agents/skills/argent-device-interact/SKILL.md所定义的统一设备交互技能:如何用同一套 MCP 工具完成点击、手势、滑动、打字、硬件按键、启动应用、打开 URL 与截图,并由工具服务器根据udid形态自动分派到 iOS 模拟器或 Android 模拟器。读完本文,你将掌握完整的工具选型矩阵、归一化坐标体系、目标发现策略(describe家族)、多步动作序列化(run-sequence)以及 Android 平台专属坑点(Metroadb reverse、锁屏、权限预授权),并能直接在本仓库的移动端工程上落地执行。
1. 技能定位与统一工具表面(udid 自动分派)
argent-device-interact是 Uniswap interface 仓库 .agents/skills 目录下的一套 Agent 技能(skill),其核心设计是统一工具表面(Unified tool surface):
- 所有交互工具都接受一个
udid参数; - 工具服务器根据
udid的形态自动分派平台:UUID 形态(如A1B2C3D4-E5F6-7890-ABCD-EF1234567890)→ iOS 模拟器;其他任何值(如emulator-5554这样的 adb serial)→ Android 模拟器/真机; - 因此 iOS 与 Android 使用完全相同的工具名:
gesture-tap、gesture-swipe、describe、screenshot、launch-app、keyboard等。
平台专属注意事项(Metroadb reverse、锁屏时describe报错等)集中在原文档第 9 节,即本文第 10 章。
这套技能的配套生态还包括 argent-ios-simulator-setup(模拟器启动与连接)、argent-android-emulator-setup(AVD 启动与 adb 前置条件)、argent-metro-debugger(Metro CDP 调试)与 argent-test-ui-flow(交互-截图-验证循环),它们共同构成在 apps/mobile 这类 React Native 工程上的完整 Agent 端开发调试工作流。
2. 开始之前:设备发现、启动与工具 schema 预加载
2.1 委托子 Agent 前确认 MCP 权限
如果要把模拟器任务委托给子 Agent,务必确保子 Agent 具备 MCP 权限,否则交互工具不可用。
2.2 用 list-devices 获取目标设备
- 调用
list-devices获取目标 id,结果带platform标签(ios或android),已启动/就绪的设备排在前面; - 选择第一个匹配所需平台的条目即可;
- 如果没有任何就绪设备,调用
boot-device:iOS 传udid,Android 传avdName。
完整的启动流程分别见 argent-ios-simulator-setup(iOS 侧:list-devices过滤platform: "ios",无就绪设备则boot-device传 UDID)与 argent-android-emulator-setup(Android 侧:需要 PATH 上有adb与emulator,通过adb version与emulator -list-avds验证,就绪设备state: "device"排在前面,无就绪设备则按avds列表中的名字调用boot-device)。
2.3 首次使用前务必加载工具 schema
手势工具(gesture-tap、gesture-swipe、gesture-pinch、gesture-rotate、gesture-custom)的 schema 可能采用延迟加载——它们的参数 schema 在主动获取前并未加载。因此在调用任何手势工具之前,必须先用 ToolSearch 加载所有计划使用的手势工具 schema。如果跳过这一步,参数可能被强制转换为字符串而不是数字,从而引发校验错误(validation errors)。
3. 最佳实践清单
原文档第 2 节给出了六条核心实践原则,直接决定交互的可靠性与效率:
- 点击前必查 tapping_rule:始终参考
argent.md规则文件中的tapping_rule再执行点击。 - 优先考虑顺序分派:执行交互前,先判断动作是否可以拆成多步序列一次性下发,更多细节见第 9 章
run-sequence。 - 列表滚动用
gesture-swipe而非gesture-custom:除非需要非线性移动;如果需要多次滑动,优先使用run-sequence批处理。 - 输入文本前先点击文本框:iOS 上先尝试
paste,失败再回退keyboard;Android 直接使用keyboard(paste仅限 iOS)。 - 坐标一律归一化:始终使用 0.0–1.0 的归一化坐标,而不是像素。
- 原生 iOS 应用导航优先
describe:describe无需重启应用即可在任何界面工作;常规应用内页面不要靠截图来导航,除非describe无法暴露可靠目标;只有需要应用级 UIKit 属性时才使用native-describe-screen。
4. 打开应用:launch-app 与 open-url
核心规则:永远不要通过点击桌面图标来导航到应用。使用launch-app或open-url,它们瞬时且可靠。
launch-app — 按 bundle ID 启动
{ "udid": "<UDID>", "bundleId": "com.apple.MobileSMS" }常用 bundle ID:
| 应用 | bundleId |
|---|---|
| 信息(Messages) | com.apple.MobileSMS |
| Safari | com.apple.mobilesafari |
| 设置(Settings) | com.apple.Preferences |
| 地图 | com.apple.Maps |
| 照片 | com.apple.Photos |
| 邮件 | com.apple.mobilemail |
| 备忘录 | com.apple.mobilenotes |
| 通讯录 | com.apple.MobileAddressBook |
open-url — 按 URL scheme 打开
{ "udid": "<UDID>", "url": "messages://" }常用 scheme:messages://、settings://、maps://?q=<query>、tel://<number>、mailto:<address>、https://...(在 Safari 中打开)。
对于本仓库的 React Native 移动端应用,launch-app接受 UDID/设备 id 与 bundle ID(iOS)或包名(Android),参见 argent-react-native-app-workflow 第 3.5 节设备控制表;open-url还承担 deep link 测试职责,例如验证钱包连接、兑换页等业务深链,这一点在 argent-create-flow 中被反复强调——深链比点击序列对布局变化更鲁棒。
5. 工具选择速查表
原文档第 4 节提供了一张完整的“动作 → 工具”映射表,这是任何交互任务的第一步决策依据:
| 动作 | 工具 | 说明 |
|---|---|---|
| 多个动作 | run-sequence | 一次调用批量执行步骤(无中间截图) |
| 打开应用 | launch-app | 总是用它——绝不点击桌面图标 |
| 重启应用 | restart-app | 按 bundle ID 终止并重新启动 |
| 打开 URL/scheme | open-url | 网页、deep link、URL scheme |
| 单击 | gesture-tap | 按钮、链接、复选框 |
| 滚动/滑动 | gesture-swipe | 直线滚动或滑动 |
| 长按 | gesture-custom | 上下文菜单、拖拽起点 |
| 拖放 | gesture-custom | 复杂拖拽交互 |
| 捏合/缩放 | gesture-pinch | 双指捏合,自动插值 |
| 旋转 | gesture-rotate | 双指旋转,自动插值 |
| 自定义手势 | gesture-custom | 任意触摸序列,可选插值 |
| 硬件按键 | button | home、back、power、volume、appSwitch、actionButton |
| 快速输入文本 | paste | 仅 iOS。表单字段——使用剪贴板 |
| 输入文本 | keyboard | iOS+Android。paste 失败时的回退;支持 Enter、Escape、方向键 |
| 旋转设备 | rotate | 改变屏幕方向 |
6. 发现点击目标:describe 家族与备选策略
核心规则:当动作执行后切换到不同屏幕、或不知道组件坐标时,务必先做正式的目标发现(discovery),不要凭截图盲猜。
6.1 发现工具矩阵
| 应用类型 | 发现工具 | 返回内容 |
|---|---|---|
| 目标应用通用发现 | describe | 当前设备屏幕的可访问性元素树(iOS AX-service 或 Android uiautomator),带归一化 frame 坐标。适用于任意应用、系统对话框与主屏幕——无需应用重启,也无需bundleId |
| React Native | debugger-component-tree | React 组件树,含名称、文本、testID 与(tap: x,y)坐标 |
| 应用级原生 | native-describe-screen | 应用级可访问性元素的低层视图,含归一化与原始坐标;需要bundleId |
| 权限/系统模态浮层 | describe | describe会自动检测系统对话框并返回带点击坐标的对话框按钮;只有describe无法暴露控件时才回退screenshot |
| 最终视觉回退 | screenshot | 仅当发现工具无法可靠检查当前 UI 时使用;不要从截图中推导常规应用内导航目标 |
在已经获得候选坐标点之后,如果需要进一步的原生诊断,可使用两个点位级工具:
native-user-interactable-view-at-point:已知原始 iOS 坐标点上、实际会接收触摸的最深原生视图;需要bundleId;native-view-at-point:已知原始 iOS 坐标点上、视觉上最深的原生视图;需要bundleId。
两者的区别在于前者是 hit-test 命中目标,后者是视觉最深层视图。
对于 React Native 应用,argent-metro-debugger 进一步补充:debugger-component-tree用于“屏幕上有什么、在哪里”的布局总览与点击目标发现;debugger-inspect-element则用逻辑像素坐标(注意:不是归一化 0–1)在 (x, y) 处定位组件,并回溯源文件文件:行号与代码片段——适用于“这个组件是什么、在哪里定义的”。在 Android 上使用这些调试器工具前,必须先执行adb -s <serial> reverse tcp:8081 tcp:8081让设备能访问宿主机上的 Metro。
6.2 describe 失败时的诊断路径
原文档要求:读精确的错误信息,然后选择与之匹配的动作:
- 错误提及
ax-service不可用或 daemon 启动失败:ax-service daemon 无法启动,检查模拟器是否已启动。临时回退用screenshot;若应用注入了原生 devtools,也可用带显式bundleId的native-describe-screen。 describe返回空元素列表:屏幕可能空白、正在加载、或显示无可访问性标签的内容。用screenshot查看可见内容,内容加载后重试。describe成功但对 React Native 应用不够详细:改用debugger-component-tree。- 需要带完整 UIKit 属性(
accessibilityIdentifier、viewClassName)的应用级检查:用带显式bundleId的native-describe-screen。这需要原生 devtools(dylib)注入——必要时先调用restart-app。 - 已有候选坐标点、想确认实际会接收触摸的视图:用
native-user-interactable-view-at-point;想看视觉最深层视图则用native-view-at-point。
7. 手势与输入工具详解
所有手势工具的坐标、距离、半径均为归一化 0.0–1.0(屏幕宽/高的比例,而非像素),这是全家族统一的空间约定,参考文件 references/gesture-examples.md 同样强调这一点。
7.1 gesture-tap — 单点单击
{ "udid": "<UDID>", "x": 0.5, "y": 0.5 }坐标约定:0.0= 左/上,1.0= 右/下。
RN 应用特例:在 React Native 应用中点击屏幕底部附近之前,先检查是否有 “Open Debugger to View Warnings” 横幅可见——点击它会断开调试器连接。若存在,先用 X 图标关闭。
7.2 gesture-swipe — 直线手势
{ "udid": "<UDID>", "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 }方向语义:向上滑(fromY > toY)= 内容向下滚动。默认时长 300ms;可选"durationMs": 500放慢速度。
7.3 gesture-pinch — 双指捏合
{ "udid": "<UDID>", "centerX": 0.5, "centerY": 0.5, "startDistance": 0.2, "endDistance": 0.6 }所有值均为归一化 0.0–1.0(屏幕比例,非像素),与所有手势工具一致。startDistance: 0.2表示双指起始相距屏幕的 20%,endDistance: 0.6表示结束时相距 60%。方向语义:startDistance < endDistance= 捏合展开(放大 zoom in);startDistance > endDistance= 捏合收拢(缩小 zoom out)。默认值:angle: 0(水平轴)、durationMs: 300;可选"angle": 90切换垂直轴、"durationMs": 500放慢速度。
references/gesture-examples.md 补充了纵向捏合示例:angle: 90时使用相同的startDistance/endDistance语义。
7.4 gesture-rotate — 双指旋转
{ "udid": "<UDID>", "centerX": 0.5, "centerY": 0.5, "radius": 0.15, "startAngle": 0, "endAngle": 90 }所有位置与半径均为归一化 0.0–1.0。radius: 0.15表示每根手指距中心为屏幕尺寸的 15%。方向语义:endAngle > startAngle= 顺时针。默认时长 300ms;可选"durationMs": 500放慢。逆时针 45 度示例见参考文件:startAngle: 0, endAngle: -45。
7.5 gesture-custom — 自定义触摸序列
用于长按、拖放及其它复杂序列。设置"interpolate": 10可自动在关键帧之间生成平滑的中间 Move 事件。参考文件 references/gesture-examples.md 提供了三种典型场景:
长按(800ms 保持):
{ "udid": "<UDID>", "events": [ { "type": "Down", "x": 0.5, "y": 0.5 }, { "type": "Up", "x": 0.5, "y": 0.5, "delayMs": 800 } ] }手动 pinch out(无插值):
{ "udid": "<UDID>", "events": [ { "type": "Down", "x": 0.4, "y": 0.5, "x2": 0.6, "y2": 0.5 }, { "type": "Move", "x": 0.2, "y": 0.5, "x2": 0.8, "y2": 0.5 }, { "type": "Up", "x": 0.2, "y": 0.5, "x2": 0.8, "y2": 0.5 } ] }带插值的平滑 pinch out(interpolate: 15):
{ "udid": "<UDID>", "events": [ { "type": "Down", "x": 0.4, "y": 0.5, "x2": 0.6, "y2": 0.5 }, { "type": "Up", "x": 0.2, "y": 0.5, "x2": 0.8, "y2": 0.5 } ], "interpolate": 15 }拖放(Drag and Drop):
{ "udid": "<UDID>", "events": [ { "type": "Down", "x": 0.3, "y": 0.4 }, { "type": "Move", "x": 0.3, "y": 0.4, "delayMs": 500 }, { "type": "Move", "x": 0.7, "y": 0.6 }, { "type": "Up", "x": 0.7, "y": 0.6 } ] }参考文件特别提示:在第一个Move上加delayMs可以模拟拖拽前的持续按压——部分拖放实现只在持续按压激活后才响应。
7.6 button — 硬件按键
{ "udid": "<UDID>", "button": "home" }可选值:home、back、power、volumeUp、volumeDown、appSwitch、actionButton。
7.7 paste — 向聚焦字段输入文本(仅 iOS)
{ "udid": "<UDID>", "text": "Hello, world!" }先点击字段,再 paste;不生效时回退keyboard。在 Android 上该调用会被能力门禁拒绝(错误信息为 “Tool 'paste' is not supported on android”),应直接使用keyboard。
7.8 keyboard — 输入文本或特殊按键
{ "udid": "<UDID>", "text": "search query", "key": "enter" }特殊按键:enter、escape、backspace、tab、space、arrow-up、arrow-down、arrow-left、arrow-right、f1–f12。可选"delayMs": 100控制按键间隔(默认 50ms)。
7.9 rotate — 改变屏幕方向
{ "udid": "<UDID>", "orientation": "LandscapeLeft" }可选值:Portrait、LandscapeLeft、LandscapeRight、PortraitUpsideDown。
8. 截图策略与 Troubleshooting
8.1 何时使用显式 screenshot 工具
只有在以下场景才使用显式screenshot工具:
- 需要在任何动作之前获取初始屏幕状态;
- 自动附带的截图显示的是过渡帧或加载帧;
- 需要额外上下文;
- 需要在延迟后检查状态(例如等待网络响应);
- 出现了权限对话框、系统弹窗或原生模态浮层,且
describe未暴露可靠目标。
使用screenshot处理权限或原生模态导航时:
- 不要因为看到模态框就切换到截图驱动导航——常规应用页面与应用内模态仍应使用
describe; - 优先点击居中的明显弹窗按钮,如
Allow、OK、Don't Allow、Not Now、Continue; - 每次只点击一个控件,并在进行下一步之前检查返回的自动截图;
- 模态关闭后,回到
describe、native-describe-screen或debugger-component-tree进行正常发现。
可选旋转参数{ "udid": "<UDID>", "rotation": "LandscapeLeft" }可以在不改变模拟器方向的情况下旋转截图。
8.2 分辨率与缩放
截图默认按原分辨率 30% 降采样以减小上下文体积。scale接受 0.01 到 1.0。若 UI 元素难以辨认或需要检查细节,传scale: 1.0获取全分辨率:
{ "udid": "<UDID>", "scale": 1.0 }8.3 Troubleshooting 对照表
| 问题 | 解决方案 |
|---|---|
| 截图超时 | 通过stop-simulator-server工具重启 simulator-server |
| 没有已启动的 iOS 模拟器 | 用 iOSudid调用boot-device |
| 没有就绪的 Android 设备 | 用avdName调用boot-device |
9. run-sequence:多步动作序列化
9.1 设计目标与适用场景
run-sequence将多个交互步骤批量放入一次工具调用,全部步骤完成后只返回一张截图。适用场景:
- 多次滚动、自动输入并提交;
- 已知的多步点击序列;
- 来回旋转设备。
关键约束:当任何一步需要观察前一步的结果才能继续时,不要使用run-sequence。使用场景判断:
- 已知某个动作需要多步且无需即时查看截图——“滚动到底部/顶部/滚动到 X”时连续滚动 3–5 次;
- 表单交互——“清空并重输字段”可以用三连击全选后输入新值;
- “提交表单”→ 按顺序填完所有字段后点击提交;
- “返回 X”→ 定义好的导航点击序列。
9.2 允许在序列内使用的工具
gesture-tap、gesture-swipe、gesture-custom、gesture-pinch、gesture-rotate、button、keyboard、rotate。
udid是共享的——不要在每一步的args里重复包含。每步可选delayMs(默认 100ms)。
9.3 示例
连续向下滚动三次:
{ "udid": "<UDID>", "steps": [ { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }, { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }, { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } } ] }向聚焦字段输入并提交:
{ "udid": "<UDID>", "steps": [ { "tool": "keyboard", "args": { "text": "hello world" } }, { "tool": "keyboard", "args": { "key": "enter" } } ] }点击已知按钮后向下滚动(第二步行前等待 300ms):
{ "udid": "<UDID>", "steps": [ { "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.15 } }, { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 }, "delayMs": 300 } ] }序列在首个错误处停止,并返回部分结果。
10. 平台专属注意事项:Android 与 iOS
10.1 Android
- Metro 可达性:在 RN 应用启动前,在设备上执行
adb reverse tcp:8081 tcp:8081,否则 Metro 无法从设备访问;完整工作流见 argent-metro-debugger。设备重启后需重新执行。 - 首次启动权限弹窗:Android 上
reinstall-app总是以-g安装,因此运行时权限在首次启动时已预授权,无需传额外标志(argent-android-emulator-setup 第 4 节同样确认了这一点)。 - 锁屏/安全界面:
describe在无法捕获时(keyguard、DRM、Play Integrity)会抛出明确错误;解锁设备或回退到screenshot。 reinstall-app的 APK 与 .app:Android 上传.apk绝对路径;iOS 上传.app目录。
10.2 iOS
原文档当前 iOS 专属坑点尚未收集(“add them as they come up”),可从 iOS 侧文档确认的基本事实包括:UDID 形态为 UUID(如A1B2C3D4-E5F6-7890-ABCD-EF1234567890);iOS 模拟器默认通过 localhost 访问同机 Metro,无需额外反向端口配置;交互工具会在未运行时自动启动服务端(argent-ios-simulator-setup)。
11. 生态联动:从交互到 UI 测试与流程回放
argent-device-interact不是孤立工具集,它与本仓库其他技能构成完整闭环:
- argent-test-ui-flow:将交互工具嵌入“截图基线 → 发现目标 → 交互 → 截图验证”的循环中,可自动执行登录、导航等端到端 UI 场景。其核心模板为:
screenshot看当前状态 → 导航/点击/输入并验证自动截图 → 执行待测动作并验证 → 报告 pass/fail。 - argent-create-flow:把验证过的交互序列录制为
.yaml流程文件(存于.argent/flows/),之后用一次flow-execute调用即可回放。录制时flow-add-step中的args必须是JSON 字符串而非对象,例如args: "{\"udid\": \"<UDID>\", \"x\": 0.5, \"y\": 0.35}"。该技能还定义了坐标漂移、元素缺失、时机、状态不匹配等故障分类与修复策略,回放失败时按“编辑 YAML → 手动恢复 → 断点重录 → 全量重录”的决策启发式处理。 - argent-react-native-app-workflow:覆盖 Metro 启动、应用构建/安装、设备控制(
list-devices、boot-device、launch-app、restart-app、open-url、rotate、stop-simulator-server)以及 release 变体验证时的陈旧代码陷阱。
12. 与 Uniswap mobile 工程的对接要点
在本仓库中,上述交互技能的服务对象主要是 apps/mobile(React Native,Expo 56 / React Native 0.85.3,见 apps/mobile/package.json)以及 apps/web 等前端应用。对接时注意:
- 构建与启动命令优先走工程自定义脚本:argent-react-native-app-workflow 强调不要默认
npx react-native start,本仓库移动端统一通过bun mobile start启动 Metro、bun mobile ios/bun mobile android运行应用(脚本定义见 apps/mobile/package.json)。 - Android 本地 release 验证:
bun mobile android:<flavor>:release:local走 apps/mobile/scripts/runAndroidLocal.sh,它会处理两层“陈旧代码”陷阱——导出EXPO_LOCAL_NO_BUILD_CACHE=1关闭 apps/mobile/app.config.ts 中的 EAS 构建缓存,并清理 gradlecreateBundle<Variant>JsAndAssets的 UP-TO-DATE 增量产物,确保 APK 内嵌的是最新 JS bundle。交互验证前应确认这是否符合你的验证目标。 - 权限与模态处理:首次启动或登录等流程常出现系统权限弹窗(如通知、相机、剪贴板),按本文第 8 章策略处理:先
describe,暴露不了再screenshot回退,点击Allow类按钮后立即回归describe。
综上,argent-device-interact提供了一套平台无关、坐标归一化、可序列化、可回放的设备交互原语,是本仓库 Agent 在 iOS 模拟器与 Android 模拟器上进行 UI 操作、导航与验证的统一入口。
- 区块链
- DeFi
- 前端
- 移动开发
【免费下载链接】interface
🦄 Open source interfaces for the Uniswap protocol
相关推荐
argent-create-flow 技能实战:在 Uniswap interface 仓库中录制与回放可复用的模拟器操作流(Flow)
argent create flow 技能实战:在 Uniswap interface 仓库中录制与回放可复用的模拟器操作流(Flow) 导读 argent c
区块链DeFi前端移动开发interface 项目 Android 模拟器接入指南:基于 argent MCP 工具的设备启动、连接与自动化交互
interface 项目 Android 模拟器接入指南:基于 argent MCP 工具的设备启动、连接与自动化交互 本文面向在 Uniswap interf
区块链DeFi前端移动开发FlashList 模拟器自动化交互实战:基于 agent-device 快照坐标的 iOS/Android 设备操控指南
FlashList 模拟器自动化交互实战:基于 agent device 快照坐标的 iOS/Android 设备操控指南 本篇技术指南聚焦 flash lis
移动开发UI组件跨平台
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考