@one2x/playwright 1.57.0-alpha.1 → 1.57.0-alpha.2

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 (155) hide show
  1. package/package.json +2 -2
  2. package/lib/agents/generateAgents.js.map +0 -7
  3. package/lib/common/config.js.map +0 -7
  4. package/lib/common/configLoader.js.map +0 -7
  5. package/lib/common/esmLoaderHost.js.map +0 -7
  6. package/lib/common/expectBundle.js.map +0 -7
  7. package/lib/common/expectBundleImpl.js.map +0 -7
  8. package/lib/common/fixtures.js.map +0 -7
  9. package/lib/common/globals.js.map +0 -7
  10. package/lib/common/ipc.js.map +0 -7
  11. package/lib/common/poolBuilder.js.map +0 -7
  12. package/lib/common/process.js.map +0 -7
  13. package/lib/common/suiteUtils.js.map +0 -7
  14. package/lib/common/test.js.map +0 -7
  15. package/lib/common/testLoader.js.map +0 -7
  16. package/lib/common/testType.js.map +0 -7
  17. package/lib/common/validators.js.map +0 -7
  18. package/lib/fsWatcher.js.map +0 -7
  19. package/lib/index.js.map +0 -7
  20. package/lib/internalsForTest.js.map +0 -7
  21. package/lib/isomorphic/events.js.map +0 -7
  22. package/lib/isomorphic/folders.js.map +0 -7
  23. package/lib/isomorphic/stringInternPool.js.map +0 -7
  24. package/lib/isomorphic/teleReceiver.js.map +0 -7
  25. package/lib/isomorphic/teleSuiteUpdater.js.map +0 -7
  26. package/lib/isomorphic/testServerConnection.js.map +0 -7
  27. package/lib/isomorphic/testServerInterface.js.map +0 -7
  28. package/lib/isomorphic/testTree.js.map +0 -7
  29. package/lib/isomorphic/types.d.js.map +0 -7
  30. package/lib/loader/loaderMain.js.map +0 -7
  31. package/lib/matchers/expect.js.map +0 -7
  32. package/lib/matchers/matcherHint.js.map +0 -7
  33. package/lib/matchers/matchers.js.map +0 -7
  34. package/lib/matchers/toBeTruthy.js.map +0 -7
  35. package/lib/matchers/toEqual.js.map +0 -7
  36. package/lib/matchers/toHaveURL.js.map +0 -7
  37. package/lib/matchers/toMatchAriaSnapshot.js.map +0 -7
  38. package/lib/matchers/toMatchSnapshot.js.map +0 -7
  39. package/lib/matchers/toMatchText.js.map +0 -7
  40. package/lib/mcp/browser/actions.d.js.map +0 -7
  41. package/lib/mcp/browser/browserContextFactory.js.map +0 -7
  42. package/lib/mcp/browser/browserServerBackend.js.map +0 -7
  43. package/lib/mcp/browser/codegen.js.map +0 -7
  44. package/lib/mcp/browser/config.js.map +0 -7
  45. package/lib/mcp/browser/context.js.map +0 -7
  46. package/lib/mcp/browser/response.js.map +0 -7
  47. package/lib/mcp/browser/sessionLog.js.map +0 -7
  48. package/lib/mcp/browser/tab.js.map +0 -7
  49. package/lib/mcp/browser/tools/actionRetry.js.map +0 -7
  50. package/lib/mcp/browser/tools/common.js.map +0 -7
  51. package/lib/mcp/browser/tools/console.js.map +0 -7
  52. package/lib/mcp/browser/tools/dialogs.js.map +0 -7
  53. package/lib/mcp/browser/tools/evaluate.js.map +0 -7
  54. package/lib/mcp/browser/tools/files.js.map +0 -7
  55. package/lib/mcp/browser/tools/form.js.map +0 -7
  56. package/lib/mcp/browser/tools/install.js.map +0 -7
  57. package/lib/mcp/browser/tools/keyboard.js.map +0 -7
  58. package/lib/mcp/browser/tools/mouse.js.map +0 -7
  59. package/lib/mcp/browser/tools/navigate.js.map +0 -7
  60. package/lib/mcp/browser/tools/network.js.map +0 -7
  61. package/lib/mcp/browser/tools/pdf.js.map +0 -7
  62. package/lib/mcp/browser/tools/screenshot.js.map +0 -7
  63. package/lib/mcp/browser/tools/snapshot.js.map +0 -7
  64. package/lib/mcp/browser/tools/tabs.js.map +0 -7
  65. package/lib/mcp/browser/tools/tool.js.map +0 -7
  66. package/lib/mcp/browser/tools/tracing.js.map +0 -7
  67. package/lib/mcp/browser/tools/utils.js.map +0 -7
  68. package/lib/mcp/browser/tools/verify.js.map +0 -7
  69. package/lib/mcp/browser/tools/wait.js.map +0 -7
  70. package/lib/mcp/browser/tools.js.map +0 -7
  71. package/lib/mcp/browser/watchdog.js.map +0 -7
  72. package/lib/mcp/config.d.js.map +0 -7
  73. package/lib/mcp/extension/cdpRelay.js.map +0 -7
  74. package/lib/mcp/extension/extensionContextFactory.js.map +0 -7
  75. package/lib/mcp/extension/protocol.js.map +0 -7
  76. package/lib/mcp/index.js.map +0 -7
  77. package/lib/mcp/log.js.map +0 -7
  78. package/lib/mcp/program.js.map +0 -7
  79. package/lib/mcp/sdk/bundle.js.map +0 -7
  80. package/lib/mcp/sdk/exports.js.map +0 -7
  81. package/lib/mcp/sdk/http.js.map +0 -7
  82. package/lib/mcp/sdk/inProcessTransport.js.map +0 -7
  83. package/lib/mcp/sdk/mdb.js.map +0 -7
  84. package/lib/mcp/sdk/proxyBackend.js.map +0 -7
  85. package/lib/mcp/sdk/server.js.map +0 -7
  86. package/lib/mcp/sdk/tool.js.map +0 -7
  87. package/lib/mcp/test/browserBackend.js.map +0 -7
  88. package/lib/mcp/test/generatorTools.js.map +0 -7
  89. package/lib/mcp/test/plannerTools.js.map +0 -7
  90. package/lib/mcp/test/seed.js.map +0 -7
  91. package/lib/mcp/test/streams.js.map +0 -7
  92. package/lib/mcp/test/testBackend.js.map +0 -7
  93. package/lib/mcp/test/testContext.js.map +0 -7
  94. package/lib/mcp/test/testTool.js.map +0 -7
  95. package/lib/mcp/test/testTools.js.map +0 -7
  96. package/lib/mcpBundleImpl.js.map +0 -7
  97. package/lib/plugins/gitCommitInfoPlugin.js.map +0 -7
  98. package/lib/plugins/index.js.map +0 -7
  99. package/lib/plugins/webServerPlugin.js.map +0 -7
  100. package/lib/program.js.map +0 -7
  101. package/lib/reporters/base.js.map +0 -7
  102. package/lib/reporters/blob.js.map +0 -7
  103. package/lib/reporters/dot.js.map +0 -7
  104. package/lib/reporters/empty.js.map +0 -7
  105. package/lib/reporters/github.js.map +0 -7
  106. package/lib/reporters/html.js.map +0 -7
  107. package/lib/reporters/internalReporter.js.map +0 -7
  108. package/lib/reporters/json.js.map +0 -7
  109. package/lib/reporters/junit.js.map +0 -7
  110. package/lib/reporters/line.js.map +0 -7
  111. package/lib/reporters/list.js.map +0 -7
  112. package/lib/reporters/listModeReporter.js.map +0 -7
  113. package/lib/reporters/markdown.js.map +0 -7
  114. package/lib/reporters/merge.js.map +0 -7
  115. package/lib/reporters/multiplexer.js.map +0 -7
  116. package/lib/reporters/reporterV2.js.map +0 -7
  117. package/lib/reporters/teleEmitter.js.map +0 -7
  118. package/lib/reporters/versions/blobV1.js.map +0 -7
  119. package/lib/runner/dispatcher.js.map +0 -7
  120. package/lib/runner/failureTracker.js.map +0 -7
  121. package/lib/runner/lastRun.js.map +0 -7
  122. package/lib/runner/loadUtils.js.map +0 -7
  123. package/lib/runner/loaderHost.js.map +0 -7
  124. package/lib/runner/processHost.js.map +0 -7
  125. package/lib/runner/projectUtils.js.map +0 -7
  126. package/lib/runner/rebase.js.map +0 -7
  127. package/lib/runner/reporters.js.map +0 -7
  128. package/lib/runner/runner.js +0 -110
  129. package/lib/runner/sigIntWatcher.js.map +0 -7
  130. package/lib/runner/taskRunner.js.map +0 -7
  131. package/lib/runner/tasks.js.map +0 -7
  132. package/lib/runner/testGroups.js.map +0 -7
  133. package/lib/runner/testRunner.js.map +0 -7
  134. package/lib/runner/testServer.js.map +0 -7
  135. package/lib/runner/uiModeReporter.js.map +0 -7
  136. package/lib/runner/vcs.js.map +0 -7
  137. package/lib/runner/watchMode.js.map +0 -7
  138. package/lib/runner/workerHost.js.map +0 -7
  139. package/lib/third_party/pirates.js.map +0 -7
  140. package/lib/third_party/tsconfig-loader.js.map +0 -7
  141. package/lib/transform/babelBundle.js.map +0 -7
  142. package/lib/transform/babelBundleImpl.js.map +0 -7
  143. package/lib/transform/compilationCache.js.map +0 -7
  144. package/lib/transform/esmLoader.js.map +0 -7
  145. package/lib/transform/portTransport.js.map +0 -7
  146. package/lib/transform/transform.js.map +0 -7
  147. package/lib/util.js.map +0 -7
  148. package/lib/utilsBundle.js.map +0 -7
  149. package/lib/utilsBundleImpl.js.map +0 -7
  150. package/lib/worker/fixtureRunner.js.map +0 -7
  151. package/lib/worker/testInfo.js.map +0 -7
  152. package/lib/worker/testTracing.js.map +0 -7
  153. package/lib/worker/timeoutManager.js.map +0 -7
  154. package/lib/worker/util.js.map +0 -7
  155. package/lib/worker/workerMain.js.map +0 -7
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/keyboard.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\nimport { elementSchema } from './snapshot';\n\nconst pressKey = defineTabTool({\n capability: 'core',\n\n schema: {\n name: 'browser_press_key',\n title: 'Press a key',\n description: 'Press a key on the keyboard',\n inputSchema: z.object({\n key: z.string().describe('Name of the key to press or a character to generate, such as `ArrowLeft` or `a`'),\n }),\n type: 'input',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n response.addCode(`// Press ${params.key}`);\n response.addCode(`await page.keyboard.press('${params.key}');`);\n\n await tab.waitForCompletion(async () => {\n await tab.page.keyboard.press(params.key);\n });\n },\n});\n\nconst typeSchema = elementSchema.extend({\n text: z.string().describe('Text to type into the element'),\n submit: z.boolean().optional().describe('Whether to submit entered text (press Enter after)'),\n slowly: 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.'),\n});\n\nconst type = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_type',\n title: 'Type text',\n description: 'Type text into editable element',\n inputSchema: typeSchema,\n type: 'input',\n },\n\n handle: async (tab, params, response) => {\n const { locator, resolved } = await tab.refLocator(params);\n const secret = tab.context.lookupSecret(params.text);\n\n await tab.waitForCompletion(async () => {\n if (params.slowly) {\n response.setIncludeSnapshot();\n response.addCode(`await page.${resolved}.pressSequentially(${secret.code});`);\n await locator.pressSequentially(secret.value);\n } else {\n response.addCode(`await page.${resolved}.fill(${secret.code});`);\n await locator.fill(secret.value);\n }\n\n if (params.submit) {\n response.setIncludeSnapshot();\n response.addCode(`await page.${resolved}.press('Enter');`);\n await locator.press('Enter');\n }\n });\n },\n});\n\nexport default [\n pressKey,\n type,\n];\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAC9B,sBAA8B;AAE9B,MAAM,eAAW,2BAAc;AAAA,EAC7B,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,KAAK,gBAAE,OAAO,EAAE,SAAS,iFAAiF;AAAA,IAC5G,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,aAAS,mBAAmB;AAC5B,aAAS,QAAQ,YAAY,OAAO,GAAG,EAAE;AACzC,aAAS,QAAQ,8BAA8B,OAAO,GAAG,KAAK;AAE9D,UAAM,IAAI,kBAAkB,YAAY;AACtC,YAAM,IAAI,KAAK,SAAS,MAAM,OAAO,GAAG;AAAA,IAC1C,CAAC;AAAA,EACH;AACF,CAAC;AAED,MAAM,aAAa,8BAAc,OAAO;AAAA,EACtC,MAAM,gBAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,EACzD,QAAQ,gBAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,EAC5F,QAAQ,gBAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,uIAAuI;AACjL,CAAC;AAED,MAAM,WAAO,2BAAc;AAAA,EACzB,YAAY;AAAA,EACZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,UAAM,EAAE,SAAS,SAAS,IAAI,MAAM,IAAI,WAAW,MAAM;AACzD,UAAM,SAAS,IAAI,QAAQ,aAAa,OAAO,IAAI;AAEnD,UAAM,IAAI,kBAAkB,YAAY;AACtC,UAAI,OAAO,QAAQ;AACjB,iBAAS,mBAAmB;AAC5B,iBAAS,QAAQ,cAAc,QAAQ,sBAAsB,OAAO,IAAI,IAAI;AAC5E,cAAM,QAAQ,kBAAkB,OAAO,KAAK;AAAA,MAC9C,OAAO;AACL,iBAAS,QAAQ,cAAc,QAAQ,SAAS,OAAO,IAAI,IAAI;AAC/D,cAAM,QAAQ,KAAK,OAAO,KAAK;AAAA,MACjC;AAEA,UAAI,OAAO,QAAQ;AACjB,iBAAS,mBAAmB;AAC5B,iBAAS,QAAQ,cAAc,QAAQ,kBAAkB;AACzD,cAAM,QAAQ,MAAM,OAAO;AAAA,MAC7B;AAAA,IACF,CAAC;AAAA,EACH;AACF,CAAC;AAED,IAAO,mBAAQ;AAAA,EACb;AAAA,EACA;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/mouse.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\n\nconst elementSchema = z.object({\n element: z.string().describe('Human-readable element description used to obtain permission to interact with the element'),\n});\n\nconst mouseMove = defineTabTool({\n capability: 'vision',\n schema: {\n name: 'browser_mouse_move_xy',\n title: 'Move mouse',\n description: 'Move mouse to a given position',\n inputSchema: elementSchema.extend({\n x: z.number().describe('X coordinate'),\n y: z.number().describe('Y coordinate'),\n }),\n type: 'input',\n },\n\n handle: async (tab, params, response) => {\n response.addCode(`// Move mouse to (${params.x}, ${params.y})`);\n response.addCode(`await page.mouse.move(${params.x}, ${params.y});`);\n\n await tab.waitForCompletion(async () => {\n await tab.page.mouse.move(params.x, params.y);\n });\n },\n});\n\nconst mouseClick = defineTabTool({\n capability: 'vision',\n schema: {\n name: 'browser_mouse_click_xy',\n title: 'Click',\n description: 'Click left mouse button at a given position',\n inputSchema: elementSchema.extend({\n x: z.number().describe('X coordinate'),\n y: z.number().describe('Y coordinate'),\n }),\n type: 'input',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n response.addCode(`// Click mouse at coordinates (${params.x}, ${params.y})`);\n response.addCode(`await page.mouse.move(${params.x}, ${params.y});`);\n response.addCode(`await page.mouse.down();`);\n response.addCode(`await page.mouse.up();`);\n\n await tab.waitForCompletion(async () => {\n await tab.page.mouse.move(params.x, params.y);\n await tab.page.mouse.down();\n await tab.page.mouse.up();\n });\n },\n});\n\nconst mouseDrag = defineTabTool({\n capability: 'vision',\n schema: {\n name: 'browser_mouse_drag_xy',\n title: 'Drag mouse',\n description: 'Drag left mouse button to a given position',\n inputSchema: elementSchema.extend({\n startX: z.number().describe('Start X coordinate'),\n startY: z.number().describe('Start Y coordinate'),\n endX: z.number().describe('End X coordinate'),\n endY: z.number().describe('End Y coordinate'),\n }),\n type: 'input',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n response.addCode(`// Drag mouse from (${params.startX}, ${params.startY}) to (${params.endX}, ${params.endY})`);\n response.addCode(`await page.mouse.move(${params.startX}, ${params.startY});`);\n response.addCode(`await page.mouse.down();`);\n response.addCode(`await page.mouse.move(${params.endX}, ${params.endY});`);\n response.addCode(`await page.mouse.up();`);\n\n await tab.waitForCompletion(async () => {\n await tab.page.mouse.move(params.startX, params.startY);\n await tab.page.mouse.down();\n await tab.page.mouse.move(params.endX, params.endY);\n await tab.page.mouse.up();\n });\n },\n});\n\nexport default [\n mouseMove,\n mouseClick,\n mouseDrag,\n];\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/navigate.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTool, defineTabTool } from './tool';\n\nconst navigate = defineTool({\n capability: 'core',\n\n schema: {\n name: 'browser_navigate',\n title: 'Navigate to a absolute URL',\n description: 'Navigate to a absolute URL',\n inputSchema: z.object({\n url: z.string().describe('The absolute URL to navigate to'),\n }),\n type: 'action',\n },\n\n handle: async (context, params, response) => {\n const tab = await context.ensureTab();\n await tab.navigate(params.url);\n\n response.setIncludeSnapshot();\n response.addCode(`await page.goto('${params.url}');`);\n },\n});\n\nconst goBack = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_navigate_back',\n title: 'Go back',\n description: 'Go back to the previous page',\n inputSchema: z.object({}),\n type: 'action',\n },\n\n handle: async (tab, params, response) => {\n await tab.page.goBack();\n response.setIncludeSnapshot();\n response.addCode(`await page.goBack();`);\n },\n});\n\nexport default [\n navigate,\n goBack,\n];\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA0C;AAE1C,MAAM,eAAW,wBAAW;AAAA,EAC1B,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,KAAK,gBAAE,OAAO,EAAE,SAAS,iCAAiC;AAAA,IAC5D,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,SAAS,QAAQ,aAAa;AAC3C,UAAM,MAAM,MAAM,QAAQ,UAAU;AACpC,UAAM,IAAI,SAAS,OAAO,GAAG;AAE7B,aAAS,mBAAmB;AAC5B,aAAS,QAAQ,oBAAoB,OAAO,GAAG,KAAK;AAAA,EACtD;AACF,CAAC;AAED,MAAM,aAAS,2BAAc;AAAA,EAC3B,YAAY;AAAA,EACZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO,CAAC,CAAC;AAAA,IACxB,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,UAAM,IAAI,KAAK,OAAO;AACtB,aAAS,mBAAmB;AAC5B,aAAS,QAAQ,sBAAsB;AAAA,EACzC;AACF,CAAC;AAED,IAAO,mBAAQ;AAAA,EACb;AAAA,EACA;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/network.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\n\nimport type * as playwright from 'playwright-core';\nimport type { Request } from '../../../../../playwright-core/src/client/network';\n\nconst requests = defineTabTool({\n capability: 'core',\n\n schema: {\n name: 'browser_network_requests',\n title: 'List network requests',\n description: 'Returns all network requests since loading the page',\n inputSchema: z.object({}),\n type: 'readOnly',\n },\n\n handle: async (tab, params, response) => {\n const requests = await tab.requests();\n for (const request of requests)\n response.addResult(await renderRequest(request));\n },\n});\n\nasync function renderRequest(request: playwright.Request) {\n const result: string[] = [];\n result.push(`[${request.method().toUpperCase()}] ${request.url()}`);\n const hasResponse = (request as Request)._hasResponse;\n if (hasResponse) {\n const response = await request.response();\n if (response)\n result.push(`=> [${response.status()}] ${response.statusText()}`);\n }\n return result.join(' ');\n}\n\nexport default [\n requests,\n];\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAK9B,MAAM,eAAW,2BAAc;AAAA,EAC7B,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO,CAAC,CAAC;AAAA,IACxB,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,UAAMA,YAAW,MAAM,IAAI,SAAS;AACpC,eAAW,WAAWA;AACpB,eAAS,UAAU,MAAM,cAAc,OAAO,CAAC;AAAA,EACnD;AACF,CAAC;AAED,eAAe,cAAc,SAA6B;AACxD,QAAM,SAAmB,CAAC;AAC1B,SAAO,KAAK,IAAI,QAAQ,OAAO,EAAE,YAAY,CAAC,KAAK,QAAQ,IAAI,CAAC,EAAE;AAClE,QAAM,cAAe,QAAoB;AACzC,MAAI,aAAa;AACf,UAAM,WAAW,MAAM,QAAQ,SAAS;AACxC,QAAI;AACF,aAAO,KAAK,OAAO,SAAS,OAAO,CAAC,KAAK,SAAS,WAAW,CAAC,EAAE;AAAA,EACpE;AACA,SAAO,OAAO,KAAK,GAAG;AACxB;AAEA,IAAO,kBAAQ;AAAA,EACb;AACF;",
6
- "names": ["requests"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/pdf.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\nimport * as javascript from '../codegen';\nimport { dateAsFileName } from './utils';\n\nconst pdfSchema = z.object({\n filename: z.string().optional().describe('File name to save the pdf to. Defaults to `page-{timestamp}.pdf` if not specified. Prefer relative file names to stay within the output directory.'),\n});\n\nconst pdf = defineTabTool({\n capability: 'pdf',\n\n schema: {\n name: 'browser_pdf_save',\n title: 'Save as PDF',\n description: 'Save page as PDF',\n inputSchema: pdfSchema,\n type: 'readOnly',\n },\n\n handle: async (tab, params, response) => {\n const fileName = await tab.context.outputFile(params.filename ?? dateAsFileName('pdf'), { origin: 'llm', reason: 'Saving PDF' });\n response.addCode(`await page.pdf(${javascript.formatObject({ path: fileName })});`);\n response.addResult(`Saved page as ${fileName}`);\n await tab.page.pdf({ path: fileName });\n },\n});\n\nexport default [\n pdf,\n];\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAC9B,iBAA4B;AAC5B,mBAA+B;AAE/B,MAAM,YAAY,gBAAE,OAAO;AAAA,EACzB,UAAU,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oJAAoJ;AAC/L,CAAC;AAED,MAAM,UAAM,2BAAc;AAAA,EACxB,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,UAAM,WAAW,MAAM,IAAI,QAAQ,WAAW,OAAO,gBAAY,6BAAe,KAAK,GAAG,EAAE,QAAQ,OAAO,QAAQ,aAAa,CAAC;AAC/H,aAAS,QAAQ,kBAAkB,WAAW,aAAa,EAAE,MAAM,SAAS,CAAC,CAAC,IAAI;AAClF,aAAS,UAAU,iBAAiB,QAAQ,EAAE;AAC9C,UAAM,IAAI,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAAA,EACvC;AACF,CAAC;AAED,IAAO,cAAQ;AAAA,EACb;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/screenshot.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs';\n\nimport { mkdirIfNeeded, scaleImageToSize } from 'playwright-core/lib/utils';\nimport { jpegjs, PNG } from 'playwright-core/lib/utilsBundle';\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\nimport * as javascript from '../codegen';\nimport { dateAsFileName } from './utils';\n\nimport type * as playwright from 'playwright-core';\n\nconst screenshotSchema = z.object({\n type: z.enum(['png', 'jpeg']).default('png').describe('Image format for the screenshot. Default is png.'),\n filename: z.string().optional().describe('File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified. Prefer relative file names to stay within the output directory.'),\n element: z.string().optional().describe('Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too.'),\n ref: z.string().optional().describe('Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.'),\n fullPage: z.boolean().optional().describe('When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots.'),\n});\n\nconst screenshot = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_take_screenshot',\n title: 'Take a screenshot',\n description: `Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.`,\n inputSchema: screenshotSchema,\n type: 'readOnly',\n },\n\n handle: async (tab, params, response) => {\n if (!!params.element !== !!params.ref)\n throw new Error('Both element and ref must be provided or neither.');\n if (params.fullPage && params.ref)\n throw new Error('fullPage cannot be used with element screenshots.');\n\n const fileType = params.type || 'png';\n const fileName = await tab.context.outputFile(params.filename || dateAsFileName(fileType), { origin: 'llm', reason: 'Saving screenshot' });\n const options: playwright.PageScreenshotOptions = {\n type: fileType,\n quality: fileType === 'png' ? undefined : 90,\n scale: 'css',\n ...(params.fullPage !== undefined && { fullPage: params.fullPage })\n };\n const isElementScreenshot = params.element && params.ref;\n\n const screenshotTarget = isElementScreenshot ? params.element : (params.fullPage ? 'full page' : 'viewport');\n response.addCode(`// Screenshot ${screenshotTarget} and save it as ${fileName}`);\n\n // Only get snapshot when element screenshot is needed\n const ref = params.ref ? await tab.refLocator({ element: params.element || '', ref: params.ref }) : null;\n\n if (ref)\n response.addCode(`await page.${ref.resolved}.screenshot(${javascript.formatObject(options)});`);\n else\n response.addCode(`await page.screenshot(${javascript.formatObject(options)});`);\n\n const buffer = ref ? await ref.locator.screenshot(options) : await tab.page.screenshot(options);\n\n await mkdirIfNeeded(fileName);\n await fs.promises.writeFile(fileName, buffer);\n\n response.addResult(`Took the ${screenshotTarget} screenshot and saved it as ${fileName}`);\n\n response.addImage({\n contentType: fileType === 'png' ? 'image/png' : 'image/jpeg',\n data: scaleImageToFitMessage(buffer, fileType)\n });\n }\n});\n\nexport function scaleImageToFitMessage(buffer: Buffer, imageType: 'png' | 'jpeg'): Buffer {\n // https://docs.claude.com/en/docs/build-with-claude/vision#evaluate-image-size\n // Not more than 1.15 megapixel, linear size not more than 1568.\n\n const image = imageType === 'png' ? PNG.sync.read(buffer) : jpegjs.decode(buffer, { maxMemoryUsageInMB: 512 });\n const pixels = image.width * image.height;\n\n const shrink = Math.min(1568 / image.width, 1568 / image.height, Math.sqrt(1.15 * 1024 * 1024 / pixels));\n if (shrink > 1)\n return buffer;\n\n const width = image.width * shrink | 0;\n const height = image.height * shrink | 0;\n const scaledImage = scaleImageToSize(image, { width, height });\n return imageType === 'png' ? PNG.sync.write(scaledImage as any) : jpegjs.encode(scaledImage, 80).data;\n}\n\nexport default [\n screenshot,\n];\n"],
5
- "mappings": "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",
6
- "names": ["import_utils", "fs"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/snapshot.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool, defineTool } from './tool';\nimport * as javascript from '../codegen';\nimport { generateLocators } from './utils';\nimport { retryWithAllowIntercept } from './actionRetry';\n\nconst snapshot = defineTool({\n capability: 'core',\n schema: {\n name: 'browser_snapshot',\n title: 'Page snapshot',\n description: 'Capture accessibility snapshot of the current page, this is better than screenshot',\n inputSchema: z.object({}),\n type: 'readOnly',\n },\n\n handle: async (context, params, response) => {\n await context.ensureTab();\n response.setIncludeSnapshot('full');\n },\n});\n\nexport const elementSchema = z.object({\n element: z.string().describe('Human-readable element description used to obtain permission to interact with the element'),\n ref: z.string().describe('Exact target element reference from the page snapshot'),\n});\n\nconst clickSchema = elementSchema.extend({\n doubleClick: z.boolean().optional().describe('Whether to perform a double click instead of a single click'),\n button: z.enum(['left', 'right', 'middle']).optional().describe('Button to click, defaults to left'),\n modifiers: z.array(z.enum(['Alt', 'Control', 'ControlOrMeta', 'Meta', 'Shift'])).optional().describe('Modifier keys to press'),\n});\n\nconst click = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_click',\n title: 'Click',\n description: 'Perform click on a web page',\n inputSchema: clickSchema,\n type: 'input',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n const { locator, resolved } = await tab.refLocator(params);\n const options = {\n button: params.button,\n modifiers: params.modifiers,\n };\n\n let usedAllowIntercept = false;\n await tab.waitForCompletion(async () => {\n const result = await retryWithAllowIntercept(\n async (opts) => {\n if (params.doubleClick)\n await locator.dblclick(opts);\n else\n await locator.click(opts);\n },\n options\n );\n usedAllowIntercept = result.usedAllowIntercept;\n });\n\n const finalOptions = usedAllowIntercept ? { ...options, allowIntercept: true } : options;\n const formatted = javascript.formatObject(finalOptions, ' ', 'oneline');\n const optionsAttr = formatted !== '{}' ? formatted : '';\n\n if (params.doubleClick)\n response.addCode(`await page.${resolved}.dblclick(${optionsAttr});`);\n else\n response.addCode(`await page.${resolved}.click(${optionsAttr});`);\n },\n});\n\nconst drag = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_drag',\n title: 'Drag mouse',\n description: 'Perform drag and drop between two elements',\n inputSchema: z.object({\n startElement: z.string().describe('Human-readable source element description used to obtain the permission to interact with the element'),\n startRef: z.string().describe('Exact source element reference from the page snapshot'),\n endElement: z.string().describe('Human-readable target element description used to obtain the permission to interact with the element'),\n endRef: z.string().describe('Exact target element reference from the page snapshot'),\n }),\n type: 'input',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n const [start, end] = await tab.refLocators([\n { ref: params.startRef, element: params.startElement },\n { ref: params.endRef, element: params.endElement },\n ]);\n\n let usedAllowIntercept = false;\n await tab.waitForCompletion(async () => {\n const result = await retryWithAllowIntercept(\n async (opts) => await start.locator.dragTo(end.locator, opts),\n {}\n );\n usedAllowIntercept = result.usedAllowIntercept;\n });\n\n const optionsAttr = usedAllowIntercept ? ', { allowIntercept: true }' : '';\n response.addCode(`await page.${start.resolved}.dragTo(page.${end.resolved}${optionsAttr});`);\n },\n});\n\nconst hover = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_hover',\n title: 'Hover mouse',\n description: 'Hover over element on page',\n inputSchema: elementSchema,\n type: 'input',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n const { locator, resolved } = await tab.refLocator(params);\n\n let usedAllowIntercept = false;\n await tab.waitForCompletion(async () => {\n const result = await retryWithAllowIntercept(\n async (opts) => await locator.hover(opts),\n {}\n );\n usedAllowIntercept = result.usedAllowIntercept;\n });\n\n const optionsAttr = usedAllowIntercept ? '{ allowIntercept: true }' : '';\n response.addCode(`await page.${resolved}.hover(${optionsAttr});`);\n },\n});\n\nconst selectOptionSchema = elementSchema.extend({\n values: z.array(z.string()).describe('Array of values to select in the dropdown. This can be a single value or multiple values.'),\n});\n\nconst selectOption = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_select_option',\n title: 'Select option',\n description: 'Select an option in a dropdown',\n inputSchema: selectOptionSchema,\n type: 'input',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n const { locator, resolved } = await tab.refLocator(params);\n response.addCode(`await page.${resolved}.selectOption(${javascript.formatObject(params.values)});`);\n\n await tab.waitForCompletion(async () => {\n await locator.selectOption(params.values);\n });\n },\n});\n\nconst pickLocator = defineTabTool({\n capability: 'testing',\n schema: {\n name: 'browser_generate_locator',\n title: 'Create locator for element',\n description: 'Generate locator for the given element to use in tests',\n inputSchema: elementSchema,\n type: 'readOnly',\n },\n\n handle: async (tab, params, response) => {\n const { resolved } = await tab.refLocator(params);\n response.addResult(resolved);\n },\n});\n\nconst elementInspect = defineTool({\n capability: 'core',\n schema: {\n name: 'browser_element_inspect',\n title: 'Inspect element for testing',\n description: 'Get element details for generating test assertions - returns suggested selector, HTML, and computed styles',\n inputSchema: elementSchema,\n type: 'readOnly',\n },\n\n handle: async (context, params, response) => {\n await context.ensureTab();\n const tab = context.currentTabOrDie();\n\n const { locator } = await tab.refLocator(params);\n\n let elementDetails: any;\n const suggestedSelectors = (await generateLocators(locator)).map(s => `\\`page.${s}\\``).join('\\n');\n\n try {\n elementDetails = await locator.evaluate(element => {\n const computedStyle = window.getComputedStyle(element);\n return {\n outerHTML: element.outerHTML,\n tagName: element.tagName.toLowerCase(),\n computedStyles: {\n display: computedStyle.display,\n visibility: computedStyle.visibility,\n opacity: computedStyle.opacity,\n position: computedStyle.position,\n width: computedStyle.width,\n height: computedStyle.height,\n backgroundColor: computedStyle.backgroundColor,\n color: computedStyle.color,\n fontSize: computedStyle.fontSize,\n fontFamily: computedStyle.fontFamily,\n textAlign: computedStyle.textAlign,\n border: computedStyle.border,\n borderRadius: computedStyle.borderRadius,\n margin: computedStyle.margin,\n padding: computedStyle.padding,\n overflow: computedStyle.overflow,\n zIndex: computedStyle.zIndex,\n transform: computedStyle.transform,\n },\n attributes: Array.from(element.attributes).reduce((acc, attr) => {\n acc[attr.name] = attr.value;\n return acc;\n }, {} as Record<string, string>),\n textContent: element.textContent?.trim() || '',\n innerText: (element as HTMLElement).innerText?.trim() || '',\n value: (element as HTMLInputElement).value || undefined,\n checked: (element as HTMLInputElement).checked || undefined,\n disabled: (element as HTMLInputElement).disabled || undefined,\n readonly: (element as HTMLInputElement).readOnly || undefined,\n bounds: element.getBoundingClientRect(),\n };\n });\n } catch (error) {\n response.addResult(`Error inspecting element \"${params.element}\": ${error instanceof Error ? error.message : String(error)}\n\nThis typically happens when:\n1. The element reference is no longer valid (element was removed)\n2. The page has navigated since the snapshot was taken\n3. The element is not accessible\n\nTry capturing a new snapshot with browser_snapshot and using the updated element reference.`);\n return;\n }\n let result = `\n**Element:** ${params.element}\n**Suggested Playwright Selector:**\n${suggestedSelectors}\n\n**HTML:**\n\\`\\`\\`html\n${elementDetails.outerHTML}\n\\`\\`\\`\n\n**Key Computed Styles:**\n- Display: ${elementDetails.computedStyles.display}\n- Visibility: ${elementDetails.computedStyles.visibility}\n- Opacity: ${elementDetails.computedStyles.opacity}\n- Position: ${elementDetails.computedStyles.position}\n- Width: ${elementDetails.computedStyles.width}\n- Height: ${elementDetails.computedStyles.height}\n- Background Color: ${elementDetails.computedStyles.backgroundColor}\n- Color: ${elementDetails.computedStyles.color}\n\n**Element Properties:**\n- Tag: ${elementDetails.tagName}\n- Text Content: \"${elementDetails.textContent}\"\n- Inner Text: \"${elementDetails.innerText}\"`;\n if (elementDetails.value !== undefined) {\n result += `\\n- Value: \"${elementDetails.value}\"`;\n }\n if (elementDetails.checked !== undefined) {\n result += `\\n- Checked: ${elementDetails.checked}`;\n }\n if (elementDetails.disabled !== undefined) {\n result += `\\n- Disabled: ${elementDetails.disabled}`;\n }\n if (elementDetails.readonly !== undefined) {\n result += `\\n- Read Only: ${elementDetails.readonly}`;\n }\n response.addResult(result);\n },\n});\n\nexport default [\n snapshot,\n click,\n drag,\n hover,\n selectOption,\n pickLocator,\n elementInspect,\n];\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/tabs.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTool } from './tool';\n\nconst browserTabs = defineTool({\n capability: 'core-tabs',\n\n schema: {\n name: 'browser_tabs',\n title: 'Manage tabs',\n description: 'List, create, close, or select a browser tab.',\n inputSchema: z.object({\n action: z.enum(['list', 'new', 'close', 'select']).describe('Operation to perform'),\n index: z.number().optional().describe('Tab index, used for close/select. If omitted for close, current tab is closed.'),\n }),\n type: 'action',\n },\n\n handle: async (context, params, response) => {\n switch (params.action) {\n case 'list': {\n await context.ensureTab();\n response.setIncludeTabs();\n return;\n }\n case 'new': {\n await context.newTab();\n response.setIncludeTabs();\n return;\n }\n case 'close': {\n await context.closeTab(params.index);\n response.setIncludeSnapshot('full');\n return;\n }\n case 'select': {\n if (params.index === undefined)\n throw new Error('Tab index is required');\n await context.selectTab(params.index);\n response.setIncludeSnapshot('full');\n return;\n }\n }\n },\n});\n\nexport default [\n browserTabs,\n];\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA2B;AAE3B,MAAM,kBAAc,wBAAW;AAAA,EAC7B,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,QAAQ,gBAAE,KAAK,CAAC,QAAQ,OAAO,SAAS,QAAQ,CAAC,EAAE,SAAS,sBAAsB;AAAA,MAClF,OAAO,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gFAAgF;AAAA,IACxH,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,SAAS,QAAQ,aAAa;AAC3C,YAAQ,OAAO,QAAQ;AAAA,MACrB,KAAK,QAAQ;AACX,cAAM,QAAQ,UAAU;AACxB,iBAAS,eAAe;AACxB;AAAA,MACF;AAAA,MACA,KAAK,OAAO;AACV,cAAM,QAAQ,OAAO;AACrB,iBAAS,eAAe;AACxB;AAAA,MACF;AAAA,MACA,KAAK,SAAS;AACZ,cAAM,QAAQ,SAAS,OAAO,KAAK;AACnC,iBAAS,mBAAmB,MAAM;AAClC;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,YAAI,OAAO,UAAU;AACnB,gBAAM,IAAI,MAAM,uBAAuB;AACzC,cAAM,QAAQ,UAAU,OAAO,KAAK;AACpC,iBAAS,mBAAmB,MAAM;AAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAED,IAAO,eAAQ;AAAA,EACb;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/tool.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { z } from 'zod';\nimport type { Context } from '../context';\nimport type * as playwright from 'playwright-core';\nimport type { ToolCapability } from '../../config';\nimport type { Tab } from '../tab';\nimport type { Response } from '../response';\nimport type { ToolSchema } from '../../sdk/tool';\n\nexport type FileUploadModalState = {\n type: 'fileChooser';\n description: string;\n fileChooser: playwright.FileChooser;\n clearedBy: string;\n};\n\nexport type DialogModalState = {\n type: 'dialog';\n description: string;\n dialog: playwright.Dialog;\n clearedBy: string;\n};\n\nexport type ModalState = FileUploadModalState | DialogModalState;\n\nexport type Tool<Input extends z.Schema = z.Schema> = {\n capability: ToolCapability;\n schema: ToolSchema<Input>;\n handle: (context: Context, params: z.output<Input>, response: Response) => Promise<void>;\n};\n\nexport function defineTool<Input extends z.Schema>(tool: Tool<Input>): Tool<Input> {\n return tool;\n}\n\nexport type TabTool<Input extends z.Schema = z.Schema> = {\n capability: ToolCapability;\n schema: ToolSchema<Input>;\n clearsModalState?: ModalState['type'];\n handle: (tab: Tab, params: z.output<Input>, response: Response) => Promise<void>;\n};\n\nexport function defineTabTool<Input extends z.Schema>(tool: TabTool<Input>): Tool<Input> {\n return {\n ...tool,\n handle: async (context, params, response) => {\n const tab = await context.ensureTab();\n const modalStates = tab.modalStates().map(state => state.type);\n if (tool.clearsModalState && !modalStates.includes(tool.clearsModalState))\n response.addError(`Error: The tool \"${tool.schema.name}\" can only be used when there is related modal state present.\\n` + tab.modalStatesMarkdown().join('\\n'));\n else if (!tool.clearsModalState && modalStates.length)\n response.addError(`Error: Tool \"${tool.schema.name}\" does not handle the modal state.\\n` + tab.modalStatesMarkdown().join('\\n'));\n else\n return tool.handle(tab, params, response);\n },\n };\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8CO,SAAS,WAAmC,MAAgC;AACjF,SAAO;AACT;AASO,SAAS,cAAsC,MAAmC;AACvF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,OAAO,SAAS,QAAQ,aAAa;AAC3C,YAAM,MAAM,MAAM,QAAQ,UAAU;AACpC,YAAM,cAAc,IAAI,YAAY,EAAE,IAAI,WAAS,MAAM,IAAI;AAC7D,UAAI,KAAK,oBAAoB,CAAC,YAAY,SAAS,KAAK,gBAAgB;AACtE,iBAAS,SAAS,oBAAoB,KAAK,OAAO,IAAI;AAAA,IAAoE,IAAI,oBAAoB,EAAE,KAAK,IAAI,CAAC;AAAA,eACvJ,CAAC,KAAK,oBAAoB,YAAY;AAC7C,iBAAS,SAAS,gBAAgB,KAAK,OAAO,IAAI;AAAA,IAAyC,IAAI,oBAAoB,EAAE,KAAK,IAAI,CAAC;AAAA;AAE/H,eAAO,KAAK,OAAO,KAAK,QAAQ,QAAQ;AAAA,IAC5C;AAAA,EACF;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/tracing.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTool } from './tool';\n\nimport type { Tracing } from '../../../../../playwright-core/src/client/tracing';\n\nconst tracingStart = defineTool({\n capability: 'tracing',\n\n schema: {\n name: 'browser_start_tracing',\n title: 'Start tracing',\n description: 'Start trace recording',\n inputSchema: z.object({}),\n type: 'readOnly',\n },\n\n handle: async (context, params, response) => {\n const browserContext = await context.ensureBrowserContext();\n const tracesDir = await context.outputFile(`traces`, { origin: 'code', reason: 'Collecting trace' });\n const name = 'trace-' + Date.now();\n await (browserContext.tracing as Tracing).start({\n name,\n screenshots: true,\n snapshots: true,\n _live: true,\n });\n const traceLegend = `- Action log: ${tracesDir}/${name}.trace\n- Network log: ${tracesDir}/${name}.network\n- Resources with content by sha1: ${tracesDir}/resources`;\n\n response.addResult(`Tracing started, saving to ${tracesDir}.\\n${traceLegend}`);\n (browserContext.tracing as any)[traceLegendSymbol] = traceLegend;\n },\n});\n\nconst tracingStop = defineTool({\n capability: 'tracing',\n\n schema: {\n name: 'browser_stop_tracing',\n title: 'Stop tracing',\n description: 'Stop trace recording',\n inputSchema: z.object({}),\n type: 'readOnly',\n },\n\n handle: async (context, params, response) => {\n const browserContext = await context.ensureBrowserContext();\n await browserContext.tracing.stop();\n const traceLegend = (browserContext.tracing as any)[traceLegendSymbol];\n response.addResult(`Tracing stopped.\\n${traceLegend}`);\n },\n});\n\nexport default [\n tracingStart,\n tracingStop,\n];\n\nconst traceLegendSymbol = Symbol('tracesDir');\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA2B;AAI3B,MAAM,mBAAe,wBAAW;AAAA,EAC9B,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO,CAAC,CAAC;AAAA,IACxB,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,SAAS,QAAQ,aAAa;AAC3C,UAAM,iBAAiB,MAAM,QAAQ,qBAAqB;AAC1D,UAAM,YAAY,MAAM,QAAQ,WAAW,UAAU,EAAE,QAAQ,QAAQ,QAAQ,mBAAmB,CAAC;AACnG,UAAM,OAAO,WAAW,KAAK,IAAI;AACjC,UAAO,eAAe,QAAoB,MAAM;AAAA,MAC9C;AAAA,MACA,aAAa;AAAA,MACb,WAAW;AAAA,MACX,OAAO;AAAA,IACT,CAAC;AACD,UAAM,cAAc,iBAAiB,SAAS,IAAI,IAAI;AAAA,iBACzC,SAAS,IAAI,IAAI;AAAA,oCACE,SAAS;AAEzC,aAAS,UAAU,8BAA8B,SAAS;AAAA,EAAM,WAAW,EAAE;AAC7E,IAAC,eAAe,QAAgB,iBAAiB,IAAI;AAAA,EACvD;AACF,CAAC;AAED,MAAM,kBAAc,wBAAW;AAAA,EAC7B,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO,CAAC,CAAC;AAAA,IACxB,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,SAAS,QAAQ,aAAa;AAC3C,UAAM,iBAAiB,MAAM,QAAQ,qBAAqB;AAC1D,UAAM,eAAe,QAAQ,KAAK;AAClC,UAAM,cAAe,eAAe,QAAgB,iBAAiB;AACrE,aAAS,UAAU;AAAA,EAAqB,WAAW,EAAE;AAAA,EACvD;AACF,CAAC;AAED,IAAO,kBAAQ;AAAA,EACb;AAAA,EACA;AACF;AAEA,MAAM,oBAAoB,OAAO,WAAW;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/utils.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// @ts-ignore\nimport { asLocator } from 'playwright-core/lib/utils';\n\nimport type * as playwright from 'playwright-core';\nimport type { Tab } from '../tab';\n\nexport async function waitForCompletion<R>(tab: Tab, callback: () => Promise<R>): Promise<R> {\n const requests = new Set<playwright.Request>();\n let frameNavigated = false;\n let waitCallback: () => void = () => {};\n const waitBarrier = new Promise<void>(f => { waitCallback = f; });\n\n const responseListener = (request: playwright.Request) => {\n requests.delete(request);\n if (!requests.size)\n waitCallback();\n };\n\n const requestListener = (request: playwright.Request) => {\n requests.add(request);\n void request.response().then(() => responseListener(request)).catch(() => {});\n };\n\n const frameNavigateListener = (frame: playwright.Frame) => {\n if (frame.parentFrame())\n return;\n frameNavigated = true;\n dispose();\n clearTimeout(timeout);\n void tab.waitForLoadState('load').then(waitCallback);\n };\n\n const onTimeout = () => {\n dispose();\n waitCallback();\n };\n\n tab.page.on('request', requestListener);\n tab.page.on('requestfailed', responseListener);\n tab.page.on('framenavigated', frameNavigateListener);\n const timeout = setTimeout(onTimeout, 10000);\n\n const dispose = () => {\n tab.page.off('request', requestListener);\n tab.page.off('requestfailed', responseListener);\n tab.page.off('framenavigated', frameNavigateListener);\n clearTimeout(timeout);\n };\n\n try {\n const result = await callback();\n if (!requests.size && !frameNavigated)\n waitCallback();\n await waitBarrier;\n await tab.waitForTimeout(1000);\n return result;\n } finally {\n dispose();\n }\n}\n\nexport async function callOnPageNoTrace<T>(page: playwright.Page, callback: (page: playwright.Page) => Promise<T>): Promise<T> {\n return await (page as any)._wrapApiCall(() => callback(page), { internal: true });\n}\n\nexport function dateAsFileName(extension: string): string {\n const date = new Date();\n return `page-${date.toISOString().replace(/[:.]/g, '-')}.${extension}`;\n}\n\nexport async function generateLocators(locator: playwright.Locator): Promise<string[]> {\n // Relies on process.env.PWTEST_UNDER_TEST environment variable: injects __injectedScript object for generating locators\n const selectors = (await locator.evaluate(el => (window as any).__injectedScript.generateSelector(el, { multiple: true, testIdAttributeName: 'data-testid' }).selectors)) as string[];\n return selectors.map(s => asLocator('javascript', s));\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBA,mBAA0B;AAK1B,eAAsB,kBAAqB,KAAU,UAAwC;AAC3F,QAAM,WAAW,oBAAI,IAAwB;AAC7C,MAAI,iBAAiB;AACrB,MAAI,eAA2B,MAAM;AAAA,EAAC;AACtC,QAAM,cAAc,IAAI,QAAc,OAAK;AAAE,mBAAe;AAAA,EAAG,CAAC;AAEhE,QAAM,mBAAmB,CAAC,YAAgC;AACxD,aAAS,OAAO,OAAO;AACvB,QAAI,CAAC,SAAS;AACZ,mBAAa;AAAA,EACjB;AAEA,QAAM,kBAAkB,CAAC,YAAgC;AACvD,aAAS,IAAI,OAAO;AACpB,SAAK,QAAQ,SAAS,EAAE,KAAK,MAAM,iBAAiB,OAAO,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAC9E;AAEA,QAAM,wBAAwB,CAAC,UAA4B;AACzD,QAAI,MAAM,YAAY;AACpB;AACF,qBAAiB;AACjB,YAAQ;AACR,iBAAa,OAAO;AACpB,SAAK,IAAI,iBAAiB,MAAM,EAAE,KAAK,YAAY;AAAA,EACrD;AAEA,QAAM,YAAY,MAAM;AACtB,YAAQ;AACR,iBAAa;AAAA,EACf;AAEA,MAAI,KAAK,GAAG,WAAW,eAAe;AACtC,MAAI,KAAK,GAAG,iBAAiB,gBAAgB;AAC7C,MAAI,KAAK,GAAG,kBAAkB,qBAAqB;AACnD,QAAM,UAAU,WAAW,WAAW,GAAK;AAE3C,QAAM,UAAU,MAAM;AACpB,QAAI,KAAK,IAAI,WAAW,eAAe;AACvC,QAAI,KAAK,IAAI,iBAAiB,gBAAgB;AAC9C,QAAI,KAAK,IAAI,kBAAkB,qBAAqB;AACpD,iBAAa,OAAO;AAAA,EACtB;AAEA,MAAI;AACF,UAAM,SAAS,MAAM,SAAS;AAC9B,QAAI,CAAC,SAAS,QAAQ,CAAC;AACrB,mBAAa;AACf,UAAM;AACN,UAAM,IAAI,eAAe,GAAI;AAC7B,WAAO;AAAA,EACT,UAAE;AACA,YAAQ;AAAA,EACV;AACF;AAEA,eAAsB,kBAAqB,MAAuB,UAA6D;AAC7H,SAAO,MAAO,KAAa,aAAa,MAAM,SAAS,IAAI,GAAG,EAAE,UAAU,KAAK,CAAC;AAClF;AAEO,SAAS,eAAe,WAA2B;AACxD,QAAM,OAAO,oBAAI,KAAK;AACtB,SAAO,QAAQ,KAAK,YAAY,EAAE,QAAQ,SAAS,GAAG,CAAC,IAAI,SAAS;AACtE;AAEA,eAAsB,iBAAiB,SAAgD;AAErF,QAAM,YAAa,MAAM,QAAQ,SAAS,QAAO,OAAe,iBAAiB,iBAAiB,IAAI,EAAE,UAAU,MAAM,qBAAqB,cAAc,CAAC,EAAE,SAAS;AACvK,SAAO,UAAU,IAAI,WAAK,wBAAU,cAAc,CAAC,CAAC;AACtD;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/verify.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\nimport * as javascript from '../codegen';\n\nconst verifyElement = defineTabTool({\n capability: 'testing',\n schema: {\n name: 'browser_verify_element_visible',\n title: 'Verify element visible',\n description: 'Verify element is visible on the page',\n inputSchema: z.object({\n role: z.string().describe('ROLE of the element. Can be found in the snapshot like this: \\`- {ROLE} \"Accessible Name\":\\`'),\n accessibleName: z.string().describe('ACCESSIBLE_NAME of the element. Can be found in the snapshot like this: \\`- role \"{ACCESSIBLE_NAME}\"\\`'),\n }),\n type: 'assertion',\n },\n\n handle: async (tab, params, response) => {\n const locator = tab.page.getByRole(params.role as any, { name: params.accessibleName });\n if (await locator.count() === 0) {\n response.addError(`Element with role \"${params.role}\" and accessible name \"${params.accessibleName}\" not found`);\n return;\n }\n\n response.addCode(`await expect(page.getByRole(${javascript.escapeWithQuotes(params.role)}, { name: ${javascript.escapeWithQuotes(params.accessibleName)} })).toBeVisible();`);\n response.addResult('Done');\n },\n});\n\nconst verifyText = defineTabTool({\n capability: 'testing',\n schema: {\n name: 'browser_verify_text_visible',\n title: 'Verify text visible',\n description: `Verify text is visible on the page. Prefer ${verifyElement.schema.name} if possible.`,\n inputSchema: z.object({\n text: z.string().describe('TEXT to verify. Can be found in the snapshot like this: \\`- role \"Accessible Name\": {TEXT}\\` or like this: \\`- text: {TEXT}\\`'),\n }),\n type: 'assertion',\n },\n\n handle: async (tab, params, response) => {\n const locator = tab.page.getByText(params.text).filter({ visible: true });\n if (await locator.count() === 0) {\n response.addError('Text not found');\n return;\n }\n\n response.addCode(`await expect(page.getByText(${javascript.escapeWithQuotes(params.text)})).toBeVisible();`);\n response.addResult('Done');\n },\n});\n\nconst verifyList = defineTabTool({\n capability: 'testing',\n schema: {\n name: 'browser_verify_list_visible',\n title: 'Verify list visible',\n description: 'Verify list is visible on the page',\n inputSchema: z.object({\n element: z.string().describe('Human-readable list description'),\n ref: z.string().describe('Exact target element reference that points to the list'),\n items: z.array(z.string()).describe('Items to verify'),\n }),\n type: 'assertion',\n },\n\n handle: async (tab, params, response) => {\n const { locator } = await tab.refLocator({ ref: params.ref, element: params.element });\n const itemTexts: string[] = [];\n for (const item of params.items) {\n const itemLocator = locator.getByText(item);\n if (await itemLocator.count() === 0) {\n response.addError(`Item \"${item}\" not found`);\n return;\n }\n itemTexts.push((await itemLocator.textContent())!);\n }\n const ariaSnapshot = `\\`\n- list:\n${itemTexts.map(t => ` - listitem: ${javascript.escapeWithQuotes(t, '\"')}`).join('\\n')}\n\\``;\n response.addCode(`await expect(page.locator('body')).toMatchAriaSnapshot(${ariaSnapshot});`);\n response.addResult('Done');\n },\n});\n\nconst verifyValue = defineTabTool({\n capability: 'testing',\n schema: {\n name: 'browser_verify_value',\n title: 'Verify value',\n description: 'Verify element value',\n inputSchema: z.object({\n type: z.enum(['textbox', 'checkbox', 'radio', 'combobox', 'slider']).describe('Type of the element'),\n element: z.string().describe('Human-readable element description'),\n ref: z.string().describe('Exact target element reference that points to the element'),\n value: z.string().describe('Value to verify. For checkbox, use \"true\" or \"false\".'),\n }),\n type: 'assertion',\n },\n\n handle: async (tab, params, response) => {\n const { locator, resolved } = await tab.refLocator({ ref: params.ref, element: params.element });\n const locatorSource = `page.${resolved}`;\n if (params.type === 'textbox' || params.type === 'slider' || params.type === 'combobox') {\n const value = await locator.inputValue();\n if (value !== params.value) {\n response.addError(`Expected value \"${params.value}\", but got \"${value}\"`);\n return;\n }\n response.addCode(`await expect(${locatorSource}).toHaveValue(${javascript.quote(params.value)});`);\n } else if (params.type === 'checkbox' || params.type === 'radio') {\n const value = await locator.isChecked();\n if (value !== (params.value === 'true')) {\n response.addError(`Expected value \"${params.value}\", but got \"${value}\"`);\n return;\n }\n const matcher = value ? 'toBeChecked' : 'not.toBeChecked';\n response.addCode(`await expect(${locatorSource}).${matcher}();`);\n }\n response.addResult('Done');\n },\n});\n\nexport default [\n verifyElement,\n verifyText,\n verifyList,\n verifyValue,\n];\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/mcp/browser/tools/wait.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTool } from './tool';\n\nconst wait = defineTool({\n capability: 'core',\n\n schema: {\n name: 'browser_wait_for',\n title: 'Wait for',\n description: 'Wait for text to appear or disappear or a specified time to pass',\n inputSchema: z.object({\n time: z.number().optional().describe('The time to wait in seconds'),\n text: z.string().optional().describe('The text to wait for'),\n textGone: z.string().optional().describe('The text to wait for to disappear'),\n }),\n type: 'assertion',\n },\n\n handle: async (context, params, response) => {\n if (!params.text && !params.textGone && !params.time)\n throw new Error('Either time, text or textGone must be provided');\n\n if (params.time) {\n response.addCode(`await new Promise(f => setTimeout(f, ${params.time!} * 1000));`);\n await new Promise(f => setTimeout(f, Math.min(30000, params.time! * 1000)));\n }\n\n const tab = context.currentTabOrDie();\n const locator = params.text ? tab.page.getByText(params.text).first() : undefined;\n const goneLocator = params.textGone ? tab.page.getByText(params.textGone).first() : undefined;\n\n if (goneLocator) {\n response.addCode(`await page.getByText(${JSON.stringify(params.textGone)}).first().waitFor({ state: 'hidden' });`);\n await goneLocator.waitFor({ state: 'hidden' });\n }\n\n if (locator) {\n response.addCode(`await page.getByText(${JSON.stringify(params.text)}).first().waitFor({ state: 'visible' });`);\n await locator.waitFor({ state: 'visible' });\n }\n\n response.addResult(`Waited for ${params.text || params.textGone || params.time}`);\n response.setIncludeSnapshot();\n },\n});\n\nexport default [\n wait,\n];\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA2B;AAE3B,MAAM,WAAO,wBAAW;AAAA,EACtB,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,MAAM,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,MAClE,MAAM,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,MAC3D,UAAU,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,IAC9E,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,SAAS,QAAQ,aAAa;AAC3C,QAAI,CAAC,OAAO,QAAQ,CAAC,OAAO,YAAY,CAAC,OAAO;AAC9C,YAAM,IAAI,MAAM,gDAAgD;AAElE,QAAI,OAAO,MAAM;AACf,eAAS,QAAQ,wCAAwC,OAAO,IAAK,YAAY;AACjF,YAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,KAAK,IAAI,KAAO,OAAO,OAAQ,GAAI,CAAC,CAAC;AAAA,IAC5E;AAEA,UAAM,MAAM,QAAQ,gBAAgB;AACpC,UAAM,UAAU,OAAO,OAAO,IAAI,KAAK,UAAU,OAAO,IAAI,EAAE,MAAM,IAAI;AACxE,UAAM,cAAc,OAAO,WAAW,IAAI,KAAK,UAAU,OAAO,QAAQ,EAAE,MAAM,IAAI;AAEpF,QAAI,aAAa;AACf,eAAS,QAAQ,wBAAwB,KAAK,UAAU,OAAO,QAAQ,CAAC,yCAAyC;AACjH,YAAM,YAAY,QAAQ,EAAE,OAAO,SAAS,CAAC;AAAA,IAC/C;AAEA,QAAI,SAAS;AACX,eAAS,QAAQ,wBAAwB,KAAK,UAAU,OAAO,IAAI,CAAC,0CAA0C;AAC9G,YAAM,QAAQ,QAAQ,EAAE,OAAO,UAAU,CAAC;AAAA,IAC5C;AAEA,aAAS,UAAU,cAAc,OAAO,QAAQ,OAAO,YAAY,OAAO,IAAI,EAAE;AAChF,aAAS,mBAAmB;AAAA,EAC9B;AACF,CAAC;AAED,IAAO,eAAQ;AAAA,EACb;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/mcp/browser/tools.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport common from './tools/common';\nimport console from './tools/console';\nimport dialogs from './tools/dialogs';\nimport evaluate from './tools/evaluate';\nimport files from './tools/files';\nimport form from './tools/form';\nimport install from './tools/install';\nimport keyboard from './tools/keyboard';\nimport mouse from './tools/mouse';\nimport navigate from './tools/navigate';\nimport network from './tools/network';\nimport pdf from './tools/pdf';\nimport snapshot from './tools/snapshot';\nimport screenshot from './tools/screenshot';\nimport tabs from './tools/tabs';\nimport tracing from './tools/tracing';\nimport wait from './tools/wait';\nimport verify from './tools/verify';\n\nimport type { Tool } from './tools/tool';\nimport type { FullConfig } from './config';\n\nexport const browserTools: Tool<any>[] = [\n ...common,\n ...console,\n ...dialogs,\n ...evaluate,\n ...files,\n ...form,\n ...install,\n ...keyboard,\n ...navigate,\n ...network,\n ...mouse,\n ...pdf,\n ...screenshot,\n ...snapshot,\n ...tabs,\n ...tracing,\n ...wait,\n ...verify,\n];\n\nexport function filteredTools(config: FullConfig) {\n return browserTools.filter(tool => tool.capability.startsWith('core') || config.capabilities?.includes(tool.capability));\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAmB;AACnB,qBAAoB;AACpB,qBAAoB;AACpB,sBAAqB;AACrB,mBAAkB;AAClB,kBAAiB;AACjB,qBAAoB;AACpB,sBAAqB;AACrB,mBAAkB;AAClB,sBAAqB;AACrB,qBAAoB;AACpB,iBAAgB;AAChB,sBAAqB;AACrB,wBAAuB;AACvB,kBAAiB;AACjB,qBAAoB;AACpB,kBAAiB;AACjB,oBAAmB;AAKZ,MAAM,eAA4B;AAAA,EACvC,GAAG,cAAAA;AAAA,EACH,GAAG,eAAAC;AAAA,EACH,GAAG,eAAAC;AAAA,EACH,GAAG,gBAAAC;AAAA,EACH,GAAG,aAAAC;AAAA,EACH,GAAG,YAAAC;AAAA,EACH,GAAG,eAAAC;AAAA,EACH,GAAG,gBAAAC;AAAA,EACH,GAAG,gBAAAC;AAAA,EACH,GAAG,eAAAC;AAAA,EACH,GAAG,aAAAC;AAAA,EACH,GAAG,WAAAC;AAAA,EACH,GAAG,kBAAAC;AAAA,EACH,GAAG,gBAAAC;AAAA,EACH,GAAG,YAAAC;AAAA,EACH,GAAG,eAAAC;AAAA,EACH,GAAG,YAAAC;AAAA,EACH,GAAG,cAAAC;AACL;AAEO,SAAS,cAAc,QAAoB;AAChD,SAAO,aAAa,OAAO,UAAQ,KAAK,WAAW,WAAW,MAAM,KAAK,OAAO,cAAc,SAAS,KAAK,UAAU,CAAC;AACzH;",
6
- "names": ["common", "console", "dialogs", "evaluate", "files", "form", "install", "keyboard", "navigate", "network", "mouse", "pdf", "screenshot", "snapshot", "tabs", "tracing", "wait", "verify"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/mcp/browser/watchdog.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SharedContextFactory } from './browserContextFactory';\nimport { Context } from './context';\n\nexport function setupExitWatchdog() {\n let isExiting = false;\n const handleExit = async () => {\n if (isExiting)\n return;\n isExiting = true;\n // eslint-disable-next-line no-restricted-properties\n setTimeout(() => process.exit(0), 15000);\n await Context.disposeAll();\n await SharedContextFactory.dispose();\n // eslint-disable-next-line no-restricted-properties\n process.exit(0);\n };\n\n process.stdin.on('close', handleExit);\n process.on('SIGINT', handleExit);\n process.on('SIGTERM', handleExit);\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,mCAAqC;AACrC,qBAAwB;AAEjB,SAAS,oBAAoB;AAClC,MAAI,YAAY;AAChB,QAAM,aAAa,YAAY;AAC7B,QAAI;AACF;AACF,gBAAY;AAEZ,eAAW,MAAM,QAAQ,KAAK,CAAC,GAAG,IAAK;AACvC,UAAM,uBAAQ,WAAW;AACzB,UAAM,kDAAqB,QAAQ;AAEnC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,MAAM,GAAG,SAAS,UAAU;AACpC,UAAQ,GAAG,UAAU,UAAU;AAC/B,UAAQ,GAAG,WAAW,UAAU;AAClC;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/mcp/config.d.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type * as playwright from 'playwright-core';\n\nexport type ToolCapability = 'core' | 'core-tabs' | 'core-install' | 'vision' | 'pdf' | 'testing' | 'tracing';\n\nexport type Config = {\n /**\n * The browser to use.\n */\n browser?: {\n /**\n * The type of browser to use.\n */\n browserName?: 'chromium' | 'firefox' | 'webkit';\n\n /**\n * Keep the browser profile in memory, do not save it to disk.\n */\n isolated?: boolean;\n\n /**\n * Path to a user data directory for browser profile persistence.\n * Temporary directory is created by default.\n */\n userDataDir?: string;\n\n /**\n * Launch options passed to\n * @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch-persistent-context\n *\n * This is useful for settings options like `channel`, `headless`, `executablePath`, etc.\n */\n launchOptions?: playwright.LaunchOptions;\n\n /**\n * Context options for the browser context.\n *\n * This is useful for settings options like `viewport`.\n */\n contextOptions?: playwright.BrowserContextOptions;\n\n /**\n * Chrome DevTools Protocol endpoint to connect to an existing browser instance in case of Chromium family browsers.\n */\n cdpEndpoint?: string;\n\n /**\n * CDP headers to send with the connect request.\n */\n cdpHeaders?: Record<string, string>;\n\n /**\n * Remote endpoint to connect to an existing Playwright server.\n */\n remoteEndpoint?: string;\n\n /**\n * Paths to JavaScript files to add as initialization scripts.\n * The scripts will be evaluated in every page before any of the page's scripts.\n */\n initScript?: string[];\n },\n\n server?: {\n /**\n * The port to listen on for SSE or MCP transport.\n */\n port?: number;\n\n /**\n * The host to bind the server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.\n */\n host?: string;\n\n /**\n * The hosts this server is allowed to serve from. Defaults to the host server is bound to.\n * This is not for CORS, but rather for the DNS rebinding protection.\n */\n allowedHosts?: string[];\n },\n\n /**\n * List of enabled tool capabilities. Possible values:\n * - 'core': Core browser automation features.\n * - 'pdf': PDF generation and manipulation.\n * - 'vision': Coordinate-based interactions.\n */\n capabilities?: ToolCapability[];\n\n /**\n * Whether to save the Playwright session into the output directory.\n */\n saveSession?: boolean;\n\n /**\n * Whether to save the Playwright trace of the session into the output directory.\n */\n saveTrace?: boolean;\n\n /**\n * If specified, saves the Playwright video of the session into the output directory.\n */\n saveVideo?: {\n width: number;\n height: number;\n };\n\n /**\n * Reuse the same browser context between all connected HTTP clients.\n */\n sharedBrowserContext?: boolean;\n\n /**\n * Secrets are used to prevent LLM from getting sensitive data while\n * automating scenarios such as authentication.\n * Prefer the browser.contextOptions.storageState over secrets file as a more secure alternative.\n */\n secrets?: Record<string, string>;\n\n /**\n * The directory to save output files.\n */\n outputDir?: string;\n\n network?: {\n /**\n * List of origins to allow the browser to request. Default is to allow all. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.\n */\n allowedOrigins?: string[];\n\n /**\n * List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.\n */\n blockedOrigins?: string[];\n };\n\n /**\n * Specify the attribute to use for test ids, defaults to \"data-testid\".\n */\n testIdAttribute?: string;\n\n timeouts?: {\n /*\n * Configures default action timeout: https://playwright.dev/docs/api/class-page#page-set-default-timeout. Defaults to 5000ms.\n */\n action?: number;\n\n /*\n * Configures default navigation timeout: https://playwright.dev/docs/api/class-page#page-set-default-navigation-timeout. Defaults to 60000ms.\n */\n navigation?: number;\n };\n\n /**\n * Whether to send image responses to the client. Can be \"allow\", \"omit\", or \"auto\". Defaults to \"auto\", which sends images if the client can display them.\n */\n imageResponses?: 'allow' | 'omit';\n};\n\n"],
5
- "mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/mcp/extension/cdpRelay.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * WebSocket server that bridges Playwright MCP and Chrome Extension\n *\n * Endpoints:\n * - /cdp/guid - Full CDP interface for Playwright MCP\n * - /extension/guid - Extension connection for chrome.debugger forwarding\n */\n\nimport { spawn } from 'child_process';\nimport http from 'http';\n\nimport { debug, ws, wsServer } from 'playwright-core/lib/utilsBundle';\nimport { registry } from 'playwright-core/lib/server/registry/index';\nimport { ManualPromise } from 'playwright-core/lib/utils';\n\nimport { httpAddressToString } from '../sdk/http';\nimport { logUnhandledError } from '../log';\nimport * as protocol from './protocol';\n\nimport type websocket from 'ws';\nimport type { ClientInfo } from '../sdk/server';\nimport type { ExtensionCommand, ExtensionEvents } from './protocol';\nimport type { WebSocket, WebSocketServer } from 'playwright-core/lib/utilsBundle';\n\n\nconst debugLogger = debug('pw:mcp:relay');\n\ntype CDPCommand = {\n id: number;\n sessionId?: string;\n method: string;\n params?: any;\n};\n\ntype CDPResponse = {\n id?: number;\n sessionId?: string;\n method?: string;\n params?: any;\n result?: any;\n error?: { code?: number; message: string };\n};\n\nexport class CDPRelayServer {\n private _wsHost: string;\n private _browserChannel: string;\n private _userDataDir?: string;\n private _executablePath?: string;\n private _cdpPath: string;\n private _extensionPath: string;\n private _wss: WebSocketServer;\n private _playwrightConnection: WebSocket | null = null;\n private _extensionConnection: ExtensionConnection | null = null;\n private _connectedTabInfo: {\n targetInfo: any;\n // Page sessionId that should be used by this connection.\n sessionId: string;\n } | undefined;\n private _nextSessionId: number = 1;\n private _extensionConnectionPromise!: ManualPromise<void>;\n\n constructor(server: http.Server, browserChannel: string, userDataDir?: string, executablePath?: string) {\n this._wsHost = httpAddressToString(server.address()).replace(/^http/, 'ws');\n this._browserChannel = browserChannel;\n this._userDataDir = userDataDir;\n this._executablePath = executablePath;\n\n const uuid = crypto.randomUUID();\n this._cdpPath = `/cdp/${uuid}`;\n this._extensionPath = `/extension/${uuid}`;\n\n this._resetExtensionConnection();\n this._wss = new wsServer({ server });\n this._wss.on('connection', this._onConnection.bind(this));\n }\n\n cdpEndpoint() {\n return `${this._wsHost}${this._cdpPath}`;\n }\n\n extensionEndpoint() {\n return `${this._wsHost}${this._extensionPath}`;\n }\n\n async ensureExtensionConnectionForMCPContext(clientInfo: ClientInfo, abortSignal: AbortSignal, toolName: string | undefined) {\n debugLogger('Ensuring extension connection for MCP context');\n if (this._extensionConnection)\n return;\n this._connectBrowser(clientInfo, toolName);\n debugLogger('Waiting for incoming extension connection');\n await Promise.race([\n this._extensionConnectionPromise,\n new Promise((_, reject) => setTimeout(() => {\n reject(new Error(`Extension connection timeout. Make sure the \"Playwright MCP Bridge\" extension is installed. See https://github.com/microsoft/playwright-mcp/blob/main/extension/README.md for installation instructions.`));\n }, process.env.PWMCP_TEST_CONNECTION_TIMEOUT ? parseInt(process.env.PWMCP_TEST_CONNECTION_TIMEOUT, 10) : 5_000)),\n new Promise((_, reject) => abortSignal.addEventListener('abort', reject))\n ]);\n debugLogger('Extension connection established');\n }\n\n private _connectBrowser(clientInfo: ClientInfo, toolName: string | undefined) {\n const mcpRelayEndpoint = `${this._wsHost}${this._extensionPath}`;\n // Need to specify \"key\" in the manifest.json to make the id stable when loading from file.\n const url = new URL('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html');\n url.searchParams.set('mcpRelayUrl', mcpRelayEndpoint);\n const client = {\n name: clientInfo.name,\n version: clientInfo.version,\n };\n url.searchParams.set('client', JSON.stringify(client));\n url.searchParams.set('protocolVersion', process.env.PWMCP_TEST_PROTOCOL_VERSION ?? protocol.VERSION.toString());\n if (toolName)\n url.searchParams.set('newTab', String(toolName === 'browser_navigate'));\n const token = process.env.PLAYWRIGHT_MCP_EXTENSION_TOKEN;\n if (token)\n url.searchParams.set('token', token);\n const href = url.toString();\n\n let executablePath = this._executablePath;\n if (!executablePath) {\n const executableInfo = registry.findExecutable(this._browserChannel);\n if (!executableInfo)\n throw new Error(`Unsupported channel: \"${this._browserChannel}\"`);\n executablePath = executableInfo.executablePath('javascript');\n if (!executablePath)\n throw new Error(`\"${this._browserChannel}\" executable not found. Make sure it is installed at a standard location.`);\n }\n\n const args: string[] = [];\n if (this._userDataDir)\n args.push(`--user-data-dir=${this._userDataDir}`);\n args.push(href);\n\n spawn(executablePath, args, {\n windowsHide: true,\n detached: true,\n shell: false,\n stdio: 'ignore',\n });\n }\n\n stop(): void {\n this.closeConnections('Server stopped');\n this._wss.close();\n }\n\n closeConnections(reason: string) {\n this._closePlaywrightConnection(reason);\n this._closeExtensionConnection(reason);\n }\n\n private _onConnection(ws: WebSocket, request: http.IncomingMessage): void {\n const url = new URL(`http://localhost${request.url}`);\n debugLogger(`New connection to ${url.pathname}`);\n if (url.pathname === this._cdpPath) {\n this._handlePlaywrightConnection(ws);\n } else if (url.pathname === this._extensionPath) {\n this._handleExtensionConnection(ws);\n } else {\n debugLogger(`Invalid path: ${url.pathname}`);\n ws.close(4004, 'Invalid path');\n }\n }\n\n private _handlePlaywrightConnection(ws: WebSocket): void {\n if (this._playwrightConnection) {\n debugLogger('Rejecting second Playwright connection');\n ws.close(1000, 'Another CDP client already connected');\n return;\n }\n this._playwrightConnection = ws;\n ws.on('message', async data => {\n try {\n const message = JSON.parse(data.toString());\n await this._handlePlaywrightMessage(message);\n } catch (error: any) {\n debugLogger(`Error while handling Playwright message\\n${data.toString()}\\n`, error);\n }\n });\n ws.on('close', () => {\n if (this._playwrightConnection !== ws)\n return;\n this._playwrightConnection = null;\n this._closeExtensionConnection('Playwright client disconnected');\n debugLogger('Playwright WebSocket closed');\n });\n ws.on('error', error => {\n debugLogger('Playwright WebSocket error:', error);\n });\n debugLogger('Playwright MCP connected');\n }\n\n private _closeExtensionConnection(reason: string) {\n this._extensionConnection?.close(reason);\n this._extensionConnectionPromise.reject(new Error(reason));\n this._resetExtensionConnection();\n }\n\n private _resetExtensionConnection() {\n this._connectedTabInfo = undefined;\n this._extensionConnection = null;\n this._extensionConnectionPromise = new ManualPromise();\n void this._extensionConnectionPromise.catch(logUnhandledError);\n }\n\n private _closePlaywrightConnection(reason: string) {\n if (this._playwrightConnection?.readyState === ws.OPEN)\n this._playwrightConnection.close(1000, reason);\n this._playwrightConnection = null;\n }\n\n private _handleExtensionConnection(ws: WebSocket): void {\n if (this._extensionConnection) {\n ws.close(1000, 'Another extension connection already established');\n return;\n }\n this._extensionConnection = new ExtensionConnection(ws);\n this._extensionConnection.onclose = (c, reason) => {\n debugLogger('Extension WebSocket closed:', reason, c === this._extensionConnection);\n if (this._extensionConnection !== c)\n return;\n this._resetExtensionConnection();\n this._closePlaywrightConnection(`Extension disconnected: ${reason}`);\n };\n this._extensionConnection.onmessage = this._handleExtensionMessage.bind(this);\n this._extensionConnectionPromise.resolve();\n }\n\n private _handleExtensionMessage<M extends keyof ExtensionEvents>(method: M, params: ExtensionEvents[M]['params']) {\n switch (method) {\n case 'forwardCDPEvent':\n const sessionId = params.sessionId || this._connectedTabInfo?.sessionId;\n this._sendToPlaywright({\n sessionId,\n method: params.method,\n params: params.params\n });\n break;\n }\n }\n\n private async _handlePlaywrightMessage(message: CDPCommand): Promise<void> {\n debugLogger('\u2190 Playwright:', `${message.method} (id=${message.id})`);\n const { id, sessionId, method, params } = message;\n try {\n const result = await this._handleCDPCommand(method, params, sessionId);\n this._sendToPlaywright({ id, sessionId, result });\n } catch (e) {\n debugLogger('Error in the extension:', e);\n this._sendToPlaywright({\n id,\n sessionId,\n error: { message: (e as Error).message }\n });\n }\n }\n\n private async _handleCDPCommand(method: string, params: any, sessionId: string | undefined): Promise<any> {\n switch (method) {\n case 'Browser.getVersion': {\n return {\n protocolVersion: '1.3',\n product: 'Chrome/Extension-Bridge',\n userAgent: 'CDP-Bridge-Server/1.0.0',\n };\n }\n case 'Browser.setDownloadBehavior': {\n return { };\n }\n case 'Target.setAutoAttach': {\n // Forward child session handling.\n if (sessionId)\n break;\n // Simulate auto-attach behavior with real target info\n const { targetInfo } = await this._extensionConnection!.send('attachToTab', { });\n this._connectedTabInfo = {\n targetInfo,\n sessionId: `pw-tab-${this._nextSessionId++}`,\n };\n debugLogger('Simulating auto-attach');\n this._sendToPlaywright({\n method: 'Target.attachedToTarget',\n params: {\n sessionId: this._connectedTabInfo.sessionId,\n targetInfo: {\n ...this._connectedTabInfo.targetInfo,\n attached: true,\n },\n waitingForDebugger: false\n }\n });\n return { };\n }\n case 'Target.getTargetInfo': {\n return this._connectedTabInfo?.targetInfo;\n }\n }\n return await this._forwardToExtension(method, params, sessionId);\n }\n\n private async _forwardToExtension(method: string, params: any, sessionId: string | undefined): Promise<any> {\n if (!this._extensionConnection)\n throw new Error('Extension not connected');\n // Top level sessionId is only passed between the relay and the client.\n if (this._connectedTabInfo?.sessionId === sessionId)\n sessionId = undefined;\n return await this._extensionConnection.send('forwardCDPCommand', { sessionId, method, params });\n }\n\n private _sendToPlaywright(message: CDPResponse): void {\n debugLogger('\u2192 Playwright:', `${message.method ?? `response(id=${message.id})`}`);\n this._playwrightConnection?.send(JSON.stringify(message));\n }\n}\n\ntype ExtensionResponse = {\n id?: number;\n method?: string;\n params?: any;\n result?: any;\n error?: string;\n};\n\nclass ExtensionConnection {\n private readonly _ws: WebSocket;\n private readonly _callbacks = new Map<number, { resolve: (o: any) => void, reject: (e: Error) => void, error: Error }>();\n private _lastId = 0;\n\n onmessage?: <M extends keyof ExtensionEvents>(method: M, params: ExtensionEvents[M]['params']) => void;\n onclose?: (self: ExtensionConnection, reason: string) => void;\n\n constructor(ws: WebSocket) {\n this._ws = ws;\n this._ws.on('message', this._onMessage.bind(this));\n this._ws.on('close', this._onClose.bind(this));\n this._ws.on('error', this._onError.bind(this));\n }\n\n async send<M extends keyof ExtensionCommand>(method: M, params: ExtensionCommand[M]['params']): Promise<any> {\n if (this._ws.readyState !== ws.OPEN)\n throw new Error(`Unexpected WebSocket state: ${this._ws.readyState}`);\n const id = ++this._lastId;\n this._ws.send(JSON.stringify({ id, method, params }));\n const error = new Error(`Protocol error: ${method}`);\n return new Promise((resolve, reject) => {\n this._callbacks.set(id, { resolve, reject, error });\n });\n }\n\n close(message: string) {\n debugLogger('closing extension connection:', message);\n if (this._ws.readyState === ws.OPEN)\n this._ws.close(1000, message);\n }\n\n private _onMessage(event: websocket.RawData) {\n const eventData = event.toString();\n let parsedJson;\n try {\n parsedJson = JSON.parse(eventData);\n } catch (e: any) {\n debugLogger(`<closing ws> Closing websocket due to malformed JSON. eventData=${eventData} e=${e?.message}`);\n this._ws.close();\n return;\n }\n try {\n this._handleParsedMessage(parsedJson);\n } catch (e: any) {\n debugLogger(`<closing ws> Closing websocket due to failed onmessage callback. eventData=${eventData} e=${e?.message}`);\n this._ws.close();\n }\n }\n\n private _handleParsedMessage(object: ExtensionResponse) {\n if (object.id && this._callbacks.has(object.id)) {\n const callback = this._callbacks.get(object.id)!;\n this._callbacks.delete(object.id);\n if (object.error) {\n const error = callback.error;\n error.message = object.error;\n callback.reject(error);\n } else {\n callback.resolve(object.result);\n }\n } else if (object.id) {\n debugLogger('\u2190 Extension: unexpected response', object);\n } else {\n this.onmessage?.(object.method! as keyof ExtensionEvents, object.params);\n }\n }\n\n private _onClose(event: websocket.CloseEvent) {\n debugLogger(`<ws closed> code=${event.code} reason=${event.reason}`);\n this._dispose();\n this.onclose?.(this, event.reason);\n }\n\n private _onError(event: websocket.ErrorEvent) {\n debugLogger(`<ws error> message=${event.message} type=${event.type} target=${event.target}`);\n this._dispose();\n }\n\n private _dispose() {\n for (const callback of this._callbacks.values())\n callback.reject(new Error('WebSocket closed'));\n this._callbacks.clear();\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_http", "ws"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/mcp/extension/extensionContextFactory.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as playwright from 'playwright-core';\nimport { debug } from 'playwright-core/lib/utilsBundle';\n\nimport { startHttpServer } from '../sdk/http';\nimport { CDPRelayServer } from './cdpRelay';\n\nimport type { BrowserContextFactory } from '../browser/browserContextFactory';\nimport type { ClientInfo } from '../sdk/server';\n\nconst debugLogger = debug('pw:mcp:relay');\n\nexport class ExtensionContextFactory implements BrowserContextFactory {\n private _browserChannel: string;\n private _userDataDir?: string;\n private _executablePath?: string;\n\n constructor(browserChannel: string, userDataDir: string | undefined, executablePath: string | undefined) {\n this._browserChannel = browserChannel;\n this._userDataDir = userDataDir;\n this._executablePath = executablePath;\n }\n\n async createContext(clientInfo: ClientInfo, abortSignal: AbortSignal, toolName: string | undefined): Promise<{ browserContext: playwright.BrowserContext, close: () => Promise<void> }> {\n const browser = await this._obtainBrowser(clientInfo, abortSignal, toolName);\n return {\n browserContext: browser.contexts()[0],\n close: async () => {\n debugLogger('close() called for browser context');\n await browser.close();\n }\n };\n }\n\n private async _obtainBrowser(clientInfo: ClientInfo, abortSignal: AbortSignal, toolName: string | undefined): Promise<playwright.Browser> {\n const relay = await this._startRelay(abortSignal);\n await relay.ensureExtensionConnectionForMCPContext(clientInfo, abortSignal, toolName);\n return await playwright.chromium.connectOverCDP(relay.cdpEndpoint());\n }\n\n private async _startRelay(abortSignal: AbortSignal) {\n const httpServer = await startHttpServer({});\n if (abortSignal.aborted) {\n httpServer.close();\n throw new Error(abortSignal.reason);\n }\n const cdpRelayServer = new CDPRelayServer(httpServer, this._browserChannel, this._userDataDir, this._executablePath);\n abortSignal.addEventListener('abort', () => cdpRelayServer.stop());\n debugLogger(`CDP relay server started, extension endpoint: ${cdpRelayServer.extensionEndpoint()}.`);\n return cdpRelayServer;\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,iBAA4B;AAC5B,yBAAsB;AAEtB,kBAAgC;AAChC,sBAA+B;AAK/B,MAAM,kBAAc,0BAAM,cAAc;AAEjC,MAAM,wBAAyD;AAAA,EAKpE,YAAY,gBAAwB,aAAiC,gBAAoC;AACvG,SAAK,kBAAkB;AACvB,SAAK,eAAe;AACpB,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,MAAM,cAAc,YAAwB,aAA0B,UAAkH;AACtL,UAAM,UAAU,MAAM,KAAK,eAAe,YAAY,aAAa,QAAQ;AAC3E,WAAO;AAAA,MACL,gBAAgB,QAAQ,SAAS,EAAE,CAAC;AAAA,MACpC,OAAO,YAAY;AACjB,oBAAY,oCAAoC;AAChD,cAAM,QAAQ,MAAM;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,eAAe,YAAwB,aAA0B,UAA2D;AACxI,UAAM,QAAQ,MAAM,KAAK,YAAY,WAAW;AAChD,UAAM,MAAM,uCAAuC,YAAY,aAAa,QAAQ;AACpF,WAAO,MAAM,WAAW,SAAS,eAAe,MAAM,YAAY,CAAC;AAAA,EACrE;AAAA,EAEA,MAAc,YAAY,aAA0B;AAClD,UAAM,aAAa,UAAM,6BAAgB,CAAC,CAAC;AAC3C,QAAI,YAAY,SAAS;AACvB,iBAAW,MAAM;AACjB,YAAM,IAAI,MAAM,YAAY,MAAM;AAAA,IACpC;AACA,UAAM,iBAAiB,IAAI,+BAAe,YAAY,KAAK,iBAAiB,KAAK,cAAc,KAAK,eAAe;AACnH,gBAAY,iBAAiB,SAAS,MAAM,eAAe,KAAK,CAAC;AACjE,gBAAY,iDAAiD,eAAe,kBAAkB,CAAC,GAAG;AAClG,WAAO;AAAA,EACT;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/mcp/extension/protocol.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Whenever the commands/events change, the version must be updated. The latest\n// extension version should be compatible with the old MCP clients.\nexport const VERSION = 1;\n\nexport type ExtensionCommand = {\n 'attachToTab': {\n params: {};\n };\n 'forwardCDPCommand': {\n params: {\n method: string,\n sessionId?: string\n params?: any,\n };\n };\n};\n\nexport type ExtensionEvents = {\n 'forwardCDPEvent': {\n params: {\n method: string,\n sessionId?: string\n params?: any,\n };\n };\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBO,MAAM,UAAU;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/mcp/index.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BrowserServerBackend } from './browser/browserServerBackend';\nimport { resolveConfig } from './browser/config';\nimport { contextFactory } from './browser/browserContextFactory';\nimport * as mcpServer from './sdk/server';\n\nimport type { Config } from './config';\nimport type { BrowserContext } from 'playwright';\nimport type { BrowserContextFactory } from './browser/browserContextFactory';\nimport type { Server } from '@modelcontextprotocol/sdk/server/index.js';\n\nconst packageJSON = require('../../package.json');\n\nexport async function createConnection(userConfig: Config = {}, contextGetter?: () => Promise<BrowserContext>): Promise<Server> {\n const config = await resolveConfig(userConfig);\n const factory = contextGetter ? new SimpleBrowserContextFactory(contextGetter) : contextFactory(config);\n return mcpServer.createServer('Playwright', packageJSON.version, new BrowserServerBackend(config, factory), false);\n}\n\nclass SimpleBrowserContextFactory implements BrowserContextFactory {\n name = 'custom';\n description = 'Connect to a browser using a custom context getter';\n\n private readonly _contextGetter: () => Promise<BrowserContext>;\n\n constructor(contextGetter: () => Promise<BrowserContext>) {\n this._contextGetter = contextGetter;\n }\n\n async createContext(): Promise<{ browserContext: BrowserContext, close: () => Promise<void> }> {\n const browserContext = await this._contextGetter();\n return {\n browserContext,\n close: () => browserContext.close()\n };\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,kCAAqC;AACrC,oBAA8B;AAC9B,mCAA+B;AAC/B,gBAA2B;AAO3B,MAAM,cAAc,QAAQ,oBAAoB;AAEhD,eAAsB,iBAAiB,aAAqB,CAAC,GAAG,eAAgE;AAC9H,QAAM,SAAS,UAAM,6BAAc,UAAU;AAC7C,QAAM,UAAU,gBAAgB,IAAI,4BAA4B,aAAa,QAAI,6CAAe,MAAM;AACtG,SAAO,UAAU,aAAa,cAAc,YAAY,SAAS,IAAI,iDAAqB,QAAQ,OAAO,GAAG,KAAK;AACnH;AAEA,MAAM,4BAA6D;AAAA,EAMjE,YAAY,eAA8C;AAL1D,gBAAO;AACP,uBAAc;AAKZ,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,MAAM,gBAAyF;AAC7F,UAAM,iBAAiB,MAAM,KAAK,eAAe;AACjD,WAAO;AAAA,MACL;AAAA,MACA,OAAO,MAAM,eAAe,MAAM;AAAA,IACpC;AAAA,EACF;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/mcp/log.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { debug } from 'playwright-core/lib/utilsBundle';\n\nconst errorDebug = debug('pw:mcp:error');\n\nexport function logUnhandledError(error: unknown) {\n errorDebug(error);\n}\n\nexport const testDebug = debug('pw:mcp:test');\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,yBAAsB;AAEtB,MAAM,iBAAa,0BAAM,cAAc;AAEhC,SAAS,kBAAkB,OAAgB;AAChD,aAAW,KAAK;AAClB;AAEO,MAAM,gBAAY,0BAAM,aAAa;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/mcp/program.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* eslint-disable no-console */\n\nimport fs from 'fs';\n\nimport { colors, ProgramOption } from 'playwright-core/lib/utilsBundle';\nimport { registry } from 'playwright-core/lib/server';\n\nimport * as mcpServer from './sdk/server';\nimport { commaSeparatedList, dotenvFileLoader, headerParser, numberParser, resolutionParser, resolveCLIConfig, semicolonSeparatedList } from './browser/config';\nimport { setupExitWatchdog } from './browser/watchdog';\nimport { contextFactory } from './browser/browserContextFactory';\nimport { ProxyBackend } from './sdk/proxyBackend';\nimport { BrowserServerBackend } from './browser/browserServerBackend';\nimport { ExtensionContextFactory } from './extension/extensionContextFactory';\n\nimport type { Command } from 'playwright-core/lib/utilsBundle';\nimport type { MCPProvider } from './sdk/proxyBackend';\n\nexport function decorateCommand(command: Command, version: string) {\n command\n .option('--allowed-hosts <hosts...>', 'comma-separated list of hosts this server is allowed to serve from. Defaults to the host the server is bound to. Pass \\'*\\' to disable the host check.', commaSeparatedList)\n .option('--allowed-origins <origins>', 'semicolon-separated list of origins to allow the browser to request. Default is to allow all.', semicolonSeparatedList)\n .option('--blocked-origins <origins>', 'semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed.', semicolonSeparatedList)\n .option('--block-service-workers', 'block service workers')\n .option('--browser <browser>', 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.')\n .option('--caps <caps>', 'comma-separated list of additional capabilities to enable, possible values: vision, pdf.', commaSeparatedList)\n .option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')\n .option('--cdp-header <headers...>', 'CDP headers to send with the connect request, multiple can be specified.', headerParser)\n .option('--config <path>', 'path to the configuration file.')\n .option('--device <device>', 'device to emulate, for example: \"iPhone 15\"')\n .option('--executable-path <path>', 'path to the browser executable.')\n .option('--extension', 'Connect to a running browser instance (Edge/Chrome only). Requires the \"Playwright MCP Bridge\" browser extension to be installed.')\n .option('--grant-permissions <permissions...>', 'List of permissions to grant to the browser context, for example \"geolocation\", \"clipboard-read\", \"clipboard-write\".', commaSeparatedList)\n .option('--headless', 'run browser in headless mode, headed by default')\n .option('--host <host>', 'host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.')\n .option('--ignore-https-errors', 'ignore https errors')\n .option('--init-script <path...>', 'path to JavaScript file to add as an initialization script. The script will be evaluated in every page before any of the page\\'s scripts. Can be specified multiple times.')\n .option('--isolated', 'keep the browser profile in memory, do not save it to disk.')\n .option('--image-responses <mode>', 'whether to send image responses to the client. Can be \"allow\" or \"omit\", Defaults to \"allow\".')\n .option('--no-sandbox', 'disable the sandbox for all process types that are normally sandboxed.')\n .option('--output-dir <path>', 'path to the directory for output files.')\n .option('--port <port>', 'port to listen on for SSE transport.')\n .option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example \".com,chromium.org,.domain.com\"')\n .option('--proxy-server <proxy>', 'specify proxy server, for example \"http://myproxy:3128\" or \"socks5://myproxy:8080\"')\n .option('--save-session', 'Whether to save the Playwright MCP session into the output directory.')\n .option('--save-trace', 'Whether to save the Playwright Trace of the session into the output directory.')\n .option('--save-video <size>', 'Whether to save the video of the session into the output directory. For example \"--save-video=800x600\"', resolutionParser.bind(null, '--save-video'))\n .option('--secrets <path>', 'path to a file containing secrets in the dotenv format', dotenvFileLoader)\n .option('--shared-browser-context', 'reuse the same browser context between all connected HTTP clients.')\n .option('--storage-state <path>', 'path to the storage state file for isolated sessions.')\n .option('--test-id-attribute <attribute>', 'specify the attribute to use for test ids, defaults to \"data-testid\"')\n .option('--timeout-action <timeout>', 'specify action timeout in milliseconds, defaults to 5000ms', numberParser)\n .option('--timeout-navigation <timeout>', 'specify navigation timeout in milliseconds, defaults to 60000ms', numberParser)\n .option('--user-agent <ua string>', 'specify user agent string')\n .option('--user-data-dir <path>', 'path to the user data directory. If not specified, a temporary directory will be created.')\n .option('--viewport-size <size>', 'specify browser viewport size in pixels, for example \"1280x720\"', resolutionParser.bind(null, '--viewport-size'))\n .addOption(new ProgramOption('--connect-tool', 'Allow to switch between different browser connection methods.').hideHelp())\n .addOption(new ProgramOption('--vision', 'Legacy option, use --caps=vision instead').hideHelp())\n .action(async options => {\n setupExitWatchdog();\n\n if (options.vision) {\n console.error('The --vision option is deprecated, use --caps=vision instead');\n options.caps = 'vision';\n }\n\n const config = await resolveCLIConfig(options);\n\n // Chromium browsers require ffmpeg to be installed to save video.\n if (config.saveVideo && !checkFfmpeg()) {\n console.error(colors.red(`\\nError: ffmpeg required to save the video is not installed.`));\n console.error(`\\nPlease run the command below. It will install a local copy of ffmpeg and will not change any system-wide settings.`);\n console.error(`\\n npx playwright install ffmpeg\\n`);\n // eslint-disable-next-line no-restricted-properties\n process.exit(1);\n }\n\n // const factoryPool = new BrowserContextFactoryPool();\n const extensionContextFactory = new ExtensionContextFactory(config.browser.launchOptions.channel || 'chrome', config.browser.userDataDir, config.browser.launchOptions.executablePath);\n\n if (options.extension) {\n const serverBackendFactory: mcpServer.ServerBackendFactory = {\n name: 'Playwright w/ extension',\n nameInConfig: 'playwright-extension',\n version,\n config: config,\n create: (cfg) => new BrowserServerBackend(cfg, extensionContextFactory)\n };\n await mcpServer.start(serverBackendFactory, config.server);\n return;\n }\n\n if (options.connectTool) {\n const providers: MCPProvider[] = [\n {\n name: 'default',\n description: 'Starts standalone browser',\n connect: () => mcpServer.wrapInProcess(new BrowserServerBackend(config, contextFactory(config))),\n },\n {\n name: 'extension',\n description: 'Connect to a browser using the Playwright MCP extension',\n connect: () => mcpServer.wrapInProcess(new BrowserServerBackend(config, extensionContextFactory)),\n },\n ];\n const factory: mcpServer.ServerBackendFactory = {\n name: 'Playwright w/ switch',\n nameInConfig: 'playwright-switch',\n version,\n config: config,\n create: (cfg) => new ProxyBackend(providers),\n };\n await mcpServer.start(factory, config.server);\n return;\n }\n\n const factory: mcpServer.ServerBackendFactory = {\n name: 'Playwright',\n nameInConfig: 'playwright',\n version,\n config: config,\n create: (cfg) => new BrowserServerBackend(cfg, contextFactory(cfg))\n };\n await mcpServer.start(factory, config.server);\n });\n}\n\nfunction checkFfmpeg(): boolean {\n try {\n const executable = registry.findExecutable('ffmpeg')!;\n return fs.existsSync(executable.executablePath('javascript')!);\n } catch (error) {\n return false;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["factory", "fs"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/mcp/sdk/bundle.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// @ts-ignore\nimport * as bundle from '../../mcpBundleImpl';\n\nconst zodToJsonSchema: typeof import('zod-to-json-schema').zodToJsonSchema = bundle.zodToJsonSchema;\nconst Client: typeof import('@modelcontextprotocol/sdk/client/index.js').Client = bundle.Client;\nconst Server: typeof import('@modelcontextprotocol/sdk/server/index.js').Server = bundle.Server;\nconst SSEClientTransport: typeof import('@modelcontextprotocol/sdk/client/sse.js').SSEClientTransport = bundle.SSEClientTransport;\nconst SSEServerTransport: typeof import('@modelcontextprotocol/sdk/server/sse.js').SSEServerTransport = bundle.SSEServerTransport;\nconst StdioClientTransport: typeof import('@modelcontextprotocol/sdk/client/stdio.js').StdioClientTransport = bundle.StdioClientTransport;\nconst StdioServerTransport: typeof import('@modelcontextprotocol/sdk/server/stdio.js').StdioServerTransport = bundle.StdioServerTransport;\nconst StreamableHTTPServerTransport: typeof import('@modelcontextprotocol/sdk/server/streamableHttp.js').StreamableHTTPServerTransport = bundle.StreamableHTTPServerTransport;\nconst StreamableHTTPClientTransport: typeof import('@modelcontextprotocol/sdk/client/streamableHttp.js').StreamableHTTPClientTransport = bundle.StreamableHTTPClientTransport;\nconst CallToolRequestSchema: typeof import('@modelcontextprotocol/sdk/types.js').CallToolRequestSchema = bundle.CallToolRequestSchema;\nconst ListRootsRequestSchema: typeof import('@modelcontextprotocol/sdk/types.js').ListRootsRequestSchema = bundle.ListRootsRequestSchema;\nconst ProgressNotificationSchema: typeof import('@modelcontextprotocol/sdk/types.js').ProgressNotificationSchema = bundle.ProgressNotificationSchema;\nconst ListToolsRequestSchema: typeof import('@modelcontextprotocol/sdk/types.js').ListToolsRequestSchema = bundle.ListToolsRequestSchema;\nconst PingRequestSchema: typeof import('@modelcontextprotocol/sdk/types.js').PingRequestSchema = bundle.PingRequestSchema;\nconst z: typeof import('zod') = bundle.z;\n\nexport {\n zodToJsonSchema,\n Client,\n Server,\n SSEClientTransport,\n SSEServerTransport,\n StdioClientTransport,\n StdioServerTransport,\n StreamableHTTPClientTransport,\n StreamableHTTPServerTransport,\n CallToolRequestSchema,\n ListRootsRequestSchema,\n ListToolsRequestSchema,\n PingRequestSchema,\n ProgressNotificationSchema,\n z,\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBA,aAAwB;AAExB,MAAM,kBAAuE,OAAO;AACpF,MAAM,SAA4E,OAAO;AACzF,MAAM,SAA4E,OAAO;AACzF,MAAM,qBAAkG,OAAO;AAC/G,MAAM,qBAAkG,OAAO;AAC/G,MAAM,uBAAwG,OAAO;AACrH,MAAM,uBAAwG,OAAO;AACrH,MAAM,gCAAmI,OAAO;AAChJ,MAAM,gCAAmI,OAAO;AAChJ,MAAM,wBAAmG,OAAO;AAChH,MAAM,yBAAqG,OAAO;AAClH,MAAM,6BAA6G,OAAO;AAC1H,MAAM,yBAAqG,OAAO;AAClH,MAAM,oBAA2F,OAAO;AACxG,MAAM,IAA0B,OAAO;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/mcp/sdk/exports.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport * from './inProcessTransport';\nexport * from './proxyBackend';\nexport * from './server';\nexport * from './tool';\nexport * from './http';\nexport * from './mdb';\n"],
5
- "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;AAgBA,4BAAc,iCAhBd;AAiBA,4BAAc,2BAjBd;AAkBA,4BAAc,qBAlBd;AAmBA,4BAAc,mBAnBd;AAoBA,4BAAc,mBApBd;AAqBA,4BAAc,kBArBd;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/mcp/sdk/http.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport assert from 'assert';\nimport net from 'net';\nimport http from 'http';\nimport crypto from 'crypto';\n\nimport { debug } from 'playwright-core/lib/utilsBundle';\nimport getRawBody from 'raw-body';\nimport contentType from 'content-type';\n\nimport * as mcpBundle from './bundle';\nimport * as mcpServer from './server';\nimport { configFromURLParams, configFromCLIOptions, mergeConfig } from '../browser/config';\n\nimport type { ServerBackendFactory } from './server';\nimport type { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';\nimport type { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport type { FullConfig, CLIOptions } from '../browser/config';\nimport type { Config } from '../config';\n\nconst testDebug = debug('pw:mcp:test');\n\nexport async function startHttpServer(config: { host?: string, port?: number }, abortSignal?: AbortSignal): Promise<http.Server> {\n const { host, port } = config;\n const httpServer = http.createServer();\n decorateServer(httpServer);\n await new Promise<void>((resolve, reject) => {\n httpServer.on('error', reject);\n abortSignal?.addEventListener('abort', () => {\n httpServer.close();\n reject(new Error('Aborted'));\n });\n httpServer.listen(port, host, () => {\n resolve();\n httpServer.removeListener('error', reject);\n });\n });\n return httpServer;\n}\n\nexport function httpAddressToString(address: string | net.AddressInfo | null): string {\n assert(address, 'Could not bind server socket');\n if (typeof address === 'string')\n return address;\n const resolvedPort = address.port;\n let resolvedHost = address.family === 'IPv4' ? address.address : `[${address.address}]`;\n if (resolvedHost === '0.0.0.0' || resolvedHost === '[::]')\n resolvedHost = 'localhost';\n return `http://${resolvedHost}:${resolvedPort}`;\n}\n\nexport async function installHttpTransport(httpServer: http.Server, serverBackendFactory: ServerBackendFactory, unguessableUrl: boolean, allowedHosts?: string[]) {\n const url = httpAddressToString(httpServer.address());\n const host = new URL(url).host;\n allowedHosts = (allowedHosts || [host]).map(h => h.toLowerCase());\n const allowAnyHost = allowedHosts.includes('*');\n const pathPrefix = unguessableUrl ? `/${crypto.randomUUID()}` : '';\n\n const sseSessions = new Map();\n const streamableSessions = new Map();\n httpServer.on('request', async (req, res) => {\n if (!allowAnyHost) {\n const host = req.headers.host?.toLowerCase();\n if (!host) {\n res.statusCode = 400;\n return res.end('Missing host');\n }\n\n // Prevent DNS evil.com -> localhost rebind.\n if (!allowedHosts.includes(host)) {\n // Access from the browser is forbidden.\n res.statusCode = 403;\n return res.end('Access is only allowed at ' + allowedHosts.join(', '));\n }\n }\n\n if (!req.url?.startsWith(pathPrefix)) {\n res.statusCode = 404;\n return res.end('Not found');\n }\n\n const path = req.url?.slice(pathPrefix.length);\n const url = new URL(`http://localhost${path}`);\n if (url.pathname === '/killkillkill' && req.method === 'GET') {\n res.statusCode = 200;\n res.end('Killing process');\n // Simulate Ctrl+C in a way that works on Windows too.\n process.emit('SIGINT');\n return;\n }\n\n // Add health check endpoint\n if (url.pathname === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({\n status: 'healthy',\n version: serverBackendFactory.version,\n service: serverBackendFactory.name,\n timestamp: new Date().toISOString()\n }));\n return;\n }\n\n if (url.pathname.startsWith('/sse'))\n await handleSSE(serverBackendFactory, req, res, url, sseSessions);\n else\n await handleStreamable(serverBackendFactory, req, res, streamableSessions);\n });\n\n return `${url}${pathPrefix}`;\n}\n\nasync function handleSSE(serverBackendFactory: ServerBackendFactory, req: http.IncomingMessage, res: http.ServerResponse, url: URL, sessions: Map<string, SSEServerTransport>) {\n if (req.method === 'POST') {\n const sessionId = url.searchParams.get('sessionId');\n if (!sessionId) {\n res.statusCode = 400;\n return res.end('Missing sessionId');\n }\n\n const transport = sessions.get(sessionId);\n if (!transport) {\n res.statusCode = 404;\n return res.end('Session not found');\n }\n\n return await transport.handlePostMessage(req, res);\n } else if (req.method === 'GET') {\n const transport = new mcpBundle.SSEServerTransport('/sse', res);\n sessions.set(transport.sessionId, transport);\n testDebug(`create SSE session: ${transport.sessionId}`);\n\n // Parse URL config overrides and merge with base config\n const urlConfigOverrides = configFromURLParams(url);\n let sessionConfig: FullConfig | undefined;\n\n if (urlConfigOverrides.browser && Object.keys(urlConfigOverrides.browser).length > 0) {\n sessionConfig = mergeConfig(serverBackendFactory.config, urlConfigOverrides);\n testDebug(`Using session-specific config for SSE session: ${JSON.stringify(sessionConfig)}`);\n } else {\n testDebug(`No config overrides for SSE session, using base config (enables browser sharing)`);\n }\n\n await mcpServer.connect(serverBackendFactory, transport, false, sessionConfig);\n res.on('close', () => {\n testDebug(`delete SSE session: ${transport.sessionId}`);\n sessions.delete(transport.sessionId);\n });\n return;\n }\n\n res.statusCode = 405;\n res.end('Method not allowed');\n}\n\nasync function handleStreamable(serverBackendFactory: ServerBackendFactory, req: http.IncomingMessage, res: http.ServerResponse, sessions: Map<string, StreamableHTTPServerTransport>) {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (sessionId) {\n const transport = sessions.get(sessionId);\n if (!transport) {\n res.statusCode = 404;\n res.end('Session not found');\n return;\n }\n return await transport.handleRequest(req, res);\n }\n\n if (req.method === 'POST') {\n // Read and parse the request body to extract config from init request\n const ct = req.headers['content-type'];\n if (!ct || !ct.includes('application/json')) {\n res.statusCode = 415;\n res.end('Unsupported Media Type');\n return;\n }\n\n const parsedCt = contentType.parse(ct);\n const body = await getRawBody(req, {\n limit: '4mb',\n encoding: parsedCt.parameters.charset ?? 'utf-8',\n });\n const parsedBody = JSON.parse(body.toString());\n\n // Extract config from init request body\n const bodyConfigOverrides = configFromInitRequest(parsedBody);\n \n // Only merge and use session config if there are actual overrides\n // Otherwise use undefined to share the factory's base config (enables browser sharing)\n let sessionConfig: FullConfig | undefined;\n if (Object.keys(bodyConfigOverrides).length > 0) {\n sessionConfig = mergeConfig(serverBackendFactory.config, bodyConfigOverrides);\n testDebug(`Using config from init request body with overrides: ${JSON.stringify(sessionConfig)}`);\n } else {\n testDebug(`No config overrides, using base config (enables browser sharing)`);\n }\n\n const transport = new mcpBundle.StreamableHTTPServerTransport({\n sessionIdGenerator: () => crypto.randomUUID(),\n onsessioninitialized: async sessionId => {\n testDebug(`create http session: ${transport.sessionId}`);\n await mcpServer.connect(serverBackendFactory, transport, true, sessionConfig);\n sessions.set(sessionId, transport);\n }\n });\n\n transport.onclose = () => {\n if (!transport.sessionId)\n return;\n sessions.delete(transport.sessionId);\n testDebug(`delete http session: ${transport.sessionId}`);\n };\n\n // Pass parsedBody to avoid double-reading\n await transport.handleRequest(req, res, parsedBody);\n return;\n }\n\n res.statusCode = 400;\n res.end('Invalid request');\n}\n\n/**\n * Extract config overrides from MCP initialization request\n * Supports passing browser config in params.playwright_config\n * Format: { \"isolated\": true, \"no_sandbox\": true, \"storage_state\": {...}, ... }\n */\nfunction configFromInitRequest(body: any): Config {\n // Check if this is an initialize request\n if (body?.method !== 'initialize')\n return {};\n\n // Extract params.playwright_config if present\n const playwrightConfig = body?.params?.playwright_config;\n if (!playwrightConfig)\n return {};\n\n testDebug('playwright_config from body:', playwrightConfig);\n\n // Convert to CLIOptions format (supporting both snake_case and camelCase)\n const options: any = {};\n\n // Map snake_case keys to CLIOptions\n const keyMap: Record<string, string> = {\n 'allowed_origins': 'allowedOrigins',\n 'blocked_origins': 'blockedOrigins',\n 'block_service_workers': 'blockServiceWorkers',\n 'browser': 'browser',\n 'caps': 'caps',\n 'cdp_endpoint': 'cdpEndpoint',\n 'device': 'device',\n 'executable_path': 'executablePath',\n 'headless': 'headless',\n 'ignore_https_errors': 'ignoreHttpsErrors',\n 'isolated': 'isolated',\n 'image_responses': 'imageResponses',\n 'no_sandbox': 'sandbox', // Special: no_sandbox=true means sandbox=false\n 'sandbox': 'sandbox',\n 'proxy_bypass': 'proxyBypass',\n 'proxy_server': 'proxyServer',\n 'storage_state': 'storageState',\n 'user_agent': 'userAgent',\n 'user_data_dir': 'userDataDir',\n 'viewport_size': 'viewportSize',\n };\n\n for (const [snakeKey, camelKey] of Object.entries(keyMap)) {\n if (playwrightConfig[snakeKey] !== undefined) {\n let value = playwrightConfig[snakeKey];\n\n // Special handling for no_sandbox: no_sandbox=true means disable sandbox\n if (snakeKey === 'no_sandbox') {\n value = !value; // Invert the boolean\n }\n\n options[camelKey] = value;\n }\n }\n\n // Also support camelCase keys directly (in case client uses them)\n for (const key of Object.keys(playwrightConfig)) {\n if (!key.includes('_') && options[key] === undefined) {\n options[key] = playwrightConfig[key];\n }\n }\n\n testDebug('Converted to CLIOptions:', options);\n\n // Use configFromCLIOptions to get the final Config (reuses all existing logic)\n return configFromCLIOptions(options);\n}\n\nfunction decorateServer(server: net.Server) {\n const sockets = new Set<net.Socket>();\n server.on('connection', socket => {\n sockets.add(socket);\n socket.once('close', () => sockets.delete(socket));\n });\n\n const close = server.close;\n server.close = (callback?: (err?: Error) => void) => {\n for (const socket of sockets)\n socket.destroy();\n sockets.clear();\n return close.call(server, callback);\n };\n}\n"],
5
- "mappings": "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",
6
- "names": ["http", "assert", "crypto", "host", "url", "contentType", "getRawBody", "sessionId"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/mcp/sdk/inProcessTransport.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport type { Transport, TransportSendOptions } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport type { JSONRPCMessage, MessageExtraInfo } from '@modelcontextprotocol/sdk/types.js';\n\nexport class InProcessTransport implements Transport {\n private _server: Server;\n private _serverTransport: InProcessServerTransport;\n private _connected: boolean = false;\n\n constructor(server: Server) {\n this._server = server;\n this._serverTransport = new InProcessServerTransport(this);\n }\n\n async start(): Promise<void> {\n if (this._connected)\n throw new Error('InprocessTransport already started!');\n\n await this._server.connect(this._serverTransport);\n this._connected = true;\n }\n\n async send(message: JSONRPCMessage, options?: TransportSendOptions): Promise<void> {\n if (!this._connected)\n throw new Error('Transport not connected');\n\n\n this._serverTransport._receiveFromClient(message);\n }\n\n async close(): Promise<void> {\n if (this._connected) {\n this._connected = false;\n this.onclose?.();\n this._serverTransport.onclose?.();\n }\n }\n\n onclose?: (() => void) | undefined;\n onerror?: ((error: Error) => void) | undefined;\n onmessage?: ((message: JSONRPCMessage, extra?: MessageExtraInfo) => void) | undefined;\n sessionId?: string | undefined;\n setProtocolVersion?: ((version: string) => void) | undefined;\n\n _receiveFromServer(message: JSONRPCMessage, extra?: MessageExtraInfo): void {\n this.onmessage?.(message, extra);\n }\n}\n\nclass InProcessServerTransport implements Transport {\n private _clientTransport: InProcessTransport;\n\n constructor(clientTransport: InProcessTransport) {\n this._clientTransport = clientTransport;\n }\n\n async start(): Promise<void> {\n }\n\n async send(message: JSONRPCMessage, options?: TransportSendOptions): Promise<void> {\n this._clientTransport._receiveFromServer(message);\n }\n\n async close(): Promise<void> {\n this.onclose?.();\n }\n\n onclose?: (() => void) | undefined;\n onerror?: ((error: Error) => void) | undefined;\n onmessage?: ((message: JSONRPCMessage, extra?: MessageExtraInfo) => void) | undefined;\n sessionId?: string | undefined;\n setProtocolVersion?: ((version: string) => void) | undefined;\n _receiveFromClient(message: JSONRPCMessage): void {\n this.onmessage?.(message);\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBO,MAAM,mBAAwC;AAAA,EAKnD,YAAY,QAAgB;AAF5B,SAAQ,aAAsB;AAG5B,SAAK,UAAU;AACf,SAAK,mBAAmB,IAAI,yBAAyB,IAAI;AAAA,EAC3D;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK;AACP,YAAM,IAAI,MAAM,qCAAqC;AAEvD,UAAM,KAAK,QAAQ,QAAQ,KAAK,gBAAgB;AAChD,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,KAAK,SAAyB,SAA+C;AACjF,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,yBAAyB;AAG3C,SAAK,iBAAiB,mBAAmB,OAAO;AAAA,EAClD;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK,YAAY;AACnB,WAAK,aAAa;AAClB,WAAK,UAAU;AACf,WAAK,iBAAiB,UAAU;AAAA,IAClC;AAAA,EACF;AAAA,EAQA,mBAAmB,SAAyB,OAAgC;AAC1E,SAAK,YAAY,SAAS,KAAK;AAAA,EACjC;AACF;AAEA,MAAM,yBAA8C;AAAA,EAGlD,YAAY,iBAAqC;AAC/C,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,MAAM,QAAuB;AAAA,EAC7B;AAAA,EAEA,MAAM,KAAK,SAAyB,SAA+C;AACjF,SAAK,iBAAiB,mBAAmB,OAAO;AAAA,EAClD;AAAA,EAEA,MAAM,QAAuB;AAC3B,SAAK,UAAU;AAAA,EACjB;AAAA,EAOA,mBAAmB,SAA+B;AAChD,SAAK,YAAY,OAAO;AAAA,EAC1B;AACF;",
6
- "names": []
7
- }