shellx-ai 1.1.2 → 1.1.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 +159 -120
- package/dist/automation/ui-action-handler.js +13 -6
- package/dist/automation/ui-action-handler.js.map +1 -1
- package/dist/cbor-compat.js +3 -0
- package/dist/cbor-compat.js.map +1 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +39 -4
- package/dist/index.js.map +1 -1
- package/dist/protocol.d.ts +1 -0
- package/dist/shellx.js +10 -5
- package/dist/shellx.js.map +1 -1
- package/dist/ui-analyzer.d.ts +90 -0
- package/dist/ui-analyzer.js +333 -0
- package/dist/ui-analyzer.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Analyzer - Extract online count and comments from UI hierarchy
|
|
3
|
+
* Direct implementation using ShellX API
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Get all UI elements from current screen
|
|
7
|
+
*/
|
|
8
|
+
export async function getAllUIElements(findElement) {
|
|
9
|
+
// Find all elements by using empty selector with multiple=true
|
|
10
|
+
const result = await findElement({ text: '' }, // Empty text to match all
|
|
11
|
+
{
|
|
12
|
+
multiple: true,
|
|
13
|
+
maxResults: 1000,
|
|
14
|
+
visibleOnly: false,
|
|
15
|
+
clickableOnly: false,
|
|
16
|
+
});
|
|
17
|
+
if (!result?.success || !result?.elements) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
return result.elements;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Extract online count from top-right corner
|
|
24
|
+
*/
|
|
25
|
+
export function extractOnlineCount(elements, screenWidth, screenHeight) {
|
|
26
|
+
// Define top-right corner area
|
|
27
|
+
const topRightThresholdX = screenWidth * 0.7; // Right 30%
|
|
28
|
+
const topRightThresholdY = screenHeight * 0.25; // Top 25%
|
|
29
|
+
// Number patterns (with optional separators)
|
|
30
|
+
const numberPatterns = [
|
|
31
|
+
/^\d+$/, // Pure numbers: "1234"
|
|
32
|
+
/^\d{1,3}(,\d{3})+$/, // Comma separated: "1,234"
|
|
33
|
+
/^\d+\.\d+[kKmM]?$/, // With decimals/suffixes: "1.2k", "1.5m"
|
|
34
|
+
/^\d+[\d,\.]*[kKmM]?$/, // Mixed: "1,234.5k"
|
|
35
|
+
];
|
|
36
|
+
const candidates = [];
|
|
37
|
+
for (const el of elements) {
|
|
38
|
+
if (!el.text || !el.visible) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const trimmedText = el.text.trim();
|
|
42
|
+
const isNumber = numberPatterns.some(pattern => pattern.test(trimmedText));
|
|
43
|
+
if (!isNumber) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const centerX = (el.bounds.left + el.bounds.right) / 2;
|
|
47
|
+
const centerY = (el.bounds.top + el.bounds.bottom) / 2;
|
|
48
|
+
// Check if in top-right corner
|
|
49
|
+
if (centerX > topRightThresholdX && centerY < topRightThresholdY) {
|
|
50
|
+
// Calculate priority (closer to top-right corner = higher priority)
|
|
51
|
+
const distanceToCorner = Math.sqrt(Math.pow(screenWidth - centerX, 2) + Math.pow(centerY, 2));
|
|
52
|
+
// Also prefer smaller text (labels vs large numbers)
|
|
53
|
+
const textSize = el.bounds.bottom - el.bounds.top;
|
|
54
|
+
candidates.push({
|
|
55
|
+
element: el,
|
|
56
|
+
centerX,
|
|
57
|
+
centerY,
|
|
58
|
+
priority: -distanceToCorner - textSize * 0.5,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (candidates.length === 0) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
// Sort by priority and get best match
|
|
66
|
+
candidates.sort((a, b) => b.priority - a.priority);
|
|
67
|
+
const best = candidates[0]?.element;
|
|
68
|
+
if (!best) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
// Parse the count
|
|
72
|
+
let count = 0;
|
|
73
|
+
const text = best.text.trim();
|
|
74
|
+
// Handle different formats
|
|
75
|
+
if (text.includes('k') || text.includes('K')) {
|
|
76
|
+
count = Math.floor(parseFloat(text.replace(/[kK,]/g, '')) * 1000);
|
|
77
|
+
}
|
|
78
|
+
else if (text.includes('m') || text.includes('M')) {
|
|
79
|
+
count = Math.floor(parseFloat(text.replace(/[mM,]/g, '')) * 1000000);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
count = parseInt(text.replace(/,/g, ''), 10);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
count: isNaN(count) ? 0 : count,
|
|
86
|
+
text,
|
|
87
|
+
bounds: {
|
|
88
|
+
left: best.bounds.left,
|
|
89
|
+
top: best.bounds.top,
|
|
90
|
+
right: best.bounds.right,
|
|
91
|
+
bottom: best.bounds.bottom,
|
|
92
|
+
},
|
|
93
|
+
confidence: candidates.length === 1 ? 'high' : 'medium',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Extract comment information from elements
|
|
98
|
+
* Looks for text elements that are likely comments based on position and content
|
|
99
|
+
*/
|
|
100
|
+
export function extractComments(elements, maxComments = 20) {
|
|
101
|
+
const comments = [];
|
|
102
|
+
const seen = new Set();
|
|
103
|
+
// Get screen bounds to identify comment sections
|
|
104
|
+
// Comments are typically in the middle/lower part of the screen
|
|
105
|
+
let minY = Infinity;
|
|
106
|
+
let maxY = -Infinity;
|
|
107
|
+
for (const el of elements) {
|
|
108
|
+
if (el.text && el.text.trim().length > 0) {
|
|
109
|
+
minY = Math.min(minY, el.bounds.top);
|
|
110
|
+
maxY = Math.max(maxY, el.bounds.bottom);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const screenHeight = maxY - minY;
|
|
114
|
+
const commentAreaTop = minY + screenHeight * 0.3; // Comments start below top 30%
|
|
115
|
+
const commentAreaBottom = maxY - screenHeight * 0.1; // Comments end before bottom 10%
|
|
116
|
+
// Filter elements that look like comments
|
|
117
|
+
for (const el of elements) {
|
|
118
|
+
if (!el.text || el.text.trim().length === 0) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const trimmedText = el.text.trim();
|
|
122
|
+
const centerY = (el.bounds.top + el.bounds.bottom) / 2;
|
|
123
|
+
// Skip if not in comment area
|
|
124
|
+
if (centerY < commentAreaTop || centerY > commentAreaBottom) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
// Skip very short texts (likely buttons/labels)
|
|
128
|
+
if (trimmedText.length < 3) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
// Skip elements that look like UI controls
|
|
132
|
+
if (el.clickable) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
// Skip common button/label patterns
|
|
136
|
+
const skipPatterns = [
|
|
137
|
+
/^(发送|取消|确定|关闭|返回|更多|展开|收起|关注|私信|分享)$/i,
|
|
138
|
+
/^(Send|Cancel|OK|Close|Back|More|Expand|Collapse|Follow|Message|Share)$/i,
|
|
139
|
+
/^\d+$/, // Pure numbers
|
|
140
|
+
/^\d{1,2}:\d{2}$/, // Time patterns like "14:15"
|
|
141
|
+
/^店铺销量/, // Shop sales info
|
|
142
|
+
/^保修期/, // Warranty info
|
|
143
|
+
/^(维度|内容|型号)$/, // Product specs
|
|
144
|
+
/^\d+年$/, // "1年", "2年" etc
|
|
145
|
+
];
|
|
146
|
+
if (skipPatterns.some(pattern => pattern.test(trimmedText))) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
// Skip single character or very short labels
|
|
150
|
+
if (trimmedText.length <= 3 && !containsChinese(trimmedText)) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
// Skip store/shop names (usually short and contain "店" or "旗舰店")
|
|
154
|
+
if (trimmedText.includes('旗舰店') || trimmedText.includes('专卖店') || trimmedText.includes('店')) {
|
|
155
|
+
// Only skip if it's short (likely a shop name, not a comment mentioning a shop)
|
|
156
|
+
if (trimmedText.length < 10) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Deduplicate by text content
|
|
161
|
+
const key = trimmedText.toLowerCase();
|
|
162
|
+
if (seen.has(key)) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
seen.add(key);
|
|
166
|
+
comments.push({
|
|
167
|
+
text: trimmedText,
|
|
168
|
+
bounds: {
|
|
169
|
+
left: el.bounds.left,
|
|
170
|
+
top: el.bounds.top,
|
|
171
|
+
right: el.bounds.right,
|
|
172
|
+
bottom: el.bounds.bottom,
|
|
173
|
+
},
|
|
174
|
+
className: el.className,
|
|
175
|
+
});
|
|
176
|
+
if (comments.length >= maxComments) {
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Sort by vertical position (top to bottom)
|
|
181
|
+
comments.sort((a, b) => a.bounds.top - b.bounds.top);
|
|
182
|
+
return comments;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Check if text contains Chinese characters
|
|
186
|
+
*/
|
|
187
|
+
function containsChinese(text) {
|
|
188
|
+
return /[一-龥]/.test(text);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Analyze screen and provide summary
|
|
192
|
+
*/
|
|
193
|
+
export function analyzeScreen(elements, screenWidth, screenHeight) {
|
|
194
|
+
const elementsByClass = {};
|
|
195
|
+
let elementsWithText = 0;
|
|
196
|
+
let clickableElements = 0;
|
|
197
|
+
for (const el of elements) {
|
|
198
|
+
// Count by class
|
|
199
|
+
elementsByClass[el.className] = (elementsByClass[el.className] || 0) + 1;
|
|
200
|
+
// Count elements with text
|
|
201
|
+
if (el.text && el.text.trim().length > 0) {
|
|
202
|
+
elementsWithText++;
|
|
203
|
+
}
|
|
204
|
+
// Count clickable elements
|
|
205
|
+
if (el.clickable) {
|
|
206
|
+
clickableElements++;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
screenWidth,
|
|
211
|
+
screenHeight,
|
|
212
|
+
totalElements: elements.length,
|
|
213
|
+
elementsWithText,
|
|
214
|
+
clickableElements,
|
|
215
|
+
elementsByClass,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Format screen analysis as readable text
|
|
220
|
+
*/
|
|
221
|
+
export function formatScreenAnalysis(analysis) {
|
|
222
|
+
const lines = [
|
|
223
|
+
'=== 屏幕分析 ===',
|
|
224
|
+
`屏幕尺寸: ${analysis.screenWidth}x${analysis.screenHeight}`,
|
|
225
|
+
`总元素数: ${analysis.totalElements}`,
|
|
226
|
+
`包含文本的元素: ${analysis.elementsWithText}`,
|
|
227
|
+
`可点击元素: ${analysis.clickableElements}`,
|
|
228
|
+
'',
|
|
229
|
+
'=== 元素类别统计 ===',
|
|
230
|
+
];
|
|
231
|
+
// Sort by count and show top 15
|
|
232
|
+
const sortedClasses = Object.entries(analysis.elementsByClass)
|
|
233
|
+
.sort((a, b) => b[1] - a[1])
|
|
234
|
+
.slice(0, 15);
|
|
235
|
+
for (const [className, count] of sortedClasses) {
|
|
236
|
+
lines.push(` ${className}: ${count}`);
|
|
237
|
+
}
|
|
238
|
+
return lines.join('\n');
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Format online count result as readable text
|
|
242
|
+
*/
|
|
243
|
+
export function formatOnlineCount(info) {
|
|
244
|
+
if (!info) {
|
|
245
|
+
return '=== 在线人数 ===\n未找到在线人数';
|
|
246
|
+
}
|
|
247
|
+
return [
|
|
248
|
+
'=== 在线人数 ===',
|
|
249
|
+
`数量: ${info.count}`,
|
|
250
|
+
`原文: "${info.text}"`,
|
|
251
|
+
`位置: [${info.bounds.left}, ${info.bounds.top} → ${info.bounds.right}, ${info.bounds.bottom}]`,
|
|
252
|
+
`置信度: ${info.confidence === 'high' ? '高' : info.confidence === 'medium' ? '中' : '低'}`,
|
|
253
|
+
].join('\n');
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Format comments as readable text
|
|
257
|
+
*/
|
|
258
|
+
export function formatComments(comments) {
|
|
259
|
+
if (comments.length === 0) {
|
|
260
|
+
return '=== 评论信息 ===\n未找到评论';
|
|
261
|
+
}
|
|
262
|
+
const lines = [
|
|
263
|
+
'=== 评论信息 ===',
|
|
264
|
+
`找到 ${comments.length} 条评论`,
|
|
265
|
+
'',
|
|
266
|
+
];
|
|
267
|
+
for (let i = 0; i < comments.length; i++) {
|
|
268
|
+
const comment = comments[i];
|
|
269
|
+
if (!comment)
|
|
270
|
+
continue;
|
|
271
|
+
lines.push(`${i + 1}. ${comment.text}`);
|
|
272
|
+
lines.push(` 位置: [${comment.bounds.left}, ${comment.bounds.top} → ${comment.bounds.right}, ${comment.bounds.bottom}]`);
|
|
273
|
+
lines.push(` 类型: ${comment.className}`);
|
|
274
|
+
lines.push('');
|
|
275
|
+
}
|
|
276
|
+
return lines.join('\n');
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Extract all meaningful text content from elements
|
|
280
|
+
* Returns all text elements that might be useful (comments, descriptions, etc.)
|
|
281
|
+
*/
|
|
282
|
+
export function extractAllTextContent(elements, maxLength = 50) {
|
|
283
|
+
const results = [];
|
|
284
|
+
for (const el of elements) {
|
|
285
|
+
if (!el.text || !el.visible) {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const trimmedText = el.text.trim();
|
|
289
|
+
// Skip very short or empty text
|
|
290
|
+
if (trimmedText.length < 2) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
// Skip single characters that are likely UI elements
|
|
294
|
+
if (trimmedText.length === 1 && !containsChinese(trimmedText)) {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
results.push({
|
|
298
|
+
text: trimmedText.length > maxLength ? trimmedText.substring(0, maxLength) + '...' : trimmedText,
|
|
299
|
+
className: el.className,
|
|
300
|
+
bounds: {
|
|
301
|
+
left: el.bounds.left,
|
|
302
|
+
top: el.bounds.top,
|
|
303
|
+
right: el.bounds.right,
|
|
304
|
+
bottom: el.bounds.bottom,
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
// Sort by vertical position
|
|
309
|
+
results.sort((a, b) => a.bounds.top - b.bounds.top);
|
|
310
|
+
return results;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Format all text content as readable text
|
|
314
|
+
*/
|
|
315
|
+
export function formatAllTextContent(contents) {
|
|
316
|
+
if (contents.length === 0) {
|
|
317
|
+
return '=== 所有文本内容 ===\n无文本内容';
|
|
318
|
+
}
|
|
319
|
+
const lines = [
|
|
320
|
+
'=== 所有文本内容 ===',
|
|
321
|
+
`共 ${contents.length} 条`,
|
|
322
|
+
'',
|
|
323
|
+
];
|
|
324
|
+
for (let i = 0; i < contents.length; i++) {
|
|
325
|
+
const item = contents[i];
|
|
326
|
+
if (!item)
|
|
327
|
+
continue;
|
|
328
|
+
lines.push(`${i + 1}. ${item.text}`);
|
|
329
|
+
lines.push(` [${item.bounds.left}, ${item.bounds.top} → ${item.bounds.right}, ${item.bounds.bottom}] ${item.className}`);
|
|
330
|
+
}
|
|
331
|
+
return lines.join('\n');
|
|
332
|
+
}
|
|
333
|
+
//# sourceMappingURL=ui-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-analyzer.js","sourceRoot":"","sources":["../src/ui-analyzer.ts"],"names":[],"mappings":"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"}
|