publishport-opencli 1.0.19 → 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/cli-manifest.json +35 -0
- 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 +16 -16
- 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
package/clis/qwen/ask.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as E,Strategy as N}from"@jackwener/opencli/registry";import{ArgumentError as u,CommandExecutionError as m,TimeoutError as k}from"@jackwener/opencli/errors";import{QIANWEN_DOMAIN as x,QIANWEN_URL as S,authRequired as w,bubbleHtmlToMarkdown as Q,dismissLoginModal as h,ensureOnQianwen as R,getMessageBubbles as T,hasLoginGate as g,normalizeBooleanFlag as r,sendMessage as F,setFeatureToggle as f,startNewChat as I,waitForAnswer as M}from"./utils.js";E({site:"qwen",name:"ask",access:"write",description:"Send a prompt to Qianwen and return the assistant reply",domain:x,strategy:N.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,defaultFormat:"plain",args:[{name:"prompt",fromFile:!0,required:!0,positional:!0,help:"Prompt to send to Qianwen"},{name:"timeout",type:"int",default:120,help:"Max seconds to wait for the response"},{name:"new",type:"boolean",default:!1,help:"Start a new chat before sending"},{name:"think",type:"boolean",default:!1,help:"Enable 深度思考 (DeepThink)"},{name:"research",type:"boolean",default:!1,help:"Enable 深度研究 (DeepResearch)"},{name:"markdown",type:"boolean",default:!1,help:"Emit assistant reply as markdown"}],columns:["Role","Text"],func:async(t,e)=>{const a=String(e.prompt||"").trim();if(!a)throw new u("prompt is required");const n=Number(e.timeout??120);if(!Number.isInteger(n)||n<=0)throw new u("timeout must be a positive integer");const s=r(e.new,!1),c=r(e.think,!1),p=r(e.research,!1),b=r(e.markdown,!1);await R(t);await h(t);if(s){await I(t);await h(t)}if(c)await f(t,"think",!0);if(p)await f(t,"research",!0);const y=await d(t),l=await F(t,a);if(!l?.ok){if(await g(t))throw w();throw new m(l?.reason||"Failed to send Qianwen prompt")}const i=await M(t,a,n,y);if(i.status==="auth_required")throw w();if(i.status==="timeout")throw new k("qianwen ask",n,"No Qianwen reply observed before timeout. Retry with --timeout increased.");const o=i.assistant;if(!o)throw new m("No assistant reply found in Qianwen chat.");const A=b&&o.html?Q(o.html)||o.text:o.text;return[{Role:"User",Text:a},{Role:"Assistant",Text:A}]}});async function d(t){const e=await T(t),a=e.length?e[e.length-1].id:"";let n="";for(let s=e.length-1;s>=0;s-=1)if(e[s].role==="Assistant"){n=e[s].id;break}return{lastBubbleId:a,lastAssistantId:n}}export const __test__={getBaselineChatAnchor:d};
|
package/clis/qwen/auth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as n,CommandExecutionError as a}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as w}from"../_shared/site-auth.js";async function o(e){return(await e.getCookies({url:"https://chat.qwen.ai"})).some((i)=>i.name==="token"&&i.value)}async function r(e){const i=(await e.getCookies({url:"https://chat.qwen.ai"})).find((u)=>u.name==="token")?.value||"";if(!i)throw new n("qwen.ai","Qwen token cookie missing");await e.goto("https://chat.qwen.ai/");await e.wait(2);const t=await e.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
|
-
const token = ${JSON.stringify(
|
|
3
|
+
const token = ${JSON.stringify(i)};
|
|
4
4
|
const res = await fetch('/api/v1/auths/', { credentials: 'include', headers: { 'Authorization': 'Bearer ' + token, 'Accept': 'application/json' } });
|
|
5
5
|
if (res.status === 401 || res.status === 403) {
|
|
6
6
|
return { kind: 'auth', detail: 'Qwen /api/v1/auths/ HTTP ' + res.status };
|
|
@@ -14,4 +14,4 @@ import{AuthRequiredError as D,CommandExecutionError as F}from"@jackwener/opencli
|
|
|
14
14
|
} catch (e) {
|
|
15
15
|
return { kind: 'exception', detail: String(e && e.message || e) };
|
|
16
16
|
}
|
|
17
|
-
})()`);if(
|
|
17
|
+
})()`);if(t?.kind==="auth")throw new n("qwen.ai",t.detail);if(t?.kind==="http")throw new a(`HTTP ${t.httpStatus} from /api/v1/auths/`);if(t?.kind==="exception")throw new a(`Qwen whoami failed: ${t.detail}`);if(!t?.ok)throw new a(`Unexpected Qwen probe: ${JSON.stringify(t)}`);return{user_id:t.user_id,name:t.name}}w({site:"qwen",domain:"qwen.ai",loginUrl:"https://chat.qwen.ai/auth?action=login",columns:["user_id","name"],quickCheck:o,verify:r,poll:async(e)=>{if(!await o(e))throw new n("qwen.ai","Waiting for Qwen token cookie");return r(e)}});
|
package/clis/qwen/detail.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as w,Strategy as d}from"@jackwener/opencli/registry";import{EmptyResultError as c}from"@jackwener/opencli/errors";import{QIANWEN_DOMAIN as m,bubbleHtmlToMarkdown as h,dismissLoginModal as u,getMessageBubbles as f,normalizeBooleanFlag as p,parseQianwenSessionId as g}from"./utils.js";w({site:"qwen",name:"detail",access:"read",description:"Open a Qianwen conversation by ID and read its messages",domain:m,strategy:d.COOKIE,browser:!0,navigateBefore:!1,siteSession:"persistent",args:[{name:"id",positional:!0,required:!0,help:"Session ID (32-char hex) or full https://www.qianwen.com/chat/<id> URL"},{name:"markdown",type:"boolean",default:!1,help:"Emit assistant replies as markdown"}],columns:["Role","Text"],func:async(t,a)=>{const o=g(a.id),n=p(a.markdown,!1);await t.goto(`https://www.qianwen.com/chat/${o}`);await t.wait(2);await u(t);let s=[];const i=20000,r=1,l=Date.now();while(Date.now()-l<i){s=await f(t);if(s.length>0)break;await t.wait(r)}if(!s.length)throw new c("qwen detail",`No visible messages found for conversation ${o}. Verify the ID is correct and that the session belongs to the current device's b-user-id (or that you are logged in for cross-device sync).`);return s.map((e)=>({Role:e.role,Text:n&&e.role==="Assistant"&&e.html?h(e.html)||e.text:e.text}))}});
|
package/clis/qwen/image.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import*as
|
|
2
|
-
const scope = ${JSON.stringify(
|
|
1
|
+
import*as p from"node:os";import*as E from"node:path";import{cli as x,Strategy as O}from"@jackwener/opencli/registry";import{saveBase64ToFile as D}from"@jackwener/opencli/utils";import{ArgumentError as y,CommandExecutionError as S,EmptyResultError as M,TimeoutError as Q}from"@jackwener/opencli/errors";import{QIANWEN_DOMAIN as B,authRequired as k,dismissLoginModal as q,ensureOnQianwen as C,getMessageBubbles as L,hasLoginGate as v,normalizeBooleanFlag as A,sendMessage as _,setFeatureToggle as T,startNewChat as U}from"./utils.js";function j(t){const e=p.homedir();return t.startsWith(e)?`~${t.slice(e.length)}`:t}function R(t){if(!t)return".jpg";if(t.includes("png"))return".png";if(t.includes("webp"))return".webp";if(t.includes("gif"))return".gif";return".jpg"}async function F(t,e){return await t.evaluate(`(() => {
|
|
2
|
+
const scope = ${JSON.stringify(e||"")};
|
|
3
3
|
const bubbles = Array.from(document.querySelectorAll('[data-msgid$="-answer"]'));
|
|
4
4
|
const target = scope
|
|
5
5
|
? bubbles.find((b) => b.getAttribute('data-msgid') === scope)
|
|
@@ -12,9 +12,9 @@ import*as S from"node:os";import*as F from"node:path";import{cli as P,Strategy a
|
|
|
12
12
|
&& !/\\.(svg)$/i.test(src)
|
|
13
13
|
&& !src.includes('alicdn.com/imgextra'));
|
|
14
14
|
return Array.from(new Set(imgs));
|
|
15
|
-
})()`)}async function
|
|
15
|
+
})()`)}async function W(t,e,u){const c=Date.now();let n=[];while(Date.now()-c<u*1000){await t.wait(2);if(await v(t))return{status:"auth_required",urls:[]};const a=await F(t,e);if(a.length&&a.length===n.length&&a.every((r,o)=>r===n[o]))return{status:"ok",urls:a};if(a.length){await t.wait(2);const r=await F(t,e);if(r.length===a.length&&r.every((o,l)=>o===a[l]))return{status:"ok",urls:r};n=r;continue}n=a}return n.length?{status:"partial",urls:n}:{status:"timeout",urls:[]}}async function G(t,e){return await t.evaluate(`(async () => {
|
|
16
16
|
try {
|
|
17
|
-
const res = await fetch(${JSON.stringify(
|
|
17
|
+
const res = await fetch(${JSON.stringify(e)}, { credentials: 'include' });
|
|
18
18
|
if (!res.ok) return { ok: false, status: res.status };
|
|
19
19
|
const mime = res.headers.get('content-type') || '';
|
|
20
20
|
const buf = await res.arrayBuffer();
|
|
@@ -28,4 +28,4 @@ import*as S from"node:os";import*as F from"node:path";import{cli as P,Strategy a
|
|
|
28
28
|
} catch (error) {
|
|
29
29
|
return { ok: false, status: 0, error: String(error?.message || error) };
|
|
30
30
|
}
|
|
31
|
-
})()`)}
|
|
31
|
+
})()`)}x({site:"qwen",name:"image",access:"write",description:"Generate images with Qianwen (AI生图) and save them locally",domain:B,strategy:O.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,defaultFormat:"plain",args:[{name:"prompt",fromFile:!0,required:!0,positional:!0,help:"Image prompt to send"},{name:"op",default:"~/Pictures/qianwen",help:"Output directory"},{name:"new",type:"boolean",default:!0,help:"Start a new chat before generating (default: true)"},{name:"sd",type:"boolean",default:!1,help:"Skip download; only show the Qianwen link"},{name:"timeout",type:"int",default:180,help:"Max seconds to wait for the image response"}],columns:["Status","File","Link"],func:async(t,e)=>{const u=String(e.prompt||"").trim();if(!u)throw new y("prompt is required");const c=String(e.op||"~/Pictures/qianwen").replace(/^~\//,`${p.homedir()}/`),n=A(e.new,!0),a=A(e.sd,!1),r=Number(e.timeout??180);if(!Number.isInteger(r)||r<=0)throw new y("timeout must be a positive integer");await C(t);await q(t);if(n){await U(t);await q(t)}await T(t,"image",!0);await t.wait(0.5);const o=await _(t,u);if(!o?.ok){if(await v(t))throw k();throw new S(o?.reason||"Failed to send Qianwen image prompt")}let l="";for(let s=0;s<5;s+=1){await t.wait(1);const i=[...await L(t)].reverse().find((d)=>d.role==="Assistant");if(i){l=i.id;break}}const m=await W(t,l,r),h=await t.evaluate("window.location.href").catch(()=>"https://www.qianwen.com/");if(m.status==="auth_required")throw k();if(m.status==="timeout")throw new Q("qianwen image",r,"No generated images observed before timeout.");const w=m.urls;if(a)return[{Status:"\uD83C\uDFA8 generated",File:null,Link:h}];const N=Date.now(),f=[];for(let s=0;s<w.length;s+=1){const g=w[s],i=await G(t,g);if(!i?.ok)throw new S(`Failed to fetch generated Qianwen image ${s+1}: status=${i?.status||"?"}`);const d=w.length>1?`_${s+1}`:"",I=R(i.mime),b=E.join(c,`qianwen_${N}${d}${I}`);await D(i.base64,b);f.push({Status:"✅ saved",File:j(b),Link:h})}if(!f.length)throw new M("qwen image","No generated images were available to download.");return f}});
|
package/clis/qwen/status.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as i,Strategy as a}from"@jackwener/opencli/registry";import{QIANWEN_DOMAIN as r,ensureOnQianwen as l,isLoggedIn as d,getCurrentSessionId as u,getModelLabel as c}from"./utils.js";i({site:"qwen",name:"status",access:"read",description:"Check Qianwen page availability, login state, current session and model",domain:r,strategy:a.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:["Status","Login","Model","SessionId","Url"],func:async(e)=>{await l(e);await e.wait(2);const[o,s,t,n]=await Promise.all([d(e),u(e),c(e),e.evaluate("window.location.href").catch(()=>"")]);return[{Status:"Connected",Login:o?"Yes":"No (guest mode)",Model:t?t:null,SessionId:s?s:null,Url:typeof n==="string"?n:""}]}});
|
package/clis/qwen/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{htmlToMarkdown as
|
|
1
|
+
import{htmlToMarkdown as b}from"@jackwener/opencli/utils";import{ArgumentError as f,AuthRequiredError as g,CommandExecutionError as A,TimeoutError as L}from"@jackwener/opencli/errors";export const QIANWEN_DOMAIN="www.qianwen.com",QIANWEN_URL="https://www.qianwen.com/",QIANWEN_API_DOMAIN="chat2-api.qianwen.com",IS_VISIBLE_JS=`
|
|
2
2
|
const isVisible = (node) => {
|
|
3
3
|
if (!(node instanceof Element)) return false;
|
|
4
4
|
const style = window.getComputedStyle(node);
|
|
@@ -6,7 +6,7 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
6
6
|
const rect = node.getBoundingClientRect();
|
|
7
7
|
return rect.width > 0 && rect.height > 0;
|
|
8
8
|
};
|
|
9
|
-
`;const
|
|
9
|
+
`;const h=2,x=6000,S=2;export function authRequired(t){return new g(QIANWEN_DOMAIN,t||"请在浏览器里用千问 APP 扫码登录 qianwen.com 后再重试。")}export function normalizeBooleanFlag(t,n=!1){if(typeof t==="boolean")return t;if(t==null||t==="")return n;const e=String(t).trim().toLowerCase();return e==="true"||e==="1"||e==="yes"||e==="on"}export async function isOnQianwen(t){const n=await t.evaluate("window.location.href").catch(()=>"");return typeof n==="string"&&n.includes("qianwen.com")}export async function ensureOnQianwen(t){if(await isOnQianwen(t))return;await t.goto(QIANWEN_URL);await t.wait(2)}export async function dismissLoginModal(t){return await t.evaluate(`(() => {
|
|
10
10
|
${IS_VISIBLE_JS}
|
|
11
11
|
const modal = document.querySelector('[role=alert-biz-modal]');
|
|
12
12
|
if (!modal || !isVisible(modal)) return { dismissed: false };
|
|
@@ -27,7 +27,7 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
27
27
|
// Last resort: synth ESC key on document
|
|
28
28
|
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', bubbles: true }));
|
|
29
29
|
return { dismissed: true, method: 'escape' };
|
|
30
|
-
})()`)}export async function hasLoginGate(
|
|
30
|
+
})()`)}export async function hasLoginGate(t){const n=await t.evaluate(`(() => {
|
|
31
31
|
${IS_VISIBLE_JS}
|
|
32
32
|
const modal = document.querySelector('[role=alert-biz-modal]');
|
|
33
33
|
if (modal && isVisible(modal)) {
|
|
@@ -36,7 +36,7 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
36
36
|
if (src.includes('passport.qianwen.com') || src.includes('login')) return true;
|
|
37
37
|
}
|
|
38
38
|
return false;
|
|
39
|
-
})()`);return Boolean(
|
|
39
|
+
})()`);return Boolean(n)}export async function isLoggedIn(t){const n=await t.evaluate(`(() => {
|
|
40
40
|
${IS_VISIBLE_JS}
|
|
41
41
|
const loginBtn = Array.from(document.querySelectorAll('button'))
|
|
42
42
|
.find((node) => (node.textContent || '').trim() === '登录' && isVisible(node));
|
|
@@ -45,14 +45,14 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
45
45
|
.find((node) => (node.textContent || '').includes('登录可同步历史对话'));
|
|
46
46
|
if (hint && isVisible(hint)) return false;
|
|
47
47
|
return true;
|
|
48
|
-
})()`);return Boolean(
|
|
48
|
+
})()`);return Boolean(n)}export async function getCurrentSessionId(t){const n=await t.evaluate("window.location.href").catch(()=>"");if(typeof n!=="string")return"";const e=n.match(/\/chat\/([A-Za-z0-9_-]+)/);return e?e[1]:""}const E=/^[a-f0-9]{32}$/i;export function parseQianwenSessionId(t){const n=String(t??"").trim();if(!n)throw new f("id","must be a non-empty session ID or qianwen.com chat URL");const e=n.match(/qianwen\.com\/chat\/([a-f0-9]{32})(?:[/?#]|$)/i),o=e?e[1]:n;if(!E.test(o))throw new f("id",`not a valid Qianwen session ID (got "${t}"); expected a 32-char hex ID like "abcd1234ef567890abcd1234ef567890" or a full https://www.qianwen.com/chat/<id> URL`);return o.toLowerCase()}export async function getModelLabel(t){const n=await t.evaluate(`(() => {
|
|
49
49
|
${IS_VISIBLE_JS}
|
|
50
50
|
const trigger = Array.from(document.querySelectorAll('[aria-haspopup=dialog]'))
|
|
51
51
|
.find((node) => isVisible(node) && (node.innerText || '').includes('Qwen'));
|
|
52
52
|
if (!trigger) return '';
|
|
53
53
|
const label = (trigger.innerText || '').split('\\n')[0].trim();
|
|
54
54
|
return label;
|
|
55
|
-
})()`);return typeof
|
|
55
|
+
})()`);return typeof n==="string"?n:""}export async function startNewChat(t){if((await t.evaluate(`(() => {
|
|
56
56
|
${IS_VISIBLE_JS}
|
|
57
57
|
const button = Array.from(document.querySelectorAll('button'))
|
|
58
58
|
.find((node) => isVisible(node) && (node.innerText || '').trim() === '新建对话');
|
|
@@ -61,12 +61,12 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
61
61
|
return { ok: true, method: 'button' };
|
|
62
62
|
}
|
|
63
63
|
return { ok: false };
|
|
64
|
-
})()`))?.ok){await
|
|
64
|
+
})()`))?.ok){await t.wait(1.5);return!0}await t.goto(QIANWEN_URL);await t.wait(2);return!0}export async function getComposer(t){return await t.evaluate(`(() => {
|
|
65
65
|
${IS_VISIBLE_JS}
|
|
66
66
|
const editor = Array.from(document.querySelectorAll('[role=textbox][contenteditable=true]'))
|
|
67
67
|
.find((node) => isVisible(node));
|
|
68
68
|
return { found: !!editor, text: editor?.textContent || '' };
|
|
69
|
-
})()`)}export async function sendMessage(
|
|
69
|
+
})()`)}export async function sendMessage(t,n){return await t.evaluate(`(async () => {
|
|
70
70
|
${IS_VISIBLE_JS}
|
|
71
71
|
const waitFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
72
72
|
|
|
@@ -89,7 +89,7 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
89
89
|
// Slate editor accepts content via beforeinput InputEvent
|
|
90
90
|
editor.dispatchEvent(new InputEvent('beforeinput', {
|
|
91
91
|
inputType: 'insertText',
|
|
92
|
-
data: ${JSON.stringify(
|
|
92
|
+
data: ${JSON.stringify(n)},
|
|
93
93
|
bubbles: true,
|
|
94
94
|
cancelable: true,
|
|
95
95
|
}));
|
|
@@ -105,7 +105,7 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
105
105
|
editor.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, bubbles: true }));
|
|
106
106
|
editor.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, bubbles: true }));
|
|
107
107
|
return { ok: true, action: 'enter-fallback' };
|
|
108
|
-
})()`)}export async function getMessageBubbles(
|
|
108
|
+
})()`)}export async function getMessageBubbles(t){const n=await t.evaluate(`(() => {
|
|
109
109
|
${IS_VISIBLE_JS}
|
|
110
110
|
const wraps = Array.from(document.querySelectorAll('[data-chat-question-wrap], [data-chat-answers-wrap]'))
|
|
111
111
|
.filter((node) => node instanceof HTMLElement && isVisible(node));
|
|
@@ -140,20 +140,20 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
140
140
|
out.push({ id, role, text: (text || '').replace(/\\s+/g, ' ').trim(), html });
|
|
141
141
|
}
|
|
142
142
|
return out;
|
|
143
|
-
})()`);if(!Array.isArray(
|
|
143
|
+
})()`);if(!Array.isArray(n))return[];return n.map((e)=>({id:String(e?.id||""),role:e?.role==="Assistant"?"Assistant":"User",text:String(e?.text||"").trim(),html:String(e?.html||"")})).filter((e)=>e.id&&e.text)}export function bubbleHtmlToMarkdown(t){try{return b(t).trim()}catch{return(t||"").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim()}}function m(t){return(t||"").replace(/\u00a0/g," ").replace(/复制\s*$/g,"").replace(/重新生成\s*$/g,"").trim()}function p(t){return m(t).replace(/\s+/g," ").trim()}function I(t){if(typeof t==="string")return{lastBubbleId:"",lastAssistantId:t};return{lastBubbleId:String(t?.lastBubbleId||""),lastAssistantId:String(t?.lastAssistantId||"")}}function q(t,n,e){const o=p(n);let a=-1;const c=Boolean(e.lastBubbleId||e.lastAssistantId);let i=!1;if(e.lastBubbleId){const s=t.findIndex((l)=>l.id===e.lastBubbleId);if(s>=0){a=s;i=!0}}if(e.lastAssistantId){const s=t.findIndex((l)=>l.id===e.lastAssistantId);if(s>=0){a=Math.max(a,s);i=!0}}if(c&&!i)return null;let r=-1;for(let s=a+1;s<t.length;s+=1)if(t[s].role==="User"&&p(t[s].text)===o)r=s;if(r<0)return null;for(let s=r+1;s<t.length;s+=1)if(t[s].role==="Assistant")return t[s];return null}export async function waitForAnswer(t,n,e,o){const a=I(o),c=Date.now();let i="",r=0,s="",l=null;while(Date.now()-c<e*1000){await t.wait(h);if(await hasLoginGate(t))return{status:"auth_required"};const w=await getMessageBubbles(t),d=q(w,n,a);if(!d)continue;if(a.lastAssistantId&&d.id===a.lastAssistantId)continue;const u=m(d.text);if(!u||u===n)continue;s=u;l=d;const y=Date.now()-c>=x;if(u===i){r+=1;if(y&&r>=S)return{status:"ok",assistant:d}}else{i=u;r=0}}if(s)return{status:"partial",assistant:l};return{status:"timeout"}}const k={think:"深度思考",research:"深度研究",task:"任务助理",image:"AI生图",ppt:"PPT创作"};export async function setFeatureToggle(t,n,e){const o=k[n];if(!o)return!1;const a=await t.evaluate(`(async () => {
|
|
144
144
|
${IS_VISIBLE_JS}
|
|
145
145
|
const waitFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
146
|
-
const label = ${JSON.stringify(
|
|
146
|
+
const label = ${JSON.stringify(o)};
|
|
147
147
|
const button = Array.from(document.querySelectorAll('button[aria-label]'))
|
|
148
148
|
.find((node) => isVisible(node) && node.getAttribute('aria-label') === label);
|
|
149
149
|
if (!(button instanceof HTMLElement)) return { found: false };
|
|
150
150
|
const selected = button.getAttribute('aria-pressed') === 'true'
|
|
151
151
|
|| /active|selected|bg-primary/.test(button.className || '');
|
|
152
|
-
if (selected === ${Boolean(
|
|
152
|
+
if (selected === ${Boolean(e)}) return { found: true, changed: false, selected };
|
|
153
153
|
button.click();
|
|
154
154
|
await waitFor(300);
|
|
155
155
|
return { found: true, changed: true };
|
|
156
|
-
})()`);return Boolean(
|
|
156
|
+
})()`);return Boolean(a?.found)}export async function getSessionListFromApi(t,n=30){const e=Number(n??30);if(!Number.isInteger(e)||e<=0||e>100)throw new A("Qianwen history page_size must be an integer between 1 and 100");const o=await t.evaluate(`(async () => {
|
|
157
157
|
try {
|
|
158
158
|
const utdid = (document.cookie.match(/(?:^|;\\s*)b-user-id=([^;]+)/)?.[1])
|
|
159
159
|
|| (document.cookie.match(/(?:^|;\\s*)utdid=([^;]+)/)?.[1])
|
|
@@ -173,7 +173,7 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
173
173
|
method: 'POST',
|
|
174
174
|
credentials: 'include',
|
|
175
175
|
headers: { 'Content-Type': 'application/json' },
|
|
176
|
-
body: JSON.stringify({ page_num: 1, page_size: ${
|
|
176
|
+
body: JSON.stringify({ page_num: 1, page_size: ${e}, page_no: 1 }),
|
|
177
177
|
});
|
|
178
178
|
const text = await res.text();
|
|
179
179
|
let body = null;
|
|
@@ -182,4 +182,4 @@ import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError a
|
|
|
182
182
|
} catch (error) {
|
|
183
183
|
return { ok: false, status: 0, error: String(error?.message || error) };
|
|
184
184
|
}
|
|
185
|
-
})()`);if(!
|
|
185
|
+
})()`);if(!o||!o.ok)return{ok:!1,status:o?.status||0,error:o?.error||"",sessions:[]};const a=o.body?.data||o.body?.result||{},i=(Array.isArray(a?.list)?a.list:Array.isArray(a?.items)?a.items:Array.isArray(a?.page_list)?a.page_list:Array.isArray(o.body?.list)?o.body.list:[]).map((r)=>({id:String(r?.session_id||r?.sessionId||r?.id||""),title:String(r?.title||r?.name||r?.summary||"").trim(),updated_at:Number(r?.updated_at||r?.last_req_timestamp||r?.updatedAt||r?.gmt_modified||r?.update_time||0)})).filter((r)=>r.id);return{ok:!0,status:o.status,sessions:i}}
|
package/clis/reddit/home.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as l,AuthRequiredError as m,CommandExecutionError as a,EmptyResultError as c}from"@jackwener/opencli/errors";import{cli as p,Strategy as h}from"@jackwener/opencli/registry";const u=100;export function parseRedditHomeLimit(e){if(e===void 0||e===null||e==="")return 25;const i=Number(e);if(!Number.isFinite(i)||!Number.isInteger(i)||i<1||i>u)throw new l(`limit must be an integer in [1, ${u}].`,`Got: ${e}`);return i}export function decodeRedditHtml(e){if(typeof e!=="string"||!e)return"";return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/gi,"'").replace(/'/g,"'")}export function extractRedditMedia(e){const i=[],s=e?.gallery_data?.items,r=e?.media_metadata;if(Array.isArray(s)&&r&&typeof r==="object")for(const o of s){const n=r[o?.media_id]?.s?.u;if(typeof n==="string"&&n)i.push(decodeRedditHtml(n))}return{post_hint:typeof e?.post_hint==="string"?e.post_hint:"",url_overridden_by_dest:decodeRedditHtml(e?.url_overridden_by_dest||""),preview_image_url:decodeRedditHtml(e?.preview?.images?.[0]?.source?.url||""),gallery_urls:i}}p({site:"reddit",name:"home",access:"read",description:"Reddit personalized home feed (Best, requires login)",domain:"reddit.com",strategy:h.COOKIE,browser:!0,args:[{name:"limit",type:"int",default:25,help:`Number of posts (1–${u})`}],columns:["rank","title","subreddit","score","comments","postId","author","url","post_hint","url_overridden_by_dest","preview_image_url","gallery_urls"],func:async(e,i)=>{const s=parseRedditHomeLimit(i.limit);await e.goto("https://www.reddit.com");const r=await e.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
3
|
const meRes = await fetch('/api/me.json', { credentials: 'include' });
|
|
4
4
|
if (meRes.status === 401 || meRes.status === 403) {
|
|
@@ -12,7 +12,7 @@ import{ArgumentError as V,AuthRequiredError as W,CommandExecutionError as N,Empt
|
|
|
12
12
|
return { kind: 'auth', detail: 'Not logged in to reddit.com (no identity in /api/me.json)' };
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const limit = ${JSON.stringify(
|
|
15
|
+
const limit = ${JSON.stringify(s)};
|
|
16
16
|
const res = await fetch('/best.json?limit=' + limit + '&raw_json=1', { credentials: 'include' });
|
|
17
17
|
if (res.status === 401 || res.status === 403) {
|
|
18
18
|
return { kind: 'auth', detail: 'Reddit /best.json returned HTTP ' + res.status };
|
|
@@ -29,4 +29,4 @@ import{ArgumentError as V,AuthRequiredError as W,CommandExecutionError as N,Empt
|
|
|
29
29
|
} catch (e) {
|
|
30
30
|
return { kind: 'exception', detail: String(e && e.message || e) };
|
|
31
31
|
}
|
|
32
|
-
})()`);if(
|
|
32
|
+
})()`);if(r?.kind==="auth")throw new m("reddit.com",r.detail);if(r?.kind==="http")throw new a(`HTTP ${r.httpStatus} from ${r.where}`);if(r?.kind==="exception")throw new a(`home failed: ${r.detail}`);if(r?.kind!=="ok")throw new a(`Unexpected result from reddit home: ${JSON.stringify(r)}`);const o=[],n=r.entries.slice(0,s);for(let d=0;d<n.length;d++){const t=n[d]?.data;if(!t||!t.id)continue;o.push({rank:d+1,title:typeof t.title==="string"?t.title:null,subreddit:typeof t.subreddit_name_prefixed==="string"?t.subreddit_name_prefixed:null,score:typeof t.score==="number"?t.score:null,comments:typeof t.num_comments==="number"?t.num_comments:null,postId:t.id,author:typeof t.author==="string"?t.author:null,url:t.permalink?"https://www.reddit.com"+t.permalink:null,...extractRedditMedia(t)})}if(o.length===0){if(n.length>0)throw new a("Reddit home feed entries were missing required post id anchors");throw new c("Reddit returned no posts in the personalized home feed.")}return o}});
|
package/clis/reddit/read.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cli as v,Strategy as
|
|
1
|
+
import{cli as v,Strategy as y}from"@jackwener/opencli/registry";import{ArgumentError as n,AuthRequiredError as _,CommandExecutionError as o,EmptyResultError as b}from"@jackwener/opencli/errors";const h=1,m=5,u=2,w=/^[a-z0-9]+$/i;function c(r){const e=String(r||"").trim();if(!w.test(e))throw new n("Post ID must be a Reddit post id, t3_ fullname, or reddit.com post URL.","Use a bare post id like 1abc123, a fullname like t3_1abc123, or a full Reddit post URL.");return e.toLowerCase()}export function normalizeRedditPostId(r){const e=String(r||"").trim();if(!e)throw new n("Post ID is required.","Use a bare post id like 1abc123, a fullname like t3_1abc123, or a full Reddit post URL.");const s=e.match(/^t3_([a-z0-9]+)$/i);if(s)return c(s[1]);if(/^https?:\/\//i.test(e)){let d;try{d=new URL(e)}catch{throw new n(`Invalid Reddit post URL: ${e}`)}const l=d.hostname.toLowerCase();if(d.protocol!=="https:"||l!=="reddit.com"&&!l.endsWith(".reddit.com"))throw new n("Post URL must be an https reddit.com URL.","Use a URL like https://www.reddit.com/r/sub/comments/1abc123/title_slug/");const a=d.pathname.split("/").filter(Boolean),p=a.indexOf("comments"),i=p+1;if(p<0||a.length<=i)throw new n("Post URL must include the target post id.","Use a URL like https://www.reddit.com/r/sub/comments/1abc123/title_slug/");if(a.length>i+3)throw new n("Post URL must end at the post slug or comment permalink id.","Remove extra path segments after the post slug or comment id.");if(a.length===i+3)c(a[i+2]);return c(a[i])}if(e.includes("/")||e.startsWith("t1_"))throw new n("Post ID must be a Reddit post id, t3_ fullname, or reddit.com post URL.","Use a bare post id like 1abc123, a fullname like t3_1abc123, or a full Reddit post URL.");return c(e)}export function parseExpandRounds(r){if(r===void 0||r===null||r==="")return u;const e=Number(r);if(!Number.isFinite(e)||!Number.isInteger(e)||e<h||e>m)throw new n(`expand-rounds must be an integer in [${h}, ${m}].`,`Got: ${r}`);return e}v({site:"reddit",name:"read",access:"read",description:"Read a Reddit post and its comments",domain:"reddit.com",strategy:y.COOKIE,browser:!0,args:[{name:"post-id",required:!0,positional:!0,help:"Post ID (e.g. 1abc123) or full URL"},{name:"sort",default:"best",help:"Comment sort: best, top, new, controversial, old, qa"},{name:"limit",type:"int",default:25,help:"Number of top-level comments"},{name:"depth",type:"int",default:2,help:"Max reply depth (1=no replies, 2=one level of replies, etc.)"},{name:"replies",type:"int",default:5,help:"Max replies shown per comment at each level (sorted by score)"},{name:"max-length",type:"int",default:2000,help:"Max characters per comment body (min 100)"},{name:"expand-more",type:"bool",default:!1,help:'Follow Reddit "more comments" stubs by calling /api/morechildren.json'},{name:"expand-rounds",type:"int",default:u,help:`Max expansion passes when --expand-more is on (${h}–${m}; each round can fan out new "more" stubs)`}],columns:["type","author","score","text","post_hint","url_overridden_by_dest","preview_image_url","gallery_urls"],func:async(r,e)=>{const s=e.sort??"best",d=Math.max(1,e.limit??25),l=Math.max(1,e.depth??2),a=Math.max(1,e.replies??5),p=Math.max(100,e["max-length"]??2000),i=Boolean(e["expand-more"]),f=parseExpandRounds(e["expand-rounds"]),g=normalizeRedditPostId(e["post-id"]),t=await r.evaluate(`
|
|
2
2
|
(async function() {
|
|
3
3
|
function decodeHtml(s) {
|
|
4
4
|
if (typeof s !== 'string' || !s) return '';
|
|
@@ -34,16 +34,16 @@ import{cli as v,Strategy as B}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
34
34
|
gallery_urls: gallery_urls,
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
-
var postId = ${JSON.stringify(
|
|
37
|
+
var postId = ${JSON.stringify(g)};
|
|
38
38
|
var linkFullname = 't3_' + postId;
|
|
39
39
|
|
|
40
|
-
var sort = ${JSON.stringify(
|
|
41
|
-
var limit = ${
|
|
42
|
-
var maxDepth = ${
|
|
43
|
-
var maxReplies = ${
|
|
44
|
-
var maxLength = ${
|
|
45
|
-
var expandMore = ${JSON.stringify(
|
|
46
|
-
var expandRounds = ${
|
|
40
|
+
var sort = ${JSON.stringify(s)};
|
|
41
|
+
var limit = ${d};
|
|
42
|
+
var maxDepth = ${l};
|
|
43
|
+
var maxReplies = ${a};
|
|
44
|
+
var maxLength = ${p};
|
|
45
|
+
var expandMore = ${JSON.stringify(i)};
|
|
46
|
+
var expandRounds = ${f};
|
|
47
47
|
|
|
48
48
|
// ---------------------------------------------------------------
|
|
49
49
|
// Step 1: fetch the post + initial comment tree
|
|
@@ -395,4 +395,4 @@ import{cli as v,Strategy as B}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
395
395
|
|
|
396
396
|
return { kind: 'ok', rows: rows, expandMeta: expandMeta };
|
|
397
397
|
})()
|
|
398
|
-
`);if(!
|
|
398
|
+
`);if(!t||typeof t!=="object")throw new o("Reddit /comments fetch returned no result envelope.");if(t.kind==="inaccessible")throw new b(t.detail);if(t.kind==="auth")throw new _("reddit.com",t.detail);if(t.kind==="http")throw new o(`HTTP ${t.httpStatus} from ${t.where}`);if(t.kind==="malformed")throw new o(t.detail);if(t.kind==="parser-drift")throw new o(t.detail);if(t.kind==="expand-failed")throw new o(t.detail);if(t.kind!=="ok"||!Array.isArray(t.rows))throw new o(`Unexpected result from reddit read: ${JSON.stringify(t)}`);return t.rows}});
|
package/clis/reddit/reply.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as o,AuthRequiredError as u,CommandExecutionError as i}from"@jackwener/opencli/errors";import{cli as l,Strategy as h}from"@jackwener/opencli/registry";const p=/^[a-z0-9]+$/i;function m(n){const t=String(n||"").trim();if(!p.test(t))throw new o("Comment ID must be a Reddit comment id, t1_ fullname, or reddit.com comment URL.","Use a bare comment id like okf3s7u, a fullname like t1_okf3s7u, or a full Reddit comment URL.");return t.toLowerCase()}export function normalizeRedditCommentFullname(n){const t=String(n||"").trim();if(!t)throw new o("Comment ID is required.","Use a bare comment id like okf3s7u, a fullname like t1_okf3s7u, or a full Reddit comment URL.");const s=t.match(/^t1_([a-z0-9]+)$/i);if(s)return`t1_${m(s[1])}`;if(/^https?:\/\//i.test(t)){let r;try{r=new URL(t)}catch{throw new o(`Invalid Reddit comment URL: ${t}`)}const e=r.hostname.toLowerCase();if(r.protocol!=="https:"||e!=="reddit.com"&&!e.endsWith(".reddit.com"))throw new o("Comment URL must be an https reddit.com URL.","Use a URL like https://www.reddit.com/r/sub/comments/post/title/okf3s7u/");const a=r.pathname.split("/").filter(Boolean),c=a.indexOf("comments"),d=c+3;if(c<0||a.length<=d)throw new o("Comment URL must include the target comment id.","Use a URL like https://www.reddit.com/r/sub/comments/post/title/okf3s7u/");if(a.length!==d+1)throw new o("Comment URL must end at the target comment id.","Remove extra path segments after the comment id.");return`t1_${m(a[d])}`}if(t.includes("/")||t.startsWith("t3_"))throw new o("Comment ID must be a Reddit comment id, t1_ fullname, or reddit.com comment URL.","Use a bare comment id like okf3s7u, a fullname like t1_okf3s7u, or a full Reddit comment URL.");return`t1_${m(t)}`}export function requireReplyText(n){const t=String(n||"");if(!t.trim())throw new o("Reply text is required.","Pass non-empty text to post as the Reddit reply.");return t}l({site:"reddit",name:"reply",access:"write",description:"Reply to a Reddit comment",domain:"reddit.com",strategy:h.COOKIE,browser:!0,args:[{name:"comment-id",type:"string",required:!0,positional:!0,help:"Comment ID (e.g. okf3s7u) or fullname (t1_xxx)"},{name:"text",fromFile:!0,type:"string",required:!0,positional:!0,help:"Reply text"}],columns:["status","message"],func:async(n,t)=>{const s=normalizeRedditCommentFullname(t["comment-id"]),r=requireReplyText(t.text);await n.goto("https://www.reddit.com");const e=await n.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
|
-
const fullname = ${JSON.stringify(
|
|
4
|
-
const text = ${JSON.stringify(
|
|
3
|
+
const fullname = ${JSON.stringify(s)};
|
|
4
|
+
const text = ${JSON.stringify(r)};
|
|
5
5
|
|
|
6
6
|
// Probe identity + modhash. /api/me.json returns data.name only when
|
|
7
7
|
// logged in — empty modhash alone is not a strong enough auth signal
|
|
@@ -53,4 +53,4 @@ import{ArgumentError as J,AuthRequiredError as Y,CommandExecutionError as L}from
|
|
|
53
53
|
} catch (e) {
|
|
54
54
|
return { kind: 'exception', detail: String(e && e.message || e) };
|
|
55
55
|
}
|
|
56
|
-
})()`);if(
|
|
56
|
+
})()`);if(e?.kind==="auth")throw new u("reddit.com",e.detail);if(e?.kind==="http")throw new i(`HTTP ${e.httpStatus} from ${e.where}`);if(e?.kind==="reddit-error")throw new i(`Reddit rejected reply: ${e.detail}`);if(e?.kind==="postcondition")throw new i(e.detail);if(e?.kind==="exception")throw new i(`Reply failed: ${e.detail}`);if(e?.kind!=="ok")throw new i(`Unexpected result from reddit reply: ${JSON.stringify(e)}`);return[{status:"success",message:e.detail}]}});
|
package/clis/reddit/submit.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as r,AuthRequiredError as u,CommandExecutionError as d}from"@jackwener/opencli/errors";import{cli as p,Strategy as m}from"@jackwener/opencli/registry";const f=/^[A-Za-z0-9][A-Za-z0-9_]{1,20}$/;export function normalizeSubreddit(n){let t=String(n||"").trim();if(!t)throw new r("Subreddit is required.",'Pass a subreddit like "test" or "r/test".');if(/^https?:\/\//i.test(t)){let a;try{a=new URL(t)}catch{throw new r(`Invalid subreddit URL: ${t}`)}const i=a.pathname.split("/").filter(Boolean),s=i.indexOf("r");if(s<0||i.length<=s+1)throw new r("Subreddit URL must contain /r/<name>.");t=i[s+1]}t=t.replace(/^\/?r\//i,"").replace(/^\/+/,"");if(!f.test(t))throw new r(`Invalid subreddit name: ${JSON.stringify(t)}`,'Use the bare name, e.g. "test" (2–21 chars, letters/digits/underscore).');return t}p({site:"reddit",name:"submit",access:"write",description:"Submit a new post to a subreddit. Text post by default (--text); pass --url for a link post. Note: many subreddits gate submissions behind karma/age requirements or flair — a rejection is surfaced verbatim.",domain:"reddit.com",strategy:m.COOKIE,browser:!0,args:[{name:"subreddit",type:"string",required:!0,positional:!0,help:'Target subreddit, e.g. "test" or "r/test"'},{name:"title",type:"string",required:!0,positional:!0,help:"Post title (max 300 chars)"},{name:"text",fromFile:!0,type:"string",help:"Body text (markdown) for a self/text post"},{name:"url",type:"string",help:"External URL for a link post (mutually exclusive with --text)"},{name:"flair-id",type:"string",help:"Flair template id, if the subreddit requires one"},{name:"flair-text",type:"string",help:"Flair text to accompany --flair-id"},{name:"nsfw",type:"bool",default:!1,help:"Mark the post as NSFW"},{name:"spoiler",type:"bool",default:!1,help:"Mark the post as a spoiler"},{name:"sendreplies",type:"bool",default:!0,help:"Receive inbox replies for this post (default: true)"}],columns:["status","url","id","message"],func:async(n,t)=>{if(!n)throw new d("Browser session required");const a=normalizeSubreddit(t.subreddit),i=String(t.title??"").trim();if(!i)throw new r("Title is required.");if(i.length>300)throw new r("Title must be at most 300 characters.");const s=typeof t.text==="string"?t.text:"",o=typeof t.url==="string"?t.url.trim():"";if(o&&s)throw new r("Pass either --text (self post) or --url (link post), not both.");const l=o?"link":"self";if(l==="link")try{new URL(o)}catch{throw new r(`Invalid --url: ${o}`)}await n.goto("https://www.reddit.com");const e=await n.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
3
|
const meRes = await fetch('/api/me.json', { credentials: 'include' });
|
|
4
4
|
if (meRes.status === 401 || meRes.status === 403) {
|
|
@@ -9,17 +9,17 @@ import{ArgumentError as H,AuthRequiredError as V,CommandExecutionError as P}from
|
|
|
9
9
|
if (!modhash) return { kind: 'auth', detail: 'No modhash — anonymous or expired session' };
|
|
10
10
|
|
|
11
11
|
const p = new URLSearchParams();
|
|
12
|
-
p.set('sr', ${JSON.stringify(
|
|
13
|
-
p.set('title', ${JSON.stringify(
|
|
14
|
-
p.set('kind', ${JSON.stringify(
|
|
15
|
-
${
|
|
12
|
+
p.set('sr', ${JSON.stringify(a)});
|
|
13
|
+
p.set('title', ${JSON.stringify(i)});
|
|
14
|
+
p.set('kind', ${JSON.stringify(l)});
|
|
15
|
+
${l==="link"?`p.set('url', ${JSON.stringify(o)}); p.set('resubmit', 'true');`:`p.set('text', ${JSON.stringify(s)});`}
|
|
16
16
|
p.set('api_type', 'json');
|
|
17
17
|
p.set('validate_on_submit', 'true');
|
|
18
|
-
p.set('sendreplies', ${
|
|
19
|
-
${
|
|
20
|
-
${
|
|
21
|
-
${
|
|
22
|
-
${
|
|
18
|
+
p.set('sendreplies', ${t.sendreplies===!1?"'false'":"'true'"});
|
|
19
|
+
${t.nsfw?"p.set('nsfw', 'true');":""}
|
|
20
|
+
${t.spoiler?"p.set('spoiler', 'true');":""}
|
|
21
|
+
${t["flair-id"]?`p.set('flair_id', ${JSON.stringify(String(t["flair-id"]))});`:""}
|
|
22
|
+
${t["flair-text"]?`p.set('flair_text', ${JSON.stringify(String(t["flair-text"]))});`:""}
|
|
23
23
|
p.set('uh', modhash);
|
|
24
24
|
|
|
25
25
|
const res = await fetch('/api/submit', {
|
|
@@ -39,4 +39,4 @@ import{ArgumentError as H,AuthRequiredError as V,CommandExecutionError as P}from
|
|
|
39
39
|
} catch (e) {
|
|
40
40
|
return { kind: 'exception', detail: String((e && e.message) || e) };
|
|
41
41
|
}
|
|
42
|
-
})()`);if(
|
|
42
|
+
})()`);if(e?.kind==="auth")throw new u("reddit.com",e.detail);if(e?.kind==="http")throw new d(`HTTP ${e.httpStatus} from /api/submit`);if(e?.kind==="exception")throw new d(`Reddit submit failed: ${e.detail}`);if(e?.kind==="reject")return[{status:"failed",url:"",id:"",message:e.detail}];if(!e?.ok)throw new d(`Unexpected Reddit submit result: ${JSON.stringify(e)}`);return[{status:"success",url:e.url,id:e.id,message:"Post submitted to r/"+a}]}});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as d,CommandExecutionError as n,EmptyResultError as c}from"@jackwener/opencli/errors";import{cli as f,Strategy as b}from"@jackwener/opencli/registry";const m=/^[A-Za-z][A-Za-z0-9_]{2,20}$/;export function parseSubredditName(i){let r=String(i||"").trim();if(!r)throw new d("Subreddit name is required.","Pass a subreddit name like `python` (or `r/python`).");if(r.startsWith("/r/"))r=r.slice(3);else if(r.startsWith("r/"))r=r.slice(2);if(!m.test(r))throw new d("Invalid subreddit name.","Subreddit names are 3–21 characters, start with a letter, and contain only letters, digits, and underscores.");return r}f({site:"reddit",name:"subreddit-info",access:"read",description:"Show metadata for a Reddit subreddit (subscribers, description, created date, NSFW)",domain:"reddit.com",strategy:b.COOKIE,browser:!0,args:[{name:"name",type:"string",required:!0,positional:!0,help:"Subreddit name (no `r/` prefix needed)"}],columns:["field","value"],func:async(i,r)=>{const o=parseSubredditName(r.name);await i.goto("https://www.reddit.com");const t=await i.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
|
-
const sub = ${JSON.stringify(
|
|
3
|
+
const sub = ${JSON.stringify(o)};
|
|
4
4
|
const res = await fetch('/r/' + encodeURIComponent(sub) + '/about.json?raw_json=1', { credentials: 'include' });
|
|
5
5
|
if (res.status === 401 || res.status === 403 || res.status === 404) {
|
|
6
6
|
return { kind: 'missing', detail: 'Subreddit r/' + sub + ' was not found or is not accessible (HTTP ' + res.status + ').' };
|
|
@@ -26,4 +26,4 @@ import{ArgumentError as K,CommandExecutionError as G,EmptyResultError as Q}from"
|
|
|
26
26
|
} catch (e) {
|
|
27
27
|
return { kind: 'exception', detail: String(e && e.message || e) };
|
|
28
28
|
}
|
|
29
|
-
})()`);if(
|
|
29
|
+
})()`);if(t?.kind==="missing")throw new c(t.detail);if(t?.kind==="http")throw new n(`HTTP ${t.httpStatus} from ${t.where}`);if(t?.kind==="malformed")throw new n(t.detail);if(t?.kind==="exception")throw new n(`subreddit-info failed: ${t.detail}`);if(t?.kind!=="ok")throw new n(`Unexpected result from reddit subreddit-info: ${JSON.stringify(t)}`);const e=t.info,u=e.created_utc?new Date(e.created_utc*1000).toISOString().split("T")[0]:null,s=typeof e.subscribers==="number"?e.subscribers:null,a=typeof e.active_user_count==="number"?e.active_user_count:typeof e.accounts_active==="number"?e.accounts_active:null,l=typeof e.public_description==="string"?e.public_description.trim():"";return[{field:"Name",value:e.display_name_prefixed||"r/"+e.display_name},{field:"Title",value:typeof e.title==="string"?e.title:null},{field:"Subscribers",value:s!=null?String(s):null},{field:"Active Now",value:a!=null?String(a):null},{field:"NSFW",value:e.over18?"Yes":"No"},{field:"Type",value:typeof e.subreddit_type==="string"?e.subreddit_type:null},{field:"Description",value:l||null},{field:"Created",value:u},{field:"URL",value:e.url?"https://www.reddit.com"+e.url:null}]}});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
2
|
-
${
|
|
1
|
+
import{ArgumentError as u,AuthRequiredError as l,CommandExecutionError as n,EmptyResultError as c}from"@jackwener/opencli/errors";import{cli as m,Strategy as f}from"@jackwener/opencli/registry";import{BROWSER_JSON_SNIFF_FN as p,throwIfLoginWall as g}from"@jackwener/opencli/utils";export const REDDIT_SUBSCRIBED_MAX_LIMIT=1000;export function parseRedditSubscribedLimit(t){if(t===void 0||t===null||t==="")return 100;const i=Number(t);if(!Number.isFinite(i)||!Number.isInteger(i)||i<1||i>REDDIT_SUBSCRIBED_MAX_LIMIT)throw new u(`limit must be an integer in [1, ${REDDIT_SUBSCRIBED_MAX_LIMIT}].`,`Got: ${t}`);return i}export function unwrapEvaluateResult(t){if(t&&typeof t==="object"&&!Array.isArray(t)&&"session"in t&&"data"in t)return t.data;return t}function h(t,i){const e=t?.data;if(!e||typeof e!=="object")throw new n(`Reddit subscriptions row ${i+1} was missing data.`);const r=typeof e.name==="string"?e.name:"",s=r.startsWith("t5_")?r:t?.kind==="t5"&&typeof e.id==="string"&&e.id?`t5_${e.id}`:"",d=typeof e.display_name==="string"&&e.display_name?e.display_name:"",o=typeof e.display_name_prefixed==="string"&&e.display_name_prefixed?e.display_name_prefixed:d?`r/${d}`:"",a=typeof e.url==="string"&&e.url.startsWith("/r/")?e.url:"";if(!s||!d||!o||!a)throw new n(`Reddit subscriptions row ${i+1} was missing subreddit identity.`);return{id:s,subreddit:o,title:typeof e.title==="string"?e.title:"",subscribers:typeof e.subscribers==="number"?e.subscribers:null,description:typeof e.public_description==="string"?e.public_description.slice(0,200):"",url:"https://www.reddit.com"+a}}m({site:"reddit",name:"subscribed",description:"List subreddits you are subscribed to",access:"read",domain:"reddit.com",strategy:f.COOKIE,browser:!0,args:[{name:"limit",type:"int",default:100,help:`Max subreddits to return (1-${REDDIT_SUBSCRIBED_MAX_LIMIT}, auto-paginates)`}],columns:["id","subreddit","title","subscribers","description","url"],func:async(t,i)=>{const e=parseRedditSubscribedLimit(i.limit);if(!t)throw new n("Browser session required");await t.goto("https://www.reddit.com");const r=unwrapEvaluateResult(await t.evaluate(`(async () => {
|
|
2
|
+
${p}
|
|
3
3
|
try {
|
|
4
4
|
// fetchJsonOrLoginWall sniffs HTML responses (login wall / WAF / rate-limit
|
|
5
5
|
// page) and returns a structured { __loginWall, status, url, ... } sentinel
|
|
@@ -17,7 +17,7 @@ import{ArgumentError as $,AuthRequiredError as q,CommandExecutionError as P,Empt
|
|
|
17
17
|
const username = me?.data?.name || me?.name;
|
|
18
18
|
if (!username) return { kind: 'auth', detail: 'Not logged in to reddit.com (no identity in /api/me.json)' };
|
|
19
19
|
|
|
20
|
-
const target = ${JSON.stringify(
|
|
20
|
+
const target = ${JSON.stringify(e)};
|
|
21
21
|
const PAGE_SIZE = 100;
|
|
22
22
|
const out = [];
|
|
23
23
|
let after = null;
|
|
@@ -65,4 +65,4 @@ import{ArgumentError as $,AuthRequiredError as q,CommandExecutionError as P,Empt
|
|
|
65
65
|
} catch (e) {
|
|
66
66
|
return { kind: 'exception', detail: String(e && e.message || e) };
|
|
67
67
|
}
|
|
68
|
-
})()`));if(
|
|
68
|
+
})()`));if(r?.kind==="login-wall")g(r.sentinel,{url:r.where});if(r?.kind==="auth")throw new l("reddit.com",r.detail);if(r?.kind==="http")throw new n(`HTTP ${r.httpStatus} from ${r.where}`);if(r?.kind==="malformed")throw new n(r.detail);if(r?.kind==="exception")throw new n(`subscribed failed: ${r.detail}`);if(r?.kind!=="ok"||!Array.isArray(r.entries))throw new n(`Unexpected result from reddit subscribed: ${JSON.stringify(r)}`);const s=r.entries.slice(0,e).map((d,o)=>h(d,o));if(s.length===0)throw new c("Reddit returned no subscribed subreddits for the logged-in account.");return s}});
|
package/clis/reddit/whoami.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as u,CommandExecutionError as a}from"@jackwener/opencli/errors";import{cli as s,Strategy as m}from"@jackwener/opencli/registry";import{cookieQuickCheck as c}from"../_shared/article/auth.js";s({site:"reddit",name:"whoami",access:"read",description:"Show the currently logged-in Reddit user",domain:"reddit.com",strategy:m.COOKIE,browser:!0,args:[],columns:["field","value"],authStatus:{quickCheck:c("https://www.reddit.com",["reddit_session"])},func:async(r)=>{await r.goto("https://www.reddit.com");const t=await r.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
3
|
const res = await fetch('/api/me.json?raw_json=1', { credentials: 'include' });
|
|
4
4
|
if (res.status === 401 || res.status === 403) {
|
|
@@ -16,4 +16,4 @@ import{AuthRequiredError as L,CommandExecutionError as F}from"@jackwener/opencli
|
|
|
16
16
|
} catch (e) {
|
|
17
17
|
return { kind: 'exception', detail: String(e && e.message || e) };
|
|
18
18
|
}
|
|
19
|
-
})()`);if(
|
|
19
|
+
})()`);if(t?.kind==="auth")throw new u("reddit.com",t.detail);if(t?.kind==="http")throw new a(`HTTP ${t.httpStatus} from ${t.where}`);if(t?.kind==="exception")throw new a(`whoami failed: ${t.detail}`);if(t?.kind!=="ok")throw new a(`Unexpected result from reddit whoami: ${JSON.stringify(t)}`);const e=t.identity,d=e.created_utc?new Date(e.created_utc*1000).toISOString().split("T")[0]:null,i=typeof e.link_karma==="number"?e.link_karma:null,n=typeof e.comment_karma==="number"?e.comment_karma:null,o=typeof e.total_karma==="number"?e.total_karma:i!=null&&n!=null?i+n:null,l=typeof e.inbox_count==="number"?e.inbox_count:null;return[{field:"Username",value:"u/"+e.name},{field:"ID",value:e.id?"t2_"+e.id:null},{field:"Post Karma",value:i!=null?String(i):null},{field:"Comment Karma",value:n!=null?String(n):null},{field:"Total Karma",value:o!=null?String(o):null},{field:"Account Created",value:d},{field:"Gold",value:e.is_gold?"Yes":"No"},{field:"Mod",value:e.is_mod?"Yes":"No"},{field:"Verified Email",value:e.has_verified_email?"Yes":"No"},{field:"Has Mail",value:e.has_mail?"Yes":"No"},{field:"Inbox Count",value:l!=null?String(l):null}]}});
|
package/clis/rednote/comments.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as p,Strategy as f}from"@jackwener/opencli/registry";import{ArgumentError as
|
|
1
|
+
import{cli as p,Strategy as f}from"@jackwener/opencli/registry";import{ArgumentError as d,AuthRequiredError as w,CommandExecutionError as h,EmptyResultError as y}from"@jackwener/opencli/errors";import{buildCommentsExtractJs as b,normalizeCommentRows as g}from"../xiaohongshu/comments.js";import{buildNoteUrl as R,parseNoteId as _}from"../xiaohongshu/note-helpers.js";const k="Pass a full rednote.com note URL with xsec_token from search results or user/profile context.";function N(o){const e=Number(o??20);if(!Number.isFinite(e)||!Number.isInteger(e))throw new d(`--limit must be an integer between 1 and 50, got ${JSON.stringify(o)}`);if(e<1||e>50)throw new d(`--limit must be between 1 and 50, got ${e}`);return e}p({site:"rednote",name:"comments",access:"read",description:"Read comments from a rednote note (supports nested replies)",domain:"www.rednote.com",strategy:f.COOKIE,navigateBefore:!1,args:[{name:"note-id",required:!0,positional:!0,help:"Full rednote note URL with xsec_token"},{name:"limit",type:"int",default:20,help:"Number of top-level comments (max 50)"},{name:"with-replies",type:"boolean",default:!1,help:"Include nested replies (楼中楼)"}],columns:["rank","author","text","likes","time","is_reply","reply_to","images"],func:async(o,e)=>{const i=N(e.limit),a=Boolean(e["with-replies"]),s=String(e["note-id"]),u=_(s);await o.goto(R(s,{commandName:"rednote comments",cookieRoot:"rednote.com",signedUrlHint:k}));await o.wait({time:2+Math.random()*3});const r=await o.evaluate(b(a,i));if(!r||typeof r!=="object")throw new y("rednote/comments","Unexpected evaluate response");if(r.securityBlock)throw new h("Rednote security block: the note detail page was blocked by risk control.",/^https?:\/\//.test(s)?"The page may be temporarily restricted. Try again later or from a different session.":"Try using a full URL from search results (with xsec_token) instead of a bare note ID.");if(r.loginWall)throw new w("www.rednote.com","Note comments require login");const m=g(r.results,"rednote/comments"),l=(t,n)=>({rank:n+1,author:t.author,text:t.text,likes:t.likes,time:t.time,is_reply:t.is_reply,reply_to:t.reply_to,images:t.images??[]});if(a){const t=[];let n=0;for(const c of m){if(!c.is_reply)n++;if(n>i)break;t.push(c)}return t.map(l)}return m.slice(0,i).map(l)}});
|