@mobileaidev/ai-app-bridge 0.2.15 → 0.3.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +7 -0
- package/README.md +306 -53
- package/bin/ai-app-bridge.js +51 -4504
- package/bin/android-permissions.js +152 -0
- package/bin/android-uia-xml.js +74 -0
- package/bin/artifact-paths.js +127 -1
- package/bin/bridge-forward.js +56 -0
- package/bin/command-discovery.js +86 -0
- package/bin/command-errors.js +60 -0
- package/bin/command-registry.js +504 -0
- package/bin/command-request.js +14 -0
- package/bin/command-router.js +80 -0
- package/bin/connection-cache.js +119 -0
- package/bin/device-provider.js +2934 -0
- package/bin/execution-host.js +596 -0
- package/bin/execution-runtime.js +101 -0
- package/bin/fact-codec.js +321 -0
- package/bin/fact-recorder.js +691 -0
- package/bin/fact-store.js +226 -0
- package/bin/feedback-probe.js +285 -0
- package/bin/intent/install-intent.js +267 -0
- package/bin/intent/intent-action-executor.js +129 -0
- package/bin/intent/intent-autonomous-adapter.js +46 -0
- package/bin/intent/intent-capture-port.js +64 -0
- package/bin/intent/intent-entry.js +226 -0
- package/bin/intent/intent-errors.js +28 -0
- package/bin/intent/intent-evidence-store.js +121 -0
- package/bin/intent/intent-lifetime.js +62 -0
- package/bin/intent/intent-observation-target.js +33 -0
- package/bin/intent/intent-observer.js +194 -0
- package/bin/intent/intent-production-adapter.js +334 -0
- package/bin/intent/intent-provider.js +27 -0
- package/bin/intent/intent-runtime.js +63 -0
- package/bin/intent/intent-worker.js +432 -0
- package/bin/intent/ios-intent-adapter.js +90 -0
- package/bin/intent/permission-intent.js +239 -0
- package/bin/intent/web-intent-adapter.js +31 -0
- package/bin/ios-device-outcome.js +47 -0
- package/bin/ios-execution.js +108 -0
- package/bin/ios-provider.js +497 -583
- package/bin/ios-runtime-binding.js +54 -0
- package/bin/ios-wda-execution.js +70 -0
- package/bin/ios-wda-port.js +98 -0
- package/bin/ios-wda-project.js +79 -0
- package/bin/mcp-server.js +83 -1040
- package/bin/mmap-scan-index.js +329 -0
- package/bin/observation-collector.js +862 -0
- package/bin/runtime-client.js +154 -0
- package/bin/runtime-directory.js +107 -0
- package/bin/runtime-protocol.js +36 -0
- package/bin/script/bounded-script-registry.js +103 -0
- package/bin/script/node-runtime-adapter.js +233 -0
- package/bin/script/progress-projector.js +63 -0
- package/bin/script/python-runtime-adapter.js +111 -0
- package/bin/script/rolling-summary.js +134 -0
- package/bin/script/script-agent-port.js +40 -0
- package/bin/script/script-assert.js +95 -0
- package/bin/script/script-capture-port.js +76 -0
- package/bin/script/script-catalog.js +85 -0
- package/bin/script/script-durable-restore.js +195 -0
- package/bin/script/script-entry-code.js +26 -0
- package/bin/script/script-entry-route.js +38 -0
- package/bin/script/script-entry.js +3 -0
- package/bin/script/script-errors.js +29 -0
- package/bin/script/script-evidence-store.js +22 -0
- package/bin/script/script-format-removed.js +26 -0
- package/bin/script/script-host-port.js +397 -0
- package/bin/script/script-ledger.js +64 -0
- package/bin/script/script-result.js +57 -0
- package/bin/script/script-sdk.js +152 -0
- package/bin/script/script-sdk.py +153 -0
- package/bin/script/script-session-channel.js +127 -0
- package/bin/script/script-spec.js +86 -0
- package/bin/script/script-supervisor.js +919 -0
- package/bin/script/templates/checkpoint-reentry.js +13 -0
- package/bin/segment-index.js +481 -0
- package/bin/segmented-fact-store.js +1571 -0
- package/bin/shared-kernel/android-h5-target.js +10 -0
- package/bin/shared-kernel/android-install-execution.js +176 -0
- package/bin/shared-kernel/android-sdk-endpoint.js +42 -0
- package/bin/shared-kernel/android-shell-execution.js +195 -0
- package/bin/shared-kernel/argument-schema.js +117 -0
- package/bin/shared-kernel/canonical-path.js +17 -0
- package/bin/shared-kernel/device-acknowledgements.js +53 -0
- package/bin/shared-kernel/device-completion-history.js +52 -0
- package/bin/shared-kernel/device-mutation-lease.js +219 -0
- package/bin/shared-kernel/device-ownership-recovery.js +95 -0
- package/bin/shared-kernel/device-ownership-store.js +94 -0
- package/bin/shared-kernel/evidence-adapters.js +251 -0
- package/bin/shared-kernel/evidence-archive.js +329 -0
- package/bin/shared-kernel/evidence-recording.js +131 -0
- package/bin/shared-kernel/evidence-schema.js +194 -0
- package/bin/shared-kernel/evidence-store.js +190 -0
- package/bin/shared-kernel/execution-admission.js +22 -0
- package/bin/shared-kernel/execution-contracts.js +171 -0
- package/bin/shared-kernel/execution-io.js +106 -0
- package/bin/shared-kernel/execution-ledger.js +125 -0
- package/bin/shared-kernel/execution-scope.js +87 -0
- package/bin/shared-kernel/execution-target.js +115 -0
- package/bin/shared-kernel/flutter-execution.js +13 -0
- package/bin/shared-kernel/flutter-h5-port.js +60 -0
- package/bin/shared-kernel/flutter-h5-target.js +9 -0
- package/bin/shared-kernel/flutter-target.js +75 -0
- package/bin/shared-kernel/h5-execution.js +11 -0
- package/bin/shared-kernel/h5-target.js +31 -0
- package/bin/shared-kernel/host-fact-store.js +49 -0
- package/bin/shared-kernel/ios-h5-target.js +9 -0
- package/bin/shared-kernel/ios-native-target.js +71 -0
- package/bin/shared-kernel/live-capture-query.js +115 -0
- package/bin/shared-kernel/managed-sdk-execution.js +78 -0
- package/bin/shared-kernel/native-execution.js +13 -0
- package/bin/shared-kernel/native-target.js +156 -0
- package/bin/shared-kernel/provider-command-contracts.js +55 -0
- package/bin/shared-kernel/recorded-payload-archive.js +195 -0
- package/bin/shared-kernel/request-context.js +35 -0
- package/bin/shared-kernel/semantic-node.js +55 -0
- package/bin/shared-kernel/summary-transformer.js +352 -0
- package/bin/shared-kernel/target-lease-protocol.js +47 -0
- package/bin/shared-kernel/text-wait.js +111 -0
- package/bin/shared-kernel/uia-execution.js +96 -0
- package/bin/shared-kernel/uia-protocol.js +214 -0
- package/bin/shared-kernel/uia-runtime-port.js +377 -0
- package/bin/shared-kernel/uia-target.js +39 -0
- package/bin/shared-kernel/web-dom-target.js +44 -0
- package/bin/shared-kernel/xml-attributes.js +25 -0
- package/bin/target-execution.js +275 -0
- package/bin/web/command-schema.js +60 -0
- package/bin/web/session-store.js +157 -0
- package/bin/web-provider.js +334 -553
- package/docs/COMMAND_CONTRACT.md +1563 -0
- package/docs/EVIDENCE_ARCHIVE.md +214 -0
- package/docs/INTENT_FOREGROUND.md +71 -0
- package/docs/INTENT_NATIVE_EDITING.md +79 -0
- package/docs/RELEASE.md +59 -0
- package/docs/SCRIPT_AUTHORING.md +489 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/LICENSE +201 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/NOTICE +7 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/binding.gyp +36 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/bindings/node/sfs_node.c +597 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/include/sfs.h +178 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/index.js +5 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/package.json +24 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/src/sfs.c +2349 -0
- package/package.json +60 -5
- package/runtime/ios-wda/AABWDABinding.h +19 -0
- package/runtime/ios-wda/AABWDABinding.m +97 -0
- package/runtime/ios-wda/AABWDAExecution.h +26 -0
- package/runtime/ios-wda/AABWDAExecution.m +172 -0
- package/runtime/ios-wda/AABWDAIntegration.h +71 -0
- package/runtime/ios-wda/AABWDAManagedRoutes.h +392 -0
- package/runtime/ios-wda/AABWDAReceiptStore.h +10 -0
- package/runtime/ios-wda/AABWDAReceiptStore.m +116 -0
- package/runtime/uia/ai-app-bridge-uia.jar +0 -0
- package/runtime/uia/manifest.json +22 -0
- package/skills/ai-app-bridge-use/SKILL.md +23 -360
|
@@ -1,385 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ai-app-bridge-use
|
|
3
|
-
description:
|
|
3
|
+
description: 通过 AI App Bridge 实际观察、操作和验证 App 时使用。用 Intent 进行观察与决策,用 Script 进行重复回归,用共享命令进行单次操作和诊断,并通过当前 MCP capabilities 核对参数与平台范围。开发 Bridge 本身时,以当前源码和命令合同为准。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# AI App Bridge Use
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 选择执行方式
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Intent 和 Script 是一等执行入口。日常页面操作、未知流程和系统窗口交互使用 Intent 的观察与决策合同;固定流程使用 JavaScript/Python Script。单次观察、动作、安装、权限夹具和诊断命令同样有独立价值。
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
1. 从任务、构建产物和设备状态确定目标。Android 动作明确传 `serial`,App 操作传 `packageName`;iOS 使用 `deviceId`/`bundleId`,Native Intent 还需绑定 `wdaRunnerBundleId`/`wdaSessionId`;Web 使用当前文档的 `sessionId`/`runtimeEpoch`/`targetId`。
|
|
13
|
+
2. 调用 `capabilities` 查询本次实际运行版本的命令。指定 `command` 时返回完整 `inputSchema`、`role`、`entrypoints` 和 Script 能力声明。先核对平台与参数,再派发。
|
|
14
|
+
3. MCP 只有 `capabilities` 和 `run`。所有命令参数放在 `run.arguments`,命令名使用 capabilities 原样返回的名称。JSON 数字、布尔值不写成字符串。Intent/Script/evidence 必须明确 operation;嵌套控制参数也以当前 inputSchema 为准,错误中的 field 指向需修正的字段。
|
|
15
|
+
4. 从当前观察取得 selector 或坐标。`tap-text` 的 `provider:auto` 按 Native、Flutter、UIAutomator 顺序观察并选择一次动作;`provider:native|flutter|uia` 可固定回归来源。结果中的 observations/provider 说明选择依据。动作前会重新定位,多重匹配、语义身份或前台变化应重新观察。UIA 同名控件可用当前 `uia-tree` 的完整 `targetRef`,或当前 Intent revision 的 `selector.nodeRef`;引用失效后重新观察。Native 前台弹窗会阻挡后台 Flutter 文字动作。
|
|
16
|
+
5. 按任务的真实结果验证。执行完成、机械动作成功、UI 变化、业务状态和证据覆盖分别判断;操作后使用本轮新证据。没有足够证据的断言保留为 inconclusive。
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
命令域:
|
|
17
|
-
- `core`: `status`/`tree`/`uia-tree`/`screenshot`/`logs`/`network`/`state`/`events`
|
|
18
|
-
- `app`: `install-apk`/`clear-app-data`/`launch-*`/`freeze-app`/`thaw-app`/`permission-*`/`appops-set`
|
|
19
|
-
- `action`: `tap`/`tap-text`/`tap-uia-text`/`input-text`/`swipe`/`keyevent`/`wait-text`/`keyboard-*`
|
|
20
|
-
- `flutter`: `flutter-tree`/`flutter-nodes`/`flutter-action`/`tap-flutter-text`/`input-flutter-text`/`scroll-flutter`
|
|
21
|
-
- `webview`: `h5-*`/`flutter-h5-*`/`webview-pages`/`webview-network`/`webview-console`
|
|
22
|
-
- `ios`: `ios-devices`/`ios-doctor`/`ios-setup`/`ios-status`/`ios-tree`/`ios-uia-tree`/`ios-tap`/`ios-input`/`ios-swipe`/`ios-h5-*`/`ios-flutter-*`
|
|
23
|
-
- `web`: `web-session-start`/`web-sessions`/`web-status`/`web-dom`/`web-logs`/`web-network`/`web-state`/`web-events`/`web-command`/`web-click`/`web-input`/`web-wait`/`web-scroll`
|
|
24
|
-
- `diagnostics`/`advanced`: `logcat`/`smoke`/`batch`/`forward`/`remove-forward`
|
|
25
|
-
|
|
26
|
-
## Agent 快速流程
|
|
27
|
-
|
|
28
|
-
1. 确认目标:Android 使用 `packageName`,iOS 使用 `bundleId`,真机多设备场景传 `deviceId`/UDID;Web 使用 `sessionId`,多 target 时加 `targetId`。没有目标 id 时先从上下文、构建配置或前台 app/session 线索推断。面向具体 app/session 的命令必须传目标 id,只有无法发现 bridge 端口时才传 `port`、`runtimeUrl` 或先启动 Web session。
|
|
29
|
-
2. 发现能力:默认 MCP surface 只有 `capabilities` 和 `run`。不确定命令或参数时先调用 `capabilities`,再用 `run` 执行。
|
|
30
|
-
3. 选择命令路径:按任务类型选 `core`、`app`、`action`、`flutter`、`webview`、`ios`、`web`、`diagnostics` 或 `advanced` 域;不要先退回原始 `adb`、浏览器脚本或坐标猜测。
|
|
31
|
-
4. 用 `batch` 串联相关步骤:观察、操作、等待、截图、tree 验证尽量放进一次 MCP 调用。
|
|
32
|
-
5. 验证可见结果:界面变化必须用 `screenshot` 加 `tree`/`uia-tree` 交叉确认。
|
|
33
|
-
6. 生成截图等默认产物时,让 AI Bridge 自动选择会被当前项目 git 忽略的目录;只有确实需要固定路径时才传 `outFile`/`artifactDir`,且路径必须在 `build`、`.build`、`.dart_tool`、`node_modules/.cache`、`target` 或其他已忽略目录内。
|
|
34
|
-
7. 只在需要稳定动态画面时使用 `freeze-app`/`thaw-app`;如果本轮冻结过 app,最终回复前必须解冻。
|
|
35
|
-
|
|
36
|
-
## 能力发现和调用
|
|
37
|
-
|
|
38
|
-
`capabilities` 用来列出命令域和参数:
|
|
39
|
-
|
|
40
|
-
```json
|
|
41
|
-
{ "domain": "webview", "includeOptions": true }
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
```json
|
|
45
|
-
{ "command": "input-text", "includeOptions": true }
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
`run` 用 CLI 形式的命令名执行能力,例如:
|
|
49
|
-
|
|
50
|
-
```json
|
|
51
|
-
{
|
|
52
|
-
"command": "screenshot",
|
|
53
|
-
"packageName": "com.example.app"
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
如果 MCP 暴露的是 full/legacy surface,直接工具名通常用下划线形式;语义与 `run` 里的连字符命令一致,例如 `tap_text` 对应 `tap-text`。
|
|
58
|
-
|
|
59
|
-
## 任务路由
|
|
60
|
-
|
|
61
|
-
| 任务 | 首选命令 |
|
|
62
|
-
| --- | --- |
|
|
63
|
-
| 当前 app 状态和桥接信息 | `status` |
|
|
64
|
-
| 真实可见画面 | `screenshot` |
|
|
65
|
-
| App 内 View 节点 | `tree`,常配 `compact`、`visibleOnly` |
|
|
66
|
-
| 系统窗口、权限弹窗、Compose/跨 app UI | `uia-tree`、`tap-uia-text` |
|
|
67
|
-
| 点击、输入、等待、滑动、按键 | `tap-text`、`tap`、`input-text`、`wait-text`、`swipe`、`keyevent` |
|
|
68
|
-
| 键盘处理 | `keyboard-state`、`hide-keyboard` |
|
|
69
|
-
| 安装、启动、清数据 | `install-apk`、`launch-app`、`launch-activity`、`clear-app-data` |
|
|
70
|
-
| 权限和 appops | `permission-state`、`permission-grant`、`permission-revoke`、`permission-dialog`、`appops-set` |
|
|
71
|
-
| Flutter UI 和动作 | `flutter-tree`、`flutter-nodes`、`tap-flutter-text`、`input-flutter-text`、`scroll-flutter`、`flutter-action` |
|
|
72
|
-
| 原生 WebView DOM | `h5-dom`、`h5-click`、`h5-input`、`h5-wait`、`h5-scroll` |
|
|
73
|
-
| Flutter H5 adapter | `flutter-h5-dom`、`flutter-h5-click`、`flutter-h5-input`、`flutter-h5-wait`、`flutter-h5-scroll` |
|
|
74
|
-
| WebView CDP 网络/控制台 | `webview-pages`、`webview-network`、`webview-console` |
|
|
75
|
-
| App 内记录 | `logs`、`network`、`state`、`events` |
|
|
76
|
-
| Android 日志 | `logcat`,按 `pid`、`appPid`、`tag`、`level`、`grep` 过滤 |
|
|
77
|
-
| iOS 设备/环境检查 | `ios-devices`、`ios-doctor`、`ios-setup` |
|
|
78
|
-
| iOS App 内证据 | `ios-status`、`ios-tree`、`ios-logs`、`ios-network`、`ios-state`、`ios-events`、`ios-h5-dom`、`ios-h5-eval` |
|
|
79
|
-
| iOS 系统级 UI 与动作 | `ios-uia-tree`、`ios-tap`、`ios-input`、`ios-swipe`、`ios-screenshot` |
|
|
80
|
-
| Web Bridge session | `web-provider-status`、`web-session-start`、`web-connect-info`、`web-sessions` |
|
|
81
|
-
| Web DOM 和证据 | `web-status`、`web-dom`、`web-logs`、`web-network`、`web-state`、`web-events` |
|
|
82
|
-
| Web 页面动作 | `web-click`、`web-input`、`web-wait`、`web-scroll`、`web-command` |
|
|
83
|
-
| 自检 | `smoke` |
|
|
84
|
-
| 多步骤串行执行 | `batch` |
|
|
85
|
-
| 动态画面稳定 | `freeze-app`、`thaw-app`,只按需使用 |
|
|
86
|
-
|
|
87
|
-
## 常用模式
|
|
88
|
-
|
|
89
|
-
观察当前界面:
|
|
90
|
-
|
|
91
|
-
```json
|
|
92
|
-
{
|
|
93
|
-
"command": "batch",
|
|
94
|
-
"arguments": {
|
|
95
|
-
"defaults": { "packageName": "com.example.app" },
|
|
96
|
-
"steps": [
|
|
97
|
-
{ "id": "status", "command": "status" },
|
|
98
|
-
{ "id": "shot", "command": "screenshot" },
|
|
99
|
-
{ "id": "tree", "command": "tree", "arguments": { "compact": true, "visibleOnly": true } }
|
|
100
|
-
],
|
|
101
|
-
"stopOnError": true,
|
|
102
|
-
"includeRaw": true
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
点击并验证结果:
|
|
108
|
-
|
|
109
|
-
```json
|
|
110
|
-
{
|
|
111
|
-
"command": "batch",
|
|
112
|
-
"arguments": {
|
|
113
|
-
"defaults": { "packageName": "com.example.app" },
|
|
114
|
-
"steps": [
|
|
115
|
-
{ "id": "tap", "command": "tap-text", "arguments": { "targetText": "继续" } },
|
|
116
|
-
{ "id": "wait", "command": "wait-text", "arguments": { "targetText": "完成", "timeoutSec": 8 } },
|
|
117
|
-
{ "id": "shot-after", "command": "screenshot" },
|
|
118
|
-
{ "id": "tree-after", "command": "tree", "arguments": { "compact": true, "visibleOnly": true } }
|
|
119
|
-
],
|
|
120
|
-
"stopOnError": true,
|
|
121
|
-
"includeRaw": true
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
输入文本:
|
|
127
|
-
|
|
128
|
-
```json
|
|
129
|
-
{
|
|
130
|
-
"command": "input-text",
|
|
131
|
-
"packageName": "com.example.app",
|
|
132
|
-
"arguments": {
|
|
133
|
-
"text": "中文输入",
|
|
134
|
-
"hideKeyboard": true
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
捕获 WebView 网络:
|
|
140
|
-
|
|
141
|
-
```json
|
|
142
|
-
{
|
|
143
|
-
"command": "webview-network",
|
|
144
|
-
"packageName": "com.example.app",
|
|
145
|
-
"arguments": {
|
|
146
|
-
"durationMs": 3000,
|
|
147
|
-
"urlFilter": "/api/"
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
iOS 观察和操作:
|
|
153
|
-
|
|
154
|
-
```json
|
|
155
|
-
{
|
|
156
|
-
"command": "batch",
|
|
157
|
-
"arguments": {
|
|
158
|
-
"defaults": {
|
|
159
|
-
"deviceId": "00008150-...",
|
|
160
|
-
"bundleId": "com.example.ios"
|
|
161
|
-
},
|
|
162
|
-
"steps": [
|
|
163
|
-
{ "id": "status", "command": "ios-status" },
|
|
164
|
-
{ "id": "tree", "command": "ios-tree" },
|
|
165
|
-
{ "id": "uia", "command": "ios-uia-tree", "arguments": { "wdaUrl": "http://[fd00::1]:8100" } },
|
|
166
|
-
{ "id": "tap", "command": "ios-tap", "arguments": { "wdaUrl": "http://[fd00::1]:8100", "tapX": 160, "tapY": 320 } },
|
|
167
|
-
{ "id": "events", "command": "ios-events" }
|
|
168
|
-
],
|
|
169
|
-
"stopOnError": true,
|
|
170
|
-
"includeRaw": true
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
Web session 启动和连接:
|
|
176
|
-
|
|
177
|
-
```json
|
|
178
|
-
{
|
|
179
|
-
"command": "web-session-start",
|
|
180
|
-
"arguments": {
|
|
181
|
-
"webPort": 18180,
|
|
182
|
-
"token": "session-token"
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
页面调试入口使用 Web SDK 连接:
|
|
188
|
-
|
|
189
|
-
```js
|
|
190
|
-
import { createAiAppBridge } from "@mobileaidev/ai-app-bridge-web";
|
|
191
|
-
|
|
192
|
-
const bridge = createAiAppBridge({
|
|
193
|
-
endpoint: "ws://127.0.0.1:18180/ai-app-bridge-web",
|
|
194
|
-
token: "session-token",
|
|
195
|
-
appName: "demo-web-app",
|
|
196
|
-
capture: { console: true, errors: true, fetch: true, xhr: true, dom: true }
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
bridge.start();
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
Web 观察、操作和验证:
|
|
18
|
+
## 最小调用
|
|
203
19
|
|
|
204
20
|
```json
|
|
205
|
-
{
|
|
206
|
-
"command": "batch",
|
|
207
|
-
"arguments": {
|
|
208
|
-
"defaults": { "sessionId": "web-session-abc123" },
|
|
209
|
-
"steps": [
|
|
210
|
-
{ "id": "status", "command": "web-status" },
|
|
211
|
-
{ "id": "dom", "command": "web-dom", "arguments": { "refresh": true } },
|
|
212
|
-
{ "id": "click", "command": "web-click", "arguments": { "selector": "button[type=submit]" } },
|
|
213
|
-
{ "id": "wait", "command": "web-wait", "arguments": { "targetText": "Saved", "timeoutMs": 5000 } },
|
|
214
|
-
{ "id": "events", "command": "web-events" }
|
|
215
|
-
],
|
|
216
|
-
"stopOnError": true,
|
|
217
|
-
"includeRaw": true
|
|
218
|
-
}
|
|
219
|
-
}
|
|
21
|
+
{"command":"tap-text","arguments":{"serial":"DEVICE","packageName":"com.example.app","targetText":"设置","provider":"auto"}}
|
|
220
22
|
```
|
|
221
23
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
把 `screenshot` 当作当前可见画面的最高优先级证据,把 `tree`/`uia-tree` 当作可操作节点和结构证据。
|
|
225
|
-
|
|
226
|
-
对打开/关闭面板、关闭弹窗、切换页面、点击 tab、进入详情页、展开抽屉、按钮触发内容变化等可见状态变化,必须同时采集截图和 tree。只有二者指向同一状态时,才报告成功。
|
|
227
|
-
|
|
228
|
-
如果截图和 tree 冲突:
|
|
229
|
-
|
|
230
|
-
- 以截图判断用户实际看到什么。
|
|
231
|
-
- 认为 tree 可能包含缓存、不可见节点、过期层或非前台窗口。
|
|
232
|
-
- 重新等待、采集或换用 `uia-tree`、坐标点击、Flutter/WebView 专用命令。
|
|
233
|
-
- 不要把冲突证据包装成确定结论。
|
|
234
|
-
|
|
235
|
-
异步 UI 用 `wait-text` 或 H5/Flutter wait 命令等待;不要用固定 sleep 代替状态判断。
|
|
236
|
-
|
|
237
|
-
## 平台专项
|
|
238
|
-
|
|
239
|
-
iOS:
|
|
240
|
-
|
|
241
|
-
- 完整能力必须同时使用两层:App 内 `AiAppBridgeIOS` runtime 负责结构化证据,WebDriverAgent/XCUITest 负责系统级 tap/input/swipe、权限弹窗、外部 UI tree 和跨 app UI。
|
|
242
|
-
- 首次真机使用先跑 `ios-devices` 和 `ios-doctor`。如果 Developer Mode、DDI、信任、解锁、Xcode Apple team 或 WDA signing 不满足,停下来报告 blocker,不要跳过 WDA 降级成只读模式。
|
|
243
|
-
- WDA 可由 `ios-setup --start-wda --team-id <APPLE_TEAM_ID>` 启动;真机上返回的 WDA URL 可能是 CoreDevice tunnel,例如 `http://[fdxx::1]:8100`,后续 `ios-uia-tree`、`ios-tap`、`ios-input`、`ios-swipe` 都优先复用这个 URL。
|
|
244
|
-
- 文本输入优先用元素目标,例如 `ios-input` 搭配 `accessibilityId` 或 `elementId` 和 `clearFirst`;坐标输入仅用于没有稳定 accessibility id 的控件。
|
|
245
|
-
- Flutter iOS 仍按 Flutter 路径读 widget/action 证据;设备级动作、权限弹窗和外部 UI 仍走 iOS WDA 命令。
|
|
24
|
+
`wait-text` 使用 `timeoutMs`(默认 10000),文字精确匹配;`requireText`/`absentText` 是字符串数组,不接受 CSV。所有条件必须由同一次前台 provider 观察证明。纯消失等待必须明确 `provider`,读取失败不能证明消失。`requireActivity` 是完整类名。Native Intent 输入必须有 SDK `editable:true`。
|
|
246
25
|
|
|
247
|
-
|
|
26
|
+
`tap` 是物理坐标;`tap-flutter` 是 Flutter 逻辑坐标。显式 App 目标必须匹配前台。系统 UI 使用已观察的系统目标与 device scope。已派发但结果未知时,先重新观察,不通过另一个 provider 重试同一动作。
|
|
248
27
|
|
|
249
|
-
|
|
250
|
-
- SDK 只放在 debug/test/client 代码里;SSR 框架必须只在浏览器端初始化,生产环境默认不要启用。
|
|
251
|
-
- 页面连接后先用 `web-sessions` 找 `sessionId`,再用 `web-status`、`web-dom`、`web-logs`、`web-network`、`web-state`、`web-events` 采集证据。
|
|
252
|
-
- 操作页面优先用 `web-command` 调注册过的白名单 action;需要 DOM 操作时用 `web-click`、`web-input`、`web-wait`、`web-scroll`,并传稳定 `selector` 或 `targetText`。
|
|
253
|
-
- 多页面、iframe 或自定义 surface 时传 `targetId`;如果返回 target ambiguous,先读取候选 target 再重试。
|
|
28
|
+
CLI 和 MCP 共用独立执行 Runtime、命令 schema 和 operationId。客户端退出后任务继续运行;用任务 cancel 停止一个任务,或 `runtime operation:stop` 等待全部已拥有工作收尾。更换版本或 Runtime 环境先显式 stop,再启动。详细生命周期见 CLI 包内 `docs/COMMAND_CONTRACT.md`(仓库路径 `desktop/ai-app-bridge-cli/docs/COMMAND_CONTRACT.md`)。
|
|
254
29
|
|
|
255
|
-
|
|
30
|
+
`script` 的 start/status/wait/result/pause/resume/decide/cancel/runtime-status 操作用于连续执行和控制。start 使用 script 及其内部 target,语言明确为 javascript 或 python;调用失败和断言结果由源码处理。status/wait 和完成事件保留小型 resultRef;最终返回值通过 `script operation:result` 加原 operationId 从持久存储读取,核对 representation 和 hash。编写脚本前查询 `capabilities {"command":"script"}`;按需读取 CLI 包内 `docs/SCRIPT_AUTHORING.md`(仓库路径 `desktop/ai-app-bridge-cli/docs/SCRIPT_AUTHORING.md`)。`app.lifecycle` 和 `app.permissions` 是可信调用者为回归夹具显式选择的额外能力。JS/Python 是 trusted-local-code,权限声明不是 OS 沙箱。
|
|
256
31
|
|
|
257
|
-
|
|
258
|
-
- 用 `flutter-nodes` 找可操作节点,用 `scroll-flutter` 处理需要滚动后才出现的文本。
|
|
32
|
+
普通 Android 命令的 timeoutMs 是包括排队和 Provider 调用的同一 Host 预算,默认 30000 ms;不能用内部重试延长。Script 的 policy.timeoutMs 限制整个运行,单个调用只能缩短预算。取消期间状态为 cancelling,已拥有的调用、回执和检查点收尾后才写 cancelled;已提交但未确认的动作仍是 ambiguous,不能宣称撤销成功。安装/权限 Intent、iOS/Web 及等待条件的范围按包内 COMMAND_CONTRACT.md 判断。
|
|
259
33
|
|
|
260
|
-
|
|
34
|
+
普通 Intent 的 timeoutMs 默认 300000,覆盖初次观察、等待决策、暂停和后续动作。cancel 会中止并等待已拥有的操作收尾,终态必须先写入检查点;写入失败是 blocked_evidence_store。重启后的 intent status 从持久证据恢复终态,live:false、recovered:true,不自动重放;缺少终态时报告 interrupted/runtime_restarted。最后一个动作的 dispatched/ambiguous 仍需独立检查。complete/fail/inconclusive 决策同样必须提供当前 basedOnRevision。
|
|
261
35
|
|
|
262
|
-
-
|
|
263
|
-
- CDP 网络/控制台用 `webview-network`/`webview-console`;目标 app 需要 debuggable,且 WebView debugging 可用。
|
|
264
|
-
- `webview-pages` 可先确认可 attach 的 page、socket、URL。
|
|
36
|
+
`install-apk` 通过 CLI 或 MCP 返回一个 supervised Intent 操作。调用者用该 operationId 观察系统页面并提交基于 revision 的唯一 selector 决策;没有 Agent 决策不会点击按钮。安装完成由 ADB 回执和独立 APK 身份核验共同确定。安装作为 Script 前置准备,后续客户端可继续观察和决策;同步 ctx.call 不提供安装入口,详见命令合同。
|
|
265
37
|
|
|
266
|
-
|
|
38
|
+
`permission-dialog` 同样返回 Intent 操作:先由 App 触发权限请求,再明确 packageName、permission 和 outcome(allow / allow-once / deny / dismiss)。依据实际弹窗决定 selector,以 PackageManager 状态及原 Activity 关闭核验结果;pending:activity_closure 时用 intent observe 继续核验。intent cancel 只停止任务;dismiss 才表示操作界面关闭弹窗。权限状态与 grant/revoke 夹具继续可直接调用;详情见包内 docs/COMMAND_CONTRACT.md。
|
|
267
39
|
|
|
268
|
-
|
|
269
|
-
- 下半屏点击前注意键盘遮挡;必要时先 `keyboard-state` 再 `hide-keyboard`。
|
|
40
|
+
## 证据与平台
|
|
270
41
|
|
|
271
|
-
|
|
42
|
+
Android 和 iOS 四流在持久后端接入后读取手机 FactStore;Host 记录执行与观察,Web 采集在接收时写入 Host FactStore。核对实际 refs、epoch、目标、窗口、coverage 和分页,保留失败或不完整覆盖。Script 和 Intent 支持 Android、iOS 和 Web,具体 provider 与动作范围以当前 schema 为准;支持平台不等于该 App 业务已经验证。
|
|
272
43
|
|
|
273
|
-
|
|
274
|
-
- 必须处理系统弹窗时,用 `permission-dialog` 或 `uia-tree`/`tap-uia-text`。
|
|
44
|
+
用 `evidence` 导出并离线核验保留的执行记录与文件;归档完整不等于业务通过。错误返回保留 `error`、`message`、`dispatched`、`ambiguous` 和操作状态。在冻结 App 的诊断中,完成后恢复运行。
|
|
275
45
|
|
|
276
|
-
##
|
|
277
|
-
|
|
278
|
-
`freeze-app`/`thaw-app` 是稳定动态画面的能力之一,不是默认动作节奏。只有冻结能让证据更可靠时才用。
|
|
279
|
-
|
|
280
|
-
`freeze-app`/`thaw-app` 只适用于移动 app runtime;Web Bridge 目标不要使用这两个命令。
|
|
281
|
-
|
|
282
|
-
适合冻结:
|
|
283
|
-
|
|
284
|
-
- 视频、动画、倒计时、实时刷新列表、游戏、播放页等会在思考期间变化的画面。
|
|
285
|
-
- 点击后出现短暂状态,需要先固定再分析截图和节点。
|
|
286
|
-
- 用户要求精确截图、坐标、像素或瞬时状态验证。
|
|
287
|
-
|
|
288
|
-
不要冻结或不要提前冻结:
|
|
289
|
-
|
|
290
|
-
- 静态页面的一次性观察、简单点击、普通表单输入。
|
|
291
|
-
- `install-apk`、`launch-*`、`clear-app-data`、权限弹窗处理。
|
|
292
|
-
- `wait-text`、点击、输入、滚动、WebView CDP 捕获、`logcat --follow` 等命令尚未完成时。
|
|
293
|
-
|
|
294
|
-
如果使用冻结:
|
|
295
|
-
|
|
296
|
-
1. 读取、操作、等待、捕获前先确保 app 解冻。
|
|
297
|
-
2. 拿到本轮证据后,确实需要稳定画面时再 `freeze-app`。
|
|
298
|
-
3. 冻结期间只做分析和规划,不执行依赖 app 运行的命令。
|
|
299
|
-
4. 下一次读取/操作/等待/捕获前先 `thaw-app`。
|
|
300
|
-
5. 最终回复前调用 `thaw-app`,不要把 app 留给用户时仍处于冻结状态。
|
|
301
|
-
|
|
302
|
-
动态画面采集并冻结:
|
|
303
|
-
|
|
304
|
-
```json
|
|
305
|
-
{
|
|
306
|
-
"command": "batch",
|
|
307
|
-
"arguments": {
|
|
308
|
-
"defaults": { "packageName": "com.example.app" },
|
|
309
|
-
"steps": [
|
|
310
|
-
{ "id": "thaw", "command": "thaw-app" },
|
|
311
|
-
{ "id": "shot", "command": "screenshot" },
|
|
312
|
-
{ "id": "tree", "command": "tree", "arguments": { "compact": true, "visibleOnly": true } },
|
|
313
|
-
{ "id": "freeze", "command": "freeze-app" }
|
|
314
|
-
],
|
|
315
|
-
"stopOnError": true,
|
|
316
|
-
"includeRaw": true
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
最终恢复:
|
|
322
|
-
|
|
323
|
-
```json
|
|
324
|
-
{
|
|
325
|
-
"command": "thaw-app",
|
|
326
|
-
"packageName": "com.example.app"
|
|
327
|
-
}
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
## 失败处理
|
|
331
|
-
|
|
332
|
-
- `packageName`/`port` 缺失:先补目标,不要让 MCP 回落到默认 sample。
|
|
333
|
-
- iOS `bundleId`/`deviceId`/`wdaUrl` 缺失:先用 `ios-devices`/`ios-setup` 补齐;需要 full-control 时不要在没有 WDA 的情况下宣称完成。
|
|
334
|
-
- iOS 设备锁屏、未信任、Developer Mode/DDI 不可用、WDA signing 失败、首次启动弹出授权/密码框:停下告诉用户需要操作,用户处理后再重试。
|
|
335
|
-
- Web `sessionId` 缺失:先跑 `web-session-start`、让页面 SDK 连接,再用 `web-sessions` 获取 session;不要把 Web 命令改成 Android `packageName`。
|
|
336
|
-
- Web provider 未运行或 endpoint/token 不匹配:用 `web-provider-status` 和 `web-connect-info` 重新确认连接信息,让页面刷新后重连。
|
|
337
|
-
- Web target ambiguous:读取 `web-sessions` 或 `web-dom` 返回的 target 候选,明确传 `targetId`。
|
|
338
|
-
- Web command 被拒绝:确认页面 SDK 是否注册了对应 action,或改用允许的 `web-click`/`web-input`/`web-scroll`;不要临时打开任意 `eval`。
|
|
339
|
-
- `screenshot` 报前台 package 不匹配:先 `launch-app` 或确认当前前台,再继续判断。
|
|
340
|
-
- `tree` 为空但截图正常:尝试 `uia-tree`、等待一轮或使用 Flutter/WebView 专用命令。
|
|
341
|
-
- WebView CDP 不可用:确认 app debuggable、WebView debugging、目标 page;不能用 CDP 时退回 `h5-*` 或可见 UI 验证。
|
|
342
|
-
- `freeze-app` 失败:继续任务;只有影响动态证据稳定性时才说明限制。
|
|
343
|
-
- 冻结状态下读取超时:先 `thaw-app` 再重试。
|
|
344
|
-
- 最终 `thaw-app` 失败:在回复中明确说明 app 可能仍被冻结。
|
|
345
|
-
|
|
346
|
-
## 安装配置
|
|
347
|
-
|
|
348
|
-
如果当前会话没有 AI App Bridge MCP,安装桌面包:
|
|
349
|
-
|
|
350
|
-
```bash
|
|
351
|
-
npm install -g @mobileaidev/ai-app-bridge
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
Web 页面需要额外在目标项目中安装调试 SDK:
|
|
355
|
-
|
|
356
|
-
```bash
|
|
357
|
-
npm install --save-dev @mobileaidev/ai-app-bridge-web
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
macOS / Linux:
|
|
361
|
-
|
|
362
|
-
```json
|
|
363
|
-
{
|
|
364
|
-
"mcpServers": {
|
|
365
|
-
"ai-app-bridge": {
|
|
366
|
-
"command": "ai-app-bridge-mcp"
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
Windows:
|
|
373
|
-
|
|
374
|
-
```json
|
|
375
|
-
{
|
|
376
|
-
"mcpServers": {
|
|
377
|
-
"ai-app-bridge": {
|
|
378
|
-
"command": "cmd",
|
|
379
|
-
"args": ["/c", "ai-app-bridge-mcp"]
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
```
|
|
46
|
+
## 版本差异
|
|
384
47
|
|
|
385
|
-
|
|
48
|
+
当前候选版移除了 batch、样例专用启动/smoke 命令、旧 MCP 工具别名和外层重复参数。连续步骤写成 Script,Flutter 普通启动用 launch-app。运行版本不支持新合同时,明确报告版本差异;以实际发现的能力继续任务,不能把旧证据描述为本轮验证。
|