@zibby/mcp-browser 0.1.0 → 0.1.6

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.
@@ -1,301 +0,0 @@
1
- "use strict";
2
- const __defProp = Object.defineProperty;
3
- const __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- const __getOwnPropNames = Object.getOwnPropertyNames;
5
- const __hasOwnProp = Object.prototype.hasOwnProperty;
6
- const __export = (target, all) => {
7
- for (const name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- const __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (const 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
- const __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- const tab_exports = {};
20
- __export(tab_exports, {
21
- Tab: () => Tab,
22
- TabEvents: () => TabEvents,
23
- renderModalStates: () => renderModalStates
24
- });
25
- module.exports = __toCommonJS(tab_exports);
26
- const import_events = require("events");
27
- const import_utils = require("playwright-core/lib/utils");
28
- const import_utils2 = require("./tools/utils");
29
- const import_log = require("../log");
30
- const import_dialogs = require("./tools/dialogs");
31
- const import_files = require("./tools/files");
32
- const import_transform = require("../../transform/transform");
33
- const TabEvents = {
34
- modalState: "modalState"
35
- };
36
- class Tab extends import_events.EventEmitter {
37
- constructor(context, page, onPageClose) {
38
- super();
39
- this._lastTitle = "about:blank";
40
- this._consoleMessages = [];
41
- this._recentConsoleMessages = [];
42
- this._requests = /* @__PURE__ */ new Set();
43
- this._modalStates = [];
44
- this._downloads = [];
45
- this._needsFullSnapshot = false;
46
- this.context = context;
47
- this.page = page;
48
- this._onPageClose = onPageClose;
49
- page.on("console", (event) => this._handleConsoleMessage(messageToConsoleMessage(event)));
50
- page.on("pageerror", (error) => this._handleConsoleMessage(pageErrorToConsoleMessage(error)));
51
- page.on("request", (request) => this._requests.add(request));
52
- page.on("close", () => this._onClose());
53
- page.on("filechooser", (chooser) => {
54
- this.setModalState({
55
- type: "fileChooser",
56
- description: "File chooser",
57
- fileChooser: chooser,
58
- clearedBy: import_files.uploadFile.schema.name
59
- });
60
- });
61
- page.on("dialog", (dialog) => this._dialogShown(dialog));
62
- page.on("download", (download) => {
63
- void this._downloadStarted(download);
64
- });
65
- page.setDefaultNavigationTimeout(this.context.config.timeouts.navigation);
66
- page.setDefaultTimeout(this.context.config.timeouts.action);
67
- page[tabSymbol] = this;
68
- this.initializedPromise = this._initialize();
69
- }
70
- static forPage(page) {
71
- return page[tabSymbol];
72
- }
73
- static async collectConsoleMessages(page) {
74
- const result = [];
75
- const messages = await page.consoleMessages().catch(() => []);
76
- for (const message of messages)
77
- result.push(messageToConsoleMessage(message));
78
- const errors = await page.pageErrors().catch(() => []);
79
- for (const error of errors)
80
- result.push(pageErrorToConsoleMessage(error));
81
- return result;
82
- }
83
- async _initialize() {
84
- for (const message of await Tab.collectConsoleMessages(this.page))
85
- this._handleConsoleMessage(message);
86
- const requests = await this.page.requests().catch(() => []);
87
- for (const request of requests)
88
- this._requests.add(request);
89
- for (const initPage of this.context.config.browser.initPage || []) {
90
- try {
91
- const { default: func } = await (0, import_transform.requireOrImport)(initPage);
92
- await func({ page: this.page });
93
- } catch (e) {
94
- (0, import_log.logUnhandledError)(e);
95
- }
96
- }
97
- }
98
- modalStates() {
99
- return this._modalStates;
100
- }
101
- setModalState(modalState) {
102
- this._modalStates.push(modalState);
103
- this.emit(TabEvents.modalState, modalState);
104
- }
105
- clearModalState(modalState) {
106
- this._modalStates = this._modalStates.filter((state) => state !== modalState);
107
- }
108
- modalStatesMarkdown() {
109
- return renderModalStates(this.context, this.modalStates());
110
- }
111
- _dialogShown(dialog) {
112
- this.setModalState({
113
- type: "dialog",
114
- description: `"${dialog.type()}" dialog with message "${dialog.message()}"`,
115
- dialog,
116
- clearedBy: import_dialogs.handleDialog.schema.name
117
- });
118
- }
119
- async _downloadStarted(download) {
120
- const entry = {
121
- download,
122
- finished: false,
123
- outputFile: await this.context.outputFile(download.suggestedFilename(), { origin: "web", reason: "Saving download" })
124
- };
125
- this._downloads.push(entry);
126
- await download.saveAs(entry.outputFile);
127
- entry.finished = true;
128
- }
129
- _clearCollectedArtifacts() {
130
- this._consoleMessages.length = 0;
131
- this._recentConsoleMessages.length = 0;
132
- this._requests.clear();
133
- }
134
- _handleConsoleMessage(message) {
135
- this._consoleMessages.push(message);
136
- this._recentConsoleMessages.push(message);
137
- }
138
- _onClose() {
139
- this._clearCollectedArtifacts();
140
- this._onPageClose(this);
141
- }
142
- async updateTitle() {
143
- await this._raceAgainstModalStates(async () => {
144
- this._lastTitle = await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.title());
145
- });
146
- }
147
- lastTitle() {
148
- return this._lastTitle;
149
- }
150
- isCurrentTab() {
151
- return this === this.context.currentTab();
152
- }
153
- async waitForLoadState(state, options) {
154
- await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.waitForLoadState(state, options).catch(import_log.logUnhandledError));
155
- }
156
- async navigate(url) {
157
- this._clearCollectedArtifacts();
158
- const downloadEvent = (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.waitForEvent("download").catch(import_log.logUnhandledError));
159
- try {
160
- await this.page.goto(url, { waitUntil: "domcontentloaded" });
161
- } catch (_e) {
162
- const e = _e;
163
- const mightBeDownload = e.message.includes("net::ERR_ABORTED") || e.message.includes("Download is starting");
164
- if (!mightBeDownload)
165
- throw e;
166
- const download = await Promise.race([
167
- downloadEvent,
168
- new Promise((resolve) => setTimeout(resolve, 3e3))
169
- ]);
170
- if (!download)
171
- throw e;
172
- await new Promise((resolve) => setTimeout(resolve, 500));
173
- return;
174
- }
175
- await this.waitForLoadState("load", { timeout: 5e3 });
176
- }
177
- async consoleMessages(type) {
178
- await this.initializedPromise;
179
- return this._consoleMessages.filter((message) => type ? message.type === type : true);
180
- }
181
- async requests() {
182
- await this.initializedPromise;
183
- return this._requests;
184
- }
185
- async captureSnapshot() {
186
- let tabSnapshot;
187
- const modalStates = await this._raceAgainstModalStates(async () => {
188
- const snapshot = await this.page._snapshotForAI({ track: "response" });
189
- tabSnapshot = {
190
- url: this.page.url(),
191
- title: await this.page.title(),
192
- ariaSnapshot: snapshot.full,
193
- ariaSnapshotDiff: this._needsFullSnapshot ? void 0 : snapshot.incremental,
194
- modalStates: [],
195
- consoleMessages: [],
196
- downloads: this._downloads
197
- };
198
- });
199
- if (tabSnapshot) {
200
- tabSnapshot.consoleMessages = this._recentConsoleMessages;
201
- this._recentConsoleMessages = [];
202
- }
203
- this._needsFullSnapshot = !tabSnapshot;
204
- return tabSnapshot ?? {
205
- url: this.page.url(),
206
- title: "",
207
- ariaSnapshot: "",
208
- modalStates,
209
- consoleMessages: [],
210
- downloads: []
211
- };
212
- }
213
- _javaScriptBlocked() {
214
- return this._modalStates.some((state) => state.type === "dialog");
215
- }
216
- async _raceAgainstModalStates(action) {
217
- if (this.modalStates().length)
218
- return this.modalStates();
219
- const promise = new import_utils.ManualPromise();
220
- const listener = (modalState) => promise.resolve([modalState]);
221
- this.once(TabEvents.modalState, listener);
222
- return await Promise.race([
223
- action().then(() => {
224
- this.off(TabEvents.modalState, listener);
225
- return [];
226
- }),
227
- promise
228
- ]);
229
- }
230
- async waitForCompletion(callback) {
231
- await this._raceAgainstModalStates(() => (0, import_utils2.waitForCompletion)(this, callback));
232
- }
233
- async refLocator(params) {
234
- return (await this.refLocators([params]))[0];
235
- }
236
- async refLocators(params) {
237
- return Promise.all(params.map(async (param) => {
238
- try {
239
- const locator = this.page.locator(`aria-ref=${param.ref}`).describe(param.element);
240
- const { resolvedSelector } = await locator._resolveSelector();
241
-
242
- // ZIBBY: Capture stable ID from element BEFORE action
243
- let stableId = null;
244
- try {
245
- stableId = await locator.getAttribute('data-zibby-id');
246
- } catch (e) {
247
- // Element may not have stable ID yet
248
- }
249
-
250
- return { locator, resolved: (0, import_utils.asLocator)("javascript", resolvedSelector), stableId };
251
- } catch (e) {
252
- throw new Error(`Ref ${param.ref} not found in the current page snapshot. Try capturing new snapshot.`);
253
- }
254
- }));
255
- }
256
- async waitForTimeout(time) {
257
- if (this._javaScriptBlocked()) {
258
- await new Promise((f) => setTimeout(f, time));
259
- return;
260
- }
261
- await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => {
262
- return page.evaluate(() => new Promise((f) => setTimeout(f, 1e3)));
263
- });
264
- }
265
- }
266
- function messageToConsoleMessage(message) {
267
- return {
268
- type: message.type(),
269
- text: message.text(),
270
- toString: () => `[${message.type().toUpperCase()}] ${message.text()} @ ${message.location().url}:${message.location().lineNumber}`
271
- };
272
- }
273
- function pageErrorToConsoleMessage(errorOrValue) {
274
- if (errorOrValue instanceof Error) {
275
- return {
276
- type: "error",
277
- text: errorOrValue.message,
278
- toString: () => errorOrValue.stack || errorOrValue.message
279
- };
280
- }
281
- return {
282
- type: "error",
283
- text: String(errorOrValue),
284
- toString: () => String(errorOrValue)
285
- };
286
- }
287
- function renderModalStates(context, modalStates) {
288
- const result = ["### Modal state"];
289
- if (modalStates.length === 0)
290
- result.push("- There is no modal state present");
291
- for (const state of modalStates)
292
- result.push(`- [${state.description}]: can be handled by the "${state.clearedBy}" tool`);
293
- return result;
294
- }
295
- const tabSymbol = Symbol("tabSymbol");
296
- // Annotate the CommonJS export names for ESM import in node:
297
- 0 && (module.exports = {
298
- Tab,
299
- TabEvents,
300
- renderModalStates
301
- });
@@ -1,67 +0,0 @@
1
- "use strict";
2
- const __defProp = Object.defineProperty;
3
- const __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- const __getOwnPropNames = Object.getOwnPropertyNames;
5
- const __hasOwnProp = Object.prototype.hasOwnProperty;
6
- const __export = (target, all) => {
7
- for (const name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- const __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (const 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
- const __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- const common_exports = {};
20
- __export(common_exports, {
21
- default: () => common_default
22
- });
23
- module.exports = __toCommonJS(common_exports);
24
- const import_bundle = require("../../sdk/bundle");
25
- const import_tool = require("./tool");
26
- const close = (0, import_tool.defineTool)({
27
- capability: "core",
28
- schema: {
29
- name: "browser_close",
30
- title: "Close browser",
31
- description: "Close the page",
32
- inputSchema: import_bundle.z.object({}),
33
- type: "action"
34
- },
35
- handle: async (context, params, response) => {
36
- // ZIBBY: Record close event BEFORE closing
37
- if (typeof global.__zibbyRecordEvent === 'function') {
38
- global.__zibbyRecordEvent('close', {});
39
- }
40
- await context.closeBrowserContext();
41
- response.setIncludeTabs();
42
- response.addCode(`await page.close()`);
43
- }
44
- });
45
- const resize = (0, import_tool.defineTabTool)({
46
- capability: "core",
47
- schema: {
48
- name: "browser_resize",
49
- title: "Resize browser window",
50
- description: "Resize the browser window",
51
- inputSchema: import_bundle.z.object({
52
- width: import_bundle.z.number().describe("Width of the browser window"),
53
- height: import_bundle.z.number().describe("Height of the browser window")
54
- }),
55
- type: "action"
56
- },
57
- handle: async (tab, params, response) => {
58
- response.addCode(`await page.setViewportSize({ width: ${params.width}, height: ${params.height} });`);
59
- await tab.waitForCompletion(async () => {
60
- await tab.page.setViewportSize({ width: params.width, height: params.height });
61
- });
62
- }
63
- });
64
- var common_default = [
65
- close,
66
- resize
67
- ];
@@ -1,88 +0,0 @@
1
- "use strict";
2
- const __defProp = Object.defineProperty;
3
- const __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- const __getOwnPropNames = Object.getOwnPropertyNames;
5
- const __hasOwnProp = Object.prototype.hasOwnProperty;
6
- const __export = (target, all) => {
7
- for (const name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- const __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (const 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
- const __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- const keyboard_exports = {};
20
- __export(keyboard_exports, {
21
- default: () => keyboard_default
22
- });
23
- module.exports = __toCommonJS(keyboard_exports);
24
- const import_bundle = require("../../sdk/bundle");
25
- const import_tool = require("./tool");
26
- const import_snapshot = require("./snapshot");
27
- const pressKey = (0, import_tool.defineTabTool)({
28
- capability: "core",
29
- schema: {
30
- name: "browser_press_key",
31
- title: "Press a key",
32
- description: "Press a key on the keyboard",
33
- inputSchema: import_bundle.z.object({
34
- key: import_bundle.z.string().describe("Name of the key to press or a character to generate, such as `ArrowLeft` or `a`")
35
- }),
36
- type: "input"
37
- },
38
- handle: async (tab, params, response) => {
39
- response.setIncludeSnapshot();
40
- response.addCode(`// Press ${params.key}`);
41
- response.addCode(`await page.keyboard.press('${params.key}');`);
42
- await tab.waitForCompletion(async () => {
43
- await tab.page.keyboard.press(params.key);
44
- });
45
- }
46
- });
47
- const typeSchema = import_snapshot.elementSchema.extend({
48
- text: import_bundle.z.string().describe("Text to type into the element"),
49
- submit: import_bundle.z.boolean().optional().describe("Whether to submit entered text (press Enter after)"),
50
- slowly: import_bundle.z.boolean().optional().describe("Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.")
51
- });
52
- const type = (0, import_tool.defineTabTool)({
53
- capability: "core",
54
- schema: {
55
- name: "browser_type",
56
- title: "Type text",
57
- description: "Type text into editable element",
58
- inputSchema: typeSchema,
59
- type: "input"
60
- },
61
- handle: async (tab, params, response) => {
62
- const { locator, resolved, stableId } = await tab.refLocator(params);
63
- const secret = tab.context.lookupSecret(params.text);
64
- await tab.waitForCompletion(async () => {
65
- if (params.slowly) {
66
- response.setIncludeSnapshot();
67
- response.addCode(`await page.${resolved}.pressSequentially(${secret.code});`);
68
- await locator.pressSequentially(secret.value);
69
- } else {
70
- response.addCode(`await page.${resolved}.fill(${secret.code});`);
71
- await locator.fill(secret.value);
72
- }
73
- if (params.submit) {
74
- response.setIncludeSnapshot();
75
- response.addCode(`await page.${resolved}.press('Enter');`);
76
- await locator.press("Enter");
77
- }
78
- });
79
- // ZIBBY: Record event with stable ID
80
- if (typeof global.__zibbyRecordEvent === 'function') {
81
- global.__zibbyRecordEvent('type', { element: params.element, ref: params.ref, text: params.text, stableId });
82
- }
83
- }
84
- });
85
- var keyboard_default = [
86
- pressKey,
87
- type
88
- ];
@@ -1,66 +0,0 @@
1
- "use strict";
2
- const __defProp = Object.defineProperty;
3
- const __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- const __getOwnPropNames = Object.getOwnPropertyNames;
5
- const __hasOwnProp = Object.prototype.hasOwnProperty;
6
- const __export = (target, all) => {
7
- for (const name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- const __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (const 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
- const __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- const navigate_exports = {};
20
- __export(navigate_exports, {
21
- default: () => navigate_default
22
- });
23
- module.exports = __toCommonJS(navigate_exports);
24
- const import_bundle = require("../../sdk/bundle");
25
- const import_tool = require("./tool");
26
- const navigate = (0, import_tool.defineTool)({
27
- capability: "core",
28
- schema: {
29
- name: "browser_navigate",
30
- title: "Navigate to a URL",
31
- description: "Navigate to a URL",
32
- inputSchema: import_bundle.z.object({
33
- url: import_bundle.z.string().describe("The URL to navigate to")
34
- }),
35
- type: "action"
36
- },
37
- handle: async (context, params, response) => {
38
- const tab = await context.ensureTab();
39
- await tab.navigate(params.url);
40
- response.setIncludeSnapshot();
41
- response.addCode(`await page.goto('${params.url}');`);
42
- // ZIBBY: Record navigate event
43
- if (typeof global.__zibbyRecordEvent === 'function') {
44
- global.__zibbyRecordEvent('navigate', { url: params.url });
45
- }
46
- }
47
- });
48
- const goBack = (0, import_tool.defineTabTool)({
49
- capability: "core",
50
- schema: {
51
- name: "browser_navigate_back",
52
- title: "Go back",
53
- description: "Go back to the previous page",
54
- inputSchema: import_bundle.z.object({}),
55
- type: "action"
56
- },
57
- handle: async (tab, params, response) => {
58
- await tab.page.goBack();
59
- response.setIncludeSnapshot();
60
- response.addCode(`await page.goBack();`);
61
- }
62
- });
63
- var navigate_default = [
64
- navigate,
65
- goBack
66
- ];