@mearl/client 2.16.0 → 2.16.2
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 +9 -6
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +46 -12
- package/dist/commands.d.ts +0 -19
- package/dist/commands.js +0 -14
- package/dist/generated-browser-action-protocol.d.ts +0 -17
- package/dist/generated-browser-action-protocol.js +0 -6
- package/dist/index.d.ts +1 -1
- package/dist/officialPluginCatalog.d.ts +0 -55
- package/dist/officialPluginCatalog.js +0 -55
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.js +13 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -153,8 +153,11 @@ setup 会补齐缺失或低于自身版本的 client、native-host;安装参
|
|
|
153
153
|
退出码为 0 表示插件已注册且入口可加载,stdout 返回同目录 `SKILL.md` 的版本,缺少版本元数据时返回 `unknown`。
|
|
154
154
|
未注册、入口丢失或加载失败会以退出码 2 和对应的 `PLUGIN_*` 错误结束。普通业务调用无需预先检查,直接处理同样的错误即可。
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
插件接受位置参数、字符串业务选项或包含 command/input 的 `--payload`。业务选项推荐写成
|
|
157
|
+
`--name=value`,也接受 `--name value`,字段名与 handler 的 input 一致且不依赖位置顺序;同一字段不能同时
|
|
158
|
+
使用位置参数和业务选项,`--payload` 不能与前两种形式混用。JSON 保留业务字段类型;正文等文件输入按具体
|
|
159
|
+
skill 的字段约定处理。`browser`、`timeout`、`output` 等宿主选项保留原有含义;同名业务字段以及数字、
|
|
160
|
+
布尔值、对象和数组通过 `--payload` 传入。插件不使用上表中内置 action 的 `--payload-file` 入口。
|
|
158
161
|
|
|
159
162
|
注册后的插件也可从 SDK 调用;实例方法 `client.invokePlugin` 复用既有连接和默认浏览器:
|
|
160
163
|
|
|
@@ -168,7 +171,7 @@ const result = await invokePlugin(
|
|
|
168
171
|
);
|
|
169
172
|
```
|
|
170
173
|
|
|
171
|
-
MCP Server 通过固定工具 `mearl_plugin` 接受同样的 `plugin`、`command` 和 `input`,不会把插件子命令动态扩展成 MCP 工具。SDK 与 MCP
|
|
174
|
+
MCP Server 通过固定工具 `mearl_plugin` 接受同样的 `plugin`、`command` 和 `input`,不会把插件子命令动态扩展成 MCP 工具。SDK 与 MCP 不接受任意入口路径;调用尚未注册的 `buc` 或 `tdbank` 时,会通过匹配当前 client 版本的 setup 自动安装并重试一次。其他未注册名称返回 `PLUGIN_NOT_REGISTERED`。
|
|
172
175
|
|
|
173
176
|
注册记录在 `~/.mearl/plugins/<name>.json`,保存入口路径和可选的简短描述;skill 业务代码原地更新直接生效,换路径或更新描述后重新注册。
|
|
174
177
|
`plugin uninstall <name>` 会对 `~/.agents/skills` 中的全局 Skill 调用 `ali-skills remove --global --yes`,
|
|
@@ -180,8 +183,9 @@ MCP Server 通过固定工具 `mearl_plugin` 接受同样的 `plugin`、`command
|
|
|
180
183
|
|
|
181
184
|
需要 BUC 身份的内部 HTTP 接口通过官方 `buc` 插件调用。CLI 使用 `mearl buc request`,业务插件使用
|
|
182
185
|
`app.invoke('buc', { command: 'request', input })`;当前身份和人员资料分别使用 `whoami` 与 `profile`
|
|
183
|
-
子命令。BUC
|
|
184
|
-
|
|
186
|
+
子命令。BUC 插件按请求创建一次性凭据,只接受无 URL 凭据的 HTTPS 地址,过滤认证字段与 Cookie;
|
|
187
|
+
调用方须按已验证的业务契约确认目标服务可信。请求始终在运行 CLI、SDK 或 MCP Server 的机器上执行,
|
|
188
|
+
不随浏览器或 connector 转发。
|
|
185
189
|
`buc request` 支持与 `send_request` 同结构的 `formData` 和 `files`;`files[].filePath` 从该插件执行
|
|
186
190
|
宿主读取,而不是浏览器 native-host,无法引用宿主路径时使用 Base64 内容与 `filename`。
|
|
187
191
|
|
|
@@ -197,7 +201,6 @@ Cookie,并始终在运行 CLI、SDK 或 MCP Server 的机器上执行,不随
|
|
|
197
201
|
| 组合调用 | `run_actions` |
|
|
198
202
|
| 页面感知 | `page_snapshot` `page_screenshot` `page_selected_element` `page_frames` |
|
|
199
203
|
| 环境与 Cookie | `set_device_emulation` `set_app_profile` `set_timezone` `get_cookie` `set_cookie` |
|
|
200
|
-
| 录制 | `record_start` `record_stop` |
|
|
201
204
|
| 浏览器 | `browser_list` `browser_release` `browser_launch` `browser_close` |
|
|
202
205
|
|
|
203
206
|
页面交互动作(`page_click` / `page_drag` / `page_type` / `page_hover` / `page_scroll` / `page_press` / `page_upload`)默认等待异步稳定并返回 `{ action, observation }`。参数、ref 或目标解析在派发前失败时返回 `action.stage: "precondition"`,省略无意义的 `observation` / `diagnostics`,CLI 退出码为 1。传 `observe: false` 可执行裸动作;需要同一动作期间的新增 error logs 和业务 requests 时传 `diagnostics: true`,埋点通过 `diagnostics.events` 按需开启。`page_eval` 默认裸执行,可按需开启观察或诊断。
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -46,7 +46,6 @@ const CATEGORIES = [
|
|
|
46
46
|
title: '环境与 Cookie',
|
|
47
47
|
names: ['set_device_emulation', 'set_app_profile', 'set_timezone', 'get_cookie', 'set_cookie'],
|
|
48
48
|
},
|
|
49
|
-
{ title: '录制', names: ['record_start', 'record_stop'] },
|
|
50
49
|
{
|
|
51
50
|
title: '浏览器',
|
|
52
51
|
names: ['browser_list', 'browser_release', 'browser_launch', 'browser_close'],
|
|
@@ -59,7 +58,7 @@ const BUILTIN_COMMANDS = [
|
|
|
59
58
|
examples: ['check'],
|
|
60
59
|
},
|
|
61
60
|
];
|
|
62
|
-
const
|
|
61
|
+
const AUTO_INSTALL_PLUGIN_COMMANDS = listOfficialPluginNames().map(name => ({
|
|
63
62
|
name,
|
|
64
63
|
description: findOfficialPlugin(name).description,
|
|
65
64
|
examples: [name],
|
|
@@ -67,9 +66,42 @@ const OFFICIAL_PLUGIN_COMMANDS = listOfficialPluginNames().map(name => ({
|
|
|
67
66
|
const SUGGESTABLE_COMMANDS = [
|
|
68
67
|
...COMMANDS,
|
|
69
68
|
...BUILTIN_COMMANDS,
|
|
70
|
-
...
|
|
69
|
+
...AUTO_INSTALL_PLUGIN_COMMANDS,
|
|
71
70
|
];
|
|
72
71
|
const ADVANCED_BUILTIN_COMMANDS = new Set(['connector_list']);
|
|
72
|
+
const PLUGIN_HOST_OPTIONS = new Set([
|
|
73
|
+
'--browser',
|
|
74
|
+
'--cdp',
|
|
75
|
+
'--compact',
|
|
76
|
+
'--connector',
|
|
77
|
+
'--help',
|
|
78
|
+
'--json',
|
|
79
|
+
'--local',
|
|
80
|
+
'--output',
|
|
81
|
+
'--payload',
|
|
82
|
+
'--payload-file',
|
|
83
|
+
'--server',
|
|
84
|
+
'--timeout',
|
|
85
|
+
'--verbose',
|
|
86
|
+
'--version',
|
|
87
|
+
]);
|
|
88
|
+
function findPluginInputOptionNames(args) {
|
|
89
|
+
const names = new Set();
|
|
90
|
+
for (const argument of args) {
|
|
91
|
+
if (!argument.startsWith('--') || argument === '--')
|
|
92
|
+
continue;
|
|
93
|
+
const equals = argument.indexOf('=');
|
|
94
|
+
const option = equals === -1 ? argument : argument.slice(0, equals);
|
|
95
|
+
if (PLUGIN_HOST_OPTIONS.has(option))
|
|
96
|
+
continue;
|
|
97
|
+
const name = option.slice(2);
|
|
98
|
+
if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(name)) {
|
|
99
|
+
throw new Error(`无效的插件业务选项: ${option}`);
|
|
100
|
+
}
|
|
101
|
+
names.add(name);
|
|
102
|
+
}
|
|
103
|
+
return [...names];
|
|
104
|
+
}
|
|
73
105
|
function printUsage(commandName, version) {
|
|
74
106
|
const lines = [
|
|
75
107
|
`${commandName} v${version}`,
|
|
@@ -122,14 +154,6 @@ function printUsage(commandName, version) {
|
|
|
122
154
|
});
|
|
123
155
|
lines.push('', '已注册插件:', ...entries);
|
|
124
156
|
}
|
|
125
|
-
const installed = new Set(plugins);
|
|
126
|
-
const available = listOfficialPluginNames().filter(name => !installed.has(name));
|
|
127
|
-
if (available.length) {
|
|
128
|
-
lines.push('', '官方插件(首次调用自动安装):', ...available.map(name => {
|
|
129
|
-
const description = findOfficialPlugin(name).description;
|
|
130
|
-
return ` ${name.padEnd(TOP_LEVEL_COMMAND_NAME_WIDTH)}${description}`;
|
|
131
|
-
}));
|
|
132
|
-
}
|
|
133
157
|
}
|
|
134
158
|
catch (error) {
|
|
135
159
|
lines.push('', error instanceof Error ? error.message : String(error));
|
|
@@ -355,6 +379,7 @@ function actionInvocationFailed(action, result) {
|
|
|
355
379
|
: false;
|
|
356
380
|
}
|
|
357
381
|
export function parseClientArgs(args, plugin = false) {
|
|
382
|
+
const pluginInputOptionNames = plugin ? findPluginInputOptionNames(args) : [];
|
|
358
383
|
const program = new Command()
|
|
359
384
|
.name('mearl')
|
|
360
385
|
.helpOption(false)
|
|
@@ -379,6 +404,8 @@ export function parseClientArgs(args, plugin = false) {
|
|
|
379
404
|
.option('-h, --help')
|
|
380
405
|
.option('-v, --version')
|
|
381
406
|
.option('--verbose');
|
|
407
|
+
for (const name of pluginInputOptionNames)
|
|
408
|
+
program.option(`--${name} <value>`);
|
|
382
409
|
try {
|
|
383
410
|
program.parse(['node', 'mearl', ...args]);
|
|
384
411
|
}
|
|
@@ -393,6 +420,12 @@ export function parseClientArgs(args, plugin = false) {
|
|
|
393
420
|
if (plugin && options.payloadFile !== undefined) {
|
|
394
421
|
throw new Error('插件使用 --payload 传入 command 和 input;正文文件可由业务字段引用');
|
|
395
422
|
}
|
|
423
|
+
const pluginInput = Object.fromEntries(pluginInputOptionNames
|
|
424
|
+
.filter(name => Object.hasOwn(options, name))
|
|
425
|
+
.map(name => [name, options[name]]));
|
|
426
|
+
if (plugin && options.payload !== undefined && Object.keys(pluginInput).length > 0) {
|
|
427
|
+
throw new Error('插件业务选项不能与 --payload 同时使用');
|
|
428
|
+
}
|
|
396
429
|
const json = options.json === true;
|
|
397
430
|
if (json && action !== 'check')
|
|
398
431
|
throw new Error('--json 仅适用于 check');
|
|
@@ -420,6 +453,7 @@ export function parseClientArgs(args, plugin = false) {
|
|
|
420
453
|
...(plugin
|
|
421
454
|
? {
|
|
422
455
|
pluginArgs: program.processedArgs[1],
|
|
456
|
+
...(Object.keys(pluginInput).length > 0 ? { pluginInput } : {}),
|
|
423
457
|
help: options.help === true,
|
|
424
458
|
version: options.version === true,
|
|
425
459
|
verbose: options.verbose === true,
|
|
@@ -471,7 +505,7 @@ async function runPluginCli(args, commandName) {
|
|
|
471
505
|
console.error(plugin.help(`${commandName} ${parsed.action}`, parsed.pluginArgs?.[0]));
|
|
472
506
|
return 0;
|
|
473
507
|
}
|
|
474
|
-
const result = await plugin.run(parsed.pluginArgs ?? [], parsed.hasPayload ? parsed.payload : undefined);
|
|
508
|
+
const result = await plugin.run(parsed.pluginArgs ?? [], parsed.hasPayload ? parsed.payload : undefined, parsed.pluginInput);
|
|
475
509
|
if (result !== undefined) {
|
|
476
510
|
if (parsed.outputPath)
|
|
477
511
|
writeOutput('', result, parsed.outputPath);
|
package/dist/commands.d.ts
CHANGED
|
@@ -790,25 +790,6 @@ export declare const COMMANDS: readonly [{
|
|
|
790
790
|
readonly description: "目标标签页 ID";
|
|
791
791
|
}];
|
|
792
792
|
readonly examples: ["page_selected_element", "page_selected_element --output ./element.png"];
|
|
793
|
-
}, {
|
|
794
|
-
readonly name: "record_start";
|
|
795
|
-
readonly description: "开始录制用户操作";
|
|
796
|
-
readonly params: [{
|
|
797
|
-
readonly name: "tabId";
|
|
798
|
-
readonly type: "number";
|
|
799
|
-
readonly description: "目标标签页 ID,从 tab_list 获取";
|
|
800
|
-
}];
|
|
801
|
-
readonly examples: ["record_start"];
|
|
802
|
-
}, {
|
|
803
|
-
readonly name: "record_stop";
|
|
804
|
-
readonly description: "停止录制并返回完整结果(操作 + 关联请求);未在录制时不报错,返回 wasRecording: false";
|
|
805
|
-
readonly summary: "停止录制并返回操作和关联请求";
|
|
806
|
-
readonly params: [{
|
|
807
|
-
readonly name: "tabId";
|
|
808
|
-
readonly type: "number";
|
|
809
|
-
readonly description: "目标标签页 ID,从 tab_list 获取";
|
|
810
|
-
}];
|
|
811
|
-
readonly examples: ["record_stop"];
|
|
812
793
|
}, {
|
|
813
794
|
readonly name: "set_device_emulation";
|
|
814
795
|
readonly description: "把目标 tab 切换为移动端模拟(视口/DPR/UA/触摸/视觉比例),等价 DevTools 设备工具栏,作用域 per-tab;需保持调试控制才持续生效";
|
package/dist/commands.js
CHANGED
|
@@ -740,20 +740,6 @@ export const COMMANDS = [
|
|
|
740
740
|
],
|
|
741
741
|
examples: ['page_selected_element', 'page_selected_element --output ./element.png'],
|
|
742
742
|
},
|
|
743
|
-
// ── 录制 ──────────────────────────────────────────────────────────────────
|
|
744
|
-
{
|
|
745
|
-
name: 'record_start',
|
|
746
|
-
description: '开始录制用户操作',
|
|
747
|
-
params: [{ name: 'tabId', type: 'number', description: '目标标签页 ID,从 tab_list 获取' }],
|
|
748
|
-
examples: ['record_start'],
|
|
749
|
-
},
|
|
750
|
-
{
|
|
751
|
-
name: 'record_stop',
|
|
752
|
-
description: '停止录制并返回完整结果(操作 + 关联请求);未在录制时不报错,返回 wasRecording: false',
|
|
753
|
-
summary: '停止录制并返回操作和关联请求',
|
|
754
|
-
params: [{ name: 'tabId', type: 'number', description: '目标标签页 ID,从 tab_list 获取' }],
|
|
755
|
-
examples: ['record_stop'],
|
|
756
|
-
},
|
|
757
743
|
// ── 移动端模拟 ────────────────────────────────────────────────────────────
|
|
758
744
|
{
|
|
759
745
|
name: 'set_device_emulation',
|
|
@@ -610,9 +610,6 @@ export interface SetCookieResult {
|
|
|
610
610
|
path: string;
|
|
611
611
|
reloaded: boolean;
|
|
612
612
|
}
|
|
613
|
-
export interface RecordParams {
|
|
614
|
-
tabId?: number;
|
|
615
|
-
}
|
|
616
613
|
export interface RequestDomainPermissionParams {
|
|
617
614
|
domain: string;
|
|
618
615
|
}
|
|
@@ -779,14 +776,6 @@ export interface BrowserActionMap {
|
|
|
779
776
|
request: SetCookieParams;
|
|
780
777
|
response: SetCookieResult;
|
|
781
778
|
};
|
|
782
|
-
record_start: {
|
|
783
|
-
request: RecordParams;
|
|
784
|
-
response: unknown;
|
|
785
|
-
};
|
|
786
|
-
record_stop: {
|
|
787
|
-
request: RecordParams;
|
|
788
|
-
response: unknown;
|
|
789
|
-
};
|
|
790
779
|
request_domain_permission: {
|
|
791
780
|
request: RequestDomainPermissionParams;
|
|
792
781
|
response: unknown;
|
|
@@ -842,8 +831,6 @@ export declare const BROWSER_ACTIONS: {
|
|
|
842
831
|
readonly set_timezone: true;
|
|
843
832
|
readonly get_cookie: true;
|
|
844
833
|
readonly set_cookie: true;
|
|
845
|
-
readonly record_start: true;
|
|
846
|
-
readonly record_stop: true;
|
|
847
834
|
readonly request_domain_permission: true;
|
|
848
835
|
readonly run_actions: true;
|
|
849
836
|
};
|
|
@@ -885,8 +872,6 @@ export declare const BROWSER_COMMAND_ACTIONS: {
|
|
|
885
872
|
readonly set_timezone: true;
|
|
886
873
|
readonly get_cookie: true;
|
|
887
874
|
readonly set_cookie: true;
|
|
888
|
-
readonly record_start: true;
|
|
889
|
-
readonly record_stop: true;
|
|
890
875
|
readonly request_domain_permission: true;
|
|
891
876
|
readonly run_actions: true;
|
|
892
877
|
};
|
|
@@ -925,8 +910,6 @@ export declare const EXTENSION_BROWSER_ACTIONS: {
|
|
|
925
910
|
readonly set_timezone: true;
|
|
926
911
|
readonly get_cookie: true;
|
|
927
912
|
readonly set_cookie: true;
|
|
928
|
-
readonly record_start: true;
|
|
929
|
-
readonly record_stop: true;
|
|
930
913
|
readonly request_domain_permission: true;
|
|
931
914
|
readonly run_actions: true;
|
|
932
915
|
};
|
|
@@ -97,8 +97,6 @@ export const BROWSER_ACTIONS = {
|
|
|
97
97
|
set_timezone: true,
|
|
98
98
|
get_cookie: true,
|
|
99
99
|
set_cookie: true,
|
|
100
|
-
record_start: true,
|
|
101
|
-
record_stop: true,
|
|
102
100
|
request_domain_permission: true,
|
|
103
101
|
run_actions: true,
|
|
104
102
|
};
|
|
@@ -140,8 +138,6 @@ export const BROWSER_COMMAND_ACTIONS = {
|
|
|
140
138
|
set_timezone: true,
|
|
141
139
|
get_cookie: true,
|
|
142
140
|
set_cookie: true,
|
|
143
|
-
record_start: true,
|
|
144
|
-
record_stop: true,
|
|
145
141
|
request_domain_permission: true,
|
|
146
142
|
run_actions: true,
|
|
147
143
|
};
|
|
@@ -180,8 +176,6 @@ export const EXTENSION_BROWSER_ACTIONS = {
|
|
|
180
176
|
set_timezone: true,
|
|
181
177
|
get_cookie: true,
|
|
182
178
|
set_cookie: true,
|
|
183
|
-
record_start: true,
|
|
184
|
-
record_stop: true,
|
|
185
179
|
request_domain_permission: true,
|
|
186
180
|
run_actions: true,
|
|
187
181
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { UnifiedClient, UnifiedClient as MearlClient, decodeBrowserTarget, invok
|
|
|
8
8
|
export type { UnifiedClientOptions, UnifiedInvokeOptions, UnifiedInvokeOptions as InvokeOptions, } from './unified.js';
|
|
9
9
|
export type { PluginInvocation, PluginInvokeOptions } from './plugin.js';
|
|
10
10
|
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, isBrowserCapabilityAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
|
|
11
|
-
export type { ActionStep, AppProfileName, BrowserAction, BrowserActionMap, BrowserActionRequest, BrowserActionResponse, BrowserCapabilities, BrowserCapabilityAction, BrowserCloseParams, BrowserCommandAction, BrowserInfo, BrowserInfoBase, BrowserJsonValue, BrowserLaunchParams, BrowserProviderOperation, BrowserListResult, BrowserPairingInfo, BrowserReleaseFailure, BrowserReleaseResult, BrowserProviderDefinition, BrowserProviderIdentity, BrowserProviderInputSchema, BrowserProviderListResult, BrowserReference, BrowserDetails, BrowserSource, BrowserStatus, BrowserScreenshotKind, BrowserTransport, CaptureCheckpointParams, CaptureCheckpointResult, BrowserDevicePresetName, BrowserEmulationOptions, ExtensionBrowserAction, GetCookieParams, GetCookieResult, GetEventsParams, GetLogsParams, GetMocksParams, GetRequestsParams, ManagedBrowserInfo, PageClickParams, PageDragEndpoint, PageDragParams, PageDragPoint, PageActAction, PageDiagnosticsOptions, PageDiagnosticsSetting, PageEvalParams, PageFramesParams, PageHoverParams, PageNavigateParams, PageObservationWaitOptions, PagePressParams, PageScreenshotParams, PageScrollParams, PageSelectedElementParams, PageSnapshotParams, PageSnapshotQuery, PageTypeParams, PageUploadParams, PageWaitParams,
|
|
11
|
+
export type { ActionStep, AppProfileName, BrowserAction, BrowserActionMap, BrowserActionRequest, BrowserActionResponse, BrowserCapabilities, BrowserCapabilityAction, BrowserCloseParams, BrowserCommandAction, BrowserInfo, BrowserInfoBase, BrowserJsonValue, BrowserLaunchParams, BrowserProviderOperation, BrowserListResult, BrowserPairingInfo, BrowserReleaseFailure, BrowserReleaseResult, BrowserProviderDefinition, BrowserProviderIdentity, BrowserProviderInputSchema, BrowserProviderListResult, BrowserReference, BrowserDetails, BrowserSource, BrowserStatus, BrowserScreenshotKind, BrowserTransport, CaptureCheckpointParams, CaptureCheckpointResult, BrowserDevicePresetName, BrowserEmulationOptions, ExtensionBrowserAction, GetCookieParams, GetCookieResult, GetEventsParams, GetLogsParams, GetMocksParams, GetRequestsParams, ManagedBrowserInfo, PageClickParams, PageDragEndpoint, PageDragParams, PageDragPoint, PageActAction, PageDiagnosticsOptions, PageDiagnosticsSetting, PageEvalParams, PageFramesParams, PageHoverParams, PageNavigateParams, PageObservationWaitOptions, PagePressParams, PageScreenshotParams, PageScrollParams, PageSelectedElementParams, PageSnapshotParams, PageSnapshotQuery, PageTypeParams, PageUploadParams, PageWaitParams, RegularBrowserInfo, RequestDomainPermissionParams, RulesResult, RunActionName, RunActionsParams, SelectBrowserParams, SelectBrowserResult, SendRequestFile, SendRequestFormValue, SendMtopRequestParams, SendRequestParams, SetAppProfileParams, SetCookieParams, SetCookieResult, SetDeviceEmulationParams, SetMockParams, SetRuleParams, SetTimezoneParams, SetTimezoneResult, TabCloseParams, TabOpenParams, } from './generated-browser-action-protocol.js';
|
|
12
12
|
import { type UnifiedInvokeOptions } from './unified.js';
|
|
13
13
|
import type * as Protocol from './generated-browser-action-protocol.js';
|
|
14
14
|
export declare function tabCheckpoint(params?: Protocol.CaptureCheckpointParams, options?: UnifiedInvokeOptions): Promise<Protocol.BrowserActionResponse<'tab_checkpoint'>>;
|
|
@@ -18,61 +18,6 @@ export declare const OFFICIAL_PLUGINS: {
|
|
|
18
18
|
readonly setup: "alibaba";
|
|
19
19
|
readonly skill: "tdbank-account";
|
|
20
20
|
};
|
|
21
|
-
readonly agentforce: {
|
|
22
|
-
readonly description: "管理 AgentForce 数字员工";
|
|
23
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "agentforce-manage", "--yes"];
|
|
24
|
-
readonly skill: "agentforce-manage";
|
|
25
|
-
};
|
|
26
|
-
readonly aliway: {
|
|
27
|
-
readonly description: "读取和管理 Aliway 内容";
|
|
28
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "aliway-doc-fetch", "--yes"];
|
|
29
|
-
readonly skill: "aliway-doc-fetch";
|
|
30
|
-
};
|
|
31
|
-
readonly ata: {
|
|
32
|
-
readonly description: "读取和管理 ATA 内容";
|
|
33
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "ata-doc-fetch", "--yes"];
|
|
34
|
-
readonly skill: "ata-doc-fetch";
|
|
35
|
-
};
|
|
36
|
-
readonly code: {
|
|
37
|
-
readonly description: "读取 code.alibaba-inc.com 代码";
|
|
38
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "code-file-fetch", "--yes"];
|
|
39
|
-
readonly skill: "code-file-fetch";
|
|
40
|
-
};
|
|
41
|
-
readonly dingtalk: {
|
|
42
|
-
readonly description: "读取钉钉文档与表格";
|
|
43
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "dingtalk-doc-fetch", "--yes"];
|
|
44
|
-
readonly skill: "dingtalk-doc-fetch";
|
|
45
|
-
};
|
|
46
|
-
readonly figma: {
|
|
47
|
-
readonly description: "提取 Figma 设计数据与素材";
|
|
48
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "figma-design-fetch", "--yes"];
|
|
49
|
-
readonly skill: "figma-design-fetch";
|
|
50
|
-
};
|
|
51
|
-
readonly flyeye: {
|
|
52
|
-
readonly description: "查询 FlyEye 分布式链路日志";
|
|
53
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "flyeye-trace-query", "--yes"];
|
|
54
|
-
readonly skill: "flyeye-trace-query";
|
|
55
|
-
};
|
|
56
|
-
readonly jarvis: {
|
|
57
|
-
readonly description: "查询和处理 Jarvis 机票退改";
|
|
58
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "jarvis-order-operations", "--yes"];
|
|
59
|
-
readonly skill: "jarvis-order-operations";
|
|
60
|
-
};
|
|
61
|
-
readonly loginsight: {
|
|
62
|
-
readonly description: "分析 LogInsight 全链路日志";
|
|
63
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "loginsight-analyze", "--yes"];
|
|
64
|
-
readonly skill: "loginsight-analyze";
|
|
65
|
-
};
|
|
66
|
-
readonly tps: {
|
|
67
|
-
readonly description: "上传 TPS 图片并获取 CDN 地址";
|
|
68
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "tps-image-upload", "--yes"];
|
|
69
|
-
readonly skill: "tps-image-upload";
|
|
70
|
-
};
|
|
71
|
-
readonly yuque: {
|
|
72
|
-
readonly description: "读取和管理阿里语雀文档";
|
|
73
|
-
readonly installArgs: readonly ["trip/mearl", "--skill", "yuque-doc-fetch", "--yes"];
|
|
74
|
-
readonly skill: "yuque-doc-fetch";
|
|
75
|
-
};
|
|
76
21
|
};
|
|
77
22
|
export type OfficialPluginName = keyof typeof OFFICIAL_PLUGINS;
|
|
78
23
|
export declare function findOfficialPlugin(name: string): OfficialPluginDefinition | undefined;
|
|
@@ -12,61 +12,6 @@ export const OFFICIAL_PLUGINS = {
|
|
|
12
12
|
setup: 'alibaba',
|
|
13
13
|
skill: 'tdbank-account',
|
|
14
14
|
},
|
|
15
|
-
agentforce: {
|
|
16
|
-
description: '管理 AgentForce 数字员工',
|
|
17
|
-
installArgs: ['trip/mearl', '--skill', 'agentforce-manage', '--yes'],
|
|
18
|
-
skill: 'agentforce-manage',
|
|
19
|
-
},
|
|
20
|
-
aliway: {
|
|
21
|
-
description: '读取和管理 Aliway 内容',
|
|
22
|
-
installArgs: ['trip/mearl', '--skill', 'aliway-doc-fetch', '--yes'],
|
|
23
|
-
skill: 'aliway-doc-fetch',
|
|
24
|
-
},
|
|
25
|
-
ata: {
|
|
26
|
-
description: '读取和管理 ATA 内容',
|
|
27
|
-
installArgs: ['trip/mearl', '--skill', 'ata-doc-fetch', '--yes'],
|
|
28
|
-
skill: 'ata-doc-fetch',
|
|
29
|
-
},
|
|
30
|
-
code: {
|
|
31
|
-
description: '读取 code.alibaba-inc.com 代码',
|
|
32
|
-
installArgs: ['trip/mearl', '--skill', 'code-file-fetch', '--yes'],
|
|
33
|
-
skill: 'code-file-fetch',
|
|
34
|
-
},
|
|
35
|
-
dingtalk: {
|
|
36
|
-
description: '读取钉钉文档与表格',
|
|
37
|
-
installArgs: ['trip/mearl', '--skill', 'dingtalk-doc-fetch', '--yes'],
|
|
38
|
-
skill: 'dingtalk-doc-fetch',
|
|
39
|
-
},
|
|
40
|
-
figma: {
|
|
41
|
-
description: '提取 Figma 设计数据与素材',
|
|
42
|
-
installArgs: ['trip/mearl', '--skill', 'figma-design-fetch', '--yes'],
|
|
43
|
-
skill: 'figma-design-fetch',
|
|
44
|
-
},
|
|
45
|
-
flyeye: {
|
|
46
|
-
description: '查询 FlyEye 分布式链路日志',
|
|
47
|
-
installArgs: ['trip/mearl', '--skill', 'flyeye-trace-query', '--yes'],
|
|
48
|
-
skill: 'flyeye-trace-query',
|
|
49
|
-
},
|
|
50
|
-
jarvis: {
|
|
51
|
-
description: '查询和处理 Jarvis 机票退改',
|
|
52
|
-
installArgs: ['trip/mearl', '--skill', 'jarvis-order-operations', '--yes'],
|
|
53
|
-
skill: 'jarvis-order-operations',
|
|
54
|
-
},
|
|
55
|
-
loginsight: {
|
|
56
|
-
description: '分析 LogInsight 全链路日志',
|
|
57
|
-
installArgs: ['trip/mearl', '--skill', 'loginsight-analyze', '--yes'],
|
|
58
|
-
skill: 'loginsight-analyze',
|
|
59
|
-
},
|
|
60
|
-
tps: {
|
|
61
|
-
description: '上传 TPS 图片并获取 CDN 地址',
|
|
62
|
-
installArgs: ['trip/mearl', '--skill', 'tps-image-upload', '--yes'],
|
|
63
|
-
skill: 'tps-image-upload',
|
|
64
|
-
},
|
|
65
|
-
yuque: {
|
|
66
|
-
description: '读取和管理阿里语雀文档',
|
|
67
|
-
installArgs: ['trip/mearl', '--skill', 'yuque-doc-fetch', '--yes'],
|
|
68
|
-
skill: 'yuque-doc-fetch',
|
|
69
|
-
},
|
|
70
15
|
};
|
|
71
16
|
export function findOfficialPlugin(name) {
|
|
72
17
|
return Object.hasOwn(OFFICIAL_PLUGINS, name)
|
package/dist/plugin.d.ts
CHANGED
|
@@ -27,13 +27,13 @@ export declare function loadPlugin(entry: string, context: Pick<PluginApp, 'invo
|
|
|
27
27
|
description: string | undefined;
|
|
28
28
|
version: string | undefined;
|
|
29
29
|
help(namespace: string, name?: string): string;
|
|
30
|
-
run(positionals: string[], payload?: unknown): Promise<unknown>;
|
|
30
|
+
run(positionals: string[], payload?: unknown, namedInput?: Record<string, unknown>): Promise<unknown>;
|
|
31
31
|
}>;
|
|
32
32
|
export declare function loadRegisteredPlugin(name: string, context: PluginExecutionContext, options?: PluginInvokeOptions): Promise<{
|
|
33
33
|
name: string | undefined;
|
|
34
34
|
description: string | undefined;
|
|
35
35
|
version: string | undefined;
|
|
36
36
|
help(namespace: string, name?: string): string;
|
|
37
|
-
run(positionals: string[], payload?: unknown): Promise<unknown>;
|
|
37
|
+
run(positionals: string[], payload?: unknown, namedInput?: Record<string, unknown>): Promise<unknown>;
|
|
38
38
|
}>;
|
|
39
39
|
export declare function invokeRegisteredPlugin(name: string, invocation: PluginInvocation, context: PluginExecutionContext, options?: PluginInvokeOptions): Promise<unknown>;
|
package/dist/plugin.js
CHANGED
|
@@ -145,21 +145,24 @@ export async function loadPlugin(entry, context, pluginName) {
|
|
|
145
145
|
'',
|
|
146
146
|
'常用选项: --browser --timeout --compact --output',
|
|
147
147
|
'连接或传输排障运行 mearl check --help。',
|
|
148
|
-
'插件选项: --verbose; -h, --help; -v, --version',
|
|
149
|
-
'
|
|
148
|
+
'插件选项: --name=value 传入字符串业务字段;--verbose; -h, --help; -v, --version',
|
|
149
|
+
'同名宿主选项及非字符串字段使用 --payload;业务字段与校验规则见对应 skill。',
|
|
150
150
|
].join('\n');
|
|
151
151
|
},
|
|
152
|
-
async run(positionals, payload) {
|
|
152
|
+
async run(positionals, payload, namedInput = {}) {
|
|
153
153
|
if (payload !== undefined && positionals.length > 0) {
|
|
154
154
|
throw new PluginError('PLUGIN_INVALID_INPUT', '位置参数调用与 --payload 调用不能混用');
|
|
155
155
|
}
|
|
156
|
+
if (payload !== undefined && Object.keys(namedInput).length > 0) {
|
|
157
|
+
throw new PluginError('PLUGIN_INVALID_INPUT', '插件业务选项与 --payload 调用不能混用');
|
|
158
|
+
}
|
|
156
159
|
if (payload !== undefined &&
|
|
157
160
|
(!isObject(payload) || typeof payload.command !== 'string' || !isObject(payload.input))) {
|
|
158
161
|
throw new PluginError('PLUGIN_INVALID_INPUT', '--payload 必须为 {"command":"...","input":{...}}');
|
|
159
162
|
}
|
|
160
163
|
const envelope = payload;
|
|
161
164
|
const { command, handler } = find(envelope?.command ?? positionals[0] ?? '');
|
|
162
|
-
const
|
|
165
|
+
const positionalInput = envelope
|
|
163
166
|
? { ...envelope.input }
|
|
164
167
|
: Object.fromEntries(command.registeredArguments
|
|
165
168
|
.map((argument, index) => [
|
|
@@ -167,6 +170,12 @@ export async function loadPlugin(entry, context, pluginName) {
|
|
|
167
170
|
argument.variadic ? positionals.slice(index + 1) : positionals[index + 1],
|
|
168
171
|
])
|
|
169
172
|
.filter(([, value]) => value !== undefined));
|
|
173
|
+
for (const name of Object.keys(namedInput)) {
|
|
174
|
+
if (Object.hasOwn(positionalInput, name)) {
|
|
175
|
+
throw new PluginError('PLUGIN_INVALID_INPUT', `参数不能重复传入: ${name}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const input = { ...positionalInput, ...namedInput };
|
|
170
179
|
if (!envelope &&
|
|
171
180
|
!command.registeredArguments.some(argument => argument.variadic) &&
|
|
172
181
|
positionals.length - 1 > command.registeredArguments.length) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/client",
|
|
3
|
-
"version": "2.16.
|
|
3
|
+
"version": "2.16.2",
|
|
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.
|
|
63
|
-
"@mearl/provider": "2.16.
|
|
62
|
+
"@mearl/cloud-types": "2.16.2",
|
|
63
|
+
"@mearl/provider": "2.16.2"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@types/node": "^24.9.1",
|