brave-real-browser-mcp-server 2.41.11 → 2.41.13
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/eng.traineddata +0 -0
- package/package.json +2 -2
- package/packages/brave-real-blocker/package.json +2 -2
- package/packages/brave-real-launcher/package.json +2 -2
- package/packages/brave-real-playwright-core/package.json +1 -1
- package/packages/brave-real-puppeteer-core/package.json +4 -4
- package/src/lsp/capabilities/diagnostics.js +55 -55
- package/src/lsp/languages/en.js +2 -3
- package/src/lsp/languages/hi.js +2 -3
- package/src/mcp/handlers.js +509 -83
- package/src/shared/tools.js +26 -40
package/eng.traineddata
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-browser-mcp-server",
|
|
3
|
-
"version": "2.41.
|
|
3
|
+
"version": "2.41.13",
|
|
4
4
|
"description": "MCP Server for Brave Real Browser - Puppeteer with Brave Browser, Stealth Mode, Ad Blocker, and Turnstile Auto-Solver for undetectable web automation.",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/esm/index.mjs",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"license": "ISC",
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
77
|
-
"brave-real-puppeteer-core": "^24.37.1-brave.
|
|
77
|
+
"brave-real-puppeteer-core": "^24.37.1-brave.12",
|
|
78
78
|
"ghost-cursor": "^1.4.2",
|
|
79
79
|
"puppeteer-extra": "^3.3.6",
|
|
80
80
|
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-blocker",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.13",
|
|
4
4
|
"description": "Advanced uBlock Origin management and stealth features for Brave Real Browser",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"@types/adm-zip": "^0.5.5",
|
|
65
65
|
"@types/fs-extra": "^11.0.4",
|
|
66
66
|
"@types/node": "^20.0.0",
|
|
67
|
-
"brave-real-puppeteer-core": "^24.37.1-brave.
|
|
67
|
+
"brave-real-puppeteer-core": "^24.37.1-brave.12",
|
|
68
68
|
"mocha": "^10.4.0",
|
|
69
69
|
"puppeteer-core": ">=24.0.0",
|
|
70
70
|
"sinon": "^17.0.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-launcher",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.13",
|
|
4
4
|
"description": "Launch Brave Browser with ease from node. Based on chrome-launcher with Brave-specific support.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"typescript": "^5.0.0"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"brave-real-blocker": "^1.17.
|
|
57
|
+
"brave-real-blocker": "^1.17.13",
|
|
58
58
|
"escape-string-regexp": "^5.0.0",
|
|
59
59
|
"is-wsl": "^3.1.0",
|
|
60
60
|
"which": "^6.0.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-puppeteer-core",
|
|
3
|
-
"version": "24.37.1-brave.
|
|
3
|
+
"version": "24.37.1-brave.12",
|
|
4
4
|
"description": "🦁 Brave Real-World Optimized Puppeteer & Playwright Core with 1-5ms ultra-fast timing, 50+ professional stealth features, intelligent browser auto-detection, and 100% bot detection bypass. Features cross-platform Brave browser integration, comprehensive anti-detection, and breakthrough performance improvements.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"automation",
|
|
@@ -134,13 +134,13 @@
|
|
|
134
134
|
"test-version": "node ./scripts/test-version-management.js"
|
|
135
135
|
},
|
|
136
136
|
"dependencies": {
|
|
137
|
-
"brave-real-launcher": "^1.23.
|
|
137
|
+
"brave-real-launcher": "^1.23.13",
|
|
138
138
|
"get-east-asian-width": "^1.4.0",
|
|
139
139
|
"yargs": "^18.0.0"
|
|
140
140
|
},
|
|
141
141
|
"optionalDependencies": {
|
|
142
|
-
"playwright-core": "^1.58.
|
|
143
|
-
"puppeteer-core": "^24.37.
|
|
142
|
+
"playwright-core": "^1.58.1",
|
|
143
|
+
"puppeteer-core": "^24.37.1"
|
|
144
144
|
},
|
|
145
145
|
"devDependencies": {
|
|
146
146
|
"test": "^3.3.0"
|
|
@@ -12,38 +12,38 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
12
12
|
const text = document.getText();
|
|
13
13
|
const lines = text.split('\n');
|
|
14
14
|
const diagnostics = [];
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
// State tracking
|
|
17
17
|
let browserInitialized = false;
|
|
18
18
|
let browserClosed = false;
|
|
19
19
|
let currentPage = null;
|
|
20
20
|
let networkRecording = false;
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
// Tool categories
|
|
23
23
|
const browserRequiredTools = [
|
|
24
24
|
'navigate', 'get_content', 'wait', 'click', 'type', 'solve_captcha',
|
|
25
25
|
'random_scroll', 'find_element', 'save_content_as_markdown', 'search_regex',
|
|
26
26
|
'extract_json', 'scrape_meta_tags', 'press_key', 'deep_analysis',
|
|
27
27
|
'network_recorder', 'link_harvester', 'cookie_manager', 'iframe_handler',
|
|
28
|
-
'stream_extractor', 'js_scrape', 'execute_js', 'player_api_hook',
|
|
28
|
+
'stream_extractor', 'js_scrape', 'execute_js', 'player_api_hook',
|
|
29
29
|
'redirect_tracer', 'file_downloader'
|
|
30
30
|
];
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
const pageRequiredTools = [
|
|
33
33
|
'get_content', 'click', 'type', 'random_scroll', 'find_element',
|
|
34
34
|
'save_content_as_markdown', 'search_regex', 'extract_json', 'scrape_meta_tags',
|
|
35
35
|
'deep_analysis', 'link_harvester', 'iframe_handler', 'stream_extractor',
|
|
36
|
-
'js_scrape', 'execute_js', 'player_api_hook', '
|
|
36
|
+
'js_scrape', 'execute_js', 'player_api_hook', 'press_key'
|
|
37
37
|
];
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
// Parse all tool calls with their parameters
|
|
40
40
|
const toolCalls = parseAllToolCalls(text, lines, tools);
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
for (const call of toolCalls) {
|
|
43
43
|
if (diagnostics.length >= maxDiagnostics) break;
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
const tool = tools.find(t => t.name === call.name);
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
// 1. Unknown tool check
|
|
48
48
|
if (!tool) {
|
|
49
49
|
diagnostics.push({
|
|
@@ -56,7 +56,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
56
56
|
});
|
|
57
57
|
continue;
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
// 2. Browser state tracking
|
|
61
61
|
if (call.name === 'browser_init') {
|
|
62
62
|
if (browserInitialized && !browserClosed) {
|
|
@@ -71,7 +71,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
71
71
|
browserInitialized = true;
|
|
72
72
|
browserClosed = false;
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
if (call.name === 'browser_close') {
|
|
76
76
|
if (!browserInitialized) {
|
|
77
77
|
diagnostics.push({
|
|
@@ -85,11 +85,11 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
85
85
|
browserClosed = true;
|
|
86
86
|
currentPage = null;
|
|
87
87
|
}
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
if (call.name === 'navigate') {
|
|
90
90
|
currentPage = call.params?.url || 'page';
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
// 3. Browser required check
|
|
94
94
|
if (browserRequiredTools.includes(call.name) && !browserInitialized) {
|
|
95
95
|
diagnostics.push({
|
|
@@ -100,7 +100,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
100
100
|
code: 'browser-not-init'
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
// 4. Browser closed check
|
|
105
105
|
if (browserRequiredTools.includes(call.name) && browserClosed) {
|
|
106
106
|
diagnostics.push({
|
|
@@ -111,7 +111,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
111
111
|
code: 'browser-closed'
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
// 5. Page required check (navigate must be called first)
|
|
116
116
|
if (pageRequiredTools.includes(call.name) && !currentPage && browserInitialized) {
|
|
117
117
|
diagnostics.push({
|
|
@@ -122,7 +122,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
122
122
|
code: 'no-page-loaded'
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
// 6. Network recorder state
|
|
127
127
|
if (call.name === 'network_recorder') {
|
|
128
128
|
if (call.params?.action === 'start') {
|
|
@@ -140,7 +140,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
140
140
|
networkRecording = false;
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
|
-
|
|
143
|
+
|
|
144
144
|
// 7. Required parameters check
|
|
145
145
|
if (tool.inputSchema?.required) {
|
|
146
146
|
for (const reqParam of tool.inputSchema.required) {
|
|
@@ -156,12 +156,12 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
-
|
|
159
|
+
|
|
160
160
|
// 8. Parameter validation
|
|
161
161
|
if (call.params && tool.inputSchema?.properties) {
|
|
162
162
|
for (const [paramName, paramValue] of Object.entries(call.params)) {
|
|
163
163
|
const schema = tool.inputSchema.properties[paramName];
|
|
164
|
-
|
|
164
|
+
|
|
165
165
|
// Unknown parameter
|
|
166
166
|
if (!schema) {
|
|
167
167
|
diagnostics.push({
|
|
@@ -174,7 +174,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
174
174
|
});
|
|
175
175
|
continue;
|
|
176
176
|
}
|
|
177
|
-
|
|
177
|
+
|
|
178
178
|
// Type validation
|
|
179
179
|
const typeError = validateParamType(paramValue, schema, paramName);
|
|
180
180
|
if (typeError) {
|
|
@@ -186,7 +186,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
186
186
|
code: 'type-error'
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
|
-
|
|
189
|
+
|
|
190
190
|
// Enum validation
|
|
191
191
|
if (schema.enum && !schema.enum.includes(paramValue)) {
|
|
192
192
|
diagnostics.push({
|
|
@@ -197,7 +197,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
197
197
|
code: 'invalid-enum'
|
|
198
198
|
});
|
|
199
199
|
}
|
|
200
|
-
|
|
200
|
+
|
|
201
201
|
// URL validation
|
|
202
202
|
if (paramName === 'url' && typeof paramValue === 'string') {
|
|
203
203
|
const urlError = validateUrl(paramValue);
|
|
@@ -211,7 +211,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
211
211
|
});
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
|
-
|
|
214
|
+
|
|
215
215
|
// Selector validation
|
|
216
216
|
if (paramName === 'selector' && typeof paramValue === 'string') {
|
|
217
217
|
const selectorError = validateSelector(paramValue);
|
|
@@ -225,7 +225,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
225
225
|
});
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
|
-
|
|
228
|
+
|
|
229
229
|
// Timeout validation
|
|
230
230
|
if (paramName === 'timeout' && typeof paramValue === 'number') {
|
|
231
231
|
if (paramValue < 0) {
|
|
@@ -246,7 +246,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
246
246
|
});
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
|
-
|
|
249
|
+
|
|
250
250
|
// Delay validation
|
|
251
251
|
if (paramName === 'delay' && typeof paramValue === 'number') {
|
|
252
252
|
if (paramValue < 0) {
|
|
@@ -269,7 +269,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
|
-
|
|
272
|
+
|
|
273
273
|
// 9. Tool-specific validations
|
|
274
274
|
if (call.name === 'type' && call.params?.text === '') {
|
|
275
275
|
diagnostics.push({
|
|
@@ -280,7 +280,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
280
280
|
code: 'empty-text'
|
|
281
281
|
});
|
|
282
282
|
}
|
|
283
|
-
|
|
283
|
+
|
|
284
284
|
if (call.name === 'wait' && call.params?.type === 'timeout') {
|
|
285
285
|
const waitValue = parseInt(call.params?.value);
|
|
286
286
|
if (waitValue > 30000) {
|
|
@@ -293,7 +293,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
293
293
|
});
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
|
-
|
|
296
|
+
|
|
297
297
|
if (call.name === 'execute_js' && call.params?.code) {
|
|
298
298
|
const jsCode = call.params.code;
|
|
299
299
|
if (jsCode.includes('eval(') || jsCode.includes('Function(')) {
|
|
@@ -306,7 +306,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
306
306
|
});
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
|
-
|
|
309
|
+
|
|
310
310
|
if (call.name === 'file_downloader' && call.params?.directory) {
|
|
311
311
|
const dir = call.params.directory;
|
|
312
312
|
if (dir.includes('..') || dir.startsWith('/')) {
|
|
@@ -320,7 +320,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
|
-
|
|
323
|
+
|
|
324
324
|
// 10. Document-level checks
|
|
325
325
|
if (browserInitialized && !browserClosed) {
|
|
326
326
|
diagnostics.push({
|
|
@@ -331,7 +331,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
331
331
|
code: 'missing-cleanup'
|
|
332
332
|
});
|
|
333
333
|
}
|
|
334
|
-
|
|
334
|
+
|
|
335
335
|
if (networkRecording) {
|
|
336
336
|
diagnostics.push({
|
|
337
337
|
severity: DiagnosticSeverity.Information,
|
|
@@ -341,7 +341,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
341
341
|
code: 'network-not-stopped'
|
|
342
342
|
});
|
|
343
343
|
}
|
|
344
|
-
|
|
344
|
+
|
|
345
345
|
// 11. Check for duplicate tool calls (potential bugs)
|
|
346
346
|
const navigateCalls = toolCalls.filter(c => c.name === 'navigate');
|
|
347
347
|
if (navigateCalls.length > 5) {
|
|
@@ -353,7 +353,7 @@ function getDiagnostics(document, tools, lang, maxDiagnostics = 100) {
|
|
|
353
353
|
code: 'many-navigates'
|
|
354
354
|
});
|
|
355
355
|
}
|
|
356
|
-
|
|
356
|
+
|
|
357
357
|
return diagnostics.slice(0, maxDiagnostics);
|
|
358
358
|
}
|
|
359
359
|
|
|
@@ -364,15 +364,15 @@ function parseAllToolCalls(text, lines, tools) {
|
|
|
364
364
|
const calls = [];
|
|
365
365
|
const toolNames = tools.map(t => t.name);
|
|
366
366
|
const toolRegex = new RegExp(`(${toolNames.join('|')})\\s*\\(\\s*(\\{[^}]*\\})?`, 'g');
|
|
367
|
-
|
|
367
|
+
|
|
368
368
|
for (let lineNum = 0; lineNum < lines.length; lineNum++) {
|
|
369
369
|
const line = lines[lineNum];
|
|
370
370
|
let match;
|
|
371
|
-
|
|
371
|
+
|
|
372
372
|
while ((match = toolRegex.exec(line)) !== null) {
|
|
373
373
|
const name = match[1];
|
|
374
374
|
const paramsStr = match[2];
|
|
375
|
-
|
|
375
|
+
|
|
376
376
|
calls.push({
|
|
377
377
|
name,
|
|
378
378
|
params: paramsStr ? parseParams(paramsStr) : null,
|
|
@@ -383,10 +383,10 @@ function parseAllToolCalls(text, lines, tools) {
|
|
|
383
383
|
}
|
|
384
384
|
});
|
|
385
385
|
}
|
|
386
|
-
|
|
386
|
+
|
|
387
387
|
toolRegex.lastIndex = 0;
|
|
388
388
|
}
|
|
389
|
-
|
|
389
|
+
|
|
390
390
|
return calls;
|
|
391
391
|
}
|
|
392
392
|
|
|
@@ -401,7 +401,7 @@ function parseParams(paramsStr) {
|
|
|
401
401
|
.replace(/(\w+)\s*:/g, '"$1":')
|
|
402
402
|
.replace(/,\s*}/g, '}')
|
|
403
403
|
.replace(/\n/g, ' ');
|
|
404
|
-
|
|
404
|
+
|
|
405
405
|
return JSON.parse(jsonStr);
|
|
406
406
|
} catch (e) {
|
|
407
407
|
return null;
|
|
@@ -414,7 +414,7 @@ function parseParams(paramsStr) {
|
|
|
414
414
|
function validateParamType(value, schema, paramName) {
|
|
415
415
|
const expectedType = schema.type;
|
|
416
416
|
const actualType = typeof value;
|
|
417
|
-
|
|
417
|
+
|
|
418
418
|
if (expectedType === 'string' && actualType !== 'string') {
|
|
419
419
|
return `Parameter ${paramName}: Expected string, got ${actualType}`;
|
|
420
420
|
}
|
|
@@ -430,7 +430,7 @@ function validateParamType(value, schema, paramName) {
|
|
|
430
430
|
if (expectedType === 'object' && (actualType !== 'object' || value === null || Array.isArray(value))) {
|
|
431
431
|
return `Parameter ${paramName}: Expected object, got ${actualType}`;
|
|
432
432
|
}
|
|
433
|
-
|
|
433
|
+
|
|
434
434
|
return null;
|
|
435
435
|
}
|
|
436
436
|
|
|
@@ -441,7 +441,7 @@ function validateUrl(url) {
|
|
|
441
441
|
if (!url || url.trim() === '') {
|
|
442
442
|
return 'URL cannot be empty';
|
|
443
443
|
}
|
|
444
|
-
|
|
444
|
+
|
|
445
445
|
try {
|
|
446
446
|
const parsed = new URL(url);
|
|
447
447
|
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
@@ -450,7 +450,7 @@ function validateUrl(url) {
|
|
|
450
450
|
} catch (e) {
|
|
451
451
|
return 'Invalid URL format. Example: https://example.com';
|
|
452
452
|
}
|
|
453
|
-
|
|
453
|
+
|
|
454
454
|
return null;
|
|
455
455
|
}
|
|
456
456
|
|
|
@@ -461,20 +461,20 @@ function validateSelector(selector) {
|
|
|
461
461
|
if (!selector || selector.trim() === '') {
|
|
462
462
|
return 'Selector cannot be empty';
|
|
463
463
|
}
|
|
464
|
-
|
|
464
|
+
|
|
465
465
|
// Check for common mistakes
|
|
466
466
|
if (selector.includes(' ')) {
|
|
467
467
|
return 'Selector contains multiple consecutive spaces';
|
|
468
468
|
}
|
|
469
|
-
|
|
469
|
+
|
|
470
470
|
if (/^[0-9]/.test(selector) && !selector.startsWith('[')) {
|
|
471
471
|
return 'Selector cannot start with a number (unless in attribute selector)';
|
|
472
472
|
}
|
|
473
|
-
|
|
473
|
+
|
|
474
474
|
// Check balanced brackets
|
|
475
475
|
const brackets = { '[': ']', '(': ')' };
|
|
476
476
|
const stack = [];
|
|
477
|
-
|
|
477
|
+
|
|
478
478
|
for (const char of selector) {
|
|
479
479
|
if (char in brackets) {
|
|
480
480
|
stack.push(brackets[char]);
|
|
@@ -484,16 +484,16 @@ function validateSelector(selector) {
|
|
|
484
484
|
}
|
|
485
485
|
}
|
|
486
486
|
}
|
|
487
|
-
|
|
487
|
+
|
|
488
488
|
if (stack.length > 0) {
|
|
489
489
|
return 'Unclosed bracket in selector';
|
|
490
490
|
}
|
|
491
|
-
|
|
491
|
+
|
|
492
492
|
// Check for empty attribute selector
|
|
493
493
|
if (selector.includes('[]')) {
|
|
494
494
|
return 'Empty attribute selector []';
|
|
495
495
|
}
|
|
496
|
-
|
|
496
|
+
|
|
497
497
|
return null;
|
|
498
498
|
}
|
|
499
499
|
|
|
@@ -502,7 +502,7 @@ function validateSelector(selector) {
|
|
|
502
502
|
*/
|
|
503
503
|
function findSimilarTools(name, tools) {
|
|
504
504
|
const lowerName = name.toLowerCase();
|
|
505
|
-
|
|
505
|
+
|
|
506
506
|
return tools
|
|
507
507
|
.map(t => ({
|
|
508
508
|
name: t.name,
|
|
@@ -520,14 +520,14 @@ function findSimilarTools(name, tools) {
|
|
|
520
520
|
function calculateSimilarity(s1, s2) {
|
|
521
521
|
const longer = s1.length > s2.length ? s1 : s2;
|
|
522
522
|
const shorter = s1.length > s2.length ? s2 : s1;
|
|
523
|
-
|
|
523
|
+
|
|
524
524
|
if (longer.length === 0) return 1.0;
|
|
525
|
-
|
|
525
|
+
|
|
526
526
|
// Quick check for common prefix
|
|
527
527
|
if (longer.startsWith(shorter) || shorter.startsWith(longer.substring(0, 3))) {
|
|
528
528
|
return 0.8;
|
|
529
529
|
}
|
|
530
|
-
|
|
530
|
+
|
|
531
531
|
// Levenshtein distance
|
|
532
532
|
const costs = [];
|
|
533
533
|
for (let i = 0; i <= s1.length; i++) {
|
|
@@ -546,7 +546,7 @@ function calculateSimilarity(s1, s2) {
|
|
|
546
546
|
}
|
|
547
547
|
if (i > 0) costs[s2.length] = lastValue;
|
|
548
548
|
}
|
|
549
|
-
|
|
549
|
+
|
|
550
550
|
return (longer.length - costs[s2.length]) / longer.length;
|
|
551
551
|
}
|
|
552
552
|
|
package/src/lsp/languages/en.js
CHANGED
|
@@ -21,7 +21,7 @@ module.exports = {
|
|
|
21
21
|
click: { label: 'Click Element', detail: 'Click with human-like behavior', documentation: 'Clicks on an element using ghost-cursor.', parameters: { selector: 'Element selector', humanLike: 'Use realistic movement', clickCount: 'Number of clicks', delay: 'Click delay' } },
|
|
22
22
|
type: { label: 'Type Text', detail: 'Type into input field', documentation: 'Types text with realistic keystroke delays.', parameters: { selector: 'Input selector', text: 'Text to type', delay: 'Keystroke delay', clear: 'Clear first' } },
|
|
23
23
|
browser_close: { label: 'Close Browser', detail: 'Close and cleanup', documentation: 'Closes the browser.', parameters: { force: 'Force close' } },
|
|
24
|
-
solve_captcha: { label: 'Solve CAPTCHA', detail: 'Auto-solve
|
|
24
|
+
solve_captcha: { label: 'Solve CAPTCHA + Form', detail: 'Auto-solve + Fill forms', documentation: 'Solves CAPTCHAs and fills forms with AI field matching.', parameters: { type: 'CAPTCHA type', timeout: 'Max time', formData: 'Form data', submit: 'Submit form' } },
|
|
25
25
|
random_scroll: { label: 'Random Scroll', detail: 'Human-like scrolling', documentation: 'Scrolls with human-like behavior.', parameters: { direction: 'Scroll direction', amount: 'Scroll amount', smooth: 'Smooth scrolling' } },
|
|
26
26
|
find_element: { label: 'Find Element', detail: 'Locate elements', documentation: 'Finds elements by selector/xpath/text.', parameters: { selector: 'CSS selector', xpath: 'XPath', text: 'Text content', multiple: 'Return all' } },
|
|
27
27
|
save_content_as_markdown: { label: 'Save as Markdown', detail: 'Export to MD', documentation: 'Saves page as Markdown file.', parameters: { filename: 'Output filename', selector: 'Content selector', includeImages: 'Include images', includeMeta: 'Include meta' } },
|
|
@@ -40,8 +40,7 @@ module.exports = {
|
|
|
40
40
|
stream_extractor: { label: 'Extract Streams', detail: 'Get video/audio', documentation: 'Extracts stream URLs.', parameters: { types: 'Stream types', quality: 'Quality' } },
|
|
41
41
|
js_scrape: { label: 'JS Scrape', detail: 'Scrape JS content', documentation: 'Scrapes JS-rendered content.', parameters: { selector: 'CSS selector', waitForJS: 'Wait for JS', timeout: 'Max wait' } },
|
|
42
42
|
execute_js: { label: 'Execute JS', detail: 'Run JavaScript', documentation: 'Executes custom JavaScript.', parameters: { code: 'JS code', returnValue: 'Return result' } },
|
|
43
|
-
player_api_hook: { label: 'Player API Hook', detail: 'Video player control', documentation: 'Hooks into video players.', parameters: { playerType: 'Player type', action: 'Action' } }
|
|
44
|
-
form_automator: { label: 'Automate Form', detail: 'Fill and submit', documentation: 'Auto-fills and submits forms.', parameters: { selector: 'Form selector', data: 'Form data', submit: 'Submit', humanLike: 'Human delays' } }
|
|
43
|
+
player_api_hook: { label: 'Player API Hook', detail: 'Video player control', documentation: 'Hooks into video players.', parameters: { playerType: 'Player type', action: 'Action' } }
|
|
45
44
|
},
|
|
46
45
|
diagnostics: {
|
|
47
46
|
browserNotInit: 'Browser not initialized. Call browser_init first.',
|
package/src/lsp/languages/hi.js
CHANGED
|
@@ -11,7 +11,7 @@ module.exports = {
|
|
|
11
11
|
click: { label: 'क्लिक करें', detail: 'मानव-जैसा क्लिक', documentation: 'ghost-cursor से क्लिक करता है।', parameters: { selector: 'एलीमेंट selector', humanLike: 'वास्तविक मूवमेंट', clickCount: 'क्लिक संख्या', delay: 'देरी' } },
|
|
12
12
|
type: { label: 'टाइप करें', detail: 'इनपुट में टाइप', documentation: 'वास्तविक कीस्ट्रोक के साथ टाइप करता है।', parameters: { selector: 'इनपुट selector', text: 'टेक्स्ट', delay: 'कीस्ट्रोक देरी', clear: 'पहले साफ करें' } },
|
|
13
13
|
browser_close: { label: 'ब्राउज़र बंद करें', detail: 'बंद और क्लीनअप', documentation: 'ब्राउज़र बंद करता है।', parameters: { force: 'फोर्स क्लोज़' } },
|
|
14
|
-
solve_captcha: { label: 'CAPTCHA
|
|
14
|
+
solve_captcha: { label: 'CAPTCHA + फॉर्म', detail: 'ऑटो-सॉल्व + फॉर्म भरें', documentation: 'CAPTCHA हल करता है और फॉर्म भी भरता है।', parameters: { type: 'CAPTCHA प्रकार', timeout: 'अधिकतम समय', formData: 'फॉर्म डेटा', submit: 'सबमिट करें' } },
|
|
15
15
|
random_scroll: { label: 'रैंडम स्क्रॉल', detail: 'मानव-जैसा स्क्रॉल', documentation: 'रैंडम स्क्रॉल करता है।', parameters: { direction: 'दिशा', amount: 'मात्रा', smooth: 'स्मूथ' } },
|
|
16
16
|
find_element: { label: 'एलीमेंट खोजें', detail: 'पेज पर खोजें', documentation: 'selector/xpath से खोजता है।', parameters: { selector: 'CSS selector', xpath: 'XPath', text: 'टेक्स्ट', multiple: 'सभी लौटाएं' } },
|
|
17
17
|
save_content_as_markdown: { label: 'MD में सेव', detail: 'Markdown एक्सपोर्ट', documentation: 'Markdown फाइल में सेव करता है।', parameters: { filename: 'फाइलनेम', selector: 'कंटेंट selector', includeImages: 'इमेज शामिल', includeMeta: 'मेटा शामिल' } },
|
|
@@ -30,8 +30,7 @@ module.exports = {
|
|
|
30
30
|
stream_extractor: { label: 'स्ट्रीम निकालें', detail: 'वीडियो/ऑडियो URL', documentation: 'स्ट्रीम URLs निकालता है।', parameters: { types: 'प्रकार', quality: 'क्वालिटी' } },
|
|
31
31
|
js_scrape: { label: 'JS स्क्रैप', detail: 'JS कंटेंट', documentation: 'JS-रेंडर्ड कंटेंट।', parameters: { selector: 'selector', waitForJS: 'JS इंतजार', timeout: 'अधिकतम' } },
|
|
32
32
|
execute_js: { label: 'JS चलाएं', detail: 'JavaScript रन', documentation: 'कस्टम JS चलाता है।', parameters: { code: 'कोड', returnValue: 'रिज़ल्ट लौटाएं' } },
|
|
33
|
-
player_api_hook: { label: 'Player Hook', detail: 'वीडियो प्लेयर', documentation: 'प्लेयर में हुक करता है।', parameters: { playerType: 'प्लेयर', action: 'एक्शन' } }
|
|
34
|
-
form_automator: { label: 'फॉर्म ऑटोमेट', detail: 'फॉर्म भरें', documentation: 'फॉर्म भरता और सबमिट करता है।', parameters: { selector: 'फॉर्म selector', data: 'डेटा', submit: 'सबमिट', humanLike: 'मानव देरी' } }
|
|
33
|
+
player_api_hook: { label: 'Player Hook', detail: 'वीडियो प्लेयर', documentation: 'प्लेयर में हुक करता है।', parameters: { playerType: 'प्लेयर', action: 'एक्शन' } }
|
|
35
34
|
},
|
|
36
35
|
diagnostics: {
|
|
37
36
|
browserNotInit: 'ब्राउज़र इनिशियलाइज़ नहीं। पहले browser_init करें।',
|