@jackwener/opencli 1.0.6 → 1.1.1
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/.agents/skills/cross-project-adapter-migration/SKILL.md +2 -2
- package/.github/pull_request_template.md +7 -0
- package/.github/workflows/doc-check.yml +36 -0
- package/.github/workflows/docs.yml +7 -42
- package/CHANGELOG.md +23 -0
- package/CLI-EXPLORER.md +9 -8
- package/README.md +51 -10
- package/README.zh-CN.md +29 -11
- package/SKILL.md +102 -33
- package/dist/browser/cdp.js +6 -1
- package/dist/browser/page.d.ts +4 -1
- package/dist/browser/page.js +7 -1
- package/dist/build-manifest.js +23 -16
- package/dist/cli-manifest.json +951 -296
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +225 -148
- package/dist/clis/antigravity/serve.js +296 -47
- package/dist/clis/apple-podcasts/commands.test.d.ts +2 -0
- package/dist/clis/apple-podcasts/commands.test.js +76 -0
- package/dist/clis/apple-podcasts/search.js +2 -2
- package/dist/clis/apple-podcasts/top.js +9 -2
- package/dist/clis/arxiv/paper.js +21 -0
- package/dist/clis/arxiv/search.js +24 -0
- package/dist/clis/arxiv/utils.d.ts +18 -0
- package/dist/clis/arxiv/utils.js +49 -0
- package/dist/clis/bilibili/dynamic.js +1 -1
- package/dist/clis/bilibili/favorite.js +1 -1
- package/dist/clis/bilibili/feed.js +1 -1
- package/dist/clis/bilibili/following.js +1 -1
- package/dist/clis/bilibili/history.js +1 -1
- package/dist/clis/bilibili/me.js +1 -1
- package/dist/clis/bilibili/ranking.js +1 -1
- package/dist/clis/bilibili/search.js +3 -3
- package/dist/clis/bilibili/subtitle.js +1 -1
- package/dist/clis/bilibili/user-videos.js +1 -1
- package/dist/{bilibili.d.ts → clis/bilibili/utils.d.ts} +1 -1
- package/dist/clis/bloomberg/businessweek.d.ts +1 -0
- package/dist/clis/bloomberg/businessweek.js +17 -0
- package/dist/clis/bloomberg/economics.d.ts +1 -0
- package/dist/clis/bloomberg/economics.js +17 -0
- package/dist/clis/bloomberg/feeds.d.ts +1 -0
- package/dist/clis/bloomberg/feeds.js +15 -0
- package/dist/clis/bloomberg/industries.d.ts +1 -0
- package/dist/clis/bloomberg/industries.js +17 -0
- package/dist/clis/bloomberg/main.d.ts +1 -0
- package/dist/clis/bloomberg/main.js +17 -0
- package/dist/clis/bloomberg/markets.d.ts +1 -0
- package/dist/clis/bloomberg/markets.js +17 -0
- package/dist/clis/bloomberg/news.d.ts +1 -0
- package/dist/clis/bloomberg/news.js +105 -0
- package/dist/clis/bloomberg/opinions.d.ts +1 -0
- package/dist/clis/bloomberg/opinions.js +17 -0
- package/dist/clis/bloomberg/politics.d.ts +1 -0
- package/dist/clis/bloomberg/politics.js +17 -0
- package/dist/clis/bloomberg/tech.d.ts +1 -0
- package/dist/clis/bloomberg/tech.js +17 -0
- package/dist/clis/bloomberg/utils.d.ts +34 -0
- package/dist/clis/bloomberg/utils.js +364 -0
- package/dist/clis/bloomberg/utils.test.d.ts +1 -0
- package/dist/clis/bloomberg/utils.test.js +129 -0
- package/dist/clis/boss/batchgreet.d.ts +1 -0
- package/dist/clis/boss/batchgreet.js +147 -0
- package/dist/clis/boss/chatlist.js +2 -2
- package/dist/clis/boss/detail.js +2 -2
- package/dist/clis/boss/exchange.d.ts +1 -0
- package/dist/clis/boss/exchange.js +111 -0
- package/dist/clis/boss/greet.d.ts +1 -0
- package/dist/clis/boss/greet.js +175 -0
- package/dist/clis/boss/invite.d.ts +1 -0
- package/dist/clis/boss/invite.js +158 -0
- package/dist/clis/boss/joblist.d.ts +1 -0
- package/dist/clis/boss/joblist.js +55 -0
- package/dist/clis/boss/mark.d.ts +1 -0
- package/dist/clis/boss/mark.js +141 -0
- package/dist/clis/boss/recommend.d.ts +1 -0
- package/dist/clis/boss/recommend.js +83 -0
- package/dist/clis/boss/search.js +1 -1
- package/dist/clis/boss/send.js +1 -1
- package/dist/clis/boss/stats.d.ts +1 -0
- package/dist/clis/boss/stats.js +116 -0
- package/dist/clis/chaoxing/assignments.js +1 -1
- package/dist/clis/chaoxing/exams.js +1 -1
- package/dist/{chaoxing.d.ts → clis/chaoxing/utils.d.ts} +1 -1
- package/dist/{chaoxing.js → clis/chaoxing/utils.js} +0 -2
- package/dist/clis/chaoxing/utils.test.d.ts +1 -0
- package/dist/{chaoxing.test.js → clis/chaoxing/utils.test.js} +1 -1
- package/dist/clis/chatgpt/read.js +1 -1
- package/dist/clis/chatwise/export.js +1 -1
- package/dist/clis/chatwise/model.js +2 -2
- package/dist/clis/chatwise/screenshot.js +1 -1
- package/dist/clis/codex/export.js +1 -1
- package/dist/clis/codex/model.js +2 -2
- package/dist/clis/codex/screenshot.js +1 -1
- package/dist/clis/coupang/add-to-cart.js +3 -4
- package/dist/clis/coupang/search.js +2 -4
- package/dist/clis/coupang/utils.test.d.ts +1 -0
- package/dist/{coupang.test.js → clis/coupang/utils.test.js} +1 -1
- package/dist/clis/ctrip/search.js +1 -1
- package/dist/clis/cursor/export.js +1 -1
- package/dist/clis/cursor/model.js +2 -2
- package/dist/clis/cursor/screenshot.js +1 -1
- package/dist/clis/jike/comment.js +2 -3
- package/dist/clis/jike/create.js +1 -2
- package/dist/clis/jike/feed.js +0 -1
- package/dist/clis/jike/like.js +1 -2
- package/dist/clis/jike/notifications.js +0 -1
- package/dist/clis/jike/post.yaml +1 -0
- package/dist/clis/jike/repost.js +1 -2
- package/dist/clis/jike/search.js +2 -3
- package/dist/clis/jike/topic.yaml +1 -0
- package/dist/clis/jike/user.yaml +1 -0
- package/dist/clis/jimeng/history.yaml +0 -1
- package/dist/clis/linkedin/search.js +7 -7
- package/dist/clis/linux-do/category.yaml +1 -0
- package/dist/clis/linux-do/search.yaml +4 -3
- package/dist/clis/linux-do/topic.yaml +1 -0
- package/dist/clis/notion/export.js +1 -1
- package/dist/clis/reddit/comment.js +3 -4
- package/dist/clis/reddit/read.js +4 -5
- package/dist/clis/reddit/save.js +2 -3
- package/dist/clis/reddit/saved.js +0 -1
- package/dist/clis/reddit/search.yaml +1 -0
- package/dist/clis/reddit/subscribe.js +0 -1
- package/dist/clis/reddit/upvote.js +2 -3
- package/dist/clis/reddit/upvoted.js +0 -1
- package/dist/clis/reddit/user-comments.yaml +1 -0
- package/dist/clis/reddit/user-posts.yaml +1 -0
- package/dist/clis/reddit/user.yaml +1 -0
- package/dist/clis/reuters/search.js +1 -1
- package/dist/clis/sinafinance/news.d.ts +7 -0
- package/dist/clis/sinafinance/news.js +61 -0
- package/dist/clis/smzdm/search.js +2 -3
- package/dist/clis/stackoverflow/search.yaml +1 -0
- package/dist/clis/steam/top-sellers.yaml +29 -0
- package/dist/clis/twitter/accept.js +2 -2
- package/dist/clis/twitter/article.js +2 -2
- package/dist/clis/twitter/block.d.ts +1 -0
- package/dist/clis/twitter/block.js +88 -0
- package/dist/clis/twitter/delete.js +1 -1
- package/dist/clis/twitter/hide-reply.d.ts +1 -0
- package/dist/clis/twitter/hide-reply.js +66 -0
- package/dist/clis/twitter/like.js +1 -1
- package/dist/clis/twitter/post.js +1 -1
- package/dist/clis/twitter/reply-dm.js +1 -1
- package/dist/clis/twitter/reply.js +2 -2
- package/dist/clis/twitter/search.js +1 -1
- package/dist/clis/twitter/thread.js +2 -2
- package/dist/clis/twitter/trending.d.ts +1 -0
- package/dist/clis/twitter/trending.js +91 -0
- package/dist/clis/twitter/unblock.d.ts +1 -0
- package/dist/clis/twitter/unblock.js +71 -0
- package/dist/clis/v2ex/topic.yaml +1 -0
- package/dist/clis/weibo/hot.js +0 -1
- package/dist/clis/weread/book.js +1 -1
- package/dist/clis/weread/highlights.js +1 -1
- package/dist/clis/weread/notes.js +1 -1
- package/dist/clis/weread/search.js +1 -1
- package/dist/clis/wikipedia/search.d.ts +1 -0
- package/dist/clis/wikipedia/search.js +30 -0
- package/dist/clis/wikipedia/summary.d.ts +1 -0
- package/dist/clis/wikipedia/summary.js +28 -0
- package/dist/clis/wikipedia/utils.d.ts +8 -0
- package/dist/clis/wikipedia/utils.js +18 -0
- package/dist/clis/xiaohongshu/creator-note-detail.d.ts +79 -5
- package/dist/clis/xiaohongshu/creator-note-detail.js +323 -70
- package/dist/clis/xiaohongshu/creator-note-detail.test.d.ts +1 -0
- package/dist/clis/xiaohongshu/creator-note-detail.test.js +258 -0
- package/dist/clis/xiaohongshu/creator-notes-summary.d.ts +28 -0
- package/dist/clis/xiaohongshu/creator-notes-summary.js +92 -0
- package/dist/clis/xiaohongshu/creator-notes-summary.test.d.ts +1 -0
- package/dist/clis/xiaohongshu/creator-notes-summary.test.js +49 -0
- package/dist/clis/xiaohongshu/creator-notes.d.ts +18 -5
- package/dist/clis/xiaohongshu/creator-notes.js +189 -71
- package/dist/clis/xiaohongshu/creator-notes.test.d.ts +1 -0
- package/dist/clis/xiaohongshu/creator-notes.test.js +191 -0
- package/dist/clis/xiaohongshu/creator-profile.js +0 -1
- package/dist/clis/xiaohongshu/creator-stats.js +0 -1
- package/dist/clis/xiaohongshu/download.js +2 -3
- package/dist/clis/xiaohongshu/feed.yaml +0 -1
- package/dist/clis/xiaohongshu/notifications.yaml +0 -1
- package/dist/clis/xiaohongshu/search.js +2 -2
- package/dist/clis/xiaohongshu/user.js +1 -2
- package/dist/clis/yahoo-finance/quote.js +0 -1
- package/dist/clis/youtube/search.js +1 -1
- package/dist/clis/youtube/transcript.js +1 -1
- package/dist/clis/youtube/video.js +1 -1
- package/dist/clis/zhihu/download.js +1 -2
- package/dist/clis/zhihu/question.js +1 -1
- package/dist/clis/zhihu/search.yaml +4 -3
- package/dist/commanderAdapter.d.ts +21 -0
- package/dist/commanderAdapter.js +111 -0
- package/dist/{engine.d.ts → discovery.d.ts} +0 -6
- package/dist/{engine.js → discovery.js} +1 -98
- package/dist/download/index.d.ts +2 -6
- package/dist/download/index.js +19 -46
- package/dist/engine.test.d.ts +1 -1
- package/dist/engine.test.js +8 -7
- package/dist/execution.d.ts +22 -0
- package/dist/execution.js +129 -0
- package/dist/explore.js +121 -107
- package/dist/external-clis.yaml +48 -0
- package/dist/external.d.ts +25 -0
- package/dist/external.js +156 -0
- package/dist/main.js +1 -1
- package/dist/pipeline/steps/browser.js +8 -2
- package/dist/registry.d.ts +2 -0
- package/dist/registry.js +2 -0
- package/dist/runtime.d.ts +5 -0
- package/dist/runtime.js +8 -0
- package/dist/serialization.d.ts +34 -0
- package/dist/serialization.js +63 -0
- package/dist/types.d.ts +4 -1
- package/docs/.vitepress/config.mts +14 -3
- package/docs/adapters/browser/arxiv.md +27 -0
- package/docs/adapters/browser/barchart.md +32 -0
- package/docs/adapters/browser/bloomberg.md +70 -0
- package/docs/adapters/browser/chaoxing.md +39 -0
- package/docs/adapters/browser/grok.md +35 -0
- package/docs/adapters/browser/hf.md +42 -0
- package/docs/adapters/browser/jike.md +45 -0
- package/docs/adapters/browser/jimeng.md +39 -0
- package/docs/adapters/browser/linux-do.md +45 -0
- package/docs/adapters/browser/sinafinance.md +35 -0
- package/docs/adapters/browser/stackoverflow.md +35 -0
- package/docs/adapters/browser/steam.md +26 -0
- package/docs/adapters/browser/twitter.md +3 -0
- package/docs/adapters/browser/weread.md +48 -0
- package/docs/adapters/browser/wikipedia.md +30 -0
- package/docs/adapters/browser/xiaohongshu.md +5 -1
- package/docs/adapters/desktop/chatgpt.md +3 -3
- package/docs/adapters/index.md +13 -0
- package/docs/advanced/download.md +4 -4
- package/docs/developer/architecture.md +17 -4
- package/package.json +1 -1
- package/scripts/check-doc-coverage.sh +69 -0
- package/scripts/copy-yaml.cjs +7 -0
- package/src/browser/cdp.ts +9 -4
- package/src/browser/page.ts +7 -1
- package/src/build-manifest.ts +25 -19
- package/src/cli.ts +253 -119
- package/src/clis/antigravity/serve.ts +323 -50
- package/src/clis/apple-podcasts/commands.test.ts +95 -0
- package/src/clis/apple-podcasts/search.ts +2 -2
- package/src/clis/apple-podcasts/top.ts +12 -2
- package/src/clis/arxiv/paper.ts +21 -0
- package/src/clis/arxiv/search.ts +24 -0
- package/src/clis/arxiv/utils.ts +63 -0
- package/src/clis/bilibili/dynamic.ts +1 -1
- package/src/clis/bilibili/favorite.ts +1 -1
- package/src/clis/bilibili/feed.ts +1 -1
- package/src/clis/bilibili/following.ts +1 -1
- package/src/clis/bilibili/history.ts +1 -1
- package/src/clis/bilibili/me.ts +1 -1
- package/src/clis/bilibili/ranking.ts +1 -1
- package/src/clis/bilibili/search.ts +3 -3
- package/src/clis/bilibili/subtitle.ts +1 -1
- package/src/clis/bilibili/user-videos.ts +1 -1
- package/src/{bilibili.ts → clis/bilibili/utils.ts} +1 -1
- package/src/clis/bloomberg/businessweek.ts +18 -0
- package/src/clis/bloomberg/economics.ts +18 -0
- package/src/clis/bloomberg/feeds.ts +16 -0
- package/src/clis/bloomberg/industries.ts +18 -0
- package/src/clis/bloomberg/main.ts +18 -0
- package/src/clis/bloomberg/markets.ts +18 -0
- package/src/clis/bloomberg/news.ts +136 -0
- package/src/clis/bloomberg/opinions.ts +18 -0
- package/src/clis/bloomberg/politics.ts +18 -0
- package/src/clis/bloomberg/tech.ts +18 -0
- package/src/clis/bloomberg/utils.test.ts +135 -0
- package/src/clis/bloomberg/utils.ts +429 -0
- package/src/clis/boss/batchgreet.ts +167 -0
- package/src/clis/boss/chatlist.ts +2 -2
- package/src/clis/boss/detail.ts +2 -2
- package/src/clis/boss/exchange.ts +126 -0
- package/src/clis/boss/greet.ts +198 -0
- package/src/clis/boss/invite.ts +177 -0
- package/src/clis/boss/joblist.ts +63 -0
- package/src/clis/boss/mark.ts +155 -0
- package/src/clis/boss/recommend.ts +94 -0
- package/src/clis/boss/search.ts +1 -1
- package/src/clis/boss/send.ts +1 -1
- package/src/clis/boss/stats.ts +130 -0
- package/src/clis/chaoxing/assignments.ts +1 -1
- package/src/clis/chaoxing/exams.ts +1 -1
- package/src/{chaoxing.test.ts → clis/chaoxing/utils.test.ts} +1 -1
- package/src/{chaoxing.ts → clis/chaoxing/utils.ts} +1 -3
- package/src/clis/chatgpt/README.zh-CN.md +3 -3
- package/src/clis/chatgpt/read.ts +1 -1
- package/src/clis/chatwise/export.ts +1 -1
- package/src/clis/chatwise/model.ts +2 -2
- package/src/clis/chatwise/screenshot.ts +1 -1
- package/src/clis/codex/export.ts +1 -1
- package/src/clis/codex/model.ts +2 -2
- package/src/clis/codex/screenshot.ts +1 -1
- package/src/clis/coupang/add-to-cart.ts +3 -4
- package/src/clis/coupang/search.ts +2 -4
- package/src/{coupang.test.ts → clis/coupang/utils.test.ts} +1 -1
- package/src/clis/ctrip/search.ts +1 -1
- package/src/clis/cursor/export.ts +1 -1
- package/src/clis/cursor/model.ts +2 -2
- package/src/clis/cursor/screenshot.ts +1 -1
- package/src/clis/jike/comment.ts +2 -3
- package/src/clis/jike/create.ts +1 -2
- package/src/clis/jike/feed.ts +0 -1
- package/src/clis/jike/like.ts +1 -2
- package/src/clis/jike/notifications.ts +0 -1
- package/src/clis/jike/post.yaml +1 -0
- package/src/clis/jike/repost.ts +1 -2
- package/src/clis/jike/search.ts +2 -3
- package/src/clis/jike/topic.yaml +1 -0
- package/src/clis/jike/user.yaml +1 -0
- package/src/clis/jimeng/history.yaml +0 -1
- package/src/clis/linkedin/search.ts +7 -7
- package/src/clis/linux-do/category.yaml +1 -0
- package/src/clis/linux-do/search.yaml +4 -3
- package/src/clis/linux-do/topic.yaml +1 -0
- package/src/clis/notion/export.ts +1 -1
- package/src/clis/reddit/comment.ts +3 -4
- package/src/clis/reddit/read.ts +4 -5
- package/src/clis/reddit/save.ts +2 -3
- package/src/clis/reddit/saved.ts +0 -1
- package/src/clis/reddit/search.yaml +1 -0
- package/src/clis/reddit/subscribe.ts +0 -1
- package/src/clis/reddit/upvote.ts +2 -3
- package/src/clis/reddit/upvoted.ts +0 -1
- package/src/clis/reddit/user-comments.yaml +1 -0
- package/src/clis/reddit/user-posts.yaml +1 -0
- package/src/clis/reddit/user.yaml +1 -0
- package/src/clis/reuters/search.ts +1 -1
- package/src/clis/sinafinance/news.ts +76 -0
- package/src/clis/smzdm/search.ts +2 -3
- package/src/clis/stackoverflow/search.yaml +1 -0
- package/src/clis/steam/top-sellers.yaml +29 -0
- package/src/clis/twitter/accept.ts +2 -2
- package/src/clis/twitter/article.ts +2 -2
- package/src/clis/twitter/block.ts +92 -0
- package/src/clis/twitter/delete.ts +1 -1
- package/src/clis/twitter/hide-reply.ts +70 -0
- package/src/clis/twitter/like.ts +1 -1
- package/src/clis/twitter/post.ts +1 -1
- package/src/clis/twitter/reply-dm.ts +1 -1
- package/src/clis/twitter/reply.ts +2 -2
- package/src/clis/twitter/search.ts +1 -1
- package/src/clis/twitter/thread.ts +2 -2
- package/src/clis/twitter/trending.ts +113 -0
- package/src/clis/twitter/unblock.ts +75 -0
- package/src/clis/v2ex/topic.yaml +1 -0
- package/src/clis/weibo/hot.ts +0 -1
- package/src/clis/weread/book.ts +1 -1
- package/src/clis/weread/highlights.ts +1 -1
- package/src/clis/weread/notes.ts +1 -1
- package/src/clis/weread/search.ts +1 -1
- package/src/clis/wikipedia/search.ts +32 -0
- package/src/clis/wikipedia/summary.ts +28 -0
- package/src/clis/wikipedia/utils.ts +20 -0
- package/src/clis/xiaohongshu/creator-note-detail.test.ts +272 -0
- package/src/clis/xiaohongshu/creator-note-detail.ts +425 -73
- package/src/clis/xiaohongshu/creator-notes-summary.test.ts +54 -0
- package/src/clis/xiaohongshu/creator-notes-summary.ts +120 -0
- package/src/clis/xiaohongshu/creator-notes.test.ts +211 -0
- package/src/clis/xiaohongshu/creator-notes.ts +254 -75
- package/src/clis/xiaohongshu/creator-profile.ts +0 -1
- package/src/clis/xiaohongshu/creator-stats.ts +0 -1
- package/src/clis/xiaohongshu/download.ts +2 -3
- package/src/clis/xiaohongshu/feed.yaml +0 -1
- package/src/clis/xiaohongshu/notifications.yaml +0 -1
- package/src/clis/xiaohongshu/search.ts +2 -2
- package/src/clis/xiaohongshu/user.ts +1 -2
- package/src/clis/yahoo-finance/quote.ts +0 -1
- package/src/clis/youtube/search.ts +1 -1
- package/src/clis/youtube/transcript.ts +1 -1
- package/src/clis/youtube/video.ts +1 -1
- package/src/clis/zhihu/download.ts +1 -2
- package/src/clis/zhihu/question.ts +1 -1
- package/src/clis/zhihu/search.yaml +4 -3
- package/src/commanderAdapter.ts +113 -0
- package/src/daemon.ts +3 -3
- package/src/{engine.ts → discovery.ts} +1 -108
- package/src/download/index.ts +21 -54
- package/src/engine.test.ts +8 -7
- package/src/execution.ts +138 -0
- package/src/explore.ts +135 -109
- package/src/external-clis.yaml +48 -0
- package/src/external.ts +185 -0
- package/src/main.ts +1 -1
- package/src/pipeline/steps/browser.ts +7 -2
- package/src/registry.ts +5 -0
- package/src/runtime.ts +9 -0
- package/src/serialization.ts +79 -0
- package/src/types.ts +1 -1
- package/tests/e2e/browser-public.test.ts +25 -0
- package/tests/e2e/public-commands.test.ts +55 -1
- package/dist/clis/twitter/trending.yaml +0 -46
- package/src/clis/twitter/trending.yaml +0 -46
- /package/dist/{chaoxing.test.d.ts → clis/arxiv/paper.d.ts} +0 -0
- /package/dist/{coupang.test.d.ts → clis/arxiv/search.d.ts} +0 -0
- /package/dist/{bilibili.js → clis/bilibili/utils.js} +0 -0
- /package/dist/{coupang.d.ts → clis/coupang/utils.d.ts} +0 -0
- /package/dist/{coupang.js → clis/coupang/utils.js} +0 -0
- /package/src/{coupang.ts → clis/coupang/utils.ts} +0 -0
|
@@ -321,15 +321,15 @@ cli({
|
|
|
321
321
|
strategy: Strategy.HEADER,
|
|
322
322
|
browser: true,
|
|
323
323
|
args: [
|
|
324
|
-
{ name: 'query', type: 'string', required: true, help: 'Job search keywords' },
|
|
324
|
+
{ name: 'query', type: 'string', required: true, positional: true, help: 'Job search keywords' },
|
|
325
325
|
{ name: 'location', type: 'string', required: false, help: 'Location text such as San Francisco Bay Area' },
|
|
326
326
|
{ name: 'limit', type: 'int', default: 10, help: 'Number of jobs to return (max 100)' },
|
|
327
327
|
{ name: 'start', type: 'int', default: 0, help: 'Result offset for pagination' },
|
|
328
328
|
{ name: 'details', type: 'bool', default: false, help: 'Include full job description and apply URL (slower)' },
|
|
329
329
|
{ name: 'company', type: 'string', required: false, help: 'Comma-separated company names or LinkedIn company IDs' },
|
|
330
|
-
{ name: '
|
|
331
|
-
{ name: '
|
|
332
|
-
{ name: '
|
|
330
|
+
{ name: 'experience-level', type: 'string', required: false, help: 'Comma-separated: internship, entry, associate, mid-senior, director, executive' },
|
|
331
|
+
{ name: 'job-type', type: 'string', required: false, help: 'Comma-separated: full-time, part-time, contract, temporary, volunteer, internship, other' },
|
|
332
|
+
{ name: 'date-posted', type: 'string', required: false, help: 'One of: any, month, week, 24h' },
|
|
333
333
|
{ name: 'remote', type: 'string', required: false, help: 'Comma-separated: on-site, hybrid, remote' },
|
|
334
334
|
],
|
|
335
335
|
columns: ['rank', 'title', 'company', 'location', 'listed', 'salary', 'url'],
|
|
@@ -353,9 +353,9 @@ cli({
|
|
|
353
353
|
limit,
|
|
354
354
|
start,
|
|
355
355
|
companyIds,
|
|
356
|
-
experienceLevels: mapFilterValues(kwargs
|
|
357
|
-
jobTypes: mapFilterValues(kwargs
|
|
358
|
-
datePostedValues: mapFilterValues(kwargs
|
|
356
|
+
experienceLevels: mapFilterValues(kwargs['experience-level'], EXPERIENCE_LEVELS, 'experience_level'),
|
|
357
|
+
jobTypes: mapFilterValues(kwargs['job-type'], JOB_TYPES, 'job_type'),
|
|
358
|
+
datePostedValues: mapFilterValues(kwargs['date-posted'], DATE_POSTED, 'date_posted'),
|
|
359
359
|
remoteTypes: mapFilterValues(kwargs.remote, REMOTE_TYPES, 'remote'),
|
|
360
360
|
};
|
|
361
361
|
const data = await fetchJobCards(page, input);
|
|
@@ -5,10 +5,11 @@ domain: linux.do
|
|
|
5
5
|
browser: true
|
|
6
6
|
|
|
7
7
|
args:
|
|
8
|
-
|
|
8
|
+
query:
|
|
9
|
+
positional: true
|
|
9
10
|
type: str
|
|
10
11
|
required: true
|
|
11
|
-
description: Search
|
|
12
|
+
description: Search query
|
|
12
13
|
limit:
|
|
13
14
|
type: int
|
|
14
15
|
default: 20
|
|
@@ -19,7 +20,7 @@ pipeline:
|
|
|
19
20
|
|
|
20
21
|
- evaluate: |
|
|
21
22
|
(async () => {
|
|
22
|
-
const keyword = ${{ args.
|
|
23
|
+
const keyword = ${{ args.query | json }};
|
|
23
24
|
const res = await fetch('/search.json?q=' + encodeURIComponent(keyword), { credentials: 'include' });
|
|
24
25
|
if (!res.ok) throw new Error('HTTP ' + res.status + ' - 请先登录 linux.do');
|
|
25
26
|
let data;
|
|
@@ -8,7 +8,7 @@ export const exportCommand = cli({
|
|
|
8
8
|
strategy: Strategy.UI,
|
|
9
9
|
browser: true,
|
|
10
10
|
args: [
|
|
11
|
-
{ name: 'output', required: false,
|
|
11
|
+
{ name: 'output', required: false, help: 'Output file (default: /tmp/notion-export.md)' },
|
|
12
12
|
],
|
|
13
13
|
columns: ['Status', 'File'],
|
|
14
14
|
func: async (page, kwargs) => {
|
|
@@ -7,18 +7,17 @@ cli({
|
|
|
7
7
|
strategy: Strategy.COOKIE,
|
|
8
8
|
browser: true,
|
|
9
9
|
args: [
|
|
10
|
-
{ name: '
|
|
11
|
-
{ name: 'text', type: 'string', required: true, help: 'Comment text' },
|
|
10
|
+
{ name: 'post-id', type: 'string', required: true, help: 'Post ID (e.g. 1abc123) or fullname (t3_xxx)' },
|
|
11
|
+
{ name: 'text', type: 'string', required: true, positional: true, help: 'Comment text' },
|
|
12
12
|
],
|
|
13
13
|
columns: ['status', 'message'],
|
|
14
14
|
func: async (page, kwargs) => {
|
|
15
15
|
if (!page)
|
|
16
16
|
throw new Error('Requires browser');
|
|
17
17
|
await page.goto('https://www.reddit.com');
|
|
18
|
-
await page.wait(3);
|
|
19
18
|
const result = await page.evaluate(`(async () => {
|
|
20
19
|
try {
|
|
21
|
-
let postId = ${JSON.stringify(kwargs
|
|
20
|
+
let postId = ${JSON.stringify(kwargs['post-id'])};
|
|
22
21
|
const urlMatch = postId.match(/comments\\/([a-z0-9]+)/);
|
|
23
22
|
if (urlMatch) postId = urlMatch[1];
|
|
24
23
|
const fullname = postId.startsWith('t3_') || postId.startsWith('t1_')
|
package/dist/clis/reddit/read.js
CHANGED
|
@@ -14,12 +14,12 @@ cli({
|
|
|
14
14
|
domain: 'reddit.com',
|
|
15
15
|
strategy: Strategy.COOKIE,
|
|
16
16
|
args: [
|
|
17
|
-
{ name: '
|
|
17
|
+
{ name: 'post-id', required: true, help: 'Post ID (e.g. 1abc123) or full URL' },
|
|
18
18
|
{ name: 'sort', default: 'best', help: 'Comment sort: best, top, new, controversial, old, qa' },
|
|
19
19
|
{ name: 'limit', type: 'int', default: 25, help: 'Number of top-level comments' },
|
|
20
20
|
{ name: 'depth', type: 'int', default: 2, help: 'Max reply depth (1=no replies, 2=one level of replies, etc.)' },
|
|
21
21
|
{ name: 'replies', type: 'int', default: 5, help: 'Max replies shown per comment at each level (sorted by score)' },
|
|
22
|
-
{ name: '
|
|
22
|
+
{ name: 'max-length', type: 'int', default: 2000, help: 'Max characters per comment body (min 100)' },
|
|
23
23
|
],
|
|
24
24
|
columns: ['type', 'author', 'score', 'text'],
|
|
25
25
|
func: async (page, kwargs) => {
|
|
@@ -27,12 +27,11 @@ cli({
|
|
|
27
27
|
const limit = Math.max(1, kwargs.limit ?? 25);
|
|
28
28
|
const maxDepth = Math.max(1, kwargs.depth ?? 2);
|
|
29
29
|
const maxReplies = Math.max(1, kwargs.replies ?? 5);
|
|
30
|
-
const maxLength = Math.max(100, kwargs
|
|
30
|
+
const maxLength = Math.max(100, kwargs['max-length'] ?? 2000);
|
|
31
31
|
await page.goto('https://www.reddit.com');
|
|
32
|
-
await page.wait(2);
|
|
33
32
|
const data = await page.evaluate(`
|
|
34
33
|
(async function() {
|
|
35
|
-
var postId = ${JSON.stringify(kwargs
|
|
34
|
+
var postId = ${JSON.stringify(kwargs['post-id'])};
|
|
36
35
|
var urlMatch = postId.match(/comments\\/([a-z0-9]+)/);
|
|
37
36
|
if (urlMatch) postId = urlMatch[1];
|
|
38
37
|
|
package/dist/clis/reddit/save.js
CHANGED
|
@@ -7,7 +7,7 @@ cli({
|
|
|
7
7
|
strategy: Strategy.COOKIE,
|
|
8
8
|
browser: true,
|
|
9
9
|
args: [
|
|
10
|
-
{ name: '
|
|
10
|
+
{ name: 'post-id', type: 'string', required: true, help: 'Post ID (e.g. 1abc123) or fullname (t3_xxx)' },
|
|
11
11
|
{ name: 'undo', type: 'boolean', default: false, help: 'Unsave instead of save' },
|
|
12
12
|
],
|
|
13
13
|
columns: ['status', 'message'],
|
|
@@ -15,10 +15,9 @@ cli({
|
|
|
15
15
|
if (!page)
|
|
16
16
|
throw new Error('Requires browser');
|
|
17
17
|
await page.goto('https://www.reddit.com');
|
|
18
|
-
await page.wait(3);
|
|
19
18
|
const result = await page.evaluate(`(async () => {
|
|
20
19
|
try {
|
|
21
|
-
let postId = ${JSON.stringify(kwargs
|
|
20
|
+
let postId = ${JSON.stringify(kwargs['post-id'])};
|
|
22
21
|
const urlMatch = postId.match(/comments\\/([a-z0-9]+)/);
|
|
23
22
|
if (urlMatch) postId = urlMatch[1];
|
|
24
23
|
const fullname = postId.startsWith('t3_') || postId.startsWith('t1_')
|
|
@@ -7,7 +7,7 @@ cli({
|
|
|
7
7
|
strategy: Strategy.COOKIE,
|
|
8
8
|
browser: true,
|
|
9
9
|
args: [
|
|
10
|
-
{ name: '
|
|
10
|
+
{ name: 'post-id', type: 'string', required: true, help: 'Post ID (e.g. 1abc123) or fullname (t3_xxx)' },
|
|
11
11
|
{ name: 'direction', type: 'string', default: 'up', help: 'Vote direction: up, down, none' },
|
|
12
12
|
],
|
|
13
13
|
columns: ['status', 'message'],
|
|
@@ -15,10 +15,9 @@ cli({
|
|
|
15
15
|
if (!page)
|
|
16
16
|
throw new Error('Requires browser');
|
|
17
17
|
await page.goto('https://www.reddit.com');
|
|
18
|
-
await page.wait(3);
|
|
19
18
|
const result = await page.evaluate(`(async () => {
|
|
20
19
|
try {
|
|
21
|
-
let postId = ${JSON.stringify(kwargs
|
|
20
|
+
let postId = ${JSON.stringify(kwargs['post-id'])};
|
|
22
21
|
// Extract ID from URL if needed
|
|
23
22
|
const urlMatch = postId.match(/comments\\/([a-z0-9]+)/);
|
|
24
23
|
if (urlMatch) postId = urlMatch[1];
|
|
@@ -10,7 +10,7 @@ cli({
|
|
|
10
10
|
domain: 'www.reuters.com',
|
|
11
11
|
strategy: Strategy.COOKIE,
|
|
12
12
|
args: [
|
|
13
|
-
{ name: 'query', required: true, help: 'Search query' },
|
|
13
|
+
{ name: 'query', required: true, positional: true, help: 'Search query' },
|
|
14
14
|
{ name: 'limit', type: 'int', default: 10, help: 'Number of results (max 40)' },
|
|
15
15
|
],
|
|
16
16
|
columns: ['rank', 'title', 'date', 'section', 'url'],
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sina Finance 7x24 live news feed.
|
|
3
|
+
*
|
|
4
|
+
* Uses the public CJ API — no key or browser required.
|
|
5
|
+
* https://app.cj.sina.com.cn/api/news/pc
|
|
6
|
+
*/
|
|
7
|
+
import { cli, Strategy } from '../../registry.js';
|
|
8
|
+
import { CliError } from '../../errors.js';
|
|
9
|
+
// User-facing type (0-9) → Sina API tag ID
|
|
10
|
+
const TYPE_MAP = [
|
|
11
|
+
0, // 0: 全部
|
|
12
|
+
10, // 1: A股
|
|
13
|
+
1, // 2: 宏观
|
|
14
|
+
3, // 3: 公司
|
|
15
|
+
4, // 4: 数据
|
|
16
|
+
5, // 5: 市场
|
|
17
|
+
102, // 6: 国际
|
|
18
|
+
6, // 7: 观点
|
|
19
|
+
6, // 8: 央行
|
|
20
|
+
8, // 9: 其它
|
|
21
|
+
];
|
|
22
|
+
function stripHtml(html) {
|
|
23
|
+
return html.replace(/<[^>]+>/g, '').trim();
|
|
24
|
+
}
|
|
25
|
+
cli({
|
|
26
|
+
site: 'sinafinance',
|
|
27
|
+
name: 'news',
|
|
28
|
+
description: '新浪财经 7x24 小时实时快讯',
|
|
29
|
+
domain: 'app.cj.sina.com.cn',
|
|
30
|
+
strategy: Strategy.PUBLIC,
|
|
31
|
+
browser: false,
|
|
32
|
+
args: [
|
|
33
|
+
{ name: 'limit', type: 'int', default: 20, help: 'Max results (max 50)' },
|
|
34
|
+
{ name: 'type', type: 'int', default: 0, help: 'News type: 0=全部 1=A股 2=宏观 3=公司 4=数据 5=市场 6=国际 7=观点 8=央行 9=其它' },
|
|
35
|
+
],
|
|
36
|
+
columns: ['id', 'time', 'content', 'views'],
|
|
37
|
+
func: async (_page, args) => {
|
|
38
|
+
const limit = Math.max(1, Math.min(Number(args.limit), 50));
|
|
39
|
+
const apiTag = TYPE_MAP[args.type] ?? 0;
|
|
40
|
+
const params = new URLSearchParams({
|
|
41
|
+
page: '1',
|
|
42
|
+
size: String(limit),
|
|
43
|
+
tag: String(apiTag),
|
|
44
|
+
});
|
|
45
|
+
const res = await fetch(`https://app.cj.sina.com.cn/api/news/pc?${params}`);
|
|
46
|
+
if (!res.ok) {
|
|
47
|
+
throw new CliError('FETCH_ERROR', `Sina Finance API HTTP ${res.status}`, 'Check your network connection');
|
|
48
|
+
}
|
|
49
|
+
const json = await res.json();
|
|
50
|
+
const list = json?.result?.data?.feed?.list ?? [];
|
|
51
|
+
if (!list.length) {
|
|
52
|
+
throw new CliError('NOT_FOUND', 'No news found', 'Try a different type or increase limit');
|
|
53
|
+
}
|
|
54
|
+
return list.map((item) => ({
|
|
55
|
+
id: item.id ?? '',
|
|
56
|
+
time: item.create_time ?? '',
|
|
57
|
+
content: stripHtml(item.rich_text ?? ''),
|
|
58
|
+
views: item.view_num ?? 0,
|
|
59
|
+
}));
|
|
60
|
+
},
|
|
61
|
+
});
|
|
@@ -13,16 +13,15 @@ cli({
|
|
|
13
13
|
domain: 'www.smzdm.com',
|
|
14
14
|
strategy: Strategy.COOKIE,
|
|
15
15
|
args: [
|
|
16
|
-
{ name: '
|
|
16
|
+
{ name: 'query', required: true, positional: true, help: 'Search keyword' },
|
|
17
17
|
{ name: 'limit', type: 'int', default: 20, help: 'Number of results' },
|
|
18
18
|
],
|
|
19
19
|
columns: ['rank', 'title', 'price', 'mall', 'comments', 'url'],
|
|
20
20
|
func: async (page, kwargs) => {
|
|
21
|
-
const q = encodeURIComponent(kwargs.
|
|
21
|
+
const q = encodeURIComponent(kwargs.query);
|
|
22
22
|
const limit = kwargs.limit || 20;
|
|
23
23
|
// Navigate directly to search results page
|
|
24
24
|
await page.goto(`https://search.smzdm.com/?c=home&s=${q}&v=b`);
|
|
25
|
-
await page.wait(2);
|
|
26
25
|
const data = await page.evaluate(`
|
|
27
26
|
(() => {
|
|
28
27
|
const limit = ${limit};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
site: steam
|
|
2
|
+
name: top-sellers
|
|
3
|
+
description: Steam top selling games
|
|
4
|
+
domain: store.steampowered.com
|
|
5
|
+
strategy: public
|
|
6
|
+
browser: false
|
|
7
|
+
|
|
8
|
+
args:
|
|
9
|
+
limit:
|
|
10
|
+
type: int
|
|
11
|
+
default: 10
|
|
12
|
+
description: Number of games
|
|
13
|
+
|
|
14
|
+
pipeline:
|
|
15
|
+
- fetch:
|
|
16
|
+
url: https://store.steampowered.com/api/featuredcategories/
|
|
17
|
+
|
|
18
|
+
- select: top_sellers.items
|
|
19
|
+
|
|
20
|
+
- map:
|
|
21
|
+
rank: ${{ index + 1 }}
|
|
22
|
+
name: ${{ item.name }}
|
|
23
|
+
price: ${{ item.final_price }}
|
|
24
|
+
discount: ${{ item.discount_percent }}
|
|
25
|
+
url: https://store.steampowered.com/app/${{ item.id }}
|
|
26
|
+
|
|
27
|
+
- limit: ${{ args.limit }}
|
|
28
|
+
|
|
29
|
+
columns: [rank, name, price, discount, url]
|
|
@@ -8,14 +8,14 @@ cli({
|
|
|
8
8
|
browser: true,
|
|
9
9
|
timeoutSeconds: 600, // 10 min — batch operation iterating many conversations
|
|
10
10
|
args: [
|
|
11
|
-
{ name: '
|
|
11
|
+
{ name: 'query', type: 'string', required: true, positional: true, help: 'Keywords to match (comma-separated for OR, e.g. "群,微信")' },
|
|
12
12
|
{ name: 'max', type: 'int', required: false, default: 20, help: 'Maximum number of requests to accept (default: 20)' },
|
|
13
13
|
],
|
|
14
14
|
columns: ['index', 'status', 'user', 'message'],
|
|
15
15
|
func: async (page, kwargs) => {
|
|
16
16
|
if (!page)
|
|
17
17
|
throw new Error('Requires browser');
|
|
18
|
-
const keywords = kwargs.
|
|
18
|
+
const keywords = kwargs.query.split(',').map((k) => k.trim()).filter(Boolean);
|
|
19
19
|
const maxAccepts = kwargs.max ?? 20;
|
|
20
20
|
const results = [];
|
|
21
21
|
let acceptCount = 0;
|
|
@@ -7,12 +7,12 @@ cli({
|
|
|
7
7
|
strategy: Strategy.COOKIE,
|
|
8
8
|
browser: true,
|
|
9
9
|
args: [
|
|
10
|
-
{ name: '
|
|
10
|
+
{ name: 'tweet-id', type: 'string', positional: true, required: true, help: 'Tweet ID or URL containing the article' },
|
|
11
11
|
],
|
|
12
12
|
columns: ['title', 'author', 'content', 'url'],
|
|
13
13
|
func: async (page, kwargs) => {
|
|
14
14
|
// Extract tweet ID from URL if needed
|
|
15
|
-
let tweetId = kwargs
|
|
15
|
+
let tweetId = kwargs['tweet-id'];
|
|
16
16
|
const urlMatch = tweetId.match(/\/(?:status|article)\/(\d+)/);
|
|
17
17
|
if (urlMatch)
|
|
18
18
|
tweetId = urlMatch[1];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { cli, Strategy } from '../../registry.js';
|
|
2
|
+
cli({
|
|
3
|
+
site: 'twitter',
|
|
4
|
+
name: 'block',
|
|
5
|
+
description: 'Block a Twitter user',
|
|
6
|
+
domain: 'x.com',
|
|
7
|
+
strategy: Strategy.UI,
|
|
8
|
+
browser: true,
|
|
9
|
+
args: [
|
|
10
|
+
{ name: 'username', type: 'string', positional: true, required: true, help: 'Twitter screen name (without @)' },
|
|
11
|
+
],
|
|
12
|
+
columns: ['status', 'message'],
|
|
13
|
+
func: async (page, kwargs) => {
|
|
14
|
+
if (!page)
|
|
15
|
+
throw new Error('Requires browser');
|
|
16
|
+
const username = kwargs.username.replace(/^@/, '');
|
|
17
|
+
await page.goto(`https://x.com/${username}`);
|
|
18
|
+
await page.wait(5);
|
|
19
|
+
const result = await page.evaluate(`(async () => {
|
|
20
|
+
try {
|
|
21
|
+
let attempts = 0;
|
|
22
|
+
|
|
23
|
+
// Check if already blocked (profile shows "Blocked" / unblock button)
|
|
24
|
+
while (attempts < 20) {
|
|
25
|
+
const blockedIndicator = document.querySelector('[data-testid$="-unblock"]');
|
|
26
|
+
if (blockedIndicator) {
|
|
27
|
+
return { ok: true, message: 'Already blocking @${username}.' };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const moreBtn = document.querySelector('[data-testid="userActions"]');
|
|
31
|
+
if (moreBtn) break;
|
|
32
|
+
|
|
33
|
+
await new Promise(r => setTimeout(r, 500));
|
|
34
|
+
attempts++;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const moreBtn = document.querySelector('[data-testid="userActions"]');
|
|
38
|
+
if (!moreBtn) {
|
|
39
|
+
return { ok: false, message: 'Could not find user actions menu. Are you logged in?' };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Open the more actions menu
|
|
43
|
+
moreBtn.click();
|
|
44
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
45
|
+
|
|
46
|
+
// Find the Block menu item
|
|
47
|
+
const menuItems = document.querySelectorAll('[role="menuitem"]');
|
|
48
|
+
let blockItem = null;
|
|
49
|
+
for (const item of menuItems) {
|
|
50
|
+
if (item.textContent && item.textContent.includes('Block')) {
|
|
51
|
+
blockItem = item;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!blockItem) {
|
|
57
|
+
return { ok: false, message: 'Could not find Block option in menu.' };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
blockItem.click();
|
|
61
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
62
|
+
|
|
63
|
+
// Confirm the block in the dialog
|
|
64
|
+
const confirmBtn = document.querySelector('[data-testid="confirmationSheetConfirm"]');
|
|
65
|
+
if (confirmBtn) {
|
|
66
|
+
confirmBtn.click();
|
|
67
|
+
await new Promise(r => setTimeout(r, 1500));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Verify
|
|
71
|
+
const verify = document.querySelector('[data-testid$="-unblock"]');
|
|
72
|
+
if (verify) {
|
|
73
|
+
return { ok: true, message: 'Successfully blocked @${username}.' };
|
|
74
|
+
} else {
|
|
75
|
+
return { ok: false, message: 'Block action initiated but UI did not update.' };
|
|
76
|
+
}
|
|
77
|
+
} catch (e) {
|
|
78
|
+
return { ok: false, message: e.toString() };
|
|
79
|
+
}
|
|
80
|
+
})()`);
|
|
81
|
+
if (result.ok)
|
|
82
|
+
await page.wait(2);
|
|
83
|
+
return [{
|
|
84
|
+
status: result.ok ? 'success' : 'failed',
|
|
85
|
+
message: result.message
|
|
86
|
+
}];
|
|
87
|
+
}
|
|
88
|
+
});
|
|
@@ -7,7 +7,7 @@ cli({
|
|
|
7
7
|
strategy: Strategy.UI, // Utilizes internal DOM flows for interaction
|
|
8
8
|
browser: true,
|
|
9
9
|
args: [
|
|
10
|
-
{ name: 'url', type: 'string', required: true, help: 'The URL of the tweet to delete' },
|
|
10
|
+
{ name: 'url', type: 'string', required: true, positional: true, help: 'The URL of the tweet to delete' },
|
|
11
11
|
],
|
|
12
12
|
columns: ['status', 'message'],
|
|
13
13
|
func: async (page, kwargs) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { cli, Strategy } from '../../registry.js';
|
|
2
|
+
cli({
|
|
3
|
+
site: 'twitter',
|
|
4
|
+
name: 'hide-reply',
|
|
5
|
+
description: 'Hide a reply on your tweet (useful for hiding bot/spam replies)',
|
|
6
|
+
domain: 'x.com',
|
|
7
|
+
strategy: Strategy.UI,
|
|
8
|
+
browser: true,
|
|
9
|
+
args: [
|
|
10
|
+
{ name: 'url', type: 'string', required: true, positional: true, help: 'The URL of the reply tweet to hide' },
|
|
11
|
+
],
|
|
12
|
+
columns: ['status', 'message'],
|
|
13
|
+
func: async (page, kwargs) => {
|
|
14
|
+
if (!page)
|
|
15
|
+
throw new Error('Requires browser');
|
|
16
|
+
await page.goto(kwargs.url);
|
|
17
|
+
await page.wait(5);
|
|
18
|
+
const result = await page.evaluate(`(async () => {
|
|
19
|
+
try {
|
|
20
|
+
let attempts = 0;
|
|
21
|
+
let moreMenu = null;
|
|
22
|
+
|
|
23
|
+
while (attempts < 20) {
|
|
24
|
+
moreMenu = document.querySelector('[aria-label="More"]');
|
|
25
|
+
if (moreMenu) break;
|
|
26
|
+
await new Promise(r => setTimeout(r, 500));
|
|
27
|
+
attempts++;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!moreMenu) {
|
|
31
|
+
return { ok: false, message: 'Could not find the "More" menu on this tweet. Are you logged in?' };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
moreMenu.click();
|
|
35
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
36
|
+
|
|
37
|
+
// Look for the "Hide reply" menu item
|
|
38
|
+
const items = document.querySelectorAll('[role="menuitem"]');
|
|
39
|
+
let hideItem = null;
|
|
40
|
+
for (const item of items) {
|
|
41
|
+
if (item.textContent && item.textContent.includes('Hide reply')) {
|
|
42
|
+
hideItem = item;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!hideItem) {
|
|
48
|
+
return { ok: false, message: 'Could not find "Hide reply" option. This may not be a reply on your tweet.' };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
hideItem.click();
|
|
52
|
+
await new Promise(r => setTimeout(r, 1500));
|
|
53
|
+
|
|
54
|
+
return { ok: true, message: 'Reply successfully hidden.' };
|
|
55
|
+
} catch (e) {
|
|
56
|
+
return { ok: false, message: e.toString() };
|
|
57
|
+
}
|
|
58
|
+
})()`);
|
|
59
|
+
if (result.ok)
|
|
60
|
+
await page.wait(2);
|
|
61
|
+
return [{
|
|
62
|
+
status: result.ok ? 'success' : 'failed',
|
|
63
|
+
message: result.message
|
|
64
|
+
}];
|
|
65
|
+
}
|
|
66
|
+
});
|
|
@@ -7,7 +7,7 @@ cli({
|
|
|
7
7
|
strategy: Strategy.UI, // Utilizes internal DOM flows for interaction
|
|
8
8
|
browser: true,
|
|
9
9
|
args: [
|
|
10
|
-
{ name: 'url', type: 'string', required: true, help: 'The URL of the tweet to like' },
|
|
10
|
+
{ name: 'url', type: 'string', required: true, positional: true, help: 'The URL of the tweet to like' },
|
|
11
11
|
],
|
|
12
12
|
columns: ['status', 'message'],
|
|
13
13
|
func: async (page, kwargs) => {
|
|
@@ -7,7 +7,7 @@ cli({
|
|
|
7
7
|
strategy: Strategy.UI,
|
|
8
8
|
browser: true,
|
|
9
9
|
args: [
|
|
10
|
-
{ name: 'text', type: 'string', required: true, help: 'The text content of the tweet' },
|
|
10
|
+
{ name: 'text', type: 'string', required: true, positional: true, help: 'The text content of the tweet' },
|
|
11
11
|
],
|
|
12
12
|
columns: ['status', 'message', 'text'],
|
|
13
13
|
func: async (page, kwargs) => {
|
|
@@ -8,7 +8,7 @@ cli({
|
|
|
8
8
|
browser: true,
|
|
9
9
|
timeoutSeconds: 600, // 10 min — batch operation
|
|
10
10
|
args: [
|
|
11
|
-
{ name: 'text', type: 'string', required: true, help: 'Message text to send (e.g. "我的微信 wxkabi")' },
|
|
11
|
+
{ name: 'text', type: 'string', required: true, positional: true, help: 'Message text to send (e.g. "我的微信 wxkabi")' },
|
|
12
12
|
{ name: 'max', type: 'int', required: false, default: 20, help: 'Maximum number of conversations to reply to (default: 20)' },
|
|
13
13
|
{ name: 'skip-replied', type: 'boolean', required: false, default: true, help: 'Skip conversations where you already sent the same text (default: true)' },
|
|
14
14
|
],
|
|
@@ -7,8 +7,8 @@ cli({
|
|
|
7
7
|
strategy: Strategy.UI, // Uses the UI directly to input and click post
|
|
8
8
|
browser: true,
|
|
9
9
|
args: [
|
|
10
|
-
{ name: 'url', type: 'string', required: true, help: 'The URL of the tweet to reply to' },
|
|
11
|
-
{ name: 'text', type: 'string', required: true, help: 'The text content of your reply' },
|
|
10
|
+
{ name: 'url', type: 'string', required: true, positional: true, help: 'The URL of the tweet to reply to' },
|
|
11
|
+
{ name: 'text', type: 'string', required: true, positional: true, help: 'The text content of your reply' },
|
|
12
12
|
],
|
|
13
13
|
columns: ['status', 'message', 'text'],
|
|
14
14
|
func: async (page, kwargs) => {
|
|
@@ -7,7 +7,7 @@ cli({
|
|
|
7
7
|
strategy: Strategy.INTERCEPT, // Use intercept strategy
|
|
8
8
|
browser: true,
|
|
9
9
|
args: [
|
|
10
|
-
{ name: 'query', type: 'string', required: true },
|
|
10
|
+
{ name: 'query', type: 'string', required: true, positional: true },
|
|
11
11
|
{ name: 'limit', type: 'int', default: 15 },
|
|
12
12
|
],
|
|
13
13
|
columns: ['id', 'author', 'text', 'likes', 'views', 'url'],
|