chore: import upstream snapshot with attribution
E2E Headed Chrome / e2e-headed (macos-15) (push) Has been cancelled
E2E Headed Chrome / e2e-headed (ubuntu-latest) (push) Has been cancelled
E2E Headed Chrome / e2e-headed (windows-latest) (push) Has been cancelled
CI / build (macos-latest) (push) Has been cancelled
CI / build (ubuntu-latest) (push) Has been cancelled
CI / build (windows-latest) (push) Has been cancelled
CI / unit-test (push) Has been cancelled
CI / bun-test (push) Has been cancelled
CI / adapter-test (push) Has been cancelled
CI / smoke-test (macos-latest) (push) Has been cancelled
CI / smoke-test (ubuntu-latest) (push) Has been cancelled
Security Audit / audit (push) Has been cancelled
Build Chrome Extension / build (push) Has been cancelled
Trigger Website Rebuild (Docs Updated) / dispatch (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:39:48 +08:00
commit 9b395f5cc3
2400 changed files with 376116 additions and 0 deletions
+289
View File
@@ -0,0 +1,289 @@
import { defineConfig } from 'vitepress'
export default defineConfig({
base: '/docs/',
title: 'OpenCLI',
description: 'Make any website or Electron App your CLI — AI-powered, account-safe, self-healing.',
head: [
['meta', { property: 'og:title', content: 'OpenCLI Documentation' }],
['meta', { property: 'og:description', content: 'Make any website or Electron App your CLI.' }],
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
],
locales: {
root: {
label: 'English',
lang: 'en',
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide/getting-started' },
{ text: 'Adapters', link: '/adapters/' },
{ text: 'Developer', link: '/developer/contributing' },
{ text: 'Advanced', link: '/advanced/cdp' },
],
sidebar: {
'/guide/': [
{
text: 'Guide',
items: [
{ text: 'Getting Started', link: '/guide/getting-started' },
{ text: 'Installation', link: '/guide/installation' },
{ text: 'Comparison', link: '/comparison' },
{ text: 'Browser Bridge', link: '/guide/browser-bridge' },
{ text: 'Remote Orchestration', link: '/guide/remote-orchestration' },
{ text: 'Troubleshooting', link: '/guide/troubleshooting' },
{ text: 'Add an Electron App CLI', link: '/guide/electron-app-cli' },
{ text: 'Extending OpenCLI', link: '/guide/extending-opencli' },
{ text: 'Plugins', link: '/guide/plugins' },
],
},
],
'/adapters/': [
{
text: 'Adapters Overview',
items: [
{ text: 'All Adapters', link: '/adapters/' },
],
},
{
text: 'Browser Adapters',
collapsed: false,
items: [
{ text: 'Twitter / X', link: '/adapters/browser/twitter' },
{ text: 'Reddit', link: '/adapters/browser/reddit' },
{ text: 'Tieba', link: '/adapters/browser/tieba' },
{ text: 'Bilibili', link: '/adapters/browser/bilibili' },
{ text: 'Zhihu', link: '/adapters/browser/zhihu' },
{ text: 'Xiaohongshu', link: '/adapters/browser/xiaohongshu' },
{ text: 'Rednote', link: '/adapters/browser/rednote' },
{ text: 'WeChat Channels (视频号)', link: '/adapters/browser/wechat-channels' },
{ text: 'Xiaoe', link: '/adapters/browser/xiaoe' },
{ text: 'Weibo', link: '/adapters/browser/weibo' },
{ text: 'YouTube', link: '/adapters/browser/youtube' },
{ text: 'Xueqiu', link: '/adapters/browser/xueqiu' },
{ text: 'V2EX', link: '/adapters/browser/v2ex' },
{ text: 'Bloomberg', link: '/adapters/browser/bloomberg' },
{ text: 'LinkedIn', link: '/adapters/browser/linkedin' },
{ text: 'Coupang', link: '/adapters/browser/coupang' },
{ text: 'BOSS Zhipin', link: '/adapters/browser/boss' },
{ text: '51job', link: '/adapters/browser/51job' },
{ text: 'PowerChina', link: '/adapters/browser/powerchina' },
{ text: 'Ctrip', link: '/adapters/browser/ctrip' },
{ text: 'Booking.com', link: '/adapters/browser/booking' },
{ text: 'GeoGebra', link: '/adapters/browser/geogebra' },
{ text: 'Reuters', link: '/adapters/browser/reuters' },
{ text: 'HLTV', link: '/adapters/browser/hltv' },
{ text: 'SMZDM', link: '/adapters/browser/smzdm' },
{ text: 'Jike', link: '/adapters/browser/jike' },
{ text: 'Jimeng', link: '/adapters/browser/jimeng' },
{ text: 'Yollomi', link: '/adapters/browser/yollomi' },
{ text: 'LINUX DO', link: '/adapters/browser/linux-do' },
{ text: 'Band', link: '/adapters/browser/band' },
{ text: 'Chaoxing', link: '/adapters/browser/chaoxing' },
{ text: 'Grok', link: '/adapters/browser/grok' },
{ text: 'Kimi', link: '/adapters/browser/kimi' },
{ text: 'Amazon', link: '/adapters/browser/amazon' },
{ text: '1688', link: '/adapters/browser/1688' },
{ text: 'Gitee', link: '/adapters/browser/gitee' },
{ text: 'Gemini', link: '/adapters/browser/gemini' },
{ text: 'Claude', link: '/adapters/browser/claude' },
{ text: 'Yuanbao', link: '/adapters/browser/yuanbao' },
{ text: 'NotebookLM', link: '/adapters/browser/notebooklm' },
{ text: 'WeRead', link: '/adapters/browser/weread' },
{ text: 'Douban', link: '/adapters/browser/douban' },
{ text: 'Sina Blog', link: '/adapters/browser/sinablog' },
{ text: 'Substack', link: '/adapters/browser/substack' },
{ text: 'Pixiv', link: '/adapters/browser/pixiv' },
{ text: 'Douban', link: '/adapters/browser/douban' },
{ text: 'Doubao', link: '/adapters/browser/doubao' },
{ text: 'Facebook', link: '/adapters/browser/facebook' },
{ text: 'Google', link: '/adapters/browser/google' },
{ text: 'IMDb', link: '/adapters/browser/imdb' },
{ text: 'Indeed', link: '/adapters/browser/indeed' },
{ text: 'Upwork', link: '/adapters/browser/upwork' },
{ text: 'Instagram', link: '/adapters/browser/instagram' },
{ text: 'JD.com', link: '/adapters/browser/jd' },
{ text: 'Medium', link: '/adapters/browser/medium' },
{ text: 'Mercury', link: '/adapters/browser/mercury' },
{ text: 'Mubu', link: '/adapters/browser/mubu' },
{ text: 'TikTok', link: '/adapters/browser/tiktok' },
{ text: 'Web (Generic)', link: '/adapters/browser/web' },
{ text: 'Weixin', link: '/adapters/browser/weixin' },
{ text: 'Xianyu', link: '/adapters/browser/xianyu' },
{ text: 'Quark', link: '/adapters/browser/quark' },
{ text: 'Uiverse', link: '/adapters/browser/uiverse' },
{ text: 'Nowcoder', link: '/adapters/browser/nowcoder' },
{ text: 'Eastmoney', link: '/adapters/browser/eastmoney' },
{ text: 'TDX', link: '/adapters/browser/tdx' },
{ text: 'THS', link: '/adapters/browser/ths' },
{ text: 'Dianping', link: '/adapters/browser/dianping' },
{ text: 'Slock', link: '/adapters/browser/slock' },
],
},
{
text: 'Public API Adapters',
collapsed: false,
items: [
{ text: 'HackerNews', link: '/adapters/browser/hackernews' },
{ text: 'Dev.to', link: '/adapters/browser/devto' },
{ text: 'Juejin', link: '/adapters/browser/juejin' },
{ text: 'Dictionary', link: '/adapters/browser/dictionary' },
{ text: 'BBC', link: '/adapters/browser/bbc' },
{ text: 'Apple Podcasts', link: '/adapters/browser/apple-podcasts' },
{ text: 'Xiaoyuzhou', link: '/adapters/browser/xiaoyuzhou' },
{ text: 'Yahoo Finance', link: '/adapters/browser/yahoo-finance' },
{ text: 'Internet Archive', link: '/adapters/browser/archive' },
{ text: 'arXiv', link: '/adapters/browser/arxiv' },
{ text: 'dblp', link: '/adapters/browser/dblp' },
{ text: 'PubMed', link: '/adapters/browser/pubmed' },
{ text: 'Semantic Scholar', link: '/adapters/browser/semanticscholar' },
{ text: 'paperreview.ai', link: '/adapters/browser/paperreview' },
{ text: 'Barchart', link: '/adapters/browser/barchart' },
{ text: 'Hugging Face', link: '/adapters/browser/hf' },
{ text: 'Sina Finance', link: '/adapters/browser/sinafinance' },
{ text: 'Spotify', link: '/adapters/browser/spotify' },
{ text: 'Jira', link: '/adapters/browser/jira' },
{ text: 'Confluence', link: '/adapters/browser/confluence' },
{ text: 'Chess.com', link: '/adapters/browser/chess' },
{ text: 'Stack Overflow', link: '/adapters/browser/stackoverflow' },
{ text: 'Wikipedia', link: '/adapters/browser/wikipedia' },
{ text: 'LessWrong', link: '/adapters/browser/lesswrong' },
{ text: 'Lobsters', link: '/adapters/browser/lobsters' },
{ text: 'Steam', link: '/adapters/browser/steam' },
],
},
{
text: 'Desktop Adapters',
collapsed: false,
items: [
{ text: 'Cursor', link: '/adapters/desktop/cursor' },
{ text: 'Trae CN', link: '/adapters/desktop/trae-cn' },
{ text: 'Codex', link: '/adapters/desktop/codex' },
{ text: 'Antigravity', link: '/adapters/desktop/antigravity' },
{ text: 'ChatGPT', link: '/adapters/desktop/chatgpt' },
{ text: 'ChatWise', link: '/adapters/desktop/chatwise' },
{ text: 'Discord', link: '/adapters/desktop/discord' },
{ text: 'Doubao App', link: '/adapters/desktop/doubao-app' },
{ text: 'Trae SOLO', link: '/adapters/desktop/trae-solo' },
],
},
],
'/developer/': [
{
text: 'Developer Guide',
items: [
{ text: 'Contributing', link: '/developer/contributing' },
{ text: 'Testing', link: '/developer/testing' },
{ text: 'Architecture', link: '/developer/architecture' },
{ text: 'YAML Adapter Guide (Deprecated)', link: '/developer/yaml-adapter' },
{ text: 'TypeScript Adapter Guide', link: '/developer/ts-adapter' },
{ text: 'AI Workflow', link: '/developer/ai-workflow' },
],
},
{
text: 'Conventions',
items: [
{ text: 'Listing↔Detail ID Pairing', link: '/conventions/listing-detail-id-pairing' },
{ text: 'Convention Audit', link: '/conventions/convention-audit' },
],
},
],
'/conventions/': [
{
text: 'Conventions',
items: [
{ text: 'Listing↔Detail ID Pairing', link: '/conventions/listing-detail-id-pairing' },
{ text: 'Convention Audit', link: '/conventions/convention-audit' },
],
},
],
'/advanced/': [
{
text: 'Advanced',
items: [
{ text: 'Chrome DevTools Protocol', link: '/advanced/cdp' },
{ text: 'Electron Apps', link: '/advanced/electron' },
{ text: 'Remote Chrome', link: '/advanced/remote-chrome' },
{ text: 'Download Support', link: '/advanced/download' },
],
},
],
},
},
},
zh: {
label: '中文',
lang: 'zh-CN',
link: '/zh/',
themeConfig: {
nav: [
{ text: '指南', link: '/zh/guide/getting-started' },
{ text: '适配器', link: '/zh/adapters/' },
{ text: '开发者', link: '/zh/developer/contributing' },
{ text: '进阶', link: '/zh/advanced/cdp' },
],
sidebar: {
'/zh/guide/': [
{
text: '指南',
items: [
{ text: '快速开始', link: '/zh/guide/getting-started' },
{ text: '安装', link: '/zh/guide/installation' },
{ text: 'Browser Bridge', link: '/zh/guide/browser-bridge' },
{ text: '给新 Electron 应用生成 CLI', link: '/zh/guide/electron-app-cli' },
{ text: '扩展 OpenCLI', link: '/zh/guide/extending-opencli' },
{ text: '插件', link: '/zh/guide/plugins' },
],
},
],
'/zh/adapters/': [
{
text: '适配器概览',
items: [
{ text: '所有适配器', link: '/zh/adapters/' },
],
},
],
'/zh/developer/': [
{
text: '开发者指南',
items: [
{ text: '贡献指南', link: '/zh/developer/contributing' },
],
},
],
'/zh/advanced/': [
{
text: '进阶',
items: [
{ text: 'Chrome DevTools Protocol', link: '/zh/advanced/cdp' },
],
},
],
},
},
},
},
themeConfig: {
search: {
provider: 'local',
},
socialLinks: [
{ icon: 'github', link: 'https://github.com/jackwener/opencli' },
{ icon: 'npm', link: 'https://www.npmjs.com/package/@jackwener/opencli' },
],
editLink: {
pattern: 'https://github.com/jackwener/opencli/edit/main/docs/:path',
text: 'Edit this page on GitHub',
},
footer: {
message: 'Released under the Apache-2.0 License.',
copyright: 'Copyright © 2024-present jackwener',
},
},
})
+211
View File
@@ -0,0 +1,211 @@
# 12306 (中国铁路 China Railway)
**Mode**: 🌐 Public (`stations`, `trains`, `train`, `price`) · 🖥️ Browser + Cookie (`me`, `passengers`, `orders`)
**Domain**: `kyfw.12306.cn`
Read-only adapter against the 12306 (China Railway) site. Anonymous queries
hit the public ticket-search endpoints; authenticated queries reuse the
user's existing browser login state. No CAPTCHA / slider / SMS / anti-abuse
bypass is performed, no credentials are stored, and no booking / payment /
ticket-sniping is implemented.
## Commands
| Command | Mode | Description |
|---------|------|-------------|
| `opencli 12306 stations` | Public | Search the station bundle by Chinese name, telecode, full pinyin, or short alias |
| `opencli 12306 trains` | Public | Trains between two stations on a given date with per-seat-class availability |
| `opencli 12306 train` | Public | Stop list (arrive / depart / stopover time) for one train segment |
| `opencli 12306 price` | Public | Ticket prices by seat class for one train segment + date |
| `opencli 12306 me` | Browser (cookie) | Logged-in account summary (sensitive fields masked by default) |
| `opencli 12306 passengers` | Browser (cookie) | Saved passenger list (sensitive fields masked by default) |
| `opencli 12306 orders` | Browser (cookie) | In-progress orders (not yet ridden / refunded / completed) |
## Usage Examples
```bash
# Search stations
opencli 12306 stations 上海 --limit 5
opencli 12306 stations beijing
opencli 12306 stations AOH # by telecode
# List trains between two stations
opencli 12306 trains 北京 上海 --date 2026-05-22 --limit 20
opencli 12306 trains BJP AOH --date 2026-05-22
# Show stops for one train
opencli 12306 train 24000000G10L --from 北京南 --to 上海虹桥 --date 2026-05-22
# Ticket prices by seat class
opencli 12306 price 24000000G10L --from 北京南 --to 上海虹桥 --date 2026-05-22
# Authenticated commands (require login on kyfw.12306.cn first)
opencli 12306 me
opencli 12306 me --include-sensitive
opencli 12306 passengers --limit 10
opencli 12306 orders
opencli 12306 orders --include-sensitive
# JSON output
opencli 12306 trains 北京 上海 --date 2026-05-22 -f json
```
## Station Resolution
The `<from>` and `<to>` arguments on `trains`, `train`, and `price` accept
any of the following forms; lookup is anchored against the public
`station_name.js` bundle 12306 ships:
- **Chinese name** (`上海虹桥`)
- **Telecode** (`AOH`, 3-4 uppercase letters, the wire format used in
12306's own API)
- **Full pinyin** (`shanghaihongqiao`, case-insensitive)
- **Short alias / abbr** (`shhq`)
Anything else raises `ArgumentError` with a hint pointing to the accepted
forms. Match order is exact-name first, so `北京` does not accidentally
resolve to `北京北` by substring.
## Columns
### `stations`
| Column | Notes |
|--------|-------|
| `name` | Chinese station name |
| `code` | 3-4 letter telecode (use in API URLs) |
| `pinyin` | Full pinyin |
| `abbr` | Short alias |
| `city` | Chinese city name |
### `trains`
| Column | Notes |
|--------|-------|
| `code` | Public train code (`G1`, `D301`, ...) |
| `from_station` / `to_station` | Chinese station names |
| `from_code` / `to_code` | Telecodes |
| `start_time` / `arrive_time` / `duration` | `HH:MM` format |
| `available` | `true` when 12306 shows 预订 status |
| `business_seat` / `first_seat` / `second_seat` | Availability for 商务座 / 一等座 / 二等座 (有 / 无 / number string) |
| `soft_sleeper` / `hard_sleeper` / `hard_seat` / `no_seat` | Same shape for 软卧 / 硬卧 / 硬座 / 无座 |
| `train_no` | Internal id used by `train` and `price` commands |
### `train`
| Column | Notes |
|--------|-------|
| `station_no` | 1-based stop index within this train's route |
| `station_name` | Chinese name |
| `arrive_time` / `start_time` / `stopover_time` | Empty string for the origin (no arrive) and destination (no stopover) |
### `price`
| Column | Notes |
|--------|-------|
| `seat_code` | 12306 seat letter (`A9` 商务座, `M` 一等座, `O` 二等座, `WZ` 无座, `A1` 硬座, `A3` 硬卧, `A4` 软卧, `F` 动卧, `P` 特等座) |
| `seat_name` | Localised Chinese label |
| `price` | Decimal string (CNY) |
| `currency` | Always `CNY` |
Rows are sorted by descending price. 12306 double-encodes some prices as
bare numeric keys (e.g. `"9": "21580"` mirroring `"A9": "¥2158.0"` in
no-decimal form); the bare-numeric duplicates are filtered out so each
seat class appears exactly once.
### `me`
| Column | Notes |
|--------|-------|
| `username` | 12306 login name (`loginUserDTO.user_name`) |
| `real_name` | Masked by default; `--include-sensitive` to opt in |
| `email` | Local-part masked by default |
| `mobile` | 12306 already masks server-side (`xxx****xxxx`) and the adapter preserves that |
| `birth_date` | Year only by default |
| `sex`, `country`, `user_type` | `男` / `女`, ISO-3, e.g. `成人` |
| `member`, `active` | Boolean flags |
### `passengers`
| Column | Notes |
|--------|-------|
| `name` | Masked by default to `<surname>*<...>` |
| `sex` | `男` / `女` |
| `born_year` | Year only by default |
| `id_type` | e.g. `居民身份证` |
| `id_no` | 12306 masks server-side; the adapter never decodes |
| `mobile` | Same as `me` |
| `passenger_type` | `成人`, `儿童`, `学生`, `残军` |
| `country` | ISO-3 |
### `orders`
| Column | Notes |
|--------|-------|
| `order_id` | 12306 sequence_no |
| `order_date` | Order placement timestamp |
| `train_code` | Public train code |
| `from_station` / `to_station` | Chinese names |
| `departure` | Departure timestamp |
| `passengers` | Comma-separated passenger names from the order; masked by default, `--include-sensitive` to opt in |
| `status` | 12306 ticket / order status name |
| `amount` | Total price (CNY) |
## Login
The three authenticated commands (`me`, `passengers`, `orders`) require a
logged-in 12306 session in the same Chrome instance that OpenCLI's bridge
talks to. Sign in once at `https://kyfw.12306.cn`; the adapter then reads
the resulting `tk` / `JSESSIONID` cookies on subsequent runs.
Login is detected via `document.cookie` rather than
`page.getCookies({url})`, because 12306 sets the auth cookies with
`Path=/otn` and CDP `Network.getCookies` filters by URL path - a bare
`https://kyfw.12306.cn` URL filter would otherwise hide them. If `tk` or
`JSESSIONID` is missing, the adapter raises `AuthRequiredError`.
## Privacy
Authenticated commands mask sensitive fields by default:
- **Email**: local part is `<first>***<last>@<domain>`
- **Mobile**: 12306's own mask is preserved (the adapter never tries to
decode it)
- **Real name / passenger/order passenger name**: Chinese names are masked to
`<first-char>*<last-char>` (or `<first-char>*` for two-character names)
- **Birth date**: year only
Pass `--include-sensitive` on `me`, `passengers`, or `orders` to opt back into
the unmasked fields the user is entitled to see on their own account. The
12306-side ID number mask is server-side and is never decoded.
## Limit Validation
All `--limit` arguments use a strict validator that throws `ArgumentError`
on non-integer / out-of-range input rather than silently clamping. The
caps are:
- `stations`: 1-50 (default 20)
- `trains`: 1-100 (default 50)
- `passengers`: 1-50 (default 20)
## Endpoint Notes
- `/otn/leftTicket/init` is hit first to mint anonymous session cookies
(`JSESSIONID`, `route`, `BIGipServerotn`).
- 12306 rotates the train-query endpoint name (`queryO`, `queryZ`,
`queryA`, `queryG`, ...) every few weeks. The adapter walks a list of
known names; when the server responds with
`{c_url: "leftTicket/queryX"}` it captures the suggested name and
retries.
- The `|`-separated train wire record includes a base64 booking-handshake
`secret` token at position 0. This adapter parses but does not surface
that field (a unit test asserts it cannot leak via the row shape).
## Non-Goals
- No ticket sniping
- No order submission / payment
- No CAPTCHA / slider / SMS / anti-abuse bypass
- No password storage
- No order history beyond the in-progress slice (left as a follow-up)
+61
View File
@@ -0,0 +1,61 @@
# 1688
**Mode**: 🔐 Browser · **Domain**: `1688.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli 1688 search "<query>" --limit <n>` | Search public product candidates with price, MOQ, seller link, and visible badges |
| `opencli 1688 item <url-or-offer-id>` | Read a public product detail page with price tiers, MOQ, delivery text, and seller basics |
| `opencli 1688 assets <url-or-offer-id>` | Extract product media assets visible on the item page (main images, SKU images, detail images, videos) |
| `opencli 1688 download <url-or-offer-id>` | Batch download product media assets visible on the item page |
| `opencli 1688 store <url-or-member-id>` | Read a public supplier/store page with company info, years on platform, categories, and visible service signals |
## Usage Examples
```bash
# Search products
opencli 1688 search "桌面置物架 宿舍 收纳" --limit 10
# JSON output
opencli 1688 search "桌面置物架 宿舍 收纳" --limit 10 -f json
# Read an item by offer id
opencli 1688 item 841141931191 -f json
# Read an item by URL
opencli 1688 item https://detail.1688.com/offer/841141931191.html -f json
# List downloadable media assets
opencli 1688 assets 841141931191 -f json
# Batch download page-visible images/videos
opencli 1688 download 841141931191 --output ./1688-downloads
# Read a supplier store
opencli 1688 store https://shop52908bfw19166.1688.com/ -f json
# Read a supplier by member id
opencli 1688 store b2b-22154705262941f196 -f json
```
## Prerequisites
- Chrome running and **logged into** `1688.com`
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- This adapter only returns or downloads fields and media visible on public pages. It does not send inquiries, place orders, or access seller back office data.
- `assets` / `download` currently prioritize page state and rendered DOM. They may not perfectly match every file exposed by the official 1688 extension workflow.
- Prefer stable identifiers such as `offer_id`, `member_id`, and `shop_id` for follow-up workflows.
- `search --limit` defaults to `20` and is capped at `100`.
- `search` deduplicates with key priority: `offer_id` first, then canonical `item_url`.
- `item` can be more sensitive to the active browser target than `search` or `store`.
## Troubleshooting
- If `opencli 1688 item` reports `did not expose product context`, first make sure the open page is a real `detail.1688.com` item page.
- If the browser target is too broad, retry with `OPENCLI_CDP_TARGET=detail.1688.com`.
- If you hit a slider or verification page, refresh the real page in Chrome and retry.
+77
View File
@@ -0,0 +1,77 @@
# 1point3acres (一亩三分地)
Browse and search **1point3acres** — a Discuz!-based BBS popular for North American job, immigration, and grad-school discussions. Public listings work without auth; `search` and `notifications` require an active browser session.
**Mode**: 🌐 Public + 🔐 Cookie · **Domain**: `www.1point3acres.com`
## Commands
| Command | Description | Auth |
|---------|-------------|------|
| `opencli 1point3acres hot` | Today's hot threads (by heat) | Public |
| `opencli 1point3acres latest` | Newest threads (by post time, desc) | Public |
| `opencli 1point3acres digest` | Editor-picked / featured threads | Public |
| `opencli 1point3acres forums` | List all forums (fid + name) | Public |
| `opencli 1point3acres forum <fid>` | List threads in a specific forum | Public |
| `opencli 1point3acres thread <tid>` | Thread detail + replies | Public |
| `opencli 1point3acres user <who>` | User profile (group / points / 大米 / posts) | Public |
| `opencli 1point3acres search <query>` | Full-text search | Cookie |
| `opencli 1point3acres notifications` | Site notifications (replies / mentions / reviews) | Cookie |
## Usage Examples
```bash
# Today's hot threads
opencli 1point3acres hot --limit 10
# Newest posts in the overseas-job-referral forum (fid=198)
opencli 1point3acres forum 198 --limit 20
# Read a thread (tid comes from any listing's `tid` column)
opencli 1point3acres thread 1158360 --limit 10
# Lookup a user (numeric → uid, otherwise username)
opencli 1point3acres user 12345
opencli 1point3acres user some-username
# Filter the forum list by keyword
opencli 1point3acres forums --filter 面经
# Search the site (requires login)
opencli 1point3acres search "OPT extension" --limit 10
# Notifications (requires login)
opencli 1point3acres notifications --kind mypost --limit 20
```
## Common Forum IDs
`145` (海外面经) · `198` (海外职位内推) · `27` (研究生申请) · `28` (博士申请) · `82` (NIW / EB-1A 移民).
Use `opencli 1point3acres forums` to see the full list.
## Output Columns
| Command | Columns |
|---------|---------|
| `hot` / `latest` / `digest` / `forum` | `rank, tid, title, forum, author, replies, views, lastReplyTime, url` |
| `thread` | `floor, pid, author, postTime, content, url` |
| `user` | `uid, username, group, credits, rice, posts, threads, digests, registerTime, lastAccess, profileUrl` |
| `forums` | `fid, name, url` |
| `search` | `rank, tid, title, forum, author, replies, views, postTime, url` |
| `notifications` | `index, from, summary, time, threadUrl` |
## Prerequisites
- No browser required for public commands (`hot` / `latest` / `digest` / `forums` / `forum` / `thread` / `user`)
- For `search` and `notifications`:
- Chrome is running
- You are already logged in to `www.1point3acres.com`
- [Browser Bridge extension](/guide/browser-bridge) is installed
## Notes
- The site serves GBK-encoded HTML; the adapter decodes to UTF-8 internally
- `tid` (thread id) is the canonical handle that pipes a listing row into `thread` for the full content
- Public endpoints serve rendered HTML, so heavy bot traffic may hit Discuz challenge / login gates — fall back to a logged-in session if `hot` / `latest` start returning empty rows
- Listing `--limit` values are validated upfront and rejected with `ArgumentError` if non-positive or above 50 (the page yields ~50 rows max) — no silent clamp
- `thread --page`, `thread --limit`, `thread --contentLimit`, and `notifications --limit` also reject invalid values explicitly instead of silently flooring them
+48
View File
@@ -0,0 +1,48 @@
# 36kr (36氪)
**Mode**: 🌐 Public / 🔐 Browser · **Domain**: `36kr.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli 36kr hot` | 36氪热榜 — trending articles |
| `opencli 36kr news` | Latest tech/startup news from 36kr |
| `opencli 36kr search <query>` | Search 36kr articles |
| `opencli 36kr article <id-or-url>` | Read full article content |
## Usage Examples
```bash
# Trending articles
opencli 36kr hot --limit 10
# Hot by type
opencli 36kr hot --type renqi --limit 10
opencli 36kr hot --type zonghe --limit 10
# Latest news
opencli 36kr news --limit 20
# Search articles
opencli 36kr search "AI" --limit 10
opencli 36kr search "OpenAI" --limit 5
# Read full article (by ID or URL)
opencli 36kr article 3000000123456
opencli 36kr article https://36kr.com/p/3000000123456
# JSON output
opencli 36kr hot -f json
```
## Notes
- `news` uses the public RSS feed and works without Browser Bridge.
- `hot`, `search`, and `article` use Browser Bridge and are best run with Chrome open.
- `hot --type` accepts `catalog`, `renqi`, `zonghe`, and `shoucang`.
## Prerequisites
- `news`: No browser required — uses public RSS feed
- `hot`, `search`, `article`: Chrome running with [Browser Bridge extension](/guide/browser-bridge) installed
+38
View File
@@ -0,0 +1,38 @@
# 51job
**Mode**: 🔐 Browser · **Domains**: `we.51job.com`, `jobs.51job.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli 51job search <keyword>` | Keyword search with city / salary / experience / degree / company filters |
| `opencli 51job hot` | Recommended jobs feed for a city |
| `opencli 51job detail <jobId>` | Full job detail page by `jobId` |
| `opencli 51job company <encCoId>` | Company profile plus active jobs by encrypted company ID |
## Usage Examples
```bash
# Search Beijing Python jobs
opencli 51job search python --area 北京 --limit 5
# Recommended jobs in Shanghai
opencli 51job hot --area 上海 --limit 5
# Detail by jobId from search/hot output
opencli 51job detail 171699769
# Company jobs by encCoId from search output
opencli 51job company MjYxMjgxMA== --limit 3
# JSON output for agent workflows
opencli 51job search Golang --area 杭州 -f json
```
## Notes
- `search` and `hot` run behind Aliyun WAF. The adapter uses a real browser session and browser-context `fetch` for the JSON API on `we.51job.com`.
- `detail` and `company` read SSR HTML pages on `jobs.51job.com`.
- `area` accepts a known city name or a 6-digit city code. Unknown non-empty values fail fast.
- `company` returns the full `companyIntro` text. It does not silently truncate content.
+24
View File
@@ -0,0 +1,24 @@
# AIbase
**Mode**: 🌐 Public · **Domain**: `aibase.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli aibase news` | AIbase daily AI industry news |
## Usage Examples
```bash
# Latest AIbase daily news
opencli aibase news --limit 20
# JSON output
opencli aibase news --limit 10 -f json
```
## Notes
- Returns `rank`, `title`, and stable article `url`.
- Invalid `--limit` values fail fast instead of being silently clamped.
+55
View File
@@ -0,0 +1,55 @@
# Amazon
**Mode**: 🔐 Browser · **Domain**: `amazon.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli amazon bestsellers [<best-sellers-url>]` | Read Amazon Best Sellers pages for ranked candidate discovery |
| `opencli amazon search "<query>"` | Read Amazon search results for coarse filtering |
| `opencli amazon product <asin-or-url>` | Read a product page with title, price, rating, breadcrumbs, and bullets |
| `opencli amazon offer <asin-or-url>` | Read seller / fulfillment / buy-box facts from the product page |
| `opencli amazon discussion <asin-or-url>` | Read review summary and sample customer reviews |
| `opencli amazon movers-shakers [<url>]` | Amazon Movers & Shakers pages for short-term growth signals |
| `opencli amazon new-releases [<url>]` | Amazon New Releases pages for early momentum discovery |
## Usage Examples
```bash
# Root Best Sellers page
opencli amazon bestsellers https://www.amazon.com/Best-Sellers/zgbs --limit 10 -f json
# Category-specific Best Sellers page
opencli amazon bestsellers "<category-best-sellers-url>" --limit 50 -f json
# Search products
opencli amazon search "desk shelf organizer" --limit 20 -f json
# Validate one product
opencli amazon product B0FJS72893 -f json
# Validate seller / offer facts
opencli amazon offer B0FJS72893 -f json
# Read review summary + samples
opencli amazon discussion B0FJS72893 --limit 5 -f json
```
## Prerequisites
- Chrome running with an active `amazon.com` session in the shared profile
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- This adapter only returns fields visible on public Amazon pages.
- `bestsellers`, `movers-shakers`, `new-releases`, and `search` are for candidate discovery; `product`, `offer`, and `discussion` are the validation surfaces.
- `offer` is the right surface for `sold_by`, `ships_from`, and Amazon-retail exclusion.
- `discussion` may return review data even when Q&A is absent. Missing Q&A is a normal outcome, not an error.
## Troubleshooting
- If Amazon shows a robot-check page, clear it in Chrome and retry.
- If CDP is attached to the wrong tab, retry with `OPENCLI_CDP_TARGET=amazon.com`.
- Avoid running multiple Amazon browser commands in parallel against the same shared Chrome target.
+28
View File
@@ -0,0 +1,28 @@
# Apple Podcasts
**Mode**: 🌐 Public · **Domain**: `podcasts.apple.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli apple-podcasts search` | |
| `opencli apple-podcasts episodes` | |
| `opencli apple-podcasts top` | |
## Usage Examples
```bash
# Quick start
opencli apple-podcasts search --limit 5
# JSON output
opencli apple-podcasts search -f json
# Verbose mode
opencli apple-podcasts search -v
```
## Prerequisites
- No browser required — uses public API
+81
View File
@@ -0,0 +1,81 @@
# Internet Archive
**Mode**: 🌐 Public · **Domain**: `archive.org`
## Commands
| Command | Description |
|---------|-------------|
| `opencli archive search <query>` | Search Internet Archive items across books, movies, audio, software, and web |
| `opencli archive item <identifier>` | Fetch metadata for a single Internet Archive item by identifier |
| `opencli archive wayback <url>` | Look up the closest Wayback Machine snapshot for a URL |
| `opencli archive snapshots <url>` | List Wayback Machine snapshots over time for a URL via the CDX API |
## Usage Examples
```bash
# Full-text search across all mediatypes (default sort by downloads)
opencli archive search "machine learning" --limit 10
# Restrict to a mediatype
opencli archive search "newton principia" --mediatype texts --limit 5
opencli archive search "moon landing" --mediatype movies --sort date --limit 5
# Single item metadata
opencli archive item open-syllabus
opencli archive item FinalFantasy2_356
# Closest Wayback snapshot, optionally near a date
opencli archive wayback wikipedia.org
opencli archive wayback wikipedia.org --timestamp 2015
# Wayback CDX history for a URL
opencli archive snapshots wikipedia.org --limit 20
opencli archive snapshots wikipedia.org --from 2010 --to 2015 --limit 50
# JSON output
opencli archive search "machine learning" -f json
```
### `search` Options
| Option | Description |
|--------|-------------|
| `query` (positional) | Full-text query (matches title, description, creator, subject) |
| `--mediatype` | `texts` / `movies` / `audio` / `software` / `image` / `web` / `data` / `collection` |
| `--sort` | `downloads` (default) / `date` / `addeddate` / `week` / `title` |
| `--limit` | Max items (1-100, default: 20) |
Returns rows with `rank, identifier, title, creator, date, mediatype, downloads, url`. The `identifier` round-trips into `opencli archive item <identifier>`.
### `item` Options
| Option | Description |
|--------|-------------|
| `identifier` (positional) | Archive item identifier (letters, digits, ".", "_", "-") |
Returns one row with `identifier, title, creator, date, mediatype, collection, description, file_count, url`.
### `wayback` Options
| Option | Description |
|--------|-------------|
| `url` (positional) | URL to look up (with or without scheme) |
| `--timestamp` | Target timestamp (`YYYY[MM[DD[hh[mm[ss]]]]]` or ISO date). Defaults to most recent snapshot |
Returns one row with `original_url, requested_timestamp, snapshot_timestamp, snapshot_url, status`. The `snapshot_url` round-trips into a regular browser fetch.
### `snapshots` Options
| Option | Description |
|--------|-------------|
| `url` (positional) | URL to look up (with or without scheme) |
| `--from` | Earliest digit-only timestamp |
| `--to` | Latest digit-only timestamp |
| `--limit` | Max snapshots (1-1000, default: 20) |
Returns rows with `timestamp, snapshot_url, status, mimetype, original_url`. Each `snapshot_url` is a direct Wayback Machine permalink. The CDX endpoint is served over HTTP only; the HTTPS endpoint returns 503 in practice.
## Prerequisites
- No browser required; uses public archive.org APIs (Advanced Search, Metadata, Wayback Available, CDX).
+52
View File
@@ -0,0 +1,52 @@
# arXiv
**Mode**: 🌐 Public · **Domain**: `arxiv.org`
## Commands
| Command | Description |
|---------|-------------|
| `opencli arxiv search <query>` | Search arXiv papers |
| `opencli arxiv paper <id>` | Get arXiv paper details by ID |
| `opencli arxiv recent <category>` | List recent submissions in a category |
| `opencli arxiv author <name>` | List papers by a given author (newest first) |
## Usage Examples
```bash
# Search for papers
opencli arxiv search "transformer attention" --limit 10
# Get full paper details (full abstract, all authors, primary/all categories, pdf url)
opencli arxiv paper 1706.03762
# Newest papers in a category, sorted by submitted date desc
opencli arxiv recent cs.CL --limit 10
opencli arxiv recent math.PR --limit 5
# Newest papers by an author (best-effort fuzzy match — try alternate spellings if empty)
opencli arxiv author "Yoshua Bengio" --limit 20
opencli arxiv author "Y Bengio" --limit 5
# JSON output
opencli arxiv search "LLM" -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `paper` | `id, title, authors, published, updated, primary_category, categories, abstract, comment, pdf, url` |
| `search` | `id, title, authors, published, primary_category, url` |
| `recent` | `id, title, authors, published, primary_category, url` |
| `author` | `id, title, authors, published, primary_category, url` |
`paper` returns the full abstract and full author list. `search`/`recent` are list-style outputs that omit the abstract for readability — pipe an id into `paper` for the full record.
## Common Categories
`cs.AI`, `cs.CL`, `cs.LG`, `cs.CV`, `cs.RO`, `stat.ML`, `math.PR`, `math.ST`, `q-bio.NC`, `econ.TH`, `physics.comp-ph`. Full list: <https://arxiv.org/category_taxonomy>.
## Prerequisites
- No browser required — uses public arXiv API
+62
View File
@@ -0,0 +1,62 @@
# 汽车之家 Autohome
**Mode**: 🌐 Public · **Domain**: `autohome.com.cn`
No login, no cookies, no signature. Reads two fully server-rendered sources:
the brand catalog (`grade/carhtml/<INITIAL>.html`) and the 口碑 page
(`k.autohome.com.cn/<seriesId>`, whose `__NEXT_DATA__` carries the aggregate
rating).
## Commands
| Command | Description |
|---------|-------------|
| `opencli autohome brand <品牌>` | A brand's car series + 厂商指导价 (guide price) |
| `opencli autohome score <series_id>` | 口碑 rating: overall + per-dimension + 故障率PPH + competitors |
`score` takes a **series_id** from `brand` (the `series_id` column) or a
`https://k.autohome.com.cn/<id>` URL.
## Usage Examples
```bash
# A brand's whole lineup with guide prices
opencli autohome brand 宝马
opencli autohome brand 比亚迪 --limit 80
opencli autohome brand 理想
# Owner-rating summary for a series
opencli autohome score 6548 # 宝马X5
# JSON output
opencli autohome brand 丰田 -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `brand` | `series_id, name, price, url` |
| `score` | `field, value` (series_id, name, brand, level, guide_price, overall, 各维度评分…, pph_每百车故障, review_users, competitors, url) |
## Notes & Limits
- **Search is by brand, not free text.** Autohome's keyword-search and the
per-trim config JSON are app-signature gated; the brand catalog is the
login-free entry point, so you search by brand (e.g. 宝马 / 比亚迪 / 理想) and
drill into a series from there. For free-text model search, use
`dongchedi search`.
- **`brand` accepts known Chinese brand names** (mapped to the catalog's pinyin
initial) or a single A-Z catalog letter. Unknown brands raise a clear error
rather than guessing.
- **`score` is the aggregate rating only.** The per-review owner-text list loads
from a separate signed XHR and is intentionally not scraped (use
`dongchedi koubei` for owner review bodies).
- **Full per-trim config (参数配置) is not offered** — Autohome's config page
obfuscates values with a rotating CSS font glyph map, which can't be read
reliably from plain HTTP; faking partial specs would be worse than omitting
them. Use `dongchedi specs` for a config overview.
## Prerequisites
None — public site, no authentication required.
+21
View File
@@ -0,0 +1,21 @@
# Baidu Scholar
**Mode**: 🌐 Public · **Domain**: `xueshu.baidu.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli baidu-scholar search <query>` | Search Baidu Scholar papers by keyword |
## Usage Examples
```bash
opencli baidu-scholar search "大语言模型"
opencli baidu-scholar search "检索增强生成" --limit 5
```
## Notes
- Runs in browser mode against public search results
- Baidu may occasionally present verification or anti-bot pages
+63
View File
@@ -0,0 +1,63 @@
# Band
**Mode**: 🔐 Browser · **Domain**: `www.band.us`
Read posts, comments, and notifications from [Band](https://www.band.us), a private community platform. Authentication uses your logged-in Chrome session (cookie-based).
## Commands
| Command | Description |
|---------|-------------|
| `opencli band bands` | List all Bands you belong to |
| `opencli band posts <band_no>` | List posts from a Band |
| `opencli band post <band_no> <post_no>` | Export full post content including nested comments |
| `opencli band mentions` | Show notifications where you were @mentioned |
## Usage Examples
```bash
# List all your bands (get band_no from here)
opencli band bands
# List recent posts in a band
opencli band posts 12345678 --limit 10
# Export a post with comments
opencli band post 12345678 987654321
# Export post body only (skip comments)
opencli band post 12345678 987654321 --comments false
# Export post and download attached photos
opencli band post 12345678 987654321 --output ./band-photos
# Show recent @mention notifications
opencli band mentions --limit 20
# Show only unread mentions
opencli band mentions --unread true
# Show all notification types
opencli band mentions --filter all
```
### `band mentions` filter options
| Filter | Description |
|--------|-------------|
| `mentioned` | Only notifications where you were @mentioned (default) |
| `all` | All notifications |
| `post` | Post-related notifications |
| `comment` | Comment-related notifications |
## Prerequisites
- Chrome running and **logged into** [band.us](https://www.band.us)
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- `band_no` is the numeric ID in the Band URL: `band.us/band/{band_no}/post`
- `band bands` lists all your bands with their `band_no` values
- `band post` output rows: `type=post` (the post itself), `type=comment` (top-level comment), `type=reply` (nested reply)
- Photo downloads use the full-resolution URL (thumbnail query params are stripped automatically)
+33
View File
@@ -0,0 +1,33 @@
# Barchart
**Mode**: 🔐 Browser · **Domain**: `barchart.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli barchart quote` | Stock quote with price, volume, and key metrics |
| `opencli barchart options` | Options chain with greeks, IV, volume, and open interest |
| `opencli barchart greeks` | Options greeks overview (IV, delta, gamma, theta, vega) |
| `opencli barchart flow` | Unusual options activity / options flow |
## Usage Examples
```bash
# Get stock quote
opencli barchart quote AAPL
# View options chain
opencli barchart options TSLA
# Options greeks overview
opencli barchart greeks NVDA
# Unusual options flow
opencli barchart flow --limit 20 -f json
```
## Prerequisites
- Chrome running and able to open `barchart.com`
- [Browser Bridge extension](/guide/browser-bridge) installed
+54
View File
@@ -0,0 +1,54 @@
# BBC News
**Mode**: 🌐 Public · **Domain**: `bbc.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli bbc news` | Latest BBC News headlines (top stories) |
| `opencli bbc topic <topic>` | Latest headlines for a single BBC topic feed |
## Usage Examples
```bash
# Top stories
opencli bbc news --limit 5
# Topic-scoped feeds (RSS at feeds.bbci.co.uk/news/<topic>/rss.xml)
opencli bbc topic technology --limit 10
opencli bbc topic world --limit 20
opencli bbc topic business
opencli bbc topic science_and_environment
# JSON output
opencli bbc topic technology -f json
```
## Topics
Valid `<topic>` values:
| Topic slug | Feed |
|------------|------|
| `world` | World news |
| `business` | Business |
| `politics` | UK politics |
| `health` | Health |
| `education` | Education & family |
| `science_and_environment` | Science & environment |
| `technology` | Technology |
| `entertainment_and_arts` | Entertainment & arts |
Pass any other value and the adapter raises `ArgumentError` with the full list.
## Output Columns
| Command | Columns |
|---------|---------|
| `news` | (see existing news row schema) |
| `topic` | `rank, title, description, pubDate, url` |
## Prerequisites
- No browser required — uses the public BBC RSS feeds at `feeds.bbci.co.uk`.
+105
View File
@@ -0,0 +1,105 @@
# Bilibili
**Mode**: 🔐 Browser · **Domain**: `bilibili.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli bilibili hot` | |
| `opencli bilibili search` | |
| `opencli bilibili me` | |
| `opencli bilibili favorite` | Read your first favorite folder, or a specific folder with `--fid` |
| `opencli bilibili history` | |
| `opencli bilibili feed` | Read the following feed, or a specific user's dynamics by uid/name |
| `opencli bilibili feed-detail` | Read one dynamic in detail, including exclusive content |
| `opencli bilibili subtitle` | |
| `opencli bilibili video` | Get one video's metadata (title, author, duration, stats) by BV / URL / b23.tv link |
| `opencli bilibili summary` | Get the official AI video summary and timestamped outline by BV / URL / b23.tv link |
| `opencli bilibili comments` | Read top-level comments, or read replies under a top-level comment with `--parent` |
| `opencli bilibili comment` | Post a top-level comment or reply under a top-level comment (requires `--execute`) |
| `opencli bilibili dynamic` | |
| `opencli bilibili ranking` | |
| `opencli bilibili following` | |
| `opencli bilibili follow` | Follow a user by UID, profile URL, or resolvable name; verifies the relation after modify |
| `opencli bilibili unfollow` | Unfollow a user by UID, profile URL, or resolvable name; verifies the relation after modify |
| `opencli bilibili user-videos` | |
| `opencli bilibili download` | |
## Usage Examples
```bash
# Quick start
opencli bilibili hot --limit 5
# Search videos
opencli bilibili search 黑神话 --limit 10
# Read one creator's videos
opencli bilibili user-videos 2 --limit 10
# Follow / unfollow a creator
opencli bilibili follow 9617619
opencli bilibili unfollow https://space.bilibili.com/9617619
# Read your first favorite folder
opencli bilibili favorite --limit 10
# Read a specific favorite folder
opencli bilibili favorite --fid 123456789 --limit 10
# Read following feed
opencli bilibili feed --limit 10
# Read one user's dynamics by UID
opencli bilibili feed 2 --limit 10
# Read one user's dynamics by username and paginate
opencli bilibili feed 老番茄 --pages 2 --type video
# Read one dynamic in detail
opencli bilibili feed-detail 1234567890123456789
# Fetch subtitles
opencli bilibili subtitle BV1xx411c7mD --lang zh-CN
# Inspect one video's metadata
opencli bilibili video BV1xx411c7mD
opencli bilibili video https://www.bilibili.com/video/BV1xx411c7mD/
# Fetch the official AI summary for a video
opencli bilibili summary BV1xx411c7mD
opencli bilibili summary https://www.bilibili.com/video/BV1xx411c7mD/
# Read comments and a reply thread under a top-level rpid
opencli bilibili comments BV1xx411c7mD --limit 10
opencli bilibili comments BV1xx411c7mD --parent 123456789 --limit 10
# Post a comment or reply. The write only happens with --execute.
opencli bilibili comment BV1xx411c7mD "这条评论来自 OpenCLI" --execute
opencli bilibili comment BV1xx411c7mD "回复楼主" --parent 123456789 --execute
# JSON output
opencli bilibili hot -f json
# Verbose mode
opencli bilibili hot -v
```
## Prerequisites
- Chrome running and **logged into** bilibili.com
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- `opencli bilibili feed` without `uid` reads your following feed
- `opencli bilibili feed <uid-or-name>` reads a specific user's dynamics
- `opencli bilibili favorite` defaults to the first favorite folder when `--fid` is omitted
- `feed-detail` expects the dynamic ID from a `https://t.bilibili.com/<id>` URL
- `comments` emits `rpid`; pass a top-level row's `rpid` to `comments --parent` to read its reply thread
- `comments --limit` accepts `1..50`; empty comment lists raise `EmptyResultError`
- `comment` is a write command and refuses to post unless `--execute` is passed
- `comment --parent` expects the top-level/root `rpid`; nested reply-to-reply targeting is not inferred
- `follow` and `unfollow` are write commands; they no-op when the current relation already matches the requested state and otherwise re-read `/x/relation` after modify before reporting success
- `follow` and `unfollow` accept numeric UID, exact `space.bilibili.com/<uid>` profile URL, or a name that resolves through Bilibili search
+52
View File
@@ -0,0 +1,52 @@
# Binance
Access **Binance** market data from the terminal via the public API (no authentication required).
**Mode**: 🌐 Public · **Domain**: `data-api.binance.vision`
## Commands
| Command | Description |
|---------|-------------|
| `opencli binance price` | Get 24h ticker stats for one symbol |
| `opencli binance prices` | Get latest prices for all symbols |
| `opencli binance ticker` | Get 24h ticker stats for all symbols |
| `opencli binance pairs` | List exchange trading pairs |
| `opencli binance trades` | Get recent trades for one symbol |
| `opencli binance depth` | Get order-book depth for one symbol |
| `opencli binance asks` | Show ask-side depth for one symbol |
| `opencli binance klines` | Get candlestick data |
| `opencli binance top` | Show top movers by volume |
| `opencli binance gainers` | Show top gainers |
| `opencli binance losers` | Show top losers |
## Usage Examples
```bash
# One symbol, 24h stats
opencli binance price BTCUSDT
# Latest prices for all pairs
opencli binance prices
# Recent trades
opencli binance trades BTCUSDT --limit 20
# Order-book depth
opencli binance depth BTCUSDT --limit 20
# 1h candles
opencli binance klines BTCUSDT --interval 1h --limit 50
# JSON output
opencli binance top -f json
```
## Prerequisites
- No browser required — uses Binance public market-data endpoints
## Notes
- Symbols use Binance market format such as `BTCUSDT` or `ETHUSDT`
- Public market-data endpoints can still be rate-limited upstream; retry if you hit transient failures
+81
View File
@@ -0,0 +1,81 @@
# Bloomberg
**Mode**: 🌐 / 🔐 Mixed · **Domains**: `feeds.bloomberg.com`, `www.bloomberg.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli bloomberg main` | Bloomberg homepage top stories from RSS |
| `opencli bloomberg markets` | Bloomberg Markets top stories from RSS |
| `opencli bloomberg economics` | Bloomberg Economics top stories from RSS |
| `opencli bloomberg industries` | Bloomberg Industries top stories from RSS |
| `opencli bloomberg tech` | Bloomberg Tech top stories from RSS |
| `opencli bloomberg politics` | Bloomberg Politics top stories from RSS |
| `opencli bloomberg businessweek` | Bloomberg Businessweek top stories from the section page |
| `opencli bloomberg opinions` | Bloomberg Opinion top stories from RSS |
| `opencli bloomberg green` | Bloomberg Green top stories from RSS |
| `opencli bloomberg crypto` | Bloomberg Crypto top stories from RSS |
| `opencli bloomberg pursuits` | Bloomberg Pursuits top stories from RSS |
| `opencli bloomberg feeds` | List the RSS feed aliases used by the adapter |
| `opencli bloomberg news <link>` | Read a standard Bloomberg story/article page and return title, summary, media links, and article text |
## What works today
- RSS-backed listing commands work without a browser:
- `main`
- `markets`
- `economics`
- `industries`
- `tech`
- `politics`
- `opinions`
- `green`
- `crypto`
- `pursuits`
- `feeds`
- `bloomberg businessweek` reads the live Businessweek section page through Browser Bridge because Bloomberg's legacy Businessweek RSS feed is currently empty.
- `bloomberg news` works on standard Bloomberg story/article pages that expose `#__NEXT_DATA__` and are accessible to your current Chrome session.
## Current limitations
- Audio pages and some other non-standard Bloomberg URLs may fail.
- Some Bloomberg pages can return bot-protection or access-gated responses instead of article data.
- This adapter is for data retrieval/extraction only. It does **not** bypass Bloomberg paywall, login, entitlement, or other access checks.
## Usage Examples
```bash
# List supported RSS feed aliases
opencli bloomberg feeds
# Fetch Bloomberg homepage headlines
opencli bloomberg main --limit 5
# Fetch a section feed as JSON
opencli bloomberg tech --limit 3 -f json
# Fetch Businessweek section stories
opencli bloomberg businessweek --limit 5 -f json
# Read a standard article page
opencli bloomberg news https://www.bloomberg.com/news/articles/2026-03-19/example -f json
# Relative article paths also work
opencli bloomberg news /news/articles/2026-03-19/example
```
## Prerequisites
- RSS commands do not require Chrome.
- `bloomberg businessweek` requires Chrome and the [Browser Bridge extension](/guide/browser-bridge) because it reads the section page.
- `bloomberg news` requires:
- Chrome running
- a Chrome session that can already access the target Bloomberg article page
- the [Browser Bridge extension](/guide/browser-bridge)
## Notes
- Listing commands support `--limit` with a maximum of 20 items.
- `bloomberg feeds` lists RSS-backed aliases only; `businessweek` is intentionally absent because it is section-page backed.
- If `bloomberg news` fails on a page from RSS, try a different standard story/article link first; not every Bloomberg URL in feeds is a normal article page.
+53
View File
@@ -0,0 +1,53 @@
# Bluesky
**Mode**: 🌐 Public · **Domain**: `bsky.app`
## Commands
| Command | Description |
|---------|-------------|
| `opencli bluesky profile` | User profile info |
| `opencli bluesky user` | Recent posts from a user |
| `opencli bluesky trending` | Trending topics |
| `opencli bluesky search` | Search users |
| `opencli bluesky feeds` | Popular feed generators |
| `opencli bluesky followers` | User's followers |
| `opencli bluesky following` | Accounts a user follows |
| `opencli bluesky thread` | Post thread with replies |
| `opencli bluesky starter-packs` | User's starter packs |
## Usage Examples
```bash
# User profile
opencli bluesky profile --handle bsky.app
# Recent posts
opencli bluesky user --handle bsky.app --limit 10
# Trending topics
opencli bluesky trending --limit 10
# Search users
opencli bluesky search --query "AI" --limit 10
# Popular feeds
opencli bluesky feeds --limit 10
# Followers / following
opencli bluesky followers --handle bsky.app --limit 10
opencli bluesky following --handle bsky.app
# Post thread with replies
opencli bluesky thread --uri "at://did:.../app.bsky.feed.post/..."
# Starter packs
opencli bluesky starter-packs --handle bsky.app
# JSON output
opencli bluesky profile --handle bsky.app -f json
```
## Prerequisites
None — all commands use the public Bluesky AT Protocol API, no browser or login required.
+92
View File
@@ -0,0 +1,92 @@
# Booking.com
**Mode**: 🔓 Public (browser) · **Domain**: `www.booking.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli booking search` | Search hotels by destination + check-in/check-out dates |
## Usage Examples
```bash
# Basic — 2 adults, 1 room, default Booking page size (25 results)
opencli booking search Tokyo --checkin 2026-06-15 --checkout 2026-06-17
# Force result locale and currency
opencli booking search Paris --checkin 2026-07-01 --checkout 2026-07-03 \
--lang en-us --currency USD
# Family stay — 2 adults + 2 children, 1 room
opencli booking search Singapore --checkin 2026-06-15 --checkout 2026-06-20 \
--adults 2 --children 2
# Paginate (Booking pages 25 per request)
opencli booking search Tokyo --checkin 2026-06-15 --checkout 2026-06-17 --offset 25
# JSON output for downstream tooling
opencli booking search Tokyo --checkin 2026-06-15 --checkout 2026-06-17 -f json
```
## Output
### `search`
| Column | Type | Notes |
|--------|------|-------|
| `rank` | int | 1-based position within this query (carries `--offset` so paginated calls stay sortable) |
| `name` | string | Hotel display name. May be localized by browser session cookies — see *Locale handling* below |
| `country` | string | ISO-3166 alpha-2 country code parsed from URL path |
| `slug` | string | URL path slug — stable cross-locale identifier, round-trips into the canonical detail URL |
| `star_rating` | int \| null | Booking star rating (15). `null` is common — Booking renders stars inconsistently on listing cards |
| `review_score` | float \| null | Aggregate guest score on a 1.010.0 scale (e.g. `8.6`) |
| `review_count` | int \| null | Number of reviews backing the score |
| `price_amount` | float \| null | Final per-stay price as a plain number, in `price_currency` |
| `price_currency` | string \| null | ISO 4217 currency code. Pass `--currency USD` (or similar) to set Booking's `selected_currency` and force a stable output code |
| `distance` | string \| null | Distance-from-centre string (locale-formatted, e.g. `3.4 km from centre` / `离中心地区3.4千米`) |
| `recommended_room` | string \| null | Recommended room type + bed config + amenity/urgency hints, concatenated as Booking ships them |
| `url` | string | Canonical `https://www.booking.com/hotel/<country>/<slug>.html` |
`null` semantics: a `null` field means Booking did not expose that field for
this card (e.g. some listings have no star rating, no review count yet, or no
price displayed because dates are unavailable). Failures (page failed to
render, captcha challenge) raise typed errors instead of silently returning
empty rows.
## Validation (no silent clamp)
- `--checkin` / `--checkout` must be `YYYY-MM-DD`; checkout must be strictly after checkin.
- `--adults` `1..30`, `--rooms` `1..30`, `--children` `0..10` — out-of-range throws `ArgumentError` (no silent clamp).
- `--limit` `1..100`, `--offset` `0..1000` — out-of-range throws `ArgumentError`.
- `--lang` must be one of the supported Booking locales (e.g. `en-us`, `zh-cn`, `ja`, `ko`, `de`, `fr`, `es`); anything else throws `ArgumentError`.
- `--currency` must be a 3-letter ISO 4217 code (`USD`, `JPY`, `CNY`, …); symbols like `US$` throw `ArgumentError`.
## Locale handling
The URL path encodes the requested locale (`searchresults.<lang>.html`) and
`selected_currency` forces ISO 4217 price symbols. **But** bound browser
session cookies can still override hotel name strings to the user's preferred
language even when `--lang en-us` is set. The `slug`, `url`, `country`, and
numeric fields stay stable regardless — prefer `slug` (not `name`) as the
round-trip key. When `--currency` is provided and Booking renders a price,
the adapter reports that requested ISO code instead of guessing from ambiguous
symbols such as `$` or `¥`.
## Anti-bot
Booking serves a `/captcha` verification page after sustained scraping. The
adapter detects this via title / body text inspection and raises
`CommandExecutionError` instead of silently returning empty rows. If you hit
this, slow your call rate or change browser profile / IP.
## Notes
- Strategy: `Strategy.PUBLIC` + `browser: true`. No login required.
- Booking's search results are server-rendered HTML; the adapter scrapes
`[data-testid=property-card]` cards via `page.evaluate(EXTRACTOR)`. The
`[data-testid]` attributes are stable, but layout details change
occasionally.
- The score block renders score text duplicated as `8.68.6` (a11y + visual
copies); the extractor anchors on the first `(\d{1,2})\.(\d)` capture to
avoid mis-parsing `8.6` as `8.68`.
+28
View File
@@ -0,0 +1,28 @@
# BOSS Zhipin
**Mode**: 🔐 Browser · **Domain**: `zhipin.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli boss search` | |
| `opencli boss detail` | |
## Usage Examples
```bash
# Quick start
opencli boss search --limit 5
# JSON output
opencli boss search -f json
# Verbose mode
opencli boss search -v
```
## Prerequisites
- Chrome running and **logged into** zhipin.com
- [Browser Bridge extension](/guide/browser-bridge) installed
+47
View File
@@ -0,0 +1,47 @@
# Brave Search
**Mode**: 🌐 Public · **Domain**: `search.brave.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli brave search <keyword>` | Search Brave Search and extract results from the page |
## What works today
- Uses browser mode to search `search.brave.com` and extract ranked results via DOM queries.
- Supports `--offset` for GET-based pagination. Brave returns approximately 18 results per page.
- Results include rank, title, URL, and snippet.
- `--limit` must be between 1 and 18; `--offset` must be a non-negative page offset.
## Current limitations
- Requires browser mode. Brave Search does not offer a public, no-auth search API.
- DOM structure uses Svelte-generated class names that may change with updates.
- Some results may have empty snippets depending on Brave's layout.
## Usage Examples
```bash
# Basic search
opencli brave search "machine learning"
# Limit results
opencli brave search "machine learning" --limit 5
# Pagination (second page)
opencli brave search "machine learning" --offset 1
# JSON output
opencli brave search "machine learning" -f json
```
## Prerequisites
- Requires Chrome running (Standalone mode will auto-launch) or the [Browser Bridge extension](/guide/browser-bridge).
## Notes
- Brave Search renders results server-side; all results are present in the initial HTML (no lazy loading).
- Brave also shows an AI-generated summary box as the first result. The adapter filters this out via the `.standalone` class check.
+39
View File
@@ -0,0 +1,39 @@
# 超星学习通 (Chaoxing)
**Mode**: 🔐 Browser · **Domain**: `mooc2-ans.chaoxing.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli chaoxing assignments` | 学习通作业列表 |
| `opencli chaoxing exams` | 学习通考试列表 |
## Usage Examples
```bash
# List all assignments
opencli chaoxing assignments --limit 20
# Filter exams by course name
opencli chaoxing exams --course "高等数学"
# Filter exams by status
opencli chaoxing exams --status ongoing
# JSON output
opencli chaoxing assignments -f json
```
### Options
| Option | Description |
|--------|-------------|
| `--course` | Filter by course name (fuzzy match) |
| `--status` | Filter by status: `all`, `upcoming`, `ongoing`, `finished` |
| `--limit` | Max number of results (default: 20) |
## Prerequisites
- Chrome running and **logged into** mooc2-ans.chaoxing.com
- [Browser Bridge extension](/guide/browser-bridge) installed
+104
View File
@@ -0,0 +1,104 @@
# ChatGPT Web
**Mode**: 🔐 Browser · **Domain**: `chatgpt.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli chatgpt ask <prompt>` | Send a prompt and wait for the visible response |
| `opencli chatgpt send <prompt>` | Send a prompt without waiting |
| `opencli chatgpt read` | Read the current conversation |
| `opencli chatgpt history` | List visible conversation history links from the sidebar |
| `opencli chatgpt detail <id-or-url>` | Open a conversation by `/c/<id>` and read it |
| `opencli chatgpt deep-research-result <id-or-url>` | Read a completed Deep Research report from a conversation |
| `opencli chatgpt new` | Start a new conversation |
| `opencli chatgpt status` | Check page and login state |
| `opencli chatgpt image <prompt>` | Generate images in ChatGPT web and optionally save them locally |
| `opencli chatgpt model <level>` | Switch the ChatGPT web intelligence level |
## Usage Examples
```bash
# Ask and wait for the answer
opencli chatgpt ask "Summarize the tradeoffs of browser session reuse"
# Continue the same ChatGPT tab but do not wait for the answer
opencli chatgpt send "Now turn that into a checklist"
# Read the current conversation
opencli chatgpt read --markdown true
# List recent visible conversations and read one by id or URL
opencli chatgpt history --limit 10
opencli chatgpt detail "https://chatgpt.com/c/<conversation-id>"
# Extract a completed Deep Research report
opencli chatgpt deep-research-result "https://chatgpt.com/c/<conversation-id>" --wait true --timeout 600
# Start a fresh chat
opencli chatgpt new
# Generate an image and save it to the default directory
opencli chatgpt image "a cyberpunk city at night"
# Switch ChatGPT's intelligence level
opencli chatgpt model fast
opencli chatgpt model balanced
opencli chatgpt model advanced
opencli chatgpt model very-high
opencli chatgpt model pro
# Upload a local image, ask ChatGPT to edit it, and save the result
opencli chatgpt image "make the background blue" --image ./cat.png
# Upload multiple local images for a combined edit
opencli chatgpt image "combine these into a poster" --image ./cat.png,./logo.png
# Save to a custom output directory
opencli chatgpt image "a robot sketching on paper" --op ~/Downloads/chatgpt-images
# Only generate in ChatGPT and print the conversation link
opencli chatgpt image "a tiny watercolor fox" --sd true
```
## Options
| Option | Description |
|--------|-------------|
| `prompt` | Prompt to send (required for `ask`, `send`, and `image`) |
| `--timeout` | Max seconds for `ask` to wait for a response (default: `120`) |
| `--wait` | For `deep-research-result`, wait until a Deep Research report completes or becomes extractable |
| `--stable` | For `deep-research-result`, seconds the report text must remain unchanged when waiting (default: `6`) |
| `--new` | Start a new conversation before `ask` / `send` |
| `--markdown` | Convert assistant message HTML to Markdown for `read` / `detail` |
| `--limit` | Max visible history conversations to return (default: `20`) |
| `--image` | Local image path to attach before prompting; comma-separated paths are supported |
| `--op` | Output directory for downloaded images (default: `~/Pictures/chatgpt`) |
| `--sd` | Skip download and only print the ChatGPT conversation link |
| `model` | ChatGPT intelligence level for `model`: `fast`, `balanced`, `advanced`, `very-high`, or `pro`; aliases include `speed`/`instant`, `balance`/`medium`, `high`/`thinking`, `ultra`/`xhigh`/`x-high`/`extra-high`, `professional`, and the Chinese labels `极速`/`均衡`/`高级`/`超高`/`专业` |
## Behavior
- ChatGPT web commands use persistent site sessions by default, so consecutive `ask` / `send` / `read` / `detail` commands continue in the same ChatGPT tab. Use `--site-session ephemeral` for one-shot isolated tabs.
- `ask` waits for the first stable assistant response after sending. `send` submits only and returns immediately.
- `history` reads visible `/c/<id>` links from the ChatGPT sidebar; it does not use private backend APIs.
- `deep-research-result` opens the requested conversation and extracts completed Deep Research output from that conversation's `/backend-api/conversation/<id>` payload, especially `metadata.chatgpt_sdk.widget_state.report_message`. It does not return a success row when no completed report is present.
- `model` switches the visible ChatGPT web intelligence level. It recognizes the current English labels (`Fast`, `Balanced`, `Advanced`, `Very High`, `Pro`), legacy labels (`Instant`, `Medium`, `High`, `Extra High`), and Chinese labels (`极速`, `均衡`, `高级`, `超高`, `专业`). Advanced and Pro first try ChatGPT's authenticated backend model preference update, then the adapter falls back to the visible picker for UI-only levels. If labels are localized differently, it only falls back to option order after confirming the guarded five-option ChatGPT intelligence picker structure.
- `image` opens a fresh `chatgpt.com/new` page before sending the image prompt.
- When `--image` is provided, local images are uploaded first and the prompt is sent as an image edit request.
- `image` output is plain `status / file / link`, not a markdown table.
- When `--sd` is enabled, the command does not download files and only prints the ChatGPT link.
- Downloaded files are named with a timestamp to avoid overwriting prior runs.
## Prerequisites
- Chrome is running
- You are already logged into `chatgpt.com`
- [Browser Bridge extension](/guide/browser-bridge) is installed
## Caveats
- This adapter targets the ChatGPT web UI, not the macOS desktop app.
- It depends on the current browser session and can fail if ChatGPT shows login, challenge, quota, or other gating UI.
- DOM or product changes on ChatGPT can break composer detection, image detection, or export behavior.
+110
View File
@@ -0,0 +1,110 @@
# Chess.com
**Mode**: 🌐 Public · **Domain**: `api.chess.com` / `www.chess.com`
Read-only adapter against the public Chess.com endpoints. `stats`, `games`, `game` use no-auth REST; `analyze` opens the Chess.com analysis board in a bound browser session.
## Commands
| Command | Description |
|---------|-------------|
| `opencli chess stats <username>` | Player rating + win/loss/draw record across game kinds (rapid / blitz / bullet / daily / chess960) |
| `opencli chess games <username>` | Recent games newest-first across one or more monthly archives |
| `opencli chess game <game-url>` | Single-game detail (white, black, result, ECO, termination, ply count) by full game URL |
| `opencli chess analyze <game-url>` | Open the game in Chess.com's analysis board in the bound browser session |
## Usage Examples
```bash
# Stats
opencli chess stats hikaru
opencli chess stats magnuscarlsen -f json
# Recent games (default 10, max 100)
opencli chess games hikaru
opencli chess games erik --limit 25
# Single-game detail from a game URL
opencli chess game https://www.chess.com/game/live/168842570216
opencli chess game https://www.chess.com/game/daily/947761777
# Open in Chess.com analysis board (browser session required)
opencli chess analyze https://www.chess.com/game/live/168842570216
```
## Columns
### `stats`
| Column | Notes |
|--------|-------|
| `kind` | `rapid` / `blitz` / `bullet` / `daily` / `chess960_daily` (only kinds the player has played) |
| `rating_current` | Latest rating |
| `rating_best` | All-time best rating |
| `wins` / `losses` / `draws` | Cumulative record |
### `games`
| Column | Notes |
|--------|-------|
| `date` | Game end date in `YYYY-MM-DD` (UTC) |
| `time_class` | `rapid` / `blitz` / `bullet` / `daily` |
| `rated` | Boolean |
| `my_color` | `white` or `black` from the viewer's perspective |
| `my_rating` | Viewer's rating in this game |
| `my_result` | `win` / `resigned` / `timeout` / `checkmated` / `agreed` / `repetition` / etc |
| `opponent` | Opponent's Chess.com username |
| `opponent_rating` | Opponent's rating at game time |
| `accuracy_white` / `accuracy_black` | Chess.com move-accuracy percentage (0-100) when computed by Game Review; empty when the game wasn't analyzed (unrated / very short / abandoned) |
| `eco` | Raw ECO opening tag or full opening URL chess.com encodes on the row |
| `opening_name` | Human-readable opening name parsed from the eco URL (e.g. `Reti Opening Nimzo Larsen Variation`); empty when `eco` is the short-code form (`A01`) which carries no name |
| `url` | Game URL on chess.com |
## Username Validation
Usernames are normalized to lowercase and matched against `^[a-zA-Z0-9_-]{3,25}$`. Invalid inputs raise `ArgumentError` before any HTTP call.
## Archive Walk
`games` calls `/pub/player/<user>/games/archives` first to list every month the player has games in, then walks the list newest-first fetching one monthly archive at a time until `--limit` is filled. Capped at 6 monthly fetches per invocation so an obscure account with a long archive history doesn't fan out.
## Limit Validation
`--limit` accepts integers in `[1, 100]`. Out-of-range / non-integer values raise `ArgumentError` (no silent clamp).
### `game`
| Column | Notes |
|--------|-------|
| `kind` | `live` or `daily` parsed from the URL |
| `game_id` | Numeric id parsed from the URL |
| `date` | `YYYY-MM-DD` from PGN headers (end-time fallback) |
| `white` / `black` | Usernames; resolved from `players.{top,bottom}` keyed by `.color`, with `pgnHeaders.{White,Black}` fallback |
| `white_rating` / `black_rating` | Per-player rating at game time |
| `result` | PGN result token: `1-0`, `0-1`, `1/2-1/2` |
| `winner_color` | `white`, `black`, or empty on draw |
| `termination` | Human-readable reason (e.g. "Hikaru won by resignation") |
| `eco` | ECO opening code |
| `time_control` | Wire `TimeControl` header for live (`180` = 3 min), `<N>d/turn` for daily |
| `rated` | Boolean |
| `ply_count` | Half-move count |
| `url` | Canonical game URL |
### `analyze`
| Column | Notes |
|--------|-------|
| `kind` | `live` / `daily` parsed from the URL |
| `game_id` | Numeric id parsed from the URL |
| `analysis_url` | Resolved `/analysis/game/<kind>/<id>` URL the bound browser session navigated to |
## Endpoint Notes
`game` uses `/callback/{live\|daily}/game/{id}` on `www.chess.com` (the same JSON the Chess.com web client hits when rendering a game page). The public REST surface at `api.chess.com/pub` has no single-game endpoint; the callback path is the cleanest way to honour "PGN for specific game" without DOM scraping.
`analyze` is a thin wrapper around `page.goto('/analysis/game/<kind>/<id>')`. Requires a bound browser session; if you only need to open a URL, `opencli browser <session> open <url>` is the more general primitive.
## Out of Scope
- Live game tracking (live moves streaming): outside the public REST surface.
- Move-by-move engine evaluation: separate concern, would belong in a future `chess engine` adapter.
+69
View File
@@ -0,0 +1,69 @@
# Claude
**Mode**: Browser · **Domain**: `claude.ai`
## Commands
| Command | Description |
|---------|-------------|
| `opencli claude ask <prompt>` | Send a prompt and get the response |
| `opencli claude send <prompt>` | Send a prompt without waiting for the response |
| `opencli claude new` | Start a new conversation |
| `opencli claude status` | Check login state and page availability |
| `opencli claude read` | Read the current conversation |
| `opencli claude history` | List recent conversations from `/recents` |
| `opencli claude detail <id>` | Open a conversation by ID and read its messages |
## Usage Examples
```bash
# Ask a question
opencli claude ask "explain quicksort in 3 sentences"
# Start a new chat before asking
opencli claude ask "hello" --new
# Pick the model (default: sonnet; opus is paid-tier)
opencli claude ask "quick summary" --model haiku
# Enable Adaptive thinking
opencli claude ask "prove that sqrt(2) is irrational" --think
# Attach a file (image / PDF / text, up to ~1 MB raw)
opencli claude ask "describe this image" --file ./photo.png
# Combine modes
opencli claude ask "what does this PDF cover?" --file ./paper.pdf --think --new
# Custom timeout (default: 120s)
opencli claude ask "write a long essay" --timeout 240
# JSON output
opencli claude ask "hello" -f json
```
### Options (ask)
| Option | Description |
|--------|-------------|
| `<prompt>` | The message to send (required, positional) |
| `--timeout` | Wait timeout in seconds (default: 120) |
| `--new` | Start a new chat before sending (default: false) |
| `--model` | Model to use: `sonnet`, `opus`, or `haiku` (default: sonnet) |
| `--think` | Enable Adaptive thinking (default: false) |
| `--file` | Attach a file (image, PDF, text) with the prompt |
## Prerequisites
- Chrome running with [Browser Bridge extension](/guide/browser-bridge) installed
- Logged in to [claude.ai](https://claude.ai)
## Caveats
- This adapter drives the Claude web UI in the browser, not an API
- Claude commands default to persistent site sessions, so consecutive `claude ask` / `claude read` / `claude detail` invocations continue in the same Claude page. Pass `--site-session ephemeral` for a one-shot tab.
- `--model opus` requires a paid Claude plan; on a free-tier account the adapter surfaces a usage error rather than silently falling back
- The default Sonnet 4.6 model uses Adaptive thinking by default; `--think` is the explicit switch but Claude may still invoke thinking for complex prompts even when not requested
- Adaptive-thinking and file-thumbnail widgets render duplicated label paragraphs (`Thought process` / `View uploaded image`) at the top of the response; these are stripped automatically so the row value is the actual answer
- File upload is constrained by the daemon HTTP body limit (1 MB; `src/daemon.ts:152`); files up to ~700 KB raw work reliably, larger files (e.g. high-res images) may fail with `ECONNRESET`
- Long responses (code, essays) may need a higher `--timeout`
+24
View File
@@ -0,0 +1,24 @@
# CNKI
**Mode**: 🔐 Browser · **Domain**: `oversea.cnki.net`
## Commands
| Command | Description |
|---------|-------------|
| `opencli cnki search <query>` | Search CNKI Overseas papers by keyword |
## Usage Examples
```bash
# Search CNKI papers
opencli cnki search "large language model"
# Limit returned results
opencli cnki search "retrieval augmented generation" --limit 5
```
## Prerequisites
- Chrome running
- [Browser Bridge extension](/guide/browser-bridge) installed
+126
View File
@@ -0,0 +1,126 @@
# CoinGecko
Access **CoinGecko** crypto market data from the terminal via the public API (no authentication required).
**Mode**: 🌐 Public · **Domain**: `api.coingecko.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli coingecko top` | Top coins by market cap |
| `opencli coingecko coin <id>` | Single coin's market detail (price / supply / ATH / homepage) |
| `opencli coingecko trending` | Top trending coins on CoinGecko in the last 24h |
| `opencli coingecko exchanges` | Top exchanges ranked by trust score / 24h BTC volume |
| `opencli coingecko categories` | Crypto sector categories (DeFi / Layer1 / Memes / …) with market cap |
| `opencli coingecko derivatives` | Top crypto derivative (perpetual / futures) markets by 24h volume |
| `opencli coingecko global` | Aggregate market totals: total cap, volume, BTC/ETH dominance |
## Usage Examples
```bash
# Top 10 coins in USD (default)
opencli coingecko top
# Top 5 coins priced in CNY
opencli coingecko top --currency cny --limit 5
# Top 50 coins in EUR
opencli coingecko top --currency eur --limit 50
# Single coin detail (slug from `top` or coingecko URL)
opencli coingecko coin bitcoin
opencli coingecko coin ethereum --currency cny
# Trending in the last 24h (search-volume based)
opencli coingecko trending
# Top exchanges (trust score, 24h BTC volume)
opencli coingecko exchanges --limit 20
# Crypto sector categories (default sort: market_cap_desc)
opencli coingecko categories --limit 10
opencli coingecko categories --sort market_cap_change_24h_desc --limit 10
# Top derivative tickers (perpetuals + futures, sorted by 24h USD volume)
opencli coingecko derivatives --limit 20
# Filter derivatives by symbol substring (BTC pairs only)
opencli coingecko derivatives --symbol BTC --limit 10
# Aggregate market totals (BTC dominance, total cap, etc.)
opencli coingecko global
opencli coingecko global --currency cny
# JSON output
opencli coingecko top -f json
```
## Options
### `top`
| Option | Description |
|--------|-------------|
| `--currency` | Quote currency (`usd` / `cny` / `eur` / `jpy` / etc., default: `usd`) |
| `--limit` | Number of coins to return (1250, default: 10) |
### `coin`
| Option | Description |
|--------|-------------|
| `id` (positional) | CoinGecko coin slug (lowercase, e.g. `bitcoin`, `ethereum`, `solana`) |
| `--currency` | Quote currency (default: `usd`) |
### `trending`
No arguments — returns the current top-7 trending list.
### `exchanges`
| Option | Description |
|--------|-------------|
| `--limit` | Number of exchanges to return (1250, default: 20) |
### `categories`
| Option | Description |
|--------|-------------|
| `--sort` | One of `market_cap_desc` (default), `market_cap_asc`, `name_desc`, `name_asc`, `market_cap_change_24h_desc`, `market_cap_change_24h_asc` |
| `--limit` | Number of categories to return (1100, default: 20) |
### `derivatives`
| Option | Description |
|--------|-------------|
| `--limit` | Max rows to return (1500, default: 20) |
| `--symbol` | Optional symbol substring filter (e.g. `BTC`, `ETHUSDT`) — also matches the `index_id` field |
### `global`
| Option | Description |
|--------|-------------|
| `--currency` | Quote currency for total market cap / volume (default: `usd`) |
## Output Columns
| Command | Columns |
|---------|---------|
| `top` | `rank, symbol, name, price, change24hPct, marketCap, volume24h, high24h, low24h` |
| `coin` | `id, symbol, name, rank, price, marketCap, volume24h, change24hPct, change7dPct, change30dPct, ath, athDate, atl, atlDate, circulatingSupply, totalSupply, maxSupply, genesisDate, homepage` |
| `trending` | `rank, id, symbol, name, marketCapRank, priceBtc, thumb` |
| `exchanges` | `rank, id, name, trustScore, volume24hBtc, country, yearEstablished, url` |
| `categories` | `rank, id, name, marketCap, volume24h, marketCapChange24hPct, top3Coins` |
| `derivatives` | `rank, market, symbol, indexId, contractType, price, change24hPct, fundingRate, openInterestUsd, volume24hUsd, expired` |
| `global` | `currency, totalMarketCap, totalVolume24h, marketCapChange24hPct, btcDominancePct, ethDominancePct, activeCryptocurrencies, markets, ongoingIcos, updatedAt` |
## Prerequisites
- No browser required — uses CoinGecko's public market-data endpoint
## Notes
- The public endpoint is rate-limited; retry briefly if you hit transient `HTTP 429` responses
- All numeric values are denominated in the selected `--currency`; `coin` fails fast if CoinGecko returns no market fields for that currency
- `change24hPct` is a raw percent (e.g. `2.34` means `+2.34%`), not a fraction
- `--limit` is validated upfront and rejected with `ArgumentError` if non-positive or above 250 (the CoinGecko `per_page` upper bound) — no silent clamp
+75
View File
@@ -0,0 +1,75 @@
# Confluence
**Mode**: 🔑 Atlassian REST API · **Domain**: configured with `ATLASSIAN_CONFLUENCE_BASE_URL`
Read, search, create, and update Confluence pages through Atlassian REST APIs. The adapter supports Confluence Cloud and Confluence Data Center without driving a browser session.
## Commands
| Command | Description |
|---------|-------------|
| `opencli confluence page <PAGE_ID>` | Page detail with storage and Markdown body |
| `opencli confluence search <CQL>` | Search content with CQL |
| `opencli confluence create` | Create a page from Markdown or storage XHTML |
| `opencli confluence update <PAGE_ID>` | Update a page body from Markdown or storage XHTML |
## Configuration
```bash
export ATLASSIAN_CONFLUENCE_BASE_URL=https://example.atlassian.net/wiki
export ATLASSIAN_DEPLOYMENT=cloud # cloud | datacenter | auto
export ATLASSIAN_EMAIL=you@example.com
export ATLASSIAN_API_TOKEN=...
```
For Data Center, use a personal access token when available:
```bash
export ATLASSIAN_CONFLUENCE_BASE_URL=https://confluence.example.com
export ATLASSIAN_DEPLOYMENT=datacenter
export ATLASSIAN_PAT=...
```
Cloud page reads and writes use Confluence REST API v2. CQL search is still exposed through Confluence REST API v1, so `search` intentionally uses the v1 search endpoint for both Cloud and Data Center.
## Usage Examples
```bash
# Read a page
opencli confluence page 123456 -f json
# Search pages in a space
opencli confluence search "type = page and title ~ \"RCA\"" --space ENG --limit 20 -f json
# Create a page from Markdown
opencli confluence create --space 987654 --title "PROJ-123 RCA" --file rca.md --execute
# Update an existing page
opencli confluence update 123456 --file rca.md --version-message "Sync from Jira PROJ-123" --execute
```
## Write Safety
`create` and `update` require `--execute`. Without it, the adapter fails before sending a remote write.
For Cloud, `--space` expects a space id. For Data Center, `--space` expects a space key. `--parent` can be used to place a new page under an existing page id.
## Input Formats
Markdown is the default input format:
```bash
opencli confluence create --space 987654 --title "Runbook" --file runbook.md --execute
```
To provide Confluence storage XHTML directly:
```bash
opencli confluence update 123456 --file page.storage.html --representation storage --execute
```
## Notes
- `update` reads the current page version first and submits `version.number + 1`.
- Markdown conversion covers headings, paragraphs, links, inline code, code blocks, flat and nested lists, and basic tables.
- Expected auth, rate-limit, version-conflict, argument, and not-found failures are normalized to `CliError` subclasses.
+106
View File
@@ -0,0 +1,106 @@
# Coupang
**Mode**: 🔐 Browser · **Domain**: `coupang.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli coupang search` | Search Coupang products with logged-in browser session |
| `opencli coupang product` | Read full product detail (price, rating, seller, delivery) for a product ID |
| `opencli coupang add-to-cart` | Add a product to the logged-in account's shopping cart |
## Usage Examples
```bash
# List rocket-shipping mice (rank, product_id, title, price, rating, ...)
opencli coupang search "마우스" --filter rocket --limit 10
# Round-trip: pick a product_id from search and pull full detail
opencli coupang product 7654321
# Pass a full product URL instead of an ID
opencli coupang product --url https://www.coupang.com/vp/products/7654321
# JSON output (any subcommand)
opencli coupang product 7654321 -f json
# Add to cart (write — must be logged in)
opencli coupang add-to-cart 7654321
```
## Output
### `search`
| Column | Type | Notes |
|--------|------|-------|
| `rank` | int | 1-based position within this query / page |
| `product_id` | string | Numeric Coupang product id; round-trips into `coupang product` |
| `title` | string | Product display name |
| `price` | int \| null | Current selling price (KRW) |
| `unit_price` | string | Per-unit price label, e.g. `(100ml당 1,200원)` |
| `rating` | float \| null | Average star rating |
| `review_count` | int \| null | Number of reviews |
| `rocket` | string | Coupang-rocket badge label (`로켓배송` / `로켓와우` / etc.) — empty string if no badge |
| `delivery_type` | string | `무료배송` / `일반배송` / empty |
| `delivery_promise` | string | `오늘도착` / `내일도착` / `새벽도착` / empty |
| `url` | string | Canonical product URL |
### `product`
Always returns a single row (or throws):
| Column | Type | Notes |
|--------|------|-------|
| `product_id` | string | Numeric Coupang product id, normalised from input |
| `title` | string \| null | Product display name; `null` if upstream did not provide |
| `price` | int \| null | Current selling price (KRW) |
| `original_price` | int \| null | Pre-discount price |
| `discount_rate` | int \| null | Discount percent |
| `rating` | float \| null | Average star rating |
| `review_count` | int \| null | Number of reviews |
| `seller` | string \| null | Vendor / seller name |
| `brand` | string \| null | Brand label (when listed) |
| `rocket` | string \| null | Coupang-rocket type label |
| `delivery_promise` | string \| null | Arrival-window label |
| `image_url` | string \| null | Primary product image |
| `url` | string | Canonical product URL |
`null` semantics: a `null` field means upstream did not expose that field on
this product (e.g. some items have no `original_price`). Failures (login wall,
page mismatch, page failed to render) raise typed errors instead of silently
returning empty rows — callers should treat any returned row as real data.
### `add-to-cart`
| Column | Type | Notes |
|--------|------|-------|
| `ok` | bool | Always `true` on success (failures throw) |
| `product_id` | string | Coupang product id added |
| `url` | string | Canonical product URL |
| `message` | string | `Added to cart` |
## Validation (no silent clamp)
`search --limit` must be `1..50`; out-of-range values throw `ArgumentError`
(no silent clamp to 50). `search --page` must be a positive integer. `search
--filter` currently only accepts `rocket`; any other value throws
`ArgumentError` rather than being silently dropped during DOM lookup.
## Prerequisites
- Chrome running and **logged into** coupang.com
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- `search` and `product` use the logged-in browser session because Coupang's
`/np/search` JSON endpoint and product pages serve different (and often
empty) responses to anonymous traffic.
- `product`'s extractor tries three sources in order: JSON-LD Product schema,
`window.__INITIAL_STATE__` / `__NEXT_DATA__` bootstrap globals, and finally
a DOM fallback. The merged result is what's returned.
- Authentication failures raise `AuthRequiredError`; missing/empty results
raise `EmptyResultError` with a helpful hint. No command silently returns
`[]` when login is the actual reason.
+62
View File
@@ -0,0 +1,62 @@
# crates.io
**Mode**: 🌐 Public · **Domain**: `crates.io`
Search and inspect crates on the public Rust crate registry. Both commands hit the unauthenticated `crates.io/api/v1` directly.
## Commands
| Command | Description |
|---------|-------------|
| `opencli crates search <query>` | Search the public crates.io registry by keyword |
| `opencli crates crate <name>` | Single crate metadata (latest version, downloads, license, repo) |
## Usage Examples
```bash
# Free-text search (name / keywords / description)
opencli crates search tokio --limit 10
opencli crates search "async runtime" --limit 20
# Single-crate detail (name from search rows)
opencli crates crate serde
opencli crates crate tokio
# JSON output
opencli crates search tokio -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, name, latestVersion, description, downloads, recentDownloads, repository, updated, url` |
| `crate` | `name, latestVersion, description, downloads, recentDownloads, versions, license, homepage, documentation, repository, keywords, categories, created, updated, url` |
The `name` column from `search` round-trips into `crate`.
## Options
### `search`
| Option | Description |
|--------|-------------|
| `query` (positional) | Free-text search query |
| `--limit` | Max results (1100, default: 20). 100 is crates.io's per-page upper bound. |
### `crate`
| Option | Description |
|--------|-------------|
| `name` (positional) | crates.io crate name (e.g. `serde`, `tokio`). Must match Rust's identifier rule. |
## Caveats
- crates.io requires a descriptive `User-Agent` per [the data-access policy](https://crates.io/data-access). The adapter sets one automatically.
- `license` is sourced from the **latest version row** in the package's version index — crate-level metadata does not carry a license field.
- `recentDownloads` is the rolling 90-day count exposed by the API; `downloads` is the lifetime total.
- `keywords` and `categories` are joined with `, ` for display.
## Prerequisites
- No browser required — uses `crates.io/api/v1`.
+123
View File
@@ -0,0 +1,123 @@
# Ctrip (携程)
**Mode**: 🌐 Public (`search`, `hotel-suggest`) · 🖥️ Browser + Cookie (`hotel-search`, `flight`)
**Domain**: `ctrip.com`
Public destination + hotel-context suggestion lookup against the
`m.ctrip.com/restapi/soa2/21881/json/gaHotelSearchEngine` endpoint plus
browser-driven hotel listing and one-way flight search on `hotels.ctrip.com`
and `flights.ctrip.com`.
## Commands
| Command | Mode | Description |
|---------|------|-------------|
| `opencli ctrip search` | Public | Suggest cities, scenic spots, railway stations and landmarks |
| `opencli ctrip hotel-suggest` | Public | Suggest cities, business areas and individual hotels |
| `opencli ctrip hotel-search` | Browser (cookie) | List hotels for a city + check-in/out date range |
| `opencli ctrip flight` | Browser (cookie) | One-way flight search by IATA route + departure date |
## Usage Examples
```bash
# Destination suggest
opencli ctrip search 苏州 --limit 10
# Hotel-context suggest (cities / business areas / hotels)
opencli ctrip hotel-suggest 陆家嘴 --limit 5
# Hotel listing (city ID from `search` / `hotel-suggest`)
opencli ctrip hotel-search 2 --checkin 2026-05-20 --checkout 2026-05-21 --limit 10
# One-way flight search
opencli ctrip flight BJS SHA --date 2026-05-20 --limit 20
# JSON output
opencli ctrip search 上海 -f json
```
## Suggest Columns (`search` / `hotel-suggest`)
Both suggest commands share a uniform column shape:
| Column | Notes |
|--------|-------|
| `rank` | 1-based position in the upstream list |
| `id` | Upstream entity id (round-trips into URL) |
| `type` | Raw type tag (`City` / `Markland` / `Hotel` / `BusinessArea` / `RailwayStation`) |
| `displayType` | Localised label (城市 / 地标 / 酒店 / 商圈 / 火车站) |
| `name` | Localised display name |
| `eName` | English name (may be empty) |
| `cityId`, `cityName`, `provinceName`, `countryName` | Geo context |
| `lat`, `lon` | Best-available coords (gaode → google → flat → null) |
| `score` | First non-zero of `commentScore` / `cStar`; `null` if both unrated |
| `url` | Canonical Ctrip URL or `null` if the entity type has no public web page |
`--limit` accepts integers in `[1, 50]`. Out-of-range values raise
`ArgumentError` (no silent clamp).
## Hotel Listing Columns (`hotel-search`)
| Column | Notes |
|--------|-------|
| `rank` | 1-based position in upstream list |
| `hotelId` | Round-trips into `https://hotels.ctrip.com/hotels/detail/?hotelid=…` |
| `name`, `enName` | Localised + English (English may be `null`) |
| `star` | `1`-`5`, `null` for unrated / 客栈 entries |
| `score`, `scoreLabel` | e.g. `4.8` / `"超棒"`; both `null` if unrated |
| `reviewCount` | Integer parsed from `"13,966条点评"` |
| `cityName`, `district`, `address` | Geo context |
| `lat`, `lon` | WGS84 (1) > GCJ02 (2) > BD09 (3) selection; `null` if all are 0 |
| `price`, `currency` | First room's quote; `null` when no rooms remain at the searched date |
| `url` | Canonical detail URL or `null` if `hotelId` is missing |
Args:
- `<city>` (positional, required) — numeric Ctrip city ID (discover via `ctrip search` / `ctrip hotel-suggest`).
- `--checkin`, `--checkout` (required) — `YYYY-MM-DD`, validated as real calendar dates with `checkin < checkout`.
- `--limit` (1-30, default 10) — Ctrip's SSR first page ships ~13 entries (10 organic + ~3 promoted). Larger limits are not currently supported because the server ignores the URL `pageSize` param.
## Flight Columns (`flight`)
| Column | Notes |
|--------|-------|
| `rank` | 1-based position after filtering incomplete rows |
| `airline`, `flightNo`, `aircraft` | Free-text from the rendered card; `aircraft` may be `null` |
| `departureTime`, `arrivalTime` | `HH:MM` strings |
| `departureAirport`, `arrivalAirport`, `terminal` | Airport names + optional `T1`/`T2` chunk |
| `price`, `currency`, `cabin` | First quoted fare; `cabin` is the Chinese suffix (e.g. `经济舱`) |
| `url` | The search URL (Ctrip's flight cards don't expose per-row stable deeplinks) |
Args:
- `<from>`, `<to>` (positional, required) — 3-letter IATA codes; `BJS`/`SHA` metro codes work alongside single-airport codes like `PEK`/`PVG`.
- `--date` (required) — `YYYY-MM-DD`.
- `--limit` (1-50, default 20).
Rows are extracted from `.flight-list > span > div` cards because Ctrip's
post-load XHR is not currently captured by the daemon network buffer (see
"Caveats" below). Cards with missing departure/arrival/airline are dropped
rather than emitted with sentinel values.
## Notes
- Suggest endpoint discriminator: `searchType=D` (search) vs `searchType=H`
(hotel-suggest). Hotel and BusinessArea rows only appear in the `H` flavour.
- Mainland China suggest rows ship `gdLat`/`gdLon` (gaode). International rows
ship `gLat`/`gLon` (wgs84). The adapter picks the first non-zero pair.
- Suggest in-band `Result: false` envelopes are surfaced as `COMMAND_EXEC`
typed errors; HTTP non-2xx becomes `FETCH_ERROR`.
## Caveats (browser-mode commands)
- **Cookie required**: `hotel-search` / `flight` use `Strategy.COOKIE` against
`hotels.ctrip.com` / `flights.ctrip.com`. If Ctrip serves a captcha redirect
(suspected bot), an `AuthRequiredError` is raised — complete the captcha in
your live browser session and retry.
- **No per-flight deeplink**: Ctrip's flight cards funnel every row through a
shared booking handoff. Until a stable per-flight `bookingId` surfaces, all
rows share the search URL.
- **Round-trip + airline-filter unsupported**: `flight` is one-way only and
passes `cabin=Y_S_C_F` (all cabins) in v1. Round-trip + advanced filters
tracked in the `#1481` follow-up.
- **Hotel SSR page size is server-fixed**: passing `&pageSize=N` is ignored
upstream — first page returns ~13 rows. Larger result sets would need
scroll-paginated DOM extraction (not implemented in v1).
+87
View File
@@ -0,0 +1,87 @@
# dblp
**Mode**: 🌐 Public · **Domain**: `dblp.org`
[dblp](https://dblp.org) is the comprehensive computer-science bibliography maintained by Schloss Dagstuhl, indexing 7M+ publications across conferences, journals, books, and theses. Both commands hit the public API directly — no auth, no browser.
## Commands
| Command | Description |
|---------|-------------|
| `opencli dblp search <query>` | Free-text search across titles, authors, and venues |
| `opencli dblp author <name>` | List one author's recent publications (newest first) by name or `--pid` |
| `opencli dblp paper <key>` | Fetch a single record's full metadata by canonical dblp key |
| `opencli dblp venue <query>` | Search dblp's venue (conference / journal) registry |
## Usage Examples
```bash
# Free-text search (matches title / author / venue)
opencli dblp search "attention is all you need" --limit 5
# Author search
opencli dblp search "Yoshua Bengio" --limit 20
# Newest publications by a specific author (resolves the dblp PID for you)
opencli dblp author "Yoshua Bengio" --limit 20
# Same call, but skip name resolution by supplying the PID directly
opencli dblp author --pid 56/953 --limit 20
# Venue search
opencli dblp search "ICLR 2024" --limit 30
# Single-record detail (round-trip from search.key)
opencli dblp paper conf/nips/VaswaniSPUJGKP17
# arXiv mirror records use the journals/corr/abs-* form
opencli dblp paper journals/corr/abs-2509-05821
# Resolve a venue acronym to dblp's canonical venue page
opencli dblp venue ICLR --limit 5
# Browse venues that match a topic keyword
opencli dblp venue "neural networks" --limit 10
# JSON output
opencli dblp search "graph neural network" -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, key, title, authors, venue, year, type, doi, url` |
| `author` | `rank, key, title, authors, venue, year, type, doi, pid, url` |
| `paper` | `key, type, title, authors, venue, year, pages, doi, open_access_url, dblp_url` |
| `venue` | `rank, acronym, venue, type, url` |
The `key` column from `search` and `author` round-trips into `paper` — it is dblp's canonical record identifier (e.g. `conf/nips/VaswaniSPUJGKP17`, `journals/corr/abs-2509-05821`, `phd/Smith20`).
The `pid` column on `author` is dblp's stable per-author identifier (e.g. `56/953` for Yoshua Bengio). Pass it back with `--pid` to skip name resolution on subsequent calls.
## Type Tag
The `type` column is a single-token simplification of dblp's verbose type strings:
| Tag | Source |
|-----|--------|
| `conf` | Conference and Workshop Papers (`<inproceedings>`) |
| `journal` | Journal Articles (`<article>`) |
| `book` | Books and Theses |
| `editorship` | Proceedings volumes |
| `reference` | Reference Works |
| `preprint` | Informal / Other Publications (CoRR, etc.) |
| `incollection` / `phdthesis` / `mastersthesis` | (paper command only — kept distinct in the XML record) |
## Caveats
- dblp does **not** expose abstracts via either endpoint. For the abstract, follow `open_access_url` (when present), `doi`, or pipe the title into `arxiv search` / `openreview search`.
- Author names occasionally carry dblp's per-author homonym suffix (`"Smith 0001"`). The adapter strips trailing 4+ digit groups so you get clean `Author, Author` strings.
- Search results include CoRR / arXiv mirror entries. These have keys like `journals/corr/abs-2509-05821` and round-trip cleanly into `paper`.
- dblp throttles aggressive clients. If you hit HTTP 429, wait a few seconds and lower `--limit` (max 100 per page).
## Prerequisites
- No browser required — uses the public dblp API at `https://dblp.org`.
- The adapter sets a polite `User-Agent` per [dblp's API guidance](https://dblp.org/faq/How+to+use+the+dblp+search+API.html).
+107
View File
@@ -0,0 +1,107 @@
# DeepSeek
**Mode**: Browser · **Domain**: `chat.deepseek.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli deepseek ask <prompt>` | Send a prompt and get the response |
| `opencli deepseek new` | Start a new conversation |
| `opencli deepseek status` | Check login state and page availability |
| `opencli deepseek read` | Read the current conversation |
| `opencli deepseek history` | List conversation history from sidebar |
| `opencli deepseek detail <id>` | Read a specific conversation by ID or URL |
| `opencli deepseek send <id> <prompt>` | Send a prompt to a specific conversation without waiting for a response |
## Usage Examples
```bash
# Ask a question
opencli deepseek ask "explain quicksort in 3 sentences"
# Start a new chat before asking
opencli deepseek ask "hello" --new
# Use Expert model instead of Instant
opencli deepseek ask "prove that sqrt(2) is irrational" --model expert
# Use Vision model with an image
opencli deepseek ask "describe this image" --model vision --file ./image.png
# Enable DeepThink mode
opencli deepseek ask "prove that sqrt(2) is irrational" --think
# Enable web search
opencli deepseek ask "latest news about AI" --search
# Attach a file
opencli deepseek ask "summarize this document" --file ./report.pdf
# Combine modes
opencli deepseek ask "what happened today?" --model expert --think --search --new
# Custom timeout (default: 120s)
opencli deepseek ask "write a long essay" --timeout 180
# JSON output
opencli deepseek ask "hello" -f json
# Check login status
opencli deepseek status
# Start a fresh conversation
opencli deepseek new
# Read current conversation
opencli deepseek read
# List recent conversations
opencli deepseek history --limit 10
# Read a specific conversation by UUID or /a/chat/s/<id> URL
opencli deepseek detail 749e6bbd-6a45-4440-beaa-ae5238bf06d8
# Send to a specific existing conversation
opencli deepseek send 749e6bbd-6a45-4440-beaa-ae5238bf06d8 "continue from the last answer"
```
### Options (ask)
| Option | Description |
|--------|-------------|
| `<prompt>` | The message to send (required, positional) |
| `--timeout` | Wait timeout in seconds (default: 120) |
| `--new` | Start a new chat before sending (default: false) |
| `--model` | Model to use: `instant`, `expert`, or `vision` (default: instant) |
| `--think` | Enable DeepThink mode (default: false) |
| `--search` | Enable web search (default: false) |
| `--file` | Attach a file (PDF, image, text) with the prompt (max 100 MB) |
### Options (detail)
| Option | Description |
|--------|-------------|
| `<id>` | DeepSeek conversation UUID or full `/a/chat/s/<id>` URL |
### Options (send)
| Option | Description |
|--------|-------------|
| `<id>` | DeepSeek conversation UUID or full `/a/chat/s/<id>` URL |
| `<prompt>` | The message to send (required, positional) |
## Prerequisites
- Chrome running with [Browser Bridge extension](/guide/browser-bridge) installed
- Logged in to [chat.deepseek.com](https://chat.deepseek.com)
## Caveats
- This adapter drives the DeepSeek web UI in the browser, not an API
- DeepSeek commands default to persistent site sessions, so consecutive `deepseek ask` / `deepseek read` / `deepseek detail` invocations continue in the same DeepSeek page. Pass `--site-session ephemeral` for a one-shot tab.
- Default mode is Instant with DeepThink and Search disabled; each flag (`--model`, `--think`, `--search`) is synced on every invocation so omitting a flag resets it
- Vision mode does not support `--search`; use `--model instant` or `--model expert` for web search
- `send` requires an explicit conversation ID; use `history` to find a conversation URL or ID first
- Long responses (code, essays) may need a higher `--timeout`
- File upload prefers the browser file-input path, falls back to base64 injection when needed, and rejects files over 100 MB
+60
View File
@@ -0,0 +1,60 @@
# DefiLlama
**Mode**: 🌐 Public · **Domain**: `defillama.com`
Browse top DeFi protocols by TVL and fetch detailed protocol metadata. Both commands hit the unauthenticated `api.llama.fi` directly.
## Commands
| Command | Description |
|---------|-------------|
| `opencli defillama protocols` | Top DeFi protocols by current TVL (slug, name, category, TVL, mcap, change, chains) |
| `opencli defillama protocol <slug>` | Single protocol details (current TVL, mcap, chains, twitter, github, description) |
## Usage Examples
```bash
# Top 30 protocols by TVL (default)
opencli defillama protocols
# Top 100, JSON output
opencli defillama protocols --limit 100 -f json
# Single protocol details (slug from protocols rows)
opencli defillama protocol aave-v3
opencli defillama protocol lido
# Parent protocols (e.g. "aave") aggregate their children's chains
opencli defillama protocol aave
```
## Output Columns
| Command | Columns |
|---------|---------|
| `protocols` | `rank, slug, name, category, tvl, mcap, change_1d, change_7d, chains, listedAt, url` |
| `protocol` | `slug, name, category, isParent, tvl, tvlAt, mcap, chains, twitter, github, audits, listedAt, description, website, url` |
The `slug` column from `protocols` round-trips into `protocol`.
## Options
### `protocols`
| Option | Description |
|--------|-------------|
| `--limit` | Number of rows to return (1500, default: 30). DefiLlama lists ~7400 protocols total. |
### `protocol`
| Option | Description |
|--------|-------------|
| `slug` (positional) | DefiLlama protocol slug (e.g. `aave-v3`, `lido`, `pancakeswap-amm`) |
## Notes
- **TVL is in USD.** `tvl` and `mcap` are scalar floats; consumers should format as money.
- **Parent vs child protocols.** "Parent" entries (`isParent=true`, e.g. `aave` covers `aave-v3`, `aave-v2`, etc.) are present on `protocol` but not on `protocols`. The adapter aggregates child chains so parents still surface a useful `chains` value.
- **`change_1d` / `change_7d` are percentages** (already as percent, e.g. `0.84` = +0.84%).
- **No API key required.** DefiLlama throttles unauthenticated traffic; an `HTTP 429` surfaces as `CommandExecutionError`.
- **Errors.** Bad slug → `ArgumentError`; unknown slug → `EmptyResultError` (DefiLlama returns `HTTP 400 "Protocol not found"` which is normalised); other 4xx/5xx → `CommandExecutionError`.
+81
View File
@@ -0,0 +1,81 @@
# Dev.to
**Mode**: 🌐 Public · **Domain**: `dev.to`
Fetch the latest and greatest developer articles from the DEV community without needing an API key.
## Commands
| Command | Description |
|---------|-------------|
| `opencli devto top` | Top DEV.to articles of the day |
| `opencli devto latest` | Latest published articles across all tags (paginated) |
| `opencli devto tag <tag>` | Latest articles for a specific tag |
| `opencli devto user <username>` | Recent articles from a specific user |
| `opencli devto read <id>` | Read the body of a single article |
## Listing columns
`top`, `latest`, `tag`, and `user` all surface the same agent-native columns so the
article id is round-trippable into `devto read`:
| Column | Source | Notes |
|--------|--------|-------|
| `rank` | local | 1-indexed position in the result |
| `id` | `item.id` | Numeric article id, feed into `devto read` |
| `title` | `item.title` | |
| `author` | `item.user.username` | (omitted for `user` since it's user-scoped) |
| `reactions` | `item.public_reactions_count` | |
| `comments` | `item.comments_count` | |
| `reading_time` | `item.reading_time_minutes` | Minutes |
| `published_at` | `item.published_at` | ISO 8601 timestamp |
| `tags` | `item.tag_list` | Comma-separated |
| `url` | `item.url` | Canonical article URL |
## `read` columns
`devto read` returns a single row with the article body. DEV.to's public API
does not expose article comments, so this reader does not emit a comment tree.
| Column | Source |
|--------|--------|
| `id` | `article.id` |
| `title` | `article.title` |
| `author` | `article.user.username` |
| `reactions` | `article.public_reactions_count` |
| `reading_time` | `article.reading_time_minutes` |
| `tags` | `article.tag_list` (joined) |
| `published_at` | `article.published_at` |
| `body` | `article.body_markdown` (truncated by `--max-length`) |
| `url` | `article.url` |
## Usage Examples
```bash
# Top articles today
opencli devto top --limit 5
# Latest published articles (newest first; supports --page for pagination)
opencli devto latest --limit 20
opencli devto latest --limit 20 --page 2
# Articles by tag (positional argument)
opencli devto tag javascript
opencli devto tag python --limit 20
# Articles by a specific author
opencli devto user ben
opencli devto user thepracticaldev --limit 5
# Read a single article body by id
opencli devto read 3605688
opencli devto read 3605688 --max-length 5000
# JSON output
opencli devto top -f json
opencli devto read 3605688 -f json
```
## Prerequisites
- No browser required — uses the public DEV.to API
+66
View File
@@ -0,0 +1,66 @@
# dianping
**Mode**: 🔐 Browser · **Domain**: `www.dianping.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli dianping search "<keyword>" --city <name-or-id> --limit <n>` | Search shops/restaurants on `www.dianping.com` |
| `opencli dianping shop <shop_id>` | Read shop detail by shop id (alias: `detail`) |
## Usage Examples
```bash
# Search "火锅" in 北京 (top 5 results, table view)
opencli dianping search 火锅 --city beijing --limit 5
# JSON output
opencli dianping search 火锅 --city 北京 --limit 5 -f json
# Search using a numeric cityId (path segment in dianping URLs)
opencli dianping search 火锅 --city 2
# Search using the cookie's currently-selected city (omit --city)
opencli dianping search 火锅
# Read a shop detail by id
opencli dianping shop GxJZ4urc9TnKE3kY
# `detail` alias works the same way
opencli dianping detail GxJZ4urc9TnKE3kY -f json
# Pass a full /shop/<id> URL — the id segment is auto-extracted
opencli dianping shop https://www.dianping.com/shop/GxJZ4urc9TnKE3kY
```
## Prerequisites
- Chrome running and **logged into** `dianping.com`
- [Browser Bridge extension](/guide/browser-bridge) installed
- The PC site (`www.dianping.com`) is the primary target. The mobile site
(`m.dianping.com`) is intentionally crippled for non-mobile UAs and is not
used by these adapters.
## Notes
- `search --limit` is between 1 and 15 (dianping fixed page size). Default is 15.
- `--city` accepts a Chinese name (`北京`/`上海`), pinyin (`beijing`/`shanghai`),
or a numeric `cityId`. When omitted, the cookie's currently-selected city is
used.
- `search` columns: `rank, shop_id, name, rating, reviews, price, cuisine, district, url`.
`shop_id` round-trips into `dianping shop`.
- `shop` returns a `field, value` sheet so missing fields surface as `null`
rather than fabricated values. The phone number is intentionally hidden on
the PC web (only revealed in the native app), so it is not included.
## Troubleshooting
- If you hit a captcha redirect to `verify.meituan.com` (icon-tap challenge),
the adapter will throw `AUTH_REQUIRED` with the captcha URL. Open the URL
manually in the same Chrome profile, solve the captcha, then retry.
- If `dianping shop` fails with `EMPTY_RESULT`, the shop may have been removed
or relocated; verify the id by visiting `https://www.dianping.com/shop/<id>`
in the browser.
- If `dianping search` returns zero rows, try a more specific keyword or a
different city — dianping's search is keyword-coverage dependent.
+27
View File
@@ -0,0 +1,27 @@
# Dictionary
**Mode**: 🌐 Public · **Domain**: `api.dictionaryapi.dev`
Search the open dictionary to quickly fetch native definitions, part of speech contexts, and phonetic pronunciations directly in your IDE terminal.
## Commands
| Command | Description |
|---------|-------------|
| `opencli dictionary search` | Fetch the exact definition of a word |
| `opencli dictionary synonyms` | Find related synonyms for a word |
| `opencli dictionary examples` | Read real-world sentence usage examples |
## Usage Examples
```bash
# Look up a complex term
opencli dictionary search serendipity
# Discover phonetics
opencli dictionary search ephemeral
```
## Prerequisites
- No browser required — utilizes the fast, open JSON definitions API.
+63
View File
@@ -0,0 +1,63 @@
# Docker Hub
**Mode**: 🌐 Public · **Domain**: `hub.docker.com`
Search and inspect public Docker Hub repositories without auth or browser. Two commands cover discovery and per-repository metadata.
## Commands
| Command | Description |
|---------|-------------|
| `opencli dockerhub search <query>` | Search Docker Hub repositories by keyword |
| `opencli dockerhub image <name>` | Repository metadata (stars, pulls, last updated, status) |
## Usage Examples
```bash
# Search repositories
opencli dockerhub search nginx --limit 10
opencli dockerhub search "bitnami redis" --limit 5
# Single repository metadata (use `image` from search rows)
opencli dockerhub image nginx # implicit `library/nginx`
opencli dockerhub image library/nginx
opencli dockerhub image bitnami/redis
# JSON output
opencli dockerhub search nginx -f json
opencli dockerhub image nginx -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, image, official, stars, pulls, description, url` |
| `image` | `image, official, stars, pulls, description, lastUpdated, lastModified, registered, status, url` |
The `image` column from `search` round-trips into `image` exactly. Bare repository names (e.g. `nginx`) resolve to the implicit `library` owner that Docker Hub uses for official images.
## Options
### `dockerhub search`
| Option | Description |
|--------|-------------|
| `query` (positional) | Search keyword |
| `--limit` | Max repositories (1-100, default: 25) |
### `dockerhub image`
| Option | Description |
|--------|-------------|
| `image` (positional) | Repository slug (`nginx`, `library/nginx`, `bitnami/redis`) |
## Caveats
- Image slugs are validated upfront against Docker Hub's `[a-z0-9][a-z0-9._-]*` pattern (2-255 chars). Bad input raises `ArgumentError`.
- Anonymous traffic is throttled. `HTTP 429` surfaces as a typed `CommandExecutionError` with a retry hint.
- Timestamp columns (`lastUpdated`, `lastModified`, `registered`) are normalized to second-precision `YYYY-MM-DDTHH:MM:SSZ`.
## Prerequisites
- No browser required — uses `hub.docker.com/v2/search/repositories/` and `hub.docker.com/v2/repositories/<owner>/<name>/`.
+80
View File
@@ -0,0 +1,80 @@
# 懂车帝 Dongchedi
**Mode**: 🌐 Public · **Domain**: `dongchedi.com`
No login, no cookies, no signature. Every command does a plain HTTP GET of a
server-rendered page and parses the `__NEXT_DATA__` JSON embedded in the HTML,
so it works out of the box.
## Commands
| Command | Description |
|---------|-------------|
| `opencli dongchedi search <keyword>` | Search car series by keyword → series + 指导价/经销商价 |
| `opencli dongchedi series <series_id>` | Series overview: brand, prices, 懂车分, sales rank, trim count |
| `opencli dongchedi models <series_id>` | Trims (款型) with guide / dealer / owner prices |
| `opencli dongchedi specs <series_id>` | Config overview: dimensions, powertrain, drivetrain, airbags |
| `opencli dongchedi score <series_id>` | 懂车分 rating — 8 axes vs same-class average |
| `opencli dongchedi koubei <series_id>` | Owner reviews (口碑): rating, trim bought, likes, full text |
`series`, `models`, `specs`, `score`, and `koubei` all take a **series_id**
get one from `search` (the `series_id` column) or paste a
`https://www.dongchedi.com/auto/series/<id>` URL.
## Usage Examples
```bash
# Find a car series
opencli dongchedi search "宝马X5" --limit 5
opencli dongchedi search "汉兰达"
# One series at a glance (prices + 懂车分 + ranks)
opencli dongchedi series 5273
# Trims and their prices
opencli dongchedi models 5273
opencli dongchedi models 5273 --status offline # discontinued trims
# Key configuration overview
opencli dongchedi specs 5273
# Rating breakdown vs same-class average
opencli dongchedi score 5273
# Owner reviews (full body in the content column)
opencli dongchedi koubei 5273 --limit 10
# JSON output
opencli dongchedi search "汉兰达" -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, series_id, name, brand, official_price, dealer_price, pictures, url` |
| `series` | `field, value` (series_id, name, brand, sub_brand, official_price, dealer_price, used_price, score, review_count, sale_rank, score_rank, models, url) |
| `models` | `car_id, name, year, official_price, dealer_price, owner_price` |
| `specs` | `field, value` (dimensions, wheelbase, power, engine, gearbox, energy, acceleration, drivetrain, suspension, airbags) |
| `score` | `dimension, score, same_level_avg` |
| `koubei` | `rank, user, car, score, likes, comments, content, url` |
Scores are rescaled to a 05 float (Dongchedi stores them as x100 ints; 422 → 4.22).
## Notes & Limits
- **Why SSR, not the JSON API:** Dongchedi's `/motor/...` XHR endpoints are
ByteDance-signature gated (`a_bogus` / `X-Bogus`) and 404 without a valid
signature. The SSR pages expose the same data unsigned, so this adapter reads
those instead — no signature replication, no breakage when the signing scheme
rotates.
- **`specs` is the overview, not the full parameter sheet.** The complete
per-trim parameter table lives behind a signed XHR; rather than fabricate it,
`specs` returns the unsigned SSR overview (dimensions, powertrain, drivetrain,
suspension, airbags). For per-trim names/prices use `models`.
- **`koubei` is a single SSR page** (up to ~15 reviews). Deep pagination uses the
signed API and is intentionally not implemented.
## Prerequisites
None — public site, no authentication required.
+68
View File
@@ -0,0 +1,68 @@
# 豆瓣 (Douban)
**Mode**: 🔐 Browser (Cookie) · **Domain**: `douban.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli douban search` | 搜索豆瓣电影、图书或音乐 |
| `opencli douban top250` | 豆瓣电影 Top 250 |
| `opencli douban subject` | 条目详情 |
| `opencli douban photos` | 获取电影海报/剧照图片列表 |
| `opencli douban download` | 下载电影海报/剧照图片 |
| `opencli douban marks` | 我的标记 |
| `opencli douban reviews` | 我的短评 |
| `opencli douban movie-hot` | 豆瓣电影热门榜单 |
| `opencli douban book-hot` | 豆瓣图书热门榜单 |
## Usage Examples
```bash
# 搜索电影
opencli douban search "流浪地球"
# 搜索图书
opencli douban search --type book "三体"
# 搜索音乐
opencli douban search --type music "周杰伦"
# 电影 Top 250
opencli douban top250 --limit 10
# 电影详情
opencli douban subject 1292052
# 图书详情
opencli douban subject 2567698 --type book
opencli douban subject 2567698 --type book -f json
# 获取海报直链(默认 type=Rb)
opencli douban photos 30382501 --limit 20
# 下载海报到本地目录
opencli douban download 30382501 --output ./douban
# 只下载指定 photo_id 的一张图
opencli douban download 30382501 --photo-id 2913621075 --output ./douban
# 返回 JSON,便于上层界面直接渲染图片并右键取图
opencli douban photos 30382501 -f json
# 电影热门
opencli douban movie-hot --limit 10
# 图书热门
opencli douban book-hot --limit 10
# JSON output
opencli douban top250 -f json
```
## Prerequisites
- Chrome logged into `douban.com`
- Browser Bridge extension installed
图书搜索和图书详情在稳定批量使用时默认需要已登录的豆瓣浏览器会话。
+40
View File
@@ -0,0 +1,40 @@
# doubao
Browser adapter for [Doubao Chat](https://www.doubao.com/chat).
## Commands
| Command | Description |
|---------|-------------|
| `opencli doubao status` | Check whether the page is reachable and whether Doubao appears logged in |
| `opencli doubao new` | Start a new Doubao conversation |
| `opencli doubao send "..."` | Send a message to the current Doubao chat |
| `opencli doubao read` | Read the visible Doubao conversation |
| `opencli doubao ask "..."` | Send a prompt and wait for a reply |
| `opencli doubao detail <id>` | 对话详情 |
| `opencli doubao history` | 历史对话列表 |
| `opencli doubao meeting-summary <id>` | 会议总结 |
| `opencli doubao meeting-transcript <id>` | 会议记录 |
## Prerequisites
- Chrome is running
- You are already logged into [doubao.com](https://www.doubao.com/)
- Browser Bridge extension is installed and enabled for OpenCLI
## Examples
```bash
opencli doubao status
opencli doubao new
opencli doubao send "帮我总结这段文档"
opencli doubao read
opencli doubao ask "请写一个 Python 快速排序示例" --timeout 90
```
## Notes
- The adapter targets the web chat page at `https://www.doubao.com/chat`
- Doubao commands default to persistent site sessions, so consecutive `doubao ask` / `doubao read` / `doubao detail` invocations continue in the same Doubao page. Pass `--site-session ephemeral` for a one-shot tab.
- `new` first tries the visible "New Chat / 新对话" button, then falls back to the new-thread route
- `ask` uses DOM polling, so very long generations may need a larger `--timeout`
+75
View File
@@ -0,0 +1,75 @@
# Douyin (抖音创作者中心)
**Mode**: 🔐 Browser · **Domain**: `creator.douyin.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli douyin profile` | 获取账号信息 |
| `opencli douyin videos` | 获取作品列表 |
| `opencli douyin drafts` | 获取草稿列表 |
| `opencli douyin draft` | 上传视频并保存为草稿 |
| `opencli douyin publish` | 定时发布视频到抖音 |
| `opencli douyin update` | 更新视频信息 |
| `opencli douyin delete` | 删除作品 |
| `opencli douyin stats` | 查询作品数据分析 |
| `opencli douyin collections` | 获取合集列表 |
| `opencli douyin activities` | 获取官方活动列表 |
| `opencli douyin location` | 搜索发布可用的地理位置 |
| `opencli douyin hashtag search` | 按关键词搜索话题 |
| `opencli douyin hashtag suggest` | 基于封面 URI 推荐话题 |
| `opencli douyin hashtag hot` | 获取热点词 |
## Usage Examples
```bash
# 账号与作品
opencli douyin profile
opencli douyin videos --limit 10
opencli douyin videos --status scheduled
opencli douyin drafts
# 发布前辅助信息
opencli douyin collections
opencli douyin activities
opencli douyin location "东京塔"
opencli douyin hashtag search "春游"
opencli douyin hashtag hot --limit 10
# 保存草稿
opencli douyin draft ./video.mp4 \
--title "春游 vlog" \
--caption "#春游 先存草稿"
# 定时发布
opencli douyin publish ./video.mp4 \
--title "春游 vlog" \
--caption "#春游 今天去看樱花" \
--schedule "2026-04-08T12:00:00+09:00"
# 也支持 Unix 秒字符串
opencli douyin publish ./video.mp4 \
--title "春游 vlog" \
--schedule 1775617200
# 更新与删除
opencli douyin update 1234567890 --caption "更新后的文案"
opencli douyin update 1234567890 --reschedule "2026-04-09T20:00:00+09:00"
opencli douyin delete 1234567890
# JSON 输出
opencli douyin profile -f json
```
## Prerequisites
- Chrome running and **logged into** `creator.douyin.com`
- The logged-in account must have access to Douyin Creator Center publishing features
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- `publish` requires `--schedule` to be at least 2 hours later and no more than 14 days later
- `draft` and `publish` upload the video through Douyin/ByteDance browser-authenticated APIs, so cookies in the active browser session must be valid
- `hashtag suggest` expects a valid `cover`/`cover_uri` value produced during the publish pipeline; for normal manual use, `hashtag search` and `hashtag hot` are usually more convenient
+60
View File
@@ -0,0 +1,60 @@
# DuckDuckGo
**Mode**: 🌐 Public · **Domains**: `html.duckduckgo.com`, `duckduckgo.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli duckduckgo search <keyword>` | Search DuckDuckGo and extract results from the page |
| `opencli duckduckgo suggest <keyword>` | Get DuckDuckGo search suggestions |
## What works today
- `duckduckgo search` uses browser mode to search `html.duckduckgo.com` and extract ranked results.
- `duckduckgo suggest` uses the public JSON API at `duckduckgo.com/ac/` — no browser needed.
- `search` supports `--region` (e.g. `jp-jp`, `us-en`, `cn-zh`) and `--time` (`d`, `w`, `m`, `y`) filters.
- `search` supports `--offset` for pagination via XHR POST (avoids page navigation issues with `form.submit()`).
## Current limitations
- `duckduckgo search` requires browser mode due to anti-bot protections on DuckDuckGo.
- The HTML version returns a maximum of 10 results per page; `--limit` must be between 1 and 10.
- Pagination uses POST-based navigation; results may have some overlap at page boundaries.
- Snippet extraction is based on the HTML version's DOM structure (`.result__snippet`).
## Usage Examples
```bash
# Basic search
opencli duckduckgo search "machine learning"
# Limit results
opencli duckduckgo search "machine learning" --limit 5
# Region-specific search
opencli duckduckgo search "machine learning" --region jp-jp
# Time filter (past week)
opencli duckduckgo search "machine learning" --time w
# Pagination (second page)
opencli duckduckgo search "machine learning" --offset 10
# JSON output
opencli duckduckgo search "machine learning" -f json
# Search suggestions
opencli duckduckgo suggest "machine" --limit 5
```
## Prerequisites
- `suggest` does not require Chrome.
- `search` requires Chrome running (Standalone mode will auto-launch) or the [Browser Bridge extension](/guide/browser-bridge).
## Notes
- DuckDuckGo uses `uddg=` URL redirects; the adapter automatically decodes them to return clean URLs.
- The `ac/` suggest API returns phonetic suggestions for CJK queries, which may not always match expected results.
- Region codes follow DuckDuckGo's format (e.g. `jp-jp`, `us-en`, `uk-en`). Default is all regions.
+39
View File
@@ -0,0 +1,39 @@
# Eastmoney
**Mode**: 🔐 Browser · **Domain**: `guba.eastmoney.com`
Access 东方财富 (Eastmoney) stock-market data from the terminal.
## Commands
| Command | Description |
|---------|-------------|
| `opencli eastmoney hot-rank` | 东方财富热股榜 (Eastmoney hot-stock ranking) |
## Usage Examples
```bash
# Top 20 hot stocks (default)
opencli eastmoney hot-rank
# Top 50 hot stocks
opencli eastmoney hot-rank --limit 50
# JSON output
opencli eastmoney hot-rank -f json
```
## Options
| Option | Default | Description |
|--------|---------|-------------|
| `--limit` | `20` | 返回数量 (number of rows to return) |
## Output Columns
`rank` · `symbol` · `name` · `price` · `changePercent` · `heat` · `url`
## Prerequisites
- Chrome extension installed and connected
- Visit `guba.eastmoney.com` once in the browser so cookies are populated
+48
View File
@@ -0,0 +1,48 @@
# endoflife.date
**Mode**: 🌐 Public · **Domain**: `endoflife.date`
Look up release cycles and end-of-life / LTS / support dates for hundreds of products (Node.js, Python, Ubuntu, Java, Postgres, Kubernetes, etc.). Hits the unauthenticated `endoflife.date/api` directly.
## Commands
| Command | Description |
|---------|-------------|
| `opencli endoflife product <name>` | Release cycles + EOL / LTS / support dates for one product |
## Usage Examples
```bash
# Node.js cycles (newest first)
opencli endoflife product nodejs
# Python, JSON output for scripts
opencli endoflife product python -f json
# Ubuntu LTS schedule
opencli endoflife product ubuntu
```
## Output Columns
| Command | Columns |
|---------|---------|
| `product` | `product, cycle, releaseDate, latest, latestReleaseDate, lts, support, eol, extendedSupport, eolStatus, url` |
## Options
### `product`
| Option | Description |
|--------|-------------|
| `product` (positional) | endoflife.date product slug (e.g. `nodejs`, `python`, `ubuntu`, `kubernetes`) |
## Notes
- **`eolStatus`** is a derived projection (`active` / `eol` / `ongoing` / `null`) computed against today's UTC date — agents can answer "is this version still supported?" without parsing dates.
- **Boolean dates → strings.** endoflife.date sometimes ships `true` for "ongoing support" / `false` for "no LTS". The adapter normalises:
- `true``"ongoing"`
- `false` / `null``null`
- ISO date string → returned as-is
- **No API key required.** Slugs are exactly what appears at `https://endoflife.date/<product>`.
- **Errors.** Bad slug shape → `ArgumentError`; unknown product → `EmptyResultError` (HTTP 404); rate-limited → `CommandExecutionError`.
+65
View File
@@ -0,0 +1,65 @@
# Facebook
**Mode**: 🔐 Browser · **Domain**: `facebook.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli facebook profile` | Get user/page profile info |
| `opencli facebook notifications` | Get recent notifications with `unread` / `time` / `url` / `notif_id` / `notif_type` |
| `opencli facebook feed` | Get news feed posts |
| `opencli facebook search` | Search people, pages, posts |
| `opencli facebook marketplace-listings` | List your Marketplace seller listings |
| `opencli facebook marketplace-inbox` | List recent Marketplace buyer/seller conversations |
## Usage Examples
```bash
# View a profile
opencli facebook profile zuck
# Get notifications (default 15, max 100)
opencli facebook notifications --limit 10
# News feed
opencli facebook feed --limit 5
# Search
opencli facebook search "OpenAI" --limit 5
# Marketplace seller listings and inbox
opencli facebook marketplace-listings --limit 10
opencli facebook marketplace-inbox --limit 10
# JSON output
opencli facebook profile zuck -f json
```
## Output
### `notifications`
| Column | Type | Notes |
|--------|------|-------|
| `index` | int | 1-based row number across the returned page |
| `unread` | bool | Derived from the explicit `<div>未读</div>` / `<div>Unread</div>` badge child; falls back to the anchor text prefix |
| `text` | string | Notification body text. Read first from the per-row "Mark as read" button's `aria-label` (with the locale prefix stripped) so it does not include the unread badge or trailing time. Full body, **no silent truncation** |
| `time` | string \| null | Time-ago label from the row's `<abbr>`, e.g. `2天` / `5 hrs`. `null` when the abbr is missing — never the legacy `'-'` sentinel |
| `url` | string | Full notification anchor href, including `notif_id` / `notif_t` query params, so callers can follow up |
| `notif_id` | string \| null | `notif_id` query param parsed from `url`; `null` when absent |
| `notif_type` | string \| null | `notif_t` query param (e.g. `onthisday`, `approve_from_another_device`, `group_recommendation`); `null` when absent |
`--limit` accepts a positive integer in `[1, 100]`. Out-of-range or
non-numeric input raises `ArgumentError` upfront — no silent clamp.
If Facebook redirects to a login/checkpoint path (for example
`/login.php`, `/login/identify/`, or `/checkpoint/`; session expired)
the command raises `AuthRequiredError`. An empty notification list after
a successful auth check raises `EmptyResultError` instead of a silent
`[]`.
## Prerequisites
- Chrome running and **logged into** facebook.com
- [Browser Bridge extension](/guide/browser-bridge) installed
+62
View File
@@ -0,0 +1,62 @@
# Flathub
**Mode**: 🌐 Public · **Domain**: `flathub.org`
Search the Flathub Linux flatpak app registry and fetch full appstream metadata for any app. Flathub is the canonical flatpak distribution channel for Linux desktop applications.
## Commands
| Command | Description |
|---------|-------------|
| `opencli flathub search <query>` | Search Flathub apps by keyword |
| `opencli flathub app <appId>` | Full Flathub appstream metadata for an app id |
## Usage Examples
```bash
# Keyword search
opencli flathub search firefox
opencli flathub search "image editor" --limit 10
opencli flathub search blender
# App detail (appId round-trips from search)
opencli flathub app org.mozilla.firefox
opencli flathub app org.gnome.Calculator
opencli flathub app org.blender.Blender
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, appId, name, summary, developer, license, isFreeLicense, mainCategories, installsLastMonth, updatedAt, url` |
| `app` | `appId, name, summary, developer, license, isFreeLicense, isEol, categories, keywords, latestVersion, latestReleaseDate, homepage, bugtracker, donation, url` |
The `appId` column round-trips between commands.
## Options
### `search`
| Option | Description |
|--------|-------------|
| `query` (positional) | Search keyword |
| `--limit` | Max apps (1100, default: 25) |
### `app`
| Option | Description |
|--------|-------------|
| `appId` (positional) | AppStream id, reverse-DNS form (e.g. `org.mozilla.firefox`, `org.gnome.Calculator`) |
## Notes
- **`appId` is the reverse-DNS AppStream id** (`org.mozilla.firefox`), not the underscored cache id (`org_mozilla_firefox`) Flathub returns alongside it. We always emit the dotted form so the `search → app` round-trip works without translation.
- **`updatedAt` normalisation**: Flathub's `/search` endpoint emits `updated_at` as unix-seconds (integer); `/appstream/<id>` emits it as ISO date strings. The adapter normalises `/search` to ISO date (`YYYY-MM-DD`) so both surfaces look consistent.
- **`releases[].timestamp` is a numeric string**, not an int — quirk of the appstream layer. The adapter coerces both shapes when picking the latest release.
- **`isEol`** is `true` for end-of-life apps (no longer maintained).
- **`isFreeLicense`** uses Flathub's classification of `project_license` (e.g. `MPL-2.0`, `GPL-3.0-or-later`). Don't use this in lieu of reading the actual license; useful as a quick filter.
- **`installsLastMonth` (search only)** is Flathub's 30-day install count per app. Useful for popularity ranking; `null` when not yet aggregated.
- **`mainCategories`** is a single string in `/search` (e.g. `'network'`); on `/appstream/<id>` the broader `categories` list is used (`'Network, WebBrowser'`).
- **No API key required.** Flathub's API is public and unauthenticated; bursts → `CommandExecutionError`.
- **Errors.** Empty query / bad appId / bad limit → `ArgumentError`; unknown appId (HTTP 404) → `EmptyResultError`; transport / 429 / non-200 → `CommandExecutionError`.
+58
View File
@@ -0,0 +1,58 @@
# Flomo
**Mode**: 🌐 Cookie · **Domain**: `flomoapp.com`, `v.flomoapp.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli flomo memos` | List your Flomo memos |
## What works today
- Lists memos from your Flomo account using the browser login session.
- Reads the access token automatically from `localStorage.me.access_token` — no manual token setup required.
- Supports `--limit` from 1 to 200. Invalid values fail instead of being silently clamped.
- Supports `--since <unix_ts>` to filter by update time.
- Supports `--slug <cursor>` for pagination from a previous memo page.
- Returns stable `id` / `url` fields plus memo content (HTML), slug, tags, image URLs, and timestamps.
## Current limitations
- Requires browser mode with an active Flomo login session.
- The Flomo API uses a custom MD5 signing mechanism with a fixed secret key (embedded in the adapter). If the signing key changes, the adapter will break.
- `--slug` pagination is experimental and may not work reliably.
- Image URLs have expiration timestamps in the query string; they may expire after some time.
- Rate limited to 360 requests per hour.
## Usage Examples
```bash
# List recent memos
opencli flomo memos
# Fetch all memos
opencli flomo memos --limit 200
# Filter by time (Unix timestamp)
opencli flomo memos --since 1735689600
# Continue from a memo cursor
opencli flomo memos --slug memo_abc123 --limit 50
# JSON output
opencli flomo memos --limit 200 -f json
```
## Prerequisites
- Requires Chrome running with an active Flomo session at `v.flomoapp.com`.
- Standalone mode will auto-launch Chrome; use the [Browser Bridge extension](/guide/browser-bridge) for an established session.
## Notes
- The adapter authenticates via `Strategy.COOKIE` — it reads the Bearer token from `localStorage` in the browser context, then calls the signed API from Node.js.
- Memo content is stored as HTML (including formatting tags like `<p>`, `<ul>`, `<strong>`, etc.).
- Image attachments are returned as thumbnail URLs from Flomo's CDN (`static.flomoapp.com`).
- The `--since` parameter expects a Unix timestamp in seconds (e.g. `1735689600` = 2025-01-01 00:00:00 UTC).
- `id` is the memo slug returned by Flomo and `url` opens the memo in Flomo's web app when the session has access.
+119
View File
@@ -0,0 +1,119 @@
# Gemini
**Mode**: 🔐 Browser · **Domain**: `gemini.google.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli gemini new` | Start a new Gemini web chat |
| `opencli gemini ask <prompt> [--model <value>] [--thinking <level>]` | Send a prompt and return only the assistant reply |
| `opencli gemini image <prompt>` | Generate images in Gemini and optionally save them locally |
| `opencli gemini models` | List available Gemini models |
| `opencli gemini deep-research <prompt>` | Start a Gemini Deep Research run and confirm it |
| `opencli gemini deep-research-result <query>` | Export Deep Research report URL from a Gemini conversation |
| `opencli gemini status` | Check Gemini web page availability and login state |
| `opencli gemini history [--limit N]` | List visible Gemini conversation history from the sidebar |
| `opencli gemini detail <id>` | Open a Gemini conversation by id, URL, or sidebar title and read its turns |
| `opencli gemini read` | Read the turns visible in the current Gemini web conversation |
## Usage Examples
```bash
# Start a fresh chat
opencli gemini new
# Ask Gemini and return minimal plain-text output
opencli gemini ask "Reply with exactly: HELLO"
# Ask with a specific model selected
opencli gemini ask "Explain quantum computing in one sentence" --model 2.5-flash
# Ask in a new chat and wait longer
opencli gemini ask "Summarize this design in 3 bullets" --new true --timeout 90
# Ask with extended thinking
opencli gemini ask "Explain quantum computing" --thinking extended
# Ask with standard thinking in a fresh chat
opencli gemini ask "Hello" --new true --thinking standard
# Ask with a specific model and thinking level combined
opencli gemini ask "Explain quantum computing in one sentence" --model 2.5-pro --thinking extended
# Ask in a new chat with a specific model and thinking level
opencli gemini ask "Summarize this design in 3 bullets" --new true --model 2.5-flash --thinking standard
# Generate an icon image with short flags
opencli gemini image "Generate a tiny cyan moon icon" --rt 1:1 --st icon
# Only generate in Gemini and print the page link without downloading files
opencli gemini image "A watercolor sunset over a lake" --sd true
# Save generated images to a custom directory
opencli gemini image "A flat illustration of a robot" --op ~/tmp/gemini-images
# List available models
opencli gemini models
# List models as JSON for scripting
opencli gemini models -f json
```
## Options
### `ask`
| Option | Description |
|--------|-------------|
| `prompt` | Prompt to send (required positional argument) |
| `--model` | Gemini model to use (e.g. `2.5-flash`, `2.5-pro`). Use `opencli gemini models` to list available values. |
| `--timeout` | Max seconds to wait for a reply (default: `60`) |
| `--new` | Start a new chat before sending (default: `false`) |
| `--thinking` | Thinking level: `standard` or `extended` (omitted = leave unchanged) |
### `image`
| Option | Description |
|--------|-------------|
| `prompt` | Image prompt to send (required positional argument) |
| `--rt` | Aspect ratio shorthand: `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3` |
| `--st` | Optional style shorthand, e.g. `icon`, `anime`, `watercolor` |
| `--op` | Output directory for downloaded images (default: `~/tmp/gemini-images`) |
| `--sd` | Skip download and only print the Gemini page link |
### `models`
| Column | Description |
|--------|-------------|
| `model` | Canonical model ID (e.g. `2.5-flash`, `2.5-pro`, `2.5-flash-lite`) |
| `thinkingValues` | Per-model thinking levels only when Gemini exposes them directly on the model entry; otherwise `[]`. The current Gemini UI usually exposes thinking controls for the active model, so this command does not infer support for every model. |
- `models` discovers available models from the visible Gemini web UI model picker.
- The command is read-only: it does not select a model, change a thinking level, start a new chat, or submit a prompt.
- Model IDs match the canonical format used by later `gemini ask` model selection.
- Throws a command error when the model picker cannot be opened, which helps surface Gemini Web UI changes. Returns an empty list only when the picker opens but no model entries are available.
## Behavior
- When `--new true` is combined with `--model` and/or `--thinking`, the new chat is created first, then the model and thinking level are selected, then the snapshot is read, and finally the prompt is submitted.
- `ask --model <value>` selects the requested model before reading the page state and sending the prompt. The selected model remains visible in the Gemini web UI after the command completes. Short aliases like `pro` or `flash` are rejected—use canonical model IDs from `opencli gemini models`.
- When `--model` is omitted, `ask` does not change the current model.
- All other Gemini commands (`image`, `deep-research`, etc.) are unaffected and do not accept `--model`.
- `ask` uses plain minimal output and returns only the assistant response text prefixed with `💬`.
- `image` also uses plain output and prints `status / file / link` instead of a table.
- `image` always starts from a fresh Gemini chat before sending the prompt.
- When `--sd` is enabled, `image` keeps the generation in Gemini and only prints the conversation link.
## Prerequisites
- Chrome is running
- You are already logged into `gemini.google.com`
- [Browser Bridge extension](/guide/browser-bridge) is installed
## Caveats
- This adapter drives the Gemini consumer web UI, not a public API.
- Gemini commands default to persistent site sessions, so consecutive `gemini ask` / `gemini image` / `gemini deep-research-result` invocations continue in the same Gemini page. Pass `--site-session ephemeral` for a one-shot tab.
- It depends on the current browser session and may fail if Gemini shows login, consent, challenge, quota, or other gating UI.
- DOM or product changes on Gemini can break composer detection, new-chat handling, or image export behavior.
+82
View File
@@ -0,0 +1,82 @@
# GeoGebra
**Mode**: Browser | **Domain**: `www.geogebra.org`
## Commands
| Command | Description |
|---------|-------------|
| `opencli geogebra eval "<cmd1>;<cmd2>;..."` | Execute one or more GeoGebra commands in a fresh automation page |
| `opencli geogebra add-point --name A --coords 1,2` | Create one point |
| `opencli geogebra add-line --points A,B --type segment` | Create a line, segment, or ray from existing points |
| `opencli geogebra add-circle --center A --radius 3` | Create a circle from an existing center |
| `opencli geogebra add-polygon --points A,B,C` | Create a polygon from existing points |
| `opencli geogebra triangle --size 4` | Draw an equilateral triangle |
| `opencli geogebra hexagon --size 3` | Draw a regular hexagon |
| `opencli geogebra list` | List current objects on the canvas |
| `opencli geogebra info --name A` | Inspect one object |
## Two Workflows
### 1. Fresh automation page
Use the site command directly when OpenCLI is allowed to open its own GeoGebra page.
```bash
opencli geogebra triangle --size 4
opencli geogebra eval "A=(0,0);B=(4,0);c=Circle(A,B);d=Circle(B,A);C=Intersect(c,d,1);Polygon(A,B,C)"
```
Important:
- Each `opencli geogebra ...` command runs in its own fresh browser session.
- `add-point`, `triangle`, and `hexagon` are self-contained and work on a blank Geometry canvas.
- `add-line`, `add-circle`, `add-polygon`, `list`, and `info` need an already-populated canvas or a bound tab workflow.
- For multi-step constructions, prefer one `eval` call with semicolon-separated commands, or use a shape-specific helper like `triangle`.
### 2. Already-open user tab
Use this when a human or another agent already has the right `geogebra.org` tab open and you want to draw in that exact tab.
```bash
opencli browser bind --workspace bound:geogebra --domain www.geogebra.org
opencli browser --workspace bound:geogebra get url
opencli browser --workspace bound:geogebra eval "(() => {
const cmds = [
'OCLIA=(0,0)',
'OCLIB=(4,0)',
'OCLIc=Circle(OCLIA,OCLIB)',
'OCLId=Circle(OCLIB,OCLIA)',
'OCLIC=Intersect(OCLIc,OCLId,1)',
'OCLIt=Polygon(OCLIA,OCLIB,OCLIC)',
];
return cmds.map(cmd => ({ cmd, label: ggbApplet.evalCommandGetLabels(cmd) }));
})()"
```
This bound-tab workflow is the safest option when:
- the user explicitly asks to use an existing Chrome tab
- the tab is already positioned the way the user wants
- you do not want OpenCLI to navigate away or replace the user's page state
## Geometry Notes
- On the GeoGebra Geometry page, `RegularPolygon(...)` is not reliable here and may show an "unknown command" error.
- Prefer explicit constructions built from `Circle`, `Intersect`, `Segment`, and `Polygon`.
- `ggbApplet.evalCommandGetLabels(...)` can return multiple labels for commands like `Polygon(...)`; that is expected.
- The source of truth is the page's `ggbApplet` API. Adapter commands treat applet load failures, malformed Browser Bridge/evaluate results, invalid object labels, invalid numeric arguments, and failed GeoGebra command execution as typed command failures instead of returning success rows.
- Object names accepted by helper commands are intentionally conservative ASCII labels (`A`, `B1`, `poly_1`). Use `geogebra eval` for advanced GeoGebra syntax that needs broader command text.
## Agent Notes
- Start with `opencli doctor` if Browser Bridge behavior looks stale.
- If the user wants the current visible tab, bind first and operate through `opencli browser --workspace bound:geogebra ...`.
- If a fresh page is acceptable, use `opencli geogebra eval ...` or `opencli geogebra triangle`.
- Use unique temporary labels like `OCLIA`, `OCLIB`, `OCLIC` in bound tabs to avoid colliding with the user's existing objects.
## Prerequisites
- Chrome running
- [Browser Bridge extension](/guide/browser-bridge) installed
- A `www.geogebra.org/geometry` page that has fully loaded
+34
View File
@@ -0,0 +1,34 @@
# Gitee
**Mode**: 🌐 Public (Browser) · **Domain**: `gitee.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli gitee trending` | Recommended open-source projects from Gitee Explore |
| `opencli gitee search` | Search Gitee repositories by keyword |
| `opencli gitee user` | Show user profile panel (nickname, followers, public repos, Gitee index) |
## Usage Examples
```bash
# Explore recommended projects
opencli gitee trending --limit 10
# Search repositories
opencli gitee search opencli --limit 10
# User profile panel
opencli gitee user fu-qingrong
# JSON output
opencli gitee trending --limit 5 -f json
opencli gitee search "ai agent" --limit 5 -f json
opencli gitee user jackwener -f json
```
## Prerequisites
- Chrome running with [Browser Bridge extension](/guide/browser-bridge) installed
- No login required for these public commands
+40
View File
@@ -0,0 +1,40 @@
# GitHub Trending
**Mode**: 🌐 Public · **Domain**: `github.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli github-trending repos` | List repositories from GitHub Trending |
## Usage Examples
```bash
# Daily trending repositories
opencli github-trending repos --limit 10
# Weekly Rust trending repositories
opencli github-trending repos --language rust --since weekly --limit 10
# Language slugs are URL-encoded before calling github.com/trending
opencli github-trending repos --language "c++" --since monthly -f json
```
## Arguments
| Argument | Description |
|----------|-------------|
| `--since` | Time range: `daily`, `weekly`, or `monthly` (default: `daily`) |
| `--language` | Optional GitHub Trending language slug, for example `python`, `rust`, or `c++` |
| `--limit` | Number of repositories to return, 1-25 |
## Output Columns
`rank`, `repo`, `description`, `language`, `stars`, `forks`, `starsSince`, `url`
## Notes
- This command reads the public server-rendered `https://github.com/trending` page. GitHub does not expose an official REST endpoint for Trending.
- It does not use the logged-in GitHub browser session and does not call `gh`.
- Parser drift is treated as a command execution error. A true empty result requires GitHub's explicit empty-state page.
+34
View File
@@ -0,0 +1,34 @@
# GitHub
**Mode**: 🔐 Browser · **Domain**: `github.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli github whoami` | Show the currently logged-in GitHub account |
| `opencli github login` | Open GitHub login and wait until the browser session is authenticated |
## Usage Examples
```bash
# Check current GitHub identity
opencli github whoami
# Open the login page if the current browser session is not authenticated
opencli github login
# JSON output for agents/scripts
opencli github whoami -f json
```
## Prerequisites
- Chrome running and **logged into** github.com
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- `whoami` verifies the current browser cookie session and does not open the login page.
- `login` opens `https://github.com/login` in a foreground browser window and waits until OpenCLI can verify the account.
- OpenCLI never fills credentials, CAPTCHA, 2FA, or passkeys. The user completes authentication in the browser; OpenCLI only verifies the resulting session.
+25
View File
@@ -0,0 +1,25 @@
# Google Scholar
**Mode**: 🌐 Public · **Domain**: `scholar.google.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli google-scholar search <query>` | Search Google Scholar papers by keyword |
| `opencli google-scholar cite <query>` | Fetch a citation export for a Scholar search result |
| `opencli google-scholar profile <author>` | Open an author profile and list top papers |
## Usage Examples
```bash
opencli google-scholar search "transformer"
opencli google-scholar search "retrieval augmented generation" --limit 5
opencli google-scholar cite "attention is all you need" --style bibtex
opencli google-scholar profile "Yann LeCun" --limit 5
```
## Notes
- Uses browser DOM extraction over public Google Scholar results
- Availability can vary by region or anti-bot challenges
+62
View File
@@ -0,0 +1,62 @@
# Google
**Mode**: 🌐 / 🔐 Mixed · **Domains**: `google.com`, `suggestqueries.google.com`, `news.google.com`, `trends.google.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli google search <keyword>` | Search Google and extract results from the page |
| `opencli google suggest <keyword>` | Get Google search suggestions |
| `opencli google news [keyword]` | Get Google News headlines (top stories or search) |
| `opencli google trends` | Get Google Trends daily trending searches |
## What works today
- Public API commands work without a browser:
- `suggest` — JSON API, no auth needed
- `news` — RSS feed, supports top stories and keyword search
- `trends` — RSS feed, supports different regions
- `google search` uses browser mode to extract results from google.com.
## Current limitations
- `google search` may trigger CAPTCHA in Standalone browser mode. Extension mode (with an established Chrome session) is more reliable.
- Google frequently changes its DOM structure. If `search` stops returning results, selectors may need updating.
- Snippet extraction may return empty for some results depending on Google's layout.
## Usage Examples
```bash
# Search Google
opencli google search "typescript tutorial" --limit 10
# Get search suggestions
opencli google suggest python
# Get top news headlines
opencli google news --limit 5
# Search news for a topic
opencli google news "artificial intelligence" --limit 10 --lang en --region US
# Get trending searches in Japan
opencli google trends --region JP --limit 10
# Output as JSON
opencli google search "machine learning" -f json
```
## Prerequisites
- `suggest`, `news`, `trends` do not require Chrome.
- `search` requires:
- Chrome running (or Standalone mode will auto-launch)
- For best results, use the [Browser Bridge extension](/guide/browser-bridge) with an established Google session
## Notes
- `suggest` defaults to `--lang zh-CN`; other commands default to `--lang en`.
- `news` supports `--lang` and `--region` parameters for localized results.
- `trends` traffic values are raw strings (e.g. "500K+", "1,000,000+"), not numeric.
- `search` output includes three result types: `result` (standard), `snippet` (featured answer box), and `paa` (People Also Ask).
+63
View File
@@ -0,0 +1,63 @@
# Go Module Proxy
**Mode**: 🌐 Public · **Domain**: `proxy.golang.org`
Fetch latest version + VCS origin metadata or list every published version tag for a Go module. Hits the unauthenticated Go module proxy (the canonical mirror used by `GOPROXY`).
## Commands
| Command | Description |
|---------|-------------|
| `opencli goproxy module <path>` | Latest version + VCS origin metadata for a Go module |
| `opencli goproxy versions <path>` | Published version tags for a Go module (newest first) |
## Usage Examples
```bash
# Latest released version of a module
opencli goproxy module github.com/gin-gonic/gin
opencli goproxy module golang.org/x/net
# Every published tag, semver-sorted (descending)
opencli goproxy versions github.com/gin-gonic/gin
# Larger window
opencli goproxy versions github.com/spf13/cobra --limit 100
# Include publish times (one extra request per row)
opencli goproxy versions golang.org/x/net --limit 10 --with-time
```
## Output Columns
| Command | Columns |
|---------|---------|
| `module` | `module, version, publishedAt, vcs, repository, commit, ref, pkgGoDevUrl, url` |
| `versions` | `rank, module, version, publishedAt, url` |
The `module` column round-trips between commands; the `version` column from `versions` round-trips into `goproxy module`'s `version` field.
## Options
### `module`
| Option | Description |
|--------|-------------|
| `module` (positional) | Go module path (e.g. `github.com/gin-gonic/gin`, `golang.org/x/net`) |
### `versions`
| Option | Description |
|--------|-------------|
| `module` (positional) | Go module path |
| `--limit` | Max rows to return (1200, default: 30) |
| `--with-time` | Fetch each version's publish time (one extra request per row, slower but adds the `publishedAt` column) |
## Notes
- **Module paths must be canonical.** Use what appears in your `go.mod` (host/path/...). The adapter rejects bare names without a host segment.
- **Pre-release tags sort lower than releases.** The default sort is descending semver; `v2.0.0` > `v1.10.1` > `v1.10.0` > `v1.9.0` (NOT alphabetic).
- **`publishedAt` is `null` by default** for `versions` to keep the request count at 1. Use `--with-time` only when you actually need the dates.
- **`module` returns the proxy's resolved upstream** — `vcs` (e.g. `git`), the actual repo URL, the resolved commit hash, and the tag/ref. Useful when a module path doesn't obviously map to a GitHub repo (`golang.org/x/net``go.googlesource.com/net`).
- **No API key required.** HTTP 404 / 410 (gone, e.g. retracted modules) → `EmptyResultError`; 429 → `CommandExecutionError`.
- **Errors.** Malformed module path or bad limit → `ArgumentError`; unknown module → `EmptyResultError`; transport / non-200 → `CommandExecutionError`.
+22
View File
@@ -0,0 +1,22 @@
# Gov Law
**Mode**: 🌐 Public · **Domain**: `flk.npc.gov.cn`
## Commands
| Command | Description |
|---------|-------------|
| `opencli gov-law search <query>` | Search the National Laws and Regulations Database |
| `opencli gov-law recent` | List the most recent laws and regulations |
## Usage Examples
```bash
opencli gov-law search "人工智能"
opencli gov-law recent --limit 10
```
## Notes
- Uses the site's Vue Router to navigate the law search SPA
- If the site restructures and Vue Router disappears, the command fails with a descriptive `FRAMEWORK_CHANGED` error
+22
View File
@@ -0,0 +1,22 @@
# Gov Policy
**Mode**: 🌐 Public · **Domain**: `www.gov.cn` / `sousuo.www.gov.cn`
## Commands
| Command | Description |
|---------|-------------|
| `opencli gov-policy search <query>` | Search policy documents on gov.cn |
| `opencli gov-policy recent` | List the latest State Council policy documents |
## Usage Examples
```bash
opencli gov-policy search "科技创新"
opencli gov-policy recent --limit 10
```
## Notes
- Both commands run in browser mode over public pages
- `search` uses the gov.cn policy search endpoint with `dataTypeId=107`
+159
View File
@@ -0,0 +1,159 @@
# Grok
Drive **Grok** (grok.com) chat from the terminal. All commands run through your existing browser session — no API key needed.
**Mode**: 🔐 Browser · **Domain**: `grok.com`
## Commands
| Command | Description | Access |
|---------|-------------|--------|
| `opencli grok status` | Page availability, login state, current model and session | read |
| `opencli grok history` | List recent conversations from the sidebar (requires login) | read |
| `opencli grok read` | Read messages in the current conversation | read |
| `opencli grok detail <id>` | Open a conversation by ID and read its messages | read |
| `opencli grok export` | Export visible conversation history metadata from the history dialog | read |
| `opencli grok export-all` | Export conversation metadata plus per-conversation transcript JSON | read |
| `opencli grok ask <prompt>` | Send a prompt and wait for the assistant reply | write |
| `opencli grok send <prompt>` | Fire-and-forget: send a prompt without waiting | write |
| `opencli grok new` | Start a fresh conversation | write |
| `opencli grok image <prompt>` | Generate images via Grok and return their URLs | write |
| `opencli grok pin <id>` | Pin a conversation from the sidebar context menu | write |
| `opencli grok unpin <id>` | Unpin a conversation from the sidebar context menu | write |
| `opencli grok delete <id> --yes` | Delete a sidebar conversation after an explicit `--yes` confirmation | write |
## Usage Examples
```bash
# Sanity check
opencli grok status
# Recent conversations
opencli grok history --limit 10
# Read the active conversation as markdown
opencli grok read --markdown true
# Read a specific historical conversation by ID (or full URL)
opencli grok detail 7c4197f2-10a1-4ebb-a84a-fea89f4f1d06
opencli grok detail https://grok.com/c/7c4197f2-10a1-4ebb-a84a-fea89f4f1d06 --markdown true
# Export loaded history metadata, then export transcripts from that manifest
opencli grok export --limit 25 -f json > grok-history.json
opencli grok export-all --manifestPath grok-history.json --limit 25 -f json > grok-transcripts.json
# Ask a question and wait for the reply
opencli grok ask "Explain quantum computing in simple terms"
# Ask in a brand-new chat
opencli grok ask "Hello" --new true
# Fire-and-forget (don't wait for the reply)
opencli grok send "continue the previous answer"
# Start a new conversation
opencli grok new
# Generate an image
opencli grok image "a cyberpunk mechanical owl, neon purple and blue" --new true
# Pin or unpin a conversation by ID (or full https://grok.com/c/<id> URL)
opencli grok pin 7c4197f2-10a1-4ebb-a84a-fea89f4f1d06
opencli grok unpin https://grok.com/c/7c4197f2-10a1-4ebb-a84a-fea89f4f1d06
# Preview then explicitly delete a conversation
opencli grok delete 7c4197f2-10a1-4ebb-a84a-fea89f4f1d06
opencli grok delete 7c4197f2-10a1-4ebb-a84a-fea89f4f1d06 --yes true
```
## Options
### `ask` / `send`
| Option | Description |
|--------|-------------|
| `prompt` | Prompt to send (required positional) |
| `--new` | Start a new chat before sending (default: `false`) |
| `--timeout` | (`ask` only) Max seconds to wait for the reply (default: `120`) |
### `read`
| Option | Description |
|--------|-------------|
| `--markdown` | Emit assistant replies as markdown (default: `false`) |
### `detail`
| Option | Description |
|--------|-------------|
| `id` | Session ID (UUID) or full `https://grok.com/c/<id>` URL (required positional) |
| `--markdown` | Emit assistant replies as markdown (default: `false`) |
### `history`
| Option | Description |
|--------|-------------|
| `--limit` | Max conversations to list (default: `20`, max `100`) |
### `export`
| Option | Description |
|--------|-------------|
| `--limit` | Max conversations to export; `0` means all loaded history (default: `0`) |
| `--maxScrolls` | Max history-dialog scroll rounds (default: `80`, max `500`) |
### `export-all`
| Option | Description |
|--------|-------------|
| `--limit` | Max conversations to export; `0` means all loaded history or all manifest rows after offset |
| `--offset` | Skip this many conversations before exporting (default: `0`) |
| `--manifestPath` | Optional JSON output from `grok export`; when present, skips history discovery and visits listed `/c/<id>` pages |
| `--maxScrolls` | Max history-dialog scroll rounds when no manifest is provided (default: `80`, max `500`) |
| `--pageScrolls` | Max per-conversation scroll-to-bottom rounds (default: `30`, max `200`) |
| `--pageTimeoutMs` | Max wait for each conversation page to show messages (default: `30000`) |
| `--delayMinMs` | Minimum polite delay after a conversation page loads (default: `0`) |
| `--delayMaxMs` | Maximum polite delay after a conversation page loads (default: `5000`) |
### `pin` / `unpin` / `delete`
| Option | Description |
|--------|-------------|
| `id` | Session ID (UUID) or full `https://grok.com/c/<id>` URL (required positional) |
| `--yes` | (`delete` only) Actually delete the conversation; without it the command returns a dry-run row |
## Output Columns
| Command | Columns |
|---------|---------|
| `status` | `Status, Login, Model, SessionId, Url` |
| `history` | `Index, Title, Url` |
| `read` | `Role, Text` |
| `detail` | `Role, Text` |
| `export` | `index, id, title, date, url` |
| `export-all` | `index, id, title, date, url, status, messageCount, error, messagesJson` |
| `ask` | `response` |
| `send` | `Status, Prompt` |
| `new` | `Status` |
| `pin` | `status, id` |
| `unpin` | `status, id` |
| `delete` | `status, id` |
## Prerequisites
- Chrome is running
- You are already signed into [grok.com](https://grok.com)
- [Browser Bridge extension](/guide/browser-bridge) is installed
## Notes
- `read` works in the current tab even without an explicit ID; pair it with `status` to discover the active session ID first.
- Grok commands default to persistent site sessions, so consecutive `grok ask` / `grok read` / `grok detail` invocations continue in the same Grok page. Pass `--site-session ephemeral` for a one-shot tab.
- `ask` waits for the streaming reply to stabilize; `send` returns immediately after submission.
- `history` reads the visible sidebar — if Grok lazy-loads older conversations, scroll the sidebar in your browser before re-running, or use `detail <id>` directly.
- `export` opens the full history dialog and scrolls it to collect real `https://grok.com/c/<id>` conversation URLs. Malformed history rows are treated as selector drift, not silently dropped.
- `export-all` visits each conversation URL and records per-conversation `status`. A page with no visible transcript produces an `empty` row with an `error` message; malformed transcript rows produce a `failed` row; malformed history or manifest identity fails before export.
- `pin`, `unpin`, and `delete` operate on conversations visible in the sidebar. `pin` / `unpin` verify the post-action context-menu state; `delete --yes` verifies the sidebar entry disappears before returning success.
- `status` returns `Model` / `SessionId` as `null` when they cannot be detected (e.g. page still loading) rather than a string sentinel — branch on `null` in agent code.
- DOM or product changes on Grok can break composer detection — `opencli grok status` is the quickest sanity check.
- `limit` is validated and rejected with `ArgumentError` if non-positive or above the documented max (`history` max 100); no silent clamp.
+65
View File
@@ -0,0 +1,65 @@
# 瓜子二手车 Guazi
**Mode**: 🌐 Public · **Domain**: `guazi.com`
No login, no cookies, no signature. Reads the **mobile** site `m.guazi.com`,
which server-renders the full listing list and car detail into the HTML (the
desktop `www.guazi.com` SPA loads data from a signature-locked API and is not
usable from a plain HTTP client).
## Commands
| Command | Description |
|---------|-------------|
| `opencli guazi browse [city]` | Used cars for sale in a city → price / mileage / year |
| `opencli guazi car <clue_id>` | One listing's detail → price, registration, mileage, specs, condition |
`car` takes a **clue_id** — get one from `browse` (the `clue_id` column) or paste
a `https://m.guazi.com/car-detail/c<id>.html` URL.
## Usage Examples
```bash
# Browse listings (defaults to Beijing)
opencli guazi browse
opencli guazi browse 上海 --limit 30
opencli guazi browse sz # city code also works
# One listing in detail
opencli guazi car 168029452296957
opencli guazi car https://m.guazi.com/car-detail/c168029452296957.html
# JSON output
opencli guazi browse 北京 -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `browse` | `rank, clue_id, title, price, down_payment, mileage, year, city, url` |
| `car` | `field, value` (clue_id, title, tag, price, reg_date, mileage, transfers, source_city, color, engine, gearbox, drivetrain, emission, condition, listing_no, url) |
## Cities
Pass a Chinese city name or a Guazi city code. Known names:
北京(bj), 上海(sh), 广州(gz), 深圳(sz), 杭州(hz), 成都(cd), 重庆(cq), 南京(nj),
武汉(wh), 天津(tj), 西安(xa), 苏州(su), 郑州(zz), 长沙(cs), 青岛(qd), 沈阳(sy),
大连(dl), 济南(jn), 合肥(hf), 佛山(fs). Any two/three-letter code is passed through
as-is, so other cities work by code too.
## Notes & Limits
- **First SSR page only.** Deep pagination and brand/keyword filtering route
through Guazi's signed `mapi.guazi.com` API, so `browse` returns the first
server-rendered page (~40 fresh listings) per city. Listings rotate, so
re-running surfaces new cars rather than the same page.
- **Condition is a summary**, not the full inspection checklist (基础车况 +
accident/transfer flags). The full 检测报告 sits behind the signed API and is
intentionally not faked.
- If Guazi ever pushes the mobile pages behind their anti-bot challenge, the
commands fail loudly with an auth-required error rather than returning blanks.
## Prerequisites
None — public site, no authentication required.
+46
View File
@@ -0,0 +1,46 @@
# HackerNews
**Mode**: 🌐 Public · **Domain**: `news.ycombinator.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli hackernews top` | Hacker News top stories |
| `opencli hackernews new` | Hacker News newest stories |
| `opencli hackernews best` | Hacker News best stories |
| `opencli hackernews ask` | Hacker News Ask HN posts |
| `opencli hackernews show` | Hacker News Show HN posts |
| `opencli hackernews jobs` | Hacker News job postings |
| `opencli hackernews search <query>` | Search Hacker News stories |
| `opencli hackernews user <username>` | Hacker News user profile |
| `opencli hackernews read <id>` | Read a story and its comment tree |
## Usage Examples
```bash
# Top stories
opencli hackernews top --limit 5
# Newest stories
opencli hackernews new --limit 10
# Search stories
opencli hackernews search "machine learning" --limit 5
# User profile
opencli hackernews user pg
# JSON output
opencli hackernews top -f json
# Sort search by date
opencli hackernews search "rust" --sort date
# Read a story and its top comments (id from any listing's `id` column)
opencli hackernews read 47999636 --limit 5 --depth 2
```
## Prerequisites
- No browser required — uses public API
+103
View File
@@ -0,0 +1,103 @@
# Hugging Face
**Mode**: 🌐 Public · **Domain**: `huggingface.co`
## Commands
| Command | Description |
|---------|-------------|
| `opencli hf top` | Top upvoted Hugging Face papers |
| `opencli hf paper <arxivId>` | Single paper detail (title / authors / summary / AI keywords / upvotes) |
| `opencli hf models` | Top Hugging Face models (downloads / likes / trending / freshness) |
| `opencli hf datasets` | Top Hugging Face datasets |
| `opencli hf spaces` | Top Hugging Face Spaces (gradio / streamlit / docker / static demos) |
## Usage Examples
```bash
# Today's top papers
opencli hf top --limit 10
# Single paper detail by arXiv id (mirrors HF's paper page)
opencli hf paper 1706.03762 # Attention Is All You Need
opencli hf paper 2005.14165 # GPT-3 paper
# All papers (no limit)
opencli hf top --all
# Specific date
opencli hf top --date 2025-03-01
# Weekly/monthly top papers
opencli hf top --period weekly
opencli hf top --period monthly
# Top models by downloads (default)
opencli hf models --limit 20
# Top text-generation models with name filter
opencli hf models --pipeline text-generation --search llama --sort likes --limit 10
# Top datasets by likes
opencli hf datasets --sort likes --limit 10
# Top Spaces by likes
opencli hf spaces --limit 20
# Filter Spaces by SDK
opencli hf spaces --sdk gradio --search llm --limit 10
# JSON output
opencli hf top -f json
```
### `top` Options
| Option | Description |
|--------|-------------|
| `--limit` | Number of papers (default: 20) |
| `--all` | Return all papers, ignoring limit |
| `--date` | Date in `YYYY-MM-DD` format (defaults to most recent) |
| `--period` | Time period: `daily`, `weekly`, or `monthly` (default: daily) |
Returns paper listing rows with `rank, id, title, upvotes, authors`. The `id` value round-trips into `opencli hf paper <id>`.
### `paper` Options
| Option | Description |
|--------|-------------|
| `id` (positional) | arXiv id (e.g. `1706.03762`, optionally with version suffix `v3`) |
Returns one row with `id, title, authors, publishedAt, upvotes, aiKeywords, summary, aiSummary, url`. The `summary` is the original arXiv abstract; `aiSummary` and `aiKeywords` are HF's AI-generated metadata (may be empty for older or non-curated papers). Returns `EmptyResultError` if HF has no paper page for that id.
### `models` Options
| Option | Description |
|--------|-------------|
| `--sort` | `downloads` / `likes` / `trending` / `created_at` / `last_modified` (default: `downloads`) |
| `--search` | Optional name/owner substring filter (e.g. `llama`, `mistralai/`) |
| `--pipeline` | Pipeline tag filter (e.g. `text-generation`, `image-classification`) |
| `--limit` | Max models (1100, default: 20) |
### `datasets` Options
| Option | Description |
|--------|-------------|
| `--sort` | Same set as `models` (default: `downloads`) |
| `--search` | Optional name/owner substring filter |
| `--limit` | Max datasets (1100, default: 20) |
### `spaces` Options
| Option | Description |
|--------|-------------|
| `--sort` | `likes` / `created_at` / `last_modified` (default: `likes`; HF doesn't accept `trending` for spaces) |
| `--search` | Optional name/owner substring filter (e.g. `stability`, `openai/`) |
| `--sdk` | SDK filter: `gradio` / `streamlit` / `docker` / `static` |
| `--limit` | Max spaces (1100, default: 20) |
Returns rows with `rank, id, author, sdk, likes, tags, lastModified, url`.
## Prerequisites
- No browser required — uses public Hugging Face API
+87
View File
@@ -0,0 +1,87 @@
# HLTV
**Mode**: 🌐 Browser · **Domain**: `hltv.org`
The HLTV adapter reads visible CS2/CS:GO stats pages through the Browser
Bridge. HLTV does not expose a stable public JSON API for these views, so the
commands parse search results, player stats, match mapstats, team stats, and
series pages from the rendered DOM.
## Commands
| Command | Description |
|---------|-------------|
| `opencli hltv search <query>` | Search players, teams, events, and articles |
| `opencli hltv player-summary` | Read a player's summary page and complete stats link |
| `opencli hltv player-matches` | Read a player's stats Matches tab |
| `opencli hltv player-form` | Aggregate recent player maps by summary, map, and opponent |
| `opencli hltv player-map-pool` | Aggregate a player's recent maps into map-pool buckets |
| `opencli hltv player-vs-team <team>` | Filter a player's maps against one team |
| `opencli hltv player-teammate-impact <playerA> <playerB>` | Compare shared and non-shared map samples for two teammates |
| `opencli hltv player-duel <playerA> <playerB>` | Compare two players on shared maps, including direct kills when available |
| `opencli hltv match-map <match>` | Read all player rows from one mapstats page |
| `opencli hltv match-series <match>` | Expand a BO1/BO3/BO5 into summary, map, and player rows |
| `opencli hltv team-matches <team>` | Read recent team map results |
| `opencli hltv team-map-pool <team>` | Read a team's visible map-pool stats |
| `opencli hltv event-matches <event>` | Read stats match rows for one event |
## Usage Examples
```bash
# Search and discover HLTV entity links
opencli hltv search niko --limit 5
# Read player pages and recent form
opencli hltv player-summary --player 3741/niko
opencli hltv player-matches --player 3741/niko --limit 10 -f json
opencli hltv player-form --player 19230/m0nesy --limit 30
# Compare two players
opencli hltv player-duel 3741/niko 21167/donk
opencli hltv player-duel 19230/m0nesy 3741/niko --mode history --limit 10
# Expand a series or inspect one mapstats URL
opencli hltv match-series https://www.hltv.org/stats/matches/126993/spirit-vs-falcons
opencli hltv match-map "https://www.hltv.org/stats/matches/mapstatsid/231594/falcons-vs-natus-vincere" -f json
# Team and event views
opencli hltv team-matches 6667/falcons --limit 10
opencli hltv team-map-pool 11283/falcons
opencli hltv event-matches 8301 --limit 10
```
## Common Subjects
- Player refs accept `id/slug`, player URLs, and compatible stats player URLs.
- Team refs accept `id/slug`, team URLs, and compatible stats team URLs.
- Match refs accept normal match URLs, stats series URLs, and mapstats URLs where
supported.
- Event refs accept event IDs, `/events/:id/:slug` URLs, and stats URLs with an
`event=` query parameter.
## Prerequisites
- Chrome running with the [Browser Bridge extension](/guide/browser-bridge)
installed
- HLTV accessible in the active browser session
- If HLTV shows a Cloudflare or human-verification page, complete it in Chrome
before retrying the command
## Notes
- The adapter is read-only and does not require HLTV login.
- Heavy match or duel commands may load multiple HLTV pages and can take longer
than search or summary commands.
- Use `--window foreground --keep-tab true` when debugging HLTV page structure
or Cloudflare interruptions.
- Primary subjects use positional arguments; filters such as `--limit`,
`--period`, `--ranking`, `--map`, and `--version` remain named options.
## Error Behaviour
| Condition | Error |
|-----------|-------|
| Invalid player, team, event, match, limit, offset, or filter argument | `ArgumentError` |
| Visible HLTV page contains no rows for the requested subject/filter | `EmptyResultError` |
| HLTV page structure changed or parser returns an unexpected shape | `CommandExecutionError` |
| Browser navigation or selector wait exceeds the command timeout | `TimeoutError` |
+77
View File
@@ -0,0 +1,77 @@
# Homebrew
**Mode**: 🌐 Public · **Domain**: `formulae.brew.sh`
Inspect Homebrew formulae and casks, plus the official install-rank analytics, without auth or browser. Three commands.
## Commands
| Command | Description |
|---------|-------------|
| `opencli homebrew formula <name>` | Single Homebrew core formula's metadata |
| `opencli homebrew cask <token>` | Single Homebrew cask's (macOS app) metadata |
| `opencli homebrew popular` | Most-installed formulae or casks (Homebrew analytics ranking) |
## Usage Examples
```bash
# Inspect a formula
opencli homebrew formula wget
opencli homebrew formula gcc@13
opencli homebrew formula imagemagick
# Inspect a cask (macOS package)
opencli homebrew cask firefox
opencli homebrew cask visual-studio-code
# Most popular installs (defaults to formula / 30d / top 30)
opencli homebrew popular
opencli homebrew popular --type cask --window 90d --limit 50
opencli homebrew popular --type formula --window 365d --limit 100
# JSON output
opencli homebrew popular -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `formula` | `formula, tap, version, license, description, homepage, dependencies, deprecated, disabled, source, url` |
| `cask` | `cask, tap, name, version, description, homepage, deprecated, disabled, download, url` |
| `popular` | `rank, token, type, installs, percent, window, url` |
The `token` column from `popular` round-trips into `formula` (when `type=formula`) or `cask` (when `type=cask`).
## Options
### `homebrew formula`
| Option | Description |
|--------|-------------|
| `name` (positional) | Formula name (`wget`, `gcc@13`, `imagemagick`) |
### `homebrew cask`
| Option | Description |
|--------|-------------|
| `token` (positional) | Cask token (`firefox`, `visual-studio-code`) |
### `homebrew popular`
| Option | Description |
|--------|-------------|
| `--type` | `formula` (default) or `cask` |
| `--window` | `30d` (default) / `90d` / `365d` |
| `--limit` | Max rows (1-500, default: 30) |
## Caveats
- Formula / cask tokens are validated against Homebrew's `[A-Za-z0-9][A-Za-z0-9._+@-]*` pattern (max 100 chars). Bad input raises `ArgumentError`.
- `--type` and `--window` are validated against the only values Homebrew analytics actually publishes. Anything else raises `ArgumentError`.
- Homebrew analytics serves install counts as comma-formatted strings (`"139,972"`); we coerce them to plain numbers.
- The endpoints are static GitHub Pages JSON regenerated daily, so timestamps lag by up to 24 h.
## Prerequisites
- No browser required — uses `formulae.brew.sh/api/formula/<name>.json`, `formulae.brew.sh/api/cask/<token>.json`, and `formulae.brew.sh/api/analytics/(install|cask-install)/<window>.json`.
+39
View File
@@ -0,0 +1,39 @@
# Huodongxing
**Mode**: 🌐 Public / Browser · **Domain**: `www.huodongxing.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli huodongxing events` | Search Huodongxing events by tag, city, date range, event type, and title keyword |
## Usage Examples
```bash
# AI events across all cities for a date range
opencli huodongxing events --tag AI --city 全部 --date 2026-06-09 --dateTo 2026-06-12
# Offline events only
opencli huodongxing events --tag AI --city 上海 --eventType 1
# Online events only
opencli huodongxing events --eventType 2 --qs Agentic --limit 10
# JSON output
opencli huodongxing events --tag AI --city 北京 -f json
```
## Filters
- `--tag` maps to Huodongxing `tag`
- `--city` maps to Huodongxing `city`
- `--date` maps to Huodongxing `date`
- `--dateTo` maps to Huodongxing `dateTo`
- `--eventType 1` filters offline events
- `--eventType 2` filters online events
- `--qs` filters by event title keyword
## Prerequisites
Chrome running with [Browser Bridge extension](/guide/browser-bridge) installed. Login is not required for public event listings.
+78
View File
@@ -0,0 +1,78 @@
# Hupu (虎扑)
**Mode**: 🌐 Public / 🔐 Browser · **Domain**: `bbs.hupu.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli hupu hot` | Read Hupu hot threads |
| `opencli hupu search <keyword>` | Search Hupu threads by keyword |
| `opencli hupu detail <tid>` | Read one thread and optional hot replies |
| `opencli hupu mentions` | Read replies that mentioned you |
| `opencli hupu reply <tid> <text>` | Reply to a thread or quote one reply |
| `opencli hupu like <tid> <pid>` | Like one reply |
| `opencli hupu unlike <tid> <pid>` | Cancel like on one reply |
## Usage Examples
```bash
# Hot threads
opencli hupu hot --limit 5
# Search threads
opencli hupu search 湖人 --limit 10
# Read one thread and include hot replies
opencli hupu detail 638234927 --replies true
# Read mentions that replied to you
opencli hupu mentions --limit 20
# Reply to the thread
opencli hupu reply 638234927 "hello from opencli" --topic_id 502
# Quote one hot reply by pid
opencli hupu reply 638234927 "replying to this comment" --topic_id 502 --quote_id 174908
# Like / unlike one reply
opencli hupu like 638234927 174908 --fid 4860
opencli hupu unlike 638234927 174908 --fid 4860
# JSON output
opencli hupu detail 638234927 -f json
```
## Notes
- `reply --topic_id` maps to Hupu's API `topicId`, for example `502` for Basketball News
- `reply --quote_id` is the quoted reply `pid`
- `mentions` reads `my.hupu.com` notification APIs from the logged-in browser session
- `like` / `unlike --fid` uses the forum ID from thread metadata
- `detail --replies true` appends top hot replies to the content field
- `hot --limit` is validated upfront: must be a positive integer in `[1, 100]`. Out-of-range or non-integer values raise `ArgumentError` — no silent clamp.
## Output
### `hot`
Reads the public `bbs.hupu.com/` landing page (no login required) via an in-page `querySelectorAll('.t-info')` walk. Replaces a legacy `documentElement.outerHTML` regex that conflated navigation links with thread rows.
| Column | Type | Notes |
|--------|------|-------|
| `rank` | int | 1-based position on the home page |
| `tid` | string | 9-digit hupu thread id; round-trips into `hupu detail <tid>` |
| `title` | string | Thread title from `.t-title`; trimmed |
| `lights` | int \| null | "亮" count (likes-equivalent), `null` if upstream omitted the span; `0` is a real value, never an unknown sentinel |
| `replies` | int \| null | "回复" count, same `null` semantics as `lights`. `万`-suffixed counts are expanded (`1.2万 → 12000`) |
| `forum` | string | Sub-section name (e.g. `步行街主干道`, `NBA湿乎乎的话题`) from the row's `.t-label` link |
| `is_hot` | bool | `true` when hupu tagged the row with `class=" hot"` — exposes hupu's own hot marker; rows are returned in page order regardless |
| `url` | string | Canonical `https://bbs.hupu.com/<tid>.html` |
Empty home page → `EmptyResultError` (the page structure may have changed); never a silent `[]`.
## Prerequisites
- Chrome running and able to open `bbs.hupu.com` and `my.hupu.com`
- [Browser Bridge extension](/guide/browser-bridge) installed
- For `mentions`, `reply`, `like`, and `unlike`, a valid Hupu login session in Chrome is required
+47
View File
@@ -0,0 +1,47 @@
# IMDb
**Mode**: 🌐 Public (Browser) · **Domain**: `www.imdb.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli imdb search` | Search movies, TV shows, and people |
| `opencli imdb title` | Get movie or TV show details |
| `opencli imdb top` | IMDb Top 250 Movies |
| `opencli imdb trending` | IMDb Most Popular Movies |
| `opencli imdb person` | Get actor or director info |
| `opencli imdb reviews` | Get user reviews for a title |
## Usage Examples
```bash
# Search for a movie
opencli imdb search "inception" --limit 10
# Get movie details
opencli imdb title tt1375666
# Get TV series details (also accepts full URL)
opencli imdb title "https://www.imdb.com/title/tt0903747/"
# Top 250 movies
opencli imdb top --limit 20
# Currently trending movies
opencli imdb trending --limit 10
# Actor/director info with filmography
opencli imdb person nm0634240 --limit 5
# User reviews
opencli imdb reviews tt1375666 --limit 5
# JSON output
opencli imdb top --limit 5 -f json
```
## Prerequisites
- Chrome with Browser Bridge extension installed
- No login required (all data is public)
+89
View File
@@ -0,0 +1,89 @@
# Indeed
**Mode**: 🍪 Browser (cookie) · **Domain**: `www.indeed.com`
Indeed sits behind Cloudflare and answers bare HTTP fetches with `403`
and a `cf-mitigated: challenge` header, so the adapter drives a real
browser session. DOM extraction happens against the rendered page.
## Commands
| Command | Description |
|---------|-------------|
| `opencli indeed search <query>` | Keyword job search on the US site |
| `opencli indeed job <jk>` (alias `detail`, `view`) | Read the full job posting by `jk` (job key) |
## Usage Examples
```bash
# Quick start — first run will route through the browser session
opencli indeed search "rust developer" --limit 10
# Narrow to recent jobs in a location, sorted by date
opencli indeed search "site reliability engineer" \
--location "Remote" --fromage 7 --sort date
# Read a job posting using the `id` surfaced by `search`
opencli indeed job dccc07ac5a6a3683
# JSON output
opencli indeed search "data engineer" -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, id, title, company, location, salary, tags, url` |
| `job` | `id, title, company, location, salary, job_type, description, url` |
`id` is the Indeed **job key (jk)** — a 16-character lowercase hex
identifier. Pipe it into `opencli indeed job <jk>` to drill into the full
posting (per the
[listing↔detail ID pairing convention](../../conventions/listing-detail-id-pairing.md)).
## Args
### `search`
| Arg | Type | Default | Notes |
|-----|------|---------|-------|
| `query` *(positional, required)* | string | — | Job title / skill / company |
| `--location` | string | *(none)* | E.g. `"Remote"`, `"New York, NY"` |
| `--fromage` | string | *(none)* | Recency filter, days back: `1` / `3` / `7` / `14` |
| `--sort` | string | `relevance` | `relevance` or `date` |
| `--start` | int | `0` | Pagination offset (multiple of 10, 0-based) |
| `--limit` | int | `15` | Max rows to return (125, capped to one page) |
### `job`
| Arg | Type | Default | Notes |
|-----|------|---------|-------|
| `id` *(positional, required)* | string | — | Job key (16-char lowercase hex from `search`) |
## Prerequisites
Indeed protects the site with Cloudflare. The first run in a fresh
browser session may surface the `Just a moment…` interstitial, in which
case the adapter throws:
```
Indeed served a Cloudflare challenge page
hint: Open https://www.indeed.com in the connected browser and clear the
challenge, then retry.
```
Open the connected browser, complete the human check on `indeed.com` once,
and the cookies will carry forward into subsequent adapter calls
(`Strategy.COOKIE`).
## Limitations
- US site (`www.indeed.com`) only. Indeed runs region-specific subdomains
(`uk.indeed.com`, `de.indeed.com`, ...) — adding them is mostly a
question of swapping the origin and re-checking the DOM selectors.
- Salary parsing pulls the visible text without normalizing currencies or
ranges. Pipe through your own normalizer if you need structured values.
- Tag column is a `·`-joined free-text list (job type, schedule, etc.);
Indeed's metadata pills change wording per A/B bucket so don't expect a
fixed taxonomy.
+65
View File
@@ -0,0 +1,65 @@
# Instagram
**Mode**: 🔐 Browser · **Domain**: `instagram.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli instagram profile` | Get user profile info |
| `opencli instagram search` | Search users |
| `opencli instagram user` | Get recent posts from a user |
| `opencli instagram explore` | Discover trending posts |
| `opencli instagram followers` | List user's followers |
| `opencli instagram following` | List user's following |
| `opencli instagram saved` | Get your saved posts (or one collection) |
| `opencli instagram collection-create` | Create a new saved-posts collection |
| `opencli instagram collection-delete` | Delete a saved-posts collection by name or id |
## Usage Examples
```bash
# View a user's profile
opencli instagram profile nasa
# Search users
opencli instagram search nasa --limit 5
# View a user's recent posts
opencli instagram user nasa --limit 10
# Discover trending posts
opencli instagram explore --limit 20
# List followers/following
opencli instagram followers nasa --limit 20
opencli instagram following nasa --limit 20
# Get your saved posts (default "All posts" feed)
opencli instagram saved --limit 10
# Get posts from a specific collection (case-insensitive name match)
opencli instagram saved --collection inspiration --limit 10
# Create a new saved-posts collection
opencli instagram collection-create "design refs"
# Delete a collection by name (or by numeric id, e.g. 17853899493659567)
opencli instagram collection-delete "design refs"
# JSON output
opencli instagram profile nasa -f json
```
### Notes on collections
- `instagram saved` without `--collection` returns the unsegmented "All posts" bucket (same as the original behaviour).
- With `--collection <name>` it resolves the name to an id via `/api/v1/collections/list/`, then fetches `/api/v1/feed/collection/{id}/posts/`. Match is case-insensitive after trimming. An unknown name throws an error that lists the available names.
- `instagram collection-create <name>` calls `POST /api/v1/collections/create/` with a multipart `name` field. Instagram silently accepts duplicate names — the API just returns a new `collection_id` each time, so dedupe client-side if you care.
- `instagram collection-delete <name-or-id>` calls `POST /api/v1/collections/{id}/delete/`. Pass either a case-insensitive collection name or a numeric `collection_id`. If the name resolves to multiple collections (e.g. duplicates from `collection-create`), the adapter throws and lists the candidate ids so you can disambiguate by passing the id explicitly. Unknown names list the available collections in the error message.
- Saving an existing post directly into a named collection in one shot is not exposed by the web app's documented endpoints (`/api/v1/web/save/{pk}/save/` only writes to "All posts"). Use `instagram save` first, then move the post in the UI, or extend with the `/api/v1/collections/{id}/edit/` mutation.
## Prerequisites
- Chrome running and **logged into** instagram.com
- [Browser Bridge extension](/guide/browser-bridge) installed
+27
View File
@@ -0,0 +1,27 @@
# JD.com
**Mode**: 🔐 Browser · **Domain**: `item.jd.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli jd item <sku>` | Fetch product details (price, shop, specs, AVIF images) |
## Usage Examples
```bash
# Get product details by SKU
opencli jd item 100291143898
# Limit returned AVIF images
opencli jd item 100291143898 --images 5
# JSON output
opencli jd item 100291143898 -f json
```
## Prerequisites
- Chrome running and **logged into** jd.com
- [Browser Bridge extension](/guide/browser-bridge) installed
+42
View File
@@ -0,0 +1,42 @@
# Jianyu
**Mode**: 🔐 Browser · **Domain**: `www.jianyu360.cn`
## Commands
| Command | Description |
|---------|-------------|
| `opencli jianyu search "<query>" --limit <n> [--since_days <n>]` | Search Jianyu bid notices and keep only accessible detail links |
| `opencli jianyu detail "<url>"` | Extract detail-page evidence blocks from a search URL |
## Usage Examples
```bash
# Search by keyword
opencli jianyu search "procurement" --limit 20 -f json
# Search another keyword with an explicit recency window
opencli jianyu search "substation" --limit 10 --since_days 30 -f json
# Extract structured detail evidence
opencli jianyu detail "https://www.jianyu360.cn/nologin/content/....html" -f json
```
## Prerequisites
- Chrome running with an active `jianyu360.cn` session
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- `search` returns accessible procurement rows with `published_at`, `detail_status`, `project_code`, `budget_or_limit`, `url`, plus compatible `publish_time/date`.
- `search` keeps all reachable rows by default. `--since_days` enables an explicit recency filter.
- `detail` returns the same structured fields and adds `detail_text` + `evidence_blocks`.
- Date fields are normalized to `YYYY-MM-DD` when date text is detectable.
- Results are deduplicated by stable notice id when it is available.
- `--limit` defaults to `20` and is capped at `50`.
## Troubleshooting
- If the page shows login/verification prompts, complete it in Chrome and retry.
- If the command returns no valid rows due to noise/navigation pages, it reports taxonomy-style extraction errors instead of silent weak results.
+50
View File
@@ -0,0 +1,50 @@
# 即刻 (Jike)
**Mode**: 🔐 Browser · **Domain**: `web.okjike.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli jike feed` | 即刻首页动态流 |
| `opencli jike search` | 搜索即刻帖子 |
| `opencli jike post` | 帖子详情及评论 |
| `opencli jike topic` | 话题详情 |
| `opencli jike user` | 用户资料 |
| `opencli jike create` | 发布即刻动态 |
| `opencli jike comment` | 评论即刻帖子 |
| `opencli jike like` | 点赞即刻帖子 |
| `opencli jike repost` | 转发即刻帖子 |
| `opencli jike notifications` | 即刻通知 |
## Usage Examples
```bash
# View feed
opencli jike feed --limit 10
# Search posts
opencli jike search "AI" --limit 20
# View post details and comments
opencli jike post <post-id>
# Create a new post
opencli jike create --content "Hello Jike!"
# Like a post
opencli jike like <post-id>
# JSON output
opencli jike feed -f json
```
## Listing Columns
`feed`, `search`, and `user` expose `id` for each post row. Pass that value
directly to `opencli jike post <id>` for the detail view.
## Prerequisites
- Chrome running and **logged into** web.okjike.com
- [Browser Bridge extension](/guide/browser-bridge) installed
+39
View File
@@ -0,0 +1,39 @@
# 即梦AI (Jimeng)
**Mode**: 🔐 Browser · **Domain**: `jimeng.jianying.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli jimeng generate` | 即梦AI 文生图 — 输入 prompt 生成图片 |
| `opencli jimeng history` | 查看生成历史 |
## Usage Examples
```bash
# Generate an image
opencli jimeng generate --prompt "一只在星空下的猫"
# Use a specific model
opencli jimeng generate --prompt "cyberpunk city" --model high_aes_general_v50
# Set custom wait timeout
opencli jimeng generate --prompt "sunset landscape" --wait 60
# View generation history
opencli jimeng history --limit 10
```
### Options (generate)
| Option | Description |
|--------|-------------|
| `--prompt` | Image description prompt (required) |
| `--model` | Model: `high_aes_general_v50` (5.0 Lite), `high_aes_general_v42` (4.6), `high_aes_general_v40` (4.0) |
| `--wait` | Wait seconds for generation (default: 40) |
## Prerequisites
- Chrome running and **logged into** jimeng.jianying.com
- [Browser Bridge extension](/guide/browser-bridge) installed
+72
View File
@@ -0,0 +1,72 @@
# Jira
**Mode**: 🔑 Atlassian REST API · **Domain**: configured with `ATLASSIAN_JIRA_BASE_URL`
Read Jira issues, comments, attachments, and links through Atlassian REST APIs. The adapter supports Jira Cloud and Jira Data Center without driving a browser session.
## Commands
| Command | Description |
|---------|-------------|
| `opencli jira issue <KEY>` | Normalized issue context for agents |
| `opencli jira search <JQL>` | Search issues with JQL |
| `opencli jira comments <KEY>` | Issue comments as Markdown |
| `opencli jira attachments <KEY>` | Issue attachment metadata |
| `opencli jira links <KEY>` | Linked Jira issues |
## Configuration
```bash
export ATLASSIAN_JIRA_BASE_URL=https://example.atlassian.net
export ATLASSIAN_DEPLOYMENT=cloud # cloud | datacenter | auto
export ATLASSIAN_EMAIL=you@example.com
export ATLASSIAN_API_TOKEN=...
```
For Data Center, use a personal access token when available:
```bash
export ATLASSIAN_JIRA_BASE_URL=https://jira.example.com
export ATLASSIAN_DEPLOYMENT=datacenter
export ATLASSIAN_PAT=...
```
Cloud instances default to Jira REST API v3. Data Center instances use Jira REST API v2. `ATLASSIAN_DEPLOYMENT=auto` treats `*.atlassian.net` as Cloud and other hosts as Data Center.
## Usage Examples
```bash
# Full issue context, including description, comments, attachments, and links
opencli jira issue PROJ-123 -f json
# Search with JQL
opencli jira search "project = PROJ order by updated desc" --limit 20 -f json
# Focused reads
opencli jira comments PROJ-123 -f json
opencli jira attachments PROJ-123 -f json
opencli jira links PROJ-123 -f json
```
## Output Notes
- `issue` returns an agent-friendly object with `key`, `summary`, `status`, `priority`, `description.markdown`, `comments`, `attachments`, `linkedIssues`, versions, components, and timestamps.
- Jira Cloud ADF descriptions and comments are converted to Markdown.
- Rendered Jira HTML from Data Center is converted through OpenCLI's Markdown converter.
- Invalid issue keys fail early with `ArgumentError`.
## Custom Fields
Some Jira fields are instance-specific. Set these environment variables to include them in `jira issue` output:
```bash
export ATLASSIAN_JIRA_ACCEPTANCE_FIELD=customfield_12345
export ATLASSIAN_JIRA_SPRINT_FIELD=customfield_10020
export ATLASSIAN_JIRA_STORY_POINTS_FIELD=customfield_10016
```
## Notes
- The adapter only reads Jira data; it does not generate RCA, design docs, or release notes itself.
- Agents should generate documentation from `jira issue ... -f json`, then write it with the Confluence adapter.
- Expected auth, rate-limit, argument, and not-found failures are normalized to `CliError` subclasses.
+55
View File
@@ -0,0 +1,55 @@
# Juejin
**Mode**: 🌐 Public · **Domain**: `api.juejin.cn`
## Commands
| Command | Description |
|---------|-------------|
| `opencli juejin recommend` | Juejin (掘金) homepage recommended article feed |
| `opencli juejin hot` | Juejin (掘金) hot article ranking, optionally scoped to a category |
## Usage Examples
```bash
# Front-page recommendation feed
opencli juejin recommend --limit 10
# Paginate the feed with the next-page cursor returned in the previous batch
opencli juejin recommend --cursor "1718900000000000000" --limit 10
# Hot ranking, default backend category
opencli juejin hot --limit 20
# Hot ranking scoped to AI / frontend
opencli juejin hot --category ai --limit 10
opencli juejin hot --category frontend --limit 10
# Hot ranking by raw category id (the API returned id)
opencli juejin hot --category 6809637773935378440 --limit 5
# JSON output
opencli juejin hot -f json
```
### `recommend` Options
| Option | Description |
|--------|-------------|
| `--limit` | Max articles (1-100, default 20) |
| `--cursor` | Pagination cursor; pass back the previous response's cursor to keep scrolling (default "0") |
Returns rows with `rank, article_id, title, brief, views, likes, comments, author, tags, url, next_cursor, has_more`. The `article_id` round-trips into `https://juejin.cn/post/<id>`. Use `next_cursor` as the next `--cursor` value when `has_more` is `true`.
### `hot` Options
| Option | Description |
|--------|-------------|
| `--category` | Category slug or numeric id. Slugs: `backend`, `frontend`, `android`, `ios`, `ai` (default backend) |
| `--limit` | Max articles (1-50, default 20) |
Returns rows with `rank, article_id, title, brief, views, likes, comments, hot_rank, author, url`.
## Prerequisites
- No browser required; uses public Juejin API endpoints.
+38
View File
@@ -0,0 +1,38 @@
# Ke
**Mode**: 🔐 Browser · **Domain**: `ke.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli ke ershoufang` | Browse second-hand housing listings |
| `opencli ke zufang` | Browse rental listings |
| `opencli ke xiaoqu` | Browse neighborhood / community listings |
| `opencli ke chengjiao` | Browse recent transaction records |
## Usage Examples
```bash
# Beijing second-hand housing
opencli ke ershoufang --city bj --district chaoyang --limit 10
# Rentals in Shanghai
opencli ke zufang --city sh --district pudong --max-price 8000 --limit 10
# Communities in Guangzhou
opencli ke xiaoqu --city gz --district tianhe --limit 10
# Recent transactions in Beijing Haidian
opencli ke chengjiao --city bj --district haidian --limit 10
```
## Prerequisites
- Chrome running and logged into `ke.com`
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- `city` uses short city codes such as `bj`, `sh`, `gz`, `sz`
- `district` expects the district slug used in Beike URLs, for example `chaoyang` or `haidian`
+101
View File
@@ -0,0 +1,101 @@
# Kimi
Drive **Kimi** (`kimi.com`) from the terminal through your existing browser session.
**Mode**: 🔐 Browser · **Domain**: `kimi.com`
## Commands
| Command | Description | Access |
|---------|-------------|--------|
| `opencli kimi status` | Check page connection, login state, and current URL | read |
| `opencli kimi account` | Read sidebar account labels | read |
| `opencli kimi usage` | Read Kimi Code console usage, rate limit, membership, and model permission cards | read |
| `opencli kimi history` | List visible sidebar conversations | read |
| `opencli kimi detail <id>` | Open a chat by ID or trusted `/chat/<id>` URL and read messages | read |
| `opencli kimi read` | Read messages in the current or selected chat | read |
| `opencli kimi send <prompt>` | Send a prompt without waiting for the assistant reply | write |
| `opencli kimi ask <prompt>` | Send a prompt and wait for the assistant reply | write |
| `opencli kimi new` | Start a new chat | write |
| `opencli kimi model` | Read, list, or switch the active model | write |
| `opencli kimi mode [name]` | List or navigate to a Kimi work mode | write |
| `opencli kimi copy-message` | Copy or return the last assistant message | write |
| `opencli kimi react` | Like or dislike the last assistant message | write |
| `opencli kimi regenerate` | Regenerate the last assistant message | write |
| `opencli kimi share` | Open the share dialog for the last assistant message | write |
| `opencli kimi history-rename --yes` | Rename a chat from the history page | write |
| `opencli kimi sidebar-toggle` | Toggle the sidebar | write |
| `opencli kimi view-all-history` | Navigate to the full history page | write |
| `opencli kimi settings` | Open settings | write |
| `opencli kimi sign-out --yes` | Sign out from settings | write |
| `opencli kimi upgrade` | Open the membership/upgrade entry point | write |
| `opencli kimi dismiss-banner` | Close a visible sidebar banner | write |
| `opencli kimi templates` | List template cards on a mode page | read |
| `opencli kimi storage-keys` | List localStorage or sessionStorage keys | read |
| `opencli kimi storage-get <key>` | Read one storage value | read |
| `opencli kimi cookies` | List JavaScript-visible cookies | read |
| `opencli kimi idb-list` | List IndexedDB databases | read |
## Usage Examples
```bash
# Check the current Kimi tab
opencli kimi status
# Read Kimi Code usage cards
opencli kimi usage
# Start a new chat and ask a question
opencli kimi new
opencli kimi ask "Summarize this plan in three bullets"
# Continue the current chat without waiting for a reply
opencli kimi send "Now expand the second bullet"
# List and read conversations
opencli kimi history --limit 10
opencli kimi detail https://kimi.com/chat/<chat-id>
opencli kimi read --conv /chat/<chat-id>
# Inspect or switch model
opencli kimi model
opencli kimi model --list true
opencli kimi model --set "K2"
# Rename a chat only after explicit confirmation
opencli kimi history-rename <chat-id> "New title" --yes true
```
## Options
| Option | Description |
|--------|-------------|
| `prompt` | Prompt to send for `ask` / `send` |
| `--conv` | Chat id, exact `/chat/<id>` path, or trusted `https://kimi.com/chat/<id>` URL for commands that target a chat |
| `--timeout` | Max seconds for `ask` to wait for a reply |
| `--limit` | Max rows for history, read, detail, or storage listings |
| `--set` | Model name to switch to; exact match is preferred, otherwise only a unique partial match is allowed |
| `--list` | Open the model menu and list model options |
| `--yes` | Required for destructive or account-changing commands such as `history-rename` and `sign-out` |
## Behavior
- Kimi commands use a persistent browser site session and operate on the live `kimi.com` UI.
- `usage` navigates to the Kimi Code console and reads the visible dashboard cards without writing account state.
- Chat ids accept bare ids, exact relative `/chat/<id>` paths, or `https://kimi.com/chat/<id>` / `https://www.kimi.com/chat/<id>` URLs only.
- `send` / `ask` verify that a new user turn containing the prompt appears after clicking Send.
- `ask` waits for an assistant turn to appear and stabilize; timeout is reported as a typed timeout instead of a successful row.
- Model switching rejects ambiguous partial matches before clicking and verifies the selected model by reading the UI back.
- `copy-message --click-button` writes to the local clipboard, so the command is marked as write access.
## Prerequisites
- Chrome is running
- You are already signed into `kimi.com`
- [Browser Bridge extension](/guide/browser-bridge) is installed
## Caveats
- This adapter targets the Kimi web UI and can break when Kimi changes DOM structure, labels, or SVG names.
- Sidebar/history commands only see conversations that the current UI has rendered.
- Cookie output is limited to cookies visible to JavaScript; httpOnly cookies are intentionally not exposed.
+56
View File
@@ -0,0 +1,56 @@
# LessWrong
**Mode**: Public · **Domain**: `www.lesswrong.com`
Rationality community and AI alignment research forum.
## Commands
| Command | Description |
|---------|-------------|
| `opencli lesswrong curated` | Editor's picks |
| `opencli lesswrong frontpage` | Algorithmic frontpage feed |
| `opencli lesswrong new` | Latest posts |
| `opencli lesswrong top` | Top rated (all time) |
| `opencli lesswrong top-week` | Top rated this week |
| `opencli lesswrong top-month` | Top rated this month |
| `opencli lesswrong top-year` | Top rated this year |
| `opencli lesswrong read` | Read full post by URL or ID |
| `opencli lesswrong comments` | Top comments on a post |
| `opencli lesswrong user` | User profile |
| `opencli lesswrong user-posts` | List a user's posts |
| `opencli lesswrong tag` | Posts by tag |
| `opencli lesswrong tags` | List popular tags |
| `opencli lesswrong sequences` | Post collections |
| `opencli lesswrong shortform` | Quick takes |
## Usage Examples
```bash
# Browse curated posts
opencli lesswrong curated --limit 5
# Top posts this week
opencli lesswrong top-week --limit 10
# Read a specific post
opencli lesswrong read CzoiqGzpShprcv2Jd
opencli lesswrong read https://www.lesswrong.com/posts/xxx/slug
# Posts tagged "AI"
opencli lesswrong tag ai --limit 5
# User profile and posts
opencli lesswrong user zvi
opencli lesswrong user-posts zvi --limit 5
# Comments on a post
opencli lesswrong comments CzoiqGzpShprcv2Jd --limit 10
# JSON output
opencli lesswrong curated -f json
```
## Prerequisites
- No browser required — uses public LessWrong GraphQL API
+60
View File
@@ -0,0 +1,60 @@
# Lichess
**Mode**: 🌐 Public · **Domain**: `lichess.org`
Look up public Lichess player profiles and per-perf top-N leaderboards. Lichess is a free open-source chess platform; its REST API is fully public and unauthenticated for these read-only endpoints.
## Commands
| Command | Description |
|---------|-------------|
| `opencli lichess user <username>` | Lichess player profile (rating, perfs, win/loss counts) |
| `opencli lichess top <perf>` | Top-N leaderboard for a perf type (bullet/blitz/rapid/classical/...) |
## Usage Examples
```bash
# Player profile
opencli lichess user DrNykterstein
opencli lichess user penguingm1
# Top-N leaderboards (username round-trips into `lichess user`)
opencli lichess top blitz
opencli lichess top bullet --limit 50
opencli lichess top rapid --limit 25
opencli lichess top chess960
```
## Output Columns
| Command | Columns |
|---------|---------|
| `user` | `username, id, title, patron, online, tosViolation, createdAt, seenAt, gamesAll, gamesWin, gamesLoss, gamesDraw, topPerfName, topPerfRating, topPerfGames, fideRating, country, bio, url` |
| `top` | `rank, username, id, title, rating, progress, patron, url` |
The `username` column round-trips from `top` into `user`.
## Options
### `user`
| Option | Description |
|--------|-------------|
| `username` (positional) | Lichess username (case-insensitive, 230 chars, letters/digits/underscore/dash) |
### `top`
| Option | Description |
|--------|-------------|
| `perf` (positional) | Perf type: `ultraBullet`, `bullet`, `blitz`, `rapid`, `classical`, `chess960`, `crazyhouse`, `antichess`, `atomic`, `horde`, `kingOfTheHill`, `racingKings`, `threeCheck` |
| `--limit` | Top-N rows (1200, default: 10) |
## Notes
- **`topPerfName`/`topPerfRating`/`topPerfGames`** picks the perf with the most games played, excluding non-game perfs (`puzzle`, `storm`, `racer`, `streak`). For most active accounts this is `bullet` or `blitz`. For inactive accounts the field surfaces whatever the account played most before going quiet.
- **Closed accounts → `EmptyResultError`.** Lichess marks deleted/closed accounts with `disabled: true` and strips most fields; surfacing a row of nulls would be silent-fallback. We surface as `EmptyResultError` instead so the agent knows the account is gone.
- **`tosViolation`** is `true` when the account has been flagged for cheating / TOS abuse — important when interpreting their rating progression.
- **`progress`** (top only) is the perf's recent rating delta (last 12 games). `null` when not enough recent games to compute.
- **`fideRating` / `country` / `bio`** are user-supplied profile fields; commonly `null` for accounts that haven't filled them in.
- **No API key required.** Lichess throttles anonymous traffic at ~60 req/min per IP; bursts → `CommandExecutionError`.
- **Errors.** Bad username / unknown perf / bad limit → `ArgumentError`; unknown / disabled user → `EmptyResultError`; transport / 429 / non-200 → `CommandExecutionError`.
@@ -0,0 +1,93 @@
# LinkedIn Learning
**Mode**: 🔐 Browser + Cookie · **Domain**: `linkedin.com`
Read-only adapter for LinkedIn Learning courses, videos, and learning paths. Shares cookie session with linkedin.com, no Commercial Use Limit (Learning queries are separate from people-search CUL).
## Commands
| Command | Description |
|---------|-------------|
| `opencli linkedin-learning search` | Search courses, videos, and paths by keyword via `learning-api/searchV2` |
| `opencli linkedin-learning trending` | Browse personalized recommendation carousels via `learning-api/feedRecommendationGroups` |
| `opencli linkedin-learning course` | Course detail by slug or full `/learning/<slug>` URL via `learning-api/courses?q=slug` |
## Usage Examples
```bash
# Search
opencli linkedin-learning search "AI agent"
opencli linkedin-learning search "rust programming" --limit 20
# Personalized recommendations
opencli linkedin-learning trending --limit 10
# Course detail (slug or full URL)
opencli linkedin-learning course agentic-ai-build-your-first-agentic-ai-system
opencli linkedin-learning course https://www.linkedin.com/learning/agentic-ai-build-your-first-agentic-ai-system
# JSON output
opencli linkedin-learning search "data science" -f json
```
## Columns
### `search`
| Column | Notes |
|--------|-------|
| `rank` | 1-based position in upstream order |
| `type` | `COURSE` / `VIDEO` / `LEARNING_PATH` / etc |
| `title` | From `headline.title.text` |
| `instructor` | Joined `firstName lastName` of all authors |
| `difficulty` | `BEGINNER` / `INTERMEDIATE` / etc (uppercase from searchV2) |
| `duration_sec` | Length in seconds (empty if non-SECOND unit) |
| `rating` | Average rating to 2 decimals, computed from `ratingSum/ratingCount` if no `averageRating` |
| `rating_count` | Number of ratings |
| `viewers` | Cumulative viewer count |
| `url` | `https://www.linkedin.com/learning/<slug>` |
### `trending`
| Column | Notes |
|--------|-------|
| `rank` | 1-based across all carousels in document order |
| `group` | Carousel title (e.g. "Top picks for you") or annotation (`TOP_PICKS`) |
| `type` | Same as `search` |
| `title` | Course / video title |
| `difficulty` | Same as `search` |
| `viewers` | Cumulative viewer count |
| `url` | Course URL |
Cards are deduplicated by slug across carousels (first-seen wins).
### `course`
| Column | Notes |
|--------|-------|
| `title` | Course title |
| `slug` | Stable slug used in URL |
| `description` | Full course description returned by `/learning-api/courses?q=slug` |
| `difficulty` | `Beginner` / `Intermediate` / etc (mixed case from detail endpoint) |
| `duration_sec` | Total length in seconds |
| `videos_count` | Number of videos in the course |
| `rating` | Average rating to 2 decimals (empty when `/courses?q=slug` omits ratings; see Caveats) |
| `rating_count` | Number of ratings (empty when omitted) |
| `released` | Activation date (`YYYY-MM-DD`) |
| `url` | `https://www.linkedin.com/learning/<slug>` |
## Prerequisites
- Chrome running with [Browser Bridge extension](/guide/browser-bridge) installed
- Logged in to [linkedin.com](https://linkedin.com); Learning shares the cookie session
## Caveats
- The course-detail endpoint (`/learning-api/courses?q=slug`) does not always include `rating` / `rating_count` even when the `search` endpoint reports them for the same slug. Use `search "<slug words>"` to get ratings if needed; a future revision may make a second call to `/learning-api/reviews?contentUrn=...&q=findByContent` to fill these in.
- `trending` returns personalized recommendations (carousel `annotation: TOP_PICKS` and similar), not a globally-ranked popularity list. The output reflects the logged-in user's recent activity and skills.
- Voyager search-cluster endpoints (used by the standard `linkedin/search` jobs adapter and `linkedin/people-search`) do not serve Learning data; `learning-api/*` is the dedicated REST surface.
## Limit Validation
- `search` and `trending` cap `--limit` at 50 with strict-integer validation (no silent clamp).
- `course` returns exactly one row by definition.
+179
View File
@@ -0,0 +1,179 @@
# LinkedIn
**Mode**: 🔐 Browser · **Domain**: `linkedin.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli linkedin connect` | Send a fail-closed connection request after verifying the exact profile |
| `opencli linkedin inbox` | List LinkedIn messaging inbox conversations and unread status |
| `opencli linkedin job-detail` | Read one LinkedIn job page with description, apply URL, workplace type, applicants, and company metadata |
| `opencli linkedin jobs-preferences` | Read visible LinkedIn Jobs preferences and alert settings without changing them |
| `opencli linkedin people-search` | Search standard LinkedIn for people by keyword (SSR DOM scrape). Each query counts toward LinkedIn's monthly Commercial Use Limit |
| `opencli linkedin profile-analytics` | Read visible profile dashboard counters such as profile views, post impressions, and search appearances |
| `opencli linkedin profile-experience` | Read visible LinkedIn profile experience entries with titles, dates, locations, skills, media, and URLs |
| `opencli linkedin profile-read` | Read visible profile sections including headline, About, experience, education, services, and featured text |
| `opencli linkedin posts` | Export visible posts from a LinkedIn profile activity page with engagement metrics |
| `opencli linkedin post-analytics` | Summarize raw visible LinkedIn post counters without custom scoring or classification |
| `opencli linkedin profile-projects` | Read visible LinkedIn profile projects with descriptions, dates, skills, media, and URLs |
| `opencli linkedin safe-send` | Verify exact recipient/thread context before optionally sending a message |
| `opencli linkedin salesnav-inbox` | List Sales Navigator message conversations with API pagination |
| `opencli linkedin salesnav-message` | Validate or send a Sales Navigator InMail to an exact lead |
| `opencli linkedin salesnav-search` | Search Sales Navigator people leads by keyword |
| `opencli linkedin salesnav-thread` | Return Sales Navigator message history for a thread or lead |
| `opencli linkedin search` | Search LinkedIn jobs (Voyager API), with optional `--details` enrichment |
| `opencli linkedin sent-invitations` | List pending sent LinkedIn invitations |
| `opencli linkedin services-read` | Read a LinkedIn Services page, including overview, services, availability, pricing, and media metadata |
| `opencli linkedin thread-snapshot` | Load a LinkedIn messaging thread and return available context |
| `opencli linkedin timeline` | Read posts from your LinkedIn home feed |
## Usage Examples
```bash
# Quick start
opencli linkedin search --limit 5
# Search with filters
opencli linkedin search "site reliability engineer" --location "San Francisco Bay Area" --remote remote
# Enrich with full description and apply URL (slower; 1 page navigation per row)
opencli linkedin search "data scientist" --limit 3 --details
# Read Jobs preferences and a single job page
opencli linkedin jobs-preferences -f json
opencli linkedin job-detail https://www.linkedin.com/jobs/view/4412279099 -f json
# Read your home timeline
opencli linkedin timeline --limit 5
# Read profile and services data
opencli linkedin profile-read -f json
opencli linkedin profile-analytics -f json
opencli linkedin services-read -f json
# Export visible profile activity posts
opencli linkedin posts --limit 5 -f json
# Summarize raw visible post counters
opencli linkedin post-analytics --limit 5 -f json
# Read visible profile projects
opencli linkedin profile-projects -f json
# Read visible profile experience entries
opencli linkedin profile-experience -f json
# List recent inbox conversations, including unread status
opencli linkedin inbox --limit 20 -f json
# Search for people by keyword (consumes 1 CUL search query)
opencli linkedin people-search "site reliability engineer berlin" --limit 5
# Verify a profile before sending a connection request; add --send to actually send
opencli linkedin connect https://www.linkedin.com/in/example/ --expected-name "Jane Doe" --note "quick note" --send
# Snapshot a thread, then safe-send only if exact recipient/thread context still matches
opencli linkedin thread-snapshot --thread-url https://www.linkedin.com/messaging/thread/abc/ -f json
opencli linkedin safe-send --thread-url https://www.linkedin.com/messaging/thread/abc/ --expected-name "Jane Doe" --message "thanks" --send
# Search Sales Navigator leads and inspect Sales Navigator messages
opencli linkedin salesnav-search "quality manager food manufacturing" --limit 10 -f json
opencli linkedin salesnav-inbox --limit 20 -f json
opencli linkedin salesnav-thread "https://www.linkedin.com/sales/inbox/2-thread" -f json
# Dry-run a Sales Navigator InMail; add --send only after validating the row
opencli linkedin salesnav-message "urn:li:fs_salesProfile:(PROFILE,NAME_SEARCH,TOKEN)" --subject "Quick question" --body "Hello"
# Reconcile pending sent invitations
opencli linkedin sent-invitations -f json
# JSON output
opencli linkedin search -f json
opencli linkedin timeline -f json
```
## Output
### `search`
Always returns: `rank` · `title` · `company` · `location` · `listed` · `salary` · `url`
When `--details` is set, each row additionally has:
| Column | Type | Notes |
|--------|------|-------|
| `description` | string \| null | Full "About the job" body. `null` if upstream had nothing or fetch failed (see `detail_error`). |
| `apply_url` | string \| null | First `apply`-labelled link on the page. `null` if upstream had nothing or fetch failed. |
| `detail_error` | string \| null | `null` on success. Otherwise short reason: `'no url'` (row had no jobId), `'fetch failed: <message>'` (navigation/parse threw), or `'missing description'` (page loaded but body was empty). |
Previously the adapter returned `description: '', apply_url: ''` for both the missing-url path and the silent-catch path — callers couldn't tell upstream gaps apart from fetch failures. The current shape preserves backward compatibility on success and surfaces failures with `null` + a typed reason on `detail_error`. Per-row failures still don't abort the batch.
`--limit` must be between 1 and 100, and `--start` must be a non-negative integer. LinkedIn login/auth walls abort with `AuthRequiredError` instead of being folded into `detail_error`.
### Job preference commands
`jobs-preferences` opens the LinkedIn Jobs page and returns `open_to_work`, `job_titles`, `locations`, `job_alerts`, `preferences_url`, `alerts_url`, and `raw_preferences`. It reads visible settings only and does not change preferences or alerts.
`job-detail` accepts a `https://www.linkedin.com/jobs/view/<id>` URL and returns `title`, `company`, `location`, `workplace_type`, `job_type`, `applicants`, `listed`, `apply_url`, `company_url`, `url`, and `description`. It normalizes the URL to LinkedIn's logged-in job detail surface and combines inline metadata with the rendered description.
### `people-search`
Returns `rank`, `name`, `headline`, `location`, and `profile_url` from the rendered LinkedIn people-search page. `profile_url` is the row identity and must be a stable `/in/<handle>/` LinkedIn profile URL; malformed extraction payloads fail typed instead of being reported as empty results.
`--limit` must be between 1 and 10. LinkedIn login/auth walls abort with `AuthRequiredError`; Commercial Use Limit redirects abort with `CommandExecutionError` because the page no longer contains a trustworthy result list.
### Profile and services commands
`profile-read` opens a profile URL, or `/in/me/` by default, and returns `profile_url`, `name`, `headline`, `location`, `about`, `about_character_count`, `about_skills`, `experience`, `education`, `services`, and `featured`. It reads visible profile sections and fails typed if LinkedIn returns an auth wall. Editor-only fields such as `about_character_count` and `about_skills` are only populated for the default self-profile flow.
`profile-analytics` opens a profile URL, or `/in/me/` by default, and returns visible dashboard counters: `profile_views`, `post_impressions`, `search_appearances`, `followers`, `connections`, plus `raw_analytics`.
`profile-experience` opens a profile URL, or `/in/me/` by default, resolves it to the profile's Experience detail page, and returns visible experience rows: `rank`, `total_count`, `title`, `employment_type`, `company`, `date_range`, `start_date`, `end_date`, `location`, `location_type`, `description`, `skills`, `media`, `urls`, `skill_url`, `media_url`, `profile_url`, and `raw_text`. If the authenticated profile has no visible Experience section, the command returns `EmptyResultError` instead of placeholder rows.
`services-read` accepts either `--services-url` or a profile URL that links to a Services page. It returns `service_url`, `page_title`, `overview`, `availability`, `work_locations`, `pricing`, `services_provided`, `services_count`, `media_count`, `media`, `messages`, and `reviews_visibility`. Owner-only edit/media fields are only populated for the default self-profile flow.
### `posts`
Exports visible rows from a LinkedIn profile activity page. It opens `/in/me/recent-activity/all/` by default, or accepts `--profile-url https://www.linkedin.com/in/<handle>/`.
Returns `rank`, `author`, `posted_at`, `body`, `reactions`, `comments`, `reposts`, `impressions`, `media`, `media_urls`, `url`, and `raw_text`. `media_urls` only includes non-decorative media or external link URLs that LinkedIn exposes in the rendered card; profile photos and reaction sprites are filtered out.
`--limit` must be between 1 and 100. LinkedIn login/auth walls abort with `AuthRequiredError`.
### `post-analytics`
Summarizes raw counters from visible LinkedIn profile activity posts. It opens `/in/me/recent-activity/all/` by default, or accepts `--profile-url https://www.linkedin.com/in/<handle>/`.
Returns `posts_analyzed`, `total_reactions`, `total_comments`, `total_reposts`, `total_impressions`, `posts_with_media`, `posts_with_urls`, `latest_posted_at`, `latest_reactions`, `latest_comments`, `latest_reposts`, `latest_impressions`, and `latest_url`.
This command does not compute custom engagement scores, topic labels, format labels, or recommendations. `--limit` must be between 1 and 100.
### `profile-projects`
Opens a profile URL, or `/in/me/` by default, resolves it to the profile's Projects detail page, and returns visible project rows.
Returns `rank`, `title`, `date_range`, `associated_with`, `description`, `skills`, `media`, `urls`, `profile_url`, and `raw_text`. If the authenticated profile has no visible Projects section, the command returns `EmptyResultError` instead of emitting placeholder rows.
### Messaging commands
`inbox` returns `rank`, `thread_url`, `thread_id`, `person_name`, `last_message_preview`, `unread`, and `timestamp`. It loads the LinkedIn messaging page with your browser session, then reuses the page's own `messengerConversations` API request as the row source instead of scraping the virtualized inbox DOM.
`connect` and `safe-send` are write commands but dry-run by default. They only click LinkedIn write actions when `--send` is explicitly passed. `connect` requires an exact `https://www.linkedin.com/in/<profile>/` URL and verifies the landed profile plus visible name before sending. `safe-send` requires an exact `https://www.linkedin.com/messaging/thread/<id>/` URL and verifies the landed thread, visible recipient name, composer presence, and optional latest-message guard before filling or sending.
`thread-snapshot` opens an exact messaging thread URL, validates `--max-scrolls` before navigation, scrolls for available history, and returns a JSON snapshot suitable for caller-side recipient safety checks.
### Sales Navigator commands
`salesnav-search` uses the Sales Navigator lead search API and returns `rank`, `name`, `title`, `company`, `location`, `degree`, `profile_url`, `lead_url`, and `recipient_urn`. Missing lead identity or malformed API payloads fail typed instead of emitting unaddressable rows.
`salesnav-inbox` and `salesnav-thread` use Sales Navigator messaging APIs rather than virtualized DOM rows. They require a signed-in LinkedIn session with Sales Navigator access; auth/API failures and malformed thread payloads fail typed, while a valid empty inbox/thread is reported as an empty result.
`salesnav-message` is a write command but dry-run by default. It resolves the recipient to a Sales Navigator lead identity, checks profile/credit state, and only sends when `--send` is explicitly passed. Post-send verification checks the Sales Navigator lead page for sent activity.
`sent-invitations` reads the pending invitations page for CRM reconciliation and returns `rank`, `name`, `profile_url`, and `invited_date_text`.
## Prerequisites
- Chrome running and **logged into** linkedin.com
- [Browser Bridge extension](/guide/browser-bridge) installed
+205
View File
@@ -0,0 +1,205 @@
# LINUX DO
**Mode**: 🔐 Browser · **Domain**: `linux.do`
## Commands
| Command | Description |
|---------|-------------|
| `opencli linux-do feed` | Browse topics (site-wide, by tag, or by category) |
| `opencli linux-do categories` | List all categories |
| `opencli linux-do tags` | List popular tags |
| `opencli linux-do search <query>` | Search topics |
| `opencli linux-do topic <id>` | View topic posts |
| `opencli linux-do topic-content <id>` | Read the main topic body as Markdown |
| `opencli linux-do user-topics <username>` | Topics created by a user |
| `opencli linux-do user-posts <username>` | Replies posted by a user |
## feed
Browse topic listings. Defaults to latest topics when called with no arguments.
- Supports filtering by `--tag`, `--category`, or both
- `--tag` accepts tag name, slug, or ID
- `--category` accepts category name, slug, ID, or `Parent / Child` path for sub-categories
- Use `--view` to switch between latest / hot / top
### Basic
```bash
# Latest topics (default)
opencli linux-do feed
# Hot topics
opencli linux-do feed --view hot
# Top topics — default period is weekly
opencli linux-do feed --view top
opencli linux-do feed --view top --period daily
opencli linux-do feed --view top --period monthly
# Sort by views descending
opencli linux-do feed --order views
# Sort by created time ascending
opencli linux-do feed --order created --ascending
# Limit results
opencli linux-do feed --limit 10
# JSON output
opencli linux-do feed -f json
```
### Filter by tag
```bash
# By tag name, slug, or ID — all equivalent
opencli linux-do feed --tag "ChatGPT"
opencli linux-do feed --tag chatgpt
opencli linux-do feed --tag 3
# Tag + hot view
opencli linux-do feed --tag "ChatGPT" --view hot
# Tag + top view with period
opencli linux-do feed --tag "OpenAI" --view top --period monthly
```
### Filter by category
Supports both top-level and sub-categories. Sub-categories auto-resolve their parent path.
```bash
# Top-level category — name, slug, or ID
opencli linux-do feed --category "开发调优"
opencli linux-do feed --category develop
opencli linux-do feed --category 4
# Sub-category
opencli linux-do feed --category "开发调优 / Lv1"
opencli linux-do feed --category "网盘资源"
# Category + hot / top view
opencli linux-do feed --category "开发调优" --view hot
opencli linux-do feed --category "开发调优" --view top --period weekly
```
### Category + tag
Combine `--category` and `--tag` to narrow results within a category.
```bash
opencli linux-do feed --category "开发调优" --tag "ChatGPT"
opencli linux-do feed --category "网盘资源" --tag "OpenAI"
opencli linux-do feed --category 94 --tag 4 --view top --period monthly
```
### Parameters
| Parameter | Description | Default |
|-----------|-------------|---------|
| `--view V` | `latest`, `hot`, `top` | `latest` |
| `--tag VALUE` | Tag name, slug, or ID | — |
| `--category VALUE` | Category name, slug, or ID | — |
| `--limit N` | Number of results | `20` |
| `--order O` | `default`, `created`, `activity`, `views`, `posts`, `category`, `likes`, `op_likes`, `posters` | `default` |
| `--ascending` | Sort ascending instead of descending | off |
| `--period P` | `all`, `daily`, `weekly`, `monthly`, `quarterly`, `yearly` (only with `--view top`) | `weekly` |
Output columns: `title`, `replies`, `created`, `likes`, `views`, `url`
## categories
List forum categories with optional sub-category expansion.
```bash
opencli linux-do categories
opencli linux-do categories --subcategories
opencli linux-do categories --limit 50
```
When `--subcategories` is enabled, sub-categories are rendered as `Parent / Child` so the `name` value can be copied directly into `opencli linux-do feed --category ...`.
Output columns: `name`, `slug`, `id`, `topics`, `description`
## tags
List tags sorted by usage count.
```bash
opencli linux-do tags
opencli linux-do tags --limit 50
```
Output columns: `rank`, `name`, `count`, `url`
## search
Search topics by keyword.
```bash
opencli linux-do search "NixOS"
opencli linux-do search "Docker" --limit 10
opencli linux-do search "Claude" -f json
```
Output columns: `rank`, `title`, `views`, `likes`, `replies`, `url`
## topic
View summarized first-page posts within a topic.
```bash
opencli linux-do topic 1234
opencli linux-do topic 1234 --limit 50
```
Notes:
- `content` is a plain-text summary extracted from each first-page post
- Each summary is truncated to 200 characters
- Use `opencli linux-do topic-content <id>` for the full main post body in Markdown
Output columns: `author`, `content`, `likes`, `created_at`
## topic-content
Read the main topic body as Markdown.
```bash
opencli linux-do topic-content 1234
opencli linux-do topic-content 1234 -f json
```
Notes:
- Default output prints the Markdown body directly for copy/paste or piping into LLMs
- Use `-f json` if you want a machine-readable wrapper
Output columns: `content`
## user-topics
List topics created by a user.
```bash
opencli linux-do user-topics neo
opencli linux-do user-topics neo --limit 10
```
Output columns: `rank`, `title`, `replies`, `created_at`, `likes`, `views`, `url`
## user-posts
List replies posted by a user.
```bash
opencli linux-do user-posts neo
opencli linux-do user-posts neo --limit 10
```
Output columns: `index`, `topic_user`, `topic`, `reply`, `time`, `url`
## Prerequisites
- Chrome running and **logged into** linux.do
- [Browser Bridge extension](/guide/browser-bridge) installed
+50
View File
@@ -0,0 +1,50 @@
# Lobsters
**Mode**: 🌐 Public · **Domain**: `lobste.rs`
## Commands
| Command | Description |
|---------|-------------|
| `opencli lobsters hot` | Hottest stories |
| `opencli lobsters newest` | Latest stories |
| `opencli lobsters active` | Most active discussions |
| `opencli lobsters tag <tag>` | Stories by tag |
| `opencli lobsters domain <domain>` | Stories submitted from a specific source domain |
| `opencli lobsters read <short_id>` | Read a story and its comment tree |
## Usage Examples
```bash
# Quick start
opencli lobsters hot --limit 10
# Filter by tag
opencli lobsters tag rust --limit 5
# Stories from a specific source domain
opencli lobsters domain github.com --limit 10
opencli lobsters domain arxiv.org --limit 5
# Read a specific story (use the short_id surfaced as `id` in any listing)
opencli lobsters read 6cmh6h --limit 25 --depth 2
# JSON output
opencli lobsters hot -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `hot` / `newest` / `active` / `tag` | `rank, id, title, score, author, comments, created_at, tags, url` |
| `domain` | `rank, id, title, score, author, comments, created_at, tags, submission_url, comments_url` |
| `read` | `type, author, score, text` (POST + L0/L1/… comments, with `[+N more replies]` stubs) |
`id` is the lobste.rs `short_id` — pipe it into `read` to drill into the discussion.
`domain` returns both `submission_url` (the underlying article URL on the source site) and `comments_url` (the lobste.rs discussion page). The legacy listing commands collapse these into a single `url` (= `comments_url`).
## Prerequisites
None — all commands use the public JSON API, no browser or login required.
+53
View File
@@ -0,0 +1,53 @@
# Maimai (脉脉)
**Mode**: 🔐 Browser · **Domain**: `maimai.cn`
## Commands
| Command | Description |
|---------|-------------|
| `opencli maimai search-talents` | Search Maimai talent profiles with keyword and structured filters |
## Usage Examples
```bash
# Search by keyword
opencli maimai search-talents Java
# Narrow by company and city
opencli maimai search-talents 产品经理 --companies "阿里巴巴,字节跳动" --cities 北京市
# Filter by school, degree, and work years
opencli maimai search-talents 算法 --schools "北京大学,清华大学" --degrees 3 --worktimes 3
# Prioritize recently active candidates
opencli maimai search-talents 运营 --sortby 1 --is_direct_chat 1
# JSON output for downstream processing
opencli maimai search-talents Java --size 10 -f json
```
## Key Filters
- `--positions`: filter by role or title
- `--companies`: comma-separated current or historical companies
- `--schools`: comma-separated school names
- `--provinces` / `--cities`: location filters
- `--worktimes`: `1=1-3y`, `2=3-5y`, `3=5-10y`, `4=10+y`
- `--degrees`: `1=大专`, `2=本科`, `3=硕士`, `4=博士`, `5=MBA`
- `--professions`: industry codes such as `01=互联网`, `02=金融`
- `--is_211` / `--is_985`: set to `1` to require those school tiers
- `--sortby`: `0=relevance`, `1=activity`, `2=work_years`, `3=education`
- `--is_direct_chat`: set to `1` to keep only candidates available for direct chat
## Prerequisites
- Chrome running and **logged into** `maimai.cn`
- The logged-in browser should be able to open `https://maimai.cn/ent/talents/discover/search_v2`
- [Browser Bridge extension](/guide/browser-bridge) installed
## Notes
- `page` is zero-based, so the first page is `--page 0`
- Output includes current company plus a deduplicated `historical_companies` field from work experience
- If the command reports login failure, first verify the same Chrome profile can access the talent search page directly
+54
View File
@@ -0,0 +1,54 @@
# manus
Adapter for [Manus](https://manus.im) — the "Hands On AI" autonomous agent web app at `manus.im/app`.
## Auth
Cookie-mode. After the user signs in to `https://manus.im/app` in the Browser Bridge profile, the `session_id` cookie carries a JWT that the adapter re-uses as a Bearer token when calling Manus's Connect-RPC backend at `https://api.manus.im/`.
## Commands
| Command | Description |
|---|---|
| `manus status` | Account snapshot — email, display name, user ID, membership tier, and headline credit numbers. |
| `manus list [--limit N] [--archived]` | List recent Manus sessions with round-trippable `id` values. Hides archived sessions unless `--archived` is passed. Default `--limit 20`. |
| `manus read <uid>` | Show full field-level detail for a single session (looked up by the `id` emitted from `manus list`). |
| `manus credits` | Full credit breakdown — total / free / periodic / pro monthly / refresh / max refresh / next refresh / interval. |
| `manus connectors [--limit N]` | List available Manus connectors (Apify, GitHub, Outlook, Slack, …). Default `--limit 50`. |
| `manus skills` | List skills, both user-added (`source=user`) and system (`source=system`). |
## Examples
```
$ opencli manus status
Field: Email Value: zhongyuelin990405@gmail.com
Field: Display Name Value: Lin Zhongyue
Field: Membership Tier Value: 60
Field: Total Credits Value: 12311
Field: Periodic Credits Value: 12000
Field: Refresh Credits Value: 300
$ opencli manus list --limit 3
id: 8UcpCxMFLrNk63ZJmzALfV Title: 制作技术方案路演风格PPT的详细要求 Status: stopped
id: YOpdpcVj7vPFD4gsBfEwVu Title: Defining Empire: … Status: stopped
$ opencli manus read 8UcpCxMFLrNk63ZJmzALfV
Field: UID Value: 8UcpCxMFLrNk63ZJmzALfV
Field: Title Value: 制作技术方案路演风格PPT的详细要求
Field: Status Value: SESSION_STATUS_STOPPED
Field: Mode Value: AGENT_TASK_MODE_HIGH_EFFORT
Field: Credits Value: 4564
```
## Notes
- Implementation is API-first: every command issues exactly one Connect-RPC POST against `api.manus.im` instead of scraping the DOM, so it is resilient to UI re-skins.
- The CLI surface intentionally excludes destructive / state-changing actions (new task submission, chat replies, archive, delete). Manus's `/app` route is a pure React SPA with no per-session URL — there is no `/app/session/<uid>` page — so there is no verifiable post-state for those operations to assert against. They are deliberately out of scope until the Manus team exposes a per-session route or confirmation dialog.
- `manus read <uid>` calls `ListSessions` with `pageSize=100` and filters in-process. If the matching session lives beyond the first 100 most-recent sessions, the command will report it as not found.
- `Status` and `Mode` are returned as the raw RPC enum strings (`SESSION_STATUS_STOPPED`, `AGENT_TASK_MODE_HIGH_EFFORT`, …). `Membership Tier` is the numeric tier code (e.g. `60`).
## NOT exposed
- `manus open <uid>``/app/session/<uid>` returns 404; the SPA has no URL routing for individual sessions.
- `manus new-task <prompt>`, `manus chat <uid> <message>`, `manus pause/resume/cancel <uid>` — destructive state mutations whose effect cannot be verified from a stable post-state (URL never changes, no confirmation dialog).
- `manus delete <uid>` / `manus archive <uid>` — same reasoning; no confirmation dialog and no URL-anchored post-state.
+66
View File
@@ -0,0 +1,66 @@
# Maven Central
**Mode**: 🌐 Public · **Domain**: `search.maven.org`
Search Maven Central artifacts and pull per-artifact version histories without auth or browser. Two commands.
## Commands
| Command | Description |
|---------|-------------|
| `opencli maven search <query>` | Search Maven Central by keyword (artifact name, groupId, tag) |
| `opencli maven artifact <coordinate>` | Version history for `groupId:artifactId[:version]` |
## Usage Examples
```bash
# Free-text search
opencli maven search jackson --limit 10
opencli maven search "ai.koog" --limit 5
# Version history for a specific artifact (use `coordinate` from search rows)
opencli maven artifact com.fasterxml.jackson.core:jackson-databind --limit 10
opencli maven artifact com.google.guava:guava --limit 5
# Pin to a specific version
opencli maven artifact com.google.guava:guava:33.0.0-jre
# JSON output
opencli maven search jackson -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, coordinate, groupId, artifactId, latestVersion, packaging, versions, lastPublished, repository, url` |
| `artifact` | `groupId, artifactId, version, packaging, publishedAt, tags, url` |
The `coordinate` column from `search` round-trips into `artifact` exactly. To pin a single version, append `:<version>`.
## Options
### `maven search`
| Option | Description |
|--------|-------------|
| `query` (positional) | Free-text query |
| `--limit` | Max artifacts (1-200, default: 30) |
### `maven artifact`
| Option | Description |
|--------|-------------|
| `coordinate` (positional) | `groupId:artifactId` or `groupId:artifactId:version` |
| `--limit` | Max versions (1-200, default: 20). Ignored when `version` is pinned. |
## Caveats
- Coordinates are validated upfront — `groupId` and `artifactId` must be `[A-Za-z0-9][A-Za-z0-9._-]*` (max 200 chars each). Bad input raises `ArgumentError`.
- `lastPublished` / `publishedAt` are derived from Solr's epoch-ms `timestamp` and rendered as second-precision `YYYY-MM-DDTHH:MM:SSZ`.
- Maven Central throttles bursts; `HTTP 429` surfaces as a typed `CommandExecutionError` with a retry hint.
- `versions` (in `search`) is the count Solr reports — it includes pre-releases as well as stable versions.
## Prerequisites
- No browser required — uses `search.maven.org/solrsearch/select` (Solr endpoint).
+55
View File
@@ -0,0 +1,55 @@
# MDN Web Docs
**Mode**: 🌐 Public · **Domain**: `developer.mozilla.org`
Search the official Mozilla Developer Network web docs without auth or browser. One command.
## Commands
| Command | Description |
|---------|-------------|
| `opencli mdn search <query>` | Search MDN Web Docs by keyword |
## Usage Examples
```bash
# Web platform feature search
opencli mdn search fetch --limit 10
opencli mdn search flexbox --limit 5
# JS reference lookups
opencli mdn search "Array.prototype.map"
# Localized search (default: en-US)
opencli mdn search fetch --locale ja --limit 5
opencli mdn search fetch --locale zh-CN --limit 5
# JSON output
opencli mdn search fetch -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, title, slug, locale, summary, url` |
The `slug` column round-trips into MDN's URL space (`https://developer.mozilla.org/<locale>/docs/<slug>`).
## Options
| Option | Description |
|--------|-------------|
| `query` (positional) | Free-text query |
| `--limit` | Max results (150, default: 10) |
| `--locale` | Doc locale (default: `en-US`). Allowed: `en-US`, `de`, `es`, `fr`, `ja`, `ko`, `pt-BR`, `ru`, `zh-CN`, `zh-TW`. |
## Caveats
- Only the locales MDN actually publishes are accepted; passing anything else raises `ArgumentError`.
- The `summary` field is MDN's pre-computed search excerpt with whitespace collapsed; it is **not** the full document body.
- MDN throttles aggressive bursts; `HTTP 429` surfaces as a typed `CommandExecutionError` with a retry hint.
## Prerequisites
- No browser required — uses `developer.mozilla.org/api/v1/search`.
+45
View File
@@ -0,0 +1,45 @@
# Medium
**Mode**: 🌗 Mixed · **Domain**: `medium.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli medium feed` | Get hot Medium posts, optionally scoped to a topic |
| `opencli medium search` | Search Medium posts by keyword |
| `opencli medium user` | Get recent articles by a user |
| `opencli medium tag <tag>` | Latest articles for a Medium tag (public RSS, no browser) |
## Usage Examples
```bash
# Get the general Medium feed
opencli medium feed --limit 10
# Search posts by keyword
opencli medium search ai
# Get articles by a user
opencli medium user @username
# Topic feed as JSON
opencli medium feed --topic programming -f json
# Latest articles for a tag (public RSS — fastest, no browser)
opencli medium tag programming --limit 10
opencli medium tag artificial-intelligence --limit 20
```
## `tag` columns
`rank, title, author, description, categories, published, url`
- `description` is the full RSS `<description>` (no silent truncation; pipe through `head` if you want a preview).
- `categories` is comma-joined Medium tags from each item's `<category>` blocks.
- `published` is the original `pubDate` ISO string when available.
## Prerequisites
- `opencli medium search` and `opencli medium tag` can run without a browser (the latter parses `medium.com/feed/tag/<tag>` RSS)
- `opencli medium feed` and `opencli medium user` require Browser Bridge access to `medium.com`
+167
View File
@@ -0,0 +1,167 @@
# Mercury
**Mode**: 🔐 Browser · **Domain**: `app.mercury.com`
Mercury reimbursements are authenticated browser UI flows. There is no public
API and no stable JSON endpoint for creating an expense, so the adapter drives
the visible Mercury reimbursements page through OpenCLI Browser Bridge. It
creates a **draft**, uploads a local receipt file, waits for Mercury OCR, then
re-applies the agent-provided fields because OCR can overwrite amount, currency,
date, or merchant.
The write command is deliberately conservative: it stops at Mercury's Review
step and never clicks the final `Submit expense` button. A human or responsible
agent must inspect the Review page before any final submission.
## Commands
| Command | Description |
|---------|-------------|
| `opencli mercury reimbursement-plan` | Validate a reimbursement payload locally without opening Mercury |
| `opencli mercury check-login` | Open Mercury reimbursements and report whether the selected browser profile is logged in |
| `opencli mercury reimbursement-draft` | Create a reimbursement draft, attach the receipt, correct OCR-overwritten fields, and stop at Review |
`reimbursement-plan` and `reimbursement-draft` take the same business payload:
| Flag | Meaning |
|------|---------|
| `--receipt` | Absolute or relative path to a local receipt/proof file |
| `--amount` | Original-currency positive amount, e.g. `140.00` |
| `--currency` | Original currency code, default `CNY` |
| `--date` | Expense date as `YYYY-MM-DD` |
| `--merchant` | Merchant name to show in Mercury |
| `--category` | Mercury expense category, default `Marketing & Advertising` |
| `--notes` | Business purpose / reimbursement notes |
| `--ocr-wait-seconds` | Seconds to wait after receipt upload before reapplying fields, default `8` |
| `--close-after-review` | Close Review after verification; still never submits |
## Agent Workflow
```bash
# 1. Confirm the selected browser profile is logged into Mercury
opencli --profile <profile> mercury check-login -f json
# 2. Validate the payload locally first
opencli mercury reimbursement-plan \
--receipt /absolute/path/to/receipt.png \
--amount 140.00 \
--currency CNY \
--date 2026-06-26 \
--merchant "Example Merchant" \
--category "Marketing & Advertising" \
--notes "Example business purpose." \
-f json
# 3. Create the draft and stop at Review
opencli --profile <profile> mercury reimbursement-draft \
--receipt /absolute/path/to/receipt.png \
--amount 140.00 \
--currency CNY \
--date 2026-06-26 \
--merchant "Example Merchant" \
--category "Marketing & Advertising" \
--notes "Example business purpose." \
-f json
```
## Expected Results
For `check-login`:
- `status: "ready"` means the profile reached Mercury reimbursements.
- `status: "needs_login"` means Mercury redirected to login; sign into Mercury
in that Chrome/OpenCLI profile and rerun.
For `reimbursement-plan`:
- `status: "ready"` means the local receipt exists and amount/date formats are
valid.
- Missing receipt files, non-positive amount strings, malformed currency codes,
invalid calendar dates, or invalid wait/boolean flags fail before Mercury is
opened.
- Output uses the receipt basename, not the absolute local path.
For `reimbursement-draft`:
- `uploaded: true`
- `reviewReady: true`
- `submitBlocked: true`
- `warnings` includes `final Submit expense was intentionally not clicked`
- Mercury shows the Review step with the expected receipt, amount, currency,
date, merchant, category, and notes.
If upload confirmation, required field correction, or the Review postcondition
fails, the command throws a typed error instead of returning a partial success
row. Keep the browser open and inspect Mercury for validation errors.
## Testing
Run repository-level checks:
```bash
npm run dev -- validate mercury
npm run typecheck
npm run docs:build
```
Run a local input smoke test:
```bash
npm run dev -- mercury reimbursement-plan \
--receipt /tmp/example-receipt.png \
--amount 1.00 \
--currency USD \
--date 2026-06-30 \
--merchant "OpenCLI Test Merchant" \
--category "Office Supplies & Equipment" \
--notes "OpenCLI adapter smoke test; do not submit." \
-f json
```
Run a real UI smoke test only in a test Mercury workspace/profile or with a
harmless test receipt:
```bash
npm run dev -- --profile <profile> mercury reimbursement-draft \
--receipt /absolute/path/to/test-receipt.png \
--amount 1.00 \
--currency USD \
--date 2026-06-30 \
--merchant "OpenCLI Test Merchant" \
--category "Office Supplies & Equipment" \
--notes "OpenCLI adapter smoke test; do not submit." \
-f json
```
Pass condition: Mercury stops at Review and the returned row has
`submitBlocked: true`. Do not click final Submit during smoke tests.
## Notes
- **Login is required.** This adapter uses the selected OpenCLI browser profile;
it does not store Mercury credentials or run an OAuth/login flow.
- **Receipt upload** targets Mercury's attachment input:
`[data-testid="expense-attachment-upload"]`. If Mercury changes that selector,
upload can fail while the rest of the form remains visible.
- **OCR happens before correction.** Mercury OCR can misread currency (for
example `CNY` as `JPY`) or overwrite merchant/amount. The command uploads the
receipt first, waits, then re-fills fields from the CLI arguments.
- **Review is not submission.** `reimbursement-draft` never presses the final
`Submit expense` button. It prepares a draft for inspection.
- **Use original currency.** Enter the currency shown on the source receipt
when Mercury supports it, then verify Mercury's converted reimbursement amount
on the Review page.
- **Output is intentionally compact.** The returned row is a control-plane
status summary; Mercury remains the source of truth for final visual review.
## Troubleshooting
- `needs_login`: open Mercury in the same Chrome/OpenCLI profile, finish login,
then rerun `check-login`.
- Upload failure: verify the file exists locally and that Mercury still uses the
receipt input selector above. The command requires Browser Bridge
`uploadFiles` support so it can verify the intended file input.
- Review failure: inspect Mercury for validation errors; the command may have
uploaded the receipt and filled fields but failed to reach Review.
- Category did not commit: custom Mercury dropdowns can be sensitive to UI
changes. Retry with the exact category label visible in Mercury.
+61
View File
@@ -0,0 +1,61 @@
# 幕布 (Mubu)
**Mode**: 🔐 Browser · **Domain**: `mubu.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli mubu doc` | 读取文档内容(Markdown / 纯文本) |
| `opencli mubu docs` | 列出文档和文件夹 |
| `opencli mubu notes` | 读取速记(今日 / 指定日期范围) |
| `opencli mubu recent` | 最近编辑的文档 |
| `opencli mubu search` | 全文搜索文档节点 |
## Usage Examples
```bash
# Read a document in Markdown (default)
opencli mubu doc <doc-id>
# Read a document as plain text
opencli mubu doc <doc-id> --output text
# List documents in root folder
opencli mubu docs
# List starred (quick-access) documents
opencli mubu docs --starred
# List documents in a specific folder
opencli mubu docs --folder <folder-id>
# Read today's daily notes
opencli mubu notes
# Read notes for a specific date
opencli mubu notes --date 2026-04-10
# Read notes for an entire month
opencli mubu notes --month 2026-04
# List note dates with entry counts (no content)
opencli mubu notes --list --month 2026-04
# Read notes for a custom date range
opencli mubu notes --from 2026-01-01 --to 2026-03-31
# Show recently edited documents
opencli mubu recent --limit 10
# Full-text search
opencli mubu search "关键词"
# JSON output
opencli mubu docs -f json
```
## Prerequisites
- Chrome running and **logged into** mubu.com
- [Browser Bridge extension](/guide/browser-bridge) installed
+86
View File
@@ -0,0 +1,86 @@
# NotebookLM
**Mode**: 🔐 Browser Bridge · **Domain**: `notebooklm.google.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli notebooklm status` | Check whether NotebookLM is reachable in the current Chrome session |
| `opencli notebooklm list` | List notebooks visible from the NotebookLM home page |
| `opencli notebooklm open <notebook>` | Open one notebook in the NotebookLM adapter session by id or URL |
| `opencli notebooklm current` | Show metadata for the currently opened notebook in the adapter session |
| `opencli notebooklm get` | Get richer metadata for the current notebook |
| `opencli notebooklm source-list` | List sources in the current notebook |
| `opencli notebooklm source-get <source>` | Resolve one source in the current notebook by id or title |
| `opencli notebooklm source-fulltext <source>` | Fetch extracted source fulltext through NotebookLM RPC |
| `opencli notebooklm source-guide <source>` | Fetch guide summary and keywords for one source |
| `opencli notebooklm history` | List conversation history threads for the current notebook |
| `opencli notebooklm note-list` | List Studio notes visible in the current notebook |
| `opencli notebooklm notes-get <note>` | Read the currently visible Studio note by title |
| `opencli notebooklm summary` | Read the current notebook summary |
| `opencli notebooklm create <title> --execute` | Create a new NotebookLM notebook |
| `opencli notebooklm add-source <notebook> (--url <url> \| --content <text> \| --file <path>) --execute` | Add one source to an existing notebook |
| `opencli notebooklm write-note <notebook> --title <title> --content <markdown> --execute` | Create a Studio note in a notebook |
| `opencli notebooklm generate-audio <notebook> --execute` | Trigger Audio Overview generation for a notebook |
| `opencli notebooklm generate-slides <notebook> --execute` | Trigger slide deck generation for a notebook |
## Compatibility Aliases
| Alias | Canonical command |
|-------|-------------------|
| `opencli notebooklm select <notebook>` | `opencli notebooklm open <notebook>` |
| `opencli notebooklm metadata` | `opencli notebooklm get` |
| `opencli notebooklm notes-list` | `opencli notebooklm note-list` |
## Positioning
This adapter reuses the existing OpenCLI Browser Bridge runtime:
- no custom NotebookLM extension
- no exported cookie replay
- requests and page state stay in the real Chrome session
Read commands expose NotebookLM metadata, sources, notes, summaries, and history from desktop Chrome with an already logged-in Google account. Write commands call NotebookLM's in-page RPC endpoints from that same logged-in browser session and require an explicit `--execute` flag before any remote mutation is attempted.
## Usage Examples
```bash
opencli notebooklm status
opencli notebooklm list -f json
opencli notebooklm open nb-demo -f json
opencli notebooklm current -f json
opencli notebooklm get -f json
opencli notebooklm source-list -f json
opencli notebooklm source-get "Quarterly report" -f json
opencli notebooklm source-guide "Quarterly report" -f json
opencli notebooklm source-fulltext "Quarterly report" -f json
opencli notebooklm history -f json
opencli notebooklm note-list -f json
opencli notebooklm notes-get "Draft note" -f json
opencli notebooklm summary -f json
# Write commands refuse to mutate unless --execute is present.
opencli notebooklm create "Research Brief" --emoji "📒" --execute
opencli notebooklm add-source 17e2b882-6a01-4c6c-9262-0738dfa2abee --url https://example.com/report --execute
opencli notebooklm add-source 17e2b882-6a01-4c6c-9262-0738dfa2abee --content "Source text" --title "Pasted source" --execute
opencli notebooklm add-source 17e2b882-6a01-4c6c-9262-0738dfa2abee --file ./paper.pdf --execute
opencli notebooklm write-note 17e2b882-6a01-4c6c-9262-0738dfa2abee --title "Open questions" --content "## Next steps" --execute
opencli notebooklm generate-audio 17e2b882-6a01-4c6c-9262-0738dfa2abee --execute
opencli notebooklm generate-slides 17e2b882-6a01-4c6c-9262-0738dfa2abee --length 3 --language en --execute
```
## Prerequisites
- Chrome running and logged into Google / NotebookLM
- [Browser Bridge extension](/guide/browser-bridge) installed
- NotebookLM accessible in the current browser session
## Notes
- Notebook-oriented commands run in OpenCLI's owned NotebookLM adapter session/window. Use `opencli notebooklm open <notebook>` first to choose the current notebook for follow-up commands.
- `list`, `get`, `source-list`, `history`, `source-fulltext`, and `source-guide` prefer NotebookLM RPC paths and fall back only when the richer path is unavailable.
- `notes-get` currently reads note content only from the visible Studio note editor; if the note is listed but not open, open it in NotebookLM first and then retry.
- All NotebookLM write commands require `--execute` and fail before opening a browser/RPC write path when it is absent.
- Write commands accept a bare notebook UUID or a canonical `https://notebooklm.google.com/notebook/<uuid>` URL. Off-domain, non-HTTPS, credentialed, or custom-port notebook URLs are rejected.
- `add-source` accepts exactly one source input: `--url`, `--content`, or `--file`.
+63
View File
@@ -0,0 +1,63 @@
# 牛客网 (Nowcoder)
**Mode**: 🌐 / 🔐 · **Domain**: `nowcoder.com`
## Commands
| Command | Description |
|---------|-------------|
| `opencli nowcoder hot` | Hot search ranking |
| `opencli nowcoder trending` | Trending posts |
| `opencli nowcoder topics` | Hot discussion topics |
| `opencli nowcoder recommend` | Recommended feed |
| `opencli nowcoder creators` | Top content creators leaderboard |
| `opencli nowcoder companies` | Hot companies for interview prep |
| `opencli nowcoder jobs` | Career category listing |
| `opencli nowcoder search <query>` | Full-text search (type: all/post/question/user/job) |
| `opencli nowcoder suggest <query>` | Search suggestions |
| `opencli nowcoder experience` | Interview experience posts |
| `opencli nowcoder referral` | Internal referral posts |
| `opencli nowcoder salary` | Salary disclosure posts |
| `opencli nowcoder papers` | Interview question bank by company & job |
| `opencli nowcoder practice` | Categorized practice questions with progress |
| `opencli nowcoder notifications` | Unread message summary |
| `opencli nowcoder detail <id>` | Post detail view (supports ID / UUID / URL) |
## Usage Examples
```bash
# Hot search ranking
opencli nowcoder hot --limit 10
# Search for interview experiences
opencli nowcoder search "bilibili" --type post --limit 5
# Search suggestions
opencli nowcoder suggest "java"
# Browse interview experience posts
opencli nowcoder experience --limit 10
# View a specific post detail (using UUID from list commands)
opencli nowcoder detail 2b6b64d4adb34ea3838e832ae4447ab1
# Interview question bank for Java at Huawei
opencli nowcoder papers --job 11002 --company 239
# Practice questions for software development
opencli nowcoder practice --job 11226 --limit 10
# Hot companies for C++ positions
opencli nowcoder companies --job 11003
# JSON output
opencli nowcoder trending -f json
# Verbose mode
opencli nowcoder hot -v
```
## Prerequisites
- **Public commands** (hot, trending, topics, recommend, creators, companies, jobs): No login required
- **Cookie commands** (all others): Chrome running and **logged into** nowcoder.com, [Browser Bridge extension](/guide/browser-bridge) installed
+79
View File
@@ -0,0 +1,79 @@
# npm
**Mode**: 🌐 Public · **Domain**: `registry.npmjs.org` (+ `api.npmjs.org` for download stats)
Search and inspect packages on the public npm registry without auth or browser. Three commands cover discovery, single-package metadata, and download stats.
## Commands
| Command | Description |
|---------|-------------|
| `opencli npm search <query>` | Search the public npm registry by keyword |
| `opencli npm package <name>` | Single-package registry metadata (latest version, license, repo, maintainers) |
| `opencli npm downloads <name>` | Download stats for one package over a fixed period or `YYYY-MM-DD:YYYY-MM-DD` range |
## Usage Examples
```bash
# Search the registry
opencli npm search react --limit 10
opencli npm search "graphql client" --limit 20
# Inspect a single package (use `name` from search rows)
opencli npm package react
opencli npm package @vercel/og
# Download stats for a fixed period
opencli npm downloads react --period last-week
opencli npm downloads react --period last-month
opencli npm downloads react --period last-year
# Custom date range (max 365 days, npm API limit)
opencli npm downloads react --period 2025-01-01:2025-01-31
# JSON output
opencli npm package react -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, name, version, description, weeklyDownloads, dependents, license, publisher, updated, url` |
| `package` | `name, latestVersion, description, license, homepage, repository, bugs, maintainers, keywords, created, modified, url` |
| `downloads` | `rank, package, day, downloads` (range) or `rank, package, day, downloads` for fixed periods (single row, `day` = `last-week:start..end`) |
The `name` column from `search` round-trips into `package` and `downloads`.
## Options
### `search`
| Option | Description |
|--------|-------------|
| `query` (positional) | Free-text query (matches name / description / keywords / readme) |
| `--limit` | Max results (1250, default: 20) |
### `package`
| Option | Description |
|--------|-------------|
| `name` (positional) | npm package name (e.g. `react`, `@vercel/og`). Validates 1214 chars and the npm naming rule. |
### `downloads`
| Option | Description |
|--------|-------------|
| `name` (positional) | npm package name |
| `--period` | One of `last-day`, `last-week`, `last-month`, `last-year`, **or** a `YYYY-MM-DD:YYYY-MM-DD` range (default: `last-week`) |
## Caveats
- The `--period` argument is validated upfront — anything that's neither one of the four named periods nor a valid `YYYY-MM-DD:YYYY-MM-DD` range raises `ArgumentError` (no silent fallback).
- npm rate-limits the search and download APIs; `HTTP 429` surfaces as a typed `CommandExecutionError` with a retry hint.
- Download stats are intentionally a separate command from `package`. If the stats endpoint fails, the registry-metadata response from `package` is unaffected.
- The package-name regex matches `^(?:@scope\/)?name$` (lowercase letters / digits / `._-`), capped at 214 chars per npm's spec.
## Prerequisites
- No browser required — uses public registry endpoints.
+61
View File
@@ -0,0 +1,61 @@
# NuGet
**Mode**: 🌐 Public · **Domain**: `api.nuget.org`
Search the NuGet package index by keyword and fetch full version history for a package id. NuGet is the canonical .NET package registry; both endpoints are public V3 JSON.
## Commands
| Command | Description |
|---------|-------------|
| `opencli nuget search <query>` | Search NuGet packages by keyword |
| `opencli nuget package <id>` | Full NuGet package version history (catalog entries) |
## Usage Examples
```bash
# Keyword search
opencli nuget search newtonsoft
opencli nuget search "asp.net core" --limit 10
opencli nuget search serilog --prerelease=true
# Full version history (id round-trips from search)
opencli nuget package Newtonsoft.Json
opencli nuget package Serilog
opencli nuget package Microsoft.Extensions.Logging
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, id, version, title, description, authors, tags, totalDownloads, verified, projectUrl, url` |
| `package` | `rank, id, version, title, authors, tags, language, licenseExpression, projectUrl, published, listed, url` |
The `id` column round-trips between commands.
## Options
### `search`
| Option | Description |
|--------|-------------|
| `query` (positional) | Search keyword |
| `--limit` | Max packages (11000, default: 20) — NuGet's max page size is 1000 |
| `--prerelease` | Include prerelease versions (default: `false`) |
### `package`
| Option | Description |
|--------|-------------|
| `id` (positional) | NuGet package id (case-insensitive). Allowed: 1100 chars of letters/digits/`.`/`_`/`-`, must start with letter or digit. |
## Notes
- **`package` returns the full version history**, newest-first (sorted by `published` desc, ties broken by version string desc). Each row is one published release. NuGet's CDN paginates internally; the adapter walks pages so even 100+ version histories come back in one call.
- **`listed` flag**: when `false`, the version was unlisted by the publisher (still installable by exact pin, but hidden from search). `null` when NuGet didn't include the field (rare, very old packages).
- **`verified` (search only)**: NuGet's "verified publisher" badge — packages signed by a verified org. Useful for filtering hostile typo-squats.
- **`totalDownloads`** is a single global counter; it does NOT split per-version. For per-version downloads NuGet exposes a different endpoint we don't surface here.
- **`tags` / `authors`** are comma-joined; raw shape is space-separated tags + JSON author array, normalised to consistent comma joins.
- **No API key required.** NuGet's V3 service index is public; no rate limit doc but bursts → `CommandExecutionError`.
- **Errors.** Bad id / bad limit / empty query → `ArgumentError`; unknown package (HTTP 404) → `EmptyResultError`; transport / 429 / non-200 → `CommandExecutionError`.
+57
View File
@@ -0,0 +1,57 @@
# NVD (NIST National Vulnerability Database)
**Mode**: 🌐 Public · **Domain**: `services.nvd.nist.gov`
Fetch a single CVE record from the NIST National Vulnerability Database via the public CVE 2.0 API.
## Commands
| Command | Description |
|---------|-------------|
| `opencli nvd cve <id>` | Fetch a CVE detail (description, CVSS, CWE, KEV flag) |
## Usage Examples
```bash
# Log4Shell
opencli nvd cve CVE-2021-44228
# Heartbleed
opencli nvd cve CVE-2014-0160
# JSON output for downstream tooling
opencli nvd cve CVE-2021-44228 -f json
```
## Output Columns
| Column | Description |
|--------|-------------|
| `id` | Canonical CVE id |
| `published` | First published date (`YYYY-MM-DD`) |
| `lastModified` | Last modified date (`YYYY-MM-DD`) |
| `vulnStatus` | NVD analysis status (e.g. `Analyzed`, `Awaiting Analysis`) |
| `baseScore` | CVSS base score (numeric, 010) |
| `severity` | CVSS severity (`CRITICAL` / `HIGH` / `MEDIUM` / `LOW` / `NONE`) |
| `attackVector` | CVSS attack vector (`NETWORK` / `LOCAL` / `PHYSICAL` / `ADJACENT`) |
| `cwe` | Comma-separated CWE id(s) |
| `kevAdded` | CISA KEV (Known Exploited Vulnerabilities) date if present |
| `description` | English description |
| `url` | Canonical NVD detail URL |
## Options
| Option | Description |
|--------|-------------|
| `id` (positional) | CVE identifier (`CVE-YYYY-N…`, case-insensitive). Validated upfront. |
## Caveats
- The CVE id is validated against `^CVE-\d{4}-\d{4,}$`; bad input raises `ArgumentError`.
- CVSS columns prefer v3.1, fall back to v3.0, then v2 if neither v3 record is present.
- NVD enforces aggressive rate limits without an API key. `HTTP 403` and `HTTP 429` both surface as typed `CommandExecutionError` with a retry hint.
- Empty / unanalyzed records (no CVSS payload) leave `baseScore` / `severity` / `attackVector` as `null` / empty rather than fabricating defaults.
## Prerequisites
- No browser required — uses `services.nvd.nist.gov/rest/json/cves/2.0`.
+69
View File
@@ -0,0 +1,69 @@
# OEIS
**Mode**: 🌐 Public · **Domain**: `oeis.org`
Search the Online Encyclopedia of Integer Sequences by keyword or pattern, and fetch full sequence detail by A-number. OEIS is the canonical reference for integer sequences in mathematics — every sequence has a unique `Annnnnn` id.
## Commands
| Command | Description |
|---------|-------------|
| `opencli oeis search <query>` | Search OEIS sequences by keyword or numeric pattern |
| `opencli oeis sequence <id>` | Full OEIS sequence detail by A-number |
## Usage Examples
```bash
# Keyword search
opencli oeis search fibonacci
opencli oeis search "prime gaps" --limit 5
# Numeric pattern search (find sequences matching a prefix)
opencli oeis search "1,1,2,3,5,8" # Fibonacci
opencli oeis search "2,3,5,7,11,13,17" # primes
# Sequence detail (A-number round-trips from search)
opencli oeis sequence A000045 # Fibonacci
opencli oeis sequence A000040 # Primes
opencli oeis sequence A000041 # Partitions
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, id, name, keywords, preview, author, created, url` |
| `sequence` | `id, name, keywords, preview, termCount, offset, author, created, revision, commentCount, formulaCount, referenceCount, xrefCount, linkCount, url` |
The `id` column round-trips between commands.
## Options
### `search`
| Option | Description |
|--------|-------------|
| `query` (positional) | Keyword or comma-separated terms |
| `--limit` | Max sequences (1100, default: 10). OEIS' wire format returns 10 per page; the adapter paginates server-side until `limit` is satisfied or upstream runs out. |
### `sequence`
| Option | Description |
|--------|-------------|
| `id` (positional) | OEIS A-number (e.g. `A000045`). Full URLs (`https://oeis.org/A000045`) and lowercase (`a000045`) are accepted. |
## Notes
- **`id` is always zero-padded to 6 digits** (`A000045`, `A000040`) — OEIS' canonical form. Search responses have raw integers (`number: 45`); the adapter formats them into the canonical id.
- **`preview` is the first 12 terms**, comma-joined. The full term sequence can be hundreds of integers; we cap with `(+N)` suffix so rows stay scannable. Use `sequence` + the `data` API tier (not exposed here) for the full term stream.
- **`keywords` is a comma-joined string**, OEIS' raw format. Common keywords:
- `core` — universally referenced
- `nice` — pleasing / well-known
- `easy` — easy to compute
- `nonn` — non-negative
- `mult` — multiplicative
- `cofr` — continued-fraction ish
- **`offset`** is OEIS' notation for where the sequence begins (`'0,4'` means first term is at index 0, first term ≥ 2 is at index 4). Useful for sequences that start with `1, 1` and you need to know where the "interesting" terms are.
- **`commentCount` / `formulaCount` / `referenceCount` / `xrefCount` / `linkCount`** are integer counts of how rich the OEIS page is. The full graphs are not surfaced — they can be enormous (Fibonacci has 250 links).
- **No API key required.** OEIS' free service is generous; bursts → `CommandExecutionError`.
- **Errors.** Empty query / bad A-number / bad limit → `ArgumentError`; unknown id / no matches → `EmptyResultError`; transport / 429 / non-200 → `CommandExecutionError`.
+59
View File
@@ -0,0 +1,59 @@
# ONES
**Mode**: 🔐 Browser Bridge · **Domain**: `ones.cn` (self-hosted via `ONES_BASE_URL`)
## Commands
| Command | Description |
|---------|-------------|
| `opencli ones login` | Login via Project API (`auth/login`) |
| `opencli ones me` | Current user profile (`users/me`) |
| `opencli ones token-info` | Token/user/team summary (`auth/token_info`) |
| `opencli ones tasks` | Team task list with status/project labels and hours |
| `opencli ones my-tasks` | My tasks (`assign`/`field004`/`owner`/`both`) |
| `opencli ones task` | Task detail by UUID (`team/:team/task/:id/info`) |
| `opencli ones worklog` | Log/backfill hours (GraphQL `addManhour` first, then REST fallbacks) |
| `opencli ones logout` | Logout (`auth/logout`) |
## Usage Examples
```bash
# Required: your ONES base URL
export ONES_BASE_URL=https://your-instance.example.com
# Optional if your deployment requires auth headers
# export ONES_USER_ID=...
# export ONES_AUTH_TOKEN=...
# Login/profile
opencli ones login --email you@company.com --password 'your-password'
opencli ones me
opencli ones token-info
# Task lists
opencli ones tasks <teamUUID> --limit 20
opencli ones tasks <teamUUID> --project <projectUUID> --assign <userUUID>
opencli ones my-tasks <teamUUID> --limit 100
opencli ones my-tasks <teamUUID> --mode both
# Task detail
opencli ones task <taskUUID> --team <teamUUID>
# Worklog: today / backfill
opencli ones worklog <taskUUID> 2 --team <teamUUID>
opencli ones worklog <taskUUID> 1.5 --team <teamUUID> --date 2026-03-23 --note "integration"
opencli ones logout
```
## Prerequisites
- Chrome running and logged into your ONES instance
- [Browser Bridge extension](/guide/browser-bridge) installed
- `ONES_BASE_URL` set to the same origin opened in Chrome
## Notes
- This adapter targets legacy ONES Project API deployments.
- `ONES_TEAM_UUID` can be set to omit `--team` in `tasks` / `my-tasks` / `task`.
- Hours display and input use `ONES_MANHOUR_SCALE` (default `100000`).
+67
View File
@@ -0,0 +1,67 @@
# OpenAlex
**Mode**: 🌐 Public · **Domain**: `api.openalex.org`
Search and inspect scholarly Works (papers, preprints, books) on OpenAlex without auth or browser. Two commands.
## Commands
| Command | Description |
|---------|-------------|
| `opencli openalex search <query>` | Search OpenAlex Works by keyword |
| `opencli openalex work <id>` | Single Work — metadata + reconstructed abstract |
## Usage Examples
```bash
# Free-text search
opencli openalex search transformers --limit 10
opencli openalex search "open access scholarly" --limit 5
# Single Work by OpenAlex id (use `id` from search rows)
opencli openalex work W2741809807
# Single Work by DOI (raw or full URL)
opencli openalex work 10.7717/peerj.4375
opencli openalex work https://doi.org/10.7717/peerj.4375
# JSON output
opencli openalex search transformers -f json
opencli openalex work W2741809807 -f json
```
## Output Columns
| Command | Columns |
|---------|---------|
| `search` | `rank, id, title, year, citations, firstAuthor, venue, openAccess, type, doi, url` |
| `work` | `id, title, type, year, date, language, authors, venue, citations, openAccess, openAccessUrl, referencedCount, doi, abstract, url` |
The `id` column from `search` round-trips into `work` exactly. `work` accepts an OpenAlex Work id, a raw DOI, or any `openalex.org` / `doi.org` URL.
## Options
### `openalex search`
| Option | Description |
|--------|-------------|
| `query` (positional) | Search text |
| `--limit` | Max Works (1-200, default: 20) |
### `openalex work`
| Option | Description |
|--------|-------------|
| `id` (positional) | OpenAlex Work id (`W2741809807`), DOI (`10.7717/peerj.4375`), or full URL |
## Caveats
- Work id input is validated upfront — only `W…` IDs / DOIs / `openalex.org` / `doi.org` URLs are accepted; OpenAlex itself does the canonicalization for DOIs. Bad input raises `ArgumentError`.
- The `abstract` column is reconstructed from OpenAlex's `abstract_inverted_index` (token → positions) — this is how OpenAlex distributes abstracts for licensing reasons. It's the verbatim abstract text.
- Set `OPENALEX_MAILTO=you@example.com` to opt into the OpenAlex polite pool (faster + more reliable). Optional — anonymous requests still work.
- OpenAlex `select=` rejects unknown fields. The adapter pins a vetted field list (`primary_location`, `open_access`, `authorships`, etc.) to avoid passing aliases that 400.
- OpenAlex throttles unauthenticated traffic; `HTTP 429` surfaces as a typed `CommandExecutionError` with a retry hint.
## Prerequisites
- No browser required — uses `api.openalex.org/works`.

Some files were not shown because too many files have changed in this diff Show More