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 @@
|
|
|
1
|
+
import{cli as m,Strategy as t}from"@jackwener/opencli/registry";import{buildMediumTagUrl as a,loadMediumPosts as d}from"./utils.js";m({site:"medium",name:"feed",access:"read",description:"Medium 热门文章 Feed",domain:"medium.com",strategy:t.COOKIE,args:[{name:"topic",default:"",help:"话题标签(如 technology, programming, ai)"},{name:"limit",type:"int",default:20,help:"返回的文章数量"}],columns:["rank","title","author","date","readTime","claps"],func:async(i,e)=>d(i,a(e.topic),Number(e.limit)||20)});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{registerArticleLogin as k}from"../_shared/article/login.js";import{mediumAuthProfile as b}from"./article.js";k({site:"medium",domain:"medium.com",profile:{home:b.home,checkAuth:b.checkAuth},loginDescription:"打开 Medium 首页并等待浏览器完成登录(供桌面客户端引导登录)。"});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as r,Strategy as m}from"@jackwener/opencli/registry";import{buildMediumSearchUrl as t,loadMediumPosts as a}from"./utils.js";r({site:"medium",name:"search",access:"read",description:"搜索 Medium 文章",domain:"medium.com",strategy:m.COOKIE,args:[{name:"keyword",required:!0,positional:!0,help:"搜索关键词"},{name:"limit",type:"int",default:20,help:"返回的文章数量"}],columns:["rank","title","author","date","readTime","claps","url"],func:async(i,e)=>a(i,t(e.keyword),Number(e.limit)||20)});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import{cli as I,Strategy as J}from"@jackwener/opencli/registry";import{EmptyResultError as K}from"@jackwener/opencli/errors";const M="https://medium.com/me/stats?publishedAt=DESC";I({site:"medium",name:"stats",access:"read",description:"Medium 文章数据(每篇曝光/浏览/读完/读完率/收益等运营指标)。首次调用要拉起浏览器会话、偏慢,客户端超时属正常,重试一次即可",domain:"medium.com",strategy:J.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"limit",type:"number",default:20,help:"返回条数"}],columns:["id","type","title","url","published_at","views","likes","comments","collects","shares","displays","reads","read_ratio","earnings","read_time","extra"],func:async(D,G)=>{const H=Math.max(1,Number(G.limit)||20);await D.goto(M);const q=await D.evaluate(`(async () => {
|
|
2
|
+
try {
|
|
3
|
+
if (!location.href.includes('medium.com')) {
|
|
4
|
+
return { error: '未登录 Medium(页面被重定向到 ' + location.href + '),请先在 Chrome 里登录 medium.com' };
|
|
5
|
+
}
|
|
6
|
+
if (location.pathname.includes('/m/signin') || location.pathname === '/') {
|
|
7
|
+
return { error: '未登录 Medium:请先在 Chrome 里登录 medium.com 再运行 medium stats' };
|
|
8
|
+
}
|
|
9
|
+
const limit = ${JSON.stringify(H)};
|
|
10
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
11
|
+
const postsInCache = () => {
|
|
12
|
+
const c = window.__APOLLO_CLIENT__ && window.__APOLLO_CLIENT__.cache;
|
|
13
|
+
if (!c) return null;
|
|
14
|
+
const state = c.extract();
|
|
15
|
+
const posts = [];
|
|
16
|
+
for (const k of Object.keys(state)) {
|
|
17
|
+
if (k.startsWith('Post:') && state[k] && state[k].totalStats) posts.push(state[k]);
|
|
18
|
+
}
|
|
19
|
+
return posts;
|
|
20
|
+
};
|
|
21
|
+
// 等首屏统计数据进缓存(Apollo 客户端 + 至少一篇带 totalStats 的 Post)
|
|
22
|
+
let posts = null;
|
|
23
|
+
for (let i = 0; i < 40; i++) {
|
|
24
|
+
posts = postsInCache();
|
|
25
|
+
if (posts && posts.length > 0) break;
|
|
26
|
+
await sleep(500);
|
|
27
|
+
}
|
|
28
|
+
if (!window.__APOLLO_CLIENT__) return { error: 'Medium 页面没有 Apollo 客户端(页面结构可能已改版),请重试或反馈' };
|
|
29
|
+
if (!posts || posts.length === 0) {
|
|
30
|
+
// 可能确实一篇都没有——再区分:页面文案有 "You haven\\u2019t published" 之类时按空处理
|
|
31
|
+
return { items: [] };
|
|
32
|
+
}
|
|
33
|
+
// 滚动加载更多(stats 列表按滚动分页),直到数量不再增长或已够 limit
|
|
34
|
+
let stall = 0;
|
|
35
|
+
while (posts.length < limit && stall < 3) {
|
|
36
|
+
const before = posts.length;
|
|
37
|
+
window.scrollTo(0, document.body.scrollHeight);
|
|
38
|
+
await sleep(1200);
|
|
39
|
+
posts = postsInCache() || posts;
|
|
40
|
+
stall = posts.length > before ? 0 : stall + 1;
|
|
41
|
+
}
|
|
42
|
+
return { items: posts.slice(0, limit).map((p) => ({
|
|
43
|
+
id: p.id,
|
|
44
|
+
title: p.title || '',
|
|
45
|
+
url: p.mediumUrl || '',
|
|
46
|
+
publishedAt: p.firstPublishedAt || null,
|
|
47
|
+
stats: p.totalStats || {},
|
|
48
|
+
earnings: p.earnings && p.earnings.total ? p.earnings.total : null,
|
|
49
|
+
readingTime: p.readingTime || null,
|
|
50
|
+
visibility: p.visibility || '',
|
|
51
|
+
isLocked: p.isLocked ?? null,
|
|
52
|
+
})) };
|
|
53
|
+
} catch (e) {
|
|
54
|
+
return { error: String((e && e.message) || e) };
|
|
55
|
+
}
|
|
56
|
+
})()`);if(!q||q.error)throw Error(q?.error||"medium stats:evaluate 无返回(浏览器会话异常)");const z=Array.isArray(q.items)?q.items:[];if(z.length===0)throw new K("medium stats","该 Medium 账号没有任何已发布文章。");z.sort((h,x)=>(x.publishedAt||0)-(h.publishedAt||0));return z.map((h)=>{const x=h.stats||{},B=x.views??0,F=x.reads??0,C=h.earnings?Number(h.earnings.units||0)+Number(h.earnings.nanos||0)/1e9:null;return{id:h.id||"",type:"article",title:h.title||"",url:h.url||"",published_at:h.publishedAt?new Date(h.publishedAt).toISOString():"",views:B,likes:"",comments:"",collects:"",shares:"",displays:x.presentations??0,reads:F,read_ratio:B>0?`${(F/B*100).toFixed(1)}%`:"",earnings:C!=null&&C>0?`$${C.toFixed(2)}`:"",read_time:h.readingTime?`${Math.round(h.readingTime)}min`:"",extra:JSON.stringify({visibility:h.visibility||"",is_locked:h.isLocked})}})}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as f,Strategy as w}from"@jackwener/opencli/registry";import{ArgumentError as o,CommandExecutionError as g,EmptyResultError as p}from"@jackwener/opencli/errors";const S=/^[a-z0-9][a-z0-9-]*$/i,x={"&":"&","<":"<",">":">",""":'"',"'":"'","'":"'"," ":" "};function s(t){return String(t??"").replace(/&#x([0-9a-fA-F]+);/g,(e,i)=>String.fromCodePoint(parseInt(i,16))).replace(/&#(\d+);/g,(e,i)=>String.fromCodePoint(parseInt(i,10))).replace(/&(amp|lt|gt|quot|apos|#39|nbsp);/g,(e)=>x[e]||e)}function m(t,e){const i=t.match(new RegExp(`<${e}[^>]*>\\s*<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>\\s*<\\/${e}>`));if(i)return i[1];const n=t.match(new RegExp(`<${e}[^>]*>([\\s\\S]*?)<\\/${e}>`));return n?n[1]:""}function T(t){const e=[],i=/<category(?:[^>]*)>(?:<!\[CDATA\[([\s\S]*?)\]\]>|([\s\S]*?))<\/category>/g;let n;while((n=i.exec(t))!==null){const r=s((n[1]??n[2]??"").trim());if(r)e.push(r)}return e}function y(t){if(!t)return"";const e=new Date(t);if(Number.isNaN(e.getTime()))return"";return e.toISOString().slice(0,10)}function $(t){return s(String(t??"").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim())}function b(t){const e=String(t??"").trim().toLowerCase();if(!e)throw new o('medium tag is required (e.g. "programming", "javascript")');if(!S.test(e))throw new o(`medium tag "${t}" is not valid`,'Tags are lowercase alphanumeric, optionally hyphenated (e.g. "machine-learning").');return e}function C(t,e,i){const n=t??e,r=typeof n==="number"?n:Number(n);if(!Number.isInteger(r)||r<=0)throw new o("medium limit must be a positive integer");if(r>i)throw new o(`medium limit must be <= ${i}`);return r}f({site:"medium",name:"tag",access:"read",description:"Latest Medium articles tagged with a given keyword (RSS feed)",domain:"medium.com",strategy:w.PUBLIC,browser:!1,args:[{name:"tag",positional:!0,required:!0,help:'Lowercase tag slug (e.g. "programming", "machine-learning")'},{name:"limit",type:"int",default:20,help:"Max articles (1-25 — single RSS page)"}],columns:["rank","title","author","description","categories","published","url"],func:async(t)=>{const e=b(t.tag),i=C(t.limit,20,25),n=`https://medium.com/feed/tag/${e}`;let r;try{r=await fetch(n,{headers:{"user-agent":"opencli-medium-adapter (+https://github.com/jackwener/opencli)",accept:"application/rss+xml, application/xml"}})}catch(a){throw new g(`medium tag request failed: ${a?.message??a}`,"Check that medium.com is reachable from this network.")}if(r.status===404)throw new p("medium tag",`Medium tag "${e}" does not exist.`);if(!r.ok)throw new g(`medium tag returned HTTP ${r.status}`);const l=await r.text(),c=[],d=/<item[^>]*>([\s\S]*?)<\/item>/g;let u;while((u=d.exec(l))!==null)c.push(u[1]);if(!c.length)throw new p("medium tag",`Medium tag "${e}" RSS feed has no items.`);return c.slice(0,i).map((a,h)=>({rank:h+1,title:s(m(a,"title")).trim(),author:s(m(a,"dc:creator")).trim(),description:$(m(a,"description")),categories:T(a).join(", "),published:y(s(m(a,"pubDate")).trim()),url:s(m(a,"link")).trim()}))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as i,Strategy as r}from"@jackwener/opencli/registry";import{buildMediumUserUrl as a,loadMediumPosts as t}from"./utils.js";i({site:"medium",name:"user",access:"read",description:"获取 Medium 用户的文章列表",domain:"medium.com",strategy:r.COOKIE,args:[{name:"username",required:!0,positional:!0,help:"Medium 用户名(如 @username 或 username)"},{name:"limit",type:"int",default:20,help:"返回的文章数量"}],columns:["rank","title","date","readTime","claps","url"],func:async(m,e)=>t(m,a(e.username),Number(e.limit)||20)});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import{CommandExecutionError as i}from"@jackwener/opencli/errors";export function buildMediumTagUrl(t){return t?`https://medium.com/tag/${encodeURIComponent(t)}`:"https://medium.com/tag/technology"}export function buildMediumSearchUrl(t){return`https://medium.com/search?q=${encodeURIComponent(t)}`}export function buildMediumUserUrl(t){return t.startsWith("@")?`https://medium.com/${t}`:`https://medium.com/@${t}`}export async function loadMediumPosts(t,r,o){if(!t)throw new i("Browser session required for medium posts");await t.goto(r);await t.wait({selector:"article",timeout:5});const e=await t.evaluate(`
|
|
2
|
+
(async () => {
|
|
3
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
4
|
+
|
|
5
|
+
const limit = ${Math.max(1,Math.min(o,50))};
|
|
6
|
+
const normalize = (value) => (value || '').replace(/\\s+/g, ' ').trim();
|
|
7
|
+
const posts = [];
|
|
8
|
+
const seen = new Set();
|
|
9
|
+
|
|
10
|
+
for (const article of Array.from(document.querySelectorAll('article'))) {
|
|
11
|
+
try {
|
|
12
|
+
const titleEl = article.querySelector('h2, h3, h1');
|
|
13
|
+
const title = normalize(titleEl?.textContent);
|
|
14
|
+
if (!title) continue;
|
|
15
|
+
|
|
16
|
+
const linkEl = titleEl?.closest('a') || article.querySelector('a[href*="/@"], a[href*="/p/"]');
|
|
17
|
+
let url = linkEl?.getAttribute('href') || '';
|
|
18
|
+
if (!url) continue;
|
|
19
|
+
if (!url.startsWith('http')) url = 'https://medium.com' + url;
|
|
20
|
+
if (seen.has(url)) continue;
|
|
21
|
+
|
|
22
|
+
const author = normalize(
|
|
23
|
+
Array.from(article.querySelectorAll('a[href^="/@"]'))
|
|
24
|
+
.map((node) => normalize(node.textContent))
|
|
25
|
+
.find((text) => text && text !== title),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const allText = normalize(article.textContent);
|
|
29
|
+
const dateEl = article.querySelector('time');
|
|
30
|
+
const date = normalize(dateEl?.textContent) ||
|
|
31
|
+
dateEl?.getAttribute('datetime') ||
|
|
32
|
+
allText.match(/\\b(?:[A-Z][a-z]{2}\\s+\\d{1,2}|\\d+[dhmw]\\s+ago)\\b/)?.[0] ||
|
|
33
|
+
'';
|
|
34
|
+
|
|
35
|
+
const readTime = allText.match(/(\\d+)\\s*min\\s*read/i)?.[0] || '';
|
|
36
|
+
const claps = allText.match(/\\b(\\d+(?:\\.\\d+)?[KkMm]?)\\s*claps?\\b/i)?.[1] || '';
|
|
37
|
+
|
|
38
|
+
const description = normalize(
|
|
39
|
+
Array.from(article.querySelectorAll('h3, p'))
|
|
40
|
+
.map((node) => normalize(node.textContent))
|
|
41
|
+
.find((text) => text && text !== title && text !== author && !/member-only story|response icon/i.test(text)),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
seen.add(url);
|
|
45
|
+
posts.push({
|
|
46
|
+
rank: posts.length + 1,
|
|
47
|
+
title,
|
|
48
|
+
author,
|
|
49
|
+
date,
|
|
50
|
+
readTime,
|
|
51
|
+
claps,
|
|
52
|
+
description: description ? description.slice(0, 150) : '',
|
|
53
|
+
url,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
if (posts.length >= limit) break;
|
|
57
|
+
} catch {}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return posts;
|
|
61
|
+
})()
|
|
62
|
+
`);return Array.isArray(e)?e:[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as v,Strategy as x}from"@jackwener/opencli/registry";import{checkLogin as z,cookieQuickCheck as B}from"../_shared/article/auth.js";import{mediumAuthProfile as E}from"./article.js";v({site:"medium",name:"whoami",access:"read",description:"查询当前登录的 Medium 账户信息。",domain:"medium.com",strategy:x.COOKIE,browser:!0,columns:["logged_in","user_id","username"],authStatus:{quickCheck:B("https://medium.com",["sid","uid"])},func:async(q)=>{const b=await z(q,E);return[{logged_in:b.isAuthenticated,user_id:b.userId||"",username:b.username||""}]}});
|
package/clis/mubu/doc.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as r,Strategy as a}from"@jackwener/opencli/registry";import{ArgumentError as m}from"@jackwener/opencli/errors";import{mubuPost as i,nodesToMarkdown as c,nodesToText as s}from"./utils.js";r({site:"mubu",name:"doc",access:"read",description:"读取幕布文档内容(默认输出 Markdown,可用 --output text 输出纯文本)",domain:"mubu.com",strategy:a.COOKIE,defaultFormat:"plain",args:[{name:"id",positional:!0,required:!0,help:"文档 ID"},{name:"output",default:"md",help:"输出格式:md(默认,缩进列表 Markdown,适合导入 Obsidian)或 text(纯文本,适合终端阅读)"}],columns:["content"],func:async(e,n)=>{const{id:d,output:t}=n;if(t!=="md"&&t!=="text")throw new m(`--output 只接受 md 或 text,收到:${t}`);await e.goto("https://mubu.com/app");const u=await i(e,"/document/edit/get",{docId:d});let o=[];try{o=JSON.parse(u.definition).nodes??[]}catch{return[{content:u.name}]}return[{content:t==="md"?c(o):s(o)}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as u,Strategy as l}from"@jackwener/opencli/registry";import{formatDate as s,mubuPost as p}from"./utils.js";u({site:"mubu",name:"docs",access:"read",description:"列出幕布文档(默认根目录,--starred 查看快速访问列表)",domain:"mubu.com",strategy:l.COOKIE,args:[{name:"folder",default:"0",help:"文件夹 ID(默认根目录 0)"},{name:"starred",type:"bool",default:!1,help:"只显示快速访问的文档和文件夹"},{name:"limit",type:"int",default:50,help:"最多显示条数"}],columns:["type","id","name","updated","stared"],func:async(a,e)=>{const{folder:m,starred:o,limit:r}=e;await a.goto("https://mubu.com/app");const d=await p(a,"/list/get",o?{source:"star"}:{folderId:m}),i=(d.folders??[]).map((t)=>({type:"\uD83D\uDCC1",id:t.id,name:t.name,updated:s(t.updateTime),stared:t.stared?"★":""})),n=(d.documents??[]).map((t)=>({type:"\uD83D\uDCC4",id:t.id,name:t.name,updated:s(t.updateTime),stared:t.stared?"★":""}));return[...i,...n].slice(0,r)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as x,Strategy as I}from"@jackwener/opencli/registry";import{ArgumentError as V}from"@jackwener/opencli/errors";import{mubuPost as M,nodesToMarkdown as Y,nodesToText as v,htmlToText as L}from"./utils.js";function P(){const q=new Date;return{year:q.getFullYear(),month:q.getMonth()+1,day:q.getDate()}}function O(q,z){return new Date(q,z,0).getDate()}function _(q,z="年份"){if(!Number.isInteger(q)||q<1)throw new V(`${z} 非法:${q},应为正整数`)}function R(q){if(!Number.isInteger(q)||q<1||q>12)throw new V(`月份非法:${q},应为 1-12`)}function N(q,z,C){const B=O(q,z);if(!Number.isInteger(C)||C<1||C>B)throw new V(`日期非法:${q}-${z}-${C}(${q} 年 ${z} 月共 ${B} 天)`)}function $(q){const z=q.split("-").map(Number);if(z.length!==3||z.some(isNaN))throw new V(`日期格式错误:${q},应为 YYYY-MM-DD`);const[C,B,H]=z;_(C);R(B);N(C,B,H);return{year:C,month:B,day:H}}function f(q){const z=q.split("-").map(Number);if(z.length!==2||z.some(isNaN))throw new V(`月份格式错误:${q},应为 YYYY-MM`);const[C,B]=z;_(C);R(B);return{year:C,month:B}}function X(q){return`${q.year}-${String(q.month).padStart(2,"0")}-${String(q.day).padStart(2,"0")}`}function D(q){const{date:z,month:C,year:B,from:H,to:J}=q;if(H||J){if(!H)throw new V("使用 --to 时必须同时指定 --from");const G=$(H),Q=J?$(J):P();if(X(G)>X(Q))throw new V("--from 不能晚于 --to");return{start:G,end:Q}}if(B!==void 0&&B!==null){_(B,"--year");return{start:{year:B,month:1,day:1},end:{year:B,month:12,day:31}}}if(C){const{year:G,month:Q}=f(C);return{start:{year:G,month:Q,day:1},end:{year:G,month:Q,day:O(G,Q)}}}if(z){const G=$(z);return{start:G,end:G}}const U=P();return{start:U,end:U}}async function S(q,z){const C=await q.evaluate("localStorage.getItem('daily_notes_doc_list')");if(!C)return null;return JSON.parse(C).find((H)=>H.name===`${z}年`)?.id??null}async function u(q,z){const C=await M(q,"/document/edit/get",{docId:z});return JSON.parse(C.definition).nodes??[]}async function E(q,z){const C=await S(q,z);if(!C)return[];const B=await u(q,C),H=[];for(const J of B){const U=parseInt(L(J.text),10);if(!J.children?.length)continue;for(const G of J.children){const Q=L(G.text).replace(/\s+/g," ").trim(),W=Q.replace(/\s/g,"").match(/^(\d+)月(\d+)日/);if(!W)continue;const F=parseInt(W[1],10),b=parseInt(W[2],10);if(F!==U)continue;const j=X({year:z,month:F,day:b});H.push({dateKey:j,label:Q,node:G})}}return H}function A(q,z){const C=[];for(let B=q.year;B<=z.year;B++)C.push(B);return C}x({site:"mubu",name:"notes",access:"read",description:"读取幕布速记(默认今天)。支持 --date/--month/--year/--from/--to 指定时间范围,--list 为概览模式(日期+条数)。",domain:"mubu.com",strategy:I.COOKIE,args:[{name:"list",type:"bool",default:!1,help:"概览模式:只输出日期和条数,不含速记内容。可与任意时间范围参数组合。"},{name:"date",help:"单日,格式 YYYY-MM-DD。不指定时间范围则默认今天(系统本地时间)。"},{name:"month",help:"整月,格式 YYYY-MM。"},{name:"year",type:"int",help:"整年,格式 YYYY(整数)。"},{name:"from",help:"范围起始日,格式 YYYY-MM-DD。须与 --to 同时使用。"},{name:"to",help:"范围截止日,格式 YYYY-MM-DD。须与 --from 同时使用。"},{name:"output",default:"md",help:"输出格式:md(默认,Markdown)或 text(纯文本)"}],columns:["date","content"],func:async(q,z)=>{const{list:C,output:B}=z;if(B!=="md"&&B!=="text")throw new V(`--output 只接受 md 或 text,收到:${B}`);await q.goto("https://mubu.com/app");const{start:H,end:J}=D(z),U=X(H),G=X(J),Z=(await Promise.all(A(H,J).map((F)=>E(q,F)))).flat().filter((F)=>F.dateKey>=U&&F.dateKey<=G);if(Z.length===0)return[{date:U===G?U:`${U} ~ ${G}`,content:"该时间段暂无速记"}];if(C)return Z.map((F)=>({date:F.label,content:`${F.node.children?.length??0} 条记录`}));const W=(F)=>B==="text"?v(F):Y(F);return Z.filter((F)=>F.node.children?.length).map((F)=>({date:F.label,content:W(F.node.children??[])||"(空)"}))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as i,Strategy as n}from"@jackwener/opencli/registry";import{formatDate as u,mubuPost as d}from"./utils.js";i({site:"mubu",name:"recent",access:"read",description:"最近编辑的幕布文档",domain:"mubu.com",strategy:n.COOKIE,args:[{name:"limit",type:"int",default:20,help:"最多显示条数"}],columns:["id","name","updated"],func:async(a,e)=>{const m=e.limit;await a.goto("https://mubu.com/app");return((await d(a,"/list/get",{folderId:"recent"})).documents??[]).slice(0,m).map((t)=>({id:t.id,name:t.name,updated:u(t.updateTime)}))}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as h,Strategy as u}from"@jackwener/opencli/registry";import{mubuPost as d,htmlToText as y}from"./utils.js";h({site:"mubu",name:"search",access:"read",description:"全局搜索幕布文档和文件夹(标题+内容,服务端全量匹配)。结果含 type/id/name/path/hits/snippet 字段。",domain:"mubu.com",strategy:u.COOKIE,args:[{name:"query",positional:!0,required:!0,help:"搜索关键词"},{name:"limit",type:"int",default:100,help:"最多显示条数(默认 100,结果被截断时用 --limit N 调大)"}],columns:["type","id","name","path","hits","snippet"],func:async(s,n)=>{const l=n.query,i=n.limit??100;await s.goto("https://mubu.com/app");const o=await d(s,"/list/search",{keywords:l}),p=(t)=>t.map((a)=>a.name).join(" > "),r=(o.folders??[]).map((t)=>({type:"folder",id:t.id,name:t.name,path:p(t.paths),hits:"",snippet:""})),c=(o.documents??[]).map((t)=>({type:"doc",id:t.id,name:t.name,path:p(t.paths),hits:t.total>0?String(t.total):"",snippet:t.nodes.map((a)=>y(a.text)).filter(Boolean).join(" | ")})),e=[...r,...c],m=e.slice(0,i);if(e.length>i)m.push({type:"...",id:"",name:`还有 ${e.length-i} 条未显示,用 --limit ${e.length} 查看全部`,path:"",hits:"",snippet:""});return m}});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import{AuthRequiredError as L,CommandExecutionError as q}from"@jackwener/opencli/errors";export const API_BASE="https://api2.mubu.com/v3/api";const y="mubu.com",O="Mubu requires a logged-in browser session at mubu.com";function N(V,v){if(V===401||V===403)return!0;if(!v)return!1;return/not logged in|login required|unauthorized|未登录|请先登录|需要登录|login expired/i.test(v)}export async function mubuPost(V,v,J){const z=`${API_BASE}${v}`,Q=await V.evaluate(`
|
|
2
|
+
(async () => {
|
|
3
|
+
const token = localStorage.getItem('Jwt-Token');
|
|
4
|
+
if (!token) return { ok: false, status: 0, data: null, error: 'no token' };
|
|
5
|
+
return await new Promise((resolve) => {
|
|
6
|
+
const xhr = new XMLHttpRequest();
|
|
7
|
+
xhr.open('POST', ${JSON.stringify(z)}, true);
|
|
8
|
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
9
|
+
xhr.setRequestHeader('Jwt-Token', token);
|
|
10
|
+
xhr.onload = () => {
|
|
11
|
+
let data = null;
|
|
12
|
+
try { data = JSON.parse(xhr.responseText); } catch {}
|
|
13
|
+
resolve({ ok: xhr.status >= 200 && xhr.status < 300, status: xhr.status, data });
|
|
14
|
+
};
|
|
15
|
+
xhr.onerror = () => resolve({ ok: false, status: 0, data: null, error: 'network error' });
|
|
16
|
+
xhr.send(${JSON.stringify(JSON.stringify(J))});
|
|
17
|
+
});
|
|
18
|
+
})()
|
|
19
|
+
`);if(!Q||Q.error==="no token")throw new L(y,O);if(!Q.ok||!Q.data)throw new q(`mubu: ${v}: HTTP ${Q.status} ${Q.error??""}`);const{data:K}=Q;if(K.code!==0){if(N(K.code,K.message))throw new L(y,O);throw new q(`mubu: ${v}: code=${K.code} ${K.message??""}`)}return K.data}export function formatDate(V){if(!V)return"";const v=new Date(V),J=(z)=>String(z).padStart(2,"0");return`${v.getFullYear()}-${J(v.getMonth()+1)}-${J(v.getDate())} ${J(v.getHours())}:${J(v.getMinutes())}`}const R={amp:"&",lt:"<",gt:">",quot:'"',apos:"'",nbsp:" "};function G(V){return V.replace(/&#x([0-9a-f]+);/gi,(v,J)=>String.fromCodePoint(parseInt(J,16))).replace(/&#(\d+);/g,(v,J)=>String.fromCodePoint(parseInt(J,10))).replace(/&(amp|lt|gt|quot|apos|nbsp);/g,(v,J)=>R[J])}function C(V){const v=[],J=V.match(/<tr[^>]*>[\s\S]*?<\/tr>/gi)??[];for(const z of J){const Q=[],K=z.match(/<(?:td|th)[^>]*>[\s\S]*?<\/(?:td|th)>/gi)??[];for(const Y of K){let Z=Y.replace(/^<(?:td|th)[^>]*>|<\/(?:td|th)>$/gi,"");Q.push(Z.trim())}v.push(Q)}return v}export function htmlToText(V){let v=V;v=v.replace(/<div class="table-container">[\s\S]*?<\/table>\s*<\/div>/g,(J)=>{return C(J).map((z)=>z.map((Q)=>{let K=Q.replace(/<br\s*\/?>/gi," ").replace(/<[^>]+>/g,"");return G(K).trim()}).join("\t")).join(`
|
|
20
|
+
`)});v=v.replace(/<br\s*\/?>/gi,`
|
|
21
|
+
`).replace(/<[^>]+>/g,"");return G(v).trim()}function j(V){const v=C(V);if(v.length===0)return"";const J=(Q)=>Q.map((K)=>{return K.replace(/<br\s*\/?>/gi,"[[BR]]")}).join(" | "),z=[`| ${J(v[0])} |`,`| ${v[0].map(()=>"---").join(" | ")} |`];for(let Q=1;Q<v.length;Q++)z.push(`| ${J(v[Q])} |`);return z.join(`
|
|
22
|
+
`)}export function htmlToMarkdown(V){let v=V;v=v.replace(/<div class="table-container">[\s\S]*?<\/table>\s*<\/div>/g,(J)=>j(J));v=v.replace(/<br\s*\/?>/gi,`
|
|
23
|
+
`);v=v.replace(/<span class="([^"]+)"[^>]*>([\s\S]*?)<\/span>/gi,(J,z,Q)=>{if(z.includes("node-mention"))return J;let K=Q;if(/\bbold\b/.test(z))K=`**${K}**`;if(/\bitalic\b/.test(z))K=`*${K}*`;if(/\bstrikethrough\b/.test(z))K=`~~${K}~~`;if(/\bunderline\b/.test(z))K=`U_OPEN${K}U_CLOSE`;return K});v=v.replace(/<span([^>]*\bclass="[^"]*\bnode-mention\b[^"]*"[^>]*)>([\s\S]*?)<\/span>/gi,(J,z,Q)=>{const K=z.match(/\bdata-doc="([^"]+)"/i),Y=K?K[1]:"";if(!Y)return J;const Z=z.match(/\bclass="([^"]+)"/i),X=Z?Z[1]:"";let W=Q.replace(/<[^>]+>/g,"").trim();if(/\bbold\b/.test(X))W=`**${W}**`;if(/\bitalic\b/.test(X))W=`*${W}*`;if(/\bstrikethrough\b/.test(X))W=`~~${W}~~`;if(/\bunderline\b/.test(X))W=`U_OPEN${W}U_CLOSE`;return`[${W}](https://mubu.com/app/edit/${Y})`});v=v.replace(/<a([^>]*)>([\s\S]*?)<\/a>/gi,(J,z,Q)=>{const K=z.match(/\bhref="([^"]+)"/i);if(!K)return J;const Y=K[1],Z=z.match(/\bclass="([^"]+)"/i),X=Z?Z[1]:"";let W=Q;if(/\bbold\b/.test(X))W=`**${W}**`;if(/\bitalic\b/.test(X))W=`*${W}*`;if(/\bstrikethrough\b/.test(X))W=`~~${W}~~`;if(/\bunderline\b/.test(X))W=`U_OPEN${W}U_CLOSE`;return`[${W}](${Y})`});v=v.replace(/<span[^>]*>([\s\S]*?)<\/span>/gi,"$1");v=v.replace(/<[^>]+>/g,"");v=G(v);v=v.replace(/\uFFFEU_OPEN\uFFFE/g,"<u>").replace(/\uFFFEU_CLOSE\uFFFE/g,"</u>");v=v.replace(/\[\[BR\]\]/g,"<br>");return v.trim()}const _="https://api2.mubu.com/v3";function P(V){return V.startsWith("http")?V:`${_}/${V}`}function S(V){if(!V.taskStatus)return"";return V.taskStatus===2?"[x] ":"[ ] "}function B(V){const v=[];if(V.deadline){const J=formatDate(V.deadline*1000);v.push(`\uD83D\uDCC5 ${V.deadlineType==="date"?J.slice(0,10):J}`)}if(V.remindAt)v.push(`⏰ ${formatDate(V.remindAt*1000)}`);return v.length?" "+v.join(" "):""}export function nodesToText(V,v=0){const J=[];for(const z of V){const Q=" ".repeat(v),K=z.emoji?z.emoji+" ":"",Y=htmlToText(z.text),Z=S(z),X=B(z);if(Y||K||Z)if(Y.includes(`
|
|
24
|
+
`)){const[W,...$]=Y.split(`
|
|
25
|
+
`);J.push(Q+Z+K+W);for(const F of $)J.push(Q+" "+F);if(X)J.push(Q+" "+X.trim())}else J.push(Q+Z+K+Y+X);if(z.note){const W=htmlToText(z.note);for(const $ of W.split(`
|
|
26
|
+
`))J.push(Q+" "+$)}if(z.images?.length)for(const W of z.images)J.push(Q+`[图片: ${P(W.uri)}]`);if(z.children?.length)J.push(nodesToText(z.children,v+1))}return J.filter(Boolean).join(`
|
|
27
|
+
`)}export function nodesToMarkdown(V,v=0){const J=[];for(const z of V){const Q=htmlToMarkdown(z.text);if(!Q&&!z.images?.length&&!z.note&&!z.emoji)continue;const K=" ".repeat(v),Y=z.emoji?z.emoji+" ":"",Z=S(z),X=B(z);if(Q||Y||Z)if(Q.includes(`
|
|
28
|
+
`)){const[W,...$]=Q.split(`
|
|
29
|
+
`);J.push(K+"- "+Z+Y+W);const F=K+" ";for(const D of $)J.push(F+D);if(X)J.push(F+X.trim())}else J.push(K+"- "+Z+Y+Q+X);if(z.note){const W=htmlToMarkdown(z.note).split(`
|
|
30
|
+
`);for(const $ of W)J.push(K+" > "+$)}if(z.images?.length)for(const W of z.images)J.push(K+` })`);if(z.children?.length)J.push(nodesToMarkdown(z.children,v+1))}return J.filter(Boolean).join(`
|
|
31
|
+
`)}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import{AuthRequiredError as n,CommandExecutionError as o}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as a}from"../_shared/site-auth.js";async function i(t){return(await t.getCookies({url:"https://note.com"})).some((s)=>s.name==="_note_session_v5")}async function r(t){if(!await i(t))throw new n("note.com","note _note_session_v5 cookie missing");await t.goto("https://note.com/");const e=await t.evaluate(`(async () => {
|
|
2
|
+
try {
|
|
3
|
+
const res = await fetch('/api/v2/current_user', { credentials: 'include', headers: { 'Accept': 'application/json' } });
|
|
4
|
+
if (res.status === 401 || res.status === 403) return { kind: 'auth', detail: 'current_user HTTP ' + res.status };
|
|
5
|
+
if (!res.ok) return { kind: 'http', httpStatus: res.status };
|
|
6
|
+
const text = await res.text();
|
|
7
|
+
let json = null; try { json = JSON.parse(text); } catch {}
|
|
8
|
+
const d = json && (json.data || json);
|
|
9
|
+
if (!d || (d.urlname == null && d.id == null)) return { kind: 'auth', detail: 'current_user returned no user — anonymous' };
|
|
10
|
+
return { ok: true, urlname: String(d.urlname || ''), nickname: String(d.nickname || ''), user_id: String(d.id || '') };
|
|
11
|
+
} catch (e) { return { kind: 'exception', detail: String(e && e.message || e) }; }
|
|
12
|
+
})()`);if(e?.kind==="auth")throw new n("note.com",e.detail);if(e?.kind==="http")throw new o(`HTTP ${e.httpStatus} from current_user`);if(e?.kind==="exception")throw new o(`note whoami failed: ${e.detail}`);if(!e?.ok)throw new o(`Unexpected note probe: ${JSON.stringify(e)}`);return{urlname:e.urlname,nickname:e.nickname,url:e.urlname?`https://note.com/${e.urlname}`:""}}a({site:"note",domain:"note.com",loginUrl:"https://note.com/login",columns:["urlname","nickname","url"],quickCheck:i,verify:r,poll:async(t)=>{if(!await i(t))throw new n("note.com","Waiting for note session cookie");return r(t)}});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{ArgumentError as M}from"@jackwener/opencli/errors";export function xsrfTokenFromCookies(B){const q=(B||[]).find((D)=>D&&D.name==="XSRF-TOKEN");if(!q)return"";try{return decodeURIComponent(q.value)}catch{return q.value}}export function noteWriteHeaders(B){return{"Content-Type":"application/json",...B?{"X-XSRF-TOKEN":B}:{}}}function G(B){return String(B??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}export function textToParagraphs(B){const q=String(B??"").replace(/\r\n/g,`
|
|
2
|
+
`).trim();if(!q)return[];return q.split(/\n{2,}/).map((D)=>D.trim()).filter(Boolean)}export function buildBodyHtml(B,q=[]){const D=(B||[]).map((F)=>`<p>${G(F)}</p>`);for(const F of q||[])D.push(`<figure><img src="${G(F)}"></figure>`);return D.join("")}export function bodyLength(B){return String(B??"").length}export function parseHashtags(B){if(!B)return[];return String(B).split(",").map((q)=>q.trim()).filter(Boolean).map((q)=>q.startsWith("#")?q:`#${q}`)}export function parseMagazineIds(B){if(!B)return[];return String(B).split(",").map((q)=>q.trim()).filter(Boolean).map((q)=>{const D=Number(q);if(!Number.isFinite(D))throw new M(`Invalid magazine id "${q}" (expected a number)`);return D})}export function buildDraftSavePayload({title:B,bodyHtml:q,imageKeys:D=[]}){return{name:String(B??""),body:String(q??""),body_length:bodyLength(q),index:!1,is_lead_form:!1,image_keys:D}}export function buildPublishPayload({title:B,bodyHtml:q,hashtags:D=[],magazineIds:F=[],imageKeys:J=[]}){return{name:String(B??""),free_body:String(q??""),pay_body:"",status:"published",price:0,separator:null,is_refund:!1,limited:!1,index:!1,image_keys:J,hashtags:D,magazine_ids:F,body_length:bodyLength(q),send_notifications_flag:!0,lead_form:null,line_add_friend:null}}export function publicUrl(B,q){return`https://note.com/${B}/n/${q}`}export function classifyImages(B){if(!B)return[];return String(B).split(",").map((q)=>q.trim()).filter(Boolean).map((q)=>({kind:/^https?:\/\//i.test(q)?"url":"path",value:q}))}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import*as K from"node:fs";import*as W from"node:path";import{cli as x,Strategy as D}from"@jackwener/opencli/registry";import{AuthRequiredError as f,ArgumentError as v,CommandExecutionError as M}from"@jackwener/opencli/errors";import{xsrfTokenFromCookies as k,noteWriteHeaders as S,textToParagraphs as w,buildBodyHtml as E,parseHashtags as h,parseMagazineIds as b,buildDraftSavePayload as c,buildPublishPayload as y,publicUrl as H,classifyImages as u}from"./note-utils.js";const m=new Set([".jpg",".jpeg",".png",".gif",".webp"]);function P(G){if(G&&typeof G==="object"&&!Array.isArray(G)&&"session"in G&&"data"in G)return G.data;return G}async function z(G,{url:J,method:Z="GET",headers:Q={},body:_=null}){const L=`(async () => {
|
|
2
|
+
try {
|
|
3
|
+
const opts = { method: ${JSON.stringify(Z)}, credentials: 'include', headers: ${JSON.stringify({Accept:"application/json",...Q})} };
|
|
4
|
+
${_!=null?`opts.body = ${JSON.stringify(_)};`:""}
|
|
5
|
+
const res = await fetch(${JSON.stringify(J)}, opts);
|
|
6
|
+
const text = await res.text();
|
|
7
|
+
let data = null; try { data = JSON.parse(text); } catch {}
|
|
8
|
+
return { ok: res.ok, status: res.status, data, text: text.slice(0, 300) };
|
|
9
|
+
} catch (e) { return { ok: false, status: 0, data: null, text: String(e && e.message || e) }; }
|
|
10
|
+
})()`;return P(await G.evaluate(L))}async function U(G,J,Z){const Q=W.resolve(J);if(!m.has(W.extname(Q).toLowerCase()))throw new v(`Unsupported image (jpg/png/gif/webp): ${J}`);const _=K.statSync(Q,{throwIfNoEntry:!1});if(!_||!_.isFile())throw new v(`Not a file: ${Q}`);const L=await z(G,{url:"https://editor.note.com/api/v1/presigns",method:"POST",headers:S(Z),body:JSON.stringify({filename:W.basename(Q)})}),N=L&&L.data&&(L.data.data||L.data),V=N&&N.url,q=N&&(N.s3_url||N.url);if(!L.ok||!V||!q)throw new M(`note image presign failed (best-effort): HTTP ${L.status} ${L.text}`);const R=K.readFileSync(Q).toString("base64"),Y=await G.evaluate(`(async () => {
|
|
11
|
+
try {
|
|
12
|
+
const bin = atob(${JSON.stringify(R)});
|
|
13
|
+
const arr = new Uint8Array(bin.length); for (let i = 0; i < bin.length; i++) arr[i] = bin.charCodeAt(i);
|
|
14
|
+
const res = await fetch(${JSON.stringify(V)}, { method: 'PUT', body: new Blob([arr]) });
|
|
15
|
+
return { ok: res.ok, status: res.status };
|
|
16
|
+
} catch (e) { return { ok: false, status: 0, text: String(e && e.message || e) }; }
|
|
17
|
+
})()`),O=P(Y);if(!O||!O.ok)throw new M(`note image upload PUT failed (best-effort): HTTP ${O?O.status:"?"}`);return q}x({site:"note",name:"publish",access:"write",description:"Publish a text note to note.com (or save a draft with --draft)",domain:"note.com",strategy:D.COOKIE,browser:!0,args:[{name:"title",type:"string",required:!0,positional:!0,help:"Note title"},{name:"body",type:"string",help:"Note body text (blank lines split paragraphs)"},{name:"tags",type:"string",help:"Hashtags, comma-separated (# optional)"},{name:"magazine",type:"string",help:"Magazine id(s) to file under, comma-separated"},{name:"images",type:"string",help:"(best-effort) in-body images: local paths and/or urls"},{name:"draft",type:"boolean",default:!1,help:"Save the draft but do not publish"}],columns:["status","note_key","url"],func:async(G,J)=>{if(!G)throw new M("Browser session required for note publish");const Z=String(J.title??"").trim();if(!Z)throw new v("note publish: title is required");const Q=h(J.tags),_=b(J.magazine),L=u(J.images);await G.goto("https://note.com/");const N=k(await G.getCookies({url:"https://note.com"})),V=await z(G,{url:"https://note.com/api/v2/current_user"}),q=V.data&&(V.data.data||V.data);if(V.status===401||V.status===403||!q||!q.urlname)throw new f("note.com",`Not logged in (current_user HTTP ${V.status})`);const R=String(q.urlname),Y=await z(G,{url:"https://note.com/api/v1/text_notes",method:"POST",headers:S(N),body:JSON.stringify({template_key:null})}),O=Y.data&&(Y.data.data||Y.data);if(!Y.ok||!O||O.id==null)throw new M(`note create-draft failed: HTTP ${Y.status} ${Y.text}`);const j=O.id;let $=O.key?String(O.key):"";const F=[];for(const A of L)F.push(A.kind==="url"?A.value:await U(G,A.value,N));const C=E(w(J.body),F),T=await z(G,{url:`https://note.com/api/v1/text_notes/draft_save?id=${encodeURIComponent(j)}&is_temp_saved=true`,method:"POST",headers:S(N),body:JSON.stringify(c({title:Z,bodyHtml:C}))});if(!T.ok)throw new M(`note draft_save failed: HTTP ${T.status} ${T.text}`);if(J.draft)return{status:"draft",note_key:$,url:$?H(R,$):`https://note.com/notes/${j}/edit`};const B=await z(G,{url:`https://note.com/api/v1/text_notes/${encodeURIComponent(j)}`,method:"PUT",headers:S(N),body:JSON.stringify(y({title:Z,bodyHtml:C,hashtags:Q,magazineIds:_}))});if(!B.ok)throw new M(`note publish failed: HTTP ${B.status} ${B.text}`);const X=B.data&&(B.data.data||B.data);if(X&&X.note_key)$=String(X.note_key);const I=X&&X.public_url||($?H(R,$):`https://note.com/${R}`);return{status:"published",note_key:$,url:I}}});export const __test__={uploadInlineImage:U};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import*as B from"node:fs";import*as L from"node:path";import{cli as U,Strategy as O}from"@jackwener/opencli/registry";import{ArgumentError as q,CommandExecutionError as j}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as h,NOTEBOOKLM_SITE as x}from"./shared.js";import{callNotebooklmRpc as C}from"./rpc.js";import{buildNotebooklmNotebookUrl as P,ensureNotebooklmHome as T,getNotebooklmAuthuser as w,parseNotebooklmNotebookTarget as _,requireNotebooklmExecute as S,requireNotebooklmSession as f,verifyNotebooklmSourceAdded as M}from"./utils.js";const A="izAoDd",b="o4cbdc",F=10485760,X=52428800,v=/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i,m={".pdf":"application/pdf",".txt":"text/plain",".md":"text/markdown",".markdown":"text/markdown",".html":"text/html",".htm":"text/html",".csv":"text/csv",".json":"application/json",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".doc":"application/msword",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".epub":"application/epub+zip",".mp3":"audio/mpeg",".m4a":"audio/mp4",".wav":"audio/wav"};export function inferMimeType(G,Q){if(Q)return String(Q);const V=L.extname(G).toLowerCase();return m[V]||"application/octet-stream"}export function readFileForUpload(G){const Q=L.resolve(G);let V;try{V=B.statSync(Q)}catch{throw new q(`--file path does not exist: ${G}`)}if(!V.isFile())throw new q(`--file path is not a regular file: ${G}`);if(V.size>X)throw new q(`--file exceeds ${X} bytes (got ${V.size}); use a smaller file or upload via the NotebookLM UI for now.`);return{base64:B.readFileSync(Q).toString("base64"),filename:L.basename(Q),size:V.size}}export function buildRegisterFileSourceArgs(G,Q){return[[[Q]],G,[2],[1,null,null,null,null,null,null,null,null,null,[1]]]}export function parseSourceUrl(G){const Q=String(G??"").trim();if(!Q)return"";let V;try{V=new URL(Q)}catch{throw new q(`Invalid source URL: "${Q}"`,"URL must be a valid http:// or https:// URL.")}if(V.protocol!=="http:"&&V.protocol!=="https:"||!V.hostname)throw new q(`Invalid source URL: "${Q}"`,"URL must start with http:// or https://.");return V.toString()}export function parseSourceText(G){if(G===void 0||G===null)return null;const Q=String(G);if(!Q.trim())throw new q("--content must not be empty");if(Q.length>F)throw new q(`--content exceeds ${F} bytes; split into smaller sources or upload as a file.`);return Q}export function parseSourceTitle(G,Q){return String(G??"").trim()||Q}export function buildAddSourceFromUrlArgs(G,Q){return[[[null,null,[Q]]],G]}export function buildAddSourceFromTextArgs(G,Q,V){return[[[null,[Q,V],null,2]],G]}function E(G){return new Set(G.map((Q)=>String(Q??"").toLowerCase()).filter(Boolean))}export function parseAddSourceResult(G,Q=[]){const V=E(Q);if(typeof G==="string")return v.test(G)&&!V.has(G.toLowerCase())?G:"";if(!Array.isArray(G)&&(typeof G!=="object"||G===null))return"";const W=[G];while(W.length){const Z=W.shift();if(typeof Z==="string"){if(v.test(Z)&&!V.has(Z.toLowerCase()))return Z;continue}if(Array.isArray(Z)){for(const $ of Z)W.push($);continue}if(Z&&typeof Z==="object")for(const $ of Object.values(Z))W.push($)}return""}async function I(G,Q,V,W,Z,$){const J=w()||"0",K=`{"PROJECT_ID":${JSON.stringify(Q)},"SOURCE_NAME":${JSON.stringify(W)},"SOURCE_ID":${JSON.stringify(V)}}`,Y=String.raw`(async () => {
|
|
2
|
+
try {
|
|
3
|
+
const initRes = await fetch(${JSON.stringify("https://notebooklm.google.com/upload/_/?authuser="+J)}, {
|
|
4
|
+
method: 'POST',
|
|
5
|
+
credentials: 'include',
|
|
6
|
+
headers: {
|
|
7
|
+
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
8
|
+
'X-Goog-Upload-Command': 'start',
|
|
9
|
+
'X-Goog-Upload-Protocol': 'resumable',
|
|
10
|
+
'X-Goog-Upload-Header-Content-Length': ${JSON.stringify(String($))},
|
|
11
|
+
'X-Goog-AuthUser': ${JSON.stringify(J)},
|
|
12
|
+
},
|
|
13
|
+
body: ${JSON.stringify(K)},
|
|
14
|
+
});
|
|
15
|
+
if (!initRes.ok) {
|
|
16
|
+
const status = initRes.headers.get('X-Goog-Upload-Status') || '';
|
|
17
|
+
const text = (await initRes.text()).slice(0, 400);
|
|
18
|
+
return { error: 'init failed HTTP ' + initRes.status + (status ? ' upload-status=' + status : '') + (text ? ' body=' + text : '') };
|
|
19
|
+
}
|
|
20
|
+
const uploadURL = initRes.headers.get('X-Goog-Upload-Url') || initRes.headers.get('x-goog-upload-url');
|
|
21
|
+
if (!uploadURL) return { error: 'no X-Goog-Upload-URL header in init response' };
|
|
22
|
+
// Decode base64 to Uint8Array for binary PUT
|
|
23
|
+
const bin = atob(${JSON.stringify(Z)});
|
|
24
|
+
const bytes = new Uint8Array(bin.length);
|
|
25
|
+
for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
|
|
26
|
+
const uploadRes = await fetch(uploadURL, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
credentials: 'include',
|
|
29
|
+
headers: {
|
|
30
|
+
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
|
|
31
|
+
'X-Goog-Upload-Command': 'upload, finalize',
|
|
32
|
+
'X-Goog-Upload-Offset': '0',
|
|
33
|
+
'X-Goog-AuthUser': ${JSON.stringify(J)},
|
|
34
|
+
},
|
|
35
|
+
body: bytes,
|
|
36
|
+
});
|
|
37
|
+
if (!uploadRes.ok) {
|
|
38
|
+
const status = uploadRes.headers.get('X-Goog-Upload-Status') || '';
|
|
39
|
+
const text = (await uploadRes.text()).slice(0, 400);
|
|
40
|
+
return { error: 'upload failed HTTP ' + uploadRes.status + (status ? ' upload-status=' + status : '') + (text ? ' body=' + text : '') };
|
|
41
|
+
}
|
|
42
|
+
return { ok: true, status: uploadRes.status };
|
|
43
|
+
} catch (e) {
|
|
44
|
+
return { error: 'upload exception: ' + ((e && e.message) || String(e)) };
|
|
45
|
+
}
|
|
46
|
+
})()`,y=await G.evaluate(Y),H=y&&typeof y==="object"&&"data"in y&&"session"in y?y.data:y;if(!H||H.error)throw new j("NotebookLM file upload failed: "+(H?.error||"unknown error"));return H}U({site:x,name:"add-source",access:"write",description:"Add a URL, text, or local file source to an existing NotebookLM notebook",domain:h,strategy:O.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"notebook",positional:!0,required:!0,help:"Notebook id from `notebooklm list` or full notebook URL"},{name:"url",help:"Source URL to add (http/https). Pass exactly one of --url, --content, --file."},{name:"content",help:"Raw text content to add as a Text source (max 10 MB)."},{name:"file",help:`Local file path to upload as a source (max ${X} bytes; pdf / txt / md / html / docx / etc.). Uses Google Drive's 3-step resumable upload protocol.`},{name:"title",help:'Title for the text source (default "Text Source"). Ignored for --url and --file.'},{name:"mime-type",help:"Override the auto-detected MIME type when --file is given."},{name:"execute",type:"boolean",help:"Actually add the remote source to the NotebookLM notebook"}],columns:["notebook_id","source_id","kind","identifier","notebook_url"],func:async(G,Q)=>{const V=_(String(Q.notebook??"")),W=parseSourceUrl(Q.url),Z=parseSourceText(Q.content),$=typeof Q.file==="string"&&Q.file.trim()?Q.file.trim():"",J=[W?"url":"",Z!==null?"text":"",$?"file":""].filter(Boolean);if(J.length===0)throw new q("Pass exactly one of --url <url>, --content <text>, or --file <path>");if(J.length>1)throw new q("Pass exactly one of --url, --content, --file (got: "+J.join(" + ")+")");S(Q.execute,"add a NotebookLM source");const K=parseSourceTitle(Q.title,"Text Source");await T(G);await f(G);if($){const z=readFileForUpload($),N=inferMimeType(z.filename,Q["mime-type"]),R=await C(G,b,buildRegisterFileSourceArgs(V,z.filename)),D=parseAddSourceResult(R.result,[V]);if(!D)throw new j("NotebookLM AddFileSource (o4cbdc) RPC returned no source id; cannot start file upload.");await I(G,V,D,z.filename,z.base64,z.size);await M(G,V,D,"add-source --file");return[{notebook_id:V,source_id:D,kind:"file",identifier:`${z.filename} (${N}, ${z.size} bytes)`,notebook_url:P(V)}]}const Y=W?buildAddSourceFromUrlArgs(V,W):buildAddSourceFromTextArgs(V,K,Z),y=await C(G,A,Y),H=parseAddSourceResult(y.result,[V]);if(!H)throw new j("NotebookLM AddSources RPC returned no source id; verify the input reaches the NotebookLM backend.");await M(G,V,H,`add-source --${W?"url":"content"}`);return[{notebook_id:V,source_id:H,kind:W?"url":"text",identifier:W||K,notebook_url:P(V)}]}});export const __test__={parseSourceUrl,parseSourceText,parseSourceTitle,inferMimeType,buildAddSourceFromUrlArgs,buildAddSourceFromTextArgs,buildRegisterFileSourceArgs,readFileForUpload,parseAddSourceResult};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import{AuthRequiredError as a,CommandExecutionError as r}from"@jackwener/opencli/errors";import{registerSiteAuthCommands as l}from"../_shared/site-auth.js";async function n(o){const t=await o.getCookies({url:"https://notebooklm.google.com"}),i=new Set(t.filter((e)=>e.value).map((e)=>e.name));return i.has("SID")&&i.has("SAPISID")}async function c(o){if(!await n(o))throw new a("notebooklm.google.com","Google SSO cookies (SID + SAPISID) missing");await o.goto("https://notebooklm.google.com/");await o.wait(3);const t=await o.evaluate(`
|
|
2
|
+
(() => {
|
|
3
|
+
if (/accounts\\.google\\.com\\/ServiceLogin/.test(location.href) || /accounts\\.google\\.com\\/signin/i.test(location.href)) {
|
|
4
|
+
return { kind: 'auth', detail: 'NotebookLM redirected to Google sign-in' };
|
|
5
|
+
}
|
|
6
|
+
const acctEl = document.querySelector('a[aria-label^="Google Account:"], a[aria-label*="Google 账号:"]');
|
|
7
|
+
if (!acctEl) {
|
|
8
|
+
return { kind: 'auth', detail: 'NotebookLM missing Google Account button' };
|
|
9
|
+
}
|
|
10
|
+
const label = acctEl.getAttribute('aria-label') || '';
|
|
11
|
+
const nameMatch = label.match(/Google Account:\\s*([^\\n\\(]+?)(?:\\s*\\n|\\s*\\()/i) ||
|
|
12
|
+
label.match(/Google 账号:\\s*([^\\n\\(]+?)(?:\\s*\\n|\\s*\\()/i);
|
|
13
|
+
const name = nameMatch ? nameMatch[1].trim() : '';
|
|
14
|
+
const authuserMatch = location.href.match(/[?&]authuser=(\\d+)/);
|
|
15
|
+
const authuser = authuserMatch ? Number(authuserMatch[1]) : 0;
|
|
16
|
+
if (!name) {
|
|
17
|
+
return { kind: 'auth', detail: 'NotebookLM Google Account aria-label found but name unparseable' };
|
|
18
|
+
}
|
|
19
|
+
return { ok: true, name, authuser };
|
|
20
|
+
})()
|
|
21
|
+
`);if(t?.kind==="auth")throw new a("notebooklm.google.com",t.detail);if(!t?.ok)throw new r(`Unexpected NotebookLM probe: ${JSON.stringify(t)}`);return{name:t.name,authuser:t.authuser}}l({site:"notebooklm",domain:"google.com",loginUrl:"https://accounts.google.com/ServiceLogin?service=lso&continue=https%3A%2F%2Fnotebooklm.google.com%2F",columns:["name","authuser"],quickCheck:n,verify:c,poll:async(o)=>{if(!await n(o))throw new a("notebooklm.google.com","Waiting for Google SSO cookies (SID + SAPISID)");return c(o)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as Z,Strategy as $}from"@jackwener/opencli/registry";import{ArgumentError as V,CommandExecutionError as f}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as q,NOTEBOOKLM_SITE as H}from"./shared.js";import{callNotebooklmRpc as J}from"./rpc.js";import{buildNotebooklmNotebookUrl as y,ensureNotebooklmHome as S,requireNotebooklmExecute as x,requireNotebooklmSession as D,verifyNotebooklmNotebookExists as L}from"./utils.js";const U="CCqFvf",W="\uD83D\uDCD2",X=200,A=/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;export function parseCreateTitle(z){const h=String(z??"").trim();if(!h)throw new V("<title> is required");if(h.length>X)throw new V(`Title must be at most ${X} characters (got ${h.length})`);return h}export function parseCreateEmoji(z){const h=String(z??"").trim();if(!h)return W;return h}export function parseCreateProjectResult(z){let h=z;while(Array.isArray(h)&&h.length===1&&Array.isArray(h[0]))h=h[0];const F=Array.isArray(h)?typeof h[2]==="string"&&h[2]||typeof h[0]==="string"&&h[0]||"":"";return typeof F==="string"&&A.test(F)?F:""}Z({site:H,name:"create",access:"write",description:"Create a new NotebookLM notebook with the given title",domain:q,strategy:$.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"title",positional:!0,required:!0,help:"Notebook title (1-200 chars)"},{name:"emoji",help:`Notebook emoji icon (default ${W})`},{name:"execute",type:"boolean",help:"Actually create the remote NotebookLM notebook"}],columns:["id","title","emoji","url"],func:async(z,h)=>{const F=parseCreateTitle(h.title),Q=parseCreateEmoji(h.emoji);x(h.execute,"create a NotebookLM notebook");await S(z);await D(z);const Y=await J(z,U,[F,Q]),G=parseCreateProjectResult(Y.result);if(!G)throw new f("NotebookLM CreateProject RPC returned no notebook id");await L(z,G,"create");return[{id:G,title:F,emoji:Q,url:y(G)}]}});export const __test__={parseCreateTitle,parseCreateEmoji,parseCreateProjectResult};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as r,Strategy as n}from"@jackwener/opencli/registry";import{EmptyResultError as e}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as a,NOTEBOOKLM_SITE as i}from"./shared.js";import{getNotebooklmPageState as s,readCurrentNotebooklm as m,requireNotebooklmSession as c}from"./utils.js";r({site:i,name:"current",access:"read",description:"Show metadata for the currently opened NotebookLM notebook tab",domain:a,strategy:n.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["id","title","url","source"],func:async(o)=>{await c(o);if((await s(o)).kind!=="notebook")throw new e("opencli notebooklm current","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");const t=await m(o);if(!t)throw new e("opencli notebooklm current","NotebookLM notebook metadata was not found on the current page.");return[t]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as f,Strategy as b}from"@jackwener/opencli/registry";import{CommandExecutionError as a,EmptyResultError as m}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as p,NOTEBOOKLM_SITE as k}from"./shared.js";import{callNotebooklmRpc as g}from"./rpc.js";import{buildNotebooklmNotebookUrl as s,listNotebooklmSourcesViaRpc as _,parseNotebooklmNotebookTarget as w,requireNotebooklmExecute as O,requireNotebooklmSession as h}from"./utils.js";const N="R7cb6c",c=[2,null,null,[1,null,null,null,null,null,null,null,null,null,[1]],[[1,4,2,3,6]]],d=/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;function E(e){return new Set(e.map((r)=>String(r??"").toLowerCase()).filter(Boolean))}export function buildCreateAudioArgs(e,r){const t=r.map((o)=>[[o]]),n=r.map((o)=>[o]);return[c,e,[null,null,1,t,null,null,[null,[null,null,null,n]]]]}export function parseAudioIdFromResult(e,r=[]){const t=E(r);if(typeof e==="string"&&d.test(e)&&!t.has(e.toLowerCase()))return e;const n=[e];while(n.length){const o=n.shift();if(typeof o==="string"&&d.test(o)&&!t.has(o.toLowerCase()))return o;if(Array.isArray(o))for(const l of o)n.push(l);else if(o&&typeof o==="object")for(const l of Object.values(o))n.push(l)}return""}f({site:k,name:"generate-audio",access:"write",description:"Trigger an Audio Overview (Deep Dive podcast) generation for a NotebookLM notebook, using all of its sources",domain:p,strategy:b.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"notebook",positional:!0,required:!0,help:"Notebook id from `notebooklm list` or full notebook URL"},{name:"execute",type:"boolean",help:"Actually trigger remote NotebookLM audio generation"}],columns:["notebook_id","audio_id","source_count","status","notebook_url"],func:async(e,r)=>{const t=w(String(r.notebook??""));O(r.execute,"generate NotebookLM audio");try{await e.goto(s(t));await e.wait(2)}catch(i){throw new a(`Failed to open NotebookLM notebook ${t}: ${i?.message||i}`)}await h(e);const o=(await _(e)).map((i)=>i.id).filter((i)=>typeof i==="string"&&i);if(o.length===0)throw new m("notebooklm generate-audio","The notebook has no sources; add a source before generating an audio overview.");const l=await g(e,N,buildCreateAudioArgs(t,o)),u=parseAudioIdFromResult(l.result,[t,...o]);if(!u)throw new a("NotebookLM CreateAudioOverview RPC returned no audio id; server may have rejected the request.");return[{notebook_id:t,audio_id:u,source_count:o.length,status:"pending",notebook_url:s(t)}]}});export const __test__={AUDIO_OVERVIEW_CONFIG_BLOCK:c,buildCreateAudioArgs,parseAudioIdFromResult};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as y,Strategy as B}from"@jackwener/opencli/registry";import{ArgumentError as D,CommandExecutionError as X,EmptyResultError as F}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as K,NOTEBOOKLM_SITE as L}from"./shared.js";import{callNotebooklmRpc as M}from"./rpc.js";import{buildNotebooklmNotebookUrl as Y,listNotebooklmSourcesViaRpc as N,parseNotebooklmNotebookTarget as P,requireNotebooklmExecute as S,requireNotebooklmSession as U}from"./utils.js";const j="R7cb6c",Z=[2,null,null,[1,null,null,null,null,null,null,null,null,null,[1]],[[1,4,2,3,6]]],$=/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;function A(f){return new Set(f.map((q)=>String(q??"").toLowerCase()).filter(Boolean))}export function buildCreateSlidesArgs(f,q,z={}){const H=q.map((V)=>[[V]]),G=z.language||"en",Q=Number.isInteger(z.length)?z.length:3;return[Z,f,[null,null,8,H,null,null,null,null,null,null,null,null,null,null,null,null,[[null,G,1,Q]]]]}export function parseSlidesIdFromResult(f,q=[]){const z=A(q);if(typeof f==="string"&&$.test(f)&&!z.has(f.toLowerCase()))return f;const H=[f];while(H.length){const G=H.shift();if(typeof G==="string"&&$.test(G)&&!z.has(G.toLowerCase()))return G;if(Array.isArray(G))for(const Q of G)H.push(Q);else if(G&&typeof G==="object")for(const Q of Object.values(G))H.push(Q)}return""}export function parseSlideDeckLength(f){if(f===void 0||f==="")return 3;const q=Number(f);if(!Number.isInteger(q)||q<=0)throw new D("--length must be a positive integer");return q}y({site:L,name:"generate-slides",access:"write",description:"Trigger a Slide Deck (AI presentation) generation for a NotebookLM notebook, using all of its sources",domain:K,strategy:B.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"notebook",positional:!0,required:!0,help:"Notebook id from `notebooklm list` or full notebook URL"},{name:"length",help:"Slide deck length: 1=Short, 3=Default (default 3)"},{name:"language",help:"Language code (default en)"},{name:"execute",type:"boolean",help:"Actually trigger remote NotebookLM slide deck generation"}],columns:["notebook_id","slides_id","source_count","status","notebook_url"],func:async(f,q)=>{const z=P(String(q.notebook??"")),H=parseSlideDeckLength(q.length),G=String(q.language??"en").trim()||"en";S(q.execute,"generate NotebookLM slides");try{await f.goto(Y(z));await f.wait(2)}catch(J){throw new X(`Failed to open NotebookLM notebook ${z}: ${J?.message||J}`)}await U(f);const V=(await N(f)).map((J)=>J.id).filter((J)=>typeof J==="string"&&J);if(V.length===0)throw new F("notebooklm generate-slides","The notebook has no sources; add a source before generating a slide deck.");const m=await M(f,j,buildCreateSlidesArgs(z,V,{length:H,language:G})),W=parseSlidesIdFromResult(m.result,[z,...V]);if(!W)throw new X("NotebookLM CreateArtifact (slides) RPC returned no slide-deck id; the server may have rejected the request.");return[{notebook_id:z,slides_id:W,source_count:V.length,status:"pending",notebook_url:Y(z)}]}});export const __test__={SLIDE_DECK_CONFIG_BLOCK:Z,buildCreateSlidesArgs,parseSlideDeckLength,parseSlidesIdFromResult};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as n,Strategy as a}from"@jackwener/opencli/registry";import{EmptyResultError as r}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as i,NOTEBOOKLM_SITE as s}from"./shared.js";import{getNotebooklmDetailViaRpc as c,getNotebooklmPageState as l,readCurrentNotebooklm as u,requireNotebooklmSession as m}from"./utils.js";n({site:s,name:"get",access:"read",aliases:["metadata"],description:"Get rich metadata for the currently opened NotebookLM notebook",domain:i,strategy:a.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["id","title","emoji","source_count","created_at","updated_at","url","source"],func:async(o)=>{await m(o);if((await l(o)).kind!=="notebook")throw new r("opencli notebooklm get","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");const t=await c(o).catch(()=>null);if(t)return[t];const e=await u(o);if(!e)throw new r("opencli notebooklm get","NotebookLM notebook metadata was not found on the current page.");return[{...e,emoji:null,source_count:null,updated_at:null}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as t,Strategy as e}from"@jackwener/opencli/registry";import{EmptyResultError as r}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as i,NOTEBOOKLM_SITE as s}from"./shared.js";import{getNotebooklmPageState as n,listNotebooklmHistoryViaRpc as a,requireNotebooklmSession as m}from"./utils.js";t({site:s,name:"history",access:"read",description:"List NotebookLM conversation history threads in the current notebook",domain:i,strategy:e.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["thread_id","item_count","preview","source","notebook_id","url"],func:async(o)=>{await m(o);if((await n(o)).kind!=="notebook")throw new r("opencli notebooklm history","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");return await a(o)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as i,Strategy as n}from"@jackwener/opencli/registry";import{AuthRequiredError as s}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as a,NOTEBOOKLM_SITE as c}from"./shared.js";import{ensureNotebooklmHome as l,listNotebooklmLinks as m,listNotebooklmViaRpc as u,readCurrentNotebooklm as f,requireNotebooklmSession as b}from"./utils.js";i({site:c,name:"list",access:"read",description:"List NotebookLM notebooks via in-page batchexecute RPC in the current logged-in session",domain:a,strategy:n.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["title","id","is_owner","created_at","source","url"],func:async(t)=>{const r=await f(t).catch(()=>null);await l(t);await b(t);try{const o=await u(t);if(o.length>0)return o}catch(o){if(o instanceof s)throw o}const e=await m(t);if(e.length>0)return e;if(r)return[r];return[]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as n,Strategy as r}from"@jackwener/opencli/registry";import{EmptyResultError as t}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as i,NOTEBOOKLM_SITE as s}from"./shared.js";import{getNotebooklmPageState as a,listNotebooklmNotesFromPage as l,requireNotebooklmSession as m}from"./utils.js";n({site:s,name:"note-list",access:"read",aliases:["notes-list"],description:"List saved notes from the Studio panel of the current NotebookLM notebook",domain:i,strategy:r.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["title","created_at","source","url"],func:async(o)=>{await m(o);if((await a(o)).kind!=="notebook")throw new t("opencli notebooklm note-list","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");const e=await l(o);if(e.length>0)return e;throw new t("opencli notebooklm note-list","No NotebookLM notes are visible in the Studio panel. Reload the notebook page or close the note editor and retry.")}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as U,Strategy as W}from"@jackwener/opencli/registry";import{EmptyResultError as J}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as X,NOTEBOOKLM_SITE as Y}from"./shared.js";import{findNotebooklmNoteRow as Z,getNotebooklmPageState as $,listNotebooklmNotesFromPage as c,readNotebooklmVisibleNoteFromPage as f,requireNotebooklmSession as h}from"./utils.js";function A(x,C){const G=C.trim().toLowerCase();if(!G)return!1;const j=x.trim().toLowerCase();return j===G||j.includes(G)}U({site:Y,name:"notes-get",access:"read",description:"Get one note from the current NotebookLM notebook by title from the visible note editor",domain:X,strategy:W.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"note",positional:!0,required:!0,help:"Note title or id from the current notebook"}],columns:["title","content","source","url"],func:async(x,C)=>{await h(x);if((await $(x)).kind!=="notebook")throw new J("opencli notebooklm notes-get","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");const j=typeof C.note==="string"?C.note:String(C.note??""),H=await f(x);if(H&&A(H.title,j))return[H];const Q=await c(x);if(Z(Q,j))throw new J("opencli notebooklm notes-get",`Note "${j}" is listed in Studio, but opencli currently reads note content only from the visible note editor. Open that note in NotebookLM, then retry.`);throw new J("opencli notebooklm notes-get",`Note "${j}" was not found in the current notebook.`)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as i,Strategy as a}from"@jackwener/opencli/registry";import{CliError as s,EmptyResultError as b}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as l,NOTEBOOKLM_SITE as k}from"./shared.js";import{buildNotebooklmNotebookUrl as d,getNotebooklmPageState as m,parseNotebooklmNotebookTarget as u,readCurrentNotebooklm as p,requireNotebooklmSession as c}from"./utils.js";i({site:k,name:"open",access:"read",aliases:["select"],description:"Open one NotebookLM notebook in the adapter session by id or URL",domain:l,strategy:a.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"notebook",positional:!0,required:!0,help:"Notebook id from list output, or a full NotebookLM notebook URL"}],columns:["id","title","url","source"],func:async(o,r)=>{const t=u(String(r.notebook??""));await o.goto(d(t));await o.wait(2);await c(o);const e=await m(o);if(e.kind!=="notebook")throw new s("NOTEBOOKLM_OPEN_FAILED",`NotebookLM notebook "${t}" did not open in the adapter session`,"Run `opencli notebooklm list -f json` first and pass a valid notebook id.");if(e.notebookId!==t)console.warn(`[notebooklm open] expected notebook "${t}" but page reports "${e.notebookId}"; continuing`);const n=await p(o);if(!n)throw new b("opencli notebooklm open","NotebookLM notebook metadata was not found after navigation.");return[n]}});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import{AuthRequiredError as $,CliError as W}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as Y}from"./shared.js";export function unwrapNotebooklmEvaluateResult(j){if(j&&typeof j==="object"&&!Array.isArray(j)&&"session"in j&&"data"in j)return j.data;return j}export function extractNotebooklmPageAuthFromHtml(j,z="/",S){const J=j.match(/"SNlM0e":"([^"]+)"/),U=j.match(/"FdrFJe":"([^"]+)"/),Q=S?.csrfToken?.trim()||(J?J[1]:""),G=S?.sessionId?.trim()||(U?U[1]:"");if(!Q||!G)throw new W("NOTEBOOKLM_TOKENS","NotebookLM page tokens were not found in the current page HTML","Open the NotebookLM notebook page in Chrome, wait for it to finish loading, then retry with --verbose if it still fails.");return{csrfToken:Q,sessionId:G,sourcePath:z||"/",authuser:S?.authuser??""}}async function F(j){const z=unwrapNotebooklmEvaluateResult(await j.evaluate(`(() => {
|
|
2
|
+
const wiz = window.WIZ_global_data || {};
|
|
3
|
+
const html = document.documentElement.innerHTML;
|
|
4
|
+
const authMatch = (location.search || '').match(/[?&]authuser=(\\d+)/);
|
|
5
|
+
const pathMatch = (location.pathname || '').match(/^\\/u\\/(\\d+)\\//);
|
|
6
|
+
return {
|
|
7
|
+
html,
|
|
8
|
+
sourcePath: location.pathname || '/',
|
|
9
|
+
readyState: document.readyState || '',
|
|
10
|
+
csrfToken: typeof wiz.SNlM0e === 'string' ? wiz.SNlM0e : '',
|
|
11
|
+
sessionId: typeof wiz.FdrFJe === 'string' ? wiz.FdrFJe : '',
|
|
12
|
+
authuser: authMatch ? authMatch[1] : (pathMatch ? pathMatch[1] : ''),
|
|
13
|
+
};
|
|
14
|
+
})()`));return{html:String(z?.html??""),sourcePath:String(z?.sourcePath??"/"),readyState:String(z?.readyState??""),csrfToken:String(z?.csrfToken??""),sessionId:String(z?.sessionId??""),authuser:String(z?.authuser??"")}}export async function getNotebooklmPageAuth(j){let z;for(let S=0;S<2;S+=1){const J=await F(j);try{return extractNotebooklmPageAuthFromHtml(J.html,J.sourcePath,{csrfToken:J.csrfToken,sessionId:J.sessionId,authuser:J.authuser})}catch(U){z=U;if(S===0&&typeof j.wait==="function"){await j.wait(0.5).catch(()=>{return});continue}}}throw z}export function buildNotebooklmRpcBody(j,z,S){const J=[[[j,JSON.stringify(z),null,"generic"]]];return`f.req=${encodeURIComponent(JSON.stringify(J))}&at=${encodeURIComponent(S)}&`}export function stripNotebooklmAntiXssi(j){if(!j.startsWith(")]}'"))return j;return j.replace(/^\)\]\}'\r?\n/,"")}export function parseNotebooklmChunkedResponse(j){const z=stripNotebooklmAntiXssi(j).trim();if(!z)return[];const S=z.split(`
|
|
15
|
+
`),J=[];for(let U=0;U<S.length;U+=1){const Q=S[U].trim();if(!Q)continue;if(/^\d+$/.test(Q)){const G=S[U+1];if(!G)continue;try{J.push(JSON.parse(G))}catch{}U+=1;continue}if(Q.startsWith("["))try{J.push(JSON.parse(Q))}catch{}}return J}export function extractNotebooklmRpcResult(j,z){const S=parseNotebooklmChunkedResponse(j);for(const J of S){if(!Array.isArray(J))continue;const U=Array.isArray(J[0])?J:[J];for(const Q of U){if(!Array.isArray(Q)||Q.length<1)continue;if(Q[0]==="er"){const G=typeof Q[2]==="number"?Q[2]:typeof Q[5]==="number"?Q[5]:null;if(G===401||G===403)throw new $(Y,`NotebookLM RPC returned auth error (${G})`);throw new W("NOTEBOOKLM_RPC",`NotebookLM RPC failed${G?` (code=${G})`:""}`,"Retry from an already logged-in NotebookLM session, or inspect the raw response with debug logging.")}if(Q[0]==="wrb.fr"&&Q[1]===z){const G=Q[2];if(typeof G==="string")try{return JSON.parse(G)}catch{return G}return G}}}return null}export async function fetchNotebooklmInPage(j,z,S={}){const J=S.method??"GET",U=S.headers??{},Q=S.body??"",G=unwrapNotebooklmEvaluateResult(await j.evaluate(`(async () => {
|
|
16
|
+
const request = {
|
|
17
|
+
url: ${JSON.stringify(z)},
|
|
18
|
+
method: ${JSON.stringify(J)},
|
|
19
|
+
headers: ${JSON.stringify(U)},
|
|
20
|
+
body: ${JSON.stringify(Q)},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const response = await fetch(request.url, {
|
|
24
|
+
method: request.method,
|
|
25
|
+
headers: request.headers,
|
|
26
|
+
body: request.method === 'GET' ? undefined : request.body,
|
|
27
|
+
credentials: 'include',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
ok: response.ok,
|
|
32
|
+
status: response.status,
|
|
33
|
+
body: await response.text(),
|
|
34
|
+
finalUrl: response.url,
|
|
35
|
+
};
|
|
36
|
+
})()`));return{ok:Boolean(G?.ok),status:Number(G?.status??0),body:String(G?.body??""),finalUrl:String(G?.finalUrl??z)}}export async function callNotebooklmRpc(j,z,S,J={}){const U=await getNotebooklmPageAuth(j),Q=buildNotebooklmRpcBody(z,S,U.csrfToken),G=U.authuser||"",Z=`https://${Y}/_/LabsTailwindUi/data/batchexecute?rpcids=${z}&source-path=${encodeURIComponent(U.sourcePath)}`+(G?`&authuser=${encodeURIComponent(G)}`:"")+`&hl=${encodeURIComponent(J.hl??"en")}&f.sid=${encodeURIComponent(U.sessionId)}&rt=c`,V=await fetchNotebooklmInPage(j,Z,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded;charset=UTF-8"},body:Q});if(V.status===401||V.status===403)throw new $(Y,`NotebookLM RPC returned auth error (${V.status})`);if(!V.ok)throw new W("NOTEBOOKLM_RPC",`NotebookLM RPC request failed with HTTP ${V.status}`,"Retry from the NotebookLM home page in an already logged-in Chrome session.");return{auth:U,url:Z,requestBody:Q,response:V,result:extractNotebooklmRpcResult(V.body,z)}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const NOTEBOOKLM_SITE="notebooklm",NOTEBOOKLM_DOMAIN="notebooklm.google.com",NOTEBOOKLM_HOME_URL="https://notebooklm.google.com/";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as G,Strategy as H}from"@jackwener/opencli/registry";import{EmptyResultError as n}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as I,NOTEBOOKLM_SITE as J}from"./shared.js";import{findNotebooklmSourceRow as K,getNotebooklmPageState as L,getNotebooklmSourceFulltextViaRpc as M,listNotebooklmSourcesFromPage as O,listNotebooklmSourcesViaRpc as P,requireNotebooklmSession as Q}from"./utils.js";G({site:J,name:"source-fulltext",access:"read",description:"Get the extracted fulltext for one source in the currently opened NotebookLM notebook",domain:I,strategy:H.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"source",positional:!0,required:!0,help:"Source id or title from the current notebook"}],columns:["title","kind","char_count","url","source"],func:async(j,v)=>{await Q(j);if((await L(j)).kind!=="notebook")throw new n("opencli notebooklm source-fulltext","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");const A=await P(j).catch(()=>[]),B=A.length>0?A:await O(j);if(B.length===0)throw new n("opencli notebooklm source-fulltext","No NotebookLM sources were found on the current page.");const C=typeof v.source==="string"?v.source:String(v.source??""),z=K(B,C);if(!z)throw new n("opencli notebooklm source-fulltext",`Source "${C}" was not found in the current notebook.`);const D=await M(j,z.id).catch(()=>null);if(D)return[D];throw new n("opencli notebooklm source-fulltext",`NotebookLM fulltext was not available for source "${z.title}".`)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as c,Strategy as u}from"@jackwener/opencli/registry";import{EmptyResultError as t}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as a,NOTEBOOKLM_SITE as l}from"./shared.js";import{findNotebooklmSourceRow as m,getNotebooklmPageState as b,listNotebooklmSourcesFromPage as p,listNotebooklmSourcesViaRpc as d,requireNotebooklmSession as f}from"./utils.js";c({site:l,name:"source-get",access:"read",description:"Get one source from the currently opened NotebookLM notebook by id or title",domain:a,strategy:u.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"source",positional:!0,required:!0,help:"Source id or title from the current notebook"}],columns:["title","id","type","size","created_at","updated_at","url","source"],func:async(o,e)=>{await f(o);if((await b(o)).kind!=="notebook")throw new t("opencli notebooklm source-get","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");const r=await d(o).catch(()=>[]),n=r.length>0?r:await p(o);if(n.length===0)throw new t("opencli notebooklm source-get","No NotebookLM sources were found on the current page.");const i=typeof e.source==="string"?e.source:String(e.source??""),s=m(n,i);if(s)return[s];throw new t("opencli notebooklm source-get",`Source "${i}" was not found in the current notebook.`)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as u,Strategy as a}from"@jackwener/opencli/registry";import{EmptyResultError as e}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as l,NOTEBOOKLM_SITE as m}from"./shared.js";import{findNotebooklmSourceRow as d,getNotebooklmPageState as b,getNotebooklmSourceGuideViaRpc as k,listNotebooklmSourcesFromPage as w,listNotebooklmSourcesViaRpc as f,requireNotebooklmSession as p}from"./utils.js";u({site:m,name:"source-guide",access:"read",description:"Get the guide summary and keywords for one source in the currently opened NotebookLM notebook",domain:l,strategy:a.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"source",positional:!0,required:!0,help:"Source id or title from the current notebook"}],columns:["source_id","notebook_id","title","type","summary","keywords","source"],func:async(o,t)=>{await p(o);if((await b(o)).kind!=="notebook")throw new e("opencli notebooklm source-guide","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");const n=await f(o).catch(()=>[]),i=n.length>0?n:await w(o);if(i.length===0)throw new e("opencli notebooklm source-guide","No NotebookLM sources were found on the current page.");const s=typeof t.source==="string"?t.source:String(t.source??""),r=d(i,s);if(!r)throw new e("opencli notebooklm source-guide",`Source "${s}" was not found in the current notebook.`);const c=await k(o,r).catch(()=>null);if(c)return[c];throw new e("opencli notebooklm source-guide",`NotebookLM guide was not available for source "${r.title}".`)}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as s,Strategy as n}from"@jackwener/opencli/registry";import{EmptyResultError as r}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as i,NOTEBOOKLM_SITE as a}from"./shared.js";import{getNotebooklmPageState as c,listNotebooklmSourcesFromPage as l,listNotebooklmSourcesViaRpc as m,requireNotebooklmSession as u}from"./utils.js";s({site:a,name:"source-list",access:"read",description:"List sources for the currently opened NotebookLM notebook",domain:i,strategy:n.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["title","id","type","size","created_at","updated_at","url","source"],func:async(o)=>{await u(o);if((await c(o)).kind!=="notebook")throw new r("opencli notebooklm source-list","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");const e=await m(o).catch(()=>[]);if(e.length>0)return e;const t=await l(o);if(t.length>0)return t;throw new r("opencli notebooklm source-list","No NotebookLM sources were found on the current page.")}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as i,Strategy as n}from"@jackwener/opencli/registry";import{NOTEBOOKLM_DOMAIN as o,NOTEBOOKLM_HOME_URL as r,NOTEBOOKLM_SITE as s}from"./shared.js";import{getNotebooklmPageState as l}from"./utils.js";i({site:s,name:"status",access:"read",description:"Check NotebookLM page availability and login state in the current Chrome session",domain:o,strategy:n.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["status","login","page","url","title","notebooks"],func:async(e)=>{const a=await e.getCurrentUrl?.().catch(()=>null);if(!a||!a.includes(o)){await e.goto(r);await e.wait(2)}const t=await l(e);return[{status:t.hostname===o?"Connected":"Unavailable",login:t.loginRequired?"Required":"OK",page:t.kind,url:t.url,title:t.title,notebooks:t.notebookCount}]}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cli as m,Strategy as a}from"@jackwener/opencli/registry";import{EmptyResultError as r}from"@jackwener/opencli/errors";import{NOTEBOOKLM_DOMAIN as n,NOTEBOOKLM_SITE as s}from"./shared.js";import{getNotebooklmPageState as i,getNotebooklmSummaryViaRpc as u,readNotebooklmSummaryFromPage as c,requireNotebooklmSession as l}from"./utils.js";m({site:s,name:"summary",access:"read",description:"Get the summary block from the currently opened NotebookLM notebook",domain:n,strategy:a.COOKIE,browser:!0,navigateBefore:!1,args:[],columns:["title","summary","source","url"],func:async(o)=>{await l(o);if((await i(o)).kind!=="notebook")throw new r("opencli notebooklm summary","No NotebookLM notebook is open in the adapter session. Run `opencli notebooklm open <notebook>` first.");const t=await c(o);if(t)return[t];const e=await u(o).catch(()=>null);if(e)return[e];throw new r("opencli notebooklm summary","NotebookLM summary was not found on the current page.")}});
|