🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@mearl/client

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mearl/client - npm Package Compare versions

Comparing version
2.2.0
to
2.2.1
+15
-5
dist/actionTimeouts.js
import { PAGE_ACT_ACTIONS } from './generated-browser-action-protocol.js';
const SEND_REQUEST_FILE_TRANSFER_TIMEOUT_MS = 120_000;
function boundedNumber(value, fallback, minimum, maximum) {

@@ -19,3 +20,6 @@ const numeric = Number(value);

if (action === 'send_request') {
return Math.max(fallback, Math.ceil(((data.timeout ?? 30000) + 5000) / 1000));
const transferTimeoutMs = Array.isArray(data.files) && data.files.length > 0
? SEND_REQUEST_FILE_TRANSFER_TIMEOUT_MS
: 0;
return Math.max(fallback, Math.ceil(((data.timeout ?? 30000) + transferTimeoutMs + 5000) / 1000));
}

@@ -37,2 +41,12 @@ if (action === 'send_mtop_request') {

return Math.max(fallback, 20);
if (action === 'run_actions') {
const actions = Array.isArray(data.actions) ? data.actions : [{}];
const timeoutSec = actions.reduce((total, step) => {
const stepAction = String(step?.action ?? '');
if (!stepAction || stepAction === 'run_actions')
return total + 15;
return total + resolveActionTimeoutSec(stepAction, step?.data ?? {}, 15);
}, 0);
return Math.max(fallback, timeoutSec);
}
// 页面交互动作默认内置观察,超时需覆盖观察与导航窗口;observe:false 时是裸动作,用默认超时

@@ -46,7 +60,3 @@ const observedAction = OBSERVED_PAGE_ACTIONS.has(action);

}
if (action === 'run_actions') {
const steps = Array.isArray(data.actions) ? data.actions.length : 1;
return Math.max(fallback, steps * 15);
}
return fallback;
}

@@ -167,3 +167,3 @@ import type { BrowserCommandAction } from './generated-browser-action-protocol.js';

readonly name: "send_request";
readonly description: "发送 HTTP 请求,自动携带浏览器 Cookie";
readonly description: "发送 HTTP 请求,自动携带浏览器 Cookie,支持 multipart 文件上传";
readonly params: [{

@@ -191,2 +191,10 @@ readonly name: "url";

}, {
readonly name: "formData";
readonly type: "object";
readonly description: "multipart 文本字段(值支持 string/number/boolean)";
}, {
readonly name: "files";
readonly type: "SendRequestFile[]";
readonly description: "multipart 文件,最多 20 个、总计不超过 40 MiB;Base64 文件总计不超过 7 MiB。每项传 fieldName 和绝对 filePath,或传 base64 + filename";
}, {
readonly name: "withCookies";

@@ -196,6 +204,2 @@ readonly type: "boolean";

}, {
readonly name: "cookieDomain";
readonly type: "string";
readonly description: "指定 Cookie 域名,不填时从 url 提取";
}, {
readonly name: "timeout";

@@ -205,3 +209,3 @@ readonly type: "number";

}];
readonly examples: ["send_request --payload '{\"url\":\"https://api.example.com/data\",\"method\":\"GET\"}'"];
readonly examples: ["send_request --payload '{\"url\":\"https://api.example.com/data\",\"method\":\"GET\"}'", "send_request --payload '{\"url\":\"https://api.example.com/upload\",\"method\":\"POST\",\"formData\":{\"folder\":\"assets\"},\"files\":[{\"fieldName\":\"file\",\"filePath\":\"/absolute/path/image.png\"}]}'"];
}, {

@@ -359,2 +363,6 @@ readonly name: "send_mtop_request";

}, {
readonly name: "openerTabId";
readonly type: "number";
readonly description: "来源 Tab ID;用于把目标 Tab 关联到来源侧边栏对话";
}, {
readonly name: "closeExisting";

@@ -401,3 +409,3 @@ readonly type: "boolean";

readonly name: "page_click";
readonly description: "点击页面元素,支持 selector / text / point 三种定位方式;auto 在可见页按设备模拟状态使用可信 mouse/touch,隐藏页使用 DOM fallback";
readonly description: "点击页面元素,支持 selector / text / point 三种定位方式;auto 在可见页按设备模拟状态使用可信 mouse/touch,隐藏页使用 DOM fallback;点击直接打开新标签页时 observation.openedTabs 返回目标信息";
readonly params: [{

@@ -404,0 +412,0 @@ readonly name: "selector";

@@ -128,3 +128,3 @@ export const COMMANDS = [

name: 'send_request',
description: '发送 HTTP 请求,自动携带浏览器 Cookie',
description: '发送 HTTP 请求,自动携带浏览器 Cookie,支持 multipart 文件上传',
params: [

@@ -136,7 +136,19 @@ { name: 'url', type: 'string', required: true, description: '完整目标 URL' },

{ name: 'body', type: 'any', description: '请求体(传对象时自动 JSON 序列化)' },
{
name: 'formData',
type: 'object',
description: 'multipart 文本字段(值支持 string/number/boolean)',
},
{
name: 'files',
type: 'SendRequestFile[]',
description: 'multipart 文件,最多 20 个、总计不超过 40 MiB;Base64 文件总计不超过 7 MiB。每项传 fieldName 和绝对 filePath,或传 base64 + filename',
},
{ name: 'withCookies', type: 'boolean', description: '是否附加浏览器 Cookie,默认 true' },
{ name: 'cookieDomain', type: 'string', description: '指定 Cookie 域名,不填时从 url 提取' },
{ name: 'timeout', type: 'number', description: '超时毫秒数,默认 30000' },
],
examples: [`send_request --payload '{"url":"https://api.example.com/data","method":"GET"}'`],
examples: [
`send_request --payload '{"url":"https://api.example.com/data","method":"GET"}'`,
`send_request --payload '{"url":"https://api.example.com/upload","method":"POST","formData":{"folder":"assets"},"files":[{"fieldName":"file","filePath":"/absolute/path/image.png"}]}'`,
],
},

@@ -265,2 +277,7 @@ {

{
name: 'openerTabId',
type: 'number',
description: '来源 Tab ID;用于把目标 Tab 关联到来源侧边栏对话',
},
{
name: 'closeExisting',

@@ -317,3 +334,3 @@ type: 'boolean',

name: 'page_click',
description: '点击页面元素,支持 selector / text / point 三种定位方式;auto 在可见页按设备模拟状态使用可信 mouse/touch,隐藏页使用 DOM fallback',
description: '点击页面元素,支持 selector / text / point 三种定位方式;auto 在可见页按设备模拟状态使用可信 mouse/touch,隐藏页使用 DOM fallback;点击直接打开新标签页时 observation.openedTabs 返回目标信息',
params: [

@@ -320,0 +337,0 @@ {

@@ -51,2 +51,25 @@ export interface GetRequestsParams {

}
export declare const SEND_REQUEST_MAX_FILES = 20;
export declare const SEND_REQUEST_MAX_TOTAL_FILE_BYTES: number;
export declare const SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES: number;
export type SendRequestFormValue = string | number | boolean;
interface SendRequestFileMetadata {
/** multipart/form-data field name. */
fieldName: string;
/** Defaults to a MIME type inferred from filename, then application/octet-stream. */
contentType?: string;
}
export type SendRequestFile = SendRequestFileMetadata & ({
/** Absolute path on the machine running Mearl native-host. */
filePath: string;
base64?: never;
/** Defaults to the basename of filePath. */
filename?: string;
} | {
filePath?: never;
/** Base64 payload; decoded Base64-backed files are limited to 7 MiB total. */
base64: string;
/** Multipart filename for the Base64 payload. */
filename: string;
});
export interface SendRequestParams {

@@ -58,4 +81,5 @@ url: string;

body?: unknown;
formData?: Record<string, SendRequestFormValue>;
files?: SendRequestFile[];
withCookies?: boolean;
cookieDomain?: string;
responseType?: 'json' | 'text' | 'auto';

@@ -208,2 +232,4 @@ timeout?: number;

active?: boolean;
/** Source tab whose Agent conversation should own the opened or reused tab. */
openerTabId?: number;
closeExisting?: boolean;

@@ -681,1 +707,2 @@ reuse?: 'never' | 'prefer' | 'require';

export declare function isExtensionBrowserAction(value: unknown): value is ExtensionBrowserAction;
export {};
// Generated by scripts/generate-client-action-protocol.mjs.
// Do not edit directly; update browser-core/src/browserActionProtocol.ts.
export const SEND_REQUEST_MAX_FILES = 20;
// Bounds multipart buffering in native-host and the extension service worker.
export const SEND_REQUEST_MAX_TOTAL_FILE_BYTES = 40 * 1024 * 1024;
// Base64 expands by 4/3; 7 MiB leaves roughly 680 KiB for JSON framing under
// the 10 MiB cloud message limit.
export const SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES = 7 * 1024 * 1024;
export const PAGE_ACT_ACTIONS = [

@@ -4,0 +10,0 @@ 'page_click',

@@ -9,4 +9,4 @@ /**

export type { InvokeOptions } from './socket.js';
export { BROWSER_ACTIONS, BROWSER_COMMAND_ACTIONS, EXTENSION_BROWSER_ACTIONS, PAGE_ACT_ACTIONS, isBrowserAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
export type { ActionStep, BrowserAction, BrowserActionMap, BrowserActionRequest, BrowserActionResponse, BrowserCloseParams, BrowserCommandAction, BrowserInfo, BrowserInfoBase, BrowserLaunchParams, BrowserListResult, BrowserReleaseFailure, BrowserReleaseResult, BrowserStatus, BrowserDevicePresetName, BrowserEmulationOptions, ExtensionBrowserAction, GetApiSchemaParams, GetCookieParams, GetCookieResult, GetEventsParams, GetLogsParams, GetMocksParams, GetRequestsParams, GetUserInfoParams, ManagedBrowserAccount, ManagedBrowserInfo, PageClickParams, PageActAction, PageEvalParams, PageFramesParams, PageHoverParams, PageNavigateParams, PageObservationWaitOptions, PagePressParams, PageScreenshotParams, PageScrollParams, PageSelectedElementParams, PageSnapshotParams, PageSnapshotQuery, PageTypeParams, PageUploadParams, PageWaitParams, RecordParams, RegularBrowserInfo, RequestDomainPermissionParams, RulesResult, RunActionName, RunActionsParams, SelectBrowserParams, SelectBrowserResult, SendMtopRequestParams, SendRequestParams, SetCookieParams, SetCookieResult, SetDeviceEmulationParams, SetMockParams, SetRuleParams, SetTimezoneParams, SetTimezoneResult, TabCloseParams, TabOpenParams, TdbankAccountParams, } from './generated-browser-action-protocol.js';
export { BROWSER_ACTIONS, BROWSER_COMMAND_ACTIONS, EXTENSION_BROWSER_ACTIONS, PAGE_ACT_ACTIONS, SEND_REQUEST_MAX_FILES, SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES, SEND_REQUEST_MAX_TOTAL_FILE_BYTES, isBrowserAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
export type { ActionStep, BrowserAction, BrowserActionMap, BrowserActionRequest, BrowserActionResponse, BrowserCloseParams, BrowserCommandAction, BrowserInfo, BrowserInfoBase, BrowserLaunchParams, BrowserListResult, BrowserReleaseFailure, BrowserReleaseResult, BrowserStatus, BrowserDevicePresetName, BrowserEmulationOptions, ExtensionBrowserAction, GetApiSchemaParams, GetCookieParams, GetCookieResult, GetEventsParams, GetLogsParams, GetMocksParams, GetRequestsParams, GetUserInfoParams, ManagedBrowserAccount, ManagedBrowserInfo, PageClickParams, PageActAction, PageEvalParams, PageFramesParams, PageHoverParams, PageNavigateParams, PageObservationWaitOptions, PagePressParams, PageScreenshotParams, PageScrollParams, PageSelectedElementParams, PageSnapshotParams, PageSnapshotQuery, PageTypeParams, PageUploadParams, PageWaitParams, RecordParams, RegularBrowserInfo, RequestDomainPermissionParams, RulesResult, RunActionName, RunActionsParams, SelectBrowserParams, SelectBrowserResult, SendRequestFile, SendRequestFormValue, SendMtopRequestParams, SendRequestParams, SetCookieParams, SetCookieResult, SetDeviceEmulationParams, SetMockParams, SetRuleParams, SetTimezoneParams, SetTimezoneResult, TabCloseParams, TabOpenParams, TdbankAccountParams, } from './generated-browser-action-protocol.js';
import type * as Protocol from './generated-browser-action-protocol.js';

@@ -13,0 +13,0 @@ export declare function getRequests(params?: Protocol.GetRequestsParams): Promise<Protocol.BrowserActionResponse<'get_requests'>>;

@@ -8,3 +8,3 @@ /**

export { invoke } from './socket.js';
export { BROWSER_ACTIONS, BROWSER_COMMAND_ACTIONS, EXTENSION_BROWSER_ACTIONS, PAGE_ACT_ACTIONS, isBrowserAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
export { BROWSER_ACTIONS, BROWSER_COMMAND_ACTIONS, EXTENSION_BROWSER_ACTIONS, PAGE_ACT_ACTIONS, SEND_REQUEST_MAX_FILES, SEND_REQUEST_MAX_TOTAL_BASE64_FILE_BYTES, SEND_REQUEST_MAX_TOTAL_FILE_BYTES, isBrowserAction, isBrowserCommandAction, isExtensionBrowserAction, } from './generated-browser-action-protocol.js';
import { invoke } from './socket.js';

@@ -11,0 +11,0 @@ export function getRequests(params = {}) {

{
"name": "@mearl/client",
"version": "2.2.0",
"version": "2.2.1",
"description": "Client SDK & CLI for Mearl — communicate with Chrome Extension via Unix Socket",

@@ -5,0 +5,0 @@ "type": "module",

@@ -43,2 +43,5 @@ # @mearl/client

# 以 multipart/form-data 上传本地文件
mearl send_request --payload '{"url":"https://api.example.com/upload","method":"POST","formData":{"folder":"assets"},"files":[{"fieldName":"file","filePath":"/absolute/path/image.png"}]}'
# 截图并保存

@@ -92,3 +95,3 @@ mearl page_screenshot --output ./screenshot.png

页面交互动作(`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` 时,页面已通过网络静默、骨架状态或保守的内容稳定判定,可在新页面重建快照。通常仅在 `fullSnapshotRecommended` 为 true 时根据 `snapshotReasons` 回退;滚动后若下一步需要读取新视口内容,可按需获取 viewport 快照。`page_eval` 默认裸执行,只有显式传入 `observe` 对象时才启用观察。
页面交互动作(`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` 对象时才启用观察。

@@ -95,0 +98,0 @@ `page_snapshot` 默认返回完整 AX Tree;长列表可传 `mode: "viewport"`,只需要当前视口内的控件时传 `mode: "interactive"`,已知 CSS 区域时传 `rootSelector`,已有 ref 时传 `rootRef`(可用 `ancestorDepth` 向上补充上下文),只查找特定文案或角色时传 `query`。视口内缺少 AX 控件语义时,`interactive` 会自动回退到 viewport,并返回 `fallbackMode: "viewport"`。`maxNodes` / `maxChars` 截断会同时保留首尾内容。