publishport-opencli 1.0.0
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/LICENSE +214 -0
- package/README.md +299 -0
- package/README.zh-CN.md +341 -0
- package/cli-manifest.json +51513 -0
- package/clis/12306/auth.js +25 -0
- package/clis/12306/me.js +9 -0
- package/clis/12306/orders.js +13 -0
- package/clis/12306/passengers.js +14 -0
- package/clis/12306/price.js +1 -0
- package/clis/12306/stations.js +1 -0
- package/clis/12306/train.js +1 -0
- package/clis/12306/trains.js +1 -0
- package/clis/12306/utils.js +1 -0
- package/clis/1688/assets.js +127 -0
- package/clis/1688/auth.js +1 -0
- package/clis/1688/download.js +1 -0
- package/clis/1688/item.js +21 -0
- package/clis/1688/search.js +129 -0
- package/clis/1688/shared.js +11 -0
- package/clis/1688/store.js +26 -0
- package/clis/1point3acres/auth.js +18 -0
- package/clis/1point3acres/digest.js +1 -0
- package/clis/1point3acres/forum.js +1 -0
- package/clis/1point3acres/forums.js +1 -0
- package/clis/1point3acres/hot.js +1 -0
- package/clis/1point3acres/latest.js +1 -0
- package/clis/1point3acres/notifications.js +1 -0
- package/clis/1point3acres/search.js +1 -0
- package/clis/1point3acres/thread.js +2 -0
- package/clis/1point3acres/user.js +1 -0
- package/clis/1point3acres/utils.js +6 -0
- package/clis/36kr/article.js +20 -0
- package/clis/36kr/hot.js +16 -0
- package/clis/36kr/news.js +1 -0
- package/clis/36kr/search.js +36 -0
- package/clis/51job/company.js +36 -0
- package/clis/51job/detail.js +35 -0
- package/clis/51job/hot.js +1 -0
- package/clis/51job/search.js +1 -0
- package/clis/51job/utils.js +21 -0
- package/clis/_atlassian/shared.js +21 -0
- package/clis/_shared/article/auth.js +16 -0
- package/clis/_shared/article/douban-md2draft.js +4 -0
- package/clis/_shared/article/format.js +1 -0
- package/clis/_shared/article/images.js +95 -0
- package/clis/_shared/article/login.js +1 -0
- package/clis/_shared/article/page-runtime.js +745 -0
- package/clis/_shared/article/publish.js +34 -0
- package/clis/_shared/common.js +1 -0
- package/clis/_shared/content-guard.js +1 -0
- package/clis/_shared/desktop-commands.js +1 -0
- package/clis/_shared/search-adapter.js +1 -0
- package/clis/_shared/site-auth.js +1 -0
- package/clis/_shared/token-auth.js +2 -0
- package/clis/_shared/video-publish.js +62 -0
- package/clis/aibase/news.js +31 -0
- package/clis/amazon/auth.js +19 -0
- package/clis/amazon/bestsellers.js +1 -0
- package/clis/amazon/discussion.js +20 -0
- package/clis/amazon/movers-shakers.js +1 -0
- package/clis/amazon/new-releases.js +1 -0
- package/clis/amazon/offer.js +29 -0
- package/clis/amazon/product.js +25 -0
- package/clis/amazon/rankings.js +68 -0
- package/clis/amazon/search.js +16 -0
- package/clis/amazon/shared.js +11 -0
- package/clis/antigravity/SKILL.md +38 -0
- package/clis/antigravity/_actions.js +201 -0
- package/clis/antigravity/audit-extras.js +78 -0
- package/clis/antigravity/delete.js +1 -0
- package/clis/antigravity/dump.js +1 -0
- package/clis/antigravity/extract-code.js +18 -0
- package/clis/antigravity/history.js +1 -0
- package/clis/antigravity/mark-read.js +1 -0
- package/clis/antigravity/model.js +90 -0
- package/clis/antigravity/new.js +9 -0
- package/clis/antigravity/read.js +10 -0
- package/clis/antigravity/rename.js +1 -0
- package/clis/antigravity/send.js +11 -0
- package/clis/antigravity/serve.js +97 -0
- package/clis/antigravity/status.js +1 -0
- package/clis/antigravity/storage.js +12 -0
- package/clis/antigravity/watch.js +6 -0
- package/clis/apple-podcasts/episodes.js +1 -0
- package/clis/apple-podcasts/search.js +1 -0
- package/clis/apple-podcasts/top.js +1 -0
- package/clis/apple-podcasts/utils.js +1 -0
- package/clis/archive/item.js +1 -0
- package/clis/archive/search.js +1 -0
- package/clis/archive/snapshots.js +1 -0
- package/clis/archive/wayback.js +1 -0
- package/clis/arxiv/author.js +1 -0
- package/clis/arxiv/paper.js +1 -0
- package/clis/arxiv/recent.js +1 -0
- package/clis/arxiv/search.js +1 -0
- package/clis/arxiv/utils.js +1 -0
- package/clis/autohome/__fixtures__/catalog.html +11 -0
- package/clis/autohome/__fixtures__/koubei.json +116 -0
- package/clis/autohome/brand.js +1 -0
- package/clis/autohome/score.js +1 -0
- package/clis/autohome/utils.js +1 -0
- package/clis/baidu-scholar/search.js +63 -0
- package/clis/baijiahao/article.js +1 -0
- package/clis/baijiahao/lists.js +1 -0
- package/clis/baijiahao/login.js +1 -0
- package/clis/baijiahao/publish.js +57 -0
- package/clis/baijiahao/stats.js +1 -0
- package/clis/baijiahao/whoami.js +1 -0
- package/clis/band/auth.js +29 -0
- package/clis/band/bands.js +37 -0
- package/clis/band/mentions.js +6 -0
- package/clis/band/post.js +76 -0
- package/clis/band/posts.js +50 -0
- package/clis/barchart/flow.js +70 -0
- package/clis/barchart/greeks.js +88 -0
- package/clis/barchart/options.js +61 -0
- package/clis/barchart/quote.js +87 -0
- package/clis/bbc/news.js +1 -0
- package/clis/bbc/topic.js +1 -0
- package/clis/bbc/utils.js +1 -0
- package/clis/bilibili/article.js +1 -0
- package/clis/bilibili/auth.js +1 -0
- package/clis/bilibili/categories.js +1 -0
- package/clis/bilibili/coin.js +1 -0
- package/clis/bilibili/comment-del.js +1 -0
- package/clis/bilibili/comment-like.js +1 -0
- package/clis/bilibili/comment.js +1 -0
- package/clis/bilibili/comments.js +1 -0
- package/clis/bilibili/dm-list.js +1 -0
- package/clis/bilibili/dm-read.js +1 -0
- package/clis/bilibili/dm-send.js +1 -0
- package/clis/bilibili/download.js +7 -0
- package/clis/bilibili/drafts.js +1 -0
- package/clis/bilibili/dynamic-post.js +24 -0
- package/clis/bilibili/dynamic.js +1 -0
- package/clis/bilibili/favorite-add.js +1 -0
- package/clis/bilibili/favorite.js +1 -0
- package/clis/bilibili/feed.js +2 -0
- package/clis/bilibili/follow.js +1 -0
- package/clis/bilibili/following.js +1 -0
- package/clis/bilibili/history.js +1 -0
- package/clis/bilibili/hot.js +15 -0
- package/clis/bilibili/like.js +1 -0
- package/clis/bilibili/me.js +1 -0
- package/clis/bilibili/partitions.js +1 -0
- package/clis/bilibili/ranking.js +1 -0
- package/clis/bilibili/search.js +1 -0
- package/clis/bilibili/stats.js +1 -0
- package/clis/bilibili/subtitle.js +21 -0
- package/clis/bilibili/summary.js +1 -0
- package/clis/bilibili/topics.js +1 -0
- package/clis/bilibili/unfollow.js +1 -0
- package/clis/bilibili/upload.js +1 -0
- package/clis/bilibili/user-videos.js +1 -0
- package/clis/bilibili/utils.js +50 -0
- package/clis/bilibili/video-drafts.js +1 -0
- package/clis/bilibili/video.js +1 -0
- package/clis/binance/asks.js +1 -0
- package/clis/binance/depth.js +1 -0
- package/clis/binance/gainers.js +1 -0
- package/clis/binance/klines.js +1 -0
- package/clis/binance/losers.js +1 -0
- package/clis/binance/pairs.js +1 -0
- package/clis/binance/price.js +1 -0
- package/clis/binance/prices.js +1 -0
- package/clis/binance/ticker.js +1 -0
- package/clis/binance/top.js +1 -0
- package/clis/binance/trades.js +1 -0
- package/clis/bloomberg/businessweek.js +12 -0
- package/clis/bloomberg/crypto.js +1 -0
- package/clis/bloomberg/economics.js +1 -0
- package/clis/bloomberg/feeds.js +1 -0
- package/clis/bloomberg/green.js +1 -0
- package/clis/bloomberg/industries.js +1 -0
- package/clis/bloomberg/main.js +1 -0
- package/clis/bloomberg/markets.js +1 -0
- package/clis/bloomberg/news.js +57 -0
- package/clis/bloomberg/opinions.js +1 -0
- package/clis/bloomberg/politics.js +1 -0
- package/clis/bloomberg/pursuits.js +1 -0
- package/clis/bloomberg/tech.js +1 -0
- package/clis/bloomberg/utils.js +17 -0
- package/clis/bluesky/post.js +1 -0
- package/clis/bluesky/shared.js +56 -0
- package/clis/bluesky/whoami.js +1 -0
- package/clis/booking/search.js +93 -0
- package/clis/boss/auth.js +13 -0
- package/clis/boss/batchgreet.js +1 -0
- package/clis/boss/chatlist.js +1 -0
- package/clis/boss/chatmsg.js +1 -0
- package/clis/boss/detail.js +1 -0
- package/clis/boss/exchange.js +1 -0
- package/clis/boss/greet.js +1 -0
- package/clis/boss/invite.js +4 -0
- package/clis/boss/joblist.js +1 -0
- package/clis/boss/mark.js +1 -0
- package/clis/boss/recommend.js +1 -0
- package/clis/boss/resume.js +90 -0
- package/clis/boss/search.js +1 -0
- package/clis/boss/send.js +1 -0
- package/clis/boss/stats.js +1 -0
- package/clis/boss/utils.js +161 -0
- package/clis/brave/search.js +23 -0
- package/clis/chaoxing/assignments.js +1 -0
- package/clis/chaoxing/auth.js +21 -0
- package/clis/chaoxing/exams.js +1 -0
- package/clis/chaoxing/utils.js +58 -0
- package/clis/chatgpt/ask.js +1 -0
- package/clis/chatgpt/auth.js +17 -0
- package/clis/chatgpt/detail.js +1 -0
- package/clis/chatgpt/history.js +1 -0
- package/clis/chatgpt/image.js +1 -0
- package/clis/chatgpt/model.js +1 -0
- package/clis/chatgpt/new.js +1 -0
- package/clis/chatgpt/project-file-add.js +1 -0
- package/clis/chatgpt/project-list.js +1 -0
- package/clis/chatgpt/read.js +1 -0
- package/clis/chatgpt/send.js +1 -0
- package/clis/chatgpt/status.js +1 -0
- package/clis/chatgpt/utils.js +1092 -0
- package/clis/chatgpt-app/ask.js +1 -0
- package/clis/chatgpt-app/ax.js +512 -0
- package/clis/chatgpt-app/model.js +1 -0
- package/clis/chatgpt-app/new.js +1 -0
- package/clis/chatgpt-app/read.js +1 -0
- package/clis/chatgpt-app/send.js +1 -0
- package/clis/chatgpt-app/status.js +1 -0
- package/clis/chatwise/ask.js +1 -0
- package/clis/chatwise/export.js +21 -0
- package/clis/chatwise/history.js +26 -0
- package/clis/chatwise/model.js +48 -0
- package/clis/chatwise/new.js +1 -0
- package/clis/chatwise/read.js +25 -0
- package/clis/chatwise/screenshot.js +1 -0
- package/clis/chatwise/send.js +1 -0
- package/clis/chatwise/status.js +1 -0
- package/clis/chatwise/utils.js +75 -0
- package/clis/chess/analyze.js +1 -0
- package/clis/chess/game.js +1 -0
- package/clis/chess/games.js +1 -0
- package/clis/chess/stats.js +1 -0
- package/clis/chess/utils.js +1 -0
- package/clis/claude/ask.js +4 -0
- package/clis/claude/auth.js +19 -0
- package/clis/claude/detail.js +1 -0
- package/clis/claude/history.js +1 -0
- package/clis/claude/new.js +1 -0
- package/clis/claude/read.js +1 -0
- package/clis/claude/send.js +1 -0
- package/clis/claude/status.js +1 -0
- package/clis/claude/utils.js +179 -0
- package/clis/cnblogs/article.js +1 -0
- package/clis/cnblogs/login.js +1 -0
- package/clis/cnblogs/stats.js +37 -0
- package/clis/cnblogs/whoami.js +1 -0
- package/clis/cnki/search.js +38 -0
- package/clis/codex/_actions.js +72 -0
- package/clis/codex/archive.js +1 -0
- package/clis/codex/ask.js +23 -0
- package/clis/codex/dump.js +1 -0
- package/clis/codex/export.js +12 -0
- package/clis/codex/extract-diff.js +28 -0
- package/clis/codex/history.js +1 -0
- package/clis/codex/model.js +118 -0
- package/clis/codex/new.js +1 -0
- package/clis/codex/pin.js +1 -0
- package/clis/codex/projects.js +1 -0
- package/clis/codex/read.js +16 -0
- package/clis/codex/rename.js +34 -0
- package/clis/codex/screenshot.js +1 -0
- package/clis/codex/send.js +16 -0
- package/clis/codex/sidebar.js +1 -0
- package/clis/codex/status.js +1 -0
- package/clis/coingecko/categories.js +1 -0
- package/clis/coingecko/coin.js +1 -0
- package/clis/coingecko/derivatives.js +1 -0
- package/clis/coingecko/exchanges.js +1 -0
- package/clis/coingecko/global.js +1 -0
- package/clis/coingecko/top.js +1 -0
- package/clis/coingecko/trending.js +1 -0
- package/clis/confluence/create.js +1 -0
- package/clis/confluence/page.js +1 -0
- package/clis/confluence/search.js +1 -0
- package/clis/confluence/shared.js +1 -0
- package/clis/confluence/update.js +1 -0
- package/clis/coupang/add-to-cart.js +86 -0
- package/clis/coupang/auth.js +16 -0
- package/clis/coupang/product.js +161 -0
- package/clis/coupang/search.js +385 -0
- package/clis/coupang/utils.js +1 -0
- package/clis/crates/crate.js +1 -0
- package/clis/crates/search.js +1 -0
- package/clis/crates/utils.js +1 -0
- package/clis/csdn/article.js +29 -0
- package/clis/csdn/columns.js +1 -0
- package/clis/csdn/login.js +1 -0
- package/clis/csdn/stats.js +71 -0
- package/clis/csdn/whoami.js +1 -0
- package/clis/cto51/article.js +1 -0
- package/clis/cto51/whoami.js +1 -0
- package/clis/ctrip/auth.js +1 -0
- package/clis/ctrip/flight.js +17 -0
- package/clis/ctrip/hotel-search.js +24 -0
- package/clis/ctrip/hotel-suggest.js +1 -0
- package/clis/ctrip/search.js +1 -0
- package/clis/ctrip/utils.js +119 -0
- package/clis/cursor/ask.js +22 -0
- package/clis/cursor/composer.js +12 -0
- package/clis/cursor/dump.js +1 -0
- package/clis/cursor/export.js +23 -0
- package/clis/cursor/extract-code.js +18 -0
- package/clis/cursor/history.js +26 -0
- package/clis/cursor/model.js +18 -0
- package/clis/cursor/new.js +1 -0
- package/clis/cursor/read.js +27 -0
- package/clis/cursor/screenshot.js +1 -0
- package/clis/cursor/send.js +12 -0
- package/clis/cursor/status.js +1 -0
- package/clis/dblp/author.js +1 -0
- package/clis/dblp/paper.js +1 -0
- package/clis/dblp/search.js +1 -0
- package/clis/dblp/utils.js +1 -0
- package/clis/dblp/venue.js +1 -0
- package/clis/deepseek/ask.js +1 -0
- package/clis/deepseek/auth.js +22 -0
- package/clis/deepseek/detail.js +1 -0
- package/clis/deepseek/history.js +1 -0
- package/clis/deepseek/new.js +1 -0
- package/clis/deepseek/read.js +1 -0
- package/clis/deepseek/send.js +50 -0
- package/clis/deepseek/status.js +1 -0
- package/clis/deepseek/utils.js +202 -0
- package/clis/defillama/protocol.js +1 -0
- package/clis/defillama/protocols.js +1 -0
- package/clis/defillama/utils.js +1 -0
- package/clis/devto/auth.js +9 -0
- package/clis/devto/latest.js +1 -0
- package/clis/devto/publish.js +17 -0
- package/clis/devto/read.js +3 -0
- package/clis/devto/stats.js +27 -0
- package/clis/devto/tag.js +1 -0
- package/clis/devto/top.js +1 -0
- package/clis/devto/user.js +1 -0
- package/clis/dianping/__fixtures__/search.html +168 -0
- package/clis/dianping/__fixtures__/shop.html +6 -0
- package/clis/dianping/auth.js +10 -0
- package/clis/dianping/cityResolver.js +4 -0
- package/clis/dianping/search.js +1 -0
- package/clis/dianping/shop.js +1 -0
- package/clis/dianping/utils.js +1 -0
- package/clis/dictionary/examples.js +1 -0
- package/clis/dictionary/search.js +1 -0
- package/clis/dictionary/synonyms.js +1 -0
- package/clis/discord-app/channels.js +1 -0
- package/clis/discord-app/delete.js +66 -0
- package/clis/discord-app/goto.js +1 -0
- package/clis/discord-app/members.js +21 -0
- package/clis/discord-app/read.js +1 -0
- package/clis/discord-app/search.js +29 -0
- package/clis/discord-app/send.js +10 -0
- package/clis/discord-app/servers.js +1 -0
- package/clis/discord-app/status.js +1 -0
- package/clis/discord-app/thread-read.js +1 -0
- package/clis/discord-app/threads.js +1 -0
- package/clis/discord-app/utils.js +226 -0
- package/clis/discord-web/auth.js +10 -0
- package/clis/discord-web/send.js +13 -0
- package/clis/dockerhub/image.js +1 -0
- package/clis/dockerhub/search.js +1 -0
- package/clis/dockerhub/utils.js +1 -0
- package/clis/dongchedi/__fixtures__/search.json +60 -0
- package/clis/dongchedi/__fixtures__/series-detail.json +911 -0
- package/clis/dongchedi/__fixtures__/series-score.json +1396 -0
- package/clis/dongchedi/koubei.js +1 -0
- package/clis/dongchedi/models.js +1 -0
- package/clis/dongchedi/score.js +1 -0
- package/clis/dongchedi/search.js +1 -0
- package/clis/dongchedi/series.js +1 -0
- package/clis/dongchedi/specs.js +1 -0
- package/clis/dongchedi/utils.js +1 -0
- package/clis/douban/article.js +53 -0
- package/clis/douban/auth.js +21 -0
- package/clis/douban/book-hot.js +1 -0
- package/clis/douban/download.js +1 -0
- package/clis/douban/marks.js +59 -0
- package/clis/douban/movie-hot.js +1 -0
- package/clis/douban/photos.js +1 -0
- package/clis/douban/reviews.js +53 -0
- package/clis/douban/search.js +1 -0
- package/clis/douban/subject.js +1 -0
- package/clis/douban/top250.js +50 -0
- package/clis/douban/utils.js +344 -0
- package/clis/doubao/ask.js +1 -0
- package/clis/doubao/auth.js +28 -0
- package/clis/doubao/detail.js +1 -0
- package/clis/doubao/history.js +1 -0
- package/clis/doubao/meeting-summary.js +1 -0
- package/clis/doubao/meeting-transcript.js +1 -0
- package/clis/doubao/new.js +1 -0
- package/clis/doubao/read.js +1 -0
- package/clis/doubao/send.js +1 -0
- package/clis/doubao/status.js +1 -0
- package/clis/doubao/utils.js +704 -0
- package/clis/doubao-app/ask.js +1 -0
- package/clis/doubao-app/dump.js +1 -0
- package/clis/doubao-app/new.js +1 -0
- package/clis/doubao-app/read.js +1 -0
- package/clis/doubao-app/screenshot.js +1 -0
- package/clis/doubao-app/send.js +1 -0
- package/clis/doubao-app/status.js +1 -0
- package/clis/doubao-app/utils.js +64 -0
- package/clis/douyin/_shared/browser-fetch.js +28 -0
- package/clis/douyin/_shared/creation-id.js +1 -0
- package/clis/douyin/_shared/evaluate-result.js +1 -0
- package/clis/douyin/_shared/imagex-upload.js +1 -0
- package/clis/douyin/_shared/public-api.js +1 -0
- package/clis/douyin/_shared/sts2.js +1 -0
- package/clis/douyin/_shared/text-extra.js +1 -0
- package/clis/douyin/_shared/timing.js +1 -0
- package/clis/douyin/_shared/tos-upload.js +5 -0
- package/clis/douyin/_shared/transcode.js +1 -0
- package/clis/douyin/_shared/types.js +1 -0
- package/clis/douyin/_shared/vod-upload.js +5 -0
- package/clis/douyin/activities.js +1 -0
- package/clis/douyin/auth.js +1 -0
- package/clis/douyin/collections.js +1 -0
- package/clis/douyin/delete.js +76 -0
- package/clis/douyin/draft.js +166 -0
- package/clis/douyin/drafts.js +1 -0
- package/clis/douyin/hashtag.js +1 -0
- package/clis/douyin/location.js +1 -0
- package/clis/douyin/profile.js +1 -0
- package/clis/douyin/publish-image.js +64 -0
- package/clis/douyin/publish.js +14 -0
- package/clis/douyin/search.js +51 -0
- package/clis/douyin/stats.js +1 -0
- package/clis/douyin/update.js +1 -0
- package/clis/douyin/user-videos.js +1 -0
- package/clis/douyin/videos.js +1 -0
- package/clis/duckduckgo/search.js +1 -0
- package/clis/duckduckgo/suggest.js +1 -0
- package/clis/eastmoney/_secid.js +1 -0
- package/clis/eastmoney/announcement.js +1 -0
- package/clis/eastmoney/article.js +1 -0
- package/clis/eastmoney/convertible.js +1 -0
- package/clis/eastmoney/etf.js +1 -0
- package/clis/eastmoney/holders.js +1 -0
- package/clis/eastmoney/hot-rank.js +30 -0
- package/clis/eastmoney/index-board.js +1 -0
- package/clis/eastmoney/kline.js +1 -0
- package/clis/eastmoney/kuaixun.js +1 -0
- package/clis/eastmoney/longhu.js +1 -0
- package/clis/eastmoney/money-flow.js +1 -0
- package/clis/eastmoney/northbound.js +1 -0
- package/clis/eastmoney/quote.js +1 -0
- package/clis/eastmoney/rank.js +1 -0
- package/clis/eastmoney/sectors.js +1 -0
- package/clis/eastmoney/whoami.js +1 -0
- package/clis/endoflife/product.js +1 -0
- package/clis/endoflife/utils.js +1 -0
- package/clis/facebook/__fixtures__/notifications-page.html +13 -0
- package/clis/facebook/add-friend.js +24 -0
- package/clis/facebook/auth.js +1 -0
- package/clis/facebook/comment.js +18 -0
- package/clis/facebook/events.js +26 -0
- package/clis/facebook/feed.js +209 -0
- package/clis/facebook/friends.js +24 -0
- package/clis/facebook/groups.js +32 -0
- package/clis/facebook/join-group.js +25 -0
- package/clis/facebook/like.js +29 -0
- package/clis/facebook/marketplace-inbox.js +34 -0
- package/clis/facebook/marketplace-listings.js +33 -0
- package/clis/facebook/memories.js +21 -0
- package/clis/facebook/notifications.js +31 -0
- package/clis/facebook/post.js +88 -0
- package/clis/facebook/profile.js +18 -0
- package/clis/facebook/search.js +22 -0
- package/clis/flathub/app.js +1 -0
- package/clis/flathub/search.js +1 -0
- package/clis/flathub/utils.js +1 -0
- package/clis/flomo/auth.js +22 -0
- package/clis/flomo/memos.js +13 -0
- package/clis/gemini/ask.js +1 -0
- package/clis/gemini/auth.js +14 -0
- package/clis/gemini/deep-research-result.js +4 -0
- package/clis/gemini/deep-research.js +1 -0
- package/clis/gemini/detail.js +1 -0
- package/clis/gemini/history.js +1 -0
- package/clis/gemini/image.js +3 -0
- package/clis/gemini/new.js +1 -0
- package/clis/gemini/read.js +1 -0
- package/clis/gemini/status.js +1 -0
- package/clis/gemini/utils.js +1234 -0
- package/clis/geogebra/add-circle.js +1 -0
- package/clis/geogebra/add-line.js +1 -0
- package/clis/geogebra/add-point.js +1 -0
- package/clis/geogebra/add-polygon.js +1 -0
- package/clis/geogebra/eval.js +1 -0
- package/clis/geogebra/hexagon.js +1 -0
- package/clis/geogebra/info.js +13 -0
- package/clis/geogebra/list.js +1 -0
- package/clis/geogebra/triangle.js +1 -0
- package/clis/geogebra/utils.js +99 -0
- package/clis/ghost/publish.js +1 -0
- package/clis/ghost/shared.js +1 -0
- package/clis/ghost/whoami.js +1 -0
- package/clis/gitee/auth.js +12 -0
- package/clis/gitee/index.js +1 -0
- package/clis/gitee/search.js +1 -0
- package/clis/gitee/trending.js +240 -0
- package/clis/gitee/user.js +71 -0
- package/clis/github/auth.js +7 -0
- package/clis/github-trending/repos.js +1 -0
- package/clis/google/news.js +1 -0
- package/clis/google/search.js +90 -0
- package/clis/google/suggest.js +1 -0
- package/clis/google/trends.js +1 -0
- package/clis/google/utils.js +1 -0
- package/clis/google-scholar/cite.js +20 -0
- package/clis/google-scholar/profile.js +36 -0
- package/clis/google-scholar/search.js +35 -0
- package/clis/goproxy/module.js +1 -0
- package/clis/goproxy/utils.js +1 -0
- package/clis/goproxy/versions.js +1 -0
- package/clis/gov-law/recent.js +1 -0
- package/clis/gov-law/search.js +14 -0
- package/clis/gov-law/shared.js +29 -0
- package/clis/gov-policy/__fixtures__/recent.html +16 -0
- package/clis/gov-policy/__fixtures__/search.html +41 -0
- package/clis/gov-policy/recent.js +8 -0
- package/clis/gov-policy/search.js +8 -0
- package/clis/gov-policy/utils.js +1 -0
- package/clis/grok/ask.js +1 -0
- package/clis/grok/auth.js +17 -0
- package/clis/grok/delete.js +1 -0
- package/clis/grok/detail.js +1 -0
- package/clis/grok/export-all.js +170 -0
- package/clis/grok/export-utils.js +1 -0
- package/clis/grok/export.js +106 -0
- package/clis/grok/history.js +1 -0
- package/clis/grok/image.js +119 -0
- package/clis/grok/image.test.ts +127 -0
- package/clis/grok/new.js +1 -0
- package/clis/grok/pin.js +1 -0
- package/clis/grok/read.js +1 -0
- package/clis/grok/send.js +1 -0
- package/clis/grok/status.js +1 -0
- package/clis/grok/utils.js +337 -0
- package/clis/guazi/__fixtures__/detail.html +7 -0
- package/clis/guazi/__fixtures__/list.html +5 -0
- package/clis/guazi/browse.js +1 -0
- package/clis/guazi/car.js +1 -0
- package/clis/guazi/utils.js +1 -0
- package/clis/hackernews/ask.js +1 -0
- package/clis/hackernews/auth.js +9 -0
- package/clis/hackernews/best.js +1 -0
- package/clis/hackernews/comment.js +61 -0
- package/clis/hackernews/jobs.js +1 -0
- package/clis/hackernews/new.js +1 -0
- package/clis/hackernews/read.js +11 -0
- package/clis/hackernews/search.js +1 -0
- package/clis/hackernews/show.js +1 -0
- package/clis/hackernews/submit.js +65 -0
- package/clis/hackernews/top.js +1 -0
- package/clis/hackernews/user.js +1 -0
- package/clis/hashnode/auth.js +11 -0
- package/clis/hashnode/publish.js +92 -0
- package/clis/hf/auth.js +12 -0
- package/clis/hf/datasets.js +1 -0
- package/clis/hf/models.js +1 -0
- package/clis/hf/paper.js +1 -0
- package/clis/hf/spaces.js +1 -0
- package/clis/hf/top.js +1 -0
- package/clis/homebrew/cask.js +1 -0
- package/clis/homebrew/formula.js +1 -0
- package/clis/homebrew/popular.js +1 -0
- package/clis/homebrew/utils.js +1 -0
- package/clis/huodongxing/events.js +1 -0
- package/clis/hupu/__fixtures__/hot-home.html +64 -0
- package/clis/hupu/auth.js +14 -0
- package/clis/hupu/detail.js +7 -0
- package/clis/hupu/hot.js +14 -0
- package/clis/hupu/like.js +1 -0
- package/clis/hupu/mentions.js +91 -0
- package/clis/hupu/reply.js +1 -0
- package/clis/hupu/search.js +1 -0
- package/clis/hupu/unlike.js +1 -0
- package/clis/hupu/utils.js +243 -0
- package/clis/imdb/person.js +140 -0
- package/clis/imdb/reviews.js +40 -0
- package/clis/imdb/search.js +113 -0
- package/clis/imdb/title.js +1 -0
- package/clis/imdb/top.js +1 -0
- package/clis/imdb/trending.js +1 -0
- package/clis/imdb/utils.js +162 -0
- package/clis/imooc/article.js +59 -0
- package/clis/imooc/login.js +1 -0
- package/clis/imooc/whoami.js +1 -0
- package/clis/indeed/job.js +20 -0
- package/clis/indeed/search.js +37 -0
- package/clis/indeed/utils.js +1 -0
- package/clis/infoq/article.js +19 -0
- package/clis/infoq/login.js +1 -0
- package/clis/infoq/whoami.js +1 -0
- package/clis/instagram/_shared/private-publish.js +75 -0
- package/clis/instagram/_shared/protocol-capture.js +180 -0
- package/clis/instagram/_shared/runtime-info.js +33 -0
- package/clis/instagram/auth.js +22 -0
- package/clis/instagram/collection-create.js +38 -0
- package/clis/instagram/collection-delete.js +72 -0
- package/clis/instagram/comment.js +26 -0
- package/clis/instagram/detail.js +2 -0
- package/clis/instagram/download.js +83 -0
- package/clis/instagram/explore.js +27 -0
- package/clis/instagram/follow.js +24 -0
- package/clis/instagram/followers.js +30 -0
- package/clis/instagram/following.js +74 -0
- package/clis/instagram/like.js +25 -0
- package/clis/instagram/note.js +162 -0
- package/clis/instagram/post.js +718 -0
- package/clis/instagram/profile.js +25 -0
- package/clis/instagram/reel.js +452 -0
- package/clis/instagram/save.js +25 -0
- package/clis/instagram/saved.js +37 -0
- package/clis/instagram/search.js +23 -0
- package/clis/instagram/story.js +21 -0
- package/clis/instagram/unfollow.js +21 -0
- package/clis/instagram/unlike.js +25 -0
- package/clis/instagram/unsave.js +25 -0
- package/clis/instagram/user.js +1 -0
- package/clis/jd/add-cart.js +22 -0
- package/clis/jd/auth.js +12 -0
- package/clis/jd/cart.js +59 -0
- package/clis/jd/detail.js +42 -0
- package/clis/jd/item.js +98 -0
- package/clis/jd/item.test.ts +517 -0
- package/clis/jd/reviews.js +31 -0
- package/clis/jd/search.js +42 -0
- package/clis/jianshu/article.js +1 -0
- package/clis/jianshu/login.js +1 -0
- package/clis/jianshu/notebooks.js +1 -0
- package/clis/jianshu/whoami.js +1 -0
- package/clis/jianyu/auth.js +28 -0
- package/clis/jianyu/detail.js +1 -0
- package/clis/jianyu/search.js +73 -0
- package/clis/jianyu/shared/china-bid-search.js +86 -0
- package/clis/jianyu/shared/procurement-contract.js +1 -0
- package/clis/jianyu/shared/procurement-detail.js +18 -0
- package/clis/jike/auth.js +19 -0
- package/clis/jike/comment.js +82 -0
- package/clis/jike/create.js +83 -0
- package/clis/jike/feed.js +32 -0
- package/clis/jike/like.js +38 -0
- package/clis/jike/notifications.js +115 -0
- package/clis/jike/post.js +33 -0
- package/clis/jike/repost.js +67 -0
- package/clis/jike/search.js +29 -0
- package/clis/jike/topic.js +20 -0
- package/clis/jike/user.js +19 -0
- package/clis/jike/utils.js +15 -0
- package/clis/jimeng/auth.js +13 -0
- package/clis/jimeng/generate.js +60 -0
- package/clis/jimeng/history.js +32 -0
- package/clis/jimeng/new.js +26 -0
- package/clis/jimeng/workspaces.js +22 -0
- package/clis/jira/attachments.js +1 -0
- package/clis/jira/comments.js +1 -0
- package/clis/jira/issue.js +1 -0
- package/clis/jira/links.js +1 -0
- package/clis/jira/search.js +1 -0
- package/clis/jira/shared.js +1 -0
- package/clis/juejin/article.js +5 -0
- package/clis/juejin/categories.js +1 -0
- package/clis/juejin/hot.js +1 -0
- package/clis/juejin/login.js +1 -0
- package/clis/juejin/recommend.js +1 -0
- package/clis/juejin/stats.js +53 -0
- package/clis/juejin/tags.js +1 -0
- package/clis/juejin/utils.js +1 -0
- package/clis/juejin/whoami.js +1 -0
- package/clis/ke/auth.js +14 -0
- package/clis/ke/chengjiao.js +45 -0
- package/clis/ke/ershoufang.js +50 -0
- package/clis/ke/utils.js +21 -0
- package/clis/ke/xiaoqu.js +45 -0
- package/clis/ke/zufang.js +50 -0
- package/clis/kimi/_utils.js +38 -0
- package/clis/kimi/audit-extras.js +64 -0
- package/clis/kimi/auth.js +17 -0
- package/clis/kimi/chat.js +77 -0
- package/clis/kimi/storage.js +14 -0
- package/clis/kimi/ui.js +89 -0
- package/clis/kimi/usage.js +51 -0
- package/clis/kuaishou/auth.js +1 -0
- package/clis/kuaishou/publish.js +53 -0
- package/clis/lesswrong/_helpers.js +9 -0
- package/clis/lesswrong/comments.js +9 -0
- package/clis/lesswrong/curated.js +5 -0
- package/clis/lesswrong/frontpage.js +5 -0
- package/clis/lesswrong/new.js +5 -0
- package/clis/lesswrong/read.js +5 -0
- package/clis/lesswrong/sequences.js +5 -0
- package/clis/lesswrong/shortform.js +5 -0
- package/clis/lesswrong/tag.js +5 -0
- package/clis/lesswrong/tags.js +5 -0
- package/clis/lesswrong/top-month.js +5 -0
- package/clis/lesswrong/top-week.js +5 -0
- package/clis/lesswrong/top-year.js +5 -0
- package/clis/lesswrong/top.js +5 -0
- package/clis/lesswrong/user-posts.js +5 -0
- package/clis/lesswrong/user.js +5 -0
- package/clis/lichess/top.js +1 -0
- package/clis/lichess/user.js +1 -0
- package/clis/lichess/utils.js +1 -0
- package/clis/linkedin/auth.js +27 -0
- package/clis/linkedin/comment.js +1 -0
- package/clis/linkedin/connect.js +244 -0
- package/clis/linkedin/create.js +113 -0
- package/clis/linkedin/follow.js +1 -0
- package/clis/linkedin/inbox.js +1 -0
- package/clis/linkedin/job-detail.js +40 -0
- package/clis/linkedin/jobs-preferences.js +34 -0
- package/clis/linkedin/like.js +1 -0
- package/clis/linkedin/notifications.js +1 -0
- package/clis/linkedin/people-search.js +1 -0
- package/clis/linkedin/post-analytics.js +1 -0
- package/clis/linkedin/post-comments.js +1 -0
- package/clis/linkedin/post-detail.js +1 -0
- package/clis/linkedin/posts-core.js +138 -0
- package/clis/linkedin/posts.js +1 -0
- package/clis/linkedin/profile-analytics.js +1 -0
- package/clis/linkedin/profile-api.js +218 -0
- package/clis/linkedin/profile-experience.js +1 -0
- package/clis/linkedin/profile-projects.js +1 -0
- package/clis/linkedin/profile-read.js +3 -0
- package/clis/linkedin/reply.js +1 -0
- package/clis/linkedin/repost.js +1 -0
- package/clis/linkedin/safe-send.js +155 -0
- package/clis/linkedin/salesnav-inbox.js +21 -0
- package/clis/linkedin/salesnav-message.js +33 -0
- package/clis/linkedin/salesnav-search.js +15 -0
- package/clis/linkedin/salesnav-thread.js +1 -0
- package/clis/linkedin/search-api.js +42 -0
- package/clis/linkedin/search.js +50 -0
- package/clis/linkedin/sent-invitations.js +46 -0
- package/clis/linkedin/services-read.js +57 -0
- package/clis/linkedin/shared.js +10 -0
- package/clis/linkedin/social-api.js +260 -0
- package/clis/linkedin/thread-snapshot.js +81 -0
- package/clis/linkedin/timeline.js +37 -0
- package/clis/linkedin-learning/auth.js +27 -0
- package/clis/linkedin-learning/course.js +17 -0
- package/clis/linkedin-learning/search.js +17 -0
- package/clis/linkedin-learning/trending.js +17 -0
- package/clis/linux-do/auth.js +20 -0
- package/clis/linux-do/categories.js +1 -0
- package/clis/linux-do/feed.js +19 -0
- package/clis/linux-do/search.js +1 -0
- package/clis/linux-do/tags.js +1 -0
- package/clis/linux-do/topic-content.js +28 -0
- package/clis/linux-do/topic.js +1 -0
- package/clis/linux-do/user-posts.js +1 -0
- package/clis/linux-do/user-topics.js +1 -0
- package/clis/lobsters/active.js +1 -0
- package/clis/lobsters/domain.js +1 -0
- package/clis/lobsters/hot.js +1 -0
- package/clis/lobsters/newest.js +1 -0
- package/clis/lobsters/read.js +11 -0
- package/clis/lobsters/tag.js +1 -0
- package/clis/maimai/auth.js +19 -0
- package/clis/maimai/search-talents.js +37 -0
- package/clis/manus/_utils.js +28 -0
- package/clis/manus/auth.js +20 -0
- package/clis/manus/connectors.js +4 -0
- package/clis/manus/credits.js +4 -0
- package/clis/manus/list.js +7 -0
- package/clis/manus/read.js +7 -0
- package/clis/manus/skills.js +4 -0
- package/clis/manus/status.js +8 -0
- package/clis/mastodon/post.js +1 -0
- package/clis/mastodon/shared.js +48 -0
- package/clis/mastodon/whoami.js +1 -0
- package/clis/maven/artifact.js +1 -0
- package/clis/maven/search.js +1 -0
- package/clis/maven/utils.js +1 -0
- package/clis/mdn/search.js +1 -0
- package/clis/medium/article.js +12 -0
- package/clis/medium/feed.js +1 -0
- package/clis/medium/login.js +1 -0
- package/clis/medium/search.js +1 -0
- package/clis/medium/stats.js +56 -0
- package/clis/medium/tag.js +1 -0
- package/clis/medium/user.js +1 -0
- package/clis/medium/utils.js +62 -0
- package/clis/medium/whoami.js +1 -0
- package/clis/mubu/doc.js +1 -0
- package/clis/mubu/docs.js +1 -0
- package/clis/mubu/notes.js +1 -0
- package/clis/mubu/recent.js +1 -0
- package/clis/mubu/search.js +1 -0
- package/clis/mubu/utils.js +31 -0
- package/clis/note/auth.js +12 -0
- package/clis/note/note-utils.js +2 -0
- package/clis/note/publish.js +17 -0
- package/clis/notebooklm/add-source.js +46 -0
- package/clis/notebooklm/auth.js +21 -0
- package/clis/notebooklm/create.js +1 -0
- package/clis/notebooklm/current.js +1 -0
- package/clis/notebooklm/generate-audio.js +1 -0
- package/clis/notebooklm/generate-slides.js +1 -0
- package/clis/notebooklm/get.js +1 -0
- package/clis/notebooklm/history.js +1 -0
- package/clis/notebooklm/list.js +1 -0
- package/clis/notebooklm/note-list.js +1 -0
- package/clis/notebooklm/notes-get.js +1 -0
- package/clis/notebooklm/open.js +1 -0
- package/clis/notebooklm/rpc.js +36 -0
- package/clis/notebooklm/shared.js +1 -0
- package/clis/notebooklm/source-fulltext.js +1 -0
- package/clis/notebooklm/source-get.js +1 -0
- package/clis/notebooklm/source-guide.js +1 -0
- package/clis/notebooklm/source-list.js +1 -0
- package/clis/notebooklm/status.js +1 -0
- package/clis/notebooklm/summary.js +1 -0
- package/clis/notebooklm/utils.js +172 -0
- package/clis/notebooklm/write-note.js +1 -0
- package/clis/nowcoder/auth.js +24 -0
- package/clis/nowcoder/comment.js +1 -0
- package/clis/nowcoder/comments.js +1 -0
- package/clis/nowcoder/companies.js +1 -0
- package/clis/nowcoder/creators.js +1 -0
- package/clis/nowcoder/delete.js +1 -0
- package/clis/nowcoder/detail.js +46 -0
- package/clis/nowcoder/dm-list.js +1 -0
- package/clis/nowcoder/dm-read.js +1 -0
- package/clis/nowcoder/dm-send.js +1 -0
- package/clis/nowcoder/drafts.js +1 -0
- package/clis/nowcoder/experience.js +20 -0
- package/clis/nowcoder/hot.js +1 -0
- package/clis/nowcoder/inbox.js +1 -0
- package/clis/nowcoder/jobs.js +1 -0
- package/clis/nowcoder/like.js +1 -0
- package/clis/nowcoder/my.js +1 -0
- package/clis/nowcoder/notifications.js +16 -0
- package/clis/nowcoder/papers.js +22 -0
- package/clis/nowcoder/post.js +1 -0
- package/clis/nowcoder/practice.js +21 -0
- package/clis/nowcoder/recommend.js +1 -0
- package/clis/nowcoder/referral.js +21 -0
- package/clis/nowcoder/salary.js +22 -0
- package/clis/nowcoder/search.js +31 -0
- package/clis/nowcoder/suggest.js +17 -0
- package/clis/nowcoder/topics.js +1 -0
- package/clis/nowcoder/trending.js +1 -0
- package/clis/nowcoder/utils.js +68 -0
- package/clis/npm/downloads.js +1 -0
- package/clis/npm/package.js +1 -0
- package/clis/npm/search.js +1 -0
- package/clis/npm/utils.js +1 -0
- package/clis/nuget/package.js +1 -0
- package/clis/nuget/search.js +1 -0
- package/clis/nuget/utils.js +1 -0
- package/clis/nvd/cve.js +1 -0
- package/clis/oeis/search.js +1 -0
- package/clis/oeis/sequence.js +1 -0
- package/clis/oeis/utils.js +1 -0
- package/clis/ones/common.js +23 -0
- package/clis/ones/enrich-tasks.js +1 -0
- package/clis/ones/login.js +2 -0
- package/clis/ones/logout.js +1 -0
- package/clis/ones/me.js +1 -0
- package/clis/ones/my-tasks.js +1 -0
- package/clis/ones/resolve-labels.js +1 -0
- package/clis/ones/task-helpers.js +1 -0
- package/clis/ones/task.js +1 -0
- package/clis/ones/tasks.js +1 -0
- package/clis/ones/token-info.js +1 -0
- package/clis/ones/worklog.js +14 -0
- package/clis/openalex/search.js +1 -0
- package/clis/openalex/utils.js +1 -0
- package/clis/openalex/work.js +1 -0
- package/clis/openfda/drug-label.js +1 -0
- package/clis/openfda/food-recall.js +1 -0
- package/clis/openfda/utils.js +1 -0
- package/clis/openreview/author.js +1 -0
- package/clis/openreview/paper.js +1 -0
- package/clis/openreview/reviews.js +4 -0
- package/clis/openreview/search.js +1 -0
- package/clis/openreview/utils.js +1 -0
- package/clis/openreview/venue.js +1 -0
- package/clis/oschina/article.js +1 -0
- package/clis/oschina/catalogs.js +1 -0
- package/clis/oschina/login.js +1 -0
- package/clis/oschina/stats.js +54 -0
- package/clis/oschina/whoami.js +1 -0
- package/clis/osv/query.js +1 -0
- package/clis/osv/utils.js +1 -0
- package/clis/osv/vulnerability.js +1 -0
- package/clis/packagist/package.js +1 -0
- package/clis/packagist/search.js +1 -0
- package/clis/packagist/utils.js +1 -0
- package/clis/paperreview/feedback.js +1 -0
- package/clis/paperreview/review.js +1 -0
- package/clis/paperreview/submit.js +1 -0
- package/clis/paperreview/utils.js +1 -0
- package/clis/pinterest/api.js +1 -0
- package/clis/pinterest/auth.js +1 -0
- package/clis/pinterest/boards.js +1 -0
- package/clis/pinterest/client.js +20 -0
- package/clis/pinterest/publish.js +13 -0
- package/clis/pixiv/auth.js +17 -0
- package/clis/pixiv/detail.js +1 -0
- package/clis/pixiv/download.js +1 -0
- package/clis/pixiv/illusts.js +1 -0
- package/clis/pixiv/ranking.js +26 -0
- package/clis/pixiv/search.js +1 -0
- package/clis/pixiv/user.js +1 -0
- package/clis/pixiv/utils.js +18 -0
- package/clis/powerchina/auth.js +17 -0
- package/clis/powerchina/search.js +1 -0
- package/clis/producthunt/browse.js +54 -0
- package/clis/producthunt/hot.js +64 -0
- package/clis/producthunt/posts.js +1 -0
- package/clis/producthunt/today.js +1 -0
- package/clis/producthunt/utils.js +1 -0
- package/clis/pubmed/article.js +1 -0
- package/clis/pubmed/author.js +1 -0
- package/clis/pubmed/citations.js +1 -0
- package/clis/pubmed/clinical-trial.js +1 -0
- package/clis/pubmed/journal.js +1 -0
- package/clis/pubmed/mesh.js +1 -0
- package/clis/pubmed/related.js +1 -0
- package/clis/pubmed/review.js +1 -0
- package/clis/pubmed/search.js +1 -0
- package/clis/pubmed/utils.js +1 -0
- package/clis/pypi/downloads.js +1 -0
- package/clis/pypi/package.js +1 -0
- package/clis/pypi/utils.js +1 -0
- package/clis/qiita/auth.js +1 -0
- package/clis/qiita/gql.js +32 -0
- package/clis/qiita/publish.js +7 -0
- package/clis/qiita/stats.js +37 -0
- package/clis/qoder/_utils.js +113 -0
- package/clis/qoder/composer.js +1 -0
- package/clis/qoder/history.js +25 -0
- package/clis/qoder/quest.js +1 -0
- package/clis/qoder/read.js +1 -0
- package/clis/qoder/status.js +1 -0
- package/clis/qoder/ui.js +59 -0
- package/clis/quark/auth.js +16 -0
- package/clis/quark/ls.js +1 -0
- package/clis/quark/mkdir.js +1 -0
- package/clis/quark/mv.js +1 -0
- package/clis/quark/rename.js +1 -0
- package/clis/quark/rm.js +1 -0
- package/clis/quark/save.js +1 -0
- package/clis/quark/share-tree.js +1 -0
- package/clis/quark/utils.js +13 -0
- package/clis/quora/create-answer.js +22 -0
- package/clis/quora/create-question.js +24 -0
- package/clis/quora/shared.js +43 -0
- package/clis/quora/whoami.js +1 -0
- package/clis/qwen/ask.js +1 -0
- package/clis/qwen/auth.js +17 -0
- package/clis/qwen/detail.js +1 -0
- package/clis/qwen/history.js +1 -0
- package/clis/qwen/image.js +31 -0
- package/clis/qwen/new.js +1 -0
- package/clis/qwen/read.js +1 -0
- package/clis/qwen/send.js +1 -0
- package/clis/qwen/status.js +1 -0
- package/clis/qwen/utils.js +185 -0
- package/clis/reddit/auth.js +17 -0
- package/clis/reddit/comment.js +36 -0
- package/clis/reddit/frontpage.js +40 -0
- package/clis/reddit/home.js +32 -0
- package/clis/reddit/hot.js +46 -0
- package/clis/reddit/popular.js +46 -0
- package/clis/reddit/read.js +398 -0
- package/clis/reddit/reply.js +56 -0
- package/clis/reddit/save.js +30 -0
- package/clis/reddit/saved.js +24 -0
- package/clis/reddit/search.js +51 -0
- package/clis/reddit/submit.js +42 -0
- package/clis/reddit/subreddit-info.js +29 -0
- package/clis/reddit/subreddit.js +52 -0
- package/clis/reddit/subscribe.js +29 -0
- package/clis/reddit/subscribed.js +68 -0
- package/clis/reddit/upvote.js +43 -0
- package/clis/reddit/upvoted.js +24 -0
- package/clis/reddit/user-comments.js +20 -0
- package/clis/reddit/user-posts.js +17 -0
- package/clis/reddit/user.js +20 -0
- package/clis/reddit/whoami.js +19 -0
- package/clis/rednote/auth.js +19 -0
- package/clis/rednote/comments.js +1 -0
- package/clis/rednote/download.js +1 -0
- package/clis/rednote/feed.js +1 -0
- package/clis/rednote/note.js +1 -0
- package/clis/rednote/notifications.js +67 -0
- package/clis/rednote/search.js +32 -0
- package/clis/rednote/user.js +1 -0
- package/clis/rest-countries/country.js +1 -0
- package/clis/rest-countries/region.js +1 -0
- package/clis/rest-countries/utils.js +1 -0
- package/clis/reuters/article-detail.js +1 -0
- package/clis/reuters/auth.js +39 -0
- package/clis/reuters/search.js +1 -0
- package/clis/reuters/utils.js +50 -0
- package/clis/rfc/rfc.js +1 -0
- package/clis/rfc/utils.js +1 -0
- package/clis/rubygems/gem.js +1 -0
- package/clis/rubygems/search.js +1 -0
- package/clis/rubygems/utils.js +1 -0
- package/clis/segmentfault/_signed-request.js +43 -0
- package/clis/segmentfault/article.js +3 -0
- package/clis/segmentfault/channels.js +1 -0
- package/clis/segmentfault/login.js +1 -0
- package/clis/segmentfault/stats.js +82 -0
- package/clis/segmentfault/tags.js +1 -0
- package/clis/segmentfault/whoami.js +1 -0
- package/clis/semanticscholar/citations.js +1 -0
- package/clis/semanticscholar/paper.js +1 -0
- package/clis/semanticscholar/recommendations.js +1 -0
- package/clis/semanticscholar/search.js +1 -0
- package/clis/semanticscholar/utils.js +1 -0
- package/clis/sinablog/article.js +1 -0
- package/clis/sinablog/hot.js +1 -0
- package/clis/sinablog/search.js +1 -0
- package/clis/sinablog/user.js +1 -0
- package/clis/sinablog/utils.js +153 -0
- package/clis/sinafinance/news.js +1 -0
- package/clis/sinafinance/rolling-news.js +20 -0
- package/clis/sinafinance/stock-rank.js +41 -0
- package/clis/sinafinance/stock.js +1 -0
- package/clis/slock/attachment-download.js +1 -0
- package/clis/slock/attachment-upload.js +34 -0
- package/clis/slock/attachment-url.js +1 -0
- package/clis/slock/auth-verify.js +1 -0
- package/clis/slock/bookmark-add.js +11 -0
- package/clis/slock/bookmark-list.js +10 -0
- package/clis/slock/bookmark-remove.js +7 -0
- package/clis/slock/channel-action.js +1 -0
- package/clis/slock/channel-archive.js +1 -0
- package/clis/slock/channel-create.js +1 -0
- package/clis/slock/channel-files.js +1 -0
- package/clis/slock/channel-info.js +1 -0
- package/clis/slock/channel-join.js +1 -0
- package/clis/slock/channel-leave.js +1 -0
- package/clis/slock/channel-list.js +1 -0
- package/clis/slock/channel-mark.js +1 -0
- package/clis/slock/channel-members.js +1 -0
- package/clis/slock/channel-unarchive.js +1 -0
- package/clis/slock/dm-list.js +1 -0
- package/clis/slock/errors.js +1 -0
- package/clis/slock/in-page.js +113 -0
- package/clis/slock/inbox-done.js +9 -0
- package/clis/slock/inbox-read-all.js +1 -0
- package/clis/slock/inbox.js +1 -0
- package/clis/slock/login.js +1 -0
- package/clis/slock/message-read.js +61 -0
- package/clis/slock/message-search.js +24 -0
- package/clis/slock/message-send.js +55 -0
- package/clis/slock/reaction-add.js +1 -0
- package/clis/slock/reaction-remove.js +1 -0
- package/clis/slock/resolve.js +1 -0
- package/clis/slock/server-list.js +9 -0
- package/clis/slock/server-use.js +18 -0
- package/clis/slock/shared.js +1 -0
- package/clis/slock/task-claim.js +14 -0
- package/clis/slock/task-convert.js +35 -0
- package/clis/slock/task-create.js +24 -0
- package/clis/slock/task-delete.js +9 -0
- package/clis/slock/task-get.js +11 -0
- package/clis/slock/task-list-server.js +12 -0
- package/clis/slock/task-list.js +14 -0
- package/clis/slock/task-status.js +19 -0
- package/clis/slock/task-unclaim.js +13 -0
- package/clis/slock/thread-done.js +1 -0
- package/clis/slock/thread-follow.js +1 -0
- package/clis/slock/thread-list.js +1 -0
- package/clis/slock/thread-state.js +1 -0
- package/clis/slock/thread-undone.js +1 -0
- package/clis/slock/thread-unfollow.js +1 -0
- package/clis/slock/unread-summary.js +18 -0
- package/clis/slock/whoami.js +1 -0
- package/clis/smzdm/search.js +71 -0
- package/clis/sohu/article.js +1 -0
- package/clis/sohu/attributes.js +1 -0
- package/clis/sohu/categories.js +1 -0
- package/clis/sohu/channels.js +1 -0
- package/clis/sohu/columns.js +1 -0
- package/clis/sohu/login.js +1 -0
- package/clis/sohu/mpbp.js +1 -0
- package/clis/sohu/stats.js +95 -0
- package/clis/sohu/topics.js +1 -0
- package/clis/sohu/whoami.js +1 -0
- package/clis/spotify/spotify.js +1 -0
- package/clis/spotify/utils.js +8 -0
- package/clis/stackoverflow/bounties.js +1 -0
- package/clis/stackoverflow/hot.js +1 -0
- package/clis/stackoverflow/read.js +13 -0
- package/clis/stackoverflow/related.js +1 -0
- package/clis/stackoverflow/search.js +1 -0
- package/clis/stackoverflow/tag.js +1 -0
- package/clis/stackoverflow/unanswered.js +1 -0
- package/clis/stackoverflow/user.js +1 -0
- package/clis/stackoverflow/utils.js +1 -0
- package/clis/steam/app.js +1 -0
- package/clis/steam/search.js +1 -0
- package/clis/steam/top-sellers.js +1 -0
- package/clis/steam/utils.js +1 -0
- package/clis/substack/auth.js +11 -0
- package/clis/substack/feed.js +1 -0
- package/clis/substack/post-utils.js +2 -0
- package/clis/substack/publication.js +1 -0
- package/clis/substack/publish.js +10 -0
- package/clis/substack/search.js +1 -0
- package/clis/substack/utils.js +108 -0
- package/clis/suno/auth.js +21 -0
- package/clis/suno/download.js +17 -0
- package/clis/suno/generate.js +4 -0
- package/clis/suno/list.js +14 -0
- package/clis/suno/status.js +1 -0
- package/clis/suno/utils.js +102 -0
- package/clis/taobao/add-cart.js +93 -0
- package/clis/taobao/auth.js +8 -0
- package/clis/taobao/cart.js +68 -0
- package/clis/taobao/detail.js +48 -0
- package/clis/taobao/reviews.js +52 -0
- package/clis/taobao/search.js +64 -0
- package/clis/tdx/hot-rank.js +25 -0
- package/clis/telegram/send.js +18 -0
- package/clis/telegram/shared.js +21 -0
- package/clis/telegram/whoami.js +1 -0
- package/clis/test-utils.js +1 -0
- package/clis/threads/post.js +152 -0
- package/clis/threads/shared.js +27 -0
- package/clis/threads/whoami.js +1 -0
- package/clis/ths/hot-rank.js +27 -0
- package/clis/tieba/hot.js +16 -0
- package/clis/tieba/posts.js +1 -0
- package/clis/tieba/read.js +84 -0
- package/clis/tieba/search.js +54 -0
- package/clis/tieba/utils.js +1 -0
- package/clis/tiktok/auth.js +30 -0
- package/clis/tiktok/comment.js +69 -0
- package/clis/tiktok/creator-videos.js +45 -0
- package/clis/tiktok/explore.js +76 -0
- package/clis/tiktok/follow.js +49 -0
- package/clis/tiktok/following.js +103 -0
- package/clis/tiktok/friends.js +79 -0
- package/clis/tiktok/like.js +19 -0
- package/clis/tiktok/live.js +79 -0
- package/clis/tiktok/notifications.js +77 -0
- package/clis/tiktok/profile.js +26 -0
- package/clis/tiktok/publish.js +82 -0
- package/clis/tiktok/save.js +15 -0
- package/clis/tiktok/search.js +24 -0
- package/clis/tiktok/unfollow.js +59 -0
- package/clis/tiktok/unlike.js +19 -0
- package/clis/tiktok/unsave.js +17 -0
- package/clis/tiktok/user.js +143 -0
- package/clis/tiktok/utils.js +272 -0
- package/clis/toutiao/article.js +1 -0
- package/clis/toutiao/articles.js +6 -0
- package/clis/toutiao/auth.js +50 -0
- package/clis/toutiao/hot.js +1 -0
- package/clis/toutiao/utils.js +2 -0
- package/clis/trae-cn/activity.js +1 -0
- package/clis/trae-cn/approve.js +1 -0
- package/clis/trae-cn/ask.js +1 -0
- package/clis/trae-cn/dump.js +1 -0
- package/clis/trae-cn/export.js +3 -0
- package/clis/trae-cn/model.js +1 -0
- package/clis/trae-cn/new.js +1 -0
- package/clis/trae-cn/read.js +1 -0
- package/clis/trae-cn/screenshot.js +1 -0
- package/clis/trae-cn/select-model.js +1 -0
- package/clis/trae-cn/send.js +1 -0
- package/clis/trae-cn/setup.js +1 -0
- package/clis/trae-cn/status.js +1 -0
- package/clis/trae-cn/targets.js +1 -0
- package/clis/trae-cn/utils.js +456 -0
- package/clis/trae-cn/watch.js +3 -0
- package/clis/trae-solo/_actions.js +41 -0
- package/clis/trae-solo/_fs.js +6 -0
- package/clis/trae-solo/_state.js +2 -0
- package/clis/trae-solo/automation.js +43 -0
- package/clis/trae-solo/history.js +15 -0
- package/clis/trae-solo/mode.js +31 -0
- package/clis/trae-solo/model.js +50 -0
- package/clis/trae-solo/renderer-storage.js +11 -0
- package/clis/trae-solo/settings.js +1 -0
- package/clis/trae-solo/skill-fs.js +1 -0
- package/clis/trae-solo/skill.js +81 -0
- package/clis/trae-solo/state-fs.js +2 -0
- package/clis/trae-solo/status.js +1 -0
- package/clis/trae-solo/task-fs.js +5 -0
- package/clis/trae-solo/user-rules.js +1 -0
- package/clis/trae-solo/workspaces-fs.js +1 -0
- package/clis/tumblr/auth.js +24 -0
- package/clis/tumblr/publish.js +14 -0
- package/clis/tvmaze/search.js +1 -0
- package/clis/tvmaze/show.js +1 -0
- package/clis/tvmaze/utils.js +1 -0
- package/clis/twitter/accept.js +116 -0
- package/clis/twitter/article.js +116 -0
- package/clis/twitter/auth.js +4 -0
- package/clis/twitter/block.js +62 -0
- package/clis/twitter/bookmark-folder.js +4 -0
- package/clis/twitter/bookmark-folders.js +4 -0
- package/clis/twitter/bookmark.js +44 -0
- package/clis/twitter/bookmarks.js +27 -0
- package/clis/twitter/delete.js +36 -0
- package/clis/twitter/device-follow.js +13 -0
- package/clis/twitter/dm-list.js +1 -0
- package/clis/twitter/dm-read.js +1 -0
- package/clis/twitter/dm-send.js +13 -0
- package/clis/twitter/dm-shared.js +6 -0
- package/clis/twitter/download.js +38 -0
- package/clis/twitter/follow-batch.js +43 -0
- package/clis/twitter/follow.js +39 -0
- package/clis/twitter/followers.js +59 -0
- package/clis/twitter/following.js +4 -0
- package/clis/twitter/hide-reply.js +57 -0
- package/clis/twitter/like.js +48 -0
- package/clis/twitter/likes.js +14 -0
- package/clis/twitter/list-add-batch.js +1 -0
- package/clis/twitter/list-add-core.js +35 -0
- package/clis/twitter/list-add.js +1 -0
- package/clis/twitter/list-batch-utils.js +1 -0
- package/clis/twitter/list-create.js +12 -0
- package/clis/twitter/list-delete.js +36 -0
- package/clis/twitter/list-remove-batch.js +1 -0
- package/clis/twitter/list-remove-core.js +127 -0
- package/clis/twitter/list-remove.js +1 -0
- package/clis/twitter/list-tweets.js +27 -0
- package/clis/twitter/lists.js +27 -0
- package/clis/twitter/notifications.js +4 -0
- package/clis/twitter/post.js +158 -0
- package/clis/twitter/profile.js +66 -0
- package/clis/twitter/quote.js +123 -0
- package/clis/twitter/reply-dm.js +112 -0
- package/clis/twitter/reply.js +97 -0
- package/clis/twitter/retweet.js +62 -0
- package/clis/twitter/schedule.js +96 -0
- package/clis/twitter/scheduled-delete.js +60 -0
- package/clis/twitter/scheduled-list.js +15 -0
- package/clis/twitter/scheduled-utils.js +18 -0
- package/clis/twitter/search.js +12 -0
- package/clis/twitter/shared.js +76 -0
- package/clis/twitter/thread.js +4 -0
- package/clis/twitter/timeline.js +4 -0
- package/clis/twitter/trending.js +18 -0
- package/clis/twitter/tweets.js +12 -0
- package/clis/twitter/unblock.js +45 -0
- package/clis/twitter/unbookmark.js +41 -0
- package/clis/twitter/unfollow.js +45 -0
- package/clis/twitter/unlike.js +48 -0
- package/clis/twitter/unretweet.js +62 -0
- package/clis/twitter/utils.js +55 -0
- package/clis/uisdc/news.js +25 -0
- package/clis/uiverse/_shared.js +257 -0
- package/clis/uiverse/code.js +1 -0
- package/clis/uiverse/preview.js +1 -0
- package/clis/upwork/auth.js +19 -0
- package/clis/upwork/detail.js +22 -0
- package/clis/upwork/feed.js +21 -0
- package/clis/upwork/search.js +21 -0
- package/clis/upwork/utils.js +1 -0
- package/clis/v2ex/auth.js +10 -0
- package/clis/v2ex/daily.js +41 -0
- package/clis/v2ex/hot.js +1 -0
- package/clis/v2ex/latest.js +1 -0
- package/clis/v2ex/me.js +58 -0
- package/clis/v2ex/member.js +1 -0
- package/clis/v2ex/node.js +1 -0
- package/clis/v2ex/nodes.js +1 -0
- package/clis/v2ex/notifications.js +40 -0
- package/clis/v2ex/replies.js +1 -0
- package/clis/v2ex/topic.js +1 -0
- package/clis/v2ex/user.js +1 -0
- package/clis/vk/post.js +1 -0
- package/clis/vk/shared.js +8 -0
- package/clis/vk/whoami.js +1 -0
- package/clis/wanfang/search.js +42 -0
- package/clis/web/read.js +260 -0
- package/clis/wechat-channels/auth.js +31 -0
- package/clis/wechat-channels/publish.js +298 -0
- package/clis/weibo/article.js +1 -0
- package/clis/weibo/auth.js +17 -0
- package/clis/weibo/comments.js +28 -0
- package/clis/weibo/delete.js +84 -0
- package/clis/weibo/favorites.js +27 -0
- package/clis/weibo/feed.js +33 -0
- package/clis/weibo/hot.js +17 -0
- package/clis/weibo/me.js +51 -0
- package/clis/weibo/post.js +46 -0
- package/clis/weibo/publish.js +98 -0
- package/clis/weibo/search.js +47 -0
- package/clis/weibo/user-posts.js +92 -0
- package/clis/weibo/user.js +37 -0
- package/clis/weibo/utils.js +16 -0
- package/clis/weixin/article.js +1 -0
- package/clis/weixin/create-draft.js +152 -0
- package/clis/weixin/download.js +100 -0
- package/clis/weixin/drafts.js +27 -0
- package/clis/weixin/login.js +1 -0
- package/clis/weixin/search.js +44 -0
- package/clis/weixin/stats.js +43 -0
- package/clis/weixin/whoami.js +1 -0
- package/clis/weread/ai-outline.js +2 -0
- package/clis/weread/auth.js +24 -0
- package/clis/weread/book-search.js +2 -0
- package/clis/weread/book.js +3 -0
- package/clis/weread/highlights.js +1 -0
- package/clis/weread/notebooks.js +1 -0
- package/clis/weread/notes.js +1 -0
- package/clis/weread/ranking.js +1 -0
- package/clis/weread/search.js +1 -0
- package/clis/weread/shelf.js +1 -0
- package/clis/weread/utils.js +67 -0
- package/clis/weread-official/book.js +1 -0
- package/clis/weread-official/discover.js +1 -0
- package/clis/weread-official/list-apis.js +1 -0
- package/clis/weread-official/notes.js +1 -0
- package/clis/weread-official/readdata.js +1 -0
- package/clis/weread-official/review.js +1 -0
- package/clis/weread-official/search.js +1 -0
- package/clis/weread-official/shelf.js +1 -0
- package/clis/weread-official/utils.js +1 -0
- package/clis/wikidata/entity.js +1 -0
- package/clis/wikidata/search.js +1 -0
- package/clis/wikidata/utils.js +1 -0
- package/clis/wikipedia/page.js +3 -0
- package/clis/wikipedia/random.js +1 -0
- package/clis/wikipedia/search.js +1 -0
- package/clis/wikipedia/summary.js +1 -0
- package/clis/wikipedia/trending.js +1 -0
- package/clis/wikipedia/utils.js +1 -0
- package/clis/wordpress/login.js +1 -0
- package/clis/wordpress/publish.js +1 -0
- package/clis/wordpress/shared.js +54 -0
- package/clis/wordpress/whoami.js +1 -0
- package/clis/woshipm/article.js +1 -0
- package/clis/woshipm/login.js +1 -0
- package/clis/woshipm/stats.js +52 -0
- package/clis/woshipm/whoami.js +1 -0
- package/clis/wttr/current.js +1 -0
- package/clis/wttr/forecast.js +1 -0
- package/clis/wttr/utils.js +1 -0
- package/clis/xianyu/auth.js +11 -0
- package/clis/xianyu/chat.js +1 -0
- package/clis/xianyu/im.js +240 -0
- package/clis/xianyu/inbox.js +1 -0
- package/clis/xianyu/item.js +97 -0
- package/clis/xianyu/messages.js +1 -0
- package/clis/xianyu/publish.js +245 -0
- package/clis/xianyu/reply.js +1 -0
- package/clis/xianyu/search.js +141 -0
- package/clis/xianyu/utils.js +1 -0
- package/clis/xiaoe/auth.js +10 -0
- package/clis/xiaoe/catalog.js +134 -0
- package/clis/xiaoe/content.js +16 -0
- package/clis/xiaoe/courses.js +43 -0
- package/clis/xiaoe/detail.js +19 -0
- package/clis/xiaoe/play-url.js +97 -0
- package/clis/xiaohongshu/ask.js +130 -0
- package/clis/xiaohongshu/auth.js +13 -0
- package/clis/xiaohongshu/collection-helpers.js +64 -0
- package/clis/xiaohongshu/comments.js +89 -0
- package/clis/xiaohongshu/creator-note-detail.js +80 -0
- package/clis/xiaohongshu/creator-notes-summary.js +1 -0
- package/clis/xiaohongshu/creator-notes.js +107 -0
- package/clis/xiaohongshu/creator-profile.js +13 -0
- package/clis/xiaohongshu/creator-stats.js +13 -0
- package/clis/xiaohongshu/delete-note.js +69 -0
- package/clis/xiaohongshu/download.js +200 -0
- package/clis/xiaohongshu/draft-clear.js +44 -0
- package/clis/xiaohongshu/draft-delete.js +37 -0
- package/clis/xiaohongshu/draft-open.js +1 -0
- package/clis/xiaohongshu/draft-utils.js +36 -0
- package/clis/xiaohongshu/drafts.js +1 -0
- package/clis/xiaohongshu/feed.js +38 -0
- package/clis/xiaohongshu/follow.js +75 -0
- package/clis/xiaohongshu/liked.js +1 -0
- package/clis/xiaohongshu/note-helpers.js +1 -0
- package/clis/xiaohongshu/note.js +32 -0
- package/clis/xiaohongshu/notifications.js +1 -0
- package/clis/xiaohongshu/publish-video.js +87 -0
- package/clis/xiaohongshu/publish.js +637 -0
- package/clis/xiaohongshu/saved.js +1 -0
- package/clis/xiaohongshu/search.js +194 -0
- package/clis/xiaohongshu/unfollow.js +98 -0
- package/clis/xiaohongshu/user-helpers.js +1 -0
- package/clis/xiaohongshu/user.js +30 -0
- package/clis/xiaoyuzhou/auth.js +3 -0
- package/clis/xiaoyuzhou/download.js +1 -0
- package/clis/xiaoyuzhou/episode.js +1 -0
- package/clis/xiaoyuzhou/podcast-episodes.js +1 -0
- package/clis/xiaoyuzhou/podcast.js +1 -0
- package/clis/xiaoyuzhou/transcript.js +1 -0
- package/clis/xiaoyuzhou/utils.js +1 -0
- package/clis/xueqiu/article.js +4 -0
- package/clis/xueqiu/auth.js +27 -0
- package/clis/xueqiu/comments.js +38 -0
- package/clis/xueqiu/danjuan-utils.js +84 -0
- package/clis/xueqiu/earnings-date.js +1 -0
- package/clis/xueqiu/events.js +17 -0
- package/clis/xueqiu/feed.js +1 -0
- package/clis/xueqiu/fund-holdings.js +1 -0
- package/clis/xueqiu/fund-snapshot.js +1 -0
- package/clis/xueqiu/groups.js +1 -0
- package/clis/xueqiu/hashtags.js +26 -0
- package/clis/xueqiu/hot-stock.js +1 -0
- package/clis/xueqiu/hot.js +1 -0
- package/clis/xueqiu/kline.js +1 -0
- package/clis/xueqiu/search.js +1 -0
- package/clis/xueqiu/stock.js +1 -0
- package/clis/xueqiu/stocks.js +13 -0
- package/clis/xueqiu/users.js +12 -0
- package/clis/xueqiu/utils.js +9 -0
- package/clis/xueqiu/watchlist.js +1 -0
- package/clis/yahoo/search.js +21 -0
- package/clis/yahoo-finance/quote.js +50 -0
- package/clis/yollomi/background.js +1 -0
- package/clis/yollomi/edit.js +1 -0
- package/clis/yollomi/face-swap.js +1 -0
- package/clis/yollomi/generate.js +1 -0
- package/clis/yollomi/models.js +1 -0
- package/clis/yollomi/object-remover.js +1 -0
- package/clis/yollomi/remove-bg.js +1 -0
- package/clis/yollomi/restore.js +1 -0
- package/clis/yollomi/try-on.js +1 -0
- package/clis/yollomi/upload.js +17 -0
- package/clis/yollomi/upscale.js +1 -0
- package/clis/yollomi/utils.js +16 -0
- package/clis/yollomi/video.js +1 -0
- package/clis/youdao/note.js +113 -0
- package/clis/youtube/auth.js +20 -0
- package/clis/youtube/channel.js +118 -0
- package/clis/youtube/comments.js +64 -0
- package/clis/youtube/feed.js +89 -0
- package/clis/youtube/history.js +87 -0
- package/clis/youtube/like.js +33 -0
- package/clis/youtube/playlist.js +47 -0
- package/clis/youtube/publish.js +56 -0
- package/clis/youtube/search.js +39 -0
- package/clis/youtube/subscribe.js +42 -0
- package/clis/youtube/subscriptions.js +26 -0
- package/clis/youtube/transcript-group.js +2 -0
- package/clis/youtube/transcript.js +417 -0
- package/clis/youtube/unlike.js +33 -0
- package/clis/youtube/unsubscribe.js +42 -0
- package/clis/youtube/utils.js +34 -0
- package/clis/youtube/video.js +96 -0
- package/clis/youtube/watch-later.js +41 -0
- package/clis/yuanbao/ask.js +145 -0
- package/clis/yuanbao/auth.js +23 -0
- package/clis/yuanbao/detail.js +1 -0
- package/clis/yuanbao/history.js +1 -0
- package/clis/yuanbao/new.js +16 -0
- package/clis/yuanbao/read.js +1 -0
- package/clis/yuanbao/send.js +1 -0
- package/clis/yuanbao/shared.js +127 -0
- package/clis/yuanbao/status.js +1 -0
- package/clis/yuque/article.js +1 -0
- package/clis/yuque/whoami.js +1 -0
- package/clis/zhihu/answer-comments.js +11 -0
- package/clis/zhihu/answer-detail.js +11 -0
- package/clis/zhihu/answer.js +15 -0
- package/clis/zhihu/article-transform.js +1 -0
- package/clis/zhihu/article.js +7 -0
- package/clis/zhihu/auth.js +11 -0
- package/clis/zhihu/collection.js +7 -0
- package/clis/zhihu/collections.js +7 -0
- package/clis/zhihu/comment.js +17 -0
- package/clis/zhihu/download.js +39 -0
- package/clis/zhihu/favorite.js +39 -0
- package/clis/zhihu/follow.js +19 -0
- package/clis/zhihu/followers.js +1 -0
- package/clis/zhihu/following.js +1 -0
- package/clis/zhihu/hot.js +21 -0
- package/clis/zhihu/like.js +16 -0
- package/clis/zhihu/paginate.js +11 -0
- package/clis/zhihu/pin.js +24 -0
- package/clis/zhihu/pins.js +1 -0
- package/clis/zhihu/question.js +7 -0
- package/clis/zhihu/recommend.js +7 -0
- package/clis/zhihu/search.js +11 -0
- package/clis/zhihu/stats.js +41 -0
- package/clis/zhihu/target.js +1 -0
- package/clis/zhihu/text.js +6 -0
- package/clis/zhihu/user-answers.js +1 -0
- package/clis/zhihu/user-arg.js +1 -0
- package/clis/zhihu/user-articles.js +1 -0
- package/clis/zhihu/user.js +11 -0
- package/clis/zhihu/write-shared.js +71 -0
- package/clis/zlibrary/info.js +1 -0
- package/clis/zlibrary/search.js +1 -0
- package/clis/zlibrary/utils.js +48 -0
- package/clis/zsxq/auth.js +33 -0
- package/clis/zsxq/dynamics.js +1 -0
- package/clis/zsxq/groups.js +1 -0
- package/clis/zsxq/search.js +1 -0
- package/clis/zsxq/topic.js +1 -0
- package/clis/zsxq/topics.js +1 -0
- package/clis/zsxq/utils.js +72 -0
- package/dist/src/adapter-shadow.d.ts +11 -0
- package/dist/src/adapter-shadow.js +2 -0
- package/dist/src/adapter-shadow.test.d.ts +1 -0
- package/dist/src/adapter-source.d.ts +11 -0
- package/dist/src/adapter-source.js +1 -0
- package/dist/src/adapter-source.test.d.ts +1 -0
- package/dist/src/browser/analyze.d.ts +118 -0
- package/dist/src/browser/analyze.js +1 -0
- package/dist/src/browser/analyze.test.d.ts +1 -0
- package/dist/src/browser/article-extract.d.ts +57 -0
- package/dist/src/browser/article-extract.e2e.test.d.ts +1 -0
- package/dist/src/browser/article-extract.js +2 -0
- package/dist/src/browser/article-extract.test.d.ts +1 -0
- package/dist/src/browser/ax-snapshot.d.ts +37 -0
- package/dist/src/browser/ax-snapshot.js +2 -0
- package/dist/src/browser/ax-snapshot.test.d.ts +1 -0
- package/dist/src/browser/base-page.d.ts +151 -0
- package/dist/src/browser/base-page.js +225 -0
- package/dist/src/browser/base-page.test.d.ts +1 -0
- package/dist/src/browser/bridge-readiness.d.ts +14 -0
- package/dist/src/browser/bridge-readiness.js +1 -0
- package/dist/src/browser/bridge-readiness.test.d.ts +1 -0
- package/dist/src/browser/bridge.d.ts +26 -0
- package/dist/src/browser/bridge.js +1 -0
- package/dist/src/browser/cdp-click-fixture.test.d.ts +1 -0
- package/dist/src/browser/cdp.d.ts +51 -0
- package/dist/src/browser/cdp.js +1 -0
- package/dist/src/browser/cdp.test.d.ts +1 -0
- package/dist/src/browser/compound.d.ts +59 -0
- package/dist/src/browser/compound.js +82 -0
- package/dist/src/browser/compound.test.d.ts +1 -0
- package/dist/src/browser/config.d.ts +2 -0
- package/dist/src/browser/config.js +1 -0
- package/dist/src/browser/daemon-client.d.ts +79 -0
- package/dist/src/browser/daemon-client.js +1 -0
- package/dist/src/browser/daemon-client.test.d.ts +1 -0
- package/dist/src/browser/daemon-lifecycle.d.ts +37 -0
- package/dist/src/browser/daemon-lifecycle.js +12 -0
- package/dist/src/browser/daemon-transport.d.ts +55 -0
- package/dist/src/browser/daemon-transport.js +1 -0
- package/dist/src/browser/daemon-version.d.ts +4 -0
- package/dist/src/browser/daemon-version.js +2 -0
- package/dist/src/browser/dom-helpers.d.ts +41 -0
- package/dist/src/browser/dom-helpers.js +166 -0
- package/dist/src/browser/dom-helpers.test.d.ts +1 -0
- package/dist/src/browser/dom-snapshot.d.ts +93 -0
- package/dist/src/browser/dom-snapshot.js +809 -0
- package/dist/src/browser/dom-snapshot.test.d.ts +11 -0
- package/dist/src/browser/errors.d.ts +38 -0
- package/dist/src/browser/errors.js +5 -0
- package/dist/src/browser/errors.test.d.ts +1 -0
- package/dist/src/browser/extract.d.ts +69 -0
- package/dist/src/browser/extract.js +42 -0
- package/dist/src/browser/extract.test.d.ts +1 -0
- package/dist/src/browser/find.d.ts +84 -0
- package/dist/src/browser/find.js +328 -0
- package/dist/src/browser/find.test.d.ts +1 -0
- package/dist/src/browser/fingerprint.d.ts +44 -0
- package/dist/src/browser/fingerprint.js +82 -0
- package/dist/src/browser/html-tree.d.ts +75 -0
- package/dist/src/browser/html-tree.js +61 -0
- package/dist/src/browser/html-tree.test.d.ts +1 -0
- package/dist/src/browser/index.d.ts +14 -0
- package/dist/src/browser/index.js +1 -0
- package/dist/src/browser/managed-chrome.d.ts +89 -0
- package/dist/src/browser/managed-chrome.js +1 -0
- package/dist/src/browser/network-cache.d.ts +49 -0
- package/dist/src/browser/network-cache.js +1 -0
- package/dist/src/browser/network-cache.test.d.ts +1 -0
- package/dist/src/browser/network-key.d.ts +22 -0
- package/dist/src/browser/network-key.js +1 -0
- package/dist/src/browser/network-key.test.d.ts +1 -0
- package/dist/src/browser/page.d.ts +83 -0
- package/dist/src/browser/page.js +15 -0
- package/dist/src/browser/page.test.d.ts +1 -0
- package/dist/src/browser/profile.d.ts +96 -0
- package/dist/src/browser/profile.js +2 -0
- package/dist/src/browser/proxy-test.d.ts +28 -0
- package/dist/src/browser/proxy-test.js +12 -0
- package/dist/src/browser/shape-filter.d.ts +52 -0
- package/dist/src/browser/shape-filter.js +1 -0
- package/dist/src/browser/shape-filter.test.d.ts +1 -0
- package/dist/src/browser/shape.d.ts +23 -0
- package/dist/src/browser/shape.js +1 -0
- package/dist/src/browser/shape.test.d.ts +1 -0
- package/dist/src/browser/stealth.d.ts +18 -0
- package/dist/src/browser/stealth.js +391 -0
- package/dist/src/browser/stealth.test.d.ts +1 -0
- package/dist/src/browser/tabs.d.ts +13 -0
- package/dist/src/browser/tabs.js +2 -0
- package/dist/src/browser/target-errors.d.ts +39 -0
- package/dist/src/browser/target-errors.js +1 -0
- package/dist/src/browser/target-errors.test.d.ts +1 -0
- package/dist/src/browser/target-resolver.d.ts +158 -0
- package/dist/src/browser/target-resolver.js +423 -0
- package/dist/src/browser/target-resolver.test.d.ts +1 -0
- package/dist/src/browser/trace.d.ts +21 -0
- package/dist/src/browser/trace.js +2 -0
- package/dist/src/browser/utils.d.ts +20 -0
- package/dist/src/browser/utils.js +1 -0
- package/dist/src/browser/utils.test.d.ts +1 -0
- package/dist/src/browser/verify-fixture.d.ts +65 -0
- package/dist/src/browser/verify-fixture.js +2 -0
- package/dist/src/browser/verify-fixture.test.d.ts +1 -0
- package/dist/src/browser/visual-refs.d.ts +11 -0
- package/dist/src/browser/visual-refs.js +94 -0
- package/dist/src/browser-session-lock.d.ts +13 -0
- package/dist/src/browser-session-lock.js +1 -0
- package/dist/src/browser-session-lock.test.d.ts +1 -0
- package/dist/src/browser.test.d.ts +1 -0
- package/dist/src/build-manifest.d.ts +103 -0
- package/dist/src/build-manifest.js +16 -0
- package/dist/src/build-manifest.test.d.ts +1 -0
- package/dist/src/capabilityRouting.d.ts +19 -0
- package/dist/src/capabilityRouting.js +1 -0
- package/dist/src/capabilityRouting.test.d.ts +1 -0
- package/dist/src/cli-argv-preprocess.d.ts +63 -0
- package/dist/src/cli-argv-preprocess.js +1 -0
- package/dist/src/cli-argv-preprocess.test.d.ts +1 -0
- package/dist/src/cli.d.ts +79 -0
- package/dist/src/cli.js +132 -0
- package/dist/src/cli.test.d.ts +1 -0
- package/dist/src/commanderAdapter.d.ts +21 -0
- package/dist/src/commanderAdapter.js +3 -0
- package/dist/src/commanderAdapter.test.d.ts +1 -0
- package/dist/src/commands/auth.d.ts +40 -0
- package/dist/src/commands/auth.js +2 -0
- package/dist/src/commands/auth.test.d.ts +1 -0
- package/dist/src/commands/daemon.d.ts +25 -0
- package/dist/src/commands/daemon.js +1 -0
- package/dist/src/commands/daemon.test.d.ts +1 -0
- package/dist/src/completion-fast.d.ts +22 -0
- package/dist/src/completion-fast.js +1 -0
- package/dist/src/completion-shared.d.ts +13 -0
- package/dist/src/completion-shared.js +30 -0
- package/dist/src/completion.d.ts +21 -0
- package/dist/src/completion.js +1 -0
- package/dist/src/completion.test.d.ts +1 -0
- package/dist/src/constants.d.ts +22 -0
- package/dist/src/constants.js +1 -0
- package/dist/src/convention-audit.d.ts +50 -0
- package/dist/src/convention-audit.js +2 -0
- package/dist/src/convention-audit.test.d.ts +1 -0
- package/dist/src/daemon-utils.d.ts +18 -0
- package/dist/src/daemon-utils.js +1 -0
- package/dist/src/daemon.d.ts +22 -0
- package/dist/src/daemon.js +1 -0
- package/dist/src/daemon.test.d.ts +1 -0
- package/dist/src/discovery.d.ts +43 -0
- package/dist/src/discovery.js +2 -0
- package/dist/src/doctor.d.ts +38 -0
- package/dist/src/doctor.js +13 -0
- package/dist/src/doctor.test.d.ts +1 -0
- package/dist/src/download/article-download.d.ts +72 -0
- package/dist/src/download/article-download.js +21 -0
- package/dist/src/download/article-download.test.d.ts +1 -0
- package/dist/src/download/index.d.ts +71 -0
- package/dist/src/download/index.js +7 -0
- package/dist/src/download/index.test.d.ts +1 -0
- package/dist/src/download/media-download.d.ts +49 -0
- package/dist/src/download/media-download.js +1 -0
- package/dist/src/download/media-download.test.d.ts +1 -0
- package/dist/src/download/progress.d.ts +36 -0
- package/dist/src/download/progress.js +5 -0
- package/dist/src/download/progress.test.d.ts +1 -0
- package/dist/src/electron-apps.d.ts +31 -0
- package/dist/src/electron-apps.js +1 -0
- package/dist/src/electron-apps.test.d.ts +1 -0
- package/dist/src/engine.test.d.ts +1 -0
- package/dist/src/errors.d.ts +117 -0
- package/dist/src/errors.js +2 -0
- package/dist/src/errors.test.d.ts +1 -0
- package/dist/src/execution.d.ts +24 -0
- package/dist/src/execution.js +2 -0
- package/dist/src/execution.test.d.ts +1 -0
- package/dist/src/extension-manifest-regression.test.d.ts +1 -0
- package/dist/src/external-clis.yaml +109 -0
- package/dist/src/external.d.ts +49 -0
- package/dist/src/external.js +1 -0
- package/dist/src/external.test.d.ts +1 -0
- package/dist/src/help.d.ts +88 -0
- package/dist/src/help.js +8 -0
- package/dist/src/help.test.d.ts +1 -0
- package/dist/src/hooks.d.ts +46 -0
- package/dist/src/hooks.js +1 -0
- package/dist/src/hooks.test.d.ts +4 -0
- package/dist/src/interceptor.d.ts +44 -0
- package/dist/src/interceptor.js +123 -0
- package/dist/src/interceptor.test.d.ts +4 -0
- package/dist/src/launcher.d.ts +41 -0
- package/dist/src/launcher.js +7 -0
- package/dist/src/launcher.test.d.ts +1 -0
- package/dist/src/logger.d.ts +26 -0
- package/dist/src/logger.js +9 -0
- package/dist/src/main.d.ts +5 -0
- package/dist/src/main.js +10 -0
- package/dist/src/manifest-types.d.ts +43 -0
- package/dist/src/manifest-types.js +1 -0
- package/dist/src/node-network.d.ts +10 -0
- package/dist/src/node-network.js +1 -0
- package/dist/src/node-network.test.d.ts +1 -0
- package/dist/src/observation/artifact.d.ts +16 -0
- package/dist/src/observation/artifact.js +8 -0
- package/dist/src/observation/artifact.test.d.ts +1 -0
- package/dist/src/observation/events.d.ts +89 -0
- package/dist/src/observation/events.js +1 -0
- package/dist/src/observation/index.d.ts +7 -0
- package/dist/src/observation/index.js +1 -0
- package/dist/src/observation/manager.d.ts +9 -0
- package/dist/src/observation/manager.js +1 -0
- package/dist/src/observation/manager.test.d.ts +1 -0
- package/dist/src/observation/redaction.d.ts +11 -0
- package/dist/src/observation/redaction.js +2 -0
- package/dist/src/observation/redaction.test.d.ts +1 -0
- package/dist/src/observation/retention.d.ts +32 -0
- package/dist/src/observation/retention.js +1 -0
- package/dist/src/observation/retention.test.d.ts +1 -0
- package/dist/src/observation/ring-buffer.d.ts +22 -0
- package/dist/src/observation/ring-buffer.js +1 -0
- package/dist/src/observation/ring-buffer.test.d.ts +1 -0
- package/dist/src/observation/session.d.ts +25 -0
- package/dist/src/observation/session.js +1 -0
- package/dist/src/output.d.ts +14 -0
- package/dist/src/output.js +2 -0
- package/dist/src/output.test.d.ts +1 -0
- package/dist/src/package-exports.test.d.ts +1 -0
- package/dist/src/package-paths.d.ts +8 -0
- package/dist/src/package-paths.js +1 -0
- package/dist/src/pipeline/executor.d.ts +11 -0
- package/dist/src/pipeline/executor.js +1 -0
- package/dist/src/pipeline/executor.test.d.ts +4 -0
- package/dist/src/pipeline/index.d.ts +5 -0
- package/dist/src/pipeline/index.js +1 -0
- package/dist/src/pipeline/registry.d.ts +28 -0
- package/dist/src/pipeline/registry.js +1 -0
- package/dist/src/pipeline/steps/browser.d.ts +13 -0
- package/dist/src/pipeline/steps/browser.js +1 -0
- package/dist/src/pipeline/steps/download.d.ts +18 -0
- package/dist/src/pipeline/steps/download.js +1 -0
- package/dist/src/pipeline/steps/download.test.d.ts +1 -0
- package/dist/src/pipeline/steps/fetch.d.ts +5 -0
- package/dist/src/pipeline/steps/fetch.js +31 -0
- package/dist/src/pipeline/steps/fetch.test.d.ts +1 -0
- package/dist/src/pipeline/steps/intercept.d.ts +5 -0
- package/dist/src/pipeline/steps/intercept.js +1 -0
- package/dist/src/pipeline/steps/tap.d.ts +12 -0
- package/dist/src/pipeline/steps/tap.js +53 -0
- package/dist/src/pipeline/steps/transform.d.ts +9 -0
- package/dist/src/pipeline/steps/transform.js +1 -0
- package/dist/src/pipeline/template.d.ts +17 -0
- package/dist/src/pipeline/template.js +1 -0
- package/dist/src/pipeline/template.test.d.ts +4 -0
- package/dist/src/pipeline/transform.test.d.ts +4 -0
- package/dist/src/plugin-manifest.d.ts +70 -0
- package/dist/src/plugin-manifest.js +1 -0
- package/dist/src/plugin-manifest.test.d.ts +4 -0
- package/dist/src/plugin-scaffold.d.ts +28 -0
- package/dist/src/plugin-scaffold.js +75 -0
- package/dist/src/plugin-scaffold.test.d.ts +4 -0
- package/dist/src/plugin.d.ts +145 -0
- package/dist/src/plugin.js +20 -0
- package/dist/src/plugin.test.d.ts +4 -0
- package/dist/src/rate-limit.d.ts +15 -0
- package/dist/src/rate-limit.js +2 -0
- package/dist/src/rate-limit.test.d.ts +1 -0
- package/dist/src/registry-api.d.ts +13 -0
- package/dist/src/registry-api.js +1 -0
- package/dist/src/registry.d.ts +130 -0
- package/dist/src/registry.js +1 -0
- package/dist/src/registry.test.d.ts +4 -0
- package/dist/src/runtime-detect.d.ts +31 -0
- package/dist/src/runtime-detect.js +1 -0
- package/dist/src/runtime-detect.test.d.ts +1 -0
- package/dist/src/runtime.d.ts +57 -0
- package/dist/src/runtime.js +1 -0
- package/dist/src/scripts/framework.d.ts +7 -0
- package/dist/src/scripts/framework.js +1 -0
- package/dist/src/scripts/interact.d.ts +4 -0
- package/dist/src/scripts/interact.js +1 -0
- package/dist/src/scripts/store.d.ts +13 -0
- package/dist/src/scripts/store.js +1 -0
- package/dist/src/serialization.d.ts +42 -0
- package/dist/src/serialization.js +4 -0
- package/dist/src/serialization.test.d.ts +1 -0
- package/dist/src/skills.d.ts +14 -0
- package/dist/src/skills.js +6 -0
- package/dist/src/skills.test.d.ts +1 -0
- package/dist/src/snapshotFormatter.d.ts +11 -0
- package/dist/src/snapshotFormatter.js +3 -0
- package/dist/src/snapshotFormatter.test.d.ts +7 -0
- package/dist/src/tui.d.ts +28 -0
- package/dist/src/tui.js +16 -0
- package/dist/src/tui.test.d.ts +1 -0
- package/dist/src/types.d.ts +236 -0
- package/dist/src/types.js +1 -0
- package/dist/src/utils.d.ts +57 -0
- package/dist/src/utils.js +38 -0
- package/dist/src/utils.test.d.ts +1 -0
- package/dist/src/validate.d.ts +21 -0
- package/dist/src/validate.js +3 -0
- package/dist/src/validate.test.d.ts +9 -0
- package/dist/src/verify.d.ts +27 -0
- package/dist/src/verify.js +2 -0
- package/dist/src/verify.test.d.ts +8 -0
- package/dist/src/version.d.ts +4 -0
- package/dist/src/version.js +1 -0
- package/dist/src/weixin-download.test.d.ts +1 -0
- package/docs/guide/browser-bridge.md +94 -0
- package/docs/guide/electron-app-cli.md +199 -0
- package/docs/guide/exit-codes.md +24 -0
- package/docs/guide/extending-opencli.md +134 -0
- package/docs/guide/getting-started.md +81 -0
- package/docs/guide/installation.md +52 -0
- package/docs/guide/plugins.md +226 -0
- package/docs/guide/remote-orchestration.md +116 -0
- package/docs/guide/troubleshooting.md +69 -0
- package/package.json +116 -0
- package/scripts/check-doc-coverage.sh +81 -0
- package/scripts/check-listing-id-pairing.mjs +193 -0
- package/scripts/check-silent-column-drop.mjs +105 -0
- package/scripts/check-typed-error-lint.mjs +118 -0
- package/scripts/clean-dist.cjs +13 -0
- package/scripts/copy-yaml.cjs +12 -0
- package/scripts/fetch-adapters.js +293 -0
- package/scripts/minify-release.mjs +115 -0
- package/scripts/postinstall.js +174 -0
- package/scripts/silent-column-drop-baseline.json +910 -0
- package/scripts/typed-error-lint-baseline.json +1098 -0
- package/skills/opencli-adapter-author/SKILL.md +256 -0
- package/skills/opencli-adapter-author/references/adapter-template.md +471 -0
- package/skills/opencli-adapter-author/references/api-discovery.md +295 -0
- package/skills/opencli-adapter-author/references/coverage-matrix.md +81 -0
- package/skills/opencli-adapter-author/references/field-conventions.md +172 -0
- package/skills/opencli-adapter-author/references/field-decode-playbook.md +181 -0
- package/skills/opencli-adapter-author/references/jsdom-fixture-pattern.md +196 -0
- package/skills/opencli-adapter-author/references/output-design.md +149 -0
- package/skills/opencli-adapter-author/references/site-memory/bilibili.md +70 -0
- package/skills/opencli-adapter-author/references/site-memory/eastmoney.md +70 -0
- package/skills/opencli-adapter-author/references/site-memory/tonghuashun.md +51 -0
- package/skills/opencli-adapter-author/references/site-memory/xueqiu.md +58 -0
- package/skills/opencli-adapter-author/references/site-memory.md +231 -0
- package/skills/opencli-adapter-author/references/site-recon.md +134 -0
- package/skills/opencli-adapter-author/references/strategy-selection.md +169 -0
- package/skills/opencli-adapter-author/references/success-rate-pitfalls.md +162 -0
- package/skills/opencli-adapter-author/references/typed-errors.md +234 -0
- package/skills/opencli-autofix/SKILL.md +297 -0
- package/skills/opencli-browser/SKILL.md +468 -0
- package/skills/opencli-browser-sitemap/SKILL.md +96 -0
- package/skills/opencli-sitemap-author/SKILL.md +161 -0
- package/skills/opencli-sitemap-author/references/sitemap-schema.md +660 -0
- package/skills/opencli-usage/SKILL.md +168 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import{cli as s,Strategy as r}from"@jackwener/opencli/registry";import{FETCH_BROWSE_FN as c,extractPlaylistVideos as l}from"./utils.js";import{CommandExecutionError as n,EmptyResultError as d}from"@jackwener/opencli/errors";s({site:"youtube",name:"watch-later",access:"read",description:"Get your YouTube Watch Later queue",domain:"www.youtube.com",strategy:r.COOKIE,args:[{name:"limit",type:"int",default:50,help:"Max videos to return (default 50, max 200)"}],columns:["rank","title","channel","duration","views","published","url"],func:async(e,o)=>{const i=Math.min(o.limit||50,200);await e.goto("https://www.youtube.com/playlist?list=WL");await e.wait(3);const t=await e.evaluate(`
|
|
2
|
+
(async () => {
|
|
3
|
+
const d = window.ytInitialData;
|
|
4
|
+
if (!d) return { error: 'YouTube data not found — are you logged in?' };
|
|
5
|
+
|
|
6
|
+
const limit = ${i};
|
|
7
|
+
const cfg = window.ytcfg?.data_ || {};
|
|
8
|
+
const apiKey = cfg.INNERTUBE_API_KEY;
|
|
9
|
+
const context = cfg.INNERTUBE_CONTEXT;
|
|
10
|
+
|
|
11
|
+
const header = d.header?.playlistHeaderRenderer;
|
|
12
|
+
const title = header?.title?.simpleText || 'Watch Later';
|
|
13
|
+
const stats = (header?.stats || [])
|
|
14
|
+
.map(s => s.runs?.map(r => r.text)?.join('') || s.simpleText || '')
|
|
15
|
+
.filter(Boolean);
|
|
16
|
+
|
|
17
|
+
const tabs = d.contents?.twoColumnBrowseResultsRenderer?.tabs || [];
|
|
18
|
+
let listContents = tabs[0]?.tabRenderer?.content?.sectionListRenderer?.contents?.[0]?.itemSectionRenderer?.contents?.[0]?.playlistVideoListRenderer?.contents || [];
|
|
19
|
+
|
|
20
|
+
${c}
|
|
21
|
+
|
|
22
|
+
const extractVideos = ${l.toString()};
|
|
23
|
+
|
|
24
|
+
let videos = extractVideos(listContents);
|
|
25
|
+
|
|
26
|
+
let contItem = listContents[listContents.length - 1];
|
|
27
|
+
while (videos.length < limit && contItem?.continuationItemRenderer && apiKey && context) {
|
|
28
|
+
const token = contItem.continuationItemRenderer?.continuationEndpoint?.continuationCommand?.token;
|
|
29
|
+
if (!token) break;
|
|
30
|
+
const contData = await fetchBrowse(apiKey, { context, continuation: token });
|
|
31
|
+
if (contData.error) break;
|
|
32
|
+
const newItems = contData.onResponseReceivedActions?.[0]?.appendContinuationItemsAction?.continuationItems || [];
|
|
33
|
+
if (!newItems.length) break;
|
|
34
|
+
videos = videos.concat(extractVideos(newItems));
|
|
35
|
+
contItem = newItems[newItems.length - 1];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return { title, stats, videos: videos.slice(0, limit) };
|
|
39
|
+
})()
|
|
40
|
+
`);if(!t||typeof t!=="object")throw new n("Failed to fetch Watch Later — make sure you are logged into YouTube");if(t.error)throw new n(String(t.error));if(!t.videos?.length)throw new d("youtube watch-later");const a=(t.stats||[]).join(" | ");process.stderr.write(`${t.title} ${a}
|
|
41
|
+
`);return t.videos}});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import{cli as N,Strategy as U}from"@jackwener/opencli/registry";import{htmlToMarkdown as O}from"@jackwener/opencli/utils";import{ArgumentError as _,CommandExecutionError as h,TimeoutError as R}from"@jackwener/opencli/errors";import{YUANBAO_DOMAIN as Y,IS_VISIBLE_JS as Z,authRequired as H,isOnYuanbao as z,ensureYuanbaoPage as M,hasLoginGate as P,normalizeBooleanFlag as Q,sendYuanbaoMessage as k}from"./shared.js";const L=2,w=8000,C=3;function S(j,y){const q=y?` Detail: ${y}`:"";return new h(`${j||"Unknown Yuanbao send failure."}${q}`,"Make sure the Yuanbao chat composer is visible and ready before retrying.")}function I(j){return typeof j==="string"?j.trim():""}export function convertYuanbaoHtmlToMarkdown(j){return O(j,(y)=>{y.addRule("table",{filter:"table",replacement:(q)=>`
|
|
2
|
+
|
|
3
|
+
${q}
|
|
4
|
+
|
|
5
|
+
`});y.addRule("tableSection",{filter:["thead","tbody","tfoot"],replacement:(q)=>q});y.addRule("tableRow",{filter:"tr",replacement:(q,F)=>{const G=F,J=Array.from(G.children),W=G.parentElement?.tagName==="THEAD"||J.length>0&&J.every((X)=>X.tagName==="TH"),K=`${q}
|
|
6
|
+
`;if(!W)return K;const V=`| ${J.map(()=>"---").join(" | ")} |
|
|
7
|
+
`;return`${K}${V}`}});y.addRule("tableCell",{filter:["th","td"],replacement:(q,F)=>{const G=F;return`${(G.parentElement?Array.from(G.parentElement.children).indexOf(G):0)===0?"| ":" "}${q.trim()} |`}})})}export function sanitizeYuanbaoResponseText(j,y){let q=j.replace(/内容由AI生成,仅供参考/gi,"").replace(/重新回答/gi,"").trim();if(/^(正在搜索资料|搜索资料中|正在思考|思考中)[.。…]*$/u.test(q))return"";const F=y.trim();if(!F)return q;if(q===F)return"";for(const G of[`
|
|
8
|
+
|
|
9
|
+
`,`
|
|
10
|
+
`,`\r
|
|
11
|
+
\r
|
|
12
|
+
`,`\r
|
|
13
|
+
`," "]){const J=`${F}${G}`;if(q.startsWith(J)){q=q.slice(J.length).trim();break}}return q}export function collectYuanbaoTranscriptAdditions(j,y,q){const F=new Set(j);return y.filter((J)=>!F.has(J)).map((J)=>sanitizeYuanbaoResponseText(J,q)).filter((J)=>J&&J!==q).join(`
|
|
14
|
+
`).trim()}export function pickLatestYuanbaoAssistantCandidate(j,y,q){const F=j.slice(Math.max(0,y)).map((G)=>sanitizeYuanbaoResponseText(G,q)).filter(Boolean);for(let G=F.length-1;G>=0;G-=1)if(F[G]!==q.trim())return F[G];return""}export function updateStableState(j,y,q){if(!q)return{previousText:"",stableCount:0};if(q===j)return{previousText:j,stableCount:y+1};return{previousText:q,stableCount:0}}function A(){return`
|
|
15
|
+
(() => {
|
|
16
|
+
const clean = (value) => (value || '')
|
|
17
|
+
.replace(/\\u00a0/g, ' ')
|
|
18
|
+
.replace(/\\n{3,}/g, '\\n\\n')
|
|
19
|
+
.trim();
|
|
20
|
+
|
|
21
|
+
const root = (
|
|
22
|
+
document.querySelector('.agent-dialogue__content--common')
|
|
23
|
+
|| document.querySelector('.agent-dialogue__content')
|
|
24
|
+
|| document.querySelector('.agent-dialogue')
|
|
25
|
+
|| document.body
|
|
26
|
+
).cloneNode(true);
|
|
27
|
+
|
|
28
|
+
const removableSelectors = [
|
|
29
|
+
'.agent-dialogue__content--common__input',
|
|
30
|
+
'.agent-dialogue__tool',
|
|
31
|
+
'.agent-dialogue__content-copyright',
|
|
32
|
+
'.index_chatLandingBox__G7hAT',
|
|
33
|
+
'.index_chatLandingBoxMobile__J8i8v',
|
|
34
|
+
'.index_chatLandingHintList__M69Lr',
|
|
35
|
+
'.yb-nav',
|
|
36
|
+
'.agent-dialogue__content--common__input .ql-toolbar',
|
|
37
|
+
'.agent-dialogue__content--common__input .ql-container',
|
|
38
|
+
'.agent-dialogue__content--common__input .ql-editor',
|
|
39
|
+
'[role="dialog"]',
|
|
40
|
+
'iframe',
|
|
41
|
+
'button',
|
|
42
|
+
'script',
|
|
43
|
+
'style',
|
|
44
|
+
'noscript',
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
for (const selector of removableSelectors) {
|
|
48
|
+
root.querySelectorAll(selector).forEach((node) => node.remove());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const stopLines = new Set([
|
|
52
|
+
'元宝',
|
|
53
|
+
'DeepSeek',
|
|
54
|
+
'深度思考',
|
|
55
|
+
'联网搜索',
|
|
56
|
+
'工具',
|
|
57
|
+
'登录',
|
|
58
|
+
'安装电脑版',
|
|
59
|
+
'内容由AI生成,仅供参考',
|
|
60
|
+
'有问题,尽管问,shift+enter换行',
|
|
61
|
+
'立即创建团队',
|
|
62
|
+
'微信',
|
|
63
|
+
'手机',
|
|
64
|
+
'QQ',
|
|
65
|
+
'微信扫码登录',
|
|
66
|
+
'扫码默认已阅读并同意',
|
|
67
|
+
'用户服务协议',
|
|
68
|
+
'隐私协议',
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
const noisyPatterns = [
|
|
72
|
+
/^支持文件格式[::]/,
|
|
73
|
+
/^文件拖动到此处即可上传/,
|
|
74
|
+
/^下载元宝电脑版/,
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
return clean(root.innerText || root.textContent || '')
|
|
78
|
+
.split('\\n')
|
|
79
|
+
.map((line) => clean(line))
|
|
80
|
+
.filter((line) => line
|
|
81
|
+
&& line.length <= 4000
|
|
82
|
+
&& !stopLines.has(line)
|
|
83
|
+
&& !noisyPatterns.some((pattern) => pattern.test(line)));
|
|
84
|
+
})()
|
|
85
|
+
`}async function B(j){const y=await j.evaluate(A());return Array.isArray(y)?y.map(I).filter(Boolean):[]}async function E(j){const y=await j.evaluate(`(() => {
|
|
86
|
+
${Z}
|
|
87
|
+
|
|
88
|
+
const roots = Array.from(document.querySelectorAll('.agent-chat__list__item--ai'))
|
|
89
|
+
.filter((node) => isVisible(node));
|
|
90
|
+
|
|
91
|
+
return roots.map((root) => {
|
|
92
|
+
const doneContent = root.querySelector('.hyc-content-md-done');
|
|
93
|
+
const markdownContent = doneContent || root.querySelector('.hyc-content-md');
|
|
94
|
+
const speechContent = root.querySelector('.agent-chat__speech-text');
|
|
95
|
+
const bubbleContent = root.querySelector('.agent-chat__bubble__content');
|
|
96
|
+
const content = markdownContent || speechContent || bubbleContent;
|
|
97
|
+
|
|
98
|
+
if (content instanceof HTMLElement) {
|
|
99
|
+
return content.innerHTML || content.textContent || '';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return root instanceof HTMLElement ? (root.innerHTML || root.textContent || '') : '';
|
|
103
|
+
}).filter(Boolean);
|
|
104
|
+
})()`);return Array.isArray(y)?y.map((q)=>convertYuanbaoHtmlToMarkdown(typeof q==="string"?q:"")).map(I).filter(Boolean):[]}async function f(j){return await j.evaluate(`(() => {
|
|
105
|
+
${Z}
|
|
106
|
+
|
|
107
|
+
const button = Array.from(document.querySelectorAll('[dt-button-id="internet_search"]'))
|
|
108
|
+
.find((node) => isVisible(node));
|
|
109
|
+
|
|
110
|
+
if (!(button instanceof HTMLElement)) return { found: false, enabled: false };
|
|
111
|
+
|
|
112
|
+
const attr = button.getAttribute('dt-internet-search') || '';
|
|
113
|
+
const className = button.className || '';
|
|
114
|
+
return {
|
|
115
|
+
found: true,
|
|
116
|
+
enabled: attr === 'openInternetSearch' || className.includes('index_v2_active__'),
|
|
117
|
+
};
|
|
118
|
+
})()`)}async function v(j,y){const q=await f(j);if(!q.found||q.enabled===y)return;await j.evaluate(`(() => {
|
|
119
|
+
${Z}
|
|
120
|
+
|
|
121
|
+
const button = Array.from(document.querySelectorAll('[dt-button-id="internet_search"]'))
|
|
122
|
+
.find((node) => isVisible(node));
|
|
123
|
+
|
|
124
|
+
if (button instanceof HTMLElement) button.click();
|
|
125
|
+
})()`);await j.wait(0.5)}async function b(j){return await j.evaluate(`(() => {
|
|
126
|
+
${Z}
|
|
127
|
+
|
|
128
|
+
const button = Array.from(document.querySelectorAll('[dt-button-id="deep_think"]'))
|
|
129
|
+
.find((node) => isVisible(node));
|
|
130
|
+
|
|
131
|
+
if (!(button instanceof HTMLElement)) return { found: false, enabled: false };
|
|
132
|
+
|
|
133
|
+
const className = button.className || '';
|
|
134
|
+
return {
|
|
135
|
+
found: true,
|
|
136
|
+
enabled: className.includes('ThinkSelector_selected__'),
|
|
137
|
+
};
|
|
138
|
+
})()`)}async function T(j,y){const q=await b(j);if(!q.found||q.enabled===y)return;await j.evaluate(`(() => {
|
|
139
|
+
${Z}
|
|
140
|
+
|
|
141
|
+
const button = Array.from(document.querySelectorAll('[dt-button-id="deep_think"]'))
|
|
142
|
+
.find((node) => isVisible(node));
|
|
143
|
+
|
|
144
|
+
if (button instanceof HTMLElement) button.click();
|
|
145
|
+
})()`);await j.wait(0.5)}async function c(j,y,q,F,G){const J=Date.now();let W="",K=0,V="";while(Date.now()-J<G*1000){await j.wait(L);if(await P(j))return"blocked";const X=await E(j),$=pickLatestYuanbaoAssistantCandidate(X,y,F)||collectYuanbaoTranscriptAdditions(q,await B(j),F);if(!$)continue;V=$;const D=updateStableState(W,K,$);W=D.previousText;K=D.stableCount;if(Date.now()-J>=w&&K>=C)return $}return V||null}export const askCommand=N({site:"yuanbao",name:"ask",access:"write",description:"Send a prompt to Yuanbao web chat and wait for the assistant response",domain:Y,strategy:U.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,defaultFormat:"plain",args:[{name:"prompt",required:!0,positional:!0,help:"Prompt to send"},{name:"timeout",type:"int",required:!1,help:"Max seconds to wait (default: 60)",default:60},{name:"search",type:"boolean",required:!1,help:"Enable Yuanbao internet search (default: true)",default:!0},{name:"think",type:"boolean",required:!1,help:"Enable Yuanbao deep thinking (default: false)",default:!1}],columns:["Role","Text"],func:async(j,y)=>{const{prompt:q,timeout:F}=y;if(!Number.isInteger(F)||F<1)throw new _("--timeout must be a positive integer (seconds)");const G=Q(y.search,!0),J=Q(y.think,!1);await M(j);if(await P(j))throw H("Yuanbao opened a login gate before sending the prompt.");await v(j,G);await T(j,J);const W=await E(j),K=await B(j),V=await k(j,q);if(!V?.ok){if(await P(j))throw H("Yuanbao opened a login gate instead of accepting the prompt.");throw S(V?.reason,V?.detail)}const X=await c(j,W.length,K,q,F);if(X==="blocked")throw H("Yuanbao opened a login gate instead of returning a chat response.");if(!X)throw new R("yuanbao ask",F,"No Yuanbao response was observed before the timeout. Retry with --timeout, and verify the current browser session is still interactive.");return[{Role:"User",Text:q},{Role:"Assistant",Text:X}]}}),__test__={collectYuanbaoTranscriptAdditions,convertYuanbaoHtmlToMarkdown,isOnYuanbao:z,normalizeBooleanFlag:Q,pickLatestYuanbaoAssistantCandidate,sanitizeYuanbaoResponseText,updateStableState};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import{AuthRequiredError as t,CommandExecutionError as y}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as u}from"../_shared/site-auth.js";import{hasLoginGate as k,ensureYuanbaoPage as m,YUANBAO_DOMAIN as o,YUANBAO_URL as d}from"./shared.js";async function a(n){return(await n.getCookies({url:"https://yuanbao.tencent.com"})).some((e)=>e.name==="hy_user"&&e.value)}async function i(n){await m(n);if(await k(n))throw new t(o,"Yuanbao showed wx login gate — anonymous session");const e=(await n.getCookies({url:"https://yuanbao.tencent.com"})).find((r)=>r.name==="hy_user")?.value||"";if(!e)throw new t(o,"Yuanbao hy_user cookie missing — anonymous session");const c=await n.evaluate(`
|
|
2
|
+
(() => {
|
|
3
|
+
const bodyText = document.body?.innerText || '';
|
|
4
|
+
const nickMatch = bodyText.match(/用户[a-z0-9]{4,}/i);
|
|
5
|
+
const state = window.__INITIAL_STATE__ || {};
|
|
6
|
+
const seen = new Set();
|
|
7
|
+
const stack = [state];
|
|
8
|
+
let stateNick = '';
|
|
9
|
+
while (stack.length) {
|
|
10
|
+
const node = stack.pop();
|
|
11
|
+
if (!node || typeof node !== 'object' || seen.has(node)) continue;
|
|
12
|
+
seen.add(node);
|
|
13
|
+
if (Array.isArray(node)) { stack.push(...node); continue; }
|
|
14
|
+
const u = node.userInfo || node.user;
|
|
15
|
+
if (u && typeof u === 'object' && (u.nickname || u.nick)) {
|
|
16
|
+
stateNick = String(u.nickname || u.nick);
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
for (const v of Object.values(node)) if (v && typeof v === 'object') stack.push(v);
|
|
20
|
+
}
|
|
21
|
+
return { nickname: stateNick || (nickMatch ? nickMatch[0] : '') };
|
|
22
|
+
})()
|
|
23
|
+
`);return{user_id:String(e),nickname:String(c.nickname||"")}}u({site:"yuanbao",domain:o,loginUrl:d,columns:["user_id","nickname"],quickCheck:a,verify:i,poll:async(n)=>{if(!await a(n))throw new t(o,"Waiting for Yuanbao hy_user cookie");return i(n)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as $,Strategy as q}from"@jackwener/opencli/registry";import{EmptyResultError as x}from"@jackwener/opencli/errors";import{YUANBAO_DOMAIN as G,YUANBAO_URL as H,getYuanbaoMessageBubbles as V,parseYuanbaoSessionId as P,hasLoginGate as T,authRequired as f}from"./shared.js";import{convertYuanbaoHtmlToMarkdown as m}from"./ask.js";$({site:"yuanbao",name:"detail",access:"read",description:"Open a Yuanbao conversation by ID and read its messages",domain:G,strategy:q.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"id",positional:!0,required:!0,help:'Full https://yuanbao.tencent.com/chat/<agentId>/<convId> URL or "<agentId>/<convId>" pair (a UUID alone is not enough — Yuanbao requires the agent slug)'}],columns:["Role","Text"],func:async(C,Q)=>{const{agentId:J,convId:K}=P(Q.id);await C.goto(`${H}chat/${J}/${K}`,{waitUntil:"load",settleMs:2500});await C.wait(2);if(await T(C))throw f("Yuanbao opened a login gate when navigating to the conversation.");let F=[];const W=20000,X=1,Z=Date.now();while(Date.now()-Z<W){F=await V(C);if(F.length>0)break;await C.wait(X)}if(!F.length)throw new x("yuanbao detail",`No visible messages found for conversation ${J}/${K}. Verify the IDs are correct and that the session belongs to the current login.`);return F.map((z)=>({Role:z.role,Text:z.role==="Assistant"&&z.html?m(z.html).trim()||z.text:z.text}))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as o,Strategy as s}from"@jackwener/opencli/registry";import{ArgumentError as u,EmptyResultError as l}from"@jackwener/opencli/errors";import{YUANBAO_DOMAIN as d,YUANBAO_URL as c,ensureYuanbaoPage as h,getYuanbaoSessionList as m,hasLoginGate as g,authRequired as b}from"./shared.js";o({site:"yuanbao",name:"history",access:"read",description:"List recent Yuanbao conversations from the sidebar (requires login)",domain:d,strategy:s.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"limit",type:"int",default:20,help:"Max conversations to list (sidebar virtual scroll caps actual count)"}],columns:["Index","Title","AgentId","SessionId","Url"],func:async(t,r)=>{const i=Number(r.limit??20);if(!Number.isInteger(i)||i<=0)throw new u("limit","must be a positive integer");await h(t);if(await g(t))throw b("Yuanbao opened a login gate when reading the sidebar.");await t.wait(1.5);const a=await m(t,i);if(!a.length)throw new l("yuanbao history","No Yuanbao conversations found in the sidebar. Either the account is logged out, the sidebar is collapsed, or the user truly has no chat history yet.");return a.map((e,n)=>({Index:n+1,Title:e.title||"(untitled)",AgentId:e.agentId,SessionId:e.cid,Url:`${c}chat/${e.agentId}/${e.cid}`}))}});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import{cli as c,Strategy as s}from"@jackwener/opencli/registry";import{YUANBAO_DOMAIN as u,YUANBAO_URL as n,IS_VISIBLE_JS as l,authRequired as w,ensureYuanbaoPage as d,hasLoginGate as a}from"./shared.js";async function o(t){const e=await t.evaluate("window.location.href").catch(()=>"");return typeof e==="string"?e:""}async function f(t){const e=await t.evaluate(`(() => {
|
|
2
|
+
const composer = document.querySelector('.ql-editor, [contenteditable="true"]');
|
|
3
|
+
return composer ? (composer.textContent || '').trim() : '';
|
|
4
|
+
})()`);return typeof e==="string"?e.trim():""}async function m(t){await d(t);if(await a(t))return"blocked";const e=await o(t);if(await t.evaluate(`(() => {
|
|
5
|
+
${l}
|
|
6
|
+
|
|
7
|
+
const trigger = Array.from(document.querySelectorAll('.yb-common-nav__trigger[data-desc="new-chat"]'))
|
|
8
|
+
.find((node) => isVisible(node));
|
|
9
|
+
|
|
10
|
+
if (trigger instanceof HTMLElement) {
|
|
11
|
+
trigger.click();
|
|
12
|
+
return 'clicked';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return 'navigate';
|
|
16
|
+
})()`)==="navigate"){await t.goto(n,{waitUntil:"load",settleMs:2500});await t.wait(1);if(await a(t))return"blocked";return"navigate"}await t.wait(1);if(await a(t))return"blocked";const i=await o(t),r=await f(t);if(i!==e||!r)return"clicked";await t.goto(n,{waitUntil:"load",settleMs:2500});await t.wait(1);return"navigate"}export const newCommand=c({site:"yuanbao",name:"new",access:"read",description:"Start a new conversation in Yuanbao web chat",domain:u,strategy:s.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:["Status","Action"],func:async(t)=>{const e=await m(t);if(e==="blocked")throw w("Yuanbao opened a login gate instead of starting a new chat.");return[{Status:"Success",Action:e==="navigate"?"Reloaded Yuanbao homepage as fallback":"Clicked New chat"}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as C,Strategy as E}from"@jackwener/opencli/registry";import{YUANBAO_DOMAIN as F,ensureYuanbaoPage as G,getYuanbaoMessageBubbles as J}from"./shared.js";import{convertYuanbaoHtmlToMarkdown as K}from"./ask.js";C({site:"yuanbao",name:"read",access:"read",description:"Read messages in the current Yuanbao conversation",domain:F,strategy:E.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:["Role","Text"],func:async(q)=>{await G(q);await q.wait(1.5);const z=await J(q);if(!z.length)return[{Role:"system",Text:"No visible messages in the current Yuanbao conversation."}];return z.map((f)=>({Role:f.role,Text:f.role==="Assistant"&&f.html?K(f.html).trim()||f.text:f.text}))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as s,Strategy as p}from"@jackwener/opencli/registry";import{ArgumentError as u,CommandExecutionError as m}from"@jackwener/opencli/errors";import{YUANBAO_DOMAIN as d,authRequired as o,ensureYuanbaoPage as l,hasLoginGate as r,normalizeBooleanFlag as c,sendYuanbaoMessage as w,startNewYuanbaoChat as f}from"./shared.js";s({site:"yuanbao",name:"send",access:"write",description:"Fire-and-forget: send a prompt to Yuanbao without waiting for the reply",domain:d,strategy:p.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[{name:"prompt",positional:!0,required:!0,help:"Prompt to send to Yuanbao"},{name:"new",type:"boolean",default:!1,help:"Start a new chat before sending"}],columns:["Status","Prompt"],func:async(t,n)=>{const a=String(n.prompt||"").trim();if(!a)throw new u("prompt","is required");const i=c(n.new,!1);await l(t);if(await r(t))throw o("Yuanbao opened a login gate before sending the prompt.");if(i){if(await f(t)==="blocked")throw o("Yuanbao opened a login gate while starting a new chat.")}const e=await w(t,a);if(!e?.ok){if(await r(t))throw o("Yuanbao opened a login gate instead of accepting the prompt.");throw new m(e?.reason||"Failed to send Yuanbao prompt",e?.detail?`Detail: ${e.detail}`:"Make sure the Yuanbao chat composer is visible and not in a disabled state.")}return[{Status:"sent",Prompt:a}]}});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import{ArgumentError as j,AuthRequiredError as P}from"@jackwener/opencli/errors";export const YUANBAO_DOMAIN="yuanbao.tencent.com",YUANBAO_URL="https://yuanbao.tencent.com/";const W="Likely login/auth/challenge/session issue in the existing yuanbao.tencent.com browser session.",q=/^[A-Za-z0-9_-]{4,40}$/,H=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;export const IS_VISIBLE_JS=`const isVisible = (node) => {
|
|
2
|
+
if (!(node instanceof HTMLElement)) return false;
|
|
3
|
+
const rect = node.getBoundingClientRect();
|
|
4
|
+
const style = window.getComputedStyle(node);
|
|
5
|
+
return rect.width > 0
|
|
6
|
+
&& rect.height > 0
|
|
7
|
+
&& style.display !== 'none'
|
|
8
|
+
&& style.visibility !== 'hidden';
|
|
9
|
+
};`;export function authRequired(x){return new P(YUANBAO_DOMAIN,`${x} ${W}`)}export function normalizeBooleanFlag(x,F=!1){if(typeof x==="boolean")return x;if(x==null||x==="")return F;const K=String(x).trim().toLowerCase();return K==="true"||K==="1"||K==="yes"||K==="on"}export async function isOnYuanbao(x){const F=await x.evaluate("window.location.href").catch(()=>"");if(typeof F!=="string"||!F)return!1;try{const K=new URL(F).hostname;return K===YUANBAO_DOMAIN||K.endsWith(`.${YUANBAO_DOMAIN}`)}catch{return!1}}export async function ensureYuanbaoPage(x){if(!await isOnYuanbao(x)){await x.goto(YUANBAO_URL,{waitUntil:"load",settleMs:2500});await x.wait(1)}}export async function hasLoginGate(x){const F=await x.evaluate(`(() => {
|
|
10
|
+
const bodyText = document.body.innerText || '';
|
|
11
|
+
const hasWechatLoginText = bodyText.includes('微信扫码登录');
|
|
12
|
+
const hasWechatIframe = Array.from(document.querySelectorAll('iframe'))
|
|
13
|
+
.some((frame) => (frame.getAttribute('src') || '').includes('open.weixin.qq.com/connect/qrconnect'));
|
|
14
|
+
|
|
15
|
+
return hasWechatLoginText || hasWechatIframe;
|
|
16
|
+
})()`);return Boolean(F)}export async function isLoggedIn(x){return!await hasLoginGate(x)}export function parseYuanbaoSessionId(x){const F=String(x??"").trim();if(!F)throw new j("id",'must be a non-empty Yuanbao chat URL or "<agentId>/<convId>" pair');const K=F.match(/yuanbao\.tencent\.com\/chat\/([A-Za-z0-9_-]+)\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[/?#]|$)/i);if(K){const[,X,$]=K;if(!q.test(X)||!H.test($))throw new j("id",`not a valid Yuanbao chat URL (got "${x}"); expected https://yuanbao.tencent.com/chat/<agentId>/<convId>`);return{agentId:X,convId:$.toLowerCase()}}const Z=F.match(/^([A-Za-z0-9_-]+)\/([0-9a-f-]{36})$/i);if(Z){const[,X,$]=Z;if(!q.test(X)||!H.test($))throw new j("id",`not a valid Yuanbao "<agentId>/<convId>" pair (got "${x}"); agentId must be 4-40 word chars, convId must be a UUID`);return{agentId:X,convId:$.toLowerCase()}}throw new j("id",`not a valid Yuanbao session reference (got "${x}"); pass either a full https://yuanbao.tencent.com/chat/<agentId>/<convId> URL or a bare "<agentId>/<convId>" pair. A UUID alone is not enough — Yuanbao requires the agentId.`)}export async function getCurrentYuanbaoSessionId(x){const F=await x.evaluate("window.location.href").catch(()=>"");if(typeof F!=="string")return null;const K=F.match(/yuanbao\.tencent\.com\/chat\/([A-Za-z0-9_-]+)\/([0-9a-f-]{36})(?:[/?#]|$)/i);if(!K)return null;const[,Z,X]=K;if(!q.test(Z)||!H.test(X))return null;return{agentId:Z,convId:X.toLowerCase()}}export async function getYuanbaoModelLabel(x){const F=await x.evaluate(`(() => {
|
|
17
|
+
const btn = document.querySelector('[dt-button-id="model_switch"]');
|
|
18
|
+
if (!(btn instanceof HTMLElement)) return null;
|
|
19
|
+
const label = (btn.querySelector('.t-button__text')?.textContent || btn.textContent || '').trim();
|
|
20
|
+
const modelId = btn.getAttribute('dt-model-id') || '';
|
|
21
|
+
return { label, modelId };
|
|
22
|
+
})()`);if(!F||typeof F!=="object")return{label:null,modelId:null};return{label:typeof F.label==="string"&&F.label?F.label:null,modelId:typeof F.modelId==="string"&&F.modelId?F.modelId:null}}export async function getYuanbaoMessageBubbles(x){const F=await x.evaluate(`(() => {
|
|
23
|
+
${IS_VISIBLE_JS}
|
|
24
|
+
const items = Array.from(document.querySelectorAll('.agent-chat__list__item--human, .agent-chat__list__item--ai'))
|
|
25
|
+
.filter((node) => isVisible(node));
|
|
26
|
+
return items.map((node, positional) => {
|
|
27
|
+
const isAi = node.classList.contains('agent-chat__list__item--ai');
|
|
28
|
+
const role = isAi ? 'Assistant' : 'User';
|
|
29
|
+
const id = node.getAttribute('data-conv-id') || ('pos-' + positional + (isAi ? '-ai' : '-human'));
|
|
30
|
+
const idx = Number(node.getAttribute('data-conv-idx') || positional + 1);
|
|
31
|
+
const contentNode = isAi
|
|
32
|
+
? (node.querySelector('.hyc-content-md-done')
|
|
33
|
+
|| node.querySelector('.hyc-content-md')
|
|
34
|
+
|| node.querySelector('.agent-chat__speech-text')
|
|
35
|
+
|| node.querySelector('.agent-chat__bubble__content'))
|
|
36
|
+
: (node.querySelector('.hyc-component-text .hyc-content-text')
|
|
37
|
+
|| node.querySelector('.hyc-content-text')
|
|
38
|
+
|| node.querySelector('.agent-chat__bubble__content'));
|
|
39
|
+
const html = contentNode instanceof HTMLElement ? (contentNode.innerHTML || '') : '';
|
|
40
|
+
const rawText = contentNode instanceof HTMLElement
|
|
41
|
+
? (contentNode.innerText || contentNode.textContent || '')
|
|
42
|
+
: ((node.innerText || node.textContent) || '');
|
|
43
|
+
return {
|
|
44
|
+
id,
|
|
45
|
+
idx,
|
|
46
|
+
role,
|
|
47
|
+
text: String(rawText || '').replace(/\\u00a0/g, ' ').trim(),
|
|
48
|
+
html,
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
})()`);if(!Array.isArray(F))return[];return F.map((K)=>({id:String(K?.id||""),idx:Number.isInteger(K?.idx)?K.idx:0,role:K?.role==="Assistant"?"Assistant":"User",text:String(K?.text||"").trim(),html:String(K?.html||"")})).filter((K)=>K.id&&(K.text||K.html))}export async function getYuanbaoSessionList(x,F){const K=Number(F??20);if(!Number.isInteger(K)||K<=0)throw new j("limit","must be a positive integer");const Z=await x.evaluate(`(() => {
|
|
52
|
+
${IS_VISIBLE_JS}
|
|
53
|
+
const nodes = Array.from(document.querySelectorAll('.yb-recent-conv-list__item'))
|
|
54
|
+
.filter((node) => isVisible(node));
|
|
55
|
+
return nodes.map((node) => {
|
|
56
|
+
const cid = node.getAttribute('dt-cid') || '';
|
|
57
|
+
const agentId = node.getAttribute('dt-agent-id') || '';
|
|
58
|
+
const titleEl = node.querySelector('[data-item-name]');
|
|
59
|
+
const title = (titleEl?.getAttribute('data-item-name') || titleEl?.textContent || '').trim();
|
|
60
|
+
return { cid, agentId, title };
|
|
61
|
+
});
|
|
62
|
+
})()`);if(!Array.isArray(Z))return[];return Z.map((X)=>({cid:String(X?.cid||"").toLowerCase(),agentId:String(X?.agentId||""),title:String(X?.title||"").trim()})).filter((X)=>H.test(X.cid)&&q.test(X.agentId)).slice(0,K)}export async function startNewYuanbaoChat(x){await ensureYuanbaoPage(x);if(await hasLoginGate(x))return"blocked";const F=await x.evaluate("window.location.href").catch(()=>"");if(await x.evaluate(`(() => {
|
|
63
|
+
${IS_VISIBLE_JS}
|
|
64
|
+
const trigger = Array.from(document.querySelectorAll('.yb-common-nav__trigger[data-desc="new-chat"], [dt-button-id="new_temp_chat"]'))
|
|
65
|
+
.find((node) => isVisible(node));
|
|
66
|
+
if (trigger instanceof HTMLElement) {
|
|
67
|
+
trigger.click();
|
|
68
|
+
return 'clicked';
|
|
69
|
+
}
|
|
70
|
+
return 'navigate';
|
|
71
|
+
})()`)==="navigate"){await x.goto(YUANBAO_URL,{waitUntil:"load",settleMs:2500});await x.wait(1);return await hasLoginGate(x)?"blocked":"navigate"}await x.wait(1);if(await hasLoginGate(x))return"blocked";const Z=await x.evaluate("window.location.href").catch(()=>"");if(typeof Z==="string"&&typeof F==="string"&&Z!==F)return"clicked";await x.goto(YUANBAO_URL,{waitUntil:"load",settleMs:2500});await x.wait(1);return"navigate"}export async function sendYuanbaoMessage(x,F){return await x.evaluate(`(async () => {
|
|
72
|
+
const waitFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
73
|
+
${IS_VISIBLE_JS}
|
|
74
|
+
|
|
75
|
+
const composer = Array.from(document.querySelectorAll('.ql-editor[contenteditable="true"], .ql-editor, [contenteditable="true"]'))
|
|
76
|
+
.find(isVisible);
|
|
77
|
+
|
|
78
|
+
if (!(composer instanceof HTMLElement)) {
|
|
79
|
+
return {
|
|
80
|
+
ok: false,
|
|
81
|
+
reason: 'Yuanbao composer was not found.',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
composer.focus();
|
|
87
|
+
const selection = window.getSelection();
|
|
88
|
+
const range = document.createRange();
|
|
89
|
+
range.selectNodeContents(composer);
|
|
90
|
+
range.collapse(false);
|
|
91
|
+
selection?.removeAllRanges();
|
|
92
|
+
selection?.addRange(range);
|
|
93
|
+
composer.textContent = '';
|
|
94
|
+
document.execCommand('insertText', false, ${JSON.stringify(F)});
|
|
95
|
+
composer.dispatchEvent(new InputEvent('input', { bubbles: true, data: ${JSON.stringify(F)}, inputType: 'insertText' }));
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
ok: false,
|
|
99
|
+
reason: 'Failed to insert the prompt into the Yuanbao composer.',
|
|
100
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const findEnabledSubmit = () => Array.from(document.querySelectorAll('a[class*="send-btn"], button[class*="send-btn"]'))
|
|
105
|
+
.find((node) => {
|
|
106
|
+
if (!(node instanceof HTMLElement) || !isVisible(node)) return false;
|
|
107
|
+
const className = typeof node.className === 'string' ? node.className : '';
|
|
108
|
+
return !className.includes('send-btn--disabled') && !className.includes('disabled');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
let submit = null;
|
|
112
|
+
const deadline = Date.now() + 3_000;
|
|
113
|
+
while (Date.now() < deadline) {
|
|
114
|
+
submit = findEnabledSubmit();
|
|
115
|
+
if (submit) break;
|
|
116
|
+
await waitFor(150);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (submit instanceof HTMLElement) {
|
|
120
|
+
submit.click();
|
|
121
|
+
return { ok: true, action: 'click' };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
composer.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, bubbles: true }));
|
|
125
|
+
composer.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', keyCode: 13, bubbles: true }));
|
|
126
|
+
return { ok: true, action: 'enter' };
|
|
127
|
+
})()`)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as F,Strategy as G}from"@jackwener/opencli/registry";import{YUANBAO_DOMAIN as H,ensureYuanbaoPage as J,isLoggedIn as K,getCurrentYuanbaoSessionId as Q,getYuanbaoModelLabel as R}from"./shared.js";F({site:"yuanbao",name:"status",access:"read",description:"Check Yuanbao page availability, login state, current session and model",domain:H,strategy:G.COOKIE,browser:!0,siteSession:"persistent",navigateBefore:!1,args:[],columns:["Status","Login","Model","ModelId","AgentId","SessionId","Url"],func:async(q)=>{await J(q);await q.wait(1.5);const[E,v,x,z]=await Promise.all([K(q),Q(q),R(q),q.evaluate("window.location.href").catch(()=>"")]);return[{Status:"Connected",Login:E?"Yes":"No (login gate)",Model:x.label,ModelId:x.modelId,AgentId:v?.agentId??null,SessionId:v?.convId??null,Url:typeof z==="string"?z:""}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{CliError as W,CommandExecutionError as n}from"@jackwener/opencli/errors";import{cli as R,Strategy as m}from"@jackwener/opencli/registry";import{publishArticle as w}from"../_shared/article/publish.js";export const yuqueProfile={home:"https://www.yuque.com/dashboard",outputFormat:"markdown",preprocessConfig:null,image:null,publish:async(X,K)=>{const $=K.cookie("yuque_ctoken");if(!$)return{ok:!1,stage:"auth",message:"未检测到语雀登录态,请先在 Chrome 中登录语雀(缺少 yuque_ctoken cookie)"};const L={"Content-Type":"application/json","x-csrf-token":$},q=await fetch("https://www.yuque.com/api/mine/common_used",{method:"GET",credentials:"include",headers:L});let G=null;try{G=await q.json()}catch(z){}if(!q.ok||!G?.data?.books?.length)return{ok:!1,stage:"auth",status:q.status,message:"无法获取语雀知识库列表,请确认已登录语雀"};const Q=G.data.books[0].target_id,A=await fetch("https://www.yuque.com/api/docs",{method:"POST",credentials:"include",headers:L,body:JSON.stringify({title:X.title,type:"Doc",format:"lake",book_id:Q,status:0})});let V=null;try{V=await A.json()}catch(z){}if(!A.ok||!V?.data?.id)return{ok:!1,stage:"create",status:A.status,message:V?.message||"创建语雀草稿文档失败"};const J=V.data.id,H="https://www.yuque.com/go/doc/"+J+"/edit";let F=X.content;const N=["yuque.com","cdn.nlark.com"],j=/!\[([^\]]*)\]\(\s*<?([^)\s>]+)>?\s*\)/g,O=[];let S;while((S=j.exec(F))!==null)O.push({full:S[0],alt:S[1],src:S[2]});const _=[],B=[],D="https://www.yuque.com/api/upload/attach?attachable_type=Doc&attachable_id="+J+"&type=image";for(let z=0;z<O.length;z++){const Y=O[z],Z=Y.src;if(!Z)continue;if(Z.indexOf("data:")===0)continue;if(N.some(function(M){return Z.indexOf(M)!==-1}))continue;try{const M=await fetch(Z,{credentials:"omit"});if(!M.ok)throw Error("图片下载失败 HTTP "+M.status);const I=await M.blob(),C=new FormData;C.append("file",I,"image.jpg");const T=await fetch(D,{method:"POST",credentials:"include",headers:{"x-csrf-token":$},body:C});let h=null;try{h=await T.json()}catch(u){}if(!T.ok||!h?.data?.url)throw Error(h&&h.message||"图片上传失败 HTTP "+T.status);const b=h.data.url;F=F.split(Y.full).join("");_.push({src:Z.slice(0,120),url:b})}catch(M){B.push({src:Z.slice(0,120),error:String(M&&M.message||M)})}}const P=await fetch("https://www.yuque.com/api/docs/convert",{method:"POST",credentials:"include",headers:L,body:JSON.stringify({from:"markdown",to:"lake",content:F})});let U=null;try{U=await P.json()}catch(z){}if(!P.ok||!U?.data?.content)return{ok:!1,stage:"convert",status:P.status,message:"内容格式转换失败(markdown→lake)",id:String(J),uploaded:_,failed:B};const E=U.data.content,v='<div class="lake-content" typography="traditional">'+E+"</div>",x=await fetch("https://www.yuque.com/api/docs/"+J+"/content",{method:"PUT",credentials:"include",headers:L,body:JSON.stringify({format:"lake",body_asl:E,body:v,body_html:v,draft_version:0,sync_dynamic_data:!1,save_type:"auto",edit_type:"Lake"})});if(!x.ok){let z="";try{z=await x.text()}catch(Y){}return{ok:!1,stage:"save",status:x.status,message:"保存正文失败:"+z.slice(0,300),id:String(J),uploaded:_,failed:B}}if(!X.draftOnly){const z=await fetch("https://www.yuque.com/api/docs/"+J+"/publish",{method:"PUT",credentials:"include",headers:L,body:JSON.stringify({status:1})});if(!z.ok){let Y="";try{Y=await z.text()}catch(Z){}return{ok:!1,stage:"publish",status:z.status,message:"发布失败:"+Y.slice(0,300),id:String(J),url:H,uploaded:_,failed:B}}}return{ok:!0,id:String(J),url:H,draft:Boolean(X.draftOnly),uploaded:_,failed:B}}};R({site:"yuque",name:"article",access:"write",description:"发布语雀文章(知识库文档)。正文默认为 Markdown,外链图片自动转存到语雀图床。",domain:"www.yuque.com",strategy:m.COOKIE,browser:!0,args:[{name:"title",positional:!0,required:!0,help:"文章标题"},{name:"text",positional:!0,help:"文章正文(Markdown 格式;或用 --file 读文件)"},{name:"file",help:"正文文件路径(UTF-8,Markdown 格式)"},{name:"html",type:"boolean",help:"把正文当 HTML 输入(语雀仍转 lake 发布)"},{name:"draft",type:"boolean",help:"仅保存草稿,不发布"},{name:"execute",type:"boolean",help:"实际执行写操作。不加此参数命令拒绝写入。"}],columns:["status","outcome","message","target_type","target","created_target","created_url"],func:async(X,K)=>{if(!X)throw new n("语雀文章发布需要浏览器会话");if(!K.execute)throw new W("INVALID_INPUT","此命令需要加 --execute 才会实际写入(防误操作)");const $=String(K.title??"").trim();if(!$)throw new W("INVALID_INPUT","文章标题不能为空");let L="";const q=typeof K.text==="string"?K.text:void 0,G=typeof K.file==="string"?K.file:void 0;if(q&&G)throw new W("INVALID_INPUT","正文和 --file 不能同时使用");if(G){const{readFile:F,stat:N}=await import("node:fs/promises");let j;try{j=await N(G)}catch{throw new W("INVALID_INPUT",`文件不存在:${G}`)}if(!j.isFile())throw new W("INVALID_INPUT",`路径不是文件:${G}`);let O;try{O=await F(G)}catch{throw new W("INVALID_INPUT",`文件无法读取:${G}`)}try{L=new TextDecoder("utf-8",{fatal:!0}).decode(O)}catch{throw new W("INVALID_INPUT",`文件无法以 UTF-8 解码:${G}`)}}else L=q??"";if(!L.trim())throw new W("INVALID_INPUT","正文不能为空");const y=Boolean(K.draft),Q=await w(X,{title:$,body:L,format:K.html?"html":"markdown",draftOnly:y,profile:yuqueProfile}),A=Q.images.uploaded.length|0,V=Q.images.failed.length|0;let J=Q.draft?"已保存语雀草稿":"语雀文章发布成功";if(A||V)J+=`(图片:${A} 张已转存${V?`,${V} 张失败`:""})`;return[{status:"success",outcome:Q.draft?"draft":"created",message:J,target_type:"article",target:"",created_target:"article:"+Q.id,created_url:Q.url}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as B,Strategy as C}from"@jackwener/opencli/registry";import{checkLogin as D}from"../_shared/article/auth.js";const yuqueAuthProfile={home:"https://www.yuque.com/dashboard",checkAuth:async(v)=>{const m=v.cookie("yuque_ctoken");if(!m)return{isAuthenticated:!1,error:"未检测到 yuque_ctoken cookie,请先登录语雀"};try{const b=await fetch("https://www.yuque.com/api/mine/common_used",{method:"GET",credentials:"include",headers:{"x-csrf-token":m}});if(!b.ok)return{isAuthenticated:!1,error:"接口返回 HTTP "+b.status};let x=null;try{x=await b.json()}catch(E){}if(!x?.data?.books?.length)return{isAuthenticated:!1,error:"未获取到语雀知识库信息"};const z=x.data.books[0].user;return{isAuthenticated:!0,userId:String(z.id),username:z.name,avatar:z.avatar_url||""}}catch(b){return{isAuthenticated:!1,error:String(b&&b.message||b)}}}};B({site:"yuque",name:"whoami",access:"read",description:"查看当前语雀登录账号信息。",domain:"www.yuque.com",strategy:C.COOKIE,browser:!0,columns:["logged_in","user_id","username"],func:async(v)=>{const m=await D(v,yuqueAuthProfile);return[{logged_in:m.isAuthenticated,user_id:m.userId||"",username:m.username||""}]}});export{yuqueAuthProfile};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{cli as S,Strategy as L}from"@jackwener/opencli/registry";import{ArgumentError as g,AuthRequiredError as N,CommandExecutionError as c,EmptyResultError as _}from"@jackwener/opencli/errors";import{stripHtml as T}from"./text.js";function E(e){return T(e,{preserveBlocks:!0})}const Z=/^\d+$/,C=/^answer:(\d+):(\d+)$/,I=/^\/question\/(\d+)\/answer\/(\d+)\/?$/,U=/^\/answer\/(\d+)\/?$/;function $(e){const n=String(e??"").trim();if(!n)return null;if(Z.test(n))return{answerId:n,questionId:""};const t=n.match(C);if(t)return{questionId:t[1],answerId:t[2]};try{const r=new URL(n);if(r.protocol!=="https:"||r.username||r.password||r.port||r.hostname!=="www.zhihu.com"&&r.hostname!=="zhihu.com")return null;let i=r.pathname.match(I);if(i)return{questionId:i[1],answerId:i[2]};i=r.pathname.match(U);if(i)return{answerId:i[1],questionId:""}}catch{return null}return null}function q(e){const n=String(e??"").trim();if(!n)return"";try{const t=new URL(n);if(t.protocol!=="https:"||t.hostname!=="www.zhihu.com"&&t.hostname!=="zhihu.com")return"";return t.pathname.match(I)?.[1]||""}catch{return""}}function x(e){return Number.isInteger(e)&&e>=0?e:0}function k(e){return typeof e==="number"&&Number.isFinite(e)&&e>0?new Date(e*1000).toISOString():""}function b(e){return e?.member?.name||e?.name||""}function v(e){if(typeof e==="string")return e.trim();if(typeof e==="number"&&Number.isSafeInteger(e)&&e>=0)return String(e);return""}function H(e,n,t,r){if(n&&t&&r)return`https://www.zhihu.com/question/${n}/answer/${t}#comment-${r}`;return typeof e==="string"?e:""}function R(e,n){if(typeof e!=="string"||!e)return"";try{const t=new URL(e),r=`/api/v4/answers/${n}/comments`,i=`/answers/${n}/comments`;if(t.protocol!=="https:"||t.username||t.password||t.port)return"";if(t.hostname==="www.zhihu.com"&&t.pathname===r)return t.toString();if(t.hostname==="api.zhihu.com"&&t.pathname===i)return`https://www.zhihu.com${r}${t.search}`}catch{return""}return""}function y(e,{answerId:n,questionId:t,topLevelLimit:r,repliesLimit:i}){const a=[];let w=0,l=0,u=0,f=!1,h=0;for(const s of e){if(!s||typeof s!=="object"||Array.isArray(s)){h+=1;continue}const o=v(s.id);if(!o){h+=1;continue}const d=b(s.author),p=b(s.reply_to_author),m=Boolean(p);if(!m){if(w>=r){f=!0;break}w+=1;l=w;u=0}else if(!l||u>=i)continue;else u+=1;a.push({rank:a.length+1,comment_rank:l,reply_rank:m?u:0,depth:0,id:o,parent_id:"",author:d||"anonymous",reply_to:p,likes:x(s.vote_count),created_at:k(s.created_time),url:H(s.url,t,n,o),content:E(s.content||"")})}return{rows:a,topLevelCount:w,reachedTopLevelLimit:f,malformedComments:h}}const A=1000,z=100,P=20;S({site:"zhihu",name:"answer-comments",access:"read",description:"知乎回答评论列表",domain:"www.zhihu.com",strategy:L.COOKIE,args:[{name:"id",required:!0,positional:!0,help:"Answer ID, full Zhihu answer URL, or typed target (answer:<qid>:<aid>)"},{name:"limit",type:"int",default:20,help:"Number of top-level comments (max 1000)"},{name:"replies-limit",type:"int",default:3,help:"Number of replies to include per top-level comment (max 100)"}],columns:["rank","comment_rank","reply_rank","depth","id","parent_id","author","reply_to","likes","created_at","url","content"],func:async(e,n)=>{const t=$(n.id);if(!t)throw new g("Answer ID must be a numeric id, a Zhihu answer URL, or answer:<qid>:<aid>","Example: opencli zhihu answer-comments 1937205528846655537");const r=Number(n.limit??20);if(!Number.isInteger(r)||r<=0||r>A)throw new g(`--limit must be a positive integer no greater than ${A}`);const i=Number(n["replies-limit"]??3);if(!Number.isInteger(i)||i<0||i>z)throw new g(`--replies-limit must be an integer between 0 and ${z}`);const{answerId:a}=t;try{await e.goto(`https://www.zhihu.com/answer/${a}`)}catch(o){throw new c(`Failed to open Zhihu answer ${a}: ${o instanceof Error?o.message:String(o)}`,"Open the answer URL in Chrome and retry after the page is reachable.")}const w=e.getCurrentUrl?q(await e.getCurrentUrl().catch(()=>"")):"",l=t.questionId||w;let u=`https://www.zhihu.com/api/v4/answers/${a}/comments?order=normal&limit=${P}&offset=0&status=open`;const f=[],h=new Set;while(u&&!h.has(u)){h.add(u);const o=await e.evaluate(`
|
|
2
|
+
(async () => {
|
|
3
|
+
const r = await fetch(${JSON.stringify(u)}, { credentials: 'include' });
|
|
4
|
+
if (!r.ok) return { __httpError: r.status };
|
|
5
|
+
try {
|
|
6
|
+
return await r.json();
|
|
7
|
+
} catch (error) {
|
|
8
|
+
return { __malformedJson: error instanceof Error ? error.message : String(error) };
|
|
9
|
+
}
|
|
10
|
+
})()
|
|
11
|
+
`).catch((m)=>{throw new c(`Zhihu answer comments request failed: ${m instanceof Error?m.message:String(m)}`,"Try again later or rerun with -v for more detail.")});if(!o||o.__httpError){const m=o?.__httpError;if(m===401||m===403)throw new N("www.zhihu.com","Failed to fetch Zhihu answer comments");if(m===404)throw new _("zhihu answer-comments",`No Zhihu answer comments resource was found for ${a}.`);throw new c(m?`Zhihu answer comments request failed (HTTP ${m})`:"Zhihu answer comments request failed","Try again later or rerun with -v for more detail")}if(o.__malformedJson)throw new c(`Zhihu answer comments returned malformed JSON: ${o.__malformedJson}`,"Try again later or rerun with -v for more detail");if(!Array.isArray(o.data)||!o.paging||typeof o.paging!=="object")throw new c("Zhihu answer comments returned a malformed payload","Try again later or rerun with -v for more detail");f.push(...o.data);const d=y(f,{answerId:a,questionId:l,topLevelLimit:r,repliesLimit:i});if(d.malformedComments>0)throw new c("Zhihu answer comments contained rows without comment ids");if(d.reachedTopLevelLimit||o.paging?.is_end){if(d.rows.length===0)throw new _("zhihu answer-comments",`No comments found for answer ${a}.`);return d.rows}const p=R(o.paging?.next,a);if(!p)throw new c("Zhihu answer comments pagination returned malformed next URL");if(h.has(p))throw new c("Zhihu answer comments pagination returned a repeated next URL");u=p}const s=y(f,{answerId:a,questionId:l,topLevelLimit:r,repliesLimit:i});if(s.malformedComments>0)throw new c("Zhihu answer comments contained rows without comment ids");if(s.rows.length===0)throw new _("zhihu answer-comments",`No comments found for answer ${a}.`);return s.rows}});export const __test__={stripHtml:E,parseAnswerTarget:$,normalizeCommentsApiUrl:R,buildRows:y};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{cli as y,Strategy as N}from"@jackwener/opencli/registry";import{ArgumentError as O,AuthRequiredError as P,CommandExecutionError as $,EmptyResultError as q}from"@jackwener/opencli/errors";import{stripHtml as H}from"./text.js";function j(G){return H(G,{preserveBlocks:!0})}const U=/^\d+$/,S=/^answer:(\d+):(\d+)$/,F=/^\/question\/(\d+)\/answer\/(\d+)\/?$/,T=/^\/answer\/(\d+)\/?$/,R=/^\/question\/(\d+)\/?$/,C=/^\/api\/v4\/questions\/(\d+)\/?$/;function D(G){const X=String(G??"").trim();if(!X)return null;if(U.test(X))return{answerId:X,questionId:""};const L=X.match(S);if(L)return{questionId:L[1],answerId:L[2]};try{const K=new URL(X);if(K.protocol!=="https:"||K.username||K.password||K.port||K.hostname!=="www.zhihu.com"&&K.hostname!=="zhihu.com")return null;let Z=K.pathname.match(F);if(Z)return{questionId:Z[1],answerId:Z[2]};Z=K.pathname.match(T);if(Z)return{answerId:Z[1],questionId:""}}catch{return null}return null}function _(G){return D(G)?.answerId??null}function M(G){const X=String(G??"").trim();if(!X)return"";try{const L=new URL(X);if(L.protocol!=="https:"||L.hostname!=="www.zhihu.com"&&L.hostname!=="zhihu.com")return"";return L.pathname.match(F)?.[1]||L.pathname.match(R)?.[1]||L.pathname.match(C)?.[1]||""}catch{return""}}function z(G){return Number.isInteger(G)&&G>=0?G:0}function h(G){return typeof G==="number"&&Number.isFinite(G)&&G>0?new Date(G*1000).toISOString():""}y({site:"zhihu",name:"answer-detail",access:"read",description:"知乎单个回答完整内容(按 answer ID 获取)",domain:"www.zhihu.com",strategy:N.COOKIE,args:[{name:"id",required:!0,positional:!0,help:"Answer ID, full Zhihu answer URL, or typed target (answer:<qid>:<aid>)"},{name:"max-content",type:"int",default:0,help:"Optional cap on stripped content length in characters (0 = no truncation, return the full answer)"}],columns:["id","author","votes","comments","question_id","question_title","url","created_at","updated_at","content"],func:async(G,X)=>{const L=D(X.id);if(!L)throw new O("Answer ID must be a numeric id, a Zhihu answer URL, or answer:<qid>:<aid>","Example: opencli zhihu answer-detail 1937205528846655537");const{answerId:K}=L,Z=X["max-content"],b=Z==null?0:Number(Z);if(!Number.isInteger(b)||b<0)throw new O("--max-content must be a non-negative integer (0 = no cap, full content)","Example: --max-content 2000");try{await G.goto(`https://www.zhihu.com/answer/${K}`)}catch(V){throw new $(`Failed to open Zhihu answer ${K}: ${V instanceof Error?V.message:String(V)}`,"Open the answer URL in Chrome and retry after the page is reachable.")}const W=G.getCurrentUrl?M(await G.getCurrentUrl().catch(()=>"")):"",k=`https://www.zhihu.com/api/v4/answers/${K}?include=content,voteup_count,comment_count,author,created_time,updated_time,question`,J=await G.evaluate(`
|
|
2
|
+
(async () => {
|
|
3
|
+
const r = await fetch(${JSON.stringify(k)}, { credentials: 'include' });
|
|
4
|
+
if (!r.ok) return { __httpError: r.status };
|
|
5
|
+
try {
|
|
6
|
+
return await r.json();
|
|
7
|
+
} catch (error) {
|
|
8
|
+
return { __malformedJson: error instanceof Error ? error.message : String(error) };
|
|
9
|
+
}
|
|
10
|
+
})()
|
|
11
|
+
`).catch((V)=>{throw new $(`Zhihu answer detail request failed: ${V instanceof Error?V.message:String(V)}`,"Try again later or rerun with -v for more detail.")});if(!J||J.__httpError){const V=J?.__httpError;if(V===401||V===403)throw new P("www.zhihu.com","Failed to fetch Zhihu answer detail");if(V===404)throw new q("zhihu answer-detail",`No Zhihu answer was found for ${K}.`);throw new $(V?`Zhihu answer detail request failed (HTTP ${V})`:"Zhihu answer detail request failed","Try again later or rerun with -v for more detail")}if(J.__malformedJson)throw new $(`Zhihu answer detail returned malformed JSON: ${J.__malformedJson}`,"Try again later or rerun with -v for more detail");if(typeof J!=="object"||Array.isArray(J))throw new $("Zhihu answer detail returned a malformed payload","Try again later or rerun with -v for more detail");if(J.error||J.error_msg||J.message)throw new $(`Zhihu answer detail returned an error payload: ${J.error?.message||J.error_msg||J.message}`,"Try again later or rerun with -v for more detail");if(!Object.prototype.hasOwnProperty.call(J,"content"))throw new $("Zhihu answer detail payload did not include answer content","Try again later or rerun with -v for more detail");const f=J.question||{},B=L.questionId||W||M(f.url)||(f.id==null?"":String(f.id)),Y=j(J.content||""),Q=b>0&&Y.length>b?Y.substring(0,b):Y;return[{id:K,author:J.author?.name||"anonymous",votes:z(J.voteup_count),comments:z(J.comment_count),question_id:B,question_title:f.title||"",url:B?`https://www.zhihu.com/question/${B}/answer/${K}`:`https://www.zhihu.com/answer/${K}`,created_at:h(J.created_time),updated_at:h(J.updated_time),content:Q}]}});export const __test__={stripHtml:j,extractAnswerId:_,parseAnswerTarget:D,extractQuestionIdFromAnswerUrl:M};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import{CliError as Q,CommandExecutionError as V}from"@jackwener/opencli/errors";import{cli as W,Strategy as X}from"@jackwener/opencli/registry";import{markdownToHtml as Y}from"../_shared/article/format.js";import{assertAllowedKinds as Z,parseTarget as $}from"./target.js";import{buildResultRow as b,requireExecute as f,resolveCurrentUserIdentity as q,resolvePayload as A}from"./write-shared.js";W({site:"zhihu",name:"answer",access:"write",description:"Answer a Zhihu question. Body is Markdown by default (paragraphs become <p>); pass --html for raw HTML.",domain:"www.zhihu.com",strategy:X.COOKIE,browser:!0,args:[{name:"target",positional:!0,required:!0,help:"Zhihu question URL (e.g. https://www.zhihu.com/question/461491497) or typed target question:461491497; bare numeric id is rejected"},{name:"text",positional:!0,help:"Answer body (Markdown by default; pass --html for raw HTML)"},{name:"file",help:"Answer body file path (UTF-8, Markdown by default)"},{name:"html",type:"boolean",help:"Treat body as raw HTML instead of Markdown"},{name:"execute",type:"boolean",help:"Actually perform the write action"}],columns:["status","outcome","message","target_type","target","created_target","created_url","author_identity"],func:async(z,D)=>{if(!z)throw new V("Browser session required for zhihu answer");f(D);const G=String(D.target),B=Z("answer",$(G)),J=await A(D),N=D.html?J:Y(J);await z.goto(B.url);await z.wait(3);const O=await q(z),F=await z.evaluate(`(async () => {
|
|
2
|
+
var questionId = ${JSON.stringify(B.id)};
|
|
3
|
+
var content = ${JSON.stringify(N)};
|
|
4
|
+
var url = 'https://www.zhihu.com/api/v4/questions/' + questionId + '/answers';
|
|
5
|
+
var resp = await fetch(url, {
|
|
6
|
+
method: 'POST',
|
|
7
|
+
credentials: 'include',
|
|
8
|
+
headers: { 'Content-Type': 'application/json' },
|
|
9
|
+
body: JSON.stringify({ content: content, reshipment_settings: 'disallowed' }),
|
|
10
|
+
});
|
|
11
|
+
var data = await resp.json();
|
|
12
|
+
if (!resp.ok) return { ok: false, status: resp.status, message: data.error ? data.error.message : 'unknown error' };
|
|
13
|
+
if (!data || !data.id) return { ok: false, status: resp.status, message: 'Answer API response did not include a created answer id' };
|
|
14
|
+
return { ok: true, id: String(data.id), url: data.url || ('https://www.zhihu.com/question/' + questionId + '/answer/' + data.id) };
|
|
15
|
+
})()`);if(!F?.ok)throw new Q("COMMAND_EXEC",F?.message||"Failed to create answer");return b(`Answered question ${B.id}`,B.kind,G,"created",{created_target:"answer:"+B.id+":"+F.id,created_url:F.url,author_identity:O})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function transformTables(A){let g=A.replace(/<figure[^>]*>\s*(<table[\s\S]*?<\/table>)\s*<\/figure>/gi,"$1");g=g.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi,(E,q)=>{const v=q.match(/<thead[^>]*>([\s\S]*?)<\/thead>/i),x=q.match(/<tbody[^>]*>([\s\S]*?)<\/tbody>/i);let B="",j="";if(v)B=v[1].replace(/<td([^>]*)>/gi,"<th$1>").replace(/<\/td>/gi,"</th>");if(x)j=x[1];else j=q.replace(/<thead[^>]*>[\s\S]*?<\/thead>/gi,"").replace(/<\/?tbody[^>]*>/gi,"");if(!v){const z=j.match(/<tr[^>]*>([\s\S]*?)<\/tr>/i);if(z){const D=z[1];if(/<th[^>]*>/i.test(D)&&!/<td[^>]*>/i.test(D)){B=z[0];j=j.replace(z[0],"")}}}return`<table data-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal"><tbody>${B}${j}</tbody></table>`});return g}export function transformZhihuHtml(A){let g=A;g=transformTables(g);g=g.replace(/<img([^>]+)src="([^"]+)"([^>]*?)\/?>/gi,(E,q,v,x)=>`<figure><img${q}src="${v}"${x}></figure>`);g=g.replace(/<figure>\s*(<figure>[\s\S]*?<\/figure>)\s*<\/figure>/gi,"$1");g=g.replace(/<pre><code class="language-(\w+)">/gi,'<pre lang="$1"><code>');g=g.replace(/\s*data-(?!draft)[a-z-]+="[^"]*"/gi,"");g=g.replace(/\s*style="[^"]*"/gi,"");return g}export const __test__={transformTables,transformZhihuHtml};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{CliError as H,CommandExecutionError as m}from"@jackwener/opencli/errors";import{cli as v,Strategy as R}from"@jackwener/opencli/registry";import{buildResultRow as h,requireExecute as f,resolvePayload as T}from"./write-shared.js";import{publishArticle as x}from"../_shared/article/publish.js";export const zhihuProfile={home:"https://zhuanlan.zhihu.com",outputFormat:"html",preprocessConfig:{removeSpecialTags:!0,removeSpecialTagsWithParent:!0,processCodeBlocks:!0,convertSectionToDiv:!0,removeTrailingBr:!0,unwrapSingleChildContainers:!0,unwrapNestedFigures:!0,compactHtml:!0,removeEmptyLines:!0,removeEmptyDivs:!0,removeNestedEmptyContainers:!0},image:{skip:["zhimg.com"],uploadFn:async(J,M)=>{if(J.indexOf("data:")!==0){const V=await fetch("https://zhuanlan.zhihu.com/api/uploaded_images",{method:"POST",credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded","x-requested-with":"fetch","x-xsrftoken":M.xsrf()},body:new URLSearchParams({url:J,source:"article"})}),S=await V.text();let $=null;try{$=JSON.parse(S)}catch(N){}if(!V.ok||!$||!$.src)throw Error("URL 转存失败: HTTP "+V.status+" "+S.slice(0,150));return{url:$.src}}const W=M.dataUriToBlob(J),Z=await W.arrayBuffer(),O=M.md5(Z),Y=await fetch("https://api.zhihu.com/images",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json","x-requested-with":"fetch"},body:JSON.stringify({image_hash:O,source:"article"})}),L=await Y.text();let U=null;try{U=JSON.parse(L)}catch(V){}if(!Y.ok||!U||!U.upload_file)throw Error("获取上传凭证失败: HTTP "+Y.status+" "+L.slice(0,150));const Q=U.upload_file;if(Q.state===1){for(let V=0;V<10;V++){const $=await(await fetch("https://api.zhihu.com/images/"+Q.image_id,{credentials:"include",headers:{"x-requested-with":"fetch"}})).json();if($&&($.status==="completed"||$.original_hash))return{url:"https://pic4.zhimg.com/"+$.original_hash};await new Promise((N)=>setTimeout(N,1000))}throw Error("图片处理超时(image_id="+Q.image_id+")")}const G=U.upload_token;if(!G||!G.access_id||!G.access_key||!G.access_token)throw Error("上传凭证响应无效: "+L.slice(0,150));const X=W.type||"application/octet-stream",q=new Date().toUTCString(),A={"x-oss-date":q,"x-oss-security-token":G.access_token,"x-oss-user-agent":"aliyun-sdk-js/6.8.0"},_=Object.keys(A).sort().map((V)=>V+":"+A[V]).join(`
|
|
2
|
+
`),B=`PUT
|
|
3
|
+
|
|
4
|
+
`+X+`
|
|
5
|
+
`+q+`
|
|
6
|
+
`+_+`
|
|
7
|
+
/zhihu-pics/`+Q.object_key,z=new TextEncoder().encode(G.access_key),C=await crypto.subtle.importKey("raw",z,{name:"HMAC",hash:"SHA-1"},!1,["sign"]),F=await crypto.subtle.sign("HMAC",C,new TextEncoder().encode(B)),j=btoa(String.fromCharCode.apply(null,Array.from(new Uint8Array(F)))),E=await fetch("https://zhihu-pics-upload.zhimg.com/"+Q.object_key,{method:"PUT",headers:{"Content-Type":X,Authorization:"OSS "+G.access_id+":"+j,"x-oss-date":q,"x-oss-security-token":G.access_token,"x-oss-user-agent":"aliyun-sdk-js/6.8.0"},body:W});if(!E.ok){const V=await E.text();throw Error("OSS 上传失败: HTTP "+E.status+" "+V.slice(0,150))}let K=Q.object_key;if(W.type==="image/gif")K=K+".gif";return{url:"https://pic4.zhimg.com/"+K}}},publish:async(J,M)=>{let W=J.content;W=W.replace(/<img([^>]+?)\/?>/gi,"<figure><img$1></figure>");const Z=J.params&&typeof J.params.cover==="string"?J.params.cover.trim():"";if(Z&&Z.indexOf("zhimg.com")===-1)return{ok:!1,stage:"cover",message:"题图必须是知乎图床(zhimg.com)地址,转存未生效:"+Z.slice(0,120)};const Y={"Content-Type":"application/json","x-requested-with":"fetch","x-xsrftoken":M.xsrf()},L="https://zhuanlan.zhihu.com/api/articles",U=await fetch(L+"/drafts",{method:"POST",credentials:"include",headers:Y,body:JSON.stringify({title:J.title})}),Q=await U.text();let G=null;try{G=JSON.parse(Q)}catch(C){}if(!U.ok||!G||!G.id)return{ok:!1,stage:"create",status:U.status,message:Q.slice(0,300)};const X=String(G.id),q={title:J.title,content:W,table_of_contents:!1,delta_time:30};if(Z){q.titleImage=Z;q.isTitleImageFullScreen=!1}const A=await fetch(L+"/"+X+"/draft",{method:"PATCH",credentials:"include",headers:Y,body:JSON.stringify(q)});if(!A.ok){const C=await A.text();return{ok:!1,stage:"update",status:A.status,message:C.slice(0,300),id:X}}if(J.draftOnly)return{ok:!0,draft:!0,id:X,url:"https://zhuanlan.zhihu.com/p/"+X+"/edit"};const _=await fetch(L+"/"+X+"/publish",{method:"PUT",credentials:"include",headers:Y,body:JSON.stringify({})}),B=await _.text();let z=null;try{z=JSON.parse(B)}catch(C){}if(!_.ok)return{ok:!1,stage:"publish",status:_.status,message:B.slice(0,300),id:X};return{ok:!0,draft:!1,id:X,url:z&&z.url||"https://zhuanlan.zhihu.com/p/"+X}}};v({site:"zhihu",name:"article",access:"write",description:"Publish a Zhihu article (文章/专栏). Body is Markdown by default; images (incl. local paths) and --cover are auto-rehosted to Zhihu.",domain:"zhuanlan.zhihu.com",strategy:R.COOKIE,browser:!0,args:[{name:"title",positional:!0,required:!0,help:"Article title"},{name:"text",positional:!0,help:"Article body (Markdown by default; pass --html for raw HTML)"},{name:"file",help:"Article body file path (UTF-8, Markdown by default)"},{name:"html",type:"boolean",help:"Treat body as raw HTML instead of Markdown"},{name:"cover",help:"Cover image (题图): local file path or image URL; auto-rehosted to Zhihu (zhimg.com)"},{name:"draft",type:"boolean",help:"Save as draft only; do not publish"},{name:"execute",type:"boolean",help:"Actually create/publish. Without it the command refuses to write."}],columns:["status","outcome","message","target_type","target","created_target","created_url"],func:async(J,M)=>{if(!J)throw new m("Browser session required for zhihu article");f(M);const W=String(M.title??"").trim();if(!W)throw new H("INVALID_INPUT","Article title cannot be empty");const Z=await T(M),O=Boolean(M.draft),Y=typeof M.cover==="string"?M.cover.trim():"",L=await x(J,{title:W,body:Z,format:M.html?"html":"markdown",draftOnly:O,profile:zhihuProfile,publishParams:Y?{cover:Y}:null}),U=L.images.uploaded.length|0,Q=L.images.failed.length|0;let G=L.draft?"Saved article draft":"Published article";if(U||Q)G+=` · images: ${U} rehosted${Q?`, ${Q} failed`:""}`;return h(G,"article","",L.draft?"draft":"created",{created_target:"article:"+L.id,created_url:L.url})}});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{AuthRequiredError as F,CommandExecutionError as H}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as L}from"../_shared/site-auth.js";async function G(B){return(await B.getCookies({url:"https://www.zhihu.com"})).some((D)=>D.name==="z_c0"&&D.value)}async function J(B){await B.goto("https://www.zhihu.com/");await B.wait(2);return B.evaluate(`
|
|
2
|
+
(async () => {
|
|
3
|
+
try {
|
|
4
|
+
const r = await fetch('https://www.zhihu.com/api/v4/me?include=url_token', { credentials: 'include' });
|
|
5
|
+
if (!r.ok) return { __httpError: r.status };
|
|
6
|
+
return await r.json();
|
|
7
|
+
} catch (e) {
|
|
8
|
+
return { __exception: String(e && e.message || e) };
|
|
9
|
+
}
|
|
10
|
+
})()
|
|
11
|
+
`)}async function K(B){if(!await G(B))throw new F("www.zhihu.com","Zhihu z_c0 cookie missing — anonymous");let z=await J(B);if(z&&(z.__httpError===401||z.__httpError===403)){await B.wait(2);z=await J(B)}if(z?.__exception)throw new H(`Zhihu whoami failed: ${z.__exception}`);if(!z||z.__httpError){const D=z?.__httpError;if(D===401||D===403)throw new F("www.zhihu.com",`Zhihu /api/v4/me returned HTTP ${D} — anonymous`);throw new H(`Zhihu identity probe failed (HTTP ${D??"unknown"})`)}if(!z.url_token)throw new F("www.zhihu.com","Zhihu /api/v4/me returned no url_token — anonymous session");return{url_token:String(z.url_token),name:String(z.name??""),uid:String(z.uid??z.id??"")}}L({site:"zhihu",domain:"www.zhihu.com",loginUrl:"https://www.zhihu.com/signin",columns:["url_token","name","uid"],quickCheck:G,verify:K,poll:async(B)=>{if(!await G(B))throw new F("www.zhihu.com","Waiting for Zhihu z_c0 cookie");return K(B)}});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{cli as y,Strategy as I}from"@jackwener/opencli/registry";import{ArgumentError as R,AuthRequiredError as L,CommandExecutionError as j,EmptyResultError as v}from"@jackwener/opencli/errors";import{log as w}from"@jackwener/opencli/logger";import{stripHtml as _}from"./text.js";function H(M,D){const z=Number(M);if(!Number.isInteger(z)||z<=0)throw new R(`zhihu collection --${D} must be a positive integer`,"Example: opencli zhihu collection 83283292 --limit 20");return z}function C(M,D){const z=Number(M);if(!Number.isInteger(z)||z<0)throw new R(`zhihu collection --${D} must be a non-negative integer`,"Example: opencli zhihu collection 83283292 --offset 0");return z}async function O(M,D,z,T){const V=`https://www.zhihu.com/api/v4/collections/${D}/items?offset=${z}&limit=${T}`,G=await M.evaluate(`
|
|
2
|
+
(async () => {
|
|
3
|
+
const r = await fetch(${JSON.stringify(V)}, { credentials: 'include' });
|
|
4
|
+
if (!r.ok) return { __httpError: r.status };
|
|
5
|
+
return await r.json();
|
|
6
|
+
})()
|
|
7
|
+
`);if(!G||G.__httpError){const B=G?.__httpError;if(B===401||B===403)throw new L("www.zhihu.com","Failed to fetch collection data from Zhihu. Please ensure you are logged in.");throw new j(B?`Zhihu collection request failed (HTTP ${B})`:"Zhihu collection request failed","Try again later or rerun with -v for more detail")}return G}function P(M){const D=M?.content||{};return`${D.type||""}:${D.id||D.url||JSON.stringify(D).slice(0,80)}`}function h(M,D){const z=M.content||{},T=z.type||"";if(!["answer","article","pin"].includes(T))throw new j(`Zhihu collection returned unsupported content type: ${T||"missing"}`,"Collection items require a supported content.type so the row identity, title, and URL are not silently blank.");let V="",G="",B="",Q="",W=0;if(T==="answer"){const J=z.question||{};V=J.title||"";G=_(z.content||"").substring(0,150);B=z.url||`https://www.zhihu.com/question/${J.id}/answer/${z.id}`;Q=z.author?.name||"匿名用户";W=z.voteup_count||0}else if(T==="article"){V=z.title||"";G=_(z.content||"").substring(0,150);B=z.url||`https://zhuanlan.zhihu.com/p/${z.id}`;Q=z.author?.name||"匿名用户";W=z.voteup_count||0}else if(T==="pin"){V="想法";G=_((z.content||[]).map((J)=>J.content||"").join(" ")).substring(0,150);B=z.url||`https://www.zhihu.com/pin/${z.id}`;Q=z.author?.name||"匿名用户";W=z.reaction_count||0}if(!String(V||"").trim()||!String(B||"").trim()||B.includes("undefined"))throw new j("Zhihu collection returned a malformed item without title or URL identity","Collection item rows require type, title, and URL so malformed payloads do not become blank listing rows.");return{rank:D,type:T,title:_(V).substring(0,100),author:Q,votes:W,excerpt:G,url:B}}y({site:"zhihu",name:"collection",access:"read",description:"知乎收藏夹内容列表(需要登录)",domain:"www.zhihu.com",strategy:I.COOKIE,browser:!0,args:[{name:"id",positional:!0,required:!0,help:"收藏夹 ID (数字,可从收藏夹 URL 中获取)"},{name:"offset",type:"int",default:0,help:"起始偏移量(用于分页)"},{name:"limit",type:"int",default:20,help:"每页数量(最大 20)"}],columns:["rank","type","title","author","votes","excerpt","url"],func:async(M,D)=>{const{id:z,offset:T=0,limit:V=20}=D,G=String(z);if(!/^\d+$/.test(G))throw new R("Collection ID must be numeric","Example: opencli zhihu collection 83283292");const B=C(T,"offset"),Q=H(V,"limit"),W=Math.min(Q,20);await M.goto("https://www.zhihu.com");const J=[],A=new Set;let X=0,Y=B;const q=Math.ceil(Q/W)+2;for(let $=0;$<q&&J.length<Q;$+=1){const S=Math.min(W,Q-J.length),K=await O(M,G,Y,S),U=Array.isArray(K.data)?K.data:[],b=K.paging||{};X=Number(b.totals||X||0);for(const F of U){const Z=P(F);if(!A.has(Z)){A.add(Z);J.push(F)}if(J.length>=Q)break}if(U.length===0||b.is_end||J.length>=Q)break;if(typeof b.next==="string")try{const F=new URL(b.next),Z=Number(F.searchParams.get("offset"));if(Number.isInteger(Z)&&Z>Y){Y=Z;continue}}catch{}if(U.length<S)break;const N=Y+U.length;if(N<=Y)break;Y=N;if(X&&Y>=X)break}const k=Math.ceil(X/W),E=Math.floor(B/W)+1;if(X>0){w.info(`收藏夹共有 ${X} 条内容,共 ${k} 页`);w.info(`当前第 ${E} 页,显示第 ${B+1} - ${Math.min(B+J.length,X)} 条`)}if(J.length===0)throw new v("zhihu collection",`No items found for collection ${G}. The collection may be empty, private, or the offset may be out of range.`);return J.slice(0,Q).map(($,S)=>h($,B+S+1))}});export const __test__={stripHtml:_,validatePositiveInt:H,validateNonNegativeInt:C,itemKey:P,mapCollectionItem:h};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{cli as P,Strategy as I}from"@jackwener/opencli/registry";import{ArgumentError as h,AuthRequiredError as w,CommandExecutionError as F,EmptyResultError as O}from"@jackwener/opencli/errors";import{log as v}from"@jackwener/opencli/logger";function J(B,V){const D=Number(B);if(!Number.isInteger(D)||D<=0)throw new h(`zhihu collections --${V} must be a positive integer`,"Example: opencli zhihu collections --limit 20");return D}async function K(B,V,D){const z=await B.evaluate(`
|
|
2
|
+
(async () => {
|
|
3
|
+
const r = await fetch(${JSON.stringify(V)}, { credentials: 'include' });
|
|
4
|
+
if (!r.ok) return { __httpError: r.status };
|
|
5
|
+
return await r.json();
|
|
6
|
+
})()
|
|
7
|
+
`);if(!z||z.__httpError){const W=z?.__httpError;if(W===401||W===403)throw new w("www.zhihu.com",`${D} from Zhihu failed. Please ensure you are logged in.`);throw new F(W?`${D} from Zhihu failed (HTTP ${W})`:`${D} from Zhihu failed`,"Try again later or rerun with -v for more detail")}return z}function R(B){return String(B?.id||B?.url||B?.title||"")}P({site:"zhihu",name:"collections",access:"read",description:"知乎收藏夹列表(需要登录)",domain:"www.zhihu.com",strategy:I.COOKIE,browser:!0,args:[{name:"limit",type:"int",default:20,help:"每页数量(最大 20)"}],columns:["rank","title","item_count","description","collection_id"],func:async(B,V)=>{const{limit:D=20}=V,z=J(D,"limit");await B.goto("https://www.zhihu.com");const U=(await K(B,"https://www.zhihu.com/api/v4/me?include=url_token","Zhihu user info request")).url_token;if(!U)throw new F("Failed to get user url_token from Zhihu","Please ensure you are logged in.");const H=[],_=new Set;let Q=0,M=0;const A=Math.min(z,20),T=Math.ceil(z/A)+2;for(let G=0;G<T&&H.length<z;G+=1){const X=Math.min(A,z-H.length),j=`https://www.zhihu.com/api/v4/people/${U}/collections?include=data%5B*%5D.updated_time&offset=${M}&limit=${X}`,S=await K(B,j,"Zhihu favorite collections request"),Y=Array.isArray(S.data)?S.data:[],Z=S.paging||{};Q=Number(Z.totals||Q||0);for(const $ of Y){const N=R($);if(N&&!_.has(N)){_.add(N);H.push($)}if(H.length>=z)break}if(Y.length===0||Z.is_end||H.length>=z)break;if(typeof Z.next==="string")try{const $=new URL(Z.next),N=Number($.searchParams.get("offset"));if(Number.isInteger(N)&&N>M){M=N;continue}}catch{}if(Y.length<X)break;const C=M+Y.length;if(C<=M)break;M=C;if(Q&&M>=Q)break}if(Q>0)v.info(`共有 ${Q} 个收藏夹`);if(H.length===0)throw new O("zhihu collections","No favorite collections were returned for the logged-in user.");return H.slice(0,z).map((G,X)=>({rank:X+1,title:G.title||"未命名",item_count:G.item_count??G.answer_count??0,description:G.description||"",collection_id:String(G.id||"")}))}});export const __test__={validatePositiveInt:J,collectionKey:R};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import{CliError as s,CommandExecutionError as u}from"@jackwener/opencli/errors";import{cli as d,Strategy as m}from"@jackwener/opencli/registry";import{assertAllowedKinds as c,parseTarget as l}from"./target.js";import{buildResultRow as p,requireExecute as h,resolveCurrentUserIdentity as w,resolvePayload as y}from"./write-shared.js";d({site:"zhihu",name:"comment",access:"write",description:"Create a top-level comment on a Zhihu answer or article",domain:"zhihu.com",strategy:m.COOKIE,browser:!0,args:[{name:"target",positional:!0,required:!0,help:"Zhihu target URL or typed target"},{name:"text",positional:!0,help:"Comment text"},{name:"file",help:"Comment text file path"},{name:"execute",type:"boolean",help:"Actually perform the write action"}],columns:["status","outcome","message","target_type","target","author_identity","created_url"],func:async(e,r)=>{if(!e)throw new u("Browser session required for zhihu comment");h(r);const o=String(r.target),t=c("comment",l(o)),i=await y(r);await e.goto(t.url);await e.wait(3);const n=await w(e),a=await e.evaluate(`(async () => {
|
|
2
|
+
var targetKind = ${JSON.stringify(t.kind)};
|
|
3
|
+
var targetId = ${JSON.stringify(t.id)};
|
|
4
|
+
var content = ${JSON.stringify(i)};
|
|
5
|
+
var resourceType = targetKind === 'answer' ? 'answers' : 'articles';
|
|
6
|
+
var url = 'https://www.zhihu.com/api/v4/' + resourceType + '/' + targetId + '/comments';
|
|
7
|
+
var resp = await fetch(url, {
|
|
8
|
+
method: 'POST',
|
|
9
|
+
credentials: 'include',
|
|
10
|
+
headers: { 'Content-Type': 'application/json' },
|
|
11
|
+
body: JSON.stringify({ content: content }),
|
|
12
|
+
});
|
|
13
|
+
var data = await resp.json();
|
|
14
|
+
if (!resp.ok) return { ok: false, status: resp.status, message: data.error ? data.error.message : 'unknown error' };
|
|
15
|
+
if (!data || !data.id) return { ok: false, status: resp.status, message: 'Comment API response did not include a created comment id' };
|
|
16
|
+
return { ok: true, id: data.id, url: data.url };
|
|
17
|
+
})()`);if(!a?.ok)throw new s("COMMAND_EXEC",a?.message||"Failed to create comment");return p(`Commented on ${t.kind} ${t.id}`,t.kind,o,"created",{author_identity:n,created_url:a.url||""})}});
|