@cotestdev/mcp_playwright 0.0.35 → 0.0.36

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.
Files changed (39) hide show
  1. package/lib/mcp/browser/browserContextFactory.js +12 -12
  2. package/lib/mcp/browser/browserServerBackend.js +24 -12
  3. package/lib/mcp/browser/config.js +37 -7
  4. package/lib/mcp/browser/context.js +13 -61
  5. package/lib/mcp/browser/response.js +183 -251
  6. package/lib/mcp/browser/sessionLog.js +19 -104
  7. package/lib/mcp/browser/tab.js +49 -28
  8. package/lib/mcp/browser/tools/common.js +4 -4
  9. package/lib/mcp/browser/tools/console.js +20 -3
  10. package/lib/mcp/browser/tools/dialogs.js +0 -1
  11. package/lib/mcp/browser/tools/evaluate.js +6 -4
  12. package/lib/mcp/browser/tools/install.js +4 -1
  13. package/lib/mcp/browser/tools/keyboard.js +75 -8
  14. package/lib/mcp/browser/tools/mouse.js +59 -7
  15. package/lib/mcp/browser/tools/navigate.js +48 -5
  16. package/lib/mcp/browser/tools/network.js +21 -3
  17. package/lib/mcp/browser/tools/pdf.js +4 -3
  18. package/lib/mcp/browser/tools/runCode.js +6 -10
  19. package/lib/mcp/browser/tools/screenshot.js +8 -26
  20. package/lib/mcp/browser/tools/snapshot.js +38 -22
  21. package/lib/mcp/browser/tools/tabs.js +8 -8
  22. package/lib/mcp/browser/tools/tool.js +3 -6
  23. package/lib/mcp/browser/tools/tracing.js +3 -3
  24. package/lib/mcp/browser/tools/utils.js +2 -2
  25. package/lib/mcp/browser/tools/verify.js +4 -4
  26. package/lib/mcp/browser/tools/wait.js +1 -1
  27. package/lib/mcp/browser/tools.js +2 -2
  28. package/lib/mcp/extension/extensionContextFactory.js +2 -2
  29. package/lib/mcp/program.js +3 -2
  30. package/lib/mcp/terminal/cli.js +4 -216
  31. package/lib/mcp/terminal/command.js +56 -0
  32. package/lib/mcp/terminal/commands.js +528 -0
  33. package/lib/mcp/terminal/daemon.js +42 -25
  34. package/lib/mcp/terminal/helpGenerator.js +152 -0
  35. package/lib/mcp/terminal/program.js +434 -0
  36. package/lib/mcp/terminal/socketConnection.js +2 -4
  37. package/lib/mcpBundleImpl/index.js +44 -44
  38. package/lib/util.js +3 -6
  39. package/package.json +1 -1
@@ -0,0 +1,528 @@
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 commands_exports = {};
20
+ __export(commands_exports, {
21
+ commands: () => commands
22
+ });
23
+ module.exports = __toCommonJS(commands_exports);
24
+ var import_mcpBundle = require("../../mcpBundle");
25
+ var import_command = require("./command");
26
+ const open = (0, import_command.declareCommand)({
27
+ name: "open",
28
+ description: "Open URL",
29
+ category: "core",
30
+ args: import_mcpBundle.z.object({
31
+ url: import_mcpBundle.z.string().describe("The URL to navigate to")
32
+ }),
33
+ toolName: "browser_navigate",
34
+ toolParams: ({ url }) => ({ url })
35
+ });
36
+ const close = (0, import_command.declareCommand)({
37
+ name: "close",
38
+ description: "Close the page",
39
+ category: "core",
40
+ args: import_mcpBundle.z.object({}),
41
+ toolName: "browser_close",
42
+ toolParams: () => ({})
43
+ });
44
+ const goBack = (0, import_command.declareCommand)({
45
+ name: "go-back",
46
+ description: "Go back to the previous page",
47
+ category: "navigation",
48
+ args: import_mcpBundle.z.object({}),
49
+ toolName: "browser_navigate_back",
50
+ toolParams: () => ({})
51
+ });
52
+ const goForward = (0, import_command.declareCommand)({
53
+ name: "go-forward",
54
+ description: "Go forward to the next page",
55
+ category: "navigation",
56
+ args: import_mcpBundle.z.object({}),
57
+ toolName: "browser_navigate_forward",
58
+ toolParams: () => ({})
59
+ });
60
+ const reload = (0, import_command.declareCommand)({
61
+ name: "reload",
62
+ description: "Reload the current page",
63
+ category: "navigation",
64
+ args: import_mcpBundle.z.object({}),
65
+ toolName: "browser_reload",
66
+ toolParams: () => ({})
67
+ });
68
+ const pressKey = (0, import_command.declareCommand)({
69
+ name: "press",
70
+ description: "Press a key on the keyboard, `a`, `ArrowLeft`",
71
+ category: "keyboard",
72
+ args: import_mcpBundle.z.object({
73
+ key: import_mcpBundle.z.string().describe("Name of the key to press or a character to generate, such as `ArrowLeft` or `a`")
74
+ }),
75
+ toolName: "browser_press_key",
76
+ toolParams: ({ key }) => ({ key })
77
+ });
78
+ const type = (0, import_command.declareCommand)({
79
+ name: "type",
80
+ description: "Type text into editable element",
81
+ category: "core",
82
+ args: import_mcpBundle.z.object({
83
+ text: import_mcpBundle.z.string().describe("Text to type into the element")
84
+ }),
85
+ options: import_mcpBundle.z.object({
86
+ submit: import_mcpBundle.z.boolean().optional().describe("Whether to submit entered text (press Enter after)")
87
+ }),
88
+ toolName: "browser_press_sequentially",
89
+ toolParams: ({ text, submit }) => ({ text, submit })
90
+ });
91
+ const keydown = (0, import_command.declareCommand)({
92
+ name: "keydown",
93
+ description: "Press a key down on the keyboard",
94
+ category: "keyboard",
95
+ args: import_mcpBundle.z.object({
96
+ key: import_mcpBundle.z.string().describe("Name of the key to press or a character to generate, such as `ArrowLeft` or `a`")
97
+ }),
98
+ toolName: "browser_keydown",
99
+ toolParams: ({ key }) => ({ key })
100
+ });
101
+ const keyup = (0, import_command.declareCommand)({
102
+ name: "keyup",
103
+ description: "Press a key up on the keyboard",
104
+ category: "keyboard",
105
+ args: import_mcpBundle.z.object({
106
+ key: import_mcpBundle.z.string().describe("Name of the key to press or a character to generate, such as `ArrowLeft` or `a`")
107
+ }),
108
+ toolName: "browser_keyup",
109
+ toolParams: ({ key }) => ({ key })
110
+ });
111
+ const mouseMove = (0, import_command.declareCommand)({
112
+ name: "mousemove",
113
+ description: "Move mouse to a given position",
114
+ category: "mouse",
115
+ args: import_mcpBundle.z.object({
116
+ x: import_mcpBundle.z.number().describe("X coordinate"),
117
+ y: import_mcpBundle.z.number().describe("Y coordinate")
118
+ }),
119
+ toolName: "browser_mouse_move_xy",
120
+ toolParams: ({ x, y }) => ({ x, y })
121
+ });
122
+ const mouseDown = (0, import_command.declareCommand)({
123
+ name: "mousedown",
124
+ description: "Press mouse down",
125
+ category: "mouse",
126
+ args: import_mcpBundle.z.object({
127
+ button: import_mcpBundle.z.string().optional().describe("Button to press, defaults to left")
128
+ }),
129
+ toolName: "browser_mouse_down",
130
+ toolParams: ({ button }) => ({ button })
131
+ });
132
+ const mouseUp = (0, import_command.declareCommand)({
133
+ name: "mouseup",
134
+ description: "Press mouse up",
135
+ category: "mouse",
136
+ args: import_mcpBundle.z.object({
137
+ button: import_mcpBundle.z.string().optional().describe("Button to press, defaults to left")
138
+ }),
139
+ toolName: "browser_mouse_up",
140
+ toolParams: ({ button }) => ({ button })
141
+ });
142
+ const mouseWheel = (0, import_command.declareCommand)({
143
+ name: "mousewheel",
144
+ description: "Scroll mouse wheel",
145
+ category: "mouse",
146
+ args: import_mcpBundle.z.object({
147
+ dx: import_mcpBundle.z.number().describe("Y delta"),
148
+ dy: import_mcpBundle.z.number().describe("X delta")
149
+ }),
150
+ toolName: "browser_mouse_wheel",
151
+ toolParams: ({ dx: deltaY, dy: deltaX }) => ({ deltaY, deltaX })
152
+ });
153
+ const click = (0, import_command.declareCommand)({
154
+ name: "click",
155
+ description: "Perform click on a web page",
156
+ category: "core",
157
+ args: import_mcpBundle.z.object({
158
+ ref: import_mcpBundle.z.string().describe("Exact target element reference from the page snapshot"),
159
+ button: import_mcpBundle.z.string().optional().describe("Button to click, defaults to left")
160
+ }),
161
+ options: import_mcpBundle.z.object({
162
+ modifiers: import_mcpBundle.z.array(import_mcpBundle.z.string()).optional().describe("Modifier keys to press")
163
+ }),
164
+ toolName: "browser_click",
165
+ toolParams: ({ ref, button, modifiers }) => ({ ref, button, modifiers })
166
+ });
167
+ const doubleClick = (0, import_command.declareCommand)({
168
+ name: "dblclick",
169
+ description: "Perform double click on a web page",
170
+ category: "core",
171
+ args: import_mcpBundle.z.object({
172
+ ref: import_mcpBundle.z.string().describe("Exact target element reference from the page snapshot"),
173
+ button: import_mcpBundle.z.string().optional().describe("Button to click, defaults to left")
174
+ }),
175
+ options: import_mcpBundle.z.object({
176
+ modifiers: import_mcpBundle.z.array(import_mcpBundle.z.string()).optional().describe("Modifier keys to press")
177
+ }),
178
+ toolName: "browser_click",
179
+ toolParams: ({ ref, button, modifiers }) => ({ ref, button, modifiers, doubleClick: true })
180
+ });
181
+ const drag = (0, import_command.declareCommand)({
182
+ name: "drag",
183
+ description: "Perform drag and drop between two elements",
184
+ category: "core",
185
+ args: import_mcpBundle.z.object({
186
+ startRef: import_mcpBundle.z.string().describe("Exact source element reference from the page snapshot"),
187
+ endRef: import_mcpBundle.z.string().describe("Exact target element reference from the page snapshot")
188
+ }),
189
+ options: import_mcpBundle.z.object({
190
+ headed: import_mcpBundle.z.boolean().default(false).describe("Run browser in headed mode")
191
+ }),
192
+ toolName: "browser_drag",
193
+ toolParams: ({ startRef, endRef }) => ({ startRef, endRef })
194
+ });
195
+ const fill = (0, import_command.declareCommand)({
196
+ name: "fill",
197
+ description: "Fill text into editable element",
198
+ category: "core",
199
+ args: import_mcpBundle.z.object({
200
+ ref: import_mcpBundle.z.string().describe("Exact target element reference from the page snapshot"),
201
+ text: import_mcpBundle.z.string().describe("Text to fill into the element")
202
+ }),
203
+ options: import_mcpBundle.z.object({
204
+ submit: import_mcpBundle.z.boolean().optional().describe("Whether to submit entered text (press Enter after)")
205
+ }),
206
+ toolName: "browser_type",
207
+ toolParams: ({ ref, text, submit }) => ({ ref, text, submit })
208
+ });
209
+ const hover = (0, import_command.declareCommand)({
210
+ name: "hover",
211
+ description: "Hover over element on page",
212
+ category: "core",
213
+ args: import_mcpBundle.z.object({
214
+ ref: import_mcpBundle.z.string().describe("Exact target element reference from the page snapshot")
215
+ }),
216
+ toolName: "browser_hover",
217
+ toolParams: ({ ref }) => ({ ref })
218
+ });
219
+ const select = (0, import_command.declareCommand)({
220
+ name: "select",
221
+ description: "Select an option in a dropdown",
222
+ category: "core",
223
+ args: import_mcpBundle.z.object({
224
+ ref: import_mcpBundle.z.string().describe("Exact target element reference from the page snapshot"),
225
+ val: import_mcpBundle.z.string().describe("Value to select in the dropdown")
226
+ }),
227
+ toolName: "browser_select_option",
228
+ toolParams: ({ ref, val: value }) => ({ ref, values: [value] })
229
+ });
230
+ const fileUpload = (0, import_command.declareCommand)({
231
+ name: "upload",
232
+ description: "Upload one or multiple files",
233
+ category: "core",
234
+ args: import_mcpBundle.z.object({
235
+ file: import_mcpBundle.z.string().describe("The absolute paths to the files to upload")
236
+ }),
237
+ toolName: "browser_file_upload",
238
+ toolParams: ({ file }) => ({ paths: [file] })
239
+ });
240
+ const check = (0, import_command.declareCommand)({
241
+ name: "check",
242
+ description: "Check a checkbox or radio button",
243
+ category: "core",
244
+ args: import_mcpBundle.z.object({
245
+ ref: import_mcpBundle.z.string().describe("Exact target element reference from the page snapshot")
246
+ }),
247
+ toolName: "browser_check",
248
+ toolParams: ({ ref }) => ({ ref })
249
+ });
250
+ const uncheck = (0, import_command.declareCommand)({
251
+ name: "uncheck",
252
+ description: "Uncheck a checkbox or radio button",
253
+ category: "core",
254
+ args: import_mcpBundle.z.object({
255
+ ref: import_mcpBundle.z.string().describe("Exact target element reference from the page snapshot")
256
+ }),
257
+ toolName: "browser_uncheck",
258
+ toolParams: ({ ref }) => ({ ref })
259
+ });
260
+ const snapshot = (0, import_command.declareCommand)({
261
+ name: "snapshot",
262
+ description: "Capture page snapshot to obtain element ref",
263
+ category: "core",
264
+ args: import_mcpBundle.z.object({}),
265
+ options: import_mcpBundle.z.object({
266
+ filename: import_mcpBundle.z.string().optional().describe("Save snapshot to markdown file instead of returning it in the response.")
267
+ }),
268
+ toolName: "browser_snapshot",
269
+ toolParams: ({ filename }) => ({ filename })
270
+ });
271
+ const evaluate = (0, import_command.declareCommand)({
272
+ name: "eval",
273
+ description: "Evaluate JavaScript expression on page or element",
274
+ category: "core",
275
+ args: import_mcpBundle.z.object({
276
+ func: import_mcpBundle.z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
277
+ ref: import_mcpBundle.z.string().optional().describe("Exact target element reference from the page snapshot")
278
+ }),
279
+ toolName: "browser_evaluate",
280
+ toolParams: ({ func, ref }) => ({ function: func, ref })
281
+ });
282
+ const dialogAccept = (0, import_command.declareCommand)({
283
+ name: "dialog-accept",
284
+ description: "Accept a dialog",
285
+ category: "core",
286
+ args: import_mcpBundle.z.object({
287
+ prompt: import_mcpBundle.z.string().optional().describe("The text of the prompt in case of a prompt dialog.")
288
+ }),
289
+ toolName: "browser_handle_dialog",
290
+ toolParams: ({ prompt: promptText }) => ({ accept: true, promptText })
291
+ });
292
+ const dialogDismiss = (0, import_command.declareCommand)({
293
+ name: "dialog-dismiss",
294
+ description: "Dismiss a dialog",
295
+ category: "core",
296
+ args: import_mcpBundle.z.object({}),
297
+ toolName: "browser_handle_dialog",
298
+ toolParams: () => ({ accept: false })
299
+ });
300
+ const resize = (0, import_command.declareCommand)({
301
+ name: "resize",
302
+ description: "Resize the browser window",
303
+ category: "core",
304
+ args: import_mcpBundle.z.object({
305
+ w: import_mcpBundle.z.number().describe("Width of the browser window"),
306
+ h: import_mcpBundle.z.number().describe("Height of the browser window")
307
+ }),
308
+ toolName: "browser_resize",
309
+ toolParams: ({ w: width, h: height }) => ({ width, height })
310
+ });
311
+ const tabList = (0, import_command.declareCommand)({
312
+ name: "tab-list",
313
+ description: "List all tabs",
314
+ category: "tabs",
315
+ args: import_mcpBundle.z.object({}),
316
+ toolName: "browser_tabs",
317
+ toolParams: () => ({ action: "list" })
318
+ });
319
+ const tabNew = (0, import_command.declareCommand)({
320
+ name: "tab-new",
321
+ description: "Create a new tab",
322
+ category: "tabs",
323
+ args: import_mcpBundle.z.object({
324
+ url: import_mcpBundle.z.string().optional().describe("The URL to navigate to in the new tab. If omitted, the new tab will be blank.")
325
+ }),
326
+ toolName: "browser_tabs",
327
+ toolParams: ({ url }) => ({ action: "new", url })
328
+ });
329
+ const tabClose = (0, import_command.declareCommand)({
330
+ name: "tab-close",
331
+ description: "Close a browser tab",
332
+ category: "tabs",
333
+ args: import_mcpBundle.z.object({
334
+ index: import_mcpBundle.z.number().optional().describe("Tab index. If omitted, current tab is closed.")
335
+ }),
336
+ toolName: "browser_tabs",
337
+ toolParams: ({ index }) => ({ action: "close", index })
338
+ });
339
+ const tabSelect = (0, import_command.declareCommand)({
340
+ name: "tab-select",
341
+ description: "Select a browser tab",
342
+ category: "tabs",
343
+ args: import_mcpBundle.z.object({
344
+ index: import_mcpBundle.z.number().describe("Tab index")
345
+ }),
346
+ toolName: "browser_tabs",
347
+ toolParams: ({ index }) => ({ action: "select", index })
348
+ });
349
+ const screenshot = (0, import_command.declareCommand)({
350
+ name: "screenshot",
351
+ description: "screenshot of the current page or element",
352
+ category: "export",
353
+ args: import_mcpBundle.z.object({
354
+ ref: import_mcpBundle.z.string().optional().describe("Exact target element reference from the page snapshot.")
355
+ }),
356
+ options: import_mcpBundle.z.object({
357
+ filename: import_mcpBundle.z.string().optional().describe("File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified."),
358
+ ["full-page"]: import_mcpBundle.z.boolean().optional().describe("When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport.")
359
+ }),
360
+ toolName: "browser_take_screenshot",
361
+ toolParams: ({ ref, filename, ["full-page"]: fullPage }) => ({ filename, ref, fullPage })
362
+ });
363
+ const pdfSave = (0, import_command.declareCommand)({
364
+ name: "pdf",
365
+ description: "Save page as PDF",
366
+ category: "export",
367
+ args: import_mcpBundle.z.object({}),
368
+ options: import_mcpBundle.z.object({
369
+ filename: import_mcpBundle.z.string().optional().describe("File name to save the pdf to. Defaults to `page-{timestamp}.pdf` if not specified.")
370
+ }),
371
+ toolName: "browser_pdf_save",
372
+ toolParams: ({ filename }) => ({ filename })
373
+ });
374
+ const consoleList = (0, import_command.declareCommand)({
375
+ name: "console",
376
+ description: "List console messages",
377
+ category: "devtools",
378
+ args: import_mcpBundle.z.object({
379
+ ["min-level"]: import_mcpBundle.z.string().optional().describe('Level of the console messages to return. Each level includes the messages of more severe levels. Defaults to "info".')
380
+ }),
381
+ options: import_mcpBundle.z.object({
382
+ clear: import_mcpBundle.z.boolean().optional().describe("Whether to clear the console list")
383
+ }),
384
+ toolName: ({ clear }) => clear ? "browser_console_clear" : "browser_console_messages",
385
+ toolParams: ({ ["min-level"]: level, clear }) => clear ? {} : { level }
386
+ });
387
+ const networkRequests = (0, import_command.declareCommand)({
388
+ name: "network",
389
+ description: "List all network requests since loading the page",
390
+ category: "devtools",
391
+ args: import_mcpBundle.z.object({}),
392
+ options: import_mcpBundle.z.object({
393
+ static: import_mcpBundle.z.boolean().optional().describe("Whether to include successful static resources like images, fonts, scripts, etc. Defaults to false."),
394
+ clear: import_mcpBundle.z.boolean().optional().describe("Whether to clear the network list")
395
+ }),
396
+ toolName: ({ clear }) => clear ? "browser_network_clear" : "browser_network_requests",
397
+ toolParams: ({ static: includeStatic, clear }) => clear ? {} : { includeStatic }
398
+ });
399
+ const runCode = (0, import_command.declareCommand)({
400
+ name: "run-code",
401
+ description: "Run Playwright code snippet",
402
+ category: "devtools",
403
+ args: import_mcpBundle.z.object({
404
+ code: import_mcpBundle.z.string().describe("A JavaScript function containing Playwright code to execute. It will be invoked with a single argument, page, which you can use for any page interaction.")
405
+ }),
406
+ toolName: "browser_run_code",
407
+ toolParams: ({ code }) => ({ code })
408
+ });
409
+ const tracingStart = (0, import_command.declareCommand)({
410
+ name: "tracing-start",
411
+ description: "Start trace recording",
412
+ category: "devtools",
413
+ args: import_mcpBundle.z.object({}),
414
+ toolName: "browser_start_tracing",
415
+ toolParams: () => ({})
416
+ });
417
+ const tracingStop = (0, import_command.declareCommand)({
418
+ name: "tracing-stop",
419
+ description: "Stop trace recording",
420
+ category: "devtools",
421
+ args: import_mcpBundle.z.object({}),
422
+ toolName: "browser_stop_tracing",
423
+ toolParams: () => ({})
424
+ });
425
+ const sessionList = (0, import_command.declareCommand)({
426
+ name: "session-list",
427
+ description: "List all sessions",
428
+ category: "session",
429
+ args: import_mcpBundle.z.object({}),
430
+ toolName: "",
431
+ toolParams: () => ({})
432
+ });
433
+ const sessionStop = (0, import_command.declareCommand)({
434
+ name: "session-stop",
435
+ description: "Stop session",
436
+ category: "session",
437
+ args: import_mcpBundle.z.object({
438
+ name: import_mcpBundle.z.string().optional().describe("Name of the session to stop. If omitted, current session is stopped.")
439
+ }),
440
+ toolName: "",
441
+ toolParams: () => ({})
442
+ });
443
+ const sessionStopAll = (0, import_command.declareCommand)({
444
+ name: "session-stop-all",
445
+ description: "Stop all sessions",
446
+ category: "session",
447
+ toolName: "",
448
+ toolParams: () => ({})
449
+ });
450
+ const sessionDelete = (0, import_command.declareCommand)({
451
+ name: "session-delete",
452
+ description: "Delete session data",
453
+ category: "session",
454
+ args: import_mcpBundle.z.object({
455
+ name: import_mcpBundle.z.string().optional().describe("Name of the session to delete. If omitted, current session is deleted.")
456
+ }),
457
+ toolName: "",
458
+ toolParams: ({ name }) => ({ name })
459
+ });
460
+ const config = (0, import_command.declareCommand)({
461
+ name: "config",
462
+ description: "Restart session with new config, defaults to `playwright-cli.json`",
463
+ category: "config",
464
+ args: import_mcpBundle.z.object({
465
+ config: import_mcpBundle.z.string().optional().describe("Path to the configuration file")
466
+ }),
467
+ toolName: "",
468
+ toolParams: () => ({})
469
+ });
470
+ const commandsArray = [
471
+ // core category
472
+ open,
473
+ close,
474
+ type,
475
+ click,
476
+ doubleClick,
477
+ fill,
478
+ drag,
479
+ hover,
480
+ select,
481
+ fileUpload,
482
+ check,
483
+ uncheck,
484
+ snapshot,
485
+ evaluate,
486
+ consoleList,
487
+ dialogAccept,
488
+ dialogDismiss,
489
+ resize,
490
+ // navigation category
491
+ goBack,
492
+ goForward,
493
+ reload,
494
+ // keyboard category
495
+ pressKey,
496
+ keydown,
497
+ keyup,
498
+ // mouse category
499
+ mouseMove,
500
+ mouseDown,
501
+ mouseUp,
502
+ mouseWheel,
503
+ // export category
504
+ screenshot,
505
+ pdfSave,
506
+ // tabs category
507
+ tabList,
508
+ tabNew,
509
+ tabClose,
510
+ tabSelect,
511
+ // config
512
+ config,
513
+ // devtools category
514
+ networkRequests,
515
+ runCode,
516
+ tracingStart,
517
+ tracingStop,
518
+ // session category
519
+ sessionList,
520
+ sessionStop,
521
+ sessionStopAll,
522
+ sessionDelete
523
+ ];
524
+ const commands = Object.fromEntries(commandsArray.map((cmd) => [cmd.name, cmd]));
525
+ // Annotate the CommonJS export names for ESM import in node:
526
+ 0 && (module.exports = {
527
+ commands
528
+ });
@@ -35,18 +35,13 @@ var import_promises = __toESM(require("fs/promises"));
35
35
  var import_net = __toESM(require("net"));
36
36
  var import_os = __toESM(require("os"));
37
37
  var import_path = __toESM(require("path"));
38
+ var import_url = __toESM(require("url"));
38
39
  var import_utilsBundle = require("playwright-core/lib/utilsBundle");
40
+ var import_utils = require("playwright-core/lib/utils");
39
41
  var import_socketConnection = require("./socketConnection");
42
+ var import_commands = require("./commands");
43
+ var import_command = require("./command");
40
44
  const daemonDebug = (0, import_utilsBundle.debug)("pw:daemon");
41
- function normalizeSocketPath(path2) {
42
- if (import_os.default.platform() === "win32") {
43
- if (path2.startsWith("\\\\.\\pipe\\"))
44
- return path2;
45
- const name = path2.replace(/[^a-zA-Z0-9]/g, "-");
46
- return `\\\\.\\pipe\\${name}`;
47
- }
48
- return path2;
49
- }
50
45
  async function socketExists(socketPath) {
51
46
  try {
52
47
  const stat = await import_promises.default.stat(socketPath);
@@ -57,24 +52,27 @@ async function socketExists(socketPath) {
57
52
  return false;
58
53
  }
59
54
  async function startMcpDaemonServer(socketPath, serverBackendFactory) {
60
- const normalizedPath = normalizeSocketPath(socketPath);
61
- if (import_os.default.platform() !== "win32" && await socketExists(normalizedPath)) {
62
- daemonDebug(`Socket already exists, removing: ${normalizedPath}`);
55
+ if (import_os.default.platform() !== "win32" && await socketExists(socketPath)) {
56
+ daemonDebug(`Socket already exists, removing: ${socketPath}`);
63
57
  try {
64
- await import_promises.default.unlink(normalizedPath);
58
+ await import_promises.default.unlink(socketPath);
65
59
  } catch (error) {
66
60
  daemonDebug(`Failed to remove existing socket: ${error}`);
67
61
  throw error;
68
62
  }
69
63
  }
70
64
  const backend = serverBackendFactory.create();
65
+ const cwd = import_url.default.pathToFileURL(process.cwd()).href;
71
66
  await backend.initialize?.({
72
- name: "mcp-daemon",
67
+ name: "playwright-cli",
73
68
  version: "1.0.0",
74
- roots: [],
69
+ roots: [{
70
+ uri: cwd,
71
+ name: "cwd"
72
+ }],
75
73
  timestamp: Date.now()
76
74
  });
77
- await import_promises.default.mkdir(import_path.default.dirname(normalizedPath), { recursive: true });
75
+ await import_promises.default.mkdir(import_path.default.dirname(socketPath), { recursive: true });
78
76
  const server = import_net.default.createServer((socket) => {
79
77
  daemonDebug("new client connection");
80
78
  const connection = new import_socketConnection.SocketConnection(socket);
@@ -85,15 +83,22 @@ async function startMcpDaemonServer(socketPath, serverBackendFactory) {
85
83
  const { id, method, params } = message;
86
84
  try {
87
85
  daemonDebug("received command", method);
88
- const response = await backend.callTool(method, params, () => {
89
- });
90
- daemonDebug("sending response", !!response);
91
- if (response)
92
- await connection.send({ id, result: response });
86
+ if (method === "stop") {
87
+ daemonDebug("stop command received, shutting down");
88
+ await connection.send({ id, result: "ok" });
89
+ server.close();
90
+ (0, import_utils.gracefullyProcessExitDoNotHang)(0);
91
+ } else if (method === "run") {
92
+ const { toolName, toolParams } = parseCliCommand(params.args);
93
+ const response = await backend.callTool(toolName, toolParams, () => {
94
+ });
95
+ await connection.send({ id, result: formatResult(response) });
96
+ } else {
97
+ throw new Error(`Unknown method: ${method}`);
98
+ }
93
99
  } catch (e) {
94
100
  daemonDebug("command failed", e);
95
101
  await connection.send({ id, error: e.message });
96
- daemonDebug("error handling message", e);
97
102
  }
98
103
  };
99
104
  });
@@ -102,12 +107,24 @@ async function startMcpDaemonServer(socketPath, serverBackendFactory) {
102
107
  daemonDebug(`server error: ${error.message}`);
103
108
  reject(error);
104
109
  });
105
- server.listen(normalizedPath, () => {
106
- daemonDebug(`daemon server listening on ${normalizedPath}`);
107
- resolve(normalizedPath);
110
+ server.listen(socketPath, () => {
111
+ daemonDebug(`daemon server listening on ${socketPath}`);
112
+ resolve(socketPath);
108
113
  });
109
114
  });
110
115
  }
116
+ function formatResult(result) {
117
+ const isError = result.isError;
118
+ const text = result.content[0].type === "text" ? result.content[0].text : void 0;
119
+ const sections = result.content[0]._meta?.sections;
120
+ return { isError, text, sections };
121
+ }
122
+ function parseCliCommand(args) {
123
+ const command = import_commands.commands[args._[0]];
124
+ if (!command)
125
+ throw new Error("Command is required");
126
+ return (0, import_command.parseCommand)(command, args);
127
+ }
111
128
  // Annotate the CommonJS export names for ESM import in node:
112
129
  0 && (module.exports = {
113
130
  startMcpDaemonServer