shellx-ai 1.0.1 → 1.0.3
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 +98 -10
- package/dist/index.d.ts +66 -4
- package/dist/index.js +332 -47
- package/dist/protocol.d.ts +1 -1
- package/dist/shellx.d.ts +9 -5
- package/dist/shellx.js +142 -196
- package/package.json +4 -12
package/README.md
CHANGED
|
@@ -3,18 +3,19 @@
|
|
|
3
3
|
[](https://badge.fury.io/js/shellx)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
**ShellX** is a powerful automation framework for Android device control and UI automation. It provides seamless shell command execution, element finding, screen capture, and automated task execution through an intelligent
|
|
6
|
+
**ShellX** is a powerful automation framework for Android device control and UI automation. It provides seamless shell command execution, element finding, screen capture, and automated task execution through an intelligent ShellX.ai service architecture.
|
|
7
7
|
|
|
8
8
|
## ✨ Features
|
|
9
9
|
|
|
10
|
-
- 🔐 **Zero-Configuration Setup** - Automatic authentication and connection
|
|
10
|
+
- 🔐 **Zero-Configuration Setup** - Automatic ShellX.ai authentication and service connection
|
|
11
11
|
- 📱 **Android Device Control** - Execute shell commands with real-time output monitoring
|
|
12
12
|
- 🎯 **Smart UI Automation** - Advanced element finding with retry logic and multiple strategies
|
|
13
13
|
- 📸 **Screen Operations** - Screenshots, screen info, and visual change detection
|
|
14
|
-
- 🔄 **Intelligent Fallback** - Automatic switching between cloud and local services
|
|
14
|
+
- 🔄 **Intelligent Fallback** - Automatic switching between ShellX.ai cloud and local services
|
|
15
15
|
- 🛡️ **Robust Error Handling** - Comprehensive error recovery and diagnostics
|
|
16
16
|
- 🧠 **Shell Output Monitoring** - Real-time command output processing and analysis
|
|
17
17
|
- 📊 **Rich Diagnostics** - Built-in element analysis and debugging tools
|
|
18
|
+
- 🔗 **Smart Connection Management** - ShellX.ai service connection status with message-based verification
|
|
18
19
|
|
|
19
20
|
## 🚀 Quick Start
|
|
20
21
|
|
|
@@ -26,11 +27,15 @@ npm install shellx-ai
|
|
|
26
27
|
|
|
27
28
|
### Node.js Version Compatibility
|
|
28
29
|
|
|
29
|
-
ShellX supports Node.js 14+ with automatic
|
|
30
|
+
ShellX supports Node.js 14+ with automatic polyfills:
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
- **Node.js
|
|
33
|
-
- **Browser**:
|
|
32
|
+
**HTTP Requests:**
|
|
33
|
+
- **Fallback**: Node.js 18+ built-in `fetch` or `node-fetch` for older versions
|
|
34
|
+
- **Browser**: Compatible with all fetch implementations
|
|
35
|
+
|
|
36
|
+
**ShellX.ai Service Connection:**
|
|
37
|
+
- **Browser**: Uses native `WebSocket` API for service communication
|
|
38
|
+
- **Node.js**: Automatically uses `ws` module for service communication
|
|
34
39
|
|
|
35
40
|
No additional configuration needed - ShellX handles environment detection automatically!
|
|
36
41
|
|
|
@@ -42,7 +47,7 @@ import { createShellXWithShellMonitoring } from 'shellx';
|
|
|
42
47
|
// Set your authentication key
|
|
43
48
|
process.env.SHELLX_AUTH_KEY = 'your-auth-key';
|
|
44
49
|
|
|
45
|
-
// Initialize ShellX with automatic authentication
|
|
50
|
+
// Initialize ShellX with automatic ShellX.ai authentication
|
|
46
51
|
const { client, shellx } = await createShellXWithShellMonitoring();
|
|
47
52
|
|
|
48
53
|
// Start automating!
|
|
@@ -71,6 +76,7 @@ set SHELLX_AUTH_KEY=your-auth-key
|
|
|
71
76
|
const result = await shellx.executeShellCommand('pm list packages', {
|
|
72
77
|
title: 'List installed packages',
|
|
73
78
|
timeout: 10000,
|
|
79
|
+
allowPartialResult: true, // Return partial results on timeout instead of throwing error
|
|
74
80
|
onOutput: (output) => {
|
|
75
81
|
console.log('Real-time output:', output);
|
|
76
82
|
}
|
|
@@ -196,13 +202,19 @@ const result = await shellx.adbCommand('shell dumpsys battery', {
|
|
|
196
202
|
});
|
|
197
203
|
```
|
|
198
204
|
|
|
205
|
+
|
|
206
|
+
|
|
199
207
|
## 🎯 ShellX Class API
|
|
200
208
|
|
|
201
209
|
### Core Methods
|
|
202
210
|
|
|
203
211
|
| Method | Description | Example |
|
|
204
212
|
|--------|-------------|---------|
|
|
205
|
-
| `executeShellCommand(cmd, opts?)` | Execute shell command with monitoring | `shellx.executeShellCommand('ls -la')` |
|
|
213
|
+
| `executeShellCommand(cmd, opts?)` | Execute shell command with monitoring | `shellx.executeShellCommand('ls -la', {allowPartialResult: true})` |
|
|
214
|
+
| `completeTask(taskId, result?, success?)` | Manually complete a specific task | `client.completeTask('task-123', {output: 'result'})` |
|
|
215
|
+
| `getPendingTaskIds()` | Get all pending task IDs | `client.getPendingTaskIds()` |
|
|
216
|
+
| `getTaskInfo(taskId)` | Get task information | `client.getTaskInfo('task-123')` |
|
|
217
|
+
| `completeTasksByType(type, result?, success?)` | Complete all tasks of a specific type | `client.completeTasksByType('action')` |
|
|
206
218
|
| `clickByText(text, exact?)` | Click element by text content | `shellx.clickByText('OK', true)` |
|
|
207
219
|
| `inputText(selector, text, opts?)` | Input text into element | `shellx.inputText({resourceId: 'field'}, 'text')` |
|
|
208
220
|
| `findElementWithRetry(selector, retries?, delay?)` | Find single element with retry | `shellx.findElementWithRetry({text: 'Button'})` |
|
|
@@ -252,6 +264,79 @@ const { client, shellx } = await createShellXWithShellMonitoring({
|
|
|
252
264
|
|
|
253
265
|
## 🔧 Advanced Features
|
|
254
266
|
|
|
267
|
+
### Shell Command Options
|
|
268
|
+
|
|
269
|
+
ShellX provides flexible options for shell command execution:
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
const result = await shellx.executeShellCommand('long-running-command', {
|
|
273
|
+
title: 'Custom command title',
|
|
274
|
+
timeout: 30000, // Command timeout in milliseconds
|
|
275
|
+
allowPartialResult: true, // Return partial results on timeout instead of throwing error
|
|
276
|
+
waitAfterMs: 1000, // Wait time after command completion
|
|
277
|
+
onOutput: (output) => { // Real-time output callback
|
|
278
|
+
console.log('Live output:', output);
|
|
279
|
+
},
|
|
280
|
+
onError: (error) => { // Error callback
|
|
281
|
+
console.error('Command error:', error);
|
|
282
|
+
},
|
|
283
|
+
successPattern: /success|completed/, // Pattern to detect success
|
|
284
|
+
errorPattern: /error|failed/ // Pattern to detect failure
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
#### allowPartialResult Parameter
|
|
289
|
+
|
|
290
|
+
The `allowPartialResult` parameter controls timeout behavior:
|
|
291
|
+
|
|
292
|
+
- **`true`**: When command times out but has partial output, returns the partial result instead of throwing an error
|
|
293
|
+
- **`false`**: When command times out, always throws an error (default behavior)
|
|
294
|
+
- **`undefined`**: Uses default behavior (returns partial results if available)
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
// Example: Allow partial results for long-running commands
|
|
298
|
+
const result = await shellx.executeShellCommand('find / -name "*.log"', {
|
|
299
|
+
timeout: 5000,
|
|
300
|
+
allowPartialResult: true
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
if (!result.success && result.error?.includes('timeout')) {
|
|
304
|
+
console.log('Command timed out, but got partial results:', result.output);
|
|
305
|
+
} else {
|
|
306
|
+
console.log('Command completed successfully:', result.output);
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Task Management
|
|
311
|
+
|
|
312
|
+
ShellX provides advanced task management capabilities for manual control:
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
// Send message and get taskId for manual control
|
|
316
|
+
const { taskId, promise } = await client.sendMessageWithTaskId(
|
|
317
|
+
{ actions: { type: 'command', command: 'long-running-command' } },
|
|
318
|
+
'action',
|
|
319
|
+
'command'
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
console.log('Task ID:', taskId);
|
|
323
|
+
|
|
324
|
+
// Manually complete the task when ready
|
|
325
|
+
client.completeTask(taskId, { output: 'Command completed' }, true);
|
|
326
|
+
|
|
327
|
+
// Get all pending task IDs
|
|
328
|
+
const pendingTasks = client.getPendingTaskIds();
|
|
329
|
+
console.log('Pending tasks:', pendingTasks);
|
|
330
|
+
|
|
331
|
+
// Get task information
|
|
332
|
+
const taskInfo = client.getTaskInfo(taskId);
|
|
333
|
+
console.log('Task info:', taskInfo);
|
|
334
|
+
|
|
335
|
+
// Complete all tasks of a specific type
|
|
336
|
+
const completedCount = client.completeTasksByType('action', { success: true });
|
|
337
|
+
console.log(`Completed ${completedCount} action tasks`);
|
|
338
|
+
```
|
|
339
|
+
|
|
255
340
|
### Shell Output Monitoring
|
|
256
341
|
|
|
257
342
|
ShellX automatically monitors shell command output in real-time:
|
|
@@ -263,10 +348,13 @@ const result = await shellx.executeShellCommand('top -n 1', {
|
|
|
263
348
|
},
|
|
264
349
|
successPattern: /Tasks:/,
|
|
265
350
|
errorPattern: /error|failed/i,
|
|
266
|
-
timeout: 10000
|
|
351
|
+
timeout: 10000,
|
|
352
|
+
allowPartialResult: true // Return partial results on timeout
|
|
267
353
|
});
|
|
268
354
|
```
|
|
269
355
|
|
|
356
|
+
|
|
357
|
+
|
|
270
358
|
### Element Diagnostics
|
|
271
359
|
|
|
272
360
|
Built-in diagnostic tools for troubleshooting:
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface PendingTask {
|
|
|
13
13
|
reject: (err: Error) => void;
|
|
14
14
|
timer: NodeJS.Timeout;
|
|
15
15
|
type: string;
|
|
16
|
+
commandType?: string;
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
18
19
|
* Enhanced WebSocket Task Client with protocol-aware task methods
|
|
@@ -20,14 +21,30 @@ export interface PendingTask {
|
|
|
20
21
|
export declare class WebSocketTaskClient {
|
|
21
22
|
private wsUrl;
|
|
22
23
|
private config;
|
|
23
|
-
ws:
|
|
24
|
-
private
|
|
24
|
+
ws: any;
|
|
25
|
+
private shellxConnected;
|
|
26
|
+
private wsConnected;
|
|
27
|
+
private authenticated;
|
|
25
28
|
private pendingTasks;
|
|
26
29
|
private messageQueue;
|
|
27
30
|
private reconnectAttempts;
|
|
28
31
|
private pingIntervalId;
|
|
32
|
+
private initializationPromise;
|
|
33
|
+
private shellx;
|
|
29
34
|
constructor(wsUrl: string, config?: Partial<TaskClientConfig>);
|
|
30
35
|
private init;
|
|
36
|
+
/**
|
|
37
|
+
* 等待WebSocket初始化完成
|
|
38
|
+
*/
|
|
39
|
+
waitForInitialization(): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* 发送认证消息
|
|
42
|
+
*/
|
|
43
|
+
private sendAuthenticationMessage;
|
|
44
|
+
/**
|
|
45
|
+
* 从WebSocket URL中提取认证密钥
|
|
46
|
+
*/
|
|
47
|
+
private extractAuthKeyFromUrl;
|
|
31
48
|
private handleMessage;
|
|
32
49
|
private processServerMessage;
|
|
33
50
|
private handleJsonDataResponse;
|
|
@@ -62,7 +79,7 @@ export declare class WebSocketTaskClient {
|
|
|
62
79
|
/**
|
|
63
80
|
* Execute an action sequence
|
|
64
81
|
*/
|
|
65
|
-
executeAction(actionSequence: ActionSequence): Promise<any>;
|
|
82
|
+
executeAction(actionSequence: ActionSequence, taskId?: string): Promise<any>;
|
|
66
83
|
/**
|
|
67
84
|
* Execute promptflow actions
|
|
68
85
|
*/
|
|
@@ -83,7 +100,7 @@ export declare class WebSocketTaskClient {
|
|
|
83
100
|
/**
|
|
84
101
|
* Send authentication data
|
|
85
102
|
*/
|
|
86
|
-
authenticate(authData:
|
|
103
|
+
authenticate(authData: string): Promise<void>;
|
|
87
104
|
/**
|
|
88
105
|
* Set user name
|
|
89
106
|
*/
|
|
@@ -96,14 +113,59 @@ export declare class WebSocketTaskClient {
|
|
|
96
113
|
* Send raw message (for custom integrations)
|
|
97
114
|
*/
|
|
98
115
|
sendRawMessage(message: WsClient): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* 发送消息并返回 taskId,允许手动控制任务完成
|
|
118
|
+
* @param message 要发送的消息
|
|
119
|
+
* @param taskType 任务类型
|
|
120
|
+
* @returns Promise<{taskId: string, promise: Promise<any>}>
|
|
121
|
+
*/
|
|
122
|
+
sendMessageWithTaskId(message: WsClient, taskType?: string, definedTaskId?: string): Promise<{
|
|
123
|
+
taskId: string;
|
|
124
|
+
promise: Promise<any>;
|
|
125
|
+
}>;
|
|
99
126
|
private startPing;
|
|
100
127
|
private stopPing;
|
|
101
128
|
private reconnect;
|
|
102
129
|
private flushQueue;
|
|
103
130
|
close(): void;
|
|
104
131
|
get isConnected(): boolean;
|
|
132
|
+
get isWebSocketConnected(): boolean;
|
|
133
|
+
get isAuthenticated(): boolean;
|
|
105
134
|
get pendingTaskCount(): number;
|
|
106
135
|
get queuedMessageCount(): number;
|
|
136
|
+
/**
|
|
137
|
+
* 设置关联的 ShellX 实例
|
|
138
|
+
*/
|
|
139
|
+
setShellX(shellx: any): void;
|
|
140
|
+
/**
|
|
141
|
+
* 获取关联的 ShellX 实例
|
|
142
|
+
*/
|
|
143
|
+
getShellX(): any;
|
|
144
|
+
/**
|
|
145
|
+
* 手动完成指定 taskId 的任务
|
|
146
|
+
* @param taskId 任务ID
|
|
147
|
+
* @param result 任务结果
|
|
148
|
+
* @param success 是否成功
|
|
149
|
+
*/
|
|
150
|
+
completeTask(taskId: string, result?: any, success?: boolean): boolean;
|
|
151
|
+
/**
|
|
152
|
+
* 获取所有待处理任务的ID列表
|
|
153
|
+
*/
|
|
154
|
+
getPendingTaskIds(): string[];
|
|
155
|
+
/**
|
|
156
|
+
* 获取指定任务的信息
|
|
157
|
+
*/
|
|
158
|
+
getTaskInfo(taskId: string): {
|
|
159
|
+
type: string;
|
|
160
|
+
commandType?: string;
|
|
161
|
+
} | null;
|
|
162
|
+
/**
|
|
163
|
+
* 批量完成指定类型的任务
|
|
164
|
+
* @param taskType 任务类型
|
|
165
|
+
* @param result 任务结果
|
|
166
|
+
* @param success 是否成功
|
|
167
|
+
*/
|
|
168
|
+
completeTasksByType(taskType: string, result?: any, success?: boolean): number;
|
|
107
169
|
}
|
|
108
170
|
export default WebSocketTaskClient;
|
|
109
171
|
export { ShellX, createShellX, createShellXWithShellMonitoring } from './shellx';
|