opencli by jackwener/opencli
npx skills add https://github.com/jackwener/opencli --skill opencli将任何网站或 Electron 应用变成你的 CLI。复用 Chrome 登录,零风险,AI 驱动的发现能力。
[!CAUTION] AI Agent 必读:创建或修改任何适配器之前,你必须先阅读CLI-EXPLORER.md! 该文档包含完整的 API 发现工作流(必须使用浏览器探索)、5 级认证策略决策树、平台 SDK 速查表、
tap步骤调试流程、分页 API 模板、级联请求模式、以及常见陷阱。 本文件(SKILL.md)仅提供命令参考和简化模板,不足以正确开发适配器。
# npm 全局安装(推荐)
npm install -g @jackwener/opencli
opencli <命令>
# 或从源码运行
cd ~/code/opencli && npm install
npx tsx src/main.ts <命令>
# 更新到最新版本
npm update -g @jackwener/opencli
浏览器命令需要:
chrome://extensions 中以未打包方式加载 extension/ 目录)广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
注意 :运行命令前,你必须在 Chrome 中登录目标网站。命令执行期间打开的标签页会在之后自动关闭。
公共 API 命令(hackernews、v2ex)不需要浏览器。
# Bilibili (浏览器)
opencli bilibili hot --limit 10 # B站热门视频
opencli bilibili search "rust" # 搜索视频 (query 位置参数)
opencli bilibili me # 我的信息
opencli bilibili favorite # 我的收藏
opencli bilibili history --limit 20 # 观看历史
opencli bilibili feed --limit 10 # 动态时间线
opencli bilibili user-videos --uid 12345 # 用户投稿
opencli bilibili subtitle --bvid BV1xxx # 获取视频字幕 (支持 --lang zh-CN)
opencli bilibili dynamic --limit 10 # 动态
opencli bilibili ranking --limit 10 # 排行榜
opencli bilibili following --limit 20 # 我的关注列表 (支持 --uid 查看他人)
# 知乎 (浏览器)
opencli zhihu hot --limit 10 # 知乎热榜
opencli zhihu search "AI" # 搜索 (query 位置参数)
opencli zhihu question 34816524 # 问题详情和回答 (id 位置参数)
# 小红书 (浏览器)
opencli xiaohongshu search "美食" # 搜索笔记 (query 位置参数)
opencli xiaohongshu notifications # 通知(提及/点赞/关注)
opencli xiaohongshu feed --limit 10 # 推荐 Feed
opencli xiaohongshu user xxx # 用户主页 (id 位置参数)
opencli xiaohongshu creator-notes --limit 10 # 创作者笔记列表
opencli xiaohongshu creator-note-detail --note-id xxx # 笔记详情
opencli xiaohongshu creator-notes-summary # 笔记数据概览
opencli xiaohongshu creator-profile # 创作者资料
opencli xiaohongshu creator-stats # 创作者数据统计
# 雪球 Xueqiu (浏览器)
opencli xueqiu hot-stock --limit 10 # 雪球热门股票榜
opencli xueqiu stock --symbol SH600519 # 查看股票实时行情
opencli xueqiu watchlist # 获取自选股/持仓列表
opencli xueqiu feed # 我的关注 timeline
opencli xueqiu hot --limit 10 # 雪球热榜
opencli xueqiu search "特斯拉" # 搜索 (query 位置参数)
# GitHub (通过 gh 外部 CLI)
opencli gh repo list # 列出仓库 (透传给 gh)
opencli gh pr list --limit 5 # PR 列表
opencli gh issue list # Issue 列表
# Twitter/X (浏览器)
opencli twitter trending --limit 10 # 热门话题
opencli twitter bookmarks --limit 20 # 获取收藏的书签推文
opencli twitter search "AI" # 搜索推文 (query 位置参数)
opencli twitter profile elonmusk # 用户资料
opencli twitter timeline --limit 20 # 时间线
opencli twitter thread 1234567890 # 推文 thread(原文 + 回复)
opencli twitter article 1891511252174299446 # 推文长文内容
opencli twitter follow elonmusk # 关注用户
opencli twitter unfollow elonmusk # 取消关注
opencli twitter bookmark https://x.com/... # 收藏推文
opencli twitter unbookmark https://x.com/... # 取消收藏
# Reddit (浏览器)
opencli reddit hot --limit 10 # 热门帖子
opencli reddit hot --subreddit programming # 指定子版块
opencli reddit frontpage --limit 10 # 首页 /r/all
opencli reddit popular --limit 10 # /r/popular 热门
opencli reddit search "AI" --sort top --time week # 搜索(支持排序+时间过滤)
opencli reddit subreddit rust --sort top --time month # 子版块浏览(支持时间过滤)
opencli reddit read --post-id 1abc123 # 阅读帖子 + 评论
opencli reddit user spez # 用户资料(karma、注册时间)
opencli reddit user-posts spez # 用户发帖历史
opencli reddit user-comments spez # 用户评论历史
opencli reddit upvote --post-id xxx --direction up # 投票(up/down/none)
opencli reddit save --post-id xxx # 收藏帖子
opencli reddit comment --post-id xxx "Great!" # 发表评论 (text 位置参数)
opencli reddit subscribe --subreddit python # 订阅子版块
opencli reddit saved --limit 10 # 我的收藏
opencli reddit upvoted --limit 10 # 我的赞
# V2EX (公共 + 浏览器)
opencli v2ex hot --limit 10 # 热门话题
opencli v2ex latest --limit 10 # 最新话题
opencli v2ex topic 1024 # 主题详情 (id 位置参数)
opencli v2ex daily # 每日签到 (浏览器)
opencli v2ex me # 我的信息 (浏览器)
opencli v2ex notifications --limit 10 # 通知 (浏览器)
# Hacker News (公共)
opencli hackernews top --limit 10 # Top stories
# BBC (公共)
opencli bbc news --limit 10 # BBC News RSS 头条
# 微博 (浏览器)
opencli weibo hot --limit 10 # 微博热搜
# BOSS直聘 (浏览器)
opencli boss search "AI agent" # 搜索职位 (query 位置参数)
opencli boss detail --security-id xxx # 职位详情
opencli boss recommend --limit 10 # 推荐职位
opencli boss joblist --limit 10 # 职位列表
opencli boss greet --security-id xxx # 打招呼
opencli boss batchgreet --job-id xxx # 批量打招呼
opencli boss send --uid xxx "消息内容" # 发消息 (text 位置参数)
opencli boss chatlist --limit 10 # 聊天列表
opencli boss chatmsg --security-id xxx # 聊天记录
opencli boss invite --security-id xxx # 邀请沟通
opencli boss mark --security-id xxx # 标记管理
opencli boss exchange --security-id xxx # 交换联系方式
opencli boss resume # 简历管理
opencli boss stats # 数据统计
# YouTube (浏览器)
opencli youtube search "rust" # 搜索视频 (query 位置参数)
opencli youtube video "https://www.youtube.com/watch?v=xxx" # 视频元数据
opencli youtube transcript "https://www.youtube.com/watch?v=xxx" # 获取视频字幕/转录
opencli youtube transcript "xxx" --lang zh-Hans --mode raw # 指定语言 + 原始时间戳模式
# Yahoo Finance (浏览器)
opencli yahoo-finance quote --symbol AAPL # 股票行情
# Sina Finance
opencli sinafinance news --limit 10 --type 1 # 7x24实时快讯 (0=全部 1=A股 2=宏观 3=公司 4=数据 5=市场 6=国际 7=观点 8=央行 9=其它)
# Reuters (浏览器)
opencli reuters search "AI" # 路透社搜索 (query 位置参数)
# 什么值得买 (浏览器)
opencli smzdm search "耳机" # 搜索好价 (query 位置参数)
# 携程 (浏览器)
opencli ctrip search "三亚" # 搜索目的地 (query 位置参数)
# Antigravity (Electron/CDP)
opencli antigravity status # 检查 CDP 连接
opencli antigravity send "hello" # 发送文本到当前 agent 聊天框
opencli antigravity read # 读取整个聊天记录面板
opencli antigravity new # 清空聊天、开启新对话
opencli antigravity dump # 导出 DOM 和快照调试信息
opencli antigravity extract-code # 自动抽取 AI 回复中的代码块
opencli antigravity model claude # 切换底层模型
opencli antigravity watch # 流式监听增量消息
opencli antigravity serve --port 8082 # 启动 Anthropic 兼容代理
# Barchart (浏览器)
opencli barchart quote --symbol AAPL # 股票行情
opencli barchart options --symbol AAPL # 期权链
opencli barchart greeks --symbol AAPL # 期权 Greeks
opencli barchart flow --limit 20 # 异常期权活动
# Jike 即刻 (浏览器)
opencli jike feed --limit 10 # 动态流
opencli jike search "AI" # 搜索 (query 位置参数)
opencli jike create "内容" # 发布动态 (text 位置参数)
opencli jike like xxx # 点赞 (id 位置参数)
opencli jike comment xxx "评论" # 评论 (id + text 位置参数)
opencli jike repost xxx # 转发 (id 位置参数)
opencli jike notifications # 通知
# Linux.do (公共)
opencli linux-do hot --limit 10 # 热门话题
opencli linux-do latest --limit 10 # 最新话题
opencli linux-do search "rust" # 搜索 (query 位置参数)
opencli linux-do topic 1024 # 主题详情 (id 位置参数)
# StackOverflow (公共)
opencli stackoverflow hot --limit 10 # 热门问题
opencli stackoverflow search "typescript" # 搜索 (query 位置参数)
opencli stackoverflow bounties --limit 10 # 悬赏问题
# WeRead 微信读书 (浏览器)
opencli weread shelf --limit 10 # 书架
opencli weread search "AI" # 搜索图书 (query 位置参数)
opencli weread book xxx # 图书详情 (book-id 位置参数)
opencli weread highlights xxx # 划线笔记 (book-id 位置参数)
opencli weread notes xxx # 想法笔记 (book-id 位置参数)
opencli weread ranking --limit 10 # 排行榜
# Jimeng 即梦 AI (浏览器)
opencli jimeng generate --prompt "描述" # AI 生图
opencli jimeng history --limit 10 # 生成历史
# Grok (默认 + 显式 web)
opencli grok ask --prompt "问题" # 提问 Grok(兼容默认路径)
opencli grok ask --prompt "问题" --web # 显式 grok.com consumer web UI 路径
# HuggingFace (公共)
opencli hf top --limit 10 # 热门模型
# 超星学习通 (浏览器)
opencli chaoxing assignments # 作业列表
opencli chaoxing exams # 考试列表
opencli list # 列出所有命令(包括外部 CLI)
opencli list --json # JSON 输出
opencli list -f yaml # YAML 输出
opencli install <name> # 自动安装外部 CLI(例如 gh, obsidian)
opencli register <name> # 注册本地自定义 CLI 以统一发现
opencli validate # 验证所有 CLI 定义
opencli validate bilibili # 验证特定站点
opencli doctor # 诊断浏览器桥接(自动启动守护进程,包含实时测试)
# 深度探索:网络拦截 → 响应分析 → 能力推断
opencli explore <url> --site <name>
# 合成:根据探索产物生成基于 evaluate 的 YAML 流水线
opencli synthesize <site>
# 生成:一次性探索 → 合成 → 注册
opencli generate <url> --goal "hot"
# 录制:你操作页面,opencli 捕获每个 API 调用 → YAML 候选
# 在自动化窗口中打开 URL,向所有标签页注入 fetch/XHR 拦截器,
# 每 2 秒轮询一次,60 秒后自动停止(或按 Enter 提前停止)。
opencli record <url> # 录制,site name 从域名推断
opencli record <url> --site mysite # 指定 site name
opencli record <url> --timeout 120000 # 自定义超时(毫秒,默认 60000)
opencli record <url> --poll 1000 # 缩短轮询间隔(毫秒,默认 2000)
opencli record <url> --out .opencli/record/x # 自定义输出目录
# 输出:
# .opencli/record/<site>/captured.json ← 原始捕获数据(带 url/method/body)
# .opencli/record/<site>/candidates/*.yaml ← 高置信度候选适配器(score ≥ 8,有 array 结果)
# 策略级联:自动探测 PUBLIC → COOKIE → HEADER
opencli cascade <api-url>
# 交互式模糊探索(点击按钮触发懒加载 API)
opencli explore <url> --auto --click "字幕,CC,评论"
# 验证:验证适配器定义
opencli verify
所有内置命令都支持 --format / -f 参数,可选 table、json、yaml、md 和 csv。list 命令支持相同的格式,并保留 --json 作为兼容性别名。
opencli list -f yaml # YAML 命令注册表
opencli bilibili hot -f table # 默认:富表格
opencli bilibili hot -f json # JSON(管道到 jq,喂给 AI agent)
opencli bilibili hot -f yaml # YAML(可读的结构化输出)
opencli bilibili hot -f md # Markdown
opencli bilibili hot -f csv # CSV
opencli bilibili hot -v # 显示每个流水线步骤和数据流
record 是为「无法用 explore 自动发现」的页面(需要登录操作、复杂交互、SPA 内路由)准备的手动录制方案。
opencli record <url>
→ 打开自动化窗口并导航到目标 URL
→ 向所有标签页注入 fetch/XHR 拦截器(幂等,可重复注入)
→ 每 2 秒轮询一次:发现新标签页自动注入,排空所有标签页的捕获缓冲区
→ 超时(默认 60 秒)或按 Enter 停止
→ 分析捕获到的 JSON 请求:去重 → 评分 → 生成候选 YAML
拦截器特性 :
window.fetch 和 XMLHttpRequestContent-Type: application/json 的响应# 1. 启动录制(建议 --timeout 给足操作时间)
opencli record "https://example.com/page" --timeout 120000
# 2. 在弹出的自动化窗口里正常操作页面:
# - 打开列表、搜索、点击条目、切换 Tab
# - 凡是触发网络请求的操作都会被捕获
# 3. 完成操作后按 Enter 停止(或等超时自动停止)
# 4. 查看结果
cat .opencli/record/<site>/captured.json # 原始捕获
ls .opencli/record/<site>/candidates/ # 候选 YAML
| 页面类型 | 预期捕获量 | 说明 |
|---|---|---|
| 列表/搜索页 | 多(5~20+) | 每次搜索/翻页都会触发新请求 |
| 详情页(只读) | 少(1~5) | 首屏数据一次性返回,后续操作走 form/redirect |
| SPA 内路由跳转 | 中等 | 路由切换会触发新接口,但首屏请求在注入前已发出 |
| 需要登录的页面 | 视操作而定 | 确保 Chrome 已登录目标网站 |
注意 :如果页面在导航完成前就发出了大部分请求(服务端渲染 / SSR 注水),拦截器会错过这些请求。 解决方案:在页面加载完成后,手动触发能产生新请求的操作(搜索、翻页、切 Tab、展开折叠项等)。
生成的候选 YAML 是起点,通常需要转换为 TypeScript(尤其是 tae 等内部系统):
候选 YAML 结构 (自动生成):
site: tae
name: getList # 从 URL path 推断的名称
strategy: cookie
browser: true
pipeline:
- navigate: https://...
- evaluate: |
(async () => {
const res = await fetch('/approval/getList.json?procInsId=...', { credentials: 'include' });
const data = await res.json();
return (data?.content?.operatorRecords || []).map(item => ({ ... }));
})()
转换为 TS CLI (参考 src/clis/tae/add-expense.ts 风格):
import { cli, Strategy } from '../../registry.js';
cli({
site: 'tae',
name: 'get-approval',
description: '查看报销单审批流程和操作记录',
domain: 'tae.alibaba-inc.com',
strategy: Strategy.COOKIE,
browser: true,
args: [
{ name: 'proc_ins_id', type: 'string', required: true, positional: true, help: '流程实例 ID(procInsId)' },
],
columns: ['step', 'operator', 'action', 'time'],
func: async (page, kwargs) => {
await page.goto('https://tae.alibaba-inc.com/expense/pc.html?_authType=SAML');
await page.wait(2);
const result = await page.evaluate(`(async () => {
const res = await fetch('/approval/getList.json?taskId=&procInsId=${kwargs.proc_ins_id}', {
credentials: 'include'
});
const data = await res.json();
return data?.content?.operatorRecords || [];
})()`);
return (result as any[]).map((r, i) => ({
step: i + 1,
operator: r.operatorName || r.userId,
action: r.operationType,
time: r.operateTime,
}));
},
});
转换要点 :
procInsId、taskId 等)提取为 argscaptured.json 里的真实 body 结构用于确定正确的数据路径(如 content.operatorRecords){ success, content, errorCode, errorMsg } 外层包裹,取数据要走 content.*credentials: 'include'),不需要额外 headersrc/clis/<site>/,无需手动注册,npm run build 后自动发现| 现象 | 原因 | 解法 |
|---|---|---|
| 捕获 0 条请求 | 拦截器注入失败,或页面无 JSON API | 检查守护进程是否运行:curl localhost:19825/status |
| 捕获量少(1~3 条) | 页面是只读详情页,首屏数据已在注入前发出 | 手动操作触发更多请求(搜索/翻页),或换用列表页 |
| 候选 YAML 为 0 | 捕获到的 JSON 都没有 array 结构 | 直接看 captured.json 手写 TS CLI |
| 新开的标签页没有被拦截 | 轮询间隔内标签页已关闭 | 缩短 --poll 500 |
| 二次运行 record 时数据不连续 | 正常,每次 record 启动都是新的自动化窗口 | 无需处理 |
[!TIP] 快速模式 :如果你只想为一个具体页面生成一个命令,直接看 CLI-ONESHOT.md。 只需要一个 URL + 一句话描述,4 步搞定。
[!IMPORTANT] 完整模式 — 在写任何代码之前,先阅读CLI-EXPLORER.md。 它包含:① AI Agent 浏览器探索工作流 ② 认证策略决策树 ③ 平台 SDK(如 Bilibili 的
apiGet/fetchJson)④ YAML vs TS 选择指南 ⑤tap步骤调试方法 ⑥ 级联请求模板 ⑦ 常见陷阱表。 下方仅为简化模板参考,直接使用极易踩坑。
创建 src/clis/<site>/<name>.yaml:
site: mysite
name: hot
description: Hot topics
domain: www.mysite.com
strategy: cookie # public | cookie | header | intercept | ui
browser: true
args:
limit:
type: int
default: 20
description: Number of items
pipeline:
- navigate: https://www.mysite.com
- evaluate: |
(async () => {
const res = await fetch('/api/hot', { credentials: 'include' });
const d = await res.json();
return d.data.items.map(item => ({
title: item.title,
score: item.score,
}));
})()
- map:
rank: ${{ index + 1 }}
title: ${{ item.title }}
score: ${{ item.score }}
- limit: ${{ args.limit }}
columns: [rank, title, score]
对于公共 API(无需浏览器):
strategy: public
browser: false
pipeline:
- fetch:
url: https://api.example.com/hot.json
- select: data.items
- map:
title: ${{ item.title }}
- limit: ${{ args.limit }}
创建 src/clis/<site>/<name>.ts。它将自动动态加载(不要在 index.ts 中手动导入):
import { cli, Strategy } from '../../registry.js';
cli({
site: 'mysite',
name: 'search',
strategy: Strategy.INTERCEPT, // 或 COOKIE
args: [{ name: 'query', required: true, positional: true }],
columns: ['rank', 'title', 'url'],
func: async (page, kwargs) => {
await page.goto('https://www.mysite.com/search');
// 注入原生 XHR/Fetch 拦截器钩子
await page.installInterceptor('/api/search');
// 自动向下滚动以触发懒加载
await page.autoScroll({ times: 3, delayMs: 2000 });
// 检索拦截到的 JSON 载荷
const requests = await page.getInterceptedRequests();
let results = [];
for (const req of requests) {
results.push(...req.data.items);
}
return results.map((item, i) => ({
rank: i + 1, title: item.title, url: item.url,
}));
},
});
何时使用 TS :XHR 拦截(page.installInterceptor)、无限滚动(page.autoScroll)、cookie 提取、复杂数据转换(如 GraphQL 解包)。
| 步骤 | 描述 | 示例 |
|---|---|---|
navigate | 导航到 URL | navigate: https://example.com |
fetch | HTTP 请求(浏览器 cookies) | fetch: { url: "...", params: { q: "..." } } |
evaluate | 在页面中运行 JavaScript | `evaluate: |
select | 提取 JSON 路径 | select: data.items |
map | 映射字段 | map: { title: "${{ item.title }}" } |
filter | 过滤项目 | filter: item.score > 100 |
sort | 排序项目 | sort: { by: score, order: desc } |
limit | 限制结果数量 | limit: ${{ args.limit }} |
intercept | 声明式 XHR 捕获 | intercept: { trigger: "navigate:...", capture: "api/hot" } |
tap | 存储操作 + XHR 捕获 | tap: { store: "feed", action: "fetchFeeds", capture: "homefeed" } |
snapshot | 页面可访问性树 | snapshot: { interactive: true } |
click | 点击元素 | click: ${{ ref }} |
type | 输入文本 | type: { ref: "@1", text: "hello" } |
wait | 等待时间/文本 | wait: 2 或 wait: { text: "loaded" } |
press | 按键 | press: Enter |
# 带默认值的参数
${{ args.query }}
${{ args.limit | default(20) }}
# 当前项目(在 map/filter 中)
${{ item.title }}
${{ item.data.nested.field }}
# 索引(从 0 开始)
${{ index }}
${{ index + 1 }}
| 层级 | 名称 | 方法 | 示例 |
|---|---|---|---|
| 1 | public | 无需认证,Node.js fetch | Hacker News, V2EX |
| 2 | cookie | 浏览器 fetch 带 credentials: include | Bilibili, 知乎 |
| 3 | header | 自定义 headers (ct0, Bearer) | Twitter GraphQL |
| 4 | intercept | XHR 拦截 + store 变更 | 小红书 Pinia |
| 5 | ui | 完整的 UI 自动化(点击/输入/滚动) | 最后手段 |
| 变量 | 默认值 | 描述 |
|---|---|---|
OPENCLI_DAEMON_PORT | 19825 | 守护进程监听端口 |
OPENCLI_BROWSER_CONNECT_TIMEOUT | 30 | 浏览器连接超时(秒) |
OPENCLI_BROWSER_COMMAND_TIMEOUT | 45 | 命令执行超时(秒) |
OPENCLI_BROWSER_EXPLORE_TIMEOUT | 120 | 探索超时(秒) |
OPENCLI_VERBOSE | — | 显示守护进程/扩展日志 |
| 问题 | 解决方案 |
|---|---|
npx not found | 安装 Node.js:brew install node |
Extension not connected | 1) Chrome 必须已打开 2) 安装 opencli 浏览器桥接扩展 |
Target page context 错误 | 在 YAML 的 evaluate: 前添加 navigate: 步骤 |
| 表格数据为空 | 检查 evaluate 是否返回正确的数据路径 |
| 守护进程问题 | curl localhost:19825/status 检查状态,curl localhost:19825/logs 查看扩展日志 |
每周安装量
97
仓库
GitHub Stars
5.0K
首次出现
9 天前
安全审计
已安装于
codex93
cline92
kimi-cli92
gemini-cli92
cursor92
opencode92
Skills CLI 使用指南:AI Agent 技能包管理器安装与管理教程
43,100 周安装