agentremote-cli 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,397 @@
1
+ # remotecli 使用指南
2
+
3
+ `remotecli` 是 AgentRemote 的 Agent 侧 CLI。AI 沙箱通过它调用远程客户机能力:桌面控制、远程 Shell、预定义 RPA 流程。
4
+
5
+ 这份文件是 `remotecli` 的主文档。旁边的 `agent.md`、`cua.md`、`shell.md`、`rpa.md` 只做速查入口,避免同一规则在多个文件里重复维护。
6
+
7
+ ## 一句话架构
8
+
9
+ ```text
10
+ AI / remotecli --HTTP--> Middleware --MQTT--> Runtime --插件--> 桌面 / Shell / RPA
11
+ ```
12
+
13
+ AI 不直接接触 MQTT,也不直接连接客户机 Runtime。它只调用 `remotecli`,`remotecli` 只访问 Middleware HTTP API。
14
+
15
+ ## 快速开始
16
+
17
+ ```bash
18
+ python -m remotecli.cli \
19
+ --wait \
20
+ --middleware http://<MIDDLEWARE_IP>:9100 \
21
+ --tenant <TENANT_ID> \
22
+ --node <NODE_ID> \
23
+ --handle wch_v1_... \
24
+ shell info
25
+ ```
26
+
27
+ 常用全局参数:
28
+
29
+ | 参数 | 说明 |
30
+ |---|---|
31
+ | `--config` | CLI 配置文件,默认使用 `remotecli/config/agentremote.cli.toml` |
32
+ | `--middleware` | Middleware HTTP 地址 |
33
+ | `--tenant` | 租户 ID |
34
+ | `--node` | 目标客户机节点 ID |
35
+ | `--agent` | Agent ID,可选 |
36
+ | `--handle` | Auth Broker handle,格式通常为 `wch_v1_...` |
37
+ | `--wait` | 提交底层任务后轮询最终结果,必须放在 `cua` / `shell` / `rpa` 前 |
38
+ | `--wait-timeout` | 等待结果的最大秒数 |
39
+ | `--poll-interval` | 轮询间隔秒数 |
40
+
41
+ 参数优先级遵循:命令行参数 > 环境变量 > TOML 配置 > 本地开发默认值。
42
+
43
+ ## 先用哪个命令
44
+
45
+ 普通 AI Agent 默认用 `agent` 子命令。只有需要底层能力时才降到 `cua`、`shell` 或 `rpa`。
46
+
47
+ | 目标 | 优先命令 | 何时降级 |
48
+ |---|---|---|
49
+ | 执行 PowerShell / cmd | `agent ps` / `agent cmd` | 需要异步提交或完整底层返回时用 `shell` |
50
+ | 打开或准备应用窗口 | `agent open <app>` | 要自定义启动脚本时用 `shell exec-script` |
51
+ | 判断页面是否 ready | `agent probe` | 已有 `pid/window_id` 时用 `cua probe-window` |
52
+ | 观察页面状态 | `agent observe` | 需要完整原始状态时加 `--format full` 或用 `cua get-window-state` |
53
+ | 点击 / 输入 / 热键 | `agent click/type/key/hotkey` | 坐标、右键、拖拽、多窗口手选时用 `cua` |
54
+ | 固定业务自动化流程 | `rpa run` | 不建议用 `agent` 拼固定 RPA 流程 |
55
+ | 查询异步结果 | `result <trace_id>` | `agent` 默认已自动等待,一般不需要 |
56
+
57
+ ## Agent 高层入口
58
+
59
+ ```bash
60
+ python -m remotecli.cli agent <action> [args]
61
+ ```
62
+
63
+ `agent ...` 面向普通 AI 使用,默认会:
64
+
65
+ - 等待任务最终结果。
66
+ - 解包 Middleware 返回里的 `result.output` JSON 字符串。
67
+ - GUI 操作前按应用名自动执行 `list-apps -> list-windows`,拿到真实 `pid/window_id`。
68
+ - 使用同一个 `--session` 时缓存窗口引用,后续步骤复用,失败时自动刷新一次。
69
+
70
+ 常用命令:
71
+
72
+ | 命令 | 用途 | 示例 |
73
+ |---|---|---|
74
+ | `ps` | 执行 PowerShell | `agent ps "Get-Process | Select-Object -First 5"` |
75
+ | `cmd` | 执行 cmd | `agent cmd "whoami"` |
76
+ | `open` | 确保应用主窗口存在并写入 session 缓存 | `agent open firefox --session crm-export-001` |
77
+ | `probe` | 探测关键目标是否出现 | `agent probe firefox --targets "Download Export,Start Date"` |
78
+ | `observe` | 返回窗口 compact 状态摘要 | `agent observe firefox --mode uia --targets "Username,Password"` |
79
+ | `click` | 语义点击目标 | `agent click firefox "Sign in"` |
80
+ | `type` | 定位目标后输入 | `agent type firefox "Username" "user@example.com"` |
81
+ | `key` | 发送单键 | `agent key firefox escape` |
82
+ | `hotkey` | 发送组合键 | `agent hotkey firefox ctrl,l` |
83
+ | `scroll` | 滚动窗口 | `agent scroll firefox --direction down --amount 3 --dispatch foreground` |
84
+ | `session-clear` | 清理窗口缓存 | `agent session-clear crm-export-001` |
85
+
86
+ 同一个 GUI 任务建议固定一个 session:
87
+
88
+ ```bash
89
+ python -m remotecli.cli agent open firefox --session crm-export-001
90
+ python -m remotecli.cli agent probe firefox --targets "Download Export,Start Date" --session crm-export-001
91
+ python -m remotecli.cli agent click firefox "Download Export" --session crm-export-001
92
+ python -m remotecli.cli agent session-clear crm-export-001
93
+ ```
94
+
95
+ 也可以用环境变量省略每条命令的 `--session`:
96
+
97
+ ```powershell
98
+ $env:REMOTECLI_SESSION="crm-export-001"
99
+ python -m remotecli.cli agent probe firefox --targets "Download Export"
100
+ python -m remotecli.cli agent click firefox "Download Export"
101
+ python -m remotecli.cli agent session-clear
102
+ ```
103
+
104
+ 窗口缓存控制:
105
+
106
+ - `--refresh-window`:强制重新解析窗口并更新缓存。
107
+ - `--no-window-cache`:完全绕过缓存,适合多窗口排查。
108
+ - 不传 session:不读写窗口缓存。
109
+
110
+ ### probe 和 observe
111
+
112
+ 页面 ready check 优先用 `agent probe`,不要一上来扫完整页面。
113
+
114
+ ```bash
115
+ python -m remotecli.cli agent probe firefox --targets "Download Export,Start Date" --mode smart
116
+ python -m remotecli.cli agent observe firefox --mode uia --targets "Username,Password,Sign in"
117
+ python -m remotecli.cli agent observe firefox --mode vision
118
+ python -m remotecli.cli agent observe firefox --mode som-full
119
+ ```
120
+
121
+ 模式含义:
122
+
123
+ | 模式 | 用途 |
124
+ |---|---|
125
+ | `uia` | 读取 UIA/AX 树,适合后台系统、普通表单、调试页面结构 |
126
+ | `vision` | 只截图,不遍历 UIA/SOM |
127
+ | `som-full` | 全量 YOLO/OCR + 标注图,仅用于 UIA 缺失后的兜底或调试 |
128
+ | `smart` | `probe` 默认模式,先 UIA,目标未命中再走 SOM/OCR |
129
+
130
+ `agent click/type` 使用独立 SmartFind 定位链路,不依赖 `observe` 返回的元素全集。如果 `observe` 结果里已经有目标元素,下一步直接行动,不要重复 observe。
131
+
132
+ ## CUA 桌面控制
133
+
134
+ ```bash
135
+ python -m remotecli.cli [global flags] cua <action> [args]
136
+ ```
137
+
138
+ `cua` 是底层桌面控制入口。普通 Agent 优先用 `agent`;以下场景直接用 `cua`:
139
+
140
+ - 已经知道准确 `pid/window_id`。
141
+ - 需要坐标点击、右键、双击、拖拽、真实滚轮事件。
142
+ - 一个应用有多个窗口,需要人工选择窗口。
143
+ - 需要异步提交任务并保留 `trace_id`。
144
+
145
+ 常用命令:
146
+
147
+ | 命令 | 用途 | 示例 |
148
+ |---|---|---|
149
+ | `list-apps` | 列出运行应用 | `cua list-apps --query Firefox` |
150
+ | `list-windows` | 列出窗口 | `cua list-windows --pid 17376` |
151
+ | `launch-app` | 启动应用 | `cua launch-app --name notepad.exe` |
152
+ | `bring-to-front` | 窗口置前 | `cua bring-to-front --pid 17376 --window-id 7014188` |
153
+ | `get-window-state` | 获取窗口状态或截图 | `cua get-window-state --pid 17376 --window-id 7014188 --mode uia` |
154
+ | `probe-window` | 探测关键目标 | `cua probe-window --pid 17376 --window-id 7014188 --targets "Save,Cancel"` |
155
+ | `click` | 语义或坐标点击 | `cua click --pid 17376 --window-id 7014188 --target 保存` |
156
+ | `type-text` | 输入文本 | `cua type-text --pid 17376 --window-id 7014188 --target 文件名 --text report.txt` |
157
+ | `set-value` | 设置控件值 | `cua set-value --pid 17376 --window-id 7014188 --target 数量 --value 10` |
158
+ | `hotkey` | 组合键 | `cua hotkey --pid 17376 --window-id 7014188 --keys ctrl,s` |
159
+ | `press-key` | 单键 | `cua press-key --pid 17376 --window-id 7014188 --key enter` |
160
+ | `scroll` | 滚动 | `cua scroll --pid 17376 --window-id 7014188 --direction down --amount 3 --dispatch foreground` |
161
+ | `move-mouse` | 验证屏幕坐标落点 | `cua move-mouse --x 500 --y 300` |
162
+ | `drag` | 按住拖拽 | `cua drag --pid 17376 --window-id 7014188 --from-x 100 --from-y 100 --to-x 400 --to-y 100` |
163
+
164
+ 定位规则:
165
+
166
+ - 优先用 `--target` 语义定位,不要优先猜坐标。
167
+ - `click/type-text/set-value` 支持 `--locate-mode smart|uia|som`。
168
+ - `smart` 默认先 UIA-only,UIA 找不到才截图 + SOM/OCR。
169
+ - `uia` 适合可访问控件,速度最快。
170
+ - `som` 适合无障碍树缺失或视觉复杂页面。
171
+ - 坐标使用客户机物理屏幕像素,不依赖固定分辨率或 DPI。
172
+ - 坐标不确定时先 `move-mouse --x ... --y ...` 验证落点。
173
+ - 普通鼠标移动不要用 `drag`;只有明确需要按住拖拽时才用。
174
+
175
+ `get-window-state` 是唯一截图入口:
176
+
177
+ ```bash
178
+ python -m remotecli.cli cua get-window-state --pid 17376 --window-id 7014188 --mode vision
179
+ python -m remotecli.cli cua get-window-state --pid 17376 --window-id 7014188 --mode som-full
180
+ ```
181
+
182
+ 如果 `click/type-text/set-value --target` 返回 `TARGET_NOT_RESOLVED`,通常表示目标不可见、页面未加载、被弹窗挡住或 UIA/SOM 都未命中。先 `get-window-state` 或 `agent observe` 看当前窗口,处理遮挡后再重试,不要重复点击背后的目标。
183
+
184
+ ## Shell 远程命令
185
+
186
+ ```bash
187
+ python -m remotecli.cli [global flags] shell <action> [args]
188
+ ```
189
+
190
+ `shell` 走 `native.shell` capability,在目标 Runtime 节点本机执行。适合环境探测、短脚本、启动 Windows 应用;涉及桌面交互时,启动后继续用 `agent` 或 `cua` 操作窗口。
191
+
192
+ | 命令 | 用途 | 示例 |
193
+ |---|---|---|
194
+ | `info` | 获取目标机器环境 | `shell info` |
195
+ | `exec` | 执行单条命令 | `shell exec --cmd "whoami"` |
196
+ | `exec-script` | 执行多行脚本 | `shell exec-script --shell powershell --script "Get-Process | Select-Object -First 5"` |
197
+
198
+ PowerShell 脚本建议用单引号包住整段 `--script`,避免 `$_.Name` 被本地 shell 展开。
199
+
200
+ 打开 Windows 应用时,不要猜 AppID,先查真实启动目标:
201
+
202
+ ```bash
203
+ python -m remotecli.cli shell exec-script --shell powershell --script 'Get-StartApps | Where-Object {$_.Name -like "*微信*"}'
204
+ python -m remotecli.cli shell exec-script --shell powershell --script '$app = Get-StartApps | Where-Object {$_.Name -like "*微信*"} | Select-Object -First 1; Start-Process ("shell:AppsFolder\" + $app.AppID)'
205
+ ```
206
+
207
+ ## RPA 流程
208
+
209
+ ```bash
210
+ python -m remotecli.cli [global flags] rpa <action> [args]
211
+ ```
212
+
213
+ `rpa` 用于执行 Runtime 侧预定义的 Robot Framework 流程。当前可用流程:
214
+
215
+ | Flow ID | 任务 |
216
+ |---|---|
217
+ | `crm-transaction-filter` | `01 - Fill Transaction Date Range` |
218
+
219
+ 示例:
220
+
221
+ ```bash
222
+ python -m remotecli.cli --wait rpa run \
223
+ --flow crm-transaction-filter \
224
+ --task "01 - Fill Transaction Date Range" \
225
+ --param START_DATE=20260701 \
226
+ --param END_DATE=20260701
227
+ ```
228
+
229
+ 规则:
230
+
231
+ - 参数用重复的 `--param KEY=VALUE` 传入。
232
+ - Runtime 会把参数转为 Robot Framework 变量:`--variable KEY:VALUE`。
233
+ - Robot 文件里用 `${KEY}` 读取。
234
+ - 参数名必须匹配 `[A-Za-z_][A-Za-z0-9_]*`。
235
+ - 参数值按字符串传递;含空格或特殊字符时按当前 shell 规则给整个 `KEY=VALUE` 加引号。
236
+
237
+ ## 结果和输出
238
+
239
+ 底层 `cua` / `shell` / `rpa` 默认异步提交,返回:
240
+
241
+ ```json
242
+ {"trace_id": "task_xxx", "status": "queued"}
243
+ ```
244
+
245
+ 查询结果:
246
+
247
+ ```bash
248
+ python -m remotecli.cli result <trace_id>
249
+ ```
250
+
251
+ 自动等待结果:
252
+
253
+ ```bash
254
+ python -m remotecli.cli --wait shell info
255
+ python -m remotecli.cli --wait --wait-timeout 60 cua click --pid 17376 --window-id 7014188 --target 保存
256
+ ```
257
+
258
+ 注意:`--wait` 必须放在 `shell` / `cua` / `rpa` 前。`agent ...` 默认已经等待最终结果,不需要顶层 `--wait`。
259
+
260
+ `agent` 命令输出会尽量压平成 AI 友好的 JSON:
261
+
262
+ ```json
263
+ {
264
+ "ok": true,
265
+ "trace_id": "task_xxx",
266
+ "stdout": "...",
267
+ "stderr": "",
268
+ "exit_code": 0,
269
+ "json": null,
270
+ "error": ""
271
+ }
272
+ ```
273
+
274
+ GUI 类 `agent` 命令还会带:
275
+
276
+ ```json
277
+ {
278
+ "ok": true,
279
+ "action": "click",
280
+ "pid": 8748,
281
+ "window_id": 460902,
282
+ "title": "GitHub - Mozilla Firefox",
283
+ "window_cached": true
284
+ }
285
+ ```
286
+
287
+ ## AI 集成
288
+
289
+ 推荐让 AI 通过 subprocess 调 CLI,最容易隔离依赖和认证配置:
290
+
291
+ ```python
292
+ import json
293
+ import subprocess
294
+
295
+ BASE = [
296
+ "python", "-m", "remotecli.cli",
297
+ "--middleware", "http://10.0.0.5:9100",
298
+ "--tenant", "acme_shanghai",
299
+ "--node", "sh_win_01",
300
+ "--handle", "wch_v1_...",
301
+ ]
302
+
303
+ def call_remotecli(args: list[str]) -> dict:
304
+ result = subprocess.run(BASE + args, capture_output=True, text=True, timeout=60)
305
+ result.check_returncode()
306
+ return json.loads(result.stdout)
307
+
308
+ call_remotecli(["agent", "ps", "whoami"])
309
+ call_remotecli(["agent", "click", "firefox", "Sign in"])
310
+ call_remotecli(["--wait", "shell", "info"])
311
+ ```
312
+
313
+ 也可以直接用 Python client:
314
+
315
+ ```python
316
+ from remotecli.client import RemoteCliClient
317
+
318
+ client = RemoteCliClient(
319
+ middleware_url="http://10.0.0.5:9100",
320
+ tenant_id="acme_shanghai",
321
+ node_id="sh_win_01",
322
+ handle="wch_v1_...",
323
+ )
324
+
325
+ queued = client.submit("desktop.cua", "click", {
326
+ "pid": 17376,
327
+ "window_id": 7014188,
328
+ "target": "保存",
329
+ })
330
+ result = client.poll_result(queued["trace_id"])
331
+ ```
332
+
333
+ ## 典型流程
334
+
335
+ 打开应用、输入并保存,普通 Agent 优先这样写:
336
+
337
+ ```bash
338
+ python -m remotecli.cli agent open notepad --session note-001
339
+ python -m remotecli.cli agent type notepad "Text Editor" "hello world" --session note-001
340
+ python -m remotecli.cli agent hotkey notepad ctrl,s --session note-001
341
+ python -m remotecli.cli agent type notepad "文件名" "hello.txt" --session note-001
342
+ python -m remotecli.cli agent key notepad enter --session note-001
343
+ python -m remotecli.cli agent session-clear note-001
344
+ ```
345
+
346
+ 已有 `pid/window_id` 或需要底层调试时:
347
+
348
+ ```bash
349
+ python -m remotecli.cli --wait cua get-window-state --pid <pid> --window-id <wid> --mode uia
350
+ python -m remotecli.cli --wait cua click --pid <pid> --window-id <wid> --target 保存 --locate-mode smart
351
+ ```
352
+
353
+ ## 错误处理
354
+
355
+ | 错误 | 含义 | 处理 |
356
+ |---|---|---|
357
+ | `AUTH_HANDLE_REQUIRED` | strict 模式下没传 handle | 加 `--handle wch_v1_...` |
358
+ | `AUTH_HANDLE_INVALID` | handle 无效或过期 | 重新签发 handle |
359
+ | `AUTH_TENANT_DENIED` | handle 不允许访问该 tenant | 检查 `--tenant` |
360
+ | `busy` / `409` | 节点被其他 Agent 租约占用 | 稍后重试或换 `--node` |
361
+ | `NODE_NO_RESPONSE` | Middleware 下发后 Runtime 无 ACK | 检查 Runtime、Broker、节点注册状态 |
362
+ | `Unknown capability` | 目标 capability 未注册 | 检查 Runtime 插件是否加载 |
363
+ | `TARGET_NOT_RESOLVED` | 目标不可见或定位失败 | 先观察窗口,处理弹窗/遮挡/页面加载后重试 |
364
+
365
+ ## 常见问题
366
+
367
+ **截图在哪里?**
368
+ `cua get-window-state --mode vision` 返回 screenshot 元数据,例如 `local_path`、`size_bytes`、`width`、`height`。截图 PNG 保存在客户机本地 `runtime_state/screenshots/`。Agent 与 Runtime 同机时可直接读 `local_path`;跨机访问需要另行提供文件访问通道。
369
+
370
+ **handle 是必须的吗?**
371
+ 取决于 Middleware 启动模式。demo mode 下 handle 可选;strict auth 模式下所有任务都必须带 handle。
372
+
373
+ **能同时控制多台客户机吗?**
374
+ 能。不同 `--node` 指向不同客户机。一台客户机同一时刻只允许一个 Agent 独占控制。
375
+
376
+ **四个子文档还要维护吗?**
377
+ 只维护速查和入口说明。完整规则集中在本文件,避免重复内容互相过期。
378
+
379
+ ## 目录
380
+
381
+ ```text
382
+ remotecli/
383
+ ├── cli.py
384
+ ├── client.py
385
+ ├── agent.py
386
+ ├── cua.py
387
+ ├── shell.py
388
+ ├── rpa.py
389
+ ├── config/
390
+ │ └── agentremote.cli.toml
391
+ └── guides/
392
+ ├── GUIDE.md # 主文档
393
+ ├── agent.md # Agent 高层命令速查
394
+ ├── cua.md # CUA 底层命令速查
395
+ ├── shell.md # Shell 命令速查
396
+ └── rpa.md # RPA 流程速查
397
+ ```
@@ -0,0 +1,60 @@
1
+ # Agent 命令速查
2
+
3
+ 完整规则见 [GUIDE.md](./GUIDE.md)。本文件只保留普通 AI Agent 最常用入口。
4
+
5
+ `agent` 是默认推荐入口:
6
+
7
+ ```bash
8
+ python -m remotecli.cli agent <action> [args]
9
+ ```
10
+
11
+ 它会自动等待最终结果、解包 `result.output`,并在 GUI 操作前按应用名查找真实 `pid/window_id`。
12
+
13
+ ## 什么时候用
14
+
15
+ | 目标 | 命令 |
16
+ |---|---|
17
+ | 执行 PowerShell | `agent ps "<script>"` |
18
+ | 执行 cmd | `agent cmd "<command>"` |
19
+ | 确保应用窗口存在 | `agent open <app>` |
20
+ | 判断按钮/输入框是否出现 | `agent probe <app> --targets "A,B"` |
21
+ | 看窗口 compact 状态 | `agent observe <app>` |
22
+ | 点击目标 | `agent click <app> "<target>"` |
23
+ | 输入文本 | `agent type <app> "<target>" "<text>"` |
24
+ | 单键 | `agent key <app> enter` |
25
+ | 组合键 | `agent hotkey <app> ctrl,l` |
26
+ | 滚动 | `agent scroll <app> --direction down --amount 3` |
27
+ | 清理窗口缓存 | `agent session-clear <session>` |
28
+
29
+ ## 常用示例
30
+
31
+ ```bash
32
+ python -m remotecli.cli agent ps "Get-Process | Select-Object -First 5"
33
+ python -m remotecli.cli agent open firefox --session crm-export-001
34
+ python -m remotecli.cli agent probe firefox --targets "Download Export,Start Date" --session crm-export-001
35
+ python -m remotecli.cli agent click firefox "Download Export" --session crm-export-001
36
+ python -m remotecli.cli agent session-clear crm-export-001
37
+ ```
38
+
39
+ ## 关键规则
40
+
41
+ - `agent ...` 默认等待最终结果,不需要顶层 `--wait`。
42
+ - 同一个 GUI 任务建议固定一个 `--session`,避免每步重复查窗口。
43
+ - 页面 ready check 优先用 `probe`,不要先扫完整页面。
44
+ - `observe --mode uia` 用于查看页面结构;`--mode vision` 只截图;`--mode som-full` 只用于 UIA 缺失后的调试。
45
+ - `click/type` 有自己的 SmartFind 定位链路,不依赖 `observe` 返回完整元素列表。
46
+ - 多窗口手选、坐标点击、右键、拖拽、异步任务、固定 RPA 流程,降到底层 `cua` / `shell` / `rpa`。
47
+
48
+ ## 窗口缓存
49
+
50
+ ```powershell
51
+ $env:REMOTECLI_SESSION="crm-export-001"
52
+ python -m remotecli.cli agent probe firefox --targets "Start Date,End Date"
53
+ python -m remotecli.cli agent click firefox "Download Export"
54
+ python -m remotecli.cli agent session-clear
55
+ ```
56
+
57
+ 调试缓存:
58
+
59
+ - `--refresh-window`:强制重新解析并更新缓存。
60
+ - `--no-window-cache`:绕过缓存。
@@ -0,0 +1,60 @@
1
+ # CUA 命令速查
2
+
3
+ 完整规则见 [GUIDE.md](./GUIDE.md)。本文件只保留底层桌面控制速查。
4
+
5
+ ```bash
6
+ python -m remotecli.cli [global flags] cua <action> [args]
7
+ ```
8
+
9
+ 普通 AI Agent 优先用 `agent` 子命令。只有需要 `pid/window_id`、坐标、右键、拖拽、多窗口手选或异步任务时,直接用 `cua`。
10
+
11
+ ## 常用命令
12
+
13
+ | 目标 | 命令示例 |
14
+ |---|---|
15
+ | 查运行应用 | `cua list-apps --query Firefox` |
16
+ | 查窗口 | `cua list-windows --pid 17376` |
17
+ | 启动应用 | `cua launch-app --name notepad.exe` |
18
+ | 前置窗口 | `cua bring-to-front --pid 17376 --window-id 7014188` |
19
+ | 获取 UIA 状态 | `cua get-window-state --pid 17376 --window-id 7014188 --mode uia` |
20
+ | 只截图 | `cua get-window-state --pid 17376 --window-id 7014188 --mode vision` |
21
+ | SOM/OCR 调试 | `cua get-window-state --pid 17376 --window-id 7014188 --mode som-full` |
22
+ | 探测目标 | `cua probe-window --pid 17376 --window-id 7014188 --targets "Save,Cancel"` |
23
+ | 语义点击 | `cua click --pid 17376 --window-id 7014188 --target 保存` |
24
+ | 输入文本 | `cua type-text --pid 17376 --window-id 7014188 --target 文件名 --text report.txt` |
25
+ | 设置控件值 | `cua set-value --pid 17376 --window-id 7014188 --target 数量 --value 10` |
26
+ | 热键 | `cua hotkey --pid 17376 --window-id 7014188 --keys ctrl,s` |
27
+ | 单键 | `cua press-key --pid 17376 --window-id 7014188 --key enter` |
28
+ | 滚动 | `cua scroll --pid 17376 --window-id 7014188 --direction down --amount 3 --dispatch foreground` |
29
+ | 验证坐标 | `cua move-mouse --x 500 --y 300` |
30
+ | 拖拽 | `cua drag --pid 17376 --window-id 7014188 --from-x 100 --from-y 100 --to-x 400 --to-y 100` |
31
+
32
+ 底层命令默认异步返回 `trace_id`。需要等待时:
33
+
34
+ ```bash
35
+ python -m remotecli.cli --wait cua click --pid 17376 --window-id 7014188 --target 保存
36
+ ```
37
+
38
+ `--wait` 必须放在 `cua` 前。
39
+
40
+ ## 定位规则
41
+
42
+ - 优先用 `--target`,不要优先猜坐标。
43
+ - `click/type-text/set-value` 支持 `--locate-mode smart|uia|som`。
44
+ - `smart` 默认先 UIA-only,UIA 找不到才截图 + SOM/OCR。
45
+ - `uia` 适合可访问控件,速度最快。
46
+ - `som` 适合 UIA 缺失或视觉复杂页面。
47
+ - 坐标使用客户机物理屏幕像素。
48
+ - 坐标不确定时先 `move-mouse` 验证落点。
49
+ - 普通鼠标移动不要用 `drag`;只有明确需要按住拖拽时才用。
50
+
51
+ ## 失败处理
52
+
53
+ `TARGET_NOT_RESOLVED` 表示目标不可见、页面未加载、被弹窗挡住或定位链路未命中。先观察窗口状态:
54
+
55
+ ```bash
56
+ python -m remotecli.cli --wait cua get-window-state --pid 17376 --window-id 7014188 --mode uia
57
+ python -m remotecli.cli --wait cua get-window-state --pid 17376 --window-id 7014188 --mode vision
58
+ ```
59
+
60
+ 处理弹窗、遮挡或页面加载后再重试,不要重复点击背后的目标。
@@ -0,0 +1,45 @@
1
+ # RPA 命令速查
2
+
3
+ 完整规则见 [GUIDE.md](./GUIDE.md)。本文件只保留 Robot Framework 流程速查。
4
+
5
+ ```bash
6
+ python -m remotecli.cli [global flags] rpa <action> [args]
7
+ ```
8
+
9
+ `rpa` 用于执行 Runtime 侧已经注册的固定业务流程,不用于临时桌面操作。
10
+
11
+ ## 常用命令
12
+
13
+ ```bash
14
+ python -m remotecli.cli rpa list-flows
15
+ ```
16
+
17
+ ```bash
18
+ python -m remotecli.cli --wait rpa run \
19
+ --flow crm-transaction-filter \
20
+ --task "01 - Fill Transaction Date Range" \
21
+ --param START_DATE=20260701 \
22
+ --param END_DATE=20260701
23
+ ```
24
+
25
+ 当前流程:
26
+
27
+ | Flow ID | 任务 |
28
+ |---|---|
29
+ | `crm-transaction-filter` | `01 - Fill Transaction Date Range` |
30
+
31
+ ## 参数规则
32
+
33
+ - 参数用重复的 `--param KEY=VALUE` 传入。
34
+ - Runtime 会转成 Robot Framework 变量:`--variable KEY:VALUE`。
35
+ - Robot 文件里用 `${KEY}` 读取。
36
+ - 参数名必须匹配 `[A-Za-z_][A-Za-z0-9_]*`。
37
+ - 参数值按字符串传递;含空格或特殊字符时给整个 `KEY=VALUE` 加引号。
38
+
39
+ ## 等待结果
40
+
41
+ 底层 `rpa` 默认异步返回 `trace_id`。自动等待时把 `--wait` 放在 `rpa` 前:
42
+
43
+ ```bash
44
+ python -m remotecli.cli --wait --wait-timeout 120 rpa run --flow crm-transaction-filter --task "01 - Fill Transaction Date Range"
45
+ ```
@@ -0,0 +1,49 @@
1
+ # Shell 命令速查
2
+
3
+ 完整规则见 [GUIDE.md](./GUIDE.md)。本文件只保留远程 Shell 速查。
4
+
5
+ ```bash
6
+ python -m remotecli.cli [global flags] shell <action> [args]
7
+ ```
8
+
9
+ `shell` 走 `native.shell` capability,在目标 Runtime 节点本机执行。适合环境探测、短脚本、启动应用;桌面交互继续用 `agent` 或 `cua`。
10
+
11
+ ## 常用命令
12
+
13
+ ```bash
14
+ python -m remotecli.cli --wait shell info
15
+ python -m remotecli.cli --wait shell exec --cmd "whoami"
16
+ python -m remotecli.cli --wait --wait-timeout 60 shell exec --cmd "dir C:\\"
17
+ ```
18
+
19
+ 执行脚本:
20
+
21
+ ```bash
22
+ python -m remotecli.cli --wait shell exec-script --shell powershell --script "Get-Process | Select-Object -First 5"
23
+ python -m remotecli.cli --wait shell exec-script --shell cmd --script "@echo off\r\necho Hello"
24
+ python -m remotecli.cli --wait shell exec-script --shell bash --script "echo hello; ls -la"
25
+ ```
26
+
27
+ 支持的 shell 取决于目标 Runtime 机器,通常包括 `cmd`、`powershell`、`pwsh`、`bash`、`sh`。
28
+
29
+ ## 打开 Windows 应用
30
+
31
+ 不要猜 AppID,先查真实启动目标:
32
+
33
+ ```bash
34
+ python -m remotecli.cli --wait shell exec-script --shell powershell --script 'Get-StartApps | Where-Object {$_.Name -like "*微信*"}'
35
+ python -m remotecli.cli --wait shell exec-script --shell powershell --script '$app = Get-StartApps | Where-Object {$_.Name -like "*微信*"} | Select-Object -First 1; Start-Process ("shell:AppsFolder\" + $app.AppID)'
36
+ ```
37
+
38
+ 然后用 `agent` 或 `cua` 操作窗口:
39
+
40
+ ```bash
41
+ python -m remotecli.cli agent probe 微信 --targets "进入微信"
42
+ python -m remotecli.cli agent click 微信 "进入微信"
43
+ ```
44
+
45
+ ## 关键规则
46
+
47
+ - 底层 `shell` 默认异步返回 `trace_id`;自动等待时把 `--wait` 放在 `shell` 前。
48
+ - PowerShell 脚本建议用单引号包住整段 `--script`,避免 `$_.Name` 被本地 shell 展开。
49
+ - 长时间任务设置 `--wait-timeout` 或底层命令自己的 `--timeout`。
remotecli/rpa.py ADDED
@@ -0,0 +1,57 @@
1
+ """
2
+ remotecli rpa — RPA 流程执行子命令.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ import re
8
+ from typing import Any, Dict
9
+
10
+ from .client import RemoteCliClient
11
+
12
+ _PARAM_NAME_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
13
+
14
+
15
+ class RpaCommands:
16
+ """RPA 流程命令构建器。"""
17
+
18
+ def __init__(self, client: RemoteCliClient) -> None:
19
+ self._client = client
20
+
21
+ def run(
22
+ self,
23
+ flow: str,
24
+ task: str = "",
25
+ timeout_sec: int = 180,
26
+ params: Dict[str, Any] | None = None,
27
+ ) -> Dict[str, Any]:
28
+ """Execute an RPA flow."""
29
+ args: Dict[str, Any] = {"flow": flow, "task": task}
30
+ normalized_params = _normalize_params(params)
31
+ if normalized_params:
32
+ args["params"] = normalized_params
33
+ return self._client.submit(
34
+ capability_id=flow, # flow id IS the capability id
35
+ tool="run",
36
+ args=args,
37
+ timeout_sec=timeout_sec,
38
+ )
39
+
40
+ def list_flows(self) -> Dict[str, Any]:
41
+ """List available RPA flows."""
42
+ caps = self._client.list_capabilities()
43
+ capabilities = caps.get("capabilities", [])
44
+ rpa_flows = [c for c in capabilities if c.get("runner") == "rpa"]
45
+ return {"flows": rpa_flows}
46
+
47
+
48
+ def _normalize_params(params: Dict[str, Any] | None) -> Dict[str, str]:
49
+ if not params:
50
+ return {}
51
+ normalized: Dict[str, str] = {}
52
+ for key, value in params.items():
53
+ name = str(key).strip()
54
+ if not _PARAM_NAME_RE.match(name):
55
+ raise ValueError(f"invalid RPA param name: {name}")
56
+ normalized[name] = "" if value is None else str(value)
57
+ return normalized