@jackwener/opencli 1.5.8 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +35 -1
  3. package/README.zh-CN.md +17 -1
  4. package/SKILL.md +31 -851
  5. package/autoresearch/baseline-browse.txt +1 -0
  6. package/autoresearch/baseline-skill.txt +1 -0
  7. package/autoresearch/browse-tasks.json +688 -0
  8. package/autoresearch/eval-browse.ts +185 -0
  9. package/autoresearch/eval-skill.ts +248 -0
  10. package/autoresearch/run-browse.sh +9 -0
  11. package/autoresearch/run-skill.sh +9 -0
  12. package/dist/browser/base-page.d.ts +48 -0
  13. package/dist/browser/base-page.js +160 -0
  14. package/dist/browser/cdp.js +4 -106
  15. package/dist/browser/daemon-client.d.ts +20 -7
  16. package/dist/browser/daemon-client.js +39 -39
  17. package/dist/browser/daemon-client.test.js +77 -0
  18. package/dist/browser/discover.d.ts +1 -4
  19. package/dist/browser/discover.js +9 -23
  20. package/dist/browser/errors.d.ts +4 -0
  21. package/dist/browser/errors.js +20 -0
  22. package/dist/browser/index.d.ts +1 -1
  23. package/dist/browser/index.js +1 -1
  24. package/dist/browser/page.d.ts +10 -35
  25. package/dist/browser/page.js +55 -187
  26. package/dist/browser/tabs.js +5 -5
  27. package/dist/browser.test.js +15 -15
  28. package/dist/cli-manifest.json +294 -22
  29. package/dist/cli.js +392 -0
  30. package/dist/clis/amazon/bestsellers.d.ts +21 -0
  31. package/dist/clis/amazon/bestsellers.js +130 -0
  32. package/dist/clis/amazon/bestsellers.test.js +20 -0
  33. package/dist/clis/amazon/discussion.d.ts +20 -0
  34. package/dist/clis/amazon/discussion.js +91 -0
  35. package/dist/clis/amazon/discussion.test.d.ts +1 -0
  36. package/dist/clis/amazon/discussion.test.js +36 -0
  37. package/dist/clis/amazon/offer.d.ts +23 -0
  38. package/dist/clis/amazon/offer.js +140 -0
  39. package/dist/clis/amazon/offer.test.d.ts +1 -0
  40. package/dist/clis/amazon/offer.test.js +29 -0
  41. package/dist/clis/amazon/product.d.ts +18 -0
  42. package/dist/clis/amazon/product.js +92 -0
  43. package/dist/clis/amazon/product.test.d.ts +1 -0
  44. package/dist/clis/amazon/product.test.js +24 -0
  45. package/dist/clis/amazon/search.d.ts +18 -0
  46. package/dist/clis/amazon/search.js +87 -0
  47. package/dist/clis/amazon/search.test.d.ts +1 -0
  48. package/dist/clis/amazon/search.test.js +22 -0
  49. package/dist/clis/amazon/shared.d.ts +64 -0
  50. package/dist/clis/amazon/shared.js +255 -0
  51. package/dist/clis/amazon/shared.test.d.ts +1 -0
  52. package/dist/clis/amazon/shared.test.js +33 -0
  53. package/dist/clis/gemini/ask.d.ts +1 -0
  54. package/dist/clis/gemini/ask.js +40 -0
  55. package/dist/clis/gemini/image.d.ts +1 -0
  56. package/dist/clis/gemini/image.js +105 -0
  57. package/dist/clis/gemini/new.d.ts +1 -0
  58. package/dist/clis/gemini/new.js +20 -0
  59. package/dist/clis/gemini/utils.d.ts +34 -0
  60. package/dist/clis/gemini/utils.js +463 -0
  61. package/dist/clis/gemini/utils.test.d.ts +1 -0
  62. package/dist/clis/gemini/utils.test.js +31 -0
  63. package/dist/clis/notebooklm/compat.test.d.ts +1 -1
  64. package/dist/clis/notebooklm/compat.test.js +3 -3
  65. package/dist/clis/notebooklm/current.js +2 -3
  66. package/dist/clis/notebooklm/get.js +2 -3
  67. package/dist/clis/notebooklm/history.js +2 -3
  68. package/dist/clis/notebooklm/note-list.js +2 -3
  69. package/dist/clis/notebooklm/notes-get.js +2 -3
  70. package/dist/clis/notebooklm/open.d.ts +1 -0
  71. package/dist/clis/notebooklm/open.js +41 -0
  72. package/dist/clis/notebooklm/open.test.d.ts +1 -0
  73. package/dist/clis/notebooklm/open.test.js +63 -0
  74. package/dist/clis/notebooklm/source-fulltext.js +2 -3
  75. package/dist/clis/notebooklm/source-get.js +2 -3
  76. package/dist/clis/notebooklm/source-guide.js +2 -3
  77. package/dist/clis/notebooklm/source-list.js +2 -3
  78. package/dist/clis/notebooklm/status.js +1 -2
  79. package/dist/clis/notebooklm/summary.js +2 -3
  80. package/dist/clis/notebooklm/utils.d.ts +2 -1
  81. package/dist/clis/notebooklm/utils.js +20 -21
  82. package/dist/clis/twitter/article.js +28 -1
  83. package/dist/clis/xiaohongshu/creator-note-detail.test.js +11 -11
  84. package/dist/clis/xiaohongshu/creator-notes-summary.test.js +6 -6
  85. package/dist/clis/xiaohongshu/creator-notes.test.js +22 -22
  86. package/dist/clis/xiaohongshu/note.js +11 -0
  87. package/dist/clis/xiaohongshu/note.test.js +49 -0
  88. package/dist/commanderAdapter.js +7 -4
  89. package/dist/commanderAdapter.test.js +76 -0
  90. package/dist/commands/daemon.js +8 -47
  91. package/dist/commands/daemon.test.js +45 -70
  92. package/dist/discovery.js +27 -0
  93. package/dist/doctor.d.ts +1 -2
  94. package/dist/doctor.js +7 -8
  95. package/dist/explore.js +1 -1
  96. package/dist/output.js +28 -0
  97. package/dist/output.test.js +15 -0
  98. package/dist/pipeline/executor.js +2 -7
  99. package/dist/pipeline/steps/browser.js +1 -1
  100. package/dist/pipeline/template.js +25 -3
  101. package/dist/record.d.ts +50 -0
  102. package/dist/record.js +298 -57
  103. package/dist/record.test.d.ts +1 -0
  104. package/dist/record.test.js +293 -0
  105. package/dist/registry.d.ts +2 -0
  106. package/dist/registry.js +1 -0
  107. package/dist/registry.test.js +10 -0
  108. package/dist/runtime.js +3 -3
  109. package/dist/snapshotFormatter.d.ts +1 -1
  110. package/dist/snapshotFormatter.js +4 -4
  111. package/dist/snapshotFormatter.test.d.ts +1 -1
  112. package/dist/snapshotFormatter.test.js +2 -2
  113. package/dist/types.d.ts +11 -1
  114. package/dist/types.js +1 -1
  115. package/docs/.vitepress/config.mts +2 -0
  116. package/docs/adapters/browser/amazon.md +53 -0
  117. package/docs/adapters/browser/gemini.md +72 -0
  118. package/docs/adapters/browser/notebooklm.md +5 -5
  119. package/docs/adapters/index.md +3 -1
  120. package/docs/guide/getting-started.md +21 -0
  121. package/docs/superpowers/specs/2026-04-02-browse-skill-testing-design.md +144 -0
  122. package/docs/zh/guide/getting-started.md +21 -0
  123. package/extension/package-lock.json +2 -2
  124. package/extension/src/background.test.ts +7 -163
  125. package/extension/src/background.ts +58 -161
  126. package/extension/src/cdp.ts +77 -124
  127. package/extension/src/protocol.ts +5 -5
  128. package/package.json +1 -1
  129. package/skills/opencli-explorer/SKILL.md +853 -0
  130. package/skills/opencli-oneshot/SKILL.md +222 -0
  131. package/skills/opencli-operate/SKILL.md +213 -0
  132. package/skills/opencli-usage/SKILL.md +152 -0
  133. package/skills/opencli-usage/browser.md +429 -0
  134. package/skills/opencli-usage/desktop.md +118 -0
  135. package/skills/opencli-usage/plugins.md +82 -0
  136. package/skills/opencli-usage/public-api.md +149 -0
  137. package/src/browser/base-page.ts +197 -0
  138. package/src/browser/cdp.ts +7 -131
  139. package/src/browser/daemon-client.test.ts +103 -0
  140. package/src/browser/daemon-client.ts +55 -43
  141. package/src/browser/discover.ts +9 -21
  142. package/src/browser/errors.ts +22 -0
  143. package/src/browser/index.ts +1 -1
  144. package/src/browser/page.ts +57 -209
  145. package/src/browser/tabs.ts +5 -5
  146. package/src/browser.test.ts +15 -15
  147. package/src/cli.ts +392 -0
  148. package/src/clis/amazon/bestsellers.test.ts +22 -0
  149. package/src/clis/amazon/bestsellers.ts +180 -0
  150. package/src/clis/amazon/discussion.test.ts +38 -0
  151. package/src/clis/amazon/discussion.ts +131 -0
  152. package/src/clis/amazon/offer.test.ts +35 -0
  153. package/src/clis/amazon/offer.ts +185 -0
  154. package/src/clis/amazon/product.test.ts +26 -0
  155. package/src/clis/amazon/product.ts +131 -0
  156. package/src/clis/amazon/search.test.ts +24 -0
  157. package/src/clis/amazon/search.ts +128 -0
  158. package/src/clis/amazon/shared.test.ts +37 -0
  159. package/src/clis/amazon/shared.ts +316 -0
  160. package/src/clis/gemini/ask.ts +46 -0
  161. package/src/clis/gemini/image.ts +115 -0
  162. package/src/clis/gemini/new.ts +22 -0
  163. package/src/clis/gemini/utils.test.ts +36 -0
  164. package/src/clis/gemini/utils.ts +523 -0
  165. package/src/clis/notebooklm/compat.test.ts +3 -3
  166. package/src/clis/notebooklm/current.ts +2 -3
  167. package/src/clis/notebooklm/get.ts +1 -3
  168. package/src/clis/notebooklm/history.ts +1 -3
  169. package/src/clis/notebooklm/note-list.ts +1 -3
  170. package/src/clis/notebooklm/notes-get.ts +1 -3
  171. package/src/clis/notebooklm/open.test.ts +78 -0
  172. package/src/clis/notebooklm/open.ts +61 -0
  173. package/src/clis/notebooklm/source-fulltext.ts +1 -3
  174. package/src/clis/notebooklm/source-get.ts +1 -3
  175. package/src/clis/notebooklm/source-guide.ts +1 -3
  176. package/src/clis/notebooklm/source-list.ts +1 -3
  177. package/src/clis/notebooklm/status.ts +1 -2
  178. package/src/clis/notebooklm/summary.ts +1 -3
  179. package/src/clis/notebooklm/utils.ts +29 -20
  180. package/src/clis/twitter/article.ts +31 -1
  181. package/src/clis/xiaohongshu/creator-note-detail.test.ts +11 -11
  182. package/src/clis/xiaohongshu/creator-notes-summary.test.ts +6 -6
  183. package/src/clis/xiaohongshu/creator-notes.test.ts +22 -22
  184. package/src/clis/xiaohongshu/note.test.ts +51 -0
  185. package/src/clis/xiaohongshu/note.ts +18 -0
  186. package/src/commanderAdapter.test.ts +109 -0
  187. package/src/commanderAdapter.ts +8 -4
  188. package/src/commands/daemon.test.ts +50 -84
  189. package/src/commands/daemon.ts +8 -56
  190. package/src/discovery.ts +22 -0
  191. package/src/doctor.ts +8 -9
  192. package/src/explore.ts +1 -1
  193. package/src/output.test.ts +17 -0
  194. package/src/output.ts +27 -0
  195. package/src/pipeline/executor.ts +2 -7
  196. package/src/pipeline/steps/browser.ts +1 -1
  197. package/src/pipeline/template.ts +27 -4
  198. package/src/record.test.ts +362 -0
  199. package/src/record.ts +341 -62
  200. package/src/registry.test.ts +12 -0
  201. package/src/registry.ts +3 -0
  202. package/src/runtime.ts +3 -3
  203. package/src/snapshotFormatter.test.ts +2 -2
  204. package/src/snapshotFormatter.ts +4 -4
  205. package/src/types.ts +11 -1
  206. package/.agents/skills/cross-project-adapter-migration/SKILL.md +0 -249
  207. package/.agents/workflows/cross-project-adapter-migration.md +0 -54
  208. package/dist/clis/notebooklm/bind-current.js +0 -29
  209. package/dist/clis/notebooklm/bind-current.test.d.ts +0 -1
  210. package/dist/clis/notebooklm/bind-current.test.js +0 -35
  211. package/dist/clis/notebooklm/binding.test.js +0 -44
  212. package/extension/dist/background.js +0 -819
  213. package/src/clis/notebooklm/bind-current.test.ts +0 -43
  214. package/src/clis/notebooklm/bind-current.ts +0 -36
  215. package/src/clis/notebooklm/binding.test.ts +0 -53
  216. /package/dist/browser/{mcp.d.ts → bridge.d.ts} +0 -0
  217. /package/dist/browser/{mcp.js → bridge.js} +0 -0
  218. /package/dist/{clis/notebooklm/bind-current.d.ts → browser/daemon-client.test.d.ts} +0 -0
  219. /package/dist/clis/{notebooklm/binding.test.d.ts → amazon/bestsellers.test.d.ts} +0 -0
  220. /package/src/browser/{mcp.ts → bridge.ts} +0 -0
@@ -0,0 +1,222 @@
1
+ ---
2
+ name: opencli-oneshot
3
+ description: Use when quickly generating a single OpenCLI command from a specific URL and goal description. 4-step process — open page, capture API, write YAML adapter, test. For full site exploration, use opencli-explorer instead.
4
+ tags: [opencli, adapter, quick-start, yaml, cli, one-shot, automation]
5
+ ---
6
+
7
+ # CLI-ONESHOT — 单点快速 CLI 生成
8
+
9
+ > 给一个 URL + 一句话描述,4 步生成一个 CLI 命令。
10
+ > 完整探索式开发请看 [CLI-EXPLORER.md](./CLI-EXPLORER.md)。
11
+
12
+ ---
13
+
14
+ ## 输入
15
+
16
+ | 项目 | 示例 |
17
+ |------|------|
18
+ | **URL** | `https://x.com/jakevin7/lists` |
19
+ | **Goal** | 获取我的 Twitter Lists |
20
+
21
+ ---
22
+
23
+ ## 流程
24
+
25
+ ### Step 1: 打开页面 + 抓包
26
+
27
+ ```
28
+ 1. browser_navigate → 打开目标 URL
29
+ 2. 等待 3-5 秒(让页面加载完、API 请求触发)
30
+ 3. browser_network_requests → 筛选 JSON API
31
+ ```
32
+
33
+ **关键**:只关注返回 `application/json` 的请求,忽略静态资源。
34
+ 如果没有自动触发 API,手动点击目标按钮/标签再抓一次。
35
+
36
+ ### Step 2: 锁定一个接口
37
+
38
+ 从抓包结果中找到**那个**目标 API。看这几个字段:
39
+
40
+ | 字段 | 关注什么 |
41
+ |------|----------|
42
+ | URL | API 路径 pattern(如 `/i/api/graphql/xxx/ListsManagePinTimeline`) |
43
+ | Method | GET / POST |
44
+ | Headers | 有 Cookie? Bearer? CSRF? 自定义签名? |
45
+ | Response | 数据在哪个路径(如 `data.list.lists`) |
46
+
47
+ ### Step 3: 验证接口能复现
48
+
49
+ 在 `browser_evaluate` 中用 `fetch` 复现请求:
50
+
51
+ ```javascript
52
+ // Tier 2 (Cookie): 大多数情况
53
+ fetch('/api/endpoint', { credentials: 'include' }).then(r => r.json())
54
+
55
+ // Tier 3 (Header): 如 Twitter 需要额外 header
56
+ const ct0 = document.cookie.match(/ct0=([^;]+)/)?.[1];
57
+ fetch('/api/endpoint', {
58
+ headers: { 'Authorization': 'Bearer ...', 'X-Csrf-Token': ct0 },
59
+ credentials: 'include'
60
+ }).then(r => r.json())
61
+ ```
62
+
63
+ 如果 fetch 能拿到数据 → 用 YAML 或简单 TS adapter。
64
+ 如果 fetch 拿不到(签名/风控)→ 用 intercept 策略。
65
+
66
+ ### Step 4: 套模板,生成 adapter
67
+
68
+ 根据 Step 3 判定的策略,选一个模板生成文件。
69
+
70
+ ---
71
+
72
+ ## 认证速查
73
+
74
+ ```
75
+ fetch(url) 直接能拿到? → Tier 1: public (YAML, browser: false)
76
+ fetch(url, {credentials:'include'})? → Tier 2: cookie (YAML)
77
+ 加 Bearer/CSRF header 后拿到? → Tier 3: header (TS)
78
+ 都不行,但页面自己能请求成功? → Tier 4: intercept (TS, installInterceptor)
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 模板
84
+
85
+ ### YAML — Cookie/Public(最简)
86
+
87
+ ```yaml
88
+ # src/clis/<site>/<name>.yaml
89
+ site: mysite
90
+ name: mycommand
91
+ description: "一句话描述"
92
+ domain: www.example.com
93
+ strategy: cookie # 或 public (加 browser: false)
94
+
95
+ args:
96
+ limit:
97
+ type: int
98
+ default: 20
99
+
100
+ pipeline:
101
+ - navigate: https://www.example.com/target-page
102
+
103
+ - evaluate: |
104
+ (async () => {
105
+ const res = await fetch('/api/target', { credentials: 'include' });
106
+ const d = await res.json();
107
+ return (d.data?.items || []).map(item => ({
108
+ title: item.title,
109
+ value: item.value,
110
+ }));
111
+ })()
112
+
113
+ - map:
114
+ rank: ${{ index + 1 }}
115
+ title: ${{ item.title }}
116
+ value: ${{ item.value }}
117
+
118
+ - limit: ${{ args.limit }}
119
+
120
+ columns: [rank, title, value]
121
+ ```
122
+
123
+ ### TS — Intercept(抓包模式)
124
+
125
+ ```typescript
126
+ // src/clis/<site>/<name>.ts
127
+ import { cli, Strategy } from '../../registry.js';
128
+
129
+ cli({
130
+ site: 'mysite',
131
+ name: 'mycommand',
132
+ description: '一句话描述',
133
+ domain: 'www.example.com',
134
+ strategy: Strategy.INTERCEPT,
135
+ browser: true,
136
+ args: [
137
+ { name: 'limit', type: 'int', default: 20 },
138
+ ],
139
+ columns: ['rank', 'title', 'value'],
140
+ func: async (page, kwargs) => {
141
+ // 1. 导航
142
+ await page.goto('https://www.example.com/target-page');
143
+ await page.wait(3);
144
+
145
+ // 2. 注入拦截器(URL 子串匹配)
146
+ await page.installInterceptor('target-api-keyword');
147
+
148
+ // 3. 触发 API(滚动/点击)
149
+ await page.autoScroll({ times: 2, delayMs: 2000 });
150
+
151
+ // 4. 读取拦截的响应
152
+ const requests = await page.getInterceptedRequests();
153
+ if (!requests?.length) return [];
154
+
155
+ let results: any[] = [];
156
+ for (const req of requests) {
157
+ const items = req.data?.data?.items || [];
158
+ results.push(...items);
159
+ }
160
+
161
+ return results.slice(0, kwargs.limit).map((item, i) => ({
162
+ rank: i + 1,
163
+ title: item.title || '',
164
+ value: item.value || '',
165
+ }));
166
+ },
167
+ });
168
+ ```
169
+
170
+ ### TS — Header(如 Twitter GraphQL)
171
+
172
+ ```typescript
173
+ import { cli, Strategy } from '../../registry.js';
174
+
175
+ cli({
176
+ site: 'twitter',
177
+ name: 'mycommand',
178
+ description: '一句话描述',
179
+ domain: 'x.com',
180
+ strategy: Strategy.HEADER,
181
+ browser: true,
182
+ args: [
183
+ { name: 'limit', type: 'int', default: 20 },
184
+ ],
185
+ columns: ['rank', 'name', 'value'],
186
+ func: async (page, kwargs) => {
187
+ await page.goto('https://x.com');
188
+ const data = await page.evaluate(`(async () => {
189
+ const ct0 = document.cookie.match(/ct0=([^;]+)/)?.[1];
190
+ if (!ct0) return { error: 'Not logged in' };
191
+ const bearer = 'AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D...';
192
+ const res = await fetch('/i/api/graphql/QUERY_ID/Endpoint', {
193
+ headers: {
194
+ 'Authorization': 'Bearer ' + decodeURIComponent(bearer),
195
+ 'X-Csrf-Token': ct0,
196
+ 'X-Twitter-Auth-Type': 'OAuth2Session',
197
+ },
198
+ credentials: 'include',
199
+ });
200
+ return res.json();
201
+ })()`);
202
+ // 解析 data...
203
+ return [];
204
+ },
205
+ });
206
+ ```
207
+
208
+ ---
209
+
210
+ ## 测试(必做)
211
+
212
+ ```bash
213
+ npm run build # 语法检查
214
+ opencli list | grep mysite # 确认注册
215
+ opencli mysite mycommand --limit 3 -v # 实际运行
216
+ ```
217
+
218
+ ---
219
+
220
+ ## 就这样,没了
221
+
222
+ 写完文件 → build → run → 提交。有问题再看 [CLI-EXPLORER.md](./CLI-EXPLORER.md)。
@@ -0,0 +1,213 @@
1
+ ---
2
+ name: opencli-operate
3
+ description: Make websites accessible for AI agents. Navigate, click, type, extract, wait — using Chrome with existing login sessions. No LLM API key needed.
4
+ allowed-tools: Bash(opencli:*), Read, Edit, Write
5
+ ---
6
+
7
+ # OpenCLI — Make Websites Accessible for AI Agents
8
+
9
+ Control Chrome step-by-step via CLI. Reuses existing login sessions — no passwords needed.
10
+
11
+ ## Prerequisites
12
+
13
+ ```bash
14
+ opencli doctor # Verify extension + daemon connectivity
15
+ ```
16
+
17
+ Requires: Chrome running + OpenCLI Browser Bridge extension installed.
18
+
19
+ ## Quickstart for AI Agents (1 step)
20
+
21
+ Point your AI agent to this file. It contains everything needed to operate browsers.
22
+
23
+ ## Quickstart for Humans (3 steps)
24
+
25
+ ```bash
26
+ npm install -g @jackwener/opencli # 1. Install
27
+ # Install extension from chrome://extensions # 2. Load extension
28
+ opencli operate open https://example.com # 3. Go!
29
+ ```
30
+
31
+ ## Core Workflow
32
+
33
+ 1. **Navigate**: `opencli operate open <url>`
34
+ 2. **Inspect**: `opencli operate state` → see elements with `[N]` indices
35
+ 3. **Interact**: use indices — `click`, `type`, `select`, `keys`
36
+ 4. **Wait**: `opencli operate wait selector ".loaded"` or `wait text "Success"`
37
+ 5. **Verify**: `opencli operate get title` or `opencli operate screenshot`
38
+ 6. **Repeat**: browser stays open between commands
39
+ 7. **Save**: write a TS adapter to `~/.opencli/clis/<site>/<command>.ts`
40
+
41
+ ## Commands
42
+
43
+ ### Navigation
44
+
45
+ ```bash
46
+ opencli operate open <url> # Open URL
47
+ opencli operate back # Go back
48
+ opencli operate scroll down # Scroll (up/down, --amount N)
49
+ opencli operate scroll up --amount 1000
50
+ ```
51
+
52
+ ### Inspect
53
+
54
+ ```bash
55
+ opencli operate state # Elements with [N] indices
56
+ opencli operate screenshot [path.png] # Screenshot
57
+ ```
58
+
59
+ ### Get (structured data)
60
+
61
+ ```bash
62
+ opencli operate get title # Page title
63
+ opencli operate get url # Current URL
64
+ opencli operate get text <index> # Element text content
65
+ opencli operate get value <index> # Input/textarea value
66
+ opencli operate get html # Full page HTML
67
+ opencli operate get html --selector "h1" # Scoped HTML
68
+ opencli operate get attributes <index> # Element attributes
69
+ ```
70
+
71
+ ### Interact
72
+
73
+ ```bash
74
+ opencli operate click <index> # Click element [N]
75
+ opencli operate type <index> "text" # Type into element [N]
76
+ opencli operate select <index> "option" # Select dropdown
77
+ opencli operate keys "Enter" # Press key (Enter, Escape, Tab, Control+a)
78
+ ```
79
+
80
+ ### Wait
81
+
82
+ ```bash
83
+ opencli operate wait selector ".loaded" # Wait for element
84
+ opencli operate wait selector ".spinner" --timeout 5000 # With timeout
85
+ opencli operate wait text "Success" # Wait for text
86
+ opencli operate wait time 3 # Wait N seconds
87
+ ```
88
+
89
+ ### Extract
90
+
91
+ ```bash
92
+ opencli operate eval "document.title"
93
+ opencli operate eval "JSON.stringify([...document.querySelectorAll('h2')].map(e => e.textContent))"
94
+ ```
95
+
96
+ ### Network (API Discovery)
97
+
98
+ ```bash
99
+ opencli operate network # Show captured API requests (auto-captured since open)
100
+ opencli operate network --detail 3 # Show full response body of request #3
101
+ opencli operate network --all # Include static resources
102
+ ```
103
+
104
+ ### Sedimentation (Save as CLI)
105
+
106
+ ```bash
107
+ opencli operate init hn/top # Generate adapter scaffold
108
+ opencli operate verify hn/top # Test the adapter
109
+ ```
110
+
111
+ ### Session
112
+
113
+ ```bash
114
+ opencli operate close # Close automation window
115
+ ```
116
+
117
+ ## Example: Extract HN Stories
118
+
119
+ ```bash
120
+ opencli operate open https://news.ycombinator.com
121
+ opencli operate state # See [1] a "Story 1", [2] a "Story 2"...
122
+ opencli operate eval "JSON.stringify([...document.querySelectorAll('.titleline a')].slice(0,5).map(a => ({title: a.textContent, url: a.href})))"
123
+ opencli operate close
124
+ ```
125
+
126
+ ## Example: Fill a Form
127
+
128
+ ```bash
129
+ opencli operate open https://httpbin.org/forms/post
130
+ opencli operate state # See [3] input "Customer Name", [4] input "Telephone"
131
+ opencli operate type 3 "OpenCLI"
132
+ opencli operate type 4 "555-0100"
133
+ opencli operate get value 3 # Verify: "OpenCLI"
134
+ opencli operate close
135
+ ```
136
+
137
+ ## Saving as Reusable CLI — Complete Workflow
138
+
139
+ ### Step-by-step sedimentation flow:
140
+
141
+ ```bash
142
+ # 1. Explore the website
143
+ opencli operate open https://news.ycombinator.com
144
+ opencli operate state # Understand DOM structure
145
+
146
+ # 2. Discover APIs (crucial for high-quality adapters)
147
+ opencli operate eval "fetch('/api/...').then(r=>r.json())" # Trigger API calls
148
+ opencli operate network # See captured API requests
149
+ opencli operate network --detail 0 # Inspect response body
150
+
151
+ # 3. Generate scaffold
152
+ opencli operate init hn/top # Creates ~/.opencli/clis/hn/top.ts
153
+
154
+ # 4. Edit the adapter (fill in func logic)
155
+ # - If API found: use fetch() directly (Strategy.PUBLIC or COOKIE)
156
+ # - If no API: use page.evaluate() for DOM extraction (Strategy.UI)
157
+
158
+ # 5. Verify
159
+ opencli operate verify hn/top # Runs the adapter and shows output
160
+
161
+ # 6. If verify fails, edit and retry
162
+ # 7. Close when done
163
+ opencli operate close
164
+ ```
165
+
166
+ ### Example adapter:
167
+
168
+ ```typescript
169
+ // ~/.opencli/clis/hn/top.ts
170
+ import { cli, Strategy } from '@jackwener/opencli/registry';
171
+
172
+ cli({
173
+ site: 'hn',
174
+ name: 'top',
175
+ description: 'Top Hacker News stories',
176
+ domain: 'news.ycombinator.com',
177
+ strategy: Strategy.PUBLIC,
178
+ browser: false,
179
+ args: [{ name: 'limit', type: 'int', default: 5 }],
180
+ columns: ['rank', 'title', 'score', 'url'],
181
+ func: async (_page, kwargs) => {
182
+ const limit = Math.min(Math.max(1, kwargs.limit ?? 5), 50);
183
+ const resp = await fetch('https://hacker-news.firebaseio.com/v0/topstories.json');
184
+ const ids = await resp.json();
185
+ return Promise.all(
186
+ ids.slice(0, limit).map(async (id: number, i: number) => {
187
+ const item = await (await fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)).json();
188
+ return { rank: i + 1, title: item.title, score: item.score, url: item.url ?? '' };
189
+ })
190
+ );
191
+ },
192
+ });
193
+ ```
194
+
195
+ Save to `~/.opencli/clis/<site>/<command>.ts` → immediately available as `opencli <site> <command>`.
196
+
197
+ ### Strategy Guide
198
+
199
+ | Strategy | When | browser: |
200
+ |----------|------|----------|
201
+ | `Strategy.PUBLIC` | Public API, no auth | `false` |
202
+ | `Strategy.COOKIE` | Needs login cookies | `true` |
203
+ | `Strategy.UI` | Direct DOM interaction | `true` |
204
+
205
+ **Always prefer API over UI** — if you discovered an API during browsing, use `fetch()` directly.
206
+
207
+ ## Troubleshooting
208
+
209
+ | Error | Fix |
210
+ |-------|-----|
211
+ | "Browser not connected" | Run `opencli doctor` |
212
+ | "attach failed: chrome-extension://" | Disable 1Password temporarily |
213
+ | Element not found | `opencli operate scroll down` then `opencli operate state` |
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: opencli-usage
3
+ description: "Use when running OpenCLI commands to interact with websites (Bilibili, Twitter, Reddit, Xiaohongshu, etc.), desktop apps (Cursor, Notion), or public APIs (HackerNews, arXiv). Covers installation, command reference, and output formats for 60+ adapters."
4
+ version: 1.6.0
5
+ author: jackwener
6
+ tags: [opencli, cli, browser, web, chrome-extension, cdp, bilibili, twitter, reddit, xiaohongshu, github, youtube, AI, agent, automation]
7
+ ---
8
+
9
+ # OpenCLI Usage Guide
10
+
11
+ > Make any website or Electron App your CLI. Reuse Chrome login, zero risk, AI-powered discovery.
12
+
13
+ ## Install & Run
14
+
15
+ ```bash
16
+ # npm global install (recommended)
17
+ npm install -g @jackwener/opencli
18
+ opencli <command>
19
+
20
+ # Or from source
21
+ cd ~/code/opencli && npm install
22
+ npx tsx src/main.ts <command>
23
+
24
+ # Update to latest
25
+ npm update -g @jackwener/opencli
26
+ ```
27
+
28
+ ## Prerequisites
29
+
30
+ Browser commands require:
31
+ 1. Chrome browser running **(logged into target sites)**
32
+ 2. **opencli Browser Bridge** Chrome extension installed (load `extension/` as unpacked in `chrome://extensions`)
33
+ 3. No further setup needed — the daemon auto-starts on first browser command
34
+
35
+ > **Note**: You must be logged into the target website in Chrome before running commands. Tabs opened during command execution are auto-closed afterwards.
36
+
37
+ Public API commands (`hackernews`, `v2ex`) need no browser.
38
+
39
+ ## Quick Lookup by Capability
40
+
41
+ | Capability | Platforms (partial list) | File |
42
+ |-----------|--------------------------|------|
43
+ | **search** | Bilibili, Twitter, Reddit, Xiaohongshu, Zhihu, YouTube, Google, arXiv, LinkedIn, Pixiv, etc. | browser.md / public-api.md |
44
+ | **hot/trending** | Bilibili, Twitter, Weibo, HackerNews, Reddit, V2EX, Xueqiu, Lobsters, Douban | browser.md / public-api.md |
45
+ | **feed/timeline** | Twitter, Reddit, Xiaohongshu, Xueqiu, Jike, Facebook, Instagram, Medium | browser.md |
46
+ | **user/profile** | Twitter, Reddit, Instagram, TikTok, Facebook, Bilibili, Pixiv | browser.md |
47
+ | **post/create** | Twitter, Jike | browser.md |
48
+ | **AI chat** | Grok, Doubao, Kimi, DeepSeek, Qwen, ChatGPT, Cursor, Codex | browser.md / desktop.md |
49
+ | **finance/stock** | Xueqiu, Yahoo Finance, Barchart, Sina Finance, Bloomberg | browser.md / public-api.md |
50
+ | **web scraping** | `opencli web read --url <url>` — any URL to Markdown | browser.md |
51
+
52
+ ## Command Quick Reference
53
+
54
+ Usage: `opencli <site> <command> [args] [--limit N] [-f json|yaml|md|csv|table]`
55
+
56
+ ### Browser-based (login required)
57
+
58
+ | Site | Commands |
59
+ |------|----------|
60
+ | **bilibili** | `hot` `search` `me` `favorite` `history` `feed` `user-videos` `subtitle` `dynamic` `ranking` `following` |
61
+ | **zhihu** | `hot` `search` `question` |
62
+ | **xiaohongshu** | `search` `notifications` `feed` `user` `creator-notes` `creator-note-detail` `creator-notes-summary` `creator-profile` `creator-stats` |
63
+ | **xueqiu** | `hot-stock` `stock` `watchlist` `feed` `hot` `search` `earnings-date` `fund-holdings` `fund-snapshot` |
64
+ | **twitter** | `trending` `bookmarks` `search` `profile` `timeline` `thread` `article` `follow` `unfollow` `bookmark` `unbookmark` `post` `like` `reply` `delete` `block` `unblock` `followers` `following` `notifications` `hide-reply` `download` `accept` `reply-dm` |
65
+ | **reddit** | `hot` `frontpage` `popular` `search` `subreddit` `read` `user` `user-posts` `user-comments` `upvote` `save` `comment` `subscribe` `saved` `upvoted` |
66
+ | **youtube** | `search` `video` `transcript` |
67
+ | **facebook** | `feed` `profile` `search` `friends` `groups` `events` `notifications` `memories` `add-friend` `join-group` |
68
+ | **instagram** | `explore` `profile` `search` `user` `followers` `following` `follow` `unfollow` `like` `unlike` `comment` `save` `unsave` `saved` |
69
+ | **tiktok** | `explore` `search` `profile` `user` `following` `follow` `unfollow` `like` `unlike` `comment` `save` `unsave` `live` `notifications` `friends` |
70
+ | **linkedin** | `search` `timeline` |
71
+ | **medium** | `feed` `search` `user` |
72
+ | **substack** | `feed` `search` `publication` |
73
+ | **sinablog** | `hot` `search` `article` `user` |
74
+ | **weibo** | `hot` |
75
+ | **boss** | `search` `detail` `recommend` `joblist` `greet` `batchgreet` `send` `chatlist` `chatmsg` `invite` `mark` `exchange` `resume` `stats` |
76
+ | **douban** | `search` `top250` `subject` `photos` `download` `marks` `reviews` |
77
+ | **pixiv** | `ranking` `search` `user` `illusts` `detail` `download` |
78
+ | **jike** | `feed` `search` `create` `like` `comment` `repost` `notifications` |
79
+ | **yahoo-finance** | `quote` |
80
+ | **barchart** | `quote` `options` `greeks` `flow` |
81
+ | **sinafinance** | `news` |
82
+ | **reuters** | `search` |
83
+ | **coupang** | `search` `add-to-cart` |
84
+ | **jd** | `item` |
85
+ | **smzdm** | `search` |
86
+ | **ctrip** | `search` |
87
+ | **weread** | `shelf` `search` `book` `highlights` `notes` `ranking` |
88
+ | **chaoxing** | `assignments` `exams` |
89
+ | **jimeng** | `generate` `history` |
90
+ | **yollomi** | `models` `generate` `video` `upload` `remove-bg` `edit` `background` `face-swap` `object-remover` `restore` `try-on` `upscale` |
91
+ | **web** | `read` — any URL to Markdown |
92
+ | **weixin** | `download` — 公众号 article to Markdown |
93
+ | **v2ex** (browser) | `daily` `me` `notifications` |
94
+ | **linux-do** (browser) | `categories` `category` |
95
+ | **bloomberg** (browser) | `news` — full article reader |
96
+ | **grok** | `ask` |
97
+ | **doubao** | `status` `new` `send` `read` `ask` |
98
+ | **kimi** | `status` `new` `ask` |
99
+ | **deepseek** | `status` `new` `ask` |
100
+ | **qwen** | `status` `new` `ask` |
101
+
102
+ ### Desktop (CDP/Electron)
103
+
104
+ | Site | Commands |
105
+ |------|----------|
106
+ | **gh** | `repo` `pr` `issue` — passthrough to gh CLI |
107
+ | **cursor** | `status` `send` `read` `new` `dump` `composer` `model` `extract-code` `ask` `screenshot` `history` `export` |
108
+ | **codex** | `status` `send` `read` `new` `dump` `extract-diff` `model` `ask` `screenshot` `history` `export` |
109
+ | **chatgpt** | `status` `new` `send` `read` `ask` |
110
+ | **chatwise** | `status` `new` `send` `read` `ask` `model` `history` `export` `screenshot` |
111
+ | **notion** | `status` `search` `read` `new` `write` `sidebar` `favorites` `export` |
112
+ | **discord-app** | `status` `send` `read` `channels` `servers` `search` `members` |
113
+ | **doubao-app** | `status` `new` `send` `read` `ask` `screenshot` `dump` |
114
+ | **antigravity** | `status` `send` `read` `new` `dump` `extract-code` `model` `watch` |
115
+
116
+ ### Public API (no browser)
117
+
118
+ | Site | Commands |
119
+ |------|----------|
120
+ | **hackernews** | `top` `new` `best` `ask` `show` `jobs` `search` `user` |
121
+ | **v2ex** (public) | `hot` `latest` `topic` `node` `nodes` `member` `user` `replies` |
122
+ | **bbc** | `news` |
123
+ | **lobsters** | `hot` `newest` `active` `tag` |
124
+ | **google** | `news` `search` `suggest` `trends` |
125
+ | **devto** | `top` `tag` `user` |
126
+ | **steam** | `top-sellers` |
127
+ | **apple-podcasts** | `top` `search` `episodes` |
128
+ | **arxiv** | `search` `paper` |
129
+ | **bloomberg** (RSS) | `main` `markets` `tech` `politics` `economics` `opinions` `industries` `businessweek` `feeds` |
130
+ | **dictionary** | `search` `synonyms` `examples` |
131
+ | **hf** | `top` |
132
+ | **stackoverflow** | `hot` `search` `bounties` |
133
+ | **xiaoyuzhou** | `podcast` `podcast-episodes` `episode` |
134
+ | **wikipedia** | `search` `summary` |
135
+ | **producthunt** | `today` `week` `month` `search` |
136
+
137
+ ### Management
138
+
139
+ ```bash
140
+ opencli list [-f json|yaml] # List all commands
141
+ opencli validate [site] # Validate adapter definitions
142
+ opencli doctor # Diagnose browser bridge
143
+ opencli explore <url> # AI-powered API discovery
144
+ opencli record <url> # Record API calls manually
145
+ ```
146
+
147
+ All commands support: `--format` / `-f` with `table` `json` `yaml` `md` `csv`
148
+
149
+ ## Related Skills
150
+
151
+ - **opencli-explorer** — Full guide for creating new adapters (API discovery, auth strategy, YAML/TS writing)
152
+ - **opencli-oneshot** — Quick 4-step template for adding a single command from a URL