@narumitw/pi-chrome-devtools 0.53.1 → 0.53.3
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/README.md +89 -230
- package/dist/chunks/{browser-settings-menu-REIU7C3Q.js → browser-settings-menu-SR7KLZT6.js} +16 -42
- package/dist/chunks/browser-settings-menu-SR7KLZT6.js.map +7 -0
- package/dist/chunks/{chunk-GTTYS5GT.js → chunk-4KMN4SFF.js} +2 -2
- package/dist/chunks/chunk-4KMN4SFF.js.map +7 -0
- package/dist/chunks/{chunk-SRT3UUIP.js → chunk-F5VG35UI.js} +23 -74
- package/dist/chunks/chunk-F5VG35UI.js.map +7 -0
- package/dist/chunks/{chunk-YJVYJ2L2.js → chunk-MZCGM6D3.js} +43 -48
- package/dist/chunks/chunk-MZCGM6D3.js.map +7 -0
- package/dist/chunks/{menu-H5HMVGHI.js → menu-YR4VRT7D.js} +10 -23
- package/dist/chunks/menu-YR4VRT7D.js.map +7 -0
- package/dist/chunks/{tools-6P7EUX37.js → tools-6R7Z6HWJ.js} +17 -59
- package/dist/chunks/tools-6R7Z6HWJ.js.map +7 -0
- package/dist/index.ts +23 -48
- package/dist/index.ts.map +2 -2
- package/docs/browser-setup.md +147 -0
- package/package.json +54 -55
- package/src/browser-manager.ts +872 -942
- package/src/browser-settings-menu.ts +315 -350
- package/src/cdp-client.ts +381 -398
- package/src/chrome-devtools.ts +205 -232
- package/src/display.ts +35 -0
- package/src/lazy-tools.ts +158 -181
- package/src/menu.ts +409 -446
- package/src/render.ts +74 -84
- package/src/runtime.ts +137 -140
- package/src/screenshot.ts +170 -186
- package/src/settings.ts +472 -523
- package/src/tool-names.ts +8 -14
- package/src/tool-selector.ts +245 -289
- package/src/tools.ts +218 -226
- package/src/webmcp/discovery.ts +184 -188
- package/src/webmcp/policy.ts +296 -329
- package/src/webmcp/protocol.ts +324 -337
- package/src/webmcp/tools.ts +136 -147
- package/dist/chunks/browser-settings-menu-REIU7C3Q.js.map +0 -7
- package/dist/chunks/chunk-GTTYS5GT.js.map +0 -7
- package/dist/chunks/chunk-SRT3UUIP.js.map +0 -7
- package/dist/chunks/chunk-YJVYJ2L2.js.map +0 -7
- package/dist/chunks/menu-H5HMVGHI.js.map +0 -7
- package/dist/chunks/tools-6P7EUX37.js.map +0 -7
package/src/webmcp/tools.ts
CHANGED
|
@@ -2,189 +2,178 @@ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
|
2
2
|
import { managedBrowserForOwner } from "../browser-manager.js";
|
|
3
3
|
import { getPage, resolvePage, textResult } from "../cdp-client.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
beginWebMcpOperation,
|
|
6
|
+
currentWebMcpGeneration,
|
|
7
|
+
webMcpEnabled,
|
|
8
|
+
webMcpOperationIsCurrent,
|
|
9
|
+
webMcpSessionSignal,
|
|
10
10
|
} from "../runtime.js";
|
|
11
11
|
import { discoverWebMcpTools, invokeDiscoveredWebMcpTool } from "./discovery.js";
|
|
12
12
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
boundedWebMcpDiscovery,
|
|
14
|
+
boundedWebMcpJson,
|
|
15
|
+
normalizeWebMcpInput,
|
|
16
|
+
requireMatchingWebMcpTool,
|
|
17
|
+
sanitizeWebMcpDisplay,
|
|
18
|
+
validateWebMcpInput,
|
|
19
|
+
type WebMcpToolIdentity,
|
|
20
|
+
webMcpConfirmationMessage,
|
|
21
|
+
webMcpErrorMessage,
|
|
22
|
+
webMcpIdentity,
|
|
23
23
|
} from "./policy.js";
|
|
24
24
|
|
|
25
25
|
interface ListInput {
|
|
26
|
-
|
|
26
|
+
pageId?: string;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
interface CallInput extends Omit<WebMcpToolIdentity, "name"> {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
input: Record<string, unknown>;
|
|
31
|
+
toolName: string;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export async function executeWebMcpListTool(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
params: ListInput,
|
|
36
|
+
toolSignal: AbortSignal | undefined,
|
|
37
|
+
ctx: ExtensionContext,
|
|
38
38
|
) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
} catch (error) {
|
|
69
|
-
throw safeToolError(error);
|
|
70
|
-
}
|
|
39
|
+
try {
|
|
40
|
+
requireWebMcpEnabled(ctx.sessionManager);
|
|
41
|
+
const preflightGeneration = currentWebMcpGeneration(ctx.sessionManager);
|
|
42
|
+
const preflightSignal = combinedSignal(ctx.sessionManager, toolSignal);
|
|
43
|
+
preflightSignal.throwIfAborted();
|
|
44
|
+
const page = await resolvePage(params.pageId, {
|
|
45
|
+
sessionOwner: ctx.sessionManager,
|
|
46
|
+
signal: preflightSignal,
|
|
47
|
+
});
|
|
48
|
+
preflightSignal.throwIfAborted();
|
|
49
|
+
requireCurrentPreflight(ctx.sessionManager, preflightGeneration);
|
|
50
|
+
const operation = beginWebMcpOperation(ctx.sessionManager, toolSignal);
|
|
51
|
+
try {
|
|
52
|
+
const tools = await discoverWebMcpTools(page, operation);
|
|
53
|
+
assertCurrent(operation);
|
|
54
|
+
const published = boundedWebMcpDiscovery({ id: page.id, title: page.title, url: page.url }, tools);
|
|
55
|
+
return textResult(published.text, {
|
|
56
|
+
page: { id: page.id, url: page.url },
|
|
57
|
+
toolCount: tools.length,
|
|
58
|
+
publishedToolCount: published.included.length,
|
|
59
|
+
truncated: published.truncated,
|
|
60
|
+
identities: published.included.map(webMcpIdentity),
|
|
61
|
+
});
|
|
62
|
+
} finally {
|
|
63
|
+
operation.dispose();
|
|
64
|
+
}
|
|
65
|
+
} catch (error) {
|
|
66
|
+
throw safeToolError(error);
|
|
67
|
+
}
|
|
71
68
|
}
|
|
72
69
|
|
|
73
70
|
export async function executeWebMcpCallTool(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
params: CallInput,
|
|
72
|
+
toolSignal: AbortSignal | undefined,
|
|
73
|
+
ctx: ExtensionContext,
|
|
77
74
|
) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
operation.dispose();
|
|
131
|
-
}
|
|
132
|
-
} catch (error) {
|
|
133
|
-
throw safeToolError(error);
|
|
134
|
-
}
|
|
75
|
+
try {
|
|
76
|
+
requireWebMcpEnabled(ctx.sessionManager);
|
|
77
|
+
if (!ctx.hasUI || (ctx.mode !== "tui" && ctx.mode !== "rpc")) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
"chrome_devtools_webmcp_call_tool requires observable confirmation in TUI or RPC mode and is unavailable in print or JSON mode.",
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
const input = normalizeWebMcpInput(params.input);
|
|
83
|
+
const expected = expectedIdentity(params);
|
|
84
|
+
const preflightGeneration = currentWebMcpGeneration(ctx.sessionManager);
|
|
85
|
+
const preflightSignal = combinedSignal(ctx.sessionManager, toolSignal);
|
|
86
|
+
preflightSignal.throwIfAborted();
|
|
87
|
+
const page = await getPage(params.pageId, {
|
|
88
|
+
sessionOwner: ctx.sessionManager,
|
|
89
|
+
signal: preflightSignal,
|
|
90
|
+
});
|
|
91
|
+
preflightSignal.throwIfAborted();
|
|
92
|
+
requireCurrentPreflight(ctx.sessionManager, preflightGeneration);
|
|
93
|
+
const operation = beginWebMcpOperation(ctx.sessionManager, toolSignal);
|
|
94
|
+
try {
|
|
95
|
+
const discovered = await discoverWebMcpTools(page, operation);
|
|
96
|
+
const current = requireMatchingWebMcpTool(discovered, expected);
|
|
97
|
+
const validatedInput = validateWebMcpInput(current.inputSchema, input);
|
|
98
|
+
assertCurrent(operation);
|
|
99
|
+
const confirmed = await ctx.ui.confirm(
|
|
100
|
+
`Allow WebMCP tool: ${sanitizeWebMcpDisplay(current.name, 256)}`,
|
|
101
|
+
webMcpConfirmationMessage(current, validatedInput, usesManagedProfile(ctx.sessionManager)),
|
|
102
|
+
{ signal: operation.signal },
|
|
103
|
+
);
|
|
104
|
+
assertCurrent(operation);
|
|
105
|
+
if (!confirmed) {
|
|
106
|
+
throw new DOMException("WebMCP tool call cancelled by the user.", "AbortError");
|
|
107
|
+
}
|
|
108
|
+
const invocation = await invokeDiscoveredWebMcpTool(page, expected, validatedInput, operation);
|
|
109
|
+
assertCurrent(operation);
|
|
110
|
+
const published = boundedWebMcpJson({
|
|
111
|
+
status: "completed",
|
|
112
|
+
tool: webMcpIdentity(invocation.tool),
|
|
113
|
+
output: invocation.output,
|
|
114
|
+
});
|
|
115
|
+
return textResult(published.text, {
|
|
116
|
+
invocationId: invocation.invocationId,
|
|
117
|
+
tool: webMcpIdentity(invocation.tool),
|
|
118
|
+
truncated: published.truncated,
|
|
119
|
+
output: published.text,
|
|
120
|
+
});
|
|
121
|
+
} finally {
|
|
122
|
+
operation.dispose();
|
|
123
|
+
}
|
|
124
|
+
} catch (error) {
|
|
125
|
+
throw safeToolError(error);
|
|
126
|
+
}
|
|
135
127
|
}
|
|
136
128
|
|
|
137
129
|
function requireWebMcpEnabled(owner: object) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
130
|
+
if (!webMcpEnabled(owner)) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
"WebMCP is disabled. Enable the experimental user setting in /chrome-devtools settings, then make the WebMCP gateway tools available.",
|
|
133
|
+
);
|
|
134
|
+
}
|
|
143
135
|
}
|
|
144
136
|
|
|
145
137
|
function combinedSignal(owner: object, toolSignal: AbortSignal | undefined) {
|
|
146
|
-
|
|
147
|
-
|
|
138
|
+
const sessionSignal = webMcpSessionSignal(owner);
|
|
139
|
+
return toolSignal ? AbortSignal.any([toolSignal, sessionSignal]) : sessionSignal;
|
|
148
140
|
}
|
|
149
141
|
|
|
150
142
|
function requireCurrentPreflight(owner: object, generation: number) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
"AbortError",
|
|
156
|
-
);
|
|
157
|
-
}
|
|
143
|
+
requireWebMcpEnabled(owner);
|
|
144
|
+
if (generation !== currentWebMcpGeneration(owner)) {
|
|
145
|
+
throw new DOMException("The WebMCP operation became stale during page resolution.", "AbortError");
|
|
146
|
+
}
|
|
158
147
|
}
|
|
159
148
|
|
|
160
149
|
function expectedIdentity(params: CallInput): WebMcpToolIdentity {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
150
|
+
return {
|
|
151
|
+
sessionGeneration: params.sessionGeneration,
|
|
152
|
+
pageId: params.pageId,
|
|
153
|
+
documentId: params.documentId,
|
|
154
|
+
frameId: params.frameId,
|
|
155
|
+
frameOrigin: params.frameOrigin,
|
|
156
|
+
name: params.toolName,
|
|
157
|
+
schemaDigest: params.schemaDigest,
|
|
158
|
+
};
|
|
170
159
|
}
|
|
171
160
|
|
|
172
161
|
function assertCurrent(operation: ReturnType<typeof beginWebMcpOperation>) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
162
|
+
operation.signal.throwIfAborted();
|
|
163
|
+
if (!webMcpOperationIsCurrent(operation)) {
|
|
164
|
+
throw new DOMException("The WebMCP operation became stale.", "AbortError");
|
|
165
|
+
}
|
|
177
166
|
}
|
|
178
167
|
|
|
179
168
|
function usesManagedProfile(owner: object) {
|
|
180
|
-
|
|
181
|
-
|
|
169
|
+
const managedBrowser = managedBrowserForOwner(owner);
|
|
170
|
+
return Boolean(managedBrowser?.ready && !managedBrowser.exited);
|
|
182
171
|
}
|
|
183
172
|
|
|
184
173
|
function safeToolError(error: unknown) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
174
|
+
const message = webMcpErrorMessage(error);
|
|
175
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
176
|
+
return new DOMException(message, "AbortError");
|
|
177
|
+
}
|
|
178
|
+
return new Error(message);
|
|
190
179
|
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/browser-settings-menu.ts"],
|
|
4
|
-
"sourcesContent": ["import { isAbsolute } from \"node:path\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { shutdownManagedBrowser, syncManagedBrowserSettings } from \"./browser-manager.js\";\nimport {\n\tapplyAvailableChromeDevtoolsTools,\n\tconfiguredChromeDevtoolsTools,\n\tsetChromeDevtoolsSessionOwner,\n} from \"./lazy-tools.js\";\nimport {\n\tapplyRuntimeBrowserSettings,\n\tapplyRuntimeWebMcpSetting,\n\tinvalidateWebMcpOperations,\n\tstate,\n\twebMcpEnabled,\n} from \"./runtime.js\";\nimport {\n\ttype BrowserSettingsPatch,\n\ttype BrowserSettingsSource,\n\tloadSettings,\n\tparseBrowserEndpoint,\n\ttype SettingsLoadResult,\n\tsaveBrowserSettings,\n\tsaveWebMcpSettings,\n} from \"./settings.js\";\nimport { sanitizeChromeDevtoolsDisplay } from \"./tool-selector.js\";\n\ntype BrowserSettingsScreen = \"settings\" | \"endpoint\" | \"executable\" | \"extensions\";\ntype BrowserSettingsAction =\n\t| \"open-endpoint\"\n\t| \"save-endpoint\"\n\t| \"set-auto-launch\"\n\t| \"set-webmcp\"\n\t| \"open-executable\"\n\t| \"save-executable\"\n\t| \"show-extensions\";\n\ninterface BrowserSettingsMenuState {\n\tload: SettingsLoadResult;\n}\n\ntype CommandContext = ExtensionCommandContext;\n\nexport async function showChromeDevtoolsBrowserSettings(\n\tpi: ExtensionAPI,\n\tctx: CommandContext,\n\tgeneration: number,\n): Promise<{ closeParent: boolean }> {\n\tsetChromeDevtoolsSessionOwner(pi, ctx.sessionManager);\n\tconst ownerSignal = state.sessionController.signal;\n\tconst isCurrent = () => generation === state.sessionGeneration && !ownerSignal.aborted;\n\tconst projectTrusted = ctx.isProjectTrusted();\n\tconst menu = defineMenu<BrowserSettingsMenuState, BrowserSettingsScreen, BrowserSettingsAction>({\n\t\tstart: \"settings\",\n\t\tscreens: {\n\t\t\tsettings: ({ state: current }) => {\n\t\t\t\tif (current.load.userFile.kind === \"invalid\") return invalidSettingsScreen(current.load);\n\t\t\t\tconst browser = current.load.effectiveBrowser;\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"settings\",\n\t\t\t\t\ttitle: \"Chrome DevTools Browser settings\",\n\t\t\t\t\tlines: settingsContextLines(current.load),\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"endpoint\",\n\t\t\t\t\t\t\tlabel: \"DevTools endpoint\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t'HTTP origin with an explicit port; enter \"default\" to restore 127.0.0.1:9222.',\n\t\t\t\t\t\t\tcurrentValue: sanitizeChromeDevtoolsDisplay(browser.endpoint),\n\t\t\t\t\t\t\taction: \"open-endpoint\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"auto-launch\",\n\t\t\t\t\t\t\tlabel: \"Auto-launch\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Launch an isolated managed browser when a local endpoint is unavailable.\",\n\t\t\t\t\t\t\tcurrentValue: browser.autoLaunchEnabled ? \"On\" : \"Off\",\n\t\t\t\t\t\t\tvalues: [\"On\", \"Off\"],\n\t\t\t\t\t\t\taction: \"set-auto-launch\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"executable\",\n\t\t\t\t\t\t\tlabel: \"Browser executable\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t'Absolute executable path; enter \"automatic\" to restore browser discovery.',\n\t\t\t\t\t\t\tcurrentValue: sanitizeChromeDevtoolsDisplay(browser.executablePath ?? \"Automatic\"),\n\t\t\t\t\t\t\taction: \"open-executable\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"webmcp\",\n\t\t\t\t\t\t\tlabel: \"WebMCP \u00B7 Experimental\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Allow user-confirmed calls to page-provided WebMCP tools in this browser session.\",\n\t\t\t\t\t\t\tcurrentValue: current.load.effectiveWebMcpEnabled ? \"On\" : \"Off\",\n\t\t\t\t\t\t\tvalues: [\"On\", \"Off\"],\n\t\t\t\t\t\t\taction: \"set-webmcp\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: \"extensions\",\n\t\t\t\t\t\t\tlabel: \"Unpacked extensions\",\n\t\t\t\t\t\t\tdescription: \"Inspect trusted extension paths configured in user or project JSON.\",\n\t\t\t\t\t\t\tcurrentValue: `${browser.extensionPaths.length} configured`,\n\t\t\t\t\t\t\taction: \"show-extensions\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t},\n\t\t\tendpoint: ({ state: current }) => ({\n\t\t\t\tkind: \"input\",\n\t\t\t\ttitle: \"DevTools endpoint\",\n\t\t\t\tlines: [\n\t\t\t\t\tsanitizeChromeDevtoolsDisplay(\n\t\t\t\t\t\t`Current effective endpoint: ${current.load.effectiveBrowser.endpoint}`,\n\t\t\t\t\t),\n\t\t\t\t\t'Enter an HTTP origin with an explicit port, or \"default\".',\n\t\t\t\t],\n\t\t\t\tplaceholder: \"http://127.0.0.1:9222\",\n\t\t\t\taction: \"save-endpoint\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\texecutable: ({ state: current }) => ({\n\t\t\t\tkind: \"input\",\n\t\t\t\ttitle: \"Browser executable\",\n\t\t\t\tlines: [\n\t\t\t\t\tsanitizeChromeDevtoolsDisplay(\n\t\t\t\t\t\t`Current effective executable: ${current.load.effectiveBrowser.executablePath ?? \"automatic discovery\"}`,\n\t\t\t\t\t),\n\t\t\t\t\t'Enter an absolute path, or \"automatic\".',\n\t\t\t\t],\n\t\t\t\tplaceholder: \"absolute browser executable path\",\n\t\t\t\taction: \"save-executable\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\textensions: ({ state: current }) => ({\n\t\t\t\tkind: \"detail\",\n\t\t\t\ttitle: \"Unpacked extensions\",\n\t\t\t\tlines: extensionDetailLines(current.load),\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\t\"open-endpoint\": () => ({ kind: \"to\", screen: \"endpoint\" }),\n\t\t\t\"save-endpoint\": async ({ value, signal }) => {\n\t\t\t\tif (value === undefined) return { kind: \"rejected\" };\n\t\t\t\tlet endpoint: string | null;\n\t\t\t\ttry {\n\t\t\t\t\tconst trimmed = value.trim();\n\t\t\t\t\tendpoint =\n\t\t\t\t\t\ttrimmed.toLowerCase() === \"default\" ? null : parseBrowserEndpoint(trimmed).endpoint;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tnotifySaveFailure(ctx, error);\n\t\t\t\t\treturn { kind: \"rejected\" };\n\t\t\t\t}\n\t\t\t\tconst saved = await saveAndApplyBrowserPatch(\n\t\t\t\t\tctx,\n\t\t\t\t\tgeneration,\n\t\t\t\t\townerSignal,\n\t\t\t\t\tsignal,\n\t\t\t\t\tprojectTrusted,\n\t\t\t\t\t{ endpoint },\n\t\t\t\t);\n\t\t\t\tif (!saved) return { kind: \"rejected\" };\n\t\t\t\tnotifyEffectiveSave(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"endpoint\",\n\t\t\t\t\tsaved.effectiveBrowser.endpoint,\n\t\t\t\t\tsaved.effectiveBrowser.endpointSource,\n\t\t\t\t);\n\t\t\t\treturn { kind: \"back\" };\n\t\t\t},\n\t\t\t\"set-auto-launch\": async ({ value, signal }) => {\n\t\t\t\tif (value !== \"On\" && value !== \"Off\") return { kind: \"rejected\" };\n\t\t\t\tconst saved = await saveAndApplyBrowserPatch(\n\t\t\t\t\tctx,\n\t\t\t\t\tgeneration,\n\t\t\t\t\townerSignal,\n\t\t\t\t\tsignal,\n\t\t\t\t\tprojectTrusted,\n\t\t\t\t\t{ autoLaunch: value === \"On\" },\n\t\t\t\t);\n\t\t\t\tif (!saved) return { kind: \"rejected\" };\n\t\t\t\tnotifyEffectiveSave(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"auto-launch\",\n\t\t\t\t\tsaved.effectiveBrowser.autoLaunchEnabled ? \"On\" : \"Off\",\n\t\t\t\t\tsaved.effectiveBrowser.autoLaunchSource,\n\t\t\t\t);\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t\t\"set-webmcp\": async ({ value, signal }) => {\n\t\t\t\tif (value !== \"On\" && value !== \"Off\") return { kind: \"rejected\" };\n\t\t\t\tconst saved = await saveAndApplyWebMcpSetting(\n\t\t\t\t\tpi,\n\t\t\t\t\tctx,\n\t\t\t\t\tgeneration,\n\t\t\t\t\townerSignal,\n\t\t\t\t\tsignal,\n\t\t\t\t\tprojectTrusted,\n\t\t\t\t\tvalue === \"On\",\n\t\t\t\t);\n\t\t\t\tif (!saved) return { kind: \"rejected\" };\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\tsaved.effectiveWebMcpEnabled\n\t\t\t\t\t\t? \"Experimental WebMCP enabled. Every page-provided tool call requires confirmation. Choose gateway availability under Browser tools.\"\n\t\t\t\t\t\t: \"Experimental WebMCP disabled. Active WebMCP work was aborted and both gateway tools are unavailable.\",\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t\t\"open-executable\": () => ({ kind: \"to\", screen: \"executable\" }),\n\t\t\t\"save-executable\": async ({ value, signal }) => {\n\t\t\t\tif (value === undefined) return { kind: \"rejected\" };\n\t\t\t\tconst trimmed = value.trim();\n\t\t\t\tconst reset = [\"automatic\", \"default\", \"none\"].includes(trimmed.toLowerCase());\n\t\t\t\tif (!reset && (!trimmed || !isAbsolute(trimmed))) {\n\t\t\t\t\tnotifySaveFailure(ctx, new Error('Enter an absolute path or \"automatic\".'));\n\t\t\t\t\treturn { kind: \"rejected\" };\n\t\t\t\t}\n\t\t\t\tconst executablePath = reset ? null : trimmed;\n\t\t\t\tconst saved = await saveAndApplyBrowserPatch(\n\t\t\t\t\tctx,\n\t\t\t\t\tgeneration,\n\t\t\t\t\townerSignal,\n\t\t\t\t\tsignal,\n\t\t\t\t\tprojectTrusted,\n\t\t\t\t\t{ executablePath },\n\t\t\t\t);\n\t\t\t\tif (!saved) return { kind: \"rejected\" };\n\t\t\t\tnotifyEffectiveSave(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"browser executable\",\n\t\t\t\t\tsaved.effectiveBrowser.executablePath ?? \"automatic discovery\",\n\t\t\t\t\tsaved.effectiveBrowser.executablePathSource,\n\t\t\t\t);\n\t\t\t\treturn { kind: \"back\" };\n\t\t\t},\n\t\t\t\"show-extensions\": () => ({ kind: \"to\", screen: \"extensions\" }),\n\t\t},\n\t});\n\tconst result = await runMenu(ctx, menu, {\n\t\tgetState: async ({ signal }) => {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst load = await loadSettings({ cwd: ctx.cwd, projectTrusted });\n\t\t\tsignal.throwIfAborted();\n\t\t\treturn { load };\n\t\t},\n\t\tsignal: ownerSignal,\n\t\tisCurrent,\n\t\tonError: (currentCtx, error) =>\n\t\t\tcurrentCtx.ui.notify(\n\t\t\t\tsanitizeChromeDevtoolsDisplay(\n\t\t\t\t\t`Chrome DevTools browser settings failed: ${formatError(error)}`,\n\t\t\t\t),\n\t\t\t\t\"error\",\n\t\t\t),\n\t});\n\treturn { closeParent: result.kind === \"closed\" && result.reason === \"close\" };\n}\n\nasync function saveAndApplyBrowserPatch(\n\tctx: CommandContext,\n\tgeneration: number,\n\townerSignal: AbortSignal,\n\tactionSignal: AbortSignal,\n\tprojectTrusted: boolean,\n\tpatch: BrowserSettingsPatch,\n) {\n\ttry {\n\t\tawait ctx.waitForIdle();\n\t\tif (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n\t\tawait saveBrowserSettings(patch);\n\t\tif (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n\t\tinvalidateWebMcpOperations(ctx.sessionManager, \"Chrome DevTools browser configuration changed\");\n\t\tawait shutdownManagedBrowser(undefined, { owner: ctx.sessionManager });\n\t\tif (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n\t\tconst loaded = await loadSettings({ cwd: ctx.cwd, projectTrusted });\n\t\tif (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n\t\tapplyRuntimeBrowserSettings(loaded.effectiveBrowser, loaded.paths, projectTrusted);\n\t\tsyncManagedBrowserSettings(ctx.sessionManager, loaded.effectiveBrowser);\n\t\tstate.settingsNotice = loaded.notice;\n\t\treturn loaded;\n\t} catch (error) {\n\t\tif (isCurrent(generation, ownerSignal, actionSignal)) notifySaveFailure(ctx, error);\n\t\treturn false;\n\t}\n}\n\nasync function saveAndApplyWebMcpSetting(\n\tpi: ExtensionAPI,\n\tctx: CommandContext,\n\tgeneration: number,\n\townerSignal: AbortSignal,\n\tactionSignal: AbortSignal,\n\tprojectTrusted: boolean,\n\tenabled: boolean,\n) {\n\tconst previousEnabled = webMcpEnabled(ctx.sessionManager);\n\tconst previousTools = configuredChromeDevtoolsTools(pi);\n\ttry {\n\t\tawait ctx.waitForIdle();\n\t\tif (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n\t\tapplyRuntimeWebMcpSetting(enabled, ctx.sessionManager);\n\t\tapplyAvailableChromeDevtoolsTools(pi, previousTools);\n\t\tawait saveWebMcpSettings(enabled);\n\t\tif (!isOwnerCurrent(generation, ownerSignal)) return false;\n\t\tconst loaded = await loadSettings({ cwd: ctx.cwd, projectTrusted });\n\t\tif (!isOwnerCurrent(generation, ownerSignal)) return false;\n\t\tstate.settingsNotice = loaded.notice;\n\t\treturn loaded;\n\t} catch (error) {\n\t\tif (!isOwnerCurrent(generation, ownerSignal)) return false;\n\t\tlet rollbackError: unknown;\n\t\ttry {\n\t\t\tapplyRuntimeWebMcpSetting(previousEnabled, ctx.sessionManager);\n\t\t\tapplyAvailableChromeDevtoolsTools(pi, previousTools);\n\t\t} catch (caught) {\n\t\t\trollbackError = caught;\n\t\t}\n\t\tif (isCurrent(generation, ownerSignal, actionSignal)) {\n\t\t\tnotifySaveFailure(\n\t\t\t\tctx,\n\t\t\t\trollbackError\n\t\t\t\t\t? new Error(\n\t\t\t\t\t\t\t`${formatError(error)}; WebMCP rollback failed: ${formatError(rollbackError)}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t: error,\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t}\n}\n\nfunction isOwnerCurrent(generation: number, ownerSignal: AbortSignal) {\n\treturn generation === state.sessionGeneration && !ownerSignal.aborted;\n}\n\nfunction isCurrent(generation: number, ownerSignal: AbortSignal, actionSignal: AbortSignal) {\n\treturn isOwnerCurrent(generation, ownerSignal) && !actionSignal.aborted;\n}\n\nfunction invalidSettingsScreen(load: SettingsLoadResult) {\n\tconst reason =\n\t\tload.userFile.kind === \"invalid\"\n\t\t\t? load.userFile.reason\n\t\t\t: \"The user settings file is unavailable.\";\n\treturn {\n\t\tkind: \"detail\" as const,\n\t\ttitle: \"Chrome DevTools Browser settings \u00B7 Read only\",\n\t\tlines: [\n\t\t\tsanitizeChromeDevtoolsDisplay(\n\t\t\t\t`Fix the active user settings before saving; the file will not be overwritten. ${reason}`,\n\t\t\t),\n\t\t],\n\t\thint: \"back\" as const,\n\t};\n}\n\nfunction settingsContextLines(load: SettingsLoadResult) {\n\tconst browser = load.effectiveBrowser;\n\treturn [\n\t\t`User settings \u00B7 ${load.paths.user}`,\n\t\t`Effective sources: endpoint ${browser.endpointSource} \u00B7 auto-launch ${browser.autoLaunchSource} \u00B7 executable ${browser.executablePathSource}`,\n\t\t...(load.notice ? [`Warning: ${load.notice}`] : []),\n\t].map((line) => sanitizeChromeDevtoolsDisplay(line));\n}\n\nfunction extensionDetailLines(load: SettingsLoadResult) {\n\tconst browser = load.effectiveBrowser;\n\treturn [\n\t\t`Effective source: ${browser.extensionPathsSource}`,\n\t\t...(browser.extensionPaths.length > 0\n\t\t\t? browser.extensionPaths.map((extensionPath) => `- ${extensionPath}`)\n\t\t\t: [\"No unpacked extensions are configured.\"]),\n\t\t\"Edit browser.extensionPaths in the user JSON or a trusted project JSON, then run /reload.\",\n\t\t\"Unpacked extensions execute privileged browser code; load only paths you trust.\",\n\t].map((line) => sanitizeChromeDevtoolsDisplay(line));\n}\n\nfunction notifyEffectiveSave(\n\tctx: CommandContext,\n\tsetting: string,\n\teffectiveValue: string,\n\tsource: BrowserSettingsSource,\n) {\n\tconst overrideNotice =\n\t\tsource === \"environment\" ? \" The deprecated environment override remains effective.\" : \"\";\n\tctx.ui.notify(\n\t\tsanitizeChromeDevtoolsDisplay(\n\t\t\t`Chrome DevTools ${setting} saved. Effective ${setting}: ${effectiveValue} (${source}).${overrideNotice}`,\n\t\t),\n\t\t\"info\",\n\t);\n}\n\nfunction notifySaveFailure(ctx: CommandContext, error: unknown) {\n\tctx.ui.notify(\n\t\tsanitizeChromeDevtoolsDisplay(\n\t\t\t`Chrome DevTools browser settings save failed; previous settings remain active: ${formatError(error)}`,\n\t\t),\n\t\t\"warning\",\n\t);\n}\n\nfunction formatError(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["isCurrent"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/cdp-client.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tdevToolsEndpoint,\n\tensureDevToolsEndpoint,\n\tfetchDevToolsJson,\n\tformatPageListItem,\n\tlaunchHint,\n\twithEndpointRetry,\n} from \"./browser-manager.js\";\nimport {\n\tDEFAULT_ENDPOINT_WAIT_MS,\n\tDEFAULT_TIMEOUT_MS,\n\ttype DevToolsPage,\n\tstate,\n} from \"./runtime.js\";\n\ninterface CdpResponse<T = unknown> {\n\terror?: { code: number; data?: unknown; message: string };\n\tid: number;\n\tresult?: T;\n}\n\ninterface CdpEvent {\n\tmethod: string;\n\tparams?: unknown;\n}\n\ninterface PendingRequest {\n\tcleanup: () => void;\n\treject: (reason: unknown) => void;\n\tresolve: (value: unknown) => void;\n}\n\ninterface EventWaiter<T = unknown> {\n\tcleanup: () => void;\n\tmethod: string;\n\tpredicate: (params: unknown) => params is T;\n\treject: (reason: unknown) => void;\n\tresolve: (params: T) => void;\n}\n\nexport type CdpWebSocketConstructor = new (url: string | URL) => WebSocket;\n\nexport interface CdpOperationOptions {\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}\n\nexport interface CdpConnectOptions extends CdpOperationOptions {\n\twebSocketConstructor?: CdpWebSocketConstructor;\n}\n\nconst MAX_BUFFERED_EVENTS_PER_METHOD = 32;\nconst MAX_CDP_MESSAGE_BYTES = 8 * 1024 * 1024;\nconst activePageIds = new WeakMap<object, string>();\n\ninterface PageOperationOptions {\n\tsessionOwner?: object;\n\tsignal?: AbortSignal;\n\twaitMs?: number;\n}\n\nexport async function listPages(options: PageOperationOptions = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);\n\treturn withEndpointRetry(\n\t\tasync () => {\n\t\t\tconst pages = await fetchDevToolsJson<DevToolsPage[]>(\n\t\t\t\t\"/json/list\",\n\t\t\t\t{ signal: options.signal },\n\t\t\t\toptions.sessionOwner,\n\t\t\t);\n\t\t\treturn pages.filter((page) => page.type === \"page\" && page.webSocketDebuggerUrl);\n\t\t},\n\t\twaitMs,\n\t\toptions.signal,\n\t);\n}\n\nexport async function getPage(pageId: string, options: PageOperationOptions = {}) {\n\tconst pages = await listPages(options);\n\treturn requirePage(pageId, pages);\n}\n\nexport async function resolvePage(pageId?: string, options: PageOperationOptions = {}) {\n\tconst pages = await listPages(options);\n\tif (pageId) return requirePage(pageId, pages);\n\n\tconst page = resolveDefaultPage(pages, options.sessionOwner);\n\tif (!page) {\n\t\tthrow new Error(\n\t\t\t[\n\t\t\t\t`No Chrome pages found at ${devToolsEndpoint(options.sessionOwner)}.`,\n\t\t\t\t\"Use chrome_devtools_navigate with a URL to create a page, or open a Chrome tab manually.\",\n\t\t\t\tlaunchHint(options.sessionOwner),\n\t\t\t].join(\"\\n\"),\n\t\t);\n\t}\n\n\treturn page;\n}\n\nexport async function resolvePageForNavigation(\n\tpageId?: string,\n\toptions: PageOperationOptions = {},\n) {\n\tconst pages = await listPages(options);\n\tif (pageId) return { created: false, page: requirePage(pageId, pages) };\n\n\tconst page = resolveDefaultPage(pages, options.sessionOwner);\n\tif (page) return { created: false, page };\n\n\treturn { created: true, page: await createPage(\"about:blank\", options) };\n}\n\nfunction resolveDefaultPage(pages: DevToolsPage[], owner?: object) {\n\tconst activePageId = owner ? activePageIds.get(owner) : state.activePageId;\n\tif (!activePageId) return pages[0];\n\n\tconst activePage = pages.find((candidate) => candidate.id === activePageId);\n\tif (activePage) return activePage;\n\n\tsetActivePageId(owner, undefined);\n\treturn pages[0];\n}\n\nexport function setActivePageId(owner: object | undefined, pageId: string | undefined) {\n\tif (!owner) {\n\t\tstate.activePageId = pageId;\n\t\treturn;\n\t}\n\tif (pageId) activePageIds.set(owner, pageId);\n\telse activePageIds.delete(owner);\n}\n\nfunction requirePage(pageId: string, pages: DevToolsPage[]) {\n\tconst page = pages.find((candidate) => candidate.id === pageId);\n\tif (page) return page;\n\n\tconst availablePages = pages.map(formatPageListItem).join(\"\\n\");\n\tthrow new Error(\n\t\t[\n\t\t\t`Chrome DevTools page not found: ${pageId}.`,\n\t\t\tavailablePages\n\t\t\t\t? `Available pages:\\n${availablePages}`\n\t\t\t\t: \"No inspectable Chrome pages are currently available.\",\n\t\t].join(\"\\n\"),\n\t);\n}\n\nexport async function createPage(url: string, options: PageOperationOptions = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);\n\tconst page = await withEndpointRetry(\n\t\t() =>\n\t\t\tfetchDevToolsJson<DevToolsPage>(\n\t\t\t\t`/json/new?${encodeURIComponent(url)}`,\n\t\t\t\t{ method: \"PUT\", signal: options.signal },\n\t\t\t\toptions.sessionOwner,\n\t\t\t),\n\t\twaitMs,\n\t\toptions.signal,\n\t);\n\tif (page.type !== \"page\" || !page.webSocketDebuggerUrl) {\n\t\tthrow new Error(\"Chrome DevTools created a target that is not an inspectable page.\");\n\t}\n\n\treturn page;\n}\n\nexport function formatPage(page: DevToolsPage) {\n\treturn {\n\t\tid: page.id,\n\t\ttype: page.type,\n\t\ttitle: page.title,\n\t\turl: page.url,\n\t};\n}\n\nexport function textResult<T>(text: string, details: T) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text }],\n\t\tdetails,\n\t};\n}\n\nexport async function withCdp<T>(\n\tpage: DevToolsPage,\n\tcallback: (client: CdpClient) => Promise<T>,\n\toptions: CdpConnectOptions = {},\n) {\n\tif (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);\n\n\tconst client = await CdpClient.connect(page.webSocketDebuggerUrl, options);\n\ttry {\n\t\treturn await callback(client);\n\t} finally {\n\t\tclient.close();\n\t}\n}\n\nexport class CdpClient {\n\t#closed = false;\n\t#eventBuffers = new Map<string, unknown[]>();\n\t#eventWaiters = new Set<EventWaiter>();\n\t#nextId = 1;\n\t#pending = new Map<number, PendingRequest>();\n\treadonly #socket: WebSocket;\n\n\tprivate constructor(socket: WebSocket) {\n\t\tthis.#socket = socket;\n\t\tsocket.addEventListener(\"message\", this.onMessage);\n\t\tsocket.addEventListener(\"close\", this.onClose);\n\t\tsocket.addEventListener(\"error\", this.onError);\n\t}\n\n\tstatic connect(url: string, options: CdpConnectOptions = {}) {\n\t\tconst timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\t\tconst WebSocketImplementation = options.webSocketConstructor ?? WebSocket;\n\t\toptions.signal?.throwIfAborted();\n\t\treturn new Promise<CdpClient>((resolve, reject) => {\n\t\t\tconst socket = new WebSocketImplementation(url);\n\t\t\tlet settled = false;\n\t\t\tconst settle = (callback: () => void) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tsocket.removeEventListener(\"open\", onOpen);\n\t\t\t\tsocket.removeEventListener(\"error\", onConnectError);\n\t\t\t\tcallback();\n\t\t\t};\n\t\t\tconst onOpen = () => settle(() => resolve(new CdpClient(socket)));\n\t\t\tconst onConnectError = () =>\n\t\t\t\tsettle(() => {\n\t\t\t\t\tsocket.close();\n\t\t\t\t\treject(new Error(`Failed to connect to Chrome DevTools WebSocket: ${url}`));\n\t\t\t\t});\n\t\t\tconst onAbort = () =>\n\t\t\t\tsettle(() => {\n\t\t\t\t\tsocket.close();\n\t\t\t\t\treject(options.signal?.reason ?? abortError(\"Chrome DevTools connection aborted\"));\n\t\t\t\t});\n\t\t\tconst timeout = setTimeout(\n\t\t\t\t() =>\n\t\t\t\t\tsettle(() => {\n\t\t\t\t\t\tsocket.close();\n\t\t\t\t\t\treject(new Error(`Timed out connecting to Chrome DevTools WebSocket: ${url}`));\n\t\t\t\t\t}),\n\t\t\t\ttimeoutMs,\n\t\t\t);\n\t\t\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tsocket.addEventListener(\"open\", onOpen, { once: true });\n\t\t\tsocket.addEventListener(\"error\", onConnectError, { once: true });\n\t\t});\n\t}\n\n\tsend<T = unknown>(\n\t\tmethod: string,\n\t\tparams: Record<string, unknown> = {},\n\t\toptions: CdpOperationOptions = {},\n\t) {\n\t\tthis.throwIfClosed();\n\t\toptions.signal?.throwIfAborted();\n\t\tconst id = this.#nextId;\n\t\tthis.#nextId += 1;\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\tcleanup();\n\t\t\t\treject(options.signal?.reason ?? abortError(`CDP command aborted: ${method}`));\n\t\t\t};\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(new Error(`Timed out waiting for CDP response: ${method}`));\n\t\t\t}, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t};\n\t\t\tthis.#pending.set(id, {\n\t\t\t\tcleanup,\n\t\t\t\treject,\n\t\t\t\tresolve: resolve as (value: unknown) => void,\n\t\t\t});\n\t\t\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\ttry {\n\t\t\t\tthis.#socket.send(JSON.stringify({ id, method, params }));\n\t\t\t} catch (error) {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t}\n\t\t});\n\t}\n\n\twaitForEvent<T>(\n\t\tmethod: string,\n\t\tpredicate: (params: unknown) => params is T,\n\t\toptions: CdpOperationOptions = {},\n\t): Promise<T> {\n\t\tthis.throwIfClosed();\n\t\toptions.signal?.throwIfAborted();\n\t\tconst buffered = this.#eventBuffers.get(method) ?? [];\n\t\tfor (const [index, params] of buffered.entries()) {\n\t\t\tif (!predicate(params)) continue;\n\t\t\tbuffered.splice(index, 1);\n\t\t\tif (buffered.length === 0) this.#eventBuffers.delete(method);\n\t\t\treturn Promise.resolve(params);\n\t\t}\n\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst waiter = {} as EventWaiter<T>;\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.#eventWaiters.delete(waiter as EventWaiter);\n\t\t\t\tcleanup();\n\t\t\t\treject(options.signal?.reason ?? abortError(`CDP event wait aborted: ${method}`));\n\t\t\t};\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.#eventWaiters.delete(waiter as EventWaiter);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(new Error(`Timed out waiting for CDP event: ${method}`));\n\t\t\t}, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t};\n\t\t\tObject.assign(waiter, { cleanup, method, predicate, reject, resolve });\n\t\t\tthis.#eventWaiters.add(waiter as EventWaiter);\n\t\t\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t});\n\t}\n\n\tclose(reason: unknown = new Error(\"Chrome DevTools WebSocket closed\")) {\n\t\tif (this.#closed) return;\n\t\tthis.#closed = true;\n\t\tthis.#socket.removeEventListener(\"message\", this.onMessage);\n\t\tthis.#socket.removeEventListener(\"close\", this.onClose);\n\t\tthis.#socket.removeEventListener(\"error\", this.onError);\n\t\tthis.rejectAll(reason);\n\t\tthis.#eventBuffers.clear();\n\t\ttry {\n\t\t\tthis.#socket.close();\n\t\t} catch {\n\t\t\t// The transport is already unusable; pending work has still been rejected.\n\t\t}\n\t}\n\n\tprivate readonly onClose = () => {\n\t\tthis.close(new Error(\"Chrome DevTools WebSocket closed\"));\n\t};\n\n\tprivate readonly onError = () => {\n\t\tthis.close(new Error(\"Chrome DevTools WebSocket error\"));\n\t};\n\n\tprivate readonly onMessage = (event: MessageEvent) => {\n\t\tif (typeof event.data !== \"string\") {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent an unsupported binary message\"));\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\tevent.data.length > MAX_CDP_MESSAGE_BYTES ||\n\t\t\tBuffer.byteLength(event.data, \"utf8\") > MAX_CDP_MESSAGE_BYTES\n\t\t) {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket message exceeds the 8 MB limit\"));\n\t\t\treturn;\n\t\t}\n\t\tlet payload: unknown;\n\t\ttry {\n\t\t\tpayload = JSON.parse(event.data) as unknown;\n\t\t} catch {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent malformed JSON\"));\n\t\t\treturn;\n\t\t}\n\t\tif (!isRecord(payload)) {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent a malformed message\"));\n\t\t\treturn;\n\t\t}\n\t\tif (typeof payload.id === \"number\") {\n\t\t\tthis.handleResponse(payload as unknown as CdpResponse);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof payload.method !== \"string\") {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent a malformed event\"));\n\t\t\treturn;\n\t\t}\n\t\tthis.handleEvent(payload as unknown as CdpEvent);\n\t};\n\n\tprivate handleResponse(response: CdpResponse) {\n\t\tconst pending = this.#pending.get(response.id);\n\t\tif (!pending) return;\n\t\tthis.#pending.delete(response.id);\n\t\tpending.cleanup();\n\t\tif (response.error) {\n\t\t\tpending.reject(\n\t\t\t\tnew Error(\n\t\t\t\t\t`CDP error ${response.error.code}: ${response.error.message}${\n\t\t\t\t\t\tresponse.error.data === undefined ? \"\" : ` (${safeJson(response.error.data)})`\n\t\t\t\t\t}`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tpending.resolve(response.result);\n\t}\n\n\tprivate handleEvent(event: CdpEvent) {\n\t\tif (event.method === \"Inspector.detached\" || event.method === \"Target.detachedFromTarget\") {\n\t\t\tthis.close(new Error(`Chrome DevTools target detached: ${safeJson(event.params)}`));\n\t\t\treturn;\n\t\t}\n\t\tfor (const waiter of this.#eventWaiters) {\n\t\t\tif (waiter.method !== event.method) continue;\n\t\t\tlet matched: boolean;\n\t\t\ttry {\n\t\t\t\tmatched = waiter.predicate(event.params);\n\t\t\t} catch (error) {\n\t\t\t\tthis.#eventWaiters.delete(waiter);\n\t\t\t\twaiter.cleanup();\n\t\t\t\twaiter.reject(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!matched) continue;\n\t\t\tthis.#eventWaiters.delete(waiter);\n\t\t\twaiter.cleanup();\n\t\t\twaiter.resolve(event.params);\n\t\t\treturn;\n\t\t}\n\t\tconst buffer = this.#eventBuffers.get(event.method) ?? [];\n\t\tbuffer.push(event.params);\n\t\tif (buffer.length > MAX_BUFFERED_EVENTS_PER_METHOD) {\n\t\t\tthis.close(\n\t\t\t\tnew Error(\n\t\t\t\t\t`Chrome DevTools WebSocket buffered more than ${MAX_BUFFERED_EVENTS_PER_METHOD} ${event.method} events`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.#eventBuffers.set(event.method, buffer);\n\t}\n\n\tprivate rejectAll(reason: unknown) {\n\t\tfor (const [id, pending] of this.#pending) {\n\t\t\tthis.#pending.delete(id);\n\t\t\tpending.cleanup();\n\t\t\tpending.reject(reason);\n\t\t}\n\t\tfor (const waiter of this.#eventWaiters) {\n\t\t\tthis.#eventWaiters.delete(waiter);\n\t\t\twaiter.cleanup();\n\t\t\twaiter.reject(reason);\n\t\t}\n\t}\n\n\tprivate throwIfClosed() {\n\t\tif (this.#closed) throw new Error(\"Chrome DevTools WebSocket is closed\");\n\t}\n}\n\nfunction abortError(message: string) {\n\treturn new DOMException(message, \"AbortError\");\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction safeJson(value: unknown) {\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|