npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mearl/client

v2.19.2

Published

Unified Mearl SDK & CLI for local and remote browsers

Readme

@mearl/client

统一浏览器 SDK 与 CLI。它会发现当前机器及已配置 cloud-server 下所有 connector 的浏览器,并根据 browser_list 返回的全局 browserId 自动选择本地 Socket 或云端 WebSocket 链路。

提供两种用法:类型安全的具名方法(getRequests、sendRequest 等),以及灵活的底层 invoke(action, payload)。

安装

npm install @mearl/client
# 或
pnpm add @mearl/client

SDK 使用

import * as client from '@mearl/client';

// 具名方法(类型安全)
const requests = await client.getRequests({ tabId: 12345, count: 5 });
const result = await client.sendRequest({
  url: 'https://api.example.com',
  method: 'GET',
  withCookies: true,
});

// 底层通用方法(灵活扩展)
const data = await client.invoke('send_request', { url: '...' });

// browser_list 默认聚合本机和所有远端 connector
const browsers = await client.browserList();
await client.getLogs({ tabId: 12345 }, { browser: browsers.browsers[0].browserId });

CLI 使用

安装后提供 mearl 命令:

# 获取最近 5 个请求
mearl get_requests --payload '{"tabId":12345,"count":5}'

# 代理一个 HTTP 请求
mearl send_request --payload '{"url":"https://api.example.com","method":"GET"}'

# 以 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"}]}'

# 截图并保存(tabId 来自 tab_open 或 tab_list)
mearl page_screenshot --payload '{"tabId":12345}' --output ./screenshot.png

# 从文件读取大体积参数(mock-data.json 需包含 tabId)
mearl set_mock --payload-file ./mock-data.json

# 环境自检
mearl check
mearl check --local --json

# 更新本地环境
npx @mearl/setup update --local

# 查看某个 action 的帮助
mearl <action> --help

# 启动两个隔离的 headless Chrome
mearl browser_launch --payload '{"name":"browser-a","url":"https://example.com"}'
mearl browser_launch --payload '{"name":"browser-b","persistent":true}'
mearl browser_launch --payload '{"name":"cookie-copy","copyCookieDomains":["example.com"]}'
mearl browser_launch --payload '{"name":"figma","userAgentMode":"desktop","copyCookieDomains":["figma.com"]}'
mearl browser_list
mearl browser_release

外部浏览器 Provider

Provider 浏览器与扩展、CDP 浏览器一起出现在 browser_list 中,并使用同一个 全局 browserId 参与路由。Provider 的安装、更新和卸载由 @mearl/setup 管理:

npx @mearl/setup provider install @ali/mearl-provider-brow
npx @mearl/setup provider install @ali/mearl-provider-agentbay

# 查看 Provider 当前版本的能力、参数与使用流程
mearl brow
mearl agentbay --help

# Provider 启动参数统一放在 providerOptions
mearl browser_launch --payload '{"provider":"brow","providerOptions":{}}'
mearl browser_list

# 后续操作使用 browser_list 返回的全局 Browser ID
mearl tab_list --browser '<browserId>'
mearl page_snapshot --payload '{"tabId":12345}' --browser '<browserId>'

npx @mearl/setup provider update brow
npx @mearl/setup provider uninstall brow

browser_launch 创建 pairing 实例时会直接返回 pairing.url 和可选的配对码;Agent 应把 URL 直接渲染为 二维码交给用户,扫码后确认同一 Browser ID 变为 connected,再开始页面操作。在设备连入前 该实例不会成为默认操作目标;可用 browser_close 删除对应 Provider 实例。每个 Provider 只接收它为该浏览器显式声明支持的 actions,截图能力同时标明为原生截图、重建画面或不支持。

输入不存在或拼写有误的 action 时,CLI 会基于可用命令和常见别名直接返回最多三个候选及调用示例, 不连接浏览器,也不会自动执行推荐命令。例如 mearl tab new 会优先推荐 mearl tab_open。

常用选项:

| 选项 | 说明 | | ------------------------ | ------------------------ | | --payload <json> | 直接传入 JSON 参数 | | --payload-file <path> | 从文件读取 JSON 参数 | | --timeout <seconds> | 请求超时时间 | | --compact | stdout 紧凑输出 | | --output <path> | 将结果写入文件(如截图) | | --browser <id\|名称> | 指定目标浏览器 |

Mearl 默认聚合当前机器和已配置 cloud-server 下的浏览器,并通过 browser_list 返回的全局 browserId 自动路由。以下覆盖参数仅在限定宿主或连接、传输排障时使用,因此不出现在默认 help:

| 选项 | 说明 | | ------------------------ | ------------------------------------- | | --connector <id\|名称> | 限制到一台远端机器 | | --local | 只使用当前机器 | | --cdp | 当前机器强制使用 CDP,并隐含 --local | | --server <url> | 覆盖自动读取的 cloud-server 地址 |

browser_list --help 和 browser_launch --help 会按场景展示宿主选择参数;连接或传输排障运行 mearl check --help。mearl check 检查连接与浏览器状态;mearl check --updates 还会并发查询 client、native-host、cloud-connector 和扩展的最新发布版本。发布版本查询最长等待约 1.5 秒, 无法访问发布源时会提示无法确认更新,不影响浏览器可用性检查。--json 输出机器可读的检查结果, 与 --updates 同用时包含更新状态。发现更新时会提示适用的命令:client/native-host 使用 npx @mearl/setup update,setup 管理的扩展使用 npx @mearl/setup extension。

全局安装的 mearl CLI 默认在每天首次使用后启动独立后台进程,查询最新发布版本,并比较 client、native-host、cloud-server 和 MCP server 的已安装版本。发现更新时调用 @mearl/setup update --yes --skip-skill 更新版本落后的运行环境及其共享 client,也支持独立安装的 CLI。 当前命令不等待网络或安装;检查和安装结果记录在 ~/.mearl/cli-auto-update-state.json。项目依赖和临时 npx 副本不会被自动修改。 浏览器扩展沿用其独立的更新入口。 在 ~/.mearl/config.json 中设置间隔天数或关闭自动更新:

{ "cliAutoUpdate": { "intervalDays": 7 } }
{ "cliAutoUpdate": false }

间隔按本地日历日计算。需要立即检查各组件的发布版本时,仍可运行 mearl check --updates。

Skill 插件

安装 skill 并自动注册命令,或直接注册已有入口:

npx @mearl/setup plugin install trip/mearl --skill yuque-doc-fetch --yes
npx @mearl/setup plugin install trip/mearl --skill buc-request --yes
npx @mearl/setup plugin install trip/mearl --skill authx-request --yes
npx @mearl/setup plugin /absolute/path/to/yuque-doc-fetch
npx @mearl/setup plugin uninstall yuque
mearl yuque read "https://aliyuque.antfin.com/group/book/doc"
mearl yuque --payload '{"command":"read","input":{"url":"https://aliyuque.antfin.com/group/book/doc"}}'
mearl yuque --help
mearl yuque --version

当已注册插件与 Provider 使用同一名称时,mearl <name> --help 会先显示 Provider 的启动和生命周期说明, 再自动追加插件注册的扩展命令;mearl <name> <command> --help 继续显示单个插件命令的详细帮助。 Provider 与插件仍可独立安装、更新和卸载,帮助聚合不会启动 Provider 或执行业务命令。

目录默认使用 scripts/main.mjs 或 scripts/main.py;两者同时存在时使用 JavaScript 入口。JavaScript 入口默认导出 register(app),Python 入口导出 register(app) 函数;两种入口都可声明简短的 name 和 description,并通过 app.command(signature, handler, description?) 注册动作、app.invoke(action, payload, options?) 复用当前浏览器上下文,并用 app.progress(message) 报告可选进度。JavaScript 插件还可传入 { message, data },让工具页通过可 JSON 序列化的 data 获取稳定的阶段、对象 ID 等机器信息;CLI 仍只显示 message。Python 的 app.invoke 是同步调用,handler 可以是普通函数或 async def。Python 插件要求 python3 >= 3.9,可用 MEARL_PYTHON 指定解释器路径;Mearl 不安装 Python 或执行 pip install。调用另一个插件时,payload 使用 { command, input } envelope;嵌套调用继承宿主选项并拒绝循环依赖。CLI 默认只输出最终结果,传入 --verbose 时才把进度写入 stderr。handler 返回文本或 JSON,宿主统一处理 --output、连接和错误。写命令在用户调用后直接执行,业务模块负责目标、状态、幂等和结果校验。 注册名优先使用显式名称,其次读取入口的 name metadata,最后回退到 skill 目录名;常规注册只传路径。 setup 会补齐缺失或低于自身版本的 client、native-host;安装参数透传给 Ali Skills,并固定全局共享安装。

需要单独检查插件时运行 mearl <name> --version。命令会解析注册记录并加载入口,但不连接浏览器; 退出码为 0 表示插件已注册且入口可加载,stdout 返回同目录 SKILL.md 的版本,缺少版本元数据时返回 unknown。 未注册、入口丢失或加载失败会以退出码 2 和对应的 PLUGIN_* 错误结束。普通业务调用无需预先检查,直接处理同样的错误即可。

插件接受位置参数、字符串业务选项或包含 command/input 的 --payload。业务选项推荐写成 --name=value,也接受 --name value,字段名与 handler 的 input 一致且不依赖位置顺序;同一字段不能同时 使用位置参数和业务选项,--payload 不能与前两种形式混用。JSON 保留业务字段类型;正文等文件输入按具体 skill 的字段约定处理。browser、timeout、output 等宿主选项保留原有含义;同名业务字段以及数字、 布尔值、对象和数组通过 --payload 传入。插件不使用上表中内置 action 的 --payload-file 入口。

注册后的插件也可从 SDK 调用;实例方法 client.invokePlugin 复用既有连接和默认浏览器:

import { invokePlugin } from '@mearl/client';

const result = await invokePlugin(
  'yuque',
  { command: 'read', input: { url: 'https://aliyuque.antfin.com/group/book/doc' } },
  { browser: 'work' },
);

MCP Server 通过固定工具 plugin_invoke 接受同样的 plugin、command 和 input,不会把插件子命令动态扩展成 MCP 工具。SDK 与 MCP 不接受任意入口路径;调用尚未注册的 buc、authx 或 tdbank 时,会通过匹配当前 client 版本的 setup 自动安装并重试一次。其他未注册名称返回 PLUGIN_NOT_REGISTERED。

注册记录在 ~/.mearl/plugins/<name>.json,保存入口路径和可选的简短描述;skill 业务代码原地更新直接生效,换路径或更新描述后重新注册。 plugin uninstall <name> 会对 ~/.agents/skills 中的全局 Skill 调用 ali-skills remove --global --yes, 成功后清除相关注册;即使入口目录已被手动删除,也会完成 Ali Skills 跟踪记录的清理。 手工路径只解除注册并保留源码。 PLUGIN_NOT_REGISTERED 表示插件尚未注册。PLUGIN_ENTRY_MISSING 会显示失效入口,并给出带有实际插件名的 卸载清理命令。其他错误按实际原因处理。 编写规范见 Mearl Skill Creator 的 Skill 插件规范。

插件可选导出 toolbox,注册后会出现在扩展 Popup 的工具箱中。页面资源放在 Skill 目录内,注册时由 Mearl 将入口 HTML 引用的本地 CSS、JavaScript 和图片内联为不可变页面包,不需要启动 HTTP 服务, 也不要求普通 HTML/CSS/JS 页面自行构建:

export const toolbox = {
  version: 1,
  title: '迭代管理',
  description: '查看多个仓库的改动与发布状态',
  icon: 'git-branch',
  locales: {
    en: {
      title: 'Iteration Management',
      description: 'Track changes and release status across repositories',
    },
  },
  agent: {
    skill: 'iteration-manager',
    layout: 'workspace',
  },
  page: {
    type: 'sandbox',
    runtime: 'preact',
    entry: 'assets/toolbox/index.html',
    commands: ['list', 'create', 'delete'],
  },
  order: 100,
};

export default function register(app) {
  app.command('list', async () => ({ items: await listItems() }));
  app.command('create <name>', async input => ({ item: await createItem(input.name) }));
  app.command('delete <id>', async input => ({ item: await deleteItem(input.id) }));
}

声明 agent 后工具页可以把任务交给对话 Agent;layout 默认为 drawer,宿主会提供顶部入口。 页面也可在 setAgentPanelVisible 或 runAgentTask 中为单次交互指定 drawer / workspace / inline; Agent 对话会保存在 Codex 会话历史中。带固定 18rem 左侧导航的工作台可默认使用 workspace,由导航项切换 Agent,并占满导航栏以外的主内容区;详情页仍可按需唤起右侧抽屉。 inline 用于把 Agent 嵌入工具页中的卡片或分区,调用时同时传入作为占位区域的 anchor 元素和稳定的 key;宿主会跟随该元素的滚动与尺寸变化同步面板位置。key 也可用于抽屉或工作区布局,为不同业务对象 隔离会话与输入草稿;setAgentPanelVisible 可同时传入绝对路径 cwd,让首次创建的会话直接绑定该目录。 传入 context 可为面板提供不显示为聊天消息的背景上下文;它会在用户首次发送消息、创建会话时作为 developer instructions 交给 Agent。

页面通过 await window.mearl.ready() 取得 { locale, theme, title, fontSize },通过 window.mearl.invoke(command, input?) 调用 commands 白名单中的同一插件命令。页面运行在无扩展 API、默认不可联网的 sandbox iframe 中;Native Host 校验插件身份、命令白名单和消息大小。页面包按 内容哈希缓存并分块传输,因此不会增加 Popup 的启动开销。使用模块脚本时需先打包为不再包含 import 的单文件;React、Vue 等工程可以把构建后的 index.html 作为 entry,注册流程仍负责最终资源封装。 需要无构建的组件与状态管理时可声明 page.runtime: 'preact',扩展会在页面完整性校验后注入固定的 Preact、Hooks 和 HTM 运行时。页面从 window.mearl.ui 读取 html、render、useState 等 API; window.mearl.ui.version 仅用于诊断,插件不能选择运行时版本。 宿主会同步扩展主题、字号,并注入 --mearl-bg-primary、--mearl-bg-secondary、 --mearl-text-primary、--mearl-text-secondary、--mearl-border、--mearl-bg-hover 和 --mearl-accent 等语义变量;主操作按钮使用 --mearl-action-primary、 --mearl-action-primary-hover 和 --mearl-action-primary-text,以保持与扩展按钮一致。

需要 BUC 身份的内部 HTTP 接口通过官方 buc 插件调用。CLI 使用 mearl buc request,业务插件使用 app.invoke('buc', { command: 'request', input });当前身份和人员资料分别使用 whoami 与 profile 子命令。BUC 插件按请求创建一次性凭据,只接受无 URL 凭据的 HTTPS 地址,过滤认证字段与 Cookie; 调用方须按已验证的业务契约确认目标服务可信。请求始终在运行 CLI、SDK 或 MCP Server 的机器上执行, 不随浏览器或 connector 转发。 buc request 支持与 send_request 同结构的 formData 和 files;files[].filePath 从该插件执行 宿主读取,而不是浏览器 native-host,无法引用宿主路径时使用 Base64 内容与 filename。

支持的操作

| 分类 | Actions | | ------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | API 调试 | tab_checkpoint get_requests get_logs get_events | | Mock & 规则 | set_mock get_mocks set_rule get_rules | | 网络请求 | send_request send_mtop_request request_domain_permission | | 标签页 | tab_open tab_list tab_close | | 页面感知 | page_snapshot page_inspect page_screenshot page_frames | | 页面操作 | page_click page_drag page_type page_hover page_scroll page_press page_wait page_navigate page_upload page_eval | | 组合调用 | run_actions | | 环境与 Cookie | set_device_emulation set_app_profile set_timezone get_cookie set_cookie | | 浏览器 | browser_list browser_launch browser_release browser_close |

页面交互动作(page_click / page_drag / page_type / page_hover / page_scroll / page_press / page_upload)默认等待异步稳定并返回 { action, observation }。参数、ref 或目标解析在派发前失败时返回 action.stage: "precondition",省略无意义的 observation / diagnostics;浏览器可能已收到输入但确认超时时返回 action.stage: "dispatch-uncertain",并保留 observation 供核验当前状态。能够在超时前确定的目标、命中、坐标、派发模式和输入序列状态保存在 action.attempt,它是诊断证据,不表示动作已经生效。失败时 CLI 退出码为 1。传 observe: false 可执行裸动作;需要同一动作期间的新增 error logs 和业务 requests 时传 diagnostics: true,埋点通过 diagnostics.events 按需开启。page_eval 默认裸执行,可按需开启观察或诊断。

tab_open active:true 会激活目标 Tab、恢复最小化窗口,并通过 activation 返回实际标签页、窗口和 visibilityState;依赖可信触摸时先确认页面为 visible。页面动作的稳定观察会在有限预算内等待有限时长 CSS 动画。selector/ref 点击遇到嵌套滚动裁剪时会先滚动目标,仍不可见时才以明确的裁剪错误停止。

page_click 默认 auto 在隐藏页使用 DOM fallback,selector、文本、ref 和坐标定位都保持可用,并通过 dispatchMode: "dom"、fallbackReason: "page-hidden" 明确说明实际路径。普通后台任务不需要为了点击主动激活页面;只有站点明确拒绝非可信事件时才切换到可见页并强制 mouse / touch。

observation.effects.interactives 会把内容未变化但 DOM 节点被框架重建的控件标记为 recreated,保留 selector/ref 与语义信息供后续定位,同时省略未变化的 value 和状态字段;值或状态确实变化时仍返回完整差异。

page_press.pressMode 支持 auto / dom / keyboard。默认 auto 在隐藏页使用 DOM 键盘事件,并通过返回的 dispatchMode、fallbackReason 和 defaultAction 说明实际派发及默认行为模拟结果;依赖浏览器原生编辑、选择或滚动行为时使用可见页面和 keyboard。

page_snapshot 默认返回完整 AX Tree;长列表可传 mode: "viewport",只需要当前视口内的控件时传 mode: "interactive",AX 信息为空或过于稀疏时可显式传 mode: "dom",返回实际渲染文本、原生控件、显式 role 和高置信 clickable 节点。DOM 模式同样返回可供后续动作使用的 @ref,但不会猜测任意容器的业务语义。已知 CSS 区域时传 rootSelector,已有 ref 时传 rootRef(可用 ancestorDepth 向上补充上下文),只查找特定文案或角色时传 query。interactive 在视口内缺少 AX 控件语义时仍只回退到 AX viewport,并返回 fallbackMode: "viewport",不会自动切换数据来源。maxNodes / maxChars 截断会同时保留首尾内容。

page_inspect 用 CSS、snapshot @ref 或 DevTools 当前选中元素 $0 返回命中数、边框盒、指定计算样式、中心点遮挡、横纵溢出像素和最近滚动容器。省略 selector 并传 filter: "horizontal-overflow" / "vertical-overflow" / "scrollable" 可直接做全页布局诊断。按文本定位时先用 page_snapshot.query 取得 matches / matchCount 和 ref,再把 ref 交给 page_inspect,不需要手写 page_eval。

重复文本点击可用 page_click.scope 限定 CSS / ref 子树;浏览器扩展后端中,容器或 iframe 内的点坐标使用 coordinateSpace: "active-frame",CSS/text 查询可用 frameId 显式指定 frame。点击结果通过 requestedTarget、resolvedTarget、dispatchTarget、hitTarget 和 coordinates 区分请求语义、DOM 解析、派发节点与可信输入实际命中;selector/ref 目标被嵌套滚动容器裁剪时会自动滚动到可点击区域,只有仍被 overflow 裁剪时才要求显式处理。需要主动浏览列表时,page_scroll.containerPolicy: "nearest" 可自动解析最近可滚动祖先。未指定 selector 时,page_scroll 会优先选择代表性视口位置命中的最近内部滚动容器,再使用文档滚动区域或层级最高且可视面积最大的滚动容器。

browser_list 统一列出普通浏览器、Provider 浏览器和托管浏览器。type 区分 regular / managed,status 区分 connected / pairing / running_disconnected / stopped;只有 connected 的浏览器可作为常规操作目标。

browser_release 仅在用户明确要求结束调试、退出接管或清理会话资源时调用;它会释放 debugger/CDP 控制和会话级临时状态,保留浏览器及全部标签页。托管实例的启动、关闭、持久化、 接入和登录态同步语义由各 Provider 声明;运行 mearl <providerId> 获取当前说明。访问入口不在 browser_list 中,需要时显式运行 mearl check --browser <id|名称>,并把返回的 browserAccess.url 按敏感信息处理。

架构

@mearl/client (CLI / SDK)
  ├─ 本机 → @mearl/native-host → Chrome Extension / CDP
  ├─ 本机 → @mearl/provider runtime → External Provider
  └─ WebSocket → @mearl/cloud-server → @mearl/cloud-connector
                                      ├─ @mearl/native-host → Chrome Extension / CDP
                                      └─ @mearl/provider runtime → External Provider

基础设施组件必须避免递归路由:@mearl/cloud-connector 使用 @mearl/client/local 子路径直连所在机器的 native-host。普通 Agent、CLI 与 MCP 集成均使用包根入口。

构建

pnpm build      # tsc 编译到 dist/,并赋予 cli.js 执行权限
pnpm dev        # tsc --watch
pnpm typecheck  # 仅类型检查

License

ISC