@mearl/client 2.9.6 → 2.11.0
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/README.md +4 -2
- package/dist/check.d.ts +11 -1
- package/dist/check.js +23 -15
- package/dist/commands.d.ts +34 -31
- package/dist/commands.js +51 -34
- package/dist/generated-browser-action-protocol.d.ts +31 -13
- package/dist/generated-browser-action-protocol.js +14 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/socket.js +3 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -69,7 +69,9 @@ mearl browser_launch --payload '{"name":"account-b","query":"test_account"}'
|
|
|
69
69
|
mearl browser_launch --payload '{"name":"cookie-copy","copyCookieDomains":["example.com"]}'
|
|
70
70
|
mearl browser_launch --payload '{"name":"cloud-login","provider":"agentbay","persistent":true,"userAgentMode":"desktop","copyCookieDomains":["example.com"],"url":"https://example.com/account"}'
|
|
71
71
|
mearl browser_launch --browser '<控制浏览器 browserId>' --payload '{"name":"cloud-login","provider":"agentbay","reuse":"require","copyCookieDomains":["example.com"]}'
|
|
72
|
+
mearl browser_launch --browser '<本地来源 browserId>' --payload '{"sessionId":"<其他设备创建的 AgentBay sessionId>","copyCookieDomains":["example.com"]}'
|
|
72
73
|
mearl browser_launch --payload '{"name":"cloud-tools","provider":"agentbay","copyCookieDomains":"mearl-services"}'
|
|
74
|
+
mearl browser_launch --payload '{"name":"cloud-tools-plus","provider":"agentbay","copyCookieDomains":{"presets":["mearl-services"],"domains":["figma.com"]}}'
|
|
73
75
|
mearl browser_launch --payload '{"name":"figma","userAgentMode":"desktop","copyCookieDomains":["figma.com"]}'
|
|
74
76
|
mearl browser_list
|
|
75
77
|
mearl browser_release
|
|
@@ -120,9 +122,9 @@ mearl browser_release
|
|
|
120
122
|
|
|
121
123
|
`browser_list` 统一列出普通浏览器和托管浏览器。`type` 区分 `regular` / `managed`,`status` 区分 `connected` / `running_disconnected` / `stopped`;只有 `connected` 的浏览器可作为操作目标。
|
|
122
124
|
|
|
123
|
-
`browser_release`
|
|
125
|
+
按 `sessionId` 接入的 AgentBay 浏览器用 `browser_release` 收尾:它会移除本机 attachment 并退出对应宿主,但不会关闭云端 Session。其他浏览器仅在用户明确要求结束调试、退出接管或清理会话资源时调用;它会释放 debugger/CDP 控制和会话级临时状态(包括设备/时区模拟),保留浏览器及全部标签页,后续浏览器操作可自动重新建立控制。
|
|
124
126
|
|
|
125
|
-
托管浏览器使用独立 Profile。控制浏览器需先登录 TDBank;生成的 SSO 地址在本地内部传递,本地实例可以使用 `headless: true`(默认)完成测试账号登录。AgentBay 固定为非 headless,传 `headless: true` 会被拒绝;`imageId` 可指定镜像别名或具体镜像 ID,省略时使用已验证的 Linux Browser Use 内网镜像。`persistent: true` 会让本地实例保留 Profile,让 AgentBay 同名实例绑定稳定的云端 Browser Context;正常关闭时同步 Cookie、LocalStorage、IndexedDB 等状态,下次启动无需再次复制本地登录态。`deleteProfile: true` 会显式删除对应 Profile 或 Context。AgentBay 的 `reuse` 支持 `never`(默认)、`prefer` 和 `require`:`prefer` 存在运行实例时复用、否则创建,`require`
|
|
127
|
+
托管浏览器使用独立 Profile。控制浏览器需先登录 TDBank;生成的 SSO 地址在本地内部传递,本地实例可以使用 `headless: true`(默认)完成测试账号登录。AgentBay 固定为非 headless,传 `headless: true` 会被拒绝;`imageId` 可指定镜像别名或具体镜像 ID,省略时使用已验证的 Linux Browser Use 内网镜像。`persistent: true` 会让本地实例保留 Profile,让 AgentBay 同名实例绑定稳定的云端 Browser Context;正常关闭时同步 Cookie、LocalStorage、IndexedDB 等状态,下次启动无需再次复制本地登录态。`deleteProfile: true` 会显式删除对应 Profile 或 Context。AgentBay 的 `reuse` 支持 `never`(默认)、`prefer` 和 `require`:`prefer` 存在运行实例时复用、否则创建,`require` 只复用且不会意外创建计费会话。另一台设备已知确切 Session 时,可传 `sessionId` 直接通过 AgentBay CDP 接入,不需要 cloud-server;当前设备需配置能访问该 Session 的 `AGENTBAY_KEY`。provider-local ID 为 `managed:agentbay:session:<sessionId>`,跨 CLI 调用使用启动响应中的全局 `browserId`,且本机只持有 attachment。`copyCookieDomains` 传数组时复制指定域,传 `"mearl-services"` 时同步 Mearl 依赖平台登录态;需要同时复制基础登录态和额外站点时传 `{ "presets": ["mearl-services"], "domains": [...] }`。Cookie 值不会经过 cloud-server,也不会出现在命令结果或日志中;`userAgentMode: "desktop"` 让本地实例使用匹配本机 Chrome 版本的桌面 UA,AgentBay 则复用当前控制浏览器的桌面 UA。`browser_list` 仅返回浏览器的稳定配置,不携带 AgentBay 串流入口或沙箱 noVNC 地址。需要时显式运行 `mearl check --browser <id|名称>`,由统一的浏览器访问入口能力实时返回 `browserAccess`;AgentBay、OpenSandbox 和 AONE Sandbox 地址都应按敏感信息处理。完整设计见 [托管浏览器与 TDBank 多账号设计](../../docs/managed-browsers.md)。
|
|
126
128
|
|
|
127
129
|
## 架构
|
|
128
130
|
|
package/dist/check.d.ts
CHANGED
|
@@ -5,6 +5,16 @@ export interface UnifiedCheckVersions {
|
|
|
5
5
|
extension?: string | null;
|
|
6
6
|
browser?: string | null;
|
|
7
7
|
}
|
|
8
|
+
export type BrowserAccessCapability = {
|
|
9
|
+
kind: 'agentbay';
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'sandbox-novnc';
|
|
12
|
+
environment: 'opensandbox' | 'aone';
|
|
13
|
+
port: number;
|
|
14
|
+
};
|
|
15
|
+
export type BrowserAccess = BrowserAccessCapability & {
|
|
16
|
+
url: string;
|
|
17
|
+
};
|
|
8
18
|
interface BrowserInfo {
|
|
9
19
|
browserId: string;
|
|
10
20
|
extensionVersion?: string;
|
|
@@ -27,7 +37,7 @@ export interface ExtensionInstallationInfo {
|
|
|
27
37
|
setupManagedPath: string | null;
|
|
28
38
|
}
|
|
29
39
|
export interface UnifiedCheckBrowserResult extends BrowserInfo {
|
|
30
|
-
|
|
40
|
+
browserAccess?: BrowserAccess;
|
|
31
41
|
check?: {
|
|
32
42
|
errors?: string[];
|
|
33
43
|
label: string;
|
package/dist/check.js
CHANGED
|
@@ -2,6 +2,20 @@ import { UnifiedClient, normalizeBrowserSelector, } from './unified.js';
|
|
|
2
2
|
function formatError(error) {
|
|
3
3
|
return error instanceof Error ? error.message : String(error);
|
|
4
4
|
}
|
|
5
|
+
function browserAccessLabel(access) {
|
|
6
|
+
if (access.kind === 'agentbay')
|
|
7
|
+
return 'AgentBay, temporary';
|
|
8
|
+
return access.environment === 'opensandbox' ? 'OpenSandbox noVNC' : 'AONE Sandbox noVNC';
|
|
9
|
+
}
|
|
10
|
+
async function getBrowserAccess(client, browser, capability, timeoutSec) {
|
|
11
|
+
const result = (await client.invoke('get_browser_access_url', {}, { timeoutSec, browser: browser.browserId }));
|
|
12
|
+
if (!result.browserAccess?.url)
|
|
13
|
+
throw new Error('Browser host did not return an access URL');
|
|
14
|
+
if (result.browserAccess.kind !== capability.kind) {
|
|
15
|
+
throw new Error('Browser host returned an unexpected access URL type');
|
|
16
|
+
}
|
|
17
|
+
return result.browserAccess;
|
|
18
|
+
}
|
|
5
19
|
function redactServerUrl(serverUrl) {
|
|
6
20
|
try {
|
|
7
21
|
const parsed = new URL(serverUrl);
|
|
@@ -223,33 +237,27 @@ export async function runUnifiedCheck(options, dependencies = {}) {
|
|
|
223
237
|
setupManagedPath: versions.setupManagedPath,
|
|
224
238
|
};
|
|
225
239
|
}
|
|
226
|
-
let
|
|
240
|
+
let browserAccess;
|
|
227
241
|
let accessUrlWarning;
|
|
228
|
-
|
|
242
|
+
const browserAccessCapability = versions.browserAccess;
|
|
243
|
+
if (browserAccessCapability && options.browser) {
|
|
229
244
|
try {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
browser: browser.browserId,
|
|
233
|
-
}));
|
|
234
|
-
if (!access.agentbayAccessUrl) {
|
|
235
|
-
throw new Error('AgentBay did not return a browser access URL');
|
|
236
|
-
}
|
|
237
|
-
agentbayAccessUrl = access.agentbayAccessUrl;
|
|
238
|
-
details.push(`AgentBay access URL (temporary, sensitive): ${access.agentbayAccessUrl}`);
|
|
245
|
+
browserAccess = await getBrowserAccess(client, browser, browserAccessCapability, timeoutSec);
|
|
246
|
+
details.push(`Browser access URL (${browserAccessLabel(browserAccess)}; sensitive): ${browserAccess.url}`);
|
|
239
247
|
}
|
|
240
248
|
catch (error) {
|
|
241
249
|
accessUrlWarning = formatError(error);
|
|
242
|
-
details.push(`
|
|
250
|
+
details.push(`Browser access URL unavailable: ${accessUrlWarning}`);
|
|
243
251
|
}
|
|
244
252
|
}
|
|
245
253
|
browserChecks.push({
|
|
246
|
-
...(
|
|
254
|
+
...(browserAccess ? { browserAccess } : {}),
|
|
247
255
|
browser,
|
|
248
256
|
...(extensionInstallation ? { extensionInstallation } : {}),
|
|
249
257
|
item: {
|
|
250
258
|
status: accessUrlWarning ? 'warning' : 'ok',
|
|
251
259
|
label: accessUrlWarning
|
|
252
|
-
? 'Browser command path ready;
|
|
260
|
+
? 'Browser command path ready; browser access URL unavailable'
|
|
253
261
|
: options.transport === 'cdp'
|
|
254
262
|
? 'CDP command path'
|
|
255
263
|
: 'Browser command path',
|
|
@@ -293,7 +301,7 @@ export async function runUnifiedCheck(options, dependencies = {}) {
|
|
|
293
301
|
return {
|
|
294
302
|
...browserIdentity,
|
|
295
303
|
selected: targets.some(target => target.browserId === browser.browserId),
|
|
296
|
-
...(check?.
|
|
304
|
+
...(check?.browserAccess ? { browserAccess: check.browserAccess } : {}),
|
|
297
305
|
...(check?.item
|
|
298
306
|
? {
|
|
299
307
|
check: {
|
package/dist/commands.d.ts
CHANGED
|
@@ -386,21 +386,24 @@ export declare const COMMANDS: readonly [{
|
|
|
386
386
|
readonly examples: ["browser_list"];
|
|
387
387
|
}, {
|
|
388
388
|
readonly name: "browser_release";
|
|
389
|
-
readonly description: "
|
|
390
|
-
readonly summary: "
|
|
389
|
+
readonly description: "sessionId 接入的 AgentBay 浏览器用它解除本机 attachment且不关闭云端 Session;其他浏览器仅按用户明确要求释放调试控制和会话级临时效果(含设备/时区模拟),不用于普通任务收尾";
|
|
390
|
+
readonly summary: "释放浏览器控制或解除 Session attachment";
|
|
391
391
|
readonly examples: ["browser_release", "browser_release --browser chrome-a"];
|
|
392
392
|
}, {
|
|
393
393
|
readonly name: "browser_launch";
|
|
394
|
-
readonly description: "启动本地 Chrome
|
|
394
|
+
readonly description: "启动本地 Chrome、创建/复用同名 AgentBay 云浏览器,或用 sessionId 接入现有云端 Session";
|
|
395
395
|
readonly params: [{
|
|
396
396
|
readonly name: "name";
|
|
397
397
|
readonly type: "string";
|
|
398
|
-
readonly
|
|
399
|
-
readonly description: "实例名称,最多 64 个字符";
|
|
398
|
+
readonly description: "实例名称,创建浏览器时必填;按 sessionId 接入时可省略";
|
|
400
399
|
}, {
|
|
401
400
|
readonly name: "provider";
|
|
402
401
|
readonly type: "\"local\" | \"agentbay\"";
|
|
403
|
-
readonly description: "运行环境,默认 local
|
|
402
|
+
readonly description: "运行环境,默认 local;传 sessionId 时自动使用 agentbay,否则 agentbay 从 AGENTBAY_KEY 创建云浏览器";
|
|
403
|
+
}, {
|
|
404
|
+
readonly name: "sessionId";
|
|
405
|
+
readonly type: "string";
|
|
406
|
+
readonly description: "显式接入现有 AgentBay Session;不会创建、初始化或取得其生命周期所有权";
|
|
404
407
|
}, {
|
|
405
408
|
readonly name: "reuse";
|
|
406
409
|
readonly type: "\"never\" | \"prefer\" | \"require\"";
|
|
@@ -451,10 +454,10 @@ export declare const COMMANDS: readonly [{
|
|
|
451
454
|
readonly description: "CDP 控制浏览器中用于读取 TDBank Cookie 的标签页";
|
|
452
455
|
}, {
|
|
453
456
|
readonly name: "copyCookieDomains";
|
|
454
|
-
readonly type: "string[] | \"mearl-services\"";
|
|
455
|
-
readonly description: "从控制浏览器复制 Cookie
|
|
457
|
+
readonly type: "string[] | \"mearl-services\" | { presets?: [\"mearl-services\"]; domains?: string[] }";
|
|
458
|
+
readonly description: "从控制浏览器复制 Cookie:可传域名数组、Mearl 登录态预设,或组合预设与额外域名";
|
|
456
459
|
}];
|
|
457
|
-
readonly examples: ["browser_launch --payload '{\"name\":\"cloud-a\",\"provider\":\"agentbay\",\"userAgentMode\":\"desktop\",\"url\":\"https://example.com\"}'", "browser_launch --payload '{\"name\":\"cloud-public\",\"provider\":\"agentbay\",\"imageId\":\"browser_latest\",\"url\":\"https://example.com\"}'", "browser_launch --payload '{\"name\":\"cloud-login\",\"provider\":\"agentbay\",\"persistent\":true,\"copyCookieDomains\":[\"example.com\"],\"url\":\"https://example.com/account\"}'", "browser_launch --payload '{\"name\":\"cloud-login\",\"provider\":\"agentbay\",\"reuse\":\"require\",\"copyCookieDomains\":[\"example.com\"]}'", "browser_launch --payload '{\"name\":\"cloud-tools\",\"provider\":\"agentbay\",\"copyCookieDomains\":\"mearl-services\"}'", "browser_launch --payload '{\"name\":\"account-a\",\"headless\":true,\"accountId\":12345}'", "browser_launch --payload '{\"name\":\"figma\",\"userAgentMode\":\"desktop\",\"copyCookieDomains\":[\"figma.com\"]}'", "browser_launch --payload '{\"name\":\"account-b\",\"query\":\"test_account\",\"url\":\"https://www.taobao.com\"}'", "browser_launch --payload '{\"name\":\"with-cookies\",\"copyCookieDomains\":[\"example.com\",\"sub.example.org\"]}'"];
|
|
460
|
+
readonly examples: ["browser_launch --payload '{\"name\":\"cloud-a\",\"provider\":\"agentbay\",\"userAgentMode\":\"desktop\",\"url\":\"https://example.com\"}'", "browser_launch --payload '{\"name\":\"cloud-public\",\"provider\":\"agentbay\",\"imageId\":\"browser_latest\",\"url\":\"https://example.com\"}'", "browser_launch --payload '{\"name\":\"cloud-login\",\"provider\":\"agentbay\",\"persistent\":true,\"copyCookieDomains\":[\"example.com\"],\"url\":\"https://example.com/account\"}'", "browser_launch --payload '{\"name\":\"cloud-login\",\"provider\":\"agentbay\",\"reuse\":\"require\",\"copyCookieDomains\":[\"example.com\"]}'", "browser_launch --browser '<本地浏览器 browserId>' --payload '{\"sessionId\":\"<AgentBay sessionId>\",\"copyCookieDomains\":[\"example.com\"]}'", "browser_launch --payload '{\"name\":\"cloud-tools\",\"provider\":\"agentbay\",\"copyCookieDomains\":\"mearl-services\"}'", "browser_launch --payload '{\"name\":\"cloud-tools\",\"provider\":\"agentbay\",\"copyCookieDomains\":{\"presets\":[\"mearl-services\"],\"domains\":[\"figma.com\"]}}'", "browser_launch --payload '{\"name\":\"account-a\",\"headless\":true,\"accountId\":12345}'", "browser_launch --payload '{\"name\":\"figma\",\"userAgentMode\":\"desktop\",\"copyCookieDomains\":[\"figma.com\"]}'", "browser_launch --payload '{\"name\":\"account-b\",\"query\":\"test_account\",\"url\":\"https://www.taobao.com\"}'", "browser_launch --payload '{\"name\":\"with-cookies\",\"copyCookieDomains\":[\"example.com\",\"sub.example.org\"]}'"];
|
|
458
461
|
}, {
|
|
459
462
|
readonly name: "browser_close";
|
|
460
463
|
readonly description: "关闭指定托管浏览器并按策略保留或清理本地 Profile / AgentBay Context";
|
|
@@ -509,25 +512,21 @@ export declare const COMMANDS: readonly [{
|
|
|
509
512
|
}, {
|
|
510
513
|
readonly name: "emulation";
|
|
511
514
|
readonly type: "object";
|
|
512
|
-
readonly description: "开 tab 即进入移动端模拟态(首屏即移动态、无需 reload)。字段同 set_device_emulation 去掉 enabled
|
|
515
|
+
readonly description: "开 tab 即进入移动端模拟态(首屏即移动态、无需 reload)。字段同 set_device_emulation 去掉 enabled/reload;deviceShell=true 时页面从首屏起在 iframe WebView 中渲染设备系统外壳";
|
|
513
516
|
}, {
|
|
514
517
|
readonly name: "appProfile";
|
|
515
518
|
readonly type: "string";
|
|
516
|
-
readonly description: "开 tab
|
|
519
|
+
readonly description: "开 tab 即注入 App 客户端环境与 JSBridge;档案名同 set_app_profile,如 \"fliggy\"。需要 iframe WebView 和系统栏时同时传 emulation.deviceShell=true";
|
|
517
520
|
}, {
|
|
518
521
|
readonly name: "os";
|
|
519
522
|
readonly type: "\"ios\" | \"android\"";
|
|
520
523
|
readonly description: "与 appProfile 配合;容器系统,默认 ios";
|
|
521
|
-
}, {
|
|
522
|
-
readonly name: "simulateSystemBars";
|
|
523
|
-
readonly type: "boolean";
|
|
524
|
-
readonly description: "与 appProfile 配合;是否模拟顶部状态/导航栏与底部手势栏,默认 true";
|
|
525
524
|
}, {
|
|
526
525
|
readonly name: "bridgeConfig";
|
|
527
526
|
readonly type: "object";
|
|
528
527
|
readonly description: "与 appProfile 配合;声明式覆盖桥方法,形如 {methods:{api:{behavior|response|noop,silent?}}}";
|
|
529
528
|
}];
|
|
530
|
-
readonly examples: ["tab_open --payload '{\"url\":\"https://example.com\"}'", "tab_open --payload '{\"url\":\"https://example.com/page\",\"reuse\":\"prefer\",\"match\":{\"ignoreSearch\":true}}'", "tab_open --payload '{\"url\":\"https://m.example.com\",\"emulation\":{\"preset\":\"iphone-
|
|
529
|
+
readonly examples: ["tab_open --payload '{\"url\":\"https://example.com\"}'", "tab_open --payload '{\"url\":\"https://example.com/page\",\"reuse\":\"prefer\",\"match\":{\"ignoreSearch\":true}}'", "tab_open --payload '{\"url\":\"https://m.example.com\",\"emulation\":{\"preset\":\"iphone-17-pro\"}}'", "tab_open --payload '{\"url\":\"https://market.m.taobao.com/app/trip/rx-home/pages/home\",\"appProfile\":\"fliggy\"}'", "tab_open --payload '{\"url\":\"https://example.com\",\"appProfile\":\"fliggy\",\"os\":\"android\"}'", "tab_open --payload '{\"url\":\"https://example.com\",\"group\":\"验证任务\"}'"];
|
|
531
530
|
}, {
|
|
532
531
|
readonly name: "tab_close";
|
|
533
532
|
readonly description: "关闭指定标签页";
|
|
@@ -912,7 +911,7 @@ export declare const COMMANDS: readonly [{
|
|
|
912
911
|
readonly examples: ["record_stop"];
|
|
913
912
|
}, {
|
|
914
913
|
readonly name: "set_device_emulation";
|
|
915
|
-
readonly description: "把目标 tab 切换为移动端模拟(视口/UA
|
|
914
|
+
readonly description: "把目标 tab 切换为移动端模拟(视口/DPR/UA/触摸/视觉比例),等价 DevTools 设备工具栏,作用域 per-tab;需保持调试控制才持续生效";
|
|
916
915
|
readonly summary: "设置或清除目标标签页的设备模拟";
|
|
917
916
|
readonly params: [{
|
|
918
917
|
readonly name: "enabled";
|
|
@@ -921,8 +920,8 @@ export declare const COMMANDS: readonly [{
|
|
|
921
920
|
readonly description: "true=启用,false=清除";
|
|
922
921
|
}, {
|
|
923
922
|
readonly name: "preset";
|
|
924
|
-
readonly type:
|
|
925
|
-
readonly description: "内置设备预设,提供 width/height/DPR/UA
|
|
923
|
+
readonly type: string;
|
|
924
|
+
readonly description: "内置设备预设,提供 width/height/DPR/UA 默认值;旧机型 ID 继续兼容";
|
|
926
925
|
}, {
|
|
927
926
|
readonly name: "width";
|
|
928
927
|
readonly type: "number";
|
|
@@ -935,6 +934,10 @@ export declare const COMMANDS: readonly [{
|
|
|
935
934
|
readonly name: "deviceScaleFactor";
|
|
936
935
|
readonly type: "number";
|
|
937
936
|
readonly description: "DPR(覆盖 preset)";
|
|
937
|
+
}, {
|
|
938
|
+
readonly name: "scale";
|
|
939
|
+
readonly type: "number";
|
|
940
|
+
readonly description: "画面视觉比例,不改变视口尺寸或 DPR;必须为有限正数,默认 1";
|
|
938
941
|
}, {
|
|
939
942
|
readonly name: "mobile";
|
|
940
943
|
readonly type: "boolean";
|
|
@@ -950,7 +953,11 @@ export declare const COMMANDS: readonly [{
|
|
|
950
953
|
}, {
|
|
951
954
|
readonly name: "touch";
|
|
952
955
|
readonly type: "boolean";
|
|
953
|
-
readonly description: "
|
|
956
|
+
readonly description: "是否启用触摸事件,默认从 preset 推断;无 preset 时跟随 mobile";
|
|
957
|
+
}, {
|
|
958
|
+
readonly name: "deviceShell";
|
|
959
|
+
readonly type: "boolean";
|
|
960
|
+
readonly description: "是否使用 iframe WebView 并渲染顶部状态栏与底部操作区,默认 false";
|
|
954
961
|
}, {
|
|
955
962
|
readonly name: "reload";
|
|
956
963
|
readonly type: "boolean";
|
|
@@ -961,10 +968,10 @@ export declare const COMMANDS: readonly [{
|
|
|
961
968
|
readonly required: true;
|
|
962
969
|
readonly description: "目标标签页 ID";
|
|
963
970
|
}];
|
|
964
|
-
readonly examples: ["set_device_emulation --payload '{\"enabled\":true,\"preset\":\"iphone-
|
|
971
|
+
readonly examples: ["set_device_emulation --payload '{\"enabled\":true,\"preset\":\"iphone-17-pro\"}'", "set_device_emulation --payload '{\"enabled\":true,\"preset\":\"pixel-11\",\"orientation\":\"landscape\"}'", "set_device_emulation --payload '{\"enabled\":false}'"];
|
|
965
972
|
}, {
|
|
966
973
|
readonly name: "set_app_profile";
|
|
967
|
-
readonly description: "
|
|
974
|
+
readonly description: "设置 App 客户端环境与 JSBridge;传 emulation 时由同一个命令联动设备模拟,省略时不改变设备状态";
|
|
968
975
|
readonly summary: "设置或清除目标标签页的 App 容器模拟";
|
|
969
976
|
readonly params: [{
|
|
970
977
|
readonly name: "enabled";
|
|
@@ -987,18 +994,14 @@ export declare const COMMANDS: readonly [{
|
|
|
987
994
|
readonly name: "deviceModel";
|
|
988
995
|
readonly type: "string";
|
|
989
996
|
readonly description: "Android 机型名(拼入 UA 与 __DEVICE_MODEL__)";
|
|
990
|
-
}, {
|
|
991
|
-
readonly name: "simulateSystemBars";
|
|
992
|
-
readonly type: "boolean";
|
|
993
|
-
readonly description: "是否模拟顶部状态/导航栏与底部手势栏,默认 true";
|
|
994
|
-
}, {
|
|
995
|
-
readonly name: "emulation";
|
|
996
|
-
readonly type: "object";
|
|
997
|
-
readonly description: "覆盖档案推荐的设备模拟参数,字段同 set_device_emulation 去掉 enabled";
|
|
998
997
|
}, {
|
|
999
998
|
readonly name: "bridgeConfig";
|
|
1000
999
|
readonly type: "object";
|
|
1001
1000
|
readonly description: "声明式覆盖桥方法,形如 {methods:{api:{behavior|response|noop,silent?}}};不执行配置脚本";
|
|
1001
|
+
}, {
|
|
1002
|
+
readonly name: "emulation";
|
|
1003
|
+
readonly type: "object";
|
|
1004
|
+
readonly description: "可选设备联动参数,字段同 set_device_emulation 去掉 enabled/reload;字段覆盖档案推荐设备,deviceShell 默认 true。省略时不设置或清除设备";
|
|
1002
1005
|
}, {
|
|
1003
1006
|
readonly name: "reload";
|
|
1004
1007
|
readonly type: "boolean";
|
|
@@ -1009,7 +1012,7 @@ export declare const COMMANDS: readonly [{
|
|
|
1009
1012
|
readonly required: true;
|
|
1010
1013
|
readonly description: "目标标签页 ID";
|
|
1011
1014
|
}];
|
|
1012
|
-
readonly examples: ["set_app_profile --payload '{\"enabled\":true,\"profile\":\"fliggy\"}'", "set_app_profile --payload '{\"enabled\":true,\"profile\":\"fliggy\",\"
|
|
1015
|
+
readonly examples: ["set_app_profile --payload '{\"enabled\":true,\"profile\":\"fliggy\"}'", "set_app_profile --payload '{\"enabled\":true,\"profile\":\"fliggy\",\"emulation\":{}}'", "set_app_profile --payload '{\"enabled\":true,\"profile\":\"alipay\",\"emulation\":{\"preset\":\"pixel-11\",\"deviceShell\":true}}'", "set_app_profile --payload '{\"enabled\":false}'", "set_app_profile --payload '{\"enabled\":false,\"emulation\":{}}'"];
|
|
1013
1016
|
}, {
|
|
1014
1017
|
readonly name: "set_timezone";
|
|
1015
1018
|
readonly description: "覆盖目标 tab 的时区,传空字符串恢复浏览器默认时区";
|
package/dist/commands.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { APP_PROFILE_NAMES, } from './generated-browser-action-protocol.js';
|
|
1
|
+
import { APP_PROFILE_NAMES, BROWSER_DEVICE_PRESET_NAMES, } from './generated-browser-action-protocol.js';
|
|
2
2
|
/** 容器档案名列表(拼进参数说明,新增档案无需改本文件) */
|
|
3
3
|
const APP_PROFILE_NAME_LIST = APP_PROFILE_NAMES.join('/');
|
|
4
|
+
const DEVICE_PRESET_TYPE = BROWSER_DEVICE_PRESET_NAMES.map(name => JSON.stringify(name)).join(' | ');
|
|
4
5
|
const PAGE_DIAGNOSTICS_PARAM = {
|
|
5
6
|
name: 'diagnostics',
|
|
6
7
|
type: 'object | boolean',
|
|
@@ -289,19 +290,28 @@ export const COMMANDS = [
|
|
|
289
290
|
},
|
|
290
291
|
{
|
|
291
292
|
name: 'browser_release',
|
|
292
|
-
description: '
|
|
293
|
-
summary: '
|
|
293
|
+
description: 'sessionId 接入的 AgentBay 浏览器用它解除本机 attachment且不关闭云端 Session;其他浏览器仅按用户明确要求释放调试控制和会话级临时效果(含设备/时区模拟),不用于普通任务收尾',
|
|
294
|
+
summary: '释放浏览器控制或解除 Session attachment',
|
|
294
295
|
examples: ['browser_release', 'browser_release --browser chrome-a'],
|
|
295
296
|
},
|
|
296
297
|
{
|
|
297
298
|
name: 'browser_launch',
|
|
298
|
-
description: '启动本地 Chrome
|
|
299
|
+
description: '启动本地 Chrome、创建/复用同名 AgentBay 云浏览器,或用 sessionId 接入现有云端 Session',
|
|
299
300
|
params: [
|
|
300
|
-
{
|
|
301
|
+
{
|
|
302
|
+
name: 'name',
|
|
303
|
+
type: 'string',
|
|
304
|
+
description: '实例名称,创建浏览器时必填;按 sessionId 接入时可省略',
|
|
305
|
+
},
|
|
301
306
|
{
|
|
302
307
|
name: 'provider',
|
|
303
308
|
type: '"local" | "agentbay"',
|
|
304
|
-
description: '运行环境,默认 local
|
|
309
|
+
description: '运行环境,默认 local;传 sessionId 时自动使用 agentbay,否则 agentbay 从 AGENTBAY_KEY 创建云浏览器',
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: 'sessionId',
|
|
313
|
+
type: 'string',
|
|
314
|
+
description: '显式接入现有 AgentBay Session;不会创建、初始化或取得其生命周期所有权',
|
|
305
315
|
},
|
|
306
316
|
{
|
|
307
317
|
name: 'reuse',
|
|
@@ -345,8 +355,8 @@ export const COMMANDS = [
|
|
|
345
355
|
},
|
|
346
356
|
{
|
|
347
357
|
name: 'copyCookieDomains',
|
|
348
|
-
type: 'string[] | "mearl-services"',
|
|
349
|
-
description: '从控制浏览器复制 Cookie
|
|
358
|
+
type: 'string[] | "mearl-services" | { presets?: ["mearl-services"]; domains?: string[] }',
|
|
359
|
+
description: '从控制浏览器复制 Cookie:可传域名数组、Mearl 登录态预设,或组合预设与额外域名',
|
|
350
360
|
},
|
|
351
361
|
],
|
|
352
362
|
examples: [
|
|
@@ -354,7 +364,9 @@ export const COMMANDS = [
|
|
|
354
364
|
`browser_launch --payload '{"name":"cloud-public","provider":"agentbay","imageId":"browser_latest","url":"https://example.com"}'`,
|
|
355
365
|
`browser_launch --payload '{"name":"cloud-login","provider":"agentbay","persistent":true,"copyCookieDomains":["example.com"],"url":"https://example.com/account"}'`,
|
|
356
366
|
`browser_launch --payload '{"name":"cloud-login","provider":"agentbay","reuse":"require","copyCookieDomains":["example.com"]}'`,
|
|
367
|
+
`browser_launch --browser '<本地浏览器 browserId>' --payload '{"sessionId":"<AgentBay sessionId>","copyCookieDomains":["example.com"]}'`,
|
|
357
368
|
`browser_launch --payload '{"name":"cloud-tools","provider":"agentbay","copyCookieDomains":"mearl-services"}'`,
|
|
369
|
+
`browser_launch --payload '{"name":"cloud-tools","provider":"agentbay","copyCookieDomains":{"presets":["mearl-services"],"domains":["figma.com"]}}'`,
|
|
358
370
|
`browser_launch --payload '{"name":"account-a","headless":true,"accountId":12345}'`,
|
|
359
371
|
`browser_launch --payload '{"name":"figma","userAgentMode":"desktop","copyCookieDomains":["figma.com"]}'`,
|
|
360
372
|
`browser_launch --payload '{"name":"account-b","query":"test_account","url":"https://www.taobao.com"}'`,
|
|
@@ -424,23 +436,18 @@ export const COMMANDS = [
|
|
|
424
436
|
{
|
|
425
437
|
name: 'emulation',
|
|
426
438
|
type: 'object',
|
|
427
|
-
description: '开 tab 即进入移动端模拟态(首屏即移动态、无需 reload)。字段同 set_device_emulation 去掉 enabled
|
|
439
|
+
description: '开 tab 即进入移动端模拟态(首屏即移动态、无需 reload)。字段同 set_device_emulation 去掉 enabled/reload;deviceShell=true 时页面从首屏起在 iframe WebView 中渲染设备系统外壳',
|
|
428
440
|
},
|
|
429
441
|
{
|
|
430
442
|
name: 'appProfile',
|
|
431
443
|
type: 'string',
|
|
432
|
-
description: '开 tab
|
|
444
|
+
description: '开 tab 即注入 App 客户端环境与 JSBridge;档案名同 set_app_profile,如 "fliggy"。需要 iframe WebView 和系统栏时同时传 emulation.deviceShell=true',
|
|
433
445
|
},
|
|
434
446
|
{
|
|
435
447
|
name: 'os',
|
|
436
448
|
type: '"ios" | "android"',
|
|
437
449
|
description: '与 appProfile 配合;容器系统,默认 ios',
|
|
438
450
|
},
|
|
439
|
-
{
|
|
440
|
-
name: 'simulateSystemBars',
|
|
441
|
-
type: 'boolean',
|
|
442
|
-
description: '与 appProfile 配合;是否模拟顶部状态/导航栏与底部手势栏,默认 true',
|
|
443
|
-
},
|
|
444
451
|
{
|
|
445
452
|
name: 'bridgeConfig',
|
|
446
453
|
type: 'object',
|
|
@@ -450,7 +457,7 @@ export const COMMANDS = [
|
|
|
450
457
|
examples: [
|
|
451
458
|
`tab_open --payload '{"url":"https://example.com"}'`,
|
|
452
459
|
`tab_open --payload '{"url":"https://example.com/page","reuse":"prefer","match":{"ignoreSearch":true}}'`,
|
|
453
|
-
`tab_open --payload '{"url":"https://m.example.com","emulation":{"preset":"iphone-
|
|
460
|
+
`tab_open --payload '{"url":"https://m.example.com","emulation":{"preset":"iphone-17-pro"}}'`,
|
|
454
461
|
`tab_open --payload '{"url":"https://market.m.taobao.com/app/trip/rx-home/pages/home","appProfile":"fliggy"}'`,
|
|
455
462
|
`tab_open --payload '{"url":"https://example.com","appProfile":"fliggy","os":"android"}'`,
|
|
456
463
|
`tab_open --payload '{"url":"https://example.com","group":"验证任务"}'`,
|
|
@@ -853,18 +860,23 @@ export const COMMANDS = [
|
|
|
853
860
|
// ── 移动端模拟 ────────────────────────────────────────────────────────────
|
|
854
861
|
{
|
|
855
862
|
name: 'set_device_emulation',
|
|
856
|
-
description: '把目标 tab 切换为移动端模拟(视口/UA
|
|
863
|
+
description: '把目标 tab 切换为移动端模拟(视口/DPR/UA/触摸/视觉比例),等价 DevTools 设备工具栏,作用域 per-tab;需保持调试控制才持续生效',
|
|
857
864
|
summary: '设置或清除目标标签页的设备模拟',
|
|
858
865
|
params: [
|
|
859
866
|
{ name: 'enabled', type: 'boolean', required: true, description: 'true=启用,false=清除' },
|
|
860
867
|
{
|
|
861
868
|
name: 'preset',
|
|
862
|
-
type:
|
|
863
|
-
description: '内置设备预设,提供 width/height/DPR/UA
|
|
869
|
+
type: DEVICE_PRESET_TYPE,
|
|
870
|
+
description: '内置设备预设,提供 width/height/DPR/UA 默认值;旧机型 ID 继续兼容',
|
|
864
871
|
},
|
|
865
872
|
{ name: 'width', type: 'number', description: '视口宽度(覆盖 preset)' },
|
|
866
873
|
{ name: 'height', type: 'number', description: '视口高度(覆盖 preset)' },
|
|
867
874
|
{ name: 'deviceScaleFactor', type: 'number', description: 'DPR(覆盖 preset)' },
|
|
875
|
+
{
|
|
876
|
+
name: 'scale',
|
|
877
|
+
type: 'number',
|
|
878
|
+
description: '画面视觉比例,不改变视口尺寸或 DPR;必须为有限正数,默认 1',
|
|
879
|
+
},
|
|
868
880
|
{ name: 'mobile', type: 'boolean', description: '是否走移动渲染模式,默认从 preset 推断' },
|
|
869
881
|
{ name: 'userAgent', type: 'string', description: '自定义 UA(覆盖 preset)' },
|
|
870
882
|
{
|
|
@@ -872,19 +884,28 @@ export const COMMANDS = [
|
|
|
872
884
|
type: '"portrait" | "landscape"',
|
|
873
885
|
description: '横竖屏,默认 portrait',
|
|
874
886
|
},
|
|
875
|
-
{
|
|
887
|
+
{
|
|
888
|
+
name: 'touch',
|
|
889
|
+
type: 'boolean',
|
|
890
|
+
description: '是否启用触摸事件,默认从 preset 推断;无 preset 时跟随 mobile',
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
name: 'deviceShell',
|
|
894
|
+
type: 'boolean',
|
|
895
|
+
description: '是否使用 iframe WebView 并渲染顶部状态栏与底部操作区,默认 false',
|
|
896
|
+
},
|
|
876
897
|
{ name: 'reload', type: 'boolean', description: '启用后是否重载页面,默认 true' },
|
|
877
898
|
{ name: 'tabId', type: 'number', required: true, description: '目标标签页 ID' },
|
|
878
899
|
],
|
|
879
900
|
examples: [
|
|
880
|
-
`set_device_emulation --payload '{"enabled":true,"preset":"iphone-
|
|
881
|
-
`set_device_emulation --payload '{"enabled":true,"preset":"pixel-
|
|
901
|
+
`set_device_emulation --payload '{"enabled":true,"preset":"iphone-17-pro"}'`,
|
|
902
|
+
`set_device_emulation --payload '{"enabled":true,"preset":"pixel-11","orientation":"landscape"}'`,
|
|
882
903
|
`set_device_emulation --payload '{"enabled":false}'`,
|
|
883
904
|
],
|
|
884
905
|
},
|
|
885
906
|
{
|
|
886
907
|
name: 'set_app_profile',
|
|
887
|
-
description: '
|
|
908
|
+
description: '设置 App 客户端环境与 JSBridge;传 emulation 时由同一个命令联动设备模拟,省略时不改变设备状态',
|
|
888
909
|
summary: '设置或清除目标标签页的 App 容器模拟',
|
|
889
910
|
params: [
|
|
890
911
|
{ name: 'enabled', type: 'boolean', required: true, description: 'true=启用,false=清除' },
|
|
@@ -901,28 +922,24 @@ export const COMMANDS = [
|
|
|
901
922
|
description: 'Android 机型名(拼入 UA 与 __DEVICE_MODEL__)',
|
|
902
923
|
},
|
|
903
924
|
{
|
|
904
|
-
name: '
|
|
905
|
-
type: 'boolean',
|
|
906
|
-
description: '是否模拟顶部状态/导航栏与底部手势栏,默认 true',
|
|
907
|
-
},
|
|
908
|
-
{
|
|
909
|
-
name: 'emulation',
|
|
925
|
+
name: 'bridgeConfig',
|
|
910
926
|
type: 'object',
|
|
911
|
-
description: '
|
|
927
|
+
description: '声明式覆盖桥方法,形如 {methods:{api:{behavior|response|noop,silent?}}};不执行配置脚本',
|
|
912
928
|
},
|
|
913
929
|
{
|
|
914
|
-
name: '
|
|
930
|
+
name: 'emulation',
|
|
915
931
|
type: 'object',
|
|
916
|
-
description: '
|
|
932
|
+
description: '可选设备联动参数,字段同 set_device_emulation 去掉 enabled/reload;字段覆盖档案推荐设备,deviceShell 默认 true。省略时不设置或清除设备',
|
|
917
933
|
},
|
|
918
934
|
{ name: 'reload', type: 'boolean', description: '应用/清除后是否重载页面,默认 true' },
|
|
919
935
|
{ name: 'tabId', type: 'number', required: true, description: '目标标签页 ID' },
|
|
920
936
|
],
|
|
921
937
|
examples: [
|
|
922
938
|
`set_app_profile --payload '{"enabled":true,"profile":"fliggy"}'`,
|
|
923
|
-
`set_app_profile --payload '{"enabled":true,"profile":"fliggy","
|
|
924
|
-
`set_app_profile --payload '{"enabled":true,"profile":"alipay","
|
|
939
|
+
`set_app_profile --payload '{"enabled":true,"profile":"fliggy","emulation":{}}'`,
|
|
940
|
+
`set_app_profile --payload '{"enabled":true,"profile":"alipay","emulation":{"preset":"pixel-11","deviceShell":true}}'`,
|
|
925
941
|
`set_app_profile --payload '{"enabled":false}'`,
|
|
942
|
+
`set_app_profile --payload '{"enabled":false,"emulation":{}}'`,
|
|
926
943
|
],
|
|
927
944
|
},
|
|
928
945
|
{
|
|
@@ -157,6 +157,8 @@ export interface ManagedBrowserInfo extends BrowserInfoBase {
|
|
|
157
157
|
persistent: boolean;
|
|
158
158
|
cdpPort?: number;
|
|
159
159
|
agentbaySessionId?: string;
|
|
160
|
+
/** Whether this host owns the AgentBay session lifecycle or only attaches to it. */
|
|
161
|
+
agentbaySessionMode?: 'owned' | 'attached';
|
|
160
162
|
/** AgentBay image used to create the session. */
|
|
161
163
|
agentbayImageId?: string;
|
|
162
164
|
/** Persistent AgentBay browser context ID when enabled for this instance. */
|
|
@@ -199,12 +201,26 @@ export interface BrowserReleaseResult {
|
|
|
199
201
|
hadActiveControl: boolean;
|
|
200
202
|
transports: Array<'extension' | 'cdp'>;
|
|
201
203
|
affectedTabIds: number[];
|
|
204
|
+
/** True when browser_release also removed a sessionId-based local AgentBay attachment. */
|
|
205
|
+
detached?: boolean;
|
|
206
|
+
/** Attached sessions remain alive in AgentBay after the local attachment is released. */
|
|
207
|
+
sessionClosed?: boolean;
|
|
208
|
+
agentbaySessionId?: string;
|
|
202
209
|
failures?: BrowserReleaseFailure[];
|
|
203
210
|
}
|
|
211
|
+
export interface CookieCopyScope {
|
|
212
|
+
/** Maintained authentication-domain presets to include. */
|
|
213
|
+
presets?: Array<'mearl-services'>;
|
|
214
|
+
/** Additional domains or URLs to copy alongside the selected presets. */
|
|
215
|
+
domains?: string[];
|
|
216
|
+
}
|
|
204
217
|
export interface BrowserLaunchParams {
|
|
205
|
-
|
|
206
|
-
|
|
218
|
+
/** Required when creating a browser; optional when attaching by AgentBay sessionId. */
|
|
219
|
+
name?: string;
|
|
220
|
+
/** Browser runtime provider. Defaults to local Chrome unless sessionId is present. */
|
|
207
221
|
provider?: 'local' | 'agentbay';
|
|
222
|
+
/** Attach to an exact live AgentBay session without creating or owning it. */
|
|
223
|
+
sessionId?: string;
|
|
208
224
|
/** AgentBay running-session reuse policy. Defaults to never. */
|
|
209
225
|
reuse?: 'never' | 'prefer' | 'require';
|
|
210
226
|
/** AgentBay image alias or concrete image ID. Only supported by the AgentBay provider. */
|
|
@@ -221,8 +237,8 @@ export interface BrowserLaunchParams {
|
|
|
221
237
|
site?: string | number;
|
|
222
238
|
query?: string;
|
|
223
239
|
tabId?: number;
|
|
224
|
-
/** Copy explicit domains
|
|
225
|
-
copyCookieDomains?: string[] | 'mearl-services';
|
|
240
|
+
/** Copy explicit domains, the Mearl-service preset, or a combination of both. */
|
|
241
|
+
copyCookieDomains?: string[] | 'mearl-services' | CookieCopyScope;
|
|
226
242
|
}
|
|
227
243
|
export interface BrowserCloseParams {
|
|
228
244
|
browser: string;
|
|
@@ -262,16 +278,20 @@ export interface PageSelectedElementParams {
|
|
|
262
278
|
includeOuterHTML?: boolean;
|
|
263
279
|
includeScreenshot?: boolean;
|
|
264
280
|
}
|
|
265
|
-
export
|
|
281
|
+
export declare const BROWSER_DEVICE_PRESET_NAMES: readonly ["iphone-17-pro", "iphone-17e", "pixel-11", "ipad-mini-a17-pro", "galaxy-s26", "pura-x-max", "iphone-15-pro", "iphone-se", "pixel-8", "ipad-mini", "galaxy-s23"];
|
|
282
|
+
export type BrowserDevicePresetName = (typeof BROWSER_DEVICE_PRESET_NAMES)[number];
|
|
266
283
|
export interface BrowserEmulationOptions {
|
|
267
284
|
preset?: BrowserDevicePresetName;
|
|
268
285
|
width?: number;
|
|
269
286
|
height?: number;
|
|
270
287
|
deviceScaleFactor?: number;
|
|
288
|
+
scale?: number;
|
|
271
289
|
mobile?: boolean;
|
|
272
290
|
userAgent?: string;
|
|
273
291
|
orientation?: 'portrait' | 'landscape';
|
|
274
292
|
touch?: boolean;
|
|
293
|
+
/** 在 iframe WebView 外渲染设备系统栏;默认 false,保持纯 CDP 设备模拟。 */
|
|
294
|
+
deviceShell?: boolean;
|
|
275
295
|
}
|
|
276
296
|
export type AppBridgeConfigBehavior = 'navigate' | 'closeAll' | 'closeBackData' | 'postMessage' | 'notifySubscribe' | 'notifyUnsubscribe' | 'notifyPost' | 'sharedFileRead' | 'sharedFileWrite' | 'sharedDataGet' | 'sharedDataSet' | 'legacyBroadcastCreate' | 'legacyBroadcastPost' | 'legacyBroadcastClose' | 'memoryGet' | 'memorySet' | 'memoryDelete' | 'availabilityMap' | 'userInfo' | 'networkInfo' | 'geolocation' | 'permission' | 'prefetch' | 'fptTrack' | 'mtopStream' | 'previewFile' | 'toast' | 'unsupportedNativeInput' | 'payment' | 'userTrack' | 'calendar' | 'networkQualityMonitor' | 'beaconRequest';
|
|
277
297
|
/** 单个桥方法的声明式覆盖;行为、固定回包、成功空实现三选一。 */
|
|
@@ -302,15 +322,12 @@ export interface TabOpenParams {
|
|
|
302
322
|
emulation?: BrowserEmulationOptions;
|
|
303
323
|
group?: string;
|
|
304
324
|
/**
|
|
305
|
-
* 客户端容器模拟档案名(如 'fliggy'
|
|
306
|
-
*
|
|
307
|
-
* 并根据页面协议与桥调用切换普通、沉浸或隐藏状态。可用档案见 APP_PROFILE_NAMES。
|
|
325
|
+
* 客户端容器模拟档案名(如 'fliggy')。只注入容器 UA、环境变量、JSBridge 与桥协议;
|
|
326
|
+
* 设备视口和 iframe 系统外壳由 emulation.deviceShell 独立控制。可用档案见 APP_PROFILE_NAMES。
|
|
308
327
|
*/
|
|
309
328
|
appProfile?: AppProfileName;
|
|
310
329
|
/** 与 appProfile 配合使用;容器系统,默认 ios */
|
|
311
330
|
os?: 'ios' | 'android';
|
|
312
|
-
/** 与 appProfile 配合使用;是否模拟顶部状态/导航栏与底部手势栏,默认 true */
|
|
313
|
-
simulateSystemBars?: boolean;
|
|
314
331
|
/** 与 appProfile 配合使用;按方法覆盖档案内置桥配置 */
|
|
315
332
|
bridgeConfig?: AppBridgeConfig;
|
|
316
333
|
}
|
|
@@ -333,11 +350,12 @@ export interface SetAppProfileParams {
|
|
|
333
350
|
os?: 'ios' | 'android';
|
|
334
351
|
appVersion?: string;
|
|
335
352
|
deviceModel?: string;
|
|
336
|
-
/** 是否模拟顶部状态/导航栏与底部手势栏,默认 true */
|
|
337
|
-
simulateSystemBars?: boolean;
|
|
338
353
|
/** 按方法覆盖档案内置桥配置,仅支持受控行为、固定 JSON 回包和成功空实现 */
|
|
339
354
|
bridgeConfig?: AppBridgeConfig;
|
|
340
|
-
/**
|
|
355
|
+
/**
|
|
356
|
+
* 可选设备联动参数。传入时显式字段覆盖档案推荐设备,空对象使用推荐设备且默认开启
|
|
357
|
+
* deviceShell;省略时不设置或清除该 tab 的设备状态。
|
|
358
|
+
*/
|
|
341
359
|
emulation?: BrowserEmulationOptions;
|
|
342
360
|
/** 默认 true:应用/清除后刷新页面使注入生效 */
|
|
343
361
|
reload?: boolean;
|
|
@@ -6,6 +6,20 @@ export const SEND_REQUEST_MAX_TOTAL_FILE_BYTES = 40 * 1024 * 1024;
|
|
|
6
6
|
// Base64 expands by 4/3; 7 MiB leaves roughly 680 KiB for JSON framing under
|
|
7
7
|
// the 10 MiB cloud message limit.
|
|
8
8
|
export const SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES = 7 * 1024 * 1024;
|
|
9
|
+
export const BROWSER_DEVICE_PRESET_NAMES = [
|
|
10
|
+
'iphone-17-pro',
|
|
11
|
+
'iphone-17e',
|
|
12
|
+
'pixel-11',
|
|
13
|
+
'ipad-mini-a17-pro',
|
|
14
|
+
'galaxy-s26',
|
|
15
|
+
'pura-x-max',
|
|
16
|
+
// 旧名称保留具体机型语义,供已有调用与历史回归基线继续使用。
|
|
17
|
+
'iphone-15-pro',
|
|
18
|
+
'iphone-se',
|
|
19
|
+
'pixel-8',
|
|
20
|
+
'ipad-mini',
|
|
21
|
+
'galaxy-s23',
|
|
22
|
+
];
|
|
9
23
|
/**
|
|
10
24
|
* 客户端容器模拟可用档案名。
|
|
11
25
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { UnifiedClient, UnifiedClient as MearlClient, decodeBrowserTarget, invoke, listCloudConnectors, } from './unified.js';
|
|
8
8
|
export type { UnifiedClientOptions, UnifiedInvokeOptions, UnifiedInvokeOptions as InvokeOptions, } from './unified.js';
|
|
9
|
-
export { APP_PROFILE_NAMES, BROWSER_ACTIONS, BROWSER_COMMAND_ACTIONS, EXTENSION_BROWSER_ACTIONS, PAGE_ACT_ACTIONS, SEND_REQUEST_MAX_FILES, SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES, SEND_REQUEST_MAX_TOTAL_FILE_BYTES, isBrowserAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
|
|
9
|
+
export { APP_PROFILE_NAMES, BROWSER_DEVICE_PRESET_NAMES, BROWSER_ACTIONS, BROWSER_COMMAND_ACTIONS, EXTENSION_BROWSER_ACTIONS, PAGE_ACT_ACTIONS, SEND_REQUEST_MAX_FILES, SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES, SEND_REQUEST_MAX_TOTAL_FILE_BYTES, isBrowserAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
|
|
10
10
|
export type { ActionStep, AppProfileName, BrowserAction, BrowserActionMap, BrowserActionRequest, BrowserActionResponse, BrowserCloseParams, BrowserCommandAction, BrowserInfo, BrowserInfoBase, BrowserLaunchParams, BrowserListResult, BrowserReleaseFailure, BrowserReleaseResult, BrowserSource, BrowserStatus, CaptureCheckpointParams, CaptureCheckpointResult, BrowserDevicePresetName, BrowserEmulationOptions, ExtensionBrowserAction, GetApiSchemaParams, GetCookieParams, GetCookieResult, GetEventsParams, GetLogsParams, GetMocksParams, GetRequestsParams, GetUserInfoParams, ManagedBrowserAccount, ManagedBrowserInfo, PageClickParams, PageDragEndpoint, PageDragParams, PageDragPoint, PageActAction, PageDiagnosticsOptions, PageDiagnosticsSetting, PageEvalParams, PageFramesParams, PageHoverParams, PageNavigateParams, PageObservationWaitOptions, PagePressParams, PageScreenshotParams, PageScrollParams, PageSelectedElementParams, PageSnapshotParams, PageSnapshotQuery, PageTypeParams, PageUploadParams, PageWaitParams, RecordParams, RegularBrowserInfo, RequestDomainPermissionParams, RulesResult, RunActionName, RunActionsParams, SelectBrowserParams, SelectBrowserResult, SendRequestFile, SendRequestFormValue, SendMtopRequestParams, SendRequestParams, SetAppProfileParams, SetCookieParams, SetCookieResult, SetDeviceEmulationParams, SetMockParams, SetRuleParams, SetTimezoneParams, SetTimezoneResult, TabCloseParams, TabOpenParams, TdbankAccountParams, } from './generated-browser-action-protocol.js';
|
|
11
11
|
import { type UnifiedInvokeOptions } from './unified.js';
|
|
12
12
|
import type * as Protocol from './generated-browser-action-protocol.js';
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* then routes actions using the global browser ids returned by browser_list.
|
|
6
6
|
*/
|
|
7
7
|
export { UnifiedClient, UnifiedClient as MearlClient, decodeBrowserTarget, invoke, listCloudConnectors, } from './unified.js';
|
|
8
|
-
export { APP_PROFILE_NAMES, BROWSER_ACTIONS, BROWSER_COMMAND_ACTIONS, EXTENSION_BROWSER_ACTIONS, PAGE_ACT_ACTIONS, SEND_REQUEST_MAX_FILES, SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES, SEND_REQUEST_MAX_TOTAL_FILE_BYTES, isBrowserAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
|
|
8
|
+
export { APP_PROFILE_NAMES, BROWSER_DEVICE_PRESET_NAMES, BROWSER_ACTIONS, BROWSER_COMMAND_ACTIONS, EXTENSION_BROWSER_ACTIONS, PAGE_ACT_ACTIONS, SEND_REQUEST_MAX_FILES, SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES, SEND_REQUEST_MAX_TOTAL_FILE_BYTES, isBrowserAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
|
|
9
9
|
import { invoke } from './unified.js';
|
|
10
10
|
export function tabCheckpoint(params = {}, options) {
|
|
11
11
|
return invoke('tab_checkpoint', params, options);
|
package/dist/socket.js
CHANGED
|
@@ -11,6 +11,7 @@ import fs from 'node:fs';
|
|
|
11
11
|
import os from 'node:os';
|
|
12
12
|
import path from 'node:path';
|
|
13
13
|
import { createRequire } from 'node:module';
|
|
14
|
+
import { StringDecoder } from 'node:string_decoder';
|
|
14
15
|
import { resolveFileRefs } from './fileRefs.js';
|
|
15
16
|
import { listLiveBrowsers, findBrowser, describeBrowser } from './browserRegistry.js';
|
|
16
17
|
import { resolveActionTimeoutSec } from './actionTimeouts.js';
|
|
@@ -255,6 +256,7 @@ function invokeOnce(action, data, timeoutSec, transport, socketPath, controlSour
|
|
|
255
256
|
const socket = net.createConnection(socketPath);
|
|
256
257
|
let settled = false;
|
|
257
258
|
let buffer = '';
|
|
259
|
+
const decoder = new StringDecoder('utf8');
|
|
258
260
|
const settle = (error, result) => {
|
|
259
261
|
if (settled)
|
|
260
262
|
return;
|
|
@@ -283,7 +285,7 @@ function invokeOnce(action, data, timeoutSec, transport, socketPath, controlSour
|
|
|
283
285
|
socket.write(JSON.stringify(message) + '\n');
|
|
284
286
|
});
|
|
285
287
|
socket.on('data', chunk => {
|
|
286
|
-
buffer +=
|
|
288
|
+
buffer += decoder.write(chunk);
|
|
287
289
|
if (Buffer.byteLength(buffer, 'utf-8') > MAX_SOCKET_BUFFER_SIZE) {
|
|
288
290
|
settle(new Error(`Socket 响应超过 ${MAX_SOCKET_BUFFER_SIZE} 字节限制`));
|
|
289
291
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "Unified Mearl SDK & CLI for local and remote browsers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"commander": "^15.0.0",
|
|
56
56
|
"fastest-levenshtein": "^1.0.16",
|
|
57
57
|
"ws": "^8.18.0",
|
|
58
|
-
"@mearl/cloud-types": "2.
|
|
58
|
+
"@mearl/cloud-types": "2.11.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@types/node": "^24.9.1",
|