patchright-bun-core 1.58.2 → 1.59.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.
- package/ThirdPartyNotices.txt +126 -650
- package/browsers.json +16 -14
- package/lib/bootstrap.js +77 -0
- package/lib/cli/browserActions.js +308 -0
- package/lib/cli/driver.js +3 -2
- package/lib/cli/installActions.js +171 -0
- package/lib/cli/program.js +47 -411
- package/lib/client/android.js +4 -4
- package/lib/client/api.js +3 -3
- package/lib/client/browser.js +8 -0
- package/lib/client/browserContext.js +18 -37
- package/lib/client/browserType.js +19 -51
- package/lib/client/cdpSession.js +6 -2
- package/lib/client/channelOwner.js +1 -1
- package/lib/client/{webSocket.js → connect.js} +57 -7
- package/lib/client/connection.js +8 -4
- package/lib/client/consoleMessage.js +3 -0
- package/lib/client/debugger.js +57 -0
- package/lib/client/dialog.js +8 -1
- package/lib/client/disposable.js +76 -0
- package/lib/client/electron.js +1 -0
- package/lib/client/elementHandle.js +1 -4
- package/lib/client/events.js +3 -3
- package/lib/client/fetch.js +0 -1
- package/lib/client/frame.js +0 -5
- package/lib/client/harRouter.js +13 -1
- package/lib/client/jsHandle.js +0 -4
- package/lib/client/locator.js +5 -7
- package/lib/client/network.js +14 -11
- package/lib/client/page.js +34 -48
- package/lib/client/platform.js +0 -3
- package/lib/client/screencast.js +88 -0
- package/lib/client/selectors.js +3 -1
- package/lib/client/tracing.js +11 -4
- package/lib/client/video.js +13 -20
- package/lib/generated/bindingsControllerSource.js +1 -1
- package/lib/generated/clockSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/generated/storageScriptSource.js +1 -1
- package/lib/generated/utilityScriptSource.js +1 -1
- package/lib/mcpBundle.js +0 -6
- package/lib/mcpBundleImpl.js +91 -0
- package/lib/protocol/validator.js +216 -118
- package/lib/protocol/validatorPrimitives.js +1 -1
- package/lib/remote/playwrightConnection.js +10 -8
- package/lib/remote/playwrightPipeServer.js +100 -0
- package/lib/remote/playwrightServer.js +13 -8
- package/lib/remote/playwrightWebSocketServer.js +73 -0
- package/lib/remote/serverTransport.js +96 -0
- package/lib/server/android/android.js +2 -2
- package/lib/server/bidi/bidiBrowser.js +30 -8
- package/lib/server/bidi/bidiChromium.js +18 -5
- package/lib/server/bidi/bidiNetworkManager.js +39 -11
- package/lib/server/bidi/bidiPage.js +31 -15
- package/lib/server/bidi/third_party/firefoxPrefs.js +3 -1
- package/lib/server/browser.js +84 -21
- package/lib/server/browserContext.js +97 -58
- package/lib/server/browserType.js +14 -12
- package/lib/server/chromium/chromium.js +15 -13
- package/lib/server/chromium/crBrowser.js +18 -10
- package/lib/server/chromium/crNetworkManager.js +4 -4
- package/lib/server/chromium/crPage.js +26 -64
- package/lib/server/chromium/crServiceWorker.js +5 -4
- package/lib/server/clock.js +33 -33
- package/lib/server/console.js +5 -1
- package/lib/server/debugController.js +12 -6
- package/lib/server/debugger.js +40 -47
- package/lib/server/deviceDescriptorsSource.json +137 -137
- package/lib/server/dispatchers/browserContextDispatcher.js +27 -30
- package/lib/server/dispatchers/browserDispatcher.js +11 -5
- package/lib/server/dispatchers/browserTypeDispatcher.js +7 -0
- package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -1
- package/lib/server/dispatchers/debuggerDispatcher.js +84 -0
- package/lib/server/dispatchers/dispatcher.js +1 -1
- package/lib/server/dispatchers/disposableDispatcher.js +39 -0
- package/lib/server/dispatchers/electronDispatcher.js +2 -1
- package/lib/server/dispatchers/frameDispatcher.js +3 -3
- package/lib/server/dispatchers/localUtilsDispatcher.js +37 -1
- package/lib/server/dispatchers/networkDispatchers.js +6 -5
- package/lib/server/dispatchers/pageDispatcher.js +101 -38
- package/lib/server/dispatchers/webSocketRouteDispatcher.js +4 -5
- package/lib/server/disposable.js +41 -0
- package/lib/server/dom.js +44 -26
- package/lib/server/download.js +3 -2
- package/lib/server/electron/electron.js +12 -7
- package/lib/server/firefox/ffBrowser.js +9 -19
- package/lib/server/firefox/ffInput.js +21 -5
- package/lib/server/firefox/ffNetworkManager.js +2 -2
- package/lib/server/firefox/ffPage.js +24 -27
- package/lib/server/frames.js +40 -11
- package/lib/server/har/harRecorder.js +2 -2
- package/lib/server/har/harTracer.js +5 -4
- package/lib/server/input.js +49 -4
- package/lib/server/instrumentation.js +5 -0
- package/lib/server/launchApp.js +0 -1
- package/lib/server/localUtils.js +6 -6
- package/lib/server/network.js +9 -8
- package/lib/server/overlay.js +138 -0
- package/lib/server/page.js +111 -51
- package/lib/server/progress.js +6 -0
- package/lib/server/recorder/recorderApp.js +9 -8
- package/lib/server/recorder.js +76 -40
- package/lib/server/registry/index.js +54 -81
- package/lib/server/registry/nativeDeps.js +1 -0
- package/lib/server/screencast.js +90 -143
- package/lib/server/trace/recorder/snapshotter.js +2 -2
- package/lib/server/trace/recorder/tracing.js +87 -36
- package/lib/server/trace/viewer/traceViewer.js +3 -4
- package/lib/server/usKeyboardLayout.js +7 -0
- package/lib/server/utils/comparators.js +1 -1
- package/lib/server/utils/disposable.js +32 -0
- package/lib/server/utils/eventsHelper.js +3 -1
- package/lib/server/utils/fileUtils.js +16 -2
- package/lib/server/utils/happyEyeballs.js +15 -12
- package/lib/server/utils/hostPlatform.js +0 -15
- package/lib/server/utils/httpServer.js +5 -3
- package/lib/server/utils/network.js +2 -1
- package/lib/server/utils/nodePlatform.js +0 -6
- package/lib/server/utils/processLauncher.js +8 -6
- package/lib/server/utils/zipFile.js +2 -2
- package/lib/server/videoRecorder.js +82 -12
- package/lib/server/webkit/wkBrowser.js +1 -6
- package/lib/server/webkit/wkPage.js +27 -25
- package/lib/server/webkit/wkWorkers.js +2 -1
- package/lib/serverRegistry.js +156 -0
- package/lib/tools/backend/browserBackend.js +79 -0
- package/lib/tools/backend/common.js +63 -0
- package/lib/tools/backend/config.js +41 -0
- package/lib/tools/backend/console.js +66 -0
- package/lib/tools/backend/context.js +296 -0
- package/lib/tools/backend/cookies.js +152 -0
- package/lib/tools/backend/devtools.js +69 -0
- package/lib/tools/backend/dialogs.js +59 -0
- package/lib/tools/backend/evaluate.js +64 -0
- package/lib/tools/backend/files.js +60 -0
- package/lib/tools/backend/form.js +64 -0
- package/lib/tools/backend/keyboard.js +155 -0
- package/lib/tools/backend/logFile.js +95 -0
- package/lib/tools/backend/mouse.js +168 -0
- package/lib/tools/backend/navigate.js +106 -0
- package/lib/tools/backend/network.js +135 -0
- package/lib/tools/backend/pdf.js +48 -0
- package/lib/tools/backend/response.js +305 -0
- package/lib/tools/backend/route.js +140 -0
- package/lib/tools/backend/runCode.js +77 -0
- package/lib/tools/backend/screenshot.js +88 -0
- package/lib/tools/backend/sessionLog.js +74 -0
- package/lib/tools/backend/snapshot.js +208 -0
- package/lib/tools/backend/storage.js +68 -0
- package/lib/tools/backend/tab.js +445 -0
- package/lib/tools/backend/tabs.js +67 -0
- package/lib/tools/backend/tool.js +47 -0
- package/lib/tools/backend/tools.js +102 -0
- package/lib/tools/backend/tracing.js +78 -0
- package/lib/tools/backend/utils.js +83 -0
- package/lib/tools/backend/verify.js +151 -0
- package/lib/tools/backend/video.js +98 -0
- package/lib/tools/backend/wait.js +63 -0
- package/lib/tools/backend/webstorage.js +223 -0
- package/lib/tools/cli-client/cli.js +6 -0
- package/lib/tools/cli-client/help.json +399 -0
- package/lib/tools/cli-client/minimist.js +128 -0
- package/lib/tools/cli-client/program.js +350 -0
- package/lib/tools/cli-client/registry.js +176 -0
- package/lib/tools/cli-client/session.js +289 -0
- package/lib/tools/cli-client/skill/SKILL.md +328 -0
- package/lib/tools/cli-client/skill/references/element-attributes.md +23 -0
- package/lib/tools/cli-client/skill/references/playwright-tests.md +39 -0
- package/lib/tools/cli-client/skill/references/request-mocking.md +87 -0
- package/lib/tools/cli-client/skill/references/running-code.md +231 -0
- package/lib/tools/cli-client/skill/references/session-management.md +169 -0
- package/lib/tools/cli-client/skill/references/storage-state.md +275 -0
- package/lib/tools/cli-client/skill/references/test-generation.md +88 -0
- package/lib/tools/cli-client/skill/references/tracing.md +139 -0
- package/lib/tools/cli-client/skill/references/video-recording.md +143 -0
- package/lib/tools/cli-daemon/command.js +73 -0
- package/lib/tools/cli-daemon/commands.js +956 -0
- package/lib/tools/cli-daemon/daemon.js +157 -0
- package/lib/tools/cli-daemon/helpGenerator.js +177 -0
- package/lib/tools/cli-daemon/program.js +129 -0
- package/lib/tools/dashboard/appIcon.png +0 -0
- package/lib/tools/dashboard/dashboardApp.js +284 -0
- package/lib/tools/dashboard/dashboardController.js +296 -0
- package/lib/tools/exports.js +60 -0
- package/lib/tools/mcp/browserFactory.js +233 -0
- package/lib/tools/mcp/cdpRelay.js +352 -0
- package/lib/tools/mcp/cli-stub.js +7 -0
- package/lib/tools/mcp/config.d.js +16 -0
- package/lib/tools/mcp/config.js +446 -0
- package/lib/tools/mcp/configIni.js +189 -0
- package/lib/tools/mcp/extensionContextFactory.js +55 -0
- package/lib/tools/mcp/index.js +62 -0
- package/lib/tools/mcp/log.js +35 -0
- package/lib/tools/mcp/program.js +107 -0
- package/lib/tools/mcp/protocol.js +28 -0
- package/lib/tools/mcp/watchdog.js +44 -0
- package/lib/tools/trace/SKILL.md +171 -0
- package/lib/{server/trace/viewer/traceParser.js → tools/trace/installSkill.js} +15 -39
- package/lib/tools/trace/traceActions.js +142 -0
- package/lib/tools/trace/traceAttachments.js +69 -0
- package/lib/tools/trace/traceCli.js +87 -0
- package/lib/tools/trace/traceConsole.js +97 -0
- package/lib/tools/trace/traceErrors.js +55 -0
- package/lib/tools/trace/traceOpen.js +69 -0
- package/lib/tools/trace/traceParser.js +96 -0
- package/lib/tools/trace/traceRequests.js +182 -0
- package/lib/tools/trace/traceScreenshot.js +68 -0
- package/lib/tools/trace/traceSnapshot.js +149 -0
- package/lib/tools/trace/traceUtils.js +153 -0
- package/lib/tools/utils/connect.js +32 -0
- package/lib/tools/utils/mcp/http.js +152 -0
- package/lib/tools/utils/mcp/server.js +230 -0
- package/lib/tools/utils/mcp/tool.js +47 -0
- package/lib/tools/utils/socketConnection.js +108 -0
- package/lib/utils/isomorphic/formatUtils.js +64 -0
- package/lib/utils/isomorphic/jsonSchema.js +89 -0
- package/lib/utils/isomorphic/mimeType.js +7 -2
- package/lib/utils/isomorphic/protocolFormatter.js +2 -2
- package/lib/utils/isomorphic/protocolMetainfo.js +127 -106
- package/lib/utils/isomorphic/stringUtils.js +3 -3
- package/lib/utils/isomorphic/timeoutRunner.js +3 -3
- package/lib/utils/isomorphic/trace/snapshotRenderer.js +35 -42
- package/lib/utils/isomorphic/trace/traceLoader.js +15 -14
- package/lib/utils/isomorphic/trace/traceModel.js +3 -2
- package/lib/utils/isomorphic/trace/traceModernizer.js +1 -0
- package/lib/utils/isomorphic/urlMatch.js +54 -1
- package/lib/utils/isomorphic/utilityScriptSerializers.js +11 -0
- package/lib/utils.js +6 -2
- package/lib/utilsBundle.js +3 -21
- package/lib/utilsBundleImpl/index.js +132 -133
- package/lib/vite/dashboard/assets/index-BAOybkp8.js +50 -0
- package/lib/vite/dashboard/assets/index-CZAYOG76.css +1 -0
- package/lib/vite/dashboard/index.html +28 -0
- package/lib/vite/htmlReport/index.html +2 -70
- package/lib/vite/htmlReport/report.css +1 -0
- package/lib/vite/htmlReport/report.js +72 -0
- package/lib/vite/recorder/assets/{codeMirrorModule-DadYNm1I.js → codeMirrorModule-C8KMvO9L.js} +20 -20
- package/lib/vite/recorder/assets/index-CqAYX1I3.js +193 -0
- package/lib/vite/recorder/index.html +1 -1
- package/lib/vite/traceViewer/assets/{codeMirrorModule-a5XoALAZ.js → codeMirrorModule-DS0FLvoc.js} +20 -20
- package/lib/vite/traceViewer/assets/defaultSettingsView-GTWI-W_B.js +262 -0
- package/lib/vite/traceViewer/defaultSettingsView.B4dS75f0.css +1 -0
- package/lib/vite/traceViewer/{index.BVu7tZDe.css → index.CzXZzn5A.css} +1 -1
- package/lib/vite/traceViewer/{index.BDwrLSGN.js → index.Dtstcb7U.js} +1 -1
- package/lib/vite/traceViewer/index.html +4 -4
- package/lib/vite/traceViewer/sw.bundle.js +4 -4
- package/lib/vite/traceViewer/uiMode.Vipi55dB.js +6 -0
- package/lib/vite/traceViewer/uiMode.html +3 -3
- package/lib/zipBundleImpl.js +2 -2
- package/lib/zodBundle.js +39 -0
- package/lib/zodBundleImpl.js +40 -0
- package/package.json +6 -1
- package/types/protocol.d.ts +947 -51
- package/types/types.d.ts +854 -74
- package/lib/client/pageAgent.js +0 -64
- package/lib/mcpBundleImpl/index.js +0 -147
- package/lib/server/agent/actionRunner.js +0 -335
- package/lib/server/agent/actions.js +0 -128
- package/lib/server/agent/codegen.js +0 -111
- package/lib/server/agent/context.js +0 -150
- package/lib/server/agent/expectTools.js +0 -156
- package/lib/server/agent/pageAgent.js +0 -204
- package/lib/server/agent/performTools.js +0 -262
- package/lib/server/agent/tool.js +0 -109
- package/lib/server/dispatchers/pageAgentDispatcher.js +0 -96
- package/lib/vite/recorder/assets/index-BhTWtUlo.js +0 -193
- package/lib/vite/traceViewer/assets/defaultSettingsView-CJSZINFr.js +0 -266
- package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +0 -1
- package/lib/vite/traceViewer/uiMode.CQJ9SCIQ.js +0 -5
- /package/lib/{server/utils → utils/isomorphic}/imageUtils.js +0 -0
- /package/lib/utils/isomorphic/{traceUtils.js → trace/traceUtils.js} +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var network_exports = {};
|
|
20
|
+
__export(network_exports, {
|
|
21
|
+
default: () => network_default,
|
|
22
|
+
isFetch: () => isFetch,
|
|
23
|
+
renderRequest: () => renderRequest
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(network_exports);
|
|
26
|
+
var import_zodBundle = require("../../zodBundle");
|
|
27
|
+
var import_tool = require("./tool");
|
|
28
|
+
const requests = (0, import_tool.defineTabTool)({
|
|
29
|
+
capability: "core",
|
|
30
|
+
schema: {
|
|
31
|
+
name: "browser_network_requests",
|
|
32
|
+
title: "List network requests",
|
|
33
|
+
description: "Returns all network requests since loading the page",
|
|
34
|
+
inputSchema: import_zodBundle.z.object({
|
|
35
|
+
static: import_zodBundle.z.boolean().default(false).describe("Whether to include successful static resources like images, fonts, scripts, etc. Defaults to false."),
|
|
36
|
+
requestBody: import_zodBundle.z.boolean().default(false).describe("Whether to include request body. Defaults to false."),
|
|
37
|
+
requestHeaders: import_zodBundle.z.boolean().default(false).describe("Whether to include request headers. Defaults to false."),
|
|
38
|
+
filter: import_zodBundle.z.string().optional().describe('Only return requests whose URL matches this regexp (e.g. "/api/.*user").'),
|
|
39
|
+
filename: import_zodBundle.z.string().optional().describe("Filename to save the network requests to. If not provided, requests are returned as text.")
|
|
40
|
+
}),
|
|
41
|
+
type: "readOnly"
|
|
42
|
+
},
|
|
43
|
+
handle: async (tab, params, response) => {
|
|
44
|
+
const requests2 = await tab.requests();
|
|
45
|
+
const filter = params.filter ? new RegExp(params.filter) : void 0;
|
|
46
|
+
const text = [];
|
|
47
|
+
for (const request of requests2) {
|
|
48
|
+
if (!params.static && !isFetch(request) && isSuccessfulResponse(request))
|
|
49
|
+
continue;
|
|
50
|
+
if (filter) {
|
|
51
|
+
filter.lastIndex = 0;
|
|
52
|
+
if (!filter.test(request.url()))
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
text.push(await renderRequest(request, params.requestBody, params.requestHeaders));
|
|
56
|
+
}
|
|
57
|
+
await response.addResult("Network", text.join("\n"), { prefix: "network", ext: "log", suggestedFilename: params.filename });
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const networkClear = (0, import_tool.defineTabTool)({
|
|
61
|
+
capability: "core",
|
|
62
|
+
skillOnly: true,
|
|
63
|
+
schema: {
|
|
64
|
+
name: "browser_network_clear",
|
|
65
|
+
title: "Clear network requests",
|
|
66
|
+
description: "Clear all network requests",
|
|
67
|
+
inputSchema: import_zodBundle.z.object({}),
|
|
68
|
+
type: "readOnly"
|
|
69
|
+
},
|
|
70
|
+
handle: async (tab, params, response) => {
|
|
71
|
+
await tab.clearRequests();
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
function isSuccessfulResponse(request) {
|
|
75
|
+
if (request.failure())
|
|
76
|
+
return false;
|
|
77
|
+
const response = request.existingResponse();
|
|
78
|
+
return !!response && response.status() < 400;
|
|
79
|
+
}
|
|
80
|
+
function isFetch(request) {
|
|
81
|
+
return ["fetch", "xhr"].includes(request.resourceType());
|
|
82
|
+
}
|
|
83
|
+
async function renderRequest(request, includeBody = false, includeHeaders = false) {
|
|
84
|
+
const response = request.existingResponse();
|
|
85
|
+
const result = [];
|
|
86
|
+
result.push(`[${request.method().toUpperCase()}] ${request.url()}`);
|
|
87
|
+
if (response)
|
|
88
|
+
result.push(` => [${response.status()}] ${response.statusText()}`);
|
|
89
|
+
else if (request.failure())
|
|
90
|
+
result.push(` => [FAILED] ${request.failure()?.errorText ?? "Unknown error"}`);
|
|
91
|
+
if (includeHeaders) {
|
|
92
|
+
const headers = request.headers();
|
|
93
|
+
const headerLines = Object.entries(headers).map(([k, v]) => ` ${k}: ${v}`).join("\n");
|
|
94
|
+
if (headerLines)
|
|
95
|
+
result.push(`
|
|
96
|
+
Request headers:
|
|
97
|
+
${headerLines}`);
|
|
98
|
+
}
|
|
99
|
+
if (includeBody) {
|
|
100
|
+
const postData = request.postData();
|
|
101
|
+
if (postData)
|
|
102
|
+
result.push(`
|
|
103
|
+
Request body: ${postData}`);
|
|
104
|
+
}
|
|
105
|
+
return result.join("");
|
|
106
|
+
}
|
|
107
|
+
const networkStateSet = (0, import_tool.defineTool)({
|
|
108
|
+
capability: "network",
|
|
109
|
+
schema: {
|
|
110
|
+
name: "browser_network_state_set",
|
|
111
|
+
title: "Set network state",
|
|
112
|
+
description: "Sets the browser network state to online or offline. When offline, all network requests will fail.",
|
|
113
|
+
inputSchema: import_zodBundle.z.object({
|
|
114
|
+
state: import_zodBundle.z.enum(["online", "offline"]).describe('Set to "offline" to simulate offline mode, "online" to restore network connectivity')
|
|
115
|
+
}),
|
|
116
|
+
type: "action"
|
|
117
|
+
},
|
|
118
|
+
handle: async (context, params, response) => {
|
|
119
|
+
const browserContext = await context.ensureBrowserContext();
|
|
120
|
+
const offline = params.state === "offline";
|
|
121
|
+
await browserContext.setOffline(offline);
|
|
122
|
+
response.addTextResult(`Network is now ${params.state}`);
|
|
123
|
+
response.addCode(`await page.context().setOffline(${offline});`);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
var network_default = [
|
|
127
|
+
requests,
|
|
128
|
+
networkClear,
|
|
129
|
+
networkStateSet
|
|
130
|
+
];
|
|
131
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
132
|
+
0 && (module.exports = {
|
|
133
|
+
isFetch,
|
|
134
|
+
renderRequest
|
|
135
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var pdf_exports = {};
|
|
20
|
+
__export(pdf_exports, {
|
|
21
|
+
default: () => pdf_default
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(pdf_exports);
|
|
24
|
+
var import_zodBundle = require("../../zodBundle");
|
|
25
|
+
var import_stringUtils = require("../../utils/isomorphic/stringUtils");
|
|
26
|
+
var import_tool = require("./tool");
|
|
27
|
+
const pdfSchema = import_zodBundle.z.object({
|
|
28
|
+
filename: import_zodBundle.z.string().optional().describe("File name to save the pdf to. Defaults to `page-{timestamp}.pdf` if not specified. Prefer relative file names to stay within the output directory.")
|
|
29
|
+
});
|
|
30
|
+
const pdf = (0, import_tool.defineTabTool)({
|
|
31
|
+
capability: "pdf",
|
|
32
|
+
schema: {
|
|
33
|
+
name: "browser_pdf_save",
|
|
34
|
+
title: "Save as PDF",
|
|
35
|
+
description: "Save page as PDF",
|
|
36
|
+
inputSchema: pdfSchema,
|
|
37
|
+
type: "readOnly"
|
|
38
|
+
},
|
|
39
|
+
handle: async (tab, params, response) => {
|
|
40
|
+
const data = await tab.page.pdf();
|
|
41
|
+
const result = await response.resolveClientFile({ prefix: "page", ext: "pdf", suggestedFilename: params.filename }, "Page as pdf");
|
|
42
|
+
await response.addFileResult(result, data);
|
|
43
|
+
response.addCode(`await page.pdf(${(0, import_stringUtils.formatObject)({ path: result.relativeName })});`);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
var pdf_default = [
|
|
47
|
+
pdf
|
|
48
|
+
];
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var response_exports = {};
|
|
30
|
+
__export(response_exports, {
|
|
31
|
+
Response: () => Response,
|
|
32
|
+
parseResponse: () => parseResponse,
|
|
33
|
+
renderTabMarkdown: () => renderTabMarkdown,
|
|
34
|
+
renderTabsMarkdown: () => renderTabsMarkdown,
|
|
35
|
+
requestDebug: () => requestDebug
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(response_exports);
|
|
38
|
+
var import_fs = __toESM(require("fs"));
|
|
39
|
+
var import_path = __toESM(require("path"));
|
|
40
|
+
var import_utilsBundle = require("../../utilsBundle");
|
|
41
|
+
var import_tab = require("./tab");
|
|
42
|
+
var import_screenshot = require("./screenshot");
|
|
43
|
+
const requestDebug = (0, import_utilsBundle.debug)("pw:mcp:request");
|
|
44
|
+
class Response {
|
|
45
|
+
constructor(context, toolName, toolArgs, relativeTo) {
|
|
46
|
+
this._results = [];
|
|
47
|
+
this._errors = [];
|
|
48
|
+
this._code = [];
|
|
49
|
+
this._includeSnapshot = "none";
|
|
50
|
+
this._isClose = false;
|
|
51
|
+
this._imageResults = [];
|
|
52
|
+
this._context = context;
|
|
53
|
+
this.toolName = toolName;
|
|
54
|
+
this.toolArgs = toolArgs;
|
|
55
|
+
this._clientWorkspace = relativeTo ?? context.options.cwd;
|
|
56
|
+
}
|
|
57
|
+
_computRelativeTo(fileName) {
|
|
58
|
+
return import_path.default.relative(this._clientWorkspace, fileName);
|
|
59
|
+
}
|
|
60
|
+
async resolveClientFile(template, title) {
|
|
61
|
+
let fileName;
|
|
62
|
+
if (template.suggestedFilename)
|
|
63
|
+
fileName = await this.resolveClientFilename(template.suggestedFilename);
|
|
64
|
+
else
|
|
65
|
+
fileName = await this._context.outputFile(template, { origin: "llm" });
|
|
66
|
+
const relativeName = this._computRelativeTo(fileName);
|
|
67
|
+
const printableLink = `- [${title}](${relativeName})`;
|
|
68
|
+
return { fileName, relativeName, printableLink };
|
|
69
|
+
}
|
|
70
|
+
async resolveClientFilename(filename) {
|
|
71
|
+
return await this._context.workspaceFile(filename, this._clientWorkspace);
|
|
72
|
+
}
|
|
73
|
+
addTextResult(text) {
|
|
74
|
+
this._results.push(text);
|
|
75
|
+
}
|
|
76
|
+
async addResult(title, data, file) {
|
|
77
|
+
if (file.suggestedFilename || typeof data !== "string") {
|
|
78
|
+
const resolvedFile = await this.resolveClientFile(file, title);
|
|
79
|
+
await this.addFileResult(resolvedFile, data);
|
|
80
|
+
} else {
|
|
81
|
+
this.addTextResult(data);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async _writeFile(resolvedFile, data) {
|
|
85
|
+
if (typeof data === "string")
|
|
86
|
+
await import_fs.default.promises.writeFile(resolvedFile.fileName, this._redactSecrets(data), "utf-8");
|
|
87
|
+
else if (data)
|
|
88
|
+
await import_fs.default.promises.writeFile(resolvedFile.fileName, data);
|
|
89
|
+
}
|
|
90
|
+
async addFileResult(resolvedFile, data) {
|
|
91
|
+
await this._writeFile(resolvedFile, data);
|
|
92
|
+
this.addTextResult(resolvedFile.printableLink);
|
|
93
|
+
}
|
|
94
|
+
addFileLink(title, fileName) {
|
|
95
|
+
const relativeName = this._computRelativeTo(fileName);
|
|
96
|
+
this.addTextResult(`- [${title}](${relativeName})`);
|
|
97
|
+
}
|
|
98
|
+
async registerImageResult(data, imageType) {
|
|
99
|
+
this._imageResults.push({ data, imageType });
|
|
100
|
+
}
|
|
101
|
+
setClose() {
|
|
102
|
+
this._isClose = true;
|
|
103
|
+
}
|
|
104
|
+
addError(error) {
|
|
105
|
+
this._errors.push(error);
|
|
106
|
+
}
|
|
107
|
+
addCode(code) {
|
|
108
|
+
this._code.push(code);
|
|
109
|
+
}
|
|
110
|
+
setIncludeSnapshot() {
|
|
111
|
+
this._includeSnapshot = this._context.config.snapshot?.mode ?? "full";
|
|
112
|
+
}
|
|
113
|
+
setIncludeFullSnapshot(includeSnapshotFileName, selector, depth) {
|
|
114
|
+
this._includeSnapshot = "explicit";
|
|
115
|
+
this._includeSnapshotFileName = includeSnapshotFileName;
|
|
116
|
+
this._includeSnapshotDepth = depth;
|
|
117
|
+
this._includeSnapshotSelector = selector;
|
|
118
|
+
}
|
|
119
|
+
_redactSecrets(text) {
|
|
120
|
+
for (const [secretName, secretValue] of Object.entries(this._context.config.secrets ?? {})) {
|
|
121
|
+
if (!secretValue)
|
|
122
|
+
continue;
|
|
123
|
+
text = text.replaceAll(secretValue, `<secret>${secretName}</secret>`);
|
|
124
|
+
}
|
|
125
|
+
return text;
|
|
126
|
+
}
|
|
127
|
+
async serialize() {
|
|
128
|
+
const sections = await this._build();
|
|
129
|
+
const text = [];
|
|
130
|
+
for (const section of sections) {
|
|
131
|
+
if (!section.content.length)
|
|
132
|
+
continue;
|
|
133
|
+
text.push(`### ${section.title}`);
|
|
134
|
+
if (section.codeframe)
|
|
135
|
+
text.push(`\`\`\`${section.codeframe}`);
|
|
136
|
+
text.push(...section.content);
|
|
137
|
+
if (section.codeframe)
|
|
138
|
+
text.push("```");
|
|
139
|
+
}
|
|
140
|
+
const content = [
|
|
141
|
+
{
|
|
142
|
+
type: "text",
|
|
143
|
+
text: sanitizeUnicode(this._redactSecrets(text.join("\n")))
|
|
144
|
+
}
|
|
145
|
+
];
|
|
146
|
+
if (this._context.config.imageResponses !== "omit") {
|
|
147
|
+
for (const imageResult of this._imageResults) {
|
|
148
|
+
const scaledData = (0, import_screenshot.scaleImageToFitMessage)(imageResult.data, imageResult.imageType);
|
|
149
|
+
content.push({ type: "image", data: scaledData.toString("base64"), mimeType: imageResult.imageType === "png" ? "image/png" : "image/jpeg" });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
content,
|
|
154
|
+
...this._isClose ? { isClose: true } : {},
|
|
155
|
+
...sections.some((section) => section.isError) ? { isError: true } : {}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async _build() {
|
|
159
|
+
const sections = [];
|
|
160
|
+
const addSection = (title, content, codeframe) => {
|
|
161
|
+
const section = { title, content, isError: title === "Error", codeframe };
|
|
162
|
+
sections.push(section);
|
|
163
|
+
return content;
|
|
164
|
+
};
|
|
165
|
+
if (this._errors.length)
|
|
166
|
+
addSection("Error", this._errors);
|
|
167
|
+
if (this._results.length)
|
|
168
|
+
addSection("Result", this._results);
|
|
169
|
+
if (this._context.config.codegen !== "none" && this._code.length)
|
|
170
|
+
addSection("Ran Playwright code", this._code, "js");
|
|
171
|
+
const tabSnapshot = this._context.currentTab() ? await this._context.currentTabOrDie().captureSnapshot(this._includeSnapshotSelector, this._includeSnapshotDepth, this._clientWorkspace) : void 0;
|
|
172
|
+
const tabHeaders = await Promise.all(this._context.tabs().map((tab) => tab.headerSnapshot()));
|
|
173
|
+
if (this._includeSnapshot !== "none" || tabHeaders.some((header) => header.changed)) {
|
|
174
|
+
if (tabHeaders.length !== 1)
|
|
175
|
+
addSection("Open tabs", renderTabsMarkdown(tabHeaders));
|
|
176
|
+
addSection("Page", renderTabMarkdown(tabHeaders.find((h) => h.current) ?? tabHeaders[0]));
|
|
177
|
+
}
|
|
178
|
+
if (this._context.tabs().length === 0)
|
|
179
|
+
this._isClose = true;
|
|
180
|
+
if (tabSnapshot?.modalStates.length)
|
|
181
|
+
addSection("Modal state", (0, import_tab.renderModalStates)(this._context.config, tabSnapshot.modalStates));
|
|
182
|
+
if (tabSnapshot && this._includeSnapshot !== "none") {
|
|
183
|
+
if (this._includeSnapshot !== "explicit" || this._includeSnapshotFileName) {
|
|
184
|
+
const suggestedFilename = this._includeSnapshotFileName === "<auto>" ? void 0 : this._includeSnapshotFileName;
|
|
185
|
+
const resolvedFile = await this.resolveClientFile({ prefix: "page", ext: "yml", suggestedFilename }, "Snapshot");
|
|
186
|
+
await this._writeFile(resolvedFile, tabSnapshot.ariaSnapshot);
|
|
187
|
+
addSection("Snapshot", [resolvedFile.printableLink]);
|
|
188
|
+
} else {
|
|
189
|
+
addSection("Snapshot", [tabSnapshot.ariaSnapshot], "yaml");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const text = [];
|
|
193
|
+
if (tabSnapshot?.consoleLink)
|
|
194
|
+
text.push(`- New console entries: ${tabSnapshot.consoleLink}`);
|
|
195
|
+
if (tabSnapshot?.events.filter((event) => event.type !== "request").length) {
|
|
196
|
+
for (const event of tabSnapshot.events) {
|
|
197
|
+
if (event.type === "download-start")
|
|
198
|
+
text.push(`- Downloading file ${event.download.download.suggestedFilename()} ...`);
|
|
199
|
+
else if (event.type === "download-finish")
|
|
200
|
+
text.push(`- Downloaded file ${event.download.download.suggestedFilename()} to "${this._computRelativeTo(event.download.outputFile)}"`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (text.length)
|
|
204
|
+
addSection("Events", text);
|
|
205
|
+
const pausedDetails = this._context.debugger().pausedDetails();
|
|
206
|
+
if (pausedDetails) {
|
|
207
|
+
addSection("Paused", [
|
|
208
|
+
`- ${pausedDetails.title} at ${this._computRelativeTo(pausedDetails.location.file)}${pausedDetails.location.line ? ":" + pausedDetails.location.line : ""}`,
|
|
209
|
+
"- Use any tools to explore and interact, resume by calling resume/step-over/pause-at"
|
|
210
|
+
]);
|
|
211
|
+
}
|
|
212
|
+
return sections;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function renderTabMarkdown(tab) {
|
|
216
|
+
const lines = [`- Page URL: ${tab.url}`];
|
|
217
|
+
if (tab.title)
|
|
218
|
+
lines.push(`- Page Title: ${tab.title}`);
|
|
219
|
+
if (tab.console.errors || tab.console.warnings)
|
|
220
|
+
lines.push(`- Console: ${tab.console.errors} errors, ${tab.console.warnings} warnings`);
|
|
221
|
+
return lines;
|
|
222
|
+
}
|
|
223
|
+
function renderTabsMarkdown(tabs) {
|
|
224
|
+
if (!tabs.length)
|
|
225
|
+
return ["No open tabs. Navigate to a URL to create one."];
|
|
226
|
+
const lines = [];
|
|
227
|
+
for (let i = 0; i < tabs.length; i++) {
|
|
228
|
+
const tab = tabs[i];
|
|
229
|
+
const current = tab.current ? " (current)" : "";
|
|
230
|
+
lines.push(`- ${i}:${current} [${tab.title}](${tab.url})`);
|
|
231
|
+
}
|
|
232
|
+
return lines;
|
|
233
|
+
}
|
|
234
|
+
function sanitizeUnicode(text) {
|
|
235
|
+
return text.toWellFormed?.() ?? text;
|
|
236
|
+
}
|
|
237
|
+
function parseSections(text) {
|
|
238
|
+
const sections = /* @__PURE__ */ new Map();
|
|
239
|
+
const sectionHeaders = text.split(/^### /m).slice(1);
|
|
240
|
+
for (const section of sectionHeaders) {
|
|
241
|
+
const firstNewlineIndex = section.indexOf("\n");
|
|
242
|
+
if (firstNewlineIndex === -1)
|
|
243
|
+
continue;
|
|
244
|
+
const sectionName = section.substring(0, firstNewlineIndex);
|
|
245
|
+
const sectionContent = section.substring(firstNewlineIndex + 1).trim();
|
|
246
|
+
sections.set(sectionName, sectionContent);
|
|
247
|
+
}
|
|
248
|
+
return sections;
|
|
249
|
+
}
|
|
250
|
+
function parseResponse(response, cwd) {
|
|
251
|
+
if (response.content?.[0].type !== "text")
|
|
252
|
+
return void 0;
|
|
253
|
+
const text = response.content[0].text;
|
|
254
|
+
const sections = parseSections(text);
|
|
255
|
+
const error = sections.get("Error");
|
|
256
|
+
const result = sections.get("Result");
|
|
257
|
+
const code = sections.get("Ran Playwright code");
|
|
258
|
+
const tabs = sections.get("Open tabs");
|
|
259
|
+
const page = sections.get("Page");
|
|
260
|
+
const snapshotSection = sections.get("Snapshot");
|
|
261
|
+
const events = sections.get("Events");
|
|
262
|
+
const modalState = sections.get("Modal state");
|
|
263
|
+
const paused = sections.get("Paused");
|
|
264
|
+
const codeNoFrame = code?.replace(/^```js\n/, "").replace(/\n```$/, "");
|
|
265
|
+
const isError = response.isError;
|
|
266
|
+
const attachments = response.content.length > 1 ? response.content.slice(1) : void 0;
|
|
267
|
+
let snapshot;
|
|
268
|
+
let inlineSnapshot;
|
|
269
|
+
if (snapshotSection) {
|
|
270
|
+
const match = snapshotSection.match(/\[Snapshot\]\(([^)]+)\)/);
|
|
271
|
+
if (match) {
|
|
272
|
+
if (cwd) {
|
|
273
|
+
try {
|
|
274
|
+
snapshot = import_fs.default.readFileSync(import_path.default.resolve(cwd, match[1]), "utf-8");
|
|
275
|
+
} catch {
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
} else {
|
|
279
|
+
inlineSnapshot = snapshotSection.replace(/^```yaml\n?/, "").replace(/\n?```$/, "");
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return {
|
|
283
|
+
result,
|
|
284
|
+
error,
|
|
285
|
+
code: codeNoFrame,
|
|
286
|
+
tabs,
|
|
287
|
+
page,
|
|
288
|
+
snapshot,
|
|
289
|
+
inlineSnapshot,
|
|
290
|
+
events,
|
|
291
|
+
modalState,
|
|
292
|
+
paused,
|
|
293
|
+
isError,
|
|
294
|
+
attachments,
|
|
295
|
+
text
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
299
|
+
0 && (module.exports = {
|
|
300
|
+
Response,
|
|
301
|
+
parseResponse,
|
|
302
|
+
renderTabMarkdown,
|
|
303
|
+
renderTabsMarkdown,
|
|
304
|
+
requestDebug
|
|
305
|
+
});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var route_exports = {};
|
|
20
|
+
__export(route_exports, {
|
|
21
|
+
default: () => route_default
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(route_exports);
|
|
24
|
+
var import_zodBundle = require("../../zodBundle");
|
|
25
|
+
var import_tool = require("./tool");
|
|
26
|
+
const route = (0, import_tool.defineTool)({
|
|
27
|
+
capability: "network",
|
|
28
|
+
schema: {
|
|
29
|
+
name: "browser_route",
|
|
30
|
+
title: "Mock network requests",
|
|
31
|
+
description: "Set up a route to mock network requests matching a URL pattern",
|
|
32
|
+
inputSchema: import_zodBundle.z.object({
|
|
33
|
+
pattern: import_zodBundle.z.string().describe('URL pattern to match (e.g., "**/api/users", "**/*.{png,jpg}")'),
|
|
34
|
+
status: import_zodBundle.z.number().optional().describe("HTTP status code to return (default: 200)"),
|
|
35
|
+
body: import_zodBundle.z.string().optional().describe("Response body (text or JSON string)"),
|
|
36
|
+
contentType: import_zodBundle.z.string().optional().describe('Content-Type header (e.g., "application/json", "text/html")'),
|
|
37
|
+
headers: import_zodBundle.z.array(import_zodBundle.z.string()).optional().describe('Headers to add in "Name: Value" format'),
|
|
38
|
+
removeHeaders: import_zodBundle.z.string().optional().describe("Comma-separated list of header names to remove from request")
|
|
39
|
+
}),
|
|
40
|
+
type: "action"
|
|
41
|
+
},
|
|
42
|
+
handle: async (context, params, response) => {
|
|
43
|
+
const addHeaders = params.headers ? Object.fromEntries(params.headers.map((h) => {
|
|
44
|
+
const colonIndex = h.indexOf(":");
|
|
45
|
+
return [h.substring(0, colonIndex).trim(), h.substring(colonIndex + 1).trim()];
|
|
46
|
+
})) : void 0;
|
|
47
|
+
const removeHeaders = params.removeHeaders ? params.removeHeaders.split(",").map((h) => h.trim()) : void 0;
|
|
48
|
+
const handler = async (route2) => {
|
|
49
|
+
if (params.body !== void 0 || params.status !== void 0) {
|
|
50
|
+
await route2.fulfill({
|
|
51
|
+
status: params.status ?? 200,
|
|
52
|
+
contentType: params.contentType,
|
|
53
|
+
body: params.body
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const headers = { ...route2.request().headers() };
|
|
58
|
+
if (addHeaders) {
|
|
59
|
+
for (const [key, value] of Object.entries(addHeaders))
|
|
60
|
+
headers[key] = value;
|
|
61
|
+
}
|
|
62
|
+
if (removeHeaders) {
|
|
63
|
+
for (const header of removeHeaders)
|
|
64
|
+
delete headers[header.toLowerCase()];
|
|
65
|
+
}
|
|
66
|
+
await route2.continue({ headers });
|
|
67
|
+
};
|
|
68
|
+
const entry = {
|
|
69
|
+
pattern: params.pattern,
|
|
70
|
+
status: params.status,
|
|
71
|
+
body: params.body,
|
|
72
|
+
contentType: params.contentType,
|
|
73
|
+
addHeaders,
|
|
74
|
+
removeHeaders,
|
|
75
|
+
handler
|
|
76
|
+
};
|
|
77
|
+
await context.addRoute(entry);
|
|
78
|
+
response.addTextResult(`Route added for pattern: ${params.pattern}`);
|
|
79
|
+
response.addCode(`await page.context().route('${params.pattern}', async route => { /* route handler */ });`);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const routeList = (0, import_tool.defineTool)({
|
|
83
|
+
capability: "network",
|
|
84
|
+
schema: {
|
|
85
|
+
name: "browser_route_list",
|
|
86
|
+
title: "List network routes",
|
|
87
|
+
description: "List all active network routes",
|
|
88
|
+
inputSchema: import_zodBundle.z.object({}),
|
|
89
|
+
type: "readOnly"
|
|
90
|
+
},
|
|
91
|
+
handle: async (context, params, response) => {
|
|
92
|
+
const routes = context.routes();
|
|
93
|
+
if (routes.length === 0) {
|
|
94
|
+
response.addTextResult("No active routes");
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const lines = [];
|
|
98
|
+
for (let i = 0; i < routes.length; i++) {
|
|
99
|
+
const route2 = routes[i];
|
|
100
|
+
const details = [];
|
|
101
|
+
if (route2.status !== void 0)
|
|
102
|
+
details.push(`status=${route2.status}`);
|
|
103
|
+
if (route2.body !== void 0)
|
|
104
|
+
details.push(`body=${route2.body.length > 50 ? route2.body.substring(0, 50) + "..." : route2.body}`);
|
|
105
|
+
if (route2.contentType)
|
|
106
|
+
details.push(`contentType=${route2.contentType}`);
|
|
107
|
+
if (route2.addHeaders)
|
|
108
|
+
details.push(`addHeaders=${JSON.stringify(route2.addHeaders)}`);
|
|
109
|
+
if (route2.removeHeaders)
|
|
110
|
+
details.push(`removeHeaders=${route2.removeHeaders.join(",")}`);
|
|
111
|
+
const detailsStr = details.length ? ` (${details.join(", ")})` : "";
|
|
112
|
+
lines.push(`${i + 1}. ${route2.pattern}${detailsStr}`);
|
|
113
|
+
}
|
|
114
|
+
response.addTextResult(lines.join("\n"));
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
const unroute = (0, import_tool.defineTool)({
|
|
118
|
+
capability: "network",
|
|
119
|
+
schema: {
|
|
120
|
+
name: "browser_unroute",
|
|
121
|
+
title: "Remove network routes",
|
|
122
|
+
description: "Remove network routes matching a pattern (or all routes if no pattern specified)",
|
|
123
|
+
inputSchema: import_zodBundle.z.object({
|
|
124
|
+
pattern: import_zodBundle.z.string().optional().describe("URL pattern to unroute (omit to remove all routes)")
|
|
125
|
+
}),
|
|
126
|
+
type: "action"
|
|
127
|
+
},
|
|
128
|
+
handle: async (context, params, response) => {
|
|
129
|
+
const removed = await context.removeRoute(params.pattern);
|
|
130
|
+
if (params.pattern)
|
|
131
|
+
response.addTextResult(`Removed ${removed} route(s) for pattern: ${params.pattern}`);
|
|
132
|
+
else
|
|
133
|
+
response.addTextResult(`Removed all ${removed} route(s)`);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
var route_default = [
|
|
137
|
+
route,
|
|
138
|
+
routeList,
|
|
139
|
+
unroute
|
|
140
|
+
];
|