@mearl/client 3.0.0-beta.5 → 3.0.0-beta.8

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.
Files changed (42) hide show
  1. package/README.md +18 -14
  2. package/dist/actionTimeouts.js +0 -3
  3. package/dist/autoUpdate.js +2 -1
  4. package/dist/bin.js +12 -5
  5. package/dist/capabilityHelp.d.ts +4 -0
  6. package/dist/capabilityHelp.js +68 -0
  7. package/dist/check.js +1 -1
  8. package/dist/cli.js +17 -16
  9. package/dist/commandHelp.js +3 -3
  10. package/dist/commandSuggestions.d.ts +3 -0
  11. package/dist/commandSuggestions.js +16 -5
  12. package/dist/commands.d.ts +50 -55
  13. package/dist/commands.js +41 -41
  14. package/dist/guide.d.ts +46 -0
  15. package/dist/guide.js +71 -0
  16. package/dist/guides/api-browser-setup.md +93 -0
  17. package/dist/guides/api-page-automation.md +140 -0
  18. package/dist/guides/api-page-debugging.md +39 -0
  19. package/dist/guides/api-page-environment.md +37 -0
  20. package/dist/guides/api-request-debugging.md +54 -0
  21. package/dist/guides/browser-tool-cooperation.md +23 -0
  22. package/dist/guides/core.md +60 -0
  23. package/dist/guides/related-skills.md +32 -0
  24. package/dist/guides/scripting.md +21 -0
  25. package/dist/guides/troubleshooting.md +170 -0
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +4 -5
  28. package/dist/plugins/officialPluginInstaller.js +2 -1
  29. package/dist/plugins/pluginRegistry.js +9 -3
  30. package/dist/plugins/runtime/pluginDiagnostics.js +1 -1
  31. package/dist/plugins/runtime/pluginHostServer.js +1 -1
  32. package/dist/plugins/runtime/pluginPageManager.js +2 -2
  33. package/dist/plugins/runtime/pluginStateManager.js +1 -1
  34. package/dist/plugins/runtime/pluginTaskManager.js +2 -2
  35. package/dist/plugins/sdk/plugin.d.ts +2 -0
  36. package/dist/plugins/sdk/plugin.js +17 -9
  37. package/dist/script.js +2 -1
  38. package/dist/socket.js +32 -8
  39. package/dist/unified.js +11 -1
  40. package/dist/unifiedConfig.d.ts +4 -0
  41. package/dist/unifiedConfig.js +11 -0
  42. package/package.json +10 -10
package/dist/guide.js ADDED
@@ -0,0 +1,71 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { CLIENT_VERSION } from './runtimePaths.js';
3
+ /** One catalog drives CLI navigation and the build-time resource copy. */
4
+ export const GUIDE_TOPICS = [
5
+ { id: 'core', file: 'core.md', title: '核心工作流与按需导航' },
6
+ { id: 'automation', file: 'api-page-automation.md', title: '控件、文件、弹窗与结果判读' },
7
+ { id: 'run', file: 'scripting.md', title: 'SDK、代码组合、超时与不确定结果' },
8
+ { id: 'debugging', file: 'api-page-debugging.md', title: '布局、遮挡、iframe 与视觉验证' },
9
+ { id: 'environment', file: 'api-page-environment.md', title: '设备、App、时区与 Cookie' },
10
+ { id: 'diagnostics', file: 'api-request-debugging.md', title: '接口、日志、埋点、权限与 Mock' },
11
+ { id: 'browsers', file: 'api-browser-setup.md', title: '目标、会话、远端与 Provider' },
12
+ { id: 'cooperation', file: 'browser-tool-cooperation.md', title: '与其他浏览器工具协作' },
13
+ { id: 'extensions', file: 'related-skills.md', title: '专用 Skill 与扩展开发入口' },
14
+ { id: 'troubleshooting', file: 'troubleshooting.md', title: '安装、连接与环境排查' },
15
+ ];
16
+ export function renderGuideLinks(source, commandName = 'mearl') {
17
+ return source.replace(/\[([^\]\n]+)\]\(([^)\s]+)\)/g, (original, label, href) => {
18
+ if (/^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith('#'))
19
+ return original;
20
+ const [file, section] = href.replace(/^\.\//, '').split('#');
21
+ const topic = GUIDE_TOPICS.find(topic => topic.file === file);
22
+ if (!topic)
23
+ throw new Error(`指南包含未打包的本地链接:${href}`);
24
+ return `${label}(\`${commandName} guide ${topic.id}\`${section ? `,小节 \`${section}\`` : ''})`;
25
+ });
26
+ }
27
+ /** Only packaged files are read; unknown IDs never become filesystem paths. */
28
+ export function readGuide(id, commandName = 'mearl', version = CLIENT_VERSION) {
29
+ const topic = GUIDE_TOPICS.find(topic => topic.id === id);
30
+ if (!topic)
31
+ throw new Error(`未知指南主题:${id}。用 ${commandName} guide --list 查看主题。`);
32
+ let source;
33
+ try {
34
+ source = readFileSync(new URL(`./guides/${topic.file}`, import.meta.url), 'utf8');
35
+ }
36
+ catch (error) {
37
+ throw new Error(`当前安装缺少指南资源:${topic.id}。请通过当前发行版的安装入口修复安装包;参数可用 ${commandName} <action> --help 查询。`, { cause: error });
38
+ }
39
+ return [
40
+ `[mearl:guide] CLI ${version} · ${topic.id}`,
41
+ '本指南随 CLI 分发;扩展、远端宿主与已安装能力仍须按目标实际帮助核验。',
42
+ '',
43
+ renderGuideLinks(source.trim(), commandName),
44
+ '',
45
+ `其他主题:${commandName} guide --list;具体参数:${commandName} <action> --help。`,
46
+ `[mearl:guide] end ${topic.id}`,
47
+ ].join('\n');
48
+ }
49
+ export function runGuideCli(args, commandName = 'mearl', version = CLIENT_VERSION) {
50
+ const list = () => GUIDE_TOPICS.map(topic => ` ${topic.id.padEnd(18)}${topic.title}`).join('\n');
51
+ if (args.length === 1 && (args[0] === '--help' || args[0] === '-h')) {
52
+ console.log(`${commandName} guide — CLI ${version}\n\n用法:${commandName} guide [topic]\n ${commandName} guide --list\n\n默认只读 core;按需读取单个专题。只读本地资源,不连接浏览器或检查更新。\n\n${list()}`);
53
+ return 0;
54
+ }
55
+ if (args.length === 1 && args[0] === '--list') {
56
+ console.log(`${commandName} guide — CLI ${version}\n${list()}`);
57
+ return 0;
58
+ }
59
+ if (args.length > 1 || args[0]?.startsWith('-') || !GUIDE_TOPICS.some(topic => topic.id === (args[0] ?? 'core'))) {
60
+ console.error(`未知指南主题或选项:${args.join(' ')}。用 ${commandName} guide --list 查看主题。`);
61
+ return 2;
62
+ }
63
+ try {
64
+ console.log(readGuide(args[0] ?? 'core', commandName, version));
65
+ return 0;
66
+ }
67
+ catch (error) {
68
+ console.error(error instanceof Error ? error.message : String(error));
69
+ return 1;
70
+ }
71
+ }
@@ -0,0 +1,93 @@
1
+ # Mearl API 场景:浏览器初始化与管理
2
+
3
+ 需要管理控制会话、选择远端 connector、在同一 connector 下选择浏览器,或列出、启动、关闭、释放普通及 Provider 托管浏览器实例时读取本文件。设备、时区和 Cookie 操作见 [页面测试环境准备](./api-page-environment.md)。
4
+
5
+ ## 目录
6
+
7
+ - [浏览器实例](#browser-instances)
8
+ - [控制会话与人工交接](#control-sessions)
9
+ - [目标宿主与高级路由参数](#cloud-connectors)
10
+ - [可选浏览器 Provider](#browser-providers)
11
+
12
+ <a id="browser-instances"></a>
13
+
14
+ ## 浏览器实例
15
+
16
+ `browser_list` 返回普通浏览器和 Provider 托管浏览器。顶层包含 `count`、`connectedCount`、`defaultBrowserId`、`browsers`,部分来源发现失败时还会返回 `warnings`。公共字段包括 `browserId`、`name`、`type` 和 `status`:
17
+
18
+ - `type` 为 `regular` 或 `managed`。
19
+ - `status` 为 `connected`、`pairing`、`running_disconnected` 或 `stopped`;只有 `connected` 可作为页面操作目标。
20
+ - Provider 实例还会返回 `provider`、`ownership`、`persistence`、`operations`、`references`、`details` 和可选的 `pairing`。用 `operations` 判断当前可执行的生命周期操作。
21
+
22
+ `browser_launch` 默认启动本地独立 Chrome。外部 Provider 使用以下通用结构,具体 `providerOptions` 必须通过 `mearl <providerId>` 查询:
23
+
24
+ ```bash
25
+ mearl browser_launch --payload '{"provider":"<providerId>","providerOptions":{}}'
26
+ ```
27
+
28
+ 本机与远端 connector 同时存在时,用 `--local`、`--connector <id|name>`,或用 `--browser <global-id>` 同时指定宿主和 Cookie/UA 的来源浏览器。启动响应中的全局 `browserId` 用于首次操作和交付;建立控制会话后,后续操作由 `--session` 固定目标,无会话时继续传选定的 `--browser`。
29
+
30
+ `browser_close` 关闭托管实例;`deleteProfile: true` 表示同时删除 Provider 持久化数据。是否支持关闭、删除、启动、同步 Cookie、detach 或访问入口,以实例的 `operations` 和 Provider 命令帮助为准。
31
+
32
+ 不带 `--session` 的 `browser_release` 通过 `--browser <id|名称>` 选择普通浏览器,只在用户明确要求结束调试、退出接管或清理环境时调用。它会释放 debugger/CDP 控制,清理依赖当前调试连接的 Mock、设备/时区模拟与持续采集,保留浏览器和标签页;存在活动控制会话时拒绝浏览器级释放。用户要求的终态依赖这些效果时保持控制。会话任务的收尾见[控制会话](#control-sessions);Provider 的 detach 或其他收尾遵循 `mearl <providerId>`。
33
+
34
+ 浏览器访问入口不会出现在 `browser_list` 中。只有用户明确需要时才运行 `mearl check --browser <id|名称>`,并把返回的 `browserAccess.url` 按敏感信息处理,不写入日志或转发给无关方。
35
+
36
+ <a id="control-sessions"></a>
37
+
38
+ ## 控制会话与人工交接
39
+
40
+ 扩展免打扰默认开启;`tab_open active:true` 为 HTTP(S) 页面启用后台焦点模拟,新页在首次导航前生效,不切换标签页或窗口。关闭免打扰后,`active:true` 才会真实激活并恢复最小化窗口。普通页面操作不会自动启用模拟。`activation.mode` 区分 `background` / `foreground`;模拟后的 `document.visibilityState` 可为 `visible`,不能据此判断窗口在前台。交给用户、释放控制或扩展连接断开时恢复,`preserveEnvironment` 不保留此临时状态;交还后按需用 `reuse:"require", active:true` 再次激活。未带会话时通过 `browser_release` 清理。纯 CDP 和外部 Provider 沿用各自激活能力。
41
+
42
+ 首次 `tab_open` / `page_snapshot` / `page_screenshot` 传 `--session new`,后续命令传 `--session <sessionId>`,使用响应的完整 `session.sessionId`。会话绑定浏览器与传输,页面操作同时指定 `tabId`;仅支持视觉感知的 Provider 可从截图建立会话。
43
+
44
+ 扩展新建的后台页面默认进入折叠的 `Mearl` 标签组,前台新页进入展开的 `Mearl · 待操作` 组;两个管理组复用同一个已有窗口,页面打开的后续标签继承源组状态。复用用户的普通页面保留原窗口和分组,`tab_open.group` 可指定其他分组。接管时会话内的管理页移入待操作组,交还后收回 `Mearl` 组;用户正在查看组内其他页面或窗口没有其他页面时保留展开状态。纯 CDP 和外部 Provider 沿用各自的页面组织方式。
45
+
46
+ 常规响应的 session 只包含 ID、浏览器、传输、状态、代次和可选 reason,不重复标签页清单。页面列表用 tab_list 查询;browser_control 的交接结果还包含会话页面的 tabs。CLI、SDK、MCP 使用同一结构。
47
+
48
+ 会话自动记录新建与复用页面,串行执行同页面操作,并阻止其他会话或无会话调用占用其页面。不同任务使用独立会话;会话不隔离 Cookie 与存储,账号或浏览器共享资源冲突时使用独立浏览器。Extension、CDP 和采用 Mearl 控制的 Provider 共用这些规则;声明外部控制的 Provider(如 Ego)拒绝 Mearl 会话,交接和收尾沿用原工具。
49
+
50
+ `browser_control` 的 `operation:"handoff"` 将控制权交给用户,`tabId` 指定会话页面,`reason` 说明需要用户处理的事项。用户在 Mearl Popup 浏览器管理页接管和交还;无扩展 UI 的环境,在用户明确确认交还后调用 `operation:"resume"`。
51
+
52
+ - `CONTROL_SESSION_PAUSED`:停止派发动作,交还后重新快照或截图,根据当前状态继续,不重放未完成批次;已派发的操作可能仍然生效。
53
+ - `CONTROL_SESSION_NOT_FOUND`:会话不存在或已失效,在原浏览器以普通调用执行 `tab_list`,获取当前 `tabId` 并检查操作结果,再按任务需要建立新会话,避免重复写操作。
54
+
55
+ 任务结束调用 `browser_release --session <sessionId>`,释放该会话的控制归属并清理临时文件,默认保留页面、Mock 与模拟环境。payload 支持以下保留与清理选项:
56
+
57
+ | 参数 | 行为 |
58
+ | --- | --- |
59
+ | `closeCreatedTabs:true` | 关闭确认不再需要的会话新建页;复用的用户页面始终保留 |
60
+ | `keepTabIds` | 配合关闭新建页时保留结果页面 |
61
+ | `preserveEnvironment:false` | 清理会话页面的 Mock 与模拟环境 |
62
+ | `keepArtifactIds` | 保留指定浏览器文件产物,其他会话临时文件清理 |
63
+
64
+ 会话释放保留 Provider 实例;关闭、退出接管和同步 Cookie 使用原有实例操作,存在活动控制会话时先释放所属会话。
65
+
66
+ <a id="cloud-connectors"></a>
67
+
68
+ ## 目标宿主与高级路由参数
69
+
70
+ 默认不传宿主、连接或传输覆盖参数。`browser_list` 会同时查询当前机器和全部远端 connector,结果名称带机器前缀,`source` 包含远端机器的 `connectorId` 和 `connectorName`,全局 `browserId` 可跨 CLI 调用并自动选择本地或远端传输。需要指定目标时优先传这个全局 ID;完整实例名称跨来源唯一时也可由客户端解析。建立控制会话后,后续 action 只需传 `--session <sessionId>` 和页面参数。不要依赖名称片段的模糊匹配。
71
+
72
+ | 参数 | 作用 | 使用时机 |
73
+ | --- | --- | --- |
74
+ | `--local` | 只使用当前机器 | 限定本机清单、检查,或让 `browser_launch` 落到本机 |
75
+ | `--connector <id\|name>` | 只使用一台远端 connector | 限定远端清单、检查或启动宿主;名称或 ID 片段必须唯一 |
76
+ | `--cdp` | 本机强制使用 CDP,并隐含 `--local` | 需要验证或绕过 Extension 控制链路时 |
77
+ | `--server <url>` | 覆盖当前调用使用的 cloud-server URL | 自动配置不可用或临时排障时 |
78
+
79
+ `--local` / `--cdp` 不能与 `--connector` 同时使用。全局远端 `browserId` 已包含 connector,普通页面 action 不重复传 `--connector`。`--server` 的解析顺序见 `mearl check --help`,连接排障见[环境安装与连接排查](./troubleshooting.md#cloud-agent)。高级诊断命令 `mearl connector_list` 只用于查看没有可列出浏览器的 connector,普通浏览器操作无需先调用它。
80
+
81
+ <a id="browser-providers"></a>
82
+
83
+ ## 可选浏览器 Provider
84
+
85
+ Provider 的参数、配置和生命周期随独立包演进,Skill 只保留能力与安装入口。安装后必须读取 Provider 自带的当前帮助,不从本文件推断字段。
86
+
87
+ 支持的平台和设备来源以已安装 Provider 的能力声明及配套 Skill 为准。
88
+
89
+ 只询问能力或配置时不创建实例。执行任务前先运行 `mearl browser_list`:已有符合目标且 `status: "connected"` 的实例时直接复用;需要创建、配对、接入或收尾时,遵循对应 Provider 命令帮助。实例返回的全局 `browserId` 用于选择目标,无会话时后续统一页面 action 继续使用该 ID。
90
+
91
+ 用户只要求移动视口、移动 UA、触摸事件或机型样式时使用设备模拟,无需创建外部 Provider 实例。通过 connector 接入远端浏览器属于控制链路,平台实例由对应 Provider 管理。
92
+
93
+ 已有 Ego 任务的接入、只读候选查询及页面目标映射见[与其他浏览器工具协作](./browser-tool-cooperation.md)。该流程仅查询明确选择的本机 Provider,不广播查询全部来源。
@@ -0,0 +1,140 @@
1
+ # Mearl 场景:常规网页自动化
2
+
3
+ 普通操作遵循 [核心工作流](./core.md)。本文件用于复杂控件、派发差异、文件操作或增量结果不足以决策的情况。布局、iframe、脚本与视觉验证见[页面排障](./api-page-debugging.md),设备/App 联动见[环境准备](./api-page-environment.md)。
4
+
5
+ ## 打开与复用页面
6
+
7
+ `tabId` 标识当前浏览器与传输中的页面,取得后持续复用;控制会话通过 `--session` 固定目标与控制归属,页面动作仍传 `tabId`。`opened` / `reused` 区分新页与既有页,复用页应保留。移动态或 App 态首屏需在新建时设置;这些配置不应用于复用页,已有页使用对应设置 action。
8
+
9
+ 需要激活已有页面时,对同 URL 使用 `reuse: "require", active: true`,避免另外新开页面。激活方式与临时状态恢复见[浏览器控制与人工交接](./api-browser-setup.md#control-sessions)。
10
+
11
+ ## 快照范围与非语义控件
12
+
13
+ 优先 viewport、局部根节点或 query,避免长页面完整输出;每次快照后只使用本次返回的新 ref。
14
+
15
+ 快照文本中的 @eN 可直接用于后续操作,内部节点映射只保存在运行时;无名称、无 ref 且无状态的分组会折叠,控件状态与文本内容保留。
16
+
17
+ AX 空或稀疏时显式使用 dom;interactive 无 AX 控件时只回退到 AX viewport,不会自动切换来源。后台弹层仍在过渡时,等待明确可见条件,或用 full + query 核验结构。
18
+
19
+ 自定义复选框、单选框或开关没有原生/ARIA 语义时,AX 可能只返回相邻文案。以文案 ref 为根,用 dom 和 ancestorDepth 1–3 获取局部容器,从其中浏览器标记的 clickable ref 定位控件,不直接点击静态文案或猜 CSS。用观察、局部快照或 inspect 验证状态。
20
+
21
+ <a id="observe"></a>
22
+
23
+ ## 动作结果判读
24
+
25
+ 交互 action 默认返回动作与增量观察。`page_eval` 默认裸执行,`run_actions` 的步骤不带内置观察。
26
+
27
+ `observe: false` 且未开启 diagnostics 时返回裸动作结果,没有 `action` 或 `observation`;开启 diagnostics 时返回 `{ action, diagnostics }`。按实际返回结构判断,不将缺少 `action.success` 当作失败。
28
+
29
+ - **未派发**:`action.stage: "precondition"` 时按 error 修正输入;过期 ref 重建最小快照。此时没有 observation/diagnostics。
30
+ - **确认不确定**:`dispatch-uncertain` 时先看 attempt 中的请求目标、解析目标、命中、坐标、派发模式和输入序列确认状态,再用 observation 或最小快照判断是否已生效,确认未生效后才重试。attempt 本身不证明效果。
31
+ - **目标差异**:`resolvedTarget`、`dispatchTarget`、`hitTarget` 只在目标存在有效差异时展开;兼容字段 tag/text 或 strategy/distance 的省略不表示缺少派发。无法确定可点击祖先时,actionableAncestorCandidates 仅供检查,不会自动改点。
32
+ - **通知**:effects.notifications 是高置信度通知;transient 表示已出现后消失,只读取文案,不继续点击。
33
+ - **控件与焦点**:effects.interactives 和 effects.focus 的 node.ref/selector 可继续操作。recreated 是同一语义控件被框架重建,不是新业务入口;状态未变时不会重复返回 value/checked。
34
+ - **普通文本**:effects.texts 按需返回短小可见文本的 selector 和当前 text,例如独立计数或金额;不推断业务含义,也不代表可点击。最多 8 项、每项 160 字符;隐藏、遮挡、复杂结构或超限时仍按快照建议核验。
35
+ - **快照建议**:按 fullSnapshotRecommended 和 snapshotReasons 补最小范围内容。已有通知/控件仍可能遗漏未分类结构;changed=true 而 effects 为空只说明没有高置信度信号,不能直接判失败。
36
+ - **导航**:mode=navigation 中 loaded 只表示文档完成,ready 才表示可继续。network-idle 表示相关请求静默;content-stable 是长连接情况下按内容与 skeleton/busy 状态判断的就绪兜底。
37
+ - **上下文重建**:mode=unavailable 时重新建立快照。delta 的 URL/标题未变化时可省略;同页请求用 network.ready/settledBy/pendingRequests 判断。
38
+ - **新页面**:openedTabs 只报告当前目标 Tab 直接打开的页面。ready=true 时直接对其 tabId 建立快照,无需 tab_list。
39
+ - **观察稳定**:quiet 已有限等待仍运行的动画;无限动画不阻塞。no-change 不自动要求快照;timeout 结合 snapshotReasons 回退。
40
+
41
+ DOM 增量覆盖主文档(scope=main-document);iframe、Shadow DOM、Canvas 或纯视觉变化可能不在覆盖范围。按目标补局部快照,跨域 iframe 或视觉任务用截图。
42
+
43
+ ## page_click
44
+
45
+ 文本多匹配时按候选 role/name 缩小范围或取 ref;原生 select 可按 option 文本点击,无需脚本改值。
46
+
47
+ auto/dom 对原生 option 执行选择并触发 input/change,返回 `selectionState.valueBefore/valueAfter/selectedAfter`。这是事件派发后的即时状态;`selectedAfter` 为 false 表示选项未保持选中(例如页面处理器恢复了旧值),先检查页面再决定下一步。后续异步变化仍需按业务状态核验。禁用的 select、option、optgroup 不会被强行选择。自定义 ARIA option 仍走普通点击。
48
+
49
+ selector/ref 目标被嵌套容器裁剪时会先滚入可见区;仍裁剪或被弹层覆盖则返回前置条件错误。用 page_inspect 的 hitTest.occludedBy 确认遮挡。派发前的命中检查允许目标自己的祖先/后代。
50
+
51
+ auto 在可见页按设备使用可信 mouse/touch,在隐藏页回退 DOM;响应的 dispatchMode、pointerType、fallbackReason 说明实际路径。显式 touch 要求可见,显式 mouse 会强制尝试可信输入;只有任务明确依赖真实用户手势时才激活。
52
+
53
+ ## page_drag
54
+
55
+ 起点自动滚入视口,但终点需同时可见;否则先滚动。坐标适合 Canvas 或组件内手势,ref 适合可见元素拖放。DOM 回退属于不可信事件;页面拒绝不可信事件时再接管为可见页可信输入。
56
+
57
+ ## page_type
58
+
59
+ 填写表单后根据 observation 检查目标值及联动控件;不要仅以输入成功判断表单已提交。
60
+
61
+ ## page_hover
62
+
63
+ hover 展开菜单后需根据内容选择下一步时逐步执行;目标已确定且紧接点击时可用 run_actions。
64
+
65
+ ## page_press
66
+
67
+ 先确认焦点;隐藏页 DOM 输入只实现部分默认行为,依赖编辑、选择、方向键或页面滚动时用可见页 keyboard。用 defaultAction 判断是否模拟了所需语义。
68
+
69
+ 原生 alert/confirm/prompt/beforeunload 会阻塞页面 JS。内置扩展与 CDP 路径通过 `page_snapshot` 返回 `dialog.id/type/message/defaultPrompt`,不运行 DOM 快照;中断回执中的弹窗文本有长度上限,完整读取时按需提高快照 `maxChars`。确认含义后用现有按键接口显式处理:
70
+
71
+ ```bash
72
+ mearl page_press --payload '{"tabId":12345,"dialogId":"<dialog.id>","key":"Escape"}'
73
+ mearl page_press --payload '{"tabId":12345,"dialogId":"<dialog.id>","key":"Enter","promptText":"仅用于 prompt"}'
74
+ ```
75
+
76
+ 普通 Enter 不处理原生弹窗;过期 ID 会拒绝,不自动接受或重试。该分支返回裸按键结果 `dispatchMode:"native-dialog"`,不进入 DOM 观察。处理后重新读页面:页面中已派发的 JS 可能继续执行,工具不会回放旧动作。动作已确认成功、仅后续观察被弹窗打断时,保留 `action.success:true` 并附带 `dialog`;没有确认回执时按 `dispatch-uncertain` 核验业务状态。
77
+
78
+ 只能读取监测连接收到的弹窗事件。首次附加前已打开、由其他调试连接持有的弹窗可能阻塞 Chrome 的 Page.enable;此时有界超时并提示人工关闭后重试,不猜测弹窗内容或盲目接受。弹窗文本存储上限 65536 字符,超出时返回 `truncated:true`。
79
+
80
+ 接受 prompt 时省略 `promptText` 会保留预填默认值,显式传 `""` 才清空;默认值超出存储上限时必须显式指定 `promptText`,避免提交被截断的值。
81
+
82
+ ## page_scroll
83
+
84
+ 用 moved、atTop/atBottom 判断是否移动或到达边界;自动发现内部容器时复用 containerSelector。ref 指向子节点时可使用 nearest 找可滚动祖先。需要读取滚动后的新视口时补 viewport 快照。
85
+
86
+ ## page_wait
87
+
88
+ 没有前置动作,或 observation 表明仍需等待且已有明确条件时再调用;以 selector/text/condition 表达业务就绪,固定时间只用于任务本身要求经过一段时间的情况。
89
+
90
+ 服务端渲染页面的节点出现不等于客户端已可交互;需要时等待已确认的业务就绪信号(例如倒计时开始更新),避免输入被后续初始化覆盖。
91
+
92
+ 等待结束后需要立即点击已确认目标时,在同一次 `mearl run` 中 await 等待并紧接点击,不把两个动作拆到不同模型轮次:
93
+
94
+ ```bash
95
+ mearl run --session '<sessionId>' --timeout 240 <<'JS'
96
+ const tabId = 12345;
97
+ const ready = await mearl.pageWait({
98
+ tabId,
99
+ condition: '!!document.querySelector("form button[type=submit]:not(:disabled)")',
100
+ timeout: 200000,
101
+ interval: 100,
102
+ });
103
+ if (!ready.waited) throw new Error('Target did not become ready');
104
+ console.log(await mearl.pageClick({ tabId, selector: 'form button[type=submit]:not(:disabled)' }));
105
+ JS
106
+ ```
107
+
108
+ 整体 `--timeout` 要覆盖等待时限及后续动作;条件等待最多 300000ms。这会省去模型往返,但两次动作仍有传输与派发延迟,不保证原子执行。点击后检查动作结果与业务确认状态;失败或派发不确定时不要自动重放整段脚本。
109
+
110
+ ## page_navigate
111
+
112
+ 在同一 tabId 中导航、刷新或前进/后退,完成后建立新快照。
113
+
114
+ <a id="file-operations"></a>
115
+
116
+ ## page_upload
117
+
118
+ 找到 input[type=file] 后直接上传,隐藏节点也可用。文件来源按以下方式指定:
119
+
120
+ - 调用方文件:`files:[{filePath:"/absolute/path"}]`,自动中转到浏览器宿主。
121
+ - 浏览器产物:`files:[{artifactId}]`,使用 `page_download` 返回的产物;会话产物继续使用所属会话。
122
+ - 浏览器或 Provider 宿主文件:`filePaths:["/absolute/path"]`,路径属于执行上传的宿主;外部平台的文件中转按 Provider 帮助执行。
123
+
124
+ `files` 与 `filePaths` 互斥。确认页面显示附件或上传成功的业务状态;外部 Provider 的文件能力按其当前帮助执行。
125
+
126
+ ## page_download
127
+
128
+ 先监听下载,再执行 `trigger` 点击并等待下载完成。`trigger` 使用不含 `tabId` 的 `page_click` 参数;目标页面由顶层 `tabId` 指定。
129
+
130
+ `--output <绝对路径>` 将文件保存到调用方;省略时返回 `download.artifactId`,文件保留在浏览器宿主,可用于后续 `page_upload`。扩展无法通过 referrer 确认下载来源时,传入已知 `url`。下载超时或归属不确定时,先检查浏览器下载状态,再决定后续操作,避免重复点击。
131
+
132
+ ## 文件产物与传输
133
+
134
+ 文件中转的单文件上限为 256 MiB。Extension/CDP 支持上传与下载;外部 Provider 按 `capabilities.actions` 声明的 `page_upload`、`page_download` 使用对应能力。无会话产物空闲一小时回收,会话产物默认随 `browser_release --session <sessionId>` 清理,需要保留时传 `keepArtifactIds`。宿主退出清理暂存文件,保存到调用方的结果文件保留。
135
+
136
+ ## run_actions
137
+
138
+ 仅批量执行无需中间判断的紧密序列。失败时只检查已完成步骤与 failedStep;后续步骤未执行,不能将部分成功当作整个任务完成。
139
+
140
+ 连续填写等已知步骤可在同一次 `mearl run` 中使用 `observe:false`,最后检查提交前的表单状态或结果页;需要根据中间结果选目标时保留逐步观察。快照 `query` 必须是对象,例如 `{"query":{"text":"提交","exact":false}}`;切换标签用 `tab_open` 的 `reuse:"require",active:true`,刷新用 `page_navigate` 的 `refresh:true`,原生选项用 `page_click` 的 `role:"option"`。
@@ -0,0 +1,39 @@
1
+ # Mearl 场景:页面排障与视觉验证
2
+
3
+ 需要检查布局、遮挡或 iframe,读取结构化 action 无法取得的状态,或核验视觉效果时读取本文件。常规交互见[网页自动化](./api-page-automation.md)。
4
+
5
+ ## 浏览器扩展页面
6
+
7
+ 调试 Mearl 自身扩展页面时,复用已连接的日常浏览器,用 `tab_open` 打开已知的 `chrome-extension://` 页面入口,持续使用返回的 `tabId` 执行快照、交互和截图,无需另起浏览器。浏览器内部页与扩展页不申请网站域名授权,由 Chrome 检查实际调试权限;读取其他扩展或内部页面失败时,按实际错误处理。将 popup 或侧边栏入口作为普通标签页打开,验证的是页面内容,真实宿主上下文和浏览器外壳交互需要另行验证。
8
+
9
+ ## 布局、遮挡与滚动容器
10
+
11
+ 优先 `page_inspect`,无需先写 page_eval 脚本。CSS、ref 和 DevTools 当前选区 `$0` 都可检查。文本/role 查找先用 page_snapshot.query,取得 matches/ref 后 inspect。
12
+
13
+ `matches[].state` 返回原生或 ARIA 声明的 checked/selected/pressed/expanded/disabled/readonly,值带 `source`,支持 mixed;缺失字段表示没有可靠语义来源。
14
+
15
+ - 命中数量与尺寸:读取 count、boundingBox、computedStyle;scanTruncated 时 count 不是完整扫描结果。
16
+ - 点不到:hitTest.receivesPointerEvents=false 时检查 occludedBy;不要反复点击或直接合成事件。
17
+ - 页面横向溢出:用 horizontal-overflow 找节点,再查看样式与横纵溢出量。
18
+ - 页面不滚:用 scrollable 找容器,或检查 scrollContainer 后以 selector/ref 滚动。
19
+ - 用户提到 Elements 当前选中节点:用 `$0`,可取得 resolvedSelector、属性、XPath 和框架信息,再进行结构化操作或元素截图。
20
+
21
+ ## iframe 定位
22
+
23
+ 用 `page_frames` 获取 frameId 与 URL/name,不猜 frame ID。扩展/CDP 的 page_eval.frameId 都在指定 frame 的页面默认上下文执行;省略时容器/设备外壳使用当前业务 frame,普通页面使用主 frame。需要读取外层容器时显式传主 frame ID。
24
+
25
+ 扩展后端在目标 frame 内取得的坐标用于点击时,同时传该 frameId 与 coordinateSpace=active-frame,避免误用外层视口或另一个业务 frame 的坐标。CDP 点击尚不支持显式 frameId/active-frame 坐标,不将 page_eval 的 frame 支持推断到其他 action。
26
+
27
+ 跨域 iframe 或快照不足以反映的视觉内容使用截图。容器中的默认业务 frame 与显式 frame 的输入派发范围,以 action help 的后端支持说明为准。
28
+
29
+ ## 最小范围脚本
30
+
31
+ 结构化快照、inspect 或滚动无法表达需求时,使用只读 page_eval 读取必要状态。默认裸执行,只返回 result;需要变更信号或诊断时才显式启用 observe/diagnostics。
32
+
33
+ 获取 selector 后回到结构化 action;直接 DOM 改写或合成点击可能绕过页面真实逻辑,不能仅用表达式执行成功证明业务成功。
34
+
35
+ ## 视觉验证
36
+
37
+ 用 `page_screenshot --output <绝对路径>` 保存后交给图像查看能力;避免将 base64 stdout 放进文本上下文。支持当前视口和指定元素截图,元素截图可能滚动目标到可见区。
38
+
39
+ Canvas、纯视觉变化、跨域 iframe 或用户明确要求的 UI 核验才需要截图,不作为每个动作后的固定步骤。图片宽高是物理像素,按 CSS 尺寸 × DPR 解释。
@@ -0,0 +1,37 @@
1
+ # Mearl 场景:页面测试环境准备
2
+
3
+ 需要联动设备/App、折叠屏/分屏、时区或 Cookie 时读取本文件。设备预设与 App 档案以当前 CLI 为准,不从静态文档推断当前列表。远端/Provider 选择见[浏览器管理](./api-browser-setup.md)。
4
+
5
+ 设备模拟直接可用。App 模拟入口由已安装的能力包提供,档案可声明 UA、JSBridge 和容器行为。先查看 `mearl set_app_profile --help` 展示的目标浏览器动态目录;需要机器可读的桥方法、可调设置与默认版本时用 SDK `mearl.getCapabilities({ app: '目录中的完整 ID' })` 或 MCP `browser_get_capabilities`。按需读取 `usage.skills` / `usage.documentation`,再执行对应动作。
6
+
7
+ ## 设备模拟与设备外壳
8
+
9
+ 移动视口、UA、触摸或机型布局用 set_device_emulation;新建页在 tab_open.emulation 中传入,首屏直接生效。已有页用设置 action,保持 tabId。默认纯设备模拟,不创建 iframe;deviceShell=true 会在根 iframe WebView 内加载业务页并显示系统栏。
10
+
11
+ scale 只改变视觉比例,不改变页面读取的视口或 DPR。预设的真实生效方向、尺寸、UA 和触摸能力以设置响应为准;折叠设备可能按自然方向归一化,不自行按 ID 推断方向。旧预设仍保留原尺寸与 UA。
12
+
13
+ 设备外壳开启/移除需要重载。任务会话用 `browser_release --session <sessionId>` 收尾,默认保留设备与 App 模拟;明确需要清理时传 `preserveEnvironment=false`。不带会话的浏览器级 release 会清理依赖调试连接的模拟,关闭 Tab 后该 Tab 的配置失效。任务只要求切换配置时,成功响应足够;要求查看页面效果时再做快照/截图。
14
+
15
+ ## App 与设备联动
16
+
17
+ 只有用户明确要求 App、客户端、容器、JSBridge 或容器栈模拟时启用 set_app_profile / tab_open.appProfile;普通 H5、唤端链接、客户端分支或操作失败不是启用理由。
18
+
19
+ - 只注入桥:省略 emulation,保留设备状态;App 注入本身不创建根 iframe 或系统栏。
20
+ - 完整端模拟:同一个 set_app_profile 调用传 emulation;空对象采用档案推荐设备,设备外壳默认开启。
21
+ - 左右分屏:App 档案与 deviceShell=true、orientation=landscape、splitScreen=true 必须同时满足。新建页需要首屏分屏时,在 tab_open 同时传 appProfile 与该 emulation 组合。
22
+ - 桥方法覆盖:bridgeConfig 只声明受控行为、固定 JSON 回包或成功空实现,不执行配置脚本。
23
+ - 恢复:enabled=false 且省略 emulation 只清除 App;传 emulation={} 同时清除设备模拟。
24
+
25
+ 页面网络环境通过已安装预设声明的 networkControl 切换,传入其 id 和 value;省略保留当前设置,null 清除。可用控制项与取值以当前能力目录和预设文档为准。仅作用于目标 Tab,扩展模式与该 Tab 的快捷设置共享;关闭 Tab 或重启浏览器后清除。单次协议请求的参数不等于修改页面网络环境。
26
+
27
+ ## 时区
28
+
29
+ 用 set_timezone 覆盖目标 Tab 的 Date/Intl 时区,无需刷新;空字符串清除覆盖。按成功响应确认 enabled/timezone,不为单纯状态切换追加页面验证。
30
+
31
+ ## Cookie 与页面状态
32
+
33
+ 用已知 Cookie 名核验功能分支、实验或账号标识,不列举全部 Cookie、不读取认证 Token;HttpOnly 读取会被拒绝。
34
+
35
+ 只操作 Cookie 时可传 url,不为获取 tabId 额外打开页面;显式 tabId 用于选择该页的存储区(含无痕)。get_cookie 不回退同名分区 Cookie。
36
+
37
+ set_cookie 只写非分区 session Cookie,空值不删除。需要页面重新读取 Cookie 时显式 reload=true 并提供 tabId;响应不回显写入值。按响应或页面业务状态验证,托管身份鉴权使用已安装的身份插件。
@@ -0,0 +1,54 @@
1
+ # Mearl 场景:接口与埋点调试
2
+
3
+ 需要跨动作诊断、复现浏览器 HTTP/Protocol、处理域权限或设置 Mock/规则时读取本文件。
4
+
5
+ ## 选择诊断通道与输出范围
6
+
7
+ - get_requests 默认查询全部请求;source=requests 只查普通 HTTP,source=protocol 只查协议插件采集的请求。大响应先用 includeBody=false、keysOnly 或 fields 控制输出;指定非空 fields 时默认省略正文,同时需要全文才传 includeBody=true。省略正文时不返回 postData / responseBody 字段。
8
+ - get_logs 按级别/内容过滤,错误排查优先 error。
9
+ - get_events 查询 RUM/aplus/ARMS,默认只保留解析字段;排查原始上报才用 includeRaw。既有页首次查询才开启采集,无历史时按 hint 刷新或重新触发。
10
+
11
+ 流式请求开始后即进入缓冲区;isPending 表示仍未完成。SSE 分片按顺序累积,协议归类由已安装的请求插件提供。不能把尚未结束的流误判为无响应;无法归属当前 Tab 的 Service Worker 请求不在采集范围内。
12
+
13
+ ## 单次动作与跨动作边界
14
+
15
+ 单次动作显式传 diagnostics,由执行器在派发前建立边界、在观察后返回新增内容;不要为每个动作额外 checkpoint。diagnostics=true 默认包含 error logs 与业务 requests,埋点用 events 显式开启。observe=false 仍返回诊断,但不等待 DOM/导航稳定。
16
+
17
+ 跨多个动作时建立一次 tab_checkpoint,再用 after 查询本次操作新增的记录:
18
+
19
+ ```bash
20
+ mearl tab_checkpoint --payload '{"tabId":12345}'
21
+ # 执行要排查的操作后,使用上一步返回的 cursor
22
+ mearl get_logs --payload '{"tabId":12345,"after":"<cursor>","level":"error"}'
23
+ mearl get_requests --payload '{"tabId":12345,"after":"<cursor>","source":"all","includeBody":false}'
24
+ ```
25
+
26
+ 同一 checkpoint cursor 可分别作为 logs/requests/events 的初始边界;查询返回的 nextCursor 带通道作用域,只用于同类续读。hasMore 表示仍有记录,gap 表示缓冲区淘汰,不应把缺口视为没有事件。tab_open 的 capture.cursor 是导航前边界,可直接读取首屏诊断。
27
+
28
+ 日志时间用 timestampMs(epoch 毫秒);同一次埋点上报保持完整批次分页。缺少历史且 captureStatus=armed 时重新触发;inactive 时按 hint 排查采集链路。
29
+
30
+ ## 选择请求能力与执行宿主
31
+
32
+ 浏览器 HTTP 用 send_request;已安装插件提供的请求使用对应插件命令,其参数、认证和业务结果结构以插件帮助为准。不能只看 HTTP 成功判断业务成功。
33
+
34
+ 需要托管身份的接口使用已安装的专用能力插件,不手工传入其管理的凭据。协议与任务匹配见[相关 Skill 路由](./related-skills.md)。
35
+
36
+ multipart 文件路径属于 native-host 所在机器;调用方不能引用远端文件时用 base64。`send_request` 还支持 `bodyFile: {filePath, contentType}` 或 `{base64, contentType}` 直接发送原始二进制(不封装 multipart);与 body、formData、files 互斥,不支持 GET/HEAD。本地文件上限 40 MiB,Base64 解码上限 7 MiB。身份插件的文件路径属于插件执行宿主,两者不能混用。扩展模式 send_request 的 Cookie 不离开扩展;二进制响应按 bodyType=base64 解码保存,不作为大段文本载入。
37
+
38
+ ## 域权限失败
39
+
40
+ send_request 报 Cookie access not authorized / Permission denied / Host permission missing 时,按错误中给出的纯主机名调用 request_permission。用户在弹窗决定,只有 granted=true 才重试原请求;拒绝/关闭/超时则停止该次重试并说明缺少域授权。独立身份插件遵循自身权限流程。
41
+
42
+ ## 请求规则的作用域
43
+
44
+ 用 set_rule 添加规则,get_rules 回查;删除时使用 enabled=false 和 ruleId。扩展规则持久化,CDP 请求头规则属于当前会话;CDP 只支持 modifyHeaders 的请求头 set。按当前后端和 Provider 能力选择,不假定所有模式支持重定向、屏蔽或响应头改写。
45
+
46
+ ## Mock 场景与回查
47
+
48
+ 完整 mockData 适合替换响应,fields 适合基于真实响应微调。需要同一接口多种情况时用 conditions 子集匹配,按业务入参隔离;无条件规则会覆盖。$index 从 0 起描述同一场景调用顺序,不作为业务请求字段匹配。
49
+
50
+ 用 get_mocks 回查目标 tabId 的配置,然后触发页面业务请求验证效果。设置成功不等于页面已收到 Mock。`browser_release --session <sessionId>` 默认保留 Mock;不带 `--session` 的浏览器级释放会清理依赖调试连接的 Mock,保持 Mock 终态时保留环境。禁用目标 Mock 用 enabled=false。
51
+
52
+ ## 大 payload 与文件引用
53
+
54
+ 整包参数用 --payload-file;某个大字段用顶层字符串 "@<绝对路径>",客户端优先解析文件为 JSON,失败时用原文本。只展开顶层,不递归;读不到文件时保留字符串。文件展开仍走原传输通道,不绕过消息大小限制。
@@ -0,0 +1,23 @@
1
+ # 与其他浏览器工具协作
2
+
3
+ Mearl 单独使用时沿用主 Skill 的页面操作流程。任务已有 Ego、agent-browser 等工具时保留其任务归属,按需使用 Mearl 的环境和调试能力。安装状态不代表当前页面已经连通或获准执行。
4
+
5
+ ## EgoLite
6
+
7
+ 需要设备/App 模拟、接口或日志调试时,优先使用已安装的 `mearl-ego` Skill。该 Skill 通过 Ego 原生 API 管理 Space 与交接,通过已连接的 Mearl 扩展操作同一页面,无需额外 Provider 或插件注册。
8
+
9
+ 未安装协作 Skill 时遵循以下边界:
10
+
11
+ - 先读取 `ego-browser skill`,沿用当前 Space;创建、关联、人工交接与 `finish({ keep })` 均按 Ego 当前指南执行。
12
+ - Ego 浏览器需安装并连接 Mearl 扩展。用 `browser_list` 选择 `transport: "extension"` 的连接,记录完整 `browserId`。
13
+ - 在 Ego Page 读取 `page.cdp("Page.getFrameTree")` 的主 frame ID,再用扩展 `tab_list` 与 `page_frames` 核对。只有 `isMainFrame: true` 的 `frameId` 唯一匹配时,才使用该扩展 `browserId + tabId`;URL、标题和其他工具的页面标识不能代替核验。
14
+ - 每轮转入扩展写操作前,按 Ego 指南确认同一 Space 仍由 Agent 控制;用户接管、Space 失活或归属变化时两套工具均停止写入。扩展不会自动继承 Ego 的控制阻断,未知结果先观察,不换工具重放。
15
+ - 设备或 App 模拟开启期间,导航、交互、快照与截图使用扩展 action;Ego 鼠标输入可能与触摸模拟冲突,原生导航或截图可能改变设备参数。撤销并确认模拟清除后,再恢复 Ego 原生页面交互。
16
+ - App 档案须已安装并取得实际站点权限,以当前目标的帮助为准。桥对象存在不证明真实原生授权或支付能力;跨域 iframe 的原生 screen/DPR、媒体查询与 CSS 安全区也不保证与真机一致。
17
+ - 普通打开后设置模拟并重载,不等于业务页首次访问即处于模拟环境。需要首屏模拟时先确认当前工具支持的准备流程。
18
+ - 成功收尾遵守 Ego 的页面保留规则;保留结果页时保留用户需要的模拟状态。需要恢复时在结束前通过扩展显式恢复原配置;Mearl 会话释放不替代 Ego 收尾,也不保证清除模拟。
19
+
20
+ ## agent-browser 等其他工具
21
+
22
+ 目前没有通用第三方 tab ID/ref 转换入口,也没有其专用 Provider。保留原工具的交互能力;只有已通过受支持连接确认到同一物理页面时才调用 Mearl 增强。
23
+ 尚不能确认映射或后端未声明所需动作时,明确说明当前限制,不按 URL 猜页或把整个任务切换到另一浏览器。
@@ -0,0 +1,60 @@
1
+ # Mearl 核心工作流
2
+
3
+ 本指南说明通用操作流程。参数、返回字段以当前 CLI 的 `mearl <action> --help`、SDK `mearl.help()` 或 MCP 工具 schema 为准;MCP 使用实际提供的工具名,不猜命令映射。仅能使用 MCP、无法执行 CLI 时,直接使用当前 MCP 工具说明与 schema。组织发行版附带的安装、认证及业务指引继续有效,公共指南不替代这些说明。
4
+
5
+ ## 进入任务
6
+
7
+ 已有目标和明确动作时直接操作,不先做环境巡检。命令不可用或连接失败时再用 `mearl check`;本机连接按需恢复,不手工启动或保活 native host。安装和排障见[连接排查](./troubleshooting.md)。
8
+
9
+ ```bash
10
+ mearl tab_open --payload '{"url":"https://example.com","reuse":"prefer"}'
11
+ # 使用打开结果中的 tabId,观察后再选择本次快照提供的 ref。
12
+ mearl page_snapshot --payload '{"tabId":12345,"mode":"viewport"}'
13
+ mearl page_click --payload '{"tabId":12345,"selector":"@e3"}'
14
+ ```
15
+
16
+ ## 目标与控制归属
17
+
18
+ 页面动作持续复用同一浏览器与传输返回的 `tabId`。无可用页时才打开;已知 URL 优先 `reuse:"prefer"`,绑定开发页时沿用其 `openerTabId`。默认后台操作;确需可见输入时激活同一页。
19
+
20
+ 默认使用统一发现,不主动指定 `--local`、`--connector`、`--server` 或 `--cdp`。需要选择目标时用 `browser_list`,沿用返回的完整实例名或 `browserId`,不要另扫进程、端口。远端连接与 Provider 选择见[浏览器管理](./api-browser-setup.md)。
21
+
22
+ 需要任务归属、并行协作或人工交接时,首次 `tab_open` / `page_snapshot` / `page_screenshot` 传 `--session new`,后续复用完整 `session.sessionId` 与 `tabId`。会话固定目标,但 Cookie/存储仍共享。目标声明由外部工具控制时(例如 Ego 任务),沿用其交接与收尾,不传 Mearl `--session`;跨工具先核验同一实例和物理页面,不能仅凭 URL/标题或直接复用 ref、label、tab ID。详见[工具协作](./browser-tool-cooperation.md)。
23
+
24
+ ## 观察、操作与判读
25
+
26
+ 1. 需要理解页面或选择目标时取一次 `page_snapshot`;只要求截图时直接截图。优先 viewport、局部根节点或 query,确需全貌才取 full;AX 不足时再用 dom。只使用本次快照的 ref。
27
+ 2. 优先结构化点击、输入、滚动等动作。已知目标的紧密步骤可组合执行;有条件、循环或等待后立即点击时用 `mearl run`,见[代码组合](./scripting.md)。未知页面先输出最小观察,再由模型决定下一步,不预写未知 ref。
28
+ 3. 默认交互检查 `action.success`;`precondition` 表示未派发,可修正输入;`dispatch-uncertain` 表示可能生效,先看 attempt、observation 或必要快照,不直接重试。关闭观察且没有诊断时可能返回裸结果,按实际结构判读。
29
+ 4. 使用 effects、导航和 openedTabs 判断效果。新页已有 tabId 时直接使用。动作已内置观察,不固定追加等待、快照或截图;ref 过期、增量不足或 `fullSnapshotRecommended` 时再补观察。`changed:true` 且 effects 为空不表示失败。
30
+ 5. 用 URL、页面内容或实际配置核验用户要求的终态;动作成功或中间页不单独证明任务完成。视觉、Canvas、跨域 iframe 用截图;只要求切换设备/时区等状态时,以设置响应结束。
31
+
32
+ 复杂控件、文件、弹窗、派发差异见[网页自动化](./api-page-automation.md);遮挡、布局与视觉验证见[页面排障](./api-page-debugging.md)。布局问题先用 `page_inspect`,必要时做最小只读 `page_eval`,取得目标后回到结构化动作。
33
+
34
+ ## 环境与诊断按需启用
35
+
36
+ 移动视口、UA、触摸使用 `set_device_emulation`,首屏生效用 `tab_open.emulation`。仅在用户明确要求客户端、JSBridge 或容器时启用 App 模拟;普通 H5、唤端链接或操作失败不构成启用理由。
37
+
38
+ App 可用性以当前目标的 `set_app_profile --help` 或 `get_capabilities` 为准,沿用当前 browser/session。`partial`、`unsupported` 不等于空目录,`available:false` 不可启用。按需读能力包的 usage 指引,不自动安装;方法存在不证明真实授权、支付等业务能力可用。环境准备见[设备与 App](./api-page-environment.md)。
39
+
40
+ 已注册插件通过当前 `mearl --help` 或 SDK `mearl.help()` 发现,具体调用看插件帮助;本指南的专用 Skill 列表不代表全部已安装扩展。插件与 Provider 自己提供业务用法,核心入口不枚举它们的参数。
41
+
42
+ 只在任务需要日志、请求或埋点时开启 diagnostics;跨动作使用一次 checkpoint,再按 cursor 查询。输出范围、协议插件、域权限和 Mock 见[接口与埋点调试](./api-request-debugging.md)。不要为每次动作重复查询能力目录;接入、所需能力改变或连接失效时再核验。
43
+
44
+ ## 人工交接与收尾
45
+
46
+ 扫码、验证码或系统交互需要用户时,用 `browser_control` 的 handoff 交接,说明原因。用户接管或 `CONTROL_SESSION_PAUSED` 后停止派发;交回后重新观察,不重放未完成批次。无扩展 UI 时,须在用户明确确认交还后再 resume。
47
+
48
+ 会话任务用 `browser_release --session <id>` 释放归属,默认保留页面、Mock 和模拟环境。保留用户原有页和结果页,只有确认不需要的过程页才关闭。不带 session 的浏览器级释放仅用于用户要求结束调试或清理环境;外部工具按其自身约定收尾。具体归属与保留参数见[控制会话](./api-browser-setup.md#control-sessions)。
49
+
50
+ ## 按需深入
51
+
52
+ - [代码组合](./scripting.md):SDK、脚本上下文、超时和不确定结果。
53
+ - [网页自动化](./api-page-automation.md):控件、文件、弹窗与动作结果。
54
+ - [页面排障](./api-page-debugging.md):布局、遮挡、iframe、脚本及视觉。
55
+ - [环境准备](./api-page-environment.md):设备、App、时区、Cookie。
56
+ - [接口与埋点调试](./api-request-debugging.md):请求、日志、权限、Mock。
57
+ - [浏览器管理](./api-browser-setup.md):目标、会话、远端与 Provider。
58
+ - [工具协作](./browser-tool-cooperation.md):与 Ego、agent-browser 配合。
59
+ - [专用 Skill 路由](./related-skills.md):匹配站点/业务意图或开发扩展;不因可安装而主动安装。
60
+ - [连接排查](./troubleshooting.md):连接失败与环境管理。
@@ -0,0 +1,32 @@
1
+ # 相关 Skill 路由
2
+
3
+ 站点或业务对象与任务意图都匹配时,优先使用已安装的专用 Skill。通用网页操作继续使用 Mearl;不要仅因关键词相同就改用其他能力。专用站点的路由说明由对应 Skill 提供。
4
+
5
+ | 意图 | Skill |
6
+ | --- | --- |
7
+ | 时间戳、Base64、图片编码、URL 编解码 | format-converter |
8
+ | 记录或检索笔记与跨会话记忆 | notes-memory |
9
+ | 管理已有浏览器标签分组、关闭受控标签页 | browser-tab-manager |
10
+ | 用户明确要求使用 TinyPNG 压缩图片 | tinypng-compress |
11
+ | 把设计稿叠加到网页并做像素差异对比 | design-overlay |
12
+ | 为网页提供持续双语阅读 | immersive-translate |
13
+ | 运行 bb-browser 站点适配器 | mearl-bbrowser |
14
+ | Ego / EgoLite 任务中配合扩展进行端模拟、接口与日志调试 | mearl-ego |
15
+ | 开发或审查外部浏览器、真机 Provider | mearl-provider-creator |
16
+ | 把网站操作沉淀为可复用 Skill、CLI 或工具箱 GUI | mearl-skill-creator |
17
+
18
+ 有脚本入口的 Skill 可安装并自动注册插件:
19
+
20
+ ```bash
21
+ npx @mearl/setup@beta plugin install https://github.com/mearlhq/mearl --skill <skill-name> --yes
22
+ ```
23
+
24
+ 已可用的专用 Skill 按其说明执行;普通业务操作不因存在可安装能力就主动安装。用户拒绝、要求继续或 Skill 不适用时回到通用流程。
25
+
26
+ `mearl-ego`、`mearl-skill-creator` 与 `mearl-provider-creator` 是指引型 Skill,没有可注册的脚本入口;直接用标准 Skills 工具安装,不运行 `setup plugin`:
27
+
28
+ ```bash
29
+ npx skills add https://github.com/mearlhq/mearl --skill mearl-skill-creator --global
30
+ ```
31
+
32
+ 已有源码时也可将 Git 来源替换为实际 Skill 目录。安装前核对所选分支或标签确实包含目标 Skill;普通任务不主动安装开发指引。
@@ -0,0 +1,21 @@
1
+ # Mearl 场景:代码组合
2
+
3
+ 目标和后续动作已确定时,优先用 `mearl run` 合并连续调用,尤其是等待就绪后立即点击,避免模型往返错过短暂可操作窗口。需要条件、循环、过滤或组合已注册 Skill 命令时也用此入口。运行时已注入 `mearl` SDK,无需安装依赖:
4
+
5
+ ```bash
6
+ mearl run --session '<sessionId>' <<'JS'
7
+ const result = await mearl.invoke('get_requests', { tabId: 12345, count: 20 });
8
+ console.log(result);
9
+ // Skill 的 command/input 以其帮助为准:
10
+ // const data = await mearl.invokePlugin('插件名', { command: '命令名', input: {} });
11
+ JS
12
+ ```
13
+
14
+ 等待后立即操作的示例及超时设置见[常规网页自动化](./api-page-automation.md#page_wait)。等待条件和点击目标须已从页面确认;等待失败就停止,不继续点击。
15
+
16
+ - 浏览器 API 可用 `mearl.pageClick({ tabId, selector })` 等 SDK 方法,或沿用 action 名称的 `mearl.invoke(action, payload, options?)`;Skill 命令用 `mearl.invokePlugin(name, { command, input }, options?)`。参数和返回值与普通调用一致,仍检查 `action.success`、派发状态与业务效果。
17
+ - 方法、参数或结果不明确时,输出 `console.log(await mearl.help('pageClick'))`;它与 `mearl page_click --help` 共用帮助,`help()` 列出方法和已注册插件。插件用 `help({ plugin: '插件名', command: '命令名' })`。动态结果可输出 `mearl.structure(result)` 查看字段与类型;它只检查已取得的值,默认取有限深度、字段和数组样本,标注截断与循环引用,不代表完整契约。无需为理解结构重跑业务命令。
18
+ - `--browser` / `--session` 等路由参数由所有调用继承。`--session new` 时先 await 建立会话的浏览器调用,再执行插件或并发调用;随后自动复用返回的 ID,可读 `mearl.session`。每轮新建 Node 进程,JS 变量不保留,后续继续传同一 `sessionId` 和 `tabId`。
19
+ - 脚本拥有当前宿主的 Node 权限,继承工作目录和环境;使用 `await import()` 加载模块。DOM 代码放入 `mearl.pageEval`,浏览器动作优先使用结构化 API。stdout 只打印必要结果;未知页面需要模型理解时,输出最小观察后在下一轮决策,不预写未知 ref。
20
+ - `--file <path>` 可读取脚本文件,内容同样支持顶层 await 和动态 import。`--timeout <seconds>` 是整个脚本时限,默认 60 秒;源码最多 1 MiB,输出最多 256 KiB。await 所有 SDK 调用,失败不自动重试。超时或取消后查看 `pendingActions` / `mayHaveLateEffects`,先核验已派发操作;不要重放整段脚本。
21
+ - MCP 使用对应的 `browser_run_code` 工具。脚本适合代码可判断的流程,`run_actions` 保留给无需中间判断的紧密序列;需要模型理解或视觉判断时逐步操作。