shellx-ai 1.0.8 → 1.0.10
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/dist/index.d.ts +8 -4
- package/dist/index.js +152 -54
- package/dist/protocol.d.ts +17 -0
- package/dist/shellx.d.ts +61 -17
- package/dist/shellx.js +520 -210
- package/dist/types.d.ts +127 -0
- package/dist/types.js +4 -0
- package/dist/utils.d.ts +0 -5
- package/dist/utils.js +0 -33
- package/package.json +1 -1
- package/README.md +0 -432
- package/dist/constants.d.ts +0 -13
- package/dist/constants.js +0 -14
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export type Point = {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
};
|
|
5
|
+
export type BaseOptions = {
|
|
6
|
+
wait?: number;
|
|
7
|
+
timeout?: number;
|
|
8
|
+
retry?: number;
|
|
9
|
+
waitAfterMs?: number;
|
|
10
|
+
};
|
|
11
|
+
export type Click = BaseOptions & {
|
|
12
|
+
targetElementId?: string;
|
|
13
|
+
targetResourceId?: string;
|
|
14
|
+
targetText?: string;
|
|
15
|
+
targetClass?: string;
|
|
16
|
+
targetX?: number;
|
|
17
|
+
targetY?: number;
|
|
18
|
+
clickType?: 'single' | 'long' | 'double';
|
|
19
|
+
visible?: boolean;
|
|
20
|
+
clickable?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export type Input = BaseOptions & {
|
|
23
|
+
text: string;
|
|
24
|
+
targetElementId?: string;
|
|
25
|
+
targetResourceId?: string;
|
|
26
|
+
targetText?: string;
|
|
27
|
+
targetClass?: string;
|
|
28
|
+
clear?: boolean;
|
|
29
|
+
hideKeyboard?: boolean;
|
|
30
|
+
visible?: boolean;
|
|
31
|
+
clickable?: boolean;
|
|
32
|
+
};
|
|
33
|
+
export type Swipe = BaseOptions & {
|
|
34
|
+
fromX: number;
|
|
35
|
+
fromY: number;
|
|
36
|
+
toX: number;
|
|
37
|
+
toY: number;
|
|
38
|
+
duration?: number;
|
|
39
|
+
};
|
|
40
|
+
export type Key = BaseOptions & {
|
|
41
|
+
key: string;
|
|
42
|
+
longPress?: boolean;
|
|
43
|
+
};
|
|
44
|
+
export type Wait = BaseOptions & {
|
|
45
|
+
targetElementId?: string;
|
|
46
|
+
targetResourceId?: string;
|
|
47
|
+
targetText?: string;
|
|
48
|
+
targetClass?: string;
|
|
49
|
+
condition?: 'visible' | 'clickable' | 'gone';
|
|
50
|
+
visible?: boolean;
|
|
51
|
+
clickable?: boolean;
|
|
52
|
+
};
|
|
53
|
+
export type Find = BaseOptions & {
|
|
54
|
+
targetElementId?: string;
|
|
55
|
+
targetResourceId?: string;
|
|
56
|
+
targetText?: string;
|
|
57
|
+
targetClass?: string;
|
|
58
|
+
multiple?: boolean;
|
|
59
|
+
maxResults?: number;
|
|
60
|
+
visible?: boolean;
|
|
61
|
+
clickable?: boolean;
|
|
62
|
+
pressClick?: boolean;
|
|
63
|
+
};
|
|
64
|
+
export type Command = BaseOptions & {
|
|
65
|
+
cmd: string;
|
|
66
|
+
};
|
|
67
|
+
export type AppInfo = BaseOptions & {
|
|
68
|
+
package: string;
|
|
69
|
+
};
|
|
70
|
+
export type Screenshot = BaseOptions & {
|
|
71
|
+
regionX?: number;
|
|
72
|
+
regionY?: number;
|
|
73
|
+
regionWidth?: number;
|
|
74
|
+
regionHeight?: number;
|
|
75
|
+
format?: 'png' | 'jpeg';
|
|
76
|
+
quality?: number;
|
|
77
|
+
};
|
|
78
|
+
export type ActionResult = {
|
|
79
|
+
success: boolean;
|
|
80
|
+
data?: any;
|
|
81
|
+
error?: string;
|
|
82
|
+
duration: number;
|
|
83
|
+
};
|
|
84
|
+
export type Element = {
|
|
85
|
+
id: string;
|
|
86
|
+
text: string;
|
|
87
|
+
class: string;
|
|
88
|
+
left: number;
|
|
89
|
+
top: number;
|
|
90
|
+
right: number;
|
|
91
|
+
bottom: number;
|
|
92
|
+
visible: boolean;
|
|
93
|
+
clickable: boolean;
|
|
94
|
+
};
|
|
95
|
+
export type FindResult = {
|
|
96
|
+
elements: Element[];
|
|
97
|
+
count: number;
|
|
98
|
+
success: boolean;
|
|
99
|
+
found: boolean;
|
|
100
|
+
};
|
|
101
|
+
export type CommandResult = {
|
|
102
|
+
success: boolean;
|
|
103
|
+
output: string;
|
|
104
|
+
error?: string;
|
|
105
|
+
exitCode?: number;
|
|
106
|
+
duration: number;
|
|
107
|
+
};
|
|
108
|
+
export type Action = ({
|
|
109
|
+
type: 'click';
|
|
110
|
+
} & Click) | ({
|
|
111
|
+
type: 'input';
|
|
112
|
+
} & Input) | ({
|
|
113
|
+
type: 'swipe';
|
|
114
|
+
} & Swipe) | ({
|
|
115
|
+
type: 'key';
|
|
116
|
+
} & Key) | ({
|
|
117
|
+
type: 'wait';
|
|
118
|
+
} & Wait) | ({
|
|
119
|
+
type: 'find';
|
|
120
|
+
} & Find) | ({
|
|
121
|
+
type: 'command';
|
|
122
|
+
} & Command) | ({
|
|
123
|
+
type: 'appInfo';
|
|
124
|
+
} & AppInfo) | ({
|
|
125
|
+
type: 'screenshot';
|
|
126
|
+
} & Screenshot);
|
|
127
|
+
export type Actions = Action[];
|
package/dist/types.js
ADDED
package/dist/utils.d.ts
CHANGED
|
@@ -11,8 +11,3 @@ export declare function setEnvVar(key: string, value: string): void;
|
|
|
11
11
|
* 安全地删除环境变量,兼容浏览器和Node.js环境
|
|
12
12
|
*/
|
|
13
13
|
export declare function deleteEnvVar(key: string): void;
|
|
14
|
-
/**
|
|
15
|
-
* 检查并获取 WebSocket URL 环境变量
|
|
16
|
-
* 如果未设置则显示错误并抛出异常
|
|
17
|
-
*/
|
|
18
|
-
export declare function getWebSocketUrl(): string;
|
package/dist/utils.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.wait = void 0;
|
|
|
4
4
|
exports.getEnvVar = getEnvVar;
|
|
5
5
|
exports.setEnvVar = setEnvVar;
|
|
6
6
|
exports.deleteEnvVar = deleteEnvVar;
|
|
7
|
-
exports.getWebSocketUrl = getWebSocketUrl;
|
|
8
7
|
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
9
8
|
exports.wait = wait;
|
|
10
9
|
/**
|
|
@@ -47,35 +46,3 @@ function deleteEnvVar(key) {
|
|
|
47
46
|
console.log("已删除环境变量:", key);
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
|
-
/**
|
|
51
|
-
* 检查并获取 WebSocket URL 环境变量
|
|
52
|
-
* 如果未设置则显示错误并抛出异常
|
|
53
|
-
*/
|
|
54
|
-
function getWebSocketUrl() {
|
|
55
|
-
// 安全地获取环境变量,兼容浏览器和Node.js环境
|
|
56
|
-
const wsUrl = getEnvVar('WEBSOCKET_URL');
|
|
57
|
-
if (!wsUrl || wsUrl.trim() === '') {
|
|
58
|
-
const errorMessage = '❌ 错误: 未设置 WEBSOCKET_URL 环境变量!\n\n📋 解决方案:\n1. 在项目根目录创建 .env 文件\n2. 在 .env 文件中添加以下内容:\n WEBSOCKET_URL=ws://127.0.0.1:9091/api/s/your-session-id\n\n💡 提示:\n- 请将 your-session-id 替换为实际的会话ID\n- 确保 ShellX 服务器正在运行\n- 检查端口号是否正确(默认9091)';
|
|
59
|
-
console.error(errorMessage);
|
|
60
|
-
// 在Node.js环境中退出,在浏览器环境中抛出异常
|
|
61
|
-
if (typeof process !== 'undefined' && process.exit) {
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
throw new Error(errorMessage);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
// 简单的 URL 格式验证
|
|
69
|
-
if (!wsUrl.startsWith('ws://') && !wsUrl.startsWith('wss://')) {
|
|
70
|
-
const errorMessage = `❌ 错误: WEBSOCKET_URL 格式不正确!\n当前值: ${wsUrl}\n应该以 ws:// 或 wss:// 开头\n例如: ws://127.0.0.1:9091/api/s/your-session-id`;
|
|
71
|
-
console.error(errorMessage);
|
|
72
|
-
// 在Node.js环境中退出,在浏览器环境中抛出异常
|
|
73
|
-
if (typeof process !== 'undefined' && process.exit) {
|
|
74
|
-
process.exit(1);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
throw new Error(errorMessage);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return wsUrl;
|
|
81
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shellx-ai",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "shellx is a powerful WebSocket-based client for controlling shell commands and UI automation on remote devices.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "git+https://github.com/10cl/shellx.git",
|
package/README.md
DELETED
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
# ShellX
|
|
2
|
-
|
|
3
|
-
[](https://badge.fury.io/js/shellx)
|
|
4
|
-
[](https://opensource.org/licenses/MIT)
|
|
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 ShellX.ai service architecture.
|
|
7
|
-
|
|
8
|
-
## ✨ Features
|
|
9
|
-
|
|
10
|
-
- 🔐 **Zero-Configuration Setup** - Automatic ShellX.ai authentication and service connection
|
|
11
|
-
- 📱 **Android Device Control** - Execute shell commands with real-time output monitoring
|
|
12
|
-
- 🎯 **Smart UI Automation** - Advanced element finding with retry logic and multiple strategies
|
|
13
|
-
- 📸 **Screen Operations** - Screenshots, screen info, and visual change detection
|
|
14
|
-
- 🔄 **Intelligent Fallback** - Automatic switching between ShellX.ai cloud and local services
|
|
15
|
-
- 🛡️ **Robust Error Handling** - Comprehensive error recovery and diagnostics
|
|
16
|
-
- 🧠 **Shell Output Monitoring** - Real-time command output processing and analysis
|
|
17
|
-
- 📊 **Rich Diagnostics** - Built-in element analysis and debugging tools
|
|
18
|
-
- 🔗 **Smart Connection Management** - ShellX.ai service connection status with message-based verification
|
|
19
|
-
|
|
20
|
-
## 🚀 Quick Start
|
|
21
|
-
|
|
22
|
-
### Installation
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
npm install shellx-ai
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### Node.js Version Compatibility
|
|
29
|
-
|
|
30
|
-
ShellX supports Node.js 14+ with automatic polyfills:
|
|
31
|
-
|
|
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
|
|
39
|
-
|
|
40
|
-
No additional configuration needed - ShellX handles environment detection automatically!
|
|
41
|
-
|
|
42
|
-
### Basic Setup
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
import { createShellXWithShellMonitoring } from 'shellx';
|
|
46
|
-
|
|
47
|
-
// Set your authentication key
|
|
48
|
-
process.env.SHELLX_AUTH_KEY = 'your-auth-key';
|
|
49
|
-
|
|
50
|
-
// Initialize ShellX with automatic ShellX.ai authentication
|
|
51
|
-
const { client, shellx } = await createShellXWithShellMonitoring();
|
|
52
|
-
|
|
53
|
-
// Start automating!
|
|
54
|
-
await shellx.executeShellCommand('getprop ro.build.version.release');
|
|
55
|
-
await shellx.clickByText('Settings');
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### Environment Setup
|
|
59
|
-
|
|
60
|
-
Set your authentication key as an environment variable:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
# Linux/macOS
|
|
64
|
-
export SHELLX_AUTH_KEY="your-auth-key"
|
|
65
|
-
|
|
66
|
-
# Windows
|
|
67
|
-
set SHELLX_AUTH_KEY=your-auth-key
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## 📱 Common Use Cases
|
|
71
|
-
|
|
72
|
-
### 1. Shell Command Execution
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
// Execute shell commands with real-time output
|
|
76
|
-
const result = await shellx.executeShellCommand('pm list packages', {
|
|
77
|
-
title: 'List installed packages',
|
|
78
|
-
timeout: 10000,
|
|
79
|
-
allowPartialResult: true, // Return partial results on timeout instead of throwing error
|
|
80
|
-
onOutput: (output) => {
|
|
81
|
-
console.log('Real-time output:', output);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
console.log('Command result:', result.output);
|
|
86
|
-
console.log('Success:', result.success);
|
|
87
|
-
console.log('Duration:', result.duration, 'ms');
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### 2. UI Element Operations
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
// Smart element finding with retry logic
|
|
94
|
-
const elements = await shellx.findElementsWithRetry({
|
|
95
|
-
className: 'android.widget.TextView',
|
|
96
|
-
textContains: 'Settings'
|
|
97
|
-
}, 3, 1000, {
|
|
98
|
-
maxResults: 10,
|
|
99
|
-
visibleOnly: true
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Print detailed element information
|
|
103
|
-
shellx.printElementsInfo(elements, 'Found Settings Elements');
|
|
104
|
-
|
|
105
|
-
// Click by text content
|
|
106
|
-
await shellx.clickByText('Wi-Fi', false);
|
|
107
|
-
|
|
108
|
-
// Input text with options
|
|
109
|
-
await shellx.inputText({
|
|
110
|
-
resourceId: 'search_field'
|
|
111
|
-
}, 'Hello ShellX', {
|
|
112
|
-
clear: true,
|
|
113
|
-
hideKeyboard: true
|
|
114
|
-
});
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### 3. Screen Operations
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
// Capture screenshot with details
|
|
121
|
-
const screenshot = await shellx.captureScreen({
|
|
122
|
-
format: 'png',
|
|
123
|
-
quality: 90,
|
|
124
|
-
saveInfo: true
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
// Swipe gestures
|
|
128
|
-
await shellx.swipe('up', 400, 800); // direction, distance, duration
|
|
129
|
-
await shellx.swipe('left', 300, 600);
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### 4. App Automation Workflow
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
// Login automation example
|
|
136
|
-
await shellx.performLogin(
|
|
137
|
-
{ resourceId: 'username_field' }, // username selector
|
|
138
|
-
{ resourceId: 'password_field' }, // password selector
|
|
139
|
-
{ resourceId: 'login_button' }, // login button selector
|
|
140
|
-
'user@example.com', // username
|
|
141
|
-
'password123' // password
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
// Navigation workflow
|
|
145
|
-
await shellx.navigateByPath([
|
|
146
|
-
'Settings',
|
|
147
|
-
'Network & internet',
|
|
148
|
-
'Wi-Fi'
|
|
149
|
-
]);
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### 5. Advanced Element Finding
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
// Wait for any of multiple elements to appear
|
|
156
|
-
const result = await shellx.waitForAnyElement([
|
|
157
|
-
{ textContains: 'OK' },
|
|
158
|
-
{ textContains: 'Cancel' },
|
|
159
|
-
{ textContains: 'Skip' }
|
|
160
|
-
], 10000);
|
|
161
|
-
|
|
162
|
-
if (result) {
|
|
163
|
-
console.log(`Found element: ${result.element.text} at index ${result.selectorIndex}`);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Scroll to find element
|
|
167
|
-
const element = await shellx.scrollToFindElement({
|
|
168
|
-
textContains: 'Privacy Settings'
|
|
169
|
-
}, 5, 'down');
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### 6. Batch Shell Commands
|
|
173
|
-
|
|
174
|
-
```typescript
|
|
175
|
-
// Execute multiple commands in sequence
|
|
176
|
-
const commands = [
|
|
177
|
-
{ command: 'am force-stop com.example.app', title: 'Stop app' },
|
|
178
|
-
{ command: 'am start -n com.example.app/.MainActivity', title: 'Start app' },
|
|
179
|
-
{ command: 'input keyevent KEYCODE_HOME', title: 'Go home', waitAfterMs: 1000 }
|
|
180
|
-
];
|
|
181
|
-
|
|
182
|
-
const results = await shellx.executeShellCommands(commands, {
|
|
183
|
-
continueOnError: true,
|
|
184
|
-
timeout: 5000
|
|
185
|
-
});
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### 7. Device Information
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
// Get comprehensive device information
|
|
192
|
-
const deviceInfo = await shellx.getDeviceInfo();
|
|
193
|
-
deviceInfo.forEach((info, index) => {
|
|
194
|
-
console.log(`${index + 1}. ${info.output}`);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
// ADB commands with enhanced output
|
|
198
|
-
const result = await shellx.adbCommand('shell dumpsys battery', {
|
|
199
|
-
title: 'Get battery status',
|
|
200
|
-
successPattern: /level: \d+/,
|
|
201
|
-
errorPattern: /error|failed/i
|
|
202
|
-
});
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
## 🎯 ShellX Class API
|
|
208
|
-
|
|
209
|
-
### Core Methods
|
|
210
|
-
|
|
211
|
-
| Method | Description | Example |
|
|
212
|
-
|--------|-------------|---------|
|
|
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')` |
|
|
218
|
-
| `clickByText(text, exact?)` | Click element by text content | `shellx.clickByText('OK', true)` |
|
|
219
|
-
| `inputText(selector, text, opts?)` | Input text into element | `shellx.inputText({resourceId: 'field'}, 'text')` |
|
|
220
|
-
| `findElementWithRetry(selector, retries?, delay?)` | Find single element with retry | `shellx.findElementWithRetry({text: 'Button'})` |
|
|
221
|
-
| `findElementsWithRetry(selector, retries?, delay?, opts?)` | Find multiple elements with retry | `shellx.findElementsWithRetry({className: 'TextView'})` |
|
|
222
|
-
| `swipe(direction, distance?, duration?)` | Perform swipe gesture | `shellx.swipe('up', 400, 800)` |
|
|
223
|
-
| `captureScreen(opts?)` | Take screenshot | `shellx.captureScreen({saveInfo: true})` |
|
|
224
|
-
|
|
225
|
-
### Utility Methods
|
|
226
|
-
|
|
227
|
-
| Method | Description |
|
|
228
|
-
|--------|-------------|
|
|
229
|
-
| `printElementInfo(element, index?)` | Print detailed element information |
|
|
230
|
-
| `printElementsInfo(elements, title?)` | Print information for multiple elements |
|
|
231
|
-
| `waitForAnyElement(selectors, timeout?)` | Wait for any of multiple elements |
|
|
232
|
-
| `scrollToFindElement(selector, maxScrolls?, direction?)` | Scroll to find element |
|
|
233
|
-
| `performLogin(userSel, passSel, btnSel, user, pass)` | Automated login flow |
|
|
234
|
-
| `navigateByPath(textPath)` | Navigate through UI by text path |
|
|
235
|
-
| `getDeviceInfo()` | Get comprehensive device information |
|
|
236
|
-
|
|
237
|
-
## 🛠️ Configuration
|
|
238
|
-
|
|
239
|
-
### Environment Variables
|
|
240
|
-
|
|
241
|
-
```bash
|
|
242
|
-
# Required: Your ShellX authentication key
|
|
243
|
-
SHELLX_AUTH_KEY=your-auth-key
|
|
244
|
-
|
|
245
|
-
# Optional: Timeout settings
|
|
246
|
-
SHELLX_TIMEOUT=20000
|
|
247
|
-
SHELLX_RETRY_ATTEMPTS=3
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Connection Options
|
|
251
|
-
|
|
252
|
-
```typescript
|
|
253
|
-
const { client, shellx } = await createShellXWithShellMonitoring({
|
|
254
|
-
timeout: 15000,
|
|
255
|
-
reconnectMaxAttempts: 3,
|
|
256
|
-
onOpen: () => console.log('Connected'),
|
|
257
|
-
onClose: (event) => console.log('Disconnected'),
|
|
258
|
-
onError: (error) => console.error('Error:', error),
|
|
259
|
-
onMessage: (data) => {
|
|
260
|
-
// Handle custom messages
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
## 🔧 Advanced Features
|
|
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
|
-
|
|
340
|
-
### Shell Output Monitoring
|
|
341
|
-
|
|
342
|
-
ShellX automatically monitors shell command output in real-time:
|
|
343
|
-
|
|
344
|
-
```typescript
|
|
345
|
-
const result = await shellx.executeShellCommand('top -n 1', {
|
|
346
|
-
onOutput: (output) => {
|
|
347
|
-
console.log('Live output:', output);
|
|
348
|
-
},
|
|
349
|
-
successPattern: /Tasks:/,
|
|
350
|
-
errorPattern: /error|failed/i,
|
|
351
|
-
timeout: 10000,
|
|
352
|
-
allowPartialResult: true // Return partial results on timeout
|
|
353
|
-
});
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
### Element Diagnostics
|
|
359
|
-
|
|
360
|
-
Built-in diagnostic tools for troubleshooting:
|
|
361
|
-
|
|
362
|
-
```typescript
|
|
363
|
-
// Automatic element diagnosis when finding fails
|
|
364
|
-
const elements = await shellx.findElementsWithRetry({
|
|
365
|
-
textContains: 'NotFound'
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
if (elements.length === 0) {
|
|
369
|
-
// ShellX automatically runs diagnostics
|
|
370
|
-
// Shows available elements, device info, etc.
|
|
371
|
-
}
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
### Intelligent Fallback
|
|
375
|
-
|
|
376
|
-
ShellX automatically handles service availability:
|
|
377
|
-
|
|
378
|
-
```typescript
|
|
379
|
-
// 1. Tries online authentication: https://shellx.ai/api/device/{authKey}
|
|
380
|
-
// 2. On success: Uses returned machine URL
|
|
381
|
-
// 3. On failure: Falls back to local: ws://127.0.0.1:9091/api/s/{authKey}
|
|
382
|
-
// 4. Seamless operation regardless of network conditions
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
## 📚 Complete Examples
|
|
386
|
-
|
|
387
|
-
Check out the [examples directory](./examples/) for comprehensive use cases:
|
|
388
|
-
|
|
389
|
-
- **[basic.ts](./examples/basic.ts)** - Basic automation operations
|
|
390
|
-
- **[shell-commands-demo.ts](./examples/shell-commands-demo.ts)** - Shell command execution
|
|
391
|
-
- **[find-elements-demo.ts](./examples/find-elements-demo.ts)** - Element finding strategies
|
|
392
|
-
|
|
393
|
-
## 🚨 Error Handling
|
|
394
|
-
|
|
395
|
-
ShellX provides comprehensive error handling with automatic recovery:
|
|
396
|
-
|
|
397
|
-
```typescript
|
|
398
|
-
try {
|
|
399
|
-
await shellx.executeShellCommand('invalid-command');
|
|
400
|
-
} catch (error) {
|
|
401
|
-
// ShellX handles timeouts, connection issues, and command failures
|
|
402
|
-
console.error('Command failed:', error.message);
|
|
403
|
-
|
|
404
|
-
// Automatic diagnostics on failure
|
|
405
|
-
// Device info, available elements, etc.
|
|
406
|
-
}
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
## 🤝 Contributing
|
|
410
|
-
|
|
411
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
412
|
-
|
|
413
|
-
## 📄 License
|
|
414
|
-
|
|
415
|
-
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
416
|
-
|
|
417
|
-
## 🆘 Support
|
|
418
|
-
|
|
419
|
-
- 📚 [Documentation](https://shellx.ai/docs)
|
|
420
|
-
- 🐛 [GitHub Issues](https://github.com/your-org/shellx/issues)
|
|
421
|
-
- 💬 [Discord Community](https://discord.gg/shellx)
|
|
422
|
-
|
|
423
|
-
## 🎉 Getting Started
|
|
424
|
-
|
|
425
|
-
1. **Install ShellX**: `npm install shellx-ai`
|
|
426
|
-
2. **Set your auth key**: `export SHELLX_AUTH_KEY="your-key"`
|
|
427
|
-
3. **Run the example**: `ts-node examples/basic.ts`
|
|
428
|
-
4. **Start automating!** 🚀
|
|
429
|
-
|
|
430
|
-
---
|
|
431
|
-
|
|
432
|
-
*Made with ❤️ for the automation community*
|
package/dist/constants.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export interface TaskClientConfig {
|
|
2
|
-
timeout: number;
|
|
3
|
-
reconnect: boolean;
|
|
4
|
-
reconnectMaxAttempts: number;
|
|
5
|
-
reconnectInterval: number;
|
|
6
|
-
pingInterval: number;
|
|
7
|
-
onOpen: () => void;
|
|
8
|
-
onClose: (event?: CloseEvent) => void;
|
|
9
|
-
onError: (error?: Event) => void;
|
|
10
|
-
onReconnectFailed: () => void;
|
|
11
|
-
onMessage?: (data: any) => void;
|
|
12
|
-
}
|
|
13
|
-
export declare const DEFAULT_CONFIG: TaskClientConfig;
|
package/dist/constants.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_CONFIG = void 0;
|
|
4
|
-
exports.DEFAULT_CONFIG = {
|
|
5
|
-
timeout: 5000,
|
|
6
|
-
reconnect: true,
|
|
7
|
-
reconnectMaxAttempts: 5,
|
|
8
|
-
reconnectInterval: 1000,
|
|
9
|
-
pingInterval: 2000,
|
|
10
|
-
onOpen: () => { },
|
|
11
|
-
onClose: () => { },
|
|
12
|
-
onError: () => { },
|
|
13
|
-
onReconnectFailed: () => { },
|
|
14
|
-
};
|