@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 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
- printProviderHelp(commandName, provider);
580
+ const extensionHelp = await sameNamePluginHelp(commandName, provider.providerId);
581
+ printProviderHelp(commandName, provider, extensionHelp);
563
582
  return 0;
564
583
  }
565
584
  if (args[0] &&
@@ -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: "\"online\" | \"pre\"";
312
- readonly description: "请求环境,默认 online";
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;传 emulation 时由同一个命令联动设备模拟,省略时不改变设备状态";
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: '"online" | "pre"', description: '请求环境,默认 online' },
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;传 emulation 时由同一个命令联动设备模拟,省略时不改变设备状态',
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?: string;
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.16.3",
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/cloud-types": "2.16.3",
63
- "@mearl/provider": "2.16.3"
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",