@mearl/client 3.0.0-beta.8 → 3.0.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.en.md +616 -0
- package/README.md +22 -14
- package/dist/bin.js +1 -1
- package/dist/capabilityHelp.js +3 -3
- package/dist/commands.d.ts +12 -12
- package/dist/commands.js +12 -12
- package/dist/guide.d.ts +4 -4
- package/dist/guide.js +13 -4
- package/dist/guides/api-page-environment.md +4 -4
- package/dist/guides/browser-tool-cooperation.md +1 -1
- package/dist/guides/core.md +2 -2
- package/dist/guides/related-skills.md +22 -3
- package/dist/guides/troubleshooting.md +7 -7
- package/dist/plugins/pluginRegistry.d.ts +2 -3
- package/dist/plugins/pluginRegistry.js +9 -2
- package/dist/plugins/runtime/pluginPageManager.js +15 -4
- package/dist/plugins/sdk/plugin.d.ts +7 -0
- package/dist/plugins/sdk/plugin.js +5 -0
- package/dist/plugins/sdk/pluginPageDefinition.js +2 -0
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# @mearl/client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[简体中文](README.md) | [English](README.en.md)
|
|
4
|
+
|
|
5
|
+
在终端使用 `mearl`,或在 TypeScript 中使用 `@mearl/client`,控制浏览器、查看请求和日志,或执行 Skill 命令。CLI、SDK 和脚本运行器共用浏览器路由与插件运行时,安装和连接由 `@mearl/setup` 管理。
|
|
4
6
|
|
|
5
7
|
首次使用当前版本可运行 `mearl guide`,默认只读取核心工作流。`mearl guide --list` 列出专题;例如 `mearl guide run` 读取 SDK 组合调用,`mearl guide environment` 读取设备与 App 指引。指南只读 npm 包内资源,不连接浏览器、加载插件、安装环境或触发自动更新。动作参数继续使用 `mearl <action> --help`,目标的已安装能力继续按现有目录查询。
|
|
6
8
|
|
|
7
|
-
指南正文唯一维护在本包的 `guides/`,构建时复制到 `dist/guides/`,`pnpm check:skills` 校验一致性。CLI 输出将本地文档链接转换为下一条指南命令。`skills/mearl/` 只分发精简的 `SKILL.md`,不附带正文副本;仅使用 MCP、无法执行 CLI 时,直接使用当前工具说明与 schema
|
|
9
|
+
指南正文唯一维护在本包的 `guides/`,构建时复制到 `dist/guides/`,`pnpm check:skills` 校验一致性。CLI 输出将本地文档链接转换为下一条指南命令。`skills/mearl/` 只分发精简的 `SKILL.md`,不附带正文副本;仅使用 MCP、无法执行 CLI 时,直接使用当前工具说明与 schema。
|
|
8
10
|
|
|
9
11
|
统一浏览器 SDK 与 CLI。它会发现当前机器及已配置 cloud-server 下所有 connector 的浏览器,并根据 `browser_list` 返回的全局 `browserId` 自动选择本地 Socket 或云端 WebSocket 链路。
|
|
10
12
|
|
|
@@ -13,9 +15,9 @@ CLI、TypeScript SDK 与脚本入口共用浏览器路由和插件运行时。
|
|
|
13
15
|
## 安装
|
|
14
16
|
|
|
15
17
|
```bash
|
|
16
|
-
npm install @mearl/client@
|
|
18
|
+
npm install @mearl/client@3
|
|
17
19
|
# 或
|
|
18
|
-
pnpm add @mearl/client@
|
|
20
|
+
pnpm add @mearl/client@3
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
## SDK 使用
|
|
@@ -64,7 +66,7 @@ mearl check
|
|
|
64
66
|
mearl check --local --json
|
|
65
67
|
|
|
66
68
|
# 更新本地环境
|
|
67
|
-
npx @mearl/setup@
|
|
69
|
+
npx @mearl/setup@3 update --local
|
|
68
70
|
|
|
69
71
|
# 查看某个 action 的帮助
|
|
70
72
|
mearl <action> --help
|
|
@@ -195,8 +197,8 @@ mearl browser_list
|
|
|
195
197
|
mearl tab_list --browser '<browserId>'
|
|
196
198
|
mearl page_snapshot --payload '{"tabId":12345}' --browser '<browserId>'
|
|
197
199
|
|
|
198
|
-
npx @mearl/setup provider update
|
|
199
|
-
npx @mearl/setup provider uninstall
|
|
200
|
+
npx @mearl/setup provider update example-device
|
|
201
|
+
npx @mearl/setup provider uninstall example-device
|
|
200
202
|
```
|
|
201
203
|
|
|
202
204
|
`browser_launch` 创建 `pairing` 实例时会直接返回 `pairing.url` 和可选的配对码;Agent 应把 URL 直接渲染为
|
|
@@ -246,7 +248,7 @@ Mearl 默认聚合当前机器和已配置 cloud-server 下的浏览器,并通
|
|
|
246
248
|
client、native-host、cloud-connector 和扩展的最新发布版本。发布版本查询最长等待约 1.5 秒,
|
|
247
249
|
无法访问发布源时会提示无法确认更新,不影响浏览器可用性检查。`--json` 输出机器可读的检查结果,
|
|
248
250
|
与 `--updates` 同用时包含更新状态。发现更新时会提示适用的命令:client/native-host 使用
|
|
249
|
-
`npx @mearl/setup@
|
|
251
|
+
`npx @mearl/setup@3 update`,setup 管理的扩展使用 `npx @mearl/setup extension`。
|
|
250
252
|
|
|
251
253
|
全局安装的 `mearl` CLI 默认在每天首次使用后启动独立后台进程,查询最新发布版本,并比较
|
|
252
254
|
client、native-host、cloud-server 和 MCP server 的已安装版本。发现更新时调用
|
|
@@ -290,6 +292,8 @@ Provider 与插件仍可独立安装、更新和卸载,帮助聚合不会启
|
|
|
290
292
|
注册名优先使用显式名称,其次读取入口的 `name` metadata,最后回退到 skill 目录名;常规注册只传路径。
|
|
291
293
|
setup 会补齐缺失或低于自身版本的 client、native-host;安装参数由 setup 的 Skills 安装器处理,并固定全局共享安装。
|
|
292
294
|
|
|
295
|
+
JavaScript 入口可导出 `setup({ runCommand })` 准备 Skill 自己的依赖。setup 的两种安装入口都会等待该钩子成功后再注册,失败时停止注册。查看帮助、加载入口及普通调用不执行此钩子;Skill 在首次使用时自行检查依赖。运行代码与资源随 Skill 分发。
|
|
296
|
+
|
|
293
297
|
需要单独检查插件时运行 `mearl <name> --version`。命令会解析注册记录并加载入口,但不连接浏览器;
|
|
294
298
|
退出码为 0 表示插件已注册且入口可加载,stdout 返回同目录 `SKILL.md` 的版本,缺少版本元数据时返回 `unknown`。
|
|
295
299
|
未注册、入口丢失或加载失败会以退出码 2 和对应的 `PLUGIN_*` 错误结束。普通业务调用无需预先检查,直接处理同样的错误即可。
|
|
@@ -364,17 +368,17 @@ Mearl 将入口 HTML 引用的本地 CSS、JavaScript 和图片内联为不可
|
|
|
364
368
|
```javascript
|
|
365
369
|
export const toolbox = {
|
|
366
370
|
version: 1,
|
|
367
|
-
title: '
|
|
368
|
-
description: '
|
|
369
|
-
icon: '
|
|
371
|
+
title: '工作区笔记',
|
|
372
|
+
description: '整理工作区笔记',
|
|
373
|
+
icon: 'notebook-pen',
|
|
370
374
|
locales: {
|
|
371
375
|
en: {
|
|
372
|
-
title: '
|
|
373
|
-
description: '
|
|
376
|
+
title: 'Workspace Notes',
|
|
377
|
+
description: 'Organize notes for a workspace',
|
|
374
378
|
},
|
|
375
379
|
},
|
|
376
380
|
agent: {
|
|
377
|
-
skill: '
|
|
381
|
+
skill: 'notebook-skill',
|
|
378
382
|
layout: 'workspace',
|
|
379
383
|
},
|
|
380
384
|
page: {
|
|
@@ -395,6 +399,8 @@ export default function register(app) {
|
|
|
395
399
|
|
|
396
400
|
`app.command(signature, handler, description?, examples?)` 注册 CLI、SDK 和 Agent 可调用的业务命令。
|
|
397
401
|
|
|
402
|
+
工具箱的 Agent 对话默认显示页面元素选择和评论入口。将 `toolbox.agent.pageElementActions` 设为 `false` 可以隐藏这两个入口。
|
|
403
|
+
|
|
398
404
|
`toolbox.icon` 支持以下字符串形式,工具列表、切换菜单与网站安装目录使用同一格式:
|
|
399
405
|
|
|
400
406
|
```js
|
|
@@ -462,6 +468,8 @@ Node 插件在运行 CLI、SDK 或 MCP Server 的宿主上执行,不随浏览
|
|
|
462
468
|
|
|
463
469
|
`tab_open active:true` 请求激活目标页。扩展免打扰默认开启:HTTP(S) 页面在首次导航前启用后台焦点模拟,不切换标签页或窗口;关闭免打扰才会真实激活并恢复最小化窗口。`activation.mode` 区分 `background` / `foreground`,模拟后的 `visibilityState` 不代表窗口在前台。焦点模拟在交接、释放控制或扩展连接断开时关闭,`preserveEnvironment` 不保留它;交还后按需对同 URL 使用 `reuse:"require", active:true` 再次激活。不带会话时通过 `browser_release` 收尾。纯 CDP 和外部 Provider 遵循各自的激活能力。页面动作的稳定观察会在有限预算内等待有限时长 CSS 动画。selector/ref 点击遇到嵌套滚动裁剪时会先滚动目标,仍不可见时才以明确的裁剪错误停止。
|
|
464
470
|
|
|
471
|
+
扩展模式下,`tab_open` 传入 `appProfile` 会应用 App 环境。需要模拟 WebView 和系统栏时,设置 `emulation.deviceShell: true`。对于使用单个 WebView 的受支持固定机型,扩展会沿用快捷设置里保存的**手机壳**偏好。Agent 的页面操作以当前业务 WebView 为目标。
|
|
472
|
+
|
|
465
473
|
`page_click` 默认 `auto` 在隐藏页使用 DOM fallback,selector、文本、ref 和坐标定位都保持可用,并通过 `dispatchMode: "dom"`、`fallbackReason: "page-hidden"` 明确说明实际路径。普通后台任务不需要为了点击主动激活页面;只有站点明确拒绝非可信事件时才切换到可见页并强制 `mouse` / `touch`。
|
|
466
474
|
|
|
467
475
|
`observation.effects.interactives` 会把内容未变化但 DOM 节点被框架重建的控件标记为 `recreated`,保留 selector/ref 与语义信息供后续定位,同时省略未变化的 value 和状态字段;值或状态确实变化时仍返回完整差异。
|
package/dist/bin.js
CHANGED
|
@@ -3,7 +3,7 @@ import { CLIENT_VERSION } from './runtimePaths.js';
|
|
|
3
3
|
const args = process.argv.slice(2);
|
|
4
4
|
if (args[0] === 'guide') {
|
|
5
5
|
const { runGuideCli } = await import('./guide.js');
|
|
6
|
-
process.exitCode = runGuideCli(args.slice(1));
|
|
6
|
+
process.exitCode = await runGuideCli(args.slice(1));
|
|
7
7
|
}
|
|
8
8
|
else {
|
|
9
9
|
const { runMearlCli } = await import('./cli.js');
|
package/dist/capabilityHelp.js
CHANGED
|
@@ -40,12 +40,12 @@ export async function readHelpCapabilities(args) {
|
|
|
40
40
|
}
|
|
41
41
|
export function formatCapabilityHelp(catalog, detailed = false) {
|
|
42
42
|
if (!catalog)
|
|
43
|
-
return '
|
|
43
|
+
return '当前浏览器能力暂不可读,以下为静态帮助。连接后再次运行 --help 可查看已安装的端模拟。';
|
|
44
44
|
const lines = [
|
|
45
|
-
'
|
|
45
|
+
'当前浏览器已安装的端模拟:',
|
|
46
46
|
];
|
|
47
47
|
if (!catalog.apps.entries.length)
|
|
48
|
-
lines.push(catalog.apps.status === 'available' ? '
|
|
48
|
+
lines.push(catalog.apps.status === 'available' ? ' 暂无已安装的端模拟。设备模拟可独立使用。' : ' 暂时无法读取端模拟列表,安装状态待确认。');
|
|
49
49
|
for (const app of catalog.apps.entries) {
|
|
50
50
|
lines.push(` ${app.id} — ${app.label}${app.available ? '' : '(暂不可用)'}`);
|
|
51
51
|
if (!detailed)
|
package/dist/commands.d.ts
CHANGED
|
@@ -445,7 +445,7 @@ export declare const COMMANDS: readonly [{
|
|
|
445
445
|
readonly type: "string[] | string | { presets?: string[]; domains?: string[] }";
|
|
446
446
|
readonly description: "从控制浏览器复制 Cookie:可传域名数组、已安装能力提供的范围名,或组合范围与额外域名";
|
|
447
447
|
}];
|
|
448
|
-
readonly examples: ["browser_launch --payload '{\"provider\":\"
|
|
448
|
+
readonly examples: ["browser_launch --payload '{\"provider\":\"example-device\",\"providerOptions\":{}}'", "browser_launch --payload '{\"name\":\"figma\",\"userAgentMode\":\"desktop\",\"copyCookieDomains\":[\"figma.com\"]}'", "browser_launch --payload '{\"name\":\"with-cookies\",\"copyCookieDomains\":[\"example.com\",\"sub.example.org\"]}'"];
|
|
449
449
|
}, {
|
|
450
450
|
readonly name: "browser_close";
|
|
451
451
|
readonly description: "关闭指定托管浏览器,并按 Provider 策略保留或清理持久化数据";
|
|
@@ -507,7 +507,7 @@ export declare const COMMANDS: readonly [{
|
|
|
507
507
|
}, {
|
|
508
508
|
readonly name: "appProfile";
|
|
509
509
|
readonly type: "string";
|
|
510
|
-
readonly description: "
|
|
510
|
+
readonly description: "启用已安装的端模拟,ID 与限制见当前动态帮助。需要系统栏时同时传 emulation.deviceShell=true";
|
|
511
511
|
}, {
|
|
512
512
|
readonly name: "os";
|
|
513
513
|
readonly type: "\"ios\" | \"android\"";
|
|
@@ -573,7 +573,7 @@ export declare const COMMANDS: readonly [{
|
|
|
573
573
|
}, {
|
|
574
574
|
readonly name: "point";
|
|
575
575
|
readonly type: "{ x: number; y: number }";
|
|
576
|
-
readonly description: "按视口坐标点击(CSS
|
|
576
|
+
readonly description: "按视口坐标点击(CSS 像素)。手机壳预览默认使用业务视口坐标,其他页面默认使用外层视口坐标";
|
|
577
577
|
}, {
|
|
578
578
|
readonly name: "frameId";
|
|
579
579
|
readonly type: "string";
|
|
@@ -581,7 +581,7 @@ export declare const COMMANDS: readonly [{
|
|
|
581
581
|
}, {
|
|
582
582
|
readonly name: "coordinateSpace";
|
|
583
583
|
readonly type: "\"outer-viewport\" | \"active-frame\"";
|
|
584
|
-
readonly description: "仅配合 point
|
|
584
|
+
readonly description: "仅配合 point 使用;手机壳预览默认 active-frame,其他页面默认 outer-viewport;扩展后端会换算 iframe 偏移与缩放";
|
|
585
585
|
}, {
|
|
586
586
|
readonly name: "role";
|
|
587
587
|
readonly type: "string";
|
|
@@ -1044,7 +1044,7 @@ export declare const COMMANDS: readonly [{
|
|
|
1044
1044
|
}, {
|
|
1045
1045
|
readonly name: "splitScreen";
|
|
1046
1046
|
readonly type: "boolean";
|
|
1047
|
-
readonly description: "是否将首页与业务页分置左右 WebView
|
|
1047
|
+
readonly description: "是否将首页与业务页分置左右 WebView;仅在已启用端模拟、deviceShell=true、横屏时生效,默认 false";
|
|
1048
1048
|
}, {
|
|
1049
1049
|
readonly name: "reload";
|
|
1050
1050
|
readonly type: "boolean";
|
|
@@ -1055,12 +1055,12 @@ export declare const COMMANDS: readonly [{
|
|
|
1055
1055
|
readonly required: true;
|
|
1056
1056
|
readonly description: "目标标签页 ID";
|
|
1057
1057
|
}];
|
|
1058
|
-
readonly notes: readonly ["无 preset 时 width/height 必须成对提供且 userAgent 必填;mobile 默认 true,touch 跟随 mobile。", "deviceShell 开启/移除时必须重载;splitScreen
|
|
1058
|
+
readonly notes: readonly ["无 preset 时 width/height 必须成对提供且 userAgent 必填;mobile 默认 true,touch 跟随 mobile。", "deviceShell 开启/移除时必须重载;splitScreen 仅在已启用端模拟、deviceShell=true、横屏时生效。"];
|
|
1059
1059
|
readonly result: readonly ["返回实际 viewport(width/height/deviceScaleFactor/scale)、UA、mobile、touch、orientation、deviceShell、splitScreen 和 reloaded;应以响应确认生效状态。"];
|
|
1060
1060
|
readonly examples: ["set_device_emulation --payload '{\"tabId\":12345,\"enabled\":true,\"preset\":\"iphone-17-pro\"}'", "set_device_emulation --payload '{\"tabId\":12345,\"enabled\":true,\"preset\":\"pixel-11\",\"orientation\":\"landscape\"}'", "set_device_emulation --payload '{\"tabId\":12345,\"enabled\":true,\"preset\":\"ipad-mini-a17-pro\",\"orientation\":\"landscape\",\"deviceShell\":true,\"splitScreen\":true}'", "set_device_emulation --payload '{\"tabId\":12345,\"enabled\":false}'"];
|
|
1061
1061
|
}, {
|
|
1062
1062
|
readonly name: "set_app_profile";
|
|
1063
|
-
readonly description: "
|
|
1063
|
+
readonly description: "设置目标标签页的端模拟;完整 JSBridge 由能力包提供。可同时设置已安装的网络控件,传 emulation 时联动设备模拟";
|
|
1064
1064
|
readonly summary: "设置或清除目标标签页的 App 容器模拟";
|
|
1065
1065
|
readonly params: [{
|
|
1066
1066
|
readonly name: "enabled";
|
|
@@ -1070,7 +1070,7 @@ export declare const COMMANDS: readonly [{
|
|
|
1070
1070
|
}, {
|
|
1071
1071
|
readonly name: "profile";
|
|
1072
1072
|
readonly type: "string";
|
|
1073
|
-
readonly description: "
|
|
1073
|
+
readonly description: "已安装的端模拟 ID(enabled=true 时必填);当前动态帮助直接展示目标浏览器目录";
|
|
1074
1074
|
}, {
|
|
1075
1075
|
readonly name: "os";
|
|
1076
1076
|
readonly type: "\"ios\" | \"android\"";
|
|
@@ -1078,7 +1078,7 @@ export declare const COMMANDS: readonly [{
|
|
|
1078
1078
|
}, {
|
|
1079
1079
|
readonly name: "refreshDefinition";
|
|
1080
1080
|
readonly type: "boolean";
|
|
1081
|
-
readonly description: "
|
|
1081
|
+
readonly description: "立即采用最新端模拟配置,保留用户显式设置";
|
|
1082
1082
|
}, {
|
|
1083
1083
|
readonly name: "lockDefinition";
|
|
1084
1084
|
readonly type: "boolean";
|
|
@@ -1086,7 +1086,7 @@ export declare const COMMANDS: readonly [{
|
|
|
1086
1086
|
}, {
|
|
1087
1087
|
readonly name: "appVersion";
|
|
1088
1088
|
readonly type: "string";
|
|
1089
|
-
readonly description: "
|
|
1089
|
+
readonly description: "覆盖配置中的默认 App 版本号";
|
|
1090
1090
|
}, {
|
|
1091
1091
|
readonly name: "deviceModel";
|
|
1092
1092
|
readonly type: "string";
|
|
@@ -1102,7 +1102,7 @@ export declare const COMMANDS: readonly [{
|
|
|
1102
1102
|
}, {
|
|
1103
1103
|
readonly name: "emulation";
|
|
1104
1104
|
readonly type: "object";
|
|
1105
|
-
readonly description: "可选设备联动参数,字段同 set_device_emulation 去掉 enabled/reload
|
|
1105
|
+
readonly description: "可选设备联动参数,字段同 set_device_emulation 去掉 enabled/reload;字段覆盖端模拟配置推荐的设备,deviceShell 默认 true,横屏时可传 splitScreen=true。省略时不设置或清除设备";
|
|
1106
1106
|
}, {
|
|
1107
1107
|
readonly name: "reload";
|
|
1108
1108
|
readonly type: "boolean";
|
|
@@ -1113,7 +1113,7 @@ export declare const COMMANDS: readonly [{
|
|
|
1113
1113
|
readonly required: true;
|
|
1114
1114
|
readonly description: "目标标签页 ID";
|
|
1115
1115
|
}];
|
|
1116
|
-
readonly notes: readonly ["只有用户明确要求 App/客户端/容器/JSBridge 模拟时启用。移动视口或普通 H5 调试使用 set_device_emulation。", "emulation={}
|
|
1116
|
+
readonly notes: readonly ["只有用户明确要求 App/客户端/容器/JSBridge 模拟时启用。移动视口或普通 H5 调试使用 set_device_emulation。", "emulation={} 使用端模拟配置推荐的设备;enabled=false 时省略 emulation 只清除 App 注入,传 {} 同时清除设备模拟。", "bridgeConfig.methods 按方法声明 behavior / response / noop 三选一,可传 silent;只支持受控行为、固定 JSON 回包或成功空实现,不执行配置脚本。"];
|
|
1117
1117
|
readonly result: readonly ["返回 enabled、profile、label、userAgent、os、networkControl、reloaded;联动设备时额外返回实际 emulation。"];
|
|
1118
1118
|
readonly examples: ["set_app_profile --payload '{\"tabId\":12345,\"enabled\":true,\"profile\":\"reader\"}'", "set_app_profile --payload '{\"tabId\":12345,\"enabled\":true,\"profile\":\"reader\",\"networkControl\":{\"id\":\"environment\",\"value\":\"pre\"}}'", "set_app_profile --payload '{\"tabId\":12345,\"enabled\":false,\"networkControl\":null}'", "set_app_profile --payload '{\"tabId\":12345,\"enabled\":true,\"profile\":\"reader\",\"emulation\":{}}'", "set_app_profile --payload '{\"tabId\":12345,\"enabled\":true,\"profile\":\"wallet\",\"emulation\":{\"preset\":\"pixel-11\",\"deviceShell\":true}}'", "set_app_profile --payload '{\"tabId\":12345,\"enabled\":true,\"profile\":\"reader\",\"emulation\":{\"preset\":\"ipad-mini-a17-pro\",\"orientation\":\"landscape\",\"deviceShell\":true,\"splitScreen\":true}}'", "set_app_profile --payload '{\"tabId\":12345,\"enabled\":false}'", "set_app_profile --payload '{\"tabId\":12345,\"enabled\":false,\"emulation\":{}}'"];
|
|
1119
1119
|
}, {
|
package/dist/commands.js
CHANGED
|
@@ -453,7 +453,7 @@ export const COMMANDS = [
|
|
|
453
453
|
},
|
|
454
454
|
],
|
|
455
455
|
examples: [
|
|
456
|
-
`browser_launch --payload '{"provider":"
|
|
456
|
+
`browser_launch --payload '{"provider":"example-device","providerOptions":{}}'`,
|
|
457
457
|
`browser_launch --payload '{"name":"figma","userAgentMode":"desktop","copyCookieDomains":["figma.com"]}'`,
|
|
458
458
|
`browser_launch --payload '{"name":"with-cookies","copyCookieDomains":["example.com","sub.example.org"]}'`,
|
|
459
459
|
],
|
|
@@ -532,7 +532,7 @@ export const COMMANDS = [
|
|
|
532
532
|
{
|
|
533
533
|
name: 'appProfile',
|
|
534
534
|
type: 'string',
|
|
535
|
-
description: '
|
|
535
|
+
description: '启用已安装的端模拟,ID 与限制见当前动态帮助。需要系统栏时同时传 emulation.deviceShell=true',
|
|
536
536
|
},
|
|
537
537
|
{
|
|
538
538
|
name: 'os',
|
|
@@ -621,7 +621,7 @@ export const COMMANDS = [
|
|
|
621
621
|
{
|
|
622
622
|
name: 'point',
|
|
623
623
|
type: '{ x: number; y: number }',
|
|
624
|
-
description: '按视口坐标点击(CSS
|
|
624
|
+
description: '按视口坐标点击(CSS 像素)。手机壳预览默认使用业务视口坐标,其他页面默认使用外层视口坐标',
|
|
625
625
|
},
|
|
626
626
|
{
|
|
627
627
|
name: 'frameId',
|
|
@@ -631,7 +631,7 @@ export const COMMANDS = [
|
|
|
631
631
|
{
|
|
632
632
|
name: 'coordinateSpace',
|
|
633
633
|
type: '"outer-viewport" | "active-frame"',
|
|
634
|
-
description: '仅配合 point
|
|
634
|
+
description: '仅配合 point 使用;手机壳预览默认 active-frame,其他页面默认 outer-viewport;扩展后端会换算 iframe 偏移与缩放',
|
|
635
635
|
},
|
|
636
636
|
{
|
|
637
637
|
name: 'role',
|
|
@@ -1151,14 +1151,14 @@ export const COMMANDS = [
|
|
|
1151
1151
|
{
|
|
1152
1152
|
name: 'splitScreen',
|
|
1153
1153
|
type: 'boolean',
|
|
1154
|
-
description: '是否将首页与业务页分置左右 WebView
|
|
1154
|
+
description: '是否将首页与业务页分置左右 WebView;仅在已启用端模拟、deviceShell=true、横屏时生效,默认 false',
|
|
1155
1155
|
},
|
|
1156
1156
|
{ name: 'reload', type: 'boolean', description: '启用后是否重载页面,默认 true' },
|
|
1157
1157
|
{ name: 'tabId', type: 'number', required: true, description: '目标标签页 ID' },
|
|
1158
1158
|
],
|
|
1159
1159
|
notes: [
|
|
1160
1160
|
'无 preset 时 width/height 必须成对提供且 userAgent 必填;mobile 默认 true,touch 跟随 mobile。',
|
|
1161
|
-
'deviceShell 开启/移除时必须重载;splitScreen
|
|
1161
|
+
'deviceShell 开启/移除时必须重载;splitScreen 仅在已启用端模拟、deviceShell=true、横屏时生效。',
|
|
1162
1162
|
],
|
|
1163
1163
|
result: [
|
|
1164
1164
|
'返回实际 viewport(width/height/deviceScaleFactor/scale)、UA、mobile、touch、orientation、deviceShell、splitScreen 和 reloaded;应以响应确认生效状态。',
|
|
@@ -1172,27 +1172,27 @@ export const COMMANDS = [
|
|
|
1172
1172
|
},
|
|
1173
1173
|
{
|
|
1174
1174
|
name: 'set_app_profile',
|
|
1175
|
-
description: '
|
|
1175
|
+
description: '设置目标标签页的端模拟;完整 JSBridge 由能力包提供。可同时设置已安装的网络控件,传 emulation 时联动设备模拟',
|
|
1176
1176
|
summary: '设置或清除目标标签页的 App 容器模拟',
|
|
1177
1177
|
params: [
|
|
1178
1178
|
{ name: 'enabled', type: 'boolean', required: true, description: 'true=启用,false=清除' },
|
|
1179
1179
|
{
|
|
1180
1180
|
name: 'profile',
|
|
1181
1181
|
type: 'string',
|
|
1182
|
-
description: '
|
|
1182
|
+
description: '已安装的端模拟 ID(enabled=true 时必填);当前动态帮助直接展示目标浏览器目录',
|
|
1183
1183
|
},
|
|
1184
1184
|
{ name: 'os', type: '"ios" | "android"', description: '容器系统,默认 ios' },
|
|
1185
1185
|
{
|
|
1186
1186
|
name: 'refreshDefinition',
|
|
1187
1187
|
type: 'boolean',
|
|
1188
|
-
description: '
|
|
1188
|
+
description: '立即采用最新端模拟配置,保留用户显式设置',
|
|
1189
1189
|
},
|
|
1190
1190
|
{
|
|
1191
1191
|
name: 'lockDefinition',
|
|
1192
1192
|
type: 'boolean',
|
|
1193
1193
|
description: '固定当前定义;默认在下次刷新或文档导航时自动更新',
|
|
1194
1194
|
},
|
|
1195
|
-
{ name: 'appVersion', type: 'string', description: '
|
|
1195
|
+
{ name: 'appVersion', type: 'string', description: '覆盖配置中的默认 App 版本号' },
|
|
1196
1196
|
{
|
|
1197
1197
|
name: 'deviceModel',
|
|
1198
1198
|
type: 'string',
|
|
@@ -1211,14 +1211,14 @@ export const COMMANDS = [
|
|
|
1211
1211
|
{
|
|
1212
1212
|
name: 'emulation',
|
|
1213
1213
|
type: 'object',
|
|
1214
|
-
description: '可选设备联动参数,字段同 set_device_emulation 去掉 enabled/reload
|
|
1214
|
+
description: '可选设备联动参数,字段同 set_device_emulation 去掉 enabled/reload;字段覆盖端模拟配置推荐的设备,deviceShell 默认 true,横屏时可传 splitScreen=true。省略时不设置或清除设备',
|
|
1215
1215
|
},
|
|
1216
1216
|
{ name: 'reload', type: 'boolean', description: '应用/清除后是否重载页面,默认 true' },
|
|
1217
1217
|
{ name: 'tabId', type: 'number', required: true, description: '目标标签页 ID' },
|
|
1218
1218
|
],
|
|
1219
1219
|
notes: [
|
|
1220
1220
|
'只有用户明确要求 App/客户端/容器/JSBridge 模拟时启用。移动视口或普通 H5 调试使用 set_device_emulation。',
|
|
1221
|
-
'emulation={}
|
|
1221
|
+
'emulation={} 使用端模拟配置推荐的设备;enabled=false 时省略 emulation 只清除 App 注入,传 {} 同时清除设备模拟。',
|
|
1222
1222
|
'bridgeConfig.methods 按方法声明 behavior / response / noop 三选一,可传 silent;只支持受控行为、固定 JSON 回包或成功空实现,不执行配置脚本。',
|
|
1223
1223
|
],
|
|
1224
1224
|
result: [
|
package/dist/guide.d.ts
CHANGED
|
@@ -32,9 +32,9 @@ export declare const GUIDE_TOPICS: readonly [{
|
|
|
32
32
|
readonly file: "browser-tool-cooperation.md";
|
|
33
33
|
readonly title: "与其他浏览器工具协作";
|
|
34
34
|
}, {
|
|
35
|
-
readonly id: "
|
|
35
|
+
readonly id: "skills";
|
|
36
36
|
readonly file: "related-skills.md";
|
|
37
|
-
readonly title: "专用 Skill
|
|
37
|
+
readonly title: "专用 Skill 使用与安装";
|
|
38
38
|
}, {
|
|
39
39
|
readonly id: "troubleshooting";
|
|
40
40
|
readonly file: "troubleshooting.md";
|
|
@@ -42,5 +42,5 @@ export declare const GUIDE_TOPICS: readonly [{
|
|
|
42
42
|
}];
|
|
43
43
|
export declare function renderGuideLinks(source: string, commandName?: string): string;
|
|
44
44
|
/** Only packaged files are read; unknown IDs never become filesystem paths. */
|
|
45
|
-
export declare function readGuide(id: string, commandName?: string, version?: string): string
|
|
46
|
-
export declare function runGuideCli(args: string[], commandName?: string, version?: string): number
|
|
45
|
+
export declare function readGuide(id: string, commandName?: string, version?: string): Promise<string>;
|
|
46
|
+
export declare function runGuideCli(args: string[], commandName?: string, version?: string): Promise<number>;
|
package/dist/guide.js
CHANGED
|
@@ -10,7 +10,7 @@ export const GUIDE_TOPICS = [
|
|
|
10
10
|
{ id: 'diagnostics', file: 'api-request-debugging.md', title: '接口、日志、埋点、权限与 Mock' },
|
|
11
11
|
{ id: 'browsers', file: 'api-browser-setup.md', title: '目标、会话、远端与 Provider' },
|
|
12
12
|
{ id: 'cooperation', file: 'browser-tool-cooperation.md', title: '与其他浏览器工具协作' },
|
|
13
|
-
{ id: '
|
|
13
|
+
{ id: 'skills', file: 'related-skills.md', title: '专用 Skill 使用与安装' },
|
|
14
14
|
{ id: 'troubleshooting', file: 'troubleshooting.md', title: '安装、连接与环境排查' },
|
|
15
15
|
];
|
|
16
16
|
export function renderGuideLinks(source, commandName = 'mearl') {
|
|
@@ -25,7 +25,7 @@ export function renderGuideLinks(source, commandName = 'mearl') {
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
/** Only packaged files are read; unknown IDs never become filesystem paths. */
|
|
28
|
-
export function readGuide(id, commandName = 'mearl', version = CLIENT_VERSION) {
|
|
28
|
+
export async function readGuide(id, commandName = 'mearl', version = CLIENT_VERSION) {
|
|
29
29
|
const topic = GUIDE_TOPICS.find(topic => topic.id === id);
|
|
30
30
|
if (!topic)
|
|
31
31
|
throw new Error(`未知指南主题:${id}。用 ${commandName} guide --list 查看主题。`);
|
|
@@ -36,9 +36,18 @@ export function readGuide(id, commandName = 'mearl', version = CLIENT_VERSION) {
|
|
|
36
36
|
catch (error) {
|
|
37
37
|
throw new Error(`当前安装缺少指南资源:${topic.id}。请通过当前发行版的安装入口修复安装包;参数可用 ${commandName} <action> --help 查询。`, { cause: error });
|
|
38
38
|
}
|
|
39
|
+
let management;
|
|
40
|
+
if (source.includes('{{setup}}')) {
|
|
41
|
+
const { readInstallationManagement, setupManagementCommand } = await import('@mearl/daemon-core/installation');
|
|
42
|
+
const installed = await readInstallationManagement();
|
|
43
|
+
const command = setupManagementCommand(installed.setup ?? { package: '@mearl/setup', version: 'beta' });
|
|
44
|
+
source = source.replaceAll('{{setup}}', command);
|
|
45
|
+
management = installed.source ? `管理入口:${command};沿用本机已选 preset。` : `首次安装入口:${command};本机尚未选择 preset。`;
|
|
46
|
+
}
|
|
39
47
|
return [
|
|
40
48
|
`[mearl:guide] CLI ${version} · ${topic.id}`,
|
|
41
49
|
'本指南随 CLI 分发;扩展、远端宿主与已安装能力仍须按目标实际帮助核验。',
|
|
50
|
+
...(management ? [management] : []),
|
|
42
51
|
'',
|
|
43
52
|
renderGuideLinks(source.trim(), commandName),
|
|
44
53
|
'',
|
|
@@ -46,7 +55,7 @@ export function readGuide(id, commandName = 'mearl', version = CLIENT_VERSION) {
|
|
|
46
55
|
`[mearl:guide] end ${topic.id}`,
|
|
47
56
|
].join('\n');
|
|
48
57
|
}
|
|
49
|
-
export function runGuideCli(args, commandName = 'mearl', version = CLIENT_VERSION) {
|
|
58
|
+
export async function runGuideCli(args, commandName = 'mearl', version = CLIENT_VERSION) {
|
|
50
59
|
const list = () => GUIDE_TOPICS.map(topic => ` ${topic.id.padEnd(18)}${topic.title}`).join('\n');
|
|
51
60
|
if (args.length === 1 && (args[0] === '--help' || args[0] === '-h')) {
|
|
52
61
|
console.log(`${commandName} guide — CLI ${version}\n\n用法:${commandName} guide [topic]\n ${commandName} guide --list\n\n默认只读 core;按需读取单个专题。只读本地资源,不连接浏览器或检查更新。\n\n${list()}`);
|
|
@@ -61,7 +70,7 @@ export function runGuideCli(args, commandName = 'mearl', version = CLIENT_VERSIO
|
|
|
61
70
|
return 2;
|
|
62
71
|
}
|
|
63
72
|
try {
|
|
64
|
-
console.log(readGuide(args[0] ?? 'core', commandName, version));
|
|
73
|
+
console.log(await readGuide(args[0] ?? 'core', commandName, version));
|
|
65
74
|
return 0;
|
|
66
75
|
}
|
|
67
76
|
catch (error) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Mearl 场景:页面测试环境准备
|
|
2
2
|
|
|
3
|
-
需要联动设备/App、折叠屏/分屏、时区或 Cookie
|
|
3
|
+
需要联动设备/App、折叠屏/分屏、时区或 Cookie 时读取本文件。设备预设与端模拟列表以当前 CLI 为准,不从静态文档推断当前列表。远端/Provider 选择见[浏览器管理](./api-browser-setup.md)。
|
|
4
4
|
|
|
5
|
-
设备模拟直接可用。App
|
|
5
|
+
设备模拟直接可用。App 模拟入口由已安装的能力包提供,配置可声明 UA、JSBridge 和容器行为。先查看 `mearl set_app_profile --help` 展示的目标浏览器动态目录;需要机器可读的桥方法、可调设置与默认版本时用 SDK `mearl.getCapabilities({ app: '目录中的完整 ID' })` 或 MCP `browser_get_capabilities`。按需读取 `usage.skills` / `usage.documentation`,再执行对应动作。
|
|
6
6
|
|
|
7
7
|
## 设备模拟与设备外壳
|
|
8
8
|
|
|
@@ -17,8 +17,8 @@ scale 只改变视觉比例,不改变页面读取的视口或 DPR。预设的
|
|
|
17
17
|
只有用户明确要求 App、客户端、容器、JSBridge 或容器栈模拟时启用 set_app_profile / tab_open.appProfile;普通 H5、唤端链接、客户端分支或操作失败不是启用理由。
|
|
18
18
|
|
|
19
19
|
- 只注入桥:省略 emulation,保留设备状态;App 注入本身不创建根 iframe 或系统栏。
|
|
20
|
-
- 完整端模拟:同一个 set_app_profile 调用传 emulation
|
|
21
|
-
-
|
|
20
|
+
- 完整端模拟:同一个 set_app_profile 调用传 emulation;空对象采用端模拟配置推荐的设备,设备外壳默认开启。
|
|
21
|
+
- 左右分屏:端模拟与 deviceShell=true、orientation=landscape、splitScreen=true 必须同时满足。新建页需要首屏分屏时,在 tab_open 同时传 appProfile 与该 emulation 组合。
|
|
22
22
|
- 桥方法覆盖:bridgeConfig 只声明受控行为、固定 JSON 回包或成功空实现,不执行配置脚本。
|
|
23
23
|
- 恢复:enabled=false 且省略 emulation 只清除 App;传 emulation={} 同时清除设备模拟。
|
|
24
24
|
|
|
@@ -13,7 +13,7 @@ Mearl 单独使用时沿用主 Skill 的页面操作流程。任务已有 Ego、
|
|
|
13
13
|
- 在 Ego Page 读取 `page.cdp("Page.getFrameTree")` 的主 frame ID,再用扩展 `tab_list` 与 `page_frames` 核对。只有 `isMainFrame: true` 的 `frameId` 唯一匹配时,才使用该扩展 `browserId + tabId`;URL、标题和其他工具的页面标识不能代替核验。
|
|
14
14
|
- 每轮转入扩展写操作前,按 Ego 指南确认同一 Space 仍由 Agent 控制;用户接管、Space 失活或归属变化时两套工具均停止写入。扩展不会自动继承 Ego 的控制阻断,未知结果先观察,不换工具重放。
|
|
15
15
|
- 设备或 App 模拟开启期间,导航、交互、快照与截图使用扩展 action;Ego 鼠标输入可能与触摸模拟冲突,原生导航或截图可能改变设备参数。撤销并确认模拟清除后,再恢复 Ego 原生页面交互。
|
|
16
|
-
-
|
|
16
|
+
- 对应的端模拟须已安装并取得实际站点权限,以当前目标的帮助为准。桥对象存在不证明真实原生授权或支付能力;跨域 iframe 的原生 screen/DPR、媒体查询与 CSS 安全区也不保证与真机一致。
|
|
17
17
|
- 普通打开后设置模拟并重载,不等于业务页首次访问即处于模拟环境。需要首屏模拟时先确认当前工具支持的准备流程。
|
|
18
18
|
- 成功收尾遵守 Ego 的页面保留规则;保留结果页时保留用户需要的模拟状态。需要恢复时在结束前通过扩展显式恢复原配置;Mearl 会话释放不替代 Ego 收尾,也不保证清除模拟。
|
|
19
19
|
|
package/dist/guides/core.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Mearl 核心工作流
|
|
2
2
|
|
|
3
|
-
本指南说明通用操作流程。参数、返回字段以当前 CLI 的 `mearl <action> --help`、SDK `mearl.help()` 或 MCP 工具 schema 为准;MCP 使用实际提供的工具名,不猜命令映射。仅能使用 MCP、无法执行 CLI 时,直接使用当前 MCP 工具说明与 schema
|
|
3
|
+
本指南说明通用操作流程。参数、返回字段以当前 CLI 的 `mearl <action> --help`、SDK `mearl.help()` 或 MCP 工具 schema 为准;MCP 使用实际提供的工具名,不猜命令映射。仅能使用 MCP、无法执行 CLI 时,直接使用当前 MCP 工具说明与 schema。
|
|
4
4
|
|
|
5
5
|
## 进入任务
|
|
6
6
|
|
|
@@ -56,5 +56,5 @@ App 可用性以当前目标的 `set_app_profile --help` 或 `get_capabilities`
|
|
|
56
56
|
- [接口与埋点调试](./api-request-debugging.md):请求、日志、权限、Mock。
|
|
57
57
|
- [浏览器管理](./api-browser-setup.md):目标、会话、远端与 Provider。
|
|
58
58
|
- [工具协作](./browser-tool-cooperation.md):与 Ego、agent-browser 配合。
|
|
59
|
-
- [专用 Skill
|
|
59
|
+
- [专用 Skill 使用与安装](./related-skills.md):如何选用和按需安装本地微信小程序等专用能力,以及在哪里查找扩展开发指引。
|
|
60
60
|
- [连接排查](./troubleshooting.md):连接失败与环境管理。
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 专用 Skill 使用与安装
|
|
2
2
|
|
|
3
3
|
站点或业务对象与任务意图都匹配时,优先使用已安装的专用 Skill。通用网页操作继续使用 Mearl;不要仅因关键词相同就改用其他能力。专用站点的路由说明由对应 Skill 提供。
|
|
4
4
|
|
|
5
5
|
| 意图 | Skill |
|
|
6
6
|
| --- | --- |
|
|
7
|
+
| 运行或验证本地微信小程序,包括 uni-app / Taro 的微信产物 | wechat-miniprogram |
|
|
7
8
|
| 时间戳、Base64、图片编码、URL 编解码 | format-converter |
|
|
8
9
|
| 记录或检索笔记与跨会话记忆 | notes-memory |
|
|
9
10
|
| 管理已有浏览器标签分组、关闭受控标签页 | browser-tab-manager |
|
|
@@ -18,10 +19,28 @@
|
|
|
18
19
|
有脚本入口的 Skill 可安装并自动注册插件:
|
|
19
20
|
|
|
20
21
|
```bash
|
|
21
|
-
|
|
22
|
+
{{setup}} plugin install https://github.com/mearlhq/mearl --skill <skill-name> --yes
|
|
22
23
|
```
|
|
23
24
|
|
|
24
|
-
已可用的专用 Skill
|
|
25
|
+
已可用的专用 Skill 按其说明执行。用户明确要求使用表中某项专用能力、且执行任务需要该插件时,可在缺失时按需安装并继续。普通网页操作使用通用流程。
|
|
26
|
+
|
|
27
|
+
## 运行本地微信小程序
|
|
28
|
+
|
|
29
|
+
任务要运行小程序工程或已编译的微信产物时,先用 `mearl --help` 检查已注册插件中是否有 `wxa`。缺失时,从已包含此 Skill 且当前可访问的官方来源补装:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
{{setup}} plugin install https://github.com/mearlhq/wechat-profile --skill wechat-miniprogram --yes
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
官方来源暂不可用且本机已有包含此 Skill 的源码时,可直接注册:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
{{setup}} plugin "/path/to/wechat-profile/skills/wechat-miniprogram"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
两种方式都会准备运行依赖并注册 `wxa`。读取对应目录中的 `wechat-miniprogram` Skill,查看 `mearl wxa run --help` 后用 `mearl wxa run <项目路径>` 编译并打开预览。框架项目先构建微信产物。看完可以直接关闭预览标签页。若安装失败,报告具体阻塞。用户只要求普通微信 H5 / WebView 模拟时,查询目标浏览器是否支持微信端模拟。
|
|
42
|
+
|
|
43
|
+
## 开发与协作指引
|
|
25
44
|
|
|
26
45
|
`mearl-ego`、`mearl-skill-creator` 与 `mearl-provider-creator` 是指引型 Skill,没有可注册的脚本入口;直接用标准 Skills 工具安装,不运行 `setup plugin`:
|
|
27
46
|
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
## 环境安装、更新与卸载
|
|
27
27
|
|
|
28
28
|
CLI、Native Host、MCP 和云端核心运行包要求 Node.js >= 20.18.0。安装前用 `node --version` 确认版本;
|
|
29
|
-
不满足时先升级 Node
|
|
30
|
-
出现 `Unknown operation: plugin` 时,用 `
|
|
29
|
+
不满足时先升级 Node。环境安装使用 `{{setup}} --yes`,沿用所展示入口的包名、版本或标签及 registry。
|
|
30
|
+
出现 `Unknown operation: plugin` 时,用 `{{setup}} --version` 核对安装器版本;
|
|
31
31
|
未指定版本时,npm 可能因 Node 不兼容而选择历史版本。
|
|
32
32
|
|
|
33
|
-
环境管理使用 `
|
|
33
|
+
环境管理使用 `{{setup}} <install|update|uninstall>`,具体选项按子命令 `--help` 查询。Agent 执行 install/uninstall 时附加 `--yes` 或 `--non-interactive`,避免等待交互;人工终端可保留交互选择。
|
|
34
34
|
|
|
35
35
|
主动安装或更新本机环境时,setup 优先使用显式 `--preset <清单 URL 或路径>`,否则保留本机已选 preset;本机未选择时,在运行时初始化后、安装任何 Skill 前检查已连接扩展的受信 preset 并补齐本机组件。首次连接最多等待约一分钟。多个浏览器选择不同、来源不受信或状态不可读时会停止并提示显式选择,不猜测。浏览器未连接时仅安装基础环境,连接后重跑 setup 即可;普通连接和后台自动更新不触发首次本机 preset 安装。
|
|
36
36
|
|
|
@@ -49,7 +49,7 @@ CLI、Native Host、MCP 和云端核心运行包要求 Node.js >= 20.18.0。安
|
|
|
49
49
|
优先安装 [Chrome 商店版](https://chromewebstore.google.com/detail/mearl/aoehhjnofngknnjefamjbplchbolghkm),由 Chrome 管理更新。商店不可用或用户明确要求 setup 托管时,执行:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
|
|
52
|
+
{{setup}} extension --full --yes
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
该命令同时准备本地环境。人工在终端执行时可省略 `--yes`。
|
|
@@ -61,7 +61,7 @@ npx @mearl/setup@beta extension --full --yes
|
|
|
61
61
|
`mearl` 或 `mearl-native-host` 命令不存在时,在浏览器所在机器安装:
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
-
|
|
64
|
+
{{setup}} --local --yes
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
命令存在但连接失败时,先检查当前链路:
|
|
@@ -73,7 +73,7 @@ mearl check
|
|
|
73
73
|
只需隔离检查当前机器时使用 `mearl check --local`;路由参数与配置优先级见 `mearl check --help`。只有检查结果表明本地组件缺失、过期或初始化不完整时,才更新并重新初始化:
|
|
74
74
|
|
|
75
75
|
```bash
|
|
76
|
-
|
|
76
|
+
{{setup}} update --local --yes
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
<a id="eacces"></a>
|
|
@@ -125,7 +125,7 @@ client 会处理当前用户的 stale socket 并尝试恢复 native host;恢
|
|
|
125
125
|
1. 安装 cloud-server、统一 client 与当前 Agent 的全局 mearl skill:
|
|
126
126
|
|
|
127
127
|
```bash
|
|
128
|
-
|
|
128
|
+
{{setup}} --cloud --yes
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
setup 会启动 cloud-server 并输出连接命令。把输出的完整命令交给用户在浏览器所在机器执行,不自行拼接地址或 token。
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AppProfileContribution } from '@mearl/browser-core';
|
|
1
|
+
import { type AppProfileContribution, type ToolboxAgentConfig } from '@mearl/browser-core';
|
|
2
2
|
export declare class PluginError extends Error {
|
|
3
3
|
readonly code: string;
|
|
4
4
|
constructor(code: string, message: string, options?: ErrorOptions);
|
|
@@ -13,9 +13,8 @@ export interface PluginToolboxLocale {
|
|
|
13
13
|
title?: string;
|
|
14
14
|
description?: string;
|
|
15
15
|
}
|
|
16
|
-
export interface PluginToolboxAgentConfig {
|
|
16
|
+
export interface PluginToolboxAgentConfig extends Pick<ToolboxAgentConfig, 'layout' | 'pageElementActions'> {
|
|
17
17
|
skill: string;
|
|
18
|
-
layout?: 'drawer' | 'workspace';
|
|
19
18
|
}
|
|
20
19
|
export interface PluginToolboxContribution {
|
|
21
20
|
version: 1;
|
|
@@ -229,11 +229,18 @@ export function normalizePluginToolboxContribution(value) {
|
|
|
229
229
|
if (!skill || skill.length > 128 || !/^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/.test(skill)) {
|
|
230
230
|
throw new Error('toolbox.agent.skill 必须是有效的 Skill 名称');
|
|
231
231
|
}
|
|
232
|
-
const layout = agentCandidate
|
|
232
|
+
const { layout, pageElementActions } = agentCandidate;
|
|
233
233
|
if (layout !== undefined && layout !== 'drawer' && layout !== 'workspace') {
|
|
234
234
|
throw new Error('toolbox.agent.layout 必须是 drawer 或 workspace');
|
|
235
235
|
}
|
|
236
|
-
|
|
236
|
+
if (pageElementActions !== undefined && typeof pageElementActions !== 'boolean') {
|
|
237
|
+
throw new Error('toolbox.agent.pageElementActions 必须是布尔值');
|
|
238
|
+
}
|
|
239
|
+
agent = {
|
|
240
|
+
skill,
|
|
241
|
+
...(layout ? { layout } : {}),
|
|
242
|
+
...(pageElementActions !== undefined ? { pageElementActions } : {}),
|
|
243
|
+
};
|
|
237
244
|
}
|
|
238
245
|
if (candidate.order !== undefined &&
|
|
239
246
|
(!Number.isInteger(candidate.order) || candidate.order < 0 || candidate.order > 10_000)) {
|