← Back to list
🛠️

opencli Checked

用 OpenCLI 驱动用户本机那个真实的、已登录的 Chrome,或调用它的 160+ 站点 adapter。任何需要登录态的页面操作都从这里开始——读登录后的后台、抓没有 API 的表格、填…
🛠️ Developer Tools skills By yan-labs Version v1.0.ff9c824 Added 2026-09-11 Updated 2026-09-22 Source ↗
9.2Overall rating
2Views
8Downloads
183Stars

Installation

🤖 Install via AI

Copy the prompt below and send it to your AI assistant (e.g. Claude Code) — it will follow the instructions and install automatically.

Install the "opencli" skill by following the instructions at https://skill123.me/install/opencli.
⌨️ Command line install

Run in your terminal — downloads and installs to ~/.claude/skills/.

curl -fsSL https://skill123.me/install/opencli.sh | bash
📦 Download ZIP

Download the zip and extract it into your skills directory (e.g. ~/.claude/skills/), then restart your session.

⬇ Download v1.0.ff9c824 · 151 KB
📊 Static rating
9.2/10
Trigger
8.0
Structure
9.3
Workflow
10.0
Content
9.0
Engineering
9.0
Security
9.5

Six-dimension rubric with reviewer rationale.

View scorecard ↓
🛡 Dynamic test
—

Not live-tested yet — this skill is rated on static analysis only.

About this skill

用 OpenCLI 驱动用户本机那个真实的、已登录的 Chrome,或调用它的 160+ 站点 adapter。任何需要登录态的页面操作都从这里开始——读登录后的后台、抓没有 API 的表格、填表提交、跑一个站点命令、把页面数据取回来。也覆盖会话命名与租约纪律("我的标签页被别人抢了")、批量取数与落盘、adapter 的编写与自修复、opencli doctor 排障。用户提到 opencli、浏览器自动化、用我的浏览器、驱动 Chrome、登录态、抓后台数据、抓表格、导出报表、填表、自动点击、截图、adapter、doctor 报错、session 撞名、标签页被抢、tab 泄漏,或说"打开这个页面看看""帮我登录后台查一下""这个站没有 API"时,务必使用本 Skill。也在需要判断"这件事该不该开浏览器"时使用——本 Skill 第零节就是那张判断表(要不要登录态、有没有现成脚本或 adapter、配额站能不能动手、什么时候该转给 agent-reach 或业务 Skill)。只要动作会落在浏览器上,先读这里再动手。

OpenCLI

OpenCLI 把任意网站、Electron 桌面应用和外部 CLI 收敛成一条 opencli <site> <command>,

再加一条 opencli browser <session> <command> 用来现场驱动浏览器。

它走的是**用户本机那个真实的、已登录的 Chrome**(浏览器扩展 + 本地守护进程),

不是无痕实例、不是沙箱。这一个事实决定了本 Skill 里几乎所有规则。

本 Skill 面向的是我们自己维护的 fork(yan-labs/OpenCLI),和上游 jackwener/opencli

有差异,差异清单见 references/our-fork.md (references/our-fork.md)。

---

Documentation

用 OpenCLI 驱动用户本机那个真实的、已登录的 Chrome,或调用它的 160+ 站点 adapter。任何需要登录态的页面操作都从这里开始——读登录后的后台、抓没有 API 的表格、填表提交、跑一个站点命令、把页面数据取回来。也覆盖会话命名与租约纪律("我的标签页被别人抢了")、批量取数与落盘、adapter 的编写与自修复、opencli doctor 排障。用户提到 opencli、浏览器自动化、用我的浏览器、驱动 Chrome、登录态、抓后台数据、抓表格、导出报表、填表、自动点击、截图、adapter、doctor 报错、session 撞名、标签页被抢、tab 泄漏,或说"打开这个页面看看""帮我登录后台查一下""这个站没有 API"时,务必使用本 Skill。也在需要判断"这件事该不该开浏览器"时使用——本 Skill 第零节就是那张判断表(要不要登录态、有没有现成脚本或 adapter、配额站能不能动手、什么时候该转给 agent-reach 或业务 Skill)。只要动作会落在浏览器上,先读这里再动手。

OpenCLI

OpenCLI 把任意网站、Electron 桌面应用和外部 CLI 收敛成一条 opencli <site> <command>,

再加一条 opencli browser <session> <command> 用来现场驱动浏览器。

它走的是**用户本机那个真实的、已登录的 Chrome**(浏览器扩展 + 本地守护进程),

不是无痕实例、不是沙箱。这一个事实决定了本 Skill 里几乎所有规则。

本 Skill 面向的是我们自己维护的 fork(yan-labs/OpenCLI),和上游 jackwener/opencli

有差异,差异清单见 references/our-fork.md (references/our-fork.md)。

---

零、我遇到这种情况,该不该用 OpenCLI

本 Skill 是**底层能力**,不是业务流程。用户不会说「用 OpenCLI」,他会说下面左边那些话。

这张表回答的是「这句话该不该落到浏览器上」——**判错方向的代价是拿到看起来正常、

内容却不同的数据**,比慢一轮贵得多。

| 用户大概会这么说 | 该走哪条 | 为什么 |

|---|---|---|

| 「帮我登录后台查一下」「看我的 GSC / 数据面板」 | **用**(opencli browser) | 需要身份。沙箱浏览器要么跳登录页,要么以匿名身份返回**更少的字段、更低的配额** |

| 「这个站没有 API,把表格给我」 | **用**,但先看第四节有没有 adapter | adapter 里封装过的坑,现场驱动要重踩一遍 |

| 「填一下这个表单」「帮我提交」 | **用**,但提交动作归业务 Skill 管 | 本 Skill 只负责把浏览器开对;能不能按提交见 backlink 的三道闸 |

| 「打开这个页面看看写了什么」(公开页) | **先不用** | 先问有没有 curl / 公开 API。只为读一段公开文本开浏览器是浪费 |

| 「帮我调研一下 X」「搜搜大家怎么说」 | **不用** → agent-reach | 它已经做好多平台路由。本 Skill 不做「找信息」,只做「把数据取回来」 |

| 「查这个词的搜索量 / 难度」「看看竞品外链」 | **不用直接开浏览器** → 先进 rankup / backlink | 那两个 Skill 里已经有现成脚本,直接跑;现写等价实现是本阶梯第 1 级明令禁止的 |

| 「Semrush / Similarweb 上帮我看个数」 | **用,但先读配额纪律** | 见下面「配额站」一节:固定会话名 + 整轮持机器级工具锁。先跑 node <opencli-skill-dir>/scripts/pressure.mjs --tool semrush |

| 「开十个 agent 一起抓」 | **不要** | 扇出的单位是 agent,资源却是标签页。采集落盘(scripts/receiver.mjs),N 个 agent 读文件,站点侧并发度 0 |

| 「我的标签页被别人抢了」「读回来的页面不对」 | **用本 Skill 排障** | 先怀疑会话撞名,见第三节四条法律 |

| 「浏览器连不上 / doctor 报红 / 命令行为和文档不符」 | **用本 Skill 排障** | 第二节:先看扩展版本,商店版会让每条规则都对不上 |

| 「过一下验证码」 | **半自动** | 把前面全部做完,只把那一下点击留给用户,见第八节 |

**一句话判据**:*无痕窗口打开它,还是不是同一个东西?* 不是 → 必须走用户真实的

Chrome(也就是本 Skill);是 → 先找 API 或现成脚本。

---

一、先判断:这件事该不该用浏览器

**动手之前先走这条阶梯,命中即停。** 每一级往下的唯一理由是「上一级确实不存在」,

不是「我对下一级更熟」。跳级的代价不是慢,是拿到看起来正常但内容不同的数据。

| 级 | 手段 | 什么时候用 |

|---|---|---|

| 1 | **现成脚本** | 项目里、兄弟 Skill 里已经有的 .mjs。直接跑,不要现写等价实现 |

| 2 | **HTTP / REST API**(curl / fetch) | 没脚本但服务有 API。先用 API,跑通后固化成脚本 |

| 3 | **opencli <site> <command> adapter** | 目标站已有 adapter。opencli list \| grep -i <site> 一眼就知道 |

| 4 | **opencli browser <session> 现场驱动** | 没有 adapter,或 adapter 不覆盖这个动作 |

| 5 | 写一个新 adapter | 这个动作以后还要重复做。见 references/adapters.md (references/adapters.md) |

### 判据:无痕窗口打开,还是不是同一个东西?

答案是「不是」,就**必须**走用户的真实浏览器(也就是 OpenCLI)。

需要身份的一切——第三方数据面板、Search Console、社区后台、聊天式 AI 工具——

用运行环境自带的沙箱浏览器打开,要么直接跳登录页,要么以匿名身份返回**看起来正常

但内容不同**的结果(配额更低、字段更少、国家库不同)。这种失败会伪装成

「这个工具没有这项数据」,而正确的结论其实是「你没登录」。

反过来,**只是看一段公开文本就不要开浏览器**——先问有没有 curl 或公开 API。

View full documentation

三个 driver 的取舍(为什么默认是 OpenCLI 而不是 agent-browser 或 Claude in Chrome,

各自的实测泄漏数据)见 references/drivers.md (references/drivers.md)。

### 不在本 Skill 范围

  • **找信息、做调研、搜某个话题** → 用 agent-reach,它已经负责多平台路由。

本 Skill 只管「怎么把浏览器开对、把数据取回来」。

---

二、开工前:doctor


opencli doctor

doctor 只诊断**浏览器桥**(守护进程 + 扩展 + Chrome 连线)。

PUBLIC / LOCAL 策略的 adapter、opencli list、外部 CLI 透传都不需要它绿。

COOKIE / INTERCEPT / UI 策略和所有 opencli browser * 才需要。

### 行为和这份文档对不上时,第一件事是查扩展版本

**本 Skill 描述的默认行为全部住在扩展里**——后台默认、opencli browser 与 adapter 命令

都在用户当前窗口开标签页、不切走活动标签页、每个会话一个以会话名命名的标签页组、

--window isolated、sessions 报 windowId / groupTitle / windowFallbackReason。

装成 Chrome 应用商店那个版本的话,**每条命令都照样成功,只是行为回到上游**:

默认前台、自己开一个窗口、抢走用户正在看的标签页、isolated 被忽略。

**这类失败没有报错,只有「怎么和文档说的不一样」。** 所以:

| 观察到 | 该做什么 |

|---|---|

| 命令成功但窗口/焦点行为与本文档不符 | 跑 opencli doctor,看 Extension 那行的版本 |

| 版本 < 1.0.33 | **告诉用户他装的是应用商店版**,需要换成 yan-labs 的 Release 里的 zip,并把商店版移除或停用 |

| doctor 自己就报了这条 | 照它说的做——它会打印下载地址和加载步骤 |

doctor 会在扩展低于 1.0.33 时主动报这个问题,**不要跳过它的输出**。

改过扩展源码(或刚拉了新构建)之后要在 chrome://extensions 里对 OpenCLI 点 **reload**——

没 reload 时 Chrome 跑的仍是旧版,doctor 会提示已加载版本低于最低要求,那不是装错,是没 reload。

红了先看 references/troubleshooting.md (references/troubleshooting.md)。

排障的第一步永远是 **npm ls -g @jackwener/opencli 确认 CLI 是发布版还是本地源码 link**——

这一步决定后面是查代码还是查环境,跳过它会浪费一整轮。

**doctor 前两行绿、第三行红**是一个特定信号:守护进程和扩展这两个组件都活着,

坏的是它们之间那条命令路径,重启守护进程通常没用。

---

三、会话纪律:本 Skill 最贵的一节

opencli browser <session> 里的 <session> **就是标签页的所有权声明**。

同名会话共用同一个标签页,不同名之间互不干扰。所以「我的标签页被别人抢了」

最常见的成因是:**两个任务挑了同一个会话名**。

OpenCLI 1.8.7 的守护进程会保护同一 profile + surface + session:第二个**并发写**

会留在本机排队,每 2 秒检查一次;前一个任务结束后自动继续,不把 session_busy 交给

外层 Agent,避免它立即重试。排队检查只访问本机 daemon,不会访问目标网站;首次等待会

明确打印占用者、等待原因和下次检查时间。默认最多等 10 分钟,超时会说明命令尚未发往

Chrome/目标网站,并要求不要立即重试。读操作仍可并行;含任一写操作的混合 batch

整体按写处理。

这只串行化同一时刻的写入。两个任务顺序或交替复用同名会话,仍会操作同一个标签页,

随后读到对方打开的页面,所以唯一会话名规则不变。

这把锁也不管站点账号的并发与限速。数据源脚本若同一账号不能并发,仍要自己加全局锁。

### 四条法律(完整实测数据见 references/session-laws.md (references/session-laws.md))

| # | 法律 | 一句话理由 |

|---|---|---|

| 1 | **一个会话一个标签页;N 个页面就要 N 个会话名** | 三个 agent 各用独立名字:跨 agent 抢占 0 次。共用 work:3 / 12 / 2 次,其中一个每次读都读错。**唯一例外是配额站,见下一节** |

| 2 | **不要用 tab new / tab select / open --tab 在一个会话里放多个页面** | 三个都**静默**失败:命令报成功,下一次读回错误的页面。一次三 agent 运行把用户的 Chrome 从 11 个标签页涨到 30 个孤儿页 |

| 3 | **绝不硬编码会话名** | opencli browser --help 的第一个例子就是 work,抄它的人全撞在一起 |

| 4 | **开工前一次性把要用的会话全部开好、handle 全部拿到,再进工作循环** | 边创建边使用会把理论上的竞态变成可复现的竞态 |

**法律 1 保护的是标签页身份,不是站点的服务端状态。** 所有会话共用同一个 Chrome

profile 和同一个登录身份,所以如果站点把「当前选中的项目/客户」存在服务端会话里,

一个标签页切换目标,其它标签页刷新后会跟着变——会话名分得再开也拦不住。

**判据:在站点里切换目标之后 URL 变不变?** 不变就先验证再并行,

细节见 references/session-laws.md (references/session-laws.md)。

### 配额站:法律 1 的唯一例外

有些站**同时加载**会触发上限。实测(2026-08-28)Semrush 大约 3 个标签页同时 load

就出问题,一个个开、中间隔几秒则没事。**受限的是导航事件,不是标签页存在**——

所以它要的不是信号量,是串行加间隔。

而串行 daemon 已经免费给了:同名会话的写会在本机排队。于是配额站的解法是把法律 1

反过来用——**一个站一个固定会话名,不带任何 per-agent 后缀**:


semrush-nav        similarweb-nav

十个 agent 拿到同一个名字,daemon 就把它们排成一队,Semrush 那边永远只看到

一个标签页在一页页地翻。

**动手前先跑 pressure.mjs:**


node <opencli-skill-dir>/scripts/pressure.mjs --tool semrush

它一句话回答「现在动手会不会把事情搞砸」——配额站已经几个标签页、到没到线、

tools-share 锁被谁拿着、那个 pid 还活着吗,然后给 go / wait / stale-lock。

退出码可以直接串起来:node pressure.mjs --tool semrush && node my-crawler.mjs。

**它报 unknown 时不要当成「没人在用」**——那是「会话列表拿不到」,不是「0 个标签页」。

| 规则 | 为什么 |

|---|---|

| **配额站用固定会话名**,sessionForUrl(url, base) 自动判 | 会话名就是并发度。名字固定 = 并发度 1 |

| **一次访问 = 一个 batch**(openAndExtract) | 「含任一写操作的混合 batch 整体按写处理」,所以整包是原子的,别人插不进来——这正是共用名字仍然安全的原因 |

| **禁止 open 一次隔几轮对话再读** | 会话一直占着,后面全在排队。实测 daemon.log 一天 1016 条 busy 轮询 |

| **采集写成顺序循环**(sequentialCrawl),不要扇出 | 排队是兜底不是调度器:daemon 默认只等 10 分钟,20 个词顺序跑就快贴到上限 |

| **间隔用 sleepStep(),不要用 wait time** | wait time 5 在 1.8.7 是坏的:报 "Waited 5s",实测 928ms 就返回。写错了整套节流静默失效 |

| **撞上限的第一动作是 close,不是 sleep** | 释放标签页本身就是退避。当成「页面没加载好」去重试只会再开一个,越retry越糟 |

**daemon 排队只串行化单条命令 / 单个 batch,保护不了跨多条命令的整轮采集。**

同名会话排队意味着两条命令之间的间隙对别人是敞开的:一轮横跨几十条命令的采集

(poll → 截图 → 滚动循环),任何 poll 间隙里别的工作流都能往同一个固定名标签页

open 自己的 URL。实测 2026-08-29 一天抓到 4 次现行接管。所以整轮采集必须**另持

机器级工具锁**(yan-tools-share-<tool>.lock,pressure.mjs 报告的就是它),

整轮持有、结束释放——「排队所以安全」只对单条 batch 成立。完整法律与参考实现见

backlink Skill 的 one-collector-per-quota-tool(backlink/SKILL.md,实现在

backlink/scripts/ground-truth.mjs)。

**分析阶段一律不碰配额站。** 采集落盘(scripts/receiver.mjs),N 个分析 agent 读文件,

站点侧并发度是 0。这是唯一能让 agent 数量和站点压力彻底解耦的做法——今天那

19 个 tm-* 标签页全开在同一个 Semrush 报表上,就是因为扇出的单位是 agent 而资源是页面。

**导航超时不等于页面没开。** 扩展硬编码 15 秒且改不了,Semrush 的重报表经常超。

标签页那时已经建好了,正确反应是先 extract 探活,确认真没内容才在**同一个会话里**

重新导航。openAndExtract 已经这么做了;手写的话千万别开新会话去重试。

> Semrush / Similarweb **一个 adapter 都没有**(opencli list 里 0 条),所以每次取数

> 都必须开真标签页。想从根上删掉这个问题,就得给最高频的几个报表写 COOKIE/INTERCEPT

> adapter——从日志看是 analytics/overview、keywordoverview、keywordmagic

> (也正好是超时最多的三个:9 / 8 / 5 次)。

### $$ 在脚本里安全,在 Bash tool 里不安全

这是我们踩过的真实事故,必须区分:

| 场景 | $$ / process.pid 行为 | 正确做法 |

|---|---|---|

| **Node 脚本**(一个进程跑完全程) | 整个生命周期同一个 PID,安全 | ` let session = ahs-${process.pid} ` |

| **Claude Code 的 Bash tool** | **每次调用都是新进程,PID 不同** | 用**描述性字面常量**(naver-birthstone、bing-check-mysite),或 S=$(uuidgen \| cut -c1-8) 存进文件再读回 |

已验证事故(2026-08-23):sub agent 用 S="naver-bs-$$" 连续调用 OpenCLI,

每条命令都创建了新会话(新空白标签页),上一条打开的页面被遗弃。

agent 看到的永远是空白页,以为页面没加载好不断重试,最终泄漏 9 个会话。

**名字要描述工作**,不只是唯一:backlink-probe-<后缀> 胜过 bl-1。

会话名是唯一存在的标识符,一个唯一但无意义的名字仍然回答不了「这是谁的标签页」。

JS 里不要手搓后缀,用 scripts/opencli-core.mjs 的 defaultSession(base);

**Bash 里 `sou

Score breakdown

Trigger
8.0
Very rich Chinese trigger vocabulary including failure phrases like tab hijacked and doctor errors, but almost no English variants and no explicit exclusion.
Structure
9.3
662-line SKILL.md offloaded to seven references with a when-to-read table; scripts, tests and evals cleanly separated.
Workflow
10.0
Exceptional: usage ladder, four session laws, quota-site serialization with pressure gate, focus-preservation rules, hard-stop repair budget, CAPTCHA human handoff.
Content
9.0
Concrete commands and measured incident data throughout; some long historical digressions reduce density slightly.
Engineering
9.0
Valid frontmatter, shebangs and unit tests present; references resolve; backlink cross-references are external but declared.
Security
9.5
Scripts spawn without shell, write only to project and ~/.opencli/logs; receiver is localhost-only with script allowlist; minor CORS-star data-injection surface while running.
Outstanding browser-control skill with a should-I-use-browser decision ladder, measured session laws, quota-site gates and localhost receiver; driving the logged-in Chrome is its declared purpose and is heavily gated, with no exfiltration or credential access in scripts.

Assessment methodology

🧪
AI-assessed
Evaluated by automated analysis across quality, usability, and security dimensions. This is not a substitute for your own review — always inspect a skill before installing it.

Version history

v1.0.ff9c824 2026-09-22
151 KB

— Refreshed from GitHub yan-labs/yan-skills@ff9c824

v1.0.0 2026-09-11
112 KB

Imported from yan-labs/yan-skills@main