shellx-ai 1.0.12 → 1.1.1

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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +666 -0
  3. package/dist/automation/element-finder.d.ts +189 -0
  4. package/dist/automation/element-finder.js +322 -0
  5. package/dist/automation/element-finder.js.map +1 -0
  6. package/dist/automation/ui-action-handler.d.ts +330 -0
  7. package/dist/automation/ui-action-handler.js +873 -0
  8. package/dist/automation/ui-action-handler.js.map +1 -0
  9. package/dist/cbor-compat.d.ts +27 -0
  10. package/dist/cbor-compat.js +111 -0
  11. package/dist/cbor-compat.js.map +1 -0
  12. package/dist/domain-manager.d.ts +80 -0
  13. package/dist/domain-manager.js +161 -0
  14. package/dist/domain-manager.js.map +1 -0
  15. package/dist/error-handler.d.ts +87 -0
  16. package/dist/error-handler.js +151 -0
  17. package/dist/error-handler.js.map +1 -0
  18. package/dist/errors.d.ts +114 -0
  19. package/dist/errors.js +139 -0
  20. package/dist/errors.js.map +1 -0
  21. package/dist/index.d.ts +163 -54
  22. package/dist/index.js +678 -481
  23. package/dist/index.js.map +1 -0
  24. package/dist/logger.d.ts +81 -0
  25. package/dist/logger.js +128 -0
  26. package/dist/logger.js.map +1 -0
  27. package/dist/protocol.d.ts +147 -31
  28. package/dist/protocol.js +2 -2
  29. package/dist/protocol.js.map +1 -0
  30. package/dist/shell/output-buffer.d.ts +152 -0
  31. package/dist/shell/output-buffer.js +176 -0
  32. package/dist/shell/output-buffer.js.map +1 -0
  33. package/dist/shell/shell-command-executor.d.ts +182 -0
  34. package/dist/shell/shell-command-executor.js +404 -0
  35. package/dist/shell/shell-command-executor.js.map +1 -0
  36. package/dist/shellx.d.ts +681 -178
  37. package/dist/shellx.js +762 -1159
  38. package/dist/shellx.js.map +1 -0
  39. package/dist/types.d.ts +132 -57
  40. package/dist/types.js +4 -4
  41. package/dist/types.js.map +1 -0
  42. package/dist/utils/retry-helper.d.ts +73 -0
  43. package/dist/utils/retry-helper.js +95 -0
  44. package/dist/utils/retry-helper.js.map +1 -0
  45. package/dist/utils.d.ts +3 -3
  46. package/dist/utils.js +20 -23
  47. package/dist/utils.js.map +1 -0
  48. package/package.json +95 -62
@@ -0,0 +1,189 @@
1
+ /**
2
+ * ElementFinder - A module for finding and managing UI elements
3
+ *
4
+ * This module provides functionality to search for UI elements with various
5
+ * selectors, retry logic, and helper methods for element navigation.
6
+ */
7
+ import type { ElementSelector, UIElement, ScreenInfoResponse, FindOptions } from "../protocol.js";
8
+ import type { Element } from "../types.js";
9
+ /**
10
+ * Interface for ConnectionClient methods used by ElementFinder
11
+ */
12
+ interface IConnectionClient {
13
+ findElement(selector: ElementSelector, options?: FindOptions): Promise<{
14
+ elements?: UIElement[];
15
+ }>;
16
+ getScreenInfo(): Promise<ScreenInfoResponse>;
17
+ }
18
+ /**
19
+ * Options for finding elements
20
+ */
21
+ export interface FindElementOptions {
22
+ /** Maximum number of retry attempts */
23
+ maxRetries?: number;
24
+ /** Delay between retry attempts in milliseconds */
25
+ retryDelay?: number;
26
+ /** Maximum number of results to return */
27
+ maxResults?: number;
28
+ /** Whether to only return visible elements */
29
+ visibleOnly?: boolean;
30
+ /** Whether to only return clickable elements */
31
+ clickableOnly?: boolean;
32
+ /** Whether to find multiple elements */
33
+ multiple?: boolean;
34
+ /** Timeout for finding elements in milliseconds */
35
+ timeout?: number;
36
+ }
37
+ /**
38
+ * Options for scrolling to find elements
39
+ */
40
+ export interface ScrollToFindOptions {
41
+ /** Maximum number of scroll attempts */
42
+ maxScrolls?: number;
43
+ /** Scroll direction */
44
+ direction?: "up" | "down" | "left" | "right";
45
+ /** Scroll distance in pixels */
46
+ distance?: number;
47
+ }
48
+ /**
49
+ * ElementFinder class handles UI element discovery and navigation
50
+ *
51
+ * This class provides methods to:
52
+ * - Find single or multiple elements with retry logic
53
+ * - Navigate through app UI using text paths
54
+ * - Scroll to find elements
55
+ * - Wait for elements to appear or disappear
56
+ */
57
+ export declare class ElementFinder {
58
+ private client;
59
+ private logger;
60
+ /**
61
+ * Creates an ElementFinder instance
62
+ *
63
+ * @param client - The ConnectionClient instance for element operations
64
+ */
65
+ constructor(client: IConnectionClient);
66
+ /**
67
+ * Convert UIElement to simplified Element type
68
+ *
69
+ * @param uiElement - The UIElement to convert
70
+ * @returns Converted Element object
71
+ */
72
+ private convertElement;
73
+ /**
74
+ * Find a single element with retry logic
75
+ *
76
+ * @param selector - The element selector criteria
77
+ * @param options - Find options with retry configuration
78
+ * @returns Promise resolving to the found UIElement or null if not found
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const element = await elementFinder.findElement(
83
+ * { text: 'Submit', visible: true },
84
+ * { maxRetries: 3, retryDelay: 1000 }
85
+ * );
86
+ * ```
87
+ */
88
+ findElement(selector: ElementSelector, options?: FindElementOptions): Promise<UIElement | null>;
89
+ /**
90
+ * Find multiple elements with retry logic
91
+ *
92
+ * @param selector - The element selector criteria
93
+ * @param options - Find options with retry configuration
94
+ * @returns Promise resolving to an array of UIElements
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * const elements = await elementFinder.findElements(
99
+ * { className: 'Button', visible: true },
100
+ * { maxResults: 10, visibleOnly: true }
101
+ * );
102
+ * ```
103
+ */
104
+ findElements(selector: ElementSelector, options?: FindElementOptions): Promise<UIElement[]>;
105
+ /**
106
+ * Find elements and return simplified Element objects
107
+ *
108
+ * @param selector - The element selector criteria
109
+ * @param options - Find options
110
+ * @returns Promise resolving to an array of simplified Element objects
111
+ */
112
+ findElementsAsSimple(selector: ElementSelector, options?: FindElementOptions): Promise<Element[]>;
113
+ /**
114
+ * Wait for any of multiple elements to appear
115
+ * @deprecated Use waitAnyElement() instead for consistency
116
+ */
117
+ waitForAnyElement(selectors: ElementSelector[], timeout?: number): Promise<{
118
+ element: UIElement;
119
+ selectorIndex: number;
120
+ } | null>;
121
+ /**
122
+ * Wait for any of multiple elements to appear
123
+ *
124
+ * @param selectors - Array of element selectors to check
125
+ * @param timeout - Maximum wait time in milliseconds (default: 10000)
126
+ * @returns Promise resolving to the first found element and its selector index, or null
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const result = await elementFinder.waitAnyElement(
131
+ * [
132
+ * { text: 'Submit' },
133
+ * { text: 'OK' },
134
+ * { text: 'Confirm' }
135
+ * ],
136
+ * 10000
137
+ * );
138
+ * if (result) {
139
+ * console.log(`Found element at selector index: ${result.selectorIndex}`);
140
+ * }
141
+ * ```
142
+ */
143
+ waitAnyElement(selectors: ElementSelector[], timeout?: number): Promise<{
144
+ element: UIElement;
145
+ selectorIndex: number;
146
+ } | null>;
147
+ /**
148
+ * Scroll to find an element
149
+ *
150
+ * This method performs scroll actions in the specified direction
151
+ * to find an element that's not currently visible on screen.
152
+ *
153
+ * @param selector - The element selector criteria
154
+ * @param swipeCallback - Callback function to perform swipe action
155
+ * @param options - Scroll options
156
+ * @returns Promise resolving to the found UIElement or null
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const element = await elementFinder.scrollToFindElement(
161
+ * { text: 'Target' },
162
+ * async (from, to) => await shellx.swipe({ fromX: from.x, fromY: from.y, toX: to.x, toY: to.y }),
163
+ * { maxScrolls: 5, direction: 'down' }
164
+ * );
165
+ * ```
166
+ */
167
+ scrollToFindElement(selector: ElementSelector, swipeCallback: (from: {
168
+ x: number;
169
+ y: number;
170
+ }, to: {
171
+ x: number;
172
+ y: number;
173
+ }) => Promise<void>, options?: ScrollToFindOptions): Promise<UIElement | null>;
174
+ /**
175
+ * Print information about a single element
176
+ *
177
+ * @param element - The UIElement to print
178
+ * @param index - Optional index number for display
179
+ */
180
+ printElementInfo(element: UIElement, index?: number): void;
181
+ /**
182
+ * Print summary information about multiple elements
183
+ *
184
+ * @param elements - Array of UIElements to summarize
185
+ * @param title - Optional title for the summary
186
+ */
187
+ printElementsInfo(elements: UIElement[], title?: string): void;
188
+ }
189
+ export {};
@@ -0,0 +1,322 @@
1
+ /**
2
+ * ElementFinder - A module for finding and managing UI elements
3
+ *
4
+ * This module provides functionality to search for UI elements with various
5
+ * selectors, retry logic, and helper methods for element navigation.
6
+ */
7
+ import { createLogger } from "../logger.js";
8
+ /**
9
+ * ElementFinder class handles UI element discovery and navigation
10
+ *
11
+ * This class provides methods to:
12
+ * - Find single or multiple elements with retry logic
13
+ * - Navigate through app UI using text paths
14
+ * - Scroll to find elements
15
+ * - Wait for elements to appear or disappear
16
+ */
17
+ export class ElementFinder {
18
+ client;
19
+ logger = createLogger("ElementFinder");
20
+ /**
21
+ * Creates an ElementFinder instance
22
+ *
23
+ * @param client - The ConnectionClient instance for element operations
24
+ */
25
+ constructor(client) {
26
+ this.client = client;
27
+ }
28
+ /**
29
+ * Convert UIElement to simplified Element type
30
+ *
31
+ * @param uiElement - The UIElement to convert
32
+ * @returns Converted Element object
33
+ */
34
+ convertElement(uiElement) {
35
+ return {
36
+ id: uiElement.elementId,
37
+ text: uiElement.text,
38
+ class: uiElement.className,
39
+ left: uiElement.bounds.left,
40
+ top: uiElement.bounds.top,
41
+ right: uiElement.bounds.right,
42
+ bottom: uiElement.bounds.bottom,
43
+ visible: uiElement.visible,
44
+ clickable: uiElement.clickable,
45
+ };
46
+ }
47
+ /**
48
+ * Find a single element with retry logic
49
+ *
50
+ * @param selector - The element selector criteria
51
+ * @param options - Find options with retry configuration
52
+ * @returns Promise resolving to the found UIElement or null if not found
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const element = await elementFinder.findElement(
57
+ * { text: 'Submit', visible: true },
58
+ * { maxRetries: 3, retryDelay: 1000 }
59
+ * );
60
+ * ```
61
+ */
62
+ async findElement(selector, options = {}) {
63
+ const { maxRetries = 3, retryDelay = 1000, maxResults = 1, visibleOnly = true, timeout = 3000, } = options;
64
+ for (let i = 0; i < maxRetries; i++) {
65
+ try {
66
+ const result = await this.client.findElement(selector, {
67
+ timeout,
68
+ visibleOnly,
69
+ maxResults,
70
+ });
71
+ if (!result || !Array.isArray(result.elements)) {
72
+ this.logger.warn("⚠️ Empty result or missing elements field");
73
+ continue;
74
+ }
75
+ if (result.elements.length > 0) {
76
+ return result.elements[0] ?? null;
77
+ }
78
+ }
79
+ catch (error) {
80
+ this.logger.info(`Find attempt ${i + 1}/${maxRetries} failed:`, error);
81
+ }
82
+ if (i < maxRetries - 1) {
83
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
84
+ }
85
+ }
86
+ return null;
87
+ }
88
+ /**
89
+ * Find multiple elements with retry logic
90
+ *
91
+ * @param selector - The element selector criteria
92
+ * @param options - Find options with retry configuration
93
+ * @returns Promise resolving to an array of UIElements
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const elements = await elementFinder.findElements(
98
+ * { className: 'Button', visible: true },
99
+ * { maxResults: 10, visibleOnly: true }
100
+ * );
101
+ * ```
102
+ */
103
+ async findElements(selector, options = {}) {
104
+ const { maxRetries = 3, retryDelay = 1000, maxResults = 10, visibleOnly = true, clickableOnly = false, timeout = 3000, } = options;
105
+ for (let i = 0; i < maxRetries; i++) {
106
+ try {
107
+ const result = await this.client.findElement(selector, {
108
+ timeout,
109
+ visibleOnly,
110
+ clickableOnly,
111
+ multiple: true,
112
+ maxResults,
113
+ });
114
+ if (!result || !Array.isArray(result.elements)) {
115
+ this.logger.warn("⚠️ Empty result or missing elements field");
116
+ continue;
117
+ }
118
+ if (result.elements.length > 0) {
119
+ this.logger.info(`🔍 Found ${result.elements.length} elements`);
120
+ return result.elements;
121
+ }
122
+ }
123
+ catch (error) {
124
+ this.logger.info(`Find attempt ${i + 1}/${maxRetries} failed:`, error);
125
+ }
126
+ if (i < maxRetries - 1) {
127
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
128
+ }
129
+ }
130
+ this.logger.info("❌ No elements found");
131
+ return [];
132
+ }
133
+ /**
134
+ * Find elements and return simplified Element objects
135
+ *
136
+ * @param selector - The element selector criteria
137
+ * @param options - Find options
138
+ * @returns Promise resolving to an array of simplified Element objects
139
+ */
140
+ async findElementsAsSimple(selector, options = {}) {
141
+ const uiElements = await this.findElements(selector, options);
142
+ return uiElements.map((el) => this.convertElement(el));
143
+ }
144
+ /**
145
+ * Wait for any of multiple elements to appear
146
+ * @deprecated Use waitAnyElement() instead for consistency
147
+ */
148
+ async waitForAnyElement(selectors, timeout = 10000) {
149
+ return this.waitAnyElement(selectors, timeout);
150
+ }
151
+ /**
152
+ * Wait for any of multiple elements to appear
153
+ *
154
+ * @param selectors - Array of element selectors to check
155
+ * @param timeout - Maximum wait time in milliseconds (default: 10000)
156
+ * @returns Promise resolving to the first found element and its selector index, or null
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const result = await elementFinder.waitAnyElement(
161
+ * [
162
+ * { text: 'Submit' },
163
+ * { text: 'OK' },
164
+ * { text: 'Confirm' }
165
+ * ],
166
+ * 10000
167
+ * );
168
+ * if (result) {
169
+ * console.log(`Found element at selector index: ${result.selectorIndex}`);
170
+ * }
171
+ * ```
172
+ */
173
+ async waitAnyElement(selectors, timeout = 10000) {
174
+ const startTime = Date.now();
175
+ const checkInterval = 500;
176
+ while (Date.now() - startTime < timeout) {
177
+ for (let i = 0; i < selectors.length; i++) {
178
+ try {
179
+ const selector = selectors[i];
180
+ if (!selector) {
181
+ continue;
182
+ }
183
+ const result = await this.client.findElement(selector, {
184
+ timeout: checkInterval,
185
+ maxResults: 1,
186
+ visibleOnly: true,
187
+ });
188
+ if (!result || !Array.isArray(result.elements)) {
189
+ continue;
190
+ }
191
+ if (result.elements.length > 0) {
192
+ const element = result.elements[0];
193
+ if (element) {
194
+ return { element, selectorIndex: i };
195
+ }
196
+ }
197
+ }
198
+ catch {
199
+ // Continue to next selector
200
+ }
201
+ }
202
+ await new Promise((resolve) => setTimeout(resolve, checkInterval));
203
+ }
204
+ return null;
205
+ }
206
+ /**
207
+ * Scroll to find an element
208
+ *
209
+ * This method performs scroll actions in the specified direction
210
+ * to find an element that's not currently visible on screen.
211
+ *
212
+ * @param selector - The element selector criteria
213
+ * @param swipeCallback - Callback function to perform swipe action
214
+ * @param options - Scroll options
215
+ * @returns Promise resolving to the found UIElement or null
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * const element = await elementFinder.scrollToFindElement(
220
+ * { text: 'Target' },
221
+ * async (from, to) => await shellx.swipe({ fromX: from.x, fromY: from.y, toX: to.x, toY: to.y }),
222
+ * { maxScrolls: 5, direction: 'down' }
223
+ * );
224
+ * ```
225
+ */
226
+ async scrollToFindElement(selector, swipeCallback, options = {}) {
227
+ const { maxScrolls = 5, direction = "down", distance = 400 } = options;
228
+ // First try to find without scrolling
229
+ let element = await this.findElement(selector, { maxRetries: 1, retryDelay: 0 });
230
+ if (element)
231
+ return element;
232
+ // Get screen info for coordinates
233
+ const screenInfo = await this.client.getScreenInfo();
234
+ const centerX = (screenInfo.width || 1080) / 2;
235
+ const centerY = (screenInfo.height || 1920) / 2;
236
+ let from;
237
+ let to;
238
+ // Calculate scroll direction
239
+ switch (direction) {
240
+ case "up":
241
+ from = { x: centerX, y: centerY + distance / 2 };
242
+ to = { x: centerX, y: centerY - distance / 2 };
243
+ break;
244
+ case "down":
245
+ from = { x: centerX, y: centerY - distance / 2 };
246
+ to = { x: centerX, y: centerY + distance / 2 };
247
+ break;
248
+ case "left":
249
+ from = { x: centerX + distance / 2, y: centerY };
250
+ to = { x: centerX - distance / 2, y: centerY };
251
+ break;
252
+ case "right":
253
+ from = { x: centerX - distance / 2, y: centerY };
254
+ to = { x: centerX + distance / 2, y: centerY };
255
+ break;
256
+ }
257
+ // Try scrolling to find element
258
+ for (let i = 0; i < maxScrolls; i++) {
259
+ this.logger.info(`Scrolling to find element, attempt ${i + 1}/${maxScrolls}...`);
260
+ await swipeCallback(from, to);
261
+ element = await this.findElement(selector, { maxRetries: 1, retryDelay: 0 });
262
+ if (element) {
263
+ this.logger.info("✅ Found element after scrolling");
264
+ return element;
265
+ }
266
+ }
267
+ this.logger.info("❌ Element not found after scrolling");
268
+ return null;
269
+ }
270
+ /**
271
+ * Print information about a single element
272
+ *
273
+ * @param element - The UIElement to print
274
+ * @param index - Optional index number for display
275
+ */
276
+ printElementInfo(element, index) {
277
+ const prefix = index !== undefined ? `📋 Element ${index + 1}:` : `📋 Element Info:`;
278
+ this.logger.info(`\n${prefix}`);
279
+ this.logger.info(` - Element ID: ${element.elementId}`);
280
+ this.logger.info(` - Class Name: ${element.className}`);
281
+ this.logger.info(` - Resource ID: ${element.resourceId}`);
282
+ this.logger.info(` - Text: "${element.text}"`);
283
+ this.logger.info(` - Description: "${element.describe}"`);
284
+ this.logger.info(` - Visible: ${element.visible}`);
285
+ this.logger.info(` - Clickable: ${element.clickable}`);
286
+ this.logger.info(` - Bounds: {left: ${element.bounds.left}, top: ${element.bounds.top}, right: ${element.bounds.right}, bottom: ${element.bounds.bottom}}`);
287
+ this.logger.info(` - Size: ${element.bounds.right - element.bounds.left} x ${element.bounds.bottom - element.bounds.top}`);
288
+ }
289
+ /**
290
+ * Print summary information about multiple elements
291
+ *
292
+ * @param elements - Array of UIElements to summarize
293
+ * @param title - Optional title for the summary
294
+ */
295
+ printElementsInfo(elements, title) {
296
+ if (elements.length === 0) {
297
+ this.logger.info("❌ No elements to display");
298
+ return;
299
+ }
300
+ this.logger.info(`\n${title || `Found ${elements.length} elements`}:`);
301
+ // Statistics
302
+ const visibleCount = elements.filter((e) => e.visible).length;
303
+ const clickableCount = elements.filter((e) => e.clickable).length;
304
+ const withTextCount = elements.filter((e) => e.text && e.text.trim().length > 0).length;
305
+ this.logger.info(`\n📊 Statistics:`);
306
+ this.logger.info(` - Total elements: ${elements.length}`);
307
+ this.logger.info(` - Visible elements: ${visibleCount}`);
308
+ this.logger.info(` - Clickable elements: ${clickableCount}`);
309
+ this.logger.info(` - Elements with text: ${withTextCount}`);
310
+ // Unique text values
311
+ const uniqueTexts = [
312
+ ...new Set(elements.map((e) => e.text).filter((text) => text && text.trim().length > 0)),
313
+ ];
314
+ if (uniqueTexts.length > 0) {
315
+ this.logger.info(`\n📝 Unique text values:`);
316
+ uniqueTexts.forEach((text, index) => {
317
+ this.logger.info(` ${index + 1}. "${text}"`);
318
+ });
319
+ }
320
+ }
321
+ }
322
+ //# sourceMappingURL=element-finder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"element-finder.js","sourceRoot":"","sources":["../../src/automation/element-finder.ts"],"names":[],"mappings":"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"}