@cotestdev/mcp_playwright 0.0.50 → 0.0.52

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 (34) hide show
  1. package/lib/mcp/browser/browserContextFactory.js +11 -4
  2. package/lib/mcp/browser/browserServerBackend.js +2 -4
  3. package/lib/mcp/browser/config.js +71 -47
  4. package/lib/mcp/browser/context.js +65 -4
  5. package/lib/mcp/browser/logFile.js +96 -0
  6. package/lib/mcp/browser/response.js +107 -104
  7. package/lib/mcp/browser/sessionLog.js +1 -1
  8. package/lib/mcp/browser/tab.js +73 -18
  9. package/lib/mcp/browser/tools/config.js +41 -0
  10. package/lib/mcp/browser/tools/console.js +6 -2
  11. package/lib/mcp/browser/tools/cookies.js +152 -0
  12. package/lib/mcp/browser/tools/install.js +1 -0
  13. package/lib/mcp/browser/tools/network.js +25 -11
  14. package/lib/mcp/browser/tools/pdf.js +3 -4
  15. package/lib/mcp/browser/tools/route.js +140 -0
  16. package/lib/mcp/browser/tools/runCode.js +0 -2
  17. package/lib/mcp/browser/tools/screenshot.js +6 -7
  18. package/lib/mcp/browser/tools/storage.js +3 -4
  19. package/lib/mcp/browser/tools/tracing.js +10 -9
  20. package/lib/mcp/browser/tools/utils.js +0 -6
  21. package/lib/mcp/browser/tools/video.js +31 -13
  22. package/lib/mcp/browser/tools/webstorage.js +223 -0
  23. package/lib/mcp/browser/tools.js +11 -3
  24. package/lib/mcp/extension/cdpRelay.js +7 -7
  25. package/lib/mcp/extension/extensionContextFactory.js +4 -2
  26. package/lib/mcp/program.js +19 -12
  27. package/lib/mcp/terminal/cli.js +23 -2
  28. package/lib/mcp/terminal/command.js +34 -30
  29. package/lib/mcp/terminal/commands.js +310 -38
  30. package/lib/mcp/terminal/daemon.js +23 -38
  31. package/lib/mcp/terminal/helpGenerator.js +8 -6
  32. package/lib/mcp/terminal/program.js +482 -199
  33. package/lib/mcp/terminal/socketConnection.js +17 -2
  34. package/package.json +2 -2
@@ -25,22 +25,40 @@ var import_mcpBundle = require("../../mcpBundle");
25
25
  var import_command = require("./command");
26
26
  const open = (0, import_command.declareCommand)({
27
27
  name: "open",
28
- description: "Open URL",
28
+ description: "Open the browser",
29
29
  category: "core",
30
30
  args: import_mcpBundle.z.object({
31
- url: import_mcpBundle.z.string().describe("The URL to navigate to")
31
+ url: import_mcpBundle.z.string().optional().describe("The URL to navigate to")
32
+ }),
33
+ options: import_mcpBundle.z.object({
34
+ browser: import_mcpBundle.z.string().optional().describe("Browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge."),
35
+ config: import_mcpBundle.z.string().optional().describe("Path to the configuration file, defaults to .playwright/cli.config.json"),
36
+ extension: import_mcpBundle.z.boolean().optional().describe("Connect to browser extension"),
37
+ headed: import_mcpBundle.z.boolean().optional().describe("Run browser in headed mode"),
38
+ persistent: import_mcpBundle.z.boolean().optional().describe("Use persistent browser profile"),
39
+ profile: import_mcpBundle.z.string().optional().describe("Use persistent browser profile, store profile in specified directory.")
32
40
  }),
33
41
  toolName: "browser_navigate",
34
- toolParams: ({ url }) => ({ url })
42
+ toolParams: ({ url }) => ({ url: url || "about:blank" })
35
43
  });
36
44
  const close = (0, import_command.declareCommand)({
37
45
  name: "close",
38
- description: "Close the page",
46
+ description: "Close the browser",
39
47
  category: "core",
40
48
  args: import_mcpBundle.z.object({}),
41
49
  toolName: "",
42
50
  toolParams: () => ({})
43
51
  });
52
+ const goto = (0, import_command.declareCommand)({
53
+ name: "goto",
54
+ description: "Navigate to a URL",
55
+ category: "core",
56
+ args: import_mcpBundle.z.object({
57
+ url: import_mcpBundle.z.string().describe("The URL to navigate to")
58
+ }),
59
+ toolName: "browser_navigate",
60
+ toolParams: ({ url }) => ({ url })
61
+ });
44
62
  const goBack = (0, import_command.declareCommand)({
45
63
  name: "go-back",
46
64
  description: "Go back to the previous page",
@@ -186,9 +204,6 @@ const drag = (0, import_command.declareCommand)({
186
204
  startRef: import_mcpBundle.z.string().describe("Exact source element reference from the page snapshot"),
187
205
  endRef: import_mcpBundle.z.string().describe("Exact target element reference from the page snapshot")
188
206
  }),
189
- options: import_mcpBundle.z.object({
190
- headed: import_mcpBundle.z.boolean().default(false).describe("Run browser in headed mode")
191
- }),
192
207
  toolName: "browser_drag",
193
208
  toolParams: ({ startRef, endRef }) => ({ startRef, endRef })
194
209
  });
@@ -356,6 +371,221 @@ const tabSelect = (0, import_command.declareCommand)({
356
371
  toolName: "browser_tabs",
357
372
  toolParams: ({ index }) => ({ action: "select", index })
358
373
  });
374
+ const stateLoad = (0, import_command.declareCommand)({
375
+ name: "state-load",
376
+ description: "Loads browser storage (authentication) state from a file",
377
+ category: "storage",
378
+ args: import_mcpBundle.z.object({
379
+ filename: import_mcpBundle.z.string().describe("File name to load the storage state from.")
380
+ }),
381
+ toolName: "browser_set_storage_state",
382
+ toolParams: ({ filename }) => ({ filename })
383
+ });
384
+ const stateSave = (0, import_command.declareCommand)({
385
+ name: "state-save",
386
+ description: "Saves the current storage (authentication) state to a file",
387
+ category: "storage",
388
+ args: import_mcpBundle.z.object({
389
+ filename: import_mcpBundle.z.string().optional().describe("File name to save the storage state to.")
390
+ }),
391
+ toolName: "browser_storage_state",
392
+ toolParams: ({ filename }) => ({ filename })
393
+ });
394
+ const cookieList = (0, import_command.declareCommand)({
395
+ name: "cookie-list",
396
+ description: "List all cookies (optionally filtered by domain/path)",
397
+ category: "storage",
398
+ args: import_mcpBundle.z.object({}),
399
+ options: import_mcpBundle.z.object({
400
+ domain: import_mcpBundle.z.string().optional().describe("Filter cookies by domain"),
401
+ path: import_mcpBundle.z.string().optional().describe("Filter cookies by path")
402
+ }),
403
+ toolName: "browser_cookie_list",
404
+ toolParams: ({ domain, path }) => ({ domain, path })
405
+ });
406
+ const cookieGet = (0, import_command.declareCommand)({
407
+ name: "cookie-get",
408
+ description: "Get a specific cookie by name",
409
+ category: "storage",
410
+ args: import_mcpBundle.z.object({
411
+ name: import_mcpBundle.z.string().describe("Cookie name")
412
+ }),
413
+ toolName: "browser_cookie_get",
414
+ toolParams: ({ name }) => ({ name })
415
+ });
416
+ const cookieSet = (0, import_command.declareCommand)({
417
+ name: "cookie-set",
418
+ description: "Set a cookie with optional flags",
419
+ category: "storage",
420
+ args: import_mcpBundle.z.object({
421
+ name: import_mcpBundle.z.string().describe("Cookie name"),
422
+ value: import_mcpBundle.z.string().describe("Cookie value")
423
+ }),
424
+ options: import_mcpBundle.z.object({
425
+ domain: import_mcpBundle.z.string().optional().describe("Cookie domain"),
426
+ path: import_mcpBundle.z.string().optional().describe("Cookie path"),
427
+ expires: import_mcpBundle.z.number().optional().describe("Cookie expiration as Unix timestamp"),
428
+ httpOnly: import_mcpBundle.z.boolean().optional().describe("Whether the cookie is HTTP only"),
429
+ secure: import_mcpBundle.z.boolean().optional().describe("Whether the cookie is secure"),
430
+ sameSite: import_mcpBundle.z.enum(["Strict", "Lax", "None"]).optional().describe("Cookie SameSite attribute")
431
+ }),
432
+ toolName: "browser_cookie_set",
433
+ toolParams: ({ name, value, domain, path, expires, httpOnly, secure, sameSite }) => ({ name, value, domain, path, expires, httpOnly, secure, sameSite })
434
+ });
435
+ const cookieDelete = (0, import_command.declareCommand)({
436
+ name: "cookie-delete",
437
+ description: "Delete a specific cookie",
438
+ category: "storage",
439
+ args: import_mcpBundle.z.object({
440
+ name: import_mcpBundle.z.string().describe("Cookie name")
441
+ }),
442
+ toolName: "browser_cookie_delete",
443
+ toolParams: ({ name }) => ({ name })
444
+ });
445
+ const cookieClear = (0, import_command.declareCommand)({
446
+ name: "cookie-clear",
447
+ description: "Clear all cookies",
448
+ category: "storage",
449
+ args: import_mcpBundle.z.object({}),
450
+ toolName: "browser_cookie_clear",
451
+ toolParams: () => ({})
452
+ });
453
+ const localStorageList = (0, import_command.declareCommand)({
454
+ name: "localstorage-list",
455
+ description: "List all localStorage key-value pairs",
456
+ category: "storage",
457
+ args: import_mcpBundle.z.object({}),
458
+ toolName: "browser_localstorage_list",
459
+ toolParams: () => ({})
460
+ });
461
+ const localStorageGet = (0, import_command.declareCommand)({
462
+ name: "localstorage-get",
463
+ description: "Get a localStorage item by key",
464
+ category: "storage",
465
+ args: import_mcpBundle.z.object({
466
+ key: import_mcpBundle.z.string().describe("Key to get")
467
+ }),
468
+ toolName: "browser_localstorage_get",
469
+ toolParams: ({ key }) => ({ key })
470
+ });
471
+ const localStorageSet = (0, import_command.declareCommand)({
472
+ name: "localstorage-set",
473
+ description: "Set a localStorage item",
474
+ category: "storage",
475
+ args: import_mcpBundle.z.object({
476
+ key: import_mcpBundle.z.string().describe("Key to set"),
477
+ value: import_mcpBundle.z.string().describe("Value to set")
478
+ }),
479
+ toolName: "browser_localstorage_set",
480
+ toolParams: ({ key, value }) => ({ key, value })
481
+ });
482
+ const localStorageDelete = (0, import_command.declareCommand)({
483
+ name: "localstorage-delete",
484
+ description: "Delete a localStorage item",
485
+ category: "storage",
486
+ args: import_mcpBundle.z.object({
487
+ key: import_mcpBundle.z.string().describe("Key to delete")
488
+ }),
489
+ toolName: "browser_localstorage_delete",
490
+ toolParams: ({ key }) => ({ key })
491
+ });
492
+ const localStorageClear = (0, import_command.declareCommand)({
493
+ name: "localstorage-clear",
494
+ description: "Clear all localStorage",
495
+ category: "storage",
496
+ args: import_mcpBundle.z.object({}),
497
+ toolName: "browser_localstorage_clear",
498
+ toolParams: () => ({})
499
+ });
500
+ const sessionStorageList = (0, import_command.declareCommand)({
501
+ name: "sessionstorage-list",
502
+ description: "List all sessionStorage key-value pairs",
503
+ category: "storage",
504
+ args: import_mcpBundle.z.object({}),
505
+ toolName: "browser_sessionstorage_list",
506
+ toolParams: () => ({})
507
+ });
508
+ const sessionStorageGet = (0, import_command.declareCommand)({
509
+ name: "sessionstorage-get",
510
+ description: "Get a sessionStorage item by key",
511
+ category: "storage",
512
+ args: import_mcpBundle.z.object({
513
+ key: import_mcpBundle.z.string().describe("Key to get")
514
+ }),
515
+ toolName: "browser_sessionstorage_get",
516
+ toolParams: ({ key }) => ({ key })
517
+ });
518
+ const sessionStorageSet = (0, import_command.declareCommand)({
519
+ name: "sessionstorage-set",
520
+ description: "Set a sessionStorage item",
521
+ category: "storage",
522
+ args: import_mcpBundle.z.object({
523
+ key: import_mcpBundle.z.string().describe("Key to set"),
524
+ value: import_mcpBundle.z.string().describe("Value to set")
525
+ }),
526
+ toolName: "browser_sessionstorage_set",
527
+ toolParams: ({ key, value }) => ({ key, value })
528
+ });
529
+ const sessionStorageDelete = (0, import_command.declareCommand)({
530
+ name: "sessionstorage-delete",
531
+ description: "Delete a sessionStorage item",
532
+ category: "storage",
533
+ args: import_mcpBundle.z.object({
534
+ key: import_mcpBundle.z.string().describe("Key to delete")
535
+ }),
536
+ toolName: "browser_sessionstorage_delete",
537
+ toolParams: ({ key }) => ({ key })
538
+ });
539
+ const sessionStorageClear = (0, import_command.declareCommand)({
540
+ name: "sessionstorage-clear",
541
+ description: "Clear all sessionStorage",
542
+ category: "storage",
543
+ args: import_mcpBundle.z.object({}),
544
+ toolName: "browser_sessionstorage_clear",
545
+ toolParams: () => ({})
546
+ });
547
+ const routeMock = (0, import_command.declareCommand)({
548
+ name: "route",
549
+ description: "Mock network requests matching a URL pattern",
550
+ category: "network",
551
+ args: import_mcpBundle.z.object({
552
+ pattern: import_mcpBundle.z.string().describe('URL pattern to match (e.g., "**/api/users")')
553
+ }),
554
+ options: import_mcpBundle.z.object({
555
+ status: import_mcpBundle.z.number().optional().describe("HTTP status code (default: 200)"),
556
+ body: import_mcpBundle.z.string().optional().describe("Response body (text or JSON string)"),
557
+ ["content-type"]: import_mcpBundle.z.string().optional().describe("Content-Type header"),
558
+ header: import_mcpBundle.z.union([import_mcpBundle.z.string(), import_mcpBundle.z.array(import_mcpBundle.z.string())]).optional().transform((v) => v ? Array.isArray(v) ? v : [v] : void 0).describe('Header to add in "Name: Value" format (repeatable)'),
559
+ ["remove-header"]: import_mcpBundle.z.string().optional().describe("Comma-separated header names to remove")
560
+ }),
561
+ toolName: "browser_route",
562
+ toolParams: ({ pattern, status, body, ["content-type"]: contentType, header: headers, ["remove-header"]: removeHeaders }) => ({
563
+ pattern,
564
+ status,
565
+ body,
566
+ contentType,
567
+ headers,
568
+ removeHeaders
569
+ })
570
+ });
571
+ const routeList = (0, import_command.declareCommand)({
572
+ name: "route-list",
573
+ description: "List all active network routes",
574
+ category: "network",
575
+ args: import_mcpBundle.z.object({}),
576
+ toolName: "browser_route_list",
577
+ toolParams: () => ({})
578
+ });
579
+ const unroute = (0, import_command.declareCommand)({
580
+ name: "unroute",
581
+ description: "Remove routes matching a pattern (or all routes)",
582
+ category: "network",
583
+ args: import_mcpBundle.z.object({
584
+ pattern: import_mcpBundle.z.string().optional().describe("URL pattern to unroute (omit to remove all)")
585
+ }),
586
+ toolName: "browser_unroute",
587
+ toolParams: ({ pattern }) => ({ pattern })
588
+ });
359
589
  const screenshot = (0, import_command.declareCommand)({
360
590
  name: "screenshot",
361
591
  description: "screenshot of the current page or element",
@@ -441,54 +671,71 @@ const videoStop = (0, import_command.declareCommand)({
441
671
  toolParams: ({ filename }) => ({ filename })
442
672
  });
443
673
  const sessionList = (0, import_command.declareCommand)({
444
- name: "session-list",
445
- description: "List all sessions",
446
- category: "session",
674
+ name: "list",
675
+ description: "List browser sessions",
676
+ category: "browsers",
447
677
  args: import_mcpBundle.z.object({}),
678
+ options: import_mcpBundle.z.object({
679
+ all: import_mcpBundle.z.boolean().optional().describe("List all browser sessions across all workspaces")
680
+ }),
448
681
  toolName: "",
449
682
  toolParams: () => ({})
450
683
  });
451
- const sessionStop = (0, import_command.declareCommand)({
452
- name: "session-stop",
453
- description: "Stop session",
454
- category: "session",
455
- args: import_mcpBundle.z.object({
456
- name: import_mcpBundle.z.string().optional().describe("Name of the session to stop. If omitted, current session is stopped.")
457
- }),
684
+ const sessionCloseAll = (0, import_command.declareCommand)({
685
+ name: "close-all",
686
+ description: "Close all browser sessions",
687
+ category: "browsers",
458
688
  toolName: "",
459
689
  toolParams: () => ({})
460
690
  });
461
- const sessionStopAll = (0, import_command.declareCommand)({
462
- name: "session-stop-all",
463
- description: "Stop all sessions",
464
- category: "session",
691
+ const killAll = (0, import_command.declareCommand)({
692
+ name: "kill-all",
693
+ description: "Forcefully kill all browser sessions (for stale/zombie processes)",
694
+ category: "browsers",
465
695
  toolName: "",
466
696
  toolParams: () => ({})
467
697
  });
468
- const sessionDelete = (0, import_command.declareCommand)({
469
- name: "session-delete",
698
+ const deleteData = (0, import_command.declareCommand)({
699
+ name: "delete-data",
470
700
  description: "Delete session data",
471
- category: "session",
472
- args: import_mcpBundle.z.object({
473
- name: import_mcpBundle.z.string().optional().describe("Name of the session to delete. If omitted, current session is deleted.")
474
- }),
701
+ category: "core",
475
702
  toolName: "",
476
- toolParams: ({ name }) => ({ name })
703
+ toolParams: () => ({})
477
704
  });
478
- const config = (0, import_command.declareCommand)({
479
- name: "config",
480
- description: "Restart session with new config, defaults to `playwright-cli.json`",
705
+ const configPrint = (0, import_command.declareCommand)({
706
+ name: "config-print",
707
+ description: "Print the final resolved config after merging CLI options, environment variables and config file.",
481
708
  category: "config",
482
- args: import_mcpBundle.z.object({
483
- config: import_mcpBundle.z.string().optional().describe("Path to the configuration file")
709
+ hidden: true,
710
+ toolName: "browser_get_config",
711
+ toolParams: () => ({})
712
+ });
713
+ const install = (0, import_command.declareCommand)({
714
+ name: "install",
715
+ description: "Initialize workspace",
716
+ category: "install",
717
+ args: import_mcpBundle.z.object({}),
718
+ options: import_mcpBundle.z.object({
719
+ skills: import_mcpBundle.z.boolean().optional().describe("Install skills for Claude / GitHub Copilot")
484
720
  }),
485
721
  toolName: "",
486
722
  toolParams: () => ({})
487
723
  });
724
+ const installBrowser = (0, import_command.declareCommand)({
725
+ name: "install-browser",
726
+ description: "Install browser",
727
+ category: "install",
728
+ options: import_mcpBundle.z.object({
729
+ browser: import_mcpBundle.z.string().optional().describe("Browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge")
730
+ }),
731
+ toolName: "browser_install",
732
+ toolParams: () => ({})
733
+ });
488
734
  const commandsArray = [
489
735
  // core category
490
736
  open,
491
737
  close,
738
+ goto,
492
739
  type,
493
740
  click,
494
741
  doubleClick,
@@ -506,6 +753,7 @@ const commandsArray = [
506
753
  dialogDismiss,
507
754
  resize,
508
755
  runCode,
756
+ deleteData,
509
757
  // navigation category
510
758
  goBack,
511
759
  goForward,
@@ -527,8 +775,33 @@ const commandsArray = [
527
775
  tabNew,
528
776
  tabClose,
529
777
  tabSelect,
530
- // config
531
- config,
778
+ // storage category
779
+ stateLoad,
780
+ stateSave,
781
+ cookieList,
782
+ cookieGet,
783
+ cookieSet,
784
+ cookieDelete,
785
+ cookieClear,
786
+ localStorageList,
787
+ localStorageGet,
788
+ localStorageSet,
789
+ localStorageDelete,
790
+ localStorageClear,
791
+ sessionStorageList,
792
+ sessionStorageGet,
793
+ sessionStorageSet,
794
+ sessionStorageDelete,
795
+ sessionStorageClear,
796
+ // network category
797
+ routeMock,
798
+ routeList,
799
+ unroute,
800
+ // config category
801
+ configPrint,
802
+ // install category
803
+ install,
804
+ installBrowser,
532
805
  // devtools category
533
806
  networkRequests,
534
807
  tracingStart,
@@ -537,9 +810,8 @@ const commandsArray = [
537
810
  videoStop,
538
811
  // session category
539
812
  sessionList,
540
- sessionStop,
541
- sessionStopAll,
542
- sessionDelete
813
+ sessionCloseAll,
814
+ killAll
543
815
  ];
544
816
  const commands = Object.fromEntries(commandsArray.map((cmd) => [cmd.name, cmd]));
545
817
  // Annotate the CommonJS export names for ESM import in node:
@@ -38,6 +38,7 @@ var import_path = __toESM(require("path"));
38
38
  var import_url = __toESM(require("url"));
39
39
  var import_utilsBundle = require("playwright-core/lib/utilsBundle");
40
40
  var import_utils = require("playwright-core/lib/utils");
41
+ var import_browserServerBackend = require("../browser/browserServerBackend");
41
42
  var import_socketConnection = require("./socketConnection");
42
43
  var import_commands = require("./commands");
43
44
  var import_command = require("./command");
@@ -51,7 +52,9 @@ async function socketExists(socketPath) {
51
52
  }
52
53
  return false;
53
54
  }
54
- async function startMcpDaemonServer(socketPath, serverBackendFactory, daemonVersion) {
55
+ async function startMcpDaemonServer(config, contextFactory) {
56
+ const sessionConfig = config.sessionConfig;
57
+ const { socketPath, version } = sessionConfig;
55
58
  if (import_os.default.platform() !== "win32" && await socketExists(socketPath)) {
56
59
  daemonDebug(`Socket already exists, removing: ${socketPath}`);
57
60
  try {
@@ -61,37 +64,38 @@ async function startMcpDaemonServer(socketPath, serverBackendFactory, daemonVers
61
64
  throw error;
62
65
  }
63
66
  }
64
- const backend = serverBackendFactory.create();
65
67
  const cwd = import_url.default.pathToFileURL(process.cwd()).href;
66
- await backend.initialize?.({
68
+ const clientInfo = {
67
69
  name: "playwright-cli",
68
- version: "1.0.0",
70
+ version: sessionConfig.version,
69
71
  roots: [{
70
72
  uri: cwd,
71
73
  name: "cwd"
72
74
  }],
73
75
  timestamp: Date.now()
76
+ };
77
+ const { browserContext, close } = await contextFactory.createContext(clientInfo, new AbortController().signal, {});
78
+ browserContext.on("close", () => {
79
+ daemonDebug("browser closed, shutting down daemon");
80
+ shutdown(0);
74
81
  });
82
+ const existingContextFactory = {
83
+ createContext: () => Promise.resolve({ browserContext, close })
84
+ };
85
+ const backend = new import_browserServerBackend.BrowserServerBackend(config, existingContextFactory, { allTools: true });
86
+ await backend.initialize?.(clientInfo);
75
87
  await import_promises.default.mkdir(import_path.default.dirname(socketPath), { recursive: true });
88
+ const shutdown = (exitCode) => {
89
+ daemonDebug(`shutting down daemon with exit code ${exitCode}`);
90
+ server.close();
91
+ (0, import_utils.gracefullyProcessExitDoNotHang)(exitCode);
92
+ };
76
93
  const server = import_net.default.createServer((socket) => {
77
94
  daemonDebug("new client connection");
78
- const connection = new import_socketConnection.SocketConnection(socket, daemonVersion);
95
+ const connection = new import_socketConnection.SocketConnection(socket, version);
79
96
  connection.onclose = () => {
80
97
  daemonDebug("client disconnected");
81
98
  };
82
- connection.onversionerror = (id, e) => {
83
- if (daemonVersion === "undefined-for-test")
84
- return false;
85
- if (semverGreater(daemonVersion, e.received)) {
86
- connection.send({ id, error: `Client is too old: daemon is ${daemonVersion}, client is ${e.received}.` }).catch((e2) => console.error(e2));
87
- } else {
88
- (0, import_utils.gracefullyProcessExitDoNotHang)(0, async () => {
89
- await connection.send({ id, error: `Daemon is too old: daemon is ${daemonVersion}, client is ${e.received}. Stopping it.` }).catch((e2) => console.error(e2));
90
- server.close();
91
- });
92
- }
93
- return true;
94
- };
95
99
  connection.onmessage = async (message) => {
96
100
  const { id, method, params } = message;
97
101
  try {
@@ -107,8 +111,7 @@ async function startMcpDaemonServer(socketPath, serverBackendFactory, daemonVers
107
111
  const { toolName, toolParams } = parseCliCommand(params.args);
108
112
  if (params.cwd)
109
113
  toolParams._meta = { cwd: params.cwd };
110
- const response = await backend.callTool(toolName, toolParams, () => {
111
- });
114
+ const response = await backend.callTool(toolName, toolParams);
112
115
  await connection.send({ id, result: formatResult(response) });
113
116
  } else {
114
117
  throw new Error(`Unknown method: ${method}`);
@@ -119,11 +122,6 @@ async function startMcpDaemonServer(socketPath, serverBackendFactory, daemonVers
119
122
  }
120
123
  };
121
124
  });
122
- backend.onBrowserContextClosed = () => {
123
- daemonDebug("browser closed, shutting down daemon");
124
- server.close();
125
- (0, import_utils.gracefullyProcessExitDoNotHang)(0);
126
- };
127
125
  return new Promise((resolve, reject) => {
128
126
  server.on("error", (error) => {
129
127
  daemonDebug(`server error: ${error.message}`);
@@ -146,19 +144,6 @@ function parseCliCommand(args) {
146
144
  throw new Error("Command is required");
147
145
  return (0, import_command.parseCommand)(command, args);
148
146
  }
149
- function semverGreater(a, b) {
150
- a = a.replace(/-next$/, "");
151
- b = b.replace(/-next$/, "");
152
- const aParts = a.split(".").map(Number);
153
- const bParts = b.split(".").map(Number);
154
- for (let i = 0; i < 4; i++) {
155
- if (aParts[i] > bParts[i])
156
- return true;
157
- if (aParts[i] < bParts[i])
158
- return false;
159
- }
160
- return false;
161
- }
162
147
  // Annotate the CommonJS export names for ESM import in node:
163
148
  0 && (module.exports = {
164
149
  startMcpDaemonServer
@@ -68,18 +68,24 @@ const categories = [
68
68
  { name: "export", title: "Save as" },
69
69
  { name: "tabs", title: "Tabs" },
70
70
  { name: "storage", title: "Storage" },
71
+ { name: "network", title: "Network" },
71
72
  { name: "devtools", title: "DevTools" },
73
+ { name: "install", title: "Install" },
72
74
  { name: "config", title: "Configuration" },
73
- { name: "session", title: "Sessions" }
75
+ { name: "browsers", title: "Browser sessions" }
74
76
  ];
75
77
  function generateHelp() {
76
78
  const lines = [];
77
79
  lines.push("Usage: playwright-cli <command> [args] [options]");
80
+ lines.push("Usage: playwright-cli -s=<session> <command> [args] [options]");
78
81
  const commandsByCategory = /* @__PURE__ */ new Map();
79
82
  for (const c of categories)
80
83
  commandsByCategory.set(c.name, []);
81
- for (const command of Object.values(import_commands.commands))
84
+ for (const command of Object.values(import_commands.commands)) {
85
+ if (command.hidden)
86
+ continue;
82
87
  commandsByCategory.get(command.category).push(command);
88
+ }
83
89
  for (const c of categories) {
84
90
  const cc = commandsByCategory.get(c.name);
85
91
  if (!cc.length)
@@ -90,11 +96,7 @@ ${c.title}:`);
90
96
  lines.push(generateHelpEntry(command));
91
97
  }
92
98
  lines.push("\nGlobal options:");
93
- lines.push(formatWithGap(" --config <path>", "create a session with custom config, defaults to `playwright-cli.json`"));
94
- lines.push(formatWithGap(" --extension", "connect to a running browser instance using Playwright MCP Bridge extension"));
95
- lines.push(formatWithGap(" --headed", "create a headed session"));
96
99
  lines.push(formatWithGap(" --help [command]", "print help"));
97
- lines.push(formatWithGap(" --session", "run command in the scope of a specific session"));
98
100
  lines.push(formatWithGap(" --version", "print version"));
99
101
  return lines.join("\n");
100
102
  }