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,30 @@
|
|
|
1
|
+
export const BUILTIN_COMMANDS=["list","validate","verify","auth","browser","tab","doctor","plugin","external","completion"];export function bashCompletionScript(){return`# Bash completion for opencli
|
|
2
|
+
# Add to ~/.bashrc: eval "$(opencli completion bash)"
|
|
3
|
+
_opencli_completions() {
|
|
4
|
+
local cur words cword
|
|
5
|
+
_get_comp_words_by_ref -n : cur words cword
|
|
6
|
+
|
|
7
|
+
local completions
|
|
8
|
+
completions=$(opencli --get-completions --cursor "$cword" "\${words[@]:1}" 2>/dev/null)
|
|
9
|
+
|
|
10
|
+
COMPREPLY=( $(compgen -W "$completions" -- "$cur") )
|
|
11
|
+
__ltrim_colon_completions "$cur"
|
|
12
|
+
}
|
|
13
|
+
complete -F _opencli_completions opencli
|
|
14
|
+
`}export function zshCompletionScript(){return`# Zsh completion for opencli
|
|
15
|
+
# Add to ~/.zshrc: eval "$(opencli completion zsh)"
|
|
16
|
+
_opencli() {
|
|
17
|
+
local -a completions
|
|
18
|
+
local cword=$((CURRENT - 1))
|
|
19
|
+
completions=(\${(f)"$(opencli --get-completions --cursor "$cword" "\${words[@]:1}" 2>/dev/null)"})
|
|
20
|
+
compadd -a completions
|
|
21
|
+
}
|
|
22
|
+
compdef _opencli opencli
|
|
23
|
+
`}export function fishCompletionScript(){return`# Fish completion for opencli
|
|
24
|
+
# Add to ~/.config/fish/config.fish: opencli completion fish | source
|
|
25
|
+
complete -c opencli -f -a '(
|
|
26
|
+
set -l tokens (commandline -cop)
|
|
27
|
+
set -l cursor (count (commandline -cop))
|
|
28
|
+
opencli --get-completions --cursor $cursor $tokens[2..] 2>/dev/null
|
|
29
|
+
)'
|
|
30
|
+
`}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell tab-completion support for opencli.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Shell script generators for bash, zsh, and fish
|
|
6
|
+
* - Dynamic completion logic that returns candidates for the current cursor position
|
|
7
|
+
*/
|
|
8
|
+
import { bashCompletionScript, zshCompletionScript, fishCompletionScript } from './completion-shared.js';
|
|
9
|
+
export { bashCompletionScript, zshCompletionScript, fishCompletionScript };
|
|
10
|
+
/**
|
|
11
|
+
* Return completion candidates given the current command-line words and cursor index.
|
|
12
|
+
* Requires full CLI discovery to have been run (uses getRegistry()).
|
|
13
|
+
*
|
|
14
|
+
* @param words - The argv after 'opencli' (words[0] is the first arg, e.g. site name)
|
|
15
|
+
* @param cursor - 1-based position of the word being completed (1 = first arg)
|
|
16
|
+
*/
|
|
17
|
+
export declare function getCompletions(words: string[], cursor: number): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Print the completion script for the requested shell.
|
|
20
|
+
*/
|
|
21
|
+
export declare function printCompletionScript(shell: string): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getRegistry as H}from"./registry.js";import{CliError as K}from"./errors.js";import{BUILTIN_COMMANDS as J,bashCompletionScript,zshCompletionScript,fishCompletionScript}from"./completion-shared.js";export{bashCompletionScript,zshCompletionScript,fishCompletionScript};export function getCompletions(x,F){if(F<=1){const k=new Set;for(const[,v]of H())k.add(v.site);return[...J,...k].sort()}const G=x[0];if(J.includes(G))return[];if(F===2){const k=[];for(const[,v]of H())if(v.site===G){k.push(v.name);if(v.aliases?.length)k.push(...v.aliases)}return[...new Set(k)].sort()}return[]}export function printCompletionScript(x){switch(x){case"bash":process.stdout.write(bashCompletionScript());break;case"zsh":process.stdout.write(zshCompletionScript());break;case"fish":process.stdout.write(fishCompletionScript());break;default:throw new K("UNSUPPORTED_SHELL",`Unsupported shell: ${x}. Supported: bash, zsh, fish`)}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared constants used across explore, synthesize, and pipeline modules.
|
|
3
|
+
*/
|
|
4
|
+
/** Default daemon port for HTTP/WebSocket communication with browser extension */
|
|
5
|
+
export declare const DEFAULT_DAEMON_PORT = 19825;
|
|
6
|
+
/**
|
|
7
|
+
* PublishPort 自有插件的专用端口。daemon 同时监听两个端口:19826 供 PublishPort 官方
|
|
8
|
+
* 插件优先连接,19825 作为回退端口(同一 /ext 升级)。daemon 只接受官方插件(hello 带
|
|
9
|
+
* brand:'publishport'),非官方 / 旧 opencli 插件即使连上任一端口也会在握手时被拒。
|
|
10
|
+
*/
|
|
11
|
+
export declare const PUBLISHPORT_DAEMON_PORT = 19826;
|
|
12
|
+
export declare function unsupportedDaemonPortEnvMessage(value?: string): string;
|
|
13
|
+
/** URL query params that are volatile/ephemeral and should be stripped from patterns */
|
|
14
|
+
export declare const VOLATILE_PARAMS: Set<string>;
|
|
15
|
+
/** Search-related query parameter names */
|
|
16
|
+
export declare const SEARCH_PARAMS: Set<string>;
|
|
17
|
+
/** Pagination-related query parameter names */
|
|
18
|
+
export declare const PAGINATION_PARAMS: Set<string>;
|
|
19
|
+
/** Limit/page-size query parameter names */
|
|
20
|
+
export declare const LIMIT_PARAMS: Set<string>;
|
|
21
|
+
/** Field role → common API field names mapping */
|
|
22
|
+
export declare const FIELD_ROLES: Record<string, string[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DEFAULT_DAEMON_PORT=19825,PUBLISHPORT_DAEMON_PORT=19826;export function unsupportedDaemonPortEnvMessage(b){return`OPENCLI_DAEMON_PORT is no longer supported${b?` (received ${b})`:""}. The OpenCLI Chrome extension can only connect to localhost:${DEFAULT_DAEMON_PORT}. Unset OPENCLI_DAEMON_PORT and rerun opencli.`}export const VOLATILE_PARAMS=new Set(["w_rid","wts","_","callback","timestamp","t","nonce","sign"]),SEARCH_PARAMS=new Set(["q","query","keyword","search","wd","kw","search_query","w"]),PAGINATION_PARAMS=new Set(["page","pn","offset","cursor","next","page_num"]),LIMIT_PARAMS=new Set(["limit","count","size","per_page","page_size","ps","num"]),FIELD_ROLES={title:["title","name","text","content","desc","description","headline","subject"],url:["url","uri","link","href","permalink","jump_url","web_url","share_url"],author:["author","username","user_name","nickname","nick","owner","creator","up_name","uname"],score:["score","hot","heat","likes","like_count","view_count","views","play","favorite_count","reply_count"],time:["time","created_at","publish_time","pub_time","date","ctime","mtime","pubdate","created"],id:["id","aid","bvid","mid","uid","oid","note_id","item_id"],cover:["cover","pic","image","thumbnail","poster","avatar"],category:["category","tag","type","tname","channel","section"]};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type ConventionRuleId = 'silent-column-drop' | 'camelCase-in-columns' | 'missing-access-metadata' | 'silent-clamp' | 'silent-empty-fallback' | 'silent-sentinel' | 'write-without-delete-pair';
|
|
2
|
+
type ManifestArg = {
|
|
3
|
+
name?: string;
|
|
4
|
+
positional?: boolean;
|
|
5
|
+
required?: boolean;
|
|
6
|
+
help?: string;
|
|
7
|
+
};
|
|
8
|
+
export type ManifestCommand = {
|
|
9
|
+
site?: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
access?: string;
|
|
12
|
+
args?: ManifestArg[];
|
|
13
|
+
columns?: string[];
|
|
14
|
+
modulePath?: string;
|
|
15
|
+
sourceFile?: string;
|
|
16
|
+
};
|
|
17
|
+
export type ConventionViolation = {
|
|
18
|
+
rule: ConventionRuleId;
|
|
19
|
+
site: string;
|
|
20
|
+
name: string;
|
|
21
|
+
command: string;
|
|
22
|
+
message: string;
|
|
23
|
+
file?: string;
|
|
24
|
+
line?: number;
|
|
25
|
+
details?: Record<string, unknown>;
|
|
26
|
+
};
|
|
27
|
+
export type ConventionCategory = {
|
|
28
|
+
rule: ConventionRuleId;
|
|
29
|
+
count: number;
|
|
30
|
+
violations: ConventionViolation[];
|
|
31
|
+
};
|
|
32
|
+
export type ConventionAuditReport = {
|
|
33
|
+
ok: boolean;
|
|
34
|
+
summary: {
|
|
35
|
+
commands: number;
|
|
36
|
+
sites: number;
|
|
37
|
+
files_scanned: number;
|
|
38
|
+
violations: number;
|
|
39
|
+
};
|
|
40
|
+
categories: ConventionCategory[];
|
|
41
|
+
};
|
|
42
|
+
export type ConventionAuditOptions = {
|
|
43
|
+
projectRoot: string;
|
|
44
|
+
manifestPath?: string;
|
|
45
|
+
target?: string;
|
|
46
|
+
site?: string;
|
|
47
|
+
};
|
|
48
|
+
export declare function runConventionAudit(opts: ConventionAuditOptions): ConventionAuditReport;
|
|
49
|
+
export declare function renderConventionAuditText(report: ConventionAuditReport): string;
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import*as D from"node:fs";import*as _ from"node:path";const S=["silent-column-drop","camelCase-in-columns","missing-access-metadata","silent-clamp","silent-empty-fallback","silent-sentinel","write-without-delete-pair"],C=new Set(["ok","error"]),E=[{match:/(^|[-_])like($|[-_])/,describe:"like",expected:(H)=>[H.replace(/like/g,"unlike"),"unlike"]},{match:/(^|[-_])follow($|[-_])/,describe:"follow",expected:(H)=>[H.replace(/follow/g,"unfollow"),"unfollow"]},{match:/(^|[-_])subscribe($|[-_])/,describe:"subscribe",expected:(H)=>[H.replace(/subscribe/g,"unsubscribe"),"unsubscribe"]},{match:/(^|[-_])bookmark($|[-_])/,describe:"bookmark",expected:(H)=>[H.replace(/bookmark/g,"unbookmark"),"unbookmark"]},{match:/(^|[-_])save($|[-_])/,describe:"save",expected:(H)=>[H.replace(/save/g,"unsave"),"unsave","delete","remove","rm"]},{match:/(^|[-_])create($|[-_])/,describe:"create",expected:(H)=>[H.replace(/create/g,"delete"),H.replace(/create/g,"remove"),"delete","remove","rm"]},{match:/(^|[-_])post($|[-_])/,describe:"post",expected:(H)=>[H.replace(/post/g,"delete"),"delete","remove","rm"]}];export function runConventionAudit(H){const J=H.manifestPath??_.join(H.projectRoot,"cli-manifest.json"),$=JSON.parse(D.readFileSync(J,"utf-8")).filter((Y)=>w(Y,H)),Z=[],G=new Map,X=new Set;for(const Y of $){const A=K(Y);if(!A)continue;if(Y.access!=="read"&&Y.access!=="write")Z.push({rule:"missing-access-metadata",...A,message:`${A.command} must declare access: 'read' | 'write'`});for(const M of Y.columns??[])if(/[a-z][A-Z]/.test(M))Z.push({rule:"camelCase-in-columns",...A,message:`${A.command} column "${M}" should use snake_case for agent-stable keys`,details:{column:M}});const W=T(H.projectRoot,Y);if(!W)continue;const U=O(W,G);if(U==null)continue;X.add(W);Z.push(...q(A,Y,U,W,H.projectRoot));Z.push(...I(A,U,W,H.projectRoot))}Z.push(...b($));const N=S.map((Y)=>{const A=Z.filter((W)=>W.rule===Y);return{rule:Y,count:A.length,violations:A}}),V=$.filter((Y)=>K(Y)!=null).length,z=new Set($.map((Y)=>Y.site).filter((Y)=>typeof Y==="string"));return{ok:Z.length===0,summary:{commands:V,sites:z.size,files_scanned:X.size,violations:Z.length},categories:N}}export function renderConventionAuditText(H){const J=[];J.push("Convention Audit Report");J.push(`Scanned ${H.summary.commands} command(s) across ${H.summary.sites} site(s), ${H.summary.files_scanned} source file(s).`);J.push(`Violations: ${H.summary.violations}`);J.push("");for(const Q of H.categories){const $=Q.count===0?"OK":String(Q.count);J.push(`${Q.rule}: ${$}`);for(const Z of Q.violations){const G=Z.file?` (${Z.file}${Z.line?`:${Z.line}`:""})`:"";J.push(` - ${Z.command}${G}`);J.push(` ${Z.message}`);const X=l(Z.details);if(X)J.push(` ${X}`)}J.push("")}if(H.ok)J.push("OK - no convention violations found.");else J.push("Run with -f yaml or -f json for machine-readable output.");return J.join(`
|
|
2
|
+
`)}function K(H){if(typeof H.site!=="string"||typeof H.name!=="string")return null;return{site:H.site,name:H.name,command:`${H.site}/${H.name}`}}function w(H,J){const Q=J.target?.trim(),$=J.site?.trim();if($&&H.site!==$)return!1;if(!Q)return!0;if(Q.includes("/"))return`${H.site}/${H.name}`===Q;return H.site===Q}function T(H,J){const Q=J.sourceFile??J.modulePath;if(!Q)return null;const $=_.join(H,"clis",Q);return D.existsSync($)?$:null}function O(H,J){if(J.has(H))return J.get(H)??null;try{const Q=D.readFileSync(H,"utf-8");J.set(H,Q);return Q}catch{J.set(H,null);return null}}function q(H,J,Q,$,Z){const G=new Set(J.columns??[]);if(G.size===0)return[];const X=y(Q,G),N=new Set,V=[];for(const z of j(Q)){if(v(z.text))continue;const Y=g(z.text).filter((M)=>!C.has(M));if(Y.length<2)continue;if(u(Y))continue;if(Y.filter((M)=>G.has(M)).length===0)continue;const W=Y.filter((M)=>!G.has(M)&&!X.has(M));if(W.length===0)continue;const U=W.sort().join(",");if(N.has(U))continue;N.add(U);V.push({rule:"silent-column-drop",...H,file:L(Z,$),line:p(Q,z.index),message:`${H.command} row emits key(s) not present in columns: ${W.join(", ")}`,details:{emitted_keys:Y,columns:[...G],missing:W}})}return V}function I(H,J,Q,$){const Z=[],G=L($,Q),X=J.split(/\r?\n/),N=k(J);let V=0;X.forEach((z,Y)=>{if(/Math\.min\s*\([^)]*limit[^)]*\)/i.test(z))Z.push({rule:"silent-clamp",...H,file:G,line:Y+1,message:"limit is clamped with Math.min; prefer validating and throwing ArgumentError on invalid input",details:{text:z.trim()}});const A=z.search(/\breturn\s+\[\s*\]\s*;?/);if(A>=0&&P(V+A,N))Z.push({rule:"silent-empty-fallback",...H,file:G,line:Y+1,message:"empty array fallback hides fetch/parse failures from agents; prefer a typed error when data is expected",details:{text:z.trim()}});const W=/(?:\?\?|\|\|)\s*(['"])(unknown|Unknown|UNKNOWN|N\/A|n\/a|NA|未知|-)\1/.exec(z);if(W){if(!R(z))Z.push({rule:"silent-sentinel",...H,file:G,line:Y+1,message:`sentinel fallback ${W[0].trim()} can turn missing data into fake data; prefer dropping the field or throwing a typed error`,details:{text:z.trim()}})}V+=z.length+1});return c(Z)}function R(H){return/\bthrow\s+new\b/.test(H)}function b(H){const J=new Map;for(const $ of H){if(!$.site||!$.name)continue;const Z=J.get($.site)??[];Z.push($);J.set($.site,Z)}const Q=[];for(const[$,Z]of J){const G=new Set(Z.map((X)=>X.name).filter((X)=>typeof X==="string"));for(const X of Z){if(X.access!=="write"||!X.name)continue;const N=E.find((z)=>z.match.test(X.name));if(!N)continue;const V=[...new Set(N.expected(X.name).filter((z)=>z!==X.name))];if(V.some((z)=>G.has(z)))continue;Q.push({rule:"write-without-delete-pair",site:$,name:X.name,command:`${$}/${X.name}`,message:`write command "${X.name}" looks like ${N.describe} but no matching undo/delete command exists on this site`,details:{expected_any_of:V}})}}return Q}function j(H){const J=[],Q=[/\.push\s*\(\s*{/g,/\breturn\s+(?:\(\s*)?{/g,/=>\s*\(\s*{/g,/\bmap\s*:\s*{/g];for(const $ of Q)for(const Z of H.matchAll($)){const X=Z[0].lastIndexOf("{");if(Z.index===void 0||X<0)continue;const N=Z.index+X,V=B(H,N);if(V)J.push({text:V,index:N})}return J}function k(H){const J=[];for(const Q of H.matchAll(/\bcatch\s*(?:\([^)]*\))?\s*{/g)){if(Q.index===void 0)continue;const $=Q.index+Q[0].lastIndexOf("{"),Z=f(H,$);if(Z>=0)J.push({start:$,end:Z})}return J}function f(H,J){let Q=0,$=null,Z=!1;for(let G=J;G<H.length;G++){const X=H[G];if($){if(Z)Z=!1;else if(X==="\\")Z=!0;else if(X===$)$=null;continue}if(X==='"'||X==="'"||X==="`"){$=X;continue}if(X==="{")Q++;if(X==="}"){Q--;if(Q===0)return G}}return-1}function P(H,J){return J.some((Q)=>H>=Q.start&&H<=Q.end)}function B(H,J){let Q=0,$=null,Z=!1;for(let G=J;G<H.length;G++){const X=H[G];if($){if(Z)Z=!1;else if(X==="\\")Z=!0;else if(X===$)$=null;continue}if(X==='"'||X==="'"||X==="`"){$=X;continue}if(X==="{")Q++;if(X==="}"){Q--;if(Q===0)return H.slice(J,G+1)}}return null}function g(H){return[...new Set(F(H).map((J)=>J.key))]}function F(H){const J=H.trim().replace(/^\{/,"").replace(/\}$/,""),Q=m(J,","),$=[];for(const Z of Q){const G=x(Z);if(G)$.push(G)}return $}function x(H){const J=H.trim();if(!J||J.startsWith("...")||J.startsWith("["))return null;const Q=d(J,":");if(Q>=0){const Z=J.slice(0,Q).trim(),G=J.slice(Q+1).trim();if(/^['"][^'"]+['"]$/.test(Z))return{key:Z.slice(1,-1),value:G};const X=/^([A-Za-z_$][\w$]*)$/.exec(Z);return X?{key:X[1],value:G}:null}const $=/^([A-Za-z_$][\w$]*)\b/.exec(J);return $?{key:$[1],value:$[1]}:null}function v(H){const J=F(H).find((Q)=>Q.key==="ok");return J!=null&&/^false\b/.test(J.value)}function y(H,J){const Q=new Set;for(const $ of h(H))for(const Z of F($.text)){if(!J.has(Z.key))continue;for(const G of Z.value.matchAll(/\b([A-Za-z_$][\w$]*(?:Raw|Class))\b/g)){const X=G[1];if(X!==Z.key)Q.add(X)}}return Q}function h(H){const J=[];for(const Q of H.matchAll(/=>\s*\(\s*{/g)){const Z=Q[0].lastIndexOf("{");if(Q.index===void 0||Z<0)continue;const G=Q.index+Z,X=B(H,G);if(X)J.push({text:X,index:G})}return J}function m(H,J){const Q=[];let $=0,Z=0,G=null,X=!1;for(let N=0;N<H.length;N++){const V=H[N];if(G){if(X)X=!1;else if(V==="\\")X=!0;else if(V===G)G=null;continue}if(V==='"'||V==="'"||V==="`"){G=V;continue}if(V==="{"||V==="["||V==="(")Z++;if(V==="}"||V==="]"||V===")")Z--;if(Z===0&&V===J){Q.push(H.slice($,N));$=N+1}}Q.push(H.slice($));return Q}function d(H,J){let Q=0,$=null,Z=!1;for(let G=0;G<H.length;G++){const X=H[G];if($){if(Z)Z=!1;else if(X==="\\")Z=!0;else if(X===$)$=null;continue}if(X==='"'||X==="'"||X==="`"){$=X;continue}if(X==="{"||X==="["||X==="(")Q++;if(X==="}"||X==="]"||X===")")Q--;if(Q===0&&X===J)return G}return-1}function u(H){const J=new Set(H);return J.has("site")&&(J.has("description")||J.has("access")||J.has("strategy"))}function p(H,J){return H.slice(0,J).split(/\r?\n/).length}function L(H,J){return _.relative(H,J).replaceAll(_.sep,"/")}function l(H){if(!H)return"";return Object.entries(H).map(([J,Q])=>`${J}: ${Array.isArray(Q)?Q.join(", "):String(Q)}`).join(" | ")}function c(H){const J=new Set;return H.filter((Q)=>{const $=`${Q.rule}:${Q.command}:${Q.file}:${Q.line}:${Q.message}`;if(J.has($))return!1;J.add($);return!0})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const COMMAND_RESULT_UNKNOWN_CODE = "command_result_unknown";
|
|
2
|
+
export declare const COMMAND_RESULT_UNKNOWN_HINT = "Inspect the browser/session state before retrying. Do not blindly retry write commands such as navigate, click, type, or eval.";
|
|
3
|
+
export declare const PROFILE_DISCONNECTED_HINT = "Open that Chrome profile and make sure the OpenCLI extension is enabled, or choose another profile with opencli profile use <name>.";
|
|
4
|
+
export type DaemonFailureContract = {
|
|
5
|
+
message: string;
|
|
6
|
+
errorCode: string;
|
|
7
|
+
errorHint: string;
|
|
8
|
+
status: number;
|
|
9
|
+
countAsCommandResultUnknown: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare function commandResultUnknownMessage(action: string): string;
|
|
12
|
+
export declare function buildExtensionDisconnectFailure(input: {
|
|
13
|
+
contextId: string;
|
|
14
|
+
action: string;
|
|
15
|
+
dispatched: boolean;
|
|
16
|
+
}): DaemonFailureContract;
|
|
17
|
+
export declare function buildCommandDispatchFailure(contextId: string): DaemonFailureContract;
|
|
18
|
+
export declare function getResponseCorsHeaders(pathname: string, origin?: string): Record<string, string> | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const COMMAND_RESULT_UNKNOWN_CODE="command_result_unknown",COMMAND_RESULT_UNKNOWN_HINT="Inspect the browser/session state before retrying. Do not blindly retry write commands such as navigate, click, type, or eval.",PROFILE_DISCONNECTED_HINT="Open that Chrome profile and make sure the OpenCLI extension is enabled, or choose another profile with opencli profile use <name>.";export function commandResultUnknownMessage(e){return`Browser connection dropped after the ${e} command was dispatched; it may have completed.`}export function buildExtensionDisconnectFailure(e){if(e.dispatched)return{message:commandResultUnknownMessage(e.action),errorCode:COMMAND_RESULT_UNKNOWN_CODE,errorHint:COMMAND_RESULT_UNKNOWN_HINT,status:503,countAsCommandResultUnknown:!0};return buildCommandDispatchFailure(e.contextId)}export function buildCommandDispatchFailure(e){return{message:`Browser profile "${e}" disconnected before command dispatch`,errorCode:"profile_disconnected",errorHint:PROFILE_DISCONNECTED_HINT,status:503,countAsCommandResultUnknown:!1}}export function getResponseCorsHeaders(e,n){if(e!=="/ping")return;if(!n||!n.startsWith("chrome-extension://"))return;return{"Access-Control-Allow-Origin":n,Vary:"Origin"}}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opencli micro-daemon — HTTP + WebSocket bridge between CLI and Chrome Extension.
|
|
3
|
+
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* CLI → HTTP POST /command → daemon → WebSocket → Extension
|
|
6
|
+
* Extension → WebSocket result → daemon → HTTP response → CLI
|
|
7
|
+
*
|
|
8
|
+
* Security (defense-in-depth against browser-based CSRF):
|
|
9
|
+
* 1. Origin check — reject HTTP/WS from non chrome-extension:// origins
|
|
10
|
+
* 2. Custom header — require X-OpenCLI header (browsers can't send it
|
|
11
|
+
* without CORS preflight, which we deny)
|
|
12
|
+
* 3. No CORS headers on command endpoints — only /ping is readable from the
|
|
13
|
+
* Browser Bridge extension origin so the extension can probe daemon reachability
|
|
14
|
+
* 4. Body size limit — 1 MB max to prevent OOM
|
|
15
|
+
* 5. WebSocket verifyClient — reject upgrade before connection is established
|
|
16
|
+
*
|
|
17
|
+
* Lifecycle:
|
|
18
|
+
* - Auto-spawned by opencli on first browser command
|
|
19
|
+
* - Persistent — stays alive until explicit shutdown, SIGTERM, or uninstall
|
|
20
|
+
* - Listens on localhost:19825
|
|
21
|
+
*/
|
|
22
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createServer as b}from"node:http";import{WebSocketServer as u,WebSocket as v}from"ws";import{DEFAULT_DAEMON_PORT as p,PUBLISHPORT_DAEMON_PORT as g,unsupportedDaemonPortEnvMessage as c}from"./constants.js";import{EXIT_CODES as S}from"./errors.js";import{log as G}from"./logger.js";import{PKG_VERSION as l}from"./version.js";import{DEFAULT_CONTEXT_ID as d}from"./browser/profile.js";import{buildCommandDispatchFailure as a,buildExtensionDisconnectFailure as i,getResponseCorsHeaders as t}from"./daemon-utils.js";import*as L from"./browser/trace.js";const B=p,h=g;if(process.env.OPENCLI_DAEMON_PORT){G.error(c(process.env.OPENCLI_DAEMON_PORT));process.exit(S.USAGE_ERROR)}const W=new Map,N=new Map;let I=0;const n=200,k=[];class E extends Error{errorCode;errorHint;status;constructor(J,K,Z,z=400){super(J);this.errorCode=K;this.errorHint=Z;this.status=z;this.name="DaemonCommandFailure"}}function s(J){k.push(J);if(k.length>n)k.shift()}function j(){return[...W.values()].filter((J)=>J.ws.readyState===v.OPEN)}function q(J){const K=typeof J==="string"&&J.trim()?J.trim():void 0;if(K){const z=W.get(K);if(z?.ws.readyState===v.OPEN)return{connection:z};const Q=j();if(Q.length===1){G.warn(`[daemon] Requested profile "${K}" not connected; falling back to the only connected profile "${Q[0].contextId}"`);return{connection:Q[0]}}return{errorCode:"profile_disconnected",error:`Browser profile "${K}" is not connected.`,errorHint:"Open that Chrome profile and make sure the OpenCLI extension is enabled, or choose another profile with opencli profile use <name>."}}const Z=j();if(Z.length===1)return{connection:Z[0]};if(Z.length>1)return{errorCode:"profile_required",error:"Multiple Browser Bridge profiles are connected; choose one with --profile.",errorHint:"Run opencli profile list, then use opencli --profile <name> ... or opencli profile use <name>."};return{errorCode:"extension_not_connected",error:"Extension not connected. Please install the opencli Browser Bridge extension."}}function o(J,K){const Z=typeof K==="string"&&K.trim()?K.trim():d,z=W.get(Z);if(z&&z.ws!==J)z.ws.close();const Q=[...W.entries()].find(([,A])=>A.ws===J);if(Q&&Q[0]!==Z)W.delete(Q[0]);const $=W.get(Z),V={contextId:Z,ws:J,extensionVersion:$?.ws===J?$.extensionVersion:null,extensionCompatRange:$?.ws===J?$.extensionCompatRange:null,lastSeenAt:Date.now()};W.set(Z,V);return V}function x(J){for(const[K,Z]of W.entries()){if(Z.ws!==J)continue;W.delete(K);L.traceExtDisconnect(K);for(const[z,Q]of N){if(Q.contextId!==K)continue;clearTimeout(Q.timer);const $=i({contextId:K,action:Q.action,dispatched:Q.dispatched});if($.countAsCommandResultUnknown){I++;G.warn(`[daemon] Command result unknown after extension disconnect (id=${z}, action=${Q.action}, context=${K})`)}L.traceResult(z,!1,Date.now()-Q.dispatchTs,$.errorCode);Q.reject(new E($.message,$.errorCode,$.errorHint,$.status));N.delete(z)}}}const w=33554432;class P extends Error{status=413;constructor(){super(`请求体超过 ${w/1024/1024} MB 上限(正文内联图片过多/过大?可减少单次发布的图片体积)`);this.name="BodyTooLargeError"}}function r(J){return new Promise((K,Z)=>{const z=[];let Q=0,$=!1;J.on("data",(V)=>{if($)return;Q+=V.length;if(Q>w){$=!0;z.length=0;Z(new P);return}z.push(V)});J.on("end",()=>{if(!$)K(Buffer.concat(z).toString("utf-8"))});J.on("error",(V)=>{if(!$)Z(V)})})}function Y(J,K,Z,z){J.writeHead(K,{"Content-Type":"application/json",...z});J.end(JSON.stringify(Z))}async function f(J,K){const Z=J.headers.origin;if(Z&&!Z.startsWith("chrome-extension://")){Y(K,403,{ok:!1,error:"Forbidden: cross-origin request blocked"});return}if(J.method==="OPTIONS"){K.writeHead(204);K.end();return}const z=J.url??"/",Q=z.split("?")[0];if(J.method==="GET"&&Q==="/ping"){Y(K,200,{ok:!0},t(Q,Z));return}if(!J.headers["x-opencli"]){Y(K,403,{ok:!1,error:"Forbidden: missing X-OpenCLI header"});return}if(J.method==="GET"&&Q==="/status"){const $=process.uptime(),V=process.memoryUsage(),F=new URL(z,`http://localhost:${B}`).searchParams.get("contextId")?.trim()||void 0,X=q(F),_=j().map((M)=>({contextId:M.contextId,extensionConnected:!0,extensionVersion:M.extensionVersion??void 0,extensionCompatRange:M.extensionCompatRange??void 0,pending:[...N.values()].filter((H)=>H.contextId===M.contextId).length,lastSeenAt:M.lastSeenAt}));Y(K,200,{ok:!0,pid:process.pid,uptime:$,daemonVersion:l,extensionConnected:!!X.connection,extensionVersion:X.connection?.extensionVersion??void 0,extensionCompatRange:X.connection?.extensionCompatRange??void 0,contextId:X.connection?.contextId??F,profileRequired:X.errorCode==="profile_required",profileDisconnected:X.errorCode==="profile_disconnected",profiles:_,pending:N.size,commandResultUnknown:I,memoryMB:Math.round(V.rss/1024/1024*10)/10,port:B});return}if(J.method==="GET"&&Q==="/logs"){const V=new URL(z,`http://localhost:${B}`).searchParams.get("level"),A=V?k.filter((F)=>F.level===V):k;Y(K,200,{ok:!0,logs:A});return}if(J.method==="DELETE"&&Q==="/logs"){k.length=0;Y(K,200,{ok:!0});return}if(J.method==="POST"&&Q==="/shutdown"){Y(K,200,{ok:!0,message:"Shutting down"});setTimeout(()=>R(),100);return}if(J.method==="POST"&&z==="/command"){try{const $=JSON.parse(await r(J));if(!$.id){Y(K,400,{ok:!1,error:"Missing command id"});return}const V=q(typeof $.contextId==="string"?$.contextId:void 0);if(!V.connection){Y(K,V.errorCode==="profile_required"?409:503,{id:$.id,ok:!1,errorCode:V.errorCode,error:V.error,...V.errorHint?{errorHint:V.errorHint}:{}});return}const A=typeof $.timeout==="number"&&$.timeout>0?$.timeout*1000:120000;if(N.has($.id)){Y(K,409,{id:$.id,ok:!1,error:"Duplicate command id already pending; retry"});return}const F=await new Promise((X,_)=>{const M=setTimeout(()=>{N.delete($.id);L.traceTimeout($.id,A,typeof $.action==="string"?$.action:void 0);_(Error(`Command timeout (${A/1000}s)`))},A),H={contextId:V.connection.contextId,action:typeof $.action==="string"?$.action:"unknown",dispatched:!1,dispatchTs:Date.now(),resolve:X,reject:_,timer:M};N.set($.id,H);const y=(U)=>{if(N.get($.id)!==H)return;const D=a(H.contextId);clearTimeout(M);N.delete($.id);_(new E(D.message,D.errorCode,D.errorHint,D.status));G.warn(`[daemon] Failed to dispatch command ${$.id}: ${U instanceof Error?U.message:String(U)}`)};try{V.connection.ws.send(JSON.stringify($),(U)=>{if(U&&!H.dispatched)y(U)});H.dispatched=!0;L.traceDispatch($)}catch(U){y(U)}});Y(K,200,F)}catch($){const V=$ instanceof E?$:null;if($ instanceof P){Y(K,413,{ok:!1,error:$.message,errorCode:"body_too_large"});return}Y(K,V?.status??($ instanceof Error&&$.message.includes("timeout")?408:400),{ok:!1,error:$ instanceof Error?$.message:"Invalid request",...V?.errorCode?{errorCode:V.errorCode}:{},...V?.errorHint?{errorHint:V.errorHint}:{}})}return}Y(K,404,{error:"Not found"})}const O=b((J,K)=>{f(J,K).catch(()=>{K.writeHead(500);K.end()})}),T=b((J,K)=>{f(J,K).catch(()=>{K.writeHead(500);K.end()})}),C=new u({noServer:!0});function m(J,K,Z){if((J.url??"/").split("?")[0]!=="/ext"){K.destroy();return}const Q=J.headers.origin;if(Q&&!Q.startsWith("chrome-extension://")){K.destroy();return}C.handleUpgrade(J,K,Z,($)=>{C.emit("connection",$,J)})}O.on("upgrade",m);T.on("upgrade",m);C.on("connection",(J)=>{G.info("[daemon] Extension connected");let K=0;const Z=setInterval(()=>{if(J.readyState!==v.OPEN){clearInterval(Z);return}if(K>=2){G.warn("[daemon] Extension heartbeat lost, closing connection");clearInterval(Z);J.terminate();return}K++;J.ping()},15000);J.on("pong",()=>{K=0});J.on("message",(z)=>{try{const Q=JSON.parse(z.toString());if(Q.type==="hello"){if(Q.brand!=="publishport"){G.warn(`[daemon] 拒绝非 PublishPort 官方扩展连接(brand=${JSON.stringify(Q.brand)})`);J.close(4003,"Only the official PublishPort extension is supported");return}const V=o(J,Q.contextId);V.extensionVersion=typeof Q.version==="string"?Q.version:null;V.extensionCompatRange=typeof Q.compatRange==="string"?Q.compatRange:null;V.lastSeenAt=Date.now();G.info(`[daemon] Extension profile connected: ${V.contextId}`);L.traceExtConnect(V.contextId,V.extensionVersion);return}if(Q.type==="log"){if(Q.level==="error")G.error(`[ext] ${Q.msg}`);else if(Q.level==="warn")G.warn(`[ext] ${Q.msg}`);else G.info(`[ext] ${Q.msg}`);s({level:Q.level,msg:Q.msg,ts:Q.ts??Date.now()});L.traceExtLog(Q.level,Q.msg);return}const $=N.get(Q.id);if($){clearTimeout($.timer);N.delete(Q.id);L.traceResult(Q.id,!!Q.ok,Date.now()-$.dispatchTs,typeof Q.errorCode==="string"?Q.errorCode:void 0,typeof Q.page==="string"?Q.page:void 0);$.resolve(Q)}}catch(Q){const $=z.toString().slice(0,200);G.warn(`[daemon] Ignoring malformed WS message from extension: ${Q instanceof Error?Q.message:String(Q)} (first 200 chars: ${JSON.stringify($)})`)}});J.on("close",()=>{G.info("[daemon] Extension disconnected");clearInterval(Z);x(J)});J.on("error",()=>{clearInterval(Z);x(J)})});O.listen(B,"127.0.0.1",()=>{G.info(`[daemon] Listening on http://127.0.0.1:${B}`)});O.on("error",(J)=>{if(J.code==="EADDRINUSE"){G.error(`[daemon] Port ${B} already in use — another daemon is likely running. Exiting.`);process.exit(S.SERVICE_UNAVAIL)}G.error(`[daemon] Server error: ${J.message}`);process.exit(S.GENERIC_ERROR)});T.listen(h,"127.0.0.1",()=>{G.info(`[daemon] Listening on http://127.0.0.1:${h} (PublishPort extension)`)});T.on("error",(J)=>{G.warn(`[daemon] PublishPort port ${h} unavailable (${J.message}) — extension will fall back to ${B}`)});function R(){for(const[,J]of N){clearTimeout(J.timer);J.reject(Error("Daemon shutting down"))}N.clear();for(const J of W.values())J.ws.close();O.close();T.close();process.exit(S.SUCCESS)}process.on("SIGTERM",R);process.on("SIGINT",R);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI discovery: finds JS CLI definitions and registers them.
|
|
3
|
+
*
|
|
4
|
+
* Supports two modes:
|
|
5
|
+
* 1. FAST PATH (manifest): If a pre-compiled cli-manifest.json exists,
|
|
6
|
+
* registers commands instantly. JS modules are loaded lazily only
|
|
7
|
+
* when their command is executed.
|
|
8
|
+
* 2. FALLBACK (filesystem scan): Traditional runtime discovery for development.
|
|
9
|
+
*/
|
|
10
|
+
/** User runtime directory: ~/.opencli */
|
|
11
|
+
export declare const USER_OPENCLI_DIR: string;
|
|
12
|
+
/** User CLIs directory: ~/.opencli/clis */
|
|
13
|
+
export declare const USER_CLIS_DIR: string;
|
|
14
|
+
/** Plugins directory: ~/.opencli/plugins/ */
|
|
15
|
+
export declare const PLUGINS_DIR: string;
|
|
16
|
+
/**
|
|
17
|
+
* Ensure ~/.opencli/node_modules/@jackwener/opencli symlink exists so that
|
|
18
|
+
* user CLIs in ~/.opencli/clis/ can `import { cli } from '@jackwener/opencli/registry'`.
|
|
19
|
+
*
|
|
20
|
+
* This is the sole resolution mechanism — adapters use package exports
|
|
21
|
+
* (e.g. `@jackwener/opencli/registry`, `@jackwener/opencli/errors`) and
|
|
22
|
+
* Node.js resolves them through this symlink.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ensureUserCliCompatShims(baseDir?: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Ensure the user adapters directory exists.
|
|
27
|
+
*
|
|
28
|
+
* With smart sync, ~/.opencli/clis/ only holds files that differ from the
|
|
29
|
+
* package baseline (upstream-synced cache + autofix output + user overrides).
|
|
30
|
+
* Built-in adapters are loaded directly from the installed package.
|
|
31
|
+
*/
|
|
32
|
+
export declare function ensureUserAdapters(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Discover and register CLI commands.
|
|
35
|
+
* Uses pre-compiled manifest when available for instant startup.
|
|
36
|
+
*/
|
|
37
|
+
export declare function discoverClis(...dirs: string[]): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Discover and register plugins from ~/.opencli/plugins/.
|
|
40
|
+
* Each subdirectory is treated as a plugin (site = directory name).
|
|
41
|
+
* Files inside are scanned flat (no nested site subdirs).
|
|
42
|
+
*/
|
|
43
|
+
export declare function discoverPlugins(): Promise<void>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import*as H from"node:fs";import*as G from"node:os";import*as Y from"node:path";import{fileURLToPath as F,pathToFileURL as v}from"node:url";import{Strategy as A,registerCommand as J}from"./registry.js";import{getErrorMessage as $}from"./errors.js";import{log as Z}from"./logger.js";import{findPackageRoot as O,getCliManifestPath as N}from"./package-paths.js";export const USER_OPENCLI_DIR=Y.join(G.homedir(),".opencli"),USER_CLIS_DIR=Y.join(USER_OPENCLI_DIR,"clis"),PLUGINS_DIR=Y.join(USER_OPENCLI_DIR,"plugins");const T=/\b(?:cli|registerSiteAuthCommands|onStartup|onBeforeExecute|onAfterExecute)\s*\(/;function b(z,x=A.COOKIE){if(!z)return x;const B=z.toUpperCase();return A[B]??x}const L=O(F(import.meta.url));export async function ensureUserCliCompatShims(z=USER_OPENCLI_DIR){await H.promises.mkdir(z,{recursive:!0});const x=Y.join(z,"package.json"),B=`${JSON.stringify({name:"opencli-user-runtime",private:!0,type:"module"},null,2)}
|
|
2
|
+
`;try{if(await H.promises.readFile(x,"utf-8")!==B)await H.promises.writeFile(x,B,"utf-8")}catch{await H.promises.writeFile(x,B,"utf-8")}const V=L,q=Y.join(z,"node_modules","@jackwener"),Q=Y.join(q,"opencli");try{let W=!0;try{if(await H.promises.readlink(Q)===V)W=!1}catch{}if(W){await H.promises.mkdir(q,{recursive:!0});try{await H.promises.rm(Q,{recursive:!0,force:!0})}catch{}const X=process.platform==="win32"?"junction":"dir";await H.promises.symlink(V,Q,X)}}catch(W){Z.warn(`Could not create symlink at ${Q}: ${$(W)}`)}}export async function ensureUserAdapters(){await H.promises.mkdir(USER_CLIS_DIR,{recursive:!0})}export async function discoverClis(...z){for(const x of z){const B=N(x);try{await H.promises.access(B);if(await M(B,x))continue}catch{}await C(x)}}async function M(z,x){try{const B=await H.promises.readFile(z,"utf-8"),V=JSON.parse(B);for(const q of V){if(!q.modulePath)continue;const Q=Y.resolve(x,q.modulePath),W={site:q.site,name:q.name,aliases:q.aliases,description:q.description??"",access:q.access,example:q.example,domain:q.domain,strategy:b(q.strategy),browser:q.browser,args:q.args??[],columns:q.columns,defaultFormat:q.defaultFormat,pipeline:q.pipeline,source:q.sourceFile?Y.resolve(x,q.sourceFile):Q,navigateBefore:q.navigateBefore,siteSession:q.siteSession,defaultWindowMode:q.defaultWindowMode,_lazy:!0,_modulePath:Q};J(W)}return!0}catch(B){Z.warn(`Failed to load manifest ${z}: ${$(B)}`);return!1}}async function C(z){try{await H.promises.access(z)}catch{return}const B=(await H.promises.readdir(z,{withFileTypes:!0})).filter((V)=>V.isDirectory()).map(async(V)=>{const q=V.name,Q=Y.join(z,q),W=await H.promises.readdir(Q);await Promise.all(W.map(async(X)=>{const K=Y.join(Q,X);if(X.endsWith(".yaml")||X.endsWith(".yml"))return;if(X.endsWith(".ts")&&!X.endsWith(".d.ts")&&!X.endsWith(".test.ts")){Z.warn(`Ignoring TypeScript adapter ${K} — .ts adapters are no longer loaded. Rename to .js or convert to JavaScript.`);return}if(X.endsWith(".js")&&!X.endsWith(".d.js")&&!X.endsWith(".test.js")){if(!await j(K))return;await import(v(K).href).catch((w)=>{Z.warn(`Failed to load module ${K}: ${$(w)}`)})}}))});await Promise.all(B)}export async function discoverPlugins(){try{await H.promises.access(PLUGINS_DIR)}catch{return}const z=await H.promises.readdir(PLUGINS_DIR,{withFileTypes:!0});await Promise.all(z.map(async(x)=>{const B=Y.join(PLUGINS_DIR,x.name);if(!await _(x,B))return;await U(B,x.name)}))}async function U(z,x){let B;try{B=await H.promises.readdir(z)}catch(q){const Q=q.code;if(Q!=="ENOENT"&&Q!=="ENOTDIR")Z.warn(`Failed to scan plugin directory ${z}: ${$(q)}`);return}const V=new Set(B);await Promise.all(B.map(async(q)=>{const Q=Y.join(z,q);if(q.endsWith(".yaml")||q.endsWith(".yml"))return;if(q.endsWith(".js")&&!q.endsWith(".d.js")){if(!await j(Q))return;await import(v(Q).href).catch((W)=>{Z.warn(`Plugin ${x}/${q}: ${$(W)}`)})}else if(q.endsWith(".ts")&&!q.endsWith(".d.ts")&&!q.endsWith(".test.ts")){const W=q.replace(/\.ts$/,".js");if(V.has(W))return;Z.warn(`Plugin ${x}/${q}: no compiled .js found. Run "opencli plugin update ${x}" to re-transpile, or install esbuild.`)}}))}async function j(z){try{const x=await H.promises.readFile(z,"utf-8");return T.test(x)}catch(x){Z.warn(`Failed to inspect module ${z}: ${$(x)}`);return!1}}async function _(z,x){if(z.isDirectory())return!0;if(!z.isSymbolicLink())return!1;try{return(await H.promises.stat(x)).isDirectory()}catch(B){const V=B.code;if(V!=="ENOENT"&&V!=="ENOTDIR")Z.warn(`Failed to inspect plugin link ${x}: ${$(B)}`);return!1}}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opencli doctor — diagnose browser connectivity.
|
|
3
|
+
*
|
|
4
|
+
* Simplified for the daemon-based architecture.
|
|
5
|
+
*/
|
|
6
|
+
import type { BrowserProfileStatus } from './browser/daemon-client.js';
|
|
7
|
+
import { type AdapterShadow } from './adapter-shadow.js';
|
|
8
|
+
export type DoctorOptions = {
|
|
9
|
+
yes?: boolean;
|
|
10
|
+
cliVersion?: string;
|
|
11
|
+
};
|
|
12
|
+
export type ConnectivityResult = {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
durationMs: number;
|
|
16
|
+
};
|
|
17
|
+
export type DoctorReport = {
|
|
18
|
+
cliVersion?: string;
|
|
19
|
+
daemonRunning: boolean;
|
|
20
|
+
daemonFlaky?: boolean;
|
|
21
|
+
daemonStale?: boolean;
|
|
22
|
+
daemonVersion?: string;
|
|
23
|
+
extensionConnected: boolean;
|
|
24
|
+
extensionFlaky?: boolean;
|
|
25
|
+
extensionVersion?: string;
|
|
26
|
+
connectivity?: ConnectivityResult;
|
|
27
|
+
profiles?: BrowserProfileStatus[];
|
|
28
|
+
adapterShadows?: AdapterShadow[];
|
|
29
|
+
issues: string[];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Test connectivity by attempting a real browser command.
|
|
33
|
+
*/
|
|
34
|
+
export declare function checkConnectivity(opts?: {
|
|
35
|
+
timeout?: number;
|
|
36
|
+
}): Promise<ConnectivityResult>;
|
|
37
|
+
export declare function runBrowserDoctor(opts?: DoctorOptions): Promise<DoctorReport>;
|
|
38
|
+
export declare function renderBrowserDoctorReport(report: DoctorReport): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{DEFAULT_DAEMON_PORT as L}from"./constants.js";import{BrowserBridge as M}from"./browser/index.js";import{getDaemonHealth as k}from"./browser/daemon-client.js";import{getErrorMessage as _}from"./errors.js";import{getRuntimeLabel as F}from"./runtime-detect.js";import{aliasForContextId as E,loadProfileConfig as T}from"./browser/profile.js";import{formatDaemonVersion as P,isDaemonStale as I,staleDaemonIssue as O}from"./browser/daemon-version.js";import{findShadowedUserAdapters as b,formatAdapterShadowIssue as j}from"./adapter-shadow.js";const w=8,y="__doctor__";function N(q){const z=q.replace(/^v/,"").split("-")[0].split(".").map(Number);if(z.length<3||z.some(isNaN))return null;return[z[0],z[1],z[2]]}function D(q,z){const G=z.match(/^(>=?)\s*(\S+)$/);if(!G)return!0;const[,K,$]=G,X=N(q),Y=N($);if(!X||!Y)return!0;const Q=X[0]-Y[0]||X[1]-Y[1]||X[2]-Y[2];return K===">="?Q>=0:Q>0}export async function checkConnectivity(q){const z=Date.now();try{const G=new M,K=await G.connect({timeout:q?.timeout??w,session:y,surface:"browser"});try{await K.evaluate("1 + 1");await K.closeWindow?.()}finally{await G.close()}return{ok:!0,durationMs:Date.now()-z}}catch(G){return{ok:!1,error:_(G),durationMs:Date.now()-z}}}export async function runBrowserDoctor(q={}){const z=await checkConnectivity(),G=await k(),K=G.state!=="stopped",$=G.state==="ready",X=z.ok&&!K,Y=z.ok&&K&&!$,Q=I(G.status,q.cliVersion),Z=G.status?.profiles,W=G.status?.extensionVersion,H=b(),J=[];if(X)J.push(`Daemon connectivity is unstable. The live browser test succeeded, but the daemon was no longer running immediately afterward.
|
|
2
|
+
This usually means the daemon crashed or exited right after serving the live probe.`);else if(!K)J.push("Daemon is not running. It should start automatically when you run an opencli browser command.");if(Q&&q.cliVersion)J.push(O(G.status,q.cliVersion));if(Y)J.push(`Extension connection is unstable. The live browser test succeeded, but the daemon reported the extension disconnected immediately afterward.
|
|
3
|
+
This usually means the Browser Bridge service worker is reconnecting slowly or Chrome suspended it.`);else if(K&&!$)if(G.state==="profile-required")J.push(`Multiple Chrome profiles are connected to the daemon, but no default profile was selected.
|
|
4
|
+
Run opencli profile list, then opencli profile use <name>, or pass --profile <name>.`);else if(G.state==="profile-disconnected")J.push(`Selected browser profile is not connected: ${G.status?.contextId??"unknown"}.
|
|
5
|
+
Open that Chrome profile and make sure the OpenCLI extension is enabled.`);else J.push(`Daemon is running but the Chrome/Chromium extension is not connected.
|
|
6
|
+
If the extension is already installed, try: opencli daemon restart
|
|
7
|
+
If the extension is not installed, install the PublishPort browser extension
|
|
8
|
+
from the PublishPort desktop app.`);if($&&!W)J.push(`Extension is connected but did not report a version.
|
|
9
|
+
This usually means an outdated Browser Bridge extension.
|
|
10
|
+
Reload or reinstall the PublishPort browser extension via the PublishPort desktop app.`);if(!z.ok)J.push(`Browser connectivity test failed: ${z.error??"unknown"}`);const B=G.status?.extensionCompatRange;if(W&&q.cliVersion&&B){if(!D(q.cliVersion,B))J.push(`CLI version incompatible with extension: extension v${W} requires CLI ${B}, but CLI is v${q.cliVersion}
|
|
11
|
+
Update via the PublishPort desktop app (or: npm install -g publishport-opencli).`)}else if(W&&q.cliVersion){const U=W.split(".")[0],A=q.cliVersion.split(".")[0];if(U!==A)J.push(`Extension major version mismatch: extension v${W} ≠ CLI v${q.cliVersion}
|
|
12
|
+
Update the PublishPort browser extension via the PublishPort desktop app.`)}if(H.length>0)J.push(j(H));return{cliVersion:q.cliVersion,daemonRunning:K,daemonFlaky:X,daemonStale:Q,daemonVersion:G.status?.daemonVersion,extensionConnected:$,extensionFlaky:Y,extensionVersion:W,connectivity:z,profiles:Z,adapterShadows:H,issues:J}}export function renderBrowserDoctorReport(q){const z=[`opencli v${q.cliVersion??"unknown"} doctor (${F()})`,""],G=q.daemonFlaky?"[WARN]":q.daemonStale?"[WARN]":q.daemonRunning?"[OK]":"[MISSING]",K=q.daemonFlaky?"unstable (running during live check, then stopped)":q.daemonRunning?`running on port ${L} (${q.daemonStale?`${P(q)}, stale; CLI v${q.cliVersion??"unknown"}`:P(q)})`:"not running";z.push(`${G} Daemon: ${K}`);const $=q.extensionFlaky||q.extensionConnected&&!q.extensionVersion?"[WARN]":q.extensionConnected?"[OK]":"[MISSING]",X=!q.extensionConnected?"":q.extensionVersion?` (v${q.extensionVersion})`:" (version unknown)",Y=q.extensionFlaky?"unstable (connected during live check, then disconnected)":q.extensionConnected?"connected":"not connected";z.push(`${$} Extension: ${Y}${X}`);if(q.profiles&&q.profiles.length>0){const Q=T();z.push("","Profiles:");for(const Z of q.profiles){const W=E(Q,Z.contextId),H=W?` (${W})`:"",J=Q.defaultContextId===Z.contextId?", default":"",B=Z.extensionVersion?`v${Z.extensionVersion}`:"version unknown";z.push(` • ${Z.contextId}${H}: connected ${B}${J}`)}}if(q.connectivity){const Q=q.connectivity.ok?"[OK]":"[FAIL]",Z=q.connectivity.ok?`connected in ${(q.connectivity.durationMs/1000).toFixed(1)}s`:`failed (${q.connectivity.error??"unknown"})`;z.push(`${Q} Connectivity: ${Z}`)}if(q.issues.length){z.push("","Issues:");for(const Q of q.issues)z.push(` • ${Q}`)}else if(q.daemonRunning&&q.extensionConnected)z.push("","Everything looks good!");return z.join(`
|
|
13
|
+
`)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Article download helper — shared logic for downloading articles as Markdown.
|
|
3
|
+
*
|
|
4
|
+
* Used by: zhihu/download, weixin/download, and future article adapters.
|
|
5
|
+
*
|
|
6
|
+
* Flow: ArticleData → TurndownService → image download → frontmatter → .md file
|
|
7
|
+
*/
|
|
8
|
+
import TurndownService from 'turndown';
|
|
9
|
+
export interface ArticleData {
|
|
10
|
+
title: string;
|
|
11
|
+
author?: string;
|
|
12
|
+
publishTime?: string;
|
|
13
|
+
sourceUrl?: string;
|
|
14
|
+
contentHtml: string;
|
|
15
|
+
/** Pre-extracted code blocks to restore after Markdown conversion */
|
|
16
|
+
codeBlocks?: Array<{
|
|
17
|
+
lang: string;
|
|
18
|
+
code: string;
|
|
19
|
+
}>;
|
|
20
|
+
/** Image URLs found in the article (pre-collected from DOM) */
|
|
21
|
+
imageUrls?: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface FrontmatterLabels {
|
|
24
|
+
author?: string;
|
|
25
|
+
publishTime?: string;
|
|
26
|
+
sourceUrl?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ArticleDownloadOptions {
|
|
29
|
+
output: string;
|
|
30
|
+
downloadImages?: boolean;
|
|
31
|
+
/** Extra headers for image downloads (e.g. { Referer: '...' }) */
|
|
32
|
+
imageHeaders?: Record<string, string>;
|
|
33
|
+
maxTitleLength?: number;
|
|
34
|
+
/** Custom TurndownService configuration callback */
|
|
35
|
+
configureTurndown?: (td: TurndownService) => void;
|
|
36
|
+
/** Custom image extension detector (default: infer from URL extension) */
|
|
37
|
+
detectImageExt?: (url: string) => string;
|
|
38
|
+
/** Custom frontmatter labels (default: Chinese labels) */
|
|
39
|
+
frontmatterLabels?: FrontmatterLabels;
|
|
40
|
+
/**
|
|
41
|
+
* Extra CSS selectors removed from the article before Turndown conversion.
|
|
42
|
+
* Use this to drop site-specific noise the adapter can't always trim upstream
|
|
43
|
+
* (e.g. zhihu 折叠卡, weixin 赞赏栏, wiki infobox).
|
|
44
|
+
*/
|
|
45
|
+
cleanSelectors?: string[];
|
|
46
|
+
/**
|
|
47
|
+
* Write the markdown to `process.stdout` instead of a file on disk. Image
|
|
48
|
+
* download and directory creation are skipped — remote image URLs are kept
|
|
49
|
+
* as-is so the output is self-contained when piped.
|
|
50
|
+
*/
|
|
51
|
+
stdout?: boolean;
|
|
52
|
+
}
|
|
53
|
+
export interface ArticleDownloadResult {
|
|
54
|
+
title: string;
|
|
55
|
+
author: string;
|
|
56
|
+
publish_time: string;
|
|
57
|
+
status: string;
|
|
58
|
+
size: string;
|
|
59
|
+
saved: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Download an article to Markdown with optional image localization.
|
|
63
|
+
*
|
|
64
|
+
* Handles the full pipeline:
|
|
65
|
+
* 1. HTML → Markdown (via TurndownService)
|
|
66
|
+
* 2. Code block placeholder restoration
|
|
67
|
+
* 3. Batch image downloading with concurrency + deduplication
|
|
68
|
+
* 4. Image URL replacement in Markdown
|
|
69
|
+
* 5. Frontmatter generation (customizable labels)
|
|
70
|
+
* 6. File write
|
|
71
|
+
*/
|
|
72
|
+
export declare function downloadArticle(data: ArticleData, options: ArticleDownloadOptions): Promise<ArticleDownloadResult[]>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import*as P from"node:fs";import*as H from"node:path";import k from"turndown";import{gfm as x}from"turndown-plugin-gfm";import{httpDownload as C,sanitizeFilename as E}from"./index.js";import{formatBytes as I}from"./progress.js";const b=5,M={author:"作者",publishTime:"发布时间",sourceUrl:"原文链接"},T=["script","style","noscript","canvas","form","button","dialog","header","footer","nav","aside"];function D(J,$){const V=new k({headingStyle:"atx",codeBlockStyle:"fenced",bulletListMarker:"-"});V.use(x);V.remove(T);V.addRule("canonicalStrikethrough",{filter:(K)=>["DEL","S","STRIKE"].includes(K.nodeName),replacement:(K)=>`~~${K}~~`});V.addRule("stripSvg",{filter:(K)=>K.nodeName==="svg"||K.nodeName==="SVG",replacement:()=>""});V.addRule("linebreak",{filter:"br",replacement:()=>`
|
|
2
|
+
`});V.addRule("ignoreBase64Images",{filter:(K)=>{if(K.nodeName!=="IMG")return!1;return(K.getAttribute?.("src")??"").startsWith("data:")},replacement:()=>""});V.addRule("videoElement",{filter:(K)=>K.nodeName==="VIDEO",replacement:(K,Q)=>{const W=Q,Z=W.getAttribute("src")||W.querySelector("source")?.getAttribute("src")||"";if(!Z)return"";const X=W.getAttribute("poster")||"";return`
|
|
3
|
+
<video src="${Z}" controls${X?` poster="${X}"`:""}></video>
|
|
4
|
+
`}});V.addRule("audioElement",{filter:(K)=>K.nodeName==="AUDIO",replacement:(K,Q)=>{const W=Q,Z=W.getAttribute("src")||W.querySelector("source")?.getAttribute("src")||"";return Z?`
|
|
5
|
+
<audio src="${Z}" controls></audio>
|
|
6
|
+
`:""}});V.addRule("iframeToLink",{filter:(K)=>K.nodeName==="IFRAME",replacement:(K,Q)=>{const W=Q,Z=W.getAttribute("src")||"";if(!Z)return"";return`
|
|
7
|
+
[${W.getAttribute("title")||"Embedded content"}](${Z})
|
|
8
|
+
`}});const q=($??[]).map((K)=>K.trim()).filter(Boolean);if(q.length>0)V.addRule("cleanSelectors",{filter:(K)=>{const Q=K.matches;if(typeof Q!=="function")return!1;return q.some((W)=>{try{return Q.call(K,W)}catch{return!1}})},replacement:()=>""});if(J)J(V);return V}function w(J,$,V,q){let Q=D(V,q).turndown(J);$.forEach((W,Z)=>{const X=`CODEBLOCK-PLACEHOLDER-${Z}`,y=`
|
|
9
|
+
\`\`\`${W.lang}
|
|
10
|
+
${W.code}
|
|
11
|
+
\`\`\`
|
|
12
|
+
`;Q=Q.replace(X,y)});Q=Q.replace(/\u00a0/g," ");Q=Q.replace(/^[ \t]*[-·][ \t]*$/gm,"");Q=Q.replace(/^[ \t]+$/gm,"");Q=Q.replace(/[ \t]+$/gm,"");Q=Q.replace(/\n{3,}/g,`
|
|
13
|
+
|
|
14
|
+
`);return Q}function U(J,$){return J.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(V,q,K)=>{const Q=$[K];return Q?``:V})}function h(J){const $=J.match(/\.(\w{3,4})(?:\?|$)/);return $?$[1]:"jpg"}async function p(J,$,V,q){const K={};if(J.length===0)return K;const Q=q||h,W=new Set,Z=J.filter((X)=>{if(W.has(X))return!1;W.add(X);return!0});for(let X=0;X<Z.length;X+=b){const y=Z.slice(X,X+b),j=await Promise.all(y.map(async(F,z)=>{const G=X+z+1;let O=F;if(O.startsWith("//"))O=`https:${O}`;const v=Q(O),Y=`img_${String(G).padStart(3,"0")}.${v}`,N=H.join($,Y);try{if((await C(O,N,{headers:V,timeout:15000})).success)return{remoteUrl:F,localPath:`images/${Y}`}}catch{}return null}));for(const F of j)if(F)K[F.remoteUrl]=F.localPath}return K}export async function downloadArticle(J,$){const{output:V,downloadImages:q=!0,imageHeaders:K,maxTitleLength:Q=80,configureTurndown:W,detectImageExt:Z,frontmatterLabels:X,cleanSelectors:y,stdout:j=!1}=$,F={...M,...X};if(!J.title)return[{title:"Error",author:"-",publish_time:"-",status:"failed — no title",size:"-",saved:"-"}];if(!J.contentHtml)return[{title:J.title,author:J.author||"-",publish_time:J.publishTime||"-",status:"failed — no content",size:"-",saved:"-"}];let z=w(J.contentHtml,J.codeBlocks||[],W,y);const G=E(J.title,Q);if(!j&&q&&J.imageUrls&&J.imageUrls.length>0){const B=H.join(V,G);P.mkdirSync(B,{recursive:!0});const R=H.join(B,"images");P.mkdirSync(R,{recursive:!0});const S=await p(J.imageUrls,R,K,Z);z=U(z,S)}const O=[`# ${J.title}`];if(J.author)O.push(`> ${F.author}: ${J.author}`);if(J.publishTime)O.push(`> ${F.publishTime}: ${J.publishTime}`);if(J.sourceUrl)O.push(`> ${F.sourceUrl}: ${J.sourceUrl}`);const Y=O.join(`
|
|
15
|
+
`)+`
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
`+z,N=Buffer.byteLength(Y,"utf-8");if(j){process.stdout.write(Y.endsWith(`
|
|
20
|
+
`)?Y:Y+`
|
|
21
|
+
`);return[{title:J.title,author:J.author||"-",publish_time:J.publishTime||"-",status:"success",size:I(N),saved:"-"}]}const _=H.join(V,G);P.mkdirSync(_,{recursive:!0});const L=`${G}.md`,A=H.join(_,L);P.writeFileSync(A,Y,"utf-8");return[{title:J.title,author:J.author||"-",publish_time:J.publishTime||"-",status:"success",size:I(N),saved:A}]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Download utilities: HTTP downloads, yt-dlp wrapper, format conversion.
|
|
3
|
+
*/
|
|
4
|
+
import type { BrowserCookie } from '../types.js';
|
|
5
|
+
export type { BrowserCookie } from '../types.js';
|
|
6
|
+
export interface DownloadOptions {
|
|
7
|
+
cookies?: string;
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
timeout?: number;
|
|
10
|
+
onProgress?: (received: number, total: number) => void;
|
|
11
|
+
maxRedirects?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface YtdlpOptions {
|
|
14
|
+
cookies?: string;
|
|
15
|
+
cookiesFile?: string;
|
|
16
|
+
format?: string;
|
|
17
|
+
extraArgs?: string[];
|
|
18
|
+
onProgress?: (percent: number) => void;
|
|
19
|
+
}
|
|
20
|
+
/** Check if yt-dlp is available in PATH. */
|
|
21
|
+
export declare function checkYtdlp(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Detect content type from URL and optional headers.
|
|
24
|
+
*/
|
|
25
|
+
export declare function detectContentType(url: string, contentType?: string): 'image' | 'video' | 'document' | 'binary';
|
|
26
|
+
/**
|
|
27
|
+
* Check if URL requires yt-dlp for download.
|
|
28
|
+
*/
|
|
29
|
+
export declare function requiresYtdlp(url: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* HTTP download with progress callback.
|
|
32
|
+
*/
|
|
33
|
+
export declare function httpDownload(url: string, destPath: string, options?: DownloadOptions, redirectCount?: number): Promise<{
|
|
34
|
+
success: boolean;
|
|
35
|
+
size: number;
|
|
36
|
+
error?: string;
|
|
37
|
+
}>;
|
|
38
|
+
export declare function resolveRedirectUrl(currentUrl: string, location: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Export cookies to Netscape format for yt-dlp.
|
|
41
|
+
*/
|
|
42
|
+
export declare function exportCookiesToNetscape(cookies: BrowserCookie[], filePath: string): void;
|
|
43
|
+
export declare function formatCookieHeader(cookies: BrowserCookie[]): string;
|
|
44
|
+
/**
|
|
45
|
+
* Download video using yt-dlp.
|
|
46
|
+
*/
|
|
47
|
+
export declare function ytdlpDownload(url: string, destPath: string, options?: YtdlpOptions): Promise<{
|
|
48
|
+
success: boolean;
|
|
49
|
+
size: number;
|
|
50
|
+
error?: string;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Save document content to file.
|
|
54
|
+
*/
|
|
55
|
+
export declare function saveDocument(content: string, destPath: string, format?: 'json' | 'markdown' | 'html' | 'text', metadata?: Record<string, unknown>): Promise<{
|
|
56
|
+
success: boolean;
|
|
57
|
+
size: number;
|
|
58
|
+
error?: string;
|
|
59
|
+
}>;
|
|
60
|
+
/**
|
|
61
|
+
* Sanitize filename by removing invalid characters.
|
|
62
|
+
*/
|
|
63
|
+
export declare function sanitizeFilename(name: string, maxLength?: number): string;
|
|
64
|
+
/**
|
|
65
|
+
* Generate filename from URL if not provided.
|
|
66
|
+
*/
|
|
67
|
+
export declare function generateFilename(url: string, index: number, extension?: string): string;
|
|
68
|
+
/**
|
|
69
|
+
* Get temp directory for cookie files.
|
|
70
|
+
*/
|
|
71
|
+
export declare function getTempDir(): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{spawn as R}from"node:child_process";import*as W from"node:fs";import*as H from"node:path";import*as E from"node:os";import{Readable as v,Transform as U}from"node:stream";import{pipeline as y}from"node:stream/promises";import{URL as _}from"node:url";import{isBinaryInstalled as T}from"../external.js";import{getErrorMessage as L}from"../errors.js";import{fetchWithNodeNetwork as x}from"../node-network.js";import{log as g}from"../logger.js";export function checkYtdlp(){return T("yt-dlp")}const k=["youtube.com","youtu.be","bilibili.com","twitter.com","x.com","tiktok.com","vimeo.com","twitch.tv"];function F(K){let J;try{J=new _(K).hostname.toLowerCase()}catch{return!1}return k.some((Q)=>J===Q||J.endsWith(`.${Q}`))}const f=new Set([".jpg",".jpeg",".png",".gif",".webp",".svg",".ico",".bmp",".avif"]),P=new Set([".mp4",".webm",".avi",".mov",".mkv",".flv",".m3u8",".ts"]),m=new Set([".html",".htm",".json",".xml",".txt",".md",".markdown"]);export function detectContentType(K,J){if(J){if(J.startsWith("image/"))return"image";if(J.startsWith("video/"))return"video";if(J.startsWith("text/")||J.includes("json")||J.includes("xml"))return"document"}let Q="";try{Q=H.extname(new _(K).pathname).toLowerCase()}catch{return"binary"}if(f.has(Q))return"image";if(P.has(Q))return"video";if(F(K))return"video";if(m.has(Q))return"document";return"binary"}export function requiresYtdlp(K){return F(K)}export async function httpDownload(K,J,Q={},Z=0){const{cookies:$,headers:Y={},timeout:z=30000,onProgress:q,maxRedirects:w=10}=Q,A={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",...Y};if($)A.Cookie=$;const D=`${J}.tmp`,M=async()=>{try{await W.promises.rm(D,{force:!0})}catch{}},C=new AbortController,X=setTimeout(()=>C.abort(),z);try{const B=await x(K,{headers:A,signal:C.signal,redirect:"manual"});clearTimeout(X);if(B.status>=300&&B.status<400){const V=B.headers.get("location");if(V){if(Z>=w)return{success:!1,size:0,error:`Too many redirects (> ${w})`};const b=resolveRedirectUrl(K,V),I=new _(K).hostname,S=new _(b).hostname,O=I===S?Q:{...Q,cookies:void 0,headers:u(Q.headers)};return httpDownload(b,J,O,Z+1)}}if(B.status!==200)return{success:!1,size:0,error:`HTTP ${B.status}`};if(!B.body)return{success:!1,size:0,error:"Empty response body"};const j=parseInt(B.headers.get("content-length")||"0",10);let G=0;const N=new U({transform(V,b,I){G+=V.length;if(q)q(G,j);I(null,V)}});try{await W.promises.mkdir(H.dirname(J),{recursive:!0});await y(v.fromWeb(B.body),N,W.createWriteStream(D));await W.promises.rename(D,J);return{success:!0,size:G}}catch(V){await M();return{success:!1,size:0,error:L(V)}}}catch(B){clearTimeout(X);await M();return{success:!1,size:0,error:B instanceof Error?B.message:String(B)}}}export function resolveRedirectUrl(K,J){return new _(J,K).toString()}function u(K){if(!K)return K;return Object.fromEntries(Object.entries(K).filter(([J])=>J.toLowerCase()!=="cookie"))}export function exportCookiesToNetscape(K,J){const Q=["# Netscape HTTP Cookie File","# https://curl.se/docs/http-cookies.html","# This is a generated file! Do not edit.",""];for(const $ of K){const Y=$.domain.startsWith(".")?$.domain:`.${$.domain}`,z="TRUE",q=$.path||"/",w=$.secure?"TRUE":"FALSE",A=typeof $.expirationDate==="number"&&$.expirationDate>0?Math.floor($.expirationDate):Math.floor(Date.now()/1000)+31536000,D=$.name.replace(/[\t\n\r]/g,""),M=$.value.replace(/[\t\n\r]/g,"");Q.push(`${Y} ${z} ${q} ${w} ${A} ${D} ${M}`)}W.mkdirSync(H.dirname(J),{recursive:!0});let Z;try{Z=W.openSync(J,W.constants.O_WRONLY|W.constants.O_CREAT|W.constants.O_TRUNC,384);W.fchmodSync(Z,384);W.writeFileSync(Z,Q.join(`
|
|
2
|
+
`),"utf8")}finally{if(Z!==void 0)W.closeSync(Z)}}export function formatCookieHeader(K){return K.map((J)=>`${J.name}=${J.value}`).join("; ")}export async function ytdlpDownload(K,J,Q={}){const{cookiesFile:Z,format:$="best",extraArgs:Y=[],onProgress:z}=Q;if(!checkYtdlp())return{success:!1,size:0,error:"yt-dlp not installed. Install with: pip install yt-dlp"};return new Promise((q)=>{const w=H.dirname(J);W.mkdirSync(w,{recursive:!0});const A=[K,"-o",J,"-f",$,"--no-playlist","--progress"];if(Z)if(W.existsSync(Z))A.push("--cookies",Z);else{g.warn(`[download] Cookies file not found: ${Z}, falling back to browser cookies`);A.push("--cookies-from-browser","chrome")}else A.push("--cookies-from-browser","chrome");A.push(...Y);const D=R("yt-dlp",A,{stdio:["ignore","pipe","pipe"]});let M=0,C="";D.stderr.on("data",(X)=>{const B=X.toString();C+=B;const j=B.match(/(\d+\.?\d*)%/);if(j&&z){const G=parseFloat(j[1]);if(G>M){M=G;z(G)}}});D.stdout.on("data",(X)=>{const j=X.toString().match(/(\d+\.?\d*)%/);if(j&&z){const G=parseFloat(j[1]);if(G>M){M=G;z(G)}}});D.on("close",(X)=>{if(X===0&&W.existsSync(J)){const B=W.statSync(J);q({success:!0,size:B.size})}else{const B=W.readdirSync(w).filter((j)=>j.startsWith(H.basename(J,H.extname(J))));if(B.length>0){const j=H.join(w,B[0]),G=W.statSync(j);q({success:!0,size:G.size})}else q({success:!1,size:0,error:C.slice(0,200)||`Exit code ${X}`})}});D.on("error",(X)=>{q({success:!1,size:0,error:X.message})})})}export async function saveDocument(K,J,Q="markdown",Z){try{const $=H.dirname(J);W.mkdirSync($,{recursive:!0});let Y;if(Q==="json")Y=JSON.stringify({...Z,content:K},null,2);else if(Q==="markdown")Y=(Z?`---
|
|
3
|
+
${Object.entries(Z).map(([q,w])=>`${q}: ${JSON.stringify(w)}`).join(`
|
|
4
|
+
`)}
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`:"")+K;else Y=K;W.writeFileSync(J,Y,"utf-8");return{success:!0,size:Buffer.byteLength(Y,"utf-8")}}catch($){return{success:!1,size:0,error:L($)}}}export function sanitizeFilename(K,J=200){return K.replace(/[<>:"/\\|?*\x00-\x1f]/g,"_").replace(/\s+/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"").slice(0,J)}export function generateFilename(K,J,Q){try{const Z=new _(K),$=Z.pathname,Y=H.basename($);if(Y&&Y!=="/"&&Y.includes("."))return sanitizeFilename(Y);const z=Q||h(K),q=Z.hostname.replace(/^www\./,"");return sanitizeFilename(`${q}_${J+1}${z}`)}catch{const Z=Q||".bin";return`download_${J+1}${Z}`}}function h(K){switch(detectContentType(K)){case"image":return".jpg";case"video":return".mp4";case"document":return".md";default:return".bin"}}export function getTempDir(){return H.join(E.tmpdir(),"opencli-download")}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media download helper — shared logic for batch downloading images/videos.
|
|
3
|
+
*
|
|
4
|
+
* Used by: xiaohongshu/download, twitter/download, bilibili/download,
|
|
5
|
+
* and future media adapters.
|
|
6
|
+
*
|
|
7
|
+
* Flow: MediaItem[] → DownloadProgressTracker → httpDownload/ytdlpDownload → results
|
|
8
|
+
*/
|
|
9
|
+
import type { BrowserCookie } from '../types.js';
|
|
10
|
+
export interface MediaItem {
|
|
11
|
+
type: 'image' | 'video' | 'video-tweet' | 'video-ytdlp';
|
|
12
|
+
url: string;
|
|
13
|
+
/** Optional custom filename (without directory) */
|
|
14
|
+
filename?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface MediaDownloadOptions {
|
|
17
|
+
output: string;
|
|
18
|
+
/** Subdirectory inside output */
|
|
19
|
+
subdir?: string;
|
|
20
|
+
/** Cookie string for HTTP downloads */
|
|
21
|
+
cookies?: string;
|
|
22
|
+
/** Raw browser cookies — auto-exported to Netscape for yt-dlp, auto-cleaned up */
|
|
23
|
+
browserCookies?: BrowserCookie[];
|
|
24
|
+
/** Timeout in ms (default: 30000 for images, 60000 for videos) */
|
|
25
|
+
timeout?: number;
|
|
26
|
+
/** File name prefix (default: 'download') */
|
|
27
|
+
filenamePrefix?: string;
|
|
28
|
+
/** Extra yt-dlp args */
|
|
29
|
+
ytdlpExtraArgs?: string[];
|
|
30
|
+
/** Whether to show progress (default: true) */
|
|
31
|
+
verbose?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface MediaDownloadResult {
|
|
34
|
+
index: number;
|
|
35
|
+
type: string;
|
|
36
|
+
status: string;
|
|
37
|
+
size: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Batch download media files with progress tracking.
|
|
41
|
+
*
|
|
42
|
+
* Handles:
|
|
43
|
+
* - DownloadProgressTracker for terminal UX
|
|
44
|
+
* - Automatic httpDownload vs ytdlpDownload routing via MediaItem.type
|
|
45
|
+
* - Cookie export to Netscape format for yt-dlp (auto-cleanup)
|
|
46
|
+
* - Directory creation
|
|
47
|
+
* - Error handling with per-file results
|
|
48
|
+
*/
|
|
49
|
+
export declare function downloadMedia(items: MediaItem[], options: MediaDownloadOptions): Promise<MediaDownloadResult[]>;
|