@mearl/client 2.16.3 → 2.17.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 -0
- package/dist/cli.js +21 -2
- package/dist/commands.d.ts +8 -4
- package/dist/commands.js +9 -2
- package/dist/generated-browser-action-protocol.d.ts +8 -1
- package/dist/plugin.d.ts +2 -0
- package/dist/plugin.js +5 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -143,6 +143,10 @@ mearl yuque --help
|
|
|
143
143
|
mearl yuque --version
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
+
当已注册插件与 Provider 使用同一名称时,`mearl <name> --help` 会先显示 Provider 的启动和生命周期说明,
|
|
147
|
+
再自动追加插件注册的扩展命令;`mearl <name> <command> --help` 继续显示单个插件命令的详细帮助。
|
|
148
|
+
Provider 与插件仍可独立安装、更新和卸载,帮助聚合不会启动 Provider 或执行业务命令。
|
|
149
|
+
|
|
146
150
|
目录默认使用 `scripts/main.mjs` 或 `scripts/main.py`;两者同时存在时使用 JavaScript 入口。JavaScript 入口默认导出 `register(app)`,Python 入口导出 `register(app)` 函数;两种入口都可声明简短的 `name` 和 `description`,并通过 `app.command(signature, handler, description?)`
|
|
147
151
|
注册动作、`app.invoke(action, payload, options?)` 复用当前浏览器上下文,并用 `app.progress(message)` 报告可选进度。Python 的 `app.invoke` 是同步调用,handler 可以是普通函数或 `async def`。Python 插件要求 `python3 >= 3.9`,可用 `MEARL_PYTHON` 指定解释器路径;Mearl 不安装 Python 或执行 `pip install`。调用另一个插件时,payload 使用 `{ command, input }` envelope;嵌套调用继承宿主选项并拒绝循环依赖。CLI 默认只输出最终结果,传入
|
|
148
152
|
`--verbose` 时才把进度写入 stderr。handler 返回文本或 JSON,宿主统一处理 `--output`、连接和错误。写命令在用户调用后直接执行,业务模块负责目标、状态、幂等和结果校验。
|
package/dist/cli.js
CHANGED
|
@@ -192,7 +192,7 @@ function providerSchemaLines(name, schema, required, indent = 2) {
|
|
|
192
192
|
}
|
|
193
193
|
return lines;
|
|
194
194
|
}
|
|
195
|
-
function printProviderHelp(commandName, provider) {
|
|
195
|
+
function printProviderHelp(commandName, provider, extensionHelp) {
|
|
196
196
|
const browserType = provider.browserType;
|
|
197
197
|
const lines = [
|
|
198
198
|
`${provider.providerId} — ${provider.name} v${provider.version}`,
|
|
@@ -230,8 +230,26 @@ function printProviderHelp(commandName, provider) {
|
|
|
230
230
|
if (browserType.documentationUrl) {
|
|
231
231
|
lines.push('', `文档:${browserType.documentationUrl}`);
|
|
232
232
|
}
|
|
233
|
+
if (extensionHelp) {
|
|
234
|
+
lines.push('', '扩展命令:', extensionHelp, '', `运行 ${commandName} ${provider.providerId} <command> --help 查看命令参数。`);
|
|
235
|
+
}
|
|
233
236
|
console.error(lines.join('\n'));
|
|
234
237
|
}
|
|
238
|
+
async function sameNamePluginHelp(commandName, name) {
|
|
239
|
+
try {
|
|
240
|
+
if (!findPluginEntry(name))
|
|
241
|
+
return undefined;
|
|
242
|
+
const plugin = await loadRegisteredPlugin(name, {
|
|
243
|
+
async invoke() {
|
|
244
|
+
throw new Error('生成插件帮助时不能调用宿主能力');
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
return plugin.commandHelp(`${commandName} ${name}`);
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
return ` (扩展命令帮助不可用:${error instanceof Error ? error.message : String(error)})`;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
235
253
|
function installedProvider(name) {
|
|
236
254
|
if (!name)
|
|
237
255
|
return undefined;
|
|
@@ -559,7 +577,8 @@ export async function runMearlCli(args, options = {}) {
|
|
|
559
577
|
const provider = installedProvider(args[0]);
|
|
560
578
|
if (provider &&
|
|
561
579
|
(args.length === 1 || args.slice(1).every(arg => arg === '--help' || arg === '-h'))) {
|
|
562
|
-
|
|
580
|
+
const extensionHelp = await sameNamePluginHelp(commandName, provider.providerId);
|
|
581
|
+
printProviderHelp(commandName, provider, extensionHelp);
|
|
563
582
|
return 0;
|
|
564
583
|
}
|
|
565
584
|
if (args[0] &&
|
package/dist/commands.d.ts
CHANGED
|
@@ -308,8 +308,8 @@ export declare const COMMANDS: readonly [{
|
|
|
308
308
|
readonly description: "签名使用的 appKey,默认 12574478";
|
|
309
309
|
}, {
|
|
310
310
|
readonly name: "env";
|
|
311
|
-
readonly type: "\"
|
|
312
|
-
readonly description: "请求环境,默认
|
|
311
|
+
readonly type: "\"prod\" | \"pre\"";
|
|
312
|
+
readonly description: "请求环境,默认 prod";
|
|
313
313
|
}, {
|
|
314
314
|
readonly name: "timeout";
|
|
315
315
|
readonly type: "number";
|
|
@@ -856,7 +856,7 @@ export declare const COMMANDS: readonly [{
|
|
|
856
856
|
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\":true,\"preset\":\"ipad-mini-a17-pro\",\"orientation\":\"landscape\",\"deviceShell\":true,\"splitScreen\":true}'", "set_device_emulation --payload '{\"enabled\":false}'"];
|
|
857
857
|
}, {
|
|
858
858
|
readonly name: "set_app_profile";
|
|
859
|
-
readonly description: "设置 App 客户端环境与 JSBridge
|
|
859
|
+
readonly description: "设置 App 客户端环境与 JSBridge;可同时设置 MTop 页面接口环境,传 emulation 时联动设备模拟";
|
|
860
860
|
readonly summary: "设置或清除目标标签页的 App 容器模拟";
|
|
861
861
|
readonly params: [{
|
|
862
862
|
readonly name: "enabled";
|
|
@@ -883,6 +883,10 @@ export declare const COMMANDS: readonly [{
|
|
|
883
883
|
readonly name: "bridgeConfig";
|
|
884
884
|
readonly type: "object";
|
|
885
885
|
readonly description: "声明式覆盖桥方法,形如 {methods:{api:{behavior|response|noop,silent?}}};不执行配置脚本";
|
|
886
|
+
}, {
|
|
887
|
+
readonly name: "mtopEnv";
|
|
888
|
+
readonly type: "\"default\" | \"prod\" | \"pre\"";
|
|
889
|
+
readonly description: "可选 MTop 页面接口环境;default 关闭环境改写,省略时保持当前设置。扩展模式全局生效,CDP 模式仅作用于目标 tab";
|
|
886
890
|
}, {
|
|
887
891
|
readonly name: "emulation";
|
|
888
892
|
readonly type: "object";
|
|
@@ -897,7 +901,7 @@ export declare const COMMANDS: readonly [{
|
|
|
897
901
|
readonly required: true;
|
|
898
902
|
readonly description: "目标标签页 ID";
|
|
899
903
|
}];
|
|
900
|
-
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\":true,\"profile\":\"fliggy\",\"emulation\":{\"preset\":\"ipad-mini-a17-pro\",\"orientation\":\"landscape\",\"deviceShell\":true,\"splitScreen\":true}}'", "set_app_profile --payload '{\"enabled\":false}'", "set_app_profile --payload '{\"enabled\":false,\"emulation\":{}}'"];
|
|
904
|
+
readonly examples: ["set_app_profile --payload '{\"enabled\":true,\"profile\":\"fliggy\"}'", "set_app_profile --payload '{\"enabled\":true,\"profile\":\"fliggy\",\"mtopEnv\":\"pre\"}'", "set_app_profile --payload '{\"enabled\":false,\"mtopEnv\":\"prod\"}'", "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\":true,\"profile\":\"fliggy\",\"emulation\":{\"preset\":\"ipad-mini-a17-pro\",\"orientation\":\"landscape\",\"deviceShell\":true,\"splitScreen\":true}}'", "set_app_profile --payload '{\"enabled\":false}'", "set_app_profile --payload '{\"enabled\":false,\"emulation\":{}}'"];
|
|
901
905
|
}, {
|
|
902
906
|
readonly name: "set_timezone";
|
|
903
907
|
readonly description: "覆盖目标 tab 的时区,传空字符串恢复浏览器默认时区";
|
package/dist/commands.js
CHANGED
|
@@ -214,7 +214,7 @@ export const COMMANDS = [
|
|
|
214
214
|
{ name: 'version', type: 'string', description: 'API 版本,默认 1.0' },
|
|
215
215
|
{ name: 'method', type: 'string', description: 'HTTP 方法,默认 GET' },
|
|
216
216
|
{ name: 'appKey', type: 'string', description: '签名使用的 appKey,默认 12574478' },
|
|
217
|
-
{ name: 'env', type: '"
|
|
217
|
+
{ name: 'env', type: '"prod" | "pre"', description: '请求环境,默认 prod' },
|
|
218
218
|
{ name: 'timeout', type: 'number', description: '超时毫秒数,默认 10000' },
|
|
219
219
|
],
|
|
220
220
|
examples: [
|
|
@@ -794,7 +794,7 @@ export const COMMANDS = [
|
|
|
794
794
|
},
|
|
795
795
|
{
|
|
796
796
|
name: 'set_app_profile',
|
|
797
|
-
description: '设置 App 客户端环境与 JSBridge
|
|
797
|
+
description: '设置 App 客户端环境与 JSBridge;可同时设置 MTop 页面接口环境,传 emulation 时联动设备模拟',
|
|
798
798
|
summary: '设置或清除目标标签页的 App 容器模拟',
|
|
799
799
|
params: [
|
|
800
800
|
{ name: 'enabled', type: 'boolean', required: true, description: 'true=启用,false=清除' },
|
|
@@ -815,6 +815,11 @@ export const COMMANDS = [
|
|
|
815
815
|
type: 'object',
|
|
816
816
|
description: '声明式覆盖桥方法,形如 {methods:{api:{behavior|response|noop,silent?}}};不执行配置脚本',
|
|
817
817
|
},
|
|
818
|
+
{
|
|
819
|
+
name: 'mtopEnv',
|
|
820
|
+
type: '"default" | "prod" | "pre"',
|
|
821
|
+
description: '可选 MTop 页面接口环境;default 关闭环境改写,省略时保持当前设置。扩展模式全局生效,CDP 模式仅作用于目标 tab',
|
|
822
|
+
},
|
|
818
823
|
{
|
|
819
824
|
name: 'emulation',
|
|
820
825
|
type: 'object',
|
|
@@ -825,6 +830,8 @@ export const COMMANDS = [
|
|
|
825
830
|
],
|
|
826
831
|
examples: [
|
|
827
832
|
`set_app_profile --payload '{"enabled":true,"profile":"fliggy"}'`,
|
|
833
|
+
`set_app_profile --payload '{"enabled":true,"profile":"fliggy","mtopEnv":"pre"}'`,
|
|
834
|
+
`set_app_profile --payload '{"enabled":false,"mtopEnv":"prod"}'`,
|
|
828
835
|
`set_app_profile --payload '{"enabled":true,"profile":"fliggy","emulation":{}}'`,
|
|
829
836
|
`set_app_profile --payload '{"enabled":true,"profile":"alipay","emulation":{"preset":"pixel-11","deviceShell":true}}'`,
|
|
830
837
|
`set_app_profile --payload '{"enabled":true,"profile":"fliggy","emulation":{"preset":"ipad-mini-a17-pro","orientation":"landscape","deviceShell":true,"splitScreen":true}}'`,
|
|
@@ -95,13 +95,15 @@ export interface SendRequestParams {
|
|
|
95
95
|
responseType?: 'json' | 'text' | 'auto';
|
|
96
96
|
timeout?: number;
|
|
97
97
|
}
|
|
98
|
+
export type MtopEnvironmentTarget = 'prod' | 'pre';
|
|
99
|
+
export type MtopEnvironment = 'default' | MtopEnvironmentTarget;
|
|
98
100
|
export interface SendMtopRequestParams {
|
|
99
101
|
api: string;
|
|
100
102
|
data?: unknown;
|
|
101
103
|
version?: string;
|
|
102
104
|
method?: string;
|
|
103
105
|
appKey?: string;
|
|
104
|
-
env?:
|
|
106
|
+
env?: MtopEnvironmentTarget;
|
|
105
107
|
timeout?: number;
|
|
106
108
|
headers?: Record<string, string>;
|
|
107
109
|
ttid?: string;
|
|
@@ -427,6 +429,11 @@ export interface SetAppProfileParams {
|
|
|
427
429
|
deviceModel?: string;
|
|
428
430
|
/** 按方法覆盖档案内置桥配置,仅支持受控行为、固定 JSON 回包和成功空实现 */
|
|
429
431
|
bridgeConfig?: AppBridgeConfig;
|
|
432
|
+
/**
|
|
433
|
+
* 可选 MTop 接口环境。default 关闭环境改写;省略时保持当前设置。
|
|
434
|
+
* 扩展模式与插件设置页共享并全局生效;CDP 模式仅作用于目标 tab。
|
|
435
|
+
*/
|
|
436
|
+
mtopEnv?: MtopEnvironment;
|
|
430
437
|
/**
|
|
431
438
|
* 可选设备联动参数。传入时显式字段覆盖档案推荐设备,空对象使用推荐设备且默认开启
|
|
432
439
|
* deviceShell;省略时不设置或清除该 tab 的设备状态。
|
package/dist/plugin.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare function loadPlugin(entry: string, context: Pick<PluginApp, 'invo
|
|
|
26
26
|
name: string | undefined;
|
|
27
27
|
description: string | undefined;
|
|
28
28
|
version: string | undefined;
|
|
29
|
+
commandHelp(namespace: string): string;
|
|
29
30
|
help(namespace: string, name?: string): string;
|
|
30
31
|
run(positionals: string[], payload?: unknown, namedInput?: Record<string, unknown>): Promise<unknown>;
|
|
31
32
|
}>;
|
|
@@ -33,6 +34,7 @@ export declare function loadRegisteredPlugin(name: string, context: PluginExecut
|
|
|
33
34
|
name: string | undefined;
|
|
34
35
|
description: string | undefined;
|
|
35
36
|
version: string | undefined;
|
|
37
|
+
commandHelp(namespace: string): string;
|
|
36
38
|
help(namespace: string, name?: string): string;
|
|
37
39
|
run(positionals: string[], payload?: unknown, namedInput?: Record<string, unknown>): Promise<unknown>;
|
|
38
40
|
}>;
|
package/dist/plugin.js
CHANGED
|
@@ -131,6 +131,11 @@ export async function loadPlugin(entry, context, pluginName) {
|
|
|
131
131
|
name,
|
|
132
132
|
description,
|
|
133
133
|
version: readPluginVersion(entry),
|
|
134
|
+
commandHelp(namespace) {
|
|
135
|
+
return [...commands.values()]
|
|
136
|
+
.map(({ command, signature }) => ` ${namespace} ${signature} ${command.description()}`)
|
|
137
|
+
.join('\n');
|
|
138
|
+
},
|
|
134
139
|
help(namespace, name) {
|
|
135
140
|
const selected = name ? [find(name)] : [...commands.values()];
|
|
136
141
|
const example = selected[0].command;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.0",
|
|
4
4
|
"description": "Unified Mearl SDK & CLI for local and remote browsers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"commander": "^15.0.0",
|
|
60
60
|
"fastest-levenshtein": "^1.0.16",
|
|
61
61
|
"ws": "^8.18.0",
|
|
62
|
-
"@mearl/
|
|
63
|
-
"@mearl/
|
|
62
|
+
"@mearl/provider": "2.17.0",
|
|
63
|
+
"@mearl/cloud-types": "2.17.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@types/node": "^24.9.1",
|