@browserstack/mcp-server 2.2.0-beta.1 → 2.2.0-beta.2
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/capability/tra.capability-index.json +36 -14
- package/dist/config.d.ts +27 -2
- package/dist/config.js +19 -6
- package/dist/lib/instrumentation.js +29 -3
- package/dist/lib/utils.js +8 -0
- package/dist/tools/accessiblity-utils/scanner.js +1 -1
- package/dist/tools/ask-browserstack/config.d.ts +0 -14
- package/dist/tools/ask-browserstack/config.js +0 -16
- package/dist/tools/ask-browserstack/deferred.d.ts +74 -0
- package/dist/tools/ask-browserstack/deferred.js +242 -0
- package/dist/tools/ask-browserstack/register.d.ts +3 -2
- package/dist/tools/ask-browserstack/register.js +219 -72
- package/dist/tools/ask-browserstack/relay.js +11 -17
- package/dist/tools/ask-browserstack/stream.d.ts +27 -5
- package/dist/tools/ask-browserstack/stream.js +25 -14
- package/dist/tools/ask-browserstack/types.d.ts +54 -3
- package/dist/tools/ask-browserstack/types.js +11 -1
- package/dist/tools/automate-utils/fetch-screenshots.js +17 -15
- package/dist/tools/capability-registry/redact.js +7 -5
- package/package.json +1 -1
- package/capability/loadtesting.capability-index.json +0 -2978
|
@@ -11,4 +11,14 @@
|
|
|
11
11
|
// describe text in register.ts, and the two a11y handoffs in tool-handoff.ts — which stop
|
|
12
12
|
// pointing here precisely because the call would now be rejected.
|
|
13
13
|
export const PRODUCTS = ["tm", "tra"];
|
|
14
|
-
export const ASK_STATUSES = [
|
|
14
|
+
export const ASK_STATUSES = [
|
|
15
|
+
"ok",
|
|
16
|
+
"blocked",
|
|
17
|
+
"error",
|
|
18
|
+
"rate_limited",
|
|
19
|
+
// Deferred only: the run reached an ask and is PARKED, not finished. Distinct from
|
|
20
|
+
// `blocked` (a human said no) and from `error` (nothing is waiting) — this one is the
|
|
21
|
+
// only status a caller is invited to come back from, and the only one carrying a
|
|
22
|
+
// `run_id`.
|
|
23
|
+
"needs_approval",
|
|
24
|
+
];
|
|
@@ -2,6 +2,7 @@ import { assertOkResponse, maybeCompressBase64 } from "../../lib/utils.js";
|
|
|
2
2
|
import { SessionType } from "../../lib/constants.js";
|
|
3
3
|
import { getBrowserStackAuth } from "../../lib/get-auth.js";
|
|
4
4
|
import { apiClient } from "../../lib/apiClient.js";
|
|
5
|
+
import globalConfig from "../../config.js";
|
|
5
6
|
async function extractScreenshotUrls(sessionId, sessionType, config) {
|
|
6
7
|
const authString = getBrowserStackAuth(config);
|
|
7
8
|
const auth = Buffer.from(authString).toString("base64");
|
|
@@ -36,23 +37,24 @@ async function extractScreenshotUrls(sessionId, sessionType, config) {
|
|
|
36
37
|
}
|
|
37
38
|
return urls;
|
|
38
39
|
}
|
|
40
|
+
async function fetchAndCompress(url) {
|
|
41
|
+
const response = await apiClient.get({ url, responseType: "arraybuffer" });
|
|
42
|
+
// Axios returns response.data as a Buffer for binary data
|
|
43
|
+
const base64 = Buffer.from(response.data).toString("base64");
|
|
44
|
+
return { url, base64: await maybeCompressBase64(base64) };
|
|
45
|
+
}
|
|
39
46
|
//Converts screenshot URLs to base64 encoded images
|
|
40
47
|
async function convertUrlsToBase64(urls) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
url,
|
|
52
|
-
base64: compressedBase64,
|
|
53
|
-
};
|
|
54
|
-
}));
|
|
55
|
-
return screenshots;
|
|
48
|
+
// Hosted pods are memory-constrained: process one image at a time. Local runs
|
|
49
|
+
// keep the concurrent path.
|
|
50
|
+
if (globalConfig.REMOTE_MCP) {
|
|
51
|
+
const screenshots = [];
|
|
52
|
+
for (const url of urls) {
|
|
53
|
+
screenshots.push(await fetchAndCompress(url));
|
|
54
|
+
}
|
|
55
|
+
return screenshots;
|
|
56
|
+
}
|
|
57
|
+
return Promise.all(urls.map(fetchAndCompress));
|
|
56
58
|
}
|
|
57
59
|
//Fetches and converts screenshot URLs to base64 encoded images
|
|
58
60
|
export async function fetchAutomationScreenshots(sessionId, sessionType = SessionType.Automate, config) {
|
|
@@ -25,13 +25,13 @@ const RULES = [
|
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
name: "email",
|
|
28
|
-
pattern: /\b[\w.%+-]
|
|
28
|
+
pattern: /\b[\w.%+-]{1,128}@[\w.-]{1,128}\.[a-z]{2,24}\b/gi,
|
|
29
29
|
replacement: "[email]",
|
|
30
30
|
},
|
|
31
31
|
// JWT: three base64url segments.
|
|
32
32
|
{
|
|
33
33
|
name: "jwt",
|
|
34
|
-
pattern: /\beyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]{8,}\b/g,
|
|
34
|
+
pattern: /\beyJ[\w-]{8,1024}\.[\w-]{8,1024}\.[\w-]{8,1024}\b/g,
|
|
35
35
|
replacement: "[token]",
|
|
36
36
|
},
|
|
37
37
|
// A long opaque run — access keys, API keys, session ids. Requires BOTH a digit and a
|
|
@@ -41,7 +41,7 @@ const RULES = [
|
|
|
41
41
|
// wording a product uses is exactly the assumption that fails.
|
|
42
42
|
{
|
|
43
43
|
name: "opaque_token",
|
|
44
|
-
pattern: /\b(?=[A-Za-z0-9_-]
|
|
44
|
+
pattern: /\b(?=[A-Za-z0-9_-]{0,256}\d)(?=[A-Za-z0-9_-]{0,256}[A-Za-z])[A-Za-z0-9_-]{20,256}\b/g,
|
|
45
45
|
replacement: "[token]",
|
|
46
46
|
},
|
|
47
47
|
{
|
|
@@ -53,7 +53,7 @@ const RULES = [
|
|
|
53
53
|
// separator or a `+`, so a bare digit run falls to long_number instead.
|
|
54
54
|
{
|
|
55
55
|
name: "phone",
|
|
56
|
-
pattern: /(?:\+\d{1,3}[\s.-]?)?(?:\(\d{2,4}\)[\s.-]?)?\d{3,5}[\s.-]\d{3,5}(?:[\s.-]\d{2,5})?\b/g,
|
|
56
|
+
pattern: /(?:\+\d{1,3}[\s.-]?)?(?:\(\d{2,4}\)[\s.-]?)?\b\d{3,5}[\s.-]\d{3,5}(?:[\s.-]\d{2,5})?\b/g,
|
|
57
57
|
replacement: "[phone]",
|
|
58
58
|
},
|
|
59
59
|
// Long bare digit runs: account ids, card numbers, unseparated phone numbers.
|
|
@@ -81,7 +81,9 @@ export function redact(text) {
|
|
|
81
81
|
try {
|
|
82
82
|
if (typeof text !== "string")
|
|
83
83
|
return undefined;
|
|
84
|
-
|
|
84
|
+
// Slice before the rules run; a multi-KB digit run makes them backtrack.
|
|
85
|
+
const SCAN_LIMIT = MAX_LENGTH * 8;
|
|
86
|
+
let out = text.slice(0, SCAN_LIMIT).replace(/\s+/g, " ").trim();
|
|
85
87
|
if (!out)
|
|
86
88
|
return undefined;
|
|
87
89
|
for (const rule of RULES)
|