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,68 @@
|
|
|
1
|
+
import{AuthRequiredError as Q,CommandExecutionError as M}from"@jackwener/opencli/errors";export const GW_BASE="https://gw-c.nowcoder.com/api/sparta",WWW_BASE="https://www.nowcoder.com";export async function getJson(z,F){const H=JSON.stringify(F);return z.evaluate(`
|
|
2
|
+
async () => {
|
|
3
|
+
const res = await fetch(${H}, { credentials: 'include' });
|
|
4
|
+
const text = await res.text();
|
|
5
|
+
try {
|
|
6
|
+
return JSON.parse(text);
|
|
7
|
+
} catch {
|
|
8
|
+
return { code: -1, msg: '非 JSON 响应 (HTTP ' + res.status + '): ' + text.slice(0, 200) };
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
`)}export async function postJson(z,F,H){const K=JSON.stringify(F),L=JSON.stringify(JSON.stringify(H));return z.evaluate(`
|
|
12
|
+
async () => {
|
|
13
|
+
const res = await fetch(${K}, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
credentials: 'include',
|
|
16
|
+
headers: { 'Content-Type': 'application/json' },
|
|
17
|
+
body: ${L},
|
|
18
|
+
});
|
|
19
|
+
const text = await res.text();
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(text);
|
|
22
|
+
} catch {
|
|
23
|
+
return { code: -1, msg: '非 JSON 响应 (HTTP ' + res.status + '): ' + text.slice(0, 200) };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
`)}export async function postForm(z,F,H){const K=JSON.stringify(F),L=JSON.stringify(H);return z.evaluate(`
|
|
27
|
+
async () => {
|
|
28
|
+
const body = new URLSearchParams(${L});
|
|
29
|
+
const res = await fetch(${K}, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
credentials: 'include',
|
|
32
|
+
headers: {
|
|
33
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
34
|
+
'x-requested-with': 'XMLHttpRequest',
|
|
35
|
+
},
|
|
36
|
+
body: body.toString(),
|
|
37
|
+
});
|
|
38
|
+
const text = await res.text();
|
|
39
|
+
try {
|
|
40
|
+
return JSON.parse(text);
|
|
41
|
+
} catch {
|
|
42
|
+
return { code: -1, msg: '非 JSON 响应 (HTTP ' + res.status + '): ' + text.slice(0, 200) };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
`)}export async function postMultipart(z,F,H){const K=JSON.stringify(F),L=JSON.stringify(H);return z.evaluate(`
|
|
46
|
+
async () => {
|
|
47
|
+
const fd = new FormData();
|
|
48
|
+
for (const [k, v] of Object.entries(${L})) fd.append(k, v);
|
|
49
|
+
const res = await fetch(${K}, {
|
|
50
|
+
method: 'POST',
|
|
51
|
+
credentials: 'include',
|
|
52
|
+
body: fd,
|
|
53
|
+
});
|
|
54
|
+
const text = await res.text();
|
|
55
|
+
try {
|
|
56
|
+
return JSON.parse(text);
|
|
57
|
+
} catch {
|
|
58
|
+
return { code: -1, msg: '非 JSON 响应 (HTTP ' + res.status + '): ' + text.slice(0, 200) };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
`)}export function requireOk(z,F){if(!z||typeof z!=="object"||Array.isArray(z))throw new M(`牛客 ${F} 接口返回了畸形响应`);if(Object.hasOwn(z,"success")?!!z.success:Object.hasOwn(z,"code")?z.code===0:Object.hasOwn(z,"data"))return z;const K=String(z.msg??z.message??"未知错误");if(/登录|登陆|未授权|token|身份/i.test(K))throw new Q("nowcoder.com",`牛客 ${F} 需要登录: ${K}`);throw new M(`牛客 ${F} 失败: ${K} (code=${z.code??"?"})`)}export async function resolveMomentId(z,F){let H=String(F??"").trim();for(const T of[/detail\/([0-9a-fA-F]{20,})/,/discuss\/(\d+)/]){const P=H.match(T);if(P){H=P[1];break}}if(/^\d+$/.test(H))return H;if(!/^[0-9a-fA-F]{20,}$/.test(H))throw new M(`无法从输入解析牛客帖子 id: ${F}`);const L=requireOk(await getJson(z,`${GW_BASE}/detail/moment-data/detail/${H}`),"帖子解析").data?.id;if(!L)throw new M(`牛客帖子 ${H} 的详情缺少数字 momentId`);return String(L)}export async function getSelfUid(z){const F=await z.evaluate(`
|
|
62
|
+
async () => {
|
|
63
|
+
const link = document.querySelector('a[href*="/users/"]');
|
|
64
|
+
const href = link ? (link.getAttribute('href') || '') : '';
|
|
65
|
+
const match = href.match(/\\/users\\/(\\d+)/);
|
|
66
|
+
return match ? match[1] : '';
|
|
67
|
+
}
|
|
68
|
+
`);if(!F)throw new Q("nowcoder.com","导航栏无登录用户链接(未登录)");return F}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as i,Strategy as m}from"@jackwener/opencli/registry";import{ArgumentError as d,EmptyResultError as p}from"@jackwener/opencli/errors";import{NPM_API as w,npmFetch as c,requirePackageName as Y}from"./utils.js";const g=new Set(["last-day","last-week","last-month","last-year"]),u=/^(\d{4}-\d{2}-\d{2}):(\d{4}-\d{2}-\d{2})$/;function y(e){const a=String(e??"last-week").trim();if(g.has(a))return a;const n=u.exec(a);if(n){const[,t,o]=n;if(new Date(t)>new Date(o))throw new d(`npm downloads period start ${t} is after end ${o}`);return`${t}:${o}`}throw new d(`npm downloads period "${e}" is invalid`,"Use last-day / last-week (default) / last-month / last-year, or YYYY-MM-DD:YYYY-MM-DD.")}i({site:"npm",name:"downloads",access:"read",description:"Daily download counts for an npm package over a window",domain:"api.npmjs.org",strategy:m.PUBLIC,browser:!1,args:[{name:"name",positional:!0,required:!0,help:'npm package name (e.g. "react", "@vercel/og")'},{name:"period",default:"last-week",help:"last-day / last-week / last-month / last-year, or YYYY-MM-DD:YYYY-MM-DD"}],columns:["rank","package","day","downloads"],func:async(e)=>{const a=Y(e.name),n=y(e.period),t=`${w}/downloads/range/${n}/${a}`,o=await c(t,`npm downloads ${a}`),s=Array.isArray(o?.downloads)?o.downloads:[];if(!s.length)throw new p("npm downloads",`npm has no download stats for "${a}" in window ${n}.`);return s.map((r,l)=>({rank:l+1,package:String(o.package??a),day:String(r.day??""),downloads:r.downloads!=null?Number(r.downloads):null}))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as p,Strategy as m}from"@jackwener/opencli/registry";import{EmptyResultError as c}from"@jackwener/opencli/errors";import{NPM_REGISTRY as l,npmFetch as g,requirePackageName as d}from"./utils.js";function f(e){if(!e)return"";if(typeof e==="string")return e;if(typeof e==="object"&&typeof e.url==="string")return e.url.replace(/^git\+/,"").replace(/\.git$/,"");return""}function y(e){if(!e)return"";if(typeof e==="string")return e;if(typeof e==="object"&&typeof e.url==="string")return e.url;return""}p({site:"npm",name:"package",access:"read",description:"Single npm package metadata (latest version, license, homepage, repository). Use `npm downloads` for stats.",domain:"registry.npmjs.org",strategy:m.PUBLIC,browser:!1,args:[{name:"name",positional:!0,required:!0,help:'npm package name (e.g. "react", "@vercel/og")'}],columns:["name","latestVersion","description","license","homepage","repository","bugs","maintainers","keywords","created","modified","url"],func:async(e)=>{const n=d(e.name),r=await g(`${l}/${n.split("/").map(encodeURIComponent).join("/")}`,`npm package ${n}`),a=r?.["dist-tags"]?.latest;if(!a)throw new c("npm package",`npm registry has no latest version for "${n}".`);const t=r?.versions?.[a]??{},s=Array.isArray(r.maintainers)?r.maintainers.map((i)=>typeof i==="object"&&i?i.name||i.email||"":String(i)).filter(Boolean).join(", "):"",o=Array.isArray(t.keywords)?t.keywords.join(", "):"";return[{name:String(r.name??n),latestVersion:String(a),description:String(t.description??r.description??""),license:typeof t.license==="string"?t.license:t.license?.type??"",homepage:String(t.homepage??""),repository:f(t.repository),bugs:y(t.bugs),maintainers:s,keywords:o,created:String(r.time?.created??"").slice(0,10),modified:String(r.time?.modified??"").slice(0,10),url:`https://www.npmjs.com/package/${n}`}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as c,Strategy as d}from"@jackwener/opencli/registry";import{EmptyResultError as m}from"@jackwener/opencli/errors";import{NPM_REGISTRY as u,npmFetch as y,requireBoundedInt as g,requireString as h}from"./utils.js";c({site:"npm",name:"search",access:"read",description:"Search the public npm registry by keyword",domain:"registry.npmjs.org",strategy:d.PUBLIC,browser:!1,args:[{name:"query",positional:!0,required:!0,help:'Search keyword (e.g. "react", "graphql client")'},{name:"limit",type:"int",default:20,help:"Max results (1-250)"}],columns:["rank","name","version","description","weeklyDownloads","dependents","license","publisher","updated","url"],func:async(r)=>{const t=h(r.query,"query"),s=g(r.limit,20,250),p=`${u}/-/v1/search?text=${encodeURIComponent(t)}&size=${s}`,i=await y(p,"npm search"),a=Array.isArray(i?.objects)?i.objects:[];if(!a.length)throw new m("npm search",`No npm packages matched "${t}".`);return a.slice(0,s).map((n,l)=>{const e=n?.package??{},o=n?.downloads??{};return{rank:l+1,name:String(e.name??""),version:String(e.version??""),description:String(e.description??""),weeklyDownloads:o.weekly!=null?Number(o.weekly):null,dependents:n.dependents!=null?Number(n.dependents):null,license:String(e.license??""),publisher:String(e.publisher?.username??""),updated:String(n.updated??"").slice(0,10),url:e.links?.npm?String(e.links.npm):e.name?`https://www.npmjs.com/package/${e.name}`:""}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ArgumentError as F,CommandExecutionError as J,EmptyResultError as L}from"@jackwener/opencli/errors";export const NPM_REGISTRY="https://registry.npmjs.org",NPM_API="https://api.npmjs.org";const O="opencli-npm-adapter (+https://github.com/jackwener/opencli)",Q=/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/i;export function requireString(B,q){const z=String(B??"").trim();if(!z)throw new F(`npm ${q} cannot be empty`);return z}export function requirePackageName(B){const q=String(B??"").trim();if(!q)throw new F('npm package name is required (e.g. "react", "@vercel/og")');if(q.length>214)throw new F(`npm package name "${B}" is too long (max 214 chars)`);if(!Q.test(q))throw new F(`npm package name "${B}" is not a valid registry name`,'Names are 1–214 chars of lowercase a-z / 0-9 / "-._" (scoped form: "@scope/name").');return q}export function requireBoundedInt(B,q,z,H="limit"){const D=B??q,I=typeof D==="number"?D:Number(D);if(!Number.isInteger(I)||I<=0)throw new F(`npm ${H} must be a positive integer`);if(I>z)throw new F(`npm ${H} must be <= ${z}`);return I}export async function npmFetch(B,q){let z;try{z=await fetch(B,{headers:{"user-agent":O,accept:"application/json"}})}catch(D){throw new J(`${q} request failed: ${D?.message??D}`,"Check that registry.npmjs.org / api.npmjs.org are reachable from this network.")}if(z.status===404)throw new L(q,`npm registry returned 404 for ${B}.`);if(z.status===429)throw new J(`${q} returned HTTP 429 (rate limited)`,"npm throttles unauthenticated bursts; wait a few seconds and retry.");if(!z.ok)throw new J(`${q} returned HTTP ${z.status}`);let H;try{H=await z.json()}catch(D){throw new J(`${q} returned malformed JSON: ${D?.message??D}`)}return H}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as $,Strategy as q}from"@jackwener/opencli/registry";import{CommandExecutionError as Q,EmptyResultError as B}from"@jackwener/opencli/errors";import{NUGET_REGISTRATION_BASE as O,joinAuthors as P,joinTags as f,nugetFetch as W,requirePackageId as v}from"./utils.js";$({site:"nuget",name:"package",access:"read",description:"Full NuGet package version history (catalogEntry per release)",domain:"api.nuget.org",strategy:q.PUBLIC,browser:!1,args:[{name:"id",positional:!0,required:!0,help:'NuGet package id (e.g. "Newtonsoft.Json", case-insensitive)'}],columns:["rank","id","version","title","authors","tags","language","licenseExpression","projectUrl","published","listed","url"],func:async(X)=>{const K=v(X.id),Y=`${O}/${encodeURIComponent(K.toLowerCase())}/index.json`,V=await W(Y,"nuget package"),Z=Array.isArray(V?.items)?V.items:[],M=[];for(const[J,H]of Z.entries()){let z=Array.isArray(H?.items)?H.items:null;if(!z){const D=typeof H?.["@id"]==="string"?H["@id"]:null;if(!D)throw new Q(`nuget package registration page ${J+1} is missing @id for package "${K}"`);const L=await W(D,"nuget package page");if(!Array.isArray(L?.items))throw new Q(`nuget package registration leaf ${D} did not include an items array`);z=L.items}for(const D of z){if(!D||typeof D!=="object"||!D.catalogEntry||typeof D.catalogEntry!=="object")throw new Q(`nuget package registration page ${J+1} contains a malformed version entry`);M.push(D)}}if(!M.length)throw new B("nuget package",`No published versions found for NuGet package "${K}".`);return[...M].sort((J,H)=>{const z=J?.catalogEntry?.published??"",D=H?.catalogEntry?.published??"";if(z!==D)return D.localeCompare(z);const L=J?.catalogEntry?.version??"";return(H?.catalogEntry?.version??"").localeCompare(L)}).map((J,H)=>{const z=J?.catalogEntry??{};return{rank:H+1,id:typeof z?.id==="string"?z.id:K,version:typeof z?.version==="string"?z.version:null,title:typeof z?.title==="string"?z.title:null,authors:P(z?.authors),tags:f(z?.tags),language:typeof z?.language==="string"?z.language:null,licenseExpression:typeof z?.licenseExpression==="string"?z.licenseExpression:null,projectUrl:typeof z?.projectUrl==="string"?z.projectUrl:null,published:typeof z?.published==="string"?z.published:null,listed:typeof z?.listed==="boolean"?z.listed:null,url:typeof z?.id==="string"&&typeof z?.version==="string"?`https://www.nuget.org/packages/${z.id}/${z.version}`:""}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as c,Strategy as d}from"@jackwener/opencli/registry";import{EmptyResultError as p}from"@jackwener/opencli/errors";import{NUGET_SEARCH_BASE as y,joinAuthors as f,joinTags as h,nugetFetch as m,requireBoundedInt as g,requireString as w}from"./utils.js";c({site:"nuget",name:"search",access:"read",description:"Search NuGet packages by keyword",domain:"api.nuget.org",strategy:d.PUBLIC,browser:!1,args:[{name:"query",positional:!0,required:!0,help:"Search keyword"},{name:"limit",type:"int",default:20,help:"Max packages (1-1000)"},{name:"prerelease",type:"boolean",default:!1,help:"Include prerelease versions"}],columns:["rank","id","version","title","description","authors","tags","totalDownloads","verified","projectUrl","url"],func:async(t)=>{const o=w(t.query,"query"),a=g(t.limit,20,1000),i=t.prerelease===!0?"true":"false",l=`${y}/query?q=${encodeURIComponent(o)}&take=${a}&prerelease=${i}`,n=await m(l,"nuget search"),s=Array.isArray(n?.data)?n.data:[];if(!s.length)throw new p("nuget search",`No NuGet packages matched "${o}".`);return s.slice(0,a).map((e,u)=>{const r=typeof e?.id==="string"?e.id:"";return{rank:u+1,id:r,version:typeof e?.version==="string"?e.version:null,title:typeof e?.title==="string"?e.title:null,description:typeof e?.description==="string"?e.description:null,authors:f(e?.authors),tags:h(e?.tags),totalDownloads:typeof e?.totalDownloads==="number"?e.totalDownloads:null,verified:e?.verified===!0,projectUrl:typeof e?.projectUrl==="string"?e.projectUrl:null,url:r?`https://www.nuget.org/packages/${r}`:""}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ArgumentError as J,CommandExecutionError as M,EmptyResultError as O}from"@jackwener/opencli/errors";export const NUGET_SEARCH_BASE="https://azuresearch-usnc.nuget.org",NUGET_REGISTRATION_BASE="https://api.nuget.org/v3/registration5-semver1";const Q="opencli-nuget-adapter/1.0 (+https://github.com/jackwener/opencli; mailto:opencli@example.com)",S=/^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,99})$/;export function requireString(z,q){const B=String(z??"").trim();if(!B)throw new J(`nuget ${q} cannot be empty`);return B}export function requireBoundedInt(z,q,B,H="limit"){const F=z??q,L=typeof F==="number"?F:Number(F);if(!Number.isInteger(L)||L<=0)throw new J(`nuget ${H} must be a positive integer`);if(L>B)throw new J(`nuget ${H} must be <= ${B}`);return L}export function requirePackageId(z){const q=String(z??"").trim();if(!q)throw new J('nuget package id is required (e.g. "Newtonsoft.Json")');if(!S.test(q))throw new J(`nuget package id "${z}" is not a valid NuGet identifier`,"NuGet IDs are 1-100 chars: letters/digits/`.`/`_`/`-`, starting with letter or digit.");return q}export async function nugetFetch(z,q){let B;try{B=await fetch(z,{headers:{"user-agent":Q,accept:"application/json"}})}catch(F){throw new M(`${q} request failed: ${F?.message??F}`,"Check that api.nuget.org is reachable from this network.")}if(B.status===404)throw new O(q,`NuGet returned 404 for ${z}.`);if(B.status===429)throw new M(`${q} returned HTTP 429 (rate limited)`);if(!B.ok)throw new M(`${q} returned HTTP ${B.status}`);let H;try{H=await B.json()}catch(F){throw new M(`${q} returned malformed JSON: ${F?.message??F}`)}return H}export function joinTags(z){if(!Array.isArray(z))return"";return z.filter((q)=>typeof q==="string"&&q.trim()).join(", ")}export function joinAuthors(z){if(Array.isArray(z))return z.filter((q)=>typeof q==="string"&&q.trim()).join(", ");if(typeof z==="string")return z.trim();return""}
|
package/clis/nvd/cve.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as v,Strategy as u}from"@jackwener/opencli/registry";import{ArgumentError as l,CommandExecutionError as a,EmptyResultError as f}from"@jackwener/opencli/errors";const p="https://services.nvd.nist.gov/rest/json/cves/2.0",g="opencli-nvd-adapter (+https://github.com/jackwener/opencli)",h=/^CVE-\d{4}-\d{4,}$/i;function y(e){const t=String(e??"").trim().toUpperCase();if(!t)throw new l('nvd CVE id is required (e.g. "CVE-2021-44228")');if(!h.test(t))throw new l(`nvd CVE id "${e}" is not a valid CVE identifier`,'Expected the form "CVE-YYYY-N..." with at least 4 sequence digits.');return t}function V(e){if(!Array.isArray(e))return"";const t=e.find((s)=>s?.lang==="en");return String(t?.value??e[0]?.value??"").trim()}function S(e){if(!e||typeof e!=="object")return null;const t=[...Array.isArray(e.cvssMetricV31)?e.cvssMetricV31:[],...Array.isArray(e.cvssMetricV30)?e.cvssMetricV30:[],...Array.isArray(e.cvssMetricV2)?e.cvssMetricV2:[]];return t.find((s)=>s?.type==="Primary")||t[0]||null}function w(e){if(!Array.isArray(e))return"";const t=new Set;for(const s of e)for(const i of s?.description??[])if(i?.value)t.add(String(i.value));return[...t].join(", ")}v({site:"nvd",name:"cve",access:"read",description:"NIST NVD CVE detail (description, CVSS, CWE, KEV flag)",domain:"services.nvd.nist.gov",strategy:u.PUBLIC,browser:!1,args:[{name:"id",positional:!0,required:!0,help:'CVE identifier (e.g. "CVE-2021-44228")'}],columns:["id","published","lastModified","vulnStatus","baseScore","severity","attackVector","cwe","kevAdded","description","url"],func:async(e)=>{const t=y(e.id),s=`${p}?cveId=${encodeURIComponent(t)}`;let i;try{i=await fetch(s,{headers:{"user-agent":g,accept:"application/json"}})}catch(n){throw new a(`nvd cve request failed: ${n?.message??n}`)}if(i.status===403)throw new a("nvd cve returned HTTP 403","NVD enforces aggressive rate limits without an API key. Wait, then retry or set NVD_API_KEY (not yet wired).");if(i.status===429)throw new a("nvd cve returned HTTP 429 (rate limited)","NVD throttles unauthenticated traffic; wait several seconds before retry.");if(!i.ok)throw new a(`nvd cve returned HTTP ${i.status}`);let c;try{c=await i.json()}catch(n){throw new a(`nvd cve returned malformed JSON: ${n?.message??n}`)}const r=(Array.isArray(c?.vulnerabilities)?c.vulnerabilities:[])[0]?.cve;if(!r||!r.id)throw new f("nvd cve",`NVD has no record for "${t}".`);const d=S(r.metrics),o=d?.cvssData??{};return[{id:String(r.id),published:String(r.published??"").slice(0,10),lastModified:String(r.lastModified??"").slice(0,10),vulnStatus:String(r.vulnStatus??""),baseScore:o.baseScore!=null?Number(o.baseScore):null,severity:String(o.baseSeverity??d?.baseSeverity??""),attackVector:String(o.attackVector??""),cwe:w(r.weaknesses),kevAdded:r.cisaExploitAdd?String(r.cisaExploitAdd).slice(0,10):"",description:V(r.descriptions),url:`https://nvd.nist.gov/vuln/detail/${r.id}`}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as Y,Strategy as Z}from"@jackwener/opencli/registry";import{EmptyResultError as $}from"@jackwener/opencli/errors";import{OEIS_BASE as V,formatId as h,oeisFetch as x,previewTerms as C,requireBoundedInt as F,requireString as P}from"./utils.js";Y({site:"oeis",name:"search",access:"read",description:"Search OEIS sequences by keyword or numeric pattern",domain:"oeis.org",strategy:Z.PUBLIC,browser:!1,args:[{name:"query",positional:!0,required:!0,help:'Search keyword or comma-separated terms (e.g. "fibonacci", "1,1,2,3,5,8")'},{name:"limit",type:"int",default:10,help:"Max sequences (1-100)"}],columns:["rank","id","name","keywords","preview","author","created","url"],func:async(N)=>{const Q=P(N.query,"query"),J=F(N.limit,10,100),H=[];let U=0;const K=10,W=Math.ceil(J/K)+1;for(let D=0;D<W&&H.length<J;D++){const L=`${V}/search?q=${encodeURIComponent(Q)}&fmt=json&start=${U}`,G=await x(L,"oeis search"),M=Array.isArray(G)?G:[];if(!M.length)break;for(const X of M){if(H.length>=J)break;H.push(X)}if(M.length<K)break;U+=K}if(!H.length)throw new $("oeis search",`No OEIS sequences matched "${Q}".`);return H.map((D,L)=>{const G=h(D?.number);return{rank:L+1,id:G,name:typeof D?.name==="string"?D.name:null,keywords:typeof D?.keyword==="string"?D.keyword:null,preview:C(D?.data),author:typeof D?.author==="string"?D.author:null,created:typeof D?.created==="string"?D.created:null,url:G?`${V}/${G}`:""}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as c,Strategy as m}from"@jackwener/opencli/registry";import{EmptyResultError as d}from"@jackwener/opencli/errors";import{OEIS_BASE as u,formatId as a,oeisFetch as p,previewTerms as y,requireSequenceId as g}from"./utils.js";function n(r){return Array.isArray(r)?r:[]}c({site:"oeis",name:"sequence",access:"read",description:"Full OEIS sequence detail by A-number (terms, name, keywords, formula counts)",domain:"oeis.org",strategy:m.PUBLIC,browser:!1,args:[{name:"id",positional:!0,required:!0,help:'OEIS sequence id (e.g. "A000045" for Fibonacci)'}],columns:["id","name","keywords","preview","termCount","offset","author","created","revision","commentCount","formulaCount","referenceCount","xrefCount","linkCount","url"],func:async(r)=>{const t=g(r.id),l=`${u}/search?q=id:${encodeURIComponent(t)}&fmt=json`,s=await p(l,"oeis sequence"),i=Array.isArray(s)?s:[];if(!i.length)throw new d("oeis sequence",`OEIS sequence "${t}" not found.`);const e=i[0],o=typeof e?.data==="string"?e.data:"",f=o?o.split(",").filter(Boolean).length:0;return[{id:a(e?.number)??t,name:typeof e?.name==="string"?e.name:null,keywords:typeof e?.keyword==="string"?e.keyword:null,preview:y(o),termCount:f,offset:typeof e?.offset==="string"?e.offset:null,author:typeof e?.author==="string"?e.author:null,created:typeof e?.created==="string"?e.created:null,revision:typeof e?.revision==="number"?e.revision:null,commentCount:n(e?.comment).length,formulaCount:n(e?.formula).length,referenceCount:n(e?.reference).length,xrefCount:n(e?.xref).length,linkCount:n(e?.link).length,url:`${u}/${a(e?.number)??t}`}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ArgumentError as H,CommandExecutionError as K,EmptyResultError as L}from"@jackwener/opencli/errors";export const OEIS_BASE="https://oeis.org";const M="opencli-oeis-adapter/1.0 (+https://github.com/jackwener/opencli; mailto:opencli@example.com)",W=/^A\d{1,7}$/;export function requireString(z,B){const q=String(z??"").trim();if(!q)throw new H(`oeis ${B} cannot be empty`);return q}export function requireBoundedInt(z,B,q,G="limit"){const F=z??B,J=typeof F==="number"?F:Number(F);if(!Number.isInteger(J)||J<=0)throw new H(`oeis ${G} must be a positive integer`);if(J>q)throw new H(`oeis ${G} must be <= ${q}`);return J}export function requireSequenceId(z){const B=String(z??"").trim().toUpperCase();if(!B)throw new H('oeis sequence id is required (e.g. "A000045" for Fibonacci)');const q=B.replace(/^HTTPS?:\/\/(?:WWW\.)?OEIS\.ORG\//,"").replace(/\/.*$/,"");if(!W.test(q))throw new H(`oeis sequence id "${z}" is not a valid A-number`,'Expected format: "A" + digits (e.g. "A000045").');return q}export async function oeisFetch(z,B){let q;try{q=await fetch(z,{headers:{"user-agent":M,accept:"application/json"}})}catch(F){throw new K(`${B} request failed: ${F?.message??F}`,"Check that oeis.org is reachable from this network.")}if(q.status===404)throw new L(B,`OEIS returned 404 for ${z}.`);if(q.status===429)throw new K(`${B} returned HTTP 429 (rate limited)`);if(!q.ok)throw new K(`${B} returned HTTP ${q.status}`);let G;try{G=await q.json()}catch(F){throw new K(`${B} returned malformed JSON: ${F?.message??F}`)}return G}export function formatId(z){if(typeof z!=="number"||!Number.isInteger(z)||z<0)return null;return`A${String(z).padStart(6,"0")}`}export function previewTerms(z,B=12){if(typeof z!=="string")return"";const q=z.split(",").map((G)=>G.trim()).filter(Boolean);if(q.length<=B)return q.join(", ");return[...q.slice(0,B),`(+${q.length-B})`].join(", ")}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import{CliError as Q}from"@jackwener/opencli/errors";export const API_PREFIX="/project/api/project";export function getOnesBaseUrl(){const D=process.env.ONES_BASE_URL?.trim().replace(/\/+$/,"");if(!D)throw new Q("CONFIG","Missing ONES_BASE_URL","Set ONES_BASE_URL to your deployment origin, e.g. https://your-team.ones.cn (no trailing slash).");return D}export function onesApiUrl(D){const K=getOnesBaseUrl(),q=D.replace(/^\/+/,"");return`${K}${API_PREFIX}/${q}`}export async function gotoOnesHome(D){await D.goto(getOnesBaseUrl(),{waitUntil:"load"});await D.wait(2)}function G(D,K){const x={Referer:getOnesBaseUrl()};if(D){const L=process.env.ONES_USER_ID?.trim()||process.env.ONES_USER_UUID?.trim()||process.env.Ones_User_Id?.trim(),N=process.env.ONES_AUTH_TOKEN?.trim()||process.env.Ones_Auth_Token?.trim();if(L&&N){x["Ones-User-Id"]=L;x["Ones-Auth-Token"]=N}}if(K)x["Content-Type"]="application/json";return x}export function summarizeOnesError(D,K){if(K&&typeof K==="object"){const q=K,x=[];if(typeof q.type==="string")x.push(q.type);if(typeof q.reason==="string")x.push(q.reason);if(typeof q.errcode==="string")x.push(q.errcode);if(typeof q.message==="string")x.push(q.message);if(q.code!==void 0&&q.code!==null)x.push(`code=${String(q.code)}`);if(x.length)return x.filter(Boolean).join(" · ")}return D===401?"Unauthorized":`HTTP ${D}`}function M(D,K){if(K===null||typeof K!=="object")return;const q=K;if(Array.isArray(q.groups))return;if(!(typeof q.reason==="string"&&q.reason.length>0||typeof q.errcode==="string"&&q.errcode.length>0||typeof q.type==="string"&&q.type.length>0))return;const L=summarizeOnesError(200,K);throw new Q("FETCH_ERROR",`ONES ${D}: ${L}`,"若 query 不合法会返回 ServerError;可试 opencli ones tasks(空 must)或检查筛选器文档。响应全文可用 -v 或临时打日志。")}export async function onesFetchInPageWithMeta(D,K,q={}){if(!q.skipGoto)await gotoOnesHome(D);const x=onesApiUrl(K),L=(q.method??"GET").toUpperCase(),N=q.auth!==!1,S=q.body??null,V=G(N,S!==null||L==="POST"||L==="PUT"||L==="PATCH"),Y=JSON.stringify(x),Z=JSON.stringify(L),$=JSON.stringify(V),j=S===null?"null":JSON.stringify(S);return await D.evaluate(`
|
|
2
|
+
(async () => {
|
|
3
|
+
const url = ${Y};
|
|
4
|
+
const method = ${Z};
|
|
5
|
+
const headers = ${$};
|
|
6
|
+
const body = ${j};
|
|
7
|
+
const init = {
|
|
8
|
+
method,
|
|
9
|
+
headers: { ...headers },
|
|
10
|
+
credentials: 'include',
|
|
11
|
+
};
|
|
12
|
+
if (body !== null) init.body = body;
|
|
13
|
+
const res = await fetch(url, init);
|
|
14
|
+
const text = await res.text();
|
|
15
|
+
let parsed = null;
|
|
16
|
+
try {
|
|
17
|
+
parsed = text ? JSON.parse(text) : null;
|
|
18
|
+
} catch {
|
|
19
|
+
parsed = text;
|
|
20
|
+
}
|
|
21
|
+
return { ok: res.ok, status: res.status, parsed };
|
|
22
|
+
})()
|
|
23
|
+
`)}export async function resolveOnesUserUuid(D,K){const q=process.env.ONES_USER_ID?.trim()||process.env.ONES_USER_UUID?.trim()||process.env.Ones_User_Id?.trim();if(q)return q;const x=await onesFetchInPage(D,"users/me",{skipGoto:K?.skipGoto}),L=x.user&&typeof x.user==="object"?x.user:x;if(!L||typeof L.uuid!=="string")throw new Q("FETCH_ERROR","Could not read current user uuid from users/me","Set ONES_USER_ID or ensure Chrome is logged in; try: opencli ones me -f json");return String(L.uuid)}export async function onesFetchInPage(D,K,q={}){const x=await onesFetchInPageWithMeta(D,K,q);if(!x.ok){const L=summarizeOnesError(x.status,x.parsed),N=x.status===401?"在 Chrome 中打开 ONES 并登录;或先执行 opencli ones login 后按提示 export ONES_USER_ID / ONES_AUTH_TOKEN;并确认 ONES_BASE_URL 与浏览器地址一致。":"检查 ONES_BASE_URL、VPN/内网,以及实例是否仍为 Project API 路径。";throw new Q("FETCH_ERROR",`ONES ${K}: ${L}`,N)}if(K.includes("/filters/peek"))M(K,x.parsed);return x.parsed}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{onesFetchInPage as m}from"./common.js";const c=40;export async function enrichPeekEntriesWithDetails(u,f,n,d){const r=[...new Set(n.map((t)=>String(t.uuid??"").trim()).filter(Boolean))];if(r.length===0)return n;const e=new Map;try{for(let t=0;t<r.length;t+=c){const i=r.slice(t,t+c),s=await m(u,`team/${f}/tasks/info`,{method:"POST",body:JSON.stringify({ids:i}),skipGoto:d}),l=Array.isArray(s.tasks)?s.tasks:[];for(const o of l){const a=String(o.uuid??"");if(a)e.set(a,o)}}}catch{return n}if(e.size===0)return n;return n.map((t)=>{const i=String(t.uuid??""),s=i?e.get(i):void 0;return s?{...t,...s}:t})}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{cli as u,Strategy as d}from"@jackwener/opencli/registry";import{CliError as n}from"@jackwener/opencli/errors";import{getOnesBaseUrl as O,onesFetchInPage as E}from"./common.js";u({site:"ones",name:"login",access:"write",description:"ONES Project API — login via Chrome Bridge (POST auth/login); stderr prints export hints for ONES_USER_ID / TOKEN",domain:"ones.cn",strategy:d.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"email",type:"str",required:!1,help:"Account email (or set ONES_EMAIL)"},{name:"phone",type:"str",required:!1,help:"Account phone (or set ONES_PHONE); ignored if email is set"},{name:"password",type:"str",required:!1,help:"Password (or set ONES_PASSWORD)"}],columns:["uuid","name","email","token_preview"],func:async(p,o)=>{const s=o.email?.trim()||process.env.ONES_EMAIL?.trim(),i=o.phone?.trim()||process.env.ONES_PHONE?.trim(),a=o.password||process.env.ONES_PASSWORD||"";if(!a)throw new n("CONFIG","Password required","Pass --password or set ONES_PASSWORD for non-interactive use.");if(!s&&!i)throw new n("CONFIG","email or phone required","Pass --email or --phone (or set ONES_EMAIL / ONES_PHONE).");O();const t={password:a};if(s)t.email=s;else t.phone=i;const e=(await E(p,"auth/login",{method:"POST",body:JSON.stringify(t),auth:!1})).user;if(!e?.uuid||!e?.token)throw new n("FETCH_ERROR","ONES login response missing user.uuid or user.token","Your server build may differ from documented Project API.");const m=String(e.uuid),r=String(e.token),S=String(e.name??""),c=String(e.email??""),l=O();console.error(["","后续请求会优先使用当前 Chrome 会话 Cookie;若接口仍要求 Header,可 export:",` export ONES_BASE_URL=${JSON.stringify(l)}`,` export ONES_USER_ID=${JSON.stringify(m)}`,` export ONES_AUTH_TOKEN=${JSON.stringify(r)}`,""].join(`
|
|
2
|
+
`));return[{uuid:m,name:S,email:c,token_preview:r.length>12?`${r.slice(0,6)}…${r.slice(-4)}`:"***"}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as t,Strategy as o}from"@jackwener/opencli/registry";import{onesFetchInPage as r}from"./common.js";t({site:"ones",name:"logout",access:"write",description:"ONES Project API — invalidate current token (GET auth/logout) via Chrome Bridge",domain:"ones.cn",strategy:o.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["ok","detail"],func:async(e)=>{await r(e,"auth/logout",{method:"GET"});return[{ok:"true",detail:"Server logout ok; clear local ONES_AUTH_TOKEN if set."}]}});
|
package/clis/ones/me.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as s,Strategy as n}from"@jackwener/opencli/registry";import{CliError as o}from"@jackwener/opencli/errors";import{onesFetchInPage as i}from"./common.js";s({site:"ones",name:"me",access:"read",description:"ONES Project API — current user (GET users/me) via Chrome Bridge",domain:"ones.cn",strategy:n.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["uuid","name","email","phone","status"],func:async(t)=>{const r=await i(t,"users/me"),e=r.user&&typeof r.user==="object"?r.user:r;if(!e||typeof e.uuid!=="string")throw new o("FETCH_ERROR","Unexpected users/me response","See raw JSON with: opencli ones me -f json");return[{uuid:String(e.uuid),name:String(e.name??""),email:String(e.email??""),phone:String(e.phone??""),status:e.status!=null?String(e.status):""}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as H,Strategy as I}from"@jackwener/opencli/registry";import{CliError as S}from"@jackwener/opencli/errors";import{gotoOnesHome as W,onesFetchInPage as B,resolveOnesUserUuid as f}from"./common.js";import{enrichPeekEntriesWithDetails as v}from"./enrich-tasks.js";import{resolveTaskListLabels as E}from"./resolve-labels.js";import{defaultPeekBody as F,flattenPeekGroups as L,mapTaskEntry as b,parsePeekLimit as A}from"./task-helpers.js";function $(x){return{must:[{equal:{assign:x}}]}}function C(x){return{must:[{in:{"field_values.field004":[x]}}]}}function D(x){return{must:[{equal:{owner:x}}]}}function O(x){const M=new Set,z=[];for(const J of x){const K=String(J.uuid??"");if(!K||M.has(K))continue;M.add(K);z.push(J)}return z}async function X(x,M,z,J){const K=`team/${M}/filters/peek`,N=F(z),Q=await B(x,K,{method:"POST",body:JSON.stringify(N),skipGoto:!0});return L(Q,J)}H({site:"ones",name:"my-tasks",access:"read",description:"ONES — my work items (filters/peek + strict must query). Default: assignee=me. Use --mode if your site uses field004 for assignee.",domain:"ones.cn",strategy:I.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"team",type:"str",required:!1,positional:!0,help:"Team UUID from URL …/team/<uuid>/…, or set ONES_TEAM_UUID"},{name:"limit",type:"int",default:100,help:"Max rows (default 100, max 500)"},{name:"mode",type:"str",default:"assign",choices:["assign","field004","owner","both"],help:"assign=负责人(顶层 assign);field004=负责人(筛选器示例里的 field004);owner=创建者;both=负责人∪创建者(两次 peek 去重)"}],columns:["title","status","project","uuid","updated","工时"],func:async(x,M)=>{const z=M.team?.trim()||process.env.ONES_TEAM_UUID?.trim()||process.env.ONES_TEAM_ID?.trim();if(!z)throw new S("CONFIG","team UUID required","Pass team from URL …/team/<team>/… or set ONES_TEAM_UUID.");const J=A(M.limit,100),K=String(M.mode??"assign");await W(x);const N=await f(x,{skipGoto:!0});let Q=[];if(K==="both"){const R=Math.min(500,J*2),Y=await X(x,z,$(N),R),V=await X(x,z,D(N),R);Q=O([...Y,...V]).slice(0,J)}else{const Y=(()=>{switch(K){case"field004":return C(N);case"owner":return D(N);case"assign":default:return $(N)}})();try{Q=await X(x,z,Y,J)}catch(V){const Z=V instanceof Error?V.message:"";if(K==="assign"&&(Z.includes("ServerError")||Z.includes("801")||Z.includes("Params is invalid")))Q=await X(x,z,C(N),J);else throw V}}const _=await v(x,z,Q,!0),G=await E(x,z,_,!0);return _.map((R)=>b(R,G))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{onesFetchInPage as m}from"./common.js";import{getTaskProjectRawId as h}from"./task-helpers.js";export async function loadTaskStatusLabels(n,a,r){const o=new Map;try{const s=await m(n,`team/${a}/task_statuses`,{method:"GET",skipGoto:r}),e=Array.isArray(s.task_statuses)?s.task_statuses:[];for(const t of e){const c=String(t.uuid??""),i=String(t.name??"");if(c&&i)o.set(c,i)}}catch{}return o}const f=25;export async function loadProjectLabels(n,a,r,o){const s=new Map,e=[...new Set(r.filter(Boolean))];if(e.length===0)return s;try{for(let t=0;t<e.length;t+=f){const i=e.slice(t,t+f).map(encodeURIComponent).join(","),y=`team/${a}/projects/info?ids=${i}`,u=await m(n,y,{method:"GET",skipGoto:o}),j=Array.isArray(u.projects)?u.projects:[];for(const p of j){const l=String(p.uuid??""),d=String(p.name??"");if(l&&d)s.set(l,d)}}}catch{}return s}export async function resolveTaskListLabels(n,a,r,o){const s=r.map((c)=>h(c)).filter(Boolean),[e,t]=await Promise.all([loadTaskStatusLabels(n,a,o),loadProjectLabels(n,a,s,o)]);return{statusByUuid:e,projectByUuid:t}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{CliError as E}from"@jackwener/opencli/errors";function H(B){if(!Array.isArray(B))return"";for(const D of B){if(!D||typeof D!=="object")continue;const G=D;if(!String(G.field_uuid??"").startsWith("field"))continue;const J=G.value;if(typeof J==="string"&&J.trim())return J.trim();if(Array.isArray(J)&&J.length&&typeof J[0]==="string"&&J[0].trim())return J[0].trim()}return""}export function pickTaskTitle(B){for(const K of["summary","name","title","subject"]){const J=B[K];if(typeof J==="string"&&J.trim())return J.trim()}const D=H(B.field_values);if(D)return D;const G=B.field_values;if(G&&typeof G==="object"&&!Array.isArray(G)){const K=G;for(const J of["field001","field002","field003"]){const N=K[J];if(typeof N==="string"&&N.trim())return N.trim()}}return""}export function ellipsizeCell(B,D=64){const G=B.trim();if(G.length<=D)return G;return`${G.slice(0,D-1)}…`}export function briefUuid(B,D=6,G=4){if(!B)return"";if(B.length<=D+G+1)return B;return`${B.slice(0,D)}…${B.slice(-G)}`}export function formatStamp(B){if(B==null||B==="")return"";const D=Number(B);if(Number.isNaN(D))return String(B);const G=D>100000000000000?Math.floor(D/1000):D>1000000000000?D:D*1000;try{return new Date(G).toISOString().replace("T"," ").slice(0,19)}catch{return String(B)}}export function flattenPeekGroups(B,D){if(!Array.isArray(B.groups))throw new E("FETCH_ERROR","Unexpected filters/peek response (missing groups)","Try -f json; check team UUID and API version.");const G=B.groups,K=[];for(const J of G){const N=Array.isArray(J.entries)?J.entries:[];for(const Q of N){K.push(Q);if(K.length>=D)break}if(K.length>=D)break}return K.slice(0,D)}function Y(B,D){if(!Array.isArray(B))return"";for(const G of B){if(!G||typeof G!=="object")continue;const K=G;if(String(K.field_uuid??"")!==D)continue;const J=K.value;if(typeof J==="string")return J;if(Array.isArray(J)&&J[0]!=null)return String(J[0])}return""}function Z(B){const D=B.field_values;return D&&typeof D==="object"&&!Array.isArray(D)?D:null}export function getTaskStatusRawId(B){const D=B.field_values,G=Z(B);if(typeof B.status_uuid==="string")return B.status_uuid;return Y(D,"field016")||(G?String(G.field016??""):"")}export function getTaskProjectRawId(B){const D=B.field_values,G=Z(B);if(typeof B.project_uuid==="string")return B.project_uuid;return Y(D,"field006")||(G?String(G.field006??""):"")}export function onesManhourScale(){const B=Number(process.env.ONES_MANHOUR_SCALE?.trim());if(Number.isFinite(B)&&B>0)return B;return 1e5}export function hoursToOnesManhourRaw(B){if(!Number.isFinite(B)||B<=0)return 0;return Math.max(1,Math.round(B*onesManhourScale()))}function V(B){if(!Number.isFinite(B))return"";const D=Math.round(B*1e6)/1e6,G=Math.round(D);if(Math.abs(D-G)<0.00001)return`${G}h`;const K=Math.round(D*10)/10;return Number.isInteger(K)?`${K}h`:`${K.toFixed(1)}h`}function X(B,D){if(D==null||D==="")return null;const G=Number(D);if(!Number.isFinite(G))return null;const K=G/onesManhourScale();return`${B}${V(K)}`}export function formatTaskManhourSummary(B){const D=[],G=X("估",B.assess_manhour),K=X("登",B.total_manhour),J=X("余",B.remaining_manhour);if(G)D.push(G);if(K)D.push(K);if(J)D.push(J);return D.length?D.join(" "):"—"}export function mapTaskEntry(B,D){const G=getTaskStatusRawId(B),K=getTaskProjectRawId(B),J=String(B.uuid??""),N=ellipsizeCell(pickTaskTitle(B)),Q=(W)=>W.length>14?briefUuid(W):W,_=D?.statusByUuid?.get(G)??Q(G),$=D?.projectByUuid?.get(K)??Q(K);return{title:N,status:ellipsizeCell(_,20),project:ellipsizeCell($,40),uuid:J,updated:formatStamp(B.server_update_stamp),工时:ellipsizeCell(formatTaskManhourSummary(B),36)}}export function defaultPeekBody(B){return{with_boards:!1,boards:null,query:B,group_by:"",sort:[{create_time:{order:"desc"}}],include_subtasks:!1,include_status_uuid:!0,include_issue_type:!1,include_project_uuid:!0,is_show_derive:!1}}export function parsePeekLimit(B,D){const G=Number.parseInt(String(B??""),10);if(!Number.isFinite(G)||G<=0)return D;return Math.max(1,Math.min(500,G))}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as M,Strategy as Q}from"@jackwener/opencli/registry";import{CliError as x}from"@jackwener/opencli/errors";import{onesFetchInPage as R}from"./common.js";import{formatStamp as V}from"./task-helpers.js";M({site:"ones",name:"task",access:"read",description:"ONES — work item detail (GET team/:team/task/:id/info); id is URL segment after …/task/",domain:"ones.cn",strategy:Q.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"id",type:"str",required:!0,positional:!0,help:"Work item UUID (often 16 chars) from …/task/<id>"},{name:"team",type:"str",required:!1,help:"Team UUID (8 chars from …/team/<team>/…), or set ONES_TEAM_UUID"}],columns:["uuid","summary","number","status_uuid","assign","owner","project_uuid","updated"],func:async(J,z)=>{const B=String(z.id??"").trim();if(!B)throw new x("CONFIG","task id required","Pass the work item uuid from the URL path …/task/<id>");const H=z.team?.trim()||process.env.ONES_TEAM_UUID?.trim()||process.env.ONES_TEAM_ID?.trim();if(!H)throw new x("CONFIG","team UUID required","Use --team <teamUUID> or set ONES_TEAM_UUID (from …/team/<team>/…).");const K=`team/${H}/task/${encodeURIComponent(B)}/info`,q=await R(J,K,{method:"GET"});if(typeof q.uuid!=="string"){const L=typeof q.reason==="string"?q.reason:"Use -f json to inspect response; check id length (often 16) and team.";throw new x("FETCH_ERROR",`ONES task info: ${L}`,"Confirm task uuid and team match the browser URL.")}return[{uuid:String(q.uuid),summary:String(q.summary??""),number:q.number!=null?String(q.number):"",status_uuid:String(q.status_uuid??""),assign:String(q.assign??""),owner:String(q.owner??""),project_uuid:String(q.project_uuid??""),updated:V(q.server_update_stamp)}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as c,Strategy as d}from"@jackwener/opencli/registry";import{CliError as h}from"@jackwener/opencli/errors";import{gotoOnesHome as y,onesFetchInPage as U}from"./common.js";import{enrichPeekEntriesWithDetails as E}from"./enrich-tasks.js";import{resolveTaskListLabels as I}from"./resolve-labels.js";import{defaultPeekBody as O,flattenPeekGroups as g,mapTaskEntry as k,parsePeekLimit as P}from"./task-helpers.js";function D(t,s){const e=[];if(t?.trim())e.push({in:{"field_values.field006":[t.trim()]}});if(s?.trim())e.push({equal:{assign:s.trim()}});if(e.length===0)return{must:[]};return{must:e}}c({site:"ones",name:"tasks",access:"read",description:"ONES Project API — list work items (POST team/:team/filters/peek); use token-info -f json for team uuid",domain:"ones.cn",strategy:d.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"team",type:"str",required:!1,positional:!0,help:"Team UUID (8 chars), or set ONES_TEAM_UUID"},{name:"project",type:"str",required:!1,help:"Filter by project UUID (field006 / 所属项目)"},{name:"assign",type:"str",required:!1,help:"Filter by assignee user UUID (负责人 assign)"},{name:"limit",type:"int",default:30,help:"Max rows after flattening groups (default 30)"}],columns:["title","status","project","uuid","updated","工时"],func:async(t,s)=>{const e=s.team?.trim()||process.env.ONES_TEAM_UUID?.trim()||process.env.ONES_TEAM_ID?.trim();if(!e)throw new h("CONFIG","team UUID required","Pass team as first argument or set ONES_TEAM_UUID (see `opencli ones token-info -f json` → teams[].uuid).");const i=s.project?.trim(),o=s.assign?.trim(),a=P(s.limit,30);await y(t);const n=O(D(i,o)),m=`team/${e}/filters/peek`,l=await U(t,m,{method:"POST",body:JSON.stringify(n),skipGoto:!0}),u=g(l,a),r=await E(t,e,u,!0),f=await I(t,e,r,!0);return r.map((p)=>k(p,f))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as m,Strategy as u}from"@jackwener/opencli/registry";import{CliError as c}from"@jackwener/opencli/errors";import{onesFetchInPage as g}from"./common.js";m({site:"ones",name:"token-info",access:"read",description:"ONES Project API — session detail (GET auth/token_info) via Chrome Bridge: user, teams, org",domain:"ones.cn",strategy:u.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["uuid","name","email","teams","org_name"],func:async(i)=>{const e=await g(i,"auth/token_info"),r=e.user&&typeof e.user==="object"?e.user:null;if(!r?.uuid)throw new c("FETCH_ERROR","Unexpected auth/token_info response","Try `opencli ones me -f json` or check ONES_* env vars.");const s=(Array.isArray(e.teams)?e.teams:[]).map((a)=>{const n=String(a.name??"").trim(),o=String(a.uuid??"").trim();if(n&&o)return`${n} (${o})`;return o||n}).filter(Boolean).join(", "),t=e.org&&typeof e.org==="object"?e.org:null;return[{uuid:String(r.uuid),name:String(r.name??""),email:String(r.email??""),teams:s,org_name:t?String(t.name??""):""}]}});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import{cli as H,Strategy as b}from"@jackwener/opencli/registry";import{CliError as $}from"@jackwener/opencli/errors";import{gotoOnesHome as S,onesFetchInPageWithMeta as R,resolveOnesUserUuid as M,summarizeOnesError as T}from"./common.js";import{hoursToOnesManhourRaw as y}from"./task-helpers.js";function f(K,V){if(!K||typeof K!=="object")return V>=400?`HTTP ${V}`:null;const J=K;if(Array.isArray(J.errors)&&J.errors.length>0){const Q=J.errors[0];if(Q&&typeof Q==="object"){const X=String(Q.message??"").trim();if(X)return X}return"graphql errors"}if(J.data&&typeof J.data==="object"){const Q=J.data;if(Q.addManhour&&typeof Q.addManhour==="object"){if(!String(Q.addManhour.key??"").trim())return"addManhour returned empty key"}}if(Array.isArray(J.bad_tasks)&&J.bad_tasks.length>0){const Q=J.bad_tasks[0];return String(Q.desc??Q.code??JSON.stringify(Q))}if(typeof J.reason==="string"&&J.reason.trim())return J.reason.trim();const N=J.code;if(N!==void 0&&N!==null){const Q=Number(N);if(Number.isFinite(Q)&&Q!==200&&Q!==0)return`code=${String(N)}`}const Z=J.errcode;if(typeof Z==="string"&&Z&&Z!=="OK")return Z;return null}function I(K){if(!K.ok)return T(K.status,K.parsed);return f(K.parsed,K.status)}function h(){const K=new Date,V=K.getFullYear(),J=String(K.getMonth()+1).padStart(2,"0"),N=String(K.getDate()).padStart(2,"0");return`${V}-${J}-${N}`}function k(K){return/^\d{4}-\d{2}-\d{2}$/.test(K)}function w(K){const J=new Date(`${K}T00:00:00`).getTime();if(!Number.isFinite(J))return 0;return Math.floor(J/1000)}function v(K){if(!K||typeof K!=="object")return null;const J=Number(K.total_manhour);return Number.isFinite(J)?J:null}export function buildAddManhourGraphqlBody(K){const{ownerId:V,taskId:J,startTime:N,rawManhour:Z,note:Q}=K,X=JSON.stringify(Q),x=JSON.stringify(V),G=JSON.stringify(J);return JSON.stringify({query:`mutation AddManhour {
|
|
2
|
+
addManhour(
|
|
3
|
+
mode: "simple"
|
|
4
|
+
owner: ${x}
|
|
5
|
+
task: ${G}
|
|
6
|
+
type: "recorded"
|
|
7
|
+
start_time: ${N}
|
|
8
|
+
hours: ${Z}
|
|
9
|
+
description: ${X}
|
|
10
|
+
customData: {}
|
|
11
|
+
) {
|
|
12
|
+
key
|
|
13
|
+
}
|
|
14
|
+
}`})}H({site:"ones",name:"worklog",access:"write",description:"ONES — log work hours on a task (defaults to today; use --date to backfill; endpoint falls back by deployment).",domain:"ones.cn",strategy:b.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"task",type:"str",required:!0,positional:!0,help:"Work item UUID (usually 16 chars), from my-tasks or browser URL …/task/<id>"},{name:"hours",type:"str",required:!0,positional:!0,help:"Hours to log for this entry (e.g. 2 or 1.5), converted with ONES_MANHOUR_SCALE"},{name:"team",type:"str",required:!1,help:"Team UUID from URL …/team/<uuid>/…, or set ONES_TEAM_UUID"},{name:"date",type:"str",required:!1,help:"Entry date YYYY-MM-DD, defaults to today (local timezone); use for backfill"},{name:"note",type:"str",required:!1,help:"Optional note (written to description/desc)"},{name:"owner",type:"str",required:!1,help:"Owner user UUID (defaults to current logged-in user)"}],columns:["task","date","hours","owner","endpoint"],func:async(K,V)=>{const J=String(V.task??"").trim();if(!J)throw new $("CONFIG","task uuid required","Pass the work item uuid from opencli ones my-tasks or the URL.");const N=V.team?.trim()||process.env.ONES_TEAM_UUID?.trim()||process.env.ONES_TEAM_ID?.trim();if(!N)throw new $("CONFIG","team UUID required","Pass --team or set ONES_TEAM_UUID (from …/team/<team>/…).");const Z=Number(String(V.hours??"").replace(/,/g,""));if(!Number.isFinite(Z)||Z<=0||Z>1000)throw new $("CONFIG","hours must be a positive number (hours)","Example: opencli ones worklog <taskUUID> 2 --team <teamUUID>");const X=V.date?.trim()||h();if(!k(X))throw new $("CONFIG","invalid --date","Use YYYY-MM-DD, e.g. 2026-03-24.");const x=String(V.note??"").trim(),G=y(Z),U=w(X);if(!U)throw new $("CONFIG","invalid date for start_time",`Could not parse date ${X}.`);await S(K);const q=V.owner?.trim()||await M(K,{skipGoto:!0}),z={owner:q,manhour:G,start_date:X,end_date:X,desc:x},Y={owner:q,allManhour:G,startDate:X,endDate:X,desc:x},_=encodeURIComponent(J),A=buildAddManhourGraphqlBody({ownerId:q,taskId:J,startTime:U,rawManhour:G,note:x}),O=[{path:`team/${N}/items/graphql`,body:A},{path:`team/${N}/task/${_}/manhours/add`,body:JSON.stringify(z)},{path:`team/${N}/task/${_}/manhours/add`,body:JSON.stringify(Y)},{path:`team/${N}/task/${_}/manhours/add`,body:JSON.stringify({manhours:[z]})},{path:`team/${N}/task/${_}/manhours/add`,body:JSON.stringify({manhours:[Y]})},{path:`team/${N}/task/${_}/manhour/add`,body:JSON.stringify(z)},{path:`team/${N}/task/${_}/manhour/add`,body:JSON.stringify(Y)},{path:`team/${N}/tasks/update3`,body:JSON.stringify({tasks:[{uuid:J,manhours:[z]}]})}],W=await R(K,`team/${N}/task/${_}/info`,{method:"GET",skipGoto:!0}),B=W.ok?v(W.parsed):null;let D="";for(const{path:P,body:C}of O){const E=await R(K,P,{method:"POST",body:C,skipGoto:!0}),j=I(E);if(!j){const F=await R(K,`team/${N}/task/${_}/info`,{method:"GET",skipGoto:!0});if(F.ok){const L=v(F.parsed);if(B===null?L!==null:L!==null&&Math.abs(L-B)>=1)return[{task:J,date:X,hours:String(Z),owner:q,endpoint:P}];D=`no effect (total_manhour ${String(B)} -> ${String(L)})`;continue}return[{task:J,date:X,hours:String(Z),owner:q,endpoint:P}]}D=j}throw new $("FETCH_ERROR",`ONES worklog: all endpoints failed (last: ${D})`)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as u,Strategy as y}from"@jackwener/opencli/registry";import{EmptyResultError as h}from"@jackwener/opencli/errors";import{OPENALEX_BASE as d,appendMailto as m,bareDoi as _,bareId as g,openalexFetch as x,requireBoundedInt as b,requireString as A}from"./utils.js";const f=["id","doi","title","publication_year","publication_date","cited_by_count","authorships","primary_location","open_access","type"].join(",");u({site:"openalex",name:"search",access:"read",description:"Search OpenAlex Works (papers, books, preprints) by keyword",domain:"api.openalex.org",strategy:y.PUBLIC,browser:!1,args:[{name:"query",positional:!0,required:!0,help:'Search text (e.g. "transformers", "open access scholarly")'},{name:"limit",type:"int",default:20,help:"Max works (1-200, single OpenAlex page)"}],columns:["rank","id","title","year","citations","firstAuthor","venue","openAccess","type","doi","url"],func:async(t)=>{const o=A(t.query,"query"),i=b(t.limit,20,200),s=m(`${d}/works?search=${encodeURIComponent(o)}&per-page=${i}&select=${f}`),a=await x(s,"openalex search"),n=Array.isArray(a?.results)?a.results:[];if(!n.length)throw new h("openalex search",`No OpenAlex works matched "${o}".`);return n.slice(0,i).map((e,p)=>{const l=Array.isArray(e.authorships)&&e.authorships.length?String(e.authorships[0]?.author?.display_name??"").trim():"",c=String(e.primary_location?.source?.display_name??"").trim(),r=g(e.id);return{rank:p+1,id:r,title:String(e.title??"").trim(),year:e.publication_year!=null?Number(e.publication_year):null,citations:e.cited_by_count!=null?Number(e.cited_by_count):null,firstAuthor:l,venue:c,openAccess:Boolean(e.open_access?.is_oa),type:String(e.type??"").trim(),doi:_(e.doi),url:r?`https://openalex.org/${r}`:""}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ArgumentError as L,CommandExecutionError as N,EmptyResultError as S}from"@jackwener/opencli/errors";export const OPENALEX_BASE="https://api.openalex.org";const T="opencli-openalex-adapter (+https://github.com/jackwener/opencli)",X=/^W\d{4,}$/,P=/^10\.\S+$/;export function requireString(G,z){const H=String(G??"").trim();if(!H)throw new L(`openalex ${z} cannot be empty`);return H}export function requireBoundedInt(G,z,H,J="limit"){const F=G??z,M=typeof F==="number"?F:Number(F);if(!Number.isInteger(M)||M<=0)throw new L(`openalex ${J} must be a positive integer`);if(M>H)throw new L(`openalex ${J} must be <= ${H}`);return M}export function requireWorkRef(G){const z=String(G??"").trim();if(!z)throw new L('openalex work id is required (e.g. "W2741809807", "10.7717/peerj.4375")');const H=z.match(/^https?:\/\/(?:api\.)?openalex\.org\/(?:works\/)?([WAaSCFwIPwT]\d+)/i);if(H){const F=H[1].toUpperCase();if(F[0]!=="W")throw new L(`openalex work id "${G}" must be a Work (W…) ID, got "${F[0]}…"`);return F}if(X.test(z.toUpperCase()))return z.toUpperCase();if(/^doi:/i.test(z)){const F=z.replace(/^doi:/i,"").trim();if(P.test(F))return`doi:${F}`}const J=z.match(/^https?:\/\/(?:dx\.)?doi\.org\/(.+)$/i);if(J&&P.test(J[1]))return`doi:${J[1]}`;if(P.test(z))return`doi:${z}`;throw new L(`openalex work id "${G}" is not recognised`,'Use a Work id ("W2741809807"), a DOI ("10.7717/peerj.4375"), or a full openalex.org / doi.org URL.')}export async function openalexFetch(G,z){let H;try{H=await fetch(G,{headers:{"user-agent":T,accept:"application/json"}})}catch(F){throw new N(`${z} request failed: ${F?.message??F}`,"Check that api.openalex.org is reachable from this network.")}if(H.status===404)throw new S(z,`OpenAlex returned 404 for ${G}.`);if(H.status===429)throw new N(`${z} returned HTTP 429 (rate limited)`,"OpenAlex throttles unauthenticated traffic; wait a few seconds and retry, or set OPENALEX_MAILTO.");if(!H.ok){let F="";try{const Q=(await H.text()).match(/"message"\s*:\s*"([^"]+)"/);if(Q)F=` (${Q[1]})`}catch{}throw new N(`${z} returned HTTP ${H.status}${F}`)}let J;try{J=await H.json()}catch(F){throw new N(`${z} returned malformed JSON: ${F?.message??F}`)}return J}export function bareId(G){const z=String(G??"").trim();if(!z)return"";return z.replace(/^https?:\/\/(?:api\.)?openalex\.org\//i,"").replace(/^works\//i,"")}export function bareDoi(G){const z=String(G??"").trim();if(!z)return"";return z.replace(/^https?:\/\/(?:dx\.)?doi\.org\//i,"")}export function reconstructAbstract(G){if(!G||typeof G!=="object")return"";const z=[];for(const[H,J]of Object.entries(G)){if(!Array.isArray(J))continue;for(const F of J)if(Number.isInteger(F)&&F>=0&&F<1e5)z[F]=H}return z.filter(Boolean).join(" ").replace(/\s+/g," ").trim()}export function appendMailto(G){const z=process.env.OPENALEX_MAILTO?.trim();if(!z)return G;const H=G.includes("?")?"&":"?";return`${G}${H}mailto=${encodeURIComponent(z)}`}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as l,Strategy as p}from"@jackwener/opencli/registry";import{OPENALEX_BASE as d,appendMailto as u,bareDoi as _,bareId as g,openalexFetch as m,reconstructAbstract as b,requireWorkRef as y}from"./utils.js";const f=["id","doi","title","publication_year","publication_date","cited_by_count","authorships","primary_location","open_access","type","referenced_works","related_works","language","abstract_inverted_index"].join(",");l({site:"openalex",name:"work",access:"read",description:"Fetch a single OpenAlex Work (paper / preprint / book) — metadata + abstract",domain:"api.openalex.org",strategy:p.PUBLIC,browser:!1,args:[{name:"id",positional:!0,required:!0,help:'OpenAlex Work id ("W2741809807"), DOI ("10.7717/peerj.4375"), or full URL'}],columns:["id","title","type","year","date","language","authors","venue","citations","openAccess","openAccessUrl","referencedCount","doi","abstract","url"],func:async(t)=>{const o=y(t.id),a=u(`${d}/works/${encodeURIComponent(o)}?select=${f}`),e=await m(a,"openalex work"),n=Array.isArray(e.authorships)?e.authorships.map((c)=>String(c?.author?.display_name??"").trim()).filter(Boolean).join(", "):"",i=String(e.primary_location?.source?.display_name??"").trim(),r=g(e.id),s=String(e.open_access?.oa_url??"").trim();return[{id:r,title:String(e.title??"").trim(),type:String(e.type??"").trim(),year:e.publication_year!=null?Number(e.publication_year):null,date:String(e.publication_date??"").trim(),language:String(e.language??"").trim(),authors:n,venue:i,citations:e.cited_by_count!=null?Number(e.cited_by_count):null,openAccess:Boolean(e.open_access?.is_oa),openAccessUrl:s,referencedCount:Array.isArray(e.referenced_works)?e.referenced_works.length:null,doi:_(e.doi),abstract:b(e.abstract_inverted_index),url:r?`https://openalex.org/${r}`:""}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as X,Strategy as Y}from"@jackwener/opencli/registry";import{EmptyResultError as Z}from"@jackwener/opencli/errors";import{OPENFDA_BASE as $,firstOrNull as v,joinOrNull as C,openfdaFetch as D,requireBoundedInt as I,requireString as P}from"./utils.js";X({site:"openfda",name:"drug-label",access:"read",description:"Search FDA-approved drug labels (brand or generic name)",domain:"fda.gov",strategy:Y.PUBLIC,browser:!1,args:[{name:"query",positional:!0,required:!0,help:'Brand or generic drug name (e.g. "aspirin", "lisinopril")'},{name:"limit",type:"int",default:5,help:"Max rows (1-25, default 5; openFDA caps anonymous tier at 25/page)"}],columns:["rank","id","brandName","genericName","manufacturer","productType","route","productNdc","pharmClass","purpose","indications","warnings","dosage","effectiveTime"],func:async(H)=>{const G=P(H.query,"query"),L=I(H.limit,5,25),M=`openfda.brand_name:"${G}"`,Q=`openfda.generic_name:"${G}"`,T=`${encodeURIComponent(M)}+OR+${encodeURIComponent(Q)}`,U=`${$}/drug/label.json?search=${T}&limit=${L}`,J=await D(U,"openfda drug-label"),K=Array.isArray(J?.results)?J.results:[];if(!K.length)throw new Z("openfda drug-label",`openFDA returned no labels matching "${G}".`);return K.map((z,V)=>{const x=z?.openfda??{},W=v(x.pharm_class_epc)??v(x.pharm_class_moa)??v(x.pharm_class_cs)??v(x.pharm_class_pe);return{rank:V+1,id:z?.id??null,brandName:v(x.brand_name),genericName:v(x.generic_name),manufacturer:v(x.manufacturer_name),productType:v(x.product_type),route:C(x.route),productNdc:v(x.product_ndc),pharmClass:W,purpose:v(z.purpose),indications:v(z.indications_and_usage),warnings:v(z.warnings),dosage:v(z.dosage_and_administration),effectiveTime:z?.effective_time??null}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as Q,Strategy as T}from"@jackwener/opencli/registry";import{EmptyResultError as U}from"@jackwener/opencli/errors";import{OPENFDA_BASE as V,openfdaFetch as W,requireBoundedInt as X}from"./utils.js";Q({site:"openfda",name:"food-recall",access:"read",description:"FDA food recall and enforcement actions (most recent first)",domain:"fda.gov",strategy:T.PUBLIC,browser:!1,args:[{name:"query",help:'Free-text Lucene query (e.g. "salmonella", "listeria"); default: all recent recalls'},{name:"status",help:'Filter by status: "Ongoing", "Completed", "Terminated"'},{name:"classification",help:'Filter by class: "Class I" (most serious), "Class II", "Class III"'},{name:"limit",type:"int",default:10,help:"Max rows (1-100, default 10; openFDA caps anonymous tier at 100/page)"}],columns:["rank","recallNumber","status","classification","voluntary","recallingFirm","city","state","country","productDescription","reasonForRecall","productQuantity","distributionPattern","reportDate","recallInitiationDate","terminationDate"],func:async(x)=>{const C=X(x.limit,10,100),z=[];if(x.query)z.push(String(x.query).trim());if(x.status)z.push(`status:"${String(x.status).trim()}"`);if(x.classification)z.push(`classification:"${String(x.classification).trim()}"`);const J=z.length?`search=${z.map((v)=>encodeURIComponent(v)).join("+AND+")}&limit=${C}`:`limit=${C}`,K=`${V}/food/enforcement.json?${J}`,G=await W(K,"openfda food-recall"),H=Array.isArray(G?.results)?G.results:[];if(!H.length)throw new U("openfda food-recall","openFDA returned no food recall records matching the filter.");return H.map((v,M)=>({rank:M+1,recallNumber:v?.recall_number??null,status:v?.status??null,classification:v?.classification??null,voluntary:v?.voluntary_mandated??null,recallingFirm:v?.recalling_firm??null,city:v?.city??null,state:v?.state??null,country:v?.country??null,productDescription:v?.product_description??null,reasonForRecall:v?.reason_for_recall??null,productQuantity:v?.product_quantity??null,distributionPattern:v?.distribution_pattern??null,reportDate:v?.report_date??null,recallInitiationDate:v?.recall_initiation_date??null,terminationDate:v?.termination_date??null}))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ArgumentError as H,EmptyResultError as I,CommandExecutionError as G}from"@jackwener/opencli/errors";export const OPENFDA_BASE="https://api.fda.gov";const J="opencli-openfda/1.0";export function requireString(q,z){if(typeof q!=="string"||!q.trim())throw new H(`--${z} is required`);return q.trim()}export function requireBoundedInt(q,z,B,F="limit"){const D=q==null||q===""?z:Number(q);if(!Number.isInteger(D)||D<1||D>B)throw new H(`--${F} must be an integer between 1 and ${B}`);return D}export async function openfdaFetch(q,z){let B;try{B=await fetch(q,{headers:{"User-Agent":J,accept:"application/json"}})}catch(D){throw new G(`${z} request failed: ${D.message}`)}if(B.status===404)throw new I(z,`${z} returned 404 (no matches).`);if(B.status===429)throw new G(`${z} rate-limited (HTTP 429); back off and retry.`);if(!B.ok)throw new G(`${z} returned HTTP ${B.status}.`);let F;try{F=await B.json()}catch(D){throw new G(`${z} returned non-JSON body: ${D.message}`)}return F}export function firstOrNull(q){if(!Array.isArray(q)||!q.length)return null;const z=q[0];if(typeof z!=="string")return z??null;const B=z.trim();return B.length?B:null}export function joinOrNull(q,z=5){if(!Array.isArray(q)||!q.length)return null;return q.slice(0,z).map(String).join(", ")}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as u,Strategy as l}from"@jackwener/opencli/registry";import{EmptyResultError as d}from"@jackwener/opencli/errors";import{noteToRow as h,openreviewFetch as f,requireBoundedInt as c,requireProfileId as m}from"./utils.js";u({site:"openreview",name:"author",access:"read",description:"List OpenReview submissions by an author profile id (newest first)",domain:"openreview.net",strategy:l.PUBLIC,browser:!1,args:[{name:"profile",positional:!0,required:!0,help:'OpenReview profile id (e.g. "~Yoshua_Bengio1"). Find it on the author profile URL on openreview.net.'},{name:"limit",type:"int",default:50,help:"Max submissions (1-1000)"}],columns:["rank","id","title","authors","venue","pdate","url"],func:async(t)=>{const i=m(t.profile),o=c(t.limit,50,1000),s=`/notes?content.authorids=${encodeURIComponent(i)}&limit=${o}&sort=cdate:desc`,r=await f(s,`openreview author ${i}`),n=Array.isArray(r?.notes)?r.notes:[];if(!n.length)throw new d("openreview author",`No OpenReview submissions found for profile "${i}". Confirm the id format (~First_LastN) and that the profile has public submissions.`);return n.slice(0,o).map((a,p)=>{const e=h(a);return{rank:p+1,id:e.id,title:e.title,authors:e.authors,venue:e.venue,pdate:e.pdate,url:e.url}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as i,Strategy as p}from"@jackwener/opencli/registry";import{EmptyResultError as s}from"@jackwener/opencli/errors";import{noteToRow as d,openreviewFetch as u,requireForumId as m}from"./utils.js";i({site:"openreview",name:"paper",access:"read",description:"Show full metadata for a single OpenReview paper",domain:"openreview.net",strategy:p.PUBLIC,browser:!1,args:[{name:"id",positional:!0,required:!0,help:'OpenReview note id (e.g. "5sRnsubyAK")'}],columns:["id","title","authors","keywords","venue","venueid","primary_area","abstract","pdate","pdf","url"],func:async(a)=>{const r=m(a.id),n=`/notes?id=${encodeURIComponent(r)}`,t=await u(n,`openreview paper ${r}`),o=Array.isArray(t?.notes)?t.notes:[];if(!o.length)throw new s("openreview",`No paper found with id "${r}". Confirm the forum/note id from openreview.net.`);const e=d(o[0]);return[{id:e.id,title:e.title,authors:e.authors,keywords:e.keywords,venue:e.venue,venueid:e.venueid,primary_area:e.primary_area,abstract:e.abstract,pdate:e.pdate,pdf:e.pdf,url:e.url}]}});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{cli as _,Strategy as A}from"@jackwener/opencli/registry";import{ArgumentError as N,EmptyResultError as T}from"@jackwener/opencli/errors";import{coerceInt as k,openreviewFetch as $,readContent as Y,requireForumId as b}from"./utils.js";const j=[["summary","Summary"],["strengths","Strengths"],["weaknesses","Weaknesses"],["questions","Questions"],["comment","Comment"],["rebuttal","Rebuttal"],["decision","Decision"],["recommendation","Recommendation"],["title","Title"],["abstract","Abstract"],["withdrawal_confirmation","Withdrawal confirmation"]];function C(B){if(!Array.isArray(B))return"";for(const z of B){const G=String(z).match(/\/-\/([^/]+)$/);if(G)return G[1]}return""}function J(B,z){if(z)return"PAPER";const G=C(B?.invitations).toLowerCase();if(G.includes("decision"))return"DECISION";if(G.includes("withdrawal"))return"WITHDRAWAL";if(G.includes("rebuttal"))return"REBUTTAL";if(G.includes("meta"))return"META_REVIEW";if(G.includes("review"))return"REVIEW";if(G.includes("comment"))return"COMMENT";return G?G.toUpperCase():"NOTE"}function R(B){if(!Array.isArray(B)||!B.length)return"";const z=String(B[0]);if(z.startsWith("~"))return z.replace(/^~/,"").replace(/\d+$/,"").replace(/_/g," ").trim();const G=z.split("/");return G[G.length-1]||z}function w(B){const z=[];for(const[G,Q]of j){const K=Y(B,G);if(K===void 0||K===null)continue;const U=(Array.isArray(K)?K.join(", "):String(K)).replace(/\r\n/g,`
|
|
2
|
+
`).trim();if(!U)continue;z.push(`${Q}: ${U}`)}return z.join(`
|
|
3
|
+
|
|
4
|
+
`)}function E(B,z){if(B.length<=z)return B;return`${B.slice(0,z-3)}...`}_({site:"openreview",name:"reviews",access:"read",description:"Show full review thread (paper + reviews + decisions) for an OpenReview forum",domain:"openreview.net",strategy:A.PUBLIC,browser:!1,args:[{name:"forum",positional:!0,required:!0,help:"OpenReview forum id (same as paper id)"},{name:"max-length",type:"int",default:4000,help:"Per-row text truncation (min 200)"}],columns:["type","author","rating","confidence","text"],func:async(B)=>{const z=b(B.forum,"forum"),G=B["max-length"]??B.maxLength??4000,Q=k(G);if(!Number.isInteger(Q)||Q<200)throw new N("openreview reviews max-length must be an integer >= 200");const K=await $(`/notes?id=${encodeURIComponent(z)}`,`openreview paper ${z}`),U=(Array.isArray(K?.notes)?K.notes:[])[0];if(!U)throw new T("openreview",`No forum found with id "${z}". Confirm the forum id from openreview.net.`);const Z=await $(`/notes?forum=${encodeURIComponent(z)}&details=replies&limit=1000`,`openreview reviews ${z}`),D=[...Array.isArray(Z?.notes)?Z.notes.filter((H)=>H?.id!==z):[]].sort((H,V)=>(H?.cdate??0)-(V?.cdate??0));return[U,...D].map((H)=>{const V=H?.id===z,M=J(H,V),O=R(H?.signatures),W=Y(H?.content,"rating"),X=Y(H?.content,"confidence"),P=E(w(H?.content),Q);return{type:M,author:O,rating:W===void 0||W===null?"":String(W),confidence:X===void 0||X===null?"":String(X),text:P}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as u,Strategy as m}from"@jackwener/opencli/registry";import{ArgumentError as c,EmptyResultError as l}from"@jackwener/opencli/errors";import{noteToRow as d,openreviewFetch as w,requireBoundedInt as h}from"./utils.js";u({site:"openreview",name:"search",access:"read",description:"Search OpenReview papers by free-text query",domain:"openreview.net",strategy:m.PUBLIC,browser:!1,args:[{name:"query",positional:!0,required:!0,help:'Search keyword (e.g. "diffusion model")'},{name:"limit",type:"int",default:25,help:"Max results (max 50)"}],columns:["rank","id","title","authors","venue","pdate","url"],func:async(t)=>{const r=String(t.query??"").trim();if(!r)throw new c("openreview search query cannot be empty");const n=h(t.limit,25,50),a=`/notes/search?term=${encodeURIComponent(r)}&type=terms&limit=${n}`,o=await w(a,"openreview search"),i=Array.isArray(o?.notes)?o.notes:[];if(!i.length)throw new l("openreview",`No papers found for "${r}". Try a different keyword.`);return i.slice(0,n).map((s,p)=>{const e=d(s);return{rank:p+1,id:e.id,title:e.title,authors:e.authors,venue:e.venue,pdate:e.pdate,url:e.url}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ArgumentError as U,CommandExecutionError as Z}from"@jackwener/opencli/errors";export const OPENREVIEW_API="https://api2.openreview.net",OPENREVIEW_BASE="https://openreview.net";const $=/^[A-Za-z0-9_-]{6,20}$/;export function coerceInt(z){if(z===void 0||z===null||z==="")return NaN;const q=typeof z==="number"?z:Number(z);return Number.isFinite(q)&&Number.isInteger(q)?q:NaN}export function requireBoundedInt(z,q,G,J="limit"){const Q=coerceInt(z??q);if(!Number.isInteger(Q)||Q<=0)throw new U(`openreview ${J} must be a positive integer`);if(Q>G)throw new U(`openreview ${J} must be <= ${G}`);return Q}export function requireNonNegativeInt(z,q,G="offset"){const H=coerceInt(z??q);if(!Number.isInteger(H)||H<0)throw new U(`openreview ${G} must be a non-negative integer`);return H}export function requireForumId(z,q="id"){const G=String(z??"").trim();if(!G)throw new U(`openreview ${q} is required`);if(!$.test(G))throw new U(`openreview ${q} "${z}" is not a valid forum id (expected 6-20 chars of [A-Za-z0-9_-])`);return G}const F=/^~(?=.*\p{L})[\p{L}\p{M}0-9._-]+\d+$/u;export function requireProfileId(z,q="profile"){const G=String(z??"").trim();if(!G)throw new U(`openreview ${q} is required`);if(!F.test(G))throw new U(`openreview ${q} "${z}" is not a valid profile id (expected "~First_Last1" or similar; find it on the author's openreview.net profile URL)`);return G}export async function openreviewFetch(z,q){const G=`${OPENREVIEW_API}${z}`;let J;try{J=await fetch(G)}catch(K){throw new Z(`Network failure fetching ${q}: ${K?.message??K}`,"Check your network connection and try again.")}if(J.status===404)return null;if(!J.ok){let K="";try{K=(await J.text()).slice(0,200)}catch{}throw new Z(`OpenReview API HTTP ${J.status} for ${q}${K?` (${K})`:""}`,"The OpenReview API may be down or rate-limiting.")}let H;try{H=await J.json()}catch(K){throw new Z(`Malformed JSON from OpenReview for ${q}: ${K?.message??K}`,"Try again or report this as an OpenReview API bug.")}const Q=Array.isArray(H?.errors)?H.errors.filter(Boolean):[],X=typeof H?.error==="string"?H.error.trim():"";if(Q.length||X){const K=X||Q.map((Y)=>{if(typeof Y==="string")return Y;if(Y?.message)return String(Y.message);return JSON.stringify(Y)}).join("; ");throw new Z(`OpenReview API error for ${q}: ${K}`,"The OpenReview API returned an application-level error.")}return H}export function formatDate(z){if(typeof z!=="number"||!Number.isFinite(z)||z<=0)return"";return new Date(z).toISOString().slice(0,10)}export function readContent(z,q){const G=z?.[q]?.value;if(G===void 0||G===null)return;return G}export function absolutePdf(z){const q=String(z??"").trim();if(!q)return"";if(/^https?:\/\//.test(q))return q;if(q.startsWith("/"))return`${OPENREVIEW_BASE}${q}`;return`${OPENREVIEW_BASE}/${q}`}function M(z){return String(z||"").replace(/^~/,"").replace(/\d+$/,"").replace(/_/g," ").trim()}export function noteToRow(z){const q=z?.content??{},G=z?.id??"",J=readContent(q,"authors"),H=readContent(q,"authorids");let Q="";if(Array.isArray(J)&&J.length)Q=J.join(", ");else if(Array.isArray(H)&&H.length)Q=H.map(M).join(", ");const X=readContent(q,"keywords"),K=Array.isArray(X)?X.join(", "):String(X??"");return{id:G,title:String(readContent(q,"title")??"").replace(/\s+/g," ").trim(),authors:Q,keywords:K,venue:String(readContent(q,"venue")??"").trim(),venueid:String(readContent(q,"venueid")??"").trim(),primary_area:String(readContent(q,"primary_area")??"").trim(),abstract:String(readContent(q,"abstract")??"").replace(/\s+/g," ").trim(),pdate:formatDate(z?.pdate??z?.cdate),pdf:absolutePdf(readContent(q,"pdf")),url:G?`${OPENREVIEW_BASE}/forum?id=${G}`:""}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as p,Strategy as m}from"@jackwener/opencli/registry";import{ArgumentError as f,EmptyResultError as d}from"@jackwener/opencli/errors";import{noteToRow as v,openreviewFetch as w,requireBoundedInt as h,requireNonNegativeInt as y}from"./utils.js";p({site:"openreview",name:"venue",access:"read",description:'List papers at an OpenReview venue (e.g. "ICLR 2024 oral" or full invitation id)',domain:"openreview.net",strategy:m.PUBLIC,browser:!1,args:[{name:"venue",positional:!0,required:!0,help:'Venue name ("ICLR 2024 oral") or invitation ("ICLR.cc/2025/Conference/-/Submission")'},{name:"limit",type:"int",default:25,help:"Max results (max 200)"},{name:"offset",type:"int",default:0,help:"Pagination offset"}],columns:["rank","id","title","authors","keywords","primary_area","pdate","pdf","url"],func:async(n)=>{const t=String(n.venue??"").trim();if(!t)throw new f("openreview venue cannot be empty");const i=h(n.limit,25,200),o=y(n.offset,0),r=t.includes("/-/"),l=`/notes?${r?`invitation=${encodeURIComponent(t)}`:`content.venue=${encodeURIComponent(t)}`}&limit=${i}&offset=${o}`,a=await w(l,`openreview venue ${t}`),s=Array.isArray(a?.notes)?a.notes:[];if(!s.length)throw new d("openreview",`No papers found at venue "${t}". ${r?'Check the invitation id (e.g. "ICLR.cc/2025/Conference/-/Submission").':'Try a venue text like "ICLR 2024 oral" or pass a full invitation id.'}`);return s.slice(0,i).map((u,c)=>{const e=v(u);return{rank:o+c+1,id:e.id,title:e.title,authors:e.authors,keywords:e.keywords,primary_area:e.primary_area,pdate:e.pdate,pdf:e.pdf,url:e.url}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{CliError as V,CommandExecutionError as A}from"@jackwener/opencli/errors";import{cli as F,Strategy as O}from"@jackwener/opencli/registry";import{readFile as _,stat as q}from"node:fs/promises";import{publishArticle as T}from"../_shared/article/publish.js";export const oschinaProfile={home:"https://my.oschina.net",outputFormat:"markdown",image:{spec:{url:"https://apiv1.oschina.net/oschinapi/ai/creation/project/uploadDetail",method:"POST",bodyType:"binary-multipart",fileField:"file",fileName:"image",body:{},responsePath:"result"},skip:["apiv1.oschina.net","oscimg.oschina.net","static.oschina.net"]},checkAuth:async()=>{const G=await fetch("https://apiv1.oschina.net/oschinapi/user/myDetails",{credentials:"include"});if(!G.ok)return{isAuthenticated:!1,error:"HTTP "+G.status};let z=null;try{z=await G.json()}catch(U){return{isAuthenticated:!1,error:"解析响应失败"}}if(!z||!z.success||!z.result||!z.result.userId)return{isAuthenticated:!1,error:z&&z.message||"未登录"};const B=String(z.result.userId),M=z.result.userVo&&z.result.userVo.name||B,Q=z.result.userVo&&z.result.userVo.portraitUrl||"";return{isAuthenticated:!0,userId:B,username:M,avatar:Q}},publish:async(G)=>{const z=G.params||{};let B="";try{const L=await(await fetch("https://apiv1.oschina.net/oschinapi/user/myDetails",{credentials:"include"})).json();if(L&&L.success&&L.result&&L.result.userId)B=String(L.result.userId)}catch(K){}if(!B)return{ok:!1,stage:"auth",status:401,message:"未登录开源中国,无法获取用户 ID"};let M=0;if(z.category){let K=[];try{const X=await(await fetch("https://apiv1.oschina.net/oschinapi/blog_catalog/list_by_user",{credentials:"include"})).json();K=X&&X.result||[]}catch(H){return{ok:!1,stage:"category",message:"获取开源中国博客分类失败:"+String(H&&H.message||H)}}const L=K.find((H)=>String(H.name)===String(z.category));if(!L)return{ok:!1,stage:"category",message:"未找到博客分类「"+z.category+"」,可选:"+(K.map((H)=>H.name).join(" / ")||"(你还没有任何分类)")};M=L.id}if(G.draftOnly){const K=await fetch("https://apiv1.oschina.net/oschinapi/api/draft/save_draft",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:G.title,user:Number(B),content:G.content,contentType:1,catalog:M,originUrl:"",privacy:!0,disableComment:!1})}),L=await K.text();let H=null;try{H=JSON.parse(L)}catch(S){}if(!K.ok||!H||!H.success||!H.result||!H.result.id)return{ok:!1,stage:"save_draft",status:K.status,message:H&&H.message||L.slice(0,300)};const X=String(H.result.id);return{ok:!0,draft:!0,id:X,url:"https://my.oschina.net/u/"+B+"/blog/ai-write/draft/"+X}}const Q=await fetch("https://apiv1.oschina.net/oschinapi/blog/web/add",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:G.title,content:G.content,contentType:1,type:"1",originUrl:"",catalog:M,privacy:!1,disableComment:!1,isAiRelated:!1,user:Number(B)})}),U=await Q.text();let J=null;try{J=JSON.parse(U)}catch(K){}if(!Q.ok||!J||J.code!==200||J.result==null)return{ok:!1,stage:"publish",status:Q.status,message:J&&(J.message||J.msg)||U.slice(0,300)};const W=String(J.result);return{ok:!0,draft:!1,id:W,url:"https://my.oschina.net/u/"+B+"/blog/"+W}}};function Y(G){if(!G.execute)throw new V("INVALID_INPUT","发布开源中国文章需要 --execute 参数。注意:本报错仅表示缺少 --execute,并未校验其余参数,不能当 dry-run 预览用")}function Z(G,z,B,M,Q={}){return[{status:"success",outcome:M,message:G,target_type:z,target:B,...Q}]}async function $(G){const z=typeof G.text==="string"?G.text:void 0,B=typeof G.file==="string"?G.file:void 0;if(z&&B)throw new V("INVALID_INPUT","正文和文件路径只能二选一,不能同时指定");let M=z??"";if(B){let Q;try{Q=await q(B)}catch{throw new V("INVALID_INPUT","文件不存在:"+B)}if(!Q.isFile())throw new V("INVALID_INPUT","必须指定可读的文本文件:"+B);let U;try{U=await _(B)}catch{throw new V("INVALID_INPUT","文件读取失败:"+B)}try{M=new TextDecoder("utf-8",{fatal:!0}).decode(U)}catch{throw new V("INVALID_INPUT","文件编码不是 UTF-8:"+B)}}if(!M.trim())throw new V("INVALID_INPUT","文章正文不能为空");return M}F({site:"oschina",name:"article",access:"write",description:"发布文章到开源中国博客。默认正式发布,加 --draft 仅存草稿。正文默认 Markdown,外链图片自动转存到开源中国图床。",domain:"my.oschina.net",strategy:O.COOKIE,browser:!0,args:[{name:"title",positional:!0,required:!0,help:"文章标题"},{name:"text",positional:!0,help:"文章正文(默认 Markdown;--html 表示原始 HTML)"},{name:"file",help:"从文件读取正文(UTF-8,默认 Markdown)"},{name:"html",type:"boolean",help:"将正文视为原始 HTML 而非 Markdown"},{name:"category",help:"个人博客分类名(精确匹配),合法值用 `oschina catalogs` 列举;可空=不分类"},{name:"draft",type:"boolean",help:"仅存草稿,不发布"},{name:"execute",type:"boolean",help:"真正执行写操作;不加此参数命令拒绝写入"}],columns:["status","outcome","message","target_type","target","created_target","created_url"],func:async(G,z)=>{if(!G)throw new A("开源中国文章发布需要浏览器会话");Y(z);const B=String(z.title??"").trim();if(!B)throw new V("INVALID_INPUT","文章标题不能为空");const M=await $(z),Q=Boolean(z.draft),U={category:typeof z.category==="string"?z.category.trim():""},J=await T(G,{title:B,body:M,format:z.html?"html":"markdown",draftOnly:Q,profile:oschinaProfile,publishParams:U}),W=J.images.uploaded.length|0,K=J.images.failed.length|0;let L=J.draft?"已保存到开源中国草稿箱":"已正式发布到开源中国博客";if(W||K)L+=`·图片:${W} 张已转存${K?`,${K} 张失败`:""}`;return Z(L,"article","",J.draft?"draft":"created",{created_target:(J.draft?"draft:":"article:")+J.id,created_url:J.url})}});export const __test__={oschinaProfile,requireExecute:Y,buildResultRow:Z,resolvePayload:$};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as z,Strategy as B}from"@jackwener/opencli/registry";import{CommandExecutionError as F}from"@jackwener/opencli/errors";import{gotoWritePage as G}from"../_shared/article/publish.js";import{oschinaProfile as H}from"./article.js";z({site:"oschina",name:"catalogs",access:"read",description:"列出当前用户的开源中国个人博客分类(id + 名称),供 `oschina article --category` 取合法分类名。",domain:"my.oschina.net",strategy:B.COOKIE,browser:!0,columns:["catalog_id","catalog_name"],func:async(q)=>{if(!q)throw new F("开源中国分类列举需要浏览器会话");await G(q,H.home);const v=await q.evaluate("(async () => {const r = await fetch('https://apiv1.oschina.net/oschinapi/blog_catalog/list_by_user', { credentials: 'include' });const j = await r.json();return ((j && j.result) || []).map(c => ({ catalog_id: String(c.id), catalog_name: c.name || '' }));})()");return Array.isArray(v)?v:[]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{registerArticleLogin as k}from"../_shared/article/login.js";import{oschinaProfile as b}from"./article.js";k({site:"oschina",domain:"oschina.net",profile:{home:b.home,originRe:b.originRe,checkAuth:b.checkAuth},loginDescription:"打开开源中国登录页并等待浏览器完成登录(供桌面客户端引导登录)。"});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import{cli as Y,Strategy as $}from"@jackwener/opencli/registry";import{CliError as I}from"@jackwener/opencli/errors";const J=10,X=30;function Z(h,H){return`
|
|
2
|
+
async () => {
|
|
3
|
+
const API = 'https://apiv1.oschina.net/oschinapi';
|
|
4
|
+
const LIMIT = ${JSON.stringify(h)};
|
|
5
|
+
const USER_ARG = ${JSON.stringify(H)};
|
|
6
|
+
const PAGE_SIZE = ${J};
|
|
7
|
+
const MAX_PAGES = ${X};
|
|
8
|
+
const getJson = async (url) => {
|
|
9
|
+
const resp = await fetch(url, { credentials: 'include' });
|
|
10
|
+
const text = await resp.text();
|
|
11
|
+
let data = null;
|
|
12
|
+
try { data = JSON.parse(text); } catch (e) {}
|
|
13
|
+
return { status: resp.status, data, textHint: data ? '' : text.slice(0, 200) };
|
|
14
|
+
};
|
|
15
|
+
// 逐页拉列表接口(result.list / result.count 结构,页面自身即如此翻页)
|
|
16
|
+
const fetchList = async (base) => {
|
|
17
|
+
const rows = [];
|
|
18
|
+
for (let pageNum = 1; pageNum <= MAX_PAGES && rows.length < LIMIT; pageNum++) {
|
|
19
|
+
const sep = base.includes('?') ? '&' : '?';
|
|
20
|
+
const r = await getJson(API + base + sep + 'pageNum=' + pageNum + '&pageSize=' + PAGE_SIZE);
|
|
21
|
+
if (!r.data || r.data.code !== 200) {
|
|
22
|
+
return { rows, error: 'HTTP ' + r.status + ' ' + ((r.data && r.data.message) || r.textHint) };
|
|
23
|
+
}
|
|
24
|
+
const list = (r.data.result && r.data.result.list) || [];
|
|
25
|
+
rows.push(...list);
|
|
26
|
+
// 注意:result.count 是本页条数不是总数(官方 SPA 即以 count<pageSize 判「没有更多」)
|
|
27
|
+
if (list.length < PAGE_SIZE) break;
|
|
28
|
+
}
|
|
29
|
+
return { rows: rows.slice(0, LIMIT), error: null };
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const out = {};
|
|
33
|
+
// 1) 登录态 + 当前用户
|
|
34
|
+
const auth = await getJson(API + '/user/myDetails');
|
|
35
|
+
const me = auth.data && auth.data.success && auth.data.result && auth.data.result.userId
|
|
36
|
+
? String(auth.data.result.userId) : '';
|
|
37
|
+
out.me = me;
|
|
38
|
+
if (!me) { out.notLoggedIn = true; return out; }
|
|
39
|
+
|
|
40
|
+
const targetUser = USER_ARG ? String(USER_ARG) : me;
|
|
41
|
+
out.targetUser = targetUser;
|
|
42
|
+
out.isSelf = targetUser === me;
|
|
43
|
+
|
|
44
|
+
// 2) 公开列表(带 viewCount 等全量指标)
|
|
45
|
+
out.pub = await fetchList('/blog/otherUser/web?userId=' + encodeURIComponent(targetUser));
|
|
46
|
+
|
|
47
|
+
// 3) 查自己时再拉后台列表(含私密博客)与定时未发布
|
|
48
|
+
if (out.isSelf) {
|
|
49
|
+
out.mine = await fetchList('/blog/my/web');
|
|
50
|
+
out.scheduled = await fetchList('/blog/my/unpublished/web');
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
`}function f(h){if(h&&typeof h==="object"&&!Array.isArray(h)&&"session"in h&&"data"in h)return h.data;return h}function U(h){return typeof h==="number"&&Number.isFinite(h)?h:""}function W(h,H,Q,T,q){const F=h.id!=null?String(h.id):"",N=T&&F?T.get(F):null,B=(z)=>h[z]!=null?h[z]:N?N[z]:void 0,K=Number(B("type")),O={};for(const[z,D]of Object.entries({reply_count:U(B("replyCount")),state:B("state"),as_recomm:h.asRecomm,detritus:B("detritus"),scheduled_time:h.scheduledTime,scheduled_state:h.scheduledState,summary:typeof B("detail")==="string"?String(B("detail")).slice(0,80):void 0}))if(D!==void 0&&D!==null&&D!=="")O[z]=D;return{id:F,type:"博客",title:h.title!=null?String(h.title):"",url:F&&H?`https://my.oschina.net/u/${H}/blog/${F}`:"",published_at:B("createTime")||"",views:U(B("viewCount")),likes:U(B("voteCount")),comments:U(B("commentCount")),collects:"",shares:"",origin:K===2?"转载":K===1?"原创":"",is_private:Q!=="已发布"?"":q||N?"否":"是",recommended:Number(B("recomm"))===1?"推荐":"",top:Number(B("asTop"))===1?"置顶":"",status:Q,extra:Object.keys(O).length?JSON.stringify(O):""}}Y({site:"oschina",name:"stats",access:"read",description:"开源中国博客数据(每篇阅读/点赞/评论等全量运营指标)",domain:"my.oschina.net",strategy:$.COOKIE,browser:!0,args:[{name:"limit",type:"number",default:20,help:"返回条数"},{name:"user",help:"查看指定用户 ID 的公开博客数据(默认当前登录账号,含私密与定时博客)"}],columns:["id","type","title","url","published_at","views","likes","comments","collects","shares","origin","is_private","recommended","top","status","extra"],func:async(h,H)=>{const Q=Number(H.limit)||20,T=H.user!=null&&String(H.user).trim()!==""?String(H.user).trim():"";await h.goto("https://my.oschina.net/");await h.wait(1);const q=f(await h.evaluate(Z(Q,T)));if(!q||typeof q!=="object")throw Error("开源中国页面取数失败:未拿到任何响应,请确认 Chrome 已打开且能访问 my.oschina.net。");if(q.notLoggedIn)throw Error("未登录开源中国:user/myDetails 未返回用户信息。请先在 Chrome 中登录 my.oschina.net(可用 opencli oschina login)。");const F=String(q.targetUser||q.me||""),N=q.pub&&q.pub.rows||[];if(q.pub&&q.pub.error)throw Error("获取开源中国博客公开列表失败:"+q.pub.error);const B=new Map(N.filter((z)=>z&&z.id!=null).map((z)=>[String(z.id),z])),K=[],O=new Set;if(q.isSelf){if(q.mine&&q.mine.error)throw Error("获取开源中国「我的创作」博客列表失败:"+q.mine.error);for(const z of q.mine&&q.mine.rows||[]){const D=W(z,F,"已发布",B);if(D.id)O.add(D.id);K.push(D)}for(const z of N){const D=z&&z.id!=null?String(z.id):"";if(!D||O.has(D))continue;O.add(D);K.push(W(z,F,"已发布",null,!0))}for(const z of q.scheduled&&q.scheduled.rows||[])K.push(W(z,F,"已定时未发布",null,!1))}else for(const z of N)K.push(W(z,F,"已发布",null,!0));if(K.length===0)throw new I("EMPTY_RESULT",q.isSelf?"当前开源中国账号没有任何博客(已发布/定时均为空)。":`用户 ${F} 没有任何公开博客。`,q.isSelf?"发布过内容后再来查看数据(opencli oschina article)。":"请确认用户 ID 是否正确。");return K.slice(0,Q)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as v,Strategy as x}from"@jackwener/opencli/registry";import{checkLogin as z,cookieQuickCheck as A}from"../_shared/article/auth.js";import{oschinaProfile as m}from"./article.js";const B={home:m.home,checkAuth:m.checkAuth};v({site:"oschina",name:"whoami",access:"read",description:"查询当前开源中国登录账号信息(登录状态 / 用户 ID / 用户名)。",domain:"my.oschina.net",strategy:x.COOKIE,browser:!0,columns:["logged_in","user_id","username"],authStatus:{quickCheck:A("https://my.oschina.net",["oscid"])},func:async(q)=>{const b=await z(q,B);return[{logged_in:b.isAuthenticated,user_id:b.userId||"",username:b.username||""}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as g,Strategy as v}from"@jackwener/opencli/registry";import{EmptyResultError as k}from"@jackwener/opencli/errors";import{OSV_BASE as h,osvPost as b,requireBoundedInt as S,requireEcosystem as q,requireString as P,severityLabel as w,trimDate as m}from"./utils.js";g({site:"osv",name:"query",access:"read",description:"OSV.dev vulnerabilities affecting a package (optionally pinned to a version)",domain:"osv.dev",strategy:v.PUBLIC,browser:!1,args:[{name:"package",positional:!0,type:"string",required:!0,help:'Package name (e.g. "lodash", "django")'},{name:"ecosystem",type:"string",required:!0,help:"OSV ecosystem (npm / PyPI / Go / Maven / NuGet / RubyGems / crates.io / Packagist / ...)"},{name:"version",type:"string",required:!1,help:'Pin to a specific version (e.g. "4.17.20"); omit for all known vulns'},{name:"limit",type:"int",default:30,help:"Max rows to return (1-200)"}],columns:["rank","id","summary","severity","aliases","published","modified","affectedPackages","url"],func:async(i)=>{const r=P(i.package,"package"),a=q(i.ecosystem),p=S(i.limit,30,200,"limit"),s={package:{name:r,ecosystem:a}};if(i.version!=null&&String(i.version).trim()!=="")s.version=String(i.version).trim();const n=await b(`${h}/v1/query`,s,`osv query ${a}:${r}`),o=Array.isArray(n?.vulns)?n.vulns:[];if(o.length===0)throw new k("osv query",`OSV.dev returned no vulnerabilities for ${a}:${r}${s.version?`@${s.version}`:""}.`);return o.slice().sort((e,t)=>String(t?.published??"").localeCompare(String(e?.published??""))).slice(0,p).map((e,t)=>{const y=Array.isArray(e.affected)?e.affected:[],l=[];for(const c of y){const u=c?.package?.ecosystem,d=c?.package?.name;if(u&&d)l.push(`${u}:${d}`)}const f=Array.isArray(e.aliases)?e.aliases.filter(Boolean):[];return{rank:t+1,id:String(e.id??""),summary:String(e.summary??"").trim(),severity:w(e),aliases:f.join(", "),published:m(e.published),modified:m(e.modified),affectedPackages:l.join(", "),url:e.id?`https://osv.dev/vulnerability/${e.id}`:""}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ArgumentError as K,CommandExecutionError as P,EmptyResultError as W}from"@jackwener/opencli/errors";export const OSV_BASE="https://api.osv.dev";const X="opencli-osv-adapter (+https://github.com/jackwener/opencli)",$=/^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$/;export const OSV_ECOSYSTEMS=new Set(["npm","PyPI","Go","Maven","NuGet","RubyGems","crates.io","Packagist","Pub","Hex","Hackage","CRAN","Bitnami","GitHub Actions","SwiftURL"]);export function requireString(B,q){const z=String(B??"").trim();if(!z)throw new K(`osv ${q} cannot be empty`);return z}export function requireVulnId(B){const q=String(B??"").trim();if(!q)throw new K('osv vulnerability id is required (e.g. "GHSA-29mw-wpgm-hmr9", "CVE-2020-28500")',"IDs are listed at https://osv.dev — paste the canonical id from the vulnerability page.");if(!$.test(q))throw new K(`osv vulnerability id "${B}" is not a valid OSV id`,'IDs are short ASCII tokens like "GHSA-...", "CVE-...", "PYSEC-...".');return q}export function requireEcosystem(B){const q=String(B??"").trim();if(!q)throw new K("osv --ecosystem is required when querying by package",`Pick one of: ${[...OSV_ECOSYSTEMS].join(", ")}.`);if(!OSV_ECOSYSTEMS.has(q))throw new K(`osv --ecosystem "${B}" is not a recognised OSV ecosystem`,`Pick one of: ${[...OSV_ECOSYSTEMS].join(", ")}.`);return q}export function requireBoundedInt(B,q,z,G="limit"){const H=B??q,Q=typeof H==="number"?H:Number(H);if(!Number.isInteger(Q)||Q<=0)throw new K(`osv ${G} must be a positive integer`);if(Q>z)throw new K(`osv ${G} must be <= ${z}`);return Q}async function Z(B,q){let z;try{z=await B.json()}catch(G){throw new P(`${q} returned malformed JSON: ${G?.message??G}`)}return z}export async function osvGet(B,q){let z;try{z=await fetch(B,{headers:{"user-agent":X,accept:"application/json"}})}catch(G){throw new P(`${q} request failed: ${G?.message??G}`,"Check that api.osv.dev is reachable from this network.")}if(z.status===404)throw new W(q,`OSV.dev returned 404 for ${B}.`);if(z.status===429)throw new P(`${q} returned HTTP 429 (rate limited)`);if(!z.ok)throw new P(`${q} returned HTTP ${z.status}`);return Z(z,q)}export async function osvPost(B,q,z){let G;try{G=await fetch(B,{method:"POST",headers:{"user-agent":X,accept:"application/json","content-type":"application/json"},body:JSON.stringify(q)})}catch(H){throw new P(`${z} request failed: ${H?.message??H}`,"Check that api.osv.dev is reachable from this network.")}if(G.status===404)throw new W(z,`OSV.dev returned 404 for ${B}.`);if(G.status===429)throw new P(`${z} returned HTTP 429 (rate limited)`);if(!G.ok){const H=await G.text().catch(()=>"");throw new P(`${z} returned HTTP ${G.status}${H?`: ${H.slice(0,200)}`:""}`)}return Z(G,z)}export function severityLabel(B){const q=B?.database_specific;if(q&&typeof q.severity==="string"&&q.severity.trim())return q.severity.trim();const z=Array.isArray(B?.severity)?B.severity:[];for(const G of z)if(G&&typeof G.score==="string"&&G.score.trim())return G.score.trim();return null}export function trimDate(B){const q=String(B??"").trim();if(!q)return null;const z=q.replace(/\.\d+/,"");return z.endsWith("Z")?z:q.length>=10?q.slice(0,10):null}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as m,Strategy as u}from"@jackwener/opencli/registry";import{EmptyResultError as y}from"@jackwener/opencli/errors";import{OSV_BASE as v,osvGet as p,requireVulnId as g,severityLabel as b,trimDate as n}from"./utils.js";m({site:"osv",name:"vulnerability",access:"read",description:"Single OSV.dev vulnerability detail (severity, affected packages, CVE/GHSA aliases)",domain:"osv.dev",strategy:u.PUBLIC,browser:!1,args:[{name:"id",positional:!0,type:"string",required:!0,help:'OSV vulnerability id (e.g. "GHSA-29mw-wpgm-hmr9", "CVE-2020-28500")'}],columns:["id","summary","severity","aliases","published","modified","affectedPackages","cwes","referenceCount","url"],func:async(o)=>{const i=g(o.id),e=await p(`${v}/v1/vulns/${encodeURIComponent(i)}`,`osv vulnerability ${i}`);if(!e||!e.id)throw new y("osv vulnerability",`OSV.dev returned no record for "${i}".`);const c=Array.isArray(e.affected)?e.affected:[],s=[];for(const a of c){const r=a?.package?.ecosystem,t=a?.package?.name;if(r&&t)s.push(`${r}:${t}`)}const d=Array.isArray(e.aliases)?e.aliases.filter(Boolean):[],l=Array.isArray(e?.database_specific?.cwe_ids)?e.database_specific.cwe_ids:[],f=Array.isArray(e.references)?e.references:[];return[{id:String(e.id),summary:String(e.summary??"").trim(),severity:b(e),aliases:d.join(", "),published:n(e.published),modified:n(e.modified),affectedPackages:s.join(", "),cwes:l.join(", "),referenceCount:f.length,url:`https://osv.dev/vulnerability/${e.id}`}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as l,Strategy as c}from"@jackwener/opencli/registry";import{CommandExecutionError as g}from"@jackwener/opencli/errors";import{PACKAGIST_BASE as p,packagistFetch as d,pickStableVersion as m,requirePackageName as u,trimDate as k}from"./utils.js";l({site:"packagist",name:"package",access:"read",description:"Fetch a Packagist package's metadata (version, downloads, license, repo, GitHub stars)",domain:"packagist.org",strategy:c.PUBLIC,browser:!1,args:[{name:"name",positional:!0,required:!0,help:'Composer package "<vendor>/<package>" (e.g. "symfony/console", "monolog/monolog")'}],columns:["package","version","releasedAt","license","description","repository","githubStars","favers","downloads","monthlyDownloads","dailyDownloads","url"],func:async(r)=>{const{full:o}=u(r.name),n=`${p}/packages/${o}.json`,e=(await d(n,"packagist package"))?.package;if(!e||typeof e!=="object")throw new g(`packagist package returned no "package" object for ${o}.`);const s=m(e.versions),t=s?e.versions?.[s]:null,i=Array.isArray(t?.license)?t.license.filter(Boolean).join(", "):"",a=e.downloads??{};return[{package:String(e.name??o).trim(),version:s?String(s):"",releasedAt:k(t?.time),license:i,description:String(e.description??"").trim(),repository:String(e.repository??"").trim(),githubStars:e.github_stars!=null?Number(e.github_stars):null,favers:e.favers!=null?Number(e.favers):null,downloads:a.total!=null?Number(a.total):null,monthlyDownloads:a.monthly!=null?Number(a.monthly):null,dailyDownloads:a.daily!=null?Number(a.daily):null,url:`https://packagist.org/packages/${o}`}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as c,Strategy as p}from"@jackwener/opencli/registry";import{EmptyResultError as l}from"@jackwener/opencli/errors";import{PACKAGIST_BASE as g,packagistFetch as u,requireBoundedInt as m,requireString as d}from"./utils.js";c({site:"packagist",name:"search",access:"read",description:"Search Packagist (PHP / Composer) packages by keyword",domain:"packagist.org",strategy:p.PUBLIC,browser:!1,args:[{name:"query",positional:!0,required:!0,help:'Search keyword (e.g. "symfony", "laravel http")'},{name:"limit",type:"int",default:30,help:"Max packages (1-100, single Packagist page)"}],columns:["rank","package","description","downloads","favers","repository","url"],func:async(r)=>{const a=d(r.query,"query"),t=m(r.limit,30,100),o=`${g}/search.json?q=${encodeURIComponent(a)}&per_page=${t}`,s=await u(o,"packagist search"),i=Array.isArray(s?.results)?s.results:[];if(!i.length)throw new l("packagist search",`No Packagist packages matched "${a}".`);return i.slice(0,t).map((e,n)=>({rank:n+1,package:String(e.name??"").trim(),description:String(e.description??"").trim(),downloads:e.downloads!=null?Number(e.downloads):null,favers:e.favers!=null?Number(e.favers):null,repository:String(e.repository??"").trim(),url:String(e.url??"").trim()}))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ArgumentError as K,CommandExecutionError as O,EmptyResultError as W}from"@jackwener/opencli/errors";export const PACKAGIST_BASE="https://packagist.org";const Y="opencli-packagist-adapter (+https://github.com/jackwener/opencli)",Q=/^[a-z0-9]([_.-]?[a-z0-9]+)*$/;export function requireString(H,q){const z=String(H??"").trim();if(!z)throw new K(`packagist ${q} cannot be empty`);return z}export function requireBoundedInt(H,q,z,J="limit"){const B=H??q,L=typeof B==="number"?B:Number(B);if(!Number.isInteger(L)||L<=0)throw new K(`packagist ${J} must be a positive integer`);if(L>z)throw new K(`packagist ${J} must be <= ${z}`);return L}export function requirePackageName(H){const q=String(H??"").trim().toLowerCase();if(!q)throw new K('packagist package name is required (e.g. "symfony/console", "monolog/monolog")');const z=q.indexOf("/");if(z<=0||z===q.length-1)throw new K(`packagist package "${H}" must be "<vendor>/<package>"`,"Both segments are required (Composer convention).");const J=q.slice(0,z),B=q.slice(z+1);if(J.length>100||B.length>100||!Q.test(J)||!Q.test(B))throw new K(`packagist package "${H}" is not a valid Composer name`,'Use lowercase letters / digits / "_-.", segments separated by single "_-." chars (max 100 chars each).');return{vendor:J,package:B,full:`${J}/${B}`}}export async function packagistFetch(H,q){let z;try{z=await fetch(H,{headers:{"user-agent":Y,accept:"application/json"}})}catch(B){throw new O(`${q} request failed: ${B?.message??B}`,"Check that packagist.org is reachable from this network.")}if(z.status===404)throw new W(q,`Packagist returned 404 for ${H}.`);if(z.status===429)throw new O(`${q} returned HTTP 429 (rate limited)`,"Packagist throttles bursts; wait a few seconds and retry.");if(!z.ok)throw new O(`${q} returned HTTP ${z.status}`);let J;try{J=await z.json()}catch(B){throw new O(`${q} returned malformed JSON: ${B?.message??B}`)}return J}export function trimDate(H){const q=String(H??"").trim();if(!q)return null;return q.replace(/\.\d+/,"").replace(/(?:[+-]\d{2}:?\d{2}|Z)?$/,"Z")}export function pickStableVersion(H){if(!H||typeof H!=="object")return null;const q=Object.keys(H);if(!q.length)return null;const z=/(?:^|[._\-+])(?:dev|alpha|beta|rc|pre|nightly)(?:[._\-+\d]|$)/i,J=/\.x-dev$|-dev$/i;for(const B of q){if(J.test(B))continue;if(z.test(B))continue;return B}return q[0]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as u,Strategy as p}from"@jackwener/opencli/registry";import{CliError as d}from"@jackwener/opencli/errors";import{PAPERREVIEW_DOMAIN as m,ensureSuccess as f,parseYesNo as c,requestJson as h,summarizeFeedback as b,validateHelpfulness as g}from"./utils.js";u({site:"paperreview",name:"feedback",access:"write",description:"Submit feedback for a paperreview.ai review token",domain:m,strategy:p.PUBLIC,browser:!1,args:[{name:"token",positional:!0,required:!0,help:"Review token returned by paperreview.ai"},{name:"helpfulness",required:!0,type:"int",help:"Helpfulness score from 1 to 5"},{name:"critical-error",required:!0,choices:["yes","no"],help:"Whether the review contains a critical error"},{name:"actionable-suggestions",required:!0,choices:["yes","no"],help:"Whether the review contains actionable suggestions"},{name:"additional-comments",help:"Optional free-text feedback"},{name:"timeout",type:"int",required:!1,default:30,help:"Max seconds for the overall command (default: 30)"}],columns:["status","token","helpfulness","critical_error","actionable_suggestions","message"],func:async(e)=>{const t=String(e.token??"").trim();if(!t)throw new d("ARGUMENT","A review token is required.");const o=g(e.helpfulness),i=c(e["critical-error"],"critical-error"),a=c(e["actionable-suggestions"],"actionable-suggestions"),r=String(e["additional-comments"]??"").trim(),n={helpfulness:o,has_critical_error:i,has_actionable_suggestions:a};if(r)n.additional_comments=r;const{response:l,payload:s}=await h(`/api/feedback/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});f(l,s,"Failed to submit feedback.","Check the token and try again");return b({token:t,helpfulness:o,criticalError:i,actionableSuggestions:a,comments:r,payload:s})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as s,Strategy as a}from"@jackwener/opencli/registry";import{CliError as o}from"@jackwener/opencli/errors";import{PAPERREVIEW_DOMAIN as n,buildReviewUrl as c,ensureSuccess as l,requestJson as u,summarizeReview as p}from"./utils.js";s({site:"paperreview",name:"review",access:"read",description:"Fetch a paperreview.ai review by token",domain:n,strategy:a.PUBLIC,browser:!1,args:[{name:"token",positional:!0,required:!0,help:"Review token returned by paperreview.ai"},{name:"timeout",type:"int",required:!1,default:30,help:"Max seconds for the overall command (default: 30)"}],columns:["status","title","venue","numerical_score","has_feedback","review_url"],func:async(i)=>{const e=String(i.token??"").trim();if(!e)throw new o("ARGUMENT","A review token is required.");const{response:t,payload:r}=await u(`/api/review/${encodeURIComponent(e)}`);if(t.status===202)return{status:"processing",token:e,review_url:c(e),title:"",venue:"",numerical_score:"",has_feedback:"",message:typeof r==="object"&&r?r.detail??"Review is still processing.":"Review is still processing."};l(t,r,"Failed to fetch the review.","Check the token and try again");return p(e,r)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as c,Strategy as h}from"@jackwener/opencli/registry";import{CliError as P}from"@jackwener/opencli/errors";import{PAPERREVIEW_DOMAIN as b,ensureApiSuccess as p,ensureSuccess as u,normalizeVenue as v,readPdfFile as w,requestJson as d,summarizeSubmission as s,uploadPresignedPdf as g}from"./utils.js";c({site:"paperreview",name:"submit",access:"write",description:"Submit a PDF to paperreview.ai for review",domain:b,strategy:h.PUBLIC,browser:!1,args:[{name:"pdf",positional:!0,required:!0,help:"Path to the paper PDF"},{name:"email",required:!0,help:"Email address for the submission"},{name:"venue",help:"Optional target venue such as ICLR or NeurIPS"},{name:"dry-run",type:"bool",default:!1,help:"Validate the input and stop before remote submission"},{name:"prepare-only",type:"bool",default:!1,help:"Request an upload slot but stop before uploading the PDF"},{name:"timeout",type:"int",required:!1,default:120,help:"Max seconds for the overall command (default: 120)"}],columns:["status","file","email","venue","token","review_url","message"],footerExtra:(e)=>{if(e["dry-run"]===!0)return"dry run only";if(e["prepare-only"]===!0)return"prepared only";return},func:async(e)=>{const r=await w(e.pdf),n=String(e.email??"").trim(),o=v(e.venue),l=e["dry-run"]===!0,m=e["prepare-only"]===!0;if(!n)throw new P("ARGUMENT","An email address is required.","Pass --email <address>");if(l)return s({pdfFile:r,email:n,venue:o,message:"Input validation passed. No remote request was sent.",dryRun:!0});const{response:f,payload:a}=await d("/api/get-upload-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filename:r.fileName,venue:o})});u(f,a,"Failed to request an upload URL.","Try again in a moment");p(a,"paperreview.ai did not return a usable upload URL.","Try again in a moment");if(m)return s({pdfFile:r,email:n,venue:o,message:"Upload slot prepared. The PDF was not uploaded and no submission was confirmed.",s3Key:a.s3_key,status:"prepared"});await g(a.presigned_url,r,a);const t=new FormData;t.append("s3_key",a.s3_key);t.append("venue",o);t.append("email",n);const{response:y,payload:i}=await d("/api/confirm-upload",{method:"POST",body:t});u(y,i,"Failed to confirm the upload with paperreview.ai.","Try again in a moment");p(i,"paperreview.ai did not confirm the submission.","Try again in a moment");return s({pdfFile:r,email:n,venue:o,token:i.token,message:i.message,s3Key:a.s3_key})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import u from"node:fs/promises";import f from"node:path";import{CliError as o,getErrorMessage as l}from"@jackwener/opencli/errors";export const PAPERREVIEW_DOMAIN="paperreview.ai",PAPERREVIEW_BASE_URL=`https://${PAPERREVIEW_DOMAIN}`,MAX_PDF_BYTES=10485760;function p(e){return e==null?"":String(e)}function i(e){return p(e).trim()}function m(e,t){if(e&&typeof e==="object"){const n=i(e.detail),s=i(e.message),a=i(e.error);if(n)return n;if(s)return s;if(a)return a}return i(e)||t}export function buildReviewUrl(e){return`${PAPERREVIEW_BASE_URL}/review?token=${encodeURIComponent(e)}`}export function parseYesNo(e,t){const r=i(e).toLowerCase();if(r==="yes")return!0;if(r==="no")return!1;throw new o("ARGUMENT",`"${t}" must be either "yes" or "no".`)}export function normalizeVenue(e){return i(e)}export function validateHelpfulness(e){const t=Number(e);if(!Number.isInteger(t)||t<1||t>5)throw new o("ARGUMENT",'"helpfulness" must be an integer from 1 to 5.');return t}export async function readPdfFile(e){const t=i(e);if(!t)throw new o("ARGUMENT","A PDF path is required.","Provide a local PDF file path");const r=f.resolve(t),n=f.basename(r);if(!n.toLowerCase().endsWith(".pdf"))throw new o("ARGUMENT","The input file must end with .pdf.","Provide a PDF file path");let s;try{s=await u.stat(r)}catch(c){if(c?.code==="ENOENT")throw new o("FILE_NOT_FOUND",`File not found: ${r}`,"Provide a valid PDF file path");throw new o("FILE_READ_ERROR",`Unable to inspect file: ${r}`,"Check file permissions and try again")}if(!s.isFile())throw new o("FILE_NOT_FOUND",`Not a file: ${r}`,"Provide a valid PDF file path");if(s.size<100)throw new o("ARGUMENT","The PDF is too small. paperreview.ai requires at least 100 bytes.","Provide the final paper PDF");if(s.size>MAX_PDF_BYTES)throw new o("FILE_TOO_LARGE","The PDF is larger than paperreview.ai's 10MB limit.","Compress the PDF or submit a smaller file");let a;try{a=await u.readFile(r)}catch{throw new o("FILE_READ_ERROR",`Unable to read file: ${r}`,"Check file permissions and try again")}return{buffer:a,fileName:n,resolvedPath:r,sizeBytes:a.byteLength}}export async function requestJson(e,t={}){let r;try{r=await fetch(`${PAPERREVIEW_BASE_URL}${e}`,t)}catch(a){throw new o("FETCH_ERROR",`Unable to reach paperreview.ai: ${l(a)}`,"Check your network connection and try again")}const n=await r.text();let s=n;if(n)try{s=JSON.parse(n)}catch{s=n}return{response:r,payload:s}}export function ensureSuccess(e,t,r,n){if(!e.ok){const s=e.status===404?"NOT_FOUND":"API_ERROR";throw new o(s,m(t,r),n)}}export function ensureApiSuccess(e,t,r){if(!e||typeof e!=="object"||e.success!==!0)throw new o("API_ERROR",m(e,t),r)}export function createUploadForm(e,t){const r=new FormData;for(const[n,s]of Object.entries(e.presigned_fields??{}))r.append(n,s);r.append("file",new Blob([new Uint8Array(t.buffer)],{type:"application/pdf"}),t.fileName);return r}export async function uploadPresignedPdf(e,t,r){let n;try{n=await fetch(e,{method:"POST",body:createUploadForm(r,t)})}catch(s){throw new o("UPLOAD_ERROR",`S3 upload failed: ${l(s)}`,"Try again in a moment")}if(!n.ok){const s=await n.text();throw new o("UPLOAD_ERROR",s||`S3 upload failed with status ${n.status}.`,"Try again in a moment")}}export function summarizeSubmission(e){const{pdfFile:t,email:r,venue:n,token:s,message:a,s3Key:c,dryRun:w=!1,status:h}=e;return{status:h??(w?"dry-run":"submitted"),file:t.fileName,file_path:t.resolvedPath,size_bytes:t.sizeBytes,email:r,venue:n,token:s??"",review_url:s?buildReviewUrl(s):"",message:a??"",s3_key:c??""}}export function summarizeReview(e,t,r="ready"){const n=t?.sections??{},s=Object.keys(n);return{status:r,token:e,review_url:buildReviewUrl(e),title:i(t?.title),venue:i(t?.venue),submission_date:i(t?.submission_date),numerical_score:t?.numerical_score??"",has_feedback:t?.has_feedback??"",available_sections:s.join(", "),section_count:s.length,summary:i(n.summary),strengths:i(n.strengths),weaknesses:i(n.weaknesses),detailed_comments:i(n.detailed_comments),questions:i(n.questions),assessment:i(n.assessment),content:i(t?.content),sections:n}}export function summarizeFeedback(e){const{token:t,helpfulness:r,criticalError:n,actionableSuggestions:s,comments:a,payload:c}=e;return{status:"submitted",token:t,helpfulness:r,critical_error:n,actionable_suggestions:s,additional_comments:a,message:i(c?.message)||"Feedback submitted."}}
|