@mearl/client 3.0.0-beta.7 → 3.0.0-beta.8

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.
@@ -146,6 +146,7 @@ export async function loadPlugin(entry, context, pluginName) {
146
146
  let registering = true;
147
147
  let name;
148
148
  let description;
149
+ let defaultCommand;
149
150
  let toolbox;
150
151
  let pageRuntime;
151
152
  let stateStorage;
@@ -312,6 +313,9 @@ export async function loadPlugin(entry, context, pluginName) {
312
313
  if (module.description !== undefined && typeof module.description !== 'string')
313
314
  throw new Error('入口的 description 导出必须为字符串');
314
315
  description = module.description;
316
+ if (module.defaultCommand !== undefined && typeof module.defaultCommand !== 'string')
317
+ throw new Error('入口的 defaultCommand 导出必须为字符串');
318
+ defaultCommand = module.defaultCommand;
315
319
  toolbox = normalizePluginToolboxContribution(module.toolbox);
316
320
  pageRuntime = normalizePluginPageRuntime(module.pageRuntime);
317
321
  stateStorage = normalizePluginState(module.stateStorage);
@@ -326,6 +330,8 @@ export async function loadPlugin(entry, context, pluginName) {
326
330
  }
327
331
  if (commands.size === 0 && !appProfiles)
328
332
  throw new Error('入口未注册任何命令');
333
+ if (defaultCommand !== undefined && (!commands.has(defaultCommand) || commands.get(defaultCommand)?.toolboxOnly || commands.get(defaultCommand)?.runtimeOnly))
334
+ throw new Error('defaultCommand 必须指向公开命令');
329
335
  for (const command of Object.keys(taskRecovery?.commands ?? {})) {
330
336
  if (!commands.has(command) ||
331
337
  commands.get(command)?.runtimeOnly ||
@@ -401,12 +407,13 @@ export async function loadPlugin(entry, context, pluginName) {
401
407
  if (payload !== undefined && Object.keys(namedInput).length > 0) {
402
408
  throw new PluginError('PLUGIN_INVALID_INPUT', '插件业务选项与 --payload 调用不能混用');
403
409
  }
404
- if (payload !== undefined &&
405
- (!isObject(payload) || typeof payload.command !== 'string' || !isObject(payload.input))) {
410
+ const defaultPayload = defaultCommand && toolboxPage === false && isObject(payload) && !Object.hasOwn(payload, 'command');
411
+ if (payload !== undefined && !defaultPayload && !isPluginInvocation(payload)) {
406
412
  throw new PluginError('PLUGIN_INVALID_INPUT', '--payload 必须为 {"command":"...","input":{...}}');
407
413
  }
408
- const envelope = payload;
409
- const commandName = envelope?.command ?? positionals[0] ?? '';
414
+ const envelope = (defaultPayload ? { command: defaultCommand, input: payload } : payload);
415
+ const positionalOffset = defaultCommand && !commands.has(positionals[0]) && toolboxPage === false ? 0 : 1;
416
+ const commandName = envelope?.command ?? (positionalOffset === 0 ? defaultCommand : positionals[0] ?? '');
410
417
  const hidden = toolboxPage === 'recovery' || toolboxPage === 'migration';
411
418
  const selected = find(commandName, hidden ? false : toolboxPage);
412
419
  const command = selected.command;
@@ -426,7 +433,7 @@ export async function loadPlugin(entry, context, pluginName) {
426
433
  : Object.fromEntries(command.registeredArguments
427
434
  .map((argument, index) => [
428
435
  argument.name(),
429
- argument.variadic ? positionals.slice(index + 1) : positionals[index + 1],
436
+ argument.variadic ? positionals.slice(index + positionalOffset) : positionals[index + positionalOffset],
430
437
  ])
431
438
  .filter(([, value]) => value !== undefined));
432
439
  for (const name of Object.keys(namedInput)) {
@@ -437,7 +444,7 @@ export async function loadPlugin(entry, context, pluginName) {
437
444
  const input = { ...positionalInput, ...namedInput };
438
445
  if (!envelope &&
439
446
  !command.registeredArguments.some(argument => argument.variadic) &&
440
- positionals.length - 1 > command.registeredArguments.length) {
447
+ positionals.length - positionalOffset > command.registeredArguments.length) {
441
448
  throw new PluginError('PLUGIN_INVALID_INPUT', '位置参数过多');
442
449
  }
443
450
  for (const argument of hidden ? [] : command.registeredArguments) {
@@ -529,6 +536,7 @@ export async function loadPlugin(entry, context, pluginName) {
529
536
  return {
530
537
  name,
531
538
  description,
539
+ defaultCommand,
532
540
  toolbox,
533
541
  pageRuntime,
534
542
  stateStorage,
@@ -538,11 +546,11 @@ export async function loadPlugin(entry, context, pluginName) {
538
546
  version: readPluginVersion(entry),
539
547
  commandHelp(namespace) {
540
548
  return publicCommands()
541
- .map(({ command, signature }) => ` ${namespace} ${signature} ${command.description()}`)
549
+ .map(({ command, signature }) => ` ${namespace} ${command.name() === defaultCommand ? signature.slice(defaultCommand.length).trim() : signature} ${command.description()}`)
542
550
  .join('\n');
543
551
  },
544
552
  help(namespace, name) {
545
- const selected = name ? [find(name)] : publicCommands();
553
+ const selected = name ? [find(defaultCommand && !commands.has(name) ? defaultCommand : name)] : publicCommands();
546
554
  if (!selected.length) {
547
555
  const location = toolbox
548
556
  ? `请在 Mearl ${toolbox.displayMode === 'popup' ? 'Popup' : '工具箱'} 中打开「${toolbox.title}」使用。`
@@ -552,7 +560,7 @@ export async function loadPlugin(entry, context, pluginName) {
552
560
  const examples = selected.flatMap(({ examples }) => examples);
553
561
  return [
554
562
  '用法:',
555
- ...selected.map(({ command, signature }) => ` ${namespace} ${signature} ${command.description()}`),
563
+ ...selected.map(({ command, signature }) => ` ${namespace} ${command.name() === defaultCommand ? signature.slice(defaultCommand.length).trim() : signature} ${command.description()}`),
556
564
  ...(examples.length
557
565
  ? ['', '示例:', ...examples.map(example => ` ${namespace} ${example}`)]
558
566
  : []),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mearl/client",
3
- "version": "3.0.0-beta.7",
3
+ "version": "3.0.0-beta.8",
4
4
  "description": "Unified Mearl SDK & CLI for local and remote browsers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -67,11 +67,11 @@
67
67
  "commander": "^14.0.3",
68
68
  "fastest-levenshtein": "^1.0.16",
69
69
  "ws": "^8.18.0",
70
- "@mearl/daemon-core": "3.0.0-beta.7",
71
- "@mearl/cloud-types": "3.0.0-beta.7",
72
- "@mearl/provider": "3.0.0-beta.7",
73
- "@mearl/agent-runtime": "3.0.0-beta.7",
74
- "@mearl/browser-core": "3.0.0-beta.7"
70
+ "@mearl/daemon-core": "3.0.0-beta.8",
71
+ "@mearl/cloud-types": "3.0.0-beta.8",
72
+ "@mearl/provider": "3.0.0-beta.8",
73
+ "@mearl/agent-runtime": "3.0.0-beta.8",
74
+ "@mearl/browser-core": "3.0.0-beta.8"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@types/node": "^24.9.1",
@@ -84,7 +84,7 @@
84
84
  "directory": "packages/client"
85
85
  },
86
86
  "scripts": {
87
- "build": "rm -rf dist/ && tsc && chmod +x dist/bin.js",
87
+ "build": "rm -rf dist/ && tsc && node build-guides.mjs && chmod +x dist/bin.js",
88
88
  "dev": "tsc --watch",
89
89
  "typecheck": "tsc --noEmit",
90
90
  "test": "vitest run"