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/qiita/stats.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as c,Strategy as l}from"@jackwener/opencli/registry";import{EmptyResultError as m,AuthRequiredError as u}from"@jackwener/opencli/errors";import{qiitaViewer as p}from"./gql.js";const h="https://qiita.com/";c({site:"qiita",name:"stats",access:"read",description:"Qiita 文章数据(每篇浏览/点赞/收藏/评论等运营指标)。逐篇补浏览数、篇数多时偏慢,客户端超时属正常,重试一次即可",domain:"qiita.com",strategy:l.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"limit",type:"number",default:20,help:"返回条数"}],columns:["id","type","title","url","published_at","views","likes","comments","collects","shares","tags","extra"],func:async(i,s)=>{const o=Math.max(1,Number(s.limit)||20);await i.goto(h);const a=(await p(i))?.urlName;if(!a)throw new u("qiita.com","未登录 Qiita:请先在 Chrome 里登录 qiita.com 再运行 qiita stats");const e=await i.evaluate(`(async () => {
|
|
2
2
|
try {
|
|
3
|
-
const limit = ${JSON.stringify(
|
|
4
|
-
const urlName = ${JSON.stringify(
|
|
3
|
+
const limit = ${JSON.stringify(o)};
|
|
4
|
+
const urlName = ${JSON.stringify(a)};
|
|
5
5
|
const items = [];
|
|
6
6
|
for (let pageNo = 1; items.length < limit && pageNo <= 100; pageNo++) {
|
|
7
7
|
const resp = await fetch('/api/v2/users/' + encodeURIComponent(urlName) + '/items?per_page=100&page=' + pageNo, {
|
|
@@ -34,4 +34,4 @@ import{cli as F,Strategy as G}from"@jackwener/opencli/registry";import{EmptyResu
|
|
|
34
34
|
} catch (e) {
|
|
35
35
|
return { error: String((e && e.message) || e) };
|
|
36
36
|
}
|
|
37
|
-
})()`);if(!
|
|
37
|
+
})()`);if(!e||e.error)throw Error(e?.error||"qiita stats:evaluate 无返回(浏览器会话异常)");const r=Array.isArray(e.items)?e.items:[];if(r.length===0)throw new m("qiita stats","该 Qiita 账号没有任何公开文章。");return r.map((t)=>({id:t.id||"",type:"article",title:t.title||"",url:t.url||"",published_at:t.created_at||"",views:t.__views??"",likes:t.likes_count??0,comments:t.comments_count??0,collects:t.stocks_count??0,shares:"",tags:Array.isArray(t.tags)?t.tags.map((n)=>n.name||"").filter(Boolean).join("|"):"",extra:JSON.stringify({reactions:t.reactions_count??null,private:t.private??null,updated_at:t.updated_at||"",organization:t.organization_url_name||""})}))}});
|
package/clis/qoder/_utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as o,CommandExecutionError as c}from"@jackwener/opencli/errors";export const IS_VISIBLE_JS=`
|
|
2
2
|
const isVisible = (el) => {
|
|
3
3
|
if (!el) return false;
|
|
4
4
|
const r = el.getBoundingClientRect();
|
|
@@ -7,9 +7,9 @@ import{ArgumentError as K,CommandExecutionError as X}from"@jackwener/opencli/err
|
|
|
7
7
|
if (cs.visibility === 'hidden' || cs.display === 'none' || cs.opacity === '0') return false;
|
|
8
8
|
return true;
|
|
9
9
|
};
|
|
10
|
-
`;export function unwrapEvaluateResult(
|
|
10
|
+
`;export function unwrapEvaluateResult(t){if(t&&typeof t==="object"&&!Array.isArray(t)&&"session"in t&&"data"in t)return t.data;return t}export async function evaluateQoder(t,e){return unwrapEvaluateResult(await t.evaluate(e))}export function requireArrayResult(t,e){if(!Array.isArray(t))throw new c(`${e}: unexpected evaluate result shape`);return t}export function parsePositiveInt(t,e,n){const r=t==null||t===""?e:Number(t);if(!Number.isInteger(r)||r<1)throw new o(`${n} must be a positive integer`);return r}export function clickFirstScript(t){return`(() => {
|
|
11
11
|
${IS_VISIBLE_JS}
|
|
12
|
-
const sels = ${JSON.stringify(
|
|
12
|
+
const sels = ${JSON.stringify(t)};
|
|
13
13
|
for (const sel of sels) {
|
|
14
14
|
const target = Array.from(document.querySelectorAll(sel)).filter(isVisible)[0];
|
|
15
15
|
if (target) {
|
|
@@ -24,11 +24,11 @@ import{ArgumentError as K,CommandExecutionError as X}from"@jackwener/opencli/err
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
return { ok: false, reason: 'No matching visible element.' };
|
|
27
|
-
})()`}export function clickByTextScript(
|
|
27
|
+
})()`}export function clickByTextScript(t,e={}){const{exact:n=!1,maxLen:r=60}=e;return`(() => {
|
|
28
28
|
${IS_VISIBLE_JS}
|
|
29
|
-
const patterns = ${JSON.stringify(
|
|
30
|
-
const exact = ${
|
|
31
|
-
const maxLen = ${
|
|
29
|
+
const patterns = ${JSON.stringify(t)};
|
|
30
|
+
const exact = ${n?"true":"false"};
|
|
31
|
+
const maxLen = ${r};
|
|
32
32
|
const isVis = isVisible;
|
|
33
33
|
const candidates = Array.from(document.querySelectorAll('button, [role="button"], a, [role="tab"]')).filter(isVis);
|
|
34
34
|
for (const pat of patterns) {
|
|
@@ -69,7 +69,7 @@ import{ArgumentError as K,CommandExecutionError as X}from"@jackwener/opencli/err
|
|
|
69
69
|
const role = /user|me-|right/.test(cls) ? 'User' : (/assistant|ai|bot|response/.test(cls) ? 'Assistant' : 'Turn');
|
|
70
70
|
return { role, text: tx };
|
|
71
71
|
}).filter(Boolean);
|
|
72
|
-
})()`;export function buildQoderInjectTextScript(
|
|
72
|
+
})()`;export function buildQoderInjectTextScript(t){return`(() => {
|
|
73
73
|
${IS_VISIBLE_JS}
|
|
74
74
|
const editors = Array.from(document.querySelectorAll('[contenteditable="true"]')).filter(isVisible);
|
|
75
75
|
const candidates = editors.map((editor, index) => {
|
|
@@ -95,19 +95,19 @@ import{ArgumentError as K,CommandExecutionError as X}from"@jackwener/opencli/err
|
|
|
95
95
|
const editor = best.editor;
|
|
96
96
|
editor.focus();
|
|
97
97
|
document.execCommand('selectAll', false);
|
|
98
|
-
const inserted = document.execCommand('insertText', false, ${JSON.stringify(String(
|
|
98
|
+
const inserted = document.execCommand('insertText', false, ${JSON.stringify(String(t??""))});
|
|
99
99
|
if (!inserted) {
|
|
100
|
-
editor.textContent = ${JSON.stringify(String(
|
|
100
|
+
editor.textContent = ${JSON.stringify(String(t??""))};
|
|
101
101
|
}
|
|
102
|
-
editor.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertText', data: ${JSON.stringify(String(
|
|
102
|
+
editor.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertText', data: ${JSON.stringify(String(t??""))} }));
|
|
103
103
|
return { ok: true, score: best.score };
|
|
104
104
|
})()`}export const QODER_MESSAGE_COUNT_JS=`(() => {
|
|
105
105
|
const turns = ${QODER_TURNS_JS};
|
|
106
106
|
return Array.isArray(turns) ? turns.length : 0;
|
|
107
|
-
})()`;export function qoderResponseAfterScript(
|
|
107
|
+
})()`;export function qoderResponseAfterScript(t,e){return`(() => {
|
|
108
108
|
const turns = ${QODER_TURNS_JS};
|
|
109
|
-
if (!Array.isArray(turns) || turns.length <= ${Number(
|
|
110
|
-
const fresh = turns.slice(${Number(
|
|
111
|
-
.filter((turn) => turn && turn.text && turn.text !== ${JSON.stringify(String(
|
|
109
|
+
if (!Array.isArray(turns) || turns.length <= ${Number(t)||0}) return null;
|
|
110
|
+
const fresh = turns.slice(${Number(t)||0})
|
|
111
|
+
.filter((turn) => turn && turn.text && turn.text !== ${JSON.stringify(String(e??""))});
|
|
112
112
|
return fresh.length ? fresh[fresh.length - 1] : null;
|
|
113
|
-
})()`}export async function waitForSelector(
|
|
113
|
+
})()`}export async function waitForSelector(t,e,n=5000,r=200){const s=Date.now()+n;while(Date.now()<s){if(await t.evaluate(`!!document.querySelector(${JSON.stringify(e)})`))return!0;await new Promise((i)=>setTimeout(i,r))}return!1}
|
package/clis/qoder/composer.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as e,Strategy as o}from"@jackwener/opencli/registry";import{CommandExecutionError as n}from"@jackwener/opencli/errors";import{clickByTextScript as a,evaluateQoder as c}from"./_utils.js";e({site:"qoder",name:"prompt-enhance",access:"write",description:'Click "Prompt Enhance" — Qoder rewrites the current composer draft for better LLM consumption.',domain:"localhost",strategy:o.UI,browser:!0,args:[],columns:["Status"],func:async(r)=>{const t=await c(r,a(["Prompt Enhance"]));if(!t?.ok)throw new n(t?.reason||"Prompt Enhance button not found","");await r.wait(0.5);return[{Status:"enhanced (check composer)"}]}});e({site:"qoder",name:"open-editor",access:"write",description:'Click "Open Editor" — opens the current draft in a full editor pane.',domain:"localhost",strategy:o.UI,browser:!0,args:[],columns:["Status"],func:async(r)=>{const t=await c(r,a(["Open Editor"]));if(!t?.ok)throw new n(t?.reason||"Open Editor button not found","");return[{Status:"clicked"}]}});
|
package/clis/qoder/quest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cli as
|
|
1
|
+
import{cli as f,Strategy as S}from"@jackwener/opencli/registry";import{ArgumentError as b,CommandExecutionError as a,TimeoutError as Q}from"@jackwener/opencli/errors";import{buildQoderInjectTextScript as g,clickByTextScript as h,clickFirstScript as y,evaluateQoder as e,parsePositiveInt as T,QODER_MESSAGE_COUNT_JS as d,qoderResponseAfterScript as q}from"./_utils.js";async function N(t,o,r=5000){const s=Math.max(1,Math.ceil(r/500));for(let n=0;n<s;n++){await t.wait(0.5);const i=await e(t,d);if(Number(i)>Number(o))return i}return o}f({site:"qoder",name:"new",access:"write",description:'Start a new Qoder Quest (conversation). Clicks the "New Quest" button in the sidebar (or its ⌘N variant).',domain:"localhost",strategy:S.UI,browser:!0,args:[],columns:["Status"],func:async(t)=>{const o=await e(t,h(["New Quest"]));if(!o?.ok)throw new a(o?.reason||"New Quest button not found","");await t.wait(0.5);return[{Status:"started"}]}});f({site:"qoder",name:"send",access:"write",description:'Type text into the Qoder composer and click "Send message" (fire-and-forget).',domain:"localhost",strategy:S.UI,browser:!0,args:[{name:"text",fromFile:!0,positional:!0,required:!0,help:"Text to send"}],columns:["Status","Length"],func:async(t,o)=>{const r=String(o?.text||"").trim();if(!r)throw new b("text is required");const s=await e(t,d),n=await e(t,g(r));if(!n?.ok)throw new a(n?.reason||"composer type failed","");await t.wait(0.3);if(!(await e(t,y(['button[aria-label="Send message"]','button[title="Send message"]'])))?.ok){if(!(await e(t,h(["Send message","Send","发送"])))?.ok)throw new a("Send button not found","")}const x=await N(t,s);if(Number(x)<=Number(s))throw new a("Qoder send did not create a new visible message row");return[{Status:"sent",Length:String(r.length)}]}});f({site:"qoder",name:"ask",access:"write",description:"Send a prompt to Qoder and wait up to --timeout seconds for the reply (best-effort: polls for the chat turn count to grow + stabilize).",domain:"localhost",strategy:S.UI,browser:!0,args:[{name:"text",fromFile:!0,positional:!0,required:!0,help:"Prompt text"},{name:"timeout",type:"int",required:!1,default:120,help:"Max seconds to wait"}],columns:["Role","Text","WaitedSeconds"],func:async(t,o)=>{const r=String(o?.text||"").trim();if(!r)throw new b("text is required");const s=T(o?.timeout,120,"--timeout"),n=await e(t,d),i=await e(t,g(r));if(!i?.ok)throw new a(i?.reason||"composer type failed","");await t.wait(0.3);if(!(await e(t,y(['button[aria-label="Send message"]','button[title="Send message"]'])))?.ok){if(!(await e(t,h(["Send message","Send","发送"])))?.ok)throw new a("Send button not found","")}const u=Date.now(),R=u+s*1000;let w=n,l=0,c=null;while(Date.now()<R){await new Promise((k)=>setTimeout(k,1500));const m=await e(t,d);if(m!==w){w=m;l=0}else l++;if(w>n&&l>=6){c=await e(t,q(n,r));if(c?.text)break}}const p=Math.round((Date.now()-u)/1000);if(!c?.text)throw new Q("Qoder response",s,"Confirm Qoder sent the prompt and finished generating, then retry with a larger --timeout.");return[{Role:"User",Text:r,WaitedSeconds:String(p)},{Role:c.role||"Assistant",Text:String(c.text).slice(0,1200),WaitedSeconds:String(p)}]}});
|
package/clis/qoder/ui.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import{cli as
|
|
2
|
-
${
|
|
1
|
+
import{cli as s,Strategy as a}from"@jackwener/opencli/registry";import{ArgumentError as f,CommandExecutionError as n,EmptyResultError as h}from"@jackwener/opencli/errors";import{IS_VISIBLE_JS as c,clickByTextScript as i,clickFirstScript as y,evaluateQoder as r,parsePositiveInt as k,requireArrayResult as w}from"./_utils.js";s({site:"qoder",name:"sidebar-toggle",access:"write",description:"Collapse / Expand the Qoder Quest List sidebar (⌘B).",domain:"localhost",strategy:a.UI,browser:!0,args:[],columns:["Status"],func:async(e)=>{const t=await r(e,i(["Collapse Quest List","Expand Quest List"]));if(!t?.ok)throw new n(t?.reason||"sidebar-toggle failed","");return[{Status:`clicked: ${t.matched}`}]}});s({site:"qoder",name:"open-panel",access:"write",description:"Open / close the Qoder bottom panel (Output / Terminal / Debug Console). ⌥⌘B equivalent.",domain:"localhost",strategy:a.UI,browser:!0,args:[],columns:["Status"],func:async(e)=>{const t=await r(e,i(["Open Panel","Close Panel"]));if(!t?.ok)throw new n(t?.reason||"open-panel failed","");return[{Status:`clicked: ${t.matched}`}]}});s({site:"qoder",name:"search",access:"read",description:"Open Qoder Search palette (⌘P), type a query, return matched options.",domain:"localhost",strategy:a.UI,browser:!0,args:[{name:"query",positional:!0,required:!0,help:"Search text"},{name:"limit",type:"int",required:!1,default:20}],columns:["Index","Item"],func:async(e,t)=>{const o=String(t?.query||"").trim();if(!o)throw new f("query","is required");const d=k(t?.limit,20,"--limit"),l=await r(e,i(["Search"]));if(!l?.ok)throw new n(l?.reason||"search open failed","");await e.wait(0.5);const u=await r(e,`(() => {
|
|
2
|
+
${c}
|
|
3
3
|
const inputs = Array.from(document.querySelectorAll('input[type="text"], input[type="search"], input:not([type])')).filter(isVisible);
|
|
4
4
|
const input = inputs[inputs.length - 1];
|
|
5
5
|
if (!input) return { ok: false, reason: 'No input visible.' };
|
|
6
6
|
const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
|
|
7
|
-
setter.call(input, ${JSON.stringify(
|
|
7
|
+
setter.call(input, ${JSON.stringify(o)});
|
|
8
8
|
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
9
9
|
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
10
10
|
return { ok: true };
|
|
11
|
-
})()`);if(!
|
|
12
|
-
${
|
|
11
|
+
})()`);if(!u?.ok)throw new n(u?.reason||"search type failed","");await e.wait(0.8);const p=w(await r(e,`(() => {
|
|
12
|
+
${c}
|
|
13
13
|
// Search palette results: prefer [role=option], else any clickable row in the modal.
|
|
14
14
|
const opts = Array.from(document.querySelectorAll('[role="option"], [role="menuitem"]')).filter(isVisible);
|
|
15
15
|
const titles = opts.map((o) => {
|
|
@@ -18,15 +18,15 @@ import{cli as K,Strategy as M}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
18
18
|
return (titleEl.textContent || '').trim().replace(/\\s+/g, ' ').slice(0, 200);
|
|
19
19
|
}).filter(Boolean);
|
|
20
20
|
return [...new Set(titles)];
|
|
21
|
-
})()`),"qoder search");try{await
|
|
22
|
-
${
|
|
21
|
+
})()`),"qoder search");try{await e.evaluate("document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));")}catch{}if(!p.length)throw new h("qoder search",`No items matched "${o}".`);return p.slice(0,d).map((m,b)=>({Index:b+1,Item:m}))}});s({site:"qoder",name:"settings",access:"write",description:"Click the Settings button in the Qoder sidebar.",domain:"localhost",strategy:a.UI,browser:!0,args:[],columns:["Status"],func:async(e)=>{if(!(await r(e,i(["Settings"])))?.ok){if(!(await r(e,y(['button[aria-label="Settings"]'])))?.ok)throw new n("Settings button not found","")}await e.wait(0.5);return[{Status:"clicked"}]}});s({site:"qoder",name:"knowledge",access:"write",description:"Open the Knowledge view (Qoder's personal/team knowledge base).",domain:"localhost",strategy:a.UI,browser:!0,args:[],columns:["Status"],func:async(e)=>{const t=await r(e,i(["Knowledge"]));if(!t?.ok)throw new n(t?.reason||"Knowledge button not found","");return[{Status:"clicked"}]}});s({site:"qoder",name:"marketplace",access:"write",description:"Open the Qoder Marketplace.",domain:"localhost",strategy:a.UI,browser:!0,args:[],columns:["Status"],func:async(e)=>{const t=await r(e,i(["Marketplace"]));if(!t?.ok)throw new n(t?.reason||"Marketplace button not found","");return[{Status:"clicked"}]}});s({site:"qoder",name:"credits",access:"read",description:'Click "Credits Usage" and return the credits-usage display text.',domain:"localhost",strategy:a.UI,browser:!0,args:[],columns:["Field","Value"],func:async(e)=>{const t=await r(e,i(["Credits Usage"]));if(!t?.ok)throw new n(t?.reason||"Credits Usage not visible","");await e.wait(0.5);const o=await r(e,`(() => {
|
|
22
|
+
${c}
|
|
23
23
|
// Find any dialog/popover that appeared.
|
|
24
24
|
const popovers = Array.from(document.querySelectorAll('[role="dialog"], [class*="popover"i], [class*="popup"i]')).filter(isVisible);
|
|
25
25
|
if (!popovers.length) return null;
|
|
26
26
|
const pop = popovers[popovers.length - 1];
|
|
27
27
|
return (pop.innerText || pop.textContent || '').trim().replace(/\\s+/g, ' ').slice(0, 600);
|
|
28
|
-
})()`);try{await
|
|
29
|
-
${
|
|
28
|
+
})()`);try{await e.evaluate("document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));")}catch{}return[{Field:"Status",Value:"clicked"},{Field:"Info",Value:o||"(no popover detected after click)"}]}});s({site:"qoder",name:"view-all",access:"write",description:'Click "View all" to show all Quests.',domain:"localhost",strategy:a.UI,browser:!0,args:[],columns:["Status"],func:async(e)=>{const t=await r(e,i(["View all"]));if(!t?.ok)throw new n(t?.reason||"View all button not visible","");return[{Status:"clicked"}]}});s({site:"qoder",name:"add-workspace",access:"write",description:'Click "Add Workspace" — opens the folder picker. Note: this opens a system file-picker dialog that Qoder controls; the actual folder selection must be done in the UI by the user.',domain:"localhost",strategy:a.UI,browser:!0,args:[],columns:["Status"],func:async(e)=>{const t=await r(e,i(["Add Workspace"]));if(!t?.ok)throw new n(t?.reason||"Add Workspace button not found","");return[{Status:"clicked — folder picker opened (manual selection required)"}]}});s({site:"qoder",name:"account",access:"read",description:"Click the account button (username) in the Qoder sidebar and return the visible account dropdown items.",domain:"localhost",strategy:a.UI,browser:!0,args:[{name:"username",required:!1,help:"Username text shown in the sidebar (default: tries common short labels)"}],columns:["Field","Value"],func:async(e,t)=>{let o=String(t?.username||"").trim();if(!o)o=await r(e,`(() => {
|
|
29
|
+
${c}
|
|
30
30
|
const btns = Array.from(document.querySelectorAll('button')).filter(isVisible);
|
|
31
31
|
const known = new Set(['Pin', 'Copy', 'New Quest', 'Search', 'Settings', 'View all', 'Knowledge', 'Marketplace', 'Credits Usage', 'Open Editor', 'Add Workspace', 'More Actions', 'Send message', 'Prompt Enhance', 'Voice input', 'button']);
|
|
32
32
|
const candidate = btns.find((b) => {
|
|
@@ -36,8 +36,8 @@ import{cli as K,Strategy as M}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
36
36
|
return true;
|
|
37
37
|
});
|
|
38
38
|
return candidate ? (candidate.innerText || '').trim() : '';
|
|
39
|
-
})()`);if(!
|
|
40
|
-
${
|
|
39
|
+
})()`);if(!o)throw new n("No account button detected. Pass --username <name> explicitly.","");if(!(await r(e,i([o],{exact:!0,maxLen:60})))?.ok)throw new n(`Click on account button "${o}" failed`,"");await e.wait(0.5);const l=w(await r(e,`(() => {
|
|
40
|
+
${c}
|
|
41
41
|
const popovers = Array.from(document.querySelectorAll('[role="menu"], [role="dialog"], [class*="popover"i], [class*="dropdown"i]')).filter(isVisible)
|
|
42
42
|
.filter((el) => { const r = el.getBoundingClientRect(); return r.width < 500 && r.height < 600; });
|
|
43
43
|
if (!popovers.length) return [];
|
|
@@ -46,8 +46,8 @@ import{cli as K,Strategy as M}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
46
46
|
.filter(isVisible)
|
|
47
47
|
.map((b) => (b.innerText || b.textContent || '').trim().replace(/\\s+/g, ' '))
|
|
48
48
|
.filter(Boolean);
|
|
49
|
-
})()`),"qoder account");try{await
|
|
50
|
-
${
|
|
49
|
+
})()`),"qoder account");try{await e.evaluate("document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));")}catch{}const u=[{Field:"Username",Value:o}];(l||[]).slice(0,20).forEach((p,m)=>{u.push({Field:`Item[${m+1}]`,Value:p})});return u}});s({site:"qoder",name:"more-actions",access:"read",description:'Click the "More Actions" button and list its menu items.',domain:"localhost",strategy:a.UI,browser:!0,args:[],columns:["Index","Item"],func:async(e)=>{const t=await r(e,i(["More Actions"]));if(!t?.ok)throw new n(t?.reason||"More Actions button not found","");await e.wait(0.4);const o=w(await r(e,`(() => {
|
|
50
|
+
${c}
|
|
51
51
|
const popovers = Array.from(document.querySelectorAll('[role="menu"], [role="dialog"], [class*="popover"i], [class*="menu"i]')).filter(isVisible)
|
|
52
52
|
.filter((el) => { const r = el.getBoundingClientRect(); return r.width < 500 && r.height < 600; });
|
|
53
53
|
if (!popovers.length) return [];
|
|
@@ -56,4 +56,4 @@ import{cli as K,Strategy as M}from"@jackwener/opencli/registry";import{ArgumentE
|
|
|
56
56
|
.filter(isVisible)
|
|
57
57
|
.map((b) => (b.innerText || b.textContent || '').trim().replace(/\\s+/g, ' '))
|
|
58
58
|
.filter(Boolean);
|
|
59
|
-
})()`),"qoder more-actions");try{await
|
|
59
|
+
})()`),"qoder more-actions");try{await e.evaluate("document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));")}catch{}if(!o.length)throw new h("qoder more-actions","Menu opened but no items detected.");return o.map((d,l)=>({Index:l+1,Item:d}))}});
|
package/clis/quark/auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as r,CommandExecutionError as a}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as i}from"../_shared/site-auth.js";const e=`(async () => {
|
|
2
2
|
try {
|
|
3
3
|
const r = await fetch('https://pan.quark.cn/account/info?fr=pc&platform=pc', { credentials: 'include', headers: { Accept: 'application/json' } });
|
|
4
4
|
if (r.status === 401 || r.status === 403) return { kind: 'auth', detail: 'Quark account/info HTTP ' + r.status };
|
|
@@ -13,4 +13,4 @@ import{AuthRequiredError as G,CommandExecutionError as F}from"@jackwener/opencli
|
|
|
13
13
|
} catch (e) {
|
|
14
14
|
return { kind: 'exception', detail: String(e && e.message || e) };
|
|
15
15
|
}
|
|
16
|
-
})()`;async function
|
|
16
|
+
})()`;async function o(n){await n.goto("https://pan.quark.cn/");await n.wait(2);const t=await n.evaluate(e);if(t?.kind==="auth")throw new r("quark.cn",t.detail);if(t?.kind==="http")throw new a(`HTTP ${t.httpStatus} from Quark account/info`);if(t?.kind==="render-error")throw new a(t.detail);if(t?.kind==="exception")throw new a(`Quark whoami failed: ${t.detail}`);if(!t?.ok)throw new a(`Unexpected Quark probe: ${JSON.stringify(t)}`);return{nickname:t.nickname}}i({site:"quark",domain:"quark.cn",loginUrl:"https://pan.quark.cn/",columns:["nickname"],verify:o,poll:async(n)=>{const t=await n.evaluate(e);if(!t?.ok)throw new r("quark.cn","Waiting for Quark login");return{nickname:t.nickname}}});
|
package/clis/quark/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as m,AuthRequiredError as d,CommandExecutionError as l,getErrorMessage as y}from"@jackwener/opencli/errors";export const SHARE_API="https://drive-h.quark.cn/1/clouddrive/share/sharepage",DRIVE_API="https://drive-pc.quark.cn/1/clouddrive/file",TASK_API="https://drive-pc.quark.cn/1/clouddrive/task";const f="pan.quark.cn",p="Quark Drive requires a logged-in browser session";function h(t,e){if(e===401||e===403)return!0;return/not logged in|login required|please log in|authentication required|unauthorized|forbidden|未登录|请先登录|需要登录|登录/.test(t.toLowerCase())}function
|
|
1
|
+
import{ArgumentError as m,AuthRequiredError as d,CommandExecutionError as l,getErrorMessage as y}from"@jackwener/opencli/errors";export const SHARE_API="https://drive-h.quark.cn/1/clouddrive/share/sharepage",DRIVE_API="https://drive-pc.quark.cn/1/clouddrive/file",TASK_API="https://drive-pc.quark.cn/1/clouddrive/task";const f="pan.quark.cn",p="Quark Drive requires a logged-in browser session";function h(t,e){if(e===401||e===403)return!0;return/not logged in|login required|please log in|authentication required|unauthorized|forbidden|未登录|请先登录|需要登录|登录/.test(t.toLowerCase())}function x(t){if(!t||typeof t!=="object"||!("status"in t))return;const e=t.status;return typeof e==="number"?e:void 0}function c(t,e){if(t.status===200)return t.data;if(h(t.message,t.status))throw new d(f,p);throw new l(`quark: ${e}: ${t.message}`)}export function extractPwdId(t){const e=t.match(/\/s\/([a-zA-Z0-9]+)/);if(e)return e[1];if(/^[a-zA-Z0-9]+$/.test(t))return t;throw new m(`Invalid Quark share URL: ${t}`)}export async function fetchJson(t,e,r){const n=r?.method||"GET",a=r?.body?JSON.stringify(r.body):void 0,i=`fetch(${JSON.stringify(e)}, {
|
|
2
2
|
method: ${JSON.stringify(n)},
|
|
3
3
|
headers: { 'Content-Type': 'application/json' },
|
|
4
4
|
credentials: 'include',
|
|
@@ -10,4 +10,4 @@ import{ArgumentError as m,AuthRequiredError as d,CommandExecutionError as l,getE
|
|
|
10
10
|
throw Object.assign(new Error('Non-JSON response: ' + text.slice(0, 200)), { status: r.status });
|
|
11
11
|
}
|
|
12
12
|
return r.json();
|
|
13
|
-
})`;try{return await t.evaluate(i)}catch(o){if(h(y(o)
|
|
13
|
+
})`;try{return await t.evaluate(i)}catch(o){if(h(y(o),x(o)))throw new d(f,p);throw o}}export async function apiGet(t,e){const r=await fetchJson(t,e);return c(r,"API error")}export async function apiPost(t,e,r){const n=await fetchJson(t,e,{method:"POST",body:r});return c(n,"API error")}export async function getToken(t,e,r=""){const n=await fetchJson(t,`${SHARE_API}/token?pr=ucpro&fr=pc`,{method:"POST",body:{pwd_id:e,passcode:r,support_visit_limit_private_share:!0}});return c(n,"Failed to get token").stoken}export async function getShareList(t,e,r,n="0",a){const i=[];let o=1,s=0;do{const g=a?.sort?`&_sort=${a.sort}`:"",w=`${SHARE_API}/detail?pr=ucpro&fr=pc&ver=2&pwd_id=${e}&stoken=${encodeURIComponent(r)}&pdir_fid=${n}&force=0&_page=${o}&_size=200&_fetch_total=1${g}`,u=await fetchJson(t,w),_=c(u,"Failed to get share list")?.list||[];i.push(..._);s=u.metadata?._total||0;o++}while(i.length<s);return i}export async function listMyDrive(t,e){const r=[];let n=1,a=0;do{const i=`${DRIVE_API}/sort?pr=ucpro&fr=pc&pdir_fid=${e}&_page=${n}&_size=200&_fetch_total=1&_sort=file_type:asc,file_name:asc`,o=await fetchJson(t,i),s=c(o,"Failed to list drive")?.list||[];r.push(...s);a=o.metadata?._total||0;n++}while(r.length<a);return r}export async function findFolder(t,e){const r=e.split("/").filter(Boolean);let n="0";for(const a of r){const o=(await listMyDrive(t,n)).find((s)=>s.dir&&s.file_name===a);if(o)n=o.fid;else throw new l(`quark: Folder "${a}" not found in "${e}"`)}return n}export function formatDate(t){if(!t)return"";return new Date(t).toISOString().replace("T"," ").slice(0,19)}export function formatSize(t){if(t<=0)return"0 B";const e=["B","KB","MB","GB","TB"],r=Math.floor(Math.log(t)/Math.log(1024));return`${(t/Math.pow(1024,r)).toFixed(2)} ${e[r]}`}export async function getTaskStatus(t,e){const r=`${TASK_API}?pr=ucpro&fr=pc&task_id=${e}&retry_index=0`;return apiGet(t,r)}export async function pollTask(t,e,r,n=30,a=500){for(let i=0;i<n;i++){await new Promise((s)=>setTimeout(s,a));const o=await getTaskStatus(t,e);if(o?.status===2){r?.(o);return!0}}return!1}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{CommandExecutionError as
|
|
1
|
+
import{CommandExecutionError as m,EmptyResultError as l}from"@jackwener/opencli/errors";import{cli as u,Strategy as s}from"@jackwener/opencli/registry";import{evaluateQuoraDom as c,normalizeLimit as w,normalizeQuoraUrl as b,openQuoraPage as d}from"./shared.js";u({site:"quora",name:"answer-comments",access:"read",description:"Read visible comments on one Quora answer.",domain:"www.quora.com",strategy:s.UI,browser:!0,args:[{name:"url",type:"string",required:!0,positional:!0,help:"Quora answer URL"},{name:"limit",type:"int",default:20,help:"Number of comments (max 50)"}],columns:["rank","author","content","upvotes","published","authorUrl"],func:async(t,o)=>{const a=b(o.url,{allowProfile:!1,allowQuestion:!1,allowAnswer:!0}),i=w(o.limit,20,50);await d(t,a.url,"answer comments");if(!(await t.evaluate(`(() => {
|
|
2
2
|
const button = document.querySelector('#mainContent .dom_annotate_answer_action_bar_comment button')
|
|
3
3
|
|| Array.from(document.querySelectorAll('#mainContent button[aria-label]'))
|
|
4
4
|
.find((item) => /comment|评论|comentario|commentaire|kommentar/i.test(item.getAttribute('aria-label') || ''));
|
|
5
5
|
if (!button) return { ok: false };
|
|
6
6
|
button.click();
|
|
7
7
|
return { ok: true, label: button.getAttribute('aria-label') || '' };
|
|
8
|
-
})()`))?.ok)throw new
|
|
9
|
-
.some((button) => /^(reply|回复|responder|répondre|antworten)$/i.test((button.innerText || button.textContent || '').trim())))()`))break;await
|
|
8
|
+
})()`))?.ok)throw new m("Quora answer comment control was not found.");for(let e=0;e<15;e++){if(await t.evaluate(`(() => Array.from(document.querySelectorAll('#mainContent button'))
|
|
9
|
+
.some((button) => /^(reply|回复|responder|répondre|antworten)$/i.test((button.innerText || button.textContent || '').trim())))()`))break;await t.wait(1)}const r=((await c(t,"comments"))?.rows||[]).slice(0,i).map((e,n)=>({...e,rank:n+1}));if(!r.length)throw new l("quora answer-comments","This answer has no visible comments.");return r}});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as l,AuthRequiredError as g,CommandExecutionError as t}from"@jackwener/opencli/errors";import{cli as b,Strategy as h}from"@jackwener/opencli/registry";import{assertLiteralContent as p}from"../_shared/content-guard.js";import{tagEditorJs as q,readEditorTextJs as y,insertEditorText as A,clickSubmitJs as m,requireExecute as L,resolveTextInput as S}from"./shared.js";const R=20,I=15,E=["\\banswer\\b","add answer","回答","写回答","répondre","responder","antworten","回答する"],v=["\\bpost\\b","submit","发布","提交","publier","publicar","veröffentlichen","投稿"],U=["\\bpost\\b","done","save","continue","confirm","确定","完成","保存","继续"];function x(){return`(() => {
|
|
2
2
|
const path = location.pathname || '';
|
|
3
3
|
if (/\\blogin\\b/i.test(path + (location.search || ''))) return 'login';
|
|
4
4
|
const visible = (el) => !!el && (el.offsetParent !== null || el.getClientRects().length > 0);
|
|
@@ -9,14 +9,14 @@ import{ArgumentError as $,AuthRequiredError as f,CommandExecutionError as G}from
|
|
|
9
9
|
.find((el) => (el.getBoundingClientRect().height || 0) >= 24);
|
|
10
10
|
if (editor) return 'editor';
|
|
11
11
|
// 否则找「Answer」入口按钮点开
|
|
12
|
-
const re = new RegExp(${JSON.stringify(
|
|
12
|
+
const re = new RegExp(${JSON.stringify(E.join("|"))}, 'i');
|
|
13
13
|
const btn = Array.from(document.querySelectorAll('button, [role="button"], a'))
|
|
14
14
|
.filter(visible)
|
|
15
15
|
.find((el) => re.test((el.getAttribute('aria-label') || '') + ' ' + (el.textContent || '')));
|
|
16
16
|
if (btn) { btn.click(); return 'clicked'; }
|
|
17
17
|
return 'wait';
|
|
18
|
-
})()`}
|
|
18
|
+
})()`}b({site:"quora",name:"create-answer",access:"write",description:"Publish an answer to a Quora question from your logged-in account. Pass the target question URL and the answer body (multi-line allowed). Write a genuine, substantive answer — Quora aggressively flags low-effort/automated content.",domain:"quora.com",strategy:h.UI,browser:!0,args:[{name:"questionUrl",type:"string",required:!0,positional:!0,help:"Target Quora question URL (https://www.quora.com/<question-slug>)"},{name:"content",type:"string",positional:!0,help:"Answer body text, or use --file for long content"},{name:"file",type:"string",help:"Read answer body from a local UTF-8 text file"},{name:"execute",type:"boolean",help:"Actually post the answer"}],columns:["status","questionUrl","message"],func:async(e,n)=>{if(!e)throw new t("Browser session required for quora create-answer");L(n);const r=String(n.questionUrl??"").trim();if(!r)throw new l("Question URL is required.");let u;try{u=new URL(r)}catch{throw new l(`Invalid question URL: ${r}`)}if(!/(^|\.)quora\.com$/.test(u.hostname))throw new l("URL must be a quora.com question URL.");const i=await S(n,{field:"content",label:"Answer content"});if(!n.file)p(i,{label:"回答正文",fileFlag:"--file"});await e.goto(r,{waitUntil:"none"});let c=!1;for(let o=0;o<R;o++){const f=await e.evaluate(x());if(f==="login")throw new g("www.quora.com","Quora 重定向到登录页——未登录");if(f==="editor"){c=!0;break}await e.wait(1)}if(!c)throw new t("未能打开回答编辑器——问题可能不可回答,或页面结构已变(需真机 recon 收紧锚点)。");if(await e.evaluate(q())!=="ready")throw new t("回答编辑器打标失败——未定位到可编辑正文区。");const w=await A(e,i);if(!w?.ok)throw new t(w?.message??"无法把正文写入 Quora 回答编辑器。");const d=await e.evaluate(m(v));if(!d?.ok)throw new t(d?.message??"未找到 Quora 回答提交按钮。");await e.wait(2);if((await e.evaluate(`(() => {
|
|
19
19
|
const dlg = document.querySelector('[role="dialog"]');
|
|
20
20
|
if (!dlg || (dlg.offsetParent === null && dlg.getClientRects().length === 0)) return { present: false };
|
|
21
21
|
return { present: true };
|
|
22
|
-
})()`))?.present){await
|
|
22
|
+
})()`))?.present){await e.evaluate(m(U));await e.wait(2)}const a=(o)=>String(o||"").replace(/\s+/g," ").trim(),s=await e.evaluate(y());if(s!=null&&a(s).length>0&&a(s)===a(i))throw new t("Quora 回答提交后正文仍在编辑器中——提交被拦(限流/风控/无权限,或 credential 弹窗未确认)。回查后再决定是否重试。");return[{status:"success",questionUrl:r,message:"Answer posted."}]}});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as d,AuthRequiredError as b,CommandExecutionError as o}from"@jackwener/opencli/errors";import{cli as w,Strategy as f}from"@jackwener/opencli/registry";import{assertLiteralContent as m}from"../_shared/content-guard.js";import{QUORA_ORIGIN as g,insertEditorText as q,readEditorTextJs as p,clickSubmitJs as x,requireExecute as y}from"./shared.js";const h=20,S=["add question","ask question","\\bask\\b","提问","添加问题","poser une question","preguntar","frage stellen"],A=["add question","\\bnext\\b","submit","done","\\bpost\\b","提交","下一步","发布","完成","添加问题"];function E(){return`(() => {
|
|
2
2
|
if (/\\blogin\\b/i.test((location.pathname || '') + (location.search || ''))) return 'login';
|
|
3
3
|
const visible = (el) => !!el && (el.offsetParent !== null || el.getClientRects().length > 0);
|
|
4
4
|
const dlg = document.querySelector('[role="dialog"]');
|
|
@@ -15,10 +15,10 @@ import{ArgumentError as X,AuthRequiredError as q,CommandExecutionError as F}from
|
|
|
15
15
|
}
|
|
16
16
|
return 'wait';
|
|
17
17
|
}
|
|
18
|
-
const re = new RegExp(${JSON.stringify(
|
|
18
|
+
const re = new RegExp(${JSON.stringify(S.join("|"))}, 'i');
|
|
19
19
|
const btn = Array.from(document.querySelectorAll('button, [role="button"], a'))
|
|
20
20
|
.filter(visible)
|
|
21
21
|
.find((el) => re.test((el.getAttribute('aria-label') || '') + ' ' + (el.textContent || '')));
|
|
22
22
|
if (btn) { btn.click(); return 'clicked'; }
|
|
23
23
|
return 'wait';
|
|
24
|
-
})()`}
|
|
24
|
+
})()`}w({site:"quora",name:"create-question",access:"write",description:"Post a new question to Quora from your logged-in account. Pass the question title. Ask a clear, genuine question — Quora aggressively flags low-effort/automated content.",domain:"quora.com",strategy:f.UI,browser:!0,args:[{name:"title",type:"string",required:!0,positional:!0,help:"The question title (a clear, complete question)"},{name:"execute",type:"boolean",help:"Actually post the question"}],columns:["status","title","message"],func:async(t,a)=>{if(!t)throw new o("Browser session required for quora create-question");y(a);const e=String(a.title??"").trim();if(!e)throw new d("Question title is required.");m(e,{label:"问题标题"});await t.goto(`${g}/`,{waitUntil:"none"});let s=!1;for(let r=0;r<h;r++){const c=await t.evaluate(E());if(c==="login")throw new b("www.quora.com","Quora 重定向到登录页——未登录");if(c==="editor"){s=!0;break}await t.wait(1)}if(!s)throw new o("未能打开 Quora 提问弹窗——顶栏入口或弹窗结构已变(需真机 recon 收紧锚点)。");const l=await q(t,e);if(!l?.ok)throw new o(l?.message??"无法把标题写入 Quora 提问框。");const u=await t.evaluate(x(A));if(!u?.ok)throw new o(u?.message??"未找到 Quora 提问提交按钮。");await t.wait(2);const i=(r)=>String(r||"").replace(/\s+/g," ").trim(),n=await t.evaluate(p());if(n!=null&&i(n).length>0&&i(n)===i(e))throw new o("Quora 提问提交后标题仍在框中——提交被拦(限流/风控/需选主题或身份未确认)。回查后再决定是否重试。");return[{status:"success",title:e,message:"Question posted."}]}});
|
package/clis/quora/shared.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ArgumentError as
|
|
1
|
+
import{ArgumentError as x,AuthRequiredError as S,CommandExecutionError as A}from"@jackwener/opencli/errors";import{readFile as T}from"node:fs/promises";export const QUORA_ORIGIN="https://www.quora.com";export async function hasQuoraAuthCookie(e){return(await e.getCookies({url:QUORA_ORIGIN})).some((r)=>r.name==="m-b"&&r.value)}export async function verifyQuoraAuth(e){if(!await hasQuoraAuthCookie(e))throw new S("www.quora.com","Quora m-b cookie 缺失——当前是游客/未登录会话");await e.goto(QUORA_ORIGIN);await e.wait(2);const u=await e.evaluate("location.pathname + location.search");if(/\blogin\b/i.test(String(u||"")))throw new S("www.quora.com",`Quora 停在登录页 (${u})——已登出`);if(!await hasQuoraAuthCookie(e))throw new S("www.quora.com","Quora m-b cookie 在导航后消失——会话失效");return{logged_in:!0}}export const EDITOR_MARK='[data-pp-quora-editor="1"]';export function tagEditorJs(){return`(() => {
|
|
2
2
|
const visible = (el) => !!el && (el.offsetParent !== null || el.getClientRects().length > 0);
|
|
3
3
|
const scope = document.querySelector('[role="dialog"]') || document;
|
|
4
4
|
const cands = Array.from(scope.querySelectorAll('[contenteditable="true"]'))
|
|
@@ -13,24 +13,24 @@ import{ArgumentError as M,AuthRequiredError as T,CommandExecutionError as _}from
|
|
|
13
13
|
})()`}export function readEditorTextJs(){return`(() => {
|
|
14
14
|
const ed = document.querySelector('${EDITOR_MARK}');
|
|
15
15
|
return ed ? ('value' in ed ? ed.value : (ed.innerText || ed.textContent || '')) : null;
|
|
16
|
-
})()`}export function execInsertJs(
|
|
16
|
+
})()`}export function execInsertJs(e){return`(() => {
|
|
17
17
|
try {
|
|
18
18
|
const ed = document.querySelector('${EDITOR_MARK}');
|
|
19
19
|
if (!ed) return { ok: false, message: '编辑器已消失,无法写入。' };
|
|
20
20
|
ed.focus();
|
|
21
21
|
const normalize = (s) => String(s || '').replace(/\\u00a0/g, ' ').replace(/\\s+/g, ' ').trim();
|
|
22
|
-
if (!document.execCommand('insertText', false, ${JSON.stringify(
|
|
22
|
+
if (!document.execCommand('insertText', false, ${JSON.stringify(e)})) {
|
|
23
23
|
const dt = new DataTransfer();
|
|
24
|
-
dt.setData('text/plain', ${JSON.stringify(
|
|
24
|
+
dt.setData('text/plain', ${JSON.stringify(e)});
|
|
25
25
|
ed.dispatchEvent(new ClipboardEvent('paste', { clipboardData: dt, bubbles: true, cancelable: true }));
|
|
26
26
|
}
|
|
27
27
|
const actual = 'value' in ed ? ed.value : (ed.innerText || ed.textContent || '');
|
|
28
|
-
if (normalize(actual).includes(normalize(${JSON.stringify(
|
|
28
|
+
if (normalize(actual).includes(normalize(${JSON.stringify(e)}))) return { ok: true };
|
|
29
29
|
return { ok: false, message: '写入后未在编辑器中校验到正文。', actualText: actual };
|
|
30
30
|
} catch (e) { return { ok: false, message: String(e) }; }
|
|
31
|
-
})()`}export async function insertEditorText(
|
|
31
|
+
})()`}export async function insertEditorText(e,u){const r=(l)=>String(l||"").replace(/ /g," ").replace(/\s+/g," ").trim(),t=[e.nativeType?.bind(e),e.insertText?.bind(e)].filter(Boolean);for(const l of t)try{await l(u);const o=await e.evaluate(readEditorTextJs());if(o!=null&&r(o).includes(r(u)))return{ok:!0}}catch(o){const y=(o instanceof Error?o.message:String(o)).toLowerCase();if(!(y.includes("unknown action")||y.includes("not supported")||y.includes("no inserted flag")))throw o}return e.evaluate(execInsertJs(u))}export function clickSubmitJs(e){return`(() => {
|
|
32
32
|
const visible = (el) => !!el && (el.offsetParent !== null || el.getClientRects().length > 0);
|
|
33
|
-
const re = new RegExp(${JSON.stringify(
|
|
33
|
+
const re = new RegExp(${JSON.stringify(e.join("|"))}, 'i');
|
|
34
34
|
const scope = document.querySelector('[role="dialog"]') || document;
|
|
35
35
|
const btns = Array.from(scope.querySelectorAll('button, [role="button"]')).filter(visible);
|
|
36
36
|
// 文案匹配至多兜底:优先取未禁用且文案命中的按钮
|
|
@@ -41,18 +41,18 @@ import{ArgumentError as M,AuthRequiredError as T,CommandExecutionError as _}from
|
|
|
41
41
|
if (!hit) return { ok: false, message: '未找到可用的提交按钮(可能未渲染/被禁用/文案不在兜底名单)。' };
|
|
42
42
|
hit.click();
|
|
43
43
|
return { ok: true };
|
|
44
|
-
})()`}export function requireExecute(
|
|
44
|
+
})()`}export function requireExecute(e){if(e.execute!==!0)throw new x("Refusing to write without --execute. Review the target and content, then rerun with --execute.")}export async function resolveTextInput(e,{field:u="content",label:r="content"}={}){const t=e[u]==null?"":String(e[u]),l=e.file==null?"":String(e.file).trim();if(t&&l)throw new x(`Use either <${u}> or --file, not both`);let o=t;if(l)try{o=await T(l,"utf8")}catch(d){throw new x(`Cannot read --file ${l}: ${d instanceof Error?d.message:String(d)}`)}if(!o.trim())throw new x(`${r} cannot be empty`);return o}export function normalizeLimit(e,u=10,r=50){const t=e==null?u:Number(e);if(!Number.isInteger(t)||t<1)throw new x("--limit must be a positive integer");if(t>r)throw new x(`--limit must be <= ${r}`);return t}export function parseCompactCount(e){const r=String(e??"").trim().replace(/,/g,"").match(/(-?\d+(?:\.\d+)?)\s*([KMB])?/i);if(!r)return null;const t={K:1000,M:1e6,B:1e9}[String(r[2]||"").toUpperCase()]||1;return Math.round(Number(r[1])*t)}export function normalizeQuoraUrl(e,{allowProfile:u=!0,allowQuestion:r=!0,allowAnswer:t=!0}={}){const l=String(e??"").trim();if(!l)throw new x("A Quora URL is required");let o;try{o=new URL(l.startsWith("/")?`${QUORA_ORIGIN}${l}`:l)}catch{throw new x(`Invalid Quora URL: ${l}`)}if(o.protocol!=="https:"||o.username||o.password||o.port||!/(^|\.)quora\.com$/i.test(o.hostname))throw new x("URL must be an https://*.quora.com URL");const d=o.pathname.replace(/\/+$/,"")||"/",y=/^\/profile\/[^/]+$/i.test(d),g=/^\/(?!profile\/|topic\/|search$|answer$|stats$)[^/]+\/answers?\/[^/]+$/i.test(d),s=/^\/(?:unanswered\/)?(?!profile\/|topic\/|search$|answer$|stats$)[^/]+$/i.test(d);if((!u||!y)&&(!t||!g)&&(!r||!s))throw new x("Expected a Quora profile, question, or answer URL supported by this command");o.hash="";return{url:o.toString(),path:d,kind:y?"profile":g?"answer":"question"}}export function normalizeProfileTarget(e){const u=String(e??"").trim();if(!u)throw new x("Profile slug or URL is required");if(/^[^/?#\s]+$/.test(u))return{slug:u,url:`${QUORA_ORIGIN}/profile/${encodeURIComponent(u)}`};const r=normalizeQuoraUrl(u,{allowProfile:!0,allowQuestion:!1,allowAnswer:!1});return{slug:decodeURIComponent(r.path.split("/").pop()),url:r.url}}export async function waitForSelector(e,u,r,t=20){for(let l=0;l<t;l++){if(await e.evaluate(`(() => !!document.querySelector(${JSON.stringify(u)}))()`))return;await e.wait(1)}throw new A(`Timed out waiting for ${r}; Quora's visible page structure may have changed.`)}export async function openQuoraPage(e,u,r){if(!e)throw new A(`Browser session required for quora ${r}`);try{await e.goto(u,{waitUntil:"none"})}catch(l){throw new A(`Failed to open Quora ${r}: ${l instanceof Error?l.message:String(l)}`)}const t=new URL(u).pathname.replace(/\/+$/,"")||"/";for(let l=0;l<20;l++){const o=await e.evaluate(`(() => ({
|
|
45
45
|
login: /\\blogin\\b/i.test((location.pathname || '') + (location.search || '')),
|
|
46
46
|
ready: !!document.querySelector('#mainContent'),
|
|
47
47
|
path: (location.pathname || '/').replace(/\\/+$/, '') || '/',
|
|
48
|
-
}))()`);if(
|
|
48
|
+
}))()`);if(o?.login)throw new S("www.quora.com",`Quora login is required for ${r}`);if(o?.ready&&o?.path===t)return;await e.wait(1)}throw new A(`Timed out opening Quora ${r}`)}export async function loadVisibleItems(e,u,r){let t=-1;for(let l=0;l<12;l++){const o=await e.evaluate(`(() => document.querySelectorAll(${JSON.stringify(u)}).length)()`);if(o>=r)return o;if(o===t&&l>=2)return o;t=o;await e.evaluate("(() => { window.scrollTo(0, document.body.scrollHeight); return true; })()");await e.wait(1)}return e.evaluate(`(() => document.querySelectorAll(${JSON.stringify(u)}).length)()`)}export function extractQuoraDom(e,u="#mainContent"){const r=document.querySelector(u);if(!r)return{ok:!1,reason:"main-content-missing",rows:[]};const t=(s)=>String(s??"").replace(/\u00a0/g," ").replace(/[ \t]+/g," ").replace(/\n{3,}/g,`
|
|
49
49
|
|
|
50
|
-
`).trim(),
|
|
51
|
-
`).filter(Boolean);return{rank:
|
|
50
|
+
`).trim(),l=(s)=>{const a=t(s).replace(/,/g,"").match(/(-?\d+(?:\.\d+)?)\s*([KMB])?/i);if(!a)return null;const n={K:1000,M:1e6,B:1e9};return Math.round(Number(a[1])*(n[String(a[2]||"").toUpperCase()]||1))},o=(s)=>{if(!s)return"";try{return new URL(s,location.origin).toString()}catch{return""}},d=(s,a)=>{const n=a==="upvotes"?"button.puppeteer_test_votable_upvote_button":a==="comments"?".dom_annotate_answer_action_bar_comment button":".dom_annotate_answer_action_bar_share button",i=s.querySelector(n)||Array.from(s.querySelectorAll("button[aria-label]")).find((m)=>{const p=m.getAttribute("aria-label")||"";return a==="upvotes"?/upvot|赞同|votar|vote/i.test(p):a==="comments"?/comment|评论|comentario|commentaire|kommentar/i.test(p):/share|分享|compartir|partager|teilen/i.test(p)});if(!i)return 0;const c=i.getAttribute("aria-label")||"";return l(`${c} ${i.innerText||i.textContent||""}`)||0},y=(s,a)=>{let n=s;while(n.parentElement&&n.parentElement!==r&&n.parentElement.querySelectorAll(a).length===1)n=n.parentElement;return n},g=()=>Array.from(r.querySelectorAll(".puppeteer_test_answer_content")).map((s,a)=>{const n=y(s,".puppeteer_test_answer_content"),f=Array.from(n.querySelectorAll('a[href*="/profile/"]')).find((p)=>t(p.innerText||p.textContent)),i=n.querySelector("a.answer_timestamp[href]"),c=n.querySelector(".puppeteer_test_question_title"),m=t(n.innerText||n.textContent).split(`
|
|
51
|
+
`).filter(Boolean);return{rank:a+1,question:t(c?.innerText||c?.textContent),author:t(f?.innerText||f?.textContent||m[0]||"Anonymous"),excerpt:t(s.innerText||s.textContent).replace(/\s*\(more\)\s*$/i,""),upvotes:d(n,"upvotes"),comments:d(n,"comments"),shares:d(n,"shares"),published:t(i?.innerText||i?.textContent),url:o(i?.getAttribute("href")||"")}});if(e==="question"||e==="answers"||e==="search-answer")return{ok:!0,title:t(r.querySelector(".puppeteer_test_question_title")?.innerText||r.querySelector(".puppeteer_test_question_title")?.textContent),rows:g()};if(e==="search-question"){const s=new Set,a=[];for(const n of r.querySelectorAll(".puppeteer_test_question_title")){const f=n.closest("a[href]")||n.parentElement?.closest("a[href]"),i=o(f?.getAttribute("href")||"");if(!i||s.has(i))continue;s.add(i);const c=y(n,".puppeteer_test_question_title"),m=Array.from(c.querySelectorAll("a[href]")).map((p)=>t(p.innerText||p.textContent)).find((p)=>/answers?/i.test(p))||"";a.push({rank:a.length+1,title:t(n.innerText||n.textContent),answers:l(m)||0,url:i})}return{ok:!0,rows:a}}if(e==="answer-detail"){const s=r.querySelector("a.answer_timestamp[href]"),a=r.querySelector("button.puppeteer_test_votable_upvote_button[aria-label]"),n=Array.from(r.querySelectorAll('a[href*="/profile/"]')).find((m)=>t(m.innerText||m.textContent)),f=r.querySelector(".puppeteer_test_question_title"),i=Array.from(r.querySelectorAll("p, li")).filter((m)=>{if(!s||!a)return!1;return Boolean(s.compareDocumentPosition(m)&4)&&Boolean(m.compareDocumentPosition(a)&4)}).map((m)=>t(m.innerText||m.textContent)).filter(Boolean),c=i.length?i.join(`
|
|
52
52
|
|
|
53
|
-
`):
|
|
54
|
-
`).map(
|
|
55
|
-
`).map(
|
|
56
|
-
`):
|
|
57
|
-
`).map(
|
|
58
|
-
`);
|
|
53
|
+
`):t(r.querySelector(".puppeteer_test_answer_content")?.innerText||r.querySelector(".puppeteer_test_answer_content")?.textContent);return{ok:!0,rows:[{question:t(f?.innerText||f?.textContent),author:t(n?.innerText||n?.textContent||"Anonymous"),content:c,upvotes:d(r,"upvotes"),comments:d(r,"comments"),shares:d(r,"shares"),published:t(s?.innerText||s?.textContent),url:o(s?.getAttribute("href")||location.href)}]}}if(e==="answer-queue")return{ok:!0,rows:Array.from(r.querySelectorAll(".puppeteer_test_question_component_base")).map((a,n)=>{const f=a.querySelector(".puppeteer_test_question_title"),i=f?.closest("a[href]")||f?.parentElement?.closest("a[href]"),c=Array.from(a.querySelectorAll("a[href]")).map((m)=>t(m.innerText||m.textContent)).find((m)=>/answers?|no answer/i.test(m))||"";return{rank:n+1,title:t(f?.innerText||f?.textContent),answers:/no answer/i.test(c)?0:l(c)||0,url:o(i?.getAttribute("href")||"")}})};if(e==="profile"){const s=t(r.innerText||r.textContent),a=u==="#mainContent"?t(document.body.innerText||document.body.textContent):s,n=s.split(`
|
|
54
|
+
`).map(t).filter(Boolean),f=t(document.title.replace(/\s*-\s*Quora\s*$/i,""))||n[0]||"",i=Array.from(r.querySelectorAll("div, span")).map((p)=>t(p.innerText||p.textContent)).filter((p)=>p&&p.length<=300),c=(p)=>l(s.match(p)?.[1]||""),m=l(a.match(/([\d.,]+\s*[KMB]?)\s+content views/i)?.[1]||"");return{ok:!0,rows:[{name:f,bio:i.find((p)=>p!==f&&!/followers?|following|answers?|questions?|posts?|profile|content views|this month/i.test(p))||n.find((p)=>p!==f&&!/followers?|following|answers?|questions?|posts?|profile|content views|this month/i.test(p))||"",followers:c(/([\d.,]+\s*[KMB]?)\s+followers/i),following:c(/([\d.,]+\s*[KMB]?)\s+following/i),answers:c(/([\d.,]+\s*[KMB]?)\s+answers/i),questions:c(/([\d.,]+\s*[KMB]?)\s+questions/i),posts:c(/([\d.,]+\s*[KMB]?)\s+posts/i),contentViews:m,url:location.href.split(/[?#]/)[0].replace(/\/(?:answers|questions|posts|followers|following)\/?$/,"")}]}}if(e==="followers"){const s=new Set,a=[];for(const n of r.querySelectorAll('a[href*="/profile/"]')){const f=t(n.innerText||n.textContent),i=o(n.getAttribute("href")||"");if(!f||!i||s.has(i))continue;let c=n;while(c.parentElement&&c.parentElement!==r){const h=c.parentElement;if(new Set(Array.from(h.querySelectorAll('a[href*="/profile/"]'),(C)=>o(C.getAttribute("href")||""))).size>1)break;c=h;if(/\d[\d.,]*\s*[KMB]?\s+followers?/i.test(t(c.innerText||c.textContent)))break}const m=t(c.innerText||c.textContent),p=m.match(/([\d.,]+\s*[KMB]?)\s+followers?/i),b=m.split(`
|
|
55
|
+
`).map(t).filter(Boolean),q=Array.from(c.querySelectorAll("div, span")).map((h)=>t(h.innerText||h.textContent)).filter((h)=>h&&h.length<=300);a.push({rank:a.length+1,name:f,headline:q.find((h)=>h!==f&&!/followers?|^follow$/i.test(h))||b.find((h)=>h!==f&&!/followers?|^follow$/i.test(h))||"",followers:l(p?.[1]||"")||0,url:i});s.add(i)}return{ok:!0,rows:a}}if(e==="stats"){const s=t(r.innerText||r.textContent),a=(f)=>{const i=s.match(new RegExp(`${f}\\s*[–—-]?\\s*([\\d.,]+\\s*[KMB]?)`,"i"));return l(i?.[1]||"")||0};return{ok:!0,rows:[{period:s.match(/Last\s+\d+\s+days|All time/i)?.[0]||"Current",views:a("Views"),upvotes:a("Upvotes"),comments:a("Comments"),shares:a("Shares \\(external\\)")}]}}if(e==="comments"){const s=new Set,a=[],n=Array.from(r.querySelectorAll("button")).filter((f)=>/^reply$/i.test(t(f.innerText||f.textContent)));for(const f of n){let i=f;while(i.parentElement&&i.parentElement!==r){const w=i.parentElement;if(Array.from(w.querySelectorAll("button")).filter((v)=>/^reply$/i.test(t(v.innerText||v.textContent))).length!==1)break;i=w;if(i.querySelector('a[href*="/profile/"]'))break}const c=Array.from(i.querySelectorAll('a[href*="/profile/"]')).find((w)=>t(w.innerText||w.textContent)),m=t(c?.innerText||c?.textContent),p=o(c?.getAttribute("href")||""),b=t(i.innerText||i.textContent),q=`${p}:${b}`;if(!m||s.has(q))continue;const h=Array.from(i.querySelectorAll("a")).map((w)=>t(w.innerText||w.textContent)).find((w)=>/^(?:updated\s+)?(?:\d+[smhdwy]|mon|tue|wed|thu|fri|sat|sun|[A-Z][a-z]{2}\s+\d{1,2})$/i.test(w))||b.match(/(?:^|\s)(\d+[smhdwy]|mon|tue|wed|thu|fri|sat|sun)(?:\s|$)/i)?.[1]||"",_=Array.from(i.querySelectorAll("p")).map((w)=>t(w.innerText||w.textContent)).filter(Boolean),C=_.length?_.join(`
|
|
56
|
+
`):b.split(`
|
|
57
|
+
`).map(t).filter((w)=>w&&w!==m&&w!==h&&!/^reply$/i.test(w)).join(`
|
|
58
|
+
`);a.push({rank:a.length+1,author:m,content:C,upvotes:d(i,"upvotes"),published:h,authorUrl:p});s.add(q)}return{ok:!0,rows:a}}return{ok:!1,reason:`unsupported-mode:${e}`,rows:[]}}export async function evaluateQuoraDom(e,u,r="#mainContent"){return e.evaluate(`(${extractQuoraDom.toString()})(${JSON.stringify(u)}, ${JSON.stringify(r)})`)}
|
package/clis/quora/whoami.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthRequiredError as
|
|
1
|
+
import{AuthRequiredError as u}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as e}from"../_shared/site-auth.js";import{hasQuoraAuthCookie as r,verifyQuoraAuth as i,QUORA_ORIGIN as t}from"./shared.js";e({site:"quora",domain:"quora.com",loginUrl:`${t}/`,whoamiDescription:"检测 Quora 当前登录状态(返回布尔 logged_in)。",loginDescription:"打开 Quora 登录页并等待浏览器会话完成登录。",columns:[],quickCheck:r,verify:i,poll:async(o)=>{if(!await r(o))throw new u("www.quora.com","等待 Quora 登录(m-b cookie 尚未就绪)");return i(o)}});
|