@jackwener/opencli 1.1.1 → 1.2.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.
- package/CONTRIBUTING.md +39 -1
- package/README.md +9 -10
- package/README.zh-CN.md +39 -17
- package/SKILL.md +10 -5
- package/dist/browser/cdp.d.ts +4 -4
- package/dist/browser/cdp.js +39 -16
- package/dist/browser/daemon-client.d.ts +2 -1
- package/dist/browser/dom-helpers.js +38 -7
- package/dist/browser/dom-snapshot.d.ts +86 -0
- package/dist/browser/dom-snapshot.js +729 -0
- package/dist/browser/dom-snapshot.test.d.ts +11 -0
- package/dist/browser/dom-snapshot.test.js +212 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.js +1 -0
- package/dist/browser/page.d.ts +14 -24
- package/dist/browser/page.js +37 -4
- package/dist/build-manifest.d.ts +11 -4
- package/dist/build-manifest.js +59 -21
- package/dist/build-manifest.test.js +58 -2
- package/dist/cli-manifest.json +3856 -1509
- package/dist/cli.js +66 -0
- package/dist/clis/barchart/greeks.js +1 -1
- package/dist/clis/barchart/options.js +1 -1
- package/dist/clis/barchart/quote.js +1 -1
- package/dist/clis/bilibili/download.js +1 -1
- package/dist/clis/bilibili/following.js +1 -1
- package/dist/clis/bilibili/subtitle.js +1 -1
- package/dist/clis/bilibili/user-videos.js +1 -1
- package/dist/clis/boss/batchgreet.js +10 -97
- package/dist/clis/boss/chatlist.js +8 -25
- package/dist/clis/boss/chatmsg.js +11 -42
- package/dist/clis/boss/common.d.ts +92 -0
- package/dist/clis/boss/common.js +223 -0
- package/dist/clis/boss/detail.js +7 -49
- package/dist/clis/boss/exchange.js +13 -79
- package/dist/clis/boss/greet.js +18 -145
- package/dist/clis/boss/invite.js +26 -121
- package/dist/clis/boss/joblist.js +6 -31
- package/dist/clis/boss/mark.js +12 -85
- package/dist/clis/boss/recommend.js +10 -49
- package/dist/clis/boss/resume.js +18 -118
- package/dist/clis/boss/search.js +12 -60
- package/dist/clis/boss/send.js +17 -151
- package/dist/clis/boss/stats.js +18 -69
- package/dist/clis/coupang/add-to-cart.js +1 -1
- package/dist/clis/devto/tag.yaml +34 -0
- package/dist/clis/devto/top.yaml +29 -0
- package/dist/clis/devto/user.yaml +33 -0
- package/dist/clis/douban/book-hot.d.ts +1 -0
- package/dist/clis/douban/book-hot.js +14 -0
- package/dist/clis/douban/marks.d.ts +1 -0
- package/dist/clis/douban/marks.js +115 -0
- package/dist/clis/douban/movie-hot.d.ts +1 -0
- package/dist/clis/douban/movie-hot.js +14 -0
- package/dist/clis/douban/reviews.d.ts +1 -0
- package/dist/clis/douban/reviews.js +106 -0
- package/dist/clis/douban/search.d.ts +1 -0
- package/dist/clis/douban/search.js +16 -0
- package/dist/clis/douban/shared.d.ts +4 -0
- package/dist/clis/douban/shared.js +155 -0
- package/dist/clis/douban/subject.yaml +76 -0
- package/dist/clis/douban/top250.yaml +70 -0
- package/dist/clis/douban/utils.d.ts +35 -0
- package/dist/clis/douban/utils.js +48 -0
- package/dist/clis/facebook/add-friend.yaml +43 -0
- package/dist/clis/facebook/events.yaml +44 -0
- package/dist/clis/facebook/feed.yaml +63 -0
- package/dist/clis/facebook/friends.yaml +42 -0
- package/dist/clis/facebook/groups.yaml +50 -0
- package/dist/clis/facebook/join-group.yaml +44 -0
- package/dist/clis/facebook/memories.yaml +39 -0
- package/dist/clis/facebook/notifications.yaml +40 -0
- package/dist/clis/facebook/profile.yaml +37 -0
- package/dist/clis/facebook/search.yaml +46 -0
- package/dist/clis/google/news.d.ts +5 -0
- package/dist/clis/google/news.js +58 -0
- package/dist/clis/google/search.d.ts +10 -0
- package/dist/clis/google/search.js +127 -0
- package/dist/clis/google/suggest.d.ts +5 -0
- package/dist/clis/google/suggest.js +34 -0
- package/dist/clis/google/trends.d.ts +5 -0
- package/dist/clis/google/trends.js +38 -0
- package/dist/clis/google/utils.d.ts +9 -0
- package/dist/clis/google/utils.js +23 -0
- package/dist/clis/google/utils.test.d.ts +1 -0
- package/dist/clis/google/utils.test.js +75 -0
- package/dist/clis/grok/ask.d.ts +14 -0
- package/dist/clis/grok/ask.js +257 -65
- package/dist/clis/grok/ask.test.d.ts +1 -0
- package/dist/clis/grok/ask.test.js +36 -0
- package/dist/clis/instagram/comment.yaml +52 -0
- package/dist/clis/instagram/explore.yaml +43 -0
- package/dist/clis/instagram/follow.yaml +41 -0
- package/dist/clis/instagram/followers.yaml +51 -0
- package/dist/clis/instagram/following.yaml +51 -0
- package/dist/clis/instagram/like.yaml +46 -0
- package/dist/clis/instagram/profile.yaml +42 -0
- package/dist/clis/instagram/save.yaml +46 -0
- package/dist/clis/instagram/saved.yaml +40 -0
- package/dist/clis/instagram/search.yaml +43 -0
- package/dist/clis/instagram/unfollow.yaml +38 -0
- package/dist/clis/instagram/unlike.yaml +46 -0
- package/dist/clis/instagram/unsave.yaml +46 -0
- package/dist/clis/instagram/user.yaml +54 -0
- package/dist/clis/jike/repost.js +1 -1
- package/dist/clis/jimeng/generate.yaml +1 -0
- package/dist/clis/linux-do/category.yaml +1 -0
- package/dist/clis/lobsters/active.yaml +29 -0
- package/dist/clis/lobsters/hot.yaml +29 -0
- package/dist/clis/lobsters/newest.yaml +29 -0
- package/dist/clis/lobsters/tag.yaml +34 -0
- package/dist/clis/medium/feed.d.ts +1 -0
- package/dist/clis/medium/feed.js +15 -0
- package/dist/clis/medium/search.d.ts +1 -0
- package/dist/clis/medium/search.js +15 -0
- package/dist/clis/medium/shared.d.ts +5 -0
- package/dist/clis/medium/shared.js +78 -0
- package/dist/clis/medium/user.d.ts +1 -0
- package/dist/clis/medium/user.js +15 -0
- package/dist/clis/reddit/comment.js +1 -1
- package/dist/clis/reddit/read.js +1 -1
- package/dist/clis/reddit/save.js +1 -1
- package/dist/clis/reddit/subreddit.yaml +1 -0
- package/dist/clis/reddit/subscribe.js +1 -1
- package/dist/clis/reddit/upvote.js +1 -1
- package/dist/clis/sinablog/article.d.ts +1 -0
- package/dist/clis/sinablog/article.js +14 -0
- package/dist/clis/sinablog/hot.d.ts +1 -0
- package/dist/clis/sinablog/hot.js +14 -0
- package/dist/clis/sinablog/search.d.ts +1 -0
- package/dist/clis/sinablog/search.js +51 -0
- package/dist/clis/sinablog/shared.d.ts +7 -0
- package/dist/clis/sinablog/shared.js +187 -0
- package/dist/clis/sinablog/user.d.ts +1 -0
- package/dist/clis/sinablog/user.js +15 -0
- package/dist/clis/substack/feed.d.ts +1 -0
- package/dist/clis/substack/feed.js +15 -0
- package/dist/clis/substack/publication.d.ts +1 -0
- package/dist/clis/substack/publication.js +15 -0
- package/dist/clis/substack/search.d.ts +1 -0
- package/dist/clis/substack/search.js +77 -0
- package/dist/clis/substack/shared.d.ts +4 -0
- package/dist/clis/substack/shared.js +129 -0
- package/dist/clis/tiktok/comment.yaml +66 -0
- package/dist/clis/tiktok/explore.yaml +39 -0
- package/dist/clis/tiktok/follow.yaml +39 -0
- package/dist/clis/tiktok/following.yaml +46 -0
- package/dist/clis/tiktok/friends.yaml +47 -0
- package/dist/clis/tiktok/like.yaml +38 -0
- package/dist/clis/tiktok/live.yaml +51 -0
- package/dist/clis/tiktok/notifications.yaml +52 -0
- package/dist/clis/tiktok/profile.yaml +45 -0
- package/dist/clis/tiktok/save.yaml +34 -0
- package/dist/clis/tiktok/search.yaml +46 -0
- package/dist/clis/tiktok/unfollow.yaml +44 -0
- package/dist/clis/tiktok/unlike.yaml +38 -0
- package/dist/clis/tiktok/unsave.yaml +36 -0
- package/dist/clis/tiktok/user.yaml +44 -0
- package/dist/clis/twitter/download.d.ts +1 -1
- package/dist/clis/twitter/download.js +3 -3
- package/dist/clis/twitter/followers.js +1 -1
- package/dist/clis/twitter/following.js +1 -1
- package/dist/clis/twitter/thread.js +1 -1
- package/dist/clis/twitter/timeline.d.ts +23 -0
- package/dist/clis/twitter/timeline.js +42 -14
- package/dist/clis/twitter/timeline.test.d.ts +1 -0
- package/dist/clis/twitter/timeline.test.js +102 -0
- package/dist/clis/wikipedia/random.d.ts +1 -0
- package/dist/clis/wikipedia/random.js +19 -0
- package/dist/clis/wikipedia/search.js +3 -3
- package/dist/clis/wikipedia/summary.js +4 -9
- package/dist/clis/wikipedia/trending.d.ts +1 -0
- package/dist/clis/wikipedia/trending.js +35 -0
- package/dist/clis/wikipedia/utils.d.ts +28 -0
- package/dist/clis/wikipedia/utils.js +13 -0
- package/dist/clis/xiaohongshu/creator-note-detail.js +1 -1
- package/dist/clis/xiaohongshu/creator-note-detail.test.js +2 -0
- package/dist/clis/xiaohongshu/creator-notes.test.js +2 -0
- package/dist/clis/xiaohongshu/download.js +1 -1
- package/dist/clis/xueqiu/earnings-date.yaml +69 -0
- package/dist/clis/xueqiu/search.yaml +2 -1
- package/dist/clis/xueqiu/stock.yaml +2 -0
- package/dist/clis/yahoo-finance/quote.js +1 -1
- package/dist/commanderAdapter.js +13 -7
- package/dist/discovery.d.ts +8 -0
- package/dist/discovery.js +105 -19
- package/dist/doctor.js +3 -1
- package/dist/doctor.test.js +46 -2
- package/dist/engine.test.d.ts +0 -3
- package/dist/engine.test.js +74 -6
- package/dist/execution.d.ts +4 -2
- package/dist/execution.js +31 -7
- package/dist/explore.d.ts +76 -3
- package/dist/explore.js +11 -4
- package/dist/generate.d.ts +41 -2
- package/dist/generate.js +5 -4
- package/dist/main.js +2 -1
- package/dist/pipeline/executor.d.ts +2 -2
- package/dist/pipeline/executor.js +2 -2
- package/dist/pipeline/executor.test.js +33 -6
- package/dist/pipeline/registry.d.ts +1 -1
- package/dist/pipeline/steps/browser.d.ts +7 -7
- package/dist/pipeline/steps/browser.js +15 -7
- package/dist/pipeline/steps/fetch.d.ts +1 -1
- package/dist/pipeline/steps/fetch.js +11 -7
- package/dist/pipeline/steps/transform.d.ts +6 -5
- package/dist/pipeline/steps/transform.js +30 -9
- package/dist/pipeline/template.d.ts +6 -6
- package/dist/pipeline/template.js +43 -5
- package/dist/pipeline/template.test.js +18 -0
- package/dist/pipeline/transform.test.js +11 -0
- package/dist/plugin.d.ts +31 -0
- package/dist/plugin.js +216 -0
- package/dist/plugin.test.d.ts +4 -0
- package/dist/plugin.test.js +76 -0
- package/dist/registry-api.d.ts +11 -0
- package/dist/registry-api.js +9 -0
- package/dist/registry.d.ts +11 -0
- package/dist/registry.js +6 -1
- package/dist/synthesize.d.ts +94 -4
- package/dist/synthesize.js +5 -4
- package/dist/types.d.ts +39 -26
- package/dist/validate.js +8 -2
- package/docs/.vitepress/config.mts +6 -4
- package/docs/adapters/browser/barchart.md +6 -5
- package/docs/adapters/browser/bilibili.md +9 -0
- package/docs/adapters/browser/devto.md +35 -0
- package/docs/adapters/browser/douban.md +38 -0
- package/docs/adapters/browser/facebook.md +36 -0
- package/docs/adapters/browser/google.md +62 -0
- package/docs/adapters/browser/grok.md +26 -8
- package/docs/adapters/browser/instagram.md +46 -0
- package/docs/adapters/browser/lobsters.md +32 -0
- package/docs/adapters/browser/medium.md +32 -0
- package/docs/adapters/browser/reddit.md +9 -0
- package/docs/adapters/browser/sinablog.md +36 -0
- package/docs/adapters/browser/substack.md +38 -0
- package/docs/adapters/browser/tiktok.md +68 -0
- package/docs/adapters/browser/wikipedia.md +11 -2
- package/docs/adapters/browser/xueqiu.md +10 -0
- package/docs/adapters/browser/yahoo-finance.md +6 -5
- package/docs/adapters/desktop/antigravity.md +6 -0
- package/docs/adapters/desktop/chatgpt.md +2 -1
- package/docs/adapters/desktop/codex.md +5 -1
- package/docs/adapters/desktop/cursor.md +4 -0
- package/docs/adapters/desktop/discord.md +7 -7
- package/docs/adapters/index.md +1 -4
- package/docs/guide/getting-started.md +1 -0
- package/docs/guide/plugins.md +153 -0
- package/docs/zh/guide/plugins.md +107 -0
- package/extension/src/background.ts +18 -11
- package/package.json +10 -5
- package/scripts/clean-dist.cjs +13 -0
- package/src/browser/cdp.ts +71 -31
- package/src/browser/daemon-client.ts +2 -1
- package/src/browser/dom-helpers.ts +38 -7
- package/src/browser/dom-snapshot.test.ts +249 -0
- package/src/browser/dom-snapshot.ts +770 -0
- package/src/browser/index.ts +2 -0
- package/src/browser/page.ts +50 -19
- package/src/build-manifest.test.ts +70 -2
- package/src/build-manifest.ts +94 -26
- package/src/cli.ts +71 -2
- package/src/clis/barchart/greeks.ts +1 -1
- package/src/clis/barchart/options.ts +1 -1
- package/src/clis/barchart/quote.ts +1 -1
- package/src/clis/bilibili/download.ts +1 -1
- package/src/clis/bilibili/following.ts +1 -1
- package/src/clis/bilibili/subtitle.ts +1 -1
- package/src/clis/bilibili/user-videos.ts +1 -1
- package/src/clis/boss/batchgreet.ts +14 -106
- package/src/clis/boss/chatlist.ts +12 -26
- package/src/clis/boss/chatmsg.ts +16 -40
- package/src/clis/boss/common.ts +287 -0
- package/src/clis/boss/detail.ts +8 -54
- package/src/clis/boss/exchange.ts +15 -89
- package/src/clis/boss/greet.ts +23 -160
- package/src/clis/boss/invite.ts +36 -133
- package/src/clis/boss/joblist.ts +7 -36
- package/src/clis/boss/mark.ts +13 -94
- package/src/clis/boss/recommend.ts +12 -57
- package/src/clis/boss/resume.ts +19 -124
- package/src/clis/boss/search.ts +13 -66
- package/src/clis/boss/send.ts +21 -161
- package/src/clis/boss/stats.ts +19 -74
- package/src/clis/coupang/add-to-cart.ts +1 -1
- package/src/clis/devto/tag.yaml +34 -0
- package/src/clis/devto/top.yaml +29 -0
- package/src/clis/devto/user.yaml +33 -0
- package/src/clis/douban/book-hot.ts +15 -0
- package/src/clis/douban/marks.ts +135 -0
- package/src/clis/douban/movie-hot.ts +15 -0
- package/src/clis/douban/reviews.ts +127 -0
- package/src/clis/douban/search.ts +17 -0
- package/src/clis/douban/shared.ts +165 -0
- package/src/clis/douban/subject.yaml +76 -0
- package/src/clis/douban/top250.yaml +70 -0
- package/src/clis/douban/utils.ts +81 -0
- package/src/clis/facebook/add-friend.yaml +43 -0
- package/src/clis/facebook/events.yaml +44 -0
- package/src/clis/facebook/feed.yaml +63 -0
- package/src/clis/facebook/friends.yaml +42 -0
- package/src/clis/facebook/groups.yaml +50 -0
- package/src/clis/facebook/join-group.yaml +44 -0
- package/src/clis/facebook/memories.yaml +39 -0
- package/src/clis/facebook/notifications.yaml +40 -0
- package/src/clis/facebook/profile.yaml +37 -0
- package/src/clis/facebook/search.yaml +46 -0
- package/src/clis/google/news.ts +66 -0
- package/src/clis/google/search.ts +133 -0
- package/src/clis/google/suggest.ts +40 -0
- package/src/clis/google/trends.ts +44 -0
- package/src/clis/google/utils.test.ts +82 -0
- package/src/clis/google/utils.ts +24 -0
- package/src/clis/grok/ask.test.ts +53 -0
- package/src/clis/grok/ask.ts +300 -69
- package/src/clis/instagram/comment.yaml +52 -0
- package/src/clis/instagram/explore.yaml +43 -0
- package/src/clis/instagram/follow.yaml +41 -0
- package/src/clis/instagram/followers.yaml +51 -0
- package/src/clis/instagram/following.yaml +51 -0
- package/src/clis/instagram/like.yaml +46 -0
- package/src/clis/instagram/profile.yaml +42 -0
- package/src/clis/instagram/save.yaml +46 -0
- package/src/clis/instagram/saved.yaml +40 -0
- package/src/clis/instagram/search.yaml +43 -0
- package/src/clis/instagram/unfollow.yaml +38 -0
- package/src/clis/instagram/unlike.yaml +46 -0
- package/src/clis/instagram/unsave.yaml +46 -0
- package/src/clis/instagram/user.yaml +54 -0
- package/src/clis/jike/repost.ts +1 -1
- package/src/clis/jimeng/generate.yaml +1 -0
- package/src/clis/linux-do/category.yaml +1 -0
- package/src/clis/lobsters/active.yaml +29 -0
- package/src/clis/lobsters/hot.yaml +29 -0
- package/src/clis/lobsters/newest.yaml +29 -0
- package/src/clis/lobsters/tag.yaml +34 -0
- package/src/clis/medium/feed.ts +16 -0
- package/src/clis/medium/search.ts +16 -0
- package/src/clis/medium/shared.ts +83 -0
- package/src/clis/medium/user.ts +16 -0
- package/src/clis/reddit/comment.ts +1 -1
- package/src/clis/reddit/read.ts +1 -1
- package/src/clis/reddit/save.ts +1 -1
- package/src/clis/reddit/subreddit.yaml +1 -0
- package/src/clis/reddit/subscribe.ts +1 -1
- package/src/clis/reddit/upvote.ts +1 -1
- package/src/clis/sinablog/article.ts +15 -0
- package/src/clis/sinablog/hot.ts +15 -0
- package/src/clis/sinablog/search.ts +56 -0
- package/src/clis/sinablog/shared.ts +198 -0
- package/src/clis/sinablog/user.ts +16 -0
- package/src/clis/substack/feed.ts +16 -0
- package/src/clis/substack/publication.ts +16 -0
- package/src/clis/substack/search.ts +91 -0
- package/src/clis/substack/shared.ts +132 -0
- package/src/clis/tiktok/comment.yaml +66 -0
- package/src/clis/tiktok/explore.yaml +39 -0
- package/src/clis/tiktok/follow.yaml +39 -0
- package/src/clis/tiktok/following.yaml +46 -0
- package/src/clis/tiktok/friends.yaml +47 -0
- package/src/clis/tiktok/like.yaml +38 -0
- package/src/clis/tiktok/live.yaml +51 -0
- package/src/clis/tiktok/notifications.yaml +52 -0
- package/src/clis/tiktok/profile.yaml +45 -0
- package/src/clis/tiktok/save.yaml +34 -0
- package/src/clis/tiktok/search.yaml +46 -0
- package/src/clis/tiktok/unfollow.yaml +44 -0
- package/src/clis/tiktok/unlike.yaml +38 -0
- package/src/clis/tiktok/unsave.yaml +36 -0
- package/src/clis/tiktok/user.yaml +44 -0
- package/src/clis/twitter/download.ts +3 -3
- package/src/clis/twitter/followers.ts +1 -1
- package/src/clis/twitter/following.ts +1 -1
- package/src/clis/twitter/thread.ts +1 -1
- package/src/clis/twitter/timeline.test.ts +109 -0
- package/src/clis/twitter/timeline.ts +59 -19
- package/src/clis/wikipedia/random.ts +19 -0
- package/src/clis/wikipedia/search.ts +10 -4
- package/src/clis/wikipedia/summary.ts +4 -9
- package/src/clis/wikipedia/trending.ts +41 -0
- package/src/clis/wikipedia/utils.ts +31 -0
- package/src/clis/xiaohongshu/creator-note-detail.test.ts +2 -0
- package/src/clis/xiaohongshu/creator-note-detail.ts +1 -1
- package/src/clis/xiaohongshu/creator-notes.test.ts +2 -0
- package/src/clis/xiaohongshu/download.ts +1 -1
- package/src/clis/xueqiu/earnings-date.yaml +69 -0
- package/src/clis/xueqiu/search.yaml +2 -1
- package/src/clis/xueqiu/stock.yaml +2 -0
- package/src/clis/yahoo-finance/quote.ts +1 -1
- package/src/commanderAdapter.ts +17 -10
- package/src/discovery.ts +134 -24
- package/src/doctor.test.ts +59 -2
- package/src/doctor.ts +4 -2
- package/src/engine.test.ts +79 -6
- package/src/execution.ts +42 -16
- package/src/explore.ts +77 -9
- package/src/generate.ts +58 -9
- package/src/main.ts +2 -1
- package/src/pipeline/executor.test.ts +35 -6
- package/src/pipeline/executor.ts +11 -7
- package/src/pipeline/registry.ts +3 -3
- package/src/pipeline/steps/browser.ts +24 -15
- package/src/pipeline/steps/fetch.ts +18 -13
- package/src/pipeline/steps/transform.ts +40 -15
- package/src/pipeline/template.test.ts +18 -0
- package/src/pipeline/template.ts +86 -13
- package/src/pipeline/transform.test.ts +15 -2
- package/src/plugin.test.ts +86 -0
- package/src/plugin.ts +254 -0
- package/src/registry-api.ts +12 -0
- package/src/registry.ts +19 -1
- package/src/synthesize.ts +102 -21
- package/src/types.ts +44 -12
- package/src/validate.ts +19 -4
- package/tests/e2e/browser-public.test.ts +11 -0
- package/tests/e2e/public-commands.test.ts +64 -0
- package/dist/clis/feishu/new.d.ts +0 -1
- package/dist/clis/feishu/new.js +0 -27
- package/dist/clis/feishu/read.d.ts +0 -1
- package/dist/clis/feishu/read.js +0 -40
- package/dist/clis/feishu/search.d.ts +0 -1
- package/dist/clis/feishu/search.js +0 -30
- package/dist/clis/feishu/send.d.ts +0 -1
- package/dist/clis/feishu/send.js +0 -39
- package/dist/clis/feishu/status.d.ts +0 -1
- package/dist/clis/feishu/status.js +0 -28
- package/dist/clis/neteasemusic/like.d.ts +0 -1
- package/dist/clis/neteasemusic/like.js +0 -25
- package/dist/clis/neteasemusic/lyrics.d.ts +0 -1
- package/dist/clis/neteasemusic/lyrics.js +0 -47
- package/dist/clis/neteasemusic/next.d.ts +0 -1
- package/dist/clis/neteasemusic/next.js +0 -26
- package/dist/clis/neteasemusic/play.d.ts +0 -1
- package/dist/clis/neteasemusic/play.js +0 -26
- package/dist/clis/neteasemusic/playing.d.ts +0 -1
- package/dist/clis/neteasemusic/playing.js +0 -59
- package/dist/clis/neteasemusic/playlist.d.ts +0 -1
- package/dist/clis/neteasemusic/playlist.js +0 -46
- package/dist/clis/neteasemusic/prev.d.ts +0 -1
- package/dist/clis/neteasemusic/prev.js +0 -25
- package/dist/clis/neteasemusic/search.d.ts +0 -1
- package/dist/clis/neteasemusic/search.js +0 -52
- package/dist/clis/neteasemusic/status.d.ts +0 -1
- package/dist/clis/neteasemusic/status.js +0 -16
- package/dist/clis/neteasemusic/volume.d.ts +0 -1
- package/dist/clis/neteasemusic/volume.js +0 -54
- package/dist/clis/wechat/chats.d.ts +0 -1
- package/dist/clis/wechat/chats.js +0 -28
- package/dist/clis/wechat/contacts.d.ts +0 -1
- package/dist/clis/wechat/contacts.js +0 -28
- package/dist/clis/wechat/read.d.ts +0 -1
- package/dist/clis/wechat/read.js +0 -58
- package/dist/clis/wechat/search.d.ts +0 -1
- package/dist/clis/wechat/search.js +0 -31
- package/dist/clis/wechat/send.d.ts +0 -1
- package/dist/clis/wechat/send.js +0 -42
- package/dist/clis/wechat/status.d.ts +0 -1
- package/dist/clis/wechat/status.js +0 -29
- package/dist/pipeline.d.ts +0 -7
- package/dist/pipeline.js +0 -7
- package/docs/adapters/browser/github.md +0 -26
- package/docs/adapters/desktop/feishu.md +0 -20
- package/docs/adapters/desktop/neteasemusic.md +0 -31
- package/docs/adapters/desktop/wechat.md +0 -28
- package/src/clis/antigravity/README.md +0 -5
- package/src/clis/antigravity/README.zh-CN.md +0 -51
- package/src/clis/chaoxing/README.md +0 -14
- package/src/clis/chaoxing/README.zh-CN.md +0 -35
- package/src/clis/chatgpt/README.md +0 -5
- package/src/clis/chatgpt/README.zh-CN.md +0 -44
- package/src/clis/chatwise/README.md +0 -5
- package/src/clis/chatwise/README.zh-CN.md +0 -38
- package/src/clis/codex/README.md +0 -5
- package/src/clis/codex/README.zh-CN.md +0 -33
- package/src/clis/cursor/README.md +0 -5
- package/src/clis/cursor/README.zh-CN.md +0 -33
- package/src/clis/discord-app/README.md +0 -5
- package/src/clis/discord-app/README.zh-CN.md +0 -28
- package/src/clis/feishu/README.md +0 -5
- package/src/clis/feishu/README.zh-CN.md +0 -20
- package/src/clis/feishu/new.ts +0 -32
- package/src/clis/feishu/read.ts +0 -48
- package/src/clis/feishu/search.ts +0 -35
- package/src/clis/feishu/send.ts +0 -46
- package/src/clis/feishu/status.ts +0 -34
- package/src/clis/neteasemusic/README.md +0 -5
- package/src/clis/neteasemusic/README.zh-CN.md +0 -31
- package/src/clis/neteasemusic/like.ts +0 -28
- package/src/clis/neteasemusic/lyrics.ts +0 -53
- package/src/clis/neteasemusic/next.ts +0 -30
- package/src/clis/neteasemusic/play.ts +0 -30
- package/src/clis/neteasemusic/playing.ts +0 -62
- package/src/clis/neteasemusic/playlist.ts +0 -51
- package/src/clis/neteasemusic/prev.ts +0 -29
- package/src/clis/neteasemusic/search.ts +0 -58
- package/src/clis/neteasemusic/status.ts +0 -18
- package/src/clis/neteasemusic/volume.ts +0 -61
- package/src/clis/notion/README.md +0 -5
- package/src/clis/notion/README.zh-CN.md +0 -29
- package/src/clis/wechat/README.md +0 -5
- package/src/clis/wechat/README.zh-CN.md +0 -28
- package/src/clis/wechat/chats.ts +0 -33
- package/src/clis/wechat/contacts.ts +0 -33
- package/src/clis/wechat/read.ts +0 -72
- package/src/clis/wechat/search.ts +0 -36
- package/src/clis/wechat/send.ts +0 -49
- package/src/clis/wechat/status.ts +0 -35
- package/src/pipeline.ts +0 -8
package/CONTRIBUTING.md
CHANGED
|
@@ -40,6 +40,11 @@ strategy: public # public | cookie | header
|
|
|
40
40
|
browser: false # true if browser session is needed
|
|
41
41
|
|
|
42
42
|
args:
|
|
43
|
+
query:
|
|
44
|
+
positional: true
|
|
45
|
+
type: str
|
|
46
|
+
required: true
|
|
47
|
+
description: Search keyword
|
|
43
48
|
limit:
|
|
44
49
|
type: int
|
|
45
50
|
default: 20
|
|
@@ -76,7 +81,7 @@ cli({
|
|
|
76
81
|
domain: 'www.mysite.com',
|
|
77
82
|
strategy: Strategy.COOKIE,
|
|
78
83
|
args: [
|
|
79
|
-
{ name: 'query', required: true, help: 'Search query' },
|
|
84
|
+
{ name: 'query', positional: true, required: true, help: 'Search query' },
|
|
80
85
|
{ name: 'limit', type: 'int', default: 10, help: 'Max results' },
|
|
81
86
|
],
|
|
82
87
|
columns: ['title', 'url', 'date'],
|
|
@@ -118,6 +123,39 @@ opencli <site> <command> --limit 3 -f json
|
|
|
118
123
|
opencli <site> <command> -v
|
|
119
124
|
```
|
|
120
125
|
|
|
126
|
+
## Arg Design Convention
|
|
127
|
+
|
|
128
|
+
Use **positional** for the primary, required argument of a command (the "what" — query, symbol, id, url, username). Use **named options** (`--flag`) for secondary/optional configuration (limit, format, sort, page, filters, language, date).
|
|
129
|
+
|
|
130
|
+
**Rule of thumb**: Think about how the user will type the command. `opencli xueqiu stock SH600519` is more natural than `opencli xueqiu stock --symbol SH600519`.
|
|
131
|
+
|
|
132
|
+
| Arg type | Positional? | Examples |
|
|
133
|
+
|----------|-------------|----------|
|
|
134
|
+
| Main target (query, symbol, id, url, username) | ✅ `positional: true` | `search '茅台'`, `stock SH600519`, `download BV1xxx` |
|
|
135
|
+
| Configuration (limit, format, sort, page, type, filters) | ❌ Named `--flag` | `--limit 10`, `--format json`, `--sort hot`, `--location seattle` |
|
|
136
|
+
|
|
137
|
+
Do **not** convert an argument to positional just because it appears first in the file. If the argument is optional, acts like a filter, or selects a mode/configuration, it should usually stay a named option.
|
|
138
|
+
|
|
139
|
+
YAML example:
|
|
140
|
+
```yaml
|
|
141
|
+
args:
|
|
142
|
+
query:
|
|
143
|
+
positional: true # ← primary arg, user types it directly
|
|
144
|
+
type: str
|
|
145
|
+
required: true
|
|
146
|
+
limit:
|
|
147
|
+
type: int # ← config arg, user types --limit 10
|
|
148
|
+
default: 20
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
TS example:
|
|
152
|
+
```typescript
|
|
153
|
+
args: [
|
|
154
|
+
{ name: 'query', positional: true, required: true, help: 'Search query' },
|
|
155
|
+
{ name: 'limit', type: 'int', default: 10, help: 'Max results' },
|
|
156
|
+
]
|
|
157
|
+
```
|
|
158
|
+
|
|
121
159
|
## Testing
|
|
122
160
|
|
|
123
161
|
See [TESTING.md](./TESTING.md) for the full guide and exact test locations.
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://nodejs.org)
|
|
10
10
|
[](./LICENSE)
|
|
11
11
|
|
|
12
|
-
A CLI tool that turns **any website** or **
|
|
12
|
+
A CLI tool that turns **any website**, **Electron app**, or **local CLI tool** into a command-line interface — Bilibili, Zhihu, 小红书, Twitter/X, Reddit, YouTube, Antigravity, `gh`, `docker`, and [many more](#built-in-commands) — powered by browser session reuse and AI-native discovery.
|
|
13
13
|
|
|
14
14
|
**Built for AI Agents**: Simply configure an instruction in your global `AGENT.md` or `.cursorrules` guiding the AI to execute `opencli list` via Bash to discover available tools. Register your favorite local CLIs (`opencli register mycli`), and the AI will automatically learn how to invoke all your tools perfectly!
|
|
15
15
|
|
|
@@ -25,6 +25,7 @@ Turn ANY Electron application into a CLI tool! Recombine, script, and extend app
|
|
|
25
25
|
- [Quick Start](#quick-start)
|
|
26
26
|
- [Built-in Commands](#built-in-commands)
|
|
27
27
|
- [Desktop App Adapters](#desktop-app-adapters)
|
|
28
|
+
- [External CLI Hub](#external-cli-hub)
|
|
28
29
|
- [Download Support](#download-support)
|
|
29
30
|
- [Output Formats](#output-formats)
|
|
30
31
|
- [For AI Agents (Developer Guide)](#for-ai-agents-developer-guide)
|
|
@@ -127,8 +128,8 @@ Run `opencli list` for the live registry.
|
|
|
127
128
|
| **notion** | `status` `search` `read` `new` `write` `sidebar` `favorites` `export` | Desktop |
|
|
128
129
|
| **discord-app** | `status` `send` `read` `channels` `servers` `search` `members` | Desktop |
|
|
129
130
|
| **v2ex** | `hot` `latest` `topic` `daily` `me` `notifications` | Public / Browser |
|
|
130
|
-
| **xueqiu** | `feed` `hot-stock` `hot` `search` `stock` `watchlist` | Browser |
|
|
131
|
-
| **antigravity** | `status` `send` `read` `new` `dump` `extract-code` `model` `watch` | Desktop |
|
|
131
|
+
| **xueqiu** | `feed` `hot-stock` `hot` `search` `stock` `watchlist` `earnings-date` | Browser |
|
|
132
|
+
| **antigravity** | `status` `send` `read` `new` `dump` `extract-code` `model` `watch` `serve` | Desktop |
|
|
132
133
|
| **chatgpt** | `status` `new` `send` `read` `ask` | Desktop |
|
|
133
134
|
| **xiaohongshu** | `search` `notifications` `feed` `user` `download` `creator-notes` `creator-note-detail` `creator-notes-summary` `creator-profile` `creator-stats` | Browser |
|
|
134
135
|
| **apple-podcasts** | `search` `episodes` `top` | Public |
|
|
@@ -140,7 +141,7 @@ Run `opencli list` for the live registry.
|
|
|
140
141
|
| **bbc** | `news` | Public |
|
|
141
142
|
| **bloomberg** | `main` `markets` `economics` `industries` `tech` `politics` `businessweek` `opinions` `feeds` `news` | Public / Browser |
|
|
142
143
|
| **ctrip** | `search` | Browser |
|
|
143
|
-
| **
|
|
144
|
+
| **devto** | `top` `tag` `user` | Public |
|
|
144
145
|
| **arxiv** | `search` `paper` | Public |
|
|
145
146
|
| **wikipedia** | `search` `summary` | Public |
|
|
146
147
|
| **hackernews** | `top` | Public |
|
|
@@ -160,6 +161,7 @@ Run `opencli list` for the live registry.
|
|
|
160
161
|
| **stackoverflow** | `hot` `search` `bounties` `unanswered` | Public |
|
|
161
162
|
| **steam** | `top-sellers` | Public |
|
|
162
163
|
| **weread** | `shelf` `search` `book` `highlights` `notes` `notebooks` `ranking` | Browser |
|
|
164
|
+
| **douban** | `search` `top250` `subject` `marks` `reviews` | Browser |
|
|
163
165
|
|
|
164
166
|
> **Bloomberg note**: The RSS-backed Bloomberg listing commands (`main`, section feeds, `feeds`) work without a browser. `bloomberg news` is for standard Bloomberg story/article pages that your current Chrome session can already access. Audio and some other non-standard pages may fail, and OpenCLI does not bypass Bloomberg paywall or entitlement checks.
|
|
165
167
|
|
|
@@ -198,9 +200,6 @@ Each desktop adapter has its own detailed documentation with commands reference,
|
|
|
198
200
|
| **ChatWise** | Multi-LLM client (GPT-4, Claude, Gemini) | [Doc](./docs/adapters/desktop/chatwise.md) |
|
|
199
201
|
| **Notion** | Search, read, write Notion pages | [Doc](./docs/adapters/desktop/notion.md) |
|
|
200
202
|
| **Discord** | Discord Desktop — messages, channels, servers | [Doc](./docs/adapters/desktop/discord.md) |
|
|
201
|
-
| **Feishu** | 飞书/Lark Desktop via AppleScript | [Doc](./docs/adapters/desktop/feishu.md) |
|
|
202
|
-
| **WeChat** | 微信 Desktop via AppleScript + Accessibility | [Doc](./docs/adapters/desktop/wechat.md) |
|
|
203
|
-
| **NeteaseMusic** | 网易云音乐 Desktop via CEF/CDP | [Doc](./docs/adapters/desktop/neteasemusic.md) |
|
|
204
203
|
|
|
205
204
|
## Download Support
|
|
206
205
|
|
|
@@ -230,11 +229,11 @@ brew install yt-dlp
|
|
|
230
229
|
|
|
231
230
|
```bash
|
|
232
231
|
# Download images/videos from Xiaohongshu note
|
|
233
|
-
opencli xiaohongshu download
|
|
232
|
+
opencli xiaohongshu download abc123 --output ./xhs
|
|
234
233
|
|
|
235
234
|
# Download Bilibili video (requires yt-dlp)
|
|
236
|
-
opencli bilibili download
|
|
237
|
-
opencli bilibili download
|
|
235
|
+
opencli bilibili download BV1xxx --output ./bilibili
|
|
236
|
+
opencli bilibili download BV1xxx --quality 1080p # Specify quality
|
|
238
237
|
|
|
239
238
|
# Download Twitter media from user
|
|
240
239
|
opencli twitter download elonmusk --limit 20 --output ./twitter
|
package/README.zh-CN.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://nodejs.org)
|
|
10
10
|
[](./LICENSE)
|
|
11
11
|
|
|
12
|
-
OpenCLI
|
|
12
|
+
OpenCLI 将任何网站、本地 CLI 或 Electron 应用(如 Antigravity)变成命令行工具 — B站、知乎、小红书、Twitter/X、Reddit、YouTube,以及 `gh`、`docker` 等[多种站点与工具](#内置命令) — 复用浏览器登录态,AI 驱动探索。
|
|
13
13
|
|
|
14
14
|
**专为 AI Agent 打造**:只需在全局 `.cursorrules` 或 `AGENT.md` 中配置简单指令,引导 AI 通过 Bash 执行 `opencli list` 来检索可用的 CLI 工具及其用法。随后,将你常用的 CLI 列表整合注册进去(`opencli register mycli`),AI 便能瞬间学会自动调用相应的本地工具!
|
|
15
15
|
|
|
@@ -27,6 +27,7 @@ CLI all electron!现在支持把所有 electron 应用 CLI 化,从而组合
|
|
|
27
27
|
- [快速开始](#快速开始)
|
|
28
28
|
- [内置命令](#内置命令)
|
|
29
29
|
- [桌面应用适配器](#桌面应用适配器)
|
|
30
|
+
- [外部 CLI 枢纽](#外部-cli-枢纽)
|
|
30
31
|
- [下载支持](#下载支持)
|
|
31
32
|
- [输出格式](#输出格式)
|
|
32
33
|
- [致 AI Agent(开发者指南)](#致-ai-agent开发者指南)
|
|
@@ -42,6 +43,7 @@ CLI all electron!现在支持把所有 electron 应用 CLI 化,从而组合
|
|
|
42
43
|
- **CLI All Electron** — 支持把所有 electron 应用(如 Antigravity Ultra)CLI 化,让 AI 控制自己!
|
|
43
44
|
- **多站点覆盖** — 覆盖 B站、知乎、小红书、Twitter、Reddit,以及多种桌面应用
|
|
44
45
|
- **零风控** — 复用 Chrome 登录态,无需存储任何凭证
|
|
46
|
+
- **外部 CLI 枢纽** — 统一发现、自动安装、透传执行 `gh`、`docker`、`kubectl` 等本地 CLI
|
|
45
47
|
- **自修复配置** — `opencli setup` 检查 Browser Bridge 连通性;`opencli doctor` 诊断 daemon、扩展和浏览器连接状态
|
|
46
48
|
- **AI 原生** — `explore` 自动发现 API,`synthesize` 生成适配器,`cascade` 探测认证策略
|
|
47
49
|
- **动态加载引擎** — 声明式的 `.yaml` 或者底层定制的 `.ts` 适配器,放入 `clis/` 文件夹即可自动注册生效
|
|
@@ -127,8 +129,8 @@ npm install -g @jackwener/opencli@latest
|
|
|
127
129
|
| **notion** | `status` `search` `read` `new` `write` `sidebar` `favorites` `export` | 桌面端 |
|
|
128
130
|
| **discord-app** | `status` `send` `read` `channels` `servers` `search` `members` | 桌面端 |
|
|
129
131
|
| **v2ex** | `hot` `latest` `topic` `daily` `me` `notifications` | 公开 / 浏览器 |
|
|
130
|
-
| **xueqiu** | `feed` `hot-stock` `hot` `search` `stock` `watchlist` | 浏览器 |
|
|
131
|
-
| **antigravity** | `status` `send` `read` `new` `dump` `extract-code` `model` `watch` | 桌面端 |
|
|
132
|
+
| **xueqiu** | `feed` `hot-stock` `hot` `search` `stock` `watchlist` `earnings-date` | 浏览器 |
|
|
133
|
+
| **antigravity** | `status` `send` `read` `new` `dump` `extract-code` `model` `watch` `serve` | 桌面端 |
|
|
132
134
|
| **chatgpt** | `status` `new` `send` `read` `ask` | 桌面端 |
|
|
133
135
|
| **xiaohongshu** | `search` `notifications` `feed` `user` `download` `creator-notes` `creator-note-detail` `creator-notes-summary` `creator-profile` `creator-stats` | 浏览器 |
|
|
134
136
|
| **apple-podcasts** | `search` `episodes` `top` | 公开 |
|
|
@@ -140,7 +142,7 @@ npm install -g @jackwener/opencli@latest
|
|
|
140
142
|
| **bbc** | `news` | 公共 API |
|
|
141
143
|
| **bloomberg** | `main` `markets` `economics` `industries` `tech` `politics` `businessweek` `opinions` `feeds` `news` | 公共 API / 浏览器 |
|
|
142
144
|
| **ctrip** | `search` | 浏览器 |
|
|
143
|
-
| **
|
|
145
|
+
| **devto** | `top` `tag` `user` | 公开 |
|
|
144
146
|
| **arxiv** | `search` `paper` | 公开 |
|
|
145
147
|
| **wikipedia** | `search` `summary` | 公开 |
|
|
146
148
|
| **hackernews** | `top` | 公共 API |
|
|
@@ -160,25 +162,45 @@ npm install -g @jackwener/opencli@latest
|
|
|
160
162
|
| **stackoverflow** | `hot` `search` `bounties` `unanswered` | 公开 |
|
|
161
163
|
| **steam** | `top-sellers` | 公开 |
|
|
162
164
|
| **weread** | `shelf` `search` `book` `highlights` `notes` `notebooks` `ranking` | 浏览器 |
|
|
165
|
+
| **douban** | `search` `top250` `subject` `marks` `reviews` | 浏览器 |
|
|
163
166
|
|
|
164
167
|
> **Bloomberg 说明**:Bloomberg 的 RSS 列表命令(`main`、各栏目 feed、`feeds`)无需浏览器即可使用。`bloomberg news` 适用于当前 Chrome 会话本身就能访问的标准 Bloomberg 文章页。音频页和部分非标准页面可能失败,OpenCLI 也不会绕过 Bloomberg 的付费墙、登录或权限校验。
|
|
165
168
|
|
|
169
|
+
### 外部 CLI 枢纽
|
|
170
|
+
|
|
171
|
+
OpenCLI 也可以作为你现有命令行工具的统一入口,负责发现、自动安装和纯透传执行。
|
|
172
|
+
|
|
173
|
+
| 外部 CLI | 描述 | 示例 |
|
|
174
|
+
|----------|------|------|
|
|
175
|
+
| **gh** | GitHub CLI | `opencli gh pr list --limit 5` |
|
|
176
|
+
| **obsidian** | Obsidian 仓库管理 | `opencli obsidian search query="AI"` |
|
|
177
|
+
| **docker** | Docker 命令行工具 | `opencli docker ps` |
|
|
178
|
+
| **kubectl** | Kubernetes CLI | `opencli kubectl get pods` |
|
|
179
|
+
| **readwise** | Readwise / Reader CLI | `opencli readwise login` |
|
|
180
|
+
|
|
181
|
+
**零配置透传**:OpenCLI 会把你的输入原样转发给底层二进制,保留原生 stdout / stderr 行为。
|
|
182
|
+
|
|
183
|
+
**自动安装**:如果你运行 `opencli gh ...` 时系统中还没有 `gh`,OpenCLI 会优先尝试通过系统包管理器安装,然后自动重试命令。
|
|
184
|
+
|
|
185
|
+
**注册自定义本地 CLI**:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
opencli register mycli
|
|
189
|
+
```
|
|
190
|
+
|
|
166
191
|
### 桌面应用适配器
|
|
167
192
|
|
|
168
193
|
每个桌面适配器都有自己详细的文档说明,包括命令参考、启动配置与使用示例:
|
|
169
194
|
|
|
170
195
|
| 应用 | 描述 | 文档 |
|
|
171
196
|
|-----|-------------|-----|
|
|
172
|
-
| **Cursor** | 控制 Cursor IDE — Composer、对话、代码提取等 | [
|
|
173
|
-
| **Codex** | 在后台(无头)驱动 OpenAI Codex CLI Agent | [
|
|
174
|
-
| **Antigravity** | 在终端直接控制 Antigravity Ultra | [
|
|
175
|
-
| **ChatGPT** | 自动化操作 ChatGPT macOS 桌面客户端 | [
|
|
176
|
-
| **ChatWise** | 多 LLM 客户端(GPT-4、Claude、Gemini) | [
|
|
177
|
-
| **Notion** | 搜索、读取、写入 Notion 页面 | [
|
|
178
|
-
| **Discord** | Discord 桌面版 — 消息、频道、服务器 | [
|
|
179
|
-
| **Feishu** | 飞书/Lark 桌面版 (AppleScript 驱动) | [README](./src/clis/feishu/README.md) |
|
|
180
|
-
| **WeChat** | 微信 Mac 桌面端 (AppleScript + 无障碍接口) | [README](./src/clis/wechat/README.md) |
|
|
181
|
-
| **NeteaseMusic** | 网易云音乐 (CEF/CDP 驱动) | [README](./src/clis/neteasemusic/README.md) |
|
|
197
|
+
| **Cursor** | 控制 Cursor IDE — Composer、对话、代码提取等 | [Doc](./docs/adapters/desktop/cursor.md) |
|
|
198
|
+
| **Codex** | 在后台(无头)驱动 OpenAI Codex CLI Agent | [Doc](./docs/adapters/desktop/codex.md) |
|
|
199
|
+
| **Antigravity** | 在终端直接控制 Antigravity Ultra | [Doc](./docs/adapters/desktop/antigravity.md) |
|
|
200
|
+
| **ChatGPT** | 自动化操作 ChatGPT macOS 桌面客户端 | [Doc](./docs/adapters/desktop/chatgpt.md) |
|
|
201
|
+
| **ChatWise** | 多 LLM 客户端(GPT-4、Claude、Gemini) | [Doc](./docs/adapters/desktop/chatwise.md) |
|
|
202
|
+
| **Notion** | 搜索、读取、写入 Notion 页面 | [Doc](./docs/adapters/desktop/notion.md) |
|
|
203
|
+
| **Discord** | Discord 桌面版 — 消息、频道、服务器 | [Doc](./docs/adapters/desktop/discord.md) |
|
|
182
204
|
|
|
183
205
|
## 下载支持
|
|
184
206
|
|
|
@@ -208,11 +230,11 @@ brew install yt-dlp
|
|
|
208
230
|
|
|
209
231
|
```bash
|
|
210
232
|
# 下载小红书笔记中的图片/视频
|
|
211
|
-
opencli xiaohongshu download
|
|
233
|
+
opencli xiaohongshu download abc123 --output ./xhs
|
|
212
234
|
|
|
213
235
|
# 下载B站视频(需要 yt-dlp)
|
|
214
|
-
opencli bilibili download
|
|
215
|
-
opencli bilibili download
|
|
236
|
+
opencli bilibili download BV1xxx --output ./bilibili
|
|
237
|
+
opencli bilibili download BV1xxx --quality 1080p # 指定画质
|
|
216
238
|
|
|
217
239
|
# 下载 Twitter 用户的媒体
|
|
218
240
|
opencli twitter download elonmusk --limit 20 --output ./twitter
|
package/SKILL.md
CHANGED
|
@@ -39,7 +39,7 @@ Browser commands require:
|
|
|
39
39
|
|
|
40
40
|
> **Note**: You must be logged into the target website in Chrome before running commands. Tabs opened during command execution are auto-closed afterwards.
|
|
41
41
|
|
|
42
|
-
Public API commands (`hackernews`, `
|
|
42
|
+
Public API commands (`hackernews`, `v2ex`) need no browser.
|
|
43
43
|
|
|
44
44
|
## Commands Reference
|
|
45
45
|
|
|
@@ -83,8 +83,10 @@ opencli xueqiu feed # 我的关注 timeline
|
|
|
83
83
|
opencli xueqiu hot --limit 10 # 雪球热榜
|
|
84
84
|
opencli xueqiu search "特斯拉" # 搜索 (query positional)
|
|
85
85
|
|
|
86
|
-
# GitHub (
|
|
87
|
-
opencli
|
|
86
|
+
# GitHub (via gh External CLI)
|
|
87
|
+
opencli gh repo list # 列出仓库 (passthrough to gh)
|
|
88
|
+
opencli gh pr list --limit 5 # PR 列表
|
|
89
|
+
opencli gh issue list # Issue 列表
|
|
88
90
|
|
|
89
91
|
# Twitter/X (browser)
|
|
90
92
|
opencli twitter trending --limit 10 # 热门话题
|
|
@@ -176,9 +178,11 @@ opencli antigravity status # 检查 CDP 连接
|
|
|
176
178
|
opencli antigravity send "hello" # 发送文本到当前 agent 聊天框
|
|
177
179
|
opencli antigravity read # 读取整个聊天记录面板
|
|
178
180
|
opencli antigravity new # 清空聊天、开启新对话
|
|
181
|
+
opencli antigravity dump # 导出 DOM 和快照调试信息
|
|
179
182
|
opencli antigravity extract-code # 自动抽取 AI 回复中的代码块
|
|
180
183
|
opencli antigravity model claude # 切换底层模型
|
|
181
184
|
opencli antigravity watch # 流式监听增量消息
|
|
185
|
+
opencli antigravity serve --port 8082 # 启动 Anthropic 兼容代理
|
|
182
186
|
|
|
183
187
|
# Barchart (browser)
|
|
184
188
|
opencli barchart quote --symbol AAPL # 股票行情
|
|
@@ -218,8 +222,9 @@ opencli weread ranking --limit 10 # 排行榜
|
|
|
218
222
|
opencli jimeng generate --prompt "描述" # AI 生图
|
|
219
223
|
opencli jimeng history --limit 10 # 生成历史
|
|
220
224
|
|
|
221
|
-
# Grok (
|
|
222
|
-
opencli grok ask "问题"
|
|
225
|
+
# Grok (default + explicit web)
|
|
226
|
+
opencli grok ask --prompt "问题" # 提问 Grok(兼容默认路径)
|
|
227
|
+
opencli grok ask --prompt "问题" --web # 显式 grok.com consumer web UI 路径
|
|
223
228
|
|
|
224
229
|
# HuggingFace (public)
|
|
225
230
|
opencli hf top --limit 10 # 热门模型
|
package/dist/browser/cdp.d.ts
CHANGED
|
@@ -25,13 +25,13 @@ export declare class CDPBridge {
|
|
|
25
25
|
}): Promise<IPage>;
|
|
26
26
|
close(): Promise<void>;
|
|
27
27
|
/** Send a CDP command with timeout guard (P0 fix #4) */
|
|
28
|
-
send(method: string, params?:
|
|
28
|
+
send(method: string, params?: Record<string, unknown>, timeoutMs?: number): Promise<unknown>;
|
|
29
29
|
/** Listen for a CDP event */
|
|
30
|
-
on(event: string, handler: (params:
|
|
30
|
+
on(event: string, handler: (params: unknown) => void): void;
|
|
31
31
|
/** Remove a CDP event listener */
|
|
32
|
-
off(event: string, handler: (params:
|
|
32
|
+
off(event: string, handler: (params: unknown) => void): void;
|
|
33
33
|
/** Wait for a CDP event to fire (one-shot) */
|
|
34
|
-
waitForEvent(event: string, timeoutMs?: number): Promise<
|
|
34
|
+
waitForEvent(event: string, timeoutMs?: number): Promise<unknown>;
|
|
35
35
|
}
|
|
36
36
|
declare function selectCDPTarget(targets: CDPTarget[]): CDPTarget | undefined;
|
|
37
37
|
declare function scoreCDPTarget(target: CDPTarget, preferredPattern?: RegExp): number;
|
package/dist/browser/cdp.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { WebSocket } from 'ws';
|
|
11
11
|
import { wrapForEval } from './utils.js';
|
|
12
|
+
import { generateSnapshotJs, scrollToRefJs, getFormStateJs } from './dom-snapshot.js';
|
|
12
13
|
import { clickJs, typeTextJs, pressKeyJs, waitForTextJs, scrollJs, autoScrollJs, networkRequestsJs, } from './dom-helpers.js';
|
|
13
14
|
const CDP_SEND_TIMEOUT = 30_000; // 30s per command
|
|
14
15
|
export class CDPBridge {
|
|
@@ -35,7 +36,8 @@ export class CDPBridge {
|
|
|
35
36
|
}
|
|
36
37
|
return new Promise((resolve, reject) => {
|
|
37
38
|
const ws = new WebSocket(wsUrl);
|
|
38
|
-
const
|
|
39
|
+
const timeoutMs = (opts?.timeout ?? 10) * 1000; // opts.timeout is in seconds
|
|
40
|
+
const timeout = setTimeout(() => reject(new Error('CDP connect timeout')), timeoutMs);
|
|
39
41
|
ws.on('open', () => {
|
|
40
42
|
clearTimeout(timeout);
|
|
41
43
|
this._ws = ws;
|
|
@@ -163,14 +165,22 @@ class CDPPage {
|
|
|
163
165
|
}
|
|
164
166
|
async getCookies(opts = {}) {
|
|
165
167
|
const result = await this.bridge.send('Network.getCookies', opts.url ? { urls: [opts.url] } : {});
|
|
166
|
-
const cookies = Array.isArray(result
|
|
167
|
-
|
|
168
|
-
|
|
168
|
+
const cookies = isRecord(result) && Array.isArray(result.cookies) ? result.cookies : [];
|
|
169
|
+
const domain = opts.domain;
|
|
170
|
+
return domain
|
|
171
|
+
? cookies.filter((cookie) => isCookie(cookie) && cookie.domain.includes(domain))
|
|
169
172
|
: cookies;
|
|
170
173
|
}
|
|
171
|
-
async snapshot(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
+
async snapshot(opts = {}) {
|
|
175
|
+
const snapshotJs = generateSnapshotJs({
|
|
176
|
+
viewportExpand: opts.viewportExpand ?? 800,
|
|
177
|
+
maxDepth: Math.max(1, Math.min(Number(opts.maxDepth) || 50, 200)),
|
|
178
|
+
interactiveOnly: opts.interactive ?? false,
|
|
179
|
+
maxTextLength: opts.maxTextLength ?? 120,
|
|
180
|
+
includeScrollInfo: true,
|
|
181
|
+
bboxDedup: true,
|
|
182
|
+
});
|
|
183
|
+
return this.evaluate(snapshotJs);
|
|
174
184
|
}
|
|
175
185
|
// ── Shared DOM operations (P1 fix #5 — using dom-helpers.ts) ──
|
|
176
186
|
async click(ref) {
|
|
@@ -182,13 +192,20 @@ class CDPPage {
|
|
|
182
192
|
async pressKey(key) {
|
|
183
193
|
await this.evaluate(pressKeyJs(key));
|
|
184
194
|
}
|
|
195
|
+
async scrollTo(ref) {
|
|
196
|
+
return this.evaluate(scrollToRefJs(ref));
|
|
197
|
+
}
|
|
198
|
+
async getFormState() {
|
|
199
|
+
return (await this.evaluate(getFormStateJs()));
|
|
200
|
+
}
|
|
185
201
|
async wait(options) {
|
|
186
202
|
if (typeof options === 'number') {
|
|
187
203
|
await new Promise(resolve => setTimeout(resolve, options * 1000));
|
|
188
204
|
return;
|
|
189
205
|
}
|
|
190
|
-
if (options.time) {
|
|
191
|
-
|
|
206
|
+
if (typeof options.time === 'number') {
|
|
207
|
+
const waitTime = options.time;
|
|
208
|
+
await new Promise(resolve => setTimeout(resolve, waitTime * 1000));
|
|
192
209
|
return;
|
|
193
210
|
}
|
|
194
211
|
if (options.text) {
|
|
@@ -211,7 +228,7 @@ class CDPPage {
|
|
|
211
228
|
quality: options.format === 'jpeg' ? (options.quality ?? 80) : undefined,
|
|
212
229
|
captureBeyondViewport: options.fullPage ?? false,
|
|
213
230
|
});
|
|
214
|
-
const base64 = result.data;
|
|
231
|
+
const base64 = isRecord(result) && typeof result.data === 'string' ? result.data : '';
|
|
215
232
|
if (options.path) {
|
|
216
233
|
const fs = await import('node:fs');
|
|
217
234
|
const path = await import('node:path');
|
|
@@ -222,7 +239,8 @@ class CDPPage {
|
|
|
222
239
|
return base64;
|
|
223
240
|
}
|
|
224
241
|
async networkRequests(includeStatic = false) {
|
|
225
|
-
|
|
242
|
+
const result = await this.evaluate(networkRequestsJs(includeStatic));
|
|
243
|
+
return Array.isArray(result) ? result : [];
|
|
226
244
|
}
|
|
227
245
|
async tabs() {
|
|
228
246
|
return [];
|
|
@@ -249,9 +267,18 @@ class CDPPage {
|
|
|
249
267
|
async getInterceptedRequests() {
|
|
250
268
|
const { generateReadInterceptedJs } = await import('../interceptor.js');
|
|
251
269
|
const result = await this.evaluate(generateReadInterceptedJs('__opencli_xhr'));
|
|
252
|
-
return result
|
|
270
|
+
return Array.isArray(result) ? result : [];
|
|
253
271
|
}
|
|
254
272
|
}
|
|
273
|
+
function isRecord(value) {
|
|
274
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
275
|
+
}
|
|
276
|
+
function isCookie(value) {
|
|
277
|
+
return isRecord(value)
|
|
278
|
+
&& typeof value.name === 'string'
|
|
279
|
+
&& typeof value.value === 'string'
|
|
280
|
+
&& typeof value.domain === 'string';
|
|
281
|
+
}
|
|
255
282
|
// ── CDP target selection (unchanged) ──
|
|
256
283
|
function selectCDPTarget(targets) {
|
|
257
284
|
const preferredPattern = compilePreferredPattern(process.env.OPENCLI_CDP_TARGET);
|
|
@@ -311,8 +338,6 @@ function scoreCDPTarget(target, preferredPattern) {
|
|
|
311
338
|
score += 120;
|
|
312
339
|
if (title.includes('discord'))
|
|
313
340
|
score += 120;
|
|
314
|
-
if (title.includes('netease'))
|
|
315
|
-
score += 120;
|
|
316
341
|
if (url.includes('antigravity'))
|
|
317
342
|
score += 100;
|
|
318
343
|
if (url.includes('codex'))
|
|
@@ -325,8 +350,6 @@ function scoreCDPTarget(target, preferredPattern) {
|
|
|
325
350
|
score += 100;
|
|
326
351
|
if (url.includes('discord'))
|
|
327
352
|
score += 100;
|
|
328
|
-
if (url.includes('netease'))
|
|
329
|
-
score += 100;
|
|
330
353
|
return score;
|
|
331
354
|
}
|
|
332
355
|
function compilePreferredPattern(raw) {
|
|
@@ -36,4 +36,5 @@ export declare function isExtensionConnected(): Promise<boolean>;
|
|
|
36
36
|
* Retries up to 3 times with 500ms delay for transient failures.
|
|
37
37
|
*/
|
|
38
38
|
export declare function sendCommand(action: DaemonCommand['action'], params?: Omit<DaemonCommand, 'id' | 'action'>): Promise<unknown>;
|
|
39
|
-
export declare function listSessions(): Promise<
|
|
39
|
+
export declare function listSessions(): Promise<BrowserSessionInfo[]>;
|
|
40
|
+
import type { BrowserSessionInfo } from '../types.js';
|
|
@@ -10,8 +10,21 @@ export function clickJs(ref) {
|
|
|
10
10
|
return `
|
|
11
11
|
(() => {
|
|
12
12
|
const ref = ${safeRef};
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
// 1. data-opencli-ref (set by snapshot engine)
|
|
14
|
+
let el = document.querySelector('[data-opencli-ref="' + ref + '"]');
|
|
15
|
+
// 2. data-ref (legacy)
|
|
16
|
+
if (!el) el = document.querySelector('[data-ref="' + ref + '"]');
|
|
17
|
+
// 3. CSS selector
|
|
18
|
+
if (!el && ref.match(/^[a-zA-Z#.\\[]/)) {
|
|
19
|
+
try { el = document.querySelector(ref); } catch {}
|
|
20
|
+
}
|
|
21
|
+
// 4. Numeric index into interactive elements
|
|
22
|
+
if (!el) {
|
|
23
|
+
const idx = parseInt(ref, 10);
|
|
24
|
+
if (!isNaN(idx)) {
|
|
25
|
+
el = document.querySelectorAll('a, button, input, select, textarea, [role="button"], [tabindex]:not([tabindex="-1"])')[idx];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
15
28
|
if (!el) throw new Error('Element not found: ' + ref);
|
|
16
29
|
el.scrollIntoView({ behavior: 'instant', block: 'center' });
|
|
17
30
|
el.click();
|
|
@@ -26,13 +39,31 @@ export function typeTextJs(ref, text) {
|
|
|
26
39
|
return `
|
|
27
40
|
(() => {
|
|
28
41
|
const ref = ${safeRef};
|
|
29
|
-
|
|
30
|
-
|
|
42
|
+
// 1. data-opencli-ref (set by snapshot engine)
|
|
43
|
+
let el = document.querySelector('[data-opencli-ref="' + ref + '"]');
|
|
44
|
+
// 2. data-ref (legacy)
|
|
45
|
+
if (!el) el = document.querySelector('[data-ref="' + ref + '"]');
|
|
46
|
+
// 3. CSS selector
|
|
47
|
+
if (!el && ref.match(/^[a-zA-Z#.\\[]/)) {
|
|
48
|
+
try { el = document.querySelector(ref); } catch {}
|
|
49
|
+
}
|
|
50
|
+
// 4. Numeric index into typeable elements
|
|
51
|
+
if (!el) {
|
|
52
|
+
const idx = parseInt(ref, 10);
|
|
53
|
+
if (!isNaN(idx)) {
|
|
54
|
+
el = document.querySelectorAll('input, textarea, [contenteditable="true"]')[idx];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
31
57
|
if (!el) throw new Error('Element not found: ' + ref);
|
|
32
58
|
el.focus();
|
|
33
|
-
el.
|
|
34
|
-
|
|
35
|
-
|
|
59
|
+
if (el.isContentEditable) {
|
|
60
|
+
el.textContent = ${safeText};
|
|
61
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
62
|
+
} else {
|
|
63
|
+
el.value = ${safeText};
|
|
64
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
65
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
66
|
+
}
|
|
36
67
|
return 'typed';
|
|
37
68
|
})()
|
|
38
69
|
`;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM Snapshot Engine — Advanced DOM pruning for LLM consumption.
|
|
3
|
+
*
|
|
4
|
+
* Inspired by browser-use's multi-layer pruning pipeline, adapted for opencli's
|
|
5
|
+
* Chrome Extension + CDP architecture. Runs entirely in-page via Runtime.evaluate.
|
|
6
|
+
*
|
|
7
|
+
* Pipeline:
|
|
8
|
+
* 1. Walk DOM tree, collect visibility + layout + interactivity signals
|
|
9
|
+
* 2. Prune invisible, zero-area, non-content elements
|
|
10
|
+
* 3. SVG & decoration collapse
|
|
11
|
+
* 4. Shadow DOM traversal
|
|
12
|
+
* 5. Same-origin iframe content extraction
|
|
13
|
+
* 6. Bounding-box parent-child dedup (link/button wrapping children)
|
|
14
|
+
* 7. Paint-order occlusion detection (overlay/modal coverage)
|
|
15
|
+
* 8. Attribute whitelist filtering
|
|
16
|
+
* 9. Table-aware serialization (markdown tables)
|
|
17
|
+
* 10. Token-efficient serialization with interactive indices
|
|
18
|
+
* 11. data-ref annotation for click/type targeting
|
|
19
|
+
* 12. Hidden interactive element hints (scroll-to-reveal)
|
|
20
|
+
* 13. Incremental diff (mark new elements with *)
|
|
21
|
+
*
|
|
22
|
+
* Additional tools:
|
|
23
|
+
* - scrollToRefJs(ref) — scroll to a data-opencli-ref element
|
|
24
|
+
* - getFormStateJs() — extract all form fields as structured JSON
|
|
25
|
+
*/
|
|
26
|
+
export interface SnapshotOptions {
|
|
27
|
+
/** Extra pixels beyond viewport to include (default 800) */
|
|
28
|
+
viewportExpand?: number;
|
|
29
|
+
/** Maximum DOM depth to traverse (default 50) */
|
|
30
|
+
maxDepth?: number;
|
|
31
|
+
/** Only emit interactive elements and their landmark ancestors */
|
|
32
|
+
interactiveOnly?: boolean;
|
|
33
|
+
/** Maximum text content length per node (default 120) */
|
|
34
|
+
maxTextLength?: number;
|
|
35
|
+
/** Include scroll position info on scrollable containers (default true) */
|
|
36
|
+
includeScrollInfo?: boolean;
|
|
37
|
+
/** Enable bounding-box parent-child dedup (default true) */
|
|
38
|
+
bboxDedup?: boolean;
|
|
39
|
+
/** Traverse Shadow DOM roots (default true) */
|
|
40
|
+
includeShadowDom?: boolean;
|
|
41
|
+
/** Extract same-origin iframe content (default true) */
|
|
42
|
+
includeIframes?: boolean;
|
|
43
|
+
/** Maximum number of iframes to process (default 5) */
|
|
44
|
+
maxIframes?: number;
|
|
45
|
+
/** Enable paint-order occlusion detection (default true) */
|
|
46
|
+
paintOrderCheck?: boolean;
|
|
47
|
+
/** Annotate interactive elements with data-opencli-ref (default true) */
|
|
48
|
+
annotateRefs?: boolean;
|
|
49
|
+
/** Report hidden interactive elements outside viewport (default true) */
|
|
50
|
+
reportHidden?: boolean;
|
|
51
|
+
/** Filter ad/noise elements (default true) */
|
|
52
|
+
filterAds?: boolean;
|
|
53
|
+
/** Serialize tables as markdown (default true) */
|
|
54
|
+
markdownTables?: boolean;
|
|
55
|
+
/** Previous snapshot hash set (JSON array of hashes) for diff marking (default null) */
|
|
56
|
+
previousHashes?: string | null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Generate JS to scroll to an element identified by data-opencli-ref.
|
|
60
|
+
* Completes the snapshot→action loop: snapshot identifies `[3]<button>`,
|
|
61
|
+
* caller can then `scrollToRef('3')` to bring it into view.
|
|
62
|
+
*/
|
|
63
|
+
export declare function scrollToRefJs(ref: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Generate JS to extract all form field values from the page.
|
|
66
|
+
* Returns structured JSON: { forms: [{ id, action, fields: [{ tag, type, name, value, ... }] }] }
|
|
67
|
+
*/
|
|
68
|
+
export declare function getFormStateJs(): string;
|
|
69
|
+
/**
|
|
70
|
+
* Generate JavaScript code that, when evaluated in a page context via CDP
|
|
71
|
+
* Runtime.evaluate, returns a pruned DOM snapshot string optimised for LLMs.
|
|
72
|
+
*
|
|
73
|
+
* The snapshot output format:
|
|
74
|
+
* [42]<button type=submit>Search</button>
|
|
75
|
+
* |scroll|<div> (0.5↑ 3.2↓)
|
|
76
|
+
* *[58]<a href=/r/1>Result 1</a>
|
|
77
|
+
* [59]<a href=/r/2>Result 2</a>
|
|
78
|
+
*
|
|
79
|
+
* - `[id]` — interactive element with backend index for targeting
|
|
80
|
+
* - `*` prefix — newly appeared element (incremental diff)
|
|
81
|
+
* - `|scroll|` — scrollable container with page counts
|
|
82
|
+
* - `|shadow|` — Shadow DOM boundary
|
|
83
|
+
* - `|iframe|` — iframe content
|
|
84
|
+
* - `|table|` — markdown table rendering
|
|
85
|
+
*/
|
|
86
|
+
export declare function generateSnapshotJs(opts?: SnapshotOptions): string;
|