@mobileaidev/ai-app-bridge 0.2.7 → 0.2.9
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/README.md +9 -7
- package/bin/ai-app-bridge.js +0 -0
- package/bin/mcp-server.js +6 -6
- package/package.json +29 -29
- package/skills/ai-app-bridge-use/SKILL.md +260 -183
- package/skills/ai-app-bridge-use/agents/openai.yaml +4 -4
package/README.md
CHANGED
|
@@ -66,13 +66,15 @@ steps as skipped without mixing results from different commands:
|
|
|
66
66
|
}
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
For dynamic screens, MCP agents
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
For dynamic or transient screens, MCP agents can use `freeze-app`/`thaw-app` as
|
|
70
|
+
an optional stabilization control: thaw before reads, actions, waits, or
|
|
71
|
+
captures; freeze after evidence capture only when a changing UI would make
|
|
72
|
+
reasoning unreliable; and thaw before the next app operation or before
|
|
73
|
+
finishing so the app is not left frozen. Static screens and ordinary form
|
|
74
|
+
flows usually do not need freezing.
|
|
75
|
+
For visible state changes such as panels, dialogs, page transitions, tabs, or
|
|
76
|
+
button-triggered content, verify with both `screenshot` and `tree`/`uia-tree`;
|
|
77
|
+
do not conclude success from UI tree alone.
|
|
76
78
|
|
|
77
79
|
WebView network and console capture use Android WebView DevTools/CDP when the
|
|
78
80
|
target app is debuggable and WebView debugging is enabled.
|
package/bin/ai-app-bridge.js
CHANGED
|
File without changes
|
package/bin/mcp-server.js
CHANGED
|
@@ -14,8 +14,8 @@ const serverInstructions = [
|
|
|
14
14
|
'AI App Bridge observes and controls Android apps for agent workflows. Prefer these tools over raw adb when inspecting UI, text, WebView, logs, network, app install, data reset, launch, and permissions.',
|
|
15
15
|
'Default surface is compact: call capabilities to discover domains, then call run with a command and arguments.',
|
|
16
16
|
'Always pass packageName for app-specific commands, or pass an explicit port. Do not rely on a sample/default package in MCP sessions.',
|
|
17
|
-
'
|
|
18
|
-
].join(' ');
|
|
17
|
+
'Use freeze-app/thaw-app only as an optional stabilization control for dynamic or transient screens: thaw before reads/actions/captures, freeze after evidence capture only when it helps reasoning, and thaw before the next operation or before finishing so the app is not left frozen.',
|
|
18
|
+
].join(' ');
|
|
19
19
|
|
|
20
20
|
let buffer = Buffer.alloc(0);
|
|
21
21
|
let responseFormat = null;
|
|
@@ -257,10 +257,10 @@ function fullToolDefinitions() {
|
|
|
257
257
|
deltaY: { type: 'number', description: 'Window scroll delta Y when no selector/text is supplied.' },
|
|
258
258
|
}),
|
|
259
259
|
bridgeTool('logs', 'Read generic in-app log records.'),
|
|
260
|
-
bridgeTool('freeze_app', '
|
|
260
|
+
bridgeTool('freeze_app', 'Optionally stop target app processes with SIGSTOP when a dynamic or transient screen needs stable evidence for review.', {
|
|
261
261
|
pid: { type: 'string', description: 'Optional explicit process id. Defaults to all processes named packageName or packageName:*.' },
|
|
262
262
|
}, ['packageName']),
|
|
263
|
-
bridgeTool('thaw_app', 'Resume
|
|
263
|
+
bridgeTool('thaw_app', 'Resume target app processes with SIGCONT before reads, waits, captures, or actions, and before finishing any task that used freeze-app.', {
|
|
264
264
|
pid: { type: 'string', description: 'Optional explicit process id. Defaults to all processes named packageName or packageName:*.' },
|
|
265
265
|
}, ['packageName']),
|
|
266
266
|
bridgeTool('logcat', 'Read Android logcat through ADB with optional pid/tag/level/grep filters.', {
|
|
@@ -458,8 +458,8 @@ const commandDefinitions = [
|
|
|
458
458
|
{ command: 'logcat', domain: 'diagnostics', summary: 'Read Android logcat with optional app pid, tag, level, and grep filters.', options: ['serial', 'packageName', 'pid', 'appPid', 'tag', 'level', 'grep', 'lines', 'since', 'follow', 'durationSec', 'clear'] },
|
|
459
459
|
{ command: 'install-apk', domain: 'app', summary: 'Install an APK and assist device-side installer confirmation screens.', options: ['serial', 'packageName', 'apkPath', 'allowDowngrade', 'streaming', 'installTimeoutMs', 'installerTimeoutMs', 'intervalMs'] },
|
|
460
460
|
{ command: 'clear-app-data', domain: 'app', summary: 'Clear target app local data through the bridge runtime.', targetApp: true, options: ['serial', 'packageName'] },
|
|
461
|
-
{ command: 'freeze-app', domain: 'app', summary: '
|
|
462
|
-
{ command: 'thaw-app', domain: 'app', summary: 'Resume target app processes with SIGCONT before
|
|
461
|
+
{ command: 'freeze-app', domain: 'app', summary: 'Optionally stop target app processes with SIGSTOP when dynamic UI needs stable evidence.', targetApp: true, options: ['serial', 'packageName', 'pid'] },
|
|
462
|
+
{ command: 'thaw-app', domain: 'app', summary: 'Resume target app processes with SIGCONT before reads, waits, captures, actions, or final handoff.', targetApp: true, options: ['serial', 'packageName', 'pid'] },
|
|
463
463
|
{ command: 'launch-app', domain: 'app', summary: 'Launch the target package LAUNCHER Activity and report launcher candidates.', targetApp: true, options: ['serial', 'packageName', 'activity', 'component', 'action', 'category', 'data', 'extra'] },
|
|
464
464
|
{ command: 'launch-activity', domain: 'app', summary: 'Launch an explicit Android Activity component with optional string extras.', targetApp: true, options: ['serial', 'packageName', 'activity', 'component', 'action', 'category', 'data', 'extra'] },
|
|
465
465
|
{ command: 'launch-native-test', domain: 'app', summary: 'Launch the debug native bridge test Activity.', targetApp: true, options: ['serial', 'packageName'] },
|
package/package.json
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@mobileaidev/ai-app-bridge",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Desktop CLI and MCP server for AI App Bridge.",
|
|
5
|
-
"repository": {
|
|
6
|
-
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/mobileAiDev/ai-app-bridge.git",
|
|
8
|
-
"directory": "desktop/ai-app-bridge-cli"
|
|
9
|
-
},
|
|
10
|
-
"homepage": "https://github.com/mobileAiDev/ai-app-bridge#readme",
|
|
11
|
-
"bugs": {
|
|
12
|
-
"url": "https://github.com/mobileAiDev/ai-app-bridge/issues"
|
|
13
|
-
},
|
|
14
|
-
"bin": {
|
|
15
|
-
"ai-app-bridge": "bin/ai-app-bridge.js",
|
|
16
|
-
"ai-app-bridge-mcp": "bin/mcp-server.js"
|
|
17
|
-
},
|
|
1
|
+
{
|
|
2
|
+
"name": "@mobileaidev/ai-app-bridge",
|
|
3
|
+
"version": "0.2.9",
|
|
4
|
+
"description": "Desktop CLI and MCP server for AI App Bridge.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/mobileAiDev/ai-app-bridge.git",
|
|
8
|
+
"directory": "desktop/ai-app-bridge-cli"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/mobileAiDev/ai-app-bridge#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/mobileAiDev/ai-app-bridge/issues"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"ai-app-bridge": "bin/ai-app-bridge.js",
|
|
16
|
+
"ai-app-bridge-mcp": "bin/mcp-server.js"
|
|
17
|
+
},
|
|
18
18
|
"files": [
|
|
19
19
|
"bin/ai-app-bridge.js",
|
|
20
20
|
"bin/mcp-server.js",
|
|
21
21
|
"skills/ai-app-bridge-use",
|
|
22
22
|
"README.md"
|
|
23
23
|
],
|
|
24
|
-
"scripts": {
|
|
25
|
-
"check": "node -c bin/ai-app-bridge.js && node -c bin/mcp-server.js && node --test",
|
|
26
|
-
"test": "node --test"
|
|
27
|
-
},
|
|
28
|
-
"license": "Apache-2.0",
|
|
29
|
-
"dependencies": {
|
|
30
|
-
"ws": "^8.18.0"
|
|
31
|
-
},
|
|
32
|
-
"publishConfig": {
|
|
33
|
-
"access": "public"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
24
|
+
"scripts": {
|
|
25
|
+
"check": "node -c bin/ai-app-bridge.js && node -c bin/mcp-server.js && node --test",
|
|
26
|
+
"test": "node --test"
|
|
27
|
+
},
|
|
28
|
+
"license": "Apache-2.0",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"ws": "^8.18.0"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1,183 +1,260 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ai-app-bridge-use
|
|
3
|
-
description: 使用 AI App Bridge MCP
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# AI App Bridge Use
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
##
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
##
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
1
|
+
---
|
|
2
|
+
name: ai-app-bridge-use
|
|
3
|
+
description: 使用 AI App Bridge MCP 观察、操作、验证和调试 Android 或 Flutter 应用。Codex 需要检查移动端 UI、截图、Android View/UIAutomator tree、点击/输入/等待/滑动、安装/启动/清数据、Flutter widget 与 action、WebView/H5 DOM 或 CDP 网络/控制台、日志/网络/状态/事件、权限/appops、smoke 测试,或按需使用 freeze/thaw 稳定动态画面时触发。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# AI App Bridge Use
|
|
7
|
+
|
|
8
|
+
## Agent 快速流程
|
|
9
|
+
|
|
10
|
+
1. 确认目标 app:优先使用用户给出的 `packageName`;没有包名时先从上下文、构建配置或前台 app 线索推断。面向具体 app 的命令必须传 `packageName`,只有包名无法发现 bridge 端口时才传 `port`。
|
|
11
|
+
2. 发现能力:默认 MCP surface 只有 `capabilities` 和 `run`。不确定命令或参数时先调用 `capabilities`,再用 `run` 执行。
|
|
12
|
+
3. 选择命令路径:按任务类型选 `core`、`app`、`action`、`flutter`、`webview`、`diagnostics` 或 `advanced` 域;不要先退回原始 `adb`。
|
|
13
|
+
4. 用 `batch` 串联相关步骤:观察、操作、等待、截图、tree 验证尽量放进一次 MCP 调用。
|
|
14
|
+
5. 验证可见结果:界面变化必须用 `screenshot` 加 `tree`/`uia-tree` 交叉确认。
|
|
15
|
+
6. 只在需要稳定动态画面时使用 `freeze-app`/`thaw-app`;如果本轮冻结过 app,最终回复前必须解冻。
|
|
16
|
+
|
|
17
|
+
## 能力发现和调用
|
|
18
|
+
|
|
19
|
+
`capabilities` 用来列出命令域和参数:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{ "domain": "webview", "includeOptions": true }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{ "command": "input-text", "includeOptions": true }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`run` 用 CLI 形式的命令名执行能力,例如:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"command": "screenshot",
|
|
34
|
+
"packageName": "com.example.app"
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
如果 MCP 暴露的是 full/legacy surface,直接工具名通常用下划线形式;语义与 `run` 里的连字符命令一致,例如 `tap_text` 对应 `tap-text`。
|
|
39
|
+
|
|
40
|
+
## 任务路由
|
|
41
|
+
|
|
42
|
+
| 任务 | 首选命令 |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| 当前 app 状态和桥接信息 | `status` |
|
|
45
|
+
| 真实可见画面 | `screenshot` |
|
|
46
|
+
| App 内 View 节点 | `tree`,常配 `compact`、`visibleOnly` |
|
|
47
|
+
| 系统窗口、权限弹窗、Compose/跨 app UI | `uia-tree`、`tap-uia-text` |
|
|
48
|
+
| 点击、输入、等待、滑动、按键 | `tap-text`、`tap`、`input-text`、`wait-text`、`swipe`、`keyevent` |
|
|
49
|
+
| 键盘处理 | `keyboard-state`、`hide-keyboard` |
|
|
50
|
+
| 安装、启动、清数据 | `install-apk`、`launch-app`、`launch-activity`、`clear-app-data` |
|
|
51
|
+
| 权限和 appops | `permission-state`、`permission-grant`、`permission-revoke`、`permission-dialog`、`appops-set` |
|
|
52
|
+
| Flutter UI 和动作 | `flutter-tree`、`flutter-nodes`、`tap-flutter-text`、`input-flutter-text`、`scroll-flutter`、`flutter-action` |
|
|
53
|
+
| 原生 WebView DOM | `h5-dom`、`h5-click`、`h5-input`、`h5-wait`、`h5-scroll` |
|
|
54
|
+
| Flutter H5 adapter | `flutter-h5-dom`、`flutter-h5-click`、`flutter-h5-input`、`flutter-h5-wait`、`flutter-h5-scroll` |
|
|
55
|
+
| WebView CDP 网络/控制台 | `webview-pages`、`webview-network`、`webview-console` |
|
|
56
|
+
| App 内记录 | `logs`、`network`、`state`、`events` |
|
|
57
|
+
| Android 日志 | `logcat`,按 `pid`、`appPid`、`tag`、`level`、`grep` 过滤 |
|
|
58
|
+
| 自检 | `smoke` |
|
|
59
|
+
| 多步骤串行执行 | `batch` |
|
|
60
|
+
| 动态画面稳定 | `freeze-app`、`thaw-app`,只按需使用 |
|
|
61
|
+
|
|
62
|
+
## 常用模式
|
|
63
|
+
|
|
64
|
+
观察当前界面:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"command": "batch",
|
|
69
|
+
"arguments": {
|
|
70
|
+
"defaults": { "packageName": "com.example.app" },
|
|
71
|
+
"steps": [
|
|
72
|
+
{ "id": "status", "command": "status" },
|
|
73
|
+
{ "id": "shot", "command": "screenshot" },
|
|
74
|
+
{ "id": "tree", "command": "tree", "arguments": { "compact": true, "visibleOnly": true } }
|
|
75
|
+
],
|
|
76
|
+
"stopOnError": true,
|
|
77
|
+
"includeRaw": true
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
点击并验证结果:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"command": "batch",
|
|
87
|
+
"arguments": {
|
|
88
|
+
"defaults": { "packageName": "com.example.app" },
|
|
89
|
+
"steps": [
|
|
90
|
+
{ "id": "tap", "command": "tap-text", "arguments": { "targetText": "继续" } },
|
|
91
|
+
{ "id": "wait", "command": "wait-text", "arguments": { "targetText": "完成", "timeoutSec": 8 } },
|
|
92
|
+
{ "id": "shot-after", "command": "screenshot" },
|
|
93
|
+
{ "id": "tree-after", "command": "tree", "arguments": { "compact": true, "visibleOnly": true } }
|
|
94
|
+
],
|
|
95
|
+
"stopOnError": true,
|
|
96
|
+
"includeRaw": true
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
输入文本:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"command": "input-text",
|
|
106
|
+
"packageName": "com.example.app",
|
|
107
|
+
"arguments": {
|
|
108
|
+
"text": "中文输入",
|
|
109
|
+
"hideKeyboard": true
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
捕获 WebView 网络:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"command": "webview-network",
|
|
119
|
+
"packageName": "com.example.app",
|
|
120
|
+
"arguments": {
|
|
121
|
+
"durationMs": 3000,
|
|
122
|
+
"urlFilter": "/api/"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## 验证规则
|
|
128
|
+
|
|
129
|
+
把 `screenshot` 当作当前可见画面的最高优先级证据,把 `tree`/`uia-tree` 当作可操作节点和结构证据。
|
|
130
|
+
|
|
131
|
+
对打开/关闭面板、关闭弹窗、切换页面、点击 tab、进入详情页、展开抽屉、按钮触发内容变化等可见状态变化,必须同时采集截图和 tree。只有二者指向同一状态时,才报告成功。
|
|
132
|
+
|
|
133
|
+
如果截图和 tree 冲突:
|
|
134
|
+
|
|
135
|
+
- 以截图判断用户实际看到什么。
|
|
136
|
+
- 认为 tree 可能包含缓存、不可见节点、过期层或非前台窗口。
|
|
137
|
+
- 重新等待、采集或换用 `uia-tree`、坐标点击、Flutter/WebView 专用命令。
|
|
138
|
+
- 不要把冲突证据包装成确定结论。
|
|
139
|
+
|
|
140
|
+
异步 UI 用 `wait-text` 或 H5/Flutter wait 命令等待;不要用固定 sleep 代替状态判断。
|
|
141
|
+
|
|
142
|
+
## 平台专项
|
|
143
|
+
|
|
144
|
+
Flutter:
|
|
145
|
+
|
|
146
|
+
- 先尝试泛用 `tap-text`/`input-text`;失败、节点不可见或语义特殊时切到 `flutter-*`。
|
|
147
|
+
- 用 `flutter-nodes` 找可操作节点,用 `scroll-flutter` 处理需要滚动后才出现的文本。
|
|
148
|
+
|
|
149
|
+
WebView/H5:
|
|
150
|
+
|
|
151
|
+
- DOM 操作优先用 `h5-*` 或 `flutter-h5-*`,避免靠坐标猜元素。
|
|
152
|
+
- CDP 网络/控制台用 `webview-network`/`webview-console`;目标 app 需要 debuggable,且 WebView debugging 可用。
|
|
153
|
+
- `webview-pages` 可先确认可 attach 的 page、socket、URL。
|
|
154
|
+
|
|
155
|
+
输入:
|
|
156
|
+
|
|
157
|
+
- 中文和 Unicode 输入优先用 `input-text` 或 `input-flutter-text`,不要用原始 `adb shell input text`。
|
|
158
|
+
- 下半屏点击前注意键盘遮挡;必要时先 `keyboard-state` 再 `hide-keyboard`。
|
|
159
|
+
|
|
160
|
+
权限和系统 UI:
|
|
161
|
+
|
|
162
|
+
- 运行时权限优先用 `permission-state`/`permission-grant`/`permission-revoke`。
|
|
163
|
+
- 必须处理系统弹窗时,用 `permission-dialog` 或 `uia-tree`/`tap-uia-text`。
|
|
164
|
+
|
|
165
|
+
## Freeze/Thaw 策略
|
|
166
|
+
|
|
167
|
+
`freeze-app`/`thaw-app` 是稳定动态画面的能力之一,不是默认动作节奏。只有冻结能让证据更可靠时才用。
|
|
168
|
+
|
|
169
|
+
适合冻结:
|
|
170
|
+
|
|
171
|
+
- 视频、动画、倒计时、实时刷新列表、游戏、播放页等会在思考期间变化的画面。
|
|
172
|
+
- 点击后出现短暂状态,需要先固定再分析截图和节点。
|
|
173
|
+
- 用户要求精确截图、坐标、像素或瞬时状态验证。
|
|
174
|
+
|
|
175
|
+
不要冻结或不要提前冻结:
|
|
176
|
+
|
|
177
|
+
- 静态页面的一次性观察、简单点击、普通表单输入。
|
|
178
|
+
- `install-apk`、`launch-*`、`clear-app-data`、权限弹窗处理。
|
|
179
|
+
- `wait-text`、点击、输入、滚动、WebView CDP 捕获、`logcat --follow` 等命令尚未完成时。
|
|
180
|
+
|
|
181
|
+
如果使用冻结:
|
|
182
|
+
|
|
183
|
+
1. 读取、操作、等待、捕获前先确保 app 解冻。
|
|
184
|
+
2. 拿到本轮证据后,确实需要稳定画面时再 `freeze-app`。
|
|
185
|
+
3. 冻结期间只做分析和规划,不执行依赖 app 运行的命令。
|
|
186
|
+
4. 下一次读取/操作/等待/捕获前先 `thaw-app`。
|
|
187
|
+
5. 最终回复前调用 `thaw-app`,不要把 app 留给用户时仍处于冻结状态。
|
|
188
|
+
|
|
189
|
+
动态画面采集并冻结:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"command": "batch",
|
|
194
|
+
"arguments": {
|
|
195
|
+
"defaults": { "packageName": "com.example.app" },
|
|
196
|
+
"steps": [
|
|
197
|
+
{ "id": "thaw", "command": "thaw-app" },
|
|
198
|
+
{ "id": "shot", "command": "screenshot" },
|
|
199
|
+
{ "id": "tree", "command": "tree", "arguments": { "compact": true, "visibleOnly": true } },
|
|
200
|
+
{ "id": "freeze", "command": "freeze-app" }
|
|
201
|
+
],
|
|
202
|
+
"stopOnError": true,
|
|
203
|
+
"includeRaw": true
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
最终恢复:
|
|
209
|
+
|
|
210
|
+
```json
|
|
211
|
+
{
|
|
212
|
+
"command": "thaw-app",
|
|
213
|
+
"packageName": "com.example.app"
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## 失败处理
|
|
218
|
+
|
|
219
|
+
- `packageName`/`port` 缺失:先补目标,不要让 MCP 回落到默认 sample。
|
|
220
|
+
- `screenshot` 报前台 package 不匹配:先 `launch-app` 或确认当前前台,再继续判断。
|
|
221
|
+
- `tree` 为空但截图正常:尝试 `uia-tree`、等待一轮或使用 Flutter/WebView 专用命令。
|
|
222
|
+
- WebView CDP 不可用:确认 app debuggable、WebView debugging、目标 page;不能用 CDP 时退回 `h5-*` 或可见 UI 验证。
|
|
223
|
+
- `freeze-app` 失败:继续任务;只有影响动态证据稳定性时才说明限制。
|
|
224
|
+
- 冻结状态下读取超时:先 `thaw-app` 再重试。
|
|
225
|
+
- 最终 `thaw-app` 失败:在回复中明确说明 app 可能仍被冻结。
|
|
226
|
+
|
|
227
|
+
## 安装配置
|
|
228
|
+
|
|
229
|
+
如果当前会话没有 AI App Bridge MCP,安装桌面包:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
npm install -g @mobileaidev/ai-app-bridge
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
macOS / Linux:
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"mcpServers": {
|
|
240
|
+
"ai-app-bridge": {
|
|
241
|
+
"command": "ai-app-bridge-mcp"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Windows:
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"mcpServers": {
|
|
252
|
+
"ai-app-bridge": {
|
|
253
|
+
"command": "cmd",
|
|
254
|
+
"args": ["/c", "ai-app-bridge-mcp"]
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
配置后重启或刷新 MCP session,再调用 `capabilities` 确认连接。
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
interface:
|
|
2
|
-
display_name: "AI App Bridge Use"
|
|
3
|
-
short_description: "
|
|
4
|
-
default_prompt: "使用
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "AI App Bridge Use"
|
|
3
|
+
short_description: "观察、操作并验证 Android/Flutter app。"
|
|
4
|
+
default_prompt: "使用 $ai-app-bridge-use 观察、操作和验证目标 Android/Flutter app;先发现能力并传 packageName,只有动态画面需要稳定证据时才使用 freeze/thaw。"
|