publishport-opencli 1.0.20 → 1.0.21
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/clis/12306/me.js +2 -2
- package/clis/12306/orders.js +3 -3
- package/clis/12306/passengers.js +3 -3
- package/clis/12306/price.js +1 -1
- package/clis/12306/stations.js +1 -1
- package/clis/12306/train.js +1 -1
- package/clis/12306/trains.js +1 -1
- package/clis/12306/utils.js +1 -1
- package/clis/1688/download.js +1 -1
- package/clis/1688/item.js +4 -4
- package/clis/1688/search.js +4 -4
- package/clis/1688/store.js +4 -4
- package/clis/1point3acres/forum.js +1 -1
- package/clis/1point3acres/forums.js +1 -1
- package/clis/1point3acres/notifications.js +1 -1
- package/clis/1point3acres/search.js +1 -1
- package/clis/1point3acres/thread.js +2 -2
- package/clis/1point3acres/user.js +1 -1
- package/clis/1point3acres/utils.js +2 -2
- package/clis/36kr/article.js +2 -2
- package/clis/36kr/hot.js +2 -2
- package/clis/36kr/news.js +1 -1
- package/clis/36kr/search.js +2 -2
- package/clis/51job/company.js +2 -2
- package/clis/51job/detail.js +2 -2
- package/clis/51job/hot.js +1 -1
- package/clis/51job/search.js +1 -1
- package/clis/51job/utils.js +7 -7
- package/clis/_atlassian/shared.js +9 -9
- package/clis/_shared/article/auth.js +4 -4
- package/clis/_shared/article/douban-md2draft.js +4 -4
- package/clis/_shared/article/format.js +1 -1
- package/clis/_shared/article/images.js +7 -7
- package/clis/_shared/article/login.js +1 -1
- package/clis/_shared/article/publish.js +11 -11
- package/clis/_shared/common.js +1 -1
- package/clis/_shared/content-guard.js +1 -1
- package/clis/_shared/desktop-commands.js +1 -1
- package/clis/_shared/file-inject.js +12 -12
- package/clis/_shared/self-hosted-sites.js +2 -2
- package/clis/_shared/site-auth.js +1 -1
- package/clis/_shared/token-auth.js +2 -2
- package/clis/_shared/video-publish.js +9 -9
- package/clis/amazon/offer.js +3 -3
- package/clis/amazon/product.js +5 -5
- package/clis/amazon/shared.js +6 -6
- package/clis/antigravity/_actions.js +13 -13
- package/clis/antigravity/audit-extras.js +10 -10
- package/clis/antigravity/delete.js +1 -1
- package/clis/antigravity/model.js +6 -6
- package/clis/antigravity/new.js +2 -2
- package/clis/antigravity/read.js +2 -2
- package/clis/antigravity/rename.js +1 -1
- package/clis/antigravity/send.js +3 -3
- package/clis/antigravity/serve.js +17 -17
- package/clis/antigravity/storage.js +6 -6
- package/clis/antigravity/watch.js +2 -2
- package/clis/apple-podcasts/episodes.js +1 -1
- package/clis/apple-podcasts/top.js +1 -1
- package/clis/apple-podcasts/utils.js +1 -1
- package/clis/archive/item.js +1 -1
- package/clis/archive/search.js +1 -1
- package/clis/archive/snapshots.js +1 -1
- package/clis/archive/wayback.js +1 -1
- package/clis/arxiv/author.js +1 -1
- package/clis/arxiv/utils.js +1 -1
- package/clis/autohome/brand.js +1 -1
- package/clis/autohome/score.js +1 -1
- package/clis/autohome/utils.js +1 -1
- package/clis/baijiahao/article.js +1 -1
- package/clis/baijiahao/lists.js +1 -1
- package/clis/baijiahao/login.js +1 -1
- package/clis/baijiahao/publish.js +9 -9
- package/clis/baijiahao/stats.js +1 -1
- package/clis/baijiahao/whoami.js +1 -1
- package/clis/band/bands.js +2 -2
- package/clis/band/mentions.js +2 -2
- package/clis/band/post.js +4 -4
- package/clis/band/posts.js +3 -3
- package/clis/barchart/flow.js +3 -3
- package/clis/barchart/greeks.js +2 -2
- package/clis/barchart/quote.js +3 -3
- package/clis/bbc/news.js +1 -1
- package/clis/bbc/topic.js +1 -1
- package/clis/bbc/utils.js +1 -1
- package/clis/bilibili/article.js +1 -1
- package/clis/bilibili/categories.js +1 -1
- package/clis/bilibili/coin.js +1 -1
- package/clis/bilibili/comment-del.js +1 -1
- package/clis/bilibili/comment-like.js +1 -1
- package/clis/bilibili/comment.js +1 -1
- package/clis/bilibili/comments.js +1 -1
- package/clis/bilibili/dm-list.js +1 -1
- package/clis/bilibili/dm-read.js +1 -1
- package/clis/bilibili/dm-send.js +1 -1
- package/clis/bilibili/download.js +2 -2
- package/clis/bilibili/drafts.js +1 -1
- package/clis/bilibili/dynamic-post.js +3 -3
- package/clis/bilibili/favorite-add.js +1 -1
- package/clis/bilibili/favorite.js +1 -1
- package/clis/bilibili/feed.js +2 -2
- package/clis/bilibili/follow.js +1 -1
- package/clis/bilibili/following.js +1 -1
- package/clis/bilibili/like.js +1 -1
- package/clis/bilibili/partitions.js +1 -1
- package/clis/bilibili/stats.js +1 -1
- package/clis/bilibili/subtitle.js +3 -3
- package/clis/bilibili/summary.js +1 -1
- package/clis/bilibili/topics.js +1 -1
- package/clis/bilibili/unfollow.js +1 -1
- package/clis/bilibili/upload.js +1 -1
- package/clis/bilibili/utils.js +10 -10
- package/clis/bilibili/video-drafts.js +1 -1
- package/clis/bilibili/video.js +1 -1
- package/clis/bloomberg/businessweek.js +4 -4
- package/clis/bloomberg/news.js +2 -2
- package/clis/bloomberg/utils.js +13 -13
- package/clis/bluesky/post.js +1 -1
- package/clis/bluesky/shared.js +11 -11
- package/clis/bluesky/whoami.js +1 -1
- package/clis/booking/search.js +2 -2
- package/clis/boss/accept.js +1 -1
- package/clis/boss/applied.js +1 -1
- package/clis/boss/auth.js +1 -1
- package/clis/boss/batchgreet.js +1 -1
- package/clis/boss/bossinfo.js +1 -1
- package/clis/boss/chatlist.js +1 -1
- package/clis/boss/chatmsg.js +1 -1
- package/clis/boss/cities.js +1 -1
- package/clis/boss/detail.js +1 -1
- package/clis/boss/exchange.js +1 -1
- package/clis/boss/greet.js +1 -1
- package/clis/boss/interviews.js +1 -1
- package/clis/boss/invite.js +1 -1
- package/clis/boss/joblist.js +1 -1
- package/clis/boss/mark.js +1 -1
- package/clis/boss/me.js +2 -2
- package/clis/boss/recommend.js +1 -1
- package/clis/boss/resumedelete.js +1 -1
- package/clis/boss/resumelist.js +1 -1
- package/clis/boss/resumeupload.js +11 -11
- package/clis/boss/search.js +1 -1
- package/clis/boss/send.js +1 -1
- package/clis/boss/sendresume.js +1 -1
- package/clis/boss/stats.js +1 -1
- package/clis/boss/unread.js +1 -1
- package/clis/boss/utils.js +13 -13
- package/clis/chaoxing/assignments.js +1 -1
- package/clis/chaoxing/exams.js +1 -1
- package/clis/chaoxing/utils.js +9 -9
- package/clis/chatgpt/ask.js +1 -1
- package/clis/chatgpt/auth.js +2 -2
- package/clis/chatgpt/detail.js +1 -1
- package/clis/chatgpt/image.js +1 -1
- package/clis/chatgpt/read.js +1 -1
- package/clis/chatgpt/send.js +1 -1
- package/clis/chatgpt/utils.js +59 -59
- package/clis/chatgpt-app/ask.js +1 -1
- package/clis/chatgpt-app/send.js +1 -1
- package/clis/chatwise/model.js +6 -6
- package/clis/chess/analyze.js +1 -1
- package/clis/chess/game.js +1 -1
- package/clis/chess/games.js +1 -1
- package/clis/chess/stats.js +1 -1
- package/clis/chess/utils.js +1 -1
- package/clis/claude/ask.js +2 -2
- package/clis/claude/detail.js +1 -1
- package/clis/claude/new.js +1 -1
- package/clis/claude/read.js +1 -1
- package/clis/claude/send.js +1 -1
- package/clis/claude/utils.js +23 -23
- package/clis/cnblogs/article.js +1 -1
- package/clis/cnblogs/login.js +1 -1
- package/clis/cnblogs/stats.js +7 -7
- package/clis/cnblogs/whoami.js +1 -1
- package/clis/codex/_actions.js +3 -3
- package/clis/codex/archive.js +1 -1
- package/clis/codex/ask.js +6 -6
- package/clis/codex/model.js +8 -8
- package/clis/codex/pin.js +1 -1
- package/clis/codex/rename.js +4 -4
- package/clis/codex/send.js +3 -3
- package/clis/codex/sidebar.js +1 -1
- package/clis/coingecko/categories.js +1 -1
- package/clis/coingecko/coin.js +1 -1
- package/clis/coingecko/derivatives.js +1 -1
- package/clis/coingecko/exchanges.js +1 -1
- package/clis/coingecko/global.js +1 -1
- package/clis/coingecko/trending.js +1 -1
- package/clis/confluence/search.js +1 -1
- package/clis/coupang/product.js +3 -3
- package/clis/coupang/utils.js +1 -1
- package/clis/crates/crate.js +1 -1
- package/clis/crates/search.js +1 -1
- package/clis/crates/utils.js +1 -1
- package/clis/csdn/article.js +13 -13
- package/clis/csdn/columns.js +1 -1
- package/clis/csdn/login.js +1 -1
- package/clis/csdn/stats.js +4 -4
- package/clis/csdn/whoami.js +1 -1
- package/clis/cto51/article.js +1 -1
- package/clis/cto51/whoami.js +1 -1
- package/clis/ctrip/flight.js +2 -2
- package/clis/ctrip/hotel-search.js +3 -3
- package/clis/ctrip/hotel-suggest.js +1 -1
- package/clis/ctrip/search.js +1 -1
- package/clis/ctrip/utils.js +6 -6
- package/clis/cursor/ask.js +5 -5
- package/clis/cursor/composer.js +2 -2
- package/clis/cursor/model.js +4 -4
- package/clis/cursor/send.js +2 -2
- package/clis/dblp/author.js +1 -1
- package/clis/dblp/paper.js +1 -1
- package/clis/dblp/search.js +1 -1
- package/clis/dblp/utils.js +1 -1
- package/clis/dblp/venue.js +1 -1
- package/clis/deepseek/ask.js +1 -1
- package/clis/deepseek/auth.js +2 -2
- package/clis/deepseek/detail.js +1 -1
- package/clis/deepseek/new.js +1 -1
- package/clis/deepseek/read.js +1 -1
- package/clis/deepseek/send.js +7 -7
- package/clis/deepseek/utils.js +25 -25
- package/clis/defillama/protocol.js +1 -1
- package/clis/defillama/protocols.js +1 -1
- package/clis/defillama/utils.js +1 -1
- package/clis/devto/auth.js +2 -2
- package/clis/devto/latest.js +1 -1
- package/clis/devto/publish.js +5 -5
- package/clis/devto/read.js +2 -2
- package/clis/devto/stats.js +3 -3
- package/clis/dianping/auth.js +2 -2
- package/clis/dianping/cityResolver.js +2 -2
- package/clis/dianping/search.js +1 -1
- package/clis/dianping/shop.js +1 -1
- package/clis/dianping/utils.js +1 -1
- package/clis/discord-app/delete.js +3 -3
- package/clis/discord-app/read.js +1 -1
- package/clis/discord-app/thread-read.js +1 -1
- package/clis/discord-web/auth.js +2 -2
- package/clis/discord-web/send.js +5 -5
- package/clis/dockerhub/image.js +1 -1
- package/clis/dockerhub/search.js +1 -1
- package/clis/dockerhub/utils.js +1 -1
- package/clis/dongchedi/koubei.js +1 -1
- package/clis/dongchedi/models.js +1 -1
- package/clis/dongchedi/score.js +1 -1
- package/clis/dongchedi/search.js +1 -1
- package/clis/dongchedi/series.js +1 -1
- package/clis/dongchedi/specs.js +1 -1
- package/clis/dongchedi/utils.js +1 -1
- package/clis/douban/article.js +3 -3
- package/clis/douban/auth.js +2 -2
- package/clis/douban/download.js +1 -1
- package/clis/douban/utils.js +23 -23
- package/clis/doubao/auth.js +3 -3
- package/clis/doubao/utils.js +39 -39
- package/clis/doubao-app/ask.js +1 -1
- package/clis/doubao-app/utils.js +4 -4
- package/clis/douyin/_shared/browser-fetch.js +7 -7
- package/clis/douyin/_shared/draft-cache.js +1 -1
- package/clis/douyin/_shared/imagex-upload.js +1 -1
- package/clis/douyin/_shared/sts2.js +1 -1
- package/clis/douyin/_shared/text-extra.js +1 -1
- package/clis/douyin/_shared/tos-upload.js +4 -4
- package/clis/douyin/_shared/transcode.js +1 -1
- package/clis/douyin/_shared/vod-upload.js +4 -4
- package/clis/douyin/draft.js +18 -18
- package/clis/douyin/drafts.js +1 -1
- package/clis/douyin/publish-image.js +12 -12
- package/clis/douyin/publish.js +9 -9
- package/clis/douyin/search.js +3 -3
- package/clis/douyin/videos.js +1 -1
- package/clis/eastmoney/_secid.js +1 -1
- package/clis/eastmoney/announcement.js +1 -1
- package/clis/eastmoney/article.js +1 -1
- package/clis/eastmoney/convertible.js +1 -1
- package/clis/eastmoney/etf.js +1 -1
- package/clis/eastmoney/holders.js +1 -1
- package/clis/eastmoney/index-board.js +1 -1
- package/clis/eastmoney/kline.js +1 -1
- package/clis/eastmoney/kuaixun.js +1 -1
- package/clis/eastmoney/longhu.js +1 -1
- package/clis/eastmoney/money-flow.js +1 -1
- package/clis/eastmoney/northbound.js +1 -1
- package/clis/eastmoney/quote.js +1 -1
- package/clis/eastmoney/rank.js +1 -1
- package/clis/eastmoney/sectors.js +1 -1
- package/clis/endoflife/product.js +1 -1
- package/clis/endoflife/utils.js +1 -1
- package/clis/facebook/comment.js +8 -8
- package/clis/facebook/feed.js +4 -4
- package/clis/facebook/like.js +5 -5
- package/clis/facebook/notifications.js +3 -3
- package/clis/facebook/post.js +11 -11
- package/clis/facebook/search.js +3 -3
- package/clis/flathub/app.js +1 -1
- package/clis/flathub/search.js +1 -1
- package/clis/flathub/utils.js +1 -1
- package/clis/flomo/memos.js +1 -1
- package/clis/gemini/deep-research-result.js +4 -4
- package/clis/gemini/deep-research.js +1 -1
- package/clis/gemini/detail.js +1 -1
- package/clis/gemini/history.js +1 -1
- package/clis/gemini/image.js +2 -2
- package/clis/gemini/status.js +1 -1
- package/clis/gemini/utils.js +43 -43
- package/clis/geogebra/hexagon.js +1 -1
- package/clis/geogebra/info.js +3 -3
- package/clis/geogebra/triangle.js +1 -1
- package/clis/geogebra/utils.js +11 -11
- package/clis/ghost/login.js +1 -1
- package/clis/ghost/shared.js +2 -2
- package/clis/gitee/auth.js +2 -2
- package/clis/github-trending/repos.js +1 -1
- package/clis/google/news.js +1 -1
- package/clis/google/search.js +2 -2
- package/clis/google/suggest.js +1 -1
- package/clis/google/trends.js +1 -1
- package/clis/google/utils.js +1 -1
- package/clis/goproxy/module.js +1 -1
- package/clis/goproxy/utils.js +1 -1
- package/clis/goproxy/versions.js +1 -1
- package/clis/gov-policy/recent.js +2 -2
- package/clis/gov-policy/search.js +2 -2
- package/clis/grok/ask.js +1 -1
- package/clis/grok/detail.js +1 -1
- package/clis/grok/image.js +8 -8
- package/clis/grok/pin.js +1 -1
- package/clis/grok/send.js +1 -1
- package/clis/grok/status.js +1 -1
- package/clis/grok/utils.js +21 -21
- package/clis/guazi/browse.js +1 -1
- package/clis/guazi/car.js +1 -1
- package/clis/guazi/utils.js +1 -1
- package/clis/hackernews/auth.js +2 -2
- package/clis/hackernews/comment.js +8 -8
- package/clis/hackernews/read.js +7 -7
- package/clis/hackernews/submit.js +7 -7
- package/clis/hashnode/auth.js +3 -3
- package/clis/hashnode/publish.js +14 -14
- package/clis/hf/auth.js +2 -2
- package/clis/hf/models.js +1 -1
- package/clis/hf/paper.js +1 -1
- package/clis/hf/spaces.js +1 -1
- package/clis/hf/top.js +1 -1
- package/clis/homebrew/cask.js +1 -1
- package/clis/homebrew/formula.js +1 -1
- package/clis/homebrew/popular.js +1 -1
- package/clis/homebrew/utils.js +1 -1
- package/clis/huodongxing/events.js +1 -1
- package/clis/hupu/detail.js +4 -4
- package/clis/hupu/hot.js +3 -3
- package/clis/hupu/reply.js +1 -1
- package/clis/hupu/search.js +1 -1
- package/clis/hupu/unlike.js +1 -1
- package/clis/hupu/utils.js +10 -10
- package/clis/imdb/person.js +2 -2
- package/clis/imdb/reviews.js +3 -3
- package/clis/imdb/search.js +2 -2
- package/clis/imdb/title.js +1 -1
- package/clis/imdb/top.js +1 -1
- package/clis/imdb/trending.js +1 -1
- package/clis/imdb/utils.js +13 -13
- package/clis/imooc/article.js +6 -6
- package/clis/imooc/login.js +1 -1
- package/clis/imooc/whoami.js +1 -1
- package/clis/indeed/job.js +2 -2
- package/clis/indeed/search.js +2 -2
- package/clis/indeed/utils.js +1 -1
- package/clis/infoq/article.js +2 -2
- package/clis/infoq/login.js +1 -1
- package/clis/infoq/whoami.js +1 -1
- package/clis/instagram/_shared/private-publish.js +4 -4
- package/clis/instagram/_shared/protocol-capture.js +9 -9
- package/clis/instagram/detail.js +3 -3
- package/clis/instagram/post.js +25 -25
- package/clis/instagram/reel.js +18 -18
- package/clis/instagram/story.js +4 -4
- package/clis/instagram/user.js +2 -2
- package/clis/jd/item.js +65 -65
- package/clis/jianshu/article.js +1 -1
- package/clis/jianshu/login.js +1 -1
- package/clis/jianshu/notebooks.js +1 -1
- package/clis/jianshu/whoami.js +1 -1
- package/clis/jianyu/search.js +6 -6
- package/clis/jianyu/shared/procurement-contract.js +1 -1
- package/clis/jike/api.js +6 -6
- package/clis/jike/auth.js +3 -3
- package/clis/jike/comment.js +1 -1
- package/clis/jike/create.js +6 -6
- package/clis/jike/feed.js +3 -3
- package/clis/jike/like.js +1 -1
- package/clis/jike/notifications.js +3 -3
- package/clis/jike/repost.js +13 -13
- package/clis/jike/search.js +3 -3
- package/clis/jimeng/auth.js +2 -2
- package/clis/jimeng/generate.js +10 -10
- package/clis/jira/shared.js +1 -1
- package/clis/juejin/article.js +4 -4
- package/clis/juejin/categories.js +1 -1
- package/clis/juejin/hot.js +1 -1
- package/clis/juejin/login.js +1 -1
- package/clis/juejin/recommend.js +1 -1
- package/clis/juejin/stats.js +3 -3
- package/clis/juejin/tags.js +1 -1
- package/clis/juejin/utils.js +1 -1
- package/clis/juejin/whoami.js +1 -1
- package/clis/ke/utils.js +4 -4
- package/clis/kimi/_utils.js +7 -7
- package/clis/kimi/audit-extras.js +14 -14
- package/clis/kimi/auth.js +3 -3
- package/clis/kimi/chat.js +15 -15
- package/clis/kimi/storage.js +5 -5
- package/clis/kimi/ui.js +13 -13
- package/clis/kimi/usage.js +3 -3
- package/clis/kuaishou/auth.js +1 -1
- package/clis/kuaishou/publish.js +6 -6
- package/clis/lesswrong/_helpers.js +5 -5
- package/clis/lesswrong/comments.js +5 -5
- package/clis/lichess/top.js +1 -1
- package/clis/lichess/user.js +1 -1
- package/clis/lichess/utils.js +1 -1
- package/clis/linkedin/comment.js +1 -1
- package/clis/linkedin/connect.js +11 -11
- package/clis/linkedin/create.js +5 -5
- package/clis/linkedin/follow.js +1 -1
- package/clis/linkedin/inbox.js +1 -1
- package/clis/linkedin/job-detail.js +3 -3
- package/clis/linkedin/like.js +1 -1
- package/clis/linkedin/notifications.js +1 -1
- package/clis/linkedin/people-search.js +1 -1
- package/clis/linkedin/post-comments.js +1 -1
- package/clis/linkedin/post-detail.js +1 -1
- package/clis/linkedin/profile-analytics.js +1 -1
- package/clis/linkedin/profile-api.js +13 -13
- package/clis/linkedin/profile-experience.js +1 -1
- package/clis/linkedin/profile-projects.js +1 -1
- package/clis/linkedin/profile-read.js +3 -3
- package/clis/linkedin/reply.js +1 -1
- package/clis/linkedin/repost.js +1 -1
- package/clis/linkedin/safe-send.js +8 -8
- package/clis/linkedin/salesnav-inbox.js +5 -5
- package/clis/linkedin/salesnav-message.js +3 -3
- package/clis/linkedin/salesnav-search.js +4 -4
- package/clis/linkedin/salesnav-thread.js +1 -1
- package/clis/linkedin/search-api.js +3 -3
- package/clis/linkedin/search.js +8 -8
- package/clis/linkedin/social-api.js +31 -31
- package/clis/linkedin/timeline.js +3 -3
- package/clis/linkedin-learning/search.js +2 -2
- package/clis/linkedin-learning/trending.js +2 -2
- package/clis/linux-do/feed.js +4 -4
- package/clis/linux-do/topic-content.js +8 -8
- package/clis/lobsters/domain.js +1 -1
- package/clis/lobsters/read.js +7 -7
- package/clis/maimai/auth.js +2 -2
- package/clis/maimai/search-talents.js +4 -4
- package/clis/manus/_utils.js +1 -1
- package/clis/mastodon/login.js +1 -1
- package/clis/mastodon/post.js +1 -1
- package/clis/mastodon/shared.js +12 -12
- package/clis/mastodon/whoami.js +1 -1
- package/clis/maven/artifact.js +1 -1
- package/clis/maven/search.js +1 -1
- package/clis/maven/utils.js +1 -1
- package/clis/mdn/search.js +1 -1
- package/clis/medium/article.js +5 -5
- package/clis/medium/login.js +1 -1
- package/clis/medium/stats.js +3 -3
- package/clis/medium/tag.js +1 -1
- package/clis/medium/whoami.js +1 -1
- package/clis/mubu/notes.js +1 -1
- package/clis/mubu/utils.js +15 -15
- package/clis/note/auth.js +2 -2
- package/clis/note/note-utils.js +2 -2
- package/clis/note/publish.js +8 -8
- package/clis/notebooklm/add-source.js +8 -8
- package/clis/notebooklm/create.js +1 -1
- package/clis/notebooklm/generate-slides.js +1 -1
- package/clis/notebooklm/notes-get.js +1 -1
- package/clis/notebooklm/rpc.js +8 -8
- package/clis/notebooklm/source-fulltext.js +1 -1
- package/clis/notebooklm/utils.js +10 -10
- package/clis/nowcoder/auth.js +2 -2
- package/clis/nowcoder/comment.js +1 -1
- package/clis/nowcoder/comments.js +1 -1
- package/clis/nowcoder/dm-list.js +1 -1
- package/clis/nowcoder/dm-read.js +1 -1
- package/clis/nowcoder/dm-send.js +1 -1
- package/clis/nowcoder/drafts.js +1 -1
- package/clis/nowcoder/inbox.js +1 -1
- package/clis/nowcoder/like.js +1 -1
- package/clis/nowcoder/my.js +1 -1
- package/clis/nowcoder/post.js +1 -1
- package/clis/nowcoder/utils.js +13 -13
- package/clis/npm/downloads.js +1 -1
- package/clis/npm/package.js +1 -1
- package/clis/npm/search.js +1 -1
- package/clis/npm/utils.js +1 -1
- package/clis/nuget/package.js +1 -1
- package/clis/nuget/search.js +1 -1
- package/clis/nuget/utils.js +1 -1
- package/clis/nvd/cve.js +1 -1
- package/clis/oeis/search.js +1 -1
- package/clis/oeis/sequence.js +1 -1
- package/clis/oeis/utils.js +1 -1
- package/clis/ones/common.js +6 -6
- package/clis/ones/enrich-tasks.js +1 -1
- package/clis/ones/my-tasks.js +1 -1
- package/clis/ones/resolve-labels.js +1 -1
- package/clis/ones/task-helpers.js +1 -1
- package/clis/ones/task.js +1 -1
- package/clis/ones/worklog.js +7 -7
- package/clis/openalex/search.js +1 -1
- package/clis/openalex/utils.js +1 -1
- package/clis/openalex/work.js +1 -1
- package/clis/openfda/drug-label.js +1 -1
- package/clis/openfda/food-recall.js +1 -1
- package/clis/openfda/utils.js +1 -1
- package/clis/openreview/author.js +1 -1
- package/clis/openreview/paper.js +1 -1
- package/clis/openreview/reviews.js +3 -3
- package/clis/openreview/search.js +1 -1
- package/clis/openreview/utils.js +1 -1
- package/clis/openreview/venue.js +1 -1
- package/clis/oschina/article.js +1 -1
- package/clis/oschina/catalogs.js +1 -1
- package/clis/oschina/login.js +1 -1
- package/clis/oschina/stats.js +6 -6
- package/clis/oschina/whoami.js +1 -1
- package/clis/osv/query.js +1 -1
- package/clis/osv/utils.js +1 -1
- package/clis/osv/vulnerability.js +1 -1
- package/clis/packagist/package.js +1 -1
- package/clis/packagist/search.js +1 -1
- package/clis/packagist/utils.js +1 -1
- package/clis/pinterest/api.js +1 -1
- package/clis/pinterest/auth.js +1 -1
- package/clis/pinterest/boards.js +1 -1
- package/clis/pinterest/client.js +6 -6
- package/clis/pinterest/publish.js +5 -5
- package/clis/pixiv/auth.js +2 -2
- package/clis/pixiv/download.js +1 -1
- package/clis/pixiv/illusts.js +1 -1
- package/clis/pixiv/search.js +1 -1
- package/clis/pixiv/utils.js +3 -3
- package/clis/powerchina/auth.js +2 -2
- package/clis/powerchina/search.js +1 -1
- package/clis/producthunt/browse.js +2 -2
- package/clis/producthunt/hot.js +2 -2
- package/clis/producthunt/posts.js +1 -1
- package/clis/producthunt/today.js +1 -1
- package/clis/producthunt/utils.js +1 -1
- package/clis/pypi/downloads.js +1 -1
- package/clis/pypi/package.js +1 -1
- package/clis/pypi/utils.js +1 -1
- package/clis/qiita/auth.js +1 -1
- package/clis/qiita/gql.js +6 -6
- package/clis/qiita/publish.js +4 -4
- package/clis/qiita/stats.js +4 -4
- package/clis/qoder/_utils.js +16 -16
- package/clis/qoder/composer.js +1 -1
- package/clis/qoder/quest.js +1 -1
- package/clis/qoder/ui.js +14 -14
- package/clis/quark/auth.js +2 -2
- package/clis/quark/utils.js +2 -2
- package/clis/quora/answer-comments.js +3 -3
- package/clis/quora/create-answer.js +4 -4
- package/clis/quora/create-question.js +3 -3
- package/clis/quora/shared.js +17 -17
- package/clis/quora/whoami.js +1 -1
- package/clis/qwen/ask.js +1 -1
- package/clis/qwen/auth.js +3 -3
- package/clis/qwen/detail.js +1 -1
- package/clis/qwen/image.js +5 -5
- package/clis/qwen/status.js +1 -1
- package/clis/qwen/utils.js +16 -16
- package/clis/reddit/home.js +3 -3
- package/clis/reddit/read.js +10 -10
- package/clis/reddit/reply.js +4 -4
- package/clis/reddit/submit.js +11 -11
- package/clis/reddit/subreddit-info.js +3 -3
- package/clis/reddit/subscribed.js +4 -4
- package/clis/reddit/whoami.js +2 -2
- package/clis/rednote/comments.js +1 -1
- package/clis/rednote/download.js +1 -1
- package/clis/rednote/feed.js +1 -1
- package/clis/rednote/note.js +1 -1
- package/clis/rednote/notifications.js +2 -2
- package/clis/rednote/search.js +2 -2
- package/clis/rest-countries/country.js +1 -1
- package/clis/rest-countries/region.js +1 -1
- package/clis/rest-countries/utils.js +1 -1
- package/clis/reuters/article-detail.js +1 -1
- package/clis/reuters/auth.js +3 -3
- package/clis/reuters/search.js +1 -1
- package/clis/reuters/utils.js +4 -4
- package/clis/rfc/rfc.js +1 -1
- package/clis/rfc/utils.js +1 -1
- package/clis/rubygems/gem.js +1 -1
- package/clis/rubygems/search.js +1 -1
- package/clis/rubygems/utils.js +1 -1
- package/clis/segmentfault/article.js +3 -3
- package/clis/segmentfault/channels.js +1 -1
- package/clis/segmentfault/login.js +1 -1
- package/clis/segmentfault/stats.js +4 -4
- package/clis/segmentfault/tags.js +1 -1
- package/clis/segmentfault/whoami.js +1 -1
- package/clis/semanticscholar/citations.js +1 -1
- package/clis/semanticscholar/paper.js +1 -1
- package/clis/semanticscholar/recommendations.js +1 -1
- package/clis/semanticscholar/search.js +1 -1
- package/clis/semanticscholar/utils.js +1 -1
- package/clis/sinafinance/news.js +1 -1
- package/clis/sinafinance/stock-rank.js +1 -1
- package/clis/sinafinance/stock.js +1 -1
- package/clis/slock/attachment-download.js +1 -1
- package/clis/slock/attachment-upload.js +7 -7
- package/clis/slock/attachment-url.js +1 -1
- package/clis/slock/auth-verify.js +1 -1
- package/clis/slock/bookmark-add.js +1 -1
- package/clis/slock/bookmark-remove.js +1 -1
- package/clis/slock/channel-action.js +1 -1
- package/clis/slock/channel-create.js +1 -1
- package/clis/slock/channel-files.js +1 -1
- package/clis/slock/channel-list.js +1 -1
- package/clis/slock/channel-mark.js +1 -1
- package/clis/slock/channel-members.js +1 -1
- package/clis/slock/channel-unarchive.js +1 -1
- package/clis/slock/dm-list.js +1 -1
- package/clis/slock/errors.js +1 -1
- package/clis/slock/in-page.js +28 -28
- package/clis/slock/inbox-done.js +5 -5
- package/clis/slock/inbox.js +1 -1
- package/clis/slock/message-read.js +22 -22
- package/clis/slock/message-search.js +10 -10
- package/clis/slock/message-send.js +25 -25
- package/clis/slock/reaction-add.js +1 -1
- package/clis/slock/reaction-remove.js +1 -1
- package/clis/slock/resolve.js +1 -1
- package/clis/slock/server-list.js +2 -2
- package/clis/slock/task-claim.js +4 -4
- package/clis/slock/task-convert.js +13 -13
- package/clis/slock/task-create.js +1 -1
- package/clis/slock/task-delete.js +5 -5
- package/clis/slock/task-get.js +5 -5
- package/clis/slock/task-list-server.js +4 -4
- package/clis/slock/task-list.js +5 -5
- package/clis/slock/task-status.js +3 -3
- package/clis/slock/task-unclaim.js +3 -3
- package/clis/slock/thread-follow.js +1 -1
- package/clis/slock/thread-state.js +1 -1
- package/clis/slock/unread-summary.js +5 -5
- package/clis/slock/whoami.js +1 -1
- package/clis/smzdm/search.js +3 -3
- package/clis/sohu/article.js +1 -1
- package/clis/sohu/attributes.js +1 -1
- package/clis/sohu/categories.js +1 -1
- package/clis/sohu/channels.js +1 -1
- package/clis/sohu/columns.js +1 -1
- package/clis/sohu/login.js +1 -1
- package/clis/sohu/stats.js +3 -3
- package/clis/sohu/topics.js +1 -1
- package/clis/sohu/whoami.js +1 -1
- package/clis/spotify/spotify.js +1 -1
- package/clis/stackoverflow/read.js +6 -6
- package/clis/stackoverflow/related.js +1 -1
- package/clis/stackoverflow/tag.js +1 -1
- package/clis/stackoverflow/user.js +1 -1
- package/clis/stackoverflow/utils.js +1 -1
- package/clis/steam/app.js +1 -1
- package/clis/steam/search.js +1 -1
- package/clis/steam/utils.js +1 -1
- package/clis/substack/auth.js +2 -2
- package/clis/substack/post-utils.js +2 -2
- package/clis/substack/publish.js +5 -5
- package/clis/suno/auth.js +2 -2
- package/clis/suno/download.js +5 -5
- package/clis/suno/generate.js +3 -3
- package/clis/suno/list.js +1 -1
- package/clis/suno/status.js +1 -1
- package/clis/suno/utils.js +29 -29
- package/clis/telegram/send.js +7 -7
- package/clis/telegram/shared.js +2 -2
- package/clis/telegram/whoami.js +1 -1
- package/clis/test-utils.js +1 -1
- package/clis/threads/post.js +23 -23
- package/clis/threads/shared.js +3 -3
- package/clis/threads/whoami.js +1 -1
- package/clis/tieba/hot.js +3 -3
- package/clis/tieba/posts.js +1 -1
- package/clis/tieba/read.js +2 -2
- package/clis/tieba/search.js +3 -3
- package/clis/tieba/utils.js +1 -1
- package/clis/tiktok/comment.js +2 -2
- package/clis/tiktok/creator-videos.js +3 -3
- package/clis/tiktok/explore.js +3 -3
- package/clis/tiktok/follow.js +8 -8
- package/clis/tiktok/following.js +4 -4
- package/clis/tiktok/friends.js +7 -7
- package/clis/tiktok/live.js +3 -3
- package/clis/tiktok/notifications.js +6 -6
- package/clis/tiktok/publish.js +17 -17
- package/clis/tiktok/unfollow.js +4 -4
- package/clis/tiktok/user.js +2 -2
- package/clis/tiktok/utils.js +1 -1
- package/clis/toutiao/article.js +1 -1
- package/clis/toutiao/articles.js +2 -2
- package/clis/toutiao/auth.js +2 -2
- package/clis/toutiao/hot.js +1 -1
- package/clis/toutiao/recommend.js +1 -1
- package/clis/toutiao/utils.js +2 -2
- package/clis/trae-solo/_actions.js +4 -4
- package/clis/trae-solo/_fs.js +5 -5
- package/clis/trae-solo/_state.js +2 -2
- package/clis/trae-solo/automation.js +4 -4
- package/clis/trae-solo/mode.js +4 -4
- package/clis/trae-solo/model.js +4 -4
- package/clis/trae-solo/renderer-storage.js +4 -4
- package/clis/trae-solo/settings.js +1 -1
- package/clis/trae-solo/skill-fs.js +1 -1
- package/clis/trae-solo/skill.js +12 -12
- package/clis/trae-solo/state-fs.js +2 -2
- package/clis/trae-solo/task-fs.js +5 -5
- package/clis/trae-solo/workspaces-fs.js +1 -1
- package/clis/tumblr/auth.js +2 -2
- package/clis/tumblr/publish.js +3 -3
- package/clis/tvmaze/search.js +1 -1
- package/clis/tvmaze/show.js +1 -1
- package/clis/tvmaze/utils.js +1 -1
- package/clis/twitter/accept.js +7 -7
- package/clis/twitter/article.js +7 -7
- package/clis/twitter/bookmark-folder.js +3 -3
- package/clis/twitter/bookmark-folders.js +3 -3
- package/clis/twitter/bookmarks.js +4 -4
- package/clis/twitter/delete.js +5 -5
- package/clis/twitter/device-follow.js +3 -3
- package/clis/twitter/dm-list.js +1 -1
- package/clis/twitter/dm-read.js +1 -1
- package/clis/twitter/dm-send.js +5 -5
- package/clis/twitter/dm-shared.js +3 -3
- package/clis/twitter/download.js +6 -6
- package/clis/twitter/followers.js +5 -5
- package/clis/twitter/following.js +2 -2
- package/clis/twitter/like.js +3 -3
- package/clis/twitter/likes.js +8 -8
- package/clis/twitter/list-add-core.js +9 -9
- package/clis/twitter/list-create.js +5 -5
- package/clis/twitter/list-remove-core.js +9 -9
- package/clis/twitter/list-tweets.js +7 -7
- package/clis/twitter/lists.js +6 -6
- package/clis/twitter/notifications.js +2 -2
- package/clis/twitter/post.js +24 -24
- package/clis/twitter/profile.js +7 -7
- package/clis/twitter/quote.js +7 -7
- package/clis/twitter/reply-dm.js +7 -7
- package/clis/twitter/reply.js +12 -12
- package/clis/twitter/retweet.js +3 -3
- package/clis/twitter/scheduled-delete.js +3 -3
- package/clis/twitter/scheduled-list.js +2 -2
- package/clis/twitter/scheduled-utils.js +3 -3
- package/clis/twitter/search.js +5 -5
- package/clis/twitter/shared.js +6 -6
- package/clis/twitter/thread.js +4 -4
- package/clis/twitter/timeline.js +3 -3
- package/clis/twitter/trending.js +2 -2
- package/clis/twitter/tweets.js +11 -11
- package/clis/twitter/unlike.js +3 -3
- package/clis/twitter/unretweet.js +3 -3
- package/clis/twitter/utils.js +6 -6
- package/clis/upwork/detail.js +2 -2
- package/clis/upwork/feed.js +2 -2
- package/clis/upwork/search.js +2 -2
- package/clis/upwork/utils.js +1 -1
- package/clis/v2ex/auth.js +2 -2
- package/clis/v2ex/daily.js +3 -3
- package/clis/v2ex/me.js +2 -2
- package/clis/v2ex/notifications.js +2 -2
- package/clis/vk/post.js +1 -1
- package/clis/vk/shared.js +2 -2
- package/clis/vk/whoami.js +1 -1
- package/clis/web/read.js +8 -8
- package/clis/wechat-channels/auth.js +2 -2
- package/clis/wechat-channels/publish.js +30 -30
- package/clis/weibo/article.js +1 -1
- package/clis/weibo/auth.js +3 -3
- package/clis/weibo/comments.js +1 -1
- package/clis/weibo/delete.js +2 -2
- package/clis/weibo/feed.js +3 -3
- package/clis/weibo/hot.js +1 -1
- package/clis/weibo/publish.js +10 -10
- package/clis/weibo/search.js +2 -2
- package/clis/weibo/user-posts.js +3 -3
- package/clis/weibo/user.js +2 -2
- package/clis/weibo/utils.js +3 -3
- package/clis/weixin/article.js +1 -1
- package/clis/weixin/create-draft.js +26 -26
- package/clis/weixin/download.js +2 -2
- package/clis/weixin/login.js +1 -1
- package/clis/weixin/search.js +2 -2
- package/clis/weixin/stats.js +3 -3
- package/clis/weixin/whoami.js +1 -1
- package/clis/weread/ai-outline.js +2 -2
- package/clis/weread/book-search.js +2 -2
- package/clis/weread/book.js +2 -2
- package/clis/weread/notebooks.js +1 -1
- package/clis/weread/search.js +1 -1
- package/clis/weread/shelf.js +1 -1
- package/clis/weread/utils.js +6 -6
- package/clis/weread-official/book.js +1 -1
- package/clis/weread-official/discover.js +1 -1
- package/clis/weread-official/list-apis.js +1 -1
- package/clis/weread-official/notes.js +1 -1
- package/clis/weread-official/readdata.js +1 -1
- package/clis/weread-official/review.js +1 -1
- package/clis/weread-official/search.js +1 -1
- package/clis/weread-official/shelf.js +1 -1
- package/clis/weread-official/utils.js +1 -1
- package/clis/wikidata/entity.js +1 -1
- package/clis/wikidata/search.js +1 -1
- package/clis/wikidata/utils.js +1 -1
- package/clis/wikipedia/page.js +1 -1
- package/clis/wikipedia/trending.js +1 -1
- package/clis/wikipedia/utils.js +1 -1
- package/clis/wordpress/login.js +1 -1
- package/clis/wordpress/publish.js +1 -1
- package/clis/wordpress/shared.js +3 -3
- package/clis/wordpress/whoami.js +1 -1
- package/clis/woshipm/article.js +1 -1
- package/clis/woshipm/login.js +1 -1
- package/clis/woshipm/stats.js +4 -4
- package/clis/woshipm/whoami.js +1 -1
- package/clis/wttr/current.js +1 -1
- package/clis/wttr/forecast.js +1 -1
- package/clis/wttr/utils.js +1 -1
- package/clis/xianyu/collect.js +1 -1
- package/clis/xianyu/inbox.js +1 -1
- package/clis/xianyu/item-stats.js +2 -2
- package/clis/xianyu/location.js +1 -1
- package/clis/xianyu/manage.js +1 -1
- package/clis/xianyu/messages.js +1 -1
- package/clis/xianyu/mtop.js +5 -5
- package/clis/xianyu/order.js +1 -1
- package/clis/xianyu/promote-stats.js +2 -2
- package/clis/xianyu/publish.js +17 -17
- package/clis/xianyu/rate.js +1 -1
- package/clis/xianyu/reply.js +1 -1
- package/clis/xianyu/search.js +8 -8
- package/clis/xianyu/seller-data.js +1 -1
- package/clis/xianyu/seller-list.js +1 -1
- package/clis/xianyu/user.js +1 -1
- package/clis/xiaoe/catalog.js +2 -2
- package/clis/xiaoe/content.js +2 -2
- package/clis/xiaoe/courses.js +2 -2
- package/clis/xiaohongshu/ask.js +6 -6
- package/clis/xiaohongshu/comments.js +6 -6
- package/clis/xiaohongshu/creator-note-detail.js +7 -7
- package/clis/xiaohongshu/creator-notes-summary.js +1 -1
- package/clis/xiaohongshu/creator-notes.js +13 -13
- package/clis/xiaohongshu/creator-profile.js +2 -2
- package/clis/xiaohongshu/creator-stats.js +2 -2
- package/clis/xiaohongshu/delete-note.js +7 -7
- package/clis/xiaohongshu/download.js +4 -4
- package/clis/xiaohongshu/feed.js +2 -2
- package/clis/xiaohongshu/follow.js +3 -3
- package/clis/xiaohongshu/human.js +3 -3
- package/clis/xiaohongshu/note-helpers.js +1 -1
- package/clis/xiaohongshu/note.js +2 -2
- package/clis/xiaohongshu/notifications.js +1 -1
- package/clis/xiaohongshu/publish-video.js +8 -8
- package/clis/xiaohongshu/publish.js +59 -59
- package/clis/xiaohongshu/search.js +8 -8
- package/clis/xiaohongshu/unfollow.js +4 -4
- package/clis/xiaohongshu/user-helpers.js +1 -1
- package/clis/xiaohongshu/user.js +2 -2
- package/clis/xiaoyuzhou/auth.js +3 -3
- package/clis/xiaoyuzhou/download.js +1 -1
- package/clis/xiaoyuzhou/utils.js +1 -1
- package/clis/xueqiu/article.js +4 -4
- package/clis/xueqiu/comments.js +4 -4
- package/clis/xueqiu/danjuan-utils.js +4 -4
- package/clis/xueqiu/earnings-date.js +1 -1
- package/clis/xueqiu/events.js +3 -3
- package/clis/xueqiu/hashtags.js +3 -3
- package/clis/xueqiu/stocks.js +3 -3
- package/clis/xueqiu/users.js +3 -3
- package/clis/xueqiu/utils.js +3 -3
- package/clis/yahoo-finance/quote.js +1 -1
- package/clis/yollomi/background.js +1 -1
- package/clis/yollomi/edit.js +1 -1
- package/clis/yollomi/face-swap.js +1 -1
- package/clis/yollomi/generate.js +1 -1
- package/clis/yollomi/object-remover.js +1 -1
- package/clis/yollomi/remove-bg.js +1 -1
- package/clis/yollomi/restore.js +1 -1
- package/clis/yollomi/try-on.js +1 -1
- package/clis/yollomi/upload.js +4 -4
- package/clis/yollomi/upscale.js +1 -1
- package/clis/yollomi/utils.js +4 -4
- package/clis/yollomi/video.js +1 -1
- package/clis/youtube/channel.js +4 -4
- package/clis/youtube/feed.js +2 -2
- package/clis/youtube/like.js +5 -5
- package/clis/youtube/playlist.js +7 -7
- package/clis/youtube/publish.js +11 -11
- package/clis/youtube/search.js +3 -3
- package/clis/youtube/subscribe.js +7 -7
- package/clis/youtube/subscriptions.js +1 -1
- package/clis/youtube/transcript-group.js +2 -2
- package/clis/youtube/transcript.js +13 -13
- package/clis/youtube/unlike.js +5 -5
- package/clis/youtube/unsubscribe.js +7 -7
- package/clis/youtube/utils.js +3 -3
- package/clis/youtube/video.js +4 -4
- package/clis/youtube/watch-later.js +2 -2
- package/clis/yuanbao/ask.js +18 -18
- package/clis/yuanbao/detail.js +1 -1
- package/clis/yuanbao/read.js +1 -1
- package/clis/yuanbao/shared.js +9 -9
- package/clis/yuanbao/status.js +1 -1
- package/clis/yuque/article.js +1 -1
- package/clis/yuque/whoami.js +1 -1
- package/clis/zhihu/answer-comments.js +2 -2
- package/clis/zhihu/answer-detail.js +3 -3
- package/clis/zhihu/answer.js +1 -1
- package/clis/zhihu/article-transform.js +1 -1
- package/clis/zhihu/article.js +1 -1
- package/clis/zhihu/auth.js +2 -2
- package/clis/zhihu/collection.js +3 -3
- package/clis/zhihu/collections.js +3 -3
- package/clis/zhihu/download.js +2 -2
- package/clis/zhihu/image-profile.js +6 -6
- package/clis/zhihu/paginate.js +3 -3
- package/clis/zhihu/pin.js +4 -4
- package/clis/zhihu/question.js +3 -3
- package/clis/zhihu/recommend.js +3 -3
- package/clis/zhihu/search.js +3 -3
- package/clis/zhihu/stats.js +3 -3
- package/clis/zhihu/user-arg.js +1 -1
- package/clis/zhihu/write-shared.js +7 -7
- package/clis/zlibrary/utils.js +6 -6
- package/clis/zsxq/auth.js +3 -3
- package/clis/zsxq/search.js +1 -1
- package/clis/zsxq/topic.js +1 -1
- package/clis/zsxq/utils.js +5 -5
- package/dist/src/adapter-source.js +1 -1
- package/dist/src/browser/analyze.js +1 -1
- package/dist/src/browser/article-extract.js +2 -2
- package/dist/src/browser/ax-snapshot.js +2 -2
- package/dist/src/browser/base-page.js +25 -25
- package/dist/src/browser/bridge.js +1 -1
- package/dist/src/browser/cdp.js +1 -1
- package/dist/src/browser/daemon-client.js +1 -1
- package/dist/src/browser/daemon-lifecycle.js +7 -7
- package/dist/src/browser/dom-helpers.js +35 -35
- package/dist/src/browser/dom-snapshot.js +19 -19
- package/dist/src/browser/errors.js +3 -3
- package/dist/src/browser/extract.js +5 -5
- package/dist/src/browser/find.js +13 -13
- package/dist/src/browser/fingerprint.js +2 -2
- package/dist/src/browser/html-tree.js +6 -6
- package/dist/src/browser/managed-chrome.js +1 -1
- package/dist/src/browser/network-cache.js +1 -1
- package/dist/src/browser/network-key.js +1 -1
- package/dist/src/browser/page.js +7 -7
- package/dist/src/browser/profile.js +2 -2
- package/dist/src/browser/proxy-test.js +8 -8
- package/dist/src/browser/shape-filter.js +1 -1
- package/dist/src/browser/shape.js +1 -1
- package/dist/src/browser/stealth.js +3 -3
- package/dist/src/browser/tabs.js +2 -2
- package/dist/src/browser/target-errors.js +1 -1
- package/dist/src/browser/target-resolver.js +23 -23
- package/dist/src/browser/trace.js +2 -2
- package/dist/src/browser/utils.js +1 -1
- package/dist/src/browser/verify-fixture.js +2 -2
- package/dist/src/browser-session-lock.js +1 -1
- package/dist/src/build-manifest.js +11 -11
- package/dist/src/capabilityRouting.js +1 -1
- package/dist/src/cli-argv-preprocess.js +1 -1
- package/dist/src/cli.js +32 -32
- package/dist/src/commanderAdapter.js +3 -3
- package/dist/src/commands/auth.js +3 -3
- package/dist/src/commands/daemon.js +1 -1
- package/dist/src/completion-fast.js +1 -1
- package/dist/src/completion.js +1 -1
- package/dist/src/constants.js +1 -1
- package/dist/src/convention-audit.js +2 -2
- package/dist/src/daemon-utils.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/discovery.js +2 -2
- package/dist/src/doctor.js +9 -9
- package/dist/src/download/article-download.js +15 -15
- package/dist/src/download/index.js +4 -4
- package/dist/src/download/media-download.js +1 -1
- package/dist/src/download/progress.js +3 -3
- package/dist/src/electron-apps.js +1 -1
- package/dist/src/errors.js +2 -2
- package/dist/src/execution.js +2 -2
- package/dist/src/external.js +1 -1
- package/dist/src/help.js +8 -8
- package/dist/src/hooks.js +1 -1
- package/dist/src/interceptor.js +21 -21
- package/dist/src/launcher.js +7 -7
- package/dist/src/logger.js +8 -8
- package/dist/src/main.js +7 -7
- package/dist/src/observation/artifact.js +5 -5
- package/dist/src/observation/retention.js +1 -1
- package/dist/src/output.js +2 -2
- package/dist/src/package-paths.js +1 -1
- package/dist/src/pipeline/executor.js +1 -1
- package/dist/src/pipeline/registry.js +1 -1
- package/dist/src/pipeline/steps/browser.js +1 -1
- package/dist/src/pipeline/steps/download.js +1 -1
- package/dist/src/pipeline/steps/fetch.js +6 -6
- package/dist/src/pipeline/steps/intercept.js +1 -1
- package/dist/src/pipeline/steps/tap.js +17 -17
- package/dist/src/pipeline/steps/transform.js +1 -1
- package/dist/src/pipeline/template.js +1 -1
- package/dist/src/plugin-manifest.js +1 -1
- package/dist/src/plugin-scaffold.js +19 -19
- package/dist/src/plugin.js +12 -12
- package/dist/src/rate-limit.js +1 -1
- package/dist/src/registry.js +1 -1
- package/dist/src/runtime-detect.js +1 -1
- package/dist/src/runtime.js +1 -1
- package/dist/src/scripts/framework.js +1 -1
- package/dist/src/scripts/interact.js +1 -1
- package/dist/src/scripts/store.js +1 -1
- package/dist/src/serialization.js +2 -2
- package/dist/src/session-lease.js +1 -1
- package/dist/src/snapshotFormatter.js +2 -2
- package/dist/src/tui.js +12 -12
- package/dist/src/user-runtime.js +1 -1
- package/dist/src/utils.d.ts +12 -0
- package/dist/src/utils.js +4 -4
- package/dist/src/validate.js +2 -2
- package/dist/src/verify.js +2 -2
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as a,AuthRequiredError as w,selectorError as g,EmptyResultError as p,CommandExecutionError as y}from"@jackwener/opencli/errors";import{cli as b,Strategy as x}from"@jackwener/opencli/registry";import{normalizeTwitterScreenName as _,unwrapBrowserResult as v}from"./shared.js";async function d(e){const i=`() => {
|
|
2
2
|
const cells = document.querySelectorAll('[data-testid="UserCell"]');
|
|
3
3
|
const out = [];
|
|
4
4
|
for (const cell of cells) {
|
|
@@ -42,11 +42,11 @@ import{ArgumentError as V,AuthRequiredError as $,selectorError as T,EmptyResultE
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
return out;
|
|
45
|
-
}`;return
|
|
45
|
+
}`;return e.evaluate(i)}function c(e){return _(e)}b({site:"twitter",name:"followers",access:"read",description:"Get accounts following a Twitter/X user (defaults to the logged-in user when no user is given)",domain:"x.com",strategy:x.UI,browser:!0,args:[{name:"user",positional:!0,type:"string",required:!1,help:"Twitter/X handle (with or without @). Omit to fetch followers of the currently logged-in account."},{name:"limit",type:"int",default:50,help:"Maximum number of follower rows to return (default 50). Must be a positive integer."}],columns:["screen_name","name","bio"],func:async(e,i)=>{const o=i.limit;if(!Number.isInteger(o)||o<=0)throw new a("limit must be a positive integer");const u=String(i.user??"").trim();let t=c(u);if(u&&!t)throw new a("twitter followers user must be a valid Twitter/X handle","Example: ppcli twitter followers @elonmusk --limit 100");if(!t){await e.goto("https://x.com/home");await e.wait({selector:'[data-testid="primaryColumn"]'});const r=v(await e.evaluate(`() => {
|
|
46
46
|
const link = document.querySelector('a[data-testid="AppTabBar_Profile_Link"]');
|
|
47
47
|
return link ? link.getAttribute('href') : null;
|
|
48
|
-
}`));if(!
|
|
49
|
-
const target = ${
|
|
48
|
+
}`));if(!r||typeof r!=="string")throw new w("x.com","Could not find logged-in user profile link. Are you logged in?");t=c(r);if(!t)throw new w("x.com","Could not find logged-in user profile link. Are you logged in?")}if(!t)throw new a("twitter followers user cannot be empty","Example: ppcli twitter followers @elonmusk --limit 100");await e.goto(`https://x.com/${t}`);await e.wait(3);const h=JSON.stringify(t);if(!await e.evaluate(`() => {
|
|
49
|
+
const target = ${h};
|
|
50
50
|
const selectors = [
|
|
51
51
|
'a[href="/' + target + '/followers"]',
|
|
52
52
|
'a[href="/' + target + '/verified_followers"]',
|
|
@@ -56,4 +56,4 @@ import{ArgumentError as V,AuthRequiredError as $,selectorError as T,EmptyResultE
|
|
|
56
56
|
if (link) { link.click(); return true; }
|
|
57
57
|
}
|
|
58
58
|
return false;
|
|
59
|
-
}`))throw
|
|
59
|
+
}`))throw g("Twitter followers link","Twitter may have changed the layout.");await e.wait({selector:'[data-testid="UserCell"]',timeout:1e4});const n=[],m=new Set;let s=0;while(n.length<o&&s<3){const r=await d(e);if(!Array.isArray(r))throw new y("Twitter followers extraction returned malformed rows");const f=r.filter((l)=>!m.has(l.screen_name));for(const l of f){m.add(l.screen_name);n.push(l)}if(f.length===0)s++;else s=0;if(n.length>=o)break;await e.autoScroll({times:1,delayMs:500});await e.wait(2)}if(n.length===0)throw new p("twitter followers",`No followers found for @${t}`);return n.slice(0,o)}});export const __test__={extractFollowersFromDOM:d,normalizeScreenName:c};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as F,Strategy as M}from"@jackwener/opencli/registry";import{ArgumentError as v,AuthRequiredError as w,CommandExecutionError as m,EmptyResultError as C}from"@jackwener/opencli/errors";import{looksLikePrivateTwitterTimeline as P,normalizeTwitterScreenName as Q,resolveTwitterQueryId as N,sanitizeQueryId as X,unwrapBrowserResult as y,describeTwitterApiError as j}from"./shared.js";import{TWITTER_BEARER_TOKEN as z}from"./utils.js";const D="F42cDX8PDFxkbjjq6JrM2w",G="IGgvgiOx4QZndDHuD3x9TQ",J=100,L={rweb_video_screen_enabled:!1,profile_label_improvements_pcf_label_in_post_enabled:!0,responsive_web_profile_redirect_enabled:!1,rweb_tipjar_consumption_enabled:!1,verified_phone_label_enabled:!1,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_timeline_navigation_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,premium_content_api_read_enabled:!1,communities_web_enable_tweet_community_results_fetch:!0,c9s_tweet_anatomy_moderator_badge_enabled:!0,responsive_web_grok_analyze_button_fetch_trends_enabled:!1,responsive_web_grok_analyze_post_followups_enabled:!0,responsive_web_jetfuel_frame:!0,responsive_web_grok_share_attachment_enabled:!0,responsive_web_grok_annotations_enabled:!0,articles_preview_enabled:!0,responsive_web_edit_tweet_api_enabled:!0,graphql_is_translatable_rweb_tweet_is_translatable_enabled:!0,view_counts_everywhere_api_enabled:!0,longform_notetweets_consumption_enabled:!0,responsive_web_twitter_article_tweet_consumption_enabled:!0,tweet_awards_web_tipping_enabled:!1,content_disclosure_indicator_enabled:!0,content_disclosure_ai_generated_indicator_enabled:!0,responsive_web_grok_show_grok_translated_post:!1,responsive_web_grok_analysis_button_from_backend:!0,post_ctas_fetch_enabled:!1,freedom_of_speech_not_reach_fetch_enabled:!0,standardized_nudges_misinfo:!0,tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled:!0,longform_notetweets_rich_text_read_enabled:!0,longform_notetweets_inline_media_enabled:!1,responsive_web_grok_image_annotation_enabled:!0,responsive_web_grok_imagine_annotation_enabled:!0,responsive_web_grok_community_note_auto_translation_is_enabled:!1,responsive_web_enhance_cards_enabled:!1};function U(e,n,t,o){const r={userId:n,count:t,includePromotedContent:!1,withClientEventToken:!1,withBirdwatchNotes:!1,withVoice:!0,withV2Timeline:!0};if(o)r.cursor=o;return`/i/api/graphql/${e}/Following?variables=${encodeURIComponent(JSON.stringify(r))}&features=${encodeURIComponent(JSON.stringify(L))}`}function S(e,n){const t=JSON.stringify({screen_name:n,withSafetyModeUserFields:!0}),o=JSON.stringify({hidden_profile_subscriptions_enabled:!0,rweb_tipjar_consumption_enabled:!0,responsive_web_graphql_exclude_directive_enabled:!0,verified_phone_label_enabled:!1,subscriptions_verification_info_is_identity_verified_enabled:!0,subscriptions_verification_info_verified_since_enabled:!0,highlights_tweets_tab_ui_enabled:!0,responsive_web_twitter_article_notes_tab_enabled:!0,subscriptions_feature_can_gift_premium:!0,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,responsive_web_graphql_timeline_navigation_enabled:!0});return`/i/api/graphql/${e}/UserByScreenName?variables=${encodeURIComponent(t)}&features=${encodeURIComponent(o)}`}function A(e){if(!e||e.__typename!=="User")return null;const n=e.core||{},t=e.legacy||{},o=n.screen_name||t.screen_name||"";if(!o)throw new m("Malformed Twitter following user: missing screen_name");return{screen_name:o,name:n.name||t.name||"",bio:t.description||e.profile_bio?.description||"",followers:t.followers_count||t.normal_followers_count||0}}function R(e){const n=[];let t=null;const o=e?.data?.user?.result?.timeline_v2?.timeline?.instructions||e?.data?.user?.result?.timeline?.timeline?.instructions||[];for(const r of o)for(const _ of r.entries||[]){const i=_.content;if(i?.entryType==="TimelineTimelineCursor"||i?.__typename==="TimelineTimelineCursor"){if(i.cursorType==="Bottom"||i.cursorType==="ShowMore")t=i.value;continue}if(_.entryId?.startsWith("cursor-bottom-")||_.entryId?.startsWith("cursor-showMore-")){t=i?.value||i?.itemContent?.value||t;continue}if(_.entryId?.startsWith("user-")){const f=A(i?.itemContent?.user_results?.result);if(f)n.push(f)}}return{users:n,nextCursor:t}}function T(e){return Q(e)}F({site:"twitter",name:"following",access:"read",description:"Get accounts a Twitter/X user is following (defaults to the logged-in user when no user is given)",domain:"x.com",strategy:M.COOKIE,browser:!0,args:[{name:"user",positional:!0,type:"string",required:!1,help:"Twitter/X handle (with or without @). Omit to fetch the accounts the currently logged-in user follows."},{name:"limit",type:"int",default:50,help:"Maximum number of following rows to return (default 50). Must be a positive integer."}],columns:["screen_name","name","bio","followers"],func:async(e,n)=>{const t=n.limit===void 0||n.limit===null?50:Number(n.limit);if(!Number.isInteger(t)||t<=0)throw new v("twitter following --limit must be a positive integer","Example: ppcli twitter following @elonmusk --limit 200");const o=String(n.user??"").trim();let r=T(o);if(o&&!r)throw new v("twitter following user must be a valid Twitter/X handle","Example: ppcli twitter following @elonmusk --limit 200");const i=(await e.getCookies({url:"https://x.com"})).find((s)=>s.name==="ct0")?.value||null;if(!i)throw new w("x.com","Not logged into x.com (no ct0 cookie)");if(!r){await e.goto("https://x.com/home");await e.wait({selector:'[data-testid="primaryColumn"]'});const s=y(await e.evaluate(`() => {
|
|
2
2
|
const link = document.querySelector('a[data-testid="AppTabBar_Profile_Link"]');
|
|
3
3
|
return link ? link.getAttribute('href') : null;
|
|
4
|
-
}`));if(!
|
|
4
|
+
}`));if(!s||typeof s!=="string")throw new w("x.com","Could not detect logged-in user. Are you logged in?");r=T(s);if(!r)throw new w("x.com","Could not detect logged-in user. Are you logged in?")}if(!r)throw new v("twitter following user cannot be empty","Example: ppcli twitter following @elonmusk --limit 200");const f=await N(e,"Following",D),q=await N(e,"UserByScreenName",G),k={Authorization:`Bearer ${decodeURIComponent(z)}`,"X-Csrf-Token":i,"X-Twitter-Auth-Type":"OAuth2Session","X-Twitter-Active-User":"yes"},l=y(await e.evaluate(async(s,b)=>{const c=await fetch(s,{headers:b,credentials:"include"});if(!c.ok)return{error:c.status};return{userId:(await c.json()).data?.user?.result?.rest_id||null}},S(q,r),k));if(l?.error===401||l?.error===403)throw new w("x.com",`Twitter user lookup failed (HTTP ${l.error})`);if(l?.error)throw new m(`HTTP ${l.error}: Failed to resolve Twitter user @${r}`);const x=l?.userId||null;if(!x)throw new m(`Could not find user @${r}`);const u=[],E=new Set;let p=null,I=null;for(let s=0;s<J&&u.length<t;s++){const b=Math.min(50,t-u.length+10),c=U(f,x,b,p),a=y(await e.evaluate(async(d,B)=>{const h=await fetch(d,{headers:B,credentials:"include"});return h.ok?await h.json():{error:h.status}},c,k));if(a?.error){if(a.error===401||a.error===403)throw new w("x.com",`Twitter following request failed (HTTP ${a.error})`);throw new m(j("Following",a.error))}I=a;const{users:O,nextCursor:g}=R(a);for(const d of O)if(!E.has(d.screen_name)){E.add(d.screen_name);u.push(d)}if(!g||g===p)break;p=g}if(u.length===0){if(P(I))throw new C("twitter following",`No following data returned for @${r} (the target account may have set their following list to private)`);throw new C("twitter following",`No following accounts found for @${r}`)}return u.slice(0,t)}});export const __test__={sanitizeQueryId:X,buildFollowingUrl:U,buildUserByScreenNameUrl:S,extractUser:A,normalizeScreenName:T,parseFollowing:R};
|
package/clis/twitter/like.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{CommandExecutionError as
|
|
1
|
+
import{CommandExecutionError as s}from"@jackwener/opencli/errors";import{cli as a,Strategy as l}from"@jackwener/opencli/registry";import{parseTweetUrl as n,buildTwitterArticleScopeSource as o}from"./shared.js";a({site:"twitter",name:"like",access:"write",description:"Like a specific tweet",domain:"x.com",strategy:l.UI,browser:!0,args:[{name:"url",type:"string",required:!0,positional:!0,help:"The URL of the tweet to like"}],columns:["status","message"],func:async(e,r)=>{if(!e)throw new s("Browser session required for twitter like");const i=n(r.url);await e.goto(i.url);await e.wait({selector:'[data-testid="primaryColumn"]'});const t=await e.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
|
-
${
|
|
3
|
+
${o(i.id)}
|
|
4
4
|
// Poll for the tweet to render. We scope state probes to the
|
|
5
5
|
// article matching the requested status id — on conversation
|
|
6
6
|
// pages multiple articles render and a bare querySelector would
|
|
@@ -45,4 +45,4 @@ import{CommandExecutionError as F}from"@jackwener/opencli/errors";import{cli as
|
|
|
45
45
|
} catch (e) {
|
|
46
46
|
return { ok: false, message: e.toString() };
|
|
47
47
|
}
|
|
48
|
-
})()`);if(
|
|
48
|
+
})()`);if(t.ok)await e.wait(2);return[{status:t.ok?"success":"failed",message:t.message}]}});
|
package/clis/twitter/likes.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as U,Strategy as O}from"@jackwener/opencli/registry";import{ArgumentError as B,AuthRequiredError as f,CommandExecutionError as g,EmptyResultError as y}from"@jackwener/opencli/errors";import{looksLikePrivateTwitterTimeline as q,normalizeTwitterScreenName as v,resolveTwitterQueryId as k,sanitizeQueryId as L,extractMedia as J,unwrapBrowserResult as b,describeTwitterApiError as M}from"./shared.js";import{TWITTER_BEARER_TOKEN as Q,applyTopByEngagement as D}from"./utils.js";const j="CDWHmpZeSdIJ3HGeRbNm0w",z="IGgvgiOx4QZndDHuD3x9TQ",P=100,X={rweb_video_screen_enabled:!1,profile_label_improvements_pcf_label_in_post_enabled:!0,responsive_web_profile_redirect_enabled:!1,rweb_tipjar_consumption_enabled:!1,verified_phone_label_enabled:!1,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_timeline_navigation_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,premium_content_api_read_enabled:!1,communities_web_enable_tweet_community_results_fetch:!0,c9s_tweet_anatomy_moderator_badge_enabled:!0,responsive_web_grok_analyze_button_fetch_trends_enabled:!1,responsive_web_grok_analyze_post_followups_enabled:!0,responsive_web_jetfuel_frame:!0,responsive_web_grok_share_attachment_enabled:!0,responsive_web_grok_annotations_enabled:!0,articles_preview_enabled:!0,responsive_web_edit_tweet_api_enabled:!0,graphql_is_translatable_rweb_tweet_is_translatable_enabled:!0,view_counts_everywhere_api_enabled:!0,longform_notetweets_consumption_enabled:!0,responsive_web_twitter_article_tweet_consumption_enabled:!0,tweet_awards_web_tipping_enabled:!1,content_disclosure_indicator_enabled:!0,content_disclosure_ai_generated_indicator_enabled:!0,responsive_web_grok_show_grok_translated_post:!1,responsive_web_grok_analysis_button_from_backend:!0,post_ctas_fetch_enabled:!1,freedom_of_speech_not_reach_fetch_enabled:!0,standardized_nudges_misinfo:!0,tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled:!0,longform_notetweets_rich_text_read_enabled:!0,longform_notetweets_inline_media_enabled:!1,responsive_web_grok_image_annotation_enabled:!0,responsive_web_grok_imagine_annotation_enabled:!0,responsive_web_grok_community_note_auto_translation_is_enabled:!1,responsive_web_enhance_cards_enabled:!1};function T(t,i,e,n){const r={userId:i,count:e,includePromotedContent:!1,withClientEventToken:!1,withBirdwatchNotes:!1,withVoice:!0};if(n)r.cursor=n;return`/i/api/graphql/${t}/Likes?variables=${encodeURIComponent(JSON.stringify(r))}&features=${encodeURIComponent(JSON.stringify(X))}`}function x(t,i){const e=JSON.stringify({screen_name:i,withSafetyModeUserFields:!0}),n=JSON.stringify({hidden_profile_subscriptions_enabled:!0,rweb_tipjar_consumption_enabled:!0,responsive_web_graphql_exclude_directive_enabled:!0,verified_phone_label_enabled:!1,subscriptions_verification_info_is_identity_verified_enabled:!0,subscriptions_verification_info_verified_since_enabled:!0,highlights_tweets_tab_ui_enabled:!0,responsive_web_twitter_article_notes_tab_enabled:!0,subscriptions_feature_can_gift_premium:!0,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,responsive_web_graphql_timeline_navigation_enabled:!0});return`/i/api/graphql/${t}/UserByScreenName?variables=${encodeURIComponent(e)}&features=${encodeURIComponent(n)}`}function N(t,i){if(!t)return null;const e=t.tweet||t,n=e.legacy||{};if(!e.rest_id||i.has(e.rest_id))return null;i.add(e.rest_id);const r=e.core?.user_results?.result,l=r?.legacy?.screen_name||r?.core?.screen_name||"unknown",o=r?.legacy?.name||r?.core?.name||"",s=e.note_tweet?.note_tweet_results?.result?.text;return{id:e.rest_id,author:l,name:o,text:s||n.full_text||"",likes:n.favorite_count||0,retweets:n.retweet_count||0,created_at:n.created_at||"",url:`https://x.com/${l}/status/${e.rest_id}`,...J(n)}}function C(t,i){const e=[];let n=null;const r=t?.data?.user?.result?.timeline_v2?.timeline?.instructions||t?.data?.user?.result?.timeline?.timeline?.instructions||[];for(const l of r)for(const o of l.entries||[]){const s=o.content;if(s?.entryType==="TimelineTimelineCursor"||s?.__typename==="TimelineTimelineCursor"){if(s.cursorType==="Bottom"||s.cursorType==="ShowMore")n=s.value;continue}if(o.entryId?.startsWith("cursor-bottom-")||o.entryId?.startsWith("cursor-showMore-")){n=s?.value||s?.itemContent?.value||n;continue}const c=N(s?.itemContent?.tweet_results?.result,i);if(c){e.push(c);continue}for(const d of s?.items||[]){const u=N(d.item?.itemContent?.tweet_results?.result,i);if(u)e.push(u)}}return{tweets:e,nextCursor:n}}U({site:"twitter",name:"likes",access:"read",description:"Fetch liked tweets of a Twitter user (defaults to the logged-in user when no username is given)",domain:"x.com",strategy:O.COOKIE,browser:!0,args:[{name:"username",type:"string",positional:!0,help:"Twitter screen name (with or without @). Defaults to the logged-in user when omitted."},{name:"limit",type:"int",default:20,help:"Maximum number of liked tweets to return (default 20)."},{name:"top-by-engagement",type:"int",default:0,help:"When set to N>0, re-rank the liked tweets by weighted engagement (likes×1 + retweets×3 + replies×2 + bookmarks×5 + log10(views+1)×0.5) and return the top N. Default 0 keeps the API's native (recency) ordering."}],columns:["id","author","name","text","likes","retweets","created_at","url","has_media","media_urls","media_posters"],func:async(t,i)=>{const e=i.limit||20,n=String(i.username??"").trim();let r=v(n);if(n&&!r)throw new B("twitter likes username must be a valid Twitter/X handle","Example: ppcli twitter likes @jack --limit 20");const o=(await t.getCookies({url:"https://x.com"})).find((a)=>a.name==="ct0")?.value||null;if(!o)throw new f("x.com","Not logged into x.com (no ct0 cookie)");if(!r){await t.goto("https://x.com/home");await t.wait({selector:'[data-testid="primaryColumn"]'});const a=b(await t.evaluate(`() => {
|
|
2
2
|
const link = document.querySelector('a[data-testid="AppTabBar_Profile_Link"]');
|
|
3
3
|
return link ? link.getAttribute('href') : null;
|
|
4
|
-
}`));if(!
|
|
5
|
-
const screenName = ${JSON.stringify(
|
|
6
|
-
const url = ${JSON.stringify(
|
|
7
|
-
const resp = await fetch(url, { headers: ${
|
|
4
|
+
}`));if(!a||typeof a!=="string")throw new f("x.com","Could not detect logged-in user. Are you logged in?");r=v(a);if(!r)throw new f("x.com","Could not detect logged-in user. Are you logged in?")}const s=await k(t,"Likes",j),c=await k(t,"UserByScreenName",z),d=JSON.stringify({Authorization:`Bearer ${decodeURIComponent(Q)}`,"X-Csrf-Token":o,"X-Twitter-Auth-Type":"OAuth2Session","X-Twitter-Active-User":"yes"}),u=b(await t.evaluate(`async () => {
|
|
5
|
+
const screenName = ${JSON.stringify(r)};
|
|
6
|
+
const url = ${JSON.stringify(x(c,r))};
|
|
7
|
+
const resp = await fetch(url, { headers: ${d}, credentials: 'include' });
|
|
8
8
|
if (!resp.ok) return null;
|
|
9
9
|
const d = await resp.json();
|
|
10
10
|
return d.data?.user?.result?.rest_id || null;
|
|
11
|
-
}`));if(!
|
|
12
|
-
const r = await fetch("${
|
|
11
|
+
}`));if(!u)throw new g(`Could not find user @${r}`);const _=[],E=new Set;let w=null,h=null;for(let a=0;a<P&&_.length<e;a++){const I=Math.min(100,e-_.length+10),A=T(s,u,I,w),m=b(await t.evaluate(`async () => {
|
|
12
|
+
const r = await fetch("${A}", { headers: ${d}, credentials: 'include' });
|
|
13
13
|
return r.ok ? await r.json() : { error: r.status };
|
|
14
|
-
}`));if(
|
|
14
|
+
}`));if(m?.error){if(_.length===0)throw new g(M("Likes",m.error));break}h=m;const{tweets:R,nextCursor:p}=C(m,E);_.push(...R);if(!p||p===w)break;w=p}if(_.length===0){if(q(h))throw new y("twitter likes",`No likes returned for @${r} (Likes are private by default on X; only the account owner can view their own likes)`);throw new y("twitter likes",`No likes found for @${r}`)}const S=_.slice(0,e);return D(S,i["top-by-engagement"])}});export const __test__={sanitizeQueryId:L,buildLikesUrl:T,buildUserByScreenNameUrl:x,parseLikes:C};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
2
|
-
const resp = await fetch(${JSON.stringify(
|
|
1
|
+
import{ArgumentError as S,AuthRequiredError as x,CommandExecutionError as i}from"@jackwener/opencli/errors";import{resolveTwitterQueryId as p,unwrapBrowserResult as E}from"./shared.js";import{parseListsManagement as U}from"./lists.js";import{TWITTER_BEARER_TOKEN as k}from"./utils.js";const M="IGgvgiOx4QZndDHuD3x9TQ",J="78UbkyXwXBD98IgUWXOy9g",q="vWPi0CTMoPFsjsL6W4IynQ",R={rweb_video_screen_enabled:!1,profile_label_improvements_pcf_label_in_post_enabled:!0,rweb_tipjar_consumption_enabled:!0,verified_phone_label_enabled:!1,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_timeline_navigation_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,premium_content_api_read_enabled:!1,communities_web_enable_tweet_community_results_fetch:!0,c9s_tweet_anatomy_moderator_badge_enabled:!0,responsive_web_grok_analyze_button_fetch_trends_enabled:!1,responsive_web_grok_analyze_post_followups_enabled:!0,responsive_web_jetfuel_frame:!1,responsive_web_grok_share_attachment_enabled:!0,articles_preview_enabled:!0,responsive_web_edit_tweet_api_enabled:!0,graphql_is_translatable_rweb_tweet_is_translatable_enabled:!0,view_counts_everywhere_api_enabled:!0,longform_notetweets_consumption_enabled:!0,responsive_web_twitter_article_tweet_consumption_enabled:!0,tweet_awards_web_tipping_enabled:!1,responsive_web_grok_show_grok_translated_post:!1,responsive_web_grok_analysis_button_from_backend:!1,creator_subscriptions_quote_tweet_preview_enabled:!1,freedom_of_speech_not_reach_fetch_enabled:!0,standardized_nudges_misinfo:!0,tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled:!0,longform_notetweets_rich_text_read_enabled:!0,longform_notetweets_inline_media_enabled:!0,responsive_web_grok_image_annotation_enabled:!0,responsive_web_enhance_cards_enabled:!1};function L(e,n){const t=JSON.stringify({screen_name:n,withSafetyModeUserFields:!0}),r=JSON.stringify({hidden_profile_subscriptions_enabled:!0,rweb_tipjar_consumption_enabled:!0,responsive_web_graphql_exclude_directive_enabled:!0,verified_phone_label_enabled:!1,subscriptions_verification_info_is_identity_verified_enabled:!0,subscriptions_verification_info_verified_since_enabled:!0,highlights_tweets_tab_ui_enabled:!0,responsive_web_twitter_article_notes_tab_enabled:!0,subscriptions_feature_can_gift_premium:!0,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,responsive_web_graphql_timeline_navigation_enabled:!0});return`/i/api/graphql/${e}/UserByScreenName?variables=${encodeURIComponent(t)}&features=${encodeURIComponent(r)}`}function C(e){return(Array.isArray(e)?e:[]).filter((t)=>!(t?.path||[]).join(".").includes("default_banner_media_results")&&!/decode/i.test(t?.message||""))}export function buildListAddMemberRow({addResult:e,memberCountBefore:n,listId:t,username:r,userId:m}){if(!e?.httpOk)throw new i(`Failed to add @${r} to list ${t}: HTTP ${e?.status??0}${e?.fetchError?" ("+e.fetchError+")":""}${e?.raw?" — "+e.raw:""}`);const l=e.mc!==null&&e.mc!==void 0,u=C(e.errors);if(!l&&u.length){const h=u.map((b)=>b.message||JSON.stringify(b)).join("; ");throw new i(`Failed to add @${r} to list ${t}: ${h.slice(0,300)}`)}if(!l)throw new i(`Failed to add @${r} to list ${t}: no member_count in response`);const s=Number(e.mc);if(!Number.isFinite(s))throw new i(`Failed to add @${r} to list ${t}: invalid member_count in response`);if(s<n)throw new i(`Failed to add @${r} to list ${t}: member_count decreased unexpectedly (${n} → ${s})`);const d=!(s>n);if(d&&e.isMember!==!0)throw new i(`Failed to add @${r} to list ${t}: member_count unchanged and membership was not confirmed`);const c=`member_count ${n} → ${s}`;return{listId:t,username:r,userId:String(m),status:d?"noop":"success",message:d?`@${r} is already a member of list ${t}`:`Added @${r} to list ${t} (verified via ${c})`}}export async function listAddUser(e,n){const t=String(n.listId||"").trim(),r=String(n.username||"").replace(/^@/,"").trim();if(!t||!/^\d+$/.test(t))throw new S(`Invalid listId: ${JSON.stringify(n.listId)}. Expected numeric ID.`,"Example: ppcli twitter list-add 123456789 alice");if(!r)throw new S("twitter list-add username is required","Example: ppcli twitter list-add 123456789 alice");await e.goto("https://x.com");await e.wait(3);const l=(await e.getCookies({url:"https://x.com"})).find((w)=>w.name==="ct0")?.value||null;if(!l)throw new x("x.com","Not logged into x.com (no ct0 cookie)");const u=await p(e,"UserByScreenName",M),s=JSON.stringify({Authorization:`Bearer ${decodeURIComponent(k)}`,"X-Csrf-Token":l,"X-Twitter-Auth-Type":"OAuth2Session","X-Twitter-Active-User":"yes"}),f=L(u,r),d=await e.evaluate(`async () => {
|
|
2
|
+
const resp = await fetch(${JSON.stringify(f)}, { headers: ${s}, credentials: 'include' });
|
|
3
3
|
if (!resp.ok) return null;
|
|
4
4
|
const d = await resp.json();
|
|
5
5
|
return d.data?.user?.result?.rest_id || null;
|
|
6
|
-
}`),
|
|
7
|
-
const r = await fetch(${JSON.stringify(
|
|
6
|
+
}`),c=E(d);if(!c)throw new i(`Could not resolve user @${r}`);const b=`/i/api/graphql/${await p(e,"ListsManagementPageTimeline",J)}/ListsManagementPageTimeline?features=${encodeURIComponent(JSON.stringify(R))}`,_=await e.evaluate(`async () => {
|
|
7
|
+
const r = await fetch(${JSON.stringify(b)}, { headers: ${s}, credentials: 'include' });
|
|
8
8
|
if (!r.ok) return { __error: 'HTTP ' + r.status };
|
|
9
9
|
return await r.json();
|
|
10
|
-
}`),
|
|
10
|
+
}`),y=_&&!_.__error?U(_,new Set):[];if(_&&_.__error)throw new i(`Could not fetch lists: ${_.__error}`);const g=y.find((w)=>w.id===t);if(!g)throw new i(`List ${t} not found among your lists (${y.length} lists fetched).`);const N=Number(g.members)||0,v=await p(e,"ListAddMember",q),T=`/i/api/graphql/${v}/ListAddMember`,I=JSON.stringify({variables:{listId:t,userId:String(c)},queryId:v}),O=await e.evaluate(`async () => {
|
|
11
11
|
try {
|
|
12
|
-
const r = await fetch(${JSON.stringify(
|
|
12
|
+
const r = await fetch(${JSON.stringify(T)}, {
|
|
13
13
|
method: 'POST',
|
|
14
|
-
headers: Object.assign({}, ${
|
|
14
|
+
headers: Object.assign({}, ${s}, { 'Content-Type': 'application/json' }),
|
|
15
15
|
credentials: 'include',
|
|
16
|
-
body: ${JSON.stringify(
|
|
16
|
+
body: ${JSON.stringify(I)},
|
|
17
17
|
});
|
|
18
18
|
const text = await r.text();
|
|
19
19
|
let body;
|
|
@@ -32,4 +32,4 @@ import{ArgumentError as U,AuthRequiredError as w,CommandExecutionError as X}from
|
|
|
32
32
|
} catch (e) {
|
|
33
33
|
return JSON.stringify([false, 0, null, null, null, null, String(e)]);
|
|
34
34
|
}
|
|
35
|
-
}`),
|
|
35
|
+
}`),A=E(O);let o;try{o=JSON.parse(A)}catch{throw new i(`Failed to add @${r} to list ${t}: malformed mutation response envelope`)}const a=Object.create(null);a.httpOk=Boolean(o?.[0]);a.status=Number(o?.[1])||0;a.mc=o?.[2];a.isMember=o?.[3];a.errors=o?.[4];a.raw=o?.[5];a.fetchError=o?.[6];return[buildListAddMemberRow({addResult:a,memberCountBefore:N,listId:t,username:r,userId:c})]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import{cli as
|
|
2
|
-
const r = await fetch(${JSON.stringify(
|
|
1
|
+
import{cli as g,Strategy as _}from"@jackwener/opencli/registry";import{ArgumentError as c,AuthRequiredError as w,CommandExecutionError as o}from"@jackwener/opencli/errors";import{unwrapBrowserResult as S}from"./shared.js";import{TWITTER_BEARER_TOKEN as T}from"./utils.js";const x="UQRa0jJ9doxGEIQRea1Y0w",l=25,p=100,C={profile_label_improvements_pcf_label_in_post_enabled:!0,responsive_web_profile_redirect_enabled:!1,rweb_tipjar_consumption_enabled:!1,verified_phone_label_enabled:!1,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,responsive_web_graphql_timeline_navigation_enabled:!0};export function parseListCreateArgs(t){const i=String(t.name||"").trim(),r=String(t.description||"").trim(),e=String(t.mode||"public").trim().toLowerCase();if(!i)throw new c("List name is required",'Example: ppcli twitter list-create "My List"');if(i.length>l)throw new c(`List name too long: ${i.length} chars (max ${l})`);if(r.length>p)throw new c(`Description too long: ${r.length} chars (max ${p})`);if(e!=="public"&&e!=="private")throw new c(`Invalid mode: ${JSON.stringify(t.mode)}. Expected "public" or "private".`);return{listName:i,listDescription:r,listMode:e,privateFlag:e==="private"}}function L(t,i,r){if(!t||typeof t!=="object")throw new o(`Unexpected result from twitter list-create: ${JSON.stringify(t)}`);if(t.httpStatus===401||t.httpStatus===403)throw new w("x.com",`Twitter CreateList returned HTTP ${t.httpStatus}`);if(!t.ok){const n=String(t.bodyText||"").slice(0,300);throw new o(`HTTP ${t.httpStatus} from CreateList: ${n}`)}if(!t.bodyJson||typeof t.bodyJson!=="object")throw new o(`CreateList returned malformed JSON payload. Body: ${String(t.bodyText||"").slice(0,300)}`);const e=t.bodyJson?.data?.list;if(!e||typeof e!=="object"){const n=t.bodyJson?.errors;if(Array.isArray(n)&&n.length>0)throw new o(`CreateList failed: ${n[0].message||JSON.stringify(n[0])}`);throw new o(`CreateList returned no list payload. Body: ${String(t.bodyText||"").slice(0,300)}`)}const s=String(e.id_str||e.id||"");if(!/^\d+$/.test(s))throw new o("CreateList returned a list payload without a numeric list id.");if(typeof e.name!=="string"||!e.name.trim())throw new o("CreateList returned a list payload without a list name.");if(e.name.trim()!==i)throw new o(`CreateList returned name ${JSON.stringify(e.name)}, expected ${JSON.stringify(i)}.`);const a=typeof e.mode==="string"?e.mode:"";if(!a)throw new o("CreateList returned a list payload without list mode.");const d=/private/i.test(a)?"private":"public";if(d!==r)throw new o(`CreateList returned mode ${d}, expected ${r}.`);return{createdList:e,listId:s,listMode:d}}export function buildListCreateRow({result:t,name:i,description:r,mode:e}){const{createdList:s,listId:a,listMode:d}=L(t,i,e);return{id:a,name:s.name,description:typeof s.description==="string"?s.description:r,mode:d,status:"success"}}g({site:"twitter",name:"list-create",description:"Create a new Twitter/X list (returns the new list id)",access:"write",domain:"x.com",strategy:_.COOKIE,browser:!0,args:[{name:"name",positional:!0,type:"string",required:!0,help:`List name (max ${l} chars)`},{name:"description",type:"string",default:"",help:`Optional list description (max ${p} chars)`},{name:"mode",type:"string",default:"public",help:"public | private"}],columns:["id","name","description","mode","status"],func:async(t,i)=>{const{listName:r,listDescription:e,listMode:s,privateFlag:a}=parseListCreateArgs(i);await t.goto("https://x.com");await t.wait(3);const n=(await t.getCookies({url:"https://x.com"})).find((b)=>b.name==="ct0")?.value||null;if(!n)throw new w("x.com","Not logged into x.com (no ct0 cookie)");const m=x,f=JSON.stringify({Authorization:`Bearer ${decodeURIComponent(T)}`,"X-Csrf-Token":n,"X-Twitter-Auth-Type":"OAuth2Session","X-Twitter-Active-User":"yes","Content-Type":"application/json"}),u=JSON.stringify({variables:{isPrivate:a,name:r,description:e},features:C,queryId:m}),h=`/i/api/graphql/${m}/CreateList`,y=S(await t.evaluate(`async () => {
|
|
2
|
+
const r = await fetch(${JSON.stringify(h)}, {
|
|
3
3
|
method: 'POST',
|
|
4
|
-
headers: ${
|
|
4
|
+
headers: ${f},
|
|
5
5
|
credentials: 'include',
|
|
6
|
-
body: ${JSON.stringify(
|
|
6
|
+
body: ${JSON.stringify(u)},
|
|
7
7
|
});
|
|
8
8
|
const bodyText = await r.text();
|
|
9
9
|
let bodyJson = null;
|
|
10
10
|
try { bodyJson = JSON.parse(bodyText); } catch {}
|
|
11
11
|
return { ok: r.ok, httpStatus: r.status, bodyJson, bodyText };
|
|
12
|
-
}`));return[buildListCreateRow({result:
|
|
12
|
+
}`));return[buildListCreateRow({result:y,name:r,description:e,mode:s})]}});
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
2
|
-
const resp = await fetch(${JSON.stringify(
|
|
1
|
+
import{ArgumentError as v,AuthRequiredError as T,CommandExecutionError as o}from"@jackwener/opencli/errors";import{resolveTwitterQueryId as g,unwrapBrowserResult as d}from"./shared.js";import{getListsManagementInstructions as R,parseListsManagement as y}from"./lists.js";import{TWITTER_BEARER_TOKEN as I}from"./utils.js";const A="IGgvgiOx4QZndDHuD3x9TQ",M="78UbkyXwXBD98IgUWXOy9g",E={rweb_video_screen_enabled:!1,profile_label_improvements_pcf_label_in_post_enabled:!0,rweb_tipjar_consumption_enabled:!0,verified_phone_label_enabled:!1,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_timeline_navigation_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,premium_content_api_read_enabled:!1,communities_web_enable_tweet_community_results_fetch:!0,c9s_tweet_anatomy_moderator_badge_enabled:!0,responsive_web_grok_analyze_button_fetch_trends_enabled:!1,responsive_web_grok_analyze_post_followups_enabled:!0,responsive_web_jetfuel_frame:!1,responsive_web_grok_share_attachment_enabled:!0,articles_preview_enabled:!0,responsive_web_edit_tweet_api_enabled:!0,graphql_is_translatable_rweb_tweet_is_translatable_enabled:!0,view_counts_everywhere_api_enabled:!0,longform_notetweets_consumption_enabled:!0,responsive_web_twitter_article_tweet_consumption_enabled:!0,tweet_awards_web_tipping_enabled:!1,responsive_web_grok_show_grok_translated_post:!1,responsive_web_grok_analysis_button_from_backend:!1,creator_subscriptions_quote_tweet_preview_enabled:!1,freedom_of_speech_not_reach_fetch_enabled:!0,standardized_nudges_misinfo:!0,tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled:!0,longform_notetweets_rich_text_read_enabled:!0,longform_notetweets_inline_media_enabled:!0,responsive_web_grok_image_annotation_enabled:!0,responsive_web_enhance_cards_enabled:!1};function x(e,r){const t=JSON.stringify({screen_name:r,withSafetyModeUserFields:!0}),i=JSON.stringify({hidden_profile_subscriptions_enabled:!0,rweb_tipjar_consumption_enabled:!0,responsive_web_graphql_exclude_directive_enabled:!0,verified_phone_label_enabled:!1,subscriptions_verification_info_is_identity_verified_enabled:!0,subscriptions_verification_info_verified_since_enabled:!0,highlights_tweets_tab_ui_enabled:!0,responsive_web_twitter_article_notes_tab_enabled:!0,subscriptions_feature_can_gift_premium:!0,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,responsive_web_graphql_timeline_navigation_enabled:!0});return`/i/api/graphql/${e}/UserByScreenName?variables=${encodeURIComponent(t)}&features=${encodeURIComponent(i)}`}export function interpretRemoveResponse(e,r){if(e===200&&r&&(r.id_str||r.id||r.slug))return{ok:!0};if(r&&Array.isArray(r.errors)&&r.errors.length>0){const t=r.errors[0];return{ok:!1,error:`${t.code?"["+t.code+"] ":""}${t.message||"Unknown error"}`}}return{ok:!1,error:`HTTP ${e}`}}export async function listRemoveUser(e,r){const t=String(r.listId||"").trim(),i=String(r.username||"").replace(/^@/,"").trim();if(!t||!/^\d+$/.test(t))throw new v(`Invalid listId: ${JSON.stringify(r.listId)}. Expected numeric ID.`);if(!i)throw new v("twitter list-remove username is required");await e.goto("https://x.com");await e.wait(3);const w=(await e.getCookies({url:"https://x.com"})).find((n)=>n.name==="ct0")?.value||null;if(!w)throw new T("x.com","Not logged into x.com (no ct0 cookie)");const k=await g(e,"UserByScreenName",A),_=JSON.stringify({Authorization:`Bearer ${decodeURIComponent(I)}`,"X-Csrf-Token":w,"X-Twitter-Auth-Type":"OAuth2Session","X-Twitter-Active-User":"yes"}),C=x(k,i),f=d(await e.evaluate(`async () => {
|
|
2
|
+
const resp = await fetch(${JSON.stringify(C)}, { headers: ${_}, credentials: 'include' });
|
|
3
3
|
if (!resp.ok) return null;
|
|
4
4
|
const d = await resp.json();
|
|
5
5
|
return d.data?.user?.result?.rest_id || null;
|
|
6
|
-
}`));if(!
|
|
7
|
-
const r = await fetch(${JSON.stringify(
|
|
6
|
+
}`));if(!f)throw new o(`Could not resolve user @${i}`);const p=`/i/api/graphql/${await g(e,"ListsManagementPageTimeline",M)}/ListsManagementPageTimeline?features=${encodeURIComponent(JSON.stringify(E))}`,c=d(await e.evaluate(`async () => {
|
|
7
|
+
const r = await fetch(${JSON.stringify(p)}, { headers: ${_}, credentials: 'include' });
|
|
8
8
|
if (!r.ok) return { __error: 'HTTP ' + r.status };
|
|
9
9
|
return await r.json();
|
|
10
|
-
}`));if(
|
|
10
|
+
}`));if(c&&c.__error)throw new o(`Could not fetch lists: ${c.__error}`);const u=y(c,new Set).find((n)=>n.id===t);if(!u)throw new o(`List ${t} not found among your lists.`);const S=u.name;await e.goto(`https://x.com/${i}`);await e.wait({selector:'[data-testid="primaryColumn"]'});const s=d(await e.evaluate(`(async () => {
|
|
11
11
|
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
12
12
|
const findOne = (sel, root = document) => root.querySelector(sel);
|
|
13
13
|
const waitFor = async (fn, { timeoutMs = 8000, intervalMs = 200 } = {}) => {
|
|
@@ -49,7 +49,7 @@ import{ArgumentError as h,AuthRequiredError as x,CommandExecutionError as X}from
|
|
|
49
49
|
const dialog = await waitFor(() => findOne('[role="dialog"]'));
|
|
50
50
|
if (!dialog) return { ok: false, message: 'List selection dialog did not open' };
|
|
51
51
|
|
|
52
|
-
const targetName = ${JSON.stringify(
|
|
52
|
+
const targetName = ${JSON.stringify(S)};
|
|
53
53
|
const scrollCandidates = [
|
|
54
54
|
dialog.querySelector('[data-viewportview="true"]'),
|
|
55
55
|
...Array.from(dialog.querySelectorAll('div')).filter(d => d.scrollHeight > d.clientHeight + 10),
|
|
@@ -120,8 +120,8 @@ import{ArgumentError as h,AuthRequiredError as x,CommandExecutionError as X}from
|
|
|
120
120
|
} catch (e) {
|
|
121
121
|
return { ok: false, message: 'UI error: ' + (e?.message || String(e)) };
|
|
122
122
|
}
|
|
123
|
-
})()`));if(!
|
|
124
|
-
const r = await fetch(${JSON.stringify(
|
|
123
|
+
})()`));if(!s.ok)throw new o(`Failed to remove @${i} from list ${t}: ${s.message}`);let b=null;if(s.needsNativeInteraction){if(typeof e.nativeClick!=="function")throw new o("Requires up-to-date Chrome extension (nativeClick).");if(!s.saveClickX)throw new o("Save button not found in dialog.");const n=Number(u.members)||0;await e.nativeClick(s.rowClickX,s.rowClickY);await new Promise((l)=>setTimeout(l,800));await e.nativeClick(s.saveClickX,s.saveClickY);await new Promise((l)=>setTimeout(l,3500));const a=d(await e.evaluate(`async () => {
|
|
124
|
+
const r = await fetch(${JSON.stringify(p)}, { headers: ${_}, credentials: 'include' });
|
|
125
125
|
if (!r.ok) return { __error: 'HTTP ' + r.status };
|
|
126
126
|
return await r.json();
|
|
127
|
-
}`));if(
|
|
127
|
+
}`));if(a&&a.__error)throw new o(`Could not verify list removal: ${a.__error}`);if(!R(a))throw new o("Could not verify list removal: unexpected lists payload shape");const h=y(a,new Set).find((l)=>l.id===t);if(!h)throw new o(`Could not verify list removal: list ${t} missing from post-delete payload`);const m=Number(h.members)||0;if(m<n)b=`member_count ${n} → ${m}`;else throw new o(`Failed to remove @${i} from list ${t}: member_count unchanged (${n} → ${m}).`)}return[{listId:t,username:i,userId:String(f),status:s.noop?"noop":"success",message:s.noop?`@${i} was not a member of list ${t}`:`Removed @${i} from list ${t} (verified via ${b})`}]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as v,Strategy as I}from"@jackwener/opencli/registry";import{AuthRequiredError as x,CommandExecutionError as h}from"@jackwener/opencli/errors";import{BROWSER_JSON_SNIFF_FN as k,throwIfLoginWall as E}from"@jackwener/opencli/utils";import{TWITTER_BEARER_TOKEN as N,applyTopByEngagement as S}from"./utils.js";import{extractCard as R,extractQuotedTweet as A,extractMedia as C,describeTwitterApiError as q}from"./shared.js";const O="RlZzktZY_9wJynoepm8ZsA",w="ListLatestTweetsTimeline",U=100,W={rweb_video_screen_enabled:!1,profile_label_improvements_pcf_label_in_post_enabled:!0,rweb_tipjar_consumption_enabled:!0,verified_phone_label_enabled:!1,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_timeline_navigation_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,premium_content_api_read_enabled:!1,communities_web_enable_tweet_community_results_fetch:!0,c9s_tweet_anatomy_moderator_badge_enabled:!0,responsive_web_grok_analyze_button_fetch_trends_enabled:!1,responsive_web_grok_analyze_post_followups_enabled:!0,responsive_web_jetfuel_frame:!1,responsive_web_grok_share_attachment_enabled:!0,articles_preview_enabled:!0,responsive_web_edit_tweet_api_enabled:!0,graphql_is_translatable_rweb_tweet_is_translatable_enabled:!0,view_counts_everywhere_api_enabled:!0,longform_notetweets_consumption_enabled:!0,responsive_web_twitter_article_tweet_consumption_enabled:!0,tweet_awards_web_tipping_enabled:!1,responsive_web_grok_show_grok_translated_post:!1,responsive_web_grok_analysis_button_from_backend:!1,creator_subscriptions_quote_tweet_preview_enabled:!1,freedom_of_speech_not_reach_fetch_enabled:!0,standardized_nudges_misinfo:!0,tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled:!0,longform_notetweets_rich_text_read_enabled:!0,longform_notetweets_inline_media_enabled:!0,responsive_web_grok_image_annotation_enabled:!0,responsive_web_enhance_cards_enabled:!1};function J(s,n,e,t){const i={listId:String(n),count:e};if(t)i.cursor=t;return`/i/api/graphql/${s}/${w}?variables=${encodeURIComponent(JSON.stringify(i))}&features=${encodeURIComponent(JSON.stringify(W))}`}export function extractTimelineTweet(s,n){if(!s)return null;const e=s.tweet||s,t=e.legacy||{};if(!e.rest_id||n.has(e.rest_id))return null;n.add(e.rest_id);const i=e.core?.user_results?.result,_=i?.legacy?.screen_name||i?.core?.screen_name||"unknown",l=i?.legacy?.name||i?.core?.name||"",r=i?.legacy?.description||"",c=e.note_tweet?.note_tweet_results?.result?.text;return{id:e.rest_id,author:_,name:l,bio:r,text:c||t.full_text||"",likes:t.favorite_count||0,retweets:t.retweet_count||0,replies:t.reply_count||0,created_at:t.created_at||"",url:`https://x.com/${_}/status/${e.rest_id}`,...C(t),card:R(e),quoted_tweet:A(e)}}export function parseListTimeline(s,n){const e=[];let t=null;const i=s?.data?.list?.tweets_timeline?.timeline?.instructions||[];for(const _ of i)for(const l of _.entries||[]){const r=l.content;if(r?.entryType==="TimelineTimelineCursor"||r?.__typename==="TimelineTimelineCursor"){if(r.cursorType==="Bottom"||r.cursorType==="ShowMore")t=r.value;continue}if(l.entryId?.startsWith("cursor-bottom-")||l.entryId?.startsWith("cursor-showMore-")){t=r?.value||r?.itemContent?.value||t;continue}const c=extractTimelineTweet(r?.itemContent?.tweet_results?.result,n);if(c){e.push(c);continue}for(const u of r?.items||[]){const a=extractTimelineTweet(u.item?.itemContent?.tweet_results?.result,n);if(a)e.push(a)}}return{tweets:e,nextCursor:t}}v({site:"twitter",name:"list-tweets",access:"read",description:"Fetch tweets from a Twitter/X list timeline",domain:"x.com",strategy:I.COOKIE,browser:!0,args:[{name:"listId",positional:!0,type:"string",required:!0,help:"Numeric ID of a Twitter/X list (e.g. from `ppcli twitter lists`)"},{name:"limit",type:"int",default:50},{name:"top-by-engagement",type:"int",default:0,help:"When set to N>0, re-rank the list timeline by weighted engagement (likes×1 + retweets×3 + replies×2 + bookmarks×5 + log10(views+1)×0.5) and return the top N. Default 0 keeps the list's native (recency) ordering."}],columns:["id","author","bio","text","likes","retweets","replies","created_at","url","has_media","media_urls","media_posters","card","quoted_tweet"],func:async(s,n)=>{const e=String(n.listId||"").trim();if(!e||!/^\d+$/.test(e))throw new h(`Invalid listId: ${JSON.stringify(n.listId)}. Expected a numeric ID (see \`ppcli twitter lists\`).`);const t=n.limit||50,_=(await s.getCookies({url:"https://x.com"})).find((o)=>o.name==="ct0")?.value||null;if(!_)throw new x("x.com","Not logged into x.com (no ct0 cookie)");const l=(o)=>o&&typeof o==="object"&&("session"in o)&&("data"in o)?o.data:o,r=await s.evaluate(`async () => {
|
|
2
2
|
try {
|
|
3
3
|
const ghResp = await fetch('https://raw.githubusercontent.com/fa0311/twitter-openapi/refs/heads/main/src/config/placeholder.json');
|
|
4
4
|
if (ghResp.ok) {
|
|
5
5
|
const data = await ghResp.json();
|
|
6
|
-
const entry = data['${
|
|
6
|
+
const entry = data['${w}'];
|
|
7
7
|
if (entry && entry.queryId) return entry.queryId;
|
|
8
8
|
}
|
|
9
9
|
} catch {}
|
|
@@ -14,14 +14,14 @@ import{cli as U,Strategy as h}from"@jackwener/opencli/registry";import{AuthRequi
|
|
|
14
14
|
for (const scriptUrl of scripts.slice(0, 15)) {
|
|
15
15
|
try {
|
|
16
16
|
const text = await (await fetch(scriptUrl)).text();
|
|
17
|
-
const re = /queryId:"([A-Za-z0-9_-]+)"[^}]{0,200}operationName:"${
|
|
17
|
+
const re = /queryId:"([A-Za-z0-9_-]+)"[^}]{0,200}operationName:"${w}"/;
|
|
18
18
|
const m = text.match(re);
|
|
19
19
|
if (m) return m[1];
|
|
20
20
|
} catch {}
|
|
21
21
|
}
|
|
22
22
|
} catch {}
|
|
23
23
|
return null;
|
|
24
|
-
}`),
|
|
25
|
-
${
|
|
26
|
-
return await fetchJsonOrLoginWall(${JSON.stringify(
|
|
27
|
-
}`),{url:
|
|
24
|
+
}`),c=l(r)||O,u=JSON.stringify({Authorization:`Bearer ${decodeURIComponent(N)}`,"X-Csrf-Token":_,"X-Twitter-Auth-Type":"OAuth2Session","X-Twitter-Active-User":"yes"}),a=[],y=new Set;let d=null;for(let o=0;o<U&&a.length<t;o++){const T=Math.min(100,t-a.length+10),f=J(c,e,T,d),m=E(await s.evaluate(`async () => {
|
|
25
|
+
${k}
|
|
26
|
+
return await fetchJsonOrLoginWall(${JSON.stringify(f)}, { headers: ${u}, credentials: 'include' });
|
|
27
|
+
}`),{url:f});if(m?.error){if(a.length===0)throw new h(q("ListLatestTweetsTimeline",m.error,"list may be private"));break}const{tweets:b,nextCursor:p}=parseListTimeline(m,y);a.push(...b);if(!p||p===d||b.length===0)break;d=p}const g=a.slice(0,t);return S(g,n["top-by-engagement"])}});
|
package/clis/twitter/lists.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as w,Strategy as b}from"@jackwener/opencli/registry";import{AuthRequiredError as g,CommandExecutionError as d,EmptyResultError as h}from"@jackwener/opencli/errors";import{TWITTER_BEARER_TOKEN as y}from"./utils.js";import{describeTwitterApiError as v}from"./shared.js";const E="78UbkyXwXBD98IgUWXOy9g",u="ListsManagementPageTimeline",x={rweb_video_screen_enabled:!1,profile_label_improvements_pcf_label_in_post_enabled:!0,rweb_tipjar_consumption_enabled:!0,verified_phone_label_enabled:!1,creator_subscriptions_tweet_preview_api_enabled:!0,responsive_web_graphql_timeline_navigation_enabled:!0,responsive_web_graphql_skip_user_profile_image_extensions_enabled:!1,premium_content_api_read_enabled:!1,communities_web_enable_tweet_community_results_fetch:!0,c9s_tweet_anatomy_moderator_badge_enabled:!0,responsive_web_grok_analyze_button_fetch_trends_enabled:!1,responsive_web_grok_analyze_post_followups_enabled:!0,responsive_web_jetfuel_frame:!1,responsive_web_grok_share_attachment_enabled:!0,articles_preview_enabled:!0,responsive_web_edit_tweet_api_enabled:!0,graphql_is_translatable_rweb_tweet_is_translatable_enabled:!0,view_counts_everywhere_api_enabled:!0,longform_notetweets_consumption_enabled:!0,responsive_web_twitter_article_tweet_consumption_enabled:!0,tweet_awards_web_tipping_enabled:!1,responsive_web_grok_show_grok_translated_post:!1,responsive_web_grok_analysis_button_from_backend:!1,creator_subscriptions_quote_tweet_preview_enabled:!1,freedom_of_speech_not_reach_fetch_enabled:!0,standardized_nudges_misinfo:!0,tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled:!0,longform_notetweets_rich_text_read_enabled:!0,longform_notetweets_inline_media_enabled:!0,responsive_web_grok_image_annotation_enabled:!0,responsive_web_enhance_cards_enabled:!1};function I(e){return`/i/api/graphql/${e}/${u}?features=${encodeURIComponent(JSON.stringify(x))}`}export function extractListEntry(e,n){const t=e?.content?.itemContent?.list||e?.content?.list||e?.item?.itemContent?.list;if(!t)return null;const i=t.id_str||t.id||"";if(!i||n.has(i))return null;n.add(i);const s=typeof t.mode==="string"&&/private/i.test(t.mode)?"private":"public";return{id:String(i),name:t.name||"",members:String(t.member_count??0),followers:String(t.subscriber_count??0),mode:s}}const T="owned-subscribed-list-module-";export function isOwnedSubscribedEntry(e){return typeof e?.entryId==="string"&&e.entryId.startsWith(T)}export function getListsManagementInstructions(e){const n=e?.data?.viewer?.list_management_timeline?.timeline?.instructions||e?.data?.viewer_v2?.user_results?.result?.list_management_timeline?.timeline?.instructions||e?.data?.list_management_timeline?.timeline?.instructions||e?.data?.data?.viewer?.list_management_timeline?.timeline?.instructions||e?.data?.data?.viewer_v2?.user_results?.result?.list_management_timeline?.timeline?.instructions||e?.data?.data?.list_management_timeline?.timeline?.instructions;return Array.isArray(n)?n:null}export function parseListsManagement(e,n){const t=[],i=getListsManagementInstructions(e)||[];for(const s of i)for(const o of s.entries||[]){if(!isOwnedSubscribedEntry(o))continue;const a=extractListEntry(o,n);if(a){t.push(a);continue}for(const c of o?.content?.items||[]){const _=extractListEntry(c,n);if(_)t.push(_)}}return t}export const command=w({site:"twitter",name:"lists",access:"read",description:"Get Twitter/X lists for the logged-in user (owned + subscribed)",domain:"x.com",strategy:b.COOKIE,browser:!0,args:[{name:"limit",type:"int",default:50,help:"Maximum number of lists to return (default 50)."}],columns:["id","name","members","followers","mode"],func:async(e,n)=>{const t=n.limit||50,s=(await e.getCookies({url:"https://x.com"})).find((r)=>r.name==="ct0")?.value||null;if(!s)throw new g("x.com","Not logged into x.com (no ct0 cookie)");const o=(r)=>r&&typeof r==="object"&&("session"in r)&&("data"in r)?r.data:r,a=await e.evaluate(`async () => {
|
|
2
2
|
try {
|
|
3
3
|
const ghResp = await fetch('https://raw.githubusercontent.com/fa0311/twitter-openapi/refs/heads/main/src/config/placeholder.json');
|
|
4
4
|
if (ghResp.ok) {
|
|
5
5
|
const data = await ghResp.json();
|
|
6
|
-
const entry = data['${
|
|
6
|
+
const entry = data['${u}'];
|
|
7
7
|
if (entry && entry.queryId) return entry.queryId;
|
|
8
8
|
}
|
|
9
9
|
} catch {}
|
|
@@ -14,14 +14,14 @@ import{cli as C,Strategy as D}from"@jackwener/opencli/registry";import{AuthRequi
|
|
|
14
14
|
for (const scriptUrl of scripts.slice(0, 15)) {
|
|
15
15
|
try {
|
|
16
16
|
const text = await (await fetch(scriptUrl)).text();
|
|
17
|
-
const re = /queryId:"([A-Za-z0-9_-]+)"[^}]{0,200}operationName:"${
|
|
17
|
+
const re = /queryId:"([A-Za-z0-9_-]+)"[^}]{0,200}operationName:"${u}"/;
|
|
18
18
|
const m = text.match(re);
|
|
19
19
|
if (m) return m[1];
|
|
20
20
|
} catch {}
|
|
21
21
|
}
|
|
22
22
|
} catch {}
|
|
23
23
|
return null;
|
|
24
|
-
}`),
|
|
25
|
-
const r = await fetch(${JSON.stringify(
|
|
24
|
+
}`),c=o(a)||E,_=JSON.stringify({Authorization:`Bearer ${decodeURIComponent(y)}`,"X-Csrf-Token":s,"X-Twitter-Auth-Type":"OAuth2Session","X-Twitter-Active-User":"yes"}),p=I(c),l=await e.evaluate(`async () => {
|
|
25
|
+
const r = await fetch(${JSON.stringify(p)}, { headers: ${_}, credentials: 'include' });
|
|
26
26
|
return r.ok ? await r.json() : { error: r.status };
|
|
27
|
-
}`);if(
|
|
27
|
+
}`);if(l?.error)throw new d(v("ListsManagementPageTimeline",l.error));const f=new Set;if(!getListsManagementInstructions(l))throw new d("Twitter lists returned an unexpected payload shape");const m=parseListsManagement(l,f);if(m.length===0)throw new h("twitter lists","No owned or subscribed lists found");return m.slice(0,t)}});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{CommandExecutionError as
|
|
1
|
+
import{CommandExecutionError as g}from"@jackwener/opencli/errors";import{cli as v,Strategy as T}from"@jackwener/opencli/registry";v({site:"twitter",name:"notifications",access:"read",description:"Get your Twitter/X notifications (the logged-in user's likes/replies/follows feed, newest first)",domain:"x.com",strategy:T.INTERCEPT,browser:!0,args:[{name:"limit",type:"int",default:20,help:"Maximum number of notifications to return (default 20)."}],columns:["id","action","author","text","url"],func:async(s,x)=>{await s.goto("https://x.com/home");await s.wait(3);await s.installInterceptor("NotificationsTimeline");await s.evaluate(`() => {
|
|
2
2
|
window.history.pushState({}, '', '/notifications');
|
|
3
3
|
window.dispatchEvent(new PopStateEvent('popstate', { state: {} }));
|
|
4
|
-
}`);await
|
|
4
|
+
}`);await s.waitForCapture(5);if(await s.evaluate("() => window.location.pathname")!=="/notifications")throw new g("SPA navigation to notifications failed. Twitter may have changed its routing.");await s.autoScroll({times:2,delayMs:2000});const _=await s.getInterceptedRequests();if(!_||_.length===0)return[];let y=[];const h=new Set;for(const r of _)try{let p=function(e,u){if(!e)return;let t=e?.notification_results?.result||e?.tweet_results?.result||e,m="Notification",f="",a="",l="";if(t.__typename==="TimelineNotification"){a=t.rich_message?.text||t.message?.text||"";const i=t.template?.from_users?.[0]?.user_results?.result;f=i?.core?.screen_name||i?.legacy?.screen_name||"";l=t.notification_url?.url||"";m=t.notification_icon||"Activity";const n=t.template?.target_objects?.[0]?.tweet_results?.result;if(n){const d=n.note_tweet?.note_tweet_results?.result?.text||n.legacy?.full_text||"";a+=a&&d?" | "+d:d;if(!l)l=`https://x.com/i/status/${n.rest_id}`}}else if(t.__typename==="TweetNotification"){const i=t.tweet_result?.result,n=i?.core?.user_results?.result;f=n?.core?.screen_name||n?.legacy?.screen_name||"";a=i?.note_tweet?.note_tweet_results?.result?.text||i?.legacy?.full_text||t.message?.text||"";m="Mention/Reply";l=`https://x.com/i/status/${i?.rest_id}`}else if(t.__typename==="Tweet"){const i=t.core?.user_results?.result;f=i?.core?.screen_name||i?.legacy?.screen_name||"";a=t.note_tweet?.note_tweet_results?.result?.text||t.legacy?.full_text||"";m="Mention";l=`https://x.com/i/status/${t.rest_id}`}const w=t.id||t.rest_id||u;if(h.has(w))return;h.add(w);y.push({id:w,action:m,author:f,text:a,url:l||"https://x.com/notifications"})},o=[];if(r.data?.viewer?.timeline_response?.timeline?.instructions)o=r.data.viewer.timeline_response.timeline.instructions;else if(r.data?.viewer_v2?.user_results?.result?.notification_timeline?.timeline?.instructions)o=r.data.viewer_v2.user_results.result.notification_timeline.timeline.instructions;else if(r.data?.timeline?.instructions)o=r.data.timeline.instructions;let c=o.find((e)=>e.type==="TimelineAddEntries");if(!c)c=o.find((e)=>e.entries&&Array.isArray(e.entries));if(!c)continue;for(const e of c.entries){if(!e.entryId.startsWith("notification-")){if(e.content?.items)for(const u of e.content.items)p(u.item?.itemContent,u.entryId);continue}p(e.content?.itemContent,e.entryId)}}catch(o){}return y.slice(0,x.limit)}});
|