@mearl/provider 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 +248 -0
- package/README.md +3 -1
- package/package.json +4 -3
package/README.en.md
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# @mearl/provider
|
|
2
|
+
|
|
3
|
+
[简体中文](README.md) | [English](README.en.md)
|
|
4
|
+
|
|
5
|
+
`@mearl/provider` defines Mearl's unified browser Provider contracts and runtime. Built-in Local Chrome and external
|
|
6
|
+
Providers share `BrowserProviderDefinition`; the runtime either runs inside Native Host
|
|
7
|
+
or connects through a local Provider Socket.
|
|
8
|
+
|
|
9
|
+
The action catalog directly reuses `@mearl/browser-core/browserActionProtocol`, without a separately generated copy.
|
|
10
|
+
|
|
11
|
+
## Core model
|
|
12
|
+
|
|
13
|
+
Mearl manages control sessions by default. Providers receive target instances, pages, and ordinary actions, without handling session IDs, resource ownership, or human handoff state. Release with `--session` ends only Mearl task control; instance closure, detachment, and Cookie synchronization use Provider lifecycle methods. Upload and download require `page_upload` and `page_download`, respectively, in `capabilities.actions`.
|
|
14
|
+
|
|
15
|
+
Mearl appends `session` to ordinary action responses with routing and control state only; `browser_control` handoff also includes session pages. Text refs from `page_snapshot` are directly actionable. Providers retain locator mappings in their runtime rather than exposing internal node-ID dictionaries.
|
|
16
|
+
|
|
17
|
+
`page_upload` receives `filePaths` on the execution host; Mearl stages caller files and browser artifacts. `page_download` receives `{ tabId, trigger, url?, timeout? }`: listen for downloads before clicking, wait for completion, then return `ProviderDownloadResult`: `{ filename, filePath, action, owned? }`. `filePath` is absolute on the local Provider process host; Providers retrieve remote files. `action` is the click result; `owned:true` lets Mearl delete the staged file after import. Mearl converts it to a browser artifact for saving, later upload, and session cleanup. Return an error on timeout or uncertain provenance without clicking again.
|
|
18
|
+
|
|
19
|
+
Provider v2 separates instance status from control mode:
|
|
20
|
+
|
|
21
|
+
- `status`: `connected`, `pairing`, `running_disconnected`, or `stopped`.
|
|
22
|
+
- `control`: Page actions are handled by the Provider, by the host's Extension/CDP, or have no current control channel.
|
|
23
|
+
|
|
24
|
+
Instances also declare `ownership`, `persistence`, currently permitted resource `operations`, stable
|
|
25
|
+
`references`, and publicly displayable `details`. Provider identity is independent of control transport, and persistent instances
|
|
26
|
+
need not pretend to be connected browsers.
|
|
27
|
+
|
|
28
|
+
## External Provider installation
|
|
29
|
+
|
|
30
|
+
External Provider packages declare `@mearl/provider` as a runtime dependency:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add @mearl/provider
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`package.json#mearl.provider` declares the protocol entry, browser type, and structured launch arguments:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"name": "@example/mearl-provider-device",
|
|
41
|
+
"version": "1.0.0",
|
|
42
|
+
"type": "module",
|
|
43
|
+
"mearl": {
|
|
44
|
+
"provider": {
|
|
45
|
+
"providerId": "example-device",
|
|
46
|
+
"name": "Example device provider",
|
|
47
|
+
"protocolVersion": 3,
|
|
48
|
+
"entry": "./dist/runtime.js",
|
|
49
|
+
"browserType": {
|
|
50
|
+
"name": "Device",
|
|
51
|
+
"help": ["Pair a device, then use its browserId with Mearl actions."],
|
|
52
|
+
"inputSchema": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"properties": {
|
|
55
|
+
"code": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"title": "Pairing code",
|
|
58
|
+
"placeholder": "Generated by default"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Schemas support string, number, boolean, array, and recursive object. Provider configuration can use
|
|
69
|
+
`browserType.configuration.inputSchema`. `mearl <providerId>` and
|
|
70
|
+
`mearl <providerId> --help` display `browserType.help`, so operation guidance evolves with the package version. If a same-name Skill plugin is registered,
|
|
71
|
+
the CLI appends a plugin command summary automatically; do not duplicate that list in `browserType.help`.
|
|
72
|
+
`local` is a reserved built-in ID.
|
|
73
|
+
|
|
74
|
+
## Minimal external runtime
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { createProviderServer, type BrowserProviderDefinition } from '@mearl/provider';
|
|
78
|
+
|
|
79
|
+
const definition: BrowserProviderDefinition = {
|
|
80
|
+
descriptor: {
|
|
81
|
+
providerId: 'example-device',
|
|
82
|
+
name: 'Example device provider',
|
|
83
|
+
version: '1.0.0',
|
|
84
|
+
},
|
|
85
|
+
browserType: {
|
|
86
|
+
name: 'Device',
|
|
87
|
+
inputSchema: {
|
|
88
|
+
type: 'object',
|
|
89
|
+
properties: { code: { type: 'string', title: 'Pairing code' } },
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
launch: async options => createDevice(String(options.code ?? '')),
|
|
93
|
+
close: async ({ browserId }) => removeDevice(browserId),
|
|
94
|
+
handleAction: async ({ browserId, action, data }) =>
|
|
95
|
+
dispatchDeviceAction(browserId, action, data),
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const server = createProviderServer({ definition });
|
|
99
|
+
await server.start();
|
|
100
|
+
server.updateBrowsers([
|
|
101
|
+
{
|
|
102
|
+
browserId: 'device-1',
|
|
103
|
+
name: 'Example device',
|
|
104
|
+
status: 'connected',
|
|
105
|
+
control: {
|
|
106
|
+
kind: 'provider',
|
|
107
|
+
capabilities: {
|
|
108
|
+
actions: ['tab_list', 'page_snapshot', 'page_click'],
|
|
109
|
+
screenshot: 'none',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
ownership: 'owned',
|
|
113
|
+
persistence: 'persistent',
|
|
114
|
+
operations: ['close'],
|
|
115
|
+
},
|
|
116
|
+
]);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Pairing devices use `status: "pairing"` with `pairing`; stopped persistent instances use
|
|
120
|
+
`status: "stopped"` and `control: { kind: "none" }`. Running instances without connected control use
|
|
121
|
+
`status: "running_disconnected"`。
|
|
122
|
+
The runtime validates schemas, state machines, operations, and page-action capabilities before calling implementations.
|
|
123
|
+
`capabilities.actions` must explicitly list implemented and verified actions. Do not derive it from all actions minus exclusions, which could falsely advertise new SDK actions. Forwarding adapters may automatically reconnect and retry only if a connection failure proves the request was never sent. Sent requests with missing responses and business execution failures must not be replayed automatically.
|
|
124
|
+
Optional implementations such as `start`, `detach`, `getAccess`, and `syncCookies` must match declared instance operations;
|
|
125
|
+
the Provider runtime coordinates these lifecycle methods while browser actions use the unified Mearl protocol.
|
|
126
|
+
|
|
127
|
+
Public `browser_launch` accepts `{ provider, providerOptions }` for all Providers and returns
|
|
128
|
+
the same `ManagedBrowserInfo` as `browser_list.browsers[]`: object-form Provider identity, state,
|
|
129
|
+
persistence policy, operations, and security metadata. Internal manager fields, control connections, and temporary access URLs are excluded.
|
|
130
|
+
Local top-level CLI arguments are convenience inputs. External Provider arguments must use `providerOptions`; the two cannot be mixed.
|
|
131
|
+
|
|
132
|
+
Built-in browsers retain local launch interactions; external Provider inputs are generated from `browserType.inputSchema`.
|
|
133
|
+
Both submit the same `providerOptions` structure.
|
|
134
|
+
Top-level schema `oneOf` can declare multiple complete object constraints,
|
|
135
|
+
such as creating or attaching sessions. Each branch has a `title`; the runtime requires input to match exactly one branch.
|
|
136
|
+
`not` excludes forbidden combinations. `default` initializes forms without implicitly modifying caller arguments.
|
|
137
|
+
Object field `copyCookieDomains` uses the `{ presets?, domains? }` Cookie scope convention.
|
|
138
|
+
With `component: "cookie-sync"`, the browser manager uses the shared Cookie
|
|
139
|
+
scope selector and requests selected-site permissions before submission. Without it, the field renders as an ordinary object.
|
|
140
|
+
`component: "switch"` renders compact boolean switches. `formHidden` hides advanced CLI/API-only
|
|
141
|
+
fields; `formWidth` controls width; `formDefault` initializes forms without changing runtime defaults;
|
|
142
|
+
`formHideOptional` hides only the optional marker, not validation; `formVisibleWhen` controls display and submission based on another field's emptiness.
|
|
143
|
+
`browserType.documentationUrl` declares an HTTP(S) documentation URL. `configuration.inputSchema` declares configuration inputs,
|
|
144
|
+
passed only to the selected Provider's `configure`, without page-local persistence.
|
|
145
|
+
|
|
146
|
+
Providers querying device pools, existing sessions, or dynamic options declare `browserType.dynamicLaunchForm: true`
|
|
147
|
+
and implement read-only `getLaunchForm({ variant?, values }, context)`.
|
|
148
|
+
`browserType.launchForm` can supply an initial form without network access, rendering fields and modes immediately.
|
|
149
|
+
Each `variants[]` entry can override mode defaults through `inputSchema/values/refreshOn/dynamicFields`.
|
|
150
|
+
`dynamicFields` identifies fields disabled during asynchronous queries; other fields and mode selection remain usable. A form status row shows loading.
|
|
151
|
+
The initial query carries static defaults and sends only parseable fields; final launch still validates all inputs strictly.
|
|
152
|
+
Input entered while waiting is retained. Mode or environment changes invalidate previous requests.
|
|
153
|
+
The manager uses the internal
|
|
154
|
+
`browser_providers` `launch_form` operation to obtain `ProviderLaunchForm`, without recognizing Provider IDs or business fields:
|
|
155
|
+
|
|
156
|
+
- `inputSchema` describes user inputs for the current mode; `required` controls required markers and submission validation.
|
|
157
|
+
- `variants` uses `id/title/description` for connection modes, with `variant` selecting the current mode.
|
|
158
|
+
- `values` contains fixed, non-sensitive Provider launch arguments, merged with user inputs on submission.
|
|
159
|
+
- String-field `options` use `{ value, label, description?, disabled? }`.
|
|
160
|
+
Disabled options are display-only. Provider `launch` revalidates final resource state.
|
|
161
|
+
- `refreshOn` identifies fields requiring a form query; changes clear selections in other option fields.
|
|
162
|
+
Refresh retains inputs and still-valid option selections; switching modes reapplies that mode's defaults.
|
|
163
|
+
- `message` displays query results; `blocked` prevents submission without resources or valid sessions.
|
|
164
|
+
|
|
165
|
+
Queries must not create or rent resources or return credentials. The runtime validates returned schemas, options,
|
|
166
|
+
modes, and fixed arguments. Final `launch` still validates against `browserType.inputSchema`; dynamic forms do not change CLI/API
|
|
167
|
+
argument contracts. Providers without dynamic forms use static schemas.
|
|
168
|
+
For local integration, link a local `@mearl/provider` build containing this public contract. Distribution requires matching releases
|
|
169
|
+
of the SDK, Mearl host, and Provider supporting dynamic forms.
|
|
170
|
+
|
|
171
|
+
Common `details` keys have fixed types: `headless` is boolean, `createdAt` is a parseable timestamp,
|
|
172
|
+
`cdpPort` is a valid port, `account` contains `nickname` and optional string `accountId/loginId`,
|
|
173
|
+
and `copiedCookies` contains string-array `domains` and nonnegative integer `count`. Other keys may contain non-sensitive JSON and are also displayed.
|
|
174
|
+
`references.kind` identifies resource categories, `id` is opaque, and `label` is the display name.
|
|
175
|
+
Common categories include `profile/session/image/context/context-name`; Providers may define others.
|
|
176
|
+
|
|
177
|
+
## Built-in runtime
|
|
178
|
+
|
|
179
|
+
Native Host runs Local directly with `createProviderRuntime(definition)`, without a Socket
|
|
180
|
+
or installation record. Built-in and external implementations share schema validation, state machines, and lifecycle dispatch. In-process host services can use `ProviderContext.host`; Provider contracts do not depend on Extension, Native Messaging, or
|
|
181
|
+
specific browser service SDKs.
|
|
182
|
+
|
|
183
|
+
Launching, configuring, or querying dynamic forms for a specific Provider starts only that Provider; full discovery checks all installed Providers. Mearl's control host manages queues and actions against caller absolute deadlines. Callers without deadlines use action-derived waits; persistent closure and long waits have no fixed two-minute limit. Adapter forwarding must cover the action's time budget and preserve uncertain-execution semantics when waiting fails.
|
|
184
|
+
|
|
185
|
+
setup manages external Provider installation, discovery, and startup:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npx @mearl/setup provider install <package>
|
|
189
|
+
npx @mearl/setup provider update <provider-id>
|
|
190
|
+
npx @mearl/setup provider uninstall <provider-id>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Socket protocol
|
|
194
|
+
|
|
195
|
+
The current Provider protocol version is **3**; request envelopes carry `protocolVersion`. Installation metadata,
|
|
196
|
+
runtime descriptors, running processes, and callers must match. Update the relevant packages and restart processes on mismatch.
|
|
197
|
+
|
|
198
|
+
- `browser_providers`: `operation: "configure"` carries `options`; `operation: "launch_form"` carries `variant?` and `values`.
|
|
199
|
+
- `browser_instances`: `operation: "start" | "detach" | "sync_cookies"`; synchronization carries `scope`, and envelope `browserId` selects the instance.
|
|
200
|
+
- `browser_launch`, `browser_close`, and `get_browser_access_url` retain their separate responsibilities.
|
|
201
|
+
- Mearl's control process handles `browser_sessions`, without forwarding to external Providers. Session release and instance `detach` are separate.
|
|
202
|
+
|
|
203
|
+
The SDK dispatches Socket requests to methods such as `configure/getLaunchForm/start/detach/syncCookies`.
|
|
204
|
+
The ordinary `browser_release` action does not detach instances; Mearl converts public CLI release without a session to `detach`.
|
|
205
|
+
Providers bundling the SDK must update it and rebuild. Editing installation metadata cannot replace running code.
|
|
206
|
+
|
|
207
|
+
## External task control and page enhancement
|
|
208
|
+
|
|
209
|
+
Providers managing their own task ownership and human handoffs can declare
|
|
210
|
+
`["external"]` in `browserType.controlSessionModes` and return `controlSessionMode: "external"` in instance `control.capabilities`.
|
|
211
|
+
The SDK checks Mearl host support at startup and before operations; unsupported hosts reject explicitly.
|
|
212
|
+
An instance's control mode is fixed within a runtime. External mode rejects Mearl `--session`; external tools own page ownership and handoff.
|
|
213
|
+
Providers omitting this field retain default behavior.
|
|
214
|
+
|
|
215
|
+
External Providers can bind Mearl Extension environment enhancement to authorized pages through
|
|
216
|
+
`createProviderEnhancementClient(providerId, browserId)`, calling `bind`, `invoke`, and `release`. Only device, App, and time-zone enhancement is allowed,
|
|
217
|
+
as advertised by the Extension. The current Extension exposes only time zones.
|
|
218
|
+
The channel applies domain authorization and page-control conflict checks without registering automation pages or granting ordinary page actions, arbitrary code execution, or closure.
|
|
219
|
+
Independent packages use `@mearl/provider-<id>`. EgoLite has native Space management and human handoff. The [mearl-ego Skill](../../skills/mearl-ego/SKILL.md) uses existing tools with the Mearl extension for simulation and debugging, without this Provider enhancement channel.
|
|
220
|
+
|
|
221
|
+
Implement read-only `getEnhancementTarget({ browserId, tabId }, context)`. Under external user control, return
|
|
222
|
+
`{ tabId, ready: false }`; when Agent control is confirmed, return
|
|
223
|
+
`{ tabId, ready: true, mainFrameId, url }`. A current physical `targetId` may replace `mainFrameId`.
|
|
224
|
+
Identity must come from the current browser target. When both are given, the host verifies both. Target-ID-only mode requires host target verification support.
|
|
225
|
+
URL narrows candidates but cannot alone prove page identity.
|
|
226
|
+
This callback and `listBrowsers` must be reentrant while `handleAction` awaits enhancement, without acquiring that operation's lock or claiming user pages.
|
|
227
|
+
|
|
228
|
+
Calls may carry the original request's absolute `deadline`, outside the business payload. Binding handles are scoped to pages, connection generations, and allowed actions;
|
|
229
|
+
process restarts or page identity changes require revalidation. After a mutation response is lost, later writes are isolated and cannot be replayed or rerouted through ordinary actions.
|
|
230
|
+
Explicit rebinding only revalidates identity; the execution host must resolve environment recovery conflicts that remain unconfirmed.
|
|
231
|
+
|
|
232
|
+
## Installed App resources
|
|
233
|
+
|
|
234
|
+
External-control Providers can read locally accepted App definitions and runtimes using
|
|
235
|
+
`createProviderAppResourceClient(providerId, browserId)`. `catalog(params?, deadline?)` returns catalog summaries only;
|
|
236
|
+
`resolve({providerTabId, profile, options?}, deadline?)` revalidates page control and identity, then returns compiled configuration,
|
|
237
|
+
capability/installation revisions, and exact runtime bindings and source. It does not install pages or execute business host services.
|
|
238
|
+
|
|
239
|
+
The full Native capability service resolves resources; Skill catalogs read registered snapshots without re-executing source files for discovery.
|
|
240
|
+
A resource protocol declaration only indicates an available reader. Explicit reads refresh and validate installation; slow or failed module initialization does not block ordinary Provider control-host startup.
|
|
241
|
+
Profiles containing bridges or globals without an explicit runtime use installed `app.defaultPageRuntime`. Missing runtimes are rejected,
|
|
242
|
+
without downgrading the profile into a fully prepared UA configuration. The SDK rechecks definition revisions, page proof, and source SHA-256.
|
|
243
|
+
The separate resource message limit is 16 MiB to accommodate JSON-encoded runtimes; ordinary enhancement remains limited to 1 MiB.
|
|
244
|
+
|
|
245
|
+
Providers store and reference verified code within their own instance/page scopes, preserving existing quotas and cleanup rules.
|
|
246
|
+
A Space listing is not the full physical browser target list and cannot justify reclaiming others' resources.
|
|
247
|
+
Obtaining resources does not establish backend support for root containers, bridge callbacks, or real authorization. Advertise App capabilities only after individual verification.
|
|
248
|
+
Hosts without the resource protocol declaration reject explicitly, without falling back to ordinary actions or arbitrary Node execution.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @mearl/provider
|
|
2
2
|
|
|
3
|
+
[简体中文](README.md) | [English](README.en.md)
|
|
4
|
+
|
|
3
5
|
`@mearl/provider` 是 Mearl 的统一浏览器 Provider 契约与运行时。内置 Local Chrome 和外部
|
|
4
6
|
Provider 使用相同的 `BrowserProviderDefinition`;区别只在于运行时位于 Native Host 进程内,
|
|
5
7
|
还是通过本地 Provider Socket 接入。
|
|
@@ -236,7 +238,7 @@ App 定义与运行时。`catalog(params?, deadline?)` 只返回目录摘要;
|
|
|
236
238
|
|
|
237
239
|
资源由完整 Native 能力服务解析,Skill 目录读取已注册快照;不会为发现目录重新执行 Skill 源文件。
|
|
238
240
|
资源协议声明只表示读取口存在;显式读取时才刷新和校验安装,能力模块的慢初始化或失败不阻塞普通 Provider 控制宿主启动。
|
|
239
|
-
|
|
241
|
+
含桥或全局变量且未显式指定运行时的端模拟配置,沿用已安装的 `app.defaultPageRuntime`;缺少运行时直接拒绝,
|
|
240
242
|
不将其降级为已完整准备的 UA 配置。SDK 会再次核验定义 revision、页面证明和源码 SHA-256。
|
|
241
243
|
独立的资源消息上限为 16 MiB,以容纳合法运行时的 JSON 编码;普通增强通道仍限 1 MiB。
|
|
242
244
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/provider",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Unified contracts and runtime utilities for built-in and external Mearl browser providers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
|
+
"README.en.md",
|
|
23
24
|
"dist",
|
|
24
25
|
"!dist/**/*.map"
|
|
25
26
|
],
|
|
@@ -35,8 +36,8 @@
|
|
|
35
36
|
"registry": "https://registry.npmjs.org"
|
|
36
37
|
},
|
|
37
38
|
"dependencies": {
|
|
38
|
-
"@mearl/daemon-core": "3.0.0
|
|
39
|
-
"@mearl/browser-core": "3.0.0
|
|
39
|
+
"@mearl/daemon-core": "3.0.0",
|
|
40
|
+
"@mearl/browser-core": "3.0.0"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/node": "^24.9.1",
|