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/jira/shared.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{adfToMarkdown as j,atlassianRequest as I,getJiraConfig as x,htmlToMarkdown as C,parseLimit as
|
|
1
|
+
import{adfToMarkdown as j,atlassianRequest as I,getJiraConfig as x,htmlToMarkdown as C,parseLimit as h,queryString as T,requireNonEmptyRows as b,requirePayloadArray as u,requirePayloadObject as a,requirePayloadString as c,requireString as N}from"../_atlassian/shared.js";import{ArgumentError as _}from"@jackwener/opencli/errors";const P=["summary","issuetype","status","priority","labels","description","comment","attachment","issuelinks","fixVersions","versions","components","project","reporter","assignee","created","updated"];function R(e){return`/rest/api/${e.deployment==="cloud"?"3":"2"}`}export function jiraApiPath(e,t,r){return`${R(e)}${t.startsWith("/")?t:`/${t}`}${r?T(r):""}`}export async function jiraRequest(e,t,r={}){return I(e,jiraApiPath(e,t,r.params),r)}function p(){return{acceptanceCriteria:process.env.ATLASSIAN_JIRA_ACCEPTANCE_FIELD?.trim()||"",sprint:process.env.ATLASSIAN_JIRA_SPRINT_FIELD?.trim()||"",storyPoints:process.env.ATLASSIAN_JIRA_STORY_POINTS_FIELD?.trim()||""}}function q(e=[]){const t=Object.values(p()).filter(Boolean);return[...new Set([...P,...t,...e.filter(Boolean)])].join(",")}export function parseJiraLimit(e,t=20,r=100){return h(e,t,r,"jira limit")}export function requireIssueKey(e){const t=N(e,"Jira issue key");if(!/^[A-Za-z][A-Za-z0-9_]+-\d+$/.test(t))throw new _(`Invalid Jira issue key: ${t}`,"Expected a key like PROJECT-123.");return t.toUpperCase()}function f(e){if(!e||typeof e!=="object")return"";return String(e.displayName??e.name??e.emailAddress??e.accountId??"")}function d(e){if(!e)return"";if(typeof e==="string")return e;if(typeof e==="object")return String(e.name??e.value??e.key??e.id??"");return String(e)}function l(e){return Array.isArray(e)?e.map(d).filter(Boolean):[]}export function jiraBodyToMarkdown(e,t){if(t)return C(t);if(e&&typeof e==="object")return j(e);if(typeof e==="string")return e.trim();return""}export function normalizeComment(e){const t=a(e,"jira comment");return{id:c(t.id,"comment id","jira comment"),author:f(t.author),created:t.created?String(t.created):"",updated:t.updated?String(t.updated):void 0,markdown:jiraBodyToMarkdown(t.body,t.renderedBody)}}export function normalizeAttachment(e){const t=a(e,"jira attachment");return{id:c(t.id,"attachment id","jira attachment"),filename:c(t.filename,"filename","jira attachment"),mimeType:t.mimeType?String(t.mimeType):void 0,size:t.size!=null?Number(t.size):void 0,url:c(t.content??t.self,"attachment url","jira attachment")}}export function normalizeIssueLink(e){const t=a(e,"jira issue link"),r=t.outwardIssue,i=t.inwardIssue;return{key:c((r??i??{}).key,"linked issue key","jira issue link"),type:String(t.type?.name??(r?t.type?.outward:t.type?.inward)??""),direction:r?"outward":"inward"}}function A(e){if(!e)return"";if(typeof e==="string")return e.trim();if(e&&typeof e==="object"&&e.type==="doc")return j(e);if(Array.isArray(e))return e.map(d).filter(Boolean).join(", ");return d(e)}function E(e,t,r){if(r.comments!==void 0)return u(r.comments,`jira issue ${t} comments`);if(r.requireNestedCollections===!1)return[];const i=a(e.comment,`jira issue ${t} comment field`);return u(i.comments,`jira issue ${t} comment field comments`)}export function normalizeJiraIssue(e,t,r={}){const i=a(e,"jira issue"),o=c(i.key,"issue key","jira issue"),n=a(i.fields,`jira issue ${o} fields`),S=i.renderedFields&&typeof i.renderedFields==="object"&&!Array.isArray(i.renderedFields)?i.renderedFields:{},s=p(),g=E(n,o,r),y=r.requireNestedCollections!==!1,w=y?u(n.attachment,`jira issue ${o} attachment field`):[],k=y?u(n.issuelinks,`jira issue ${o} issuelinks field`):[],m={key:o,id:i.id!=null?String(i.id):"",url:`${t.baseUrl}/browse/${o}`,summary:String(n.summary??""),issueType:d(n.issuetype)||void 0,status:d(n.status)||void 0,priority:d(n.priority)||void 0,project:d(n.project)||void 0,reporter:f(n.reporter)||void 0,assignee:f(n.assignee)||void 0,labels:Array.isArray(n.labels)?n.labels.map(String):[],description:{raw:n.description??null,markdown:jiraBodyToMarkdown(n.description,S.description)},comments:g.map(normalizeComment),attachments:w.map(normalizeAttachment),linkedIssues:k.map(normalizeIssueLink),fixVersions:l(n.fixVersions),affectedVersions:l(n.versions),components:l(n.components),created:n.created?String(n.created):void 0,updated:n.updated?String(n.updated):void 0};if(s.acceptanceCriteria&&n[s.acceptanceCriteria]!==void 0)m.acceptanceCriteria={raw:n[s.acceptanceCriteria],markdown:A(n[s.acceptanceCriteria])};if(s.sprint&&n[s.sprint]!==void 0)m.sprint=A(n[s.sprint]);if(s.storyPoints&&n[s.storyPoints]!==void 0)m.storyPoints=Number(n[s.storyPoints]);return m}export function issueSummaryRow(e,t){const r=normalizeJiraIssue(e,t,{comments:[],requireNestedCollections:!1});return{key:r.key,summary:r.summary,issueType:r.issueType,status:r.status,priority:r.priority,assignee:r.assignee,updated:r.updated,url:r.url}}export async function fetchIssue(e,t,r=[]){const i=await jiraRequest(e,`/issue/${encodeURIComponent(t)}`,{params:{fields:q(r),expand:"renderedFields"},label:`jira issue ${t}`});return a(i,`jira issue ${t}`)}export async function fetchComments(e,t,r=100){const i=parseJiraLimit(r,100,100),o=await jiraRequest(e,`/issue/${encodeURIComponent(t)}/comment`,{params:{startAt:0,maxResults:i,expand:"renderedBody"},label:`jira comments ${t}`}),n=a(o,`jira comments ${t}`);return u(n.comments,`jira comments ${t}`)}export function jiraRowsOrEmpty(e,t,r){return b(e,t,r)}export function jiraConfig(){return x()}export const __test__={configuredFieldNames:p,fetchIssue,issueSummaryRow,jiraApiPath,jiraBodyToMarkdown,normalizeAttachment,normalizeComment,normalizeIssueLink,normalizeJiraIssue,requireIssueKey};
|
package/clis/juejin/article.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{CliError as
|
|
1
|
+
import{CliError as U,CommandExecutionError as ft}from"@jackwener/opencli/errors";import{cli as gt,Strategy as ht}from"@jackwener/opencli/registry";import{publishArticle as yt}from"../_shared/article/publish.js";export const juejinProfile={home:"https://juejin.cn",outputFormat:"markdown",checkAuth:async(a)=>{try{const t=await(await fetch("https://api.juejin.cn/user_api/v1/user/get",{method:"GET",credentials:"include"})).json();if(t&&t.data&&t.data.user_id)return{isAuthenticated:!0,userId:t.data.user_id,username:t.data.user_name||"",avatar:t.data.avatar_large||""};return{isAuthenticated:!1}}catch(e){return{isAuthenticated:!1,error:String(e&&e.message||e)}}},image:{skip:["juejin.cn","p1-juejin","p3-juejin","p6-juejin","p9-juejin","byteimg.com"],uploadFn:async(a,e)=>{async function t(r,g){const A=r instanceof Uint8Array?r:new Uint8Array(r),h=await crypto.subtle.importKey("raw",A.buffer,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return crypto.subtle.sign("HMAC",h,new TextEncoder().encode(g))}async function d(r){const g=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(r));return Array.from(new Uint8Array(g)).map((A)=>A.toString(16).padStart(2,"0")).join("")}function u(r){return Array.from(new Uint8Array(r)).map((g)=>g.toString(16).padStart(2,"0")).join("")}async function p(r,g,A,h,b){const E=new URL(g),at=E.pathname,rt=Array.from(E.searchParams.entries()).sort((k,C)=>k[0].localeCompare(C[0])).map(([k,C])=>encodeURIComponent(k)+"="+encodeURIComponent(C)).join("&"),M=new Date,F=M.toISOString().replace(/[:-]|\.\d{3}/g,""),V=M.toISOString().slice(0,10).replace(/-/g,""),N={"x-amz-date":F};if(b)N["x-amz-security-token"]=b;const q=Object.keys(N).map((k)=>k.toLowerCase()).sort().join(";"),nt=Object.entries(N).map(([k,C])=>k.toLowerCase()+":"+C.trim()).sort().join(`
|
|
2
2
|
`)+`
|
|
3
|
-
`,
|
|
4
|
-
`),
|
|
5
|
-
`),
|
|
3
|
+
`,ot=await d(""),st=[r.toUpperCase(),at||"/",rt,nt,q,ot].join(`
|
|
4
|
+
`),G="cn-north-1",z="imagex",B="AWS4-HMAC-SHA256",J=V+"/"+G+"/"+z+"/aws4_request",it=await d(st),ct=[B,F,J,it].join(`
|
|
5
|
+
`),lt=await t(new TextEncoder().encode("AWS4"+h),V),dt=await t(lt,G),ut=await t(dt,z),pt=await t(ut,"aws4_request"),mt=u(await t(pt,ct)),X={authorization:B+" Credential="+A+"/"+J+", SignedHeaders="+q+", Signature="+mt,"x-amz-date":F};if(b)X["x-amz-security-token"]=b;return X}function x(r){let g=4294967295;const A=new Uint32Array(256);for(let h=0;h<256;h++){let b=h;for(let E=0;E<8;E++)b=b&1?3988292384^b>>>1:b>>>1;A[h]=b}for(let h=0;h<r.length;h++)g=g>>>8^A[(g^r[h])&255];return((g^4294967295)>>>0).toString(16).padStart(8,"0")}const i="2608",y="73owjymdk6",_=Date.now().toString(16)+Math.random().toString(16).slice(2);let n;if(a.indexOf("data:")===0)n=await fetch(a).then(function(r){return r.blob()});else{const r=await fetch(a,{method:"GET"});if(!r.ok)throw Error("下载图片失败: "+r.status);n=await r.blob()}const S="https://api.juejin.cn/imagex/v2/gen_token?aid="+i+"&uuid="+_+"&client=web",m=await(await fetch(S,{method:"GET",credentials:"include",headers:{"Content-Type":"application/json"}})).json();if(m.err_no&&m.err_no!==0)throw Error("获取 ImageX 凭证失败: "+(m.err_msg||m.err_no));const j=m.data&&m.data.token;if(!j||!j.AccessKeyId||!j.SecretAccessKey)throw Error("ImageX 凭证响应无效");const{AccessKeyId:c,SecretAccessKey:R,SessionToken:s}=j,f="https://imagex.bytedanceapi.com/?Action=ApplyImageUpload&Version=2018-08-01&ServiceId="+y,o=await p("GET",f,c,R,s),I=await(await fetch(f,{method:"GET",headers:o})).json(),w=I&&I.Result&&I.Result.UploadAddress;if(!w)throw Error("申请上传地址失败");const P=w.StoreInfos&&w.StoreInfos[0],O=w.UploadHosts&&w.UploadHosts[0];if(!P||!O)throw Error("上传地址无效");const W=w.SessionKey,Q=await n.arrayBuffer(),Y=new Uint8Array(Q),Z=x(Y),tt="https://"+O+"/"+P.StoreUri,D=await fetch(tt,{method:"PUT",headers:{Authorization:P.Auth,"Content-Type":n.type||"application/octet-stream","Content-CRC32":Z},body:n});if(!D.ok){const r=await D.text();throw Error("TOS 上传失败: "+D.status+" "+r.slice(0,100))}const H="https://imagex.bytedanceapi.com/?Action=CommitImageUpload&Version=2018-08-01&SessionKey="+encodeURIComponent(W)+"&ServiceId="+y,L=await p("POST",H,c,R,s);L["Content-Length"]="0";if(!(await(await fetch(H,{method:"POST",headers:L})).json()).Result)throw Error("提交图片上传失败");const et=P.StoreUri,T=await(await fetch("https://api.juejin.cn/imagex/v2/get_img_url?aid="+i+"&uuid="+_+"&uri="+encodeURIComponent(et)+"&img_type=private",{method:"GET",credentials:"include",headers:{"Content-Type":"application/json"}})).json();if(T.err_no&&T.err_no!==0)throw Error("获取图片 URL 失败: "+(T.err_msg||T.err_no));const K=T.data&&(T.data.main_url||T.data.backup_url);if(!K)throw Error("图片 URL 响应无效");return{url:K}}},publish:async(a,e)=>{const t=a.params||{},d=typeof t.cover==="string"?t.cover.trim():"";let u="";try{const f=(await fetch("https://api.juejin.cn/user_api/v1/sys/token",{method:"HEAD",credentials:"include",headers:{"x-secsdk-csrf-request":"1","x-secsdk-csrf-version":"1.2.10"}})).headers.get("x-ware-csrf-token");if(f){const o=f.split(",");if(o.length>=2)u=o[1]}}catch(s){}const p={"Content-Type":"application/json"};if(u)p["x-secsdk-csrf-token"]=u;let x="0";if(t.category){let s=[];try{const l=await(await fetch("https://api.juejin.cn/tag_api/v1/query_category_briefs",{method:"GET",credentials:"include"})).json();s=l&&l.data||[]}catch(o){return{ok:!1,stage:"category",message:"获取掘金分类列表失败:"+String(o&&o.message||o)}}const f=s.find((o)=>o.category_name===t.category);if(!f)return{ok:!1,stage:"category",message:"未找到分类「"+t.category+"」,可选:"+s.map((o)=>o.category_name).join(" / ")};x=String(f.category_id)}const i=[];if(t.tags&&t.tags.length)for(const s of t.tags){let f=[];try{const I=await(await fetch("https://api.juejin.cn/tag_api/v1/query_tag_list",{method:"POST",credentials:"include",headers:p,body:JSON.stringify({cursor:"0",key_word:s,limit:20,sort_type:1})})).json();f=(I&&I.data||[]).map((w)=>w&&w.tag?w.tag:w)}catch(l){return{ok:!1,stage:"tag",message:"搜索标签「"+s+"」失败:"+String(l&&l.message||l)}}const o=f.find((l)=>String(l.tag_name||"").toLowerCase()===String(s).toLowerCase());if(!o){const l=f.slice(0,8).map((I)=>I.tag_name).filter(Boolean).join(" / ");return{ok:!1,stage:"tag",message:"未找到标签「"+s+"」(精确名匹配)"+(l?";相近:"+l:"")}}i.push(String(o.tag_id))}if(!a.draftOnly){if(x==="0")return{ok:!1,stage:"validate",message:"发布掘金文章必须指定分类:--category <后端|前端|Android|iOS|人工智能|开发工具|代码人生|阅读>"};if(!i.length)return{ok:!1,stage:"validate",message:"发布掘金文章必须指定标签:--tags <标签名,标签名>(至少一个,按名精确匹配)"};if(!String(t.brief||"").trim())return{ok:!1,stage:"validate",message:"发布掘金文章必须填写摘要:--brief <摘要>(掘金要求约 50-100 字,不可留空)"}}const y=await fetch("https://api.juejin.cn/content_api/v1/article_draft/create",{method:"POST",credentials:"include",headers:p,body:JSON.stringify({brief_content:t.brief||"",category_id:x,cover_image:d,edit_type:10,html_content:"",link_url:"",mark_content:a.content,tag_ids:i,theme_ids:[],title:a.title})}),_=await y.text();let n=null;try{n=JSON.parse(_)}catch(s){}if(!y.ok)return{ok:!1,stage:"create",status:y.status,message:_.slice(0,300)};if(n&&n.err_no&&n.err_no!==0)return{ok:!1,stage:"create",status:y.status,message:n.err_msg||"创建草稿失败: err_no="+n.err_no};if(!n||!n.data||!n.data.id)return{ok:!1,stage:"create",status:y.status,message:_.slice(0,300)};const S=String(n.data.id),v="https://juejin.cn/editor/drafts/"+S;if(a.draftOnly)return{ok:!0,draft:!0,id:S,url:v};const m=await fetch("https://api.juejin.cn/content_api/v1/article/publish",{method:"POST",credentials:"include",headers:p,body:JSON.stringify({draft_id:S,sync_to_org:!1,column_ids:[]})}),j=await m.text();let c=null;try{c=JSON.parse(j)}catch(s){}if(!m.ok)return{ok:!1,stage:"publish",status:m.status,message:j.slice(0,300),id:S,url:v};if(c&&c.err_no&&c.err_no!==0)return{ok:!1,stage:"publish",status:m.status,message:c.err_msg||"发布失败: err_no="+c.err_no,id:S,url:v};const R=c&&c.data&&String(c.data.article_id||c.data.id||"");if(!R)return{ok:!1,stage:"publish",status:m.status,message:j.slice(0,300),id:S,url:v};return{ok:!0,draft:!1,id:R,url:"https://juejin.cn/post/"+R}}};import{readFile as wt,stat as _t}from"node:fs/promises";function St(a){if(!a.execute)throw new U("INVALID_INPUT","此命令需要 --execute 参数才能执行写操作。注意:本报错仅表示缺少 --execute,并未校验其余参数,不能当 dry-run 预览用")}async function jt(a){const e=typeof a.text==="string"?a.text:void 0,t=typeof a.file==="string"?a.file:void 0;if(e&&t)throw new U("INVALID_INPUT","不能同时指定正文参数和 --file,请二选一");let d=e??"";if(t){let u;try{u=await _t(t)}catch{throw new U("INVALID_INPUT","文件不存在: "+t)}if(!u.isFile())throw new U("INVALID_INPUT","必须是可读的文本文件: "+t);let p;try{p=await wt(t)}catch{throw new U("INVALID_INPUT","无法读取文件: "+t)}try{d=new TextDecoder("utf-8",{fatal:!0}).decode(p)}catch{throw new U("INVALID_INPUT","文件必须是 UTF-8 编码: "+t)}}if(!d.trim())throw new U("INVALID_INPUT","正文不能为空");return d}function bt(a,e,t,d,u={}){return[{status:"success",outcome:d,message:a,target_type:e,target:t,...u}]}gt({site:"juejin",name:"article",access:"write",description:"发布掘金文章。默认正式发布(需 --category 和 --tags);加 --draft 仅存草稿。正文默认 Markdown;正文图片与 --cover 封面自动转存至掘金图床(字节 ImageX)。",domain:"juejin.cn",strategy:ht.COOKIE,browser:!0,args:[{name:"title",positional:!0,required:!0,help:"文章标题"},{name:"text",positional:!0,help:"文章正文(默认 Markdown;传 --html 则视为 HTML)"},{name:"file",help:"正文文件路径(UTF-8 编码,默认 Markdown)"},{name:"html",type:"boolean",help:"将正文视为原始 HTML 而非 Markdown"},{name:"category",help:"【正式发布必填】分类名(精确匹配):后端 / 前端 / Android / iOS / 人工智能 / 开发工具 / 代码人生 / 阅读"},{name:"tags",help:'【正式发布必填】标签名,逗号分隔,至少一个(按名精确匹配掘金标签库,如 "Linux,后端")'},{name:"brief",help:"【正式发布必填】文章摘要,掘金要求约 50-100 字(不做自动截取,必须显式提供)"},{name:"cover",help:"封面图(本机绝对路径或图片 URL),自动转存至掘金图床后设为文章封面"},{name:"draft",type:"boolean",help:"仅保存草稿,不发布(草稿无需分类/标签)"},{name:"execute",type:"boolean",help:"确认执行写操作。不加此参数则拒绝写入。"}],columns:["status","outcome","message","target_type","target","created_target","created_url"],func:async(a,e)=>{if(!a)throw new ft("掘金文章发布需要浏览器会话");St(e);const t=String(e.title??"").trim();if(!t)throw new U("INVALID_INPUT","文章标题不能为空");const d=await jt(e),u=Boolean(e.draft),p=String(e.tags??"").split(",").map((S)=>S.trim()).filter(Boolean),x={category:typeof e.category==="string"?e.category.trim():"",tags:p,brief:typeof e.brief==="string"?e.brief:"",cover:typeof e.cover==="string"?e.cover.trim():""},i=await yt(a,{title:t,body:d,format:e.html?"html":"markdown",draftOnly:u,profile:juejinProfile,publishParams:x}),y=i.images.uploaded.length|0,_=i.images.failed.length|0;let n=i.draft?"草稿已保存至掘金(需在编辑器内手动发布)":"文章已正式发布至掘金";if(y||_)n+=";图片:"+y+" 张已转存"+(_?","+_+" 张失败":"");return bt(n,"article","",i.draft?"draft":"publish",{created_target:"article:"+i.id,created_url:i.url})}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as a,Strategy as i}from"@jackwener/opencli/registry";import{CommandExecutionError as r}from"@jackwener/opencli/errors";import{gotoWritePage as n}from"../_shared/article/publish.js";a({site:"juejin",name:"categories",access:"read",description:"列出掘金全部文章分类(id + 名称),供 `juejin article --category` 取准确分类名。",domain:"juejin.cn",strategy:i.COOKIE,browser:!0,columns:["category_id","category_name"],func:async(t)=>{if(!t)throw new r("掘金分类列举需要浏览器会话");await n(t,c());const e=await t.evaluate("(async () => {const r = await fetch('https://api.juejin.cn/tag_api/v1/query_category_briefs', { credentials: 'include' });const j = await r.json();return (j && j.data || []).map(c => ({ category_id: String(c.category_id), category_name: c.category_name }));})()");if(!Array.isArray(e)||!e.length)throw new r("未取到掘金分类(可能未登录掘金)");return e}});function c(){return"https://juejin.cn"}
|
package/clis/juejin/hot.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as l,Strategy as s}from"@jackwener/opencli/registry";import{CATEGORY_ALIASES as t,juejinFetch as u,mapHotItem as d,readDataArray as m,requireBoundedInt as p,resolveCategory as y}from"./utils.js";l({site:"juejin",name:"hot",access:"read",description:"Juejin (掘金) hot article ranking, optionally scoped to a category",domain:"api.juejin.cn",strategy:s.PUBLIC,browser:!1,args:[{name:"category",type:"string",required:!1,help:`Category slug or numeric id. Slugs: ${Object.keys(t).join(", ")}. Defaults to "backend".`},{name:"limit",type:"int",default:20,help:"Max articles (1-50)."}],columns:["rank","article_id","title","brief","views","likes","comments","hot_rank","author","url"],func:async(e)=>{const a=y(e.category)||t.backend,n=p(e.limit,20,50),o=`/content_api/v1/content/article_rank?category_id=${encodeURIComponent(a)}&type=hot`,i=await u(o,null,"juejin hot","GET");return m(i,"juejin hot").slice(0,n).map((r,c)=>d(r,c+1))}});
|
package/clis/juejin/login.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{registerArticleLogin as
|
|
1
|
+
import{registerArticleLogin as e}from"../_shared/article/login.js";import{juejinProfile as i}from"./article.js";e({site:"juejin",domain:"juejin.cn",profile:{home:i.home,originRe:i.originRe,checkAuth:i.checkAuth},loginDescription:"打开掘金首页并等待浏览器完成登录(供桌面客户端引导登录)。"});
|
package/clis/juejin/recommend.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as l,Strategy as d}from"@jackwener/opencli/registry";import{CommandExecutionError as o}from"@jackwener/opencli/errors";import{juejinFetch as p,mapFeedItem as h,readDataArray as f,requireBoundedInt as _,requireCursor as a}from"./utils.js";function j(r){if(r==null||r==="")return"";try{return a(r)}catch{throw new o("juejin recommend returned a malformed cursor")}}l({site:"juejin",name:"recommend",access:"read",description:"Juejin (掘金) homepage recommended article feed",domain:"api.juejin.cn",strategy:d.PUBLIC,browser:!1,args:[{name:"limit",type:"int",default:20,help:"Max articles (1-100, single page)."},{name:"cursor",type:"string",default:"0",help:"Pagination cursor; pass back the previous response's next-page cursor to keep scrolling."}],columns:["rank","article_id","title","brief","views","likes","comments","author","tags","url","next_cursor","has_more"],func:async(r)=>{const t=_(r.limit,20,100),s=a(r.cursor),e=await p("/recommend_api/v1/article/recommend_all_feed",{id_type:2,client_type:2608,sort_type:200,limit:t,cursor:s},"juejin recommend"),i=f(e,"juejin recommend"),n=j(e.cursor);if(e.has_more!=null&&typeof e.has_more!=="boolean")throw new o("juejin recommend returned a malformed has_more flag");const m=e.has_more==null?"":String(e.has_more);if(e.has_more===!0&&!n)throw new o("juejin recommend returned has_more without a next cursor");return i.slice(0,t).map((c,u)=>({...h(c,u+1),next_cursor:n,has_more:m}))}});
|
package/clis/juejin/stats.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as d,Strategy as m}from"@jackwener/opencli/registry";import{EmptyResultError as p}from"@jackwener/opencli/errors";const _="https://juejin.cn/creator/data/content/article/single";d({site:"juejin",name:"stats",access:"read",description:"掘金文章数据(每篇展现/阅读/点赞/评论/收藏/阅读比/热度等全量运营指标)。首次调用要拉起浏览器会话、偏慢,客户端超时属正常,重试一次即可",domain:"juejin.cn",strategy:m.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","displays","read_ratio","hot_index","category","tags","read_time","extra"],func:async(n,c)=>{const l=Math.max(1,Number(c.limit)||20);await n.goto(_);const s=await n.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
3
|
if (!location.href.includes('juejin.cn')) {
|
|
4
4
|
return { error: '未登录掘金(页面被重定向到 ' + location.href + '),请先在 Chrome 里登录 juejin.cn' };
|
|
@@ -28,7 +28,7 @@ import{cli as K,Strategy as M}from"@jackwener/opencli/registry";import{EmptyResu
|
|
|
28
28
|
return { error: '拿不到掘金接口参数(页面尚未发出任何 api.juejin.cn 请求),请重试' };
|
|
29
29
|
}
|
|
30
30
|
// 分页拉取单篇数据(page_size/audit_status 逐字复刻页面真实请求)
|
|
31
|
-
const limit = ${JSON.stringify(
|
|
31
|
+
const limit = ${JSON.stringify(l)};
|
|
32
32
|
const items = [];
|
|
33
33
|
let total = Infinity;
|
|
34
34
|
for (let pageNo = 1; items.length < Math.min(limit, total) && pageNo <= 100; pageNo++) {
|
|
@@ -50,4 +50,4 @@ import{cli as K,Strategy as M}from"@jackwener/opencli/registry";import{EmptyResu
|
|
|
50
50
|
} catch (e) {
|
|
51
51
|
return { error: String((e && e.message) || e) };
|
|
52
52
|
}
|
|
53
|
-
})()`);if(!
|
|
53
|
+
})()`);if(!s||s.error)throw Error(s?.error||"juejin stats:evaluate 无返回(浏览器会话异常)");const o=Array.isArray(s.items)?s.items:[];if(o.length===0)throw new p("juejin stats","该掘金账号没有任何文章数据(含审核中/未通过)。");const u=(e)=>{const t=Number(e);if(!Number.isFinite(t)||t<=0)return"";const i=new Date(t*1000+28800000),r=(a)=>String(a).padStart(2,"0");return`${i.getUTCFullYear()}-${r(i.getUTCMonth()+1)}-${r(i.getUTCDate())} ${r(i.getUTCHours())}:${r(i.getUTCMinutes())}`};return o.map((e)=>{const t=e.article_info||{},i=t.view_count??0,r=t.display_count??0;return{id:e.article_id||t.article_id||"",type:"article",title:t.title||"",url:e.article_id?`https://juejin.cn/post/${e.article_id}`:"",published_at:u(t.ctime),views:i,likes:t.digg_count??0,comments:t.comment_count??0,collects:t.collect_count??0,shares:"",displays:r,read_ratio:r>0?`${(i/r*100).toFixed(1)}%`:"",hot_index:t.hot_index??0,category:e.category&&e.category.category_name||"",tags:(e.tags||[]).map((a)=>a.tag_name||"").filter(Boolean).join("|"),read_time:t.read_time||"",extra:JSON.stringify({brief:t.brief_content||"",audit_status:t.audit_status,verify_status:t.verify_status,status:t.status,updated_at:u(t.mtime),is_original:t.is_original})}})}});
|
package/clis/juejin/tags.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as e,Strategy as n}from"@jackwener/opencli/registry";import{CliError as o,CommandExecutionError as s}from"@jackwener/opencli/errors";import{gotoWritePage as c}from"../_shared/article/publish.js";e({site:"juejin",name:"tags",access:"read",description:"按关键词搜索掘金标签,返回标签 id 和名称,供 `juejin article --tags` 取准确标签名。",domain:"juejin.cn",strategy:n.COOKIE,browser:!0,args:[{name:"keyword",positional:!0,required:!0,help:'标签搜索关键词,如 "Linux"、"AI"'}],columns:["tag_id","tag_name"],func:async(t,i)=>{if(!t)throw new s("掘金标签搜索需要浏览器会话");const r=String(i.keyword??"").trim();if(!r)throw new o("INVALID_INPUT","请提供标签搜索关键词");await c(t,"https://juejin.cn");const a=await t.evaluate("(async () => {const r = await fetch('https://api.juejin.cn/tag_api/v1/query_tag_list', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ cursor: '0', key_word: "+JSON.stringify(r)+", limit: 20, sort_type: 1 }),});const j = await r.json();return ((j && j.data) || []).map(x => { const t = (x && x.tag) ? x.tag : x; return { tag_id: String(t.tag_id || ''), tag_name: t.tag_name || '' }; });})()");return Array.isArray(a)?a:[]}});
|
package/clis/juejin/utils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as a,CommandExecutionError as s,EmptyResultError as j}from"@jackwener/opencli/errors";export const JUEJIN_API_BASE="https://api.juejin.cn",JUEJIN_POST_URL="https://juejin.cn/post",JUEJIN_USER_URL="https://juejin.cn/user";const w="opencli-juejin-adapter (+https://github.com/jackwener/OpenCLI)",f=/^\d{16,20}$/;export const CATEGORY_ALIASES={backend:"6809637769959178254",frontend:"6809637767543259144",android:"6809635626879549454",ios:"6809635626661445640",ai:"6809637773935378440"};export function requireString(e,t){const r=String(e??"").trim();if(!r)throw new a(`juejin ${t} cannot be empty`);return r}export function requireBoundedInt(e,t,r,n="limit"){const u=e??t;let i;if(typeof u==="number")i=u;else if(typeof u==="string"&&/^[1-9]\d*$/.test(u))i=Number(u);else throw new a(`juejin ${n} must be a positive decimal integer`);if(!Number.isSafeInteger(i)||i<=0)throw new a(`juejin ${n} must be a positive integer`);if(i>r)throw new a(`juejin ${n} must be <= ${r}`);return i}export function requireCursor(e){const t=e??"0";if(typeof t==="number"){if(Number.isSafeInteger(t)&&t>=0)return String(t);throw new a("juejin cursor must be a non-negative decimal integer")}if(typeof t==="string"&&/^(0|[1-9]\d*)$/.test(t))return t;throw new a("juejin cursor must be a non-negative decimal integer")}export function resolveCategory(e){if(e==null)return"";const t=String(e).trim();if(!t)return"";if(f.test(t))return t;const r=t.toLowerCase();if(CATEGORY_ALIASES[r])return CATEGORY_ALIASES[r];throw new a(`juejin category "${e}" is not recognised`,`Use a category id (e.g. "${CATEGORY_ALIASES.backend}") or one of: ${Object.keys(CATEGORY_ALIASES).join(", ")}.`)}export async function juejinFetch(e,t,r,n="POST"){const u=`${JUEJIN_API_BASE}${e}`;let i;try{const c={method:n,headers:{"user-agent":w,accept:"application/json"}};if(n==="POST"){c.headers["content-type"]="application/json";c.body=JSON.stringify(t??{})}i=await fetch(u,c)}catch(c){throw new s(`${r} request failed: ${c?.message??c}`,"Check that api.juejin.cn is reachable from this network.")}if(i.status===429)throw new s(`${r} returned HTTP 429 (rate limited)`,"Juejin throttles bursty traffic; wait a few seconds and retry.");if(!i.ok)throw new s(`${r} returned HTTP ${i.status}`);let o;try{o=await i.json()}catch(c){throw new s(`${r} returned malformed JSON: ${c?.message??c}`)}if(!o||typeof o!=="object"||Array.isArray(o)||!Object.hasOwn(o,"err_no"))throw new s(`${r} returned a malformed API envelope`);if(o.err_no!==0)throw new s(`${r} returned err_no ${o.err_no}: ${o.err_msg??""}`);return o}export function readDataArray(e,t){if(!e||typeof e!=="object"||Array.isArray(e)||!Object.hasOwn(e,"data"))throw new s(`${t} returned a malformed payload`);if(!Array.isArray(e.data))throw new s(`${t} returned a non-array data field`);if(e.data.length===0)throw new j(t,`${t} returned no articles.`);return e.data}function d(e,t){const r=String(e??"").trim();if(!f.test(r))throw new s(`${t} returned a malformed article id`);return r}function m(e,t){if(e==null)return null;const r=Number(e);if(!Number.isFinite(r))throw new s(`${t} returned a malformed numeric field`);return r}export function mapFeedItem(e,t){const r=e?.item_info??{},n=r.article_info??{},u=r.author_user_info??{},i=Array.isArray(r.tags)?r.tags.map((c)=>c?.tag_name).filter(Boolean).slice(0,6).join(", "):"",o=d(n.article_id,"juejin recommend");return{rank:t,article_id:o,title:String(n.title??"").trim(),brief:String(n.brief_content??"").trim(),views:m(n.view_count,"juejin recommend"),likes:m(n.digg_count,"juejin recommend"),comments:m(n.comment_count,"juejin recommend"),author:String(u.user_name??"").trim(),tags:i,url:o?`${JUEJIN_POST_URL}/${o}`:""}}export function mapHotItem(e,t){const r=e?.content??{},n=e?.content_counter??{},u=e?.author??{},i=d(r.content_id,"juejin hot");return{rank:t,article_id:i,title:String(r.title??"").trim(),brief:String(r.brief??"").trim(),views:m(n.view,"juejin hot"),likes:m(n.like,"juejin hot"),comments:m(n.comment_count,"juejin hot"),hot_rank:m(n.hot_rank,"juejin hot"),author:String(u.name??"").trim(),url:i?`${JUEJIN_POST_URL}/${i}`:""}}
|
package/clis/juejin/whoami.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as t,Strategy as n}from"@jackwener/opencli/registry";import{checkLogin as o,cookieQuickCheck as r}from"../_shared/article/auth.js";import{juejinProfile as i}from"./article.js";const c={home:i.home,checkAuth:i.checkAuth};t({site:"juejin",name:"whoami",access:"read",description:"检测掘金当前登录状态,返回用户 ID 和用户名。",domain:"juejin.cn",strategy:n.COOKIE,browser:!0,columns:["logged_in","user_id","username"],authStatus:{quickCheck:r("https://juejin.cn",["sessionid","sessionid_ss","sid_tt"])},func:async(s)=>{const e=await o(s,c);return[{logged_in:e.isAuthenticated,user_id:e.userId||"",username:e.username||""}]}});
|
package/clis/ke/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as c,CommandExecutionError as s}from"@jackwener/opencli/errors";const a=["请拖动下方滑块完成验证","请按住滑块","验证码","安全验证","访问验证","滑动验证"],u=["请登录","登录后","账号登录","手机登录","立即登录","扫码登录"];function i(t){return typeof t==="string"?t.replace(/\u00a0/g," ").replace(/\s+/g," ").trim():""}export async function readPageState(t){const e=await t.evaluate(`
|
|
2
2
|
(() => {
|
|
3
3
|
try {
|
|
4
4
|
return {
|
|
@@ -10,12 +10,12 @@ import{AuthRequiredError as Q,CommandExecutionError as W}from"@jackwener/opencli
|
|
|
10
10
|
return { href: '', title: '', body_text: '' };
|
|
11
11
|
}
|
|
12
12
|
})()
|
|
13
|
-
`);if(!
|
|
14
|
-
const res = await fetch(${JSON.stringify(
|
|
13
|
+
`);if(!e)return{href:"",title:"",body_text:""};return{href:i(e.href),title:i(e.title),body_text:i(e.body_text)}}export function assertNotBlocked(t){const{href:e,title:n,body_text:o}=t;if(e.includes("hip.ke.com/captcha")||e.includes("/captcha"))throw new c("ke.com","触发了验证码,请先在浏览器中完成验证");if(a.some((r)=>n.includes(r)||o.includes(r)))throw new c("ke.com","触发了验证码,请先在浏览器中完成滑块验证");if(u.some((r)=>n.includes(r)))throw new c("ke.com","未登录,请先在浏览器中登录贝壳找房")}export async function gotoKe(t,e){await t.goto(e,{settleMs:2500});await t.wait(2);const n=await readPageState(t);assertNotBlocked(n);return n}export async function fetchKeJson(t,e){const n=await t.evaluate(`(async () => {
|
|
14
|
+
const res = await fetch(${JSON.stringify(e)}, { credentials: 'include' });
|
|
15
15
|
if (!res.ok) return { __keErr: res.status };
|
|
16
16
|
try {
|
|
17
17
|
return await res.json();
|
|
18
18
|
} catch {
|
|
19
19
|
return { __keErr: 'parse' };
|
|
20
20
|
}
|
|
21
|
-
})()`),
|
|
21
|
+
})()`),o=n;if(o?.__keErr!==void 0){const r=o.__keErr;if(r===401||r===403)throw new c("ke.com","未登录或登录已过期,请先在浏览器中登录贝壳找房");if(r==="parse")throw new s("响应不是有效 JSON","可能触发了风控,请检查登录状态或稍后重试");throw new s(`HTTP ${r}`,"请检查网络连接或登录状态")}return n}export function cityUrl(t){return`https://${t}.ke.com`}
|
package/clis/kimi/_utils.js
CHANGED
|
@@ -7,11 +7,11 @@ export const KIMI_DOMAIN="kimi.com",KIMI_URL="https://www.kimi.com/",IS_VISIBLE_
|
|
|
7
7
|
if (cs.visibility === 'hidden' || cs.display === 'none' || cs.opacity === '0') return false;
|
|
8
8
|
return true;
|
|
9
9
|
};
|
|
10
|
-
`;export function isKimiUrl(
|
|
10
|
+
`;export function isKimiUrl(t){try{const e=new URL(String(t||"")),r=e.hostname.toLowerCase();return e.protocol==="https:"&&(r===KIMI_DOMAIN||r===`www.${KIMI_DOMAIN}`)}catch{return!1}}export async function ensureOnKimi(t){const e=await t.evaluate("window.location.href").catch(()=>"");if(isKimiUrl(e))return;await t.goto(KIMI_URL);await t.wait(2)}const o=/^[0-9a-f-]{8,}$/i;export function parseChatId(t){const e=String(t||"").trim();if(!e)return"";const r=(n)=>o.test(n)?n.toLowerCase():"";if(/^https?:\/\//i.test(e))try{const n=new URL(e),i=n.hostname.toLowerCase();if(n.protocol!=="https:"||i!==KIMI_DOMAIN&&i!==`www.${KIMI_DOMAIN}`)return"";const s=n.pathname.match(/^\/chat\/([0-9a-f-]{8,})$/i);return s?r(s[1]):""}catch{return""}if(e.startsWith("/"))try{const i=new URL(e,KIMI_URL).pathname.match(/^\/chat\/([0-9a-f-]{8,})$/i);return i?r(i[1]):""}catch{return""}return r(e)}export function clickBySvgNameScript(t,e={}){const{last:r=!0}=e;return`(() => {
|
|
11
11
|
${IS_VISIBLE_JS}
|
|
12
|
-
const svgs = Array.from(document.querySelectorAll('svg[name="' + ${JSON.stringify(
|
|
13
|
-
if (!svgs.length) return { ok: false, reason: 'No visible svg[name="' + ${JSON.stringify(
|
|
14
|
-
const svg = ${
|
|
12
|
+
const svgs = Array.from(document.querySelectorAll('svg[name="' + ${JSON.stringify(t)} + '"], svg[role="img"][name="' + ${JSON.stringify(t)} + '"]')).filter(isVisible);
|
|
13
|
+
if (!svgs.length) return { ok: false, reason: 'No visible svg[name="' + ${JSON.stringify(t)} + '"].' };
|
|
14
|
+
const svg = ${r?"svgs[svgs.length - 1]":"svgs[0]"};
|
|
15
15
|
// Walk up to the nearest clickable ancestor.
|
|
16
16
|
let target = svg;
|
|
17
17
|
for (let i = 0; i < 6; i++) {
|
|
@@ -28,11 +28,11 @@ export const KIMI_DOMAIN="kimi.com",KIMI_URL="https://www.kimi.com/",IS_VISIBLE_
|
|
|
28
28
|
target.dispatchEvent(new MouseEvent('mouseup', opts));
|
|
29
29
|
target.click();
|
|
30
30
|
return { ok: true };
|
|
31
|
-
})()`}export function navByHrefScript(
|
|
31
|
+
})()`}export function navByHrefScript(t){return`(() => {
|
|
32
32
|
${IS_VISIBLE_JS}
|
|
33
33
|
const anchors = Array.from(document.querySelectorAll('a[href]')).filter(isVisible);
|
|
34
|
-
const target = anchors.find((a) => a.getAttribute('href') === ${JSON.stringify(
|
|
35
|
-
if (!target) return { ok: false, reason: 'No visible <a href="' + ${JSON.stringify(
|
|
34
|
+
const target = anchors.find((a) => a.getAttribute('href') === ${JSON.stringify(t)} || a.getAttribute('href').startsWith(${JSON.stringify(t)}));
|
|
35
|
+
if (!target) return { ok: false, reason: 'No visible <a href="' + ${JSON.stringify(t)} + '">.' };
|
|
36
36
|
target.click();
|
|
37
37
|
return { ok: true, href: target.getAttribute('href') };
|
|
38
38
|
})()`}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{cli as
|
|
2
|
-
${
|
|
1
|
+
import{cli as a,Strategy as o}from"@jackwener/opencli/registry";import{ArgumentError as w,CommandExecutionError as l,EmptyResultError as y}from"@jackwener/opencli/errors";import{KIMI_DOMAIN as c,KIMI_URL as f,IS_VISIBLE_JS as m,ensureOnKimi as p,parseChatId as b,clickBySvgNameScript as g}from"./_utils.js";const u=["Status","Index","Category","Title","ChatId","NewTitle"];a({site:"kimi",name:"sign-out",access:"write",description:"Click SignOut on the Kimi /settings page. Navigates to /settings first if not already there. Requires --yes.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"yes",type:"boolean",default:!1,help:"Actually sign out (default: dry-run)"}],columns:u,func:async(e,t)=>{if(!(t?.yes===!0||t?.yes==="true"||t?.yes==="1"))return[{Status:"dry-run — pass --yes to actually sign out"}];const n=await e.evaluate("window.location.href");if(!String(n||"").includes("/settings")){await e.goto(`${f}settings`);await e.wait(1.5)}const s=await e.evaluate(g("SignOut"));if(!s?.ok)throw new l(s?.reason||"SignOut svg not found","");await e.wait(1);return[{Status:"signed-out"}]}});a({site:"kimi",name:"upgrade",access:"write",description:'Click the "Upgrade" button (or 升级会员) in the Kimi sidebar — opens the membership/upgrade page or dialog.',domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:u,func:async(e)=>{await p(e);const t=await e.evaluate(`(() => {
|
|
2
|
+
${m}
|
|
3
3
|
const btns = Array.from(document.querySelectorAll('button, [role="button"], a')).filter(isVisible);
|
|
4
4
|
const target = btns.find((b) => {
|
|
5
5
|
const t = (b.innerText || b.textContent || '').trim();
|
|
@@ -14,8 +14,8 @@ import{cli as W,Strategy as Y}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
14
14
|
target.dispatchEvent(new MouseEvent('mouseup', opts));
|
|
15
15
|
target.click();
|
|
16
16
|
return { ok: true };
|
|
17
|
-
})()`);if(!
|
|
18
|
-
${
|
|
17
|
+
})()`);if(!t?.ok)throw new l(t?.reason||"upgrade click failed","");await e.wait(0.6);return[{Status:"clicked"}]}});a({site:"kimi",name:"dismiss-banner",access:"write",description:'Close any visible sidebar banner (e.g., "Make a Review & Earn Credit", "获取应用程序") by clicking its Close svg.',domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:u,func:async(e)=>{await p(e);if(!(await e.evaluate(g("Close",{last:!1})))?.ok)throw new y("kimi dismiss-banner","No Close svg visible — no banner to dismiss?");return[{Status:"dismissed"}]}});a({site:"kimi",name:"templates",access:"read",description:"List template cards visible on a Kimi mode page (PPT/docs/deep-research/agent). Each mode shows curated example projects organized by category. Pass --mode to navigate first.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"mode",required:!1,help:"Navigate to mode first: ppt|docs|deep-research|agent|websites|sheets|agent-swarm|code"},{name:"limit",type:"int",required:!1,default:30}],columns:u,func:async(e,t)=>{const i=String(t?.mode||"").trim().toLowerCase(),n={ppt:"/slides",docs:"/docs","deep-research":"/deep-research",agent:"/agent",websites:"/websites",sheets:"/sheets","agent-swarm":"/agent-swarm",code:"/code"};if(i){const r=n[i];if(!r)throw new w("mode",`unknown mode "${i}"`);await e.goto(`${f}${r.slice(1)}`);await e.wait(2)}else await p(e);const s=await e.evaluate(`(() => {
|
|
18
|
+
${m}
|
|
19
19
|
const els = Array.from(document.querySelectorAll('a, [role="button"], button')).filter(isVisible);
|
|
20
20
|
const out = [];
|
|
21
21
|
for (const el of els) {
|
|
@@ -33,9 +33,9 @@ import{cli as W,Strategy as Y}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
33
33
|
seen.add(c.title);
|
|
34
34
|
return true;
|
|
35
35
|
});
|
|
36
|
-
})()`);if(!
|
|
37
|
-
${
|
|
38
|
-
const row = Array.from(document.querySelectorAll('a[href*="/chat/' + ${JSON.stringify(
|
|
36
|
+
})()`);if(!s.length)throw new y("kimi templates","No template cards visible. Are you on a mode page?");const d=Number.isInteger(t?.limit)&&t.limit>0?t.limit:30;return s.slice(0,d).map((r,h)=>({Index:h+1,Category:r.category,Title:r.title}))}});a({site:"kimi",name:"history-rename",access:"write",description:"Rename a chat from the /chat/history page (clicks the inline Edit svg next to a chat row, types the new title, and saves). Requires --yes.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"chat-id",positional:!0,required:!0,help:"Chat id (UUID-like)"},{name:"new-title",positional:!0,required:!0,help:"New title"},{name:"yes",type:"boolean",default:!1,help:"Actually rename (default: dry-run)"}],columns:u,func:async(e,t)=>{const i=b(t?.["chat-id"]),n=String(t?.["new-title"]||"").trim();if(!i)throw new w("chat-id","is required");if(!n)throw new w("new-title","is required");if(!(t?.yes===!0||t?.yes==="true"||t?.yes==="1"))return[{Status:"dry-run — pass --yes to rename",ChatId:i,NewTitle:n}];await e.goto(`${f}chat/history`);await e.wait(2);const d=await e.evaluate(`(() => {
|
|
37
|
+
${m}
|
|
38
|
+
const row = Array.from(document.querySelectorAll('a[href*="/chat/' + ${JSON.stringify(i)} + '"]')).find(isVisible);
|
|
39
39
|
if (!row) return { ok: false, reason: 'Chat row not found in history.' };
|
|
40
40
|
// The Edit svg is in a sibling or descendant.
|
|
41
41
|
let container = row.parentElement || row;
|
|
@@ -46,19 +46,19 @@ import{cli as W,Strategy as Y}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
46
46
|
for (let i = 0; i < 5 && editBtn.parentElement; i++) { editBtn = editBtn.parentElement; if (editBtn.getAttribute('role') === 'button' || editBtn.tagName === 'BUTTON') break; }
|
|
47
47
|
editBtn.click();
|
|
48
48
|
return { ok: true };
|
|
49
|
-
})()`);if(!
|
|
50
|
-
${
|
|
49
|
+
})()`);if(!d?.ok)throw new l(d?.reason||"Edit click failed","");await e.wait(0.5);const r=await e.evaluate(`(() => {
|
|
50
|
+
${m}
|
|
51
51
|
const inputs = Array.from(document.querySelectorAll('input[type="text"], input:not([type])')).filter(isVisible);
|
|
52
52
|
const input = inputs[inputs.length - 1];
|
|
53
53
|
if (!input) return { ok: false, reason: 'No input mounted after clicking Edit.' };
|
|
54
54
|
const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
|
|
55
|
-
setter.call(input, ${JSON.stringify(
|
|
55
|
+
setter.call(input, ${JSON.stringify(n)});
|
|
56
56
|
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
57
57
|
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
58
58
|
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
59
59
|
return { ok: true };
|
|
60
|
-
})()`);if(!
|
|
61
|
-
const row = Array.from(document.querySelectorAll('a[href*="/chat/' + ${JSON.stringify(
|
|
62
|
-
.find((el) => (el.innerText || el.textContent || '').includes(${JSON.stringify(
|
|
60
|
+
})()`);if(!r?.ok)throw new l(r?.reason||"Rename input fill failed","");await e.wait(1);if(!await e.evaluate(`(() => {
|
|
61
|
+
const row = Array.from(document.querySelectorAll('a[href*="/chat/' + ${JSON.stringify(i)} + '"]'))
|
|
62
|
+
.find((el) => (el.innerText || el.textContent || '').includes(${JSON.stringify(n)}));
|
|
63
63
|
return !!row;
|
|
64
|
-
})()`))throw new
|
|
64
|
+
})()`))throw new l(`Kimi history rename was not verified for chat ${i}`,"The edit input was submitted, but the history row did not show the requested title.");return[{Status:"renamed",ChatId:i,NewTitle:n}]}});
|
package/clis/kimi/auth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as n,CommandExecutionError as o}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as c}from"../_shared/site-auth.js";async function s(t){const r=await t.getCookies({url:"https://www.kimi.com"}),e=new Set(r.filter((i)=>i.value).map((i)=>i.name));return e.has("access_token")||e.has("refresh_token")}async function a(t){const e=(await t.getCookies({url:"https://www.kimi.com"})).find((m)=>m.name==="access_token")?.value||"";if(!e)throw new n("kimi.com","Kimi access_token cookie missing");await t.goto("https://www.kimi.com/");await t.wait(3);const i=await t.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
|
-
const token = ${JSON.stringify(
|
|
3
|
+
const token = ${JSON.stringify(e)};
|
|
4
4
|
const res = await fetch('/api/user', { credentials: 'include', headers: { 'Authorization': 'Bearer ' + token, 'Accept': 'application/json' } });
|
|
5
5
|
if (res.status === 401 || res.status === 403) {
|
|
6
6
|
return { kind: 'auth', detail: 'Kimi /api/user HTTP ' + res.status };
|
|
@@ -14,4 +14,4 @@ import{AuthRequiredError as D,CommandExecutionError as F}from"@jackwener/opencli
|
|
|
14
14
|
} catch (e) {
|
|
15
15
|
return { kind: 'exception', detail: String(e && e.message || e) };
|
|
16
16
|
}
|
|
17
|
-
})()`);if(
|
|
17
|
+
})()`);if(i?.kind==="auth")throw new n("kimi.com",i.detail);if(i?.kind==="http")throw new o(`HTTP ${i.httpStatus} from /api/user`);if(i?.kind==="exception")throw new o(`Kimi whoami failed: ${i.detail}`);if(!i?.ok)throw new o(`Unexpected Kimi probe: ${JSON.stringify(i)}`);return{user_id:i.user_id,name:i.name}}c({site:"kimi",domain:"kimi.com",loginUrl:"https://www.kimi.com/",columns:["user_id","name"],quickCheck:s,verify:a,poll:async(t)=>{if(!await s(t))throw new n("kimi.com","Waiting for Kimi auth cookies");return a(t)}});
|
package/clis/kimi/chat.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as r,Strategy as o}from"@jackwener/opencli/registry";import{ArgumentError as h,CommandExecutionError as u,EmptyResultError as p,TimeoutError as R}from"@jackwener/opencli/errors";import{KIMI_DOMAIN as c,KIMI_URL as k,IS_VISIBLE_JS as x,ensureOnKimi as f,parseChatId as I,clickBySvgNameScript as w}from"./_utils.js";const l=["Field","Value","Status","Url","Index","Title","ChatId","Role","Text","Length","ClipboardClicked","Reaction","WaitedSeconds","ReplyPreview"];async function g(e,t){if(!t){await f(e);return}const i=I(t);if(!i)throw new h("conv","must be a Kimi chat id or https://www.kimi.com/chat/<id> URL");await e.goto(`${k}chat/${i}?chat_enter_method=history`);await e.wait(2);for(let s=0;s<15;s++){if(await e.evaluate(`(() => {
|
|
2
2
|
const list = document.querySelector('.chat-content-list') || document.querySelector('.message-list');
|
|
3
3
|
if (!list) return false;
|
|
4
4
|
// Check for actual chat-content-item rows (the new container) OR any direct children (older container)
|
|
5
5
|
return list.querySelectorAll('.chat-content-item, .segment').length > 0 || list.children.length > 0;
|
|
6
|
-
})()`))return;await
|
|
6
|
+
})()`))return;await e.wait(1)}}r({site:"kimi",name:"status",access:"read",description:"Check Kimi page connection, login state, and current URL.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:l,func:async(e)=>{await f(e);const t=await e.evaluate(`(() => {
|
|
7
7
|
// Kimi marks logged-in users via the user avatar at bottom-left.
|
|
8
8
|
const avatar = document.querySelector('img[src*="avatar.moonshot.cn"]');
|
|
9
9
|
const loggedIn = !!avatar;
|
|
@@ -13,8 +13,8 @@ import{cli as W,Strategy as X}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
13
13
|
loggedIn,
|
|
14
14
|
userLabel: loggedIn ? (avatar.alt || '') : '',
|
|
15
15
|
};
|
|
16
|
-
})()`);return[{Field:"Status",Value:"Connected"},{Field:"Url",Value:
|
|
17
|
-
${
|
|
16
|
+
})()`);return[{Field:"Status",Value:"Connected"},{Field:"Url",Value:t.url},{Field:"Title",Value:t.title},{Field:"LoggedIn",Value:t.loggedIn?"Yes":"No"},{Field:"User",Value:t.userLabel||"(unknown)"}]}});r({site:"kimi",name:"new",access:"write",description:"Start a new Kimi chat (navigates to / with chat_enter_method=new_chat).",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:l,func:async(e)=>{await e.goto(`${k}?chat_enter_method=new_chat`);await e.wait(1);const t=await e.evaluate("window.location.href");return[{Status:"started",Url:String(t||"")}]}});r({site:"kimi",name:"history",access:"read",description:"List recent Kimi chats from the sidebar (with chat IDs extracted from href).",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"limit",type:"int",required:!1,default:30}],columns:l,func:async(e,t)=>{await f(e);const i=await e.evaluate(`(() => {
|
|
17
|
+
${x}
|
|
18
18
|
const anchors = Array.from(document.querySelectorAll('a[href*="/chat/"]')).filter(isVisible);
|
|
19
19
|
const seen = new Set();
|
|
20
20
|
const out = [];
|
|
@@ -29,11 +29,11 @@ import{cli as W,Strategy as X}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
29
29
|
out.push({ id, title: title || '(untitled)' });
|
|
30
30
|
}
|
|
31
31
|
return out;
|
|
32
|
-
})()`);if(!
|
|
32
|
+
})()`);if(!i.length)throw new p("kimi history","No chats visible in sidebar. Are you logged in?");const s=Number.isInteger(t?.limit)&&t.limit>0?t.limit:30;return i.slice(0,s).map((a,n)=>({Index:n+1,Title:a.title,ChatId:a.id}))}});r({site:"kimi",name:"detail",access:"read",description:"Open a Kimi chat by ID and return its visible messages.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"id",positional:!0,required:!0,help:"Chat ID or full /chat/<id> URL"},{name:"limit",type:"int",required:!1,default:20}],columns:l,func:async(e,t)=>{const i=I(t.id);if(!i)throw new h("id","is required");await e.goto(`${k}chat/${i}?chat_enter_method=history`);for(let n=0;n<15;n++){if(await e.evaluate(`(() => {
|
|
33
33
|
const list = document.querySelector('.chat-content-list') || document.querySelector('.message-list');
|
|
34
34
|
return !!list && list.querySelectorAll('.chat-content-item, .segment').length > 0;
|
|
35
|
-
})()`))break;await
|
|
36
|
-
${
|
|
35
|
+
})()`))break;await e.wait(1)}const s=await y(e);if(!s.length)throw new p("kimi detail",`No messages found in /chat/${i}.`);const a=Number.isInteger(t?.limit)&&t.limit>0?t.limit:20;return s.slice(0,a).map((n,m)=>({Index:m+1,Role:n.role,Text:(n.text||"").slice(0,1200)}))}});r({site:"kimi",name:"read",access:"read",description:"Read messages in the current Kimi chat. Pass --conv <id> to navigate to a specific chat first.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"conv",required:!1,help:"Chat id or URL (navigates there before reading)"},{name:"limit",type:"int",required:!1,default:20}],columns:l,func:async(e,t)=>{await g(e,t?.conv);const i=await y(e);if(!i.length)throw new p("kimi read","No chat turns found on current page.");const s=Number.isInteger(t?.limit)&&t.limit>0?t.limit:20;return i.slice(0,s).map((a,n)=>({Index:n+1,Role:a.role,Text:(a.text||"").slice(0,1200)}))}});async function y(e){return await e.evaluate(`(() => {
|
|
36
|
+
${x}
|
|
37
37
|
// Prefer .chat-content-list (the actual messages container); fall back
|
|
38
38
|
// to .message-list (older Kimi UI) and .chat-detail-content (parent).
|
|
39
39
|
const box = document.querySelector('.chat-content-list') || document.querySelector('.message-list') || document.querySelector('.chat-detail-content');
|
|
@@ -56,22 +56,22 @@ import{cli as W,Strategy as X}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
56
56
|
turns.push({ role, text: tx });
|
|
57
57
|
}
|
|
58
58
|
return turns;
|
|
59
|
-
})()`)}async function
|
|
59
|
+
})()`)}async function q(e,t){const i=String(t||"").trim();if(!i)throw new h("text","is required");await f(e);const s=await e.evaluate(`(() => {
|
|
60
60
|
return Array.from(document.querySelectorAll('.chat-content-list .chat-content-item, .message-list > *, .segment'))
|
|
61
61
|
.filter((row) => /user|sent-by-user|me-/i.test(String(row.className || ''))).length;
|
|
62
|
-
})()`),
|
|
63
|
-
${
|
|
62
|
+
})()`),a=await e.evaluate(`(() => {
|
|
63
|
+
${x}
|
|
64
64
|
const editor = document.querySelector('[contenteditable="true"][role="textbox"]');
|
|
65
65
|
if (!editor || !isVisible(editor)) return { ok: false, reason: 'Kimi composer not visible.' };
|
|
66
66
|
editor.focus();
|
|
67
67
|
document.execCommand('selectAll', false);
|
|
68
|
-
document.execCommand('insertText', false, ${JSON.stringify(
|
|
68
|
+
document.execCommand('insertText', false, ${JSON.stringify(i)});
|
|
69
69
|
return { ok: true };
|
|
70
|
-
})()`);if(!
|
|
70
|
+
})()`);if(!a?.ok)throw new u(a?.reason||"composer type failed","");await e.wait(0.3);const n=await e.evaluate(w("Send"));if(!n?.ok)throw new u(n?.reason||"Send button click failed","");const m=Date.now()+3000;while(Date.now()<m){if(await e.evaluate(`(() => {
|
|
71
71
|
const normalize = (value) => String(value || '').replace(/\\u00a0/g, ' ').replace(/\\s+/g, ' ').trim();
|
|
72
|
-
const prompt = normalize(${JSON.stringify(
|
|
73
|
-
const before = Number(${JSON.stringify(
|
|
72
|
+
const prompt = normalize(${JSON.stringify(i)});
|
|
73
|
+
const before = Number(${JSON.stringify(s)}) || 0;
|
|
74
74
|
const rows = Array.from(document.querySelectorAll('.chat-content-list .chat-content-item, .message-list > *, .segment'))
|
|
75
75
|
.filter((row) => /user|sent-by-user|me-/i.test(String(row.className || '')));
|
|
76
76
|
return rows.slice(before).some((row) => normalize(row.innerText || row.textContent).includes(prompt));
|
|
77
|
-
})()`))return{prompt:
|
|
77
|
+
})()`))return{prompt:i};await e.wait(0.2)}throw new u("Kimi message submission was not verified","The prompt was injected and Send was clicked, but no new user turn containing that prompt appeared.")}r({site:"kimi",name:"send",access:"write",description:"Send a message in the current Kimi chat (fire-and-forget; does not wait for reply).",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"text",fromFile:!0,positional:!0,required:!0,help:"Message text"}],columns:l,func:async(e,t)=>{const i=await q(e,t?.text);return[{Status:"sent",Length:String(i.prompt.length)}]}});r({site:"kimi",name:"copy-message",access:"write",description:"Return the text of the last assistant message. Pass --conv <id> to navigate to a specific chat first.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"conv",required:!1,help:"Chat id or URL (navigates there before reading)"},{name:"click-button",type:"boolean",default:!1,help:"Also click in-UI Copy button (writes to clipboard)"}],columns:l,func:async(e,t)=>{await g(e,t?.conv);const s=(await y(e)).filter((n)=>n.role==="Assistant");if(!s.length)throw new p("kimi copy-message","No assistant message visible.");const a=s[s.length-1];if(t?.["click-button"]===!0||t?.["click-button"]==="true"){const n=await e.evaluate(w("Copy"));if(!n?.ok)throw new u(n?.reason||"Copy button not visible","")}return[{Field:"Length",Value:String((a.text||"").length)+" chars"},{Field:"ClipboardClicked",Value:t?.["click-button"]===!0||t?.["click-button"]==="true"?"yes":"no"},{Field:"Text",Value:a.text||""}]}});r({site:"kimi",name:"regenerate",access:"write",description:"Click Refresh (Kimi's regenerate button) on the last assistant message. Pass --conv <id> to target a specific chat.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"conv",required:!1,help:"Chat id or URL"}],columns:l,func:async(e,t)=>{await g(e,t?.conv);const i=await e.evaluate(w("Refresh"));if(!i?.ok)throw new u(i?.reason||"Refresh button not visible","");return[{Status:"regenerated"}]}});r({site:"kimi",name:"react",access:"write",description:"Like or dislike the last assistant message. Pass --conv <id> to target a specific chat.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"kind",positional:!0,required:!0,help:"like or dislike"},{name:"conv",required:!1,help:"Chat id or URL"}],columns:l,func:async(e,t)=>{const i=String(t?.kind||"").trim().toLowerCase();if(i!=="like"&&i!=="dislike")throw new h("kind",'must be "like" or "dislike"');await g(e,t?.conv);const s=i==="like"?"Like":"Dislike",a=await e.evaluate(w(s));if(!a?.ok)throw new u(a?.reason||`${i} button not visible`,"");return[{Status:"clicked",Reaction:i}]}});r({site:"kimi",name:"share",access:"write",description:"Click Share on the last assistant message (opens Kimi's share dialog). Pass --conv <id> to target a specific chat.",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"conv",required:!1,help:"Chat id or URL"}],columns:l,func:async(e,t)=>{await g(e,t?.conv);const i=await e.evaluate(w("Share_a"));if(!i?.ok)throw new u(i?.reason||"Share button not visible","");await e.wait(1);return[{Status:"share dialog opened"}]}});r({site:"kimi",name:"ask",access:"write",description:"Send a message and wait up to --timeout seconds for the assistant reply (best-effort: polls for turn count to grow + stabilize).",domain:c,strategy:o.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"text",fromFile:!0,positional:!0,required:!0,help:"Prompt text"},{name:"timeout",type:"int",required:!1,default:120}],columns:l,func:async(e,t)=>{const i=String(t?.text||"").trim();if(!i)throw new h("text","is required");const s=Number.isInteger(t?.timeout)&&t.timeout>0?t.timeout:120;await f(e);const a=(await y(e)).filter((C)=>C.role==="Assistant").length;await q(e,i);const n=Date.now(),m=n+s*1000;let d="",b=0;while(Date.now()<m){await e.wait(1.5);const v=(await y(e).catch(()=>[])).filter((O)=>O.role==="Assistant");if(v.length<=a)continue;const S=v[v.length-1]?.text||"";if(S&&S===d)b++;else{d=S;b=0}if(d&&b>=2)break}const K=Math.round((Date.now()-n)/1000);if(!d)throw new R("kimi ask",s,"No new Kimi assistant reply was visible before the timeout.");return[{Status:"reply-received",Length:String(i.length),WaitedSeconds:String(K),ReplyPreview:d.slice(0,300)}]}});
|