shellx-ai 1.0.12 → 1.1.0
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 +21 -0
- package/README.md +586 -0
- package/dist/automation/element-finder.d.ts +189 -0
- package/dist/automation/element-finder.js +322 -0
- package/dist/automation/element-finder.js.map +1 -0
- package/dist/automation/ui-action-handler.d.ts +330 -0
- package/dist/automation/ui-action-handler.js +873 -0
- package/dist/automation/ui-action-handler.js.map +1 -0
- package/dist/cbor-compat.d.ts +27 -0
- package/dist/cbor-compat.js +108 -0
- package/dist/cbor-compat.js.map +1 -0
- package/dist/domain-manager.d.ts +80 -0
- package/dist/domain-manager.js +158 -0
- package/dist/domain-manager.js.map +1 -0
- package/dist/error-handler.d.ts +87 -0
- package/dist/error-handler.js +148 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/errors.d.ts +114 -0
- package/dist/errors.js +139 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +163 -54
- package/dist/index.js +706 -480
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +81 -0
- package/dist/logger.js +128 -0
- package/dist/logger.js.map +1 -0
- package/dist/protocol.d.ts +147 -31
- package/dist/protocol.js +2 -2
- package/dist/protocol.js.map +1 -0
- package/dist/shell/output-buffer.d.ts +152 -0
- package/dist/shell/output-buffer.js +163 -0
- package/dist/shell/output-buffer.js.map +1 -0
- package/dist/shell/shell-command-executor.d.ts +182 -0
- package/dist/shell/shell-command-executor.js +348 -0
- package/dist/shell/shell-command-executor.js.map +1 -0
- package/dist/shellx.d.ts +681 -178
- package/dist/shellx.js +762 -1159
- package/dist/shellx.js.map +1 -0
- package/dist/types.d.ts +132 -57
- package/dist/types.js +4 -4
- package/dist/types.js.map +1 -0
- package/dist/utils/retry-helper.d.ts +73 -0
- package/dist/utils/retry-helper.js +92 -0
- package/dist/utils/retry-helper.js.map +1 -0
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +17 -23
- package/dist/utils.js.map +1 -0
- package/package.json +95 -62
package/dist/shellx.d.ts
CHANGED
|
@@ -1,204 +1,707 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
/**
|
|
2
|
+
* ShellX - High-level automation utilities for Android device control
|
|
3
|
+
*
|
|
4
|
+
* This module provides a comprehensive API for automating Android devices,
|
|
5
|
+
* including UI actions, shell commands, element finding, and device information.
|
|
6
|
+
*
|
|
7
|
+
* @module shellx
|
|
8
|
+
*/
|
|
9
|
+
import type { ElementSelector, UIElement, WsServer } from "./protocol.js";
|
|
10
|
+
import type { Actions, AppInfo, AppInfoResult, BaseResult, Click, ClickResult, Clipboard, ClipboardResult, Command, CommandResult as TypesCommandResult, Element, ExecuteActionsResult, Find, FindResult as TypesFindResult, Input, InputResult, Key, KeyResult, ScreenInfoResult, Screenshot, ScreenshotResult, Swipe, SwipeResult, Wait, WaitResult } from "./types.js";
|
|
11
|
+
import ConnectionClient from "./index.js";
|
|
12
|
+
import { type LogLevel } from "./logger.js";
|
|
13
|
+
import type { WsClient } from "./protocol.js";
|
|
14
|
+
export type { UIElement, ElementSelector };
|
|
15
|
+
export type { LogLevel } from "./logger.js";
|
|
16
|
+
export type { Click, Input, Swipe, Key, Wait, Find, Command, AppInfo, Screenshot, Clipboard, Actions, ClickResult, InputResult, SwipeResult, KeyResult, WaitResult, TypesFindResult as FindResult, TypesCommandResult as CommandResult, ClipboardResult, AppInfoResult, ScreenshotResult, ScreenInfoResult, ExecuteActionsResult, BaseResult, Element, };
|
|
17
|
+
export type { ShellCommandResult, ShellCommandOptions } from "./shell/output-buffer.js";
|
|
18
|
+
/**
|
|
19
|
+
* Configuration options for ShellX instance
|
|
20
|
+
*/
|
|
21
|
+
export interface ShellXOptions {
|
|
22
|
+
/** Device ID (UUID or identifier) */
|
|
23
|
+
deviceId: string | undefined;
|
|
24
|
+
/** Connection timeout in milliseconds (default: 5000) */
|
|
15
25
|
timeout?: number;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
/** Enable automatic reconnection (default: true) */
|
|
27
|
+
reconnect?: boolean;
|
|
28
|
+
/** Maximum reconnection attempts (default: 5) */
|
|
29
|
+
reconnectMaxAttempts?: number;
|
|
30
|
+
/** Reconnection interval in milliseconds (default: 1000) */
|
|
31
|
+
reconnectInterval?: number;
|
|
32
|
+
/** Ping interval in milliseconds (default: 2000) */
|
|
33
|
+
pingInterval?: number;
|
|
34
|
+
/** Log level (default: LogLevel.INFO) */
|
|
35
|
+
logLevel?: LogLevel;
|
|
36
|
+
/** Callback when connection is opened */
|
|
37
|
+
onOpen?: () => void;
|
|
38
|
+
/** Callback when connection is closed */
|
|
39
|
+
onClose?: () => void;
|
|
40
|
+
/** Callback when connection error occurs */
|
|
41
|
+
onError?: (error?: Error | Event) => void;
|
|
42
|
+
/** Callback for reconnection failure */
|
|
43
|
+
onReconnectFailed?: () => void;
|
|
44
|
+
/** Callback for WebSocket messages */
|
|
45
|
+
onMessage?: (message: WsServer) => void;
|
|
22
46
|
}
|
|
23
47
|
/**
|
|
24
|
-
* ShellX automation
|
|
48
|
+
* ShellX - High-level Android automation SDK (Recommended API)
|
|
49
|
+
*
|
|
50
|
+
* **This is the recommended API for 95% of users.**
|
|
51
|
+
*
|
|
52
|
+
* ShellX provides a simple, intuitive interface for Android automation with:
|
|
53
|
+
*
|
|
54
|
+
* - ✅ Automatic error handling and retry logic
|
|
55
|
+
* - ✅ Type-safe TypeScript API
|
|
56
|
+
* - ✅ Consistent method signatures
|
|
57
|
+
* - ✅ Built-in timing and performance tracking
|
|
58
|
+
* - ✅ Simplified element selection
|
|
59
|
+
*
|
|
60
|
+
* **Key Features:**
|
|
61
|
+
* - UI interaction: click, input, swipe, press, wait
|
|
62
|
+
* - Element finding with smart selectors
|
|
63
|
+
* - Shell command execution
|
|
64
|
+
* - Screen info and screenshots
|
|
65
|
+
* - Batch operations
|
|
66
|
+
*
|
|
67
|
+
* **Quick Start:**
|
|
68
|
+
* ```typescript
|
|
69
|
+
* import { ShellX } from '@shellx-ai/sdk';
|
|
70
|
+
*
|
|
71
|
+
* // Initialize
|
|
72
|
+
* const shellx = new ShellX({ deviceId: 'your-device-id' });
|
|
73
|
+
*
|
|
74
|
+
* // Connect
|
|
75
|
+
* await shellx.connect();
|
|
76
|
+
*
|
|
77
|
+
* // Automate
|
|
78
|
+
* await shellx.click('Submit');
|
|
79
|
+
* await shellx.input({ text: 'Hello World' });
|
|
80
|
+
* await shellx.swipe({ fromX: 500, fromY: 1000, toX: 500, toY: 500 });
|
|
81
|
+
*
|
|
82
|
+
* // Get info
|
|
83
|
+
* const screen = await shellx.getScreenInfo();
|
|
84
|
+
* console.log(`Screen: ${screen.width}x${screen.height}`);
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* **Note:** For low-level WebSocket access, see ConnectionClient (advanced users only).
|
|
88
|
+
*
|
|
89
|
+
* @see API-GUIDE.md for comprehensive documentation
|
|
90
|
+
* @see ConnectionClient for low-level protocol access
|
|
25
91
|
*/
|
|
26
92
|
export declare class ShellX {
|
|
93
|
+
/** Logger instance for ShellX */
|
|
94
|
+
private logger;
|
|
95
|
+
/** UI action handler for executing UI operations */
|
|
96
|
+
private uiActionHandler;
|
|
97
|
+
/** Element finder for locating UI elements */
|
|
98
|
+
private elementFinder;
|
|
99
|
+
/** Shell command executor for running shell commands */
|
|
100
|
+
private shellCommandExecutor;
|
|
101
|
+
/** Connection client for device communication */
|
|
27
102
|
private client;
|
|
28
|
-
private shellOutputBuffers;
|
|
29
|
-
private shellCommandPromises;
|
|
30
|
-
constructor(client: ConnectionTaskClient);
|
|
31
|
-
/**
|
|
32
|
-
* Get the WebSocket client instance
|
|
33
|
-
*/
|
|
34
|
-
getClient(): ConnectionTaskClient;
|
|
35
|
-
/**
|
|
36
|
-
* 设置 shell 输出监听器(需要在创建 WebSocketTaskClient 时调用)
|
|
37
|
-
*/
|
|
38
|
-
static createShellOutputHandler(helpers: ShellX): (message: WsServer) => void;
|
|
39
|
-
/**
|
|
40
|
-
* 处理 shell 输出数据
|
|
41
|
-
*/
|
|
42
|
-
handleShellOutput(chunks: [any, number, Uint8Array[]]): void;
|
|
43
|
-
/**
|
|
44
|
-
* 清理命令输出,去除输入的命令内容
|
|
45
|
-
*/
|
|
46
|
-
private cleanCommandOutput;
|
|
47
|
-
/**
|
|
48
|
-
* 合并多个 session 的输出
|
|
49
|
-
*/
|
|
50
|
-
private combineSessionOutputs;
|
|
51
|
-
/**
|
|
52
|
-
* 通用重试机制 - 失败时返回 undefined 而不是抛出异常
|
|
53
|
-
*/
|
|
54
|
-
private withRetry;
|
|
55
|
-
/**
|
|
56
|
-
* 转换精简选择器为原始选择器
|
|
57
|
-
*/
|
|
58
|
-
private convertSelector;
|
|
59
|
-
/**
|
|
60
|
-
* 转换精简元素为原始元素
|
|
61
|
-
*/
|
|
62
|
-
private convertElement;
|
|
63
|
-
/**
|
|
64
|
-
* 点击操作 - 支持元素ID、坐标或选择器
|
|
65
|
-
*/
|
|
66
|
-
click(clickData: Click): Promise<ActionResult>;
|
|
67
|
-
/**
|
|
68
|
-
* 输入操作 - 支持元素ID、资源ID或选择器
|
|
69
|
-
*/
|
|
70
|
-
input(inputData: Input): Promise<ActionResult>;
|
|
71
|
-
/**
|
|
72
|
-
* 滑动操作 - 支持坐标点
|
|
73
|
-
*/
|
|
74
|
-
swipe(swipeData: Swipe): Promise<ActionResult>;
|
|
75
|
-
/**
|
|
76
|
-
* 按键操作
|
|
77
|
-
*/
|
|
78
|
-
pressKey(keyData: Key): Promise<ActionResult>;
|
|
79
|
-
/**
|
|
80
|
-
* 等待操作 - 等待元素出现或消失
|
|
81
|
-
*/
|
|
82
|
-
wait(waitData: Wait): Promise<ActionResult>;
|
|
83
|
-
/**
|
|
84
|
-
* 查找操作 - 查找元素
|
|
85
|
-
*/
|
|
86
|
-
find(findData: Find): Promise<FindResult>;
|
|
87
|
-
/**
|
|
88
|
-
* 执行命令 - 兼容现有的 shell 命令执行
|
|
89
|
-
*/
|
|
90
|
-
executeCommand(commandData: Command): Promise<CommandResult>;
|
|
91
|
-
executeCodeEval(context: any, code: string, timeout?: number): Promise<any>;
|
|
92
|
-
executeCode(agentCode: string, context: any, timeout?: number): Promise<any>;
|
|
93
|
-
/**
|
|
94
|
-
* 获取应用信息
|
|
95
|
-
*/
|
|
96
|
-
getAppInfo(appInfoData: AppInfo): Promise<ActionResult>;
|
|
97
103
|
/**
|
|
98
|
-
*
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
*
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
*
|
|
104
|
+
* Creates a ShellX instance
|
|
105
|
+
*
|
|
106
|
+
* @param options - Configuration options for ShellX instance
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const shellx = new ShellX({
|
|
111
|
+
* deviceId: 'device-id',
|
|
112
|
+
* onOpen: () => console.log('Connected!'),
|
|
113
|
+
* onMessage: (msg) => console.log(msg)
|
|
114
|
+
* });
|
|
115
|
+
*
|
|
116
|
+
* // Optionally wait for connection
|
|
117
|
+
* await shellx.ready();
|
|
118
|
+
*
|
|
119
|
+
* // Start using ShellX
|
|
120
|
+
* await shellx.click('Settings');
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
constructor(options: ShellXOptions);
|
|
124
|
+
/**
|
|
125
|
+
* Wait for connection to be ready
|
|
126
|
+
*
|
|
127
|
+
* This method waits for the WebSocket connection to be established.
|
|
128
|
+
* Most operations will automatically wait for connection, but you can
|
|
129
|
+
* call this method explicitly if you need to ensure connection before
|
|
130
|
+
* performing operations.
|
|
131
|
+
*
|
|
132
|
+
* @returns Promise that resolves when connection is ready
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* const shellx = new ShellX({ deviceId: 'device-id' });
|
|
137
|
+
* await shellx.ready();
|
|
138
|
+
* console.log('Connection is ready!');
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
ready(): Promise<void>;
|
|
142
|
+
/**
|
|
143
|
+
* Get the underlying ConnectionClient instance
|
|
144
|
+
*
|
|
145
|
+
* @returns The ConnectionClient instance
|
|
146
|
+
*/
|
|
147
|
+
getClient(): ConnectionClient;
|
|
148
|
+
/**
|
|
149
|
+
* Get the current log level
|
|
150
|
+
*
|
|
151
|
+
* @returns Current log level
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const shellx = new ShellX({ deviceId: 'device-id' });
|
|
156
|
+
* console.log('Current log level:', shellx.getLogLevel());
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
getLogLevel(): LogLevel;
|
|
160
|
+
/**
|
|
161
|
+
* Set the log level
|
|
162
|
+
*
|
|
163
|
+
* @param level - Log level to set
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* import { ShellX, LogLevel } from '@shellx-ai/sdk';
|
|
168
|
+
*
|
|
169
|
+
* const shellx = new ShellX({ deviceId: 'device-id' });
|
|
170
|
+
* shellx.setLogLevel(LogLevel.NONE); // Disable all logging
|
|
171
|
+
* shellx.setLogLevel(LogLevel.ERROR); // Only errors
|
|
172
|
+
* shellx.setLogLevel(LogLevel.DEBUG); // All logs
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
setLogLevel(level: LogLevel): void;
|
|
176
|
+
/**
|
|
177
|
+
* Enable all logging (equivalent to setLogLevel(LogLevel.DEBUG))
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* const shellx = new ShellX({ deviceId: 'device-id' });
|
|
182
|
+
* shellx.enableDebugLogging();
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
enableDebugLogging(): void;
|
|
186
|
+
/**
|
|
187
|
+
* Disable all logging (equivalent to setLogLevel(LogLevel.NONE))
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* const shellx = new ShellX({ deviceId: 'device-id' });
|
|
192
|
+
* shellx.disableLogging();
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
disableLogging(): void;
|
|
196
|
+
/**
|
|
197
|
+
* Ensure connection is ready before executing device operations
|
|
198
|
+
*
|
|
199
|
+
* @param timeout - Timeout in milliseconds (default: 10000ms)
|
|
200
|
+
* @throws Error if connection timeout
|
|
201
|
+
*/
|
|
202
|
+
private ensureConnectionReady;
|
|
203
|
+
/**
|
|
204
|
+
* Send chat message through ShellX
|
|
205
|
+
*
|
|
206
|
+
* @param message - The chat message to send
|
|
207
|
+
* @returns Promise that resolves when the message is sent
|
|
208
|
+
*/
|
|
209
|
+
sendChat(message: string): Promise<void>;
|
|
210
|
+
/**
|
|
211
|
+
* Execute a click action
|
|
212
|
+
*
|
|
213
|
+
* @param selector - Element selector (text) or full click configuration
|
|
214
|
+
* @param options - Additional click options (when using string selector)
|
|
215
|
+
* @returns Promise resolving to ClickResult
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```typescript
|
|
219
|
+
* // Simplified - click by text
|
|
220
|
+
* await shellx.click('Submit');
|
|
221
|
+
*
|
|
222
|
+
* // Simplified - click by text with options
|
|
223
|
+
* await shellx.click('Submit', { clickType: 'long' });
|
|
224
|
+
*
|
|
225
|
+
* // Full - click by element ID
|
|
226
|
+
* await shellx.click({ elementId: 'element123' });
|
|
227
|
+
*
|
|
228
|
+
* // Full - click by coordinates
|
|
229
|
+
* await shellx.click({ x: 500, y: 1000 });
|
|
230
|
+
*
|
|
231
|
+
* // Full - click by text
|
|
232
|
+
* await shellx.click({ text: 'Submit' });
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
click(selector: string, options?: Omit<Click, "text" | "elementId" | "resourceId" | "class" | "x" | "y">): Promise<ClickResult>;
|
|
236
|
+
click(clickData: Click): Promise<ClickResult>;
|
|
237
|
+
/**
|
|
238
|
+
* Execute an input action
|
|
239
|
+
*
|
|
240
|
+
* @param inputData - Input configuration
|
|
241
|
+
* @returns Promise resolving to InputResult
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* const result = await shellx.input({
|
|
246
|
+
* elementId: 'field123',
|
|
247
|
+
* text: 'Hello World',
|
|
248
|
+
* clear: true
|
|
249
|
+
* });
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
input(inputData: Input): Promise<InputResult>;
|
|
253
|
+
/**
|
|
254
|
+
* Execute a swipe action
|
|
255
|
+
*
|
|
256
|
+
* @param swipeData - Swipe configuration
|
|
257
|
+
* @returns Promise resolving to SwipeResult
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* const result = await shellx.swipe({
|
|
262
|
+
* fromX: 500,
|
|
263
|
+
* fromY: 1000,
|
|
264
|
+
* toX: 500,
|
|
265
|
+
* toY: 500,
|
|
266
|
+
* duration: 800
|
|
267
|
+
* });
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
swipe(swipeData: Swipe): Promise<SwipeResult>;
|
|
271
|
+
/**
|
|
272
|
+
* Execute a key press action
|
|
273
|
+
*
|
|
274
|
+
* @param key - Key code (without KEYCODE_ prefix) or full key configuration
|
|
275
|
+
* @param options - Additional key options (when using string key)
|
|
276
|
+
* @returns Promise resolving to KeyResult
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```typescript
|
|
280
|
+
* // Simplified - press back key
|
|
281
|
+
* await shellx.press('BACK');
|
|
282
|
+
*
|
|
283
|
+
* // Simplified - press home key
|
|
284
|
+
* await shellx.press('HOME');
|
|
285
|
+
*
|
|
286
|
+
* // Simplified - long press menu key
|
|
287
|
+
* await shellx.press('MENU', { longPress: true });
|
|
288
|
+
*
|
|
289
|
+
* // Full - press with all options
|
|
290
|
+
* await shellx.press({ key: 'BACK', longPress: true });
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
press(key: string, options?: Omit<Key, "key">): Promise<KeyResult>;
|
|
294
|
+
press(keyData: Key): Promise<KeyResult>;
|
|
295
|
+
/**
|
|
296
|
+
* Wait for an element condition
|
|
297
|
+
*
|
|
298
|
+
* @param selector - Element selector (text) or full wait configuration
|
|
299
|
+
* @param options - Additional wait options (when using string selector)
|
|
300
|
+
* @returns Promise resolving to WaitResult
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```typescript
|
|
304
|
+
* // Simplified - wait for element to appear
|
|
305
|
+
* await shellx.wait('Submit');
|
|
306
|
+
*
|
|
307
|
+
* // Simplified - wait with timeout
|
|
308
|
+
* await shellx.wait('Loading', { timeout: 10000 });
|
|
309
|
+
*
|
|
310
|
+
* // Simplified - wait for element to disappear
|
|
311
|
+
* await shellx.wait('Loading', { condition: 'gone' });
|
|
312
|
+
*
|
|
313
|
+
* // Full - wait with all options
|
|
314
|
+
* await shellx.wait({ text: 'Submit', condition: 'visible', timeout: 10000 });
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
wait(selector: string, options?: Omit<Wait, "text" | "elementId" | "resourceId" | "class">): Promise<WaitResult>;
|
|
318
|
+
wait(waitData: Wait): Promise<WaitResult>;
|
|
319
|
+
/**
|
|
320
|
+
* Find UI elements
|
|
321
|
+
*
|
|
322
|
+
* @param selector - Element selector (text) or full find configuration
|
|
323
|
+
* @param options - Additional find options (when using string selector)
|
|
324
|
+
* @returns Promise resolving to FindResult
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ```typescript
|
|
328
|
+
* // Simplified - find single element
|
|
329
|
+
* const result = await shellx.find('Submit');
|
|
330
|
+
*
|
|
331
|
+
* // Simplified - find multiple elements
|
|
332
|
+
* const all = await shellx.find('Submit', { multiple: true, maxResults: 10 });
|
|
333
|
+
*
|
|
334
|
+
* // Full - find with all options
|
|
335
|
+
* const result = await shellx.find({ text: 'Submit', multiple: true });
|
|
336
|
+
*
|
|
337
|
+
* console.log(`Found ${result.count} elements`);
|
|
338
|
+
* result.elements.forEach(el => console.log(el.text));
|
|
339
|
+
* ```
|
|
340
|
+
*/
|
|
341
|
+
find(selector: string, options?: Omit<Find, "text" | "elementId" | "resourceId" | "class">): Promise<TypesFindResult>;
|
|
342
|
+
find(findData: Find): Promise<TypesFindResult>;
|
|
343
|
+
/**
|
|
344
|
+
* Execute a shell command
|
|
345
|
+
*
|
|
346
|
+
* @param cmd - Command string or full command configuration
|
|
347
|
+
* @param options - Additional command options (when using string command)
|
|
348
|
+
* @returns Promise resolving to CommandResult
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* ```typescript
|
|
352
|
+
* // Simplified - execute command
|
|
353
|
+
* const result = await shellx.command('ls -la');
|
|
354
|
+
*
|
|
355
|
+
* // Simplified - execute with timeout
|
|
356
|
+
* const result = await shellx.command('ls -la', { timeout: 5000 });
|
|
357
|
+
*
|
|
358
|
+
* // Full - execute with all options
|
|
359
|
+
* const result = await shellx.command({ cmd: 'ls -la', timeout: 5000 });
|
|
360
|
+
*
|
|
361
|
+
* console.log(result.output);
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
command(cmd: string, options?: Omit<Command, "cmd">): Promise<TypesCommandResult>;
|
|
365
|
+
command(commandData: Command): Promise<TypesCommandResult>;
|
|
366
|
+
/**
|
|
367
|
+
* Execute a clipboard action
|
|
368
|
+
*
|
|
369
|
+
* @param clipboardData - Clipboard configuration
|
|
370
|
+
* @returns Promise resolving to ClipboardResult
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* ```typescript
|
|
374
|
+
* // Get clipboard content
|
|
375
|
+
* const result = await shellx.clipboard({ get: true });
|
|
376
|
+
* console.log(result.text);
|
|
377
|
+
*
|
|
378
|
+
* // Set clipboard content
|
|
379
|
+
* await shellx.clipboard({ text: 'Hello' });
|
|
380
|
+
*
|
|
381
|
+
* // Paste clipboard content
|
|
382
|
+
* await shellx.clipboard({ paste: true });
|
|
383
|
+
* ```
|
|
384
|
+
*/
|
|
385
|
+
clipboard(clipboardData: Clipboard): Promise<ClipboardResult>;
|
|
386
|
+
/**
|
|
387
|
+
* Get application information
|
|
388
|
+
*
|
|
389
|
+
* @param pkg - Package name or full app info configuration
|
|
390
|
+
* @param options - Additional app info options (when using string package)
|
|
391
|
+
* @returns Promise resolving to AppInfoResult
|
|
392
|
+
*
|
|
393
|
+
* @example
|
|
394
|
+
* ```typescript
|
|
395
|
+
* // Simplified - get app info
|
|
396
|
+
* const result = await shellx.getAppInfo('com.example.app');
|
|
397
|
+
*
|
|
398
|
+
* // Simplified - get with retry
|
|
399
|
+
* const result = await shellx.getAppInfo('com.example.app', { retry: 3 });
|
|
400
|
+
*
|
|
401
|
+
* // Full - get with all options
|
|
402
|
+
* const result = await shellx.getAppInfo({ package: 'com.example.app', retry: 3 });
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
getAppInfo(pkg: string, options?: Omit<AppInfo, "package">): Promise<AppInfoResult>;
|
|
406
|
+
getAppInfo(appInfoData: AppInfo): Promise<AppInfoResult>;
|
|
407
|
+
/**
|
|
408
|
+
* Get list of installed applications
|
|
409
|
+
*
|
|
410
|
+
* @param options - Options for filtering app list
|
|
411
|
+
* @returns Promise resolving to app list response
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```typescript
|
|
415
|
+
* // Get all user apps
|
|
416
|
+
* const result = await shellx.getAppList();
|
|
417
|
+
* console.log(`Found ${result.userAppCount} user apps`);
|
|
418
|
+
* result.apps.forEach(app => {
|
|
419
|
+
* console.log(`${app.appName} (${app.packageName})`);
|
|
420
|
+
* });
|
|
421
|
+
*
|
|
422
|
+
* // Get user and system apps
|
|
423
|
+
* const allApps = await shellx.getAppList({
|
|
424
|
+
* includeSystemApps: true,
|
|
425
|
+
* includeDisabledApps: false
|
|
426
|
+
* });
|
|
427
|
+
* ```
|
|
428
|
+
*/
|
|
429
|
+
getAppList(options?: {
|
|
430
|
+
includeSystemApps?: boolean;
|
|
431
|
+
includeDisabledApps?: boolean;
|
|
432
|
+
}): Promise<{
|
|
433
|
+
apps: Array<{
|
|
434
|
+
packageName: string;
|
|
435
|
+
appName: string;
|
|
436
|
+
versionName: string;
|
|
437
|
+
versionCode: number;
|
|
438
|
+
isSystemApp: boolean;
|
|
439
|
+
isEnabled: boolean;
|
|
440
|
+
firstInstallTime: number;
|
|
441
|
+
lastUpdateTime: number;
|
|
442
|
+
sourceDir: string;
|
|
443
|
+
}>;
|
|
444
|
+
totalCount: number;
|
|
445
|
+
systemAppCount: number;
|
|
446
|
+
userAppCount: number;
|
|
447
|
+
timestamp: number;
|
|
448
|
+
success?: boolean;
|
|
449
|
+
error?: string;
|
|
450
|
+
}>;
|
|
451
|
+
/**
|
|
452
|
+
* Take a screenshot
|
|
453
|
+
*
|
|
454
|
+
* @param screenshotData - Screenshot configuration
|
|
455
|
+
* @returns Promise resolving to ScreenshotResult
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
* ```typescript
|
|
459
|
+
* const result = await shellx.takeScreenshot({
|
|
460
|
+
* format: 'png',
|
|
461
|
+
* quality: 100,
|
|
462
|
+
* saveToFile: true
|
|
463
|
+
* });
|
|
464
|
+
*
|
|
465
|
+
* console.log(result.imagePath);
|
|
466
|
+
* ```
|
|
467
|
+
*/
|
|
468
|
+
takeScreenshot(screenshotData?: Screenshot): Promise<ScreenshotResult>;
|
|
469
|
+
/**
|
|
470
|
+
* Get screen information
|
|
471
|
+
*
|
|
472
|
+
* @returns Promise resolving to ScreenInfoResult
|
|
473
|
+
*
|
|
474
|
+
* @example
|
|
475
|
+
* ```typescript
|
|
476
|
+
* const screenInfo = await shellx.getScreenInfo();
|
|
477
|
+
* console.log(`Screen: ${screenInfo.width}x${screenInfo.height}`);
|
|
478
|
+
* console.log(`Current app: ${screenInfo.foregroundApp}`);
|
|
479
|
+
* ```
|
|
480
|
+
*/
|
|
481
|
+
getScreenInfo(): Promise<ScreenInfoResult>;
|
|
482
|
+
/**
|
|
483
|
+
* Execute multiple actions in sequence
|
|
484
|
+
*
|
|
485
|
+
* @param actions - Array of actions to execute
|
|
486
|
+
* @returns Promise resolving to ExecuteActionsResult
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```typescript
|
|
490
|
+
* const result = await shellx.executeActions([
|
|
491
|
+
* { text: 'Settings' },
|
|
492
|
+
* { text: 'Accounts' },
|
|
493
|
+
* { cmd: 'ls -la' }
|
|
494
|
+
* ]);
|
|
495
|
+
*
|
|
496
|
+
* console.log(`Success: ${result.successCount}, Failed: ${result.failureCount}`);
|
|
497
|
+
* result.results.forEach((res, index) => {
|
|
498
|
+
* console.log(`Action ${index + 1}: ${res.success ? 'Success' : 'Failed'}`);
|
|
499
|
+
* });
|
|
500
|
+
* ```
|
|
501
|
+
*/
|
|
502
|
+
executeActions(actions: Array<Click | Input | Swipe | Key | Wait | Find | Command | AppInfo | Screenshot | Clipboard>): Promise<ExecuteActionsResult>;
|
|
503
|
+
/**
|
|
504
|
+
* Find a single element with retry logic
|
|
505
|
+
*
|
|
506
|
+
* @param selector - Element selector
|
|
507
|
+
* @param maxRetries - Maximum retry attempts (default: 3)
|
|
508
|
+
* @param retryDelay - Delay between retries in milliseconds (default: 1000)
|
|
509
|
+
* @returns Promise resolving to UIElement or null
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```typescript
|
|
513
|
+
* const element = await shellx.findElement(
|
|
514
|
+
* { text: 'Submit', visible: true },
|
|
515
|
+
* 3,
|
|
516
|
+
* 1000
|
|
517
|
+
* );
|
|
518
|
+
* ```
|
|
107
519
|
*/
|
|
108
520
|
findElementWithRetry(selector: ElementSelector, maxRetries?: number, retryDelay?: number): Promise<UIElement | null>;
|
|
109
521
|
/**
|
|
110
|
-
*
|
|
522
|
+
* Find multiple elements with retry logic
|
|
523
|
+
*
|
|
524
|
+
* @param selector - Element selector
|
|
525
|
+
* @param maxRetries - Maximum retry attempts (default: 3)
|
|
526
|
+
* @param retryDelay - Delay between retries in milliseconds (default: 1000)
|
|
527
|
+
* @param options - Additional find options
|
|
528
|
+
* @returns Promise resolving to array of UIElements
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```typescript
|
|
532
|
+
* const elements = await shellx.findElementsWithRetry(
|
|
533
|
+
* { className: 'Button', visible: true },
|
|
534
|
+
* 3,
|
|
535
|
+
* 1000,
|
|
536
|
+
* { maxResults: 10 }
|
|
537
|
+
* );
|
|
538
|
+
* ```
|
|
111
539
|
*/
|
|
112
540
|
findElementsWithRetry(selector: ElementSelector, maxRetries?: number, retryDelay?: number, options?: {
|
|
113
541
|
maxResults?: number;
|
|
114
542
|
visibleOnly?: boolean;
|
|
115
543
|
clickableOnly?: boolean;
|
|
116
544
|
}): Promise<UIElement[]>;
|
|
117
|
-
/**
|
|
118
|
-
* 打印元素信息的工具方法
|
|
119
|
-
*/
|
|
120
|
-
printElementInfo(element: UIElement, index?: number): void;
|
|
121
|
-
/**
|
|
122
|
-
* 打印多个元素信息的工具方法
|
|
123
|
-
*/
|
|
124
|
-
printElementsInfo(elements: UIElement[], title?: string): void;
|
|
125
|
-
/**
|
|
126
|
-
* Click element by text content
|
|
127
|
-
*/
|
|
128
|
-
clickByText(text: string, exact?: boolean): Promise<boolean>;
|
|
129
|
-
/**
|
|
130
|
-
* Input text into field
|
|
131
|
-
*/
|
|
132
|
-
inputText(selector: ElementSelector, text: string, options?: {
|
|
133
|
-
clear?: boolean;
|
|
134
|
-
hideKeyboard?: boolean;
|
|
135
|
-
}): Promise<boolean>;
|
|
136
|
-
/**
|
|
137
|
-
* Take screenshot and save info
|
|
138
|
-
*/
|
|
139
|
-
captureScreen(options?: ScreenShotOptions & {
|
|
140
|
-
saveInfo?: boolean;
|
|
141
|
-
}): Promise<import("./protocol").ScreenShotResponse>;
|
|
142
545
|
/**
|
|
143
546
|
* Wait for any of multiple elements to appear
|
|
547
|
+
* @deprecated Use waitAnyElement() instead for consistency
|
|
144
548
|
*/
|
|
145
549
|
waitForAnyElement(selectors: ElementSelector[], timeout?: number): Promise<{
|
|
146
550
|
element: UIElement;
|
|
147
551
|
selectorIndex: number;
|
|
148
552
|
} | null>;
|
|
149
553
|
/**
|
|
150
|
-
*
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
*
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
*
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
*
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
executeShellCommands(commands: Array<{
|
|
173
|
-
command: string;
|
|
174
|
-
title?: string;
|
|
175
|
-
waitAfterMs?: number;
|
|
176
|
-
}>, options?: {
|
|
177
|
-
continueOnError?: boolean;
|
|
178
|
-
timeout?: number;
|
|
179
|
-
}): Promise<ShellCommandResult[]>;
|
|
180
|
-
/**
|
|
181
|
-
* Common ADB commands helper
|
|
182
|
-
*/
|
|
183
|
-
adbCommand(command: string, options?: ShellCommandOptions): Promise<ShellCommandResult>;
|
|
184
|
-
/**
|
|
185
|
-
* Device info commands
|
|
186
|
-
*/
|
|
187
|
-
getDeviceInfo(): Promise<ShellCommandResult[]>;
|
|
554
|
+
* Wait for any of multiple elements to appear
|
|
555
|
+
*
|
|
556
|
+
* @param selectors - Array of element selectors
|
|
557
|
+
* @param timeout - Maximum wait time in milliseconds (default: 10000)
|
|
558
|
+
* @returns Promise resolving to the first found element and its index, or null
|
|
559
|
+
*
|
|
560
|
+
* @example
|
|
561
|
+
* ```typescript
|
|
562
|
+
* const result = await shellx.waitAnyElement(
|
|
563
|
+
* [
|
|
564
|
+
* { text: 'Submit' },
|
|
565
|
+
* { text: 'OK' },
|
|
566
|
+
* { text: 'Confirm' }
|
|
567
|
+
* ],
|
|
568
|
+
* 10000
|
|
569
|
+
* );
|
|
570
|
+
* ```
|
|
571
|
+
*/
|
|
572
|
+
waitAnyElement(selectors: ElementSelector[], timeout?: number): Promise<{
|
|
573
|
+
element: UIElement;
|
|
574
|
+
selectorIndex: number;
|
|
575
|
+
} | null>;
|
|
188
576
|
/**
|
|
189
|
-
*
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
577
|
+
* Scroll to find an element
|
|
578
|
+
*
|
|
579
|
+
* @param selector - Element selector
|
|
580
|
+
* @param maxScrolls - Maximum scroll attempts (default: 5)
|
|
581
|
+
* @param direction - Scroll direction (default: 'down')
|
|
582
|
+
* @returns Promise resolving to UIElement or null
|
|
583
|
+
*
|
|
584
|
+
* @example
|
|
585
|
+
* ```typescript
|
|
586
|
+
* const element = await shellx.scrollToFindElement(
|
|
587
|
+
* { text: 'Target' },
|
|
588
|
+
* 5,
|
|
589
|
+
* 'down'
|
|
590
|
+
* );
|
|
591
|
+
* ```
|
|
592
|
+
*/
|
|
593
|
+
scrollToFindElement(selector: ElementSelector, maxScrolls?: number, direction?: "up" | "down"): Promise<UIElement | null>;
|
|
594
|
+
/**
|
|
595
|
+
* Handle shell output from WebSocket messages
|
|
596
|
+
*
|
|
597
|
+
* This method should be called in the WebSocket message handler.
|
|
598
|
+
*
|
|
599
|
+
* @param chunks - Shell output chunks
|
|
600
|
+
*
|
|
601
|
+
* @example
|
|
602
|
+
* ```typescript
|
|
603
|
+
* const client = new ConnectionClient(deviceId, {
|
|
604
|
+
* onMessage: (message) => {
|
|
605
|
+
* if (message.chunks) {
|
|
606
|
+
* shellx.handleShellOutput(message.chunks);
|
|
607
|
+
* }
|
|
608
|
+
* }
|
|
609
|
+
* });
|
|
610
|
+
* ```
|
|
611
|
+
*/
|
|
612
|
+
handleShellOutput(chunks: [number, number, Uint8Array[]]): void;
|
|
613
|
+
/**
|
|
614
|
+
* Send raw WebSocket message (for advanced use cases)
|
|
615
|
+
*
|
|
616
|
+
* This method allows you to send raw WebSocket protocol messages directly,
|
|
617
|
+
* bypassing the high-level ShellX API. This is useful for:
|
|
618
|
+
* - Custom protocol operations not exposed by ShellX
|
|
619
|
+
* - Testing and debugging
|
|
620
|
+
* - Advanced integrations requiring low-level control
|
|
621
|
+
*
|
|
622
|
+
* @param message - Raw WebSocket client message (WsClient type)
|
|
623
|
+
* @returns Promise resolving to the server response
|
|
624
|
+
*
|
|
625
|
+
* @example
|
|
626
|
+
* ```typescript
|
|
627
|
+
* // Send a custom find element request
|
|
628
|
+
* await shellx.sendRawMessage({
|
|
629
|
+
* findElement: {
|
|
630
|
+
* type: 'find',
|
|
631
|
+
* selector: { text: 'Submit' },
|
|
632
|
+
* options: { maxResults: 10 }
|
|
633
|
+
* }
|
|
634
|
+
* });
|
|
635
|
+
*
|
|
636
|
+
* // Send a custom action sequence
|
|
637
|
+
* await shellx.sendRawMessage({
|
|
638
|
+
* actions: [
|
|
639
|
+
* { action: 'Launch', app: 'com.example.app' },
|
|
640
|
+
* { action: 'Tap', element: [500, 1000] }
|
|
641
|
+
* ]
|
|
642
|
+
* });
|
|
643
|
+
*
|
|
644
|
+
* // Send screen info request
|
|
645
|
+
* await shellx.sendRawMessage({
|
|
646
|
+
* screenInfo: { keepScreenOn: true, wakeApp: true }
|
|
647
|
+
* });
|
|
648
|
+
* ```
|
|
649
|
+
*/
|
|
650
|
+
sendRawMessage(message: WsClient): Promise<unknown>;
|
|
651
|
+
/**
|
|
652
|
+
* Start ASR (Automatic Speech Recognition)
|
|
653
|
+
* @returns Promise that resolves when speech recognition has started
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* ```typescript
|
|
657
|
+
* await shellx.startSpeechRecognition();
|
|
658
|
+
* console.log('Speech recognition started');
|
|
659
|
+
* ```
|
|
660
|
+
*/
|
|
661
|
+
startSpeechRecognition(): Promise<void>;
|
|
662
|
+
/**
|
|
663
|
+
* Stop ASR (Automatic Speech Recognition)
|
|
664
|
+
* @returns Promise that resolves when speech recognition has stopped
|
|
665
|
+
*
|
|
666
|
+
* @example
|
|
667
|
+
* ```typescript
|
|
668
|
+
* await shellx.stopSpeechRecognition();
|
|
669
|
+
* console.log('Speech recognition stopped');
|
|
670
|
+
* ```
|
|
671
|
+
*/
|
|
672
|
+
stopSpeechRecognition(): Promise<void>;
|
|
673
|
+
/**
|
|
674
|
+
* Speak text aloud using TTS (Text-to-Speech)
|
|
675
|
+
* @param text - The text to speak
|
|
676
|
+
* @returns Promise that resolves when TTS has started speaking
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* ```typescript
|
|
680
|
+
* await shellx.speak('Hello, world!');
|
|
681
|
+
* ```
|
|
682
|
+
*/
|
|
683
|
+
speak(text: string): Promise<void>;
|
|
684
|
+
/**
|
|
685
|
+
* Stop TTS (Text-to-Speech)
|
|
686
|
+
* @returns Promise that resolves when TTS has stopped speaking
|
|
687
|
+
*
|
|
688
|
+
* @example
|
|
689
|
+
* ```typescript
|
|
690
|
+
* await shellx.stopSpeaking();
|
|
691
|
+
* ```
|
|
692
|
+
*/
|
|
693
|
+
stopSpeaking(): Promise<void>;
|
|
694
|
+
/**
|
|
695
|
+
* Static factory method to create shell output handler
|
|
696
|
+
* @deprecated This method is kept for backward compatibility but is no longer needed
|
|
697
|
+
* @param shellx - The ShellX instance
|
|
698
|
+
* @returns Message handler function
|
|
699
|
+
*
|
|
700
|
+
* @example
|
|
701
|
+
* ```typescript
|
|
702
|
+
* const shellx = new ShellX({ deviceId: 'device-id' });
|
|
703
|
+
* const handler = ShellX.createShellOutputHandler(shellx);
|
|
704
|
+
* ```
|
|
705
|
+
*/
|
|
706
|
+
static createShellOutputHandler(shellx: ShellX): (message: WsServer) => void;
|
|
195
707
|
}
|
|
196
|
-
/**
|
|
197
|
-
* Create ShellX instance
|
|
198
|
-
*/
|
|
199
|
-
export declare function createShellX(client: ConnectionTaskClient): ShellX;
|
|
200
|
-
/**
|
|
201
|
-
* Create ShellX instance with automatic authentication and shell output monitoring
|
|
202
|
-
* 自动处理ShellX.ai认证和连接,无需外部提供连接地址
|
|
203
|
-
*/
|
|
204
|
-
export declare function createShellXWithShellMonitoring(config?: any): Promise<ShellX>;
|