@mearl/client 2.1.0 → 2.2.1
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 +5 -2
- package/dist/actionTimeouts.js +22 -16
- package/dist/commands.d.ts +898 -4
- package/dist/commands.js +30 -9
- package/dist/generated-browser-action-protocol.d.ts +704 -0
- package/dist/generated-browser-action-protocol.js +150 -0
- package/dist/index.d.ts +41 -486
- package/dist/index.js +1 -16
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -40,6 +40,9 @@ mearl get_requests --payload '{"count":5}'
|
|
|
40
40
|
# 代理一个 HTTP 请求
|
|
41
41
|
mearl send_request --payload '{"url":"https://api.example.com","method":"GET"}'
|
|
42
42
|
|
|
43
|
+
# 以 multipart/form-data 上传本地文件
|
|
44
|
+
mearl send_request --payload '{"url":"https://api.example.com/upload","method":"POST","formData":{"folder":"assets"},"files":[{"fieldName":"file","filePath":"/absolute/path/image.png"}]}'
|
|
45
|
+
|
|
43
46
|
# 截图并保存
|
|
44
47
|
mearl page_screenshot --output ./screenshot.png
|
|
45
48
|
|
|
@@ -88,7 +91,7 @@ mearl browser_release
|
|
|
88
91
|
| TDBank | `tdbank_account` |
|
|
89
92
|
| 浏览器 | `browser_list` `browser_release` `browser_launch` `browser_close` |
|
|
90
93
|
|
|
91
|
-
页面交互动作(`page_click` / `page_type` / `page_hover` / `page_scroll` / `page_press` / `page_upload`)默认内置观察:同一次调用内执行动作并等待异步稳定,返回 `{ action, observation }`;传 `observe: false` 可关闭观察仅执行裸动作。观察结果不替代完整页面理解:`mode: "delta"` 只返回主文档中的 `effects.notifications`、`effects.interactives` 和 `effects.focus` 等高置信度信号,并明确携带 `scope: "main-document"`;可交互节点会尽量携带真实 backend `node.ref`,后续动作优先使用 ref,缺少 ref 时使用 `node.selector`。`mode: "navigation"` 且 `ready: true`
|
|
94
|
+
页面交互动作(`page_click` / `page_type` / `page_hover` / `page_scroll` / `page_press` / `page_upload`)默认内置观察:同一次调用内执行动作并等待异步稳定,返回 `{ action, observation }`;传 `observe: false` 可关闭观察仅执行裸动作。观察结果不替代完整页面理解:`mode: "delta"` 只返回主文档中的 `effects.notifications`、`effects.interactives` 和 `effects.focus` 等高置信度信号,并明确携带 `scope: "main-document"`;可交互节点会尽量携带真实 backend `node.ref`,后续动作优先使用 ref,缺少 ref 时使用 `node.selector`。`mode: "navigation"` 且 `ready: true` 时,页面已通过网络静默、骨架状态或保守的内容稳定判定,可在新页面重建快照。动作直接打开新标签页时,`observation.openedTabs` 返回新标签页的 `tabId`、URL、标题和加载状态,可直接把该 `tabId` 用于后续操作,不必调用 `tab_list`。通常仅在 `fullSnapshotRecommended` 为 true 时根据 `snapshotReasons` 回退;滚动后若下一步需要读取新视口内容,可按需获取 viewport 快照。`page_eval` 默认裸执行,只有显式传入 `observe` 对象时才启用观察。
|
|
92
95
|
|
|
93
96
|
`page_snapshot` 默认返回完整 AX Tree;长列表可传 `mode: "viewport"`,只需要当前视口内的控件时传 `mode: "interactive"`,已知 CSS 区域时传 `rootSelector`,已有 ref 时传 `rootRef`(可用 `ancestorDepth` 向上补充上下文),只查找特定文案或角色时传 `query`。视口内缺少 AX 控件语义时,`interactive` 会自动回退到 viewport,并返回 `fallbackMode: "viewport"`。`maxNodes` / `maxChars` 截断会同时保留首尾内容。
|
|
94
97
|
|
|
@@ -96,7 +99,7 @@ mearl browser_release
|
|
|
96
99
|
|
|
97
100
|
`browser_list` 统一列出普通浏览器和托管浏览器。`type` 区分 `regular` / `managed`,`status` 区分 `connected` / `running_disconnected` / `stopped`;只有 `connected` 的浏览器可作为操作目标。
|
|
98
101
|
|
|
99
|
-
`browser_release`
|
|
102
|
+
`browser_release` 仅在用户明确要求结束调试、退出接管或清理会话资源时使用,不作为普通任务收尾。它会释放当前目标浏览器的 debugger/CDP 控制和会话级临时状态(包括设备/时区模拟),保留浏览器及全部标签页;后续浏览器操作可自动重新建立控制。
|
|
100
103
|
|
|
101
104
|
托管浏览器使用独立 Profile 和动态 CDP 端口。控制浏览器需先登录 TDBank;生成的 SSO 地址在本地内部传递,新实例可以使用 `headless: true`(默认)完成测试账号登录。`copyCookieDomains` 可把控制浏览器指定域的 Cookie 复制到新实例,Cookie 值不会出现在命令结果或日志中;`userAgentMode: "desktop"` 可让实例使用匹配本机 Chrome 版本的桌面 UA。完整设计见 [托管浏览器与 TDBank 多账号设计](../../docs/managed-browsers.md)。
|
|
102
105
|
|
package/dist/actionTimeouts.js
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
+
import { PAGE_ACT_ACTIONS } from './generated-browser-action-protocol.js';
|
|
2
|
+
const SEND_REQUEST_FILE_TRANSFER_TIMEOUT_MS = 120_000;
|
|
1
3
|
function boundedNumber(value, fallback, minimum, maximum) {
|
|
2
4
|
const numeric = Number(value);
|
|
3
5
|
if (!Number.isFinite(numeric))
|
|
4
6
|
return fallback;
|
|
5
7
|
return Math.min(Math.max(numeric, minimum), maximum);
|
|
6
8
|
}
|
|
7
|
-
|
|
8
|
-
// 需与 browser-core/pageAct.ts 的 PAGE_ACT_ACTIONS 保持一致。
|
|
9
|
-
const OBSERVED_PAGE_ACTIONS = new Set([
|
|
10
|
-
'page_click',
|
|
11
|
-
'page_type',
|
|
12
|
-
'page_hover',
|
|
13
|
-
'page_scroll',
|
|
14
|
-
'page_press',
|
|
15
|
-
'page_upload',
|
|
16
|
-
]);
|
|
9
|
+
const OBSERVED_PAGE_ACTIONS = new Set(PAGE_ACT_ACTIONS);
|
|
17
10
|
export function resolveObservedActionTimeoutSec(data) {
|
|
18
11
|
const observe = data.observe ?? {};
|
|
19
12
|
const observationMs = boundedNumber(observe.timeoutMs, 3000, 500, 30000);
|
|
@@ -24,7 +17,10 @@ export function resolveObservedActionTimeoutSec(data) {
|
|
|
24
17
|
}
|
|
25
18
|
export function resolveActionTimeoutSec(action, data, fallback = 15) {
|
|
26
19
|
if (action === 'send_request') {
|
|
27
|
-
|
|
20
|
+
const transferTimeoutMs = Array.isArray(data.files) && data.files.length > 0
|
|
21
|
+
? SEND_REQUEST_FILE_TRANSFER_TIMEOUT_MS
|
|
22
|
+
: 0;
|
|
23
|
+
return Math.max(fallback, Math.ceil(((data.timeout ?? 30000) + transferTimeoutMs + 5000) / 1000));
|
|
28
24
|
}
|
|
29
25
|
if (action === 'send_mtop_request') {
|
|
30
26
|
return Math.max(fallback, Math.ceil(((data.timeout ?? 10000) + 5000) / 1000));
|
|
@@ -41,13 +37,23 @@ export function resolveActionTimeoutSec(action, data, fallback = 15) {
|
|
|
41
37
|
return Math.max(fallback, 90);
|
|
42
38
|
if (action === 'browser_close' || action === 'tdbank_account')
|
|
43
39
|
return Math.max(fallback, 20);
|
|
40
|
+
if (action === 'run_actions') {
|
|
41
|
+
const actions = Array.isArray(data.actions) ? data.actions : [{}];
|
|
42
|
+
const timeoutSec = actions.reduce((total, step) => {
|
|
43
|
+
const stepAction = String(step?.action ?? '');
|
|
44
|
+
if (!stepAction || stepAction === 'run_actions')
|
|
45
|
+
return total + 15;
|
|
46
|
+
return total + resolveActionTimeoutSec(stepAction, step?.data ?? {}, 15);
|
|
47
|
+
}, 0);
|
|
48
|
+
return Math.max(fallback, timeoutSec);
|
|
49
|
+
}
|
|
44
50
|
// 页面交互动作默认内置观察,超时需覆盖观察与导航窗口;observe:false 时是裸动作,用默认超时
|
|
45
|
-
|
|
51
|
+
const observedAction = OBSERVED_PAGE_ACTIONS.has(action);
|
|
52
|
+
const observationEnabled = action === 'page_eval'
|
|
53
|
+
? data.observe !== null && typeof data.observe === 'object' && !Array.isArray(data.observe)
|
|
54
|
+
: data.observe !== false;
|
|
55
|
+
if (observedAction && observationEnabled) {
|
|
46
56
|
return Math.max(fallback, resolveObservedActionTimeoutSec(data));
|
|
47
57
|
}
|
|
48
|
-
if (action === 'run_actions') {
|
|
49
|
-
const steps = Array.isArray(data.actions) ? data.actions.length : 1;
|
|
50
|
-
return Math.max(fallback, steps * 15);
|
|
51
|
-
}
|
|
52
58
|
return fallback;
|
|
53
59
|
}
|