@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 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 should follow the `ai-app-bridge-use` cadence:
70
- thaw immediately before reading app content or performing an app action, freeze
71
- immediately after evidence or action results are captured, keep the app frozen
72
- while reasoning/planning, and thaw once more before finishing the overall task.
73
- For visible state changes such as panels, dialogs, page transitions, tabs, or
74
- button-triggered content, verify with both `screenshot` and `tree`/`uia-tree`;
75
- do not conclude success from UI tree alone.
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.
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
- 'When freezing is available, keep the target app frozen while the model thinks or plans. Thaw only immediately before reading app content or performing an app action, freeze again as soon as that evidence/action result is captured, and thaw once more before finishing the overall task so the app is not left frozen.',
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', 'Stop the target app processes with SIGSTOP after app content is captured, preventing playback or animation from changing the observed evidence.', {
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 the target app processes with SIGCONT before reading app content or dispatching actions, so bridge endpoints can answer.', {
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: 'Stop target app processes with SIGSTOP after content capture to keep observed evidence stable.', targetApp: true, options: ['serial', 'packageName', 'pid'] },
462
- { command: 'thaw-app', domain: 'app', summary: 'Resume target app processes with SIGCONT before content capture or actions so bridge data can be read.', targetApp: true, options: ['serial', 'packageName', 'pid'] },
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.7",
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 观察、操作、验证 Android 或 Flutter 应用。Codex 需要读取 app UI 内容、截图、View treeFlutter widget、WebView DOM、日志、网络请求、状态,或通过 ai-app-bridge-mcp 执行 Android app 操作时触发;必须在模型思考和规划下一步期间冻结 app,只在读取内容或执行操作前短暂解冻,并在全部任务结束前解冻 app。
4
- ---
5
-
6
- # AI App Bridge Use
7
-
8
- ## MCP 安装
9
-
10
- 使用前先确认 AI App Bridge MCP server 已安装并配置。如果当前会话里已经有 `ai-app-bridge` MCP 工具,直接进入“冻结节奏”。
11
-
12
- 安装桌面 MCP 包:
13
-
14
- ```bash
15
- npm install -g @mobileaidev/ai-app-bridge
16
- ```
17
-
18
- 把 MCP server 加到用户的 agent 配置里。
19
-
20
- macOS / Linux:
21
-
22
- ```json
23
- {
24
- "mcpServers": {
25
- "ai-app-bridge": {
26
- "command": "ai-app-bridge-mcp"
27
- }
28
- }
29
- }
30
- ```
31
-
32
- Windows:
33
-
34
- ```json
35
- {
36
- "mcpServers": {
37
- "ai-app-bridge": {
38
- "command": "cmd",
39
- "args": ["/c", "ai-app-bridge-mcp"]
40
- }
41
- }
42
- }
43
- ```
44
-
45
- 配置后重启或刷新 agent MCP session。第一次使用时先调用 `capabilities`,确认 compact surface 里有 `run`、`freeze-app` 和 `thaw-app`。
46
-
47
- ## 冻结节奏
48
-
49
- 核心规则:**模型思考、分析证据、规划下一步期间,app 必须保持冻结;全部任务结束前,app 必须恢复解冻。**
50
-
51
- 每一轮都按这个循环执行:
52
-
53
- 1. 准备读取 app 内容或执行 app 操作前,调用 `thaw-app`。
54
- 2. 立即执行需要 app 运行的 MCP 命令,例如读取 `tree`、截图、等待文本、点击、输入、滚动、抓取 WebView 网络等。
55
- 3. 一旦拿到本轮需要的证据或动作结果,立即调用 `freeze-app`。
56
- 4. app 已冻结的状态下,再分析证据、判断是否成功、规划下一步。
57
- 5. 下一轮真正要读内容或操作 app 时,再次 `thaw-app`。
58
- 6. 当确认整个用户任务已经完成、准备给用户最终回复前,最后调用一次 `thaw-app`,不要把 app 留在冻结状态。
59
-
60
- 换句话说,app 只在“采集证据/执行动作”的短窗口内运行;模型停下来思考时,app 应该已经被冻结;任务结束交还给用户前,app 应该已经解冻。
61
-
62
- ## 状态变化校验
63
-
64
- 对任何会改变可见界面的操作,例如打开/关闭面板、关闭弹窗、切换页面、点击 tab、进入详情页、展开抽屉、点击按钮后读取内容,不能只依赖 `uia-tree` 或 `tree` 判断成功。
65
-
66
- 操作后必须同时采集:
67
-
68
- 1. `screenshot`
69
- 2. `uia-tree` 或 `tree`
70
-
71
- 只有当截图中的可见画面与 UI tree 的关键节点一致时,才能认为操作成功。
72
-
73
- 如果两者冲突:
74
-
75
- - 以截图作为当前真实可见界面的优先证据。
76
- - 将 UI tree 视为可能存在缓存、残留节点、不可见层或过期节点。
77
- - 重新点击、调整坐标、等待后再采集。
78
- - 不得基于冲突证据向用户报告结论。
79
-
80
- 禁止仅凭 UI tree 中存在目标文本,就断言目标面板、弹窗、页面或 tab 已经打开;必须确认该文本在截图中对应的可见区域也存在,或截图中存在等价的可见状态标志。
81
-
82
- 例如打开评论面板后,必须确认:
83
-
84
- - 截图中实际出现评论面板、评论标题或评论列表。
85
- - UI tree 中也出现 `评论` 标题、评论列表节点或评论输入栏。
86
- - 两者内容对应同一个界面。
87
-
88
- ## 推荐批处理
89
-
90
- 优先用 `batch` 把“解冻 -> 采集/操作 -> 冻结”放进同一个 MCP 调用,避免中间留下 app 继续播放或动画变化。
91
-
92
- 读取当前屏幕:
93
-
94
- ```json
95
- {
96
- "command": "batch",
97
- "arguments": {
98
- "defaults": {
99
- "packageName": "com.example.app"
100
- },
101
- "steps": [
102
- { "id": "thaw", "command": "thaw-app" },
103
- { "id": "tree", "command": "tree", "arguments": { "compact": true, "visibleOnly": true } },
104
- { "id": "freeze", "command": "freeze-app" }
105
- ],
106
- "stopOnError": true,
107
- "includeRaw": true
108
- }
109
- }
110
- ```
111
-
112
- 执行点击并读取结果:
113
-
114
- ```json
115
- {
116
- "command": "batch",
117
- "arguments": {
118
- "defaults": {
119
- "packageName": "com.example.app"
120
- },
121
- "steps": [
122
- { "id": "thaw", "command": "thaw-app" },
123
- { "id": "tap", "command": "tap-text", "arguments": { "targetText": "继续" } },
124
- { "id": "screenshot-after", "command": "screenshot" },
125
- { "id": "tree-after", "command": "tree", "arguments": { "compact": true, "visibleOnly": true } },
126
- { "id": "freeze", "command": "freeze-app" }
127
- ],
128
- "stopOnError": true,
129
- "includeRaw": true
130
- }
131
- }
132
- ```
133
-
134
- 任务结束前恢复 app:
135
-
136
- ```json
137
- {
138
- "command": "thaw-app",
139
- "packageName": "com.example.app"
140
- }
141
- ```
142
-
143
- ## 单步命令模式
144
-
145
- 如果不能用 `batch`,也必须手动保持同样顺序:
146
-
147
- ```json
148
- { "command": "thaw-app", "packageName": "com.example.app" }
149
- ```
150
-
151
- ```json
152
- { "command": "tree", "packageName": "com.example.app", "arguments": { "compact": true, "visibleOnly": true } }
153
- ```
154
-
155
- ```json
156
- { "command": "freeze-app", "packageName": "com.example.app" }
157
- ```
158
-
159
- 之后再开始思考和规划下一步。全部任务完成后,再执行一次:
160
-
161
- ```json
162
- { "command": "thaw-app", "packageName": "com.example.app" }
163
- ```
164
-
165
- ## 什么时候不要提前冻结
166
-
167
- 不要在一个需要 app 持续运行的 MCP 命令还没完成前冻结,例如:
168
-
169
- - `wait-text`
170
- - 点击、输入、滚动、启动 Activity
171
- - 带 `durationMs` 的 `webview-network` / `webview-console`
172
- - `logcat --follow`
173
- - 安装、授权、权限弹窗处理
174
-
175
- 这些命令执行前先解冻,命令返回并拿到结果后立刻冻结,然后再思考。等全部任务完成并准备结束时,再解冻 app。
176
-
177
- ## 失败处理
178
-
179
- 如果 `freeze-app` 失败,继续用 MCP 完成观察和操作,但在结果里说明限制。常见原因包括:app 不是 debuggable、目标进程不存在、`run-as` 不可用、系统已经杀掉进程。
180
-
181
- 如果 app 已经被冻结,而 MCP 读取内容超时或无法返回数据,先调用 `thaw-app`,再重试读取;不要在冻结状态下反复读取 bridge 数据。
182
-
183
- 如果最终 `thaw-app` 失败,也要在给用户的最终回复里说明 app 可能仍处于冻结状态,以及失败原因。
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: "使用 AI App Bridge MCP,在思考期间冻结 app,结束前解冻。"
4
- default_prompt: "使用 AI App Bridge MCP 观察和操作 Android app。每轮读取内容或操作前先解冻,拿到证据后立刻冻结,再思考和规划下一步;全部任务结束前最后解冻 app。"
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。"