@midscene/web 1.7.7 → 1.7.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/bridge-mode/io-client.mjs +1 -1
- package/dist/es/bridge-mode/io-server.mjs +2 -2
- package/dist/es/bridge-mode/page-browser-side.mjs +1 -1
- package/dist/es/cli-options.mjs +99 -0
- package/dist/es/cli-options.mjs.map +1 -0
- package/dist/es/cli.mjs +11 -32
- package/dist/es/cli.mjs.map +1 -1
- package/dist/es/common/viewport.mjs +38 -0
- package/dist/es/common/viewport.mjs.map +1 -0
- package/dist/es/mcp-server.mjs +1 -1
- package/dist/es/mcp-tools-cdp.mjs +2 -4
- package/dist/es/mcp-tools-cdp.mjs.map +1 -1
- package/dist/es/mcp-tools-puppeteer.mjs +48 -24
- package/dist/es/mcp-tools-puppeteer.mjs.map +1 -1
- package/dist/es/mcp-tools.mjs +2 -4
- package/dist/es/mcp-tools.mjs.map +1 -1
- package/dist/es/puppeteer/agent-launcher.mjs +2 -14
- package/dist/es/puppeteer/agent-launcher.mjs.map +1 -1
- package/dist/lib/bridge-mode/io-client.js +1 -1
- package/dist/lib/bridge-mode/io-server.js +2 -2
- package/dist/lib/bridge-mode/page-browser-side.js +1 -1
- package/dist/lib/cli-options.js +133 -0
- package/dist/lib/cli-options.js.map +1 -0
- package/dist/lib/cli.js +11 -32
- package/dist/lib/cli.js.map +1 -1
- package/dist/lib/common/viewport.js +90 -0
- package/dist/lib/common/viewport.js.map +1 -0
- package/dist/lib/mcp-server.js +1 -1
- package/dist/lib/mcp-tools-cdp.js +2 -4
- package/dist/lib/mcp-tools-cdp.js.map +1 -1
- package/dist/lib/mcp-tools-puppeteer.js +55 -25
- package/dist/lib/mcp-tools-puppeteer.js.map +1 -1
- package/dist/lib/mcp-tools.js +2 -4
- package/dist/lib/mcp-tools.js.map +1 -1
- package/dist/lib/puppeteer/agent-launcher.js +4 -16
- package/dist/lib/puppeteer/agent-launcher.js.map +1 -1
- package/dist/types/cli-options.d.ts +8 -0
- package/dist/types/common/viewport.d.ts +17 -0
- package/dist/types/mcp-tools-puppeteer.d.ts +8 -0
- package/dist/types/puppeteer/agent-launcher.d.ts +1 -3
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-tools.mjs","sources":["../../src/mcp-tools.ts"],"sourcesContent":["import { ScreenshotItem, z } from '@midscene/core';\nimport { BaseMidsceneTools } from '@midscene/shared/mcp/base-tools';\nimport type { ToolDefinition } from '@midscene/shared/mcp/types';\nimport { AgentOverChromeBridge } from './bridge-mode';\nimport { StaticPage } from './static';\n\n/**\n * Tools manager for Web bridge-mode MCP\n */\nexport class WebMidsceneTools extends BaseMidsceneTools<AgentOverChromeBridge> {\n protected getCliReportSessionName() {\n return 'midscene-web';\n }\n\n protected createTemporaryDevice() {\n // Use require to avoid type incompatibility with DeviceAction vs ActionSpaceItem\n // StaticPage.actionSpace() returns DeviceAction[] which is compatible at runtime\n // Use screenshotBase64 field to avoid async ScreenshotItem.create()\n return new StaticPage({\n screenshot: ScreenshotItem.create('', Date.now()),\n shotSize:
|
|
1
|
+
{"version":3,"file":"mcp-tools.mjs","sources":["../../src/mcp-tools.ts"],"sourcesContent":["import { ScreenshotItem, z } from '@midscene/core';\nimport { BaseMidsceneTools } from '@midscene/shared/mcp/base-tools';\nimport type { ToolDefinition } from '@midscene/shared/mcp/types';\nimport { AgentOverChromeBridge } from './bridge-mode';\nimport { defaultStaticPageViewportSize } from './common/viewport';\nimport { StaticPage } from './static';\n\n/**\n * Tools manager for Web bridge-mode MCP\n */\nexport class WebMidsceneTools extends BaseMidsceneTools<AgentOverChromeBridge> {\n protected getCliReportSessionName() {\n return 'midscene-web';\n }\n\n protected createTemporaryDevice() {\n // Use require to avoid type incompatibility with DeviceAction vs ActionSpaceItem\n // StaticPage.actionSpace() returns DeviceAction[] which is compatible at runtime\n // Use screenshotBase64 field to avoid async ScreenshotItem.create()\n return new StaticPage({\n screenshot: ScreenshotItem.create('', Date.now()),\n shotSize: defaultStaticPageViewportSize,\n shrunkShotToLogicalRatio: 1,\n });\n }\n\n protected async ensureAgent(\n openNewTabWithUrl?: string,\n ): Promise<AgentOverChromeBridge> {\n // Re-init if URL provided\n if (this.agent && openNewTabWithUrl) {\n try {\n await this.agent?.destroy?.();\n } catch (error) {\n console.debug('Failed to destroy agent during re-init:', error);\n }\n this.agent = undefined;\n }\n\n if (this.agent) return this.agent;\n\n // Connect to current tab when no URL provided (handles CLI stateless calls)\n this.agent = await this.initBridgeModeAgent(openNewTabWithUrl);\n\n return this.agent;\n }\n\n private async initBridgeModeAgent(\n url?: string,\n ): Promise<AgentOverChromeBridge> {\n const reportOptions = this.readCliReportAgentOptions();\n const agent = new AgentOverChromeBridge({\n closeConflictServer: true,\n ...(reportOptions ?? {}),\n });\n\n if (!url) {\n await agent.connectCurrentTab();\n } else {\n await agent.connectNewTabWithUrl(url);\n }\n\n return agent;\n }\n\n protected preparePlatformTools(): ToolDefinition[] {\n return [\n {\n name: 'web_connect',\n description:\n 'Connect to web page. If URL provided, opens new tab; otherwise connects to current tab.',\n schema: {\n url: z\n .string()\n .url()\n .optional()\n .describe('URL to open in new tab (omit to connect current tab)'),\n },\n handler: async (args) => {\n const { url } = args as { url?: string };\n\n // Bypass ensureAgent's URL check — directly init bridge agent\n if (this.agent) {\n try {\n await this.agent.destroy?.();\n } catch {}\n this.agent = undefined;\n }\n const reportSession = this.createNewCliReportSession(\n url ?? 'current-tab',\n );\n this.commitCliReportSession(reportSession);\n this.agent = await this.initBridgeModeAgent(url);\n\n const screenshot = await this.agent.page?.screenshotBase64();\n const label = url ?? 'current tab';\n\n return {\n content: [\n { type: 'text', text: `Connected to: ${label}` },\n ...(screenshot ? this.buildScreenshotContent(screenshot) : []),\n ],\n };\n },\n },\n {\n name: 'web_disconnect',\n description:\n 'Disconnect from current web page and release browser resources',\n schema: {},\n handler: this.createDisconnectHandler('web page'),\n },\n ];\n }\n}\n"],"names":["WebMidsceneTools","BaseMidsceneTools","StaticPage","ScreenshotItem","Date","defaultStaticPageViewportSize","openNewTabWithUrl","error","console","undefined","url","reportOptions","agent","AgentOverChromeBridge","z","args","reportSession","screenshot","label"],"mappings":";;;;;AAUO,MAAMA,yBAAyBC;IAC1B,0BAA0B;QAClC,OAAO;IACT;IAEU,wBAAwB;QAIhC,OAAO,IAAIC,WAAW;YACpB,YAAYC,eAAe,MAAM,CAAC,IAAIC,KAAK,GAAG;YAC9C,UAAUC;YACV,0BAA0B;QAC5B;IACF;IAEA,MAAgB,YACdC,iBAA0B,EACM;QAEhC,IAAI,IAAI,CAAC,KAAK,IAAIA,mBAAmB;YACnC,IAAI;gBACF,MAAM,IAAI,CAAC,KAAK,EAAE;YACpB,EAAE,OAAOC,OAAO;gBACdC,QAAQ,KAAK,CAAC,2CAA2CD;YAC3D;YACA,IAAI,CAAC,KAAK,GAAGE;QACf;QAEA,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK;QAGjC,IAAI,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAACH;QAE5C,OAAO,IAAI,CAAC,KAAK;IACnB;IAEA,MAAc,oBACZI,GAAY,EACoB;QAChC,MAAMC,gBAAgB,IAAI,CAAC,yBAAyB;QACpD,MAAMC,QAAQ,IAAIC,sBAAsB;YACtC,qBAAqB;YACrB,GAAIF,iBAAiB,CAAC,CAAC;QACzB;QAEA,IAAKD,KAGH,MAAME,MAAM,oBAAoB,CAACF;aAFjC,MAAME,MAAM,iBAAiB;QAK/B,OAAOA;IACT;IAEU,uBAAyC;QACjD,OAAO;YACL;gBACE,MAAM;gBACN,aACE;gBACF,QAAQ;oBACN,KAAKE,EAAAA,MACI,GACN,GAAG,GACH,QAAQ,GACR,QAAQ,CAAC;gBACd;gBACA,SAAS,OAAOC;oBACd,MAAM,EAAEL,GAAG,EAAE,GAAGK;oBAGhB,IAAI,IAAI,CAAC,KAAK,EAAE;wBACd,IAAI;4BACF,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO;wBAC1B,EAAE,OAAM,CAAC;wBACT,IAAI,CAAC,KAAK,GAAGN;oBACf;oBACA,MAAMO,gBAAgB,IAAI,CAAC,yBAAyB,CAClDN,OAAO;oBAET,IAAI,CAAC,sBAAsB,CAACM;oBAC5B,IAAI,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAACN;oBAE5C,MAAMO,aAAa,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;oBAC1C,MAAMC,QAAQR,OAAO;oBAErB,OAAO;wBACL,SAAS;4BACP;gCAAE,MAAM;gCAAQ,MAAM,CAAC,cAAc,EAAEQ,OAAO;4BAAC;+BAC3CD,aAAa,IAAI,CAAC,sBAAsB,CAACA,cAAc,EAAE;yBAC9D;oBACH;gBACF;YACF;YACA;gBACE,MAAM;gBACN,aACE;gBACF,QAAQ,CAAC;gBACT,SAAS,IAAI,CAAC,uBAAuB,CAAC;YACxC;SACD;IACH;AACF"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { getDebug } from "@midscene/shared/logger";
|
|
3
3
|
import { assert } from "@midscene/shared/utils";
|
|
4
|
+
import { defaultViewportHeight, defaultViewportWidth, resolveWebViewportSize } from "../common/viewport.mjs";
|
|
4
5
|
import { PuppeteerAgent } from "./index.mjs";
|
|
5
6
|
import { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from "@midscene/shared/constants";
|
|
6
7
|
import puppeteer from "puppeteer";
|
|
7
8
|
const defaultUA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36';
|
|
8
|
-
const defaultViewportWidth = 1440;
|
|
9
|
-
const defaultViewportHeight = 768;
|
|
10
9
|
const defaultViewportScale = 0;
|
|
11
10
|
const defaultWaitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
|
|
12
11
|
function resolveAiActionContext(target, preference) {
|
|
@@ -68,18 +67,7 @@ async function launchPuppeteerPage(target, preference, browser, existingPage) {
|
|
|
68
67
|
assert(target.url, 'url is required');
|
|
69
68
|
const freeFn = [];
|
|
70
69
|
const ua = target.userAgent || defaultUA;
|
|
71
|
-
|
|
72
|
-
if (void 0 !== target.viewportWidth && null !== target.viewportWidth) {
|
|
73
|
-
assert('number' == typeof target.viewportWidth, 'viewportWidth must be a number');
|
|
74
|
-
width = Number.parseInt(target.viewportWidth, 10);
|
|
75
|
-
assert(width > 0, `viewportWidth must be greater than 0, but got ${width}`);
|
|
76
|
-
}
|
|
77
|
-
let height = defaultViewportHeight;
|
|
78
|
-
if (void 0 !== target.viewportHeight && null !== target.viewportHeight) {
|
|
79
|
-
assert('number' == typeof target.viewportHeight, 'viewportHeight must be a number');
|
|
80
|
-
height = Number.parseInt(target.viewportHeight, 10);
|
|
81
|
-
assert(height > 0, `viewportHeight must be greater than 0, but got ${height}`);
|
|
82
|
-
}
|
|
70
|
+
const { width, height } = resolveWebViewportSize(target);
|
|
83
71
|
let dpr = defaultViewportScale;
|
|
84
72
|
if (void 0 !== target.deviceScaleFactor && null !== target.deviceScaleFactor) {
|
|
85
73
|
assert('number' == typeof target.deviceScaleFactor, 'deviceScaleFactor must be a number');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"puppeteer/agent-launcher.mjs","sources":["../../../src/puppeteer/agent-launcher.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nimport { PuppeteerAgent } from '@/puppeteer/index';\nimport type { AgentOpt, Cache, MidsceneYamlScriptWebEnv } from '@midscene/core';\nimport { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from '@midscene/shared/constants';\nimport puppeteer, { type Browser, type Page } from 'puppeteer';\n\nexport const defaultUA =\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36';\nexport const defaultViewportWidth = 1440;\nexport const defaultViewportHeight = 768;\n// Setting deviceScaleFactor value to `0` means reset this value to the system default in Puppeteer.\nexport const defaultViewportScale = 0;\nexport const defaultWaitForNetworkIdleTimeout =\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n\nexport function resolveAiActionContext(\n target: MidsceneYamlScriptWebEnv,\n preference?: Partial<Pick<AgentOpt, 'aiActionContext' | 'aiActContext'>>,\n): AgentOpt['aiActionContext'] | undefined {\n // Prefer agent-level preference if provided; otherwise fall back to target-level context.\n // Priority: preference.aiActContext > preference.aiActionContext (deprecated) > target.aiActionContext\n const data =\n preference?.aiActContext ??\n preference?.aiActionContext ??\n target.aiActionContext;\n return data;\n}\n\n/**\n * Chrome arguments that may reduce browser security.\n * These should only be used in controlled testing environments.\n *\n * Security implications:\n * - `--no-sandbox`: Disables Chrome's sandbox security model\n * - `--disable-setuid-sandbox`: Disables setuid sandbox on Linux\n * - `--disable-web-security`: Allows cross-origin requests without CORS\n * - `--ignore-certificate-errors`: Ignores SSL/TLS certificate errors\n * - `--disable-features=IsolateOrigins`: Disables origin isolation\n * - `--disable-site-isolation-trials`: Disables site isolation\n * - `--allow-running-insecure-content`: Allows mixed HTTP/HTTPS content\n */\nconst DANGEROUS_ARGS = [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-web-security',\n '--ignore-certificate-errors',\n '--disable-features=IsolateOrigins',\n '--disable-site-isolation-trials',\n '--allow-running-insecure-content',\n] as const;\n\n/**\n * Validates Chrome launch arguments for security concerns.\n * Emits a warning if dangerous arguments are detected.\n *\n * This function filters out arguments that are already present in baseArgs\n * to avoid warning about platform-specific defaults (e.g., --no-sandbox on non-Windows).\n *\n * @param args - Chrome launch arguments to validate\n * @param baseArgs - Base Chrome arguments already configured\n *\n * @example\n * ```typescript\n * // Will show warning for --disable-web-security\n * validateChromeArgs(['--disable-web-security', '--headless'], ['--no-sandbox']);\n *\n * // Will NOT show warning for --no-sandbox (already in baseArgs)\n * validateChromeArgs(['--no-sandbox'], ['--no-sandbox', '--headless']);\n * ```\n */\nfunction validateChromeArgs(args: string[], baseArgs: string[]): void {\n // Filter out arguments that are already in baseArgs\n const newArgs = args.filter(\n (arg) =>\n !baseArgs.some((baseArg) => {\n // Check if arg starts with the same flag as baseArg (before '=' if present)\n const argFlag = arg.split('=')[0];\n const baseFlag = baseArg.split('=')[0];\n return argFlag === baseFlag;\n }),\n );\n\n const dangerousArgs = newArgs.filter((arg) =>\n DANGEROUS_ARGS.some((dangerous) => arg.startsWith(dangerous)),\n );\n\n if (dangerousArgs.length > 0) {\n console.warn(\n `Warning: Dangerous Chrome arguments detected: ${dangerousArgs.join(', ')}.\\nThese arguments may reduce browser security. Use only in controlled testing environments.`,\n );\n }\n}\n\ninterface FreeFn {\n name: string;\n fn: () => void;\n}\n\nconst launcherDebug = getDebug('puppeteer:launcher');\n\nexport interface BuildChromeArgsOptions {\n userAgent?: string;\n windowSize?: { width: number; height: number };\n chromeArgs?: string[];\n}\n\n/**\n * Builds Chrome launch arguments with sensible defaults.\n *\n * Platform-specific behavior:\n * - On non-Windows systems, automatically adds --no-sandbox and --disable-setuid-sandbox\n * for compatibility with containerized/CI environments\n *\n * @param options - Configuration options for Chrome arguments\n * @returns Array of Chrome launch arguments\n *\n * @example\n * ```typescript\n * // Basic usage\n * const args = buildChromeArgs();\n *\n * // With custom arguments\n * const args = buildChromeArgs({\n * chromeArgs: ['--disable-gpu', '--disable-dev-shm-usage'],\n * userAgent: 'CustomUA/1.0',\n * windowSize: { width: 1920, height: 1080 },\n * });\n * ```\n */\nexport function buildChromeArgs(options?: BuildChromeArgsOptions): string[] {\n const isWindows = process.platform === 'win32';\n\n const sandboxArgs = isWindows\n ? []\n : ['--no-sandbox', '--disable-setuid-sandbox'];\n const featureArgs = [\n '--disable-features=HttpsFirstBalancedModeAutoEnable',\n '--disable-features=PasswordLeakDetection',\n '--disable-save-password-bubble',\n ];\n const userAgentArg = options?.userAgent\n ? [`--user-agent=\"${options.userAgent}\"`]\n : [];\n const windowSizeArg = options?.windowSize\n ? [`--window-size=${options.windowSize.width},${options.windowSize.height}`]\n : [];\n\n const baseArgs = [\n ...sandboxArgs,\n ...featureArgs,\n ...userAgentArg,\n ...windowSizeArg,\n ];\n\n if (options?.chromeArgs?.length) {\n validateChromeArgs(options.chromeArgs, baseArgs);\n return [...baseArgs, ...options.chromeArgs];\n }\n\n return baseArgs;\n}\n\nexport async function launchPuppeteerPage(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n ignoreDefaultArgs?: boolean | string[];\n },\n browser?: Browser,\n existingPage?: Page,\n) {\n assert(target.url, 'url is required');\n const freeFn: FreeFn[] = [];\n\n // prepare the environment\n const ua = target.userAgent || defaultUA;\n let width = defaultViewportWidth;\n if (target.viewportWidth !== undefined && target.viewportWidth !== null) {\n assert(\n typeof target.viewportWidth === 'number',\n 'viewportWidth must be a number',\n );\n width = Number.parseInt(target.viewportWidth as unknown as string, 10);\n assert(width > 0, `viewportWidth must be greater than 0, but got ${width}`);\n }\n let height = defaultViewportHeight;\n if (target.viewportHeight !== undefined && target.viewportHeight !== null) {\n assert(\n typeof target.viewportHeight === 'number',\n 'viewportHeight must be a number',\n );\n height = Number.parseInt(target.viewportHeight as unknown as string, 10);\n assert(\n height > 0,\n `viewportHeight must be greater than 0, but got ${height}`,\n );\n }\n let dpr = defaultViewportScale;\n if (\n target.deviceScaleFactor !== undefined &&\n target.deviceScaleFactor !== null\n ) {\n assert(\n typeof target.deviceScaleFactor === 'number',\n 'deviceScaleFactor must be a number',\n );\n dpr = target.deviceScaleFactor;\n assert(dpr > 0, `deviceScaleFactor must be > 0, but got ${dpr}`);\n }\n const viewportConfig = {\n width,\n height,\n deviceScaleFactor: dpr,\n };\n\n const headed = preference?.headed || preference?.keepWindow;\n const defaultViewportConfig = headed ? null : viewportConfig;\n\n // launch the browser\n if (headed && process.env.CI === '1') {\n console.warn(\n 'you are probably running headed mode in CI, this will usually fail.',\n );\n }\n\n // Build Chrome arguments using the shared helper\n // Only pass windowSize in headed mode; in headless mode, defaultViewport takes precedence\n // Add 100px to height to account for browser UI (address bar, tabs, etc.)\n const browserUIHeight = 100;\n const args = buildChromeArgs({\n userAgent: ua,\n windowSize: headed\n ? { width, height: height + browserUIHeight }\n : undefined,\n chromeArgs: target.chromeArgs,\n });\n\n launcherDebug(\n 'launching browser with viewport, headed',\n headed,\n 'viewport',\n viewportConfig,\n 'args',\n args,\n 'preference',\n preference,\n );\n // If an existing page is provided, reuse it instead of creating a new one\n // This allows sharing localStorage and sessionStorage between YAML files\n let page: Page;\n let browserInstance = browser;\n\n if (existingPage) {\n // Reuse the existing page - this preserves localStorage and sessionStorage\n page = existingPage;\n launcherDebug('reusing existing page for shared browser context');\n\n // Get the browser instance from the existing page\n if (!browserInstance) {\n browserInstance = page.browser();\n }\n } else {\n // Create a new browser and page\n if (!browserInstance) {\n browserInstance = await puppeteer.launch({\n headless: !preference?.headed,\n defaultViewport: defaultViewportConfig,\n args,\n acceptInsecureCerts: target.acceptInsecureCerts,\n ignoreDefaultArgs: preference?.ignoreDefaultArgs,\n });\n freeFn.push({\n name: 'puppeteer_browser',\n fn: () => {\n if (!preference?.keepWindow) {\n if (process.platform === 'win32') {\n setTimeout(() => {\n browserInstance?.close();\n }, 800);\n } else {\n browserInstance?.close();\n }\n }\n },\n });\n }\n page = await browserInstance.newPage();\n }\n\n if (target.cookie) {\n const cookieFileContent = readFileSync(target.cookie, 'utf-8');\n await browserInstance.setCookie(...JSON.parse(cookieFileContent));\n }\n\n if (ua) {\n await page.setUserAgent(ua);\n }\n\n if (viewportConfig) {\n await page.setViewport(viewportConfig);\n }\n\n const waitForNetworkIdleTimeout =\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : defaultWaitForNetworkIdleTimeout;\n\n try {\n launcherDebug('goto', target.url);\n await page.goto(target.url);\n if (waitForNetworkIdleTimeout > 0) {\n launcherDebug('waitForNetworkIdle', waitForNetworkIdleTimeout);\n await page.waitForNetworkIdle({\n timeout: waitForNetworkIdleTimeout,\n });\n }\n } catch (e) {\n if (\n typeof target.waitForNetworkIdle?.continueOnNetworkIdleError ===\n 'boolean' &&\n !target.waitForNetworkIdle?.continueOnNetworkIdleError\n ) {\n const newError = new Error(`failed to wait for network idle: ${e}`, {\n cause: e,\n });\n throw newError;\n }\n const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;\n console.warn(newMessage);\n }\n\n return { page, freeFn };\n}\n\nexport async function puppeteerAgentForTarget(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n } & Partial<\n Pick<\n AgentOpt,\n | 'groupName'\n | 'groupDescription'\n | 'generateReport'\n | 'persistExecutionDump'\n | 'autoPrintReportMsg'\n | 'reportFileName'\n | 'replanningCycleLimit'\n | 'cache'\n | 'aiActionContext'\n >\n >,\n browser?: Browser,\n existingPage?: Page,\n) {\n const { page, freeFn } = await launchPuppeteerPage(\n target,\n preference,\n browser,\n existingPage,\n );\n const aiActContext = resolveAiActionContext(target, preference);\n\n const { aiActionContext, ...preferenceToUse } = preference ?? {};\n\n // prepare Midscene agent\n const agent = new PuppeteerAgent(page, {\n ...preferenceToUse,\n aiActContext,\n waitForNetworkIdleTimeout:\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : undefined,\n forceSameTabNavigation:\n typeof target.forceSameTabNavigation !== 'undefined'\n ? target.forceSameTabNavigation\n : true, // true for default in yaml script\n });\n\n freeFn.push({\n name: 'midscene_puppeteer_agent',\n fn: () => agent.destroy(),\n });\n\n return { agent, freeFn };\n}\n"],"names":["defaultUA","defaultViewportWidth","defaultViewportHeight","defaultViewportScale","defaultWaitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","resolveAiActionContext","target","preference","data","DANGEROUS_ARGS","validateChromeArgs","args","baseArgs","newArgs","arg","baseArg","argFlag","baseFlag","dangerousArgs","dangerous","console","launcherDebug","getDebug","buildChromeArgs","options","isWindows","process","sandboxArgs","featureArgs","userAgentArg","windowSizeArg","launchPuppeteerPage","browser","existingPage","assert","freeFn","ua","width","undefined","Number","height","dpr","viewportConfig","headed","defaultViewportConfig","browserUIHeight","page","browserInstance","puppeteer","setTimeout","cookieFileContent","readFileSync","JSON","waitForNetworkIdleTimeout","e","newError","Error","newMessage","puppeteerAgentForTarget","aiActContext","aiActionContext","preferenceToUse","agent","PuppeteerAgent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"puppeteer/agent-launcher.mjs","sources":["../../../src/puppeteer/agent-launcher.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nimport {\n defaultViewportHeight,\n defaultViewportWidth,\n resolveWebViewportSize,\n} from '@/common/viewport';\nimport { PuppeteerAgent } from '@/puppeteer/index';\nimport type { AgentOpt, Cache, MidsceneYamlScriptWebEnv } from '@midscene/core';\nimport { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from '@midscene/shared/constants';\nimport puppeteer, { type Browser, type Page } from 'puppeteer';\n\nexport { defaultViewportWidth, defaultViewportHeight } from '@/common/viewport';\n\nexport const defaultUA =\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36';\n// Setting deviceScaleFactor value to `0` means reset this value to the system default in Puppeteer.\nexport const defaultViewportScale = 0;\nexport const defaultWaitForNetworkIdleTimeout =\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n\nexport function resolveAiActionContext(\n target: MidsceneYamlScriptWebEnv,\n preference?: Partial<Pick<AgentOpt, 'aiActionContext' | 'aiActContext'>>,\n): AgentOpt['aiActionContext'] | undefined {\n // Prefer agent-level preference if provided; otherwise fall back to target-level context.\n // Priority: preference.aiActContext > preference.aiActionContext (deprecated) > target.aiActionContext\n const data =\n preference?.aiActContext ??\n preference?.aiActionContext ??\n target.aiActionContext;\n return data;\n}\n\n/**\n * Chrome arguments that may reduce browser security.\n * These should only be used in controlled testing environments.\n *\n * Security implications:\n * - `--no-sandbox`: Disables Chrome's sandbox security model\n * - `--disable-setuid-sandbox`: Disables setuid sandbox on Linux\n * - `--disable-web-security`: Allows cross-origin requests without CORS\n * - `--ignore-certificate-errors`: Ignores SSL/TLS certificate errors\n * - `--disable-features=IsolateOrigins`: Disables origin isolation\n * - `--disable-site-isolation-trials`: Disables site isolation\n * - `--allow-running-insecure-content`: Allows mixed HTTP/HTTPS content\n */\nconst DANGEROUS_ARGS = [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-web-security',\n '--ignore-certificate-errors',\n '--disable-features=IsolateOrigins',\n '--disable-site-isolation-trials',\n '--allow-running-insecure-content',\n] as const;\n\n/**\n * Validates Chrome launch arguments for security concerns.\n * Emits a warning if dangerous arguments are detected.\n *\n * This function filters out arguments that are already present in baseArgs\n * to avoid warning about platform-specific defaults (e.g., --no-sandbox on non-Windows).\n *\n * @param args - Chrome launch arguments to validate\n * @param baseArgs - Base Chrome arguments already configured\n *\n * @example\n * ```typescript\n * // Will show warning for --disable-web-security\n * validateChromeArgs(['--disable-web-security', '--headless'], ['--no-sandbox']);\n *\n * // Will NOT show warning for --no-sandbox (already in baseArgs)\n * validateChromeArgs(['--no-sandbox'], ['--no-sandbox', '--headless']);\n * ```\n */\nfunction validateChromeArgs(args: string[], baseArgs: string[]): void {\n // Filter out arguments that are already in baseArgs\n const newArgs = args.filter(\n (arg) =>\n !baseArgs.some((baseArg) => {\n // Check if arg starts with the same flag as baseArg (before '=' if present)\n const argFlag = arg.split('=')[0];\n const baseFlag = baseArg.split('=')[0];\n return argFlag === baseFlag;\n }),\n );\n\n const dangerousArgs = newArgs.filter((arg) =>\n DANGEROUS_ARGS.some((dangerous) => arg.startsWith(dangerous)),\n );\n\n if (dangerousArgs.length > 0) {\n console.warn(\n `Warning: Dangerous Chrome arguments detected: ${dangerousArgs.join(', ')}.\\nThese arguments may reduce browser security. Use only in controlled testing environments.`,\n );\n }\n}\n\ninterface FreeFn {\n name: string;\n fn: () => void;\n}\n\nconst launcherDebug = getDebug('puppeteer:launcher');\n\nexport interface BuildChromeArgsOptions {\n userAgent?: string;\n windowSize?: { width: number; height: number };\n chromeArgs?: string[];\n}\n\n/**\n * Builds Chrome launch arguments with sensible defaults.\n *\n * Platform-specific behavior:\n * - On non-Windows systems, automatically adds --no-sandbox and --disable-setuid-sandbox\n * for compatibility with containerized/CI environments\n *\n * @param options - Configuration options for Chrome arguments\n * @returns Array of Chrome launch arguments\n *\n * @example\n * ```typescript\n * // Basic usage\n * const args = buildChromeArgs();\n *\n * // With custom arguments\n * const args = buildChromeArgs({\n * chromeArgs: ['--disable-gpu', '--disable-dev-shm-usage'],\n * userAgent: 'CustomUA/1.0',\n * windowSize: { width: 1920, height: 1080 },\n * });\n * ```\n */\nexport function buildChromeArgs(options?: BuildChromeArgsOptions): string[] {\n const isWindows = process.platform === 'win32';\n\n const sandboxArgs = isWindows\n ? []\n : ['--no-sandbox', '--disable-setuid-sandbox'];\n const featureArgs = [\n '--disable-features=HttpsFirstBalancedModeAutoEnable',\n '--disable-features=PasswordLeakDetection',\n '--disable-save-password-bubble',\n ];\n const userAgentArg = options?.userAgent\n ? [`--user-agent=\"${options.userAgent}\"`]\n : [];\n const windowSizeArg = options?.windowSize\n ? [`--window-size=${options.windowSize.width},${options.windowSize.height}`]\n : [];\n\n const baseArgs = [\n ...sandboxArgs,\n ...featureArgs,\n ...userAgentArg,\n ...windowSizeArg,\n ];\n\n if (options?.chromeArgs?.length) {\n validateChromeArgs(options.chromeArgs, baseArgs);\n return [...baseArgs, ...options.chromeArgs];\n }\n\n return baseArgs;\n}\n\nexport async function launchPuppeteerPage(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n ignoreDefaultArgs?: boolean | string[];\n },\n browser?: Browser,\n existingPage?: Page,\n) {\n assert(target.url, 'url is required');\n const freeFn: FreeFn[] = [];\n\n // prepare the environment\n const ua = target.userAgent || defaultUA;\n const { width, height } = resolveWebViewportSize(target);\n let dpr = defaultViewportScale;\n if (\n target.deviceScaleFactor !== undefined &&\n target.deviceScaleFactor !== null\n ) {\n assert(\n typeof target.deviceScaleFactor === 'number',\n 'deviceScaleFactor must be a number',\n );\n dpr = target.deviceScaleFactor;\n assert(dpr > 0, `deviceScaleFactor must be > 0, but got ${dpr}`);\n }\n const viewportConfig = {\n width,\n height,\n deviceScaleFactor: dpr,\n };\n\n const headed = preference?.headed || preference?.keepWindow;\n const defaultViewportConfig = headed ? null : viewportConfig;\n\n // launch the browser\n if (headed && process.env.CI === '1') {\n console.warn(\n 'you are probably running headed mode in CI, this will usually fail.',\n );\n }\n\n // Build Chrome arguments using the shared helper\n // Only pass windowSize in headed mode; in headless mode, defaultViewport takes precedence\n // Add 100px to height to account for browser UI (address bar, tabs, etc.)\n const browserUIHeight = 100;\n const args = buildChromeArgs({\n userAgent: ua,\n windowSize: headed\n ? { width, height: height + browserUIHeight }\n : undefined,\n chromeArgs: target.chromeArgs,\n });\n\n launcherDebug(\n 'launching browser with viewport, headed',\n headed,\n 'viewport',\n viewportConfig,\n 'args',\n args,\n 'preference',\n preference,\n );\n // If an existing page is provided, reuse it instead of creating a new one\n // This allows sharing localStorage and sessionStorage between YAML files\n let page: Page;\n let browserInstance = browser;\n\n if (existingPage) {\n // Reuse the existing page - this preserves localStorage and sessionStorage\n page = existingPage;\n launcherDebug('reusing existing page for shared browser context');\n\n // Get the browser instance from the existing page\n if (!browserInstance) {\n browserInstance = page.browser();\n }\n } else {\n // Create a new browser and page\n if (!browserInstance) {\n browserInstance = await puppeteer.launch({\n headless: !preference?.headed,\n defaultViewport: defaultViewportConfig,\n args,\n acceptInsecureCerts: target.acceptInsecureCerts,\n ignoreDefaultArgs: preference?.ignoreDefaultArgs,\n });\n freeFn.push({\n name: 'puppeteer_browser',\n fn: () => {\n if (!preference?.keepWindow) {\n if (process.platform === 'win32') {\n setTimeout(() => {\n browserInstance?.close();\n }, 800);\n } else {\n browserInstance?.close();\n }\n }\n },\n });\n }\n page = await browserInstance.newPage();\n }\n\n if (target.cookie) {\n const cookieFileContent = readFileSync(target.cookie, 'utf-8');\n await browserInstance.setCookie(...JSON.parse(cookieFileContent));\n }\n\n if (ua) {\n await page.setUserAgent(ua);\n }\n\n if (viewportConfig) {\n await page.setViewport(viewportConfig);\n }\n\n const waitForNetworkIdleTimeout =\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : defaultWaitForNetworkIdleTimeout;\n\n try {\n launcherDebug('goto', target.url);\n await page.goto(target.url);\n if (waitForNetworkIdleTimeout > 0) {\n launcherDebug('waitForNetworkIdle', waitForNetworkIdleTimeout);\n await page.waitForNetworkIdle({\n timeout: waitForNetworkIdleTimeout,\n });\n }\n } catch (e) {\n if (\n typeof target.waitForNetworkIdle?.continueOnNetworkIdleError ===\n 'boolean' &&\n !target.waitForNetworkIdle?.continueOnNetworkIdleError\n ) {\n const newError = new Error(`failed to wait for network idle: ${e}`, {\n cause: e,\n });\n throw newError;\n }\n const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;\n console.warn(newMessage);\n }\n\n return { page, freeFn };\n}\n\nexport async function puppeteerAgentForTarget(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n } & Partial<\n Pick<\n AgentOpt,\n | 'groupName'\n | 'groupDescription'\n | 'generateReport'\n | 'persistExecutionDump'\n | 'autoPrintReportMsg'\n | 'reportFileName'\n | 'replanningCycleLimit'\n | 'cache'\n | 'aiActionContext'\n >\n >,\n browser?: Browser,\n existingPage?: Page,\n) {\n const { page, freeFn } = await launchPuppeteerPage(\n target,\n preference,\n browser,\n existingPage,\n );\n const aiActContext = resolveAiActionContext(target, preference);\n\n const { aiActionContext, ...preferenceToUse } = preference ?? {};\n\n // prepare Midscene agent\n const agent = new PuppeteerAgent(page, {\n ...preferenceToUse,\n aiActContext,\n waitForNetworkIdleTimeout:\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : undefined,\n forceSameTabNavigation:\n typeof target.forceSameTabNavigation !== 'undefined'\n ? target.forceSameTabNavigation\n : true, // true for default in yaml script\n });\n\n freeFn.push({\n name: 'midscene_puppeteer_agent',\n fn: () => agent.destroy(),\n });\n\n return { agent, freeFn };\n}\n"],"names":["defaultUA","defaultViewportScale","defaultWaitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","resolveAiActionContext","target","preference","data","DANGEROUS_ARGS","validateChromeArgs","args","baseArgs","newArgs","arg","baseArg","argFlag","baseFlag","dangerousArgs","dangerous","console","launcherDebug","getDebug","buildChromeArgs","options","isWindows","process","sandboxArgs","featureArgs","userAgentArg","windowSizeArg","launchPuppeteerPage","browser","existingPage","assert","freeFn","ua","width","height","resolveWebViewportSize","dpr","undefined","viewportConfig","headed","defaultViewportConfig","browserUIHeight","page","browserInstance","puppeteer","setTimeout","cookieFileContent","readFileSync","JSON","waitForNetworkIdleTimeout","e","newError","Error","newMessage","puppeteerAgentForTarget","aiActContext","aiActionContext","preferenceToUse","agent","PuppeteerAgent"],"mappings":"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"}
|
|
@@ -115,7 +115,7 @@ class BridgeServer {
|
|
|
115
115
|
(0, shared_utils_namespaceObject.logMsg)('one client connected');
|
|
116
116
|
this.socket = socket;
|
|
117
117
|
const clientVersion = socket.handshake.query.version;
|
|
118
|
-
(0, shared_utils_namespaceObject.logMsg)(`Bridge connected, cli-side version v1.7.
|
|
118
|
+
(0, shared_utils_namespaceObject.logMsg)(`Bridge connected, cli-side version v1.7.9, browser-side version v${clientVersion}`);
|
|
119
119
|
socket.on(external_common_js_namespaceObject.BridgeEvent.CallResponse, (params)=>{
|
|
120
120
|
const id = params.id;
|
|
121
121
|
const response = params.response;
|
|
@@ -139,7 +139,7 @@ class BridgeServer {
|
|
|
139
139
|
setTimeout(()=>{
|
|
140
140
|
this.onConnect?.();
|
|
141
141
|
const payload = {
|
|
142
|
-
version: "1.7.
|
|
142
|
+
version: "1.7.9"
|
|
143
143
|
};
|
|
144
144
|
socket.emit(external_common_js_namespaceObject.BridgeEvent.Connected, payload);
|
|
145
145
|
Promise.resolve().then(()=>{
|
|
@@ -103,7 +103,7 @@ class ExtensionBridgePageBrowserSide extends page_js_default() {
|
|
|
103
103
|
throw new Error('Connection denied by user');
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.7.
|
|
106
|
+
this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.7.9`, 'log');
|
|
107
107
|
}
|
|
108
108
|
async connect() {
|
|
109
109
|
return await this.setupBridgeClient();
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
parseWebCliOptions: ()=>parseWebCliOptions
|
|
28
|
+
});
|
|
29
|
+
const cli_namespaceObject = require("@midscene/shared/cli");
|
|
30
|
+
const viewport_js_namespaceObject = require("./common/viewport.js");
|
|
31
|
+
const viewportWidthFlag = '--viewport-width';
|
|
32
|
+
const viewportHeightFlag = '--viewport-height';
|
|
33
|
+
function isLikelyCdpEndpoint(value) {
|
|
34
|
+
return !!value && /^(wss?):\/\//.test(value);
|
|
35
|
+
}
|
|
36
|
+
function parsePositiveIntegerOption(flag, rawValue) {
|
|
37
|
+
const value = Number(rawValue);
|
|
38
|
+
if (!Number.isInteger(value) || value <= 0) throw new cli_namespaceObject.CLIError(`Invalid value for "${flag}": expected a positive integer, got "${rawValue}".`);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
function readRequiredOptionValue(args, index, flag) {
|
|
42
|
+
const currentArg = args[index];
|
|
43
|
+
const inlinePrefix = `${flag}=`;
|
|
44
|
+
if (currentArg.startsWith(inlinePrefix)) return {
|
|
45
|
+
value: currentArg.slice(inlinePrefix.length),
|
|
46
|
+
nextIndex: index
|
|
47
|
+
};
|
|
48
|
+
const nextArg = args[index + 1];
|
|
49
|
+
if (!nextArg || nextArg.startsWith('--')) throw new cli_namespaceObject.CLIError(`Option "${flag}" requires a value.`);
|
|
50
|
+
return {
|
|
51
|
+
value: nextArg,
|
|
52
|
+
nextIndex: index + 1
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function readOptionalCdpEndpoint(args, index) {
|
|
56
|
+
const currentArg = args[index];
|
|
57
|
+
const inlinePrefix = '--cdp=';
|
|
58
|
+
if (currentArg.startsWith(inlinePrefix)) return {
|
|
59
|
+
value: currentArg.slice(inlinePrefix.length),
|
|
60
|
+
nextIndex: index
|
|
61
|
+
};
|
|
62
|
+
const nextArg = args[index + 1];
|
|
63
|
+
if (!isLikelyCdpEndpoint(nextArg)) return {
|
|
64
|
+
nextIndex: index
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
value: nextArg,
|
|
68
|
+
nextIndex: index + 1
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function parseWebCliOptions(rawArgs, env = process.env) {
|
|
72
|
+
const argv = [];
|
|
73
|
+
let isBridge = false;
|
|
74
|
+
let isCdp = false;
|
|
75
|
+
let viewportWidth;
|
|
76
|
+
let viewportHeight;
|
|
77
|
+
let cdpEndpoint;
|
|
78
|
+
for(let index = 0; index < rawArgs.length; index += 1){
|
|
79
|
+
const arg = rawArgs[index];
|
|
80
|
+
if ('--bridge' === arg) {
|
|
81
|
+
isBridge = true;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if ('--cdp' === arg || arg.startsWith('--cdp=')) {
|
|
85
|
+
isCdp = true;
|
|
86
|
+
const parsed = readOptionalCdpEndpoint(rawArgs, index);
|
|
87
|
+
cdpEndpoint = parsed.value ?? cdpEndpoint;
|
|
88
|
+
index = parsed.nextIndex;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (arg === viewportWidthFlag || arg.startsWith(`${viewportWidthFlag}=`)) {
|
|
92
|
+
const parsed = readRequiredOptionValue(rawArgs, index, viewportWidthFlag);
|
|
93
|
+
viewportWidth = parsePositiveIntegerOption(viewportWidthFlag, parsed.value);
|
|
94
|
+
index = parsed.nextIndex;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (arg === viewportHeightFlag || arg.startsWith(`${viewportHeightFlag}=`)) {
|
|
98
|
+
const parsed = readRequiredOptionValue(rawArgs, index, viewportHeightFlag);
|
|
99
|
+
viewportHeight = parsePositiveIntegerOption(viewportHeightFlag, parsed.value);
|
|
100
|
+
index = parsed.nextIndex;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
argv.push(arg);
|
|
104
|
+
}
|
|
105
|
+
if (isBridge && isCdp) throw new cli_namespaceObject.CLIError('--bridge and --cdp are mutually exclusive. Please specify only one.');
|
|
106
|
+
const mode = isBridge ? 'bridge' : isCdp ? 'cdp' : 'puppeteer';
|
|
107
|
+
if ('puppeteer' !== mode) {
|
|
108
|
+
if (void 0 !== viewportWidth || void 0 !== viewportHeight) throw new cli_namespaceObject.CLIError('Viewport options are only supported in the default Puppeteer mode.');
|
|
109
|
+
}
|
|
110
|
+
if ('cdp' === mode) {
|
|
111
|
+
cdpEndpoint = cdpEndpoint ?? env.MIDSCENE_CDP_ENDPOINT;
|
|
112
|
+
if (!cdpEndpoint) throw new cli_namespaceObject.CLIError('CDP endpoint is required. Provide it as: --cdp <ws-endpoint> or set MIDSCENE_CDP_ENDPOINT environment variable.');
|
|
113
|
+
}
|
|
114
|
+
const hasViewportOverride = void 0 !== viewportWidth || void 0 !== viewportHeight;
|
|
115
|
+
return {
|
|
116
|
+
argv,
|
|
117
|
+
mode,
|
|
118
|
+
cdpEndpoint,
|
|
119
|
+
viewport: hasViewportOverride ? (0, viewport_js_namespaceObject.resolveViewportSize)({
|
|
120
|
+
width: viewportWidth,
|
|
121
|
+
height: viewportHeight
|
|
122
|
+
}, viewport_js_namespaceObject.defaultPuppeteerWindowViewportSize) : void 0
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
exports.parseWebCliOptions = __webpack_exports__.parseWebCliOptions;
|
|
126
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
127
|
+
"parseWebCliOptions"
|
|
128
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
129
|
+
Object.defineProperty(exports, '__esModule', {
|
|
130
|
+
value: true
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
//# sourceMappingURL=cli-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-options.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/cli-options.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { CLIError } from '@midscene/shared/cli';\nimport {\n type ViewportSize,\n defaultPuppeteerWindowViewportSize,\n resolveViewportSize,\n} from './common/viewport';\n\nconst viewportWidthFlag = '--viewport-width';\nconst viewportHeightFlag = '--viewport-height';\n\nexport interface ParsedWebCliOptions {\n argv: string[];\n mode: 'bridge' | 'cdp' | 'puppeteer';\n cdpEndpoint?: string;\n viewport?: ViewportSize;\n}\n\nfunction isLikelyCdpEndpoint(value: string | undefined): boolean {\n return !!value && /^(wss?):\\/\\//.test(value);\n}\n\nfunction parsePositiveIntegerOption(flag: string, rawValue: string): number {\n const value = Number(rawValue);\n if (!Number.isInteger(value) || value <= 0) {\n throw new CLIError(\n `Invalid value for \"${flag}\": expected a positive integer, got \"${rawValue}\".`,\n );\n }\n\n return value;\n}\n\nfunction readRequiredOptionValue(\n args: string[],\n index: number,\n flag: string,\n): { value: string; nextIndex: number } {\n const currentArg = args[index];\n const inlinePrefix = `${flag}=`;\n if (currentArg.startsWith(inlinePrefix)) {\n return {\n value: currentArg.slice(inlinePrefix.length),\n nextIndex: index,\n };\n }\n\n const nextArg = args[index + 1];\n if (!nextArg || nextArg.startsWith('--')) {\n throw new CLIError(`Option \"${flag}\" requires a value.`);\n }\n\n return {\n value: nextArg,\n nextIndex: index + 1,\n };\n}\n\nfunction readOptionalCdpEndpoint(\n args: string[],\n index: number,\n): { value?: string; nextIndex: number } {\n const currentArg = args[index];\n const inlinePrefix = '--cdp=';\n if (currentArg.startsWith(inlinePrefix)) {\n return {\n value: currentArg.slice(inlinePrefix.length),\n nextIndex: index,\n };\n }\n\n const nextArg = args[index + 1];\n if (!isLikelyCdpEndpoint(nextArg)) {\n return { nextIndex: index };\n }\n\n return {\n value: nextArg,\n nextIndex: index + 1,\n };\n}\n\nexport function parseWebCliOptions(\n rawArgs: string[],\n env: NodeJS.ProcessEnv = process.env,\n): ParsedWebCliOptions {\n const argv: string[] = [];\n let isBridge = false;\n let isCdp = false;\n let viewportWidth: number | undefined;\n let viewportHeight: number | undefined;\n let cdpEndpoint: string | undefined;\n\n for (let index = 0; index < rawArgs.length; index += 1) {\n const arg = rawArgs[index];\n\n if (arg === '--bridge') {\n isBridge = true;\n continue;\n }\n\n if (arg === '--cdp' || arg.startsWith('--cdp=')) {\n isCdp = true;\n const parsed = readOptionalCdpEndpoint(rawArgs, index);\n cdpEndpoint = parsed.value ?? cdpEndpoint;\n index = parsed.nextIndex;\n continue;\n }\n\n if (arg === viewportWidthFlag || arg.startsWith(`${viewportWidthFlag}=`)) {\n const parsed = readRequiredOptionValue(rawArgs, index, viewportWidthFlag);\n viewportWidth = parsePositiveIntegerOption(\n viewportWidthFlag,\n parsed.value,\n );\n index = parsed.nextIndex;\n continue;\n }\n\n if (\n arg === viewportHeightFlag ||\n arg.startsWith(`${viewportHeightFlag}=`)\n ) {\n const parsed = readRequiredOptionValue(\n rawArgs,\n index,\n viewportHeightFlag,\n );\n viewportHeight = parsePositiveIntegerOption(\n viewportHeightFlag,\n parsed.value,\n );\n index = parsed.nextIndex;\n continue;\n }\n\n argv.push(arg);\n }\n\n if (isBridge && isCdp) {\n throw new CLIError(\n '--bridge and --cdp are mutually exclusive. Please specify only one.',\n );\n }\n\n const mode = isBridge ? 'bridge' : isCdp ? 'cdp' : 'puppeteer';\n\n if (mode !== 'puppeteer') {\n if (viewportWidth !== undefined || viewportHeight !== undefined) {\n throw new CLIError(\n 'Viewport options are only supported in the default Puppeteer mode.',\n );\n }\n }\n\n if (mode === 'cdp') {\n cdpEndpoint = cdpEndpoint ?? env.MIDSCENE_CDP_ENDPOINT;\n if (!cdpEndpoint) {\n throw new CLIError(\n 'CDP endpoint is required. Provide it as: --cdp <ws-endpoint> or set MIDSCENE_CDP_ENDPOINT environment variable.',\n );\n }\n }\n\n const hasViewportOverride =\n viewportWidth !== undefined || viewportHeight !== undefined;\n\n return {\n argv,\n mode,\n cdpEndpoint,\n viewport: hasViewportOverride\n ? resolveViewportSize(\n {\n width: viewportWidth,\n height: viewportHeight,\n },\n defaultPuppeteerWindowViewportSize,\n )\n : undefined,\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","viewportWidthFlag","viewportHeightFlag","isLikelyCdpEndpoint","value","parsePositiveIntegerOption","flag","rawValue","Number","CLIError","readRequiredOptionValue","args","index","currentArg","inlinePrefix","nextArg","readOptionalCdpEndpoint","parseWebCliOptions","rawArgs","env","process","argv","isBridge","isCdp","viewportWidth","viewportHeight","cdpEndpoint","arg","parsed","mode","undefined","hasViewportOverride","resolveViewportSize","defaultPuppeteerWindowViewportSize"],"mappings":"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"}
|
package/dist/lib/cli.js
CHANGED
|
@@ -27,6 +27,7 @@ const core_namespaceObject = require("@midscene/core");
|
|
|
27
27
|
const cli_namespaceObject = require("@midscene/shared/cli");
|
|
28
28
|
const external_dotenv_namespaceObject = require("dotenv");
|
|
29
29
|
var external_dotenv_default = /*#__PURE__*/ __webpack_require__.n(external_dotenv_namespaceObject);
|
|
30
|
+
const external_cli_options_js_namespaceObject = require("./cli-options.js");
|
|
30
31
|
const external_mcp_tools_js_namespaceObject = require("./mcp-tools.js");
|
|
31
32
|
const external_mcp_tools_cdp_js_namespaceObject = require("./mcp-tools-cdp.js");
|
|
32
33
|
const external_mcp_tools_puppeteer_js_namespaceObject = require("./mcp-tools-puppeteer.js");
|
|
@@ -34,38 +35,16 @@ const envFile = (0, external_node_path_namespaceObject.join)(process.cwd(), '.en
|
|
|
34
35
|
if ((0, external_node_fs_namespaceObject.existsSync)(envFile)) external_dotenv_default().config({
|
|
35
36
|
path: envFile
|
|
36
37
|
});
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (next && !next.startsWith('-')) cdpEndpoint = next;
|
|
48
|
-
if (!cdpEndpoint) cdpEndpoint = process.env.MIDSCENE_CDP_ENDPOINT;
|
|
49
|
-
if (!cdpEndpoint) {
|
|
50
|
-
console.error('CDP endpoint is required. Provide it as: --cdp <ws-endpoint> or set MIDSCENE_CDP_ENDPOINT environment variable.');
|
|
51
|
-
process.exit(1);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
const bridgeIdx = process.argv.indexOf('--bridge');
|
|
55
|
-
const cdpValueIdx = -1 !== cdpIdx && cdpIdx + 1 < process.argv.length && !process.argv[cdpIdx + 1].startsWith('-') ? cdpIdx + 1 : -1;
|
|
56
|
-
const skipIndices = new Set([
|
|
57
|
-
bridgeIdx,
|
|
58
|
-
cdpIdx,
|
|
59
|
-
cdpValueIdx
|
|
60
|
-
].filter((i)=>-1 !== i));
|
|
61
|
-
const argv = process.argv.slice(2).filter((_, idx)=>!skipIndices.has(idx + 2));
|
|
62
|
-
let tools;
|
|
63
|
-
tools = isBridge ? new external_mcp_tools_js_namespaceObject.WebMidsceneTools() : isCdp ? new external_mcp_tools_cdp_js_namespaceObject.WebCdpMidsceneTools(cdpEndpoint) : new external_mcp_tools_puppeteer_js_namespaceObject.WebPuppeteerMidsceneTools();
|
|
64
|
-
(0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-web', {
|
|
65
|
-
stripPrefix: 'web_',
|
|
66
|
-
argv,
|
|
67
|
-
version: "1.7.7",
|
|
68
|
-
extraCommands: (0, core_namespaceObject.createReportCliCommands)()
|
|
38
|
+
Promise.resolve().then(()=>{
|
|
39
|
+
const parsedOptions = (0, external_cli_options_js_namespaceObject.parseWebCliOptions)(process.argv.slice(2));
|
|
40
|
+
let tools;
|
|
41
|
+
tools = 'bridge' === parsedOptions.mode ? new external_mcp_tools_js_namespaceObject.WebMidsceneTools() : 'cdp' === parsedOptions.mode ? new external_mcp_tools_cdp_js_namespaceObject.WebCdpMidsceneTools(parsedOptions.cdpEndpoint) : new external_mcp_tools_puppeteer_js_namespaceObject.WebPuppeteerMidsceneTools(parsedOptions.viewport);
|
|
42
|
+
return (0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-web', {
|
|
43
|
+
stripPrefix: 'web_',
|
|
44
|
+
argv: parsedOptions.argv,
|
|
45
|
+
version: "1.7.9",
|
|
46
|
+
extraCommands: (0, core_namespaceObject.createReportCliCommands)()
|
|
47
|
+
});
|
|
69
48
|
}).catch((e)=>{
|
|
70
49
|
process.exit((0, cli_namespaceObject.reportCLIError)(e));
|
|
71
50
|
});
|
package/dist/lib/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","../../src/cli.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createReportCliCommands } from '@midscene/core';\nimport { reportCLIError, runToolsCLI } from '@midscene/shared/cli';\nimport dotenv from 'dotenv';\nimport { WebMidsceneTools } from './mcp-tools';\nimport { WebCdpMidsceneTools } from './mcp-tools-cdp';\nimport { WebPuppeteerMidsceneTools } from './mcp-tools-puppeteer';\n\n// Load .env early so MIDSCENE_CDP_ENDPOINT is available during arg parsing\nconst envFile = join(process.cwd(), '.env');\nif (existsSync(envFile)) {\n dotenv.config({ path: envFile });\n}\n\ndeclare const __VERSION__: string;\
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","../../src/cli.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createReportCliCommands } from '@midscene/core';\nimport { reportCLIError, runToolsCLI } from '@midscene/shared/cli';\nimport dotenv from 'dotenv';\nimport { parseWebCliOptions } from './cli-options';\nimport { WebMidsceneTools } from './mcp-tools';\nimport { WebCdpMidsceneTools } from './mcp-tools-cdp';\nimport { WebPuppeteerMidsceneTools } from './mcp-tools-puppeteer';\n\n// Load .env early so MIDSCENE_CDP_ENDPOINT is available during arg parsing\nconst envFile = join(process.cwd(), '.env');\nif (existsSync(envFile)) {\n dotenv.config({ path: envFile });\n}\n\ndeclare const __VERSION__: string;\n\nPromise.resolve()\n .then(() => {\n const parsedOptions = parseWebCliOptions(process.argv.slice(2));\n\n let tools:\n | WebMidsceneTools\n | WebPuppeteerMidsceneTools\n | WebCdpMidsceneTools;\n if (parsedOptions.mode === 'bridge') {\n tools = new WebMidsceneTools();\n } else if (parsedOptions.mode === 'cdp') {\n tools = new WebCdpMidsceneTools(parsedOptions.cdpEndpoint!);\n } else {\n tools = new WebPuppeteerMidsceneTools(parsedOptions.viewport);\n }\n\n return runToolsCLI(tools, 'midscene-web', {\n stripPrefix: 'web_',\n argv: parsedOptions.argv,\n version: __VERSION__,\n extraCommands: createReportCliCommands(),\n });\n })\n .catch((e) => {\n process.exit(reportCLIError(e));\n });\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","envFile","join","process","existsSync","dotenv","Promise","parsedOptions","parseWebCliOptions","tools","WebMidsceneTools","WebCdpMidsceneTools","WebPuppeteerMidsceneTools","runToolsCLI","__VERSION__","createReportCliCommands","e","reportCLIError"],"mappings":";;;IACAA,oBAAoB,CAAC,GAAG,CAACC;QACxB,IAAIC,SAASD,UAAUA,OAAO,UAAU,GACvC,IAAOA,MAAM,CAAC,UAAU,GACxB,IAAOA;QACRD,oBAAoB,CAAC,CAACE,QAAQ;YAAE,GAAGA;QAAO;QAC1C,OAAOA;IACR;;;ICPAF,oBAAoB,CAAC,GAAG,CAAC,UAASG;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGH,oBAAoB,CAAC,CAACG,YAAYC,QAAQ,CAACJ,oBAAoB,CAAC,CAAC,UAASI,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAJ,oBAAoB,CAAC,GAAG,CAACM,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;;;;;;;;;;;ACWlF,MAAMC,UAAUC,AAAAA,IAAAA,mCAAAA,IAAAA,AAAAA,EAAKC,QAAQ,GAAG,IAAI;AACpC,IAAIC,AAAAA,IAAAA,iCAAAA,UAAAA,AAAAA,EAAWH,UACbI,0BAAAA,MAAa,CAAC;IAAE,MAAMJ;AAAQ;AAKhCK,QAAQ,OAAO,GACZ,IAAI,CAAC;IACJ,MAAMC,gBAAgBC,AAAAA,IAAAA,wCAAAA,kBAAAA,AAAAA,EAAmBL,QAAQ,IAAI,CAAC,KAAK,CAAC;IAE5D,IAAIM;IAKFA,QADEF,AAAuB,aAAvBA,cAAc,IAAI,GACZ,IAAIG,sCAAAA,gBAAgBA,KACnBH,AAAuB,UAAvBA,cAAc,IAAI,GACnB,IAAII,0CAAAA,mBAAmBA,CAACJ,cAAc,WAAW,IAEjD,IAAIK,gDAAAA,yBAAyBA,CAACL,cAAc,QAAQ;IAG9D,OAAOM,AAAAA,IAAAA,oBAAAA,WAAAA,AAAAA,EAAYJ,OAAO,gBAAgB;QACxC,aAAa;QACb,MAAMF,cAAc,IAAI;QACxB,SAASO;QACT,eAAeC,AAAAA,IAAAA,qBAAAA,uBAAAA,AAAAA;IACjB;AACF,GACC,KAAK,CAAC,CAACC;IACNb,QAAQ,IAAI,CAACc,AAAAA,IAAAA,oBAAAA,cAAAA,AAAAA,EAAeD;AAC9B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
defaultViewportSize: ()=>defaultViewportSize,
|
|
28
|
+
defaultStaticPageViewportSize: ()=>defaultStaticPageViewportSize,
|
|
29
|
+
defaultViewportWidth: ()=>defaultViewportWidth,
|
|
30
|
+
resolveViewportSize: ()=>resolveViewportSize,
|
|
31
|
+
resolveWebViewportSize: ()=>resolveWebViewportSize,
|
|
32
|
+
defaultPuppeteerWindowViewportSize: ()=>defaultPuppeteerWindowViewportSize,
|
|
33
|
+
defaultViewportHeight: ()=>defaultViewportHeight
|
|
34
|
+
});
|
|
35
|
+
const utils_namespaceObject = require("@midscene/shared/utils");
|
|
36
|
+
const defaultViewportWidth = 1440;
|
|
37
|
+
const defaultViewportHeight = 800;
|
|
38
|
+
const defaultViewportSize = {
|
|
39
|
+
width: defaultViewportWidth,
|
|
40
|
+
height: defaultViewportHeight
|
|
41
|
+
};
|
|
42
|
+
const defaultPuppeteerWindowViewportSize = {
|
|
43
|
+
width: defaultViewportWidth,
|
|
44
|
+
height: defaultViewportHeight
|
|
45
|
+
};
|
|
46
|
+
const defaultStaticPageViewportSize = {
|
|
47
|
+
width: defaultViewportWidth,
|
|
48
|
+
height: defaultViewportHeight
|
|
49
|
+
};
|
|
50
|
+
function parseViewportDimension(rawValue, name) {
|
|
51
|
+
const parsedValue = 'number' == typeof rawValue ? rawValue : Number(rawValue);
|
|
52
|
+
(0, utils_namespaceObject.assert)(Number.isInteger(parsedValue), `${name} must be a positive integer, but got ${rawValue}`);
|
|
53
|
+
(0, utils_namespaceObject.assert)(parsedValue > 0, `${name} must be greater than 0, but got ${rawValue}`);
|
|
54
|
+
return parsedValue;
|
|
55
|
+
}
|
|
56
|
+
function resolveViewportSize(viewport, fallback = defaultViewportSize) {
|
|
57
|
+
const width = viewport?.width === void 0 || null === viewport.width ? fallback.width : parseViewportDimension(viewport.width, 'viewportWidth');
|
|
58
|
+
const height = viewport?.height === void 0 || null === viewport.height ? fallback.height : parseViewportDimension(viewport.height, 'viewportHeight');
|
|
59
|
+
return {
|
|
60
|
+
width,
|
|
61
|
+
height
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function resolveWebViewportSize(viewport, fallback = defaultViewportSize) {
|
|
65
|
+
return resolveViewportSize({
|
|
66
|
+
width: viewport?.viewportWidth,
|
|
67
|
+
height: viewport?.viewportHeight
|
|
68
|
+
}, fallback);
|
|
69
|
+
}
|
|
70
|
+
exports.defaultPuppeteerWindowViewportSize = __webpack_exports__.defaultPuppeteerWindowViewportSize;
|
|
71
|
+
exports.defaultStaticPageViewportSize = __webpack_exports__.defaultStaticPageViewportSize;
|
|
72
|
+
exports.defaultViewportHeight = __webpack_exports__.defaultViewportHeight;
|
|
73
|
+
exports.defaultViewportSize = __webpack_exports__.defaultViewportSize;
|
|
74
|
+
exports.defaultViewportWidth = __webpack_exports__.defaultViewportWidth;
|
|
75
|
+
exports.resolveViewportSize = __webpack_exports__.resolveViewportSize;
|
|
76
|
+
exports.resolveWebViewportSize = __webpack_exports__.resolveWebViewportSize;
|
|
77
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
78
|
+
"defaultPuppeteerWindowViewportSize",
|
|
79
|
+
"defaultStaticPageViewportSize",
|
|
80
|
+
"defaultViewportHeight",
|
|
81
|
+
"defaultViewportSize",
|
|
82
|
+
"defaultViewportWidth",
|
|
83
|
+
"resolveViewportSize",
|
|
84
|
+
"resolveWebViewportSize"
|
|
85
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
86
|
+
Object.defineProperty(exports, '__esModule', {
|
|
87
|
+
value: true
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=viewport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common/viewport.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/common/viewport.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { assert } from '@midscene/shared/utils';\n\nexport interface ViewportSize {\n width: number;\n height: number;\n}\n\nexport const defaultViewportWidth = 1440;\nexport const defaultViewportHeight = 800;\nexport const defaultViewportSize: ViewportSize = {\n width: defaultViewportWidth,\n height: defaultViewportHeight,\n};\nexport const defaultPuppeteerWindowViewportSize: ViewportSize = {\n width: defaultViewportWidth,\n height: defaultViewportHeight,\n};\nexport const defaultStaticPageViewportSize: ViewportSize = {\n width: defaultViewportWidth,\n height: defaultViewportHeight,\n};\n\nfunction parseViewportDimension(\n rawValue: number | string,\n name: 'viewportWidth' | 'viewportHeight',\n): number {\n const parsedValue =\n typeof rawValue === 'number' ? rawValue : Number(rawValue);\n\n assert(\n Number.isInteger(parsedValue),\n `${name} must be a positive integer, but got ${rawValue}`,\n );\n assert(\n parsedValue > 0,\n `${name} must be greater than 0, but got ${rawValue}`,\n );\n\n return parsedValue;\n}\n\nexport function resolveViewportSize(\n viewport?: {\n width?: number | string | null;\n height?: number | string | null;\n },\n fallback: ViewportSize = defaultViewportSize,\n): ViewportSize {\n const width =\n viewport?.width === undefined || viewport.width === null\n ? fallback.width\n : parseViewportDimension(viewport.width, 'viewportWidth');\n const height =\n viewport?.height === undefined || viewport.height === null\n ? fallback.height\n : parseViewportDimension(viewport.height, 'viewportHeight');\n\n return { width, height };\n}\n\nexport function resolveWebViewportSize(\n viewport?: {\n viewportWidth?: number | string | null;\n viewportHeight?: number | string | null;\n },\n fallback: ViewportSize = defaultViewportSize,\n): ViewportSize {\n return resolveViewportSize(\n {\n width: viewport?.viewportWidth,\n height: viewport?.viewportHeight,\n },\n fallback,\n );\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","defaultViewportWidth","defaultViewportHeight","defaultViewportSize","defaultPuppeteerWindowViewportSize","defaultStaticPageViewportSize","parseViewportDimension","rawValue","name","parsedValue","Number","assert","resolveViewportSize","viewport","fallback","width","undefined","height","resolveWebViewportSize"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;;;ACCO,MAAMI,uBAAuB;AAC7B,MAAMC,wBAAwB;AAC9B,MAAMC,sBAAoC;IAC/C,OAAOF;IACP,QAAQC;AACV;AACO,MAAME,qCAAmD;IAC9D,OAAOH;IACP,QAAQC;AACV;AACO,MAAMG,gCAA8C;IACzD,OAAOJ;IACP,QAAQC;AACV;AAEA,SAASI,uBACPC,QAAyB,EACzBC,IAAwC;IAExC,MAAMC,cACJ,AAAoB,YAApB,OAAOF,WAAwBA,WAAWG,OAAOH;IAEnDI,IAAAA,sBAAAA,MAAAA,AAAAA,EACED,OAAO,SAAS,CAACD,cACjB,GAAGD,KAAK,qCAAqC,EAAED,UAAU;IAE3DI,IAAAA,sBAAAA,MAAAA,AAAAA,EACEF,cAAc,GACd,GAAGD,KAAK,iCAAiC,EAAED,UAAU;IAGvD,OAAOE;AACT;AAEO,SAASG,oBACdC,QAGC,EACDC,WAAyBX,mBAAmB;IAE5C,MAAMY,QACJF,UAAU,UAAUG,UAAaH,AAAmB,SAAnBA,SAAS,KAAK,GAC3CC,SAAS,KAAK,GACdR,uBAAuBO,SAAS,KAAK,EAAE;IAC7C,MAAMI,SACJJ,UAAU,WAAWG,UAAaH,AAAoB,SAApBA,SAAS,MAAM,GAC7CC,SAAS,MAAM,GACfR,uBAAuBO,SAAS,MAAM,EAAE;IAE9C,OAAO;QAAEE;QAAOE;IAAO;AACzB;AAEO,SAASC,uBACdL,QAGC,EACDC,WAAyBX,mBAAmB;IAE5C,OAAOS,oBACL;QACE,OAAOC,UAAU;QACjB,QAAQA,UAAU;IACpB,GACAC;AAEJ"}
|
package/dist/lib/mcp-server.js
CHANGED
|
@@ -37,7 +37,7 @@ class WebMCPServer extends mcp_namespaceObject.BaseMCPServer {
|
|
|
37
37
|
constructor(toolsManager){
|
|
38
38
|
super({
|
|
39
39
|
name: '@midscene/web-bridge-mcp',
|
|
40
|
-
version: "1.7.
|
|
40
|
+
version: "1.7.9",
|
|
41
41
|
description: 'Control the browser using natural language commands'
|
|
42
42
|
}, toolsManager);
|
|
43
43
|
}
|
|
@@ -42,6 +42,7 @@ const external_puppeteer_core_namespaceObject = require("puppeteer-core");
|
|
|
42
42
|
var external_puppeteer_core_default = /*#__PURE__*/ __webpack_require__.n(external_puppeteer_core_namespaceObject);
|
|
43
43
|
const external_cdp_proxy_manager_js_namespaceObject = require("./cdp-proxy-manager.js");
|
|
44
44
|
const external_cdp_target_store_js_namespaceObject = require("./cdp-target-store.js");
|
|
45
|
+
const viewport_js_namespaceObject = require("./common/viewport.js");
|
|
45
46
|
const index_js_namespaceObject = require("./puppeteer/index.js");
|
|
46
47
|
const external_static_index_js_namespaceObject = require("./static/index.js");
|
|
47
48
|
function _define_property(obj, key, value) {
|
|
@@ -66,10 +67,7 @@ class WebCdpMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools {
|
|
|
66
67
|
createTemporaryDevice() {
|
|
67
68
|
return new external_static_index_js_namespaceObject.StaticPage({
|
|
68
69
|
screenshot: core_namespaceObject.ScreenshotItem.create('', Date.now()),
|
|
69
|
-
shotSize:
|
|
70
|
-
width: 1920,
|
|
71
|
-
height: 1080
|
|
72
|
-
},
|
|
70
|
+
shotSize: viewport_js_namespaceObject.defaultStaticPageViewportSize,
|
|
73
71
|
shrunkShotToLogicalRatio: 1
|
|
74
72
|
});
|
|
75
73
|
}
|