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
package/src/ai/core.js DELETED
@@ -1,378 +0,0 @@
1
- /**
2
- * AI Core Module - Foundation for all AI-powered features
3
- *
4
- * This module provides AI capabilities that are automatically available
5
- * to ALL tools in the project. Any new tool added will automatically
6
- * benefit from these AI features.
7
- *
8
- * Features:
9
- * - Smart element finding with multiple strategies
10
- * - Auto-healing selectors when they break
11
- * - Page understanding and structure analysis
12
- * - Natural language command parsing
13
- * - Confidence scoring for element matches
14
- * - Fallback strategies when primary method fails
15
- */
16
-
17
- const ElementFinder = require('./element-finder');
18
- const SelectorHealer = require('./selector-healer');
19
- const PageAnalyzer = require('./page-analyzer');
20
- const ActionParser = require('./action-parser');
21
-
22
- /**
23
- * AI Core class - Central AI intelligence for the browser automation
24
- */
25
- class AICore {
26
- constructor() {
27
- this.elementFinder = new ElementFinder();
28
- this.selectorHealer = new SelectorHealer();
29
- this.pageAnalyzer = new PageAnalyzer();
30
- this.actionParser = new ActionParser();
31
-
32
- // Cache for performance
33
- this.pageCache = new Map();
34
- this.selectorCache = new Map();
35
-
36
- // Configuration
37
- this.config = {
38
- defaultConfidence: 0.7,
39
- maxCacheAge: 30000, // 30 seconds
40
- enableAutoHeal: true,
41
- enableSmartFind: true,
42
- logLevel: 'info' // 'debug' | 'info' | 'warn' | 'error'
43
- };
44
- }
45
-
46
- /**
47
- * Configure AI Core settings
48
- */
49
- configure(options = {}) {
50
- this.config = { ...this.config, ...options };
51
- return this;
52
- }
53
-
54
- /**
55
- * AI-Enhanced element finding
56
- * Tries multiple strategies to find an element
57
- */
58
- async smartFind(page, query, options = {}) {
59
- const {
60
- strategy = 'auto',
61
- context = null,
62
- confidence = this.config.defaultConfidence,
63
- returnMultiple = false
64
- } = options;
65
-
66
- this.log('debug', `SmartFind: "${query}" with strategy: ${strategy}`);
67
-
68
- const results = await this.elementFinder.find(page, query, {
69
- strategy,
70
- context,
71
- confidence,
72
- returnMultiple
73
- });
74
-
75
- this.log('info', `SmartFind found ${results.length} elements with confidence >= ${confidence}`);
76
-
77
- return results;
78
- }
79
-
80
- /**
81
- * AI-Enhanced click with auto-healing
82
- * If selector fails, tries to find the element using AI
83
- */
84
- async smartClick(page, selector, options = {}) {
85
- const { humanLike = true, autoHeal = this.config.enableAutoHeal } = options;
86
-
87
- try {
88
- // Try original selector first
89
- const element = await page.$(selector);
90
- if (element) {
91
- if (humanLike) {
92
- try {
93
- const { createCursor } = require('ghost-cursor-patchright');
94
- const cursor = createCursor(page);
95
- await cursor.click(selector);
96
- } catch {
97
- await element.click();
98
- }
99
- } else {
100
- await element.click();
101
- }
102
- return { success: true, selector, healed: false };
103
- }
104
- } catch (e) {
105
- this.log('warn', `Original selector failed: ${selector}`);
106
- }
107
-
108
- // Auto-heal if enabled
109
- if (autoHeal) {
110
- this.log('info', `Attempting to heal selector: ${selector}`);
111
- const healed = await this.healAndExecute(page, selector, 'click', options);
112
- if (healed.success) {
113
- return { ...healed, healed: true };
114
- }
115
- }
116
-
117
- return { success: false, error: `Element not found: ${selector}` };
118
- }
119
-
120
- /**
121
- * AI-Enhanced type with auto-healing
122
- */
123
- async smartType(page, selector, text, options = {}) {
124
- const { delay = 50, clear = false, autoHeal = this.config.enableAutoHeal } = options;
125
-
126
- try {
127
- const element = await page.$(selector);
128
- if (element) {
129
- if (clear) {
130
- await element.click({ clickCount: 3 });
131
- await page.keyboard.press('Backspace');
132
- }
133
- await element.type(text, { delay });
134
- return { success: true, selector, healed: false };
135
- }
136
- } catch (e) {
137
- this.log('warn', `Original selector failed: ${selector}`);
138
- }
139
-
140
- if (autoHeal) {
141
- const healed = await this.healAndExecute(page, selector, 'type', { text, ...options });
142
- if (healed.success) {
143
- return { ...healed, healed: true };
144
- }
145
- }
146
-
147
- return { success: false, error: `Element not found: ${selector}` };
148
- }
149
-
150
- /**
151
- * Heal a broken selector and execute action
152
- */
153
- async healAndExecute(page, brokenSelector, action, options = {}) {
154
- const alternatives = await this.selectorHealer.heal(page, brokenSelector, {
155
- maxAlternatives: 5
156
- });
157
-
158
- for (const alt of alternatives) {
159
- try {
160
- const element = await page.$(alt.selector);
161
- if (element) {
162
- this.log('info', `Healed selector: ${brokenSelector} -> ${alt.selector} (confidence: ${alt.confidence})`);
163
-
164
- // Cache the healed selector
165
- this.selectorCache.set(brokenSelector, {
166
- healed: alt.selector,
167
- timestamp: Date.now()
168
- });
169
-
170
- // Execute action
171
- if (action === 'click') {
172
- await element.click();
173
- } else if (action === 'type') {
174
- if (options.clear) {
175
- await element.click({ clickCount: 3 });
176
- await page.keyboard.press('Backspace');
177
- }
178
- await element.type(options.text, { delay: options.delay || 50 });
179
- }
180
-
181
- return { success: true, selector: alt.selector, originalSelector: brokenSelector };
182
- }
183
- } catch (e) {
184
- continue;
185
- }
186
- }
187
-
188
- return { success: false, error: 'Could not heal selector' };
189
- }
190
-
191
- /**
192
- * Understand page structure
193
- */
194
- async understandPage(page, options = {}) {
195
- const cacheKey = page.url();
196
- const cached = this.pageCache.get(cacheKey);
197
-
198
- if (cached && (Date.now() - cached.timestamp) < this.config.maxCacheAge) {
199
- this.log('debug', 'Using cached page analysis');
200
- return cached.analysis;
201
- }
202
-
203
- const analysis = await this.pageAnalyzer.analyze(page, options);
204
-
205
- this.pageCache.set(cacheKey, {
206
- analysis,
207
- timestamp: Date.now()
208
- });
209
-
210
- return analysis;
211
- }
212
-
213
- /**
214
- * Parse natural language command and execute
215
- */
216
- async executeCommand(page, command, options = {}) {
217
- const { context = {}, dryRun = false, humanLike = true } = options;
218
-
219
- this.log('info', `Parsing command: "${command}"`);
220
-
221
- const parsed = await this.actionParser.parse(command, context);
222
-
223
- if (dryRun) {
224
- return { success: true, dryRun: true, parsed };
225
- }
226
-
227
- // Execute parsed action
228
- return await this.executeAction(page, parsed, { humanLike });
229
- }
230
-
231
- /**
232
- * Execute a parsed action
233
- */
234
- async executeAction(page, action, options = {}) {
235
- const { humanLike = true } = options;
236
-
237
- switch (action.type) {
238
- case 'click':
239
- return await this.smartClick(page, action.target, { humanLike });
240
-
241
- case 'type':
242
- return await this.smartType(page, action.target, action.text, { humanLike });
243
-
244
- case 'navigate':
245
- await page.goto(action.url, { waitUntil: 'networkidle2' });
246
- return { success: true, url: action.url };
247
-
248
- case 'scroll':
249
- await page.evaluate((direction, amount) => {
250
- window.scrollBy({ top: direction === 'up' ? -amount : amount, behavior: 'smooth' });
251
- }, action.direction || 'down', action.amount || 300);
252
- return { success: true, direction: action.direction };
253
-
254
- case 'wait':
255
- await new Promise(r => setTimeout(r, action.duration || 1000));
256
- return { success: true, waited: action.duration };
257
-
258
- case 'find':
259
- const results = await this.smartFind(page, action.query);
260
- return { success: true, found: results.length, elements: results };
261
-
262
- default:
263
- return { success: false, error: `Unknown action type: ${action.type}` };
264
- }
265
- }
266
-
267
- /**
268
- * Wrap any handler with AI capabilities
269
- * This allows existing handlers to benefit from AI features
270
- */
271
- wrapHandler(handler, handlerName) {
272
- const aiCore = this;
273
-
274
- return async function aiEnhancedHandler(params = {}) {
275
- const startTime = Date.now();
276
-
277
- // Check if AI features are requested
278
- const useAI = params._useAI !== false;
279
- const autoHeal = params._autoHeal !== false && aiCore.config.enableAutoHeal;
280
-
281
- try {
282
- // Execute original handler
283
- const result = await handler(params);
284
-
285
- // If success, return result
286
- if (result.success) {
287
- return {
288
- ...result,
289
- _ai: { used: false, duration: Date.now() - startTime }
290
- };
291
- }
292
-
293
- // If failed and autoHeal is enabled, try AI recovery
294
- if (autoHeal && result.error?.includes('not found')) {
295
- aiCore.log('info', `AI attempting recovery for ${handlerName}`);
296
-
297
- // Extract selector from params
298
- const selector = params.selector || params.target;
299
- if (selector) {
300
- const healed = await aiCore.selectorHealer.heal(
301
- params._page,
302
- selector,
303
- { maxAlternatives: 3 }
304
- );
305
-
306
- if (healed.length > 0) {
307
- // Retry with healed selector
308
- const retryParams = { ...params, selector: healed[0].selector };
309
- const retryResult = await handler(retryParams);
310
-
311
- return {
312
- ...retryResult,
313
- _ai: {
314
- used: true,
315
- healed: true,
316
- originalSelector: selector,
317
- healedSelector: healed[0].selector,
318
- duration: Date.now() - startTime
319
- }
320
- };
321
- }
322
- }
323
- }
324
-
325
- return {
326
- ...result,
327
- _ai: { used: useAI, duration: Date.now() - startTime }
328
- };
329
-
330
- } catch (error) {
331
- aiCore.log('error', `Handler ${handlerName} failed: ${error.message}`);
332
- return {
333
- success: false,
334
- error: error.message,
335
- _ai: { used: useAI, duration: Date.now() - startTime }
336
- };
337
- }
338
- };
339
- }
340
-
341
- /**
342
- * Clear caches
343
- */
344
- clearCache() {
345
- this.pageCache.clear();
346
- this.selectorCache.clear();
347
- this.log('info', 'AI caches cleared');
348
- }
349
-
350
- /**
351
- * Logging utility
352
- */
353
- log(level, message) {
354
- const levels = ['debug', 'info', 'warn', 'error'];
355
- const configLevel = levels.indexOf(this.config.logLevel);
356
- const msgLevel = levels.indexOf(level);
357
-
358
- if (msgLevel >= configLevel) {
359
- const emoji = { debug: '🔍', info: '🤖', warn: '⚠️', error: '❌' }[level];
360
- console.error(`${emoji} [AI] ${message}`);
361
- }
362
- }
363
- }
364
-
365
- // Singleton instance
366
- const aiCore = new AICore();
367
-
368
- module.exports = {
369
- AICore,
370
- aiCore,
371
- smartFind: (page, query, options) => aiCore.smartFind(page, query, options),
372
- smartClick: (page, selector, options) => aiCore.smartClick(page, selector, options),
373
- smartType: (page, selector, text, options) => aiCore.smartType(page, selector, text, options),
374
- understandPage: (page, options) => aiCore.understandPage(page, options),
375
- executeCommand: (page, command, options) => aiCore.executeCommand(page, command, options),
376
- wrapHandler: (handler, name) => aiCore.wrapHandler(handler, name),
377
- configure: (options) => aiCore.configure(options)
378
- };