@mearl/provider 2.13.0 → 2.14.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
@@ -1,36 +1,29 @@
1
1
  # @mearl/provider
2
2
 
3
- External browser providers use this package to register themselves with Mearl, publish their
4
- available browsers, and handle Mearl browser actions over a local socket.
3
+ `@mearl/provider` Mearl 的统一浏览器 Provider 契约与运行时。内置的 Local Chrome、AgentBay
4
+ 和外部 Provider 使用相同的 `BrowserProviderDefinition`;区别只在于运行时位于 Native Host
5
+ 进程内,还是通过本地 Provider Socket 接入。
5
6
 
6
- ## Installation
7
+ ## 核心模型
7
8
 
8
- Provider packages should declare `@mearl/provider` as a runtime dependency:
9
+ Provider v2 分开表达实例状态与控制方式:
9
10
 
10
- ```bash
11
- pnpm add @mearl/provider
12
- ```
11
+ - `status`:实例处于 `connected`、`pairing`、`running_disconnected` 或 `stopped`。
12
+ - `control`:页面操作由 Provider 自己处理、由宿主的 Extension/CDP 处理,或当前没有控制通道。
13
13
 
14
- Provider implementations import the package root. The `/host` and `/runtime` subpaths are for
15
- Mearl's setup, discovery, and routing processes rather than Provider business code.
14
+ 实例还会声明 `ownership`、`persistence`、当前允许的资源 `operations`、稳定
15
+ `references` 和可公开展示的 `details`。因此 Provider identity 不再等同于控制传输,持久化实例
16
+ 也不需要伪装成已连接浏览器。
16
17
 
17
- ## Provider lifecycle
18
+ ## 外部 Provider 安装
18
19
 
19
- 1. The provider package declares its protocol entry in `package.json#mearl.provider`.
20
- 2. `npx @mearl/setup provider install <package>` installs the package and registers its metadata.
21
- 3. `mearl browser_list` starts an `on-demand` provider when necessary.
22
- 4. The provider starts `createProviderServer()` and publishes browsers with `updateBrowsers()`.
23
- 5. Mearl reads browser discovery from the shared registry and routes each supported browser action
24
- to the provider socket with the provider-local browser id.
25
- 6. The provider removes its live browser records when it stops.
20
+ 外部 Provider 包将 `@mearl/provider` 声明为运行依赖:
26
21
 
27
- Mearl discovers only explicit manifests in `~/.mearl/providers/installed`. It does not scan or
28
- execute arbitrary global packages.
29
-
30
- ## Package metadata
22
+ ```bash
23
+ pnpm add @mearl/provider
24
+ ```
31
25
 
32
- Provider packages do not need a user-facing binary or lifecycle scripts. Their `package.json`
33
- declares an internal Node.js entry owned by the package:
26
+ 包的 `package.json#mearl.provider` 声明协议入口、浏览器类型和结构化启动参数:
34
27
 
35
28
  ```json
36
29
  {
@@ -41,90 +34,111 @@ declares an internal Node.js entry owned by the package:
41
34
  "provider": {
42
35
  "providerId": "example-device",
43
36
  "name": "Example device provider",
44
- "protocolVersion": 1,
37
+ "protocolVersion": 2,
45
38
  "entry": "./dist/runtime.js",
46
39
  "browserType": {
47
40
  "name": "Device",
48
- "parameters": [
49
- { "key": "code", "label": "Pairing code", "placeholder": "Generated by default" }
50
- ]
41
+ "inputSchema": {
42
+ "type": "object",
43
+ "properties": {
44
+ "code": {
45
+ "type": "string",
46
+ "title": "Pairing code",
47
+ "placeholder": "Generated by default"
48
+ }
49
+ }
50
+ }
51
51
  }
52
52
  }
53
53
  }
54
54
  }
55
55
  ```
56
56
 
57
- The entry must be a relative path to a file inside the installed package. Mearl launches registered
58
- providers on demand with the current Node.js runtime; packages cannot register arbitrary commands,
59
- arguments, working directories, or environment overrides.
57
+ Schema 支持 string、number、boolean、array 和递归 object;Provider 配置也可通过
58
+ `browserType.configuration.inputSchema` 声明。`local` `agentbay` 是内置保留 ID。
60
59
 
61
- ## Minimal runtime
60
+ ## 最小外部运行时
62
61
 
63
62
  ```ts
64
- import { createProviderServer } from '@mearl/provider';
63
+ import { createProviderServer, type BrowserProviderDefinition } from '@mearl/provider';
65
64
 
66
- const server = createProviderServer({
67
- descriptor: { providerId: 'example', name: 'Example provider', version: '1.0.0' },
68
- handleAction: async ({ browserId, action, data }) => {
69
- // Translate Mearl actions to the external browser-control backend.
70
- return { browserId, action, data };
65
+ const definition: BrowserProviderDefinition = {
66
+ descriptor: {
67
+ providerId: 'example-device',
68
+ name: 'Example device provider',
69
+ version: '1.0.0',
70
+ },
71
+ browserType: {
72
+ name: 'Device',
73
+ inputSchema: {
74
+ type: 'object',
75
+ properties: { code: { type: 'string', title: 'Pairing code' } },
76
+ },
71
77
  },
72
- createBrowser: async parameters => createDevice(parameters),
73
- deleteBrowser: async browserId => deleteDevice(browserId),
74
- });
78
+ launch: async options => createDevice(String(options.code ?? '')),
79
+ close: async ({ browserId }) => removeDevice(browserId),
80
+ handleAction: async ({ browserId, action, data }) =>
81
+ dispatchDeviceAction(browserId, action, data),
82
+ };
75
83
 
84
+ const server = createProviderServer({ definition });
76
85
  await server.start();
77
86
  server.updateBrowsers([
78
87
  {
79
88
  browserId: 'device-1',
80
89
  name: 'Example device',
81
- capabilities: {
82
- actions: ['tab_list', 'page_snapshot', 'page_click'],
83
- screenshot: 'none',
90
+ status: 'connected',
91
+ control: {
92
+ kind: 'provider',
93
+ capabilities: {
94
+ actions: ['tab_list', 'page_snapshot', 'page_click'],
95
+ screenshot: 'none',
96
+ },
84
97
  },
98
+ ownership: 'owned',
99
+ persistence: 'persistent',
100
+ operations: ['close'],
85
101
  },
86
102
  ]);
87
103
  ```
88
104
 
89
- `createBrowser` returns the Provider-local `browserId`, display `name`, and initial `status`.
90
- When the initial status is `pairing`, it also returns the same `pairing` metadata published during
91
- discovery, so `browser_launch` callers can present the QR URL without an extra `browser_list` call.
92
- Mearl converts that local id into the same global id shape returned by `browser_list`.
93
-
94
- A device provider can remain discoverable before its hardware is online by publishing a pairing
95
- browser. Mearl keeps it out of implicit action routing and can render its QR URL:
105
+ 配对中的设备使用 `status: "pairing"` 并提供 `pairing`;停止的持久化实例使用
106
+ `status: "stopped"` `control: { kind: "none" }`。运行但尚未接通控制链路时使用
107
+ `status: "running_disconnected"`。
108
+ Runtime 会统一校验 schema、状态机、操作能力和页面 action capability,校验通过后才调用实现。
109
+ `start`、`detach`、`getAccess`、`syncCookies` 等可选实现必须与实例声明的 operation 对应;
110
+ 这些是 Provider runtime 的内部能力,不会要求 Mearl 公共协议增加一一对应的 action。
111
+
112
+ 公共 `browser_launch` 对所有 Provider 接收 `{ provider, providerOptions }`,返回与
113
+ `browser_list.browsers[]` 相同的 `ManagedBrowserInfo`(对象形式的 Provider identity、状态、
114
+ 持久化策略、操作和安全元数据)。管理器内部字段、控制连接和临时访问地址不进入该结果。
115
+ Local/AgentBay 的 CLI 顶层参数是便捷输入,由协调层转换;不得与 `providerOptions` 混用。
116
+
117
+ 内置浏览器保留针对本地启动、云端创建和接管的专用交互;外部 Provider 根据
118
+ `browserType.inputSchema` 生成输入项。两者提交同一结构的 `providerOptions`。
119
+ Schema 的顶层 `oneOf` 可声明多个完整对象约束,
120
+ 例如创建与接管会话;每个分支用 `title` 命名,Runtime 要求输入恰好匹配一个分支,
121
+ `not` 可排除不允许的字段组合。`default` 是表单初始值,不会隐式修改调用方参数。
122
+ 对象字段 `copyCookieDomains` 约定使用 `{ presets?, domains? }` Cookie 范围结构;内置浏览器表单保留范围选择与授权交互。
123
+ `browserType.documentationUrl` 声明 HTTP(S) 文档地址;`configuration.inputSchema` 声明配置参数,
124
+ 配置只传给所选 Provider 的 `configure`,不存入页面本地存储。
125
+
126
+ `details` 中的通用键具有固定类型:`headless` 为布尔值,`createdAt` 为可解析时间字符串,
127
+ `cdpPort` 为有效端口,`account` 包含 `nickname` 和可选的字符串 `accountId/loginId`,
128
+ `copiedCookies` 包含字符串数组 `domains` 和非负整数 `count`。其余键允许非敏感 JSON,界面同样展示。
129
+ `references` 的 `kind` 表示资源类别,`id` 为不透明标识,`label` 为展示名;
130
+ 通用类别包括 `profile/session/image/context/context-name`,也允许 Provider 自定义类别。
131
+
132
+ ## 内置运行时
133
+
134
+ Native Host 使用 `createProviderRuntime(definition)` 直接运行内置 Provider,不需要创建 Socket
135
+ 或注册安装记录。内置与外部实现共享同一份 schema 校验、状态机和生命周期派发逻辑;需要宿主服务的进程内调用可通过 `ProviderContext.host` 注入,Provider 合同本身不依赖 Extension、Native Messaging 或
136
+ AgentBay SDK。
137
+
138
+ 外部 Provider 的安装、发现与启动仍由 `@mearl/setup` 管理:
96
139
 
97
- ```ts
98
- const pairing = {
99
- kind: 'qr' as const,
100
- url: 'https://example.test/pair?id=device-pairing',
101
- code: 'device-pairing',
102
- };
103
-
104
- const createBrowser = async () => ({
105
- browserId: 'device-pairing',
106
- name: 'Pair a device',
107
- status: 'pairing' as const,
108
- pairing,
109
- });
110
-
111
- server.updateBrowsers([
112
- {
113
- browserId: 'device-pairing',
114
- name: 'Pair a device',
115
- status: 'pairing',
116
- pairing,
117
- capabilities: { actions: [], screenshot: 'none' },
118
- },
119
- ]);
140
+ ```bash
141
+ npx @mearl/setup provider install <package>
142
+ npx @mearl/setup provider update <provider-id>
143
+ npx @mearl/setup provider uninstall <provider-id>
120
144
  ```
121
-
122
- Screenshot capability is declared as `native`, `reconstructed`, or `none`, so callers can retain
123
- the image while distinguishing real pixels from an HTML reconstruction.
124
-
125
- Capabilities stay in Mearl's internal routing registry and are returned by `get_versions` for a
126
- selected provider browser. They are intentionally omitted from `browser_list`; use
127
- `mearl check --browser <id>` to inspect them. The package accepts only declared browser-targeted Mearl
128
- actions. Mearl owns discovery, while `browser_launch` and `browser_close` are routed to the
129
- Provider's `createBrowser` and `deleteBrowser` handlers. Requests for undeclared actions are
130
- rejected before reaching the provider.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './types.js';
2
2
  export { PROVIDER_ACTIONS, isProviderAction } from './generated-provider-actions.js';
3
3
  export { providerDataDir } from './registry.js';
4
+ export { createProviderRuntime, validateProviderBrowser, validateProviderInput, } from './provider-runtime.js';
4
5
  export { createProviderServer } from './server.js';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './types.js';
2
2
  export { PROVIDER_ACTIONS, isProviderAction } from './generated-provider-actions.js';
3
3
  export { providerDataDir } from './registry.js';
4
+ export { createProviderRuntime, validateProviderBrowser, validateProviderInput, } from './provider-runtime.js';
4
5
  export { createProviderServer } from './server.js';
@@ -0,0 +1,5 @@
1
+ import type { BrowserProviderDefinition, JsonObject, ProviderBrowser, ProviderInputSchema, ProviderObjectSchema, ProviderRuntime } from './types.js';
2
+ export declare function isProviderInputSchema(value: unknown, depth?: number): value is ProviderInputSchema;
3
+ export declare function validateProviderInput(schema: ProviderObjectSchema, value: JsonObject): void;
4
+ export declare function validateProviderBrowser(browser: ProviderBrowser): void;
5
+ export declare function createProviderRuntime(definition: BrowserProviderDefinition): ProviderRuntime;