@jackwener/opencli 1.7.11 → 1.7.12
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/README.zh-CN.md +2 -1
- package/cli-manifest.json +1417 -24
- package/clis/1688/assets.js +1 -0
- package/clis/1688/download.js +1 -0
- package/clis/1688/item.js +1 -0
- package/clis/1688/search.js +2 -1
- package/clis/1688/store.js +1 -0
- package/clis/36kr/article.js +1 -0
- package/clis/36kr/hot.js +1 -0
- package/clis/36kr/news.js +1 -0
- package/clis/36kr/search.js +1 -0
- package/clis/51job/company.js +1 -0
- package/clis/51job/detail.js +1 -0
- package/clis/51job/hot.js +1 -0
- package/clis/51job/search.js +1 -0
- package/clis/amazon/bestsellers.js +1 -0
- package/clis/amazon/discussion.js +1 -0
- package/clis/amazon/movers-shakers.js +1 -0
- package/clis/amazon/new-releases.js +1 -0
- package/clis/amazon/offer.js +1 -0
- package/clis/amazon/product.js +1 -0
- package/clis/amazon/rankings.js +1 -0
- package/clis/amazon/search.js +1 -0
- package/clis/antigravity/dump.js +1 -0
- package/clis/antigravity/extract-code.js +1 -0
- package/clis/antigravity/model.js +1 -0
- package/clis/antigravity/new.js +1 -0
- package/clis/antigravity/read.js +1 -0
- package/clis/antigravity/send.js +1 -0
- package/clis/antigravity/status.js +1 -0
- package/clis/antigravity/watch.js +1 -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/arxiv/arxiv.test.js +112 -0
- package/clis/arxiv/paper.js +4 -3
- package/clis/arxiv/recent.js +33 -0
- package/clis/arxiv/search.js +19 -7
- package/clis/arxiv/utils.js +68 -5
- package/clis/baidu-scholar/search.js +1 -0
- package/clis/band/bands.js +1 -0
- package/clis/band/mentions.js +1 -0
- package/clis/band/post.js +1 -0
- package/clis/band/posts.js +1 -0
- package/clis/barchart/flow.js +1 -0
- package/clis/barchart/greeks.js +1 -0
- package/clis/barchart/options.js +1 -0
- package/clis/barchart/quote.js +1 -0
- package/clis/bbc/news.js +1 -0
- package/clis/bilibili/comments.js +1 -0
- package/clis/bilibili/download.js +1 -0
- package/clis/bilibili/dynamic.js +1 -0
- package/clis/bilibili/favorite.js +1 -0
- package/clis/bilibili/feed.js +2 -0
- package/clis/bilibili/following.js +1 -0
- package/clis/bilibili/history.js +1 -0
- package/clis/bilibili/hot.js +6 -1
- package/clis/bilibili/hot.test.js +17 -0
- package/clis/bilibili/me.js +1 -1
- package/clis/bilibili/ranking.js +1 -0
- package/clis/bilibili/search.js +1 -1
- package/clis/bilibili/subtitle.js +1 -0
- package/clis/bilibili/user-videos.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 +1 -0
- package/clis/bloomberg/economics.js +1 -0
- package/clis/bloomberg/feeds.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 +1 -0
- package/clis/bloomberg/opinions.js +1 -0
- package/clis/bloomberg/politics.js +1 -0
- package/clis/bloomberg/tech.js +1 -0
- package/clis/bluesky/feeds.js +1 -0
- package/clis/bluesky/followers.js +1 -0
- package/clis/bluesky/following.js +1 -0
- package/clis/bluesky/profile.js +1 -0
- package/clis/bluesky/search.js +1 -0
- package/clis/bluesky/starter-packs.js +1 -0
- package/clis/bluesky/thread.js +1 -0
- package/clis/bluesky/trending.js +1 -0
- package/clis/bluesky/user.js +3 -1
- 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 +1 -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 +1 -0
- package/clis/boss/search.js +1 -0
- package/clis/boss/send.js +1 -0
- package/clis/boss/stats.js +1 -0
- package/clis/chaoxing/assignments.js +1 -0
- package/clis/chaoxing/exams.js +1 -0
- package/clis/chatgpt/image.js +1 -0
- package/clis/chatgpt-app/ask.js +1 -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 +1 -0
- package/clis/chatwise/history.js +1 -0
- package/clis/chatwise/model.js +1 -0
- package/clis/chatwise/read.js +1 -0
- package/clis/chatwise/send.js +1 -0
- package/clis/claude/ask.js +1 -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/cnki/search.js +1 -0
- package/clis/codex/ask.js +1 -0
- package/clis/codex/export.js +1 -0
- package/clis/codex/extract-diff.js +1 -0
- package/clis/codex/history.js +1 -0
- package/clis/codex/model.js +1 -0
- package/clis/codex/read.js +1 -0
- package/clis/codex/send.js +1 -0
- package/clis/coupang/add-to-cart.js +1 -0
- package/clis/coupang/search.js +1 -0
- package/clis/ctrip/search.js +1 -0
- package/clis/cursor/ask.js +1 -0
- package/clis/cursor/composer.js +1 -0
- package/clis/cursor/export.js +1 -0
- package/clis/cursor/extract-code.js +1 -0
- package/clis/cursor/history.js +1 -0
- package/clis/cursor/model.js +1 -0
- package/clis/cursor/read.js +1 -0
- package/clis/cursor/send.js +1 -0
- package/clis/dblp/dblp.test.js +397 -0
- package/clis/dblp/paper.js +40 -0
- package/clis/dblp/search.js +45 -0
- package/clis/dblp/utils.js +290 -0
- package/clis/deepseek/ask.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/status.js +1 -0
- package/clis/devto/devto.test.js +236 -0
- package/clis/devto/read.js +103 -0
- package/clis/devto/tag.js +5 -1
- package/clis/devto/top.js +5 -1
- package/clis/devto/user.js +5 -1
- package/clis/dianping/__fixtures__/search.html +168 -0
- package/clis/dianping/__fixtures__/shop.html +6 -0
- package/clis/dianping/dianping.test.js +424 -0
- package/clis/dianping/search.js +154 -0
- package/clis/dianping/shop.js +173 -0
- package/clis/dianping/utils.js +157 -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 +1 -0
- package/clis/discord-app/members.js +1 -0
- package/clis/discord-app/read.js +1 -0
- package/clis/discord-app/search.js +1 -0
- package/clis/discord-app/send.js +1 -0
- package/clis/discord-app/servers.js +1 -0
- package/clis/discord-app/status.js +1 -0
- package/clis/douban/book-hot.js +1 -0
- package/clis/douban/download.js +1 -0
- package/clis/douban/marks.js +1 -0
- package/clis/douban/movie-hot.js +2 -1
- package/clis/douban/movie-hot.test.js +14 -0
- package/clis/douban/photos.js +2 -1
- package/clis/douban/reviews.js +1 -0
- package/clis/douban/search.js +1 -0
- package/clis/douban/subject.js +1 -0
- package/clis/douban/top250.js +1 -0
- package/clis/douban/utils.js +11 -13
- package/clis/douban/utils.test.js +79 -0
- package/clis/doubao/ask.js +1 -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-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/douyin/activities.js +1 -0
- package/clis/douyin/collections.js +1 -0
- package/clis/douyin/delete.js +1 -0
- package/clis/douyin/draft.js +1 -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.js +1 -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/eastmoney/announcement.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 +1 -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/facebook/add-friend.js +1 -0
- package/clis/facebook/events.js +1 -0
- package/clis/facebook/feed.js +1 -0
- package/clis/facebook/friends.js +1 -0
- package/clis/facebook/groups.js +1 -0
- package/clis/facebook/join-group.js +1 -0
- package/clis/facebook/marketplace-inbox.js +1 -0
- package/clis/facebook/marketplace-listings.js +1 -0
- package/clis/facebook/memories.js +1 -0
- package/clis/facebook/notifications.js +1 -0
- package/clis/facebook/profile.js +1 -0
- package/clis/facebook/search.js +1 -0
- package/clis/gemini/ask.js +1 -0
- package/clis/gemini/deep-research-result.js +1 -0
- package/clis/gemini/deep-research.js +1 -0
- package/clis/gemini/image.js +1 -0
- package/clis/gemini/new.js +1 -0
- package/clis/gitee/search.js +1 -0
- package/clis/gitee/trending.js +1 -0
- package/clis/gitee/user.js +1 -0
- package/clis/google/news.js +1 -0
- package/clis/google/search.js +1 -0
- package/clis/google/suggest.js +1 -0
- package/clis/google/trends.js +1 -0
- package/clis/google-scholar/cite.js +1 -0
- package/clis/google-scholar/profile.js +1 -0
- package/clis/google-scholar/search.js +1 -0
- package/clis/gov-law/recent.js +1 -0
- package/clis/gov-law/search.js +1 -0
- package/clis/gov-policy/recent.js +1 -0
- package/clis/gov-policy/search.js +1 -0
- package/clis/grok/ask.js +1 -0
- package/clis/grok/image.ts +1 -0
- package/clis/hackernews/ask.js +3 -1
- package/clis/hackernews/best.js +3 -1
- package/clis/hackernews/hackernews.test.js +132 -0
- package/clis/hackernews/jobs.js +3 -1
- package/clis/hackernews/new.js +3 -1
- package/clis/hackernews/read.js +188 -0
- package/clis/hackernews/search.js +3 -1
- package/clis/hackernews/show.js +3 -1
- package/clis/hackernews/top.js +3 -1
- package/clis/hackernews/user.js +1 -0
- package/clis/hf/top.js +1 -0
- package/clis/hupu/detail.js +1 -0
- package/clis/hupu/hot.js +3 -1
- package/clis/hupu/like.js +1 -0
- package/clis/hupu/mentions.js +2 -1
- package/clis/hupu/reply.js +1 -0
- package/clis/hupu/search.js +3 -1
- package/clis/hupu/unlike.js +1 -0
- package/clis/imdb/person.js +1 -0
- package/clis/imdb/reviews.js +1 -0
- package/clis/imdb/search.js +1 -0
- package/clis/imdb/title.js +1 -0
- package/clis/imdb/top.js +1 -0
- package/clis/imdb/trending.js +1 -0
- package/clis/indeed/indeed.test.js +375 -0
- package/clis/indeed/job.js +86 -0
- package/clis/indeed/search.js +110 -0
- package/clis/indeed/utils.js +152 -0
- package/clis/instagram/collection-create.js +1 -0
- package/clis/instagram/collection-delete.js +1 -0
- package/clis/instagram/comment.js +1 -0
- package/clis/instagram/download.js +1 -0
- package/clis/instagram/explore.js +1 -0
- package/clis/instagram/follow.js +1 -0
- package/clis/instagram/followers.js +1 -0
- package/clis/instagram/following.js +1 -0
- package/clis/instagram/like.js +1 -0
- package/clis/instagram/note.js +1 -0
- package/clis/instagram/post.js +1 -0
- package/clis/instagram/profile.js +1 -0
- package/clis/instagram/reel.js +1 -0
- package/clis/instagram/save.js +1 -0
- package/clis/instagram/saved.js +1 -0
- package/clis/instagram/search.js +1 -0
- package/clis/instagram/story.js +1 -0
- package/clis/instagram/unfollow.js +1 -0
- package/clis/instagram/unlike.js +1 -0
- package/clis/instagram/unsave.js +1 -0
- package/clis/instagram/user.js +1 -0
- package/clis/jd/add-cart.js +1 -0
- package/clis/jd/cart.js +1 -0
- package/clis/jd/detail.js +1 -0
- package/clis/jd/item.js +1 -0
- package/clis/jd/reviews.js +1 -0
- package/clis/jd/search.js +1 -0
- package/clis/jianyu/detail.js +1 -0
- package/clis/jianyu/search.js +1 -0
- package/clis/jike/comment.js +1 -0
- package/clis/jike/create.js +1 -0
- package/clis/jike/feed.js +3 -1
- package/clis/jike/like.js +1 -0
- package/clis/jike/notifications.js +1 -0
- package/clis/jike/post.js +1 -0
- package/clis/jike/repost.js +1 -0
- package/clis/jike/search.js +3 -1
- package/clis/jike/topic.js +1 -0
- package/clis/jike/user.js +3 -1
- package/clis/jimeng/generate.js +1 -0
- package/clis/jimeng/history.js +1 -0
- package/clis/jimeng/new.js +1 -0
- package/clis/jimeng/workspaces.js +1 -0
- package/clis/ke/chengjiao.js +1 -0
- package/clis/ke/ershoufang.js +1 -0
- package/clis/ke/xiaoqu.js +1 -0
- package/clis/ke/zufang.js +1 -0
- package/clis/lesswrong/comments.js +1 -0
- package/clis/lesswrong/curated.js +1 -0
- package/clis/lesswrong/frontpage.js +1 -0
- package/clis/lesswrong/new.js +1 -0
- package/clis/lesswrong/read.js +1 -0
- package/clis/lesswrong/sequences.js +1 -0
- package/clis/lesswrong/shortform.js +1 -0
- package/clis/lesswrong/tag.js +1 -0
- package/clis/lesswrong/tags.js +1 -0
- package/clis/lesswrong/top-month.js +1 -0
- package/clis/lesswrong/top-week.js +1 -0
- package/clis/lesswrong/top-year.js +1 -0
- package/clis/lesswrong/top.js +1 -0
- package/clis/lesswrong/user-posts.js +1 -0
- package/clis/lesswrong/user.js +1 -0
- package/clis/linkedin/search.js +1 -0
- package/clis/linkedin/timeline.js +1 -0
- package/clis/linux-do/categories.js +1 -0
- package/clis/linux-do/category.js +1 -0
- package/clis/linux-do/feed.js +1 -0
- package/clis/linux-do/hot.js +1 -0
- package/clis/linux-do/latest.js +1 -0
- package/clis/linux-do/search.js +1 -0
- package/clis/linux-do/tags.js +2 -1
- package/clis/linux-do/topic-content.js +1 -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 +4 -1
- package/clis/lobsters/hot.js +4 -1
- package/clis/lobsters/lobsters.test.js +169 -0
- package/clis/lobsters/newest.js +4 -1
- package/clis/lobsters/read.js +196 -0
- package/clis/lobsters/tag.js +4 -1
- package/clis/maimai/search-talents.js +1 -0
- package/clis/medium/feed.js +1 -0
- package/clis/medium/search.js +1 -0
- package/clis/medium/user.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/notebooklm/current.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/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/notion/export.js +1 -0
- package/clis/notion/favorites.js +1 -0
- package/clis/notion/new.js +1 -0
- package/clis/notion/read.js +1 -0
- package/clis/notion/search.js +1 -0
- package/clis/notion/sidebar.js +1 -0
- package/clis/notion/status.js +1 -0
- package/clis/notion/write.js +1 -0
- package/clis/nowcoder/companies.js +1 -0
- package/clis/nowcoder/creators.js +1 -0
- package/clis/nowcoder/detail.js +1 -0
- package/clis/nowcoder/experience.js +1 -0
- package/clis/nowcoder/hot.js +1 -0
- package/clis/nowcoder/jobs.js +1 -0
- package/clis/nowcoder/notifications.js +1 -0
- package/clis/nowcoder/papers.js +1 -0
- package/clis/nowcoder/practice.js +1 -0
- package/clis/nowcoder/recommend.js +1 -0
- package/clis/nowcoder/referral.js +1 -0
- package/clis/nowcoder/salary.js +1 -0
- package/clis/nowcoder/search.js +1 -0
- package/clis/nowcoder/suggest.js +1 -0
- package/clis/nowcoder/topics.js +1 -0
- package/clis/nowcoder/trending.js +1 -0
- package/clis/ones/login.js +1 -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/task.js +1 -0
- package/clis/ones/tasks.js +1 -0
- package/clis/ones/token-info.js +1 -0
- package/clis/ones/worklog.js +1 -0
- package/clis/openreview/openreview.test.js +345 -0
- package/clis/openreview/paper.js +43 -0
- package/clis/openreview/reviews.js +131 -0
- package/clis/openreview/search.js +46 -0
- package/clis/openreview/utils.js +158 -0
- package/clis/openreview/venue.js +63 -0
- package/clis/paperreview/feedback.js +1 -0
- package/clis/paperreview/review.js +1 -0
- package/clis/paperreview/submit.js +1 -0
- package/clis/pixiv/detail.js +1 -0
- package/clis/pixiv/download.js +1 -0
- package/clis/pixiv/illusts.js +2 -1
- package/clis/pixiv/ranking.js +2 -1
- package/clis/pixiv/search.js +2 -1
- package/clis/pixiv/user.js +2 -0
- package/clis/powerchina/search.js +1 -0
- package/clis/producthunt/browse.js +1 -0
- package/clis/producthunt/hot.js +1 -0
- package/clis/producthunt/posts.js +1 -0
- package/clis/producthunt/today.js +1 -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/reddit/comment.js +1 -0
- package/clis/reddit/frontpage.js +1 -0
- package/clis/reddit/hot.js +6 -1
- package/clis/reddit/hot.test.js +18 -0
- package/clis/reddit/popular.js +1 -0
- package/clis/reddit/read.js +1 -0
- package/clis/reddit/save.js +1 -0
- package/clis/reddit/saved.js +1 -0
- package/clis/reddit/search.js +1 -0
- package/clis/reddit/subreddit.js +1 -0
- package/clis/reddit/subscribe.js +1 -0
- package/clis/reddit/upvote.js +1 -0
- package/clis/reddit/upvoted.js +1 -0
- package/clis/reddit/user-comments.js +1 -0
- package/clis/reddit/user-posts.js +1 -0
- package/clis/reddit/user.js +1 -0
- package/clis/reuters/search.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/sinafinance/news.js +1 -0
- package/clis/sinafinance/rolling-news.js +1 -0
- package/clis/sinafinance/stock-rank.js +1 -0
- package/clis/sinafinance/stock.js +1 -0
- package/clis/smzdm/search.js +1 -0
- package/clis/spotify/spotify.js +11 -0
- package/clis/stackoverflow/bounties.js +11 -3
- package/clis/stackoverflow/hot.js +10 -2
- package/clis/stackoverflow/read.js +314 -0
- package/clis/stackoverflow/search.js +10 -2
- package/clis/stackoverflow/stackoverflow.test.js +346 -0
- package/clis/stackoverflow/unanswered.js +9 -2
- package/clis/steam/top-sellers.js +1 -0
- package/clis/substack/feed.js +1 -0
- package/clis/substack/publication.js +1 -0
- package/clis/substack/search.js +1 -0
- package/clis/taobao/add-cart.js +1 -0
- package/clis/taobao/cart.js +1 -0
- package/clis/taobao/detail.js +1 -0
- package/clis/taobao/reviews.js +1 -0
- package/clis/taobao/search.js +1 -0
- package/clis/tdx/hot-rank.js +1 -0
- package/clis/ths/hot-rank.js +1 -0
- package/clis/tieba/hot.js +2 -1
- package/clis/tieba/posts.js +1 -0
- package/clis/tieba/read.js +1 -0
- package/clis/tieba/search.js +2 -1
- package/clis/tiktok/comment.js +1 -0
- package/clis/tiktok/explore.js +1 -0
- package/clis/tiktok/follow.js +1 -0
- package/clis/tiktok/following.js +1 -0
- package/clis/tiktok/friends.js +1 -0
- package/clis/tiktok/like.js +1 -0
- package/clis/tiktok/live.js +1 -0
- package/clis/tiktok/notifications.js +1 -0
- package/clis/tiktok/profile.js +1 -0
- package/clis/tiktok/save.js +1 -0
- package/clis/tiktok/search.js +1 -0
- package/clis/tiktok/unfollow.js +1 -0
- package/clis/tiktok/unlike.js +1 -0
- package/clis/tiktok/unsave.js +1 -0
- package/clis/tiktok/user.js +1 -0
- package/clis/toutiao/articles.js +1 -0
- package/clis/twitter/accept.js +1 -0
- package/clis/twitter/article.js +1 -0
- package/clis/twitter/block.js +1 -0
- package/clis/twitter/bookmark.js +1 -0
- package/clis/twitter/bookmarks.js +2 -1
- package/clis/twitter/delete.js +1 -0
- package/clis/twitter/download.js +1 -0
- package/clis/twitter/follow.js +1 -0
- package/clis/twitter/followers.js +1 -0
- package/clis/twitter/following.js +1 -0
- package/clis/twitter/hide-reply.js +1 -0
- package/clis/twitter/like.js +1 -0
- package/clis/twitter/likes.js +2 -1
- package/clis/twitter/list-add.js +1 -0
- package/clis/twitter/list-remove.js +1 -0
- package/clis/twitter/list-tweets.js +1 -0
- package/clis/twitter/lists.js +1 -0
- package/clis/twitter/notifications.js +1 -0
- package/clis/twitter/post.js +1 -0
- package/clis/twitter/profile.js +1 -0
- package/clis/twitter/reply-dm.js +1 -0
- package/clis/twitter/reply.js +1 -0
- package/clis/twitter/search.js +1 -0
- package/clis/twitter/thread.js +1 -0
- package/clis/twitter/timeline.js +1 -0
- package/clis/twitter/trending.js +11 -12
- package/clis/twitter/trending.test.js +15 -0
- package/clis/twitter/tweets.js +2 -1
- package/clis/twitter/tweets.test.js +2 -2
- package/clis/twitter/unblock.js +1 -0
- package/clis/twitter/unbookmark.js +1 -0
- package/clis/twitter/unfollow.js +1 -0
- package/clis/uiverse/code.js +1 -0
- package/clis/uiverse/preview.js +1 -0
- package/clis/v2ex/daily.js +1 -0
- package/clis/v2ex/hot.js +1 -0
- package/clis/v2ex/latest.js +1 -0
- package/clis/v2ex/me.js +1 -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 +1 -0
- package/clis/v2ex/replies.js +1 -0
- package/clis/v2ex/topic.js +1 -0
- package/clis/v2ex/user.js +1 -0
- package/clis/wanfang/search.js +1 -0
- package/clis/web/read.js +1 -0
- package/clis/weibo/comments.js +1 -0
- package/clis/weibo/favorites.js +1 -0
- package/clis/weibo/feed.js +3 -1
- package/clis/weibo/hot.js +1 -0
- package/clis/weibo/me.js +1 -0
- package/clis/weibo/post.js +1 -0
- package/clis/weibo/publish.js +1 -0
- package/clis/weibo/search.js +8 -2
- package/clis/weibo/user.js +1 -0
- package/clis/weixin/create-draft.js +1 -0
- package/clis/weixin/download.js +1 -0
- package/clis/weixin/drafts.js +1 -0
- package/clis/weread/ai-outline.js +1 -0
- package/clis/weread/book.js +1 -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/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/xianyu/chat.js +1 -0
- package/clis/xianyu/item.js +1 -0
- package/clis/xianyu/search.js +1 -0
- package/clis/xiaoe/catalog.js +2 -1
- package/clis/xiaoe/content.js +1 -0
- package/clis/xiaoe/courses.js +1 -0
- package/clis/xiaoe/detail.js +1 -0
- package/clis/xiaoe/play-url.js +1 -0
- package/clis/xiaohongshu/comments.js +1 -0
- package/clis/xiaohongshu/creator-note-detail.js +1 -0
- package/clis/xiaohongshu/creator-notes-summary.js +1 -0
- package/clis/xiaohongshu/creator-notes.js +1 -0
- package/clis/xiaohongshu/creator-profile.js +1 -0
- package/clis/xiaohongshu/creator-stats.js +1 -0
- package/clis/xiaohongshu/download.js +1 -0
- package/clis/xiaohongshu/feed.js +2 -1
- package/clis/xiaohongshu/note.js +1 -0
- package/clis/xiaohongshu/notifications.js +1 -0
- package/clis/xiaohongshu/publish.js +1 -0
- package/clis/xiaohongshu/search.js +1 -0
- package/clis/xiaohongshu/user.js +1 -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/xueqiu/comments.js +1 -0
- package/clis/xueqiu/earnings-date.js +1 -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/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/watchlist.js +1 -0
- package/clis/yahoo-finance/quote.js +1 -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 +1 -0
- package/clis/yollomi/upscale.js +1 -0
- package/clis/yollomi/video.js +1 -0
- package/clis/youtube/channel.js +1 -0
- package/clis/youtube/comments.js +1 -0
- package/clis/youtube/feed.js +8 -7
- package/clis/youtube/feed.test.js +131 -0
- package/clis/youtube/history.js +1 -0
- package/clis/youtube/like.js +1 -0
- package/clis/youtube/playlist.js +1 -0
- package/clis/youtube/search.js +1 -0
- package/clis/youtube/subscribe.js +1 -0
- package/clis/youtube/subscriptions.js +1 -0
- package/clis/youtube/transcript.js +1 -0
- package/clis/youtube/unlike.js +1 -0
- package/clis/youtube/unsubscribe.js +1 -0
- package/clis/youtube/video.js +1 -0
- package/clis/youtube/watch-later.js +1 -0
- package/clis/yuanbao/ask.js +1 -0
- package/clis/yuanbao/new.js +1 -0
- package/clis/zhihu/answer.js +1 -0
- package/clis/zhihu/collection.js +1 -0
- package/clis/zhihu/collections.js +1 -0
- package/clis/zhihu/comment.js +1 -0
- package/clis/zhihu/download.js +1 -0
- package/clis/zhihu/favorite.js +1 -0
- package/clis/zhihu/follow.js +1 -0
- package/clis/zhihu/hot.js +1 -0
- package/clis/zhihu/like.js +1 -0
- package/clis/zhihu/question.js +1 -0
- package/clis/zhihu/search.js +1 -0
- package/clis/zlibrary/info.js +1 -0
- package/clis/zlibrary/search.js +1 -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/dist/src/adapter-source.test.js +1 -1
- package/dist/src/browser/analyze.test.js +2 -0
- package/dist/src/browser/base-page.d.ts +9 -0
- package/dist/src/browser/base-page.js +72 -3
- package/dist/src/browser/base-page.test.js +42 -0
- package/dist/src/browser/cdp.js +6 -0
- package/dist/src/browser/cdp.test.js +3 -0
- package/dist/src/browser/page.d.ts +1 -0
- package/dist/src/browser/page.js +6 -0
- package/dist/src/browser/page.test.js +17 -0
- package/dist/src/browser/target-resolver.d.ts +10 -3
- package/dist/src/browser/target-resolver.js +16 -10
- package/dist/src/browser/verify-fixture.d.ts +6 -1
- package/dist/src/browser/verify-fixture.js +87 -0
- package/dist/src/browser/verify-fixture.test.js +44 -1
- package/dist/src/build-manifest.js +3 -0
- package/dist/src/build-manifest.test.js +18 -12
- package/dist/src/capabilityRouting.test.js +1 -1
- package/dist/src/cli.js +141 -5
- package/dist/src/cli.test.js +179 -0
- package/dist/src/commanderAdapter.d.ts +1 -1
- package/dist/src/commanderAdapter.js +17 -7
- package/dist/src/commanderAdapter.test.js +7 -6
- package/dist/src/convention-audit.d.ts +50 -0
- package/dist/src/convention-audit.js +546 -0
- package/dist/src/convention-audit.test.d.ts +1 -0
- package/dist/src/convention-audit.test.js +226 -0
- package/dist/src/discovery.js +2 -0
- package/dist/src/doctor.js +0 -1
- package/dist/src/doctor.test.js +1 -1
- package/dist/src/engine.test.js +10 -10
- package/dist/src/execution.js +1 -1
- package/dist/src/execution.test.js +9 -9
- package/dist/src/help.d.ts +15 -0
- package/dist/src/help.js +149 -0
- package/dist/src/main.js +13 -7
- package/dist/src/manifest-types.d.ts +2 -0
- package/dist/src/plugin.test.js +26 -26
- package/dist/src/registry.d.ts +5 -0
- package/dist/src/registry.js +8 -0
- package/dist/src/registry.test.js +27 -20
- package/dist/src/serialization.d.ts +4 -0
- package/dist/src/serialization.js +27 -1
- package/dist/src/serialization.test.js +24 -2
- package/dist/src/types.d.ts +2 -0
- package/package.json +4 -1
- 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/silent-column-drop-baseline.json +962 -0
- package/scripts/typed-error-lint-baseline.json +1586 -0
package/dist/src/plugin.test.js
CHANGED
|
@@ -361,7 +361,7 @@ describe('listPlugins', () => {
|
|
|
361
361
|
});
|
|
362
362
|
it('lists installed plugins', () => {
|
|
363
363
|
fs.mkdirSync(testDir, { recursive: true });
|
|
364
|
-
fs.writeFileSync(path.join(testDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
364
|
+
fs.writeFileSync(path.join(testDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
365
365
|
const plugins = listPlugins();
|
|
366
366
|
const found = plugins.find(p => p.name === '__test-list-plugin__');
|
|
367
367
|
expect(found).toBeDefined();
|
|
@@ -369,7 +369,7 @@ describe('listPlugins', () => {
|
|
|
369
369
|
});
|
|
370
370
|
it('includes version metadata from the lock file', () => {
|
|
371
371
|
fs.mkdirSync(testDir, { recursive: true });
|
|
372
|
-
fs.writeFileSync(path.join(testDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
372
|
+
fs.writeFileSync(path.join(testDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
373
373
|
const lock = _readLockFile();
|
|
374
374
|
lock['__test-list-plugin__'] = {
|
|
375
375
|
source: { kind: 'git', url: 'https://github.com/user/repo.git' },
|
|
@@ -393,7 +393,7 @@ describe('listPlugins', () => {
|
|
|
393
393
|
const localTarget = fs.mkdtempSync(path.join(os.tmpdir(), 'opencli-local-list-'));
|
|
394
394
|
const linkPath = path.join(PLUGINS_DIR, '__test-list-plugin__');
|
|
395
395
|
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
396
|
-
fs.writeFileSync(path.join(localTarget, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
396
|
+
fs.writeFileSync(path.join(localTarget, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
397
397
|
try {
|
|
398
398
|
fs.unlinkSync(linkPath);
|
|
399
399
|
}
|
|
@@ -435,13 +435,13 @@ describe('uninstallPlugin', () => {
|
|
|
435
435
|
});
|
|
436
436
|
it('removes plugin directory', () => {
|
|
437
437
|
fs.mkdirSync(testDir, { recursive: true });
|
|
438
|
-
fs.writeFileSync(path.join(testDir, 'test.js'), 'cli({ site: "test", name: "test" })');
|
|
438
|
+
fs.writeFileSync(path.join(testDir, 'test.js'), 'cli({ site: "test", name: "test", access: "read" })');
|
|
439
439
|
uninstallPlugin('__test-uninstall__');
|
|
440
440
|
expect(fs.existsSync(testDir)).toBe(false);
|
|
441
441
|
});
|
|
442
442
|
it('removes lock entry on uninstall', () => {
|
|
443
443
|
fs.mkdirSync(testDir, { recursive: true });
|
|
444
|
-
fs.writeFileSync(path.join(testDir, 'test.js'), 'cli({ site: "test", name: "test" })');
|
|
444
|
+
fs.writeFileSync(path.join(testDir, 'test.js'), 'cli({ site: "test", name: "test", access: "read" })');
|
|
445
445
|
const lock = _readLockFile();
|
|
446
446
|
lock['__test-uninstall__'] = {
|
|
447
447
|
source: { kind: 'git', url: 'https://github.com/user/repo.git' },
|
|
@@ -464,7 +464,7 @@ describe('updatePlugin', () => {
|
|
|
464
464
|
const localTarget = fs.mkdtempSync(path.join(os.tmpdir(), 'opencli-local-update-'));
|
|
465
465
|
const linkPath = path.join(PLUGINS_DIR, '__test-local-update__');
|
|
466
466
|
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
467
|
-
fs.writeFileSync(path.join(localTarget, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
467
|
+
fs.writeFileSync(path.join(localTarget, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
468
468
|
fs.symlinkSync(localTarget, linkPath, 'dir');
|
|
469
469
|
const lock = _readLockFile();
|
|
470
470
|
lock['__test-local-update__'] = {
|
|
@@ -540,7 +540,7 @@ describe('postInstallMonorepoLifecycle', () => {
|
|
|
540
540
|
private: true,
|
|
541
541
|
workspaces: ['packages/*'],
|
|
542
542
|
}));
|
|
543
|
-
fs.writeFileSync(path.join(subDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
543
|
+
fs.writeFileSync(path.join(subDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
544
544
|
});
|
|
545
545
|
afterEach(() => {
|
|
546
546
|
fs.rmSync(repoDir, { recursive: true, force: true });
|
|
@@ -575,9 +575,9 @@ describe('updateAllPlugins', () => {
|
|
|
575
575
|
fs.mkdirSync(testDirA, { recursive: true });
|
|
576
576
|
fs.mkdirSync(testDirB, { recursive: true });
|
|
577
577
|
fs.mkdirSync(testDirC, { recursive: true });
|
|
578
|
-
fs.writeFileSync(path.join(testDirA, 'cmd.js'), 'cli({ site: "a", name: "cmd" })');
|
|
579
|
-
fs.writeFileSync(path.join(testDirB, 'cmd.js'), 'cli({ site: "b", name: "cmd" })');
|
|
580
|
-
fs.writeFileSync(path.join(testDirC, 'cmd.js'), 'cli({ site: "c", name: "cmd" })');
|
|
578
|
+
fs.writeFileSync(path.join(testDirA, 'cmd.js'), 'cli({ site: "a", name: "cmd", access: "read" })');
|
|
579
|
+
fs.writeFileSync(path.join(testDirB, 'cmd.js'), 'cli({ site: "b", name: "cmd", access: "read" })');
|
|
580
|
+
fs.writeFileSync(path.join(testDirC, 'cmd.js'), 'cli({ site: "c", name: "cmd", access: "read" })');
|
|
581
581
|
const lock = _readLockFile();
|
|
582
582
|
lock['plugin-a'] = {
|
|
583
583
|
source: { kind: 'git', url: 'https://github.com/user/plugin-a.git' },
|
|
@@ -622,7 +622,7 @@ describe('updateAllPlugins', () => {
|
|
|
622
622
|
const cloneUrl = String(args[3]);
|
|
623
623
|
const cloneDir = String(args[4]);
|
|
624
624
|
fs.mkdirSync(cloneDir, { recursive: true });
|
|
625
|
-
fs.writeFileSync(path.join(cloneDir, 'cmd.js'), 'cli({ site: "test", name: "hello" })');
|
|
625
|
+
fs.writeFileSync(path.join(cloneDir, 'cmd.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
626
626
|
if (cloneUrl.includes('plugin-b')) {
|
|
627
627
|
fs.writeFileSync(path.join(cloneDir, 'package.json'), JSON.stringify({ name: 'plugin-b' }));
|
|
628
628
|
}
|
|
@@ -709,7 +709,7 @@ describe('monorepo uninstall with symlink', () => {
|
|
|
709
709
|
monoDir = path.join(_getMonoreposDir(), '__test-mono__');
|
|
710
710
|
const subDir = path.join(monoDir, 'packages', 'sub');
|
|
711
711
|
fs.mkdirSync(subDir, { recursive: true });
|
|
712
|
-
fs.writeFileSync(path.join(subDir, 'cmd.js'), 'cli({ site: "test", name: "cmd" })');
|
|
712
|
+
fs.writeFileSync(path.join(subDir, 'cmd.js'), 'cli({ site: "test", name: "cmd", access: "read" })');
|
|
713
713
|
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
714
714
|
fs.symlinkSync(subDir, pluginDir, 'dir');
|
|
715
715
|
const lock = _readLockFile();
|
|
@@ -776,7 +776,7 @@ describe('listPlugins with monorepo metadata', () => {
|
|
|
776
776
|
const testLink = path.join(PLUGINS_DIR, '__test-mono-list__');
|
|
777
777
|
beforeEach(() => {
|
|
778
778
|
fs.mkdirSync(testSymlinkTarget, { recursive: true });
|
|
779
|
-
fs.writeFileSync(path.join(testSymlinkTarget, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
779
|
+
fs.writeFileSync(path.join(testSymlinkTarget, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
780
780
|
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
781
781
|
try {
|
|
782
782
|
fs.unlinkSync(testLink);
|
|
@@ -823,7 +823,7 @@ describe('installLocalPlugin', () => {
|
|
|
823
823
|
const pluginName = '__test-local-plugin__';
|
|
824
824
|
beforeEach(() => {
|
|
825
825
|
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'opencli-local-install-'));
|
|
826
|
-
fs.writeFileSync(path.join(tmpDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
826
|
+
fs.writeFileSync(path.join(tmpDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
827
827
|
});
|
|
828
828
|
afterEach(() => {
|
|
829
829
|
const linkPath = path.join(PLUGINS_DIR, pluginName);
|
|
@@ -963,7 +963,7 @@ describe('installPlugin transactional staging', () => {
|
|
|
963
963
|
if (cmd === 'git' && Array.isArray(args) && args[0] === 'clone') {
|
|
964
964
|
const cloneDir = String(args[args.length - 1]);
|
|
965
965
|
fs.mkdirSync(cloneDir, { recursive: true });
|
|
966
|
-
fs.writeFileSync(path.join(cloneDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
966
|
+
fs.writeFileSync(path.join(cloneDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
967
967
|
fs.writeFileSync(path.join(cloneDir, 'package.json'), JSON.stringify({ name: standaloneName }));
|
|
968
968
|
return '';
|
|
969
969
|
}
|
|
@@ -994,7 +994,7 @@ describe('installPlugin transactional staging', () => {
|
|
|
994
994
|
alpha: { path: 'packages/alpha' },
|
|
995
995
|
},
|
|
996
996
|
}));
|
|
997
|
-
fs.writeFileSync(path.join(alphaDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
997
|
+
fs.writeFileSync(path.join(alphaDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
998
998
|
return '';
|
|
999
999
|
}
|
|
1000
1000
|
if (cmd === 'npm' && Array.isArray(args) && args[0] === 'install') {
|
|
@@ -1051,7 +1051,7 @@ describe('installPlugin with existing monorepo', () => {
|
|
|
1051
1051
|
[pluginName]: { path: `packages/${pluginName}` },
|
|
1052
1052
|
},
|
|
1053
1053
|
}));
|
|
1054
|
-
fs.writeFileSync(path.join(subDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
1054
|
+
fs.writeFileSync(path.join(subDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
1055
1055
|
mockExecFileSync.mockImplementation((cmd, args) => {
|
|
1056
1056
|
if (cmd === 'git' && Array.isArray(args) && args[0] === 'clone') {
|
|
1057
1057
|
const cloneDir = String(args[4]);
|
|
@@ -1110,7 +1110,7 @@ describe('updatePlugin transactional staging', () => {
|
|
|
1110
1110
|
});
|
|
1111
1111
|
it('keeps the existing standalone plugin when staged update preparation fails', () => {
|
|
1112
1112
|
fs.mkdirSync(standaloneDir, { recursive: true });
|
|
1113
|
-
fs.writeFileSync(path.join(standaloneDir, 'old.js'), 'cli({ site: "old", name: "old" })');
|
|
1113
|
+
fs.writeFileSync(path.join(standaloneDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
|
|
1114
1114
|
const lock = _readLockFile();
|
|
1115
1115
|
lock[standaloneName] = {
|
|
1116
1116
|
source: {
|
|
@@ -1125,7 +1125,7 @@ describe('updatePlugin transactional staging', () => {
|
|
|
1125
1125
|
if (cmd === 'git' && Array.isArray(args) && args[0] === 'clone') {
|
|
1126
1126
|
const cloneDir = String(args[4]);
|
|
1127
1127
|
fs.mkdirSync(cloneDir, { recursive: true });
|
|
1128
|
-
fs.writeFileSync(path.join(cloneDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
1128
|
+
fs.writeFileSync(path.join(cloneDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
1129
1129
|
fs.writeFileSync(path.join(cloneDir, 'package.json'), JSON.stringify({ name: standaloneName }));
|
|
1130
1130
|
return '';
|
|
1131
1131
|
}
|
|
@@ -1145,7 +1145,7 @@ describe('updatePlugin transactional staging', () => {
|
|
|
1145
1145
|
it('keeps the existing monorepo repo and link when staged update preparation fails', () => {
|
|
1146
1146
|
const subDir = path.join(monorepoRepoDir, 'packages', monorepoPluginName);
|
|
1147
1147
|
fs.mkdirSync(subDir, { recursive: true });
|
|
1148
|
-
fs.writeFileSync(path.join(subDir, 'old.js'), 'cli({ site: "old", name: "old" })');
|
|
1148
|
+
fs.writeFileSync(path.join(subDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
|
|
1149
1149
|
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
1150
1150
|
fs.symlinkSync(subDir, monorepoLink, 'dir');
|
|
1151
1151
|
const lock = _readLockFile();
|
|
@@ -1174,7 +1174,7 @@ describe('updatePlugin transactional staging', () => {
|
|
|
1174
1174
|
[monorepoPluginName]: { path: `packages/${monorepoPluginName}` },
|
|
1175
1175
|
},
|
|
1176
1176
|
}));
|
|
1177
|
-
fs.writeFileSync(path.join(alphaDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
1177
|
+
fs.writeFileSync(path.join(alphaDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
1178
1178
|
return '';
|
|
1179
1179
|
}
|
|
1180
1180
|
if (cmd === 'npm' && Array.isArray(args) && args[0] === 'install') {
|
|
@@ -1194,7 +1194,7 @@ describe('updatePlugin transactional staging', () => {
|
|
|
1194
1194
|
it('relinks monorepo plugins when the updated manifest moves their subPath', () => {
|
|
1195
1195
|
const oldSubDir = path.join(monorepoRepoDir, 'packages', 'old-alpha');
|
|
1196
1196
|
fs.mkdirSync(oldSubDir, { recursive: true });
|
|
1197
|
-
fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old" })');
|
|
1197
|
+
fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
|
|
1198
1198
|
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
1199
1199
|
fs.symlinkSync(oldSubDir, monorepoLink, 'dir');
|
|
1200
1200
|
const lock = _readLockFile();
|
|
@@ -1219,7 +1219,7 @@ describe('updatePlugin transactional staging', () => {
|
|
|
1219
1219
|
[monorepoPluginName]: { path: 'packages/moved-alpha' },
|
|
1220
1220
|
},
|
|
1221
1221
|
}));
|
|
1222
|
-
fs.writeFileSync(path.join(movedDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
1222
|
+
fs.writeFileSync(path.join(movedDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
1223
1223
|
return '';
|
|
1224
1224
|
}
|
|
1225
1225
|
if (cmd === 'git' && Array.isArray(args) && args[0] === 'rev-parse' && args[1] === 'HEAD') {
|
|
@@ -1238,7 +1238,7 @@ describe('updatePlugin transactional staging', () => {
|
|
|
1238
1238
|
it('rejects monorepo updates whose manifest path escapes the repo root', () => {
|
|
1239
1239
|
const oldSubDir = path.join(monorepoRepoDir, 'packages', 'old-alpha');
|
|
1240
1240
|
fs.mkdirSync(oldSubDir, { recursive: true });
|
|
1241
|
-
fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old" })');
|
|
1241
|
+
fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
|
|
1242
1242
|
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
1243
1243
|
fs.symlinkSync(oldSubDir, monorepoLink, 'dir');
|
|
1244
1244
|
const lock = _readLockFile();
|
|
@@ -1279,7 +1279,7 @@ describe('updatePlugin transactional staging', () => {
|
|
|
1279
1279
|
it('rolls back the monorepo repo swap when relinking fails', () => {
|
|
1280
1280
|
const oldSubDir = path.join(monorepoRepoDir, 'packages', 'old-alpha');
|
|
1281
1281
|
fs.mkdirSync(oldSubDir, { recursive: true });
|
|
1282
|
-
fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old" })');
|
|
1282
|
+
fs.writeFileSync(path.join(oldSubDir, 'old.js'), 'cli({ site: "old", name: "old", access: "read" })');
|
|
1283
1283
|
fs.mkdirSync(monorepoLink, { recursive: true });
|
|
1284
1284
|
fs.writeFileSync(path.join(monorepoLink, 'blocker.txt'), 'not a symlink');
|
|
1285
1285
|
const lock = _readLockFile();
|
|
@@ -1304,7 +1304,7 @@ describe('updatePlugin transactional staging', () => {
|
|
|
1304
1304
|
[monorepoPluginName]: { path: 'packages/moved-alpha' },
|
|
1305
1305
|
},
|
|
1306
1306
|
}));
|
|
1307
|
-
fs.writeFileSync(path.join(movedDir, 'hello.js'), 'cli({ site: "test", name: "hello" })');
|
|
1307
|
+
fs.writeFileSync(path.join(movedDir, 'hello.js'), 'cli({ site: "test", name: "hello", access: "read" })');
|
|
1308
1308
|
return '';
|
|
1309
1309
|
}
|
|
1310
1310
|
if (cmd === 'git' && Array.isArray(args) && args[0] === 'rev-parse' && args[1] === 'HEAD') {
|
package/dist/src/registry.d.ts
CHANGED
|
@@ -27,11 +27,15 @@ export interface RequiredEnv {
|
|
|
27
27
|
export type CommandArgs = Record<string, any>;
|
|
28
28
|
export type BrowserCommandFunc = (page: IPage, kwargs: CommandArgs, debug?: boolean) => Promise<unknown>;
|
|
29
29
|
export type NonBrowserCommandFunc = (kwargs: CommandArgs, debug?: boolean) => Promise<unknown>;
|
|
30
|
+
export type CommandAccess = 'read' | 'write';
|
|
30
31
|
interface BaseCliCommand {
|
|
31
32
|
site: string;
|
|
32
33
|
name: string;
|
|
33
34
|
aliases?: string[];
|
|
34
35
|
description: string;
|
|
36
|
+
access: CommandAccess;
|
|
37
|
+
/** Canonical invocation shown in agent-facing help. Generated when omitted. */
|
|
38
|
+
example?: string;
|
|
35
39
|
domain?: string;
|
|
36
40
|
strategy?: Strategy;
|
|
37
41
|
args: Arg[];
|
|
@@ -89,6 +93,7 @@ export type InternalCliCommand = CliCommand & {
|
|
|
89
93
|
type RequiredCliOptions = {
|
|
90
94
|
site: string;
|
|
91
95
|
name: string;
|
|
96
|
+
access: CommandAccess;
|
|
92
97
|
description?: string;
|
|
93
98
|
args?: Arg[];
|
|
94
99
|
};
|
package/dist/src/registry.js
CHANGED
|
@@ -17,6 +17,7 @@ export function cli(opts) {
|
|
|
17
17
|
name: opts.name,
|
|
18
18
|
aliases: opts.aliases,
|
|
19
19
|
description: opts.description ?? '',
|
|
20
|
+
access: opts.access,
|
|
20
21
|
domain: opts.domain,
|
|
21
22
|
strategy: opts.strategy,
|
|
22
23
|
browser: opts.browser,
|
|
@@ -58,6 +59,7 @@ export function strategyLabel(cmd) {
|
|
|
58
59
|
* 2. Derived from strategy + domain (the defaults below)
|
|
59
60
|
*/
|
|
60
61
|
function normalizeCommand(cmd) {
|
|
62
|
+
assertCommandAccess(cmd);
|
|
61
63
|
const strategy = cmd.strategy ?? (cmd.browser === false ? Strategy.PUBLIC : Strategy.COOKIE);
|
|
62
64
|
const browser = cmd.browser ?? (strategy !== Strategy.PUBLIC && strategy !== Strategy.LOCAL);
|
|
63
65
|
let navigateBefore = cmd.navigateBefore;
|
|
@@ -76,6 +78,12 @@ function normalizeCommand(cmd) {
|
|
|
76
78
|
? { ...cmd, strategy, browser: true, navigateBefore }
|
|
77
79
|
: { ...cmd, strategy, browser: false, navigateBefore };
|
|
78
80
|
}
|
|
81
|
+
function assertCommandAccess(cmd) {
|
|
82
|
+
if (cmd.access === 'read' || cmd.access === 'write')
|
|
83
|
+
return;
|
|
84
|
+
const key = `${cmd.site}/${cmd.name}`;
|
|
85
|
+
throw new Error(`Command ${key} must declare access: 'read' | 'write'`);
|
|
86
|
+
}
|
|
79
87
|
export function registerCommand(cmd) {
|
|
80
88
|
const normalized = normalizeCommand(cmd);
|
|
81
89
|
const canonicalKey = fullName(normalized);
|
|
@@ -7,13 +7,14 @@ describe('cli() registration', () => {
|
|
|
7
7
|
it('registers a command and returns it', () => {
|
|
8
8
|
const cmd = cli({
|
|
9
9
|
site: 'test-registry',
|
|
10
|
-
name: 'hello',
|
|
10
|
+
name: 'hello', access: 'read',
|
|
11
11
|
description: 'A test command',
|
|
12
12
|
strategy: Strategy.PUBLIC,
|
|
13
13
|
browser: false,
|
|
14
14
|
});
|
|
15
15
|
expect(cmd.site).toBe('test-registry');
|
|
16
16
|
expect(cmd.name).toBe('hello');
|
|
17
|
+
expect(cmd.access).toBe('read');
|
|
17
18
|
expect(cmd.strategy).toBe(Strategy.PUBLIC);
|
|
18
19
|
expect(cmd.browser).toBe(false);
|
|
19
20
|
expect(cmd.args).toEqual([]);
|
|
@@ -21,7 +22,7 @@ describe('cli() registration', () => {
|
|
|
21
22
|
it('puts registered command in the registry', () => {
|
|
22
23
|
cli({
|
|
23
24
|
site: 'test-registry',
|
|
24
|
-
name: 'registered',
|
|
25
|
+
name: 'registered', access: 'read',
|
|
25
26
|
description: 'test',
|
|
26
27
|
});
|
|
27
28
|
const registry = getRegistry();
|
|
@@ -30,7 +31,7 @@ describe('cli() registration', () => {
|
|
|
30
31
|
it('defaults strategy to COOKIE when browser is true', () => {
|
|
31
32
|
const cmd = cli({
|
|
32
33
|
site: 'test-registry',
|
|
33
|
-
name: 'default-strategy',
|
|
34
|
+
name: 'default-strategy', access: 'read',
|
|
34
35
|
});
|
|
35
36
|
expect(cmd.strategy).toBe(Strategy.COOKIE);
|
|
36
37
|
expect(cmd.browser).toBe(true);
|
|
@@ -38,7 +39,7 @@ describe('cli() registration', () => {
|
|
|
38
39
|
it('defaults strategy to PUBLIC when browser is false', () => {
|
|
39
40
|
const cmd = cli({
|
|
40
41
|
site: 'test-registry',
|
|
41
|
-
name: 'no-browser',
|
|
42
|
+
name: 'no-browser', access: 'read',
|
|
42
43
|
browser: false,
|
|
43
44
|
});
|
|
44
45
|
expect(cmd.strategy).toBe(Strategy.PUBLIC);
|
|
@@ -46,7 +47,7 @@ describe('cli() registration', () => {
|
|
|
46
47
|
it('preserves LOCAL strategy on registration', () => {
|
|
47
48
|
const cmd = cli({
|
|
48
49
|
site: 'test-registry',
|
|
49
|
-
name: 'local-strategy',
|
|
50
|
+
name: 'local-strategy', access: 'read',
|
|
50
51
|
description: 'reads local credentials',
|
|
51
52
|
strategy: Strategy.LOCAL,
|
|
52
53
|
browser: false,
|
|
@@ -55,15 +56,15 @@ describe('cli() registration', () => {
|
|
|
55
56
|
expect(cmd.browser).toBe(false);
|
|
56
57
|
});
|
|
57
58
|
it('overwrites existing command on re-registration', () => {
|
|
58
|
-
cli({ site: 'test-registry', name: 'overwrite', description: 'v1' });
|
|
59
|
-
cli({ site: 'test-registry', name: 'overwrite', description: 'v2' });
|
|
59
|
+
cli({ site: 'test-registry', name: 'overwrite', access: 'read', description: 'v1' });
|
|
60
|
+
cli({ site: 'test-registry', name: 'overwrite', access: 'read', description: 'v2' });
|
|
60
61
|
const reg = getRegistry();
|
|
61
62
|
expect(reg.get('test-registry/overwrite')?.description).toBe('v2');
|
|
62
63
|
});
|
|
63
64
|
it('registers aliases as alternate registry keys for the same command', () => {
|
|
64
65
|
const cmd = cli({
|
|
65
66
|
site: 'test-registry',
|
|
66
|
-
name: 'canonical',
|
|
67
|
+
name: 'canonical', access: 'read',
|
|
67
68
|
description: 'test aliases',
|
|
68
69
|
aliases: ['compat', 'legacy-name'],
|
|
69
70
|
});
|
|
@@ -76,18 +77,24 @@ describe('cli() registration', () => {
|
|
|
76
77
|
it('preserves defaultFormat on the registered command', () => {
|
|
77
78
|
const cmd = cli({
|
|
78
79
|
site: 'test-registry',
|
|
79
|
-
name: 'plain-default',
|
|
80
|
+
name: 'plain-default', access: 'read',
|
|
80
81
|
description: 'prefers plain output',
|
|
81
82
|
defaultFormat: 'plain',
|
|
82
83
|
});
|
|
83
84
|
expect(cmd.defaultFormat).toBe('plain');
|
|
84
85
|
expect(getRegistry().get('test-registry/plain-default')?.defaultFormat).toBe('plain');
|
|
85
86
|
});
|
|
87
|
+
it('rejects commands without explicit access metadata', () => {
|
|
88
|
+
expect(() => cli({
|
|
89
|
+
site: 'test-registry',
|
|
90
|
+
name: 'missing-access',
|
|
91
|
+
})).toThrow("Command test-registry/missing-access must declare access: 'read' | 'write'");
|
|
92
|
+
});
|
|
86
93
|
});
|
|
87
94
|
describe('fullName', () => {
|
|
88
95
|
it('returns site/name', () => {
|
|
89
96
|
const cmd = {
|
|
90
|
-
site: 'bilibili', name: 'hot', description: '', args: [],
|
|
97
|
+
site: 'bilibili', name: 'hot', access: 'read', description: '', args: [],
|
|
91
98
|
};
|
|
92
99
|
expect(fullName(cmd)).toBe('bilibili/hot');
|
|
93
100
|
});
|
|
@@ -95,14 +102,14 @@ describe('fullName', () => {
|
|
|
95
102
|
describe('strategyLabel', () => {
|
|
96
103
|
it('returns strategy string', () => {
|
|
97
104
|
const cmd = {
|
|
98
|
-
site: 'test', name: 'test', description: '', args: [],
|
|
105
|
+
site: 'test', name: 'test', access: 'read', description: '', args: [],
|
|
99
106
|
strategy: Strategy.INTERCEPT,
|
|
100
107
|
};
|
|
101
108
|
expect(strategyLabel(cmd)).toBe('intercept');
|
|
102
109
|
});
|
|
103
110
|
it('returns public when no strategy set', () => {
|
|
104
111
|
const cmd = {
|
|
105
|
-
site: 'test', name: 'test', description: '', args: [],
|
|
112
|
+
site: 'test', name: 'test', access: 'read', description: '', args: [],
|
|
106
113
|
};
|
|
107
114
|
expect(strategyLabel(cmd)).toBe('public');
|
|
108
115
|
});
|
|
@@ -111,7 +118,7 @@ describe('registerCommand', () => {
|
|
|
111
118
|
it('registers a pre-built command', () => {
|
|
112
119
|
const cmd = {
|
|
113
120
|
site: 'test-registry',
|
|
114
|
-
name: 'direct-reg',
|
|
121
|
+
name: 'direct-reg', access: 'read',
|
|
115
122
|
description: 'directly registered',
|
|
116
123
|
args: [],
|
|
117
124
|
strategy: Strategy.HEADER,
|
|
@@ -125,7 +132,7 @@ describe('registerCommand', () => {
|
|
|
125
132
|
describe('normalizeCommand (via registerCommand)', () => {
|
|
126
133
|
it('COOKIE + domain → navigateBefore is the domain URL', () => {
|
|
127
134
|
registerCommand({
|
|
128
|
-
site: 'test-norm', name: 'cookie-domain', description: '', args: [],
|
|
135
|
+
site: 'test-norm', name: 'cookie-domain', access: 'read', description: '', args: [],
|
|
129
136
|
strategy: Strategy.COOKIE, domain: 'x.com',
|
|
130
137
|
});
|
|
131
138
|
const cmd = getRegistry().get('test-norm/cookie-domain');
|
|
@@ -134,7 +141,7 @@ describe('normalizeCommand (via registerCommand)', () => {
|
|
|
134
141
|
});
|
|
135
142
|
it('COOKIE without domain → navigateBefore is true (auth context, no URL)', () => {
|
|
136
143
|
registerCommand({
|
|
137
|
-
site: 'test-norm', name: 'cookie-nodomain', description: '', args: [],
|
|
144
|
+
site: 'test-norm', name: 'cookie-nodomain', access: 'read', description: '', args: [],
|
|
138
145
|
strategy: Strategy.COOKIE,
|
|
139
146
|
});
|
|
140
147
|
const cmd = getRegistry().get('test-norm/cookie-nodomain');
|
|
@@ -143,7 +150,7 @@ describe('normalizeCommand (via registerCommand)', () => {
|
|
|
143
150
|
});
|
|
144
151
|
it('INTERCEPT → navigateBefore is true (auth context)', () => {
|
|
145
152
|
registerCommand({
|
|
146
|
-
site: 'test-norm', name: 'intercept', description: '', args: [],
|
|
153
|
+
site: 'test-norm', name: 'intercept', access: 'read', description: '', args: [],
|
|
147
154
|
strategy: Strategy.INTERCEPT, domain: 'example.com',
|
|
148
155
|
});
|
|
149
156
|
const cmd = getRegistry().get('test-norm/intercept');
|
|
@@ -152,7 +159,7 @@ describe('normalizeCommand (via registerCommand)', () => {
|
|
|
152
159
|
});
|
|
153
160
|
it('PUBLIC → browser false, navigateBefore undefined', () => {
|
|
154
161
|
registerCommand({
|
|
155
|
-
site: 'test-norm', name: 'public', description: '', args: [],
|
|
162
|
+
site: 'test-norm', name: 'public', access: 'read', description: '', args: [],
|
|
156
163
|
strategy: Strategy.PUBLIC,
|
|
157
164
|
});
|
|
158
165
|
const cmd = getRegistry().get('test-norm/public');
|
|
@@ -161,7 +168,7 @@ describe('normalizeCommand (via registerCommand)', () => {
|
|
|
161
168
|
});
|
|
162
169
|
it('LOCAL → browser false, navigateBefore undefined', () => {
|
|
163
170
|
registerCommand({
|
|
164
|
-
site: 'test-norm', name: 'local', description: '', args: [],
|
|
171
|
+
site: 'test-norm', name: 'local', access: 'read', description: '', args: [],
|
|
165
172
|
strategy: Strategy.LOCAL,
|
|
166
173
|
});
|
|
167
174
|
const cmd = getRegistry().get('test-norm/local');
|
|
@@ -172,7 +179,7 @@ describe('normalizeCommand (via registerCommand)', () => {
|
|
|
172
179
|
});
|
|
173
180
|
it('explicit navigateBefore: false overrides COOKIE + domain', () => {
|
|
174
181
|
registerCommand({
|
|
175
|
-
site: 'test-norm', name: 'cookie-override', description: '', args: [],
|
|
182
|
+
site: 'test-norm', name: 'cookie-override', access: 'read', description: '', args: [],
|
|
176
183
|
strategy: Strategy.COOKIE, domain: 'amazon.com', navigateBefore: false,
|
|
177
184
|
});
|
|
178
185
|
const cmd = getRegistry().get('test-norm/cookie-override');
|
|
@@ -181,7 +188,7 @@ describe('normalizeCommand (via registerCommand)', () => {
|
|
|
181
188
|
});
|
|
182
189
|
it('explicit navigateBefore URL overrides strategy default', () => {
|
|
183
190
|
registerCommand({
|
|
184
|
-
site: 'test-norm', name: 'explicit-url', description: '', args: [],
|
|
191
|
+
site: 'test-norm', name: 'explicit-url', access: 'read', description: '', args: [],
|
|
185
192
|
strategy: Strategy.COOKIE, domain: 'x.com',
|
|
186
193
|
navigateBefore: 'https://x.com/explore',
|
|
187
194
|
});
|
|
@@ -24,15 +24,19 @@ export declare function serializeCommand(cmd: CliCommand): {
|
|
|
24
24
|
name: string;
|
|
25
25
|
aliases: string[];
|
|
26
26
|
description: string;
|
|
27
|
+
access: import("./registry.js").CommandAccess;
|
|
27
28
|
strategy: string;
|
|
28
29
|
browser: boolean;
|
|
29
30
|
args: SerializedArg[];
|
|
30
31
|
columns: string[];
|
|
31
32
|
domain: string | null;
|
|
33
|
+
example: string;
|
|
32
34
|
deprecated: string | boolean | null;
|
|
33
35
|
replacedBy: string | null;
|
|
34
36
|
};
|
|
35
37
|
/** Human-readable arg summary: `<required> [optional]` style. */
|
|
36
38
|
export declare function formatArgSummary(args: Arg[]): string;
|
|
39
|
+
/** Agent-facing canonical invocation. Adapter authors may override with `example`. */
|
|
40
|
+
export declare function formatCommandExample(cmd: CliCommand): string;
|
|
37
41
|
/** Generate the --help appendix showing registry metadata not exposed by Commander. */
|
|
38
42
|
export declare function formatRegistryHelpText(cmd: CliCommand): string;
|
|
@@ -26,11 +26,13 @@ export function serializeCommand(cmd) {
|
|
|
26
26
|
name: cmd.name,
|
|
27
27
|
aliases: cmd.aliases ?? [],
|
|
28
28
|
description: cmd.description,
|
|
29
|
+
access: cmd.access,
|
|
29
30
|
strategy: strategyLabel(cmd),
|
|
30
31
|
browser: !!cmd.browser,
|
|
31
32
|
args: cmd.args.map(serializeArg),
|
|
32
33
|
columns: cmd.columns ?? [],
|
|
33
34
|
domain: cmd.domain ?? null,
|
|
35
|
+
example: formatCommandExample(cmd),
|
|
34
36
|
deprecated: cmd.deprecated ?? null,
|
|
35
37
|
replacedBy: cmd.replacedBy ?? null,
|
|
36
38
|
};
|
|
@@ -51,6 +53,29 @@ function summarizeChoices(choices) {
|
|
|
51
53
|
return choices.join(', ');
|
|
52
54
|
return `${choices.slice(0, 4).join(', ')}, ... (+${choices.length - 4} more)`;
|
|
53
55
|
}
|
|
56
|
+
function formatValuePlaceholder(name) {
|
|
57
|
+
return `<${name}>`;
|
|
58
|
+
}
|
|
59
|
+
/** Agent-facing canonical invocation. Adapter authors may override with `example`. */
|
|
60
|
+
export function formatCommandExample(cmd) {
|
|
61
|
+
if (cmd.example?.trim())
|
|
62
|
+
return cmd.example.trim();
|
|
63
|
+
const parts = ['opencli', cmd.site, cmd.name];
|
|
64
|
+
for (const arg of cmd.args) {
|
|
65
|
+
if (arg.positional && arg.required) {
|
|
66
|
+
parts.push(formatValuePlaceholder(arg.name));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const arg of cmd.args) {
|
|
70
|
+
if (arg.positional || !arg.required)
|
|
71
|
+
continue;
|
|
72
|
+
parts.push(`--${arg.name}`);
|
|
73
|
+
if (arg.type !== 'bool' && arg.type !== 'boolean')
|
|
74
|
+
parts.push(formatValuePlaceholder(arg.name));
|
|
75
|
+
}
|
|
76
|
+
parts.push('-f', 'yaml');
|
|
77
|
+
return parts.join(' ');
|
|
78
|
+
}
|
|
54
79
|
/** Generate the --help appendix showing registry metadata not exposed by Commander. */
|
|
55
80
|
export function formatRegistryHelpText(cmd) {
|
|
56
81
|
const lines = [];
|
|
@@ -61,7 +86,7 @@ export function formatRegistryHelpText(cmd) {
|
|
|
61
86
|
lines.push(` ${prefix}: ${summarizeChoices(a.choices)}${def}`);
|
|
62
87
|
}
|
|
63
88
|
const meta = [];
|
|
64
|
-
meta.push(`
|
|
89
|
+
meta.push(`Access: ${cmd.access}`);
|
|
65
90
|
meta.push(`Browser: ${cmd.browser ? 'yes' : 'no'}`);
|
|
66
91
|
if (cmd.domain)
|
|
67
92
|
meta.push(`Domain: ${cmd.domain}`);
|
|
@@ -72,6 +97,7 @@ export function formatRegistryHelpText(cmd) {
|
|
|
72
97
|
if (cmd.aliases?.length)
|
|
73
98
|
meta.push(`Aliases: ${cmd.aliases.join(', ')}`);
|
|
74
99
|
lines.push(meta.join(' | '));
|
|
100
|
+
lines.push(`Example: ${formatCommandExample(cmd)}`);
|
|
75
101
|
if (cmd.columns?.length)
|
|
76
102
|
lines.push(`Output columns: ${cmd.columns.join(', ')}`);
|
|
77
103
|
return '\n' + lines.join('\n') + '\n';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { Strategy } from './registry.js';
|
|
3
|
-
import { formatRegistryHelpText, serializeCommand } from './serialization.js';
|
|
3
|
+
import { formatCommandExample, formatRegistryHelpText, serializeCommand } from './serialization.js';
|
|
4
4
|
describe('formatRegistryHelpText', () => {
|
|
5
5
|
it('summarizes long choices lists so help text stays readable', () => {
|
|
6
6
|
const cmd = {
|
|
7
7
|
site: 'demo',
|
|
8
|
-
name: 'dynamic',
|
|
8
|
+
name: 'dynamic', access: 'read',
|
|
9
9
|
description: 'Demo command',
|
|
10
10
|
strategy: Strategy.PUBLIC,
|
|
11
11
|
browser: false,
|
|
@@ -24,6 +24,7 @@ describe('formatRegistryHelpText', () => {
|
|
|
24
24
|
const cmd = {
|
|
25
25
|
site: 'demo',
|
|
26
26
|
name: 'get',
|
|
27
|
+
access: 'read',
|
|
27
28
|
aliases: ['metadata'],
|
|
28
29
|
description: 'Demo command',
|
|
29
30
|
strategy: Strategy.COOKIE,
|
|
@@ -32,8 +33,29 @@ describe('formatRegistryHelpText', () => {
|
|
|
32
33
|
};
|
|
33
34
|
expect(serializeCommand(cmd)).toMatchObject({
|
|
34
35
|
command: 'demo/get',
|
|
36
|
+
access: 'read',
|
|
35
37
|
aliases: ['metadata'],
|
|
36
38
|
});
|
|
37
39
|
expect(formatRegistryHelpText(cmd)).toContain('Aliases: metadata');
|
|
38
40
|
});
|
|
41
|
+
it('surfaces access and canonical examples instead of strategy as primary help metadata', () => {
|
|
42
|
+
const cmd = {
|
|
43
|
+
site: 'bilibili',
|
|
44
|
+
name: 'hot',
|
|
45
|
+
access: 'read',
|
|
46
|
+
description: 'Bilibili hot videos',
|
|
47
|
+
strategy: Strategy.COOKIE,
|
|
48
|
+
browser: true,
|
|
49
|
+
args: [],
|
|
50
|
+
};
|
|
51
|
+
expect(formatCommandExample(cmd)).toBe('opencli bilibili hot -f yaml');
|
|
52
|
+
expect(serializeCommand(cmd)).toMatchObject({
|
|
53
|
+
command: 'bilibili/hot',
|
|
54
|
+
access: 'read',
|
|
55
|
+
example: 'opencli bilibili hot -f yaml',
|
|
56
|
+
});
|
|
57
|
+
expect(formatRegistryHelpText(cmd)).toContain('Access: read');
|
|
58
|
+
expect(formatRegistryHelpText(cmd)).toContain('Example: opencli bilibili hot -f yaml');
|
|
59
|
+
expect(formatRegistryHelpText(cmd)).not.toContain('Strategy:');
|
|
60
|
+
});
|
|
39
61
|
});
|
package/dist/src/types.d.ts
CHANGED
|
@@ -130,6 +130,8 @@ export interface IPage {
|
|
|
130
130
|
setActivePage?(page?: string): void;
|
|
131
131
|
/** Send a raw CDP command via chrome.debugger passthrough. */
|
|
132
132
|
cdp?(method: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
133
|
+
/** Accept or dismiss the currently open JavaScript alert/confirm/prompt dialog. */
|
|
134
|
+
handleJavaScriptDialog?(accept: boolean, promptText?: string): Promise<void>;
|
|
133
135
|
/** List cross-origin iframe targets in snapshot order. */
|
|
134
136
|
frames?(): Promise<Array<{
|
|
135
137
|
index: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jackwener/opencli",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.12",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -57,6 +57,9 @@
|
|
|
57
57
|
"test:adapter": "vitest run --project adapter",
|
|
58
58
|
"test:all": "vitest run",
|
|
59
59
|
"test:e2e": "vitest run --project e2e",
|
|
60
|
+
"advise:listing-id-pairing": "node scripts/check-listing-id-pairing.mjs",
|
|
61
|
+
"check:silent-column-drop": "node scripts/check-silent-column-drop.mjs",
|
|
62
|
+
"check:typed-error-lint": "node scripts/check-typed-error-lint.mjs",
|
|
60
63
|
"docs:dev": "vitepress dev docs",
|
|
61
64
|
"docs:build": "vitepress build docs",
|
|
62
65
|
"docs:preview": "vitepress preview docs"
|