@mearl/client 2.14.0 → 2.15.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
@@ -63,15 +63,10 @@ npx @mearl/setup update --local
63
63
  # 查看某个 action 的帮助
64
64
  mearl <action> --help
65
65
 
66
- # 启动两个隔离的 headless Chrome,并分别登录不同 TDBank 账号
67
- mearl browser_launch --payload '{"name":"account-a","accountId":12345}'
68
- mearl browser_launch --payload '{"name":"account-b","query":"test_account"}'
66
+ # 启动两个隔离的 headless Chrome
67
+ mearl browser_launch --payload '{"name":"browser-a","url":"https://example.com"}'
68
+ mearl browser_launch --payload '{"name":"browser-b","persistent":true}'
69
69
  mearl browser_launch --payload '{"name":"cookie-copy","copyCookieDomains":["example.com"]}'
70
- mearl browser_launch --payload '{"name":"cloud-login","provider":"agentbay","persistent":true,"userAgentMode":"desktop","copyCookieDomains":["example.com"],"url":"https://example.com/account"}'
71
- mearl browser_launch --browser '<控制浏览器 browserId>' --payload '{"name":"cloud-login","provider":"agentbay","reuse":"require","copyCookieDomains":["example.com"]}'
72
- mearl browser_launch --browser '<本地来源 browserId>' --payload '{"sessionId":"<其他设备创建的 AgentBay sessionId>","copyCookieDomains":["example.com"]}'
73
- mearl browser_launch --payload '{"name":"cloud-tools","provider":"agentbay","copyCookieDomains":"mearl-services"}'
74
- mearl browser_launch --payload '{"name":"cloud-tools-plus","provider":"agentbay","copyCookieDomains":{"presets":["mearl-services"],"domains":["figma.com"]}}'
75
70
  mearl browser_launch --payload '{"name":"figma","userAgentMode":"desktop","copyCookieDomains":["figma.com"]}'
76
71
  mearl browser_list
77
72
  mearl browser_release
@@ -79,16 +74,19 @@ mearl browser_release
79
74
 
80
75
  ### 外部浏览器 Provider
81
76
 
82
- Provider 浏览器与扩展、CDP 和 AgentBay 浏览器一起出现在 `browser_list` 中,并使用同一个
77
+ Provider 浏览器与扩展、CDP 浏览器一起出现在 `browser_list` 中,并使用同一个
83
78
  全局 `browserId` 参与路由。Provider 的安装、更新和卸载由 `@mearl/setup` 管理:
84
79
 
85
80
  ```bash
86
81
  npx @mearl/setup provider install @ali/mearl-provider-brow
82
+ npx @mearl/setup provider install @ali/mearl-provider-agentbay
87
83
 
88
- # 让 Brow 创建一个配对实例;debugId 可省略并自动生成
89
- mearl browser_launch --payload '{"provider":"brow","providerOptions":{"debugId":"my-device"}}'
84
+ # 查看 Provider 当前版本的能力、参数与使用流程
85
+ mearl brow
86
+ mearl agentbay --help
90
87
 
91
- # 扫码后确认同一个实例已经连接
88
+ # Provider 启动参数统一放在 providerOptions
89
+ mearl browser_launch --payload '{"provider":"brow","providerOptions":{}}'
92
90
  mearl browser_list
93
91
 
94
92
  # 后续操作使用 browser_list 返回的全局 Browser ID
@@ -130,7 +128,7 @@ Mearl 默认聚合当前机器和已配置 cloud-server 下的浏览器,并通
130
128
  `browser_list --help` 和 `browser_launch --help` 会按场景展示宿主选择参数;连接或传输排障运行
131
129
  `mearl check --help`。其中 `--json` 仅用于输出机器可读的检查结果。
132
130
 
133
- ## Skill CLI 插件
131
+ ## Skill 插件
134
132
 
135
133
  安装 skill 并自动注册命令,或直接注册已有入口:
136
134
 
@@ -158,19 +156,44 @@ setup 会补齐缺失或低于自身版本的 client、native-host;安装参
158
156
  插件接受位置参数或包含 command/input 的 `--payload`,两种形式不能混用。JSON 保留业务字段类型;正文等文件输入
159
157
  按具体 skill 的字段约定处理。插件不使用上表中内置 action 的 `--payload-file` 入口。
160
158
 
159
+ 注册后的插件也可从 SDK 调用;实例方法 `client.invokePlugin` 复用既有连接和默认浏览器:
160
+
161
+ ```typescript
162
+ import { invokePlugin } from '@mearl/client';
163
+
164
+ const result = await invokePlugin(
165
+ 'yuque',
166
+ { command: 'read', input: { url: 'https://aliyuque.antfin.com/group/book/doc' } },
167
+ { browser: 'work' },
168
+ );
169
+ ```
170
+
171
+ MCP Server 通过固定工具 `mearl_plugin` 接受同样的 `plugin`、`command` 和 `input`,不会把插件子命令动态扩展成 MCP 工具。SDK 与 MCP 都只解析本机 registry 中已注册的名称,不接受任意入口路径。
172
+
161
173
  注册记录在 `~/.mearl/plugins/<name>.json`,保存入口路径和可选的简短描述;skill 业务代码原地更新直接生效,换路径或更新描述后重新注册。
162
174
  `plugin uninstall <name>` 会对 `~/.agents/skills` 中的全局 Skill 调用 `ali-skills remove --global --yes`,
163
175
  成功后清除相关注册;即使入口目录已被手动删除,也会完成 Ali Skills 跟踪记录的清理。
164
176
  手工路径只解除注册并保留源码。
165
177
  `PLUGIN_NOT_REGISTERED` 表示插件尚未注册。`PLUGIN_ENTRY_MISSING` 会显示失效入口,并给出带有实际插件名的
166
178
  卸载清理命令。其他错误按实际原因处理。
167
- 编写规范见 [Mearl Skill Creator 的 CLI 插件规范](../skills/mearl-skill-creator/references/cli-plugin.md)。
179
+ 编写规范见 [Mearl Skill Creator 的 Skill 插件规范](../skills/mearl-skill-creator/references/cli-plugin.md)。
180
+
181
+ 插件通过 `app.buc.request({ app, auth, url, ... })` 调用需要 BUC 身份的内部 HTTP 接口。`auth` 支持
182
+ `id-token`(默认)、`ticket-header` 和兼容旧服务的 `ticket-query`。Mearl 按请求创建一次性凭据并注入
183
+ `Authorization` + `DPoP`、`SSO-TICKET` Header 或 `SSO_TICKET` Query,只允许访问 HTTPS
184
+ `alibaba-inc.com` 域名;凭据不会返回给插件,也不会复用到下一次请求,调用方也不能自行传入这些认证字段。
185
+ `app.buc.whoami()` 返回当前身份的
186
+ `empId` 和姓名,并在 Agent 身份场景返回 `agentId`;仅在确实需要部门等详细字段时使用
187
+ `app.buc.profile()`,它通过一次性 `alineiwai` Ticket
188
+ 建立内存会话、校验资料属于当前员工,并只返回白名单字段,Ticket 与 Cookie 均不暴露给插件。
189
+ 缺少 BUC CLI 时 Mearl 会从官方 CLI Hub 安装后重试。这些方法与 `app.invoke` 一样,只能在插件 handler
190
+ 执行期间调用。BUC 请求始终在运行 CLI、SDK 或 MCP Server 的机器上执行,不会随浏览器或 connector 转发到远端浏览器宿主。
168
191
 
169
192
  ## 支持的操作
170
193
 
171
194
  | 分类 | Actions |
172
195
  | ------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
173
- | API 调试 | `tab_checkpoint` `get_requests` `get_logs` `get_events` `get_api_schema` |
196
+ | API 调试 | `tab_checkpoint` `get_requests` `get_logs` `get_events` |
174
197
  | Mock & 规则 | `set_mock` `get_mocks` `set_rule` `get_rules` |
175
198
  | 网络请求 | `send_request` `send_mtop_request` `request_domain_permission` |
176
199
  | 标签页 | `tab_open` `tab_close` `tab_list` |
@@ -178,9 +201,7 @@ setup 会补齐缺失或低于自身版本的 client、native-host;安装参
178
201
  | 组合调用 | `run_actions` |
179
202
  | 页面感知 | `page_snapshot` `page_screenshot` `page_selected_element` `page_frames` |
180
203
  | 环境与 Cookie | `set_device_emulation` `set_app_profile` `set_timezone` `get_cookie` `set_cookie` |
181
- | 用户信息 | `get_user_info` |
182
204
  | 录制 | `record_start` `record_stop` |
183
- | TDBank | `tdbank_account` |
184
205
  | 浏览器 | `browser_list` `browser_release` `browser_launch` `browser_close` |
185
206
 
186
207
  页面交互动作(`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` 默认裸执行,可按需开启观察或诊断。
@@ -193,9 +214,11 @@ setup 会补齐缺失或低于自身版本的 client、native-host;安装参
193
214
  `regular` / `managed`,`status` 区分 `connected` / `pairing` / `running_disconnected` /
194
215
  `stopped`;只有 `connected` 的浏览器可作为常规操作目标。
195
216
 
196
- 按 `sessionId` 接入的 AgentBay 浏览器用 `browser_release` 收尾:它会移除本机 attachment 并退出对应宿主,但不会关闭云端 Session。其他浏览器仅在用户明确要求结束调试、退出接管或清理会话资源时调用;它会释放 debugger/CDP 控制和会话级临时状态(包括设备/时区模拟),保留浏览器及全部标签页,后续浏览器操作可自动重新建立控制。
197
-
198
- 托管浏览器使用独立 Profile。控制浏览器需先登录 TDBank;生成的 SSO 地址在本地内部传递,本地实例可以使用 `headless: true`(默认)完成测试账号登录。AgentBay 固定为非 headless,传 `headless: true` 会被拒绝;`imageId` 可指定镜像别名或具体镜像 ID,省略时使用已验证的 Linux Browser Use 内网镜像。`persistent: true` 会让本地实例保留 Profile,让 AgentBay 同名实例绑定稳定的云端 Browser Context;正常关闭时同步 Cookie、LocalStorage、IndexedDB 等状态,下次启动无需再次复制本地登录态。`deleteProfile: true` 会显式删除对应 Profile 或 Context。AgentBay 的 `reuse` 支持 `never`(默认)、`prefer` 和 `require`:`prefer` 存在运行实例时复用、否则创建,`require` 只复用且不会意外创建计费会话。另一台设备已知确切 Session 时,可传 `sessionId` 直接通过 AgentBay CDP 接入,不需要 cloud-server;当前设备需配置能访问该 Session 的 `AGENTBAY_KEY`。provider-local ID 为 `managed:agentbay:session:<sessionId>`,跨 CLI 调用使用启动响应中的全局 `browserId`,且本机只持有 attachment。`copyCookieDomains` 传数组时复制指定域,传 `"mearl-services"` 时同步 Mearl 依赖平台登录态;需要同时复制基础登录态和额外站点时传 `{ "presets": ["mearl-services"], "domains": [...] }`。Cookie 值不会经过 cloud-server,也不会出现在命令结果或日志中;`userAgentMode: "desktop"` 让本地实例使用匹配本机 Chrome 版本的桌面 UA,AgentBay 则复用当前控制浏览器的桌面 UA。`browser_list` 仅返回浏览器的稳定配置,不携带 AgentBay 串流入口或沙箱 noVNC 地址。需要时显式运行 `mearl check --browser <id|名称>`,由统一的浏览器访问入口能力实时返回 `browserAccess`;AgentBay、OpenSandbox 和 AONE Sandbox 地址都应按敏感信息处理。完整设计见 [托管浏览器与 TDBank 多账号设计](../../docs/managed-browsers.md)。
217
+ `browser_release` 仅在用户明确要求结束调试、退出接管或清理会话资源时调用;它会释放
218
+ debugger/CDP 控制和会话级临时状态,保留浏览器及全部标签页。托管实例的启动、关闭、持久化、
219
+ 接入和登录态同步语义由各 Provider 声明;运行 `mearl <providerId>` 获取当前说明。访问入口不在
220
+ `browser_list` 中,需要时显式运行 `mearl check --browser <id|名称>`,并把返回的
221
+ `browserAccess.url` 按敏感信息处理。
199
222
 
200
223
  ## 架构
201
224
 
@@ -1,8 +1,8 @@
1
1
  import { PAGE_ACT_ACTIONS } from './generated-browser-action-protocol.js';
2
2
  const SEND_REQUEST_FILE_TRANSFER_TIMEOUT_MS = 120_000;
3
- // AgentBay staging can spend up to 60s transferring bytes and then 120s syncing the session disk.
3
+ // Remote Providers may stage files before forwarding a page upload.
4
4
  const PAGE_UPLOAD_FILE_TRANSFER_TIMEOUT_MS = 180_000;
5
- // AgentBay context sync can poll for about 12 minutes before session deletion waits up to 5 more.
5
+ // Persistent Providers may need to synchronize remote state before closing an instance.
6
6
  const BROWSER_CLOSE_TIMEOUT_SEC = 18 * 60;
7
7
  function boundedNumber(value, fallback, minimum, maximum) {
8
8
  const numeric = Number(value);
@@ -41,8 +41,6 @@ export function resolveActionTimeoutSec(action, data, fallback = 15) {
41
41
  return Math.max(fallback, 90);
42
42
  if (action === 'browser_close')
43
43
  return Math.max(fallback, BROWSER_CLOSE_TIMEOUT_SEC);
44
- if (action === 'tdbank_account')
45
- return Math.max(fallback, 20);
46
44
  if (action === 'run_actions') {
47
45
  const actions = Array.isArray(data.actions) ? data.actions : [{}];
48
46
  const timeoutSec = actions.reduce((total, step) => {
package/dist/buc.d.ts ADDED
@@ -0,0 +1,65 @@
1
+ interface ProgramResult {
2
+ stdout: string;
3
+ stderr: string;
4
+ }
5
+ export interface BucIdentity {
6
+ agentId?: string;
7
+ empId: string;
8
+ name?: string;
9
+ }
10
+ export interface BucProfile extends BucIdentity {
11
+ bucUserId?: string;
12
+ gid?: string;
13
+ empType?: string;
14
+ photoPath?: string;
15
+ displayName?: string;
16
+ nickName?: string;
17
+ deptId?: string;
18
+ admin?: boolean;
19
+ buName?: string;
20
+ buNo?: string;
21
+ deptDesc?: string;
22
+ lang?: string;
23
+ cid?: string;
24
+ jobDesc?: string;
25
+ loginWorkNo?: string;
26
+ }
27
+ export type BucRequestFormValue = string | number | boolean;
28
+ export type BucRequestAuth = 'id-token' | 'ticket-header' | 'ticket-query';
29
+ export interface BucRequestParams {
30
+ app: string;
31
+ url: string;
32
+ auth?: BucRequestAuth;
33
+ method?: string;
34
+ headers?: Record<string, string>;
35
+ params?: Record<string, string | number | boolean | null | undefined>;
36
+ body?: unknown;
37
+ formData?: Record<string, BucRequestFormValue>;
38
+ responseType?: 'json' | 'text' | 'auto';
39
+ timeoutMs?: number;
40
+ }
41
+ export interface BucRequestResult {
42
+ status: number;
43
+ statusText: string;
44
+ headers: Record<string, string>;
45
+ body: unknown;
46
+ }
47
+ export interface BucApi {
48
+ request(params: BucRequestParams): Promise<BucRequestResult>;
49
+ whoami(): Promise<BucIdentity>;
50
+ profile(): Promise<BucProfile>;
51
+ }
52
+ export type BucCommandRunner = (args: string[]) => Promise<ProgramResult>;
53
+ export interface BucDependencies {
54
+ fetch?: typeof fetch;
55
+ installBuc?: () => Promise<void>;
56
+ runBuc?: BucCommandRunner;
57
+ }
58
+ export declare const runBucCommand: BucCommandRunner;
59
+ export declare function installBucCli(): Promise<void>;
60
+ export declare function bucWhoami(dependencies?: BucDependencies): Promise<BucIdentity>;
61
+ export declare function bucProfile(dependencies?: BucDependencies): Promise<BucProfile>;
62
+ /** Executes one internal request with a fresh credential in the selected BUC authentication mode. */
63
+ export declare function bucRequest(input: BucRequestParams, dependencies?: BucDependencies): Promise<BucRequestResult>;
64
+ export declare const buc: BucApi;
65
+ export {};