@webmcp-bridge/playwright 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 holon-run
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,9 @@
1
+ /**
2
+ * This module attaches the WebMCP bridge into a Playwright page and wires tool calls to a Node-side adapter.
3
+ * It depends on core bridge types and Playwright page hooks for init script injection and exposed callbacks.
4
+ */
5
+ import type { Page } from "playwright";
6
+ import type { PlaywrightBridgeOptions, PlaywrightBridgeSession } from "./types.js";
7
+ export declare function attachBridge(page: Page, options: PlaywrightBridgeOptions): Promise<PlaywrightBridgeSession>;
8
+ export declare function detachBridge(page: Page): Promise<void>;
9
+ //# sourceMappingURL=attach.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attach.d.ts","sourceRoot":"","sources":["../src/attach.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EAExB,MAAM,YAAY,CAAC;AAgFpB,wBAAsB,YAAY,CAChC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,uBAAuB,CAAC,CAuDlC;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5D"}
package/dist/attach.js ADDED
@@ -0,0 +1,135 @@
1
+ /**
2
+ * This module attaches the WebMCP bridge into a Playwright page and wires tool calls to a Node-side adapter.
3
+ * It depends on core bridge types and Playwright page hooks for init script injection and exposed callbacks.
4
+ */
5
+ import { randomUUID } from "node:crypto";
6
+ const SESSIONS = new WeakMap();
7
+ const INJECT_SCRIPT = String.raw `
8
+ (() => {
9
+ const navAny = navigator;
10
+ const globalAny = window;
11
+ const hasNative =
12
+ navAny &&
13
+ navAny.modelContext &&
14
+ typeof navAny.modelContext.registerTool === "function" &&
15
+ typeof navAny.modelContext.unregisterTool === "function";
16
+ if (hasNative) {
17
+ globalAny.__WEBMCP_BRIDGE_MODE__ = "native";
18
+ return;
19
+ }
20
+
21
+ const tools = new Map();
22
+ const contexts = [];
23
+
24
+ const modelContext = {
25
+ provideContext: async (context) => {
26
+ contexts.push(context || {});
27
+ },
28
+ clearContext: async () => {
29
+ contexts.splice(0, contexts.length);
30
+ tools.clear();
31
+ },
32
+ registerTool: async (tool) => {
33
+ const name = tool && typeof tool.name === "string" ? tool.name : "";
34
+ if (!name) {
35
+ throw new Error("tool.name is required");
36
+ }
37
+ if (tools.has(name)) {
38
+ throw new Error("tool already registered");
39
+ }
40
+ tools.set(name, tool);
41
+ },
42
+ unregisterTool: async (name) => {
43
+ tools.delete(String(name || ""));
44
+ },
45
+ callTool: async (name, input) => {
46
+ const local = tools.get(String(name || ""));
47
+ if (local && typeof local.execute === "function") {
48
+ return await local.execute(input || {});
49
+ }
50
+ if (typeof globalAny.__WEBMCP_BRIDGE_CALL__ !== "function") {
51
+ throw new Error("bridge call handler missing");
52
+ }
53
+ return await globalAny.__WEBMCP_BRIDGE_CALL__(String(name || ""), input || {});
54
+ },
55
+ };
56
+
57
+ try {
58
+ Object.defineProperty(navAny, "modelContext", {
59
+ configurable: true,
60
+ enumerable: false,
61
+ writable: false,
62
+ value: modelContext,
63
+ });
64
+ } catch {
65
+ navAny.modelContext = modelContext;
66
+ }
67
+ globalAny.__webmcpBridge = {
68
+ list: () =>
69
+ Array.from(tools.values()).map((tool) => ({
70
+ name: tool.name,
71
+ description: tool.description || "",
72
+ inputSchema: tool.inputSchema || { type: "object" },
73
+ annotations: tool.annotations || {},
74
+ })),
75
+ invoke: async (name, input) => {
76
+ return await modelContext.callTool(String(name || ""), input || {});
77
+ },
78
+ };
79
+ globalAny.__WEBMCP_BRIDGE_MODE__ = "shim";
80
+ })();
81
+ `;
82
+ export async function attachBridge(page, options) {
83
+ const existing = SESSIONS.get(page);
84
+ if (existing) {
85
+ return existing.session;
86
+ }
87
+ const preferNative = options.preferNative ?? true;
88
+ const reinjectOnNavigate = options.reinjectOnNavigate ?? true;
89
+ const adapter = options.adapter;
90
+ await adapter.start?.({ page });
91
+ const exposedName = `__WEBMCP_BRIDGE_CALL__${randomUUID().replaceAll("-", "")}`;
92
+ await page.exposeFunction(exposedName, async (name, input) => {
93
+ return await adapter.callTool({ name, input }, { page });
94
+ });
95
+ const bindScript = `window.__WEBMCP_BRIDGE_CALL__ = window.${exposedName};`;
96
+ await page.addInitScript(INJECT_SCRIPT);
97
+ await page.addInitScript(bindScript);
98
+ await page.evaluate(INJECT_SCRIPT);
99
+ await page.evaluate(bindScript);
100
+ const mode = await page.evaluate(() => {
101
+ const globalAny = window;
102
+ return globalAny.__WEBMCP_BRIDGE_MODE__ ?? "shim";
103
+ });
104
+ const onNavigate = async () => {
105
+ await page.evaluate(bindScript);
106
+ };
107
+ if (reinjectOnNavigate) {
108
+ page.on("framenavigated", () => {
109
+ void onNavigate();
110
+ });
111
+ }
112
+ const session = {
113
+ id: randomUUID(),
114
+ mode: preferNative && mode === "native" ? "native" : "shim",
115
+ page,
116
+ adapter,
117
+ };
118
+ const cleanup = async () => {
119
+ if (reinjectOnNavigate) {
120
+ page.removeAllListeners("framenavigated");
121
+ }
122
+ await adapter.stop?.({ page });
123
+ };
124
+ SESSIONS.set(page, { session, cleanup });
125
+ return session;
126
+ }
127
+ export async function detachBridge(page) {
128
+ const existing = SESSIONS.get(page);
129
+ if (!existing) {
130
+ return;
131
+ }
132
+ await existing.cleanup();
133
+ SESSIONS.delete(page);
134
+ }
135
+ //# sourceMappingURL=attach.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attach.js","sourceRoot":"","sources":["../src/attach.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * This module provides a native-first WebMCP page gateway with polyfill and adapter-shim fallback wiring.
3
+ * It depends on Playwright page APIs and shared bridge types so local-mcp can call browser WebMCP uniformly.
4
+ */
5
+ import type { Page } from "playwright";
6
+ import type { CreateWebMcpPageGatewayOptions, WebMcpPageGateway } from "./types.js";
7
+ export declare function createWebMcpPageGateway(page: Page, options?: CreateWebMcpPageGatewayOptions): Promise<WebMcpPageGateway>;
8
+ export declare function closeWebMcpPageGateway(page: Page): Promise<void>;
9
+ //# sourceMappingURL=gateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EACV,8BAA8B,EAE9B,iBAAiB,EAElB,MAAM,YAAY,CAAC;AA4GpB,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,8BAA8B,GACvC,OAAO,CAAC,iBAAiB,CAAC,CAkJ5B;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtE"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * This module provides a native-first WebMCP page gateway with polyfill and adapter-shim fallback wiring.
3
+ * It depends on Playwright page APIs and shared bridge types so local-mcp can call browser WebMCP uniformly.
4
+ */
5
+ import { randomUUID } from "node:crypto";
6
+ const INJECT_SCRIPT = String.raw `
7
+ (() => {
8
+ const navAny = navigator;
9
+ const globalAny = window;
10
+ const hasNative =
11
+ navAny &&
12
+ navAny.modelContext &&
13
+ typeof navAny.modelContext.registerTool === "function" &&
14
+ typeof navAny.modelContext.unregisterTool === "function";
15
+
16
+ if (hasNative) {
17
+ globalAny.__webmcpBridge = {
18
+ list: async () => {
19
+ if (typeof navAny.modelContext.listTools === "function") {
20
+ const nativeTools = await navAny.modelContext.listTools();
21
+ return Array.isArray(nativeTools) ? nativeTools : [];
22
+ }
23
+ return [];
24
+ },
25
+ invoke: async (name, input) => {
26
+ if (typeof navAny.modelContext.callTool !== "function") {
27
+ throw new Error("native modelContext callTool is not available");
28
+ }
29
+ return await navAny.modelContext.callTool(String(name || ""), input || {});
30
+ },
31
+ };
32
+ globalAny.__WEBMCP_BRIDGE_MODE__ = "native";
33
+ return;
34
+ }
35
+
36
+ const tools = new Map();
37
+ const contexts = [];
38
+
39
+ const modelContext = {
40
+ provideContext: async (context) => {
41
+ contexts.push(context || {});
42
+ },
43
+ clearContext: async () => {
44
+ contexts.splice(0, contexts.length);
45
+ tools.clear();
46
+ },
47
+ registerTool: async (tool) => {
48
+ const name = tool && typeof tool.name === "string" ? tool.name : "";
49
+ if (!name) {
50
+ throw new Error("tool.name is required");
51
+ }
52
+ if (tools.has(name)) {
53
+ throw new Error("tool already registered");
54
+ }
55
+ tools.set(name, tool);
56
+ },
57
+ unregisterTool: async (name) => {
58
+ tools.delete(String(name || ""));
59
+ },
60
+ callTool: async (name, input) => {
61
+ const local = tools.get(String(name || ""));
62
+ if (local && typeof local.execute === "function") {
63
+ return await local.execute(input || {});
64
+ }
65
+ if (typeof globalAny.__WEBMCP_BRIDGE_CALL__ !== "function") {
66
+ throw new Error("bridge call handler missing");
67
+ }
68
+ return await globalAny.__WEBMCP_BRIDGE_CALL__(String(name || ""), input || {});
69
+ },
70
+ };
71
+
72
+ try {
73
+ Object.defineProperty(navAny, "modelContext", {
74
+ configurable: true,
75
+ enumerable: false,
76
+ writable: false,
77
+ value: modelContext,
78
+ });
79
+ } catch {
80
+ navAny.modelContext = modelContext;
81
+ }
82
+
83
+ globalAny.__webmcpBridge = {
84
+ list: async () =>
85
+ Array.from(tools.values()).map((tool) => {
86
+ const output = {
87
+ name: tool.name,
88
+ inputSchema: tool.inputSchema || { type: "object" },
89
+ annotations: tool.annotations || {},
90
+ };
91
+ if (typeof tool.description === "string" && tool.description.trim()) {
92
+ return { ...output, description: tool.description };
93
+ }
94
+ return output;
95
+ }),
96
+ invoke: async (name, input) => {
97
+ return await modelContext.callTool(String(name || ""), input || {});
98
+ },
99
+ };
100
+
101
+ globalAny.__WEBMCP_BRIDGE_MODE__ = "polyfill";
102
+ })();
103
+ `;
104
+ const SESSIONS = new WeakMap();
105
+ export async function createWebMcpPageGateway(page, options) {
106
+ const existing = SESSIONS.get(page);
107
+ if (existing) {
108
+ return existing.gateway;
109
+ }
110
+ const fallbackAdapter = options?.fallbackAdapter;
111
+ const preferNative = options?.preferNative ?? true;
112
+ const reinjectOnNavigate = options?.reinjectOnNavigate ?? true;
113
+ let fallbackStarted = false;
114
+ let fallbackStartPromise;
115
+ const ensureFallbackStarted = async () => {
116
+ if (!fallbackAdapter || fallbackStarted) {
117
+ return;
118
+ }
119
+ if (!fallbackStartPromise) {
120
+ fallbackStartPromise = (async () => {
121
+ await fallbackAdapter.start?.({ page });
122
+ fallbackStarted = true;
123
+ })();
124
+ }
125
+ await fallbackStartPromise;
126
+ };
127
+ const exposedName = `__WEBMCP_BRIDGE_CALL__${randomUUID().replaceAll("-", "")}`;
128
+ await page.exposeFunction(exposedName, async (name, input) => {
129
+ if (!fallbackAdapter) {
130
+ return {
131
+ error: {
132
+ code: "NOT_SUPPORTED",
133
+ message: "fallback adapter is not configured",
134
+ },
135
+ };
136
+ }
137
+ await ensureFallbackStarted();
138
+ return await fallbackAdapter.callTool({ name, input }, { page });
139
+ });
140
+ const bindScript = `window.__WEBMCP_BRIDGE_CALL__ = window.${exposedName};`;
141
+ await page.addInitScript(INJECT_SCRIPT);
142
+ await page.addInitScript(bindScript);
143
+ await page.evaluate(INJECT_SCRIPT);
144
+ await page.evaluate(bindScript);
145
+ const detectedMode = await page.evaluate(() => {
146
+ const globalAny = window;
147
+ return globalAny.__WEBMCP_BRIDGE_MODE__ ?? "polyfill";
148
+ });
149
+ const mode = preferNative && detectedMode === "native"
150
+ ? "native"
151
+ : fallbackAdapter
152
+ ? "adapter-shim"
153
+ : "polyfill";
154
+ if (mode === "adapter-shim") {
155
+ await ensureFallbackStarted();
156
+ }
157
+ const rebindOnNavigate = () => {
158
+ void page.evaluate(bindScript).catch(() => {
159
+ // Ignore transient navigation races; the init script will rebind on next document.
160
+ });
161
+ };
162
+ if (reinjectOnNavigate) {
163
+ page.on("framenavigated", rebindOnNavigate);
164
+ }
165
+ const gateway = {
166
+ id: randomUUID(),
167
+ mode,
168
+ page,
169
+ listTools: async () => {
170
+ if (mode === "adapter-shim" && fallbackAdapter) {
171
+ await ensureFallbackStarted();
172
+ const adapterTools = await fallbackAdapter.listTools({ page });
173
+ return adapterTools.map((tool) => ({
174
+ ...tool,
175
+ inputSchema: tool.inputSchema ?? { type: "object" },
176
+ }));
177
+ }
178
+ return await page.evaluate(async () => {
179
+ const globalAny = window;
180
+ const list = globalAny.__webmcpBridge?.list;
181
+ if (typeof list !== "function") {
182
+ return [];
183
+ }
184
+ const tools = await list();
185
+ return Array.isArray(tools) ? tools : [];
186
+ });
187
+ },
188
+ callTool: async (name, input) => {
189
+ const payload = {
190
+ callName: name,
191
+ callInput: input,
192
+ };
193
+ const result = await page.evaluate(async ({ callName, callInput }) => {
194
+ const globalAny = window;
195
+ const invoke = globalAny.__webmcpBridge?.invoke;
196
+ if (typeof invoke !== "function") {
197
+ throw new Error("WebMCP bridge invoke handler missing");
198
+ }
199
+ return await invoke(String(callName || ""), callInput ?? {});
200
+ }, payload);
201
+ return result;
202
+ },
203
+ close: async () => {
204
+ const session = SESSIONS.get(page);
205
+ if (!session) {
206
+ return;
207
+ }
208
+ await session.cleanup();
209
+ SESSIONS.delete(page);
210
+ },
211
+ };
212
+ const cleanup = async () => {
213
+ if (reinjectOnNavigate) {
214
+ const pageEvents = page;
215
+ if (typeof pageEvents.removeListener === "function") {
216
+ pageEvents.removeListener("framenavigated", rebindOnNavigate);
217
+ }
218
+ else if (typeof pageEvents.removeAllListeners === "function") {
219
+ pageEvents.removeAllListeners("framenavigated");
220
+ }
221
+ }
222
+ if (fallbackStarted) {
223
+ await fallbackAdapter?.stop?.({ page });
224
+ }
225
+ };
226
+ SESSIONS.set(page, { gateway, cleanup });
227
+ return gateway;
228
+ }
229
+ export async function closeWebMcpPageGateway(page) {
230
+ const session = SESSIONS.get(page);
231
+ if (!session) {
232
+ return;
233
+ }
234
+ await session.cleanup();
235
+ SESSIONS.delete(page);
236
+ }
237
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * This module exposes Playwright gateway public APIs.
3
+ * It depends on type and gateway modules to provide browser WebMCP integration entrypoints.
4
+ */
5
+ export * from "./types.js";
6
+ export * from "./gateway.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * This module exposes Playwright gateway public APIs.
3
+ * It depends on type and gateway modules to provide browser WebMCP integration entrypoints.
4
+ */
5
+ export * from "./types.js";
6
+ export * from "./gateway.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * This module defines Playwright WebMCP gateway and fallback adapter contracts.
3
+ * It is depended on by gateway lifecycle implementation and adapter packages.
4
+ */
5
+ import type { JsonValue } from "@webmcp-bridge/core";
6
+ import type { Page } from "playwright";
7
+ export type WebMcpToolDefinition = {
8
+ name: string;
9
+ description?: string;
10
+ inputSchema?: JsonValue;
11
+ annotations?: {
12
+ readOnlyHint?: boolean;
13
+ };
14
+ };
15
+ export type AdapterManifest = {
16
+ id: string;
17
+ displayName: string;
18
+ version: string;
19
+ bridgeApiVersion: string;
20
+ defaultUrl?: string;
21
+ hostPatterns: string[];
22
+ authProbeTool?: string;
23
+ };
24
+ export type SiteAdapter = {
25
+ name: string;
26
+ listTools: (context: {
27
+ page: Page;
28
+ }) => Promise<Array<WebMcpToolDefinition>>;
29
+ callTool: (request: {
30
+ name: string;
31
+ input: JsonValue;
32
+ }, context: {
33
+ page: Page;
34
+ }) => Promise<JsonValue>;
35
+ start?: (context: {
36
+ page: Page;
37
+ }) => Promise<void>;
38
+ stop?: (context: {
39
+ page: Page;
40
+ }) => Promise<void>;
41
+ };
42
+ export type SiteAdapterModule = {
43
+ manifest: AdapterManifest;
44
+ createAdapter: () => SiteAdapter;
45
+ };
46
+ export type CreateWebMcpPageGatewayOptions = {
47
+ fallbackAdapter?: SiteAdapter;
48
+ preferNative?: boolean;
49
+ reinjectOnNavigate?: boolean;
50
+ };
51
+ export type WebMcpPageGateway = {
52
+ id: string;
53
+ mode: "native" | "polyfill" | "adapter-shim";
54
+ page: Page;
55
+ listTools: () => Promise<WebMcpToolDefinition[]>;
56
+ callTool: (name: string, input: JsonValue) => Promise<JsonValue>;
57
+ close: () => Promise<void>;
58
+ };
59
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE;QACZ,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,KAAK,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,EAAE,OAAO,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACvG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,eAAe,CAAC;IAC1B,aAAa,EAAE,MAAM,WAAW,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,cAAc,CAAC;IAC7C,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,MAAM,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACjD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACjE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * This module defines Playwright WebMCP gateway and fallback adapter contracts.
3
+ * It is depended on by gateway lifecycle implementation and adapter packages.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@webmcp-bridge/playwright",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "dependencies": {
17
+ "playwright": "^1.58.2",
18
+ "@webmcp-bridge/core": "0.1.0"
19
+ },
20
+ "license": "MIT",
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.build.json",
23
+ "typecheck": "tsc --noEmit -p tsconfig.json"
24
+ }
25
+ }