shellx-ai 1.1.0 → 1.1.2

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.
Files changed (40) hide show
  1. package/README.md +162 -586
  2. package/dist/automation/element-finder.d.ts +0 -8
  3. package/dist/automation/element-finder.js +0 -7
  4. package/dist/automation/element-finder.js.map +1 -1
  5. package/dist/automation/ui-action-handler.d.ts +1 -1
  6. package/dist/automation/ui-action-handler.js +58 -31
  7. package/dist/automation/ui-action-handler.js.map +1 -1
  8. package/dist/cbor-compat.js +9 -11
  9. package/dist/cbor-compat.js.map +1 -1
  10. package/dist/data/index.d.ts +9 -0
  11. package/dist/data/index.js +11 -0
  12. package/dist/data/index.js.map +1 -0
  13. package/dist/data/types.d.ts +351 -0
  14. package/dist/data/types.js +8 -0
  15. package/dist/data/types.js.map +1 -0
  16. package/dist/domain-manager.js +15 -13
  17. package/dist/domain-manager.js.map +1 -1
  18. package/dist/error-handler.js +5 -2
  19. package/dist/error-handler.js.map +1 -1
  20. package/dist/errors.js +4 -2
  21. package/dist/errors.js.map +1 -1
  22. package/dist/index.d.ts +36 -26
  23. package/dist/index.js +197 -86
  24. package/dist/index.js.map +1 -1
  25. package/dist/protocol.d.ts +27 -5
  26. package/dist/shellx.d.ts +139 -56
  27. package/dist/shellx.js +201 -88
  28. package/dist/shellx.js.map +1 -1
  29. package/dist/types.d.ts +38 -1
  30. package/dist/utils/retry-helper.js +5 -2
  31. package/dist/utils/retry-helper.js.map +1 -1
  32. package/dist/utils.js +6 -3
  33. package/dist/utils.js.map +1 -1
  34. package/package.json +25 -4
  35. package/dist/shell/output-buffer.d.ts +0 -152
  36. package/dist/shell/output-buffer.js +0 -163
  37. package/dist/shell/output-buffer.js.map +0 -1
  38. package/dist/shell/shell-command-executor.d.ts +0 -182
  39. package/dist/shell/shell-command-executor.js +0 -348
  40. package/dist/shell/shell-command-executor.js.map +0 -1
package/README.md CHANGED
@@ -1,586 +1,162 @@
1
- # ShellX AI
2
-
3
- <div align="center">
4
-
5
- **A powerful TypeScript library for Android device automation and UI control**
6
-
7
- [![npm version](https://badge.fury.io/js/shellx-ai.svg)](https://www.npmjs.org/package/shellx-ai)
8
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![Node.js Version](https://img.shields.io/node/v/shellx-ai.svg)](https://nodejs.org)
10
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue.svg)](https://www.typescriptlang.org/)
11
- [![Code Style](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://prettier.io)
12
-
13
- [Features](#-features) [Quick Start](#-quick-start) • [API Guide](#-api-guide) • [API Reference](#-api-reference) • [Examples](#-examples) • [Contributing](#-contributing)
14
-
15
- </div>
16
-
17
- ---
18
-
19
- ## 🎯 Which API Should I Use?
20
-
21
- ShellX provides two API levels. Choose the one that matches your needs:
22
-
23
- ### 🟢 ShellX (High-Level API) - **Recommended for 95% of users**
24
-
25
- Perfect for most automation tasks:
26
- - Simple, intuitive methods
27
- - ✅ Automatic error handling & retry
28
- - Type-safe with TypeScript
29
- - ✅ Less code to write
30
-
31
- ```typescript
32
- import { ShellX } from 'shellx-ai';
33
-
34
- const shellx = new ShellX({ deviceId: 'your-device-id' });
35
- await shellx.connect();
36
-
37
- // Easy to use!
38
- await shellx.click('Submit');
39
- await shellx.input({ text: 'Hello World' });
40
- await shellx.swipe({ fromX: 500, fromY: 1000, toX: 500, toY: 500 });
41
- ```
42
-
43
- ### 🔵 ConnectionClient (Low-Level API) - Advanced users only
44
-
45
- For special cases requiring direct WebSocket access:
46
- - Custom protocol implementations
47
- - Debugging WebSocket communication
48
- - Non-standard operations
49
-
50
- **⚠️ Warning:** Steeper learning curve. Most users don't need this.
51
-
52
- ```typescript
53
- import { ConnectionClient } from 'shellx-ai';
54
-
55
- const client = new ConnectionClient('device-id');
56
- await client.ensureConnected();
57
-
58
- // Low-level protocol access
59
- await client.sendMessage({ click: { elementId: 'element123' } });
60
- ```
61
-
62
- **📚 See [API-GUIDE.md](./API-GUIDE.md) for detailed comparison and examples.**
63
-
64
- ---
65
-
66
- ## ✨ Features
67
-
68
- ShellX AI provides a comprehensive suite of tools for Android device automation:
69
-
70
- - 🎯 **Smart UI Automation** - Advanced element finding with retry logic and multiple selector strategies
71
- - 🔧 **Shell Command Execution** - Execute shell commands with real-time output monitoring
72
- - 📸 **Screen Operations** - Screenshots, screen info, and visual element capture
73
- - 🔄 **Automatic Retry Logic** - Built-in retry mechanism for robust operations
74
- - 🛠️ **Modular Architecture** - Clean, maintainable code structure with separation of concerns
75
- - 📝 **Type-Safe API** - Full TypeScript support with comprehensive type definitions
76
- - 🌍 **Global Optimization** - Automatic domain selection based on user location
77
- - 🧪 **Well-Tested** - Comprehensive test coverage for reliability
78
-
79
- ## 📦 Installation
80
-
81
- ```bash
82
- npm install shellx-ai
83
- ```
84
-
85
- ### Requirements
86
-
87
- - **Node.js**: >= 14.0.0
88
- - **TypeScript**: >= 4.0.0 (recommended)
89
-
90
- ## 🚀 Quick Start
91
-
92
- ### Basic Usage
93
-
94
- ```typescript
95
- import { ShellX } from 'shellx-ai';
96
-
97
- // Create ShellX instance
98
- const shellx = new ShellX({
99
- deviceId: 'your-device-id',
100
- onOpen: () => console.log('Connected!'),
101
- onMessage: (message) => console.log('Message:', message)
102
- });
103
-
104
- // Wait for connection to be ready
105
- await shellx.ready();
106
-
107
- // Execute shell command
108
- const result = await shellx.command({ cmd: 'getprop ro.build.version.release' });
109
- console.log('Android version:', result.output);
110
-
111
- // Click UI element (simplified API)
112
- await shellx.click('Settings');
113
-
114
- // Or use full API
115
- await shellx.click({ text: 'Settings', clickType: 'single' });
116
-
117
- // Find elements
118
- const elements = await shellx.find({
119
- text: 'Submit',
120
- multiple: true,
121
- maxResults: 10
122
- });
123
-
124
- console.log(`Found ${elements.count} elements`);
125
- ```
126
-
127
- ### With Connection Callbacks
128
-
129
- ```typescript
130
- import { ShellX } from 'shellx-ai';
131
-
132
- const shellx = new ShellX({
133
- deviceId: 'your-device-id',
134
- timeout: 5000,
135
- reconnect: true,
136
- reconnectMaxAttempts: 5,
137
- onOpen: () => console.log('✅ Connected'),
138
- onClose: () => console.log('❌ Disconnected'),
139
- onError: (error) => console.error('⚠️ Error:', error),
140
- onMessage: (message) => console.log('📨 Message:', message)
141
- });
142
-
143
- // Wait for connection
144
- await shellx.ready();
145
-
146
- // Ready to use!
147
- await shellx.command('pm list packages');
148
- ```
149
-
150
- ## 🎯 API Reference
151
-
152
- ### Core Classes
153
-
154
- #### `ShellX`
155
-
156
- Main class providing high-level automation utilities.
157
-
158
- **Constructor:**
159
- ```typescript
160
- constructor(options: ShellXOptions)
161
- ```
162
-
163
- **ShellXOptions:**
164
- ```typescript
165
- interface ShellXOptions {
166
- deviceId: string; // Required: Device ID
167
- timeout?: number; // Connection timeout (default: 5000ms)
168
- reconnect?: boolean; // Enable auto-reconnect (default: true)
169
- reconnectMaxAttempts?: number; // Max reconnect attempts (default: 5)
170
- reconnectInterval?: number; // Reconnect interval (default: 1000ms)
171
- pingInterval?: number; // Ping interval (default: 2000ms)
172
- onOpen?: () => void; // Connection opened callback
173
- onClose?: () => void; // Connection closed callback
174
- onError?: (error?: Event) => void; // Error callback
175
- onReconnectFailed?: () => void; // Reconnect failed callback
176
- onMessage?: (message: WsServer) => void; // Message callback
177
- }
178
- ```
179
-
180
- **Methods:**
181
-
182
- | Method | Description | Return Type |
183
- |--------|-------------|-------------|
184
- | `ready()` | Wait for connection to be ready | `Promise<void>` |
185
- | `click(data)` | Click element by ID, coordinates, or selector | `Promise<ActionResult>` |
186
- | `input(data)` | Input text into element | `Promise<ActionResult>` |
187
- | `swipe(data)` | Perform swipe gesture | `Promise<ActionResult>` |
188
- | `pressKey(data)` | Press hardware key | `Promise<ActionResult>` |
189
- | `wait(data)` | Wait for element condition | `Promise<ActionResult>` |
190
- | `find(data)` | Find UI elements | `Promise<FindResult>` |
191
- | `clipboard(data)` | Clipboard operations (get/set/paste) | `Promise<ActionResult>` |
192
- | `takeScreenshot(data)` | Capture screenshot | `Promise<ActionResult>` |
193
- | `getScreenInfo()` | Get screen information | `Promise<ScreenInfoResponse>` |
194
- | `executeActions(actions)` | Execute multiple actions in sequence | `Promise<ActionResult[]>` |
195
-
196
- **Element Finder Methods:**
197
-
198
- | Method | Description | Return Type |
199
- |--------|-------------|-------------|
200
- | `findElementWithRetry(selector, maxRetries, retryDelay)` | Find single element with retry | `Promise<UIElement \| null>` |
201
- | `findElementsWithRetry(selector, maxRetries, retryDelay, options)` | Find multiple elements | `Promise<UIElement[]>` |
202
- | `waitForAnyElement(selectors, timeout)` | Wait for any element to appear | `Promise<{element, selectorIndex} \| null>` |
203
- | `scrollToFindElement(selector, maxScrolls, direction)` | Scroll to find element | `Promise<UIElement \| null>` |
204
-
205
- **Shell Command Methods:**
206
-
207
- | Method | Description | Return Type |
208
- |--------|-------------|-------------|
209
- | `executeShellCommand(command, options)` | Execute shell command with monitoring | `Promise<ShellCommandResult>` |
210
- | `executeSimpleShellCommand(command, options)` | Execute simple shell command | `Promise<ShellCommandResult>` |
211
- | `executeShellCommands(commands, options)` | Execute multiple commands | `Promise<ShellCommandResult[]>` |
212
- | `adbCommand(command, options)` | Execute ADB command | `Promise<ShellCommandResult>` |
213
- | `executeCode(code, context, timeout)` | Execute code in sandboxed environment | `Promise<any>` |
214
-
215
- **Device Info Methods:**
216
-
217
- | Method | Description | Return Type |
218
- |--------|-------------|-------------|
219
- | `getDeviceInfo()` | Get comprehensive device information | `Promise<ShellCommandResult[]>` |
220
- | `getDeviceModel()` | Get device model | `Promise<string \| undefined>` |
221
- | `getAndroidVersion()` | Get Android version | `Promise<string \| undefined>` |
222
- | `getScreenSize()` | Get screen size | `Promise<string \| undefined>` |
223
- | `getBatteryInfo()` | Get battery information | `Promise<BatteryInfo \| undefined>` |
224
- | `getDeviceInfoSummary()` | Get device information summary | `Promise<DeviceInfo>` |
225
-
226
- **Navigation Methods:**
227
-
228
- | Method | Description | Return Type |
229
- |--------|-------------|-------------|
230
- | `navigateByPath(textPath)` | Navigate using text path | `Promise<boolean>` |
231
- | `clickByText(text, exact)` | Click element by text | `Promise<boolean>` |
232
- | `inputText(selector, text, options)` | Input text into field | `Promise<boolean>` |
233
-
234
- ### Type Definitions
235
-
236
- #### `Click`
237
-
238
- ```typescript
239
- interface Click {
240
- targetElementId?: string;
241
- targetResourceId?: string;
242
- targetText?: string;
243
- targetClass?: string;
244
- targetX?: number;
245
- targetY?: number;
246
- clickType?: 'single' | 'double' | 'long';
247
- wait?: number;
248
- retry?: number;
249
- }
250
- ```
251
-
252
- #### `Input`
253
-
254
- ```typescript
255
- interface Input {
256
- targetElementId?: string;
257
- targetResourceId?: string;
258
- targetText?: string;
259
- targetClass?: string;
260
- text: string;
261
- clear?: boolean;
262
- hideKeyboard?: boolean;
263
- wait?: number;
264
- retry?: number;
265
- }
266
- ```
267
-
268
- #### `Swipe`
269
-
270
- ```typescript
271
- interface Swipe {
272
- fromX: number;
273
- fromY: number;
274
- toX: number;
275
- toY: number;
276
- duration?: number;
277
- wait?: number;
278
- retry?: number;
279
- }
280
- ```
281
-
282
- #### `Command`
283
-
284
- ```typescript
285
- interface Command {
286
- cmd: string;
287
- timeout?: number;
288
- wait?: number;
289
- retry?: number;
290
- }
291
- ```
292
-
293
- #### `ActionResult`
294
-
295
- ```typescript
296
- interface ActionResult {
297
- success: boolean;
298
- data?: any;
299
- error?: string;
300
- duration: number;
301
- }
302
- ```
303
-
304
- ## 📚 Examples
305
-
306
- ### Example 1: UI Automation Workflow
307
-
308
- ```typescript
309
- import { createShellXWithShellMonitoring } from 'shellx-ai';
310
-
311
- async function automateApp() {
312
- const shellx = await createShellXWithShellMonitoring({
313
- deviceId: process.env.SHELLX_DEVICE_ID
314
- });
315
-
316
- try {
317
- // Navigate to settings
318
- await shellx.clickByText('Settings');
319
- await shellx.wait({ targetText: 'Accounts', condition: 'visible', timeout: 5000 });
320
-
321
- // Click on account item
322
- await shellx.click({ targetText: 'Accounts' });
323
-
324
- // Input text
325
- await shellx.input({
326
- targetResourceId: 'username_field',
327
- text: 'user@example.com',
328
- clear: true
329
- });
330
-
331
- // Take screenshot
332
- await shellx.takeScreenshot({
333
- format: 'png',
334
- quality: 90,
335
- saveToFile: true
336
- });
337
-
338
- console.log('Automation completed successfully!');
339
- } catch (error) {
340
- console.error('Automation failed:', error);
341
- }
342
- }
343
-
344
- automateApp();
345
- ```
346
-
347
- ### Example 2: Batch Command Execution
348
-
349
- ```typescript
350
- import { createShellX } from 'shellx-ai';
351
- import ConnectionTaskClient from 'shellx-ai';
352
-
353
- async function executeDeviceCommands() {
354
- const client = new ConnectionTaskClient('device-id');
355
- await client.waitForInitialization();
356
- const shellx = createShellX(client);
357
-
358
- // Execute multiple commands
359
- const commands = [
360
- { command: 'pm list packages', title: 'List packages' },
361
- { command: 'dumpsys battery', title: 'Get battery info' },
362
- { command: 'wm size', title: 'Get screen size' }
363
- ];
364
-
365
- const results = await shellx.executeShellCommands(commands, {
366
- continueOnError: true,
367
- timeout: 10000
368
- });
369
-
370
- results.forEach((result, index) => {
371
- console.log(`\n${commands[index].title}:`);
372
- console.log(`Success: ${result.success}`);
373
- console.log(`Output: ${result.output}`);
374
- if (result.error) {
375
- console.error(`Error: ${result.error}`);
376
- }
377
- });
378
- }
379
-
380
- executeDeviceCommands();
381
- ```
382
-
383
- ### Example 3: Advanced Element Finding
384
-
385
- ```typescript
386
- async function findAndInteract() {
387
- const shellx = await createShellXWithShellMonitoring({
388
- deviceId: 'device-id'
389
- });
390
-
391
- // Find element with retry
392
- const element = await shellx.findElementWithRetry(
393
- { text: 'Submit Button', visible: true, clickable: true },
394
- 5, // max retries
395
- 1000 // retry delay
396
- );
397
-
398
- if (element) {
399
- console.log('Found element:', element.elementId);
400
- shellx.printElementInfo(element);
401
- } else {
402
- console.log('Element not found');
403
-
404
- // Try scrolling to find it
405
- const foundElement = await shellx.scrollToFindElement(
406
- { text: 'Submit Button' },
407
- 5,
408
- 'down'
409
- );
410
-
411
- if (foundElement) {
412
- console.log('Found after scrolling!');
413
- await shellx.click({ targetElementId: foundElement.elementId });
414
- }
415
- }
416
- }
417
-
418
- findAndInteract();
419
- ```
420
-
421
- ### Example 4: Action Sequence
422
-
423
- ```typescript
424
- async function executeActionSequence() {
425
- const shellx = await createShellXWithShellMonitoring({
426
- deviceId: 'device-id'
427
- });
428
-
429
- // Execute multiple actions
430
- const actions = [
431
- // Click settings
432
- { targetText: 'Settings' },
433
-
434
- // Wait for menu
435
- { targetText: 'Network', condition: 'visible', timeout: 5000 },
436
-
437
- // Click network
438
- { targetText: 'Network' },
439
-
440
- // Execute command
441
- { cmd: 'dumpsys wifi' },
442
-
443
- // Take screenshot
444
- { format: 'png' }
445
- ];
446
-
447
- const results = await shellx.executeActions(actions);
448
-
449
- results.forEach((result, index) => {
450
- const status = result.success ? '✅' : '❌';
451
- console.log(`Action ${index + 1}: ${status}`);
452
- if (!result.success) {
453
- console.error(` Error: ${result.error}`);
454
- }
455
- });
456
- }
457
-
458
- executeActionSequence();
459
- ```
460
-
461
- ## 🛠️ Development
462
-
463
- ### Setup
464
-
465
- ```bash
466
- # Clone repository
467
- git clone https://github.com/10cl/shellx.git
468
- cd shellx
469
-
470
- # Install dependencies
471
- npm install
472
-
473
- # Build project
474
- npm run build
475
-
476
- # Run tests
477
- npm test
478
- ```
479
-
480
- ### Available Scripts
481
-
482
- | Script | Description |
483
- |--------|-------------|
484
- | `npm run build` | Compile TypeScript to JavaScript |
485
- | `npm run build:watch` | Watch mode for compilation |
486
- | `npm run type-check` | Type check without emitting files |
487
- | `npm run lint` | Run ESLint |
488
- | `npm run lint:fix` | Fix ESLint errors automatically |
489
- | `npm run format` | Format code with Prettier |
490
- | `npm run format:check` | Check code formatting |
491
- | `npm test` | Run tests |
492
- | `npm run test:coverage` | Run tests with coverage |
493
- | `npm run clean` | Remove dist directory |
494
-
495
- ### Project Structure
496
-
497
- ```
498
- shellx-ai/
499
- ├── src/
500
- │ ├── automation/
501
- │ │ ├── element-finder.ts # Element finding with retry logic
502
- │ │ ├── ui-action-handler.ts # UI action execution
503
- │ │ └── device-info-helper.ts # Device information retrieval
504
- │ ├── shell/
505
- │ │ ├── output-buffer.ts # Shell output buffering
506
- │ │ └── shell-command-executor.ts # Shell command execution
507
- │ ├── utils/
508
- │ │ └── retry-helper.ts # Generic retry mechanism
509
- │ ├── index.ts # Main connection client
510
- │ ├── shellx.ts # Main ShellX class
511
- │ ├── protocol.ts # Protocol type definitions
512
- │ ├── types.ts # Simplified type definitions
513
- │ ├── domain-manager.ts # Domain management
514
- │ └── utils.ts # Utility functions
515
- ├── dist/ # Compiled output
516
- ├── package.json
517
- ├── tsconfig.json
518
- ├── jest.config.js
519
- ├── .eslintrc.json
520
- ├── .prettierrc.json
521
- └── README.md
522
- ```
523
-
524
- ## 🧪 Testing
525
-
526
- ```bash
527
- # Run all tests
528
- npm test
529
-
530
- # Run tests in watch mode
531
- npm run test:watch
532
-
533
- # Generate coverage report
534
- npm run test:coverage
535
-
536
- # Type checking
537
- npm run type-check
538
-
539
- # Linting
540
- npm run lint
541
- ```
542
-
543
- ## 🤝 Contributing
544
-
545
- We welcome contributions! Please follow these steps:
546
-
547
- 1. Fork the repository
548
- 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
549
- 3. Commit your changes (`git commit -m 'Add amazing feature'`)
550
- 4. Push to the branch (`git push origin feature/amazing-feature`)
551
- 5. Open a Pull Request
552
-
553
- ### Code Style
554
-
555
- - Use TypeScript for all new features
556
- - Follow ESLint rules (`npm run lint`)
557
- - Format code with Prettier (`npm run format`)
558
- - Add JSDoc comments for public APIs
559
- - Write tests for new functionality
560
- - Ensure all tests pass before submitting
561
-
562
- ## 📝 License
563
-
564
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
565
-
566
- ## 🆘 Support
567
-
568
- - 📚 [Documentation](https://github.com/10cl/shellx/wiki)
569
- - 🐛 [Issue Tracker](https://github.com/10cl/shellx/issues)
570
- - 💬 [Discussions](https://github.com/10cl/shellx/discussions)
571
-
572
- ## 🌟 Acknowledgments
573
-
574
- - Built with [TypeScript](https://www.typescriptlang.org/)
575
- - Powered by [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
576
- - Tested with [Jest](https://jestjs.io/)
577
-
578
- ---
579
-
580
- <div align="center">
581
-
582
- **Built with ❤️ for the automation community**
583
-
584
- [⬆ Back to Top](#shellx-ai)
585
-
586
- </div>
1
+ # ShellX-AI 架构文档
2
+
3
+ ## 概述
4
+
5
+ ShellX-AI 是一个 Android 设备自动化控制库,提供 WebSocket 通信和 HTTP API 支持。
6
+
7
+ ## 模块结构
8
+
9
+ ```
10
+ shellx-ai/ # 核心库
11
+ ├── src/
12
+ │ ├── index.ts # 入口,导出 ConnectionClient 和 ShellX
13
+ │ ├── shellx.ts # 高级 API
14
+ │ ├── protocol.ts # 协议定义
15
+ │ └── data/ # 数据操作类型
16
+ │ └── types.ts # 日历、联系人等数据类型
17
+
18
+ phone-agent/ # Phone Agent
19
+ ├── src/
20
+ │ ├── index.ts # Agent 初始化
21
+ │ └── tools.ts # 工具定义
22
+
23
+ shellx-cli/ # HTTP API 服务器
24
+ ├── src/
25
+ │ ├── server/ # HTTP 路由
26
+ │ └── cli-core.ts # CLI 核心
27
+
28
+ shellx-cli-v2/ # CLI v2 (pi-tui)
29
+ ├── src/
30
+ │ └── agent.ts # Agent 包装器
31
+ ```
32
+
33
+ ## 架构层次
34
+
35
+ ```
36
+ ┌─────────────────────────────────────────────────────┐
37
+ │ Phone Agent (phone-agent) │
38
+ │ - 工具定义和参数验证 │
39
+ │ - LLM 意图转换 │
40
+ └─────────────────────────────────────────────────────┘
41
+
42
+ ┌─────────────────────────────────────────────────────┐
43
+ │ ShellX-AI (shellx-ai)
44
+ │ - ShellX: 高级 API (推荐) │
45
+ │ - ConnectionClient: WebSocket 原始 API │
46
+ └─────────────────────────────────────────────────────┘
47
+
48
+ ┌─────────────────────────────────────────────────────┐
49
+ │ Android 设备端 │
50
+ │ (ShellX 服务 + OpenClaw) │
51
+ └─────────────────────────────────────────────────────┘
52
+ ```
53
+
54
+ ## 核心功能
55
+
56
+ ### ShellX API
57
+
58
+ ```typescript
59
+ // 连接管理
60
+ const shellx = new ShellX({ deviceId, timeout: 5000 });
61
+
62
+ // UI 操作
63
+ await shellx.click(selector);
64
+ await shellx.input(selector, text);
65
+ await shellx.swipe(from, to);
66
+
67
+ // 数据操作
68
+ await shellx.getCalendarList();
69
+ await shellx.getCalendarEvents({ limit: 10 });
70
+ await shellx.addCalendarEvent({ title, startTime, endTime });
71
+ ```
72
+
73
+ ### Phone Agent
74
+
75
+ ```typescript
76
+ import { PhoneAgent } from '@shellx/phone-agent';
77
+
78
+ const agent = new PhoneAgent({
79
+ apiKey,
80
+ baseUrl,
81
+ model,
82
+ shellx,
83
+ maxSteps: 10,
84
+ });
85
+
86
+ await agent.run("帮我添加一个明天下午3点的会议");
87
+ ```
88
+
89
+ ### HTTP API
90
+
91
+ ```bash
92
+ # 获取日历事件
93
+ GET /api/data/calendar/events?limit=10
94
+
95
+ # 添加日历事件
96
+ POST /api/data/calendar/add
97
+ {
98
+ "title": "会议",
99
+ "startTime": 1740990000000,
100
+ "endTime": 1740997200000
101
+ }
102
+ ```
103
+
104
+ ## 协议
105
+
106
+ ### WebSocket (dataRequest)
107
+
108
+ ```typescript
109
+ // 请求
110
+ {
111
+ dataRequest: {
112
+ requestType: "getCalendarEvents",
113
+ params: { limit: 10 }
114
+ }
115
+ }
116
+
117
+ // 响应
118
+ {
119
+ dataRequest: {
120
+ requestType: "getCalendarEvents",
121
+ result: { success: true, events: [...] }
122
+ }
123
+ }
124
+ ```
125
+
126
+ ## 技术栈
127
+
128
+ - **TypeScript** - 类型安全
129
+ - **WebSocket** - 设备通信
130
+ - **CBOR** - 消息编码
131
+ - **@sinclair/typebox** - 参数验证
132
+ - **@mariozechner/pi-agent-core** - Agent 框架
133
+ - **Ink** - TUI 组件库
134
+
135
+ ## 环境变量
136
+
137
+ | 变量名 | 用途 | 默认值 |
138
+ |--------|------|--------|
139
+ | `SHELLX_DEVICE_ID` | 设备 ID | - |
140
+ | `SHELLX_SERVER_PORT` | HTTP 端口 | 8080 |
141
+ | `SHELLX_LOG_LEVEL` | 日志级别 | INFO |
142
+
143
+ ## 快速开始
144
+
145
+ ```bash
146
+ # 安装依赖
147
+ npm install
148
+
149
+ # 构建
150
+ npm run build
151
+
152
+ # 启动设备端服务
153
+ # (需要单独安装 Android 端服务)
154
+
155
+ # 运行 Phone Agent
156
+ npm run build:phone-agent
157
+ ```
158
+
159
+ ## 文档
160
+
161
+ - [API 文档](./API中文版.md) - 完整的 API 参考
162
+ - [架构设计文档](./架构设计文档.md) - 详细的架构说明