real-browser-mcp-server 1.3.4 → 1.4.0

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 (118) hide show
  1. package/README.md +96 -9
  2. package/dist/lib/cjs/index.d.ts +2 -0
  3. package/dist/lib/cjs/index.d.ts.map +1 -0
  4. package/dist/lib/cjs/index.js +386 -0
  5. package/dist/lib/cjs/index.js.map +1 -0
  6. package/dist/lib/cjs/module/pageController.d.ts +2 -0
  7. package/dist/lib/cjs/module/pageController.d.ts.map +1 -0
  8. package/{lib → dist/lib}/cjs/module/pageController.js +28 -29
  9. package/dist/lib/cjs/module/pageController.js.map +1 -0
  10. package/dist/lib/cjs/module/turnstile.d.ts +2 -0
  11. package/dist/lib/cjs/module/turnstile.d.ts.map +1 -0
  12. package/{lib → dist/lib}/cjs/module/turnstile.js +24 -12
  13. package/dist/lib/cjs/module/turnstile.js.map +1 -0
  14. package/dist/src/index.d.ts +11 -0
  15. package/dist/src/index.d.ts.map +1 -0
  16. package/dist/src/index.js +118 -0
  17. package/dist/src/index.js.map +1 -0
  18. package/dist/src/mcp/handlers/browser.d.ts +30 -0
  19. package/dist/src/mcp/handlers/browser.d.ts.map +1 -0
  20. package/dist/src/mcp/handlers/browser.js +232 -0
  21. package/dist/src/mcp/handlers/browser.js.map +1 -0
  22. package/dist/src/mcp/handlers/dom.d.ts +149 -0
  23. package/dist/src/mcp/handlers/dom.d.ts.map +1 -0
  24. package/dist/src/mcp/handlers/dom.js +577 -0
  25. package/dist/src/mcp/handlers/dom.js.map +1 -0
  26. package/dist/src/mcp/handlers/extract.d.ts +59 -0
  27. package/dist/src/mcp/handlers/extract.d.ts.map +1 -0
  28. package/dist/src/mcp/handlers/extract.js +455 -0
  29. package/dist/src/mcp/handlers/extract.js.map +1 -0
  30. package/dist/src/mcp/handlers/form-handlers.d.ts +9 -0
  31. package/dist/src/mcp/handlers/form-handlers.d.ts.map +1 -0
  32. package/dist/src/mcp/handlers/form-handlers.js +56 -0
  33. package/dist/src/mcp/handlers/form-handlers.js.map +1 -0
  34. package/dist/src/mcp/handlers/helpers.d.ts +47 -0
  35. package/dist/src/mcp/handlers/helpers.d.ts.map +1 -0
  36. package/dist/src/mcp/handlers/helpers.js +515 -0
  37. package/dist/src/mcp/handlers/helpers.js.map +1 -0
  38. package/dist/src/mcp/handlers/index.d.ts +6 -0
  39. package/dist/src/mcp/handlers/index.d.ts.map +1 -0
  40. package/dist/src/mcp/handlers/index.js +61 -0
  41. package/dist/src/mcp/handlers/index.js.map +1 -0
  42. package/dist/src/mcp/handlers/media-handlers.d.ts +10 -0
  43. package/dist/src/mcp/handlers/media-handlers.d.ts.map +1 -0
  44. package/dist/src/mcp/handlers/media-handlers.js +535 -0
  45. package/dist/src/mcp/handlers/media-handlers.js.map +1 -0
  46. package/dist/src/mcp/handlers/network.d.ts +147 -0
  47. package/dist/src/mcp/handlers/network.d.ts.map +1 -0
  48. package/dist/src/mcp/handlers/network.js +1135 -0
  49. package/dist/src/mcp/handlers/network.js.map +1 -0
  50. package/dist/src/mcp/handlers/state.d.ts +34 -0
  51. package/dist/src/mcp/handlers/state.d.ts.map +1 -0
  52. package/dist/src/mcp/handlers/state.js +226 -0
  53. package/dist/src/mcp/handlers/state.js.map +1 -0
  54. package/dist/src/mcp/handlers/utility-handlers.d.ts +167 -0
  55. package/dist/src/mcp/handlers/utility-handlers.d.ts.map +1 -0
  56. package/dist/src/mcp/handlers/utility-handlers.js +280 -0
  57. package/dist/src/mcp/handlers/utility-handlers.js.map +1 -0
  58. package/dist/src/mcp/handlers/vision.d.ts +127 -0
  59. package/dist/src/mcp/handlers/vision.d.ts.map +1 -0
  60. package/dist/src/mcp/handlers/vision.js +549 -0
  61. package/dist/src/mcp/handlers/vision.js.map +1 -0
  62. package/dist/src/mcp/index.d.ts +3 -0
  63. package/dist/src/mcp/index.d.ts.map +1 -0
  64. package/dist/src/mcp/index.js +166 -0
  65. package/dist/src/mcp/index.js.map +1 -0
  66. package/dist/src/mcp/server.d.ts +2 -0
  67. package/dist/src/mcp/server.d.ts.map +1 -0
  68. package/dist/src/mcp/server.js +117 -0
  69. package/dist/src/mcp/server.js.map +1 -0
  70. package/dist/src/mcp/tools.d.ts +8 -0
  71. package/dist/src/mcp/tools.d.ts.map +1 -0
  72. package/{src → dist/src}/mcp/tools.js +12 -11
  73. package/dist/src/mcp/tools.js.map +1 -0
  74. package/dist/src/shared/cache-manager.d.ts +80 -0
  75. package/dist/src/shared/cache-manager.d.ts.map +1 -0
  76. package/dist/src/shared/cache-manager.js +221 -0
  77. package/dist/src/shared/cache-manager.js.map +1 -0
  78. package/dist/src/shared/tools.d.ts +2 -0
  79. package/dist/src/shared/tools.d.ts.map +1 -0
  80. package/dist/src/shared/tools.js +606 -0
  81. package/dist/src/shared/tools.js.map +1 -0
  82. package/dist/src/types.d.ts +376 -0
  83. package/dist/src/types.d.ts.map +1 -0
  84. package/dist/src/types.js +9 -0
  85. package/dist/src/types.js.map +1 -0
  86. package/dist/test/cjs/test.d.ts +11 -0
  87. package/dist/test/cjs/test.d.ts.map +1 -0
  88. package/dist/test/cjs/test.js +289 -0
  89. package/dist/test/cjs/test.js.map +1 -0
  90. package/dist/test/mcp/smoke-test.d.ts +29 -0
  91. package/dist/test/mcp/smoke-test.d.ts.map +1 -0
  92. package/dist/test/mcp/smoke-test.js +132 -0
  93. package/dist/test/mcp/smoke-test.js.map +1 -0
  94. package/lib/esm/index.mjs +229 -184
  95. package/lib/esm/module/pageController.mjs +21 -18
  96. package/lib/esm/module/turnstile.mjs +7 -0
  97. package/package.json +25 -16
  98. package/typings.d.ts +7 -1
  99. package/.github/ISSUE_TEMPLATE/general_issue.yaml +0 -58
  100. package/.github/SETUP.md +0 -111
  101. package/.github/workflows/publish.yml +0 -135
  102. package/Dockerfile +0 -79
  103. package/lib/cjs/adblocker.bin +0 -0
  104. package/lib/cjs/index.js +0 -352
  105. package/src/ai/action-parser.js +0 -274
  106. package/src/ai/core.js +0 -378
  107. package/src/ai/element-finder.js +0 -466
  108. package/src/ai/index.js +0 -82
  109. package/src/ai/page-analyzer.js +0 -304
  110. package/src/ai/selector-healer.js +0 -236
  111. package/src/index.js +0 -121
  112. package/src/mcp/handlers.js +0 -5071
  113. package/src/mcp/index.js +0 -190
  114. package/src/mcp/server.js +0 -144
  115. package/src/shared/tools.js +0 -618
  116. package/test/cjs/test.js +0 -267
  117. package/test/esm/package.json +0 -13
  118. package/test/esm/test.js +0 -235
@@ -1,466 +0,0 @@
1
- /**
2
- * AI Element Finder - Smart element finding with multiple strategies
3
- *
4
- * Strategies:
5
- * - text: Find by visible text content
6
- * - aria: Find by accessibility attributes (aria-label, role, etc.)
7
- * - visual: Find by position, size, color context
8
- * - semantic: Find by HTML structure and semantic meaning
9
- * - auto: Try all strategies and return best matches
10
- */
11
-
12
- class ElementFinder {
13
- constructor() {
14
- // Common element patterns for different types
15
- this.patterns = {
16
- button: {
17
- tags: ['button', 'input[type="button"]', 'input[type="submit"]', 'a.btn', '[role="button"]'],
18
- keywords: ['click', 'submit', 'button', 'btn', 'press']
19
- },
20
- input: {
21
- tags: ['input', 'textarea', '[contenteditable="true"]'],
22
- keywords: ['input', 'field', 'textbox', 'enter', 'type', 'write']
23
- },
24
- link: {
25
- tags: ['a[href]', '[role="link"]'],
26
- keywords: ['link', 'go to', 'navigate', 'open']
27
- },
28
- search: {
29
- tags: ['input[type="search"]', 'input[name*="search"]', 'input[placeholder*="search"]', '[role="searchbox"]'],
30
- keywords: ['search', 'find', 'lookup', 'query']
31
- },
32
- login: {
33
- tags: ['input[type="password"]', 'input[name*="password"]', 'input[name*="login"]', 'input[name*="user"]'],
34
- keywords: ['login', 'password', 'username', 'email', 'signin', 'sign in']
35
- },
36
- form: {
37
- tags: ['form', '[role="form"]'],
38
- keywords: ['form', 'submit']
39
- },
40
- menu: {
41
- tags: ['nav', '[role="navigation"]', '[role="menu"]', 'ul.menu', '.nav'],
42
- keywords: ['menu', 'navigation', 'nav']
43
- },
44
- image: {
45
- tags: ['img', 'picture', '[role="img"]', 'svg'],
46
- keywords: ['image', 'picture', 'photo', 'icon', 'logo']
47
- },
48
- video: {
49
- tags: ['video', 'iframe[src*="youtube"]', 'iframe[src*="vimeo"]', '[role="video"]'],
50
- keywords: ['video', 'player', 'watch']
51
- }
52
- };
53
-
54
- // Common action keywords
55
- this.actionKeywords = {
56
- click: ['click', 'press', 'tap', 'hit', 'select', 'choose'],
57
- type: ['type', 'enter', 'write', 'input', 'fill'],
58
- scroll: ['scroll', 'move', 'go down', 'go up'],
59
- hover: ['hover', 'mouse over', 'point'],
60
- wait: ['wait', 'pause', 'delay']
61
- };
62
- }
63
-
64
- /**
65
- * Find elements matching the query
66
- */
67
- async find(page, query, options = {}) {
68
- const {
69
- strategy = 'auto',
70
- context = null,
71
- confidence = 0.7,
72
- returnMultiple = false
73
- } = options;
74
-
75
- let results = [];
76
-
77
- // Parse query to understand what user is looking for
78
- const parsedQuery = this.parseQuery(query);
79
-
80
- // Apply different strategies
81
- if (strategy === 'auto' || strategy === 'text') {
82
- const textResults = await this.findByText(page, parsedQuery, context);
83
- results = [...results, ...textResults];
84
- }
85
-
86
- if (strategy === 'auto' || strategy === 'aria') {
87
- const ariaResults = await this.findByAria(page, parsedQuery, context);
88
- results = [...results, ...ariaResults];
89
- }
90
-
91
- if (strategy === 'auto' || strategy === 'semantic') {
92
- const semanticResults = await this.findBySemantic(page, parsedQuery, context);
93
- results = [...results, ...semanticResults];
94
- }
95
-
96
- if (strategy === 'auto' || strategy === 'visual') {
97
- const visualResults = await this.findByVisual(page, parsedQuery, context);
98
- results = [...results, ...visualResults];
99
- }
100
-
101
- // Deduplicate and sort by confidence
102
- results = this.deduplicateResults(results);
103
- results.sort((a, b) => b.confidence - a.confidence);
104
-
105
- // Filter by confidence threshold
106
- results = results.filter(r => r.confidence >= confidence);
107
-
108
- return returnMultiple ? results : results.slice(0, 1);
109
- }
110
-
111
- /**
112
- * Parse natural language query
113
- */
114
- parseQuery(query) {
115
- const lowerQuery = query.toLowerCase();
116
-
117
- // Detect element type
118
- let elementType = 'any';
119
- for (const [type, pattern] of Object.entries(this.patterns)) {
120
- if (pattern.keywords.some(kw => lowerQuery.includes(kw))) {
121
- elementType = type;
122
- break;
123
- }
124
- }
125
-
126
- // Extract key terms
127
- const terms = query.split(/\s+/).filter(t => t.length > 2);
128
-
129
- // Detect if looking for specific text
130
- const textMatch = query.match(/["']([^"']+)["']|containing\s+(.+)|with text\s+(.+)|labeled\s+(.+)/i);
131
- const targetText = textMatch ? (textMatch[1] || textMatch[2] || textMatch[3] || textMatch[4]) : null;
132
-
133
- // Detect color mentions
134
- const colorMatch = query.match(/\b(red|blue|green|yellow|orange|purple|black|white|gray|grey)\b/i);
135
- const color = colorMatch ? colorMatch[1].toLowerCase() : null;
136
-
137
- // Detect position mentions
138
- const positionMatch = query.match(/\b(top|bottom|left|right|center|first|last|header|footer)\b/i);
139
- const position = positionMatch ? positionMatch[1].toLowerCase() : null;
140
-
141
- return {
142
- original: query,
143
- elementType,
144
- terms,
145
- targetText,
146
- color,
147
- position
148
- };
149
- }
150
-
151
- /**
152
- * Find by text content
153
- */
154
- async findByText(page, parsedQuery, context) {
155
- const contextSelector = context || 'body';
156
-
157
- return await page.evaluate(({ parsedQuery, contextSelector }) => {
158
- const results = [];
159
- const container = document.querySelector(contextSelector) || document.body;
160
-
161
- // Get all interactive and text-containing elements
162
- const elements = container.querySelectorAll('button, a, input, label, span, div, p, h1, h2, h3, h4, h5, h6, [role]');
163
-
164
- for (const el of elements) {
165
- const text = el.textContent?.trim().toLowerCase() || '';
166
- const placeholder = el.placeholder?.toLowerCase() || '';
167
- const value = el.value?.toLowerCase() || '';
168
- const ariaLabel = el.getAttribute('aria-label')?.toLowerCase() || '';
169
-
170
- let confidence = 0;
171
- const matchedTerms = [];
172
-
173
- // Check each search term
174
- for (const term of parsedQuery.terms) {
175
- const lowerTerm = term.toLowerCase();
176
-
177
- if (text.includes(lowerTerm)) {
178
- confidence += 0.3;
179
- matchedTerms.push({ term, in: 'text' });
180
- }
181
- if (placeholder.includes(lowerTerm)) {
182
- confidence += 0.25;
183
- matchedTerms.push({ term, in: 'placeholder' });
184
- }
185
- if (ariaLabel.includes(lowerTerm)) {
186
- confidence += 0.25;
187
- matchedTerms.push({ term, in: 'aria-label' });
188
- }
189
- }
190
-
191
- // Exact text match bonus
192
- if (parsedQuery.targetText && text.includes(parsedQuery.targetText.toLowerCase())) {
193
- confidence += 0.4;
194
- }
195
-
196
- // Visibility bonus
197
- const rect = el.getBoundingClientRect();
198
- if (rect.width > 0 && rect.height > 0) {
199
- confidence += 0.1;
200
- }
201
-
202
- if (confidence > 0) {
203
- // Generate selector
204
- let selector = '';
205
- if (el.id) {
206
- selector = `#${el.id}`;
207
- } else if (el.className && typeof el.className === 'string') {
208
- const classes = el.className.split(' ').filter(c => c).slice(0, 2).join('.');
209
- selector = `${el.tagName.toLowerCase()}.${classes}`;
210
- } else {
211
- selector = el.tagName.toLowerCase();
212
- if (el.getAttribute('type')) {
213
- selector += `[type="${el.getAttribute('type')}"]`;
214
- }
215
- }
216
-
217
- results.push({
218
- selector,
219
- confidence: Math.min(confidence, 1),
220
- text: text.substring(0, 100),
221
- strategy: 'text',
222
- matchedTerms,
223
- tag: el.tagName.toLowerCase(),
224
- visible: rect.width > 0 && rect.height > 0
225
- });
226
- }
227
- }
228
-
229
- return results;
230
- }, { parsedQuery, contextSelector });
231
- }
232
-
233
- /**
234
- * Find by ARIA attributes
235
- */
236
- async findByAria(page, parsedQuery, context) {
237
- const contextSelector = context || 'body';
238
-
239
- return await page.evaluate(({ parsedQuery, contextSelector }) => {
240
- const results = [];
241
- const container = document.querySelector(contextSelector) || document.body;
242
-
243
- // Find elements with ARIA attributes
244
- const ariaElements = container.querySelectorAll('[aria-label], [aria-describedby], [role], [aria-placeholder]');
245
-
246
- for (const el of ariaElements) {
247
- const ariaLabel = el.getAttribute('aria-label')?.toLowerCase() || '';
248
- const role = el.getAttribute('role')?.toLowerCase() || '';
249
- const ariaPlaceholder = el.getAttribute('aria-placeholder')?.toLowerCase() || '';
250
-
251
- let confidence = 0;
252
-
253
- for (const term of parsedQuery.terms) {
254
- const lowerTerm = term.toLowerCase();
255
-
256
- if (ariaLabel.includes(lowerTerm)) {
257
- confidence += 0.35;
258
- }
259
- if (role.includes(lowerTerm)) {
260
- confidence += 0.2;
261
- }
262
- if (ariaPlaceholder.includes(lowerTerm)) {
263
- confidence += 0.25;
264
- }
265
- }
266
-
267
- // Role matching for element type
268
- if (parsedQuery.elementType !== 'any') {
269
- if (role === parsedQuery.elementType ||
270
- role === 'button' && parsedQuery.elementType === 'button') {
271
- confidence += 0.2;
272
- }
273
- }
274
-
275
- if (confidence > 0) {
276
- let selector = '';
277
- if (el.getAttribute('aria-label')) {
278
- selector = `[aria-label="${el.getAttribute('aria-label')}"]`;
279
- } else if (el.id) {
280
- selector = `#${el.id}`;
281
- } else {
282
- selector = `[role="${role}"]`;
283
- }
284
-
285
- const rect = el.getBoundingClientRect();
286
-
287
- results.push({
288
- selector,
289
- confidence: Math.min(confidence, 1),
290
- ariaLabel,
291
- role,
292
- strategy: 'aria',
293
- tag: el.tagName.toLowerCase(),
294
- visible: rect.width > 0 && rect.height > 0
295
- });
296
- }
297
- }
298
-
299
- return results;
300
- }, { parsedQuery, contextSelector });
301
- }
302
-
303
- /**
304
- * Find by semantic HTML structure
305
- */
306
- async findBySemantic(page, parsedQuery, context) {
307
- const contextSelector = context || 'body';
308
- const patterns = this.patterns;
309
-
310
- return await page.evaluate(({ parsedQuery, contextSelector, patterns }) => {
311
- const results = [];
312
- const container = document.querySelector(contextSelector) || document.body;
313
-
314
- // Get pattern for element type
315
- const pattern = patterns[parsedQuery.elementType];
316
-
317
- if (pattern) {
318
- for (const tagSelector of pattern.tags) {
319
- const elements = container.querySelectorAll(tagSelector);
320
-
321
- for (const el of elements) {
322
- const rect = el.getBoundingClientRect();
323
- if (rect.width === 0 || rect.height === 0) continue;
324
-
325
- let confidence = 0.5; // Base confidence for matching pattern
326
-
327
- // Check text content matches
328
- const text = el.textContent?.toLowerCase() || '';
329
- for (const term of parsedQuery.terms) {
330
- if (text.includes(term.toLowerCase())) {
331
- confidence += 0.2;
332
- }
333
- }
334
-
335
- // Generate unique selector
336
- let selector = '';
337
- if (el.id) {
338
- selector = `#${el.id}`;
339
- confidence += 0.1;
340
- } else if (el.name) {
341
- selector = `[name="${el.name}"]`;
342
- confidence += 0.1;
343
- } else {
344
- selector = tagSelector;
345
- }
346
-
347
- results.push({
348
- selector,
349
- confidence: Math.min(confidence, 1),
350
- text: text.substring(0, 50),
351
- strategy: 'semantic',
352
- elementType: parsedQuery.elementType,
353
- tag: el.tagName.toLowerCase(),
354
- visible: true
355
- });
356
- }
357
- }
358
- }
359
-
360
- return results;
361
- }, { parsedQuery, contextSelector, patterns });
362
- }
363
-
364
- /**
365
- * Find by visual properties (position, approximate area)
366
- */
367
- async findByVisual(page, parsedQuery, context) {
368
- const contextSelector = context || 'body';
369
-
370
- return await page.evaluate(({ parsedQuery, contextSelector }) => {
371
- const results = [];
372
- const container = document.querySelector(contextSelector) || document.body;
373
-
374
- // Get viewport dimensions
375
- const viewportHeight = window.innerHeight;
376
- const viewportWidth = window.innerWidth;
377
-
378
- const elements = container.querySelectorAll('button, a, input, [role="button"], [role="link"]');
379
-
380
- for (const el of elements) {
381
- const rect = el.getBoundingClientRect();
382
- if (rect.width === 0 || rect.height === 0) continue;
383
-
384
- let confidence = 0.3; // Base confidence
385
-
386
- // Position matching
387
- if (parsedQuery.position) {
388
- const pos = parsedQuery.position;
389
-
390
- if (pos === 'top' && rect.top < viewportHeight * 0.3) {
391
- confidence += 0.3;
392
- } else if (pos === 'bottom' && rect.bottom > viewportHeight * 0.7) {
393
- confidence += 0.3;
394
- } else if (pos === 'left' && rect.left < viewportWidth * 0.3) {
395
- confidence += 0.3;
396
- } else if (pos === 'right' && rect.right > viewportWidth * 0.7) {
397
- confidence += 0.3;
398
- } else if (pos === 'center' &&
399
- rect.left > viewportWidth * 0.3 &&
400
- rect.right < viewportWidth * 0.7) {
401
- confidence += 0.3;
402
- } else if (pos === 'header' && rect.top < 100) {
403
- confidence += 0.3;
404
- } else if (pos === 'footer' && rect.bottom > viewportHeight - 100) {
405
- confidence += 0.3;
406
- }
407
- }
408
-
409
- // Check text content
410
- const text = el.textContent?.toLowerCase() || '';
411
- for (const term of parsedQuery.terms) {
412
- if (text.includes(term.toLowerCase())) {
413
- confidence += 0.2;
414
- }
415
- }
416
-
417
- if (confidence > 0.3) {
418
- let selector = '';
419
- if (el.id) {
420
- selector = `#${el.id}`;
421
- } else {
422
- selector = el.tagName.toLowerCase();
423
- if (el.className && typeof el.className === 'string') {
424
- selector += '.' + el.className.split(' ')[0];
425
- }
426
- }
427
-
428
- results.push({
429
- selector,
430
- confidence: Math.min(confidence, 1),
431
- text: text.substring(0, 50),
432
- strategy: 'visual',
433
- position: {
434
- top: Math.round(rect.top),
435
- left: Math.round(rect.left),
436
- width: Math.round(rect.width),
437
- height: Math.round(rect.height)
438
- },
439
- tag: el.tagName.toLowerCase(),
440
- visible: true
441
- });
442
- }
443
- }
444
-
445
- return results;
446
- }, { parsedQuery, contextSelector });
447
- }
448
-
449
- /**
450
- * Deduplicate results based on selector
451
- */
452
- deduplicateResults(results) {
453
- const seen = new Map();
454
-
455
- for (const result of results) {
456
- const existing = seen.get(result.selector);
457
- if (!existing || existing.confidence < result.confidence) {
458
- seen.set(result.selector, result);
459
- }
460
- }
461
-
462
- return Array.from(seen.values());
463
- }
464
- }
465
-
466
- module.exports = ElementFinder;
package/src/ai/index.js DELETED
@@ -1,82 +0,0 @@
1
- /**
2
- * AI Module - Main Entry Point
3
- *
4
- * This module provides AI-powered features that automatically enhance
5
- * ALL tools in the browser automation project.
6
- *
7
- * Features:
8
- * 1. Smart Element Finding - Find elements using natural language
9
- * 2. Selector Auto-Healing - Automatically fix broken selectors
10
- * 3. Page Understanding - Analyze and understand page structure
11
- * 4. Natural Language Commands - Execute actions from text commands
12
- *
13
- * Usage:
14
- * ```javascript
15
- * const { aiCore, smartFind, smartClick, executeCommand } = require('./ai');
16
- *
17
- * // Smart find
18
- * const elements = await smartFind(page, 'login button');
19
- *
20
- * // Smart click with auto-healing
21
- * await smartClick(page, '#old-selector');
22
- *
23
- * // Execute natural language command
24
- * await executeCommand(page, 'click the submit button');
25
- * ```
26
- *
27
- * Integration with existing tools:
28
- * All existing handlers can be wrapped with AI capabilities using:
29
- * ```javascript
30
- * const enhancedHandler = wrapHandler(originalHandler, 'handlerName');
31
- * ```
32
- */
33
-
34
- const {
35
- AICore,
36
- aiCore,
37
- smartFind,
38
- smartClick,
39
- smartType,
40
- understandPage,
41
- executeCommand,
42
- wrapHandler,
43
- configure
44
- } = require('./core');
45
-
46
- const ElementFinder = require('./element-finder');
47
- const SelectorHealer = require('./selector-healer');
48
- const PageAnalyzer = require('./page-analyzer');
49
- const ActionParser = require('./action-parser');
50
-
51
- // Export everything
52
- module.exports = {
53
- // Main AI Core
54
- AICore,
55
- aiCore,
56
-
57
- // Quick access functions
58
- smartFind,
59
- smartClick,
60
- smartType,
61
- understandPage,
62
- executeCommand,
63
- wrapHandler,
64
- configure,
65
-
66
- // Individual modules (for advanced usage)
67
- ElementFinder,
68
- SelectorHealer,
69
- PageAnalyzer,
70
- ActionParser,
71
-
72
- // Version info
73
- version: '1.0.0',
74
-
75
- // Feature flags
76
- features: {
77
- smartFind: true,
78
- autoHealing: true,
79
- pageAnalysis: true,
80
- naturalLanguage: true
81
- }
82
- };