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/deepseek/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as h}from"@jackwener/opencli/errors";export const DEEPSEEK_DOMAIN="chat.deepseek.com",DEEPSEEK_URL="https://chat.deepseek.com/",TEXTAREA_SELECTOR='textarea[placeholder*="DeepSeek"]',MESSAGE_SELECTOR=".ds-message";const b=/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;export function parseDeepSeekConversationId(e){const t=String(e??"").trim();if(!t)throw new h("id","must be a non-empty conversation ID or URL");const n=t.match(/\/a\/chat\/s\/([a-f0-9-]+)/i),r=n?n[1]:t;if(!b.test(r))throw new h("id",`not a valid DeepSeek conversation ID (got "${e}"); expected a UUID like "749e6bbd-6a45-4440-beaa-ae5238bf06d8" or a full /a/chat/s/<id> URL`);return r.toLowerCase()}export async function isOnDeepSeek(e){const t=await e.evaluate("window.location.href").catch(()=>"");if(typeof t!=="string"||!t)return!1;try{const n=new URL(t).hostname;return n==="deepseek.com"||n.endsWith(".deepseek.com")}catch{return!1}}export async function ensureOnDeepSeek(e){if(await isOnDeepSeek(e))return!1;await e.goto(DEEPSEEK_URL);try{await e.wait({selector:TEXTAREA_SELECTOR,timeout:8})}catch{}return!0}export async function getPageState(e){return e.evaluate(`(() => {
|
|
2
2
|
const url = window.location.href;
|
|
3
3
|
const title = document.title;
|
|
4
4
|
const textarea = document.querySelector('${TEXTAREA_SELECTOR}');
|
|
@@ -9,31 +9,31 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
9
9
|
hasTextarea: !!textarea,
|
|
10
10
|
isLoggedIn: !!avatar,
|
|
11
11
|
};
|
|
12
|
-
})()`)}export async function selectModel(
|
|
12
|
+
})()`)}export async function selectModel(e,t){return e.evaluate(`(() => {
|
|
13
13
|
var radios = document.querySelectorAll('div[role="radio"]');
|
|
14
14
|
if (radios.length === 0) return { ok: false };
|
|
15
|
-
var name = '${
|
|
15
|
+
var name = '${t}'.toLowerCase();
|
|
16
16
|
var index = name === 'instant' ? 0 : name === 'expert' ? 1 : name === 'vision' ? 2 : -1;
|
|
17
17
|
if (index < 0 || index >= radios.length) return { ok: false };
|
|
18
18
|
var target = radios[index];
|
|
19
19
|
var alreadySelected = target.getAttribute('aria-checked') === 'true';
|
|
20
20
|
if (!alreadySelected) target.click();
|
|
21
21
|
return { ok: true, toggled: !alreadySelected };
|
|
22
|
-
})()`)}export async function setFeature(
|
|
22
|
+
})()`)}export async function setFeature(e,t,n){var r=t==="DeepThink"?0:1;return e.evaluate(`(() => {
|
|
23
23
|
var toggles = Array.from(document.querySelectorAll('.ds-toggle-button'));
|
|
24
|
-
var btn = toggles[${
|
|
24
|
+
var btn = toggles[${r}];
|
|
25
25
|
if (!btn) return { ok: false };
|
|
26
26
|
var isActive = btn.classList.contains('ds-toggle-button--selected');
|
|
27
|
-
if (${
|
|
28
|
-
return { ok: true, toggled: ${
|
|
29
|
-
})()`)}export async function sendMessage(
|
|
27
|
+
if (${n} !== isActive) btn.click();
|
|
28
|
+
return { ok: true, toggled: ${n} !== isActive };
|
|
29
|
+
})()`)}export async function sendMessage(e,t){const n=JSON.stringify(t);return e.evaluate(`(async () => {
|
|
30
30
|
const box = document.querySelector('${TEXTAREA_SELECTOR}');
|
|
31
31
|
if (!box) return { ok: false, reason: 'textarea not found' };
|
|
32
32
|
|
|
33
33
|
box.focus();
|
|
34
34
|
box.value = '';
|
|
35
35
|
document.execCommand('selectAll');
|
|
36
|
-
document.execCommand('insertText', false, ${
|
|
36
|
+
document.execCommand('insertText', false, ${n});
|
|
37
37
|
await new Promise(r => setTimeout(r, 800));
|
|
38
38
|
|
|
39
39
|
// Find the send button: last non-toggle button in the textarea's container
|
|
@@ -53,9 +53,9 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
53
53
|
|
|
54
54
|
box.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, bubbles: true }));
|
|
55
55
|
return { ok: true, method: 'enter' };
|
|
56
|
-
})()`)}export async function getBubbleCount(
|
|
56
|
+
})()`)}export async function getBubbleCount(e){return await e.evaluate(`(() => {
|
|
57
57
|
return document.querySelectorAll('${MESSAGE_SELECTOR}').length;
|
|
58
|
-
})()`)||0}export function parseThinkingResponse(
|
|
58
|
+
})()`)||0}export function parseThinkingResponse(e){if(!e)return null;const t=e.match(/^(Thought for ([\d.]+) seconds?|已思考(用时 ([\d.]+) 秒))\s*/);if(!t)return{response:e,thinking:null,thinking_time:null};const n=t[2]||t[3];return{response:"",thinking:e.slice(t[0].length).trim(),thinking_time:n}}export async function waitForResponse(e,t,n,r,o=!1){const i=Date.now();let s="",d=0;while(Date.now()-i<r){await e.wait(3);let a;try{a=await e.evaluate(`(() => {
|
|
59
59
|
const bubbles = document.querySelectorAll('${MESSAGE_SELECTOR}');
|
|
60
60
|
const texts = Array.from(bubbles).map(b => (b.innerText || '').trim()).filter(Boolean);
|
|
61
61
|
var last = texts[texts.length - 1] || '';
|
|
@@ -66,7 +66,7 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
66
66
|
// final answer in the main .ds-markdown region. By querying
|
|
67
67
|
// these separately we avoid any text-heuristic split.
|
|
68
68
|
var thinkEl = null, answerEl = null, thinkTime = null;
|
|
69
|
-
if (${
|
|
69
|
+
if (${o} && bubbles.length > 0) {
|
|
70
70
|
var lastBubble = bubbles[bubbles.length - 1];
|
|
71
71
|
// Thinking container — DeepSeek uses various class names;
|
|
72
72
|
// try common selectors.
|
|
@@ -103,7 +103,7 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
103
103
|
answerText: answerEl ? (answerEl.innerText || '').trim() : null,
|
|
104
104
|
thinkTime: thinkTime,
|
|
105
105
|
};
|
|
106
|
-
})()`)}catch{continue}if(!
|
|
106
|
+
})()`)}catch{continue}if(!a)continue;const l=a.last;if(l&&a.count>t&&l!==n.trim()){if(l===s){d++;if(d>=3){if(o){if(a.thinkText!=null||a.answerText!=null)return{thinking:a.thinkText||"",response:a.answerText||"",thinking_time:a.thinkTime||null};return parseThinkingResponse(l)}return l}}else d=0;s=l}}if(o&&s)return parseThinkingResponse(s);return s||null}export async function getVisibleMessages(e){const t=await e.evaluate(`(() => {
|
|
107
107
|
const msgs = document.querySelectorAll('${MESSAGE_SELECTOR}');
|
|
108
108
|
return Array.from(msgs).map(m => {
|
|
109
109
|
// User messages carry an extra hash-class alongside ds-message
|
|
@@ -113,12 +113,12 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
113
113
|
Text: (m.innerText || '').trim(),
|
|
114
114
|
};
|
|
115
115
|
}).filter(m => m.Text);
|
|
116
|
-
})()`);return Array.isArray(
|
|
116
|
+
})()`);return Array.isArray(t)?t:[]}export async function getConversationList(e){await ensureOnDeepSeek(e);await e.evaluate(`(() => {
|
|
117
117
|
if (document.querySelectorAll('a[href*="/a/chat/s/"]').length === 0) {
|
|
118
118
|
const btn = document.querySelector('div[tabindex="0"][role="button"]');
|
|
119
119
|
if (btn) btn.click();
|
|
120
120
|
}
|
|
121
|
-
})()`);for(let
|
|
121
|
+
})()`);for(let t=0;t<5;t++){await e.wait(2);const n=await e.evaluate(`(() => {
|
|
122
122
|
const items = [];
|
|
123
123
|
const links = document.querySelectorAll('a[href*="/a/chat/s/"]');
|
|
124
124
|
links.forEach((link, i) => {
|
|
@@ -133,12 +133,12 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
133
133
|
});
|
|
134
134
|
});
|
|
135
135
|
return items;
|
|
136
|
-
})()`);if(Array.isArray(
|
|
136
|
+
})()`);if(Array.isArray(n)&&n.length>0)return n}return[]}export async function pickResumeUrl(e){await e.evaluate(`(() => {
|
|
137
137
|
if (document.querySelectorAll('a[href*="/a/chat/s/"]').length === 0) {
|
|
138
138
|
const btn = document.querySelector('div[tabindex="0"][role="button"]');
|
|
139
139
|
if (btn) btn.click();
|
|
140
140
|
}
|
|
141
|
-
})()`);for(let
|
|
141
|
+
})()`);for(let t=0;t<5;t++){await e.wait(2);const n=await e.evaluate(`(() => {
|
|
142
142
|
const links = document.querySelectorAll('a[href*="/a/chat/s/"]');
|
|
143
143
|
if (links.length === 0) return null;
|
|
144
144
|
const PINNED_HEADER = /^\\s*(置\\s*顶|Pinned)\\s*$/i;
|
|
@@ -151,8 +151,8 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
151
151
|
const target = Array.from(links).find((l) => !isPinned(l)) || links[0];
|
|
152
152
|
const href = target.getAttribute('href') || '';
|
|
153
153
|
return href ? 'https://chat.deepseek.com' + href : null;
|
|
154
|
-
})()`);if(
|
|
155
|
-
var name = ${JSON.stringify(
|
|
154
|
+
})()`);if(n)return n}return null}async function k(e,t){for(let n=0;n<8;n++){await e.wait(2);if(await e.evaluate(`(() => {
|
|
155
|
+
var name = ${JSON.stringify(t)};
|
|
156
156
|
var hasFileName = Array.from(document.querySelectorAll('div'))
|
|
157
157
|
.some(function(el) { return el.children.length === 0 && (el.textContent || '').trim() === name; });
|
|
158
158
|
if (hasFileName) return true;
|
|
@@ -164,17 +164,17 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
164
164
|
while (c && !c.querySelector('div[role="button"]')) c = c.parentElement;
|
|
165
165
|
if (!c) return false;
|
|
166
166
|
return !!c.querySelector('img[src], canvas, video, [style*="background-image"], [class*="preview"], [class*="upload"]');
|
|
167
|
-
})()`))return!0}return!1}export async function sendWithFile(
|
|
167
|
+
})()`))return!0}return!1}export async function sendWithFile(e,t,n){const r=await import("node:fs"),o=await import("node:path"),i=o.default.resolve(t);if(!r.default.existsSync(i))return{ok:!1,reason:`File not found: ${i}`};const s=r.default.statSync(i);if(s.size>104857600)return{ok:!1,reason:`File too large (${(s.size/1024/1024).toFixed(1)} MB). Max: 100 MB`};const d=o.default.basename(i);await e.evaluate(`(() => {
|
|
168
168
|
if (document.querySelectorAll('a[href*="/a/chat/s/"]').length > 0) {
|
|
169
169
|
const btn = document.querySelector('div[tabindex="0"][role="button"]');
|
|
170
170
|
if (btn) btn.click();
|
|
171
171
|
}
|
|
172
|
-
})()`);await
|
|
173
|
-
var binary = atob('${
|
|
172
|
+
})()`);await e.wait(0.5);let a=!1;if(e.setFileInput)try{await e.setFileInput([i],'input[type="file"]');a=!0}catch(c){const u=String(c?.message||c);if(!u.includes("Unknown action")&&!u.includes("not supported")&&!u.includes("Not allowed")&&!u.includes("File access not granted"))throw c}if(!a){const u=r.default.readFileSync(i).toString("base64"),f=await e.evaluate(`(async () => {
|
|
173
|
+
var binary = atob('${u}');
|
|
174
174
|
var bytes = new Uint8Array(binary.length);
|
|
175
175
|
for (var i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
176
176
|
|
|
177
|
-
var file = new File([bytes], ${JSON.stringify(
|
|
177
|
+
var file = new File([bytes], ${JSON.stringify(d)});
|
|
178
178
|
var dt = new DataTransfer();
|
|
179
179
|
dt.items.add(file);
|
|
180
180
|
|
|
@@ -190,7 +190,7 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
190
190
|
// Use inp.files, not dt.files; assignment transfers ownership
|
|
191
191
|
inp[propsKey].onChange({ target: { files: inp.files } });
|
|
192
192
|
return { ok: true };
|
|
193
|
-
})()`);if(
|
|
193
|
+
})()`);if(f&&!f.ok)return f}if(!await k(e,d))return{ok:!1,reason:"file preview did not appear"};let m=!1;for(let c=0;c<15;c++){if(await e.evaluate(`(() => {
|
|
194
194
|
var box = document.querySelector('${TEXTAREA_SELECTOR}');
|
|
195
195
|
if (!box) return false;
|
|
196
196
|
var c = box.parentElement;
|
|
@@ -199,4 +199,4 @@ import{ArgumentError as F}from"@jackwener/opencli/errors";export const DEEPSEEK_
|
|
|
199
199
|
var btns = c.querySelectorAll('div[role="button"]:not(.ds-toggle-button)');
|
|
200
200
|
var last = btns[btns.length - 1];
|
|
201
201
|
return !!(last && last.getAttribute('aria-disabled') === 'false');
|
|
202
|
-
})()`)){
|
|
202
|
+
})()`)){m=!0;break}await e.wait(1)}if(!m)return{ok:!1,reason:"send button did not enable after upload"};return sendMessage(e,n)}export async function withRetry(e,t=2){for(let n=0;n<=t;n++)try{return await e()}catch(r){const o=String(r?.message||r);if(n<t&&o.includes("Promise was collected")){await new Promise((i)=>setTimeout(i,2000));continue}throw r}}export function parseBoolFlag(e){if(typeof e==="boolean")return e;return String(e??"").trim().toLowerCase()==="true"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as h,Strategy as A}from"@jackwener/opencli/registry";import{EmptyResultError as S}from"@jackwener/opencli/errors";import{LLAMA_BASE as m,llamaFetch as u,requireSlug as b,unixToDate as d}from"./utils.js";h({site:"defillama",name:"protocol",access:"read",description:"Single DefiLlama protocol details (current TVL, mcap, chains, twitter, github, description)",domain:"defillama.com",strategy:A.PUBLIC,browser:!1,args:[{name:"slug",positional:!0,type:"string",required:!0,help:'DefiLlama protocol slug (e.g. "aave", "lido")'}],columns:["slug","name","category","isParent","tvl","tvlAt","mcap","chains","twitter","github","audits","listedAt","description","website","url"],func:async(g)=>{const r=b(g.slug,"slug"),t=await u(`${m}/protocol/${encodeURIComponent(r)}`,`defillama protocol ${r}`);if(!t||!t.name)throw new S("defillama protocol",`DefiLlama returned no metadata for "${r}".`);const e=Array.isArray(t.tvl)?t.tvl:[],o=e.length?e[e.length-1]:null,p=o&&Number.isFinite(Number(o.totalLiquidityUSD))?Number(o.totalLiquidityUSD):null,f=o?d(o.date):null,n=t.isParentProtocol===!0;let c="";const l=new Set(Array.isArray(t.chains)?t.chains:[]),s=await u(`${m}/protocols`,`defillama protocol ${r} list lookup`);if(Array.isArray(s)){if(!n){const i=s.find((a)=>a&&a.slug===r);if(i&&typeof i.category==="string")c=i.category;if(i&&Array.isArray(i.chains))for(const a of i.chains)l.add(a)}else for(const i of s)if(i&&i.parentProtocol===t.id&&Array.isArray(i.chains))for(const a of i.chains)l.add(a)}const y=Array.isArray(t.github)?t.github:[];return[{slug:r,name:String(t.name).trim(),category:c,isParent:n,tvl:p,tvlAt:f,mcap:t.mcap==null?null:Number(t.mcap),chains:[...l].join(", "),twitter:String(t.twitter??"").trim(),github:y.join(", "),audits:String(t.audits??"").trim(),listedAt:d(t.listedAt),description:String(t.description??"").trim(),website:String(t.url??"").trim(),url:`https://defillama.com/protocol/${r}`}]}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as m,Strategy as c}from"@jackwener/opencli/registry";import{EmptyResultError as n}from"@jackwener/opencli/errors";import{LLAMA_BASE as s,llamaFetch as u,requireBoundedInt as d,unixToDate as g}from"./utils.js";m({site:"defillama",name:"protocols",access:"read",description:"Top DeFi protocols on DefiLlama by current TVL (slug, name, category, TVL, mcap, change_1d/7d, chains)",domain:"defillama.com",strategy:c.PUBLIC,browser:!1,args:[{name:"limit",type:"int",default:30,help:"Number of rows to return (1-500)"}],columns:["rank","slug","name","category","tvl","mcap","change_1d","change_7d","chains","listedAt","url"],func:async(o)=>{const i=d(o.limit,30,500,"limit"),r=await u(`${s}/protocols`,"defillama protocols");if(!Array.isArray(r)||r.length===0)throw new n("defillama protocols","DefiLlama returned no protocol entries.");const l=r.filter((e)=>e&&(e.slug||e.name)&&Number.isFinite(Number(e.tvl))).sort((e,t)=>Number(t.tvl)-Number(e.tvl)).slice(0,i);if(l.length===0)throw new n("defillama protocols","DefiLlama returned no protocols with numeric TVL.");return l.map((e,t)=>{const a=String(e.slug??"").trim();return{rank:t+1,slug:a,name:String(e.name??"").trim(),category:String(e.category??"").trim(),tvl:Number(e.tvl),mcap:e.mcap==null?null:Number(e.mcap),change_1d:e.change_1d==null?null:Number(e.change_1d),change_7d:e.change_7d==null?null:Number(e.change_7d),chains:Array.isArray(e.chains)?e.chains.join(", "):"",listedAt:g(e.listedAt),url:a?`https://defillama.com/protocol/${a}`:""}})}});
|
package/clis/defillama/utils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as o,CommandExecutionError as a,EmptyResultError as u}from"@jackwener/opencli/errors";export const LLAMA_BASE="https://api.llama.fi";const c="opencli-defillama-adapter (+https://github.com/jackwener/OpenCLI)",m=/^[a-z0-9][a-z0-9._-]{0,99}$/;export function requireString(r,t){const e=String(r??"").trim();if(!e)throw new o(`defillama ${t} cannot be empty`);return e}export function requireSlug(r,t="slug"){const e=String(r??"").trim();if(!e)throw new o(`defillama ${t} is required (e.g. "aave", "lido")`,"Use the protocol slug as it appears on https://defillama.com/protocol/<slug>.");if(!m.test(e))throw new o(`defillama ${t} "${r}" is not a valid DefiLlama slug`,'Slugs are lowercase ASCII (letters / digits / "._-"), e.g. "aave", "lido", "pancakeswap-amm".');return e}export function requireBoundedInt(r,t,e,i="limit"){const n=r??t,s=typeof n==="number"?n:Number(n);if(!Number.isInteger(s)||s<=0)throw new o(`defillama ${i} must be a positive integer`);if(s>e)throw new o(`defillama ${i} must be <= ${e}`);return s}export async function llamaFetch(r,t){let e;try{e=await fetch(r,{headers:{"user-agent":c,accept:"application/json"}})}catch(n){throw new a(`${t} request failed: ${n?.message??n}`,"Check that api.llama.fi is reachable from this network.")}if(e.status===404)throw new u(t,`DefiLlama returned 404 for ${r}.`);if(e.status===400){const n=await e.text().catch(()=>"");if(/not\s*found/i.test(n))throw new u(t,`DefiLlama: ${n.trim()||"not found"}.`);throw new a(`${t} returned HTTP 400: ${n.slice(0,200)}`)}if(e.status===429)throw new a(`${t} returned HTTP 429 (rate limited)`,"DefiLlama throttles unauthenticated traffic; wait a few seconds and retry.");if(!e.ok)throw new a(`${t} returned HTTP ${e.status}`);let i;try{i=await e.json()}catch(n){throw new a(`${t} returned malformed JSON: ${n?.message??n}`)}return i}export function unixToDate(r){if(r==null)return null;const t=typeof r==="number"?r:Number(r);if(!Number.isFinite(t)||t<=0)return null;const e=t>1000000000000?t:t*1000,i=new Date(e);if(Number.isNaN(i.getTime()))return null;return i.toISOString().slice(0,10)}
|
package/clis/devto/auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as t}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as i}from"../_shared/site-auth.js";const n="https://dev.to";async function a(o){return(await o.getCookies({url:n})).some((r)=>r.name==="remember_user_token"&&r.value)}async function s(o){await o.goto(n);const e=await o.evaluate(`(() => {
|
|
2
2
|
try {
|
|
3
3
|
var du = document.body && document.body.getAttribute('data-user');
|
|
4
4
|
if (!du) return { ok: false, reason: 'no data-user' };
|
|
@@ -6,4 +6,4 @@ import{AuthRequiredError as B}from"@jackwener/opencli/errors";import{registerSit
|
|
|
6
6
|
if (!u || u.id == null) return { ok: false, reason: 'anonymous' };
|
|
7
7
|
return { ok: true, id: String(u.id), username: String(u.username || ''), name: String(u.name || '') };
|
|
8
8
|
} catch (e) { return { ok: false, reason: String(e && e.message || e) }; }
|
|
9
|
-
})()`);if(!
|
|
9
|
+
})()`);if(!e||!e.ok)throw new t("dev.to",`Not logged in (${e?e.reason:"no probe"})`);return{user_id:e.id,username:e.username,name:e.name}}i({site:"devto",domain:"dev.to",loginUrl:"https://dev.to/enter",columns:["user_id","username","name"],loginDescription:"打开 dev.to 登录页并等待浏览器完成登录(供桌面客户端引导登录)。",quickCheck:a,verify:s,poll:async(o)=>{if(!await a(o))throw new t("dev.to","Waiting for dev.to session cookie");return s(o)}});
|
package/clis/devto/latest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as p,Strategy as m}from"@jackwener/opencli/registry";import{ArgumentError as
|
|
1
|
+
import{cli as p,Strategy as m}from"@jackwener/opencli/registry";import{ArgumentError as u,CommandExecutionError as i,EmptyResultError as g}from"@jackwener/opencli/errors";function c(n,s,r){const a=n??s,e=typeof a==="number"?a:Number(a);if(!Number.isInteger(e)||e<=0)throw new u("devto limit must be a positive integer");if(e>r)throw new u(`devto limit must be <= ${r}`);return e}p({site:"devto",name:"latest",access:"read",description:"Newest dev.to articles (firehose, all tags)",domain:"dev.to",strategy:m.PUBLIC,browser:!1,args:[{name:"limit",type:"int",default:20,help:"Articles per page (1-100)"},{name:"page",type:"int",default:1,help:"Page number (1-based)"}],columns:["rank","id","title","author","tags","reactions","comments","published","url"],func:async(n)=>{const s=c(n.limit,20,100),r=c(n.page,1,1000),a=`https://dev.to/api/articles/latest?per_page=${s}&page=${r}`;let e;try{e=await fetch(a,{headers:{accept:"application/json"}})}catch(t){throw new i(`devto latest request failed: ${t?.message??t}`,"Check that dev.to is reachable from this network.")}if(!e.ok)throw new i(`devto latest returned HTTP ${e.status}`);let o;try{o=await e.json()}catch(t){throw new i(`devto latest returned malformed JSON: ${t?.message??t}`)}const l=Array.isArray(o)?o:[];if(!l.length)throw new g("devto latest",`dev.to /articles/latest returned no items at page ${r}.`);return l.map((t,d)=>({rank:(r-1)*s+d+1,id:t.id!=null?String(t.id):"",title:String(t.title??""),author:String(t?.user?.username??""),tags:String(t.tag_list??"").replace(/,\s*/g,", "),reactions:t.public_reactions_count!=null?Number(t.public_reactions_count):null,comments:t.comments_count!=null?Number(t.comments_count):null,published:String(t.published_at??"").slice(0,10),url:String(t.url??"")}))}});
|
package/clis/devto/publish.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as c from"node:fs";import{cli as y,Strategy as g}from"@jackwener/opencli/registry";import{ArgumentError as a,AuthRequiredError as b,CommandExecutionError as d}from"@jackwener/opencli/errors";import{assertLiteralContent as S}from"../_shared/content-guard.js";const f=4;export function resolveBody(e){if(e["body-file"]){const t=String(e["body-file"]);if(!c.statSync(t,{throwIfNoEntry:!1})?.isFile())throw new a(`--body-file not found: ${t}`);return c.readFileSync(t,"utf8")}if(e.body!==void 0&&e.body!==null){S(String(e.body),{fileFlag:"--body-file"});return String(e.body)}return}export function resolveTagList(e){if(e===void 0||e===null||e==="")return;const t=String(e).split(",").map((i)=>i.trim().toLowerCase()).filter(Boolean);if(t.length>f)throw new a(`Too many tags: ${t.length} (DEV.to max ${f})`);for(const i of t)if(!/^[a-z0-9]+$/.test(i))throw new a(`Invalid tag "${i}". DEV.to tags must be lowercase alphanumeric (no spaces/punctuation).`);return t.join(", ")}export function buildArticle(e,t,i){const n={};if(e.title!==void 0)n.title=String(e.title);if(t!==void 0)n.body_markdown=t;if(e.published!==void 0)n.published=!!e.published;if(i!==void 0)n.tag_list=i;if(e["cover-image"])n.main_image=String(e["cover-image"]);if(e["canonical-url"])n.canonical_url=String(e["canonical-url"]);if(e.series)n.series=String(e.series);if(e.description)n.description=String(e.description);return n}y({site:"devto",name:"publish",access:"write",description:"Publish or update a DEV.to article (markdown). Draft by default; pass --published to go live.",domain:"dev.to",strategy:g.COOKIE,browser:!0,args:[{name:"title",type:"string",required:!1,help:"Article title (required for new articles)"},{name:"body",type:"string",required:!1,help:"Article body in Markdown (or use --body-file)"},{name:"body-file",type:"string",required:!1,help:"Path to a Markdown file for the body"},{name:"published",type:"boolean",required:!1,default:!1,help:"Publish live now (default: save as draft)"},{name:"tags",type:"string",required:!1,help:"Comma-separated tags, max 4, lowercase alphanumeric"},{name:"cover-image",type:"string",required:!1,help:"Cover image URL (main_image)"},{name:"canonical-url",type:"string",required:!1,help:"Canonical URL (original source)"},{name:"series",type:"string",required:!1,help:"Series name to group articles"},{name:"description",type:"string",required:!1,help:"Social/SEO description"},{name:"id",type:"string",required:!1,help:"Existing article id to update (PUT instead of POST)"}],columns:["status","id","url","published","slug"],func:async(e,t)=>{if(!e)throw new d("Browser session required for devto publish");const i=t.id?String(t.id).trim():"",n=resolveBody(t),p=resolveTagList(t.tags);if(!i&&!t.title)throw new a("--title is required when creating a new article");if(!i&&n===void 0)throw new a("--body or --body-file is required when creating a new article");const l=buildArticle(t,n,p),h=i?"PUT":"POST",m=i?`/articles/${encodeURIComponent(i)}`:"/articles";await e.goto("https://dev.to/");const r=await e.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
3
|
var csrf = (document.querySelector('meta[name="csrf-token"]') || {}).content || window.csrfToken;
|
|
4
4
|
if (!csrf) return { kind: 'auth', detail: 'no csrf-token meta — not logged in?' };
|
|
5
|
-
var r = await fetch(${JSON.stringify(
|
|
6
|
-
method: ${JSON.stringify(
|
|
5
|
+
var r = await fetch(${JSON.stringify(m)}, {
|
|
6
|
+
method: ${JSON.stringify(h)},
|
|
7
7
|
credentials: 'include',
|
|
8
8
|
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-CSRF-Token': csrf },
|
|
9
|
-
body: JSON.stringify({ article: ${JSON.stringify(
|
|
9
|
+
body: JSON.stringify({ article: ${JSON.stringify(l)} }),
|
|
10
10
|
});
|
|
11
11
|
var text = await r.text();
|
|
12
12
|
var data = null; try { data = JSON.parse(text); } catch (e) {}
|
|
@@ -14,4 +14,4 @@ import*as V from"node:fs";import{cli as q,Strategy as B}from"@jackwener/opencli/
|
|
|
14
14
|
if (!r.ok) return { kind: 'http', status: r.status, detail: text.slice(0, 300) };
|
|
15
15
|
return { kind: 'ok', data: data };
|
|
16
16
|
} catch (e) { return { kind: 'exception', detail: String(e && e.message || e) }; }
|
|
17
|
-
})()`);if(
|
|
17
|
+
})()`);if(r?.kind==="auth")throw new b("dev.to",`Not logged in (${r.detail}). Run \`ppcli devto login\`.`);if(r?.kind==="http")throw new d(`dev.to publish failed: HTTP ${r.status} ${r.detail}`);if(r?.kind==="exception")throw new d(`dev.to publish error: ${r.detail}`);if(r?.kind!=="ok"||!r.data)throw new d(`Unexpected dev.to response: ${JSON.stringify(r)}`);const o=r.data,u=!!l.published;let s="";if(o.current_state_path)try{s=new URL(o.current_state_path,"https://dev.to").href}catch(v){s=String(o.current_state_path)}else if(o.url)s=String(o.url);return[{status:i?"updated":"created",id:o.id??"",url:u?s:"",published:u,slug:o.slug??""}]}});
|
package/clis/devto/read.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as u,Strategy as m}from"@jackwener/opencli/registry";import{ArgumentError as d,CommandExecutionError as i,EmptyResultError as c}from"@jackwener/opencli/errors";const h="https://dev.to/api/articles";async function y(e){let r;try{r=await fetch(`${h}/${e}`)}catch(n){const t=n instanceof Error?n.message:String(n);throw new i(`DEV.to API request failed for article ${e}`,t)}if(r.status===404)throw new c(`devto/${e}`,"Article not found");if(!r.ok)throw new i(`DEV.to API HTTP ${r.status} for article ${e}`,"Check the article id");try{return await r.json()}catch{throw new i(`DEV.to API returned invalid JSON for article ${e}`,"Retry later or open the article URL directly")}}function f(e,r,n){const t=typeof e==="number"?e:Number(e);if(!Number.isInteger(t)||t<r)throw new d(`${n} must be an integer >= ${r}`);return t}function w(e,r){if(typeof e.body_markdown==="string"&&e.body_markdown.trim())return e.body_markdown;throw new i(`DEV.to article ${r} did not include body_markdown`,"DEV.to API response shape may have changed. Open the article URL directly or retry later.")}u({site:"devto",name:"read",access:"read",description:"Read a DEV.to article body by id",domain:"dev.to",strategy:m.PUBLIC,browser:!1,args:[{name:"id",required:!0,positional:!0,help:"DEV.to article id (numeric, e.g. 3605688)"},{name:"max-length",type:"int",default:20000,help:"Max characters of body to return (min 100)"}],columns:["id","title","author","reactions","reading_time","tags","published_at","body","url"],func:async(e)=>{const r=String(e.id||"").trim();if(!/^\d+$/.test(r))throw new d(`Invalid DEV.to article id: ${e.id}`,"Pass a numeric id like 3605688");const n=f(e["max-length"]??20000,100,"devto read --max-length"),t=await y(r);if(!t||!t.id)throw new c(`devto/${r}`,"Article not found");const o=w(t,r),s=o.length>n?o.slice(0,n)+`
|
|
2
2
|
|
|
3
|
-
... [truncated]`:
|
|
3
|
+
... [truncated]`:o,a=t.tag_list??t.tags??"",l=Array.isArray(a)?a.join(", "):String(a);return[{id:t.id,title:t.title||"",author:t.user?.username||"[deleted]",reactions:t.public_reactions_count??0,reading_time:t.reading_time_minutes??0,tags:l,published_at:t.published_at||"",body:s,url:t.url||""}]}});
|
package/clis/devto/stats.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as o,Strategy as n}from"@jackwener/opencli/registry";import{EmptyResultError as l}from"@jackwener/opencli/errors";const c="https://dev.to/dashboard";o({site:"devto",name:"stats",access:"read",description:"dev.to 文章数据(每篇浏览/反应/评论等运营指标,含草稿)。首次调用要拉起浏览器会话、偏慢,客户端超时属正常,重试一次即可",domain:"dev.to",strategy:n.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"limit",type:"number",default:20,help:"返回条数"}],columns:["id","type","title","url","published_at","views","likes","comments","collects","shares","tags","read_time","extra"],func:async(r,s)=>{const i=Math.max(1,Number(s.limit)||20);await r.goto(c);const t=await r.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
3
|
if (!location.href.includes('dev.to')) {
|
|
4
4
|
return { error: '未登录 dev.to(页面被重定向到 ' + location.href + '),请先在 Chrome 里登录 dev.to' };
|
|
5
5
|
}
|
|
6
|
-
const limit = ${JSON.stringify(
|
|
6
|
+
const limit = ${JSON.stringify(i)};
|
|
7
7
|
const items = [];
|
|
8
8
|
for (let pageNo = 1; items.length < limit && pageNo <= 50; pageNo++) {
|
|
9
9
|
const per = Math.min(100, limit - items.length + 1);
|
|
@@ -24,4 +24,4 @@ import{cli as C,Strategy as F}from"@jackwener/opencli/registry";import{EmptyResu
|
|
|
24
24
|
} catch (e) {
|
|
25
25
|
return { error: String((e && e.message) || e) };
|
|
26
26
|
}
|
|
27
|
-
})()`);if(!
|
|
27
|
+
})()`);if(!t||t.error)throw Error(t?.error||"devto stats:evaluate 无返回(浏览器会话异常)");const a=Array.isArray(t.items)?t.items:[];if(a.length===0)throw new l("devto stats","该 dev.to 账号没有任何文章(含草稿)。");return a.map((e)=>({id:String(e.id??""),type:"article",title:e.title||"",url:e.url||"",published_at:e.published_at||"",views:e.page_views_count??0,likes:e.public_reactions_count??0,comments:e.comments_count??0,collects:"",shares:"",tags:Array.isArray(e.tag_list)?e.tag_list.join("|"):String(e.tag_list||""),read_time:e.reading_time_minutes?`${e.reading_time_minutes}min`:"",extra:JSON.stringify({published:e.published??null,positive_reactions:e.positive_reactions_count??null,description:e.description||"",cover_image:e.cover_image||"",canonical_url:e.canonical_url||""})}))}});
|
package/clis/dianping/auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as t,CommandExecutionError as a}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as c}from"../_shared/site-auth.js";async function r(i){return(await i.getCookies({url:"https://www.dianping.com"})).some((n)=>n.name==="dper"&&n.value)}async function o(i){if(!await r(i))throw new t("dianping.com","Dianping dper cookie missing");await i.goto("https://www.dianping.com/citylist");await i.wait(2);const e=await i.evaluate("location.href");if(/account\.dianping\.com\/(pc)?login/.test(String(e||"")))throw new t("dianping.com",`Dianping page redirected to login: ${e}`);const n=await i.evaluate(`
|
|
2
2
|
(() => {
|
|
3
3
|
const trigger = document.querySelector('.userinfo-container .J-user-trigger, .userinfo-container a.username');
|
|
4
4
|
if (!trigger) return { loggedOut: true };
|
|
@@ -7,4 +7,4 @@ import{AuthRequiredError as F,CommandExecutionError as K}from"@jackwener/opencli
|
|
|
7
7
|
const uid = (String(href).match(/\\/member\\/(\\d+)/) || [])[1] || '';
|
|
8
8
|
return { user_id: uid, nickname };
|
|
9
9
|
})()
|
|
10
|
-
`);if(
|
|
10
|
+
`);if(n?.loggedOut)throw new t("dianping.com","Dianping session anonymous — no logged-in user trigger in top nav");if(!n?.user_id)throw new a("Dianping user trigger found but no /member/<id> href — layout drift");return{user_id:String(n.user_id),nickname:String(n.nickname||"")}}c({site:"dianping",domain:"dianping.com",loginUrl:"https://account.dianping.com/pclogin",columns:["user_id","nickname"],quickCheck:r,verify:o,poll:async(i)=>{if(!await r(i))throw new t("dianping.com","Waiting for Dianping dper cookie");return o(i)}});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as l,CommandExecutionError as f}from"@jackwener/opencli/errors";import{CITY_ID as w,resolveCityId as y}from"./utils.js";const u=/^[一-龥]+$/,d=/^[a-z]+$/,a=new Map;export function clearCityResolverCache(){a.clear()}export async function resolveCityIdAsync(n,e){if(e==null||e==="")return null;const t=String(e).trim();if(!t)return null;if(/^\d+$/.test(t))return Number(t);const c=t.toLowerCase();try{const i=y(t);if(i!=null)return i}catch(i){if(i?.code!=="ARGUMENT")throw i}if(a.has(c))return a.get(c);if(a.has(t))return a.get(t);let o=null;if(d.test(c))o=c;else if(u.test(t)){o=await h(n,t);if(!o){const i=Object.keys(w).filter((s)=>/^[a-z]+$/.test(s)).join(", ");throw new l("city",`unknown city '${e}'. pass a numeric cityId, a pinyin slug (e.g. shantou), a Chinese name listed on dianping.com/citylist, or one of: ${i}`)}}else{const i=Object.keys(w).filter((s)=>/^[a-z]+$/.test(s)).join(", ");throw new l("city",`unknown city '${e}'. pass a numeric cityId, a pinyin slug (e.g. shantou), a Chinese name listed on dianping.com/citylist, or one of: ${i}`)}const r=await m(n,o);if(!r)throw new f(`dianping could not resolve cityId for '${e}' (pinyin=${o}); the city page rendered without a /search/keyword/{id}/ link`);a.set(c,r);a.set(o,r);if(u.test(t))a.set(t,r);return r}export async function resolveDefaultCityId(n){await n.goto("https://www.dianping.com/");await n.wait(1);const e=await n.evaluate(`(() => {
|
|
2
2
|
const el = document.querySelector('.city-select-text, .city-select-content');
|
|
3
3
|
return el ? (el.textContent || '').trim() : '';
|
|
4
|
-
})()`);if(!
|
|
4
|
+
})()`);if(!e||!u.test(e))return null;return resolveCityIdAsync(n,e)}async function h(n,e){await n.goto("https://www.dianping.com/citylist");const t=await n.evaluate(`(${buildCitylistMap.toString()})()`);if(!t||typeof t!=="object"||Object.keys(t).length===0)throw new f("dianping citylist did not render any city anchors; cannot resolve Chinese city names");if(t&&typeof t==="object"&&t[e])return String(t[e]).toLowerCase();return null}export function buildCitylistMap(){const n={};document.querySelectorAll("a").forEach((t)=>{const c=t.getAttribute("href")||"",o=(t.textContent||"").trim();if(!o||!/^[一-龥]+$/.test(o))return;const r=c.replace(/^https?:/,""),i=r.match(/^\/\/(?:www\.)?dianping\.com\/([a-z]+)\/?$/)||r.match(/^\/([a-z]+)\/?$/);if(!i)return;const s=i[1].toLowerCase();if(s==="citylist"||s==="promo"||s==="events")return;if(!n[o])n[o]=s});return n}async function m(n,e){await n.goto(`https://www.dianping.com/${e}`);const t=await n.evaluate(`(${extractCityIdFromPage.toString()})()`);return Number.isInteger(t)&&t>0?t:null}export function extractCityIdFromPage(){const n=typeof location<"u"&&location.href||"https://www.dianping.com/",e=document.querySelectorAll("a[href]");for(const t of e){const c=t.getAttribute("href")||"";let o;try{o=new URL(c,n)}catch{continue}if(o.protocol!=="https:")continue;if(o.hostname!=="www.dianping.com"&&o.hostname!=="dianping.com")continue;const r=o.pathname.match(/^\/search\/keyword\/(\d+)(?:\/|$)/);if(!r)continue;const i=Number(r[1]);if(Number.isInteger(i)&&i>0)return i}return null}
|
package/clis/dianping/search.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as S,Strategy as C}from"@jackwener/opencli/registry";import{ArgumentError as x,CommandExecutionError as h}from"@jackwener/opencli/errors";import{SEARCH_COLUMNS as v,detectAuthOrPageFailure as q,parsePrice as b,parseReviewCount as k,requireSearchLimit as A,wrapDianpingStep as p}from"./utils.js";import{resolveCityIdAsync as _,resolveDefaultCityId as E}from"./cityResolver.js";export function extractSearchRows(){const i=document.querySelectorAll("#shop-all-list li");if(i.length===0){const t=document.body;return{ok:!1,sample:(t&&(t.innerText||t.textContent)||"").slice(0,800),url:location.href}}const o=[];i.forEach((t,u)=>{if(!(t.querySelector(".tit h4, .review-num, .mean-price, .tag-addr")||t.querySelector('.tit a, a[data-shopid], a[href*="/shop/"]')))return;const n=t.querySelector('.tit a[href*="/shop/"]')||t.querySelector("a[data-shopid]")||t.querySelector('a[href*="/shop/"]'),a=n&&n.getAttribute("data-shopid")||n&&(n.getAttribute("href")||"").match(/\/shop\/([^?#/]+)/)?.[1]||"",r=t.querySelector(".tit h4"),l=r&&r.textContent&&r.textContent.trim()||n&&n.getAttribute("title")||"",e=t.querySelector(".review-num b"),g=e&&e.textContent&&e.textContent.trim()||"",d=t.querySelector(".mean-price b"),f=d&&d.textContent&&d.textContent.trim()||"",m=Array.from(t.querySelectorAll(".tag-addr .tag")).map((s)=>s.textContent.trim()).filter(Boolean);let w="";const y=t.querySelector(".nebula_star");if(y){const s=y.outerHTML.match(/star_(\d{2})/g);if(s&&s.length)w=s[s.length-1].match(/star_(\d{2})/)[1]}o.push({rank:u+1,shop_id:a,name:l,starClass:w,reviewsRaw:g,priceRaw:f,cuisine:m[0]||"",district:m[1]||"",url:a?"https://www.dianping.com/shop/"+a:""})});return{ok:!0,rows:o}}S({site:"dianping",name:"search",access:"read",description:"大众点评店铺搜索(按关键词 + 城市)",domain:"www.dianping.com",strategy:C.COOKIE,args:[{name:"keyword",required:!0,positional:!0,help:'搜索关键词,例如 "火锅"'},{name:"city",help:"城市名(北京/上海/汕头/beijing/shantou/...)或 cityId 数字。未在静态表中的城市会通过 dianping.com 在线解析。不传则使用 cookie 默认城市"},{name:"limit",type:"int",default:15,help:"返回的店铺数量(最多 15,dianping 单页固定 15 条)"}],columns:v,func:async(i,o)=>{const t=String(o.keyword||"").trim();if(!t)throw new x("keyword","must be a non-empty string");const u=A(o.limit);let c=await p("city resolve",()=>_(i,o.city));if(c==null)c=await p("default city resolve",()=>E(i));if(c==null)throw new h("dianping search 需要城市:未传 --city 且无法确定默认城市。请显式指定,例如 --city 上海");const a=`https://www.dianping.com${`/search/keyword/${c}/0_${encodeURIComponent(t)}`}`;await p(`search "${t}" navigation`,async()=>{await i.goto(a);await i.wait(2)});const r=await p(`search "${t}" extraction`,()=>i.evaluate(`(${extractSearchRows.toString()})()`));if(!r||!r.ok)q({text:String(r?.sample||""),url:String(r?.url||a)},`search "${t}"`,{emptyPatterns:[/没有找到|暂无结果|暂无商户|换个关键词|未找到相关/i]});const l=(r.rows||[]).slice(0,u);if(l.length===0)throw new h("dianping search parser found no result-shaped shop cards");if(l.some((e)=>!e?.shop_id))throw new h("dianping search parser found result cards without shop_id values");return l.map((e)=>({rank:e.rank,shop_id:e.shop_id,name:e.name,rating:e.starClass?Number((Number(e.starClass)/10).toFixed(1)):null,reviews:k(e.reviewsRaw),price:b(e.priceRaw),cuisine:e.cuisine,district:e.district,url:e.url}))}});
|
package/clis/dianping/shop.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as S,Strategy as v}from"@jackwener/opencli/registry";import{SHOP_COLUMNS as k,detectAuthOrPageFailure as q,normalizeShopId as N,parsePrice as R,parseReviewCount as E,wrapDianpingStep as b}from"./utils.js";export function extractShopFields(){const a=document.querySelector(".shop-head");if(!a){const e=document.body;return{ok:!1,sample:(e&&(e.innerText||e.textContent)||"").slice(0,800),url:location.href}}const s=a.textContent.trim().replace(/\s+/g," "),o=document.querySelector(".shop-name, .shop-head h2, .shop-head h1");let i=o&&o.textContent&&o.textContent.trim()||"";if(!i){const r=(document.title||"").match(/【([^】]+)】/);if(r)i=r[1].trim()}const t=document.querySelector(".star-score"),l=t&&t.textContent&&t.textContent.trim()||"",d=Array.from(document.querySelectorAll(".shop-feature")).map((e)=>e.textContent.trim()).filter(Boolean),c=document.querySelector(".desc-info"),n=c&&c.textContent&&c.textContent.trim()||"",m=s.match(/距(?:地铁)?[^\s]+?步行\d+m/),h=m?m[0]:"",u=document.querySelector(".reviews, .review-num, .reviewCount, .reviewCountSentence");let p=u&&u.textContent&&u.textContent.trim()||"";if(!p){const e=document.querySelector(".review-title"),r=e&&e.textContent,y=r&&r.match(/评价\(([\d.,万]+)\)/);if(y)p=y[1]}const w=s.match(/[¥¥]\s*\d+(?:\.\d+)?/),f={},C=["口味","环境","服务","食材"];for(const e of C){const r=s.match(new RegExp(e+"[::]\\s*([0-9.]+)"));if(r)f[e]=Number(r[1])}const x=s.match(/营业中[^\s]*\d{1,2}:\d{2}-(?:次日)?\d{1,2}:\d{2}|今日休息|暂停营业/),g=s.match(/[^\s]+?(?:口味|人气|环境|服务)榜\s*[·•]\s*第\d+名/);return{ok:!0,name:i,rating:l,reviewsRaw:p,priceRaw:w&&w[0]||"",breakdown:f,features:d,address:n,subway:h,hours:x&&x[0]||"",rank:g&&g[0]||"",url:location.href}}S({site:"dianping",name:"shop",access:"read",aliases:["detail"],description:"大众点评店铺详情(按 shop_id)",domain:"www.dianping.com",strategy:v.COOKIE,args:[{name:"shop_id",required:!0,positional:!0,help:"店铺 ID(来自 search 的 shop_id 列,或 https://www.dianping.com/shop/<id> URL 段)"}],columns:k,func:async(a,s)=>{const o=N(s.shop_id),i=`https://www.dianping.com/shop/${o}`;await b(`shop ${o} navigation`,async()=>{await a.goto(i);await a.wait(3)});const t=await b(`shop ${o} extraction`,()=>a.evaluate(`(${extractShopFields.toString()})()`));if(!t||!t.ok)q({text:String(t?.sample||""),url:String(t?.url||i)},`shop ${o}`,{emptyPatterns:[/商户不存在|店铺不存在|店铺已关闭|页面不存在|404|已下线|没有找到相关商户/i]});const l=t.rating?Number(t.rating):null,d=E(t.reviewsRaw),c=R(t.priceRaw),n=t.breakdown||{};return[["shop_id",o],["name",t.name||""],["rating",Number.isFinite(l)?l:null],["reviews",d],["price",c],["rank",t.rank||""],["taste",Number.isFinite(n["口味"])?n["口味"]:null],["environment",Number.isFinite(n["环境"])?n["环境"]:null],["service",Number.isFinite(n["服务"])?n["服务"]:null],["ingredients",Number.isFinite(n["食材"])?n["食材"]:null],["hours",t.hours||""],["address",t.address||""],["subway",t.subway||""],["features",(t.features||[]).join(", ")],["url",t.url||i]].map(([h,u])=>({field:h,value:u}))}});
|
package/clis/dianping/utils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as a,AuthRequiredError as s,CommandExecutionError as u,EmptyResultError as h}from"@jackwener/opencli/errors";export const CITY_ID={beijing:2,"北京":2,shanghai:1,"上海":1,guangzhou:4,"广州":4,shenzhen:7,"深圳":7,hangzhou:3,"杭州":3,chengdu:8,"成都":8,chongqing:9,"重庆":9,nanjing:5,"南京":5,suzhou:6,"苏州":6,xian:17,"西安":17,wuhan:16,"武汉":16,tianjin:10,"天津":10,qingdao:21,"青岛":21,changsha:344,"长沙":344,dalian:19,"大连":19,shenyang:18,"沈阳":18,kunming:25,"昆明":25,fuzhou:110,"福州":110,xiamen:14,"厦门":14,hefei:26,"合肥":26},SEARCH_COLUMNS=["rank","shop_id","name","rating","reviews","price","cuisine","district","url"],SHOP_COLUMNS=["field","value"];export function resolveCityId(i){if(i==null||i==="")return null;const e=String(i).trim().toLowerCase();if(/^\d+$/.test(e))return Number(e);const n=CITY_ID[e];if(!n){const t=Object.keys(CITY_ID).filter((r)=>/^[a-z]+$/.test(r)).join(", ");throw new a("city",`unknown city '${i}'. pass a numeric cityId or one of: ${t}`)}return n}export function requireSearchLimit(i){const e=i==null||i===""?15:i,n=typeof e==="number"?e:Number(String(e).trim());if(!Number.isInteger(n)||n<1||n>15)throw new a("limit must be an integer between 1 and 15 (dianping single page)");return n}export function normalizeShopId(i){const e=String(i||"").trim();if(!e)throw new a("shop_id must be a non-empty string");const n=e.match(/\/shop\/([^?#/]+)/),t=n?n[1]:e;if(!/^[A-Za-z0-9_-]+$/.test(t))throw new a(`'${e}' does not look like a dianping shop id`);return t}export function wrapDianpingStep(i,e){return Promise.resolve().then(e).catch((n)=>{if(n?.code)throw n;const t=n?.message||String(n);throw new u(`dianping ${i} failed: ${t}`)})}export function detectAuthOrPageFailure({text:i="",url:e=""},n,{emptyPatterns:t=[]}={}){const r=`${e} ${i}`;if(/verify\.meituan\.com|verifyimg|身份核实|请依次点击|美团安全验证|Yoda/i.test(r))throw new s("dianping.com",`dianping ${n} blocked by captcha — open ${e||"www.dianping.com"} manually in this profile and solve the captcha, then retry`);if(/login\.dianping\.com|account\.dianping\.com|请先登录|未登录|请登录/.test(r))throw new s("dianping.com",`dianping ${n} requires login — sign in to dianping.com in this profile, then retry`);if(t.some((c)=>c.test(r)))throw new h(`dianping ${n}`);const o=i?`; sample: ${String(i).slice(0,160)}`:"";throw new u(`dianping ${n} did not render expected data${o}`,"This usually means dianping changed its HTML, returned an unexpected error page, or the browser profile hit an unrecognized anti-bot state.")}export function parseReviewCount(i){if(i==null)return null;const e=String(i).trim();if(!e)return null;const n=e.match(/^([\d.]+)\s*万/);if(n){const o=Number(n[1]);return Number.isFinite(o)?Math.round(o*1e4):null}const t=e.match(/(\d+(?:\.\d+)?)/);if(!t)return null;const r=Number(t[1]);return Number.isFinite(r)?Math.round(r):null}export function parsePrice(i){if(!i)return null;const e=String(i).match(/[¥¥]\s*(\d+(?:\.\d+)?)/);if(!e)return null;const n=Number(e[1]);return Number.isFinite(n)?n:null}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as a,Strategy as i}from"@jackwener/opencli/registry";import{CommandExecutionError as o}from"@jackwener/opencli/errors";function r(e){return`(async () => {
|
|
2
2
|
try {
|
|
3
|
-
const messageId = ${JSON.stringify(
|
|
3
|
+
const messageId = ${JSON.stringify(e)};
|
|
4
4
|
|
|
5
5
|
// Find the message element by its ID attribute (format: chat-messages-{channelId}-{messageId})
|
|
6
6
|
const msgEl = document.querySelector('[id$="-' + messageId + '"]');
|
|
@@ -63,4 +63,4 @@ import{cli as G,Strategy as H}from"@jackwener/opencli/registry";import{CommandEx
|
|
|
63
63
|
} catch (e) {
|
|
64
64
|
return { ok: false, message: e.toString() };
|
|
65
65
|
}
|
|
66
|
-
})()`}
|
|
66
|
+
})()`}a({site:"discord-app",name:"delete",access:"write",description:"Delete a message by its ID in the active Discord channel",domain:"localhost",strategy:i.UI,browser:!0,args:[{name:"message_id",type:"string",required:!0,positional:!0,help:"The ID of the message to delete (visible via Developer Mode or the read command)"}],columns:["status","message"],func:async(e,n)=>{if(!e)throw new o("Browser session required for discord-app delete");const t=n.message_id;if(!/^\d+$/.test(t))throw new o(`Invalid message ID: "${t}". A Discord message ID is a numeric snowflake (e.g. 1234567890123456789).`);await e.wait(0.5);const s=await e.evaluate(r(t));if(s.ok)await e.wait(1);return[{status:s.ok?"success":"failed",message:s.message}]}});export const __test__={buildDeleteScript:r};
|
package/clis/discord-app/read.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as o,Strategy as n}from"@jackwener/opencli/registry";import{EmptyResultError as d}from"@jackwener/opencli/errors";import{assertDiscordMessageRowsBelongToTarget as i,maybeNavigateToDiscordChannel as c,parsePositiveInt as l,readDiscordMessages as m}from"./utils.js";export const readCommand=o({site:"discord-app",name:"read",access:"read",description:"Read recent messages from the active or targeted Discord channel",domain:"localhost",strategy:n.UI,browser:!0,args:[{name:"count",required:!1,help:"Number of messages to read (default: 20)",default:"20"},{name:"guild",required:!1,help:"Guild/server id or visible name for targeted reads"},{name:"channel",required:!1,help:"Channel id or visible name for targeted reads"},{name:"url",required:!1,help:"Discord channel URL to open before reading"}],columns:["Author","Time","Message","channel_id","message_id"],func:async(e,r)=>{const s=l(r.count,20,"count"),t=await c(e,r,{waitForContent:"messages"}),a=i(await m(e,s),t,"Discord channel read");if(a.length===0)throw new d("discord-app read","No messages were found in the selected Discord channel.");return a}}),__test__={readCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as o,Strategy as d}from"@jackwener/opencli/registry";import{EmptyResultError as i}from"@jackwener/opencli/errors";import{assertDiscordMessageRowsBelongToTarget as n,navigateToDiscordTarget as c,parsePositiveInt as l,readDiscordMessages as m,resolveDiscordThreadTarget as h}from"./utils.js";export const threadReadCommand=o({site:"discord-app",name:"thread-read",access:"read",description:"Read recent messages from a Discord thread/post by id or URL",domain:"localhost",strategy:d.UI,browser:!0,args:[{name:"thread",required:!1,help:"Thread/post id, or a full Discord thread/post URL"},{name:"count",required:!1,default:"20",help:"Number of messages to read (default: 20)"},{name:"guild",required:!1,help:"Parent guild/server id or visible name"},{name:"channel",required:!1,help:"Parent forum/channel id or visible name"},{name:"url",required:!1,help:"Discord thread/post URL"}],columns:["Author","Time","Message","channel_id","message_id"],func:async(e,r)=>{const t=l(r.count,20,"count"),a=await h(e,r);await c(e,a,{waitForContent:"messages"});const s=n(await m(e,t),a,"Discord thread read");if(s.length===0)throw new i("discord-app thread-read","No messages were found in the selected Discord thread.");return s}}),__test__={threadReadCommand};
|
package/clis/discord-web/auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as e}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as a}from"../_shared/site-auth.js";const l="https://discord.com/channels/@me";async function c(t){return t.evaluate(`(() => {
|
|
2
2
|
if (/\\/login(\\b|\\/|\\?|$)/.test(location.pathname)) return null;
|
|
3
3
|
const panel = document.querySelector('[class*=panelTitleContainer]');
|
|
4
4
|
if (!panel) return null;
|
|
@@ -7,4 +7,4 @@ import{AuthRequiredError as z}from"@jackwener/opencli/errors";import{registerSit
|
|
|
7
7
|
const handle = handleEl ? (handleEl.textContent || '').trim() : '';
|
|
8
8
|
if (!display && !handle) return null;
|
|
9
9
|
return { display_name: display, username: handle || display };
|
|
10
|
-
})()`)}async function
|
|
10
|
+
})()`)}async function i(t){await t.goto(l);for(let o=0;o<8;o++){const r=await c(t);if(r)return r;await t.wait(1)}const n=await t.evaluate("location.href");if(/\/login/.test(String(n||"")))throw new e("discord.com","Discord redirected to /login — not signed in");throw new e("discord.com","Discord account panel not found — not signed in or app failed to load")}a({site:"discord-web",domain:"discord.com",loginUrl:"https://discord.com/login",columns:["username","display_name"],quickCheckRequiresNavigation:!0,quickCheck:async(t)=>{try{return{logged_in:!0,...await i(t)}}catch(n){if(n instanceof e)return{logged_in:!1};throw n}},verify:i,poll:async(t)=>i(t)});
|